Пример #1
0
    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()
Пример #2
0
 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))
Пример #3
0
 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()
Пример #4
0
    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()
Пример #5
0
 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()
Пример #6
0
 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)
Пример #7
0
 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()
Пример #8
0
    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}")
Пример #9
0
 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
Пример #10
0
    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()
Пример #11
0
 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))
Пример #12
0
 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()
Пример #13
0
 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()
Пример #14
0
 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()
Пример #15
0
    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))
Пример #16
0
    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()
Пример #17
0
    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()
Пример #18
0
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)
Пример #19
0
 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
Пример #20
0
 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()
Пример #21
0
    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
Пример #22
0
    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)
Пример #23
0
 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()
Пример #24
0
 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
Пример #25
0
 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()
Пример #26
0
 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()
Пример #27
0
    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()
Пример #28
0
 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)
Пример #29
0
    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()
Пример #30
0
 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()