示例#1
0
    def __copy(self):
        """Ask a name to copy a data."""
        row = self.collections_list.currentRow()
        if not row > -1:
            return

        name, ok = QInputDialog.getText(
            self,
            "Profile name",
            "Please enter a new profile name:"
        )
        if not ok:
            return

        if not name:
            QMessageBox.warning(
                self,
                "Profile name",
                "Can not use blank string to rename."
            )
            return

        name_old = self.collections_list.item(row).text()
        self.collections[name] = self.collections[name_old].copy()
        self.collections_list.addItem(name)
        self.unsave_func()
示例#2
0
 def pasteStorage(self):
     """Add the storage data from string."""
     expr, ok = QInputDialog.getMultiLineText(self, "Storage",
                                              "Please input expression:")
     if not ok:
         return
     try:
         # Put the expression into parser to see if it is legal.
         parse_params(expr)
     except Exception as e:
         print(e)
         QMessageBox.warning(self, "Loading failed",
                             "Your expression is in an incorrect format.")
         return
     name, ok = QInputDialog.getText(self, "Storage",
                                     "Please input name tag:")
     if not ok:
         return
     name_list = [
         self.mechanism_storage.item(i).text()
         for i in range(self.mechanism_storage.count())
     ]
     i = 0
     name = name or f"Prototype_{i}"
     while name in name_list:
         name = f"Prototype_{i}"
         i += 1
     self.__add_storage(name, expr)
示例#3
0
    def __rename(self):
        """Show up a string input to change the data name."""
        row = self.collections_list.currentRow()
        if not row > -1:
            return

        name, ok = QInputDialog.getText(
            self,
            "Profile name",
            "Please enter the profile name:"
        )
        if not ok:
            return

        if not name:
            QMessageBox.warning(
                self,
                "Profile name",
                "Can not use blank string to rename."
            )
            return

        item = self.collections_list.item(row)
        self.collections[name] = self.collections.pop(item.text())
        item.setText(name)
        self.unsave_func()
示例#4
0
 def on_importXLSX_clicked(self):
     """Paste path data from a Excel file."""
     fileName = self.inputFrom(
         "Excel file",
         ["Microsoft Office Excel (*.xlsx *.xlsm *.xltx *.xltm)"]
     )
     if not fileName:
         return
     wb = openpyxl.load_workbook(fileName)
     ws = wb.get_sheet_by_name(wb.get_sheet_names()[0])
     data = []
     #Keep finding until there is no value.
     i = 1
     while True:
         x = ws.cell(row=i, column=1).value
         y = ws.cell(row=i, column=2).value
         if x == None or y == None:
             break
         try:
             data.append((round(float(x), 4), round(float(y), 4)))
         except:
             QMessageBox.warning(self,
                 "File error",
                 "Wrong format.\n" +
                 "The datasheet seems to including non-digital cell."
             )
             break
         i += 1
     for x, y in data:
         self.add_point(x, y)
示例#5
0
    def __add_from_files(self):
        """Append atlas by text files."""
        file_names = self.input_from("Edges data", ["Text File (*.txt)"],
                                     multiple=True)
        if not file_names:
            return

        read_data = []
        for file_name in file_names:
            with open(file_name, 'r', encoding='utf-8') as f:
                for line in f:
                    read_data.append(line)

        collections = []
        for edges in read_data:
            try:
                collections.append(Graph(eval(edges)))
            except (SyntaxError, TypeError):
                QMessageBox.warning(self, "Wrong format",
                                    "Please check the edges text format.")
                return
        if not collections:
            return
        self.collections += collections
        self.__reload_atlas()
示例#6
0
    def __read_slvs(self, file_name: str):
        """Read slvs format.

        + Choose a group.
        + Read the entities of the group.
        """
        parser = SlvsParser(file_name)
        if not parser.isValid():
            QMessageBox.warning(self, "Format error",
                                "The format is not support.")
            return
        groups = parser.getGroups()
        if not groups:
            QMessageBox.warning(self, "Format error",
                                "The model file is empty.")
            return
        group, ok = QInputDialog.getItem(
            self, "Solvespace groups", "Choose a group:\n"
            "(Please know that the group must contain a sketch only.)",
            ["@".join(g) for g in groups], 0, False)
        if not ok:
            return
        self.clear()
        self.DatabaseWidget.reset()
        print(f"Read from group: {group}")
        self.parseExpression(parser.parse(group.split('@')[0]))
