Преглед изворни кода

- finished adding in Paint Tool the usage of an external object to set the extent of th area painted. For simple shapes (single Polygon) the shape can be anything, for the rest will be a convex hull of the reference object
- modified NCC tool so for simple objects (single Polygon) the external object used as reference can have any shape, for the other types of objects the copper cleared area will be the convex hull of the reference object
- modified the strings of the app wherever they contained the char seq <b> </b> so it is not included in the translated string

Marius Stanciu пре 6 година
родитељ
комит
36586aecce

+ 2 - 2
FlatCAMApp.py

@@ -4027,7 +4027,7 @@ class App(QtCore.QObject):
         msgbox = QtWidgets.QMessageBox()
         msgbox = QtWidgets.QMessageBox()
         msgbox.setWindowTitle(_("Toggle Units"))
         msgbox.setWindowTitle(_("Toggle Units"))
         msgbox.setWindowIcon(QtGui.QIcon('share/toggle_units32.png'))
         msgbox.setWindowIcon(QtGui.QIcon('share/toggle_units32.png'))
-        msgbox.setText(_("<B>Change project units ...</B>"))
+        msgbox.setText("<B>%s</B>" % _("Change project units ..."))
         msgbox.setInformativeText(_("Changing the units of the project causes all geometrical "
         msgbox.setInformativeText(_("Changing the units of the project causes all geometrical "
                                     "properties of all objects to be scaled accordingly.\nContinue?"))
                                     "properties of all objects to be scaled accordingly.\nContinue?"))
         bt_ok = msgbox.addButton(_('Ok'), QtWidgets.QMessageBox.AcceptRole)
         bt_ok = msgbox.addButton(_('Ok'), QtWidgets.QMessageBox.AcceptRole)
@@ -5007,7 +5007,7 @@ class App(QtCore.QObject):
                 msgbox = QtWidgets.QMessageBox()
                 msgbox = QtWidgets.QMessageBox()
                 msgbox.setWindowTitle(_("Delete objects"))
                 msgbox.setWindowTitle(_("Delete objects"))
                 msgbox.setWindowIcon(QtGui.QIcon('share/deleteshape32.png'))
                 msgbox.setWindowIcon(QtGui.QIcon('share/deleteshape32.png'))
-                # msgbox.setText(_("<B>Delete FlatCAM objects ...</B>"))
+                # msgbox.setText("<B>%s</B>" % _("Change project units ..."))
                 msgbox.setText(_("Are you sure you want to permanently delete\n"
                 msgbox.setText(_("Are you sure you want to permanently delete\n"
                                  "the selected objects?"))
                                  "the selected objects?"))
                 bt_ok = msgbox.addButton(_('Ok'), QtWidgets.QMessageBox.AcceptRole)
                 bt_ok = msgbox.addButton(_('Ok'), QtWidgets.QMessageBox.AcceptRole)

+ 3 - 0
README.md

@@ -17,6 +17,9 @@ CAD program, and create G-Code for Isolation routing.
 - in NCC Tool added a new parameter (radio button) that offer the choice on the order of the tools both in tools table and in execution of engraving; added as a parameter also in Edit -> Preferences -> Tools -> NCC Tool
 - in NCC Tool added a new parameter (radio button) that offer the choice on the order of the tools both in tools table and in execution of engraving; added as a parameter also in Edit -> Preferences -> Tools -> NCC Tool
 - added possibility to drag & drop FlatCAM config files (*.FlatConfig) into the canvas to be opened into the application
 - added possibility to drag & drop FlatCAM config files (*.FlatConfig) into the canvas to be opened into the application
 - added GUI in Paint tool in beginning to add Paint by external reference object 
 - added GUI in Paint tool in beginning to add Paint by external reference object 
+- finished adding in Paint Tool the usage of an external object to set the extent of th area painted. For simple shapes (single Polygon) the shape can be anything, for the rest will be a convex hull of the reference object
+- modified NCC tool so for simple objects (single Polygon) the external object used as reference can have any shape, for the other types of objects the copper cleared area will be the convex hull of the reference object
+- modified the strings of the app wherever they contained the char seq <b> </b> so it is not included in the translated string
 
 
 17.08.2019
 17.08.2019
 
 

+ 38 - 32
flatcamGUI/FlatCAMGUI.py

@@ -4166,7 +4166,7 @@ class GerberGenPrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("Gerber General")))
         self.setTitle(str(_("Gerber General")))
 
 
         # ## Plot options
         # ## Plot options
-        self.plot_options_label = QtWidgets.QLabel(_("<b>Plot Options:</b>"))
+        self.plot_options_label = QtWidgets.QLabel("<b>%s:</b>" % _("Plot Options"))
         self.layout.addWidget(self.plot_options_label)
         self.layout.addWidget(self.plot_options_label)
 
 
         grid0 = QtWidgets.QGridLayout()
         grid0 = QtWidgets.QGridLayout()
@@ -4214,7 +4214,7 @@ class GerberOptPrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("Gerber Options")))
         self.setTitle(str(_("Gerber Options")))
 
 
         # ## Isolation Routing
         # ## Isolation Routing
