def __replace_project(self): """Replace in project.""" self.__find_project() count = self.find_list.count() if count == 0: return if QMessageBox.question(self, "Replace in project", f"Replace all? ({count})") != QMessageBox.Yes: return replace_text = self.replace_bar.text() if not replace_text: if QMessageBox.question( self, "Empty replace text", f"Replace text is an empty string, still replace all?" ) != QMessageBox.No: return text, replace_text, flags = self.__search_option() used_code = set() for row in range(self.find_list.count()): code = int(self.find_list.item(row).toolTip().split(':')[0]) if code in used_code: continue self.data[code] = re.sub(text, replace_text, self.data[code], flags) used_code.add(code) self.__root_unsaved()
def on_record_list_itemDoubleClicked(self, item): """View path data.""" name = item.text().split(":")[0] try: data = self.pathData[name] except KeyError: return reply = QMessageBox.question( self, "Path data", "This path data including {}.".format(", ".join( "Point{}".format(i) for i in range(len(data)) if data[i])), (QMessageBox.Save | QMessageBox.Close), QMessageBox.Close) if reply != QMessageBox.Save: return file_name = self.outputTo( "path data", ["Comma-Separated Values (*.csv)", "Text file (*.txt)"]) if not file_name: return with open(file_name, 'w', newline='') as stream: writer = csv.writer(stream) for point in data: for coordinate in point: writer.writerow(coordinate) writer.writerow(()) print("Output path data: {}".format(file_name))
def on_Combine_type_all_clicked(self): """Type synthesis - find all. If the data of number synthesis has multiple results, execute type synthesis one by one. """ if not self.Expression_number.currentRow()>-1: self.on_Combine_number_clicked() if self.Expression_number.currentItem().links is None: return answers = [] break_point = False for row in range(self.Expression_number.count()): answer = self.combineType(row) if answer: answers += answer else: break_point = True break if not answers: return if break_point: reply = QMessageBox.question(self, "Type synthesis - abort", "Do you want to keep the results?" ) if reply != QMessageBox.Yes: return self.answer = answers self.on_reload_atlas_clicked()
def restoreStorage(self, item: Optional[QListWidgetItem] = None): """Restore the storage data.""" if item is None: item = self.mechanism_storage.currentItem() if not item: return reply = QMessageBox.question( self, "Storage", "Restore mechanism will overwrite the canvas.\n" "Do you want to continue?") if reply != QMessageBox.Yes: return name = item.text() self.CommandStack.beginMacro(f"Restore from {{Mechanism: {name}}}") # After saved storage, clean all the item of two table widgets. self.EntitiesPoint.clear() self.EntitiesLink.clear() self.InputsWidget.variableExcluding() self.parseExpression(item.expr) self.CommandStack.push( DeleteStorage(self.mechanism_storage.row(item), self.mechanism_storage)) self.CommandStack.push( AddStorageName(name, self.mechanism_storage_name_tag)) self.CommandStack.endMacro()
def on_expression_auto_clicked(self): """Auto configure the solutions.""" if not self.driver_list.count(): QMessageBox.information(self, "Auto configure", "Please setting the driver joint(s).") return reply = QMessageBox.question( self, "Auto configure", "This function can detect the structure " + "to configure the solutions.\n" + "The current settings will be cleared.") if ((reply != QMessageBox.Yes) or (not self.on_expression_clear_clicked())): return exprs = vpoints_configure( graph2vpoints(self.PreviewWindow.G, self.PreviewWindow.pos, self.PreviewWindow.cus, self.PreviewWindow.same), [ eval(item.text().replace('P', '')) for item in list_items(self.driver_list) ], self.PreviewWindow.status) for expr in exprs: self.__addSolution(*expr) self.__hasSolution() self.__setWarning(self.expression_list_label, not self.PreviewWindow.isAllLock()) self.PreviewWindow.update()
def on_save_edges_clicked(self): """Saving all the atlas to text file.""" fileName = "" if self.save_edges_auto.isChecked(): fileName = self.outputTo( "Atlas edges expression", ["Text file (*.txt)"] ) if not fileName: return reply = QMessageBox.question(self, "Type synthesis", "Do you want to Re-synthesis?", (QMessageBox.Yes | QMessageBox.YesToAll | QMessageBox.Cancel), QMessageBox.YesToAll ) if reply == QMessageBox.Yes: self.on_Combine_type_clicked() elif reply == QMessageBox.YesToAll: self.on_Combine_type_all_clicked() count = self.Topologic_result.count() if not count: return if not fileName: fileName = self.outputTo( "Atlas edges expression", ["Text file (*.txt)"] ) if not fileName: return with open(fileName, 'w') as f: f.write('\n'.join(str(G.edges) for G in self.answer)) self.saveReplyBox("edges expression", fileName)
def on_clear_button_clicked(self): if self.profile_name.text() == "No setting": return reply = QMessageBox.question(self, "Clear setting", "Do you want to clear the setting?") if reply == QMessageBox.Yes: self.__clearSettings()
def __path_dlg(self, item: QListWidgetItem): """View path data.""" name = item.text().split(":")[0] try: data = self.__path_data[name] except KeyError: return points_text = ", ".join(f"Point{i}" for i in range(len(data))) if QMessageBox.question( self, "Path data", f"This path data including {points_text}.", (QMessageBox.Save | QMessageBox.Close), QMessageBox.Close ) != QMessageBox.Save: return file_name = self.output_to( "path data", ["Comma-Separated Values (*.csv)", "Text file (*.txt)"] ) if not file_name: return with open(file_name, 'w', encoding='utf-8', newline='') as stream: writer = csv.writer(stream) for point in data: for coordinate in point: writer.writerow(coordinate) writer.writerow(()) logger.info(f"Output path data: {file_name}")
def __checkSaved(self) -> bool: """Check and warn if user is not saved yet.""" if not self.changed: return True reply = QMessageBox.question( self, "Message", "Are you sure to load?\nAny changes won't be saved.") return reply == QMessageBox.Yes
def __user_clear(self): if not self.profile_name.text(): return if QMessageBox.question( self, "Clear setting", "Do you want to clear the setting?") == QMessageBox.Yes: self.__clear_settings()
def on_mergeButton_clicked(self): """Merge mechanism into main canvas.""" row = self.Result_list.currentRow() if not row > -1: return reply = QMessageBox.question(self, "Merge", "Merge this result to your canvas?") if reply == QMessageBox.Yes: self.mergeResult(row, self.__getPath(row))
def __user_clear(self): """Ask user before clear.""" reply = QMessageBox.question( self, "New profile", "Triangular iteration should be added structure diagrams " "from structure collections.\n" "Do you want to create a new profile?") if reply == QMessageBox.Yes: self.__clear_panel()
def on_clear_button_clicked(self): """Ask user before clear.""" if not self.collections: return reply = QMessageBox.question(self, "Delete", "Sure to remove all your collections?") if reply != QMessageBox.Yes: return self.clear() self.unsaveFunc()
def __clearPath(self, ask: bool = True): """Clear the current target path.""" if ask: reply = QMessageBox.question( self, "Clear path", "Are you sure to clear the current path?") if reply != QMessageBox.Yes: return self.currentPath().clear() self.path_list.clear() self.__currentPathChanged()
def __merge_result(self): """Merge mechanism into main canvas.""" row = self.result_list.currentRow() if not row > -1: return if QMessageBox.question( self, "Merge", "Add the result expression into storage?") == QMessageBox.Yes: expression: str = self.mechanism_data[row]['Expression'] self.merge_result(expression, self.__get_path(row))
def __user_clear(self): """Ask user before clear.""" if not self.collections: return if QMessageBox.question( self, "Delete", "Sure to remove all your collections?") != QMessageBox.Yes: return self.clear() self.unsaveFunc()
def __clear_path(self, *, ask: bool = True): """Clear the current target path.""" if ask: if QMessageBox.question(self, "Clear path", "Are you sure to clear the current path?" ) != QMessageBox.Yes: return self.current_path().clear() self.path_list.clear() self.__current_path_changed()
def on_action_Output_to_Expression_triggered(self): """Output as expression.""" expr = "M[{}]".format(", ".join(vpoint.expr for vpoint in self.EntitiesPoint.data())) text = ("You can copy the expression and import to another workbook:" + "\n\n{}\n\nClick the save button to copy it.".format(expr)) reply = QMessageBox.question(self, "Pyslvs Expression", text, (QMessageBox.Save | QMessageBox.Close), QMessageBox.Save) if reply == QMessageBox.Save: QApplication.clipboard().setText(expr)
def on_Expression_clear_clicked(self) -> bool: """Clear the solutions. Return true if success.""" if not self.Expression_list.count(): return True reply = QMessageBox.question(self, "Clear the solutions", "Are you sure to clear the solutions?") if reply == QMessageBox.Yes: self.PreviewWindow.setGrounded(self.grounded_list.currentRow()) self.Expression_list.clear() self.Expression.clear() self.hasSolution() return reply == QMessageBox.Yes
def on_Expression_auto_clicked(self): """Auto configure the solutions.""" if not self.Driver_list.count(): QMessageBox.information(self, "Auto configure", "Please setting the driver joint(s).") return reply = QMessageBox.question( self, "Auto configure", "This function can detect the structure to configure the solutions.\n" + "The current settings will be cleared.") if reply == QMessageBox.Yes and self.on_Expression_clear_clicked(): self.auto_configure_expression()
def __user_clear(self) -> bool: """Ask user before clear.""" if not self.configure_canvas.G.nodes: return True if QMessageBox.question( self, "New profile", "Do you want to create a new profile?\n" "Unsaved changes will be cleared!") == QMessageBox.Yes: self.__clear_panel() return True return False
def __save_atlas(self): """Saving all the atlas to image file. We should turn transparent background to white first. Then using QImage class to merge into one image. """ file_name = "" lateral = 0 if self.save_edges_auto.isChecked(): lateral, ok = QInputDialog.getInt(self, "Atlas", "The number of lateral:", 5, 1, 10) if not ok: return file_name = self.outputTo("Atlas image", qt_image_format) if file_name: reply = QMessageBox.question( self, "Type synthesis", "Do you want to Re-synthesis?", (QMessageBox.Yes | QMessageBox.YesToAll | QMessageBox.Cancel), QMessageBox.Yes) if reply == QMessageBox.Yes: self.__structure_synthesis() elif reply == QMessageBox.YesToAll: self.__structure_synthesis_all() count = self.structure_list.count() if not count: return if not lateral: lateral, ok = QInputDialog.getInt(self, "Atlas", "The number of lateral:", 5, 1, 10) if not ok: return if not file_name: file_name = self.outputTo("Atlas image", qt_image_format) if not file_name: return width = self.structure_list.iconSize().width() image_main = QImage( QSize(lateral * width if count > lateral else count * width, ((count // lateral) + bool(count % lateral)) * width), self.__atlas_image(0).format()) image_main.fill(QColor(Qt.white).rgb()) painter = QPainter(image_main) for row in range(count): image = self.__atlas_image(row) painter.drawImage( QPointF(row % lateral * width, row // lateral * width), image) painter.end() pixmap = QPixmap() pixmap.convertFromImage(image_main) pixmap.save(file_name, format=QFileInfo(file_name).suffix()) self.saveReplyBox("Atlas", file_name)
def on_delete_button_clicked(self): """Delete a data.""" row = self.collections_list.currentRow() if not row > -1: return reply = QMessageBox.question(self, "Delete", "Do you want to delete this structure?") if reply != QMessageBox.Yes: return item = self.collections_list.takeItem(row) del self.collections[item.text()] self.PreviewCanvas.clear() self.__hasCollection()
def __clear_expr(self) -> bool: """Clear the solutions. Return true if succeeded.""" if not self.expression_list.count(): return True reply = QMessageBox.question(self, "Clear the solutions", "Are you sure to clear the solutions?") if reply != QMessageBox.Yes: return False self.PreviewWindow.setGrounded(self.grounded_list.currentRow()) self.expression_list.clear() self.expr_show.clear() self.__has_solution() return True
def on_deleteButton_clicked(self): """Delete a result.""" row = self.Result_list.currentRow() if not row > -1: return reply = QMessageBox.question(self, "Delete", "Delete this result from list?") if reply != QMessageBox.Yes: return del self.mechanism_data[row] self.Result_list.takeItem(row) self.unsaveFunc() self.__hasResult()
def on_delete_button_clicked(self): """Delete the selected collection.""" row = self.collection_list.currentRow() if not row > -1: return reply = QMessageBox.question( self, "Delete", "Sure to remove #{} from your collections?".format(row)) if reply != QMessageBox.Yes: return self.clearSelection() self.collection_list.takeItem(row) del self.collections[row] self.unsaveFunc()
def __delete_result(self): """Delete a result.""" row = self.result_list.currentRow() if not row > -1: return if QMessageBox.question( self, "Delete", "Delete this result from list?") != QMessageBox.Yes: return self.mechanism_data.pop(row) self.result_list.takeItem(row) self.workbook_no_save() self.__has_result()
def on_grounded_merge_clicked(self): """Merge the grounded result.""" item = self.grounded_list.currentItem() if not item: return G = self.collections_grounded[0] text = item.text() if text == "Released": ground_link = None else: ground_link = int(text.replace(" constrainted", "").split("_")[1]) reply = QMessageBox.question( self, "Message", "Merge \"{}\" chain to your canvas?".format(text)) if reply == QMessageBox.Yes: self.add_points_by_graph(G, self.ground_engine, ground_link)
def __delete_collection(self): """Delete the selected collection.""" row = self.collection_list.currentRow() if not row > -1: return if QMessageBox.question( self, "Delete", f"Sure to remove #{row} from your collections?" ) != QMessageBox.Yes: return self.collection_list.takeItem(row) del self.collections[row] self.__clear_selection() self.unsaveFunc()
def on_variable_remove_clicked(self): """Remove and reset angle.""" row = self.variable_list.currentRow() if not row > -1: return reply = QMessageBox.question(self, "Remove variable", "Do you want to remove this variable?") if reply != QMessageBox.Yes: return self.variable_stop.click() self.CommandStack.beginMacro("Remove variable of Point{}".format(row)) self.CommandStack.push(DeleteVariable(row, self.variable_list)) self.CommandStack.endMacro() self.EntitiesPoint.getBackPosition() self.resolve()