示例#7
0
 def __import_xlsx(self):
     """Paste path data from a Excel file."""
     file_name = self.input_from(
         "Excel file",
         ["Microsoft Office Excel (*.xlsx *.xlsm *.xltx *.xltm)"])
     if not file_name:
         return
     wb = load_workbook(file_name)
     ws = wb.get_sheet_by_name(wb.get_sheet_names()[0])
     data = []
     # Keep finding until there is no value.
     i = 1
     while True:
         x = ws.cell(row=i, column=1).value
         y = ws.cell(row=i, column=2).value
         if None in {x, y}:
             break
         try:
             data.append((round(float(x), 4), round(float(y), 4)))
         except (IndexError, AttributeError):
             QMessageBox.warning(
                 self, "File error", "Wrong format.\n"
                 "The data sheet seems to including non-digital cell.")
             break
         i += 1
     for x, y in data:
         self.add_point(x, y)
示例#8
0
    def refresh_proj(self, node: Optional[QTreeWidgetItem] = None):
        """Re-parse the file node."""
        if node is None:
            node = self.tree_main.currentItem()
        if not node.text(1):
            QMessageBox.warning(self, "No path",
                                "Can only refresh from valid path.")
            return

        self.__delete_node_data(node)
        node.takeChildren()
        parse(node, self.data)
        self.tree_main.setCurrentItem(node)
        _expand_recursive(node)
        code = int(node.text(2))
        self.text_editor.setText(self.data[code])
        self.data.set_saved(code, True)
        self.__add_macros()

        # File keeper
        if self.keeper is not None:
            self.keeper.stop()
        self.keeper = FileKeeper(LOADED_FILES, self)
        self.keeper.file_changed.connect(self.file_changed_warning)
        self.keeper.start()
示例#9
0
 def on_Edges_to_altas_clicked(self):
     """Turn the text files into a atlas image.
     
     This opreation will load all edges to list widget first.
     """
     fileNames = self.inputFrom(
         "Edges data",
         ["Text File (*.txt)"],
         multiple=True
     )
     if not fileNames:
         return
     read_data = []
     for fileName in fileNames:
         with open(fileName, 'r') as f:
             read_data += f.read().split('\n')
     answer = []
     for edges in read_data:
         try:
             answer.append(Graph(eval(edges)))
         except:
             QMessageBox.warning(self,
                 "Wrong format",
                 "Please check the edges text format."
             )
             return
     if not answer:
         return
     self.answer = answer
     self.on_reload_atlas_clicked()
     check_status = self.save_edges_auto.isChecked()
     self.save_edges_auto.setChecked(False)
     self.on_save_atlas_clicked()
     self.save_edges_auto.setChecked(check_status)
示例#10
0
def on_mechanism_storage_paste_clicked(self):
    """Add the storage data from string."""
    expr, ok = QInputDialog.getText(self, "Storage",
                                    "Please input expression:")
    if not ok:
        return
    try:
        #Put the expression into parser to see if it is legal.
        PMKS_parser.parse(expr)
    except:
        QMessageBox.warning(self, "Loading failed",
                            "Your expression is in an incorrect format.")
        return
    name, ok = QInputDialog.getText(self, "Storage", "Please input name tag:")
    if not ok:
        return
    if not name:
        nameList = [
            self.mechanism_storage.item(i).text()
            for i in range(self.mechanism_storage.count())
        ]
        i = 0
        while "Prototype_{}".format(i) in nameList:
            i += 1
        name = "Prototype_{}".format(i)
    _addStorage(self, name, expr, clear=False)
