Просмотр исходного кода

Merged in marius_stanciu/flatcam_beta/Beta (pull request #171)

Beta
Marius Stanciu 6 лет назад
Родитель
Сommit
af5c8f8f3c

+ 211 - 15
FlatCAMApp.py

@@ -255,6 +255,15 @@ class App(QtCore.QObject):
             json.dump([], f)
             json.dump([], f)
             f.close()
             f.close()
 
 
+        try:
+            fp = open(self.data_path + '/recent_projects.json')
+            fp.close()
+        except IOError:
+            App.log.debug('Creating empty recent_projects.json')
+            fp = open(self.data_path + '/recent_projects.json', 'w')
+            json.dump([], fp)
+            fp.close()
+
         # Application directory. CHDIR to it. Otherwise, trying to load
         # Application directory. CHDIR to it. Otherwise, trying to load
         # GUI icons will fail as their path is relative.
         # GUI icons will fail as their path is relative.
         # This will fail under cx_freeze ...
         # This will fail under cx_freeze ...
@@ -294,6 +303,8 @@ class App(QtCore.QObject):
         # ### Data ####
         # ### Data ####
         # #############
         # #############
         self.recent = []
         self.recent = []
+        self.recent_projects = []
+
         self.clipboard = QtWidgets.QApplication.clipboard()
         self.clipboard = QtWidgets.QApplication.clipboard()
         self.proc_container = FCVisibleProcessContainer(self.ui.activity_view)
         self.proc_container = FCVisibleProcessContainer(self.ui.activity_view)
 
 
@@ -1499,6 +1510,7 @@ class App(QtCore.QObject):
         self.ui.general_defaults_form.general_app_group.units_radio.activated_custom.connect(
         self.ui.general_defaults_form.general_app_group.units_radio.activated_custom.connect(
             lambda: self.on_toggle_units(no_pref=False))
             lambda: self.on_toggle_units(no_pref=False))
 
 
+
         # ##############################
         # ##############################
         # ### GUI PREFERENCES SIGNALS ##
         # ### GUI PREFERENCES SIGNALS ##
         # ##############################
         # ##############################
@@ -1960,6 +1972,9 @@ class App(QtCore.QObject):
         # Variable to store the GCODE that was edited
         # Variable to store the GCODE that was edited
         self.gcode_edited = ""
         self.gcode_edited = ""
 
 
+        # if Preferences are changed in the Edit -> Preferences tab the value will be set to True
+        self.preferences_changed_flag = False
+
         self.grb_list = ['gbr', 'ger', 'gtl', 'gbl', 'gts', 'gbs', 'gtp', 'gbp', 'gto', 'gbo', 'gm1', 'gm2', 'gm3',
         self.grb_list = ['gbr', 'ger', 'gtl', 'gbl', 'gts', 'gbs', 'gtp', 'gbp', 'gto', 'gbo', 'gm1', 'gm2', 'gm3',
                          'gko', 'cmp', 'sol', 'stc', 'sts', 'plc', 'pls', 'crc', 'crs', 'tsm', 'bsm', 'ly2', 'ly15',
                          'gko', 'cmp', 'sol', 'stc', 'sts', 'plc', 'pls', 'crc', 'crs', 'tsm', 'bsm', 'ly2', 'ly15',
                          'dim', 'mil', 'grb', 'top', 'bot', 'smt', 'smb', 'sst', 'ssb', 'spt', 'spb', 'pho', 'gdo',
                          'dim', 'mil', 'grb', 'top', 'bot', 'smt', 'smb', 'sst', 'ssb', 'spt', 'spb', 'pho', 'gdo',
@@ -2922,12 +2937,19 @@ class App(QtCore.QObject):
         record = {'kind': str(kind), 'filename': str(filename)}
         record = {'kind': str(kind), 'filename': str(filename)}
         if record in self.recent:
         if record in self.recent:
             return
             return
-
-        self.recent.insert(0, record)
+        if record in self.recent_projects:
+            return
+        if record['kind'] == 'project':
+            self.recent_projects.insert(0, record)
+        else:
+            self.recent.insert(0, record)
 
 
         if len(self.recent) > self.defaults['global_recent_limit']:  # Limit reached
         if len(self.recent) > self.defaults['global_recent_limit']:  # Limit reached
             self.recent.pop()
             self.recent.pop()
 
 
+        if len(self.recent_projects) > self.defaults['global_recent_limit']:  # Limit reached
+            self.recent_projects.pop()
+
         try:
         try:
             f = open(self.data_path + '/recent.json', 'w')
             f = open(self.data_path + '/recent.json', 'w')
         except IOError:
         except IOError:
@@ -2938,6 +2960,16 @@ class App(QtCore.QObject):
         json.dump(self.recent, f, default=to_dict, indent=2, sort_keys=True)
         json.dump(self.recent, f, default=to_dict, indent=2, sort_keys=True)
         f.close()
         f.close()
 
 
+        try:
+            fp = open(self.data_path + '/recent_projects.json', 'w')
+        except IOError:
+            App.log.error("Failed to open recent items file for writing.")
+            self.inform.emit(_('[ERROR_NOTCL] Failed to open recent projects file for writing.'))
+            return
+
+        json.dump(self.recent_projects, fp, default=to_dict, indent=2, sort_keys=True)
+        fp.close()
+
         # Re-build the recent items menu
         # Re-build the recent items menu
         self.setup_recent_items()
         self.setup_recent_items()
 
 
@@ -4541,6 +4573,7 @@ class App(QtCore.QObject):
 
 
     def on_save_button(self):
     def on_save_button(self):
         log.debug("App.on_save_button() --> Saving preferences to file.")
         log.debug("App.on_save_button() --> Saving preferences to file.")
+        self.preferences_changed_flag = False
 
 
         self.save_defaults(silent=False)
         self.save_defaults(silent=False)
         # load the defaults so they are updated into the app
         # load the defaults so they are updated into the app
@@ -5133,7 +5166,6 @@ class App(QtCore.QObject):
                 self.draw_selection_shape(curr_sel_obj)
                 self.draw_selection_shape(curr_sel_obj)
 
 
     def on_preferences(self):
     def on_preferences(self):
-
         # add the tab if it was closed
         # add the tab if it was closed
         self.ui.plot_tab_area.addTab(self.ui.preferences_tab, _("Preferences"))
         self.ui.plot_tab_area.addTab(self.ui.preferences_tab, _("Preferences"))
 
 
@@ -5145,6 +5177,115 @@ class App(QtCore.QObject):
         self.ui.plot_tab_area.setCurrentWidget(self.ui.preferences_tab)
         self.ui.plot_tab_area.setCurrentWidget(self.ui.preferences_tab)
         self.ui.show()
         self.ui.show()
 
 
+        # this disconnect() is done so the slot will be connected only once
+        try:
+            self.ui.plot_tab_area.tab_closed_signal.disconnect(self.on_preferences_closed)
+        except TypeError:
+            pass
+        self.ui.plot_tab_area.tab_closed_signal.connect(self.on_preferences_closed)
+
+        # detect changes in the preferences
+        for idx in range(self.ui.pref_tab_area.count()):
+            for tb in self.ui.pref_tab_area.widget(idx).findChildren(QtCore.QObject):
+                try:
+                    try:
+                        tb.textEdited.disconnect()
+                    except TypeError:
+                        pass
+                    tb.textEdited.connect(self.on_preferences_edited)
+                except AttributeError:
+                    pass
+
+                try:
+                    try:
+                        tb.modificationChanged.disconnect()
+                    except TypeError:
+                        pass
+                    tb.modificationChanged.connect(self.on_preferences_edited)
+                except AttributeError:
+                    pass
+
+                try:
+                    try:
+                        tb.toggled.disconnect()
+                    except TypeError:
+                        pass
+                    tb.toggled.connect(self.on_preferences_edited)
+                except AttributeError:
+                    pass
+
+                try:
+                    try:
+                        tb.valueChanged.disconnect()
+                    except TypeError:
+                        pass
+                    tb.valueChanged.connect(self.on_preferences_edited)
+                except AttributeError:
+                    pass
+
+                try:
+                    try:
+                        tb.currentIndexChanged.disconnect()
+                    except TypeError:
+                        pass
+                    tb.currentIndexChanged.connect(self.on_preferences_edited)
+                except AttributeError:
+                    pass
+
+    def on_preferences_edited(self):
+        self.inform.emit(_("[WARNING_NOTCL] Preferences edited but not saved."))
+        self.preferences_changed_flag = True
+
+    def on_preferences_closed(self):
+        # disconnect
+        for idx in range(self.ui.pref_tab_area.count()):
+            for tb in self.ui.pref_tab_area.widget(idx).findChildren(QtCore.QObject):
+                try:
+                    tb.textEdited.disconnect()
+                except (TypeError, AttributeError):
+                    pass
+
+                try:
+                    tb.modificationChanged.disconnect()
+                except (TypeError, AttributeError):
+                    pass
+
+                try:
+                    tb.toggled.disconnect()
+                except (TypeError, AttributeError):
+                    pass
+
+                try:
+                    tb.valueChanged.disconnect()
+                except (TypeError, AttributeError):
+                    pass
+
+                try:
+                    tb.currentIndexChanged.disconnect()
+                except (TypeError, AttributeError):
+                    pass
+
+        if self.preferences_changed_flag is True:
+            msgbox = QtWidgets.QMessageBox()
+            msgbox.setText(_("One or more values are changed.\n"
+                             "Do you want to save the Preferences?"))
+            msgbox.setWindowTitle(_("Save Preferences"))
+            msgbox.setWindowIcon(QtGui.QIcon('share/save_as.png'))
+
+            bt_yes = msgbox.addButton(_('Yes'), QtWidgets.QMessageBox.YesRole)
+            bt_no = msgbox.addButton(_('No'), QtWidgets.QMessageBox.NoRole)
+
+            msgbox.setDefaultButton(bt_yes)
+            msgbox.exec_()
+            response = msgbox.clickedButton()
+
+            if response == bt_yes:
+                self.on_save_button()
+                self.inform.emit(_("[success] Defaults saved."))
+            else:
+                self.preferences_changed_flag = False
+                return
+
     def on_flipy(self):
     def on_flipy(self):
         self.report_usage("on_flipy()")
         self.report_usage("on_flipy()")
 
 
@@ -8253,7 +8394,7 @@ class App(QtCore.QObject):
             'pdf': lambda fname: self.worker_task.emit({'fcn': self.pdf_tool.open_pdf, 'params': [fname]})
             'pdf': lambda fname: self.worker_task.emit({'fcn': self.pdf_tool.open_pdf, 'params': [fname]})
         }
         }
 
 
-        # Open file
+        # Open recent file for files
         try:
         try:
             f = open(self.data_path + '/recent.json')
             f = open(self.data_path + '/recent.json')
         except IOError:
         except IOError:
@@ -8270,6 +8411,23 @@ class App(QtCore.QObject):
             return
             return
         f.close()
         f.close()
 
 
+        # Open recent file for projects
+        try:
+            fp = open(self.data_path + '/recent_projects.json')
+        except IOError:
+            App.log.error("Failed to load recent project item list.")
+            self.inform.emit(_("[ERROR_NOTCL] Failed to load recent projects item list."))
+            return
+
+        try:
+            self.recent_projects = json.load(fp)
+        except json.scanner.JSONDecodeError:
+            App.log.error("Failed to parse recent project item list.")
+            self.inform.emit(_("[ERROR_NOTCL] Failed to parse recent project item list."))
+            fp.close()
+            return
+        fp.close()
+
         # Closure needed to create callbacks in a loop.
         # Closure needed to create callbacks in a loop.
         # Otherwise late binding occurs.
         # Otherwise late binding occurs.
         def make_callback(func, fname):
         def make_callback(func, fname):
@@ -8277,7 +8435,7 @@ class App(QtCore.QObject):
                 func(fname)
                 func(fname)
             return opener
             return opener
 
 
-        def reset_recent():
+        def reset_recent_files():
             # Reset menu
             # Reset menu
             self.ui.recent.clear()
             self.ui.recent.clear()
             self.recent = []
             self.recent = []
@@ -8289,28 +8447,66 @@ class App(QtCore.QObject):
 
 
             json.dump(self.recent, f)
             json.dump(self.recent, f)
 
 
+        def reset_recent_projects():
+            # Reset menu
+            self.ui.recent_projects.clear()
+            self.recent_projects = []
+
+            try:
+                fp = open(self.data_path + '/recent_projects.json', 'w')
+            except IOError:
+                App.log.error("Failed to open recent projects items file for writing.")
+                return
+
+            json.dump(self.recent, fp)
+
         # Reset menu
         # Reset menu
         self.ui.recent.clear()
         self.ui.recent.clear()
+        self.ui.recent_projects.clear()
+
+        # Create menu items for projects
+        for recent in self.recent_projects:
+            filename = recent['filename'].split('/')[-1].split('\\')[-1]
+
+            if recent['kind'] == 'project':
+                try:
+                    action = QtWidgets.QAction(QtGui.QIcon(icons[recent["kind"]]), filename, self)
+
+                    # Attach callback
+                    o = make_callback(openers[recent["kind"]], recent['filename'])
+                    action.triggered.connect(o)
+
+                    self.ui.recent_projects.addAction(action)
+
+                except KeyError:
+                    App.log.error("Unsupported file type: %s" % recent["kind"])
 
 
-        # Create menu items
+        # Last action in Recent Files menu is one that Clear the content
+        clear_action_proj = QtWidgets.QAction(QtGui.QIcon('share/trash32.png'), (_("Clear Recent files")), self)
+        clear_action_proj.triggered.connect(reset_recent_projects)
+        self.ui.recent_projects.addSeparator()
+        self.ui.recent_projects.addAction(clear_action_proj)
+
+        # Create menu items for files
         for recent in self.recent:
         for recent in self.recent:
             filename = recent['filename'].split('/')[-1].split('\\')[-1]
             filename = recent['filename'].split('/')[-1].split('\\')[-1]
 
 
-            try:
-                action = QtWidgets.QAction(QtGui.QIcon(icons[recent["kind"]]), filename, self)
+            if recent['kind'] != 'project':
+                try:
+                    action = QtWidgets.QAction(QtGui.QIcon(icons[recent["kind"]]), filename, self)
 
 
-                # Attach callback
-                o = make_callback(openers[recent["kind"]], recent['filename'])
-                action.triggered.connect(o)
+                    # Attach callback
+                    o = make_callback(openers[recent["kind"]], recent['filename'])
+                    action.triggered.connect(o)
 
 
-                self.ui.recent.addAction(action)
+                    self.ui.recent.addAction(action)
 
 
-            except KeyError:
-                App.log.error("Unsupported file type: %s" % recent["kind"])
+                except KeyError:
+                    App.log.error("Unsupported file type: %s" % recent["kind"])
 
 
         # Last action in Recent Files menu is one that Clear the content
         # Last action in Recent Files menu is one that Clear the content
         clear_action = QtWidgets.QAction(QtGui.QIcon('share/trash32.png'), (_("Clear Recent files")), self)
         clear_action = QtWidgets.QAction(QtGui.QIcon('share/trash32.png'), (_("Clear Recent files")), self)
-        clear_action.triggered.connect(reset_recent)
+        clear_action.triggered.connect(reset_recent_files)
         self.ui.recent.addSeparator()
         self.ui.recent.addSeparator()
         self.ui.recent.addAction(clear_action)
         self.ui.recent.addAction(clear_action)
 
 

+ 10 - 0
README.md

@@ -9,6 +9,16 @@ CAD program, and create G-Code for Isolation routing.
 
 
 =================================================
 =================================================
 
 
+31.07.2019
+
+- changed the order of the menu entries in the FIle -> Open ...
+- organized the list of recent files so the Project entries are to the top and separated from the other types of file
+- work on identification of changes in Preferences tab
+- added categories names for the recent files
+- added a detection if any values are changed in the Edit -> Preferences window and on close it will ask the user if he wants to save the changes or not
+- created a new menu entry in the File menu named Recent projects that will hold the recent projects and the previous "Recent files" will hold only the previous loaded files
+- updated all translations for the new strings
+
 30.07.2019
 30.07.2019
 
 
 - fixed bug that crashed the software when trying to edit a GUI value in Geometry selected tab without having a tool in the Tools Table
 - fixed bug that crashed the software when trying to edit a GUI value in Geometry selected tab without having a tool in the Tools Table

+ 17 - 14
flatcamGUI/FlatCAMGUI.py

@@ -79,13 +79,16 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         self.menufile_open = self.menufile.addMenu(QtGui.QIcon('share/folder32_bis.png'), _('Open'))
         self.menufile_open = self.menufile.addMenu(QtGui.QIcon('share/folder32_bis.png'), _('Open'))
         self.menufile_open.setToolTipsVisible(True)
         self.menufile_open.setToolTipsVisible(True)
 
 
-        # Open gerber ...
+        # Open Project ...
+        self.menufileopenproject = QtWidgets.QAction(QtGui.QIcon('share/folder16.png'), _('Open &Project ...'), self)
+        self.menufile_open.addAction(self.menufileopenproject)
+        self.menufile_open.addSeparator()
+
+        # Open Gerber ...
         self.menufileopengerber = QtWidgets.QAction(QtGui.QIcon('share/flatcam_icon24.png'),
         self.menufileopengerber = QtWidgets.QAction(QtGui.QIcon('share/flatcam_icon24.png'),
                                                     _('Open &Gerber ...\tCTRL+G'), self)
                                                     _('Open &Gerber ...\tCTRL+G'), self)
         self.menufile_open.addAction(self.menufileopengerber)
         self.menufile_open.addAction(self.menufileopengerber)
 
 
-        self.menufile_open.addSeparator()
-
         # Open Excellon ...
         # Open Excellon ...
         self.menufileopenexcellon = QtWidgets.QAction(QtGui.QIcon('share/open_excellon32.png'),
         self.menufileopenexcellon = QtWidgets.QAction(QtGui.QIcon('share/open_excellon32.png'),
                                                       _('Open &Excellon ...\tCTRL+E'), self)
                                                       _('Open &Excellon ...\tCTRL+E'), self)
@@ -95,10 +98,6 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         self.menufileopengcode = QtWidgets.QAction(QtGui.QIcon('share/code.png'), _('Open G-&Code ...'), self)
         self.menufileopengcode = QtWidgets.QAction(QtGui.QIcon('share/code.png'), _('Open G-&Code ...'), self)
         self.menufile_open.addAction(self.menufileopengcode)
         self.menufile_open.addAction(self.menufileopengcode)
 
 
-        # Open Project ...
-        self.menufileopenproject = QtWidgets.QAction(QtGui.QIcon('share/folder16.png'), _('Open &Project ...'), self)
-        self.menufile_open.addAction(self.menufileopenproject)
-
         self.menufile_open.addSeparator()
         self.menufile_open.addSeparator()
 
 
         # Open Config File...
         # Open Config File...
@@ -106,6 +105,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         self.menufile_open.addAction(self.menufileopenconfig)
         self.menufile_open.addAction(self.menufileopenconfig)
 
 
         # Recent
         # Recent
+        self.recent_projects = self.menufile.addMenu(QtGui.QIcon('share/recent_files.png'), _("Recent projects"))
         self.recent = self.menufile.addMenu(QtGui.QIcon('share/recent_files.png'), _("Recent files"))
         self.recent = self.menufile.addMenu(QtGui.QIcon('share/recent_files.png'), _("Recent files"))
 
 
         # Separator
         # Separator
@@ -757,10 +757,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         self.snap_max_dist_entry.setToolTip(_("Max. magnet distance"))
         self.snap_max_dist_entry.setToolTip(_("Max. magnet distance"))
         self.snap_magnet = self.snap_toolbar.addWidget(self.snap_max_dist_entry)
         self.snap_magnet = self.snap_toolbar.addWidget(self.snap_max_dist_entry)
 
 
-
-        ############## ##
+        # ############# ##
         # ## Notebook # ##
         # ## Notebook # ##
-        ############## ##
+        # ############# ##
 
 
         # ## Project # ##
         # ## Project # ##
         # self.project_tab = QtWidgets.QWidget()
         # self.project_tab = QtWidgets.QWidget()
@@ -811,7 +810,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         self.right_lay.setContentsMargins(0, 0, 0, 0)
         self.right_lay.setContentsMargins(0, 0, 0, 0)
         self.right_widget.setLayout(self.right_lay)
         self.right_widget.setLayout(self.right_lay)
         # self.plot_tab_area = FCTab()
         # self.plot_tab_area = FCTab()
-        self.plot_tab_area = FCDetachableTab(protect=False, protect_by_name=[_('Plot Area')])
+        self.plot_tab_area = FCDetachableTab2(protect=False, protect_by_name=[_('Plot Area')])
         self.plot_tab_area.useOldIndex(True)
         self.plot_tab_area.useOldIndex(True)
 
 
         self.right_lay.addWidget(self.plot_tab_area)
         self.right_lay.addWidget(self.plot_tab_area)
@@ -828,9 +827,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         # remove the close button from the Plot Area tab (first tab index = 0) as this one will always be ON
         # remove the close button from the Plot Area tab (first tab index = 0) as this one will always be ON
         self.plot_tab_area.protectTab(0)
         self.plot_tab_area.protectTab(0)
 
 
-        ###################################### ##
+        # ##################################### ##
         # ## HERE WE BUILD THE PREF. TAB AREA # ##
         # ## HERE WE BUILD THE PREF. TAB AREA # ##
-        ###################################### ##
+        # ##################################### ##
         self.preferences_tab = QtWidgets.QWidget()
         self.preferences_tab = QtWidgets.QWidget()
         self.pref_tab_layout = QtWidgets.QVBoxLayout(self.preferences_tab)
         self.pref_tab_layout = QtWidgets.QVBoxLayout(self.preferences_tab)
         self.pref_tab_layout.setContentsMargins(2, 2, 2, 2)
         self.pref_tab_layout.setContentsMargins(2, 2, 2, 2)
@@ -843,6 +842,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         self.pref_tab_layout.addWidget(self.pref_tab_area)
         self.pref_tab_layout.addWidget(self.pref_tab_area)
 
 
         self.general_tab = QtWidgets.QWidget()
         self.general_tab = QtWidgets.QWidget()
+        self.general_tab.setObjectName("general_tab")
         self.pref_tab_area.addTab(self.general_tab, _("General"))
         self.pref_tab_area.addTab(self.general_tab, _("General"))
         self.general_tab_lay = QtWidgets.QVBoxLayout()
         self.general_tab_lay = QtWidgets.QVBoxLayout()
         self.general_tab_lay.setContentsMargins(2, 2, 2, 2)
         self.general_tab_lay.setContentsMargins(2, 2, 2, 2)
@@ -864,6 +864,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         self.general_tab_lay.addWidget(self.general_scroll_area)
         self.general_tab_lay.addWidget(self.general_scroll_area)
 
 
         self.gerber_tab = QtWidgets.QWidget()
         self.gerber_tab = QtWidgets.QWidget()
+        self.gerber_tab.setObjectName("gerber_tab")
         self.pref_tab_area.addTab(self.gerber_tab, _("GERBER"))
         self.pref_tab_area.addTab(self.gerber_tab, _("GERBER"))
         self.gerber_tab_lay = QtWidgets.QVBoxLayout()
         self.gerber_tab_lay = QtWidgets.QVBoxLayout()
         self.gerber_tab_lay.setContentsMargins(2, 2, 2, 2)
         self.gerber_tab_lay.setContentsMargins(2, 2, 2, 2)
@@ -873,6 +874,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         self.gerber_tab_lay.addWidget(self.gerber_scroll_area)
         self.gerber_tab_lay.addWidget(self.gerber_scroll_area)
 
 
         self.excellon_tab = QtWidgets.QWidget()
         self.excellon_tab = QtWidgets.QWidget()
+        self.excellon_tab.setObjectName("excellon_tab")
         self.pref_tab_area.addTab(self.excellon_tab, _("EXCELLON"))
         self.pref_tab_area.addTab(self.excellon_tab, _("EXCELLON"))
         self.excellon_tab_lay = QtWidgets.QVBoxLayout()
         self.excellon_tab_lay = QtWidgets.QVBoxLayout()
         self.excellon_tab_lay.setContentsMargins(2, 2, 2, 2)
         self.excellon_tab_lay.setContentsMargins(2, 2, 2, 2)
@@ -882,6 +884,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         self.excellon_tab_lay.addWidget(self.excellon_scroll_area)
         self.excellon_tab_lay.addWidget(self.excellon_scroll_area)
 
 
         self.geometry_tab = QtWidgets.QWidget()
         self.geometry_tab = QtWidgets.QWidget()
+        self.geometry_tab.setObjectName("geometry_tab")
         self.pref_tab_area.addTab(self.geometry_tab, _("GEOMETRY"))
         self.pref_tab_area.addTab(self.geometry_tab, _("GEOMETRY"))
         self.geometry_tab_lay = QtWidgets.QVBoxLayout()
         self.geometry_tab_lay = QtWidgets.QVBoxLayout()
         self.geometry_tab_lay.setContentsMargins(2, 2, 2, 2)
         self.geometry_tab_lay.setContentsMargins(2, 2, 2, 2)
@@ -2484,7 +2487,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
                 if key == QtCore.Qt.Key_3 or key == '3':
                 if key == QtCore.Qt.Key_3 or key == '3':
                     self.app.on_select_tab('tool')
                     self.app.on_select_tab('tool')
 
 
-                if self.app.geo_editor.active_tool is not None and self.geo_select_btn.isChecked() == False:
+                if self.app.geo_editor.active_tool is not None and self.geo_select_btn.isChecked() is False:
                     response = self.app.geo_editor.active_tool.on_key(key=key)
                     response = self.app.geo_editor.active_tool.on_key(key=key)
                     if response is not None:
                     if response is not None:
                         self.app.inform.emit(response)
                         self.app.inform.emit(response)

+ 23 - 0
flatcamGUI/GUIElements.py

@@ -884,6 +884,7 @@ class FCDetachableTab(QtWidgets.QTabWidget):
         :param currentIndex:
         :param currentIndex:
         :return:
         :return:
         """
         """
+
         self.removeTab(currentIndex)
         self.removeTab(currentIndex)
 
 
     def protectTab(self, currentIndex):
     def protectTab(self, currentIndex):
@@ -1348,6 +1349,28 @@ class FCDetachableTab(QtWidgets.QTabWidget):
             self.detachedTabDropSignal.emit(name, index, dropPos)
             self.detachedTabDropSignal.emit(name, index, dropPos)
 
 
 
 
+class FCDetachableTab2(FCDetachableTab):
+    tab_closed_signal = pyqtSignal()
+
+    def __init__(self, protect=None, protect_by_name=None, parent=None):
+        super(FCDetachableTab2, self).__init__(protect=protect, protect_by_name=protect_by_name, parent=parent)
+
+    def closeTab(self, currentIndex):
+        """
+        Slot connected to the tabCloseRequested signal
+
+        :param currentIndex:
+        :return:
+        """
+        idx = self.currentIndex()
+
+        # emit the signal only if the name is the one we want; the name should be a parameter somehow
+        if self.tabText(idx) == _("Preferences"):
+            self.tab_closed_signal.emit()
+
+        self.removeTab(currentIndex)
+
+
 class VerticalScrollArea(QtWidgets.QScrollArea):
 class VerticalScrollArea(QtWidgets.QScrollArea):
     """
     """
     This widget extends QtGui.QScrollArea to make a vertical-only
     This widget extends QtGui.QScrollArea to make a vertical-only

BIN
locale/de/LC_MESSAGES/strings.mo


Разница между файлами не показана из-за своего большого размера
+ 211 - 189
locale/de/LC_MESSAGES/strings.po


BIN
locale/en/LC_MESSAGES/strings.mo


Разница между файлами не показана из-за своего большого размера
+ 211 - 189
locale/en/LC_MESSAGES/strings.po


BIN
locale/es/LC_MESSAGES/strings.mo


Разница между файлами не показана из-за своего большого размера
+ 210 - 189
locale/es/LC_MESSAGES/strings.po


BIN
locale/pt_BR/LC_MESSAGES/strings.mo


Разница между файлами не показана из-за своего большого размера
+ 217 - 193
locale/pt_BR/LC_MESSAGES/strings.po


BIN
locale/ro/LC_MESSAGES/strings.mo


Разница между файлами не показана из-за своего большого размера
+ 211 - 189
locale/ro/LC_MESSAGES/strings.po


BIN
locale/ru/LC_MESSAGES/strings.mo


Разница между файлами не показана из-за своего большого размера
+ 208 - 188
locale/ru/LC_MESSAGES/strings.po


Разница между файлами не показана из-за своего большого размера
+ 232 - 214
locale_template/strings.pot


Некоторые файлы не были показаны из-за большого количества измененных файлов