-        self.isolation_routing_label = QtWidgets.QLabel(_("<b>Isolation Routing:</b>"))
+        self.isolation_routing_label = QtWidgets.QLabel("<b>%s:</b>" % _("Isolation Routing"))
         self.isolation_routing_label.setToolTip(
         self.isolation_routing_label.setToolTip(
             _("Create a Geometry object with\n"
             _("Create a Geometry object with\n"
               "toolpaths to cut outside polygons.")
               "toolpaths to cut outside polygons.")
@@ -4274,7 +4274,7 @@ class GerberOptPrefGroupUI(OptionsGroupUI):
         grid0.addWidget(self.combine_passes_cb, 4, 0, 1, 2)
         grid0.addWidget(self.combine_passes_cb, 4, 0, 1, 2)
 
 
         # ## Clear non-copper regions
         # ## Clear non-copper regions
-        self.clearcopper_label = QtWidgets.QLabel(_("<b>Clear non-copper:</b>"))
+        self.clearcopper_label = QtWidgets.QLabel("<b>%s:</b>" % _("Clear non-copper"))
         self.clearcopper_label.setToolTip(
         self.clearcopper_label.setToolTip(
             _("Create a Geometry object with\n"
             _("Create a Geometry object with\n"
               "toolpaths to cut all non-copper regions.")
               "toolpaths to cut all non-copper regions.")
@@ -4339,7 +4339,7 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("Gerber Adv. Options")))
         self.setTitle(str(_("Gerber Adv. Options")))
 
 
         # ## Advanced Gerber Parameters
         # ## Advanced Gerber Parameters
-        self.adv_param_label = QtWidgets.QLabel(_("<b>Advanced Param.:</b>"))
+        self.adv_param_label = QtWidgets.QLabel("<b>%s:</b>" % _("Advanced Param."))
         self.adv_param_label.setToolTip(
         self.adv_param_label.setToolTip(
             _("A list of Gerber advanced parameters.\n"
             _("A list of Gerber advanced parameters.\n"
               "Those parameters are available only for\n"
               "Those parameters are available only for\n"
@@ -4404,7 +4404,7 @@ class GerberExpPrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("Gerber Export")))
         self.setTitle(str(_("Gerber Export")))
 
 
         # Plot options
         # Plot options
-        self.export_options_label = QtWidgets.QLabel(_("<b>Export Options:</b>"))
+        self.export_options_label = QtWidgets.QLabel("<b>%s:</b>" % _("Export Options"))
         self.export_options_label.setToolTip(
         self.export_options_label.setToolTip(
             _("The parameters set here are used in the file exported\n"
             _("The parameters set here are used in the file exported\n"
               "when using the File -> Export -> Export Gerber menu entry.")
               "when using the File -> Export -> Export Gerber menu entry.")
@@ -4429,7 +4429,7 @@ class GerberExpPrefGroupUI(OptionsGroupUI):
         form.addRow(self.gerber_units_label, self.gerber_units_radio)
         form.addRow(self.gerber_units_label, self.gerber_units_radio)
 
 
         # Gerber format
         # Gerber format
-        self.digits_label = QtWidgets.QLabel(_("<b>Int/Decimals:</b>"))
+        self.digits_label = QtWidgets.QLabel("<b>%s:</b>" % _("Int/Decimals"))
         self.digits_label.setToolTip(
         self.digits_label.setToolTip(
             _("The number of digits in the whole part of the number\n"
             _("The number of digits in the whole part of the number\n"
               "and in the fractional part of the number.")
               "and in the fractional part of the number.")
@@ -4498,7 +4498,7 @@ class GerberEditorPrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("Gerber Editor")))
         self.setTitle(str(_("Gerber Editor")))
 
 
         # Advanced Gerber Parameters
         # Advanced Gerber Parameters
-        self.param_label = QtWidgets.QLabel(_("<b>Parameters:</b>"))
+        self.param_label = QtWidgets.QLabel("<b>%s:</b>" % _("Parameters"))
         self.param_label.setToolTip(
         self.param_label.setToolTip(
             _("A list of Gerber Editor parameters.")
             _("A list of Gerber Editor parameters.")
         )
         )
@@ -4533,7 +4533,7 @@ class ExcellonGenPrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("Excellon General")))
         self.setTitle(str(_("Excellon General")))
 
 
         # Plot options
         # Plot options
-        self.plot_options_label = QtWidgets.QLabel(_("<b>Plot Options:</b>"))
+        self.plot_options_label = QtWidgets.QLabel("<b>%s:</b>" % _("Plot Options"))
         self.layout.addWidget(self.plot_options_label)
         self.layout.addWidget(self.plot_options_label)
 
 
         grid1 = QtWidgets.QGridLayout()
         grid1 = QtWidgets.QGridLayout()
@@ -4552,7 +4552,7 @@ class ExcellonGenPrefGroupUI(OptionsGroupUI):
         grid1.addWidget(self.solid_cb, 0, 1)
         grid1.addWidget(self.solid_cb, 0, 1)
 
 
         # Excellon format
         # Excellon format
-        self.excellon_format_label = QtWidgets.QLabel(_("<b>Excellon Format:</b>"))
+        self.excellon_format_label = QtWidgets.QLabel("<b>%s:</b>" % _("Excellon Format"))
         self.excellon_format_label.setToolTip(
         self.excellon_format_label.setToolTip(
             _("The NC drill files, usually named Excellon files\n"
             _("The NC drill files, usually named Excellon files\n"
               "are files that can be found in different formats.\n"
               "are files that can be found in different formats.\n"
@@ -4692,7 +4692,7 @@ class ExcellonGenPrefGroupUI(OptionsGroupUI):
 
 
         grid2.addWidget(QtWidgets.QLabel(""), 2, 0)
         grid2.addWidget(QtWidgets.QLabel(""), 2, 0)
 
 
-        self.excellon_general_label = QtWidgets.QLabel(_("<b>Excellon Optimization:</b>"))
+        self.excellon_general_label = QtWidgets.QLabel("<b>%s:</b>" % _("Excellon Optimization"))
         grid2.addWidget(self.excellon_general_label, 3, 0, 1, 2)
         grid2.addWidget(self.excellon_general_label, 3, 0, 1, 2)
 
 
         self.excellon_optimization_label = QtWidgets.QLabel(_('Algorithm:   '))
         self.excellon_optimization_label = QtWidgets.QLabel(_('Algorithm:   '))
@@ -5056,7 +5056,7 @@ class ExcellonExpPrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("Excellon Export")))
         self.setTitle(str(_("Excellon Export")))
 
 
         # Plot options
         # Plot options
-        self.export_options_label = QtWidgets.QLabel(_("<b>Export Options:</b>"))
+        self.export_options_label = QtWidgets.QLabel("<b>%s:</b>" % _("Export Options"))
         self.export_options_label.setToolTip(
         self.export_options_label.setToolTip(
             _("The parameters set here are used in the file exported\n"
             _("The parameters set here are used in the file exported\n"
               "when using the File -> Export -> Export Excellon menu entry.")
               "when using the File -> Export -> Export Excellon menu entry.")
@@ -5081,7 +5081,7 @@ class ExcellonExpPrefGroupUI(OptionsGroupUI):
         form.addRow(self.excellon_units_label, self.excellon_units_radio)
         form.addRow(self.excellon_units_label, self.excellon_units_radio)
 
 
         # Excellon non-decimal format
         # Excellon non-decimal format
-        self.digits_label = QtWidgets.QLabel(_("<b>Int/Decimals:</b>"))
+        self.digits_label = QtWidgets.QLabel("<b>%s:</b>" % _("Int/Decimals"))
         self.digits_label.setToolTip(
         self.digits_label.setToolTip(
             _("The NC drill files, usually named Excellon files\n"
             _("The NC drill files, usually named Excellon files\n"
               "are files that can be found in different formats.\n"
               "are files that can be found in different formats.\n"
@@ -5119,7 +5119,7 @@ class ExcellonExpPrefGroupUI(OptionsGroupUI):
         form.addRow(self.digits_label, hlay1)
         form.addRow(self.digits_label, hlay1)
 
 
         # Select the Excellon Format
         # Select the Excellon Format
-        self.format_label = QtWidgets.QLabel(_("<b>Format:</b>"))
+        self.format_label = QtWidgets.QLabel("<b>%s:</b>" % _("Format"))
         self.format_label.setToolTip(
         self.format_label.setToolTip(
             _("Select the kind of coordinates format used.\n"
             _("Select the kind of coordinates format used.\n"
               "Coordinates can be saved with decimal point or without.\n"
               "Coordinates can be saved with decimal point or without.\n"
@@ -5206,7 +5206,7 @@ class ExcellonEditorPrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("Excellon Editor")))
         self.setTitle(str(_("Excellon Editor")))
 
 
         # Excellon Editor Parameters
         # Excellon Editor Parameters
-        self.param_label = QtWidgets.QLabel(_("<b>Parameters:</b>"))
+        self.param_label = QtWidgets.QLabel("<b>%s:</b>" % _("Parameters"))
         self.param_label.setToolTip(
         self.param_label.setToolTip(
             _("A list of Excellon Editor parameters.")
             _("A list of Excellon Editor parameters.")
         )
         )
@@ -5461,7 +5461,7 @@ class GeometryGenPrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("Geometry General")))
         self.setTitle(str(_("Geometry General")))
 
 
         # ## Plot options
         # ## Plot options
-        self.plot_options_label = QtWidgets.QLabel(_("<b>Plot Options:</b>"))
+        self.plot_options_label = QtWidgets.QLabel("<b>%s:</b>" % _("Plot Options"))
         self.layout.addWidget(self.plot_options_label)
         self.layout.addWidget(self.plot_options_label)
 
 
         # Plot CB
         # Plot CB
@@ -5485,7 +5485,7 @@ class GeometryGenPrefGroupUI(OptionsGroupUI):
         grid0.addWidget(self.circle_steps_entry, 1, 1)
         grid0.addWidget(self.circle_steps_entry, 1, 1)
 
 
         # Tools
         # Tools
-        self.tools_label = QtWidgets.QLabel(_("<b>Tools:</b>"))
+        self.tools_label = QtWidgets.QLabel("<b>%s:</b>" % _("Tools"))
         grid0.addWidget(self.tools_label, 2, 0, 1, 2)
         grid0.addWidget(self.tools_label, 2, 0, 1, 2)
 
 
         # Tooldia
         # Tooldia
@@ -5796,7 +5796,7 @@ class GeometryEditorPrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("Geometry Editor")))
         self.setTitle(str(_("Geometry Editor")))
 
 
         # Advanced Geometry Parameters
         # Advanced Geometry Parameters
-        self.param_label = QtWidgets.QLabel(_("<b>Parameters:</b>"))
+        self.param_label = QtWidgets.QLabel("<b>%s:</b>" % _("Parameters"))
         self.param_label.setToolTip(
         self.param_label.setToolTip(
             _("A list of Geometry Editor parameters.")
             _("A list of Geometry Editor parameters.")
         )
         )
@@ -5830,7 +5830,7 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("CNC Job General")))
         self.setTitle(str(_("CNC Job General")))
 
 
         # ## Plot options
         # ## Plot options
-        self.plot_options_label = QtWidgets.QLabel(_("<b>Plot Options:</b>"))
+        self.plot_options_label = QtWidgets.QLabel("<b>%s:</b>" % _("Plot Options"))
         self.layout.addWidget(self.plot_options_label)
         self.layout.addWidget(self.plot_options_label)
 
 
         grid0 = QtWidgets.QGridLayout()
         grid0 = QtWidgets.QGridLayout()
@@ -5963,7 +5963,7 @@ class CNCJobOptPrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("CNC Job Options")))
         self.setTitle(str(_("CNC Job Options")))
 
 
         # ## Export G-Code
         # ## Export G-Code
-        self.export_gcode_label = QtWidgets.QLabel(_("<b>Export G-Code:</b>"))
+        self.export_gcode_label = QtWidgets.QLabel("<b>%s:</b>" % _("Export G-Code"))
         self.export_gcode_label.setToolTip(
         self.export_gcode_label.setToolTip(
             _("Export and save G-Code to\n"
             _("Export and save G-Code to\n"
               "make this object to a file.")
               "make this object to a file.")
@@ -6004,7 +6004,7 @@ class CNCJobAdvOptPrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("CNC Job Adv. Options")))
         self.setTitle(str(_("CNC Job Adv. Options")))
 
 
         # ## Export G-Code
         # ## Export G-Code
-        self.export_gcode_label = QtWidgets.QLabel(_("<b>Export G-Code:</b>"))
+        self.export_gcode_label = QtWidgets.QLabel("<b>%s:</b>" % _("Export G-Code"))
         self.export_gcode_label.setToolTip(
         self.export_gcode_label.setToolTip(
             _("Export and save G-Code to\n"
             _("Export and save G-Code to\n"
               "make this object to a file.")
               "make this object to a file.")
@@ -6088,7 +6088,7 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("NCC Tool Options")))
         self.setTitle(str(_("NCC Tool Options")))
 
 
         # ## Clear non-copper regions
         # ## Clear non-copper regions
-        self.clearcopper_label = QtWidgets.QLabel(_("<b>Parameters:</b>"))
+        self.clearcopper_label = QtWidgets.QLabel("<b>%s:</b>" % _("Parameters"))
         self.clearcopper_label.setToolTip(
         self.clearcopper_label.setToolTip(
             _("Create a Geometry object with\n"
             _("Create a Geometry object with\n"
               "toolpaths to cut all non-copper regions.")
               "toolpaths to cut all non-copper regions.")
@@ -6253,7 +6253,7 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("Cutout Tool Options")))
         self.setTitle(str(_("Cutout Tool Options")))
 
 
         # ## Board cuttout
         # ## Board cuttout
-        self.board_cutout_label = QtWidgets.QLabel(_("<b>Parameters:</b>"))
+        self.board_cutout_label = QtWidgets.QLabel("<b>%s:</b>" % _("Parameters"))
         self.board_cutout_label.setToolTip(
         self.board_cutout_label.setToolTip(
             _("Create toolpaths to cut around\n"
             _("Create toolpaths to cut around\n"
               "the PCB and separate it from\n"
               "the PCB and separate it from\n"
@@ -6347,7 +6347,7 @@ class Tools2sidedPrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("2Sided Tool Options")))
         self.setTitle(str(_("2Sided Tool Options")))
 
 
         # ## Board cuttout
         # ## Board cuttout
-        self.dblsided_label = QtWidgets.QLabel(_("<b>Parameters:</b>"))
+        self.dblsided_label = QtWidgets.QLabel("<b>%s:</b>" % _("Parameters"))
         self.dblsided_label.setToolTip(
         self.dblsided_label.setToolTip(
             _("A tool to help in creating a double sided\n"
             _("A tool to help in creating a double sided\n"
               "PCB using alignment holes.")
               "PCB using alignment holes.")
@@ -6488,13 +6488,19 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI):
         # Polygon selection
         # Polygon selection
         selectlabel = QtWidgets.QLabel(_('Selection:'))
         selectlabel = QtWidgets.QLabel(_('Selection:'))
         selectlabel.setToolTip(
         selectlabel.setToolTip(
-            _("How to select the polygons to paint.")
+            _("How to select the polygons to paint.<BR>"
+              "Options:<BR>"
+              "- <B>Single</B>: left mouse click on the polygon to be painted.<BR>"
+              "- <B>Area</B>: left mouse click to start selection of the area to be painted.<BR>"
+              "- <B>All</B>: paint all polygons.<BR>"
+              "- <B>Ref</B>: paint an area described by an external reference object.")
         )
         )
         grid0.addWidget(selectlabel, 6, 0)
         grid0.addWidget(selectlabel, 6, 0)
         self.selectmethod_combo = RadioSet([
         self.selectmethod_combo = RadioSet([
             {"label": _("Single"), "value": "single"},
             {"label": _("Single"), "value": "single"},
             {"label": _("Area"), "value": "area"},
             {"label": _("Area"), "value": "area"},
-            {"label": _("All"), "value": "all"}
+            {"label": _("All"), "value": "all"},
+            {"label": _("Ref."), "value": "ref"}
         ])
         ])
         grid0.addWidget(self.selectmethod_combo, 6, 1)
         grid0.addWidget(self.selectmethod_combo, 6, 1)
 
 
@@ -6509,7 +6515,7 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("Film Tool Options")))
         self.setTitle(str(_("Film Tool Options")))
 
 
         # ## Board cuttout
         # ## Board cuttout
-        self.film_label = QtWidgets.QLabel(_("<b>Parameters:</b>"))
+        self.film_label = QtWidgets.QLabel("<b>%s:</b>" % _("Parameters"))
         self.film_label.setToolTip(
         self.film_label.setToolTip(
             _("Create a PCB film from a Gerber or Geometry\n"
             _("Create a PCB film from a Gerber or Geometry\n"
               "FlatCAM object.\n"
               "FlatCAM object.\n"
@@ -6570,7 +6576,7 @@ class ToolsPanelizePrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("Panelize Tool Options")))
         self.setTitle(str(_("Panelize Tool Options")))
 
 
         # ## Board cuttout
         # ## Board cuttout
-        self.panelize_label = QtWidgets.QLabel(_("<b>Parameters:</b>"))
+        self.panelize_label = QtWidgets.QLabel("<b>%s:</b>" % _("Parameters"))
         self.panelize_label.setToolTip(
         self.panelize_label.setToolTip(
             _("Create an object that contains an array of (x, y) elements,\n"
             _("Create an object that contains an array of (x, y) elements,\n"
               "each element is a copy of the source object spaced\n"
               "each element is a copy of the source object spaced\n"
@@ -6672,7 +6678,7 @@ class ToolsCalculatorsPrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("Calculators Tool Options")))
         self.setTitle(str(_("Calculators Tool Options")))
 
 
         # ## V-shape Calculator Tool
         # ## V-shape Calculator Tool
-        self.vshape_tool_label = QtWidgets.QLabel(_("<b>V-Shape Tool Calculator:</b>"))
+        self.vshape_tool_label = QtWidgets.QLabel("<b>%s:</b>" % _("V-Shape Tool Calculator"))
         self.vshape_tool_label.setToolTip(
         self.vshape_tool_label.setToolTip(
             _("Calculate the tool diameter for a given V-shape tool,\n"
             _("Calculate the tool diameter for a given V-shape tool,\n"
               "having the tip diameter, tip angle and\n"
               "having the tip diameter, tip angle and\n"
@@ -6714,7 +6720,7 @@ class ToolsCalculatorsPrefGroupUI(OptionsGroupUI):
         grid0.addWidget(self.cut_z_entry, 2, 1)
         grid0.addWidget(self.cut_z_entry, 2, 1)
 
 
         # ## Electroplating Calculator Tool
         # ## Electroplating Calculator Tool
-        self.plate_title_label = QtWidgets.QLabel(_("<b>ElectroPlating Calculator:</b>"))
+        self.plate_title_label = QtWidgets.QLabel("<b>%s:</b>" % _("ElectroPlating Calculator"))
         self.plate_title_label.setToolTip(
         self.plate_title_label.setToolTip(
             _("This calculator is useful for those who plate the via/pad/drill holes,\n"
             _("This calculator is useful for those who plate the via/pad/drill holes,\n"
               "using a method like grahite ink or calcium hypophosphite ink or palladium chloride.")
               "using a method like grahite ink or calcium hypophosphite ink or palladium chloride.")
@@ -6769,7 +6775,7 @@ class ToolsTransformPrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("Transform Tool Options")))
         self.setTitle(str(_("Transform Tool Options")))
 
 
         # ## Transformations
         # ## Transformations
-        self.transform_label = QtWidgets.QLabel(_("<b>Parameters:</b>"))
+        self.transform_label = QtWidgets.QLabel("<b>%s:</b>" % _("Parameters"))
         self.transform_label.setToolTip(
         self.transform_label.setToolTip(
             _("Various transformations that can be applied\n"
             _("Various transformations that can be applied\n"
               "on a FlatCAM object.")
               "on a FlatCAM object.")
@@ -6896,7 +6902,7 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("SolderPaste Tool Options")))
         self.setTitle(str(_("SolderPaste Tool Options")))
 
 
         # ## Solder Paste Dispensing
         # ## Solder Paste Dispensing
-        self.solderpastelabel = QtWidgets.QLabel(_("<b>Parameters:</b>"))
+        self.solderpastelabel = QtWidgets.QLabel("<b>%s:</b>" % _("Parameters"))
         self.solderpastelabel.setToolTip(
         self.solderpastelabel.setToolTip(
             _("A tool to create GCode for dispensing\n"
             _("A tool to create GCode for dispensing\n"
               "solder paste onto a PCB.")
               "solder paste onto a PCB.")
@@ -7069,7 +7075,7 @@ class ToolsSubPrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("Substractor Tool Options")))
         self.setTitle(str(_("Substractor Tool Options")))
 
 
         # ## Solder Paste Dispensing
         # ## Solder Paste Dispensing
-        self.sublabel = QtWidgets.QLabel(_("<b>Parameters:</b>"))
+        self.sublabel = QtWidgets.QLabel("<b>%s:</b>" % _("Parameters"))
         self.sublabel.setToolTip(
         self.sublabel.setToolTip(
             _("A tool to substract one Gerber or Geometry object\n"
             _("A tool to substract one Gerber or Geometry object\n"
               "from another of the same type.")
               "from another of the same type.")

+ 21 - 22
flatcamGUI/ObjectUI.py

@@ -147,7 +147,7 @@ class GerberObjectUI(ObjectUI):
         grid0.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
         grid0.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
         self.custom_box.addLayout(grid0)
         self.custom_box.addLayout(grid0)
 
 
-        self.plot_options_label = QtWidgets.QLabel(_("<b>Plot Options:</b>"))
+        self.plot_options_label = QtWidgets.QLabel("<b>%s:</b>" % _("Plot Options"))
         self.plot_options_label.setMinimumWidth(90)
         self.plot_options_label.setMinimumWidth(90)
 
 
         grid0.addWidget(self.plot_options_label, 0, 0)
         grid0.addWidget(self.plot_options_label, 0, 0)
@@ -179,7 +179,7 @@ class GerberObjectUI(ObjectUI):
         # ## Object name
         # ## Object name
         self.name_hlay = QtWidgets.QHBoxLayout()
         self.name_hlay = QtWidgets.QHBoxLayout()
         self.custom_box.addLayout(self.name_hlay)
         self.custom_box.addLayout(self.name_hlay)
-        name_label = QtWidgets.QLabel(_("<b>Name:</b>"))
+        name_label = QtWidgets.QLabel("<b>%s:</b>" % _("Name"))
         self.name_entry = FCEntry()
         self.name_entry = FCEntry()
         self.name_entry.setFocusPolicy(QtCore.Qt.StrongFocus)
         self.name_entry.setFocusPolicy(QtCore.Qt.StrongFocus)
         self.name_hlay.addWidget(name_label)
         self.name_hlay.addWidget(name_label)
@@ -247,7 +247,7 @@ class GerberObjectUI(ObjectUI):
         self.apertures_table.setVisible(False)
         self.apertures_table.setVisible(False)
 
 
         # Isolation Routing
         # Isolation Routing
-        self.isolation_routing_label = QtWidgets.QLabel(_("<b>Isolation Routing:</b>"))
+        self.isolation_routing_label = QtWidgets.QLabel("<b>%s:</b>" % _("Isolation Routing"))
         self.isolation_routing_label.setToolTip(
         self.isolation_routing_label.setToolTip(
             _("Create a Geometry object with\n"
             _("Create a Geometry object with\n"
               "toolpaths to cut outside polygons.")
               "toolpaths to cut outside polygons.")
@@ -320,7 +320,7 @@ class GerberObjectUI(ObjectUI):
         )
         )
         grid1.addWidget(self.follow_cb, 4, 1)
         grid1.addWidget(self.follow_cb, 4, 1)
 
 
-        self.gen_iso_label = QtWidgets.QLabel(_("<b>Generate Isolation Geometry:</b>"))
+        self.gen_iso_label = QtWidgets.QLabel("<b>%s:</b>" % _("Generate Isolation Geometry"))
         self.gen_iso_label.setToolTip(
         self.gen_iso_label.setToolTip(
             _("Create a Geometry object with toolpaths to cut \n"
             _("Create a Geometry object with toolpaths to cut \n"
               "isolation outside, inside or on both sides of the\n"
               "isolation outside, inside or on both sides of the\n"
@@ -379,7 +379,7 @@ class GerberObjectUI(ObjectUI):
         self.custom_box.addLayout(grid2)
         self.custom_box.addLayout(grid2)
 
 
         # ## Clear non-copper regions
         # ## Clear non-copper regions
-        self.clearcopper_label = QtWidgets.QLabel(_("<b>Clear N-copper:</b>"))
+        self.clearcopper_label = QtWidgets.QLabel("<b>%s:</b>" % _("Clear N-copper"))
         self.clearcopper_label.setToolTip(
         self.clearcopper_label.setToolTip(
             _("Create a Geometry object with\n"
             _("Create a Geometry object with\n"
               "toolpaths to cut all non-copper regions.")
               "toolpaths to cut all non-copper regions.")
@@ -395,7 +395,7 @@ class GerberObjectUI(ObjectUI):
         grid2.addWidget(self.generate_ncc_button, 0, 1)
         grid2.addWidget(self.generate_ncc_button, 0, 1)
 
 
         # ## Board cutout
         # ## Board cutout
-        self.board_cutout_label = QtWidgets.QLabel(_("<b>Board cutout:</b>"))
+        self.board_cutout_label = QtWidgets.QLabel("<b>%s:</b>" % _("Board cutout"))
         self.board_cutout_label.setToolTip(
         self.board_cutout_label.setToolTip(
             _("Create toolpaths to cut around\n"
             _("Create toolpaths to cut around\n"
               "the PCB and separate it from\n"
               "the PCB and separate it from\n"
@@ -411,7 +411,7 @@ class GerberObjectUI(ObjectUI):
         grid2.addWidget(self.generate_cutout_button, 1, 1)
         grid2.addWidget(self.generate_cutout_button, 1, 1)
 
 
         # ## Non-copper regions
         # ## Non-copper regions
-        self.noncopper_label = QtWidgets.QLabel(_("<b>Non-copper regions:</b>"))
+        self.noncopper_label = QtWidgets.QLabel("<b>%s:</b>" % _("Non-copper regions"))
         self.noncopper_label.setToolTip(
         self.noncopper_label.setToolTip(
             _("Create polygons covering the\n"
             _("Create polygons covering the\n"
               "areas without copper on the PCB.\n"
               "areas without copper on the PCB.\n"
@@ -500,7 +500,7 @@ class ExcellonObjectUI(ObjectUI):
         hlay_plot = QtWidgets.QHBoxLayout()
         hlay_plot = QtWidgets.QHBoxLayout()
         self.custom_box.addLayout(hlay_plot)
         self.custom_box.addLayout(hlay_plot)
 
 
-        self.plot_options_label = QtWidgets.QLabel(_("<b>Plot Options:</b>"))
+        self.plot_options_label = QtWidgets.QLabel("<b>%s:</b>" % _("Plot Options"))
         self.solid_cb = FCCheckBox(label=_('Solid'))
         self.solid_cb = FCCheckBox(label=_('Solid'))
         self.solid_cb.setToolTip(
         self.solid_cb.setToolTip(
             _("Solid circles.")
             _("Solid circles.")
@@ -512,7 +512,7 @@ class ExcellonObjectUI(ObjectUI):
         # ## Object name
         # ## Object name
         self.name_hlay = QtWidgets.QHBoxLayout()
         self.name_hlay = QtWidgets.QHBoxLayout()
         self.custom_box.addLayout(self.name_hlay)
         self.custom_box.addLayout(self.name_hlay)
-        name_label = QtWidgets.QLabel(_("<b>Name:</b>"))
+        name_label = QtWidgets.QLabel("<b>%s:</b>" % _("Name"))
         self.name_entry = FCEntry()
         self.name_entry = FCEntry()
         self.name_entry.setFocusPolicy(QtCore.Qt.StrongFocus)
         self.name_entry.setFocusPolicy(QtCore.Qt.StrongFocus)
         self.name_hlay.addWidget(name_label)
         self.name_hlay.addWidget(name_label)
@@ -828,13 +828,13 @@ class GeometryObjectUI(ObjectUI):
                                                icon_file='share/geometry32.png', parent=parent)
                                                icon_file='share/geometry32.png', parent=parent)
 
 
         # Plot options
         # Plot options
-        self.plot_options_label = QtWidgets.QLabel(_("<b>Plot Options:</b>"))
+        self.plot_options_label = QtWidgets.QLabel("<b>%s:</b>" % _("Plot Options"))
         self.custom_box.addWidget(self.plot_options_label)
         self.custom_box.addWidget(self.plot_options_label)
 
 
         # ## Object name
         # ## Object name
         self.name_hlay = QtWidgets.QHBoxLayout()
         self.name_hlay = QtWidgets.QHBoxLayout()
         self.custom_box.addLayout(self.name_hlay)
         self.custom_box.addLayout(self.name_hlay)
-        name_label = QtWidgets.QLabel(_("<b>Name:</b>"))
+        name_label = QtWidgets.QLabel("<b>%s:</b>" % _("Name"))
         self.name_entry = FCEntry()
         self.name_entry = FCEntry()
         self.name_entry.setFocusPolicy(QtCore.Qt.StrongFocus)
         self.name_entry.setFocusPolicy(QtCore.Qt.StrongFocus)
         self.name_hlay.addWidget(name_label)
         self.name_hlay.addWidget(name_label)
@@ -1353,10 +1353,10 @@ class CNCObjectUI(ObjectUI):
         self.offset_button.hide()
         self.offset_button.hide()
 
 
         # ## Plot options
         # ## Plot options
-        self.plot_options_label = QtWidgets.QLabel(_("<b>Plot Options:</b>"))
+        self.plot_options_label = QtWidgets.QLabel("<b>%s:</b>" % _("Plot Options"))
         self.custom_box.addWidget(self.plot_options_label)
         self.custom_box.addWidget(self.plot_options_label)
 
 
-        self.cncplot_method_label = QtWidgets.QLabel(_("<b>Plot kind:</b>"))
+        self.cncplot_method_label = QtWidgets.QLabel("<b>%s:</b>" % _("Plot kind"))
         self.cncplot_method_label.setToolTip(
         self.cncplot_method_label.setToolTip(
             _(
             _(
                 "This selects the kind of geometries on the canvas to plot.\n"
                 "This selects the kind of geometries on the canvas to plot.\n"
@@ -1372,12 +1372,11 @@ class CNCObjectUI(ObjectUI):
             {"label": _("Cut"), "value": "cut"}
             {"label": _("Cut"), "value": "cut"}
         ], stretch=False)
         ], stretch=False)
 
 
-        self.annotation_label = QtWidgets.QLabel(_("<b>Display Annotation:</b>"))
+        self.annotation_label = QtWidgets.QLabel("<b>%s:</b>" % _("Display Annotation"))
         self.annotation_label.setToolTip(
         self.annotation_label.setToolTip(
-            _(
-                "This selects if to display text annotation on the plot.\n"
-                "When checked it will display numbers in order for each end\n"
-                "of a travel line."
+            _("This selects if to display text annotation on the plot.\n"
+              "When checked it will display numbers in order for each end\n"
+              "of a travel line."
             )
             )
         )
         )
         self.annotation_cb = FCCheckBox()
         self.annotation_cb = FCCheckBox()
@@ -1385,13 +1384,13 @@ class CNCObjectUI(ObjectUI):
         # ## Object name
         # ## Object name
         self.name_hlay = QtWidgets.QHBoxLayout()
         self.name_hlay = QtWidgets.QHBoxLayout()
         self.custom_box.addLayout(self.name_hlay)
         self.custom_box.addLayout(self.name_hlay)
-        name_label = QtWidgets.QLabel(_("<b>Name:</b>"))
+        name_label = QtWidgets.QLabel("<b>%s:</b>" % _("Name"))
         self.name_entry = FCEntry()
         self.name_entry = FCEntry()
         self.name_entry.setFocusPolicy(QtCore.Qt.StrongFocus)
         self.name_entry.setFocusPolicy(QtCore.Qt.StrongFocus)
         self.name_hlay.addWidget(name_label)
         self.name_hlay.addWidget(name_label)
         self.name_hlay.addWidget(self.name_entry)
         self.name_hlay.addWidget(self.name_entry)
 
 
-        self.t_distance_label = QtWidgets.QLabel(_("<b>Travelled dist.:</b>"))
+        self.t_distance_label = QtWidgets.QLabel("<b>%s:</b>" % _("Travelled dist."))
         self.t_distance_label.setToolTip(
         self.t_distance_label.setToolTip(
             _("This is the total travelled distance on X-Y plane.\n"
             _("This is the total travelled distance on X-Y plane.\n"
               "In current units.")
               "In current units.")
@@ -1403,7 +1402,7 @@ class CNCObjectUI(ObjectUI):
         )
         )
         self.units_label = QtWidgets.QLabel()
         self.units_label = QtWidgets.QLabel()
 
 
-        self.t_time_label = QtWidgets.QLabel(_("<b>Estimated time:</b>"))
+        self.t_time_label = QtWidgets.QLabel("<b>%s:</b>" % _("Estimated time"))
         self.t_time_label.setToolTip(
         self.t_time_label.setToolTip(
             _("This is the estimated time to do the routing/drilling,\n"
             _("This is the estimated time to do the routing/drilling,\n"
               "without the time spent in ToolChange events.")
               "without the time spent in ToolChange events.")
@@ -1497,7 +1496,7 @@ class CNCObjectUI(ObjectUI):
         # ####################
         # ####################
         # ## Export G-Code ##
         # ## Export G-Code ##
         # ####################
         # ####################
-        self.export_gcode_label = QtWidgets.QLabel(_("<b>Export CNC Code:</b>"))
+        self.export_gcode_label = QtWidgets.QLabel("<b>%s:</b>" % _("Export CNC Code"))
         self.export_gcode_label.setToolTip(
         self.export_gcode_label.setToolTip(
             _("Export and save G-Code to\n"
             _("Export and save G-Code to\n"
             "make this object to a file.")
             "make this object to a file.")

+ 3 - 3
flatcamTools/ToolDblSided.py

@@ -44,7 +44,7 @@ class DblSidedTool(FlatCAMTool):
         self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
         self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
         self.gerber_object_combo.setCurrentIndex(1)
         self.gerber_object_combo.setCurrentIndex(1)
 
 
-        self.botlay_label = QtWidgets.QLabel(_("<b>GERBER:</b>"))
+        self.botlay_label = QtWidgets.QLabel("<b>%s:</b>" % _("GERBER"))
         self.botlay_label.setToolTip(
         self.botlay_label.setToolTip(
             "Gerber  to be mirrored."
             "Gerber  to be mirrored."
         )
         )
@@ -68,7 +68,7 @@ class DblSidedTool(FlatCAMTool):
         self.exc_object_combo.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex()))
         self.exc_object_combo.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex()))
         self.exc_object_combo.setCurrentIndex(1)
         self.exc_object_combo.setCurrentIndex(1)
 
 
-        self.excobj_label = QtWidgets.QLabel(_("<b>EXCELLON:</b>"))
+        self.excobj_label = QtWidgets.QLabel("<b>%s:</b>" % _("EXCELLON"))
         self.excobj_label.setToolTip(
         self.excobj_label.setToolTip(
             _("Excellon Object to be mirrored.")
             _("Excellon Object to be mirrored.")
         )
         )
@@ -92,7 +92,7 @@ class DblSidedTool(FlatCAMTool):
         self.geo_object_combo.setRootModelIndex(self.app.collection.index(2, 0, QtCore.QModelIndex()))
         self.geo_object_combo.setRootModelIndex(self.app.collection.index(2, 0, QtCore.QModelIndex()))
         self.geo_object_combo.setCurrentIndex(1)
         self.geo_object_combo.setCurrentIndex(1)
 
 
-        self.geoobj_label = QtWidgets.QLabel(_("<b>GEOMETRY</b>:"))
+        self.geoobj_label = QtWidgets.QLabel("<b>%s</b>:" % _("GEOMETRY"))
         self.geoobj_label.setToolTip(
         self.geoobj_label.setToolTip(
             _("Geometry Obj to be mirrored.")
             _("Geometry Obj to be mirrored.")
         )
         )

+ 8 - 4
flatcamTools/ToolNonCopperClear.py

@@ -10,10 +10,10 @@ from FlatCAMTool import FlatCAMTool
 from copy import copy, deepcopy
 from copy import copy, deepcopy
 from ObjectCollection import *
 from ObjectCollection import *
 import time
 import time
+from shapely.geometry import base
 
 
 import gettext
 import gettext
 import FlatCAMTranslation as fcTranslate
 import FlatCAMTranslation as fcTranslate
-from shapely.geometry import base
 import builtins
 import builtins
 
 
 fcTranslate.apply_language('strings')
 fcTranslate.apply_language('strings')
@@ -860,12 +860,16 @@ class NonCopperClear(FlatCAMTool, Gerber):
             return "Could not retrieve object: %s" % self.obj_name
             return "Could not retrieve object: %s" % self.obj_name
 
 
         # Prepare non-copper polygons
         # Prepare non-copper polygons
+        geo_n = self.bound_obj.solid_geometry
         try:
         try:
-            if not isinstance(self.bound_obj.solid_geometry, MultiPolygon):
+            if isinstance(geo_n, MultiPolygon):
+                env_obj = geo_n.convex_hull
+            elif (isinstance(geo_n, MultiPolygon) and len(geo_n) == 1) or \
+                    (isinstance(geo_n, list) and len(geo_n) == 1) and isinstance(geo_n[0], Polygon):
                 env_obj = cascaded_union(self.bound_obj.solid_geometry)
                 env_obj = cascaded_union(self.bound_obj.solid_geometry)
-                env_obj = env_obj.convex_hull
             else:
             else:
-                env_obj = self.bound_obj.solid_geometry.convex_hull
+                env_obj = cascaded_union(self.bound_obj.solid_geometry)
+                env_obj = env_obj.convex_hull
             bounding_box = env_obj.buffer(distance=margin, join_style=base.JOIN_STYLE.mitre)
             bounding_box = env_obj.buffer(distance=margin, join_style=base.JOIN_STYLE.mitre)
         except Exception as e:
         except Exception as e:
             log.debug("NonCopperClear.on_ncc() --> %s" % str(e))
             log.debug("NonCopperClear.on_ncc() --> %s" % str(e))

+ 50 - 9
flatcamTools/ToolPaint.py

@@ -9,6 +9,7 @@
 from FlatCAMTool import FlatCAMTool
 from FlatCAMTool import FlatCAMTool
 from copy import copy, deepcopy
 from copy import copy, deepcopy
 from ObjectCollection import *
 from ObjectCollection import *
+from shapely.geometry import base
 
 
 import gettext
 import gettext
 import FlatCAMTranslation as fcTranslate
 import FlatCAMTranslation as fcTranslate
@@ -238,19 +239,27 @@ class ToolPaint(FlatCAMTool, Gerber):
         selectlabel.setToolTip(
         selectlabel.setToolTip(
             _("How to select the polygons to paint.<BR>"
             _("How to select the polygons to paint.<BR>"
               "Options:<BR>"
               "Options:<BR>"
-              "- <B>Single</B>: left mouse click on the polygon to be painted.<BR>"
-              "- <B>Area</B>: left mouse click to start selection of the area to be painted.<BR>"
-              "- <B>All</B>: paint all polygons.<BR>"
-              "- <B>Ref</B>: paint an area described by an external reference object.")
+              "- <B>Single Polygons</B>: left mouse click on the polygon to be painted.<BR>"
+              "- <B>Area Selection</B>: left mouse click to start selection of the area to be painted.<BR>"
+              "- <B>All Polygons</B>: paint all polygons.<BR>"
+              "- <B>Reference Object</B>: paint an area described by an external reference object.")
         )
         )
         grid3.addWidget(selectlabel, 7, 0)
         grid3.addWidget(selectlabel, 7, 0)
         # grid3 = QtWidgets.QGridLayout()
         # grid3 = QtWidgets.QGridLayout()
         self.selectmethod_combo = RadioSet([
         self.selectmethod_combo = RadioSet([
-            {"label": _("Single"), "value": "single"},
-            {"label": _("Area"), "value": "area"},
-            {"label": _("All"), "value": "all"},
-            {"label": _("Ref."), "value": "ref"}
-        ])
+            {"label": _("Single Polygon"), "value": "single"},
+            {"label": _("Area Selection"), "value": "area"},
+            {"label": _("All Polygons"), "value": "all"},
+            {"label": _("Reference Object"), "value": "ref"}
+        ], orientation='vertical', stretch=False)
+        self.selectmethod_combo.setToolTip(
+            _("How to select the polygons to paint.<BR>"
+              "Options:<BR>"
+              "- <B>Single Polygons</B>: left mouse click on the polygon to be painted.<BR>"
+              "- <B>Area Selection</B>: left mouse click to start selection of the area to be painted.<BR>"
+              "- <B>All Polygons</B>: paint all polygons.<BR>"
+              "- <B>Reference Object</B>: paint an area described by an external reference object.")
+        )
         grid3.addWidget(self.selectmethod_combo, 7, 1)
         grid3.addWidget(self.selectmethod_combo, 7, 1)
 
 
         grid4 = QtWidgets.QGridLayout()
         grid4 = QtWidgets.QGridLayout()
@@ -950,6 +959,38 @@ class ToolPaint(FlatCAMTool, Gerber):
             self.app.plotcanvas.vis_connect('mouse_press', on_mouse_press)
             self.app.plotcanvas.vis_connect('mouse_press', on_mouse_press)
             self.app.plotcanvas.vis_connect('mouse_move', on_mouse_move)
             self.app.plotcanvas.vis_connect('mouse_move', on_mouse_move)
 
 
+        elif select_method == 'ref':
+            self.bound_obj_name = self.box_combo.currentText()
+            # Get source object.
+            try:
+                self.bound_obj = self.app.collection.get_by_name(self.bound_obj_name)
+            except Exception as e:
+                self.app.inform.emit(_("[ERROR_NOTCL] Could not retrieve object: %s") % self.obj_name)
+                return "Could not retrieve object: %s" % self.obj_name
+
+            geo = self.bound_obj.solid_geometry
+            try:
+                if isinstance(geo, MultiPolygon):
+                    env_obj = geo.convex_hull
+                elif (isinstance(geo, MultiPolygon) and len(geo) == 1) or \
+                    (isinstance(geo, list) and len(geo) == 1) and isinstance(geo[0], Polygon):
+                    env_obj = cascaded_union(self.bound_obj.solid_geometry)
+                else:
+                    env_obj = cascaded_union(self.bound_obj.solid_geometry)
+                    env_obj = env_obj.convex_hull
+                sel_rect = env_obj.buffer(distance=0.0000001, join_style=base.JOIN_STYLE.mitre)
+            except Exception as e:
+                log.debug("ToolPaint.on_paint_button_click() --> %s" % str(e))
+                self.app.inform.emit(_("[ERROR_NOTCL] No object available."))
+                return
+
+            self.paint_poly_area(obj=self.paint_obj,
+                                 sel_obj=sel_rect,
+                                 outname=o_name,
+                                 overlap=overlap,
+                                 connect=connect,
+                                 contour=contour)
+
     def paint_poly(self, obj, inside_pt, tooldia, overlap, outname=None, connect=True, contour=True):
     def paint_poly(self, obj, inside_pt, tooldia, overlap, outname=None, connect=True, contour=True):
         """
         """
         Paints a polygon selected by clicking on its interior.
         Paints a polygon selected by clicking on its interior.

+ 3 - 3
flatcamTools/ToolPanelize.py

@@ -83,7 +83,7 @@ class Panelize(FlatCAMTool):
         # Type of box Panel object
         # Type of box Panel object
         self.reference_radio = RadioSet([{'label': _('Object'), 'value': 'object'},
         self.reference_radio = RadioSet([{'label': _('Object'), 'value': 'object'},
                                          {'label': _('Bounding Box'), 'value': 'bbox'}])
                                          {'label': _('Bounding Box'), 'value': 'bbox'}])
-        self.box_label = QtWidgets.QLabel(_("<b>Penelization Reference:</b>"))
+        self.box_label = QtWidgets.QLabel("<b>%s:</b>" % _("Penelization Reference"))
         self.box_label.setToolTip(
         self.box_label.setToolTip(
             _("Choose the reference for panelization:\n"
             _("Choose the reference for panelization:\n"
               "- Object = the bounding box of a different object\n"
               "- Object = the bounding box of a different object\n"
@@ -131,7 +131,7 @@ class Panelize(FlatCAMTool):
         form_layout.addRow(self.box_combo_label, self.box_combo)
         form_layout.addRow(self.box_combo_label, self.box_combo)
         form_layout.addRow(QtWidgets.QLabel(""))
         form_layout.addRow(QtWidgets.QLabel(""))
 
 
-        panel_data_label = QtWidgets.QLabel(_("<b>Panel Data:</b>"))
+        panel_data_label = QtWidgets.QLabel("<b>%s:</b>" % _("Panel Data"))
         panel_data_label.setToolTip(
         panel_data_label.setToolTip(
             _("This informations will shape the resulting panel.\n"
             _("This informations will shape the resulting panel.\n"
               "The number of rows and columns will set how many\n"
               "The number of rows and columns will set how many\n"
@@ -180,7 +180,7 @@ class Panelize(FlatCAMTool):
         # Type of resulting Panel object
         # Type of resulting Panel object
         self.panel_type_radio = RadioSet([{'label': _('Gerber'), 'value': 'gerber'},
         self.panel_type_radio = RadioSet([{'label': _('Gerber'), 'value': 'gerber'},
                                           {'label': _('Geo'), 'value': 'geometry'}])
                                           {'label': _('Geo'), 'value': 'geometry'}])
-        self.panel_type_label = QtWidgets.QLabel(_("<b>Panel Type:</b>"))
+        self.panel_type_label = QtWidgets.QLabel("<b>%s:</b>" % _("Panel Type"))
         self.panel_type_label.setToolTip(
         self.panel_type_label.setToolTip(
             _("Choose the type of object for the panel object:\n"
             _("Choose the type of object for the panel object:\n"
               "- Geometry\n"
               "- Geometry\n"

+ 2 - 2
flatcamTools/ToolPcbWizard.py

@@ -48,7 +48,7 @@ class PcbWizard(FlatCAMTool):
         self.layout.addWidget(title_label)
         self.layout.addWidget(title_label)
 
 
         self.layout.addWidget(QtWidgets.QLabel(""))
         self.layout.addWidget(QtWidgets.QLabel(""))
-        self.layout.addWidget(QtWidgets.QLabel(_("<b>Load files:</b>")))
+        self.layout.addWidget(QtWidgets.QLabel("<b>%s:</b>" % _("Load files")))
 
 
         # Form Layout
         # Form Layout
         form_layout = QtWidgets.QFormLayout()
         form_layout = QtWidgets.QFormLayout()
@@ -84,7 +84,7 @@ class PcbWizard(FlatCAMTool):
         self.tools_table.setVisible(False)
         self.tools_table.setVisible(False)
 
 
         self.layout.addWidget(QtWidgets.QLabel(""))
         self.layout.addWidget(QtWidgets.QLabel(""))
-        self.layout.addWidget(QtWidgets.QLabel(_("<b>Excellon format:</b>")))
+        self.layout.addWidget(QtWidgets.QLabel("<b>%s:</b>" % _("Excellon format")))
         # Form Layout
         # Form Layout
         form_layout1 = QtWidgets.QFormLayout()
         form_layout1 = QtWidgets.QFormLayout()
         self.layout.addLayout(form_layout1)
         self.layout.addLayout(form_layout1)

+ 2 - 2
flatcamTools/ToolSub.py

@@ -52,7 +52,7 @@ class ToolSub(FlatCAMTool):
         form_layout = QtWidgets.QFormLayout()
         form_layout = QtWidgets.QFormLayout()
         self.tools_box.addLayout(form_layout)
         self.tools_box.addLayout(form_layout)
 
 
-        self.gerber_title = QtWidgets.QLabel(_("<b>Gerber Objects</b>"))
+        self.gerber_title = QtWidgets.QLabel("<b>%s</b>" % _("Gerber Objects"))
         form_layout.addRow(self.gerber_title)
         form_layout.addRow(self.gerber_title)
 
 
         # Target Gerber Object
         # Target Gerber Object
@@ -98,7 +98,7 @@ class ToolSub(FlatCAMTool):
         form_geo_layout = QtWidgets.QFormLayout()
         form_geo_layout = QtWidgets.QFormLayout()
         self.tools_box.addLayout(form_geo_layout)
         self.tools_box.addLayout(form_geo_layout)
 
 
-        self.geo_title = QtWidgets.QLabel(_("<b>Geometry Objects</b>"))
+        self.geo_title = QtWidgets.QLabel("<b>%s</b>" % _("Geometry Objects"))
         form_geo_layout.addRow(self.geo_title)
         form_geo_layout.addRow(self.geo_title)
 
 
         # Target Geometry Object
         # Target Geometry Object