示例#11
0
def on_action_Import_PMKS_server_triggered(self):
    """Load PMKS URL and turn it to expression."""
    URL, ok = QInputDialog.getText(self, "PMKS URL input",
                                   "Please input link string:")
    if not ok:
        return
    if not URL:
        QMessageBox.warning(self, "Loading failed",
                            "Your link is in an incorrect format.")
        return
    try:
        for s in URL.split('?')[-1].split('&'):
            if 'mech=' in s:
                expr = s.replace('mech=', '').split('|')
                break
        textList = [s for s in expr if s not in ('', " ", '\n')]
        expression = []
        while textList:
            item = textList.pop(0).split(',')[:-1]
            for i, e in enumerate(reversed(item)):
                if e in ['R', 'P', 'RP']:
                    t = -(i + 1)
                    break
            links = item[:t]
            item = item[t:]
            expression.append("J[{}, P[{}], L[{}]]".format(
                "{}:{}".format(item[0], item[-1]) if item[0] != 'R' else 'R',
                ", ".join((item[1], item[2])), ", ".join(links)))
        expression = "M[{}]".format(", ".join(expression))
    except:
        QMessageBox.warning(self, "Loading failed",
                            "Your link is in an incorrect format.")
    else:
        self.parseExpression(expression)
示例#12
0
 def parse_expression(self, expr: str):
     """Parse expression."""
     try:
         args_list = parse_params(expr)
     except LarkError:
         QMessageBox.warning(
             self,
             "Loading failed",
             f"Your expression is in an incorrect format."
         )
     else:
         for args in args_list:
             links = args[0].split(',')
             link_names = {
                 vlink.name for vlink in self.entities_link.data()
             }
             for link_name in links:
                 # If link name not exist.
                 if link_name not in link_names:
                     self.add_link(link_name, 'Blue')
             row_count = self.entities_point.rowCount()
             self.command_stack.beginMacro(f"Add {{Point{row_count}}}")
             self.command_stack.push(AddTable(self.entities_point))
             self.command_stack.push(EditPointTable(
                 row_count,
                 self.entities_point,
                 self.entities_link,
                 args
             ))
             self.command_stack.endMacro()
示例#13
0
 def loadCommitID(self, id: int):
     """Check the id is correct."""
     try:
         commit = self.history_commit.where(CommitModel.id == id).get()
     except CommitModel.DoesNotExist:
         QMessageBox.warning(self, "Warning", "Commit ID is not exist.")
     except AttributeError:
         QMessageBox.warning(self, "Warning", "Nothing submitted.")
     else:
         self.loadCommit(commit)
示例#14
0
 def add_collection(self, edges: Sequence[Tuple[int, int]]):
     """Add collection by in put edges."""
     graph = Graph(edges)
     error = self.__is_valid_graph(graph)
     if error:
         QMessageBox.warning(self, "Add Collection Error",
                             f"Error: {error}")
         return
     self.collections.append(graph)
     self.unsaveFunc()
     self.__reload_atlas()
示例#15
0
 def refresh_proj(self):
     """Re-parse the file node."""
     node = self.tree_main.currentItem()
     if not node.text(1):
         QMessageBox.warning(
             self,
             "No path",
             "Can only refresh from valid path."
         )
     parse(node, self.data)
     self.tree_main.setCurrentItem(node)
     self.text_editor.setText(self.data[int(node.text(2))])
示例#16
0
 def __readPathFromCSV(self, data: List[str]):
     """Trun STR to FLOAT then add them to current target path."""
     try:
         data = [(round(float(data[i]), 4), round(float(data[i + 1]), 4))
                 for i in range(0, len(data), 2)]
     except:
         QMessageBox.warning(
             self, "File error",
             "Wrong format.\nIt should be look like this:" +
             "\n0.0,0.0[\\n]" * 3)
     else:
         for e in data:
             self.addPoint(e[0], e[1])
示例#17
0
 def __from_canvas(self):
     """Get a collection data from current mechanism."""
     try:
         collection = self.getCollection()
     except ValueError as e:
         QMessageBox.warning(self, "Mechanism not support.", str(e))
     else:
         num = 0
         name = f"mechanism{num}"
         while name in self.collections:
             name = f"mechanism{num}"
             num += 1
         self.collections[name] = collection.copy()
         self.collections_list.addItem(name)
示例#18
0
 def __read_path_from_csv(self, raw_data: List[str]):
     """Turn string to float then add them to current target path."""
     try:
         data = [(round(float(raw_data[i]),
                        4), round(float(raw_data[i + 1]), 4))
                 for i in range(0, len(raw_data), 2)]
     except (IndexError, ValueError):
         QMessageBox.warning(
             self, "File error",
             "Wrong format.\nIt should be look like this:" +
             ("\n0.0,0.0[\\n]" * 3))
     else:
         for x, y in data:
             self.add_point(x, y)
