Explorar el Código

- added a secondary link in the bookmark manager
- fixed the bookmark manager order of bookmark links; first two links are always protected from deletion or drag-and-drop to other positions

Marius Stanciu hace 6 años
padre
commit
dff5b262eb
Se han modificado 4 ficheros con 124 adiciones y 34 borrados
  1. 42 4
      FlatCAMApp.py
  2. 2 0
      README.md
  3. 65 29
      flatcamGUI/FlatCAMGUI.py
  4. 15 1
      flatcamGUI/GUIElements.py

+ 42 - 4
FlatCAMApp.py

@@ -4713,7 +4713,8 @@ class App(QtCore.QObject):
         if book_dict is None:
             self.defaults["global_bookmarks"].update(
                 {
-                    'FlatCAM': "http://flatcam.org"
+                    '1': ['FlatCAM', "http://flatcam.org"],
+                    '2': ['Backup Site', ""]
                 }
             )
         else:
@@ -4735,19 +4736,39 @@ class App(QtCore.QObject):
 
         bm_limit = int(self.defaults["global_bookmarks_limit"])
         if self.defaults["global_bookmarks"]:
-            for title, weblink in list(self.defaults["global_bookmarks"].items())[:bm_limit]:
+
+            # order the self.defaults["global_bookmarks"] dict keys by the value as integer
+            # the whole convoluted things is because when serializing the self.defaults (on app close or save)
+            # the JSON is first making the keys as strings (therefore I have to use strings too
+            # or do the conversion :(
+            # )
+            # and it is ordering them (actually I want that to make the defaults easy to search within) but making
+            # the '10' entry jsut after '1' therefore ordering as strings
+
+            sorted_bookmarks = sorted(list(self.defaults["global_bookmarks"].items())[:bm_limit],
+                                      key=lambda x: int(x[0]))
+            for entry, bookmark in sorted_bookmarks:
+                title = bookmark[0]
+                weblink = bookmark[1]
+
                 act = QtWidgets.QAction(parent=self.ui.menuhelp_bookmarks)
                 act.setText(title)
 
                 act.setIcon(QtGui.QIcon('share/link16.png'))
                 # from here: https://stackoverflow.com/questions/20390323/pyqt-dynamic-generate-qmenu-action-and-connect
-                act.triggered.connect(lambda sig, link=weblink: webbrowser.open(link))
+                if title == 'Backup Site' and weblink == "":
+                    act.triggered.connect(self.on_backup_site)
+                else:
+                    act.triggered.connect(lambda sig, link=weblink: webbrowser.open(link))
                 self.ui.menuhelp_bookmarks.insertAction(self.ui.menuhelp_bookmarks_manager, act)
 
         self.ui.menuhelp_bookmarks_manager.triggered.connect(self.on_bookmarks_manager)
 
     def on_bookmarks_manager(self):
-
+        """
+        Adds the bookmark manager in a Tab in Plot Area
+        :return:
+        """
         for idx in range(self.ui.plot_tab_area.count()):
             if self.ui.plot_tab_area.tabText(idx) == _("Bookmarks Manager"):
                 # there can be only one instance of Bookmark Manager at one time
@@ -4766,6 +4787,23 @@ class App(QtCore.QObject):
         # Switch plot_area to preferences page
         self.ui.plot_tab_area.setCurrentWidget(self.book_dialog_tab)
 
