Explorar o código

- fixed bug in saving the maximized state
- fixed bug in applying default language on first start
- on activating 'V' key shortcut (zoom fit) the mouse cursor is now jumping to origin (0, 0)
- fixed bug in saving toolbars state; the file was saved before setting the self.defaults['global_toolbar_view]

Marius Stanciu %!s(int64=6) %!d(string=hai) anos
pai
achega
e8a0fcaef1

+ 57 - 49
FlatCAMApp.py

@@ -629,7 +629,7 @@ class App(QtCore.QObject):
             "global_def_win_y": 100,
             "global_def_win_w": 1024,
             "global_def_win_h": 650,
-
+            "global_def_notebook_width": 1,
             # Constants...
             "global_defaults_save_period_ms": 20000,  # Time between default saves.
             "global_shell_shape": [500, 300],  # Shape of the shell in pixels.
@@ -1847,7 +1847,7 @@ class App(QtCore.QObject):
         if not factory_defaults:
             self.save_factory_defaults(silent=False)
             # ONLY AT FIRST STARTUP INIT THE GUI LAYOUT TO 'COMPACT'
-            initial_lay = 'Compact'
+            initial_lay = 'compact'
             self.on_layout(index=None, lay=initial_lay)
             # Set the combobox in Preferences to the current layout
             idx = self.ui.general_defaults_form.general_gui_set_group.layout_combo.findText(initial_lay)
@@ -2675,7 +2675,7 @@ class App(QtCore.QObject):
         self.defaults["global_def_win_y"] = y
         self.defaults["global_def_win_w"] = width
         self.defaults["global_def_win_h"] = height
-        self.defaults["def_notebook_width"] = notebook_width
+        self.defaults["global_def_notebook_width"] = notebook_width
         self.save_defaults()
 
     def message_dialog(self, title, message, kind="info"):
@@ -3084,15 +3084,6 @@ class App(QtCore.QObject):
         defaults.update(self.defaults)
         self.propagate_defaults(silent=True)
 
-        # Save update options
-        try:
-            f = open(self.data_path + "/current_defaults.FlatConfig", "w")
-            json.dump(defaults, f, default=to_dict, indent=2, sort_keys=True)
-            f.close()
-        except:
-            self.inform.emit(_("[ERROR_NOTCL] Failed to write defaults to file."))
-            return
-
         # Save the toolbar view
         tb_status = 0
         if self.ui.toolbarfile.isVisible():
@@ -3124,6 +3115,15 @@ class App(QtCore.QObject):
 
         self.defaults["global_toolbar_view"] = tb_status
 
+        # Save update options
+        try:
+            f = open(self.data_path + "/current_defaults.FlatConfig", "w")
+            json.dump(defaults, f, default=to_dict, indent=2, sort_keys=True)
+            f.close()
+        except:
+            self.inform.emit(_("[ERROR_NOTCL] Failed to write defaults to file."))
+            return
+
         if not silent:
             self.inform.emit(_("[success] Defaults saved."))
 
@@ -3201,7 +3201,7 @@ class App(QtCore.QObject):
             elif response == QtWidgets.QMessageBox.Cancel:
                 return
         else:
-            QtWidgets.qApp.quit()
+            self.quit_application()
 
     def quit_application(self):
         self.save_defaults()
@@ -4009,7 +4009,7 @@ class App(QtCore.QObject):
         except:
             pass
 
-        if current_layout == 'Standard':
+        if current_layout == 'standard':
             ### TOOLBAR INSTALLATION ###
             self.ui.toolbarfile = QtWidgets.QToolBar('File Toolbar')
             self.ui.toolbarfile.setObjectName('File_TB')
@@ -4053,7 +4053,7 @@ class App(QtCore.QObject):
 
             self.ui.corner_snap_btn.setVisible(False)
             self.ui.snap_magnet.setVisible(False)
-        elif current_layout == 'Compact':
+        elif current_layout == 'compact':
             ### TOOLBAR INSTALLATION ###
             self.ui.toolbarfile = QtWidgets.QToolBar('File Toolbar')
             self.ui.toolbarfile.setObjectName('File_TB')
@@ -4405,7 +4405,7 @@ class App(QtCore.QObject):
 
         self.plotcanvas.vis_connect('mouse_press', self.on_set_zero_click)
 
-    def on_jump_to(self):
+    def on_jump_to(self, custom_location=None):
         """
         Jump to a location by setting the mouse cursor location
         :return:
@@ -4413,20 +4413,23 @@ class App(QtCore.QObject):
         """
         self.report_usage("on_jump_to()")
 
-        dia_box = Dialog_box(title=_("Jump to ..."),
-                             label=_("Enter the coordinates in format X,Y:"),
-                             icon=QtGui.QIcon('share/jump_to16.png'))
+        if custom_location is None:
+            dia_box = Dialog_box(title=_("Jump to ..."),
+                                 label=_("Enter the coordinates in format X,Y:"),
+                                 icon=QtGui.QIcon('share/jump_to16.png'))
 
-        if dia_box.ok is True:
-            try:
-                location = eval(dia_box.location)
-                if not isinstance(location, tuple):
-                    self.inform.emit(_("Wrong coordinates. Enter coordinates in format: X,Y"))
+            if dia_box.ok is True:
+                try:
+                    location = eval(dia_box.location)
+                    if not isinstance(location, tuple):
+                        self.inform.emit(_("Wrong coordinates. Enter coordinates in format: X,Y"))
+                        return
+                except:
                     return
-            except:
+            else:
                 return
         else:
-            return
+            location = custom_location
 
         self.plotcanvas.fit_center(loc=location)
 
@@ -7270,15 +7273,15 @@ class App(QtCore.QObject):
                                 self.defaults["global_def_win_y"],
                                 self.defaults["global_def_win_w"],
                                 self.defaults["global_def_win_h"])