示例#19
0
    def __import_pmks_url(self):
        """Load PMKS URL and turn it to expression."""
        url, ok = QInputDialog.getText(
            self,
            "PMKS URL input",
            "Please input link string:"
        )
        if not ok:
            return
        if not url:
            QMessageBox.warning(
                self,
                "Loading failed",
                "Your link is in an incorrect format."
            )
            return
        try:
            for s in url.split('?')[-1].split('&'):
                if 'mech=' in s:
                    expr = s.replace('mech=', '').split('|')
                    break
            else:
                raise ValueError

            text_list = [s for s in expr if s not in ('', " ", '\n')]
            expr.clear()
            while text_list:
                item = text_list.pop(0).split(',')[:-1]
                for i, e in enumerate(reversed(item)):
                    if e in {'R', 'P', 'RP'}:
                        t = -(i + 1)
                        break
                else:
                    raise ValueError
                links = item[:t]
                item = item[t:]
                type_text = f"{item[0]}:{item[-1]}" if item[0] != 'R' else 'R'
                links_text = ", ".join(links)
                expr.append(f"J[{type_text}, P[{item[1]}, {item[2]}], L[{links_text}]]")
            expr = "M[" + ", ".join(expr) + "]"
        except (ValueError, IndexError):
            QMessageBox.warning(
                self,
                "Loading failed",
                "Your link is in an incorrect format."
            )
        else:
            self.parse_expression(expr)
示例#20
0
 def file_changed_warning(self, path: str, node: QTreeWidgetItem):
     """Triggered when file changed."""
     if QMessageBox.warning(self, "File Changed",
                            f"File {path} has changed.\nReload the file?",
                            QMessageBox.Yes
                            | QMessageBox.No) == QMessageBox.Yes:
         self.refresh_proj(node)
示例#21
0
 def __drawAtlas(self, i: int, G: Graph) -> bool:
     """Draw atlas and return True if done."""
     item = QListWidgetItem("No. {}".format(i + 1))
     try:
         item.setIcon(
             graph(G,
                   self.Topologic_result.iconSize().width(), self.engine,
                   self.graph_link_as_node.isChecked()))
     except EngineError as e:
         QMessageBox.warning(
             self, str(e),
             "Please install and make sure Graphviz is working.")
         return False
     else:
         item.setToolTip(str(G.edges))
         self.Topologic_result.addItem(item)
         return True
示例#22
0
    def __accepted(self):
        """Use the file path to export the project."""
        qdir = QDir(_get_name(self.path_edit, ispath=True))
        if self.newfolder_option.isChecked():
            new_folder = self.filename_edit.placeholderText()
            if (not qdir.mkdir(new_folder)) and self.warn_radio.isChecked():
                self.exist_warning(new_folder, folder=True)
                return
            qdir.cd(new_folder)

        try:
            ok = self.do(qdir)
        except PermissionError as error:
            QMessageBox.warning(self, "Permission error", str(error))
        else:
            if ok:
                self.accept()
示例#23
0
 def read(self, file_name: str):
     """Load database commit."""
     self.__connect_database(file_name)
     history_commit = CommitModel.select().order_by(CommitModel.id)
     commit_count = len(history_commit)
     if not commit_count:
         QMessageBox.warning(self, "Warning",
                             "This file is a non-committed database.")
         return
     self.__clear_func()
     self.reset()
     self.history_commit = history_commit
     for commit in self.history_commit:
         self.__add_commit(commit)
     print(f"{commit_count} commit(s) was find in database.")
     self.__load_commit(self.history_commit.order_by(-CommitModel.id).get())
     self.file_name = QFileInfo(file_name)
     self.__workbook_saved()
示例#24
0
 def __add_from_edges(self):
     """Add collection by input string."""
     edges_str = ""
     while not edges_str:
         edges_str, ok = QInputDialog.getText(
             self, "Add by edges", "Please enter a connection expression:\n"
             "Example: [(0, 1), (1, 2), (2, 3), (3, 0)]")
         if not ok:
             return
     try:
         edges = eval(edges_str)
         if any(len(edge) != 2 for edge in edges):
             raise ValueError("wrong format")
     except (SyntaxError, ValueError) as error:
         QMessageBox.warning(self, str(error), f"Error: {error}")
         return
     else:
         self.add_collection(edges)