+    def on_backup_site(self):
+        msgbox = QtWidgets.QMessageBox()
+        msgbox.setText(_("This entry will resolve to another website if:\n\n"
+                         "1. FlatCAM.org website is down\n"
+                         "2. Someone forked FlatCAM project and wants to point\n"
+                         "to his own website\n\n"
+                         "If you can't get any informations about FlatCAM beta\n"
+                         "use the YouTube channel link from the Help menu."))
+
+        msgbox.setWindowTitle(_("Alternative website"))
+        msgbox.setWindowIcon(QtGui.QIcon('share/globe16.png'))
+        bt_yes = msgbox.addButton(_('Close'), QtWidgets.QMessageBox.YesRole)
+
+        msgbox.setDefaultButton(bt_yes)
+        msgbox.exec_()
+        # response = msgbox.clickedButton()
+
     def on_file_savedefaults(self):
         """
         Callback for menu item File->Save Defaults. Saves application default options

+ 2 - 0
README.md

@@ -21,6 +21,8 @@ CAD program, and create G-Code for Isolation routing.
 - fixed an issue that caused the impossibility to load a GCode file that contained the % symbol even when was loaded in a regular way from the File menu
 - re-added the CNC tool diameter entry for the CNCjob object in Selected tab.FCSpinner
 - since the CNCjob geometry creation is only useful for graphical purposes and have no impact on the GCode creation I have removed the cascaded union on the GCode geometry therefore speeding up the Gcode display by many factors (perhaps hundreds of times faster)
+- added a secondary link in the bookmark manager
+- fixed the bookmark manager order of bookmark links; first two links are always protected from deletion or drag-and-drop to other positions
 
 13.10.2019
 

+ 65 - 29
flatcamGUI/FlatCAMGUI.py

@@ -3724,7 +3724,7 @@ class BookmarkManager(QtWidgets.QWidget):
         table_hlay = QtWidgets.QHBoxLayout()
         layout.addLayout(table_hlay)
 
-        self.table_widget = FCTable(drag_drop=True)
+        self.table_widget = FCTable(drag_drop=True, protected_rows=[0, 1])
         self.table_widget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
         table_hlay.addWidget(self.table_widget)
 
@@ -3794,8 +3794,8 @@ class BookmarkManager(QtWidgets.QWidget):
         remove_entry_btn.clicked.connect(self.on_remove_entry)
         export_list_btn.clicked.connect(self.on_export_bookmarks)
         import_list_btn.clicked.connect(self.on_import_bookmarks)
-        self.title_entry.editingFinished.connect(self.on_add_entry)
-        self.link_entry.editingFinished.connect(self.on_add_entry)
+        self.title_entry.returnPressed.connect(self.on_add_entry)
+        self.link_entry.returnPressed.connect(self.on_add_entry)
         # closebtn.clicked.connect(self.accept)
 
         self.table_widget.drag_drop_sig.connect(self.mark_table_rows_for_actions)
@@ -3806,15 +3806,19 @@ class BookmarkManager(QtWidgets.QWidget):
         self.table_widget.setRowCount(len(self.bm_dict))
 
         nr_crt = 0
-        for title, weblink in self.bm_dict.items():
+        sorted_bookmarks = sorted(list(self.bm_dict.items()), key=lambda x: int(x[0]))
+        for entry, bookmark in sorted_bookmarks:
             row = nr_crt
             nr_crt += 1
+
+            title = bookmark[0]
+            weblink = bookmark[1]
+
             id_item = QtWidgets.QTableWidgetItem('%d' % int(nr_crt))
             # id.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
             self.table_widget.setItem(row, 0, id_item)  # Tool name/id
 
             title_item = QtWidgets.QTableWidgetItem(title)
-
             self.table_widget.setItem(row, 1, title_item)
 
             weblink_txt = QtWidgets.QTextBrowser()
@@ -3839,6 +3843,10 @@ class BookmarkManager(QtWidgets.QWidget):
 
         self.mark_table_rows_for_actions()
 
+        self.app.defaults["global_bookmarks"].clear()
+        for key, val in self.bm_dict.items():
+            self.app.defaults["global_bookmarks"][key] = deepcopy(val)
+
     def on_add_entry(self, **kwargs):
         """
         Add a entry in the Bookmark Table and in the menu actions
@@ -3856,6 +3864,7 @@ class BookmarkManager(QtWidgets.QWidget):
             link = kwargs['link']
         else:
             link = self.link_entry.get_value()
+
         if link == 'http://':
             self.app.inform.emit(f'[ERROR_NOTCL] {_("Web link entry is empty.")}')
             return 'fail'
@@ -3863,23 +3872,29 @@ class BookmarkManager(QtWidgets.QWidget):
         # if 'http' not in link or 'https' not in link:
         #     link = 'http://' + link
 
-        if title in self.bm_dict.keys() or link in self.bm_dict.values():
-            self.app.inform.emit(f'[ERROR_NOTCL] {_("Either the Title or the Weblink already in the table.")}')
-            return 'fail'
+        for bookmark in self.bm_dict.values():
+            if title == bookmark[0] or link == bookmark[1]:
+                self.app.inform.emit(f'[ERROR_NOTCL] {_("Either the Title or the Weblink already in the table.")}')
+                return 'fail'
 
         # for some reason if the last char in the weblink is a slash it does not make the link clickable
         # so I remove it
         if link[-1] == '/':
             link = link[:-1]
         # add the new entry to storage
-        self.bm_dict[title] = link
+        new_entry = len(self.bm_dict) + 1
+        self.bm_dict[str(new_entry)] = [title, link]
+
+        # add the link to the menu but only if it is within the set limit
+        bm_limit = int(self.app.defaults["global_bookmarks_limit"])
+        if len(self.bm_dict) < bm_limit:
+            act = QtWidgets.QAction(parent=self.app.ui.menuhelp_bookmarks)
+            act.setText(title)
+            act.setIcon(QtGui.QIcon('share/link16.png'))
+            act.triggered.connect(lambda: webbrowser.open(link))
+            self.app.ui.menuhelp_bookmarks.insertAction(self.app.ui.menuhelp_bookmarks_manager, act)
 