-            self.ui.splitter.setSizes([self.defaults["def_notebook_width"], 0])
+            self.ui.splitter.setSizes([self.defaults["global_def_notebook_width"], 0])
 
             settings = QSettings("Open Source", "FlatCAM")
             if settings.contains("maximized_gui"):
                 maximized_ui = settings.value('maximized_gui', type=bool)
                 if maximized_ui is True:
                     self.ui.showMaximized()
-        except KeyError:
-            pass
+        except KeyError as e:
+            log.debug("App.restore_main_win_geom() --> %s" % str(e))
 
     def plot_all(self, zoom=True):
         """
@@ -7951,31 +7954,36 @@ The normal flow when working in FlatCAM is the following:</span></p>
                     self.inform.emit(_("[ERROR_NOTCL] Failed to save project file: %s. Retry to save it.") % filename)
 
             if quit:
-                t = threading.Thread(target=lambda: self.check_project_file_size(1, filename=filename))
-                t.start()
+                # t = threading.Thread(target=lambda: self.check_project_file_size(1, filename=filename))
+                # t.start()
+                self.start_delayed_quit(delay=500, filename=filename)
 
-    def check_project_file_size(self, delay, filename):
+    def start_delayed_quit(self, delay, filename):
         """
-        Using Alfe's answer from here:
-        https://stackoverflow.com/questions/474528/what-is-the-best-way-to-repeatedly-execute-a-function-every-x-seconds-in-python
 
-        :param delay: period of checking if project file size is more than zero; in seconds
-        :param filename: the name of the project file to be checked for size more than zero
+        :param delay:       period of checking if project file size is more than zero; in seconds
+        :param filename:    the name of the project file to be checked periodically for size more than zero
         :return:
         """
-        next_time = time.time() + delay
-        while True:
-            time.sleep(max(0, next_time - time.time()))
-            try:
-                statinfo = os.stat(filename)
-                if statinfo:
-                    self.app_quit.emit()
-            except Exception:
-                traceback.print_exc()
-                # in production code you might want to have this instead of course:
-                # logger.exception("Problem while executing repetitive task.")
-            # skip tasks if we are behind schedule:
-            next_time += (time.time() - next_time) // delay * delay + delay
+
+        self.quit_timer = QtCore.QTimer()
+        self.quit_timer.setInterval(delay)
+        self.quit_timer.timeout.connect(lambda : self.check_project_file_size(filename=filename))
+        self.quit_timer.start()
+
+    def check_project_file_size(self, filename):
+        """
+
+        :param filename: the name of the project file to be checked periodically for size more than zero
+        :return:
+        """
+
+        try:
+            if os.stat(filename).st_size > 0:
+                self.quit_timer.stop()
+                self.app_quit.emit()
+        except Exception:
+            traceback.print_exc()
 
     def on_options_app2project(self):
         """

+ 6 - 0
FlatCAMTranslation.py

@@ -112,6 +112,12 @@ def apply_language(domain, lang=None):
             name = settings.value('language')
         else:
             name = settings.value('English')
+            # in case the 'language' parameter is not in QSettings add it to QSettings and it's value is
+            # the default language, English
+            settings.setValue('language', 'English')
+
+            # This will write the setting to the platform specific storage.
+            del settings
     else:
         name = str(lang)
 

