Sfoglia il codice sorgente

- updated the new shortcut list with the shortcuts added lately
- now the special messages in the Shell are color coded according to the level. Before they all were RED. Now the WARNINGS are yellow, ERRORS are red and SUCCESS is a dark green. Also the level is in CAPS LOCK to make them more obvious
- some more changes to GUI interface (solved issues)
- added some status bar messages in the Geometry Editor to guide the user when using the Geometry Tools
- now the '`' shortcut key that shows the 'shortcut key list' in Editors points to the same window which is created in a tab no longer as a pop-up window. This tab can be detached if needed.

Marius Stanciu 7 anni fa
parent
commit
6ea3499d39

+ 113 - 99
FlatCAMApp.py

@@ -1499,7 +1499,7 @@ class App(QtCore.QObject):
         if isinstance(edited_object, FlatCAMGeometry):
             # for now, if the Geometry is MultiGeo do not allow the editing
             if edited_object.multigeo is True:
-                self.inform.emit("[warning_notcl]Editing a MultiGeo Geometry is not possible for the moment.")
+                self.inform.emit("[WARNING_NOTCL]Editing a MultiGeo Geometry is not possible for the moment.")
                 return
 
             self.geo_editor.edit_fcgeometry(edited_object)
@@ -1512,7 +1512,7 @@ class App(QtCore.QObject):
             # set call source to the Editor we go into
             self.call_source = 'exc_editor'
         else:
-            self.inform.emit("[warning_notcl]Select a Geometry or Excellon Object to edit.")
+            self.inform.emit("[WARNING_NOTCL]Select a Geometry or Excellon Object to edit.")
             return
 
         # make sure that we can't select another object while in Editor Mode:
@@ -1523,7 +1523,7 @@ class App(QtCore.QObject):
 
         self.ui.plot_tab_area.setTabText(0, "EDITOR Area")
         self.ui.plot_tab_area.protectTab(0)
-        self.inform.emit("[warning_notcl]Editor is activated ...")
+        self.inform.emit("[WARNING_NOTCL]Editor is activated ...")
 
     def editor2object(self):
         """
@@ -1553,7 +1553,7 @@ class App(QtCore.QObject):
                 edited_obj.options['xmax'] = xmax
                 edited_obj.options['ymax'] = ymax
             except AttributeError:
-                self.inform.emit("[warning] Object empty after edit.")
+                self.inform.emit("[WARNING] Object empty after edit.")
 
         elif isinstance(edited_obj, FlatCAMExcellon):
             obj_type = "Excellon"
@@ -1569,9 +1569,9 @@ class App(QtCore.QObject):
                 edited_obj.options['xmax'] = xmax
                 edited_obj.options['ymax'] = ymax
             except AttributeError:
-                self.inform.emit("[warning] Object empty after edit.")
+                self.inform.emit("[WARNING] Object empty after edit.")
         else:
-            self.inform.emit("[warning_notcl]Select a Geometry or Excellon Object to update.")
+            self.inform.emit("[WARNING_NOTCL]Select a Geometry or Excellon Object to update.")
             return
 
         # restore the call_source to app
@@ -1628,7 +1628,7 @@ class App(QtCore.QObject):
         """
         pass
 