-        # add the link to the menu
-        act = QtWidgets.QAction(parent=self.app.ui.menuhelp_bookmarks)
-        act.setText(title)
-        act.setIcon(QtGui.QIcon('share/link16.png'))
-        act.triggered.connect(lambda: webbrowser.open(link))
-        self.app.ui.menuhelp_bookmarks.insertAction(self.app.ui.menuhelp_bookmarks_manager, act)
+        self.app.inform.emit(f'[success] {_("Bookmark added.")}')
 
         # add the new entry to the bookmark manager table
         self.build_bm_ui()
@@ -3895,19 +3910,39 @@ class BookmarkManager(QtWidgets.QWidget):
             index_list.append(index)
             title_to_remove = self.table_widget.item(model_index.row(), 1).text()
 
-            if title_to_remove in list(self.bm_dict.keys()):
-                # remove from the storage
-                self.bm_dict.pop(title_to_remove, None)
-
-                for act in self.app.ui.menuhelp_bookmarks.actions():
-                    if act.text() == title_to_remove:
-                        # disconnect the signal
-                        try:
-                            act.triggered.disconnect()
-                        except TypeError:
-                            pass
-                        # remove the action from the menu
-                        self.app.ui.menuhelp_bookmarks.removeAction(act)
+            if title_to_remove == 'FlatCAM' or title_to_remove == 'Backup Site':
+                self.app.inform.emit('[WARNING_NOTCL] %s.' % _("This bookmark can not be removed"))
+                self.build_bm_ui()
+                return
+            else:
+                for k, bookmark in list(self.bm_dict.items()):
+                    if title_to_remove == bookmark[0]:
+                        # remove from the storage
+                        self.bm_dict.pop(k, None)
+
+                        for act in self.app.ui.menuhelp_bookmarks.actions():
+                            if act.text() == title_to_remove:
+                                # disconnect the signal
+                                try:
+                                    act.triggered.disconnect()
+                                except TypeError:
+                                    pass
+                                # remove the action from the menu
+                                self.app.ui.menuhelp_bookmarks.removeAction(act)
+
+        # house keeping: it pays to have keys increased by one
+        new_key = 0
+        new_dict = dict()
+        for k, v in self.bm_dict.items():
+            # we start with key 1 so we can use the len(self.bm_dict)
+            # when adding bookmarks (keys in bm_dict)
+            new_key += 1
+            new_dict[str(new_key)] = v
+
+        self.bm_dict = deepcopy(new_dict)
+        new_dict.clear()
+
+        self.app.inform.emit(f'[success] {_("Bookmark removed.")}')
 
         # for index in index_list:
         #     self.table_widget.model().removeRow(index.row())
@@ -4013,9 +4048,10 @@ class BookmarkManager(QtWidgets.QWidget):
             title = self.table_widget.item(row, 1).text()
             wlink = self.table_widget.cellWidget(row, 2).toPlainText()
 
+            entry = int(row) + 1
             self.bm_dict.update(
                 {
-                    title: wlink
+                    str(entry): [title, wlink]
                 }
             )
 

+ 15 - 1
flatcamGUI/GUIElements.py

@@ -1711,7 +1711,7 @@ class FCTable(QtWidgets.QTableWidget):
 
     drag_drop_sig = pyqtSignal()
 
-    def __init__(self, drag_drop=False, parent=None):
+    def __init__(self, drag_drop=False, protected_rows=None, parent=None):
         super(FCTable, self).__init__(parent)
 
         if drag_drop:
@@ -1725,6 +1725,14 @@ class FCTable(QtWidgets.QTableWidget):
             self.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
             self.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove)
 
+        self.rows_not_for_drag_and_drop = list()
+        if protected_rows:
+            try:
+                for r in protected_rows:
+                    self.rows_not_for_drag_and_drop.append(r)
+            except TypeError:
+                self.rows_not_for_drag_and_drop = [protected_rows]
+
         self.rows_to_move = list()
 
     def sizeHint(self):
@@ -1843,6 +1851,12 @@ class FCTable(QtWidgets.QTableWidget):
         """
         if event.source() == self:
             rows = set([mi.row() for mi in self.selectedIndexes()])
+
+            # if one of the selected rows for drag and drop is within the protected list, return
+            for r in rows:
+                if r in self.rows_not_for_drag_and_drop:
+                    return
+
             targetRow = self.indexAt(event.pos()).row()
             rows.discard(targetRow)
             rows = sorted(rows)