+ 4 - 0
README.md

@@ -17,6 +17,10 @@ CAD program, and create G-Code for Isolation routing.
 - WIP in Gerber Editor: geometry is no longer stored in a Rtree storage as it is not needed
 - changed the way delayed plot is working in Gerber Editor to use a Qtimer instead of python threading module
 - WIP in Gerber Editor
+- fixed bug in saving the maximized state
+- fixed bug in applying default language on first start
+- on activating 'V' key shortcut (zoom fit) the mouse cursor is now jumping to origin (0, 0)
+- fixed bug in saving toolbars state; the file was saved before setting the self.defaults['global_toolbar_view]
 
 4.04.2019
 

+ 29 - 2
flatcamEditors/FlatCAMGeoEditor.py

@@ -1882,6 +1882,33 @@ class DrawTool(object):
     def utility_geometry(self, data=None):
         return None
 
+    def bounds(self, obj):
+        def bounds_rec(o):
+            if type(o) is list:
+                minx = Inf
+                miny = Inf
+                maxx = -Inf
+                maxy = -Inf
+
+                for k in o:
+                    try:
+                        minx_, miny_, maxx_, maxy_ = bounds_rec(k)
+                    except Exception as e:
+                        log.debug("camlib.Gerber.bounds() --> %s" % str(e))
+                        return
+
+                    minx = min(minx, minx_)
+                    miny = min(miny, miny_)
+                    maxx = max(maxx, maxx_)
+                    maxy = max(maxy, maxy_)
+                return minx, miny, maxx, maxy
+            else:
+                # it's a Shapely object, return it's bounds
+                return o.geo.bounds
+
+        bounds_coords = bounds_rec(obj)
+        return bounds_coords
+
 
 class FCShapeTool(DrawTool):
     """
@@ -2843,14 +2870,14 @@ class FlatCAMGeoEditor(QtCore.QObject):
         settings = QSettings("Open Source", "FlatCAM")
         if settings.contains("layout"):
             layout = settings.value('layout', type=str)
-            if layout == 'Standard':
+            if layout == 'standard':
                 # self.app.ui.geo_edit_toolbar.setVisible(False)
 
                 self.app.ui.snap_max_dist_entry.setEnabled(False)
                 self.app.ui.corner_snap_btn.setEnabled(False)
                 self.app.ui.snap_magnet.setVisible(False)
                 self.app.ui.corner_snap_btn.setVisible(False)
-            elif layout == 'Compact':
+            elif layout == 'compact':
                 # self.app.ui.geo_edit_toolbar.setVisible(True)
 
                 self.app.ui.snap_max_dist_entry.setEnabled(False)

+ 30 - 19
flatcamEditors/FlatCAMGrbEditor.py

@@ -116,7 +116,7 @@ class FCApertureResize(FCShapeTool):
             sel_shapes_to_be_deleted = []
 
         self.draw_app.build_ui()
-        self.draw_app.replot()
+        self.draw_app.plot_all()
 
         self.draw_app.resize_frame.hide()
         self.complete = True
@@ -287,9 +287,10 @@ class FCApertureSelect(DrawTool):
         self.grb_editor_app.apertures_table.clearSelection()
 
         for storage in self.grb_editor_app.storage_dict:
-            for shape in self.grb_editor_app.storage_dict[storage]:
+            for shape in self.grb_editor_app.storage_dict[storage]['solid_geometry']:
                 if Point(pos).within(shape.geo):
-                    self.sel_storage.append(DrawToolShape(shape.geo))
+                    self.sel_storage.append(shape)
+        xmin, ymin, xmax, ymax = self.bounds(self.sel_storage)
 
         if pos[0] < xmin or pos[0] > xmax or pos[1] < ymin or pos[1] > ymax:
             self.grb_editor_app.selected = []
@@ -1028,7 +1029,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
 
             self.app.inform.emit(_("[success] Deleted tool with dia: {del_dia} {units}").format(del_dia=str(deleted_tool_dia), units=str(self.units)))
 
-        self.replot()
+        self.plot_all()
         # self.app.inform.emit("Could not delete selected tool")
 
         self.build_ui()
@@ -1069,7 +1070,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
             modified_offset = self.gerber_obj.tool_offset.pop(dia_changed)
             self.gerber_obj.tool_offset[current_table_dia_edited] = modified_offset
 
-            self.replot()
+            self.plot_all()
         else:
             # tool diameter is already in use so we move the drills from the prior tool to the new tool
             factor = current_table_dia_edited / dia_changed
@@ -1217,7 +1218,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
         self.tool_shape.clear(update=True)
 
         # self.storage = FlatCAMExcEditor.make_storage()
-        self.replot()
+        self.plot_all()
 
     def edit_fcgerber(self, exc_obj):
         """
@@ -1274,8 +1275,12 @@ class FlatCAMGrbEditor(QtCore.QObject):
                     else:
                         self.storage_dict[apid][k] = v
 
+                apid_promise = apid
+
                 # Check promises and clear if exists
-                self.app.collection.plot_remove_promise(apid)
+                self.app.collection.plot_remove_promise(apid_promise)
+                # if apid_promise in self.app.collection.plot_promises:
+                #     self.app.collection.plot_promises.remove(apid_promise)
 
         for apid in self.gerber_obj.apertures:
             self.app.worker_task.emit({'fcn': job_thread, 'params': [apid]})
@@ -1291,6 +1296,12 @@ class FlatCAMGrbEditor(QtCore.QObject):
         :return: None
         """
 
+        # if the 'delayed plot' malfunctioned stop the QTimer
+        try:
+            self.plot_thread.stop()
+        except:
+            pass
+
         if "_edit" in self.edited_obj_name:
             try:
                 id = int(self.edited_obj_name[-1]) + 1
@@ -1310,7 +1321,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
 
         # restore GUI to the Selected TAB
         # Remove anything else in the GUI
-        self.app.ui.tool_scroll_area.takeWidget()
+        self.app.ui.selected_scroll_area.takeWidget()
         # Switch notebook to Selected page
         self.app.ui.notebook.setCurrentWidget(self.app.ui.selected_tab)
 
@@ -1443,7 +1454,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
         except Exception as e:
             self.app.log.debug(str(e))
 
-        self.replot()
+        self.plot_all()
 
     def toolbar_tool_toggle(self, key):
         self.options[key] = self.sender().isChecked()
@@ -1500,7 +1511,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
 
                 if isinstance(self.active_tool, FCApertureSelect):
                     # self.app.log.debug("Replotting after click.")
-                    self.replot()
+                    self.plot_all()
             else:
                 self.app.log.debug("No active tool to respond to click!")
 
@@ -1519,7 +1530,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
         self.tool_shape.clear(update=True)
 
         # Replot and reset tool.
-        self.replot()
+        self.plot_all()
         # self.active_tool = type(self.active_tool)(self)
 
     def add_gerber_shape(self, shape, storage):
@@ -1617,7 +1628,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
                     # msg = self.active_tool.click_release((self.pos[0], self.pos[1]))
                     # self.app.inform.emit(msg)
                     self.active_tool.click_release((self.pos[0], self.pos[1]))
-                    self.replot()
+                    self.plot_all()
         except Exception as e:
             log.warning("Error: %s" % str(e))
             raise
@@ -1658,7 +1669,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
                             # item.setSelected(True)
                             # self.grb_editor_app.apertures_table.selectItem(key - 1)
 
-        self.replot()
+        self.plot_all()
 
     def on_canvas_move(self, event):
         """
@@ -1783,9 +1794,6 @@ class FlatCAMGrbEditor(QtCore.QObject):
 
             self.tool_shape.redraw()
 
-    def replot(self):
-        self.plot_all()
-
     def plot_all(self):
         """
         Plots all shapes in the editor.
@@ -1817,14 +1825,17 @@ class FlatCAMGrbEditor(QtCore.QObject):
     def start_delayed_plot(self, check_period):
         # self.plot_thread = threading.Thread(target=lambda: self.check_plot_finished(check_period))
         # self.plot_thread.start()
+        log.debug("FlatCAMGrbEditor --> Delayed Plot started.")
         self.plot_thread = QtCore.QTimer()
         self.plot_thread.setInterval(check_period)
         self.plot_thread.timeout.connect(self.check_plot_finished)
         self.plot_thread.start()
 
     def check_plot_finished(self):
+        print(self.app.collection.plot_promises)
         try:
-            if self.app.collection.has_plot_promises() is False:
+            has_promise = self.app.collection.has_plot_promises()
+            if has_promise == False:
                 self.plot_thread.stop()
                 self.plot_all()
                 log.debug("FlatCAMGrbEditor --> delayed_plot finished")
@@ -1890,7 +1901,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
         self.tool_shape.clear(update=True)
 
         # Replot and reset tool.
-        self.replot()
+        self.plot_all()
         # self.active_tool = type(self.active_tool)(self)
 
     def get_selected(self):
@@ -1947,7 +1958,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
 
     def on_delete_btn(self):
         self.delete_selected()
-        self.replot()
+        self.plot_all()
 
     def select_tool(self, toolname):
         """

+ 15 - 16
flatcamGUI/FlatCAMGUI.py

@@ -567,9 +567,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         settings = QSettings("Open Source", "FlatCAM")
         if settings.contains("layout"):
             layout = settings.value('layout', type=str)
-            if layout == 'Standard':
+            if layout == 'standard':
                 pass
-            elif layout == 'Compact':
+            elif layout == 'compact':
                 self.removeToolBar(self.snap_toolbar)
                 self.snap_toolbar.setMaximumHeight(30)
                 self.splitter_left.addWidget(self.snap_toolbar)
@@ -672,13 +672,6 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         self.grb_select_btn = self.grb_edit_toolbar.addAction(QtGui.QIcon('share/pointer32.png'), _("Select"))
 
 
-
-
-
-
-
-
-
         ### Snap Toolbar ###
         # Snap GRID toolbar is always active to facilitate usage of measurements done on GRID
         # self.addToolBar(self.snap_toolbar)
@@ -1616,7 +1609,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
 
                 self.corner_snap_btn.setVisible(False)
                 self.snap_magnet.setVisible(False)
-            elif layout == 'Compact':
+            elif layout == 'compact':
                 self.exc_edit_toolbar.setDisabled(True)
                 self.geo_edit_toolbar.setDisabled(True)
                 self.grb_edit_toolbar.setDisabled(True)
@@ -1746,12 +1739,10 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         self.geo_edit_toolbar.addSeparator()
         self.geo_move_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/move32.png'), _("Move Objects"))
 
-        ### Geometry Editor Toolbar ###
+        ### Gerber Editor Toolbar ###
         self.grb_select_btn = self.grb_edit_toolbar.addAction(QtGui.QIcon('share/pointer32.png'), _("Select"))
 
 
-
-
         ### Snap Toolbar ###
         # Snap GRID toolbar is always active to facilitate usage of measurements done on GRID
         # self.addToolBar(self.snap_toolbar)
@@ -1802,7 +1793,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
 
                 self.corner_snap_btn.setVisible(False)
                 self.snap_magnet.setVisible(False)
-            elif layout == 'Compact':
+            elif layout == 'compact':
                 self.exc_edit_toolbar.setVisible(True)
                 self.exc_edit_toolbar.setDisabled(True)
                 self.geo_edit_toolbar.setVisible(True)
@@ -2097,6 +2088,8 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
                 # Zoom Fit
                 if key == QtCore.Qt.Key_V:
                     self.app.on_zoom_fit(None)
+                    # and move mouse cursor to origin
+                    self.app.on_jump_to(custom_location=(0, 0))
 
                 # Mirror on X the selected object(s)
                 if key == QtCore.Qt.Key_X:
@@ -2362,6 +2355,8 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
 
                 if key == QtCore.Qt.Key_V or key == 'V':
                     self.app.on_zoom_fit(None)
+                    # and move mouse cursor to origin
+                    self.app.on_jump_to(custom_location=(0, 0))
 
                 # Flip on X axis
                 if key == QtCore.Qt.Key_X or key == 'X':
@@ -2541,6 +2536,8 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
                 if key == QtCore.Qt.Key_V or key == 'V':
                     self.app.grb_editor.launched_from_shortcuts = True
                     self.app.on_zoom_fit(None)
+                    # and move mouse cursor to origin
+                    self.app.on_jump_to(custom_location=(0, 0))
                     return
 
                 # Propagate to tool
@@ -2738,6 +2735,8 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
                 if key == QtCore.Qt.Key_V or key == 'V':
                     self.app.exc_editor.launched_from_shortcuts = True
                     self.app.on_zoom_fit(None)
+                    # and move mouse cursor to origin
+                    self.app.on_jump_to(custom_location=(0, 0))
                     return
 
                 # Propagate to tool
@@ -3287,8 +3286,8 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
         )
         self.layout_combo = FCComboBox()
         # don't translate the QCombo items as they are used in QSettings and identified by name
-        self.layout_combo.addItem("Standard")
-        self.layout_combo.addItem("Compact")
+        self.layout_combo.addItem("standard")
+        self.layout_combo.addItem("compact")
 
         # Set the current index for layout_combo
         settings = QSettings("Open Source", "FlatCAM")