-    def shell_message(self, msg, show=False, error=False):
+    def shell_message(self, msg, show=False, error=False, warning=False, success=False):
         """
         Shows a message on the FlatCAM Shell
 
@@ -1643,7 +1643,13 @@ class App(QtCore.QObject):
             if error:
                 self.shell.append_error(msg + "\n")
             else:
-                self.shell.append_output(msg + "\n")
+                if warning:
+                    self.shell.append_warning(msg + "\n")
+                else:
+                    if success:
+                        self.shell.append_success(msg + "\n")
+                    else:
+                        self.shell.append_output(msg + "\n")
         except AttributeError:
             log.debug("shell_message() is called before Shell Class is instantiated. The message is: %s", str(msg))
 
@@ -1809,12 +1815,20 @@ class App(QtCore.QObject):
             msg_ = match.group(2)
             self.ui.fcinfo.set_status(str(msg_), level=level)
 
-            if level == "error" or level == "warning":
+            if level.lower() == "error":
                 self.shell_message(msg, error=True, show=True)
-            elif level == "error_notcl" or level == "warning_notcl":
+            elif level.lower() == "warning":
+                self.shell_message(msg, warning=True, show=True)
+
+            elif level.lower() == "error_notcl":
                 self.shell_message(msg, error=True, show=False)
+            elif level.lower() == "warning_notcl":
+                self.shell_message(msg, warning=True, show=False)
+
+            elif level.lower() == "success":
+                self.shell_message(msg, success=True, show=False)
             else:
-                self.shell_message(msg, error=False, show=False)
+                self.shell_message(msg, show=False)
         else:
             self.ui.fcinfo.set_status(str(msg), level="info")
 
@@ -1873,7 +1887,7 @@ class App(QtCore.QObject):
             f.close()
         except IOError:
             self.log.error("Could not load defaults file.")
-            self.inform.emit("[error] Could not load defaults file.")
+            self.inform.emit("[ERROR] Could not load defaults file.")
             # in case the defaults file can't be loaded, show all toolbars
             self.defaults["global_toolbar_view"] = 127
             return
@@ -1885,7 +1899,7 @@ class App(QtCore.QObject):
             self.defaults["global_toolbar_view"] = 127
             e = sys.exc_info()[0]
             App.log.error(str(e))
-            self.inform.emit("[error] Failed to parse defaults file.")
+            self.inform.emit("[ERROR] Failed to parse defaults file.")
             return
         self.defaults.update(defaults)
         log.debug("FlatCAM defaults loaded from: %s" % filename)
@@ -1914,7 +1928,7 @@ class App(QtCore.QObject):
         filename = str(filename)
 
         if filename == "":
-            self.inform.emit("[warning_notcl]FlatCAM preferences import cancelled.")
+            self.inform.emit("[WARNING_NOTCL]FlatCAM preferences import cancelled.")
         else:
             try:
                 f = open(filename)
@@ -1922,7 +1936,7 @@ class App(QtCore.QObject):
                 f.close()
             except IOError:
                 self.log.error("Could not load defaults file.")
-                self.inform.emit("[error_notcl] Could not load defaults file.")
+                self.inform.emit("[ERROR_NOTCL] Could not load defaults file.")
                 return
 
             try:
@@ -1930,7 +1944,7 @@ class App(QtCore.QObject):
             except:
                 e = sys.exc_info()[0]
                 App.log.error(str(e))
-                self.inform.emit("[error_notcl] Failed to parse defaults file.")
+                self.inform.emit("[ERROR_NOTCL] Failed to parse defaults file.")
                 return
             self.defaults.update(defaults_from_file)
             self.inform.emit("[success]Imported Defaults from %s" %filename)
@@ -1951,7 +1965,7 @@ class App(QtCore.QObject):
         defaults_from_file = {}
 
         if filename == "":
-            self.inform.emit("[warning_notcl]FlatCAM preferences export cancelled.")
+            self.inform.emit("[WARNING_NOTCL]FlatCAM preferences export cancelled.")
             return
         else:
             try:
@@ -1967,7 +1981,7 @@ class App(QtCore.QObject):
                 e = sys.exc_info()[0]
                 App.log.error("Could not load defaults file.")
                 App.log.error(str(e))
-                self.inform.emit("[error_notcl]Could not load defaults file.")
+                self.inform.emit("[ERROR_NOTCL]Could not load defaults file.")
                 return
 
             try:
@@ -1986,7 +2000,7 @@ class App(QtCore.QObject):
                 json.dump(defaults_from_file, f)
                 f.close()
             except:
-                self.inform.emit("[error_notcl] Failed to write defaults to file.")
+                self.inform.emit("[ERROR_NOTCL] Failed to write defaults to file.")
                 return
         self.inform.emit("[success]Exported Defaults to %s" % filename)
 
@@ -2034,7 +2048,7 @@ class App(QtCore.QObject):
             f = open(self.data_path + '/recent.json', 'w')
         except IOError:
             App.log.error("Failed to open recent items file for writing.")
-            self.inform.emit('[error_notcl]Failed to open recent files file for writing.')
+            self.inform.emit('[ERROR_NOTCL]Failed to open recent files file for writing.')
             return
 
         #try:
@@ -2120,15 +2134,15 @@ class App(QtCore.QObject):
         try:
             return_value = initialize(obj, self)
         except Exception as e:
-            msg = "[error_notcl] An internal error has ocurred. See shell.\n"
+            msg = "[ERROR_NOTCL] An internal error has ocurred. See shell.\n"
             msg += "Object (%s) failed because: %s \n\n" % (kind, str(e))
             msg += traceback.format_exc()
             self.inform.emit(msg)
 
             # if str(e) == "Empty Geometry":
-            #     self.inform.emit("[error_notcl] )
+            #     self.inform.emit("[ERROR_NOTCL] )
             # else:
-            #     self.inform.emit("[error] Object (%s) failed because: %s" % (kind, str(e)))
+            #     self.inform.emit("[ERROR] Object (%s) failed because: %s" % (kind, str(e)))
             return "fail"
 
         t2 = time.time()
@@ -2360,7 +2374,7 @@ class App(QtCore.QObject):
             e = sys.exc_info()[0]
             App.log.error("Could not load defaults file.")
             App.log.error(str(e))
-            self.inform.emit("[error_notcl] Could not load defaults file.")
+            self.inform.emit("[ERROR_NOTCL] Could not load defaults file.")
             return
 
         try:
@@ -2369,7 +2383,7 @@ class App(QtCore.QObject):
             e = sys.exc_info()[0]
             App.log.error("Failed to parse defaults file.")
             App.log.error(str(e))
-            self.inform.emit("[error_notcl] Failed to parse defaults file.")
+            self.inform.emit("[ERROR_NOTCL] Failed to parse defaults file.")
             return
 
         # Update options
@@ -2383,7 +2397,7 @@ class App(QtCore.QObject):
             json.dump(defaults, f)
             f.close()
         except:
-            self.inform.emit("[error_notcl] Failed to write defaults to file.")
+            self.inform.emit("[ERROR_NOTCL] Failed to write defaults to file.")
             return
 
         # Save the toolbar view
@@ -2433,7 +2447,7 @@ class App(QtCore.QObject):
             e = sys.exc_info()[0]
             App.log.error("Could not load factory defaults file.")
             App.log.error(str(e))
-            self.inform.emit("[error_notcl] Could not load factory defaults file.")
+            self.inform.emit("[ERROR_NOTCL] Could not load factory defaults file.")
             return
 
         try:
@@ -2442,7 +2456,7 @@ class App(QtCore.QObject):
             e = sys.exc_info()[0]
             App.log.error("Failed to parse factory defaults file.")
             App.log.error(str(e))
-            self.inform.emit("[error_notcl] Failed to parse factory defaults file.")
+            self.inform.emit("[ERROR_NOTCL] Failed to parse factory defaults file.")
             return
 
         # Update options
@@ -2456,7 +2470,7 @@ class App(QtCore.QObject):
             json.dump(factory_defaults, f_f_def_s)
             f_f_def_s.close()
         except:
-            self.inform.emit("[error_notcl] Failed to write factory defaults to file.")
+            self.inform.emit("[ERROR_NOTCL] Failed to write factory defaults to file.")
             return
 
         if silent is False:
@@ -2516,7 +2530,7 @@ class App(QtCore.QObject):
 
         # if len(set(geo_type_list)) == 1 means that all list elements are the same
         if len(set(geo_type_list)) != 1:
-            self.inform.emit("[error] Failed join. The Geometry objects are of different types.\n"
+            self.inform.emit("[ERROR] Failed join. The Geometry objects are of different types.\n"
                              "At least one is MultiGeo type and the other is SingleGeo type. A possibility is to "
                              "convert from one to another and retry joining \n"
                              "but in the case of converting from MultiGeo to SingleGeo, informations may be lost and "
@@ -2553,7 +2567,7 @@ class App(QtCore.QObject):
 
         for obj in objs:
             if not isinstance(obj, FlatCAMExcellon):
-                self.inform.emit("[error_notcl]Failed. Excellon joining works only on Excellon objects.")
+                self.inform.emit("[ERROR_NOTCL]Failed. Excellon joining works only on Excellon objects.")
                 return
 
         def initialize(obj, app):
@@ -2572,7 +2586,7 @@ class App(QtCore.QObject):
 
         for obj in objs:
             if not isinstance(obj, FlatCAMGerber):
-                self.inform.emit("[error_notcl]Failed. Gerber joining works only on Gerber objects.")
+                self.inform.emit("[ERROR_NOTCL]Failed. Gerber joining works only on Gerber objects.")
                 return
 
         def initialize(obj, app):
@@ -2584,11 +2598,11 @@ class App(QtCore.QObject):
         obj = self.collection.get_active()
 
         if obj is None:
-            self.inform.emit("[error_notcl]Failed. Select a Geometry Object and try again.")
+            self.inform.emit("[ERROR_NOTCL]Failed. Select a Geometry Object and try again.")
             return
 
         if not isinstance(obj, FlatCAMGeometry):
-            self.inform.emit("[error_notcl]Expected a FlatCAMGeometry, got %s" % type(obj))
+            self.inform.emit("[ERROR_NOTCL]Expected a FlatCAMGeometry, got %s" % type(obj))
             return
 
         obj.multigeo = True
@@ -2605,11 +2619,11 @@ class App(QtCore.QObject):
         obj = self.collection.get_active()
 
         if obj is None:
-            self.inform.emit("[error_notcl]Failed. Select a Geometry Object and try again.")
+            self.inform.emit("[ERROR_NOTCL]Failed. Select a Geometry Object and try again.")
             return
 
         if not isinstance(obj, FlatCAMGeometry):
-            self.inform.emit("[error_notcl]Expected a FlatCAMGeometry, got %s" % type(obj))
+            self.inform.emit("[ERROR_NOTCL]Expected a FlatCAMGeometry, got %s" % type(obj))
             return
 
         obj.multigeo = False
@@ -3548,7 +3562,7 @@ class App(QtCore.QObject):
         ymaxlist = []
 
         if not obj_list:
-            self.inform.emit("[warning_notcl] No object selected to Flip on Y axis.")
+            self.inform.emit("[WARNING_NOTCL] No object selected to Flip on Y axis.")
         else:
             try:
                 # first get a bounding box to fit all
@@ -3574,7 +3588,7 @@ class App(QtCore.QObject):
                     obj.plot()
                     self.object_changed.emit(obj)
             except Exception as e:
-                self.inform.emit("[error_notcl] Due of %s, Flip action was not executed." % str(e))
+                self.inform.emit("[ERROR_NOTCL] Due of %s, Flip action was not executed." % str(e))
                 return
 
     def on_flipx(self):
@@ -3585,7 +3599,7 @@ class App(QtCore.QObject):
         ymaxlist = []
 
         if not obj_list:
-            self.inform.emit("[warning_notcl] No object selected to Flip on X axis.")
+            self.inform.emit("[WARNING_NOTCL] No object selected to Flip on X axis.")
         else:
             try:
                 # first get a bounding box to fit all
@@ -3611,7 +3625,7 @@ class App(QtCore.QObject):
                     obj.plot()
                     self.object_changed.emit(obj)
             except Exception as e:
-                self.inform.emit("[error_notcl] Due of %s, Flip action was not executed." % str(e))
+                self.inform.emit("[ERROR_NOTCL] Due of %s, Flip action was not executed." % str(e))
                 return
 
     def on_rotate(self, silent=False, preset=None):
@@ -3622,7 +3636,7 @@ class App(QtCore.QObject):
         ymaxlist = []
 
         if not obj_list:
-            self.inform.emit("[warning_notcl] No object selected to Rotate.")
+            self.inform.emit("[WARNING_NOTCL] No object selected to Rotate.")
         else:
             if silent is False:
                 rotatebox = FCInputDialog(title="Transform", text="Enter the Angle value:",
@@ -3655,7 +3669,7 @@ class App(QtCore.QObject):
                         sel_obj.plot()
                         self.object_changed.emit(sel_obj)
                 except Exception as e:
-                    self.inform.emit("[error_notcl] Due of %s, rotation movement was not executed." % str(e))
+                    self.inform.emit("[ERROR_NOTCL] Due of %s, rotation movement was not executed." % str(e))
                     return
 
     def on_skewx(self):
@@ -3664,7 +3678,7 @@ class App(QtCore.QObject):
         yminlist = []
 
         if not obj_list:
-            self.inform.emit("[warning_notcl] No object selected to Skew/Shear on X axis.")
+            self.inform.emit("[WARNING_NOTCL] No object selected to Skew/Shear on X axis.")
         else:
             skewxbox = FCInputDialog(title="Transform", text="Enter the Angle value:",
                                           min=-360, max=360, decimals=3)
@@ -3691,7 +3705,7 @@ class App(QtCore.QObject):
         yminlist = []
 
         if not obj_list:
-            self.inform.emit("[warning_notcl] No object selected to Skew/Shear on Y axis.")
+            self.inform.emit("[WARNING_NOTCL] No object selected to Skew/Shear on Y axis.")
         else:
             skewybox = FCInputDialog(title="Transform", text="Enter the Angle value:",
                                           min=-360, max=360, decimals=3)
@@ -4006,7 +4020,7 @@ class App(QtCore.QObject):
             name = obj.options["name"]
         except AttributeError:
             log.debug("on_copy_name() --> No object selected to copy it's name")
-            self.inform.emit("[warning_notcl]No object selected to copy it's name")
+            self.inform.emit("[WARNING_NOTCL]No object selected to copy it's name")
             return
 
         self.clipboard.setText(name)
@@ -4296,7 +4310,7 @@ class App(QtCore.QObject):
                     # TODO: on selected objects change the object colors and do not draw the selection box
                     # self.plotcanvas.vispy_canvas.update() # this updates the canvas
         except Exception as e:
-            log.error("[error] Something went bad. %s" % str(e))
+            log.error("[ERROR] Something went bad. %s" % str(e))
             return
 
     def delete_selection_shape(self):
@@ -4451,7 +4465,7 @@ class App(QtCore.QObject):
         filenames = [str(filename) for filename in filenames]
 
         if len(filenames) == 0:
-            self.inform.emit("[warning_notcl]Open Gerber cancelled.")
+            self.inform.emit("[WARNING_NOTCL]Open Gerber cancelled.")
         else:
             for filename in filenames:
                 if filename != '':
@@ -4489,7 +4503,7 @@ class App(QtCore.QObject):
         follow = True
 
         if filename == "":
-            self.inform.emit("[warning_notcl]Open Gerber-Follow cancelled.")
+            self.inform.emit("[WARNING_NOTCL]Open Gerber-Follow cancelled.")
         else:
             self.worker_task.emit({'fcn': self.open_gerber,
                                    'params': [filename, follow]})
@@ -4516,7 +4530,7 @@ class App(QtCore.QObject):
         filenames = [str(filename) for filename in filenames]
 
         if len(filenames) == 0:
-            self.inform.emit("[warning_notcl]Open Excellon cancelled.")
+            self.inform.emit("[WARNING_NOTCL]Open Excellon cancelled.")
         else:
             for filename in filenames:
                 if filename != '':
@@ -4546,7 +4560,7 @@ class App(QtCore.QObject):
         filenames = [str(filename) for filename in filenames]
 
         if len(filenames) == 0:
-            self.inform.emit("[warning_notcl]Open G-Code cancelled.")
+            self.inform.emit("[WARNING_NOTCL]Open G-Code cancelled.")
         else:
             for filename in filenames:
                 if filename != '':
@@ -4575,7 +4589,7 @@ class App(QtCore.QObject):
         filename = str(filename)
 
         if filename == "":
-            self.inform.emit("[warning_notcl]Open Project cancelled.")
+            self.inform.emit("[WARNING_NOTCL]Open Project cancelled.")
         else:
             # self.worker_task.emit({'fcn': self.open_project,
             #                        'params': [filename]})
@@ -4606,7 +4620,7 @@ class App(QtCore.QObject):
         # Check for more compatible types and add as required
         if (not isinstance(obj, FlatCAMGeometry) and not isinstance(obj, FlatCAMGerber) and not isinstance(obj, FlatCAMCNCjob)
             and not isinstance(obj, FlatCAMExcellon)):
-            msg = "[error_notcl] Only Geometry, Gerber and CNCJob objects can be used."
+            msg = "[ERROR_NOTCL] Only Geometry, Gerber and CNCJob objects can be used."
             msgbox = QtWidgets.QMessageBox()
             msgbox.setInformativeText(msg)
             msgbox.setStandardButtons(QtWidgets.QMessageBox.Ok)
@@ -4626,7 +4640,7 @@ class App(QtCore.QObject):
         filename = str(filename)
 
         if filename == "":
-            self.inform.emit("[warning_notcl]Export SVG cancelled.")
+            self.inform.emit("[WARNING_NOTCL]Export SVG cancelled.")
             return
         else:
             self.export_svg(name, filename)
@@ -4640,7 +4654,7 @@ class App(QtCore.QObject):
         image = _screenshot()
         data = np.asarray(image)
         if not data.ndim == 3 and data.shape[-1] in (3, 4):
-            self.inform.emit('[[warning_notcl]] Data must be a 3D array with last dimension 3 or 4')
+            self.inform.emit('[[WARNING_NOTCL]] Data must be a 3D array with last dimension 3 or 4')
             return
 
         filter = "PNG File (*.png);;All Files (*.*)"
@@ -4670,7 +4684,7 @@ class App(QtCore.QObject):
 
         obj = self.collection.get_active()
         if obj is None:
-            self.inform.emit("[warning_notcl] No object selected.")
+            self.inform.emit("[WARNING_NOTCL] No object selected.")
             msg = "Please Select an Excellon object to export"
             msgbox = QtWidgets.QMessageBox()
             msgbox.setInformativeText(msg)
@@ -4681,7 +4695,7 @@ class App(QtCore.QObject):
 
         # Check for more compatible types and add as required
         if not isinstance(obj, FlatCAMExcellon):
-            msg = "[warning_notcl] Only Excellon objects can be used."
+            msg = "[WARNING_NOTCL] Only Excellon objects can be used."
             msgbox = QtWidgets.QMessageBox()
             msgbox.setInformativeText(msg)
             msgbox.setStandardButtons(QtWidgets.QMessageBox.Ok)
@@ -4701,7 +4715,7 @@ class App(QtCore.QObject):
         filename = str(filename)
 
         if filename == "":
-            self.inform.emit("[warning_notcl]Export Excellon cancelled.")
+            self.inform.emit("[WARNING_NOTCL]Export Excellon cancelled.")
             return
         else:
             if altium_format == None:
@@ -4722,7 +4736,7 @@ class App(QtCore.QObject):
 
         obj = self.collection.get_active()
         if obj is None:
-            self.inform.emit("W[warning_notcl] No object selected.")
+            self.inform.emit("W[WARNING_NOTCL] No object selected.")
             msg = "Please Select a Geometry object to export"
             msgbox = QtWidgets.QMessageBox()
             msgbox.setInformativeText(msg)
@@ -4733,7 +4747,7 @@ class App(QtCore.QObject):
 
         # Check for more compatible types and add as required
         if not isinstance(obj, FlatCAMGeometry):
-            msg = "[error_notcl] Only Geometry objects can be used."
+            msg = "[ERROR_NOTCL] Only Geometry objects can be used."
             msgbox = QtWidgets.QMessageBox()
             msgbox.setInformativeText(msg)
             msgbox.setStandardButtons(QtWidgets.QMessageBox.Ok)
@@ -4753,7 +4767,7 @@ class App(QtCore.QObject):
         filename = str(filename)
 
         if filename == "":
-            self.inform.emit("[warning_notcl]Export DXF cancelled.")
+            self.inform.emit("[WARNING_NOTCL]Export DXF cancelled.")
             return
         else:
             self.export_dxf(name, filename)
@@ -4782,7 +4796,7 @@ class App(QtCore.QObject):
         filenames = [str(filename) for filename in filenames]
 
         if len(filenames) == 0:
-            self.inform.emit("[warning_notcl]Open SVG cancelled.")
+            self.inform.emit("[WARNING_NOTCL]Open SVG cancelled.")
         else:
             for filename in filenames:
                 if filename != '':
@@ -4812,7 +4826,7 @@ class App(QtCore.QObject):
         filenames = [str(filename) for filename in filenames]
 
         if len(filenames) == 0:
-            self.inform.emit("[warning_notcl]Open DXF cancelled.")
+            self.inform.emit("[WARNING_NOTCL]Open DXF cancelled.")
         else:
             for filename in filenames:
                 if filename != '':
@@ -4841,7 +4855,7 @@ class App(QtCore.QObject):
         filename = str(filename)
 
         if filename == "":
-            self.inform.emit("[warning_notcl]Open TCL script cancelled.")
+            self.inform.emit("[WARNING_NOTCL]Open TCL script cancelled.")
         else:
             try:
                 with open(filename, "r") as tcl_script:
@@ -4894,7 +4908,7 @@ class App(QtCore.QObject):
         filename = str(filename)
 
         if filename == '':
-            self.inform.emit("[warning_notcl]Save Project cancelled.")
+            self.inform.emit("[WARNING_NOTCL]Save Project cancelled.")
             return
 
         try:
@@ -5008,7 +5022,7 @@ class App(QtCore.QObject):
             return "Could not retrieve object: %s" % box_name
 
         if box is None:
-            self.inform.emit("[warning_notcl]No object Box. Using instead %s" % obj)
+            self.inform.emit("[WARNING_NOTCL]No object Box. Using instead %s" % obj)
             box = obj
 
         def make_negative_film():
@@ -5127,7 +5141,7 @@ class App(QtCore.QObject):
             return "Could not retrieve object: %s" % box_name
 
         if box is None:
-            self.inform.emit("[warning_notcl]No object Box. Using instead %s" % obj)
+            self.inform.emit("[WARNING_NOTCL]No object Box. Using instead %s" % obj)
             box = obj
 
         def make_black_film():
@@ -5295,14 +5309,14 @@ class App(QtCore.QObject):
                 def job_thread_exc(app_obj):
                     ret = make_excellon()
                     if ret == 'fail':
-                        self.inform.emit('[error_notcl] Could not export Excellon file.')
+                        self.inform.emit('[ERROR_NOTCL] Could not export Excellon file.')
                         return
 
                 self.worker_task.emit({'fcn': job_thread_exc, 'params': [self]})
         else:
             ret = make_excellon()
             if ret == 'fail':
-                self.inform.emit('[error_notcl] Could not export Excellon file.')
+                self.inform.emit('[ERROR_NOTCL] Could not export Excellon file.')
                 return
 
     def export_dxf(self, obj_name, filename, use_thread=True):
@@ -5351,14 +5365,14 @@ class App(QtCore.QObject):
                 def job_thread_exc(app_obj):
                     ret = make_dxf()
                     if ret == 'fail':
-                        self.inform.emit('[[warning_notcl]] Could not export DXF file.')
+                        self.inform.emit('[[WARNING_NOTCL]] Could not export DXF file.')
                         return
 
                 self.worker_task.emit({'fcn': job_thread_exc, 'params': [self]})
         else:
             ret = make_dxf()
             if ret == 'fail':
-                self.inform.emit('[[warning_notcl]] Could not export DXF file.')
+                self.inform.emit('[[WARNING_NOTCL]] Could not export DXF file.')
                 return
 
     def import_svg(self, filename, geo_type='geometry', outname=None):
@@ -5376,7 +5390,7 @@ class App(QtCore.QObject):
         elif geo_type == "gerber":
             obj_type = geo_type
         else:
-            self.inform.emit("[error_notcl] Not supported type was choosed as parameter. "
+            self.inform.emit("[ERROR_NOTCL] Not supported type was choosed as parameter. "
                              "Only Geometry and Gerber are supported")
             return
 
@@ -5417,7 +5431,7 @@ class App(QtCore.QObject):
         elif geo_type == "gerber":
             obj_type = geo_type
         else:
-            self.inform.emit("[error_notcl] Not supported type was choosed as parameter. "
+            self.inform.emit("[ERROR_NOTCL] Not supported type was choosed as parameter. "
                              "Only Geometry and Gerber are supported")
             return
 
@@ -5456,7 +5470,7 @@ class App(QtCore.QObject):
         elif type == "gerber":
             obj_type = type
         else:
-            self.inform.emit("[error_notcl] Not supported type was picked as parameter. "
+            self.inform.emit("[ERROR_NOTCL] Not supported type was picked as parameter. "
                              "Only Geometry and Gerber are supported")
             return
 
@@ -5505,27 +5519,27 @@ class App(QtCore.QObject):
             try:
                 gerber_obj.parse_file(filename, follow=follow)
             except IOError:
-                app_obj.inform.emit("[error_notcl] Failed to open file: " + filename)
+                app_obj.inform.emit("[ERROR_NOTCL] Failed to open file: " + filename)
                 app_obj.progress.emit(0)
-                self.inform.emit('[error_notcl] Failed to open file: ' + filename)
+                self.inform.emit('[ERROR_NOTCL] Failed to open file: ' + filename)
                 return "fail"
             except ParseError as err:
-                app_obj.inform.emit("[error_notcl] Failed to parse file: " + filename + ". " + str(err))
+                app_obj.inform.emit("[ERROR_NOTCL] Failed to parse file: " + filename + ". " + str(err))
                 app_obj.progress.emit(0)
                 self.log.error(str(err))
                 return "fail"
 
             except:
-                msg = "[error] An internal error has ocurred. See shell.\n"
+                msg = "[ERROR] An internal error has ocurred. See shell.\n"
                 msg += traceback.format_exc()
                 app_obj.inform.emit(msg)
                 return "fail"
 
             if gerber_obj.is_empty():
-                # app_obj.inform.emit("[error] No geometry found in file: " + filename)
+                # app_obj.inform.emit("[ERROR] No geometry found in file: " + filename)
                 # self.collection.set_active(gerber_obj.options["name"])
                 # self.collection.delete_active()
-                self.inform.emit("[error_notcl] Object is not Gerber file or empty. Aborting object creation.")
+                self.inform.emit("[ERROR_NOTCL] Object is not Gerber file or empty. Aborting object creation.")
                 return "fail"
 
             # Further parsing
@@ -5546,7 +5560,7 @@ class App(QtCore.QObject):
             ### Object creation ###
             ret = self.new_object("gerber", name, obj_init, autoselected=False)
             if ret == 'fail':
-                self.inform.emit('[error_notcl] Open Gerber failed. Probable not a Gerber file.')
+                self.inform.emit('[ERROR_NOTCL] Open Gerber failed. Probable not a Gerber file.')
                 return
 
             # Register recent file
@@ -5582,15 +5596,15 @@ class App(QtCore.QObject):
                 ret = excellon_obj.parse_file(filename)
                 if ret == "fail":
                     log.debug("Excellon parsing failed.")
-                    self.inform.emit("[error_notcl] This is not Excellon file.")
+                    self.inform.emit("[ERROR_NOTCL] This is not Excellon file.")
                     return "fail"
             except IOError:
-                app_obj.inform.emit("[error_notcl] Cannot open file: " + filename)
+                app_obj.inform.emit("[ERROR_NOTCL] Cannot open file: " + filename)
                 log.debug("Could not open Excellon object.")
                 self.progress.emit(0)  # TODO: self and app_bjj mixed
                 return "fail"
             except:
-                msg = "[error_notcl] An internal error has occurred. See shell.\n"
+                msg = "[ERROR_NOTCL] An internal error has occurred. See shell.\n"
                 msg += traceback.format_exc()
                 app_obj.inform.emit(msg)
                 return "fail"
@@ -5601,7 +5615,7 @@ class App(QtCore.QObject):
                 return "fail"
 
             if excellon_obj.is_empty():
-                app_obj.inform.emit("[error_notcl] No geometry found in file: " + filename)
+                app_obj.inform.emit("[ERROR_NOTCL] No geometry found in file: " + filename)
                 return "fail"
 
         with self.proc_container.new("Opening Excellon."):
@@ -5611,7 +5625,7 @@ class App(QtCore.QObject):
 
             ret = self.new_object("excellon", name, obj_init, autoselected=False)
             if ret == 'fail':
-                self.inform.emit('[error_notcl] Open Excellon file failed. Probable not an Excellon file.')
+                self.inform.emit('[ERROR_NOTCL] Open Excellon file failed. Probable not an Excellon file.')
                 return
 
                 # Register recent file
@@ -5650,7 +5664,7 @@ class App(QtCore.QObject):
                 gcode = f.read()
                 f.close()
             except IOError:
-                app_obj_.inform.emit("[error_notcl] Failed to open " + filename)
+                app_obj_.inform.emit("[ERROR_NOTCL] Failed to open " + filename)
                 self.progress.emit(0)
                 return "fail"
 
@@ -5660,7 +5674,7 @@ class App(QtCore.QObject):
 
             ret = job_obj.gcode_parse()
             if ret == "fail":
-                self.inform.emit("[error_notcl] This is not GCODE")
+                self.inform.emit("[ERROR_NOTCL] This is not GCODE")
                 return "fail"
 
             self.progress.emit(60)
@@ -5674,7 +5688,7 @@ class App(QtCore.QObject):
             # New object creation and file processing
             ret = self.new_object("cncjob", name, obj_init, autoselected=False)
             if ret == 'fail':
-                self.inform.emit("[error_notcl] Failed to create CNCJob Object. Probable not a GCode file.\n "
+                self.inform.emit("[ERROR_NOTCL] Failed to create CNCJob Object. Probable not a GCode file.\n "
                                  "Attempting to create a FlatCAM CNCJob Object from "
                                  "G-Code file failed during processing")
                 return "fail"
@@ -5708,14 +5722,14 @@ class App(QtCore.QObject):
             f = open(filename, 'r')
         except IOError:
             App.log.error("Failed to open project file: %s" % filename)
-            self.inform.emit("[error_notcl] Failed to open project file: %s" % filename)
+            self.inform.emit("[ERROR_NOTCL] Failed to open project file: %s" % filename)
             return
 
         try:
             d = json.load(f, object_hook=dict2obj)
         except:
             App.log.error("Failed to parse project file: %s" % filename)
-            self.inform.emit("[error_notcl] Failed to parse project file: %s" % filename)
+            self.inform.emit("[ERROR_NOTCL] Failed to parse project file: %s" % filename)
             f.close()
             return
 
@@ -6066,14 +6080,14 @@ class App(QtCore.QObject):
             f = open(self.data_path + '/recent.json')
         except IOError:
             App.log.error("Failed to load recent item list.")
-            self.inform.emit("[error_notcl] Failed to load recent item list.")
+            self.inform.emit("[ERROR_NOTCL] Failed to load recent item list.")
             return
 
         try:
             self.recent = json.load(f)
         except json.scanner.JSONDecodeError:
             App.log.error("Failed to parse recent item list.")
-            self.inform.emit("[error_notcl] Failed to parse recent item list.")
+            self.inform.emit("[ERROR_NOTCL] Failed to parse recent item list.")
             f.close()
             return
         f.close()
@@ -6180,14 +6194,14 @@ class App(QtCore.QObject):
         except:
             # App.log.warning("Failed checking for latest version. Could not connect.")
             self.log.warning("Failed checking for latest version. Could not connect.")
-            self.inform.emit("[warning_notcl] Failed checking for latest version. Could not connect.")
+            self.inform.emit("[WARNING_NOTCL] Failed checking for latest version. Could not connect.")
             return
 
         try:
             data = json.load(f)
         except Exception as e:
             App.log.error("Could not parse information about latest version.")
-            self.inform.emit("[error_notcl] Could not parse information about latest version.")
+            self.inform.emit("[ERROR_NOTCL] Could not parse information about latest version.")
             App.log.debug("json.load(): %s" % str(e))
             f.close()
             return
@@ -6344,7 +6358,7 @@ class App(QtCore.QObject):
             try:
                 self.collection.get_active().read_form()
             except:
-                self.log.debug("[warning] There was no active object")
+                self.log.debug("[WARNING] There was no active object")
                 pass
             # Project options
             self.options_read_form()
@@ -6358,7 +6372,7 @@ class App(QtCore.QObject):
             try:
                 f = open(filename, 'w')
             except IOError:
-                App.log.error("[error] Failed to open file for saving: %s", filename)
+                App.log.error("[ERROR] Failed to open file for saving: %s", filename)
                 return
 
             # Write
@@ -6370,13 +6384,13 @@ class App(QtCore.QObject):
             try:
                 saved_f = open(filename, 'r')
             except IOError:
-                self.inform.emit("[error_notcl] Failed to verify project file: %s. Retry to save it." % filename)
+                self.inform.emit("[ERROR_NOTCL] Failed to verify project file: %s. Retry to save it." % filename)
                 return
 
             try:
                 saved_d = json.load(saved_f, object_hook=dict2obj)
             except:
-                self.inform.emit("[error_notcl] Failed to parse saved project file: %s. Retry to save it." % filename)
+                self.inform.emit("[ERROR_NOTCL] Failed to parse saved project file: %s. Retry to save it." % filename)
                 f.close()
                 return
             saved_f.close()
@@ -6384,7 +6398,7 @@ class App(QtCore.QObject):
             if 'version' in saved_d:
                 self.inform.emit("[success] Project saved to: %s" % filename)
             else:
-                self.inform.emit("[error_notcl] Failed to save project file: %s. Retry to save it." % filename)
+                self.inform.emit("[ERROR_NOTCL] Failed to save project file: %s. Retry to save it." % filename)
 
     def on_options_app2project(self):
         """