示例#25
0
 def read(self, fileName: str):
     """Load database commit."""
     self.connectDatabase(fileName)
     history_commit = CommitModel.select().order_by(CommitModel.id)
     commit_count = len(history_commit)
     if not commit_count:
         QMessageBox.warning(self, "Warning",
                             "This file is a non-committed database.")
         return
     self.clearFunc()
     self.reset()
     self.history_commit = history_commit
     for commit in self.history_commit:
         self.addCommit(commit)
     print("{} commit(s) was find in database.".format(commit_count))
     self.loadCommit(self.history_commit.order_by(-CommitModel.id).get())
     self.fileName = QFileInfo(fileName)
     self.isSavedFunc()
示例#26
0
 def addCollection(self, edges: Tuple[Tuple[int, int]]):
     """Add collection by in put edges."""
     G = Graph(edges)
     try:
         if not edges:
             raise TestError("is empty graph.")
         for n in G.nodes:
             if len(list(G.neighbors(n))) < 2:
                 raise TestError("is not close chain")
         for H in self.collections:
             if is_isomorphic(G, H):
                 raise TestError("is isomorphic")
     except TestError as e:
         QMessageBox.warning(self, "Add Collection Error",
                             "Error: {}".format(e))
         return
     self.collections.append(G)
     self.unsaveFunc()
     self.on_reload_atlas_clicked()
示例#27
0
 def on_add_by_edges_button_clicked(self):
     """Add collection by input string."""
     edgesSTR = ""
     while not edgesSTR:
         edgesSTR, ok = QInputDialog.getText(
             self, "Add by edges",
             "Please enter a connection expression:\n" +
             "Example: [(0, 1), (1, 2), (2, 3), (3, 0)]")
         if not ok:
             return
     try:
         edges = eval(edgesSTR)
         if any(len(edge) != 2 for edge in edges):
             raise SyntaxError("Wrong format")
     except Exception as e:
         QMessageBox.warning(self, str(e), "Error: {}".format(e))
         return
     else:
         self.addCollection(edges)
示例#28
0
 def __delete_branch(self):
     """Delete all commits in the branch."""
     if not self.BranchList.currentRow() > -1:
         return
     branch_name = self.BranchList.currentItem().text()
     if branch_name == self.branch_current.text():
         QMessageBox.warning(self, "Warning",
                             "Cannot delete current branch.")
         return
     file_name = self.file_name.absoluteFilePath()
     # Connect on database to remove all the commit in this branch.
     with _db.atomic():
         CommitModel.delete().where(
             CommitModel.branch.in_(BranchModel.select().where(
                 BranchModel.name == branch_name))).execute()
         BranchModel.delete().where(
             BranchModel.name == branch_name).execute()
     _db.close()
     print(f"Branch {branch_name} was deleted.")
     # Reload database.
     self.read(file_name)
示例#29
0
 def on_branch_delete_clicked(self):
     """Delete all commits in the branch."""
     if not self.BranchList.currentRow() > -1:
         return
     branch_name = self.BranchList.currentItem().text()
     if branch_name != self.branch_current.text():
         fileName = self.fileName.absoluteFilePath()
         #Connect on database to remove all the commit in this branch.
         with db.atomic():
             branch_quary = (BranchModel.select().where(
                 BranchModel.name == branch_name))
             (CommitModel.delete().where(
                 CommitModel.branch.in_(branch_quary)).execute())
             (BranchModel.delete().where(
                 BranchModel.name == branch_name).execute())
         db.close()
         print("Branch {} was deleted.".format(branch_name))
         #Reload database.
         self.read(fileName)
     else:
         QMessageBox.warning(self, "Warning",
                             "Cannot delete current branch.")
示例#30
0
 def on_add_by_files_button_clicked(self):
     """Append atlas by text files."""
     fileNames = self.inputFrom("Edges data", ["Text File (*.txt)"],
                                multiple=True)
     if not fileNames:
         return
     read_data = []
     for fileName in fileNames:
         with open(fileName, 'r') as f:
             read_data += f.read().split('\n')
     collections = []
     for edges in read_data:
         try:
             collections.append(Graph(eval(edges)))
         except:
             QMessageBox.warning(self, "Wrong format",
                                 "Please check the edges text format.")
             return
     if not collections:
         return
     self.collections += collections
     self.on_reload_atlas_clicked()