+ 58 - 111
FlatCAMEditor.py

@@ -590,6 +590,7 @@ class FCCircle(FCShapeTool):
         self.points.append(point)
 
         if len(self.points) == 1:
+            self.draw_app.app.inform.emit("Click on Circle perimeter point to complete ...")
             return "Click on perimeter to complete ..."
 
         if len(self.points) == 2:
@@ -638,9 +639,11 @@ class FCArc(FCShapeTool):
         self.points.append(point)
 
         if len(self.points) == 1:
+            self.draw_app.app.inform.emit("Click on Start arc point ...")
             return "Click on 1st point ..."
 
         if len(self.points) == 2:
+            self.draw_app.app.inform.emit("Click on End arc point to complete ...")
             return "Click on 2nd point to complete ..."
 
         if len(self.points) == 3:
@@ -850,6 +853,7 @@ class FCPolygon(FCShapeTool):
         self.points.append(point)
 
         if len(self.points) > 0:
+            self.draw_app.app.inform.emit("Click on next Point or click Right mouse button to complete ...")
             return "Click on next point or hit ENTER to complete ..."
 
         return ""
@@ -1239,7 +1243,7 @@ class FCText(FCShapeTool):
             self.geometry = DrawToolShape(affinity.translate(self.text_gui.text_path, xoff=dx, yoff=dy))
         except Exception as e:
             log.debug("Font geometry is empty or incorrect: %s" % str(e))
-            self.draw_app.app.inform.emit("[error]Font not supported. Only Regular, Bold, Italic and BoldItalic are "
+            self.draw_app.app.inform.emit("[ERROR]Font not supported. Only Regular, Bold, Italic and BoldItalic are "
                                           "supported. Error: %s" % str(e))
             self.text_gui.text_path = []
             self.text_gui.hide_tool()
@@ -1416,7 +1420,7 @@ class FCDrillAdd(FCShapeTool):
             self.draw_app.tools_table_exc.setCurrentItem(item)
 
         except KeyError:
-            self.draw_app.app.inform.emit("[warning_notcl] To add a drill first select a tool")
+            self.draw_app.app.inform.emit("[WARNING_NOTCL] To add a drill first select a tool")
             self.draw_app.select_tool("select")
             return
 
@@ -1500,7 +1504,7 @@ class FCDrillArray(FCShapeTool):
             item = self.draw_app.tools_table_exc.item((self.draw_app.last_tool_selected - 1), 1)
             self.draw_app.tools_table_exc.setCurrentItem(item)
         except KeyError:
-            self.draw_app.app.inform.emit("[warning_notcl] To add an Drill Array first select a tool in Tool Table")
+            self.draw_app.app.inform.emit("[WARNING_NOTCL] To add an Drill Array first select a tool in Tool Table")
             return
 
         geo = self.utility_geometry(data=(self.draw_app.snap_x, self.draw_app.snap_y), static=True)
@@ -1525,7 +1529,7 @@ class FCDrillArray(FCShapeTool):
 
                 self.flag_for_circ_array = True
                 self.set_origin(point)
-                self.draw_app.app.inform.emit("Click on the circular array Start position")
+                self.draw_app.app.inform.emit("Click on the Drill Circular Array Start position")
             else:
                 self.destination = point
                 self.make()
@@ -1547,10 +1551,10 @@ class FCDrillArray(FCShapeTool):
                 self.drill_angle = float(self.draw_app.drill_angle_entry.get_value())
             except TypeError:
                 self.draw_app.app.inform.emit(
-                    "[error_notcl] The value is not Float. Check for comma instead of dot separator.")
+                    "[ERROR_NOTCL] The value is not Float. Check for comma instead of dot separator.")
                 return
         except Exception as e:
-            self.draw_app.app.inform.emit("[error_notcl] The value is mistyped. Check the value.")
+            self.draw_app.app.inform.emit("[ERROR_NOTCL] The value is mistyped. Check the value.")
             return
 
         if self.drill_array == 'Linear':
@@ -1630,7 +1634,7 @@ class FCDrillArray(FCShapeTool):
                 self.geometry.append(DrawToolShape(geo))
         else:
             if (self.drill_angle * self.drill_array_size) > 360:
-                self.draw_app.app.inform.emit("[warning_notcl]Too many drills for the selected spacing angle.")
+                self.draw_app.app.inform.emit("[WARNING_NOTCL]Too many drills for the selected spacing angle.")
                 return
 
             radius = distance(self.destination, self.origin)
@@ -1676,7 +1680,7 @@ class FCDrillResize(FCShapeTool):
         try:
             new_dia = self.draw_app.resdrill_entry.get_value()
         except:
-            self.draw_app.app.inform.emit("[error_notcl]Resize drill(s) failed. Please enter a diameter for resize.")
+            self.draw_app.app.inform.emit("[ERROR_NOTCL]Resize drill(s) failed. Please enter a diameter for resize.")
             return
 
         if new_dia not in self.draw_app.olddia_newdia:
@@ -2080,15 +2084,18 @@ class FlatCAMGeoEditor(QtCore.QObject):
             theme = settings.value('theme', type=str)
             if theme == '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 theme == 'compact':
                 self.app.ui.snap_max_dist_entry.setEnabled(False)
+
                 self.app.ui.corner_snap_btn.setEnabled(False)
         else:
             self.app.ui.geo_edit_toolbar.setVisible(False)
+
             self.app.ui.snap_magnet.setVisible(False)
             self.app.ui.corner_snap_btn.setVisible(False)
             self.app.ui.snap_max_dist_entry.setEnabled(False)
@@ -2102,6 +2109,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
         self.app.ui.geo_editor_menu.setDisabled(True)
         self.app.ui.geo_editor_menu.menuAction().setVisible(False)
 
+        self.app.ui.update_obj_btn.setEnabled(False)
 
         self.app.ui.g_editor_cmenu.setEnabled(False)
         self.app.ui.e_editor_cmenu.setEnabled(False)
@@ -2594,7 +2602,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
         if event.key.name == 'Escape':
             # TODO: ...?
             # self.on_tool_select("select")
-            self.app.inform.emit("[warning_notcl]Cancelled.")
+            self.app.inform.emit("[WARNING_NOTCL]Cancelled.")
 
             self.delete_utility_geometry()
 
@@ -2756,47 +2764,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
 
         # Show Shortcut list
         if event.key.name == '`':
-            self.on_shortcut_list()
-
-    def on_shortcut_list(self):
-        msg = '''<b>Shortcut list in Geometry Editor</b><br>
-<br>
-<b>1:</b>       Zoom Fit<br>
-<b>2:</b>       Zoom Out<br>
-<b>3:</b>       Zoom In<br>
-<b>A:</b>       Add an 'Arc'<br>
-<b>B:</b>       Add a Buffer Geo<br>
-<b>C:</b>       Copy Geo Item<br>
-<b>E:</b>       Intersection Tool<br>
-<b>G:</b>       Grid Snap On/Off<br>
-<b>I:</b>       Paint Tool<br>
-<b>K:</b>       Corner Snap On/Off<br>
-<b>M:</b>       Move Geo Item<br>
-<br>
-<b>N:</b>       Add an 'Polygon'<br>
-<b>O:</b>       Add a 'Circle'<br>
-<b>P:</b>       Add a 'Path'<br>
-<b>R:</b>       Add an 'Rectangle'<br>
-<b>S:</b>       Substraction Tool<br>
-<b>T:</b>       Add Text Geometry<br>
-<b>U:</b>       Union Tool<br>
-<br>
-<b>X:</b>       Cut Path<br>
-<br>
-<b>~:</b>       Show Shortcut List<br>
-<br>
-<b>Space:</b>   Rotate selected Geometry<br>
-<b>Enter:</b>   Finish Current Action<br>
-<b>Escape:</b>  Select Tool (Exit any other Tool)<br>
-<b>Delete:</b>  Delete Obj'''
-
-        helpbox =QtWidgets.QMessageBox()
-        helpbox.setText(msg)
-        helpbox.setWindowTitle("Help")
-        helpbox.setWindowIcon(QtGui.QIcon('share/help.png'))
-        helpbox.setStandardButtons(QtWidgets.QMessageBox.Ok)
-        helpbox.setDefaultButton(QtWidgets.QMessageBox.Ok)
-        helpbox.exec_()
+            self.app.on_shortcut_list()
 
     def on_canvas_key_release(self, event):
         self.key = None
@@ -3070,7 +3038,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
             results = shapes[0].geo
         except Exception as e:
             log.debug("FlatCAMGeoEditor.intersection() --> %s" % str(e))
-            self.app.inform.emit("[warning_notcl]A selection of at least 2 geo items is required to do Intersection.")
+            self.app.inform.emit("[WARNING_NOTCL]A selection of at least 2 geo items is required to do Intersection.")
             self.select_tool('select')
             return
 
@@ -3108,7 +3076,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
 
         if buf_distance < 0:
             self.app.inform.emit(
-                "[error_notcl]Negative buffer value is not accepted. Use Buffer interior to generate an 'inside' shape")
+                "[ERROR_NOTCL]Negative buffer value is not accepted. Use Buffer interior to generate an 'inside' shape")
 
             # deselect everything
             self.selected = []
@@ -3116,11 +3084,11 @@ class FlatCAMGeoEditor(QtCore.QObject):
             return
 
         if len(selected) == 0:
-            self.app.inform.emit("[warning_notcl] Nothing selected for buffering.")
+            self.app.inform.emit("[WARNING_NOTCL] Nothing selected for buffering.")
             return
 
         if not isinstance(buf_distance, float):
-            self.app.inform.emit("[warning_notcl] Invalid distance for buffering.")
+            self.app.inform.emit("[WARNING_NOTCL] Invalid distance for buffering.")
 
             # deselect everything
             self.selected = []
@@ -3130,7 +3098,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
         pre_buffer = cascaded_union([t.geo for t in selected])
         results = pre_buffer.buffer(buf_distance - 1e-10, resolution=32, join_style=join_style)
         if results.is_empty:
-            self.app.inform.emit("[error_notcl]Failed, the result is empty. Choose a different buffer value.")
+            self.app.inform.emit("[ERROR_NOTCL]Failed, the result is empty. Choose a different buffer value.")
             # deselect everything
             self.selected = []
             self.replot()
@@ -3145,18 +3113,18 @@ class FlatCAMGeoEditor(QtCore.QObject):
 
         if buf_distance < 0:
             self.app.inform.emit(
-                "[error_notcl]Negative buffer value is not accepted. Use Buffer interior to generate an 'inside' shape")
+                "[ERROR_NOTCL]Negative buffer value is not accepted. Use Buffer interior to generate an 'inside' shape")
             # deselect everything
             self.selected = []
             self.replot()
             return
 
         if len(selected) == 0:
-            self.app.inform.emit("[warning_notcl] Nothing selected for buffering.")
+            self.app.inform.emit("[WARNING_NOTCL] Nothing selected for buffering.")
             return
 
         if not isinstance(buf_distance, float):
-            self.app.inform.emit("[warning_notcl] Invalid distance for buffering.")
+            self.app.inform.emit("[WARNING_NOTCL] Invalid distance for buffering.")
             # deselect everything
             self.selected = []
             self.replot()
@@ -3165,7 +3133,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
         pre_buffer = cascaded_union([t.geo for t in selected])
         results = pre_buffer.buffer(-buf_distance + 1e-10, resolution=32, join_style=join_style)
         if results.is_empty:
-            self.app.inform.emit("[error_notcl]Failed, the result is empty. Choose a smaller buffer value.")
+            self.app.inform.emit("[ERROR_NOTCL]Failed, the result is empty. Choose a smaller buffer value.")
             # deselect everything
             self.selected = []
             self.replot()
@@ -3185,7 +3153,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
         #     return
         #
         # if not isinstance(buf_distance, float):
-        #     self.app.inform.emit("[warning] Invalid distance for buffering.")
+        #     self.app.inform.emit("[WARNING] Invalid distance for buffering.")
         #     return
         #
         # pre_buffer = cascaded_union([t.geo for t in selected])
@@ -3215,7 +3183,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
         selected = self.get_selected()
 
         if buf_distance < 0:
-            self.app.inform.emit("[error_notcl]Negative buffer value is not accepted. "
+            self.app.inform.emit("[ERROR_NOTCL]Negative buffer value is not accepted. "
                                  "Use Buffer interior to generate an 'inside' shape")
             # deselect everything
             self.selected = []
@@ -3223,11 +3191,11 @@ class FlatCAMGeoEditor(QtCore.QObject):
             return
 
         if len(selected) == 0:
-            self.app.inform.emit("[warning_notcl] Nothing selected for buffering.")
+            self.app.inform.emit("[WARNING_NOTCL] Nothing selected for buffering.")
             return
 
         if not isinstance(buf_distance, float):
-            self.app.inform.emit("[warning_notcl] Invalid distance for buffering.")
+            self.app.inform.emit("[WARNING_NOTCL] Invalid distance for buffering.")
             # deselect everything
             self.selected = []
             self.replot()
@@ -3236,7 +3204,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
         pre_buffer = cascaded_union([t.geo for t in selected])
         results = pre_buffer.buffer(buf_distance - 1e-10, resolution=32, join_style=join_style)
         if results.is_empty:
-            self.app.inform.emit("[error_notcl]Failed, the result is empty. Choose a different buffer value.")
+            self.app.inform.emit("[ERROR_NOTCL]Failed, the result is empty. Choose a different buffer value.")
             # deselect everything
             self.selected = []
             self.replot()
@@ -3254,13 +3222,13 @@ class FlatCAMGeoEditor(QtCore.QObject):
     #     selected = self.get_selected()
     #
     #     if len(selected) == 0:
-    #         self.app.inform.emit("[warning] Nothing selected for painting.")
+    #         self.app.inform.emit("[WARNING] Nothing selected for painting.")
     #         return
     #
     #     for param in [tooldia, overlap, margin]:
     #         if not isinstance(param, float):
     #             param_name = [k for k, v in locals().items() if v is param][0]
-    #             self.app.inform.emit("[warning] Invalid value for {}".format(param))
+    #             self.app.inform.emit("[WARNING] Invalid value for {}".format(param))
     #
     #     # Todo: Check for valid method.
     #
@@ -3312,19 +3280,19 @@ class FlatCAMGeoEditor(QtCore.QObject):
         selected = self.get_selected()
 
         if len(selected) == 0:
-            self.app.inform.emit("[warning_notcl]Nothing selected for painting.")
+            self.app.inform.emit("[WARNING_NOTCL]Nothing selected for painting.")
             return
 
         for param in [tooldia, overlap, margin]:
             if not isinstance(param, float):
                 param_name = [k for k, v in locals().items() if v is param][0]
-                self.app.inform.emit("[warning] Invalid value for {}".format(param))
+                self.app.inform.emit("[WARNING] Invalid value for {}".format(param))
 
         results = []
 
         if tooldia >= overlap:
             self.app.inform.emit(
-                "[error_notcl] Could not do Paint. Overlap value has to be less than Tool Dia value.")
+                "[ERROR_NOTCL] Could not do Paint. Overlap value has to be less than Tool Dia value.")
             return
 
         def recurse(geometry, reset=True):
@@ -3383,7 +3351,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
                 except Exception as e:
                     log.debug("Could not Paint the polygons. %s" % str(e))
                     self.app.inform.emit(
-                        "[error] Could not do Paint. Try a different combination of parameters. "
+                        "[ERROR] Could not do Paint. Try a different combination of parameters. "
                         "Or a different method of Paint\n%s" % str(e))
                     return
 
@@ -4090,7 +4058,7 @@ class FlatCAMExcEditor(QtCore.QObject):
             # each time a tool diameter is edited or added
             self.olddia_newdia[tool_dia] = tool_dia
         else:
-            self.app.inform.emit("[warning_notcl]Tool already in the original or actual tool list.\n"
+            self.app.inform.emit("[WARNING_NOTCL]Tool already in the original or actual tool list.\n"
                                  "Save and reedit Excellon if you need to add this tool. ")
             return
 
@@ -4128,7 +4096,7 @@ class FlatCAMExcEditor(QtCore.QObject):
                 else:
                     deleted_tool_dia_list.append(float('%.4f' % dia))
         except:
-            self.app.inform.emit("[warning_notcl]Select a tool in Tool Table")
+            self.app.inform.emit("[WARNING_NOTCL]Select a tool in Tool Table")
             return
 
         for deleted_tool_dia in deleted_tool_dia_list:
@@ -4248,18 +4216,21 @@ class FlatCAMExcEditor(QtCore.QObject):
             theme = settings.value('theme', type=str)
             if theme == 'standard':
                 self.app.ui.exc_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 theme == 'compact':
-                self.app.ui.exc_edit_toolbar.setVisible(False)
+                self.app.ui.exc_edit_toolbar.setVisible(True)
+
                 self.app.ui.snap_max_dist_entry.setEnabled(False)
                 self.app.ui.corner_snap_btn.setEnabled(False)
                 self.app.ui.snap_magnet.setVisible(True)
                 self.app.ui.corner_snap_btn.setVisible(True)
         else:
             self.app.ui.exc_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)
@@ -4275,7 +4246,9 @@ class FlatCAMExcEditor(QtCore.QObject):
 
         self.app.ui.exc_editor_menu.setDisabled(True)
         self.app.ui.exc_editor_menu.menuAction().setVisible(False)
+
         self.app.ui.update_obj_btn.setEnabled(False)
+
         self.app.ui.g_editor_cmenu.setEnabled(False)
         self.app.ui.e_editor_cmenu.setEnabled(False)
 
@@ -4494,6 +4467,10 @@ class FlatCAMExcEditor(QtCore.QObject):
         try:
             if not obj.options:
                 obj.options = {}
+                obj.options['xmin'] = 0
+                obj.options['ymin'] = 0
+                obj.options['xmax'] = 0
+                obj.options['ymax'] = 0
                 return True
             else:
                 return False
@@ -4526,9 +4503,9 @@ class FlatCAMExcEditor(QtCore.QObject):
                 excellon_obj.create_geometry()
             except KeyError:
                 self.app.inform.emit(
-                    "[error_notcl] There are no Tools definitions in the file. Aborting Excellon creation.")
+                    "[ERROR_NOTCL] There are no Tools definitions in the file. Aborting Excellon creation.")
             except:
-                msg = "[error] An internal error has ocurred. See shell.\n"
+                msg = "[ERROR] An internal error has ocurred. See shell.\n"
                 msg += traceback.format_exc()
                 app_obj.inform.emit(msg)
                 raise
@@ -4560,7 +4537,7 @@ class FlatCAMExcEditor(QtCore.QObject):
             # self.draw_app.select_tool('select')
             self.complete = True
             current_tool = 'select'
-            self.app.inform.emit("[warning_notcl]Cancelled. There is no Tool/Drill selected")
+            self.app.inform.emit("[WARNING_NOTCL]Cancelled. There is no Tool/Drill selected")
 
         # This is to make the group behave as radio group
         if current_tool in self.tools_exc:
@@ -4904,7 +4881,7 @@ class FlatCAMExcEditor(QtCore.QObject):
         if event.key.name == 'Escape':
             # TODO: ...?
             # self.on_tool_select("select")
-            self.app.inform.emit("[warning_notcl]Cancelled.")
+            self.app.inform.emit("[WARNING_NOTCL]Cancelled.")
 
             self.delete_utility_geometry()
 
@@ -4921,7 +4898,7 @@ class FlatCAMExcEditor(QtCore.QObject):
                 self.delete_selected()
                 self.replot()
             else:
-                self.app.inform.emit("[warning_notcl]Cancelled. Nothing selected to delete.")
+                self.app.inform.emit("[WARNING_NOTCL]Cancelled. Nothing selected to delete.")
             return
 
         if event.key == '1':
@@ -4953,7 +4930,7 @@ class FlatCAMExcEditor(QtCore.QObject):
                 self.on_tool_select('copy')
                 self.active_tool.set_origin((self.snap_x, self.snap_y))
             else:
-                self.app.inform.emit("[warning_notcl]Cancelled. Nothing selected to copy.")
+                self.app.inform.emit("[WARNING_NOTCL]Cancelled. Nothing selected to copy.")
             return
 
         # Add Drill Hole Tool
@@ -4990,7 +4967,7 @@ class FlatCAMExcEditor(QtCore.QObject):
                 self.on_tool_select('move')
                 self.active_tool.set_origin((self.snap_x, self.snap_y))
             else:
-                self.app.inform.emit("[warning_notcl]Cancelled. Nothing selected to move.")
+                self.app.inform.emit("[WARNING_NOTCL]Cancelled. Nothing selected to move.")
             return
 
         # Resize Tool
@@ -5014,39 +4991,9 @@ class FlatCAMExcEditor(QtCore.QObject):
 
         # Show Shortcut list
         if event.key.name == '`':
-            self.on_shortcut_list()
+            self.app.on_shortcut_list()
             return
 
-    def on_shortcut_list(self):
-        msg = '''<b>Shortcut list in Geometry Editor</b><br>
-<br>
-<b>1:</b>       Zoom Fit<br>
-<b>2:</b>       Zoom Out<br>
-<b>3:</b>       Zoom In<br>
-<b>A:</b>       Add an 'Drill Array'<br>
-<b>C:</b>       Copy Drill Hole<br>
-<b>D:</b>       Add an Drill Hole<br>
-<b>G:</b>       Grid Snap On/Off<br>
-<b>K:</b>       Corner Snap On/Off<br>
-<b>M:</b>       Move Drill Hole<br>
-<br>
-<b>R:</b>       Resize a 'Drill Hole'<br>
-<b>S:</b>       Select Tool Active<br>
-<br>
-<b>~:</b>       Show Shortcut List<br>
-<br>
-<b>Enter:</b>   Finish Current Action<br>
-<b>Escape:</b>  Abort Current Action<br>
-<b>Delete:</b>  Delete Drill Hole'''
-
-        helpbox =QtWidgets.QMessageBox()
-        helpbox.setText(msg)
-        helpbox.setWindowTitle("Help")
-        helpbox.setWindowIcon(QtGui.QIcon('share/help.png'))
-        helpbox.setStandardButtons(QtWidgets.QMessageBox.Ok)
-        helpbox.setDefaultButton(QtWidgets.QMessageBox.Ok)
-        helpbox.exec_()
-
     def on_canvas_key_release(self, event):
         self.key = None
 

+ 48 - 13
FlatCAMGUI.py

@@ -747,7 +747,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         self.sh_tab_layout.addWidget(self.sh_title)
         self.sh_tab_layout.addLayout(self.sh_hlay)
 
-        self.app_sh_msg = '''<b>Shortcut list</b><br>
+        self.app_sh_msg = '''<b>General Shortcut list</b><br>
 <br>
 <b>~:</b>       Show Shortcut List<br>
 <br>
@@ -778,6 +778,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
 <b>CTRL+M:</b>   Measurement Tool<br>
 <b>CTRL+O:</b>   Open Project<br>
 <b>CTRL+S:</b>   Save Project As<br>
+<b>CTRL+F10:</b> Toggle Plot Area<br>
 <br>
 <b>SHIFT+C:</b>  Copy Obj_Name<br>
 <b>SHIFT+G:</b>  Toggle the axis<br>
@@ -795,6 +796,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
 <b>ALT+P:</b>    Paint Area Tool<br>
 <b>ALT+R:</b>    Transformation Tool<br>
 <b>ALT+U:</b>    Cutout PCB Tool<br>
+<b>ALT+1:</b>    Enable all Plots<br>
+<b>ALT+2:</b>    Disable all Plots<br>
+<b>ALT+3:</b>    Disable Non-selected Plots<br>
 <b>ALT+F10:</b>  Toggle Full Screen<br>
 <br>
 <b>F1:</b>       Open Online Manual<br>
@@ -808,18 +812,49 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         self.sh_app.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
         self.sh_hlay.addWidget(self.sh_app)
 
-        self.editor_sh_msg = '''<b>A:</b>       Draw an Arc (when in Edit Mode)<br>
-<b>C:</b>       Copy Geo Item (when in Edit Mode)<br>
-<b>M:</b>       Move Geo Item (when in Edit Mode)<br>
-<b>N:</b>       Draw a Polygon (when in Edit Mode)<br>
-<b>O:</b>       Draw a Circle (when in Edit Mode)<br>
-<b>P:</b>       Draw a Path (when in Edit Mode)<br>
-<b>R:</b>       Draw Rectangle (when in Edit Mode)<br>
+        self.editor_sh_msg = '''<b>Editor Shortcut list</b><br>
 <br>
-<b>CTRL+S:</b>   Save Object and Exit Editor (when in Edit Mode)<br>
+<b></b>         GEOMETRY EDITOR<br>
+<br>
+<b>A:</b>       Draw an Arc<br>
+<b>B:</b>       Buffer Tool<br>
+<b>C:</b>       Copy Geo Item<br>
+<b>E:</b>       Polygon Intersection Tool<br>
+
+<b>I:</b>       Paint Tool<br>
+<b>K:</b>       Toggle Corner Snap<br>
+
+<b>M:</b>       Move Geo Item<br>
+<b>N:</b>       Draw a Polygon<br>
+<b>O:</b>       Draw a Circle<br>
+<b>P:</b>       Draw a Path<br>
+<b>R:</b>       Draw Rectangle<br>
+<b>S:</b>       Polygon Substraction Tool<br>
+<b>T:</b>       Add Text Tool<br>
+<b>U:</b>       Polygon Union Tool<br>
+<b>X:</b>       Polygon Cut Tool<br>
+
+<br>
+<b>CTRL+S:</b>  Save Object and Exit Editor<br>
 <br>            
-<b>Space:</b>    Rotate Geometry<br>
-<b>ENTER:</b>    Finish drawing for certain tools<br>
+<b>Space:</b>   Rotate Geometry<br>
+<b>ENTER:</b>   Finish drawing for certain tools<br>
+<b>ESC:</b>     Abort and return to Select<br>
+<b>Del:</b>     Delete Shape<br>
+<br>
+<br>
+<b></b>         EXCELLON EDITOR<br>
+<br>
+<b>A:</b>       Add Drill Array<br>
+<b>C:</b>       Copy Drill(s)<br>
+<b>D:</b>       Add Drill<br>
+<b>M:</b>       Move Drill(s)<br>
+
+<b>R:</b>       Resize Drill(s)<br>
+<br>
+<b>Del:</b>     Delete Drill(s)<br>
+<b>ESC:</b>     Abort and return to Select<br>
+<b>CTRL+S:</b>  Save Object and Exit Editor<br>
         '''
         self.sh_editor = QtWidgets.QTextEdit()
         self.sh_editor.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
@@ -3196,11 +3231,11 @@ class FlatCAMInfoBar(QtWidgets.QWidget):
     def set_status(self, text, level="info"):
         level = str(level)
         self.pmap.fill()
-        if level == "error" or level == "error_notcl":
+        if level == "ERROR" or level == "ERROR_NOTCL":
             self.pmap = QtGui.QPixmap('share/redlight12.png')
         elif level == "success":
             self.pmap = QtGui.QPixmap('share/greenlight12.png')
-        elif level == "warning" or level == "warning_notcl":
+        elif level == "WARNING" or level == "WARNING_NOTCL":
             self.pmap = QtGui.QPixmap('share/yellowlight12.png')
         else:
             self.pmap = QtGui.QPixmap('share/graylight12.png')

+ 28 - 28
FlatCAMObj.py

@@ -1467,12 +1467,12 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
             log.debug("Tools 'all' and sorted are: %s" % str(tools))
 
         if len(tools) == 0:
-            self.app.inform.emit("[error_notcl]Please select one or more tools from the list and try again.")
+            self.app.inform.emit("[ERROR_NOTCL]Please select one or more tools from the list and try again.")
             return False, "Error: No tools."
 
         for tool in tools:
             if tooldia > self.tools[tool]["C"]:
-                self.app.inform.emit("[error_notcl] Milling tool for DRILLS is larger than hole size. Cancelled.")
+                self.app.inform.emit("[ERROR_NOTCL] Milling tool for DRILLS is larger than hole size. Cancelled.")
                 return False, "Error: Milling tool is larger than hole."
 
         def geo_init(geo_obj, app_obj):
@@ -1554,12 +1554,12 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
             log.debug("Tools 'all' and sorted are: %s" % str(tools))
 
         if len(tools) == 0:
-            self.app.inform.emit("[error_notcl]Please select one or more tools from the list and try again.")
+            self.app.inform.emit("[ERROR_NOTCL]Please select one or more tools from the list and try again.")
             return False, "Error: No tools."
 
         for tool in tools:
             if tooldia > self.tools[tool]["C"]:
-                self.app.inform.emit("[error_notcl] Milling tool for SLOTS is larger than hole size. Cancelled.")
+                self.app.inform.emit("[ERROR_NOTCL] Milling tool for SLOTS is larger than hole size. Cancelled.")
                 return False, "Error: Milling tool is larger than hole."
 
         def geo_init(geo_obj, app_obj):
@@ -1635,7 +1635,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
         tools = self.get_selected_tools_list()
 
         if len(tools) == 0:
-            self.app.inform.emit("[error_notcl]Please select one or more tools from the list and try again.")
+            self.app.inform.emit("[ERROR_NOTCL]Please select one or more tools from the list and try again.")
             return
 
         xmin = self.options['xmin']
@@ -1739,7 +1739,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
         else:
             coords_xy = [float(eval(coord)) for coord in self.app.defaults["excellon_toolchangexy"].split(",")]
             if len(coords_xy) < 2:
-                self.app.inform.emit("[error]The Toolchange X,Y field in Edit -> Preferences has to be "
+                self.app.inform.emit("[ERROR]The Toolchange X,Y field in Edit -> Preferences has to be "
                                      "in the format (x, y) \nbut now there is only one value, not two. ")
                 return 'fail'
             coords_xy[0] *= factor
@@ -2300,7 +2300,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
                                 self.ui.tool_offset_entry.get_value().replace(',', '.')
                             )
                         except ValueError:
-                            self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                            self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                                  "use a number.")
                             return
 
@@ -2438,7 +2438,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
 
             if tooldia is None:
                 self.build_ui()
-                self.app.inform.emit("[error_notcl] Please enter the desired tool diameter in Float format.")
+                self.app.inform.emit("[ERROR_NOTCL] Please enter the desired tool diameter in Float format.")
                 return
 
         # construct a list of all 'tooluid' in the self.tools
@@ -2514,7 +2514,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
             self.app.inform.emit("[success] Tool added in Tool Table.")
         else:
             change_message = False
-            self.app.inform.emit("[error_notcl]Default Tool added. Wrong value format entered.")
+            self.app.inform.emit("[ERROR_NOTCL]Default Tool added. Wrong value format entered.")
         self.build_ui()
 
     def on_tool_copy(self, all=None):
@@ -2542,7 +2542,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
                         max_uid += 1
                         self.tools[int(max_uid)] = copy.deepcopy(self.tools[tooluid_copy])
                     except AttributeError:
-                        self.app.inform.emit("[warning_notcl]Failed. Select a tool to copy.")
+                        self.app.inform.emit("[WARNING_NOTCL]Failed. Select a tool to copy.")
                         self.build_ui()
                         return
                     except Exception as e:
@@ -2550,7 +2550,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
                 # deselect the table
                 # self.ui.geo_tools_table.clearSelection()
             else:
-                self.app.inform.emit("[warning_notcl]Failed. Select a tool to copy.")
+                self.app.inform.emit("[WARNING_NOTCL]Failed. Select a tool to copy.")
                 self.build_ui()
                 return
         else:
@@ -2591,7 +2591,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
             try:
                 d = float(self.ui.geo_tools_table.item(current_row, 1).text().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                      "use a number.")
                 return
 
@@ -2631,7 +2631,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
                         self.tools = copy.deepcopy(temp_tools)
                         temp_tools.clear()
                     except AttributeError:
-                        self.app.inform.emit("[warning_notcl]Failed. Select a tool to delete.")
+                        self.app.inform.emit("[WARNING_NOTCL]Failed. Select a tool to delete.")
                         self.build_ui()
                         return
                     except Exception as e:
@@ -2639,7 +2639,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
                 # deselect the table
                 # self.ui.geo_tools_table.clearSelection()
             else:
-                self.app.inform.emit("[warning_notcl]Failed. Select a tool to delete.")
+                self.app.inform.emit("[WARNING_NOTCL]Failed. Select a tool to delete.")
                 self.build_ui()
                 return
         else:
@@ -2870,7 +2870,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
                 offset_value_item = float(self.ui.tool_offset_entry.get_value().replace(',', '.')
                                      )
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                      "use a number.")
                 return
 
@@ -3021,7 +3021,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
                     try:
                         tooldia = float(self.ui.geo_tools_table.item(x.row(), 1).text().replace(',', '.'))
                     except ValueError:
-                        self.app.inform.emit("[error_notcl]Wrong Tool Dia value format entered, "
+                        self.app.inform.emit("[ERROR_NOTCL]Wrong Tool Dia value format entered, "
                                              "use a number.")
                         return
                 tooluid = int(self.ui.geo_tools_table.item(x.row(), 5).text())
@@ -3035,7 +3035,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
 
             self.ui.geo_tools_table.clearSelection()
         else:
-            self.app.inform.emit("[error_notcl] Failed. No tool selected in the tool table ...")
+            self.app.inform.emit("[ERROR_NOTCL] Failed. No tool selected in the tool table ...")
 
     def mtool_gen_cncjob(self, segx=None, segy=None, use_thread=True):
         """
@@ -3185,14 +3185,14 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
                             offset_value = float(self.ui.tool_offset_entry.get_value().replace(',', '.')
                                                  )
                         except ValueError:
-                            self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                            self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                                  "use a number.")
                             return
                     if offset_value:
                         tool_offset = float(offset_value)
                     else:
                         self.app.inform.emit(
-                            "[warning] Tool Offset is selected in Tool Table but no value is provided.\n"
+                            "[WARNING] Tool Offset is selected in Tool Table but no value is provided.\n"
                             "Add a Tool Offset or change the Offset Type."
                         )
                         return
@@ -3372,14 +3372,14 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
                             offset_value = float(self.ui.tool_offset_entry.get_value().replace(',', '.')
                                                   )
                         except ValueError:
-                            self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                            self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                                  "use a number.")
                             return
                     if offset_value:
                         tool_offset = float(offset_value)
                     else:
                         self.app.inform.emit(
-                            "[warning] Tool Offset is selected in Tool Table but no value is provided.\n"
+                            "[WARNING] Tool Offset is selected in Tool Table but no value is provided.\n"
                             "Add a Tool Offset or change the Offset Type."
                         )
                         return
@@ -3595,7 +3595,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         try:
             xfactor = float(xfactor)
         except:
-            self.app.inform.emit("[error_notcl] Scale factor has to be a number: integer or float.")
+            self.app.inform.emit("[ERROR_NOTCL] Scale factor has to be a number: integer or float.")
             return
 
         if yfactor is None:
@@ -3604,7 +3604,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
             try:
                 yfactor = float(yfactor)
             except:
-                self.app.inform.emit("[error_notcl] Scale factor has to be a number: integer or float.")
+                self.app.inform.emit("[ERROR_NOTCL] Scale factor has to be a number: integer or float.")
                 return
 
         if point is None:
@@ -3654,7 +3654,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         try:
             dx, dy = vect
         except TypeError:
-            self.app.inform.emit("[error_notcl]An (x,y) pair of values are needed. "
+            self.app.inform.emit("[ERROR_NOTCL]An (x,y) pair of values are needed. "
                                  "Probable you entered only one value in the Offset field.")
             return
 
@@ -3698,7 +3698,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         else:
             coords_xy = [float(eval(coord)) for coord in self.app.defaults["geometry_toolchangexy"].split(",")]
             if len(coords_xy) < 2:
-                self.app.inform.emit("[error]The Toolchange X,Y field in Edit -> Preferences has to be "
+                self.app.inform.emit("[ERROR]The Toolchange X,Y field in Edit -> Preferences has to be "
                                      "in the format (x, y) \nbut now there is only one value, not two. ")
                 return 'fail'
             coords_xy[0] *= factor
@@ -3735,7 +3735,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
                             custom_offset = float(self.ui.tool_offset_entry.get_value().replace(',', '.')
                             )
                         except ValueError:
-                            self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                            self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                                  "use a number.")
                             return
 
@@ -4291,7 +4291,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
 
             # if it did not find 'G20' and it did not find 'G21' then there is an error and return
             if g_idx == -1:
-                self.app.inform.emit("[error_notcl] G-code does not have a units code: either G20 or G21")
+                self.app.inform.emit("[ERROR_NOTCL] G-code does not have a units code: either G20 or G21")
                 return
 
             g = gcode[:g_idx] + preamble + '\n' + gcode[g_idx:] + postamble
@@ -4307,7 +4307,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
                         f.write(line)
 
             except FileNotFoundError:
-                self.app.inform.emit("[warning_notcl] No such file or directory")
+                self.app.inform.emit("[WARNING_NOTCL] No such file or directory")
                 return
         elif to_file is False:
             # Just for adding it to the recent files list.

+ 2 - 2
ParseFont.py

@@ -287,8 +287,8 @@ class ParseFont():
             elif font_type == 'regular':
                 path_filename = regular_dict[font_name]
         except Exception as e:
-            self.app.inform.emit("[error_notcl] Font not supported, try another one.")
-            log.debug("[error_notcl] Font Loading: %s" % str(e))
+            self.app.inform.emit("[ERROR_NOTCL] Font not supported, try another one.")
+            log.debug("[ERROR_NOTCL] Font Loading: %s" % str(e))
             return "flatcam font parse failed"
 
         face = ft.Face(path_filename)

+ 2 - 2
ParseSVG.py

@@ -121,7 +121,7 @@ def path2shapely(path, object_type, res=1.0):
                 # geo_element = Polygon(points)
                 geo_element = LineString(points)
             else:
-                log.error("[error]: Not a valid target object.")
+                log.error("[ERROR]: Not a valid target object.")
             if not points:
                 continue
             else:
@@ -639,7 +639,7 @@ def parse_svg_transform(trstr):
             continue
 
         # raise Exception("Don't know how to parse: %s" % trstr)
-        log.error("[error] Don't know how to parse: %s" % trstr)
+        log.error("[ERROR] Don't know how to parse: %s" % trstr)
 
     return trlist
 

+ 10 - 1
README.md

@@ -9,6 +9,15 @@ CAD program, and create G-Code for Isolation routing.
 
 =================================================
 
+3.3.2019
+
+- updated the new shortcut list with the shortcuts added lately
+- now the special messages in the Shell are color coded according to the level. Before they all were RED. Now the WARNINGS are yellow, ERRORS are red and SUCCESS is a dark green. Also the level is in CAPS LOCK to make them more obvious
+- some more changes to GUI interface (solved issues)
+- added some status bar messages in the Geometry Editor to guide the user when using the Geometry Tools
+- now the '`' shortcut key that shows the 'shortcut key list' in Editors points to the same window which is created in a tab no longer as a pop-up window. This tab can be detached if needed.
+- 
+
 2.2.2019
 
 - code cleanup in Tools
@@ -288,7 +297,7 @@ CAD program, and create G-Code for Isolation routing.
 - solved a small bug that didn't allow the Paint Job to be done with lines when the results were geometries not iterable 
 - added protection for the case when trying to run the cncjob Tcl Command on a Geometry object that do not have solid geometry or one that is multi-tool
 - Paint Tool Table: now it is possible to edit a tool to a new diameter and then edit another tool to the former diameter of the first edited tool
-- added a new type of warning, [warning_notcl]
+- added a new type of warning, [WARNING_NOTCL]
 - fixed conflict with "space" keyboard shortcut for CNC job
 
 16.12.2018

+ 30 - 30
camlib.py

@@ -186,7 +186,7 @@ class Geometry(object):
         if isinstance(self.solid_geometry, list):
             return len(self.solid_geometry) == 0
 
-        self.app.inform.emit("[error_notcl] self.solid_geometry is neither BaseGeometry or list.")
+        self.app.inform.emit("[ERROR_NOTCL] self.solid_geometry is neither BaseGeometry or list.")
         return
 
     def subtract_polygon(self, points):
@@ -300,7 +300,7 @@ class Geometry(object):
         #     else:
         #         return self.solid_geometry.bounds
         # except Exception as e:
-        #     self.app.inform.emit("[error_notcl] Error cause: %s" % str(e))
+        #     self.app.inform.emit("[ERROR_NOTCL] Error cause: %s" % str(e))
 
         # log.debug("Geometry->bounds()")
         # if self.solid_geometry is None:
@@ -1361,7 +1361,7 @@ class Geometry(object):
                 self.solid_geometry = mirror_geom(self.solid_geometry)
             self.app.inform.emit('[success]Object was mirrored ...')
         except AttributeError:
-            self.app.inform.emit("[error_notcl] Failed to mirror. No object selected")
+            self.app.inform.emit("[ERROR_NOTCL] Failed to mirror. No object selected")
 
 
 
@@ -1401,7 +1401,7 @@ class Geometry(object):
                 self.solid_geometry = rotate_geom(self.solid_geometry)
             self.app.inform.emit('[success]Object was rotated ...')
         except AttributeError:
-            self.app.inform.emit("[error_notcl] Failed to rotate. No object selected")
+            self.app.inform.emit("[ERROR_NOTCL] Failed to rotate. No object selected")
 
     def skew(self, angle_x, angle_y, point):
         """
@@ -1437,7 +1437,7 @@ class Geometry(object):
                 self.solid_geometry = skew_geom(self.solid_geometry)
             self.app.inform.emit('[success]Object was skewed ...')
         except AttributeError:
-            self.app.inform.emit("[error_notcl] Failed to skew. No object selected")
+            self.app.inform.emit("[ERROR_NOTCL] Failed to skew. No object selected")
 
         # if type(self.solid_geometry) == list:
         #     self.solid_geometry = [affinity.skew(g, angle_x, angle_y, origin=(px, py))
@@ -2533,8 +2533,8 @@ class Gerber (Geometry):
                                     pass
                             last_path_aperture = current_aperture
                         else:
-                            self.app.inform.emit("[warning] Coordinates missing, line ignored: %s" % str(gline))
-                            self.app.inform.emit("[warning_notcl] GERBER file might be CORRUPT. Check the file !!!")
+                            self.app.inform.emit("[WARNING] Coordinates missing, line ignored: %s" % str(gline))
+                            self.app.inform.emit("[WARNING_NOTCL] GERBER file might be CORRUPT. Check the file !!!")
 
                     elif current_operation_code == 2:
                         if len(path) > 1:
@@ -2552,7 +2552,7 @@ class Gerber (Geometry):
                                         geo = Polygon(path)
                                     except ValueError:
                                         log.warning("Problem %s %s" % (gline, line_num))
-                                        self.app.inform.emit("[error] Region does not have enough points. "
+                                        self.app.inform.emit("[ERROR] Region does not have enough points. "
                                                              "File will be processed but there are parser errors. "
                                                              "Line number: %s" % str(line_num))
                             else:
@@ -2576,8 +2576,8 @@ class Gerber (Geometry):
                         if linear_x is not None and linear_y is not None:
                             path = [[linear_x, linear_y]]  # Start new path
                         else:
-                            self.app.inform.emit("[warning] Coordinates missing, line ignored: %s" % str(gline))
-                            self.app.inform.emit("[warning_notcl] GERBER file might be CORRUPT. Check the file !!!")
+                            self.app.inform.emit("[WARNING] Coordinates missing, line ignored: %s" % str(gline))
+                            self.app.inform.emit("[WARNING_NOTCL] GERBER file might be CORRUPT. Check the file !!!")
 
                     # Flash
                     # Not allowed in region mode.
@@ -2862,7 +2862,7 @@ class Gerber (Geometry):
 
             log.error("Gerber PARSING FAILED. Line %d: %s" % (line_num, gline))
             loc = 'Gerber Line #%d Gerber Line Content: %s\n' % (line_num, gline) + repr(err)
-            self.app.inform.emit("[error]Gerber Parser ERROR.\n%s:" % loc)
+            self.app.inform.emit("[ERROR]Gerber Parser ERROR.\n%s:" % loc)
 
     @staticmethod
     def create_flash_geometry(location, aperture, steps_per_circle=None):
@@ -3039,7 +3039,7 @@ class Gerber (Geometry):
         try:
             xfactor = float(xfactor)
         except:
-            self.app.inform.emit("[error_notcl] Scale factor has to be a number: integer or float.")
+            self.app.inform.emit("[ERROR_NOTCL] Scale factor has to be a number: integer or float.")
             return
 
         if yfactor is None:
@@ -3048,7 +3048,7 @@ class Gerber (Geometry):
             try:
                 yfactor = float(yfactor)
             except:
-                self.app.inform.emit("[error_notcl] Scale factor has to be a number: integer or float.")
+                self.app.inform.emit("[ERROR_NOTCL] Scale factor has to be a number: integer or float.")
                 return
 
         if point is None:
@@ -3100,7 +3100,7 @@ class Gerber (Geometry):
         try:
             dx, dy = vect
         except TypeError:
-            self.app.inform.emit("[error_notcl]An (x,y) pair of values are needed. "
+            self.app.inform.emit("[ERROR_NOTCL]An (x,y) pair of values are needed. "
                                  "Probable you entered only one value in the Offset field.")
             return
 
@@ -3464,7 +3464,7 @@ class Excellon(Geometry):
                 # and we need to exit from here
                 if self.detect_gcode_re.search(eline):
                     log.warning("This is GCODE mark: %s" % eline)
-                    self.app.inform.emit('[error_notcl] This is GCODE mark: %s' % eline)
+                    self.app.inform.emit('[ERROR_NOTCL] This is GCODE mark: %s' % eline)
                     return
 
                 # Header Begin (M48) #
@@ -3993,8 +3993,8 @@ class Excellon(Geometry):
 
         except Exception as e:
             log.error("Excellon PARSING FAILED. Line %d: %s" % (line_num, eline))
-            msg = "[error_notcl] An internal error has ocurred. See shell.\n"
-            msg += '[error] Excellon Parser error.\nParsing Failed. Line %d: %s\n' % (line_num, eline)
+            msg = "[ERROR_NOTCL] An internal error has ocurred. See shell.\n"
+            msg += '[ERROR] Excellon Parser error.\nParsing Failed. Line %d: %s\n' % (line_num, eline)
             msg += traceback.format_exc()
             self.app.inform.emit(msg)
 
@@ -4066,7 +4066,7 @@ class Excellon(Geometry):
             for drill in self.drills:
                 # poly = drill['point'].buffer(self.tools[drill['tool']]["C"]/2.0)
                 if drill['tool'] is '':
-                    self.app.inform.emit("[warning] Excellon.create_geometry() -> a drill location was skipped "
+                    self.app.inform.emit("[WARNING] Excellon.create_geometry() -> a drill location was skipped "
                                          "due of not having a tool associated.\n"
                                          "Check the resulting GCode.")
                     log.debug("Excellon.create_geometry() -> a drill location was skipped "
@@ -4534,14 +4534,14 @@ class CNCjob(Geometry):
         :rtype: None
         """
         if drillz > 0:
-            self.app.inform.emit("[warning] The Cut Z parameter has positive value. "
+            self.app.inform.emit("[WARNING] The Cut Z parameter has positive value. "
                                  "It is the depth value to drill into material.\n"
                                  "The Cut Z parameter needs to have a negative value, assuming it is a typo "
                                  "therefore the app will convert the value to negative. "
                                  "Check the resulting CNC code (Gcode etc).")
             self.z_cut = -drillz
         elif drillz == 0:
-            self.app.inform.emit("[warning] The Cut Z parameter is zero. "
+            self.app.inform.emit("[WARNING] The Cut Z parameter is zero. "
                                  "There will be no cut, skipping %s file" % exobj.options['name'])
             return
         else:
@@ -4555,7 +4555,7 @@ class CNCjob(Geometry):
             else:
                 self.toolchange_xy = [float(eval(a)) for a in toolchangexy.split(",")]
                 if len(self.toolchange_xy) < 2:
-                    self.app.inform.emit("[error]The Toolchange X,Y field in Edit -> Preferences has to be "
+                    self.app.inform.emit("[ERROR]The Toolchange X,Y field in Edit -> Preferences has to be "
                                          "in the format (x, y) \nbut now there is only one value, not two. ")
                     return 'fail'
         except Exception as e:
@@ -4817,7 +4817,7 @@ class CNCjob(Geometry):
                             self.oldy = locy
                 log.debug("The total travel distance with OR-TOOLS Basic Algorithm is: %s" % str(measured_distance))
             else:
-                self.app.inform.emit("[error_notcl] Wrong optimization type selected.")
+                self.app.inform.emit("[ERROR_NOTCL] Wrong optimization type selected.")
                 return
         else:
             log.debug("Using Travelling Salesman drill path optimization.")
@@ -4931,7 +4931,7 @@ class CNCjob(Geometry):
             else:
                 self.toolchange_xy = [float(eval(a)) for a in toolchangexy.split(",")]
                 if len(self.toolchange_xy) < 2:
-                    self.app.inform.emit("[error]The Toolchange X,Y field in Edit -> Preferences has to be "
+                    self.app.inform.emit("[ERROR]The Toolchange X,Y field in Edit -> Preferences has to be "
                                          "in the format (x, y) \nbut now there is only one value, not two. ")
                     return 'fail'
         except Exception as e:
@@ -4942,14 +4942,14 @@ class CNCjob(Geometry):
         self.f_plunge = self.app.defaults["geometry_f_plunge"]
 
         if self.z_cut > 0:
-            self.app.inform.emit("[warning] The Cut Z parameter has positive value. "
+            self.app.inform.emit("[WARNING] The Cut Z parameter has positive value. "
                                  "It is the depth value to cut into material.\n"
                                  "The Cut Z parameter needs to have a negative value, assuming it is a typo "
                                  "therefore the app will convert the value to negative."
                                  "Check the resulting CNC code (Gcode etc).")
             self.z_cut = -self.z_cut
         elif self.z_cut == 0:
-            self.app.inform.emit("[warning] The Cut Z parameter is zero. "
+            self.app.inform.emit("[WARNING] The Cut Z parameter is zero. "
                                  "There will be no cut, skipping %s file" % self.options['name'])
 
         ## Index first and last points in paths
@@ -5074,13 +5074,13 @@ class CNCjob(Geometry):
         """
 
         if not isinstance(geometry, Geometry):
-            self.app.inform.emit("[error]Expected a Geometry, got %s" % type(geometry))
+            self.app.inform.emit("[ERROR]Expected a Geometry, got %s" % type(geometry))
             return 'fail'
         log.debug("Generate_from_geometry_2()")
 
         # if solid_geometry is empty raise an exception
         if not geometry.solid_geometry:
-            self.app.inform.emit("[error_notcl]Trying to generate a CNC Job "
+            self.app.inform.emit("[ERROR_NOTCL]Trying to generate a CNC Job "
                                  "from a Geometry object without solid_geometry.")
 
         temp_solid_geometry = []
@@ -5125,7 +5125,7 @@ class CNCjob(Geometry):
             else:
                 self.toolchange_xy = [float(eval(a)) for a in toolchangexy.split(",")]
                 if len(self.toolchange_xy) < 2:
-                    self.app.inform.emit("[error]The Toolchange X,Y field in Edit -> Preferences has to be "
+                    self.app.inform.emit("[ERROR]The Toolchange X,Y field in Edit -> Preferences has to be "
                                          "in the format (x, y) \nbut now there is only one value, not two. ")
                     return 'fail'
         except Exception as e:
@@ -5136,14 +5136,14 @@ class CNCjob(Geometry):
         self.f_plunge = self.app.defaults["geometry_f_plunge"]
 
         if self.z_cut > 0:
-            self.app.inform.emit("[warning] The Cut Z parameter has positive value. "
+            self.app.inform.emit("[WARNING] The Cut Z parameter has positive value. "
                                  "It is the depth value to cut into material.\n"
                                  "The Cut Z parameter needs to have a negative value, assuming it is a typo "
                                  "therefore the app will convert the value to negative."
                                  "Check the resulting CNC code (Gcode etc).")
             self.z_cut = -self.z_cut
         elif self.z_cut == 0:
-            self.app.inform.emit("[warning] The Cut Z parameter is zero. "
+            self.app.inform.emit("[WARNING] The Cut Z parameter is zero. "
                                  "There will be no cut, skipping %s file" % geometry.options['name'])
 
         ## Index first and last points in paths

+ 7 - 7
flatcamTools/ToolCalculators.py

@@ -260,7 +260,7 @@ class ToolCalculator(FlatCAMTool):
             try:
                 tip_diameter = float(self.tipDia_entry.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                      "use a number.")
                 return
 
@@ -271,7 +271,7 @@ class ToolCalculator(FlatCAMTool):
             try:
                 half_tip_angle = float(self.tipAngle_entry.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                      "use a number.")
                 return
         half_tip_angle /= 2
@@ -283,7 +283,7 @@ class ToolCalculator(FlatCAMTool):
             try:
                 cut_depth = float(self.cutDepth_entry.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                      "use a number.")
                 return
 
@@ -305,7 +305,7 @@ class ToolCalculator(FlatCAMTool):
             try:
                 length = float(self.pcblength_entry.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                      "use a number.")
                 return
 
@@ -316,7 +316,7 @@ class ToolCalculator(FlatCAMTool):
             try:
                 width = float(self.pcbwidth_entry.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                      "use a number.")
                 return
 
@@ -327,7 +327,7 @@ class ToolCalculator(FlatCAMTool):
             try:
                 density = float(self.cdensity_entry.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                      "use a number.")
                 return
 
@@ -338,7 +338,7 @@ class ToolCalculator(FlatCAMTool):
             try:
                 copper = float(self.growth_entry.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                      "use a number.")
                 return
 

+ 17 - 17
flatcamTools/ToolCutOut.py

@@ -219,11 +219,11 @@ class ToolCutOut(FlatCAMTool):
         try:
             cutout_obj = self.app.collection.get_by_name(str(name))
         except:
-            self.app.inform.emit("[error_notcl]Could not retrieve object: %s" % name)
+            self.app.inform.emit("[ERROR_NOTCL]Could not retrieve object: %s" % name)
             return "Could not retrieve object: %s" % name
 
         if cutout_obj is None:
-            self.app.inform.emit("[error_notcl]There is no object selected for Cutout.\nSelect one and try again.")
+            self.app.inform.emit("[ERROR_NOTCL]There is no object selected for Cutout.\nSelect one and try again.")
             return
 
         try:
@@ -233,7 +233,7 @@ class ToolCutOut(FlatCAMTool):
             try:
                 dia = float(self.dia.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[warning_notcl] Tool diameter value is missing or wrong format. "
+                self.app.inform.emit("[WARNING_NOTCL] Tool diameter value is missing or wrong format. "
                                      "Add it and retry.")
                 return
 
@@ -244,7 +244,7 @@ class ToolCutOut(FlatCAMTool):
             try:
                 margin = float(self.margin.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[warning_notcl] Margin value is missing or wrong format. "
+                self.app.inform.emit("[WARNING_NOTCL] Margin value is missing or wrong format. "
                                      "Add it and retry.")
                 return
 
@@ -255,27 +255,27 @@ class ToolCutOut(FlatCAMTool):
             try:
                 gapsize = float(self.gapsize.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[warning_notcl] Gap size value is missing or wrong format. "
+                self.app.inform.emit("[WARNING_NOTCL] Gap size value is missing or wrong format. "
                                      "Add it and retry.")
                 return
 
         try:
             gaps = self.gaps.get_value()
         except TypeError:
-            self.app.inform.emit("[warning_notcl] Number of gaps value is missing. Add it and retry.")
+            self.app.inform.emit("[WARNING_NOTCL] Number of gaps value is missing. Add it and retry.")
             return
 
         if 0 in {dia}:
-            self.app.inform.emit("[warning_notcl]Tool Diameter is zero value. Change it to a positive integer.")
+            self.app.inform.emit("[WARNING_NOTCL]Tool Diameter is zero value. Change it to a positive integer.")
             return "Tool Diameter is zero value. Change it to a positive integer."
 
         if gaps not in ['lr', 'tb', '2lr', '2tb', '4', '8']:
-            self.app.inform.emit("[warning_notcl] Gaps value can be only one of: 'lr', 'tb', '2lr', '2tb', 4 or 8. "
+            self.app.inform.emit("[WARNING_NOTCL] Gaps value can be only one of: 'lr', 'tb', '2lr', '2tb', 4 or 8. "
                                  "Fill in a correct value and retry. ")
             return
 
         if cutout_obj.multigeo is True:
-            self.app.inform.emit("[error]Cutout operation cannot be done on a multi-geo Geometry.\n"
+            self.app.inform.emit("[ERROR]Cutout operation cannot be done on a multi-geo Geometry.\n"
                                  "Optionally, this Multi-geo Geometry can be converted to Single-geo Geometry,\n"
                                  "and after that perform Cutout.")
             return
@@ -359,11 +359,11 @@ class ToolCutOut(FlatCAMTool):
         try:
             cutout_obj = self.app.collection.get_by_name(str(name))
         except:
-            self.app.inform.emit("[error_notcl]Could not retrieve object: %s" % name)
+            self.app.inform.emit("[ERROR_NOTCL]Could not retrieve object: %s" % name)
             return "Could not retrieve object: %s" % name
 
         if cutout_obj is None:
-            self.app.inform.emit("[error_notcl]Object not found: %s" % cutout_obj)
+            self.app.inform.emit("[ERROR_NOTCL]Object not found: %s" % cutout_obj)
 
         try:
             dia = float(self.dia.get_value())
@@ -372,7 +372,7 @@ class ToolCutOut(FlatCAMTool):
             try:
                 dia = float(self.dia.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[warning_notcl] Tool diameter value is missing or wrong format. "
+                self.app.inform.emit("[WARNING_NOTCL] Tool diameter value is missing or wrong format. "
                                      "Add it and retry.")
                 return
 
@@ -383,7 +383,7 @@ class ToolCutOut(FlatCAMTool):
             try:
                 margin = float(self.margin.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[warning_notcl] Margin value is missing or wrong format. "
+                self.app.inform.emit("[WARNING_NOTCL] Margin value is missing or wrong format. "
                                      "Add it and retry.")
                 return
 
@@ -394,22 +394,22 @@ class ToolCutOut(FlatCAMTool):
             try:
                 gapsize = float(self.gapsize.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[warning_notcl] Gap size value is missing or wrong format. "
+                self.app.inform.emit("[WARNING_NOTCL] Gap size value is missing or wrong format. "
                                      "Add it and retry.")
                 return
 
         try:
             gaps = self.gaps_rect_radio.get_value()
         except TypeError:
-            self.app.inform.emit("[warning_notcl] Number of gaps value is missing. Add it and retry.")
+            self.app.inform.emit("[WARNING_NOTCL] Number of gaps value is missing. Add it and retry.")
             return
 
         if 0 in {dia}:
-            self.app.inform.emit("[error_notcl]Tool Diameter is zero value. Change it to a positive integer.")
+            self.app.inform.emit("[ERROR_NOTCL]Tool Diameter is zero value. Change it to a positive integer.")
             return "Tool Diameter is zero value. Change it to a positive integer."
 
         if cutout_obj.multigeo is True:
-            self.app.inform.emit("[error]Cutout operation cannot be done on a multi-geo Geometry.\n"
+            self.app.inform.emit("[ERROR]Cutout operation cannot be done on a multi-geo Geometry.\n"
                                  "Optionally, this Multi-geo Geometry can be converted to Single-geo Geometry,\n"
                                  "and after that perform Cutout.")
             return

+ 13 - 13
flatcamTools/ToolDblSided.py

@@ -283,7 +283,7 @@ class DblSidedTool(FlatCAMTool):
             try:
                 px, py = self.point_entry.get_value()
             except TypeError:
-                self.app.inform.emit("[warning_notcl] 'Point' reference is selected and 'Point' coordinates "
+                self.app.inform.emit("[WARNING_NOTCL] 'Point' reference is selected and 'Point' coordinates "
                                      "are missing. Add them and retry.")
                 return
         else:
@@ -298,14 +298,14 @@ class DblSidedTool(FlatCAMTool):
 
         dia = self.drill_dia.get_value()
         if dia is None:
-            self.app.inform.emit("[warning_notcl]No value or wrong format in Drill Dia entry. Add it and retry.")
+            self.app.inform.emit("[WARNING_NOTCL]No value or wrong format in Drill Dia entry. Add it and retry.")
             return
         tools = {"1": {"C": dia}}
 
         # holes = self.alignment_holes.get_value()
         holes = eval('[{}]'.format(self.alignment_holes.text()))
         if not holes:
-            self.app.inform.emit("[warning_notcl] There are no Alignment Drill Coordinates to use. Add them and retry.")
+            self.app.inform.emit("[WARNING_NOTCL] There are no Alignment Drill Coordinates to use. Add them and retry.")
             return
 
         drills = []
@@ -331,11 +331,11 @@ class DblSidedTool(FlatCAMTool):
         try:
             fcobj = model_index.internalPointer().obj
         except Exception as e:
-            self.app.inform.emit("[warning_notcl] There is no Gerber object loaded ...")
+            self.app.inform.emit("[WARNING_NOTCL] There is no Gerber object loaded ...")
             return
 
         if not isinstance(fcobj, FlatCAMGerber):
-            self.app.inform.emit("[error_notcl] Only Gerber, Excellon and Geometry objects can be mirrored.")
+            self.app.inform.emit("[ERROR_NOTCL] Only Gerber, Excellon and Geometry objects can be mirrored.")
             return
 
         axis = self.mirror_axis.get_value()
@@ -345,7 +345,7 @@ class DblSidedTool(FlatCAMTool):
             try:
                 px, py = self.point_entry.get_value()
             except TypeError:
-                self.app.inform.emit("[warning_notcl] 'Point' coordinates missing. "
+                self.app.inform.emit("[WARNING_NOTCL] 'Point' coordinates missing. "
                                      "Using Origin (0, 0) as mirroring reference.")
                 px, py = (0, 0)
 
@@ -355,7 +355,7 @@ class DblSidedTool(FlatCAMTool):
             try:
                 bb_obj = model_index_box.internalPointer().obj
             except Exception as e:
-                self.app.inform.emit("[warning_notcl] There is no Box object loaded ...")
+                self.app.inform.emit("[WARNING_NOTCL] There is no Box object loaded ...")
                 return
 
             xmin, ymin, xmax, ymax = bb_obj.bounds()
@@ -373,11 +373,11 @@ class DblSidedTool(FlatCAMTool):
         try:
             fcobj = model_index.internalPointer().obj
         except Exception as e:
-            self.app.inform.emit("[warning_notcl] There is no Excellon object loaded ...")
+            self.app.inform.emit("[WARNING_NOTCL] There is no Excellon object loaded ...")
             return
 
         if not isinstance(fcobj, FlatCAMExcellon):
-            self.app.inform.emit("[error_notcl] Only Gerber, Excellon and Geometry objects can be mirrored.")
+            self.app.inform.emit("[ERROR_NOTCL] Only Gerber, Excellon and Geometry objects can be mirrored.")
             return
 
         axis = self.mirror_axis.get_value()
@@ -391,7 +391,7 @@ class DblSidedTool(FlatCAMTool):
             try:
                 bb_obj = model_index_box.internalPointer().obj
             except Exception as e:
-                self.app.inform.emit("[warning_notcl] There is no Box object loaded ...")
+                self.app.inform.emit("[WARNING_NOTCL] There is no Box object loaded ...")
                 return
 
             xmin, ymin, xmax, ymax = bb_obj.bounds()
@@ -409,11 +409,11 @@ class DblSidedTool(FlatCAMTool):
         try:
             fcobj = model_index.internalPointer().obj
         except Exception as e:
-            self.app.inform.emit("[warning_notcl] There is no Geometry object loaded ...")
+            self.app.inform.emit("[WARNING_NOTCL] There is no Geometry object loaded ...")
             return
 
         if not isinstance(fcobj, FlatCAMGeometry):
-            self.app.inform.emit("[error_notcl] Only Gerber, Excellon and Geometry objects can be mirrored.")
+            self.app.inform.emit("[ERROR_NOTCL] Only Gerber, Excellon and Geometry objects can be mirrored.")
             return
 
         axis = self.mirror_axis.get_value()
@@ -427,7 +427,7 @@ class DblSidedTool(FlatCAMTool):
             try:
                 bb_obj = model_index_box.internalPointer().obj
             except Exception as e:
-                self.app.inform.emit("[warning_notcl] There is no Box object loaded ...")
+                self.app.inform.emit("[WARNING_NOTCL] There is no Box object loaded ...")
                 return
 
             xmin, ymin, xmax, ymax = bb_obj.bounds()

+ 3 - 3
flatcamTools/ToolFilm.py

@@ -164,12 +164,12 @@ class Film(FlatCAMTool):
         try:
             name = self.tf_object_combo.currentText()
         except:
-            self.app.inform.emit("[error_notcl] No Film object selected. Load a Film object and retry.")
+            self.app.inform.emit("[ERROR_NOTCL] No Film object selected. Load a Film object and retry.")
             return
         try:
             boxname = self.tf_box_combo.currentText()
         except:
-            self.app.inform.emit("[error_notcl] No Box object selected. Load a Box object and retry.")
+            self.app.inform.emit("[ERROR_NOTCL] No Box object selected. Load a Box object and retry.")
             return
 
         try:
@@ -179,7 +179,7 @@ class Film(FlatCAMTool):
             try:
                 border = float(self.boundary_entry.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                      "use a number.")
                 return
 

+ 6 - 6
flatcamTools/ToolMove.py

@@ -68,7 +68,7 @@ class ToolMove(FlatCAMTool):
                 self.setVisible(False)
                 # signal that there is no command active
                 self.app.command_active = None
-                self.app.inform.emit("[warning_notcl]MOVE action cancelled. No object(s) to move.")
+                self.app.inform.emit("[WARNING_NOTCL]MOVE action cancelled. No object(s) to move.")
 
     def on_left_click(self, event):
         # mouse click will be accepted only if the left button is clicked
@@ -115,7 +115,7 @@ class ToolMove(FlatCAMTool):
 
                         try:
                             if not obj_list:
-                                self.app.inform.emit("[warning_notcl] No object(s) selected.")
+                                self.app.inform.emit("[WARNING_NOTCL] No object(s) selected.")
                                 return "fail"
                             else:
                                 for sel_obj in obj_list:
@@ -131,7 +131,7 @@ class ToolMove(FlatCAMTool):
                                     # self.app.collection.set_active(sel_obj.options['name'])
                         except Exception as e:
                             proc.done()
-                            self.app.inform.emit('[error_notcl] '
+                            self.app.inform.emit('[ERROR_NOTCL] '
                                                  'ToolMove.on_left_click() --> %s' % str(e))
                             return "fail"
                         proc.done()
@@ -146,7 +146,7 @@ class ToolMove(FlatCAMTool):
                     return
 
                 except TypeError:
-                    self.app.inform.emit('[error_notcl] '
+                    self.app.inform.emit('[ERROR_NOTCL] '
                                          'ToolMove.on_left_click() --> Error when mouse left click.')
                     return
 
@@ -174,7 +174,7 @@ class ToolMove(FlatCAMTool):
     def on_key_press(self, event):
         if event.key == 'escape':
             # abort the move action
-            self.app.inform.emit("[warning_notcl]Move action cancelled.")
+            self.app.inform.emit("[WARNING_NOTCL]Move action cancelled.")
             self.toggle()
         return
 
@@ -186,7 +186,7 @@ class ToolMove(FlatCAMTool):
 
         obj_list = self.app.collection.get_selected()
         if not obj_list:
-            self.app.inform.emit("[warning_notcl]Object(s) not selected")
+            self.app.inform.emit("[WARNING_NOTCL]Object(s) not selected")
             self.toggle()
         else:
             # if we have an object selected then we can safely activate the mouse events

+ 14 - 14
flatcamTools/ToolNonCopperClear.py

@@ -437,12 +437,12 @@ class NonCopperClear(FlatCAMTool, Gerber):
                 try:
                     tool_dia = float(self.addtool_entry.get_value().replace(',', '.'))
                 except ValueError:
-                    self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                    self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                          "use a number.")
                     return
             if tool_dia is None:
                 self.build_ui()
-                self.app.inform.emit("[warning_notcl] Please enter a tool diameter to add, in Float format.")
+                self.app.inform.emit("[WARNING_NOTCL] Please enter a tool diameter to add, in Float format.")
                 return
 
         # construct a list of all 'tooluid' in the self.tools
@@ -466,7 +466,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
 
         if float('%.4f' % tool_dia) in tool_dias:
             if muted is None:
-                self.app.inform.emit("[warning_notcl]Adding tool cancelled. Tool already in Tool Table.")
+                self.app.inform.emit("[WARNING_NOTCL]Adding tool cancelled. Tool already in Tool Table.")
             self.tools_table.itemChanged.connect(self.on_tool_edit)
             return
         else:
@@ -504,7 +504,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
                 try:
                     new_tool_dia = float(self.tools_table.item(row, 1).text().replace(',', '.'))
                 except ValueError:
-                    self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                    self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                          "use a number.")
                     return
 
@@ -524,7 +524,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
                         break
                 restore_dia_item = self.tools_table.item(row, 1)
                 restore_dia_item.setText(str(old_tool_dia))
-                self.app.inform.emit("[warning_notcl] Edit cancelled. New diameter value is already in the Tool Table.")
+                self.app.inform.emit("[WARNING_NOTCL] Edit cancelled. New diameter value is already in the Tool Table.")
         self.build_ui()
 
     def on_tool_delete(self, rows_to_delete=None, all=None):
@@ -563,7 +563,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
                     self.ncc_tools.pop(t, None)
 
         except AttributeError:
-            self.app.inform.emit("[warning_notcl]Delete failed. Select a tool to delete.")
+            self.app.inform.emit("[WARNING_NOTCL]Delete failed. Select a tool to delete.")
             return
         except Exception as e:
             log.debug(str(e))
@@ -580,7 +580,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
             try:
                 over = float(self.ncc_overlap_entry.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                      "use a number.")
                 return
         over = over if over else self.app.defaults["tools_nccoverlap"]
@@ -592,7 +592,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
             try:
                 margin = float(self.ncc_margin_entry.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                      "use a number.")
                 return
         margin = margin if margin else self.app.defaults["tools_nccmargin"]
@@ -614,7 +614,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
         try:
             self.ncc_obj = self.app.collection.get_by_name(self.obj_name)
         except:
-            self.app.inform.emit("[error_notcl]Could not retrieve object: %s" % self.obj_name)
+            self.app.inform.emit("[ERROR_NOTCL]Could not retrieve object: %s" % self.obj_name)
             return "Could not retrieve object: %s" % self.obj_name
 
 
@@ -622,7 +622,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
         try:
             bounding_box = self.ncc_obj.solid_geometry.envelope.buffer(distance=margin, join_style=JOIN_STYLE.mitre)
         except AttributeError:
-            self.app.inform.emit("[error_notcl]No Gerber file available.")
+            self.app.inform.emit("[ERROR_NOTCL]No Gerber file available.")
             return
 
         # calculate the empty area by substracting the solid_geometry from the object bounding box geometry
@@ -747,14 +747,14 @@ class NonCopperClear(FlatCAMTool, Gerber):
                 app_obj.new_object("geometry", name, initialize)
             except Exception as e:
                 proc.done()
-                self.app.inform.emit('[error_notcl] NCCTool.clear_non_copper() --> %s' % str(e))
+                self.app.inform.emit('[ERROR_NOTCL] NCCTool.clear_non_copper() --> %s' % str(e))
                 return
             proc.done()
 
             if app_obj.poly_not_cleared is False:
                 self.app.inform.emit('[success] NCC Tool finished.')
             else:
-                self.app.inform.emit('[warning_notcl] NCC Tool finished but some PCB features could not be cleared. '
+                self.app.inform.emit('[WARNING_NOTCL] NCC Tool finished but some PCB features could not be cleared. '
                                      'Check the result.')
             # reset the variable for next use
             app_obj.poly_not_cleared = False
@@ -898,7 +898,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
                 app_obj.new_object("geometry", name, initialize_rm)
             except Exception as e:
                 proc.done()
-                self.app.inform.emit('[error_notcl] NCCTool.clear_non_copper_rest() --> %s' % str(e))
+                self.app.inform.emit('[ERROR_NOTCL] NCCTool.clear_non_copper_rest() --> %s' % str(e))
                 return
 
             if app_obj.poly_not_cleared is True:
@@ -906,7 +906,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
                 # focus on Selected Tab
                 self.app.ui.notebook.setCurrentWidget(self.app.ui.selected_tab)
             else:
-                self.app.inform.emit('[error_notcl] NCC Tool finished but could not clear the object '
+                self.app.inform.emit('[ERROR_NOTCL] NCC Tool finished but could not clear the object '
                                      'with current settings.')
                 # focus on Project Tab
                 self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab)

+ 24 - 24
flatcamTools/ToolPaint.py

@@ -493,13 +493,13 @@ class ToolPaint(FlatCAMTool, Gerber):
                 try:
                     tool_dia = float(self.addtool_entry.get_value().replace(',', '.'))
                 except ValueError:
-                    self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                    self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                          "use a number.")
                     return
 
             if tool_dia is None:
                 self.build_ui()
-                self.app.inform.emit("[warning_notcl] Please enter a tool diameter to add, in Float format.")
+                self.app.inform.emit("[WARNING_NOTCL] Please enter a tool diameter to add, in Float format.")
                 return
 
         # construct a list of all 'tooluid' in the self.tools
@@ -523,7 +523,7 @@ class ToolPaint(FlatCAMTool, Gerber):
 
         if float('%.4f' % tool_dia) in tool_dias:
             if muted is None:
-                self.app.inform.emit("[warning_notcl]Adding tool cancelled. Tool already in Tool Table.")
+                self.app.inform.emit("[WARNING_NOTCL]Adding tool cancelled. Tool already in Tool Table.")
             self.tools_table.itemChanged.connect(self.on_tool_edit)
             return
         else:
@@ -563,7 +563,7 @@ class ToolPaint(FlatCAMTool, Gerber):
                 try:
                     new_tool_dia = float(self.tools_table.item(row, 1).text().replace(',', '.'))
                 except ValueError:
-                    self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                    self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                          "use a number.")
                     return
             tooluid = int(self.tools_table.item(row, 3).text())
@@ -582,7 +582,7 @@ class ToolPaint(FlatCAMTool, Gerber):
                         break
                 restore_dia_item = self.tools_table.item(row, 1)
                 restore_dia_item.setText(str(old_tool_dia))
-                self.app.inform.emit("[warning_notcl] Edit cancelled. New diameter value is already in the Tool Table.")
+                self.app.inform.emit("[WARNING_NOTCL] Edit cancelled. New diameter value is already in the Tool Table.")
         self.build_ui()
 
     # def on_tool_copy(self, all=None):
@@ -615,7 +615,7 @@ class ToolPaint(FlatCAMTool, Gerber):
     #                         print("COPIED", self.paint_tools[td])
     #                     self.build_ui()
     #                 except AttributeError:
-    #                     self.app.inform.emit("[warning_notcl]Failed. Select a tool to copy.")
+    #                     self.app.inform.emit("[WARNING_NOTCL]Failed. Select a tool to copy.")
     #                     self.build_ui()
     #                     return
     #                 except Exception as e:
@@ -623,7 +623,7 @@ class ToolPaint(FlatCAMTool, Gerber):
     #             # deselect the table
     #             # self.ui.geo_tools_table.clearSelection()
     #         else:
-    #             self.app.inform.emit("[warning_notcl]Failed. Select a tool to copy.")
+    #             self.app.inform.emit("[WARNING_NOTCL]Failed. Select a tool to copy.")
     #             self.build_ui()
     #             return
     #     else:
@@ -679,7 +679,7 @@ class ToolPaint(FlatCAMTool, Gerber):
                     self.paint_tools.pop(t, None)
 
         except AttributeError:
-            self.app.inform.emit("[warning_notcl]Delete failed. Select a tool to delete.")
+            self.app.inform.emit("[WARNING_NOTCL]Delete failed. Select a tool to delete.")
             return
         except Exception as e:
             log.debug(str(e))
@@ -690,7 +690,7 @@ class ToolPaint(FlatCAMTool, Gerber):
     def on_paint_button_click(self):
         self.app.report_usage("geometry_on_paint_button")
 
-        self.app.inform.emit("[warning_notcl]Click inside the desired polygon.")
+        self.app.inform.emit("[WARNING_NOTCL]Click inside the desired polygon.")
         try:
             overlap = float(self.paintoverlap_entry.get_value())
         except ValueError:
@@ -698,7 +698,7 @@ class ToolPaint(FlatCAMTool, Gerber):
             try:
                 overlap = float(self.paintoverlap_entry.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                      "use a number.")
                 return
 
@@ -712,11 +712,11 @@ class ToolPaint(FlatCAMTool, Gerber):
         try:
             self.paint_obj = self.app.collection.get_by_name(str(self.obj_name))
         except:
-            self.app.inform.emit("[error_notcl]Could not retrieve object: %s" % self.obj_name)
+            self.app.inform.emit("[ERROR_NOTCL]Could not retrieve object: %s" % self.obj_name)
             return
 
         if self.paint_obj is None:
-            self.app.inform.emit("[error_notcl]Object not found: %s" % self.paint_obj)
+            self.app.inform.emit("[ERROR_NOTCL]Object not found: %s" % self.paint_obj)
             return
 
         o_name = '%s_multitool_paint' % (self.obj_name)
@@ -729,7 +729,7 @@ class ToolPaint(FlatCAMTool, Gerber):
                                 contour=contour)
 
         if select_method == "single":
-            self.app.inform.emit("[warning_notcl]Click inside the desired polygon.")
+            self.app.inform.emit("[WARNING_NOTCL]Click inside the desired polygon.")
 
             # use the first tool in the tool table; get the diameter
             tooldia = float('%.4f' % float(self.tools_table.item(0, 1).text()))
@@ -780,14 +780,14 @@ class ToolPaint(FlatCAMTool, Gerber):
             try:
                 paint_margin = float(self.paintmargin_entry.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                      "use a number.")
                 return
 
         # No polygon?
         if poly is None:
             self.app.log.warning('No polygon found.')
-            self.app.inform.emit('[warning] No polygon found.')
+            self.app.inform.emit('[WARNING] No polygon found.')
             return
 
         proc = self.app.proc_container.new("Painting polygon.")
@@ -832,7 +832,7 @@ class ToolPaint(FlatCAMTool, Gerber):
                     geo_obj.solid_geometry += list(cp.get_objects())
                     return cp
                 else:
-                    self.app.inform.emit('[error_notcl] Geometry could not be painted completely')
+                    self.app.inform.emit('[ERROR_NOTCL] Geometry could not be painted completely')
                     return None
 
             geo_obj.solid_geometry = []
@@ -847,7 +847,7 @@ class ToolPaint(FlatCAMTool, Gerber):
             except Exception as e:
                 log.debug("Could not Paint the polygons. %s" % str(e))
                 self.app.inform.emit(
-                    "[error] Could not do Paint. Try a different combination of parameters. "
+                    "[ERROR] Could not do Paint. Try a different combination of parameters. "
                     "Or a different strategy of paint\n%s" % str(e))
                 return
 
@@ -878,7 +878,7 @@ class ToolPaint(FlatCAMTool, Gerber):
             #     self.app.inform.emit("[success] Paint single polygon Done")
             # else:
             #     print("[WARNING] Paint single polygon done with errors")
-            #     self.app.inform.emit("[warning] Paint single polygon done with errors. "
+            #     self.app.inform.emit("[WARNING] Paint single polygon done with errors. "
             #                          "%d area(s) could not be painted.\n"
             #                          "Use different paint parameters or edit the paint geometry and correct"
             #                          "the issue."
@@ -889,7 +889,7 @@ class ToolPaint(FlatCAMTool, Gerber):
                 app_obj.new_object("geometry", name, gen_paintarea)
             except Exception as e:
                 proc.done()
-                self.app.inform.emit('[error_notcl] PaintTool.paint_poly() --> %s' % str(e))
+                self.app.inform.emit('[ERROR_NOTCL] PaintTool.paint_poly() --> %s' % str(e))
                 return
             proc.done()
             # focus on Selected Tab
@@ -924,7 +924,7 @@ class ToolPaint(FlatCAMTool, Gerber):
             try:
                 paint_margin = float(self.paintmargin_entry.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                      "use a number.")
                 return
 
@@ -1033,7 +1033,7 @@ class ToolPaint(FlatCAMTool, Gerber):
                     except Exception as e:
                         log.debug("Could not Paint the polygons. %s" % str(e))
                         self.app.inform.emit(
-                            "[error] Could not do Paint All. Try a different combination of parameters. "
+                            "[ERROR] Could not do Paint All. Try a different combination of parameters. "
                             "Or a different Method of paint\n%s" % str(e))
                         return
 
@@ -1057,7 +1057,7 @@ class ToolPaint(FlatCAMTool, Gerber):
                 if geo_obj.tools[tooluid]['solid_geometry']:
                     has_solid_geo += 1
             if has_solid_geo == 0:
-                self.app.inform.emit("[error] There is no Painting Geometry in the file.\n"
+                self.app.inform.emit("[ERROR] There is no Painting Geometry in the file.\n"
                                       "Usually it means that the tool diameter is too big for the painted geometry.\n"
                                       "Change the painting parameters and try again.")
                 return
@@ -1112,7 +1112,7 @@ class ToolPaint(FlatCAMTool, Gerber):
                     except Exception as e:
                         log.debug("Could not Paint the polygons. %s" % str(e))
                         self.app.inform.emit(
-                            "[error] Could not do Paint All. Try a different combination of parameters. "
+                            "[ERROR] Could not do Paint All. Try a different combination of parameters. "
                             "Or a different Method of paint\n%s" % str(e))
                         return
 
@@ -1142,7 +1142,7 @@ class ToolPaint(FlatCAMTool, Gerber):
                 if geo_obj.tools[tooluid]['solid_geometry']:
                     has_solid_geo += 1
             if has_solid_geo == 0:
-                self.app.inform.emit("[error_notcl] There is no Painting Geometry in the file.\n"
+                self.app.inform.emit("[ERROR_NOTCL] There is no Painting Geometry in the file.\n"
                                       "Usually it means that the tool diameter is too big for the painted geometry.\n"
                                       "Change the painting parameters and try again.")
                 return

+ 13 - 13
flatcamTools/ToolPanelize.py

@@ -214,13 +214,13 @@ class Panelize(FlatCAMTool):
         try:
             obj = self.app.collection.get_by_name(str(name))
         except:
-            self.app.inform.emit("[error_notcl]Could not retrieve object: %s" % name)
+            self.app.inform.emit("[ERROR_NOTCL]Could not retrieve object: %s" % name)
             return "Could not retrieve object: %s" % name
 
         panel_obj = obj
 
         if panel_obj is None:
-            self.app.inform.emit("[error_notcl]Object not found: %s" % panel_obj)
+            self.app.inform.emit("[ERROR_NOTCL]Object not found: %s" % panel_obj)
             return "Object not found: %s" % panel_obj
 
         boxname = self.box_combo.currentText()
@@ -228,11 +228,11 @@ class Panelize(FlatCAMTool):
         try:
             box = self.app.collection.get_by_name(boxname)
         except:
-            self.app.inform.emit("[error_notcl]Could not retrieve object: %s" % boxname)
+            self.app.inform.emit("[ERROR_NOTCL]Could not retrieve object: %s" % boxname)
             return "Could not retrieve object: %s" % boxname
 
         if box is None:
-            self.app.inform.emit("[warning]No object Box. Using instead %s" % panel_obj)
+            self.app.inform.emit("[WARNING]No object Box. Using instead %s" % panel_obj)
             box = panel_obj
 
         self.outname = name + '_panelized'
@@ -244,7 +244,7 @@ class Panelize(FlatCAMTool):
             try:
                 spacing_columns = float(self.spacing_columns.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                      "use a number.")
                 return
         spacing_columns = spacing_columns if spacing_columns is not None else 0
@@ -256,7 +256,7 @@ class Panelize(FlatCAMTool):
             try:
                 spacing_rows = float(self.spacing_rows.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                      "use a number.")
                 return
         spacing_rows = spacing_rows if spacing_rows is not None else 0
@@ -269,7 +269,7 @@ class Panelize(FlatCAMTool):
                 rows = float(self.rows.get_value().replace(',', '.'))
                 rows = int(rows)
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                      "use a number.")
                 return
         rows = rows if rows is not None else 1
@@ -282,7 +282,7 @@ class Panelize(FlatCAMTool):
                 columns = float(self.columns.get_value().replace(',', '.'))
                 columns = int(columns)
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                      "use a number.")
                 return
         columns = columns if columns is not None else 1
@@ -294,7 +294,7 @@ class Panelize(FlatCAMTool):
             try:
                 constrain_dx = float(self.x_width_entry.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                      "use a number.")
                 return
 
@@ -305,12 +305,12 @@ class Panelize(FlatCAMTool):
             try:
                 constrain_dy = float(self.y_height_entry.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
                                      "use a number.")
                 return
 
         if 0 in {columns, rows}:
-            self.app.inform.emit("[error_notcl]Columns or Rows are zero value. Change them to a positive integer.")
+            self.app.inform.emit("[ERROR_NOTCL]Columns or Rows are zero value. Change them to a positive integer.")
             return "Columns or Rows are zero value. Change them to a positive integer."
 
         xmin, ymin, xmax, ymax = box.bounds()
@@ -406,7 +406,7 @@ class Panelize(FlatCAMTool):
         #             self.app.new_object("geometry", self.outname, job_init_geometry, plot=True, autoselected=True)
         #
         #     else:
-        #         self.app.inform.emit("[error_notcl] Obj is None")
+        #         self.app.inform.emit("[ERROR_NOTCL] Obj is None")
         #         return "ERROR: Obj is None"
 
         # panelize()
@@ -519,7 +519,7 @@ class Panelize(FlatCAMTool):
             self.app.inform.emit("[success]Panel done...")
         else:
             self.constrain_flag = False
-            self.app.inform.emit("[warning] Too big for the constrain area. Final panel has %s columns and %s rows" %
+            self.app.inform.emit("[WARNING] Too big for the constrain area. Final panel has %s columns and %s rows" %
                                  (columns, rows))
 
         proc = self.app.proc_container.new("Generating panel ... Please wait.")

+ 1 - 1
flatcamTools/ToolProperties.py

@@ -60,7 +60,7 @@ class Properties(FlatCAMTool):
     def properties(self):
         obj_list = self.app.collection.get_selected()
         if not obj_list:
-            self.app.inform.emit("[error_notcl] Properties Tool was not displayed. No object selected.")
+            self.app.inform.emit("[ERROR_NOTCL] Properties Tool was not displayed. No object selected.")
             self.app.ui.notebook.setTabText(2, "Tools")
             self.properties_frame.hide()
             self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab)

+ 15 - 1
flatcamTools/ToolShell.py

@@ -234,7 +234,7 @@ class TermWidget(QWidget):
         """
         Convert text to HTML for inserting it to browser
         """
-        assert style in ('in', 'out', 'err')
+        assert style in ('in', 'out', 'err', 'warning', 'success')
 
         text = html.escape(text)
         text = text.replace('\n', '<br/>')
@@ -243,6 +243,10 @@ class TermWidget(QWidget):
             text = '<span style="font-weight: bold;">%s</span>' % text
         elif style == 'err':
             text = '<span style="font-weight: bold; color: red;">%s</span>' % text
+        elif style == 'warning':
+            text = '<span style="font-weight: bold; color: rgb(244, 182, 66);">%s</span>' % text
+        elif style == 'success':
+            text = '<span style="font-weight: bold; color: rgb(8, 68, 0);">%s</span>' % text
         else:
             text = '<span>%s</span>' % text  # without span <br/> is ignored!!!
 
@@ -304,6 +308,16 @@ class TermWidget(QWidget):
         """
         self._append_to_browser('out', text)
 
+    def append_success(self, text):
+        """Appent text to output widget
+        """
+        self._append_to_browser('success', text)
+
+    def append_warning(self, text):
+        """Appent text to output widget
+        """
+        self._append_to_browser('warning', text)
+
     def append_error(self, text):
         """Appent error text to output widget. Text is drawn with red background
         """

+ 17 - 17
flatcamTools/ToolTransform.py

@@ -382,7 +382,7 @@ class ToolTransform(FlatCAMTool):
             try:
                 value = float(self.rotate_entry.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered for Rotate, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered for Rotate, "
                                      "use a number.")
                 return
         self.app.worker_task.emit({'fcn': self.on_rotate_action,
@@ -416,7 +416,7 @@ class ToolTransform(FlatCAMTool):
             try:
                 value = float(self.skewx_entry.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered for Skew X, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered for Skew X, "
                                      "use a number.")
                 return
 
@@ -434,7 +434,7 @@ class ToolTransform(FlatCAMTool):
             try:
                 value = float(self.skewy_entry.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered for Skew Y, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered for Skew Y, "
                                      "use a number.")
                 return
 
@@ -452,7 +452,7 @@ class ToolTransform(FlatCAMTool):
             try:
                 xvalue = float(self.scalex_entry.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered for Scale X, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered for Scale X, "
                                      "use a number.")
                 return
 
@@ -486,7 +486,7 @@ class ToolTransform(FlatCAMTool):
             try:
                 yvalue = float(self.scaley_entry.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered for Scale Y, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered for Scale Y, "
                                      "use a number.")
                 return
 
@@ -515,7 +515,7 @@ class ToolTransform(FlatCAMTool):
             try:
                 value = float(self.offx_entry.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered for Offset X, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered for Offset X, "
                                      "use a number.")
                 return
 
@@ -533,7 +533,7 @@ class ToolTransform(FlatCAMTool):
             try:
                 value = float(self.offy_entry.get_value().replace(',', '.'))
             except ValueError:
-                self.app.inform.emit("[error_notcl]Wrong value format entered for Offset Y, "
+                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered for Offset Y, "
                                      "use a number.")
                 return
 
@@ -551,7 +551,7 @@ class ToolTransform(FlatCAMTool):
         ymaxlist = []
 
         if not obj_list:
-            self.app.inform.emit("[warning_notcl] No object selected. Please Select an object to rotate!")
+            self.app.inform.emit("[WARNING_NOTCL] No object selected. Please Select an object to rotate!")
             return
         else:
             with self.app.proc_container.new("Appying Rotate"):
@@ -592,7 +592,7 @@ class ToolTransform(FlatCAMTool):
                     self.app.progress.emit(100)
 
                 except Exception as e:
-                    self.app.inform.emit("[error_notcl] Due of %s, rotation movement was not executed." % str(e))
+                    self.app.inform.emit("[ERROR_NOTCL] Due of %s, rotation movement was not executed." % str(e))
                     return
 
     def on_flip(self, axis):
@@ -603,7 +603,7 @@ class ToolTransform(FlatCAMTool):
         ymaxlist = []
 
         if not obj_list:
-            self.app.inform.emit("[warning_notcl] No object selected. Please Select an object to flip!")
+            self.app.inform.emit("[WARNING_NOTCL] No object selected. Please Select an object to flip!")
             return
         else:
             with self.app.proc_container.new("Applying Flip"):
@@ -665,7 +665,7 @@ class ToolTransform(FlatCAMTool):
                     self.app.progress.emit(100)
 
                 except Exception as e:
-                    self.app.inform.emit("[error_notcl] Due of %s, Flip action was not executed." % str(e))
+                    self.app.inform.emit("[ERROR_NOTCL] Due of %s, Flip action was not executed." % str(e))
                     return
 
     def on_skew(self, axis, num):
@@ -674,7 +674,7 @@ class ToolTransform(FlatCAMTool):
         yminlist = []
 
         if not obj_list:
-            self.app.inform.emit("[warning_notcl] No object selected. Please Select an object to shear/skew!")
+            self.app.inform.emit("[WARNING_NOTCL] No object selected. Please Select an object to shear/skew!")
             return
         else:
             with self.app.proc_container.new("Applying Skew"):
@@ -712,7 +712,7 @@ class ToolTransform(FlatCAMTool):
                     self.app.progress.emit(100)
 
                 except Exception as e:
-                    self.app.inform.emit("[error_notcl] Due of %s, Skew action was not executed." % str(e))
+                    self.app.inform.emit("[ERROR_NOTCL] Due of %s, Skew action was not executed." % str(e))
                     return
 
     def on_scale(self, axis, xfactor, yfactor, point=None):
@@ -723,7 +723,7 @@ class ToolTransform(FlatCAMTool):
         ymaxlist = []
 
         if not obj_list:
-            self.app.inform.emit("[warning_notcl] No object selected. Please Select an object to scale!")
+            self.app.inform.emit("[WARNING_NOTCL] No object selected. Please Select an object to scale!")
             return
         else:
             with self.app.proc_container.new("Applying Scale"):
@@ -767,7 +767,7 @@ class ToolTransform(FlatCAMTool):
                     self.app.inform.emit('Object(s) were scaled on %s axis ...' % str(axis))
                     self.app.progress.emit(100)
                 except Exception as e:
-                    self.app.inform.emit("[error_notcl] Due of %s, Scale action was not executed." % str(e))
+                    self.app.inform.emit("[ERROR_NOTCL] Due of %s, Scale action was not executed." % str(e))
                     return
 
     def on_offset(self, axis, num):
@@ -776,7 +776,7 @@ class ToolTransform(FlatCAMTool):
         yminlist = []
 
         if not obj_list:
-            self.app.inform.emit("[warning_notcl] No object selected. Please Select an object to offset!")
+            self.app.inform.emit("[WARNING_NOTCL] No object selected. Please Select an object to offset!")
             return
         else:
             with self.app.proc_container.new("Applying Offset"):
@@ -813,7 +813,7 @@ class ToolTransform(FlatCAMTool):
                     self.app.progress.emit(100)
 
                 except Exception as e:
-                    self.app.inform.emit("[error_notcl] Due of %s, Offset action was not executed." % str(e))
+                    self.app.inform.emit("[ERROR_NOTCL] Due of %s, Offset action was not executed." % str(e))
                     return
 
 # end of file

+ 1 - 1
tclCommands/TclCommandCutout.py

@@ -56,7 +56,7 @@ class TclCommandCutout(TclCommand):
             name = args['name']
         else:
             self.app.inform.emit(
-                "[warning]The name of the object for which cutout is done is missing. Add it and retry.")
+                "[WARNING]The name of the object for which cutout is done is missing. Add it and retry.")
             return
 
         if 'margin' in args:

+ 4 - 4
tclCommands/TclCommandCutoutAny.py

@@ -61,7 +61,7 @@ class TclCommandCutoutAny(TclCommand):
             name = args['name']
         else:
             self.app.inform.emit(
-                "[warning]The name of the object for which cutout is done is missing. Add it and retry.")
+                "[WARNING]The name of the object for which cutout is done is missing. Add it and retry.")
             return
 
         if 'margin' in args:
@@ -91,11 +91,11 @@ class TclCommandCutoutAny(TclCommand):
             return "Could not retrieve object: %s" % name
 
         if 0 in {dia}:
-            self.app.inform.emit("[warning]Tool Diameter is zero value. Change it to a positive integer.")
+            self.app.inform.emit("[WARNING]Tool Diameter is zero value. Change it to a positive integer.")
             return "Tool Diameter is zero value. Change it to a positive integer."
 
         if gaps not in ['lr', 'tb', '2lr', '2tb', 4, 8]:
-            self.app.inform.emit("[warning]Gaps value can be only one of: 'lr', 'tb', '2lr', '2tb', 4 or 8. "
+            self.app.inform.emit("[WARNING]Gaps value can be only one of: 'lr', 'tb', '2lr', '2tb', 4 or 8. "
                                  "Fill in a correct value and retry. ")
             return
 
@@ -129,7 +129,7 @@ class TclCommandCutoutAny(TclCommand):
 
             cutout_obj = self.app.collection.get_by_name(outname)
         else:
-            self.app.inform.emit("[error]Cancelled. Object type is not supported.")
+            self.app.inform.emit("[ERROR]Cancelled. Object type is not supported.")
             return
 
         try:

+ 2 - 2
tclCommands/TclCommandOpenGerber.py

@@ -57,12 +57,12 @@ class TclCommandOpenGerber(TclCommandSignaled):
                 gerber_obj.parse_file(filename, follow=follow)
 
             except IOError:
-                app_obj.inform.emit("[error_notcl] Failed to open file: %s " % filename)
+                app_obj.inform.emit("[ERROR_NOTCL] Failed to open file: %s " % filename)
                 app_obj.progress.emit(0)
                 self.raise_tcl_error('Failed to open file: %s' % filename)
 
             except ParseError as e:
-                app_obj.inform.emit("[error_notcl] Failed to parse file: %s, %s " % (filename, str(e)))
+                app_obj.inform.emit("[ERROR_NOTCL] Failed to parse file: %s, %s " % (filename, str(e)))
                 app_obj.progress.emit(0)
                 self.log.error(str(e))
                 return