From 9505ecf80f37cde69f8be8424c9fc45534c072c7 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 9 Jan 2020 15:56:41 +0200 Subject: [PATCH 001/209] - working on new NCC tool --- flatcamTools/ToolNonCopperClear.py | 186 +++++++++++------------------ 1 file changed, 72 insertions(+), 114 deletions(-) diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNonCopperClear.py index 9a6e047e..c97f0ac3 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/flatcamTools/ToolNonCopperClear.py @@ -311,30 +311,35 @@ class NonCopperClear(FlatCAMTool, Gerber): "with the diameter specified above.") ) + self.addtool_from_db_btn = QtWidgets.QPushButton(_('Add from DB')) + self.addtool_from_db_btn.setToolTip( + _("Add a new tool to the Tool Table\n" + "from the Tool DataBase.") + ) + + hlay.addWidget(self.addtool_btn) + hlay.addWidget(self.addtool_from_db_btn) + + self.grid3.addLayout(hlay, 7, 0, 1, 2) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + self.grid3.addWidget(separator_line, 8, 0, 1, 2) + self.deltool_btn = QtWidgets.QPushButton(_('Delete')) self.deltool_btn.setToolTip( _("Delete a selection of tools in the Tool Table\n" "by first selecting a row(s) in the Tool Table.") ) + self.grid3.addWidget(self.deltool_btn, 9, 0, 1, 2) - hlay.addWidget(self.addtool_btn) - hlay.addWidget(self.deltool_btn) - - self.grid3.addLayout(hlay, 7, 0, 1, 2) - - self.addtool_from_db_btn = QtWidgets.QPushButton(_('Add Tool from DataBase')) - self.addtool_from_db_btn.setToolTip( - _("Add a new tool to the Tool Table\n" - "from the Tool DataBase.") - ) - self.grid3.addWidget(self.addtool_from_db_btn, 8, 0, 1, 2) - - self.grid3.addWidget(QtWidgets.QLabel(''), 9, 0, 1, 2) + self.grid3.addWidget(QtWidgets.QLabel(''), 10, 0, 1, 2) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - self.grid3.addWidget(separator_line, 10, 0, 1, 2) + self.grid3.addWidget(separator_line, 11, 0, 1, 2) self.tool_data_label = QtWidgets.QLabel( "%s: %s %d" % (_('Parameters for'), _("Tool"), int(1))) @@ -344,7 +349,7 @@ class NonCopperClear(FlatCAMTool, Gerber): "Each tool store it's own set of such data." ) ) - self.grid3.addWidget(self.tool_data_label, 11, 0, 1, 2) + self.grid3.addWidget(self.tool_data_label, 12, 0, 1, 2) # Overlap Entry nccoverlabel = QtWidgets.QLabel('%s:' % _('Overlap Rate')) @@ -364,8 +369,8 @@ class NonCopperClear(FlatCAMTool, Gerber): self.ncc_overlap_entry.setSingleStep(0.1) self.ncc_overlap_entry.setObjectName(_("Overlap Rate")) - self.grid3.addWidget(nccoverlabel, 12, 0) - self.grid3.addWidget(self.ncc_overlap_entry, 12, 1) + self.grid3.addWidget(nccoverlabel, 13, 0) + self.grid3.addWidget(self.ncc_overlap_entry, 13, 1) # Margin nccmarginlabel = QtWidgets.QLabel('%s:' % _('Margin')) @@ -377,8 +382,8 @@ class NonCopperClear(FlatCAMTool, Gerber): self.ncc_margin_entry.set_range(-9999.9999, 9999.9999) self.ncc_margin_entry.setObjectName(_("Margin")) - self.grid3.addWidget(nccmarginlabel, 13, 0) - self.grid3.addWidget(self.ncc_margin_entry, 13, 1) + self.grid3.addWidget(nccmarginlabel, 14, 0) + self.grid3.addWidget(self.ncc_margin_entry, 14, 1) # Method methodlabel = QtWidgets.QLabel('%s:' % _('Method')) @@ -395,8 +400,8 @@ class NonCopperClear(FlatCAMTool, Gerber): ], orientation='vertical', stretch=False) self.ncc_method_radio.setObjectName(_("Method")) - self.grid3.addWidget(methodlabel, 14, 0) - self.grid3.addWidget(self.ncc_method_radio, 14, 1) + self.grid3.addWidget(methodlabel, 15, 0) + self.grid3.addWidget(self.ncc_method_radio, 15, 1) # Connect lines self.ncc_connect_cb = FCCheckBox('%s' % _("Connect")) @@ -406,7 +411,7 @@ class NonCopperClear(FlatCAMTool, Gerber): _("Draw lines between resulting\n" "segments to minimize tool lifts.") ) - self.grid3.addWidget(self.ncc_connect_cb, 15, 0, 1, 2) + self.grid3.addWidget(self.ncc_connect_cb, 16, 0, 1, 2) # Contour self.ncc_contour_cb = FCCheckBox('%s' % _("Contour")) @@ -416,7 +421,7 @@ class NonCopperClear(FlatCAMTool, Gerber): _("Cut around the perimeter of the polygon\n" "to trim rough edges.") ) - self.grid3.addWidget(self.ncc_contour_cb, 16, 0, 1, 2) + self.grid3.addWidget(self.ncc_contour_cb, 17, 0, 1, 2) # Rest Machining self.ncc_rest_cb = FCCheckBox('%s' % _("Rest Machining")) @@ -432,7 +437,7 @@ class NonCopperClear(FlatCAMTool, Gerber): "If not checked, use the standard algorithm.") ) - self.grid3.addWidget(self.ncc_rest_cb, 17, 0, 1, 2) + self.grid3.addWidget(self.ncc_rest_cb, 18, 0, 1, 2) # ## NCC Offset choice self.ncc_choice_offset_cb = FCCheckBox('%s' % _("Offset")) @@ -444,7 +449,7 @@ class NonCopperClear(FlatCAMTool, Gerber): "from the copper features.\n" "The value can be between 0 and 10 FlatCAM units.") ) - self.grid3.addWidget(self.ncc_choice_offset_cb, 18, 0, 1, 2) + self.grid3.addWidget(self.ncc_choice_offset_cb, 19, 0, 1, 2) # ## NCC Offset value self.ncc_offset_label = QtWidgets.QLabel('%s:' % _("Offset value")) @@ -466,8 +471,8 @@ class NonCopperClear(FlatCAMTool, Gerber): else: self.ncc_offset_spinner.setSingleStep(0.01) - self.grid3.addWidget(self.ncc_offset_label, 19, 0) - self.grid3.addWidget(self.ncc_offset_spinner, 19, 1) + self.grid3.addWidget(self.ncc_offset_label, 20, 0) + self.grid3.addWidget(self.ncc_offset_spinner, 20, 1) self.ncc_offset_label.hide() self.ncc_offset_spinner.hide() @@ -486,11 +491,11 @@ class NonCopperClear(FlatCAMTool, Gerber): "- 'Area Selection' - left mouse click to start selection of the area to be painted.\n" "- 'Reference Object' - will do non copper clearing within the area specified by another object.") ) - self.grid3.addWidget(self.reference_label, 20, 0) - self.grid3.addWidget(self.reference_radio, 20, 1) + self.grid3.addWidget(self.reference_label, 21, 0) + self.grid3.addWidget(self.reference_radio, 21, 1) form1 = QtWidgets.QFormLayout() - self.grid3.addLayout(form1, 21, 0, 1, 2) + self.grid3.addLayout(form1, 22, 0, 1, 2) self.box_combo_type_label = QtWidgets.QLabel('%s:' % _("Ref. Type")) self.box_combo_type_label.setToolTip( @@ -521,14 +526,14 @@ class NonCopperClear(FlatCAMTool, Gerber): separator_line2 = QtWidgets.QFrame() separator_line2.setFrameShape(QtWidgets.QFrame.HLine) separator_line2.setFrameShadow(QtWidgets.QFrame.Sunken) - self.grid3.addWidget(separator_line2, 22, 0, 1, 2) + self.grid3.addWidget(separator_line2, 23, 0, 1, 2) self.apply_param_to_all = FCButton(_("Apply parameters to all tools")) self.apply_param_to_all.setToolTip( _("The parameters in the current form will be applied\n" "on all the tools from the Tool Table.") ) - self.grid3.addWidget(self.apply_param_to_all, 23, 0, 1, 2) + self.grid3.addWidget(self.apply_param_to_all, 24, 0, 1, 2) self.generate_ncc_button = QtWidgets.QPushButton(_('Generate Geometry')) self.generate_ncc_button.setToolTip( @@ -564,11 +569,16 @@ class NonCopperClear(FlatCAMTool, Gerber): # ############################################################################# self.tools_table.setupContextMenu() self.tools_table.addContextMenu( - "Add", self.on_add_tool_by_key, icon=QtGui.QIcon(self.app.resource_location + "/plus16.png")) + _("Add"), self.on_add_tool_by_key, icon=QtGui.QIcon(self.app.resource_location + "/plus16.png") + ) self.tools_table.addContextMenu( - "Delete", lambda: + _("Add from DB"), self.on_add_tool_by_key, icon=QtGui.QIcon(self.app.resource_location + "/plus16.png") + ) + self.tools_table.addContextMenu( + _("Delete"), lambda: self.on_tool_delete(rows_to_delete=None, all_tools=None), - icon=QtGui.QIcon(self.app.resource_location + "/delete32.png")) + icon=QtGui.QIcon(self.app.resource_location + "/delete32.png") + ) # ############################################################################# # ########################## VARIABLES ######################################## @@ -1070,20 +1080,21 @@ class NonCopperClear(FlatCAMTool, Gerber): current_widget = self.form_fields[opt] if isinstance(current_widget, FCCheckBox): try: - current_widget.stateChanged.disconnect(self.form_to_storage) + current_widget.stateChanged.disconnect() except (TypeError, ValueError): pass if isinstance(current_widget, RadioSet): try: - current_widget.activated_custom.disconnect(self.form_to_storage) + current_widget.activated_custom.disconnect() except (TypeError, ValueError): pass elif isinstance(current_widget, FCDoubleSpinner): try: - current_widget.returnPressed.disconnect(self.form_to_storage) + current_widget.returnPressed.disconnect() except (TypeError, ValueError): pass + # then reconnect for opt in self.form_fields: current_widget = self.form_fields[opt] if isinstance(current_widget, FCCheckBox): @@ -1093,6 +1104,10 @@ class NonCopperClear(FlatCAMTool, Gerber): elif isinstance(current_widget, FCDoubleSpinner): current_widget.returnPressed.connect(self.form_to_storage) + self.ncc_choice_offset_cb.stateChanged.connect(self.on_offset_choice) + self.ncc_rest_cb.stateChanged.connect(self.on_rest_machining_check) + self.ncc_order_radio.activated_custom[str].connect(self.on_order_changed) + def ui_disconnect(self): try: # if connected, disconnect the signal from the slot on item_changed as it creates issues @@ -1416,18 +1431,17 @@ class NonCopperClear(FlatCAMTool, Gerber): # init values for the next usage self.reset_usage() + self.app.report_usage("on_paint_button_click") self.overlap = float(self.ncc_overlap_entry.get_value()) / 100.0 - self.grb_circle_steps = int(self.app.defaults["gerber_circle_steps"]) - self.connect = self.ncc_connect_cb.get_value() self.contour = self.ncc_contour_cb.get_value() self.has_offset = self.ncc_choice_offset_cb.isChecked() self.rest = self.ncc_rest_cb.get_value() - self.obj_name = self.object_combo.currentText() + # Get source object. try: self.ncc_obj = self.app.collection.get_by_name(self.obj_name) @@ -1523,11 +1537,11 @@ class NonCopperClear(FlatCAMTool, Gerber): def on_mouse_release(self, event): if self.app.is_legacy is False: event_pos = event.pos - event_is_dragging = event.is_dragging + # event_is_dragging = event.is_dragging right_button = 2 else: event_pos = (event.xdata, event.ydata) - event_is_dragging = self.app.plotcanvas.is_dragging + # event_is_dragging = self.app.plotcanvas.is_dragging right_button = 3 event_pos = self.app.plotcanvas.translate_coords(event_pos) @@ -1539,13 +1553,13 @@ class NonCopperClear(FlatCAMTool, Gerber): self.app.inform.emit('[WARNING_NOTCL] %s' % _("Click the end point of the paint area.")) self.cursor_pos = self.app.plotcanvas.translate_coords(event_pos) - if self.app.grid_status() == True: + if self.app.grid_status(): self.cursor_pos = self.app.geo_editor.snap(event_pos[0], event_pos[1]) else: self.app.inform.emit(_("Zone added. Click to start adding next zone or right click to finish.")) self.app.delete_selection_shape() - if self.app.grid_status() == True: + if self.app.grid_status(): curr_pos = self.app.geo_editor.snap(event_pos[0], event_pos[1]) else: curr_pos = (event_pos[0], event_pos[1]) @@ -1566,7 +1580,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.first_click = False return - elif event.button == right_button and self.mouse_is_dragging == False: + elif event.button == right_button and self.mouse_is_dragging is False: self.first_click = False self.delete_tool_selection_shape() @@ -1606,11 +1620,11 @@ class NonCopperClear(FlatCAMTool, Gerber): if self.app.is_legacy is False: event_pos = event.pos event_is_dragging = event.is_dragging - right_button = 2 + # right_button = 2 else: event_pos = (event.xdata, event.ydata) event_is_dragging = self.app.plotcanvas.is_dragging - right_button = 3 + # right_button = 3 curr_pos = self.app.plotcanvas.translate_coords(event_pos) @@ -1621,7 +1635,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.mouse_is_dragging = False # update the cursor position - if self.app.grid_status() == True: + if self.app.grid_status(): # Update cursor curr_pos = self.app.geo_editor.snap(curr_pos[0], curr_pos[1]) @@ -1651,17 +1665,8 @@ class NonCopperClear(FlatCAMTool, Gerber): sel_obj=None, ncctooldia=None, isotooldia=None, - margin=None, - has_offset=None, - offset=None, - select_method=None, outname=None, - overlap=None, - connect=None, - contour=None, order=None, - method=None, - rest=None, tools_storage=None, plot=True, run_threaded=True): @@ -1671,18 +1676,7 @@ class NonCopperClear(FlatCAMTool, Gerber): :param ncc_obj: ncc cleared object :param ncctooldia: a tuple or single element made out of diameters of the tools to be used to ncc clear :param isotooldia: a tuple or single element made out of diameters of the tools to be used for isolation - :param overlap: value by which the paths will overlap - :param order: if the tools are ordered and how - :param select_method: if to do ncc on the whole object, on an defined area or on an area defined by - another object - :param has_offset: True if an offset is needed - :param offset: distance from the copper features where the copper clearing is stopping - :param margin: a border around cleared area :param outname: name of the resulting object - :param connect: Connect lines to avoid tool lifts. - :param contour: Paint around the edges. - :param method: choice out of 'seed', 'normal', 'lines' - :param rest: True if to use rest-machining :param tools_storage: whether to use the current tools_storage self.ncc_tools or a different one. Usage of the different one is related to when this function is called from a TcL command. :param plot: if True after the job is finished the result will be plotted, else it will not. @@ -1701,25 +1695,6 @@ class NonCopperClear(FlatCAMTool, Gerber): # ##################################################################### units = self.app.defaults['units'] - - log.debug("NCC Tool started. Reading parameters.") - self.app.inform.emit(_("NCC Tool started. Reading parameters.")) - - ncc_method = method if method else self.ncc_method_radio.get_value() - - if margin is not None: - ncc_margin = margin - else: - ncc_margin = float(self.ncc_margin_entry.get_value()) - - if select_method is not None: - ncc_select = select_method - else: - ncc_select = self.reference_radio.get_value() - - overlap = overlap if overlap is not None else float(self.app.defaults["tools_nccoverlap"]) / 100.0 - connect = connect if connect else self.app.defaults["tools_nccconnect"] - contour = contour if contour else self.app.defaults["tools_ncccontour"] order = order if order else self.ncc_order_radio.get_value() # determine if to use the progressive plotting @@ -1733,17 +1708,6 @@ class NonCopperClear(FlatCAMTool, Gerber): else: tools_storage = self.ncc_tools - ncc_offset = 0.0 - if has_offset is True: - if offset is not None: - ncc_offset = offset - else: - try: - ncc_offset = float(self.ncc_offset_spinner.get_value()) - except ValueError: - self.app.inform.emit('[ERROR_NOTCL] %s' % _("Wrong value format entered, use a number.")) - return - # ###################################################################################################### # # Read the tooldia parameter and create a sorted list out them - they may be more than one diameter ## # ###################################################################################################### @@ -1843,11 +1807,7 @@ class NonCopperClear(FlatCAMTool, Gerber): # set the name for the future Geometry object # I do it here because it is also stored inside the gen_clear_area() and gen_clear_area_rest() methods # ######################################################################################################## - rest_machining_choice = rest if rest is not None else self.app.defaults["tools_nccrest"] - if rest_machining_choice is True: - name = outname if outname is not None else self.obj_name + "_ncc_rm" - else: - name = outname if outname is not None else self.obj_name + "_ncc" + name = outname if outname is not None else self.obj_name + "_ncc" # ########################################################################################## # Initializes the new geometry object ###################################################### @@ -2026,7 +1986,7 @@ class NonCopperClear(FlatCAMTool, Gerber): if has_offset is True: app_obj.inform.emit('[WARNING_NOTCL] %s ...' % _("Buffering")) sol_geo = sol_geo.buffer(distance=ncc_offset) - app_obj.inform.emit('[success] %s ...' % _("Buffering finished")) + app_obj.inform.emit('[success] %s ...' % _("Buffering finished")) empty = self.get_ncc_empty_area(target=sol_geo, boundary=bounding_box) if empty == 'fail': return 'fail' @@ -2071,7 +2031,7 @@ class NonCopperClear(FlatCAMTool, Gerber): area = empty.buffer(-offset) try: area = area.difference(cleared) - except Exception as e: + except Exception: continue # Transform area to MultiPolygon @@ -2330,7 +2290,7 @@ class NonCopperClear(FlatCAMTool, Gerber): if has_offset is True: app_obj.inform.emit('[WARNING_NOTCL] %s ...' % _("Buffering")) sol_geo = sol_geo.buffer(distance=ncc_offset) - app_obj.inform.emit('[success] %s ...' % _("Buffering finished")) + app_obj.inform.emit('[success] %s ...' % _("Buffering finished")) empty = self.get_ncc_empty_area(target=sol_geo, boundary=bounding_box) if empty == 'fail': return 'fail' @@ -2407,7 +2367,7 @@ class NonCopperClear(FlatCAMTool, Gerber): new_geo = line_elem.intersection(bounding_box) if new_geo and not new_geo.is_empty: new_geometry.append(new_geo) - except Exception as e: + except Exception: pass # a MultiLineString geometry element will show that the isolation is broken for this tool @@ -2516,7 +2476,6 @@ class NonCopperClear(FlatCAMTool, Gerber): # variables to display the percentage of work done geo_len = len(area.geoms) - disp_number = 0 old_disp_number = 0 log.warning("Total number of polygons to be cleared. %s" % str(geo_len)) @@ -3065,7 +3024,7 @@ class NonCopperClear(FlatCAMTool, Gerber): if has_offset is True: app_obj.inform.emit('[WARNING_NOTCL] %s ...' % _("Buffering")) sol_geo = sol_geo.buffer(distance=ncc_offset) - app_obj.inform.emit('[success] %s ...' % _("Buffering finished")) + app_obj.inform.emit('[success] %s ...' % _("Buffering finished")) empty = self.get_ncc_empty_area(target=sol_geo, boundary=bounding_box) if empty == 'fail': return 'fail' @@ -3110,7 +3069,7 @@ class NonCopperClear(FlatCAMTool, Gerber): area = empty.buffer(-offset) try: area = area.difference(cleared) - except Exception as e: + except Exception: continue # Transform area to MultiPolygon @@ -3332,7 +3291,7 @@ class NonCopperClear(FlatCAMTool, Gerber): if has_offset is True: app_obj.inform.emit('[WARNING_NOTCL] %s ...' % _("Buffering")) sol_geo = sol_geo.buffer(distance=ncc_offset) - app_obj.inform.emit('[success] %s ...' % _("Buffering finished")) + app_obj.inform.emit('[success] %s ...' % _("Buffering finished")) empty = self.get_ncc_empty_area(target=sol_geo, boundary=bounding_box) if empty == 'fail': return 'fail' @@ -3500,7 +3459,7 @@ class NonCopperClear(FlatCAMTool, Gerber): raise FlatCAMApp.GracefulException try: area = area.difference(poly) - except Exception as e: + except Exception: pass cleared_by_last_tool[:] = [] @@ -3518,7 +3477,6 @@ class NonCopperClear(FlatCAMTool, Gerber): # variables to display the percentage of work done geo_len = len(area.geoms) - disp_number = 0 old_disp_number = 0 log.warning("Total number of polygons to be cleared. %s" % str(geo_len)) From 7d0a792085137f3db6158f41e77eb93c941d3fd3 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 10 Jan 2020 14:55:32 +0200 Subject: [PATCH 002/209] - small changes --- FlatCAMApp.py | 3 ++- flatcamGUI/PreferencesUI.py | 22 ++++------------------ flatcamGUI/VisPyCanvas.py | 23 ++--------------------- 3 files changed, 8 insertions(+), 40 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index e41567d2..6d26bfe3 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -8465,7 +8465,7 @@ class App(QtCore.QObject): self.draw_moving_selection_shape(self.pos, pos, color=self.defaults['global_alt_sel_line'], face_color=self.defaults['global_alt_sel_fill']) self.selection_type = False - elif dx > 0: + elif dx >= 0: self.draw_moving_selection_shape(self.pos, pos) self.selection_type = True else: @@ -8862,6 +8862,7 @@ class App(QtCore.QObject): pt4 = (float(sel_obj.options['xmin']), float(sel_obj.options['ymax'])) sel_rect = Polygon([pt1, pt2, pt3, pt4]) + if self.defaults['units'].upper() == 'MM': sel_rect = sel_rect.buffer(-0.1) sel_rect = sel_rect.buffer(0.2) diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index 365fd17e..b84a514b 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -333,7 +333,8 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI): # Theme selection self.theme_label = QtWidgets.QLabel('%s:' % _('Theme')) self.theme_label.setToolTip( - _("Select a theme for FlatCAM.") + _("Select a theme for FlatCAM.\n" + "It will theme the plot area.") ) self.theme_radio = RadioSet([ @@ -356,6 +357,7 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI): self.theme_button = FCButton(_("Apply Theme")) self.theme_button.setToolTip( _("Select a theme for FlatCAM.\n" + "It will theme the plot area.\n" "The application will restart after change.") ) grid0.addWidget(self.theme_button, 2, 0, 1, 3) @@ -1587,14 +1589,6 @@ class GeneralAppPrefGroupUI(OptionsGroupUI): "After change, it will be applied at next App start.") ) self.worker_number_sb = FCSpinner() - self.worker_number_sb.setToolTip( - _("The number of Qthreads made available to the App.\n" - "A bigger number may finish the jobs more quickly but\n" - "depending on your computer speed, may make the App\n" - "unresponsive. Can have a value between 2 and 16.\n" - "Default value is 2.\n" - "After change, it will be applied at next App start.") - ) self.worker_number_sb.set_range(2, 16) grid0.addWidget(self.worker_number_label, 25, 0) @@ -1604,21 +1598,13 @@ class GeneralAppPrefGroupUI(OptionsGroupUI): tol_label = QtWidgets.QLabel('%s:' % _("Geo Tolerance")) tol_label.setToolTip(_( "This value can counter the effect of the Circle Steps\n" - "parameter. Default value is 0.01.\n" + "parameter. Default value is 0.005.\n" "A lower value will increase the detail both in image\n" "and in Gcode for the circles, with a higher cost in\n" "performance. Higher value will provide more\n" "performance at the expense of level of detail." )) self.tol_entry = FCDoubleSpinner() - self.tol_entry.setToolTip(_( - "This value can counter the effect of the Circle Steps\n" - "parameter. Default value is 0.01.\n" - "A lower value will increase the detail both in image\n" - "and in Gcode for the circles, with a higher cost in\n" - "performance. Higher value will provide more\n" - "performance at the expense of level of detail." - )) self.tol_entry.setSingleStep(0.001) self.tol_entry.set_precision(6) diff --git a/flatcamGUI/VisPyCanvas.py b/flatcamGUI/VisPyCanvas.py index f7a9c552..7d7efe13 100644 --- a/flatcamGUI/VisPyCanvas.py +++ b/flatcamGUI/VisPyCanvas.py @@ -24,24 +24,16 @@ black = Color("#000000") class VisPyCanvas(scene.SceneCanvas): def __init__(self, config=None): - print("vp_1") - try: - # scene.SceneCanvas.__init__(self, keys=None, config=config) - super().__init__(config=config, keys=None) - except Exception as e: - print("VisPyCanvas.__init__() -> %s" % str(e)) - - print("vp_2") + # scene.SceneCanvas.__init__(self, keys=None, config=config) + super().__init__(config=config, keys=None) self.unfreeze() - print("vp_3") settings = QSettings("Open Source", "FlatCAM") if settings.contains("axis_font_size"): a_fsize = settings.value('axis_font_size', type=int) else: a_fsize = 8 - print("vp_4") if settings.contains("theme"): theme = settings.value('theme', type=str) @@ -59,8 +51,6 @@ class VisPyCanvas(scene.SceneCanvas): # back_color = Color('#272822') # darker # back_color = Color('#3c3f41') # lighter - print("vp_5") - self.central_widget.bgcolor = back_color self.central_widget.border_color = back_color @@ -70,8 +60,6 @@ class VisPyCanvas(scene.SceneCanvas): top_padding = self.grid_widget.add_widget(row=0, col=0, col_span=2) top_padding.height_max = 0 - print("vp_6") - self.yaxis = scene.AxisWidget( orientation='left', axis_color=tick_color, text_color=tick_color, font_size=a_fsize, axis_width=1 ) @@ -89,13 +77,9 @@ class VisPyCanvas(scene.SceneCanvas): # right_padding.width_max = 24 right_padding.width_max = 0 - print("vp_7") - view = self.grid_widget.add_view(row=1, col=1, border_color=tick_color, bgcolor=theme_color) view.camera = Camera(aspect=1, rect=(-25, -25, 150, 150)) - print("vp_8") - # Following function was removed from 'prepare_draw()' of 'Grid' class by patch, # it is necessary to call manually self.grid_widget._update_child_widget_dim() @@ -118,10 +102,7 @@ class VisPyCanvas(scene.SceneCanvas): else: self.grid = scene.GridLines(parent=self.view.scene, color='#dededeff') - print("vp_9") - self.grid.set_gl_state(depth_test=False) - print("vp_10") self.freeze() From fc31bb573d8af5d194e1f2db32d376711897b354 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 10 Jan 2020 15:56:23 +0200 Subject: [PATCH 003/209] - working on a new tool: Extract Drills Tool who will create a Excellon object out of the apertures of a Gerber object --- README.md | 4 + flatcamTools/ToolExtractDrills.py | 264 ++++++++++++++++++++++++++++++ flatcamTools/__init__.py | 5 +- 3 files changed, 271 insertions(+), 2 deletions(-) create mode 100644 flatcamTools/ToolExtractDrills.py diff --git a/README.md b/README.md index db7ea631..454d3bac 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +10.02.2019 + +- working on a new tool: Extract Drills Tool who will create a Excellon object out of the apertures of a Gerber object + 8.01.2019 - working in NCC Tool diff --git a/flatcamTools/ToolExtractDrills.py b/flatcamTools/ToolExtractDrills.py new file mode 100644 index 00000000..be2002a8 --- /dev/null +++ b/flatcamTools/ToolExtractDrills.py @@ -0,0 +1,264 @@ + +from PyQt5 import QtWidgets, QtCore + +from FlatCAMTool import FlatCAMTool +from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, EvalEntry, FCEntry +from FlatCAMObj import FlatCAMGerber, FlatCAMExcellon, FlatCAMGeometry + +from numpy import Inf + +from shapely.geometry import Point +from shapely import affinity + +import logging +import gettext +import FlatCAMTranslation as fcTranslate +import builtins + +fcTranslate.apply_language('strings') +if '_' not in builtins.__dict__: + _ = gettext.gettext + +log = logging.getLogger('base') + + +class ToolExtractDrills(FlatCAMTool): + + toolName = _("Extract Drills") + + def __init__(self, app): + FlatCAMTool.__init__(self, app) + self.decimals = self.app.decimals + + # ## Title + title_label = QtWidgets.QLabel("%s" % self.toolName) + title_label.setStyleSheet(""" + QLabel + { + font-size: 16px; + font-weight: bold; + } + """) + self.layout.addWidget(title_label) + + self.empty_lb = QtWidgets.QLabel("") + self.layout.addWidget(self.empty_lb) + + # ## Grid Layout + grid_lay = QtWidgets.QGridLayout() + self.layout.addLayout(grid_lay) + grid_lay.setColumnStretch(0, 1) + grid_lay.setColumnStretch(1, 0) + + # ## Gerber Object + self.gerber_object_combo = QtWidgets.QComboBox() + self.gerber_object_combo.setModel(self.app.collection) + self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) + self.gerber_object_combo.setCurrentIndex(1) + + self.grb_label = QtWidgets.QLabel("%s:" % _("GERBER")) + self.grb_label.setToolTip('%s.' % _("Gerber from which to extract drill holes")) + + self.mirror_gerber_button.setStyleSheet(""" + QPushButton + { + font-weight: bold; + } + """) + self.mirror_gerber_button.setMinimumWidth(60) + + # grid_lay.addRow("Bottom Layer:", self.object_combo) + grid_lay.addWidget(self.grb_label, 0, 0) + grid_lay.addWidget(self.gerber_object_combo, 1, 0) + + # ## Grid Layout + grid_lay1 = QtWidgets.QGridLayout() + self.layout.addLayout(grid_lay1) + + # ## Axis + self.hole_size_radio = RadioSet([{'label': _("Fixed"), 'value': 'fixed'}, + {'label': _("Proportional"), 'value': 'prop'}]) + self.hole_size_label = QtWidgets.QLabel('%s:' % _("Hole Size")) + self.hole_size_label.setToolTip( + _("The type of hole size. Can be:\n" + "- Fixed -> all holes will have a set size\n" + "- Proprotional -> each hole will havea a variable size\n" + "such as to preserve a set annular ring")) + + grid_lay1.addWidget(self.hole_size_label, 3, 0) + grid_lay1.addWidget(self.hole_size_radio, 3, 1) + + self.layout.addWidget(QtWidgets.QLabel('')) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + self.layout.addWidget(separator_line) + + grid1 = QtWidgets.QGridLayout() + self.layout.addLayout(grid1) + grid1.setColumnStretch(0, 0) + grid1.setColumnStretch(1, 1) + + # Diameter value + self.dia_entry = FCDoubleSpinner() + self.dia_entry.set_precision(self.decimals) + self.dia_entry.set_range(0.0000, 9999.9999) + + self.dia_label = QtWidgets.QLabel('%s:' % _("Diameter")) + self.dia_label.setToolTip( + _("Fixed hole diameter.") + ) + + grid1.addWidget(self.dia_label, 1, 0) + grid1.addWidget(self.dia_entry, 1, 1) + + # Annular Ring value + self.ring_entry = FCDoubleSpinner() + self.ring_entry.set_precision(self.decimals) + self.ring_entry.set_range(0.0000, 9999.9999) + + self.ring_label = QtWidgets.QLabel('%s:' % _("Annular Ring")) + self.ring_label.setToolTip( + _("The size of annular ring.\n" + "The copper sliver between the drill hole exterior\n" + "and the margin of the copper pad.") + ) + + grid1.addWidget(self.ring_label, 2, 0) + grid1.addWidget(self.ring_entry, 2, 1) + + # Calculate Bounding box + self.e_drills_button = QtWidgets.QPushButton(_("Extract Drills")) + self.e_drills_button.setToolTip( + _("Extract drills from a given Gerber file.") + ) + self.e_drills_button.setStyleSheet(""" + QPushButton + { + font-weight: bold; + } + """) + self.layout.addWidget(self.e_drills_button) + + self.layout.addStretch() + + # ## Reset Tool + self.reset_button = QtWidgets.QPushButton(_("Reset Tool")) + self.reset_button.setToolTip( + _("Will reset the tool parameters.") + ) + self.reset_button.setStyleSheet(""" + QPushButton + { + font-weight: bold; + } + """) + self.layout.addWidget(self.reset_button) + + # ## Signals + self.hole_size_radio.activated_custom(self.on_hole_size_toggle) + self.e_drills_button.clicked.connect(self.on_extract_drills_click) + self.reset_button.clicked.connect(self.set_tool_ui) + + self.tools = list() + self.drills = dict() + + def install(self, icon=None, separator=None, **kwargs): + FlatCAMTool.install(self, icon, separator, shortcut='ALT+D', **kwargs) + + def run(self, toggle=True): + self.app.report_usage("Extract Drills()") + + if toggle: + # if the splitter is hidden, display it, else hide it but only if the current widget is the same + if self.app.ui.splitter.sizes()[0] == 0: + self.app.ui.splitter.setSizes([1, 1]) + else: + try: + if self.app.ui.tool_scroll_area.widget().objectName() == self.toolName: + # if tab is populated with the tool but it does not have the focus, focus on it + if not self.app.ui.notebook.currentWidget() is self.app.ui.tool_tab: + # focus on Tool Tab + self.app.ui.notebook.setCurrentWidget(self.app.ui.tool_tab) + else: + self.app.ui.splitter.setSizes([0, 1]) + except AttributeError: + pass + else: + if self.app.ui.splitter.sizes()[0] == 0: + self.app.ui.splitter.setSizes([1, 1]) + + FlatCAMTool.run(self) + self.set_tool_ui() + + self.app.ui.notebook.setTabText(2, _("Extract Drills Tool")) + + def set_tool_ui(self): + self.reset_fields() + + self.hole_size_radio.set_value(self.app.defaults["tools_edrills_hole_type"]) + + self.dia_entry.set_value(float(self.app.defaults["tools_edrills_hole_fixed_dia"])) + self.ring_entry.set_value(float(self.app.defaults["tools_edrills_hole_ring"])) + + def on_extract_drills_click(self): + selection_index = self.gerber_object_combo.currentIndex() + # fcobj = self.app.collection.object_list[selection_index] + model_index = self.app.collection.index(selection_index, 0, self.gerber_object_combo.rootModelIndex()) + try: + fcobj = model_index.internalPointer().obj + except Exception as e: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no Gerber object loaded ...")) + return + + if not isinstance(fcobj, FlatCAMGerber): + self.app.inform.emit('[ERROR_NOTCL] %s' % _("Only Gerber, Excellon and Geometry objects can be mirrored.")) + return + + axis = self.mirror_axis.get_value() + mode = self.axis_location.get_value() + + if mode == "point": + try: + px, py = self.point_entry.get_value() + except TypeError: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("'Point' coordinates missing. " + "Using Origin (0, 0) as mirroring reference.")) + px, py = (0, 0) + + else: + selection_index_box = self.box_combo.currentIndex() + model_index_box = self.app.collection.index(selection_index_box, 0, self.box_combo.rootModelIndex()) + try: + bb_obj = model_index_box.internalPointer().obj + except Exception as e: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no Box object loaded ...")) + return + + xmin, ymin, xmax, ymax = bb_obj.bounds() + px = 0.5 * (xmin + xmax) + py = 0.5 * (ymin + ymax) + + fcobj.mirror(axis, [px, py]) + self.app.object_changed.emit(fcobj) + fcobj.plot() + self.app.inform.emit('[success] Gerber %s %s...' % (str(fcobj.options['name']), _("was mirrored"))) + + def on_hole_size_toggle(self, val): + if val == "fixed": + self.dia_entry.show() + self.dia_label.show() + + self.ring_label.hide() + self.ring_entry.hide() + else: + self.dia_entry.hide() + self.dia_label.hide() + + self.ring_label.show() + self.ring_entry.show() + + def reset_fields(self): + self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) + self.gerber_object_combo.setCurrentIndex(0) diff --git a/flatcamTools/__init__.py b/flatcamTools/__init__.py index d986974e..be389e70 100644 --- a/flatcamTools/__init__.py +++ b/flatcamTools/__init__.py @@ -1,6 +1,5 @@ import sys - from flatcamTools.ToolCalculators import ToolCalculator from flatcamTools.ToolCalibration import ToolCalibration from flatcamTools.ToolCutOut import CutOut @@ -17,10 +16,10 @@ from flatcamTools.ToolDistanceMin import DistanceMin from flatcamTools.ToolMove import ToolMove from flatcamTools.ToolNonCopperClear import NonCopperClear +from flatcamTools.ToolPaint import ToolPaint from flatcamTools.ToolOptimal import ToolOptimal -from flatcamTools.ToolPaint import ToolPaint from flatcamTools.ToolPanelize import Panelize from flatcamTools.ToolPcbWizard import PcbWizard from flatcamTools.ToolPDF import ToolPDF @@ -32,6 +31,8 @@ from flatcamTools.ToolRulesCheck import RulesCheck from flatcamTools.ToolCopperThieving import ToolCopperThieving from flatcamTools.ToolFiducials import ToolFiducials +from flatcamTools.ToolExtractDrills import ToolExtractDrills + from flatcamTools.ToolShell import FCShell from flatcamTools.ToolSolderPaste import SolderPaste from flatcamTools.ToolSub import ToolSub From f2ccb48c98ada313ce1eccb515fde86f39f2d04a Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 10 Jan 2020 16:56:29 +0200 Subject: [PATCH 004/209] - finished the GUI in the Extract Drills Tool --- FlatCAMApp.py | 28 +++++--- README.md | 1 + flatcamTools/ToolExtractDrills.py | 115 +++++++++++++----------------- 3 files changed, 70 insertions(+), 74 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 6d26bfe3..3815287c 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -954,6 +954,11 @@ class App(QtCore.QObject): "tools_cal_toolchange_xy": '', "tools_cal_sec_point": 'tl', + # Drills Extraction Tool + "tools_edrills_hole_type": 'fixed', + "tools_edrills_hole_fixed_dia": 0.5, + "tools_edrills_hole_ring": 0.2, + # Utilities # file associations "fa_excellon": 'drd, drl, exc, ncd, tap, xln', @@ -2464,12 +2469,13 @@ class App(QtCore.QObject): self.qrcode_tool = None self.copper_thieving_tool = None self.fiducial_tool = None + self.edrills_tool = None # always install tools only after the shell is initialized because the self.inform.emit() depends on shell try: self.install_tools() - except AttributeError: - pass + except AttributeError as e: + log.debug("App.__init__() install tools() --> %s" % str(e)) # ################################################################################## # ########################### SETUP RECENT ITEMS ################################### @@ -3017,13 +3023,6 @@ class App(QtCore.QObject): :return: None """ - self.dblsidedtool = DblSidedTool(self) - self.dblsidedtool.install(icon=QtGui.QIcon(self.resource_location + '/doubleside16.png'), separator=True) - - self.cal_exc_tool = ToolCalibration(self) - self.cal_exc_tool.install(icon=QtGui.QIcon(self.resource_location + '/calibrate_16.png'), pos=self.ui.menutool, - before=self.dblsidedtool.menuAction, - separator=False) self.distance_tool = Distance(self) self.distance_tool.install(icon=QtGui.QIcon(self.resource_location + '/distance16.png'), pos=self.ui.menuedit, before=self.ui.menueditorigin, @@ -3035,6 +3034,17 @@ class App(QtCore.QObject): before=self.ui.menueditorigin, separator=True) + self.dblsidedtool = DblSidedTool(self) + self.dblsidedtool.install(icon=QtGui.QIcon(self.resource_location + '/doubleside16.png'), separator=False) + + self.cal_exc_tool = ToolCalibration(self) + self.cal_exc_tool.install(icon=QtGui.QIcon(self.resource_location + '/calibrate_16.png'), pos=self.ui.menutool, + before=self.dblsidedtool.menuAction, + separator=False) + + self.edrills_tool = ToolExtractDrills(self) + self.edrills_tool.install(icon=QtGui.QIcon(self.resource_location + '/drill16.png'), separator=True) + self.panelize_tool = Panelize(self) self.panelize_tool.install(icon=QtGui.QIcon(self.resource_location + '/panelize16.png')) diff --git a/README.md b/README.md index 454d3bac..9093667b 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 10.02.2019 - working on a new tool: Extract Drills Tool who will create a Excellon object out of the apertures of a Gerber object +- finished the GUI in the Extract Drills Tool 8.01.2019 diff --git a/flatcamTools/ToolExtractDrills.py b/flatcamTools/ToolExtractDrills.py index be2002a8..7f47ab3e 100644 --- a/flatcamTools/ToolExtractDrills.py +++ b/flatcamTools/ToolExtractDrills.py @@ -59,21 +59,15 @@ class ToolExtractDrills(FlatCAMTool): self.grb_label = QtWidgets.QLabel("%s:" % _("GERBER")) self.grb_label.setToolTip('%s.' % _("Gerber from which to extract drill holes")) - self.mirror_gerber_button.setStyleSheet(""" - QPushButton - { - font-weight: bold; - } - """) - self.mirror_gerber_button.setMinimumWidth(60) - # grid_lay.addRow("Bottom Layer:", self.object_combo) grid_lay.addWidget(self.grb_label, 0, 0) grid_lay.addWidget(self.gerber_object_combo, 1, 0) # ## Grid Layout - grid_lay1 = QtWidgets.QGridLayout() - self.layout.addLayout(grid_lay1) + grid1 = QtWidgets.QGridLayout() + self.layout.addLayout(grid1) + grid1.setColumnStretch(0, 0) + grid1.setColumnStretch(1, 1) # ## Axis self.hole_size_radio = RadioSet([{'label': _("Fixed"), 'value': 'fixed'}, @@ -85,20 +79,15 @@ class ToolExtractDrills(FlatCAMTool): "- Proprotional -> each hole will havea a variable size\n" "such as to preserve a set annular ring")) - grid_lay1.addWidget(self.hole_size_label, 3, 0) - grid_lay1.addWidget(self.hole_size_radio, 3, 1) + grid1.addWidget(self.hole_size_label, 3, 0) + grid1.addWidget(self.hole_size_radio, 3, 1) - self.layout.addWidget(QtWidgets.QLabel('')) + # grid_lay1.addWidget(QtWidgets.QLabel('')) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - self.layout.addWidget(separator_line) - - grid1 = QtWidgets.QGridLayout() - self.layout.addLayout(grid1) - grid1.setColumnStretch(0, 0) - grid1.setColumnStretch(1, 1) + grid1.addWidget(separator_line, 5, 0, 1, 2) # Diameter value self.dia_entry = FCDoubleSpinner() @@ -110,8 +99,8 @@ class ToolExtractDrills(FlatCAMTool): _("Fixed hole diameter.") ) - grid1.addWidget(self.dia_label, 1, 0) - grid1.addWidget(self.dia_entry, 1, 1) + grid1.addWidget(self.dia_label, 7, 0) + grid1.addWidget(self.dia_entry, 7, 1) # Annular Ring value self.ring_entry = FCDoubleSpinner() @@ -125,8 +114,8 @@ class ToolExtractDrills(FlatCAMTool): "and the margin of the copper pad.") ) - grid1.addWidget(self.ring_label, 2, 0) - grid1.addWidget(self.ring_entry, 2, 1) + grid1.addWidget(self.ring_label, 8, 0) + grid1.addWidget(self.ring_entry, 8, 1) # Calculate Bounding box self.e_drills_button = QtWidgets.QPushButton(_("Extract Drills")) @@ -157,7 +146,7 @@ class ToolExtractDrills(FlatCAMTool): self.layout.addWidget(self.reset_button) # ## Signals - self.hole_size_radio.activated_custom(self.on_hole_size_toggle) + self.hole_size_radio.activated_custom.connect(self.on_hole_size_toggle) self.e_drills_button.clicked.connect(self.on_extract_drills_click) self.reset_button.clicked.connect(self.set_tool_ui) @@ -165,7 +154,7 @@ class ToolExtractDrills(FlatCAMTool): self.drills = dict() def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+D', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='ALT+E', **kwargs) def run(self, toggle=True): self.app.report_usage("Extract Drills()") @@ -204,60 +193,56 @@ class ToolExtractDrills(FlatCAMTool): def on_extract_drills_click(self): selection_index = self.gerber_object_combo.currentIndex() - # fcobj = self.app.collection.object_list[selection_index] model_index = self.app.collection.index(selection_index, 0, self.gerber_object_combo.rootModelIndex()) + try: fcobj = model_index.internalPointer().obj except Exception as e: self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no Gerber object loaded ...")) return - if not isinstance(fcobj, FlatCAMGerber): - self.app.inform.emit('[ERROR_NOTCL] %s' % _("Only Gerber, Excellon and Geometry objects can be mirrored.")) - return - - axis = self.mirror_axis.get_value() - mode = self.axis_location.get_value() - - if mode == "point": - try: - px, py = self.point_entry.get_value() - except TypeError: - self.app.inform.emit('[WARNING_NOTCL] %s' % _("'Point' coordinates missing. " - "Using Origin (0, 0) as mirroring reference.")) - px, py = (0, 0) - - else: - selection_index_box = self.box_combo.currentIndex() - model_index_box = self.app.collection.index(selection_index_box, 0, self.box_combo.rootModelIndex()) - try: - bb_obj = model_index_box.internalPointer().obj - except Exception as e: - self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no Box object loaded ...")) - return - - xmin, ymin, xmax, ymax = bb_obj.bounds() - px = 0.5 * (xmin + xmax) - py = 0.5 * (ymin + ymax) - - fcobj.mirror(axis, [px, py]) - self.app.object_changed.emit(fcobj) - fcobj.plot() + # axis = self.mirror_axis.get_value() + # mode = self.axis_location.get_value() + # + # if mode == "point": + # try: + # px, py = self.point_entry.get_value() + # except TypeError: + # self.app.inform.emit('[WARNING_NOTCL] %s' % _("'Point' coordinates missing. " + # "Using Origin (0, 0) as mirroring reference.")) + # px, py = (0, 0) + # + # else: + # selection_index_box = self.box_combo.currentIndex() + # model_index_box = self.app.collection.index(selection_index_box, 0, self.box_combo.rootModelIndex()) + # try: + # bb_obj = model_index_box.internalPointer().obj + # except Exception as e: + # self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no Box object loaded ...")) + # return + # + # xmin, ymin, xmax, ymax = bb_obj.bounds() + # px = 0.5 * (xmin + xmax) + # py = 0.5 * (ymin + ymax) + # + # fcobj.mirror(axis, [px, py]) + # self.app.object_changed.emit(fcobj) + # fcobj.plot() self.app.inform.emit('[success] Gerber %s %s...' % (str(fcobj.options['name']), _("was mirrored"))) def on_hole_size_toggle(self, val): if val == "fixed": - self.dia_entry.show() - self.dia_label.show() + self.dia_entry.setDisabled(False) + self.dia_label.setDisabled(False) - self.ring_label.hide() - self.ring_entry.hide() + self.ring_label.setDisabled(True) + self.ring_entry.setDisabled(True) else: - self.dia_entry.hide() - self.dia_label.hide() + self.dia_entry.setDisabled(True) + self.dia_label.setDisabled(True) - self.ring_label.show() - self.ring_entry.show() + self.ring_label.setDisabled(False) + self.ring_entry.setDisabled(False) def reset_fields(self): self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) From c16ecfe0c3de7eb8855da06bf43cc923100604db Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 11 Jan 2020 00:52:06 +0200 Subject: [PATCH 005/209] - fixed issue in Film Tool where some parameters names in calls of method export_positive() were not matching the actual parameters name - finished the Extract Drills Tool - fixed a small issue in the DoubleSided Tool --- FlatCAMApp.py | 17 ++++-- README.md | 3 + flatcamTools/ToolDblSided.py | 7 ++- flatcamTools/ToolExtractDrills.py | 98 +++++++++++++++++++++---------- flatcamTools/ToolFilm.py | 31 ++++++---- 5 files changed, 103 insertions(+), 53 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 3815287c..d80e3ec5 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -10389,7 +10389,8 @@ class App(QtCore.QObject): self.report_usage("export_svg()") if filename is None: - filename = self.defaults["global_last_save_folder"] + filename = self.defaults["global_last_save_folder"] if self.defaults["global_last_save_folder"] \ + is not None else self.defaults["global_last_folder"] self.log.debug("export_svg()") @@ -10457,7 +10458,8 @@ class App(QtCore.QObject): self.report_usage("save source file()") if filename is None: - filename = self.defaults["global_last_save_folder"] + filename = self.defaults["global_last_save_folder"] if self.defaults["global_last_save_folder"] \ + is not None else self.defaults["global_last_folder"] self.log.debug("save source file()") @@ -10500,7 +10502,10 @@ class App(QtCore.QObject): self.report_usage("export_excellon()") if filename is None: - filename = self.defaults["global_last_save_folder"] + '/' + 'exported_excellon' + if self.defaults["global_last_save_folder"]: + filename = self.defaults["global_last_save_folder"] + '/' + 'exported_excellon' + else: + filename = self.defaults["global_last_folder"] + '/' + 'exported_excellon' self.log.debug("export_excellon()") @@ -10656,7 +10661,8 @@ class App(QtCore.QObject): self.report_usage("export_gerber()") if filename is None: - filename = self.defaults["global_last_save_folder"] + filename = self.defaults["global_last_save_folder"] if self.defaults["global_last_save_folder"] \ + is not None else self.defaults["global_last_folder"] self.log.debug("export_gerber()") @@ -10792,7 +10798,8 @@ class App(QtCore.QObject): self.report_usage("export_dxf()") if filename is None: - filename = self.defaults["global_last_save_folder"] + filename = self.defaults["global_last_save_folder"] if self.defaults["global_last_save_folder"] \ + is not None else self.defaults["global_last_folder"] self.log.debug("export_dxf()") diff --git a/README.md b/README.md index 9093667b..3cc30ba8 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,9 @@ CAD program, and create G-Code for Isolation routing. - working on a new tool: Extract Drills Tool who will create a Excellon object out of the apertures of a Gerber object - finished the GUI in the Extract Drills Tool +- fixed issue in Film Tool where some parameters names in calls of method export_positive() were not matching the actual parameters name +- finished the Extract Drills Tool +- fixed a small issue in the DoubleSided Tool 8.01.2019 diff --git a/flatcamTools/ToolDblSided.py b/flatcamTools/ToolDblSided.py index 3308c159..0b00fc6e 100644 --- a/flatcamTools/ToolDblSided.py +++ b/flatcamTools/ToolDblSided.py @@ -533,16 +533,17 @@ class DblSidedTool(FlatCAMTool): "Add them and retry.")) return - drills = [] + drills = list() for hole in holes: point = Point(hole) point_mirror = affinity.scale(point, xscale, yscale, origin=(px, py)) drills.append({"point": point, "tool": "1"}) drills.append({"point": point_mirror, "tool": "1"}) - if 'solid_geometry' not in tools: - tools["1"]['solid_geometry'] = [] + if 'solid_geometry' not in tools["1"]: + tools["1"]['solid_geometry'] = list() else: + tools["1"]['solid_geometry'].append(point) tools["1"]['solid_geometry'].append(point_mirror) def obj_init(obj_inst, app_inst): diff --git a/flatcamTools/ToolExtractDrills.py b/flatcamTools/ToolExtractDrills.py index 7f47ab3e..5d2a604e 100644 --- a/flatcamTools/ToolExtractDrills.py +++ b/flatcamTools/ToolExtractDrills.py @@ -150,11 +150,8 @@ class ToolExtractDrills(FlatCAMTool): self.e_drills_button.clicked.connect(self.on_extract_drills_click) self.reset_button.clicked.connect(self.set_tool_ui) - self.tools = list() - self.drills = dict() - def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+E', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='ALT+I', **kwargs) def run(self, toggle=True): self.app.report_usage("Extract Drills()") @@ -192,6 +189,12 @@ class ToolExtractDrills(FlatCAMTool): self.ring_entry.set_value(float(self.app.defaults["tools_edrills_hole_ring"])) def on_extract_drills_click(self): + + drill_dia = self.dia_entry.get_value() + ring_val = self.ring_entry.get_value() + drills = list() + tools = dict() + selection_index = self.gerber_object_combo.currentIndex() model_index = self.app.collection.index(selection_index, 0, self.gerber_object_combo.rootModelIndex()) @@ -201,34 +204,65 @@ class ToolExtractDrills(FlatCAMTool): self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no Gerber object loaded ...")) return - # axis = self.mirror_axis.get_value() - # mode = self.axis_location.get_value() - # - # if mode == "point": - # try: - # px, py = self.point_entry.get_value() - # except TypeError: - # self.app.inform.emit('[WARNING_NOTCL] %s' % _("'Point' coordinates missing. " - # "Using Origin (0, 0) as mirroring reference.")) - # px, py = (0, 0) - # - # else: - # selection_index_box = self.box_combo.currentIndex() - # model_index_box = self.app.collection.index(selection_index_box, 0, self.box_combo.rootModelIndex()) - # try: - # bb_obj = model_index_box.internalPointer().obj - # except Exception as e: - # self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no Box object loaded ...")) - # return - # - # xmin, ymin, xmax, ymax = bb_obj.bounds() - # px = 0.5 * (xmin + xmax) - # py = 0.5 * (ymin + ymax) - # - # fcobj.mirror(axis, [px, py]) - # self.app.object_changed.emit(fcobj) - # fcobj.plot() - self.app.inform.emit('[success] Gerber %s %s...' % (str(fcobj.options['name']), _("was mirrored"))) + outname = fcobj.options['name'].rpartition('.')[0] + + mode = self.hole_size_radio.get_value() + + if mode == 'fixed': + tools = {"1": {"C": drill_dia}} + for apid, apid_value in fcobj.apertures.items(): + for geo_el in apid_value['geometry']: + if 'follow' in geo_el and isinstance(geo_el['follow'], Point): + drills.append({"point": geo_el['follow'], "tool": "1"}) + if 'solid_geometry' not in tools["1"]: + tools["1"]['solid_geometry'] = list() + else: + tools["1"]['solid_geometry'].append(geo_el['follow']) + else: + for apid, apid_value in fcobj.apertures.items(): + ap_type = apid_value['type'] + + dia = float(apid_value['size']) - (2 * ring_val) + if ap_type == 'R' or ap_type == 'O': + width = float(apid_value['width']) + height = float(apid_value['height']) + if width >= height: + dia = float(apid_value['height']) - (2 * ring_val) + else: + dia = float(apid_value['width']) - (2 * ring_val) + + tool_in_drills = False + for tool, tool_val in tools.items(): + if abs(float('%.*f' % (self.decimals, tool_val["C"])) - dia) < (10 ** -self.decimals): + tool_in_drills = tool + + if tool_in_drills is False: + if tools: + new_tool = max([int(t) for t in tools]) + 1 + tool_in_drills = str(new_tool) + else: + tool_in_drills = "1" + + for geo_el in apid_value['geometry']: + if 'follow' in geo_el and isinstance(geo_el['follow'], Point): + if tool_in_drills not in tools: + tools[tool_in_drills] = {"C": dia} + + drills.append({"point": geo_el['follow'], "tool": tool_in_drills}) + + if 'solid_geometry' not in tools[tool_in_drills]: + tools[tool_in_drills]['solid_geometry'] = list() + else: + tools[tool_in_drills]['solid_geometry'].append(geo_el['follow']) + + def obj_init(obj_inst, app_inst): + obj_inst.tools = tools + obj_inst.drills = drills + obj_inst.create_geometry() + obj_inst.source_file = self.app.export_excellon(obj_name=outname, local_use=obj_inst, filename=None, + use_thread=False) + + self.app.new_object("excellon", outname, obj_init) def on_hole_size_toggle(self, val): if val == "fixed": diff --git a/flatcamTools/ToolFilm.py b/flatcamTools/ToolFilm.py index ead110b1..a3542e29 100644 --- a/flatcamTools/ToolFilm.py +++ b/flatcamTools/ToolFilm.py @@ -752,7 +752,7 @@ class Film(FlatCAMTool): skew_factor_x=skew_factor_x, skew_factor_y=skew_factor_y, skew_reference=skew_reference, mirror=mirror, - pagesize=pagesize, orientation=orientation, color=color, opacity=1.0, + pagesize_val=pagesize, orientation_val=orientation, color_val=color, opacity_val=1.0, ftype=ftype ) @@ -1080,23 +1080,28 @@ class Film(FlatCAMTool): skew_factor_x=None, skew_factor_y=None, skew_reference='center', mirror=None, orientation_val='p', pagesize_val='A4', color_val='black', opacity_val=1.0, use_thread=True, ftype='svg'): + """ Exports a Geometry Object to an SVG file in positive black. - :param obj_name: the name of the FlatCAM object to be saved as SVG - :param box_name: the name of the FlatCAM object to be used as delimitation of the content to be saved - :param filename: Path to the SVG file to save to. + :param obj_name: the name of the FlatCAM object to be saved + :param box_name: the name of the FlatCAM object to be used as delimitation of the content to be saved + :param filename: Path to the file to save to. :param scale_stroke_factor: factor by which to change/scale the thickness of the features - :param scale_factor_x: factor to scale the svg geometry on the X axis - :param scale_factor_y: factor to scale the svg geometry on the Y axis - :param skew_factor_x: factor to skew the svg geometry on the X axis - :param skew_factor_y: factor to skew the svg geometry on the Y axis - :param skew_reference: reference to use for skew. Can be 'bottomleft', 'bottomright', 'topleft', 'topright' and - those are the 4 points of the bounding box of the geometry to be skewed. - :param mirror: can be 'x' or 'y' or 'both'. Axis on which to mirror the svg geometry + :param scale_factor_x: factor to scale the geometry on the X axis + :param scale_factor_y: factor to scale the geometry on the Y axis + :param skew_factor_x: factor to skew the geometry on the X axis + :param skew_factor_y: factor to skew the geometry on the Y axis + :param skew_reference: reference to use for skew. Can be 'bottomleft', 'bottomright', 'topleft', + 'topright' and those are the 4 points of the bounding box of the geometry to be skewed. + :param mirror: can be 'x' or 'y' or 'both'. Axis on which to mirror the svg geometry + :param orientation_val: + :param pagesize_val: + :param color_val: + :param opacity_val: + :param use_thread: if to be run in a separate thread; boolean + :param ftype: the type of file for saving the film: 'svg', 'png' or 'pdf' - :param use_thread: if to be run in a separate thread; boolean - :param ftype: the type of file for saving the film: 'svg', 'png' or 'pdf' :return: """ self.app.report_usage("export_positive()") From c28f08a3927859887b0c1530c7831334441dd494 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 11 Jan 2020 17:30:48 +0200 Subject: [PATCH 006/209] - fixed an issue in the Distance Tool - expanded the Extract Drills Tool to use a particular annular ring for each type of aperture flash (pad) --- FlatCAMApp.py | 11 +- README.md | 11 +- flatcamGUI/GUIElements.py | 4 + flatcamTools/ToolDistance.py | 23 +-- flatcamTools/ToolExtractDrills.py | 279 +++++++++++++++++++++++++++--- 5 files changed, 287 insertions(+), 41 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index d80e3ec5..05c2a850 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -957,7 +957,16 @@ class App(QtCore.QObject): # Drills Extraction Tool "tools_edrills_hole_type": 'fixed', "tools_edrills_hole_fixed_dia": 0.5, - "tools_edrills_hole_ring": 0.2, + "tools_edrills_circular_ring": 0.2, + "tools_edrills_oblong_ring": 0.2, + "tools_edrills_square_ring": 0.2, + "tools_edrills_rectangular_ring": 0.2, + "tools_edrills_others_ring": 0.2, + "tools_edrills_circular": True, + "tools_edrills_oblong": False, + "tools_edrills_square": False, + "tools_edrills_rectangular": False, + "tools_edrills_others": False, # Utilities # file associations diff --git a/README.md b/README.md index 3cc30ba8..19a3cfa8 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,12 @@ CAD program, and create G-Code for Isolation routing. ================================================= -10.02.2019 +11.01.2020 + +- fixed an issue in the Distance Tool +- expanded the Extract Drills Tool to use a particular annular ring for each type of aperture flash (pad) + +10.02.2020 - working on a new tool: Extract Drills Tool who will create a Excellon object out of the apertures of a Gerber object - finished the GUI in the Extract Drills Tool @@ -17,14 +22,14 @@ CAD program, and create G-Code for Isolation routing. - finished the Extract Drills Tool - fixed a small issue in the DoubleSided Tool -8.01.2019 +8.01.2020 - working in NCC Tool - selected rows in the Tools Tables will stay colored in blue after loosing focus instead of the default gray - in NCC Tool the Tool name in the Parameters section will be the Tool ID in the Tool Table - added an exception catch in case the plotcanvas init failed for the OpenGL graphic engine and warn user about what happened -7.01.2019 +7.01.2020 - solved issue #368 - when using the Enable/Disable prj context menu entries the plotted status is not updated in the object properties - updates in NCC Tool diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index f52aced9..05314ffe 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -2009,6 +2009,10 @@ class FCTable(QtWidgets.QTableWidget): palette = QtGui.QPalette() palette.setColor(QtGui.QPalette.Inactive, QtGui.QPalette.Highlight, palette.color(QtGui.QPalette.Active, QtGui.QPalette.Highlight)) + + # make inactive rows text some color as active; may be useful in the future + # palette.setColor(QtGui.QPalette.Inactive, QtGui.QPalette.HighlightedText, + # palette.color(QtGui.QPalette.Active, QtGui.QPalette.HighlightedText)) self.setPalette(palette) if drag_drop: diff --git a/flatcamTools/ToolDistance.py b/flatcamTools/ToolDistance.py index c1f9ed8b..1a5bc568 100644 --- a/flatcamTools/ToolDistance.py +++ b/flatcamTools/ToolDistance.py @@ -361,11 +361,12 @@ class Distance(FlatCAMTool): self.distance_x_entry.set_value('%.*f' % (self.decimals, abs(dx))) self.distance_y_entry.set_value('%.*f' % (self.decimals, abs(dy))) - try: - angle = math.degrees(math.atan(dy / dx)) - self.angle_entry.set_value('%.*f' % (self.decimals, angle)) - except Exception as e: - pass + if dx != 0.0: + try: + angle = math.degrees(math.atan(dy / dx)) + self.angle_entry.set_value('%.*f' % (self.decimals, angle)) + except Exception as e: + pass self.total_distance_entry.set_value('%.*f' % (self.decimals, abs(d))) self.app.ui.rel_position_label.setText( @@ -424,11 +425,13 @@ class Distance(FlatCAMTool): if len(self.points) == 1: self.utility_geometry(pos=pos) # and display the temporary angle - try: - angle = math.degrees(math.atan(dy / dx)) - self.angle_entry.set_value('%.*f' % (self.decimals, angle)) - except Exception as e: - pass + if dx != 0.0: + try: + angle = math.degrees(math.atan(dy / dx)) + self.angle_entry.set_value('%.*f' % (self.decimals, angle)) + except Exception as e: + log.debug("Distance.on_mouse_move_meas() -> update utility geometry -> %s" % str(e)) + pass except Exception as e: log.debug("Distance.on_mouse_move_meas() --> %s" % str(e)) diff --git a/flatcamTools/ToolExtractDrills.py b/flatcamTools/ToolExtractDrills.py index 5d2a604e..fa50ecc8 100644 --- a/flatcamTools/ToolExtractDrills.py +++ b/flatcamTools/ToolExtractDrills.py @@ -2,13 +2,9 @@ from PyQt5 import QtWidgets, QtCore from FlatCAMTool import FlatCAMTool -from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, EvalEntry, FCEntry -from FlatCAMObj import FlatCAMGerber, FlatCAMExcellon, FlatCAMGeometry - -from numpy import Inf +from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox from shapely.geometry import Point -from shapely import affinity import logging import gettext @@ -60,8 +56,62 @@ class ToolExtractDrills(FlatCAMTool): self.grb_label.setToolTip('%s.' % _("Gerber from which to extract drill holes")) # grid_lay.addRow("Bottom Layer:", self.object_combo) - grid_lay.addWidget(self.grb_label, 0, 0) - grid_lay.addWidget(self.gerber_object_combo, 1, 0) + grid_lay.addWidget(self.grb_label, 0, 0, 1, 2) + grid_lay.addWidget(self.gerber_object_combo, 1, 0, 1, 2) + + self.padt_label = QtWidgets.QLabel("%s:" % _("Processed Pads Type")) + self.padt_label.setToolTip( + _("The type of pads shape to be processed.\n" + "If the PCB has many SMD pads with rectangular pads,\n" + "disable the Rectangular aperture.") + ) + + grid_lay.addWidget(self.padt_label, 2, 0, 1, 2) + + # Circular Aperture Selection + self.circular_cb = FCCheckBox('%s' % _("Circular")) + self.circular_cb.setToolTip( + _("Create drills from circular pads.") + ) + + grid_lay.addWidget(self.circular_cb, 3, 0, 1, 2) + + # Oblong Aperture Selection + self.oblong_cb = FCCheckBox('%s' % _("Oblong")) + self.oblong_cb.setToolTip( + _("Create drills from oblong pads.") + ) + + grid_lay.addWidget(self.oblong_cb, 4, 0, 1, 2) + + # Square Aperture Selection + self.square_cb = FCCheckBox('%s' % _("Square")) + self.square_cb.setToolTip( + _("Create drills from square pads.") + ) + + grid_lay.addWidget(self.square_cb, 5, 0, 1, 2) + + # Rectangular Aperture Selection + self.rectangular_cb = FCCheckBox('%s' % _("Rectangular")) + self.rectangular_cb.setToolTip( + _("Create drills from rectangular pads.") + ) + + grid_lay.addWidget(self.rectangular_cb, 6, 0, 1, 2) + + # Others type of Apertures Selection + self.other_cb = FCCheckBox('%s' % _("Others")) + self.other_cb.setToolTip( + _("Create drills from other types of pad shape.") + ) + + grid_lay.addWidget(self.other_cb, 7, 0, 1, 2) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid_lay.addWidget(separator_line, 8, 0, 1, 2) # ## Grid Layout grid1 = QtWidgets.QGridLayout() @@ -102,22 +152,95 @@ class ToolExtractDrills(FlatCAMTool): grid1.addWidget(self.dia_label, 7, 0) grid1.addWidget(self.dia_entry, 7, 1) - # Annular Ring value - self.ring_entry = FCDoubleSpinner() - self.ring_entry.set_precision(self.decimals) - self.ring_entry.set_range(0.0000, 9999.9999) + self.ring_frame = QtWidgets.QFrame() + self.ring_frame.setContentsMargins(0, 0, 0, 0) + self.layout.addWidget(self.ring_frame) - self.ring_label = QtWidgets.QLabel('%s:' % _("Annular Ring")) + self.ring_box = QtWidgets.QVBoxLayout() + self.ring_box.setContentsMargins(0, 0, 0, 0) + self.ring_frame.setLayout(self.ring_box) + + # ## Grid Layout + grid2 = QtWidgets.QGridLayout() + grid2.setColumnStretch(0, 0) + grid2.setColumnStretch(1, 1) + self.ring_box.addLayout(grid2) + + # Annular Ring value + self.ring_label = QtWidgets.QLabel('%s' % _("Annular Ring")) self.ring_label.setToolTip( _("The size of annular ring.\n" "The copper sliver between the drill hole exterior\n" "and the margin of the copper pad.") ) + grid2.addWidget(self.ring_label, 0, 0, 1, 2) - grid1.addWidget(self.ring_label, 8, 0) - grid1.addWidget(self.ring_entry, 8, 1) + # Circular Annular Ring Value + self.circular_ring_label = QtWidgets.QLabel('%s:' % _("Circular")) + self.circular_ring_label.setToolTip( + _("The size of annular ring for circular pads.") + ) - # Calculate Bounding box + self.circular_ring_entry = FCDoubleSpinner() + self.circular_ring_entry.set_precision(self.decimals) + self.circular_ring_entry.set_range(0.0000, 9999.9999) + + grid2.addWidget(self.circular_ring_label, 1, 0) + grid2.addWidget(self.circular_ring_entry, 1, 1) + + # Oblong Annular Ring Value + self.oblong_ring_label = QtWidgets.QLabel('%s:' % _("Oblong")) + self.oblong_ring_label.setToolTip( + _("The size of annular ring for oblong pads.") + ) + + self.oblong_ring_entry = FCDoubleSpinner() + self.oblong_ring_entry.set_precision(self.decimals) + self.oblong_ring_entry.set_range(0.0000, 9999.9999) + + grid2.addWidget(self.oblong_ring_label, 2, 0) + grid2.addWidget(self.oblong_ring_entry, 2, 1) + + # Square Annular Ring Value + self.square_ring_label = QtWidgets.QLabel('%s:' % _("Square")) + self.square_ring_label.setToolTip( + _("The size of annular ring for square pads.") + ) + + self.square_ring_entry = FCDoubleSpinner() + self.square_ring_entry.set_precision(self.decimals) + self.square_ring_entry.set_range(0.0000, 9999.9999) + + grid2.addWidget(self.square_ring_label, 3, 0) + grid2.addWidget(self.square_ring_entry, 3, 1) + + # Rectangular Annular Ring Value + self.rectangular_ring_label = QtWidgets.QLabel('%s:' % _("Rectangular")) + self.rectangular_ring_label.setToolTip( + _("The size of annular ring for rectangular pads.") + ) + + self.rectangular_ring_entry = FCDoubleSpinner() + self.rectangular_ring_entry.set_precision(self.decimals) + self.rectangular_ring_entry.set_range(0.0000, 9999.9999) + + grid2.addWidget(self.rectangular_ring_label, 4, 0) + grid2.addWidget(self.rectangular_ring_entry, 4, 1) + + # Others Annular Ring Value + self.other_ring_label = QtWidgets.QLabel('%s:' % _("Others")) + self.other_ring_label.setToolTip( + _("The size of annular ring for other pads.") + ) + + self.other_ring_entry = FCDoubleSpinner() + self.other_ring_entry.set_precision(self.decimals) + self.other_ring_entry.set_range(0.0000, 9999.9999) + + grid2.addWidget(self.other_ring_label, 5, 0) + grid2.addWidget(self.other_ring_entry, 5, 1) + + # Extract drills from Gerber apertures flashes (pads) self.e_drills_button = QtWidgets.QPushButton(_("Extract Drills")) self.e_drills_button.setToolTip( _("Extract drills from a given Gerber file.") @@ -145,11 +268,42 @@ class ToolExtractDrills(FlatCAMTool): """) self.layout.addWidget(self.reset_button) + self.circular_ring_entry.setEnabled(False) + self.oblong_ring_entry.setEnabled(False) + self.square_ring_entry.setEnabled(False) + self.rectangular_ring_entry.setEnabled(False) + self.other_ring_entry.setEnabled(False) + # ## Signals self.hole_size_radio.activated_custom.connect(self.on_hole_size_toggle) self.e_drills_button.clicked.connect(self.on_extract_drills_click) self.reset_button.clicked.connect(self.set_tool_ui) + self.circular_cb.stateChanged.connect( + lambda state: + self.circular_ring_entry.setDisabled(False) if state else self.circular_ring_entry.setDisabled(True) + ) + + self.oblong_cb.stateChanged.connect( + lambda state: + self.oblong_ring_entry.setDisabled(False) if state else self.oblong_ring_entry.setDisabled(True) + ) + + self.square_cb.stateChanged.connect( + lambda state: + self.square_ring_entry.setDisabled(False) if state else self.square_ring_entry.setDisabled(True) + ) + + self.rectangular_cb.stateChanged.connect( + lambda state: + self.rectangular_ring_entry.setDisabled(False) if state else self.rectangular_ring_entry.setDisabled(True) + ) + + self.other_cb.stateChanged.connect( + lambda state: + self.other_ring_entry.setDisabled(False) if state else self.other_ring_entry.setDisabled(True) + ) + def install(self, icon=None, separator=None, **kwargs): FlatCAMTool.install(self, icon, separator, shortcut='ALT+I', **kwargs) @@ -186,12 +340,28 @@ class ToolExtractDrills(FlatCAMTool): self.hole_size_radio.set_value(self.app.defaults["tools_edrills_hole_type"]) self.dia_entry.set_value(float(self.app.defaults["tools_edrills_hole_fixed_dia"])) - self.ring_entry.set_value(float(self.app.defaults["tools_edrills_hole_ring"])) + + self.circular_ring_entry.set_value(float(self.app.defaults["tools_edrills_circular_ring"])) + self.oblong_ring_entry.set_value(float(self.app.defaults["tools_edrills_oblong_ring"])) + self.square_ring_entry.set_value(float(self.app.defaults["tools_edrills_square_ring"])) + self.rectangular_ring_entry.set_value(float(self.app.defaults["tools_edrills_rectangular_ring"])) + self.other_ring_entry.set_value(float(self.app.defaults["tools_edrills_others_ring"])) + + self.circular_cb.set_value(self.app.defaults["tools_edrills_circular"]) + self.oblong_cb.set_value(self.app.defaults["tools_edrills_oblong"]) + self.square_cb.set_value(self.app.defaults["tools_edrills_square"]) + self.rectangular_cb.set_value(self.app.defaults["tools_edrills_rectangular"]) + self.other_cb.set_value(self.app.defaults["tools_edrills_others"]) def on_extract_drills_click(self): drill_dia = self.dia_entry.get_value() - ring_val = self.ring_entry.get_value() + circ_r_val = self.circular_ring_entry.get_value() + oblong_r_val = self.oblong_ring_entry.get_value() + square_r_val = self.square_ring_entry.get_value() + rect_r_val = self.rectangular_ring_entry.get_value() + other_r_val = self.other_ring_entry.get_value() + drills = list() tools = dict() @@ -211,6 +381,29 @@ class ToolExtractDrills(FlatCAMTool): if mode == 'fixed': tools = {"1": {"C": drill_dia}} for apid, apid_value in fcobj.apertures.items(): + ap_type = apid_value['type'] + + if ap_type == 'C': + if self.circular_cb.get_value() is False: + continue + elif ap_type == 'O': + if self.oblong_cb.get_value() is False: + continue + elif ap_type == 'R': + width = float(apid_value['width']) + height = float(apid_value['height']) + + # if the height == width (float numbers so the reason for the following) + if round(width, self.decimals) == round(height, self.decimals): + if self.square_cb.get_value() is False: + continue + else: + if self.rectangular_cb.get_value() is False: + continue + else: + if self.other_cb.get_value() is False: + continue + for geo_el in apid_value['geometry']: if 'follow' in geo_el and isinstance(geo_el['follow'], Point): drills.append({"point": geo_el['follow'], "tool": "1"}) @@ -218,22 +411,46 @@ class ToolExtractDrills(FlatCAMTool): tools["1"]['solid_geometry'] = list() else: tools["1"]['solid_geometry'].append(geo_el['follow']) + + if 'solid_geometry' not in tools["1"] or not tools["1"]['solid_geometry']: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("No drills extracted. Try different parameters.")) + return else: + drills_found = set() for apid, apid_value in fcobj.apertures.items(): ap_type = apid_value['type'] - dia = float(apid_value['size']) - (2 * ring_val) - if ap_type == 'R' or ap_type == 'O': + dia = None + if ap_type == 'C': + if self.circular_cb.get_value(): + dia = float(apid_value['size']) - (2 * circ_r_val) + elif ap_type == 'R' or ap_type == 'O': width = float(apid_value['width']) height = float(apid_value['height']) - if width >= height: - dia = float(apid_value['height']) - (2 * ring_val) + + # if the height == width (float numbers so the reason for the following) + if abs(float('%.*f' % (self.decimals, width)) - float('%.*f' % (self.decimals, height))) < \ + (10 ** -self.decimals): + if self.square_cb.get_value(): + dia = float(apid_value['height']) - (2 * square_r_val) else: - dia = float(apid_value['width']) - (2 * ring_val) + if self.rectangular_cb.get_value(): + if width > height: + dia = float(apid_value['height']) - (2 * rect_r_val) + else: + dia = float(apid_value['width']) - (2 * rect_r_val) + else: + if self.other_cb.get_value(): + dia = float(apid_value['size']) - (2 * other_r_val) + + # if dia is None then none of the above applied so we skip th e following + if dia is None: + continue tool_in_drills = False for tool, tool_val in tools.items(): - if abs(float('%.*f' % (self.decimals, tool_val["C"])) - dia) < (10 ** -self.decimals): + if abs(float('%.*f' % (self.decimals, tool_val["C"])) - float('%.*f' % (self.decimals, dia))) < \ + (10 ** -self.decimals): tool_in_drills = tool if tool_in_drills is False: @@ -255,6 +472,16 @@ class ToolExtractDrills(FlatCAMTool): else: tools[tool_in_drills]['solid_geometry'].append(geo_el['follow']) + if tool_in_drills in tools: + if 'solid_geometry' not in tools[tool_in_drills] or not tools[tool_in_drills]['solid_geometry']: + drills_found.add(False) + else: + drills_found.add(True) + + if True not in drills_found: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("No drills extracted. Try different parameters.")) + return + def obj_init(obj_inst, app_inst): obj_inst.tools = tools obj_inst.drills = drills @@ -269,14 +496,12 @@ class ToolExtractDrills(FlatCAMTool): self.dia_entry.setDisabled(False) self.dia_label.setDisabled(False) - self.ring_label.setDisabled(True) - self.ring_entry.setDisabled(True) + self.ring_frame.setDisabled(True) else: self.dia_entry.setDisabled(True) self.dia_label.setDisabled(True) - self.ring_label.setDisabled(False) - self.ring_entry.setDisabled(False) + self.ring_frame.setDisabled(False) def reset_fields(self): self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) From f8c22ea32fb1c3dc8d3380afcb103d90ef63496c Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 12 Jan 2020 00:30:17 +0200 Subject: [PATCH 007/209] - Extract Drills Tool: fixed issue with oblong pads and with pads made from aperture macros - Extract Drills Tool: added controls in Edit -> Preferences --- FlatCAMApp.py | 14 +++ README.md | 2 + flatcamGUI/PreferencesUI.py | 190 +++++++++++++++++++++++++++++- flatcamTools/ToolExtractDrills.py | 27 ++++- 4 files changed, 228 insertions(+), 5 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 05c2a850..63504639 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -1592,6 +1592,20 @@ class App(QtCore.QObject): "tools_cal_toolchange_xy": self.ui.tools2_defaults_form.tools2_cal_group.toolchange_xy_entry, "tools_cal_sec_point": self.ui.tools2_defaults_form.tools2_cal_group.second_point_radio, + # Extract Drills Tool + "tools_edrills_hole_type": self.ui.tools2_defaults_form.tools2_edrills_group.hole_size_radio, + "tools_edrills_hole_fixed_dia": self.ui.tools2_defaults_form.tools2_edrills_group.dia_entry, + "tools_edrills_circular_ring": self.ui.tools2_defaults_form.tools2_edrills_group.circular_ring_entry, + "tools_edrills_oblong_ring": self.ui.tools2_defaults_form.tools2_edrills_group.oblong_ring_entry, + "tools_edrills_square_ring": self.ui.tools2_defaults_form.tools2_edrills_group.square_ring_entry, + "tools_edrills_rectangular_ring": self.ui.tools2_defaults_form.tools2_edrills_group.rectangular_ring_entry, + "tools_edrills_others_ring": self.ui.tools2_defaults_form.tools2_edrills_group.other_ring_entry, + "tools_edrills_circular": self.ui.tools2_defaults_form.tools2_edrills_group.circular_cb, + "tools_edrills_oblong": self.ui.tools2_defaults_form.tools2_edrills_group.oblong_cb, + "tools_edrills_square": self.ui.tools2_defaults_form.tools2_edrills_group.square_cb, + "tools_edrills_rectangular": self.ui.tools2_defaults_form.tools2_edrills_group.rectangular_cb, + "tools_edrills_others": self.ui.tools2_defaults_form.tools2_edrills_group.other_cb, + # Utilities # File associations "fa_excellon": self.ui.util_defaults_form.fa_excellon_group.exc_list_text, diff --git a/README.md b/README.md index 19a3cfa8..afbc0e06 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ CAD program, and create G-Code for Isolation routing. - fixed an issue in the Distance Tool - expanded the Extract Drills Tool to use a particular annular ring for each type of aperture flash (pad) +- Extract Drills Tool: fixed issue with oblong pads and with pads made from aperture macros +- Extract Drills Tool: added controls in Edit -> Preferences 10.02.2020 diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index b84a514b..a073b534 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -242,19 +242,23 @@ class Tools2PreferencesUI(QtWidgets.QWidget): self.tools2_cal_group = Tools2CalPrefGroupUI(decimals=self.decimals) self.tools2_cal_group.setMinimumWidth(220) + self.tools2_edrills_group = Tools2EDrillsPrefGroupUI(decimals=self.decimals) + self.tools2_edrills_group.setMinimumWidth(220) + self.vlay = QtWidgets.QVBoxLayout() self.vlay.addWidget(self.tools2_checkrules_group) self.vlay.addWidget(self.tools2_optimal_group) self.vlay1 = QtWidgets.QVBoxLayout() self.vlay1.addWidget(self.tools2_qrcode_group) + self.vlay1.addWidget(self.tools2_fiducials_group) self.vlay2 = QtWidgets.QVBoxLayout() self.vlay2.addWidget(self.tools2_cfill_group) self.vlay3 = QtWidgets.QVBoxLayout() - self.vlay3.addWidget(self.tools2_fiducials_group) self.vlay3.addWidget(self.tools2_cal_group) + self.vlay3.addWidget(self.tools2_edrills_group) self.layout.addLayout(self.vlay) self.layout.addLayout(self.vlay1) @@ -7618,6 +7622,190 @@ class Tools2CalPrefGroupUI(OptionsGroupUI): self.layout.addStretch() +class Tools2EDrillsPrefGroupUI(OptionsGroupUI): + def __init__(self, decimals=4, parent=None): + + super(Tools2EDrillsPrefGroupUI, self).__init__(self) + + self.setTitle(str(_("Extract Drills Options"))) + self.decimals = decimals + + # ## Grid Layout + grid_lay = QtWidgets.QGridLayout() + self.layout.addLayout(grid_lay) + grid_lay.setColumnStretch(0, 0) + grid_lay.setColumnStretch(1, 1) + + self.param_label = QtWidgets.QLabel('%s:' % _('Parameters')) + self.param_label.setToolTip( + _("Parameters used for this tool.") + ) + grid_lay.addWidget(self.param_label, 0, 0, 1, 2) + + self.padt_label = QtWidgets.QLabel("%s:" % _("Processed Pads Type")) + self.padt_label.setToolTip( + _("The type of pads shape to be processed.\n" + "If the PCB has many SMD pads with rectangular pads,\n" + "disable the Rectangular aperture.") + ) + + grid_lay.addWidget(self.padt_label, 2, 0, 1, 2) + + # Circular Aperture Selection + self.circular_cb = FCCheckBox('%s' % _("Circular")) + self.circular_cb.setToolTip( + _("Create drills from circular pads.") + ) + + grid_lay.addWidget(self.circular_cb, 3, 0, 1, 2) + + # Oblong Aperture Selection + self.oblong_cb = FCCheckBox('%s' % _("Oblong")) + self.oblong_cb.setToolTip( + _("Create drills from oblong pads.") + ) + + grid_lay.addWidget(self.oblong_cb, 4, 0, 1, 2) + + # Square Aperture Selection + self.square_cb = FCCheckBox('%s' % _("Square")) + self.square_cb.setToolTip( + _("Create drills from square pads.") + ) + + grid_lay.addWidget(self.square_cb, 5, 0, 1, 2) + + # Rectangular Aperture Selection + self.rectangular_cb = FCCheckBox('%s' % _("Rectangular")) + self.rectangular_cb.setToolTip( + _("Create drills from rectangular pads.") + ) + + grid_lay.addWidget(self.rectangular_cb, 6, 0, 1, 2) + + # Others type of Apertures Selection + self.other_cb = FCCheckBox('%s' % _("Others")) + self.other_cb.setToolTip( + _("Create drills from other types of pad shape.") + ) + + grid_lay.addWidget(self.other_cb, 7, 0, 1, 2) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid_lay.addWidget(separator_line, 8, 0, 1, 2) + + # ## Axis + self.hole_size_radio = RadioSet([{'label': _("Fixed"), 'value': 'fixed'}, + {'label': _("Proportional"), 'value': 'prop'}]) + self.hole_size_label = QtWidgets.QLabel('%s:' % _("Hole Size")) + self.hole_size_label.setToolTip( + _("The type of hole size. Can be:\n" + "- Fixed -> all holes will have a set size\n" + "- Proprotional -> each hole will havea a variable size\n" + "such as to preserve a set annular ring")) + + grid_lay.addWidget(self.hole_size_label, 9, 0) + grid_lay.addWidget(self.hole_size_radio, 9, 1) + + # grid_lay1.addWidget(QtWidgets.QLabel('')) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid_lay.addWidget(separator_line, 10, 0, 1, 2) + + # Diameter value + self.dia_entry = FCDoubleSpinner() + self.dia_entry.set_precision(self.decimals) + self.dia_entry.set_range(0.0000, 9999.9999) + + self.dia_label = QtWidgets.QLabel('%s:' % _("Diameter")) + self.dia_label.setToolTip( + _("Fixed hole diameter.") + ) + + grid_lay.addWidget(self.dia_label, 11, 0) + grid_lay.addWidget(self.dia_entry, 11, 1) + + # Annular Ring value + self.ring_label = QtWidgets.QLabel('%s' % _("Annular Ring")) + self.ring_label.setToolTip( + _("The size of annular ring.\n" + "The copper sliver between the drill hole exterior\n" + "and the margin of the copper pad.") + ) + grid_lay.addWidget(self.ring_label, 12, 0, 1, 2) + + # Circular Annular Ring Value + self.circular_ring_label = QtWidgets.QLabel('%s:' % _("Circular")) + self.circular_ring_label.setToolTip( + _("The size of annular ring for circular pads.") + ) + + self.circular_ring_entry = FCDoubleSpinner() + self.circular_ring_entry.set_precision(self.decimals) + self.circular_ring_entry.set_range(0.0000, 9999.9999) + + grid_lay.addWidget(self.circular_ring_label, 13, 0) + grid_lay.addWidget(self.circular_ring_entry, 13, 1) + + # Oblong Annular Ring Value + self.oblong_ring_label = QtWidgets.QLabel('%s:' % _("Oblong")) + self.oblong_ring_label.setToolTip( + _("The size of annular ring for oblong pads.") + ) + + self.oblong_ring_entry = FCDoubleSpinner() + self.oblong_ring_entry.set_precision(self.decimals) + self.oblong_ring_entry.set_range(0.0000, 9999.9999) + + grid_lay.addWidget(self.oblong_ring_label, 14, 0) + grid_lay.addWidget(self.oblong_ring_entry, 14, 1) + + # Square Annular Ring Value + self.square_ring_label = QtWidgets.QLabel('%s:' % _("Square")) + self.square_ring_label.setToolTip( + _("The size of annular ring for square pads.") + ) + + self.square_ring_entry = FCDoubleSpinner() + self.square_ring_entry.set_precision(self.decimals) + self.square_ring_entry.set_range(0.0000, 9999.9999) + + grid_lay.addWidget(self.square_ring_label, 15, 0) + grid_lay.addWidget(self.square_ring_entry, 15, 1) + + # Rectangular Annular Ring Value + self.rectangular_ring_label = QtWidgets.QLabel('%s:' % _("Rectangular")) + self.rectangular_ring_label.setToolTip( + _("The size of annular ring for rectangular pads.") + ) + + self.rectangular_ring_entry = FCDoubleSpinner() + self.rectangular_ring_entry.set_precision(self.decimals) + self.rectangular_ring_entry.set_range(0.0000, 9999.9999) + + grid_lay.addWidget(self.rectangular_ring_label, 16, 0) + grid_lay.addWidget(self.rectangular_ring_entry, 16, 1) + + # Others Annular Ring Value + self.other_ring_label = QtWidgets.QLabel('%s:' % _("Others")) + self.other_ring_label.setToolTip( + _("The size of annular ring for other pads.") + ) + + self.other_ring_entry = FCDoubleSpinner() + self.other_ring_entry.set_precision(self.decimals) + self.other_ring_entry.set_range(0.0000, 9999.9999) + + grid_lay.addWidget(self.other_ring_label, 17, 0) + grid_lay.addWidget(self.other_ring_entry, 17, 1) + + self.layout.addStretch() + + class FAExcPrefGroupUI(OptionsGroupUI): def __init__(self, decimals=4, parent=None): # OptionsGroupUI.__init__(self, "Excellon File associations Preferences", parent=None) diff --git a/flatcamTools/ToolExtractDrills.py b/flatcamTools/ToolExtractDrills.py index fa50ecc8..c0300549 100644 --- a/flatcamTools/ToolExtractDrills.py +++ b/flatcamTools/ToolExtractDrills.py @@ -59,7 +59,7 @@ class ToolExtractDrills(FlatCAMTool): grid_lay.addWidget(self.grb_label, 0, 0, 1, 2) grid_lay.addWidget(self.gerber_object_combo, 1, 0, 1, 2) - self.padt_label = QtWidgets.QLabel("%s:" % _("Processed Pads Type")) + self.padt_label = QtWidgets.QLabel("%s" % _("Processed Pads Type")) self.padt_label.setToolTip( _("The type of pads shape to be processed.\n" "If the PCB has many SMD pads with rectangular pads,\n" @@ -424,7 +424,15 @@ class ToolExtractDrills(FlatCAMTool): if ap_type == 'C': if self.circular_cb.get_value(): dia = float(apid_value['size']) - (2 * circ_r_val) - elif ap_type == 'R' or ap_type == 'O': + elif ap_type == 'O': + width = float(apid_value['width']) + height = float(apid_value['height']) + if self.oblong_cb.get_value(): + if width > height: + dia = float(apid_value['height']) - (2 * rect_r_val) + else: + dia = float(apid_value['width']) - (2 * rect_r_val) + elif ap_type == 'R': width = float(apid_value['width']) height = float(apid_value['height']) @@ -441,9 +449,20 @@ class ToolExtractDrills(FlatCAMTool): dia = float(apid_value['width']) - (2 * rect_r_val) else: if self.other_cb.get_value(): - dia = float(apid_value['size']) - (2 * other_r_val) + try: + dia = float(apid_value['size']) - (2 * other_r_val) + except KeyError: + if ap_type == 'AM': + pol = apid_value['geometry'][0]['solid'] + x0, y0, x1, y1 = pol.bounds + dx = x1 - x0 + dy = y1 - y0 + if dx <= dy: + dia = dx - (2 * other_r_val) + else: + dia = dy - (2 * other_r_val) - # if dia is None then none of the above applied so we skip th e following + # if dia is None then none of the above applied so we skip the following if dia is None: continue From a9b93cafa17f5cfebb65d9d1e0b5aff2f41d67c1 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 12 Jan 2020 03:28:05 +0200 Subject: [PATCH 008/209] - improved the circle approximation resolution --- FlatCAMObj.py | 11 ++++------- README.md | 6 +++++- camlib.py | 31 +++++++++++++++---------------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 712d766a..1ba88825 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -1307,7 +1307,6 @@ class FlatCAMGerber(FlatCAMObj, Gerber): else: iso_name = outname - # TODO: This is ugly. Create way to pass data into init function. def iso_init(geo_obj, app_obj): # Propagate options geo_obj.options["cnctooldia"] = str(self.options["isotooldia"]) @@ -1318,8 +1317,8 @@ class FlatCAMGerber(FlatCAMObj, Gerber): iso_offset = dia * ((2 * i + 1) / 2.0) - (i * overlap * dia) # if milling type is climb then the move is counter-clockwise around features - mill_t = 1 if milling_type == 'cl' else 0 - geom = self.generate_envelope(iso_offset, mill_t, geometry=work_geo, env_iso_type=iso_t, + mill_dir = 1 if milling_type == 'cl' else 0 + geom = self.generate_envelope(iso_offset, mill_dir, geometry=work_geo, env_iso_type=iso_t, follow=follow, nr_passes=i) if geom == 'fail': @@ -1438,7 +1437,6 @@ class FlatCAMGerber(FlatCAMObj, Gerber): else: iso_name = outname - # TODO: This is ugly. Create way to pass data into init function. def iso_init(geo_obj, app_obj): # Propagate options geo_obj.options["cnctooldia"] = str(self.options["isotooldia"]) @@ -1448,9 +1446,8 @@ class FlatCAMGerber(FlatCAMObj, Gerber): geo_obj.tool_type = 'C1' # if milling type is climb then the move is counter-clockwise around features - mill_t = 1 if milling_type == 'cl' else 0 - mill_t = 1 if milling_type == 'cl' else 0 - geom = self.generate_envelope(offset, mill_t, geometry=work_geo, env_iso_type=iso_t, + mill_dir = 1 if milling_type == 'cl' else 0 + geom = self.generate_envelope(offset, mill_dir, geometry=work_geo, env_iso_type=iso_t, follow=follow, nr_passes=i) diff --git a/README.md b/README.md index afbc0e06..39de865e 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +12.01.2020 + +- improved the circle approximation resolution + 11.01.2020 - fixed an issue in the Distance Tool @@ -36,7 +40,7 @@ CAD program, and create G-Code for Isolation routing. - solved issue #368 - when using the Enable/Disable prj context menu entries the plotted status is not updated in the object properties - updates in NCC Tool -6.01.2019 +6.01.2020 - working on new NCC Tool diff --git a/camlib.py b/camlib.py index 1e58a423..6bbaf9ef 100644 --- a/camlib.py +++ b/camlib.py @@ -458,8 +458,8 @@ class Geometry(object): """ defaults = { - "units": 'in', - "geo_steps_per_circle": 64 + "units": 'mm', + # "geo_steps_per_circle": 128 } def __init__(self, geo_steps_per_circle=None): @@ -529,12 +529,12 @@ class Geometry(object): if type(self.solid_geometry) is list: self.solid_geometry.append(Point(origin).buffer( - radius, int(int(self.geo_steps_per_circle) / 4))) + radius, int(self.geo_steps_per_circle))) return try: self.solid_geometry = self.solid_geometry.union(Point(origin).buffer( - radius, int(int(self.geo_steps_per_circle) / 4))) + radius, int(self.geo_steps_per_circle))) except Exception as e: log.error("Failed to run union on polygons. %s" % str(e)) return @@ -944,7 +944,7 @@ class Geometry(object): geo_iso.append(pol) else: corner_type = 1 if corner is None else corner - geo_iso.append(pol.buffer(offset, int(int(self.geo_steps_per_circle) / 4), join_style=corner_type)) + geo_iso.append(pol.buffer(offset, int(self.geo_steps_per_circle), join_style=corner_type)) pol_nr += 1 disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100])) @@ -959,8 +959,7 @@ class Geometry(object): geo_iso.append(working_geo) else: corner_type = 1 if corner is None else corner - geo_iso.append(working_geo.buffer(offset, int(int(self.geo_steps_per_circle) / 4), - join_style=corner_type)) + geo_iso.append(working_geo.buffer(offset, int(self.geo_steps_per_circle), join_style=corner_type)) self.app.proc_container.update_view_text(' %s' % _("Buffering")) geo_iso = unary_union(geo_iso) @@ -1225,7 +1224,7 @@ class Geometry(object): # Can only result in a Polygon or MultiPolygon # NOTE: The resulting polygon can be "empty". - current = polygon.buffer((-tooldia / 1.999999), int(int(steps_per_circle) / 4)) + current = polygon.buffer((-tooldia / 1.999999), int(steps_per_circle)) if current.area == 0: # Otherwise, trying to to insert current.exterior == None # into the FlatCAMStorage will fail. @@ -1254,7 +1253,7 @@ class Geometry(object): QtWidgets.QApplication.processEvents() # Can only result in a Polygon or MultiPolygon - current = current.buffer(-tooldia * (1 - overlap), int(int(steps_per_circle) / 4)) + current = current.buffer(-tooldia * (1 - overlap), int(steps_per_circle)) if current.area > 0: # current can be a MultiPolygon @@ -1372,11 +1371,12 @@ class Geometry(object): # Clean inside edges (contours) of the original polygon if contour: - outer_edges = [x.exterior for x in autolist( - polygon_to_clear.buffer(-tooldia / 2, int(steps_per_circle / 4)))] + outer_edges = [ + x.exterior for x in autolist(polygon_to_clear.buffer(-tooldia / 2, int(steps_per_circle))) + ] inner_edges = [] # Over resulting polygons - for x in autolist(polygon_to_clear.buffer(-tooldia / 2, int(steps_per_circle / 4))): + for x in autolist(polygon_to_clear.buffer(-tooldia / 2, int(steps_per_circle))): for y in x.interiors: # Over interiors of each polygon inner_edges.append(y) # geoms += outer_edges + inner_edges @@ -1626,7 +1626,7 @@ class Geometry(object): # Straight line from current_pt to pt. # Is the toolpath inside the geometry? walk_path = LineString([current_pt, pt]) - walk_cut = walk_path.buffer(tooldia / 2, int(steps_per_circle / 4)) + walk_cut = walk_path.buffer(tooldia / 2, int(steps_per_circle)) if walk_cut.within(boundary) and walk_path.length < max_walk: # log.debug("Walk to path #%d is inside. Joining." % path_count) @@ -4213,7 +4213,7 @@ class CNCjob(Geometry): radius = np.sqrt(gobj['I']**2 + gobj['J']**2) start = np.arctan2(-gobj['J'], -gobj['I']) stop = np.arctan2(-center[1] + y, -center[0] + x) - path += arc(center, radius, start, stop, arcdir[current['G']], int(self.steps_per_circle / 4)) + path += arc(center, radius, start, stop, arcdir[current['G']], int(self.steps_per_circle)) current['X'] = x current['Y'] = y @@ -4362,8 +4362,7 @@ class CNCjob(Geometry): visible=visible, layer=1) else: # For Incremental coordinates type G91 - self.app.inform.emit('[ERROR_NOTCL] %s' % - _('G91 coordinates not implemented ...')) + self.app.inform.emit('[ERROR_NOTCL] %s' % _('G91 coordinates not implemented ...')) for geo in gcode_parsed: if geo['kind'][0] == 'T': current_position = geo['geom'].coords[0] From c9111dac9b861d0144e52f45c58d5dc9aef05991 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 12 Jan 2020 04:05:13 +0200 Subject: [PATCH 009/209] - fixed an issue in Gerber parser with detecting old kind of units --- README.md | 1 + camlib.py | 8 ++++---- flatcamParsers/ParseGerber.py | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 39de865e..57224d90 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 12.01.2020 - improved the circle approximation resolution +- fixed an issue in Gerber parser with detecting old kind of units 11.01.2020 diff --git a/camlib.py b/camlib.py index 6bbaf9ef..063478b1 100644 --- a/camlib.py +++ b/camlib.py @@ -528,13 +528,13 @@ class Geometry(object): self.solid_geometry = [] if type(self.solid_geometry) is list: - self.solid_geometry.append(Point(origin).buffer( - radius, int(self.geo_steps_per_circle))) + self.solid_geometry.append(Point(origin).buffer(radius, int(self.geo_steps_per_circle))) return try: - self.solid_geometry = self.solid_geometry.union(Point(origin).buffer( - radius, int(self.geo_steps_per_circle))) + self.solid_geometry = self.solid_geometry.union( + Point(origin).buffer(radius, int(self.geo_steps_per_circle)) + ) except Exception as e: log.error("Failed to run union on polygons. %s" % str(e)) return diff --git a/flatcamParsers/ParseGerber.py b/flatcamParsers/ParseGerber.py index 6f79c31a..7fbfce1f 100644 --- a/flatcamParsers/ParseGerber.py +++ b/flatcamParsers/ParseGerber.py @@ -595,6 +595,7 @@ class Gerber(Geometry): match = self.units_re.search(gline) if match: obs_gerber_units = {'0': 'IN', '1': 'MM'}[match.group(1)] + self.units = obs_gerber_units log.warning("Gerber obsolete units found = %s" % obs_gerber_units) # Changed for issue #80 # self.convert_units({'0': 'IN', '1': 'MM'}[match.group(1)]) From 5b3f318e567555f258bb7fab5e48b36dcd3fa854 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 12 Jan 2020 17:26:48 +0200 Subject: [PATCH 010/209] - if CTRL key is pressed during app startup the app will start in the Legacy(2D) graphic engine compatibility mode --- FlatCAMApp.py | 9 ++++++--- README.md | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 63504639..2b25ad8f 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -12025,7 +12025,12 @@ class App(QtCore.QObject): else: plot_container = self.ui.right_layout - if self.is_legacy is False: + modifier = QtWidgets.QApplication.queryKeyboardModifiers() + if self.is_legacy is True or modifier == QtCore.Qt.ControlModifier: + self.is_legacy = True + self.defaults["global_graphic_engine"] = "2D" + self.plotcanvas = PlotCanvasLegacy(plot_container, self) + else: try: self.plotcanvas = PlotCanvas(plot_container, self) except Exception as er: @@ -12038,8 +12043,6 @@ class App(QtCore.QObject): msg += msg_txt self.inform.emit(msg) return 'fail' - else: - self.plotcanvas = PlotCanvasLegacy(plot_container, self) # So it can receive key presses self.plotcanvas.native.setFocus() diff --git a/README.md b/README.md index 57224d90..786cbb6b 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ CAD program, and create G-Code for Isolation routing. - improved the circle approximation resolution - fixed an issue in Gerber parser with detecting old kind of units +- if CTRL key is pressed during app startup the app will start in the Legacy(2D) graphic engine compatibility mode 11.01.2020 From 02cfd9671566718e4d799d9d025d0a7fd2afaa88 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 13 Jan 2020 16:06:29 +0200 Subject: [PATCH 011/209] - fixed a small GUI issue in Excellon UI when Basic mode is active --- FlatCAMApp.py | 4 ++-- FlatCAMObj.py | 5 ++++- README.md | 4 ++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 2b25ad8f..43e94c63 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -524,8 +524,8 @@ class App(QtCore.QObject): "global_cursor_type": "small", "global_cursor_size": 20, "global_cursor_width": 2, - "global_cursor_color": '#000000', - "global_cursor_color_enabled": False, + "global_cursor_color": '#FF0000', + "global_cursor_color_enabled": True, # Gerber General "gerber_plot": True, diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 1ba88825..6b98f6f2 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -2638,7 +2638,10 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): horizontal_header.setDefaultSectionSize(70) horizontal_header.setSectionResizeMode(0, QtWidgets.QHeaderView.Fixed) horizontal_header.resizeSection(0, 20) - horizontal_header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents) + if self.app.defaults["global_app_level"] == 'b': + horizontal_header.setSectionResizeMode(1, QtWidgets.QHeaderView.Stretch) + else: + horizontal_header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents) horizontal_header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents) horizontal_header.setSectionResizeMode(3, QtWidgets.QHeaderView.ResizeToContents) horizontal_header.setSectionResizeMode(4, QtWidgets.QHeaderView.Stretch) diff --git a/README.md b/README.md index 786cbb6b..a30058fc 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +13.01.2020 + +- fixed a small GUI issue in Excellon UI when Basic mode is active + 12.01.2020 - improved the circle approximation resolution From 41277d78ce99bf742862a3337c27ed61da139f6a Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 13 Jan 2020 21:43:25 +0200 Subject: [PATCH 012/209] - started the add of a new Tool: Align Objects Tool which will align (sync) objects of Gerber or Excellon type --- FlatCAMApp.py | 4 + README.md | 1 + flatcamTools/ToolAlignObjects.py | 423 ++++++++++++++++++++++++++++++ flatcamTools/ToolExtractDrills.py | 6 + flatcamTools/__init__.py | 4 +- share/align16.png | Bin 0 -> 457 bytes share/align32.png | Bin 0 -> 539 bytes 7 files changed, 436 insertions(+), 2 deletions(-) create mode 100644 flatcamTools/ToolAlignObjects.py create mode 100644 share/align16.png create mode 100644 share/align32.png diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 43e94c63..ca691c00 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -2493,6 +2493,7 @@ class App(QtCore.QObject): self.copper_thieving_tool = None self.fiducial_tool = None self.edrills_tool = None + self.align_objects_tool = None # always install tools only after the shell is initialized because the self.inform.emit() depends on shell try: @@ -3065,6 +3066,9 @@ class App(QtCore.QObject): before=self.dblsidedtool.menuAction, separator=False) + self.align_objects_tool = AlignObjects(self) + self.align_objects_tool.install(icon=QtGui.QIcon(self.resource_location + '/align16.png'), separator=False) + self.edrills_tool = ToolExtractDrills(self) self.edrills_tool.install(icon=QtGui.QIcon(self.resource_location + '/drill16.png'), separator=True) diff --git a/README.md b/README.md index a30058fc..414cffad 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 13.01.2020 - fixed a small GUI issue in Excellon UI when Basic mode is active +- started the add of a new Tool: Align Objects Tool which will align (sync) objects of Gerber or Excellon type 12.01.2020 diff --git a/flatcamTools/ToolAlignObjects.py b/flatcamTools/ToolAlignObjects.py new file mode 100644 index 00000000..e787d0c6 --- /dev/null +++ b/flatcamTools/ToolAlignObjects.py @@ -0,0 +1,423 @@ +# ########################################################## +# FlatCAM: 2D Post-processing for Manufacturing # +# File Author: Marius Adrian Stanciu (c) # +# Date: 1/13/2020 # +# MIT Licence # +# ########################################################## + +from PyQt5 import QtWidgets, QtGui, QtCore +from FlatCAMTool import FlatCAMTool + +from flatcamGUI.GUIElements import FCComboBox + +from copy import deepcopy + +import numpy as np + +from shapely.geometry import Point + +import gettext +import FlatCAMTranslation as fcTranslate +import builtins +import logging + +fcTranslate.apply_language('strings') +if '_' not in builtins.__dict__: + _ = gettext.gettext + +log = logging.getLogger('base') + + +class AlignObjects(FlatCAMTool): + + toolName = _("Align Objects") + + def __init__(self, app): + FlatCAMTool.__init__(self, app) + + self.app = app + self.decimals = app.decimals + + self.canvas = self.app.plotcanvas + + # ## Title + title_label = QtWidgets.QLabel("%s" % self.toolName) + title_label.setStyleSheet(""" + QLabel + { + font-size: 16px; + font-weight: bold; + } + """) + self.layout.addWidget(title_label) + + # Form Layout + grid0 = QtWidgets.QGridLayout() + grid0.setColumnStretch(0, 0) + grid0.setColumnStretch(1, 1) + self.layout.addLayout(grid0) + + self.aligned_label = QtWidgets.QLabel('%s' % _("Selection of the aligned object")) + grid0.addWidget(self.aligned_label, 0, 0, 1, 2) + + # Type of object to be aligned + self.type_obj_combo = QtWidgets.QComboBox() + self.type_obj_combo.addItem("Gerber") + self.type_obj_combo.addItem("Excellon") + self.type_obj_combo.addItem("Geometry") + + self.type_obj_combo.setItemIcon(0, QtGui.QIcon(self.app.resource_location + "/flatcam_icon16.png")) + self.type_obj_combo.setItemIcon(1, QtGui.QIcon(self.app.resource_location + "/drill16.png")) + self.type_obj_combo.setItemIcon(2, QtGui.QIcon(self.app.resource_location + "/geometry16.png")) + + self.type_obj_combo_label = QtWidgets.QLabel('%s:' % _("Object Type")) + self.type_obj_combo_label.setToolTip( + _("Specify the type of object to be aligned.\n" + "It can be of type: Gerber, Excellon or Geometry.\n" + "The selection here decide the type of objects that will be\n" + "in the Object combobox.") + ) + grid0.addWidget(self.type_obj_combo_label, 2, 0) + grid0.addWidget(self.type_obj_combo, 2, 1) + + # Object to be aligned + self.object_combo = QtWidgets.QComboBox() + self.object_combo.setModel(self.app.collection) + self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) + self.object_combo.setCurrentIndex(1) + + self.object_label = QtWidgets.QLabel('%s:' % _("Object")) + self.object_label.setToolTip( + _("Object to be aligned.") + ) + + grid0.addWidget(self.object_label, 3, 0) + grid0.addWidget(self.object_combo, 3, 1) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(separator_line, 4, 0, 1, 2) + + self.aligned_label = QtWidgets.QLabel('%s' % _("Selection of the aligner object")) + self.aligned_label.setToolTip( + _("Object to which the other objects will be aligned to (moved).") + ) + grid0.addWidget(self.aligned_label, 6, 0, 1, 2) + + # Type of object to be aligned to = aligner + self.type_aligner_obj_combo = QtWidgets.QComboBox() + self.type_aligner_obj_combo.addItem("Gerber") + self.type_aligner_obj_combo.addItem("Excellon") + self.type_aligner_obj_combo.addItem("Geometry") + + self.type_aligner_obj_combo.setItemIcon(0, QtGui.QIcon(self.app.resource_location + "/flatcam_icon16.png")) + self.type_aligner_obj_combo.setItemIcon(1, QtGui.QIcon(self.app.resource_location + "/drill16.png")) + self.type_aligner_obj_combo.setItemIcon(2, QtGui.QIcon(self.app.resource_location + "/geometry16.png")) + + self.type_aligner_obj_combo_label = QtWidgets.QLabel('%s:' % _("Object Type")) + self.type_aligner_obj_combo_label.setToolTip( + _("Specify the type of object to be aligned to.\n" + "It can be of type: Gerber, Excellon or Geometry.\n" + "The selection here decide the type of objects that will be\n" + "in the Object combobox.") + ) + grid0.addWidget(self.type_aligner_obj_combo_label, 7, 0) + grid0.addWidget(self.type_aligner_obj_combo, 7, 1) + + # Object to be aligned to = aligner + self.aligner_object_combo = QtWidgets.QComboBox() + self.aligner_object_combo.setModel(self.app.collection) + self.aligner_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) + self.aligner_object_combo.setCurrentIndex(1) + + self.aligner_object_label = QtWidgets.QLabel('%s:' % _("Object")) + self.aligner_object_label.setToolTip( + _("Object to be aligned to. Aligner.") + ) + + grid0.addWidget(self.aligner_object_label, 8, 0) + grid0.addWidget(self.aligner_object_combo, 8, 1) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(separator_line, 9, 0, 1, 2) + + # Buttons + self.align_object_button = QtWidgets.QPushButton(_("Align Object")) + self.align_object_button.setToolTip( + _("Align the specified object to the aligner object.\n" + "If only one point is used then it assumes translation.\n" + "If tho points are used it assume translation and rotation.") + ) + self.align_object_button.setStyleSheet(""" + QPushButton + { + font-weight: bold; + } + """) + self.layout.addWidget(self.align_object_button) + + self.layout.addStretch() + + # ## Reset Tool + self.reset_button = QtWidgets.QPushButton(_("Reset Tool")) + self.reset_button.setToolTip( + _("Will reset the tool parameters.") + ) + self.reset_button.setStyleSheet(""" + QPushButton + { + font-weight: bold; + } + """) + self.layout.addWidget(self.reset_button) + + # Signals + self.align_object_button.clicked.connect(self.on_align) + self.type_obj_combo.currentIndexChanged.connect(self.on_type_obj_index_changed) + self.type_aligner_obj_combo.currentIndexChanged.connect(self.on_type_aligner_index_changed) + self.reset_button.clicked.connect(self.set_tool_ui) + + self.mr = None + + # if the mouse events are connected to a local method set this True + self.local_connected = False + + # store the status of the grid + self.grid_status_memory = None + + self.aligned_obj = None + self.aligner_obj = None + + # here store the alignment points for the aligned object + self.aligned_clicked_points = list() + + # here store the alignment points for the aligner object + self.aligner_clicked_points = list() + + # counter for the clicks + self.click_cnt = 0 + + def run(self, toggle=True): + self.app.report_usage("ToolAlignObjects()") + + if toggle: + # if the splitter is hidden, display it, else hide it but only if the current widget is the same + if self.app.ui.splitter.sizes()[0] == 0: + self.app.ui.splitter.setSizes([1, 1]) + else: + try: + if self.app.ui.tool_scroll_area.widget().objectName() == self.toolName: + # if tab is populated with the tool but it does not have the focus, focus on it + if not self.app.ui.notebook.currentWidget() is self.app.ui.tool_tab: + # focus on Tool Tab + self.app.ui.notebook.setCurrentWidget(self.app.ui.tool_tab) + else: + self.app.ui.splitter.setSizes([0, 1]) + except AttributeError: + pass + else: + if self.app.ui.splitter.sizes()[0] == 0: + self.app.ui.splitter.setSizes([1, 1]) + + FlatCAMTool.run(self) + self.set_tool_ui() + + self.app.ui.notebook.setTabText(2, _("Align Tool")) + + def install(self, icon=None, separator=None, **kwargs): + FlatCAMTool.install(self, icon, separator, shortcut='ALT+A', **kwargs) + + def set_tool_ui(self): + self.reset_fields() + + self.click_cnt = 0 + + if self.local_connected is True: + self.disconnect_cal_events() + + def on_type_obj_index_changed(self): + obj_type = self.type_obj_combo.currentIndex() + self.object_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) + self.object_combo.setCurrentIndex(0) + + def on_type_aligner_index_changed(self): + obj_type = self.type_aligner_obj_combo.currentIndex() + self.aligner_object_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) + self.aligner_object_combo.setCurrentIndex(0) + + def on_align(self): + + obj_sel_index = self.object_combo.currentIndex() + obj_model_index = self.app.collection.index(obj_sel_index, 0, self.object_combo.rootModelIndex()) + try: + self.aligned_obj = obj_model_index.internalPointer().obj + except AttributeError: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no aligned FlatCAM object selected...")) + return + + aligner_obj_sel_index = self.object_combo.currentIndex() + aligner_obj_model_index = self.app.collection.index( + aligner_obj_sel_index, 0, self.object_combo.rootModelIndex()) + + try: + self.aligner_obj = aligner_obj_model_index.internalPointer().obj + except AttributeError: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no aligner FlatCAM object selected...")) + return + + # disengage the grid snapping since it will be hard to find the drills or pads on grid + if self.app.ui.grid_snap_btn.isChecked(): + self.grid_status_memory = True + self.app.ui.grid_snap_btn.trigger() + else: + self.grid_status_memory = False + + self.mr = self.canvas.graph_event_connect('mouse_release', self.on_mouse_click_release) + + if self.app.is_legacy is False: + self.canvas.graph_event_disconnect('mouse_release', self.app.on_mouse_click_release_over_plot) + else: + self.canvas.graph_event_disconnect(self.app.mr) + + self.local_connected = True + + self.app.inform.emit(_("Get First alignment point on the aligned object.")) + + def on_mouse_click_release(self, event): + if self.app.is_legacy is False: + event_pos = event.pos + right_button = 2 + self.app.event_is_dragging = self.app.event_is_dragging + else: + event_pos = (event.xdata, event.ydata) + right_button = 3 + self.app.event_is_dragging = self.app.ui.popMenu.mouse_is_panning + + pos_canvas = self.canvas.translate_coords(event_pos) + + if event.button == 1: + click_pt = Point([pos_canvas[0], pos_canvas[1]]) + + if self.app.selection_type is not None: + # delete previous selection shape + self.app.delete_selection_shape() + self.app.selection_type = None + else: + if self.target_obj.kind.lower() == 'excellon': + for tool, tool_dict in self.target_obj.tools.items(): + for geo in tool_dict['solid_geometry']: + if click_pt.within(geo): + center_pt = geo.centroid + self.click_points.append( + [ + float('%.*f' % (self.decimals, center_pt.x)), + float('%.*f' % (self.decimals, center_pt.y)) + ] + ) + self.check_points() + elif self.target_obj.kind.lower() == 'gerber': + for apid, apid_val in self.target_obj.apertures.items(): + for geo_el in apid_val['geometry']: + if 'solid' in geo_el: + if click_pt.within(geo_el['solid']): + if isinstance(geo_el['follow'], Point): + center_pt = geo_el['solid'].centroid + self.click_points.append( + [ + float('%.*f' % (self.decimals, center_pt.x)), + float('%.*f' % (self.decimals, center_pt.y)) + ] + ) + self.check_points() + + elif event.button == right_button and self.app.event_is_dragging is False: + if not len(self.click_points): + self.reset_calibration_points() + self.disconnect_cal_events() + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled by user request.")) + + def check_points(self): + if len(self.aligned_click_points) == 1: + self.app.inform.emit(_("Get Second alignment point on aligned object. " + "Or right click to get First alignment point on the aligner object.")) + + if len(self.aligned_click_points) == 2: + self.app.inform.emit(_("Get First alignment point on the aligner object.")) + + if len(self.aligner_click_points) == 1: + self.app.inform.emit(_("Get Second alignment point on the aligner object. Or right click to finish.")) + self.align_translate() + self.align_rotate() + self.disconnect_cal_events() + + def align_translate(self): + pass + + def align_rotate(self): + pass + + def execute(self): + aligned_name = self.object_combo.currentText() + + # Get source object. + try: + aligned_obj = self.app.collection.get_by_name(str(aligned_name)) + except Exception as e: + log.debug("AlignObjects.on_align() --> %s" % str(e)) + self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), aligned_name)) + return "Could not retrieve object: %s" % aligned_name + + if aligned_obj is None: + self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Object not found"), aligned_obj)) + return "Object not found: %s" % aligned_obj + + aligner_name = self.box_combo.currentText() + + try: + aligner_obj = self.app.collection.get_by_name(aligner_name) + except Exception as e: + log.debug("AlignObjects.on_align() --> %s" % str(e)) + self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), aligner_name)) + return "Could not retrieve object: %s" % aligner_name + + if aligner_obj is None: + self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), aligner_name)) + + def align_job(): + pass + + proc = self.app.proc_container.new(_("Working...")) + + def job_thread(app_obj): + try: + align_job() + app_obj.inform.emit('[success] %s' % _("Panel created successfully.")) + except Exception as ee: + proc.done() + log.debug(str(ee)) + return + proc.done() + + self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]}) + + def disconnect_cal_events(self): + # restore the Grid snapping if it was active before + if self.grid_status_memory is True: + self.app.ui.grid_snap_btn.trigger() + + self.app.mr = self.canvas.graph_event_connect('mouse_release', self.app.on_mouse_click_release_over_plot) + + if self.app.is_legacy is False: + self.canvas.graph_event_disconnect('mouse_release', self.on_mouse_click_release) + else: + self.canvas.graph_event_disconnect(self.mr) + + self.local_connected = False + self.click_cnt = 0 + + def reset_fields(self): + self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) + self.aligner_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) diff --git a/flatcamTools/ToolExtractDrills.py b/flatcamTools/ToolExtractDrills.py index c0300549..e0c72c95 100644 --- a/flatcamTools/ToolExtractDrills.py +++ b/flatcamTools/ToolExtractDrills.py @@ -1,3 +1,9 @@ +# ########################################################## +# FlatCAM: 2D Post-processing for Manufacturing # +# File Author: Marius Adrian Stanciu (c) # +# Date: 1/10/2020 # +# MIT Licence # +# ########################################################## from PyQt5 import QtWidgets, QtCore diff --git a/flatcamTools/__init__.py b/flatcamTools/__init__.py index be389e70..a593e6c4 100644 --- a/flatcamTools/__init__.py +++ b/flatcamTools/__init__.py @@ -5,6 +5,8 @@ from flatcamTools.ToolCalibration import ToolCalibration from flatcamTools.ToolCutOut import CutOut from flatcamTools.ToolDblSided import DblSidedTool +from flatcamTools.ToolExtractDrills import ToolExtractDrills +from flatcamTools.ToolAlignObjects import AlignObjects from flatcamTools.ToolFilm import Film @@ -31,8 +33,6 @@ from flatcamTools.ToolRulesCheck import RulesCheck from flatcamTools.ToolCopperThieving import ToolCopperThieving from flatcamTools.ToolFiducials import ToolFiducials -from flatcamTools.ToolExtractDrills import ToolExtractDrills - from flatcamTools.ToolShell import FCShell from flatcamTools.ToolSolderPaste import SolderPaste from flatcamTools.ToolSub import ToolSub diff --git a/share/align16.png b/share/align16.png new file mode 100644 index 0000000000000000000000000000000000000000..d21f1cec306b4d64a76075be2dd1bcb12a04237c GIT binary patch literal 457 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+uenMVO6iP5s=4O z;1OBOz`%C|gc+x5^GO2**-JcqUD=;7@(N2TujDx{1r(a@>EaloaenDVTdqS10xb`Z z&%Yw(nJ>%2pOn6|DS~TfllljlFtMbW#W!B)uF-8e;uN@Fh3nC69iGDmyS+V>I9tn( zZrH-pns>C|lm5&#I}Zo2BpG(_9Olaw4{jAI$@$WAZ*tL6*r2<1_o9J2D}v-zz{&vkei>9nO2Eg zLyhW$A3zO~ARB`7(@M${i&7cN%ggmL^RkPR6AM!H@{7`Ezq0{_6oaR$pUXO@geCw+ CkCP1m literal 0 HcmV?d00001 diff --git a/share/align32.png b/share/align32.png new file mode 100644 index 0000000000000000000000000000000000000000..b81511a28901c479d7b078e86de71a66c8d92602 GIT binary patch literal 539 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`F}-3QJ1nGsvv~3cd7naSZV|es!uXUz3AC>;47e z3KeYL8a7S#8xO_3Kft=>i;7BE)UB230>YWL&7G~Sy^P#EjlA!?)Kq?LyFIhgIzO#U zyd^{Oja{tXB<6Q_zVhX!lr26S>}4?d#ed$Mh|?T$HedLrnH)80JkI6*`u&DOzjOFJ zEHD4mIH;zidcpg{jp-U)53Q?SrCn91lzCCin&7#Ld;O#dYdub$RXUZ+#%UVpD`2d~ zm~c?0p+!;MI96@pjrJt*oWA=W9g=&vS3Ek_;W59_dj-!Vt5bZ6d2^*q>&1QaFPX_N z*?*KJ-t7aoytkI}46}R3#Cgv-*j-b21Pnd~)e_f;l9a@fRIB8oR3OD*WME{VYhb8r zXdGf_X=P*zMA`-hRt5$KFKOID(U6;;l9^VCTf>I_328tLk{}y`^V3So6N^$A%FE03 gGV`*FlM@S4_413-XTP(N0xDwgboFyt=akR{080n5DgXcg literal 0 HcmV?d00001 From 5c932dc5cc0bdc86bee72957fe20a92bc2dd18b8 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Tue, 14 Jan 2020 01:36:37 +0200 Subject: [PATCH 013/209] - fixed an issue in Gerber parser introduced recently due of changes made to make Gerber files produced by Sprint Layout --- README.md | 1 + flatcamParsers/ParseGerber.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 414cffad..6e9d4270 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ CAD program, and create G-Code for Isolation routing. - fixed a small GUI issue in Excellon UI when Basic mode is active - started the add of a new Tool: Align Objects Tool which will align (sync) objects of Gerber or Excellon type +- fixed an issue in Gerber parser introduced recently due of changes made to make Gerber files produced by Sprint Layout 12.01.2020 diff --git a/flatcamParsers/ParseGerber.py b/flatcamParsers/ParseGerber.py index 7fbfce1f..16ce8f37 100644 --- a/flatcamParsers/ParseGerber.py +++ b/flatcamParsers/ParseGerber.py @@ -835,7 +835,8 @@ class Gerber(Geometry): # --- Buffered --- geo_dict = dict() if current_aperture in self.apertures: - buff_value = float(self.apertures[current_aperture]['size']) / 2.0 + # the following line breaks loading of Circuit Studio Gerber files + # buff_value = float(self.apertures[current_aperture]['size']) / 2.0 # region_geo = Polygon(path).buffer(buff_value, int(self.steps_per_circle)) region_geo = Polygon(path) # Sprint Layout Gerbers with ground fill are crashed with above else: From f9ec233b0f4d27417ec3279be1cd4eecc1ef3e85 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Tue, 14 Jan 2020 02:45:03 +0200 Subject: [PATCH 014/209] - working on the Align Objects Tool --- FlatCAMApp.py | 3 + README.md | 1 + flatcamTools/ToolAlignObjects.py | 104 ++++++++++++++++++++++--------- 3 files changed, 79 insertions(+), 29 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index ca691c00..b7aa387b 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -968,6 +968,9 @@ class App(QtCore.QObject): "tools_edrills_rectangular": False, "tools_edrills_others": False, + # Align Objects Tool + "tools_align_objects_align_type": 'sp', + # Utilities # file associations "fa_excellon": 'drd, drl, exc, ncd, tap, xln', diff --git a/README.md b/README.md index 6e9d4270..ac71ea1e 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ CAD program, and create G-Code for Isolation routing. - fixed a small GUI issue in Excellon UI when Basic mode is active - started the add of a new Tool: Align Objects Tool which will align (sync) objects of Gerber or Excellon type - fixed an issue in Gerber parser introduced recently due of changes made to make Gerber files produced by Sprint Layout +- working on the Align Objects Tool 12.01.2020 diff --git a/flatcamTools/ToolAlignObjects.py b/flatcamTools/ToolAlignObjects.py index e787d0c6..a0e031ab 100644 --- a/flatcamTools/ToolAlignObjects.py +++ b/flatcamTools/ToolAlignObjects.py @@ -8,7 +8,7 @@ from PyQt5 import QtWidgets, QtGui, QtCore from FlatCAMTool import FlatCAMTool -from flatcamGUI.GUIElements import FCComboBox +from flatcamGUI.GUIElements import FCComboBox, RadioSet from copy import deepcopy @@ -61,7 +61,7 @@ class AlignObjects(FlatCAMTool): grid0.addWidget(self.aligned_label, 0, 0, 1, 2) # Type of object to be aligned - self.type_obj_combo = QtWidgets.QComboBox() + self.type_obj_combo = FCComboBox() self.type_obj_combo.addItem("Gerber") self.type_obj_combo.addItem("Excellon") self.type_obj_combo.addItem("Geometry") @@ -81,7 +81,7 @@ class AlignObjects(FlatCAMTool): grid0.addWidget(self.type_obj_combo, 2, 1) # Object to be aligned - self.object_combo = QtWidgets.QComboBox() + self.object_combo = FCComboBox() self.object_combo.setModel(self.app.collection) self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.object_combo.setCurrentIndex(1) @@ -106,7 +106,7 @@ class AlignObjects(FlatCAMTool): grid0.addWidget(self.aligned_label, 6, 0, 1, 2) # Type of object to be aligned to = aligner - self.type_aligner_obj_combo = QtWidgets.QComboBox() + self.type_aligner_obj_combo = FCComboBox() self.type_aligner_obj_combo.addItem("Gerber") self.type_aligner_obj_combo.addItem("Excellon") self.type_aligner_obj_combo.addItem("Geometry") @@ -126,7 +126,7 @@ class AlignObjects(FlatCAMTool): grid0.addWidget(self.type_aligner_obj_combo, 7, 1) # Object to be aligned to = aligner - self.aligner_object_combo = QtWidgets.QComboBox() + self.aligner_object_combo = FCComboBox() self.aligner_object_combo.setModel(self.app.collection) self.aligner_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.aligner_object_combo.setCurrentIndex(1) @@ -144,6 +144,30 @@ class AlignObjects(FlatCAMTool): separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) grid0.addWidget(separator_line, 9, 0, 1, 2) + # Alignment Type + self.a_type_lbl = QtWidgets.QLabel('%s:' % _("Alignment Type")) + self.a_type_lbl.setToolTip( + _("The type of alignment can be:\n" + "- Single Point -> it require a single point of sync, the action will be a translation\n" + "- Dual Point -> it require two points of sync, the action will be translation followed by rotation") + ) + self.a_type_radio = RadioSet( + [ + {'label': _('Single Point'), 'value': 'sp'}, + {'label': _('Dual Point'), 'value': 'dp'} + ], + orientation='horizontal', + stretch=False + ) + + grid0.addWidget(self.a_type_lbl, 10, 0, 1, 2) + grid0.addWidget(self.a_type_radio, 11, 0, 1, 2) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(separator_line, 12, 0, 1, 2) + # Buttons self.align_object_button = QtWidgets.QPushButton(_("Align Object")) self.align_object_button.setToolTip( @@ -191,14 +215,13 @@ class AlignObjects(FlatCAMTool): self.aligned_obj = None self.aligner_obj = None - # here store the alignment points for the aligned object - self.aligned_clicked_points = list() + # this is one of the objects: self.aligned_obj or self.aligner_obj + self.target_obj = None - # here store the alignment points for the aligner object - self.aligner_clicked_points = list() + # here store the alignment points + self.clicked_points = list() - # counter for the clicks - self.click_cnt = 0 + self.align_type = None def run(self, toggle=True): self.app.report_usage("ToolAlignObjects()") @@ -233,7 +256,12 @@ class AlignObjects(FlatCAMTool): def set_tool_ui(self): self.reset_fields() - self.click_cnt = 0 + self.clicked_points = list() + self.target_obj = None + self.aligned_obj = None + self.aligner_obj = None + + self.a_type_radio.set_value(self.app.defaults["tools_align_objects_align_type"]) if self.local_connected is True: self.disconnect_cal_events() @@ -268,6 +296,8 @@ class AlignObjects(FlatCAMTool): self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no aligner FlatCAM object selected...")) return + self.align_type = self.a_type_radio.get_value() + # disengage the grid snapping since it will be hard to find the drills or pads on grid if self.app.ui.grid_snap_btn.isChecked(): self.grid_status_memory = True @@ -285,6 +315,7 @@ class AlignObjects(FlatCAMTool): self.local_connected = True self.app.inform.emit(_("Get First alignment point on the aligned object.")) + self.target_obj = self.aligned_obj def on_mouse_click_release(self, event): if self.app.is_legacy is False: @@ -311,7 +342,7 @@ class AlignObjects(FlatCAMTool): for geo in tool_dict['solid_geometry']: if click_pt.within(geo): center_pt = geo.centroid - self.click_points.append( + self.clicked_points.append( [ float('%.*f' % (self.decimals, center_pt.x)), float('%.*f' % (self.decimals, center_pt.y)) @@ -325,7 +356,7 @@ class AlignObjects(FlatCAMTool): if click_pt.within(geo_el['solid']): if isinstance(geo_el['follow'], Point): center_pt = geo_el['solid'].centroid - self.click_points.append( + self.clicked_points.append( [ float('%.*f' % (self.decimals, center_pt.x)), float('%.*f' % (self.decimals, center_pt.y)) @@ -334,24 +365,37 @@ class AlignObjects(FlatCAMTool): self.check_points() elif event.button == right_button and self.app.event_is_dragging is False: - if not len(self.click_points): - self.reset_calibration_points() - self.disconnect_cal_events() - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled by user request.")) + self.clicked_points = list() + self.disconnect_cal_events() + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled by user request.")) def check_points(self): - if len(self.aligned_click_points) == 1: - self.app.inform.emit(_("Get Second alignment point on aligned object. " - "Or right click to get First alignment point on the aligner object.")) + if self.align_type == 'sp': + if len(self.clicked_points) == 1: + self.app.inform.emit(_("Get First alignment point on the aligner object.")) + # TODO: not working + self.target_obj = self.aligner_obj - if len(self.aligned_click_points) == 2: - self.app.inform.emit(_("Get First alignment point on the aligner object.")) + if len(self.clicked_points) == 2: + self.app.inform.emit('[success] %s' % _("Done.")) + self.align_translate() + self.disconnect_cal_events() + else: + if len(self.clicked_points) == 1: + self.app.inform.emit(_("Get Second alignment point on aligned object. Or right click to cancel.")) - if len(self.aligner_click_points) == 1: - self.app.inform.emit(_("Get Second alignment point on the aligner object. Or right click to finish.")) - self.align_translate() - self.align_rotate() - self.disconnect_cal_events() + if len(self.clicked_points) == 2: + self.app.inform.emit(_("Get First alignment point on the aligner object.")) + self.target_obj = self.aligner_obj + + if len(self.clicked_points) == 3: + self.app.inform.emit(_("Get Second alignment point on the aligner object. Or right click to cancel.")) + + if len(self.clicked_points) == 4: + self.app.inform.emit('[success] %s' % _("Done.")) + self.align_translate() + self.align_rotate() + self.disconnect_cal_events() def align_translate(self): pass @@ -416,7 +460,9 @@ class AlignObjects(FlatCAMTool): self.canvas.graph_event_disconnect(self.mr) self.local_connected = False - self.click_cnt = 0 + self.target_obj = None + self.aligned_obj = None + self.aligner_obj = None def reset_fields(self): self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) From 853f3f5d125df08bcf4690a532d04de70b39cc3b Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Tue, 14 Jan 2020 03:27:15 +0200 Subject: [PATCH 015/209] - working on the Align Objects Tool --- flatcamTools/ToolAlignObjects.py | 35 ++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/flatcamTools/ToolAlignObjects.py b/flatcamTools/ToolAlignObjects.py index a0e031ab..505c5a30 100644 --- a/flatcamTools/ToolAlignObjects.py +++ b/flatcamTools/ToolAlignObjects.py @@ -10,11 +10,8 @@ from FlatCAMTool import FlatCAMTool from flatcamGUI.GUIElements import FCComboBox, RadioSet -from copy import deepcopy - -import numpy as np - from shapely.geometry import Point +from shapely.affinity import translate, rotate import gettext import FlatCAMTranslation as fcTranslate @@ -221,6 +218,9 @@ class AlignObjects(FlatCAMTool): # here store the alignment points self.clicked_points = list() + self.new_start = None + self.new_stop = None + self.align_type = None def run(self, toggle=True): @@ -286,9 +286,9 @@ class AlignObjects(FlatCAMTool): self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no aligned FlatCAM object selected...")) return - aligner_obj_sel_index = self.object_combo.currentIndex() + aligner_obj_sel_index = self.aligner_object_combo.currentIndex() aligner_obj_model_index = self.app.collection.index( - aligner_obj_sel_index, 0, self.object_combo.rootModelIndex()) + aligner_obj_sel_index, 0, self.aligner_object_combo.rootModelIndex()) try: self.aligner_obj = aligner_obj_model_index.internalPointer().obj @@ -373,12 +373,13 @@ class AlignObjects(FlatCAMTool): if self.align_type == 'sp': if len(self.clicked_points) == 1: self.app.inform.emit(_("Get First alignment point on the aligner object.")) - # TODO: not working self.target_obj = self.aligner_obj if len(self.clicked_points) == 2: self.app.inform.emit('[success] %s' % _("Done.")) self.align_translate() + self.app.plot_all() + self.disconnect_cal_events() else: if len(self.clicked_points) == 1: @@ -395,13 +396,29 @@ class AlignObjects(FlatCAMTool): self.app.inform.emit('[success] %s' % _("Done.")) self.align_translate() self.align_rotate() + self.app.plot_all() + self.disconnect_cal_events() def align_translate(self): - pass + dx = self.clicked_points[1][0] - self.clicked_points[0][0] + dy = self.clicked_points[1][1] - self.clicked_points[0][1] + + if self.align_type == 'dp': + self.new_start = translate(Point(self.clicked_points[2]), xoff=dx, yoff=dy) + self.new_dest = translate(Point(self.clicked_points[3]), xoff=dx, yoff=dy) + + self.aligned_obj.offset((dx, dy)) + + # Update the object bounding box options + a, b, c, d = self.aligned_obj.bounds() + self.aligned_obj.options['xmin'] = a + self.aligned_obj.options['ymin'] = b + self.aligned_obj.options['xmax'] = c + self.aligned_obj.options['ymax'] = d def align_rotate(self): - pass + print(self.new_start.x == self.new_dest.x) def execute(self): aligned_name = self.object_combo.currentText() From 9a3f3b600b6aa733df09808ea40ad394ee863b3b Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Tue, 14 Jan 2020 16:23:23 +0200 Subject: [PATCH 016/209] - in Extract Drill Tool added a new method of drills extraction. The methods are: fixed diameter, fixed annular ring and proportional - in Align Objects Tool finished the Single Point method of alignment --- FlatCAMApp.py | 32 +++-- README.md | 5 + flatcamGUI/PreferencesUI.py | 72 +++++++---- flatcamTools/ToolAlignObjects.py | 106 +++++++++++----- flatcamTools/ToolExtractDrills.py | 194 +++++++++++++++++++++++++++--- 5 files changed, 326 insertions(+), 83 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index b7aa387b..80df6cab 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -957,6 +957,7 @@ class App(QtCore.QObject): # Drills Extraction Tool "tools_edrills_hole_type": 'fixed', "tools_edrills_hole_fixed_dia": 0.5, + "tools_edrills_hole_prop_factor": 80.0, "tools_edrills_circular_ring": 0.2, "tools_edrills_oblong_ring": 0.2, "tools_edrills_square_ring": 0.2, @@ -1598,6 +1599,7 @@ class App(QtCore.QObject): # Extract Drills Tool "tools_edrills_hole_type": self.ui.tools2_defaults_form.tools2_edrills_group.hole_size_radio, "tools_edrills_hole_fixed_dia": self.ui.tools2_defaults_form.tools2_edrills_group.dia_entry, + "tools_edrills_hole_prop_factor": self.ui.tools2_defaults_form.tools2_edrills_group.factor_entry, "tools_edrills_circular_ring": self.ui.tools2_defaults_form.tools2_edrills_group.circular_ring_entry, "tools_edrills_oblong_ring": self.ui.tools2_defaults_form.tools2_edrills_group.oblong_ring_entry, "tools_edrills_square_ring": self.ui.tools2_defaults_form.tools2_edrills_group.square_ring_entry, @@ -4277,9 +4279,20 @@ class App(QtCore.QObject): obj.options['xmax'] = xmax obj.options['ymax'] = ymax except Exception as e: - log.warning("The object has no bounds properties. %s" % str(e)) + log.warning("App.new_object() -> The object has no bounds properties. %s" % str(e)) return "fail" + try: + if kind == 'excellon': + obj.fill_color = self.app.defaults["excellon_plot_fill"] + obj.outline_color = self.app.defaults["excellon_plot_line"] + + if kind == 'gerber': + obj.fill_color = self.app.defaults["gerber_plot_fill"] + obj.outline_color = self.app.defaults["gerber_plot_line"] + except Exception as e: + log.warning("App.new_object() -> setting colors error. %s" % str(e)) + # update the KeyWords list with the name of the file self.myKeywords.append(obj.options['name']) @@ -12305,19 +12318,12 @@ class App(QtCore.QObject): new_line_color = color_variant(new_color[:7], 0.7) for sel_obj in sel_obj_list: - if self.is_legacy is False: - sel_obj.fill_color = new_color - sel_obj.outline_color = new_line_color + sel_obj.fill_color = new_color + sel_obj.outline_color = new_line_color - sel_obj.shapes.redraw( - update_colors=(new_color, new_line_color) - ) - else: - sel_obj.fill_color = new_color - sel_obj.outline_color = new_line_color - sel_obj.shapes.redraw( - update_colors=(new_color, new_line_color) - ) + sel_obj.shapes.redraw( + update_colors=(new_color, new_line_color) + ) def on_grid_snap_triggered(self, state): if state: diff --git a/README.md b/README.md index ac71ea1e..ca9dc47d 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,11 @@ CAD program, and create G-Code for Isolation routing. ================================================= +14.01.2020 + +- in Extract Drill Tool added a new method of drills extraction. The methods are: fixed diameter, fixed annular ring and proportional +- in Align Objects Tool finished the Single Point method of alignment + 13.01.2020 - fixed a small GUI issue in Excellon UI when Basic mode is active diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index a073b534..41ae3f32 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -7697,14 +7697,20 @@ class Tools2EDrillsPrefGroupUI(OptionsGroupUI): grid_lay.addWidget(separator_line, 8, 0, 1, 2) # ## Axis - self.hole_size_radio = RadioSet([{'label': _("Fixed"), 'value': 'fixed'}, - {'label': _("Proportional"), 'value': 'prop'}]) - self.hole_size_label = QtWidgets.QLabel('%s:' % _("Hole Size")) + self.hole_size_radio = RadioSet( + [ + {'label': _("Fixed Diameter"), 'value': 'fixed'}, + {'label': _("Fixed Annular Ring"), 'value': 'ring'}, + {'label': _("Proportional"), 'value': 'prop'} + ], + orientation='vertical', + stretch=False) + self.hole_size_label = QtWidgets.QLabel('%s:' % _("Method")) self.hole_size_label.setToolTip( - _("The type of hole size. Can be:\n" - "- Fixed -> all holes will have a set size\n" - "- Proprotional -> each hole will havea a variable size\n" - "such as to preserve a set annular ring")) + _("The selected method of extracting the drills. Can be:\n" + "- Fixed Diameter -> all holes will have a set size\n" + "- Fixed Annular Ring -> all holes will have a set annular ring\n" + "- Proportional -> each hole size will be a fraction of the pad size")) grid_lay.addWidget(self.hole_size_label, 9, 0) grid_lay.addWidget(self.hole_size_radio, 9, 1) @@ -7716,27 +7722,31 @@ class Tools2EDrillsPrefGroupUI(OptionsGroupUI): separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) grid_lay.addWidget(separator_line, 10, 0, 1, 2) + # Annular Ring + self.fixed_label = QtWidgets.QLabel('%s' % _("Fixed Diameter")) + grid_lay.addWidget(self.fixed_label, 11, 0, 1, 2) + # Diameter value self.dia_entry = FCDoubleSpinner() self.dia_entry.set_precision(self.decimals) self.dia_entry.set_range(0.0000, 9999.9999) - self.dia_label = QtWidgets.QLabel('%s:' % _("Diameter")) + self.dia_label = QtWidgets.QLabel('%s:' % _("value")) self.dia_label.setToolTip( _("Fixed hole diameter.") ) - grid_lay.addWidget(self.dia_label, 11, 0) - grid_lay.addWidget(self.dia_entry, 11, 1) + grid_lay.addWidget(self.dia_label, 12, 0) + grid_lay.addWidget(self.dia_entry, 12, 1) # Annular Ring value - self.ring_label = QtWidgets.QLabel('%s' % _("Annular Ring")) + self.ring_label = QtWidgets.QLabel('%s' % _("Fixed Annular Ring")) self.ring_label.setToolTip( _("The size of annular ring.\n" "The copper sliver between the drill hole exterior\n" "and the margin of the copper pad.") ) - grid_lay.addWidget(self.ring_label, 12, 0, 1, 2) + grid_lay.addWidget(self.ring_label, 13, 0, 1, 2) # Circular Annular Ring Value self.circular_ring_label = QtWidgets.QLabel('%s:' % _("Circular")) @@ -7748,8 +7758,8 @@ class Tools2EDrillsPrefGroupUI(OptionsGroupUI): self.circular_ring_entry.set_precision(self.decimals) self.circular_ring_entry.set_range(0.0000, 9999.9999) - grid_lay.addWidget(self.circular_ring_label, 13, 0) - grid_lay.addWidget(self.circular_ring_entry, 13, 1) + grid_lay.addWidget(self.circular_ring_label, 14, 0) + grid_lay.addWidget(self.circular_ring_entry, 14, 1) # Oblong Annular Ring Value self.oblong_ring_label = QtWidgets.QLabel('%s:' % _("Oblong")) @@ -7761,8 +7771,8 @@ class Tools2EDrillsPrefGroupUI(OptionsGroupUI): self.oblong_ring_entry.set_precision(self.decimals) self.oblong_ring_entry.set_range(0.0000, 9999.9999) - grid_lay.addWidget(self.oblong_ring_label, 14, 0) - grid_lay.addWidget(self.oblong_ring_entry, 14, 1) + grid_lay.addWidget(self.oblong_ring_label, 15, 0) + grid_lay.addWidget(self.oblong_ring_entry, 15, 1) # Square Annular Ring Value self.square_ring_label = QtWidgets.QLabel('%s:' % _("Square")) @@ -7774,8 +7784,8 @@ class Tools2EDrillsPrefGroupUI(OptionsGroupUI): self.square_ring_entry.set_precision(self.decimals) self.square_ring_entry.set_range(0.0000, 9999.9999) - grid_lay.addWidget(self.square_ring_label, 15, 0) - grid_lay.addWidget(self.square_ring_entry, 15, 1) + grid_lay.addWidget(self.square_ring_label, 16, 0) + grid_lay.addWidget(self.square_ring_entry, 16, 1) # Rectangular Annular Ring Value self.rectangular_ring_label = QtWidgets.QLabel('%s:' % _("Rectangular")) @@ -7787,8 +7797,8 @@ class Tools2EDrillsPrefGroupUI(OptionsGroupUI): self.rectangular_ring_entry.set_precision(self.decimals) self.rectangular_ring_entry.set_range(0.0000, 9999.9999) - grid_lay.addWidget(self.rectangular_ring_label, 16, 0) - grid_lay.addWidget(self.rectangular_ring_entry, 16, 1) + grid_lay.addWidget(self.rectangular_ring_label, 17, 0) + grid_lay.addWidget(self.rectangular_ring_entry, 17, 1) # Others Annular Ring Value self.other_ring_label = QtWidgets.QLabel('%s:' % _("Others")) @@ -7800,8 +7810,26 @@ class Tools2EDrillsPrefGroupUI(OptionsGroupUI): self.other_ring_entry.set_precision(self.decimals) self.other_ring_entry.set_range(0.0000, 9999.9999) - grid_lay.addWidget(self.other_ring_label, 17, 0) - grid_lay.addWidget(self.other_ring_entry, 17, 1) + grid_lay.addWidget(self.other_ring_label, 18, 0) + grid_lay.addWidget(self.other_ring_entry, 18, 1) + + self.prop_label = QtWidgets.QLabel('%s' % _("Proportional Diameter")) + grid_lay.addWidget(self.prop_label, 19, 0, 1, 2) + + # Factor value + self.factor_entry = FCDoubleSpinner(suffix='%') + self.factor_entry.set_precision(self.decimals) + self.factor_entry.set_range(0.0000, 100.0000) + self.factor_entry.setSingleStep(0.1) + + self.factor_label = QtWidgets.QLabel('%s:' % _("Factor")) + self.factor_label.setToolTip( + _("Proportional Diameter.\n" + "The drill diameter will be a fraction of the pad size.") + ) + + grid_lay.addWidget(self.factor_label, 20, 0) + grid_lay.addWidget(self.factor_entry, 20, 1) self.layout.addStretch() diff --git a/flatcamTools/ToolAlignObjects.py b/flatcamTools/ToolAlignObjects.py index 505c5a30..91594c16 100644 --- a/flatcamTools/ToolAlignObjects.py +++ b/flatcamTools/ToolAlignObjects.py @@ -54,18 +54,16 @@ class AlignObjects(FlatCAMTool): grid0.setColumnStretch(1, 1) self.layout.addLayout(grid0) - self.aligned_label = QtWidgets.QLabel('%s' % _("Selection of the aligned object")) + self.aligned_label = QtWidgets.QLabel('%s' % _("Selection of the WORKING object")) grid0.addWidget(self.aligned_label, 0, 0, 1, 2) # Type of object to be aligned self.type_obj_combo = FCComboBox() self.type_obj_combo.addItem("Gerber") self.type_obj_combo.addItem("Excellon") - self.type_obj_combo.addItem("Geometry") self.type_obj_combo.setItemIcon(0, QtGui.QIcon(self.app.resource_location + "/flatcam_icon16.png")) self.type_obj_combo.setItemIcon(1, QtGui.QIcon(self.app.resource_location + "/drill16.png")) - self.type_obj_combo.setItemIcon(2, QtGui.QIcon(self.app.resource_location + "/geometry16.png")) self.type_obj_combo_label = QtWidgets.QLabel('%s:' % _("Object Type")) self.type_obj_combo_label.setToolTip( @@ -96,9 +94,9 @@ class AlignObjects(FlatCAMTool): separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) grid0.addWidget(separator_line, 4, 0, 1, 2) - self.aligned_label = QtWidgets.QLabel('%s' % _("Selection of the aligner object")) + self.aligned_label = QtWidgets.QLabel('%s' % _("Selection of the TARGET object")) self.aligned_label.setToolTip( - _("Object to which the other objects will be aligned to (moved).") + _("Object to which the other objects will be aligned to (moved to).") ) grid0.addWidget(self.aligned_label, 6, 0, 1, 2) @@ -106,11 +104,9 @@ class AlignObjects(FlatCAMTool): self.type_aligner_obj_combo = FCComboBox() self.type_aligner_obj_combo.addItem("Gerber") self.type_aligner_obj_combo.addItem("Excellon") - self.type_aligner_obj_combo.addItem("Geometry") self.type_aligner_obj_combo.setItemIcon(0, QtGui.QIcon(self.app.resource_location + "/flatcam_icon16.png")) self.type_aligner_obj_combo.setItemIcon(1, QtGui.QIcon(self.app.resource_location + "/drill16.png")) - self.type_aligner_obj_combo.setItemIcon(2, QtGui.QIcon(self.app.resource_location + "/geometry16.png")) self.type_aligner_obj_combo_label = QtWidgets.QLabel('%s:' % _("Object Type")) self.type_aligner_obj_combo_label.setToolTip( @@ -219,10 +215,17 @@ class AlignObjects(FlatCAMTool): self.clicked_points = list() self.new_start = None - self.new_stop = None + self.new_dest = None self.align_type = None + # old colors of objects involved in the alignment + self.aligner_old_fill_color = None + self.aligner_old_line_color = None + self.aligned_old_fill_color = None + self.aligned_old_line_color = None + + def run(self, toggle=True): self.app.report_usage("ToolAlignObjects()") @@ -261,6 +264,11 @@ class AlignObjects(FlatCAMTool): self.aligned_obj = None self.aligner_obj = None + self.aligner_old_fill_color = None + self.aligner_old_line_color = None + self.aligned_old_fill_color = None + self.aligned_old_line_color = None + self.a_type_radio.set_value(self.app.defaults["tools_align_objects_align_type"]) if self.local_connected is True: @@ -277,6 +285,7 @@ class AlignObjects(FlatCAMTool): self.aligner_object_combo.setCurrentIndex(0) def on_align(self): + self.app.delete_selection_shape() obj_sel_index = self.object_combo.currentIndex() obj_model_index = self.app.collection.index(obj_sel_index, 0, self.object_combo.rootModelIndex()) @@ -314,8 +323,14 @@ class AlignObjects(FlatCAMTool): self.local_connected = True - self.app.inform.emit(_("Get First alignment point on the aligned object.")) + self.aligner_old_fill_color = self.aligner_obj.fill_color + self.aligner_old_line_color = self.aligner_obj.outline_color + self.aligned_old_fill_color = self.aligned_obj.fill_color + self.aligned_old_line_color = self.aligned_obj.outline_color + + self.app.inform.emit('%s: %s' % (_("First Point"), _("Click on the START point."))) self.target_obj = self.aligned_obj + self.set_color() def on_mouse_click_release(self, event): if self.app.is_legacy is False: @@ -365,40 +380,47 @@ class AlignObjects(FlatCAMTool): self.check_points() elif event.button == right_button and self.app.event_is_dragging is False: + self.reset_color() self.clicked_points = list() self.disconnect_cal_events() self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled by user request.")) def check_points(self): - if self.align_type == 'sp': - if len(self.clicked_points) == 1: - self.app.inform.emit(_("Get First alignment point on the aligner object.")) - self.target_obj = self.aligner_obj + if len(self.clicked_points) == 1: + self.app.inform.emit('%s: %s. %s' % ( + _("First Point"), _("Click on the DESTINATION point."), _(" Or right click to cancel."))) + self.target_obj = self.aligner_obj + self.reset_color() + self.set_color() - if len(self.clicked_points) == 2: + if len(self.clicked_points) == 2: + self.align_translate() + if self.align_type == 'sp': self.app.inform.emit('[success] %s' % _("Done.")) - self.align_translate() self.app.plot_all() self.disconnect_cal_events() - else: - if len(self.clicked_points) == 1: - self.app.inform.emit(_("Get Second alignment point on aligned object. Or right click to cancel.")) + return + else: + self.app.inform.emit('%s: %s. %s' % ( + _("Second Point"), _("Click on the START point."), _(" Or right click to cancel."))) + self.target_obj = self.aligned_obj + self.reset_color() + self.set_color() - if len(self.clicked_points) == 2: - self.app.inform.emit(_("Get First alignment point on the aligner object.")) - self.target_obj = self.aligner_obj + if len(self.clicked_points) == 3: + self.app.inform.emit('%s: %s. %s' % ( + _("Second Point"), _("Click on the DESTINATION point."), _(" Or right click to cancel."))) + self.target_obj = self.aligner_obj + self.reset_color() + self.set_color() - if len(self.clicked_points) == 3: - self.app.inform.emit(_("Get Second alignment point on the aligner object. Or right click to cancel.")) + if len(self.clicked_points) == 4: + self.align_rotate() + self.app.inform.emit('[success] %s' % _("Done.")) - if len(self.clicked_points) == 4: - self.app.inform.emit('[success] %s' % _("Done.")) - self.align_translate() - self.align_rotate() - self.app.plot_all() - - self.disconnect_cal_events() + self.disconnect_cal_events() + self.app.plot_all() def align_translate(self): dx = self.clicked_points[1][0] - self.clicked_points[0][0] @@ -477,9 +499,27 @@ class AlignObjects(FlatCAMTool): self.canvas.graph_event_disconnect(self.mr) self.local_connected = False - self.target_obj = None - self.aligned_obj = None - self.aligner_obj = None + + self.aligner_old_fill_color = None + self.aligner_old_line_color = None + self.aligned_old_fill_color = None + self.aligned_old_line_color = None + + def set_color(self): + new_color = "#15678abf" + new_line_color = new_color + self.target_obj.shapes.redraw( + update_colors=(new_color, new_line_color) + ) + + def reset_color(self): + self.aligned_obj.shapes.redraw( + update_colors=(self.aligned_old_fill_color, self.aligned_old_line_color) + ) + + self.aligner_obj.shapes.redraw( + update_colors=(self.aligner_old_fill_color, self.aligner_old_line_color) + ) def reset_fields(self): self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) diff --git a/flatcamTools/ToolExtractDrills.py b/flatcamTools/ToolExtractDrills.py index e0c72c95..d75a61b5 100644 --- a/flatcamTools/ToolExtractDrills.py +++ b/flatcamTools/ToolExtractDrills.py @@ -125,15 +125,25 @@ class ToolExtractDrills(FlatCAMTool): grid1.setColumnStretch(0, 0) grid1.setColumnStretch(1, 1) + self.method_label = QtWidgets.QLabel('%s' % _("Method")) + grid1.addWidget(self.method_label, 2, 0, 1, 2) + # ## Axis - self.hole_size_radio = RadioSet([{'label': _("Fixed"), 'value': 'fixed'}, - {'label': _("Proportional"), 'value': 'prop'}]) + self.hole_size_radio = RadioSet( + [ + {'label': _("Fixed Diameter"), 'value': 'fixed'}, + {'label': _("Fixed Annular Ring"), 'value': 'ring'}, + {'label': _("Proportional"), 'value': 'prop'} + ], + orientation='vertical', + stretch=False) + self.hole_size_label = QtWidgets.QLabel('%s:' % _("Hole Size")) self.hole_size_label.setToolTip( - _("The type of hole size. Can be:\n" - "- Fixed -> all holes will have a set size\n" - "- Proprotional -> each hole will havea a variable size\n" - "such as to preserve a set annular ring")) + _("The selected method of extracting the drills. Can be:\n" + "- Fixed Diameter -> all holes will have a set size\n" + "- Fixed Annular Ring -> all holes will have a set annular ring\n" + "- Proportional -> each hole size will be a fraction of the pad size")) grid1.addWidget(self.hole_size_label, 3, 0) grid1.addWidget(self.hole_size_radio, 3, 1) @@ -145,18 +155,27 @@ class ToolExtractDrills(FlatCAMTool): separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) grid1.addWidget(separator_line, 5, 0, 1, 2) + # Annular Ring + self.fixed_label = QtWidgets.QLabel('%s' % _("Fixed Diameter")) + grid1.addWidget(self.fixed_label, 6, 0, 1, 2) + # Diameter value self.dia_entry = FCDoubleSpinner() self.dia_entry.set_precision(self.decimals) self.dia_entry.set_range(0.0000, 9999.9999) - self.dia_label = QtWidgets.QLabel('%s:' % _("Diameter")) + self.dia_label = QtWidgets.QLabel('%s:' % _("Value")) self.dia_label.setToolTip( _("Fixed hole diameter.") ) - grid1.addWidget(self.dia_label, 7, 0) - grid1.addWidget(self.dia_entry, 7, 1) + grid1.addWidget(self.dia_label, 8, 0) + grid1.addWidget(self.dia_entry, 8, 1) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid1.addWidget(separator_line, 9, 0, 1, 2) self.ring_frame = QtWidgets.QFrame() self.ring_frame.setContentsMargins(0, 0, 0, 0) @@ -173,7 +192,7 @@ class ToolExtractDrills(FlatCAMTool): self.ring_box.addLayout(grid2) # Annular Ring value - self.ring_label = QtWidgets.QLabel('%s' % _("Annular Ring")) + self.ring_label = QtWidgets.QLabel('%s' % _("Fixed Annular Ring")) self.ring_label.setToolTip( _("The size of annular ring.\n" "The copper sliver between the drill hole exterior\n" @@ -246,6 +265,35 @@ class ToolExtractDrills(FlatCAMTool): grid2.addWidget(self.other_ring_label, 5, 0) grid2.addWidget(self.other_ring_entry, 5, 1) + grid3 = QtWidgets.QGridLayout() + self.layout.addLayout(grid3) + grid3.setColumnStretch(0, 0) + grid3.setColumnStretch(1, 1) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid3.addWidget(separator_line, 1, 0, 1, 2) + + # Annular Ring value + self.prop_label = QtWidgets.QLabel('%s' % _("Proportional Diameter")) + grid3.addWidget(self.prop_label, 2, 0, 1, 2) + + # Diameter value + self.factor_entry = FCDoubleSpinner(suffix='%') + self.factor_entry.set_precision(self.decimals) + self.factor_entry.set_range(0.0000, 100.0000) + self.factor_entry.setSingleStep(0.1) + + self.factor_label = QtWidgets.QLabel('%s:' % _("Value")) + self.factor_label.setToolTip( + _("Proportional Diameter.\n" + "The drill diameter will be a fraction of the pad size.") + ) + + grid3.addWidget(self.factor_label, 3, 0) + grid3.addWidget(self.factor_entry, 3, 1) + # Extract drills from Gerber apertures flashes (pads) self.e_drills_button = QtWidgets.QPushButton(_("Extract Drills")) self.e_drills_button.setToolTip( @@ -280,6 +328,13 @@ class ToolExtractDrills(FlatCAMTool): self.rectangular_ring_entry.setEnabled(False) self.other_ring_entry.setEnabled(False) + self.dia_entry.setDisabled(True) + self.dia_label.setDisabled(True) + self.factor_label.setDisabled(True) + self.factor_entry.setDisabled(True) + + self.ring_frame.setDisabled(True) + # ## Signals self.hole_size_radio.activated_custom.connect(self.on_hole_size_toggle) self.e_drills_button.clicked.connect(self.on_extract_drills_click) @@ -359,6 +414,8 @@ class ToolExtractDrills(FlatCAMTool): self.rectangular_cb.set_value(self.app.defaults["tools_edrills_rectangular"]) self.other_cb.set_value(self.app.defaults["tools_edrills_others"]) + self.factor_entry.set_value(float(self.app.defaults["tools_edrills_hole_prop_factor"])) + def on_extract_drills_click(self): drill_dia = self.dia_entry.get_value() @@ -368,6 +425,8 @@ class ToolExtractDrills(FlatCAMTool): rect_r_val = self.rectangular_ring_entry.get_value() other_r_val = self.other_ring_entry.get_value() + prop_factor = self.factor_entry.get_value() / 100.0 + drills = list() tools = dict() @@ -376,7 +435,7 @@ class ToolExtractDrills(FlatCAMTool): try: fcobj = model_index.internalPointer().obj - except Exception as e: + except Exception: self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no Gerber object loaded ...")) return @@ -421,7 +480,7 @@ class ToolExtractDrills(FlatCAMTool): if 'solid_geometry' not in tools["1"] or not tools["1"]['solid_geometry']: self.app.inform.emit('[WARNING_NOTCL] %s' % _("No drills extracted. Try different parameters.")) return - else: + elif mode == 'ring': drills_found = set() for apid, apid_value in fcobj.apertures.items(): ap_type = apid_value['type'] @@ -435,9 +494,9 @@ class ToolExtractDrills(FlatCAMTool): height = float(apid_value['height']) if self.oblong_cb.get_value(): if width > height: - dia = float(apid_value['height']) - (2 * rect_r_val) + dia = float(apid_value['height']) - (2 * oblong_r_val) else: - dia = float(apid_value['width']) - (2 * rect_r_val) + dia = float(apid_value['width']) - (2 * oblong_r_val) elif ap_type == 'R': width = float(apid_value['width']) height = float(apid_value['height']) @@ -506,6 +565,91 @@ class ToolExtractDrills(FlatCAMTool): if True not in drills_found: self.app.inform.emit('[WARNING_NOTCL] %s' % _("No drills extracted. Try different parameters.")) return + else: + drills_found = set() + for apid, apid_value in fcobj.apertures.items(): + ap_type = apid_value['type'] + + dia = None + if ap_type == 'C': + if self.circular_cb.get_value(): + dia = float(apid_value['size']) * prop_factor + elif ap_type == 'O': + width = float(apid_value['width']) + height = float(apid_value['height']) + if self.oblong_cb.get_value(): + if width > height: + dia = float(apid_value['height']) * prop_factor + else: + dia = float(apid_value['width']) * prop_factor + elif ap_type == 'R': + width = float(apid_value['width']) + height = float(apid_value['height']) + + # if the height == width (float numbers so the reason for the following) + if abs(float('%.*f' % (self.decimals, width)) - float('%.*f' % (self.decimals, height))) < \ + (10 ** -self.decimals): + if self.square_cb.get_value(): + dia = float(apid_value['height']) * prop_factor + else: + if self.rectangular_cb.get_value(): + if width > height: + dia = float(apid_value['height']) * prop_factor + else: + dia = float(apid_value['width']) * prop_factor + else: + if self.other_cb.get_value(): + try: + dia = float(apid_value['size']) * prop_factor + except KeyError: + if ap_type == 'AM': + pol = apid_value['geometry'][0]['solid'] + x0, y0, x1, y1 = pol.bounds + dx = x1 - x0 + dy = y1 - y0 + if dx <= dy: + dia = dx * prop_factor + else: + dia = dy * prop_factor + + # if dia is None then none of the above applied so we skip the following + if dia is None: + continue + + tool_in_drills = False + for tool, tool_val in tools.items(): + if abs(float('%.*f' % (self.decimals, tool_val["C"])) - float('%.*f' % (self.decimals, dia))) < \ + (10 ** -self.decimals): + tool_in_drills = tool + + if tool_in_drills is False: + if tools: + new_tool = max([int(t) for t in tools]) + 1 + tool_in_drills = str(new_tool) + else: + tool_in_drills = "1" + + for geo_el in apid_value['geometry']: + if 'follow' in geo_el and isinstance(geo_el['follow'], Point): + if tool_in_drills not in tools: + tools[tool_in_drills] = {"C": dia} + + drills.append({"point": geo_el['follow'], "tool": tool_in_drills}) + + if 'solid_geometry' not in tools[tool_in_drills]: + tools[tool_in_drills]['solid_geometry'] = list() + else: + tools[tool_in_drills]['solid_geometry'].append(geo_el['follow']) + + if tool_in_drills in tools: + if 'solid_geometry' not in tools[tool_in_drills] or not tools[tool_in_drills]['solid_geometry']: + drills_found.add(False) + else: + drills_found.add(True) + + if True not in drills_found: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("No drills extracted. Try different parameters.")) + return def obj_init(obj_inst, app_inst): obj_inst.tools = tools @@ -518,16 +662,36 @@ class ToolExtractDrills(FlatCAMTool): def on_hole_size_toggle(self, val): if val == "fixed": + self.fixed_label.setDisabled(False) self.dia_entry.setDisabled(False) self.dia_label.setDisabled(False) self.ring_frame.setDisabled(True) - else: + + self.prop_label.setDisabled(True) + self.factor_label.setDisabled(True) + self.factor_entry.setDisabled(True) + elif val == "ring": + self.fixed_label.setDisabled(True) self.dia_entry.setDisabled(True) self.dia_label.setDisabled(True) self.ring_frame.setDisabled(False) + self.prop_label.setDisabled(True) + self.factor_label.setDisabled(True) + self.factor_entry.setDisabled(True) + elif val == "prop": + self.fixed_label.setDisabled(True) + self.dia_entry.setDisabled(True) + self.dia_label.setDisabled(True) + + self.ring_frame.setDisabled(True) + + self.prop_label.setDisabled(False) + self.factor_label.setDisabled(False) + self.factor_entry.setDisabled(False) + def reset_fields(self): self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.gerber_object_combo.setCurrentIndex(0) From a8bea7805ed59e6044763fc8d2d8f83647794990 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Tue, 14 Jan 2020 17:18:24 +0200 Subject: [PATCH 017/209] - working on the Dual Point option in Align Objects Tool - angle has to be recalculated --- README.md | 1 + flatcamTools/ToolAlignObjects.py | 34 ++++++++++++++++++++++-------- flatcamTools/ToolNonCopperClear.py | 2 +- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index ca9dc47d..79b484b3 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ CAD program, and create G-Code for Isolation routing. - in Extract Drill Tool added a new method of drills extraction. The methods are: fixed diameter, fixed annular ring and proportional - in Align Objects Tool finished the Single Point method of alignment +- working on the Dual Point option in Align Objects Tool - angle has to be recalculated 13.01.2020 diff --git a/flatcamTools/ToolAlignObjects.py b/flatcamTools/ToolAlignObjects.py index 91594c16..9d79de17 100644 --- a/flatcamTools/ToolAlignObjects.py +++ b/flatcamTools/ToolAlignObjects.py @@ -10,8 +10,10 @@ from FlatCAMTool import FlatCAMTool from flatcamGUI.GUIElements import FCComboBox, RadioSet +import math + from shapely.geometry import Point -from shapely.affinity import translate, rotate +from shapely.affinity import translate import gettext import FlatCAMTranslation as fcTranslate @@ -68,7 +70,7 @@ class AlignObjects(FlatCAMTool): self.type_obj_combo_label = QtWidgets.QLabel('%s:' % _("Object Type")) self.type_obj_combo_label.setToolTip( _("Specify the type of object to be aligned.\n" - "It can be of type: Gerber, Excellon or Geometry.\n" + "It can be of type: Gerber or Excellon.\n" "The selection here decide the type of objects that will be\n" "in the Object combobox.") ) @@ -111,7 +113,7 @@ class AlignObjects(FlatCAMTool): self.type_aligner_obj_combo_label = QtWidgets.QLabel('%s:' % _("Object Type")) self.type_aligner_obj_combo_label.setToolTip( _("Specify the type of object to be aligned to.\n" - "It can be of type: Gerber, Excellon or Geometry.\n" + "It can be of type: Gerber or Excellon.\n" "The selection here decide the type of objects that will be\n" "in the Object combobox.") ) @@ -394,8 +396,8 @@ class AlignObjects(FlatCAMTool): self.set_color() if len(self.clicked_points) == 2: - self.align_translate() if self.align_type == 'sp': + self.align_translate() self.app.inform.emit('[success] %s' % _("Done.")) self.app.plot_all() @@ -416,6 +418,7 @@ class AlignObjects(FlatCAMTool): self.set_color() if len(self.clicked_points) == 4: + self.align_translate() self.align_rotate() self.app.inform.emit('[success] %s' % _("Done.")) @@ -426,10 +429,6 @@ class AlignObjects(FlatCAMTool): dx = self.clicked_points[1][0] - self.clicked_points[0][0] dy = self.clicked_points[1][1] - self.clicked_points[0][1] - if self.align_type == 'dp': - self.new_start = translate(Point(self.clicked_points[2]), xoff=dx, yoff=dy) - self.new_dest = translate(Point(self.clicked_points[3]), xoff=dx, yoff=dy) - self.aligned_obj.offset((dx, dy)) # Update the object bounding box options @@ -440,7 +439,24 @@ class AlignObjects(FlatCAMTool): self.aligned_obj.options['ymax'] = d def align_rotate(self): - print(self.new_start.x == self.new_dest.x) + dx = self.clicked_points[1][0] - self.clicked_points[0][0] + dy = self.clicked_points[1][1] - self.clicked_points[0][1] + + new_start_pt = translate(Point(self.clicked_points[2]), xoff=dx, yoff=dy) + self.new_start = (new_start_pt.x, new_start_pt.y) + self.new_dest = self.clicked_points[3] + + origin_pt = self.clicked_points[1] + + sec_dx = self.new_dest[0] - self.new_start[0] + sec_dy = self.new_dest[1] - self.new_start[1] + + rotation_not_needed = (abs(self.new_start[0] - self.new_dest[0]) <= (10 ** -self.decimals)) or \ + (abs(self.new_start[1] - self.new_dest[1]) <= (10 ** -self.decimals)) + if rotation_not_needed is False: + # calculate rotation angle + angle = math.degrees(math.atan(sec_dy / sec_dx)) + self.aligned_obj.rotate(angle=angle, point=origin_pt) def execute(self): aligned_name = self.object_combo.currentText() diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNonCopperClear.py index 9a6e047e..8b6ba546 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/flatcamTools/ToolNonCopperClear.py @@ -641,7 +641,7 @@ class NonCopperClear(FlatCAMTool, Gerber): } # ############################################################################# - # ############################ SGINALS ######################################## + # ############################ SIGNALS ######################################## # ############################################################################# self.addtool_btn.clicked.connect(self.on_tool_add) self.addtool_entry.returnPressed.connect(self.on_tool_add) From acfb1ca9e7f1febbefb41668ef76b2122c4d2091 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 15 Jan 2020 00:55:12 +0200 Subject: [PATCH 018/209] - finished Dual Point option in Align Objects Tool --- README.md | 1 + flatcamTools/ToolAlignObjects.py | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 79b484b3..5e49cd87 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ CAD program, and create G-Code for Isolation routing. - in Extract Drill Tool added a new method of drills extraction. The methods are: fixed diameter, fixed annular ring and proportional - in Align Objects Tool finished the Single Point method of alignment - working on the Dual Point option in Align Objects Tool - angle has to be recalculated +- finished Dual Point option in Align Objects Tool 13.01.2020 diff --git a/flatcamTools/ToolAlignObjects.py b/flatcamTools/ToolAlignObjects.py index 9d79de17..7368b865 100644 --- a/flatcamTools/ToolAlignObjects.py +++ b/flatcamTools/ToolAlignObjects.py @@ -216,9 +216,6 @@ class AlignObjects(FlatCAMTool): # here store the alignment points self.clicked_points = list() - self.new_start = None - self.new_dest = None - self.align_type = None # old colors of objects involved in the alignment @@ -442,20 +439,25 @@ class AlignObjects(FlatCAMTool): dx = self.clicked_points[1][0] - self.clicked_points[0][0] dy = self.clicked_points[1][1] - self.clicked_points[0][1] - new_start_pt = translate(Point(self.clicked_points[2]), xoff=dx, yoff=dy) - self.new_start = (new_start_pt.x, new_start_pt.y) - self.new_dest = self.clicked_points[3] + test_rotation_pt = translate(Point(self.clicked_points[2]), xoff=dx, yoff=dy) + new_start = (test_rotation_pt.x, test_rotation_pt.y) + new_dest = self.clicked_points[3] origin_pt = self.clicked_points[1] - sec_dx = self.new_dest[0] - self.new_start[0] - sec_dy = self.new_dest[1] - self.new_start[1] + dxd = new_dest[0] - origin_pt[0] + dyd = new_dest[1] - origin_pt[1] - rotation_not_needed = (abs(self.new_start[0] - self.new_dest[0]) <= (10 ** -self.decimals)) or \ - (abs(self.new_start[1] - self.new_dest[1]) <= (10 ** -self.decimals)) + dxs = new_start[0] - origin_pt[0] + dys = new_start[1] - origin_pt[1] + + rotation_not_needed = (abs(new_start[0] - new_dest[0]) <= (10 ** -self.decimals)) or \ + (abs(new_start[1] - new_dest[1]) <= (10 ** -self.decimals)) if rotation_not_needed is False: # calculate rotation angle - angle = math.degrees(math.atan(sec_dy / sec_dx)) + angle_dest = math.degrees(math.atan(dyd / dxd)) + angle_start = math.degrees(math.atan(dys / dxs)) + angle = angle_dest - angle_start self.aligned_obj.rotate(angle=angle, point=origin_pt) def execute(self): From 821014f719e681dd26ddaa77687eae1c8c6019c9 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 15 Jan 2020 02:50:27 +0200 Subject: [PATCH 019/209] - added key shortcuts and toolbar icons for the new tools: Align Object Tool (ALT+A) and Extract Drills (ALT+I) - added new functionality (key shortcut SHIFT+J) to locate the corners of the bounding box (and center) in a selected object --- FlatCAMApp.py | 155 ++++++++++++++++++++++++++++++- README.md | 5 + flatcamGUI/FlatCAMGUI.py | 63 +++++++++++-- flatcamTools/ToolAlignObjects.py | 45 --------- share/extract_drill16.png | Bin 0 -> 459 bytes share/extract_drill32.png | Bin 0 -> 745 bytes share/locate16.png | Bin 0 -> 565 bytes share/locate32.png | Bin 0 -> 900 bytes 8 files changed, 214 insertions(+), 54 deletions(-) create mode 100644 share/extract_drill16.png create mode 100644 share/extract_drill32.png create mode 100644 share/locate16.png create mode 100644 share/locate32.png diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 80df6cab..5324290e 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -240,6 +240,9 @@ class App(QtCore.QObject): # signal emitted when jumping jump_signal = pyqtSignal(tuple) + # signal emitted when jumping + locate_signal = pyqtSignal(tuple, str) + # close app signal close_app_signal = pyqtSignal() @@ -429,6 +432,7 @@ class App(QtCore.QObject): "global_stats": dict(), "global_tabs_detachable": True, "global_jump_ref": 'abs', + "global_locate_pt": 'bl', "global_tpdf_tmargin": 15.0, "global_tpdf_bmargin": 10.0, "global_tpdf_lmargin": 20.0, @@ -1956,6 +1960,7 @@ class App(QtCore.QObject): self.ui.menueditorigin.triggered.connect(self.on_set_origin) self.ui.menueditjump.triggered.connect(self.on_jump_to) + self.ui.menueditlocate.triggered.connect(lambda: self.on_locate(obj=self.collection.get_active())) self.ui.menuedittoggleunits.triggered.connect(self.on_toggle_units_click) self.ui.menueditselectall.triggered.connect(self.on_selectall) @@ -3241,6 +3246,7 @@ class App(QtCore.QObject): self.ui.distance_min_btn.triggered.connect(lambda: self.distance_min_tool.run(toggle=True)) self.ui.origin_btn.triggered.connect(self.on_set_origin) self.ui.jmp_btn.triggered.connect(self.on_jump_to) + self.ui.locate_btn.triggered.connect(lambda: self.on_locate(obj=self.collection.get_active())) self.ui.shell_btn.triggered.connect(self.on_toggle_shell) self.ui.new_script_btn.triggered.connect(self.on_filenewscript) @@ -3250,6 +3256,9 @@ class App(QtCore.QObject): # Tools Toolbar Signals self.ui.dblsided_btn.triggered.connect(lambda: self.dblsidedtool.run(toggle=True)) self.ui.cal_btn.triggered.connect(lambda: self.cal_exc_tool.run(toggle=True)) + self.ui.align_btn.triggered.connect(lambda: self.align_objects_tool.run(toggle=True)) + self.ui.extract_btn.triggered.connect(lambda: self.edrills_tool.run(toggle=True)) + self.ui.cutout_btn.triggered.connect(lambda: self.cutout_tool.run(toggle=True)) self.ui.ncc_btn.triggered.connect(lambda: self.ncclear_tool.run(toggle=True)) self.ui.paint_btn.triggered.connect(lambda: self.paint_tool.run(toggle=True)) @@ -7288,7 +7297,151 @@ class App(QtCore.QObject): self.jump_signal.emit(location) - units = self.defaults['units'].upper() + if fit_center: + self.plotcanvas.fit_center(loc=location) + + cursor = QtGui.QCursor() + + if self.is_legacy is False: + # I don't know where those differences come from but they are constant for the current + # execution of the application and they are multiples of a value around 0.0263mm. + # In a random way sometimes they are more sometimes they are less + # if units == 'MM': + # cal_factor = 0.0263 + # else: + # cal_factor = 0.0263 / 25.4 + + cal_location = (location[0], location[1]) + + canvas_origin = self.plotcanvas.native.mapToGlobal(QtCore.QPoint(0, 0)) + jump_loc = self.plotcanvas.translate_coords_2((cal_location[0], cal_location[1])) + + j_pos = ( + int(canvas_origin.x() + round(jump_loc[0])), + int(canvas_origin.y() + round(jump_loc[1])) + ) + cursor.setPos(j_pos[0], j_pos[1]) + else: + # find the canvas origin which is in the top left corner + canvas_origin = self.plotcanvas.native.mapToGlobal(QtCore.QPoint(0, 0)) + # determine the coordinates for the lowest left point of the canvas + x0, y0 = canvas_origin.x(), canvas_origin.y() + self.ui.right_layout.geometry().height() + + # transform the given location from data coordinates to display coordinates. THe display coordinates are + # in pixels where the origin 0,0 is in the lowest left point of the display window (in our case is the + # canvas) and the point (width, height) is in the top-right location + loc = self.plotcanvas.axes.transData.transform_point(location) + j_pos = ( + int(x0 + loc[0]), + int(y0 - loc[1]) + ) + cursor.setPos(j_pos[0], j_pos[1]) + self.plotcanvas.mouse = [location[0], location[1]] + if self.defaults["global_cursor_color_enabled"] is True: + self.plotcanvas.draw_cursor(x_pos=location[0], y_pos=location[1], color=self.cursor_color_3D) + else: + self.plotcanvas.draw_cursor(x_pos=location[0], y_pos=location[1]) + + if self.grid_status(): + # Update cursor + self.app_cursor.set_data(np.asarray([(location[0], location[1])]), + symbol='++', edge_color=self.cursor_color_3D, + edge_width=self.defaults["global_cursor_width"], + size=self.defaults["global_cursor_size"]) + + # Set the position label + self.ui.position_label.setText("    X: %.4f   " + "Y: %.4f" % (location[0], location[1])) + # Set the relative position label + dx = location[0] - float(self.rel_point1[0]) + dy = location[1] - float(self.rel_point1[1]) + self.ui.rel_position_label.setText("Dx: %.4f   Dy: " + "%.4f    " % (dx, dy)) + + self.inform.emit('[success] %s' % _("Done.")) + return location + + def on_locate(self, obj, fit_center=True): + """ + Jump to one of the corners (or center) of an object by setting the mouse cursor location + :return: + + """ + self.report_usage("on_locate()") + + if obj is None: + self.inform.emit('[WARNING_NOTCL] %s' % _("There is no object selected...")) + return 'fail' + + class DialogBoxChoice(QtWidgets.QDialog): + def __init__(self, title=None, icon=None, choice='bl'): + """ + + :param title: string with the window title + """ + super(DialogBoxChoice, self).__init__() + + self.ok = False + + self.setWindowIcon(icon) + self.setWindowTitle(str(title)) + + self.form = QtWidgets.QFormLayout(self) + + self.ref_radio = RadioSet([ + {"label": _("Bottom-Left"), "value": "bl"}, + {"label": _("Top-Left"), "value": "tl"}, + {"label": _("Bottom-Right"), "value": "br"}, + {"label": _("Top-Right"), "value": "tr"}, + {"label": _("Center"), "value": "c"} + ], orientation='vertical', stretch=False) + self.ref_radio.set_value(choice) + self.form.addRow(self.ref_radio) + + self.button_box = QtWidgets.QDialogButtonBox( + QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel, + Qt.Horizontal, parent=self) + self.form.addRow(self.button_box) + + self.button_box.accepted.connect(self.accept) + self.button_box.rejected.connect(self.reject) + + if self.exec_() == QtWidgets.QDialog.Accepted: + self.ok = True + self.location_point = self.ref_radio.get_value() + else: + self.ok = False + self.location_point = None + + dia_box = DialogBoxChoice(title=_("Locate ..."), + icon=QtGui.QIcon(self.resource_location + '/locate16.png'), + choice=self.defaults['global_locate_pt']) + + if dia_box.ok is True: + try: + location_point = dia_box.location_point + self.defaults['global_locate_pt'] = dia_box.location_point + except Exception: + return + else: + return + + loc_b = obj.bounds() + if location_point == 'bl': + location = (loc_b[0], loc_b[1]) + elif location_point == 'tl': + location = (loc_b[0], loc_b[3]) + elif location_point == 'br': + location = (loc_b[2], loc_b[1]) + elif location_point == 'tr': + location = (loc_b[2], loc_b[3]) + else: + # center + cx = loc_b[0] + ((loc_b[2] - loc_b[0]) / 2) + cy = loc_b[1] + ((loc_b[3] - loc_b[1]) / 2) + location = (cx, cy) + + self.locate_signal.emit(location, location_point) if fit_center: self.plotcanvas.fit_center(loc=location) diff --git a/README.md b/README.md index 5e49cd87..2c446e8a 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,11 @@ CAD program, and create G-Code for Isolation routing. ================================================= +15.01.2020 + +- added key shortcuts and toolbar icons for the new tools: Align Object Tool (ALT+A) and Extract Drills (ALT+I) +- added new functionality (key shortcut SHIFT+J) to locate the corners of the bounding box (and center) in a selected object + 14.01.2020 - in Extract Drill Tool added a new method of drills extraction. The methods are: fixed diameter, fixed annular ring and proportional diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index 111a9895..86974e3f 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -373,6 +373,8 @@ class FlatCAMGUI(QtWidgets.QMainWindow): QtGui.QIcon(self.app.resource_location + '/origin16.png'), _('Se&t Origin\tO')) self.menueditjump = self.menuedit.addAction( QtGui.QIcon(self.app.resource_location + '/jump_to16.png'), _('Jump to Location\tJ')) + self.menueditlocate = self.menuedit.addAction( + QtGui.QIcon(self.app.resource_location + '/locate16.png'), _('Locate in Object\tSHIFT+J')) # Separator self.menuedit.addSeparator() @@ -825,6 +827,8 @@ class FlatCAMGUI(QtWidgets.QMainWindow): QtGui.QIcon(self.app.resource_location + '/origin32.png'), _('Set Origin')) self.jmp_btn = self.toolbargeo.addAction( QtGui.QIcon(self.app.resource_location + '/jump_to16.png'), _('Jump to Location')) + self.locate_btn = self.toolbargeo.addAction( + QtGui.QIcon(self.app.resource_location + '/locate32.png'), _('Locate in Object')) # ######################################################################## # ########################## View Toolbar# ############################### @@ -859,6 +863,11 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # ######################################################################## self.dblsided_btn = self.toolbartools.addAction( QtGui.QIcon(self.app.resource_location + '/doubleside32.png'), _("2Sided Tool")) + self.align_btn = self.toolbartools.addAction( + QtGui.QIcon(self.app.resource_location + '/align32.png'), _("Align Objects Tool")) + self.extract_btn = self.toolbartools.addAction( + QtGui.QIcon(self.app.resource_location + '/extract_drill32.png'), _("Extract Drills Tool")) + self.cutout_btn = self.toolbartools.addAction( QtGui.QIcon(self.app.resource_location + '/cut16_bis.png'), _("Cutout Tool")) self.ncc_btn = self.toolbartools.addAction( @@ -1474,6 +1483,10 @@ class FlatCAMGUI(QtWidgets.QMainWindow): SHIFT+G  %s + + SHIFT+J +  %s + SHIFT+M  %s @@ -1506,6 +1519,10 @@ class FlatCAMGUI(QtWidgets.QMainWindow):     + + ALT+A +  %s + ALT+C  %s @@ -1518,6 +1535,10 @@ class FlatCAMGUI(QtWidgets.QMainWindow): ALT+E  %s + + ALT+I +  %s + ALT+J  %s @@ -1637,11 +1658,13 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # SHIFT section _("Copy Obj_Name"), - _("Toggle Code Editor"), _("Toggle the axis"), _("Distance Minimum Tool"), _("Open Preferences Window"), + _("Toggle Code Editor"), _("Toggle the axis"), _("Locate in Object"), _("Distance Minimum Tool"), + _("Open Preferences Window"), _("Rotate by 90 degree CCW"), _("Run a Script"), _("Toggle the workspace"), _("Skew on X axis"), _("Skew on Y axis"), # ALT section - _("Calculators Tool"), _("2-Sided PCB Tool"), _("Transformations Tool"), _("Fiducials Tool"), + _("Align Objects Tool"), _("Calculators Tool"), _("2-Sided PCB Tool"), _("Transformations Tool"), + _("Extract Drills Tool"), _("Fiducials Tool"), _("Solder Paste Dispensing Tool"), _("Film PCB Tool"), _("Non-Copper Clearing Tool"), _("Optimal Tool"), _("Paint Area Tool"), _("QRCode Tool"), _("Rules Check Tool"), @@ -2457,8 +2480,12 @@ class FlatCAMGUI(QtWidgets.QMainWindow): QtGui.QIcon(self.app.resource_location + '/origin32.png'), _('Set Origin')) self.jmp_btn = self.toolbargeo.addAction( QtGui.QIcon(self.app.resource_location + '/jump_to16.png'), _('Jump to Location')) + self.locate_btn = self.toolbargeo.addAction( + QtGui.QIcon(self.app.resource_location + '/locate32.png'), _('Locate in Object')) - # ## View Toolbar # ## + # ######################################################################## + # ########################## View Toolbar# ############################### + # ######################################################################## self.replot_btn = self.toolbarview.addAction( QtGui.QIcon(self.app.resource_location + '/replot32.png'), _("&Replot")) self.clear_plot_btn = self.toolbarview.addAction( @@ -2470,9 +2497,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.zoom_fit_btn = self.toolbarview.addAction( QtGui.QIcon(self.app.resource_location + '/zoom_fit32.png'), _("Zoom Fit")) - # self.toolbarview.setVisible(False) - - # ## Shell Toolbar # ## + # ######################################################################## + # ########################## Shell Toolbar# ############################## + # ######################################################################## self.shell_btn = self.toolbarshell.addAction( QtGui.QIcon(self.app.resource_location + '/shell32.png'), _("&Command Line")) self.new_script_btn = self.toolbarshell.addAction( @@ -2485,6 +2512,11 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # ## Tools Toolbar # ## self.dblsided_btn = self.toolbartools.addAction( QtGui.QIcon(self.app.resource_location + '/doubleside32.png'), _("2Sided Tool")) + self.align_btn = self.toolbartools.addAction( + QtGui.QIcon(self.app.resource_location + '/align32.png'), _("Align Objects Tool")) + self.extract_btn = self.toolbartools.addAction( + QtGui.QIcon(self.app.resource_location + '/extract_drill32.png'), _("Extract Drills Tool")) + self.cutout_btn = self.toolbartools.addAction( QtGui.QIcon(self.app.resource_location + '/cut16_bis.png'), _("&Cutout Tool")) self.ncc_btn = self.toolbartools.addAction( @@ -2498,10 +2530,13 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.film_btn = self.toolbartools.addAction( QtGui.QIcon(self.app.resource_location + '/film16.png'), _("Film Tool")) self.solder_btn = self.toolbartools.addAction( - QtGui.QIcon(self.app.resource_location + '/solderpastebis32.png'), - _("SolderPaste Tool")) + QtGui.QIcon(self.app.resource_location + '/solderpastebis32.png'), _("SolderPaste Tool")) self.sub_btn = self.toolbartools.addAction( QtGui.QIcon(self.app.resource_location + '/sub32.png'), _("Subtract Tool")) + self.rules_btn = self.toolbartools.addAction( + QtGui.QIcon(self.app.resource_location + '/rules32.png'), _("Rules Tool")) + self.optimal_btn = self.toolbartools.addAction( + QtGui.QIcon(self.app.resource_location + '/open_excellon32.png'), _("Optimal Tool")) self.toolbartools.addSeparator() @@ -2834,6 +2869,10 @@ class FlatCAMGUI(QtWidgets.QMainWindow): if key == QtCore.Qt.Key_G: self.app.on_toggle_axis() + # Locate in Object + if key == QtCore.Qt.Key_J: + self.app.on_locate(obj=self.app.collection.get_active()) + # Run Distance Minimum Tool if key == QtCore.Qt.Key_M: self.app.distance_min_tool.run() @@ -2882,6 +2921,10 @@ class FlatCAMGUI(QtWidgets.QMainWindow): if key == Qt.Key_3: self.app.disable_other_plots() + # Align in Object Tool + if key == QtCore.Qt.Key_A: + self.app.align_objects_tool.run(toggle=True) + # Calculator Tool if key == QtCore.Qt.Key_C: self.app.calculator_tool.run(toggle=True) @@ -2906,6 +2949,10 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.app.on_toggle_grid_lines() return + # Align in Object Tool + if key == QtCore.Qt.Key_I: + self.app.edrills_tool.run(toggle=True) + # Fiducials Tool if key == QtCore.Qt.Key_J: self.app.fiducial_tool.run(toggle=True) diff --git a/flatcamTools/ToolAlignObjects.py b/flatcamTools/ToolAlignObjects.py index 7368b865..d1e77442 100644 --- a/flatcamTools/ToolAlignObjects.py +++ b/flatcamTools/ToolAlignObjects.py @@ -224,7 +224,6 @@ class AlignObjects(FlatCAMTool): self.aligned_old_fill_color = None self.aligned_old_line_color = None - def run(self, toggle=True): self.app.report_usage("ToolAlignObjects()") @@ -460,50 +459,6 @@ class AlignObjects(FlatCAMTool): angle = angle_dest - angle_start self.aligned_obj.rotate(angle=angle, point=origin_pt) - def execute(self): - aligned_name = self.object_combo.currentText() - - # Get source object. - try: - aligned_obj = self.app.collection.get_by_name(str(aligned_name)) - except Exception as e: - log.debug("AlignObjects.on_align() --> %s" % str(e)) - self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), aligned_name)) - return "Could not retrieve object: %s" % aligned_name - - if aligned_obj is None: - self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Object not found"), aligned_obj)) - return "Object not found: %s" % aligned_obj - - aligner_name = self.box_combo.currentText() - - try: - aligner_obj = self.app.collection.get_by_name(aligner_name) - except Exception as e: - log.debug("AlignObjects.on_align() --> %s" % str(e)) - self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), aligner_name)) - return "Could not retrieve object: %s" % aligner_name - - if aligner_obj is None: - self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), aligner_name)) - - def align_job(): - pass - - proc = self.app.proc_container.new(_("Working...")) - - def job_thread(app_obj): - try: - align_job() - app_obj.inform.emit('[success] %s' % _("Panel created successfully.")) - except Exception as ee: - proc.done() - log.debug(str(ee)) - return - proc.done() - - self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]}) - def disconnect_cal_events(self): # restore the Grid snapping if it was active before if self.grid_status_memory is True: diff --git a/share/extract_drill16.png b/share/extract_drill16.png new file mode 100644 index 0000000000000000000000000000000000000000..4b3a29abcbd40df29de8bdf4ab9798ff03c17576 GIT binary patch literal 459 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6XVU3I`u#fXMsm#F#`je z9|$vEn-I1eC^$dBC&U#<4`#4^vYiXieWoQre!&d-Fcpb6ALp-t2BX literal 0 HcmV?d00001 diff --git a/share/extract_drill32.png b/share/extract_drill32.png new file mode 100644 index 0000000000000000000000000000000000000000..41f740f249b02779fe8d74b1ecfa69ba7e1ea76e GIT binary patch literal 745 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyjKx9jPK-BC>eK@{oCO|{#S9E= zejv>?paQ`FpAc7|h-TdC#@_ zj!4m{1f7>3Y`Mc;YdY)~4{B#&V&gCFwmJul11?V&$B>FS$q5R421bGb2hKPxezqJt87lRy2f%1PJVA5)cp;pYE{LG0015rna)S zdb5)L`UNYN^yn;D)O92<`1*w_j~)w)UA@-Wy|ATuo!sg^rTP0B7fv*cIdeqhDred= zv1wsE6^&bYXEm&q)snwD+u=Y)|Ecl~stXvHEsTmDPAw05P=0Lfp`%knIVGg?)~$PY zL$sozs`B&4pFcKjC@}u4|0cE$FL>C4e^W1y8Q*L2^CSQ40 z$*IX6OSIMppKQ2$BW00V#dg+jcYkh>&A;^P^ox0wk>P12Ql$x@)_2V|#6?$JToSW4 z;iQ7F*c#=9*VAfadKS%eIM}S5t@TUx-%j5syTqH_$Df_Qs4iXcFL{gL`*ZslCu}#p z7QiOA6c|FPC9V-ADTyViR>?)FK#IZ0z{o(?z);uFG{nHb%D}?P#84Z=Fc8n)>WZQv zH$NpatrE9}G&A0xKn;>08-nxGO3D+9QW?t2%k?tzvWt@w3sUv+i_&MmvylQSV(@hJ Kb6Mw<&;$TR7|D+S literal 0 HcmV?d00001 diff --git a/share/locate32.png b/share/locate32.png new file mode 100644 index 0000000000000000000000000000000000000000..66d630b07edd92fcc124cfdfaaef755ab35847f1 GIT binary patch literal 900 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`F}-GjPZ!UiQ@oY6|jnaSZV|zVyod?!HQi;~%Gg z+;Fz%U{sjonF*J=d=*bCbe>RAa`)>np7VhJLe6b9%L($C;YCVr773GtU4uR;tFy76 z>iKHWdh_e=@W;E^zyG~+{%=LzGfBJeC;#qU_x|g@xcjen{rWWb)pybR5ubY|e!e1V z{+sLH%|ctJPj?O0>OZvKCCq;B`n$yn6{&7d8*G~%Y&w~+V?XOb-O#D6*DEwL!e?)i z6=M0U&3s0XCEF`!@fVJ5)AP@HW$Ek)OR9dND5b?5;(U_z#d5QcU$`pR!lvAK_Dl2Q zmsOfg54O(iOx3i>>>QvQK$i zU`F!d-}4#k{6A@Ctp7ga!KA|q>-R-8A4@XYcx&!Po2~!O|Fg(xuTEP%slQ4n^+EvK z0$2a6ukJM`x8J&BdViM_+eE)xa{|B4UHN>;md4FGA7-Ch^sp^evf!X|{-^2BXk24^fuoVMch$)B&Kn;yph-gIw;-K%;r=BF)*+)u&^>V)CMsOWY_J9LD7(#pOTqYiCaU? zXO;&*4U!-mg7ec#$`gxH8OqDc^)mCai<1)zQuXqS(r3T3kpe1W@O1TaS?83{1OVCZ Bf)W4# literal 0 HcmV?d00001 From 9a9b6908bc8a73d632e183f0716b0b0069f02d94 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 15 Jan 2020 03:02:45 +0200 Subject: [PATCH 020/209] - minor changes --- FlatCAMApp.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 5324290e..dce2111f 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -141,7 +141,7 @@ class App(QtCore.QObject): # ################## Version and VERSION DATE ############################## # ########################################################################## version = 8.992 - version_date = "2020/01/02" + version_date = "2020/01/20" beta = True engine = '3D' @@ -7202,15 +7202,13 @@ class App(QtCore.QObject): obj.options['ymin'] = b obj.options['xmax'] = c obj.options['ymax'] = d - self.inform.emit('[success] %s...' % - _('Origin set')) + self.inform.emit('[success] %s...' % _('Origin set')) if noplot_sig is False: self.replot_signal.emit([]) if location is not None: if len(location) != 2: - self.inform.emit('[ERROR_NOTCL] %s...' % - _("Origin coordinates specified but incomplete.")) + self.inform.emit('[ERROR_NOTCL] %s...' % _("Origin coordinates specified but incomplete.")) return 'fail' x, y = location From f9a8d09b26441f22f04d92135937af125ba716ee Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 15 Jan 2020 17:47:28 +0200 Subject: [PATCH 021/209] - modified the NCC Tool GUI to prepare for accepting a tool from a tool database - started to modify the Paint Tool to be similar to NCC Tool and to accept a tool from a database --- FlatCAMApp.py | 6 + README.md | 2 + flatcamTools/ToolNonCopperClear.py | 148 ++++--- flatcamTools/ToolPaint.py | 631 +++++++++++++++++++++++++---- 4 files changed, 639 insertions(+), 148 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index dce2111f..e073978d 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -803,6 +803,12 @@ class App(QtCore.QObject): "tools_pathconnect": True, "tools_paintcontour": True, "tools_paint_plotting": 'normal', + "tools_paintrest": False, + "tools_painttool_type": 'V', + "tools_paintcutz": -0.05, + "tools_painttipdia": 0.1, + "tools_painttipangle": 30, + "tools_paintnewdia": 1.0, # 2-Sided Tool "tools_2sided_mirror_axis": "X", diff --git a/README.md b/README.md index 2c446e8a..f91a123c 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ CAD program, and create G-Code for Isolation routing. - added key shortcuts and toolbar icons for the new tools: Align Object Tool (ALT+A) and Extract Drills (ALT+I) - added new functionality (key shortcut SHIFT+J) to locate the corners of the bounding box (and center) in a selected object +- modified the NCC Tool GUI to prepare for accepting a tool from a tool database +- started to modify the Paint Tool to be similar to NCC Tool and to accept a tool from a database 14.01.2020 diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNonCopperClear.py index b8e365c5..5b2e8b1d 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/flatcamTools/ToolNonCopperClear.py @@ -411,7 +411,7 @@ class NonCopperClear(FlatCAMTool, Gerber): _("Draw lines between resulting\n" "segments to minimize tool lifts.") ) - self.grid3.addWidget(self.ncc_connect_cb, 16, 0, 1, 2) + self.grid3.addWidget(self.ncc_connect_cb, 16, 0) # Contour self.ncc_contour_cb = FCCheckBox('%s' % _("Contour")) @@ -421,7 +421,69 @@ class NonCopperClear(FlatCAMTool, Gerber): _("Cut around the perimeter of the polygon\n" "to trim rough edges.") ) - self.grid3.addWidget(self.ncc_contour_cb, 17, 0, 1, 2) + self.grid3.addWidget(self.ncc_contour_cb, 16, 1) + + # ## NCC Offset choice + self.ncc_choice_offset_cb = FCCheckBox('%s' % _("Offset")) + self.ncc_choice_offset_cb.setObjectName(_("Offset")) + + self.ncc_choice_offset_cb.setToolTip( + _("If used, it will add an offset to the copper features.\n" + "The copper clearing will finish to a distance\n" + "from the copper features.\n" + "The value can be between 0 and 10 FlatCAM units.") + ) + self.grid3.addWidget(self.ncc_choice_offset_cb, 19, 0) + + # ## NCC Offset value + # self.ncc_offset_label = QtWidgets.QLabel('%s:' % _("Offset value")) + # self.ncc_offset_label.setToolTip( + # _("If used, it will add an offset to the copper features.\n" + # "The copper clearing will finish to a distance\n" + # "from the copper features.\n" + # "The value can be between 0 and 10 FlatCAM units.") + # ) + self.ncc_offset_spinner = FCDoubleSpinner() + self.ncc_offset_spinner.set_range(0.00, 10.00) + self.ncc_offset_spinner.set_precision(4) + self.ncc_offset_spinner.setWrapping(True) + self.ncc_offset_spinner.setObjectName(_("Offset value")) + + units = self.app.defaults['units'].upper() + if units == 'MM': + self.ncc_offset_spinner.setSingleStep(0.1) + else: + self.ncc_offset_spinner.setSingleStep(0.01) + + # self.grid3.addWidget(self.ncc_offset_label, 20, 0) + self.grid3.addWidget(self.ncc_offset_spinner, 19, 1) + + # self.ncc_offset_label.hide() + self.ncc_offset_spinner.setEnabled(False) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + self.grid3.addWidget(separator_line, 21, 0, 1, 2) + + self.apply_param_to_all = FCButton(_("Apply parameters to all tools")) + self.apply_param_to_all.setToolTip( + _("The parameters in the current form will be applied\n" + "on all the tools from the Tool Table.") + ) + self.grid3.addWidget(self.apply_param_to_all, 22, 0, 1, 2) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + self.grid3.addWidget(separator_line, 23, 0, 1, 2) + + # General Parameters + self.gen_param_label = QtWidgets.QLabel('%s' % _("Common Parameters")) + self.gen_param_label.setToolTip( + _("Parameters that are common for all tools.") + ) + self.grid3.addWidget(self.gen_param_label, 24, 0, 1, 2) # Rest Machining self.ncc_rest_cb = FCCheckBox('%s' % _("Rest Machining")) @@ -437,51 +499,13 @@ class NonCopperClear(FlatCAMTool, Gerber): "If not checked, use the standard algorithm.") ) - self.grid3.addWidget(self.ncc_rest_cb, 18, 0, 1, 2) - - # ## NCC Offset choice - self.ncc_choice_offset_cb = FCCheckBox('%s' % _("Offset")) - self.ncc_choice_offset_cb.setObjectName(_("Offset")) - - self.ncc_choice_offset_cb.setToolTip( - _("If used, it will add an offset to the copper features.\n" - "The copper clearing will finish to a distance\n" - "from the copper features.\n" - "The value can be between 0 and 10 FlatCAM units.") - ) - self.grid3.addWidget(self.ncc_choice_offset_cb, 19, 0, 1, 2) - - # ## NCC Offset value - self.ncc_offset_label = QtWidgets.QLabel('%s:' % _("Offset value")) - self.ncc_offset_label.setToolTip( - _("If used, it will add an offset to the copper features.\n" - "The copper clearing will finish to a distance\n" - "from the copper features.\n" - "The value can be between 0 and 10 FlatCAM units.") - ) - self.ncc_offset_spinner = FCDoubleSpinner() - self.ncc_offset_spinner.set_range(0.00, 10.00) - self.ncc_offset_spinner.set_precision(4) - self.ncc_offset_spinner.setWrapping(True) - self.ncc_offset_spinner.setObjectName(_("Offset value")) - - units = self.app.defaults['units'].upper() - if units == 'MM': - self.ncc_offset_spinner.setSingleStep(0.1) - else: - self.ncc_offset_spinner.setSingleStep(0.01) - - self.grid3.addWidget(self.ncc_offset_label, 20, 0) - self.grid3.addWidget(self.ncc_offset_spinner, 20, 1) - - self.ncc_offset_label.hide() - self.ncc_offset_spinner.hide() + self.grid3.addWidget(self.ncc_rest_cb, 25, 0, 1, 2) # ## Reference self.reference_radio = RadioSet([ {'label': _('Itself'), 'value': 'itself'}, {"label": _("Area Selection"), "value": "area"}, - {'label': _("Reference Object"), 'value': 'box'} + {'label': _("Reference Object"), 'value': 'box'} ], orientation='vertical', stretch=False) self.reference_radio.setObjectName(_("Reference")) @@ -491,11 +515,11 @@ class NonCopperClear(FlatCAMTool, Gerber): "- 'Area Selection' - left mouse click to start selection of the area to be painted.\n" "- 'Reference Object' - will do non copper clearing within the area specified by another object.") ) - self.grid3.addWidget(self.reference_label, 21, 0) - self.grid3.addWidget(self.reference_radio, 21, 1) + self.grid3.addWidget(self.reference_label, 26, 0, 1, 2) + self.grid3.addWidget(self.reference_radio, 27, 0, 1, 2) form1 = QtWidgets.QFormLayout() - self.grid3.addLayout(form1, 22, 0, 1, 2) + self.grid3.addLayout(form1, 28, 0, 1, 2) self.box_combo_type_label = QtWidgets.QLabel('%s:' % _("Ref. Type")) self.box_combo_type_label.setToolTip( @@ -523,17 +547,10 @@ class NonCopperClear(FlatCAMTool, Gerber): self.box_combo_type.hide() self.box_combo_type_label.hide() - separator_line2 = QtWidgets.QFrame() - separator_line2.setFrameShape(QtWidgets.QFrame.HLine) - separator_line2.setFrameShadow(QtWidgets.QFrame.Sunken) - self.grid3.addWidget(separator_line2, 23, 0, 1, 2) - - self.apply_param_to_all = FCButton(_("Apply parameters to all tools")) - self.apply_param_to_all.setToolTip( - _("The parameters in the current form will be applied\n" - "on all the tools from the Tool Table.") - ) - self.grid3.addWidget(self.apply_param_to_all, 24, 0, 1, 2) + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + self.grid3.addWidget(separator_line, 29, 0, 1, 2) self.generate_ncc_button = QtWidgets.QPushButton(_('Generate Geometry')) self.generate_ncc_button.setToolTip( @@ -630,10 +647,8 @@ class NonCopperClear(FlatCAMTool, Gerber): "nccmethod": self.ncc_method_radio, "nccconnect": self.ncc_connect_cb, "ncccontour": self.ncc_contour_cb, - "nccrest": self.ncc_rest_cb, "nccoffset": self.ncc_choice_offset_cb, "nccoffset_value": self.ncc_offset_spinner, - "nccref": self.reference_radio, "milling_type": self.milling_type_radio } @@ -643,10 +658,8 @@ class NonCopperClear(FlatCAMTool, Gerber): _('Method'): "nccmethod", _("Connect"): "nccconnect", _("Contour"): "ncccontour", - _("Rest Machining"): "nccrest", _("Offset"): "nccoffset", _("Offset value"): "nccoffset_value", - _("Reference"): "nccref", _('Milling Type'): "milling_type", } @@ -720,7 +733,7 @@ class NonCopperClear(FlatCAMTool, Gerber): form_value_storage = tooluid_value[key] self.storage_to_form(form_value_storage) except Exception as e: - log.debug("FlatCAMObj ---> update_ui() " + str(e)) + log.debug("NonCopperClear ---> update_ui() " + str(e)) self.blockSignals(False) @@ -1164,12 +1177,13 @@ class NonCopperClear(FlatCAMTool, Gerber): self.box_combo_type_label.show() def on_offset_choice(self, state): - if state: - self.ncc_offset_label.show() - self.ncc_offset_spinner.show() - else: - self.ncc_offset_label.hide() - self.ncc_offset_spinner.hide() + # if state: + # self.ncc_offset_label.show() + # self.ncc_offset_spinner.show() + # else: + # self.ncc_offset_label.hide() + # self.ncc_offset_spinner.hide() + self.ncc_offset_spinner.setEnabled(state) def on_order_changed(self, order): if order != 'no': diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 91dee46f..95fc26e7 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -14,13 +14,14 @@ from copy import deepcopy from flatcamParsers.ParseGerber import Gerber from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry from camlib import Geometry -from flatcamGUI.GUIElements import FCTable, FCDoubleSpinner, FCCheckBox, FCInputDialog, RadioSet +from flatcamGUI.GUIElements import FCTable, FCDoubleSpinner, FCCheckBox, FCInputDialog, RadioSet, FCButton import FlatCAMApp from shapely.geometry import base, Polygon, MultiPolygon, LinearRing from shapely.ops import cascaded_union import numpy as np +import math from numpy import Inf import traceback import logging @@ -66,8 +67,10 @@ class ToolPaint(FlatCAMTool, Gerber): self.tools_frame.setLayout(self.tools_box) # ## Form Layout - form_layout = QtWidgets.QFormLayout() - self.tools_box.addLayout(form_layout) + grid0 = QtWidgets.QGridLayout() + grid0.setColumnStretch(0, 0) + grid0.setColumnStretch(1, 1) + self.tools_box.addLayout(grid0) # ################################################ # ##### Type of object to be painted ############# @@ -90,7 +93,8 @@ class ToolPaint(FlatCAMTool, Gerber): "of objects that will populate the 'Object' combobox.") ) self.type_obj_combo_label.setMinimumWidth(60) - form_layout.addRow(self.type_obj_combo_label, self.type_obj_combo) + grid0.addWidget(self.type_obj_combo_label, 1, 0) + grid0.addWidget(self.type_obj_combo, 1, 1) # ################################################ # ##### The object to be painted ################# @@ -103,10 +107,13 @@ class ToolPaint(FlatCAMTool, Gerber): self.object_label = QtWidgets.QLabel('%s:' % _("Object")) self.object_label.setToolTip(_("Object to be painted.")) - form_layout.addRow(self.object_label, self.obj_combo) + grid0.addWidget(self.object_label, 2, 0) + grid0.addWidget(self.obj_combo, 2, 1) - e_lab_0 = QtWidgets.QLabel('') - form_layout.addRow(e_lab_0) + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(separator_line, 5, 0, 1, 2) # ### Tools ## ## self.tools_table_label = QtWidgets.QLabel('%s' % _('Tools Table')) @@ -114,10 +121,11 @@ class ToolPaint(FlatCAMTool, Gerber): _("Tools pool from which the algorithm\n" "will pick the ones used for painting.") ) - self.tools_box.addWidget(self.tools_table_label) self.tools_table = FCTable() - self.tools_box.addWidget(self.tools_table) + + grid0.addWidget(self.tools_table_label, 6, 0, 1, 2) + grid0.addWidget(self.tools_table, 7, 0, 1, 2) self.tools_table.setColumnCount(4) self.tools_table.setHorizontalHeaderLabels(['#', _('Diameter'), _('TT'), '']) @@ -167,23 +175,107 @@ class ToolPaint(FlatCAMTool, Gerber): "'Reverse' --> menas that the tools will ordered from big to small\n\n" "WARNING: using rest machining will automatically set the order\n" "in reverse and disable this control.")) - form = QtWidgets.QFormLayout() - self.tools_box.addLayout(form) - form.addRow(QtWidgets.QLabel(''), QtWidgets.QLabel('')) - form.addRow(self.order_label, self.order_radio) - # ### Add a new Tool ## ## + grid0.addWidget(self.order_label, 9, 0) + grid0.addWidget(self.order_radio, 9, 1) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(separator_line, 10, 0, 1, 2) + + self.grid3 = QtWidgets.QGridLayout() + self.tools_box.addLayout(self.grid3) + self.grid3.setColumnStretch(0, 0) + self.grid3.setColumnStretch(1, 1) + + # ############################################################################## + # ###################### ADD A NEW TOOL ######################################## + # ############################################################################## + self.tool_sel_label = QtWidgets.QLabel('%s' % _("New Tool")) + self.grid3.addWidget(self.tool_sel_label, 1, 0, 1, 2) + + # Tool Type Radio Button + self.tool_type_label = QtWidgets.QLabel('%s:' % _('Tool Type')) + self.tool_type_label.setToolTip( + _("Default tool type:\n" + "- 'V-shape'\n" + "- Circular") + ) + + self.tool_type_radio = RadioSet([{'label': _('V-shape'), 'value': 'V'}, + {'label': _('Circular'), 'value': 'C1'}]) + self.tool_type_radio.setToolTip( + _("Default tool type:\n" + "- 'V-shape'\n" + "- Circular") + ) + self.tool_type_radio.setObjectName(_("Tool Type")) + + self.grid3.addWidget(self.tool_type_label, 2, 0) + self.grid3.addWidget(self.tool_type_radio, 2, 1) + + # Tip Dia + self.tipdialabel = QtWidgets.QLabel('%s:' % _('V-Tip Dia')) + self.tipdialabel.setToolTip( + _("The tip diameter for V-Shape Tool")) + self.tipdia_entry = FCDoubleSpinner() + self.tipdia_entry.set_precision(self.decimals) + self.tipdia_entry.set_range(0.0000, 9999.9999) + self.tipdia_entry.setSingleStep(0.1) + self.tipdia_entry.setObjectName(_("V-Tip Dia")) + + self.grid3.addWidget(self.tipdialabel, 3, 0) + self.grid3.addWidget(self.tipdia_entry, 3, 1) + + # Tip Angle + self.tipanglelabel = QtWidgets.QLabel('%s:' % _('V-Tip Angle')) + self.tipanglelabel.setToolTip( + _("The tip angle for V-Shape Tool.\n" + "In degree.")) + self.tipangle_entry = FCDoubleSpinner() + self.tipangle_entry.set_precision(self.decimals) + self.tipangle_entry.set_range(0.0000, 180.0000) + self.tipangle_entry.setSingleStep(5) + self.tipangle_entry.setObjectName(_("V-Tip Angle")) + + self.grid3.addWidget(self.tipanglelabel, 4, 0) + self.grid3.addWidget(self.tipangle_entry, 4, 1) + + # Cut Z entry + cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z')) + cutzlabel.setToolTip( + _("Depth of cut into material. Negative value.\n" + "In FlatCAM units.") + ) + self.cutz_entry = FCDoubleSpinner() + self.cutz_entry.set_precision(self.decimals) + self.cutz_entry.set_range(-99999.9999, 0.0000) + self.cutz_entry.setObjectName(_("Cut Z")) + + self.cutz_entry.setToolTip( + _("Depth of cut into material. Negative value.\n" + "In FlatCAM units.") + ) + self.grid3.addWidget(cutzlabel, 5, 0) + self.grid3.addWidget(self.cutz_entry, 5, 1) + + # ### Tool Diameter #### self.addtool_entry_lbl = QtWidgets.QLabel('%s:' % _('Tool Dia')) self.addtool_entry_lbl.setToolTip( - _("Diameter for the new tool.") + _("Diameter for the new tool to add in the Tool Table.\n" + "If the tool is V-shape type then this value is automatically\n" + "calculated from the other parameters.") ) self.addtool_entry = FCDoubleSpinner() self.addtool_entry.set_precision(self.decimals) + self.addtool_entry.set_range(0.000, 9999.9999) + self.addtool_entry.setObjectName(_("Tool Dia")) - form.addRow(self.addtool_entry_lbl, self.addtool_entry) + self.grid3.addWidget(self.addtool_entry_lbl, 6, 0) + self.grid3.addWidget(self.addtool_entry, 6, 1) - grid2 = QtWidgets.QGridLayout() - self.tools_box.addLayout(grid2) + hlay = QtWidgets.QHBoxLayout() self.addtool_btn = QtWidgets.QPushButton(_('Add')) self.addtool_btn.setToolTip( @@ -191,29 +283,50 @@ class ToolPaint(FlatCAMTool, Gerber): "with the diameter specified above.") ) - # self.copytool_btn = QtWidgets.QPushButton('Copy') - # self.copytool_btn.setToolTip( - # "Copy a selection of tools in the Tool Table\n" - # "by first selecting a row in the Tool Table." - # ) + self.addtool_from_db_btn = QtWidgets.QPushButton(_('Add from DB')) + self.addtool_from_db_btn.setToolTip( + _("Add a new tool to the Tool Table\n" + "from the Tool DataBase.") + ) + + hlay.addWidget(self.addtool_btn) + hlay.addWidget(self.addtool_from_db_btn) + + self.grid3.addLayout(hlay, 7, 0, 1, 2) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + self.grid3.addWidget(separator_line, 8, 0, 1, 2) self.deltool_btn = QtWidgets.QPushButton(_('Delete')) self.deltool_btn.setToolTip( _("Delete a selection of tools in the Tool Table\n" "by first selecting a row(s) in the Tool Table.") ) + self.grid3.addWidget(self.deltool_btn, 9, 0, 1, 2) - grid2.addWidget(self.addtool_btn, 0, 0) - # grid2.addWidget(self.copytool_btn, 0, 1) - grid2.addWidget(self.deltool_btn, 0, 2) + self.grid3.addWidget(QtWidgets.QLabel(''), 10, 0, 1, 2) - self.empty_label_0 = QtWidgets.QLabel('') - self.tools_box.addWidget(self.empty_label_0) + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + self.grid3.addWidget(separator_line, 11, 0, 1, 2) - grid3 = QtWidgets.QGridLayout() - self.tools_box.addLayout(grid3) - grid3.setColumnStretch(0, 0) - grid3.setColumnStretch(1, 1) + self.tool_data_label = QtWidgets.QLabel( + "%s: %s %d" % (_('Parameters for'), _("Tool"), int(1))) + self.tool_data_label.setToolTip( + _( + "The data used for creating GCode.\n" + "Each tool store it's own set of such data." + ) + ) + self.grid3.addWidget(self.tool_data_label, 12, 0, 1, 2) + + grid4 = QtWidgets.QGridLayout() + grid4.setColumnStretch(0, 0) + grid4.setColumnStretch(1, 1) + self.tools_box.addLayout(grid4) # Overlap ovlabel = QtWidgets.QLabel('%s:' % _('Overlap Rate')) @@ -231,8 +344,10 @@ class ToolPaint(FlatCAMTool, Gerber): self.paintoverlap_entry.setWrapping(True) self.paintoverlap_entry.setRange(0.0000, 99.9999) self.paintoverlap_entry.setSingleStep(0.1) - grid3.addWidget(ovlabel, 1, 0) - grid3.addWidget(self.paintoverlap_entry, 1, 1) + self.paintoverlap_entry.setObjectName(_("Overlap Rate")) + + grid4.addWidget(ovlabel, 1, 0) + grid4.addWidget(self.paintoverlap_entry, 1, 1) # Margin marginlabel = QtWidgets.QLabel('%s:' % _('Margin')) @@ -241,11 +356,12 @@ class ToolPaint(FlatCAMTool, Gerber): "the edges of the polygon to\n" "be painted.") ) - grid3.addWidget(marginlabel, 2, 0) self.paintmargin_entry = FCDoubleSpinner() self.paintmargin_entry.set_precision(self.decimals) + self.paintmargin_entry.setObjectName(_("Margin")) - grid3.addWidget(self.paintmargin_entry, 2, 1) + grid4.addWidget(marginlabel, 2, 0) + grid4.addWidget(self.paintmargin_entry, 2, 1) # Method methodlabel = QtWidgets.QLabel('%s:' % _('Method')) @@ -255,30 +371,60 @@ class ToolPaint(FlatCAMTool, Gerber): "- Seed-based: Outwards from seed.\n" "- Line-based: Parallel lines.") ) - grid3.addWidget(methodlabel, 3, 0) self.paintmethod_combo = RadioSet([ {"label": _("Standard"), "value": "standard"}, {"label": _("Seed-based"), "value": "seed"}, {"label": _("Straight lines"), "value": "lines"} ], orientation='vertical', stretch=False) - grid3.addWidget(self.paintmethod_combo, 3, 1) + self.paintmethod_combo.setObjectName(_("Method")) + + grid4.addWidget(methodlabel, 3, 0) + grid4.addWidget(self.paintmethod_combo, 3, 1) # Connect lines self.pathconnect_cb = FCCheckBox('%s' % _("Connect")) + self.pathconnect_cb.setObjectName(_("Connect")) self.pathconnect_cb.setToolTip( _("Draw lines between resulting\n" "segments to minimize tool lifts.") ) - grid3.addWidget(self.pathconnect_cb, 4, 0, 1, 2) self.paintcontour_cb = FCCheckBox('%s' % _("Contour")) + self.paintcontour_cb.setObjectName(_("Contour")) self.paintcontour_cb.setToolTip( _("Cut around the perimeter of the polygon\n" "to trim rough edges.") ) - grid3.addWidget(self.paintcontour_cb, 5, 0, 1, 2) + + grid4.addWidget(self.pathconnect_cb, 4, 0) + grid4.addWidget(self.paintcontour_cb, 4, 1) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid4.addWidget(separator_line, 5, 0, 1, 2) + + self.apply_param_to_all = FCButton(_("Apply parameters to all tools")) + self.apply_param_to_all.setToolTip( + _("The parameters in the current form will be applied\n" + "on all the tools from the Tool Table.") + ) + grid4.addWidget(self.apply_param_to_all, 7, 0, 1, 2) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid4.addWidget(separator_line, 8, 0, 1, 2) + + # General Parameters + self.gen_param_label = QtWidgets.QLabel('%s' % _("Common Parameters")) + self.gen_param_label.setToolTip( + _("Parameters that are common for all tools.") + ) + grid4.addWidget(self.gen_param_label, 10, 0, 1, 2) self.rest_cb = FCCheckBox('%s' % _("Rest Machining")) + self.rest_cb.setObjectName(_("Rest Machining")) self.rest_cb.setToolTip( _("If checked, use 'rest machining'.\n" "Basically it will clear copper outside PCB features,\n" @@ -288,7 +434,7 @@ class ToolPaint(FlatCAMTool, Gerber): "no more copper to clear or there are no more tools.\n\n" "If not checked, use the standard algorithm.") ) - grid3.addWidget(self.rest_cb, 6, 0, 1, 2) + grid4.addWidget(self.rest_cb, 11, 0, 1, 2) # Polygon selection selectlabel = QtWidgets.QLabel('%s:' % _('Selection')) @@ -301,7 +447,7 @@ class ToolPaint(FlatCAMTool, Gerber): "- 'Reference Object' - will do non copper clearing within the area\n" "specified by another object.") ) - grid3.addWidget(selectlabel, 7, 0) + # grid3 = QtWidgets.QGridLayout() self.selectmethod_combo = RadioSet([ {"label": _("Polygon Selection"), "value": "single"}, @@ -309,6 +455,7 @@ class ToolPaint(FlatCAMTool, Gerber): {"label": _("All Polygons"), "value": "all"}, {"label": _("Reference Object"), "value": "ref"} ], orientation='vertical', stretch=False) + self.selectmethod_combo.setObjectName(_("Selection")) self.selectmethod_combo.setToolTip( _("How to select Polygons to be painted.\n" "- 'Polygon Selection' - left mouse click to add/remove polygons to be painted.\n" @@ -318,10 +465,12 @@ class ToolPaint(FlatCAMTool, Gerber): "- 'Reference Object' - will do non copper clearing within the area\n" "specified by another object.") ) - grid3.addWidget(self.selectmethod_combo, 7, 1) + + grid4.addWidget(selectlabel, 13, 0, 1, 2) + grid4.addWidget(self.selectmethod_combo, 14, 0, 1, 2) form1 = QtWidgets.QFormLayout() - self.tools_box.addLayout(form1) + grid4.addLayout(form1, 15, 0, 1, 2) self.box_combo_type_label = QtWidgets.QLabel('%s:' % _("Ref. Type")) self.box_combo_type_label.setToolTip( @@ -350,7 +499,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.box_combo_type_label.hide() # GO Button - self.generate_paint_button = QtWidgets.QPushButton(_('Create Paint Geometry')) + self.generate_paint_button = QtWidgets.QPushButton(_('Generate Geometry')) self.generate_paint_button.setToolTip( _("- 'Area Selection' - left mouse click to start selection of the area to be painted.\n" "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple areas.\n" @@ -381,8 +530,28 @@ class ToolPaint(FlatCAMTool, Gerber): """) self.tools_box.addWidget(self.reset_button) - # #################################### FINSIHED GUI ##################################### - # ####################################################################################### + # #################################### FINSIHED GUI ########################### + # ############################################################################# + + # ############################################################################# + # ###################### Setup CONTEXT MENU ################################### + # ############################################################################# + self.tools_table.setupContextMenu() + self.tools_table.addContextMenu( + _("Add"), self.on_add_tool_by_key, icon=QtGui.QIcon(self.app.resource_location + "/plus16.png") + ) + self.tools_table.addContextMenu( + _("Add from DB"), self.on_add_tool_by_key, icon=QtGui.QIcon(self.app.resource_location + "/plus16.png") + ) + self.tools_table.addContextMenu( + _("Delete"), lambda: + self.on_tool_delete(rows_to_delete=None, all_tools=None), + icon=QtGui.QIcon(self.app.resource_location + "/delete32.png") + ) + + # ############################################################################# + # ########################## VARIABLES ######################################## + # ############################################################################# self.obj_name = "" self.paint_obj = None @@ -422,8 +591,8 @@ class ToolPaint(FlatCAMTool, Gerber): "name": '_paint', "plot": self.app.defaults["geometry_plot"], "cutz": self.app.defaults["geometry_cutz"], - "vtipdia": 0.1, - "vtipangle": 30, + "vtipdia": float(self.tipdia_entry.get_value()), + "vtipangle": float(self.tipangle_entry.get_value()), "travelz": self.app.defaults["geometry_travelz"], "feedrate": self.app.defaults["geometry_feedrate"], "feedrate_z": self.app.defaults["geometry_feedrate_z"], @@ -448,19 +617,43 @@ class ToolPaint(FlatCAMTool, Gerber): "selectmethod": self.app.defaults["tools_selectmethod"], "pathconnect": self.app.defaults["tools_pathconnect"], "paintcontour": self.app.defaults["tools_paintcontour"], - "paintoverlap": self.app.defaults["tools_paintoverlap"] + "paintoverlap": self.app.defaults["tools_paintoverlap"], + "paintrest": self.app.defaults["tools_paintrest"], }) self.tool_type_item_options = ["C1", "C2", "C3", "C4", "B", "V"] + self.form_fields = { + "paintoverlap": self.paintoverlap_entry, + "paintmargin": self.paintmargin_entry, + "paintmethod": self.paintmethod_combo, + "pathconnect": self.pathconnect_cb, + "paintcontour": self.paintcontour_cb, + } + + self.name2option = { + _('Overlap Rate'): "paintoverlap", + _('Margin'): "paintmargin", + _('Method'): "paintmethod", + _("Connect"): "pathconnect", + _("Contour"): "paintcontour", + } + # ############################################################################# # ################################# Signals ################################### # ############################################################################# self.addtool_btn.clicked.connect(self.on_tool_add) self.addtool_entry.returnPressed.connect(self.on_tool_add) - # self.copytool_btn.clicked.connect(lambda: self.on_tool_copy()) - self.tools_table.itemChanged.connect(self.on_tool_edit) self.deltool_btn.clicked.connect(self.on_tool_delete) + + self.tipdia_entry.returnPressed.connect(self.on_calculate_tooldia) + self.tipangle_entry.returnPressed.connect(self.on_calculate_tooldia) + self.cutz_entry.returnPressed.connect(self.on_calculate_tooldia) + + # self.copytool_btn.clicked.connect(lambda: self.on_tool_copy()) + # self.tools_table.itemChanged.connect(self.on_tool_edit) + self.tools_table.currentItemChanged.connect(self.on_row_selection_change) + self.generate_paint_button.clicked.connect(self.on_paint_button_click) self.selectmethod_combo.activated_custom.connect(self.on_radio_selection) self.order_radio.activated_custom[str].connect(self.on_order_changed) @@ -489,22 +682,6 @@ class ToolPaint(FlatCAMTool, Gerber): def install(self, icon=None, separator=None, **kwargs): FlatCAMTool.install(self, icon, separator, shortcut='ALT+P', **kwargs) - def on_add_tool_by_key(self): - tool_add_popup = FCInputDialog(title='%s...' % _("New Tool"), - text='%s:' % _('Enter a Tool Diameter'), - min=0.0000, max=99.9999, decimals=4) - tool_add_popup.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/letter_t_32.png')) - - val, ok = tool_add_popup.get_value() - if ok: - if float(val) == 0: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Please enter a tool diameter with non-zero value, in Float format.")) - return - self.on_tool_add(dia=float(val)) - else: - self.app.inform.emit('[WARNING_NOTCL] %s...' % _("Adding Tool cancelled")) - def run(self, toggle=True): self.app.report_usage("ToolPaint()") @@ -532,16 +709,203 @@ class ToolPaint(FlatCAMTool, Gerber): self.app.ui.notebook.setTabText(2, _("Paint Tool")) - def reset_usage(self): - self.obj_name = "" - self.paint_obj = None - self.bound_obj = None + def on_row_selection_change(self): + self.update_ui() - self.first_click = False - self.cursor_pos = None - self.mouse_is_dragging = False + def update_ui(self, row=None): + self.blockSignals(True) - self.sel_rect = [] + if row is None: + try: + current_row = self.tools_table.currentRow() + except Exception: + current_row = 0 + else: + current_row = row + + if current_row < 0: + current_row = 0 + + # populate the form with the data from the tool associated with the row parameter + try: + item = self.tools_table.item(current_row, 3) + if item is not None: + tooluid = int(item.text()) + else: + return + except Exception as e: + log.debug("Tool missing. Add a tool in the Tool Table. %s" % str(e)) + return + + # update the QLabel that shows for which Tool we have the parameters in the UI form + self.tool_data_label.setText( + "%s: %s %d" % (_('Parameters for'), _("Tool"), (current_row + 1)) + ) + + try: + # set the form with data from the newly selected tool + for tooluid_key, tooluid_value in list(self.paint_tools.items()): + if int(tooluid_key) == tooluid: + for key, value in tooluid_value.items(): + if key == 'data': + form_value_storage = tooluid_value[key] + self.storage_to_form(form_value_storage) + except Exception as e: + log.debug("ToolPaint ---> update_ui() " + str(e)) + + self.blockSignals(False) + + def storage_to_form(self, dict_storage): + for form_key in self.form_fields: + for storage_key in dict_storage: + if form_key == storage_key: + try: + self.form_fields[form_key].set_value(dict_storage[form_key]) + except Exception: + pass + + def form_to_storage(self): + if self.tools_table.rowCount() == 0: + # there is no tool in tool table so we can't save the GUI elements values to storage + return + + self.blockSignals(True) + + widget_changed = self.sender() + wdg_objname = widget_changed.objectName() + option_changed = self.name2option[wdg_objname] + + row = self.tools_table.currentRow() + if row < 0: + row = 0 + tooluid_item = int(self.tools_table.item(row, 3).text()) + + for tooluid_key, tooluid_val in self.paint_tools.items(): + if int(tooluid_key) == tooluid_item: + new_option_value = self.form_fields[option_changed].get_value() + if option_changed in tooluid_val: + tooluid_val[option_changed] = new_option_value + if option_changed in tooluid_val['data']: + tooluid_val['data'][option_changed] = new_option_value + + self.blockSignals(False) + + def on_apply_param_to_all_clicked(self): + if self.tools_table.rowCount() == 0: + # there is no tool in tool table so we can't save the GUI elements values to storage + log.debug("NonCopperClear.on_apply_param_to_all_clicked() --> no tool in Tools Table, aborting.") + return + + self.blockSignals(True) + + row = self.tools_table.currentRow() + if row < 0: + row = 0 + + # this new dict will hold the actual useful data, another dict that is the value of key 'data' + temp_tools = {} + temp_dia = {} + temp_data = {} + + for tooluid_key, tooluid_value in self.paint_tools.items(): + for key, value in tooluid_value.items(): + if key == 'data': + # update the 'data' section + for data_key in tooluid_value[key].keys(): + for form_key, form_value in self.form_fields.items(): + if form_key == data_key: + temp_data[data_key] = form_value.get_value() + # make sure we make a copy of the keys not in the form (we may use 'data' keys that are + # updated from self.app.defaults + if data_key not in self.form_fields: + temp_data[data_key] = value[data_key] + temp_dia[key] = deepcopy(temp_data) + temp_data.clear() + + elif key == 'solid_geometry': + temp_dia[key] = deepcopy(self.tools[tooluid_key]['solid_geometry']) + else: + temp_dia[key] = deepcopy(value) + + temp_tools[tooluid_key] = deepcopy(temp_dia) + + self.paint_tools.clear() + self.paint_tools = deepcopy(temp_tools) + temp_tools.clear() + + self.blockSignals(False) + + def on_add_tool_by_key(self): + tool_add_popup = FCInputDialog(title='%s...' % _("New Tool"), + text='%s:' % _('Enter a Tool Diameter'), + min=0.0000, max=99.9999, decimals=4) + tool_add_popup.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/letter_t_32.png')) + + val, ok = tool_add_popup.get_value() + if ok: + if float(val) == 0: + self.app.inform.emit('[WARNING_NOTCL] %s' % + _("Please enter a tool diameter with non-zero value, in Float format.")) + return + self.on_tool_add(dia=float(val)) + else: + self.app.inform.emit('[WARNING_NOTCL] %s...' % _("Adding Tool cancelled")) + + def on_tooltable_cellwidget_change(self): + cw = self.sender() + cw_index = self.tools_table.indexAt(cw.pos()) + cw_row = cw_index.row() + cw_col = cw_index.column() + + current_uid = int(self.tools_table.item(cw_row, 3).text()) + + # if the sender is in the column with index 2 then we update the tool_type key + if cw_col == 2: + tt = cw.currentText() + typ = 'Iso' if tt == 'V' else "Rough" + + self.paint_tools[current_uid].update({ + 'type': typ, + 'tool_type': tt, + }) + + def on_tool_type(self, val): + if val == 'V': + self.addtool_entry_lbl.setDisabled(True) + self.addtool_entry.setDisabled(True) + self.tipdialabel.show() + self.tipdia_entry.show() + self.tipanglelabel.show() + self.tipangle_entry.show() + else: + self.addtool_entry_lbl.setDisabled(False) + self.addtool_entry.setDisabled(False) + self.tipdialabel.hide() + self.tipdia_entry.hide() + self.tipanglelabel.hide() + self.tipangle_entry.hide() + + def on_calculate_tooldia(self): + if self.tool_type_radio.get_value() == 'V': + tip_dia = float(self.tipdia_entry.get_value()) + tip_angle = float(self.tipangle_entry.get_value()) / 2.0 + cut_z = float(self.cutz_entry.get_value()) + cut_z = -cut_z if cut_z < 0 else cut_z + + # calculated tool diameter so the cut_z parameter is obeyed + tool_dia = tip_dia + (2 * cut_z * math.tan(math.radians(tip_angle))) + + # update the default_data so it is used in the ncc_tools dict + self.default_data.update({ + "vtipdia": tip_dia, + "vtipangle": (tip_angle * 2), + }) + + self.addtool_entry.set_value(tool_dia) + + return tool_dia + else: + return float(self.addtool_entry.get_value()) def on_radio_selection(self): if self.selectmethod_combo.get_value() == "ref": @@ -596,6 +960,14 @@ class ToolPaint(FlatCAMTool, Gerber): self.paintcontour_cb.set_value(self.default_data["paintcontour"]) self.paintoverlap_entry.set_value(self.default_data["paintoverlap"]) + self.cutz_entry.set_value(self.app.defaults["tools_paintcutz"]) + self.tool_type_radio.set_value(self.app.defaults["tools_painttool_type"]) + self.tipdia_entry.set_value(self.app.defaults["tools_painttipdia"]) + self.tipangle_entry.set_value(self.app.defaults["tools_painttipangle"]) + self.addtool_entry.set_value(self.app.defaults["tools_paintnewdia"]) + + self.on_tool_type(val=self.tool_type_radio.get_value()) + # make the default object type, "Geometry" self.type_obj_combo.setCurrentIndex(2) # updated units @@ -610,8 +982,8 @@ class ToolPaint(FlatCAMTool, Gerber): "name": '_paint', "plot": self.app.defaults["geometry_plot"], "cutz": float(self.app.defaults["geometry_cutz"]), - "vtipdia": 0.1, - "vtipangle": 30, + "vtipdia": float(self.tipdia_entry.get_value()), + "vtipangle": float(self.tipangle_entry.get_value()), "travelz": float(self.app.defaults["geometry_travelz"]), "feedrate": float(self.app.defaults["geometry_feedrate"]), "feedrate_z": float(self.app.defaults["geometry_feedrate_z"]), @@ -1077,9 +1449,7 @@ class ToolPaint(FlatCAMTool, Gerber): try: self.bound_obj = self.app.collection.get_by_name(self.bound_obj_name) except Exception as e: - self.app.inform.emit('[ERROR_NOTCL] %s: %s' % - (_("Could not retrieve object"), - self.obj_name)) + self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), self.obj_name)) return "Could not retrieve object: %s" % self.obj_name self.paint_poly_ref(obj=self.paint_obj, @@ -2694,6 +3064,105 @@ class ToolPaint(FlatCAMTool, Gerber): plot=plot, run_threaded=run_threaded) + def ui_connect(self): + self.tools_table.itemChanged.connect(self.on_tool_edit) + + for row in range(self.tools_table.rowCount()): + try: + self.tools_table.cellWidget(row, 2).currentIndexChanged.connect(self.on_tooltable_cellwidget_change) + except AttributeError: + pass + + try: + self.tools_table.cellWidget(row, 4).currentIndexChanged.connect(self.on_tooltable_cellwidget_change) + except AttributeError: + pass + + self.tool_type_radio.activated_custom.connect(self.on_tool_type) + + # first disconnect + for opt in self.form_fields: + current_widget = self.form_fields[opt] + if isinstance(current_widget, FCCheckBox): + try: + current_widget.stateChanged.disconnect() + except (TypeError, ValueError): + pass + if isinstance(current_widget, RadioSet): + try: + current_widget.activated_custom.disconnect() + except (TypeError, ValueError): + pass + elif isinstance(current_widget, FCDoubleSpinner): + try: + current_widget.returnPressed.disconnect() + except (TypeError, ValueError): + pass + + # then reconnect + for opt in self.form_fields: + current_widget = self.form_fields[opt] + if isinstance(current_widget, FCCheckBox): + current_widget.stateChanged.connect(self.form_to_storage) + if isinstance(current_widget, RadioSet): + current_widget.activated_custom.connect(self.form_to_storage) + elif isinstance(current_widget, FCDoubleSpinner): + current_widget.returnPressed.connect(self.form_to_storage) + + self.ncc_choice_offset_cb.stateChanged.connect(self.on_offset_choice) + self.ncc_rest_cb.stateChanged.connect(self.on_rest_machining_check) + self.ncc_order_radio.activated_custom[str].connect(self.on_order_changed) + + def ui_disconnect(self): + try: + # if connected, disconnect the signal from the slot on item_changed as it creates issues + self.tools_table.itemChanged.disconnect() + except (TypeError, AttributeError): + pass + + try: + # if connected, disconnect the signal from the slot on item_changed as it creates issues + self.tool_type_radio.activated_custom.disconnect() + except (TypeError, AttributeError): + pass + + for row in range(self.tools_table.rowCount()): + for col in [2, 4]: + try: + self.ui.geo_tools_table.cellWidget(row, col).currentIndexChanged.disconnect() + except (TypeError, AttributeError): + pass + + for opt in self.form_fields: + current_widget = self.form_fields[opt] + if isinstance(current_widget, FCCheckBox): + try: + current_widget.stateChanged.disconnect() + except (TypeError, ValueError): + pass + if isinstance(current_widget, RadioSet): + try: + current_widget.activated_custom.disconnect() + except (TypeError, ValueError): + pass + elif isinstance(current_widget, FCDoubleSpinner): + try: + current_widget.returnPressed.disconnect() + except (TypeError, ValueError): + pass + + def reset_usage(self): + self.obj_name = "" + self.paint_obj = None + self.bound_obj = None + + self.first_click = False + self.cursor_pos = None + self.mouse_is_dragging = False + + self.sel_rect = [] + + @staticmethod def paint_bounds(geometry): def bounds_rec(o): From 82afd3bb6e569cd6d9268618c326d99e2473ab9e Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 15 Jan 2020 17:59:12 +0200 Subject: [PATCH 022/209] - work in Paint Tool GUI functionality --- README.md | 1 + flatcamTools/ToolPaint.py | 22 +++++++--------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index f91a123c..4a872ab7 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ CAD program, and create G-Code for Isolation routing. - added new functionality (key shortcut SHIFT+J) to locate the corners of the bounding box (and center) in a selected object - modified the NCC Tool GUI to prepare for accepting a tool from a tool database - started to modify the Paint Tool to be similar to NCC Tool and to accept a tool from a database +- work in Paint Tool GUI functionality 14.01.2020 diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 95fc26e7..462aaeef 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -1034,11 +1034,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.tools_table.setContextMenuPolicy(Qt.NoContextMenu) def build_ui(self): - try: - # if connected, disconnect the signal from the slot on item_changed as it creates issues - self.tools_table.itemChanged.disconnect() - except (TypeError, AttributeError): - pass + self.ui_disconnect() # updated units self.units = self.app.defaults['units'].upper() @@ -1119,8 +1115,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.tools_table.setMinimumHeight(self.tools_table.getHeight()) self.tools_table.setMaximumHeight(self.tools_table.getHeight()) - # we reactivate the signals after the after the tool adding as we don't need to see the tool been populated - self.tools_table.itemChanged.connect(self.on_tool_edit) + self.ui_connect() def on_combo_box_type(self): obj_type = self.box_combo_type.currentIndex() @@ -1166,21 +1161,19 @@ class ToolPaint(FlatCAMTool, Gerber): if float('%.*f' % (self.decimals, tool_dia)) in tool_dias: if muted is None: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Adding tool cancelled. Tool already in Tool Table.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Adding tool cancelled. Tool already in Tool Table.")) self.tools_table.itemChanged.connect(self.on_tool_edit) return else: if muted is None: - self.app.inform.emit('[success] %s' % - _("New tool added to Tool Table.")) + self.app.inform.emit('[success] %s' % _("New tool added to Tool Table.")) self.paint_tools.update({ int(self.tooluid): { 'tooldia': float('%.*f' % (self.decimals, tool_dia)), 'offset': 'Path', 'offset_value': 0.0, 'type': 'Iso', - 'tool_type': 'V', + 'tool_type': self.tool_type_radio.get_value(), 'data': dict(self.default_data), 'solid_geometry': [] } @@ -3109,9 +3102,8 @@ class ToolPaint(FlatCAMTool, Gerber): elif isinstance(current_widget, FCDoubleSpinner): current_widget.returnPressed.connect(self.form_to_storage) - self.ncc_choice_offset_cb.stateChanged.connect(self.on_offset_choice) - self.ncc_rest_cb.stateChanged.connect(self.on_rest_machining_check) - self.ncc_order_radio.activated_custom[str].connect(self.on_order_changed) + self.rest_cb.stateChanged.connect(self.on_rest_machining_check) + self.order_radio.activated_custom[str].connect(self.on_order_changed) def ui_disconnect(self): try: From 002617c2837113d3752fa08699ef3502150a46df Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 15 Jan 2020 18:14:07 +0200 Subject: [PATCH 023/209] - work in Paint Tool GUI functionality --- flatcamTools/ToolPaint.py | 83 ++++++++++----------------------------- 1 file changed, 20 insertions(+), 63 deletions(-) diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 462aaeef..dd4e76a5 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -533,22 +533,6 @@ class ToolPaint(FlatCAMTool, Gerber): # #################################### FINSIHED GUI ########################### # ############################################################################# - # ############################################################################# - # ###################### Setup CONTEXT MENU ################################### - # ############################################################################# - self.tools_table.setupContextMenu() - self.tools_table.addContextMenu( - _("Add"), self.on_add_tool_by_key, icon=QtGui.QIcon(self.app.resource_location + "/plus16.png") - ) - self.tools_table.addContextMenu( - _("Add from DB"), self.on_add_tool_by_key, icon=QtGui.QIcon(self.app.resource_location + "/plus16.png") - ) - self.tools_table.addContextMenu( - _("Delete"), lambda: - self.on_tool_delete(rows_to_delete=None, all_tools=None), - icon=QtGui.QIcon(self.app.resource_location + "/delete32.png") - ) - # ############################################################################# # ########################## VARIABLES ######################################## # ############################################################################# @@ -586,40 +570,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.poly_dict = dict() # store here the default data for Geometry Data - self.default_data = {} - self.default_data.update({ - "name": '_paint', - "plot": self.app.defaults["geometry_plot"], - "cutz": self.app.defaults["geometry_cutz"], - "vtipdia": float(self.tipdia_entry.get_value()), - "vtipangle": float(self.tipangle_entry.get_value()), - "travelz": self.app.defaults["geometry_travelz"], - "feedrate": self.app.defaults["geometry_feedrate"], - "feedrate_z": self.app.defaults["geometry_feedrate_z"], - "feedrate_rapid": self.app.defaults["geometry_feedrate_rapid"], - "dwell": self.app.defaults["geometry_dwell"], - "dwelltime": self.app.defaults["geometry_dwelltime"], - "multidepth": self.app.defaults["geometry_multidepth"], - "ppname_g": self.app.defaults["geometry_ppname_g"], - "depthperpass": self.app.defaults["geometry_depthperpass"], - "extracut": self.app.defaults["geometry_extracut"], - "extracut_length": self.app.defaults["geometry_extracut_length"], - "toolchange": self.app.defaults["geometry_toolchange"], - "toolchangez": self.app.defaults["geometry_toolchangez"], - "endz": self.app.defaults["geometry_endz"], - "spindlespeed": self.app.defaults["geometry_spindlespeed"], - "toolchangexy": self.app.defaults["geometry_toolchangexy"], - "startz": self.app.defaults["geometry_startz"], - - "tooldia": self.app.defaults["tools_painttooldia"], - "paintmargin": self.app.defaults["tools_paintmargin"], - "paintmethod": self.app.defaults["tools_paintmethod"], - "selectmethod": self.app.defaults["tools_selectmethod"], - "pathconnect": self.app.defaults["tools_pathconnect"], - "paintcontour": self.app.defaults["tools_paintcontour"], - "paintoverlap": self.app.defaults["tools_paintoverlap"], - "paintrest": self.app.defaults["tools_paintrest"], - }) + self.default_data = dict() self.tool_type_item_options = ["C1", "C2", "C3", "C4", "B", "V"] @@ -668,11 +619,16 @@ class ToolPaint(FlatCAMTool, Gerber): # ############################################################################# self.tools_table.setupContextMenu() self.tools_table.addContextMenu( - "Add", self.on_add_tool_by_key, icon=QtGui.QIcon(self.app.resource_location + "/plus16.png")) + _("Add"), self.on_add_tool_by_key, icon=QtGui.QIcon(self.app.resource_location + "/plus16.png") + ) self.tools_table.addContextMenu( - "Delete", lambda: - self.on_tool_delete(rows_to_delete=None, all=None), - icon=QtGui.QIcon(self.app.resource_location + "/delete32.png")) + _("Add from DB"), self.on_add_tool_by_key, icon=QtGui.QIcon(self.app.resource_location + "/plus16.png") + ) + self.tools_table.addContextMenu( + _("Delete"), lambda: + self.on_tool_delete(rows_to_delete=None, all_tools=None), + icon=QtGui.QIcon(self.app.resource_location + "/delete32.png") + ) def on_type_obj_index_changed(self, index): obj_type = self.type_obj_combo.currentIndex() @@ -953,12 +909,12 @@ class ToolPaint(FlatCAMTool, Gerber): # ## Init the GUI interface self.order_radio.set_value(self.app.defaults["tools_paintorder"]) - self.paintmargin_entry.set_value(self.default_data["paintmargin"]) - self.paintmethod_combo.set_value(self.default_data["paintmethod"]) - self.selectmethod_combo.set_value(self.default_data["selectmethod"]) - self.pathconnect_cb.set_value(self.default_data["pathconnect"]) - self.paintcontour_cb.set_value(self.default_data["paintcontour"]) - self.paintoverlap_entry.set_value(self.default_data["paintoverlap"]) + self.paintmargin_entry.set_value(self.app.defaults["tools_paintmargin"]) + self.paintmethod_combo.set_value(self.app.defaults["tools_paintmethod"]) + self.selectmethod_combo.set_value(self.app.defaults["tools_selectmethod"]) + self.pathconnect_cb.set_value(self.app.defaults["tools_pathconnect"]) + self.paintcontour_cb.set_value(self.app.defaults["tools_paintcontour"]) + self.paintoverlap_entry.set_value(self.app.defaults["tools_paintoverlap"]) self.cutz_entry.set_value(self.app.defaults["tools_paintcutz"]) self.tool_type_radio.set_value(self.app.defaults["tools_painttool_type"]) @@ -981,7 +937,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.default_data.update({ "name": '_paint', "plot": self.app.defaults["geometry_plot"], - "cutz": float(self.app.defaults["geometry_cutz"]), + "cutz": float(self.cutz_entry.get_value()), "vtipdia": float(self.tipdia_entry.get_value()), "vtipangle": float(self.tipangle_entry.get_value()), "travelz": float(self.app.defaults["geometry_travelz"]), @@ -1003,12 +959,13 @@ class ToolPaint(FlatCAMTool, Gerber): "startz": self.app.defaults["geometry_startz"], "tooldia": self.app.defaults["tools_painttooldia"], - "paintmargin": float(self.app.defaults["tools_paintmargin"]), + "paintmargin": self.app.defaults["tools_paintmargin"], "paintmethod": self.app.defaults["tools_paintmethod"], "selectmethod": self.app.defaults["tools_selectmethod"], "pathconnect": self.app.defaults["tools_pathconnect"], "paintcontour": self.app.defaults["tools_paintcontour"], - "paintoverlap": self.app.defaults["tools_paintoverlap"] + "paintoverlap": self.app.defaults["tools_paintoverlap"], + "paintrest": self.app.defaults["tools_paintrest"], }) try: From 3c569fdf6c72eb3c1161596cab6de03c974254d9 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 16 Jan 2020 02:07:00 +0200 Subject: [PATCH 024/209] - updated/optimized the GUI in Preferences for Paint Tool and for NCC Tool - work in Paint Tool to bring it up to date with NCC Tool --- FlatCAMApp.py | 15 +- README.md | 5 + flatcamEditors/FlatCAMGeoEditor.py | 2 +- flatcamGUI/PreferencesUI.py | 290 +++++++++++++++++++++-------- flatcamTools/ToolNonCopperClear.py | 17 +- flatcamTools/ToolPaint.py | 51 ++--- 6 files changed, 272 insertions(+), 108 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index e073978d..258c0852 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -776,11 +776,11 @@ class App(QtCore.QObject): "tools_nccref": 'itself', "tools_ncc_plotting": 'normal', "tools_nccmilling_type": 'cl', - "tools_ncctool_type": 'V', + "tools_ncctool_type": 'C1', "tools_ncccutz": -0.05, "tools_ncctipdia": 0.1, "tools_ncctipangle": 30, - "tools_nccnewdia": 1.0, + "tools_nccnewdia": 0.1, # Cutout Tool "tools_cutouttooldia": 2.4, @@ -804,11 +804,11 @@ class App(QtCore.QObject): "tools_paintcontour": True, "tools_paint_plotting": 'normal', "tools_paintrest": False, - "tools_painttool_type": 'V', + "tools_painttool_type": 'C1', "tools_paintcutz": -0.05, "tools_painttipdia": 0.1, "tools_painttipangle": 30, - "tools_paintnewdia": 1.0, + "tools_paintnewdia": 0.1, # 2-Sided Tool "tools_2sided_mirror_axis": "X", @@ -1453,6 +1453,13 @@ class App(QtCore.QObject): "tools_paintcontour": self.ui.tools_defaults_form.tools_paint_group.contour_cb, "tools_paint_plotting": self.ui.tools_defaults_form.tools_paint_group.paint_plotting_radio, + "tools_paintrest": self.ui.tools_defaults_form.tools_paint_group.rest_cb, + "tools_painttool_type": self.ui.tools_defaults_form.tools_paint_group.tool_type_radio, + "tools_paintcutz": self.ui.tools_defaults_form.tools_paint_group.cutz_entry, + "tools_painttipdia": self.ui.tools_defaults_form.tools_paint_group.tipdia_entry, + "tools_painttipangle": self.ui.tools_defaults_form.tools_paint_group.tipangle_entry, + "tools_paintnewdia": self.ui.tools_defaults_form.tools_paint_group.newdia_entry, + # 2-sided Tool "tools_2sided_mirror_axis": self.ui.tools_defaults_form.tools_2sided_group.mirror_axis_radio, "tools_2sided_axis_loc": self.ui.tools_defaults_form.tools_2sided_group.axis_location_radio, diff --git a/README.md b/README.md index 4a872ab7..a2f7d29a 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,11 @@ CAD program, and create G-Code for Isolation routing. ================================================= +16.01.2020 + +- updated/optimized the GUI in Preferences for Paint Tool and for NCC Tool +- work in Paint Tool to bring it up to date with NCC Tool + 15.01.2020 - added key shortcuts and toolbar icons for the new tools: Align Object Tool (ALT+A) and Extract Drills (ALT+I) diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index 20ccb225..5b0b95b9 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -451,7 +451,7 @@ class PaintOptionsTool(FlatCAMTool): grid.addWidget(self.painttooldia_entry, 0, 1) # Overlap - ovlabel = QtWidgets.QLabel('%s:' % _('Overlap Rate')) + ovlabel = QtWidgets.QLabel('%s:' % _('Overlap')) ovlabel.setToolTip( _("How much (percentage) of the tool width to overlap each tool pass.\n" "Adjust the value starting with lower values\n" diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index 41ae3f32..ca736455 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -163,6 +163,7 @@ class ToolsPreferencesUI(QtWidgets.QWidget): self.tools_ncc_group = ToolsNCCPrefGroupUI(decimals=self.decimals) self.tools_ncc_group.setMinimumWidth(220) + self.tools_paint_group = ToolsPaintPrefGroupUI(decimals=self.decimals) self.tools_paint_group.setMinimumWidth(220) @@ -192,26 +193,29 @@ class ToolsPreferencesUI(QtWidgets.QWidget): self.vlay = QtWidgets.QVBoxLayout() self.vlay.addWidget(self.tools_ncc_group) - self.vlay.addWidget(self.tools_paint_group) + self.vlay.addWidget(self.tools_cutout_group) self.vlay1 = QtWidgets.QVBoxLayout() - self.vlay1.addWidget(self.tools_cutout_group) - self.vlay1.addWidget(self.tools_transform_group) - self.vlay1.addWidget(self.tools_2sided_group) + self.vlay1.addWidget(self.tools_paint_group) + self.vlay1.addWidget(self.tools_panelize_group) self.vlay2 = QtWidgets.QVBoxLayout() - self.vlay2.addWidget(self.tools_panelize_group) + self.vlay2.addWidget(self.tools_transform_group) + self.vlay2.addWidget(self.tools_2sided_group) self.vlay2.addWidget(self.tools_sub_group) - self.vlay2.addWidget(self.tools_film_group) self.vlay3 = QtWidgets.QVBoxLayout() - self.vlay3.addWidget(self.tools_solderpaste_group) + self.vlay3.addWidget(self.tools_film_group) self.vlay3.addWidget(self.tools_calculators_group) + self.vlay4 = QtWidgets.QVBoxLayout() + self.vlay4.addWidget(self.tools_solderpaste_group) + self.layout.addLayout(self.vlay) self.layout.addLayout(self.vlay1) self.layout.addLayout(self.vlay2) self.layout.addLayout(self.vlay3) + self.layout.addLayout(self.vlay4) self.layout.addStretch() @@ -3562,8 +3566,8 @@ class ExcellonEditorPrefGroupUI(OptionsGroupUI): grid0.addWidget(self.sel_limit_label, 0, 0) grid0.addWidget(self.sel_limit_entry, 0, 1) - # New tool diameter - self.addtool_entry_lbl = QtWidgets.QLabel('%s:' % _('New Tool Dia')) + # New Diameter + self.addtool_entry_lbl = QtWidgets.QLabel('%s:' % _('New Dia')) self.addtool_entry_lbl.setToolTip( _("Diameter for the new tool") ) @@ -5012,7 +5016,7 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): grid0 = QtWidgets.QGridLayout() self.layout.addLayout(grid0) - ncctdlabel = QtWidgets.QLabel('%s:' % _('Tools dia')) + ncctdlabel = QtWidgets.QLabel('%s:' % _('Tools Dia')) ncctdlabel.setToolTip( _("Diameters of the cutting tools, separated by comma.\n" "The value of the diameter has to use the dot decimals separator.\n" @@ -5088,9 +5092,12 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): grid0.addWidget(self.cutz_entry, 4, 1) # New Diameter - self.newdialabel = QtWidgets.QLabel('%s:' % _('New Tool Dia')) + self.newdialabel = QtWidgets.QLabel('%s:' % _('New Dia')) self.newdialabel.setToolTip( - _("The new tool diameter (cut width) to add in the tool table.")) + _("Diameter for the new tool to add in the Tool Table.\n" + "If the tool is V-shape type then this value is automatically\n" + "calculated from the other parameters.") + ) self.newdia_entry = FCDoubleSpinner() self.newdia_entry.set_precision(self.decimals) self.newdia_entry.set_range(0.0001, 9999.9999) @@ -5099,6 +5106,11 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): grid0.addWidget(self.newdialabel, 5, 0) grid0.addWidget(self.newdia_entry, 5, 1) + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(separator_line, 6, 0, 1, 2) + # Milling Type Radio Button self.milling_type_label = QtWidgets.QLabel('%s:' % _('Milling Type')) self.milling_type_label.setToolTip( @@ -5115,8 +5127,8 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): "- conventional / useful when there is no backlash compensation") ) - grid0.addWidget(self.milling_type_label, 6, 0) - grid0.addWidget(self.milling_type_radio, 6, 1) + grid0.addWidget(self.milling_type_label, 7, 0) + grid0.addWidget(self.milling_type_radio, 7, 1) # Tool order Radio Button self.ncc_order_label = QtWidgets.QLabel('%s:' % _('Tool order')) @@ -5136,11 +5148,16 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): "'Reverse' --> menas that the tools will ordered from big to small\n\n" "WARNING: using rest machining will automatically set the order\n" "in reverse and disable this control.")) - grid0.addWidget(self.ncc_order_label, 7, 0) - grid0.addWidget(self.ncc_order_radio, 7, 1) + grid0.addWidget(self.ncc_order_label, 8, 0) + grid0.addWidget(self.ncc_order_radio, 8, 1) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(separator_line, 9, 0, 1, 2) # Overlap Entry - nccoverlabel = QtWidgets.QLabel('%s:' % _('Overlap Rate')) + nccoverlabel = QtWidgets.QLabel('%s:' % _('Overlap')) nccoverlabel.setToolTip( _("How much (percentage) of the tool width to overlap each tool pass.\n" "Adjust the value starting with lower values\n" @@ -5155,8 +5172,9 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): self.ncc_overlap_entry.setWrapping(True) self.ncc_overlap_entry.setRange(0.0000, 99.9999) self.ncc_overlap_entry.setSingleStep(0.1) - grid0.addWidget(nccoverlabel, 8, 0) - grid0.addWidget(self.ncc_overlap_entry, 8, 1) + + grid0.addWidget(nccoverlabel, 10, 0) + grid0.addWidget(self.ncc_overlap_entry, 10, 1) # Margin entry nccmarginlabel = QtWidgets.QLabel('%s:' % _('Margin')) @@ -5168,8 +5186,8 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): self.ncc_margin_entry.set_range(-10000, 10000) self.ncc_margin_entry.setSingleStep(0.1) - grid0.addWidget(nccmarginlabel, 9, 0) - grid0.addWidget(self.ncc_margin_entry, 9, 1) + grid0.addWidget(nccmarginlabel, 11, 0) + grid0.addWidget(self.ncc_margin_entry, 11, 1) # Method methodlabel = QtWidgets.QLabel('%s:' % _('Method')) @@ -5186,8 +5204,8 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): {"label": _("Straight lines"), "value": "lines"} ], orientation='vertical', stretch=False) - grid0.addWidget(methodlabel, 10, 0) - grid0.addWidget(self.ncc_method_radio, 10, 1) + grid0.addWidget(methodlabel, 12, 0) + grid0.addWidget(self.ncc_method_radio, 12, 1) # Connect lines self.ncc_connect_cb = FCCheckBox('%s' % _("Connect")) @@ -5196,7 +5214,7 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): "segments to minimize tool lifts.") ) - grid0.addWidget(self.ncc_connect_cb, 11, 0, 1, 2) + grid0.addWidget(self.ncc_connect_cb, 13, 0) # Contour Checkbox self.ncc_contour_cb = FCCheckBox('%s' % _("Contour")) @@ -5205,21 +5223,7 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): "to trim rough edges.") ) - grid0.addWidget(self.ncc_contour_cb, 12, 0, 1, 2) - - # Rest machining CheckBox - self.ncc_rest_cb = FCCheckBox('%s' % _("Rest Machining")) - self.ncc_rest_cb.setToolTip( - _("If checked, use 'rest machining'.\n" - "Basically it will clear copper outside PCB features,\n" - "using the biggest tool and continue with the next tools,\n" - "from bigger to smaller, to clear areas of copper that\n" - "could not be cleared by previous tool, until there is\n" - "no more copper to clear or there are no more tools.\n" - "If not checked, use the standard algorithm.") - ) - - grid0.addWidget(self.ncc_rest_cb, 13, 0, 1, 2) + grid0.addWidget(self.ncc_contour_cb, 13, 1) # ## NCC Offset choice self.ncc_choice_offset_cb = FCCheckBox('%s' % _("Offset")) @@ -5249,10 +5253,31 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): grid0.addWidget(self.ncc_offset_label, 15, 0) grid0.addWidget(self.ncc_offset_spinner, 15, 1) + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(separator_line, 16, 0, 1, 2) + + # Rest machining CheckBox + self.ncc_rest_cb = FCCheckBox('%s' % _("Rest Machining")) + self.ncc_rest_cb.setToolTip( + _("If checked, use 'rest machining'.\n" + "Basically it will clear copper outside PCB features,\n" + "using the biggest tool and continue with the next tools,\n" + "from bigger to smaller, to clear areas of copper that\n" + "could not be cleared by previous tool, until there is\n" + "no more copper to clear or there are no more tools.\n" + "If not checked, use the standard algorithm.") + ) + + grid0.addWidget(self.ncc_rest_cb, 17, 0, 1, 2) + # ## Reference self.reference_radio = RadioSet([{'label': _('Itself'), 'value': 'itself'}, - {"label": _("Area"), "value": "area"}, - {'label': _('Ref'), 'value': 'box'}]) + {"label": _("Area Selection"), "value": "area"}, + {'label': _('Reference Object'), 'value': 'box'}], + orientation='vertical', + stretch=None) reference_label = QtWidgets.QLabel('%s:' % _("Reference")) reference_label.setToolTip( _("- 'Itself' - the non copper clearing extent\n" @@ -5263,8 +5288,13 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): "specified by another object.") ) - grid0.addWidget(reference_label, 16, 0) - grid0.addWidget(self.reference_radio, 16, 1) + grid0.addWidget(reference_label, 18, 0) + grid0.addWidget(self.reference_radio, 18, 1) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(separator_line, 19, 0, 1, 2) # ## Plotting type self.ncc_plotting_radio = RadioSet([{'label': _('Normal'), 'value': 'normal'}, @@ -5274,8 +5304,8 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): _("- 'Normal' - normal plotting, done at the end of the NCC job\n" "- 'Progressive' - after each shape is generated it will be plotted.") ) - grid0.addWidget(plotting_label, 17, 0) - grid0.addWidget(self.ncc_plotting_radio, 17, 1) + grid0.addWidget(plotting_label, 20, 0) + grid0.addWidget(self.ncc_plotting_radio, 20, 1) self.layout.addStretch() @@ -5520,10 +5550,12 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI): self.layout.addWidget(self.paint_label) grid0 = QtWidgets.QGridLayout() + grid0.setColumnStretch(0, 0) + grid0.setColumnStretch(1, 1) self.layout.addLayout(grid0) # Tool dia - ptdlabel = QtWidgets.QLabel('%s:' % _('Tool dia')) + ptdlabel = QtWidgets.QLabel('%s:' % _('Tools Dia')) ptdlabel.setToolTip( _("Diameters of the cutting tools, separated by comma.\n" "The value of the diameter has to use the dot decimals separator.\n" @@ -5536,7 +5568,88 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI): grid0.addWidget(self.painttooldia_entry, 0, 1) - self.paint_order_label = QtWidgets.QLabel('%s:' % _('Tool order')) + # Tool Type Radio Button + self.tool_type_label = QtWidgets.QLabel('%s:' % _('Tool Type')) + self.tool_type_label.setToolTip( + _("Default tool type:\n" + "- 'V-shape'\n" + "- Circular") + ) + + self.tool_type_radio = RadioSet([{'label': _('V-shape'), 'value': 'V'}, + {'label': _('Circular'), 'value': 'C1'}]) + + self.tool_type_radio.setObjectName(_("Tool Type")) + + grid0.addWidget(self.tool_type_label, 1, 0) + grid0.addWidget(self.tool_type_radio, 1, 1) + + # Tip Dia + self.tipdialabel = QtWidgets.QLabel('%s:' % _('V-Tip Dia')) + self.tipdialabel.setToolTip( + _("The tip diameter for V-Shape Tool")) + self.tipdia_entry = FCDoubleSpinner() + self.tipdia_entry.set_precision(self.decimals) + self.tipdia_entry.set_range(0.0000, 9999.9999) + self.tipdia_entry.setSingleStep(0.1) + self.tipdia_entry.setObjectName(_("V-Tip Dia")) + + grid0.addWidget(self.tipdialabel, 2, 0) + grid0.addWidget(self.tipdia_entry, 2, 1) + + # Tip Angle + self.tipanglelabel = QtWidgets.QLabel('%s:' % _('V-Tip Angle')) + self.tipanglelabel.setToolTip( + _("The tip angle for V-Shape Tool.\n" + "In degree.")) + self.tipangle_entry = FCDoubleSpinner() + self.tipangle_entry.set_precision(self.decimals) + self.tipangle_entry.set_range(0.0000, 180.0000) + self.tipangle_entry.setSingleStep(5) + self.tipangle_entry.setObjectName(_("V-Tip Angle")) + + grid0.addWidget(self.tipanglelabel, 3, 0) + grid0.addWidget(self.tipangle_entry, 3, 1) + + # Cut Z entry + cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z')) + cutzlabel.setToolTip( + _("Depth of cut into material. Negative value.\n" + "In FlatCAM units.") + ) + self.cutz_entry = FCDoubleSpinner() + self.cutz_entry.set_precision(self.decimals) + self.cutz_entry.set_range(-99999.9999, 0.0000) + self.cutz_entry.setObjectName(_("Cut Z")) + + self.cutz_entry.setToolTip( + _("Depth of cut into material. Negative value.\n" + "In FlatCAM units.") + ) + grid0.addWidget(cutzlabel, 4, 0) + grid0.addWidget(self.cutz_entry, 4, 1) + + # ### Tool Diameter #### + self.newdialabel = QtWidgets.QLabel('%s:' % _('New Dia')) + self.newdialabel.setToolTip( + _("Diameter for the new tool to add in the Tool Table.\n" + "If the tool is V-shape type then this value is automatically\n" + "calculated from the other parameters.") + ) + self.newdia_entry = FCDoubleSpinner() + self.newdia_entry.set_precision(self.decimals) + self.newdia_entry.set_range(0.000, 9999.9999) + self.newdia_entry.setObjectName(_("Tool Dia")) + + grid0.addWidget(self.newdialabel, 5, 0) + grid0.addWidget(self.newdia_entry, 5, 1) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(separator_line, 6, 0, 1, 2) + + self.paint_order_label = QtWidgets.QLabel('%s:' % _('Tool order')) self.paint_order_label.setToolTip(_("This set the way that the tools in the tools table are used.\n" "'No' --> means that the used order is the one in the tool table\n" "'Forward' --> means that the tools will be ordered from small to big\n" @@ -5547,17 +5660,17 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI): self.paint_order_radio = RadioSet([{'label': _('No'), 'value': 'no'}, {'label': _('Forward'), 'value': 'fwd'}, {'label': _('Reverse'), 'value': 'rev'}]) - self.paint_order_radio.setToolTip(_("This set the way that the tools in the tools table are used.\n" - "'No' --> means that the used order is the one in the tool table\n" - "'Forward' --> means that the tools will be ordered from small to big\n" - "'Reverse' --> menas that the tools will ordered from big to small\n\n" - "WARNING: using rest machining will automatically set the order\n" - "in reverse and disable this control.")) - grid0.addWidget(self.paint_order_label, 1, 0) - grid0.addWidget(self.paint_order_radio, 1, 1) + + grid0.addWidget(self.paint_order_label, 7, 0) + grid0.addWidget(self.paint_order_radio, 7, 1) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(separator_line, 8, 0, 1, 2) # Overlap - ovlabel = QtWidgets.QLabel('%s:' % _('Overlap Rate')) + ovlabel = QtWidgets.QLabel('%s:' % _('Overlap')) ovlabel.setToolTip( _("How much (percentage) of the tool width to overlap each tool pass.\n" "Adjust the value starting with lower values\n" @@ -5573,8 +5686,8 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI): self.paintoverlap_entry.setRange(0.0000, 99.9999) self.paintoverlap_entry.setSingleStep(0.1) - grid0.addWidget(ovlabel, 2, 0) - grid0.addWidget(self.paintoverlap_entry, 2, 1) + grid0.addWidget(ovlabel, 9, 0) + grid0.addWidget(self.paintoverlap_entry, 9, 1) # Margin marginlabel = QtWidgets.QLabel('%s:' % _('Margin')) @@ -5583,13 +5696,13 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI): "the edges of the polygon to\n" "be painted.") ) - grid0.addWidget(marginlabel, 3, 0) self.paintmargin_entry = FCDoubleSpinner() self.paintmargin_entry.set_range(-9999.9999, 9999.9999) self.paintmargin_entry.set_precision(self.decimals) self.paintmargin_entry.setSingleStep(0.1) - grid0.addWidget(self.paintmargin_entry, 3, 1) + grid0.addWidget(marginlabel, 10, 0) + grid0.addWidget(self.paintmargin_entry, 10, 1) # Method methodlabel = QtWidgets.QLabel('%s:' % _('Method')) @@ -5599,13 +5712,15 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI): "Seed-based: Outwards from seed.
" "Line-based: Parallel lines.") ) - grid0.addWidget(methodlabel, 4, 0) + self.paintmethod_combo = RadioSet([ {"label": _("Standard"), "value": "standard"}, {"label": _("Seed-based"), "value": "seed"}, {"label": _("Straight lines"), "value": "lines"} ], orientation='vertical', stretch=False) - grid0.addWidget(self.paintmethod_combo, 4, 1) + + grid0.addWidget(methodlabel, 11, 0) + grid0.addWidget(self.paintmethod_combo, 11, 1) # Connect lines self.pathconnect_cb = FCCheckBox('%s' % _("Connect")) @@ -5613,7 +5728,7 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI): _("Draw lines between resulting\n" "segments to minimize tool lifts.") ) - grid0.addWidget(self.pathconnect_cb, 5, 0, 1, 2) + grid0.addWidget(self.pathconnect_cb, 12, 0) # Paint contour self.contour_cb = FCCheckBox('%s' % _("Contour")) @@ -5621,7 +5736,25 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI): _("Cut around the perimeter of the polygon\n" "to trim rough edges.") ) - grid0.addWidget(self.contour_cb, 6, 0, 1, 2) + grid0.addWidget(self.contour_cb, 12, 1) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(separator_line, 13, 0, 1, 2) + + self.rest_cb = FCCheckBox('%s' % _("Rest Machining")) + self.rest_cb.setObjectName(_("Rest Machining")) + self.rest_cb.setToolTip( + _("If checked, use 'rest machining'.\n" + "Basically it will clear copper outside PCB features,\n" + "using the biggest tool and continue with the next tools,\n" + "from bigger to smaller, to clear areas of copper that\n" + "could not be cleared by previous tool, until there is\n" + "no more copper to clear or there are no more tools.\n\n" + "If not checked, use the standard algorithm.") + ) + grid0.addWidget(self.rest_cb, 14, 0, 1, 2) # Polygon selection selectlabel = QtWidgets.QLabel('%s:' % _('Selection')) @@ -5634,14 +5767,23 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI): "- 'Reference Object' - will do non copper clearing within the area\n" "specified by another object.") ) - self.selectmethod_combo = RadioSet([ - {"label": _("Sel"), "value": "single"}, - {"label": _("Area"), "value": "area"}, - {"label": _("All"), "value": "all"}, - {"label": _("Ref"), "value": "ref"} - ]) - grid0.addWidget(selectlabel, 7, 0) - grid0.addWidget(self.selectmethod_combo, 7, 1) + self.selectmethod_combo = RadioSet( + [ + {"label": _("Polygon Selection"), "value": "single"}, + {"label": _("Area Selection"), "value": "area"}, + {"label": _("All Polygons"), "value": "all"}, + {"label": _("Reference Object"), "value": "ref"} + ], + orientation='vertical', + stretch=None + ) + grid0.addWidget(selectlabel, 15, 0) + grid0.addWidget(self.selectmethod_combo, 15, 1) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(separator_line, 16, 0, 1, 2) # ## Plotting type self.paint_plotting_radio = RadioSet([{'label': _('Normal'), 'value': 'normal'}, @@ -5651,8 +5793,8 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI): _("- 'Normal' - normal plotting, done at the end of the Paint job\n" "- 'Progressive' - after each shape is generated it will be plotted.") ) - grid0.addWidget(plotting_label, 8, 0) - grid0.addWidget(self.paint_plotting_radio, 8, 1) + grid0.addWidget(plotting_label, 17, 0) + grid0.addWidget(self.paint_plotting_radio, 17, 1) self.layout.addStretch() diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNonCopperClear.py index 5b2e8b1d..1b0896dc 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/flatcamTools/ToolNonCopperClear.py @@ -352,7 +352,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.grid3.addWidget(self.tool_data_label, 12, 0, 1, 2) # Overlap Entry - nccoverlabel = QtWidgets.QLabel('%s:' % _('Overlap Rate')) + nccoverlabel = QtWidgets.QLabel('%s:' % _('Overlap')) nccoverlabel.setToolTip( _("How much (percentage) of the tool width to overlap each tool pass.\n" "Adjust the value starting with lower values\n" @@ -367,7 +367,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.ncc_overlap_entry.setWrapping(True) self.ncc_overlap_entry.setRange(0.000, 99.9999) self.ncc_overlap_entry.setSingleStep(0.1) - self.ncc_overlap_entry.setObjectName(_("Overlap Rate")) + self.ncc_overlap_entry.setObjectName(_("Overlap")) self.grid3.addWidget(nccoverlabel, 13, 0) self.grid3.addWidget(self.ncc_overlap_entry, 13, 1) @@ -653,7 +653,7 @@ class NonCopperClear(FlatCAMTool, Gerber): } self.name2option = { - _('Overlap Rate'): "nccoverlap", + _('Overlap'): "nccoverlap", _('Margin'): "nccmargin", _('Method'): "nccmethod", _("Connect"): "nccconnect", @@ -663,6 +663,8 @@ class NonCopperClear(FlatCAMTool, Gerber): _('Milling Type'): "milling_type", } + self.old_tool_dia = None + # ############################################################################# # ############################ SIGNALS ######################################## # ############################################################################# @@ -901,6 +903,8 @@ class NonCopperClear(FlatCAMTool, Gerber): self.tipangle_entry.set_value(self.app.defaults["tools_ncctipangle"]) self.addtool_entry.set_value(self.app.defaults["tools_nccnewdia"]) + self.old_tool_dia = self.app.defaults["tools_nccnewdia"] + self.on_tool_type(val=self.tool_type_radio.get_value()) # init the working variables @@ -1238,6 +1242,8 @@ class NonCopperClear(FlatCAMTool, Gerber): self.tipdia_entry.show() self.tipanglelabel.show() self.tipangle_entry.show() + + self.on_calculate_tooldia() else: self.addtool_entry_lbl.setDisabled(False) self.addtool_entry.setDisabled(False) @@ -1246,6 +1252,8 @@ class NonCopperClear(FlatCAMTool, Gerber): self.tipanglelabel.hide() self.tipangle_entry.hide() + self.addtool_entry.set_value(self.old_tool_dia) + def on_calculate_tooldia(self): if self.tool_type_radio.get_value() == 'V': tip_dia = float(self.tipdia_entry.get_value()) @@ -1332,7 +1340,6 @@ class NonCopperClear(FlatCAMTool, Gerber): }) self.blockSignals(False) - self.build_ui() def on_tool_edit(self): @@ -1393,7 +1400,7 @@ class NonCopperClear(FlatCAMTool, Gerber): deleted_tools_list = [] if all_tools: - self.paint_tools.clear() + self.ncc_tools.clear() self.blockSignals(False) self.build_ui() return diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index dd4e76a5..18f1f3a9 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -329,7 +329,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.tools_box.addLayout(grid4) # Overlap - ovlabel = QtWidgets.QLabel('%s:' % _('Overlap Rate')) + ovlabel = QtWidgets.QLabel('%s:' % _('Overlap')) ovlabel.setToolTip( _("How much (percentage) of the tool width to overlap each tool pass.\n" "Adjust the value starting with lower values\n" @@ -344,7 +344,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.paintoverlap_entry.setWrapping(True) self.paintoverlap_entry.setRange(0.0000, 99.9999) self.paintoverlap_entry.setSingleStep(0.1) - self.paintoverlap_entry.setObjectName(_("Overlap Rate")) + self.paintoverlap_entry.setObjectName(_("Overlap")) grid4.addWidget(ovlabel, 1, 0) grid4.addWidget(self.paintoverlap_entry, 1, 1) @@ -583,13 +583,15 @@ class ToolPaint(FlatCAMTool, Gerber): } self.name2option = { - _('Overlap Rate'): "paintoverlap", + _('Overlap'): "paintoverlap", _('Margin'): "paintmargin", _('Method'): "paintmethod", _("Connect"): "pathconnect", _("Contour"): "paintcontour", } + self.old_tool_dia = None + # ############################################################################# # ################################# Signals ################################### # ############################################################################# @@ -833,6 +835,8 @@ class ToolPaint(FlatCAMTool, Gerber): self.tipdia_entry.show() self.tipanglelabel.show() self.tipangle_entry.show() + + self.on_calculate_tooldia() else: self.addtool_entry_lbl.setDisabled(False) self.addtool_entry.setDisabled(False) @@ -841,6 +845,8 @@ class ToolPaint(FlatCAMTool, Gerber): self.tipanglelabel.hide() self.tipangle_entry.hide() + self.addtool_entry.set_value(self.old_tool_dia) + def on_calculate_tooldia(self): if self.tool_type_radio.get_value() == 'V': tip_dia = float(self.tipdia_entry.get_value()) @@ -921,6 +927,9 @@ class ToolPaint(FlatCAMTool, Gerber): self.tipdia_entry.set_value(self.app.defaults["tools_painttipdia"]) self.tipangle_entry.set_value(self.app.defaults["tools_painttipangle"]) self.addtool_entry.set_value(self.app.defaults["tools_paintnewdia"]) + self.rest_cb.set_value(self.app.defaults["tools_paintrest"]) + + self.old_tool_dia = self.app.defaults["tools_paintnewdia"] self.on_tool_type(val=self.tool_type_radio.get_value()) @@ -1080,21 +1089,16 @@ class ToolPaint(FlatCAMTool, Gerber): self.box_combo.setCurrentIndex(0) def on_tool_add(self, dia=None, muted=None): - - try: - self.tools_table.itemChanged.disconnect() - except TypeError: - pass + self.blockSignals(True) if dia: tool_dia = dia else: - tool_dia = float(self.addtool_entry.get_value()) + tool_dia = self.on_calculate_tooldia() if tool_dia is None: self.build_ui() - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Please enter a tool diameter to add, in Float format.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Please enter a tool diameter to add, in Float format.")) return # construct a list of all 'tooluid' in the self.tools @@ -1136,15 +1140,13 @@ class ToolPaint(FlatCAMTool, Gerber): } }) + self.blockSignals(False) self.build_ui() def on_tool_edit(self): - old_tool_dia = '' + self.blockSignals(True) - try: - self.tools_table.itemChanged.disconnect() - except TypeError: - pass + old_tool_dia = '' tool_dias = [] for k, v in self.paint_tools.items(): @@ -1182,6 +1184,7 @@ class ToolPaint(FlatCAMTool, Gerber): restore_dia_item.setText(str(old_tool_dia)) self.app.inform.emit('[WARNING_NOTCL] %s' % _("Edit cancelled. New diameter value is already in the Tool Table.")) + self.blockSignals(False) self.build_ui() # def on_tool_copy(self, all=None): @@ -1240,15 +1243,13 @@ class ToolPaint(FlatCAMTool, Gerber): # self.app.inform.emit("[success] Tool was copied in the Tool Table.") def on_tool_delete(self, rows_to_delete=None, all=None): - try: - self.tools_table.itemChanged.disconnect() - except TypeError: - pass + self.blockSignals(True) deleted_tools_list = [] if all: self.paint_tools.clear() + self.blockSignals(False) self.build_ui() return @@ -1262,6 +1263,8 @@ class ToolPaint(FlatCAMTool, Gerber): for t in deleted_tools_list: self.paint_tools.pop(t, None) + + self.blockSignals(False) self.build_ui() return @@ -1278,14 +1281,14 @@ class ToolPaint(FlatCAMTool, Gerber): self.paint_tools.pop(t, None) except AttributeError: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Delete failed. Select a tool to delete.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Delete failed. Select a tool to delete.")) + self.blockSignals(False) return except Exception as e: log.debug(str(e)) - self.app.inform.emit('[success] %s' % - _("Tool(s) deleted from Tool Table.")) + self.app.inform.emit('[success] %s' % _("Tool(s) deleted from Tool Table.")) + self.blockSignals(False) self.build_ui() def on_paint_button_click(self): From 5ffa9b647085fc02dd08c335cab3f7ad146a2148 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 16 Jan 2020 02:21:20 +0200 Subject: [PATCH 025/209] - updated the GUI in preferences for Calculator Tool --- README.md | 1 + flatcamGUI/PreferencesUI.py | 23 +++++++++++------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index a2f7d29a..3ae584b3 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ CAD program, and create G-Code for Isolation routing. - updated/optimized the GUI in Preferences for Paint Tool and for NCC Tool - work in Paint Tool to bring it up to date with NCC Tool +- updated the GUI in preferences for Calculator Tool 15.01.2020 diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index ca736455..728f86f6 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -6241,6 +6241,8 @@ class ToolsCalculatorsPrefGroupUI(OptionsGroupUI): self.layout.addWidget(self.vshape_tool_label) grid0 = QtWidgets.QGridLayout() + grid0.setColumnStretch(0, 0) + grid0.setColumnStretch(1, 1) self.layout.addLayout(grid0) # ## Tip Diameter @@ -6291,10 +6293,7 @@ class ToolsCalculatorsPrefGroupUI(OptionsGroupUI): _("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.") ) - self.layout.addWidget(self.plate_title_label) - - grid1 = QtWidgets.QGridLayout() - self.layout.addLayout(grid1) + grid0.addWidget(self.plate_title_label, 3, 0, 1, 2) # ## PCB Length self.pcblength_entry = FCDoubleSpinner() @@ -6305,8 +6304,8 @@ class ToolsCalculatorsPrefGroupUI(OptionsGroupUI): self.pcblengthlabel = QtWidgets.QLabel('%s:' % _("Board Length")) self.pcblengthlabel.setToolTip(_('This is the board length. In centimeters.')) - grid1.addWidget(self.pcblengthlabel, 0, 0) - grid1.addWidget(self.pcblength_entry, 0, 1) + grid0.addWidget(self.pcblengthlabel, 4, 0) + grid0.addWidget(self.pcblength_entry, 4, 1) # ## PCB Width self.pcbwidth_entry = FCDoubleSpinner() @@ -6317,8 +6316,8 @@ class ToolsCalculatorsPrefGroupUI(OptionsGroupUI): self.pcbwidthlabel = QtWidgets.QLabel('%s:' % _("Board Width")) self.pcbwidthlabel.setToolTip(_('This is the board width.In centimeters.')) - grid1.addWidget(self.pcbwidthlabel, 1, 0) - grid1.addWidget(self.pcbwidth_entry, 1, 1) + grid0.addWidget(self.pcbwidthlabel, 5, 0) + grid0.addWidget(self.pcbwidth_entry, 5, 1) # ## Current Density self.cdensity_label = QtWidgets.QLabel('%s:' % _("Current Density")) @@ -6329,8 +6328,8 @@ class ToolsCalculatorsPrefGroupUI(OptionsGroupUI): self.cdensity_label.setToolTip(_("Current density to pass through the board. \n" "In Amps per Square Feet ASF.")) - grid1.addWidget(self.cdensity_label, 2, 0) - grid1.addWidget(self.cdensity_entry, 2, 1) + grid0.addWidget(self.cdensity_label, 6, 0) + grid0.addWidget(self.cdensity_entry, 6, 1) # ## PCB Copper Growth self.growth_label = QtWidgets.QLabel('%s:' % _("Copper Growth")) @@ -6341,8 +6340,8 @@ class ToolsCalculatorsPrefGroupUI(OptionsGroupUI): self.growth_label.setToolTip(_("How thick the copper growth is intended to be.\n" "In microns.")) - grid1.addWidget(self.growth_label, 3, 0) - grid1.addWidget(self.growth_entry, 3, 1) + grid0.addWidget(self.growth_label, 7, 0) + grid0.addWidget(self.growth_entry, 7, 1) self.layout.addStretch() From 24e01ad51824001a9c11cf977ebc8384d772a2db Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 16 Jan 2020 02:33:54 +0200 Subject: [PATCH 026/209] - a small change in the Excellon UI --- README.md | 1 + flatcamGUI/ObjectUI.py | 28 +++++++++++++++++++--------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 3ae584b3..e49424ed 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ CAD program, and create G-Code for Isolation routing. - updated/optimized the GUI in Preferences for Paint Tool and for NCC Tool - work in Paint Tool to bring it up to date with NCC Tool - updated the GUI in preferences for Calculator Tool +- a small change in the Excellon UI 15.01.2020 diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index 9cadf1ee..94729ce2 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -1050,6 +1050,16 @@ class ExcellonObjectUI(ObjectUI): self.excellon_gcode_type_radio.setVisible(False) gcode_type_label.hide() + warning_lbl = QtWidgets.QLabel( + _( + "Add / Select at least one tool in the tool-table.\n" + "Click the header to select all, or Ctrl + LMB\n" + "for custom selection of tools." + )) + + grid2.addWidget(QtWidgets.QLabel(''), 2, 0, 1, 3) + grid2.addWidget(warning_lbl, 3, 0, 1, 3) + self.generate_cnc_button = QtWidgets.QPushButton(_('Create Drills GCode')) self.generate_cnc_button.setToolTip( _("Generate the CNC Job.") @@ -1060,7 +1070,7 @@ class ExcellonObjectUI(ObjectUI): font-weight: bold; } """) - grid2.addWidget(self.generate_cnc_button, 2, 0, 1, 3) + grid2.addWidget(self.generate_cnc_button, 4, 0, 1, 3) # ### Milling Holes Drills #### self.mill_hole_label = QtWidgets.QLabel('%s' % _('Mill Holes')) @@ -1069,7 +1079,7 @@ class ExcellonObjectUI(ObjectUI): "Select from the Tools Table above the hole dias to be\n" "milled. Use the # column to make the selection.") ) - grid2.addWidget(self.mill_hole_label, 3, 0, 1, 3) + grid2.addWidget(self.mill_hole_label, 5, 0, 1, 3) self.tdlabel = QtWidgets.QLabel('%s:' % _('Drill Tool dia')) self.tdlabel.setToolTip( @@ -1092,9 +1102,9 @@ class ExcellonObjectUI(ObjectUI): } """) - grid2.addWidget(self.tdlabel, 4, 0) - grid2.addWidget(self.tooldia_entry, 4, 1) - grid2.addWidget(self.generate_milling_button, 4, 2) + grid2.addWidget(self.tdlabel, 6, 0) + grid2.addWidget(self.tooldia_entry, 6, 1) + grid2.addWidget(self.generate_milling_button, 6, 2) self.stdlabel = QtWidgets.QLabel('%s:' % _('Slot Tool dia')) self.stdlabel.setToolTip( @@ -1119,9 +1129,9 @@ class ExcellonObjectUI(ObjectUI): } """) - grid2.addWidget(self.stdlabel, 5, 0) - grid2.addWidget(self.slot_tooldia_entry, 5, 1) - grid2.addWidget(self.generate_milling_slots_button, 5, 2) + grid2.addWidget(self.stdlabel, 7, 0) + grid2.addWidget(self.slot_tooldia_entry, 7, 1) + grid2.addWidget(self.generate_milling_slots_button, 7, 2) def hide_drills(self, state=True): if state is True: @@ -1697,7 +1707,7 @@ class GeometryObjectUI(ObjectUI): warning_lbl = QtWidgets.QLabel( _( - "Add at least one tool in the tool-table.\n" + "Add / Select at least one tool in the tool-table.\n" "Click the header to select all, or Ctrl + LMB\n" "for custom selection of tools." )) From 0221a9cfb6718a6ea175fea8c016498817e41c85 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 16 Jan 2020 15:49:51 +0200 Subject: [PATCH 027/209] - updated the Excellon and Geometry UI to be similar - put bases for future changes to Excellon Object UI such that each tool will hold it's own parameters --- FlatCAMObj.py | 276 +++++++++++++++++++++++++++-------------- README.md | 2 + flatcamGUI/ObjectUI.py | 79 ++++++------ 3 files changed, 229 insertions(+), 128 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 6b98f6f2..8adf87c9 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -2775,22 +2775,92 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): def ui_connect(self): + # selective plotting for row in range(self.ui.tools_table.rowCount() - 2): self.ui.tools_table.cellWidget(row, 5).clicked.connect(self.on_plot_cb_click_table) self.ui.plot_cb.stateChanged.connect(self.on_plot_cb_click) + # rows selected + self.ui.tools_table.clicked.connect(self.on_row_selection_change) + self.ui.tools_table.horizontalHeader().sectionClicked.connect(self.on_row_selection_change) + def ui_disconnect(self): + # selective plotting for row in range(self.ui.tools_table.rowCount()): try: self.ui.tools_table.cellWidget(row, 5).clicked.disconnect() except (TypeError, AttributeError): pass - try: self.ui.plot_cb.stateChanged.disconnect() except (TypeError, AttributeError): pass + # rows selected + try: + self.ui.tools_table.clicked.disconnect() + except (TypeError, AttributeError): + pass + try: + self.ui.tools_table.horizontalHeader().sectionClicked.disconnect() + except (TypeError, AttributeError): + pass + + def on_row_selection_change(self): + self.update_ui() + + def update_ui(self, row=None): + self.ui.blockSignals(True) + + if row is None: + sel_rows = list() + sel_items = self.ui.tools_table.selectedItems() + for it in sel_items: + sel_rows.append(it.row()) + else: + sel_rows = row if type(row) == list else [row] + + if not sel_rows: + sel_rows = [0] + + if len(sel_rows) == 1: + # update the QLabel that shows for which Tool we have the parameters in the UI form + tooluid = int(self.ui.tools_table.item(sel_rows[0], 0).text()) + self.ui.tool_data_label.setText( + "%s: %s %d" % (_('Parameters for'), _("Tool"), tooluid) + ) + else: + self.ui.tool_data_label.setText( + "%s: %s" % (_('Parameters for'), _("Multiple Tools")) + ) + + for c_row in sel_rows: + # populate the form with the data from the tool associated with the row parameter + try: + item = self.ui.tools_table.item(c_row, 0) + if type(item) is not None: + tooluid = int(item.text()) + else: + self.ui.blockSignals(False) + return + except Exception as e: + log.debug("Tool missing. Add a tool in Geo Tool Table. %s" % str(e)) + self.ui.blockSignals(False) + return + + # try: + # # set the form with data from the newly selected tool + # for tooluid_key, tooluid_value in list(self.tools.items()): + # if int(tooluid_key) == tooluid: + # for key, value in tooluid_value.items(): + # if key == 'data': + # form_value_storage = tooluid_value[key] + # self.update_form(form_value_storage) + # except Exception as e: + # log.debug("FlatCAMObj ---> update_ui() " + str(e)) + + self.ui.blockSignals(False) + def on_tool_offset_edit(self): # if connected, disconnect the signal from the slot on item_changed as it creates issues for row in range(self.ui.tools_table.rowCount()): @@ -4056,7 +4126,10 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ui.copytool_btn.clicked.connect(lambda: self.on_tool_copy()) self.ui.deltool_btn.clicked.connect(lambda: self.on_tool_delete()) - self.ui.geo_tools_table.currentItemChanged.connect(self.on_row_selection_change) + # self.ui.geo_tools_table.currentItemChanged.connect(self.on_row_selection_change) + self.ui.geo_tools_table.clicked.connect(self.on_row_selection_change) + self.ui.geo_tools_table.horizontalHeader().sectionClicked.connect(self.on_row_selection_change) + self.ui.geo_tools_table.itemChanged.connect(self.on_tool_edit) self.ui.tool_offset_entry.returnPressed.connect(self.on_offset_value_edited) @@ -4115,7 +4188,11 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): pass try: - self.ui.geo_tools_table.currentItemChanged.disconnect() + self.ui.geo_tools_table.clicked.disconnect() + except (TypeError, AttributeError): + pass + try: + self.ui.geo_tools_table.horizontalHeader().sectionClicked.disconnect() except (TypeError, AttributeError): pass @@ -4140,8 +4217,84 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): except (TypeError, AttributeError): pass + def on_row_selection_change(self): + self.update_ui() + + def update_ui(self, row=None): + self.ui.blockSignals(True) + + if row is None: + sel_rows = list() + sel_items = self.ui.geo_tools_table.selectedItems() + for it in sel_items: + sel_rows.append(it.row()) + else: + sel_rows = row if type(row) == list else [row] + + if not sel_rows: + sel_rows = [0] + + for current_row in sel_rows: + self.set_tool_offset_visibility(current_row) + + # populate the form with the data from the tool associated with the row parameter + try: + item = self.ui.geo_tools_table.item(current_row, 5) + if type(item) is not None: + tooluid = int(item.text()) + else: + self.ui.blockSignals(False) + return + except Exception as e: + log.debug("Tool missing. Add a tool in Geo Tool Table. %s" % str(e)) + self.ui.blockSignals(False) + return + + # update the QLabel that shows for which Tool we have the parameters in the UI form + if len(sel_rows) == 1: + self.ui.tool_data_label.setText( + "%s: %s %d" % (_('Parameters for'), _("Tool"), tooluid) + ) + else: + self.ui.tool_data_label.setText( + "%s: %s" % (_('Parameters for'), _("Multiple Tools")) + ) + + # update the form with the V-Shape fields if V-Shape selected in the geo_tool_table + # also modify the Cut Z form entry to reflect the calculated Cut Z from values got from V-Shape Fields + try: + item = self.ui.geo_tools_table.cellWidget(current_row, 4) + if item is not None: + tool_type_txt = item.currentText() + self.ui_update_v_shape(tool_type_txt=tool_type_txt) + else: + self.ui.blockSignals(False) + return + except Exception as e: + log.debug("Tool missing in ui_update_v_shape(). Add a tool in Geo Tool Table. %s" % str(e)) + return + + try: + # set the form with data from the newly selected tool + for tooluid_key, tooluid_value in list(self.tools.items()): + if int(tooluid_key) == tooluid: + for key, value in tooluid_value.items(): + if key == 'data': + form_value_storage = tooluid_value[key] + self.update_form(form_value_storage) + if key == 'offset_value': + # update the offset value in the entry even if the entry is hidden + self.ui.tool_offset_entry.set_value(tooluid_value[key]) + + if key == 'tool_type' and value == 'V': + self.update_cutz() + except Exception as e: + log.debug("FlatCAMObj ---> update_ui() " + str(e)) + + self.ui.blockSignals(False) + def on_tool_add(self, dia=None): - self.ui_disconnect() + self.ui.blockSignals(True) self.units = self.app.defaults['units'].upper() @@ -4214,6 +4367,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ser_attrs.append('tools') self.app.inform.emit('[success] %s' % _("Tool added in Tool Table.")) + self.ui.blockSignals(False) self.build_ui() # if there is no tool left in the Tools Table, enable the parameters GUI @@ -4244,7 +4398,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): :return: None """ - self.ui_disconnect() + self.ui.blockSignals(True) self.units = self.app.defaults['units'].upper() tooldia = float(tool['tooldia']) @@ -4288,6 +4442,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): pass self.ser_attrs.append('tools') + self.ui.blockSignals(False) self.build_ui() # if there is no tool left in the Tools Table, enable the parameters GUI @@ -4295,7 +4450,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ui.geo_param_frame.setDisabled(False) def on_tool_copy(self, all=None): - self.ui_disconnect() + self.ui.blockSignals(True) # find the tool_uid maximum value in the self.tools uid_list = [] @@ -4319,8 +4474,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): max_uid += 1 self.tools[int(max_uid)] = deepcopy(self.tools[tooluid_copy]) except AttributeError: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Failed. Select a tool to copy.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Failed. Select a tool to copy.")) + self.ui.blockSignals(False) self.build_ui() return except Exception as e: @@ -4328,8 +4483,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): # deselect the table # self.ui.geo_tools_table.clearSelection() else: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Failed. Select a tool to copy.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Failed. Select a tool to copy.")) + self.ui.blockSignals(False) self.build_ui() return else: @@ -4355,12 +4510,12 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): pass self.ser_attrs.append('tools') + self.ui.blockSignals(False) self.build_ui() self.app.inform.emit('[success] %s' % _("Tool was copied in Tool Table.")) def on_tool_edit(self, current_item): - - self.ui_disconnect() + self.ui.blockSignals(True) current_row = current_item.row() try: @@ -4385,10 +4540,11 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): pass self.app.inform.emit('[success] %s' % _("Tool was edited in Tool Table.")) + self.ui.blockSignals(False) self.build_ui() def on_tool_delete(self, all=None): - self.ui_disconnect() + self.ui.blockSignals(True) if all is None: if self.ui.geo_tools_table.selectedItems(): @@ -4412,8 +4568,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.tools = deepcopy(temp_tools) temp_tools.clear() except AttributeError: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Failed. Select a tool to delete.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Failed. Select a tool to delete.")) + self.ui.blockSignals(False) self.build_ui() return except Exception as e: @@ -4421,8 +4577,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): # deselect the table # self.ui.geo_tools_table.clearSelection() else: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Failed. Select a tool to delete.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Failed. Select a tool to delete.")) + self.ui.blockSignals(False) self.build_ui() return else: @@ -4443,9 +4599,9 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): pass self.ser_attrs.append('tools') + self.ui.blockSignals(False) self.build_ui() - self.app.inform.emit('[success] %s' % - _("Tool was deleted in Tool Table.")) + self.app.inform.emit('[success] %s' % _("Tool was deleted in Tool Table.")) obj_active = self.app.collection.get_active() # if the object was MultiGeo and now it has no tool at all (therefore no geometry) @@ -4474,72 +4630,6 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): if self.ui.geo_tools_table.rowCount() == 0: self.ui.geo_param_frame.setDisabled(True) - def on_row_selection_change(self): - self.update_ui() - - def update_ui(self, row=None): - self.ui_disconnect() - - if row is None: - try: - current_row = self.ui.geo_tools_table.currentRow() - except Exception: - current_row = 0 - else: - current_row = row - - if current_row < 0: - current_row = 0 - - self.set_tool_offset_visibility(current_row) - - # populate the form with the data from the tool associated with the row parameter - try: - item = self.ui.geo_tools_table.item(current_row, 5) - if type(item) is not None: - tooluid = int(item.text()) - else: - return - except Exception as e: - log.debug("Tool missing. Add a tool in Geo Tool Table. %s" % str(e)) - return - - # update the QLabel that shows for which Tool we have the parameters in the UI form - self.ui.tool_data_label.setText( - "%s: %s %d" % (_('Parameters for'), _("Tool"), tooluid) - ) - - # update the form with the V-Shape fields if V-Shape selected in the geo_tool_table - # also modify the Cut Z form entry to reflect the calculated Cut Z from values got from V-Shape Fields - try: - item = self.ui.geo_tools_table.cellWidget(current_row, 4) - if item is not None: - tool_type_txt = item.currentText() - self.ui_update_v_shape(tool_type_txt=tool_type_txt) - else: - return - except Exception as e: - log.debug("Tool missing in ui_update_v_shape(). Add a tool in Geo Tool Table. %s" % str(e)) - return - - try: - # set the form with data from the newly selected tool - for tooluid_key, tooluid_value in list(self.tools.items()): - if int(tooluid_key) == tooluid: - for key, value in tooluid_value.items(): - if key == 'data': - form_value_storage = tooluid_value[key] - self.update_form(form_value_storage) - if key == 'offset_value': - # update the offset value in the entry even if the entry is hidden - self.ui.tool_offset_entry.set_value(tooluid_value[key]) - - if key == 'tool_type' and value == 'V': - self.update_cutz() - except Exception as e: - log.debug("FlatCAMObj ---> update_ui() " + str(e)) - self.ui_connect() - def ui_update_v_shape(self, tool_type_txt): if tool_type_txt == 'V': self.ui.tipdialabel.show() @@ -4643,7 +4733,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): log.debug("FlatCAMGeometry.gui_form_to_storage() --> no tool in Tools Table, aborting.") return - self.ui_disconnect() + self.ui.blockSignals(True) row = self.ui.geo_tools_table.currentRow() if row < 0: @@ -4698,7 +4788,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.tools = deepcopy(temp_tools) temp_tools.clear() - self.ui_connect() + self.ui.blockSignals(False) def gui_form_to_storage(self): if self.ui.geo_tools_table.rowCount() == 0: @@ -4706,7 +4796,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): log.debug("FlatCAMGeometry.gui_form_to_storage() --> no tool in Tools Table, aborting.") return - self.ui_disconnect() + self.ui.blockSignals(True) widget_changed = self.sender() try: widget_idx = self.ui.grid3.indexOf(widget_changed) @@ -4785,7 +4875,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.tools.clear() self.tools = deepcopy(temp_tools) temp_tools.clear() - self.ui_connect() + self.ui.blockSignals(False) def select_tools_table_row(self, row, clearsel=None): if clearsel: @@ -5813,7 +5903,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.read_form_item('plot') self.plot() - self.ui_disconnect() + self.ui.blockSignals(True) cb_flag = self.ui.plot_cb.isChecked() for row in range(self.ui.geo_tools_table.rowCount()): table_cb = self.ui.geo_tools_table.cellWidget(row, 6) @@ -5821,11 +5911,11 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): table_cb.setChecked(True) else: table_cb.setChecked(False) - self.ui_connect() + self.ui.blockSignals(False) def on_plot_cb_click_table(self): # self.ui.cnc_tools_table.cellWidget(row, 2).widget().setCheckState(QtCore.Qt.Unchecked) - self.ui_disconnect() + self.ui.blockSignals(True) # cw = self.sender() # cw_index = self.ui.geo_tools_table.indexAt(cw.pos()) # cw_row = cw_index.row() @@ -5858,7 +5948,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ui.plot_cb.setChecked(False) else: self.ui.plot_cb.setChecked(True) - self.ui_connect() + self.ui.blockSignals(False) def merge(self, geo_list, geo_final, multigeo=None): """ diff --git a/README.md b/README.md index e49424ed..807ddbed 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ CAD program, and create G-Code for Isolation routing. - work in Paint Tool to bring it up to date with NCC Tool - updated the GUI in preferences for Calculator Tool - a small change in the Excellon UI +- updated the Excellon and Geometry UI to be similar +- put bases for future changes to Excellon Object UI such that each tool will hold it's own parameters 15.01.2020 diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index 94729ce2..5137b47d 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -800,16 +800,26 @@ class ExcellonObjectUI(ObjectUI): _("Toggle display of the drills for the current tool.\n" "This does not select the tools for G-code generation.")) - self.empty_label = QtWidgets.QLabel('') - self.tools_box.addWidget(self.empty_label) + self.tools_box.addWidget(QtWidgets.QLabel('')) - # ### Create CNC Job #### - self.cncjob_label = QtWidgets.QLabel('%s' % _('Create CNC Job')) - self.cncjob_label.setToolTip( - _("Create a CNC Job object\n" - "for this drill object.") + # ########################################################### + # ############# Create CNC Job ############################## + # ########################################################### + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + self.tools_box.addWidget(separator_line) + + self.tool_data_label = QtWidgets.QLabel( + "%s: %s %d" % (_('Parameters for'), _("Tool"), int(1))) + self.tool_data_label.setToolTip( + _( + "The data used for creating GCode.\n" + "Each tool store it's own set of such data." + ) ) - self.tools_box.addWidget(self.cncjob_label) + self.tools_box.addWidget(self.tool_data_label) grid1 = QtWidgets.QGridLayout() self.tools_box.addLayout(grid1) @@ -855,33 +865,29 @@ class ExcellonObjectUI(ObjectUI): grid1.addWidget(self.travelz_entry, 1, 1) # Tool change: - self.toolchange_cb = FCCheckBox('%s' % _("Tool change")) + self.toolchange_cb = FCCheckBox('%s:' % _("Tool change Z")) self.toolchange_cb.setToolTip( _("Include tool-change sequence\n" "in G-Code (Pause for tool change).") ) - grid1.addWidget(self.toolchange_cb, 2, 0, 1, 2) - # Tool change Z: - toolchzlabel = QtWidgets.QLabel('%s:' % _("Tool change Z")) - toolchzlabel.setToolTip( + self.toolchangez_entry = FCDoubleSpinner() + self.toolchangez_entry.set_precision(self.decimals) + self.toolchangez_entry.setToolTip( _("Z-axis position (height) for\n" "tool change.") ) - grid1.addWidget(toolchzlabel, 3, 0) - self.toolchangez_entry = FCDoubleSpinner() - self.toolchangez_entry.set_precision(self.decimals) - if machinist_setting == 0: self.toolchangez_entry.set_range(0.0, 9999.9999) else: self.toolchangez_entry.set_range(-9999.9999, 9999.9999) self.toolchangez_entry.setSingleStep(0.1) - - grid1.addWidget(self.toolchangez_entry, 3, 1) self.ois_tcz_e = OptionalInputSection(self.toolchange_cb, [self.toolchangez_entry]) + grid1.addWidget(self.toolchange_cb, 2, 0) + grid1.addWidget(self.toolchangez_entry, 2, 1) + # Start move Z: self.estartz_label = QtWidgets.QLabel('%s:' % _("Start Z")) self.estartz_label.setToolTip( @@ -1022,6 +1028,11 @@ class ExcellonObjectUI(ObjectUI): self.feedrate_probe_label.hide() self.feedrate_probe_entry.setVisible(False) + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid1.addWidget(separator_line, 13, 0, 1, 2) + grid2 = QtWidgets.QGridLayout() self.tools_box.addLayout(grid2) grid2.setColumnStretch(0, 0) @@ -1349,9 +1360,9 @@ class GeometryObjectUI(ObjectUI): self.empty_label = QtWidgets.QLabel('') self.geo_tools_box.addWidget(self.empty_label) - # ################## - # Create CNC Job ### - # ################## + # ########################################################### + # ############# Create CNC Job ############################## + # ########################################################### separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) @@ -1477,15 +1488,8 @@ class GeometryObjectUI(ObjectUI): self.grid3.addWidget(travelzlabel, 5, 0) self.grid3.addWidget(self.travelz_entry, 5, 1) - # Tool change: - self.toolchzlabel = QtWidgets.QLabel('%s:' % _("Tool change Z")) - self.toolchzlabel.setToolTip( - _( - "Z-axis position (height) for\n" - "tool change." - ) - ) - self.toolchangeg_cb = FCCheckBox('%s' % _("Tool change")) + # Tool change + self.toolchangeg_cb = FCCheckBox('%s:' % _("Tool change Z")) self.toolchangeg_cb.setToolTip( _( "Include tool-change sequence\n" @@ -1494,6 +1498,12 @@ class GeometryObjectUI(ObjectUI): ) self.toolchangez_entry = FCDoubleSpinner() self.toolchangez_entry.set_precision(self.decimals) + self.toolchangez_entry.setToolTip( + _( + "Z-axis position (height) for\n" + "tool change." + ) + ) if machinist_setting == 0: self.toolchangez_entry.set_range(0, 9999.9999) @@ -1501,12 +1511,11 @@ class GeometryObjectUI(ObjectUI): self.toolchangez_entry.set_range(-9999.9999, 9999.9999) self.toolchangez_entry.setSingleStep(0.1) - - self.grid3.addWidget(self.toolchangeg_cb, 6, 0, 1, 2) - self.grid3.addWidget(self.toolchzlabel, 7, 0) - self.grid3.addWidget(self.toolchangez_entry, 7, 1) self.ois_tcz_geo = OptionalInputSection(self.toolchangeg_cb, [self.toolchangez_entry]) + self.grid3.addWidget(self.toolchangeg_cb, 6, 0) + self.grid3.addWidget(self.toolchangez_entry, 6, 1) + # The Z value for the start move # startzlabel = QtWidgets.QLabel('Start move Z:') # startzlabel.setToolTip( From b71d4e8c4570b862c2834d270a4c7f8bc47f5279 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 16 Jan 2020 16:43:39 +0200 Subject: [PATCH 028/209] - in ParseExcellon.Excellon the self.tools dict has now a key 'data' which holds a dict with all the default values for Excellon and Geometry - Excellon and Geometry objects, when started with multiple tools selected, the parameters tool name reflect this situation --- FlatCAMObj.py | 23 ++++++++++++++++++++++- README.md | 2 ++ flatcamParsers/ParseExcellon.py | 26 ++++++++++++++++++++------ 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 8adf87c9..cbb4a83b 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -2622,9 +2622,10 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): # sort the tool diameter column # self.ui.tools_table.sortItems(1) + # all the tools are selected by default self.ui.tools_table.selectColumn(0) - # + self.ui.tools_table.resizeColumnsToContents() self.ui.tools_table.resizeRowsToContents() @@ -2686,6 +2687,16 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): except (TypeError, AttributeError): pass + # set the text on tool_data_label after loading the object + sel_rows = list() + sel_items = self.ui.tools_table.selectedItems() + for it in sel_items: + sel_rows.append(it.row()) + if len(sel_rows) > 1: + self.ui.tool_data_label.setText( + "%s: %s" % (_('Parameters for'), _("Multiple Tools")) + ) + self.ui_connect() def set_ui(self, ui): @@ -3855,6 +3866,16 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ui.e_cut_entry.setDisabled(False) if self.ui.extracut_cb.get_value() else \ self.ui.e_cut_entry.setDisabled(True) + # set the text on tool_data_label after loading the object + sel_rows = list() + sel_items = self.ui.geo_tools_table.selectedItems() + for it in sel_items: + sel_rows.append(it.row()) + if len(sel_rows) > 1: + self.ui.tool_data_label.setText( + "%s: %s" % (_('Parameters for'), _("Multiple Tools")) + ) + def set_ui(self, ui): FlatCAMObj.set_ui(self, ui) diff --git a/README.md b/README.md index 807ddbed..9e4ab4c3 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,8 @@ CAD program, and create G-Code for Isolation routing. - a small change in the Excellon UI - updated the Excellon and Geometry UI to be similar - put bases for future changes to Excellon Object UI such that each tool will hold it's own parameters +- in ParseExcellon.Excellon the self.tools dict has now a key 'data' which holds a dict with all the default values for Excellon and Geometry +- Excellon and Geometry objects, when started with multiple tools selected, the parameters tool name reflect this situation 15.01.2020 diff --git a/flatcamParsers/ParseExcellon.py b/flatcamParsers/ParseExcellon.py index adba5941..fb024bf4 100644 --- a/flatcamParsers/ParseExcellon.py +++ b/flatcamParsers/ParseExcellon.py @@ -121,6 +121,9 @@ class Excellon(Geometry): self.zeros_found = deepcopy(self.zeros) self.units_found = deepcopy(self.units) + # default set of data to be added to each tool in self.tools as self.tools[tool]['data'] = self.default_data + self.default_data = dict() + # this will serve as a default if the Excellon file has no info regarding of tool diameters (this info may be # in another file like for PCB WIzard ECAD software self.toolless_diam = 1.0 @@ -261,6 +264,14 @@ class Excellon(Geometry): except Exception: return "fail" + # fill in self.default_data values from self.options + for opt_key, opt_val in self.app.options.items(): + if opt_key.find('excellon_') == 0: + self.default_data[opt_key] = deepcopy(opt_val) + for opt_key, opt_val in self.app.options.items(): + if opt_key.find('geometry_') == 0: + self.default_data[opt_key] = deepcopy(opt_val) + def parse_lines(self, elines): """ Main Excellon parser. @@ -961,10 +972,8 @@ class Excellon(Geometry): try: # clear the solid_geometry in self.tools for tool in self.tools: - try: - self.tools[tool]['solid_geometry'][:] = [] - except KeyError: - self.tools[tool]['solid_geometry'] = [] + self.tools[tool]['solid_geometry'] = list() + self.tools[tool]['data'] = dict() for drill in self.drills: # poly = drill['point'].buffer(self.tools[drill['tool']]["C"]/2.0) @@ -979,7 +988,10 @@ class Excellon(Geometry): tooldia = self.tools[drill['tool']]['C'] poly = drill['point'].buffer(tooldia / 2.0, int(int(self.geo_steps_per_circle) / 4)) self.solid_geometry.append(poly) - self.tools[drill['tool']]['solid_geometry'].append(poly) + + tool_in_drills = drill['tool'] + self.tools[tool_in_drills]['solid_geometry'].append(poly) + self.tools[tool_in_drills]['data'] = deepcopy(self.default_data) for slot in self.slots: slot_tooldia = self.tools[slot['tool']]['C'] @@ -989,8 +1001,10 @@ class Excellon(Geometry): lines_string = LineString([start, stop]) poly = lines_string.buffer(slot_tooldia / 2.0, int(int(self.geo_steps_per_circle) / 4)) self.solid_geometry.append(poly) - self.tools[slot['tool']]['solid_geometry'].append(poly) + tool_in_slots = slot['tool'] + self.tools[tool_in_slots]['solid_geometry'].append(poly) + self.tools[tool_in_slots]['data'] = deepcopy(self.default_data) except Exception as e: log.debug("flatcamParsers.ParseExcellon.Excellon.create_geometry() -> " "Excellon geometry creation failed due of ERROR: %s" % str(e)) From c41703089608ab7a01f0306d7e396544dc6c3821 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 16 Jan 2020 16:55:34 +0200 Subject: [PATCH 029/209] - moved default_data data update from Excellon parser to the Excellon object constructor --- FlatCAMObj.py | 11 +++++++++++ README.md | 1 + flatcamParsers/ParseExcellon.py | 11 ----------- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index cbb4a83b..2e466d78 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -2269,6 +2269,17 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): # dict to hold the tool number as key and tool offset as value self.tool_offset = dict() + # default set of data to be added to each tool in self.tools as self.tools[tool]['data'] = self.default_data + self.default_data = dict() + + # fill in self.default_data values from self.options + for opt_key, opt_val in self.app.options.items(): + if opt_key.find('excellon_') == 0: + self.default_data[opt_key] = deepcopy(opt_val) + for opt_key, opt_val in self.app.options.items(): + if opt_key.find('geometry_') == 0: + self.default_data[opt_key] = deepcopy(opt_val) + # variable to store the total amount of drills per job self.tot_drill_cnt = 0 self.tool_row = 0 diff --git a/README.md b/README.md index 9e4ab4c3..d8c3dbb6 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ CAD program, and create G-Code for Isolation routing. - put bases for future changes to Excellon Object UI such that each tool will hold it's own parameters - in ParseExcellon.Excellon the self.tools dict has now a key 'data' which holds a dict with all the default values for Excellon and Geometry - Excellon and Geometry objects, when started with multiple tools selected, the parameters tool name reflect this situation +- moved default_data data update from Excellon parser to the Excellon object constructor 15.01.2020 diff --git a/flatcamParsers/ParseExcellon.py b/flatcamParsers/ParseExcellon.py index fb024bf4..a82cf401 100644 --- a/flatcamParsers/ParseExcellon.py +++ b/flatcamParsers/ParseExcellon.py @@ -121,9 +121,6 @@ class Excellon(Geometry): self.zeros_found = deepcopy(self.zeros) self.units_found = deepcopy(self.units) - # default set of data to be added to each tool in self.tools as self.tools[tool]['data'] = self.default_data - self.default_data = dict() - # this will serve as a default if the Excellon file has no info regarding of tool diameters (this info may be # in another file like for PCB WIzard ECAD software self.toolless_diam = 1.0 @@ -264,14 +261,6 @@ class Excellon(Geometry): except Exception: return "fail" - # fill in self.default_data values from self.options - for opt_key, opt_val in self.app.options.items(): - if opt_key.find('excellon_') == 0: - self.default_data[opt_key] = deepcopy(opt_val) - for opt_key, opt_val in self.app.options.items(): - if opt_key.find('geometry_') == 0: - self.default_data[opt_key] = deepcopy(opt_val) - def parse_lines(self, elines): """ Main Excellon parser. From 957903d30799c30af313219b5df778abd0d173bb Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 17 Jan 2020 03:15:13 +0200 Subject: [PATCH 030/209] - more changes to Excellon UI --- FlatCAMObj.py | 97 +++++++---- README.md | 4 + flatcamGUI/ObjectUI.py | 378 ++++++++++++++++++++++++++++++++--------- 3 files changed, 363 insertions(+), 116 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 2e466d78..447090a5 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -2792,6 +2792,9 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.ui.generate_milling_button.clicked.connect(self.on_generate_milling_button_click) self.ui.generate_milling_slots_button.clicked.connect(self.on_generate_milling_slots_button_click) + self.on_operation_type(val='drill') + self.ui.operation_radio.activated_custom.connect(self.on_operation_type) + self.ui.pp_excellon_name_cb.activated.connect(self.on_pp_changed) self.units_found = self.app.defaults['units'] @@ -2832,7 +2835,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.update_ui() def update_ui(self, row=None): - self.ui.blockSignals(True) + self.ui_disconnect() if row is None: sel_rows = list() @@ -2863,11 +2866,11 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): if type(item) is not None: tooluid = int(item.text()) else: - self.ui.blockSignals(False) + self.ui_connect() return except Exception as e: log.debug("Tool missing. Add a tool in Geo Tool Table. %s" % str(e)) - self.ui.blockSignals(False) + self.ui_connect() return # try: @@ -2881,7 +2884,31 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): # except Exception as e: # log.debug("FlatCAMObj ---> update_ui() " + str(e)) - self.ui.blockSignals(False) + self.ui_connect() + + def on_operation_type(self, val): + if val == 'mill': + self.ui.mill_type_label.show() + self.ui.mill_type_radio.show() + self.ui.mill_dia_label.show() + self.ui.mill_dia_entry.show() + self.ui.mpass_cb.show() + self.ui.maxdepth_entry.show() + self.ui.frxylabel.show() + self.ui.xyfeedrate_entry.show() + self.ui.extracut_cb.show() + self.ui.e_cut_entry.show() + else: + self.ui.mill_type_label.hide() + self.ui.mill_type_radio.hide() + self.ui.mill_dia_label.hide() + self.ui.mill_dia_entry.hide() + self.ui.mpass_cb.hide() + self.ui.maxdepth_entry.hide() + self.ui.frxylabel.hide() + self.ui.xyfeedrate_entry.hide() + self.ui.extracut_cb.hide() + self.ui.e_cut_entry.hide() def on_tool_offset_edit(self): # if connected, disconnect the signal from the slot on item_changed as it creates issues @@ -4253,7 +4280,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.update_ui() def update_ui(self, row=None): - self.ui.blockSignals(True) + self.ui_disconnect() if row is None: sel_rows = list() @@ -4275,11 +4302,11 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): if type(item) is not None: tooluid = int(item.text()) else: - self.ui.blockSignals(False) + self.ui_connect() return except Exception as e: log.debug("Tool missing. Add a tool in Geo Tool Table. %s" % str(e)) - self.ui.blockSignals(False) + self.ui_connect() return # update the QLabel that shows for which Tool we have the parameters in the UI form @@ -4300,7 +4327,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): tool_type_txt = item.currentText() self.ui_update_v_shape(tool_type_txt=tool_type_txt) else: - self.ui.blockSignals(False) + self.ui_connect() return except Exception as e: log.debug("Tool missing in ui_update_v_shape(). Add a tool in Geo Tool Table. %s" % str(e)) @@ -4308,25 +4335,25 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): try: # set the form with data from the newly selected tool - for tooluid_key, tooluid_value in list(self.tools.items()): + for tooluid_key, tooluid_value in self.tools.items(): if int(tooluid_key) == tooluid: for key, value in tooluid_value.items(): if key == 'data': - form_value_storage = tooluid_value[key] + form_value_storage = tooluid_value['data'] self.update_form(form_value_storage) if key == 'offset_value': # update the offset value in the entry even if the entry is hidden - self.ui.tool_offset_entry.set_value(tooluid_value[key]) + self.ui.tool_offset_entry.set_value(tooluid_value['offset_value']) if key == 'tool_type' and value == 'V': self.update_cutz() except Exception as e: - log.debug("FlatCAMObj ---> update_ui() " + str(e)) + log.debug("FlatCAMGeometry.update_ui() -> %s " % str(e)) - self.ui.blockSignals(False) + self.ui_connect() def on_tool_add(self, dia=None): - self.ui.blockSignals(True) + self.ui_disconnect() self.units = self.app.defaults['units'].upper() @@ -4399,7 +4426,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ser_attrs.append('tools') self.app.inform.emit('[success] %s' % _("Tool added in Tool Table.")) - self.ui.blockSignals(False) + self.ui_connect() self.build_ui() # if there is no tool left in the Tools Table, enable the parameters GUI @@ -4430,7 +4457,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): :return: None """ - self.ui.blockSignals(True) + self.ui_disconnect() self.units = self.app.defaults['units'].upper() tooldia = float(tool['tooldia']) @@ -4474,7 +4501,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): pass self.ser_attrs.append('tools') - self.ui.blockSignals(False) + self.ui_connect() self.build_ui() # if there is no tool left in the Tools Table, enable the parameters GUI @@ -4482,7 +4509,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ui.geo_param_frame.setDisabled(False) def on_tool_copy(self, all=None): - self.ui.blockSignals(True) + self.ui_disconnect() # find the tool_uid maximum value in the self.tools uid_list = [] @@ -4507,7 +4534,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.tools[int(max_uid)] = deepcopy(self.tools[tooluid_copy]) except AttributeError: self.app.inform.emit('[WARNING_NOTCL] %s' % _("Failed. Select a tool to copy.")) - self.ui.blockSignals(False) + self.ui_connect() self.build_ui() return except Exception as e: @@ -4516,7 +4543,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): # self.ui.geo_tools_table.clearSelection() else: self.app.inform.emit('[WARNING_NOTCL] %s' % _("Failed. Select a tool to copy.")) - self.ui.blockSignals(False) + self.ui_connect() self.build_ui() return else: @@ -4542,12 +4569,12 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): pass self.ser_attrs.append('tools') - self.ui.blockSignals(False) + self.ui_connect() self.build_ui() self.app.inform.emit('[success] %s' % _("Tool was copied in Tool Table.")) def on_tool_edit(self, current_item): - self.ui.blockSignals(True) + self.ui_disconnect() current_row = current_item.row() try: @@ -4572,11 +4599,11 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): pass self.app.inform.emit('[success] %s' % _("Tool was edited in Tool Table.")) - self.ui.blockSignals(False) + self.ui_connect() self.build_ui() def on_tool_delete(self, all=None): - self.ui.blockSignals(True) + self.ui_disconnect() if all is None: if self.ui.geo_tools_table.selectedItems(): @@ -4601,7 +4628,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): temp_tools.clear() except AttributeError: self.app.inform.emit('[WARNING_NOTCL] %s' % _("Failed. Select a tool to delete.")) - self.ui.blockSignals(False) + self.ui_connect() self.build_ui() return except Exception as e: @@ -4610,7 +4637,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): # self.ui.geo_tools_table.clearSelection() else: self.app.inform.emit('[WARNING_NOTCL] %s' % _("Failed. Select a tool to delete.")) - self.ui.blockSignals(False) + self.ui_connect() self.build_ui() return else: @@ -4631,7 +4658,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): pass self.ser_attrs.append('tools') - self.ui.blockSignals(False) + self.ui_connect() self.build_ui() self.app.inform.emit('[success] %s' % _("Tool was deleted in Tool Table.")) @@ -4765,7 +4792,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): log.debug("FlatCAMGeometry.gui_form_to_storage() --> no tool in Tools Table, aborting.") return - self.ui.blockSignals(True) + self.ui_disconnect() row = self.ui.geo_tools_table.currentRow() if row < 0: @@ -4820,7 +4847,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.tools = deepcopy(temp_tools) temp_tools.clear() - self.ui.blockSignals(False) + self.ui_connect() def gui_form_to_storage(self): if self.ui.geo_tools_table.rowCount() == 0: @@ -4828,7 +4855,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): log.debug("FlatCAMGeometry.gui_form_to_storage() --> no tool in Tools Table, aborting.") return - self.ui.blockSignals(True) + self.ui_disconnect() widget_changed = self.sender() try: widget_idx = self.ui.grid3.indexOf(widget_changed) @@ -4907,7 +4934,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.tools.clear() self.tools = deepcopy(temp_tools) temp_tools.clear() - self.ui.blockSignals(False) + self.ui_connect() def select_tools_table_row(self, row, clearsel=None): if clearsel: @@ -5935,7 +5962,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.read_form_item('plot') self.plot() - self.ui.blockSignals(True) + self.ui_disconnect() cb_flag = self.ui.plot_cb.isChecked() for row in range(self.ui.geo_tools_table.rowCount()): table_cb = self.ui.geo_tools_table.cellWidget(row, 6) @@ -5943,11 +5970,11 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): table_cb.setChecked(True) else: table_cb.setChecked(False) - self.ui.blockSignals(False) + self.ui_connect() def on_plot_cb_click_table(self): # self.ui.cnc_tools_table.cellWidget(row, 2).widget().setCheckState(QtCore.Qt.Unchecked) - self.ui.blockSignals(True) + self.ui_disconnect() # cw = self.sender() # cw_index = self.ui.geo_tools_table.indexAt(cw.pos()) # cw_row = cw_index.row() @@ -5980,7 +6007,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ui.plot_cb.setChecked(False) else: self.ui.plot_cb.setChecked(True) - self.ui.blockSignals(False) + self.ui_connect() def merge(self, geo_list, geo_final, multigeo=None): """ diff --git a/README.md b/README.md index d8c3dbb6..899a10e3 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +17.01.2020 + +- more changes to Excellon UI + 16.01.2020 - updated/optimized the GUI in Preferences for Paint Tool and for NCC Tool diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index 5137b47d..7143de33 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -821,10 +821,74 @@ class ExcellonObjectUI(ObjectUI): ) self.tools_box.addWidget(self.tool_data_label) - grid1 = QtWidgets.QGridLayout() - self.tools_box.addLayout(grid1) - grid1.setColumnStretch(0, 0) - grid1.setColumnStretch(1, 1) + self.exc_param_frame = QtWidgets.QFrame() + self.exc_param_frame.setContentsMargins(0, 0, 0, 0) + self.tools_box.addWidget(self.exc_param_frame) + + self.exc_tools_box = QtWidgets.QVBoxLayout() + self.exc_tools_box.setContentsMargins(0, 0, 0, 0) + self.exc_param_frame.setLayout(self.exc_tools_box) + + # ################################################################# + # ################# GRID LAYOUT 3 ############################### + # ################################################################# + + self.grid3 = QtWidgets.QGridLayout() + self.grid3.setColumnStretch(0, 0) + self.grid3.setColumnStretch(1, 1) + self.exc_tools_box.addLayout(self.grid3) + + # Operation Type + self.operation_label = QtWidgets.QLabel('%s:' % _('Operation')) + self.operation_label.setToolTip( + _("Operation type:\n" + "- Drilling -> will drill the drills/slots associated with this tool\n" + "- Milling -> will mill the drills/slots") + ) + self.operation_radio = RadioSet( + [ + {'label': _('Drilling'), 'value': 'drill'}, + {'label': _("Milling"), 'value': 'mill'} + ] + ) + + self.grid3.addWidget(self.operation_label, 0, 0) + self.grid3.addWidget(self.operation_radio, 0, 1) + + # separator_line = QtWidgets.QFrame() + # separator_line.setFrameShape(QtWidgets.QFrame.HLine) + # separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + # self.grid3.addWidget(separator_line, 1, 0, 1, 2) + + self.mill_type_label = QtWidgets.QLabel('%s:' % _('Milling Type')) + self.mill_type_label.setToolTip( + _("Milling type:\n" + "- Drills -> will mill the drills associated with this tool\n" + "- Slots -> will mill the slots associated with this tool\n" + "- Both -> will mill both drills and mills or whatever is available") + ) + self.mill_type_radio = RadioSet( + [ + {'label': _('Drills'), 'value': 'drills'}, + {'label': _("Slots"), 'value': 'slots'}, + {'label': _("Both"), 'value': 'both'}, + ] + ) + + self.grid3.addWidget(self.mill_type_label, 2, 0) + self.grid3.addWidget(self.mill_type_radio, 2, 1) + + self.mill_dia_label = QtWidgets.QLabel('%s:' % _('Milling Diameter')) + self.mill_dia_label.setToolTip( + _("The diameter of the tool who will do the milling") + ) + + self.mill_dia_entry = FCDoubleSpinner() + self.mill_dia_entry.set_precision(self.decimals) + self.mill_dia_entry.set_range(0.0000, 9999.9999) + + self.grid3.addWidget(self.mill_dia_label, 3, 0) + self.grid3.addWidget(self.mill_dia_entry, 3, 1) # Cut Z cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z')) @@ -832,7 +896,7 @@ class ExcellonObjectUI(ObjectUI): _("Drill depth (negative)\n" "below the copper surface.") ) - grid1.addWidget(cutzlabel, 0, 0) + self.cutz_entry = FCDoubleSpinner() self.cutz_entry.set_precision(self.decimals) @@ -843,7 +907,34 @@ class ExcellonObjectUI(ObjectUI): self.cutz_entry.setSingleStep(0.1) - grid1.addWidget(self.cutz_entry, 0, 1) + self.grid3.addWidget(cutzlabel, 4, 0) + self.grid3.addWidget(self.cutz_entry, 4, 1) + + # Multi-Depth + self.mpass_cb = FCCheckBox('%s:' % _("Multi-Depth")) + self.mpass_cb.setToolTip( + _( + "Use multiple passes to limit\n" + "the cut depth in each pass. Will\n" + "cut multiple times until Cut Z is\n" + "reached." + ) + ) + + self.maxdepth_entry = FCDoubleSpinner() + self.maxdepth_entry.set_precision(self.decimals) + self.maxdepth_entry.set_range(0, 9999.9999) + self.maxdepth_entry.setSingleStep(0.1) + + self.maxdepth_entry.setToolTip( + _( + "Depth of each pass (positive)." + ) + ) + self.mis_mpass_geo = OptionalInputSection(self.mpass_cb, [self.maxdepth_entry]) + + self.grid3.addWidget(self.mpass_cb, 5, 0) + self.grid3.addWidget(self.maxdepth_entry, 5, 1) # Travel Z (z_move) travelzlabel = QtWidgets.QLabel('%s:' % _('Travel Z')) @@ -851,7 +942,7 @@ class ExcellonObjectUI(ObjectUI): _("Tool height when travelling\n" "across the XY plane.") ) - grid1.addWidget(travelzlabel, 1, 0) + self.travelz_entry = FCDoubleSpinner() self.travelz_entry.set_precision(self.decimals) @@ -862,7 +953,8 @@ class ExcellonObjectUI(ObjectUI): self.travelz_entry.setSingleStep(0.1) - grid1.addWidget(self.travelz_entry, 1, 1) + self.grid3.addWidget(travelzlabel, 6, 0) + self.grid3.addWidget(self.travelz_entry, 6, 1) # Tool change: self.toolchange_cb = FCCheckBox('%s:' % _("Tool change Z")) @@ -885,8 +977,8 @@ class ExcellonObjectUI(ObjectUI): self.toolchangez_entry.setSingleStep(0.1) self.ois_tcz_e = OptionalInputSection(self.toolchange_cb, [self.toolchangez_entry]) - grid1.addWidget(self.toolchange_cb, 2, 0) - grid1.addWidget(self.toolchangez_entry, 2, 1) + self.grid3.addWidget(self.toolchange_cb, 8, 0) + self.grid3.addWidget(self.toolchangez_entry, 8, 1) # Start move Z: self.estartz_label = QtWidgets.QLabel('%s:' % _("Start Z")) @@ -894,9 +986,10 @@ class ExcellonObjectUI(ObjectUI): _("Height of the tool just after start.\n" "Delete the value if you don't need this feature.") ) - grid1.addWidget(self.estartz_label, 4, 0) self.estartz_entry = FloatEntry() - grid1.addWidget(self.estartz_entry, 4, 1) + + self.grid3.addWidget(self.estartz_label, 9, 0) + self.grid3.addWidget(self.estartz_entry, 9, 1) # End move Z: self.eendz_label = QtWidgets.QLabel('%s:' % _("End move Z")) @@ -904,7 +997,6 @@ class ExcellonObjectUI(ObjectUI): _("Height of the tool after\n" "the last move at the end of the job.") ) - grid1.addWidget(self.eendz_label, 5, 0) self.eendz_entry = FCDoubleSpinner() self.eendz_entry.set_precision(self.decimals) @@ -915,7 +1007,22 @@ class ExcellonObjectUI(ObjectUI): self.eendz_entry.setSingleStep(0.1) - grid1.addWidget(self.eendz_entry, 5, 1) + self.grid3.addWidget(self.eendz_label, 11, 0) + self.grid3.addWidget(self.eendz_entry, 11, 1) + + # Feedrate X-Y + self.frxylabel = QtWidgets.QLabel('%s:' % _('Feedrate X-Y')) + self.frxylabel.setToolTip( + _("Cutting speed in the XY\n" + "plane in units per minute") + ) + self.xyfeedrate_entry = FCDoubleSpinner() + self.xyfeedrate_entry.set_precision(self.decimals) + self.xyfeedrate_entry.set_range(0, 9999.9999) + self.xyfeedrate_entry.setSingleStep(0.1) + + self.grid3.addWidget(self.frxylabel, 12, 0) + self.grid3.addWidget(self.xyfeedrate_entry, 12, 1) # Excellon Feedrate Z frlabel = QtWidgets.QLabel('%s:' % _('Feedrate Z')) @@ -925,13 +1032,13 @@ class ExcellonObjectUI(ObjectUI): "So called 'Plunge' feedrate.\n" "This is for linear move G01.") ) - grid1.addWidget(frlabel, 6, 0) self.feedrate_entry = FCDoubleSpinner() self.feedrate_entry.set_precision(self.decimals) self.feedrate_entry.set_range(0.0, 9999.9999) self.feedrate_entry.setSingleStep(0.1) - grid1.addWidget(self.feedrate_entry, 6, 1) + self.grid3.addWidget(frlabel, 14, 0) + self.grid3.addWidget(self.feedrate_entry, 14, 1) # Excellon Rapid Feedrate self.feedrate_rapid_label = QtWidgets.QLabel('%s:' % _('Feedrate Rapids')) @@ -942,28 +1049,57 @@ class ExcellonObjectUI(ObjectUI): "It is useful only for Marlin,\n" "ignore for any other cases.") ) - grid1.addWidget(self.feedrate_rapid_label, 7, 0) self.feedrate_rapid_entry = FCDoubleSpinner() self.feedrate_rapid_entry.set_precision(self.decimals) self.feedrate_rapid_entry.set_range(0.0, 9999.9999) self.feedrate_rapid_entry.setSingleStep(0.1) - grid1.addWidget(self.feedrate_rapid_entry, 7, 1) + self.grid3.addWidget(self.feedrate_rapid_label, 16, 0) + self.grid3.addWidget(self.feedrate_rapid_entry, 16, 1) + # default values is to hide self.feedrate_rapid_label.hide() self.feedrate_rapid_entry.hide() + # Cut over 1st point in path + self.extracut_cb = FCCheckBox('%s:' % _('Re-cut')) + self.extracut_cb.setToolTip( + _("In order to remove possible\n" + "copper leftovers where first cut\n" + "meet with last cut, we generate an\n" + "extended cut over the first cut section.") + ) + + self.e_cut_entry = FCDoubleSpinner() + self.e_cut_entry.set_range(0, 99999) + self.e_cut_entry.set_precision(self.decimals) + self.e_cut_entry.setSingleStep(0.1) + self.e_cut_entry.setWrapping(True) + self.e_cut_entry.setToolTip( + _("In order to remove possible\n" + "copper leftovers where first cut\n" + "meet with last cut, we generate an\n" + "extended cut over the first cut section.") + ) + + self.ois_recut = OptionalInputSection(self.extracut_cb, [self.e_cut_entry]) + + self.grid3.addWidget(self.extracut_cb, 17, 0) + self.grid3.addWidget(self.e_cut_entry, 17, 1) + # Spindlespeed spdlabel = QtWidgets.QLabel('%s:' % _('Spindle speed')) spdlabel.setToolTip( _("Speed of the spindle\n" "in RPM (optional)") ) - grid1.addWidget(spdlabel, 8, 0) + self.spindlespeed_entry = FCSpinner() self.spindlespeed_entry.set_range(0, 1000000) self.spindlespeed_entry.setSingleStep(100) - grid1.addWidget(self.spindlespeed_entry, 8, 1) + + self.grid3.addWidget(spdlabel, 19, 0) + self.grid3.addWidget(self.spindlespeed_entry, 19, 1) # Dwell self.dwell_cb = FCCheckBox('%s:' % _('Dwell')) @@ -979,35 +1115,27 @@ class ExcellonObjectUI(ObjectUI): self.dwelltime_entry.setToolTip( _("Number of time units for spindle to dwell.") ) - grid1.addWidget(self.dwell_cb, 9, 0) - grid1.addWidget(self.dwelltime_entry, 9, 1) + + self.grid3.addWidget(self.dwell_cb, 20, 0) + self.grid3.addWidget(self.dwelltime_entry, 20, 1) self.ois_dwell = OptionalInputSection(self.dwell_cb, [self.dwelltime_entry]) - # preprocessor selection - pp_excellon_label = QtWidgets.QLabel('%s:' % _("Preprocessor")) - pp_excellon_label.setToolTip( - _("The preprocessor JSON file that dictates\n" - "Gcode output.") - ) - self.pp_excellon_name_cb = FCComboBox() - self.pp_excellon_name_cb.setFocusPolicy(QtCore.Qt.StrongFocus) - grid1.addWidget(pp_excellon_label, 10, 0) - grid1.addWidget(self.pp_excellon_name_cb, 10, 1) - # Probe depth self.pdepth_label = QtWidgets.QLabel('%s:' % _("Probe Z depth")) self.pdepth_label.setToolTip( _("The maximum depth that the probe is allowed\n" "to probe. Negative value, in current units.") ) - grid1.addWidget(self.pdepth_label, 11, 0) + self.pdepth_entry = FCDoubleSpinner() self.pdepth_entry.set_precision(self.decimals) self.pdepth_entry.set_range(-9999.9999, 9999.9999) self.pdepth_entry.setSingleStep(0.1) - grid1.addWidget(self.pdepth_entry, 11, 1) + self.grid3.addWidget(self.pdepth_label, 22, 0) + self.grid3.addWidget(self.pdepth_entry, 22, 1) + self.pdepth_label.hide() self.pdepth_entry.setVisible(False) @@ -1022,21 +1150,20 @@ class ExcellonObjectUI(ObjectUI): self.feedrate_probe_entry.set_range(0.0, 9999.9999) self.feedrate_probe_entry.setSingleStep(0.1) - grid1.addWidget(self.feedrate_probe_label, 12, 0) - grid1.addWidget(self.feedrate_probe_entry, 12, 1) + self.grid3.addWidget(self.feedrate_probe_label, 24, 0) + self.grid3.addWidget(self.feedrate_probe_entry, 24, 1) self.feedrate_probe_label.hide() self.feedrate_probe_entry.setVisible(False) - separator_line = QtWidgets.QFrame() - separator_line.setFrameShape(QtWidgets.QFrame.HLine) - separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - grid1.addWidget(separator_line, 13, 0, 1, 2) + # ################################################################# + # ################# GRID LAYOUT 4 ############################### + # ################################################################# - grid2 = QtWidgets.QGridLayout() - self.tools_box.addLayout(grid2) - grid2.setColumnStretch(0, 0) - grid2.setColumnStretch(1, 1) + self.grid4 = QtWidgets.QGridLayout() + self.exc_tools_box.addLayout(self.grid4) + self.grid4.setColumnStretch(0, 0) + self.grid4.setColumnStretch(1, 1) # choose_tools_label = QtWidgets.QLabel( # _("Select from the Tools Table above the hole dias to be\n" @@ -1055,12 +1182,69 @@ class ExcellonObjectUI(ObjectUI): self.excellon_gcode_type_radio = RadioSet([{'label': 'Drills', 'value': 'drills'}, {'label': 'Slots', 'value': 'slots'}, {'label': 'Both', 'value': 'both'}]) - grid2.addWidget(gcode_type_label, 1, 0) - grid2.addWidget(self.excellon_gcode_type_radio, 1, 1) + self.grid4.addWidget(gcode_type_label, 1, 0) + self.grid4.addWidget(self.excellon_gcode_type_radio, 1, 1) # temporary action until I finish the feature self.excellon_gcode_type_radio.setVisible(False) gcode_type_label.hide() + # ################################################################# + # ################# GRID LAYOUT 5 ############################### + # ################################################################# + + self.grid5 = QtWidgets.QGridLayout() + self.grid5.setColumnStretch(0, 0) + self.grid5.setColumnStretch(1, 1) + self.exc_tools_box.addLayout(self.grid5) + + separator_line2 = QtWidgets.QFrame() + separator_line2.setFrameShape(QtWidgets.QFrame.HLine) + separator_line2.setFrameShadow(QtWidgets.QFrame.Sunken) + self.grid5.addWidget(separator_line2, 0, 0, 1, 2) + + self.apply_param_to_all = FCButton(_("Apply parameters to all tools")) + self.apply_param_to_all.setToolTip( + _("The parameters in the current form will be applied\n" + "on all the tools from the Tool Table.") + ) + self.grid5.addWidget(self.apply_param_to_all, 1, 0, 1, 2) + + separator_line2 = QtWidgets.QFrame() + separator_line2.setFrameShape(QtWidgets.QFrame.HLine) + separator_line2.setFrameShadow(QtWidgets.QFrame.Sunken) + self.grid5.addWidget(separator_line2, 2, 0, 1, 2) + + # General Parameters + self.gen_param_label = QtWidgets.QLabel('%s' % _("Common Parameters")) + self.gen_param_label.setToolTip( + _("Parameters that are common for all tools.") + ) + self.grid5.addWidget(self.gen_param_label, 3, 0, 1, 2) + + # preprocessor selection + pp_excellon_label = QtWidgets.QLabel('%s:' % _("Preprocessor")) + pp_excellon_label.setToolTip( + _("The preprocessor JSON file that dictates\n" + "Gcode output.") + ) + self.pp_excellon_name_cb = FCComboBox() + self.pp_excellon_name_cb.setFocusPolicy(QtCore.Qt.StrongFocus) + self.grid5.addWidget(pp_excellon_label, 4, 0) + self.grid5.addWidget(self.pp_excellon_name_cb, 4, 1) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + self.grid5.addWidget(separator_line, 5, 0, 1, 2) + + # ################################################################# + # ################# GRID LAYOUT 6 ############################### + # ################################################################# + self.grid6 = QtWidgets.QGridLayout() + self.grid6.setColumnStretch(0, 0) + self.grid6.setColumnStretch(1, 1) + self.tools_box.addLayout(self.grid6) + warning_lbl = QtWidgets.QLabel( _( "Add / Select at least one tool in the tool-table.\n" @@ -1068,12 +1252,13 @@ class ExcellonObjectUI(ObjectUI): "for custom selection of tools." )) - grid2.addWidget(QtWidgets.QLabel(''), 2, 0, 1, 3) - grid2.addWidget(warning_lbl, 3, 0, 1, 3) + self.grid6.addWidget(QtWidgets.QLabel(''), 1, 0, 1, 3) + self.grid6.addWidget(warning_lbl, 2, 0, 1, 3) - self.generate_cnc_button = QtWidgets.QPushButton(_('Create Drills GCode')) + self.generate_cnc_button = QtWidgets.QPushButton(_('Generate GCode')) self.generate_cnc_button.setToolTip( - _("Generate the CNC Job.") + _("Generate the CNC Job.\n" + "If milling then an additional Geometry object will be created") ) self.generate_cnc_button.setStyleSheet(""" QPushButton @@ -1081,7 +1266,12 @@ class ExcellonObjectUI(ObjectUI): font-weight: bold; } """) - grid2.addWidget(self.generate_cnc_button, 4, 0, 1, 3) + self.grid6.addWidget(self.generate_cnc_button, 3, 0, 1, 3) + + separator_line2 = QtWidgets.QFrame() + separator_line2.setFrameShape(QtWidgets.QFrame.HLine) + separator_line2.setFrameShadow(QtWidgets.QFrame.Sunken) + self.grid6.addWidget(separator_line2, 4, 0, 1, 2) # ### Milling Holes Drills #### self.mill_hole_label = QtWidgets.QLabel('%s' % _('Mill Holes')) @@ -1090,7 +1280,7 @@ class ExcellonObjectUI(ObjectUI): "Select from the Tools Table above the hole dias to be\n" "milled. Use the # column to make the selection.") ) - grid2.addWidget(self.mill_hole_label, 5, 0, 1, 3) + self.grid6.addWidget(self.mill_hole_label, 5, 0, 1, 3) self.tdlabel = QtWidgets.QLabel('%s:' % _('Drill Tool dia')) self.tdlabel.setToolTip( @@ -1113,9 +1303,9 @@ class ExcellonObjectUI(ObjectUI): } """) - grid2.addWidget(self.tdlabel, 6, 0) - grid2.addWidget(self.tooldia_entry, 6, 1) - grid2.addWidget(self.generate_milling_button, 6, 2) + self.grid6.addWidget(self.tdlabel, 6, 0) + self.grid6.addWidget(self.tooldia_entry, 6, 1) + self.grid6.addWidget(self.generate_milling_button, 6, 2) self.stdlabel = QtWidgets.QLabel('%s:' % _('Slot Tool dia')) self.stdlabel.setToolTip( @@ -1140,9 +1330,9 @@ class ExcellonObjectUI(ObjectUI): } """) - grid2.addWidget(self.stdlabel, 7, 0) - grid2.addWidget(self.slot_tooldia_entry, 7, 1) - grid2.addWidget(self.generate_milling_slots_button, 7, 2) + self.grid6.addWidget(self.stdlabel, 7, 0) + self.grid6.addWidget(self.slot_tooldia_entry, 7, 1) + self.grid6.addWidget(self.generate_milling_slots_button, 7, 2) def hide_drills(self, state=True): if state is True: @@ -1332,7 +1522,7 @@ class GeometryObjectUI(ObjectUI): self.grid1.addWidget(self.addtool_entry, 1, 1) self.grid1.addWidget(self.addtool_btn, 1, 2) - self.addtool_from_db_btn = QtWidgets.QPushButton(_('Add Tool from DataBase')) + self.addtool_from_db_btn = QtWidgets.QPushButton(_('Add from DB')) self.addtool_from_db_btn.setToolTip( _("Add a new tool to the Tool Table\n" "from the Tool DataBase.") @@ -1388,7 +1578,13 @@ class GeometryObjectUI(ObjectUI): self.geo_param_box.setContentsMargins(0, 0, 0, 0) self.geo_param_frame.setLayout(self.geo_param_box) + # ################################################################# + # ################# GRID LAYOUT 3 ############################### + # ################################################################# + self.grid3 = QtWidgets.QGridLayout() + self.grid3.setColumnStretch(0, 0) + self.grid3.setColumnStretch(1, 1) self.geo_param_box.addLayout(self.grid3) # Tip Dia @@ -1655,18 +1851,6 @@ class GeometryObjectUI(ObjectUI): self.grid3.addWidget(self.dwell_cb, 15, 0) self.grid3.addWidget(self.dwelltime_entry, 15, 1) - # preprocessor selection - pp_label = QtWidgets.QLabel('%s:' % _("Preprocessor")) - pp_label.setToolTip( - _("The Preprocessor file that dictates\n" - "the Machine Code (like GCode, RML, HPGL) output.") - ) - self.pp_geometry_name_cb = FCComboBox() - self.pp_geometry_name_cb.setFocusPolicy(QtCore.Qt.StrongFocus) - - self.grid3.addWidget(pp_label, 16, 0) - self.grid3.addWidget(self.pp_geometry_name_cb, 16, 1) - # Probe depth self.pdepth_label = QtWidgets.QLabel('%s:' % _("Probe Z depth")) self.pdepth_label.setToolTip( @@ -1700,27 +1884,59 @@ class GeometryObjectUI(ObjectUI): self.feedrate_probe_label.hide() self.feedrate_probe_entry.setVisible(False) + # ################################################################# + # ################# GRID LAYOUT 4 ############################### + # ################################################################# + + self.grid4 = QtWidgets.QGridLayout() + self.grid4.setColumnStretch(0, 0) + self.grid4.setColumnStretch(1, 1) + self.geo_param_box.addLayout(self.grid4) + separator_line2 = QtWidgets.QFrame() separator_line2.setFrameShape(QtWidgets.QFrame.HLine) separator_line2.setFrameShadow(QtWidgets.QFrame.Sunken) - self.grid3.addWidget(separator_line2, 19, 0, 1, 2) + self.grid4.addWidget(separator_line2, 0, 0, 1, 2) self.apply_param_to_all = FCButton(_("Apply parameters to all tools")) self.apply_param_to_all.setToolTip( _("The parameters in the current form will be applied\n" "on all the tools from the Tool Table.") ) - self.grid3.addWidget(self.apply_param_to_all, 20, 0, 1, 2) + self.grid4.addWidget(self.apply_param_to_all, 1, 0, 1, 2) - self.grid3.addWidget(QtWidgets.QLabel(''), 21, 0, 1, 2) + separator_line2 = QtWidgets.QFrame() + separator_line2.setFrameShape(QtWidgets.QFrame.HLine) + separator_line2.setFrameShadow(QtWidgets.QFrame.Sunken) + self.grid4.addWidget(separator_line2, 2, 0, 1, 2) + # General Parameters + self.gen_param_label = QtWidgets.QLabel('%s' % _("Common Parameters")) + self.gen_param_label.setToolTip( + _("Parameters that are common for all tools.") + ) + self.grid4.addWidget(self.gen_param_label, 3, 0, 1, 2) + + # preprocessor selection + pp_label = QtWidgets.QLabel('%s:' % _("Preprocessor")) + pp_label.setToolTip( + _("The Preprocessor file that dictates\n" + "the Machine Code (like GCode, RML, HPGL) output.") + ) + self.pp_geometry_name_cb = FCComboBox() + self.pp_geometry_name_cb.setFocusPolicy(QtCore.Qt.StrongFocus) + + self.grid4.addWidget(pp_label, 4, 0) + self.grid4.addWidget(self.pp_geometry_name_cb, 4, 1) + + self.grid4.addWidget(QtWidgets.QLabel(''), 5, 0, 1, 2) warning_lbl = QtWidgets.QLabel( _( "Add / Select at least one tool in the tool-table.\n" "Click the header to select all, or Ctrl + LMB\n" "for custom selection of tools." )) - self.grid3.addWidget(warning_lbl, 22, 0, 1, 2) + self.grid4.addWidget(warning_lbl, 6, 0, 1, 2) # Button self.generate_cnc_button = QtWidgets.QPushButton(_('Generate CNCJob object')) @@ -1733,9 +1949,9 @@ class GeometryObjectUI(ObjectUI): font-weight: bold; } """) - self.grid3.addWidget(self.generate_cnc_button, 23, 0, 1, 2) + self.grid4.addWidget(self.generate_cnc_button, 7, 0, 1, 2) - self.grid3.addWidget(QtWidgets.QLabel(''), 24, 0, 1, 2) + self.grid4.addWidget(QtWidgets.QLabel(''), 8, 0, 1, 2) # ############## # Paint area ## @@ -1744,7 +1960,7 @@ class GeometryObjectUI(ObjectUI): self.tools_label.setToolTip( _("Launch Paint Tool in Tools Tab.") ) - self.grid3.addWidget(self.tools_label, 25, 0, 1, 2) + self.grid4.addWidget(self.tools_label, 10, 0, 1, 2) # Paint Button self.paint_tool_button = QtWidgets.QPushButton(_('Paint Tool')) @@ -1762,7 +1978,7 @@ class GeometryObjectUI(ObjectUI): font-weight: bold; } """) - self.grid3.addWidget(self.paint_tool_button, 26, 0, 1, 2) + self.grid4.addWidget(self.paint_tool_button, 12, 0, 1, 2) # NCC Tool self.generate_ncc_button = QtWidgets.QPushButton(_('NCC Tool')) @@ -1776,7 +1992,7 @@ class GeometryObjectUI(ObjectUI): font-weight: bold; } """) - self.grid3.addWidget(self.generate_ncc_button, 27, 0, 1, 2) + self.grid4.addWidget(self.generate_ncc_button, 13, 0, 1, 2) class CNCObjectUI(ObjectUI): From eae5b3d8e3cea60a6fb6b896775e110a983a0bd3 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 17 Jan 2020 03:42:50 +0200 Subject: [PATCH 031/209] - changes to Geometry UI --- README.md | 1 + flatcamGUI/ObjectUI.py | 21 +++++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 899a10e3..204ff374 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 17.01.2020 - more changes to Excellon UI +- changes to Geometry UI 16.01.2020 diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index 7143de33..807b9cf3 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -1503,6 +1503,14 @@ class GeometryObjectUI(ObjectUI): self.grid1.addWidget(self.tool_offset_lbl, 0, 0) self.grid1.addWidget(self.tool_offset_entry, 0, 1, 1, 2) + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + self.grid1.addWidget(separator_line, 1, 0, 1, 3) + + self.tool_sel_label = QtWidgets.QLabel('%s' % _("New Tool")) + self.grid1.addWidget(self.tool_sel_label, 2, 0, 1, 3) + self.addtool_entry_lbl = QtWidgets.QLabel('%s:' % _('Tool Dia')) self.addtool_entry_lbl.setToolTip( _("Diameter for the new tool") @@ -1518,16 +1526,21 @@ class GeometryObjectUI(ObjectUI): "with the specified diameter.") ) - self.grid1.addWidget(self.addtool_entry_lbl, 1, 0) - self.grid1.addWidget(self.addtool_entry, 1, 1) - self.grid1.addWidget(self.addtool_btn, 1, 2) + self.grid1.addWidget(self.addtool_entry_lbl, 3, 0) + self.grid1.addWidget(self.addtool_entry, 3, 1) + self.grid1.addWidget(self.addtool_btn, 3, 2) self.addtool_from_db_btn = QtWidgets.QPushButton(_('Add from DB')) self.addtool_from_db_btn.setToolTip( _("Add a new tool to the Tool Table\n" "from the Tool DataBase.") ) - self.grid1.addWidget(self.addtool_from_db_btn, 2, 0, 1, 3) + self.grid1.addWidget(self.addtool_from_db_btn, 4, 0, 1, 3) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + self.grid1.addWidget(separator_line, 5, 0, 1, 3) grid2 = QtWidgets.QGridLayout() self.geo_tools_box.addLayout(grid2) From 316b04a56a5976d7f3f9b8b480f5e271456a514b Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 17 Jan 2020 03:44:34 +0200 Subject: [PATCH 032/209] - wip --- flatcamGUI/ObjectUI.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index 807b9cf3..3d97ccb6 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -1255,7 +1255,7 @@ class ExcellonObjectUI(ObjectUI): self.grid6.addWidget(QtWidgets.QLabel(''), 1, 0, 1, 3) self.grid6.addWidget(warning_lbl, 2, 0, 1, 3) - self.generate_cnc_button = QtWidgets.QPushButton(_('Generate GCode')) + self.generate_cnc_button = QtWidgets.QPushButton(_('Generate CNCJob object')) self.generate_cnc_button.setToolTip( _("Generate the CNC Job.\n" "If milling then an additional Geometry object will be created") From 6c43ffca1edf6233643ba34943f6afa3178bef56 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 17 Jan 2020 17:02:49 +0200 Subject: [PATCH 033/209] - more work in NCC Tool upgrade; each tool now work with it's own set of parameters --- FlatCAMApp.py | 8 +- README.md | 1 + flatcamTools/ToolNonCopperClear.py | 780 +++++++++++++---------------- 3 files changed, 340 insertions(+), 449 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 258c0852..60457078 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -4306,12 +4306,12 @@ class App(QtCore.QObject): try: if kind == 'excellon': - obj.fill_color = self.app.defaults["excellon_plot_fill"] - obj.outline_color = self.app.defaults["excellon_plot_line"] + obj.fill_color = self.defaults["excellon_plot_fill"] + obj.outline_color = self.defaults["excellon_plot_line"] if kind == 'gerber': - obj.fill_color = self.app.defaults["gerber_plot_fill"] - obj.outline_color = self.app.defaults["gerber_plot_line"] + obj.fill_color = self.defaults["gerber_plot_fill"] + obj.outline_color = self.defaults["gerber_plot_line"] except Exception as e: log.warning("App.new_object() -> setting colors error. %s" % str(e)) diff --git a/README.md b/README.md index 204ff374..e7b553e6 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ CAD program, and create G-Code for Isolation routing. - more changes to Excellon UI - changes to Geometry UI +- more work in NCC Tool upgrade; each tool now work with it's own set of parameters 16.01.2020 diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNonCopperClear.py index 1b0896dc..2b145606 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/flatcamTools/ToolNonCopperClear.py @@ -1455,12 +1455,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.app.report_usage("on_paint_button_click") - self.overlap = float(self.ncc_overlap_entry.get_value()) / 100.0 self.grb_circle_steps = int(self.app.defaults["gerber_circle_steps"]) - self.connect = self.ncc_connect_cb.get_value() - self.contour = self.ncc_contour_cb.get_value() - self.has_offset = self.ncc_choice_offset_cb.isChecked() - self.rest = self.ncc_rest_cb.get_value() self.obj_name = self.object_combo.currentText() # Get source object. @@ -1514,12 +1509,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.clear_copper(ncc_obj=self.ncc_obj, ncctooldia=self.ncc_dia_list, isotooldia=self.iso_dia_list, - has_offset=self.has_offset, - outname=self.o_name, - overlap=self.overlap, - connect=self.connect, - contour=self.contour, - rest=self.rest) + outname=self.o_name) elif self.select_method == 'area': self.app.inform.emit('[WARNING_NOTCL] %s' % _("Click the start point of the area.")) @@ -1547,12 +1537,7 @@ class NonCopperClear(FlatCAMTool, Gerber): sel_obj=self.bound_obj, ncctooldia=self.ncc_dia_list, isotooldia=self.iso_dia_list, - has_offset=self.has_offset, - outname=self.o_name, - overlap=self.overlap, - connect=self.connect, - contour=self.contour, - rest=self.rest) + outname=self.o_name) # To be called after clicking on the plot. def on_mouse_release(self, event): @@ -1629,12 +1614,7 @@ class NonCopperClear(FlatCAMTool, Gerber): sel_obj=self.bound_obj, ncctooldia=self.ncc_dia_list, isotooldia=self.iso_dia_list, - has_offset=self.has_offset, - outname=self.o_name, - overlap=self.overlap, - connect=self.connect, - contour=self.contour, - rest=self.rest) + outname=self.o_name) # called on mouse move def on_mouse_move(self, event): @@ -1682,73 +1662,18 @@ class NonCopperClear(FlatCAMTool, Gerber): self.app.draw_moving_selection_shape(old_coords=(self.cursor_pos[0], self.cursor_pos[1]), coords=(curr_pos[0], curr_pos[1])) - def clear_copper(self, ncc_obj, - sel_obj=None, - ncctooldia=None, - isotooldia=None, - outname=None, - order=None, - tools_storage=None, - plot=True, - run_threaded=True): + def get_tool_bounding_box(self, ncc_obj, sel_obj, ncc_select, ncc_margin): """ - Clear the excess copper from the entire object. + Prepare non-copper polygons. + Create the bounding box area from which the copper features will be subtracted - :param ncc_obj: ncc cleared object - :param ncctooldia: a tuple or single element made out of diameters of the tools to be used to ncc clear - :param isotooldia: a tuple or single element made out of diameters of the tools to be used for isolation - :param outname: name of the resulting object - :param tools_storage: whether to use the current tools_storage self.ncc_tools or a different one. - Usage of the different one is related to when this function is called from a TcL command. - :param plot: if True after the job is finished the result will be plotted, else it will not. - :param run_threaded: If True the method will be run in a threaded way suitable for GUI usage; if False it will - run non-threaded for TclShell usage - :return: + :param ncc_obj: the Gerber object to be non-copper cleared + :param sel_obj: the FlatCAM object to be used as a area delimitator + :param ncc_select: the kind of area to be copper cleared + :param ncc_margin: the margin around the area to be copper cleared + :return: an geometric element (Polygon or MultiPolygon) that specify the area to be copper cleared """ - if run_threaded: - proc = self.app.proc_container.new(_("Non-Copper clearing ...")) - else: - self.app.proc_container.view.set_busy(_("Non-Copper clearing ...")) - QtWidgets.QApplication.processEvents() - # ##################################################################### - # ####### Read the parameters ######################################### - # ##################################################################### - - units = self.app.defaults['units'] - order = order if order else self.ncc_order_radio.get_value() - - # determine if to use the progressive plotting - if self.app.defaults["tools_ncc_plotting"] == 'progressive': - prog_plot = True - else: - prog_plot = False - - if tools_storage is not None: - tools_storage = tools_storage - else: - tools_storage = self.ncc_tools - - # ###################################################################################################### - # # Read the tooldia parameter and create a sorted list out them - they may be more than one diameter ## - # ###################################################################################################### - sorted_tools = [] - if ncctooldia is not None: - try: - sorted_tools = [float(eval(dia)) for dia in ncctooldia.split(",") if dia != ''] - except AttributeError: - if not isinstance(ncctooldia, list): - sorted_tools = [float(ncctooldia)] - else: - sorted_tools = ncctooldia - else: - for row in range(self.tools_table.rowCount()): - if self.tools_table.cellWidget(row, 1).currentText() == 'clear_op': - sorted_tools.append(float(self.tools_table.item(row, 1).text())) - - # ############################################################################################################## - # Prepare non-copper polygons. Create the bounding box area from which the copper features will be subtracted ## - # ############################################################################################################## log.debug("NCC Tool. Preparing non-copper polygons.") self.app.inform.emit(_("NCC Tool. Preparing non-copper polygons.")) @@ -1824,6 +1749,245 @@ class NonCopperClear(FlatCAMTool, Gerber): return 'fail' log.debug("NCC Tool. Finished non-copper polygons.") + return bounding_box + + def get_tool_empty_area(self, name, ncc_obj, geo_obj, isotooldia, has_offset, ncc_offset, ncc_margin, + bounding_box, tools_storage): + """ + Calculate the empty area by subtracting the solid_geometry from the object bounding box geometry. + + :param name: + :param ncc_obj: + :param geo_obj: + :param isotooldia: + :param has_offset: + :param ncc_offset: + :param ncc_margin: + :param bounding_box: + :param tools_storage: + :return: + """ + + log.debug("NCC Tool. Calculate 'empty' area.") + self.app.inform.emit(_("NCC Tool. Calculate 'empty' area.")) + + # a flag to signal that the isolation is broken by the bounding box in 'area' and 'box' cases + # will store the number of tools for which the isolation is broken + warning_flag = 0 + + if ncc_obj.kind == 'gerber' and not isotooldia: + # unfortunately for this function to work time efficient, + # if the Gerber was loaded without buffering then it require the buffering now. + if self.app.defaults['gerber_buffering'] == 'no': + sol_geo = ncc_obj.solid_geometry.buffer(0) + else: + sol_geo = ncc_obj.solid_geometry + + if has_offset is True: + self.app.inform.emit('[WARNING_NOTCL] %s ...' % _("Buffering")) + if isinstance(sol_geo, list): + sol_geo = MultiPolygon(sol_geo) + sol_geo = sol_geo.buffer(distance=ncc_offset) + self.app.inform.emit('[success] %s ...' % _("Buffering finished")) + + empty = self.get_ncc_empty_area(target=sol_geo, boundary=bounding_box) + if empty == 'fail': + return 'fail' + + if empty.is_empty: + self.app.inform.emit('[ERROR_NOTCL] %s' % + _("Could not get the extent of the area to be non copper cleared.")) + return 'fail' + elif ncc_obj.kind == 'gerber' and isotooldia: + isolated_geo = [] + + # unfortunately for this function to work time efficient, + # if the Gerber was loaded without buffering then it require the buffering now. + if self.app.defaults['gerber_buffering'] == 'no': + self.solid_geometry = ncc_obj.solid_geometry.buffer(0) + else: + self.solid_geometry = ncc_obj.solid_geometry + + # if milling type is climb then the move is counter-clockwise around features + milling_type = self.milling_type_radio.get_value() + + for tool_iso in isotooldia: + new_geometry = [] + + if milling_type == 'cl': + isolated_geo = self.generate_envelope(tool_iso / 2, 1) + else: + isolated_geo = self.generate_envelope(tool_iso / 2, 0) + + if isolated_geo == 'fail': + self.app.inform.emit('[ERROR_NOTCL] %s' % _("Isolation geometry could not be generated.")) + else: + if ncc_margin < tool_iso: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Isolation geometry is broken. Margin is less " + "than isolation tool diameter.")) + try: + for geo_elem in isolated_geo: + # provide the app with a way to process the GUI events when in a blocking loop + QtWidgets.QApplication.processEvents() + + if self.app.abort_flag: + # graceful abort requested by the user + raise FlatCAMApp.GracefulException + + if isinstance(geo_elem, Polygon): + for ring in self.poly2rings(geo_elem): + new_geo = ring.intersection(bounding_box) + if new_geo and not new_geo.is_empty: + new_geometry.append(new_geo) + elif isinstance(geo_elem, MultiPolygon): + for poly in geo_elem: + for ring in self.poly2rings(poly): + new_geo = ring.intersection(bounding_box) + if new_geo and not new_geo.is_empty: + new_geometry.append(new_geo) + elif isinstance(geo_elem, LineString): + new_geo = geo_elem.intersection(bounding_box) + if new_geo: + if not new_geo.is_empty: + new_geometry.append(new_geo) + elif isinstance(geo_elem, MultiLineString): + for line_elem in geo_elem: + new_geo = line_elem.intersection(bounding_box) + if new_geo and not new_geo.is_empty: + new_geometry.append(new_geo) + except TypeError: + if isinstance(isolated_geo, Polygon): + for ring in self.poly2rings(isolated_geo): + new_geo = ring.intersection(bounding_box) + if new_geo: + if not new_geo.is_empty: + new_geometry.append(new_geo) + elif isinstance(isolated_geo, LineString): + new_geo = isolated_geo.intersection(bounding_box) + if new_geo and not new_geo.is_empty: + new_geometry.append(new_geo) + elif isinstance(isolated_geo, MultiLineString): + for line_elem in isolated_geo: + new_geo = line_elem.intersection(bounding_box) + if new_geo and not new_geo.is_empty: + new_geometry.append(new_geo) + + # a MultiLineString geometry element will show that the isolation is broken for this tool + for geo_e in new_geometry: + if type(geo_e) == MultiLineString: + warning_flag += 1 + break + + current_uid = 0 + for k, v in tools_storage.items(): + if float('%.*f' % (self.decimals, v['tooldia'])) == float('%.*f' % (self.decimals, + tool_iso)): + current_uid = int(k) + # add the solid_geometry to the current too in self.paint_tools dictionary + # and then reset the temporary list that stored that solid_geometry + v['solid_geometry'] = deepcopy(new_geometry) + v['data']['name'] = name + break + geo_obj.tools[current_uid] = dict(tools_storage[current_uid]) + + sol_geo = cascaded_union(isolated_geo) + if has_offset is True: + self.app.inform.emit('[WARNING_NOTCL] %s ...' % _("Buffering")) + sol_geo = sol_geo.buffer(distance=ncc_offset) + self.app.inform.emit('[success] %s ...' % _("Buffering finished")) + empty = self.get_ncc_empty_area(target=sol_geo, boundary=bounding_box) + if empty == 'fail': + return 'fail' + + if empty.is_empty: + self.app.inform.emit('[ERROR_NOTCL] %s' % + _("Isolation geometry is broken. Margin is less than isolation tool diameter.")) + return 'fail' + elif ncc_obj.kind == 'geometry': + sol_geo = cascaded_union(ncc_obj.solid_geometry) + if has_offset is True: + self.app.inform.emit('[WARNING_NOTCL] %s ...' % _("Buffering")) + sol_geo = sol_geo.buffer(distance=ncc_offset) + self.app.inform.emit('[success] %s ...' % _("Buffering finished")) + empty = self.get_ncc_empty_area(target=sol_geo, boundary=bounding_box) + if empty == 'fail': + return 'fail' + + if empty.is_empty: + self.app.inform.emit('[ERROR_NOTCL] %s' % + _("Could not get the extent of the area to be non copper cleared.")) + return 'fail' + else: + self.app.inform.emit('[ERROR_NOTCL] %s' % _('The selected object is not suitable for copper clearing.')) + return 'fail' + + if type(empty) is Polygon: + empty = MultiPolygon([empty]) + + log.debug("NCC Tool. Finished calculation of 'empty' area.") + self.app.inform.emit(_("NCC Tool. Finished calculation of 'empty' area.")) + + return empty, warning_flag + + def clear_copper(self, ncc_obj, + sel_obj=None, + ncctooldia=None, + isotooldia=None, + outname=None, + order=None, + tools_storage=None, + run_threaded=True): + """ + Clear the excess copper from the entire object. + + :param ncc_obj: ncc cleared object + :param ncctooldia: a tuple or single element made out of diameters of the tools to be used to ncc clear + :param isotooldia: a tuple or single element made out of diameters of the tools to be used for isolation + :param outname: name of the resulting object + + :param tools_storage: whether to use the current tools_storage self.ncc_tools or a different one. + Usage of the different one is related to when this function is called from a TcL command. + + :param run_threaded: If True the method will be run in a threaded way suitable for GUI usage; if False it will + run non-threaded for TclShell usage + :return: + """ + if run_threaded: + proc = self.app.proc_container.new(_("Non-Copper clearing ...")) + else: + self.app.proc_container.view.set_busy(_("Non-Copper clearing ...")) + QtWidgets.QApplication.processEvents() + + # ##################################################################### + # ####### Read the parameters ######################################### + # ##################################################################### + + units = self.app.defaults['units'] + order = order if order else self.ncc_order_radio.get_value() + ncc_select = self.reference_radio.get_value() + rest_machining_choice = self.ncc_rest_cb.get_value() + + # determine if to use the progressive plotting + prog_plot = True if self.app.defaults["tools_ncc_plotting"] == 'progressive' else False + tools_storage = tools_storage if tools_storage is not None else self.ncc_tools + + # ###################################################################################################### + # # Read the tooldia parameter and create a sorted list out them - they may be more than one diameter ## + # ###################################################################################################### + sorted_tools = [] + if ncctooldia is not None: + try: + sorted_tools = [float(eval(dia)) for dia in ncctooldia.split(",") if dia != ''] + except AttributeError: + if not isinstance(ncctooldia, list): + sorted_tools = [float(ncctooldia)] + else: + sorted_tools = ncctooldia + else: + for row in range(self.tools_table.rowCount()): + if self.tools_table.cellWidget(row, 1).currentText() == 'clear_op': + sorted_tools.append(float(self.tools_table.item(row, 1).text())) + # ######################################################################################################## # set the name for the future Geometry object # I do it here because it is also stored inside the gen_clear_area() and gen_clear_area_rest() methods @@ -1870,163 +2034,6 @@ class NonCopperClear(FlatCAMTool, Gerber): except TypeError: tool = eval(self.app.defaults["tools_ncctools"]) - # ################################################################################################### - # Calculate the empty area by subtracting the solid_geometry from the object bounding box geometry ## - # ################################################################################################### - log.debug("NCC Tool. Calculate 'empty' area.") - self.app.inform.emit(_("NCC Tool. Calculate 'empty' area.")) - - if ncc_obj.kind == 'gerber' and not isotooldia: - # unfortunately for this function to work time efficient, - # if the Gerber was loaded without buffering then it require the buffering now. - if self.app.defaults['gerber_buffering'] == 'no': - sol_geo = ncc_obj.solid_geometry.buffer(0) - else: - sol_geo = ncc_obj.solid_geometry - - if has_offset is True: - app_obj.inform.emit('[WARNING_NOTCL] %s ...' % _("Buffering")) - sol_geo = sol_geo.buffer(distance=ncc_offset) - app_obj.inform.emit('[success] %s ...' % _("Buffering finished")) - - empty = self.get_ncc_empty_area(target=sol_geo, boundary=bounding_box) - if empty == 'fail': - return 'fail' - - if empty.is_empty: - app_obj.inform.emit('[ERROR_NOTCL] %s' % - _("Could not get the extent of the area to be non copper cleared.")) - return 'fail' - elif ncc_obj.kind == 'gerber' and isotooldia: - isolated_geo = [] - - # unfortunately for this function to work time efficient, - # if the Gerber was loaded without buffering then it require the buffering now. - if self.app.defaults['gerber_buffering'] == 'no': - self.solid_geometry = ncc_obj.solid_geometry.buffer(0) - else: - self.solid_geometry = ncc_obj.solid_geometry - - # if milling type is climb then the move is counter-clockwise around features - milling_type = self.milling_type_radio.get_value() - - for tool_iso in isotooldia: - new_geometry = [] - - if milling_type == 'cl': - isolated_geo = self.generate_envelope(tool_iso / 2, 1) - else: - isolated_geo = self.generate_envelope(tool_iso / 2, 0) - - if isolated_geo == 'fail': - app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Isolation geometry could not be generated.")) - else: - if ncc_margin < tool_iso: - app_obj.inform.emit('[WARNING_NOTCL] %s' % _("Isolation geometry is broken. Margin is less " - "than isolation tool diameter.")) - try: - for geo_elem in isolated_geo: - # provide the app with a way to process the GUI events when in a blocking loop - QtWidgets.QApplication.processEvents() - - if self.app.abort_flag: - # graceful abort requested by the user - raise FlatCAMApp.GracefulException - - if isinstance(geo_elem, Polygon): - for ring in self.poly2rings(geo_elem): - new_geo = ring.intersection(bounding_box) - if new_geo and not new_geo.is_empty: - new_geometry.append(new_geo) - elif isinstance(geo_elem, MultiPolygon): - for poly in geo_elem: - for ring in self.poly2rings(poly): - new_geo = ring.intersection(bounding_box) - if new_geo and not new_geo.is_empty: - new_geometry.append(new_geo) - elif isinstance(geo_elem, LineString): - new_geo = geo_elem.intersection(bounding_box) - if new_geo: - if not new_geo.is_empty: - new_geometry.append(new_geo) - elif isinstance(geo_elem, MultiLineString): - for line_elem in geo_elem: - new_geo = line_elem.intersection(bounding_box) - if new_geo and not new_geo.is_empty: - new_geometry.append(new_geo) - except TypeError: - if isinstance(isolated_geo, Polygon): - for ring in self.poly2rings(isolated_geo): - new_geo = ring.intersection(bounding_box) - if new_geo: - if not new_geo.is_empty: - new_geometry.append(new_geo) - elif isinstance(isolated_geo, LineString): - new_geo = isolated_geo.intersection(bounding_box) - if new_geo and not new_geo.is_empty: - new_geometry.append(new_geo) - elif isinstance(isolated_geo, MultiLineString): - for line_elem in isolated_geo: - new_geo = line_elem.intersection(bounding_box) - if new_geo and not new_geo.is_empty: - new_geometry.append(new_geo) - - # a MultiLineString geometry element will show that the isolation is broken for this tool - for geo_e in new_geometry: - if type(geo_e) == MultiLineString: - warning_flag += 1 - break - - for k, v in tools_storage.items(): - if float('%.*f' % (self.decimals, v['tooldia'])) == float('%.*f' % (self.decimals, - tool_iso)): - current_uid = int(k) - # add the solid_geometry to the current too in self.paint_tools dictionary - # and then reset the temporary list that stored that solid_geometry - v['solid_geometry'] = deepcopy(new_geometry) - v['data']['name'] = name - break - geo_obj.tools[current_uid] = dict(tools_storage[current_uid]) - - sol_geo = cascaded_union(isolated_geo) - if has_offset is True: - app_obj.inform.emit('[WARNING_NOTCL] %s ...' % _("Buffering")) - sol_geo = sol_geo.buffer(distance=ncc_offset) - app_obj.inform.emit('[success] %s ...' % _("Buffering finished")) - empty = self.get_ncc_empty_area(target=sol_geo, boundary=bounding_box) - if empty == 'fail': - return 'fail' - - if empty.is_empty: - app_obj.inform.emit('[ERROR_NOTCL] %s' % - _("Isolation geometry is broken. Margin is less than isolation tool diameter.")) - return 'fail' - - elif ncc_obj.kind == 'geometry': - sol_geo = cascaded_union(ncc_obj.solid_geometry) - if has_offset is True: - app_obj.inform.emit('[WARNING_NOTCL] %s ...' % _("Buffering")) - sol_geo = sol_geo.buffer(distance=ncc_offset) - app_obj.inform.emit('[success] %s ...' % _("Buffering finished")) - empty = self.get_ncc_empty_area(target=sol_geo, boundary=bounding_box) - if empty == 'fail': - return 'fail' - - if empty.is_empty: - app_obj.inform.emit('[ERROR_NOTCL] %s' % - _("Could not get the extent of the area to be non copper cleared.")) - return 'fail' - - else: - app_obj.inform.emit('[ERROR_NOTCL] %s' % _('The selected object is not suitable for copper clearing.')) - return 'fail' - - if type(empty) is Polygon: - empty = MultiPolygon([empty]) - - log.debug("NCC Tool. Finished calculation of 'empty' area.") - self.app.inform.emit(_("NCC Tool. Finished calculation of 'empty' area.")) - # COPPER CLEARING # cp = None for tool in sorted_tools: @@ -2043,12 +2050,36 @@ class NonCopperClear(FlatCAMTool, Gerber): ) app_obj.proc_container.update_view_text(' %d%%' % 0) + tooluid = 0 + for k, v in self.ncc_tools.items(): + if float('%.*f' % (self.decimals, v['tooldia'])) == float('%.*f' % (self.decimals, tool)): + tooluid = int(k) + break + + ncc_overlap = float(self.ncc_tools[tooluid]["data"]["nccoverlap"]) / 100.0 + ncc_margin = float(self.ncc_tools[tooluid]["data"]["nccmargin"]) + ncc_method = self.ncc_tools[tooluid]["data"]["nccmethod"] + ncc_connect = self.ncc_tools[tooluid]["data"]["nccconnect"] + ncc_contour = self.ncc_tools[tooluid]["data"]["ncccontour"] + has_offset = self.ncc_tools[tooluid]["data"]["nccoffset"] + ncc_offset = float(self.ncc_tools[tooluid]["data"]["nccoffset_value"]) + cleared_geo[:] = [] # Get remaining tools offset offset -= (tool - 1e-12) + # Bounding box for current tool + bbox = self.get_tool_bounding_box(ncc_obj=ncc_obj, sel_obj=sel_obj, ncc_select=ncc_select, + ncc_margin=ncc_margin) + # Area to clear + empty, warning_flag = self.get_tool_empty_area(name=name, ncc_obj=ncc_obj, geo_obj=geo_obj, + isotooldia=isotooldia, + has_offset=has_offset, ncc_offset=ncc_offset, + ncc_margin=ncc_margin, tools_storage=tools_storage, + bounding_box=bbox) + area = empty.buffer(-offset) try: area = area.difference(cleared) @@ -2087,20 +2118,20 @@ class NonCopperClear(FlatCAMTool, Gerber): if ncc_method == 'standard': cp = self.clear_polygon(pol, tool, self.grb_circle_steps, - overlap=overlap, contour=contour, - connect=connect, + overlap=ncc_overlap, contour=ncc_contour, + connect=ncc_connect, prog_plot=prog_plot) elif ncc_method == 'seed': cp = self.clear_polygon2(pol, tool, self.grb_circle_steps, - overlap=overlap, contour=contour, - connect=connect, + overlap=ncc_overlap, contour=ncc_contour, + connect=ncc_connect, prog_plot=prog_plot) else: cp = self.clear_polygon3(pol, tool, self.grb_circle_steps, - overlap=overlap, contour=contour, - connect=connect, + overlap=ncc_overlap, contour=ncc_contour, + connect=ncc_connect, prog_plot=prog_plot) if cp: cleared_geo += list(cp.get_objects()) @@ -2115,15 +2146,18 @@ class NonCopperClear(FlatCAMTool, Gerber): if isinstance(p, Polygon): if ncc_method == 'standard': cp = self.clear_polygon(p, tool, self.grb_circle_steps, - overlap=overlap, contour=contour, connect=connect, + overlap=ncc_overlap, contour=ncc_contour, + connect=ncc_connect, prog_plot=prog_plot) elif ncc_method == 'seed': cp = self.clear_polygon2(p, tool, self.grb_circle_steps, - overlap=overlap, contour=contour, connect=connect, + overlap=ncc_overlap, contour=ncc_contour, + connect=ncc_connect, prog_plot=prog_plot) else: cp = self.clear_polygon3(p, tool, self.grb_circle_steps, - overlap=overlap, contour=contour, connect=connect, + overlap=ncc_overlap, contour=ncc_contour, + connect=ncc_connect, prog_plot=prog_plot) if cp: cleared_geo += list(cp.get_objects()) @@ -2155,7 +2189,7 @@ class NonCopperClear(FlatCAMTool, Gerber): # check if there is a geometry at all in the cleared geometry if cleared_geo: # Overall cleared area - cleared = empty.buffer(-offset * (1 + overlap)).buffer(-tool / 1.999999).buffer( + cleared = empty.buffer(-offset * (1 + ncc_overlap)).buffer(-tool / 1.999999).buffer( tool / 1.999999) # clean-up cleared geo @@ -2181,18 +2215,6 @@ class NonCopperClear(FlatCAMTool, Gerber): if self.app.defaults["tools_ncc_plotting"] == 'progressive': self.temp_shapes.clear(update=True) - # # delete tools with empty geometry - # keys_to_delete = [] - # # look for keys in the tools_storage dict that have 'solid_geometry' values empty - # for uid in tools_storage: - # # if the solid_geometry (type=list) is empty - # if not tools_storage[uid]['solid_geometry']: - # keys_to_delete.append(uid) - # - # # actual delete of keys from the tools_storage dict - # for k in keys_to_delete: - # tools_storage.pop(k, None) - # delete tools with empty geometry # look for keys in the tools_storage dict that have 'solid_geometry' values empty for uid, uid_val in list(tools_storage.items()): @@ -2248,26 +2270,9 @@ class NonCopperClear(FlatCAMTool, Gerber): app_obj.poly_not_cleared = False return "fail" - # create the solid_geometry - # geo_obj.solid_geometry = list() - # for tooluid in geo_obj.tools: - # if geo_obj.tools[tooluid]['solid_geometry']: - # try: - # for geo in geo_obj.tools[tooluid]['solid_geometry']: - # geo_obj.solid_geometry.append(geo) - # except TypeError: - # geo_obj.solid_geometry.append(geo_obj.tools[tooluid]['solid_geometry']) - # # # Experimental... # # print("Indexing...", end=' ') # # geo_obj.make_index() - # if warning_flag == 0: - # self.app.inform.emit('[success] %s' % _("NCC Tool clear all done.")) - # else: - # self.app.inform.emit('[WARNING] %s: %s %s.' % ( - # _("NCC Tool clear all done but the copper features isolation is broken for"), - # str(warning_flag), - # _("tools"))) # ########################################################################################### # Initializes the new geometry object for the case of the rest-machining #################### @@ -2300,175 +2305,57 @@ class NonCopperClear(FlatCAMTool, Gerber): # repurposed flag for final object, geo_obj. True if it has any solid_geometry, False if not. app_obj.poly_not_cleared = True + log.debug("NCC Tool. Calculate 'empty' area.") app_obj.inform.emit("NCC Tool. Calculate 'empty' area.") - # ################################################################################################### - # Calculate the empty area by subtracting the solid_geometry from the object bounding box geometry ## - # ################################################################################################### - if ncc_obj.kind == 'gerber' and not isotooldia: - sol_geo = ncc_obj.solid_geometry - if has_offset is True: - app_obj.inform.emit('[WARNING_NOTCL] %s ...' % _("Buffering")) - sol_geo = sol_geo.buffer(distance=ncc_offset) - app_obj.inform.emit('[success] %s ...' % _("Buffering finished")) - empty = self.get_ncc_empty_area(target=sol_geo, boundary=bounding_box) - if empty == 'fail': - return 'fail' - - if empty.is_empty: - app_obj.inform.emit('[ERROR_NOTCL] %s' % - _("Could not get the extent of the area to be non copper cleared.")) - return 'fail' - elif ncc_obj.kind == 'gerber' and isotooldia: - isolated_geo = [] - self.solid_geometry = ncc_obj.solid_geometry - - # if milling type is climb then the move is counter-clockwise around features - milling_type = self.milling_type_radio.get_value() - - for tool_iso in isotooldia: - new_geometry = [] - - if milling_type == 'cl': - isolated_geo = self.generate_envelope(tool_iso, 1) - else: - isolated_geo = self.generate_envelope(tool_iso, 0) - - if isolated_geo == 'fail': - app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Isolation geometry could not be generated.")) - else: - app_obj.inform.emit('[WARNING_NOTCL] %s' % _("Isolation geometry is broken. Margin is less " - "than isolation tool diameter.")) - - try: - for geo_elem in isolated_geo: - # provide the app with a way to process the GUI events when in a blocking loop - QtWidgets.QApplication.processEvents() - - if self.app.abort_flag: - # graceful abort requested by the user - raise FlatCAMApp.GracefulException - - if isinstance(geo_elem, Polygon): - for ring in self.poly2rings(geo_elem): - new_geo = ring.intersection(bounding_box) - if new_geo and not new_geo.is_empty: - new_geometry.append(new_geo) - elif isinstance(geo_elem, MultiPolygon): - for poly in geo_elem: - for ring in self.poly2rings(poly): - new_geo = ring.intersection(bounding_box) - if new_geo and not new_geo.is_empty: - new_geometry.append(new_geo) - elif isinstance(geo_elem, LineString): - new_geo = geo_elem.intersection(bounding_box) - if new_geo: - if not new_geo.is_empty: - new_geometry.append(new_geo) - elif isinstance(geo_elem, MultiLineString): - for line_elem in geo_elem: - new_geo = line_elem.intersection(bounding_box) - if new_geo and not new_geo.is_empty: - new_geometry.append(new_geo) - except TypeError: - try: - if isinstance(isolated_geo, Polygon): - for ring in self.poly2rings(isolated_geo): - new_geo = ring.intersection(bounding_box) - if new_geo: - if not new_geo.is_empty: - new_geometry.append(new_geo) - elif isinstance(isolated_geo, LineString): - new_geo = isolated_geo.intersection(bounding_box) - if new_geo and not new_geo.is_empty: - new_geometry.append(new_geo) - elif isinstance(isolated_geo, MultiLineString): - for line_elem in isolated_geo: - new_geo = line_elem.intersection(bounding_box) - if new_geo and not new_geo.is_empty: - new_geometry.append(new_geo) - except Exception: - pass - - # a MultiLineString geometry element will show that the isolation is broken for this tool - for geo_e in new_geometry: - if type(geo_e) == MultiLineString: - warning_flag += 1 - break - - for k, v in tools_storage.items(): - if float('%.*f' % (self.decimals, v['tooldia'])) == float('%.*f' % (self.decimals, - tool_iso)): - current_uid = int(k) - # add the solid_geometry to the current too in self.paint_tools dictionary - # and then reset the temporary list that stored that solid_geometry - v['solid_geometry'] = deepcopy(new_geometry) - v['data']['name'] = name - break - geo_obj.tools[current_uid] = dict(tools_storage[current_uid]) - - sol_geo = cascaded_union(isolated_geo) - if has_offset is True: - app_obj.inform.emit('[WARNING_NOTCL] %s ...' % _("Buffering")) - sol_geo = sol_geo.buffer(distance=ncc_offset) - app_obj.inform.emit('[success] %s ...' % _("Buffering finished")) - empty = self.get_ncc_empty_area(target=sol_geo, boundary=bounding_box) - if empty == 'fail': - return 'fail' - - if empty.is_empty: - app_obj.inform.emit('[ERROR_NOTCL] %s' % - _("Isolation geometry is broken. Margin is less than isolation tool diameter.")) - return 'fail' - - elif ncc_obj.kind == 'geometry': - sol_geo = cascaded_union(ncc_obj.solid_geometry) - if has_offset is True: - app_obj.inform.emit('[WARNING_NOTCL] %s ...' % _("Buffering")) - sol_geo = sol_geo.buffer(distance=ncc_offset) - app_obj.inform.emit('[success] %s ...' % _("Buffering finished")) - empty = self.get_ncc_empty_area(target=sol_geo, boundary=bounding_box) - if empty == 'fail': - return 'fail' - - if empty.is_empty: - app_obj.inform.emit('[ERROR_NOTCL] %s' % - _("Could not get the extent of the area to be non copper cleared.")) - return 'fail' - else: - app_obj.inform.emit('[ERROR_NOTCL] %s' % _('The selected object is not suitable for copper clearing.')) - return - - if self.app.abort_flag: - # graceful abort requested by the user - raise FlatCAMApp.GracefulException - - if type(empty) is Polygon: - empty = MultiPolygon([empty]) - - area = empty.buffer(0) - - log.debug("NCC Tool. Finished calculation of 'empty' area.") - app_obj.inform.emit("NCC Tool. Finished calculation of 'empty' area.") - # Generate area for each tool while sorted_tools: + log.debug("Starting geometry processing for tool: %s" % str(tool)) if self.app.abort_flag: # graceful abort requested by the user raise FlatCAMApp.GracefulException - tool = sorted_tools.pop(0) - log.debug("Starting geometry processing for tool: %s" % str(tool)) + # provide the app with a way to process the GUI events when in a blocking loop + QtWidgets.QApplication.processEvents() app_obj.inform.emit('[success] %s = %s%s %s' % ( _('NCC Tool clearing with tool diameter'), str(tool), units.lower(), _('started.')) ) app_obj.proc_container.update_view_text(' %d%%' % 0) + tool = sorted_tools.pop(0) + + tooluid = 0 + for k, v in self.ncc_tools.items(): + if float('%.*f' % (self.decimals, v['tooldia'])) == float('%.*f' % (self.decimals, tool)): + tooluid = int(k) + break + + ncc_overlap = float(self.ncc_tools[tooluid]["data"]["nccoverlap"]) / 100.0 + ncc_margin = float(self.ncc_tools[tooluid]["data"]["nccmargin"]) + ncc_method = self.ncc_tools[tooluid]["data"]["nccmethod"] + ncc_connect = self.ncc_tools[tooluid]["data"]["nccconnect"] + ncc_contour = self.ncc_tools[tooluid]["data"]["ncccontour"] + has_offset = self.ncc_tools[tooluid]["data"]["nccoffset"] + ncc_offset = float(self.ncc_tools[tooluid]["data"]["nccoffset_value"]) + tool_used = tool - 1e-12 cleared_geo[:] = [] + # Bounding box for current tool + bbox = self.get_tool_bounding_box(ncc_obj=ncc_obj, sel_obj=sel_obj, ncc_select=ncc_select, + ncc_margin=ncc_margin) + + # Area to clear + empty, warning_flag = self.get_tool_empty_area(name=name, ncc_obj=ncc_obj, geo_obj=geo_obj, + isotooldia=isotooldia, + has_offset=has_offset, ncc_offset=ncc_offset, + ncc_margin=ncc_margin, tools_storage=tools_storage, + bounding_box=bbox) + + area = empty.buffer(0) + # Area to clear for poly in cleared_by_last_tool: # provide the app with a way to process the GUI events when in a blocking loop @@ -2479,7 +2366,7 @@ class NonCopperClear(FlatCAMTool, Gerber): raise FlatCAMApp.GracefulException try: area = area.difference(poly) - except Exception as e: + except Exception: pass cleared_by_last_tool[:] = [] @@ -2520,17 +2407,20 @@ class NonCopperClear(FlatCAMTool, Gerber): if ncc_method == 'standard': cp = self.clear_polygon(p, tool_used, self.grb_circle_steps, - overlap=overlap, contour=contour, connect=connect, + overlap=ncc_overlap, contour=ncc_contour, + connect=ncc_connect, prog_plot=prog_plot) elif ncc_method == 'seed': cp = self.clear_polygon2(p, tool_used, self.grb_circle_steps, - overlap=overlap, contour=contour, connect=connect, + overlap=ncc_overlap, contour=ncc_contour, + connect=ncc_connect, prog_plot=prog_plot) else: cp = self.clear_polygon3(p, tool_used, self.grb_circle_steps, - overlap=overlap, contour=contour, connect=connect, + overlap=ncc_overlap, contour=ncc_contour, + connect=ncc_connect, prog_plot=prog_plot) cleared_geo.append(list(cp.get_objects())) except Exception as e: @@ -2549,20 +2439,20 @@ class NonCopperClear(FlatCAMTool, Gerber): if ncc_method == 'standard': cp = self.clear_polygon(poly, tool_used, self.grb_circle_steps, - overlap=overlap, contour=contour, - connect=connect, + overlap=ncc_overlap, contour=ncc_contour, + connect=ncc_connect, prog_plot=prog_plot) elif ncc_method == 'seed': cp = self.clear_polygon2(poly, tool_used, self.grb_circle_steps, - overlap=overlap, contour=contour, - connect=connect, + overlap=ncc_overlap, contour=ncc_contour, + connect=ncc_connect, prog_plot=prog_plot) else: cp = self.clear_polygon3(poly, tool_used, self.grb_circle_steps, - overlap=overlap, contour=contour, - connect=connect, + overlap=ncc_overlap, contour=ncc_contour, + connect=ncc_connect, prog_plot=prog_plot) cleared_geo.append(list(cp.get_objects())) except Exception as e: @@ -2662,9 +2552,9 @@ class NonCopperClear(FlatCAMTool, Gerber): def job_thread(app_obj): try: if rest_machining_choice is True: - app_obj.new_object("geometry", name, gen_clear_area_rest, plot=plot) + app_obj.new_object("geometry", name, gen_clear_area_rest) else: - app_obj.new_object("geometry", name, gen_clear_area, plot=plot) + app_obj.new_object("geometry", name, gen_clear_area) except FlatCAMApp.GracefulException: if run_threaded: proc.done() From 0ad0dbd9ea2112bd5c5634eb16370d3baf5757fe Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 17 Jan 2020 19:31:37 +0200 Subject: [PATCH 034/209] - NCC Tool - some PEP 8 corrections --- flatcamTools/ToolNonCopperClear.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNonCopperClear.py index 2b145606..fb88a710 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/flatcamTools/ToolNonCopperClear.py @@ -1796,7 +1796,7 @@ class NonCopperClear(FlatCAMTool, Gerber): if empty.is_empty: self.app.inform.emit('[ERROR_NOTCL] %s' % - _("Could not get the extent of the area to be non copper cleared.")) + _("Could not get the extent of the area to be non copper cleared.")) return 'fail' elif ncc_obj.kind == 'gerber' and isotooldia: isolated_geo = [] @@ -1824,7 +1824,7 @@ class NonCopperClear(FlatCAMTool, Gerber): else: if ncc_margin < tool_iso: self.app.inform.emit('[WARNING_NOTCL] %s' % _("Isolation geometry is broken. Margin is less " - "than isolation tool diameter.")) + "than isolation tool diameter.")) try: for geo_elem in isolated_geo: # provide the app with a way to process the GUI events when in a blocking loop @@ -1901,7 +1901,7 @@ class NonCopperClear(FlatCAMTool, Gerber): if empty.is_empty: self.app.inform.emit('[ERROR_NOTCL] %s' % - _("Isolation geometry is broken. Margin is less than isolation tool diameter.")) + _("Isolation geometry is broken. Margin is less than isolation tool diameter.")) return 'fail' elif ncc_obj.kind == 'geometry': sol_geo = cascaded_union(ncc_obj.solid_geometry) @@ -1915,7 +1915,7 @@ class NonCopperClear(FlatCAMTool, Gerber): if empty.is_empty: self.app.inform.emit('[ERROR_NOTCL] %s' % - _("Could not get the extent of the area to be non copper cleared.")) + _("Could not get the extent of the area to be non copper cleared.")) return 'fail' else: self.app.inform.emit('[ERROR_NOTCL] %s' % _('The selected object is not suitable for copper clearing.')) @@ -1941,10 +1941,11 @@ class NonCopperClear(FlatCAMTool, Gerber): Clear the excess copper from the entire object. :param ncc_obj: ncc cleared object + :param sel_obj: :param ncctooldia: a tuple or single element made out of diameters of the tools to be used to ncc clear :param isotooldia: a tuple or single element made out of diameters of the tools to be used for isolation :param outname: name of the resulting object - + :param order: :param tools_storage: whether to use the current tools_storage self.ncc_tools or a different one. Usage of the different one is related to when this function is called from a TcL command. @@ -2035,7 +2036,6 @@ class NonCopperClear(FlatCAMTool, Gerber): tool = eval(self.app.defaults["tools_ncctools"]) # COPPER CLEARING # - cp = None for tool in sorted_tools: log.debug("Starting geometry processing for tool: %s" % str(tool)) if self.app.abort_flag: @@ -2604,6 +2604,7 @@ class NonCopperClear(FlatCAMTool, Gerber): Clear the excess copper from the entire object. To be used only in a TCL command. :param ncc_obj: ncc cleared object + :param sel_obj: :param ncctooldia: a tuple or single element made out of diameters of the tools to be used to ncc clear :param isotooldia: a tuple or single element made out of diameters of the tools to be used for isolation :param overlap: value by which the paths will overlap @@ -2946,7 +2947,7 @@ class NonCopperClear(FlatCAMTool, Gerber): return 'fail' else: - app_obj.inform.emit('[ERROR_NOTCL] %s' % _('The selected object is not suitable for copper clearing.')) + app_obj.inform.emit('[ERROR_NOTCL] %s' % _('The selected object is not suitable for copper clearing.')) return 'fail' if type(empty) is Polygon: @@ -2956,7 +2957,6 @@ class NonCopperClear(FlatCAMTool, Gerber): self.app.inform.emit(_("NCC Tool. Finished calculation of 'empty' area.")) # COPPER CLEARING # - cp = None for tool in sorted_tools: log.debug("Starting geometry processing for tool: %s" % str(tool)) if self.app.abort_flag: @@ -3279,7 +3279,7 @@ class NonCopperClear(FlatCAMTool, Gerber): new_geo = line_elem.intersection(bounding_box) if new_geo and not new_geo.is_empty: new_geometry.append(new_geo) - except Exception as e: + except Exception: pass # a MultiLineString geometry element will show that the isolation is broken for this tool @@ -3424,8 +3424,8 @@ class NonCopperClear(FlatCAMTool, Gerber): overlap=overlap, contour=contour, connect=connect, prog_plot=False) cleared_geo.append(list(cp.get_objects())) - except Exception as e: - log.warning("Polygon can't be cleared. %s" % str(e)) + except Exception as ee: + log.warning("Polygon can't be cleared. %s" % str(ee)) # this polygon should be added to a list and then try clear it with # a smaller tool rest_geo.append(p) @@ -3456,8 +3456,8 @@ class NonCopperClear(FlatCAMTool, Gerber): connect=connect, prog_plot=False) cleared_geo.append(list(cp.get_objects())) - except Exception as e: - log.warning("Polygon can't be cleared. %s" % str(e)) + except Exception as eee: + log.warning("Polygon can't be cleared. %s" % str(eee)) # this polygon should be added to a list and then try clear it with # a smaller tool rest_geo.append(poly) @@ -3598,7 +3598,7 @@ class NonCopperClear(FlatCAMTool, Gerber): boundary = boundary try: ret_val = boundary.difference(target) - except Exception as e: + except Exception: try: for el in target: # provide the app with a way to process the GUI events when in a blocking loop @@ -3615,7 +3615,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.app.proc_container.update_view_text(' %d%%' % disp_number) old_disp_number = disp_number return boundary - except Exception as e: + except Exception: self.app.inform.emit('[ERROR_NOTCL] %s' % _("Try to use the Buffering Type = Full in Preferences -> Gerber General. " "Reload the Gerber file after this change.")) From 36280d9f543772dce3ba1099b7844c2e4cb15d8c Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 17 Jan 2020 23:06:28 +0200 Subject: [PATCH 035/209] - some updates in NCC Tool --- README.md | 1 + flatcamTools/ToolNonCopperClear.py | 44 +++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e7b553e6..86a2a19b 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ CAD program, and create G-Code for Isolation routing. - more changes to Excellon UI - changes to Geometry UI - more work in NCC Tool upgrade; each tool now work with it's own set of parameters +- some updates in NCC Tool 16.01.2020 diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNonCopperClear.py index fb88a710..840e383f 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/flatcamTools/ToolNonCopperClear.py @@ -669,7 +669,7 @@ class NonCopperClear(FlatCAMTool, Gerber): # ############################ SIGNALS ######################################## # ############################################################################# self.addtool_btn.clicked.connect(self.on_tool_add) - self.addtool_entry.returnPressed.connect(self.on_tool_add) + self.addtool_entry.returnPressed.connect(self.on_tooldia_updated) self.deltool_btn.clicked.connect(self.on_tool_delete) self.generate_ncc_button.clicked.connect(self.on_ncc_click) @@ -686,8 +686,6 @@ class NonCopperClear(FlatCAMTool, Gerber): self.type_obj_combo.currentIndexChanged.connect(self.on_type_obj_index_changed) self.reset_button.clicked.connect(self.set_tool_ui) - self.tools_table.currentItemChanged.connect(self.on_row_selection_change) - def on_type_obj_index_changed(self, index): obj_type = self.type_obj_combo.currentIndex() self.object_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) @@ -760,6 +758,7 @@ class NonCopperClear(FlatCAMTool, Gerber): option_changed = self.name2option[wdg_objname] row = self.tools_table.currentRow() + if row < 0: row = 0 tooluid_item = int(self.tools_table.item(row, 3).text()) @@ -882,6 +881,7 @@ class NonCopperClear(FlatCAMTool, Gerber): def set_tool_ui(self): self.units = self.app.defaults['units'].upper() + self.old_tool_dia = self.app.defaults["tools_nccnewdia"] self.tools_frame.show() @@ -1079,6 +1079,10 @@ class NonCopperClear(FlatCAMTool, Gerber): def ui_connect(self): self.tools_table.itemChanged.connect(self.on_tool_edit) + # rows selected + self.tools_table.clicked.connect(self.on_row_selection_change) + self.tools_table.horizontalHeader().sectionClicked.connect(self.on_row_selection_change) + for row in range(self.tools_table.rowCount()): try: self.tools_table.cellWidget(row, 2).currentIndexChanged.connect(self.on_tooltable_cellwidget_change) @@ -1111,6 +1115,15 @@ class NonCopperClear(FlatCAMTool, Gerber): except (TypeError, ValueError): pass + try: + self.ncc_rest_cb.stateChanged.disconnect() + except (TypeError, ValueError): + pass + try: + self.ncc_order_radio.activated_custom[str].disconnect() + except (TypeError, ValueError): + pass + # then reconnect for opt in self.form_fields: current_widget = self.form_fields[opt] @@ -1121,11 +1134,11 @@ class NonCopperClear(FlatCAMTool, Gerber): elif isinstance(current_widget, FCDoubleSpinner): current_widget.returnPressed.connect(self.form_to_storage) - self.ncc_choice_offset_cb.stateChanged.connect(self.on_offset_choice) self.ncc_rest_cb.stateChanged.connect(self.on_rest_machining_check) self.ncc_order_radio.activated_custom[str].connect(self.on_order_changed) def ui_disconnect(self): + try: # if connected, disconnect the signal from the slot on item_changed as it creates issues self.tools_table.itemChanged.disconnect() @@ -1163,6 +1176,29 @@ class NonCopperClear(FlatCAMTool, Gerber): except (TypeError, ValueError): pass + try: + self.ncc_rest_cb.stateChanged.disconnect() + except (TypeError, ValueError): + pass + try: + self.ncc_order_radio.activated_custom[str].disconnect() + except (TypeError, ValueError): + pass + + # rows selected + try: + self.tools_table.clicked.disconnect() + except (TypeError, AttributeError): + pass + try: + self.tools_table.horizontalHeader().sectionClicked.disconnect() + except (TypeError, AttributeError): + pass + + def on_tooldia_updated(self): + if self.tool_type_radio.get_value() == 'C1': + self.old_tool_dia = self.addtool_entry.get_value() + def on_combo_box_type(self): obj_type = self.box_combo_type.currentIndex() self.box_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) From abc20cf0a5d21e13ffddac41322d26d01aa5ad5e Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 18 Jan 2020 01:47:48 +0200 Subject: [PATCH 036/209] - optimized the object envelope generation in the redesigned NCC Tool --- README.md | 1 + flatcamTools/ToolNonCopperClear.py | 146 ++++++++++++++++++----------- 2 files changed, 93 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index 86a2a19b..540febd5 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ CAD program, and create G-Code for Isolation routing. - changes to Geometry UI - more work in NCC Tool upgrade; each tool now work with it's own set of parameters - some updates in NCC Tool +- optimized the object envelope generation in the redesigned NCC Tool 16.01.2020 diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNonCopperClear.py index 840e383f..7eca4da2 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/flatcamTools/ToolNonCopperClear.py @@ -1698,33 +1698,19 @@ class NonCopperClear(FlatCAMTool, Gerber): self.app.draw_moving_selection_shape(old_coords=(self.cursor_pos[0], self.cursor_pos[1]), coords=(curr_pos[0], curr_pos[1])) - def get_tool_bounding_box(self, ncc_obj, sel_obj, ncc_select, ncc_margin): - """ - Prepare non-copper polygons. - Create the bounding box area from which the copper features will be subtracted - - :param ncc_obj: the Gerber object to be non-copper cleared - :param sel_obj: the FlatCAM object to be used as a area delimitator - :param ncc_select: the kind of area to be copper cleared - :param ncc_margin: the margin around the area to be copper cleared - :return: an geometric element (Polygon or MultiPolygon) that specify the area to be copper cleared + def envelope_object(self, ncc_obj, ncc_select, box_obj=None): """ - log.debug("NCC Tool. Preparing non-copper polygons.") - self.app.inform.emit(_("NCC Tool. Preparing non-copper polygons.")) + :param ncc_obj: + :param box_obj: + :param ncc_select: + :return: + """ + box_kind = box_obj.kind if box_obj is not None else None - try: - if sel_obj is None or sel_obj == 'itself': - ncc_sel_obj = ncc_obj - else: - ncc_sel_obj = sel_obj - except Exception as e: - log.debug("NonCopperClear.clear_copper() --> %s" % str(e)) - return 'fail' - - bounding_box = None + env_obj = None if ncc_select == 'itself': - geo_n = ncc_sel_obj.solid_geometry + geo_n = ncc_obj.solid_geometry try: if isinstance(geo_n, MultiPolygon): @@ -1735,51 +1721,85 @@ class NonCopperClear(FlatCAMTool, Gerber): else: env_obj = cascaded_union(geo_n) env_obj = env_obj.convex_hull - - bounding_box = env_obj.buffer(distance=ncc_margin, join_style=base.JOIN_STYLE.mitre) except Exception as e: - log.debug("NonCopperClear.clear_copper() 'itself' --> %s" % str(e)) + log.debug("NonCopperClear.envelope_object() 'itself' --> %s" % str(e)) self.app.inform.emit('[ERROR_NOTCL] %s' % _("No object available.")) + return None + elif ncc_select == 'area': + env_obj = cascaded_union(self.sel_rect) + try: + __ = iter(env_obj) + except Exception: + env_obj = [env_obj] + elif ncc_select == 'box': + if box_obj is None: + return None, None + + box_geo = box_obj.solid_geometry + if box_kind == 'geometry': + try: + __ = iter(box_geo) + env_obj = box_geo + except Exception: + env_obj = [box_geo] + + elif box_kind == 'gerber': + box_geo = cascaded_union(box_obj.solid_geometry).convex_hull + ncc_geo = cascaded_union(ncc_obj.solid_geometry).convex_hull + env_obj = ncc_geo.intersection(box_geo) + else: + self.app.inform.emit('[ERROR_NOTCL] %s' % _("The reference object type is not supported.")) return 'fail' - elif ncc_select == 'area': - geo_n = cascaded_union(self.sel_rect) - try: - __ = iter(geo_n) - except Exception as e: - log.debug("NonCopperClear.clear_copper() 'area' --> %s" % str(e)) - geo_n = [geo_n] + return env_obj, box_kind + def envelope_object_to_tool_bounding_box(self, env_obj, box_kind, ncc_select, ncc_margin): + """ + Prepare non-copper polygons. + Create the bounding box area from which the copper features will be subtracted + + :param env_obj: the Geometry to be used as bounding box after applying the ncc_margin + :param box_kind: "geometry" or "gerber" + :param ncc_select: the kind of area to be copper cleared + :param ncc_margin: the margin around the area to be copper cleared + :return: an geometric element (Polygon or MultiPolygon) that specify the area to be copper cleared + """ + + log.debug("NCC Tool. Preparing non-copper polygons.") + self.app.inform.emit(_("NCC Tool. Preparing non-copper polygons.")) + + if env_obj is None: + log.debug("NonCopperClear.envelope_object_to_tool_bounding_box() --> The object is None") + return 'fail' + + bounding_box = None + if ncc_select == 'itself': + try: + bounding_box = env_obj.buffer(distance=ncc_margin, join_style=base.JOIN_STYLE.mitre) + except Exception as e: + log.debug("NonCopperClear.envelope_object_to_tool_bounding_box() 'itself' --> %s" % str(e)) + self.app.inform.emit('[ERROR_NOTCL] %s' % _("No object available.")) + return 'fail' + elif ncc_select == 'area': geo_buff_list = [] - for poly in geo_n: + for poly in env_obj: if self.app.abort_flag: # graceful abort requested by the user raise FlatCAMApp.GracefulException geo_buff_list.append(poly.buffer(distance=ncc_margin, join_style=base.JOIN_STYLE.mitre)) - bounding_box = cascaded_union(geo_buff_list) - elif ncc_select == 'box': - geo_n = ncc_sel_obj.solid_geometry - if ncc_sel_obj.kind == 'geometry': - try: - __ = iter(geo_n) - except Exception as e: - log.debug("NonCopperClear.clear_copper() 'box' --> %s" % str(e)) - geo_n = [geo_n] - - geo_buff_list = [] - for poly in geo_n: + if box_kind == 'geometry': + geo_buff_list = list() + for poly in env_obj: if self.app.abort_flag: # graceful abort requested by the user raise FlatCAMApp.GracefulException geo_buff_list.append(poly.buffer(distance=ncc_margin, join_style=base.JOIN_STYLE.mitre)) bounding_box = cascaded_union(geo_buff_list) - elif ncc_sel_obj.kind == 'gerber': - geo_n = cascaded_union(geo_n).convex_hull - bounding_box = cascaded_union(self.ncc_obj.solid_geometry).convex_hull.intersection(geo_n) - bounding_box = bounding_box.buffer(distance=ncc_margin, join_style=base.JOIN_STYLE.mitre) + elif box_kind == 'gerber': + bounding_box = env_obj.buffer(distance=ncc_margin, join_style=base.JOIN_STYLE.mitre) else: self.app.inform.emit('[ERROR_NOTCL] %s' % _("The reference object type is not supported.")) return 'fail' @@ -2071,6 +2091,15 @@ class NonCopperClear(FlatCAMTool, Gerber): except TypeError: tool = eval(self.app.defaults["tools_ncctools"]) + if ncc_select == 'box': + env_obj, box_obj_kind = self.envelope_object(ncc_obj=ncc_obj, box_obj=sel_obj, ncc_select=ncc_select) + else: + env_obj, box_obj_kind = self.envelope_object(ncc_obj=ncc_obj, ncc_select=ncc_select) + + if env_obj is None and box_obj_kind is None: + self.app.inform.emit("[ERROR_NOTCL] %s" % _("NCC Tool failed creating bounding box.")) + return "fail" + # COPPER CLEARING # for tool in sorted_tools: log.debug("Starting geometry processing for tool: %s" % str(tool)) @@ -2106,8 +2135,8 @@ class NonCopperClear(FlatCAMTool, Gerber): offset -= (tool - 1e-12) # Bounding box for current tool - bbox = self.get_tool_bounding_box(ncc_obj=ncc_obj, sel_obj=sel_obj, ncc_select=ncc_select, - ncc_margin=ncc_margin) + bbox = self.envelope_object_to_tool_bounding_box(env_obj=env_obj, box_kind=box_obj_kind, + ncc_select=ncc_select, ncc_margin=ncc_margin) # Area to clear empty, warning_flag = self.get_tool_empty_area(name=name, ncc_obj=ncc_obj, geo_obj=geo_obj, @@ -2342,6 +2371,15 @@ class NonCopperClear(FlatCAMTool, Gerber): # repurposed flag for final object, geo_obj. True if it has any solid_geometry, False if not. app_obj.poly_not_cleared = True + if ncc_select == 'box': + env_obj, box_obj_kind = self.envelope_object(ncc_obj=ncc_obj, box_obj=sel_obj, ncc_select=ncc_select) + else: + env_obj, box_obj_kind = self.envelope_object(ncc_obj=ncc_obj, ncc_select=ncc_select) + + if env_obj is None and box_obj_kind is None: + self.app.inform.emit("[ERROR_NOTCL] %s" % _("NCC Tool failed creating bounding box.")) + return "fail" + log.debug("NCC Tool. Calculate 'empty' area.") app_obj.inform.emit("NCC Tool. Calculate 'empty' area.") @@ -2380,8 +2418,8 @@ class NonCopperClear(FlatCAMTool, Gerber): cleared_geo[:] = [] # Bounding box for current tool - bbox = self.get_tool_bounding_box(ncc_obj=ncc_obj, sel_obj=sel_obj, ncc_select=ncc_select, - ncc_margin=ncc_margin) + bbox = self.envelope_object_to_tool_bounding_box(env_obj=env_obj, box_kind=box_obj_kind, + ncc_select=ncc_select, ncc_margin=ncc_margin) # Area to clear empty, warning_flag = self.get_tool_empty_area(name=name, ncc_obj=ncc_obj, geo_obj=geo_obj, From 24260b29b4c2652ca5a732e9c1462bc7ecc57a9c Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 19 Jan 2020 17:09:41 +0200 Subject: [PATCH 037/209] - fixed some bugs that are visible in Linux regarding the ArgsThread class: on app close we need to quit the QThread running the ArgsThread class and also close the opened Socket --- FlatCAMApp.py | 8 ++++++++ README.md | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index dce2111f..1c843738 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -2681,6 +2681,9 @@ class App(QtCore.QObject): from flatcamGUI.PlotCanvasLegacy import ShapeCollectionLegacy self.tool_shapes = ShapeCollectionLegacy(obj=self, app=self, name="tool") + # used in the delayed shutdown self.start_delayed_quit() method + self.save_timer = None + # ############################################################################### # ################# ADDING FlatCAM EDITORS section ############################## # ############################################################################### @@ -5200,6 +5203,7 @@ class App(QtCore.QObject): del stgs log.debug("App.final_save() --> App UI state saved.") + self.th.quit() self.close_app_signal.emit() def kill_app(self): @@ -12654,6 +12658,10 @@ class ArgsThread(QtCore.QObject): conn.send('close') # close the current instance only if there are args if len(sys.argv) > 1: + try: + listener.close() + except Exception: + pass sys.exit() def serve(self, conn): diff --git a/README.md b/README.md index 2c446e8a..e99020bc 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +19.01.2020 + +- fixed some bugs that are visible in Linux regarding the ArgsThread class: on app close we need to quit the QThread running the ArgsThread class and also close the opened Socket + 15.01.2020 - added key shortcuts and toolbar icons for the new tools: Align Object Tool (ALT+A) and Extract Drills (ALT+I) From a9d69a57fe829130bf64b83e2a81fcada979afee Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 19 Jan 2020 17:39:32 +0200 Subject: [PATCH 038/209] - make sure that the fixes above apply when rebooting app for theme change or for language change --- FlatCAMApp.py | 23 +++++++++++++++++++---- FlatCAMTranslation.py | 6 ++++++ README.md | 1 + 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 1c843738..63924a09 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -5203,7 +5203,20 @@ class App(QtCore.QObject): del stgs log.debug("App.final_save() --> App UI state saved.") - self.th.quit() + + # try to quit the QThread that run ArgsThread class + try: + self.th.quit() + except Exception: + pass + + # try to quit the Socket opened by ArgsThread class + try: + self.new_launch.listener.close() + except Exception: + pass + + # quit app by signalling for self.kill_app() method self.close_app_signal.emit() def kill_app(self): @@ -12644,13 +12657,15 @@ class ArgsThread(QtCore.QObject): def __init__(self): super(ArgsThread, self).__init__() + self.listener = None + self.start.connect(self.run) def my_loop(self, address): try: - listener = Listener(*address) + self.listener = Listener(*address) while True: - conn = listener.accept() + conn = self.listener.accept() self.serve(conn) except socket.error: conn = Client(*address) @@ -12659,7 +12674,7 @@ class ArgsThread(QtCore.QObject): # close the current instance only if there are args if len(sys.argv) > 1: try: - listener.close() + self.listener.close() except Exception: pass sys.exit() diff --git a/FlatCAMTranslation.py b/FlatCAMTranslation.py index 7db184d9..f7e75d96 100644 --- a/FlatCAMTranslation.py +++ b/FlatCAMTranslation.py @@ -183,6 +183,12 @@ def restart_program(app, ask=None): else: resource_loc = 'share' + # close the Socket in ArgsThread class + app.new_launch.listener.close() + + # close the QThread that runs ArgsThread class + app.th.quit() + if app.should_we_save and app.collection.get_list() or ask is True: msgbox = QtWidgets.QMessageBox() msgbox.setText(_("There are files/objects modified in FlatCAM. " diff --git a/README.md b/README.md index e99020bc..b49bd5e4 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 19.01.2020 - fixed some bugs that are visible in Linux regarding the ArgsThread class: on app close we need to quit the QThread running the ArgsThread class and also close the opened Socket +- make sure that the fixes above apply when rebooting app for theme change or for language change 15.01.2020 From 87faa7e8406c52944f5964352cc746defd2c133e Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 19 Jan 2020 17:47:35 +0200 Subject: [PATCH 039/209] - restored the Readme file --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 540febd5..556d8f16 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,11 @@ CAD program, and create G-Code for Isolation routing. ================================================= +19.01.2020 + +- fixed some bugs that are visible in Linux regarding the ArgsThread class: on app close we need to quit the QThread running the ArgsThread class and also close the opened Socket +- make sure that the fixes above apply when rebooting app for theme change or for language change + 17.01.2020 - more changes to Excellon UI From 4047cc8499cc81d11775074cec451e401be4ec93 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 19 Jan 2020 17:55:34 +0200 Subject: [PATCH 040/209] - fixed and issue that made setting colors for the Gerber file not possible if using a translation --- FlatCAMApp.py | 17 ++++++++--------- README.md | 1 + 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 375601b0..3f3731ff 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -12459,33 +12459,32 @@ class App(QtCore.QObject): def on_set_color_action_triggered(self): new_color = self.defaults['gerber_plot_fill'] - act_name = self.sender().text().lower() - + act_name = self.sender().text() sel_obj_list = self.collection.get_selected() if not sel_obj_list: return - if act_name == 'red': + if act_name == _('Red'): new_color = '#FF0000' + \ str(hex(self.ui.gerber_defaults_form.gerber_gen_group.pf_color_alpha_slider.value())[2:]) - if act_name == 'blue': + if act_name == _('Blue'): new_color = '#0000FF' + \ str(hex(self.ui.gerber_defaults_form.gerber_gen_group.pf_color_alpha_slider.value())[2:]) - if act_name == 'yellow': + if act_name == _('Yellow'): new_color = '#FFDF00' + \ str(hex(self.ui.gerber_defaults_form.gerber_gen_group.pf_color_alpha_slider.value())[2:]) - if act_name == 'green': + if act_name == _('Green'): new_color = '#00FF00' + \ str(hex(self.ui.gerber_defaults_form.gerber_gen_group.pf_color_alpha_slider.value())[2:]) - if act_name == 'purple': + if act_name == _('Purple'): new_color = '#FF00FF' + \ str(hex(self.ui.gerber_defaults_form.gerber_gen_group.pf_color_alpha_slider.value())[2:]) - if act_name == 'brown': + if act_name == _('Brown'): new_color = '#A52A2A' + \ str(hex(self.ui.gerber_defaults_form.gerber_gen_group.pf_color_alpha_slider.value())[2:]) - if act_name == 'custom': + if act_name == _('Custom'): new_color = QtGui.QColor(self.defaults['gerber_plot_fill'][:7]) c_dialog = QtWidgets.QColorDialog() plot_fill_color = c_dialog.getColor(initial=new_color) diff --git a/README.md b/README.md index 556d8f16..f8f3643c 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ CAD program, and create G-Code for Isolation routing. - fixed some bugs that are visible in Linux regarding the ArgsThread class: on app close we need to quit the QThread running the ArgsThread class and also close the opened Socket - make sure that the fixes above apply when rebooting app for theme change or for language change +- fixed and issue that made setting colors for the Gerber file not possible if using a translation 17.01.2020 From 5b63dee50d90c55b1a8de91b211e332dfdaedf7d Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 19 Jan 2020 19:47:42 +0200 Subject: [PATCH 041/209] - made possible to set the colors for Excellon objects too - added to the possible colors the fundamentals: black and white - in the project context menu for setting colors added the option to set the transparency and also a default option which revert the color to the default value set in the Preferences --- FlatCAMApp.py | 84 +++++++++++++++++++++++++++++++++------- FlatCAMObj.py | 13 ++++++- ObjectCollection.py | 2 +- README.md | 3 ++ flatcamGUI/FlatCAMGUI.py | 16 ++++++++ 5 files changed, 101 insertions(+), 17 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 3f3731ff..9d73c0c8 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -12465,24 +12465,39 @@ class App(QtCore.QObject): if not sel_obj_list: return + # a default value, I just chose this one + alpha_level = 'BF' + for sel_obj in sel_obj_list: + if sel_obj.kind == 'excellon': + alpha_level = str(hex( + self.ui.excellon_defaults_form.excellon_gen_group.color_alpha_slider.value())[2:]) + elif sel_obj.kind == 'gerber': + alpha_level = str(hex(self.ui.gerber_defaults_form.gerber_gen_group.pf_color_alpha_slider.value())[2:]) + elif sel_obj.kind == 'geometry': + alpha_level = 'FF' + else: + log.debug( + "App.on_set_color_action_triggered() --> Default alpfa for this object type not supported yet") + continue + sel_obj.alpha_level = alpha_level + if act_name == _('Red'): - new_color = '#FF0000' + \ - str(hex(self.ui.gerber_defaults_form.gerber_gen_group.pf_color_alpha_slider.value())[2:]) + new_color = '#FF0000' + alpha_level if act_name == _('Blue'): - new_color = '#0000FF' + \ - str(hex(self.ui.gerber_defaults_form.gerber_gen_group.pf_color_alpha_slider.value())[2:]) + new_color = '#0000FF' + alpha_level + if act_name == _('Yellow'): - new_color = '#FFDF00' + \ - str(hex(self.ui.gerber_defaults_form.gerber_gen_group.pf_color_alpha_slider.value())[2:]) + new_color = '#FFDF00' + alpha_level if act_name == _('Green'): - new_color = '#00FF00' + \ - str(hex(self.ui.gerber_defaults_form.gerber_gen_group.pf_color_alpha_slider.value())[2:]) + new_color = '#00FF00' + alpha_level if act_name == _('Purple'): - new_color = '#FF00FF' + \ - str(hex(self.ui.gerber_defaults_form.gerber_gen_group.pf_color_alpha_slider.value())[2:]) + new_color = '#FF00FF' + alpha_level if act_name == _('Brown'): - new_color = '#A52A2A' + \ - str(hex(self.ui.gerber_defaults_form.gerber_gen_group.pf_color_alpha_slider.value())[2:]) + new_color = '#A52A2A' + alpha_level + if act_name == _('White'): + new_color = '#FFFFFF' + alpha_level + if act_name == _('Black'): + new_color = '#000000' + alpha_level if act_name == _('Custom'): new_color = QtGui.QColor(self.defaults['gerber_plot_fill'][:7]) @@ -12492,10 +12507,51 @@ class App(QtCore.QObject): if plot_fill_color.isValid() is False: return - new_color = str(plot_fill_color.name()) + \ - str(hex(self.ui.gerber_defaults_form.gerber_gen_group.pf_color_alpha_slider.value())[2:]) + new_color = str(plot_fill_color.name()) + alpha_level + + if act_name == _("Default"): + for sel_obj in sel_obj_list: + if sel_obj.kind == 'excellon': + new_color = self.defaults['excellon_plot_fill'] + new_line_color = self.defaults['excellon_plot_line'] + elif sel_obj.kind == 'gerber': + new_color = self.defaults['gerber_plot_fill'] + new_line_color = self.defaults['gerber_plot_line'] + elif sel_obj.kind == 'geometry': + new_color = self.defaults['geometry_plot_line'] + new_line_color = self.defaults['geometry_plot_line'] + else: + log.debug( + "App.on_set_color_action_triggered() --> Default color for this object type not supported yet") + continue + + sel_obj.fill_color = new_color + sel_obj.outline_color = new_line_color + + sel_obj.shapes.redraw( + update_colors=(new_color, new_line_color) + ) + return + + if act_name == _("Transparency"): + alpha_level, ok_button = QtWidgets.QInputDialog.getInt( + self.ui, _("Set alpha level ..."), '%s:' % _("Value"), min=0, max=255, step=1, value=191) + + if ok_button: + + alpha_str = str(hex(alpha_level)[2:]) if alpha_level != 0 else '00' + for sel_obj in sel_obj_list: + sel_obj.fill_color = sel_obj.fill_color[:-2] + alpha_str + + sel_obj.shapes.redraw( + update_colors=(sel_obj.fill_color, sel_obj.outline_color) + ) + + return new_line_color = color_variant(new_color[:7], 0.7) + if act_name == _("White"): + new_line_color = color_variant("#dedede", 0.7) for sel_obj in sel_obj_list: sel_obj.fill_color = new_color diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 447090a5..37a2d4bc 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -661,6 +661,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber): self.fill_color = self.app.defaults['gerber_plot_fill'] self.outline_color = self.app.defaults['gerber_plot_line'] + self.alpha_level = 'bf' # keep track if the UI is built so we don't have to build it every time self.ui_build = False @@ -671,7 +672,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber): # Attributes to be included in serialization # Always append to it because it carries contents # from predecessors. - self.ser_attrs += ['options', 'kind', 'fill_color', 'outline_color'] + self.ser_attrs += ['options', 'kind', 'fill_color', 'outline_color', 'alpha_level'] def set_ui(self, ui): """ @@ -2297,10 +2298,14 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.multigeo = False self.units_found = self.app.defaults['units'] + self.fill_color = self.app.defaults['excellon_plot_fill'] + self.outline_color = self.app.defaults['excellon_plot_line'] + self.alpha_level = 'bf' + # Attributes to be included in serialization # Always append to it because it carries contents # from predecessors. - self.ser_attrs += ['options', 'kind'] + self.ser_attrs += ['options', 'kind',] def merge(self, exc_list, exc_final): """ @@ -3753,6 +3758,10 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): # save here the old value for the Cut Z before it is changed by selecting a V-shape type tool in the tool table self.old_cutz = self.app.defaults["geometry_cutz"] + self.fill_color = self.app.defaults['geometry_plot_line'] + self.outline_color = self.app.defaults['geometry_plot_line'] + self.alpha_level = 'FF' + # Attributes to be included in serialization # Always append to it because it carries contents # from predecessors. diff --git a/ObjectCollection.py b/ObjectCollection.py index f134fc32..bf7c07dd 100644 --- a/ObjectCollection.py +++ b/ObjectCollection.py @@ -338,7 +338,7 @@ class ObjectCollection(QtCore.QAbstractItemModel): self.app.ui.menuprojectcolor.setEnabled(False) for obj in self.get_selected(): - if type(obj) == FlatCAMGerber: + if type(obj) == FlatCAMGerber or type(obj) == FlatCAMExcellon: self.app.ui.menuprojectcolor.setEnabled(True) if type(obj) != FlatCAMGeometry: diff --git a/README.md b/README.md index f8f3643c..da4e6eb1 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,9 @@ CAD program, and create G-Code for Isolation routing. - fixed some bugs that are visible in Linux regarding the ArgsThread class: on app close we need to quit the QThread running the ArgsThread class and also close the opened Socket - make sure that the fixes above apply when rebooting app for theme change or for language change - fixed and issue that made setting colors for the Gerber file not possible if using a translation +- made possible to set the colors for Excellon objects too +- added to the possible colors the fundamentals: black and white +- in the project context menu for setting colors added the option to set the transparency and also a default option which revert the color to the default value set in the Preferences 17.01.2020 diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index 86974e3f..9f7700d3 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -686,9 +686,25 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.menuproject_brown = self.menuprojectcolor.addAction( QtGui.QIcon(self.app.resource_location + '/brown32.png'), _('Brown')) + self.menuproject_brown = self.menuprojectcolor.addAction( + QtGui.QIcon(self.app.resource_location + '/white32.png'), _('White')) + + self.menuproject_brown = self.menuprojectcolor.addAction( + QtGui.QIcon(self.app.resource_location + '/black32.png'), _('Black')) + + self.menuprojectcolor.addSeparator() + self.menuproject_custom = self.menuprojectcolor.addAction( QtGui.QIcon(self.app.resource_location + '/set_color32.png'), _('Custom')) + self.menuprojectcolor.addSeparator() + + self.menuproject_custom = self.menuprojectcolor.addAction( + QtGui.QIcon(self.app.resource_location + '/set_color32.png'), _('Transparency')) + + self.menuproject_custom = self.menuprojectcolor.addAction( + QtGui.QIcon(self.app.resource_location + '/set_color32.png'), _('Default')) + self.menuproject.addSeparator() self.menuprojectgeneratecnc = self.menuproject.addAction( From 6a616168e10aa22e3d52020a3fc76c5350a77fc4 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 19 Jan 2020 19:49:34 +0200 Subject: [PATCH 042/209] - added the new icons - forgot about them in previous commit --- FlatCAMApp.py | 2 +- share/black32.png | Bin 0 -> 183 bytes share/white32.png | Bin 0 -> 189 bytes 3 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 share/black32.png create mode 100644 share/white32.png diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 9d73c0c8..9ddc1770 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -141,7 +141,7 @@ class App(QtCore.QObject): # ################## Version and VERSION DATE ############################## # ########################################################################## version = 8.992 - version_date = "2020/01/20" + version_date = "2020/01/22" beta = True engine = '3D' diff --git a/share/black32.png b/share/black32.png new file mode 100644 index 0000000000000000000000000000000000000000..ff19e7adb4a0102433789276f5a234b5953bf55c GIT binary patch literal 183 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJI!_nJkO=p;(@zUFDDbdOX7UmB z`v3OFN+#}(#S+KQztEj{crnAhO>?Hbe13R(?ZrML{&ha7$(wqO8+P&8>)+qT?Xb8r z?VU5Di*TykS%)vL`{fxJcn%;V2URwuNpIq8s~3e%N^?`cwQlE=SsC($uXg<|`^mI< Xx{=~J-so-^vAN#G^%I%Em%$x@2O{)2G7*ryQe$?GQv+b?y zg2m~FLPQf9+&67tyz=kwO8abq2A&hh$f1~d#e|f8BP*e|>Y39%R`vC8s0zO|_4Dql cyBo*&*}p+?&N;qgK=&|sy85}Sb4q9e00=}!!T Date: Wed, 22 Jan 2020 01:08:35 +0200 Subject: [PATCH 043/209] - fixed a bug in the bounding box generation --- FlatCAMObj.py | 4 ++++ README.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 37a2d4bc..751063a7 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -1022,6 +1022,10 @@ class FlatCAMGerber(FlatCAMObj, Gerber): def geo_init(geo_obj, app_obj): assert isinstance(geo_obj, FlatCAMGeometry) + + if isinstance(self.solid_geometry, list): + self.solid_geometry = MultiPolygon(self.solid_geometry) + # Bounding box with rounded corners bounding_box = self.solid_geometry.envelope.buffer(float(self.options["bboxmargin"])) if not self.options["bboxrounded"]: # Remove rounded corners diff --git a/README.md b/README.md index da4e6eb1..8c96a14b 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +22.01.2020 + +- fixed a bug in the bounding box generation + 19.01.2020 - fixed some bugs that are visible in Linux regarding the ArgsThread class: on app close we need to quit the QThread running the ArgsThread class and also close the opened Socket From ca87475694829d618bb48a3736c2d92d5e87333d Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 24 Jan 2020 22:12:15 +0200 Subject: [PATCH 044/209] - small changes to the Toolchange manual preprocessor - fix for plotting Excellon objects if the color is changed and then the object is moved - laying the GUI for a new Tool: Punch Gerber Tool which will add holes in the Gerber apertures --- FlatCAMApp.py | 5 + FlatCAMObj.py | 23 +- README.md | 6 + flatcamGUI/FlatCAMGUI.py | 2 + flatcamTools/ToolExtractDrills.py | 5 +- flatcamTools/ToolPunchGerber.py | 373 +++++++++++++++++++++++++++++ flatcamTools/__init__.py | 1 + preprocessors/Toolchange_manual.py | 2 + share/punch16.png | Bin 0 -> 551 bytes share/punch32.png | Bin 0 -> 839 bytes 10 files changed, 409 insertions(+), 8 deletions(-) create mode 100644 flatcamTools/ToolPunchGerber.py create mode 100644 share/punch16.png create mode 100644 share/punch32.png diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 9ddc1770..05cc7136 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -2517,6 +2517,7 @@ class App(QtCore.QObject): self.fiducial_tool = None self.edrills_tool = None self.align_objects_tool = None + self.punch_tool = None # always install tools only after the shell is initialized because the self.inform.emit() depends on shell try: @@ -3150,6 +3151,9 @@ class App(QtCore.QObject): self.qrcode_tool.install(icon=QtGui.QIcon(self.resource_location + '/qrcode32.png'), pos=self.ui.menutool) + self.punch_tool = ToolPunchGerber(self) + self.punch_tool.install(icon=QtGui.QIcon(self.resource_location + '/punch32.png'), pos=self.ui.menutool) + self.transform_tool = ToolTransform(self) self.transform_tool.install(icon=QtGui.QIcon(self.resource_location + '/transform.png'), pos=self.ui.menuoptions, separator=True) @@ -3291,6 +3295,7 @@ class App(QtCore.QObject): self.ui.qrcode_btn.triggered.connect(lambda: self.qrcode_tool.run(toggle=True)) self.ui.copperfill_btn.triggered.connect(lambda: self.copper_thieving_tool.run(toggle=True)) self.ui.fiducials_btn.triggered.connect(lambda: self.fiducial_tool.run(toggle=True)) + self.ui.punch_btn.triggered.connect(lambda: self.punch_tool.run(toggle=True)) def object2editor(self): """ diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 751063a7..8cbc596a 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -1004,15 +1004,21 @@ class FlatCAMGerber(FlatCAMObj, Gerber): def geo_init(geo_obj, app_obj): assert isinstance(geo_obj, FlatCAMGeometry) if isinstance(self.solid_geometry, list): - self.solid_geometry = cascaded_union(self.solid_geometry) + try: + self.solid_geometry = MultiPolygon(self.solid_geometry) + except Exception: + self.solid_geometry = cascaded_union(self.solid_geometry) bounding_box = self.solid_geometry.envelope.buffer(float(self.options["noncoppermargin"])) if not self.options["noncopperrounded"]: bounding_box = bounding_box.envelope non_copper = bounding_box.difference(self.solid_geometry) + + if non_copper is None or non_copper.is_empty: + self.app.inform.emit("[ERROR_NOTCL] %s" % _("Operation could not be done.")) + return "fail" geo_obj.solid_geometry = non_copper - # TODO: Check for None self.app.new_object("geometry", name, geo_init) def on_generatebb_button_click(self, *args): @@ -1024,12 +1030,19 @@ class FlatCAMGerber(FlatCAMObj, Gerber): assert isinstance(geo_obj, FlatCAMGeometry) if isinstance(self.solid_geometry, list): - self.solid_geometry = MultiPolygon(self.solid_geometry) + try: + self.solid_geometry = MultiPolygon(self.solid_geometry) + except Exception: + self.solid_geometry = cascaded_union(self.solid_geometry) # Bounding box with rounded corners bounding_box = self.solid_geometry.envelope.buffer(float(self.options["bboxmargin"])) if not self.options["bboxrounded"]: # Remove rounded corners bounding_box = bounding_box.envelope + + if bounding_box is None or bounding_box.is_empty: + self.app.inform.emit("[ERROR_NOTCL] %s" % _("Operation could not be done.")) + return "fail" geo_obj.solid_geometry = bounding_box self.app.new_object("geometry", name, geo_init) @@ -3641,8 +3654,8 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): if self.options["solid"]: for geo in self.solid_geometry: self.add_shape(shape=geo, - color=self.app.defaults["excellon_plot_line"], - face_color=self.app.defaults["excellon_plot_fill"], + color=self.outline_color, + face_color=self.fill_color, visible=visible, layer=2) else: diff --git a/README.md b/README.md index 8c96a14b..33637b91 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,12 @@ CAD program, and create G-Code for Isolation routing. ================================================= +24.02.2020 + +- small changes to the Toolchange manual preprocessor +- fix for plotting Excellon objects if the color is changed and then the object is moved +- laying the GUI for a new Tool: Punch Gerber Tool which will add holes in the Gerber apertures + 22.01.2020 - fixed a bug in the bounding box generation diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index 9f7700d3..2c921197 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -920,6 +920,8 @@ class FlatCAMGUI(QtWidgets.QMainWindow): QtGui.QIcon(self.app.resource_location + '/fiducials_32.png'), _("Fiducials Tool")) self.cal_btn = self.toolbartools.addAction( QtGui.QIcon(self.app.resource_location + '/calibrate_32.png'), _("Calibration Tool")) + self.punch_btn = self.toolbartools.addAction( + QtGui.QIcon(self.app.resource_location + '/punch32.png'), _("Punch Gerber Tool")) # ######################################################################## # ########################## Excellon Editor Toolbar# #################### diff --git a/flatcamTools/ToolExtractDrills.py b/flatcamTools/ToolExtractDrills.py index d75a61b5..6973aecc 100644 --- a/flatcamTools/ToolExtractDrills.py +++ b/flatcamTools/ToolExtractDrills.py @@ -43,8 +43,7 @@ class ToolExtractDrills(FlatCAMTool): """) self.layout.addWidget(title_label) - self.empty_lb = QtWidgets.QLabel("") - self.layout.addWidget(self.empty_lb) + self.layout.addWidget(QtWidgets.QLabel("")) # ## Grid Layout grid_lay = QtWidgets.QGridLayout() @@ -128,7 +127,7 @@ class ToolExtractDrills(FlatCAMTool): self.method_label = QtWidgets.QLabel('%s' % _("Method")) grid1.addWidget(self.method_label, 2, 0, 1, 2) - # ## Axis + # ## Holes Size self.hole_size_radio = RadioSet( [ {'label': _("Fixed Diameter"), 'value': 'fixed'}, diff --git a/flatcamTools/ToolPunchGerber.py b/flatcamTools/ToolPunchGerber.py new file mode 100644 index 00000000..17fa3a80 --- /dev/null +++ b/flatcamTools/ToolPunchGerber.py @@ -0,0 +1,373 @@ +# ########################################################## +# FlatCAM: 2D Post-processing for Manufacturing # +# File Author: Marius Adrian Stanciu (c) # +# Date: 1/24/2020 # +# MIT Licence # +# ########################################################## + +from PyQt5 import QtGui, QtCore, QtWidgets + +from FlatCAMTool import FlatCAMTool +from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox, \ + OptionalHideInputSection, OptionalInputSection, FCComboBox + +from copy import deepcopy +import logging +from shapely.geometry import Polygon, MultiPolygon, Point + +from reportlab.graphics import renderPDF +from reportlab.pdfgen import canvas +from reportlab.graphics import renderPM +from reportlab.lib.units import inch, mm +from reportlab.lib.pagesizes import landscape, portrait + +from svglib.svglib import svg2rlg +from xml.dom.minidom import parseString as parse_xml_string +from lxml import etree as ET +from io import StringIO + +import gettext +import FlatCAMTranslation as fcTranslate +import builtins + +fcTranslate.apply_language('strings') +if '_' not in builtins.__dict__: + _ = gettext.gettext + +log = logging.getLogger('base') + + +class ToolPunchGerber(FlatCAMTool): + + toolName = _("Punch Gerber") + + def __init__(self, app): + FlatCAMTool.__init__(self, app) + + self.decimals = self.app.decimals + + # Title + title_label = QtWidgets.QLabel("%s" % self.toolName) + title_label.setStyleSheet(""" + QLabel + { + font-size: 16px; + font-weight: bold; + } + """) + self.layout.addWidget(title_label) + + # Punch Drill holes + self.layout.addWidget(QtWidgets.QLabel("")) + + # ## Grid Layout + grid_lay = QtWidgets.QGridLayout() + self.layout.addLayout(grid_lay) + grid_lay.setColumnStretch(0, 1) + grid_lay.setColumnStretch(1, 0) + + # ## Gerber Object + self.gerber_object_combo = QtWidgets.QComboBox() + self.gerber_object_combo.setModel(self.app.collection) + self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) + self.gerber_object_combo.setCurrentIndex(1) + + self.grb_label = QtWidgets.QLabel("%s:" % _("GERBER")) + self.grb_label.setToolTip('%s.' % _("Gerber into which to punch holes")) + + grid_lay.addWidget(self.grb_label, 0, 0, 1, 2) + grid_lay.addWidget(self.gerber_object_combo, 1, 0, 1, 2) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid_lay.addWidget(separator_line, 2, 0, 1, 2) + + # Grid Layout + grid0 = QtWidgets.QGridLayout() + self.layout.addLayout(grid0) + grid0.setColumnStretch(0, 0) + grid0.setColumnStretch(1, 1) + + self.method_label = QtWidgets.QLabel('%s:' % _("Method")) + self.method_label.setToolTip( + _("The punch hole source can be:\n" + "- Excellon -> an Excellon holes center will serve as reference.\n" + "- Fixed Diameter -> will try to use the pads center as reference.\n" + "- Fixed Annular Ring -> will try to use the pads center as reference.\n" + "- Proportional -> will try to use the pads center as reference.\n") + ) + self.method_punch = RadioSet( + [ + {'label': _('Excellon'), 'value': 'exc'}, + {'label': _("Fixed Diameter"), 'value': 'fixed'}, + {'label': _("Fixed Annular Ring"), 'value': 'ring'}, + {'label': _("Proportional"), 'value': 'prop'} + ], + orientation='vertical', + stretch=False) + grid0.addWidget(self.method_label, 0, 0) + grid0.addWidget(self.method_punch, 0, 1) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(separator_line, 1, 0, 1, 2) + + self.exc_label = QtWidgets.QLabel('%s' % _("Excellon")) + self.exc_label.setToolTip( + _("Remove the geometry of Excellon from the Gerber to create the holes in pads.") + ) + + self.exc_combo = QtWidgets.QComboBox() + self.exc_combo.setModel(self.app.collection) + self.exc_combo.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex())) + self.exc_combo.setCurrentIndex(1) + + grid0.addWidget(self.exc_label, 2, 0, 1, 2) + grid0.addWidget(self.exc_combo, 3, 0, 1, 2) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(separator_line, 5, 0, 1, 2) + + # Fixed Dia + self.fixed_label = QtWidgets.QLabel('%s' % _("Fixed Diameter")) + grid0.addWidget(self.fixed_label, 6, 0, 1, 2) + + # Diameter value + self.dia_entry = FCDoubleSpinner() + self.dia_entry.set_precision(self.decimals) + self.dia_entry.set_range(0.0000, 9999.9999) + + self.dia_label = QtWidgets.QLabel('%s:' % _("Value")) + self.dia_label.setToolTip( + _("Fixed hole diameter.") + ) + + grid0.addWidget(self.dia_label, 8, 0) + grid0.addWidget(self.dia_entry, 8, 1) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(separator_line, 9, 0, 1, 2) + + self.ring_frame = QtWidgets.QFrame() + self.ring_frame.setContentsMargins(0, 0, 0, 0) + grid0.addWidget(self.ring_frame, 10, 0, 1, 2) + + self.ring_box = QtWidgets.QVBoxLayout() + self.ring_box.setContentsMargins(0, 0, 0, 0) + self.ring_frame.setLayout(self.ring_box) + + # ## Grid Layout + grid1 = QtWidgets.QGridLayout() + grid1.setColumnStretch(0, 0) + grid1.setColumnStretch(1, 1) + self.ring_box.addLayout(grid1) + + # Annular Ring value + self.ring_label = QtWidgets.QLabel('%s' % _("Fixed Annular Ring")) + self.ring_label.setToolTip( + _("The size of annular ring.\n" + "The copper sliver between the drill hole exterior\n" + "and the margin of the copper pad.") + ) + grid1.addWidget(self.ring_label, 0, 0, 1, 2) + + # Circular Annular Ring Value + self.circular_ring_label = QtWidgets.QLabel('%s:' % _("Circular")) + self.circular_ring_label.setToolTip( + _("The size of annular ring for circular pads.") + ) + + self.circular_ring_entry = FCDoubleSpinner() + self.circular_ring_entry.set_precision(self.decimals) + self.circular_ring_entry.set_range(0.0000, 9999.9999) + + grid1.addWidget(self.circular_ring_label, 1, 0) + grid1.addWidget(self.circular_ring_entry, 1, 1) + + # Oblong Annular Ring Value + self.oblong_ring_label = QtWidgets.QLabel('%s:' % _("Oblong")) + self.oblong_ring_label.setToolTip( + _("The size of annular ring for oblong pads.") + ) + + self.oblong_ring_entry = FCDoubleSpinner() + self.oblong_ring_entry.set_precision(self.decimals) + self.oblong_ring_entry.set_range(0.0000, 9999.9999) + + grid1.addWidget(self.oblong_ring_label, 2, 0) + grid1.addWidget(self.oblong_ring_entry, 2, 1) + + # Square Annular Ring Value + self.square_ring_label = QtWidgets.QLabel('%s:' % _("Square")) + self.square_ring_label.setToolTip( + _("The size of annular ring for square pads.") + ) + + self.square_ring_entry = FCDoubleSpinner() + self.square_ring_entry.set_precision(self.decimals) + self.square_ring_entry.set_range(0.0000, 9999.9999) + + grid1.addWidget(self.square_ring_label, 3, 0) + grid1.addWidget(self.square_ring_entry, 3, 1) + + # Rectangular Annular Ring Value + self.rectangular_ring_label = QtWidgets.QLabel('%s:' % _("Rectangular")) + self.rectangular_ring_label.setToolTip( + _("The size of annular ring for rectangular pads.") + ) + + self.rectangular_ring_entry = FCDoubleSpinner() + self.rectangular_ring_entry.set_precision(self.decimals) + self.rectangular_ring_entry.set_range(0.0000, 9999.9999) + + grid1.addWidget(self.rectangular_ring_label, 4, 0) + grid1.addWidget(self.rectangular_ring_entry, 4, 1) + + # Others Annular Ring Value + self.other_ring_label = QtWidgets.QLabel('%s:' % _("Others")) + self.other_ring_label.setToolTip( + _("The size of annular ring for other pads.") + ) + + self.other_ring_entry = FCDoubleSpinner() + self.other_ring_entry.set_precision(self.decimals) + self.other_ring_entry.set_range(0.0000, 9999.9999) + + grid1.addWidget(self.other_ring_label, 5, 0) + grid1.addWidget(self.other_ring_entry, 5, 1) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(separator_line, 11, 0, 1, 2) + + # Proportional value + self.prop_label = QtWidgets.QLabel('%s' % _("Proportional Diameter")) + grid0.addWidget(self.prop_label, 12, 0, 1, 2) + + # Diameter value + self.factor_entry = FCDoubleSpinner(suffix='%') + self.factor_entry.set_precision(self.decimals) + self.factor_entry.set_range(0.0000, 100.0000) + self.factor_entry.setSingleStep(0.1) + + self.factor_label = QtWidgets.QLabel('%s:' % _("Value")) + self.factor_label.setToolTip( + _("Proportional Diameter.\n" + "The drill diameter will be a fraction of the pad size.") + ) + + grid0.addWidget(self.factor_label, 13, 0) + grid0.addWidget(self.factor_entry, 13, 1) + + separator_line3 = QtWidgets.QFrame() + separator_line3.setFrameShape(QtWidgets.QFrame.HLine) + separator_line3.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(separator_line3, 14, 0, 1, 2) + + # Buttons + self.punch_object_button = QtWidgets.QPushButton(_("Punch Gerber")) + self.punch_object_button.setToolTip( + _("Create a Gerber object from the selected object, within\n" + "the specified box.") + ) + self.punch_object_button.setStyleSheet(""" + QPushButton + { + font-weight: bold; + } + """) + self.layout.addWidget(self.punch_object_button) + + self.layout.addStretch() + + # ## Reset Tool + self.reset_button = QtWidgets.QPushButton(_("Reset Tool")) + self.reset_button.setToolTip( + _("Will reset the tool parameters.") + ) + self.reset_button.setStyleSheet(""" + QPushButton + { + font-weight: bold; + } + """) + self.layout.addWidget(self.reset_button) + + self.units = self.app.defaults['units'] + + # ## Signals + + self.method_punch.activated_custom.connect(self.on_method) + self.reset_button.clicked.connect(self.set_tool_ui) + + def run(self, toggle=True): + self.app.report_usage("ToolPunchGerber()") + + if toggle: + # if the splitter is hidden, display it, else hide it but only if the current widget is the same + if self.app.ui.splitter.sizes()[0] == 0: + self.app.ui.splitter.setSizes([1, 1]) + else: + try: + if self.app.ui.tool_scroll_area.widget().objectName() == self.toolName: + # if tab is populated with the tool but it does not have the focus, focus on it + if not self.app.ui.notebook.currentWidget() is self.app.ui.tool_tab: + # focus on Tool Tab + self.app.ui.notebook.setCurrentWidget(self.app.ui.tool_tab) + else: + self.app.ui.splitter.setSizes([0, 1]) + except AttributeError: + pass + else: + if self.app.ui.splitter.sizes()[0] == 0: + self.app.ui.splitter.setSizes([1, 1]) + + FlatCAMTool.run(self) + + self.set_tool_ui() + + self.app.ui.notebook.setTabText(2, _("Punch Tool")) + + def install(self, icon=None, separator=None, **kwargs): + FlatCAMTool.install(self, icon, separator, shortcut='ALT+H', **kwargs) + + def set_tool_ui(self): + self.reset_fields() + + self.method_punch.set_value('exc') + + def on_method(self, val): + self.exc_label.setEnabled(False) + self.exc_combo.setEnabled(False) + self.fixed_label.setEnabled(False) + self.dia_label.setEnabled(False) + self.dia_entry.setEnabled(False) + self.ring_frame.setEnabled(False) + self.prop_label.setEnabled(False) + self.factor_label.setEnabled(False) + self.factor_entry.setEnabled(False) + + if val == 'exc': + self.exc_label.setEnabled(True) + self.exc_combo.setEnabled(True) + elif val == 'fixed': + self.fixed_label.setEnabled(True) + self.dia_label.setEnabled(True) + self.dia_entry.setEnabled(True) + elif val == 'ring': + self.ring_frame.setEnabled(True) + elif val == 'prop': + self.prop_label.setEnabled(True) + self.factor_label.setEnabled(True) + self.factor_entry.setEnabled(True) + + def reset_fields(self): + self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) + self.exc_combo.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex())) diff --git a/flatcamTools/__init__.py b/flatcamTools/__init__.py index a593e6c4..b503ca38 100644 --- a/flatcamTools/__init__.py +++ b/flatcamTools/__init__.py @@ -38,3 +38,4 @@ from flatcamTools.ToolSolderPaste import SolderPaste from flatcamTools.ToolSub import ToolSub from flatcamTools.ToolTransform import ToolTransform +from flatcamTools.ToolPunchGerber import ToolPunchGerber diff --git a/preprocessors/Toolchange_manual.py b/preprocessors/Toolchange_manual.py index dc7a304d..ef583a7c 100644 --- a/preprocessors/Toolchange_manual.py +++ b/preprocessors/Toolchange_manual.py @@ -119,6 +119,7 @@ M0 G00 Z{z_toolchange} (MSG, Now the tool can be tightened more securely.) M0 +(MSG, Drilling with Tool Dia = {toolC} ||| Total drills for tool T{tool} = {t_drills}) """.format(x_toolchange=self.coordinate_format % (p.coords_decimals, x_toolchange), y_toolchange=self.coordinate_format % (p.coords_decimals, y_toolchange), z_toolchange=self.coordinate_format % (p.coords_decimals, z_toolchange), @@ -139,6 +140,7 @@ M0 G00 Z{z_toolchange} (MSG, Now the tool can be tightened more securely.) M0 +(MSG, Milling with Tool Dia = {toolC} ||| Total drills for tool T{tool} = {t_drills}) """.format( z_toolchange=self.coordinate_format % (p.coords_decimals, z_toolchange), tool=int(p.tool), diff --git a/share/punch16.png b/share/punch16.png new file mode 100644 index 0000000000000000000000000000000000000000..65c2581087206249e9a21e88c4d510da661ad720 GIT binary patch literal 551 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+uenMVO6iP5s=4O z;1OBOz`%C|gc+x5^GO2**-JcqUD=;7O7NPh)T;>`01AEeba4#PIA40tG@QyEbfVu4jt_*nxNsgL}qHzshJ{A-TnB^^{u<3Z#D5xHOh36 zd%v%Sz16@Et*namy>P@9den$^;><;7O&{tELB9d$78~xPD zFLHi+M^D`0OTJzQ_oQ!EZ11vbmJd$8ly_wE!7%CSC*u7~ddfkYQ`Q0lK()j*q9i4; zB-JXpC>2OC7#SED=o%R68kvL`8e5qfTN#^a8yHv_81!^bI)$PkH$NpatrE9}zgM)% yfEpx0HU#IVm6RtIr81P4m+NKbWfvzW7NqLs7p2dBXCnnv#Ng@b=d#Wzp$Py-JjYuA literal 0 HcmV?d00001 diff --git a/share/punch32.png b/share/punch32.png new file mode 100644 index 0000000000000000000000000000000000000000..b3c130ba19b5f210fe256bfd6f5e78bd3cdf4a56 GIT binary patch literal 839 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`F{<@S5^1nR``OlaA7emy0kz^$EhkvU>Rp7 zOJ>3PCdX?EQXMIG*y8$bJ&xbO<~unr?uXxBG1X(1Rxw7}KA$4(ZV2pX ze%F?JH_}{frz+c7PT{!4=l5tDhnp_r^5S<}x~kV_rNyF{g^xE)V!R}D|7hHai>t21 zY3p7{yuhrVBV@khT*fDxqSDL_fgzLMzuWm}t^BMn)@r`p?M0KBxxQF68_mC>{_NV1 zv~;D@X>Ze(J8jv$GU&{v1=efxSXAS_g~S!POndE?Gs~zr-ur=Gg{J-0nL2-0o1dS< zeaCXW=n|(tD{JQZv8)T6zGy>-(q1X1@+;Lx69rX&HU0M7+kfhi(zNbdVmoSot)219 z*=3=Vq^H1Y-c?+8@&Z?@i*4rZ?)G2xC4QAbM(l&KjwtJmJB~cR^8K8c;nT*|g29#> zf20Wg{eSE6<0Zx`j1ofAR;1lCyskXEmUaD}jYctS1wrnQTGtsEd`$9{KTzra^p#lzv6Z2Twt<0_fkC8k%RCefx%nxXX_dG&Xyn-_0X0a1YzWRzD=AMb mN@XZ7FW1Y=%Pvk%EJ)SMFG`>N&PEETh{4m<&t;ucLK6VOOi9ZC literal 0 HcmV?d00001 From 3ac8e960711569b2ed90672dc91bf73822c19f26 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 25 Jan 2020 01:44:44 +0200 Subject: [PATCH 045/209] - fixed bugs in Minimum Distance Tool --- FlatCAMApp.py | 17 ++++++++++------- README.md | 1 + flatcamEditors/FlatCAMExcEditor.py | 2 +- flatcamEditors/FlatCAMGeoEditor.py | 2 +- flatcamEditors/FlatCAMGrbEditor.py | 2 +- flatcamGUI/FlatCAMGUI.py | 2 +- flatcamTools/ToolCalibration.py | 4 ++-- flatcamTools/ToolDistanceMin.py | 16 ++++++++++++++-- 8 files changed, 31 insertions(+), 15 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 05cc7136..e6dc95ea 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -1967,7 +1967,7 @@ class App(QtCore.QObject): self.ui.menueditdelete.triggered.connect(self.on_delete) - self.ui.menueditcopyobject.triggered.connect(self.on_copy_object) + self.ui.menueditcopyobject.triggered.connect(self.on_copy_command) self.ui.menueditconvert_any2geo.triggered.connect(self.convert_any2geo) self.ui.menueditconvert_any2gerber.triggered.connect(self.convert_any2gerber) @@ -2030,7 +2030,7 @@ class App(QtCore.QObject): self.ui.menuprojectgeneratecnc.triggered.connect(lambda: self.generate_cnc_job(self.collection.get_selected())) self.ui.menuprojectviewsource.triggered.connect(self.on_view_source) - self.ui.menuprojectcopy.triggered.connect(self.on_copy_object) + self.ui.menuprojectcopy.triggered.connect(self.on_copy_command) self.ui.menuprojectedit.triggered.connect(self.object2editor) self.ui.menuprojectdelete.triggered.connect(self.on_delete) @@ -2061,7 +2061,7 @@ class App(QtCore.QObject): self.ui.clearplot.triggered.connect(self.clear_plots) self.ui.replot.triggered.connect(self.plot_all) - self.ui.popmenu_copy.triggered.connect(self.on_copy_object) + self.ui.popmenu_copy.triggered.connect(self.on_copy_command) self.ui.popmenu_delete.triggered.connect(self.on_delete) self.ui.popmenu_edit.triggered.connect(self.object2editor) self.ui.popmenu_save.triggered.connect(lambda: self.editor2object()) @@ -3259,7 +3259,7 @@ class App(QtCore.QObject): self.ui.newexc_btn.triggered.connect(self.new_excellon_object) self.ui.editgeo_btn.triggered.connect(self.object2editor) self.ui.update_obj_btn.triggered.connect(lambda: self.editor2object()) - self.ui.copy_btn.triggered.connect(self.on_copy_object) + self.ui.copy_btn.triggered.connect(self.on_copy_command) self.ui.delete_btn.triggered.connect(self.on_delete) self.ui.distance_btn.triggered.connect(lambda: self.distance_tool.run(toggle=True)) @@ -7540,8 +7540,8 @@ class App(QtCore.QObject): self.inform.emit('[success] %s' % _("Done.")) return location - def on_copy_object(self): - self.report_usage("on_copy_object()") + def on_copy_command(self): + self.report_usage("on_copy_command()") def initialize(obj_init, app): obj_init.solid_geometry = deepcopy(obj.solid_geometry) @@ -7559,7 +7559,7 @@ class App(QtCore.QObject): if obj.tools: obj_init.tools = deepcopy(obj.tools) except Exception as e: - log.debug("App.on_copy_object() --> %s" % str(e)) + log.debug("App.on_copy_command() --> %s" % str(e)) try: obj_init.source_file = deepcopy(obj.source_file) @@ -7600,6 +7600,9 @@ class App(QtCore.QObject): except Exception as e: return "Operation failed: %s" % str(e) + def on_paste_command(self): + pass + def on_copy_object2(self, custom_name): def initialize_geometry(obj_init, app): diff --git a/README.md b/README.md index 33637b91..a196be6e 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ CAD program, and create G-Code for Isolation routing. - small changes to the Toolchange manual preprocessor - fix for plotting Excellon objects if the color is changed and then the object is moved - laying the GUI for a new Tool: Punch Gerber Tool which will add holes in the Gerber apertures +- fixed bugs in Minimum Distance Tool 22.01.2020 diff --git a/flatcamEditors/FlatCAMExcEditor.py b/flatcamEditors/FlatCAMExcEditor.py index b77019cd..1e621a9c 100644 --- a/flatcamEditors/FlatCAMExcEditor.py +++ b/flatcamEditors/FlatCAMExcEditor.py @@ -2974,7 +2974,7 @@ class FlatCAMExcEditor(QtCore.QObject): except (TypeError, AttributeError): pass - self.app.ui.popmenu_copy.triggered.connect(self.app.on_copy_object) + self.app.ui.popmenu_copy.triggered.connect(self.app.on_copy_command) self.app.ui.popmenu_delete.triggered.connect(self.app.on_delete) self.app.ui.popmenu_move.triggered.connect(self.app.obj_move) diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index 5b0b95b9..8e12c935 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -3553,7 +3553,7 @@ class FlatCAMGeoEditor(QtCore.QObject): except (TypeError, AttributeError): pass - self.app.ui.popmenu_copy.triggered.connect(self.app.on_copy_object) + self.app.ui.popmenu_copy.triggered.connect(self.app.on_copy_command) self.app.ui.popmenu_delete.triggered.connect(self.app.on_delete) self.app.ui.popmenu_move.triggered.connect(self.app.obj_move) diff --git a/flatcamEditors/FlatCAMGrbEditor.py b/flatcamEditors/FlatCAMGrbEditor.py index 5d1b4ae5..0aba714b 100644 --- a/flatcamEditors/FlatCAMGrbEditor.py +++ b/flatcamEditors/FlatCAMGrbEditor.py @@ -3742,7 +3742,7 @@ class FlatCAMGrbEditor(QtCore.QObject): except (TypeError, AttributeError): pass - self.app.ui.popmenu_copy.triggered.connect(self.app.on_copy_object) + self.app.ui.popmenu_copy.triggered.connect(self.app.on_copy_command) self.app.ui.popmenu_delete.triggered.connect(self.app.on_delete) self.app.ui.popmenu_move.triggered.connect(self.app.obj_move) diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index 2c921197..e7a4bc68 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -2815,7 +2815,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.app.tools_db_tab.on_tool_copy() return - self.app.on_copy_object() + self.app.on_copy_command() # Copy an FlatCAM object if key == QtCore.Qt.Key_D: diff --git a/flatcamTools/ToolCalibration.py b/flatcamTools/ToolCalibration.py index 7e50a3c3..fa533f9e 100644 --- a/flatcamTools/ToolCalibration.py +++ b/flatcamTools/ToolCalibration.py @@ -1275,7 +1275,7 @@ class ToolCalibration(FlatCAMTool): if obj.tools: obj_init.tools = deepcopy(obj.tools) except Exception as ee: - log.debug("App.on_copy_object() --> %s" % str(ee)) + log.debug("ToolCalibration.new_calibrated_object.initialize_geometry() --> %s" % str(ee)) obj_init.scale(xfactor=scalex, yfactor=scaley, point=(origin_x, origin_y)) obj_init.skew(angle_x=skewx, angle_y=skewy, point=(origin_x, origin_y)) @@ -1301,7 +1301,7 @@ class ToolCalibration(FlatCAMTool): if obj.tools: obj_init.tools = deepcopy(obj.tools) except Exception as err: - log.debug("App.on_copy_object() --> %s" % str(err)) + log.debug("ToolCalibration.new_calibrated_object.initialize_gerber() --> %s" % str(err)) obj_init.scale(xfactor=scalex, yfactor=scaley, point=(origin_x, origin_y)) obj_init.skew(angle_x=skewx, angle_y=skewy, point=(origin_x, origin_y)) diff --git a/flatcamTools/ToolDistanceMin.py b/flatcamTools/ToolDistanceMin.py index 9197ac58..08bfc62f 100644 --- a/flatcamTools/ToolDistanceMin.py +++ b/flatcamTools/ToolDistanceMin.py @@ -11,7 +11,8 @@ from flatcamGUI.VisPyVisuals import * from flatcamGUI.GUIElements import FCEntry from shapely.ops import nearest_points -from shapely.geometry import Point +from shapely.geometry import Point, MultiPolygon +from shapely.ops import cascaded_union import math import logging @@ -205,6 +206,17 @@ class DistanceMin(FlatCAMTool): str(len(selected_objs)))) return else: + if isinstance(selected_objs[0].solid_geometry, list): + try: + selected_objs[0].solid_geometry = MultiPolygon(selected_objs[0].solid_geometry) + except Exception: + selected_objs[0].solid_geometry = cascaded_union(selected_objs[0].solid_geometry) + + try: + selected_objs[1].solid_geometry = MultiPolygon(selected_objs[1].solid_geometry) + except Exception: + selected_objs[1].solid_geometry = cascaded_union(selected_objs[1].solid_geometry) + first_pos, last_pos = nearest_points(selected_objs[0].solid_geometry, selected_objs[1].solid_geometry) elif self.app.call_source == 'geo_editor': @@ -278,7 +290,7 @@ class DistanceMin(FlatCAMTool): ) if d != 0: - self.app.inform.emit("{tx1}: {tx2} D(x) = {d_x} | D(y) = {d_y} | (tx3} = {d_z}".format( + self.app.inform.emit("{tx1}: {tx2} D(x) = {d_x} | D(y) = {d_y} | {tx3} = {d_z}".format( tx1=_("MEASURING"), tx2=_("Result"), tx3=_("Distance"), From 0be89a4dfbe588fc372510c8755048266aff6c1f Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 25 Jan 2020 03:19:42 +0200 Subject: [PATCH 046/209] - update in the GUI for the Punch Gerber Tool --- README.md | 1 + flatcamTools/ToolPunchGerber.py | 136 ++++++++++++++++++++++++-------- 2 files changed, 105 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index a196be6e..fa51f802 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ CAD program, and create G-Code for Isolation routing. - fix for plotting Excellon objects if the color is changed and then the object is moved - laying the GUI for a new Tool: Punch Gerber Tool which will add holes in the Gerber apertures - fixed bugs in Minimum Distance Tool +- update in the GUI for the Punch Gerber Tool 22.01.2020 diff --git a/flatcamTools/ToolPunchGerber.py b/flatcamTools/ToolPunchGerber.py index 17fa3a80..9938b14a 100644 --- a/flatcamTools/ToolPunchGerber.py +++ b/flatcamTools/ToolPunchGerber.py @@ -92,10 +92,10 @@ class ToolPunchGerber(FlatCAMTool): self.method_label = QtWidgets.QLabel('%s:' % _("Method")) self.method_label.setToolTip( _("The punch hole source can be:\n" - "- Excellon -> an Excellon holes center will serve as reference.\n" - "- Fixed Diameter -> will try to use the pads center as reference.\n" - "- Fixed Annular Ring -> will try to use the pads center as reference.\n" - "- Proportional -> will try to use the pads center as reference.\n") + "- Excellon Object-> the Excellon object drills center will serve as reference.\n" + "- Fixed Diameter -> will try to use the pads center as reference adding fixed diameter holes.\n" + "- Fixed Annular Ring -> will try to keep a set annular ring.\n" + "- Proportional -> will make a Gerber punch hole having the diameter a percentage of the pad diameter.\n") ) self.method_punch = RadioSet( [ @@ -162,12 +162,6 @@ class ToolPunchGerber(FlatCAMTool): self.ring_box.setContentsMargins(0, 0, 0, 0) self.ring_frame.setLayout(self.ring_box) - # ## Grid Layout - grid1 = QtWidgets.QGridLayout() - grid1.setColumnStretch(0, 0) - grid1.setColumnStretch(1, 1) - self.ring_box.addLayout(grid1) - # Annular Ring value self.ring_label = QtWidgets.QLabel('%s' % _("Fixed Annular Ring")) self.ring_label.setToolTip( @@ -175,11 +169,21 @@ class ToolPunchGerber(FlatCAMTool): "The copper sliver between the drill hole exterior\n" "and the margin of the copper pad.") ) - grid1.addWidget(self.ring_label, 0, 0, 1, 2) + self.ring_box.addWidget(self.ring_label) + + # Select all + self.select_all_cb = FCCheckBox('%s' % _("ALL")) + self.ring_box.addWidget(self.select_all_cb) + + # ## Grid Layout + self.grid1 = QtWidgets.QGridLayout() + self.grid1.setColumnStretch(0, 0) + self.grid1.setColumnStretch(1, 1) + self.ring_box.addLayout(self.grid1) # Circular Annular Ring Value - self.circular_ring_label = QtWidgets.QLabel('%s:' % _("Circular")) - self.circular_ring_label.setToolTip( + self.circular_ring_cb = FCCheckBox('%s:' % _("Circular")) + self.circular_ring_cb.setToolTip( _("The size of annular ring for circular pads.") ) @@ -187,12 +191,14 @@ class ToolPunchGerber(FlatCAMTool): self.circular_ring_entry.set_precision(self.decimals) self.circular_ring_entry.set_range(0.0000, 9999.9999) - grid1.addWidget(self.circular_ring_label, 1, 0) - grid1.addWidget(self.circular_ring_entry, 1, 1) + self.c_ois = OptionalInputSection(self.circular_ring_cb, [self.circular_ring_entry]) + + self.grid1.addWidget(self.circular_ring_cb, 3, 0) + self.grid1.addWidget(self.circular_ring_entry, 3, 1) # Oblong Annular Ring Value - self.oblong_ring_label = QtWidgets.QLabel('%s:' % _("Oblong")) - self.oblong_ring_label.setToolTip( + self.oblong_ring_cb= FCCheckBox('%s:' % _("Oblong")) + self.oblong_ring_cb.setToolTip( _("The size of annular ring for oblong pads.") ) @@ -200,12 +206,14 @@ class ToolPunchGerber(FlatCAMTool): self.oblong_ring_entry.set_precision(self.decimals) self.oblong_ring_entry.set_range(0.0000, 9999.9999) - grid1.addWidget(self.oblong_ring_label, 2, 0) - grid1.addWidget(self.oblong_ring_entry, 2, 1) + self.o_ois = OptionalInputSection(self.oblong_ring_cb, [self.oblong_ring_entry]) + + self.grid1.addWidget(self.oblong_ring_cb, 4, 0) + self.grid1.addWidget(self.oblong_ring_entry, 4, 1) # Square Annular Ring Value - self.square_ring_label = QtWidgets.QLabel('%s:' % _("Square")) - self.square_ring_label.setToolTip( + self.square_ring_cb = FCCheckBox('%s:' % _("Square")) + self.square_ring_cb.setToolTip( _("The size of annular ring for square pads.") ) @@ -213,12 +221,14 @@ class ToolPunchGerber(FlatCAMTool): self.square_ring_entry.set_precision(self.decimals) self.square_ring_entry.set_range(0.0000, 9999.9999) - grid1.addWidget(self.square_ring_label, 3, 0) - grid1.addWidget(self.square_ring_entry, 3, 1) + self.s_ois = OptionalInputSection(self.square_ring_cb, [self.square_ring_entry]) + + self.grid1.addWidget(self.square_ring_cb, 5, 0) + self.grid1.addWidget(self.square_ring_entry, 5, 1) # Rectangular Annular Ring Value - self.rectangular_ring_label = QtWidgets.QLabel('%s:' % _("Rectangular")) - self.rectangular_ring_label.setToolTip( + self.rectangular_ring_cb = FCCheckBox('%s:' % _("Rectangular")) + self.rectangular_ring_cb.setToolTip( _("The size of annular ring for rectangular pads.") ) @@ -226,12 +236,14 @@ class ToolPunchGerber(FlatCAMTool): self.rectangular_ring_entry.set_precision(self.decimals) self.rectangular_ring_entry.set_range(0.0000, 9999.9999) - grid1.addWidget(self.rectangular_ring_label, 4, 0) - grid1.addWidget(self.rectangular_ring_entry, 4, 1) + self.r_ois = OptionalInputSection(self.rectangular_ring_cb, [self.rectangular_ring_entry]) + + self.grid1.addWidget(self.rectangular_ring_cb, 6, 0) + self.grid1.addWidget(self.rectangular_ring_entry, 6, 1) # Others Annular Ring Value - self.other_ring_label = QtWidgets.QLabel('%s:' % _("Others")) - self.other_ring_label.setToolTip( + self.other_ring_cb = FCCheckBox('%s:' % _("Others")) + self.other_ring_cb.setToolTip( _("The size of annular ring for other pads.") ) @@ -239,8 +251,10 @@ class ToolPunchGerber(FlatCAMTool): self.other_ring_entry.set_precision(self.decimals) self.other_ring_entry.set_range(0.0000, 9999.9999) - grid1.addWidget(self.other_ring_label, 5, 0) - grid1.addWidget(self.other_ring_entry, 5, 1) + self.ot_ois = OptionalInputSection(self.other_ring_cb, [self.other_ring_entry]) + + self.grid1.addWidget(self.other_ring_cb, 7, 0) + self.grid1.addWidget(self.other_ring_entry, 7, 1) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) @@ -302,8 +316,12 @@ class ToolPunchGerber(FlatCAMTool): self.units = self.app.defaults['units'] - # ## Signals + self.cb_items = [ + self.grid1.itemAt(w).widget() for w in range(self.grid1.count()) + if isinstance(self.grid1.itemAt(w).widget(), FCCheckBox) + ] + # ## Signals self.method_punch.activated_custom.connect(self.on_method) self.reset_button.clicked.connect(self.set_tool_ui) @@ -341,7 +359,25 @@ class ToolPunchGerber(FlatCAMTool): def set_tool_ui(self): self.reset_fields() + self.ui_connect() self.method_punch.set_value('exc') + self.select_all_cb.set_value(True) + + def on_select_all(self, state): + self.ui_disconnect() + if state: + self.circular_ring_cb.setChecked(True) + self.oblong_ring_cb.setChecked(True) + self.square_ring_cb.setChecked(True) + self.rectangular_ring_cb.setChecked(True) + self.other_ring_cb.setChecked(True) + else: + self.circular_ring_cb.setChecked(False) + self.oblong_ring_cb.setChecked(False) + self.square_ring_cb.setChecked(False) + self.rectangular_ring_cb.setChecked(False) + self.other_ring_cb.setChecked(False) + self.ui_connect() def on_method(self, val): self.exc_label.setEnabled(False) @@ -368,6 +404,42 @@ class ToolPunchGerber(FlatCAMTool): self.factor_label.setEnabled(True) self.factor_entry.setEnabled(True) + def on_ring_cb_toggled(self): + sum_cb = 0 + for it in self.cb_items: + if it.get_value(): + sum_cb += 1 + + self.ui_disconnect() + if sum_cb == 5: + self.select_all_cb.set_value(True) + else: + self.select_all_cb.set_value(False) + self.ui_connect() + + def ui_connect(self): + self.select_all_cb.stateChanged.connect(self.on_select_all) + + for it in self.cb_items: + try: + it.stateChanged.connect(self.on_ring_cb_toggled) + except (AttributeError, TypeError): + pass + + def ui_disconnect(self): + try: + self.select_all_cb.stateChanged.disconnect() + except (AttributeError, TypeError): + pass + + for it in self.cb_items: + try: + it.stateChanged.disconnect() + except (AttributeError, TypeError): + pass + def reset_fields(self): self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.exc_combo.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex())) + self.ui_disconnect() + From 03e1dc54e7194178e60214f4d601fb85407ed488 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 25 Jan 2020 03:49:55 +0200 Subject: [PATCH 047/209] - update in the GUI for the Punch Gerber Tool --- flatcamTools/ToolExtractDrills.py | 15 +-- flatcamTools/ToolPunchGerber.py | 203 +++++++++++++++++++----------- 2 files changed, 135 insertions(+), 83 deletions(-) diff --git a/flatcamTools/ToolExtractDrills.py b/flatcamTools/ToolExtractDrills.py index 6973aecc..7fa1dc98 100644 --- a/flatcamTools/ToolExtractDrills.py +++ b/flatcamTools/ToolExtractDrills.py @@ -125,6 +125,11 @@ class ToolExtractDrills(FlatCAMTool): grid1.setColumnStretch(1, 1) self.method_label = QtWidgets.QLabel('%s' % _("Method")) + self.method_label.setToolTip( + _("The selected method of extracting the drills. Can be:\n" + "- Fixed Diameter -> all holes will have a set size\n" + "- Fixed Annular Ring -> all holes will have a set annular ring\n" + "- Proportional -> each hole size will be a fraction of the pad size")) grid1.addWidget(self.method_label, 2, 0, 1, 2) # ## Holes Size @@ -137,15 +142,7 @@ class ToolExtractDrills(FlatCAMTool): orientation='vertical', stretch=False) - self.hole_size_label = QtWidgets.QLabel('%s:' % _("Hole Size")) - self.hole_size_label.setToolTip( - _("The selected method of extracting the drills. Can be:\n" - "- Fixed Diameter -> all holes will have a set size\n" - "- Fixed Annular Ring -> all holes will have a set annular ring\n" - "- Proportional -> each hole size will be a fraction of the pad size")) - - grid1.addWidget(self.hole_size_label, 3, 0) - grid1.addWidget(self.hole_size_radio, 3, 1) + grid1.addWidget(self.hole_size_radio, 3, 0, 1, 2) # grid_lay1.addWidget(QtWidgets.QLabel('')) diff --git a/flatcamTools/ToolPunchGerber.py b/flatcamTools/ToolPunchGerber.py index 9938b14a..3a1dcf79 100644 --- a/flatcamTools/ToolPunchGerber.py +++ b/flatcamTools/ToolPunchGerber.py @@ -83,13 +83,71 @@ class ToolPunchGerber(FlatCAMTool): separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) grid_lay.addWidget(separator_line, 2, 0, 1, 2) + self.padt_label = QtWidgets.QLabel("%s" % _("Processed Pads Type")) + self.padt_label.setToolTip( + _("The type of pads shape to be processed.\n" + "If the PCB has many SMD pads with rectangular pads,\n" + "disable the Rectangular aperture.") + ) + + grid_lay.addWidget(self.padt_label, 3, 0, 1, 2) + + # Select all + self.select_all_cb = FCCheckBox('%s' % _("ALL")) + grid_lay.addWidget(self.select_all_cb) + + # Circular Aperture Selection + self.circular_cb = FCCheckBox('%s' % _("Circular")) + self.circular_cb.setToolTip( + _("Create drills from circular pads.") + ) + + grid_lay.addWidget(self.circular_cb, 5, 0, 1, 2) + + # Oblong Aperture Selection + self.oblong_cb = FCCheckBox('%s' % _("Oblong")) + self.oblong_cb.setToolTip( + _("Create drills from oblong pads.") + ) + + grid_lay.addWidget(self.oblong_cb, 6, 0, 1, 2) + + # Square Aperture Selection + self.square_cb = FCCheckBox('%s' % _("Square")) + self.square_cb.setToolTip( + _("Create drills from square pads.") + ) + + grid_lay.addWidget(self.square_cb, 7, 0, 1, 2) + + # Rectangular Aperture Selection + self.rectangular_cb = FCCheckBox('%s' % _("Rectangular")) + self.rectangular_cb.setToolTip( + _("Create drills from rectangular pads.") + ) + + grid_lay.addWidget(self.rectangular_cb, 8, 0, 1, 2) + + # Others type of Apertures Selection + self.other_cb = FCCheckBox('%s' % _("Others")) + self.other_cb.setToolTip( + _("Create drills from other types of pad shape.") + ) + + grid_lay.addWidget(self.other_cb, 9, 0, 1, 2) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid_lay.addWidget(separator_line, 10, 0, 1, 2) + # Grid Layout grid0 = QtWidgets.QGridLayout() self.layout.addLayout(grid0) grid0.setColumnStretch(0, 0) grid0.setColumnStretch(1, 1) - self.method_label = QtWidgets.QLabel('%s:' % _("Method")) + self.method_label = QtWidgets.QLabel('%s:' % _("Method")) self.method_label.setToolTip( _("The punch hole source can be:\n" "- Excellon Object-> the Excellon object drills center will serve as reference.\n" @@ -106,13 +164,13 @@ class ToolPunchGerber(FlatCAMTool): ], orientation='vertical', stretch=False) - grid0.addWidget(self.method_label, 0, 0) - grid0.addWidget(self.method_punch, 0, 1) + grid0.addWidget(self.method_label, 0, 0, 1, 2) + grid0.addWidget(self.method_punch, 1, 0, 1, 2) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - grid0.addWidget(separator_line, 1, 0, 1, 2) + grid0.addWidget(separator_line, 2, 0, 1, 2) self.exc_label = QtWidgets.QLabel('%s' % _("Excellon")) self.exc_label.setToolTip( @@ -124,8 +182,8 @@ class ToolPunchGerber(FlatCAMTool): self.exc_combo.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex())) self.exc_combo.setCurrentIndex(1) - grid0.addWidget(self.exc_label, 2, 0, 1, 2) - grid0.addWidget(self.exc_combo, 3, 0, 1, 2) + grid0.addWidget(self.exc_label, 3, 0, 1, 2) + grid0.addWidget(self.exc_combo, 4, 0, 1, 2) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) @@ -171,10 +229,6 @@ class ToolPunchGerber(FlatCAMTool): ) self.ring_box.addWidget(self.ring_label) - # Select all - self.select_all_cb = FCCheckBox('%s' % _("ALL")) - self.ring_box.addWidget(self.select_all_cb) - # ## Grid Layout self.grid1 = QtWidgets.QGridLayout() self.grid1.setColumnStretch(0, 0) @@ -182,8 +236,8 @@ class ToolPunchGerber(FlatCAMTool): self.ring_box.addLayout(self.grid1) # Circular Annular Ring Value - self.circular_ring_cb = FCCheckBox('%s:' % _("Circular")) - self.circular_ring_cb.setToolTip( + self.circular_ring_label = QtWidgets.QLabel('%s:' % _("Circular")) + self.circular_ring_label.setToolTip( _("The size of annular ring for circular pads.") ) @@ -191,14 +245,12 @@ class ToolPunchGerber(FlatCAMTool): self.circular_ring_entry.set_precision(self.decimals) self.circular_ring_entry.set_range(0.0000, 9999.9999) - self.c_ois = OptionalInputSection(self.circular_ring_cb, [self.circular_ring_entry]) - - self.grid1.addWidget(self.circular_ring_cb, 3, 0) + self.grid1.addWidget(self.circular_ring_label, 3, 0) self.grid1.addWidget(self.circular_ring_entry, 3, 1) # Oblong Annular Ring Value - self.oblong_ring_cb= FCCheckBox('%s:' % _("Oblong")) - self.oblong_ring_cb.setToolTip( + self.oblong_ring_label= QtWidgets.QLabel('%s:' % _("Oblong")) + self.oblong_ring_label.setToolTip( _("The size of annular ring for oblong pads.") ) @@ -206,14 +258,12 @@ class ToolPunchGerber(FlatCAMTool): self.oblong_ring_entry.set_precision(self.decimals) self.oblong_ring_entry.set_range(0.0000, 9999.9999) - self.o_ois = OptionalInputSection(self.oblong_ring_cb, [self.oblong_ring_entry]) - - self.grid1.addWidget(self.oblong_ring_cb, 4, 0) + self.grid1.addWidget(self.oblong_ring_label, 4, 0) self.grid1.addWidget(self.oblong_ring_entry, 4, 1) # Square Annular Ring Value - self.square_ring_cb = FCCheckBox('%s:' % _("Square")) - self.square_ring_cb.setToolTip( + self.square_ring_label = QtWidgets.QLabel('%s:' % _("Square")) + self.square_ring_label.setToolTip( _("The size of annular ring for square pads.") ) @@ -221,14 +271,12 @@ class ToolPunchGerber(FlatCAMTool): self.square_ring_entry.set_precision(self.decimals) self.square_ring_entry.set_range(0.0000, 9999.9999) - self.s_ois = OptionalInputSection(self.square_ring_cb, [self.square_ring_entry]) - - self.grid1.addWidget(self.square_ring_cb, 5, 0) + self.grid1.addWidget(self.square_ring_label, 5, 0) self.grid1.addWidget(self.square_ring_entry, 5, 1) # Rectangular Annular Ring Value - self.rectangular_ring_cb = FCCheckBox('%s:' % _("Rectangular")) - self.rectangular_ring_cb.setToolTip( + self.rectangular_ring_label = QtWidgets.QLabel('%s:' % _("Rectangular")) + self.rectangular_ring_label.setToolTip( _("The size of annular ring for rectangular pads.") ) @@ -236,14 +284,12 @@ class ToolPunchGerber(FlatCAMTool): self.rectangular_ring_entry.set_precision(self.decimals) self.rectangular_ring_entry.set_range(0.0000, 9999.9999) - self.r_ois = OptionalInputSection(self.rectangular_ring_cb, [self.rectangular_ring_entry]) - - self.grid1.addWidget(self.rectangular_ring_cb, 6, 0) + self.grid1.addWidget(self.rectangular_ring_label, 6, 0) self.grid1.addWidget(self.rectangular_ring_entry, 6, 1) # Others Annular Ring Value - self.other_ring_cb = FCCheckBox('%s:' % _("Others")) - self.other_ring_cb.setToolTip( + self.other_ring_label = QtWidgets.QLabel('%s:' % _("Others")) + self.other_ring_label.setToolTip( _("The size of annular ring for other pads.") ) @@ -251,9 +297,7 @@ class ToolPunchGerber(FlatCAMTool): self.other_ring_entry.set_precision(self.decimals) self.other_ring_entry.set_range(0.0000, 9999.9999) - self.ot_ois = OptionalInputSection(self.other_ring_cb, [self.other_ring_entry]) - - self.grid1.addWidget(self.other_ring_cb, 7, 0) + self.grid1.addWidget(self.other_ring_label, 7, 0) self.grid1.addWidget(self.other_ring_entry, 7, 1) separator_line = QtWidgets.QFrame() @@ -316,15 +360,51 @@ class ToolPunchGerber(FlatCAMTool): self.units = self.app.defaults['units'] - self.cb_items = [ - self.grid1.itemAt(w).widget() for w in range(self.grid1.count()) - if isinstance(self.grid1.itemAt(w).widget(), FCCheckBox) - ] + # self.cb_items = [ + # self.grid1.itemAt(w).widget() for w in range(self.grid1.count()) + # if isinstance(self.grid1.itemAt(w).widget(), FCCheckBox) + # ] + + self.circular_ring_entry.setEnabled(False) + self.oblong_ring_entry.setEnabled(False) + self.square_ring_entry.setEnabled(False) + self.rectangular_ring_entry.setEnabled(False) + self.other_ring_entry.setEnabled(False) + + self.dia_entry.setDisabled(True) + self.dia_label.setDisabled(True) + self.factor_label.setDisabled(True) + self.factor_entry.setDisabled(True) # ## Signals self.method_punch.activated_custom.connect(self.on_method) self.reset_button.clicked.connect(self.set_tool_ui) + self.circular_cb.stateChanged.connect( + lambda state: + self.circular_ring_entry.setDisabled(False) if state else self.circular_ring_entry.setDisabled(True) + ) + + self.oblong_cb.stateChanged.connect( + lambda state: + self.oblong_ring_entry.setDisabled(False) if state else self.oblong_ring_entry.setDisabled(True) + ) + + self.square_cb.stateChanged.connect( + lambda state: + self.square_ring_entry.setDisabled(False) if state else self.square_ring_entry.setDisabled(True) + ) + + self.rectangular_cb.stateChanged.connect( + lambda state: + self.rectangular_ring_entry.setDisabled(False) if state else self.rectangular_ring_entry.setDisabled(True) + ) + + self.other_cb.stateChanged.connect( + lambda state: + self.other_ring_entry.setDisabled(False) if state else self.other_ring_entry.setDisabled(True) + ) + def run(self, toggle=True): self.app.report_usage("ToolPunchGerber()") @@ -366,17 +446,17 @@ class ToolPunchGerber(FlatCAMTool): def on_select_all(self, state): self.ui_disconnect() if state: - self.circular_ring_cb.setChecked(True) - self.oblong_ring_cb.setChecked(True) - self.square_ring_cb.setChecked(True) - self.rectangular_ring_cb.setChecked(True) - self.other_ring_cb.setChecked(True) + self.circular_cb.setChecked(True) + self.oblong_cb.setChecked(True) + self.square_cb.setChecked(True) + self.rectangular_cb.setChecked(True) + self.other_cb.setChecked(True) else: - self.circular_ring_cb.setChecked(False) - self.oblong_ring_cb.setChecked(False) - self.square_ring_cb.setChecked(False) - self.rectangular_ring_cb.setChecked(False) - self.other_ring_cb.setChecked(False) + self.circular_cb.setChecked(False) + self.oblong_cb.setChecked(False) + self.square_cb.setChecked(False) + self.rectangular_cb.setChecked(False) + self.other_cb.setChecked(False) self.ui_connect() def on_method(self, val): @@ -404,40 +484,15 @@ class ToolPunchGerber(FlatCAMTool): self.factor_label.setEnabled(True) self.factor_entry.setEnabled(True) - def on_ring_cb_toggled(self): - sum_cb = 0 - for it in self.cb_items: - if it.get_value(): - sum_cb += 1 - - self.ui_disconnect() - if sum_cb == 5: - self.select_all_cb.set_value(True) - else: - self.select_all_cb.set_value(False) - self.ui_connect() - def ui_connect(self): self.select_all_cb.stateChanged.connect(self.on_select_all) - for it in self.cb_items: - try: - it.stateChanged.connect(self.on_ring_cb_toggled) - except (AttributeError, TypeError): - pass - def ui_disconnect(self): try: self.select_all_cb.stateChanged.disconnect() except (AttributeError, TypeError): pass - for it in self.cb_items: - try: - it.stateChanged.disconnect() - except (AttributeError, TypeError): - pass - def reset_fields(self): self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.exc_combo.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex())) From 408d46fd820dc02fbd99c18f7b4cd12b5c3fbf09 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 25 Jan 2020 03:57:37 +0200 Subject: [PATCH 048/209] - changed icons for Punch Gerber Tool --- FlatCAMApp.py | 2 +- share/punch16.png | Bin 551 -> 514 bytes share/punch32.png | Bin 839 -> 726 bytes 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index e6dc95ea..a97d67f6 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -141,7 +141,7 @@ class App(QtCore.QObject): # ################## Version and VERSION DATE ############################## # ########################################################################## version = 8.992 - version_date = "2020/01/22" + version_date = "2020/01/30" beta = True engine = '3D' diff --git a/share/punch16.png b/share/punch16.png index 65c2581087206249e9a21e88c4d510da661ad720..679b1b75111f660db5a8fe50dbe37998483e00e1 100644 GIT binary patch delta 339 zcmZ3^(!?^MyIzvfTt7R-^fUtl!v#+l#}JM4trr)19WE3(`mx_a%*7y6>afDJ#2MU8 zz6D&yH|}u1;S|ZSJFw`WLI?kXiyJIv+*~8(cv?qFBv4=v+y6h`+wZ5S&prK9ZpZY~ zEWS_kjyG+}RjoZ<7xcx4rH2 delta 328 zcmZo-S1Xo;c~y z(axd?8h%S;rY4=5De~0akMCUHx;r}Vsau6Kv+A2>UpjTN|8UypySF}n`ne~5e){`+ z@BKaI&S1@yU$^J#;efZ>lwJpISC!1(XJU}eruq9;6aQ4BOc%NL_4{hrTMevaIjL6@z38gBREK<_H%1n2@wy{ii#-_e0!WZ{z ztkYg_CepRvc%#>Z?RPJv-c*|8cl0pF?l3+MeKnOSBDrS1(NCTHBImbv^u!&$4|711kfA Vp3X_9CNIDu@%M^W+2o6ih5&OAk?sHh diff --git a/share/punch32.png b/share/punch32.png index b3c130ba19b5f210fe256bfd6f5e78bd3cdf4a56..5c1efec102e5939138c2dfbb0ad9d93f1e079eaa 100644 GIT binary patch delta 553 zcmX@kc8zsHcfBN|xy+Rb7;fJa{@4wxeXZfMJ z>hV@(-)-L4;N|~2; zy5q|O2CV3LSNA} z!HbG%J2M^4BKvQ|I5VSULjfkxUI59 zZo(xyQS0;Wyr56(`!RJ`tPq!?#Y~b6V%$Rd)4x^3&E| zu8(e*roh0!pjzS@QIe8al4_M)lnSI6j0}tnbPWu3jZ8xf46RH}t&A+R4GgRd4E!u( Z9-(N+%}>cptCYj7!#?Fn++;CkLjWO?4 z*pwmS;%chlvZ#flv#UwUlQnSSVzo{I7Z%f^OAC~AoT`EZmT_jXWEQM%a=fM>)sb?C zEw1m@etH8`eLo-+udF?nVIX0RkP9jE9%d#{YXn!I-T}5ZMoBy z-7AC6Y+7KwHjhO$?psJ)k;}B#ZaK4zisQW>=v8RiU!AG*ceVNXIox+F*NZN3`m?fT zt{=;~!0C%NbSUkWVk*B92oq@r}BwzUhmHtm}>85c%^pd#lDtQ0P zjiv1-NBKO;BW5oYm{5|OC#iNhtW@sxH}Cqy6*k+tciF}r@?M@E;E}Z3XYsey^B5O| zNH6gWm$HdT6cHDFZvOR3wbHM3KNA=j7*tDKBT7;dOH!?pi&B9UgOP!efv$m}u8~QI sp|O>zv6Z2Twt<0_fkC8k%RCefx%nxXX_crN1dw%T Date: Mon, 27 Jan 2020 04:12:46 +0200 Subject: [PATCH 049/209] - in Geometry Editor made sure that on final save, for MultiLineString geometry all the connected lines are merged into one LineString to minimize the number of vertical movements in GCode - more work in Punch Gerber Tool --- README.md | 5 ++ flatcamEditors/FlatCAMGeoEditor.py | 23 +++-- flatcamTools/ToolPunchGerber.py | 137 +++++++++++++++++++++++++++++ 3 files changed, 160 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index fa51f802..5d35f12f 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,11 @@ CAD program, and create G-Code for Isolation routing. ================================================= +27.01.2020 + +- in Geometry Editor made sure that on final save, for MultiLineString geometry all the connected lines are merged into one LineString to minimize the number of vertical movements in GCode +- more work in Punch Gerber Tool + 24.02.2020 - small changes to the Toolchange manual preprocessor diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index 8e12c935..4dbf6389 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -23,7 +23,7 @@ from flatcamParsers.ParseFont import * import FlatCAMApp from shapely.geometry import LineString, LinearRing, MultiLineString, Polygon, MultiPolygon -from shapely.ops import cascaded_union, unary_union +from shapely.ops import cascaded_union, unary_union, linemerge import shapely.affinity as affinity from shapely.geometry.polygon import orient @@ -2498,6 +2498,9 @@ class FCSelect(DrawTool): raise return "" + def clean_up(self): + pass + class FCExplode(FCShapeTool): def __init__(self, draw_app): @@ -3739,8 +3742,7 @@ class FlatCAMGeoEditor(QtCore.QObject): ) ) else: - geo_to_edit = self.flatten(geometry=fcgeometry.solid_geometry, - orient_val=milling_type) + geo_to_edit = self.flatten(geometry=fcgeometry.solid_geometry, orient_val=milling_type) for shape in geo_to_edit: if shape is not None: # TODO: Make flatten never create a None @@ -4396,13 +4398,24 @@ class FlatCAMGeoEditor(QtCore.QObject): fcgeometry.tools[self.multigeo_tool]['solid_geometry'] = [] # for shape in self.shape_buffer: for shape in self.storage.get_objects(): - fcgeometry.tools[self.multigeo_tool]['solid_geometry'].append(shape.geo) + new_geo = shape.geo + + # simplify the MultiLineString + if isinstance(new_geo, MultiLineString): + new_geo = linemerge(new_geo) + + fcgeometry.tools[self.multigeo_tool]['solid_geometry'].append(new_geo) self.multigeo_tool = None fcgeometry.solid_geometry = [] # for shape in self.shape_buffer: for shape in self.storage.get_objects(): - fcgeometry.solid_geometry.append(shape.geo) + new_geo = shape.geo + + # simplify the MultiLineString + if isinstance(new_geo, MultiLineString): + new_geo = linemerge(new_geo) + fcgeometry.solid_geometry.append(new_geo) def update_options(self, obj): if self.paint_tooldia: diff --git a/flatcamTools/ToolPunchGerber.py b/flatcamTools/ToolPunchGerber.py index 3a1dcf79..b52058ef 100644 --- a/flatcamTools/ToolPunchGerber.py +++ b/flatcamTools/ToolPunchGerber.py @@ -379,6 +379,7 @@ class ToolPunchGerber(FlatCAMTool): # ## Signals self.method_punch.activated_custom.connect(self.on_method) self.reset_button.clicked.connect(self.set_tool_ui) + self.punch_object_button.clicked.connect(self.on_generate_object) self.circular_cb.stateChanged.connect( lambda state: @@ -493,6 +494,142 @@ class ToolPunchGerber(FlatCAMTool): except (AttributeError, TypeError): pass + def on_generate_object(self): + + # get the Gerber file who is the source of the punched Gerber + selection_index = self.gerber_object_combo.currentIndex() + model_index = self.app.collection.index(selection_index, 0, self.gerber_object_combo.rootModelIndex()) + + try: + grb_obj = model_index.internalPointer().obj + except Exception: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no Gerber object loaded ...")) + return + + name = grb_obj.options['name'].rpartition('.')[0] + outname = name + "_punched" + + punch_method = self.method_punch.get_value() + + if punch_method == 'exc': + + # get the Excellon file whose geometry will create the punch holes + selection_index = self.exc_combo.currentIndex() + model_index = self.app.collection.index(selection_index, 0, self.exc_combo.rootModelIndex()) + + try: + exc_obj = model_index.internalPointer().obj + except Exception: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no Excellon object loaded ...")) + return + + # this is the punching geometry + exc_solid_geometry = MultiPolygon(exc_obj.solid_geometry) + if isinstance(grb_obj.solid_geometry, list): + grb_solid_geometry = MultiPolygon(grb_obj.solid_geometry) + else: + grb_solid_geometry = grb_obj.solid_geometry + + # create the punched Gerber solid_geometry + punched_solid_geometry = grb_solid_geometry.difference(exc_solid_geometry) + + new_apertures = dict() + new_apertures = deepcopy(grb_obj.apertures) + + holes_apertures = dict() + + for apid, val in new_apertures.items(): + for elem in val['geometry']: + # make it work only for Gerber Flashes who are Points in 'follow' + if 'solid' in elem and isinstance(elem['follow'], Point): + for drill in exc_obj.drills: + clear_apid = exc_obj.tools[drill['tool']]['C'] + exc_poly = drill['point'].buffer(clear_apid / 2.0) + if exc_poly.within(elem['solid']): + + if clear_apid not in holes_apertures or holes_apertures[clear_apid]['type'] != 'C': + holes_apertures[clear_apid] = dict() + holes_apertures[clear_apid]['type'] = 'C' + holes_apertures[clear_apid]['size'] = clear_apid + holes_apertures[clear_apid]['geometry'] = list() + geo_elem = dict() + geo_elem['clear'] = exc_poly + geo_elem['follow'] = exc_poly.centroid + holes_apertures[clear_apid]['geometry'].append(deepcopy(geo_elem)) + + elem['clear'] = exc_poly.centroid + + for apid, val in new_apertures.items(): + for clear_apid, clear_val in holes_apertures.items(): + if round(clear_apid, self.decimals) == round(val['size'], self.decimals): + geo_elem = dict() + + val['geometry'].append(geo_elem) + + def init_func(new_obj, app_obj): + new_obj.options.update(grb_obj.options) + new_obj.options['name'] = outname + new_obj.fill_color = deepcopy(grb_obj.fill_color) + new_obj.outline_color = deepcopy(grb_obj.outline_color) + + new_obj.apertures = deepcopy(new_apertures) + + new_obj.solid_geometry = deepcopy(punched_solid_geometry) + new_obj.source_file = self.app.export_gerber(obj_name=outname, filename=None, + local_use=new_obj, use_thread=False) + + self.app.new_object('gerber', outname, init_func) + elif punch_method == 'fixed': + punch_size = float(self.dia_entry.get_value()) + + punching_geo = list() + for apid in grb_obj.apertures: + if grb_obj.apertures[apid]['type'] == 'C': + if punch_size >= float(grb_obj.apertures[apid]['size']): + self.app.inform.emit('[ERROR_NOTCL] %s' % + _(" Could not generate punched hole Gerber because the punch hole size" + "is bigger than some of the apertures in the Gerber object.")) + return 'fail' + else: + for elem in grb_obj.apertures[apid]['geometry']: + if 'follow' in elem: + if isinstance(elem['follow'], Point): + punching_geo.append(elem['follow'].buffer(punch_size / 2)) + else: + if punch_size >= float(grb_obj.apertures[apid]['width']) or \ + punch_size >= float(grb_obj.apertures[apid]['height']): + self.app.inform.emit('[ERROR_NOTCL] %s' % + _("Could not generate punched hole Gerber because the punch hole size" + "is bigger than some of the apertures in the Gerber object.")) + return 'fail' + else: + for elem in grb_obj.apertures[apid]['geometry']: + if 'follow' in elem: + if isinstance(elem['follow'], Point): + punching_geo.append(elem['follow'].buffer(punch_size / 2)) + + punching_geo = MultiPolygon(punching_geo) + if isinstance(grb_obj.solid_geometry, list): + temp_solid_geometry = MultiPolygon(grb_obj.solid_geometry) + else: + temp_solid_geometry = grb_obj.solid_geometry + punched_solid_geometry = temp_solid_geometry.difference(punching_geo) + + if punched_solid_geometry == temp_solid_geometry: + self.app.inform.emit('[WARNING_NOTCL] %s' % + _("Could not generate punched hole Gerber because the newly created object " + "geometry is the same as the one in the source object geometry...")) + return 'fail' + + def init_func(new_obj, app_obj): + new_obj.solid_geometry = deepcopy(punched_solid_geometry) + + self.app.new_object('gerber', outname, init_func) + elif punch_method == 'ring': + pass + elif punch_method == 'prop': + pass + def reset_fields(self): self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.exc_combo.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex())) From aa7bc125f4827f6e22efeecb2560fe330bda8fcd Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 27 Jan 2020 15:27:34 +0200 Subject: [PATCH 050/209] - the Jump To popup window will now autoselect the LineEdit therefore no more need for an extra click after launching the function --- README.md | 1 + flatcamGUI/GUIElements.py | 6 ++++-- flatcamTools/ToolPunchGerber.py | 3 +-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5d35f12f..555aad09 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ CAD program, and create G-Code for Isolation routing. - in Geometry Editor made sure that on final save, for MultiLineString geometry all the connected lines are merged into one LineString to minimize the number of vertical movements in GCode - more work in Punch Gerber Tool +- the Jump To popup window will now autoselect the LineEdit therefore no more need for an extra click after launching the function 24.02.2020 diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index 05314ffe..8127739a 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -2278,7 +2278,7 @@ class Dialog_box(QtWidgets.QWidget): class DialogBoxRadio(QtWidgets.QDialog): - def __init__(self, title=None, label=None, icon=None, initial_text=None, reference='abs'): + def __init__(self, title=None, label=None, icon=None, initial_text=None, reference='abs', parent=None): """ :param title: string with the window title @@ -2322,8 +2322,10 @@ class DialogBoxRadio(QtWidgets.QDialog): "If the reference is Relative then the Jump will be at the (x,y) distance\n" "from the current mouse location point.") ) - self.lineEdit = EvalEntry() + self.lineEdit = EvalEntry(self) self.lineEdit.setText(str(self.location).replace('(', '').replace(')', '')) + self.lineEdit.selectAll() + self.lineEdit.setFocus() self.form.addRow(self.loc_label, self.lineEdit) self.button_box = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel, diff --git a/flatcamTools/ToolPunchGerber.py b/flatcamTools/ToolPunchGerber.py index b52058ef..16aeabb8 100644 --- a/flatcamTools/ToolPunchGerber.py +++ b/flatcamTools/ToolPunchGerber.py @@ -249,7 +249,7 @@ class ToolPunchGerber(FlatCAMTool): self.grid1.addWidget(self.circular_ring_entry, 3, 1) # Oblong Annular Ring Value - self.oblong_ring_label= QtWidgets.QLabel('%s:' % _("Oblong")) + self.oblong_ring_label = QtWidgets.QLabel('%s:' % _("Oblong")) self.oblong_ring_label.setToolTip( _("The size of annular ring for oblong pads.") ) @@ -634,4 +634,3 @@ class ToolPunchGerber(FlatCAMTool): self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.exc_combo.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex())) self.ui_disconnect() - From fbf0b8606ed41d25197ba952a0f01e7e4fd173bd Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 27 Jan 2020 17:20:06 +0200 Subject: [PATCH 051/209] - made some structural changes in Properties Tool --- README.md | 1 + flatcamGUI/GUIElements.py | 34 ++++++ flatcamTools/ToolProperties.py | 206 ++++++++++++++++----------------- 3 files changed, 137 insertions(+), 104 deletions(-) diff --git a/README.md b/README.md index 555aad09..caf14993 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ CAD program, and create G-Code for Isolation routing. - in Geometry Editor made sure that on final save, for MultiLineString geometry all the connected lines are merged into one LineString to minimize the number of vertical movements in GCode - more work in Punch Gerber Tool - the Jump To popup window will now autoselect the LineEdit therefore no more need for an extra click after launching the function +- made some structural changes in Properties Tool 24.02.2020 diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index 8127739a..a136e16c 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -152,6 +152,40 @@ class RadioSet(QtWidgets.QWidget): # wgt.show() +class FCTree(QtWidgets.QTreeWidget): + + def __init__(self, parent=None, columns=2, header_hidden=True): + super(FCTree, self).__init__(parent) + + self.setColumnCount(columns) + self.setHeaderHidden(header_hidden) + self.header().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents) + self.setSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Expanding) + + def addParent(self, parent, title, expanded=False, color=None, font=None): + item = QtWidgets.QTreeWidgetItem(parent, [title]) + item.setChildIndicatorPolicy(QtWidgets.QTreeWidgetItem.ShowIndicator) + item.setExpanded(expanded) + if color is not None: + # item.setTextColor(0, color) # PyQt4 + item.setForeground(0, QtGui.QBrush(color)) + if font is not None: + item.setFont(0, font) + return item + + def addChild(self, parent, title, column1=None, font=None, font_items=None): + item = QtWidgets.QTreeWidgetItem(parent) + item.setText(0, str(title[0])) + if column1 is not None: + item.setText(1, str(title[1])) + if font and font_items: + try: + for fi in font_items: + item.setFont(fi, font) + except TypeError: + item.setFont(font_items, font) + + class LengthEntry(QtWidgets.QLineEdit): def __init__(self, output_units='IN', decimals=None, parent=None): super(LengthEntry, self).__init__(parent) diff --git a/flatcamTools/ToolProperties.py b/flatcamTools/ToolProperties.py index 03dfb755..6429982e 100644 --- a/flatcamTools/ToolProperties.py +++ b/flatcamTools/ToolProperties.py @@ -7,6 +7,7 @@ from PyQt5 import QtGui, QtCore, QtWidgets from FlatCAMTool import FlatCAMTool +from flatcamGUI.GUIElements import FCTree from shapely.geometry import MultiPolygon, Polygon from shapely.ops import cascaded_union @@ -64,11 +65,7 @@ class Properties(FlatCAMTool): self.properties_box.addLayout(self.vlay) - self.treeWidget = QtWidgets.QTreeWidget() - self.treeWidget.setColumnCount(2) - self.treeWidget.setHeaderHidden(True) - self.treeWidget.header().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents) - self.treeWidget.setSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Expanding) + self.treeWidget = FCTree(columns=2) self.vlay.addWidget(self.treeWidget) self.vlay.setStretch(0, 0) @@ -146,36 +143,50 @@ class Properties(FlatCAMTool): font.setBold(True) # main Items categories - obj_type = self.addParent(parent, _('TYPE'), expanded=True, color=QtGui.QColor("#000000"), font=font) - obj_name = self.addParent(parent, _('NAME'), expanded=True, color=QtGui.QColor("#000000"), font=font) - dims = self.addParent(parent, _('Dimensions'), expanded=True, color=QtGui.QColor("#000000"), font=font) - units = self.addParent(parent, _('Units'), expanded=True, color=QtGui.QColor("#000000"), font=font) - options = self.addParent(parent, _('Options'), color=QtGui.QColor("#000000"), font=font) + obj_type = self.treeWidget.addParent(parent, _('TYPE'), expanded=True, color=QtGui.QColor("#000000"), font=font) + obj_name = self.treeWidget.addParent(parent, _('NAME'), expanded=True, color=QtGui.QColor("#000000"), font=font) + dims = self.treeWidget.addParent( + parent, _('Dimensions'), expanded=True, color=QtGui.QColor("#000000"), font=font) + units = self.treeWidget.addParent(parent, _('Units'), expanded=True, color=QtGui.QColor("#000000"), font=font) + options = self.treeWidget.addParent(parent, _('Options'), color=QtGui.QColor("#000000"), font=font) if obj.kind.lower() == 'gerber': - apertures = self.addParent(parent, _('Apertures'), expanded=True, color=QtGui.QColor("#000000"), font=font) + apertures = self.treeWidget.addParent( + parent, _('Apertures'), expanded=True, color=QtGui.QColor("#000000"), font=font) else: - tools = self.addParent(parent, _('Tools'), expanded=True, color=QtGui.QColor("#000000"), font=font) + tools = self.treeWidget.addParent( + parent, _('Tools'), expanded=True, color=QtGui.QColor("#000000"), font=font) if obj.kind.lower() == 'excellon': - drills = self.addParent(parent, _('Drills'), expanded=True, color=QtGui.QColor("#000000"), font=font) - slots = self.addParent(parent, _('Slots'), expanded=True, color=QtGui.QColor("#000000"), font=font) + drills = self.treeWidget.addParent( + parent, _('Drills'), expanded=True, color=QtGui.QColor("#000000"), font=font) + slots = self.treeWidget.addParent( + parent, _('Slots'), expanded=True, color=QtGui.QColor("#000000"), font=font) if obj.kind.lower() == 'cncjob': - others = self.addParent(parent, _('Others'), expanded=True, color=QtGui.QColor("#000000"), font=font) + others = self.treeWidget.addParent( + parent, _('Others'), expanded=True, color=QtGui.QColor("#000000"), font=font) - separator = self.addParent(parent, '') + separator = self.treeWidget.addParent(parent, '') - self.addChild(obj_type, ['%s:' % _('Object Type'), ('%s' % (obj.kind.upper()))], True, font=font, font_items=1) + self.treeWidget.addChild( + obj_type, ['%s:' % _('Object Type'), ('%s' % (obj.kind.upper()))], True, font=font, font_items=1) try: - self.addChild(obj_type, - ['%s:' % _('Geo Type'), - ('%s' % ({False: _("Single-Geo"), True: _("Multi-Geo")}[obj.multigeo]))], - True) + self.treeWidget.addChild(obj_type, + [ + '%s:' % _('Geo Type'), + ('%s' % ( + { + False: _("Single-Geo"), + True: _("Multi-Geo") + }[obj.multigeo]) + ) + ], + True) except Exception as e: log.debug("Properties.addItems() --> %s" % str(e)) - self.addChild(obj_name, [obj.options['name']]) + self.treeWidget.addChild(obj_name, [obj.options['name']]) def job_thread(obj_prop): proc = self.app.proc_container.new(_("Calculating dimensions ... Please wait.")) @@ -193,8 +204,8 @@ class Properties(FlatCAMTool): length = abs(xmax - xmin) width = abs(ymax - ymin) - except Exception as e: - log.debug("PropertiesTool.addItems() -> calculate dimensions --> %s" % str(e)) + except Exception as ee: + log.debug("PropertiesTool.addItems() -> calculate dimensions --> %s" % str(ee)) # calculate box area if self.app.defaults['units'].lower() == 'mm': @@ -278,24 +289,27 @@ class Properties(FlatCAMTool): except TypeError: copper_area += geo_tools.area copper_area /= 100 - except Exception as e: - log.debug("Properties.addItems() --> %s" % str(e)) + except Exception as err: + log.debug("Properties.addItems() --> %s" % str(err)) area_chull = 0.0 if obj_prop.kind.lower() != 'cncjob': # calculate and add convex hull area if geo: - 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(obj_prop.solid_geometry) - env_obj = env_obj.convex_hull - else: - env_obj = cascaded_union(obj_prop.solid_geometry) - env_obj = env_obj.convex_hull + if isinstance(geo, list) and geo[0] is not None: + 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(geo) + env_obj = env_obj.convex_hull + else: + env_obj = cascaded_union(geo) + env_obj = env_obj.convex_hull - area_chull = env_obj.area + area_chull = env_obj.area + else: + area_chull = 0 else: try: area_chull = [] @@ -303,9 +317,9 @@ class Properties(FlatCAMTool): area_el = cascaded_union(obj_prop.tools[tool_k]['solid_geometry']).convex_hull area_chull.append(area_el.area) area_chull = max(area_chull) - except Exception as e: + except Exception as er: area_chull = None - log.debug("Properties.addItems() --> %s" % str(e)) + log.debug("Properties.addItems() --> %s" % str(er)) if self.app.defaults['units'].lower() == 'mm' and area_chull: area_chull = area_chull / 100 @@ -319,7 +333,7 @@ class Properties(FlatCAMTool): # Units items f_unit = {'in': _('Inch'), 'mm': _('Metric')}[str(self.app.defaults['units'].lower())] - self.addChild(units, ['FlatCAM units:', f_unit], True) + self.treeWidget.addChild(units, ['FlatCAM units:', f_unit], True) o_unit = { 'in': _('Inch'), @@ -327,13 +341,13 @@ class Properties(FlatCAMTool): 'inch': _('Inch'), 'metric': _('Metric') }[str(obj.units_found.lower())] - self.addChild(units, ['Object units:', o_unit], True) + self.treeWidget.addChild(units, ['Object units:', o_unit], True) # Options items for option in obj.options: if option is 'name': continue - self.addChild(options, [str(option), str(obj.options[option])], True) + self.treeWidget.addChild(options, [str(option), str(obj.options[option])], True) # Items that depend on the object type if obj.kind.lower() == 'gerber': @@ -363,15 +377,17 @@ class Properties(FlatCAMTool): temp_ap['Follow_Geo'] = '%s LineStrings' % str(follow_nr) temp_ap['Clear_Geo'] = '%s Polygons' % str(clear_nr) - apid = self.addParent(apertures, str(ap), expanded=False, color=QtGui.QColor("#000000"), font=font) + apid = self.treeWidget.addParent( + apertures, str(ap), expanded=False, color=QtGui.QColor("#000000"), font=font) for key in temp_ap: - self.addChild(apid, [str(key), str(temp_ap[key])], True) + self.treeWidget.addChild(apid, [str(key), str(temp_ap[key])], True) elif obj.kind.lower() == 'excellon': tot_drill_cnt = 0 tot_slot_cnt = 0 for tool, value in obj.tools.items(): - toolid = self.addParent(tools, str(tool), expanded=False, color=QtGui.QColor("#000000"), font=font) + toolid = self.treeWidget.addParent( + tools, str(tool), expanded=False, color=QtGui.QColor("#000000"), font=font) drill_cnt = 0 # variable to store the nr of drills per tool slot_cnt = 0 # variable to store the nr of slots per tool @@ -390,7 +406,7 @@ class Properties(FlatCAMTool): tot_slot_cnt += slot_cnt - self.addChild( + self.treeWidget.addChild( toolid, [ _('Diameter'), @@ -398,52 +414,55 @@ class Properties(FlatCAMTool): ], True ) - self.addChild(toolid, [_('Drills number'), str(drill_cnt)], True) - self.addChild(toolid, [_('Slots number'), str(slot_cnt)], True) + self.treeWidget.addChild(toolid, [_('Drills number'), str(drill_cnt)], True) + self.treeWidget.addChild(toolid, [_('Slots number'), str(slot_cnt)], True) - self.addChild(drills, [_('Drills total number:'), str(tot_drill_cnt)], True) - self.addChild(slots, [_('Slots total number:'), str(tot_slot_cnt)], True) + self.treeWidget.addChild(drills, [_('Drills total number:'), str(tot_drill_cnt)], True) + self.treeWidget.addChild(slots, [_('Slots total number:'), str(tot_slot_cnt)], True) elif obj.kind.lower() == 'geometry': for tool, value in obj.tools.items(): - geo_tool = self.addParent(tools, str(tool), expanded=True, color=QtGui.QColor("#000000"), font=font) + geo_tool = self.treeWidget.addParent( + tools, str(tool), expanded=True, color=QtGui.QColor("#000000"), font=font) for k, v in value.items(): if k == 'solid_geometry': printed_value = _('Present') if v else _('None') - self.addChild(geo_tool, [str(k), printed_value], True) + self.treeWidget.addChild(geo_tool, [str(k), printed_value], True) elif k == 'data': - tool_data = self.addParent(geo_tool, str(k).capitalize(), - color=QtGui.QColor("#000000"), font=font) + tool_data = self.treeWidget.addParent( + geo_tool, str(k).capitalize(), color=QtGui.QColor("#000000"), font=font) for data_k, data_v in v.items(): - self.addChild(tool_data, [str(data_k), str(data_v)], True) + self.treeWidget.addChild(tool_data, [str(data_k), str(data_v)], True) else: - self.addChild(geo_tool, [str(k), str(v)], True) + self.treeWidget.addChild(geo_tool, [str(k), str(v)], True) elif obj.kind.lower() == 'cncjob': # for cncjob objects made from gerber or geometry for tool, value in obj.cnc_tools.items(): - geo_tool = self.addParent(tools, str(tool), expanded=True, color=QtGui.QColor("#000000"), font=font) + geo_tool = self.treeWidget.addParent( + tools, str(tool), expanded=True, color=QtGui.QColor("#000000"), font=font) for k, v in value.items(): if k == 'solid_geometry': printed_value = _('Present') if v else _('None') - self.addChild(geo_tool, [_("Solid Geometry"), printed_value], True) + self.treeWidget.addChild(geo_tool, [_("Solid Geometry"), printed_value], True) elif k == 'gcode': printed_value = _('Present') if v != '' else _('None') - self.addChild(geo_tool, [_("GCode Text"), printed_value], True) + self.treeWidget.addChild(geo_tool, [_("GCode Text"), printed_value], True) elif k == 'gcode_parsed': printed_value = _('Present') if v else _('None') - self.addChild(geo_tool, [_("GCode Geometry"), printed_value], True) + self.treeWidget.addChild(geo_tool, [_("GCode Geometry"), printed_value], True) elif k == 'data': - tool_data = self.addParent(geo_tool, _("Data"), color=QtGui.QColor("#000000"), font=font) + tool_data = self.treeWidget.addParent( + geo_tool, _("Data"), color=QtGui.QColor("#000000"), font=font) for data_k, data_v in v.items(): - self.addChild(tool_data, [str(data_k).capitalize(), str(data_v)], True) + self.treeWidget.addChild(tool_data, [str(data_k).capitalize(), str(data_v)], True) else: - self.addChild(geo_tool, [str(k), str(v)], True) + self.treeWidget.addChild(geo_tool, [str(k), str(v)], True) # for cncjob objects made from excellon for tool_dia, value in obj.exc_cnc_tools.items(): - exc_tool = self.addParent( + exc_tool = self.treeWidget.addParent( tools, str(value['tool']), expanded=False, color=QtGui.QColor("#000000"), font=font ) - self.addChild( + self.treeWidget.addChild( exc_tool, [ _('Diameter'), @@ -454,15 +473,15 @@ class Properties(FlatCAMTool): for k, v in value.items(): if k == 'solid_geometry': printed_value = _('Present') if v else _('None') - self.addChild(exc_tool, [_("Solid Geometry"), printed_value], True) + self.treeWidget.addChild(exc_tool, [_("Solid Geometry"), printed_value], True) elif k == 'nr_drills': - self.addChild(exc_tool, [_("Drills number"), str(v)], True) + self.treeWidget.addChild(exc_tool, [_("Drills number"), str(v)], True) elif k == 'nr_slots': - self.addChild(exc_tool, [_("Slots number"), str(v)], True) + self.treeWidget.addChild(exc_tool, [_("Slots number"), str(v)], True) else: pass - self.addChild( + self.treeWidget.addChild( exc_tool, [ _("Depth of Cut"), @@ -474,7 +493,7 @@ class Properties(FlatCAMTool): ], True ) - self.addChild( + self.treeWidget.addChild( exc_tool, [ _("Clearance Height"), @@ -486,7 +505,7 @@ class Properties(FlatCAMTool): ], True ) - self.addChild( + self.treeWidget.addChild( exc_tool, [ _("Feedrate"), @@ -506,14 +525,14 @@ class Properties(FlatCAMTool): r_time *= 60 units_lbl = 'sec' r_time = math.ceil(float(r_time)) - self.addChild( + self.treeWidget.addChild( others, [ '%s:' % _('Routing time'), '%.*f %s' % (self.decimals, r_time, units_lbl)], True ) - self.addChild( + self.treeWidget.addChild( others, [ '%s:' % _('Travelled distance'), @@ -522,40 +541,17 @@ class Properties(FlatCAMTool): True ) - self.addChild(separator, ['']) - - def addParent(self, parent, title, expanded=False, color=None, font=None): - item = QtWidgets.QTreeWidgetItem(parent, [title]) - item.setChildIndicatorPolicy(QtWidgets.QTreeWidgetItem.ShowIndicator) - item.setExpanded(expanded) - if color is not None: - # item.setTextColor(0, color) # PyQt4 - item.setForeground(0, QtGui.QBrush(color)) - if font is not None: - item.setFont(0, font) - return item - - def addChild(self, parent, title, column1=None, font=None, font_items=None): - item = QtWidgets.QTreeWidgetItem(parent) - item.setText(0, str(title[0])) - if column1 is not None: - item.setText(1, str(title[1])) - if font and font_items: - try: - for fi in font_items: - item.setFont(fi, font) - except TypeError: - item.setFont(font_items, font) + self.treeWidget.addChild(separator, ['']) def show_area_chull(self, area, length, width, chull_area, copper_area, location): # add dimensions - self.addChild( + self.treeWidget.addChild( location, ['%s:' % _('Length'), '%.*f %s' % (self.decimals, length, self.app.defaults['units'].lower())], True ) - self.addChild( + self.treeWidget.addChild( location, ['%s:' % _('Width'), '%.*f %s' % (self.decimals, width, self.app.defaults['units'].lower())], True @@ -563,16 +559,16 @@ class Properties(FlatCAMTool): # add box area if self.app.defaults['units'].lower() == 'mm': - self.addChild(location, ['%s:' % _('Box Area'), '%.*f %s' % (self.decimals, area, 'cm2')], True) - self.addChild( + self.treeWidget.addChild(location, ['%s:' % _('Box Area'), '%.*f %s' % (self.decimals, area, 'cm2')], True) + self.treeWidget.addChild( location, ['%s:' % _('Convex_Hull Area'), '%.*f %s' % (self.decimals, chull_area, 'cm2')], True ) else: - self.addChild(location, ['%s:' % _('Box Area'), '%.*f %s' % (self.decimals, area, 'in2')], True) - self.addChild( + self.treeWidget.addChild(location, ['%s:' % _('Box Area'), '%.*f %s' % (self.decimals, area, 'in2')], True) + self.treeWidget.addChild( location, ['%s:' % _('Convex_Hull Area'), '%.*f %s' % (self.decimals, chull_area, 'in2')], True @@ -580,8 +576,10 @@ class Properties(FlatCAMTool): # add copper area if self.app.defaults['units'].lower() == 'mm': - self.addChild(location, ['%s:' % _('Copper Area'), '%.*f %s' % (self.decimals, copper_area, 'cm2')], True) + self.treeWidget.addChild( + location, ['%s:' % _('Copper Area'), '%.*f %s' % (self.decimals, copper_area, 'cm2')], True) else: - self.addChild(location, ['%s:' % _('Copper Area'), '%.*f %s' % (self.decimals, copper_area, 'in2')], True) + self.treeWidget.addChild( + location, ['%s:' % _('Copper Area'), '%.*f %s' % (self.decimals, copper_area, 'in2')], True) # end of file From 64ff4fb9fd13c13318124a7a9e87a128ce7a889c Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 27 Jan 2020 17:43:00 +0200 Subject: [PATCH 052/209] - started t omake some changs in Geometry Editor --- FlatCAMApp.py | 5 ++--- README.md | 1 + flatcamEditors/FlatCAMGeoEditor.py | 36 +++++++++++++++++++++--------- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index a97d67f6..db4c9ad1 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -3314,8 +3314,7 @@ class App(QtCore.QObject): isinstance(edited_object, FlatCAMExcellon): pass else: - self.inform.emit('[WARNING_NOTCL] %s' % - _("Select a Geometry, Gerber or Excellon Object to edit.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Select a Geometry, Gerber or Excellon Object to edit.")) return if isinstance(edited_object, FlatCAMGeometry): @@ -3323,7 +3322,7 @@ class App(QtCore.QObject): self.geo_editor.toolbar_old_state = True if self.ui.geo_edit_toolbar.isVisible() else False # we set the notebook to hidden - self.ui.splitter.setSizes([0, 1]) + # self.ui.splitter.setSizes([0, 1]) if edited_object.multigeo is True: sel_rows = [item.row() for item in edited_object.ui.geo_tools_table.selectedItems()] diff --git a/README.md b/README.md index caf14993..ed74004a 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ CAD program, and create G-Code for Isolation routing. - more work in Punch Gerber Tool - the Jump To popup window will now autoselect the LineEdit therefore no more need for an extra click after launching the function - made some structural changes in Properties Tool +- started t omake some changs in Geometry Editor 24.02.2020 diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index 4dbf6389..340c61bc 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -3341,10 +3341,25 @@ class FlatCAMGeoEditor(QtCore.QObject): self.delete_selected() self.replot() + def set_ui(self): + # updated units + self.units = self.app.defaults['units'].upper() + self.decimals = self.app.decimals + + def build_ui(self, first_run=None): + + # try: + # # if connected, disconnect the signal from the slot on item_changed as it creates issues + # self.apertures_table.itemChanged.disconnect() + # except (TypeError, AttributeError): + # pass + pass + def activate(self): # adjust the status of the menu entries related to the editor self.app.ui.menueditedit.setDisabled(True) self.app.ui.menueditok.setDisabled(False) + # adjust the visibility of some of the canvas context menu self.app.ui.popmenu_edit.setVisible(False) self.app.ui.popmenu_save.setVisible(True) @@ -3382,9 +3397,9 @@ class FlatCAMGeoEditor(QtCore.QObject): self.app.ui.g_editor_cmenu.menuAction().setVisible(True) # prevent the user to change anything in the Selected Tab while the Geo Editor is active - sel_tab_widget_list = self.app.ui.selected_tab.findChildren(QtWidgets.QWidget) - for w in sel_tab_widget_list: - w.setEnabled(False) + # sel_tab_widget_list = self.app.ui.selected_tab.findChildren(QtWidgets.QWidget) + # for w in sel_tab_widget_list: + # w.setEnabled(False) # Tell the App that the editor is active self.editor_active = True @@ -3399,6 +3414,7 @@ class FlatCAMGeoEditor(QtCore.QObject): # adjust the status of the menu entries related to the editor self.app.ui.menueditedit.setDisabled(False) self.app.ui.menueditok.setDisabled(True) + # adjust the visibility of some of the canvas context menu self.app.ui.popmenu_edit.setVisible(True) self.app.ui.popmenu_save.setVisible(False) @@ -3456,13 +3472,13 @@ class FlatCAMGeoEditor(QtCore.QObject): self.app.ui.e_editor_cmenu.menuAction().setVisible(False) self.app.ui.g_editor_cmenu.menuAction().setVisible(False) - try: - # re-enable all the widgets in the Selected Tab that were disabled after entering in Edit Geometry Mode - sel_tab_widget_list = self.app.ui.selected_tab.findChildren(QtWidgets.QWidget) - for w in sel_tab_widget_list: - w.setEnabled(True) - except Exception as e: - log.debug("FlatCAMGeoEditor.deactivate() --> %s" % str(e)) + # try: + # # re-enable all the widgets in the Selected Tab that were disabled after entering in Edit Geometry Mode + # sel_tab_widget_list = self.app.ui.selected_tab.findChildren(QtWidgets.QWidget) + # for w in sel_tab_widget_list: + # w.setEnabled(True) + # except Exception as e: + # log.debug("FlatCAMGeoEditor.deactivate() --> %s" % str(e)) # Show original geometry if self.fcgeometry: From fd0438842d9a234806a6df66a7da1da8bacc1d63 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Tue, 28 Jan 2020 03:59:15 +0200 Subject: [PATCH 053/209] - finished adding in Geometry Editor a TreeWidget with the geometry shapes found in the edited object --- FlatCAMApp.py | 11 +- README.md | 3 +- camlib.py | 2 +- flatcamEditors/FlatCAMGeoEditor.py | 202 ++++++++++++++++++++++++++--- flatcamGUI/GUIElements.py | 5 +- 5 files changed, 202 insertions(+), 21 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index db4c9ad1..1a228bf9 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -3444,6 +3444,13 @@ class App(QtCore.QObject): self.inform.emit('[WARNING] %s' % _("Object empty after edit.")) log.debug("App.editor2object() --> Geometry --> %s" % str(e)) + + # restore GUI to the Selected TAB + # Remove anything else in the GUI + self.ui.tool_scroll_area.takeWidget() + # Switch notebook to Selected page + self.ui.notebook.setCurrentWidget(self.ui.selected_tab) + elif isinstance(edited_obj, FlatCAMGerber): obj_type = "Gerber" if cleanup is None: @@ -3494,8 +3501,7 @@ class App(QtCore.QObject): _("Select a Gerber, Geometry or Excellon Object to update.")) return - self.inform.emit('[selected] %s %s' % - (obj_type, _("is updated, returning to App..."))) + self.inform.emit('[selected] %s %s' % (obj_type, _("is updated, returning to App..."))) elif response == bt_no: # clean the Tools Tab self.ui.tool_scroll_area.takeWidget() @@ -3514,6 +3520,7 @@ class App(QtCore.QObject): _("Select a Gerber, Geometry or Excellon Object to update.")) return edited_obj.set_ui(edited_obj.ui_type(decimals=self.decimals)) + edited_obj.build_ui() self.ui.notebook.setCurrentWidget(self.ui.selected_tab) elif response == bt_cancel: return diff --git a/README.md b/README.md index ed74004a..e3dfaf54 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,8 @@ CAD program, and create G-Code for Isolation routing. - more work in Punch Gerber Tool - the Jump To popup window will now autoselect the LineEdit therefore no more need for an extra click after launching the function - made some structural changes in Properties Tool -- started t omake some changs in Geometry Editor +- started to make some changes in Geometry Editor +- finished adding in Geometry Editor a TreeWidget with the geometry shapes found in the edited object 24.02.2020 diff --git a/camlib.py b/camlib.py index 063478b1..d234dc90 100644 --- a/camlib.py +++ b/camlib.py @@ -5972,7 +5972,7 @@ class FlatCAMRTreeStorage(FlatCAMRTree): self.objects.append(obj) idx = len(self.objects) - 1 - # Note: Shapely objects are not hashable any more, althought + # Note: Shapely objects are not hashable any more, although # there seem to be plans to re-introduce the feature in # version 2.0. For now, we will index using the object's id, # but it's important to remember that shapely geometry is diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index 340c61bc..7a5a63c6 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -18,7 +18,7 @@ from camlib import distance, arc, three_point_circle, Geometry, FlatCAMRTreeStor from FlatCAMTool import FlatCAMTool from flatcamGUI.ObjectUI import RadioSet from flatcamGUI.GUIElements import OptionalInputSection, FCCheckBox, FCEntry, FCComboBox, FCTextAreaRich, \ - FCTable, FCDoubleSpinner, FCButton, EvalEntry2, FCInputDialog + FCTable, FCDoubleSpinner, FCButton, EvalEntry2, FCInputDialog, FCTree from flatcamParsers.ParseFont import * import FlatCAMApp @@ -2494,8 +2494,29 @@ class FCSelect(DrawTool): self.draw_app.selected = [] self.draw_app.selected.append(obj_to_add) except Exception as e: - log.error("[ERROR] Something went bad. %s" % str(e)) - raise + log.error("[ERROR] FlatCAMGeoEditor.FCSelect.click_release() -> Something went bad. %s" % str(e)) + + # if selection is done on canvas update the Tree in Selected Tab with the selection + try: + self.draw_app.tw.itemSelectionChanged.disconnect(self.draw_app.on_tree_selection_change) + except (AttributeError, TypeError): + pass + + self.draw_app.tw.selectionModel().clearSelection() + for sel_shape in self.draw_app.selected: + iterator = QtWidgets.QTreeWidgetItemIterator(self.draw_app.tw) + while iterator.value(): + item = iterator.value() + try: + if int(item.text(1)) == id(sel_shape): + item.setSelected(True) + except ValueError: + pass + + iterator += 1 + + self.draw_app.tw.itemSelectionChanged.connect(self.draw_app.on_tree_selection_change) + return "" def clean_up(self): @@ -3126,6 +3147,9 @@ class FCTransform(FCShapeTool): # ############################################### class FlatCAMGeoEditor(QtCore.QObject): + # will emit the name of the object that was just selected + item_selected = QtCore.pyqtSignal(str) + transform_complete = QtCore.pyqtSignal() draw_shape_idx = -1 @@ -3140,6 +3164,47 @@ class FlatCAMGeoEditor(QtCore.QObject): self.canvas = app.plotcanvas self.decimals = app.decimals + self.geo_edit_widget = QtWidgets.QWidget() + # ## Box for custom widgets + # This gets populated in offspring implementations. + layout = QtWidgets.QVBoxLayout() + self.geo_edit_widget.setLayout(layout) + + # add a frame and inside add a vertical box layout. Inside this vbox layout I add all the Drills widgets + # this way I can hide/show the frame + self.geo_frame = QtWidgets.QFrame() + self.geo_frame.setContentsMargins(0, 0, 0, 0) + layout.addWidget(self.geo_frame) + self.tools_box = QtWidgets.QVBoxLayout() + self.tools_box.setContentsMargins(0, 0, 0, 0) + self.geo_frame.setLayout(self.tools_box) + + # ## Page Title box (spacing between children) + self.title_box = QtWidgets.QHBoxLayout() + self.tools_box.addLayout(self.title_box) + + # ## Page Title icon + pixmap = QtGui.QPixmap(self.app.resource_location + '/flatcam_icon32.png') + self.icon = QtWidgets.QLabel() + self.icon.setPixmap(pixmap) + self.title_box.addWidget(self.icon, stretch=0) + + # ## Title label + self.title_label = QtWidgets.QLabel("%s" % _('Geometry Editor')) + self.title_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) + self.title_box.addWidget(self.title_label, stretch=1) + self.title_box.addWidget(QtWidgets.QLabel('')) + + self.tw = FCTree(extended_sel=True) + self.tools_box.addWidget(self.tw) + + self.geo_font = QtGui.QFont() + self.geo_font.setBold(True) + + parent = self.tw.invisibleRootItem() + self.geo_parent = self.tw.addParent( + parent, _('Geometry Elements'), expanded=True, color=QtGui.QColor("#000000"), font=self.geo_font) + # ## Toolbar events and properties self.tools = { "select": {"button": self.app.ui.geo_select_btn, @@ -3346,6 +3411,13 @@ class FlatCAMGeoEditor(QtCore.QObject): self.units = self.app.defaults['units'].upper() self.decimals = self.app.decimals + # Remove anything else in the GUI Selected Tab + self.app.ui.selected_scroll_area.takeWidget() + # Put ourselves in the GUI Selected Tab + self.app.ui.selected_scroll_area.setWidget(self.geo_edit_widget) + # Switch notebook to Selected page + self.app.ui.notebook.setCurrentWidget(self.app.ui.selected_tab) + def build_ui(self, first_run=None): # try: @@ -3353,8 +3425,56 @@ class FlatCAMGeoEditor(QtCore.QObject): # self.apertures_table.itemChanged.disconnect() # except (TypeError, AttributeError): # pass + + iterator = QtWidgets.QTreeWidgetItemIterator(self.geo_parent) + to_delete = list() + while iterator.value(): + item = iterator.value() + to_delete.append(item) + iterator += 1 + for it in to_delete: + self.geo_parent.removeChild(it) + + for elem in self.storage.get_objects(): + geo_type = type(elem.geo) + title = None + if geo_type is LinearRing: + title = _('ID Ring') + elif geo_type is LineString: + title = _('ID Line') + elif geo_type is Polygon: + title = _('ID Polygon') + elif geo_type is MultiLineString: + title = _('ID Multi-Line') + elif geo_type is MultiPolygon: + title = _('ID Multi-Polygon') + + self.tw.addChild( + self.geo_parent, + [ + '%s:' % title, + str(id(elem)) + ], + True, + font=self.geo_font, + font_items=1 + ) + + def on_geo_elem_selected(self): pass + def on_tree_selection_change(self): + self.selected = list() + selected_tree_items = self.tw.selectedItems() + for sel in selected_tree_items: + for obj_shape in self.storage.get_objects(): + try: + if id(obj_shape) == int(sel.text(1)): + self.selected.append(obj_shape) + except ValueError: + pass + self.replot() + def activate(self): # adjust the status of the menu entries related to the editor self.app.ui.menueditedit.setDisabled(True) @@ -3403,12 +3523,22 @@ class FlatCAMGeoEditor(QtCore.QObject): # Tell the App that the editor is active self.editor_active = True + + self.item_selected.connect(self.on_geo_elem_selected) + + # ## GUI Events + self.tw.itemSelectionChanged.connect(self.on_tree_selection_change) + # self.tw.keyPressed.connect(self.app.ui.keyPressEvent) + # self.tw.customContextMenuRequested.connect(self.on_menu_request) + + self.geo_frame.show() + log.debug("Finished activating the Geometry Editor...") def deactivate(self): try: QtGui.QGuiApplication.restoreOverrideCursor() - except Exception as e: + except Exception: pass # adjust the status of the menu entries related to the editor @@ -3472,6 +3602,19 @@ class FlatCAMGeoEditor(QtCore.QObject): self.app.ui.e_editor_cmenu.menuAction().setVisible(False) self.app.ui.g_editor_cmenu.menuAction().setVisible(False) + try: + self.item_selected.disconnect() + except (AttributeError, TypeError): + pass + + try: + # ## GUI Events + self.tw.itemSelectionChanged.disconnect(self.on_tree_selection_change) + # self.tw.keyPressed.connect(self.app.ui.keyPressEvent) + # self.tw.customContextMenuRequested.connect(self.on_menu_request) + except (AttributeError, TypeError): + pass + # try: # # re-enable all the widgets in the Selected Tab that were disabled after entering in Edit Geometry Mode # sel_tab_widget_list = self.app.ui.selected_tab.findChildren(QtWidgets.QWidget) @@ -3483,6 +3626,10 @@ class FlatCAMGeoEditor(QtCore.QObject): # Show original geometry if self.fcgeometry: self.fcgeometry.visible = True + + # hide the UI + self.geo_frame.hide() + log.debug("Finished deactivating the Geometry Editor...") def connect_canvas_event_handlers(self): @@ -3684,6 +3831,7 @@ class FlatCAMGeoEditor(QtCore.QObject): self.utility.append(shape) else: self.storage.insert(shape) # TODO: Check performance + self.build_ui() def delete_utility_geometry(self): # for_deletion = [shape for shape in self.shape_buffer if shape.utility] @@ -3724,6 +3872,8 @@ class FlatCAMGeoEditor(QtCore.QObject): self.deactivate() self.activate() + self.set_ui() + # Hide original geometry self.fcgeometry = fcgeometry fcgeometry.visible = False @@ -3845,7 +3995,7 @@ class FlatCAMGeoEditor(QtCore.QObject): self.pos = self.canvas.translate_coords(event_pos) - if self.app.grid_status() == True: + if self.app.grid_status(): self.pos = self.app.geo_editor.snap(self.pos[0], self.pos[1]) else: self.pos = (self.pos[0], self.pos[1]) @@ -3925,7 +4075,7 @@ class FlatCAMGeoEditor(QtCore.QObject): return # ### Snap coordinates ### - if self.app.grid_status() == True: + if self.app.grid_status(): x, y = self.snap(x, y) # Update cursor @@ -3939,7 +4089,7 @@ class FlatCAMGeoEditor(QtCore.QObject): # update the position label in the infobar since the APP mouse event handlers are disconnected self.app.ui.position_label.setText("    X: %.4f   " - "Y: %.4f" % (x, y)) + "Y: %.4f" % (x, y)) if self.pos is None: self.pos = (0, 0) @@ -3948,7 +4098,7 @@ class FlatCAMGeoEditor(QtCore.QObject): # update the reference position label in the infobar since the APP mouse event handlers are disconnected self.app.ui.rel_position_label.setText("Dx: %.4f   Dy: " - "%.4f    " % (dx, dy)) + "%.4f    " % (dx, dy)) if event.button == 1 and event_is_dragging and isinstance(self.active_tool, FCEraser): pass @@ -3961,8 +4111,8 @@ class FlatCAMGeoEditor(QtCore.QObject): self.app.delete_selection_shape() if dx < 0: self.app.draw_moving_selection_shape((self.pos[0], self.pos[1]), (x, y), - color=self.app.defaults["global_alt_sel_line"], - face_color=self.app.defaults['global_alt_sel_fill']) + color=self.app.defaults["global_alt_sel_line"], + face_color=self.app.defaults['global_alt_sel_fill']) self.app.selection_type = False else: self.app.draw_moving_selection_shape((self.pos[0], self.pos[1]), (x, y)) @@ -4011,19 +4161,18 @@ class FlatCAMGeoEditor(QtCore.QObject): # self.app.inform.emit(msg) self.replot() elif event.button == right_button: # right click - if self.app.ui.popMenu.mouse_is_panning == False: + if self.app.ui.popMenu.mouse_is_panning is False: if self.in_action is False: try: QtGui.QGuiApplication.restoreOverrideCursor() - except Exception as e: + except Exception: pass if self.active_tool.complete is False and not isinstance(self.active_tool, FCSelect): self.active_tool.complete = True self.in_action = False self.delete_utility_geometry() - self.app.inform.emit('[success] %s' % - _("Done.")) + self.app.inform.emit('[success] %s' % _("Done.")) self.select_tool('select') else: self.app.cursor = QtGui.QCursor() @@ -4037,8 +4186,7 @@ class FlatCAMGeoEditor(QtCore.QObject): self.active_tool.make() if self.active_tool.complete: self.on_shape_complete() - self.app.inform.emit('[success] %s' % - _("Done.")) + self.app.inform.emit('[success] %s' % _("Done.")) self.select_tool(self.active_tool.name) except Exception as e: log.warning("FLatCAMGeoEditor.on_geo_click_release() --> Error: %s" % str(e)) @@ -4082,6 +4230,27 @@ class FlatCAMGeoEditor(QtCore.QObject): self.selected = [] self.selected = sel_objects_list + # if selection is done on canvas update the Tree in Selected Tab with the selection + try: + self.tw.itemSelectionChanged.disconnect(self.on_tree_selection_change) + except (AttributeError, TypeError): + pass + + self.tw.selectionModel().clearSelection() + for sel_shape in self.selected: + iterator = QtWidgets.QTreeWidgetItemIterator(self.tw) + while iterator.value(): + item = iterator.value() + try: + if int(item.text(1)) == id(sel_shape): + item.setSelected(True) + except ValueError: + pass + + iterator += 1 + + self.tw.itemSelectionChanged.connect(self.on_tree_selection_change) + self.replot() def draw_utility_geometry(self, geo): @@ -4131,6 +4300,7 @@ class FlatCAMGeoEditor(QtCore.QObject): for shape in tempref: self.delete_shape(shape) self.selected = [] + self.build_ui() def delete_shape(self, shape): diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index a136e16c..b9f17d9e 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -154,7 +154,7 @@ class RadioSet(QtWidgets.QWidget): class FCTree(QtWidgets.QTreeWidget): - def __init__(self, parent=None, columns=2, header_hidden=True): + def __init__(self, parent=None, columns=2, header_hidden=True, extended_sel=False): super(FCTree, self).__init__(parent) self.setColumnCount(columns) @@ -162,6 +162,9 @@ class FCTree(QtWidgets.QTreeWidget): self.header().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents) self.setSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Expanding) + if extended_sel: + self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) + def addParent(self, parent, title, expanded=False, color=None, font=None): item = QtWidgets.QTreeWidgetItem(parent, [title]) item.setChildIndicatorPolicy(QtWidgets.QTreeWidgetItem.ShowIndicator) From 85afb7cdb2a1173653431c87e5f941dd652e5a55 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Tue, 28 Jan 2020 17:34:21 +0200 Subject: [PATCH 054/209] - some changes in Excellon Editor --- FlatCAMApp.py | 16 ++++++---------- README.md | 4 ++++ flatcamTools/ToolPunchGerber.py | 11 ----------- 3 files changed, 10 insertions(+), 21 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 1a228bf9..a0c2bd30 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -3448,8 +3448,6 @@ class App(QtCore.QObject): # restore GUI to the Selected TAB # Remove anything else in the GUI self.ui.tool_scroll_area.takeWidget() - # Switch notebook to Selected page - self.ui.notebook.setCurrentWidget(self.ui.selected_tab) elif isinstance(edited_obj, FlatCAMGerber): obj_type = "Gerber" @@ -3473,14 +3471,12 @@ class App(QtCore.QObject): # restore GUI to the Selected TAB # Remove anything else in the GUI self.ui.selected_scroll_area.takeWidget() - # Switch notebook to Selected page - self.ui.notebook.setCurrentWidget(self.ui.selected_tab) elif isinstance(edited_obj, FlatCAMExcellon): obj_type = "Excellon" if cleanup is None: self.exc_editor.update_fcexcellon(edited_obj) - self.exc_editor.update_options(edited_obj) + # self.exc_editor.update_options(edited_obj) self.exc_editor.deactivate() @@ -3493,8 +3489,6 @@ class App(QtCore.QObject): # restore GUI to the Selected TAB # Remove anything else in the GUI self.ui.tool_scroll_area.takeWidget() - # Switch notebook to Selected page - self.ui.notebook.setCurrentWidget(self.ui.selected_tab) else: self.inform.emit('[WARNING_NOTCL] %s' % @@ -3519,11 +3513,13 @@ class App(QtCore.QObject): self.inform.emit('[WARNING_NOTCL] %s' % _("Select a Gerber, Geometry or Excellon Object to update.")) return - edited_obj.set_ui(edited_obj.ui_type(decimals=self.decimals)) - edited_obj.build_ui() - self.ui.notebook.setCurrentWidget(self.ui.selected_tab) elif response == bt_cancel: return + + edited_obj.set_ui(edited_obj.ui_type(decimals=self.decimals)) + edited_obj.build_ui() + # Switch notebook to Selected page + self.ui.notebook.setCurrentWidget(self.ui.selected_tab) else: if isinstance(edited_obj, FlatCAMGeometry): self.geo_editor.deactivate() diff --git a/README.md b/README.md index e3dfaf54..fc0ebf77 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +28.01.2020 + +- some changes in Excellon Editor + 27.01.2020 - in Geometry Editor made sure that on final save, for MultiLineString geometry all the connected lines are merged into one LineString to minimize the number of vertical movements in GCode diff --git a/flatcamTools/ToolPunchGerber.py b/flatcamTools/ToolPunchGerber.py index 16aeabb8..807bbe0c 100644 --- a/flatcamTools/ToolPunchGerber.py +++ b/flatcamTools/ToolPunchGerber.py @@ -15,17 +15,6 @@ from copy import deepcopy import logging from shapely.geometry import Polygon, MultiPolygon, Point -from reportlab.graphics import renderPDF -from reportlab.pdfgen import canvas -from reportlab.graphics import renderPM -from reportlab.lib.units import inch, mm -from reportlab.lib.pagesizes import landscape, portrait - -from svglib.svglib import svg2rlg -from xml.dom.minidom import parseString as parse_xml_string -from lxml import etree as ET -from io import StringIO - import gettext import FlatCAMTranslation as fcTranslate import builtins From d7f7d79d6a522cf5ccac196dea07c4bdcf82bc84 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 29 Jan 2020 03:14:46 +0200 Subject: [PATCH 055/209] - changes in how the Editor exit is handled - small fix in some pywin32 imports --- FlatCAMApp.py | 62 +++++++++++++++++------------- ObjectCollection.py | 53 +++++++++++++++++++++++++ README.md | 5 +++ flatcamEditors/FlatCAMExcEditor.py | 2 + 4 files changed, 96 insertions(+), 26 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index a0c2bd30..c84bfc4b 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -279,7 +279,7 @@ class App(QtCore.QObject): # Folder for user settings. if sys.platform == 'win32': - from win32com.shell import shell, shellcon + from win32comext.shell import shell, shellcon if platform.architecture()[0] == '32bit': App.log.debug("Win32!") else: @@ -3430,9 +3430,14 @@ class App(QtCore.QObject): obj_type = "Geometry" if cleanup is None: self.geo_editor.update_fcgeometry(edited_obj) - self.geo_editor.update_options(edited_obj) + # self.geo_editor.update_options(edited_obj) + self.geo_editor.deactivate() + # restore GUI to the Selected TAB + # Remove anything else in the GUI + self.ui.tool_scroll_area.takeWidget() + # update the geo object options so it is including the bounding box values try: xmin, ymin, xmax, ymax = edited_obj.bounds() @@ -3441,13 +3446,11 @@ class App(QtCore.QObject): edited_obj.options['xmax'] = xmax edited_obj.options['ymax'] = ymax except AttributeError as e: - self.inform.emit('[WARNING] %s' % - _("Object empty after edit.")) + self.inform.emit('[WARNING] %s' % _("Object empty after edit.")) log.debug("App.editor2object() --> Geometry --> %s" % str(e)) - # restore GUI to the Selected TAB - # Remove anything else in the GUI - self.ui.tool_scroll_area.takeWidget() + edited_obj.build_ui() + self.inform.emit('[success] %s' % _("Editor exited. Editor content saved.")) elif isinstance(edited_obj, FlatCAMGerber): obj_type = "Gerber" @@ -3468,6 +3471,8 @@ class App(QtCore.QObject): # a single Polygon, therefore we pass this pass + self.inform.emit('[success] %s' % _("Editor exited. Editor content saved.")) + # restore GUI to the Selected TAB # Remove anything else in the GUI self.ui.selected_scroll_area.takeWidget() @@ -3480,16 +3485,16 @@ class App(QtCore.QObject): self.exc_editor.deactivate() - # delete the old object (the source object) if it was an empty one - if len(edited_obj.drills) == 0 and len(edited_obj.slots) == 0: - old_name = edited_obj.options['name'] - self.collection.set_active(old_name) - self.collection.delete_active() - # restore GUI to the Selected TAB # Remove anything else in the GUI self.ui.tool_scroll_area.takeWidget() + # delete the old object (the source object) if it was an empty one + if len(edited_obj.drills) == 0 and len(edited_obj.slots) == 0: + old_name = edited_obj.options['name'] + self.collection.delete_by_name(name=old_name) + self.inform.emit('[success] %s' % _("Editor exited. Editor content saved.")) + else: self.inform.emit('[WARNING_NOTCL] %s' % _("Select a Gerber, Geometry or Excellon Object to update.")) @@ -3502,13 +3507,17 @@ class App(QtCore.QObject): self.ui.tool_scroll_area.setWidget(QtWidgets.QWidget()) self.ui.notebook.setTabText(2, "Tool") + self.inform.emit('[WARNING_NOTCL] %s' % _("Editor exited. Editor content was not saved.")) + if isinstance(edited_obj, FlatCAMGeometry): self.geo_editor.deactivate() + edited_obj.build_ui() elif isinstance(edited_obj, FlatCAMGerber): self.grb_editor.deactivate_grb_editor() + edited_obj.build_ui() elif isinstance(edited_obj, FlatCAMExcellon): self.exc_editor.deactivate() - # set focus on the project tab + edited_obj.build_ui() else: self.inform.emit('[WARNING_NOTCL] %s' % _("Select a Gerber, Geometry or Excellon Object to update.")) @@ -3516,8 +3525,8 @@ class App(QtCore.QObject): elif response == bt_cancel: return - edited_obj.set_ui(edited_obj.ui_type(decimals=self.decimals)) - edited_obj.build_ui() + # edited_obj.set_ui(edited_obj.ui_type(decimals=self.decimals)) + # edited_obj.build_ui() # Switch notebook to Selected page self.ui.notebook.setCurrentWidget(self.ui.selected_tab) else: @@ -3926,7 +3935,8 @@ class App(QtCore.QObject): json.dump(self.defaults, f_f_def_s, default=to_dict, indent=2, sort_keys=True) f_f_def_s.close() - # and then make the factory_defaults.FlatConfig file read_only so it can't be modified after creation. + # and then make the factory_defaults.FlatConfig file read_only + # so it can't be modified after creation. os.chmod(fact_def_file_path, S_IREAD | S_IRGRP | S_IROTH) except Exception as e: log.debug("App.load_defaults() -> deleting old factory defaults file -> %s" % str(e)) @@ -10362,7 +10372,7 @@ class App(QtCore.QObject): filename, _f = QtWidgets.QFileDialog.getSaveFileName( caption=_("Save Project As ..."), directory=('{l_save}/{proj}_{date}').format(l_save=str(self.get_last_save_folder()), date=self.date, - proj=_("Project")), + proj=_("Project")), filter=filter_ ) except TypeError: @@ -10416,8 +10426,8 @@ class App(QtCore.QObject): filename, _f = QtWidgets.QFileDialog.getSaveFileName( caption=_("Save Object as PDF ..."), directory=('{l_save}/{obj_name}_{date}').format(l_save=str(self.get_last_save_folder()), - obj_name=obj_name, - date=self.date), + obj_name=obj_name, + date=self.date), filter=filter_ ) except TypeError: @@ -11204,7 +11214,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]%s' % _(' Open Gerber failed. Probable not a Gerber file.')) + self.inform.emit('[ERROR_NOTCL]%s' % _(' Open Gerber failed. Probable not a Gerber file.')) return 'fail' # Register recent file @@ -11218,11 +11228,11 @@ class App(QtCore.QObject): Opens an Excellon file, parses it and creates a new object for it in the program. Thread-safe. - :param outname: Name of the resulting object. None causes the - name to be that of the file. - :param filename: Excellon file filename - :type filename: str - :return: None + :param outname: Name of the resulting object. None causes the name to be that of the file. + :param filename: Excellon file filename + :type filename: str + :param plot: boolean, to plot or not the resulting object + :return: None """ App.log.debug("open_excellon()") diff --git a/ObjectCollection.py b/ObjectCollection.py index bf7c07dd..799d163c 100644 --- a/ObjectCollection.py +++ b/ObjectCollection.py @@ -645,6 +645,59 @@ class ObjectCollection(QtCore.QAbstractItemModel): if not self.get_list(): self.app.ui.splitter.setSizes([0, 1]) + def delete_by_name(self, name, select_project=True): + obj = self.get_by_name(name=name) + item = obj.item + group = self.group_items[obj.kind] + + group_index = self.index(group.row(), 0, QtCore.QModelIndex()) + item_index = self.index(item.row(), 0, group_index) + + deleted = item_index.internalPointer() + group = deleted.parent_item + + # some objects add a Tab on creation, close it here + for idx in range(self.app.ui.plot_tab_area.count()): + if self.app.ui.plot_tab_area.widget(idx).objectName() == deleted.obj.options['name']: + self.app.ui.plot_tab_area.removeTab(idx) + break + + # update the SHELL auto-completer model data + name = deleted.obj.options['name'] + try: + self.app.myKeywords.remove(name) + self.app.shell._edit.set_model_data(self.app.myKeywords) + # this is not needed any more because now the code editor is created on demand + # self.app.ui.code_editor.set_model_data(self.app.myKeywords) + except Exception as e: + log.debug( + "delete_active() --> Could not remove the old object name from auto-completer model list. %s" % str(e)) + + self.app.object_status_changed.emit(deleted.obj, 'delete', name) + + # ############ OBJECT DELETION FROM MODEL STARTS HERE #################### + self.beginRemoveRows(self.index(group.row(), 0, QtCore.QModelIndex()), deleted.row(), deleted.row()) + group.remove_child(deleted) + # after deletion of object store the current list of objects into the self.app.all_objects_list + self.app.all_objects_list = self.get_list() + self.endRemoveRows() + # ############ OBJECT DELETION FROM MODEL STOPS HERE #################### + + if self.app.is_legacy is False: + self.app.plotcanvas.redraw() + + if select_project: + # always go to the Project Tab after object deletion as it may be done with a shortcut key + self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab) + + self.app.should_we_save = True + + # decide if to show or hide the Notebook side of the screen + if self.app.defaults["global_project_autohide"] is True: + # hide the notebook if there are no objects in the collection + if not self.get_list(): + self.app.ui.splitter.setSizes([0, 1]) + def delete_all(self): FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.delete_all()") diff --git a/README.md b/README.md index fc0ebf77..dcd8d762 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,11 @@ CAD program, and create G-Code for Isolation routing. ================================================= +29.01.2020 + +- changes in how the Editor exit is handled +- small fix in some pywin32 imports + 28.01.2020 - some changes in Excellon Editor diff --git a/flatcamEditors/FlatCAMExcEditor.py b/flatcamEditors/FlatCAMExcEditor.py index 1e621a9c..e2dc8bdb 100644 --- a/flatcamEditors/FlatCAMExcEditor.py +++ b/flatcamEditors/FlatCAMExcEditor.py @@ -3270,6 +3270,8 @@ class FlatCAMExcEditor(QtCore.QObject): self.new_slots, self.new_tools]}) + return self.edited_obj_name + def update_options(self, obj): try: if not obj.options: From a6b2b0af54287e68bee28991283340aab6e4f538 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 29 Jan 2020 15:52:44 +0200 Subject: [PATCH 056/209] - remade the GUI + small fixes in 2Sided Tool --- FlatCAMApp.py | 5 +- README.md | 1 + flatcamTools/ToolDblSided.py | 260 ++++++++++++++++++++++------------- 3 files changed, 168 insertions(+), 98 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index c84bfc4b..fcd66c45 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -7152,12 +7152,11 @@ class App(QtCore.QObject): pass self.delete_first_selected() - self.inform.emit('%s...' % - _("Object(s) deleted")) + self.inform.emit('%s...' % _("Object(s) deleted")) # make sure that the selection shape is deleted, too self.delete_selection_shape() else: - self.inform.emit(_("Failed. No object(s) selected...")) + self.inform.emit('[ERROR_NOTCL] %s' % _("Failed. No object(s) selected...")) else: self.inform.emit(_("Save the work in Editor and try again ...")) diff --git a/README.md b/README.md index dcd8d762..5510fb44 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ CAD program, and create G-Code for Isolation routing. - changes in how the Editor exit is handled - small fix in some pywin32 imports +- remade the GUI + small fixes in 2Sided Tool 28.01.2020 diff --git a/flatcamTools/ToolDblSided.py b/flatcamTools/ToolDblSided.py index 0b00fc6e..bbc6c266 100644 --- a/flatcamTools/ToolDblSided.py +++ b/flatcamTools/ToolDblSided.py @@ -2,7 +2,7 @@ from PyQt5 import QtWidgets, QtCore from FlatCAMTool import FlatCAMTool -from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, EvalEntry, FCEntry +from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, EvalEntry, FCEntry, FCButton from FlatCAMObj import FlatCAMGerber, FlatCAMExcellon, FlatCAMGeometry from numpy import Inf @@ -41,14 +41,19 @@ class DblSidedTool(FlatCAMTool): """) self.layout.addWidget(title_label) - self.empty_lb = QtWidgets.QLabel("") - self.layout.addWidget(self.empty_lb) + self.layout.addWidget(QtWidgets.QLabel("")) # ## Grid Layout grid_lay = QtWidgets.QGridLayout() - self.layout.addLayout(grid_lay) grid_lay.setColumnStretch(0, 1) grid_lay.setColumnStretch(1, 0) + self.layout.addLayout(grid_lay) + + # Objects to be mirrored + self.m_objects_label = QtWidgets.QLabel("%s:" % _("Mirror Operation")) + self.m_objects_label.setToolTip('%s.' % _("Objects to be mirrored")) + + grid_lay.addWidget(self.m_objects_label, 0, 0, 1, 2) # ## Gerber Object to mirror self.gerber_object_combo = QtWidgets.QComboBox() @@ -56,7 +61,7 @@ class DblSidedTool(FlatCAMTool): self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.gerber_object_combo.setCurrentIndex(1) - self.botlay_label = QtWidgets.QLabel("%s:" % _("GERBER")) + self.botlay_label = QtWidgets.QLabel("%s:" % _("GERBER")) self.botlay_label.setToolTip('%s.' % _("Gerber to be mirrored")) self.mirror_gerber_button = QtWidgets.QPushButton(_("Mirror")) @@ -73,10 +78,9 @@ class DblSidedTool(FlatCAMTool): """) self.mirror_gerber_button.setMinimumWidth(60) - # grid_lay.addRow("Bottom Layer:", self.object_combo) - grid_lay.addWidget(self.botlay_label, 0, 0) - grid_lay.addWidget(self.gerber_object_combo, 1, 0) - grid_lay.addWidget(self.mirror_gerber_button, 1, 1) + grid_lay.addWidget(self.botlay_label, 1, 0) + grid_lay.addWidget(self.gerber_object_combo, 2, 0) + grid_lay.addWidget(self.mirror_gerber_button, 2, 1) # ## Excellon Object to mirror self.exc_object_combo = QtWidgets.QComboBox() @@ -84,7 +88,7 @@ class DblSidedTool(FlatCAMTool): self.exc_object_combo.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex())) self.exc_object_combo.setCurrentIndex(1) - self.excobj_label = QtWidgets.QLabel("%s:" % _("EXCELLON")) + self.excobj_label = QtWidgets.QLabel("%s:" % _("EXCELLON")) self.excobj_label.setToolTip(_("Excellon Object to be mirrored.")) self.mirror_exc_button = QtWidgets.QPushButton(_("Mirror")) @@ -101,10 +105,9 @@ class DblSidedTool(FlatCAMTool): """) self.mirror_exc_button.setMinimumWidth(60) - # grid_lay.addRow("Bottom Layer:", self.object_combo) - grid_lay.addWidget(self.excobj_label, 2, 0) - grid_lay.addWidget(self.exc_object_combo, 3, 0) - grid_lay.addWidget(self.mirror_exc_button, 3, 1) + grid_lay.addWidget(self.excobj_label, 3, 0) + grid_lay.addWidget(self.exc_object_combo, 4, 0) + grid_lay.addWidget(self.mirror_exc_button, 4, 1) # ## Geometry Object to mirror self.geo_object_combo = QtWidgets.QComboBox() @@ -112,7 +115,7 @@ class DblSidedTool(FlatCAMTool): self.geo_object_combo.setRootModelIndex(self.app.collection.index(2, 0, QtCore.QModelIndex())) self.geo_object_combo.setCurrentIndex(1) - self.geoobj_label = QtWidgets.QLabel("%s:" % _("GEOMETRY")) + self.geoobj_label = QtWidgets.QLabel("%s:" % _("GEOMETRY")) self.geoobj_label.setToolTip( _("Geometry Obj to be mirrored.") ) @@ -132,58 +135,57 @@ class DblSidedTool(FlatCAMTool): self.mirror_geo_button.setMinimumWidth(60) # grid_lay.addRow("Bottom Layer:", self.object_combo) - grid_lay.addWidget(self.geoobj_label, 4, 0) - grid_lay.addWidget(self.geo_object_combo, 5, 0) - grid_lay.addWidget(self.mirror_geo_button, 5, 1) + grid_lay.addWidget(self.geoobj_label, 5, 0) + grid_lay.addWidget(self.geo_object_combo, 6, 0) + grid_lay.addWidget(self.mirror_geo_button, 6, 1) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid_lay.addWidget(separator_line, 7, 0, 1, 2) + + self.layout.addWidget(QtWidgets.QLabel("")) # ## Grid Layout grid_lay1 = QtWidgets.QGridLayout() + grid_lay1.setColumnStretch(0, 0) + grid_lay1.setColumnStretch(1, 1) self.layout.addLayout(grid_lay1) + # Objects to be mirrored + self.param_label = QtWidgets.QLabel("%s:" % _("Mirror Parameters")) + self.param_label.setToolTip('%s.' % _("Parameters for the mirror operation")) + + grid_lay1.addWidget(self.param_label, 0, 0, 1, 3) + # ## Axis + self.mirax_label = QtWidgets.QLabel(_("Axis:")) + self.mirax_label.setToolTip(_("Mirror vertically (X) or horizontally (Y).")) self.mirror_axis = RadioSet([{'label': 'X', 'value': 'X'}, {'label': 'Y', 'value': 'Y'}]) - self.mirax_label = QtWidgets.QLabel(_("Mirror Axis:")) - self.mirax_label.setToolTip(_("Mirror vertically (X) or horizontally (Y).")) - # grid_lay.addRow("Mirror Axis:", self.mirror_axis) - self.empty_lb1 = QtWidgets.QLabel("") - grid_lay1.addWidget(self.empty_lb1, 6, 0) - grid_lay1.addWidget(self.mirax_label, 7, 0) - grid_lay1.addWidget(self.mirror_axis, 7, 1) + grid_lay1.addWidget(self.mirax_label, 2, 0) + grid_lay1.addWidget(self.mirror_axis, 2, 1, 1, 2) # ## Axis Location + self.axloc_label = QtWidgets.QLabel('%s:' % _("Reference")) + self.axloc_label.setToolTip( + _("The coordinates used as reference for the mirror operation.\n" + "Can be:\n" + "- Point -> a set of coordinates (x,y) around which the object is mirrored\n" + "- Box -> a set of coordinates (x, y) obtained from the center of the\n" + "bounding box of another object selected below") + ) self.axis_location = RadioSet([{'label': _('Point'), 'value': 'point'}, {'label': _('Box'), 'value': 'box'}]) - self.axloc_label = QtWidgets.QLabel('%s:' % _("Axis Ref")) - self.axloc_label.setToolTip( - _("The axis should pass through a point or cut\n " - "a specified box (in a FlatCAM object) through \n" - "the center.") - ) - # grid_lay.addRow("Axis Location:", self.axis_location) - grid_lay1.addWidget(self.axloc_label, 8, 0) - grid_lay1.addWidget(self.axis_location, 8, 1) - self.empty_lb2 = QtWidgets.QLabel("") - grid_lay1.addWidget(self.empty_lb2, 9, 0) - - # ## Grid Layout - grid_lay2 = QtWidgets.QGridLayout() - self.layout.addLayout(grid_lay2) - grid_lay2.setColumnStretch(0, 1) - grid_lay2.setColumnStretch(1, 0) + grid_lay1.addWidget(self.axloc_label, 4, 0) + grid_lay1.addWidget(self.axis_location, 4, 1, 1, 2) # ## Point/Box - self.point_box_container = QtWidgets.QVBoxLayout() - self.pb_label = QtWidgets.QLabel("%s:" % _('Point/Box Reference')) - self.pb_label.setToolTip( - _("If 'Point' is selected above it store the coordinates (x, y) through which\n" - "the mirroring axis passes.\n" - "If 'Box' is selected above, select here a FlatCAM object (Gerber, Exc or Geo).\n" - "Through the center of this object pass the mirroring axis selected above.") - ) + self.point_entry = EvalEntry() + # Add a reference self.add_point_button = QtWidgets.QPushButton(_("Add")) self.add_point_button.setToolTip( _("Add the coordinates in format (x, y) through which the mirroring axis \n " @@ -192,42 +194,75 @@ class DblSidedTool(FlatCAMTool): "and left mouse button click on canvas or you can enter the coords manually.") ) self.add_point_button.setStyleSheet(""" - QPushButton - { - font-weight: bold; - } - """) + QPushButton + { + font-weight: bold; + } + """) self.add_point_button.setMinimumWidth(60) - grid_lay2.addWidget(self.pb_label, 10, 0) - grid_lay2.addLayout(self.point_box_container, 11, 0) - grid_lay2.addWidget(self.add_point_button, 11, 1) + grid_lay1.addWidget(self.point_entry, 7, 0, 1, 2) + grid_lay1.addWidget(self.add_point_button, 7, 2) - self.point_entry = EvalEntry() - self.point_box_container.addWidget(self.point_entry) + # ## Grid Layout + grid_lay2 = QtWidgets.QGridLayout() + grid_lay2.setColumnStretch(0, 0) + grid_lay2.setColumnStretch(1, 1) + self.layout.addLayout(grid_lay2) + self.box_type_label = QtWidgets.QLabel('%s:' % _("Object Type")) + self.box_type_label.setToolTip( + _("It can be of type: Gerber or Excellon or Geometry.\n" + "The selection here decide the type of objects that will be\n" + "in the Object combobox.") + ) + + # Type of object used as BOX reference + self.box_type_radio = RadioSet([{'label': _('Gerber'), 'value': 'grb'}, + {'label': _('Excellon'), 'value': 'exc'}, + {'label': _('Geometry'), 'value': 'geo'}]) + + self.box_type_label.hide() + self.box_type_radio.hide() + + grid_lay2.addWidget(self.box_type_label, 0, 0, 1, 2) + grid_lay2.addWidget(self.box_type_radio, 1, 0, 1, 2) + + self.box_object_label = QtWidgets.QLabel('%s:' % _("Object")) + self.box_object_label.setToolTip( + _("Object to be used as mirror reference.") + ) + + # Object used as BOX reference self.box_combo = QtWidgets.QComboBox() self.box_combo.setModel(self.app.collection) self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.box_combo.setCurrentIndex(1) - self.box_combo_type = QtWidgets.QComboBox() - self.box_combo_type.addItem(_("Reference Gerber")) - self.box_combo_type.addItem(_("Reference Excellon")) - self.box_combo_type.addItem(_("Reference Geometry")) - - self.point_box_container.addWidget(self.box_combo_type) - self.point_box_container.addWidget(self.box_combo) + self.box_object_label.hide() self.box_combo.hide() - self.box_combo_type.hide() + + grid_lay2.addWidget(self.box_object_label, 2, 0, 1, 2) + grid_lay2.addWidget(self.box_combo, 3, 0, 1, 2) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - grid_lay2.addWidget(separator_line, 12, 0, 1, 2) + self.layout.addWidget(separator_line) + + self.layout.addWidget(QtWidgets.QLabel("")) # ## Alignment holes - self.ah_label = QtWidgets.QLabel("%s:" % _('Alignment Drill Coordinates')) + self.alignment_label = QtWidgets.QLabel("%s:" % _('Alignment Excellon object')) + self.alignment_label.setToolTip( + _("Creates an Excellon Object containing the\n" + "specified alignment holes and their mirror\n" + "images.") + ) + self.layout.addWidget(self.alignment_label) + + # ## Alignment holes + self.ah_label = QtWidgets.QLabel("%s:" % _('Alignment Drill Coordinates')) self.ah_label.setToolTip( _("Alignment holes (x1, y1), (x2, y2), ... " "on one side of the mirror axis. For each set of (x, y) coordinates\n" @@ -241,8 +276,9 @@ class DblSidedTool(FlatCAMTool): self.layout.addLayout(grid_lay3) self.alignment_holes = EvalEntry() + grid_lay3.addWidget(self.alignment_holes, 0, 0, 1, 2) - self.add_drill_point_button = QtWidgets.QPushButton(_("Add")) + self.add_drill_point_button = FCButton(_("Add")) self.add_drill_point_button.setToolTip( _("Add alignment drill holes coords in the format: (x1, y1), (x2, y2), ... \n" "on one side of the mirror axis.\n\n" @@ -258,10 +294,17 @@ class DblSidedTool(FlatCAMTool): font-weight: bold; } """) - self.add_drill_point_button.setMinimumWidth(60) - grid_lay3.addWidget(self.alignment_holes, 0, 0) - grid_lay3.addWidget(self.add_drill_point_button, 0, 1) + self.delete_drill_point_button = FCButton(_("Delete Last")) + self.delete_drill_point_button.setToolTip( + _("Delete the last coordinates tupple in the list.") + ) + drill_hlay = QtWidgets.QHBoxLayout() + + drill_hlay.addWidget(self.add_drill_point_button) + drill_hlay.addWidget(self.delete_drill_point_button) + + grid_lay3.addLayout(drill_hlay, 1, 0, 1, 2) grid0 = QtWidgets.QGridLayout() self.layout.addLayout(grid0) @@ -269,7 +312,7 @@ class DblSidedTool(FlatCAMTool): grid0.setColumnStretch(1, 1) # ## Drill diameter for alignment holes - self.dt_label = QtWidgets.QLabel("%s:" % _('Alignment Drill Diameter')) + self.dt_label = QtWidgets.QLabel("%s:" % _('Alignment Drill Diameter')) self.dt_label.setToolTip( _("Diameter of the drill for the " "alignment holes.") @@ -315,6 +358,14 @@ class DblSidedTool(FlatCAMTool): grid1.setColumnStretch(0, 0) grid1.setColumnStretch(1, 1) + # ## Title Bounds Values + self.bv_label = QtWidgets.QLabel("%s:" % _('Bounds Values')) + self.bv_label.setToolTip( + _("Select on canvas the object(s)\n" + "for which to calculate bounds values.") + ) + grid1.addWidget(self.bv_label, 0, 0, 1, 2) + # Xmin value self.xmin_entry = FCDoubleSpinner() self.xmin_entry.set_precision(self.decimals) @@ -420,7 +471,8 @@ class DblSidedTool(FlatCAMTool): self.mirror_geo_button.clicked.connect(self.on_mirror_geo) self.add_point_button.clicked.connect(self.on_point_add) self.add_drill_point_button.clicked.connect(self.on_drill_add) - self.box_combo_type.currentIndexChanged.connect(self.on_combo_box_type) + self.delete_drill_point_button.clicked.connect(self.on_drill_delete_last) + self.box_type_radio.activated_custom.connect(self.on_combo_box_type) self.axis_location.group_toggle_fn = self.on_toggle_pointbox @@ -477,8 +529,12 @@ class DblSidedTool(FlatCAMTool): self.ymax_entry.set_value(0.0) self.center_entry.set_value('') - def on_combo_box_type(self): - obj_type = self.box_combo_type.currentIndex() + def on_combo_box_type(self, val): + obj_type = { + 'grb': 0, + 'exc': 1, + 'geo': 2 + }[val] self.box_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) self.box_combo.setCurrentIndex(0) @@ -524,7 +580,10 @@ class DblSidedTool(FlatCAMTool): _("No value or wrong format in Drill Dia entry. Add it and retry.")) return - tools = {"1": {"C": dia}} + tools = dict() + tools["1"] = dict() + tools["1"]["C"] = dia + tools["1"]['solid_geometry'] = list() # holes = self.alignment_holes.get_value() holes = eval('[{}]'.format(self.alignment_holes.text())) @@ -538,18 +597,19 @@ class DblSidedTool(FlatCAMTool): for hole in holes: point = Point(hole) point_mirror = affinity.scale(point, xscale, yscale, origin=(px, py)) + drills.append({"point": point, "tool": "1"}) drills.append({"point": point_mirror, "tool": "1"}) - if 'solid_geometry' not in tools["1"]: - tools["1"]['solid_geometry'] = list() - else: - tools["1"]['solid_geometry'].append(point) - tools["1"]['solid_geometry'].append(point_mirror) + + tools["1"]['solid_geometry'].append(point) + tools["1"]['solid_geometry'].append(point_mirror) def obj_init(obj_inst, app_inst): obj_inst.tools = tools obj_inst.drills = drills obj_inst.create_geometry() + obj_inst.source_file = self.app.export_excellon(obj_name=obj_inst.options['name'], local_use=obj_inst, + filename=None, use_thread=False) self.app.new_object("excellon", "Alignment Drills", obj_init) self.drill_values = '' @@ -561,7 +621,7 @@ class DblSidedTool(FlatCAMTool): model_index = self.app.collection.index(selection_index, 0, self.gerber_object_combo.rootModelIndex()) try: fcobj = model_index.internalPointer().obj - except Exception as e: + except Exception: self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no Gerber object loaded ...")) return @@ -585,7 +645,7 @@ class DblSidedTool(FlatCAMTool): model_index_box = self.app.collection.index(selection_index_box, 0, self.box_combo.rootModelIndex()) try: bb_obj = model_index_box.internalPointer().obj - except Exception as e: + except Exception: self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no Box object loaded ...")) return @@ -604,7 +664,7 @@ class DblSidedTool(FlatCAMTool): model_index = self.app.collection.index(selection_index, 0, self.exc_object_combo.rootModelIndex()) try: fcobj = model_index.internalPointer().obj - except Exception as e: + except Exception: self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no Excellon object loaded ...")) return @@ -648,7 +708,7 @@ class DblSidedTool(FlatCAMTool): model_index = self.app.collection.index(selection_index, 0, self.geo_object_combo.rootModelIndex()) try: fcobj = model_index.internalPointer().obj - except Exception as e: + except Exception: self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no Geometry object loaded ...")) return @@ -666,7 +726,7 @@ class DblSidedTool(FlatCAMTool): model_index_box = self.app.collection.index(selection_index_box, 0, self.box_combo.rootModelIndex()) try: bb_obj = model_index_box.internalPointer().obj - except Exception as e: + except Exception: self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no Box object loaded ...")) return @@ -679,7 +739,6 @@ class DblSidedTool(FlatCAMTool): fcobj.plot() self.app.inform.emit('[success] Geometry %s %s...' % (str(fcobj.options['name']), _("was mirrored"))) - def on_point_add(self): val = self.app.defaults["global_point_clipboard_format"] % (self.app.pos[0], self.app.pos[1]) self.point_entry.set_value(val) @@ -689,17 +748,27 @@ class DblSidedTool(FlatCAMTool): (self.app.pos[0], self.app.pos[1])) + ',' self.alignment_holes.set_value(self.drill_values) + def on_drill_delete_last(self): + drill_values_without_last_tupple = self.drill_values.rpartition('(')[0] + self.drill_values = drill_values_without_last_tupple + self.alignment_holes.set_value(self.drill_values) + def on_toggle_pointbox(self): if self.axis_location.get_value() == "point": self.point_entry.show() + self.add_point_button.show() + self.box_type_label.hide() + self.box_type_radio.hide() + self.box_object_label.hide() self.box_combo.hide() - self.box_combo_type.hide() - self.add_point_button.setDisabled(False) else: self.point_entry.hide() + self.add_point_button.hide() + + self.box_type_label.show() + self.box_type_radio.show() + self.box_object_label.show() self.box_combo.show() - self.box_combo_type.show() - self.add_point_button.setDisabled(True) def on_bbox_coordinates(self): @@ -735,6 +804,7 @@ class DblSidedTool(FlatCAMTool): self.center_entry.set_value(val_txt) self.axis_location.set_value('point') self.point_entry.set_value(val_txt) + self.app.delete_selection_shape() def reset_fields(self): self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) @@ -746,6 +816,6 @@ class DblSidedTool(FlatCAMTool): self.exc_object_combo.setCurrentIndex(0) self.geo_object_combo.setCurrentIndex(0) self.box_combo.setCurrentIndex(0) - self.box_combo_type.setCurrentIndex(0) + self.box_type_radio.set_value('grb') self.drill_values = "" From cd45276819488f651b17c782fed422ea875e72ad Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 29 Jan 2020 21:49:22 +0200 Subject: [PATCH 057/209] - updated 2Sided Tool --- FlatCAMApp.py | 9 +- README.md | 1 + flatcamEditors/FlatCAMGeoEditor.py | 4 +- flatcamEditors/FlatCAMGrbEditor.py | 3 +- flatcamGUI/PreferencesUI.py | 25 +- flatcamTools/ToolDblSided.py | 406 +++++++++++++++++------------ 6 files changed, 270 insertions(+), 178 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index fcd66c45..697978a7 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -516,7 +516,7 @@ class App(QtCore.QObject): "zoom_in_key": '=', "grid_toggle_key": 'G', "global_zoom_ratio": 1.5, - "global_point_clipboard_format": "(%.4f, %.4f)", + "global_point_clipboard_format": "(%.*f, %.*f)", "global_zdownrate": None, # General GUI Settings @@ -814,6 +814,7 @@ class App(QtCore.QObject): "tools_2sided_mirror_axis": "X", "tools_2sided_axis_loc": "point", "tools_2sided_drilldia": 3.125, + "tools_2sided_allign_axis": "X", # Film Tool "tools_film_type": 'neg', @@ -1464,6 +1465,7 @@ class App(QtCore.QObject): "tools_2sided_mirror_axis": self.ui.tools_defaults_form.tools_2sided_group.mirror_axis_radio, "tools_2sided_axis_loc": self.ui.tools_defaults_form.tools_2sided_group.axis_location_radio, "tools_2sided_drilldia": self.ui.tools_defaults_form.tools_2sided_group.drill_dia_entry, + "tools_2sided_allign_axis": self.ui.tools_defaults_form.tools_2sided_group.align_axis_radio, # Film Tool "tools_film_type": self.ui.tools_defaults_form.tools_film_group.film_type_radio, @@ -8799,7 +8801,10 @@ class App(QtCore.QObject): # do not auto open the Project Tab self.click_noproject = True - self.clipboard.setText(self.defaults["global_point_clipboard_format"] % (self.pos[0], self.pos[1])) + self.clipboard.setText( + self.defaults["global_point_clipboard_format"] % + (self.decimals, self.pos[0], self.decimals, self.pos[1]) + ) self.inform.emit('[success] %s' % _("Coordinates copied to clipboard.")) return diff --git a/README.md b/README.md index 5510fb44..9e86ffa6 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ CAD program, and create G-Code for Isolation routing. - changes in how the Editor exit is handled - small fix in some pywin32 imports - remade the GUI + small fixes in 2Sided Tool +- updated 2Sided Tool 28.01.2020 diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index 7a5a63c6..0bd67d36 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -4008,7 +4008,9 @@ class FlatCAMGeoEditor(QtCore.QObject): # If the SHIFT key is pressed when LMB is clicked then the coordinates are copied to clipboard if modifiers == QtCore.Qt.ShiftModifier: self.app.clipboard.setText( - self.app.defaults["global_point_clipboard_format"] % (self.pos[0], self.pos[1])) + self.app.defaults["global_point_clipboard_format"] % + (self.decimals, self.pos[0], self.decimals, self.pos[1]) + ) return # Selection with left mouse button diff --git a/flatcamEditors/FlatCAMGrbEditor.py b/flatcamEditors/FlatCAMGrbEditor.py index 0aba714b..2bd6a8bb 100644 --- a/flatcamEditors/FlatCAMGrbEditor.py +++ b/flatcamEditors/FlatCAMGrbEditor.py @@ -4371,7 +4371,8 @@ class FlatCAMGrbEditor(QtCore.QObject): # If the SHIFT key is pressed when LMB is clicked then the coordinates are copied to clipboard if modifiers == QtCore.Qt.ShiftModifier: self.app.clipboard.setText( - self.app.defaults["global_point_clipboard_format"] % (self.pos[0], self.pos[1]) + self.app.defaults["global_point_clipboard_format"] % + (self.decimals, self.pos[0], self.decimals, self.pos[1]) ) self.app.inform.emit('[success] %s' % _("Coordinates copied to clipboard.")) diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index 728f86f6..57b6b68d 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -5500,6 +5500,17 @@ class Tools2sidedPrefGroupUI(OptionsGroupUI): grid0.addWidget(self.dd_label, 0, 0) grid0.addWidget(self.drill_dia_entry, 0, 1) + # ## Alignment Axis + self.align_ax_label = QtWidgets.QLabel('%s:' % _("Align Axis")) + self.align_ax_label.setToolTip( + _("Mirror vertically (X) or horizontally (Y).") + ) + self.align_axis_radio = RadioSet([{'label': 'X', 'value': 'X'}, + {'label': 'Y', 'value': 'Y'}]) + + grid0.addWidget(self.align_ax_label, 1, 0) + grid0.addWidget(self.align_axis_radio, 1, 1) + # ## Axis self.mirror_axis_radio = RadioSet([{'label': 'X', 'value': 'X'}, {'label': 'Y', 'value': 'Y'}]) @@ -5507,11 +5518,11 @@ class Tools2sidedPrefGroupUI(OptionsGroupUI): self.mirax_label.setToolTip( _("Mirror vertically (X) or horizontally (Y).") ) - # grid_lay.addRow("Mirror Axis:", self.mirror_axis) + self.empty_lb1 = QtWidgets.QLabel("") - grid0.addWidget(self.empty_lb1, 1, 0) - grid0.addWidget(self.mirax_label, 2, 0) - grid0.addWidget(self.mirror_axis_radio, 2, 1) + grid0.addWidget(self.empty_lb1, 2, 0) + grid0.addWidget(self.mirax_label, 3, 0) + grid0.addWidget(self.mirror_axis_radio, 3, 1) # ## Axis Location self.axis_location_radio = RadioSet([{'label': _('Point'), 'value': 'point'}, @@ -5522,9 +5533,9 @@ class Tools2sidedPrefGroupUI(OptionsGroupUI): "a specified box (in a FlatCAM object) through \n" "the center.") ) - # grid_lay.addRow("Axis Location:", self.axis_location) - grid0.addWidget(self.axloc_label, 3, 0) - grid0.addWidget(self.axis_location_radio, 3, 1) + + grid0.addWidget(self.axloc_label, 4, 0) + grid0.addWidget(self.axis_location_radio, 4, 1) self.layout.addStretch() diff --git a/flatcamTools/ToolDblSided.py b/flatcamTools/ToolDblSided.py index bbc6c266..11888004 100644 --- a/flatcamTools/ToolDblSided.py +++ b/flatcamTools/ToolDblSided.py @@ -159,7 +159,7 @@ class DblSidedTool(FlatCAMTool): grid_lay1.addWidget(self.param_label, 0, 0, 1, 3) # ## Axis - self.mirax_label = QtWidgets.QLabel(_("Axis:")) + self.mirax_label = QtWidgets.QLabel('%s:' % _("Axis")) self.mirax_label.setToolTip(_("Mirror vertically (X) or horizontally (Y).")) self.mirror_axis = RadioSet([{'label': 'X', 'value': 'X'}, {'label': 'Y', 'value': 'Y'}]) @@ -191,7 +191,7 @@ class DblSidedTool(FlatCAMTool): _("Add the coordinates in format (x, y) through which the mirroring axis \n " "selected in 'MIRROR AXIS' pass.\n" "The (x, y) coordinates are captured by pressing SHIFT key\n" - "and left mouse button click on canvas or you can enter the coords manually.") + "and left mouse button click on canvas or you can enter the coordinates manually.") ) self.add_point_button.setStyleSheet(""" QPushButton @@ -210,11 +210,11 @@ class DblSidedTool(FlatCAMTool): grid_lay2.setColumnStretch(1, 1) self.layout.addLayout(grid_lay2) - self.box_type_label = QtWidgets.QLabel('%s:' % _("Object Type")) + self.box_type_label = QtWidgets.QLabel('%s:' % _("Reference Object")) self.box_type_label.setToolTip( _("It can be of type: Gerber or Excellon or Geometry.\n" - "The selection here decide the type of objects that will be\n" - "in the Object combobox.") + "The coordinates of the center of the bounding box are used\n" + "as reference for mirror operation.") ) # Type of object used as BOX reference @@ -228,38 +228,179 @@ class DblSidedTool(FlatCAMTool): grid_lay2.addWidget(self.box_type_label, 0, 0, 1, 2) grid_lay2.addWidget(self.box_type_radio, 1, 0, 1, 2) - self.box_object_label = QtWidgets.QLabel('%s:' % _("Object")) - self.box_object_label.setToolTip( - _("Object to be used as mirror reference.") - ) - # Object used as BOX reference self.box_combo = QtWidgets.QComboBox() self.box_combo.setModel(self.app.collection) self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.box_combo.setCurrentIndex(1) - self.box_object_label.hide() self.box_combo.hide() - grid_lay2.addWidget(self.box_object_label, 2, 0, 1, 2) grid_lay2.addWidget(self.box_combo, 3, 0, 1, 2) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - self.layout.addWidget(separator_line) + grid_lay2.addWidget(separator_line, 4, 0, 1, 2) - self.layout.addWidget(QtWidgets.QLabel("")) + grid_lay2.addWidget(QtWidgets.QLabel(""), 5, 0, 1, 2) + + # ## Title Bounds Values + self.bv_label = QtWidgets.QLabel("%s:" % _('Bounds Values')) + self.bv_label.setToolTip( + _("Select on canvas the object(s)\n" + "for which to calculate bounds values.") + ) + grid_lay2.addWidget(self.bv_label, 6, 0, 1, 2) + + # Xmin value + self.xmin_entry = FCDoubleSpinner() + self.xmin_entry.set_precision(self.decimals) + self.xmin_entry.set_range(-9999.9999, 9999.9999) + + self.xmin_btn = FCButton('%s:' % _("X min")) + self.xmin_btn.setToolTip( + _("Minimum location.") + ) + self.xmin_entry.setReadOnly(True) + + grid_lay2.addWidget(self.xmin_btn, 7, 0) + grid_lay2.addWidget(self.xmin_entry, 7, 1) + + # Ymin value + self.ymin_entry = FCDoubleSpinner() + self.ymin_entry.set_precision(self.decimals) + self.ymin_entry.set_range(-9999.9999, 9999.9999) + + self.ymin_btn = FCButton('%s:' % _("Y min")) + self.ymin_btn.setToolTip( + _("Minimum location.") + ) + self.ymin_entry.setReadOnly(True) + + grid_lay2.addWidget(self.ymin_btn, 8, 0) + grid_lay2.addWidget(self.ymin_entry, 8, 1) + + # Xmax value + self.xmax_entry = FCDoubleSpinner() + self.xmax_entry.set_precision(self.decimals) + self.xmax_entry.set_range(-9999.9999, 9999.9999) + + self.xmax_btn = FCButton('%s:' % _("X max")) + self.xmax_btn.setToolTip( + _("Maximum location.") + ) + self.xmax_entry.setReadOnly(True) + + grid_lay2.addWidget(self.xmax_btn, 9, 0) + grid_lay2.addWidget(self.xmax_entry, 9, 1) + + # Ymax value + self.ymax_entry = FCDoubleSpinner() + self.ymax_entry.set_precision(self.decimals) + self.ymax_entry.set_range(-9999.9999, 9999.9999) + + self.ymax_btn = FCButton('%s:' % _("Y max")) + self.ymax_btn.setToolTip( + _("Maximum location.") + ) + self.ymax_entry.setReadOnly(True) + + grid_lay2.addWidget(self.ymax_btn, 10, 0) + grid_lay2.addWidget(self.ymax_entry, 10, 1) + + # Center point value + self.center_entry = FCEntry() + + self.center_btn = FCButton('%s:' % _("Centroid")) + self.center_btn.setToolTip( + _("The center point location for the rectangular\n" + "bounding shape. Centroid. Format is (x, y).") + ) + self.center_entry.setReadOnly(True) + + grid_lay2.addWidget(self.center_btn, 12, 0) + grid_lay2.addWidget(self.center_entry, 12, 1) + + # Calculate Bounding box + self.calculate_bb_button = QtWidgets.QPushButton(_("Calculate Bounds Values")) + self.calculate_bb_button.setToolTip( + _("Calculate the enveloping rectangular shape coordinates,\n" + "for the selection of objects.\n" + "The envelope shape is parallel with the X, Y axis.") + ) + self.calculate_bb_button.setStyleSheet(""" + QPushButton + { + font-weight: bold; + } + """) + grid_lay2.addWidget(self.calculate_bb_button, 13, 0, 1, 2) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid_lay2.addWidget(separator_line, 14, 0, 1, 2) + + grid_lay2.addWidget(QtWidgets.QLabel(""), 15, 0, 1, 2) # ## Alignment holes - self.alignment_label = QtWidgets.QLabel("%s:" % _('Alignment Excellon object')) + self.alignment_label = QtWidgets.QLabel("%s:" % _('PCB Alignment')) self.alignment_label.setToolTip( _("Creates an Excellon Object containing the\n" "specified alignment holes and their mirror\n" "images.") ) - self.layout.addWidget(self.alignment_label) + grid_lay2.addWidget(self.alignment_label, 25, 0, 1, 2) + + # ## Drill diameter for alignment holes + self.dt_label = QtWidgets.QLabel("%s:" % _('Drill Diameter')) + self.dt_label.setToolTip( + _("Diameter of the drill for the alignment holes.") + ) + + self.drill_dia = FCDoubleSpinner() + self.drill_dia.setToolTip( + _("Diameter of the drill for the alignment holes.") + ) + self.drill_dia.set_precision(self.decimals) + self.drill_dia.set_range(0.0000, 9999.9999) + + grid_lay2.addWidget(self.dt_label, 26, 0) + grid_lay2.addWidget(self.drill_dia, 26, 1) + + # ## Alignment Axis + self.align_ax_label = QtWidgets.QLabel('%s:' % _("Align Axis")) + self.align_ax_label.setToolTip( + _("Mirror vertically (X) or horizontally (Y).") + ) + self.align_axis_radio = RadioSet([{'label': 'X', 'value': 'X'}, + {'label': 'Y', 'value': 'Y'}]) + + grid_lay2.addWidget(self.align_ax_label, 27, 0) + grid_lay2.addWidget(self.align_axis_radio, 27, 1) + + # ## Alignment Reference Point + self.align_ref_label = QtWidgets.QLabel('%s:' % _("Reference")) + self.align_ref_label.setToolTip( + _("The reference point used to create the second alignment drill\n" + "from the first alignment drill, by doing mirror.\n" + "It can be modified in the Mirror Parameters -> Reference section") + ) + + self.align_ref_label_val = EvalEntry() + self.align_ref_label_val.setToolTip( + _("The reference point used to create the second alignment drill\n" + "from the first alignment drill, by doing mirror.\n" + "It can be modified in the Mirror Parameters -> Reference section") + ) + self.align_ref_label_val.setDisabled(True) + + grid_lay2.addWidget(self.align_ref_label, 28, 0) + grid_lay2.addWidget(self.align_ref_label_val, 28, 1) + + grid_lay4 = QtWidgets.QGridLayout() + self.layout.addLayout(grid_lay4) # ## Alignment holes self.ah_label = QtWidgets.QLabel("%s:" % _('Alignment Drill Coordinates')) @@ -268,68 +409,41 @@ class DblSidedTool(FlatCAMTool): "on one side of the mirror axis. For each set of (x, y) coordinates\n" "entered here, a pair of drills will be created:\n\n" "- one drill at the coordinates from the field\n" - "- one drill in mirror position over the axis selected above in the 'Mirror Axis'.") + "- one drill in mirror position over the axis selected above in the 'Align Axis'.") ) - self.layout.addWidget(self.ah_label) - - grid_lay3 = QtWidgets.QGridLayout() - self.layout.addLayout(grid_lay3) self.alignment_holes = EvalEntry() - grid_lay3.addWidget(self.alignment_holes, 0, 0, 1, 2) + + grid_lay4.addWidget(self.ah_label, 0, 0, 1, 2) + grid_lay4.addWidget(self.alignment_holes, 1, 0, 1, 2) self.add_drill_point_button = FCButton(_("Add")) self.add_drill_point_button.setToolTip( - _("Add alignment drill holes coords in the format: (x1, y1), (x2, y2), ... \n" - "on one side of the mirror axis.\n\n" + _("Add alignment drill holes coordinates in the format: (x1, y1), (x2, y2), ... \n" + "on one side of the alignment axis.\n\n" "The coordinates set can be obtained:\n" "- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" "- press SHIFT key and left mouse clicking on canvas. Then CTRL+V in the field.\n" "- press SHIFT key and left mouse clicking on canvas. Then RMB click in the field and click Paste.\n" "- by entering the coords manually in the format: (x1, y1), (x2, y2), ...") ) - self.add_drill_point_button.setStyleSheet(""" - QPushButton - { - font-weight: bold; - } - """) + # self.add_drill_point_button.setStyleSheet(""" + # QPushButton + # { + # font-weight: bold; + # } + # """) self.delete_drill_point_button = FCButton(_("Delete Last")) self.delete_drill_point_button.setToolTip( - _("Delete the last coordinates tupple in the list.") + _("Delete the last coordinates tuple in the list.") ) drill_hlay = QtWidgets.QHBoxLayout() drill_hlay.addWidget(self.add_drill_point_button) drill_hlay.addWidget(self.delete_drill_point_button) - grid_lay3.addLayout(drill_hlay, 1, 0, 1, 2) - - grid0 = QtWidgets.QGridLayout() - self.layout.addLayout(grid0) - grid0.setColumnStretch(0, 0) - grid0.setColumnStretch(1, 1) - - # ## Drill diameter for alignment holes - self.dt_label = QtWidgets.QLabel("%s:" % _('Alignment Drill Diameter')) - self.dt_label.setToolTip( - _("Diameter of the drill for the " - "alignment holes.") - ) - grid0.addWidget(self.dt_label, 0, 0, 1, 2) - - # Drill diameter value - self.drill_dia = FCDoubleSpinner() - self.drill_dia.set_precision(self.decimals) - self.drill_dia.set_range(0.0000, 9999.9999) - - self.drill_dia.setToolTip( - _("Diameter of the drill for the " - "alignment holes.") - ) - - grid0.addWidget(self.drill_dia, 1, 0, 1, 2) + grid_lay4.addLayout(drill_hlay, 2, 0, 1, 2) # ## Buttons self.create_alignment_hole_button = QtWidgets.QPushButton(_("Create Excellon Object")) @@ -346,110 +460,6 @@ class DblSidedTool(FlatCAMTool): """) self.layout.addWidget(self.create_alignment_hole_button) - separator_line = QtWidgets.QFrame() - separator_line.setFrameShape(QtWidgets.QFrame.HLine) - separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - self.layout.addWidget(separator_line) - - self.layout.addWidget(QtWidgets.QLabel('')) - - grid1 = QtWidgets.QGridLayout() - self.layout.addLayout(grid1) - grid1.setColumnStretch(0, 0) - grid1.setColumnStretch(1, 1) - - # ## Title Bounds Values - self.bv_label = QtWidgets.QLabel("%s:" % _('Bounds Values')) - self.bv_label.setToolTip( - _("Select on canvas the object(s)\n" - "for which to calculate bounds values.") - ) - grid1.addWidget(self.bv_label, 0, 0, 1, 2) - - # Xmin value - self.xmin_entry = FCDoubleSpinner() - self.xmin_entry.set_precision(self.decimals) - self.xmin_entry.set_range(-9999.9999, 9999.9999) - - self.xmin_label = QtWidgets.QLabel('%s:' % _("X min")) - self.xmin_label.setToolTip( - _("Minimum location.") - ) - self.xmin_entry.setReadOnly(True) - - grid1.addWidget(self.xmin_label, 1, 0) - grid1.addWidget(self.xmin_entry, 1, 1) - - # Ymin value - self.ymin_entry = FCDoubleSpinner() - self.ymin_entry.set_precision(self.decimals) - self.ymin_entry.set_range(-9999.9999, 9999.9999) - - self.ymin_label = QtWidgets.QLabel('%s:' % _("Y min")) - self.ymin_label.setToolTip( - _("Minimum location.") - ) - self.ymin_entry.setReadOnly(True) - - grid1.addWidget(self.ymin_label, 2, 0) - grid1.addWidget(self.ymin_entry, 2, 1) - - # Xmax value - self.xmax_entry = FCDoubleSpinner() - self.xmax_entry.set_precision(self.decimals) - self.xmax_entry.set_range(-9999.9999, 9999.9999) - - self.xmax_label = QtWidgets.QLabel('%s:' % _("X max")) - self.xmax_label.setToolTip( - _("Maximum location.") - ) - self.xmax_entry.setReadOnly(True) - - grid1.addWidget(self.xmax_label, 3, 0) - grid1.addWidget(self.xmax_entry, 3, 1) - - # Ymax value - self.ymax_entry = FCDoubleSpinner() - self.ymax_entry.set_precision(self.decimals) - self.ymax_entry.set_range(-9999.9999, 9999.9999) - - self.ymax_label = QtWidgets.QLabel('%s:' % _("Y max")) - self.ymax_label.setToolTip( - _("Maximum location.") - ) - self.ymax_entry.setReadOnly(True) - - grid1.addWidget(self.ymax_label, 4, 0) - grid1.addWidget(self.ymax_entry, 4, 1) - - # Center point value - self.center_entry = FCEntry() - - self.center_label = QtWidgets.QLabel('%s:' % _("Centroid")) - self.center_label.setToolTip( - _("The center point location for the rectangular\n" - "bounding shape. Centroid. Format is (x, y).") - ) - self.center_entry.setReadOnly(True) - - grid1.addWidget(self.center_label, 5, 0) - grid1.addWidget(self.center_entry, 5, 1) - - # Calculate Bounding box - self.calculate_bb_button = QtWidgets.QPushButton(_("Calculate Bounds Values")) - self.calculate_bb_button.setToolTip( - _("Calculate the enveloping rectangular shape coordinates,\n" - "for the selection of objects.\n" - "The envelope shape is parallel with the X, Y axis.") - ) - self.calculate_bb_button.setStyleSheet(""" - QPushButton - { - font-weight: bold; - } - """) - self.layout.addWidget(self.calculate_bb_button) - self.layout.addStretch() # ## Reset Tool @@ -469,6 +479,7 @@ class DblSidedTool(FlatCAMTool): self.mirror_gerber_button.clicked.connect(self.on_mirror_gerber) self.mirror_exc_button.clicked.connect(self.on_mirror_exc) self.mirror_geo_button.clicked.connect(self.on_mirror_geo) + self.add_point_button.clicked.connect(self.on_point_add) self.add_drill_point_button.clicked.connect(self.on_drill_add) self.delete_drill_point_button.clicked.connect(self.on_drill_delete_last) @@ -476,6 +487,18 @@ class DblSidedTool(FlatCAMTool): self.axis_location.group_toggle_fn = self.on_toggle_pointbox + self.point_entry.textChanged.connect(lambda val: self.align_ref_label_val.set_value(val)) + + self.xmin_btn.clicked.connect(self.on_xmin_clicked) + self.ymin_btn.clicked.connect(self.on_ymin_clicked) + self.xmax_btn.clicked.connect(self.on_xmax_clicked) + self.ymax_btn.clicked.connect(self.on_ymax_clicked) + + self.center_btn.clicked.connect( + lambda: self.point_entry.set_value(self.center_entry.get_value()) + ) + + self.create_alignment_hole_button.clicked.connect(self.on_create_alignment_holes) self.calculate_bb_button.clicked.connect(self.on_bbox_coordinates) @@ -522,6 +545,7 @@ class DblSidedTool(FlatCAMTool): self.mirror_axis.set_value(self.app.defaults["tools_2sided_mirror_axis"]) self.axis_location.set_value(self.app.defaults["tools_2sided_axis_loc"]) self.drill_dia.set_value(self.app.defaults["tools_2sided_drilldia"]) + self.align_axis_radio.set_value(self.app.defaults["tools_2sided_allign_axis"]) self.xmin_entry.set_value(0.0) self.ymin_entry.set_value(0.0) @@ -529,6 +553,8 @@ class DblSidedTool(FlatCAMTool): self.ymax_entry.set_value(0.0) self.center_entry.set_value('') + self.align_ref_label_val.set_value('%.*f' % (self.decimals, 0.0)) + def on_combo_box_type(self, val): obj_type = { 'grb': 0, @@ -539,7 +565,7 @@ class DblSidedTool(FlatCAMTool): self.box_combo.setCurrentIndex(0) def on_create_alignment_holes(self): - axis = self.mirror_axis.get_value() + axis = self.align_axis_radio.get_value() mode = self.axis_location.get_value() if mode == "point": @@ -608,7 +634,7 @@ class DblSidedTool(FlatCAMTool): obj_inst.tools = tools obj_inst.drills = drills obj_inst.create_geometry() - obj_inst.source_file = self.app.export_excellon(obj_name=obj_inst.options['name'], local_use=obj_inst, + obj_inst.source_file = app_inst.export_excellon(obj_name=obj_inst.options['name'], local_use=obj_inst, filename=None, use_thread=False) self.app.new_object("excellon", "Alignment Drills", obj_init) @@ -740,12 +766,13 @@ class DblSidedTool(FlatCAMTool): self.app.inform.emit('[success] Geometry %s %s...' % (str(fcobj.options['name']), _("was mirrored"))) def on_point_add(self): - val = self.app.defaults["global_point_clipboard_format"] % (self.app.pos[0], self.app.pos[1]) + val = self.app.defaults["global_point_clipboard_format"] % \ + (self.decimals, self.app.pos[0], self.decimals, self.app.pos[1]) self.point_entry.set_value(val) def on_drill_add(self): self.drill_values += (self.app.defaults["global_point_clipboard_format"] % - (self.app.pos[0], self.app.pos[1])) + ',' + (self.decimals, self.app.pos[0], self.decimals, self.app.pos[1])) + ',' self.alignment_holes.set_value(self.drill_values) def on_drill_delete_last(self): @@ -759,7 +786,6 @@ class DblSidedTool(FlatCAMTool): self.add_point_button.show() self.box_type_label.hide() self.box_type_radio.hide() - self.box_object_label.hide() self.box_combo.hide() else: self.point_entry.hide() @@ -767,9 +793,10 @@ class DblSidedTool(FlatCAMTool): self.box_type_label.show() self.box_type_radio.show() - self.box_object_label.show() self.box_combo.show() + self.align_ref_label_val.set_value("Box centroid") + def on_bbox_coordinates(self): xmin = Inf @@ -806,6 +833,50 @@ class DblSidedTool(FlatCAMTool): self.point_entry.set_value(val_txt) self.app.delete_selection_shape() + def on_xmin_clicked(self): + xmin = self.xmin_entry.get_value() + self.axis_location.set_value('point') + + try: + px, py = self.point_entry.get_value() + val = self.app.defaults["global_point_clipboard_format"] % (self.decimals, xmin, self.decimals, py) + except TypeError: + val = self.app.defaults["global_point_clipboard_format"] % (self.decimals, xmin, self.decimals, 0.0) + self.point_entry.set_value(val) + + def on_ymin_clicked(self): + ymin = self.ymin_entry.get_value() + self.axis_location.set_value('point') + + try: + px, py = self.point_entry.get_value() + val = self.app.defaults["global_point_clipboard_format"] % (self.decimals, px, self.decimals, ymin) + except TypeError: + val = self.app.defaults["global_point_clipboard_format"] % (self.decimals, 0.0, self.decimals, ymin) + self.point_entry.set_value(val) + + def on_xmax_clicked(self): + xmax = self.xmax_entry.get_value() + self.axis_location.set_value('point') + + try: + px, py = self.point_entry.get_value() + val = self.app.defaults["global_point_clipboard_format"] % (self.decimals, xmax, self.decimals, py) + except TypeError: + val = self.app.defaults["global_point_clipboard_format"] % (self.decimals, xmax, self.decimals, 0.0) + self.point_entry.set_value(val) + + def on_ymax_clicked(self): + ymax = self.ymax_entry.get_value() + self.axis_location.set_value('point') + + try: + px, py = self.point_entry.get_value() + val = self.app.defaults["global_point_clipboard_format"] % (self.decimals, px, self.decimals, ymax) + except TypeError: + val = self.app.defaults["global_point_clipboard_format"] % (self.decimals, 0.0, self.decimals, ymax) + self.point_entry.set_value(val) + def reset_fields(self): self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.exc_object_combo.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex())) @@ -819,3 +890,4 @@ class DblSidedTool(FlatCAMTool): self.box_type_radio.set_value('grb') self.drill_values = "" + self.align_ref_label_val.set_value('') From e7c25e9b8aabf562f161f19f0482ef00160ab60d Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 29 Jan 2020 22:04:23 +0200 Subject: [PATCH 058/209] - updated 2Sided Tool- wip --- flatcamTools/ToolDblSided.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/flatcamTools/ToolDblSided.py b/flatcamTools/ToolDblSided.py index 11888004..dc1bbd9f 100644 --- a/flatcamTools/ToolDblSided.py +++ b/flatcamTools/ToolDblSided.py @@ -159,7 +159,7 @@ class DblSidedTool(FlatCAMTool): grid_lay1.addWidget(self.param_label, 0, 0, 1, 3) # ## Axis - self.mirax_label = QtWidgets.QLabel('%s:' % _("Axis")) + self.mirax_label = QtWidgets.QLabel('%s:' % _("Mirror Axis")) self.mirax_label.setToolTip(_("Mirror vertically (X) or horizontally (Y).")) self.mirror_axis = RadioSet([{'label': 'X', 'value': 'X'}, {'label': 'Y', 'value': 'Y'}]) @@ -787,6 +787,8 @@ class DblSidedTool(FlatCAMTool): self.box_type_label.hide() self.box_type_radio.hide() self.box_combo.hide() + + self.align_ref_label_val.set_value(self.point_entry.get_value()) else: self.point_entry.hide() self.add_point_button.hide() From 123ae16b203ce66b176cbaa702238c5058c2c5ea Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 30 Jan 2020 05:14:05 +0200 Subject: [PATCH 059/209] - remade GUI in Tool Cutout, Tool Align Objects, Tool Panelize --- README.md | 4 ++ flatcamTools/ToolAlignObjects.py | 94 +++++++++++++------------- flatcamTools/ToolCutOut.py | 110 +++++++++++++++++-------------- flatcamTools/ToolPanelize.py | 35 +++++----- 4 files changed, 127 insertions(+), 116 deletions(-) diff --git a/README.md b/README.md index 9e86ffa6..9a1c3463 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +30.01.2020 + +- remade GUI in Tool Cutout, Tool Align Objects, Tool Panelize + 29.01.2020 - changes in how the Editor exit is handled diff --git a/flatcamTools/ToolAlignObjects.py b/flatcamTools/ToolAlignObjects.py index d1e77442..9cc4c196 100644 --- a/flatcamTools/ToolAlignObjects.py +++ b/flatcamTools/ToolAlignObjects.py @@ -50,32 +50,31 @@ class AlignObjects(FlatCAMTool): """) self.layout.addWidget(title_label) + self.layout.addWidget(QtWidgets.QLabel('')) + # Form Layout grid0 = QtWidgets.QGridLayout() grid0.setColumnStretch(0, 0) grid0.setColumnStretch(1, 1) self.layout.addLayout(grid0) - self.aligned_label = QtWidgets.QLabel('%s' % _("Selection of the WORKING object")) + self.aligned_label = QtWidgets.QLabel('%s:' % _("MOVING object")) grid0.addWidget(self.aligned_label, 0, 0, 1, 2) - # Type of object to be aligned - self.type_obj_combo = FCComboBox() - self.type_obj_combo.addItem("Gerber") - self.type_obj_combo.addItem("Excellon") - - self.type_obj_combo.setItemIcon(0, QtGui.QIcon(self.app.resource_location + "/flatcam_icon16.png")) - self.type_obj_combo.setItemIcon(1, QtGui.QIcon(self.app.resource_location + "/drill16.png")) - - self.type_obj_combo_label = QtWidgets.QLabel('%s:' % _("Object Type")) - self.type_obj_combo_label.setToolTip( + self.aligned_label.setToolTip( _("Specify the type of object to be aligned.\n" "It can be of type: Gerber or Excellon.\n" "The selection here decide the type of objects that will be\n" "in the Object combobox.") ) - grid0.addWidget(self.type_obj_combo_label, 2, 0) - grid0.addWidget(self.type_obj_combo, 2, 1) + + # Type of object to be aligned + self.type_obj_radio = RadioSet([ + {"label": _("Gerber"), "value": "grb"}, + {"label": _("Excellon"), "value": "exc"}, + ], orientation='vertical', stretch=False) + + grid0.addWidget(self.type_obj_radio, 3, 0, 1, 2) # Object to be aligned self.object_combo = FCComboBox() @@ -83,42 +82,35 @@ class AlignObjects(FlatCAMTool): self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.object_combo.setCurrentIndex(1) - self.object_label = QtWidgets.QLabel('%s:' % _("Object")) - self.object_label.setToolTip( + self.object_combo.setToolTip( _("Object to be aligned.") ) - grid0.addWidget(self.object_label, 3, 0) - grid0.addWidget(self.object_combo, 3, 1) + grid0.addWidget(self.object_combo, 4, 0, 1, 2) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - grid0.addWidget(separator_line, 4, 0, 1, 2) + grid0.addWidget(separator_line, 5, 0, 1, 2) - self.aligned_label = QtWidgets.QLabel('%s' % _("Selection of the TARGET object")) + grid0.addWidget(QtWidgets.QLabel(''), 6, 0, 1, 2) + + self.aligned_label = QtWidgets.QLabel('%s:' % _("TARGET object")) self.aligned_label.setToolTip( - _("Object to which the other objects will be aligned to (moved to).") - ) - grid0.addWidget(self.aligned_label, 6, 0, 1, 2) - - # Type of object to be aligned to = aligner - self.type_aligner_obj_combo = FCComboBox() - self.type_aligner_obj_combo.addItem("Gerber") - self.type_aligner_obj_combo.addItem("Excellon") - - self.type_aligner_obj_combo.setItemIcon(0, QtGui.QIcon(self.app.resource_location + "/flatcam_icon16.png")) - self.type_aligner_obj_combo.setItemIcon(1, QtGui.QIcon(self.app.resource_location + "/drill16.png")) - - self.type_aligner_obj_combo_label = QtWidgets.QLabel('%s:' % _("Object Type")) - self.type_aligner_obj_combo_label.setToolTip( _("Specify the type of object to be aligned to.\n" "It can be of type: Gerber or Excellon.\n" "The selection here decide the type of objects that will be\n" "in the Object combobox.") ) - grid0.addWidget(self.type_aligner_obj_combo_label, 7, 0) - grid0.addWidget(self.type_aligner_obj_combo, 7, 1) + grid0.addWidget(self.aligned_label, 7, 0, 1, 2) + + # Type of object to be aligned to = aligner + self.type_aligner_obj_radio = RadioSet([ + {"label": _("Gerber"), "value": "grb"}, + {"label": _("Excellon"), "value": "exc"}, + ], orientation='vertical', stretch=False) + + grid0.addWidget(self.type_aligner_obj_radio, 8, 0, 1, 2) # Object to be aligned to = aligner self.aligner_object_combo = FCComboBox() @@ -126,18 +118,18 @@ class AlignObjects(FlatCAMTool): self.aligner_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.aligner_object_combo.setCurrentIndex(1) - self.aligner_object_label = QtWidgets.QLabel('%s:' % _("Object")) - self.aligner_object_label.setToolTip( + self.aligner_object_combo.setToolTip( _("Object to be aligned to. Aligner.") ) - grid0.addWidget(self.aligner_object_label, 8, 0) - grid0.addWidget(self.aligner_object_combo, 8, 1) + grid0.addWidget(self.aligner_object_combo, 9, 0, 1, 2) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - grid0.addWidget(separator_line, 9, 0, 1, 2) + grid0.addWidget(separator_line, 10, 0, 1, 2) + + grid0.addWidget(QtWidgets.QLabel(''), 11, 0, 1, 2) # Alignment Type self.a_type_lbl = QtWidgets.QLabel('%s:' % _("Alignment Type")) @@ -151,17 +143,17 @@ class AlignObjects(FlatCAMTool): {'label': _('Single Point'), 'value': 'sp'}, {'label': _('Dual Point'), 'value': 'dp'} ], - orientation='horizontal', + orientation='vertical', stretch=False ) - grid0.addWidget(self.a_type_lbl, 10, 0, 1, 2) - grid0.addWidget(self.a_type_radio, 11, 0, 1, 2) + grid0.addWidget(self.a_type_lbl, 12, 0, 1, 2) + grid0.addWidget(self.a_type_radio, 13, 0, 1, 2) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - grid0.addWidget(separator_line, 12, 0, 1, 2) + grid0.addWidget(separator_line, 14, 0, 1, 2) # Buttons self.align_object_button = QtWidgets.QPushButton(_("Align Object")) @@ -195,8 +187,8 @@ class AlignObjects(FlatCAMTool): # Signals self.align_object_button.clicked.connect(self.on_align) - self.type_obj_combo.currentIndexChanged.connect(self.on_type_obj_index_changed) - self.type_aligner_obj_combo.currentIndexChanged.connect(self.on_type_aligner_index_changed) + self.type_obj_radio.activated_custom.connect(self.on_type_obj_changed) + self.type_aligner_obj_radio.activated_custom.connect(self.on_type_aligner_changed) self.reset_button.clicked.connect(self.set_tool_ui) self.mr = None @@ -268,17 +260,19 @@ class AlignObjects(FlatCAMTool): self.aligned_old_line_color = None self.a_type_radio.set_value(self.app.defaults["tools_align_objects_align_type"]) + self.type_obj_radio.set_value('grb') + self.type_aligner_obj_radio.set_value('grb') if self.local_connected is True: self.disconnect_cal_events() - def on_type_obj_index_changed(self): - obj_type = self.type_obj_combo.currentIndex() + def on_type_obj_changed(self, val): + obj_type = {'grb': 0, 'exc': 1}[val] self.object_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) self.object_combo.setCurrentIndex(0) - def on_type_aligner_index_changed(self): - obj_type = self.type_aligner_obj_combo.currentIndex() + def on_type_aligner_changed(self, val): + obj_type = {'grb': 0, 'exc': 1}[val] self.aligner_object_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) self.aligner_object_combo.setCurrentIndex(0) diff --git a/flatcamTools/ToolCutOut.py b/flatcamTools/ToolCutOut.py index 4209b70b..2e0d7924 100644 --- a/flatcamTools/ToolCutOut.py +++ b/flatcamTools/ToolCutOut.py @@ -7,7 +7,7 @@ from PyQt5 import QtWidgets, QtGui, QtCore from FlatCAMTool import FlatCAMTool -from flatcamGUI.GUIElements import FCDoubleSpinner, FCCheckBox, RadioSet, FCComboBox, OptionalInputSection +from flatcamGUI.GUIElements import FCDoubleSpinner, FCCheckBox, RadioSet, FCComboBox, OptionalInputSection, FCButton from FlatCAMObj import FlatCAMGerber from shapely.geometry import box, MultiPolygon, Polygon, LineString, LinearRing @@ -59,46 +59,18 @@ class CutOut(FlatCAMTool): """) self.layout.addWidget(title_label) + self.layout.addWidget(QtWidgets.QLabel('')) + # Form Layout grid0 = QtWidgets.QGridLayout() grid0.setColumnStretch(0, 0) grid0.setColumnStretch(1, 1) self.layout.addLayout(grid0) - # Type of object to be cutout - self.type_obj_combo = QtWidgets.QComboBox() - self.type_obj_combo.addItem("Gerber") - self.type_obj_combo.addItem("Excellon") - self.type_obj_combo.addItem("Geometry") - - # we get rid of item1 ("Excellon") as it is not suitable for creating film - self.type_obj_combo.view().setRowHidden(1, True) - self.type_obj_combo.setItemIcon(0, QtGui.QIcon(self.app.resource_location + "/flatcam_icon16.png")) - # self.type_obj_combo.setItemIcon(1, QtGui.QIcon(self.app.resource_location + "/drill16.png")) - self.type_obj_combo.setItemIcon(2, QtGui.QIcon(self.app.resource_location + "/geometry16.png")) - - self.type_obj_combo_label = QtWidgets.QLabel('%s:' % _("Object Type")) - self.type_obj_combo_label.setToolTip( - _("Specify the type of object to be cutout.\n" - "It can be of type: Gerber or Geometry.\n" - "What is selected here will dictate the kind\n" - "of objects that will populate the 'Object' combobox.") - ) - self.type_obj_combo_label.setMinimumWidth(60) - grid0.addWidget(self.type_obj_combo_label, 0, 0) - grid0.addWidget(self.type_obj_combo, 0, 1) - - self.object_label = QtWidgets.QLabel('%s:' % _("Object to be cutout")) + self.object_label = QtWidgets.QLabel('%s:' % _("Source Object")) self.object_label.setToolTip('%s.' % _("Object to be cutout")) - # Object to be cutout - self.obj_combo = QtWidgets.QComboBox() - self.obj_combo.setModel(self.app.collection) - self.obj_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.obj_combo.setCurrentIndex(1) - - grid0.addWidget(self.object_label, 1, 0, 1, 2) - grid0.addWidget(self.obj_combo, 2, 0, 1, 2) + grid0.addWidget(self.object_label, 0, 0, 1, 2) # Object kind self.kindlabel = QtWidgets.QLabel('%s:' % _('Object kind')) @@ -112,8 +84,43 @@ class CutOut(FlatCAMTool): {"label": _("Single"), "value": "single"}, {"label": _("Panel"), "value": "panel"}, ]) - grid0.addWidget(self.kindlabel, 3, 0) - grid0.addWidget(self.obj_kind_combo, 3, 1) + grid0.addWidget(self.kindlabel, 1, 0) + grid0.addWidget(self.obj_kind_combo, 1, 1) + + # Type of object to be cutout + self.type_obj_radio = RadioSet([ + {"label": _("Gerber"), "value": "grb"}, + {"label": _("Geometry"), "value": "geo"}, + ]) + + self.type_obj_combo_label = QtWidgets.QLabel('%s:' % _("Object Type")) + self.type_obj_combo_label.setToolTip( + _("Specify the type of object to be cutout.\n" + "It can be of type: Gerber or Geometry.\n" + "What is selected here will dictate the kind\n" + "of objects that will populate the 'Object' combobox.") + ) + + grid0.addWidget(self.type_obj_combo_label, 2, 0) + grid0.addWidget(self.type_obj_radio, 2, 1) + + # Object to be cutout + self.obj_combo = QtWidgets.QComboBox() + self.obj_combo.setModel(self.app.collection) + self.obj_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) + self.obj_combo.setCurrentIndex(1) + + grid0.addWidget(self.obj_combo, 3, 0, 1, 2) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(separator_line, 4, 0, 1, 2) + + grid0.addWidget(QtWidgets.QLabel(''), 5, 0, 1, 2) + + self.param_label = QtWidgets.QLabel('%s:' % _("Tool Parameters")) + grid0.addWidget(self.param_label, 6, 0, 1, 2) # Tool Diameter self.dia = FCDoubleSpinner() @@ -125,8 +132,8 @@ class CutOut(FlatCAMTool): _("Diameter of the tool used to cutout\n" "the PCB shape out of the surrounding material.") ) - grid0.addWidget(self.dia_label, 4, 0) - grid0.addWidget(self.dia, 4, 1) + grid0.addWidget(self.dia_label, 8, 0) + grid0.addWidget(self.dia, 8, 1) # Cut Z cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z')) @@ -146,8 +153,8 @@ class CutOut(FlatCAMTool): self.cutz_entry.setSingleStep(0.1) - grid0.addWidget(cutzlabel, 5, 0) - grid0.addWidget(self.cutz_entry, 5, 1) + grid0.addWidget(cutzlabel, 9, 0) + grid0.addWidget(self.cutz_entry, 9, 1) # Multi-pass self.mpass_cb = FCCheckBox('%s:' % _("Multi-Depth")) @@ -172,8 +179,8 @@ class CutOut(FlatCAMTool): ) self.ois_mpass_geo = OptionalInputSection(self.mpass_cb, [self.maxdepth_entry]) - grid0.addWidget(self.mpass_cb, 6, 0) - grid0.addWidget(self.maxdepth_entry, 6, 1) + grid0.addWidget(self.mpass_cb, 10, 0) + grid0.addWidget(self.maxdepth_entry, 10, 1) # Margin self.margin = FCDoubleSpinner() @@ -187,8 +194,8 @@ class CutOut(FlatCAMTool): "will make the cutout of the PCB further from\n" "the actual PCB border") ) - grid0.addWidget(self.margin_label, 7, 0) - grid0.addWidget(self.margin, 7, 1) + grid0.addWidget(self.margin_label, 11, 0) + grid0.addWidget(self.margin, 11, 1) # Gapsize self.gapsize = FCDoubleSpinner() @@ -201,8 +208,8 @@ class CutOut(FlatCAMTool): "the surrounding material (the one \n" "from which the PCB is cutout).") ) - grid0.addWidget(self.gapsize_label, 8, 0) - grid0.addWidget(self.gapsize, 8, 1) + grid0.addWidget(self.gapsize_label, 13, 0) + grid0.addWidget(self.gapsize, 13, 1) # How gaps wil be rendered: # lr - left + right @@ -219,12 +226,14 @@ class CutOut(FlatCAMTool): _("Create a convex shape surrounding the entire PCB.\n" "Used only if the source object type is Gerber.") ) - grid0.addWidget(self.convex_box, 9, 0, 1, 2) + grid0.addWidget(self.convex_box, 15, 0, 1, 2) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - grid0.addWidget(separator_line, 10, 0, 1, 2) + grid0.addWidget(separator_line, 16, 0, 1, 2) + + grid0.addWidget(QtWidgets.QLabel(''), 17, 0, 1, 2) # Title2 title_param_label = QtWidgets.QLabel("%s" % _('A. Automatic Bridge Gaps')) @@ -398,13 +407,13 @@ class CutOut(FlatCAMTool): self.ff_cutout_object_btn.clicked.connect(self.on_freeform_cutout) self.rect_cutout_object_btn.clicked.connect(self.on_rectangular_cutout) - self.type_obj_combo.currentIndexChanged.connect(self.on_type_obj_index_changed) + self.type_obj_radio.activated_custom.connect(self.on_type_obj_changed) self.man_geo_creation_btn.clicked.connect(self.on_manual_geo) self.man_gaps_creation_btn.clicked.connect(self.on_manual_gap_click) self.reset_button.clicked.connect(self.set_tool_ui) - def on_type_obj_index_changed(self, index): - obj_type = self.type_obj_combo.currentIndex() + def on_type_obj_changed(self, val): + obj_type = {'grb': 0, 'geo': 2}[val] self.obj_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) self.obj_combo.setCurrentIndex(0) @@ -451,6 +460,7 @@ class CutOut(FlatCAMTool): self.gapsize.set_value(float(self.app.defaults["tools_cutoutgapsize"])) self.gaps.set_value(self.app.defaults["tools_gaps_ff"]) self.convex_box.set_value(self.app.defaults['tools_cutout_convexshape']) + self.type_obj_radio.set_value('grb') def on_freeform_cutout(self): diff --git a/flatcamTools/ToolPanelize.py b/flatcamTools/ToolPanelize.py index 7159e81f..a836d320 100644 --- a/flatcamTools/ToolPanelize.py +++ b/flatcamTools/ToolPanelize.py @@ -49,6 +49,18 @@ class Panelize(FlatCAMTool): """) self.layout.addWidget(title_label) + self.layout.addWidget(QtWidgets.QLabel('')) + + self.object_label = QtWidgets.QLabel('%s:' % _("Source Object")) + self.object_label.setToolTip( + _("Specify the type of object to be panelized\n" + "It can be of type: Gerber, Excellon or Geometry.\n" + "The selection here decide the type of objects that will be\n" + "in the Object combobox.") + ) + + self.layout.addWidget(self.object_label) + # Form Layout form_layout_0 = QtWidgets.QFormLayout() self.layout.addLayout(form_layout_0) @@ -63,14 +75,9 @@ class Panelize(FlatCAMTool): self.type_obj_combo.setItemIcon(1, QtGui.QIcon(self.app.resource_location + "/drill16.png")) self.type_obj_combo.setItemIcon(2, QtGui.QIcon(self.app.resource_location + "/geometry16.png")) - self.type_obj_combo_label = QtWidgets.QLabel('%s:' % _("Object Type")) - self.type_obj_combo_label.setToolTip( - _("Specify the type of object to be panelized\n" - "It can be of type: Gerber, Excellon or Geometry.\n" - "The selection here decide the type of objects that will be\n" - "in the Object combobox.") - ) - form_layout_0.addRow(self.type_obj_combo_label, self.type_obj_combo) + self.type_object_label = QtWidgets.QLabel('%s:' % _("Object Type")) + + form_layout_0.addRow(self.type_object_label, self.type_obj_combo) # Object to be panelized self.object_combo = QtWidgets.QComboBox() @@ -78,12 +85,11 @@ class Panelize(FlatCAMTool): self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.object_combo.setCurrentIndex(1) - self.object_label = QtWidgets.QLabel('%s:' % _("Object")) - self.object_label.setToolTip( + self.object_combo.setToolTip( _("Object to be panelized. This means that it will\n" "be duplicated in an array of rows and columns.") ) - form_layout_0.addRow(self.object_label, self.object_combo) + form_layout_0.addRow(self.object_combo) form_layout_0.addRow(QtWidgets.QLabel("")) # Form Layout @@ -133,12 +139,11 @@ class Panelize(FlatCAMTool): self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.box_combo.setCurrentIndex(1) - self.box_combo_label = QtWidgets.QLabel('%s:' % _("Box Object")) - self.box_combo_label.setToolTip( + self.box_combo.setToolTip( _("The actual object that is used a container for the\n " "selected object that is to be panelized.") ) - form_layout.addRow(self.box_combo_label, self.box_combo) + form_layout.addRow(self.box_combo) form_layout.addRow(QtWidgets.QLabel("")) panel_data_label = QtWidgets.QLabel("%s:" % _("Panel Data")) @@ -382,12 +387,10 @@ class Panelize(FlatCAMTool): self.type_box_combo.setDisabled(False) self.type_box_combo_label.setDisabled(False) self.box_combo.setDisabled(False) - self.box_combo_label.setDisabled(False) else: self.type_box_combo.setDisabled(True) self.type_box_combo_label.setDisabled(True) self.box_combo.setDisabled(True) - self.box_combo_label.setDisabled(True) def on_panelize(self): name = self.object_combo.currentText() From a44d7b97b561d8751efcc1e698bb39c1ea5bcdfd Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 30 Jan 2020 05:55:46 +0200 Subject: [PATCH 060/209] - some changed in the Excellon UI --- FlatCAMObj.py | 13 ++++++++++++- README.md | 1 + flatcamGUI/ObjectUI.py | 4 ++-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 8cbc596a..3ed53b66 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -2868,7 +2868,18 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): sel_rows = row if type(row) == list else [row] if not sel_rows: - sel_rows = [0] + self.ui.tool_data_label.setText( + "%s: %s" % (_('Parameters for'), _("No Tool Selected")) + ) + self.ui.generate_cnc_button.setDisabled(True) + self.ui.generate_milling_button.setDisabled(True) + self.ui.generate_milling_slots_button.setDisabled(True) + self.ui_connect() + return + else: + self.ui.generate_cnc_button.setDisabled(False) + self.ui.generate_milling_button.setDisabled(False) + self.ui.generate_milling_slots_button.setDisabled(False) if len(sel_rows) == 1: # update the QLabel that shows for which Tool we have the parameters in the UI form diff --git a/README.md b/README.md index 9a1c3463..e16d8193 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 30.01.2020 - remade GUI in Tool Cutout, Tool Align Objects, Tool Panelize +- some changed in the Excellon UI 29.01.2020 diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index 3d97ccb6..6a0b2df5 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -1248,7 +1248,7 @@ class ExcellonObjectUI(ObjectUI): warning_lbl = QtWidgets.QLabel( _( "Add / Select at least one tool in the tool-table.\n" - "Click the header to select all, or Ctrl + LMB\n" + "Click the # header to select all, or Ctrl + LMB\n" "for custom selection of tools." )) @@ -1946,7 +1946,7 @@ class GeometryObjectUI(ObjectUI): warning_lbl = QtWidgets.QLabel( _( "Add / Select at least one tool in the tool-table.\n" - "Click the header to select all, or Ctrl + LMB\n" + "Click the # header to select all, or Ctrl + LMB\n" "for custom selection of tools." )) self.grid4.addWidget(warning_lbl, 6, 0, 1, 2) From ece94b7f6050efc8a77f52cc42c75daea82eae84 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 30 Jan 2020 06:26:14 +0200 Subject: [PATCH 061/209] - some UI changes in the common object UI --- FlatCAMObj.py | 4 -- README.md | 1 + flatcamGUI/ObjectUI.py | 97 ++++++++++++++++++++++-------------------- 3 files changed, 51 insertions(+), 51 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 3ed53b66..33c6aeed 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -2695,20 +2695,16 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.ui.tools_table.setMaximumHeight(self.ui.tools_table.getHeight()) if not self.drills: - self.ui.tdlabel.hide() self.ui.tooldia_entry.hide() self.ui.generate_milling_button.hide() else: - self.ui.tdlabel.show() self.ui.tooldia_entry.show() self.ui.generate_milling_button.show() if not self.slots: - self.ui.stdlabel.hide() self.ui.slot_tooldia_entry.hide() self.ui.generate_milling_slots_button.hide() else: - self.ui.stdlabel.show() self.ui.slot_tooldia_entry.show() self.ui.generate_milling_slots_button.show() diff --git a/README.md b/README.md index e16d8193..92b79cb6 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ CAD program, and create G-Code for Isolation routing. - remade GUI in Tool Cutout, Tool Align Objects, Tool Panelize - some changed in the Excellon UI +- some UI changes in the common object UI 29.01.2020 diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index 6a0b2df5..6270e332 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -95,28 +95,31 @@ class ObjectUI(QtWidgets.QWidget): # ########################### if common is True: self.common_grid = QtWidgets.QGridLayout() + self.common_grid.setColumnStretch(0, 1) + self.common_grid.setColumnStretch(1, 0) layout.addLayout(self.common_grid) - self.common_grid.setColumnStretch(0, 0) - self.common_grid.setColumnStretch(1, 1) - # ### Scale #### - self.scale_label = QtWidgets.QLabel('%s' % _('Scale')) - self.scale_label.setToolTip( - _("Change the size of the object.") + # self.common_grid.addWidget(QtWidgets.QLabel(''), 1, 0, 1, 2) + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + self.common_grid.addWidget(separator_line, 1, 0, 1, 2) + + self.transform_label = QtWidgets.QLabel('%s' % _('Transformations')) + self.transform_label.setToolTip( + _("Geometrical transformations of the current object.") ) - self.common_grid.addWidget(self.scale_label, 0, 0, 1, 3) + self.common_grid.addWidget(self.transform_label, 2, 0, 1, 2) - # Factor - faclabel = QtWidgets.QLabel('%s:' % _('Factor')) - faclabel.setToolTip( + # ### Scale #### + self.scale_entry = FCEntry() + self.scale_entry.set_value(1.0) + self.scale_entry.setToolTip( _("Factor by which to multiply\n" "geometric features of this object.\n" "Expressions are allowed. E.g: 1/25.4") ) - self.scale_entry = FCEntry() - self.scale_entry.set_value(1.0) - # GO Button self.scale_button = QtWidgets.QPushButton(_('Scale')) self.scale_button.setToolTip( @@ -124,26 +127,17 @@ class ObjectUI(QtWidgets.QWidget): ) self.scale_button.setMinimumWidth(70) - self.common_grid.addWidget(faclabel, 1, 0) - self.common_grid.addWidget(self.scale_entry, 1, 1) - self.common_grid.addWidget(self.scale_button, 1, 2) + self.common_grid.addWidget(self.scale_entry, 3, 0) + self.common_grid.addWidget(self.scale_button, 3, 1) # ### Offset #### - self.offset_label = QtWidgets.QLabel('%s' % _('Offset')) - self.offset_label.setToolTip( - _("Change the position of this object.") - ) - - self.common_grid.addWidget(self.offset_label, 2, 0, 1, 3) - - self.offset_vectorlabel = QtWidgets.QLabel('%s:' % _('Vector')) - self.offset_vectorlabel.setToolTip( + self.offsetvector_entry = EvalEntry2() + self.offsetvector_entry.setText("(0.0, 0.0)") + self.offsetvector_entry.setToolTip( _("Amount by which to move the object\n" "in the x and y axes in (x, y) format.\n" "Expressions are allowed. E.g: (1/3.2, 0.5*3)") ) - self.offsetvector_entry = EvalEntry2() - self.offsetvector_entry.setText("(0.0, 0.0)") self.offset_button = QtWidgets.QPushButton(_('Offset')) self.offset_button.setToolTip( @@ -151,9 +145,8 @@ class ObjectUI(QtWidgets.QWidget): ) self.offset_button.setMinimumWidth(70) - self.common_grid.addWidget(self.offset_vectorlabel, 3, 0) - self.common_grid.addWidget(self.offsetvector_entry, 3, 1) - self.common_grid.addWidget(self.offset_button, 3, 2) + self.common_grid.addWidget(self.offsetvector_entry, 4, 0) + self.common_grid.addWidget(self.offset_button, 4, 1) layout.addStretch() @@ -1156,6 +1149,21 @@ class ExcellonObjectUI(ObjectUI): self.feedrate_probe_label.hide() self.feedrate_probe_entry.setVisible(False) + # Tool Offset + self.tool_offset_label = QtWidgets.QLabel('%s:' % _('Offset Z')) + self.tool_offset_label.setToolTip( + _("Some drill bits (the larger ones) need to drill deeper\n" + "to create the desired exit hole diameter due of the tip shape.\n" + "The value here can compensate the Cut Z parameter.") + ) + + self.offset_entry = FCDoubleSpinner() + self.offset_entry.set_precision(self.decimals) + self.offset_entry.set_range(-9999.9999, 9999.9999) + + self.grid3.addWidget(self.tool_offset_label, 25, 0) + self.grid3.addWidget(self.offset_entry, 25, 1) + # ################################################################# # ################# GRID LAYOUT 4 ############################### # ################################################################# @@ -1271,10 +1279,10 @@ class ExcellonObjectUI(ObjectUI): separator_line2 = QtWidgets.QFrame() separator_line2.setFrameShape(QtWidgets.QFrame.HLine) separator_line2.setFrameShadow(QtWidgets.QFrame.Sunken) - self.grid6.addWidget(separator_line2, 4, 0, 1, 2) + self.grid6.addWidget(separator_line2, 4, 0, 1, 3) # ### Milling Holes Drills #### - self.mill_hole_label = QtWidgets.QLabel('%s' % _('Mill Holes')) + self.mill_hole_label = QtWidgets.QLabel('%s' % _('Milling Geometry')) self.mill_hole_label.setToolTip( _("Create Geometry for milling holes.\n" "Select from the Tools Table above the hole dias to be\n" @@ -1282,16 +1290,19 @@ class ExcellonObjectUI(ObjectUI): ) self.grid6.addWidget(self.mill_hole_label, 5, 0, 1, 3) - self.tdlabel = QtWidgets.QLabel('%s:' % _('Drill Tool dia')) + self.tdlabel = QtWidgets.QLabel('%s:' % _('Tool Dia')) self.tdlabel.setToolTip( _("Diameter of the cutting tool.") ) + + self.grid6.addWidget(self.tdlabel, 6, 0, 1, 3) + self.tooldia_entry = FCDoubleSpinner() self.tooldia_entry.set_precision(self.decimals) self.tooldia_entry.set_range(0.0, 9999.9999) self.tooldia_entry.setSingleStep(0.1) - self.generate_milling_button = QtWidgets.QPushButton(_('Mill Drills Geo')) + self.generate_milling_button = QtWidgets.QPushButton(_('Mill Drills')) self.generate_milling_button.setToolTip( _("Create the Geometry Object\n" "for milling DRILLS toolpaths.") @@ -1303,22 +1314,15 @@ class ExcellonObjectUI(ObjectUI): } """) - self.grid6.addWidget(self.tdlabel, 6, 0) - self.grid6.addWidget(self.tooldia_entry, 6, 1) - self.grid6.addWidget(self.generate_milling_button, 6, 2) - - self.stdlabel = QtWidgets.QLabel('%s:' % _('Slot Tool dia')) - self.stdlabel.setToolTip( - _("Diameter of the cutting tool\n" - "when milling slots.") - ) + self.grid6.addWidget(self.tooldia_entry, 7, 0, 1, 2) + self.grid6.addWidget(self.generate_milling_button, 7, 2) self.slot_tooldia_entry = FCDoubleSpinner() self.slot_tooldia_entry.set_precision(self.decimals) self.slot_tooldia_entry.set_range(0.0, 9999.9999) self.slot_tooldia_entry.setSingleStep(0.1) - self.generate_milling_slots_button = QtWidgets.QPushButton(_('Mill Slots Geo')) + self.generate_milling_slots_button = QtWidgets.QPushButton(_('Mill Slots')) self.generate_milling_slots_button.setToolTip( _("Create the Geometry Object\n" "for milling SLOTS toolpaths.") @@ -1330,9 +1334,8 @@ class ExcellonObjectUI(ObjectUI): } """) - self.grid6.addWidget(self.stdlabel, 7, 0) - self.grid6.addWidget(self.slot_tooldia_entry, 7, 1) - self.grid6.addWidget(self.generate_milling_slots_button, 7, 2) + self.grid6.addWidget(self.slot_tooldia_entry, 8, 0, 1, 2) + self.grid6.addWidget(self.generate_milling_slots_button, 8, 2) def hide_drills(self, state=True): if state is True: From 0b162bbd550480ab1f821b8ed3e2039bb754ee6d Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 31 Jan 2020 22:34:20 +0200 Subject: [PATCH 062/209] - added a new functionality, a variation of Set Origin named Move to Origin. It will move a selection of objects to origin such as the bottom left corner of the bounding box that fit them all is in origin. --- FlatCAMApp.py | 53 ++++++++++++++++++++++++++++++++++++++- README.md | 4 +++ flatcamGUI/FlatCAMGUI.py | 6 +++++ share/origin16.png | Bin 563 -> 523 bytes share/origin2_16.png | Bin 0 -> 516 bytes share/origin2_32.png | Bin 0 -> 763 bytes share/origin32.png | Bin 750 -> 808 bytes 7 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 share/origin2_16.png create mode 100644 share/origin2_32.png diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 697978a7..14a05111 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -1974,6 +1974,8 @@ class App(QtCore.QObject): self.ui.menueditconvert_any2gerber.triggered.connect(self.convert_any2gerber) self.ui.menueditorigin.triggered.connect(self.on_set_origin) + self.ui.menuedit_move2origin.triggered.connect(self.on_move2origin) + self.ui.menueditjump.triggered.connect(self.on_jump_to) self.ui.menueditlocate.triggered.connect(lambda: self.on_locate(obj=self.collection.get_active())) @@ -3267,6 +3269,8 @@ class App(QtCore.QObject): self.ui.distance_btn.triggered.connect(lambda: self.distance_tool.run(toggle=True)) self.ui.distance_min_btn.triggered.connect(lambda: self.distance_min_tool.run(toggle=True)) self.ui.origin_btn.triggered.connect(self.on_set_origin) + self.ui.move2origin_btn.triggered.connect(self.on_move2origin) + self.ui.jmp_btn.triggered.connect(self.on_jump_to) self.ui.locate_btn.triggered.connect(lambda: self.on_locate(obj=self.collection.get_active())) @@ -7275,7 +7279,7 @@ class App(QtCore.QObject): event_pos = (event.xdata, event.ydata) pos_canvas = self.plotcanvas.translate_coords(event_pos) - if self.grid_status() == True: + if self.grid_status(): pos = self.geo_editor.snap(pos_canvas[0], pos_canvas[1]) else: pos = pos_canvas @@ -7289,6 +7293,53 @@ class App(QtCore.QObject): worker_task() self.should_we_save = True + def on_move2origin(self, use_thread=True): + """ + + :param event: + :param location: + :param noplot: + :param use_thread: + :return: + """ + + def worker_task(): + with self.proc_container.new(_("Moving to Origin...")): + obj_list = self.collection.get_selected() + xminlist = list() + yminlist = list() + + # first get a bounding box to fit all + for obj in obj_list: + xmin, ymin, xmax, ymax = obj.bounds() + xminlist.append(xmin) + yminlist.append(ymin) + + # get the minimum x,y for all objects selected + x = min(xminlist) + y = min(yminlist) + + for obj in obj_list: + obj.offset((-x, -y)) + self.object_changed.emit(obj) + + # Update the object bounding box options + a, b, c, d = obj.bounds() + obj.options['xmin'] = a + obj.options['ymin'] = b + obj.options['xmax'] = c + obj.options['ymax'] = d + + for obj in obj_list: + obj.plot() + self.inform.emit('[success] %s...' % _('Origin set')) + + if use_thread is True: + self.worker_task.emit({'fcn': worker_task, 'params': []}) + else: + worker_task() + self.should_we_save = True + def on_jump_to(self, custom_location=None, fit_center=True): """ Jump to a location by setting the mouse cursor location diff --git a/README.md b/README.md index 92b79cb6..c537aaf9 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +31.01.2020 + +- added a new functionality, a variation of Set Origin named Move to Origin. It will move a selection of objects to origin such as the bottom left corner of the bounding box that fit them all is in origin. + 30.01.2020 - remade GUI in Tool Cutout, Tool Align Objects, Tool Panelize diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index e7a4bc68..b67b4c0e 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -371,6 +371,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.menuedit.addSeparator() self.menueditorigin = self.menuedit.addAction( QtGui.QIcon(self.app.resource_location + '/origin16.png'), _('Se&t Origin\tO')) + self.menuedit_move2origin = self.menuedit.addAction( + QtGui.QIcon(self.app.resource_location + '/origin2_16.png'), _('Move to Origin\tSHIFT+O')) + self.menueditjump = self.menuedit.addAction( QtGui.QIcon(self.app.resource_location + '/jump_to16.png'), _('Jump to Location\tJ')) self.menueditlocate = self.menuedit.addAction( @@ -841,6 +844,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow): QtGui.QIcon(self.app.resource_location + '/distance_min32.png'), _("Distance Min Tool")) self.origin_btn = self.toolbargeo.addAction( QtGui.QIcon(self.app.resource_location + '/origin32.png'), _('Set Origin')) + self.move2origin_btn = self.toolbargeo.addAction( + QtGui.QIcon(self.app.resource_location + '/origin2_32.png'), _('Move to Origin')) + self.jmp_btn = self.toolbargeo.addAction( QtGui.QIcon(self.app.resource_location + '/jump_to16.png'), _('Jump to Location')) self.locate_btn = self.toolbargeo.addAction( diff --git a/share/origin16.png b/share/origin16.png index e9fa79406da44f822d269ff5fb394d930e69e6f5..2c0374d81eff13a16666d3c0b0ea8613f1256f30 100644 GIT binary patch delta 330 zcmdnY(#Uk%e0^&Pnj1(?MmAHP`LMrGbVrA|NToPRY~-0xYeIYhb8rY#3r_VP$A&WoWK#U|?lnaO~g|ugMn~ Q#c;`QpQH0_G82;_0Ivau(f|Me delta 394 zcmeBX*~~Jbv;Hv`Kc~7??D^Ts3=E8no-U3d8s|eV9Mo=%f!bFzq{^VBq-`HFfwC;(L9@oidAKq=ZVBfX zyk5~Pp>1~OG)IlrjuPSNSL*vSXYcrMV{%YutGV;MyWhO)*UmTLpX(<3l!1XkwZt`| zBqgyV)hf9t6-Y4{85mmX8XD*tnuZuyS{YkfnObNYm{=JYM71u+M$wR)pOTqYiCcsA P4T^mT`@Tw0nS*ukeH=5SChz^rkFqry!mryOl1A=xW6NsSswZ*H7h`|Rvo^Y8A) zZf?Fx8GDk_{f^EKS??qq&b0f-m&eBzy)03hoRHS$@~*V#R>l2rs z3`zXD-gd(FV?0m3y$;p4IjtogG*eyw?6+gjoUDHY?bw!cpGj$Y#hUE$#l`RJADF2I zu90RdP`(kYX@0Ff!0JFw`|R3^BB@GB&j`FxECOure@Mzj$R0 ziiX_$l+3hB+#2rv6FdOaAPKS|I6tkVJh3R1p}f3YFEcN@I61K(RWH9NefB#WDWD<- MPgg&ebxsLQ0J@~H`Tzg` literal 0 HcmV?d00001 diff --git a/share/origin2_32.png b/share/origin2_32.png new file mode 100644 index 0000000000000000000000000000000000000000..b4c6c721ec72937a194949c4e7fe30cb7a7b35ec GIT binary patch literal 763 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`F}V3n}S#UirYrz`%IY)5S5wrB1dO zla*`NUR%QFRk^MII(ujOuYI52*?zzG`QGg}rE zWqXe4&)B?l;i@G|RwV{IYQ+^@suew*=lMD)WXgoH+g)8vDa*gq<>#C>ncv-Y_VW^1 z?_Z03-fUm;Xi{sy$4cc@YlR#ejptS7AG)sm`*+eIcJ70YO-$eCOb+dr`M7)yWBK8^ z>siw54{Ug7rng$=o9i>3@}eD`p+C!tPM^KOWNa3_a!OlCPNO3)^Z%gmn)em@d=mp~ zcPQW8@oK*6AF)vSi6MQJ1ja>+G8*m@8o~JZ~Fh( zzrRk~2ZS;f>^zP+QeKTvVc)%0_7s_nQE zkG$)>A$^7;d6UA#2H|6^lDtz_pZAD$beo>YEynYDievwklBIfXt*bK(Ra^G#QB}Oy zBKOeq=ZizdTTXa>wbGb)wShiPH{uU?NxQ*{6TwruD>{NSm_V*Lgw{XR{Y<*ht=j%&)aXmp6#}}YA62f z`$O-C{~BC3m)&@|x^hqP!ip)$tWjR6Wt*Mk=W(@n8(E~B6nMw&e*OG|$*gN74lh;u zlN#N#@alQdjEQpGk+*%l=f+=lY~SN@%rmim!58l>oXHld=@)rRg*p%Coj#p;%=@9w z&JMShye%_CJ_S`O`eYp|OHDkQh#UmS+O7Af3Y6kxpgv2!t)zVNDJB&FVZ|$F delta 614 zcmZ3%_KsDtGr-TCmrII^fq{Y7)59eQNK1e)2Mdt&s{2|zQ8AfA?*~$zI zjC(v?978NlPrY*1drF`P+lTuvG#q`|`aFH!{%R7N>c+tpse4O;({alS=9Rup3W7UJ z1m8umvij}FP!_#vA0VVFCBu_`LQSJX?B%62!CsFEy3fw7Hr}gev-o6pNHzLz$+HmjM;&KJ3wG=EQZ*_E#o zj1sTi`|+CF@2J_`e8*)UtGXlq&h~rR6SMaAvloXpt!%LF*|F}nUVP|*a`w08+v5}$ zrlcRJ?aGrdf46MWy$QLWJ(FTDBwH=mvdHJllAcB14%n0y-QDrHNU`?nlBFvy)K6Ly z&G@_|w0F1m!#S?W4>pw_yU;B1&Ehq`h0@})Q9+T1y6&G!xT>ET65w_!D?ux4%34)h zw?k$(ACz|IM9kEAS0Ohe@H6AW)7=?Ttn7=H@oTzWu6`O(y5Q=M7h9ehG-#gR;{D_0 zB*mi-&PuzRTiHHwYzcOI`n1=}b!Yp!tLxqBCvRsni|yr3`}e=dN@PyID36v$cjp$# z{x|D{OJ;qsDynwAy!Eo^_P-zQCDvS2f4naCbBNR3;lXO`7z!Lg@QD z-T$Wl7?=Oa-go=pr%Yh{s+PD$l%ynogODkhbD^m+? j0}~4?1B0m61=%P%a`RI%(<*W30BX>_A#r{3cP2vs7^@DS From 6eb96264f1e9eb1f9a2a80e6446cb60b3aa5ea92 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 1 Feb 2020 04:01:48 +0200 Subject: [PATCH 063/209] - fixed some bugs --- FlatCAMObj.py | 32 ++++++++++++++++------------- README.md | 1 + camlib.py | 11 +++++----- flatcamEditors/FlatCAMTextEditor.py | 2 +- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 33c6aeed..870003b9 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -4229,6 +4229,9 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ui.geo_tools_table.cellWidget(row, 6).clicked.connect(self.on_plot_cb_click_table) self.ui.plot_cb.stateChanged.connect(self.on_plot_cb_click) + # common parameters update + self.ui.pp_geometry_name_cb.currentIndexChanged.connect(self.update_common_param_in_storage) + def ui_disconnect(self): # on any change to the widgets that matter it will be called self.gui_form_to_storage which will save the @@ -4969,6 +4972,10 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): temp_tools.clear() self.ui_connect() + def update_common_param_in_storage(self): + for tooluid_value in self.tools.values(): + tooluid_value['data']['ppname_g'] = self.ui.pp_geometry_name_cb.get_value() + def select_tools_table_row(self, row, clearsel=None): if clearsel: self.ui.geo_tools_table.clearSelection() @@ -5117,16 +5124,14 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): # this reads the values in the UI form to the self.options dictionary self.read_form() - self.sel_tools = {} + self.sel_tools = dict() try: if self.special_group: - self.app.inform.emit('[WARNING_NOTCL] %s %s %s.' % - (_("This Geometry can't be processed because it is"), - str(self.special_group), - _("geometry") - ) - ) + self.app.inform.emit( + '[WARNING_NOTCL] %s %s %s.' % + (_("This Geometry can't be processed because it is"), str(self.special_group), _("geometry")) + ) return except AttributeError: pass @@ -5166,8 +5171,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ui.geo_tools_table.clearSelection() else: - self.app.inform.emit('[ERROR_NOTCL] %s' % - _("Failed. No tool selected in the tool table ...")) + self.app.inform.emit('[ERROR_NOTCL] %s' % _("Failed. No tool selected in the tool table ...")) def mtool_gen_cncjob(self, outname=None, tools_dict=None, tools_in_use=None, segx=None, segy=None, plot=True, use_thread=True): @@ -5261,15 +5265,15 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): try: offset_value = float(self.ui.tool_offset_entry.get_value().replace(',', '.')) except ValueError: - self.app.inform.emit('[ERROR_NOTCL] %s' % - _("Wrong value format entered, use a number.")) + self.app.inform.emit('[ERROR_NOTCL] %s' % _("Wrong value format entered, use a number.")) return if offset_value: tool_offset = float(offset_value) else: - self.app.inform.emit('[WARNING] %s' % _("Tool Offset is selected in Tool Table but " - "no value is provided.\n" - "Add a Tool Offset or change the Offset Type.")) + self.app.inform.emit( + '[WARNING] %s' % _("Tool Offset is selected in Tool Table but no value is provided.\n" + "Add a Tool Offset or change the Offset Type.") + ) return else: tool_offset = 0.0 diff --git a/README.md b/README.md index c537aaf9..513825ac 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 31.01.2020 - added a new functionality, a variation of Set Origin named Move to Origin. It will move a selection of objects to origin such as the bottom left corner of the bounding box that fit them all is in origin. +- fixed some bugs 30.01.2020 diff --git a/camlib.py b/camlib.py index d234dc90..b51be9a8 100644 --- a/camlib.py +++ b/camlib.py @@ -2876,7 +2876,7 @@ class CNCjob(Geometry): # Tool change sequence (optional) if toolchange: - gcode += self.doformat(p.toolchange_code,toolchangexy=(self.oldx, self.oldy)) + gcode += self.doformat(p.toolchange_code, toolchangexy=(self.oldx, self.oldy)) gcode += self.doformat(p.spindle_code) # Spindle start) if self.dwell is True: gcode += self.doformat(p.dwell_code) # Dwell time @@ -3419,7 +3419,7 @@ class CNCjob(Geometry): self.app.inform.emit('[ERROR] %s: %s' % (_("Expected a Geometry, got"), type(geometry))) return 'fail' - log.debug("Generate_from_geometry_2()") + log.debug("Executing camlib.CNCJob.generate_from_geometry_2()") # if solid_geometry is empty raise an exception if not geometry.solid_geometry: @@ -3470,7 +3470,7 @@ class CNCjob(Geometry): return 'fail' # hack: make offset smaller by 0.0000000001 which is insignificant difference but allow the job # to continue - elif -offset == ((c - a) / 2) or -offset == ((d - b) / 2): + elif -offset == ((c - a) / 2) or -offset == ((d - b) / 2): offset_for_use = offset - 0.0000000001 for it in geometry.solid_geometry: @@ -3487,11 +3487,12 @@ class CNCjob(Geometry): flat_geometry = self.flatten(temp_solid_geometry, pathonly=True) log.debug("%d paths" % len(flat_geometry)) - if type(self.app.defaults["geometry_cnctooldia"]) == float: + default_dia = 0.01 + if isinstance(self.app.defaults["geometry_cnctooldia"], float): default_dia = self.app.defaults["geometry_cnctooldia"] else: try: - tools_string = self.defaults["geometry_cnctooldia"].split(",") + tools_string = self.app.defaults["geometry_cnctooldia"].split(",") tools_diameters = [eval(a) for a in tools_string if a != ''] default_dia = tools_diameters[0] if tools_diameters else 0.0 except Exception as e: diff --git a/flatcamEditors/FlatCAMTextEditor.py b/flatcamEditors/FlatCAMTextEditor.py index a8d9eff7..4e1dbe60 100644 --- a/flatcamEditors/FlatCAMTextEditor.py +++ b/flatcamEditors/FlatCAMTextEditor.py @@ -313,7 +313,7 @@ class TextEditor(QtWidgets.QWidget): if qc.hasSelection(): qc.insertText(new) else: - self.ui.code_editor.moveCursor(QtGui.QTextCursor.Start) + self.code_editor.moveCursor(QtGui.QTextCursor.Start) break # Mark end of undo block cursor.endEditBlock() From 7aea33914c995f23842b0d21dba087a801dfc7c8 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 1 Feb 2020 06:59:15 +0200 Subject: [PATCH 064/209] - fixed a division by zero error: fixed #377 --- FlatCAMApp.py | 8 ++++++-- FlatCAMObj.py | 6 +++++- README.md | 1 + flatcamEditors/FlatCAMTextEditor.py | 4 +++- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 14a05111..23340b0c 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -7193,8 +7193,7 @@ class App(QtCore.QObject): # Clear form self.setup_component_editor() - self.inform.emit('%s: %s' % - (_("Object deleted"), name)) + self.inform.emit('%s: %s' % (_("Object deleted"), name)) def on_set_origin(self): """ @@ -7306,6 +7305,11 @@ class App(QtCore.QObject): def worker_task(): with self.proc_container.new(_("Moving to Origin...")): obj_list = self.collection.get_selected() + + if not obj_list: + self.inform.emit('[ERROR_NOTCL] %s' % _("Failed. No object(s) selected...")) + return + xminlist = list() yminlist = list() diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 870003b9..288ae791 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -4756,7 +4756,11 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): return tooldia = float(tool_dia_item.text()) - new_cutz = (tooldia - vdia) / (2 * math.tan(math.radians(half_vangle))) + try: + new_cutz = (tooldia - vdia) / (2 * math.tan(math.radians(half_vangle))) + except ZeroDivisionError: + new_cutz = self.old_cutz + new_cutz = float('%.*f' % (self.decimals, new_cutz)) * -1.0 # this value has to be negative self.ui.cutz_entry.set_value(new_cutz) diff --git a/README.md b/README.md index 513825ac..a324e0e9 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ CAD program, and create G-Code for Isolation routing. - added a new functionality, a variation of Set Origin named Move to Origin. It will move a selection of objects to origin such as the bottom left corner of the bounding box that fit them all is in origin. - fixed some bugs +- fixed a division by zero error: fixed #377 30.01.2020 diff --git a/flatcamEditors/FlatCAMTextEditor.py b/flatcamEditors/FlatCAMTextEditor.py index 4e1dbe60..fe0b847e 100644 --- a/flatcamEditors/FlatCAMTextEditor.py +++ b/flatcamEditors/FlatCAMTextEditor.py @@ -29,6 +29,8 @@ class TextEditor(QtWidgets.QWidget): super().__init__() self.app = app + self.plain_text = plain_text + self.setSizePolicy( QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding @@ -45,7 +47,7 @@ class TextEditor(QtWidgets.QWidget): self.work_editor_layout.setContentsMargins(2, 2, 2, 2) self.t_frame.setLayout(self.work_editor_layout) - if plain_text: + if self.plain_text: self.editor_class = FCTextAreaLineNumber() self.code_editor = self.editor_class.edit From bfd71a81b8a7a0ff30e37fffe667789364322228 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 2 Feb 2020 05:34:26 +0200 Subject: [PATCH 065/209] - fixed issue #376 where the V-Shape parameters from Gerber UI are not transfered to the resulting Geometry object if the 'combine' checkbox is not checked in the Gerber UI --- FlatCAMApp.py | 2 +- FlatCAMObj.py | 174 +++++++++++++++++++++++++++++++++----------------- README.md | 4 ++ 3 files changed, 120 insertions(+), 60 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 23340b0c..b6a695ae 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -141,7 +141,7 @@ class App(QtCore.QObject): # ################## Version and VERSION DATE ############################## # ########################################################################## version = 8.992 - version_date = "2020/01/30" + version_date = "2020/02/12" beta = True engine = '3D' diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 288ae791..9e5dd15d 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -1156,8 +1156,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber): visible=True) self.poly_dict[shape_id] = clicked_poly self.app.inform.emit( - '%s: %d. %s' % (_("Added polygon"), - int(len(self.poly_dict)), + '%s: %d. %s' % (_("Added polygon"), int(len(self.poly_dict)), _("Click to add next polygon or right click to start isolation.")) ) else: @@ -1330,7 +1329,61 @@ class FlatCAMGerber(FlatCAMObj, Gerber): geo_obj.options["cnctooldia"] = str(self.options["isotooldia"]) geo_obj.tool_type = self.ui.tool_type_radio.get_value().upper() - geo_obj.solid_geometry = [] + geo_obj.solid_geometry = list() + + # transfer the Cut Z and Vtip and VAngle values in case that we use the V-Shape tool in Gerber UI + if self.ui.tool_type_radio.get_value() == 'v': + new_cutz = self.ui.cutz_spinner.get_value() + new_vtipdia = self.ui.tipdia_spinner.get_value() + new_vtipangle = self.ui.tipangle_spinner.get_value() + tool_type = 'V' + else: + new_cutz = self.app.defaults['geometry_cutz'] + new_vtipdia = self.app.defaults['geometry_vtipdia'] + new_vtipangle = self.app.defaults['geometry_vtipangle'] + tool_type = 'C1' + + # store here the default data for Geometry Data + default_data = {} + default_data.update({ + "name": iso_name, + "plot": self.app.defaults['geometry_plot'], + "cutz": new_cutz, + "vtipdia": new_vtipdia, + "vtipangle": new_vtipangle, + "travelz": self.app.defaults['geometry_travelz'], + "feedrate": self.app.defaults['geometry_feedrate'], + "feedrate_z": self.app.defaults['geometry_feedrate_z'], + "feedrate_rapid": self.app.defaults['geometry_feedrate_rapid'], + "dwell": self.app.defaults['geometry_dwell'], + "dwelltime": self.app.defaults['geometry_dwelltime'], + "multidepth": self.app.defaults['geometry_multidepth'], + "ppname_g": self.app.defaults['geometry_ppname_g'], + "depthperpass": self.app.defaults['geometry_depthperpass'], + "extracut": self.app.defaults['geometry_extracut'], + "extracut_length": self.app.defaults['geometry_extracut_length'], + "toolchange": self.app.defaults['geometry_toolchange'], + "toolchangez": self.app.defaults['geometry_toolchangez'], + "endz": self.app.defaults['geometry_endz'], + "spindlespeed": self.app.defaults['geometry_spindlespeed'], + "toolchangexy": self.app.defaults['geometry_toolchangexy'], + "startz": self.app.defaults['geometry_startz'] + }) + + geo_obj.tools = dict() + geo_obj.tools['1'] = dict() + geo_obj.tools.update({ + '1': { + 'tooldia': float(self.options["isotooldia"]), + 'offset': 'Path', + 'offset_value': 0.0, + 'type': _('Rough'), + 'tool_type': tool_type, + 'data': default_data, + 'solid_geometry': geo_obj.solid_geometry + } + }) + for i in range(passes): iso_offset = dia * ((2 * i + 1) / 2.0) - (i * overlap * dia) @@ -1344,58 +1397,8 @@ class FlatCAMGerber(FlatCAMObj, Gerber): return 'fail' geo_obj.solid_geometry.append(geom) - # transfer the Cut Z and Vtip and VAngle values in case that we use the V-Shape tool in Gerber UI - if self.ui.tool_type_radio.get_value() == 'v': - new_cutz = self.ui.cutz_spinner.get_value() - new_vtipdia = self.ui.tipdia_spinner.get_value() - new_vtipangle = self.ui.tipangle_spinner.get_value() - tool_type = 'V' - else: - new_cutz = self.app.defaults['geometry_cutz'] - new_vtipdia = self.app.defaults['geometry_vtipdia'] - new_vtipangle = self.app.defaults['geometry_vtipangle'] - tool_type = 'C1' - - # store here the default data for Geometry Data - default_data = {} - default_data.update({ - "name": iso_name, - "plot": self.app.defaults['geometry_plot'], - "cutz": new_cutz, - "vtipdia": new_vtipdia, - "vtipangle": new_vtipangle, - "travelz": self.app.defaults['geometry_travelz'], - "feedrate": self.app.defaults['geometry_feedrate'], - "feedrate_z": self.app.defaults['geometry_feedrate_z'], - "feedrate_rapid": self.app.defaults['geometry_feedrate_rapid'], - "dwell": self.app.defaults['geometry_dwell'], - "dwelltime": self.app.defaults['geometry_dwelltime'], - "multidepth": self.app.defaults['geometry_multidepth'], - "ppname_g": self.app.defaults['geometry_ppname_g'], - "depthperpass": self.app.defaults['geometry_depthperpass'], - "extracut": self.app.defaults['geometry_extracut'], - "extracut_length": self.app.defaults['geometry_extracut_length'], - "toolchange": self.app.defaults['geometry_toolchange'], - "toolchangez": self.app.defaults['geometry_toolchangez'], - "endz": self.app.defaults['geometry_endz'], - "spindlespeed": self.app.defaults['geometry_spindlespeed'], - "toolchangexy": self.app.defaults['geometry_toolchangexy'], - "startz": self.app.defaults['geometry_startz'] - }) - - geo_obj.tools = dict() - geo_obj.tools['1'] = dict() - geo_obj.tools.update({ - '1': { - 'tooldia': float(self.options["isotooldia"]), - 'offset': 'Path', - 'offset_value': 0.0, - 'type': _('Rough'), - 'tool_type': tool_type, - 'data': default_data, - 'solid_geometry': geo_obj.solid_geometry - } - }) + # update the geometry in the tools + geo_obj.tools['1']['solid_geometry'] = geo_obj.solid_geometry # detect if solid_geometry is empty and this require list flattening which is "heavy" # or just looking in the lists (they are one level depth) and if any is not empty @@ -1415,8 +1418,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber): if empty_cnt == len(geo_obj.solid_geometry): raise ValidationError("Empty Geometry", None) else: - app_obj.inform.emit('[success] %s" %s' % - (_("Isolation geometry created"), geo_obj.options["name"])) + app_obj.inform.emit('[success] %s" %s' % (_("Isolation geometry created"), geo_obj.options["name"])) # even if combine is checked, one pass is still single-geo geo_obj.multigeo = True if passes > 1 else False @@ -1470,12 +1472,66 @@ class FlatCAMGerber(FlatCAMObj, Gerber): nr_passes=i) if geom == 'fail': - app_obj.inform.emit('[ERROR_NOTCL] %s' % - _("Isolation geometry could not be generated.")) + app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Isolation geometry could not be generated.")) return 'fail' geo_obj.solid_geometry = geom + # transfer the Cut Z and Vtip and VAngle values in case that we use the V-Shape tool in Gerber UI + # even if the resulting geometry is not multigeo we add the tools dict which will hold the data + # required to be transfered to the Geometry object + if self.ui.tool_type_radio.get_value() == 'v': + new_cutz = self.ui.cutz_spinner.get_value() + new_vtipdia = self.ui.tipdia_spinner.get_value() + new_vtipangle = self.ui.tipangle_spinner.get_value() + tool_type = 'V' + else: + new_cutz = self.app.defaults['geometry_cutz'] + new_vtipdia = self.app.defaults['geometry_vtipdia'] + new_vtipangle = self.app.defaults['geometry_vtipangle'] + tool_type = 'C1' + + # store here the default data for Geometry Data + default_data = {} + default_data.update({ + "name": iso_name, + "plot": self.app.defaults['geometry_plot'], + "cutz": new_cutz, + "vtipdia": new_vtipdia, + "vtipangle": new_vtipangle, + "travelz": self.app.defaults['geometry_travelz'], + "feedrate": self.app.defaults['geometry_feedrate'], + "feedrate_z": self.app.defaults['geometry_feedrate_z'], + "feedrate_rapid": self.app.defaults['geometry_feedrate_rapid'], + "dwell": self.app.defaults['geometry_dwell'], + "dwelltime": self.app.defaults['geometry_dwelltime'], + "multidepth": self.app.defaults['geometry_multidepth'], + "ppname_g": self.app.defaults['geometry_ppname_g'], + "depthperpass": self.app.defaults['geometry_depthperpass'], + "extracut": self.app.defaults['geometry_extracut'], + "extracut_length": self.app.defaults['geometry_extracut_length'], + "toolchange": self.app.defaults['geometry_toolchange'], + "toolchangez": self.app.defaults['geometry_toolchangez'], + "endz": self.app.defaults['geometry_endz'], + "spindlespeed": self.app.defaults['geometry_spindlespeed'], + "toolchangexy": self.app.defaults['geometry_toolchangexy'], + "startz": self.app.defaults['geometry_startz'] + }) + + geo_obj.tools = dict() + geo_obj.tools['1'] = dict() + geo_obj.tools.update({ + '1': { + 'tooldia': float(self.options["isotooldia"]), + 'offset': 'Path', + 'offset_value': 0.0, + 'type': _('Rough'), + 'tool_type': tool_type, + 'data': default_data, + 'solid_geometry': geo_obj.solid_geometry + } + }) + # detect if solid_geometry is empty and this require list flattening which is "heavy" # or just looking in the lists (they are one level depth) and if any is not empty # proceed with object creation, if there are empty and the number of them is the length diff --git a/README.md b/README.md index a324e0e9..dcec7b58 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +2.02.2020 + +- fixed issue #376 where the V-Shape parameters from Gerber UI are not transfered to the resulting Geometry object if the 'combine' checkbox is not checked in the Gerber UI + 31.01.2020 - added a new functionality, a variation of Set Origin named Move to Origin. It will move a selection of objects to origin such as the bottom left corner of the bounding box that fit them all is in origin. From 1be1851ac7cb50b9e4bc016a8d617f3415daa18d Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 2 Feb 2020 05:53:03 +0200 Subject: [PATCH 066/209] - in Excellon UI, if Basic application mode is selected in Preferences, the Plot column 'P' is hidden now because some inexperienced users mistake this column checkboxes for tool selection --- FlatCAMObj.py | 1 + README.md | 1 + 2 files changed, 2 insertions(+) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 9e5dd15d..e9982564 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -2847,6 +2847,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.ui.level.setText('%s' % _('Basic')) self.ui.tools_table.setColumnHidden(4, True) + self.ui.tools_table.setColumnHidden(5, True) self.ui.estartz_label.hide() self.ui.estartz_entry.hide() self.ui.feedrate_rapid_label.hide() diff --git a/README.md b/README.md index dcec7b58..90b2adbe 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 2.02.2020 - fixed issue #376 where the V-Shape parameters from Gerber UI are not transfered to the resulting Geometry object if the 'combine' checkbox is not checked in the Gerber UI +- in Excellon UI, if Basic application mode is selected in Preferences, the Plot column 'P' is hidden now because some inexperienced users mistake this column checkboxes for tool selection 31.01.2020 From c7074d71bafea4d83324ca6cf5316d269e129eb1 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 2 Feb 2020 15:54:09 +0200 Subject: [PATCH 067/209] - fixed an error in Gerber Parser; the initial values for currnet_x, current_y were None but should have been 0.0 - limited the lower limit of angle of V-tip to a value of 1 because 0 makes no sense --- README.md | 2 ++ flatcamGUI/ObjectUI.py | 4 ++-- flatcamGUI/PreferencesUI.py | 6 +++--- flatcamParsers/ParseGerber.py | 8 ++++---- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 90b2adbe..daf74c75 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ CAD program, and create G-Code for Isolation routing. - fixed issue #376 where the V-Shape parameters from Gerber UI are not transfered to the resulting Geometry object if the 'combine' checkbox is not checked in the Gerber UI - in Excellon UI, if Basic application mode is selected in Preferences, the Plot column 'P' is hidden now because some inexperienced users mistake this column checkboxes for tool selection +- fixed an error in Gerber Parser; the initial values for currnet_x, current_y were None but should have been 0.0 +- limited the lower limit of angle of V-tip to a value of 1 because 0 makes no sense 31.01.2020 diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index 6270e332..0b5b251a 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -327,7 +327,7 @@ class GerberObjectUI(ObjectUI): "In degree.") ) self.tipangle_spinner = FCDoubleSpinner() - self.tipangle_spinner.set_range(0, 180) + self.tipangle_spinner.set_range(1, 180) self.tipangle_spinner.set_precision(self.decimals) self.tipangle_spinner.setSingleStep(5) self.tipangle_spinner.setWrapping(True) @@ -1628,7 +1628,7 @@ class GeometryObjectUI(ObjectUI): ) self.tipangle_entry = FCDoubleSpinner() self.tipangle_entry.set_precision(self.decimals) - self.tipangle_entry.set_range(0.0, 180.0) + self.tipangle_entry.set_range(1.0, 180.0) self.tipangle_entry.setSingleStep(1) self.grid3.addWidget(self.tipanglelabel, 2, 0) diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index 57b6b68d..be3e1e20 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -2235,7 +2235,7 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI): "In degree.") ) self.tipangle_spinner = FCSpinner() - self.tipangle_spinner.set_range(0, 180) + self.tipangle_spinner.set_range(1, 180) self.tipangle_spinner.setSingleStep(5) self.tipangle_spinner.setWrapping(True) grid0.addWidget(self.tipanglelabel, 5, 0) @@ -5065,7 +5065,7 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): "In degree.")) self.tipangle_entry = FCDoubleSpinner() self.tipangle_entry.set_precision(self.decimals) - self.tipangle_entry.set_range(-360, 360) + self.tipangle_entry.set_range(1, 180) self.tipangle_entry.setSingleStep(5) self.tipangle_entry.setWrapping(True) @@ -5615,7 +5615,7 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI): "In degree.")) self.tipangle_entry = FCDoubleSpinner() self.tipangle_entry.set_precision(self.decimals) - self.tipangle_entry.set_range(0.0000, 180.0000) + self.tipangle_entry.set_range(1.0000, 180.0000) self.tipangle_entry.setSingleStep(5) self.tipangle_entry.setObjectName(_("V-Tip Angle")) diff --git a/flatcamParsers/ParseGerber.py b/flatcamParsers/ParseGerber.py index 16ce8f37..8acb3482 100644 --- a/flatcamParsers/ParseGerber.py +++ b/flatcamParsers/ParseGerber.py @@ -394,10 +394,10 @@ class Gerber(Geometry): current_operation_code = None # Current coordinates - current_x = None - current_y = None - previous_x = None - previous_y = None + current_x = 0 + current_y = 0 + previous_x = 0 + previous_y = 0 current_d = None From 31c0cd09522eaf13a9ec1c0d0f285793150084c0 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 3 Feb 2020 00:43:38 +0200 Subject: [PATCH 068/209] - small changes in Gerber UI - in Geometry Editor make sure that after an edit is finished (correctly or forced) the QTree in the Editor UI is cleared of items --- README.md | 6 +++-- flatcamEditors/FlatCAMGeoEditor.py | 6 +++++ flatcamGUI/ObjectUI.py | 38 +++++++++++++----------------- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index daf74c75..e05d72fc 100644 --- a/README.md +++ b/README.md @@ -11,10 +11,12 @@ CAD program, and create G-Code for Isolation routing. 2.02.2020 -- fixed issue #376 where the V-Shape parameters from Gerber UI are not transfered to the resulting Geometry object if the 'combine' checkbox is not checked in the Gerber UI +- fixed issue #376 where the V-Shape parameters from Gerber UI are not transferred to the resulting Geometry object if the 'combine' checkbox is not checked in the Gerber UI - in Excellon UI, if Basic application mode is selected in Preferences, the Plot column 'P' is hidden now because some inexperienced users mistake this column checkboxes for tool selection -- fixed an error in Gerber Parser; the initial values for currnet_x, current_y were None but should have been 0.0 +- fixed an error in Gerber Parser; the initial values for current_x, current_y were None but should have been 0.0 - limited the lower limit of angle of V-tip to a value of 1 because 0 makes no sense +- small changes in Gerber UI +- in Geometry Editor make sure that after an edit is finished (correctly or forced) the QTree in the Editor UI is cleared of items 31.01.2020 diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index 0bd67d36..604227b1 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -3627,6 +3627,12 @@ class FlatCAMGeoEditor(QtCore.QObject): if self.fcgeometry: self.fcgeometry.visible = True + # clear the Tree + self.tw.clear() + parent = self.tw.invisibleRootItem() + self.geo_parent = self.tw.addParent( + parent, _('Geometry Elements'), expanded=True, color=QtGui.QColor("#000000"), font=self.geo_font) + # hide the UI self.geo_frame.hide() diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index 0b5b251a..67559194 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -160,8 +160,6 @@ class GerberObjectUI(ObjectUI): ObjectUI.__init__(self, title=_('Gerber Object'), parent=parent, decimals=decimals) self.decimals = decimals - self.custom_box.addWidget(QtWidgets.QLabel('')) - # Plot options grid0 = QtWidgets.QGridLayout() grid0.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) @@ -169,20 +167,10 @@ class GerberObjectUI(ObjectUI): grid0.setColumnStretch(0, 0) grid0.setColumnStretch(1, 1) - # Plot CB - self.plot_cb = FCCheckBox() - self.plot_cb.setToolTip( - _("Plot (show) this object.") - ) - plot_label = QtWidgets.QLabel('%s:' % _("Plot")) - - grid0.addWidget(plot_label, 0, 0) - grid0.addWidget(self.plot_cb, 0, 1) - self.plot_options_label = QtWidgets.QLabel("%s:" % _("Plot Options")) self.plot_options_label.setMinimumWidth(90) - grid0.addWidget(self.plot_options_label, 1, 0) + grid0.addWidget(self.plot_options_label, 0, 0) # Solid CB self.solid_cb = FCCheckBox(label=_('Solid')) @@ -190,7 +178,7 @@ class GerberObjectUI(ObjectUI): _("Solid color polygons.") ) self.solid_cb.setMinimumWidth(50) - grid0.addWidget(self.solid_cb, 1, 1) + grid0.addWidget(self.solid_cb, 0, 1) # Multicolored CB self.multicolored_cb = FCCheckBox(label=_('Multi-Color')) @@ -198,7 +186,14 @@ class GerberObjectUI(ObjectUI): _("Draw polygons in different colors.") ) self.multicolored_cb.setMinimumWidth(55) - grid0.addWidget(self.multicolored_cb, 1, 2) + grid0.addWidget(self.multicolored_cb, 0, 2) + + # Plot CB + self.plot_cb = FCCheckBox('%s' % _("Plot")) + # self.plot_cb.setLayoutDirection(QtCore.Qt.RightToLeft) + self.plot_cb.setToolTip(_("Plot (show) this object.")) + + grid0.addWidget(self.plot_cb, 1, 0, 1, 2) # ## Object name self.name_hlay = QtWidgets.QHBoxLayout() @@ -526,7 +521,7 @@ class GerberObjectUI(ObjectUI): "Clicking this will create the buffered geometry\n" "required for isolation.") ) - grid1.addWidget(self.create_buffer_button, 13, 0, 1, 2) + grid1.addWidget(self.create_buffer_button, 13, 0, 1, 3) self.ohis_iso = OptionalHideInputSection( self.except_cb, @@ -534,7 +529,11 @@ class GerberObjectUI(ObjectUI): logic=True ) - grid1.addWidget(QtWidgets.QLabel(''), 14, 0) + separator_line2 = QtWidgets.QFrame() + separator_line2.setFrameShape(QtWidgets.QFrame.HLine) + separator_line2.setFrameShadow(QtWidgets.QFrame.Sunken) + grid1.addWidget(separator_line2, 14, 0, 1, 3) + # grid1.addWidget(QtWidgets.QLabel(''), 15, 0) # ########################################### # ########## NEW GRID ####################### @@ -681,11 +680,6 @@ class GerberObjectUI(ObjectUI): grid2.addWidget(self.bbrounded_cb, 10, 0) grid2.addWidget(self.generate_bb_button, 10, 1) - separator_line2 = QtWidgets.QFrame() - separator_line2.setFrameShape(QtWidgets.QFrame.HLine) - separator_line2.setFrameShadow(QtWidgets.QFrame.Sunken) - grid2.addWidget(separator_line2, 11, 0, 1, 2) - class ExcellonObjectUI(ObjectUI): """ From 10d4ed512b37a7d43cdcbcf387c754f478839faf Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 3 Feb 2020 02:18:28 +0200 Subject: [PATCH 069/209] - modified Spinbox and DoubleSpinbox Custom UI elements such that they issue a warning status message when the typed value is out of range --- ObjectCollection.py | 2 +- README.md | 4 + flatcamGUI/GUIElements.py | 42 +++++++++- flatcamGUI/ObjectUI.py | 162 ++++++++++++++++++++++---------------- 4 files changed, 136 insertions(+), 74 deletions(-) diff --git a/ObjectCollection.py b/ObjectCollection.py index 799d163c..e0f0bd4c 100644 --- a/ObjectCollection.py +++ b/ObjectCollection.py @@ -504,7 +504,7 @@ class ObjectCollection(QtCore.QAbstractItemModel): name += "_1" obj.options["name"] = name - obj.set_ui(obj.ui_type(decimals=self.app.decimals)) + obj.set_ui(obj.ui_type(app=self.app)) # Required before appending (Qt MVC) group = self.group_items[obj.kind] diff --git a/README.md b/README.md index e05d72fc..2ee1e479 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +3.02.2020 + +- modified Spinbox and DoubleSpinbox Custom UI elements such that they issue a warning status message when the typed value is out of range + 2.02.2020 - fixed issue #376 where the V-Shape parameters from Gerber UI are not transferred to the resulting Geometry object if the 'combine' checkbox is not checked in the Gerber UI diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index b9f17d9e..de4fd34f 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -575,12 +575,16 @@ class EvalEntry2(QtWidgets.QLineEdit): class FCSpinner(QtWidgets.QSpinBox): returnPressed = QtCore.pyqtSignal() + confirmation_signal = QtCore.pyqtSignal(bool, float, float) - def __init__(self, suffix=None, alignment=None, parent=None): + def __init__(self, suffix=None, alignment=None, parent=None, callback=None): super(FCSpinner, self).__init__(parent) self.readyToEdit = True self.editingFinished.connect(self.on_edit_finished) + if callback: + self.confirmation_signal.connect(callback) + self.lineEdit().installEventFilter(self) if suffix: @@ -650,6 +654,21 @@ class FCSpinner(QtWidgets.QSpinBox): return self.setValue(k) + def validate(self, p_str, p_int): + text = p_str + + min_val = self.minimum() + max_val = self.maximum() + try: + if int(text) < min_val or int(text) > max_val: + self.confirmation_signal.emit(False, min_val, max_val) + return QtGui.QValidator.Intermediate, text, p_int + except ValueError: + pass + + self.confirmation_signal.emit(True, min_val, max_val) + return QtGui.QValidator.Acceptable, p_str, p_int + def set_range(self, min_val, max_val): self.setRange(min_val, max_val) @@ -661,12 +680,23 @@ class FCSpinner(QtWidgets.QSpinBox): class FCDoubleSpinner(QtWidgets.QDoubleSpinBox): returnPressed = QtCore.pyqtSignal() + confirmation_signal = QtCore.pyqtSignal(bool, float, float) - def __init__(self, suffix=None, alignment=None, parent=None): + def __init__(self, suffix=None, alignment=None, parent=None, callback=None): + """ + + :param suffix: a char added to the end of the value in the LineEdit; like a '%' or '$' etc + :param alignment: the value is aligned to left or right + :param parent: + :param callback: called when the entered value is outside limits; the min and max value will be passed to it + """ super(FCDoubleSpinner, self).__init__(parent) self.readyToEdit = True self.editingFinished.connect(self.on_edit_finished) + if callback: + self.confirmation_signal.connect(callback) + self.lineEdit().installEventFilter(self) # by default don't allow the minus sign to be entered as the default for QDoubleSpinBox is the positive range @@ -736,11 +766,17 @@ class FCDoubleSpinner(QtWidgets.QDoubleSpinBox): def validate(self, p_str, p_int): text = p_str.replace(',', '.') + + min_val = self.minimum() + max_val = self.maximum() try: - if float(text) < self.minimum() or float(text) > self.maximum(): + if float(text) < min_val or float(text) > max_val: + self.confirmation_signal.emit(False, min_val, max_val) return QtGui.QValidator.Intermediate, text, p_int except ValueError: pass + + self.confirmation_signal.emit(True, min_val, max_val) return QtGui.QValidator.Acceptable, p_str, p_int def get_value(self): diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index 67559194..63c747a4 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -35,11 +35,11 @@ class ObjectUI(QtWidgets.QWidget): put UI elements in ObjectUI.custom_box (QtWidgets.QLayout). """ - def __init__(self, icon_file='share/flatcam_icon32.png', title=_('FlatCAM Object'), parent=None, common=True, - decimals=4): + def __init__(self, app, icon_file='share/flatcam_icon32.png', title=_('FlatCAM Object'), parent=None, common=True): QtWidgets.QWidget.__init__(self, parent=parent) - - self.decimals = decimals + + self.app = app + self.decimals = app.decimals theme_settings = QtCore.QSettings("Open Source", "FlatCAM") if theme_settings.contains("theme"): @@ -149,6 +149,20 @@ class ObjectUI(QtWidgets.QWidget): self.common_grid.addWidget(self.offset_button, 4, 1) layout.addStretch() + + def confirmation_message(self, accepted, minval, maxval): + if accepted is False: + self.app.inform.emit('[WARNING_NOTCL] %s: [%.*f, %.*f]' % + (_("Edited value is out of range"), self.decimals, minval, self.decimals, maxval)) + else: + self.app.inform.emit('[success] %s' % _("Edited value is within limits.")) + + def confirmation_message_int(self, accepted, minval, maxval): + if accepted is False: + self.app.inform.emit('[WARNING_NOTCL] %s: [%d, %d]' % + (_("Edited value is out of range"), minval, maxval)) + else: + self.app.inform.emit('[success] %s' % _("Edited value is within limits.")) class GerberObjectUI(ObjectUI): @@ -156,9 +170,11 @@ class GerberObjectUI(ObjectUI): User interface for Gerber objects. """ - def __init__(self, decimals, parent=None): - ObjectUI.__init__(self, title=_('Gerber Object'), parent=parent, decimals=decimals) - self.decimals = decimals + def __init__(self, app, parent=None): + self.decimals = app.decimals + self.app = app + + ObjectUI.__init__(self, title=_('Gerber Object'), parent=parent, app=self.app) # Plot options grid0 = QtWidgets.QGridLayout() @@ -307,7 +323,7 @@ class GerberObjectUI(ObjectUI): self.tipdialabel.setToolTip( _("The tip diameter for V-Shape Tool") ) - self.tipdia_spinner = FCDoubleSpinner() + self.tipdia_spinner = FCDoubleSpinner(callback=self.confirmation_message) self.tipdia_spinner.set_range(-99.9999, 99.9999) self.tipdia_spinner.set_precision(self.decimals) self.tipdia_spinner.setSingleStep(0.1) @@ -321,7 +337,7 @@ class GerberObjectUI(ObjectUI): _("The tip angle for V-Shape Tool.\n" "In degree.") ) - self.tipangle_spinner = FCDoubleSpinner() + self.tipangle_spinner = FCDoubleSpinner(callback=self.confirmation_message) self.tipangle_spinner.set_range(1, 180) self.tipangle_spinner.set_precision(self.decimals) self.tipangle_spinner.setSingleStep(5) @@ -335,7 +351,7 @@ class GerberObjectUI(ObjectUI): _("Cutting depth (negative)\n" "below the copper surface.") ) - self.cutz_spinner = FCDoubleSpinner() + self.cutz_spinner = FCDoubleSpinner(callback=self.confirmation_message) self.cutz_spinner.set_range(-9999.9999, 0.0000) self.cutz_spinner.set_precision(self.decimals) self.cutz_spinner.setSingleStep(0.1) @@ -353,7 +369,7 @@ class GerberObjectUI(ObjectUI): "this parameter.") ) tdlabel.setMinimumWidth(90) - self.iso_tool_dia_entry = FCDoubleSpinner() + self.iso_tool_dia_entry = FCDoubleSpinner(callback=self.confirmation_message) self.iso_tool_dia_entry.set_range(-9999.9999, 9999.9999) self.iso_tool_dia_entry.set_precision(self.decimals) self.iso_tool_dia_entry.setSingleStep(0.1) @@ -368,7 +384,7 @@ class GerberObjectUI(ObjectUI): "number (integer) of tool widths.") ) passlabel.setMinimumWidth(90) - self.iso_width_entry = FCSpinner() + self.iso_width_entry = FCSpinner(callback=self.confirmation_message_int) self.iso_width_entry.set_range(1, 999) grid1.addWidget(passlabel, 5, 0) grid1.addWidget(self.iso_width_entry, 5, 1, 1, 2) @@ -379,7 +395,7 @@ class GerberObjectUI(ObjectUI): _("How much (percentage) of the tool width to overlap each tool pass.") ) overlabel.setMinimumWidth(90) - self.iso_overlap_entry = FCDoubleSpinner(suffix='%') + self.iso_overlap_entry = FCDoubleSpinner(suffix='%', callback=self.confirmation_message) self.iso_overlap_entry.set_precision(self.decimals) self.iso_overlap_entry.setWrapping(True) self.iso_overlap_entry.set_range(0.0000, 99.9999) @@ -617,7 +633,7 @@ class GerberObjectUI(ObjectUI): "distance.") ) bmlabel.setMinimumWidth(90) - self.noncopper_margin_entry = FCDoubleSpinner() + self.noncopper_margin_entry = FCDoubleSpinner(callback=self.confirmation_message) self.noncopper_margin_entry.set_range(-9999.9999, 9999.9999) self.noncopper_margin_entry.set_precision(self.decimals) self.noncopper_margin_entry.setSingleStep(0.1) @@ -656,7 +672,7 @@ class GerberObjectUI(ObjectUI): "to the nearest polygon.") ) bbmargin.setMinimumWidth(90) - self.bbmargin_entry = FCDoubleSpinner() + self.bbmargin_entry = FCDoubleSpinner(callback=self.confirmation_message) self.bbmargin_entry.set_range(-9999.9999, 9999.9999) self.bbmargin_entry.set_precision(self.decimals) self.bbmargin_entry.setSingleStep(0.1) @@ -686,7 +702,10 @@ class ExcellonObjectUI(ObjectUI): User interface for Excellon objects. """ - def __init__(self, decimals, parent=None): + def __init__(self, app, parent=None): + + self.decimals = app.decimals + self.app = app theme_settings = QtCore.QSettings("Open Source", "FlatCAM") if theme_settings.contains("theme"): @@ -702,9 +721,7 @@ class ExcellonObjectUI(ObjectUI): ObjectUI.__init__(self, title=_('Excellon Object'), icon_file=self.resource_loc + '/drill32.png', parent=parent, - decimals=decimals) - - self.decimals = decimals + app=self.app) # ### Plot options #### hlay_plot = QtWidgets.QHBoxLayout() @@ -870,7 +887,7 @@ class ExcellonObjectUI(ObjectUI): _("The diameter of the tool who will do the milling") ) - self.mill_dia_entry = FCDoubleSpinner() + self.mill_dia_entry = FCDoubleSpinner(callback=self.confirmation_message) self.mill_dia_entry.set_precision(self.decimals) self.mill_dia_entry.set_range(0.0000, 9999.9999) @@ -884,7 +901,7 @@ class ExcellonObjectUI(ObjectUI): "below the copper surface.") ) - self.cutz_entry = FCDoubleSpinner() + self.cutz_entry = FCDoubleSpinner(callback=self.confirmation_message) self.cutz_entry.set_precision(self.decimals) if machinist_setting == 0: @@ -908,7 +925,7 @@ class ExcellonObjectUI(ObjectUI): ) ) - self.maxdepth_entry = FCDoubleSpinner() + self.maxdepth_entry = FCDoubleSpinner(callback=self.confirmation_message) self.maxdepth_entry.set_precision(self.decimals) self.maxdepth_entry.set_range(0, 9999.9999) self.maxdepth_entry.setSingleStep(0.1) @@ -930,7 +947,7 @@ class ExcellonObjectUI(ObjectUI): "across the XY plane.") ) - self.travelz_entry = FCDoubleSpinner() + self.travelz_entry = FCDoubleSpinner(callback=self.confirmation_message) self.travelz_entry.set_precision(self.decimals) if machinist_setting == 0: @@ -950,7 +967,7 @@ class ExcellonObjectUI(ObjectUI): "in G-Code (Pause for tool change).") ) - self.toolchangez_entry = FCDoubleSpinner() + self.toolchangez_entry = FCDoubleSpinner(callback=self.confirmation_message) self.toolchangez_entry.set_precision(self.decimals) self.toolchangez_entry.setToolTip( _("Z-axis position (height) for\n" @@ -984,7 +1001,7 @@ class ExcellonObjectUI(ObjectUI): _("Height of the tool after\n" "the last move at the end of the job.") ) - self.eendz_entry = FCDoubleSpinner() + self.eendz_entry = FCDoubleSpinner(callback=self.confirmation_message) self.eendz_entry.set_precision(self.decimals) if machinist_setting == 0: @@ -1003,7 +1020,7 @@ class ExcellonObjectUI(ObjectUI): _("Cutting speed in the XY\n" "plane in units per minute") ) - self.xyfeedrate_entry = FCDoubleSpinner() + self.xyfeedrate_entry = FCDoubleSpinner(callback=self.confirmation_message) self.xyfeedrate_entry.set_precision(self.decimals) self.xyfeedrate_entry.set_range(0, 9999.9999) self.xyfeedrate_entry.setSingleStep(0.1) @@ -1019,7 +1036,7 @@ class ExcellonObjectUI(ObjectUI): "So called 'Plunge' feedrate.\n" "This is for linear move G01.") ) - self.feedrate_entry = FCDoubleSpinner() + self.feedrate_entry = FCDoubleSpinner(callback=self.confirmation_message) self.feedrate_entry.set_precision(self.decimals) self.feedrate_entry.set_range(0.0, 9999.9999) self.feedrate_entry.setSingleStep(0.1) @@ -1036,7 +1053,7 @@ class ExcellonObjectUI(ObjectUI): "It is useful only for Marlin,\n" "ignore for any other cases.") ) - self.feedrate_rapid_entry = FCDoubleSpinner() + self.feedrate_rapid_entry = FCDoubleSpinner(callback=self.confirmation_message) self.feedrate_rapid_entry.set_precision(self.decimals) self.feedrate_rapid_entry.set_range(0.0, 9999.9999) self.feedrate_rapid_entry.setSingleStep(0.1) @@ -1057,7 +1074,7 @@ class ExcellonObjectUI(ObjectUI): "extended cut over the first cut section.") ) - self.e_cut_entry = FCDoubleSpinner() + self.e_cut_entry = FCDoubleSpinner(callback=self.confirmation_message) self.e_cut_entry.set_range(0, 99999) self.e_cut_entry.set_precision(self.decimals) self.e_cut_entry.setSingleStep(0.1) @@ -1081,7 +1098,7 @@ class ExcellonObjectUI(ObjectUI): "in RPM (optional)") ) - self.spindlespeed_entry = FCSpinner() + self.spindlespeed_entry = FCSpinner(callback=self.confirmation_message_int) self.spindlespeed_entry.set_range(0, 1000000) self.spindlespeed_entry.setSingleStep(100) @@ -1094,7 +1111,7 @@ class ExcellonObjectUI(ObjectUI): _("Pause to allow the spindle to reach its\n" "speed before cutting.") ) - self.dwelltime_entry = FCDoubleSpinner() + self.dwelltime_entry = FCDoubleSpinner(callback=self.confirmation_message) self.dwelltime_entry.set_precision(self.decimals) self.dwelltime_entry.set_range(0.0, 9999.9999) self.dwelltime_entry.setSingleStep(0.1) @@ -1115,7 +1132,7 @@ class ExcellonObjectUI(ObjectUI): "to probe. Negative value, in current units.") ) - self.pdepth_entry = FCDoubleSpinner() + self.pdepth_entry = FCDoubleSpinner(callback=self.confirmation_message) self.pdepth_entry.set_precision(self.decimals) self.pdepth_entry.set_range(-9999.9999, 9999.9999) self.pdepth_entry.setSingleStep(0.1) @@ -1132,7 +1149,7 @@ class ExcellonObjectUI(ObjectUI): _("The feedrate used while the probe is probing.") ) - self.feedrate_probe_entry = FCDoubleSpinner() + self.feedrate_probe_entry = FCDoubleSpinner(callback=self.confirmation_message) self.feedrate_probe_entry.set_precision(self.decimals) self.feedrate_probe_entry.set_range(0.0, 9999.9999) self.feedrate_probe_entry.setSingleStep(0.1) @@ -1151,7 +1168,7 @@ class ExcellonObjectUI(ObjectUI): "The value here can compensate the Cut Z parameter.") ) - self.offset_entry = FCDoubleSpinner() + self.offset_entry = FCDoubleSpinner(callback=self.confirmation_message) self.offset_entry.set_precision(self.decimals) self.offset_entry.set_range(-9999.9999, 9999.9999) @@ -1291,7 +1308,7 @@ class ExcellonObjectUI(ObjectUI): self.grid6.addWidget(self.tdlabel, 6, 0, 1, 3) - self.tooldia_entry = FCDoubleSpinner() + self.tooldia_entry = FCDoubleSpinner(callback=self.confirmation_message) self.tooldia_entry.set_precision(self.decimals) self.tooldia_entry.set_range(0.0, 9999.9999) self.tooldia_entry.setSingleStep(0.1) @@ -1311,7 +1328,7 @@ class ExcellonObjectUI(ObjectUI): self.grid6.addWidget(self.tooldia_entry, 7, 0, 1, 2) self.grid6.addWidget(self.generate_milling_button, 7, 2) - self.slot_tooldia_entry = FCDoubleSpinner() + self.slot_tooldia_entry = FCDoubleSpinner(callback=self.confirmation_message) self.slot_tooldia_entry.set_precision(self.decimals) self.slot_tooldia_entry.set_range(0.0, 9999.9999) self.slot_tooldia_entry.setSingleStep(0.1) @@ -1343,7 +1360,10 @@ class GeometryObjectUI(ObjectUI): User interface for Geometry objects. """ - def __init__(self, decimals, parent=None): + def __init__(self, app, parent=None): + + self.decimals = app.decimals + self.app = app theme_settings = QtCore.QSettings("Open Source", "FlatCAM") if theme_settings.contains("theme"): @@ -1358,11 +1378,9 @@ class GeometryObjectUI(ObjectUI): super(GeometryObjectUI, self).__init__( title=_('Geometry Object'), - icon_file=self.resource_loc + '/geometry32.png', parent=parent, decimals=decimals + icon_file=self.resource_loc + '/geometry32.png', parent=parent, app=self.app ) - self.decimals = decimals - # Plot options self.plot_options_label = QtWidgets.QLabel("%s:" % _("Plot Options")) self.custom_box.addWidget(self.plot_options_label) @@ -1492,7 +1510,7 @@ class GeometryObjectUI(ObjectUI): "cut and negative for 'inside' cut." ) ) - self.tool_offset_entry = FCDoubleSpinner() + self.tool_offset_entry = FCDoubleSpinner(callback=self.confirmation_message) self.tool_offset_entry.set_precision(self.decimals) self.tool_offset_entry.set_range(-9999.9999, 9999.9999) self.tool_offset_entry.setSingleStep(0.1) @@ -1512,7 +1530,7 @@ class GeometryObjectUI(ObjectUI): self.addtool_entry_lbl.setToolTip( _("Diameter for the new tool") ) - self.addtool_entry = FCDoubleSpinner() + self.addtool_entry = FCDoubleSpinner(callback=self.confirmation_message) self.addtool_entry.set_precision(self.decimals) self.addtool_entry.set_range(0.00001, 9999.9999) self.addtool_entry.setSingleStep(0.1) @@ -1604,7 +1622,7 @@ class GeometryObjectUI(ObjectUI): "The tip diameter for V-Shape Tool" ) ) - self.tipdia_entry = FCDoubleSpinner() + self.tipdia_entry = FCDoubleSpinner(callback=self.confirmation_message) self.tipdia_entry.set_precision(self.decimals) self.tipdia_entry.set_range(0.00001, 9999.9999) self.tipdia_entry.setSingleStep(0.1) @@ -1620,7 +1638,7 @@ class GeometryObjectUI(ObjectUI): "In degree." ) ) - self.tipangle_entry = FCDoubleSpinner() + self.tipangle_entry = FCDoubleSpinner(callback=self.confirmation_message) self.tipangle_entry.set_precision(self.decimals) self.tipangle_entry.set_range(1.0, 180.0) self.tipangle_entry.setSingleStep(1) @@ -1636,7 +1654,7 @@ class GeometryObjectUI(ObjectUI): "below the copper surface." ) ) - self.cutz_entry = FCDoubleSpinner() + self.cutz_entry = FCDoubleSpinner(callback=self.confirmation_message) self.cutz_entry.set_precision(self.decimals) if machinist_setting == 0: @@ -1660,7 +1678,7 @@ class GeometryObjectUI(ObjectUI): ) ) - self.maxdepth_entry = FCDoubleSpinner() + self.maxdepth_entry = FCDoubleSpinner(callback=self.confirmation_message) self.maxdepth_entry.set_precision(self.decimals) self.maxdepth_entry.set_range(0, 9999.9999) self.maxdepth_entry.setSingleStep(0.1) @@ -1681,7 +1699,7 @@ class GeometryObjectUI(ObjectUI): _("Height of the tool when\n" "moving without cutting.") ) - self.travelz_entry = FCDoubleSpinner() + self.travelz_entry = FCDoubleSpinner(callback=self.confirmation_message) self.travelz_entry.set_precision(self.decimals) if machinist_setting == 0: @@ -1702,7 +1720,7 @@ class GeometryObjectUI(ObjectUI): "in the Machine Code (Pause for tool change)." ) ) - self.toolchangez_entry = FCDoubleSpinner() + self.toolchangez_entry = FCDoubleSpinner(callback=self.confirmation_message) self.toolchangez_entry.set_precision(self.decimals) self.toolchangez_entry.setToolTip( _( @@ -1739,7 +1757,7 @@ class GeometryObjectUI(ObjectUI): _("Height of the tool after\n" "the last move at the end of the job.") ) - self.gendz_entry = FCDoubleSpinner() + self.gendz_entry = FCDoubleSpinner(callback=self.confirmation_message) self.gendz_entry.set_precision(self.decimals) if machinist_setting == 0: @@ -1758,7 +1776,7 @@ class GeometryObjectUI(ObjectUI): _("Cutting speed in the XY\n" "plane in units per minute") ) - self.cncfeedrate_entry = FCDoubleSpinner() + self.cncfeedrate_entry = FCDoubleSpinner(callback=self.confirmation_message) self.cncfeedrate_entry.set_precision(self.decimals) self.cncfeedrate_entry.set_range(0, 9999.9999) self.cncfeedrate_entry.setSingleStep(0.1) @@ -1773,7 +1791,7 @@ class GeometryObjectUI(ObjectUI): "plane in units per minute.\n" "It is called also Plunge.") ) - self.cncplunge_entry = FCDoubleSpinner() + self.cncplunge_entry = FCDoubleSpinner(callback=self.confirmation_message) self.cncplunge_entry.set_precision(self.decimals) self.cncplunge_entry.set_range(0, 9999.9999) self.cncplunge_entry.setSingleStep(0.1) @@ -1790,7 +1808,7 @@ class GeometryObjectUI(ObjectUI): "It is useful only for Marlin,\n" "ignore for any other cases.") ) - self.cncfeedrate_rapid_entry = FCDoubleSpinner() + self.cncfeedrate_rapid_entry = FCDoubleSpinner(callback=self.confirmation_message) self.cncfeedrate_rapid_entry.set_precision(self.decimals) self.cncfeedrate_rapid_entry.set_range(0, 9999.9999) self.cncfeedrate_rapid_entry.setSingleStep(0.1) @@ -1810,7 +1828,7 @@ class GeometryObjectUI(ObjectUI): "extended cut over the first cut section.") ) - self.e_cut_entry = FCDoubleSpinner() + self.e_cut_entry = FCDoubleSpinner(callback=self.confirmation_message) self.e_cut_entry.set_range(0, 99999) self.e_cut_entry.set_precision(self.decimals) self.e_cut_entry.setSingleStep(0.1) @@ -1833,7 +1851,7 @@ class GeometryObjectUI(ObjectUI): "this value is the power of laser." ) ) - self.cncspindlespeed_entry = FCSpinner() + self.cncspindlespeed_entry = FCSpinner(callback=self.confirmation_message_int) self.cncspindlespeed_entry.set_range(0, 1000000) self.cncspindlespeed_entry.setSingleStep(100) @@ -1848,7 +1866,7 @@ class GeometryObjectUI(ObjectUI): "speed before cutting." ) ) - self.dwelltime_entry = FCDoubleSpinner() + self.dwelltime_entry = FCDoubleSpinner(callback=self.confirmation_message) self.dwelltime_entry.set_precision(self.decimals) self.dwelltime_entry.set_range(0, 9999.9999) self.dwelltime_entry.setSingleStep(0.1) @@ -1867,7 +1885,7 @@ class GeometryObjectUI(ObjectUI): _("The maximum depth that the probe is allowed\n" "to probe. Negative value, in current units.") ) - self.pdepth_entry = FCDoubleSpinner() + self.pdepth_entry = FCDoubleSpinner(callback=self.confirmation_message) self.pdepth_entry.set_precision(self.decimals) self.pdepth_entry.set_range(-9999.9999, 9999.9999) self.pdepth_entry.setSingleStep(0.1) @@ -1883,7 +1901,7 @@ class GeometryObjectUI(ObjectUI): self.feedrate_probe_label.setToolTip( _("The feedrate used while the probe is probing.") ) - self.feedrate_probe_entry = FCDoubleSpinner() + self.feedrate_probe_entry = FCDoubleSpinner(callback=self.confirmation_message) self.feedrate_probe_entry.set_precision(self.decimals) self.feedrate_probe_entry.set_range(0.0, 9999.9999) self.feedrate_probe_entry.setSingleStep(0.1) @@ -2010,12 +2028,15 @@ class CNCObjectUI(ObjectUI): User interface for CNCJob objects. """ - def __init__(self, decimals, parent=None): + def __init__(self, app, parent=None): """ Creates the user interface for CNCJob objects. GUI elements should be placed in ``self.custom_box`` to preserve the layout. """ + self.decimals = app.decimals + self.app = app + theme_settings = QtCore.QSettings("Open Source", "FlatCAM") if theme_settings.contains("theme"): theme = theme_settings.value('theme', type=str) @@ -2030,8 +2051,7 @@ class CNCObjectUI(ObjectUI): ObjectUI.__init__( self, title=_('CNC Job Object'), icon_file=self.resource_loc + '/cnc32.png', parent=parent, - decimals=decimals) - self.decimals = decimals + app=self.app) for i in range(0, self.common_grid.count()): self.common_grid.itemAt(i).widget().hide() @@ -2172,7 +2192,7 @@ class CNCObjectUI(ObjectUI): _('P')]) self.exc_cnc_tools_table.setColumnHidden(4, True) - self.tooldia_entry = FCDoubleSpinner() + self.tooldia_entry = FCDoubleSpinner(callback=self.confirmation_message) self.tooldia_entry.set_range(0, 9999.9999) self.tooldia_entry.set_precision(self.decimals) self.tooldia_entry.setSingleStep(0.1) @@ -2341,12 +2361,15 @@ class ScriptObjectUI(ObjectUI): User interface for Script objects. """ - def __init__(self, decimals, parent=None): + def __init__(self, app, parent=None): """ Creates the user interface for Script objects. GUI elements should be placed in ``self.custom_box`` to preserve the layout. """ + self.decimals = app.decimals + self.app = app + theme_settings = QtCore.QSettings("Open Source", "FlatCAM") if theme_settings.contains("theme"): theme = theme_settings.value('theme', type=str) @@ -2362,9 +2385,7 @@ class ScriptObjectUI(ObjectUI): icon_file=self.resource_loc + '/script_new24.png', parent=parent, common=False, - decimals=decimals) - - self.decimals = decimals + app=self.app) # ## Object name self.name_hlay = QtWidgets.QHBoxLayout() @@ -2407,12 +2428,15 @@ class DocumentObjectUI(ObjectUI): User interface for Notes objects. """ - def __init__(self, decimals, parent=None): + def __init__(self, app, parent=None): """ Creates the user interface for Notes objects. GUI elements should be placed in ``self.custom_box`` to preserve the layout. """ + self.decimals = app.decimals + self.app = app + theme_settings = QtCore.QSettings("Open Source", "FlatCAM") if theme_settings.contains("theme"): theme = theme_settings.value('theme', type=str) @@ -2428,9 +2452,7 @@ class DocumentObjectUI(ObjectUI): icon_file=self.resource_loc + '/notes16_1.png', parent=parent, common=False, - decimals=decimals) - - self.decimals = decimals + app=self.app) # ## Object name self.name_hlay = QtWidgets.QHBoxLayout() @@ -2589,7 +2611,7 @@ class DocumentObjectUI(ObjectUI): self.tab_size_label.setToolTip( _("Set the tab size. In pixels. Default value is 80 pixels.") ) - self.tab_size_spinner = FCSpinner() + self.tab_size_spinner = FCSpinner(callback=self.confirmation_message_int) self.tab_size_spinner.set_range(0, 1000) self.form_box.addRow(self.tab_size_label, self.tab_size_spinner) From 23a1495c328122018445827abc216920dccff256 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 3 Feb 2020 14:46:39 +0200 Subject: [PATCH 070/209] - fixed the preprocessors with 'laser' in the name to use the spindle direction set in the Preferences - increased the upper limit for feedrates by an order of magnitude --- README.md | 2 ++ camlib.py | 10 ++++++---- flatcamGUI/ObjectUI.py | 10 +++++----- flatcamGUI/PreferencesUI.py | 22 +++++++++++----------- flatcamTools/ToolSolderPaste.py | 18 +++++++++--------- preprocessors/default.py | 10 +++++----- preprocessors/grbl_laser.py | 5 +++-- 7 files changed, 41 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 2ee1e479..e50d47be 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ CAD program, and create G-Code for Isolation routing. 3.02.2020 - modified Spinbox and DoubleSpinbox Custom UI elements such that they issue a warning status message when the typed value is out of range +- fixed the preprocessors with 'laser' in the name to use the spindle direction set in the Preferences +- increased the upper limit for feedrates by an order of magnitude 2.02.2020 diff --git a/camlib.py b/camlib.py index b51be9a8..9eaa8ab8 100644 --- a/camlib.py +++ b/camlib.py @@ -3105,7 +3105,9 @@ class CNCjob(Geometry): :param feedrate_z: :param feedrate_rapid: :param spindlespeed: - :param spindledir: + :param spindledir: Direction of rotation for the spindle. If using GRBL laser mode will + adjust the laser mode + :param dwell: :param dwelltime: :param multidepth: If True, use multiple passes to reach the desired depth. @@ -4055,14 +4057,14 @@ class CNCjob(Geometry): else: command['Z'] = 0 - elif 'grbl_laser' in self.pp_excellon_name or 'grbl_laser' in self.pp_geometry_name or \ - (self.pp_solderpaste_name is not None and 'Paste' in self.pp_solderpaste_name): + elif 'laser' in self.pp_excellon_name.lower() or 'laser' in self.pp_geometry_name.lower() or \ + (self.pp_solderpaste_name is not None and 'paste' in self.pp_solderpaste_name.lower()): match_lsr = re.search(r"X([\+-]?\d+.[\+-]?\d+)\s*Y([\+-]?\d+.[\+-]?\d+)", gline) if match_lsr: command['X'] = float(match_lsr.group(1).replace(" ", "")) command['Y'] = float(match_lsr.group(2).replace(" ", "")) - match_lsr_pos = re.search(r"^(M0[3|5])", gline) + match_lsr_pos = re.search(r"^(M0[3-5])", gline) if match_lsr_pos: if 'M05' in match_lsr_pos.group(1): # the value does not matter, only that it is positive so the gcode_parse() know it is > 0, diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index 63c747a4..ed9863ae 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -1038,7 +1038,7 @@ class ExcellonObjectUI(ObjectUI): ) self.feedrate_entry = FCDoubleSpinner(callback=self.confirmation_message) self.feedrate_entry.set_precision(self.decimals) - self.feedrate_entry.set_range(0.0, 9999.9999) + self.feedrate_entry.set_range(0.0, 99999.9999) self.feedrate_entry.setSingleStep(0.1) self.grid3.addWidget(frlabel, 14, 0) @@ -1055,7 +1055,7 @@ class ExcellonObjectUI(ObjectUI): ) self.feedrate_rapid_entry = FCDoubleSpinner(callback=self.confirmation_message) self.feedrate_rapid_entry.set_precision(self.decimals) - self.feedrate_rapid_entry.set_range(0.0, 9999.9999) + self.feedrate_rapid_entry.set_range(0.0, 99999.9999) self.feedrate_rapid_entry.setSingleStep(0.1) self.grid3.addWidget(self.feedrate_rapid_label, 16, 0) @@ -1778,7 +1778,7 @@ class GeometryObjectUI(ObjectUI): ) self.cncfeedrate_entry = FCDoubleSpinner(callback=self.confirmation_message) self.cncfeedrate_entry.set_precision(self.decimals) - self.cncfeedrate_entry.set_range(0, 9999.9999) + self.cncfeedrate_entry.set_range(0, 99999.9999) self.cncfeedrate_entry.setSingleStep(0.1) self.grid3.addWidget(frlabel, 10, 0) @@ -1793,7 +1793,7 @@ class GeometryObjectUI(ObjectUI): ) self.cncplunge_entry = FCDoubleSpinner(callback=self.confirmation_message) self.cncplunge_entry.set_precision(self.decimals) - self.cncplunge_entry.set_range(0, 9999.9999) + self.cncplunge_entry.set_range(0, 99999.9999) self.cncplunge_entry.setSingleStep(0.1) self.grid3.addWidget(frzlabel, 11, 0) @@ -1810,7 +1810,7 @@ class GeometryObjectUI(ObjectUI): ) self.cncfeedrate_rapid_entry = FCDoubleSpinner(callback=self.confirmation_message) self.cncfeedrate_rapid_entry.set_precision(self.decimals) - self.cncfeedrate_rapid_entry.set_range(0, 9999.9999) + self.cncfeedrate_rapid_entry.set_range(0, 99999.9999) self.cncfeedrate_rapid_entry.setSingleStep(0.1) self.grid3.addWidget(self.fr_rapidlabel, 12, 0) diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index be3e1e20..cde679cf 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -3154,7 +3154,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): ) self.feedrate_entry = FCDoubleSpinner() self.feedrate_entry.set_precision(self.decimals) - self.feedrate_entry.set_range(0, 999) + self.feedrate_entry.set_range(0, 99999.9999) grid2.addWidget(frlabel, 5, 0) grid2.addWidget(self.feedrate_entry, 5, 1) @@ -3316,7 +3316,7 @@ class ExcellonAdvOptPrefGroupUI(OptionsGroupUI): ) self.feedrate_rapid_entry = FCDoubleSpinner() self.feedrate_rapid_entry.set_precision(self.decimals) - self.feedrate_rapid_entry.set_range(0, 9999999.9999) + self.feedrate_rapid_entry.set_range(0, 99999.9999) grid1.addWidget(fr_rapid_label, 3, 0) grid1.addWidget(self.feedrate_rapid_entry, 3, 1) @@ -3341,7 +3341,7 @@ class ExcellonAdvOptPrefGroupUI(OptionsGroupUI): ) self.feedrate_probe_entry = FCDoubleSpinner() self.feedrate_probe_entry.set_precision(self.decimals) - self.feedrate_probe_entry.set_range(0, 9999999.9999) + self.feedrate_probe_entry.set_range(0, 99999.9999) grid1.addWidget(self.feedrate_probe_label, 5, 0) grid1.addWidget(self.feedrate_probe_entry, 5, 1) @@ -4081,7 +4081,7 @@ class GeometryOptPrefGroupUI(OptionsGroupUI): "plane in units per minute") ) self.cncfeedrate_entry = FCDoubleSpinner() - self.cncfeedrate_entry.set_range(0, 99999) + self.cncfeedrate_entry.set_range(0, 99999.9999) self.cncfeedrate_entry.set_precision(self.decimals) self.cncfeedrate_entry.setSingleStep(0.1) self.cncfeedrate_entry.setWrapping(True) @@ -4097,7 +4097,7 @@ class GeometryOptPrefGroupUI(OptionsGroupUI): "It is called also Plunge.") ) self.cncplunge_entry = FCDoubleSpinner() - self.cncplunge_entry.set_range(0, 99999) + self.cncplunge_entry.set_range(0, 99999.9999) self.cncplunge_entry.set_precision(self.decimals) self.cncplunge_entry.setSingleStep(0.1) self.cncplunge_entry.setWrapping(True) @@ -4208,7 +4208,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI): "ignore for any other cases.") ) self.cncfeedrate_rapid_entry = FCDoubleSpinner() - self.cncfeedrate_rapid_entry.set_range(0, 99999) + self.cncfeedrate_rapid_entry.set_range(0, 99999.9999) self.cncfeedrate_rapid_entry.set_precision(self.decimals) self.cncfeedrate_rapid_entry.setSingleStep(0.1) self.cncfeedrate_rapid_entry.setWrapping(True) @@ -4260,7 +4260,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI): _("The feedrate used while the probe is probing.") ) self.feedrate_probe_entry = FCDoubleSpinner() - self.feedrate_probe_entry.set_range(0, 99999) + self.feedrate_probe_entry.set_range(0, 99999.9999) self.feedrate_probe_entry.set_precision(self.decimals) self.feedrate_probe_entry.setSingleStep(0.1) self.feedrate_probe_entry.setWrapping(True) @@ -6709,7 +6709,7 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI): # Feedrate X-Y self.frxy_entry = FCDoubleSpinner() self.frxy_entry.set_precision(self.decimals) - self.frxy_entry.set_range(0.0000001, 9999.9999) + self.frxy_entry.set_range(0.0000001, 99999.9999) self.frxy_entry.setSingleStep(0.1) self.frxy_label = QtWidgets.QLabel('%s:' % _("Feedrate X-Y")) @@ -6722,7 +6722,7 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI): # Feedrate Z self.frz_entry = FCDoubleSpinner() self.frz_entry.set_precision(self.decimals) - self.frz_entry.set_range(0.0000001, 9999.9999) + self.frz_entry.set_range(0.0000001, 99999.9999) self.frz_entry.setSingleStep(0.1) self.frz_label = QtWidgets.QLabel('%s:' % _("Feedrate Z")) @@ -6736,7 +6736,7 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI): # Feedrate Z Dispense self.frz_dispense_entry = FCDoubleSpinner() self.frz_dispense_entry.set_precision(self.decimals) - self.frz_dispense_entry.set_range(0.0000001, 9999.9999) + self.frz_dispense_entry.set_range(0.0000001, 99999.9999) self.frz_dispense_entry.setSingleStep(0.1) self.frz_dispense_label = QtWidgets.QLabel('%s:' % _("Feedrate Z Dispense")) @@ -6749,7 +6749,7 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI): # Spindle Speed Forward self.speedfwd_entry = FCSpinner() - self.speedfwd_entry.set_range(0, 999999) + self.speedfwd_entry.set_range(0, 99999) self.speedfwd_entry.setSingleStep(1000) self.speedfwd_label = QtWidgets.QLabel('%s:' % _("Spindle Speed FWD")) diff --git a/flatcamTools/ToolSolderPaste.py b/flatcamTools/ToolSolderPaste.py index c2393bd2..af227bd3 100644 --- a/flatcamTools/ToolSolderPaste.py +++ b/flatcamTools/ToolSolderPaste.py @@ -245,7 +245,7 @@ class SolderPaste(FlatCAMTool): # Feedrate X-Y self.frxy_entry = FCDoubleSpinner() - self.frxy_entry.set_range(0.0000001, 9999.9999) + self.frxy_entry.set_range(0.0000, 99999.9999) self.frxy_entry.set_precision(self.decimals) self.frxy_entry.setSingleStep(0.1) @@ -257,7 +257,7 @@ class SolderPaste(FlatCAMTool): # Feedrate Z self.frz_entry = FCDoubleSpinner() - self.frz_entry.set_range(0.0000001, 9999.9999) + self.frz_entry.set_range(0.0000, 99999.9999) self.frz_entry.set_precision(self.decimals) self.frz_entry.setSingleStep(0.1) @@ -270,7 +270,7 @@ class SolderPaste(FlatCAMTool): # Feedrate Z Dispense self.frz_dispense_entry = FCDoubleSpinner() - self.frz_dispense_entry.set_range(0.0000001, 9999.9999) + self.frz_dispense_entry.set_range(0.0000, 99999.9999) self.frz_dispense_entry.set_precision(self.decimals) self.frz_dispense_entry.setSingleStep(0.1) @@ -491,6 +491,8 @@ class SolderPaste(FlatCAMTool): self.units = '' self.name = "" + self.obj = None + self.text_editor_tab = None # this will be used in the combobox context menu, for delete entry @@ -652,10 +654,10 @@ class SolderPaste(FlatCAMTool): for tooluid_key, tooluid_value in self.tooltable_tools.items(): if float('%.*f' % (self.decimals, tooluid_value['tooldia'])) == tool_sorted: tool_id += 1 - id = QtWidgets.QTableWidgetItem('%d' % int(tool_id)) - id.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + id_item = QtWidgets.QTableWidgetItem('%d' % int(tool_id)) + id_item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) row_no = tool_id - 1 - self.tools_table.setItem(row_no, 0, id) # Tool name/id + self.tools_table.setItem(row_no, 0, id_item) # Tool name/id # Make sure that the drill diameter when in MM is with no more than 2 decimals # There are no drill bits in MM with more than 2 decimals diameter @@ -1295,7 +1297,7 @@ class SolderPaste(FlatCAMTool): if obj.tools[tooluid_key]['solid_geometry'] is None: a += 1 if a == len(obj.tools): - self.app.inform.emit('[ERROR_NOTCL] %s...' % _('Cancelled. Empty file, it has no geometry')) + self.app.inform.emit('[ERROR_NOTCL] %s...' % _('Cancelled. Empty file, it has no geometry')) return 'fail' # use the name of the first tool selected in self.geo_tools_table which has the diameter passed as tool_dia @@ -1334,8 +1336,6 @@ class SolderPaste(FlatCAMTool): assert isinstance(job_obj, FlatCAMCNCjob), \ "Initializer expected a FlatCAMCNCjob, got %s" % type(job_obj) - tool_cnc_dict = {} - # this turn on the FlatCAMCNCJob plot for multiple tools job_obj.multitool = True job_obj.multigeo = True diff --git a/preprocessors/default.py b/preprocessors/default.py index d1ddf6ad..e57ed812 100644 --- a/preprocessors/default.py +++ b/preprocessors/default.py @@ -117,11 +117,11 @@ M6 M0 G00 Z{z_toolchange} """.format(x_toolchange=self.coordinate_format % (p.coords_decimals, x_toolchange), - y_toolchange=self.coordinate_format % (p.coords_decimals, y_toolchange), - z_toolchange=self.coordinate_format % (p.coords_decimals, z_toolchange), - tool=int(p.tool), - t_drills=no_drills, - toolC=toolC_formatted) + y_toolchange=self.coordinate_format % (p.coords_decimals, y_toolchange), + z_toolchange=self.coordinate_format % (p.coords_decimals, z_toolchange), + tool=int(p.tool), + t_drills=no_drills, + toolC=toolC_formatted) else: gcode = """ M5 diff --git a/preprocessors/grbl_laser.py b/preprocessors/grbl_laser.py index a95708ca..e975a703 100644 --- a/preprocessors/grbl_laser.py +++ b/preprocessors/grbl_laser.py @@ -54,10 +54,11 @@ class grbl_laser(FlatCAMPostProc): return 'M05 S0' def down_code(self, p): + sdir = {'CW': 'M03', 'CCW': 'M04'}[p.spindledir] if p.spindlespeed: - return 'M03 S%d' % p.spindlespeed + return '%s S%s' % (sdir, str(p.spindlespeed)) else: - return 'M03' + return sdir def toolchange_code(self, p): return '' From 7424bb917ca2f42f0b2d6c0b7b50bd34ccbbb332 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 6 Feb 2020 01:39:19 +0200 Subject: [PATCH 071/209] - Modified the Distance Tool such that the Measure button can't be clicked while measuring is in progress - optimized selection of drills in the Excellon Editor - fixed bugs in multiple selection in Excellon Editor - fixed selection problems in Gerber Editor - in Distance Tool, when run in the Excellon or Gerber Editor, added a new option to snap to center of the geometry (drill for Excellon, pad for Gerber) --- FlatCAMApp.py | 3 + README.md | 8 + flatcamEditors/FlatCAMExcEditor.py | 62 +++--- flatcamEditors/FlatCAMGrbEditor.py | 53 ++--- flatcamTools/ToolDistance.py | 300 +++++++++++++++++++++-------- 5 files changed, 298 insertions(+), 128 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index b6a695ae..3f0d9086 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -890,6 +890,9 @@ class App(QtCore.QObject): # Subtract Tool "tools_sub_close_paths": True, + # Distance Tool + "tools_dist_snap_center": False, + # ################################################################################### # ################################ TOOLS 2 ########################################## # ################################################################################### diff --git a/README.md b/README.md index e50d47be..2728cc8b 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,14 @@ CAD program, and create G-Code for Isolation routing. ================================================= +5.02.2020 + +- Modified the Distance Tool such that the Measure button can't be clicked while measuring is in progress +- optimized selection of drills in the Excellon Editor +- fixed bugs in multiple selection in Excellon Editor +- fixed selection problems in Gerber Editor +- in Distance Tool, when run in the Excellon or Gerber Editor, added a new option to snap to center of the geometry (drill for Excellon, pad for Gerber) + 3.02.2020 - modified Spinbox and DoubleSpinbox Custom UI elements such that they issue a warning status message when the typed value is out of range diff --git a/flatcamEditors/FlatCAMExcEditor.py b/flatcamEditors/FlatCAMExcEditor.py index e2dc8bdb..a4136d3c 100644 --- a/flatcamEditors/FlatCAMExcEditor.py +++ b/flatcamEditors/FlatCAMExcEditor.py @@ -1334,8 +1334,8 @@ class FCDrillCopy(FCDrillMove): class FCDrillSelect(DrawTool): - def __init__(self, exc_editor_app): - DrawTool.__init__(self, exc_editor_app) + def __init__(self, draw_app): + DrawTool.__init__(self, draw_app) self.name = 'drill_select' try: @@ -1343,7 +1343,7 @@ class FCDrillSelect(DrawTool): except Exception as e: pass - self.exc_editor_app = exc_editor_app + self.exc_editor_app = draw_app self.storage = self.exc_editor_app.storage_dict # self.selected = self.exc_editor_app.selected @@ -1368,10 +1368,10 @@ class FCDrillSelect(DrawTool): else: mod_key = None - if mod_key == self.draw_app.app.defaults["global_mselect_key"]: + if mod_key == self.exc_editor_app.app.defaults["global_mselect_key"]: pass else: - self.exc_editor_app.selected = [] + self.exc_editor_app.selected = list() def click_release(self, pos): self.exc_editor_app.tools_table_exc.clearSelection() @@ -1379,8 +1379,10 @@ class FCDrillSelect(DrawTool): try: for storage in self.exc_editor_app.storage_dict: - for sh in self.exc_editor_app.storage_dict[storage].get_objects(): - self.sel_storage.insert(sh) + # for sh in self.exc_editor_app.storage_dict[storage].get_objects(): + # self.sel_storage.insert(sh) + _, st_closest_shape = self.exc_editor_app.storage_dict[storage].nearest(pos) + self.sel_storage.insert(st_closest_shape) _, closest_shape = self.sel_storage.nearest(pos) @@ -1417,37 +1419,41 @@ class FCDrillSelect(DrawTool): else: mod_key = None - if mod_key == self.draw_app.app.defaults["global_mselect_key"]: + if mod_key == self.exc_editor_app.app.defaults["global_mselect_key"]: if closest_shape in self.exc_editor_app.selected: self.exc_editor_app.selected.remove(closest_shape) else: self.exc_editor_app.selected.append(closest_shape) else: - self.draw_app.selected = [] - self.draw_app.selected.append(closest_shape) + self.exc_editor_app.selected = list() + self.exc_editor_app.selected.append(closest_shape) # select the diameter of the selected shape in the tool table try: - self.draw_app.tools_table_exc.cellPressed.disconnect() + self.exc_editor_app.tools_table_exc.cellPressed.disconnect() except (TypeError, AttributeError): pass - self.exc_editor_app.tools_table_exc.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection) + # if mod_key == self.exc_editor_app.app.defaults["global_mselect_key"]: + # self.exc_editor_app.tools_table_exc.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection) + self.sel_tools.clear() + for shape_s in self.exc_editor_app.selected: for storage in self.exc_editor_app.storage_dict: if shape_s in self.exc_editor_app.storage_dict[storage].get_objects(): self.sel_tools.add(storage) + self.exc_editor_app.tools_table_exc.clearSelection() for storage in self.sel_tools: - for k, v in self.draw_app.tool2tooldia.items(): + for k, v in self.exc_editor_app.tool2tooldia.items(): if v == storage: self.exc_editor_app.tools_table_exc.selectRow(int(k) - 1) - self.draw_app.last_tool_selected = int(k) + self.exc_editor_app.last_tool_selected = int(k) break - self.exc_editor_app.tools_table_exc.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) + # self.exc_editor_app.tools_table_exc.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) - self.draw_app.tools_table_exc.cellPressed.connect(self.draw_app.on_row_selected) + self.exc_editor_app.tools_table_exc.cellPressed.connect(self.exc_editor_app.on_row_selected) # delete whatever is in selection storage, there is no longer need for those shapes self.sel_storage = FlatCAMExcEditor.make_storage() @@ -2054,32 +2060,32 @@ class FlatCAMExcEditor(QtCore.QObject): self.in_action = False - self.storage_dict = {} + self.storage_dict = dict() - self.current_storage = [] + self.current_storage = list() # build the data from the Excellon point into a dictionary # {tool_dia: [geometry_in_points]} - self.points_edit = {} - self.slot_points_edit = {} + self.points_edit = dict() + self.slot_points_edit = dict() - self.sorted_diameters = [] + self.sorted_diameters = list() - self.new_drills = [] - self.new_tools = {} - self.new_slots = [] - self.new_tool_offset = {} + self.new_drills = list() + self.new_tools = dict() + self.new_slots = list() + self.new_tool_offset = dict() # dictionary to store the tool_row and diameters in Tool_table # it will be updated everytime self.build_ui() is called - self.olddia_newdia = {} + self.olddia_newdia = dict() - self.tool2tooldia = {} + self.tool2tooldia = dict() # this will store the value for the last selected tool, for use after clicking on canvas when the selection # is cleared but as a side effect also the selected tool is cleared self.last_tool_selected = None - self.utility = [] + self.utility = list() # this will flag if the Editor "tools" are launched from key shortcuts (True) or from menu toolbar (False) self.launched_from_shortcuts = False diff --git a/flatcamEditors/FlatCAMGrbEditor.py b/flatcamEditors/FlatCAMGrbEditor.py index 2bd6a8bb..e1006725 100644 --- a/flatcamEditors/FlatCAMGrbEditor.py +++ b/flatcamEditors/FlatCAMGrbEditor.py @@ -2300,10 +2300,10 @@ class FCApertureSelect(DrawTool): # since FCApertureSelect tool is activated whenever a tool is exited I place here the reinitialization of the # bending modes using in FCRegion and FCTrack - self.draw_app.bend_mode = 1 + self.grb_editor_app.bend_mode = 1 # here store the selected apertures - self.sel_aperture = set() + self.sel_aperture = list() try: self.grb_editor_app.apertures_table.clearSelection() @@ -2332,7 +2332,7 @@ class FCApertureSelect(DrawTool): else: mod_key = None - if mod_key == self.draw_app.app.defaults["global_mselect_key"]: + if mod_key == self.grb_editor_app.app.defaults["global_mselect_key"]: pass else: self.grb_editor_app.selected = [] @@ -2348,46 +2348,53 @@ class FCApertureSelect(DrawTool): else: mod_key = None + if mod_key != self.grb_editor_app.app.defaults["global_mselect_key"]: + self.grb_editor_app.selected.clear() + self.sel_aperture.clear() + for storage in self.grb_editor_app.storage_dict: try: - for geo_el in self.grb_editor_app.storage_dict[storage]['geometry']: - if 'solid' in geo_el.geo: - geometric_data = geo_el.geo['solid'] + for shape_stored in self.grb_editor_app.storage_dict[storage]['geometry']: + if 'solid' in shape_stored.geo: + geometric_data = shape_stored.geo['solid'] if Point(point).within(geometric_data): - if mod_key == self.grb_editor_app.app.defaults["global_mselect_key"]: - if geo_el in self.draw_app.selected: - self.draw_app.selected.remove(geo_el) - self.sel_aperture.remove(storage) - else: - # add the object to the selected shapes - self.draw_app.selected.append(geo_el) - self.sel_aperture.add(storage) + if shape_stored in self.grb_editor_app.selected: + self.grb_editor_app.selected.remove(shape_stored) else: - self.draw_app.selected.append(geo_el) - self.sel_aperture.add(storage) + # add the object to the selected shapes + self.grb_editor_app.selected.append(shape_stored) except KeyError: pass # select the aperture in the Apertures Table that is associated with the selected shape + self.sel_aperture.clear() + + self.grb_editor_app.apertures_table.clearSelection() try: - self.draw_app.apertures_table.cellPressed.disconnect() + self.grb_editor_app.apertures_table.cellPressed.disconnect() except Exception as e: log.debug("FlatCAMGrbEditor.FCApertureSelect.click_release() --> %s" % str(e)) - self.grb_editor_app.apertures_table.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection) + for shape_s in self.grb_editor_app.selected: + for storage in self.grb_editor_app.storage_dict: + if shape_s in self.grb_editor_app.storage_dict[storage]['geometry']: + self.sel_aperture.append(storage) + + # self.grb_editor_app.apertures_table.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection) for aper in self.sel_aperture: for row in range(self.grb_editor_app.apertures_table.rowCount()): if str(aper) == self.grb_editor_app.apertures_table.item(row, 1).text(): - self.grb_editor_app.apertures_table.selectRow(row) - self.draw_app.last_aperture_selected = aper - self.grb_editor_app.apertures_table.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) + if not self.grb_editor_app.apertures_table.item(row, 0).isSelected(): + self.grb_editor_app.apertures_table.selectRow(row) + self.grb_editor_app.last_aperture_selected = aper + # self.grb_editor_app.apertures_table.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) - self.draw_app.apertures_table.cellPressed.connect(self.draw_app.on_row_selected) + self.grb_editor_app.apertures_table.cellPressed.connect(self.grb_editor_app.on_row_selected) return "" def clean_up(self): - self.draw_app.plot_all() + self.grb_editor_app.plot_all() class FCTransform(FCShapeTool): diff --git a/flatcamTools/ToolDistance.py b/flatcamTools/ToolDistance.py index 1a5bc568..84a6c547 100644 --- a/flatcamTools/ToolDistance.py +++ b/flatcamTools/ToolDistance.py @@ -9,13 +9,18 @@ from PyQt5 import QtWidgets, QtCore from FlatCAMTool import FlatCAMTool from flatcamGUI.VisPyVisuals import * -from flatcamGUI.GUIElements import FCEntry +from flatcamGUI.GUIElements import FCEntry, FCButton, FCCheckBox + +from shapely.geometry import Point, MultiLineString, Polygon + +import FlatCAMTranslation as fcTranslate +from camlib import FlatCAMRTreeStorage +from flatcamEditors.FlatCAMGeoEditor import DrawToolShape from copy import copy import math import logging import gettext -import FlatCAMTranslation as fcTranslate import builtins fcTranslate.apply_language('strings') @@ -43,82 +48,101 @@ class Distance(FlatCAMTool): self.layout.addWidget(title_label) # ## Form Layout - form_layout = QtWidgets.QFormLayout() - self.layout.addLayout(form_layout) + grid0 = QtWidgets.QGridLayout() + grid0.setColumnStretch(0, 0) + grid0.setColumnStretch(1, 1) + self.layout.addLayout(grid0) self.units_label = QtWidgets.QLabel('%s:' % _("Units")) self.units_label.setToolTip(_("Those are the units in which the distance is measured.")) self.units_value = QtWidgets.QLabel("%s" % str({'mm': _("METRIC (mm)"), 'in': _("INCH (in)")}[self.units])) self.units_value.setDisabled(True) + grid0.addWidget(self.units_label, 0, 0) + grid0.addWidget(self.units_value, 0, 1) + + self.snap_center_cb = FCCheckBox(_("Snap to center")) + self.snap_center_cb.setToolTip( + _("Mouse cursor will snap to the center of the pad/drill\n" + "when it is hovering over the geometry of the pad/drill.") + ) + grid0.addWidget(self.snap_center_cb, 1, 0, 1, 2) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(separator_line, 2, 0, 1, 2) + self.start_label = QtWidgets.QLabel("%s:" % _('Start Coords')) self.start_label.setToolTip(_("This is measuring Start point coordinates.")) - self.stop_label = QtWidgets.QLabel("%s:" % _('Stop Coords')) - self.stop_label.setToolTip(_("This is the measuring Stop point coordinates.")) - - self.distance_x_label = QtWidgets.QLabel('%s:' % _("Dx")) - self.distance_x_label.setToolTip(_("This is the distance measured over the X axis.")) - - self.distance_y_label = QtWidgets.QLabel('%s:' % _("Dy")) - self.distance_y_label.setToolTip(_("This is the distance measured over the Y axis.")) - - self.angle_label = QtWidgets.QLabel('%s:' % _("Angle")) - self.angle_label.setToolTip(_("This is orientation angle of the measuring line.")) - - self.total_distance_label = QtWidgets.QLabel("%s:" % _('DISTANCE')) - self.total_distance_label.setToolTip(_("This is the point to point Euclidian distance.")) - self.start_entry = FCEntry() self.start_entry.setReadOnly(True) self.start_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.start_entry.setToolTip(_("This is measuring Start point coordinates.")) + grid0.addWidget(self.start_label, 3, 0) + grid0.addWidget(self.start_entry, 3, 1) + + self.stop_label = QtWidgets.QLabel("%s:" % _('Stop Coords')) + self.stop_label.setToolTip(_("This is the measuring Stop point coordinates.")) + self.stop_entry = FCEntry() self.stop_entry.setReadOnly(True) self.stop_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.stop_entry.setToolTip(_("This is the measuring Stop point coordinates.")) + grid0.addWidget(self.stop_label, 4, 0) + grid0.addWidget(self.stop_entry, 4, 1) + + self.distance_x_label = QtWidgets.QLabel('%s:' % _("Dx")) + self.distance_x_label.setToolTip(_("This is the distance measured over the X axis.")) + self.distance_x_entry = FCEntry() self.distance_x_entry.setReadOnly(True) self.distance_x_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.distance_x_entry.setToolTip(_("This is the distance measured over the X axis.")) + grid0.addWidget(self.distance_x_label, 5, 0) + grid0.addWidget(self.distance_x_entry, 5, 1) + + self.distance_y_label = QtWidgets.QLabel('%s:' % _("Dy")) + self.distance_y_label.setToolTip(_("This is the distance measured over the Y axis.")) + self.distance_y_entry = FCEntry() self.distance_y_entry.setReadOnly(True) self.distance_y_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.distance_y_entry.setToolTip(_("This is the distance measured over the Y axis.")) + grid0.addWidget(self.distance_y_label, 6, 0) + grid0.addWidget(self.distance_y_entry, 6, 1) + + self.angle_label = QtWidgets.QLabel('%s:' % _("Angle")) + self.angle_label.setToolTip(_("This is orientation angle of the measuring line.")) + self.angle_entry = FCEntry() self.angle_entry.setReadOnly(True) self.angle_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.angle_entry.setToolTip(_("This is orientation angle of the measuring line.")) + grid0.addWidget(self.angle_label, 7, 0) + grid0.addWidget(self.angle_entry, 7, 1) + + self.total_distance_label = QtWidgets.QLabel("%s:" % _('DISTANCE')) + self.total_distance_label.setToolTip(_("This is the point to point Euclidian distance.")) + self.total_distance_entry = FCEntry() self.total_distance_entry.setReadOnly(True) self.total_distance_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.total_distance_entry.setToolTip(_("This is the point to point Euclidian distance.")) - self.measure_btn = QtWidgets.QPushButton(_("Measure")) + grid0.addWidget(self.total_distance_label, 8, 0) + grid0.addWidget(self.total_distance_entry, 8, 1) + + self.measure_btn = FCButton(_("Measure")) # self.measure_btn.setFixedWidth(70) self.layout.addWidget(self.measure_btn) - form_layout.addRow(self.units_label, self.units_value) - form_layout.addRow(self.start_label, self.start_entry) - form_layout.addRow(self.stop_label, self.stop_entry) - form_layout.addRow(self.distance_x_label, self.distance_x_entry) - form_layout.addRow(self.distance_y_label, self.distance_y_entry) - form_layout.addRow(self.angle_label, self.angle_entry) - form_layout.addRow(self.total_distance_label, self.total_distance_entry) - - # initial view of the layout - self.start_entry.set_value('(0, 0)') - self.stop_entry.set_value('(0, 0)') - self.distance_x_entry.set_value('0.0') - self.distance_y_entry.set_value('0.0') - self.angle_entry.set_value('0.0') - self.total_distance_entry.set_value('0.0') - self.layout.addStretch() # store here the first click and second click of the measurement process @@ -137,6 +161,15 @@ class Distance(FlatCAMTool): self.mm = None self.mr = None + # monitor if the tool was used + self.tool_done = False + + # store the grid status here + self.grid_status_memory = False + + # store here if the snap button was clicked + self.snap_toggled = None + # VisPy visuals if self.app.is_legacy is False: self.sel_shapes = ShapeCollection(parent=self.app.plotcanvas.view.scene, layers=1) @@ -145,6 +178,7 @@ class Distance(FlatCAMTool): self.sel_shapes = ShapeCollectionLegacy(obj=self, app=self.app, name='measurement') self.measure_btn.clicked.connect(self.activate_measure_tool) + self.snap_center_cb.toggled.connect(self.on_snap_toggled) def run(self, toggle=False): self.app.report_usage("ToolDistance()") @@ -154,6 +188,8 @@ class Distance(FlatCAMTool): self.rel_point1 = None self.rel_point2 = None + self.tool_done = False + if self.app.tool_tab_locked is True: return @@ -177,7 +213,7 @@ class Distance(FlatCAMTool): # Remove anything else in the GUI self.app.ui.tool_scroll_area.takeWidget() - # Put ourself in the GUI + # Put ourselves in the GUI self.app.ui.tool_scroll_area.setWidget(self) # Switch notebook to tool page @@ -195,20 +231,45 @@ class Distance(FlatCAMTool): self.angle_entry.set_value('0.0') self.total_distance_entry.set_value('0.0') + self.snap_center_cb.set_value(self.app.defaults['tools_dist_snap_center']) + + # snap center works only for Gerber and Execellon Editor's + if self.original_call_source == 'exc_editor' or self.original_call_source == 'grb_editor': + self.snap_center_cb.show() + else: + self.snap_center_cb.hide() + # this is a hack; seems that triggering the grid will make the visuals better # trigger it twice to return to the original state self.app.ui.grid_snap_btn.trigger() self.app.ui.grid_snap_btn.trigger() + if self.app.ui.grid_snap_btn.isChecked(): + self.grid_status_memory = True + log.debug("Distance Tool --> tool initialized") + def on_snap_toggled(self, state): + self.app.defaults['tools_dist_snap_center'] = state + if state: + # disengage the grid snapping since it will be hard to find the drills or pads on grid + if self.app.ui.grid_snap_btn.isChecked(): + self.app.ui.grid_snap_btn.trigger() + def activate_measure_tool(self): # ENABLE the Measuring TOOL self.active = True + # disable the measuring button + self.measure_btn.setDisabled(True) + self.measure_btn.setText('%s...' % _("Working")) + self.clicked_meas = 0 self.original_call_source = copy(self.app.call_source) + snap_center = self.app.defaults['tools_dist_snap_center'] + self.on_snap_toggled(snap_center) + self.app.inform.emit(_("MEASURING: Click on the Start point ...")) self.units = self.app.defaults['units'].lower() @@ -267,6 +328,10 @@ class Distance(FlatCAMTool): self.active = False self.points = [] + # disable the measuring button + self.measure_btn.setDisabled(False) + self.measure_btn.setText(_("Measure")) + self.app.call_source = copy(self.original_call_source) if self.original_call_source == 'app': self.app.mm = self.canvas.graph_event_connect('mouse_move', self.app.on_mouse_move_over_plot) @@ -307,8 +372,16 @@ class Distance(FlatCAMTool): # delete the measuring line self.delete_shape() + # restore the grid status + if (self.app.ui.grid_snap_btn.isChecked() and self.grid_status_memory is False) or \ + (not self.app.ui.grid_snap_btn.isChecked() and self.grid_status_memory is True): + self.app.ui.grid_snap_btn.trigger() + log.debug("Distance Tool --> exit tool") + if self.tool_done is False: + self.app.inform.emit('%s' % _("Distance Tool finished.")) + def on_mouse_click_release(self, event): # mouse click releases will be accepted only if the left button is clicked # this is necessary because right mouse click or middle mouse click @@ -323,11 +396,71 @@ class Distance(FlatCAMTool): pos_canvas = self.canvas.translate_coords(event_pos) - # if GRID is active we need to get the snapped positions - if self.app.grid_status() == True: - pos = self.app.geo_editor.snap(pos_canvas[0], pos_canvas[1]) + if self.snap_center_cb.get_value() is False: + # if GRID is active we need to get the snapped positions + if self.app.grid_status(): + pos = self.app.geo_editor.snap(pos_canvas[0], pos_canvas[1]) + else: + pos = pos_canvas[0], pos_canvas[1] else: - pos = pos_canvas[0], pos_canvas[1] + pos = (pos_canvas[0], pos_canvas[1]) + current_pt = Point(pos) + shapes_storage = self.make_storage() + + if self.original_call_source == 'exc_editor': + for storage in self.app.exc_editor.storage_dict: + __, st_closest_shape = self.app.exc_editor.storage_dict[storage].nearest(pos) + shapes_storage.insert(st_closest_shape) + + __, closest_shape = shapes_storage.nearest(pos) + + # if it's a drill + if isinstance(closest_shape.geo, MultiLineString): + radius = closest_shape.geo[0].length / 2.0 + center_pt = closest_shape.geo.centroid + + geo_buffered = center_pt.buffer(radius) + + if current_pt.within(geo_buffered): + pos = (center_pt.x, center_pt.y) + + # if it's a slot + elif isinstance(closest_shape.geo, Polygon): + geo_buffered = closest_shape.geo.buffer(0) + center_pt = geo_buffered.centroid + + if current_pt.within(geo_buffered): + pos = (center_pt.x, center_pt.y) + + elif self.original_call_source == 'grb_editor': + clicked_pads = list() + for storage in self.app.grb_editor.storage_dict: + try: + for shape_stored in self.app.grb_editor.storage_dict[storage]['geometry']: + if 'solid' in shape_stored.geo: + geometric_data = shape_stored.geo['solid'] + if Point(current_pt).within(geometric_data): + if isinstance(shape_stored.geo['follow'], Point): + clicked_pads.append(shape_stored.geo['follow']) + except KeyError: + pass + + if len(clicked_pads) > 1: + self.tool_done = True + self.deactivate_measure_tool() + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Pads overlapped. Aborting.")) + return + + pos = (clicked_pads[0].x, clicked_pads[0].y) + + self.app.on_jump_to(custom_location=pos, fit_center=False) + # Update cursor + self.app.app_cursor.enabled = True + self.app.app_cursor.set_data(np.asarray([(pos[0], pos[1])]), + symbol='++', edge_color='#000000', + edge_width=self.app.defaults["global_cursor_width"], + size=self.app.defaults["global_cursor_size"]) + self.points.append(pos) # Reset here the relative coordinates so there is a new reference on the click position @@ -340,41 +473,46 @@ class Distance(FlatCAMTool): self.rel_point2 = copy(self.rel_point1) self.rel_point1 = pos - if len(self.points) == 1: - self.start_entry.set_value("(%.*f, %.*f)" % (self.decimals, pos[0], self.decimals, pos[1])) - self.app.inform.emit(_("MEASURING: Click on the Destination point ...")) - elif len(self.points) == 2: - dx = self.points[1][0] - self.points[0][0] - dy = self.points[1][1] - self.points[0][1] - d = math.sqrt(dx ** 2 + dy ** 2) - self.stop_entry.set_value("(%.*f, %.*f)" % (self.decimals, pos[0], self.decimals, pos[1])) + self.calculate_distance(pos=pos) - self.app.inform.emit("{tx1}: {tx2} D(x) = {d_x} | D(y) = {d_y} | {tx3} = {d_z}".format( - tx1=_("MEASURING"), - tx2=_("Result"), - tx3=_("Distance"), - d_x='%*f' % (self.decimals, abs(dx)), - d_y='%*f' % (self.decimals, abs(dy)), - d_z='%*f' % (self.decimals, abs(d))) + def calculate_distance(self, pos): + if len(self.points) == 1: + self.start_entry.set_value("(%.*f, %.*f)" % (self.decimals, pos[0], self.decimals, pos[1])) + self.app.inform.emit(_("MEASURING: Click on the Destination point ...")) + elif len(self.points) == 2: + self.app.app_cursor.enabled = False + dx = self.points[1][0] - self.points[0][0] + dy = self.points[1][1] - self.points[0][1] + d = math.sqrt(dx ** 2 + dy ** 2) + self.stop_entry.set_value("(%.*f, %.*f)" % (self.decimals, pos[0], self.decimals, pos[1])) + + self.app.inform.emit("{tx1}: {tx2} D(x) = {d_x} | D(y) = {d_y} | {tx3} = {d_z}".format( + tx1=_("MEASURING"), + tx2=_("Result"), + tx3=_("Distance"), + d_x='%*f' % (self.decimals, abs(dx)), + d_y='%*f' % (self.decimals, abs(dy)), + d_z='%*f' % (self.decimals, abs(d))) + ) + + self.distance_x_entry.set_value('%.*f' % (self.decimals, abs(dx))) + self.distance_y_entry.set_value('%.*f' % (self.decimals, abs(dy))) + + if dx != 0.0: + try: + angle = math.degrees(math.atan(dy / dx)) + self.angle_entry.set_value('%.*f' % (self.decimals, angle)) + except Exception: + pass + + self.total_distance_entry.set_value('%.*f' % (self.decimals, abs(d))) + self.app.ui.rel_position_label.setText( + "Dx: {}   Dy: {}    ".format( + '%.*f' % (self.decimals, pos[0]), '%.*f' % (self.decimals, pos[1]) ) - - self.distance_x_entry.set_value('%.*f' % (self.decimals, abs(dx))) - self.distance_y_entry.set_value('%.*f' % (self.decimals, abs(dy))) - - if dx != 0.0: - try: - angle = math.degrees(math.atan(dy / dx)) - self.angle_entry.set_value('%.*f' % (self.decimals, angle)) - except Exception as e: - pass - - self.total_distance_entry.set_value('%.*f' % (self.decimals, abs(d))) - self.app.ui.rel_position_label.setText( - "Dx: {}   Dy: {}    ".format( - '%.*f' % (self.decimals, pos[0]), '%.*f' % (self.decimals, pos[1]) - ) - ) - self.deactivate_measure_tool() + ) + self.tool_done = True + self.deactivate_measure_tool() def on_mouse_move_meas(self, event): try: # May fail in case mouse not within axes @@ -391,7 +529,7 @@ class Distance(FlatCAMTool): pos_canvas = self.app.plotcanvas.translate_coords((x, y)) - if self.app.grid_status() == True: + if self.app.grid_status(): pos = self.app.geo_editor.snap(pos_canvas[0], pos_canvas[1]) # Update cursor @@ -465,7 +603,15 @@ class Distance(FlatCAMTool): self.sel_shapes.clear() self.sel_shapes.redraw() - def set_meas_units(self, units): - self.meas.units_label.setText("[" + self.app.options["units"].lower() + "]") + @staticmethod + def make_storage(): + # ## Shape storage. + storage = FlatCAMRTreeStorage() + storage.get_points = DrawToolShape.get_pts + + return storage + + # def set_meas_units(self, units): + # self.meas.units_label.setText("[" + self.app.options["units"].lower() + "]") # end of file From 9911402c959ef16e41ff834112766bb04ac213a9 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 8 Feb 2020 18:01:32 +0200 Subject: [PATCH 072/209] - added a new preprocessor for using laser on a Marlin 3D printer named 'Marlin_laser' - modified the Geometry UI when using laser preprocessors --- FlatCAMApp.py | 4 +- FlatCAMObj.py | 123 +++++++++++++++++++++++-- README.md | 7 +- camlib.py | 75 +++++++-------- flatcamGUI/ObjectUI.py | 80 ++++++++-------- flatcamGUI/PreferencesUI.py | 20 ++-- preprocessors/{marlin.py => Marlin.py} | 4 +- preprocessors/Marlin_laser.py | 122 ++++++++++++++++++++++++ preprocessors/grbl_laser.py | 8 +- 9 files changed, 336 insertions(+), 107 deletions(-) rename preprocessors/{marlin.py => Marlin.py} (98%) create mode 100644 preprocessors/Marlin_laser.py diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 3f0d9086..9189e8f8 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -1291,7 +1291,7 @@ class App(QtCore.QObject): "excellon_drillz": self.ui.excellon_defaults_form.excellon_opt_group.cutz_entry, "excellon_travelz": self.ui.excellon_defaults_form.excellon_opt_group.travelz_entry, "excellon_endz": self.ui.excellon_defaults_form.excellon_opt_group.eendz_entry, - "excellon_feedrate": self.ui.excellon_defaults_form.excellon_opt_group.feedrate_entry, + "excellon_feedrate": self.ui.excellon_defaults_form.excellon_opt_group.feedrate_z_entry, "excellon_spindlespeed": self.ui.excellon_defaults_form.excellon_opt_group.spindlespeed_entry, "excellon_dwell": self.ui.excellon_defaults_form.excellon_opt_group.dwell_cb, "excellon_dwelltime": self.ui.excellon_defaults_form.excellon_opt_group.dwelltime_entry, @@ -1361,7 +1361,7 @@ class App(QtCore.QObject): "geometry_cutz": self.ui.geometry_defaults_form.geometry_opt_group.cutz_entry, "geometry_travelz": self.ui.geometry_defaults_form.geometry_opt_group.travelz_entry, "geometry_feedrate": self.ui.geometry_defaults_form.geometry_opt_group.cncfeedrate_entry, - "geometry_feedrate_z": self.ui.geometry_defaults_form.geometry_opt_group.cncplunge_entry, + "geometry_feedrate_z": self.ui.geometry_defaults_form.geometry_opt_group.feedrate_z_entry, "geometry_spindlespeed": self.ui.geometry_defaults_form.geometry_opt_group.cncspindlespeed_entry, "geometry_dwell": self.ui.geometry_defaults_form.geometry_opt_group.dwell_cb, "geometry_dwelltime": self.ui.geometry_defaults_form.geometry_opt_group.dwelltime_entry, diff --git a/FlatCAMObj.py b/FlatCAMObj.py index e9982564..fdc45475 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -2804,7 +2804,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): "solid": self.ui.solid_cb, "drillz": self.ui.cutz_entry, "travelz": self.ui.travelz_entry, - "feedrate": self.ui.feedrate_entry, + "feedrate": self.ui.feedrate_z_entry, "feedrate_rapid": self.ui.feedrate_rapid_entry, "tooldia": self.ui.tooldia_entry, "slot_tooldia": self.ui.slot_tooldia_entry, @@ -2978,12 +2978,14 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.ui.mill_type_radio.show() self.ui.mill_dia_label.show() self.ui.mill_dia_entry.show() - self.ui.mpass_cb.show() - self.ui.maxdepth_entry.show() self.ui.frxylabel.show() self.ui.xyfeedrate_entry.show() self.ui.extracut_cb.show() self.ui.e_cut_entry.show() + + if 'laser' not in self.ui.pp_excellon_name_cb.get_value().lower(): + self.ui.mpass_cb.show() + self.ui.maxdepth_entry.show() else: self.ui.mill_type_label.hide() self.ui.mill_type_radio.hide() @@ -3464,6 +3466,59 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.ui.feedrate_rapid_label.hide() self.ui.feedrate_rapid_entry.hide() + if 'laser' in current_pp.lower(): + self.ui.cutzlabel.hide() + self.ui.cutz_entry.hide() + try: + self.ui.mpass_cb.hide() + self.ui.maxdepth_entry.hide() + except AttributeError: + pass + + self.ui.travelzlabel.setText('%s:' % _("Focus Z")) + + try: + self.ui.frzlabel.hide() + self.ui.feedrate_z_entry.hide() + except AttributeError: + pass + self.ui.dwell_cb.hide() + self.ui.dwelltime_entry.hide() + + self.ui.spindle_label.setText('%s:' % _("Laser Power")) + + try: + self.ui.tool_offset_label.hide() + self.ui.offset_entry.hide() + except AttributeError: + pass + else: + self.ui.cutzlabel.show() + self.ui.cutz_entry.show() + try: + self.ui.mpass_cb.show() + self.ui.maxdepth_entry.show() + except AttributeError: + pass + + self.ui.travelzlabel.setText('%s:' % _('Travel Z')) + + try: + self.ui.frzlabel.show() + self.ui.feedrate_z_entry.show() + except AttributeError: + pass + self.ui.dwell_cb.show() + self.ui.dwelltime_entry.show() + + self.ui.spindle_label.setText('%s:' % _('Spindle speed')) + + try: + self.ui.tool_offset_lbl.show() + self.ui.offset_entry.show() + except AttributeError: + pass + def on_create_cncjob_button_click(self, *args): self.app.report_usage("excellon_on_create_cncjob_button") self.read_form() @@ -4026,7 +4081,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): "vtipangle": self.ui.tipangle_entry, "travelz": self.ui.travelz_entry, "feedrate": self.ui.cncfeedrate_entry, - "feedrate_z": self.ui.cncplunge_entry, + "feedrate_z": self.ui.feedrate_z_entry, "feedrate_rapid": self.ui.cncfeedrate_rapid_entry, "spindlespeed": self.ui.cncspindlespeed_entry, "dwell": self.ui.dwell_cb, @@ -5178,6 +5233,59 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ui.fr_rapidlabel.hide() self.ui.cncfeedrate_rapid_entry.hide() + if 'laser' in current_pp.lower(): + self.ui.cutzlabel.hide() + self.ui.cutz_entry.hide() + try: + self.ui.mpass_cb.hide() + self.ui.maxdepth_entry.hide() + except AttributeError: + pass + + self.ui.travelzlabel.setText('%s:' % _("Focus Z")) + + try: + self.ui.frzlabel.hide() + self.ui.feedrate_z_entry.hide() + except AttributeError: + pass + self.ui.dwell_cb.hide() + self.ui.dwelltime_entry.hide() + + self.ui.spindle_label.setText('%s:' % _("Laser Power")) + + try: + self.ui.tool_offset_label.hide() + self.ui.offset_entry.hide() + except AttributeError: + pass + else: + self.ui.cutzlabel.show() + self.ui.cutz_entry.show() + try: + self.ui.mpass_cb.show() + self.ui.maxdepth_entry.show() + except AttributeError: + pass + + self.ui.travelzlabel.setText('%s:' % _('Travel Z')) + + try: + self.ui.frzlabel.show() + self.ui.feedrate_z_entry.show() + except AttributeError: + pass + self.ui.dwell_cb.show() + self.ui.dwelltime_entry.show() + + self.ui.spindle_label.setText('%s:' % _('Spindle speed')) + + try: + self.ui.tool_offset_lbl.show() + self.ui.offset_entry.show() + except AttributeError: + pass + def on_generatecnc_button_click(self, *args): log.debug("Generating CNCJob from Geometry ...") self.app.report_usage("geometry_on_generatecnc_button") @@ -6783,7 +6891,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): try: for key in self.cnc_tools: ppg = self.cnc_tools[key]['data']['ppname_g'] - if ppg == 'marlin' or ppg == 'Repetier': + if 'marlin' in ppg.lower() or 'repetier' in ppg.lower() : marlin = True break if ppg == 'hpgl': @@ -6797,7 +6905,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): pass try: - if self.options['ppname_e'] == 'marlin' or self.options['ppname_e'] == 'Repetier': + if 'marlin' in self.options['ppname_e'].lower() or 'repetier' in self.options['ppname_e'].lower(): marlin = True except KeyError: # log.debug("FlatCAMCNCJob.gcode_header(): --> There is no such self.option: %s" % str(e)) @@ -7150,8 +7258,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): _("The used preprocessor file has to have in it's name: " "'toolchange_custom'")) except KeyError: - self.app.inform.emit('[ERROR] %s' % - _("There is no preprocessor file.")) + self.app.inform.emit('[ERROR] %s' % _("There is no preprocessor file.")) def get_gcode(self, preamble='', postamble=''): # we need this to be able get_gcode separatelly for shell command export_gcode diff --git a/README.md b/README.md index 2728cc8b..38b752bc 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,11 @@ CAD program, and create G-Code for Isolation routing. ================================================= +8.02.2020 + +- added a new preprocessor for using laser on a Marlin 3D printer named 'Marlin_laser' +- modified the Geometry UI when using laser preprocessors + 5.02.2020 - Modified the Distance Tool such that the Measure button can't be clicked while measuring is in progress @@ -583,7 +588,7 @@ CAD program, and create G-Code for Isolation routing. 16.11.2019 -- fixed issue #341 that affected both postprocessors that have inlined feedrate: marlin and repetier. THe used feedrate was the Feedrate X-Y and instead had to be Feedrate Z. +- fixed issue #341 that affected both postprocessors that have inlined feedrate: marlin and repetier. The used feedrate was the Feedrate X-Y and instead had to be Feedrate Z. 15.11.2019 diff --git a/camlib.py b/camlib.py index 9eaa8ab8..217e3ef5 100644 --- a/camlib.py +++ b/camlib.py @@ -3299,7 +3299,7 @@ class CNCjob(Geometry): # ## Iterate over geometry paths getting the nearest each time. log.debug("Starting G-Code...") - self.app.inform.emit(_("Starting G-Code...")) + self.app.inform.emit('%s...' % _("Starting G-Code")) path_count = 0 current_pt = (0, 0) @@ -3381,12 +3381,9 @@ class CNCjob(Geometry): self.gcode += self.doformat(p.spindle_stop_code) self.gcode += self.doformat(p.lift_code, x=current_pt[0], y=current_pt[1]) self.gcode += self.doformat(p.end_code, x=0, y=0) - self.app.inform.emit('%s... %s %s.' % - (_("Finished G-Code generation"), - str(path_count), - _("paths traced") - ) - ) + self.app.inform.emit( + '%s... %s %s.' % (_("Finished G-Code generation"), str(path_count), _("paths traced")) + ) return self.gcode def generate_from_geometry_2( @@ -3418,8 +3415,7 @@ class CNCjob(Geometry): """ if not isinstance(geometry, Geometry): - self.app.inform.emit('[ERROR] %s: %s' % - (_("Expected a Geometry, got"), type(geometry))) + self.app.inform.emit('[ERROR] %s: %s' % (_("Expected a Geometry, got"), type(geometry))) return 'fail' log.debug("Executing camlib.CNCJob.generate_from_geometry_2()") @@ -3465,10 +3461,11 @@ class CNCjob(Geometry): # if the offset is less than half of the total length or less than half of the total width of the # solid geometry it's obvious we can't do the offset if -offset > ((c - a) / 2) or -offset > ((d - b) / 2): - self.app.inform.emit('[ERROR_NOTCL] %s' % _( - "The Tool Offset value is too negative to use " - "for the current_geometry.\n" - "Raise the value (in module) and try again.")) + self.app.inform.emit( + '[ERROR_NOTCL] %s' % + _("The Tool Offset value is too negative to use for the current_geometry.\n" + "Raise the value (in module) and try again.") + ) return 'fail' # hack: make offset smaller by 0.0000000001 which is insignificant difference but allow the job # to continue @@ -3532,9 +3529,11 @@ class CNCjob(Geometry): else: self.xy_toolchange = [float(eval(a)) for a in toolchangexy.split(",")] if len(self.xy_toolchange) < 2: - self.app.inform.emit('[ERROR] %s' % - _("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. ")) + self.app.inform.emit( + '[ERROR] %s' % + _("The Toolchange X,Y field in Edit -> Preferences has to be in the format (x, y) \n" + "but now there is only one value, not two. ") + ) return 'fail' except Exception as e: log.debug("camlib.CNCJob.generate_from_geometry_2() --> %s" % str(e)) @@ -3545,9 +3544,10 @@ class CNCjob(Geometry): if self.machinist_setting == 0: if self.z_cut is None: - self.app.inform.emit('[ERROR_NOTCL] %s' % - _("Cut_Z parameter is None or zero. Most likely a bad combinations of " - "other parameters.")) + self.app.inform.emit( + '[ERROR_NOTCL] %s' % _("Cut_Z parameter is None or zero. Most likely a bad combinations of " + "other parameters.") + ) return 'fail' if self.z_cut > 0: @@ -3559,14 +3559,14 @@ class CNCjob(Geometry): "Check the resulting CNC code (Gcode etc).")) self.z_cut = -self.z_cut elif self.z_cut == 0: - self.app.inform.emit('[WARNING] %s: %s' % - (_("The Cut Z parameter is zero. There will be no cut, skipping file"), - geometry.options['name'])) + self.app.inform.emit( + '[WARNING] %s: %s' % (_("The Cut Z parameter is zero. There will be no cut, skipping file"), + geometry.options['name']) + ) return 'fail' if self.z_move is None: - self.app.inform.emit('[ERROR_NOTCL] %s' % - _("Travel Z parameter is None or zero.")) + self.app.inform.emit('[ERROR_NOTCL] %s' % _("Travel Z parameter is None or zero.")) return 'fail' if self.z_move < 0: @@ -3578,9 +3578,10 @@ class CNCjob(Geometry): "Check the resulting CNC code (Gcode etc).")) self.z_move = -self.z_move elif self.z_move == 0: - self.app.inform.emit('[WARNING] %s: %s' % - (_("The Z Travel parameter is zero. " - "This is dangerous, skipping file"), self.options['name'])) + self.app.inform.emit( + '[WARNING] %s: %s' % (_("The Z Travel parameter is zero. This is dangerous, skipping file"), + self.options['name']) + ) return 'fail' # made sure that depth_per_cut is no more then the z_cut @@ -3663,7 +3664,7 @@ class CNCjob(Geometry): # Iterate over geometry paths getting the nearest each time. log.debug("Starting G-Code...") - self.app.inform.emit(_("Starting G-Code...")) + self.app.inform.emit('%s...' % _("Starting G-Code")) # variables to display the percentage of work done geo_len = len(flat_geometry) @@ -3674,9 +3675,7 @@ class CNCjob(Geometry): current_tooldia = float('%.*f' % (self.decimals, float(self.tooldia))) self.app.inform.emit( - '%s: %s%s.' % (_("Starting G-Code for tool with diameter"), - str(current_tooldia), - str(self.units)) + '%s: %s%s.' % (_("Starting G-Code for tool with diameter"), str(current_tooldia), str(self.units)) ) path_count = 0 @@ -3859,13 +3858,9 @@ class CNCjob(Geometry): pass log.debug("Finishing SolderPste G-Code... %s paths traced." % path_count) - self.app.inform.emit('%s... %s %s' % - (_("Finished SolderPste G-Code generation"), - str(path_count), - _("paths traced.") - ) - ) - + self.app.inform.emit( + '%s... %s %s' % (_("Finished SolderPste G-Code generation"), str(path_count), _("paths traced.")) + ) # Finish self.gcode += self.doformat(p.lift_code) @@ -4064,9 +4059,9 @@ class CNCjob(Geometry): command['X'] = float(match_lsr.group(1).replace(" ", "")) command['Y'] = float(match_lsr.group(2).replace(" ", "")) - match_lsr_pos = re.search(r"^(M0[3-5])", gline) + match_lsr_pos = re.search(r"^(M0?[3-5])", gline) if match_lsr_pos: - if 'M05' in match_lsr_pos.group(1): + if 'M05' in match_lsr_pos.group(1) or 'M5' in match_lsr_pos.group(1): # the value does not matter, only that it is positive so the gcode_parse() know it is > 0, # therefore the move is of kind T (travel) command['Z'] = 1 diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index ed9863ae..0a08d60b 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -895,8 +895,8 @@ class ExcellonObjectUI(ObjectUI): self.grid3.addWidget(self.mill_dia_entry, 3, 1) # Cut Z - cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z')) - cutzlabel.setToolTip( + self.cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z')) + self.cutzlabel.setToolTip( _("Drill depth (negative)\n" "below the copper surface.") ) @@ -911,7 +911,7 @@ class ExcellonObjectUI(ObjectUI): self.cutz_entry.setSingleStep(0.1) - self.grid3.addWidget(cutzlabel, 4, 0) + self.grid3.addWidget(self.cutzlabel, 4, 0) self.grid3.addWidget(self.cutz_entry, 4, 1) # Multi-Depth @@ -930,19 +930,15 @@ class ExcellonObjectUI(ObjectUI): self.maxdepth_entry.set_range(0, 9999.9999) self.maxdepth_entry.setSingleStep(0.1) - self.maxdepth_entry.setToolTip( - _( - "Depth of each pass (positive)." - ) - ) + self.maxdepth_entry.setToolTip(_("Depth of each pass (positive).")) self.mis_mpass_geo = OptionalInputSection(self.mpass_cb, [self.maxdepth_entry]) self.grid3.addWidget(self.mpass_cb, 5, 0) self.grid3.addWidget(self.maxdepth_entry, 5, 1) # Travel Z (z_move) - travelzlabel = QtWidgets.QLabel('%s:' % _('Travel Z')) - travelzlabel.setToolTip( + self.travelzlabel = QtWidgets.QLabel('%s:' % _('Travel Z')) + self.travelzlabel.setToolTip( _("Tool height when travelling\n" "across the XY plane.") ) @@ -957,7 +953,7 @@ class ExcellonObjectUI(ObjectUI): self.travelz_entry.setSingleStep(0.1) - self.grid3.addWidget(travelzlabel, 6, 0) + self.grid3.addWidget(self.travelzlabel, 6, 0) self.grid3.addWidget(self.travelz_entry, 6, 1) # Tool change: @@ -1029,20 +1025,20 @@ class ExcellonObjectUI(ObjectUI): self.grid3.addWidget(self.xyfeedrate_entry, 12, 1) # Excellon Feedrate Z - frlabel = QtWidgets.QLabel('%s:' % _('Feedrate Z')) - frlabel.setToolTip( + self.frzlabel = QtWidgets.QLabel('%s:' % _('Feedrate Z')) + self.frzlabel.setToolTip( _("Tool speed while drilling\n" "(in units per minute).\n" "So called 'Plunge' feedrate.\n" "This is for linear move G01.") ) - self.feedrate_entry = FCDoubleSpinner(callback=self.confirmation_message) - self.feedrate_entry.set_precision(self.decimals) - self.feedrate_entry.set_range(0.0, 99999.9999) - self.feedrate_entry.setSingleStep(0.1) + self.feedrate_z_entry = FCDoubleSpinner(callback=self.confirmation_message) + self.feedrate_z_entry.set_precision(self.decimals) + self.feedrate_z_entry.set_range(0.0, 99999.9999) + self.feedrate_z_entry.setSingleStep(0.1) - self.grid3.addWidget(frlabel, 14, 0) - self.grid3.addWidget(self.feedrate_entry, 14, 1) + self.grid3.addWidget(self.frzlabel, 14, 0) + self.grid3.addWidget(self.feedrate_z_entry, 14, 1) # Excellon Rapid Feedrate self.feedrate_rapid_label = QtWidgets.QLabel('%s:' % _('Feedrate Rapids')) @@ -1092,8 +1088,8 @@ class ExcellonObjectUI(ObjectUI): self.grid3.addWidget(self.e_cut_entry, 17, 1) # Spindlespeed - spdlabel = QtWidgets.QLabel('%s:' % _('Spindle speed')) - spdlabel.setToolTip( + self.spindle_label = QtWidgets.QLabel('%s:' % _('Spindle speed')) + self.spindle_label.setToolTip( _("Speed of the spindle\n" "in RPM (optional)") ) @@ -1102,7 +1098,7 @@ class ExcellonObjectUI(ObjectUI): self.spindlespeed_entry.set_range(0, 1000000) self.spindlespeed_entry.setSingleStep(100) - self.grid3.addWidget(spdlabel, 19, 0) + self.grid3.addWidget(self.spindle_label, 19, 0) self.grid3.addWidget(self.spindlespeed_entry, 19, 1) # Dwell @@ -1647,8 +1643,8 @@ class GeometryObjectUI(ObjectUI): self.grid3.addWidget(self.tipangle_entry, 2, 1) # Cut Z - cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z')) - cutzlabel.setToolTip( + self.cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z')) + self.cutzlabel.setToolTip( _( "Cutting depth (negative)\n" "below the copper surface." @@ -1664,7 +1660,7 @@ class GeometryObjectUI(ObjectUI): self.cutz_entry.setSingleStep(0.1) - self.grid3.addWidget(cutzlabel, 3, 0) + self.grid3.addWidget(self.cutzlabel, 3, 0) self.grid3.addWidget(self.cutz_entry, 3, 1) # Multi-pass @@ -1694,8 +1690,8 @@ class GeometryObjectUI(ObjectUI): self.grid3.addWidget(self.maxdepth_entry, 4, 1) # Travel Z - travelzlabel = QtWidgets.QLabel('%s:' % _('Travel Z')) - travelzlabel.setToolTip( + self.travelzlabel = QtWidgets.QLabel('%s:' % _('Travel Z')) + self.travelzlabel.setToolTip( _("Height of the tool when\n" "moving without cutting.") ) @@ -1709,7 +1705,7 @@ class GeometryObjectUI(ObjectUI): self.travelz_entry.setSingleStep(0.1) - self.grid3.addWidget(travelzlabel, 5, 0) + self.grid3.addWidget(self.travelzlabel, 5, 0) self.grid3.addWidget(self.travelz_entry, 5, 1) # Tool change @@ -1771,8 +1767,8 @@ class GeometryObjectUI(ObjectUI): self.grid3.addWidget(self.gendz_entry, 9, 1) # Feedrate X-Y - frlabel = QtWidgets.QLabel('%s:' % _('Feedrate X-Y')) - frlabel.setToolTip( + self.frlabel = QtWidgets.QLabel('%s:' % _('Feedrate X-Y')) + self.frlabel.setToolTip( _("Cutting speed in the XY\n" "plane in units per minute") ) @@ -1781,23 +1777,23 @@ class GeometryObjectUI(ObjectUI): self.cncfeedrate_entry.set_range(0, 99999.9999) self.cncfeedrate_entry.setSingleStep(0.1) - self.grid3.addWidget(frlabel, 10, 0) + self.grid3.addWidget(self.frlabel, 10, 0) self.grid3.addWidget(self.cncfeedrate_entry, 10, 1) # Feedrate Z (Plunge) - frzlabel = QtWidgets.QLabel('%s:' % _('Feedrate Z')) - frzlabel.setToolTip( + self.frzlabel = QtWidgets.QLabel('%s:' % _('Feedrate Z')) + self.frzlabel.setToolTip( _("Cutting speed in the XY\n" "plane in units per minute.\n" "It is called also Plunge.") ) - self.cncplunge_entry = FCDoubleSpinner(callback=self.confirmation_message) - self.cncplunge_entry.set_precision(self.decimals) - self.cncplunge_entry.set_range(0, 99999.9999) - self.cncplunge_entry.setSingleStep(0.1) + self.feedrate_z_entry = FCDoubleSpinner(callback=self.confirmation_message) + self.feedrate_z_entry.set_precision(self.decimals) + self.feedrate_z_entry.set_range(0, 99999.9999) + self.feedrate_z_entry.setSingleStep(0.1) - self.grid3.addWidget(frzlabel, 11, 0) - self.grid3.addWidget(self.cncplunge_entry, 11, 1) + self.grid3.addWidget(self.frzlabel, 11, 0) + self.grid3.addWidget(self.feedrate_z_entry, 11, 1) # Feedrate rapids self.fr_rapidlabel = QtWidgets.QLabel('%s:' % _('Feedrate Rapids')) @@ -1843,8 +1839,8 @@ class GeometryObjectUI(ObjectUI): self.grid3.addWidget(self.e_cut_entry, 13, 1) # Spindlespeed - spdlabel = QtWidgets.QLabel('%s:' % _('Spindle speed')) - spdlabel.setToolTip( + self.spindle_label = QtWidgets.QLabel('%s:' % _('Spindle speed')) + self.spindle_label.setToolTip( _( "Speed of the spindle in RPM (optional).\n" "If LASER preprocessor is used,\n" @@ -1855,7 +1851,7 @@ class GeometryObjectUI(ObjectUI): self.cncspindlespeed_entry.set_range(0, 1000000) self.cncspindlespeed_entry.setSingleStep(100) - self.grid3.addWidget(spdlabel, 14, 0) + self.grid3.addWidget(self.spindle_label, 14, 0) self.grid3.addWidget(self.cncspindlespeed_entry, 14, 1) # Dwell diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index cde679cf..92e06f69 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -3152,12 +3152,12 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): "So called 'Plunge' feedrate.\n" "This is for linear move G01.") ) - self.feedrate_entry = FCDoubleSpinner() - self.feedrate_entry.set_precision(self.decimals) - self.feedrate_entry.set_range(0, 99999.9999) + self.feedrate_z_entry = FCDoubleSpinner() + self.feedrate_z_entry.set_precision(self.decimals) + self.feedrate_z_entry.set_range(0, 99999.9999) grid2.addWidget(frlabel, 5, 0) - grid2.addWidget(self.feedrate_entry, 5, 1) + grid2.addWidget(self.feedrate_z_entry, 5, 1) # Spindle speed spdlabel = QtWidgets.QLabel('%s:' % _('Spindle Speed')) @@ -4096,14 +4096,14 @@ class GeometryOptPrefGroupUI(OptionsGroupUI): "plane in units per minute.\n" "It is called also Plunge.") ) - self.cncplunge_entry = FCDoubleSpinner() - self.cncplunge_entry.set_range(0, 99999.9999) - self.cncplunge_entry.set_precision(self.decimals) - self.cncplunge_entry.setSingleStep(0.1) - self.cncplunge_entry.setWrapping(True) + self.feedrate_z_entry = FCDoubleSpinner() + self.feedrate_z_entry.set_range(0, 99999.9999) + self.feedrate_z_entry.set_precision(self.decimals) + self.feedrate_z_entry.setSingleStep(0.1) + self.feedrate_z_entry.setWrapping(True) grid1.addWidget(frz_label, 8, 0) - grid1.addWidget(self.cncplunge_entry, 8, 1) + grid1.addWidget(self.feedrate_z_entry, 8, 1) # Spindle Speed spdlabel = QtWidgets.QLabel('%s:' % _('Spindle speed')) diff --git a/preprocessors/marlin.py b/preprocessors/Marlin.py similarity index 98% rename from preprocessors/marlin.py rename to preprocessors/Marlin.py index 5eafd92d..65428e8f 100644 --- a/preprocessors/marlin.py +++ b/preprocessors/Marlin.py @@ -9,7 +9,7 @@ from FlatCAMPostProc import * -class marlin(FlatCAMPostProc): +class Marlin(FlatCAMPostProc): include_header = True coordinate_format = "%.*f" @@ -34,7 +34,7 @@ class marlin(FlatCAMPostProc): if str(p['options']['type']) == 'Geometry': gcode += ';Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + '\n' - gcode += ';Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + '\n' + '\n' + gcode += ';Feedrate rapids: ' + str(p['feedrate_rapid']) + units + '/min' + '\n' + '\n' gcode += ';Z_Cut: ' + str(p['z_cut']) + units + '\n' if str(p['options']['type']) == 'Geometry': diff --git a/preprocessors/Marlin_laser.py b/preprocessors/Marlin_laser.py new file mode 100644 index 00000000..e67e9bb5 --- /dev/null +++ b/preprocessors/Marlin_laser.py @@ -0,0 +1,122 @@ +# ########################################################## +# FlatCAM: 2D Post-processing for Manufacturing # +# Website: http://flatcam.org # +# File Author: Marius Adrian Stanciu (c) # +# Date: 8-Feb-2020 # +# License: MIT Licence # +# ########################################################## + +from FlatCAMPostProc import * + + +class Marlin_laser(FlatCAMPostProc): + + include_header = True + coordinate_format = "%.*f" + feedrate_format = '%.*f' + feedrate_rapid_format = feedrate_format + + def start_code(self, p): + units = ' ' + str(p['units']).lower() + coords_xy = p['xy_toolchange'] + gcode = '' + + xmin = '%.*f' % (p.coords_decimals, p['options']['xmin']) + xmax = '%.*f' % (p.coords_decimals, p['options']['xmax']) + ymin = '%.*f' % (p.coords_decimals, p['options']['ymin']) + ymax = '%.*f' % (p.coords_decimals, p['options']['ymax']) + + gcode += ';Feedrate: ' + str(p['feedrate']) + units + '/min' + '\n' + gcode += ';Feedrate rapids: ' + str(p['feedrate_rapid']) + units + '/min' + '\n' + '\n' + + gcode += ';Z Focus: ' + str(p['z_move']) + units + '\n' + + gcode += ';Steps per circle: ' + str(p['steps_per_circle']) + '\n' + + if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry': + gcode += ';Preprocessor Excellon: ' + str(p['pp_excellon_name']) + '\n' + else: + gcode += ';Preprocessor Geometry: ' + str(p['pp_geometry_name']) + '\n' + '\n' + + gcode += ';X range: ' + '{: >9s}'.format(xmin) + ' ... ' + '{: >9s}'.format(xmax) + ' ' + units + '\n' + gcode += ';Y range: ' + '{: >9s}'.format(ymin) + ' ... ' + '{: >9s}'.format(ymax) + ' ' + units + '\n\n' + + gcode += ';Laser Power (Spindle Speed): ' + str(p['spindlespeed']) + '\n' + '\n' + + gcode += ('G20' if p.units.upper() == 'IN' else 'G21') + "\n" + gcode += 'G90\n' + gcode += 'G94' + + return gcode + + def startz_code(self, p): + if p.startz is not None: + return 'G0 Z' + self.coordinate_format % (p.coords_decimals, p.z_move) + else: + return '' + + def lift_code(self, p): + gcode = 'M400\n' + gcode += 'M5 S0' + return gcode + + def down_code(self, p): + sdir = {'CW': 'M3', 'CCW': 'M4'}[p.spindledir] + if p.spindlespeed: + return '%s S%s' % (sdir, str(p.spindlespeed)) + else: + return sdir + + def toolchange_code(self, p): + return '' + + def up_to_zero_code(self, p): + gcode = 'M400\n' + gcode += 'M5' + return gcode + + def position_code(self, p): + return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ + (p.coords_decimals, p.x, p.coords_decimals, p.y) + + def rapid_code(self, p): + return ('G0 ' + self.position_code(p)).format(**p) + " " + self.feedrate_rapid_code(p) + + def linear_code(self, p): + return ('G1 ' + self.position_code(p)).format(**p) + " " + self.inline_feedrate_code(p) + + def end_code(self, p): + coords_xy = p['xy_toolchange'] + gcode = ('G0 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + " " + self.feedrate_rapid_code(p) + "\n") + + if coords_xy is not None: + gcode += 'G0 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + " " + self.feedrate_rapid_code(p) + "\n" + + return gcode + + def feedrate_code(self, p): + return 'G1 F' + str(self.feedrate_format % (p.fr_decimals, p.feedrate)) + + def z_feedrate_code(self, p): + return 'G1 F' + str(self.feedrate_format % (p.fr_decimals, p.z_feedrate)) + + def inline_feedrate_code(self, p): + return 'F' + self.feedrate_format % (p.fr_decimals, p.feedrate) + + def feedrate_rapid_code(self, p): + return 'F' + self.feedrate_rapid_format % (p.fr_decimals, p.feedrate_rapid) + + def spindle_code(self, p): + sdir = {'CW': 'M3', 'CCW': 'M4'}[p.spindledir] + if p.spindlespeed: + return '%s S%s' % (sdir, str(p.spindlespeed)) + else: + return sdir + + def dwell_code(self, p): + return '' + + def spindle_stop_code(self, p): + gcode = 'M400\n' + gcode += 'M5' + return gcode diff --git a/preprocessors/grbl_laser.py b/preprocessors/grbl_laser.py index e975a703..a3f4da7d 100644 --- a/preprocessors/grbl_laser.py +++ b/preprocessors/grbl_laser.py @@ -28,7 +28,9 @@ class grbl_laser(FlatCAMPostProc): ymax = '%.*f' % (p.coords_decimals, p['options']['ymax']) gcode += '(Feedrate: ' + str(p['feedrate']) + units + '/min' + ')\n' - gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' + gcode += '(Feedrate rapids: ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' + + gcode += '(Z Focus: ' + str(p['z_move']) + units + ')\n' gcode += '(Steps per circle: ' + str(p['steps_per_circle']) + ')\n' @@ -40,10 +42,12 @@ class grbl_laser(FlatCAMPostProc): gcode += '(X range: ' + '{: >9s}'.format(xmin) + ' ... ' + '{: >9s}'.format(xmax) + ' ' + units + ')\n' gcode += '(Y range: ' + '{: >9s}'.format(ymin) + ' ... ' + '{: >9s}'.format(ymax) + ' ' + units + ')\n\n' + gcode += '(Laser Power (Spindle Speed): ' + str(p['spindlespeed']) + ')\n\n' + gcode += ('G20' if p.units.upper() == 'IN' else 'G21') + "\n" gcode += 'G90\n' gcode += 'G17\n' - gcode += 'G94\n' + gcode += 'G94' return gcode From 48029da52b726c8c37dbf6fb1548ccb2afe6195a Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 8 Feb 2020 20:38:51 +0200 Subject: [PATCH 073/209] - added a new preprocessor file for using laser on a Marlin motion controller but with the laser connected to one of the FAN pins, named 'Marlin_laser_use_FAN_pin' --- FlatCAMApp.py | 10 +- FlatCAMObj.py | 52 ++++++-- README.md | 11 +- camlib.py | 7 + flatcamGUI/ObjectUI.py | 48 +++---- flatcamGUI/PreferencesUI.py | 48 +++---- preprocessors/Berta_CNC.py | 4 +- .../{grbl_laser.py => GRBL_laser.py} | 11 +- preprocessors/ISEL_CNC.py | 2 +- preprocessors/ISEL_ICP_CNC.py | 2 +- preprocessors/Marlin.py | 10 +- preprocessors/Marlin_laser_use_FAN_pin.py | 120 ++++++++++++++++++ ...ser.py => Marlin_laser_use_Spindle_pin.py} | 10 +- preprocessors/Repetier.py | 2 +- preprocessors/Toolchange_Probe_MACH3.py | 2 +- preprocessors/default.py | 5 +- preprocessors/grbl_11.py | 3 +- 17 files changed, 256 insertions(+), 91 deletions(-) rename preprocessors/{grbl_laser.py => GRBL_laser.py} (92%) create mode 100644 preprocessors/Marlin_laser_use_FAN_pin.py rename preprocessors/{Marlin_laser.py => Marlin_laser_use_Spindle_pin.py} (93%) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 9189e8f8..36c06ba9 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -1001,7 +1001,7 @@ class App(QtCore.QObject): 'box, center_x, center_y, columns, combine, connect, contour, default, ' 'depthperpass, dia, diatol, dist, drilled_dias, drillz, dwelltime, ' 'extracut_length, ' - 'feedrate_z, grbl_11, grbl_laser, gridoffsety, gridx, gridy, has_offset, ' + 'feedrate_z, grbl_11, GRBL_laser, gridoffsety, gridx, gridy, has_offset, ' 'holes, hpgl, iso_type, line_xyz, margin, marlin, method, milled_dias, ' 'minoffset, name, offset, opt_type, order, outname, overlap, ' 'passes, postamble, pp, ppname_e, ppname_g, preamble, radius, ref, rest, ' @@ -1290,7 +1290,7 @@ class App(QtCore.QObject): # Excellon Options "excellon_drillz": self.ui.excellon_defaults_form.excellon_opt_group.cutz_entry, "excellon_travelz": self.ui.excellon_defaults_form.excellon_opt_group.travelz_entry, - "excellon_endz": self.ui.excellon_defaults_form.excellon_opt_group.eendz_entry, + "excellon_endz": self.ui.excellon_defaults_form.excellon_opt_group.endz_entry, "excellon_feedrate": self.ui.excellon_defaults_form.excellon_opt_group.feedrate_z_entry, "excellon_spindlespeed": self.ui.excellon_defaults_form.excellon_opt_group.spindlespeed_entry, "excellon_dwell": self.ui.excellon_defaults_form.excellon_opt_group.dwell_cb, @@ -1368,14 +1368,14 @@ class App(QtCore.QObject): "geometry_ppname_g": self.ui.geometry_defaults_form.geometry_opt_group.pp_geometry_name_cb, "geometry_toolchange": self.ui.geometry_defaults_form.geometry_opt_group.toolchange_cb, "geometry_toolchangez": self.ui.geometry_defaults_form.geometry_opt_group.toolchangez_entry, - "geometry_endz": self.ui.geometry_defaults_form.geometry_opt_group.gendz_entry, + "geometry_endz": self.ui.geometry_defaults_form.geometry_opt_group.endz_entry, "geometry_depthperpass": self.ui.geometry_defaults_form.geometry_opt_group.depthperpass_entry, "geometry_multidepth": self.ui.geometry_defaults_form.geometry_opt_group.multidepth_cb, # Geometry Advanced Options "geometry_toolchangexy": self.ui.geometry_defaults_form.geometry_adv_opt_group.toolchangexy_entry, "geometry_startz": self.ui.geometry_defaults_form.geometry_adv_opt_group.gstartz_entry, - "geometry_feedrate_rapid": self.ui.geometry_defaults_form.geometry_adv_opt_group.cncfeedrate_rapid_entry, + "geometry_feedrate_rapid": self.ui.geometry_defaults_form.geometry_adv_opt_group.feedrate_rapid_entry, "geometry_extracut": self.ui.geometry_defaults_form.geometry_adv_opt_group.extracut_cb, "geometry_extracut_length": self.ui.geometry_defaults_form.geometry_adv_opt_group.e_cut_entry, "geometry_z_pdepth": self.ui.geometry_defaults_form.geometry_adv_opt_group.pdepth_entry, @@ -2263,7 +2263,7 @@ class App(QtCore.QObject): 'box', 'center_x', 'center_y', 'columns', 'combine', 'connect', 'contour', 'default', 'depthperpass', 'dia', 'diatol', 'dist', 'drilled_dias', 'drillz', 'dwelltime', 'extracut_length', - 'feedrate_z', 'grbl_11', 'grbl_laser', 'gridoffsety', 'gridx', 'gridy', + 'feedrate_z', 'grbl_11', 'GRBL_laser', 'gridoffsety', 'gridx', 'gridy', 'has_offset', 'holes', 'hpgl', 'iso_type', 'line_xyz', 'margin', 'marlin', 'method', 'milled_dias', 'minoffset', 'name', 'offset', 'opt_type', 'order', 'outname', 'overlap', 'passes', 'postamble', 'pp', 'ppname_e', 'ppname_g', diff --git a/FlatCAMObj.py b/FlatCAMObj.py index fdc45475..f7faf045 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -2814,7 +2814,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): "dwell": self.ui.dwell_cb, "dwelltime": self.ui.dwelltime_entry, "startz": self.ui.estartz_entry, - "endz": self.ui.eendz_entry, + "endz": self.ui.endz_entry, "ppname_e": self.ui.pp_excellon_name_cb, "z_pdepth": self.ui.pdepth_entry, "feedrate_probe": self.ui.feedrate_probe_entry, @@ -3475,13 +3475,23 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): except AttributeError: pass - self.ui.travelzlabel.setText('%s:' % _("Focus Z")) + if 'marlin' in current_pp.lower(): + self.ui.travelzlabel.setText('%s:' % _("Focus Z")) + self.ui.endz_label.show() + self.ui.endz_entry.show() + else: + self.ui.travelzlabel.hide() + self.ui.travelz_entry.hide() + + self.ui.endz_label.hide() + self.ui.endz_entry.hide() try: self.ui.frzlabel.hide() self.ui.feedrate_z_entry.hide() except AttributeError: pass + self.ui.dwell_cb.hide() self.ui.dwelltime_entry.hide() @@ -3503,6 +3513,12 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.ui.travelzlabel.setText('%s:' % _('Travel Z')) + self.ui.travelzlabel.show() + self.ui.travelz_entry.show() + + self.ui.endz_label.show() + self.ui.endz_entry.show() + try: self.ui.frzlabel.show() self.ui.feedrate_z_entry.show() @@ -4082,7 +4098,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): "travelz": self.ui.travelz_entry, "feedrate": self.ui.cncfeedrate_entry, "feedrate_z": self.ui.feedrate_z_entry, - "feedrate_rapid": self.ui.cncfeedrate_rapid_entry, + "feedrate_rapid": self.ui.feedrate_rapid_entry, "spindlespeed": self.ui.cncspindlespeed_entry, "dwell": self.ui.dwell_cb, "dwelltime": self.ui.dwelltime_entry, @@ -4095,7 +4111,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): "extracut_length": self.ui.e_cut_entry, "toolchange": self.ui.toolchangeg_cb, "toolchangez": self.ui.toolchangez_entry, - "endz": self.ui.gendz_entry, + "endz": self.ui.endz_entry, "cnctooldia": self.ui.addtool_entry }) @@ -4225,10 +4241,10 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ui.addtool_btn.hide() self.ui.copytool_btn.hide() self.ui.deltool_btn.hide() - # self.ui.endzlabel.hide() - # self.ui.gendz_entry.hide() + # self.ui.endz_label.hide() + # self.ui.endz_entry.hide() self.ui.fr_rapidlabel.hide() - self.ui.cncfeedrate_rapid_entry.hide() + self.ui.feedrate_rapid_entry.hide() self.ui.extracut_cb.hide() self.ui.e_cut_entry.hide() self.ui.pdepth_label.hide() @@ -5228,10 +5244,10 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): if 'marlin' in current_pp.lower() or 'custom' in current_pp.lower(): self.ui.fr_rapidlabel.show() - self.ui.cncfeedrate_rapid_entry.show() + self.ui.feedrate_rapid_entry.show() else: self.ui.fr_rapidlabel.hide() - self.ui.cncfeedrate_rapid_entry.hide() + self.ui.feedrate_rapid_entry.hide() if 'laser' in current_pp.lower(): self.ui.cutzlabel.hide() @@ -5242,13 +5258,23 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): except AttributeError: pass - self.ui.travelzlabel.setText('%s:' % _("Focus Z")) + if 'marlin' in current_pp.lower(): + self.ui.travelzlabel.setText('%s:' % _("Focus Z")) + self.ui.endz_label.show() + self.ui.endz_entry.show() + else: + self.ui.travelzlabel.hide() + self.ui.travelz_entry.hide() + + self.ui.endz_label.hide() + self.ui.endz_entry.hide() try: self.ui.frzlabel.hide() self.ui.feedrate_z_entry.hide() except AttributeError: pass + self.ui.dwell_cb.hide() self.ui.dwelltime_entry.hide() @@ -5270,6 +5296,12 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ui.travelzlabel.setText('%s:' % _('Travel Z')) + self.ui.travelzlabel.show() + self.ui.travelz_entry.show() + + self.ui.endz_label.show() + self.ui.endz_entry.show() + try: self.ui.frzlabel.show() self.ui.feedrate_z_entry.show() diff --git a/README.md b/README.md index 38b752bc..f727c607 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,9 @@ CAD program, and create G-Code for Isolation routing. 8.02.2020 -- added a new preprocessor for using laser on a Marlin 3D printer named 'Marlin_laser' +- added a new preprocessor for using laser on a Marlin 3D printer named 'Marlin_laser_use_Spindle_pin' - modified the Geometry UI when using laser preprocessors +- added a new preprocessor file for using laser on a Marlin motion controller but with the laser connected to one of the FAN pins, named 'Marlin_laser_use_FAN_pin' 5.02.2020 @@ -2772,7 +2773,7 @@ CAD program, and create G-Code for Isolation routing. - added options for trace segmentation that can be useful for auto-levelling (code snippet from Lei Zheng from a rejected pull request on FlatCAM https://bitbucket.org/realthunder/ ) - added shortcut key 'L' for creating 'New Excellon' - added shortcut key combo 'SHIFT+S' for Running a Script. -- modified grbl_laser postprocessor file so it includes a Sxxxx command on the line with M03 (laser active) whenever a value is enter in the Spindlespeed entry field +- modified GRBL_laser postprocessor file so it includes a Sxxxx command on the line with M03 (laser active) whenever a value is enter in the Spindlespeed entry field - remade the EDIT -> PREFERENCES window, the Excellon and Gerber sections. Created a new section named TOOLS 26.01.2019 @@ -2780,7 +2781,7 @@ CAD program, and create G-Code for Isolation routing. - fixed grbl_11 postprocessor in linear_code() function - added icons to the Project Tab context menu - added new entries to the Canvas context menu (Copy, Delete, Edit/Save, Move, New Excellon, New Geometry, New Project) -- fixed grbl_laser postprocessor file +- fixed GRBL_laser postprocessor file - updated function for copy of an Excellon object for the case when the object has slots - updated FlatCAMExcellon.merge() function to work in case some (or all) of the merged objects have slots @@ -2800,8 +2801,8 @@ CAD program, and create G-Code for Isolation routing. - added the Copy entry to the Project context menu - made the functions behind Disable and Enable project context menu entries, non-threaded to fix a possible issue - added multiple object selection on Open ... and Import ... (idea and code snippet came from Travers Carter, BitBucket user https://bitbucket.org/travc/) -- fixed 'grbl_laser' postprocessor bugs (missing functions) -- fixed display geometry for 'grbl_laser' postprocessor +- fixed 'GRBL_laser' postprocessor bugs (missing functions) +- fixed display geometry for 'GRBL_laser' postprocessor - Excellon Editor - added possibility to create an linear drill array rotated at an custom angle - added the Edit and Properties entries to the Project context menu diff --git a/camlib.py b/camlib.py index 217e3ef5..e3002d8a 100644 --- a/camlib.py +++ b/camlib.py @@ -4067,6 +4067,13 @@ class CNCjob(Geometry): command['Z'] = 1 else: command['Z'] = 0 + + match_lsr_pos_2 = re.search(r"^(M10[6|7])", gline) + if match_lsr_pos_2: + if 'M107' in match_lsr_pos_2.group(1): + command['Z'] = 1 + else: + command['Z'] = 0 elif self.pp_solderpaste_name is not None: if 'Paste' in self.pp_solderpaste_name: match_paste = re.search(r"X([\+-]?\d+.[\+-]?\d+)\s*Y([\+-]?\d+.[\+-]?\d+)", gline) diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index 0a08d60b..1bac450d 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -992,23 +992,23 @@ class ExcellonObjectUI(ObjectUI): self.grid3.addWidget(self.estartz_entry, 9, 1) # End move Z: - self.eendz_label = QtWidgets.QLabel('%s:' % _("End move Z")) - self.eendz_label.setToolTip( + self.endz_label = QtWidgets.QLabel('%s:' % _("End move Z")) + self.endz_label.setToolTip( _("Height of the tool after\n" "the last move at the end of the job.") ) - self.eendz_entry = FCDoubleSpinner(callback=self.confirmation_message) - self.eendz_entry.set_precision(self.decimals) + self.endz_entry = FCDoubleSpinner(callback=self.confirmation_message) + self.endz_entry.set_precision(self.decimals) if machinist_setting == 0: - self.eendz_entry.set_range(0.0, 9999.9999) + self.endz_entry.set_range(0.0, 9999.9999) else: - self.eendz_entry.set_range(-9999.9999, 9999.9999) + self.endz_entry.set_range(-9999.9999, 9999.9999) - self.eendz_entry.setSingleStep(0.1) + self.endz_entry.setSingleStep(0.1) - self.grid3.addWidget(self.eendz_label, 11, 0) - self.grid3.addWidget(self.eendz_entry, 11, 1) + self.grid3.addWidget(self.endz_label, 11, 0) + self.grid3.addWidget(self.endz_entry, 11, 1) # Feedrate X-Y self.frxylabel = QtWidgets.QLabel('%s:' % _('Feedrate X-Y')) @@ -1748,23 +1748,23 @@ class GeometryObjectUI(ObjectUI): # self.grid3.addWidget(self.gstartz_entry, 8, 1) # The Z value for the end move - self.endzlabel = QtWidgets.QLabel('%s:' % _('End move Z')) - self.endzlabel.setToolTip( + self.endz_label = QtWidgets.QLabel('%s:' % _('End move Z')) + self.endz_label.setToolTip( _("Height of the tool after\n" "the last move at the end of the job.") ) - self.gendz_entry = FCDoubleSpinner(callback=self.confirmation_message) - self.gendz_entry.set_precision(self.decimals) + self.endz_entry = FCDoubleSpinner(callback=self.confirmation_message) + self.endz_entry.set_precision(self.decimals) if machinist_setting == 0: - self.gendz_entry.set_range(0, 9999.9999) + self.endz_entry.set_range(0, 9999.9999) else: - self.gendz_entry.set_range(-9999.9999, 9999.9999) + self.endz_entry.set_range(-9999.9999, 9999.9999) - self.gendz_entry.setSingleStep(0.1) + self.endz_entry.setSingleStep(0.1) - self.grid3.addWidget(self.endzlabel, 9, 0) - self.grid3.addWidget(self.gendz_entry, 9, 1) + self.grid3.addWidget(self.endz_label, 9, 0) + self.grid3.addWidget(self.endz_entry, 9, 1) # Feedrate X-Y self.frlabel = QtWidgets.QLabel('%s:' % _('Feedrate X-Y')) @@ -1804,16 +1804,16 @@ class GeometryObjectUI(ObjectUI): "It is useful only for Marlin,\n" "ignore for any other cases.") ) - self.cncfeedrate_rapid_entry = FCDoubleSpinner(callback=self.confirmation_message) - self.cncfeedrate_rapid_entry.set_precision(self.decimals) - self.cncfeedrate_rapid_entry.set_range(0, 99999.9999) - self.cncfeedrate_rapid_entry.setSingleStep(0.1) + self.feedrate_rapid_entry = FCDoubleSpinner(callback=self.confirmation_message) + self.feedrate_rapid_entry.set_precision(self.decimals) + self.feedrate_rapid_entry.set_range(0, 99999.9999) + self.feedrate_rapid_entry.setSingleStep(0.1) self.grid3.addWidget(self.fr_rapidlabel, 12, 0) - self.grid3.addWidget(self.cncfeedrate_rapid_entry, 12, 1) + self.grid3.addWidget(self.feedrate_rapid_entry, 12, 1) # default values is to hide self.fr_rapidlabel.hide() - self.cncfeedrate_rapid_entry.hide() + self.feedrate_rapid_entry.hide() # Cut over 1st point in path self.extracut_cb = FCCheckBox('%s:' % _('Re-cut')) diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index 92e06f69..33c23ab3 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -3128,21 +3128,21 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): grid2.addWidget(self.toolchangez_entry, 3, 1) # End Move Z - endzlabel = QtWidgets.QLabel('%s:' % _('End move Z')) - endzlabel.setToolTip( + endz_label = QtWidgets.QLabel('%s:' % _('End move Z')) + endz_label.setToolTip( _("Height of the tool after\n" "the last move at the end of the job.") ) - self.eendz_entry = FCDoubleSpinner() - self.eendz_entry.set_precision(self.decimals) + self.endz_entry = FCDoubleSpinner() + self.endz_entry.set_precision(self.decimals) if machinist_setting == 0: - self.eendz_entry.set_range(0.0000, 9999.9999) + self.endz_entry.set_range(0.0000, 9999.9999) else: - self.eendz_entry.set_range(-9999.9999, 9999.9999) + self.endz_entry.set_range(-9999.9999, 9999.9999) - grid2.addWidget(endzlabel, 4, 0) - grid2.addWidget(self.eendz_entry, 4, 1) + grid2.addWidget(endz_label, 4, 0) + grid2.addWidget(self.endz_entry, 4, 1) # Feedrate Z frlabel = QtWidgets.QLabel('%s:' % _('Feedrate Z')) @@ -4055,24 +4055,24 @@ class GeometryOptPrefGroupUI(OptionsGroupUI): grid1.addWidget(self.toolchangez_entry, 5, 1) # End move Z - endzlabel = QtWidgets.QLabel('%s:' % _('End move Z')) - endzlabel.setToolTip( + endz_label = QtWidgets.QLabel('%s:' % _('End move Z')) + endz_label.setToolTip( _("Height of the tool after\n" "the last move at the end of the job.") ) - self.gendz_entry = FCDoubleSpinner() + self.endz_entry = FCDoubleSpinner() if machinist_setting == 0: - self.gendz_entry.set_range(0.000, 9999.9999) + self.endz_entry.set_range(0.000, 9999.9999) else: - self.gendz_entry.set_range(-9999.9999, 9999.9999) + self.endz_entry.set_range(-9999.9999, 9999.9999) - self.gendz_entry.set_precision(self.decimals) - self.gendz_entry.setSingleStep(0.1) - self.gendz_entry.setWrapping(True) + self.endz_entry.set_precision(self.decimals) + self.endz_entry.setSingleStep(0.1) + self.endz_entry.setWrapping(True) - grid1.addWidget(endzlabel, 6, 0) - grid1.addWidget(self.gendz_entry, 6, 1) + grid1.addWidget(endz_label, 6, 0) + grid1.addWidget(self.endz_entry, 6, 1) # Feedrate X-Y frlabel = QtWidgets.QLabel('%s:' % _('Feedrate X-Y')) @@ -4207,14 +4207,14 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI): "It is useful only for Marlin,\n" "ignore for any other cases.") ) - self.cncfeedrate_rapid_entry = FCDoubleSpinner() - self.cncfeedrate_rapid_entry.set_range(0, 99999.9999) - self.cncfeedrate_rapid_entry.set_precision(self.decimals) - self.cncfeedrate_rapid_entry.setSingleStep(0.1) - self.cncfeedrate_rapid_entry.setWrapping(True) + self.feedrate_rapid_entry = FCDoubleSpinner() + self.feedrate_rapid_entry.set_range(0, 99999.9999) + self.feedrate_rapid_entry.set_precision(self.decimals) + self.feedrate_rapid_entry.setSingleStep(0.1) + self.feedrate_rapid_entry.setWrapping(True) grid1.addWidget(fr_rapid_label, 4, 0) - grid1.addWidget(self.cncfeedrate_rapid_entry, 4, 1) + grid1.addWidget(self.feedrate_rapid_entry, 4, 1) # End move extra cut self.extracut_cb = FCCheckBox('%s' % _('Re-cut')) diff --git a/preprocessors/Berta_CNC.py b/preprocessors/Berta_CNC.py index 784f0cd0..6da9d5d6 100644 --- a/preprocessors/Berta_CNC.py +++ b/preprocessors/Berta_CNC.py @@ -22,7 +22,7 @@ class Berta_CNC(FlatCAMPostProc): def start_code(self, p): units = ' ' + str(p['units']).lower() coords_xy = p['xy_toolchange'] - gcode = '' + gcode = '(This preprocessor is used with a BERTA CNC router.)\n\n' xmin = '%.*f' % (p.coords_decimals, p['options']['xmin']) xmax = '%.*f' % (p.coords_decimals, p['options']['xmax']) @@ -80,7 +80,7 @@ class Berta_CNC(FlatCAMPostProc): gcode += 'G54\n' gcode += 'G0\n' gcode += '(Berta)\n' - gcode += 'G94\n' + gcode += 'G94' return gcode diff --git a/preprocessors/grbl_laser.py b/preprocessors/GRBL_laser.py similarity index 92% rename from preprocessors/grbl_laser.py rename to preprocessors/GRBL_laser.py index a3f4da7d..6c7a7c34 100644 --- a/preprocessors/grbl_laser.py +++ b/preprocessors/GRBL_laser.py @@ -12,7 +12,7 @@ from FlatCAMPostProc import * # is compatible with almost any version of Grbl. -class grbl_laser(FlatCAMPostProc): +class GRBL_laser(FlatCAMPostProc): include_header = True coordinate_format = "%.*f" @@ -20,7 +20,8 @@ class grbl_laser(FlatCAMPostProc): def start_code(self, p): units = ' ' + str(p['units']).lower() - gcode = '' + gcode = '(This preprocessor is used with a motion controller loaded with GRBL firmware. )\n' + gcode += '(It is for the case when it is used together with a LASER connected on the SPINDLE connector.)\n\n' xmin = '%.*f' % (p.coords_decimals, p['options']['xmin']) xmax = '%.*f' % (p.coords_decimals, p['options']['xmax']) @@ -55,7 +56,7 @@ class grbl_laser(FlatCAMPostProc): return '' def lift_code(self, p): - return 'M05 S0' + return 'M5' def down_code(self, p): sdir = {'CW': 'M03', 'CCW': 'M04'}[p.spindledir] @@ -68,7 +69,7 @@ class grbl_laser(FlatCAMPostProc): return '' def up_to_zero_code(self, p): - return 'M05' + return 'M5' def position_code(self, p): return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ @@ -106,4 +107,4 @@ class grbl_laser(FlatCAMPostProc): return '' def spindle_stop_code(self, p): - return 'M05' + return 'M5' diff --git a/preprocessors/ISEL_CNC.py b/preprocessors/ISEL_CNC.py index 7753669c..c32b4272 100644 --- a/preprocessors/ISEL_CNC.py +++ b/preprocessors/ISEL_CNC.py @@ -17,7 +17,7 @@ class ISEL_CNC(FlatCAMPostProc): def start_code(self, p): units = ' ' + str(p['units']).lower() coords_xy = p['xy_toolchange'] - gcode = '' + gcode = '(This preprocessor is used with a ISEL CNC router.)\n\n' xmin = '%.*f' % (p.coords_decimals, p['options']['xmin']) xmax = '%.*f' % (p.coords_decimals, p['options']['xmax']) diff --git a/preprocessors/ISEL_ICP_CNC.py b/preprocessors/ISEL_ICP_CNC.py index 5898437e..ca820d8f 100644 --- a/preprocessors/ISEL_ICP_CNC.py +++ b/preprocessors/ISEL_ICP_CNC.py @@ -15,7 +15,7 @@ class ISEL_ICP_CNC(FlatCAMPostProc): def start_code(self, p): units = ' ' + str(p['units']).lower() coords_xy = p['xy_toolchange'] - gcode = '' + gcode = '; This preprocessor is used with a ISEL ICP CNC router.\n\n' xmin = '%.*f' % (p.coords_decimals, p['options']['xmin']) xmax = '%.*f' % (p.coords_decimals, p['options']['xmax']) diff --git a/preprocessors/Marlin.py b/preprocessors/Marlin.py index 65428e8f..128d1937 100644 --- a/preprocessors/Marlin.py +++ b/preprocessors/Marlin.py @@ -66,8 +66,7 @@ class Marlin(FlatCAMPostProc): gcode += ';Spindle Speed: ' + str(p['spindlespeed']) + ' RPM' + '\n' + '\n' gcode += ('G20' if p.units.upper() == 'IN' else 'G21') + "\n" - gcode += 'G90\n' - gcode += 'G94\n' + gcode += 'G90' return gcode @@ -219,8 +218,11 @@ G0 Z{z_toolchange} return sdir def dwell_code(self, p): + gcode = 'G4 P' + str(p.dwelltime) if p.dwelltime: - return 'G4 P' + str(p.dwelltime) + return gcode def spindle_stop_code(self, p): - return 'M5' + gcode = 'M400\n' + gcode += 'M5' + return gcode diff --git a/preprocessors/Marlin_laser_use_FAN_pin.py b/preprocessors/Marlin_laser_use_FAN_pin.py new file mode 100644 index 00000000..36d958a4 --- /dev/null +++ b/preprocessors/Marlin_laser_use_FAN_pin.py @@ -0,0 +1,120 @@ +# ########################################################## +# FlatCAM: 2D Post-processing for Manufacturing # +# Website: http://flatcam.org # +# File Author: Marius Adrian Stanciu (c) # +# Date: 8-Feb-2020 # +# License: MIT Licence # +# ########################################################## + +from FlatCAMPostProc import * + + +class Marlin_laser_use_FAN_pin(FlatCAMPostProc): + + include_header = True + coordinate_format = "%.*f" + feedrate_format = '%.*f' + feedrate_rapid_format = feedrate_format + + def start_code(self, p): + units = ' ' + str(p['units']).lower() + coords_xy = p['xy_toolchange'] + gcode = ';This preprocessor is used with a motion controller loaded with MARLIN firmware.\n' + gcode += ';It is for the case when it is used together with a LASER connected on one of the FAN pins.\n\n' + + xmin = '%.*f' % (p.coords_decimals, p['options']['xmin']) + xmax = '%.*f' % (p.coords_decimals, p['options']['xmax']) + ymin = '%.*f' % (p.coords_decimals, p['options']['ymin']) + ymax = '%.*f' % (p.coords_decimals, p['options']['ymax']) + + gcode += ';Feedrate: ' + str(p['feedrate']) + units + '/min' + '\n' + gcode += ';Feedrate rapids: ' + str(p['feedrate_rapid']) + units + '/min' + '\n\n' + + gcode += ';Z Focus: ' + str(p['z_move']) + units + '\n' + + gcode += ';Steps per circle: ' + str(p['steps_per_circle']) + '\n' + + if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry': + gcode += ';Preprocessor Excellon: ' + str(p['pp_excellon_name']) + '\n' + else: + gcode += ';Preprocessor Geometry: ' + str(p['pp_geometry_name']) + '\n' + '\n' + + gcode += ';X range: ' + '{: >9s}'.format(xmin) + ' ... ' + '{: >9s}'.format(xmax) + ' ' + units + '\n' + gcode += ';Y range: ' + '{: >9s}'.format(ymin) + ' ... ' + '{: >9s}'.format(ymax) + ' ' + units + '\n\n' + + gcode += ';Laser Power (Spindle Speed): ' + str(p['spindlespeed']) + '\n' + '\n' + + gcode += ('G20' if p.units.upper() == 'IN' else 'G21') + "\n" + gcode += 'G90' + + return gcode + + def startz_code(self, p): + if p.startz is not None: + return 'G0 Z' + self.coordinate_format % (p.coords_decimals, p.z_move) + else: + return '' + + def lift_code(self, p): + gcode = 'M400\n' + gcode += 'M107' + return gcode + + def down_code(self, p): + if p.spindlespeed: + return '%s S%s' % ('M106', str(p.spindlespeed)) + else: + return 'M106' + + def toolchange_code(self, p): + return '' + + def up_to_zero_code(self, p): + gcode = 'M400\n' + gcode += 'M107' + return gcode + + def position_code(self, p): + return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ + (p.coords_decimals, p.x, p.coords_decimals, p.y) + + def rapid_code(self, p): + return ('G0 ' + self.position_code(p)).format(**p) + " " + self.feedrate_rapid_code(p) + + def linear_code(self, p): + return ('G1 ' + self.position_code(p)).format(**p) + " " + self.inline_feedrate_code(p) + + def end_code(self, p): + coords_xy = p['xy_toolchange'] + gcode = ('G0 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + " " + self.feedrate_rapid_code(p) + "\n") + + if coords_xy is not None: + gcode += 'G0 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + " " + self.feedrate_rapid_code(p) + "\n" + + return gcode + + def feedrate_code(self, p): + return 'G1 F' + str(self.feedrate_format % (p.fr_decimals, p.feedrate)) + + def z_feedrate_code(self, p): + return 'G1 F' + str(self.feedrate_format % (p.fr_decimals, p.z_feedrate)) + + def inline_feedrate_code(self, p): + return 'F' + self.feedrate_format % (p.fr_decimals, p.feedrate) + + def feedrate_rapid_code(self, p): + return 'F' + self.feedrate_rapid_format % (p.fr_decimals, p.feedrate_rapid) + + def spindle_code(self, p): + if p.spindlespeed: + return '%s S%s' % ('M106 ', str(p.spindlespeed)) + else: + return 'M106' + + def dwell_code(self, p): + return '' + + def spindle_stop_code(self, p): + gcode = 'M400\n' + gcode += 'M107' + return gcode diff --git a/preprocessors/Marlin_laser.py b/preprocessors/Marlin_laser_use_Spindle_pin.py similarity index 93% rename from preprocessors/Marlin_laser.py rename to preprocessors/Marlin_laser_use_Spindle_pin.py index e67e9bb5..a1f7fb1e 100644 --- a/preprocessors/Marlin_laser.py +++ b/preprocessors/Marlin_laser_use_Spindle_pin.py @@ -9,7 +9,7 @@ from FlatCAMPostProc import * -class Marlin_laser(FlatCAMPostProc): +class Marlin_laser_use_Spindle_pin(FlatCAMPostProc): include_header = True coordinate_format = "%.*f" @@ -19,7 +19,8 @@ class Marlin_laser(FlatCAMPostProc): def start_code(self, p): units = ' ' + str(p['units']).lower() coords_xy = p['xy_toolchange'] - gcode = '' + gcode = ';This preprocessor is used with a motion controller loaded with MARLIN firmware.\n' + gcode += ';It is for the case when it is used together with a LASER connected on the SPINDLE connector.\n\n' xmin = '%.*f' % (p.coords_decimals, p['options']['xmin']) xmax = '%.*f' % (p.coords_decimals, p['options']['xmax']) @@ -44,8 +45,7 @@ class Marlin_laser(FlatCAMPostProc): gcode += ';Laser Power (Spindle Speed): ' + str(p['spindlespeed']) + '\n' + '\n' gcode += ('G20' if p.units.upper() == 'IN' else 'G21') + "\n" - gcode += 'G90\n' - gcode += 'G94' + gcode += 'G90' return gcode @@ -57,7 +57,7 @@ class Marlin_laser(FlatCAMPostProc): def lift_code(self, p): gcode = 'M400\n' - gcode += 'M5 S0' + gcode += 'M5' return gcode def down_code(self, p): diff --git a/preprocessors/Repetier.py b/preprocessors/Repetier.py index c149513c..fa760dfd 100644 --- a/preprocessors/Repetier.py +++ b/preprocessors/Repetier.py @@ -19,7 +19,7 @@ class Repetier(FlatCAMPostProc): def start_code(self, p): units = ' ' + str(p['units']).lower() coords_xy = p['xy_toolchange'] - gcode = '' + gcode = ';This preprocessor is used with a motion controller loaded with REPETIER firmware.\n\n' xmin = '%.*f' % (p.coords_decimals, p['options']['xmin']) xmax = '%.*f' % (p.coords_decimals, p['options']['xmax']) diff --git a/preprocessors/Toolchange_Probe_MACH3.py b/preprocessors/Toolchange_Probe_MACH3.py index 38371154..424848f8 100644 --- a/preprocessors/Toolchange_Probe_MACH3.py +++ b/preprocessors/Toolchange_Probe_MACH3.py @@ -18,7 +18,7 @@ class Toolchange_Probe_MACH3(FlatCAMPostProc): def start_code(self, p): units = ' ' + str(p['units']).lower() coords_xy = p['xy_toolchange'] - gcode = '' + gcode = '(This preprocessor is used with MACH3 with probing height.)\n\n' xmin = '%.*f' % (p.coords_decimals, p['options']['xmin']) xmax = '%.*f' % (p.coords_decimals, p['options']['xmax']) diff --git a/preprocessors/default.py b/preprocessors/default.py index e57ed812..ce4bd85b 100644 --- a/preprocessors/default.py +++ b/preprocessors/default.py @@ -18,7 +18,8 @@ class default(FlatCAMPostProc): def start_code(self, p): units = ' ' + str(p['units']).lower() coords_xy = p['xy_toolchange'] - gcode = '' + gcode = '(This preprocessor is the default preprocessor used by FlatCAM.)\n' + gcode += '(It is made to work with MACH3 compatible motion controllers.)\n\n' xmin = '%.*f' % (p.coords_decimals, p['options']['xmin']) xmax = '%.*f' % (p.coords_decimals, p['options']['xmax']) @@ -66,7 +67,7 @@ class default(FlatCAMPostProc): gcode += ('G20\n' if p.units.upper() == 'IN' else 'G21\n') gcode += 'G90\n' - gcode += 'G94\n' + gcode += 'G94' return gcode diff --git a/preprocessors/grbl_11.py b/preprocessors/grbl_11.py index 9a53c0ab..a8a03b88 100644 --- a/preprocessors/grbl_11.py +++ b/preprocessors/grbl_11.py @@ -18,7 +18,8 @@ class grbl_11(FlatCAMPostProc): def start_code(self, p): units = ' ' + str(p['units']).lower() coords_xy = p['xy_toolchange'] - gcode = '' + gcode = '(This preprocessor is used with a motion controller loaded with GRBL firmware.)\n' + gcode += '(It is configured to be compatible with almost any version of GRBL firmware.)\n\n' xmin = '%.*f' % (p.coords_decimals, p['options']['xmin']) xmax = '%.*f' % (p.coords_decimals, p['options']['xmax']) From d33505096c518f2e926b62ae1120dfea67b375d9 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 8 Feb 2020 22:38:08 +0200 Subject: [PATCH 074/209] - modified the Excellon GCode generation so now it can use multi depth drilling; modified the preprocessors to show the number of passes --- FlatCAMApp.py | 4 + FlatCAMObj.py | 18 ++- README.md | 1 + camlib.py | 141 ++++++++++++++++++------ flatcamGUI/PreferencesUI.py | 80 ++++++++++---- preprocessors/ISEL_CNC.py | 7 +- preprocessors/ISEL_ICP_CNC.py | 8 +- preprocessors/Marlin.py | 7 +- preprocessors/Repetier.py | 7 +- preprocessors/Toolchange_Custom.py | 7 +- preprocessors/Toolchange_Probe_MACH3.py | 7 +- preprocessors/Toolchange_manual.py | 7 +- preprocessors/default.py | 7 +- preprocessors/grbl_11.py | 7 +- preprocessors/line_xyz.py | 7 +- 15 files changed, 215 insertions(+), 100 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 36c06ba9..8fe6897a 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -633,6 +633,8 @@ class App(QtCore.QObject): # Excellon Options "excellon_drillz": -1.7, + "excellon_multidepth": False, + "excellon_depthperpass": 0.7, "excellon_travelz": 2, "excellon_endz": 0.5, "excellon_feedrate": 300, @@ -1289,6 +1291,8 @@ class App(QtCore.QObject): # Excellon Options "excellon_drillz": self.ui.excellon_defaults_form.excellon_opt_group.cutz_entry, + "excellon_multidepth": self.ui.excellon_defaults_form.excellon_opt_group.mpass_cb, + "excellon_depthperpass":self.ui.excellon_defaults_form.excellon_opt_group.maxdepth_entry, "excellon_travelz": self.ui.excellon_defaults_form.excellon_opt_group.travelz_entry, "excellon_endz": self.ui.excellon_defaults_form.excellon_opt_group.endz_entry, "excellon_feedrate": self.ui.excellon_defaults_form.excellon_opt_group.feedrate_z_entry, diff --git a/FlatCAMObj.py b/FlatCAMObj.py index f7faf045..6567993f 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -2317,6 +2317,8 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): "plot": True, "solid": False, "drillz": -0.1, + "multidepth": False, + "depthperpass": 0.7, "travelz": 0.1, "feedrate": 5.0, "feedrate_rapid": 5.0, @@ -2803,6 +2805,8 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): "plot": self.ui.plot_cb, "solid": self.ui.solid_cb, "drillz": self.ui.cutz_entry, + "multidepth": self.ui.mpass_cb, + "depthperpass": self.ui.maxdepth_entry, "travelz": self.ui.travelz_entry, "feedrate": self.ui.feedrate_z_entry, "feedrate_rapid": self.ui.feedrate_rapid_entry, @@ -2983,16 +2987,16 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.ui.extracut_cb.show() self.ui.e_cut_entry.show() - if 'laser' not in self.ui.pp_excellon_name_cb.get_value().lower(): - self.ui.mpass_cb.show() - self.ui.maxdepth_entry.show() + # if 'laser' not in self.ui.pp_excellon_name_cb.get_value().lower(): + # self.ui.mpass_cb.show() + # self.ui.maxdepth_entry.show() else: self.ui.mill_type_label.hide() self.ui.mill_type_radio.hide() self.ui.mill_dia_label.hide() self.ui.mill_dia_entry.hide() - self.ui.mpass_cb.hide() - self.ui.maxdepth_entry.hide() + # self.ui.mpass_cb.hide() + # self.ui.maxdepth_entry.hide() self.ui.frxylabel.hide() self.ui.xyfeedrate_entry.hide() self.ui.extracut_cb.hide() @@ -3580,6 +3584,10 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): job_obj.options['ppname_e'] = pp_excellon_name job_obj.z_cut = float(self.options["drillz"]) + + job_obj.multidepth = self.options["multidepth"] + job_obj.z_depthpercut = self.options["depthperpass"] + job_obj.tool_offset = self.tool_offset job_obj.z_move = float(self.options["travelz"]) job_obj.feedrate = float(self.options["feedrate"]) diff --git a/README.md b/README.md index f727c607..434c81bb 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ CAD program, and create G-Code for Isolation routing. - added a new preprocessor for using laser on a Marlin 3D printer named 'Marlin_laser_use_Spindle_pin' - modified the Geometry UI when using laser preprocessors - added a new preprocessor file for using laser on a Marlin motion controller but with the laser connected to one of the FAN pins, named 'Marlin_laser_use_FAN_pin' +- modified the Excellon GCode generation so now it can use multi depth drilling; modified the preprocessors to show the number of passes 5.02.2020 diff --git a/camlib.py b/camlib.py index e3002d8a..2c62d018 100644 --- a/camlib.py +++ b/camlib.py @@ -2230,7 +2230,7 @@ class CNCjob(Geometry): z_cut=-0.002, z_move=0.1, feedrate=3.0, feedrate_z=3.0, feedrate_rapid=3.0, feedrate_probe=3.0, pp_geometry_name='default', pp_excellon_name='default', - depthpercut=0.1,z_pdepth=-0.02, + depthpercut=0.1, z_pdepth=-0.02, spindlespeed=None, spindledir='CW', dwell=True, dwelltime=1000, toolchangez=0.787402, toolchange_xy=[0.0, 0.0], endz=2.0, @@ -2265,7 +2265,10 @@ class CNCjob(Geometry): self.toolC = tooldia + self.startz = None self.z_end = endz + + self.multidepth = False self.z_depthpercut = depthpercut self.unitcode = {"IN": "G20", "MM": "G21"} @@ -2566,8 +2569,6 @@ class CNCjob(Geometry): [it[0], it[1], drill_no, slot_no] ) - print(self.options['Tools_in_use']) - self.app.inform.emit(_("Creating a list of points to drill...")) # Points (Group by tool) points = dict() @@ -2777,18 +2778,43 @@ class CNCjob(Geometry): locy = locations[k][1] gcode += self.doformat(p.rapid_code, x=locx, y=locy) - gcode += self.doformat(p.down_code, x=locx, y=locy) - measured_down_distance += abs(self.z_cut) + abs(self.z_move) + if self.multidepth and abs(self.z_cut) > abs(self.z_depthpercut): + doc = deepcopy(self.z_cut) + self.z_cut = 0.0 + + while abs(self.z_cut) < abs(doc): + + self.z_cut -= self.z_depthpercut + if abs(doc) < abs(self.z_cut) < (abs(doc) + self.z_depthpercut): + self.z_cut = doc + gcode += self.doformat(p.down_code, x=locx, y=locy) + + measured_down_distance += abs(self.z_cut) + abs(self.z_move) + + if self.f_retract is False: + gcode += self.doformat(p.up_to_zero_code, x=locx, y=locy) + measured_up_to_zero_distance += abs(self.z_cut) + measured_lift_distance += abs(self.z_move) + else: + measured_lift_distance += abs(self.z_cut) + abs(self.z_move) + + gcode += self.doformat(p.lift_code, x=locx, y=locy) - if self.f_retract is False: - gcode += self.doformat(p.up_to_zero_code, x=locx, y=locy) - measured_up_to_zero_distance += abs(self.z_cut) - measured_lift_distance += abs(self.z_move) else: - measured_lift_distance += abs(self.z_cut) + abs(self.z_move) + gcode += self.doformat(p.down_code, x=locx, y=locy) + + measured_down_distance += abs(self.z_cut) + abs(self.z_move) + + if self.f_retract is False: + gcode += self.doformat(p.up_to_zero_code, x=locx, y=locy) + measured_up_to_zero_distance += abs(self.z_cut) + measured_lift_distance += abs(self.z_move) + else: + measured_lift_distance += abs(self.z_cut) + abs(self.z_move) + + gcode += self.doformat(p.lift_code, x=locx, y=locy) - gcode += self.doformat(p.lift_code, x=locx, y=locy) measured_distance += abs(distance_euclidian(locx, locy, self.oldx, self.oldy)) self.oldx = locx self.oldy = locy @@ -2920,18 +2946,43 @@ class CNCjob(Geometry): locy = locations[k][1] gcode += self.doformat(p.rapid_code, x=locx, y=locy) - gcode += self.doformat(p.down_code, x=locx, y=locy) - measured_down_distance += abs(self.z_cut) + abs(self.z_move) + if self.multidepth and abs(self.z_cut) > abs(self.z_depthpercut): + doc = deepcopy(self.z_cut) + self.z_cut = 0.0 + + while abs(self.z_cut) < abs(doc): + + self.z_cut -= self.z_depthpercut + if abs(doc) < abs(self.z_cut) < (abs(doc) + self.z_depthpercut): + self.z_cut = doc + gcode += self.doformat(p.down_code, x=locx, y=locy) + + measured_down_distance += abs(self.z_cut) + abs(self.z_move) + + if self.f_retract is False: + gcode += self.doformat(p.up_to_zero_code, x=locx, y=locy) + measured_up_to_zero_distance += abs(self.z_cut) + measured_lift_distance += abs(self.z_move) + else: + measured_lift_distance += abs(self.z_cut) + abs(self.z_move) + + gcode += self.doformat(p.lift_code, x=locx, y=locy) - if self.f_retract is False: - gcode += self.doformat(p.up_to_zero_code, x=locx, y=locy) - measured_up_to_zero_distance += abs(self.z_cut) - measured_lift_distance += abs(self.z_move) else: - measured_lift_distance += abs(self.z_cut) + abs(self.z_move) + gcode += self.doformat(p.down_code, x=locx, y=locy) + + measured_down_distance += abs(self.z_cut) + abs(self.z_move) + + if self.f_retract is False: + gcode += self.doformat(p.up_to_zero_code, x=locx, y=locy) + measured_up_to_zero_distance += abs(self.z_cut) + measured_lift_distance += abs(self.z_move) + else: + measured_lift_distance += abs(self.z_cut) + abs(self.z_move) + + gcode += self.doformat(p.lift_code, x=locx, y=locy) - gcode += self.doformat(p.lift_code, x=locx, y=locy) measured_distance += abs(distance_euclidian(locx, locy, self.oldx, self.oldy)) self.oldx = locx self.oldy = locy @@ -3023,22 +3074,50 @@ class CNCjob(Geometry): # graceful abort requested by the user raise FlatCAMApp.GracefulException - gcode += self.doformat(p.rapid_code, x=point[0], y=point[1]) - gcode += self.doformat(p.down_code, x=point[0], y=point[1]) + locx = point[0] + locy = point[1] - measured_down_distance += abs(self.z_cut) + abs(self.z_move) + gcode += self.doformat(p.rapid_code, x=locx, y=locy) + + if self.multidepth and abs(self.z_cut) > abs(self.z_depthpercut): + doc = deepcopy(self.z_cut) + self.z_cut = 0.0 + + while abs(self.z_cut) < abs(doc): + + self.z_cut -= self.z_depthpercut + if abs(doc) < abs(self.z_cut) < (abs(doc) + self.z_depthpercut): + self.z_cut = doc + gcode += self.doformat(p.down_code, x=locx, y=locy) + + measured_down_distance += abs(self.z_cut) + abs(self.z_move) + + if self.f_retract is False: + gcode += self.doformat(p.up_to_zero_code, x=locx, y=locy) + measured_up_to_zero_distance += abs(self.z_cut) + measured_lift_distance += abs(self.z_move) + else: + measured_lift_distance += abs(self.z_cut) + abs(self.z_move) + + gcode += self.doformat(p.lift_code, x=locx, y=locy) - if self.f_retract is False: - gcode += self.doformat(p.up_to_zero_code, x=point[0], y=point[1]) - measured_up_to_zero_distance += abs(self.z_cut) - measured_lift_distance += abs(self.z_move) else: - measured_lift_distance += abs(self.z_cut) + abs(self.z_move) + gcode += self.doformat(p.down_code, x=locx, y=locy) - gcode += self.doformat(p.lift_code, x=point[0], y=point[1]) - measured_distance += abs(distance_euclidian(point[0], point[1], self.oldx, self.oldy)) - self.oldx = point[0] - self.oldy = point[1] + measured_down_distance += abs(self.z_cut) + abs(self.z_move) + + if self.f_retract is False: + gcode += self.doformat(p.up_to_zero_code, x=locx, y=locy) + measured_up_to_zero_distance += abs(self.z_cut) + measured_lift_distance += abs(self.z_move) + else: + measured_lift_distance += abs(self.z_cut) + abs(self.z_move) + + gcode += self.doformat(p.lift_code, x=locx, y=locy) + + measured_distance += abs(distance_euclidian(locx, locy, self.oldx, self.oldy)) + self.oldx = locx + self.oldy = locy loc_nr += 1 disp_number = int(np.interp(loc_nr, [0, geo_len], [0, 100])) diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index 33c23ab3..b003b71c 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -3074,7 +3074,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): _("Drill depth (negative)\n" "below the copper surface.") ) - grid2.addWidget(cutzlabel, 0, 0) + self.cutz_entry = FCDoubleSpinner() if machinist_setting == 0: @@ -3084,15 +3084,38 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): self.cutz_entry.setSingleStep(0.1) self.cutz_entry.set_precision(self.decimals) + + grid2.addWidget(cutzlabel, 0, 0) grid2.addWidget(self.cutz_entry, 0, 1) + # Multi-Depth + self.mpass_cb = FCCheckBox('%s:' % _("Multi-Depth")) + self.mpass_cb.setToolTip( + _( + "Use multiple passes to limit\n" + "the cut depth in each pass. Will\n" + "cut multiple times until Cut Z is\n" + "reached." + ) + ) + + self.maxdepth_entry = FCDoubleSpinner() + self.maxdepth_entry.set_precision(self.decimals) + self.maxdepth_entry.set_range(0, 9999.9999) + self.maxdepth_entry.setSingleStep(0.1) + + self.maxdepth_entry.setToolTip(_("Depth of each pass (positive).")) + + grid2.addWidget(self.mpass_cb, 1, 0) + grid2.addWidget(self.maxdepth_entry, 1, 1) + # Travel Z travelzlabel = QtWidgets.QLabel('%s:' % _('Travel Z')) travelzlabel.setToolTip( _("Tool height when travelling\n" "across the XY plane.") ) - grid2.addWidget(travelzlabel, 1, 0) + self.travelz_entry = FCDoubleSpinner() self.travelz_entry.set_precision(self.decimals) @@ -3101,7 +3124,8 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): else: self.travelz_entry.set_range(-9999.9999, 9999.9999) - grid2.addWidget(self.travelz_entry, 1, 1) + grid2.addWidget(travelzlabel, 2, 0) + grid2.addWidget(self.travelz_entry, 2, 1) # Tool change: self.toolchange_cb = FCCheckBox('%s' % _("Tool change")) @@ -3109,14 +3133,15 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): _("Include tool-change sequence\n" "in G-Code (Pause for tool change).") ) - grid2.addWidget(self.toolchange_cb, 2, 0, 1, 2) + grid2.addWidget(self.toolchange_cb, 3, 0, 1, 2) + # Tool Change Z toolchangezlabel = QtWidgets.QLabel('%s:' % _('Toolchange Z')) toolchangezlabel.setToolTip( _("Z-axis position (height) for\n" "tool change.") ) - grid2.addWidget(toolchangezlabel, 3, 0) + self.toolchangez_entry = FCDoubleSpinner() self.toolchangez_entry.set_precision(self.decimals) @@ -3125,7 +3150,8 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): else: self.toolchangez_entry.set_range(-9999.9999, 9999.9999) - grid2.addWidget(self.toolchangez_entry, 3, 1) + grid2.addWidget(toolchangezlabel, 4, 0) + grid2.addWidget(self.toolchangez_entry, 4, 1) # End Move Z endz_label = QtWidgets.QLabel('%s:' % _('End move Z')) @@ -3141,8 +3167,8 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): else: self.endz_entry.set_range(-9999.9999, 9999.9999) - grid2.addWidget(endz_label, 4, 0) - grid2.addWidget(self.endz_entry, 4, 1) + grid2.addWidget(endz_label, 5, 0) + grid2.addWidget(self.endz_entry, 5, 1) # Feedrate Z frlabel = QtWidgets.QLabel('%s:' % _('Feedrate Z')) @@ -3156,8 +3182,8 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): self.feedrate_z_entry.set_precision(self.decimals) self.feedrate_z_entry.set_range(0, 99999.9999) - grid2.addWidget(frlabel, 5, 0) - grid2.addWidget(self.feedrate_z_entry, 5, 1) + grid2.addWidget(frlabel, 6, 0) + grid2.addWidget(self.feedrate_z_entry, 6, 1) # Spindle speed spdlabel = QtWidgets.QLabel('%s:' % _('Spindle Speed')) @@ -3165,11 +3191,13 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): _("Speed of the spindle\n" "in RPM (optional)") ) - grid2.addWidget(spdlabel, 6, 0) + self.spindlespeed_entry = FCSpinner() self.spindlespeed_entry.set_range(0, 1000000) self.spindlespeed_entry.setSingleStep(100) - grid2.addWidget(self.spindlespeed_entry, 6, 1) + + grid2.addWidget(spdlabel, 10, 0) + grid2.addWidget(self.spindlespeed_entry, 10, 1) # Dwell self.dwell_cb = FCCheckBox('%s' % _('Enable Dwell')) @@ -3177,16 +3205,18 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): _("Pause to allow the spindle to reach its\n" "speed before cutting.") ) - grid2.addWidget(self.dwell_cb, 7, 0, 1, 2) + grid2.addWidget(self.dwell_cb, 11, 0, 1, 2) + + # Dwell Time dwelltime = QtWidgets.QLabel('%s:' % _('Duration')) dwelltime.setToolTip(_("Number of time units for spindle to dwell.")) self.dwelltime_entry = FCDoubleSpinner() self.dwelltime_entry.set_precision(self.decimals) self.dwelltime_entry.set_range(0, 99999.9999) - grid2.addWidget(dwelltime, 8, 0) - grid2.addWidget(self.dwelltime_entry, 8, 1) + grid2.addWidget(dwelltime, 12, 0) + grid2.addWidget(self.dwelltime_entry, 12, 1) self.ois_dwell_exc = OptionalInputSection(self.dwell_cb, [self.dwelltime_entry]) @@ -3196,10 +3226,12 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): _("The preprocessor JSON file that dictates\n" "Gcode output.") ) - grid2.addWidget(pp_excellon_label, 9, 0) + self.pp_excellon_name_cb = FCComboBox() self.pp_excellon_name_cb.setFocusPolicy(Qt.StrongFocus) - grid2.addWidget(self.pp_excellon_name_cb, 9, 1) + + grid2.addWidget(pp_excellon_label, 14, 0) + grid2.addWidget(self.pp_excellon_name_cb, 14, 1) # ### Choose what to use for Gcode creation: Drills, Slots or Both excellon_gcode_type_label = QtWidgets.QLabel('%s' % _('Gcode')) @@ -3212,8 +3244,8 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): self.excellon_gcode_type_radio = RadioSet([{'label': 'Drills', 'value': 'drills'}, {'label': 'Slots', 'value': 'slots'}, {'label': 'Both', 'value': 'both'}]) - grid2.addWidget(excellon_gcode_type_label, 10, 0) - grid2.addWidget(self.excellon_gcode_type_radio, 10, 1) + grid2.addWidget(excellon_gcode_type_label, 15, 0) + grid2.addWidget(self.excellon_gcode_type_radio, 15, 1) # until I decide to implement this feature those remain disabled excellon_gcode_type_label.hide() @@ -3224,7 +3256,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): self.mill_hole_label.setToolTip( _("Create Geometry for milling holes.") ) - grid2.addWidget(self.mill_hole_label, 11, 0, 1, 2) + grid2.addWidget(self.mill_hole_label, 16, 0, 1, 2) tdlabel = QtWidgets.QLabel('%s:' % _('Drill Tool dia')) tdlabel.setToolTip( @@ -3234,8 +3266,8 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): self.tooldia_entry.set_precision(self.decimals) self.tooldia_entry.set_range(0, 999.9999) - grid2.addWidget(tdlabel, 12, 0) - grid2.addWidget(self.tooldia_entry, 12, 1) + grid2.addWidget(tdlabel, 18, 0) + grid2.addWidget(self.tooldia_entry, 18, 1) stdlabel = QtWidgets.QLabel('%s:' % _('Slot Tool dia')) stdlabel.setToolTip( @@ -3246,8 +3278,8 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): self.slot_tooldia_entry.set_precision(self.decimals) self.slot_tooldia_entry.set_range(0, 999.9999) - grid2.addWidget(stdlabel, 13, 0) - grid2.addWidget(self.slot_tooldia_entry, 13, 1) + grid2.addWidget(stdlabel, 21, 0) + grid2.addWidget(self.slot_tooldia_entry, 21, 1) self.layout.addStretch() diff --git a/preprocessors/ISEL_CNC.py b/preprocessors/ISEL_CNC.py index c32b4272..2e20c06e 100644 --- a/preprocessors/ISEL_CNC.py +++ b/preprocessors/ISEL_CNC.py @@ -35,10 +35,9 @@ class ISEL_CNC(FlatCAMPostProc): gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' - if str(p['options']['type']) == 'Geometry': - if p['multidepth'] is True: - gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ - str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' + if p['multidepth'] is True: + gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ + str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' diff --git a/preprocessors/ISEL_ICP_CNC.py b/preprocessors/ISEL_ICP_CNC.py index ca820d8f..92a08691 100644 --- a/preprocessors/ISEL_ICP_CNC.py +++ b/preprocessors/ISEL_ICP_CNC.py @@ -33,10 +33,10 @@ class ISEL_ICP_CNC(FlatCAMPostProc): gcode += '\n' gcode += '; Z_Cut: ' + str(p['z_cut']) + units + '\n' - if str(p['options']['type']) == 'Geometry': - if p['multidepth'] is True: - gcode += '; DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ - str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + '\n' + if p['multidepth'] is True: + gcode += '; DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ + str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + '\n' + gcode += '; Z_Move: ' + str(p['z_move']) + units + '\n' gcode += '; Z Toolchange: ' + str(p['z_toolchange']) + units + '\n' if coords_xy is not None: diff --git a/preprocessors/Marlin.py b/preprocessors/Marlin.py index 128d1937..d5144d59 100644 --- a/preprocessors/Marlin.py +++ b/preprocessors/Marlin.py @@ -37,10 +37,9 @@ class Marlin(FlatCAMPostProc): gcode += ';Feedrate rapids: ' + str(p['feedrate_rapid']) + units + '/min' + '\n' + '\n' gcode += ';Z_Cut: ' + str(p['z_cut']) + units + '\n' - if str(p['options']['type']) == 'Geometry': - if p['multidepth'] is True: - gcode += ';DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ - str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + '\n' + if p['multidepth'] is True: + gcode += ';DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ + str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + '\n' gcode += ';Z_Move: ' + str(p['z_move']) + units + '\n' gcode += ';Z Toolchange: ' + str(p['z_toolchange']) + units + '\n' diff --git a/preprocessors/Repetier.py b/preprocessors/Repetier.py index fa760dfd..3d31a176 100644 --- a/preprocessors/Repetier.py +++ b/preprocessors/Repetier.py @@ -37,10 +37,9 @@ class Repetier(FlatCAMPostProc): gcode += ';Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + '\n' + '\n' gcode += ';Z_Cut: ' + str(p['z_cut']) + units + '\n' - if str(p['options']['type']) == 'Geometry': - if p['multidepth'] is True: - gcode += ';DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ - str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + '\n' + if p['multidepth'] is True: + gcode += ';DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ + str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + '\n' gcode += ';Z_Move: ' + str(p['z_move']) + units + '\n' gcode += ';Z Toolchange: ' + str(p['z_toolchange']) + units + '\n' diff --git a/preprocessors/Toolchange_Custom.py b/preprocessors/Toolchange_Custom.py index ce6814b9..162defbb 100644 --- a/preprocessors/Toolchange_Custom.py +++ b/preprocessors/Toolchange_Custom.py @@ -36,10 +36,9 @@ class Toolchange_Custom(FlatCAMPostProc): gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' - if str(p['options']['type']) == 'Geometry': - if p['multidepth'] is True: - gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ - str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' + if p['multidepth'] is True: + gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ + str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' diff --git a/preprocessors/Toolchange_Probe_MACH3.py b/preprocessors/Toolchange_Probe_MACH3.py index 424848f8..3f0bb7c8 100644 --- a/preprocessors/Toolchange_Probe_MACH3.py +++ b/preprocessors/Toolchange_Probe_MACH3.py @@ -37,10 +37,9 @@ class Toolchange_Probe_MACH3(FlatCAMPostProc): gcode += '(Feedrate Probe ' + str(p['feedrate_probe']) + units + '/min' + ')\n' + '\n' gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' - if str(p['options']['type']) == 'Geometry': - if p['multidepth'] is True: - gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ - str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' + if p['multidepth'] is True: + gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ + str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' diff --git a/preprocessors/Toolchange_manual.py b/preprocessors/Toolchange_manual.py index ef583a7c..f096ab25 100644 --- a/preprocessors/Toolchange_manual.py +++ b/preprocessors/Toolchange_manual.py @@ -36,10 +36,9 @@ class Toolchange_manual(FlatCAMPostProc): gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' - if str(p['options']['type']) == 'Geometry': - if p['multidepth'] is True: - gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ - str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' + if p['multidepth'] is True: + gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ + str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' diff --git a/preprocessors/default.py b/preprocessors/default.py index ce4bd85b..216ba98e 100644 --- a/preprocessors/default.py +++ b/preprocessors/default.py @@ -37,10 +37,9 @@ class default(FlatCAMPostProc): gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' - if str(p['options']['type']) == 'Geometry': - if p['multidepth'] is True: - gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ - str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' + if p['multidepth'] is True: + gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ + str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' diff --git a/preprocessors/grbl_11.py b/preprocessors/grbl_11.py index a8a03b88..9fc8676b 100644 --- a/preprocessors/grbl_11.py +++ b/preprocessors/grbl_11.py @@ -37,10 +37,9 @@ class grbl_11(FlatCAMPostProc): gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' - if str(p['options']['type']) == 'Geometry': - if p['multidepth'] is True: - gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ - str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' + if p['multidepth'] is True: + gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ + str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' diff --git a/preprocessors/line_xyz.py b/preprocessors/line_xyz.py index b3beacdd..b6130729 100644 --- a/preprocessors/line_xyz.py +++ b/preprocessors/line_xyz.py @@ -36,10 +36,9 @@ class line_xyz(FlatCAMPostProc): gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' - if str(p['options']['type']) == 'Geometry': - if p['multidepth'] is True: - gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ - str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' + if p['multidepth'] is True: + gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ + str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' From c004c9082f9442ff7e123362f78324bd999a62c5 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 10 Feb 2020 04:00:34 +0200 Subject: [PATCH 075/209] - optimized the Paint and NCC Tools. When the Lines type of painting/clearing is used, the lines will try to arrange themselves on the direction that the lines length clearing the polygon are bigger --- README.md | 4 +++ camlib.py | 84 ++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 63 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 434c81bb..49619892 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +10.02.2020 + +- optimized the Paint and NCC Tools. When the Lines type of painting/clearing is used, the lines will try to arrange themselves on the direction that the lines length clearing the polygon are bigger + 8.02.2020 - added a new preprocessor for using laser on a Marlin 3D printer named 'Marlin_laser_use_Spindle_pin' diff --git a/camlib.py b/camlib.py index 2c62d018..165635b8 100644 --- a/camlib.py +++ b/camlib.py @@ -1445,37 +1445,71 @@ class Geometry(object): log.debug("camlib.Geometry.clear_polygon3() --> Could not buffer the Polygon") return None - # First line - try: - y = top - tooldia / 1.99999999 - while y > bot + tooldia / 1.999999999: - if self.app.abort_flag: - # graceful abort requested by the user - raise FlatCAMApp.GracefulException + # decide the direction of the lines + if abs(left - right) >= abs(top -bot): + # First line + try: + y = top - tooldia / 1.99999999 + while y > bot + tooldia / 1.999999999: + if self.app.abort_flag: + # graceful abort requested by the user + raise FlatCAMApp.GracefulException - # provide the app with a way to process the GUI events when in a blocking loop - QtWidgets.QApplication.processEvents() + # provide the app with a way to process the GUI events when in a blocking loop + QtWidgets.QApplication.processEvents() + line = LineString([(left, y), (right, y)]) + line = line.intersection(margin_poly) + lines_trimmed.append(line) + y -= tooldia * (1 - overlap) + if prog_plot: + self.plot_temp_shapes(line) + self.temp_shapes.redraw() + + # Last line + y = bot + tooldia / 2 line = LineString([(left, y), (right, y)]) line = line.intersection(margin_poly) - lines_trimmed.append(line) - y -= tooldia * (1 - overlap) - if prog_plot: - self.plot_temp_shapes(line) - self.temp_shapes.redraw() - # Last line - y = bot + tooldia / 2 - line = LineString([(left, y), (right, y)]) - line = line.intersection(margin_poly) + for ll in line: + lines_trimmed.append(ll) + if prog_plot: + self.plot_temp_shapes(line) + except Exception as e: + log.debug('camlib.Geometry.clear_polygon3() Processing poly --> %s' % str(e)) + return None + else: + # First line + try: + x = left + tooldia / 1.99999999 + while x < right - tooldia / 1.999999999: + if self.app.abort_flag: + # graceful abort requested by the user + raise FlatCAMApp.GracefulException - for ll in line: - lines_trimmed.append(ll) - if prog_plot: - self.plot_temp_shapes(line) - except Exception as e: - log.debug('camlib.Geometry.clear_polygon3() Processing poly --> %s' % str(e)) - return None + # provide the app with a way to process the GUI events when in a blocking loop + QtWidgets.QApplication.processEvents() + + line = LineString([(x, top), (x, bot)]) + line = line.intersection(margin_poly) + lines_trimmed.append(line) + x += tooldia * (1 - overlap) + if prog_plot: + self.plot_temp_shapes(line) + self.temp_shapes.redraw() + + # Last line + x = right + tooldia / 2 + line = LineString([(x, top), (x, bot)]) + line = line.intersection(margin_poly) + + for ll in line: + lines_trimmed.append(ll) + if prog_plot: + self.plot_temp_shapes(line) + except Exception as e: + log.debug('camlib.Geometry.clear_polygon3() Processing poly --> %s' % str(e)) + return None if prog_plot: self.temp_shapes.redraw() From 0807e9aaf12cbda4c59dd892f0fae59c5fdc3414 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 10 Feb 2020 04:28:46 +0200 Subject: [PATCH 076/209] - solved bug that made drilling with Marlin preprocessor very slow --- FlatCAMObj.py | 1 + README.md | 1 + 2 files changed, 2 insertions(+) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 6567993f..da4a2a07 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -3591,6 +3591,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): job_obj.tool_offset = self.tool_offset job_obj.z_move = float(self.options["travelz"]) job_obj.feedrate = float(self.options["feedrate"]) + job_obj.z_feedrate = float(self.options["feedrate"]) job_obj.feedrate_rapid = float(self.options["feedrate_rapid"]) job_obj.spindlespeed = float(self.options["spindlespeed"]) if self.options["spindlespeed"] != 0 else None diff --git a/README.md b/README.md index 49619892..8baee38b 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 10.02.2020 - optimized the Paint and NCC Tools. When the Lines type of painting/clearing is used, the lines will try to arrange themselves on the direction that the lines length clearing the polygon are bigger +- solved bug that made drilling with Marlin preprocessor very slow 8.02.2020 From e3be6ff22f1660537d95adcbb7183d500fd9d0f8 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 10 Feb 2020 04:30:32 +0200 Subject: [PATCH 077/209] - applied the fix for above bug to the TclCommand Drillcncjob too --- README.md | 1 + tclCommands/TclCommandDrillcncjob.py | 3 +++ 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index 8baee38b..1466cc4b 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ CAD program, and create G-Code for Isolation routing. - optimized the Paint and NCC Tools. When the Lines type of painting/clearing is used, the lines will try to arrange themselves on the direction that the lines length clearing the polygon are bigger - solved bug that made drilling with Marlin preprocessor very slow +- applied the fix for above bug to the TclCommand Drillcncjob too 8.02.2020 diff --git a/tclCommands/TclCommandDrillcncjob.py b/tclCommands/TclCommandDrillcncjob.py index a815569c..a420f2ae 100644 --- a/tclCommands/TclCommandDrillcncjob.py +++ b/tclCommands/TclCommandDrillcncjob.py @@ -185,7 +185,10 @@ class TclCommandDrillcncjob(TclCommandSignaled): opt_type = args["opt_type"] if "opt_type" in args and args["opt_type"] else 'B' job_obj.z_move = args["travelz"] if "travelz" in args and args["travelz"] else obj.options["travelz"] + job_obj.feedrate = args["feedrate"] if "feedrate" in args and args["feedrate"] else obj.options["feedrate"] + job_obj.z_feedrate = args["feedrate"] if "feedrate" in args and args["feedrate"] else \ + obj.options["feedrate"] job_obj.feedrate_rapid = args["feedrate_rapid"] \ if "feedrate_rapid" in args and args["feedrate_rapid"] else obj.options["feedrate_rapid"] From 82ab0d83d65f149dea2ab2f863487ea5241e8595 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 10 Feb 2020 12:27:49 +0200 Subject: [PATCH 078/209] - started a new way to clear the Gerber polygons based on the 'follow' lines --- README.md | 1 + camlib.py | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 141 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1466cc4b..bc8f6675 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ CAD program, and create G-Code for Isolation routing. - optimized the Paint and NCC Tools. When the Lines type of painting/clearing is used, the lines will try to arrange themselves on the direction that the lines length clearing the polygon are bigger - solved bug that made drilling with Marlin preprocessor very slow - applied the fix for above bug to the TclCommand Drillcncjob too +- started a new way to clear the Gerber polygons based on the 'follow' lines 8.02.2020 diff --git a/camlib.py b/camlib.py index 165635b8..2fb8180e 100644 --- a/camlib.py +++ b/camlib.py @@ -1446,7 +1446,7 @@ class Geometry(object): return None # decide the direction of the lines - if abs(left - right) >= abs(top -bot): + if abs(left - right) >= abs(top - bot): # First line try: y = top - tooldia / 1.99999999 @@ -1562,6 +1562,145 @@ class Geometry(object): return geoms + def fill_with_lines(self, line, aperture_size, tooldia, steps_per_circle, overlap=0.15, connect=True, contour=True, + prog_plot=False): + """ + Creates geometry of lines inside a polygon for a tool to cover + the whole area. + + This algorithm draws parallel lines inside the polygon. + + :param line: The target line that create painted polygon. + :type line: shapely.geometry.LineString or shapely.geometry.MultiLineString + :param tooldia: Tool diameter. + :param steps_per_circle: how many linear segments to use to approximate a circle + :param overlap: Tool path overlap percentage. + :param connect: Connect lines to avoid tool lifts. + :param contour: Paint around the edges. + :param prog_plot: boolean; if to use the progressive plotting + :return: + """ + + # log.debug("camlib.fill_with_lines()") + if not isinstance(line, LineString) or not isinstance(line, MultiLineString): + log.debug("camlib.Geometry.fill_with_lines() --> Not a LineString/MultiLineString but %s" % str(type(line))) + return None + + # ## The toolpaths + # Index first and last points in paths + def get_pts(o): + return [o.coords[0], o.coords[-1]] + + geoms = FlatCAMRTreeStorage() + geoms.get_points = get_pts + + lines_trimmed = [] + + polygon = line.buffer(aperture_size / 1.99999999999999999, int(steps_per_circle)) + + try: + margin_poly = polygon.buffer(-tooldia / 1.99999999, int(steps_per_circle)) + except Exception: + log.debug("camlib.Geometry.fill_with_lines() --> Could not buffer the Polygon, tool diameter too high") + return None + + # First line + try: + delta = 0 + while delta < aperture_size / 2: + if self.app.abort_flag: + # graceful abort requested by the user + raise FlatCAMApp.GracefulException + + # provide the app with a way to process the GUI events when in a blocking loop + QtWidgets.QApplication.processEvents() + + line = line.parallel_offset(distance=delta, side='left', resolution=int(steps_per_circle)) + line = line.intersection(margin_poly) + lines_trimmed.append(line) + + line = line.parallel_offset(distance=delta, side='right', resolution=int(steps_per_circle)) + line = line.intersection(margin_poly) + lines_trimmed.append(line) + + delta += tooldia * (1 - overlap) + if prog_plot: + self.plot_temp_shapes(line) + self.temp_shapes.redraw() + + # Last line + delta = aperture_size / 2 + + line = line.parallel_offset(distance=delta, side='left', resolution=int(steps_per_circle)) + line = line.intersection(margin_poly) + + for ll in line: + lines_trimmed.append(ll) + if prog_plot: + self.plot_temp_shapes(line) + + line = line.parallel_offset(distance=delta, side='left', resolution=int(steps_per_circle)) + line = line.intersection(margin_poly) + + for ll in line: + lines_trimmed.append(ll) + if prog_plot: + self.plot_temp_shapes(line) + except Exception as e: + log.debug('camlib.Geometry.fill_with_lines() Processing poly --> %s' % str(e)) + return None + + if prog_plot: + self.temp_shapes.redraw() + + lines_trimmed = unary_union(lines_trimmed) + + # Add lines to storage + try: + for line in lines_trimmed: + if isinstance(line, LineString) or isinstance(line, LinearRing): + geoms.insert(line) + else: + log.debug("camlib.Geometry.fill_with_lines(). Not a line: %s" % str(type(line))) + except TypeError: + # in case lines_trimmed are not iterable (Linestring, LinearRing) + geoms.insert(lines_trimmed) + + # Add margin (contour) to storage + if contour: + try: + for poly in margin_poly: + if isinstance(poly, Polygon) and not poly.is_empty: + geoms.insert(poly.exterior) + if prog_plot: + self.plot_temp_shapes(poly.exterior) + for ints in poly.interiors: + geoms.insert(ints) + if prog_plot: + self.plot_temp_shapes(ints) + except TypeError: + if isinstance(margin_poly, Polygon) and not margin_poly.is_empty: + marg_ext = margin_poly.exterior + geoms.insert(marg_ext) + if prog_plot: + self.plot_temp_shapes(margin_poly.exterior) + for ints in margin_poly.interiors: + geoms.insert(ints) + if prog_plot: + self.plot_temp_shapes(ints) + + if prog_plot: + self.temp_shapes.redraw() + + # Optimization: Reduce lifts + if connect: + # log.debug("Reducing tool lifts...") + geoms_conn = Geometry.paint_connect(geoms, polygon, tooldia, steps_per_circle) + if geoms_conn: + return geoms_conn + + return geoms + def scale(self, xfactor, yfactor, point=None): """ Scales all of the object's geometry by a given factor. Override From cf9f15152a01fcfb82fcf86db02105c964cda8fa Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 10 Feb 2020 13:46:03 +0200 Subject: [PATCH 079/209] - some cleanup and bug fixes for the Paint Tool --- README.md | 2 ++ flatcamTools/ToolPaint.py | 50 +++++++++++++++++++-------------------- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index bc8f6675..250aef2a 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ CAD program, and create G-Code for Isolation routing. - solved bug that made drilling with Marlin preprocessor very slow - applied the fix for above bug to the TclCommand Drillcncjob too - started a new way to clear the Gerber polygons based on the 'follow' lines +- some cleanup and bug fixes for the Paint Tool + 8.02.2020 diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 18f1f3a9..60ff4f07 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -542,7 +542,9 @@ class ToolPaint(FlatCAMTool, Gerber): self.bound_obj_name = "" self.bound_obj = None - self.tooldia_list = [] + self.tooldia_list = list() + self.tooldia = None + self.sel_rect = None self.o_name = None self.overlap = None @@ -1122,7 +1124,7 @@ class ToolPaint(FlatCAMTool, Gerber): if float('%.*f' % (self.decimals, tool_dia)) in tool_dias: if muted is None: - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Adding tool cancelled. Tool already in Tool Table.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Adding tool cancelled. Tool already in Tool Table.")) self.tools_table.itemChanged.connect(self.on_tool_edit) return else: @@ -1242,12 +1244,12 @@ class ToolPaint(FlatCAMTool, Gerber): # # self.app.inform.emit("[success] Tool was copied in the Tool Table.") - def on_tool_delete(self, rows_to_delete=None, all=None): + def on_tool_delete(self, rows_to_delete=None, all_tools=None): self.blockSignals(True) deleted_tools_list = [] - if all: + if all_tools: self.paint_tools.clear() self.blockSignals(False) self.build_ui() @@ -1316,25 +1318,20 @@ class ToolPaint(FlatCAMTool, Gerber): self.paint_obj = self.app.collection.get_by_name(str(self.obj_name)) except Exception as e: log.debug("ToolPaint.on_paint_button_click() --> %s" % str(e)) - self.app.inform.emit('[ERROR_NOTCL] %s: %s' % - (_("Could not retrieve object: %s"), - self.obj_name)) + self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object: %s"), self.obj_name)) return if self.paint_obj is None: - self.app.inform.emit('[ERROR_NOTCL] %s: %s' % - (_("Object not found"), - self.paint_obj)) + self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Object not found"), self.paint_obj)) return # test if the Geometry Object is multigeo and return Fail if True because # for now Paint don't work on MultiGeo if self.paint_obj.multigeo is True: - self.app.inform.emit('[ERROR_NOTCL] %s...' % - _("Can't do Paint on MultiGeo geometries")) + self.app.inform.emit('[ERROR_NOTCL] %s...' % _("Can't do Paint on MultiGeo geometries")) return 'Fail' - o_name = '%s_multitool_paint' % self.obj_name + self.o_name = '%s_mt_paint' % self.obj_name # use the selected tools in the tool table; get diameters self.tooldia_list = list() @@ -1347,8 +1344,7 @@ class ToolPaint(FlatCAMTool, Gerber): try: self.tooldia = float(self.tools_table.item(x.row(), 1).text().replace(',', '.')) except ValueError: - self.app.inform.emit('[ERROR_NOTCL] %s' % - _("Wrong value format entered, use a number.")) + self.app.inform.emit('[ERROR_NOTCL] %s' % _("Wrong value format entered, use a number.")) continue self.tooldia_list.append(self.tooldia) else: @@ -1401,7 +1397,7 @@ class ToolPaint(FlatCAMTool, Gerber): # Get source object. try: self.bound_obj = self.app.collection.get_by_name(self.bound_obj_name) - except Exception as e: + except Exception: self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), self.obj_name)) return "Could not retrieve object: %s" % self.obj_name @@ -1525,14 +1521,14 @@ class ToolPaint(FlatCAMTool, Gerber): _("Click the end point of the paint area.")) self.cursor_pos = self.app.plotcanvas.translate_coords(event_pos) - if self.app.grid_status() == True: + if self.app.grid_status(): self.cursor_pos = self.app.geo_editor.snap(self.cursor_pos[0], self.cursor_pos[1]) else: self.app.inform.emit(_("Zone added. Click to start adding next zone or right click to finish.")) self.app.delete_selection_shape() curr_pos = self.app.plotcanvas.translate_coords(event_pos) - if self.app.grid_status() == True: + if self.app.grid_status(): curr_pos = self.app.geo_editor.snap(curr_pos[0], curr_pos[1]) x0, y0 = self.cursor_pos[0], self.cursor_pos[1] @@ -1608,7 +1604,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.mouse_is_dragging = False # update the cursor position - if self.app.grid_status() == True: + if self.app.grid_status(): # Update cursor curr_pos = self.app.geo_editor.snap(curr_pos[0], curr_pos[1]) @@ -1768,14 +1764,14 @@ class ToolPaint(FlatCAMTool, Gerber): prog_plot=prog_plot) except FlatCAMApp.GracefulException: return "fail" - except Exception as e: - log.debug("ToolPaint.paint_poly().gen_paintarea().paint_p() --> %s" % str(e)) + except Exception as ee: + log.debug("ToolPaint.paint_poly().gen_paintarea().paint_p() --> %s" % str(ee)) if cpoly is not None: geo_obj.solid_geometry += list(cpoly.get_objects()) return cpoly else: - app_obj.inform.emit('[ERROR_NOTCL] %s' % _('Geometry could not be painted completely')) + app_obj.inform.emit('[ERROR_NOTCL] %s' % _('Geometry could not be painted completely')) return None current_uid = int(1) @@ -1843,7 +1839,11 @@ class ToolPaint(FlatCAMTool, Gerber): geo_obj.solid_geometry = cascaded_union(tools_storage[current_uid]['solid_geometry']) try: - a, b, c, d = geo_obj.solid_geometry.bounds + if isinstance(geo_obj.solid_geometry, list): + a, b, c, d = MultiPolygon(geo_obj.solid_geometry).bounds + else: + a, b, c, d = geo_obj.solid_geometry.bounds + geo_obj.options['xmin'] = a geo_obj.options['ymin'] = b geo_obj.options['xmax'] = c @@ -2194,7 +2194,8 @@ class ToolPaint(FlatCAMTool, Gerber): continue # try: - # # Polygons are the only really paintable geometries, lines in theory have no area to be painted + # # Polygons are the only really paintable geometries, + # # lines in theory have no area to be painted # if not isinstance(geo, Polygon): # continue # poly_buf = geo.buffer(-paint_margin) @@ -3114,7 +3115,6 @@ class ToolPaint(FlatCAMTool, Gerber): self.sel_rect = [] - @staticmethod def paint_bounds(geometry): def bounds_rec(o): From 76545de4347e4cc723bba6677cbb00f1354744d9 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Tue, 11 Feb 2020 00:14:50 +0200 Subject: [PATCH 080/209] - working on Tool Punch; finished the geometry update with the clear geometry for the case of Excellon method --- README.md | 4 ++++ flatcamTools/ToolPunchGerber.py | 41 ++++++++++++++++++--------------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index bc8f6675..11009b5a 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +11.02.2020 + +- working on Tool Punch; finished the geometry update with the clear geometry for the case of Excellon method + 10.02.2020 - optimized the Paint and NCC Tools. When the Lines type of painting/clearing is used, the lines will try to arrange themselves on the direction that the lines length clearing the polygon are bigger diff --git a/flatcamTools/ToolPunchGerber.py b/flatcamTools/ToolPunchGerber.py index 807bbe0c..b78cd9a0 100644 --- a/flatcamTools/ToolPunchGerber.py +++ b/flatcamTools/ToolPunchGerber.py @@ -522,38 +522,41 @@ class ToolPunchGerber(FlatCAMTool): # create the punched Gerber solid_geometry punched_solid_geometry = grb_solid_geometry.difference(exc_solid_geometry) - new_apertures = dict() + # update the gerber apertures to include the clear geometry so it can be exported successfully new_apertures = deepcopy(grb_obj.apertures) + new_apertures_items = new_apertures.items() + # find maximum aperture id + new_apid = max([int(x) for x, __ in new_apertures_items]) + + # store here the clear geometry, the key is the drill size holes_apertures = dict() - for apid, val in new_apertures.items(): + for apid, val in new_apertures_items: for elem in val['geometry']: # make it work only for Gerber Flashes who are Points in 'follow' if 'solid' in elem and isinstance(elem['follow'], Point): for drill in exc_obj.drills: - clear_apid = exc_obj.tools[drill['tool']]['C'] - exc_poly = drill['point'].buffer(clear_apid / 2.0) - if exc_poly.within(elem['solid']): + clear_apid_size = exc_obj.tools[drill['tool']]['C'] - if clear_apid not in holes_apertures or holes_apertures[clear_apid]['type'] != 'C': - holes_apertures[clear_apid] = dict() - holes_apertures[clear_apid]['type'] = 'C' - holes_apertures[clear_apid]['size'] = clear_apid - holes_apertures[clear_apid]['geometry'] = list() + # since there may be drills that do not drill into a pad we test only for drills in a pad + if drill['point'].within(elem['solid']): geo_elem = dict() - geo_elem['clear'] = exc_poly - geo_elem['follow'] = exc_poly.centroid - holes_apertures[clear_apid]['geometry'].append(deepcopy(geo_elem)) + geo_elem['clear'] = drill['point'] - elem['clear'] = exc_poly.centroid + if clear_apid_size not in holes_apertures: + holes_apertures[clear_apid_size] = dict() + holes_apertures[clear_apid_size]['type'] = 'C' + holes_apertures[clear_apid_size]['size'] = clear_apid_size + holes_apertures[clear_apid_size]['geometry'] = list() - for apid, val in new_apertures.items(): - for clear_apid, clear_val in holes_apertures.items(): - if round(clear_apid, self.decimals) == round(val['size'], self.decimals): - geo_elem = dict() + holes_apertures[clear_apid_size]['geometry'].append(deepcopy(geo_elem)) - val['geometry'].append(geo_elem) + # add the clear geometry to new apertures; it's easier than to test if there are apertures with the same + # size and add there the clear geometry + for hole_size, ap_val in holes_apertures.items(): + new_apid += 1 + new_apertures[str(new_apid)] = deepcopy(ap_val) def init_func(new_obj, app_obj): new_obj.options.update(grb_obj.options) From f9c63c03aaf4b2ab6c861324f7f189ad146cab28 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 12 Feb 2020 02:48:35 +0200 Subject: [PATCH 081/209] - working on Tool Punch; finished the geometry update with the clear geometry for the case of Fixed Diameter method --- README.md | 1 + flatcamTools/ToolPunchGerber.py | 81 ++++++++++++++++++++++++++++++--- 2 files changed, 75 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index ece316d7..f1f5f28e 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 11.02.2020 - working on Tool Punch; finished the geometry update with the clear geometry for the case of Excellon method +- working on Tool Punch; finished the geometry update with the clear geometry for the case of Fixed Diameter method 10.02.2020 diff --git a/flatcamTools/ToolPunchGerber.py b/flatcamTools/ToolPunchGerber.py index b78cd9a0..10bf4b92 100644 --- a/flatcamTools/ToolPunchGerber.py +++ b/flatcamTools/ToolPunchGerber.py @@ -5,15 +5,14 @@ # MIT Licence # # ########################################################## -from PyQt5 import QtGui, QtCore, QtWidgets +from PyQt5 import QtCore, QtWidgets from FlatCAMTool import FlatCAMTool -from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox, \ - OptionalHideInputSection, OptionalInputSection, FCComboBox +from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox from copy import deepcopy import logging -from shapely.geometry import Polygon, MultiPolygon, Point +from shapely.geometry import MultiPolygon, Point import gettext import FlatCAMTranslation as fcTranslate @@ -574,9 +573,13 @@ class ToolPunchGerber(FlatCAMTool): elif punch_method == 'fixed': punch_size = float(self.dia_entry.get_value()) + if punch_size == 0.0: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("The value of the fixed diameter is 0.0. Aborting.")) + return 'fail' + punching_geo = list() for apid in grb_obj.apertures: - if grb_obj.apertures[apid]['type'] == 'C': + if grb_obj.apertures[apid]['type'] == 'C' and self.circular_cb.get_value(): if punch_size >= float(grb_obj.apertures[apid]['size']): self.app.inform.emit('[ERROR_NOTCL] %s' % _(" Could not generate punched hole Gerber because the punch hole size" @@ -587,18 +590,37 @@ class ToolPunchGerber(FlatCAMTool): if 'follow' in elem: if isinstance(elem['follow'], Point): punching_geo.append(elem['follow'].buffer(punch_size / 2)) - else: + elif grb_obj.apertures[apid]['type'] == 'R': if punch_size >= float(grb_obj.apertures[apid]['width']) or \ punch_size >= float(grb_obj.apertures[apid]['height']): self.app.inform.emit('[ERROR_NOTCL] %s' % _("Could not generate punched hole Gerber because the punch hole size" "is bigger than some of the apertures in the Gerber object.")) return 'fail' - else: + elif round(float(grb_obj.apertures[apid]['width']), self.decimals) == \ + round(float(grb_obj.apertures[apid]['height']), self.decimals) and \ + self.square_cb.get_value(): for elem in grb_obj.apertures[apid]['geometry']: if 'follow' in elem: if isinstance(elem['follow'], Point): punching_geo.append(elem['follow'].buffer(punch_size / 2)) + elif round(float(grb_obj.apertures[apid]['width']), self.decimals) != \ + round(float(grb_obj.apertures[apid]['height']), self.decimals) and \ + self.rectangular_cb.get_value(): + for elem in grb_obj.apertures[apid]['geometry']: + if 'follow' in elem: + if isinstance(elem['follow'], Point): + punching_geo.append(elem['follow'].buffer(punch_size / 2)) + elif grb_obj.apertures[apid]['type'] == 'O' and self.oblong_cb.get_value(): + for elem in grb_obj.apertures[apid]['geometry']: + if 'follow' in elem: + if isinstance(elem['follow'], Point): + punching_geo.append(elem['follow'].buffer(punch_size / 2)) + elif grb_obj.apertures[apid]['type'] not in ['C', 'R', 'O'] and self.other_cb.get_value(): + for elem in grb_obj.apertures[apid]['geometry']: + if 'follow' in elem: + if isinstance(elem['follow'], Point): + punching_geo.append(elem['follow'].buffer(punch_size / 2)) punching_geo = MultiPolygon(punching_geo) if isinstance(grb_obj.solid_geometry, list): @@ -613,8 +635,53 @@ class ToolPunchGerber(FlatCAMTool): "geometry is the same as the one in the source object geometry...")) return 'fail' + # update the gerber apertures to include the clear geometry so it can be exported successfully + new_apertures = deepcopy(grb_obj.apertures) + new_apertures_items = new_apertures.items() + + # find maximum aperture id + new_apid = max([int(x) for x, __ in new_apertures_items]) + + # store here the clear geometry, the key is the drill size + holes_apertures = dict() + + for apid, val in new_apertures_items: + for elem in val['geometry']: + # make it work only for Gerber Flashes who are Points in 'follow' + if 'solid' in elem and isinstance(elem['follow'], Point): + for geo in punching_geo: + clear_apid_size = punch_size + + # since there may be drills that do not drill into a pad we test only for drills in a pad + if geo.within(elem['solid']): + geo_elem = dict() + geo_elem['clear'] = geo.centroid + + if clear_apid_size not in holes_apertures: + holes_apertures[clear_apid_size] = dict() + holes_apertures[clear_apid_size]['type'] = 'C' + holes_apertures[clear_apid_size]['size'] = clear_apid_size + holes_apertures[clear_apid_size]['geometry'] = list() + + holes_apertures[clear_apid_size]['geometry'].append(deepcopy(geo_elem)) + + # add the clear geometry to new apertures; it's easier than to test if there are apertures with the same + # size and add there the clear geometry + for hole_size, ap_val in holes_apertures.items(): + new_apid += 1 + new_apertures[str(new_apid)] = deepcopy(ap_val) + def init_func(new_obj, app_obj): + new_obj.options.update(grb_obj.options) + new_obj.options['name'] = outname + new_obj.fill_color = deepcopy(grb_obj.fill_color) + new_obj.outline_color = deepcopy(grb_obj.outline_color) + + new_obj.apertures = deepcopy(new_apertures) + new_obj.solid_geometry = deepcopy(punched_solid_geometry) + new_obj.source_file = self.app.export_gerber(obj_name=outname, filename=None, + local_use=new_obj, use_thread=False) self.app.new_object('gerber', outname, init_func) elif punch_method == 'ring': From 67a2350a5925a6ca5536fa84dfd9cdb9b792caa4 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 12 Feb 2020 02:51:15 +0200 Subject: [PATCH 082/209] - minor change in ReadMe file --- README.md | 130 +++++++++++++++++++++++++++--------------------------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index f1f5f28e..5c264eac 100644 --- a/README.md +++ b/README.md @@ -465,7 +465,7 @@ CAD program, and create G-Code for Isolation routing. - in Excellon UI fixed bug that did not allow editing of the Offset Z parameter from the Tool table - in Properties Tool added new information's for the tools in the CNCjob objects - few bugs solved regarding the newly created empty objects -- changed everywhere the name "postprocessor" with "preprocessor" +- changed everywhere the name "preprocessor" with "preprocessor" - updated the preprocessor files in the toolchange section in order to avoid a graphical representation of travel lines glitch - fixed a GUI glitch in the Excellon tool table - added units to some of the parameters in the Properties Tool @@ -604,7 +604,7 @@ CAD program, and create G-Code for Isolation routing. 16.11.2019 -- fixed issue #341 that affected both postprocessors that have inlined feedrate: marlin and repetier. The used feedrate was the Feedrate X-Y and instead had to be Feedrate Z. +- fixed issue #341 that affected both preprocessors that have inlined feedrate: marlin and repetier. The used feedrate was the Feedrate X-Y and instead had to be Feedrate Z. 15.11.2019 @@ -614,7 +614,7 @@ CAD program, and create G-Code for Isolation routing. 14.11.2019 -- made sure that the 'default' postprocessor file is always loaded first such that this name is always first in the GUI comboboxes +- made sure that the 'default' preprocessor file is always loaded first such that this name is always first in the GUI comboboxes - added a class in GUIElements for a TextEdit box with line numbers and highlight 13.11.2019 @@ -626,7 +626,7 @@ CAD program, and create G-Code for Isolation routing. 12.11.2019 -- added two new postprocessor files for ISEL CNC and for BERTA CNC +- added two new preprocessor files for ISEL CNC and for BERTA CNC - clicking on a FCTable GUI element empty space will also clear the focus now 11.11.2019 @@ -1156,7 +1156,7 @@ CAD program, and create G-Code for Isolation routing. - more GUI optimizations related to being part of the Advanced category or not - added possibility to change the positive SVG exported file color in Tool Film - fixed some issues recently introduced in the TclCommands CNCJob, DrillCNCJob and write_gcode; changed some parameters names -- fixed issue in the Laser postprocessor where the laser was turned on as soon as the GCode started creating an unwanted cut up until the job start +- fixed issue in the Laser preprocessor where the laser was turned on as soon as the GCode started creating an unwanted cut up until the job start - added new links in Menu -> Help (Excellon, Gerber specifications and a Report Bug) - made the splashscreen to be showed on the current monitor on systems with multiple monitors - added a new entry in Menu -> View -> Redraw All which is doing what the name says: redraw all loaded objects @@ -1369,7 +1369,7 @@ CAD program, and create G-Code for Isolation routing. - remade the NCC Tool in preparation for the newly added TclCommand CopperClear - finished adding the TclCommandCopperClear that can be called with alias: 'ncc' - added new capability in NCC Tool when the reference object is of Gerber type and fixed some newly introduced errors -- fixed issue #298. The changes in postprocessors done in Preferences dis not update the object UI layout as it was supposed to. The selection of Marlin postproc. did not unhidden the Feedrate Rapids entry. +- fixed issue #298. The changes in preprocessors done in Preferences dis not update the object UI layout as it was supposed to. The selection of Marlin postproc. did not unhidden the Feedrate Rapids entry. - fixed minor issues - fixed Tcl Command AddPolygon, AddPolyline - fixed Tcl Command CncJob @@ -1895,7 +1895,7 @@ CAD program, and create G-Code for Isolation routing. 11.05.2019 - fixed issue in camlib.CNCjob.generate_from_excellon_by_tool() in the drill path optimization algorithm selection when selecting the MH algorithm. The new API's for Google OR-tools required some changes and also the time parameter can be now just an integer therefore I modified the GUI -- made the Feedrate Rapids parameter to depend on the type of postprocessor choosed. It will be showed only for a postprocessor which the name contain 'marlin' and for any postprocessor's that have 'custom' in the name +- made the Feedrate Rapids parameter to depend on the type of preprocessor choosed. It will be showed only for a preprocessor which the name contain 'marlin' and for any preprocessor's that have 'custom' in the name - fixed the camlib.Gerber functions of mirror, scale, offset, skew and rotate to work with the new data structure for apertures geometry - fixed Gerber Editor selection to work with the new Gerber data structure in self.apertures - fixed Gerber Editor FCPad class to work with the new Gerber data structure in self.apertures @@ -2325,7 +2325,7 @@ CAD program, and create G-Code for Isolation routing. - added a fix in the Gerber parser when adding the geometry in the self.apertures dict for the case that the current aperture is None (Allegro does that) - finished support for internationalization by adding a set of .po/.mo files for the English language. Unfortunately the final action can be done only when Beta will be out of Beta (no more changes) or when I will decide to stop working on this app. -- changed the tooltip for 'feedrate_rapids' parameter to point out that this parameter is useful only for the Marlin postprocessor +- changed the tooltip for 'feedrate_rapids' parameter to point out that this parameter is useful only for the Marlin preprocessor - fix app crash for the case that there are no translation files - fixed some forgotten strings to be prepared for internationalization in ToolCalculators - fixed Tools menu no longer working due of changes @@ -2364,7 +2364,7 @@ CAD program, and create G-Code for Isolation routing. 5.03.2019 -- modified the grbl-laser postprocessor lift_code() +- modified the grbl-laser preprocessor lift_code() - treated an error created by Z_Cut parameter being None - changed the hover and selection box transparency @@ -2417,7 +2417,7 @@ CAD program, and create G-Code for Isolation routing. - because adding shapes to the shapes collection (when doing Mark or Mark All) is time consuming I made the plot_aperture() threaded. - made the polygon fusing in modified Gerber creation, a list comprehension in an attempt for optimization - when right clicking the files in Project tab, the Save option for Excellon no longer export it but really save the original. -- in ToolChange Custom Code replacement, the Text Box in the CNCJob Selected tab will be active only if there is a 'toolchange_custom' in the name of the postprocessor file. This assume that it is, or was created having as template the Toolchange Custom postprocessor file. +- in ToolChange Custom Code replacement, the Text Box in the CNCJob Selected tab will be active only if there is a 'toolchange_custom' in the name of the preprocessor file. This assume that it is, or was created having as template the Toolchange Custom preprocessor file. 25.02.2019 @@ -2444,7 +2444,7 @@ CAD program, and create G-Code for Isolation routing. - added all the Tools in a new ToolBar - fixed bug that after changing the layout all the toolbar actions are no longer working - fixed bug in Set Origin function -- fixed a typo in Toolchange_Probe_MACH3 postprocessor +- fixed a typo in Toolchange_Probe_MACH3 preprocessor 23.02.2019 @@ -2455,7 +2455,7 @@ CAD program, and create G-Code for Isolation routing. 22.02.2019 -- added Repetier postprocessor file +- added Repetier preprocessor file - removed "added ability to regenerate objects (it's actually deletion followed by recreation)" because of the way Python pass parameters to functions by reference instead of copy - added ability to toggle globally the display of ToolTips. Edit -> Preferences -> General -> Enable ToolTips checkbox. - added true fullscreen support (for Windows OS) @@ -2484,7 +2484,7 @@ CAD program, and create G-Code for Isolation routing. - finished added a Tool Table for Tool SolderPaste - working on multi tool solder paste dispensing - finished the Edit -> Preferences defaults section -- finished the UI, created the postprocessor file template +- finished the UI, created the preprocessor file template - finished the multi-tool solder paste dispensing: it will start using the biggest nozzle, fill the pads it can, and then go to the next smaller nozzle until there are no pads without solder. 19.02.2019 @@ -2607,12 +2607,12 @@ CAD program, and create G-Code for Isolation routing. - the SELECTED type of messages are no longer printed to shell from 2 reasons: first, too much spam and second, issue with displaying html - on set_zero function and creation of new geometry or new excellon there is no longer a zoom fit - repurposed shortcut key 'Delete' to delete tools in tooltable when the mouse is over the Seleted tab (with Geometry inside) or in Tools tab (when NCC Tool or Paint Tool is inside). Or in Excellon Editor when mouse is hovering the Selected tab selecting a tool, 'Delete' key will delete that tool, if on canvas 'Delete' key will delete a selected shape (drill). In rest, will delete selected objects. -- adjusted the postprocessor files so the Spindle Off command (M5) is done before the move to Toolchange Z -- adjusted the Toolchange Manual postprocessor file to have more descriptive messages on the toolchange event +- adjusted the preprocessor files so the Spindle Off command (M5) is done before the move to Toolchange Z +- adjusted the Toolchange Manual preprocessor file to have more descriptive messages on the toolchange event - added a strong focus to the object_name entry in the Selected tab - the keypad keyPressed are now detected correctly -- added a pause and message/warning to do a rough zero for the Z axis, in case of Toolchange_Probe_MACH3 postprocessor file -- changes in Toolchange_Probe_MACH3 postprocessor file +- added a pause and message/warning to do a rough zero for the Z axis, in case of Toolchange_Probe_MACH3 preprocessor file +- changes in Toolchange_Probe_MACH3 preprocessor file 9.02.2019 @@ -2678,16 +2678,16 @@ CAD program, and create G-Code for Isolation routing. - added a text in the Selected Tab which is showed whenever the Selected Tab is selected but without having an object selected to display it's properties - added an initial text in the Tools tab - added possibility to use the shortcut key for shortcut list in the Notebook tabs -- added a way to set the Probe depth if Toolchange_Probe postprocessors are selected -- finished the postprocessor file for MACH3 tool probing on toolchange event -- added a new parameter to set the feedrate of the probing in case the used postprocessor does probing (has toolchange_probe in it's name) -- fixed bug in Marlin postprocessor for the Excellon files; the header and toolchange event always used the parenthesis witch is not compatible with GCode for Marlin +- added a way to set the Probe depth if Toolchange_Probe preprocessors are selected +- finished the preprocessor file for MACH3 tool probing on toolchange event +- added a new parameter to set the feedrate of the probing in case the used preprocessor does probing (has toolchange_probe in it's name) +- fixed bug in Marlin preprocessor for the Excellon files; the header and toolchange event always used the parenthesis witch is not compatible with GCode for Marlin - fixed a issue with a move to Z_move before any toolchange 4.02.2019 -- modified the Toolchange_Probe_general postprocessor file to remove any Z moves before the actual toolchange event -- created a prototype postprocessor file for usage with tool probing in MACH3 +- modified the Toolchange_Probe_general preprocessor file to remove any Z moves before the actual toolchange event +- created a prototype preprocessor file for usage with tool probing in MACH3 - added the default values for Tool Film and Tool Panelize to the Edit -> Preferences - added a new parameter in the Tool Film which control the thickness of the stroke width in the resulting SVG. It's a scale parameter. - whatever was the visibility of the corresponding toolbar when we enter in the Editor, it will be set after exit from the Editor (either Geometry Editor or Excellon Editor). @@ -2714,14 +2714,14 @@ CAD program, and create G-Code for Isolation routing. - some GUI structure optimization's - added protection against entering float numbers with comma separator instead of decimal dot separator in key points of FlatCAM (not everywhere) - added a choice of plotting the kind of geometry for the CNC plot (all, travel and cut kind of geometries) in CNCJob Selected Tab -- added a new postprocessor file named: 'probe_from_zmove' which allow probing to be done from z_move position on toolchange event +- added a new preprocessor file named: 'probe_from_zmove' which allow probing to be done from z_move position on toolchange event - fixed the snap magnet button in Geometry Editor, restored the checkable property to True - some more changes in the Editors GUI in deactivate() function - a fix for saving as empty an edited new and empty Excellon Object 1.02.2019 -- fixed postprocessor files so now the bounds values are right aligned (assuming max string length of 9 chars which means 4 digits and 4 decimals) +- fixed preprocessor files so now the bounds values are right aligned (assuming max string length of 9 chars which means 4 digits and 4 decimals) - corrected small type in list_sys Tcl command; added a protection of the Plot Area Tab after a successful edit. - remade the way FlatCAM saves the GUI position data from a file (previously) to use PyQt QSettings - added a 'theme' combo selection in Edit -> Preferences. Two themes are available: standard and compact. @@ -2745,7 +2745,7 @@ CAD program, and create G-Code for Isolation routing. 30.01.2019 -- added a space before Y coordinate in end_code() function in some of the postprocessor files +- added a space before Y coordinate in end_code() function in some of the preprocessor files - added in Calculators Tool an Electroplating Calculator. - remade the App Menu for Editors: now they will be showed only when the respective Editor is active and hidden when the Editor is closed. - added a traceback report in the TCL Shell for the errors that don't allow creation of an object; useful to trace exceptions/errors @@ -2753,9 +2753,9 @@ CAD program, and create G-Code for Isolation routing. - fixed an issue in camlib.CNCJob where tha variable self.toolchange_xy was used for 2 different purposes which created loss of information. - fixed unit conversion functions in case the toolchange_xy parameter is None - more fixes in camlib.CNCJob regarding usage of toolchange (in case it is None) -- fixed postprocessor files to work with toolchange_xy parameter value = None (no values in Edit - Preferences fields) +- fixed preprocessor files to work with toolchange_xy parameter value = None (no values in Edit - Preferences fields) - fixed Tcl commands CncJob and DrillCncJob to work with toolchange -- added to the postprocessor files the command after toolchange to go with G00 (fastest) to "Z Move" value of Z pozition. +- added to the preprocessor files the command after toolchange to go with G00 (fastest) to "Z Move" value of Z pozition. 29.01.2019 @@ -2788,15 +2788,15 @@ CAD program, and create G-Code for Isolation routing. - added options for trace segmentation that can be useful for auto-levelling (code snippet from Lei Zheng from a rejected pull request on FlatCAM https://bitbucket.org/realthunder/ ) - added shortcut key 'L' for creating 'New Excellon' - added shortcut key combo 'SHIFT+S' for Running a Script. -- modified GRBL_laser postprocessor file so it includes a Sxxxx command on the line with M03 (laser active) whenever a value is enter in the Spindlespeed entry field +- modified GRBL_laser preprocessor file so it includes a Sxxxx command on the line with M03 (laser active) whenever a value is enter in the Spindlespeed entry field - remade the EDIT -> PREFERENCES window, the Excellon and Gerber sections. Created a new section named TOOLS 26.01.2019 -- fixed grbl_11 postprocessor in linear_code() function +- fixed grbl_11 preprocessor in linear_code() function - added icons to the Project Tab context menu - added new entries to the Canvas context menu (Copy, Delete, Edit/Save, Move, New Excellon, New Geometry, New Project) -- fixed GRBL_laser postprocessor file +- fixed GRBL_laser preprocessor file - updated function for copy of an Excellon object for the case when the object has slots - updated FlatCAMExcellon.merge() function to work in case some (or all) of the merged objects have slots @@ -2816,14 +2816,14 @@ CAD program, and create G-Code for Isolation routing. - added the Copy entry to the Project context menu - made the functions behind Disable and Enable project context menu entries, non-threaded to fix a possible issue - added multiple object selection on Open ... and Import ... (idea and code snippet came from Travers Carter, BitBucket user https://bitbucket.org/travc/) -- fixed 'GRBL_laser' postprocessor bugs (missing functions) -- fixed display geometry for 'GRBL_laser' postprocessor +- fixed 'GRBL_laser' preprocessor bugs (missing functions) +- fixed display geometry for 'GRBL_laser' preprocessor - Excellon Editor - added possibility to create an linear drill array rotated at an custom angle - added the Edit and Properties entries to the Project context menu 23.01.2019 -- added a new postprocessor file named 'line_xyz' which have x, y, z values on the same GCode line +- added a new preprocessor file named 'line_xyz' which have x, y, z values on the same GCode line - fixed calculation of total path for Excellon Gcode file - modified the way FlatCAM preferences are saved. Now they can be saved as new files with .FlatConfig extension by the user and shared. - added possibility to open the folder where FlatCAM is saving the preferences files @@ -2840,19 +2840,19 @@ CAD program, and create G-Code for Isolation routing. - fixed the HPGL code geometry rendering when travel - fixed the message box layout when asking to save the current work -- made sure that whenever the HPGL postprocessor is selected the Toolchange is always ON and the MultiDepth is OFF -- the HPGL postprocessor entry is not allowed in Excellon Object postprocessor selection combobox as it is only applicable for Geometry +- made sure that whenever the HPGL preprocessor is selected the Toolchange is always ON and the MultiDepth is OFF +- the HPGL preprocessor entry is not allowed in Excellon Object preprocessor selection combobox as it is only applicable for Geometry - when saving HPGL code it will be saved as a file with extension .plt - the units mentioned in HPGL format are only METRIC therefore if FlatCAM units are in INCH they will be transform to METRIC - the minimum unit in HPGL is 0.025mm therefore the coordinates are rounded to a multiple of 0.025mm - removed the raise statement in do_worker_task() function as this is fatal in conjunction with PyQt5 - added a try - except clause for the situations when for a font can't be determined the family and name - moved font parsing to the Geometry Editor: it is done everytime the Text tool is invoked -- made sure that the HPGL postprocessor is not populated in the Excellon postprocessors in Preferences as it make no sense (HPGL is useful only for Geometries) +- made sure that the HPGL preprocessor is not populated in the Excellon preprocessors in Preferences as it make no sense (HPGL is useful only for Geometries) 19.01.2019 -- added initial implementation of HPGL postprocessor +- added initial implementation of HPGL preprocessor - fixed display HPGL code geometry on canvas 11.01.2019 @@ -2876,9 +2876,9 @@ CAD program, and create G-Code for Isolation routing. 6.01.2019 -- fixed the Marlin postprocessor detection in GCode header +- fixed the Marlin preprocessor detection in GCode header - the version date in GCode header is now the one set in FlatCAMApp.App.version_date -- fixed bug in postprocessor files: number of drills is now calculated only for the Excellon objects in toolchange function (only Excellon objects have drills) +- fixed bug in preprocessor files: number of drills is now calculated only for the Excellon objects in toolchange function (only Excellon objects have drills) 5.01.2019 @@ -3042,8 +3042,8 @@ now there is a Tool Table in CNC Object UI and each tool GCode can be enabled or - Geometry Tool Table: new tool added copy all the form fields (data) from the last tool - finished work on generation of a single CNC Job file (therefore a single GCODE file) even for multiple tools in Geo Tool Table - GCode header is added only on saving the file therefore the time generation will be reflected in the file -- modified postprocessors to accommodate the new CNC Job file with multiple tools -- modified postprocessors so the last X,Y move will be to the toolchange X,Y pos (set in Preferences) +- modified preprocessors to accommodate the new CNC Job file with multiple tools +- modified preprocessors so the last X,Y move will be to the toolchange X,Y pos (set in Preferences) - save_project and load_project now work with the new type of multitool geometry and cncjob objects 10.12.2018 @@ -3112,7 +3112,7 @@ now there is a Tool Table in CNC Object UI and each tool GCode can be enabled or - added checks for using a Z Cut with positive value. The Z Cut parameter has to be negative so if the app will detect a positive value it will automatically convert it to negative - started to implement rest-machining for Non Copper clearing Tool - for now the results are not great -- added Toolchange X,Y position parameters and modified the default and manual_toolchange postprocessor file to use them +- added Toolchange X,Y position parameters and modified the default and manual_toolchange preprocessor file to use them For now they are used only for Excellon objects who do have toolchange events - added Toolchange event selection for Geometry objects; for now it is as before, single tool on each file - remade the GUI for objects and in Preferences to have uniformity @@ -3120,14 +3120,14 @@ For now they are used only for Excellon objects who do have toolchange events - fixed some bugs in Tool Add feature of the new Non Copper Clear Tool - added some messages in the Non Copper Clear Tool - added parameters for coordinates no of decimals and for feedrate no of decimals used in the resulting GCODE. They are in EDIT -> Preferences -> CNC Job Options -- modified the postprocessors to use the "decimals" parameters +- modified the preprocessors to use the "decimals" parameters 28.11.2018 - added different methods of copper clearing (standard, seed, line_based) and "connect", "contour" options found in Paint function - remake of the non-copper clearing tool as a separate tool - modified the "About" menu entry to mention the main contributors to FlatCAM 3000 -- modified Marlin postprocessor according to modifications made by @redbull0174 user from FlatCAM.org forum +- modified Marlin preprocessor according to modifications made by @redbull0174 user from FlatCAM.org forum - modified Move Tool so it will detect if there is no object to move and issue a message 27.11.2018 @@ -3146,7 +3146,7 @@ For now they are used only for Excellon objects who do have toolchange events - restored the selection method in Geometry Editor to the original one found in FlatCAM 8.5 - minor changes in Clear Copper function -- minor changes in some postprocessors +- minor changes in some preprocessors - change Join Geometry menu entry to Join Geo/Gerber - added menu entry for Toggle Axis in Menu -> View - added menu entry for Toggle Workspace in Menu -> View @@ -3162,7 +3162,7 @@ For now they are used only for Excellon objects who do have toolchange events 19.11.2018 -- fixed issue with nested comment in postprocessors +- fixed issue with nested comment in preprocessors - fixed issue in Paint All; reverted changes 18.11.2018 @@ -3179,13 +3179,13 @@ For now they are used only for Excellon objects who do have toolchange events 12.11.2018 - fixed bug in Paint Single Polygon -- added spindle speed in laser postprocessor +- added spindle speed in laser preprocessor - added Z start move parameter. It controls the height at which the tool travel on the fist move in the job. Leave it blank if you don't need it. 9.11.2018 - fixed a reported bug generated by a typo for feedrate_z object in camlib.py. Because of that, the project could not be saved. -- fixed a G01 usage (should be G1) in Marlin postprocessor. +- fixed a G01 usage (should be G1) in Marlin preprocessor. - changed the position of the Tool Dia entry in the Object UI and in FlatCAMGUI - fixed issues in the installer @@ -3404,9 +3404,9 @@ the setting in the Preferences) and drag the rectangle across the objects you wa - work on Excellon Editor. Excellon editor working functions are: loading an Excellon object into Editor, saving an Excellon object from editor to FlatCAM, selecting drills by left click, selection of drills by dragging rectangle, deletion of drills. - fixed Excellon merge -- added more Gcode details (depthperpass parameter in Gcode header) in postprocessors -- deleted the Tool informations from header in postprocessors due to Mach3 not liking the lot of square brackets -- more corrections in postprocessors +- added more Gcode details (depthperpass parameter in Gcode header) in preprocessors +- deleted the Tool informations from header in preprocessors due to Mach3 not liking the lot of square brackets +- more corrections in preprocessors 28.09.2018 @@ -3481,7 +3481,7 @@ an Excellon file, a G-Code file or a SVG file. - added new information's in the object properties: all used Tool-Table items are included in a new entry in self.options dictionary -- modified the postprocessor files so they now include information's about +- modified the preprocessor files so they now include information's about how many drills (or slots) are for each tool. The Gcode will have this information displayed on the message from ToolChange. - removed some log.debug and add new log.debug especially for moments when some process is finished @@ -3519,7 +3519,7 @@ is faster 17.09.2018 - fixed Measuring Tool not working when grid is turned OFF -- fixed Roland MDX20 postprocessor +- fixed Roland MDX20 preprocessor - added a .GBR extension in the open_gerber filter - added ability to Scale and Offset (for all types of objects) to just press Enter after entering a value in the Entry just like in Tool Transform @@ -3533,8 +3533,8 @@ to FlatCAM.py 15.09.2018 -- removed dwell line generator and included dwell generation in the postprocessor files -- added a proposed RML1 Roland_MDX20 postprocessor file. +- removed dwell line generator and included dwell generation in the preprocessor files +- added a proposed RML1 Roland_MDX20 preprocessor file. - added a limit of 15mm/sec (900mm/min) to the feedrate and to the feedrate_rapid. Anything faster than this will be capped to 900mm/min regardless what is entered in the program GUI. This is because Roland MDX-20 has a mechanical limit of the speed to 15mm/sec (900mm/min in GUI) @@ -3915,7 +3915,7 @@ total number of drills - modified generate_milling method which had issues from the Python3 port (it could not sort the tools due of dict to dict comparison no longer possible). -- modified the 'default' postprocessor in order to include a space +- modified the 'default' preprocessor in order to include a space between the value of Xcoord and the following Y - made optional the using of threads for the milling command; by default it is OFF (False) because in the current configuration it creates issues @@ -3935,7 +3935,7 @@ clicked and Options Combo was in Project Options - fixed issue with Tcl Shell loosing focus after each command, therefore needing to click in the edit line before we type a new command (borrowed from @brainstorm -- added a header in the postprocessor files mentioning that the GCODE +- added a header in the preprocessor files mentioning that the GCODE files were generated by FlatCAM. - modified the number of decimals in some of the line entries to 4. - added an alias for the millholes Tcl Command: 'mill' @@ -4038,14 +4038,14 @@ Delete: Delete Obj 22.05.2018 -- Added Marlin postprocessor +- Added Marlin preprocessor - Added a new entry into the Geometry and Excellon Object's UI: Feedrate rapid: the purpose is to set a feedrate for the G0 command that some firmwares like Marlin don't intepret as 'move with highest speed' - FlatCAM was not making the conversion from one type of units to another for a lot of parameters. Corrected that. -- Modified the Marlin Postprocessor so it will generate the required +- Modified the Marlin preprocessor so it will generate the required GCODE. 21.05.2018 @@ -4125,7 +4125,7 @@ make a board cutout from a "any shape" Gerber or Geometry file parameter value as the toolchangez parameter value and for the endz value used a default value = 1 -- added postprocessor name into the TCL command "drillcncjob" parameters +- added preprocessor name into the TCL command "drillcncjob" parameters - when adding a new geometry the default name is now: "New_Geometry" instead of "New Geometry". TCL commands don't handle the spaces inside the name and @@ -4212,19 +4212,19 @@ is less than 6 then the software will multiply by 10 the coordinates - fixed bug in Geometry CNCJob generation that prevented generating the object -- added GRBL 1.1 postprocessor and Laser postprocessor (adapted from +- added GRBL 1.1 preprocessor and Laser preprocessor (adapted from the work of MARCO A QUEZADA) 13.05.2018 - added postprocessing in correct form -- added the possibility to select an postprocessor for Excellon Object -- added a new postprocessor, manual_toolchange.py. It allows to change +- added the possibility to select an preprocessor for Excellon Object +- added a new preprocessor, manual_toolchange.py. It allows to change the tools and adjust the drill tip to touch the surface manually, always in the X=0, Y=0, Z = toolchangeZ coordinates. - fixed drillcncjob TCL command by adding toolchangeZ parameter -- fixed the posprocessor file template 'default.py' in the toolchange +- fixed the preprocessor file template 'default.py' in the toolchange command section - after I created a feature that the message in infobar is cleared by moving mouse on canvas, it generated a bug in TCL shell: everytime From c2373da17ad4fc5873a6d5d6e28670b4a8b79892 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 12 Feb 2020 16:43:13 +0200 Subject: [PATCH 083/209] - working on fixing a bug in FlatCAMGeometry.merge() --- FlatCAMApp.py | 7 +++-- FlatCAMObj.py | 53 +++++++++++++++++++--------------- README.md | 6 ++++ flatcamTools/ToolProperties.py | 6 +++- 4 files changed, 44 insertions(+), 28 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 8fe6897a..b1eca4af 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -5689,11 +5689,12 @@ class App(QtCore.QObject): if True in geo_type_set: def initialize(geo_obj, app): FlatCAMGeometry.merge(self, geo_list=objs, geo_final=geo_obj, multigeo=True) - app.inform.emit('[success] %s.' % _("Multigeo. Geometry merging finished")) + app.inform.emit('[success] %s.' % _("Geometry merging finished")) # rename all the ['name] key in obj.tools[tooluid]['data'] to the obj_name_multi - for v in obj.tools.values(): + for v in geo_obj.tools.values(): v['data']['name'] = obj_name_multi + self.new_object("geometry", obj_name_multi, initialize) else: def initialize(geo_obj, app): @@ -5701,7 +5702,7 @@ class App(QtCore.QObject): app.inform.emit('[success] %s.' % _("Geometry merging finished")) # rename all the ['name] key in obj.tools[tooluid]['data'] to the obj_name_multi - for v in obj.tools.values(): + for v in geo_obj.tools.values(): v['data']['name'] = obj_name_single self.new_object("geometry", obj_name_single, initialize) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index da4a2a07..c43e0dbb 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -6268,53 +6268,58 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): """ if geo_final.solid_geometry is None: - geo_final.solid_geometry = [] + geo_final.solid_geometry = list() - if type(geo_final.solid_geometry) is not list: + try: + __ = iter(geo_final.solid_geometry) + except TypeError: geo_final.solid_geometry = [geo_final.solid_geometry] - for geo in geo_list: - for option in geo.options: + new_solid_geometry = list() + new_options = dict() + new_tools = dict() + + for geo_obj in geo_list: + for option in geo_obj.options: if option is not 'name': try: - geo_final.options[option] = deepcopy(geo.options[option]) + new_options[option] = geo_obj.options[option] except Exception as e: log.warning("Failed to copy option %s. Error: %s" % (str(option), str(e))) # Expand lists - if type(geo) is list: - FlatCAMGeometry.merge(self, geo_list=geo, geo_final=geo_final) + if type(geo_obj) is list: + FlatCAMGeometry.merge(self, geo_list=geo_obj, geo_final=geo_final) # If not list, just append else: - # merge solid_geometry, useful for singletool geometry, for multitool each is empty if multigeo is None or multigeo is False: geo_final.multigeo = False - try: - geo_final.solid_geometry.append(deepcopy(geo.solid_geometry)) - except Exception as e: - log.debug("FlatCAMGeometry.merge() --> %s" % str(e)) else: geo_final.multigeo = True - # if multigeo the solid_geometry is empty in the object attributes because it now lives in the - # tools object attribute, as a key value - geo_final.solid_geometry = [] - - # find the tool_uid maximum value in the geo_final - geo_final_uid_list = [] - for key in geo_final.tools: - geo_final_uid_list.append(int(key)) try: - max_uid = max(geo_final_uid_list, key=int) + new_solid_geometry.append(geo_obj.solid_geometry) + except Exception as e: + log.debug("FlatCAMGeometry.merge() --> %s" % str(e)) + + # find the tool_uid maximum value in the geo_final + try: + max_uid = max([int(i) for i in new_tools.keys()]) except ValueError: max_uid = 0 # add and merge tools. If what we try to merge as Geometry is Excellon's and/or Gerber's then don't try # to merge the obj.tools as it is likely there is none to merge. - if not isinstance(geo, FlatCAMGerber) and not isinstance(geo, FlatCAMExcellon): - for tool_uid in geo.tools: + if not isinstance(geo_obj, FlatCAMGerber) and not isinstance(geo_obj, FlatCAMExcellon): + for tool_uid in geo_obj.tools: max_uid += 1 - geo_final.tools[max_uid] = deepcopy(geo.tools[tool_uid]) + new_tools[max_uid] = geo_obj.tools[tool_uid] + + geo_final.options.update(deepcopy(new_options)) + geo_final.solid_geometry = deepcopy(list(geo_final.flatten_list(new_solid_geometry))) + geo_final.tools = deepcopy(new_tools) + for td in geo_final.tools: + print(td, geo_final.tools[td]) @staticmethod def get_pts(o): diff --git a/README.md b/README.md index 5c264eac..b1fe58ff 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,12 @@ CAD program, and create G-Code for Isolation routing. ================================================= +12.02.2020 + + +- working on fixing a bug in FlatCAMGeometry.merge() + + 11.02.2020 - working on Tool Punch; finished the geometry update with the clear geometry for the case of Excellon method diff --git a/flatcamTools/ToolProperties.py b/flatcamTools/ToolProperties.py index 6429982e..78e48afc 100644 --- a/flatcamTools/ToolProperties.py +++ b/flatcamTools/ToolProperties.py @@ -425,7 +425,11 @@ class Properties(FlatCAMTool): tools, str(tool), expanded=True, color=QtGui.QColor("#000000"), font=font) for k, v in value.items(): if k == 'solid_geometry': - printed_value = _('Present') if v else _('None') + # printed_value = _('Present') if v else _('None') + try: + printed_value = str(len(v)) + except (TypeError, AttributeError): + printed_value = '1' self.treeWidget.addChild(geo_tool, [str(k), printed_value], True) elif k == 'data': tool_data = self.treeWidget.addParent( From b3ba2d32da5af4871fbe0902476b3368093786a4 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 12 Feb 2020 16:47:11 +0200 Subject: [PATCH 084/209] - working on fixing a bug in FlatCAMGeometry.merge() - FIXED --- FlatCAMObj.py | 12 +++++------- README.md | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index c43e0dbb..0d3ca646 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -5618,10 +5618,10 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): # find the tool_dia associated with the tooluid_key # search in the self.tools for the sel_tool_dia and when found see what tooluid has # on the found tooluid in self.tools we also have the solid_geometry that interest us - for k, v in self.tools.items(): - if float('%.*f' % (self.decimals, float(v['tooldia']))) == tooldia_val: - current_uid = int(k) - break + # for k, v in self.tools.items(): + # if float('%.*f' % (self.decimals, float(v['tooldia']))) == tooldia_val: + # current_uid = int(k) + # break if dia_cnc_dict['offset'] == 'in': tool_offset = -tooldia_val / 2 @@ -5664,7 +5664,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): pp_geometry_name = tools_dict[tooluid_key]['data']["ppname_g"] spindledir = self.app.defaults['geometry_spindledir'] - tool_solid_geometry = self.tools[current_uid]['solid_geometry'] + tool_solid_geometry = self.tools[tooluid_key]['solid_geometry'] job_obj.coords_decimals = self.app.defaults["cncjob_coords_decimals"] job_obj.fr_decimals = self.app.defaults["cncjob_fr_decimals"] @@ -6318,8 +6318,6 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): geo_final.options.update(deepcopy(new_options)) geo_final.solid_geometry = deepcopy(list(geo_final.flatten_list(new_solid_geometry))) geo_final.tools = deepcopy(new_tools) - for td in geo_final.tools: - print(td, geo_final.tools[td]) @staticmethod def get_pts(o): diff --git a/README.md b/README.md index b1fe58ff..ef44379e 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ CAD program, and create G-Code for Isolation routing. 12.02.2020 -- working on fixing a bug in FlatCAMGeometry.merge() +- working on fixing a bug in FlatCAMGeometry.merge() - FIXED 11.02.2020 From 8665d4c90da4c95d460fa0195f4ccb38052348ef Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 12 Feb 2020 17:15:34 +0200 Subject: [PATCH 085/209] - added a debug message --- FlatCAMApp.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index b1eca4af..cbbdee3b 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -7162,8 +7162,10 @@ class App(QtCore.QObject): try: obj_active.annotation.clear(update=True) obj_active.annotation.enabled = False - except AttributeError: - pass + except AttributeError as e: + log.debug( + "App.on_delete() --> delete annotations on a FlatCAMCNCJob object. %s" % str(e) + ) self.delete_first_selected() self.inform.emit('%s...' % _("Object(s) deleted")) From e936e0e1163722c273d62f61d1d66695004fa6d6 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 12 Feb 2020 23:28:21 +0200 Subject: [PATCH 086/209] - fixed bug: when deleting a FlatCAMCNCJob with annotations enabled, the annotations are not deleted from canvas; - fixed bug: creating a new project while a project is open and it contain CNCJob annotations and/or Gerber mark shapes, did not delete them from canvas --- FlatCAMApp.py | 22 ++++++++++------ FlatCAMObj.py | 12 ++++----- README.md | 2 ++ camlib.py | 69 ++++++++++++++++++++++++--------------------------- 4 files changed, 55 insertions(+), 50 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index cbbdee3b..16c98005 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -7149,8 +7149,7 @@ class App(QtCore.QObject): if self.collection.get_active(): self.log.debug("App.on_delete()") - while self.collection.get_active(): - obj_active = self.collection.get_active() + for obj_active in self.collection.get_selected(): # if the deleted object is FlatCAMGerber then make sure to delete the possible mark shapes if isinstance(obj_active, FlatCAMGerber): for el in obj_active.mark_shapes: @@ -7160,12 +7159,16 @@ class App(QtCore.QObject): del el elif isinstance(obj_active, FlatCAMCNCjob): try: + obj_active.text_col.enabled = False + del obj_active.text_col obj_active.annotation.clear(update=True) - obj_active.annotation.enabled = False + del obj_active.annotation except AttributeError as e: log.debug( "App.on_delete() --> delete annotations on a FlatCAMCNCJob object. %s" % str(e) ) + + while self.collection.get_selected(): self.delete_first_selected() self.inform.emit('%s...' % _("Object(s) deleted")) @@ -9280,8 +9283,7 @@ class App(QtCore.QObject): self.on_file_new() else: self.on_file_new() - self.inform.emit('[success] %s...' % - _("New Project created")) + self.inform.emit('[success] %s...' % _("New Project created")) def on_file_new(self, cli=None): """ @@ -9310,16 +9312,20 @@ class App(QtCore.QObject): # delete shapes left drawn from mark shape_collections, if any if isinstance(obj, FlatCAMGerber): try: - obj.mark_shapes.enabled = False - obj.mark_shapes.clear(update=True) + for el in obj.mark_shapes: + obj.mark_shapes[el].clear(update=True) + obj.mark_shapes[el].enabled = False + del el except AttributeError: pass # also delete annotation shapes, if any elif isinstance(obj, FlatCAMCNCjob): try: - obj.annotation.enabled = False + obj.text_col.enabled = False + del obj.text_col obj.annotation.clear(update=True) + del obj.annotation except AttributeError: pass diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 0d3ca646..8a1023b7 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -6283,7 +6283,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): for option in geo_obj.options: if option is not 'name': try: - new_options[option] = geo_obj.options[option] + new_options[option] = deepcopy(geo_obj.options[option]) except Exception as e: log.warning("Failed to copy option %s. Error: %s" % (str(option), str(e))) @@ -6298,7 +6298,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): geo_final.multigeo = True try: - new_solid_geometry.append(geo_obj.solid_geometry) + new_solid_geometry += deepcopy(geo_obj.solid_geometry) except Exception as e: log.debug("FlatCAMGeometry.merge() --> %s" % str(e)) @@ -6313,11 +6313,11 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): if not isinstance(geo_obj, FlatCAMGerber) and not isinstance(geo_obj, FlatCAMExcellon): for tool_uid in geo_obj.tools: max_uid += 1 - new_tools[max_uid] = geo_obj.tools[tool_uid] + new_tools[max_uid] = deepcopy(geo_obj.tools[tool_uid]) - geo_final.options.update(deepcopy(new_options)) - geo_final.solid_geometry = deepcopy(list(geo_final.flatten_list(new_solid_geometry))) - geo_final.tools = deepcopy(new_tools) + geo_final.options.update(new_options) + geo_final.solid_geometry = new_solid_geometry + geo_final.tools = new_tools @staticmethod def get_pts(o): diff --git a/README.md b/README.md index ef44379e..23c5ed06 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ CAD program, and create G-Code for Isolation routing. - working on fixing a bug in FlatCAMGeometry.merge() - FIXED +- fixed bug: when deleting a FlatCAMCNCJob with annotations enabled, the annotations are not deleted from canvas; +- fixed bug: creating a new project while a project is open and it contain CNCJob annotations and/or Gerber mark shapes, did not delete them from canvas 11.02.2020 diff --git a/camlib.py b/camlib.py index 2fb8180e..a939f9a1 100644 --- a/camlib.py +++ b/camlib.py @@ -948,7 +948,7 @@ class Geometry(object): pol_nr += 1 disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100])) - if old_disp_number < disp_number <= 100: + if old_disp_number < disp_number <= 100: self.app.proc_container.update_view_text(' %s %d: %d%%' % (_("Pass"), int(passes + 1), int(disp_number))) old_disp_number = disp_number @@ -979,8 +979,8 @@ class Geometry(object): log.debug("Geometry.isolation_geometry() --> Type of isolation not supported") return "fail" - def flatten_list(self, list): - for item in list: + def flatten_list(self, obj_list): + for item in obj_list: if isinstance(item, Iterable) and not isinstance(item, (str, bytes)): yield from self.flatten_list(item) else: @@ -1187,7 +1187,6 @@ class Geometry(object): if boundary is None: boundary = self.solid_geometry.envelope return boundary.difference(self.solid_geometry) - def clear_polygon(self, polygon, tooldia, steps_per_circle, overlap=0.15, connect=True, contour=True, prog_plot=False): @@ -1441,7 +1440,7 @@ class Geometry(object): try: margin_poly = polygon.buffer(-tooldia / 1.99999999, (int(steps_per_circle))) - except Exception as e: + except Exception: log.debug("camlib.Geometry.clear_polygon3() --> Could not buffer the Polygon") return None @@ -1571,6 +1570,7 @@ class Geometry(object): This algorithm draws parallel lines inside the polygon. :param line: The target line that create painted polygon. + :param aperture_size: the size of the aperture that is used to draw the 'line' as a polygon :type line: shapely.geometry.LineString or shapely.geometry.MultiLineString :param tooldia: Tool diameter. :param steps_per_circle: how many linear segments to use to approximate a circle @@ -1758,7 +1758,7 @@ class Geometry(object): # storage.get_points = get_pts # # for shape in geolist: - # if shape is not None: # TODO: This shouldn't have happened. + # if shape is not None: # # Make LlinearRings into linestrings otherwise # # When chaining the coordinates path is messed up. # storage.insert(LineString(shape)) @@ -2268,8 +2268,7 @@ class Geometry(object): # variables to display the percentage of work done self.geo_len = 0 try: - for g in self.solid_geometry: - self.geo_len += 1 + self.geo_len = len(self.solid_geometry) except TypeError: self.geo_len = 1 self.old_disp_number = 0 @@ -2355,7 +2354,7 @@ class Geometry(object): self.solid_geometry = buffer_geom(self.solid_geometry) - self.app.inform.emit('[success] %s...' % _('Object was buffered')) + self.app.inform.emit('[success] %s...' % _('Object was buffered')) except AttributeError: self.app.inform.emit('[ERROR_NOTCL] %s' % _("Failed to buffer. No object selected")) @@ -2387,8 +2386,8 @@ class CNCjob(Geometry): defaults = { "global_zdownrate": None, - "pp_geometry_name":'default', - "pp_excellon_name":'default', + "pp_geometry_name": 'default', + "pp_excellon_name": 'default', "excellon_optimization_type": "B", } @@ -2591,7 +2590,7 @@ class CNCjob(Geometry): must_visit.remove(nearest) return path - def generate_from_excellon_by_tool(self, exobj, tools="all", drillz = 3.0, toolchange=False, toolchangez=0.1, + def generate_from_excellon_by_tool(self, exobj, tools="all", drillz=3.0, toolchange=False, toolchangez=0.1, toolchangexy='', endz=2.0, startz=None, excellon_optimization_type='B'): """ Creates gcode for this object from an Excellon object @@ -2675,7 +2674,7 @@ class CNCjob(Geometry): sort = [] for k, v in list(exobj.tools.items()): sort.append((k, v.get('C'))) - sorted_tools = sorted(sort,key=lambda t1: t1[1]) + sorted_tools = sorted(sort, key=lambda t1: t1[1]) if tools == "all": tools = [i[0] for i in sorted_tools] # we get a array of ordered tools @@ -2783,7 +2782,7 @@ class CNCjob(Geometry): """Initialize distance array.""" locations = create_data_array() size = len(locations) - self.matrix = {} + self.matrix = dict() for from_node in range(size): self.matrix[from_node] = {} @@ -2833,7 +2832,7 @@ class CNCjob(Geometry): log.debug("Using OR-Tools Metaheuristic Guided Local Search drill path optimization.") if exobj.drills: for tool in tools: - self.tool=tool + self.tool = tool self.postdata['toolC'] = exobj.tools[tool]["C"] self.tooldia = exobj.tools[tool]["C"] @@ -3019,7 +3018,7 @@ class CNCjob(Geometry): # graceful abort requested by the user raise FlatCAMApp.GracefulException - self.tool=tool + self.tool = tool self.postdata['toolC']=exobj.tools[tool]["C"] self.tooldia = exobj.tools[tool]["C"] @@ -3105,7 +3104,6 @@ class CNCjob(Geometry): # Drillling! for Absolute coordinates type G90 # variables to display the percentage of work done geo_len = len(node_list) - disp_number = 0 old_disp_number = 0 log.warning("Number of drills for which to generate GCode: %s" % str(geo_len)) @@ -3237,7 +3235,6 @@ class CNCjob(Geometry): node_list = self.optimized_travelling_salesman(altPoints) # variables to display the percentage of work done geo_len = len(node_list) - disp_number = 0 old_disp_number = 0 log.warning("Number of drills for which to generate GCode: %s" % str(geo_len)) @@ -3299,7 +3296,7 @@ class CNCjob(Geometry): self.app.proc_container.update_view_text(' %d%%' % disp_number) old_disp_number = disp_number else: - self.app.inform.emit('[ERROR_NOTCL] %s...' % _('G91 coordinates not implemented')) + self.app.inform.emit('[ERROR_NOTCL] %s...' % _('G91 coordinates not implemented')) return 'fail' else: log.debug("camlib.CNCJob.generate_from_excellon_by_tool() --> " @@ -3564,9 +3561,9 @@ class CNCjob(Geometry): current_tooldia = float('%.*f' % (self.decimals, float(self.tooldia))) - self.app.inform.emit( '%s: %s%s.' % (_("Starting G-Code for tool with diameter"), - str(current_tooldia), - str(self.units))) + self.app.inform.emit('%s: %s%s.' % (_("Starting G-Code for tool with diameter"), + str(current_tooldia), + str(self.units))) pt, geo = storage.nearest(current_pt) @@ -3886,8 +3883,8 @@ class CNCjob(Geometry): self.gcode += self.doformat(p.feedrate_code) # sets the feed rate if toolchange is False: - self.gcode += self.doformat(p.lift_code, x=self.oldx , y=self.oldy ) # Move (up) to travel height - self.gcode += self.doformat(p.startz_code, x=self.oldx , y=self.oldy ) + self.gcode += self.doformat(p.lift_code, x=self.oldx, y=self.oldy) # Move (up) to travel height + self.gcode += self.doformat(p.startz_code, x=self.oldx , y=self.oldy) if toolchange: # if "line_xyz" in self.pp_geometry_name: @@ -3975,7 +3972,7 @@ class CNCjob(Geometry): total_travel += abs(distance(pt1=current_pt, pt2=pt)) current_pt = geo.coords[-1] - pt, geo = storage.nearest(current_pt) # Next + pt, geo = storage.nearest(current_pt) # Next disp_number = int(np.interp(path_count, [0, geo_len], [0, 100])) if old_disp_number < disp_number <= 100: @@ -4077,7 +4074,6 @@ class CNCjob(Geometry): # variables to display the percentage of work done geo_len = len(flat_geometry) - disp_number = 0 old_disp_number = 0 pt, geo = storage.nearest(current_pt) @@ -4141,7 +4137,7 @@ class CNCjob(Geometry): # Move down to cutting depth gcode += self.doformat(p.z_feedrate_code) gcode += self.doformat(p.down_z_start_code) - gcode += self.doformat(p.spindle_fwd_code) # Start dispensing + gcode += self.doformat(p.spindle_fwd_code) # Start dispensing gcode += self.doformat(p.dwell_fwd_code) gcode += self.doformat(p.feedrate_z_dispense_code) gcode += self.doformat(p.lift_z_dispense_code) @@ -4164,7 +4160,7 @@ class CNCjob(Geometry): prev_y = next_y # Up to travelling height. - gcode += self.doformat(p.spindle_off_code) # Stop dispensing + gcode += self.doformat(p.spindle_off_code) # Stop dispensing gcode += self.doformat(p.spindle_rev_code) gcode += self.doformat(p.down_z_stop_code) gcode += self.doformat(p.spindle_off_code) @@ -4176,7 +4172,7 @@ class CNCjob(Geometry): gcode += self.doformat(p.feedrate_z_dispense_code) gcode += self.doformat(p.down_z_start_code) - gcode += self.doformat(p.spindle_fwd_code) # Start dispensing + gcode += self.doformat(p.spindle_fwd_code) # Start dispensing gcode += self.doformat(p.dwell_fwd_code) gcode += self.doformat(p.lift_z_dispense_code) @@ -4191,7 +4187,6 @@ class CNCjob(Geometry): def create_gcode_single_pass(self, geometry, extracut, extracut_length, tolerance, old_point=(0, 0)): # G-code. Note: self.linear2gcode() and self.point2gcode() will lower and raise the tool every time. - gcode_single_pass = '' if type(geometry) == LineString or type(geometry) == LinearRing: if extracut is False: @@ -4574,8 +4569,8 @@ class CNCjob(Geometry): if geo['kind'][0] == 'C': obj.add_shape(shape=geo['geom'], color=color['C'][1], visible=visible) else: - text = [] - pos = [] + text = list() + pos = list() self.coordinates_type = self.app.defaults["cncjob_coords_type"] if self.coordinates_type == "G90": # For Absolute coordinates type G90 @@ -5084,10 +5079,10 @@ class CNCjob(Geometry): if self.z_feedrate is not None: gcode += self.doformat(p.z_feedrate_code) - gcode += self.doformat(p.down_code, x=first_x, y=first_y, z_cut = self.z_cut) + gcode += self.doformat(p.down_code, x=first_x, y=first_y, z_cut=self.z_cut) gcode += self.doformat(p.feedrate_code) else: - gcode += self.doformat(p.down_code, x=first_x, y=first_y, z_cut = self.z_cut) # Start cutting + gcode += self.doformat(p.down_code, x=first_x, y=first_y, z_cut=self.z_cut) # Start cutting gcode += self.doformat(p.lift_code, x=first_x, y=first_y) # Stop cutting return gcode @@ -5122,8 +5117,10 @@ class CNCjob(Geometry): # graceful abort requested by the user raise FlatCAMApp.GracefulException - if g['kind'][0] == 'C': cuts.append(g) - if g['kind'][0] == 'T': travels.append(g) + if g['kind'][0] == 'C': + cuts.append(g) + if g['kind'][0] == 'T': + travels.append(g) # Used to determine the overall board size self.solid_geometry = cascaded_union([geo['geom'] for geo in self.gcode_parsed]) From 1a2b6501f859456d5db4ab7359c35842bad348dc Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 12 Feb 2020 23:30:28 +0200 Subject: [PATCH 087/209] - updated the ReadMe to update that the latest issues were fixed --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 23c5ed06..4f826947 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,8 @@ CAD program, and create G-Code for Isolation routing. 12.02.2020 -- working on fixing a bug in FlatCAMGeometry.merge() - FIXED -- fixed bug: when deleting a FlatCAMCNCJob with annotations enabled, the annotations are not deleted from canvas; +- working on fixing a bug in FlatCAMGeometry.merge() - FIXED issue #380 +- fixed bug: when deleting a FlatCAMCNCJob with annotations enabled, the annotations are not deleted from canvas; fixed issue #379 - fixed bug: creating a new project while a project is open and it contain CNCJob annotations and/or Gerber mark shapes, did not delete them from canvas From 7c9c390ac3816cd130940225717bbe850b66f1d5 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 13 Feb 2020 21:06:10 +0200 Subject: [PATCH 088/209] - finished Punch Gerber Tool - minor PEP8 changes --- FlatCAMApp.py | 63 ++++-- README.md | 6 +- flatcamGUI/FlatCAMGUI.py | 10 +- flatcamGUI/PreferencesUI.py | 239 ++++++++++++++++++++++- flatcamTools/ToolExtractDrills.py | 16 +- flatcamTools/ToolPunchGerber.py | 315 ++++++++++++++++++++++++++++-- 6 files changed, 599 insertions(+), 50 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 16c98005..7f3596e3 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -9,7 +9,6 @@ import urllib.request import urllib.parse import urllib.error -import webbrowser import getopt import random @@ -141,7 +140,7 @@ class App(QtCore.QObject): # ################## Version and VERSION DATE ############################## # ########################################################################## version = 8.992 - version_date = "2020/02/12" + version_date = "2020/02/22" beta = True engine = '3D' @@ -985,6 +984,21 @@ class App(QtCore.QObject): "tools_edrills_rectangular": False, "tools_edrills_others": False, + # Punch Gerber Tool + "tools_punch_hole_type": 'exc', + "tools_punch_hole_fixed_dia": 0.5, + "tools_punch_hole_prop_factor": 80.0, + "tools_punch_circular_ring": 0.2, + "tools_punch_oblong_ring": 0.2, + "tools_punch_square_ring": 0.2, + "tools_punch_rectangular_ring": 0.2, + "tools_punch_others_ring": 0.2, + "tools_punch_circular": True, + "tools_punch_oblong": False, + "tools_punch_square": True, + "tools_punch_rectangular": False, + "tools_punch_others": False, + # Align Objects Tool "tools_align_objects_align_type": 'sp', @@ -1637,6 +1651,21 @@ class App(QtCore.QObject): "tools_edrills_rectangular": self.ui.tools2_defaults_form.tools2_edrills_group.rectangular_cb, "tools_edrills_others": self.ui.tools2_defaults_form.tools2_edrills_group.other_cb, + # Punch Gerber Tool + "tools_punch_hole_type": self.ui.tools2_defaults_form.tools2_punch_group.hole_size_radio, + "tools_punch_hole_fixed_dia": self.ui.tools2_defaults_form.tools2_punch_group.dia_entry, + "tools_punch_hole_prop_factor": self.ui.tools2_defaults_form.tools2_punch_group.factor_entry, + "tools_punch_circular_ring": self.ui.tools2_defaults_form.tools2_punch_group.circular_ring_entry, + "tools_punch_oblong_ring": self.ui.tools2_defaults_form.tools2_punch_group.oblong_ring_entry, + "tools_punch_square_ring": self.ui.tools2_defaults_form.tools2_punch_group.square_ring_entry, + "tools_punch_rectangular_ring": self.ui.tools2_defaults_form.tools2_punch_group.rectangular_ring_entry, + "tools_punch_others_ring": self.ui.tools2_defaults_form.tools2_punch_group.other_ring_entry, + "tools_punch_circular": self.ui.tools2_defaults_form.tools2_punch_group.circular_cb, + "tools_punch_oblong": self.ui.tools2_defaults_form.tools2_punch_group.oblong_cb, + "tools_punch_square": self.ui.tools2_defaults_form.tools2_punch_group.square_cb, + "tools_punch_rectangular": self.ui.tools2_defaults_form.tools2_punch_group.rectangular_cb, + "tools_punch_others": self.ui.tools2_defaults_form.tools2_punch_group.other_cb, + # Utilities # File associations "fa_excellon": self.ui.util_defaults_form.fa_excellon_group.exc_list_text, @@ -3459,7 +3488,7 @@ class App(QtCore.QObject): edited_obj.options['xmax'] = xmax edited_obj.options['ymax'] = ymax except AttributeError as e: - self.inform.emit('[WARNING] %s' % _("Object empty after edit.")) + self.inform.emit('[WARNING] %s' % _("Object empty after edit.")) log.debug("App.editor2object() --> Geometry --> %s" % str(e)) edited_obj.build_ui() @@ -5972,7 +6001,6 @@ class App(QtCore.QObject): tools_diameters[t] *= sfactor self.defaults['geometry_cnctooldia'] += "%.*f," % (self.decimals, tools_diameters[t]) elif dim == 'tools_ncctools': - ncctools = list() if type(self.defaults["tools_ncctools"]) == float: ncctools = [self.defaults["tools_ncctools"]] else: @@ -5988,7 +6016,6 @@ class App(QtCore.QObject): ncctools[t] *= sfactor self.defaults['tools_ncctools'] += "%.*f," % (self.decimals, ncctools[t]) elif dim == 'tools_solderpaste_tools': - sptools = list() if type(self.defaults["tools_solderpaste_tools"]) == float: sptools = [self.defaults["tools_solderpaste_tools"]] else: @@ -6017,7 +6044,6 @@ class App(QtCore.QObject): elif dim == 'global_gridx' or dim == 'global_gridy': if new_units == 'IN': - val = 0.1 try: val = float(self.defaults[dim]) * sfactor except Exception as e: @@ -6026,7 +6052,6 @@ class App(QtCore.QObject): self.defaults[dim] = float('%.*f' % (self.decimals, val)) else: - val = 0.1 try: val = float(self.defaults[dim]) * sfactor except Exception as e: @@ -6035,7 +6060,6 @@ class App(QtCore.QObject): self.defaults[dim] = float('%.*f' % (self.decimals, val)) else: - val = 0.1 if self.defaults[dim]: try: val = float(self.defaults[dim]) * sfactor @@ -7149,7 +7173,7 @@ class App(QtCore.QObject): if self.collection.get_active(): self.log.debug("App.on_delete()") - for obj_active in self.collection.get_selected(): + for obj_active in self.collection.get_selected(): # if the deleted object is FlatCAMGerber then make sure to delete the possible mark shapes if isinstance(obj_active, FlatCAMGerber): for el in obj_active.mark_shapes: @@ -7692,6 +7716,7 @@ class App(QtCore.QObject): obj_init.follow_geometry = deepcopy(obj.follow_geometry) except AttributeError: pass + try: obj_init.apertures = deepcopy(obj.apertures) except AttributeError: @@ -7725,8 +7750,8 @@ class App(QtCore.QObject): self.new_object("gerber", str(obj_name) + custom_name, initialize_gerber) elif isinstance(obj, FlatCAMGeometry): self.new_object("geometry", str(obj_name) + custom_name, initialize_geometry) - except Exception as e: - return "Operation failed: %s" % str(e) + except Exception as er: + return "Operation failed: %s" % str(er) def on_rename_object(self, text): self.report_usage("on_rename_object()") @@ -8761,7 +8786,7 @@ class App(QtCore.QObject): try: # May fail in case mouse not within axes pos_canvas = self.plotcanvas.translate_coords(event_pos) - if self.grid_status() == True: + if self.grid_status(): pos = self.geo_editor.snap(pos_canvas[0], pos_canvas[1]) # Update cursor @@ -8847,7 +8872,7 @@ class App(QtCore.QObject): right_button = 3 pos_canvas = self.plotcanvas.translate_coords(event_pos) - if self.grid_status() == True: + if self.grid_status(): pos = self.geo_editor.snap(pos_canvas[0], pos_canvas[1]) else: pos = (pos_canvas[0], pos_canvas[1]) @@ -10446,8 +10471,8 @@ class App(QtCore.QObject): try: filename, _f = QtWidgets.QFileDialog.getSaveFileName( caption=_("Save Project As ..."), - directory=('{l_save}/{proj}_{date}').format(l_save=str(self.get_last_save_folder()), date=self.date, - proj=_("Project")), + directory='{l_save}/{proj}_{date}'.format(l_save=str(self.get_last_save_folder()), date=self.date, + proj=_("Project")), filter=filter_ ) except TypeError: @@ -10500,9 +10525,9 @@ class App(QtCore.QObject): try: filename, _f = QtWidgets.QFileDialog.getSaveFileName( caption=_("Save Object as PDF ..."), - directory=('{l_save}/{obj_name}_{date}').format(l_save=str(self.get_last_save_folder()), - obj_name=obj_name, - date=self.date), + directory='{l_save}/{obj_name}_{date}'.format(l_save=str(self.get_last_save_folder()), + obj_name=obj_name, + date=self.date), filter=filter_ ) except TypeError: @@ -11484,7 +11509,7 @@ class App(QtCore.QObject): # # ## Object creation # ## ret = self.new_object("geometry", name, obj_init, autoselected=False) if ret == 'fail': - self.inform.emit('[ERROR_NOTCL]%s' % _(' Open HPGL2 failed. Probable not a HPGL2 file.')) + self.inform.emit('[ERROR_NOTCL]%s' % _(' Open HPGL2 failed. Probable not a HPGL2 file.')) return 'fail' # Register recent file diff --git a/README.md b/README.md index 4f826947..8ab918e5 100644 --- a/README.md +++ b/README.md @@ -9,14 +9,16 @@ CAD program, and create G-Code for Isolation routing. ================================================= -12.02.2020 +13.02.2020 +- finished Punch Gerber Tool + +12.02.2020 - working on fixing a bug in FlatCAMGeometry.merge() - FIXED issue #380 - fixed bug: when deleting a FlatCAMCNCJob with annotations enabled, the annotations are not deleted from canvas; fixed issue #379 - fixed bug: creating a new project while a project is open and it contain CNCJob annotations and/or Gerber mark shapes, did not delete them from canvas - 11.02.2020 - working on Tool Punch; finished the geometry update with the clear geometry for the case of Excellon method diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index b67b4c0e..b8154db7 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -1559,6 +1559,10 @@ class FlatCAMGUI(QtWidgets.QMainWindow): ALT+E  %s + + ALT+H +  %s + ALT+I  %s @@ -1688,7 +1692,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): _("Skew on Y axis"), # ALT section _("Align Objects Tool"), _("Calculators Tool"), _("2-Sided PCB Tool"), _("Transformations Tool"), - _("Extract Drills Tool"), _("Fiducials Tool"), + _("Punch Gerber Tool"), _("Extract Drills Tool"), _("Fiducials Tool"), _("Solder Paste Dispensing Tool"), _("Film PCB Tool"), _("Non-Copper Clearing Tool"), _("Optimal Tool"), _("Paint Area Tool"), _("QRCode Tool"), _("Rules Check Tool"), @@ -2974,6 +2978,10 @@ class FlatCAMGUI(QtWidgets.QMainWindow): return # Align in Object Tool + if key == QtCore.Qt.Key_H: + self.app.punch_tool.run(toggle=True) + + # Extract Drills Tool if key == QtCore.Qt.Key_I: self.app.edrills_tool.run(toggle=True) diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index b003b71c..eeeb413a 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -249,6 +249,9 @@ class Tools2PreferencesUI(QtWidgets.QWidget): self.tools2_edrills_group = Tools2EDrillsPrefGroupUI(decimals=self.decimals) self.tools2_edrills_group.setMinimumWidth(220) + self.tools2_punch_group = Tools2PunchGerberPrefGroupUI(decimals=self.decimals) + self.tools2_punch_group.setMinimumWidth(220) + self.vlay = QtWidgets.QVBoxLayout() self.vlay.addWidget(self.tools2_checkrules_group) self.vlay.addWidget(self.tools2_optimal_group) @@ -264,10 +267,14 @@ class Tools2PreferencesUI(QtWidgets.QWidget): self.vlay3.addWidget(self.tools2_cal_group) self.vlay3.addWidget(self.tools2_edrills_group) + self.vlay4 = QtWidgets.QVBoxLayout() + self.vlay4.addWidget(self.tools2_punch_group) + self.layout.addLayout(self.vlay) self.layout.addLayout(self.vlay1) self.layout.addLayout(self.vlay2) self.layout.addLayout(self.vlay3) + self.layout.addLayout(self.vlay4) self.layout.addStretch() @@ -7838,7 +7845,7 @@ class Tools2EDrillsPrefGroupUI(OptionsGroupUI): # Circular Aperture Selection self.circular_cb = FCCheckBox('%s' % _("Circular")) self.circular_cb.setToolTip( - _("Create drills from circular pads.") + _("Process Circular Pads.") ) grid_lay.addWidget(self.circular_cb, 3, 0, 1, 2) @@ -7846,7 +7853,7 @@ class Tools2EDrillsPrefGroupUI(OptionsGroupUI): # Oblong Aperture Selection self.oblong_cb = FCCheckBox('%s' % _("Oblong")) self.oblong_cb.setToolTip( - _("Create drills from oblong pads.") + _("Process Oblong Pads.") ) grid_lay.addWidget(self.oblong_cb, 4, 0, 1, 2) @@ -7854,7 +7861,7 @@ class Tools2EDrillsPrefGroupUI(OptionsGroupUI): # Square Aperture Selection self.square_cb = FCCheckBox('%s' % _("Square")) self.square_cb.setToolTip( - _("Create drills from square pads.") + _("Process Square Pads.") ) grid_lay.addWidget(self.square_cb, 5, 0, 1, 2) @@ -7862,7 +7869,7 @@ class Tools2EDrillsPrefGroupUI(OptionsGroupUI): # Rectangular Aperture Selection self.rectangular_cb = FCCheckBox('%s' % _("Rectangular")) self.rectangular_cb.setToolTip( - _("Create drills from rectangular pads.") + _("Process Rectangular Pads.") ) grid_lay.addWidget(self.rectangular_cb, 6, 0, 1, 2) @@ -7870,7 +7877,7 @@ class Tools2EDrillsPrefGroupUI(OptionsGroupUI): # Others type of Apertures Selection self.other_cb = FCCheckBox('%s' % _("Others")) self.other_cb.setToolTip( - _("Create drills from other types of pad shape.") + _("Process pads not in the categories above.") ) grid_lay.addWidget(self.other_cb, 7, 0, 1, 2) @@ -7891,7 +7898,7 @@ class Tools2EDrillsPrefGroupUI(OptionsGroupUI): stretch=False) self.hole_size_label = QtWidgets.QLabel('%s:' % _("Method")) self.hole_size_label.setToolTip( - _("The selected method of extracting the drills. Can be:\n" + _("The method for processing pads. Can be:\n" "- Fixed Diameter -> all holes will have a set size\n" "- Fixed Annular Ring -> all holes will have a set annular ring\n" "- Proportional -> each hole size will be a fraction of the pad size")) @@ -7915,7 +7922,7 @@ class Tools2EDrillsPrefGroupUI(OptionsGroupUI): self.dia_entry.set_precision(self.decimals) self.dia_entry.set_range(0.0000, 9999.9999) - self.dia_label = QtWidgets.QLabel('%s:' % _("value")) + self.dia_label = QtWidgets.QLabel('%s:' % _("Value")) self.dia_label.setToolTip( _("Fixed hole diameter.") ) @@ -7927,7 +7934,7 @@ class Tools2EDrillsPrefGroupUI(OptionsGroupUI): self.ring_label = QtWidgets.QLabel('%s' % _("Fixed Annular Ring")) self.ring_label.setToolTip( _("The size of annular ring.\n" - "The copper sliver between the drill hole exterior\n" + "The copper sliver between the hole exterior\n" "and the margin of the copper pad.") ) grid_lay.addWidget(self.ring_label, 13, 0, 1, 2) @@ -8009,7 +8016,221 @@ class Tools2EDrillsPrefGroupUI(OptionsGroupUI): self.factor_label = QtWidgets.QLabel('%s:' % _("Factor")) self.factor_label.setToolTip( _("Proportional Diameter.\n" - "The drill diameter will be a fraction of the pad size.") + "The hole diameter will be a fraction of the pad size.") + ) + + grid_lay.addWidget(self.factor_label, 20, 0) + grid_lay.addWidget(self.factor_entry, 20, 1) + + self.layout.addStretch() + + +class Tools2PunchGerberPrefGroupUI(OptionsGroupUI): + def __init__(self, decimals=4, parent=None): + + super(Tools2PunchGerberPrefGroupUI, self).__init__(self) + + self.setTitle(str(_("Punch Gerber Options"))) + self.decimals = decimals + + # ## Grid Layout + grid_lay = QtWidgets.QGridLayout() + self.layout.addLayout(grid_lay) + grid_lay.setColumnStretch(0, 0) + grid_lay.setColumnStretch(1, 1) + + self.param_label = QtWidgets.QLabel('%s:' % _('Parameters')) + self.param_label.setToolTip( + _("Parameters used for this tool.") + ) + grid_lay.addWidget(self.param_label, 0, 0, 1, 2) + + self.padt_label = QtWidgets.QLabel("%s:" % _("Processed Pads Type")) + self.padt_label.setToolTip( + _("The type of pads shape to be processed.\n" + "If the PCB has many SMD pads with rectangular pads,\n" + "disable the Rectangular aperture.") + ) + + grid_lay.addWidget(self.padt_label, 2, 0, 1, 2) + + # Circular Aperture Selection + self.circular_cb = FCCheckBox('%s' % _("Circular")) + self.circular_cb.setToolTip( + _("Process Circular Pads.") + ) + + grid_lay.addWidget(self.circular_cb, 3, 0, 1, 2) + + # Oblong Aperture Selection + self.oblong_cb = FCCheckBox('%s' % _("Oblong")) + self.oblong_cb.setToolTip( + _("Process Oblong Pads.") + ) + + grid_lay.addWidget(self.oblong_cb, 4, 0, 1, 2) + + # Square Aperture Selection + self.square_cb = FCCheckBox('%s' % _("Square")) + self.square_cb.setToolTip( + _("Process Square Pads.") + ) + + grid_lay.addWidget(self.square_cb, 5, 0, 1, 2) + + # Rectangular Aperture Selection + self.rectangular_cb = FCCheckBox('%s' % _("Rectangular")) + self.rectangular_cb.setToolTip( + _("Process Rectangular Pads.") + ) + + grid_lay.addWidget(self.rectangular_cb, 6, 0, 1, 2) + + # Others type of Apertures Selection + self.other_cb = FCCheckBox('%s' % _("Others")) + self.other_cb.setToolTip( + _("Process pads not in the categories above.") + ) + + grid_lay.addWidget(self.other_cb, 7, 0, 1, 2) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid_lay.addWidget(separator_line, 8, 0, 1, 2) + + # ## Axis + self.hole_size_radio = RadioSet( + [ + {'label': _("Excellon"), 'value': 'exc'}, + {'label': _("Fixed Diameter"), 'value': 'fixed'}, + {'label': _("Fixed Annular Ring"), 'value': 'ring'}, + {'label': _("Proportional"), 'value': 'prop'} + ], + orientation='vertical', + stretch=False) + self.hole_size_label = QtWidgets.QLabel('%s:' % _("Method")) + self.hole_size_label.setToolTip( + _("The punch hole source can be:\n" + "- Excellon Object-> the Excellon object drills center will serve as reference.\n" + "- Fixed Diameter -> will try to use the pads center as reference adding fixed diameter holes.\n" + "- Fixed Annular Ring -> will try to keep a set annular ring.\n" + "- Proportional -> will make a Gerber punch hole having the diameter a percentage of the pad diameter.\n") + ) + grid_lay.addWidget(self.hole_size_label, 9, 0) + grid_lay.addWidget(self.hole_size_radio, 9, 1) + + # grid_lay1.addWidget(QtWidgets.QLabel('')) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid_lay.addWidget(separator_line, 10, 0, 1, 2) + + # Annular Ring + self.fixed_label = QtWidgets.QLabel('%s' % _("Fixed Diameter")) + grid_lay.addWidget(self.fixed_label, 11, 0, 1, 2) + + # Diameter value + self.dia_entry = FCDoubleSpinner() + self.dia_entry.set_precision(self.decimals) + self.dia_entry.set_range(0.0000, 9999.9999) + + self.dia_label = QtWidgets.QLabel('%s:' % _("Value")) + self.dia_label.setToolTip( + _("Fixed hole diameter.") + ) + + grid_lay.addWidget(self.dia_label, 12, 0) + grid_lay.addWidget(self.dia_entry, 12, 1) + + # Annular Ring value + self.ring_label = QtWidgets.QLabel('%s' % _("Fixed Annular Ring")) + self.ring_label.setToolTip( + _("The size of annular ring.\n" + "The copper sliver between the hole exterior\n" + "and the margin of the copper pad.") + ) + grid_lay.addWidget(self.ring_label, 13, 0, 1, 2) + + # Circular Annular Ring Value + self.circular_ring_label = QtWidgets.QLabel('%s:' % _("Circular")) + self.circular_ring_label.setToolTip( + _("The size of annular ring for circular pads.") + ) + + self.circular_ring_entry = FCDoubleSpinner() + self.circular_ring_entry.set_precision(self.decimals) + self.circular_ring_entry.set_range(0.0000, 9999.9999) + + grid_lay.addWidget(self.circular_ring_label, 14, 0) + grid_lay.addWidget(self.circular_ring_entry, 14, 1) + + # Oblong Annular Ring Value + self.oblong_ring_label = QtWidgets.QLabel('%s:' % _("Oblong")) + self.oblong_ring_label.setToolTip( + _("The size of annular ring for oblong pads.") + ) + + self.oblong_ring_entry = FCDoubleSpinner() + self.oblong_ring_entry.set_precision(self.decimals) + self.oblong_ring_entry.set_range(0.0000, 9999.9999) + + grid_lay.addWidget(self.oblong_ring_label, 15, 0) + grid_lay.addWidget(self.oblong_ring_entry, 15, 1) + + # Square Annular Ring Value + self.square_ring_label = QtWidgets.QLabel('%s:' % _("Square")) + self.square_ring_label.setToolTip( + _("The size of annular ring for square pads.") + ) + + self.square_ring_entry = FCDoubleSpinner() + self.square_ring_entry.set_precision(self.decimals) + self.square_ring_entry.set_range(0.0000, 9999.9999) + + grid_lay.addWidget(self.square_ring_label, 16, 0) + grid_lay.addWidget(self.square_ring_entry, 16, 1) + + # Rectangular Annular Ring Value + self.rectangular_ring_label = QtWidgets.QLabel('%s:' % _("Rectangular")) + self.rectangular_ring_label.setToolTip( + _("The size of annular ring for rectangular pads.") + ) + + self.rectangular_ring_entry = FCDoubleSpinner() + self.rectangular_ring_entry.set_precision(self.decimals) + self.rectangular_ring_entry.set_range(0.0000, 9999.9999) + + grid_lay.addWidget(self.rectangular_ring_label, 17, 0) + grid_lay.addWidget(self.rectangular_ring_entry, 17, 1) + + # Others Annular Ring Value + self.other_ring_label = QtWidgets.QLabel('%s:' % _("Others")) + self.other_ring_label.setToolTip( + _("The size of annular ring for other pads.") + ) + + self.other_ring_entry = FCDoubleSpinner() + self.other_ring_entry.set_precision(self.decimals) + self.other_ring_entry.set_range(0.0000, 9999.9999) + + grid_lay.addWidget(self.other_ring_label, 18, 0) + grid_lay.addWidget(self.other_ring_entry, 18, 1) + + self.prop_label = QtWidgets.QLabel('%s' % _("Proportional Diameter")) + grid_lay.addWidget(self.prop_label, 19, 0, 1, 2) + + # Factor value + self.factor_entry = FCDoubleSpinner(suffix='%') + self.factor_entry.set_precision(self.decimals) + self.factor_entry.set_range(0.0000, 100.0000) + self.factor_entry.setSingleStep(0.1) + + self.factor_label = QtWidgets.QLabel('%s:' % _("Factor")) + self.factor_label.setToolTip( + _("Proportional Diameter.\n" + "The hole diameter will be a fraction of the pad size.") ) grid_lay.addWidget(self.factor_label, 20, 0) diff --git a/flatcamTools/ToolExtractDrills.py b/flatcamTools/ToolExtractDrills.py index 7fa1dc98..bc772e42 100644 --- a/flatcamTools/ToolExtractDrills.py +++ b/flatcamTools/ToolExtractDrills.py @@ -76,7 +76,7 @@ class ToolExtractDrills(FlatCAMTool): # Circular Aperture Selection self.circular_cb = FCCheckBox('%s' % _("Circular")) self.circular_cb.setToolTip( - _("Create drills from circular pads.") + _("Process Circular Pads.") ) grid_lay.addWidget(self.circular_cb, 3, 0, 1, 2) @@ -84,7 +84,7 @@ class ToolExtractDrills(FlatCAMTool): # Oblong Aperture Selection self.oblong_cb = FCCheckBox('%s' % _("Oblong")) self.oblong_cb.setToolTip( - _("Create drills from oblong pads.") + _("Process Oblong Pads.") ) grid_lay.addWidget(self.oblong_cb, 4, 0, 1, 2) @@ -92,7 +92,7 @@ class ToolExtractDrills(FlatCAMTool): # Square Aperture Selection self.square_cb = FCCheckBox('%s' % _("Square")) self.square_cb.setToolTip( - _("Create drills from square pads.") + _("Process Square Pads.") ) grid_lay.addWidget(self.square_cb, 5, 0, 1, 2) @@ -100,7 +100,7 @@ class ToolExtractDrills(FlatCAMTool): # Rectangular Aperture Selection self.rectangular_cb = FCCheckBox('%s' % _("Rectangular")) self.rectangular_cb.setToolTip( - _("Create drills from rectangular pads.") + _("Process Rectangular Pads.") ) grid_lay.addWidget(self.rectangular_cb, 6, 0, 1, 2) @@ -108,7 +108,7 @@ class ToolExtractDrills(FlatCAMTool): # Others type of Apertures Selection self.other_cb = FCCheckBox('%s' % _("Others")) self.other_cb.setToolTip( - _("Create drills from other types of pad shape.") + _("Process pads not in the categories above.") ) grid_lay.addWidget(self.other_cb, 7, 0, 1, 2) @@ -126,7 +126,7 @@ class ToolExtractDrills(FlatCAMTool): self.method_label = QtWidgets.QLabel('%s' % _("Method")) self.method_label.setToolTip( - _("The selected method of extracting the drills. Can be:\n" + _("The method for processing pads. Can be:\n" "- Fixed Diameter -> all holes will have a set size\n" "- Fixed Annular Ring -> all holes will have a set annular ring\n" "- Proportional -> each hole size will be a fraction of the pad size")) @@ -191,7 +191,7 @@ class ToolExtractDrills(FlatCAMTool): self.ring_label = QtWidgets.QLabel('%s' % _("Fixed Annular Ring")) self.ring_label.setToolTip( _("The size of annular ring.\n" - "The copper sliver between the drill hole exterior\n" + "The copper sliver between the hole exterior\n" "and the margin of the copper pad.") ) grid2.addWidget(self.ring_label, 0, 0, 1, 2) @@ -284,7 +284,7 @@ class ToolExtractDrills(FlatCAMTool): self.factor_label = QtWidgets.QLabel('%s:' % _("Value")) self.factor_label.setToolTip( _("Proportional Diameter.\n" - "The drill diameter will be a fraction of the pad size.") + "The hole diameter will be a fraction of the pad size.") ) grid3.addWidget(self.factor_label, 3, 0) diff --git a/flatcamTools/ToolPunchGerber.py b/flatcamTools/ToolPunchGerber.py index 10bf4b92..f7378933 100644 --- a/flatcamTools/ToolPunchGerber.py +++ b/flatcamTools/ToolPunchGerber.py @@ -87,7 +87,7 @@ class ToolPunchGerber(FlatCAMTool): # Circular Aperture Selection self.circular_cb = FCCheckBox('%s' % _("Circular")) self.circular_cb.setToolTip( - _("Create drills from circular pads.") + _("Process Circular Pads.") ) grid_lay.addWidget(self.circular_cb, 5, 0, 1, 2) @@ -95,7 +95,7 @@ class ToolPunchGerber(FlatCAMTool): # Oblong Aperture Selection self.oblong_cb = FCCheckBox('%s' % _("Oblong")) self.oblong_cb.setToolTip( - _("Create drills from oblong pads.") + _("Process Oblong Pads.") ) grid_lay.addWidget(self.oblong_cb, 6, 0, 1, 2) @@ -103,7 +103,7 @@ class ToolPunchGerber(FlatCAMTool): # Square Aperture Selection self.square_cb = FCCheckBox('%s' % _("Square")) self.square_cb.setToolTip( - _("Create drills from square pads.") + _("Process Square Pads.") ) grid_lay.addWidget(self.square_cb, 7, 0, 1, 2) @@ -111,7 +111,7 @@ class ToolPunchGerber(FlatCAMTool): # Rectangular Aperture Selection self.rectangular_cb = FCCheckBox('%s' % _("Rectangular")) self.rectangular_cb.setToolTip( - _("Create drills from rectangular pads.") + _("Process Rectangular Pads.") ) grid_lay.addWidget(self.rectangular_cb, 8, 0, 1, 2) @@ -119,7 +119,7 @@ class ToolPunchGerber(FlatCAMTool): # Others type of Apertures Selection self.other_cb = FCCheckBox('%s' % _("Others")) self.other_cb.setToolTip( - _("Create drills from other types of pad shape.") + _("Process pads not in the categories above.") ) grid_lay.addWidget(self.other_cb, 9, 0, 1, 2) @@ -212,7 +212,7 @@ class ToolPunchGerber(FlatCAMTool): self.ring_label = QtWidgets.QLabel('%s' % _("Fixed Annular Ring")) self.ring_label.setToolTip( _("The size of annular ring.\n" - "The copper sliver between the drill hole exterior\n" + "The copper sliver between the hole exterior\n" "and the margin of the copper pad.") ) self.ring_box.addWidget(self.ring_label) @@ -306,7 +306,7 @@ class ToolPunchGerber(FlatCAMTool): self.factor_label = QtWidgets.QLabel('%s:' % _("Value")) self.factor_label.setToolTip( _("Proportional Diameter.\n" - "The drill diameter will be a fraction of the pad size.") + "The hole diameter will be a fraction of the pad size.") ) grid0.addWidget(self.factor_label, 13, 0) @@ -429,8 +429,24 @@ class ToolPunchGerber(FlatCAMTool): self.reset_fields() self.ui_connect() - self.method_punch.set_value('exc') - self.select_all_cb.set_value(True) + self.method_punch.set_value(self.app.defaults["tools_punch_hole_type"]) + self.select_all_cb.set_value(False) + + self.dia_entry.set_value(float(self.app.defaults["tools_punch_hole_fixed_dia"])) + + self.circular_ring_entry.set_value(float(self.app.defaults["tools_punch_circular_ring"])) + self.oblong_ring_entry.set_value(float(self.app.defaults["tools_punch_oblong_ring"])) + self.square_ring_entry.set_value(float(self.app.defaults["tools_punch_square_ring"])) + self.rectangular_ring_entry.set_value(float(self.app.defaults["tools_punch_rectangular_ring"])) + self.other_ring_entry.set_value(float(self.app.defaults["tools_punch_others_ring"])) + + self.circular_cb.set_value(self.app.defaults["tools_punch_circular"]) + self.oblong_cb.set_value(self.app.defaults["tools_punch_oblong"]) + self.square_cb.set_value(self.app.defaults["tools_punch_square"]) + self.rectangular_cb.set_value(self.app.defaults["tools_punch_rectangular"]) + self.other_cb.set_value(self.app.defaults["tools_punch_others"]) + + self.factor_entry.set_value(float(self.app.defaults["tools_punch_hole_prop_factor"])) def on_select_all(self, state): self.ui_disconnect() @@ -685,9 +701,286 @@ class ToolPunchGerber(FlatCAMTool): self.app.new_object('gerber', outname, init_func) elif punch_method == 'ring': - pass + circ_r_val = self.circular_ring_entry.get_value() + oblong_r_val = self.oblong_ring_entry.get_value() + square_r_val = self.square_ring_entry.get_value() + rect_r_val = self.rectangular_ring_entry.get_value() + other_r_val = self.other_ring_entry.get_value() + + dia = None + + if isinstance(grb_obj.solid_geometry, list): + temp_solid_geometry = MultiPolygon(grb_obj.solid_geometry) + else: + temp_solid_geometry = grb_obj.solid_geometry + + punched_solid_geometry = temp_solid_geometry + + new_apertures = deepcopy(grb_obj.apertures) + new_apertures_items = new_apertures.items() + + # find maximum aperture id + new_apid = max([int(x) for x, __ in new_apertures_items]) + + # store here the clear geometry, the key is the new aperture size + holes_apertures = dict() + + for apid, apid_value in grb_obj.apertures.items(): + ap_type = apid_value['type'] + punching_geo = list() + + if ap_type == 'C' and self.circular_cb.get_value(): + dia = float(apid_value['size']) - (2 * circ_r_val) + for elem in apid_value['geometry']: + if 'follow' in elem and isinstance(elem['follow'], Point): + punching_geo.append(elem['follow'].buffer(dia / 2)) + + elif ap_type == 'O' and self.oblong_cb.get_value(): + width = float(apid_value['width']) + height = float(apid_value['height']) + + if width > height: + dia = float(apid_value['height']) - (2 * oblong_r_val) + else: + dia = float(apid_value['width']) - (2 * oblong_r_val) + + for elem in grb_obj.apertures[apid]['geometry']: + if 'follow' in elem: + if isinstance(elem['follow'], Point): + punching_geo.append(elem['follow'].buffer(dia / 2)) + + elif ap_type == 'R': + width = float(apid_value['width']) + height = float(apid_value['height']) + + # if the height == width (float numbers so the reason for the following) + if round(width, self.decimals) == round(height, self.decimals): + if self.square_cb.get_value(): + dia = float(apid_value['height']) - (2 * square_r_val) + + for elem in grb_obj.apertures[apid]['geometry']: + if 'follow' in elem: + if isinstance(elem['follow'], Point): + punching_geo.append(elem['follow'].buffer(dia / 2)) + elif self.rectangular_cb.get_value(): + if width > height: + dia = float(apid_value['height']) - (2 * rect_r_val) + else: + dia = float(apid_value['width']) - (2 * rect_r_val) + + for elem in grb_obj.apertures[apid]['geometry']: + if 'follow' in elem: + if isinstance(elem['follow'], Point): + punching_geo.append(elem['follow'].buffer(dia / 2)) + + elif self.other_cb.get_value(): + try: + dia = float(apid_value['size']) - (2 * other_r_val) + except KeyError: + if ap_type == 'AM': + pol = apid_value['geometry'][0]['solid'] + x0, y0, x1, y1 = pol.bounds + dx = x1 - x0 + dy = y1 - y0 + if dx <= dy: + dia = dx - (2 * other_r_val) + else: + dia = dy - (2 * other_r_val) + + for elem in grb_obj.apertures[apid]['geometry']: + if 'follow' in elem: + if isinstance(elem['follow'], Point): + punching_geo.append(elem['follow'].buffer(dia / 2)) + + # if dia is None then none of the above applied so we skip the following + if dia is None: + continue + + punching_geo = MultiPolygon(punching_geo) + + if punching_geo is None or punching_geo.is_empty: + continue + + punched_solid_geometry = punched_solid_geometry.difference(punching_geo) + + # update the gerber apertures to include the clear geometry so it can be exported successfully + for elem in apid_value['geometry']: + # make it work only for Gerber Flashes who are Points in 'follow' + if 'solid' in elem and isinstance(elem['follow'], Point): + clear_apid_size = dia + for geo in punching_geo: + + # since there may be drills that do not drill into a pad we test only for geos in a pad + if geo.within(elem['solid']): + geo_elem = dict() + geo_elem['clear'] = geo.centroid + + if clear_apid_size not in holes_apertures: + holes_apertures[clear_apid_size] = dict() + holes_apertures[clear_apid_size]['type'] = 'C' + holes_apertures[clear_apid_size]['size'] = clear_apid_size + holes_apertures[clear_apid_size]['geometry'] = list() + + holes_apertures[clear_apid_size]['geometry'].append(deepcopy(geo_elem)) + + # add the clear geometry to new apertures; it's easier than to test if there are apertures with the same + # size and add there the clear geometry + for hole_size, ap_val in holes_apertures.items(): + new_apid += 1 + new_apertures[str(new_apid)] = deepcopy(ap_val) + + def init_func(new_obj, app_obj): + new_obj.options.update(grb_obj.options) + new_obj.options['name'] = outname + new_obj.fill_color = deepcopy(grb_obj.fill_color) + new_obj.outline_color = deepcopy(grb_obj.outline_color) + + new_obj.apertures = deepcopy(new_apertures) + + new_obj.solid_geometry = deepcopy(punched_solid_geometry) + new_obj.source_file = self.app.export_gerber(obj_name=outname, filename=None, + local_use=new_obj, use_thread=False) + + self.app.new_object('gerber', outname, init_func) + elif punch_method == 'prop': - pass + prop_factor = self.factor_entry.get_value() / 100.0 + + dia = None + + if isinstance(grb_obj.solid_geometry, list): + temp_solid_geometry = MultiPolygon(grb_obj.solid_geometry) + else: + temp_solid_geometry = grb_obj.solid_geometry + + punched_solid_geometry = temp_solid_geometry + + new_apertures = deepcopy(grb_obj.apertures) + new_apertures_items = new_apertures.items() + + # find maximum aperture id + new_apid = max([int(x) for x, __ in new_apertures_items]) + + # store here the clear geometry, the key is the new aperture size + holes_apertures = dict() + + for apid, apid_value in grb_obj.apertures.items(): + ap_type = apid_value['type'] + punching_geo = list() + + if ap_type == 'C' and self.circular_cb.get_value(): + dia = float(apid_value['size']) * prop_factor + for elem in apid_value['geometry']: + if 'follow' in elem and isinstance(elem['follow'], Point): + punching_geo.append(elem['follow'].buffer(dia / 2)) + + elif ap_type == 'O' and self.oblong_cb.get_value(): + width = float(apid_value['width']) + height = float(apid_value['height']) + + if width > height: + dia = float(apid_value['height']) * prop_factor + else: + dia = float(apid_value['width']) * prop_factor + + for elem in grb_obj.apertures[apid]['geometry']: + if 'follow' in elem: + if isinstance(elem['follow'], Point): + punching_geo.append(elem['follow'].buffer(dia / 2)) + + elif ap_type == 'R': + width = float(apid_value['width']) + height = float(apid_value['height']) + + # if the height == width (float numbers so the reason for the following) + if round(width, self.decimals) == round(height, self.decimals): + if self.square_cb.get_value(): + dia = float(apid_value['height']) * prop_factor + + for elem in grb_obj.apertures[apid]['geometry']: + if 'follow' in elem: + if isinstance(elem['follow'], Point): + punching_geo.append(elem['follow'].buffer(dia / 2)) + elif self.rectangular_cb.get_value(): + if width > height: + dia = float(apid_value['height']) * prop_factor + else: + dia = float(apid_value['width']) * prop_factor + + for elem in grb_obj.apertures[apid]['geometry']: + if 'follow' in elem: + if isinstance(elem['follow'], Point): + punching_geo.append(elem['follow'].buffer(dia / 2)) + + elif self.other_cb.get_value(): + try: + dia = float(apid_value['size']) * prop_factor + except KeyError: + if ap_type == 'AM': + pol = apid_value['geometry'][0]['solid'] + x0, y0, x1, y1 = pol.bounds + dx = x1 - x0 + dy = y1 - y0 + if dx <= dy: + dia = dx * prop_factor + else: + dia = dy * prop_factor + + for elem in grb_obj.apertures[apid]['geometry']: + if 'follow' in elem: + if isinstance(elem['follow'], Point): + punching_geo.append(elem['follow'].buffer(dia / 2)) + + # if dia is None then none of the above applied so we skip the following + if dia is None: + continue + + punching_geo = MultiPolygon(punching_geo) + + if punching_geo is None or punching_geo.is_empty: + continue + + punched_solid_geometry = punched_solid_geometry.difference(punching_geo) + + # update the gerber apertures to include the clear geometry so it can be exported successfully + for elem in apid_value['geometry']: + # make it work only for Gerber Flashes who are Points in 'follow' + if 'solid' in elem and isinstance(elem['follow'], Point): + clear_apid_size = dia + for geo in punching_geo: + + # since there may be drills that do not drill into a pad we test only for geos in a pad + if geo.within(elem['solid']): + geo_elem = dict() + geo_elem['clear'] = geo.centroid + + if clear_apid_size not in holes_apertures: + holes_apertures[clear_apid_size] = dict() + holes_apertures[clear_apid_size]['type'] = 'C' + holes_apertures[clear_apid_size]['size'] = clear_apid_size + holes_apertures[clear_apid_size]['geometry'] = list() + + holes_apertures[clear_apid_size]['geometry'].append(deepcopy(geo_elem)) + + # add the clear geometry to new apertures; it's easier than to test if there are apertures with the same + # size and add there the clear geometry + for hole_size, ap_val in holes_apertures.items(): + new_apid += 1 + new_apertures[str(new_apid)] = deepcopy(ap_val) + + def init_func(new_obj, app_obj): + new_obj.options.update(grb_obj.options) + new_obj.options['name'] = outname + new_obj.fill_color = deepcopy(grb_obj.fill_color) + new_obj.outline_color = deepcopy(grb_obj.outline_color) + + new_obj.apertures = deepcopy(new_apertures) + + new_obj.solid_geometry = deepcopy(punched_solid_geometry) + new_obj.source_file = self.app.export_gerber(obj_name=outname, filename=None, + local_use=new_obj, use_thread=False) + + self.app.new_object('gerber', outname, init_func) def reset_fields(self): self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) From 9417049eefbb0dabb17af9fbc94ad499bcb54125 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 13 Feb 2020 21:11:06 +0200 Subject: [PATCH 089/209] - some updates in the requirements file and in setup_ubuntu.sh; for now versions higher than 5.12.1 of pyqt5 are not working --- requirements.txt | 3 ++- setup_ubuntu.sh | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 259ef455..6e58e3f7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,8 @@ # This file contains python only requirements to be installed with pip # Python packages that cannot be installed with pip (e.g. PyQt5, GDAL) are not included. # Usage: pip3 install -r requirements.txt -numpy >=1.16 +pyqt5==5.12 +numpy>=1.16 matplotlib>=3.1 cycler>=0.10 python-dateutil>=2.1 diff --git a/setup_ubuntu.sh b/setup_ubuntu.sh index 4830b383..9054a57c 100644 --- a/setup_ubuntu.sh +++ b/setup_ubuntu.sh @@ -3,6 +3,7 @@ sudo apt install --reinstall libpng-dev libfreetype6 libfreetype6-dev libgeos-de sudo apt install --reinstall python3-dev python3-pyqt5 python3-pyqt5.qtopengl python3-gdal python3-simplejson sudo apt install --reinstall python3-pip python3-tk python3-imaging +sudo python3 -m pip install --upgrade pyqt5==5.12 sudo python3 -m pip install --upgrade pip numpy scipy shapely rtree tk lxml cycler python-dateutil kiwisolver dill sudo python3 -m pip install --upgrade vispy pyopengl setuptools svg.path ortools freetype-py fontTools rasterio ezdxf sudo python3 -m pip install --upgrade matplotlib qrcode reportlab svglib \ No newline at end of file From 8ff3248c25b70e69fc7f290d710f878f2d459401 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 13 Feb 2020 21:22:21 +0200 Subject: [PATCH 090/209] - minor changes in the Tool Transform and Tool Calculators UI to bring them up2date with the other tools --- README.md | 1 + flatcamTools/ToolCalculators.py | 14 ++++++++++++++ flatcamTools/ToolTransform.py | 15 +++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/README.md b/README.md index 8ab918e5..2fb1bf22 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 13.02.2020 - finished Punch Gerber Tool +- minor changes in the Tool Transform and Tool Calculators UI to bring them up2date with the other tools 12.02.2020 diff --git a/flatcamTools/ToolCalculators.py b/flatcamTools/ToolCalculators.py index 2cc2551e..3a7ff665 100644 --- a/flatcamTools/ToolCalculators.py +++ b/flatcamTools/ToolCalculators.py @@ -242,6 +242,19 @@ class ToolCalculator(FlatCAMTool): self.layout.addStretch() + # ## Reset Tool + self.reset_button = QtWidgets.QPushButton(_("Reset Tool")) + self.reset_button.setToolTip( + _("Will reset the tool parameters.") + ) + self.reset_button.setStyleSheet(""" + QPushButton + { + font-weight: bold; + } + """) + self.layout.addWidget(self.reset_button) + self.units = '' # ## Signals @@ -255,6 +268,7 @@ class ToolCalculator(FlatCAMTool): self.inch_entry.editingFinished.connect(self.on_calculate_mm_units) self.calculate_plate_button.clicked.connect(self.on_calculate_eplate) + self.reset_button.clicked.connect(self.set_tool_ui) def run(self, toggle=True): self.app.report_usage("ToolCalculators()") diff --git a/flatcamTools/ToolTransform.py b/flatcamTools/ToolTransform.py index aa0a9a1e..04cb1dc8 100644 --- a/flatcamTools/ToolTransform.py +++ b/flatcamTools/ToolTransform.py @@ -412,6 +412,19 @@ class ToolTransform(FlatCAMTool): self.transform_lay.addStretch() + # ## Reset Tool + self.reset_button = QtWidgets.QPushButton(_("Reset Tool")) + self.reset_button.setToolTip( + _("Will reset the tool parameters.") + ) + self.reset_button.setStyleSheet(""" + QPushButton + { + font-weight: bold; + } + """) + self.transform_lay.addWidget(self.reset_button) + # ## Signals self.rotate_button.clicked.connect(self.on_rotate) self.skewx_button.clicked.connect(self.on_skewx) @@ -426,6 +439,8 @@ class ToolTransform(FlatCAMTool): self.buffer_button.clicked.connect(self.on_buffer_by_distance) self.buffer_factor_button.clicked.connect(self.on_buffer_by_factor) + self.reset_button.clicked.connect(self.set_tool_ui) + # self.rotate_entry.returnPressed.connect(self.on_rotate) # self.skewx_entry.returnPressed.connect(self.on_skewx) # self.skewy_entry.returnPressed.connect(self.on_skewy) From e8ecf7a83cce9a32ec297e479e89430c606e605a Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 13 Feb 2020 21:45:43 +0200 Subject: [PATCH 091/209] - PEP8 changes --- FlatCAMObj.py | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 8a1023b7..e0534d7a 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -35,7 +35,9 @@ import FlatCAMApp from flatcamGUI.VisPyVisuals import ShapeCollection import tkinter as tk -import os, sys, itertools +import os +import sys +import itertools import ezdxf import math @@ -246,7 +248,7 @@ class FlatCAMObj(QtCore.QObject): self.app.myKeywords.append(new_name) self.app.shell._edit.set_model_data(self.app.myKeywords) self.app.ui.code_editor.set_model_data(self.app.myKeywords) - except Exception as e: + except Exception: log.debug("on_name_activate() --> Could not remove the old object name from auto-completer model list") self.options["name"] = self.ui.name_entry.get_value() @@ -791,15 +793,15 @@ class FlatCAMGerber(FlatCAMObj, Gerber): def on_calculate_tooldia(self): try: tdia = float(self.ui.tipdia_spinner.get_value()) - except Exception as e: + except Exception: return try: dang = float(self.ui.tipangle_spinner.get_value()) - except Exception as e: + except Exception: return try: cutz = float(self.ui.cutz_spinner.get_value()) - except Exception as e: + except Exception: return cutz *= -1 @@ -1384,13 +1386,13 @@ class FlatCAMGerber(FlatCAMObj, Gerber): } }) - for i in range(passes): - iso_offset = dia * ((2 * i + 1) / 2.0) - (i * overlap * dia) + for nr_pass in range(passes): + iso_offset = dia * ((2 * nr_pass + 1) / 2.0) - (nr_pass * overlap * dia) # if milling type is climb then the move is counter-clockwise around features mill_dir = 1 if milling_type == 'cl' else 0 geom = self.generate_envelope(iso_offset, mill_dir, geometry=work_geo, env_iso_type=iso_t, - follow=follow, nr_passes=i) + follow=follow, nr_passes=nr_pass) if geom == 'fail': app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Isolation geometry could not be generated.")) @@ -2380,7 +2382,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): # Attributes to be included in serialization # Always append to it because it carries contents # from predecessors. - self.ser_attrs += ['options', 'kind',] + self.ser_attrs += ['options', 'kind'] def merge(self, exc_list, exc_final): """ @@ -2425,7 +2427,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): if option is not 'name': try: exc_final.options[option] = exc.options[option] - except Exception as e: + except Exception: exc.app.log.warning("Failed to copy option.", option) for drill in exc.drills: @@ -3934,7 +3936,6 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.units = self.app.defaults['units'] - offset = 0 tool_idx = 0 n = len(self.tools) @@ -4852,7 +4853,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): obj_active.options['ymin'] = ymin obj_active.options['xmax'] = xmax obj_active.options['ymax'] = ymax - except Exception as e: + except Exception: obj_active.options['xmin'] = 0 obj_active.options['ymin'] = 0 obj_active.options['xmax'] = 0 @@ -5036,7 +5037,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): widget_changed = self.sender() try: widget_idx = self.ui.grid3.indexOf(widget_changed) - except Exception as e: + except Exception: return # those are the indexes for the V-Tip Dia and V-Tip Angle, if edited calculate the new Cut Z @@ -5887,7 +5888,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): try: xfactor = float(xfactor) except Exception: - self.app.inform.emit('[ERROR_NOTCL] %s' % _("Scale factor has to be a number: integer or float.")) + self.app.inform.emit('[ERROR_NOTCL] %s' % _("Scale factor has to be a number: integer or float.")) return if yfactor is None: @@ -6497,7 +6498,6 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): self.ui_connect() def build_cnc_tools_table(self): - offset = 0 tool_idx = 0 n = len(self.cnc_tools) @@ -6508,9 +6508,9 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): tool_idx += 1 row_no = tool_idx - 1 - id = QtWidgets.QTableWidgetItem('%d' % int(tool_idx)) + t_id = QtWidgets.QTableWidgetItem('%d' % int(tool_idx)) # id.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - self.ui.cnc_tools_table.setItem(row_no, 0, id) # Tool name/id + self.ui.cnc_tools_table.setItem(row_no, 0, t_id) # Tool name/id # Make sure that the tool diameter when in MM is with no more than 2 decimals. # There are no tool bits in MM with more than 2 decimals diameter. @@ -6524,7 +6524,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): type_item = QtWidgets.QTableWidgetItem(str(dia_value['type'])) tool_type_item = QtWidgets.QTableWidgetItem(str(dia_value['tool_type'])) - id.setFlags(QtCore.Qt.ItemIsEnabled) + t_id.setFlags(QtCore.Qt.ItemIsEnabled) dia_item.setFlags(QtCore.Qt.ItemIsEnabled) offset_item.setFlags(QtCore.Qt.ItemIsEnabled) type_item.setFlags(QtCore.Qt.ItemIsEnabled) @@ -6606,13 +6606,13 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): tool_idx += 1 row_no = tool_idx - 1 - id = QtWidgets.QTableWidgetItem('%d' % int(tool_idx)) + t_id = QtWidgets.QTableWidgetItem('%d' % int(tool_idx)) dia_item = QtWidgets.QTableWidgetItem('%.*f' % (self.decimals, float(tooldia_key))) nr_drills_item = QtWidgets.QTableWidgetItem('%d' % int(dia_value['nr_drills'])) nr_slots_item = QtWidgets.QTableWidgetItem('%d' % int(dia_value['nr_slots'])) cutz_item = QtWidgets.QTableWidgetItem('%.*f' % (self.decimals, float(dia_value['offset_z']) + self.z_cut)) - id.setFlags(QtCore.Qt.ItemIsEnabled) + t_id.setFlags(QtCore.Qt.ItemIsEnabled) dia_item.setFlags(QtCore.Qt.ItemIsEnabled) nr_drills_item.setFlags(QtCore.Qt.ItemIsEnabled) nr_slots_item.setFlags(QtCore.Qt.ItemIsEnabled) @@ -6638,7 +6638,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): # TODO until the feature of individual plot for an Excellon tool is implemented plot_item.setDisabled(True) - self.ui.exc_cnc_tools_table.setItem(row_no, 0, id) # Tool name/id + self.ui.exc_cnc_tools_table.setItem(row_no, 0, t_id) # Tool name/id self.ui.exc_cnc_tools_table.setItem(row_no, 1, dia_item) # Diameter self.ui.exc_cnc_tools_table.setItem(row_no, 2, nr_drills_item) # Nr of drills self.ui.exc_cnc_tools_table.setItem(row_no, 3, nr_slots_item) # Nr of slots @@ -6935,7 +6935,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): try: for key in self.cnc_tools: ppg = self.cnc_tools[key]['data']['ppname_g'] - if 'marlin' in ppg.lower() or 'repetier' in ppg.lower() : + if 'marlin' in ppg.lower() or 'repetier' in ppg.lower(): marlin = True break if ppg == 'hpgl': @@ -7711,9 +7711,10 @@ class FlatCAMDocument(FlatCAMObj): self.source_file = '' self.doc_code = '' + self.font_name = None self.font_italic = None self.font_bold = None - self.font_underline =None + self.font_underline = None self.document_editor_tab = None From 2369ebe72af51fb5a496138782946fb5922769d1 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 14 Feb 2020 04:18:49 +0200 Subject: [PATCH 092/209] - more PEP8 changes --- flatcamTools/ToolPaint.py | 40 ++++++++++++++------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 60ff4f07..5d9780f3 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -1630,25 +1630,17 @@ class ToolPaint(FlatCAMTool, Gerber): self.app.draw_moving_selection_shape(old_coords=(self.cursor_pos[0], self.cursor_pos[1]), coords=(curr_pos[0], curr_pos[1])) - def paint_poly(self, obj, - inside_pt=None, - poly_list=None, - tooldia=None, - overlap=None, - order=None, - margin=None, - method=None, - outname=None, - connect=None, - contour=None, - tools_storage=None, - plot=True, - run_threaded=True): + def paint_poly(self, obj, inside_pt=None, poly_list=None, tooldia=None, overlap=None, order=None, + margin=None, method=None, outname=None, connect=None, contour=None, tools_storage=None, + plot=True, run_threaded=True): """ Paints a polygon selected by clicking on its interior or by having a point coordinates given Note: * The margin is taken directly from the form. + :param run_threaded: + :param plot: + :param poly_list: :param obj: painted object :param inside_pt: [x, y] :param tooldia: Diameter of the painting tool @@ -1909,21 +1901,13 @@ class ToolPaint(FlatCAMTool, Gerber): else: job_thread(app_obj=self.app) - def paint_poly_all(self, obj, - tooldia=None, - overlap=None, - order=None, - margin=None, - method=None, - outname=None, - connect=None, - contour=None, - tools_storage=None, - plot=True, - run_threaded=True): + def paint_poly_all(self, obj, tooldia=None, overlap=None, order=None, margin=None, method=None, outname=None, + connect=None, contour=None, tools_storage=None, plot=True, run_threaded=True): """ Paints all polygons in this object. + :param run_threaded: + :param plot: :param obj: painted object :param tooldia: a tuple or single element made out of diameters of the tools to be used :param overlap: value by which the paths will overlap @@ -2499,6 +2483,8 @@ class ToolPaint(FlatCAMTool, Gerber): """ Paints all polygons in this object that are within the sel_obj object + :param run_threaded: + :param plot: :param obj: painted object :param sel_obj: paint only what is inside this object bounds :param tooldia: a tuple or single element made out of diameters of the tools to be used @@ -2974,6 +2960,8 @@ class ToolPaint(FlatCAMTool, Gerber): """ Paints all polygons in this object that are within the sel_obj object + :param run_threaded: + :param plot: :param obj: painted object :param sel_obj: paint only what is inside this object bounds :param tooldia: a tuple or single element made out of diameters of the tools to be used From 6926b5be658bd4eb91c196e9617c3da8a1597e79 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 14 Feb 2020 05:07:11 +0200 Subject: [PATCH 093/209] - adjusted the UI for Excellon and Geometry objects --- README.md | 4 + flatcamGUI/ObjectUI.py | 250 ++++++++++++++++++++--------------------- 2 files changed, 129 insertions(+), 125 deletions(-) diff --git a/README.md b/README.md index 2fb1bf22..076452e3 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +14.02.2020 + +- adjusted the UI for Excellon and Geometry objects + 13.02.2020 - finished Punch Gerber Tool diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index 1bac450d..5a2f62c2 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -956,60 +956,6 @@ class ExcellonObjectUI(ObjectUI): self.grid3.addWidget(self.travelzlabel, 6, 0) self.grid3.addWidget(self.travelz_entry, 6, 1) - # Tool change: - self.toolchange_cb = FCCheckBox('%s:' % _("Tool change Z")) - self.toolchange_cb.setToolTip( - _("Include tool-change sequence\n" - "in G-Code (Pause for tool change).") - ) - - self.toolchangez_entry = FCDoubleSpinner(callback=self.confirmation_message) - self.toolchangez_entry.set_precision(self.decimals) - self.toolchangez_entry.setToolTip( - _("Z-axis position (height) for\n" - "tool change.") - ) - if machinist_setting == 0: - self.toolchangez_entry.set_range(0.0, 9999.9999) - else: - self.toolchangez_entry.set_range(-9999.9999, 9999.9999) - - self.toolchangez_entry.setSingleStep(0.1) - self.ois_tcz_e = OptionalInputSection(self.toolchange_cb, [self.toolchangez_entry]) - - self.grid3.addWidget(self.toolchange_cb, 8, 0) - self.grid3.addWidget(self.toolchangez_entry, 8, 1) - - # Start move Z: - self.estartz_label = QtWidgets.QLabel('%s:' % _("Start Z")) - self.estartz_label.setToolTip( - _("Height of the tool just after start.\n" - "Delete the value if you don't need this feature.") - ) - self.estartz_entry = FloatEntry() - - self.grid3.addWidget(self.estartz_label, 9, 0) - self.grid3.addWidget(self.estartz_entry, 9, 1) - - # End move Z: - self.endz_label = QtWidgets.QLabel('%s:' % _("End move Z")) - self.endz_label.setToolTip( - _("Height of the tool after\n" - "the last move at the end of the job.") - ) - self.endz_entry = FCDoubleSpinner(callback=self.confirmation_message) - self.endz_entry.set_precision(self.decimals) - - if machinist_setting == 0: - self.endz_entry.set_range(0.0, 9999.9999) - else: - self.endz_entry.set_range(-9999.9999, 9999.9999) - - self.endz_entry.setSingleStep(0.1) - - self.grid3.addWidget(self.endz_label, 11, 0) - self.grid3.addWidget(self.endz_entry, 11, 1) - # Feedrate X-Y self.frxylabel = QtWidgets.QLabel('%s:' % _('Feedrate X-Y')) self.frxylabel.setToolTip( @@ -1236,7 +1182,61 @@ class ExcellonObjectUI(ObjectUI): ) self.grid5.addWidget(self.gen_param_label, 3, 0, 1, 2) - # preprocessor selection + # Tool change Z: + self.toolchange_cb = FCCheckBox('%s:' % _("Tool change Z")) + self.toolchange_cb.setToolTip( + _("Include tool-change sequence\n" + "in G-Code (Pause for tool change).") + ) + + self.toolchangez_entry = FCDoubleSpinner(callback=self.confirmation_message) + self.toolchangez_entry.set_precision(self.decimals) + self.toolchangez_entry.setToolTip( + _("Z-axis position (height) for\n" + "tool change.") + ) + if machinist_setting == 0: + self.toolchangez_entry.set_range(0.0, 9999.9999) + else: + self.toolchangez_entry.set_range(-9999.9999, 9999.9999) + + self.toolchangez_entry.setSingleStep(0.1) + self.ois_tcz_e = OptionalInputSection(self.toolchange_cb, [self.toolchangez_entry]) + + self.grid5.addWidget(self.toolchange_cb, 8, 0) + self.grid5.addWidget(self.toolchangez_entry, 8, 1) + + # Start move Z: + self.estartz_label = QtWidgets.QLabel('%s:' % _("Start Z")) + self.estartz_label.setToolTip( + _("Height of the tool just after start.\n" + "Delete the value if you don't need this feature.") + ) + self.estartz_entry = FloatEntry() + + self.grid5.addWidget(self.estartz_label, 9, 0) + self.grid5.addWidget(self.estartz_entry, 9, 1) + + # End move Z: + self.endz_label = QtWidgets.QLabel('%s:' % _("End move Z")) + self.endz_label.setToolTip( + _("Height of the tool after\n" + "the last move at the end of the job.") + ) + self.endz_entry = FCDoubleSpinner(callback=self.confirmation_message) + self.endz_entry.set_precision(self.decimals) + + if machinist_setting == 0: + self.endz_entry.set_range(0.0, 9999.9999) + else: + self.endz_entry.set_range(-9999.9999, 9999.9999) + + self.endz_entry.setSingleStep(0.1) + + self.grid5.addWidget(self.endz_label, 11, 0) + self.grid5.addWidget(self.endz_entry, 11, 1) + + # Preprocessor selection pp_excellon_label = QtWidgets.QLabel('%s:' % _("Preprocessor")) pp_excellon_label.setToolTip( _("The preprocessor JSON file that dictates\n" @@ -1244,13 +1244,13 @@ class ExcellonObjectUI(ObjectUI): ) self.pp_excellon_name_cb = FCComboBox() self.pp_excellon_name_cb.setFocusPolicy(QtCore.Qt.StrongFocus) - self.grid5.addWidget(pp_excellon_label, 4, 0) - self.grid5.addWidget(self.pp_excellon_name_cb, 4, 1) + self.grid5.addWidget(pp_excellon_label, 12, 0) + self.grid5.addWidget(self.pp_excellon_name_cb, 12, 1) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - self.grid5.addWidget(separator_line, 5, 0, 1, 2) + self.grid5.addWidget(separator_line, 13, 0, 1, 2) # ################################################################# # ################# GRID LAYOUT 6 ############################### @@ -1708,64 +1708,6 @@ class GeometryObjectUI(ObjectUI): self.grid3.addWidget(self.travelzlabel, 5, 0) self.grid3.addWidget(self.travelz_entry, 5, 1) - # Tool change - self.toolchangeg_cb = FCCheckBox('%s:' % _("Tool change Z")) - self.toolchangeg_cb.setToolTip( - _( - "Include tool-change sequence\n" - "in the Machine Code (Pause for tool change)." - ) - ) - self.toolchangez_entry = FCDoubleSpinner(callback=self.confirmation_message) - self.toolchangez_entry.set_precision(self.decimals) - self.toolchangez_entry.setToolTip( - _( - "Z-axis position (height) for\n" - "tool change." - ) - ) - - if machinist_setting == 0: - self.toolchangez_entry.set_range(0, 9999.9999) - else: - self.toolchangez_entry.set_range(-9999.9999, 9999.9999) - - self.toolchangez_entry.setSingleStep(0.1) - self.ois_tcz_geo = OptionalInputSection(self.toolchangeg_cb, [self.toolchangez_entry]) - - self.grid3.addWidget(self.toolchangeg_cb, 6, 0) - self.grid3.addWidget(self.toolchangez_entry, 6, 1) - - # The Z value for the start move - # startzlabel = QtWidgets.QLabel('Start move Z:') - # startzlabel.setToolTip( - # "Tool height just before starting the work.\n" - # "Delete the value if you don't need this feature." - # - # ) - # self.grid3.addWidget(startzlabel, 8, 0) - # self.gstartz_entry = FloatEntry() - # self.grid3.addWidget(self.gstartz_entry, 8, 1) - - # The Z value for the end move - self.endz_label = QtWidgets.QLabel('%s:' % _('End move Z')) - self.endz_label.setToolTip( - _("Height of the tool after\n" - "the last move at the end of the job.") - ) - self.endz_entry = FCDoubleSpinner(callback=self.confirmation_message) - self.endz_entry.set_precision(self.decimals) - - if machinist_setting == 0: - self.endz_entry.set_range(0, 9999.9999) - else: - self.endz_entry.set_range(-9999.9999, 9999.9999) - - self.endz_entry.setSingleStep(0.1) - - self.grid3.addWidget(self.endz_label, 9, 0) - self.grid3.addWidget(self.endz_entry, 9, 1) - # Feedrate X-Y self.frlabel = QtWidgets.QLabel('%s:' % _('Feedrate X-Y')) self.frlabel.setToolTip( @@ -1941,6 +1883,64 @@ class GeometryObjectUI(ObjectUI): ) self.grid4.addWidget(self.gen_param_label, 3, 0, 1, 2) + # Tool change Z + self.toolchangeg_cb = FCCheckBox('%s:' % _("Tool change Z")) + self.toolchangeg_cb.setToolTip( + _( + "Include tool-change sequence\n" + "in the Machine Code (Pause for tool change)." + ) + ) + self.toolchangez_entry = FCDoubleSpinner(callback=self.confirmation_message) + self.toolchangez_entry.set_precision(self.decimals) + self.toolchangez_entry.setToolTip( + _( + "Z-axis position (height) for\n" + "tool change." + ) + ) + + if machinist_setting == 0: + self.toolchangez_entry.set_range(0, 9999.9999) + else: + self.toolchangez_entry.set_range(-9999.9999, 9999.9999) + + self.toolchangez_entry.setSingleStep(0.1) + self.ois_tcz_geo = OptionalInputSection(self.toolchangeg_cb, [self.toolchangez_entry]) + + self.grid4.addWidget(self.toolchangeg_cb, 6, 0) + self.grid4.addWidget(self.toolchangez_entry, 6, 1) + + # The Z value for the start move + # startzlabel = QtWidgets.QLabel('Start move Z:') + # startzlabel.setToolTip( + # "Tool height just before starting the work.\n" + # "Delete the value if you don't need this feature." + # + # ) + # self.grid3.addWidget(startzlabel, 8, 0) + # self.gstartz_entry = FloatEntry() + # self.grid3.addWidget(self.gstartz_entry, 8, 1) + + # The Z value for the end move + self.endz_label = QtWidgets.QLabel('%s:' % _('End move Z')) + self.endz_label.setToolTip( + _("Height of the tool after\n" + "the last move at the end of the job.") + ) + self.endz_entry = FCDoubleSpinner(callback=self.confirmation_message) + self.endz_entry.set_precision(self.decimals) + + if machinist_setting == 0: + self.endz_entry.set_range(0, 9999.9999) + else: + self.endz_entry.set_range(-9999.9999, 9999.9999) + + self.endz_entry.setSingleStep(0.1) + + self.grid4.addWidget(self.endz_label, 9, 0) + self.grid4.addWidget(self.endz_entry, 9, 1) + # preprocessor selection pp_label = QtWidgets.QLabel('%s:' % _("Preprocessor")) pp_label.setToolTip( @@ -1950,17 +1950,17 @@ class GeometryObjectUI(ObjectUI): self.pp_geometry_name_cb = FCComboBox() self.pp_geometry_name_cb.setFocusPolicy(QtCore.Qt.StrongFocus) - self.grid4.addWidget(pp_label, 4, 0) - self.grid4.addWidget(self.pp_geometry_name_cb, 4, 1) + self.grid4.addWidget(pp_label, 11, 0) + self.grid4.addWidget(self.pp_geometry_name_cb, 11, 1) - self.grid4.addWidget(QtWidgets.QLabel(''), 5, 0, 1, 2) + self.grid4.addWidget(QtWidgets.QLabel(''), 12, 0, 1, 2) warning_lbl = QtWidgets.QLabel( _( "Add / Select at least one tool in the tool-table.\n" "Click the # header to select all, or Ctrl + LMB\n" "for custom selection of tools." )) - self.grid4.addWidget(warning_lbl, 6, 0, 1, 2) + self.grid4.addWidget(warning_lbl, 13, 0, 1, 2) # Button self.generate_cnc_button = QtWidgets.QPushButton(_('Generate CNCJob object')) @@ -1973,9 +1973,9 @@ class GeometryObjectUI(ObjectUI): font-weight: bold; } """) - self.grid4.addWidget(self.generate_cnc_button, 7, 0, 1, 2) + self.grid4.addWidget(self.generate_cnc_button, 14, 0, 1, 2) - self.grid4.addWidget(QtWidgets.QLabel(''), 8, 0, 1, 2) + self.grid4.addWidget(QtWidgets.QLabel(''), 15, 0, 1, 2) # ############## # Paint area ## @@ -1984,7 +1984,7 @@ class GeometryObjectUI(ObjectUI): self.tools_label.setToolTip( _("Launch Paint Tool in Tools Tab.") ) - self.grid4.addWidget(self.tools_label, 10, 0, 1, 2) + self.grid4.addWidget(self.tools_label, 16, 0, 1, 2) # Paint Button self.paint_tool_button = QtWidgets.QPushButton(_('Paint Tool')) @@ -2002,7 +2002,7 @@ class GeometryObjectUI(ObjectUI): font-weight: bold; } """) - self.grid4.addWidget(self.paint_tool_button, 12, 0, 1, 2) + self.grid4.addWidget(self.paint_tool_button, 17, 0, 1, 2) # NCC Tool self.generate_ncc_button = QtWidgets.QPushButton(_('NCC Tool')) @@ -2016,7 +2016,7 @@ class GeometryObjectUI(ObjectUI): font-weight: bold; } """) - self.grid4.addWidget(self.generate_ncc_button, 13, 0, 1, 2) + self.grid4.addWidget(self.generate_ncc_button, 18, 0, 1, 2) class CNCObjectUI(ObjectUI): From 9fc2ba8ffdc085a73c3cd33c074c4f73ccaf0d62 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 14 Feb 2020 17:08:06 +0200 Subject: [PATCH 094/209] - added a new FlatCAM Tool: Gerber Invert Tool. It will invert the copper features in a Gerber file: where is copper there will be empty and where is empty it will be copper --- FlatCAMApp.py | 21 ++- FlatCAMObj.py | 25 +-- README.md | 1 + flatcamGUI/FlatCAMGUI.py | 2 + flatcamParsers/ParseGerber.py | 9 +- flatcamTools/ToolInvertGerber.py | 274 +++++++++++++++++++++++++++++++ flatcamTools/ToolPaint.py | 1 + flatcamTools/ToolPunchGerber.py | 10 +- flatcamTools/ToolSub.py | 6 +- flatcamTools/__init__.py | 2 + share/invert16.png | Bin 0 -> 245 bytes share/invert32.png | Bin 0 -> 374 bytes 12 files changed, 324 insertions(+), 27 deletions(-) create mode 100644 flatcamTools/ToolInvertGerber.py create mode 100644 share/invert16.png create mode 100644 share/invert32.png diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 7f3596e3..06ffbc72 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -14,7 +14,7 @@ import getopt import random import simplejson as json import lzma -import threading +# import threading import shutil import stat @@ -26,7 +26,7 @@ import ctypes from reportlab.graphics import renderPDF from reportlab.pdfgen import canvas -from reportlab.graphics import renderPM +# from reportlab.graphics import renderPM from reportlab.lib.units import inch, mm from reportlab.lib.pagesizes import landscape, portrait from svglib.svglib import svg2rlg @@ -39,9 +39,9 @@ from xml.dom.minidom import parseString as parse_xml_string from multiprocessing.connection import Listener, Client from multiprocessing import Pool import socket -from array import array +# from array import array -import vispy.scene as scene +# import vispy.scene as scene # ####################################### # # Imports part of FlatCAM ## @@ -1306,7 +1306,7 @@ class App(QtCore.QObject): # Excellon Options "excellon_drillz": self.ui.excellon_defaults_form.excellon_opt_group.cutz_entry, "excellon_multidepth": self.ui.excellon_defaults_form.excellon_opt_group.mpass_cb, - "excellon_depthperpass":self.ui.excellon_defaults_form.excellon_opt_group.maxdepth_entry, + "excellon_depthperpass": self.ui.excellon_defaults_form.excellon_opt_group.maxdepth_entry, "excellon_travelz": self.ui.excellon_defaults_form.excellon_opt_group.travelz_entry, "excellon_endz": self.ui.excellon_defaults_form.excellon_opt_group.endz_entry, "excellon_feedrate": self.ui.excellon_defaults_form.excellon_opt_group.feedrate_z_entry, @@ -2558,6 +2558,7 @@ class App(QtCore.QObject): self.edrills_tool = None self.align_objects_tool = None self.punch_tool = None + self.invert_tool = None # always install tools only after the shell is initialized because the self.inform.emit() depends on shell try: @@ -2724,6 +2725,8 @@ class App(QtCore.QObject): # this holds a widget that is installed in the Plot Area when View Source option is used self.source_editor_tab = None + self.pagesize = dict() + # Storage for shapes, storage that can be used by FlatCAm tools for utility geometry # VisPy visuals if self.is_legacy is False: @@ -3194,6 +3197,9 @@ class App(QtCore.QObject): self.punch_tool = ToolPunchGerber(self) self.punch_tool.install(icon=QtGui.QIcon(self.resource_location + '/punch32.png'), pos=self.ui.menutool) + self.invert_tool = ToolInvertGerber(self) + self.invert_tool.install(icon=QtGui.QIcon(self.resource_location + '/invert32.png'), pos=self.ui.menutool) + self.transform_tool = ToolTransform(self) self.transform_tool.install(icon=QtGui.QIcon(self.resource_location + '/transform.png'), pos=self.ui.menuoptions, separator=True) @@ -3338,6 +3344,7 @@ class App(QtCore.QObject): self.ui.copperfill_btn.triggered.connect(lambda: self.copper_thieving_tool.run(toggle=True)) self.ui.fiducials_btn.triggered.connect(lambda: self.fiducial_tool.run(toggle=True)) self.ui.punch_btn.triggered.connect(lambda: self.punch_tool.run(toggle=True)) + self.ui.invert_btn.triggered.connect(lambda: self.invert_tool.run(toggle=True)) def object2editor(self): """ @@ -8716,14 +8723,14 @@ class App(QtCore.QObject): else: event_pos = (event.xdata, event.ydata) # Matplotlib has the middle and right buttons mapped in reverse compared with VisPy - pan_button = 3 if self.defaults["global_pan_button"] == '2'else 2 + pan_button = 3 if self.defaults["global_pan_button"] == '2' else 2 # So it can receive key presses self.plotcanvas.native.setFocus() self.pos_canvas = self.plotcanvas.translate_coords(event_pos) - if self.grid_status() == True: + if self.grid_status(): self.pos = self.geo_editor.snap(self.pos_canvas[0], self.pos_canvas[1]) else: self.pos = (self.pos_canvas[0], self.pos_canvas[1]) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index e0534d7a..159cd1d5 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -2164,14 +2164,17 @@ class FlatCAMGerber(FlatCAMObj, Gerber): gerber_code += 'D02*\n' gerber_code += 'G37*\n' gerber_code += '%LPD*%\n' + except Exception as e: + log.debug("FlatCAMObj.FlatCAMGerber.export_gerber() '0' aperture --> %s" % str(e)) - for apid in self.apertures: - if apid == '0': - continue - else: - gerber_code += 'D%s*\n' % str(apid) - if 'geometry' in self.apertures[apid]: - for geo_elem in self.apertures[apid]['geometry']: + for apid in self.apertures: + if apid == '0': + continue + else: + gerber_code += 'D%s*\n' % str(apid) + if 'geometry' in self.apertures[apid]: + for geo_elem in self.apertures[apid]['geometry']: + try: if 'follow' in geo_elem: geo = geo_elem['follow'] if not geo.is_empty: @@ -2212,7 +2215,10 @@ class FlatCAMGerber(FlatCAMObj, Gerber): prev_coord = coord # gerber_code += "D02*\n" + except Exception as e: + log.debug("FlatCAMObj.FlatCAMGerber.export_gerber() 'follow' --> %s" % str(e)) + try: if 'clear' in geo_elem: gerber_code += '%LPC*%\n' @@ -2256,9 +2262,8 @@ class FlatCAMGerber(FlatCAMObj, Gerber): prev_coord = coord # gerber_code += "D02*\n" gerber_code += '%LPD*%\n' - - except Exception as e: - log.debug("FlatCAMObj.FlatCAMGerber.export_gerber() --> %s" % str(e)) + except Exception as e: + log.debug("FlatCAMObj.FlatCAMGerber.export_gerber() 'clear' --> %s" % str(e)) if not self.apertures: log.debug("FlatCAMObj.FlatCAMGerber.export_gerber() --> Gerber Object is empty: no apertures.") diff --git a/README.md b/README.md index 076452e3..6ef6dff6 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 14.02.2020 - adjusted the UI for Excellon and Geometry objects +- added a new FlatCAM Tool: Gerber Invert Tool. It will invert the copper features in a Gerber file: where is copper there will be empty and where is empty it will be copper 13.02.2020 diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index b8154db7..82d55bcf 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -928,6 +928,8 @@ class FlatCAMGUI(QtWidgets.QMainWindow): QtGui.QIcon(self.app.resource_location + '/calibrate_32.png'), _("Calibration Tool")) self.punch_btn = self.toolbartools.addAction( QtGui.QIcon(self.app.resource_location + '/punch32.png'), _("Punch Gerber Tool")) + self.invert_btn = self.toolbartools.addAction( + QtGui.QIcon(self.app.resource_location + '/invert32.png'), _("Invert Gerber Tool")) # ######################################################################## # ########################## Excellon Editor Toolbar# #################### diff --git a/flatcamParsers/ParseGerber.py b/flatcamParsers/ParseGerber.py index 8acb3482..235521b4 100644 --- a/flatcamParsers/ParseGerber.py +++ b/flatcamParsers/ParseGerber.py @@ -1414,9 +1414,12 @@ class Gerber(Geometry): self.follow_geometry = follow_buffer # this treats the case when we are storing geometry as solids - - if len(poly_buffer) == 0 and len(self.solid_geometry) == 0: - log.error("Object is not Gerber file or empty. Aborting Object creation.") + try: + if len(poly_buffer) == 0 and len(self.solid_geometry) == 0: + log.error("Object is not Gerber file or empty. Aborting Object creation.") + return 'fail' + except TypeError as e: + log.error("Object is not Gerber file or empty. Aborting Object creation. %s" % str(e)) return 'fail' log.warning("Joining %d polygons." % len(poly_buffer)) diff --git a/flatcamTools/ToolInvertGerber.py b/flatcamTools/ToolInvertGerber.py new file mode 100644 index 00000000..8d96419e --- /dev/null +++ b/flatcamTools/ToolInvertGerber.py @@ -0,0 +1,274 @@ +# ########################################################## +# FlatCAM: 2D Post-processing for Manufacturing # +# File Author: Marius Adrian Stanciu (c) # +# Date: 2/14/2020 # +# MIT Licence # +# ########################################################## + +from PyQt5 import QtWidgets, QtCore + +from FlatCAMTool import FlatCAMTool +from flatcamGUI.GUIElements import FCButton, FCDoubleSpinner + +from shapely.geometry import Polygon, MultiPolygon, MultiLineString, LineString, box +from shapely.ops import cascaded_union + +import traceback +from copy import deepcopy +import time +import logging +import gettext +import FlatCAMTranslation as fcTranslate +import builtins + +fcTranslate.apply_language('strings') +if '_' not in builtins.__dict__: + _ = gettext.gettext + +log = logging.getLogger('base') + + +class ToolInvertGerber(FlatCAMTool): + + toolName = _("Invert Tool") + + def __init__(self, app): + self.app = app + self.decimals = self.app.decimals + + FlatCAMTool.__init__(self, app) + + self.tools_frame = QtWidgets.QFrame() + self.tools_frame.setContentsMargins(0, 0, 0, 0) + self.layout.addWidget(self.tools_frame) + self.tools_box = QtWidgets.QVBoxLayout() + self.tools_box.setContentsMargins(0, 0, 0, 0) + self.tools_frame.setLayout(self.tools_box) + + # Title + title_label = QtWidgets.QLabel("%s" % self.toolName) + title_label.setStyleSheet(""" + QLabel + { + font-size: 16px; + font-weight: bold; + } + """) + self.tools_box.addWidget(title_label) + + # Form Layout + grid0 = QtWidgets.QGridLayout() + grid0.setColumnStretch(0, 0) + grid0.setColumnStretch(1, 1) + self.tools_box.addLayout(grid0) + + grid0.addWidget(QtWidgets.QLabel(''), 0, 0, 1, 2) + + # Target Gerber Object + self.gerber_combo = QtWidgets.QComboBox() + self.gerber_combo.setModel(self.app.collection) + self.gerber_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) + self.gerber_combo.setCurrentIndex(1) + + self.gerber_label = QtWidgets.QLabel('%s:' % _("Gerber Object")) + self.gerber_label.setToolTip( + _("Gerber object that will be inverted.") + ) + + grid0.addWidget(self.gerber_label, 1, 0, 1, 2) + grid0.addWidget(self.gerber_combo, 2, 0, 1, 2) + + # Margin + self.margin_label = QtWidgets.QLabel('%s:' % _('Margin')) + self.margin_label.setToolTip( + _("Distance by which to avoid\n" + "the edges of the Gerber object.") + ) + self.margin_entry = FCDoubleSpinner() + self.margin_entry.set_precision(self.decimals) + self.margin_entry.set_range(0.0000, 9999.9999) + self.margin_entry.setObjectName(_("Margin")) + + grid0.addWidget(self.margin_label, 3, 0) + grid0.addWidget(self.margin_entry, 3, 1) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(separator_line, 4, 0, 1, 2) + + self.invert_btn = FCButton(_('Invert Gerber')) + self.invert_btn.setToolTip( + _("Will invert the Gerber object: areas that have copper\n" + "will be emty of copper and previous empty area will be\n" + "filled with copper.") + ) + self.invert_btn.setStyleSheet(""" + QPushButton + { + font-weight: bold; + } + """) + grid0.addWidget(self.invert_btn, 5, 0, 1, 2) + + self.tools_box.addStretch() + + # ## Reset Tool + self.reset_button = QtWidgets.QPushButton(_("Reset Tool")) + self.reset_button.setToolTip( + _("Will reset the tool parameters.") + ) + self.reset_button.setStyleSheet(""" + QPushButton + { + font-weight: bold; + } + """) + self.tools_box.addWidget(self.reset_button) + + self.invert_btn.clicked.connect(self.on_grb_invert) + self.reset_button.clicked.connect(self.set_tool_ui) + + def install(self, icon=None, separator=None, **kwargs): + FlatCAMTool.install(self, icon, separator, shortcut='', **kwargs) + + def run(self, toggle=True): + self.app.report_usage("ToolInvertGerber()") + log.debug("ToolInvertGerber() is running ...") + + if toggle: + # if the splitter is hidden, display it, else hide it but only if the current widget is the same + if self.app.ui.splitter.sizes()[0] == 0: + self.app.ui.splitter.setSizes([1, 1]) + else: + try: + if self.app.ui.tool_scroll_area.widget().objectName() == self.toolName: + # if tab is populated with the tool but it does not have the focus, focus on it + if not self.app.ui.notebook.currentWidget() is self.app.ui.tool_tab: + # focus on Tool Tab + self.app.ui.notebook.setCurrentWidget(self.app.ui.tool_tab) + else: + self.app.ui.splitter.setSizes([0, 1]) + except AttributeError: + pass + else: + if self.app.ui.splitter.sizes()[0] == 0: + self.app.ui.splitter.setSizes([1, 1]) + + FlatCAMTool.run(self) + self.set_tool_ui() + + self.app.ui.notebook.setTabText(2, _("Invert Tool")) + + def set_tool_ui(self): + self.margin_entry.set_value(0.0) + + def on_grb_invert(self): + margin = self.margin_entry.get_value() + if round(margin, self.decimals) == 0.0: + margin = 1E-10 + + grb_circle_steps = int(self.app.defaults["gerber_circle_steps"]) + obj_name = self.gerber_combo.currentText() + + outname = obj_name + "_inverted" + + # Get source object. + try: + grb_obj = self.app.collection.get_by_name(obj_name) + except Exception as e: + self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), str(obj_name))) + return "Could not retrieve object: %s with error: %s" % (obj_name, str(e)) + + if grb_obj is None: + self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Object not found"), str(obj_name))) + return + + xmin, ymin, xmax, ymax = grb_obj.bounds() + + grb_box = box(xmin, ymin, xmax, ymax).buffer(margin, resolution=grb_circle_steps, join_style=2) + + try: + __ = iter(grb_obj.solid_geometry) + except TypeError: + grb_obj.solid_geometry = list(grb_obj.solid_geometry) + + new_solid_geometry = deepcopy(grb_box) + + for poly in grb_obj.solid_geometry: + new_solid_geometry = new_solid_geometry.difference(poly) + + new_options = dict() + for opt in grb_obj.options: + new_options[opt] = deepcopy(grb_obj.options[opt]) + + new_apertures = dict() + + # for apid, val in grb_obj.apertures.items(): + # new_apertures[apid] = dict() + # for key in val: + # if key == 'geometry': + # new_apertures[apid]['geometry'] = list() + # for elem in val['geometry']: + # geo_elem = dict() + # if 'follow' in elem: + # try: + # geo_elem['clear'] = elem['follow'].buffer(val['size'] / 2.0).exterior + # except AttributeError: + # # TODO should test if width or height is bigger + # geo_elem['clear'] = elem['follow'].buffer(val['width'] / 2.0).exterior + # if 'clear' in elem: + # if isinstance(elem['clear'], Polygon): + # try: + # geo_elem['solid'] = elem['clear'].buffer(val['size'] / 2.0, grb_circle_steps) + # except AttributeError: + # # TODO should test if width or height is bigger + # geo_elem['solid'] = elem['clear'].buffer(val['width'] / 2.0, grb_circle_steps) + # else: + # geo_elem['follow'] = elem['clear'] + # new_apertures[apid]['geometry'].append(deepcopy(geo_elem)) + # else: + # new_apertures[apid][key] = deepcopy(val[key]) + + if '0' not in new_apertures: + new_apertures['0'] = dict() + new_apertures['0']['type'] = 'C' + new_apertures['0']['size'] = 0.0 + new_apertures['0']['geometry'] = list() + + try: + for poly in new_solid_geometry: + new_el = dict() + new_el['solid'] = poly + new_el['follow'] = poly.exterior + new_apertures['0']['geometry'].append(new_el) + except TypeError: + new_el = dict() + new_el['solid'] = new_solid_geometry + new_el['follow'] = new_solid_geometry.exterior + new_apertures['0']['geometry'].append(new_el) + + for td in new_apertures: + print(td, new_apertures[td]) + + def init_func(new_obj, app_obj): + new_obj.options.update(new_options) + new_obj.options['name'] = outname + new_obj.fill_color = deepcopy(grb_obj.fill_color) + new_obj.outline_color = deepcopy(grb_obj.outline_color) + + new_obj.apertures = deepcopy(new_apertures) + + new_obj.solid_geometry = deepcopy(new_solid_geometry) + new_obj.source_file = self.app.export_gerber(obj_name=outname, filename=None, + local_use=new_obj, use_thread=False) + + self.app.new_object('gerber', outname, init_func) + + def reset_fields(self): + self.gerber_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) + + @staticmethod + def poly2rings(poly): + return [poly.exterior] + [interior for interior in poly.interiors] +# end of file diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 5d9780f3..d0a945a1 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -358,6 +358,7 @@ class ToolPaint(FlatCAMTool, Gerber): ) self.paintmargin_entry = FCDoubleSpinner() self.paintmargin_entry.set_precision(self.decimals) + self.paintmargin_entry.set_range(-9999.9999, 9999.9999) self.paintmargin_entry.setObjectName(_("Margin")) grid4.addWidget(marginlabel, 2, 0) diff --git a/flatcamTools/ToolPunchGerber.py b/flatcamTools/ToolPunchGerber.py index f7378933..2a5d8ef4 100644 --- a/flatcamTools/ToolPunchGerber.py +++ b/flatcamTools/ToolPunchGerber.py @@ -515,6 +515,8 @@ class ToolPunchGerber(FlatCAMTool): punch_method = self.method_punch.get_value() + new_options = deepcopy(grb_obj.options) + if punch_method == 'exc': # get the Excellon file whose geometry will create the punch holes @@ -574,7 +576,7 @@ class ToolPunchGerber(FlatCAMTool): new_apertures[str(new_apid)] = deepcopy(ap_val) def init_func(new_obj, app_obj): - new_obj.options.update(grb_obj.options) + new_obj.options.update(new_options) new_obj.options['name'] = outname new_obj.fill_color = deepcopy(grb_obj.fill_color) new_obj.outline_color = deepcopy(grb_obj.outline_color) @@ -688,7 +690,7 @@ class ToolPunchGerber(FlatCAMTool): new_apertures[str(new_apid)] = deepcopy(ap_val) def init_func(new_obj, app_obj): - new_obj.options.update(grb_obj.options) + new_obj.options.update(new_options) new_obj.options['name'] = outname new_obj.fill_color = deepcopy(grb_obj.fill_color) new_obj.outline_color = deepcopy(grb_obj.outline_color) @@ -830,7 +832,7 @@ class ToolPunchGerber(FlatCAMTool): new_apertures[str(new_apid)] = deepcopy(ap_val) def init_func(new_obj, app_obj): - new_obj.options.update(grb_obj.options) + new_obj.options.update(new_options) new_obj.options['name'] = outname new_obj.fill_color = deepcopy(grb_obj.fill_color) new_obj.outline_color = deepcopy(grb_obj.outline_color) @@ -969,7 +971,7 @@ class ToolPunchGerber(FlatCAMTool): new_apertures[str(new_apid)] = deepcopy(ap_val) def init_func(new_obj, app_obj): - new_obj.options.update(grb_obj.options) + new_obj.options.update(new_options) new_obj.options['name'] = outname new_obj.fill_color = deepcopy(grb_obj.fill_color) new_obj.outline_color = deepcopy(grb_obj.outline_color) diff --git a/flatcamTools/ToolSub.py b/flatcamTools/ToolSub.py index 37d47ed3..99cc9fa8 100644 --- a/flatcamTools/ToolSub.py +++ b/flatcamTools/ToolSub.py @@ -254,14 +254,14 @@ class ToolSub(FlatCAMTool): FlatCAMTool.run(self) self.set_tool_ui() + self.app.ui.notebook.setTabText(2, _("Sub Tool")) + + def set_tool_ui(self): self.new_apertures.clear() self.new_tools.clear() self.new_solid_geometry = [] self.target_options.clear() - self.app.ui.notebook.setTabText(2, _("Sub Tool")) - - def set_tool_ui(self): self.tools_frame.show() self.close_paths_cb.setChecked(self.app.defaults["tools_sub_close_paths"]) diff --git a/flatcamTools/__init__.py b/flatcamTools/__init__.py index b503ca38..74d1aff5 100644 --- a/flatcamTools/__init__.py +++ b/flatcamTools/__init__.py @@ -39,3 +39,5 @@ from flatcamTools.ToolSub import ToolSub from flatcamTools.ToolTransform import ToolTransform from flatcamTools.ToolPunchGerber import ToolPunchGerber + +from flatcamTools.ToolInvertGerber import ToolInvertGerber diff --git a/share/invert16.png b/share/invert16.png new file mode 100644 index 0000000000000000000000000000000000000000..4246eb5b0a8459c7172e6512f08440d96671b3ae GIT binary patch literal 245 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_uJY5_^ zEP9VlGUPjCz~d?}>aBOtxrAw@d%{{Pr9#0&HziITImWZR!BBRVhrIT}Ajzzglahbm zzP~Xs_hyIew1m~HzU;L*^(u7@)mx+wFp585d{f+@P{o|pdG&zhE!oyW;UBpN800G4 z#5S|8lPu`ky3OI8aH(@YbX^qpJazoTB<9Xi5 p^7vH0>-n$n&5yZ${-<9?O#d(FW*f>~od9$-gQu&X%Q~loCII{8TloM0 literal 0 HcmV?d00001 diff --git a/share/invert32.png b/share/invert32.png new file mode 100644 index 0000000000000000000000000000000000000000..76e19dff2e2d182b32a97eb7d2b1bb3e041e61b0 GIT binary patch literal 374 zcmV-+0g3*JP)lcCXnS4)^n@9EjD*{o9c0ysSqzyMz%32DTU z*frPATux76oB7oi*Z@2GJpkT-p%b&PBUrv29e@e)?P&p1;7C?>SEUsQ0XP67MScQw z>j0Q2a*d5$#Rm96F1uu&0%x*wQ3;^EhM!V$!8~!k+rU_}uohq+V1Ct0On|cTmzjg| ze`^7Hf#&enBZ4Iz!Y%nKn36d65cZw;DA#bRG*5x|!kSS4t{tw*{2S=h0bs~F+={Hk zQrSNQ^C$qO5Hkekz|xKx`Nk6!z<1KMx)~sbxfj6qC_NGQlJV#jc$PeyS8=087lwGZ U0(5>a?f?J)07*qoM6N<$f)N>><^TWy literal 0 HcmV?d00001 From 49c82a3e3353ca941764a178503592de275e21fa Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 15 Feb 2020 03:41:11 +0200 Subject: [PATCH 095/209] - added the Preferences entries for the Gerber Invert Tool --- FlatCAMApp.py | 8 +++++ README.md | 1 + flatcamGUI/PreferencesUI.py | 60 ++++++++++++++++++++++++++++++++ flatcamTools/ToolInvertGerber.py | 59 +++++++++++++++++++++++-------- flatcamTools/ToolPunchGerber.py | 4 ++- 5 files changed, 116 insertions(+), 16 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 06ffbc72..3574dcfa 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -1002,6 +1002,10 @@ class App(QtCore.QObject): # Align Objects Tool "tools_align_objects_align_type": 'sp', + # Invert Gerber Tool + "tools_invert_margin": 0.1, + "tools_invert_join_style": 's', + # Utilities # file associations "fa_excellon": 'drd, drl, exc, ncd, tap, xln', @@ -1666,6 +1670,10 @@ class App(QtCore.QObject): "tools_punch_rectangular": self.ui.tools2_defaults_form.tools2_punch_group.rectangular_cb, "tools_punch_others": self.ui.tools2_defaults_form.tools2_punch_group.other_cb, + # Invert Gerber Tool + "tools_invert_margin": self.ui.tools2_defaults_form.tools2_invert_group.margin_entry, + "tools_invert_join_style": self.ui.tools2_defaults_form.tools2_invert_group.join_radio, + # Utilities # File associations "fa_excellon": self.ui.util_defaults_form.fa_excellon_group.exc_list_text, diff --git a/README.md b/README.md index 6ef6dff6..374c683c 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ CAD program, and create G-Code for Isolation routing. - adjusted the UI for Excellon and Geometry objects - added a new FlatCAM Tool: Gerber Invert Tool. It will invert the copper features in a Gerber file: where is copper there will be empty and where is empty it will be copper +- added the Preferences entries for the Gerber Invert Tool 13.02.2020 diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index eeeb413a..df1c0021 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -252,6 +252,9 @@ class Tools2PreferencesUI(QtWidgets.QWidget): self.tools2_punch_group = Tools2PunchGerberPrefGroupUI(decimals=self.decimals) self.tools2_punch_group.setMinimumWidth(220) + self.tools2_invert_group = Tools2InvertPrefGroupUI(decimals=self.decimals) + self.tools2_invert_group.setMinimumWidth(220) + self.vlay = QtWidgets.QVBoxLayout() self.vlay.addWidget(self.tools2_checkrules_group) self.vlay.addWidget(self.tools2_optimal_group) @@ -269,6 +272,7 @@ class Tools2PreferencesUI(QtWidgets.QWidget): self.vlay4 = QtWidgets.QVBoxLayout() self.vlay4.addWidget(self.tools2_punch_group) + self.vlay4.addWidget(self.tools2_invert_group) self.layout.addLayout(self.vlay) self.layout.addLayout(self.vlay1) @@ -8239,6 +8243,62 @@ class Tools2PunchGerberPrefGroupUI(OptionsGroupUI): self.layout.addStretch() +class Tools2InvertPrefGroupUI(OptionsGroupUI): + def __init__(self, decimals=4, parent=None): + + super(Tools2InvertPrefGroupUI, self).__init__(self) + + self.setTitle(str(_("Invert Gerber Tool Options"))) + self.decimals = decimals + + # ## Subtractor Tool Parameters + self.sublabel = QtWidgets.QLabel("%s:" % _("Parameters")) + self.sublabel.setToolTip( + _("A tool to invert Gerber geometry from positive to negative\n" + "and in revers.") + ) + self.layout.addWidget(self.sublabel) + + # Grid Layout + grid0 = QtWidgets.QGridLayout() + grid0.setColumnStretch(0, 0) + grid0.setColumnStretch(1, 1) + self.layout.addLayout(grid0) + + # Margin + self.margin_label = QtWidgets.QLabel('%s:' % _('Margin')) + self.margin_label.setToolTip( + _("Distance by which to avoid\n" + "the edges of the Gerber object.") + ) + self.margin_entry = FCDoubleSpinner() + self.margin_entry.set_precision(self.decimals) + self.margin_entry.set_range(0.0000, 9999.9999) + self.margin_entry.setObjectName(_("Margin")) + + grid0.addWidget(self.margin_label, 2, 0, 1, 2) + grid0.addWidget(self.margin_entry, 3, 0, 1, 2) + + self.join_label = QtWidgets.QLabel('%s:' % _("Lines Join Style")) + self.join_label.setToolTip( + _("The way that the lines in the object outline will be joined.\n" + "Can be:\n" + "- rounded -> an arc is added between two joining lines\n" + "- square -> the lines meet in 90 degrees angle\n" + "- bevel -> the lines are joined by a third line") + ) + self.join_radio = RadioSet([ + {'label': 'Rounded', 'value': 'r'}, + {'label': 'Square', 'value': 's'}, + {'label': 'Bevel', 'value': 'b'} + ], orientation='vertical', stretch=False) + + grid0.addWidget(self.join_label, 5, 0, 1, 2) + grid0.addWidget(self.join_radio, 7, 0, 1, 2) + + self.layout.addStretch() + + class FAExcPrefGroupUI(OptionsGroupUI): def __init__(self, decimals=4, parent=None): # OptionsGroupUI.__init__(self, "Excellon File associations Preferences", parent=None) diff --git a/flatcamTools/ToolInvertGerber.py b/flatcamTools/ToolInvertGerber.py index 8d96419e..df1af676 100644 --- a/flatcamTools/ToolInvertGerber.py +++ b/flatcamTools/ToolInvertGerber.py @@ -8,14 +8,12 @@ from PyQt5 import QtWidgets, QtCore from FlatCAMTool import FlatCAMTool -from flatcamGUI.GUIElements import FCButton, FCDoubleSpinner +from flatcamGUI.GUIElements import FCButton, FCDoubleSpinner, RadioSet -from shapely.geometry import Polygon, MultiPolygon, MultiLineString, LineString, box -from shapely.ops import cascaded_union +from shapely.geometry import box -import traceback from copy import deepcopy -import time + import logging import gettext import FlatCAMTranslation as fcTranslate @@ -30,7 +28,7 @@ log = logging.getLogger('base') class ToolInvertGerber(FlatCAMTool): - toolName = _("Invert Tool") + toolName = _("Invert Gerber Tool") def __init__(self, app): self.app = app @@ -56,7 +54,7 @@ class ToolInvertGerber(FlatCAMTool): """) self.tools_box.addWidget(title_label) - # Form Layout + # Grid Layout grid0 = QtWidgets.QGridLayout() grid0.setColumnStretch(0, 0) grid0.setColumnStretch(1, 1) @@ -70,7 +68,7 @@ class ToolInvertGerber(FlatCAMTool): self.gerber_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.gerber_combo.setCurrentIndex(1) - self.gerber_label = QtWidgets.QLabel('%s:' % _("Gerber Object")) + self.gerber_label = QtWidgets.QLabel('%s:' % _("GERBER")) self.gerber_label.setToolTip( _("Gerber object that will be inverted.") ) @@ -78,6 +76,13 @@ class ToolInvertGerber(FlatCAMTool): grid0.addWidget(self.gerber_label, 1, 0, 1, 2) grid0.addWidget(self.gerber_combo, 2, 0, 1, 2) + grid0.addWidget(QtWidgets.QLabel(""), 3, 0, 1, 2) + + self.param_label = QtWidgets.QLabel("%s:" % _("Parameters")) + self.param_label.setToolTip('%s.' % _("Parameters for this tool")) + + grid0.addWidget(self.param_label, 4, 0, 1, 2) + # Margin self.margin_label = QtWidgets.QLabel('%s:' % _('Margin')) self.margin_label.setToolTip( @@ -89,18 +94,35 @@ class ToolInvertGerber(FlatCAMTool): self.margin_entry.set_range(0.0000, 9999.9999) self.margin_entry.setObjectName(_("Margin")) - grid0.addWidget(self.margin_label, 3, 0) - grid0.addWidget(self.margin_entry, 3, 1) + grid0.addWidget(self.margin_label, 5, 0, 1, 2) + grid0.addWidget(self.margin_entry, 6, 0, 1, 2) + + self.join_label = QtWidgets.QLabel('%s:' % _("Lines Join Style")) + self.join_label.setToolTip( + _("The way that the lines in the object outline will be joined.\n" + "Can be:\n" + "- rounded -> an arc is added between two joining lines\n" + "- square -> the lines meet in 90 degrees angle\n" + "- bevel -> the lines are joined by a third line") + ) + self.join_radio = RadioSet([ + {'label': 'Rounded', 'value': 'r'}, + {'label': 'Square', 'value': 's'}, + {'label': 'Bevel', 'value': 'b'} + ], orientation='vertical', stretch=False) + + grid0.addWidget(self.join_label, 7, 0, 1, 2) + grid0.addWidget(self.join_radio, 8, 0, 1, 2) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - grid0.addWidget(separator_line, 4, 0, 1, 2) + grid0.addWidget(separator_line, 9, 0, 1, 2) self.invert_btn = FCButton(_('Invert Gerber')) self.invert_btn.setToolTip( _("Will invert the Gerber object: areas that have copper\n" - "will be emty of copper and previous empty area will be\n" + "will be empty of copper and previous empty area will be\n" "filled with copper.") ) self.invert_btn.setStyleSheet(""" @@ -109,7 +131,7 @@ class ToolInvertGerber(FlatCAMTool): font-weight: bold; } """) - grid0.addWidget(self.invert_btn, 5, 0, 1, 2) + grid0.addWidget(self.invert_btn, 10, 0, 1, 2) self.tools_box.addStretch() @@ -161,13 +183,18 @@ class ToolInvertGerber(FlatCAMTool): self.app.ui.notebook.setTabText(2, _("Invert Tool")) def set_tool_ui(self): - self.margin_entry.set_value(0.0) + self.margin_entry.set_value(float(self.app.defaults["tools_invert_margin"])) + self.join_radio.set_value(self.app.defaults["tools_invert_join_style"]) def on_grb_invert(self): margin = self.margin_entry.get_value() if round(margin, self.decimals) == 0.0: margin = 1E-10 + join_style = {'r': 1, 'b': 3, 's': 2}[self.join_radio.get_value()] + if join_style is None: + join_style = 'r' + grb_circle_steps = int(self.app.defaults["gerber_circle_steps"]) obj_name = self.gerber_combo.currentText() @@ -181,12 +208,14 @@ class ToolInvertGerber(FlatCAMTool): return "Could not retrieve object: %s with error: %s" % (obj_name, str(e)) if grb_obj is None: + if obj_name == '': + obj_name = 'None' self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Object not found"), str(obj_name))) return xmin, ymin, xmax, ymax = grb_obj.bounds() - grb_box = box(xmin, ymin, xmax, ymax).buffer(margin, resolution=grb_circle_steps, join_style=2) + grb_box = box(xmin, ymin, xmax, ymax).buffer(margin, resolution=grb_circle_steps, join_style=join_style) try: __ = iter(grb_obj.solid_geometry) diff --git a/flatcamTools/ToolPunchGerber.py b/flatcamTools/ToolPunchGerber.py index 2a5d8ef4..282c20d4 100644 --- a/flatcamTools/ToolPunchGerber.py +++ b/flatcamTools/ToolPunchGerber.py @@ -515,7 +515,9 @@ class ToolPunchGerber(FlatCAMTool): punch_method = self.method_punch.get_value() - new_options = deepcopy(grb_obj.options) + new_options = dict() + for opt in grb_obj.options: + new_options[opt] = deepcopy(grb_obj.options[opt]) if punch_method == 'exc': From d24290a2b6fcf648152140cf19d964356ea06cac Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 15 Feb 2020 06:23:39 +0200 Subject: [PATCH 096/209] - in Paint Tool added a new method of painting named Combo who will pass through all the methods until the polygon is cleared - in Paint Tool attempting to add a new mode suitable for Laser usage --- README.md | 5 + flatcamTools/ToolPaint.py | 326 +++++++++++++++++++++++++++++++++++--- 2 files changed, 308 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 374c683c..f9eca5f7 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,11 @@ CAD program, and create G-Code for Isolation routing. ================================================= +15.02.2020 + +- in Paint Tool added a new method of painting named Combo who will pass through all the methods until the polygon is cleared +- in Paint Tool attempting to add a new mode suitable for Laser usage + 14.02.2020 - adjusted the UI for Excellon and Geometry objects diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index d0a945a1..57a2cc43 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -17,7 +17,7 @@ from camlib import Geometry from flatcamGUI.GUIElements import FCTable, FCDoubleSpinner, FCCheckBox, FCInputDialog, RadioSet, FCButton import FlatCAMApp -from shapely.geometry import base, Polygon, MultiPolygon, LinearRing +from shapely.geometry import base, Polygon, MultiPolygon, LinearRing, Point from shapely.ops import cascaded_union import numpy as np @@ -370,17 +370,27 @@ class ToolPaint(FlatCAMTool, Gerber): _("Algorithm for painting:\n" "- Standard: Fixed step inwards.\n" "- Seed-based: Outwards from seed.\n" - "- Line-based: Parallel lines.") + "- Line-based: Parallel lines.\n" + "- Laser-lines: Active only when Laser Mode is active and only for Gerber objects.\n" + "Will create lines that follow the traces.\n" + "- Combo: In case of failure a new method will be picked from the above\n" + "in the order specified.") ) self.paintmethod_combo = RadioSet([ {"label": _("Standard"), "value": "standard"}, {"label": _("Seed-based"), "value": "seed"}, - {"label": _("Straight lines"), "value": "lines"} + {"label": _("Straight lines"), "value": "lines"}, + {"label": _("Laser lines"), "value": "laser_lines"}, + {"label": _("Combo"), "value": "combo"} ], orientation='vertical', stretch=False) self.paintmethod_combo.setObjectName(_("Method")) - grid4.addWidget(methodlabel, 3, 0) - grid4.addWidget(self.paintmethod_combo, 3, 1) + for choice in self.paintmethod_combo.choices: + if choice['value'] == "laser_lines": + choice["radio"].setEnabled(False) + + grid4.addWidget(methodlabel, 7, 0) + grid4.addWidget(self.paintmethod_combo, 7, 1) # Connect lines self.pathconnect_cb = FCCheckBox('%s' % _("Connect")) @@ -397,32 +407,32 @@ class ToolPaint(FlatCAMTool, Gerber): "to trim rough edges.") ) - grid4.addWidget(self.pathconnect_cb, 4, 0) - grid4.addWidget(self.paintcontour_cb, 4, 1) + grid4.addWidget(self.pathconnect_cb, 10, 0) + grid4.addWidget(self.paintcontour_cb, 10, 1) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - grid4.addWidget(separator_line, 5, 0, 1, 2) + grid4.addWidget(separator_line, 11, 0, 1, 2) self.apply_param_to_all = FCButton(_("Apply parameters to all tools")) self.apply_param_to_all.setToolTip( _("The parameters in the current form will be applied\n" "on all the tools from the Tool Table.") ) - grid4.addWidget(self.apply_param_to_all, 7, 0, 1, 2) + grid4.addWidget(self.apply_param_to_all, 12, 0, 1, 2) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - grid4.addWidget(separator_line, 8, 0, 1, 2) + grid4.addWidget(separator_line, 13, 0, 1, 2) # General Parameters self.gen_param_label = QtWidgets.QLabel('%s' % _("Common Parameters")) self.gen_param_label.setToolTip( _("Parameters that are common for all tools.") ) - grid4.addWidget(self.gen_param_label, 10, 0, 1, 2) + grid4.addWidget(self.gen_param_label, 15, 0, 1, 2) self.rest_cb = FCCheckBox('%s' % _("Rest Machining")) self.rest_cb.setObjectName(_("Rest Machining")) @@ -435,7 +445,17 @@ class ToolPaint(FlatCAMTool, Gerber): "no more copper to clear or there are no more tools.\n\n" "If not checked, use the standard algorithm.") ) - grid4.addWidget(self.rest_cb, 11, 0, 1, 2) + grid4.addWidget(self.rest_cb, 16, 0, 1, 2) + + + # Laser Mode + self.laser_cb = FCCheckBox(_("Laser Mode")) + self.laser_cb.setToolTip( + _("This control is enabled only for Gerber objects.\n" + "If checked then a new method is shown in Methods,\n" + "and it is also added to the Combo Method sequence.") + ) + grid4.addWidget(self.laser_cb, 17, 0, 1, 2) # Polygon selection selectlabel = QtWidgets.QLabel('%s:' % _('Selection')) @@ -467,11 +487,11 @@ class ToolPaint(FlatCAMTool, Gerber): "specified by another object.") ) - grid4.addWidget(selectlabel, 13, 0, 1, 2) - grid4.addWidget(self.selectmethod_combo, 14, 0, 1, 2) + grid4.addWidget(selectlabel, 18, 0, 1, 2) + grid4.addWidget(self.selectmethod_combo, 19, 0, 1, 2) form1 = QtWidgets.QFormLayout() - grid4.addLayout(form1, 15, 0, 1, 2) + grid4.addLayout(form1, 20, 0, 1, 2) self.box_combo_type_label = QtWidgets.QLabel('%s:' % _("Ref. Type")) self.box_combo_type_label.setToolTip( @@ -617,6 +637,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.box_combo_type.currentIndexChanged.connect(self.on_combo_box_type) self.type_obj_combo.currentIndexChanged.connect(self.on_type_obj_index_changed) + self.laser_cb.stateChanged.connect(self.on_laser_mode_toggled) self.reset_button.clicked.connect(self.set_tool_ui) # ############################################################################# @@ -640,6 +661,21 @@ class ToolPaint(FlatCAMTool, Gerber): self.obj_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) self.obj_combo.setCurrentIndex(0) + if self.type_obj_combo.currentText().lower() == 'gerber': + self.laser_cb.setEnabled(True) + else: + self.laser_cb.setEnabled(False) + + def on_laser_mode_toggled(self, val): + for choice in self.paintmethod_combo.choices: + if choice['value'] == "laser_lines": + if val: + choice["radio"].setEnabled(True) + else: + choice["radio"].setEnabled(False) + if self.paintmethod_combo.get_value() == "laser_lines": + self.paintmethod_combo.set_value('lines') + def install(self, icon=None, separator=None, **kwargs): FlatCAMTool.install(self, icon, separator, shortcut='ALT+P', **kwargs) @@ -938,6 +974,10 @@ class ToolPaint(FlatCAMTool, Gerber): # make the default object type, "Geometry" self.type_obj_combo.setCurrentIndex(2) + + # make the Laser Mode disabled because the Geometry object is default + self.laser_cb.setEnabled(False) + # updated units self.units = self.app.defaults['units'].upper() @@ -1486,6 +1526,7 @@ class ToolPaint(FlatCAMTool, Gerber): if self.poly_dict: poly_list = deepcopy(list(self.poly_dict.values())) self.paint_poly(self.paint_obj, + inside_pt=(curr_pos[0], curr_pos[1]), poly_list=poly_list, tooldia=self.tooldia_list, overlap=self.overlap, @@ -1746,7 +1787,7 @@ class ToolPaint(FlatCAMTool, Gerber): connect=conn, prog_plot=prog_plot) - else: + elif paint_method == "standard": # Type(cp) == FlatCAMRTreeStorage | None cpoly = self.clear_polygon(polyg, tooldia=tooldiameter, @@ -1755,12 +1796,73 @@ class ToolPaint(FlatCAMTool, Gerber): contour=cont, connect=conn, prog_plot=prog_plot) + elif paint_method == "laser_lines": + line = None + aperture_size = None + + # determine the Gerber follow line + for apid, apval in obj.apertures.items(): + for geo_el in apval['geometry']: + if 'solid' in geo_el: + if Point(inside_pt).within(geo_el['solid']): + if not isinstance(geo_el['follow'], Point): + line = geo_el['follow'] + + if apval['type'] == 'C': + aperture_size = apval['size'] + else: + if apval['width'] > apval['height']: + aperture_size = apval['height'] + else: + aperture_size = apval['width'] + print(line, aperture_size) + if line: + cpoly = self.fill_with_lines(line, aperture_size, + tooldia=tooldiameter, + steps_per_circle=self.app.defaults["geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + + elif paint_method == "combo": + self.app.inform.emit(_("Painting polygon with method: lines.")) + cpoly = self.clear_polygon3(polyg, + tooldia=tooldiameter, + steps_per_circle=self.app.defaults["geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + + if cpoly and cpoly.objects: + pass + else: + self.app.inform.emit(_("Failed. Painting polygon with method: seed.")) + cpoly = self.clear_polygon2(polyg, + tooldia=tooldiameter, + steps_per_circle=self.app.defaults["geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + if cpoly and cpoly.objects: + pass + else: + self.app.inform.emit(_("Failed. Painting polygon with method: standard.")) + cpoly = self.clear_polygon(polyg, + tooldia=tooldiameter, + steps_per_circle=self.app.defaults["geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) except FlatCAMApp.GracefulException: return "fail" except Exception as ee: log.debug("ToolPaint.paint_poly().gen_paintarea().paint_p() --> %s" % str(ee)) - if cpoly is not None: + if cpoly and cpoly.objects: geo_obj.solid_geometry += list(cpoly.get_objects()) return cpoly else: @@ -2095,6 +2197,7 @@ class ToolPaint(FlatCAMTool, Gerber): try: for pol in poly_buf: if pol is not None and isinstance(pol, Polygon): + cp = None if paint_method == 'standard': cp = self.clear_polygon(pol, tooldia=tool_dia, @@ -2113,7 +2216,7 @@ class ToolPaint(FlatCAMTool, Gerber): contour=cont, connect=conn, prog_plot=prog_plot) - else: + elif paint_method == "standard": cp = self.clear_polygon3(pol, tooldia=tool_dia, steps_per_circle=self.app.defaults[ @@ -2122,7 +2225,44 @@ class ToolPaint(FlatCAMTool, Gerber): contour=cont, connect=conn, prog_plot=prog_plot) - if cp: + elif paint_method == "combo": + self.app.inform.emit(_("Painting polygons with method: lines.")) + cp = self.clear_polygon3(pol, + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + + if cp and cp.objects: + pass + else: + self.app.inform.emit(_("Failed. Painting polygons with method: seed.")) + cp = self.clear_polygon2(pol, + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + if cp and cp.objects: + pass + else: + self.app.inform.emit( + _("Failed. Painting polygons with method: standard.")) + + cp = self.clear_polygon(pol, + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + if cp and cp.objects: total_geometry += list(cp.get_objects()) poly_processed.append(True) else: @@ -2133,6 +2273,7 @@ class ToolPaint(FlatCAMTool, Gerber): "It is: %s" % str(type(pol))) except TypeError: if isinstance(poly_buf, Polygon): + cp = None if paint_method == 'standard': cp = self.clear_polygon(poly_buf, tooldia=tool_dia, @@ -2151,7 +2292,7 @@ class ToolPaint(FlatCAMTool, Gerber): contour=cont, connect=conn, prog_plot=prog_plot) - else: + elif paint_method == 'standard': cp = self.clear_polygon3(poly_buf, tooldia=tool_dia, steps_per_circle=self.app.defaults[ @@ -2160,6 +2301,41 @@ class ToolPaint(FlatCAMTool, Gerber): contour=cont, connect=conn, prog_plot=prog_plot) + elif paint_method == "combo": + self.app.inform.emit(_("Painting polygons with method: lines.")) + cp = self.clear_polygon3(poly_buf, + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + + if cp and cp.objects: + pass + else: + self.app.inform.emit(_("Failed. Painting polygons with method: seed.")) + cp = self.clear_polygon2(poly_buf, + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + if cp and cp.objects: + pass + else: + self.app.inform.emit(_("Failed. Painting polygons with method: standard.")) + cp = self.clear_polygon(poly_buf, + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) if cp: total_geometry += list(cp.get_objects()) poly_processed.append(True) @@ -2377,6 +2553,41 @@ class ToolPaint(FlatCAMTool, Gerber): steps_per_circle=self.app.defaults["geometry_circle_steps"], overlap=over, contour=cont, connect=conn, prog_plot=prog_plot) + elif paint_method == "combo": + self.app.inform.emit(_("Painting polygons with method: lines.")) + cp = self.clear_polygon3(poly_buf, + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + + if cp and cp.objects: + pass + else: + self.app.inform.emit(_("Failed. Painting polygons with method: seed.")) + cp = self.clear_polygon2(poly_buf, + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + if cp and cp.objects: + pass + else: + self.app.inform.emit(_("Failed. Painting polygons with method: standard.")) + cp = self.clear_polygon(poly_buf, + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) if cp is not None: cleared_geo += list(cp.get_objects()) @@ -2666,6 +2877,7 @@ class ToolPaint(FlatCAMTool, Gerber): continue poly_buf = geo.buffer(-paint_margin) + cp = None if paint_method == "seed": # Type(cp) == FlatCAMRTreeStorage | None cp = self.clear_polygon2(poly_buf, @@ -2686,7 +2898,7 @@ class ToolPaint(FlatCAMTool, Gerber): connect=conn, prog_plot=prog_plot) - else: + elif paint_method == 'standard': # Type(cp) == FlatCAMRTreeStorage | None cp = self.clear_polygon(poly_buf, tooldia=tool_dia, @@ -2695,8 +2907,42 @@ class ToolPaint(FlatCAMTool, Gerber): contour=cont, connect=conn, prog_plot=prog_plot) + elif paint_method == "combo": + self.app.inform.emit(_("Painting polygons with method: lines.")) + cp = self.clear_polygon3(poly_buf, + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) - if cp is not None: + if cp and cp.objects: + pass + else: + self.app.inform.emit(_("Failed. Painting polygons with method: seed.")) + cp = self.clear_polygon2(poly_buf, + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + if cp and cp.objects: + pass + else: + self.app.inform.emit(_("Failed. Painting polygons with method: standard.")) + cp = self.clear_polygon(poly_buf, + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + if cp and cp.objects: total_geometry += list(cp.get_objects()) except FlatCAMApp.GracefulException: return "fail" @@ -2855,8 +3101,42 @@ class ToolPaint(FlatCAMTool, Gerber): steps_per_circle=self.app.defaults["geometry_circle_steps"], overlap=over, contour=cont, connect=conn, prog_plot=prog_plot) + elif paint_method == "combo": + self.app.inform.emit(_("Painting polygons with method: lines.")) + cp = self.clear_polygon3(poly_buf, + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) - if cp is not None: + if cp and cp.objects: + pass + else: + self.app.inform.emit(_("Failed. Painting polygons with method: seed.")) + cp = self.clear_polygon2(poly_buf, + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + if cp and cp.objects: + pass + else: + self.app.inform.emit(_("Failed. Painting polygons with method: standard.")) + cp = self.clear_polygon(poly_buf, + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + if cp and cp.objects: cleared_geo += list(cp.get_objects()) except FlatCAMApp.GracefulException: return "fail" From 25c9a31179c5e5fe8c59b0deeedde47a9dec8186 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 15 Feb 2020 21:11:06 +0200 Subject: [PATCH 097/209] - more work in the new Laser Mode in the Paint Tool --- README.md | 1 + camlib.py | 90 ++-- flatcamTools/ToolPaint.py | 1005 ++++++++++++++++++++++++++++++++----- 3 files changed, 930 insertions(+), 166 deletions(-) diff --git a/README.md b/README.md index f9eca5f7..bf72391f 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ CAD program, and create G-Code for Isolation routing. - in Paint Tool added a new method of painting named Combo who will pass through all the methods until the polygon is cleared - in Paint Tool attempting to add a new mode suitable for Laser usage +- more work in the new Laser Mode in the Paint Tool 14.02.2020 diff --git a/camlib.py b/camlib.py index a939f9a1..52bd863c 100644 --- a/camlib.py +++ b/camlib.py @@ -1582,7 +1582,7 @@ class Geometry(object): """ # log.debug("camlib.fill_with_lines()") - if not isinstance(line, LineString) or not isinstance(line, MultiLineString): + if not isinstance(line, LineString) and not isinstance(line, MultiLineString): log.debug("camlib.Geometry.fill_with_lines() --> Not a LineString/MultiLineString but %s" % str(type(line))) return None @@ -1596,10 +1596,10 @@ class Geometry(object): lines_trimmed = [] - polygon = line.buffer(aperture_size / 1.99999999999999999, int(steps_per_circle)) + polygon = line.buffer(aperture_size / 2.0, int(steps_per_circle)) try: - margin_poly = polygon.buffer(-tooldia / 1.99999999, int(steps_per_circle)) + margin_poly = polygon.buffer(-tooldia / 2.0, int(steps_per_circle)) except Exception: log.debug("camlib.Geometry.fill_with_lines() --> Could not buffer the Polygon, tool diameter too high") return None @@ -1615,41 +1615,51 @@ class Geometry(object): # provide the app with a way to process the GUI events when in a blocking loop QtWidgets.QApplication.processEvents() - line = line.parallel_offset(distance=delta, side='left', resolution=int(steps_per_circle)) - line = line.intersection(margin_poly) - lines_trimmed.append(line) + new_line = line.parallel_offset(distance=delta, side='left', resolution=int(steps_per_circle)) + new_line = new_line.intersection(margin_poly) + lines_trimmed.append(new_line) - line = line.parallel_offset(distance=delta, side='right', resolution=int(steps_per_circle)) - line = line.intersection(margin_poly) - lines_trimmed.append(line) + new_line = line.parallel_offset(distance=delta, side='right', resolution=int(steps_per_circle)) + new_line = new_line.intersection(margin_poly) + lines_trimmed.append(new_line) delta += tooldia * (1 - overlap) if prog_plot: - self.plot_temp_shapes(line) + self.plot_temp_shapes(new_line) self.temp_shapes.redraw() # Last line - delta = aperture_size / 2 + delta = (aperture_size / 2) - (tooldia / 2.00000001) - line = line.parallel_offset(distance=delta, side='left', resolution=int(steps_per_circle)) - line = line.intersection(margin_poly) - - for ll in line: - lines_trimmed.append(ll) - if prog_plot: - self.plot_temp_shapes(line) - - line = line.parallel_offset(distance=delta, side='left', resolution=int(steps_per_circle)) - line = line.intersection(margin_poly) - - for ll in line: - lines_trimmed.append(ll) - if prog_plot: - self.plot_temp_shapes(line) + new_line = line.parallel_offset(distance=delta, side='left', resolution=int(steps_per_circle)) + new_line = new_line.intersection(margin_poly) except Exception as e: log.debug('camlib.Geometry.fill_with_lines() Processing poly --> %s' % str(e)) return None + try: + for ll in new_line: + lines_trimmed.append(ll) + if prog_plot: + self.plot_temp_shapes(ll) + except TypeError: + lines_trimmed.append(new_line) + if prog_plot: + self.plot_temp_shapes(new_line) + + new_line = line.parallel_offset(distance=delta, side='right', resolution=int(steps_per_circle)) + new_line = new_line.intersection(margin_poly) + + try: + for ll in new_line: + lines_trimmed.append(ll) + if prog_plot: + self.plot_temp_shapes(ll) + except TypeError: + lines_trimmed.append(new_line) + if prog_plot: + self.plot_temp_shapes(new_line) + if prog_plot: self.temp_shapes.redraw() @@ -3434,10 +3444,13 @@ class CNCjob(Geometry): self.f_plunge = self.app.defaults["geometry_f_plunge"] if self.z_cut is None: - self.app.inform.emit('[ERROR_NOTCL] %s' % - _("Cut_Z parameter is None or zero. Most likely a bad combinations of " - "other parameters.")) - return 'fail' + if 'laser' not in self.pp_geometry_name: + self.app.inform.emit('[ERROR_NOTCL] %s' % + _("Cut_Z parameter is None or zero. Most likely a bad combinations of " + "other parameters.")) + return 'fail' + else: + self.z_cut = 0 if self.machinist_setting == 0: if self.z_cut > 0: @@ -3448,7 +3461,7 @@ class CNCjob(Geometry): "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: + elif self.z_cut == 0 and 'laser' not in self.pp_geometry_name: self.app.inform.emit('[WARNING] %s: %s' % (_("The Cut Z parameter is zero. There will be no cut, skipping file"), self.options['name'])) @@ -3793,11 +3806,14 @@ class CNCjob(Geometry): if self.machinist_setting == 0: if self.z_cut is None: - self.app.inform.emit( - '[ERROR_NOTCL] %s' % _("Cut_Z parameter is None or zero. Most likely a bad combinations of " - "other parameters.") - ) - return 'fail' + if 'laser' not in self.pp_geometry_name: + self.app.inform.emit( + '[ERROR_NOTCL] %s' % _("Cut_Z parameter is None or zero. Most likely a bad combinations of " + "other parameters.") + ) + return 'fail' + else: + self.z_cut = 0.0 if self.z_cut > 0: self.app.inform.emit('[WARNING] %s' % @@ -3807,7 +3823,7 @@ class CNCjob(Geometry): "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: + elif self.z_cut == 0 and 'laser' not in self.pp_geometry_name: self.app.inform.emit( '[WARNING] %s: %s' % (_("The Cut Z parameter is zero. There will be no cut, skipping file"), geometry.options['name']) diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 57a2cc43..8774c137 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -13,12 +13,12 @@ from copy import deepcopy # from ObjectCollection import * from flatcamParsers.ParseGerber import Gerber from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry -from camlib import Geometry +from camlib import Geometry, FlatCAMRTreeStorage from flatcamGUI.GUIElements import FCTable, FCDoubleSpinner, FCCheckBox, FCInputDialog, RadioSet, FCButton import FlatCAMApp -from shapely.geometry import base, Polygon, MultiPolygon, LinearRing, Point -from shapely.ops import cascaded_union +from shapely.geometry import base, Polygon, MultiPolygon, LinearRing, Point, MultiLineString +from shapely.ops import cascaded_union, unary_union, linemerge import numpy as np import math @@ -447,7 +447,6 @@ class ToolPaint(FlatCAMTool, Gerber): ) grid4.addWidget(self.rest_cb, 16, 0, 1, 2) - # Laser Mode self.laser_cb = FCCheckBox(_("Laser Mode")) self.laser_cb.setToolTip( @@ -681,6 +680,7 @@ class ToolPaint(FlatCAMTool, Gerber): def run(self, toggle=True): self.app.report_usage("ToolPaint()") + log.debug("ToolPaint().run() was launched ...") if toggle: # if the splitter is hidden, display it, else hide it but only if the current widget is the same @@ -795,9 +795,9 @@ class ToolPaint(FlatCAMTool, Gerber): self.blockSignals(True) - row = self.tools_table.currentRow() - if row < 0: - row = 0 + # row = self.tools_table.currentRow() + # if row < 0: + # row = 0 # this new dict will hold the actual useful data, another dict that is the value of key 'data' temp_tools = {} @@ -952,32 +952,8 @@ class ToolPaint(FlatCAMTool, Gerber): self.tools_frame.show() self.reset_fields() - # ## Init the GUI interface - self.order_radio.set_value(self.app.defaults["tools_paintorder"]) - self.paintmargin_entry.set_value(self.app.defaults["tools_paintmargin"]) - self.paintmethod_combo.set_value(self.app.defaults["tools_paintmethod"]) - self.selectmethod_combo.set_value(self.app.defaults["tools_selectmethod"]) - self.pathconnect_cb.set_value(self.app.defaults["tools_pathconnect"]) - self.paintcontour_cb.set_value(self.app.defaults["tools_paintcontour"]) - self.paintoverlap_entry.set_value(self.app.defaults["tools_paintoverlap"]) - - self.cutz_entry.set_value(self.app.defaults["tools_paintcutz"]) - self.tool_type_radio.set_value(self.app.defaults["tools_painttool_type"]) - self.tipdia_entry.set_value(self.app.defaults["tools_painttipdia"]) - self.tipangle_entry.set_value(self.app.defaults["tools_painttipangle"]) - self.addtool_entry.set_value(self.app.defaults["tools_paintnewdia"]) - self.rest_cb.set_value(self.app.defaults["tools_paintrest"]) - self.old_tool_dia = self.app.defaults["tools_paintnewdia"] - self.on_tool_type(val=self.tool_type_radio.get_value()) - - # make the default object type, "Geometry" - self.type_obj_combo.setCurrentIndex(2) - - # make the Laser Mode disabled because the Geometry object is default - self.laser_cb.setEnabled(False) - # updated units self.units = self.app.defaults['units'].upper() @@ -1020,6 +996,30 @@ class ToolPaint(FlatCAMTool, Gerber): "paintrest": self.app.defaults["tools_paintrest"], }) + # ## Init the GUI interface + self.order_radio.set_value(self.app.defaults["tools_paintorder"]) + self.paintmargin_entry.set_value(self.app.defaults["tools_paintmargin"]) + self.paintmethod_combo.set_value(self.app.defaults["tools_paintmethod"]) + self.selectmethod_combo.set_value(self.app.defaults["tools_selectmethod"]) + self.pathconnect_cb.set_value(self.app.defaults["tools_pathconnect"]) + self.paintcontour_cb.set_value(self.app.defaults["tools_paintcontour"]) + self.paintoverlap_entry.set_value(self.app.defaults["tools_paintoverlap"]) + + self.cutz_entry.set_value(self.app.defaults["tools_paintcutz"]) + self.tool_type_radio.set_value(self.app.defaults["tools_painttool_type"]) + self.tipdia_entry.set_value(self.app.defaults["tools_painttipdia"]) + self.tipangle_entry.set_value(self.app.defaults["tools_painttipangle"]) + self.addtool_entry.set_value(self.app.defaults["tools_paintnewdia"]) + self.rest_cb.set_value(self.app.defaults["tools_paintrest"]) + + self.on_tool_type(val=self.tool_type_radio.get_value()) + + # make the default object type, "Geometry" + self.type_obj_combo.setCurrentIndex(2) + + # make the Laser Mode disabled because the Geometry object is default + self.laser_cb.setEnabled(False) + try: diameters = [float(self.app.defaults["tools_painttooldia"])] except (ValueError, TypeError): @@ -1718,7 +1718,7 @@ class ToolPaint(FlatCAMTool, Gerber): polygon_list = None if inside_pt and poly_list is None: polygon_list = [self.find_polygon(point=inside_pt, geoset=obj.solid_geometry)] - elif inside_pt is None and poly_list: + elif (inside_pt is None and poly_list) or (inside_pt and poly_list): polygon_list = poly_list # No polygon? @@ -1797,43 +1797,161 @@ class ToolPaint(FlatCAMTool, Gerber): connect=conn, prog_plot=prog_plot) elif paint_method == "laser_lines": - line = None - aperture_size = None + # line = None + # aperture_size = None - # determine the Gerber follow line + # the key is the aperture type and the val is a list of geo elements + flash_el_dict = dict() + # the key is the aperture size, the val is a list of geo elements + traces_el_dict = dict() + + # find the flashes and the lines that are in the selected polygon and store them separately for apid, apval in obj.apertures.items(): for geo_el in apval['geometry']: - if 'solid' in geo_el: - if Point(inside_pt).within(geo_el['solid']): - if not isinstance(geo_el['follow'], Point): - line = geo_el['follow'] + if apval["size"] == 0.0: + if apval["size"] in traces_el_dict: + traces_el_dict[apval["size"]].append(geo_el) + else: + traces_el_dict[apval["size"]] = [geo_el] - if apval['type'] == 'C': - aperture_size = apval['size'] + if 'follow' in geo_el and geo_el['follow'].within(polyg): + if isinstance(geo_el['follow'], Point): + if apval["type"] == 'C': + if 'C' in flash_el_dict: + flash_el_dict['C'].append(geo_el) else: - if apval['width'] > apval['height']: - aperture_size = apval['height'] - else: - aperture_size = apval['width'] - print(line, aperture_size) - if line: - cpoly = self.fill_with_lines(line, aperture_size, - tooldia=tooldiameter, - steps_per_circle=self.app.defaults["geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) + flash_el_dict['C'] = [geo_el] + elif apval["type"] == 'O': + if 'O' in flash_el_dict: + flash_el_dict['O'].append(geo_el) + else: + flash_el_dict['O'] = [geo_el] + elif apval["type"] == 'R': + if 'R' in flash_el_dict: + flash_el_dict['R'].append(geo_el) + else: + flash_el_dict['R'] = [geo_el] + else: + aperture_size = apval['size'] + + if aperture_size in traces_el_dict: + traces_el_dict[aperture_size].append(geo_el) + else: + traces_el_dict[aperture_size] = [geo_el] + + cpoly = FlatCAMRTreeStorage() + pads_lines_list = list() + + # process the flashes found in the selected polygon with the 'lines' method for rectangular + # flashes and with 'seed' for oblong and circular flashes + # and pads (flahes) need the contour therefore I override the GUI settings with always True + for ap_type in flash_el_dict: + for elem in flash_el_dict[ap_type]: + if 'solid' in elem: + if ap_type == 'C': + f_o = self.clear_polygon2(elem['solid'], + tooldia=tooldiameter, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=True, + connect=conn, + prog_plot=prog_plot) + pads_lines_list += [p for p in f_o.get_objects() if p] + + elif ap_type == 'O': + f_o = self.clear_polygon2(elem['solid'], + tooldia=tooldiameter, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=True, + connect=conn, + prog_plot=prog_plot) + pads_lines_list += [p for p in f_o.get_objects() if p] + + elif ap_type == 'R': + f_o = self.clear_polygon3(elem['solid'], + tooldia=tooldiameter, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=True, + connect=conn, + prog_plot=prog_plot) + + pads_lines_list += [p for p in f_o.get_objects() if p] + + # add the lines from pads to the storage + try: + for lin in pads_lines_list: + if lin: + cpoly.insert(lin) + except TypeError: + cpoly.insert(pads_lines_list) + + copper_lines_list = list() + # process the traces found in the selected polygon using the 'laser_lines' method, + # method which will follow the 'follow' line therefore use the longer path possible for the + # laser, therefore the acceleration will play a smaller factor + for aperture_size in traces_el_dict: + for elem in traces_el_dict[aperture_size]: + line = elem['follow'] + if line: + t_o = self.fill_with_lines(line, aperture_size, + tooldia=tooldiameter, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + + copper_lines_list += [p for p in t_o.get_objects() if p] + + # add the lines from copper features to storage but first try to make as few lines as possible + # by trying to fuse them + lines_union = linemerge(unary_union(copper_lines_list)) + try: + for lin in lines_union: + if lin: + cpoly.insert(lin) + except TypeError: + cpoly.insert(lines_union) + # # determine the Gerber follow line + # for apid, apval in obj.apertures.items(): + # for geo_el in apval['geometry']: + # if 'solid' in geo_el: + # if Point(inside_pt).within(geo_el['solid']): + # if not isinstance(geo_el['follow'], Point): + # line = geo_el['follow'] + # + # if apval['type'] == 'C': + # aperture_size = apval['size'] + # else: + # if apval['width'] > apval['height']: + # aperture_size = apval['height'] + # else: + # aperture_size = apval['width'] + # + # if line: + # cpoly = self.fill_with_lines(line, aperture_size, + # tooldia=tooldiameter, + # steps_per_circle=self.app.defaults["geometry_circle_steps"], + # overlap=over, + # contour=cont, + # connect=conn, + # prog_plot=prog_plot) elif paint_method == "combo": self.app.inform.emit(_("Painting polygon with method: lines.")) cpoly = self.clear_polygon3(polyg, - tooldia=tooldiameter, - steps_per_circle=self.app.defaults["geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) + tooldia=tooldiameter, + steps_per_circle=self.app.defaults["geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) if cpoly and cpoly.objects: pass @@ -1851,12 +1969,12 @@ class ToolPaint(FlatCAMTool, Gerber): else: self.app.inform.emit(_("Failed. Painting polygon with method: standard.")) cpoly = self.clear_polygon(polyg, - tooldia=tooldiameter, - steps_per_circle=self.app.defaults["geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) + tooldia=tooldiameter, + steps_per_circle=self.app.defaults["geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) except FlatCAMApp.GracefulException: return "fail" except Exception as ee: @@ -2225,29 +2343,155 @@ class ToolPaint(FlatCAMTool, Gerber): contour=cont, connect=conn, prog_plot=prog_plot) + elif paint_method == "laser_lines": + # line = None + # aperture_size = None + + # the key is the aperture type and the val is a list of geo elements + flash_el_dict = dict() + # the key is the aperture size, the val is a list of geo elements + traces_el_dict = dict() + + # find the flashes and the lines that are in the selected polygon and store + # them separately + for apid, apval in obj.apertures.items(): + for geo_el in apval['geometry']: + if apval["size"] == 0.0: + if apval["size"] in traces_el_dict: + traces_el_dict[apval["size"]].append(geo_el) + else: + traces_el_dict[apval["size"]] = [geo_el] + + if 'follow' in geo_el and geo_el['follow'].within(pol): + if isinstance(geo_el['follow'], Point): + if apval["type"] == 'C': + if 'C' in flash_el_dict: + flash_el_dict['C'].append(geo_el) + else: + flash_el_dict['C'] = [geo_el] + elif apval["type"] == 'O': + if 'O' in flash_el_dict: + flash_el_dict['O'].append(geo_el) + else: + flash_el_dict['O'] = [geo_el] + elif apval["type"] == 'R': + if 'R' in flash_el_dict: + flash_el_dict['R'].append(geo_el) + else: + flash_el_dict['R'] = [geo_el] + else: + aperture_size = apval['size'] + + if aperture_size in traces_el_dict: + traces_el_dict[aperture_size].append(geo_el) + else: + traces_el_dict[aperture_size] = [geo_el] + + cp = FlatCAMRTreeStorage() + pads_lines_list = list() + + # process the flashes found in the selected polygon with the 'lines' method + # for rectangular flashes and with 'seed' for oblong and circular flashes + # and pads (flahes) need the contour therefore I override the GUI settings + # with always True + for ap_type in flash_el_dict: + for elem in flash_el_dict[ap_type]: + if 'solid' in elem: + if ap_type == 'C': + f_o = self.clear_polygon2(elem['solid'], + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=True, + connect=conn, + prog_plot=prog_plot) + pads_lines_list += [p for p in f_o.get_objects() if p] + + elif ap_type == 'O': + f_o = self.clear_polygon2(elem['solid'], + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=True, + connect=conn, + prog_plot=prog_plot) + pads_lines_list += [p for p in f_o.get_objects() if p] + + elif ap_type == 'R': + f_o = self.clear_polygon3(elem['solid'], + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=True, + connect=conn, + prog_plot=prog_plot) + + pads_lines_list += [p for p in f_o.get_objects() if p] + + # add the lines from pads to the storage + try: + for lin in pads_lines_list: + if lin: + cp.insert(lin) + except TypeError: + cp.insert(pads_lines_list) + + copper_lines_list = list() + # process the traces found in the selected polygon using the 'laser_lines' + # method, method which will follow the 'follow' line therefore use the longer + # path possible for the laser, therefore the acceleration will play + # a smaller factor + for aperture_size in traces_el_dict: + for elem in traces_el_dict[aperture_size]: + line = elem['follow'] + if line: + t_o = self.fill_with_lines(line, aperture_size, + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + + copper_lines_list += [p for p in t_o.get_objects() if p] + + # add the lines from copper features to storage but first try to make as few + # lines as possible + # by trying to fuse them + lines_union = linemerge(unary_union(copper_lines_list)) + try: + for lin in lines_union: + if lin: + cp.insert(lin) + except TypeError: + cp.insert(lines_union) elif paint_method == "combo": self.app.inform.emit(_("Painting polygons with method: lines.")) cp = self.clear_polygon3(pol, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) if cp and cp.objects: pass else: self.app.inform.emit(_("Failed. Painting polygons with method: seed.")) cp = self.clear_polygon2(pol, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) if cp and cp.objects: pass else: @@ -2255,13 +2499,13 @@ class ToolPaint(FlatCAMTool, Gerber): _("Failed. Painting polygons with method: standard.")) cp = self.clear_polygon(pol, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) if cp and cp.objects: total_geometry += list(cp.get_objects()) poly_processed.append(True) @@ -2301,16 +2545,142 @@ class ToolPaint(FlatCAMTool, Gerber): contour=cont, connect=conn, prog_plot=prog_plot) + elif paint_method == "laser_lines": + # line = None + # aperture_size = None + + # the key is the aperture type and the val is a list of geo elements + flash_el_dict = dict() + # the key is the aperture size, the val is a list of geo elements + traces_el_dict = dict() + + # find the flashes and the lines that are in the selected polygon and store + # them separately + for apid, apval in obj.apertures.items(): + for geo_el in apval['geometry']: + if apval["size"] == 0.0: + if apval["size"] in traces_el_dict: + traces_el_dict[apval["size"]].append(geo_el) + else: + traces_el_dict[apval["size"]] = [geo_el] + + if 'follow' in geo_el and geo_el['follow'].within(poly_buf): + if isinstance(geo_el['follow'], Point): + if apval["type"] == 'C': + if 'C' in flash_el_dict: + flash_el_dict['C'].append(geo_el) + else: + flash_el_dict['C'] = [geo_el] + elif apval["type"] == 'O': + if 'O' in flash_el_dict: + flash_el_dict['O'].append(geo_el) + else: + flash_el_dict['O'] = [geo_el] + elif apval["type"] == 'R': + if 'R' in flash_el_dict: + flash_el_dict['R'].append(geo_el) + else: + flash_el_dict['R'] = [geo_el] + else: + aperture_size = apval['size'] + + if aperture_size in traces_el_dict: + traces_el_dict[aperture_size].append(geo_el) + else: + traces_el_dict[aperture_size] = [geo_el] + + cp = FlatCAMRTreeStorage() + pads_lines_list = list() + + # process the flashes found in the selected polygon with the 'lines' method + # for rectangular flashes and with 'seed' for oblong and circular flashes + # and pads (flahes) need the contour therefore I override the GUI settings + # with always True + for ap_type in flash_el_dict: + for elem in flash_el_dict[ap_type]: + if 'solid' in elem: + if ap_type == 'C': + f_o = self.clear_polygon2(elem['solid'], + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=True, + connect=conn, + prog_plot=prog_plot) + pads_lines_list += [p for p in f_o.get_objects() if p] + + elif ap_type == 'O': + f_o = self.clear_polygon2(elem['solid'], + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=True, + connect=conn, + prog_plot=prog_plot) + pads_lines_list += [p for p in f_o.get_objects() if p] + + elif ap_type == 'R': + f_o = self.clear_polygon3(elem['solid'], + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=True, + connect=conn, + prog_plot=prog_plot) + + pads_lines_list += [p for p in f_o.get_objects() if p] + + # add the lines from pads to the storage + try: + for lin in pads_lines_list: + if lin: + cp.insert(lin) + except TypeError: + cp.insert(pads_lines_list) + + copper_lines_list = list() + # process the traces found in the selected polygon using the 'laser_lines' + # method, method which will follow the 'follow' line therefore use the longer + # path possible for the laser, therefore the acceleration will play + # a smaller factor + for aperture_size in traces_el_dict: + for elem in traces_el_dict[aperture_size]: + line = elem['follow'] + if line: + t_o = self.fill_with_lines(line, aperture_size, + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + + copper_lines_list += [p for p in t_o.get_objects() if p] + + # add the lines from copper features to storage but first try to make as few + # lines as possible + # by trying to fuse them + lines_union = linemerge(unary_union(copper_lines_list)) + try: + for lin in lines_union: + if lin: + cp.insert(lin) + except TypeError: + cp.insert(lines_union) elif paint_method == "combo": self.app.inform.emit(_("Painting polygons with method: lines.")) cp = self.clear_polygon3(poly_buf, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) if cp and cp.objects: pass @@ -2329,13 +2699,13 @@ class ToolPaint(FlatCAMTool, Gerber): else: self.app.inform.emit(_("Failed. Painting polygons with method: standard.")) cp = self.clear_polygon(poly_buf, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) if cp: total_geometry += list(cp.get_objects()) poly_processed.append(True) @@ -2553,6 +2923,132 @@ class ToolPaint(FlatCAMTool, Gerber): steps_per_circle=self.app.defaults["geometry_circle_steps"], overlap=over, contour=cont, connect=conn, prog_plot=prog_plot) + elif paint_method == "laser_lines": + # line = None + # aperture_size = None + + # the key is the aperture type and the val is a list of geo elements + flash_el_dict = dict() + # the key is the aperture size, the val is a list of geo elements + traces_el_dict = dict() + + # find the flashes and the lines that are in the selected polygon and store + # them separately + for apid, apval in obj.apertures.items(): + for geo_el in apval['geometry']: + if apval["size"] == 0.0: + if apval["size"] in traces_el_dict: + traces_el_dict[apval["size"]].append(geo_el) + else: + traces_el_dict[apval["size"]] = [geo_el] + + if 'follow' in geo_el and geo_el['follow'].within(poly_buf): + if isinstance(geo_el['follow'], Point): + if apval["type"] == 'C': + if 'C' in flash_el_dict: + flash_el_dict['C'].append(geo_el) + else: + flash_el_dict['C'] = [geo_el] + elif apval["type"] == 'O': + if 'O' in flash_el_dict: + flash_el_dict['O'].append(geo_el) + else: + flash_el_dict['O'] = [geo_el] + elif apval["type"] == 'R': + if 'R' in flash_el_dict: + flash_el_dict['R'].append(geo_el) + else: + flash_el_dict['R'] = [geo_el] + else: + aperture_size = apval['size'] + + if aperture_size in traces_el_dict: + traces_el_dict[aperture_size].append(geo_el) + else: + traces_el_dict[aperture_size] = [geo_el] + + cp = FlatCAMRTreeStorage() + pads_lines_list = list() + + # process the flashes found in the selected polygon with the 'lines' method + # for rectangular flashes and with 'seed' for oblong and circular flashes + # and pads (flahes) need the contour therefore I override the GUI settings + # with always True + for ap_type in flash_el_dict: + for elem in flash_el_dict[ap_type]: + if 'solid' in elem: + if ap_type == 'C': + f_o = self.clear_polygon2(elem['solid'], + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=True, + connect=conn, + prog_plot=prog_plot) + pads_lines_list += [p for p in f_o.get_objects() if p] + + elif ap_type == 'O': + f_o = self.clear_polygon2(elem['solid'], + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=True, + connect=conn, + prog_plot=prog_plot) + pads_lines_list += [p for p in f_o.get_objects() if p] + + elif ap_type == 'R': + f_o = self.clear_polygon3(elem['solid'], + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=True, + connect=conn, + prog_plot=prog_plot) + + pads_lines_list += [p for p in f_o.get_objects() if p] + + # add the lines from pads to the storage + try: + for lin in pads_lines_list: + if lin: + cp.insert(lin) + except TypeError: + cp.insert(pads_lines_list) + + copper_lines_list = list() + # process the traces found in the selected polygon using the 'laser_lines' + # method, method which will follow the 'follow' line therefore use the longer + # path possible for the laser, therefore the acceleration will play + # a smaller factor + for aperture_size in traces_el_dict: + for elem in traces_el_dict[aperture_size]: + line = elem['follow'] + if line: + t_o = self.fill_with_lines(line, aperture_size, + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + + copper_lines_list += [p for p in t_o.get_objects() if p] + + # add the lines from copper features to storage but first try to make as few + # lines as possible + # by trying to fuse them + lines_union = linemerge(unary_union(copper_lines_list)) + try: + for lin in lines_union: + if lin: + cp.insert(lin) + except TypeError: + cp.insert(lines_union) elif paint_method == "combo": self.app.inform.emit(_("Painting polygons with method: lines.")) cp = self.clear_polygon3(poly_buf, @@ -2907,16 +3403,142 @@ class ToolPaint(FlatCAMTool, Gerber): contour=cont, connect=conn, prog_plot=prog_plot) + elif paint_method == "laser_lines": + # line = None + # aperture_size = None + + # the key is the aperture type and the val is a list of geo elements + flash_el_dict = dict() + # the key is the aperture size, the val is a list of geo elements + traces_el_dict = dict() + + # find the flashes and the lines that are in the selected polygon and store + # them separately + for apid, apval in obj.apertures.items(): + for geo_el in apval['geometry']: + if apval["size"] == 0.0: + if apval["size"] in traces_el_dict: + traces_el_dict[apval["size"]].append(geo_el) + else: + traces_el_dict[apval["size"]] = [geo_el] + + if 'follow' in geo_el and geo_el['follow'].within(poly_buf): + if isinstance(geo_el['follow'], Point): + if apval["type"] == 'C': + if 'C' in flash_el_dict: + flash_el_dict['C'].append(geo_el) + else: + flash_el_dict['C'] = [geo_el] + elif apval["type"] == 'O': + if 'O' in flash_el_dict: + flash_el_dict['O'].append(geo_el) + else: + flash_el_dict['O'] = [geo_el] + elif apval["type"] == 'R': + if 'R' in flash_el_dict: + flash_el_dict['R'].append(geo_el) + else: + flash_el_dict['R'] = [geo_el] + else: + aperture_size = apval['size'] + + if aperture_size in traces_el_dict: + traces_el_dict[aperture_size].append(geo_el) + else: + traces_el_dict[aperture_size] = [geo_el] + + cp = FlatCAMRTreeStorage() + pads_lines_list = list() + + # process the flashes found in the selected polygon with the 'lines' method + # for rectangular flashes and with 'seed' for oblong and circular flashes + # and pads (flahes) need the contour therefore I override the GUI settings + # with always True + for ap_type in flash_el_dict: + for elem in flash_el_dict[ap_type]: + if 'solid' in elem: + if ap_type == 'C': + f_o = self.clear_polygon2(elem['solid'], + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=True, + connect=conn, + prog_plot=prog_plot) + pads_lines_list += [p for p in f_o.get_objects() if p] + + elif ap_type == 'O': + f_o = self.clear_polygon2(elem['solid'], + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=True, + connect=conn, + prog_plot=prog_plot) + pads_lines_list += [p for p in f_o.get_objects() if p] + + elif ap_type == 'R': + f_o = self.clear_polygon3(elem['solid'], + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=True, + connect=conn, + prog_plot=prog_plot) + + pads_lines_list += [p for p in f_o.get_objects() if p] + + # add the lines from pads to the storage + try: + for lin in pads_lines_list: + if lin: + cp.insert(lin) + except TypeError: + cp.insert(pads_lines_list) + + copper_lines_list = list() + # process the traces found in the selected polygon using the 'laser_lines' + # method, method which will follow the 'follow' line therefore use the longer + # path possible for the laser, therefore the acceleration will play + # a smaller factor + for aperture_size in traces_el_dict: + for elem in traces_el_dict[aperture_size]: + line = elem['follow'] + if line: + t_o = self.fill_with_lines(line, aperture_size, + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + + copper_lines_list += [p for p in t_o.get_objects() if p] + + # add the lines from copper features to storage but first try to make as few + # lines as possible + # by trying to fuse them + lines_union = linemerge(unary_union(copper_lines_list)) + try: + for lin in lines_union: + if lin: + cp.insert(lin) + except TypeError: + cp.insert(lines_union) elif paint_method == "combo": self.app.inform.emit(_("Painting polygons with method: lines.")) cp = self.clear_polygon3(poly_buf, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) if cp and cp.objects: pass @@ -2935,13 +3557,13 @@ class ToolPaint(FlatCAMTool, Gerber): else: self.app.inform.emit(_("Failed. Painting polygons with method: standard.")) cp = self.clear_polygon(poly_buf, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) if cp and cp.objects: total_geometry += list(cp.get_objects()) except FlatCAMApp.GracefulException: @@ -3101,16 +3723,141 @@ class ToolPaint(FlatCAMTool, Gerber): steps_per_circle=self.app.defaults["geometry_circle_steps"], overlap=over, contour=cont, connect=conn, prog_plot=prog_plot) + elif paint_method == "laser_lines": + # line = None + # aperture_size = None + + # the key is the aperture type and the val is a list of geo elements + flash_el_dict = dict() + # the key is the aperture size, the val is a list of geo elements + copper_el_dict = dict() + + # find the flashes and the lines that are in the selected polygon and store + # them separately + for apid, apval in obj.apertures.items(): + for geo_el in apval['geometry']: + if apval["size"] == 0.0: + if apval["size"] in copper_el_dict: + copper_el_dict[apval["size"]].append(geo_el) + else: + copper_el_dict[apval["size"]] = [geo_el] + + if 'follow' in geo_el and geo_el['follow'].within(poly_buf): + if isinstance(geo_el['follow'], Point): + if apval["type"] == 'C': + if 'C' in flash_el_dict: + flash_el_dict['C'].append(geo_el) + else: + flash_el_dict['C'] = [geo_el] + elif apval["type"] == 'O': + if 'O' in flash_el_dict: + flash_el_dict['O'].append(geo_el) + else: + flash_el_dict['O'] = [geo_el] + elif apval["type"] == 'R': + if 'R' in flash_el_dict: + flash_el_dict['R'].append(geo_el) + else: + flash_el_dict['R'] = [geo_el] + else: + aperture_size = apval['size'] + + if aperture_size in copper_el_dict: + copper_el_dict[aperture_size].append(geo_el) + else: + copper_el_dict[aperture_size] = [geo_el] + + cp = FlatCAMRTreeStorage() + pads_lines_list = list() + + # process the flashes found in the selected polygon with the 'lines' method + # for rectangular flashes and with 'seed' for oblong and circular flashes + # and pads (flahes) need the contour therefore I override the GUI settings + # with always True + for ap_type in flash_el_dict: + for elem in flash_el_dict[ap_type]: + if 'solid' in elem: + if ap_type == 'C': + f_o = self.clear_polygon2(elem['solid'], + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=True, + connect=conn, + prog_plot=prog_plot) + pads_lines_list += [p for p in f_o.get_objects() if p] + + elif ap_type == 'O': + f_o = self.clear_polygon2(elem['solid'], + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=True, + connect=conn, + prog_plot=prog_plot) + pads_lines_list += [p for p in f_o.get_objects() if p] + + elif ap_type == 'R': + f_o = self.clear_polygon3(elem['solid'], + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=True, + connect=conn, + prog_plot=prog_plot) + + pads_lines_list += [p for p in f_o.get_objects() if p] + + # add the lines from pads to the storage + try: + for lin in pads_lines_list: + if lin: + cp.insert(lin) + except TypeError: + cp.insert(pads_lines_list) + + copper_lines_list = list() + # process the traces found in the selected polygon using the 'laser_lines' + # method, method which will follow the 'follow' line therefore use the longer + # path possible for the laser, therefore the acceleration will play + # a smaller factor + for aperture_size in copper_el_dict: + for elem in copper_el_dict[aperture_size]: + line = elem['follow'] + if line: + t_o = self.fill_with_lines(line, aperture_size, + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + + copper_lines_list += [p for p in t_o.get_objects() if p] + + # add the lines from copper features to storage but first try to make as few + # lines as possible + # by trying to fuse them + lines_union = linemerge(unary_union(copper_lines_list)) + try: + for lin in lines_union: + if lin: + cp.insert(lin) + except TypeError: + cp.insert(lines_union) elif paint_method == "combo": self.app.inform.emit(_("Painting polygons with method: lines.")) cp = self.clear_polygon3(poly_buf, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) + tooldia=tool_dia, + steps_per_circle=self.app.defaults["geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) if cp and cp.objects: pass @@ -3129,13 +3876,13 @@ class ToolPaint(FlatCAMTool, Gerber): else: self.app.inform.emit(_("Failed. Painting polygons with method: standard.")) cp = self.clear_polygon(poly_buf, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) + tooldia=tool_dia, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) if cp and cp.objects: cleared_geo += list(cp.get_objects()) except FlatCAMApp.GracefulException: From 64912949c6a52ee8c7c11ef654206522594f5810 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 16 Feb 2020 03:11:46 +0200 Subject: [PATCH 098/209] - modified the Paint Tool UI --- FlatCAMApp.py | 2 +- README.md | 1 + flatcamGUI/PreferencesUI.py | 26 ++++++---- flatcamTools/ToolPaint.py | 100 ++++++++++++++++-------------------- 4 files changed, 64 insertions(+), 65 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 3574dcfa..67fbc5e9 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -799,7 +799,7 @@ class App(QtCore.QObject): "tools_paintorder": 'rev', "tools_paintoverlap": 20, "tools_paintmargin": 0.0, - "tools_paintmethod": "seed", + "tools_paintmethod": _("Seed-based"), "tools_selectmethod": "all", "tools_pathconnect": True, "tools_paintcontour": True, diff --git a/README.md b/README.md index bf72391f..ed4827fc 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ CAD program, and create G-Code for Isolation routing. - in Paint Tool added a new method of painting named Combo who will pass through all the methods until the polygon is cleared - in Paint Tool attempting to add a new mode suitable for Laser usage - more work in the new Laser Mode in the Paint Tool +- modified the Paint Tool UI 14.02.2020 diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index df1c0021..305179fd 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -5761,17 +5761,25 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI): # Method methodlabel = QtWidgets.QLabel('%s:' % _('Method')) methodlabel.setToolTip( - _("Algorithm for non-copper clearing:
" - "Standard: Fixed step inwards.
" - "Seed-based: Outwards from seed.
" - "Line-based: Parallel lines.") + _("Algorithm for painting:\n" + "- Standard: Fixed step inwards.\n" + "- Seed-based: Outwards from seed.\n" + "- Line-based: Parallel lines.\n" + "- Laser-lines: Active only for Gerber objects.\n" + "Will create lines that follow the traces.\n" + "- Combo: In case of failure a new method will be picked from the above\n" + "in the order specified.") ) - self.paintmethod_combo = RadioSet([ - {"label": _("Standard"), "value": "standard"}, - {"label": _("Seed-based"), "value": "seed"}, - {"label": _("Straight lines"), "value": "lines"} - ], orientation='vertical', stretch=False) + # self.paintmethod_combo = RadioSet([ + # {"label": _("Standard"), "value": "standard"}, + # {"label": _("Seed-based"), "value": "seed"}, + # {"label": _("Straight lines"), "value": "lines"} + # ], orientation='vertical', stretch=False) + self.paintmethod_combo = FCComboBox() + self.paintmethod_combo.addItems( + [_("Standard"), _("Seed-based"), _("Straight lines"), _("Laser lines"), _("Combo")] + ) grid0.addWidget(methodlabel, 11, 0) grid0.addWidget(self.paintmethod_combo, 11, 1) diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 8774c137..2ae02a41 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -14,7 +14,7 @@ from copy import deepcopy from flatcamParsers.ParseGerber import Gerber from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry from camlib import Geometry, FlatCAMRTreeStorage -from flatcamGUI.GUIElements import FCTable, FCDoubleSpinner, FCCheckBox, FCInputDialog, RadioSet, FCButton +from flatcamGUI.GUIElements import FCTable, FCDoubleSpinner, FCCheckBox, FCInputDialog, RadioSet, FCButton, FCComboBox import FlatCAMApp from shapely.geometry import base, Polygon, MultiPolygon, LinearRing, Point, MultiLineString @@ -75,15 +75,6 @@ class ToolPaint(FlatCAMTool, Gerber): # ################################################ # ##### Type of object to be painted ############# # ################################################ - self.type_obj_combo = QtWidgets.QComboBox() - self.type_obj_combo.addItem("Gerber") - self.type_obj_combo.addItem("Excellon") - self.type_obj_combo.addItem("Geometry") - - # we get rid of item1 ("Excellon") as it is not suitable - self.type_obj_combo.view().setRowHidden(1, True) - self.type_obj_combo.setItemIcon(0, QtGui.QIcon(self.app.resource_location + "/flatcam_icon16.png")) - self.type_obj_combo.setItemIcon(2, QtGui.QIcon(self.app.resource_location + "/geometry16.png")) self.type_obj_combo_label = QtWidgets.QLabel('%s:' % _("Obj Type")) self.type_obj_combo_label.setToolTip( @@ -93,6 +84,10 @@ class ToolPaint(FlatCAMTool, Gerber): "of objects that will populate the 'Object' combobox.") ) self.type_obj_combo_label.setMinimumWidth(60) + + self.type_obj_combo = RadioSet([{'label': "Geometry", 'value': 'geometry'}, + {'label': "Gerber", 'value': 'gerber'}]) + grid0.addWidget(self.type_obj_combo_label, 1, 0) grid0.addWidget(self.type_obj_combo, 1, 1) @@ -371,23 +366,38 @@ class ToolPaint(FlatCAMTool, Gerber): "- Standard: Fixed step inwards.\n" "- Seed-based: Outwards from seed.\n" "- Line-based: Parallel lines.\n" - "- Laser-lines: Active only when Laser Mode is active and only for Gerber objects.\n" + "- Laser-lines: Active only for Gerber objects.\n" "Will create lines that follow the traces.\n" "- Combo: In case of failure a new method will be picked from the above\n" "in the order specified.") ) - self.paintmethod_combo = RadioSet([ - {"label": _("Standard"), "value": "standard"}, - {"label": _("Seed-based"), "value": "seed"}, - {"label": _("Straight lines"), "value": "lines"}, - {"label": _("Laser lines"), "value": "laser_lines"}, - {"label": _("Combo"), "value": "combo"} - ], orientation='vertical', stretch=False) - self.paintmethod_combo.setObjectName(_("Method")) + # self.paintmethod_combo = RadioSet([ + # {"label": _("Standard"), "value": "standard"}, + # {"label": _("Seed-based"), "value": "seed"}, + # {"label": _("Straight lines"), "value": "lines"}, + # {"label": _("Laser lines"), "value": "laser_lines"}, + # {"label": _("Combo"), "value": "combo"} + # ], orientation='vertical', stretch=False) - for choice in self.paintmethod_combo.choices: - if choice['value'] == "laser_lines": - choice["radio"].setEnabled(False) + # for choice in self.paintmethod_combo.choices: + # if choice['value'] == "laser_lines": + # choice["radio"].setEnabled(False) + + self.paintmethod_combo = FCComboBox() + self.paintmethod_combo.addItems( + [_("Standard"), _("Seed-based"), _("Straight lines"), _("Laser lines"), _("Combo")] + ) + self.p_mth = { + _("Standard"): "standard", + _("Seed-based"): "seed", + _("Straight lines"): "lines", + _("Laser lines"): "laser_lines", + _("Combo"): "combo" + } + idx = self.paintmethod_combo.findText(_("Laser lines")) + self.paintmethod_combo.model().item(idx).setEnabled(False) + + self.paintmethod_combo.setObjectName(_("Method")) grid4.addWidget(methodlabel, 7, 0) grid4.addWidget(self.paintmethod_combo, 7, 1) @@ -447,15 +457,6 @@ class ToolPaint(FlatCAMTool, Gerber): ) grid4.addWidget(self.rest_cb, 16, 0, 1, 2) - # Laser Mode - self.laser_cb = FCCheckBox(_("Laser Mode")) - self.laser_cb.setToolTip( - _("This control is enabled only for Gerber objects.\n" - "If checked then a new method is shown in Methods,\n" - "and it is also added to the Combo Method sequence.") - ) - grid4.addWidget(self.laser_cb, 17, 0, 1, 2) - # Polygon selection selectlabel = QtWidgets.QLabel('%s:' % _('Selection')) selectlabel.setToolTip( @@ -635,8 +636,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.rest_cb.stateChanged.connect(self.on_rest_machining_check) self.box_combo_type.currentIndexChanged.connect(self.on_combo_box_type) - self.type_obj_combo.currentIndexChanged.connect(self.on_type_obj_index_changed) - self.laser_cb.stateChanged.connect(self.on_laser_mode_toggled) + self.type_obj_combo.activated_custom.connect(self.on_type_obj_index_changed) self.reset_button.clicked.connect(self.set_tool_ui) # ############################################################################# @@ -655,25 +655,18 @@ class ToolPaint(FlatCAMTool, Gerber): icon=QtGui.QIcon(self.app.resource_location + "/delete32.png") ) - def on_type_obj_index_changed(self, index): - obj_type = self.type_obj_combo.currentIndex() + def on_type_obj_index_changed(self, val): + obj_type = 0 if val == 'gerber' else 2 self.obj_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) self.obj_combo.setCurrentIndex(0) - if self.type_obj_combo.currentText().lower() == 'gerber': - self.laser_cb.setEnabled(True) + idx = self.paintmethod_combo.findText(_("Laser lines")) + if self.type_obj_combo.get_value().lower() == 'gerber': + self.paintmethod_combo.model().item(idx).setEnabled(True) else: - self.laser_cb.setEnabled(False) - - def on_laser_mode_toggled(self, val): - for choice in self.paintmethod_combo.choices: - if choice['value'] == "laser_lines": - if val: - choice["radio"].setEnabled(True) - else: - choice["radio"].setEnabled(False) - if self.paintmethod_combo.get_value() == "laser_lines": - self.paintmethod_combo.set_value('lines') + self.paintmethod_combo.model().item(idx).setEnabled(False) + if self.paintmethod_combo.get_value() == _("Laser lines"): + self.paintmethod_combo.set_value(_("Straight lines")) def install(self, icon=None, separator=None, **kwargs): FlatCAMTool.install(self, icon, separator, shortcut='ALT+P', **kwargs) @@ -1015,10 +1008,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.on_tool_type(val=self.tool_type_radio.get_value()) # make the default object type, "Geometry" - self.type_obj_combo.setCurrentIndex(2) - - # make the Laser Mode disabled because the Geometry object is default - self.laser_cb.setEnabled(False) + self.type_obj_combo.set_value("geometry") try: diameters = [float(self.app.defaults["tools_painttooldia"])] @@ -1727,7 +1717,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.app.inform.emit('[WARNING] %s' % _('No polygon found.')) return - paint_method = method if method is not None else self.paintmethod_combo.get_value() + paint_method = method if method is not None else self.p_mth[self.paintmethod_combo.get_value()] paint_margin = float(self.paintmargin_entry.get_value()) if margin is None else margin # determine if to use the progressive plotting prog_plot = True if self.app.defaults["tools_paint_plotting"] == 'progressive' else False @@ -2142,7 +2132,7 @@ class ToolPaint(FlatCAMTool, Gerber): Usage of the different one is related to when this function is called from a TcL command. :return: """ - paint_method = method if method is not None else self.paintmethod_combo.get_value() + paint_method = method if method is not None else self.p_mth[self.paintmethod_combo.get_value()] if margin is not None: paint_margin = margin @@ -3207,7 +3197,7 @@ class ToolPaint(FlatCAMTool, Gerber): Usage of the different one is related to when this function is called from a TcL command. :return: """ - paint_method = method if method is not None else self.paintmethod_combo.get_value() + paint_method = method if method is not None else self.p_mth[self.paintmethod_combo.get_value()] if margin is not None: paint_margin = margin From d1408a3d2c36c2104c19d318dde7503e57f3c8e4 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 16 Feb 2020 16:50:24 +0200 Subject: [PATCH 099/209] - small update to NCC Tool UI --- README.md | 4 ++++ flatcamTools/ToolNonCopperClear.py | 32 ++++++++++++++++++------------ flatcamTools/ToolPaint.py | 4 ++-- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index ed4827fc..7e948bd3 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +16.02.2020 + +- small update to NCC Tool UI + 15.02.2020 - in Paint Tool added a new method of painting named Combo who will pass through all the methods until the polygon is cleared diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNonCopperClear.py index 7eca4da2..d96ac687 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/flatcamTools/ToolNonCopperClear.py @@ -8,7 +8,7 @@ from PyQt5 import QtWidgets, QtCore, QtGui from FlatCAMTool import FlatCAMTool -from flatcamGUI.GUIElements import FCCheckBox, FCDoubleSpinner, RadioSet, FCTable, FCInputDialog, FCButton +from flatcamGUI.GUIElements import FCCheckBox, FCDoubleSpinner, RadioSet, FCTable, FCInputDialog, FCButton, FCComboBox from flatcamParsers.ParseGerber import Gerber import FlatCAMApp @@ -70,15 +70,15 @@ class NonCopperClear(FlatCAMTool, Gerber): # ################################################ # ##### Type of object to be copper cleaned ###### # ################################################ - self.type_obj_combo = QtWidgets.QComboBox() - self.type_obj_combo.addItem("Gerber") - self.type_obj_combo.addItem("Excellon") - self.type_obj_combo.addItem("Geometry") - - # we get rid of item1 ("Excellon") as it is not suitable - self.type_obj_combo.view().setRowHidden(1, True) - self.type_obj_combo.setItemIcon(0, QtGui.QIcon(self.app.resource_location + "/flatcam_icon16.png")) - self.type_obj_combo.setItemIcon(2, QtGui.QIcon(self.app.resource_location + "/geometry16.png")) + # self.type_obj_combo = QtWidgets.QComboBox() + # self.type_obj_combo.addItem("Gerber") + # self.type_obj_combo.addItem("Excellon") + # self.type_obj_combo.addItem("Geometry") + # + # # we get rid of item1 ("Excellon") as it is not suitable + # self.type_obj_combo.view().setRowHidden(1, True) + # self.type_obj_combo.setItemIcon(0, QtGui.QIcon(self.app.resource_location + "/flatcam_icon16.png")) + # self.type_obj_combo.setItemIcon(2, QtGui.QIcon(self.app.resource_location + "/geometry16.png")) self.type_obj_combo_label = QtWidgets.QLabel('%s:' % _("Obj Type")) self.type_obj_combo_label.setToolTip( @@ -88,6 +88,10 @@ class NonCopperClear(FlatCAMTool, Gerber): "of objects that will populate the 'Object' combobox.") ) self.type_obj_combo_label.setMinimumWidth(60) + + self.type_obj_combo = RadioSet([{'label': "Geometry", 'value': 'geometry'}, + {'label': "Gerber", 'value': 'gerber'}]) + form_layout.addRow(self.type_obj_combo_label, self.type_obj_combo) # ################################################ @@ -683,11 +687,11 @@ class NonCopperClear(FlatCAMTool, Gerber): self.ncc_rest_cb.stateChanged.connect(self.on_rest_machining_check) self.ncc_order_radio.activated_custom[str].connect(self.on_order_changed) - self.type_obj_combo.currentIndexChanged.connect(self.on_type_obj_index_changed) + self.type_obj_combo.activated_custom.connect(self.on_type_obj_index_changed) self.reset_button.clicked.connect(self.set_tool_ui) - def on_type_obj_index_changed(self, index): - obj_type = self.type_obj_combo.currentIndex() + def on_type_obj_index_changed(self, val): + obj_type = 0 if val == 'gerber' else 2 self.object_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) self.object_combo.setCurrentIndex(0) @@ -885,6 +889,8 @@ class NonCopperClear(FlatCAMTool, Gerber): self.tools_frame.show() + self.type_obj_combo.set_value('gerber') + self.ncc_order_radio.set_value(self.app.defaults["tools_nccorder"]) self.ncc_overlap_entry.set_value(self.app.defaults["tools_nccoverlap"]) self.ncc_margin_entry.set_value(self.app.defaults["tools_nccmargin"]) diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 2ae02a41..6b64d4f9 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -636,7 +636,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.rest_cb.stateChanged.connect(self.on_rest_machining_check) self.box_combo_type.currentIndexChanged.connect(self.on_combo_box_type) - self.type_obj_combo.activated_custom.connect(self.on_type_obj_index_changed) + self.type_obj_combo.activated_custom.connect(self.on_type_obj_changed) self.reset_button.clicked.connect(self.set_tool_ui) # ############################################################################# @@ -655,7 +655,7 @@ class ToolPaint(FlatCAMTool, Gerber): icon=QtGui.QIcon(self.app.resource_location + "/delete32.png") ) - def on_type_obj_index_changed(self, val): + def on_type_obj_changed(self, val): obj_type = 0 if val == 'gerber' else 2 self.obj_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) self.obj_combo.setCurrentIndex(0) From 1e9232aeaa6b5de0df113baf4f1e4cd38c29e5e8 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 17 Feb 2020 04:43:01 +0200 Subject: [PATCH 100/209] - updated the Excellon UI to hold data for each tool - in Excellon UI removed the tools table column for Offset Z and used the UI form parameter - updated the Excellon Editor to add for each tool a 'data' dictionary - updated all FlatCAM tools to use the new confirmation message that show if the entered value is within range or outside --- FlatCAMApp.py | 22 +- FlatCAMObj.py | 314 +++++++++++++++++---------- FlatCAMTool.py | 22 ++ README.md | 7 + camlib.py | 9 +- flatcamEditors/FlatCAMExcEditor.py | 54 ++++- flatcamGUI/ObjectUI.py | 180 ++++++++------- flatcamGUI/PreferencesUI.py | 73 +++++-- flatcamParsers/ParseExcellon.py | 1 + flatcamTools/ToolCalculators.py | 18 +- flatcamTools/ToolCalibration.py | 22 +- flatcamTools/ToolCopperThieving.py | 22 +- flatcamTools/ToolCutOut.py | 10 +- flatcamTools/ToolDblSided.py | 10 +- flatcamTools/ToolExtractDrills.py | 12 +- flatcamTools/ToolFiducials.py | 6 +- flatcamTools/ToolFilm.py | 14 +- flatcamTools/ToolInvertGerber.py | 2 +- flatcamTools/ToolNonCopperClear.py | 12 +- flatcamTools/ToolPaint.py | 10 +- flatcamTools/ToolPanelize.py | 8 +- flatcamTools/ToolPunchGerber.py | 12 +- flatcamTools/ToolRulesCheck.py | 20 +- flatcamTools/ToolSolderPaste.py | 22 +- flatcamTools/ToolTransform.py | 16 +- preprocessors/default.py | 7 + tclCommands/TclCommandDrillcncjob.py | 5 +- 27 files changed, 582 insertions(+), 328 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 67fbc5e9..53dfe415 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -622,7 +622,9 @@ class App(QtCore.QObject): "excellon_zeros": "L", "excellon_units": "INCH", "excellon_update": True, + "excellon_optimization_type": 'B', + "excellon_search_time": 3, "excellon_save_filters": "Excellon File (*.txt);;Excellon File (*.drd);;Excellon File (*.drl);;" "Excellon File (*.exc);;Excellon File (*.ncd);;Excellon File (*.tap);;" @@ -631,12 +633,17 @@ class App(QtCore.QObject): "excellon_plot_line": '#750000BF', # Excellon Options - "excellon_drillz": -1.7, + "excellon_operation": "drill", + "excellon_milling_type": "drills", + + "excellon_milling_dia": 0.8, + + "excellon_cutz": -1.7, "excellon_multidepth": False, "excellon_depthperpass": 0.7, "excellon_travelz": 2, "excellon_endz": 0.5, - "excellon_feedrate": 300, + "excellon_feedrate_z": 300, "excellon_spindlespeed": 0, "excellon_dwell": False, "excellon_dwelltime": 1, @@ -1308,12 +1315,17 @@ class App(QtCore.QObject): "excellon_plot_line": self.ui.excellon_defaults_form.excellon_gen_group.line_color_entry, # Excellon Options - "excellon_drillz": self.ui.excellon_defaults_form.excellon_opt_group.cutz_entry, + "excellon_operation": self.ui.excellon_defaults_form.excellon_opt_group.operation_radio, + "excellon_milling_type": self.ui.excellon_defaults_form.excellon_opt_group.milling_type_radio, + + "excellon_milling_dia": self.ui.excellon_defaults_form.excellon_opt_group.mill_dia_entry, + + "excellon_cutz": self.ui.excellon_defaults_form.excellon_opt_group.cutz_entry, "excellon_multidepth": self.ui.excellon_defaults_form.excellon_opt_group.mpass_cb, "excellon_depthperpass": self.ui.excellon_defaults_form.excellon_opt_group.maxdepth_entry, "excellon_travelz": self.ui.excellon_defaults_form.excellon_opt_group.travelz_entry, "excellon_endz": self.ui.excellon_defaults_form.excellon_opt_group.endz_entry, - "excellon_feedrate": self.ui.excellon_defaults_form.excellon_opt_group.feedrate_z_entry, + "excellon_feedrate_z": self.ui.excellon_defaults_form.excellon_opt_group.feedrate_z_entry, "excellon_spindlespeed": self.ui.excellon_defaults_form.excellon_opt_group.spindlespeed_entry, "excellon_dwell": self.ui.excellon_defaults_form.excellon_opt_group.dwell_cb, "excellon_dwelltime": self.ui.excellon_defaults_form.excellon_opt_group.dwelltime_entry, @@ -5944,7 +5956,7 @@ class App(QtCore.QObject): dimensions = ['gerber_isotooldia', 'gerber_noncoppermargin', 'gerber_bboxmargin', "gerber_isooverlap", "gerber_editor_newsize", "gerber_editor_lin_pitch", "gerber_editor_buff_f", - 'excellon_drillz', 'excellon_travelz', "excellon_toolchangexy", + 'excellon_cutz', 'excellon_travelz', "excellon_toolchangexy", 'excellon_offset', 'excellon_feedrate', 'excellon_feedrate_rapid', 'excellon_toolchangez', 'excellon_tooldia', 'excellon_slot_tooldia', 'excellon_endz', "excellon_feedrate_probe", "excellon_z_pdepth", "excellon_editor_newdia", "excellon_editor_lin_pitch", diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 159cd1d5..1e0119e5 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -2323,34 +2323,46 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.options.update({ "plot": True, "solid": False, - "drillz": -0.1, + + "operation": "drill", + "milling_type": "drills", + + "milling_dia": 0.04, + + "cutz": -0.1, "multidepth": False, "depthperpass": 0.7, "travelz": 0.1, - "feedrate": 5.0, + "feedrate": self.app.defaults["geometry_feedrate"], + "feedrate_z": 5.0, "feedrate_rapid": 5.0, "tooldia": 0.1, "slot_tooldia": 0.1, "toolchange": False, "toolchangez": 1.0, "toolchangexy": "0.0, 0.0", + "extracut": self.app.defaults["geometry_extracut"], + "extracut_length":self.app.defaults["geometry_extracut_length"], "endz": 2.0, "startz": None, + "offset": 0.0, "spindlespeed": 0, "dwell": True, "dwelltime": 1000, - "ppname_e": 'defaults', + "ppname_e": 'default', + "ppname_g": self.app.defaults["geometry_ppname_g"], "z_pdepth": -0.02, "feedrate_probe": 3.0, - "optimization_type": "R", - "gcode_type": "drills" + "optimization_type": "B", }) # TODO: Document this. self.tool_cbs = dict() - # dict to hold the tool number as key and tool offset as value - self.tool_offset = dict() + # dict that holds the object names and the option name + # the key is the object name (defines in ObjectUI) for each UI element that is a parameter + # particular for a tool and the value is the actual name of the option that the UI element is changing + self.name2option = dict() # default set of data to be added to each tool in self.tools as self.tools[tool]['data'] = self.default_data self.default_data = dict() @@ -2598,8 +2610,17 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): sorted_tools = sorted(sort, key=lambda t1: t1[1]) tools = [i[0] for i in sorted_tools] + new_options = dict() + for opt in self.options: + new_options[opt] = self.options[opt] + for tool_no in tools: + # add the data dictionary for each tool with the default values + self.tools[tool_no]['data'] = deepcopy(new_options) + # self.tools[tool_no]['data']["tooldia"] = self.tools[tool_no]["C"] + # self.tools[tool_no]['data']["slot_tooldia"] = self.tools[tool_no]["C"] + drill_cnt = 0 # variable to store the nr of drills per tool slot_cnt = 0 # variable to store the nr of slots per tool @@ -2631,18 +2652,6 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): slot_count_item = QtWidgets.QTableWidgetItem(slot_count_str) slot_count_item.setFlags(QtCore.Qt.ItemIsEnabled) - try: - t_offset = self.tool_offset[float('%.*f' % (self.decimals, float(self.tools[tool_no]['C'])))] - except KeyError: - t_offset = self.app.defaults['excellon_offset'] - - tool_offset_item = FCDoubleSpinner() - tool_offset_item.set_precision(self.decimals) - tool_offset_item.set_range(-9999.9999, 9999.9999) - tool_offset_item.setWrapping(True) - tool_offset_item.setSingleStep(0.1) if self.units == 'MM' else tool_offset_item.setSingleStep(0.01) - tool_offset_item.set_value(t_offset) - plot_item = FCCheckBox() plot_item.setLayoutDirection(QtCore.Qt.RightToLeft) if self.ui.plot_cb.isChecked(): @@ -2652,7 +2661,6 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.ui.tools_table.setItem(self.tool_row, 1, dia_item) # Diameter self.ui.tools_table.setItem(self.tool_row, 2, drill_count_item) # Number of drills per tool self.ui.tools_table.setItem(self.tool_row, 3, slot_count_item) # Number of drills per tool - self.ui.tools_table.setCellWidget(self.tool_row, 4, tool_offset_item) # Tool offset empty_plot_item = QtWidgets.QTableWidgetItem('') empty_plot_item.setFlags(~QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.ui.tools_table.setItem(self.tool_row, 5, empty_plot_item) @@ -2679,7 +2687,6 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.ui.tools_table.setItem(self.tool_row, 1, label_tot_drill_count) self.ui.tools_table.setItem(self.tool_row, 2, tot_drill_count) # Total number of drills self.ui.tools_table.setItem(self.tool_row, 3, empty_1_1) - self.ui.tools_table.setItem(self.tool_row, 4, empty_1_2) self.ui.tools_table.setItem(self.tool_row, 5, empty_1_3) font = QtGui.QFont() @@ -2711,7 +2718,6 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.ui.tools_table.setItem(self.tool_row, 1, label_tot_slot_count) self.ui.tools_table.setItem(self.tool_row, 2, empty_2_1) self.ui.tools_table.setItem(self.tool_row, 3, tot_slot_count) # Total number of slots - self.ui.tools_table.setItem(self.tool_row, 4, empty_2_2) self.ui.tools_table.setItem(self.tool_row, 5, empty_2_3) for kl in [1, 2, 3]: @@ -2737,13 +2743,11 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): horizontal_header.setDefaultSectionSize(70) horizontal_header.setSectionResizeMode(0, QtWidgets.QHeaderView.Fixed) horizontal_header.resizeSection(0, 20) - if self.app.defaults["global_app_level"] == 'b': - horizontal_header.setSectionResizeMode(1, QtWidgets.QHeaderView.Stretch) - else: - horizontal_header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents) + + horizontal_header.setSectionResizeMode(1, QtWidgets.QHeaderView.Stretch) + horizontal_header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents) horizontal_header.setSectionResizeMode(3, QtWidgets.QHeaderView.ResizeToContents) - horizontal_header.setSectionResizeMode(4, QtWidgets.QHeaderView.Stretch) horizontal_header.setSectionResizeMode(5, QtWidgets.QHeaderView.Fixed) horizontal_header.resizeSection(5, 17) self.ui.tools_table.setColumnWidth(5, 17) @@ -2773,14 +2777,6 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.ui.slot_tooldia_entry.show() self.ui.generate_milling_slots_button.show() - # we reactivate the signals after the after the tool adding as we don't need to see the tool been populated - for row in range(self.ui.tools_table.rowCount()): - try: - offset_spin_widget = self.ui.tools_table.cellWidget(row, 4) - offset_spin_widget.valueChanged.connect(self.on_tool_offset_edit) - except (TypeError, AttributeError): - pass - # set the text on tool_data_label after loading the object sel_rows = list() sel_items = self.ui.tools_table.selectedItems() @@ -2811,33 +2807,71 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.form_fields.update({ "plot": self.ui.plot_cb, "solid": self.ui.solid_cb, - "drillz": self.ui.cutz_entry, + + "operation": self.ui.operation_radio, + "milling_type": self.ui.milling_type_radio, + + "milling_dia": self.ui.mill_dia_entry, + "cutz": self.ui.cutz_entry, "multidepth": self.ui.mpass_cb, "depthperpass": self.ui.maxdepth_entry, "travelz": self.ui.travelz_entry, - "feedrate": self.ui.feedrate_z_entry, + "feedrate_z": self.ui.feedrate_z_entry, + "feedrate": self.ui.xyfeedrate_entry, "feedrate_rapid": self.ui.feedrate_rapid_entry, "tooldia": self.ui.tooldia_entry, "slot_tooldia": self.ui.slot_tooldia_entry, "toolchange": self.ui.toolchange_cb, "toolchangez": self.ui.toolchangez_entry, + "extracut": self.ui.extracut_cb, + "extracut_length": self.ui.e_cut_entry, + "spindlespeed": self.ui.spindlespeed_entry, "dwell": self.ui.dwell_cb, "dwelltime": self.ui.dwelltime_entry, + "startz": self.ui.estartz_entry, "endz": self.ui.endz_entry, + "offset": self.ui.offset_entry, + "ppname_e": self.ui.pp_excellon_name_cb, + "ppname_g": self.ui.pp_geo_name_cb, "z_pdepth": self.ui.pdepth_entry, "feedrate_probe": self.ui.feedrate_probe_entry, - "gcode_type": self.ui.excellon_gcode_type_radio + # "gcode_type": self.ui.excellon_gcode_type_radio }) + self.name2option = { + "e_operation": "operation", + "e_milling_type": "milling_type", + "e_milling_dia": "milling_dia", + "e_cutz" : "cutz", + "e_multidepth" : "multidepth", + "e_depthperpass" : "depthperpass", + + "e_travelz" : "travelz", + "e_feedratexy" : "feedrate", + "e_feedratez" : "feedrate_z", + "e_fr_rapid" : "feedrate_rapid", + "e_extracut" : "extracut", + "e_extracut_length" : "extracut_length", + "e_spindlespeed" : "spindlespeed", + "e_dwell" : "dwell", + "e_dwelltime" : "dwelltime", + "e_offset" : "offset", + } + + # populate Excellon preprocessor combobox list for name in list(self.app.preprocessors.keys()): # the HPGL preprocessor is only for Geometry not for Excellon job therefore don't add it if name == 'hpgl': continue self.ui.pp_excellon_name_cb.addItem(name) + # populate Geometry (milling) preprocessor combobox list + for name in list(self.app.preprocessors.keys()): + self.ui.pp_geo_name_cb.addItem(name) + # Fill form fields self.to_form() @@ -2846,13 +2880,6 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): # self.ui.pp_excellon_name_cb combobox self.on_pp_changed() - # initialize the dict that holds the tools offset - t_default_offset = self.app.defaults["excellon_offset"] - if not self.tool_offset: - for value in self.tools.values(): - dia = float('%.*f' % (self.decimals, float(value['C']))) - self.tool_offset[dia] = t_default_offset - # Show/Hide Advanced Options if self.app.defaults["global_app_level"] == 'b': self.ui.level.setText('%s' % _('Basic')) @@ -2895,6 +2922,17 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.ui.tools_table.clicked.connect(self.on_row_selection_change) self.ui.tools_table.horizontalHeader().sectionClicked.connect(self.on_row_selection_change) + # value changed in the particular parameters of a tool + for key, option in self.name2option.items(): + current_widget = self.form_fields[option] + + if isinstance(current_widget, FCCheckBox): + current_widget.stateChanged.connect(self.form_to_storage) + if isinstance(current_widget, RadioSet): + current_widget.activated_custom.connect(self.form_to_storage) + elif isinstance(current_widget, FCDoubleSpinner) or isinstance(current_widget, FCSpinner): + current_widget.returnPressed.connect(self.form_to_storage) + def ui_disconnect(self): # selective plotting for row in range(self.ui.tools_table.rowCount()): @@ -2917,19 +2955,33 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): except (TypeError, AttributeError): pass - def on_row_selection_change(self): - self.update_ui() + # value changed in the particular parameters of a tool + for key, option in self.name2option.items(): + current_widget = self.form_fields[option] - def update_ui(self, row=None): + if isinstance(current_widget, FCCheckBox): + try: + current_widget.stateChanged.disconnect(self.form_to_storage) + except (TypeError, ValueError): + pass + if isinstance(current_widget, RadioSet): + try: + current_widget.activated_custom.disconnect(self.form_to_storage) + except (TypeError, ValueError): + pass + elif isinstance(current_widget, FCDoubleSpinner) or isinstance(current_widget, FCSpinner): + try: + current_widget.returnPressed.disconnect(self.form_to_storage) + except (TypeError, ValueError): + pass + + def on_row_selection_change(self): self.ui_disconnect() - if row is None: - sel_rows = list() - sel_items = self.ui.tools_table.selectedItems() - for it in sel_items: - sel_rows.append(it.row()) - else: - sel_rows = row if type(row) == list else [row] + sel_rows = list() + sel_items = self.ui.tools_table.selectedItems() + for it in sel_items: + sel_rows.append(it.row()) if not sel_rows: self.ui.tool_data_label.setText( @@ -2961,7 +3013,8 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): try: item = self.ui.tools_table.item(c_row, 0) if type(item) is not None: - tooluid = int(item.text()) + tooluid = item.text() + self.storage_to_form(self.tools[str(tooluid)]['data']) else: self.ui_connect() return @@ -2970,23 +3023,49 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.ui_connect() return - # try: - # # set the form with data from the newly selected tool - # for tooluid_key, tooluid_value in list(self.tools.items()): - # if int(tooluid_key) == tooluid: - # for key, value in tooluid_value.items(): - # if key == 'data': - # form_value_storage = tooluid_value[key] - # self.update_form(form_value_storage) - # except Exception as e: - # log.debug("FlatCAMObj ---> update_ui() " + str(e)) + self.ui_connect() + + def storage_to_form(self, dict_storage): + for form_key in self.form_fields: + for storage_key in dict_storage: + if form_key == storage_key: + try: + self.form_fields[form_key].set_value(dict_storage[form_key]) + except Exception as e: + log.debug("FlatCAMExcellon.storage_to_form() --> %s" % str(e)) + pass + + def form_to_storage(self): + if self.ui.tools_table.rowCount() == 0: + # there is no tool in tool table so we can't save the GUI elements values to storage + return + + self.ui_disconnect() + + widget_changed = self.sender() + wdg_objname = widget_changed.objectName() + option_changed = self.name2option[wdg_objname] + + row = self.ui.tools_table.currentRow() + + if row < 0: + row = 0 + tooluid_item = int(self.ui.tools_table.item(row, 0).text()) + + for tooluid_key, tooluid_val in self.tools.items(): + if int(tooluid_key) == tooluid_item: + new_option_value = self.form_fields[option_changed].get_value() + if option_changed in tooluid_val: + tooluid_val[option_changed] = new_option_value + if option_changed in tooluid_val['data']: + tooluid_val['data'][option_changed] = new_option_value self.ui_connect() def on_operation_type(self, val): if val == 'mill': self.ui.mill_type_label.show() - self.ui.mill_type_radio.show() + self.ui.milling_type_radio.show() self.ui.mill_dia_label.show() self.ui.mill_dia_entry.show() self.ui.frxylabel.show() @@ -2999,7 +3078,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): # self.ui.maxdepth_entry.show() else: self.ui.mill_type_label.hide() - self.ui.mill_type_radio.hide() + self.ui.milling_type_radio.hide() self.ui.mill_dia_label.hide() self.ui.mill_dia_entry.hide() # self.ui.mpass_cb.hide() @@ -3009,32 +3088,6 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.ui.extracut_cb.hide() self.ui.e_cut_entry.hide() - def on_tool_offset_edit(self): - # if connected, disconnect the signal from the slot on item_changed as it creates issues - for row in range(self.ui.tools_table.rowCount()): - try: - # if connected, disconnect the signal from the slot on item_changed as it creates issues - offset_spin_widget = self.ui.tools_table.cellWidget(row, 4) - offset_spin_widget.valueChanged.disconnect() - except (TypeError, AttributeError): - pass - - self.units = self.app.defaults['units'].upper() - self.is_modified = True - - row_of_item_changed = self.ui.tools_table.currentRow() - dia = float('%.*f' % (self.decimals, float(self.ui.tools_table.item(row_of_item_changed, 1).text()))) - - self.tool_offset[dia] = self.sender().get_value() - - # we reactivate the signals after the after the tool editing - for row in range(self.ui.tools_table.rowCount()): - try: - offset_spin_widget = self.ui.tools_table.cellWidget(row, 4) - offset_spin_widget.valueChanged.connect(self.on_tool_offset_edit) - except (TypeError, AttributeError): - pass - def get_selected_tools_list(self): """ Returns the keys to the self.tools dictionary corresponding @@ -3590,15 +3643,14 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): job_obj.options['type'] = 'Excellon' job_obj.options['ppname_e'] = pp_excellon_name - job_obj.z_cut = float(self.options["drillz"]) + job_obj.z_cut = float(self.options["cutz"]) job_obj.multidepth = self.options["multidepth"] job_obj.z_depthpercut = self.options["depthperpass"] - job_obj.tool_offset = self.tool_offset job_obj.z_move = float(self.options["travelz"]) - job_obj.feedrate = float(self.options["feedrate"]) - job_obj.z_feedrate = float(self.options["feedrate"]) + job_obj.feedrate = float(self.options["feedrate_z"]) + job_obj.z_feedrate = float(self.options["feedrate_z"]) job_obj.feedrate_rapid = float(self.options["feedrate_rapid"]) job_obj.spindlespeed = float(self.options["spindlespeed"]) if self.options["spindlespeed"] != 0 else None @@ -3627,7 +3679,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): tools_csv = ','.join(tools) ret_val = job_obj.generate_from_excellon_by_tool( self, tools_csv, - drillz=float(self.options['drillz']), + drillz=float(self.options['cutz']), toolchange=self.options["toolchange"], toolchangexy=self.app.defaults["excellon_toolchangexy"], toolchangez=float(self.options["toolchangez"]), @@ -3754,17 +3806,6 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.ui.plot_cb.setChecked(True) self.ui_connect() - # def plot_element(self, element, color='red', visible=None, layer=None): - # - # visible = visible if visible else self.options['plot'] - # - # try: - # for sub_el in element: - # self.plot_element(sub_el) - # - # except TypeError: # Element is not iterable... - # self.add_shape(shape=element, color=color, visible=visible, layer=0) - def plot(self, visible=None, kind=None): # Does all the required setup and returns False @@ -3819,6 +3860,59 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): except (ObjectDeleted, AttributeError): self.shapes.clear(update=True) + def on_apply_param_to_all_clicked(self): + if self.tools_table.rowCount() == 0: + # there is no tool in tool table so we can't save the GUI elements values to storage + log.debug("NonCopperClear.on_apply_param_to_all_clicked() --> no tool in Tools Table, aborting.") + return + + self.blockSignals(True) + + row = self.tools_table.currentRow() + if row < 0: + row = 0 + + # store all the data associated with the row parameter to the self.tools storage + tooldia_item = float(self.tools_table.item(row, 1).text()) + type_item = self.tools_table.cellWidget(row, 2).currentText() + operation_type_item = self.ui.geo_tools_table.cellWidget(row, 4).currentText() + + nccoffset_item = self.ncc_choice_offset_cb.get_value() + nccoffset_value_item = float(self.ncc_offset_spinner.get_value()) + + # this new dict will hold the actual useful data, another dict that is the value of key 'data' + temp_tools = {} + temp_dia = {} + temp_data = {} + + for tooluid_key, tooluid_value in self.ncc_tools.items(): + for key, value in tooluid_value.items(): + if key == 'data': + # update the 'data' section + for data_key in tooluid_value[key].keys(): + for form_key, form_value in self.form_fields.items(): + if form_key == data_key: + temp_data[data_key] = form_value.get_value() + # make sure we make a copy of the keys not in the form (we may use 'data' keys that are + # updated from self.app.defaults + if data_key not in self.form_fields: + temp_data[data_key] = value[data_key] + temp_dia[key] = deepcopy(temp_data) + temp_data.clear() + + elif key == 'solid_geometry': + temp_dia[key] = deepcopy(self.tools[tooluid_key]['solid_geometry']) + else: + temp_dia[key] = deepcopy(value) + + temp_tools[tooluid_key] = deepcopy(temp_dia) + + self.ncc_tools.clear() + self.ncc_tools = deepcopy(temp_tools) + temp_tools.clear() + + self.blockSignals(False) + class FlatCAMGeometry(FlatCAMObj, Geometry): """ diff --git a/FlatCAMTool.py b/FlatCAMTool.py index 6c51ecb9..02bd08bd 100644 --- a/FlatCAMTool.py +++ b/FlatCAMTool.py @@ -11,6 +11,14 @@ from PyQt5.QtCore import Qt from shapely.geometry import Polygon +import gettext +import FlatCAMTranslation as fcTranslate +import builtins + +fcTranslate.apply_language('strings') +if '_' not in builtins.__dict__: + _ = gettext.gettext + class FlatCAMTool(QtWidgets.QWidget): @@ -138,3 +146,17 @@ class FlatCAMTool(QtWidgets.QWidget): def delete_tool_selection_shape(self): self.app.tool_shapes.clear() self.app.tool_shapes.redraw() + + def confirmation_message(self, accepted, minval, maxval): + if accepted is False: + self.app.inform.emit('[WARNING_NOTCL] %s: [%.*f, %.*f]' % + (_("Edited value is out of range"), self.decimals, minval, self.decimals, maxval)) + else: + self.app.inform.emit('[success] %s' % _("Edited value is within limits.")) + + def confirmation_message_int(self, accepted, minval, maxval): + if accepted is False: + self.app.inform.emit('[WARNING_NOTCL] %s: [%d, %d]' % + (_("Edited value is out of range"), minval, maxval)) + else: + self.app.inform.emit('[success] %s' % _("Edited value is within limits.")) diff --git a/README.md b/README.md index 7e948bd3..501d28a0 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,13 @@ CAD program, and create G-Code for Isolation routing. ================================================= +17.02.2020 + +- updated the Excellon UI to hold data for each tool +- in Excellon UI removed the tools table column for Offset Z and used the UI form parameter +- updated the Excellon Editor to add for each tool a 'data' dictionary +- updated all FlatCAM tools to use the new confirmation message that show if the entered value is within range or outside + 16.02.2020 - small update to NCC Tool UI diff --git a/camlib.py b/camlib.py index 52bd863c..f296b113 100644 --- a/camlib.py +++ b/camlib.py @@ -2432,7 +2432,6 @@ class CNCjob(Geometry): self.units = units self.z_cut = z_cut - self.tool_offset = dict() self.z_move = z_move @@ -2728,7 +2727,7 @@ class CNCjob(Geometry): ) try: - z_off = float(self.tool_offset[it[1]]) * (-1) + z_off = float(exobj.tools[it[0]]['data']['offset']) * (-1) except KeyError: z_off = 0 @@ -2936,7 +2935,7 @@ class CNCjob(Geometry): # TODO apply offset only when using the GUI, for TclCommand this will create an error # because the values for Z offset are created in build_ui() try: - z_offset = float(self.tool_offset[current_tooldia]) * (-1) + z_offset = float(exobj.tools[tool]['data']['offset']) * (-1) except KeyError: z_offset = 0 self.z_cut = z_offset + old_zcut @@ -3104,7 +3103,7 @@ class CNCjob(Geometry): # TODO apply offset only when using the GUI, for TclCommand this will create an error # because the values for Z offset are created in build_ui() try: - z_offset = float(self.tool_offset[current_tooldia]) * (-1) + z_offset = float(exobj.tools[tool]['data']['offset']) * (-1) except KeyError: z_offset = 0 self.z_cut = z_offset + old_zcut @@ -3230,7 +3229,7 @@ class CNCjob(Geometry): # TODO apply offset only when using the GUI, for TclCommand this will create an error # because the values for Z offset are created in build_ui() try: - z_offset = float(self.tool_offset[current_tooldia]) * (-1) + z_offset = float(exobj.tools[tool]['data']['offset']) * (-1) except KeyError: z_offset = 0 self.z_cut = z_offset + old_zcut diff --git a/flatcamEditors/FlatCAMExcEditor.py b/flatcamEditors/FlatCAMExcEditor.py index a4136d3c..5897b9cb 100644 --- a/flatcamEditors/FlatCAMExcEditor.py +++ b/flatcamEditors/FlatCAMExcEditor.py @@ -2074,7 +2074,6 @@ class FlatCAMExcEditor(QtCore.QObject): self.new_drills = list() self.new_tools = dict() self.new_slots = list() - self.new_tool_offset = dict() # dictionary to store the tool_row and diameters in Tool_table # it will be updated everytime self.build_ui() is called @@ -2186,6 +2185,42 @@ class FlatCAMExcEditor(QtCore.QObject): if option in self.app.options: self.options[option] = self.app.options[option] + self.data_defaults = { + "plot": self.app.defaults["excellon_plot"], + "solid": self.app.defaults["excellon_solid"], + + "operation": self.app.defaults["excellon_operation"], + "milling_type": self.app.defaults["excellon_milling_type"], + + "milling_dia":self.app.defaults["excellon_milling_dia"], + + "cutz": self.app.defaults["excellon_cutz"], + "multidepth": self.app.defaults["excellon_multidepth"], + "depthperpass": self.app.defaults["excellon_depthperpass"], + "travelz": self.app.defaults["excellon_travelz"], + "feedrate": self.app.defaults["geometry_feedrate"], + "feedrate_z": self.app.defaults["excellon_feedrate_z"], + "feedrate_rapid": self.app.defaults["excellon_feedrate_rapid"], + "tooldia": self.app.defaults["excellon_tooldia"], + "slot_tooldia": self.app.defaults["excellon_slot_tooldia"], + "toolchange": self.app.defaults["excellon_toolchange"], + "toolchangez": self.app.defaults["excellon_toolchangez"], + "toolchangexy": self.app.defaults["excellon_toolchangexy"], + "extracut": self.app.defaults["geometry_extracut"], + "extracut_length": self.app.defaults["geometry_extracut_length"], + "endz": self.app.defaults["excellon_endz"], + "startz": self.app.defaults["excellon_startz"], + "offset": self.app.defaults["excellon_offset"], + "spindlespeed": self.app.defaults["excellon_spindlespeed"], + "dwell": self.app.defaults["excellon_dwell"], + "dwelltime": self.app.defaults["excellon_dwelltime"], + "ppname_e": self.app.defaults["excellon_ppname_e"], + "ppname_g": self.app.defaults["geometry_ppname_g"], + "z_pdepth": self.app.defaults["excellon_z_pdepth"], + "feedrate_probe": self.app.defaults["excellon_feedrate_probe"], + "optimization_type": self.app.defaults["excellon_optimization_type"] + } + self.rtree_exc_index = rtindex.Index() # flag to show if the object was modified self.is_modified = False @@ -2592,9 +2627,6 @@ class FlatCAMExcEditor(QtCore.QObject): for deleted_tool_dia in deleted_tool_dia_list: - # delete de tool offset - self.exc_obj.tool_offset.pop(float(deleted_tool_dia), None) - # delete the storage used for that tool storage_elem = FlatCAMGeoEditor.make_storage() self.storage_dict[deleted_tool_dia] = storage_elem @@ -2795,7 +2827,7 @@ class FlatCAMExcEditor(QtCore.QObject): self.new_drills = [] self.new_tools = {} self.new_slots = [] - self.new_tool_offset = {} + self.olddia_newdia = {} self.shapes.enabled = True @@ -3036,8 +3068,8 @@ class FlatCAMExcEditor(QtCore.QObject): self.exc_obj = exc_obj exc_obj.visible = False - self.points_edit = {} - self.slot_points_edit = {} + self.points_edit = dict() + self.slot_points_edit = dict() # Set selection tolerance # DrawToolShape.tolerance = fc_excellon.drawing_tolerance * 10 @@ -3268,7 +3300,6 @@ class FlatCAMExcEditor(QtCore.QObject): self.edited_obj_name += "_1" else: self.edited_obj_name += "_edit" - self.new_tool_offset = self.exc_obj.tool_offset self.app.worker_task.emit({'fcn': self.new_edited_excellon, 'params': [self.edited_obj_name, @@ -3316,9 +3347,14 @@ class FlatCAMExcEditor(QtCore.QObject): excellon_obj.drills = deepcopy(new_drills) excellon_obj.tools = deepcopy(new_tools) excellon_obj.slots = deepcopy(new_slots) - excellon_obj.tool_offset = self.new_tool_offset + excellon_obj.options['name'] = outname + # add a 'data' dict for each tool with the default values + for tool in excellon_obj.tools: + excellon_obj.tools[tool]['data'] = dict() + excellon_obj.tools[tool]['data'].update(deepcopy(self.data_defaults)) + try: excellon_obj.create_geometry() except KeyError: diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index 5a2f62c2..ab30498d 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -779,7 +779,7 @@ class ExcellonObjectUI(ObjectUI): self.tools_table.setColumnCount(6) self.tools_table.setHorizontalHeaderLabels(['#', _('Diameter'), _('Drills'), _('Slots'), - _('Offset Z'), 'P']) + "NOT USED", 'P']) self.tools_table.setSortingEnabled(False) self.tools_table.horizontalHeaderItem(0).setToolTip( @@ -796,14 +796,13 @@ class ExcellonObjectUI(ObjectUI): self.tools_table.horizontalHeaderItem(3).setToolTip( _("The number of Slot holes. Holes that are created by\n" "milling them with an endmill bit.")) - self.tools_table.horizontalHeaderItem(4).setToolTip( - _("Some drill bits (the larger ones) need to drill deeper\n" - "to create the desired exit hole diameter due of the tip shape.\n" - "The value here can compensate the Cut Z parameter.")) self.tools_table.horizontalHeaderItem(5).setToolTip( _("Toggle display of the drills for the current tool.\n" "This does not select the tools for G-code generation.")) + # this column is not used; reserved for future usage + self.tools_table.setColumnHidden(4, True) + self.tools_box.addWidget(QtWidgets.QLabel('')) # ########################################################### @@ -855,6 +854,7 @@ class ExcellonObjectUI(ObjectUI): {'label': _("Milling"), 'value': 'mill'} ] ) + self.operation_radio.setObjectName("e_operation") self.grid3.addWidget(self.operation_label, 0, 0) self.grid3.addWidget(self.operation_radio, 0, 1) @@ -871,16 +871,17 @@ class ExcellonObjectUI(ObjectUI): "- Slots -> will mill the slots associated with this tool\n" "- Both -> will mill both drills and mills or whatever is available") ) - self.mill_type_radio = RadioSet( + self.milling_type_radio = RadioSet( [ {'label': _('Drills'), 'value': 'drills'}, {'label': _("Slots"), 'value': 'slots'}, {'label': _("Both"), 'value': 'both'}, ] ) + self.milling_type_radio.setObjectName("e_milling_type") self.grid3.addWidget(self.mill_type_label, 2, 0) - self.grid3.addWidget(self.mill_type_radio, 2, 1) + self.grid3.addWidget(self.milling_type_radio, 2, 1) self.mill_dia_label = QtWidgets.QLabel('%s:' % _('Milling Diameter')) self.mill_dia_label.setToolTip( @@ -890,6 +891,7 @@ class ExcellonObjectUI(ObjectUI): self.mill_dia_entry = FCDoubleSpinner(callback=self.confirmation_message) self.mill_dia_entry.set_precision(self.decimals) self.mill_dia_entry.set_range(0.0000, 9999.9999) + self.mill_dia_entry.setObjectName("e_milling_dia") self.grid3.addWidget(self.mill_dia_label, 3, 0) self.grid3.addWidget(self.mill_dia_entry, 3, 1) @@ -910,6 +912,7 @@ class ExcellonObjectUI(ObjectUI): self.cutz_entry.set_range(-9999.9999, 9999.9999) self.cutz_entry.setSingleStep(0.1) + self.cutz_entry.setObjectName("e_cutz") self.grid3.addWidget(self.cutzlabel, 4, 0) self.grid3.addWidget(self.cutz_entry, 4, 1) @@ -924,6 +927,7 @@ class ExcellonObjectUI(ObjectUI): "reached." ) ) + self.mpass_cb.setObjectName("e_multidepth") self.maxdepth_entry = FCDoubleSpinner(callback=self.confirmation_message) self.maxdepth_entry.set_precision(self.decimals) @@ -931,6 +935,8 @@ class ExcellonObjectUI(ObjectUI): self.maxdepth_entry.setSingleStep(0.1) self.maxdepth_entry.setToolTip(_("Depth of each pass (positive).")) + self.maxdepth_entry.setObjectName("e_depthperpass") + self.mis_mpass_geo = OptionalInputSection(self.mpass_cb, [self.maxdepth_entry]) self.grid3.addWidget(self.mpass_cb, 5, 0) @@ -952,6 +958,7 @@ class ExcellonObjectUI(ObjectUI): self.travelz_entry.set_range(-9999.9999, 9999.9999) self.travelz_entry.setSingleStep(0.1) + self.travelz_entry.setObjectName("e_travelz") self.grid3.addWidget(self.travelzlabel, 6, 0) self.grid3.addWidget(self.travelz_entry, 6, 1) @@ -966,6 +973,7 @@ class ExcellonObjectUI(ObjectUI): self.xyfeedrate_entry.set_precision(self.decimals) self.xyfeedrate_entry.set_range(0, 9999.9999) self.xyfeedrate_entry.setSingleStep(0.1) + self.xyfeedrate_entry.setObjectName("e_feedratexy") self.grid3.addWidget(self.frxylabel, 12, 0) self.grid3.addWidget(self.xyfeedrate_entry, 12, 1) @@ -982,6 +990,7 @@ class ExcellonObjectUI(ObjectUI): self.feedrate_z_entry.set_precision(self.decimals) self.feedrate_z_entry.set_range(0.0, 99999.9999) self.feedrate_z_entry.setSingleStep(0.1) + self.feedrate_z_entry.setObjectName("e_feedratez") self.grid3.addWidget(self.frzlabel, 14, 0) self.grid3.addWidget(self.feedrate_z_entry, 14, 1) @@ -999,6 +1008,7 @@ class ExcellonObjectUI(ObjectUI): self.feedrate_rapid_entry.set_precision(self.decimals) self.feedrate_rapid_entry.set_range(0.0, 99999.9999) self.feedrate_rapid_entry.setSingleStep(0.1) + self.feedrate_rapid_entry.setObjectName("e_fr_rapid") self.grid3.addWidget(self.feedrate_rapid_label, 16, 0) self.grid3.addWidget(self.feedrate_rapid_entry, 16, 1) @@ -1015,6 +1025,7 @@ class ExcellonObjectUI(ObjectUI): "meet with last cut, we generate an\n" "extended cut over the first cut section.") ) + self.extracut_cb.setObjectName("e_extracut") self.e_cut_entry = FCDoubleSpinner(callback=self.confirmation_message) self.e_cut_entry.set_range(0, 99999) @@ -1027,6 +1038,7 @@ class ExcellonObjectUI(ObjectUI): "meet with last cut, we generate an\n" "extended cut over the first cut section.") ) + self.e_cut_entry.setObjectName("e_extracut_length") self.ois_recut = OptionalInputSection(self.extracut_cb, [self.e_cut_entry]) @@ -1043,6 +1055,7 @@ class ExcellonObjectUI(ObjectUI): self.spindlespeed_entry = FCSpinner(callback=self.confirmation_message_int) self.spindlespeed_entry.set_range(0, 1000000) self.spindlespeed_entry.setSingleStep(100) + self.spindlespeed_entry.setObjectName("e_spindlespeed") self.grid3.addWidget(self.spindle_label, 19, 0) self.grid3.addWidget(self.spindlespeed_entry, 19, 1) @@ -1053,6 +1066,8 @@ class ExcellonObjectUI(ObjectUI): _("Pause to allow the spindle to reach its\n" "speed before cutting.") ) + self.dwell_cb.setObjectName("e_dwell") + self.dwelltime_entry = FCDoubleSpinner(callback=self.confirmation_message) self.dwelltime_entry.set_precision(self.decimals) self.dwelltime_entry.set_range(0.0, 9999.9999) @@ -1061,47 +1076,13 @@ class ExcellonObjectUI(ObjectUI): self.dwelltime_entry.setToolTip( _("Number of time units for spindle to dwell.") ) + self.dwelltime_entry.setObjectName("e_dwelltime") self.grid3.addWidget(self.dwell_cb, 20, 0) self.grid3.addWidget(self.dwelltime_entry, 20, 1) self.ois_dwell = OptionalInputSection(self.dwell_cb, [self.dwelltime_entry]) - # Probe depth - self.pdepth_label = QtWidgets.QLabel('%s:' % _("Probe Z depth")) - self.pdepth_label.setToolTip( - _("The maximum depth that the probe is allowed\n" - "to probe. Negative value, in current units.") - ) - - self.pdepth_entry = FCDoubleSpinner(callback=self.confirmation_message) - self.pdepth_entry.set_precision(self.decimals) - self.pdepth_entry.set_range(-9999.9999, 9999.9999) - self.pdepth_entry.setSingleStep(0.1) - - self.grid3.addWidget(self.pdepth_label, 22, 0) - self.grid3.addWidget(self.pdepth_entry, 22, 1) - - self.pdepth_label.hide() - self.pdepth_entry.setVisible(False) - - # Probe feedrate - self.feedrate_probe_label = QtWidgets.QLabel('%s:' % _("Feedrate Probe")) - self.feedrate_probe_label.setToolTip( - _("The feedrate used while the probe is probing.") - ) - - self.feedrate_probe_entry = FCDoubleSpinner(callback=self.confirmation_message) - self.feedrate_probe_entry.set_precision(self.decimals) - self.feedrate_probe_entry.set_range(0.0, 9999.9999) - self.feedrate_probe_entry.setSingleStep(0.1) - - self.grid3.addWidget(self.feedrate_probe_label, 24, 0) - self.grid3.addWidget(self.feedrate_probe_entry, 24, 1) - - self.feedrate_probe_label.hide() - self.feedrate_probe_entry.setVisible(False) - # Tool Offset self.tool_offset_label = QtWidgets.QLabel('%s:' % _('Offset Z')) self.tool_offset_label.setToolTip( @@ -1113,6 +1094,7 @@ class ExcellonObjectUI(ObjectUI): self.offset_entry = FCDoubleSpinner(callback=self.confirmation_message) self.offset_entry.set_precision(self.decimals) self.offset_entry.set_range(-9999.9999, 9999.9999) + self.offset_entry.setObjectName("e_offset") self.grid3.addWidget(self.tool_offset_label, 25, 0) self.grid3.addWidget(self.offset_entry, 25, 1) @@ -1121,37 +1103,38 @@ class ExcellonObjectUI(ObjectUI): # ################# GRID LAYOUT 4 ############################### # ################################################################# - self.grid4 = QtWidgets.QGridLayout() - self.exc_tools_box.addLayout(self.grid4) - self.grid4.setColumnStretch(0, 0) - self.grid4.setColumnStretch(1, 1) - - # choose_tools_label = QtWidgets.QLabel( - # _("Select from the Tools Table above the hole dias to be\n" - # "drilled. Use the # column to make the selection.") + # self.grid4 = QtWidgets.QGridLayout() + # self.exc_tools_box.addLayout(self.grid4) + # self.grid4.setColumnStretch(0, 0) + # self.grid4.setColumnStretch(1, 1) + # + # # choose_tools_label = QtWidgets.QLabel( + # # _("Select from the Tools Table above the hole dias to be\n" + # # "drilled. Use the # column to make the selection.") + # # ) + # # grid2.addWidget(choose_tools_label, 0, 0, 1, 3) + # + # # ### Choose what to use for Gcode creation: Drills, Slots or Both + # gcode_type_label = QtWidgets.QLabel('%s' % _('Gcode')) + # gcode_type_label.setToolTip( + # _("Choose what to use for GCode generation:\n" + # "'Drills', 'Slots' or 'Both'.\n" + # "When choosing 'Slots' or 'Both', slots will be\n" + # "converted to a series of drills.") # ) - # grid2.addWidget(choose_tools_label, 0, 0, 1, 3) - - # ### Choose what to use for Gcode creation: Drills, Slots or Both - gcode_type_label = QtWidgets.QLabel('%s' % _('Gcode')) - gcode_type_label.setToolTip( - _("Choose what to use for GCode generation:\n" - "'Drills', 'Slots' or 'Both'.\n" - "When choosing 'Slots' or 'Both', slots will be\n" - "converted to a series of drills.") - ) - self.excellon_gcode_type_radio = RadioSet([{'label': 'Drills', 'value': 'drills'}, - {'label': 'Slots', 'value': 'slots'}, - {'label': 'Both', 'value': 'both'}]) - self.grid4.addWidget(gcode_type_label, 1, 0) - self.grid4.addWidget(self.excellon_gcode_type_radio, 1, 1) - # temporary action until I finish the feature - self.excellon_gcode_type_radio.setVisible(False) - gcode_type_label.hide() + # self.excellon_gcode_type_radio = RadioSet([{'label': 'Drills', 'value': 'drills'}, + # {'label': 'Slots', 'value': 'slots'}, + # {'label': 'Both', 'value': 'both'}]) + # self.grid4.addWidget(gcode_type_label, 1, 0) + # self.grid4.addWidget(self.excellon_gcode_type_radio, 1, 1) + # # temporary action until I finish the feature + # self.excellon_gcode_type_radio.setVisible(False) + # gcode_type_label.hide() # ################################################################# # ################# GRID LAYOUT 5 ############################### # ################################################################# + # ################# COMMON PARAMETERS ############################# self.grid5 = QtWidgets.QGridLayout() self.grid5.setColumnStretch(0, 0) @@ -1236,21 +1219,70 @@ class ExcellonObjectUI(ObjectUI): self.grid5.addWidget(self.endz_label, 11, 0) self.grid5.addWidget(self.endz_entry, 11, 1) - # Preprocessor selection - pp_excellon_label = QtWidgets.QLabel('%s:' % _("Preprocessor")) + # Probe depth + self.pdepth_label = QtWidgets.QLabel('%s:' % _("Probe Z depth")) + self.pdepth_label.setToolTip( + _("The maximum depth that the probe is allowed\n" + "to probe. Negative value, in current units.") + ) + + self.pdepth_entry = FCDoubleSpinner(callback=self.confirmation_message) + self.pdepth_entry.set_precision(self.decimals) + self.pdepth_entry.set_range(-9999.9999, 9999.9999) + self.pdepth_entry.setSingleStep(0.1) + + self.grid5.addWidget(self.pdepth_label, 12, 0) + self.grid5.addWidget(self.pdepth_entry, 12, 1) + + self.pdepth_label.hide() + self.pdepth_entry.setVisible(False) + + # Probe feedrate + self.feedrate_probe_label = QtWidgets.QLabel('%s:' % _("Feedrate Probe")) + self.feedrate_probe_label.setToolTip( + _("The feedrate used while the probe is probing.") + ) + + self.feedrate_probe_entry = FCDoubleSpinner(callback=self.confirmation_message) + self.feedrate_probe_entry.set_precision(self.decimals) + self.feedrate_probe_entry.set_range(0.0, 9999.9999) + self.feedrate_probe_entry.setSingleStep(0.1) + self.feedrate_probe_entry.setObjectName(_("e_fr_probe")) + + self.grid5.addWidget(self.feedrate_probe_label, 13, 0) + self.grid5.addWidget(self.feedrate_probe_entry, 13, 1) + + self.feedrate_probe_label.hide() + self.feedrate_probe_entry.setVisible(False) + + # Preprocessor Excellon selection + pp_excellon_label = QtWidgets.QLabel('%s:' % _("Preprocessor E")) pp_excellon_label.setToolTip( _("The preprocessor JSON file that dictates\n" - "Gcode output.") + "Gcode output for Excellon Objects.") ) self.pp_excellon_name_cb = FCComboBox() self.pp_excellon_name_cb.setFocusPolicy(QtCore.Qt.StrongFocus) - self.grid5.addWidget(pp_excellon_label, 12, 0) - self.grid5.addWidget(self.pp_excellon_name_cb, 12, 1) + + self.grid5.addWidget(pp_excellon_label, 14, 0) + self.grid5.addWidget(self.pp_excellon_name_cb, 14, 1) + + # Preprocessor Geometry selection + pp_geo_label = QtWidgets.QLabel('%s:' % _("Preprocessor G")) + pp_geo_label.setToolTip( + _("The preprocessor JSON file that dictates\n" + "Gcode output for Geometry (Milling) Objects.") + ) + self.pp_geo_name_cb = FCComboBox() + self.pp_geo_name_cb.setFocusPolicy(QtCore.Qt.StrongFocus) + + self.grid5.addWidget(pp_geo_label, 15, 0) + self.grid5.addWidget(self.pp_geo_name_cb, 15, 1) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - self.grid5.addWidget(separator_line, 13, 0, 1, 2) + self.grid5.addWidget(separator_line, 16, 0, 1, 2) # ################################################################# # ################# GRID LAYOUT 6 ############################### diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index 305179fd..e3fd5fff 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -3079,6 +3079,53 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): grid2.setColumnStretch(0, 0) grid2.setColumnStretch(1, 1) + # Operation Type + self.operation_label = QtWidgets.QLabel('%s:' % _('Operation')) + self.operation_label.setToolTip( + _("Operation type:\n" + "- Drilling -> will drill the drills/slots associated with this tool\n" + "- Milling -> will mill the drills/slots") + ) + self.operation_radio = RadioSet( + [ + {'label': _('Drilling'), 'value': 'drill'}, + {'label': _("Milling"), 'value': 'mill'} + ] + ) + + grid2.addWidget(self.operation_label, 0, 0) + grid2.addWidget(self.operation_radio, 0, 1) + + self.mill_type_label = QtWidgets.QLabel('%s:' % _('Milling Type')) + self.mill_type_label.setToolTip( + _("Milling type:\n" + "- Drills -> will mill the drills associated with this tool\n" + "- Slots -> will mill the slots associated with this tool\n" + "- Both -> will mill both drills and mills or whatever is available") + ) + self.milling_type_radio = RadioSet( + [ + {'label': _('Drills'), 'value': 'drills'}, + {'label': _("Slots"), 'value': 'slots'}, + {'label': _("Both"), 'value': 'both'}, + ] + ) + + grid2.addWidget(self.mill_type_label, 1, 0) + grid2.addWidget(self.milling_type_radio, 1, 1) + + self.mill_dia_label = QtWidgets.QLabel('%s:' % _('Milling Diameter')) + self.mill_dia_label.setToolTip( + _("The diameter of the tool who will do the milling") + ) + + self.mill_dia_entry = FCDoubleSpinner() + self.mill_dia_entry.set_precision(self.decimals) + self.mill_dia_entry.set_range(0.0000, 9999.9999) + + grid2.addWidget(self.mill_dia_label, 2, 0) + grid2.addWidget(self.mill_dia_entry, 2, 1) + # Cut Z cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z')) cutzlabel.setToolTip( @@ -3096,8 +3143,8 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): self.cutz_entry.setSingleStep(0.1) self.cutz_entry.set_precision(self.decimals) - grid2.addWidget(cutzlabel, 0, 0) - grid2.addWidget(self.cutz_entry, 0, 1) + grid2.addWidget(cutzlabel, 3, 0) + grid2.addWidget(self.cutz_entry, 3, 1) # Multi-Depth self.mpass_cb = FCCheckBox('%s:' % _("Multi-Depth")) @@ -3117,8 +3164,8 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): self.maxdepth_entry.setToolTip(_("Depth of each pass (positive).")) - grid2.addWidget(self.mpass_cb, 1, 0) - grid2.addWidget(self.maxdepth_entry, 1, 1) + grid2.addWidget(self.mpass_cb, 4, 0) + grid2.addWidget(self.maxdepth_entry, 4, 1) # Travel Z travelzlabel = QtWidgets.QLabel('%s:' % _('Travel Z')) @@ -3135,8 +3182,8 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): else: self.travelz_entry.set_range(-9999.9999, 9999.9999) - grid2.addWidget(travelzlabel, 2, 0) - grid2.addWidget(self.travelz_entry, 2, 1) + grid2.addWidget(travelzlabel, 5, 0) + grid2.addWidget(self.travelz_entry, 5, 1) # Tool change: self.toolchange_cb = FCCheckBox('%s' % _("Tool change")) @@ -3144,7 +3191,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): _("Include tool-change sequence\n" "in G-Code (Pause for tool change).") ) - grid2.addWidget(self.toolchange_cb, 3, 0, 1, 2) + grid2.addWidget(self.toolchange_cb, 6, 0, 1, 2) # Tool Change Z toolchangezlabel = QtWidgets.QLabel('%s:' % _('Toolchange Z')) @@ -3161,8 +3208,8 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): else: self.toolchangez_entry.set_range(-9999.9999, 9999.9999) - grid2.addWidget(toolchangezlabel, 4, 0) - grid2.addWidget(self.toolchangez_entry, 4, 1) + grid2.addWidget(toolchangezlabel, 7, 0) + grid2.addWidget(self.toolchangez_entry, 7, 1) # End Move Z endz_label = QtWidgets.QLabel('%s:' % _('End move Z')) @@ -3178,8 +3225,8 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): else: self.endz_entry.set_range(-9999.9999, 9999.9999) - grid2.addWidget(endz_label, 5, 0) - grid2.addWidget(self.endz_entry, 5, 1) + grid2.addWidget(endz_label, 8, 0) + grid2.addWidget(self.endz_entry, 8, 1) # Feedrate Z frlabel = QtWidgets.QLabel('%s:' % _('Feedrate Z')) @@ -3193,8 +3240,8 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): self.feedrate_z_entry.set_precision(self.decimals) self.feedrate_z_entry.set_range(0, 99999.9999) - grid2.addWidget(frlabel, 6, 0) - grid2.addWidget(self.feedrate_z_entry, 6, 1) + grid2.addWidget(frlabel, 9, 0) + grid2.addWidget(self.feedrate_z_entry, 9, 1) # Spindle speed spdlabel = QtWidgets.QLabel('%s:' % _('Spindle Speed')) diff --git a/flatcamParsers/ParseExcellon.py b/flatcamParsers/ParseExcellon.py index a82cf401..059e09f3 100644 --- a/flatcamParsers/ParseExcellon.py +++ b/flatcamParsers/ParseExcellon.py @@ -43,6 +43,7 @@ class Excellon(Geometry): ================ ==================================== C Diameter of the tool solid_geometry Geometry list for each tool + data dictionary which holds the options for each tool Others Not supported (Ignored). ================ ==================================== diff --git a/flatcamTools/ToolCalculators.py b/flatcamTools/ToolCalculators.py index 3a7ff665..a5b0afca 100644 --- a/flatcamTools/ToolCalculators.py +++ b/flatcamTools/ToolCalculators.py @@ -92,7 +92,7 @@ class ToolCalculator(FlatCAMTool): self.layout.addLayout(form_layout) self.tipDia_label = QtWidgets.QLabel('%s:' % _("Tip Diameter")) - self.tipDia_entry = FCDoubleSpinner() + self.tipDia_entry = FCDoubleSpinner(callback=self.confirmation_message) self.tipDia_entry.set_precision(self.decimals) self.tipDia_entry.set_range(0.0, 9999.9999) self.tipDia_entry.setSingleStep(0.1) @@ -112,7 +112,7 @@ class ToolCalculator(FlatCAMTool): "It is specified by manufacturer.")) self.cutDepth_label = QtWidgets.QLabel('%s:' % _("Cut Z")) - self.cutDepth_entry = FCDoubleSpinner() + self.cutDepth_entry = FCDoubleSpinner(callback=self.confirmation_message) self.cutDepth_entry.set_range(-9999.9999, 9999.9999) self.cutDepth_entry.set_precision(self.decimals) @@ -121,7 +121,7 @@ class ToolCalculator(FlatCAMTool): "In the CNCJob is the CutZ parameter.")) self.effectiveToolDia_label = QtWidgets.QLabel('%s:' % _("Tool Diameter")) - self.effectiveToolDia_entry = FCDoubleSpinner() + self.effectiveToolDia_entry = FCDoubleSpinner(callback=self.confirmation_message) self.effectiveToolDia_entry.set_precision(self.decimals) # self.effectiveToolDia_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) @@ -165,7 +165,7 @@ class ToolCalculator(FlatCAMTool): self.layout.addLayout(plate_form_layout) self.pcblengthlabel = QtWidgets.QLabel('%s:' % _("Board Length")) - self.pcblength_entry = FCDoubleSpinner() + self.pcblength_entry = FCDoubleSpinner(callback=self.confirmation_message) self.pcblength_entry.set_precision(self.decimals) self.pcblength_entry.set_range(0.0, 9999.9999) @@ -173,7 +173,7 @@ class ToolCalculator(FlatCAMTool): self.pcblengthlabel.setToolTip(_('This is the board length. In centimeters.')) self.pcbwidthlabel = QtWidgets.QLabel('%s:' % _("Board Width")) - self.pcbwidth_entry = FCDoubleSpinner() + self.pcbwidth_entry = FCDoubleSpinner(callback=self.confirmation_message) self.pcbwidth_entry.set_precision(self.decimals) self.pcbwidth_entry.set_range(0.0, 9999.9999) @@ -181,7 +181,7 @@ class ToolCalculator(FlatCAMTool): self.pcbwidthlabel.setToolTip(_('This is the board width.In centimeters.')) self.cdensity_label = QtWidgets.QLabel('%s:' % _("Current Density")) - self.cdensity_entry = FCDoubleSpinner() + self.cdensity_entry = FCDoubleSpinner(callback=self.confirmation_message) self.cdensity_entry.set_precision(self.decimals) self.cdensity_entry.set_range(0.0, 9999.9999) self.cdensity_entry.setSingleStep(0.1) @@ -191,7 +191,7 @@ class ToolCalculator(FlatCAMTool): "In Amps per Square Feet ASF.")) self.growth_label = QtWidgets.QLabel('%s:' % _("Copper Growth")) - self.growth_entry = FCDoubleSpinner() + self.growth_entry = FCDoubleSpinner(callback=self.confirmation_message) self.growth_entry.set_precision(self.decimals) self.growth_entry.set_range(0.0, 9999.9999) self.growth_entry.setSingleStep(0.01) @@ -203,7 +203,7 @@ class ToolCalculator(FlatCAMTool): # self.growth_entry.setEnabled(False) self.cvaluelabel = QtWidgets.QLabel('%s:' % _("Current Value")) - self.cvalue_entry = FCDoubleSpinner() + self.cvalue_entry = FCDoubleSpinner(callback=self.confirmation_message) self.cvalue_entry.set_precision(self.decimals) self.cvalue_entry.set_range(0.0, 9999.9999) self.cvalue_entry.setSingleStep(0.1) @@ -214,7 +214,7 @@ class ToolCalculator(FlatCAMTool): self.cvalue_entry.setReadOnly(True) self.timelabel = QtWidgets.QLabel('%s:' % _("Time")) - self.time_entry = FCDoubleSpinner() + self.time_entry = FCDoubleSpinner(callback=self.confirmation_message) self.time_entry.set_precision(self.decimals) self.time_entry.set_range(0.0, 9999.9999) self.time_entry.setSingleStep(0.1) diff --git a/flatcamTools/ToolCalibration.py b/flatcamTools/ToolCalibration.py index fa533f9e..cc964b1a 100644 --- a/flatcamTools/ToolCalibration.py +++ b/flatcamTools/ToolCalibration.py @@ -76,7 +76,7 @@ class ToolCalibration(FlatCAMTool): _("Height (Z) for travelling between the points.") ) - self.travelz_entry = FCDoubleSpinner() + self.travelz_entry = FCDoubleSpinner(callback=self.confirmation_message) self.travelz_entry.set_range(-9999.9999, 9999.9999) self.travelz_entry.set_precision(self.decimals) self.travelz_entry.setSingleStep(0.1) @@ -90,7 +90,7 @@ class ToolCalibration(FlatCAMTool): _("Height (Z) for checking the point.") ) - self.verz_entry = FCDoubleSpinner() + self.verz_entry = FCDoubleSpinner(callback=self.confirmation_message) self.verz_entry.set_range(-9999.9999, 9999.9999) self.verz_entry.set_precision(self.decimals) self.verz_entry.setSingleStep(0.1) @@ -113,7 +113,7 @@ class ToolCalibration(FlatCAMTool): _("Height (Z) for mounting the verification probe.") ) - self.toolchangez_entry = FCDoubleSpinner() + self.toolchangez_entry = FCDoubleSpinner(callback=self.confirmation_message) self.toolchangez_entry.set_range(0.0000, 9999.9999) self.toolchangez_entry.set_precision(self.decimals) self.toolchangez_entry.setSingleStep(0.1) @@ -471,7 +471,7 @@ class ToolCalibration(FlatCAMTool): self.scalex_label.setToolTip( _("Factor for Scale action over X axis.") ) - self.scalex_entry = FCDoubleSpinner() + self.scalex_entry = FCDoubleSpinner(callback=self.confirmation_message) self.scalex_entry.set_range(0, 9999.9999) self.scalex_entry.set_precision(self.decimals) self.scalex_entry.setSingleStep(0.1) @@ -483,7 +483,7 @@ class ToolCalibration(FlatCAMTool): self.scaley_label.setToolTip( _("Factor for Scale action over Y axis.") ) - self.scaley_entry = FCDoubleSpinner() + self.scaley_entry = FCDoubleSpinner(callback=self.confirmation_message) self.scaley_entry.set_range(0, 9999.9999) self.scaley_entry.set_precision(self.decimals) self.scaley_entry.setSingleStep(0.1) @@ -508,7 +508,7 @@ class ToolCalibration(FlatCAMTool): _("Angle for Skew action, in degrees.\n" "Float number between -360 and 359.") ) - self.skewx_entry = FCDoubleSpinner() + self.skewx_entry = FCDoubleSpinner(callback=self.confirmation_message) self.skewx_entry.set_range(-360, 360) self.skewx_entry.set_precision(self.decimals) self.skewx_entry.setSingleStep(0.1) @@ -521,7 +521,7 @@ class ToolCalibration(FlatCAMTool): _("Angle for Skew action, in degrees.\n" "Float number between -360 and 359.") ) - self.skewy_entry = FCDoubleSpinner() + self.skewy_entry = FCDoubleSpinner(callback=self.confirmation_message) self.skewy_entry.set_range(-360, 360) self.skewy_entry.set_precision(self.decimals) self.skewy_entry.setSingleStep(0.1) @@ -552,7 +552,7 @@ class ToolCalibration(FlatCAMTool): # self.fin_scalex_label.setToolTip( # _("Final factor for Scale action over X axis.") # ) - # self.fin_scalex_entry = FCDoubleSpinner() + # self.fin_scalex_entry = FCDoubleSpinner(callback=self.confirmation_message) # self.fin_scalex_entry.set_range(0, 9999.9999) # self.fin_scalex_entry.set_precision(self.decimals) # self.fin_scalex_entry.setSingleStep(0.1) @@ -564,7 +564,7 @@ class ToolCalibration(FlatCAMTool): # self.fin_scaley_label.setToolTip( # _("Final factor for Scale action over Y axis.") # ) - # self.fin_scaley_entry = FCDoubleSpinner() + # self.fin_scaley_entry = FCDoubleSpinner(callback=self.confirmation_message) # self.fin_scaley_entry.set_range(0, 9999.9999) # self.fin_scaley_entry.set_precision(self.decimals) # self.fin_scaley_entry.setSingleStep(0.1) @@ -577,7 +577,7 @@ class ToolCalibration(FlatCAMTool): # _("Final value for angle for Skew action, in degrees.\n" # "Float number between -360 and 359.") # ) - # self.fin_skewx_entry = FCDoubleSpinner() + # self.fin_skewx_entry = FCDoubleSpinner(callback=self.confirmation_message) # self.fin_skewx_entry.set_range(-360, 360) # self.fin_skewx_entry.set_precision(self.decimals) # self.fin_skewx_entry.setSingleStep(0.1) @@ -590,7 +590,7 @@ class ToolCalibration(FlatCAMTool): # _("Final value for angle for Skew action, in degrees.\n" # "Float number between -360 and 359.") # ) - # self.fin_skewy_entry = FCDoubleSpinner() + # self.fin_skewy_entry = FCDoubleSpinner(callback=self.confirmation_message) # self.fin_skewy_entry.set_range(-360, 360) # self.fin_skewy_entry.set_precision(self.decimals) # self.fin_skewy_entry.setSingleStep(0.1) diff --git a/flatcamTools/ToolCopperThieving.py b/flatcamTools/ToolCopperThieving.py index 38c5ccf7..aa9ab7f1 100644 --- a/flatcamTools/ToolCopperThieving.py +++ b/flatcamTools/ToolCopperThieving.py @@ -99,7 +99,7 @@ class ToolCopperThieving(FlatCAMTool): "(the polygon fill may be split in multiple polygons)\n" "and the copper traces in the Gerber file.") ) - self.clearance_entry = FCDoubleSpinner() + self.clearance_entry = FCDoubleSpinner(callback=self.confirmation_message) self.clearance_entry.set_range(0.00001, 9999.9999) self.clearance_entry.set_precision(self.decimals) self.clearance_entry.setSingleStep(0.1) @@ -112,7 +112,7 @@ class ToolCopperThieving(FlatCAMTool): self.margin_label.setToolTip( _("Bounding box margin.") ) - self.margin_entry = FCDoubleSpinner() + self.margin_entry = FCDoubleSpinner(callback=self.confirmation_message) self.margin_entry.set_range(0.0, 9999.9999) self.margin_entry.set_precision(self.decimals) self.margin_entry.setSingleStep(0.1) @@ -221,7 +221,7 @@ class ToolCopperThieving(FlatCAMTool): self.dotdia_label.setToolTip( _("Dot diameter in Dots Grid.") ) - self.dot_dia_entry = FCDoubleSpinner() + self.dot_dia_entry = FCDoubleSpinner(callback=self.confirmation_message) self.dot_dia_entry.set_range(0.0, 9999.9999) self.dot_dia_entry.set_precision(self.decimals) self.dot_dia_entry.setSingleStep(0.1) @@ -234,7 +234,7 @@ class ToolCopperThieving(FlatCAMTool): self.dotspacing_label.setToolTip( _("Distance between each two dots in Dots Grid.") ) - self.dot_spacing_entry = FCDoubleSpinner() + self.dot_spacing_entry = FCDoubleSpinner(callback=self.confirmation_message) self.dot_spacing_entry.set_range(0.0, 9999.9999) self.dot_spacing_entry.set_precision(self.decimals) self.dot_spacing_entry.setSingleStep(0.1) @@ -261,7 +261,7 @@ class ToolCopperThieving(FlatCAMTool): self.square_size_label.setToolTip( _("Square side size in Squares Grid.") ) - self.square_size_entry = FCDoubleSpinner() + self.square_size_entry = FCDoubleSpinner(callback=self.confirmation_message) self.square_size_entry.set_range(0.0, 9999.9999) self.square_size_entry.set_precision(self.decimals) self.square_size_entry.setSingleStep(0.1) @@ -274,7 +274,7 @@ class ToolCopperThieving(FlatCAMTool): self.squares_spacing_label.setToolTip( _("Distance between each two squares in Squares Grid.") ) - self.squares_spacing_entry = FCDoubleSpinner() + self.squares_spacing_entry = FCDoubleSpinner(callback=self.confirmation_message) self.squares_spacing_entry.set_range(0.0, 9999.9999) self.squares_spacing_entry.set_precision(self.decimals) self.squares_spacing_entry.setSingleStep(0.1) @@ -301,7 +301,7 @@ class ToolCopperThieving(FlatCAMTool): self.line_size_label.setToolTip( _("Line thickness size in Lines Grid.") ) - self.line_size_entry = FCDoubleSpinner() + self.line_size_entry = FCDoubleSpinner(callback=self.confirmation_message) self.line_size_entry.set_range(0.0, 9999.9999) self.line_size_entry.set_precision(self.decimals) self.line_size_entry.setSingleStep(0.1) @@ -314,7 +314,7 @@ class ToolCopperThieving(FlatCAMTool): self.lines_spacing_label.setToolTip( _("Distance between each two lines in Lines Grid.") ) - self.lines_spacing_entry = FCDoubleSpinner() + self.lines_spacing_entry = FCDoubleSpinner(callback=self.confirmation_message) self.lines_spacing_entry.set_range(0.0, 9999.9999) self.lines_spacing_entry.set_precision(self.decimals) self.lines_spacing_entry.setSingleStep(0.1) @@ -362,7 +362,7 @@ class ToolCopperThieving(FlatCAMTool): self.rb_margin_label.setToolTip( _("Bounding box margin for robber bar.") ) - self.rb_margin_entry = FCDoubleSpinner() + self.rb_margin_entry = FCDoubleSpinner(callback=self.confirmation_message) self.rb_margin_entry.set_range(-9999.9999, 9999.9999) self.rb_margin_entry.set_precision(self.decimals) self.rb_margin_entry.setSingleStep(0.1) @@ -375,7 +375,7 @@ class ToolCopperThieving(FlatCAMTool): self.rb_thickness_label.setToolTip( _("The robber bar thickness.") ) - self.rb_thickness_entry = FCDoubleSpinner() + self.rb_thickness_entry = FCDoubleSpinner(callback=self.confirmation_message) self.rb_thickness_entry.set_range(0.0000, 9999.9999) self.rb_thickness_entry.set_precision(self.decimals) self.rb_thickness_entry.setSingleStep(0.1) @@ -431,7 +431,7 @@ class ToolCopperThieving(FlatCAMTool): _("The distance between the possible copper thieving elements\n" "and/or robber bar and the actual openings in the mask.") ) - self.clearance_ppm_entry = FCDoubleSpinner() + self.clearance_ppm_entry = FCDoubleSpinner(callback=self.confirmation_message) self.clearance_ppm_entry.set_range(-9999.9999, 9999.9999) self.clearance_ppm_entry.set_precision(self.decimals) self.clearance_ppm_entry.setSingleStep(0.1) diff --git a/flatcamTools/ToolCutOut.py b/flatcamTools/ToolCutOut.py index 2e0d7924..32e799b1 100644 --- a/flatcamTools/ToolCutOut.py +++ b/flatcamTools/ToolCutOut.py @@ -123,7 +123,7 @@ class CutOut(FlatCAMTool): grid0.addWidget(self.param_label, 6, 0, 1, 2) # Tool Diameter - self.dia = FCDoubleSpinner() + self.dia = FCDoubleSpinner(callback=self.confirmation_message) self.dia.set_precision(self.decimals) self.dia.set_range(0.0000, 9999.9999) @@ -143,7 +143,7 @@ class CutOut(FlatCAMTool): "below the copper surface." ) ) - self.cutz_entry = FCDoubleSpinner() + self.cutz_entry = FCDoubleSpinner(callback=self.confirmation_message) self.cutz_entry.set_precision(self.decimals) if machinist_setting == 0: @@ -167,7 +167,7 @@ class CutOut(FlatCAMTool): ) ) - self.maxdepth_entry = FCDoubleSpinner() + self.maxdepth_entry = FCDoubleSpinner(callback=self.confirmation_message) self.maxdepth_entry.set_precision(self.decimals) self.maxdepth_entry.setRange(0, 9999.9999) self.maxdepth_entry.setSingleStep(0.1) @@ -183,7 +183,7 @@ class CutOut(FlatCAMTool): grid0.addWidget(self.maxdepth_entry, 10, 1) # Margin - self.margin = FCDoubleSpinner() + self.margin = FCDoubleSpinner(callback=self.confirmation_message) self.margin.set_range(-9999.9999, 9999.9999) self.margin.setSingleStep(0.1) self.margin.set_precision(self.decimals) @@ -198,7 +198,7 @@ class CutOut(FlatCAMTool): grid0.addWidget(self.margin, 11, 1) # Gapsize - self.gapsize = FCDoubleSpinner() + self.gapsize = FCDoubleSpinner(callback=self.confirmation_message) self.gapsize.set_precision(self.decimals) self.gapsize_label = QtWidgets.QLabel('%s:' % _("Gap size")) diff --git a/flatcamTools/ToolDblSided.py b/flatcamTools/ToolDblSided.py index dc1bbd9f..b7c975d9 100644 --- a/flatcamTools/ToolDblSided.py +++ b/flatcamTools/ToolDblSided.py @@ -254,7 +254,7 @@ class DblSidedTool(FlatCAMTool): grid_lay2.addWidget(self.bv_label, 6, 0, 1, 2) # Xmin value - self.xmin_entry = FCDoubleSpinner() + self.xmin_entry = FCDoubleSpinner(callback=self.confirmation_message) self.xmin_entry.set_precision(self.decimals) self.xmin_entry.set_range(-9999.9999, 9999.9999) @@ -268,7 +268,7 @@ class DblSidedTool(FlatCAMTool): grid_lay2.addWidget(self.xmin_entry, 7, 1) # Ymin value - self.ymin_entry = FCDoubleSpinner() + self.ymin_entry = FCDoubleSpinner(callback=self.confirmation_message) self.ymin_entry.set_precision(self.decimals) self.ymin_entry.set_range(-9999.9999, 9999.9999) @@ -282,7 +282,7 @@ class DblSidedTool(FlatCAMTool): grid_lay2.addWidget(self.ymin_entry, 8, 1) # Xmax value - self.xmax_entry = FCDoubleSpinner() + self.xmax_entry = FCDoubleSpinner(callback=self.confirmation_message) self.xmax_entry.set_precision(self.decimals) self.xmax_entry.set_range(-9999.9999, 9999.9999) @@ -296,7 +296,7 @@ class DblSidedTool(FlatCAMTool): grid_lay2.addWidget(self.xmax_entry, 9, 1) # Ymax value - self.ymax_entry = FCDoubleSpinner() + self.ymax_entry = FCDoubleSpinner(callback=self.confirmation_message) self.ymax_entry.set_precision(self.decimals) self.ymax_entry.set_range(-9999.9999, 9999.9999) @@ -359,7 +359,7 @@ class DblSidedTool(FlatCAMTool): _("Diameter of the drill for the alignment holes.") ) - self.drill_dia = FCDoubleSpinner() + self.drill_dia = FCDoubleSpinner(callback=self.confirmation_message) self.drill_dia.setToolTip( _("Diameter of the drill for the alignment holes.") ) diff --git a/flatcamTools/ToolExtractDrills.py b/flatcamTools/ToolExtractDrills.py index bc772e42..05c1e2d0 100644 --- a/flatcamTools/ToolExtractDrills.py +++ b/flatcamTools/ToolExtractDrills.py @@ -156,7 +156,7 @@ class ToolExtractDrills(FlatCAMTool): grid1.addWidget(self.fixed_label, 6, 0, 1, 2) # Diameter value - self.dia_entry = FCDoubleSpinner() + self.dia_entry = FCDoubleSpinner(callback=self.confirmation_message) self.dia_entry.set_precision(self.decimals) self.dia_entry.set_range(0.0000, 9999.9999) @@ -202,7 +202,7 @@ class ToolExtractDrills(FlatCAMTool): _("The size of annular ring for circular pads.") ) - self.circular_ring_entry = FCDoubleSpinner() + self.circular_ring_entry = FCDoubleSpinner(callback=self.confirmation_message) self.circular_ring_entry.set_precision(self.decimals) self.circular_ring_entry.set_range(0.0000, 9999.9999) @@ -215,7 +215,7 @@ class ToolExtractDrills(FlatCAMTool): _("The size of annular ring for oblong pads.") ) - self.oblong_ring_entry = FCDoubleSpinner() + self.oblong_ring_entry = FCDoubleSpinner(callback=self.confirmation_message) self.oblong_ring_entry.set_precision(self.decimals) self.oblong_ring_entry.set_range(0.0000, 9999.9999) @@ -228,7 +228,7 @@ class ToolExtractDrills(FlatCAMTool): _("The size of annular ring for square pads.") ) - self.square_ring_entry = FCDoubleSpinner() + self.square_ring_entry = FCDoubleSpinner(callback=self.confirmation_message) self.square_ring_entry.set_precision(self.decimals) self.square_ring_entry.set_range(0.0000, 9999.9999) @@ -241,7 +241,7 @@ class ToolExtractDrills(FlatCAMTool): _("The size of annular ring for rectangular pads.") ) - self.rectangular_ring_entry = FCDoubleSpinner() + self.rectangular_ring_entry = FCDoubleSpinner(callback=self.confirmation_message) self.rectangular_ring_entry.set_precision(self.decimals) self.rectangular_ring_entry.set_range(0.0000, 9999.9999) @@ -254,7 +254,7 @@ class ToolExtractDrills(FlatCAMTool): _("The size of annular ring for other pads.") ) - self.other_ring_entry = FCDoubleSpinner() + self.other_ring_entry = FCDoubleSpinner(callback=self.confirmation_message) self.other_ring_entry.set_precision(self.decimals) self.other_ring_entry.set_range(0.0000, 9999.9999) diff --git a/flatcamTools/ToolFiducials.py b/flatcamTools/ToolFiducials.py index 6b4d1d85..33113dac 100644 --- a/flatcamTools/ToolFiducials.py +++ b/flatcamTools/ToolFiducials.py @@ -159,7 +159,7 @@ class ToolFiducials(FlatCAMTool): "otherwise is the size of the fiducial.\n" "The soldermask opening is double than that.") ) - self.fid_size_entry = FCDoubleSpinner() + self.fid_size_entry = FCDoubleSpinner(callback=self.confirmation_message) self.fid_size_entry.set_range(1.0000, 3.0000) self.fid_size_entry.set_precision(self.decimals) self.fid_size_entry.setWrapping(True) @@ -173,7 +173,7 @@ class ToolFiducials(FlatCAMTool): self.margin_label.setToolTip( _("Bounding box margin.") ) - self.margin_entry = FCDoubleSpinner() + self.margin_entry = FCDoubleSpinner(callback=self.confirmation_message) self.margin_entry.set_range(-9999.9999, 9999.9999) self.margin_entry.set_precision(self.decimals) self.margin_entry.setSingleStep(0.1) @@ -236,7 +236,7 @@ class ToolFiducials(FlatCAMTool): self.line_thickness_label.setToolTip( _("Bounding box margin.") ) - self.line_thickness_entry = FCDoubleSpinner() + self.line_thickness_entry = FCDoubleSpinner(callback=self.confirmation_message) self.line_thickness_entry.set_range(0.00001, 9999.9999) self.line_thickness_entry.set_precision(self.decimals) self.line_thickness_entry.setSingleStep(0.1) diff --git a/flatcamTools/ToolFilm.py b/flatcamTools/ToolFilm.py index a3542e29..4772d0ad 100644 --- a/flatcamTools/ToolFilm.py +++ b/flatcamTools/ToolFilm.py @@ -160,7 +160,7 @@ class Film(FlatCAMTool): grid0.addWidget(self.film_scale_cb, 6, 0, 1, 2) self.film_scalex_label = QtWidgets.QLabel('%s:' % _("X factor")) - self.film_scalex_entry = FCDoubleSpinner() + self.film_scalex_entry = FCDoubleSpinner(callback=self.confirmation_message) self.film_scalex_entry.set_range(-999.9999, 999.9999) self.film_scalex_entry.set_precision(self.decimals) self.film_scalex_entry.setSingleStep(0.01) @@ -169,7 +169,7 @@ class Film(FlatCAMTool): grid0.addWidget(self.film_scalex_entry, 7, 1) self.film_scaley_label = QtWidgets.QLabel('%s:' % _("Y factor")) - self.film_scaley_entry = FCDoubleSpinner() + self.film_scaley_entry = FCDoubleSpinner(callback=self.confirmation_message) self.film_scaley_entry.set_range(-999.9999, 999.9999) self.film_scaley_entry.set_precision(self.decimals) self.film_scaley_entry.setSingleStep(0.01) @@ -199,7 +199,7 @@ class Film(FlatCAMTool): grid0.addWidget(self.film_skew_cb, 10, 0, 1, 2) self.film_skewx_label = QtWidgets.QLabel('%s:' % _("X angle")) - self.film_skewx_entry = FCDoubleSpinner() + self.film_skewx_entry = FCDoubleSpinner(callback=self.confirmation_message) self.film_skewx_entry.set_range(-999.9999, 999.9999) self.film_skewx_entry.set_precision(self.decimals) self.film_skewx_entry.setSingleStep(0.01) @@ -208,7 +208,7 @@ class Film(FlatCAMTool): grid0.addWidget(self.film_skewx_entry, 11, 1) self.film_skewy_label = QtWidgets.QLabel('%s:' % _("Y angle")) - self.film_skewy_entry = FCDoubleSpinner() + self.film_skewy_entry = FCDoubleSpinner(callback=self.confirmation_message) self.film_skewy_entry.set_range(-999.9999, 999.9999) self.film_skewy_entry.set_precision(self.decimals) self.film_skewy_entry.setSingleStep(0.01) @@ -275,7 +275,7 @@ class Film(FlatCAMTool): grid0.addWidget(self.film_param_label, 18, 0, 1, 2) # Scale Stroke size - self.film_scale_stroke_entry = FCDoubleSpinner() + self.film_scale_stroke_entry = FCDoubleSpinner(callback=self.confirmation_message) self.film_scale_stroke_entry.set_range(-999.9999, 999.9999) self.film_scale_stroke_entry.setSingleStep(0.01) self.film_scale_stroke_entry.set_precision(self.decimals) @@ -308,7 +308,7 @@ class Film(FlatCAMTool): grid0.addWidget(self.film_type, 21, 1) # Boundary for negative film generation - self.boundary_entry = FCDoubleSpinner() + self.boundary_entry = FCDoubleSpinner(callback=self.confirmation_message) self.boundary_entry.set_range(-999.9999, 999.9999) self.boundary_entry.setSingleStep(0.01) self.boundary_entry.set_precision(self.decimals) @@ -378,7 +378,7 @@ class Film(FlatCAMTool): self.punch_size_label = QtWidgets.QLabel('%s:' % _("Punch Size")) self.punch_size_label.setToolTip(_("The value here will control how big is the punch hole in the pads.")) - self.punch_size_spinner = FCDoubleSpinner() + self.punch_size_spinner = FCDoubleSpinner(callback=self.confirmation_message) self.punch_size_spinner.set_range(0, 999.9999) self.punch_size_spinner.setSingleStep(0.1) self.punch_size_spinner.set_precision(self.decimals) diff --git a/flatcamTools/ToolInvertGerber.py b/flatcamTools/ToolInvertGerber.py index df1af676..c4338b79 100644 --- a/flatcamTools/ToolInvertGerber.py +++ b/flatcamTools/ToolInvertGerber.py @@ -89,7 +89,7 @@ class ToolInvertGerber(FlatCAMTool): _("Distance by which to avoid\n" "the edges of the Gerber object.") ) - self.margin_entry = FCDoubleSpinner() + self.margin_entry = FCDoubleSpinner(callback=self.confirmation_message) self.margin_entry.set_precision(self.decimals) self.margin_entry.set_range(0.0000, 9999.9999) self.margin_entry.setObjectName(_("Margin")) diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNonCopperClear.py index d96ac687..6a03bdf6 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/flatcamTools/ToolNonCopperClear.py @@ -251,7 +251,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.tipdialabel = QtWidgets.QLabel('%s:' % _('V-Tip Dia')) self.tipdialabel.setToolTip( _("The tip diameter for V-Shape Tool")) - self.tipdia_entry = FCDoubleSpinner() + self.tipdia_entry = FCDoubleSpinner(callback=self.confirmation_message) self.tipdia_entry.set_precision(self.decimals) self.tipdia_entry.set_range(0.0000, 9999.9999) self.tipdia_entry.setSingleStep(0.1) @@ -265,7 +265,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.tipanglelabel.setToolTip( _("The tip angle for V-Shape Tool.\n" "In degree.")) - self.tipangle_entry = FCDoubleSpinner() + self.tipangle_entry = FCDoubleSpinner(callback=self.confirmation_message) self.tipangle_entry.set_precision(self.decimals) self.tipangle_entry.set_range(0.0000, 180.0000) self.tipangle_entry.setSingleStep(5) @@ -280,7 +280,7 @@ class NonCopperClear(FlatCAMTool, Gerber): _("Depth of cut into material. Negative value.\n" "In FlatCAM units.") ) - self.cutz_entry = FCDoubleSpinner() + self.cutz_entry = FCDoubleSpinner(callback=self.confirmation_message) self.cutz_entry.set_precision(self.decimals) self.cutz_entry.set_range(-99999.9999, 0.0000) self.cutz_entry.setObjectName(_("Cut Z")) @@ -299,7 +299,7 @@ class NonCopperClear(FlatCAMTool, Gerber): "If the tool is V-shape type then this value is automatically\n" "calculated from the other parameters.") ) - self.addtool_entry = FCDoubleSpinner() + self.addtool_entry = FCDoubleSpinner(callback=self.confirmation_message) self.addtool_entry.set_precision(self.decimals) self.addtool_entry.set_range(0.000, 9999.9999) self.addtool_entry.setObjectName(_("Tool Dia")) @@ -381,7 +381,7 @@ class NonCopperClear(FlatCAMTool, Gerber): nccmarginlabel.setToolTip( _("Bounding box margin.") ) - self.ncc_margin_entry = FCDoubleSpinner() + self.ncc_margin_entry = FCDoubleSpinner(callback=self.confirmation_message) self.ncc_margin_entry.set_precision(self.decimals) self.ncc_margin_entry.set_range(-9999.9999, 9999.9999) self.ncc_margin_entry.setObjectName(_("Margin")) @@ -447,7 +447,7 @@ class NonCopperClear(FlatCAMTool, Gerber): # "from the copper features.\n" # "The value can be between 0 and 10 FlatCAM units.") # ) - self.ncc_offset_spinner = FCDoubleSpinner() + self.ncc_offset_spinner = FCDoubleSpinner(callback=self.confirmation_message) self.ncc_offset_spinner.set_range(0.00, 10.00) self.ncc_offset_spinner.set_precision(4) self.ncc_offset_spinner.setWrapping(True) diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 6b64d4f9..abfa7364 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -214,7 +214,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.tipdialabel = QtWidgets.QLabel('%s:' % _('V-Tip Dia')) self.tipdialabel.setToolTip( _("The tip diameter for V-Shape Tool")) - self.tipdia_entry = FCDoubleSpinner() + self.tipdia_entry = FCDoubleSpinner(callback=self.confirmation_message) self.tipdia_entry.set_precision(self.decimals) self.tipdia_entry.set_range(0.0000, 9999.9999) self.tipdia_entry.setSingleStep(0.1) @@ -228,7 +228,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.tipanglelabel.setToolTip( _("The tip angle for V-Shape Tool.\n" "In degree.")) - self.tipangle_entry = FCDoubleSpinner() + self.tipangle_entry = FCDoubleSpinner(callback=self.confirmation_message) self.tipangle_entry.set_precision(self.decimals) self.tipangle_entry.set_range(0.0000, 180.0000) self.tipangle_entry.setSingleStep(5) @@ -243,7 +243,7 @@ class ToolPaint(FlatCAMTool, Gerber): _("Depth of cut into material. Negative value.\n" "In FlatCAM units.") ) - self.cutz_entry = FCDoubleSpinner() + self.cutz_entry = FCDoubleSpinner(callback=self.confirmation_message) self.cutz_entry.set_precision(self.decimals) self.cutz_entry.set_range(-99999.9999, 0.0000) self.cutz_entry.setObjectName(_("Cut Z")) @@ -262,7 +262,7 @@ class ToolPaint(FlatCAMTool, Gerber): "If the tool is V-shape type then this value is automatically\n" "calculated from the other parameters.") ) - self.addtool_entry = FCDoubleSpinner() + self.addtool_entry = FCDoubleSpinner(callback=self.confirmation_message) self.addtool_entry.set_precision(self.decimals) self.addtool_entry.set_range(0.000, 9999.9999) self.addtool_entry.setObjectName(_("Tool Dia")) @@ -351,7 +351,7 @@ class ToolPaint(FlatCAMTool, Gerber): "the edges of the polygon to\n" "be painted.") ) - self.paintmargin_entry = FCDoubleSpinner() + self.paintmargin_entry = FCDoubleSpinner(callback=self.confirmation_message) self.paintmargin_entry.set_precision(self.decimals) self.paintmargin_entry.set_range(-9999.9999, 9999.9999) self.paintmargin_entry.setObjectName(_("Margin")) diff --git a/flatcamTools/ToolPanelize.py b/flatcamTools/ToolPanelize.py index a836d320..9a1e5f7a 100644 --- a/flatcamTools/ToolPanelize.py +++ b/flatcamTools/ToolPanelize.py @@ -158,7 +158,7 @@ class Panelize(FlatCAMTool): form_layout.addRow(panel_data_label) # Spacing Columns - self.spacing_columns = FCDoubleSpinner() + self.spacing_columns = FCDoubleSpinner(callback=self.confirmation_message) self.spacing_columns.set_range(0, 9999) self.spacing_columns.set_precision(4) @@ -170,7 +170,7 @@ class Panelize(FlatCAMTool): form_layout.addRow(self.spacing_columns_label, self.spacing_columns) # Spacing Rows - self.spacing_rows = FCDoubleSpinner() + self.spacing_rows = FCDoubleSpinner(callback=self.confirmation_message) self.spacing_rows.set_range(0, 9999) self.spacing_rows.set_precision(4) @@ -225,7 +225,7 @@ class Panelize(FlatCAMTool): ) form_layout.addRow(self.constrain_cb) - self.x_width_entry = FCDoubleSpinner() + self.x_width_entry = FCDoubleSpinner(callback=self.confirmation_message) self.x_width_entry.set_precision(4) self.x_width_entry.set_range(0, 9999) @@ -236,7 +236,7 @@ class Panelize(FlatCAMTool): ) form_layout.addRow(self.x_width_lbl, self.x_width_entry) - self.y_height_entry = FCDoubleSpinner() + self.y_height_entry = FCDoubleSpinner(callback=self.confirmation_message) self.y_height_entry.set_range(0, 9999) self.y_height_entry.set_precision(4) diff --git a/flatcamTools/ToolPunchGerber.py b/flatcamTools/ToolPunchGerber.py index 282c20d4..75bf2495 100644 --- a/flatcamTools/ToolPunchGerber.py +++ b/flatcamTools/ToolPunchGerber.py @@ -183,7 +183,7 @@ class ToolPunchGerber(FlatCAMTool): grid0.addWidget(self.fixed_label, 6, 0, 1, 2) # Diameter value - self.dia_entry = FCDoubleSpinner() + self.dia_entry = FCDoubleSpinner(callback=self.confirmation_message) self.dia_entry.set_precision(self.decimals) self.dia_entry.set_range(0.0000, 9999.9999) @@ -229,7 +229,7 @@ class ToolPunchGerber(FlatCAMTool): _("The size of annular ring for circular pads.") ) - self.circular_ring_entry = FCDoubleSpinner() + self.circular_ring_entry = FCDoubleSpinner(callback=self.confirmation_message) self.circular_ring_entry.set_precision(self.decimals) self.circular_ring_entry.set_range(0.0000, 9999.9999) @@ -242,7 +242,7 @@ class ToolPunchGerber(FlatCAMTool): _("The size of annular ring for oblong pads.") ) - self.oblong_ring_entry = FCDoubleSpinner() + self.oblong_ring_entry = FCDoubleSpinner(callback=self.confirmation_message) self.oblong_ring_entry.set_precision(self.decimals) self.oblong_ring_entry.set_range(0.0000, 9999.9999) @@ -255,7 +255,7 @@ class ToolPunchGerber(FlatCAMTool): _("The size of annular ring for square pads.") ) - self.square_ring_entry = FCDoubleSpinner() + self.square_ring_entry = FCDoubleSpinner(callback=self.confirmation_message) self.square_ring_entry.set_precision(self.decimals) self.square_ring_entry.set_range(0.0000, 9999.9999) @@ -268,7 +268,7 @@ class ToolPunchGerber(FlatCAMTool): _("The size of annular ring for rectangular pads.") ) - self.rectangular_ring_entry = FCDoubleSpinner() + self.rectangular_ring_entry = FCDoubleSpinner(callback=self.confirmation_message) self.rectangular_ring_entry.set_precision(self.decimals) self.rectangular_ring_entry.set_range(0.0000, 9999.9999) @@ -281,7 +281,7 @@ class ToolPunchGerber(FlatCAMTool): _("The size of annular ring for other pads.") ) - self.other_ring_entry = FCDoubleSpinner() + self.other_ring_entry = FCDoubleSpinner(callback=self.confirmation_message) self.other_ring_entry.set_precision(self.decimals) self.other_ring_entry.set_range(0.0000, 9999.9999) diff --git a/flatcamTools/ToolRulesCheck.py b/flatcamTools/ToolRulesCheck.py index bad1f902..39561ef2 100644 --- a/flatcamTools/ToolRulesCheck.py +++ b/flatcamTools/ToolRulesCheck.py @@ -260,7 +260,7 @@ class RulesCheck(FlatCAMTool): self.form_layout_1.addRow(self.trace_size_cb) # Trace size value - self.trace_size_entry = FCDoubleSpinner() + self.trace_size_entry = FCDoubleSpinner(callback=self.confirmation_message) self.trace_size_entry.set_range(0.00001, 999.99999) self.trace_size_entry.set_precision(self.decimals) self.trace_size_entry.setSingleStep(0.1) @@ -282,7 +282,7 @@ class RulesCheck(FlatCAMTool): self.form_layout_1.addRow(self.clearance_copper2copper_cb) # Copper2copper clearance value - self.clearance_copper2copper_entry = FCDoubleSpinner() + self.clearance_copper2copper_entry = FCDoubleSpinner(callback=self.confirmation_message) self.clearance_copper2copper_entry.set_range(0.00001, 999.99999) self.clearance_copper2copper_entry.set_precision(self.decimals) self.clearance_copper2copper_entry.setSingleStep(0.1) @@ -305,7 +305,7 @@ class RulesCheck(FlatCAMTool): self.form_layout_1.addRow(self.clearance_copper2ol_cb) # Copper2outline clearance value - self.clearance_copper2ol_entry = FCDoubleSpinner() + self.clearance_copper2ol_entry = FCDoubleSpinner(callback=self.confirmation_message) self.clearance_copper2ol_entry.set_range(0.00001, 999.99999) self.clearance_copper2ol_entry.set_precision(self.decimals) self.clearance_copper2ol_entry.setSingleStep(0.1) @@ -328,7 +328,7 @@ class RulesCheck(FlatCAMTool): self.form_layout_1.addRow(self.clearance_silk2silk_cb) # Copper2silkscreen clearance value - self.clearance_silk2silk_entry = FCDoubleSpinner() + self.clearance_silk2silk_entry = FCDoubleSpinner(callback=self.confirmation_message) self.clearance_silk2silk_entry.set_range(0.00001, 999.99999) self.clearance_silk2silk_entry.set_precision(self.decimals) self.clearance_silk2silk_entry.setSingleStep(0.1) @@ -351,7 +351,7 @@ class RulesCheck(FlatCAMTool): self.form_layout_1.addRow(self.clearance_silk2sm_cb) # Silkscreen2soldermask clearance value - self.clearance_silk2sm_entry = FCDoubleSpinner() + self.clearance_silk2sm_entry = FCDoubleSpinner(callback=self.confirmation_message) self.clearance_silk2sm_entry.set_range(0.00001, 999.99999) self.clearance_silk2sm_entry.set_precision(self.decimals) self.clearance_silk2sm_entry.setSingleStep(0.1) @@ -374,7 +374,7 @@ class RulesCheck(FlatCAMTool): self.form_layout_1.addRow(self.clearance_silk2ol_cb) # Silk2outline clearance value - self.clearance_silk2ol_entry = FCDoubleSpinner() + self.clearance_silk2ol_entry = FCDoubleSpinner(callback=self.confirmation_message) self.clearance_silk2ol_entry.set_range(0.00001, 999.99999) self.clearance_silk2ol_entry.set_precision(self.decimals) self.clearance_silk2ol_entry.setSingleStep(0.1) @@ -397,7 +397,7 @@ class RulesCheck(FlatCAMTool): self.form_layout_1.addRow(self.clearance_sm2sm_cb) # Soldermask2soldermask clearance value - self.clearance_sm2sm_entry = FCDoubleSpinner() + self.clearance_sm2sm_entry = FCDoubleSpinner(callback=self.confirmation_message) self.clearance_sm2sm_entry.set_range(0.00001, 999.99999) self.clearance_sm2sm_entry.set_precision(self.decimals) self.clearance_sm2sm_entry.setSingleStep(0.1) @@ -420,7 +420,7 @@ class RulesCheck(FlatCAMTool): self.form_layout_1.addRow(self.ring_integrity_cb) # Ring integrity value - self.ring_integrity_entry = FCDoubleSpinner() + self.ring_integrity_entry = FCDoubleSpinner(callback=self.confirmation_message) self.ring_integrity_entry.set_range(0.00001, 999.99999) self.ring_integrity_entry.set_precision(self.decimals) self.ring_integrity_entry.setSingleStep(0.1) @@ -445,7 +445,7 @@ class RulesCheck(FlatCAMTool): self.form_layout_1.addRow(self.clearance_d2d_cb) # Hole2Hole clearance value - self.clearance_d2d_entry = FCDoubleSpinner() + self.clearance_d2d_entry = FCDoubleSpinner(callback=self.confirmation_message) self.clearance_d2d_entry.set_range(0.00001, 999.99999) self.clearance_d2d_entry.set_precision(self.decimals) self.clearance_d2d_entry.setSingleStep(0.1) @@ -468,7 +468,7 @@ class RulesCheck(FlatCAMTool): self.form_layout_1.addRow(self.drill_size_cb) # Drile holes value - self.drill_size_entry = FCDoubleSpinner() + self.drill_size_entry = FCDoubleSpinner(callback=self.confirmation_message) self.drill_size_entry.set_range(0.00001, 999.99999) self.drill_size_entry.set_precision(self.decimals) self.drill_size_entry.setSingleStep(0.1) diff --git a/flatcamTools/ToolSolderPaste.py b/flatcamTools/ToolSolderPaste.py index af227bd3..9f268a3e 100644 --- a/flatcamTools/ToolSolderPaste.py +++ b/flatcamTools/ToolSolderPaste.py @@ -105,7 +105,7 @@ class SolderPaste(FlatCAMTool): self.addtool_entry_lbl.setToolTip( _("Diameter for the new Nozzle tool to add in the Tool Table") ) - self.addtool_entry = FCDoubleSpinner() + self.addtool_entry = FCDoubleSpinner(callback=self.confirmation_message) self.addtool_entry.set_range(0.0000001, 9999.9999) self.addtool_entry.set_precision(self.decimals) self.addtool_entry.setSingleStep(0.1) @@ -174,7 +174,7 @@ class SolderPaste(FlatCAMTool): self.gcode_box.addLayout(self.gcode_form_layout) # Z dispense start - self.z_start_entry = FCDoubleSpinner() + self.z_start_entry = FCDoubleSpinner(callback=self.confirmation_message) self.z_start_entry.set_range(0.0000001, 9999.9999) self.z_start_entry.set_precision(self.decimals) self.z_start_entry.setSingleStep(0.1) @@ -186,7 +186,7 @@ class SolderPaste(FlatCAMTool): self.gcode_form_layout.addRow(self.z_start_label, self.z_start_entry) # Z dispense - self.z_dispense_entry = FCDoubleSpinner() + self.z_dispense_entry = FCDoubleSpinner(callback=self.confirmation_message) self.z_dispense_entry.set_range(0.0000001, 9999.9999) self.z_dispense_entry.set_precision(self.decimals) self.z_dispense_entry.setSingleStep(0.1) @@ -198,7 +198,7 @@ class SolderPaste(FlatCAMTool): self.gcode_form_layout.addRow(self.z_dispense_label, self.z_dispense_entry) # Z dispense stop - self.z_stop_entry = FCDoubleSpinner() + self.z_stop_entry = FCDoubleSpinner(callback=self.confirmation_message) self.z_stop_entry.set_range(0.0000001, 9999.9999) self.z_stop_entry.set_precision(self.decimals) self.z_stop_entry.setSingleStep(0.1) @@ -210,7 +210,7 @@ class SolderPaste(FlatCAMTool): self.gcode_form_layout.addRow(self.z_stop_label, self.z_stop_entry) # Z travel - self.z_travel_entry = FCDoubleSpinner() + self.z_travel_entry = FCDoubleSpinner(callback=self.confirmation_message) self.z_travel_entry.set_range(0.0000001, 9999.9999) self.z_travel_entry.set_precision(self.decimals) self.z_travel_entry.setSingleStep(0.1) @@ -223,7 +223,7 @@ class SolderPaste(FlatCAMTool): self.gcode_form_layout.addRow(self.z_travel_label, self.z_travel_entry) # Z toolchange location - self.z_toolchange_entry = FCDoubleSpinner() + self.z_toolchange_entry = FCDoubleSpinner(callback=self.confirmation_message) self.z_toolchange_entry.set_range(0.0000001, 9999.9999) self.z_toolchange_entry.set_precision(self.decimals) self.z_toolchange_entry.setSingleStep(0.1) @@ -244,7 +244,7 @@ class SolderPaste(FlatCAMTool): self.gcode_form_layout.addRow(self.xy_toolchange_label, self.xy_toolchange_entry) # Feedrate X-Y - self.frxy_entry = FCDoubleSpinner() + self.frxy_entry = FCDoubleSpinner(callback=self.confirmation_message) self.frxy_entry.set_range(0.0000, 99999.9999) self.frxy_entry.set_precision(self.decimals) self.frxy_entry.setSingleStep(0.1) @@ -256,7 +256,7 @@ class SolderPaste(FlatCAMTool): self.gcode_form_layout.addRow(self.frxy_label, self.frxy_entry) # Feedrate Z - self.frz_entry = FCDoubleSpinner() + self.frz_entry = FCDoubleSpinner(callback=self.confirmation_message) self.frz_entry.set_range(0.0000, 99999.9999) self.frz_entry.set_precision(self.decimals) self.frz_entry.setSingleStep(0.1) @@ -269,7 +269,7 @@ class SolderPaste(FlatCAMTool): self.gcode_form_layout.addRow(self.frz_label, self.frz_entry) # Feedrate Z Dispense - self.frz_dispense_entry = FCDoubleSpinner() + self.frz_dispense_entry = FCDoubleSpinner(callback=self.confirmation_message) self.frz_dispense_entry.set_range(0.0000, 99999.9999) self.frz_dispense_entry.set_precision(self.decimals) self.frz_dispense_entry.setSingleStep(0.1) @@ -294,7 +294,7 @@ class SolderPaste(FlatCAMTool): self.gcode_form_layout.addRow(self.speedfwd_label, self.speedfwd_entry) # Dwell Forward - self.dwellfwd_entry = FCDoubleSpinner() + self.dwellfwd_entry = FCDoubleSpinner(callback=self.confirmation_message) self.dwellfwd_entry.set_range(0.0000001, 9999.9999) self.dwellfwd_entry.set_precision(self.decimals) self.dwellfwd_entry.setSingleStep(0.1) @@ -318,7 +318,7 @@ class SolderPaste(FlatCAMTool): self.gcode_form_layout.addRow(self.speedrev_label, self.speedrev_entry) # Dwell Reverse - self.dwellrev_entry = FCDoubleSpinner() + self.dwellrev_entry = FCDoubleSpinner(callback=self.confirmation_message) self.dwellrev_entry.set_range(0.0000001, 9999.9999) self.dwellrev_entry.set_precision(self.decimals) self.dwellrev_entry.setSingleStep(0.1) diff --git a/flatcamTools/ToolTransform.py b/flatcamTools/ToolTransform.py index 04cb1dc8..aa5bd6c7 100644 --- a/flatcamTools/ToolTransform.py +++ b/flatcamTools/ToolTransform.py @@ -68,7 +68,7 @@ class ToolTransform(FlatCAMTool): "Negative numbers for CCW motion.") ) - self.rotate_entry = FCDoubleSpinner() + self.rotate_entry = FCDoubleSpinner(callback=self.confirmation_message) self.rotate_entry.set_precision(self.decimals) self.rotate_entry.setSingleStep(45) self.rotate_entry.setWrapping(True) @@ -103,7 +103,7 @@ class ToolTransform(FlatCAMTool): _("Angle for Skew action, in degrees.\n" "Float number between -360 and 360.") ) - self.skewx_entry = FCDoubleSpinner() + self.skewx_entry = FCDoubleSpinner(callback=self.confirmation_message) # self.skewx_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.skewx_entry.set_precision(self.decimals) self.skewx_entry.set_range(-360, 360) @@ -125,7 +125,7 @@ class ToolTransform(FlatCAMTool): _("Angle for Skew action, in degrees.\n" "Float number between -360 and 360.") ) - self.skewy_entry = FCDoubleSpinner() + self.skewy_entry = FCDoubleSpinner(callback=self.confirmation_message) # self.skewy_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.skewy_entry.set_precision(self.decimals) self.skewy_entry.set_range(-360, 360) @@ -155,7 +155,7 @@ class ToolTransform(FlatCAMTool): self.scalex_label.setToolTip( _("Factor for scaling on X axis.") ) - self.scalex_entry = FCDoubleSpinner() + self.scalex_entry = FCDoubleSpinner(callback=self.confirmation_message) # self.scalex_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.scalex_entry.set_precision(self.decimals) self.scalex_entry.setMinimum(-1e6) @@ -176,7 +176,7 @@ class ToolTransform(FlatCAMTool): self.scaley_label.setToolTip( _("Factor for scaling on Y axis.") ) - self.scaley_entry = FCDoubleSpinner() + self.scaley_entry = FCDoubleSpinner(callback=self.confirmation_message) # self.scaley_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.scaley_entry.set_precision(self.decimals) self.scaley_entry.setMinimum(-1e6) @@ -228,7 +228,7 @@ class ToolTransform(FlatCAMTool): self.offx_label.setToolTip( _("Distance to offset on X axis. In current units.") ) - self.offx_entry = FCDoubleSpinner() + self.offx_entry = FCDoubleSpinner(callback=self.confirmation_message) # self.offx_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.offx_entry.set_precision(self.decimals) self.offx_entry.setMinimum(-1e6) @@ -249,7 +249,7 @@ class ToolTransform(FlatCAMTool): self.offy_label.setToolTip( _("Distance to offset on Y axis. In current units.") ) - self.offy_entry = FCDoubleSpinner() + self.offy_entry = FCDoubleSpinner(callback=self.confirmation_message) # self.offy_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.offy_entry.set_precision(self.decimals) self.offy_entry.setMinimum(-1e6) @@ -353,7 +353,7 @@ class ToolTransform(FlatCAMTool): "or decreased with the 'distance'.") ) - self.buffer_entry = FCDoubleSpinner() + self.buffer_entry = FCDoubleSpinner(callback=self.confirmation_message) self.buffer_entry.set_precision(self.decimals) self.buffer_entry.setSingleStep(0.1) self.buffer_entry.setWrapping(True) diff --git a/preprocessors/default.py b/preprocessors/default.py index 216ba98e..640620f6 100644 --- a/preprocessors/default.py +++ b/preprocessors/default.py @@ -37,6 +37,13 @@ class default(FlatCAMPostProc): gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' + if str(p['options']['type']) == 'Excellon': + gcode += '\n(Tools Offset: )\n' + for tool, val in p['exc_cnc_tools'].items(): + gcode += '(Tool: %s -> ' % str(val['tool']) + 'Dia: %s -> ' % str(tool) + \ + 'Offset Z: %s' % str(val['offset_z']) + ')\n' + gcode += '\n' + if p['multidepth'] is True: gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' diff --git a/tclCommands/TclCommandDrillcncjob.py b/tclCommands/TclCommandDrillcncjob.py index a420f2ae..64404fde 100644 --- a/tclCommands/TclCommandDrillcncjob.py +++ b/tclCommands/TclCommandDrillcncjob.py @@ -169,7 +169,7 @@ class TclCommandDrillcncjob(TclCommandSignaled): else: return "fail" - drillz = args["drillz"] if "drillz" in args and args["drillz"] is not None else obj.options["drillz"] + drillz = args["drillz"] if "drillz" in args and args["drillz"] is not None else obj.options["cutz"] if "toolchangez" in args: toolchange = True @@ -229,9 +229,6 @@ class TclCommandDrillcncjob(TclCommandSignaled): float(job_obj.exc_cnc_tools[t_item]['offset_z']) + float(drillz) job_obj.exc_cnc_tools[t_item]['data']['ppname_e'] = obj.options['ppname_e'] - # for now there is no tool offset support in this Tcl Command so we write the 0.0 value here - job_obj.tool_offset[t_item] = 0.0 - job_obj.origin_kind = 'excellon' job_obj.gcode_parse() From ea1b99242c155a54dae5d63282c180fa5d89d66d Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 17 Feb 2020 04:56:57 +0200 Subject: [PATCH 101/209] - updated all FlatCAM tools to use the new confirmation message for QSpinBoxes, too --- README.md | 1 + flatcamTools/ToolCalculators.py | 2 +- flatcamTools/ToolExtractDrills.py | 2 +- flatcamTools/ToolImage.py | 10 +++++----- flatcamTools/ToolNonCopperClear.py | 2 +- flatcamTools/ToolOptimal.py | 2 +- flatcamTools/ToolPaint.py | 2 +- flatcamTools/ToolPanelize.py | 4 ++-- flatcamTools/ToolPcbWizard.py | 4 ++-- flatcamTools/ToolPunchGerber.py | 2 +- flatcamTools/ToolQRCode.py | 6 +++--- flatcamTools/ToolSolderPaste.py | 4 ++-- flatcamTools/ToolTransform.py | 2 +- 13 files changed, 22 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 501d28a0..09b4835c 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ CAD program, and create G-Code for Isolation routing. - in Excellon UI removed the tools table column for Offset Z and used the UI form parameter - updated the Excellon Editor to add for each tool a 'data' dictionary - updated all FlatCAM tools to use the new confirmation message that show if the entered value is within range or outside +- updated all FlatCAM tools to use the new confirmation message for QSpinBoxes, too 16.02.2020 diff --git a/flatcamTools/ToolCalculators.py b/flatcamTools/ToolCalculators.py index a5b0afca..a7dbda2e 100644 --- a/flatcamTools/ToolCalculators.py +++ b/flatcamTools/ToolCalculators.py @@ -103,7 +103,7 @@ class ToolCalculator(FlatCAMTool): "It is specified by manufacturer.") ) self.tipAngle_label = QtWidgets.QLabel('%s:' % _("Tip Angle")) - self.tipAngle_entry = FCSpinner() + self.tipAngle_entry = FCSpinner(callback=self.confirmation_message_int) self.tipAngle_entry.set_range(0,180) self.tipAngle_entry.setSingleStep(5) diff --git a/flatcamTools/ToolExtractDrills.py b/flatcamTools/ToolExtractDrills.py index 05c1e2d0..5a693300 100644 --- a/flatcamTools/ToolExtractDrills.py +++ b/flatcamTools/ToolExtractDrills.py @@ -276,7 +276,7 @@ class ToolExtractDrills(FlatCAMTool): grid3.addWidget(self.prop_label, 2, 0, 1, 2) # Diameter value - self.factor_entry = FCDoubleSpinner(suffix='%') + self.factor_entry = FCDoubleSpinner(callback=self.confirmation_message, suffix='%') self.factor_entry.set_precision(self.decimals) self.factor_entry.set_range(0.0000, 100.0000) self.factor_entry.setSingleStep(0.1) diff --git a/flatcamTools/ToolImage.py b/flatcamTools/ToolImage.py index a87d7d4b..3e8f2d57 100644 --- a/flatcamTools/ToolImage.py +++ b/flatcamTools/ToolImage.py @@ -61,7 +61,7 @@ class ToolImage(FlatCAMTool): ti_form_layout.addRow(self.tf_type_obj_combo_label, self.tf_type_obj_combo) # DPI value of the imported image - self.dpi_entry = FCSpinner() + self.dpi_entry = FCSpinner(callback=self.confirmation_message_int) self.dpi_entry.set_range(0, 99999) self.dpi_label = QtWidgets.QLabel('%s:' % _("DPI value")) self.dpi_label.setToolTip(_("Specify a DPI value for the image.") ) @@ -87,7 +87,7 @@ class ToolImage(FlatCAMTool): ti2_form_layout.addRow(self.image_type_label, self.image_type) # Mask value of the imported image when image monochrome - self.mask_bw_entry = FCSpinner() + self.mask_bw_entry = FCSpinner(callback=self.confirmation_message_int) self.mask_bw_entry.set_range(0, 255) self.mask_bw_label = QtWidgets.QLabel("%s B/W:" % _('Mask value')) @@ -102,7 +102,7 @@ class ToolImage(FlatCAMTool): ti2_form_layout.addRow(self.mask_bw_label, self.mask_bw_entry) # Mask value of the imported image for RED color when image color - self.mask_r_entry = FCSpinner() + self.mask_r_entry = FCSpinner(callback=self.confirmation_message_int) self.mask_r_entry.set_range(0, 255) self.mask_r_label = QtWidgets.QLabel("%s R:" % _('Mask value')) @@ -115,7 +115,7 @@ class ToolImage(FlatCAMTool): ti2_form_layout.addRow(self.mask_r_label, self.mask_r_entry) # Mask value of the imported image for GREEN color when image color - self.mask_g_entry = FCSpinner() + self.mask_g_entry = FCSpinner(callback=self.confirmation_message_int) self.mask_g_entry.set_range(0, 255) self.mask_g_label = QtWidgets.QLabel("%s G:" % _('Mask value')) @@ -128,7 +128,7 @@ class ToolImage(FlatCAMTool): ti2_form_layout.addRow(self.mask_g_label, self.mask_g_entry) # Mask value of the imported image for BLUE color when image color - self.mask_b_entry = FCSpinner() + self.mask_b_entry = FCSpinner(callback=self.confirmation_message_int) self.mask_b_entry.set_range(0, 255) self.mask_b_label = QtWidgets.QLabel("%s B:" % _('Mask value')) diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNonCopperClear.py index 6a03bdf6..b1c5c65e 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/flatcamTools/ToolNonCopperClear.py @@ -366,7 +366,7 @@ class NonCopperClear(FlatCAMTool, Gerber): "Higher values = slow processing and slow execution on CNC\n" "due of too many paths.") ) - self.ncc_overlap_entry = FCDoubleSpinner(suffix='%') + self.ncc_overlap_entry = FCDoubleSpinner(callback=self.confirmation_message, suffix='%') self.ncc_overlap_entry.set_precision(self.decimals) self.ncc_overlap_entry.setWrapping(True) self.ncc_overlap_entry.setRange(0.000, 99.9999) diff --git a/flatcamTools/ToolOptimal.py b/flatcamTools/ToolOptimal.py index c5cd509d..876b0ded 100644 --- a/flatcamTools/ToolOptimal.py +++ b/flatcamTools/ToolOptimal.py @@ -78,7 +78,7 @@ class ToolOptimal(FlatCAMTool): self.precision_label = QtWidgets.QLabel('%s:' % _("Precision")) self.precision_label.setToolTip(_("Number of decimals kept for found distances.")) - self.precision_spinner = FCSpinner() + self.precision_spinner = FCSpinner(callback=self.confirmation_message_int) self.precision_spinner.set_range(2, 10) self.precision_spinner.setWrapping(True) form_lay.addRow(self.precision_label, self.precision_spinner) diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index abfa7364..d1524a96 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -334,7 +334,7 @@ class ToolPaint(FlatCAMTool, Gerber): "Higher values = slow processing and slow execution on CNC\n" "due of too many paths.") ) - self.paintoverlap_entry = FCDoubleSpinner(suffix='%') + self.paintoverlap_entry = FCDoubleSpinner(callback=self.confirmation_message, suffix='%') self.paintoverlap_entry.set_precision(3) self.paintoverlap_entry.setWrapping(True) self.paintoverlap_entry.setRange(0.0000, 99.9999) diff --git a/flatcamTools/ToolPanelize.py b/flatcamTools/ToolPanelize.py index 9a1e5f7a..8aeddabf 100644 --- a/flatcamTools/ToolPanelize.py +++ b/flatcamTools/ToolPanelize.py @@ -182,7 +182,7 @@ class Panelize(FlatCAMTool): form_layout.addRow(self.spacing_rows_label, self.spacing_rows) # Columns - self.columns = FCSpinner() + self.columns = FCSpinner(callback=self.confirmation_message_int) self.columns.set_range(0, 9999) self.columns_label = QtWidgets.QLabel('%s:' % _("Columns")) @@ -192,7 +192,7 @@ class Panelize(FlatCAMTool): form_layout.addRow(self.columns_label, self.columns) # Rows - self.rows = FCSpinner() + self.rows = FCSpinner(callback=self.confirmation_message_int) self.rows.set_range(0, 9999) self.rows_label = QtWidgets.QLabel('%s:' % _("Rows")) diff --git a/flatcamTools/ToolPcbWizard.py b/flatcamTools/ToolPcbWizard.py index 753b6667..fbd57896 100644 --- a/flatcamTools/ToolPcbWizard.py +++ b/flatcamTools/ToolPcbWizard.py @@ -90,7 +90,7 @@ class PcbWizard(FlatCAMTool): self.layout.addLayout(form_layout1) # Integral part of the coordinates - self.int_entry = FCSpinner() + self.int_entry = FCSpinner(callback=self.confirmation_message_int) self.int_entry.set_range(1, 10) self.int_label = QtWidgets.QLabel('%s:' % _("Int. digits")) self.int_label.setToolTip( @@ -99,7 +99,7 @@ class PcbWizard(FlatCAMTool): form_layout1.addRow(self.int_label, self.int_entry) # Fractional part of the coordinates - self.frac_entry = FCSpinner() + self.frac_entry = FCSpinner(callback=self.confirmation_message_int) self.frac_entry.set_range(1, 10) self.frac_label = QtWidgets.QLabel('%s:' % _("Frac. digits")) self.frac_label.setToolTip( diff --git a/flatcamTools/ToolPunchGerber.py b/flatcamTools/ToolPunchGerber.py index 75bf2495..b0f5c326 100644 --- a/flatcamTools/ToolPunchGerber.py +++ b/flatcamTools/ToolPunchGerber.py @@ -298,7 +298,7 @@ class ToolPunchGerber(FlatCAMTool): grid0.addWidget(self.prop_label, 12, 0, 1, 2) # Diameter value - self.factor_entry = FCDoubleSpinner(suffix='%') + self.factor_entry = FCDoubleSpinner(callback=self.confirmation_message, suffix='%') self.factor_entry.set_precision(self.decimals) self.factor_entry.set_range(0.0000, 100.0000) self.factor_entry.setSingleStep(0.1) diff --git a/flatcamTools/ToolQRCode.py b/flatcamTools/ToolQRCode.py index 7e5aac40..a70b1f63 100644 --- a/flatcamTools/ToolQRCode.py +++ b/flatcamTools/ToolQRCode.py @@ -101,7 +101,7 @@ class QRCode(FlatCAMTool): _("QRCode version can have values from 1 (21x21 boxes)\n" "to 40 (177x177 boxes).") ) - self.version_entry = FCSpinner() + self.version_entry = FCSpinner(callback=self.confirmation_message_int) self.version_entry.set_range(1, 40) self.version_entry.setWrapping(True) @@ -137,7 +137,7 @@ class QRCode(FlatCAMTool): _("Box size control the overall size of the QRcode\n" "by adjusting the size of each box in the code.") ) - self.bsize_entry = FCSpinner() + self.bsize_entry = FCSpinner(callback=self.confirmation_message_int) self.bsize_entry.set_range(1, 9999) self.bsize_entry.setWrapping(True) @@ -150,7 +150,7 @@ class QRCode(FlatCAMTool): _("Size of the QRCode border. How many boxes thick is the border.\n" "Default value is 4. The width of the clearance around the QRCode.") ) - self.border_size_entry = FCSpinner() + self.border_size_entry = FCSpinner(callback=self.confirmation_message_int) self.border_size_entry.set_range(1, 9999) self.border_size_entry.setWrapping(True) self.border_size_entry.set_value(4) diff --git a/flatcamTools/ToolSolderPaste.py b/flatcamTools/ToolSolderPaste.py index 9f268a3e..0626a4c9 100644 --- a/flatcamTools/ToolSolderPaste.py +++ b/flatcamTools/ToolSolderPaste.py @@ -282,7 +282,7 @@ class SolderPaste(FlatCAMTool): self.gcode_form_layout.addRow(self.frz_dispense_label, self.frz_dispense_entry) # Spindle Speed Forward - self.speedfwd_entry = FCSpinner() + self.speedfwd_entry = FCSpinner(callback=self.confirmation_message_int) self.speedfwd_entry.set_range(0, 999999) self.speedfwd_entry.setSingleStep(1000) @@ -306,7 +306,7 @@ class SolderPaste(FlatCAMTool): self.gcode_form_layout.addRow(self.dwellfwd_label, self.dwellfwd_entry) # Spindle Speed Reverse - self.speedrev_entry = FCSpinner() + self.speedrev_entry = FCSpinner(callback=self.confirmation_message_int) self.speedrev_entry.set_range(0, 999999) self.speedrev_entry.setSingleStep(1000) diff --git a/flatcamTools/ToolTransform.py b/flatcamTools/ToolTransform.py index aa5bd6c7..cebe6953 100644 --- a/flatcamTools/ToolTransform.py +++ b/flatcamTools/ToolTransform.py @@ -380,7 +380,7 @@ class ToolTransform(FlatCAMTool): "of the initial dimension.") ) - self.buffer_factor_entry = FCDoubleSpinner(suffix='%') + self.buffer_factor_entry = FCDoubleSpinner(callback=self.confirmation_message, suffix='%') self.buffer_factor_entry.set_range(-100.0000, 1000.0000) self.buffer_factor_entry.set_precision(self.decimals) self.buffer_factor_entry.setWrapping(True) From ae22ddb516a9090c8c8f60e3af1b9e258f367511 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 17 Feb 2020 05:19:21 +0200 Subject: [PATCH 102/209] - in Excellon UI protected the values that are common parameters from change on tool selection change --- FlatCAMObj.py | 3 ++- README.md | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 1e0119e5..4c71180b 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -3028,7 +3028,8 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): def storage_to_form(self, dict_storage): for form_key in self.form_fields: for storage_key in dict_storage: - if form_key == storage_key: + if form_key == storage_key and form_key not in \ + ["toolchangez", "startz", "endz", "ppname_e", "ppname_g"]: try: self.form_fields[form_key].set_value(dict_storage[form_key]) except Exception as e: diff --git a/README.md b/README.md index 09b4835c..a1c37433 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ CAD program, and create G-Code for Isolation routing. - updated the Excellon Editor to add for each tool a 'data' dictionary - updated all FlatCAM tools to use the new confirmation message that show if the entered value is within range or outside - updated all FlatCAM tools to use the new confirmation message for QSpinBoxes, too +- in Excellon UI protected the values that are common parameters from change on tool selection change 16.02.2020 From 7292a30b9ef91b403d6374a58bc95bbc6e030ff0 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 17 Feb 2020 14:27:45 +0200 Subject: [PATCH 103/209] - fixed some issues realted to the usage of the new confirmation message in FlatCAM Tools - made sure that the FlatCAM Tools UI initialization is done only in set_tool_ui() method and not in the constructor --- FlatCAMCommon.py | 2 +- README.md | 2 ++ flatcamGUI/GUIElements.py | 7 +++++++ flatcamGUI/ObjectUI.py | 5 +++-- flatcamGUI/PreferencesUI.py | 29 +++++++++++++++-------------- flatcamTools/ToolCalculators.py | 2 +- flatcamTools/ToolCalibration.py | 5 +++-- flatcamTools/ToolDistanceMin.py | 9 --------- flatcamTools/ToolOptimal.py | 6 +++--- flatcamTools/ToolQRCode.py | 3 ++- flatcamTools/ToolSolderPaste.py | 4 ++-- flatcamTools/ToolTransform.py | 31 ++++++++++++++++--------------- 12 files changed, 55 insertions(+), 50 deletions(-) diff --git a/FlatCAMCommon.py b/FlatCAMCommon.py index d4a7f0ff..2bc95131 100644 --- a/FlatCAMCommon.py +++ b/FlatCAMCommon.py @@ -927,7 +927,7 @@ class ToolsDB(QtWidgets.QWidget): spindlespeed_item = FCSpinner() spindlespeed_item.set_range(0, 1000000) spindlespeed_item.set_value(int(data['spindlespeed'])) - spindlespeed_item.setSingleStep(100) + spindlespeed_item.set_step(100) widget.setCellWidget(row, 16, spindlespeed_item) dwell_item = FCCheckBox() diff --git a/README.md b/README.md index a1c37433..be19c4c3 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,8 @@ CAD program, and create G-Code for Isolation routing. - updated all FlatCAM tools to use the new confirmation message that show if the entered value is within range or outside - updated all FlatCAM tools to use the new confirmation message for QSpinBoxes, too - in Excellon UI protected the values that are common parameters from change on tool selection change +- fixed some issues realted to the usage of the new confirmation message in FlatCAM Tools +- made sure that the FlatCAM Tools UI initialization is done only in set_tool_ui() method and not in the constructor 16.02.2020 diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index de4fd34f..d53575d2 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -670,7 +670,14 @@ class FCSpinner(QtWidgets.QSpinBox): return QtGui.QValidator.Acceptable, p_str, p_int def set_range(self, min_val, max_val): + self.blockSignals(True) self.setRange(min_val, max_val) + self.blockSignals(False) + + def set_step(self, p_int): + self.blockSignals(True) + self.setSingleStep(p_int) + self.blockSignals(False) # def sizeHint(self): # default_hint_size = super(FCSpinner, self).sizeHint() diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index ab30498d..c4204765 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -386,6 +386,7 @@ class GerberObjectUI(ObjectUI): passlabel.setMinimumWidth(90) self.iso_width_entry = FCSpinner(callback=self.confirmation_message_int) self.iso_width_entry.set_range(1, 999) + grid1.addWidget(passlabel, 5, 0) grid1.addWidget(self.iso_width_entry, 5, 1, 1, 2) @@ -1054,7 +1055,7 @@ class ExcellonObjectUI(ObjectUI): self.spindlespeed_entry = FCSpinner(callback=self.confirmation_message_int) self.spindlespeed_entry.set_range(0, 1000000) - self.spindlespeed_entry.setSingleStep(100) + self.spindlespeed_entry.set_step(100) self.spindlespeed_entry.setObjectName("e_spindlespeed") self.grid3.addWidget(self.spindle_label, 19, 0) @@ -1823,7 +1824,7 @@ class GeometryObjectUI(ObjectUI): ) self.cncspindlespeed_entry = FCSpinner(callback=self.confirmation_message_int) self.cncspindlespeed_entry.set_range(0, 1000000) - self.cncspindlespeed_entry.setSingleStep(100) + self.cncspindlespeed_entry.set_step(100) self.grid3.addWidget(self.spindle_label, 14, 0) self.grid3.addWidget(self.cncspindlespeed_entry, 14, 1) diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index e3fd5fff..0c5537c8 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -1133,7 +1133,7 @@ class GeneralAPPSetGroupUI(OptionsGroupUI): ) self.notebook_font_size_spinner = FCSpinner() - self.notebook_font_size_spinner.setRange(8, 40) + self.notebook_font_size_spinner.set_range(8, 40) self.notebook_font_size_spinner.setWrapping(True) settings = QSettings("Open Source", "FlatCAM") @@ -1152,7 +1152,7 @@ class GeneralAPPSetGroupUI(OptionsGroupUI): ) self.axis_font_size_spinner = FCSpinner() - self.axis_font_size_spinner.setRange(0, 40) + self.axis_font_size_spinner.set_range(0, 40) self.axis_font_size_spinner.setWrapping(True) settings = QSettings("Open Source", "FlatCAM") @@ -1172,7 +1172,7 @@ class GeneralAPPSetGroupUI(OptionsGroupUI): ) self.textbox_font_size_spinner = FCSpinner() - self.textbox_font_size_spinner.setRange(8, 40) + self.textbox_font_size_spinner.set_range(8, 40) self.textbox_font_size_spinner.setWrapping(True) settings = QSettings("Open Source", "FlatCAM") @@ -1342,6 +1342,7 @@ class GeneralAPPSetGroupUI(OptionsGroupUI): # Bookmarks Limit in the Help Menu self.bm_limit_spinner = FCSpinner() + self.bm_limit_spinner.set_range(0, 9999) self.bm_limit_label = QtWidgets.QLabel('%s:' % _('Bookmarks limit')) self.bm_limit_label.setToolTip( _("The maximum number of bookmarks that may be installed in the menu.\n" @@ -2040,7 +2041,7 @@ class GerberOptPrefGroupUI(OptionsGroupUI): "number (integer) of tool widths.") ) self.iso_width_entry = FCSpinner() - self.iso_width_entry.setRange(1, 999) + self.iso_width_entry.set_range(1, 999) grid0.addWidget(passlabel, 1, 0) grid0.addWidget(self.iso_width_entry, 1, 1) @@ -2247,7 +2248,7 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI): ) self.tipangle_spinner = FCSpinner() self.tipangle_spinner.set_range(1, 180) - self.tipangle_spinner.setSingleStep(5) + self.tipangle_spinner.set_step(5) self.tipangle_spinner.setWrapping(True) grid0.addWidget(self.tipanglelabel, 5, 0) grid0.addWidget(self.tipangle_spinner, 5, 1, 1, 2) @@ -2379,7 +2380,7 @@ class GerberExpPrefGroupUI(OptionsGroupUI): self.format_whole_entry = FCSpinner() self.format_whole_entry.set_range(0, 9) - self.format_whole_entry.setSingleStep(1) + self.format_whole_entry.set_step(1) self.format_whole_entry.setWrapping(True) self.format_whole_entry.setMinimumWidth(30) @@ -2395,7 +2396,7 @@ class GerberExpPrefGroupUI(OptionsGroupUI): self.format_dec_entry = FCSpinner() self.format_dec_entry.set_range(0, 9) - self.format_dec_entry.setSingleStep(1) + self.format_dec_entry.set_step(1) self.format_dec_entry.setWrapping(True) self.format_dec_entry.setMinimumWidth(30) @@ -3252,7 +3253,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): self.spindlespeed_entry = FCSpinner() self.spindlespeed_entry.set_range(0, 1000000) - self.spindlespeed_entry.setSingleStep(100) + self.spindlespeed_entry.set_step(100) grid2.addWidget(spdlabel, 10, 0) grid2.addWidget(self.spindlespeed_entry, 10, 1) @@ -4207,7 +4208,7 @@ class GeometryOptPrefGroupUI(OptionsGroupUI): grid1.addWidget(spdlabel, 9, 0) self.cncspindlespeed_entry = FCSpinner() self.cncspindlespeed_entry.set_range(0, 1000000) - self.cncspindlespeed_entry.setSingleStep(100) + self.cncspindlespeed_entry.set_step(100) grid1.addWidget(self.cncspindlespeed_entry, 9, 1) @@ -6258,7 +6259,7 @@ class ToolsPanelizePrefGroupUI(OptionsGroupUI): # ## Columns self.pcolumns = FCSpinner() self.pcolumns.set_range(1, 1000) - self.pcolumns.setSingleStep(1) + self.pcolumns.set_step(1) self.columns_label = QtWidgets.QLabel('%s:' % _("Columns")) self.columns_label.setToolTip( @@ -6270,7 +6271,7 @@ class ToolsPanelizePrefGroupUI(OptionsGroupUI): # ## Rows self.prows = FCSpinner() self.prows.set_range(1, 1000) - self.prows.setSingleStep(1) + self.prows.set_step(1) self.rows_label = QtWidgets.QLabel('%s:' % _("Rows")) self.rows_label.setToolTip( @@ -6848,7 +6849,7 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI): # Spindle Speed Forward self.speedfwd_entry = FCSpinner() self.speedfwd_entry.set_range(0, 99999) - self.speedfwd_entry.setSingleStep(1000) + self.speedfwd_entry.set_step(1000) self.speedfwd_label = QtWidgets.QLabel('%s:' % _("Spindle Speed FWD")) self.speedfwd_label.setToolTip( @@ -6874,7 +6875,7 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI): # Spindle Speed Reverse self.speedrev_entry = FCSpinner() self.speedrev_entry.set_range(0, 999999) - self.speedrev_entry.setSingleStep(1000) + self.speedrev_entry.set_step(1000) self.speedrev_label = QtWidgets.QLabel('%s:' % _("Spindle Speed REV")) self.speedrev_label.setToolTip( @@ -7180,7 +7181,7 @@ class Tools2OptimalPrefGroupUI(OptionsGroupUI): self.precision_sp = FCSpinner() self.precision_sp.set_range(2, 10) - self.precision_sp.setSingleStep(1) + self.precision_sp.set_step(1) self.precision_sp.setWrapping(True) self.precision_lbl = QtWidgets.QLabel('%s:' % _("Precision")) diff --git a/flatcamTools/ToolCalculators.py b/flatcamTools/ToolCalculators.py index a7dbda2e..086ab83e 100644 --- a/flatcamTools/ToolCalculators.py +++ b/flatcamTools/ToolCalculators.py @@ -105,7 +105,7 @@ class ToolCalculator(FlatCAMTool): self.tipAngle_label = QtWidgets.QLabel('%s:' % _("Tip Angle")) self.tipAngle_entry = FCSpinner(callback=self.confirmation_message_int) self.tipAngle_entry.set_range(0,180) - self.tipAngle_entry.setSingleStep(5) + self.tipAngle_entry.set_step(5) # self.tipAngle_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.tipAngle_label.setToolTip(_("This is the angle of the tip of the tool.\n" diff --git a/flatcamTools/ToolCalibration.py b/flatcamTools/ToolCalibration.py index cc964b1a..ae83edb6 100644 --- a/flatcamTools/ToolCalibration.py +++ b/flatcamTools/ToolCalibration.py @@ -263,8 +263,6 @@ class ToolCalibration(FlatCAMTool): self.bottom_left_coordy_found = EvalEntry() self.points_table.setCellWidget(row, 3, self.bottom_left_coordy_found) - self.bottom_left_coordx_found.set_value(_("Origin")) - self.bottom_left_coordy_found.set_value(_("Origin")) self.bottom_left_coordx_found.setDisabled(True) self.bottom_left_coordy_found.setDisabled(True) row += 1 @@ -770,6 +768,9 @@ class ToolCalibration(FlatCAMTool): if self.local_connected is True: self.disconnect_cal_events() + self.bottom_left_coordx_found.set_value(_("Origin")) + self.bottom_left_coordy_found.set_value(_("Origin")) + self.reset_calibration_points() self.cal_source_radio.set_value(self.app.defaults['tools_cal_calsource']) diff --git a/flatcamTools/ToolDistanceMin.py b/flatcamTools/ToolDistanceMin.py index 08bfc62f..485fca3b 100644 --- a/flatcamTools/ToolDistanceMin.py +++ b/flatcamTools/ToolDistanceMin.py @@ -128,15 +128,6 @@ class DistanceMin(FlatCAMTool): form_layout.addRow(self.total_distance_label, self.total_distance_entry) form_layout.addRow(self.half_point_label, self.half_point_entry) - # initial view of the layout - self.start_entry.set_value('(0, 0)') - self.stop_entry.set_value('(0, 0)') - self.distance_x_entry.set_value('0.0') - self.distance_y_entry.set_value('0.0') - self.angle_entry.set_value('0.0') - self.total_distance_entry.set_value('0.0') - self.half_point_entry.set_value('(0, 0)') - self.layout.addStretch() self.h_point = (0, 0) diff --git a/flatcamTools/ToolOptimal.py b/flatcamTools/ToolOptimal.py index 876b0ded..5160fc81 100644 --- a/flatcamTools/ToolOptimal.py +++ b/flatcamTools/ToolOptimal.py @@ -282,9 +282,6 @@ class ToolOptimal(FlatCAMTool): def run(self, toggle=True): self.app.report_usage("ToolOptimal()") - self.result_entry.set_value(0.0) - self.freq_entry.set_value('0') - if toggle: # if the splitter is hidden, display it, else hide it but only if the current widget is the same if self.app.ui.splitter.sizes()[0] == 0: @@ -310,6 +307,9 @@ class ToolOptimal(FlatCAMTool): self.app.ui.notebook.setTabText(2, _("Optimal Tool")) def set_tool_ui(self): + self.result_entry.set_value(0.0) + self.freq_entry.set_value('0') + self.precision_spinner.set_value(int(self.app.defaults["tools_opt_precision"])) self.locations_textb.clear() # new cursor - select all document diff --git a/flatcamTools/ToolQRCode.py b/flatcamTools/ToolQRCode.py index a70b1f63..5e9b8ff0 100644 --- a/flatcamTools/ToolQRCode.py +++ b/flatcamTools/ToolQRCode.py @@ -153,7 +153,6 @@ class QRCode(FlatCAMTool): self.border_size_entry = FCSpinner(callback=self.confirmation_message_int) self.border_size_entry.set_range(1, 9999) self.border_size_entry.setWrapping(True) - self.border_size_entry.set_value(4) grid_lay.addWidget(self.border_size_label, 4, 0) grid_lay.addWidget(self.border_size_entry, 4, 1) @@ -386,6 +385,8 @@ class QRCode(FlatCAMTool): def set_tool_ui(self): self.units = self.app.defaults['units'] + self.border_size_entry.set_value(4) + self.version_entry.set_value(int(self.app.defaults["tools_qrcode_version"])) self.error_radio.set_value(self.app.defaults["tools_qrcode_error"]) self.bsize_entry.set_value(int(self.app.defaults["tools_qrcode_box_size"])) diff --git a/flatcamTools/ToolSolderPaste.py b/flatcamTools/ToolSolderPaste.py index 0626a4c9..655ab3aa 100644 --- a/flatcamTools/ToolSolderPaste.py +++ b/flatcamTools/ToolSolderPaste.py @@ -284,7 +284,7 @@ class SolderPaste(FlatCAMTool): # Spindle Speed Forward self.speedfwd_entry = FCSpinner(callback=self.confirmation_message_int) self.speedfwd_entry.set_range(0, 999999) - self.speedfwd_entry.setSingleStep(1000) + self.speedfwd_entry.set_step(1000) self.speedfwd_label = QtWidgets.QLabel('%s:' % _("Spindle Speed FWD")) self.speedfwd_label.setToolTip( @@ -308,7 +308,7 @@ class SolderPaste(FlatCAMTool): # Spindle Speed Reverse self.speedrev_entry = FCSpinner(callback=self.confirmation_message_int) self.speedrev_entry.set_range(0, 999999) - self.speedrev_entry.setSingleStep(1000) + self.speedrev_entry.set_step(1000) self.speedrev_label = QtWidgets.QLabel('%s:' % _("Spindle Speed REV")) self.speedrev_label.setToolTip( diff --git a/flatcamTools/ToolTransform.py b/flatcamTools/ToolTransform.py index cebe6953..8ce0eff5 100644 --- a/flatcamTools/ToolTransform.py +++ b/flatcamTools/ToolTransform.py @@ -77,7 +77,6 @@ class ToolTransform(FlatCAMTool): # self.rotate_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.rotate_button = FCButton() - self.rotate_button.set_value(_("Rotate")) self.rotate_button.setToolTip( _("Rotate the selected object(s).\n" "The point of reference is the middle of\n" @@ -109,7 +108,6 @@ class ToolTransform(FlatCAMTool): self.skewx_entry.set_range(-360, 360) self.skewx_button = FCButton() - self.skewx_button.set_value(_("Skew X")) self.skewx_button.setToolTip( _("Skew/shear the selected object(s).\n" "The point of reference is the middle of\n" @@ -131,7 +129,6 @@ class ToolTransform(FlatCAMTool): self.skewy_entry.set_range(-360, 360) self.skewy_button = FCButton() - self.skewy_button.set_value(_("Skew Y")) self.skewy_button.setToolTip( _("Skew/shear the selected object(s).\n" "The point of reference is the middle of\n" @@ -161,7 +158,6 @@ class ToolTransform(FlatCAMTool): self.scalex_entry.setMinimum(-1e6) self.scalex_button = FCButton() - self.scalex_button.set_value(_("Scale X")) self.scalex_button.setToolTip( _("Scale the selected object(s).\n" "The point of reference depends on \n" @@ -182,7 +178,6 @@ class ToolTransform(FlatCAMTool): self.scaley_entry.setMinimum(-1e6) self.scaley_button = FCButton() - self.scaley_button.set_value(_("Scale Y")) self.scaley_button.setToolTip( _("Scale the selected object(s).\n" "The point of reference depends on \n" @@ -194,7 +189,6 @@ class ToolTransform(FlatCAMTool): grid0.addWidget(self.scaley_button, 9, 2) self.scale_link_cb = FCCheckBox() - self.scale_link_cb.set_value(True) self.scale_link_cb.setText(_("Link")) self.scale_link_cb.setToolTip( _("Scale the selected object(s)\n" @@ -202,7 +196,6 @@ class ToolTransform(FlatCAMTool): ) self.scale_zero_ref_cb = FCCheckBox() - self.scale_zero_ref_cb.set_value(True) self.scale_zero_ref_cb.setText('%s' % _("Scale Reference")) self.scale_zero_ref_cb.setToolTip( _("Scale the selected object(s)\n" @@ -234,7 +227,6 @@ class ToolTransform(FlatCAMTool): self.offx_entry.setMinimum(-1e6) self.offx_button = FCButton() - self.offx_button.set_value(_("Offset X")) self.offx_button.setToolTip( _("Offset the selected object(s).\n" "The point of reference is the middle of\n" @@ -255,7 +247,6 @@ class ToolTransform(FlatCAMTool): self.offy_entry.setMinimum(-1e6) self.offy_button = FCButton() - self.offy_button.set_value(_("Offset Y")) self.offy_button.setToolTip( _("Offset the selected object(s).\n" "The point of reference is the middle of\n" @@ -276,13 +267,11 @@ class ToolTransform(FlatCAMTool): grid0.addWidget(flip_title_label, 16, 0, 1, 3) self.flipx_button = FCButton() - self.flipx_button.set_value(_("Flip on X")) self.flipx_button.setToolTip( _("Flip the selected object(s) over the X axis.") ) self.flipy_button = FCButton() - self.flipy_button.set_value(_("Flip on Y")) self.flipy_button.setToolTip( _("Flip the selected object(s) over the X axis.") ) @@ -294,7 +283,6 @@ class ToolTransform(FlatCAMTool): hlay0.addWidget(self.flipy_button) self.flip_ref_cb = FCCheckBox() - self.flip_ref_cb.set_value(True) self.flip_ref_cb.setText('%s' % _("Mirror Reference")) self.flip_ref_cb.setToolTip( _("Flip the selected object(s)\n" @@ -320,7 +308,6 @@ class ToolTransform(FlatCAMTool): # self.flip_ref_entry.setFixedWidth(70) self.flip_ref_button = FCButton() - self.flip_ref_button.set_value(_("Add")) self.flip_ref_button.setToolTip( _("The point coordinates can be captured by\n" "left click on canvas together with pressing\n" @@ -360,7 +347,6 @@ class ToolTransform(FlatCAMTool): self.buffer_entry.set_range(-9999.9999, 9999.9999) self.buffer_button = FCButton() - self.buffer_button.set_value(_("Buffer D")) self.buffer_button.setToolTip( _("Create the buffer effect on each geometry,\n" "element from the selected object, using the distance.") @@ -387,7 +373,6 @@ class ToolTransform(FlatCAMTool): self.buffer_factor_entry.setSingleStep(1) self.buffer_factor_button = FCButton() - self.buffer_factor_button.set_value(_("Buffer F")) self.buffer_factor_button.setToolTip( _("Create the buffer effect on each geometry,\n" "element from the selected object, using the factor.") @@ -481,6 +466,22 @@ class ToolTransform(FlatCAMTool): FlatCAMTool.install(self, icon, separator, shortcut='ALT+T', **kwargs) def set_tool_ui(self): + self.rotate_button.set_value(_("Rotate")) + self.skewx_button.set_value(_("Skew X")) + self.skewy_button.set_value(_("Skew Y")) + self.scalex_button.set_value(_("Scale X")) + self.scaley_button.set_value(_("Scale Y")) + self.scale_link_cb.set_value(True) + self.scale_zero_ref_cb.set_value(True) + self.offx_button.set_value(_("Offset X")) + self.offy_button.set_value(_("Offset Y")) + self.flipx_button.set_value(_("Flip on X")) + self.flipy_button.set_value(_("Flip on Y")) + self.flip_ref_cb.set_value(True) + self.flip_ref_button.set_value(_("Add")) + self.buffer_button.set_value(_("Buffer D")) + self.buffer_factor_button.set_value(_("Buffer F")) + # ## Initialize form if self.app.defaults["tools_transform_rotate"]: self.rotate_entry.set_value(self.app.defaults["tools_transform_rotate"]) From 124ba6cdc684b95672967117e4faf0663d2cd93a Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 17 Feb 2020 16:35:09 +0200 Subject: [PATCH 104/209] - adapted the GCode generation from Excellon to work with multiple tools data and modified the preprocessors header --- FlatCAMObj.py | 20 ++- README.md | 1 + camlib.py | 170 ++++++++++++++++++------ preprocessors/Berta_CNC.py | 57 ++++++-- preprocessors/ISEL_CNC.py | 61 ++++++--- preprocessors/ISEL_ICP_CNC.py | 85 ++++++++---- preprocessors/Marlin.py | 67 +++++++--- preprocessors/Repetier.py | 67 +++++++--- preprocessors/Toolchange_Custom.py | 63 ++++++--- preprocessors/Toolchange_Probe_MACH3.py | 65 ++++++--- preprocessors/Toolchange_manual.py | 63 ++++++--- preprocessors/default.py | 62 ++++++--- preprocessors/grbl_11.py | 69 +++++++--- preprocessors/line_xyz.py | 65 ++++++--- 14 files changed, 663 insertions(+), 252 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 4c71180b..f451f30d 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -3673,20 +3673,16 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): job_obj.z_pdepth = float(self.options["z_pdepth"]) job_obj.feedrate_probe = float(self.options["feedrate_probe"]) - # There could be more than one drill size... - # job_obj.tooldia = # TODO: duplicate variable! - # job_obj.options["tooldia"] = + job_obj.z_cut = float(self.options['cutz']) + job_obj.toolchange = self.options["toolchange"] + job_obj.xy_toolchange = self.app.defaults["excellon_toolchangexy"] + job_obj.z_toolchange = float(self.options["toolchangez"]) + job_obj.startz = float(self.options["startz"]) if self.options["startz"] else None + job_obj.endz = float(self.options["endz"]) + job_obj.excellon_optimization_type = self.app.defaults["excellon_optimization_type"] tools_csv = ','.join(tools) - ret_val = job_obj.generate_from_excellon_by_tool( - self, tools_csv, - drillz=float(self.options['cutz']), - toolchange=self.options["toolchange"], - toolchangexy=self.app.defaults["excellon_toolchangexy"], - toolchangez=float(self.options["toolchangez"]), - startz=float(self.options["startz"]) if self.options["startz"] else None, - endz=float(self.options["endz"]), - excellon_optimization_type=self.app.defaults["excellon_optimization_type"]) + ret_val = job_obj.generate_from_excellon_by_tool(self, tools_csv, use_ui=True) if ret_val == 'fail': return 'fail' diff --git a/README.md b/README.md index be19c4c3..08c2b639 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ CAD program, and create G-Code for Isolation routing. - in Excellon UI protected the values that are common parameters from change on tool selection change - fixed some issues realted to the usage of the new confirmation message in FlatCAM Tools - made sure that the FlatCAM Tools UI initialization is done only in set_tool_ui() method and not in the constructor +- adapted the GCode generation from Excellon to work with multiple tools data and modified the preprocessors header 16.02.2020 diff --git a/camlib.py b/camlib.py index f296b113..46877405 100644 --- a/camlib.py +++ b/camlib.py @@ -2428,11 +2428,9 @@ class CNCjob(Geometry): Geometry.__init__(self, geo_steps_per_circle=self.steps_per_circle) self.kind = kind - self.units = units self.z_cut = z_cut - self.z_move = z_move self.feedrate = feedrate @@ -2440,6 +2438,7 @@ class CNCjob(Geometry): self.feedrate_rapid = feedrate_rapid self.tooldia = tooldia + self.toolchange = False self.z_toolchange = toolchangez self.xy_toolchange = toolchange_xy self.toolchange_xy_type = None @@ -2452,6 +2451,11 @@ class CNCjob(Geometry): self.multidepth = False self.z_depthpercut = depthpercut + self.excellon_optimization_type = 'B' + + # if set True then the GCode generation will use UI; used in Excellon GVode for now + self.use_ui = False + self.unitcode = {"IN": "G20", "MM": "G21"} self.feedminutecode = "G94" @@ -2504,6 +2508,7 @@ class CNCjob(Geometry): # used for creating drill CCode geometry; will be updated in the generate_from_excellon_by_tool() self.exc_drills = None + # store here the Excellon source object tools to be accessible locally self.exc_tools = None # search for toolchange parameters in the Toolchange Custom Code @@ -2599,8 +2604,7 @@ class CNCjob(Geometry): must_visit.remove(nearest) return path - def generate_from_excellon_by_tool(self, exobj, tools="all", drillz=3.0, toolchange=False, toolchangez=0.1, - toolchangexy='', endz=2.0, startz=None, excellon_optimization_type='B'): + def generate_from_excellon_by_tool(self, exobj, tools="all", use_ui=False): """ Creates gcode for this object from an Excellon object for the specified tools. @@ -2609,21 +2613,7 @@ class CNCjob(Geometry): :type exobj: Excellon :param tools: Comma separated tool names :type: tools: str - :param drillz: drill Z depth - :type drillz: float - :param toolchange: Use tool change sequence between tools. - :type toolchange: bool - :param toolchangez: Height at which to perform the tool change. - :type toolchangez: float - :param toolchangexy: Toolchange X,Y position - :type toolchangexy: String containing 2 floats separated by comma - :param startz: Z position just before starting the job - :type startz: float - :param endz: final Z position to move to at the end of the CNC job - :type endz: float - :param excellon_optimization_type: Single character that defines which drill re-ordering optimisation algorithm - is to be used: 'M' for meta-heuristic and 'B' for basic - :type excellon_optimization_type: string + :param use_ui: Bool, if True the method will use parameters set in UI :return: None :rtype: None """ @@ -2632,31 +2622,31 @@ class CNCjob(Geometry): self.exc_drills = deepcopy(exobj.drills) self.exc_tools = deepcopy(exobj.tools) - self.z_cut = deepcopy(drillz) - old_zcut = deepcopy(drillz) + # the Excellon GCode preprocessor will use this info in the start_code() method + self.use_ui = True if use_ui else False + + old_zcut = deepcopy(self.z_cut) if self.machinist_setting == 0: - if drillz > 0: + if self.z_cut > 0: self.app.inform.emit('[WARNING] %s' % _("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.z_cut = -self.z_cut + elif self.z_cut == 0: self.app.inform.emit('[WARNING] %s: %s' % (_("The Cut Z parameter is zero. There will be no cut, skipping file"), exobj.options['name'])) return 'fail' - self.z_toolchange = toolchangez - try: - if toolchangexy == '': + if self.xy_toolchange == '': self.xy_toolchange = None else: - self.xy_toolchange = [float(eval(a)) for a in toolchangexy.split(",")] + self.xy_toolchange = [float(eval(a)) for a in self.xy_toolchange.split(",")] if len(self.xy_toolchange) < 2: self.app.inform.emit('[ERROR]%s' % _("The Toolchange X,Y field in Edit -> Preferences has to be " @@ -2666,9 +2656,6 @@ class CNCjob(Geometry): log.debug("camlib.CNCJob.generate_from_excellon_by_tool() --> %s" % str(e)) pass - self.startz = startz - self.z_end = endz - self.pp_excellon = self.app.preprocessors[self.pp_excellon_name] p = self.pp_excellon @@ -2751,6 +2738,7 @@ class CNCjob(Geometry): ) self.app.inform.emit(_("Creating a list of points to drill...")) + # Points (Group by tool) points = dict() for drill in exobj.drills: @@ -2773,9 +2761,10 @@ class CNCjob(Geometry): # Initialization gcode = self.doformat(p.start_code) - gcode += self.doformat(p.feedrate_code) + if not use_ui: + gcode += self.doformat(p.z_feedrate_code) - if toolchange is False: + if self.toolchange is False: if self.xy_toolchange is not None: gcode += self.doformat(p.lift_code, x=self.xy_toolchange[0], y=self.xy_toolchange[1]) gcode += self.doformat(p.startz_code, x=self.xy_toolchange[0], y=self.xy_toolchange[1]) @@ -2836,18 +2825,50 @@ class CNCjob(Geometry): current_platform = platform.architecture()[0] if current_platform == '64bit': - used_excellon_optimization_type = excellon_optimization_type + used_excellon_optimization_type = self.excellon_optimization_type if used_excellon_optimization_type == 'M': log.debug("Using OR-Tools Metaheuristic Guided Local Search drill path optimization.") if exobj.drills: for tool in tools: + if self.app.abort_flag: + # graceful abort requested by the user + raise FlatCAMApp.GracefulException + self.tool = tool self.postdata['toolC'] = exobj.tools[tool]["C"] self.tooldia = exobj.tools[tool]["C"] - if self.app.abort_flag: - # graceful abort requested by the user - raise FlatCAMApp.GracefulException + if use_ui: + self.z_feedrate = exobj.tools[tool]['data']['feedrate_z'] + self.feedrate = exobj.tools[tool]['data']['feedrate'] + gcode += self.doformat(p.z_feedrate_code) + + self.z_cut = exobj.tools[tool]['data']['cutz'] + + if self.machinist_setting == 0: + if self.z_cut > 0: + self.app.inform.emit('[WARNING] %s' % + _("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 = -self.z_cut + elif self.z_cut == 0: + self.app.inform.emit('[WARNING] %s: %s' % + (_( + "The Cut Z parameter is zero. There will be no cut, skipping file"), + exobj.options['name'])) + return 'fail' + + old_zcut = deepcopy(self.z_cut) + + self.z_move = exobj.tools[tool]['data']['travelz'] + self.spindlespeed = exobj.tools[tool]['data']['spindlespeed'] + self.dwell = exobj.tools[tool]['data']['dwell'] + self.dwelltime = exobj.tools[tool]['data']['dwelltime'] + self.multidepth = exobj.tools[tool]['data']['multidepth'] + self.z_depthpercut = exobj.tools[tool]['data']['depthperpass'] # ############################################### # ############ Create the data. ################# @@ -2914,7 +2935,7 @@ class CNCjob(Geometry): raise FlatCAMApp.GracefulException # Tool change sequence (optional) - if toolchange: + if self.toolchange: gcode += self.doformat(p.toolchange_code, toolchangexy=(self.oldx, self.oldy)) gcode += self.doformat(p.spindle_code) # Spindle start if self.dwell is True: @@ -3031,7 +3052,42 @@ class CNCjob(Geometry): self.postdata['toolC']=exobj.tools[tool]["C"] self.tooldia = exobj.tools[tool]["C"] - # ############################################# ## + if use_ui: + self.z_feedrate = exobj.tools[tool]['data']['feedrate_z'] + self.feedrate = exobj.tools[tool]['data']['feedrate'] + gcode += self.doformat(p.z_feedrate_code) + self.z_cut = exobj.tools[tool]['data']['cutz'] + + if self.machinist_setting == 0: + if self.z_cut > 0: + self.app.inform.emit('[WARNING] %s' % + _("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 = -self.z_cut + elif self.z_cut == 0: + self.app.inform.emit('[WARNING] %s: %s' % + (_( + "The Cut Z parameter is zero. There will be no cut, skipping file"), + exobj.options['name'])) + return 'fail' + + old_zcut = deepcopy(self.z_cut) + + self.z_move = exobj.tools[tool]['data']['travelz'] + print(self.z_move) + self.spindlespeed = exobj.tools[tool]['data']['spindlespeed'] + self.dwell = exobj.tools[tool]['data']['dwell'] + self.dwelltime = exobj.tools[tool]['data']['dwelltime'] + self.multidepth = exobj.tools[tool]['data']['multidepth'] + self.z_depthpercut = exobj.tools[tool]['data']['depthperpass'] + + # ############################################### + # ############ Create the data. ################# + # ############################################### + node_list = [] locations = create_data_array() tsp_size = len(locations) @@ -3082,7 +3138,7 @@ class CNCjob(Geometry): raise FlatCAMApp.GracefulException # Tool change sequence (optional) - if toolchange: + if self.toolchange: gcode += self.doformat(p.toolchange_code, toolchangexy=(self.oldx, self.oldy)) gcode += self.doformat(p.spindle_code) # Spindle start) if self.dwell is True: @@ -3201,6 +3257,38 @@ class CNCjob(Geometry): self.postdata['toolC'] = exobj.tools[tool]["C"] self.tooldia = exobj.tools[tool]["C"] + if use_ui: + self.z_feedrate = exobj.tools[tool]['data']['feedrate_z'] + self.feedrate = exobj.tools[tool]['data']['feedrate'] + gcode += self.doformat(p.z_feedrate_code) + + self.z_cut = exobj.tools[tool]['data']['cutz'] + + if self.machinist_setting == 0: + if self.z_cut > 0: + self.app.inform.emit('[WARNING] %s' % + _("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 = -self.z_cut + elif self.z_cut == 0: + self.app.inform.emit('[WARNING] %s: %s' % + (_( + "The Cut Z parameter is zero. There will be no cut, skipping file"), + exobj.options['name'])) + return 'fail' + + old_zcut = deepcopy(self.z_cut) + + self.z_move = exobj.tools[tool]['data']['travelz'] + self.spindlespeed = exobj.tools[tool]['data']['spindlespeed'] + self.dwell = exobj.tools[tool]['data']['dwell'] + self.dwelltime = exobj.tools[tool]['data']['dwelltime'] + self.multidepth = exobj.tools[tool]['data']['multidepth'] + self.z_depthpercut = exobj.tools[tool]['data']['depthperpass'] + # Only if tool has points. if tool in points: if self.app.abort_flag: @@ -3208,7 +3296,7 @@ class CNCjob(Geometry): raise FlatCAMApp.GracefulException # Tool change sequence (optional) - if toolchange: + if self.toolchange: gcode += self.doformat(p.toolchange_code, toolchangexy=(self.oldx, self.oldy)) gcode += self.doformat(p.spindle_code) # Spindle start) if self.dwell is True: diff --git a/preprocessors/Berta_CNC.py b/preprocessors/Berta_CNC.py index 6da9d5d6..18f84578 100644 --- a/preprocessors/Berta_CNC.py +++ b/preprocessors/Berta_CNC.py @@ -35,24 +35,57 @@ class Berta_CNC(FlatCAMPostProc): gcode += '(Feedrate: ' + str(p['feedrate']) + units + '/min' + ')\n' if str(p['options']['type']) == 'Geometry': + gcode += '(TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + ')\n' + gcode += '(Feedrate_XY: ' + str(p['feedrate']) + units + '/min' + ')\n' gcode += '(Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + ')\n' - - gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' - gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' - - if str(p['options']['type']) == 'Geometry': + gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' + gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' if p['multidepth'] is True: gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' + gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' - gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' - gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' + elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True: + gcode += '\n(TOOLS DIAMETER: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n' - if coords_xy is not None: - gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0], - p.decimals, coords_xy[1]) + units + ')\n' - else: - gcode += '(X,Y Toolchange: ' + "None" + units + ')\n' + gcode += '\n(FEEDRATE Z: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % str(val['data']["feedrate_z"]) + ')\n' + + gcode += '\n(FEEDRATE RAPIDS: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate Rapids: %s' % \ + str(val['data']["feedrate_rapid"]) + ')\n' + + gcode += '\n(Z_CUT: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["cutz"]) + ')\n' + + gcode += '\n(Tools Offset: )\n' + for tool, val in p['exc_cnc_tools'].items(): + gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % str(val['offset_z']) + ')\n' + + if p['multidepth'] is True: + gcode += '\n(DEPTH_PER_CUT: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'DeptPerCut: %s' % \ + str(val['data']["depthperpass"]) + ')\n' + + gcode += '\n(Z_MOVE: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["travelz"]) + ')\n' + gcode += '\n' + + if p['toolchange'] is True: + gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' + + if coords_xy is not None: + gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0], + p.decimals, coords_xy[1]) + units + ')\n' + else: + gcode += '(X,Y Toolchange: ' + "None" + units + ')\n' gcode += '(Z Start: ' + str(p['startz']) + units + ')\n' gcode += '(Z End: ' + str(p['z_end']) + units + ')\n' diff --git a/preprocessors/ISEL_CNC.py b/preprocessors/ISEL_CNC.py index 2e20c06e..e8225b8e 100644 --- a/preprocessors/ISEL_CNC.py +++ b/preprocessors/ISEL_CNC.py @@ -26,27 +26,56 @@ class ISEL_CNC(FlatCAMPostProc): if str(p['options']['type']) == 'Geometry': gcode += '(TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + ')\n' - - gcode += '(Feedrate: ' + str(p['feedrate']) + units + '/min' + ')\n' - - if str(p['options']['type']) == 'Geometry': + gcode += '(Feedrate_XY: ' + str(p['feedrate']) + units + '/min' + ')\n' gcode += '(Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + ')\n' + gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' + gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' + if p['multidepth'] is True: + gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ + str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' + gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' - gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' - gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' + elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True: + gcode += '\n(TOOLS DIAMETER: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n' - if p['multidepth'] is True: - gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ - str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' + gcode += '\n(FEEDRATE Z: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % str(val['data']["feedrate_z"]) + ')\n' - gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' - gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' + gcode += '\n(FEEDRATE RAPIDS: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate Rapids: %s' % \ + str(val['data']["feedrate_rapid"]) + ')\n' - if coords_xy is not None: - gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0], - p.decimals, coords_xy[1]) + units + ')\n' - else: - gcode += '(X,Y Toolchange: ' + "None" + units + ')\n' + gcode += '\n(Z_CUT: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["cutz"]) + ')\n' + + gcode += '\n(Tools Offset: )\n' + for tool, val in p['exc_cnc_tools'].items(): + gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % str(val['offset_z']) + ')\n' + + if p['multidepth'] is True: + gcode += '\n(DEPTH_PER_CUT: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'DeptPerCut: %s' % \ + str(val['data']["depthperpass"]) + ')\n' + + gcode += '\n(Z_MOVE: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["travelz"]) + ')\n' + gcode += '\n' + + if p['toolchange'] is True: + gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' + + if coords_xy is not None: + gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0], + p.decimals, coords_xy[1]) + units + ')\n' + else: + gcode += '(X,Y Toolchange: ' + "None" + units + ')\n' gcode += '(Z Start: ' + str(p['startz']) + units + ')\n' gcode += '(Z End: ' + str(p['z_end']) + units + ')\n' diff --git a/preprocessors/ISEL_ICP_CNC.py b/preprocessors/ISEL_ICP_CNC.py index 92a08691..a6a137f8 100644 --- a/preprocessors/ISEL_ICP_CNC.py +++ b/preprocessors/ISEL_ICP_CNC.py @@ -25,36 +25,71 @@ class ISEL_ICP_CNC(FlatCAMPostProc): gcode += 'IMF_PBL flatcam\n\n' if str(p['options']['type']) == 'Geometry': - gcode += '; TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + '\n' - gcode += '; Spindle Speed: %s RPM\n' % str(p['spindlespeed']) - gcode += '; Feedrate: ' + str(p['feedrate']) + units + '/min' + '\n' - if str(p['options']['type']) == 'Geometry': - gcode += '; Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + '\n' - gcode += '\n' - gcode += '; Z_Cut: ' + str(p['z_cut']) + units + '\n' + gcode += ';TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + '\n' + gcode += ';Feedrate_XY: ' + str(p['feedrate']) + units + '/min' + '\n' + gcode += ';Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + '\n' + gcode += ';Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + '\n' + '\n' + gcode += ';Z_Cut: ' + str(p['z_cut']) + units + '\n' + if p['multidepth'] is True: + gcode += ';DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ + str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + '\n' + gcode += ';Z_Move: ' + str(p['z_move']) + units + '\n' - if p['multidepth'] is True: - gcode += '; DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ - str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + '\n' + elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True: + gcode += '\n;TOOLS DIAMETER: \n' + for tool, val in p['exc_tools'].items(): + gcode += ';Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + '\n' + + gcode += '\n;FEEDRATE Z: \n' + for tool, val in p['exc_tools'].items(): + gcode += ';Tool: %s -> ' % str(tool) + 'Feedrate: %s' % str(val['data']["feedrate_z"]) + '\n' + + gcode += '\n;FEEDRATE RAPIDS: \n' + for tool, val in p['exc_tools'].items(): + gcode += ';Tool: %s -> ' % str(tool) + 'Feedrate Rapids: %s' % \ + str(val['data']["feedrate_rapid"]) + '\n' + + gcode += '\n;Z_CUT: \n' + for tool, val in p['exc_tools'].items(): + gcode += ';Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["cutz"]) + '\n' + + gcode += '\n;Tools Offset: \n' + for tool, val in p['exc_cnc_tools'].items(): + gcode += ';Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % str(val['offset_z']) + '\n' + + if p['multidepth'] is True: + gcode += '\n;DEPTH_PER_CUT: \n' + for tool, val in p['exc_tools'].items(): + gcode += ';Tool: %s -> ' % str(tool) + 'DeptPerCut: %s' % \ + str(val['data']["depthperpass"]) + '\n' + + gcode += '\n;Z_MOVE: \n' + for tool, val in p['exc_tools'].items(): + gcode += ';Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["travelz"]) + '\n' + gcode += '\n' + + if p['toolchange'] is True: + gcode += ';Z Toolchange: ' + str(p['z_toolchange']) + units + '\n' + + if coords_xy is not None: + gcode += ';X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0], + p.decimals, coords_xy[1]) + units + '\n' + else: + gcode += ';X,Y Toolchange: ' + "None" + units + '\n' + + gcode += ';Z Start: ' + str(p['startz']) + units + '\n' + gcode += ';Z End: ' + str(p['z_end']) + units + '\n' + gcode += ';Steps per circle: ' + str(p['steps_per_circle']) + '\n' - gcode += '; Z_Move: ' + str(p['z_move']) + units + '\n' - gcode += '; Z Toolchange: ' + str(p['z_toolchange']) + units + '\n' - if coords_xy is not None: - gcode += '; X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0], - p.decimals, coords_xy[1]) + units + '\n' - else: - gcode += '; X,Y Toolchange: ' + "None" + units + '\n' - gcode += '; Z Start: ' + str(p['startz']) + units + '\n' - gcode += '; Z End: ' + str(p['z_end']) + units + '\n' - gcode += '; Steps per circle: ' + str(p['steps_per_circle']) + '\n' if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry': - gcode += '; Preprocessor Excellon: ' + str(p['pp_excellon_name']) + '\n' + gcode += ';Preprocessor Excellon: ' + str(p['pp_excellon_name']) + '\n' + '\n' else: - gcode += '; Preprocessor Geometry: ' + str(p['pp_geometry_name']) + '\n' - gcode += '\n' + gcode += ';Preprocessor Geometry: ' + str(p['pp_geometry_name']) + '\n' + '\n' - gcode += '; X range: ' + '{: >9s}'.format(xmin) + ' ... ' + '{: >9s}'.format(xmax) + ' ' + units + '\n' - gcode += '; Y range: ' + '{: >9s}'.format(ymin) + ' ... ' + '{: >9s}'.format(ymax) + ' ' + units + '\n' + gcode += ';X range: ' + '{: >9s}'.format(xmin) + ' ... ' + '{: >9s}'.format(xmax) + ' ' + units + '\n' + gcode += ';Y range: ' + '{: >9s}'.format(ymin) + ' ... ' + '{: >9s}'.format(ymax) + ' ' + units + '\n\n' + + gcode += ';Spindle Speed: %s RPM)\n' % str(p['spindlespeed']) return gcode diff --git a/preprocessors/Marlin.py b/preprocessors/Marlin.py index d5144d59..aaf9079d 100644 --- a/preprocessors/Marlin.py +++ b/preprocessors/Marlin.py @@ -27,42 +27,71 @@ class Marlin(FlatCAMPostProc): ymax = '%.*f' % (p.coords_decimals, p['options']['ymax']) if str(p['options']['type']) == 'Geometry': - gcode += ';TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + '\n' + '\n' - - gcode += ';Feedrate: ' + str(p['feedrate']) + units + '/min' + '\n' - - if str(p['options']['type']) == 'Geometry': + gcode += ';TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + '\n' + gcode += ';Feedrate_XY: ' + str(p['feedrate']) + units + '/min' + '\n' gcode += ';Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + '\n' + gcode += ';Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + '\n' + '\n' + gcode += ';Z_Cut: ' + str(p['z_cut']) + units + '\n' + if p['multidepth'] is True: + gcode += ';DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ + str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + '\n' + gcode += ';Z_Move: ' + str(p['z_move']) + units + '\n' - gcode += ';Feedrate rapids: ' + str(p['feedrate_rapid']) + units + '/min' + '\n' + '\n' - gcode += ';Z_Cut: ' + str(p['z_cut']) + units + '\n' + elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True: + gcode += '\n;TOOLS DIAMETER: \n' + for tool, val in p['exc_tools'].items(): + gcode += ';Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + '\n' - if p['multidepth'] is True: - gcode += ';DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ - str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + '\n' + gcode += '\n;FEEDRATE Z: \n' + for tool, val in p['exc_tools'].items(): + gcode += ';Tool: %s -> ' % str(tool) + 'Feedrate: %s' % str(val['data']["feedrate_z"]) + '\n' - gcode += ';Z_Move: ' + str(p['z_move']) + units + '\n' - gcode += ';Z Toolchange: ' + str(p['z_toolchange']) + units + '\n' + gcode += '\n;FEEDRATE RAPIDS: \n' + for tool, val in p['exc_tools'].items(): + gcode += ';Tool: %s -> ' % str(tool) + 'Feedrate Rapids: %s' % \ + str(val['data']["feedrate_rapid"]) + '\n' - if coords_xy is not None: - gcode += ';X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0], - p.decimals, coords_xy[1]) + units + '\n' - else: - gcode += ';X,Y Toolchange: ' + "None" + units + '\n' + gcode += '\n;Z_CUT: \n' + for tool, val in p['exc_tools'].items(): + gcode += ';Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["cutz"]) + '\n' + + gcode += '\n;Tools Offset: \n' + for tool, val in p['exc_cnc_tools'].items(): + gcode += ';Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % str(val['offset_z']) + '\n' + + if p['multidepth'] is True: + gcode += '\n;DEPTH_PER_CUT: \n' + for tool, val in p['exc_tools'].items(): + gcode += ';Tool: %s -> ' % str(tool) + 'DeptPerCut: %s' % \ + str(val['data']["depthperpass"]) + '\n' + + gcode += '\n;Z_MOVE: \n' + for tool, val in p['exc_tools'].items(): + gcode += ';Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["travelz"]) + '\n' + gcode += '\n' + + if p['toolchange'] is True: + gcode += ';Z Toolchange: ' + str(p['z_toolchange']) + units + '\n' + + if coords_xy is not None: + gcode += ';X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0], + p.decimals, coords_xy[1]) + units + '\n' + else: + gcode += ';X,Y Toolchange: ' + "None" + units + '\n' gcode += ';Z Start: ' + str(p['startz']) + units + '\n' gcode += ';Z End: ' + str(p['z_end']) + units + '\n' gcode += ';Steps per circle: ' + str(p['steps_per_circle']) + '\n' if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry': - gcode += ';Preprocessor Excellon: ' + str(p['pp_excellon_name']) + '\n' + gcode += ';Preprocessor Excellon: ' + str(p['pp_excellon_name']) + '\n' + '\n' else: gcode += ';Preprocessor Geometry: ' + str(p['pp_geometry_name']) + '\n' + '\n' gcode += ';X range: ' + '{: >9s}'.format(xmin) + ' ... ' + '{: >9s}'.format(xmax) + ' ' + units + '\n' gcode += ';Y range: ' + '{: >9s}'.format(ymin) + ' ... ' + '{: >9s}'.format(ymax) + ' ' + units + '\n\n' - gcode += ';Spindle Speed: ' + str(p['spindlespeed']) + ' RPM' + '\n' + '\n' + gcode += ';Spindle Speed: %s RPM)\n' % str(p['spindlespeed']) gcode += ('G20' if p.units.upper() == 'IN' else 'G21') + "\n" gcode += 'G90' diff --git a/preprocessors/Repetier.py b/preprocessors/Repetier.py index 3d31a176..ea15317e 100644 --- a/preprocessors/Repetier.py +++ b/preprocessors/Repetier.py @@ -27,42 +27,71 @@ class Repetier(FlatCAMPostProc): ymax = '%.*f' % (p.coords_decimals, p['options']['ymax']) if str(p['options']['type']) == 'Geometry': - gcode += ';TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + '\n' + '\n' - - gcode += ';Feedrate: ' + str(p['feedrate']) + units + '/min' + '\n' - - if str(p['options']['type']) == 'Geometry': + gcode += ';TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + '\n' + gcode += ';Feedrate_XY: ' + str(p['feedrate']) + units + '/min' + '\n' gcode += ';Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + '\n' + gcode += ';Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + '\n' + '\n' + gcode += ';Z_Cut: ' + str(p['z_cut']) + units + '\n' + if p['multidepth'] is True: + gcode += ';DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ + str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + '\n' + gcode += ';Z_Move: ' + str(p['z_move']) + units + '\n' - gcode += ';Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + '\n' + '\n' - gcode += ';Z_Cut: ' + str(p['z_cut']) + units + '\n' + elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True: + gcode += '\n;TOOLS DIAMETER: \n' + for tool, val in p['exc_tools'].items(): + gcode += ';Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + '\n' - if p['multidepth'] is True: - gcode += ';DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ - str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + '\n' + gcode += '\n;FEEDRATE Z: \n' + for tool, val in p['exc_tools'].items(): + gcode += ';Tool: %s -> ' % str(tool) + 'Feedrate: %s' % str(val['data']["feedrate_z"]) + '\n' - gcode += ';Z_Move: ' + str(p['z_move']) + units + '\n' - gcode += ';Z Toolchange: ' + str(p['z_toolchange']) + units + '\n' + gcode += '\n;FEEDRATE RAPIDS: \n' + for tool, val in p['exc_tools'].items(): + gcode += ';Tool: %s -> ' % str(tool) + 'Feedrate Rapids: %s' % \ + str(val['data']["feedrate_rapid"]) + '\n' - if coords_xy is not None: - gcode += ';X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0], - p.decimals, coords_xy[1]) + units + '\n' - else: - gcode += ';X,Y Toolchange: ' + "None" + units + '\n' + gcode += '\n;Z_CUT: \n' + for tool, val in p['exc_tools'].items(): + gcode += ';Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["cutz"]) + '\n' + + gcode += '\n;Tools Offset: \n' + for tool, val in p['exc_cnc_tools'].items(): + gcode += ';Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % str(val['offset_z']) + '\n' + + if p['multidepth'] is True: + gcode += '\n;DEPTH_PER_CUT: \n' + for tool, val in p['exc_tools'].items(): + gcode += ';Tool: %s -> ' % str(tool) + 'DeptPerCut: %s' % \ + str(val['data']["depthperpass"]) + '\n' + + gcode += '\n;Z_MOVE: \n' + for tool, val in p['exc_tools'].items(): + gcode += ';Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["travelz"]) + '\n' + gcode += '\n' + + if p['toolchange'] is True: + gcode += ';Z Toolchange: ' + str(p['z_toolchange']) + units + '\n' + + if coords_xy is not None: + gcode += ';X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0], + p.decimals, coords_xy[1]) + units + '\n' + else: + gcode += ';X,Y Toolchange: ' + "None" + units + '\n' gcode += ';Z Start: ' + str(p['startz']) + units + '\n' gcode += ';Z End: ' + str(p['z_end']) + units + '\n' gcode += ';Steps per circle: ' + str(p['steps_per_circle']) + '\n' if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry': - gcode += ';Preprocessor Excellon: ' + str(p['pp_excellon_name']) + '\n' + gcode += ';Preprocessor Excellon: ' + str(p['pp_excellon_name']) + '\n' + '\n' else: gcode += ';Preprocessor Geometry: ' + str(p['pp_geometry_name']) + '\n' + '\n' gcode += ';X range: ' + '{: >9s}'.format(xmin) + ' ... ' + '{: >9s}'.format(xmax) + ' ' + units + '\n' gcode += ';Y range: ' + '{: >9s}'.format(ymin) + ' ... ' + '{: >9s}'.format(ymax) + ' ' + units + '\n\n' - gcode += ';Spindle Speed: ' + str(p['spindlespeed']) + ' RPM' + '\n' + '\n' + gcode += ';Spindle Speed: %s RPM)\n' % str(p['spindlespeed']) gcode += ('G20' if p.units.upper() == 'IN' else 'G21') + "\n" gcode += 'G90\n' diff --git a/preprocessors/Toolchange_Custom.py b/preprocessors/Toolchange_Custom.py index 162defbb..5c22b85a 100644 --- a/preprocessors/Toolchange_Custom.py +++ b/preprocessors/Toolchange_Custom.py @@ -27,34 +27,63 @@ class Toolchange_Custom(FlatCAMPostProc): if str(p['options']['type']) == 'Geometry': gcode += '(TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + ')\n' - - gcode += '(Feedrate: ' + str(p['feedrate']) + units + '/min' + ')\n' - - if str(p['options']['type']) == 'Geometry': + gcode += '(Feedrate_XY: ' + str(p['feedrate']) + units + '/min' + ')\n' gcode += '(Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + ')\n' + gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' + gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' + if p['multidepth'] is True: + gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ + str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' + gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' - gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' - gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' + elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True: + gcode += '\n(TOOLS DIAMETER: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n' - if p['multidepth'] is True: - gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ - str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' + gcode += '\n(FEEDRATE Z: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % str(val['data']["feedrate_z"]) + ')\n' - gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' - gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' + gcode += '\n(FEEDRATE RAPIDS: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate Rapids: %s' % \ + str(val['data']["feedrate_rapid"]) + ')\n' - if coords_xy is not None: - gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0], - p.decimals, coords_xy[1]) + units + ')\n' - else: - gcode += '(X,Y Toolchange: ' + "None" + units + ')\n' + gcode += '\n(Z_CUT: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["cutz"]) + ')\n' + + gcode += '\n(Tools Offset: )\n' + for tool, val in p['exc_cnc_tools'].items(): + gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % str(val['offset_z']) + ')\n' + + if p['multidepth'] is True: + gcode += '\n(DEPTH_PER_CUT: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'DeptPerCut: %s' % \ + str(val['data']["depthperpass"]) + ')\n' + + gcode += '\n(Z_MOVE: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["travelz"]) + ')\n' + gcode += '\n' + + if p['toolchange'] is True: + gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' + + if coords_xy is not None: + gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0], + p.decimals, coords_xy[1]) + units + ')\n' + else: + gcode += '(X,Y Toolchange: ' + "None" + units + ')\n' gcode += '(Z Start: ' + str(p['startz']) + units + ')\n' gcode += '(Z End: ' + str(p['z_end']) + units + ')\n' gcode += '(Steps per circle: ' + str(p['steps_per_circle']) + ')\n' if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry': - gcode += '(Preprocessor Excellon: ' + str(p['pp_excellon_name']) + ')\n' + gcode += '(Preprocessor Excellon: ' + str(p['pp_excellon_name']) + ')\n' + '\n' else: gcode += '(Preprocessor Geometry: ' + str(p['pp_geometry_name']) + ')\n' + '\n' diff --git a/preprocessors/Toolchange_Probe_MACH3.py b/preprocessors/Toolchange_Probe_MACH3.py index 3f0bb7c8..3d4c95f8 100644 --- a/preprocessors/Toolchange_Probe_MACH3.py +++ b/preprocessors/Toolchange_Probe_MACH3.py @@ -27,36 +27,63 @@ class Toolchange_Probe_MACH3(FlatCAMPostProc): if str(p['options']['type']) == 'Geometry': gcode += '(TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + ')\n' - - gcode += '(Feedrate: ' + str(p['feedrate']) + units + '/min' + ')\n' - - if str(p['options']['type']) == 'Geometry': + gcode += '(Feedrate_XY: ' + str(p['feedrate']) + units + '/min' + ')\n' gcode += '(Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + ')\n' + gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' + gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' + if p['multidepth'] is True: + gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ + str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' + gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' - gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' - gcode += '(Feedrate Probe ' + str(p['feedrate_probe']) + units + '/min' + ')\n' + '\n' - gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' + elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True: + gcode += '\n(TOOLS DIAMETER: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n' - if p['multidepth'] is True: - gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ - str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' + gcode += '\n(FEEDRATE Z: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % str(val['data']["feedrate_z"]) + ')\n' - gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' - gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' + gcode += '\n(FEEDRATE RAPIDS: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate Rapids: %s' % \ + str(val['data']["feedrate_rapid"]) + ')\n' - if coords_xy is not None: - gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0], - p.decimals, coords_xy[1]) + units + ')\n' - else: - gcode += '(X,Y Toolchange: ' + "None" + units + ')\n' + gcode += '\n(Z_CUT: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["cutz"]) + ')\n' + + gcode += '\n(Tools Offset: )\n' + for tool, val in p['exc_cnc_tools'].items(): + gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % str(val['offset_z']) + ')\n' + + if p['multidepth'] is True: + gcode += '\n(DEPTH_PER_CUT: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'DeptPerCut: %s' % \ + str(val['data']["depthperpass"]) + ')\n' + + gcode += '\n(Z_MOVE: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["travelz"]) + ')\n' + gcode += '\n' + + if p['toolchange'] is True: + gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' + + if coords_xy is not None: + gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0], + p.decimals, coords_xy[1]) + units + ')\n' + else: + gcode += '(X,Y Toolchange: ' + "None" + units + ')\n' gcode += '(Z Start: ' + str(p['startz']) + units + ')\n' gcode += '(Z End: ' + str(p['z_end']) + units + ')\n' - gcode += '(Z Probe Depth: ' + str(p['z_pdepth']) + units + ')\n' gcode += '(Steps per circle: ' + str(p['steps_per_circle']) + ')\n' if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry': - gcode += '(Preprocessor Excellon: ' + str(p['pp_excellon_name']) + ')\n' + gcode += '(Preprocessor Excellon: ' + str(p['pp_excellon_name']) + ')\n' + '\n' else: gcode += '(Preprocessor Geometry: ' + str(p['pp_geometry_name']) + ')\n' + '\n' diff --git a/preprocessors/Toolchange_manual.py b/preprocessors/Toolchange_manual.py index f096ab25..fceef14c 100644 --- a/preprocessors/Toolchange_manual.py +++ b/preprocessors/Toolchange_manual.py @@ -27,26 +27,57 @@ class Toolchange_manual(FlatCAMPostProc): if str(p['options']['type']) == 'Geometry': gcode += '(TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + ')\n' - - gcode += '(Feedrate: ' + str(p['feedrate']) + units + '/min' + ')\n' - - if str(p['options']['type']) == 'Geometry': + gcode += '(Feedrate_XY: ' + str(p['feedrate']) + units + '/min' + ')\n' gcode += '(Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + ')\n' + gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' + gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' + if p['multidepth'] is True: + gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ + str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' + gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' - gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' - gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' + elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True: + gcode += '\n(TOOLS DIAMETER: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n' - if p['multidepth'] is True: - gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ - str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' + gcode += '\n(FEEDRATE Z: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % str(val['data']["feedrate_z"]) + ')\n' + + gcode += '\n(FEEDRATE RAPIDS: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate Rapids: %s' % \ + str(val['data']["feedrate_rapid"]) + ')\n' + + gcode += '\n(Z_CUT: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["cutz"]) + ')\n' + + gcode += '\n(Tools Offset: )\n' + for tool, val in p['exc_cnc_tools'].items(): + gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % str(val['offset_z']) + ')\n' + + if p['multidepth'] is True: + gcode += '\n(DEPTH_PER_CUT: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'DeptPerCut: %s' % \ + str(val['data']["depthperpass"]) + ')\n' + + gcode += '\n(Z_MOVE: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["travelz"]) + ')\n' + gcode += '\n' + + if p['toolchange'] is True: + gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' + + if coords_xy is not None: + gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0], + p.decimals, coords_xy[1]) + units + ')\n' + else: + gcode += '(X,Y Toolchange: ' + "None" + units + ')\n' - gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' - gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' - if coords_xy is not None: - gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0], - p.decimals, coords_xy[1]) + units + ')\n' - else: - gcode += '(X,Y Toolchange: ' + "None" + units + ')\n' gcode += '(Z Start: ' + str(p['startz']) + units + ')\n' gcode += '(Z End: ' + str(p['z_end']) + units + ')\n' gcode += '(Steps per circle: ' + str(p['steps_per_circle']) + ')\n' diff --git a/preprocessors/default.py b/preprocessors/default.py index 640620f6..f46ff824 100644 --- a/preprocessors/default.py +++ b/preprocessors/default.py @@ -28,34 +28,56 @@ class default(FlatCAMPostProc): if str(p['options']['type']) == 'Geometry': gcode += '(TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + ')\n' - - gcode += '(Feedrate: ' + str(p['feedrate']) + units + '/min' + ')\n' - - if str(p['options']['type']) == 'Geometry': + gcode += '(Feedrate_XY: ' + str(p['feedrate']) + units + '/min' + ')\n' gcode += '(Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + ')\n' + gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' + gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' + if p['multidepth'] is True: + gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ + str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' + gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' - gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' - gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' + elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True: + gcode += '\n(TOOLS DIAMETER: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n' + + gcode += '\n(FEEDRATE Z: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % str(val['data']["feedrate_z"]) + ')\n' + + gcode += '\n(FEEDRATE RAPIDS: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate Rapids: %s' % \ + str(val['data']["feedrate_rapid"]) + ')\n' + + gcode += '\n(Z_CUT: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["cutz"]) + ')\n' - if str(p['options']['type']) == 'Excellon': gcode += '\n(Tools Offset: )\n' for tool, val in p['exc_cnc_tools'].items(): - gcode += '(Tool: %s -> ' % str(val['tool']) + 'Dia: %s -> ' % str(tool) + \ - 'Offset Z: %s' % str(val['offset_z']) + ')\n' + gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % str(val['offset_z']) + ')\n' + + if p['multidepth'] is True: + gcode += '\n(DEPTH_PER_CUT: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'DeptPerCut: %s' % \ + str(val['data']["depthperpass"]) + ')\n' + + gcode += '\n(Z_MOVE: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["travelz"]) + ')\n' gcode += '\n' - if p['multidepth'] is True: - gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ - str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' + if p['toolchange'] is True: + gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' - gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' - gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' - - if coords_xy is not None: - gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0], - p.decimals, coords_xy[1]) + units + ')\n' - else: - gcode += '(X,Y Toolchange: ' + "None" + units + ')\n' + if coords_xy is not None: + gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0], + p.decimals, coords_xy[1]) + units + ')\n' + else: + gcode += '(X,Y Toolchange: ' + "None" + units + ')\n' gcode += '(Z Start: ' + str(p['startz']) + units + ')\n' gcode += '(Z End: ' + str(p['z_end']) + units + ')\n' diff --git a/preprocessors/grbl_11.py b/preprocessors/grbl_11.py index 9fc8676b..0d4cf868 100644 --- a/preprocessors/grbl_11.py +++ b/preprocessors/grbl_11.py @@ -27,40 +27,71 @@ class grbl_11(FlatCAMPostProc): ymax = '%.*f' % (p.coords_decimals, p['options']['ymax']) if str(p['options']['type']) == 'Geometry': - gcode += '(TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + ')\n' + '\n' - - gcode += '(Feedrate: ' + str(p['feedrate']) + units + '/min' + ')\n' - - if str(p['options']['type']) == 'Geometry': + gcode += '(TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + ')\n' + gcode += '(Feedrate_XY: ' + str(p['feedrate']) + units + '/min' + ')\n' gcode += '(Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + ')\n' + gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' + gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' + if p['multidepth'] is True: + gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ + str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' + gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' - gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' - gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' + elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True: + gcode += '\n(TOOLS DIAMETER: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n' - if p['multidepth'] is True: - gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ - str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' + gcode += '\n(FEEDRATE Z: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % str(val['data']["feedrate_z"]) + ')\n' + + gcode += '\n(FEEDRATE RAPIDS: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate Rapids: %s' % \ + str(val['data']["feedrate_rapid"]) + ')\n' + + gcode += '\n(Z_CUT: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["cutz"]) + ')\n' + + gcode += '\n(Tools Offset: )\n' + for tool, val in p['exc_cnc_tools'].items(): + gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % str(val['offset_z']) + ')\n' + + if p['multidepth'] is True: + gcode += '\n(DEPTH_PER_CUT: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'DeptPerCut: %s' % \ + str(val['data']["depthperpass"]) + ')\n' + + gcode += '\n(Z_MOVE: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["travelz"]) + ')\n' + gcode += '\n' + + if p['toolchange'] is True: + gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' + + if coords_xy is not None: + gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0], + p.decimals, coords_xy[1]) + units + ')\n' + else: + gcode += '(X,Y Toolchange: ' + "None" + units + ')\n' - gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' - gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' - if coords_xy is not None: - gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0], - p.decimals, coords_xy[1]) + units + ')\n' - else: - gcode += '(X,Y Toolchange: ' + "None" + units + ')\n' gcode += '(Z Start: ' + str(p['startz']) + units + ')\n' gcode += '(Z End: ' + str(p['z_end']) + units + ')\n' gcode += '(Steps per circle: ' + str(p['steps_per_circle']) + ')\n' if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry': - gcode += '(Preprocessor Excellon: ' + str(p['pp_excellon_name']) + ')\n' + gcode += '(Preprocessor Excellon: ' + str(p['pp_excellon_name']) + ')\n' + '\n' else: gcode += '(Preprocessor Geometry: ' + str(p['pp_geometry_name']) + ')\n' + '\n' gcode += '(X range: ' + '{: >9s}'.format(xmin) + ' ... ' + '{: >9s}'.format(xmax) + ' ' + units + ')\n' gcode += '(Y range: ' + '{: >9s}'.format(ymin) + ' ... ' + '{: >9s}'.format(ymax) + ' ' + units + ')\n\n' - gcode += '(Spindle Speed: ' + str(p['spindlespeed']) + ' RPM' + ')\n' + '\n' + gcode += '(Spindle Speed: %s RPM)\n' % str(p['spindlespeed']) gcode += ('G20' if p.units.upper() == 'IN' else 'G21') + "\n" gcode += 'G90\n' diff --git a/preprocessors/line_xyz.py b/preprocessors/line_xyz.py index b6130729..d7cebb7f 100644 --- a/preprocessors/line_xyz.py +++ b/preprocessors/line_xyz.py @@ -27,32 +27,63 @@ class line_xyz(FlatCAMPostProc): if str(p['options']['type']) == 'Geometry': gcode += '(TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + ')\n' - - gcode += '(Feedrate: ' + str(p['feedrate']) + units + '/min' + ')\n' - - if str(p['options']['type']) == 'Geometry': + gcode += '(Feedrate_XY: ' + str(p['feedrate']) + units + '/min' + ')\n' gcode += '(Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + ')\n' + gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' + gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' + if p['multidepth'] is True: + gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ + str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' + gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' - gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n' - gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n' + elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True: + gcode += '\n(TOOLS DIAMETER: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n' - if p['multidepth'] is True: - gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \ - str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n' + gcode += '\n(FEEDRATE Z: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % str(val['data']["feedrate_z"]) + ')\n' + + gcode += '\n(FEEDRATE RAPIDS: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate Rapids: %s' % \ + str(val['data']["feedrate_rapid"]) + ')\n' + + gcode += '\n(Z_CUT: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["cutz"]) + ')\n' + + gcode += '\n(Tools Offset: )\n' + for tool, val in p['exc_cnc_tools'].items(): + gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % str(val['offset_z']) + ')\n' + + if p['multidepth'] is True: + gcode += '\n(DEPTH_PER_CUT: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'DeptPerCut: %s' % \ + str(val['data']["depthperpass"]) + ')\n' + + gcode += '\n(Z_MOVE: )\n' + for tool, val in p['exc_tools'].items(): + gcode += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["travelz"]) + ')\n' + gcode += '\n' + + if p['toolchange'] is True: + gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' + + if coords_xy is not None: + gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0], + p.decimals, coords_xy[1]) + units + ')\n' + else: + gcode += '(X,Y Toolchange: ' + "None" + units + ')\n' - gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' - gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n' - if coords_xy is not None: - gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0], - p.decimals, coords_xy[1]) + units + ')\n' - else: - gcode += '(X,Y Toolchange: ' + "None" + units + ')\n' gcode += '(Z Start: ' + str(p['startz']) + units + ')\n' gcode += '(Z End: ' + str(p['z_end']) + units + ')\n' gcode += '(Steps per circle: ' + str(p['steps_per_circle']) + ')\n' if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry': - gcode += '(Preprocessor Excellon: ' + str(p['pp_excellon_name']) + ')\n' + gcode += '(Preprocessor Excellon: ' + str(p['pp_excellon_name']) + ')\n' + '\n' else: gcode += '(Preprocessor Geometry: ' + str(p['pp_geometry_name']) + ')\n' + '\n' From a9c6db73bf2fcd4b7e59736fe75a6427cf1003b2 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Tue, 18 Feb 2020 04:12:23 +0200 Subject: [PATCH 105/209] - when multiple tools are selected in Excellon UI and parameters are modified it will applied to all selected - in Excellon UI, Paint Tool and NCC Tool finished the "Apply parameters to all tools" functionality - updated Paint Tool and NCC Tool in the UI functionality --- FlatCAMApp.py | 2 +- FlatCAMObj.py | 159 ++++++-------- README.md | 5 +- flatcamGUI/PreferencesUI.py | 2 +- flatcamTools/ToolNonCopperClear.py | 159 +++++++------- flatcamTools/ToolPaint.py | 341 +++++++++++++++-------------- 6 files changed, 328 insertions(+), 340 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 53dfe415..e1be9814 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -806,7 +806,7 @@ class App(QtCore.QObject): "tools_paintorder": 'rev', "tools_paintoverlap": 20, "tools_paintmargin": 0.0, - "tools_paintmethod": _("Seed-based"), + "tools_paintmethod": _("Seed"), "tools_selectmethod": "all", "tools_pathconnect": True, "tools_paintcontour": True, diff --git a/FlatCAMObj.py b/FlatCAMObj.py index f451f30d..8073b9da 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -2778,10 +2778,8 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.ui.generate_milling_slots_button.show() # set the text on tool_data_label after loading the object - sel_rows = list() sel_items = self.ui.tools_table.selectedItems() - for it in sel_items: - sel_rows.append(it.row()) + sel_rows = [it.row() for it in sel_items] if len(sel_rows) > 1: self.ui.tool_data_label.setText( "%s: %s" % (_('Parameters for'), _("Multiple Tools")) @@ -2909,8 +2907,17 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.ui.operation_radio.activated_custom.connect(self.on_operation_type) self.ui.pp_excellon_name_cb.activated.connect(self.on_pp_changed) + + self.ui.apply_param_to_all.clicked.connect(self.on_apply_param_to_all_clicked) + self.units_found = self.app.defaults['units'] + # ######################################## + # #######3 TEMP SETTINGS ################# + # ######################################## + self.ui.operation_radio.set_value("drill") + self.ui.operation_radio.setEnabled(False) + def ui_connect(self): # selective plotting @@ -3029,7 +3036,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): for form_key in self.form_fields: for storage_key in dict_storage: if form_key == storage_key and form_key not in \ - ["toolchangez", "startz", "endz", "ppname_e", "ppname_g"]: + ["toolchange", "toolchangez", "startz", "endz", "ppname_e", "ppname_g"]: try: self.form_fields[form_key].set_value(dict_storage[form_key]) except Exception as e: @@ -3047,19 +3054,20 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): wdg_objname = widget_changed.objectName() option_changed = self.name2option[wdg_objname] - row = self.ui.tools_table.currentRow() + # row = self.ui.tools_table.currentRow() + rows = sorted(set(index.row() for index in self.ui.tools_table.selectedIndexes())) + for row in rows: + if row < 0: + row = 0 + tooluid_item = int(self.ui.tools_table.item(row, 0).text()) - if row < 0: - row = 0 - tooluid_item = int(self.ui.tools_table.item(row, 0).text()) - - for tooluid_key, tooluid_val in self.tools.items(): - if int(tooluid_key) == tooluid_item: - new_option_value = self.form_fields[option_changed].get_value() - if option_changed in tooluid_val: - tooluid_val[option_changed] = new_option_value - if option_changed in tooluid_val['data']: - tooluid_val['data'][option_changed] = new_option_value + for tooluid_key, tooluid_val in self.tools.items(): + if int(tooluid_key) == tooluid_item: + new_option_value = self.form_fields[option_changed].get_value() + if option_changed in tooluid_val: + tooluid_val[option_changed] = new_option_value + if option_changed in tooluid_val['data']: + tooluid_val['data'][option_changed] = new_option_value self.ui_connect() @@ -3858,57 +3866,33 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.shapes.clear(update=True) def on_apply_param_to_all_clicked(self): - if self.tools_table.rowCount() == 0: + if self.ui.tools_table.rowCount() == 0: # there is no tool in tool table so we can't save the GUI elements values to storage - log.debug("NonCopperClear.on_apply_param_to_all_clicked() --> no tool in Tools Table, aborting.") + log.debug("FlatCAMExcellon.on_apply_param_to_all_clicked() --> no tool in Tools Table, aborting.") return - self.blockSignals(True) + self.ui_disconnect() - row = self.tools_table.currentRow() + row = self.ui.tools_table.currentRow() if row < 0: row = 0 - # store all the data associated with the row parameter to the self.tools storage - tooldia_item = float(self.tools_table.item(row, 1).text()) - type_item = self.tools_table.cellWidget(row, 2).currentText() - operation_type_item = self.ui.geo_tools_table.cellWidget(row, 4).currentText() + tooluid_item = int(self.ui.tools_table.item(row, 0).text()) + temp_tool_data = dict() - nccoffset_item = self.ncc_choice_offset_cb.get_value() - nccoffset_value_item = float(self.ncc_offset_spinner.get_value()) + for tooluid_key, tooluid_val in self.tools.items(): + if int(tooluid_key) == tooluid_item: + # this will hold the 'data' key of the self.tools[tool] dictionary that corresponds to + # the current row in the tool table + temp_tool_data = tooluid_val['data'] + break - # this new dict will hold the actual useful data, another dict that is the value of key 'data' - temp_tools = {} - temp_dia = {} - temp_data = {} + for tooluid_key, tooluid_val in self.tools.items(): + tooluid_val['data'] = deepcopy(temp_tool_data) - for tooluid_key, tooluid_value in self.ncc_tools.items(): - for key, value in tooluid_value.items(): - if key == 'data': - # update the 'data' section - for data_key in tooluid_value[key].keys(): - for form_key, form_value in self.form_fields.items(): - if form_key == data_key: - temp_data[data_key] = form_value.get_value() - # make sure we make a copy of the keys not in the form (we may use 'data' keys that are - # updated from self.app.defaults - if data_key not in self.form_fields: - temp_data[data_key] = value[data_key] - temp_dia[key] = deepcopy(temp_data) - temp_data.clear() + self.app.inform.emit('[success] %s' % _("Current Tool parameters were applied to all tools.")) - elif key == 'solid_geometry': - temp_dia[key] = deepcopy(self.tools[tooluid_key]['solid_geometry']) - else: - temp_dia[key] = deepcopy(value) - - temp_tools[tooluid_key] = deepcopy(temp_dia) - - self.ncc_tools.clear() - self.ncc_tools = deepcopy(temp_tools) - temp_tools.clear() - - self.blockSignals(False) + self.ui_connect() class FlatCAMGeometry(FlatCAMObj, Geometry): @@ -4584,42 +4568,43 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ui.tool_data_label.setText( "%s: %s %d" % (_('Parameters for'), _("Tool"), tooluid) ) + + # update the form with the V-Shape fields if V-Shape selected in the geo_tool_table + # also modify the Cut Z form entry to reflect the calculated Cut Z from values got from V-Shape Fields + try: + item = self.ui.geo_tools_table.cellWidget(current_row, 4) + if item is not None: + tool_type_txt = item.currentText() + self.ui_update_v_shape(tool_type_txt=tool_type_txt) + else: + self.ui_connect() + return + except Exception as e: + log.debug("Tool missing in ui_update_v_shape(). Add a tool in Geo Tool Table. %s" % str(e)) + return + + try: + # set the form with data from the newly selected tool + for tooluid_key, tooluid_value in self.tools.items(): + if int(tooluid_key) == tooluid: + for key, value in tooluid_value.items(): + if key == 'data': + form_value_storage = tooluid_value['data'] + self.update_form(form_value_storage) + if key == 'offset_value': + # update the offset value in the entry even if the entry is hidden + self.ui.tool_offset_entry.set_value(tooluid_value['offset_value']) + + if key == 'tool_type' and value == 'V': + self.update_cutz() + except Exception as e: + log.debug("FlatCAMGeometry.update_ui() -> %s " % str(e)) + else: self.ui.tool_data_label.setText( "%s: %s" % (_('Parameters for'), _("Multiple Tools")) ) - # update the form with the V-Shape fields if V-Shape selected in the geo_tool_table - # also modify the Cut Z form entry to reflect the calculated Cut Z from values got from V-Shape Fields - try: - item = self.ui.geo_tools_table.cellWidget(current_row, 4) - if item is not None: - tool_type_txt = item.currentText() - self.ui_update_v_shape(tool_type_txt=tool_type_txt) - else: - self.ui_connect() - return - except Exception as e: - log.debug("Tool missing in ui_update_v_shape(). Add a tool in Geo Tool Table. %s" % str(e)) - return - - try: - # set the form with data from the newly selected tool - for tooluid_key, tooluid_value in self.tools.items(): - if int(tooluid_key) == tooluid: - for key, value in tooluid_value.items(): - if key == 'data': - form_value_storage = tooluid_value['data'] - self.update_form(form_value_storage) - if key == 'offset_value': - # update the offset value in the entry even if the entry is hidden - self.ui.tool_offset_entry.set_value(tooluid_value['offset_value']) - - if key == 'tool_type' and value == 'V': - self.update_cutz() - except Exception as e: - log.debug("FlatCAMGeometry.update_ui() -> %s " % str(e)) - self.ui_connect() def on_tool_add(self, dia=None): diff --git a/README.md b/README.md index 08c2b639..6a9c7726 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,12 @@ CAD program, and create G-Code for Isolation routing. - updated all FlatCAM tools to use the new confirmation message that show if the entered value is within range or outside - updated all FlatCAM tools to use the new confirmation message for QSpinBoxes, too - in Excellon UI protected the values that are common parameters from change on tool selection change -- fixed some issues realted to the usage of the new confirmation message in FlatCAM Tools +- fixed some issues related to the usage of the new confirmation message in FlatCAM Tools - made sure that the FlatCAM Tools UI initialization is done only in set_tool_ui() method and not in the constructor - adapted the GCode generation from Excellon to work with multiple tools data and modified the preprocessors header +- when multiple tools are selected in Excellon UI and parameters are modified it will applied to all selected +- in Excellon UI, Paint Tool and NCC Tool finished the "Apply parameters to all tools" functionality +- updated Paint Tool and NCC Tool in the UI functionality 16.02.2020 diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index 0c5537c8..7f8f9ec6 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -5826,7 +5826,7 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI): # ], orientation='vertical', stretch=False) self.paintmethod_combo = FCComboBox() self.paintmethod_combo.addItems( - [_("Standard"), _("Seed-based"), _("Straight lines"), _("Laser lines"), _("Combo")] + [_("Standard"), _("Seed"), _("Lines"), _("Laser_lines"), _("Combo")] ) grid0.addWidget(methodlabel, 11, 0) diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNonCopperClear.py index b1c5c65e..89889a5d 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/flatcamTools/ToolNonCopperClear.py @@ -8,7 +8,8 @@ from PyQt5 import QtWidgets, QtCore, QtGui from FlatCAMTool import FlatCAMTool -from flatcamGUI.GUIElements import FCCheckBox, FCDoubleSpinner, RadioSet, FCTable, FCInputDialog, FCButton, FCComboBox +from flatcamGUI.GUIElements import FCCheckBox, FCDoubleSpinner, RadioSet, FCTable, FCInputDialog, FCButton, FCComboBox, \ + OptionalInputSection from flatcamParsers.ParseGerber import Gerber import FlatCAMApp @@ -70,7 +71,7 @@ class NonCopperClear(FlatCAMTool, Gerber): # ################################################ # ##### Type of object to be copper cleaned ###### # ################################################ - # self.type_obj_combo = QtWidgets.QComboBox() + # self.type_obj_combo = FCComboBox() # self.type_obj_combo.addItem("Gerber") # self.type_obj_combo.addItem("Excellon") # self.type_obj_combo.addItem("Geometry") @@ -97,7 +98,7 @@ class NonCopperClear(FlatCAMTool, Gerber): # ################################################ # ##### The object to be copper cleaned ########## # ################################################ - self.object_combo = QtWidgets.QComboBox() + self.object_combo = FCComboBox() self.object_combo.setModel(self.app.collection) self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.object_combo.setCurrentIndex(1) @@ -439,14 +440,7 @@ class NonCopperClear(FlatCAMTool, Gerber): ) self.grid3.addWidget(self.ncc_choice_offset_cb, 19, 0) - # ## NCC Offset value - # self.ncc_offset_label = QtWidgets.QLabel('%s:' % _("Offset value")) - # self.ncc_offset_label.setToolTip( - # _("If used, it will add an offset to the copper features.\n" - # "The copper clearing will finish to a distance\n" - # "from the copper features.\n" - # "The value can be between 0 and 10 FlatCAM units.") - # ) + # ## NCC Offset Entry self.ncc_offset_spinner = FCDoubleSpinner(callback=self.confirmation_message) self.ncc_offset_spinner.set_range(0.00, 10.00) self.ncc_offset_spinner.set_precision(4) @@ -459,12 +453,10 @@ class NonCopperClear(FlatCAMTool, Gerber): else: self.ncc_offset_spinner.setSingleStep(0.01) - # self.grid3.addWidget(self.ncc_offset_label, 20, 0) self.grid3.addWidget(self.ncc_offset_spinner, 19, 1) - - # self.ncc_offset_label.hide() - self.ncc_offset_spinner.setEnabled(False) - + + self.ois_ncc_offset = OptionalInputSection(self.ncc_choice_offset_cb, [self.ncc_offset_spinner]) + separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) @@ -530,7 +522,7 @@ class NonCopperClear(FlatCAMTool, Gerber): _("The type of FlatCAM object to be used as non copper clearing reference.\n" "It can be Gerber, Excellon or Geometry.") ) - self.box_combo_type = QtWidgets.QComboBox() + self.box_combo_type = FCComboBox() self.box_combo_type.addItem(_("Reference Gerber")) self.box_combo_type.addItem(_("Reference Excellon")) self.box_combo_type.addItem(_("Reference Geometry")) @@ -540,7 +532,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.box_combo_label.setToolTip( _("The FlatCAM object to be used as non copper clearing reference.") ) - self.box_combo = QtWidgets.QComboBox() + self.box_combo = FCComboBox() self.box_combo.setModel(self.app.collection) self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.box_combo.setCurrentIndex(1) @@ -683,11 +675,14 @@ class NonCopperClear(FlatCAMTool, Gerber): self.box_combo_type.currentIndexChanged.connect(self.on_combo_box_type) self.reference_radio.group_toggle_fn = self.on_toggle_reference - self.ncc_choice_offset_cb.stateChanged.connect(self.on_offset_choice) + self.ncc_rest_cb.stateChanged.connect(self.on_rest_machining_check) self.ncc_order_radio.activated_custom[str].connect(self.on_order_changed) self.type_obj_combo.activated_custom.connect(self.on_type_obj_index_changed) + + self.apply_param_to_all.clicked.connect(self.on_apply_param_to_all_clicked) + self.reset_button.clicked.connect(self.set_tool_ui) def on_type_obj_index_changed(self, val): @@ -696,48 +691,46 @@ class NonCopperClear(FlatCAMTool, Gerber): self.object_combo.setCurrentIndex(0) def on_row_selection_change(self): - self.update_ui() - - def update_ui(self, row=None): self.blockSignals(True) - if row is None: + sel_rows = [it.row() for it in self.tools_table.selectedItems()] + # sel_rows = sorted(set(index.row() for index in self.tools_table.selectedIndexes())) + + if not sel_rows: + sel_rows = [0] + + for current_row in sel_rows: + # populate the form with the data from the tool associated with the row parameter try: - current_row = self.tools_table.currentRow() - except Exception: - current_row = 0 - else: - current_row = row - - if current_row < 0: - current_row = 0 - - # populate the form with the data from the tool associated with the row parameter - try: - item = self.tools_table.item(current_row, 3) - if item is not None: - tooluid = int(item.text()) - else: + item = self.tools_table.item(current_row, 3) + if item is not None: + tooluid = int(item.text()) + else: + return + except Exception as e: + log.debug("Tool missing. Add a tool in the Tool Table. %s" % str(e)) return - except Exception as e: - log.debug("Tool missing. Add a tool in the Tool Table. %s" % str(e)) - return - # update the QLabel that shows for which Tool we have the parameters in the UI form - self.tool_data_label.setText( - "%s: %s %d" % (_('Parameters for'), _("Tool"), (current_row + 1)) - ) - - try: - # set the form with data from the newly selected tool - for tooluid_key, tooluid_value in list(self.ncc_tools.items()): - if int(tooluid_key) == tooluid: - for key, value in tooluid_value.items(): - if key == 'data': - form_value_storage = tooluid_value[key] - self.storage_to_form(form_value_storage) - except Exception as e: - log.debug("NonCopperClear ---> update_ui() " + str(e)) + # update the QLabel that shows for which Tool we have the parameters in the UI form + if len(sel_rows) == 1: + cr = current_row + 1 + self.tool_data_label.setText( + "%s: %s %d" % (_('Parameters for'), _("Tool"), cr) + ) + try: + # set the form with data from the newly selected tool + for tooluid_key, tooluid_value in list(self.ncc_tools.items()): + if int(tooluid_key) == tooluid: + for key, value in tooluid_value.items(): + if key == 'data': + form_value_storage = tooluid_value[key] + self.storage_to_form(form_value_storage) + except Exception as e: + log.debug("NonCopperClear ---> update_ui() " + str(e)) + else: + self.tool_data_label.setText( + "%s: %s" % (_('Parameters for'), _("Multiple Tools")) + ) self.blockSignals(False) @@ -761,19 +754,20 @@ class NonCopperClear(FlatCAMTool, Gerber): wdg_objname = widget_changed.objectName() option_changed = self.name2option[wdg_objname] - row = self.tools_table.currentRow() + # row = self.tools_table.currentRow() + rows = sorted(set(index.row() for index in self.tools_table.selectedIndexes())) + for row in rows: + if row < 0: + row = 0 + tooluid_item = int(self.tools_table.item(row, 3).text()) - if row < 0: - row = 0 - tooluid_item = int(self.tools_table.item(row, 3).text()) - - for tooluid_key, tooluid_val in self.ncc_tools.items(): - if int(tooluid_key) == tooluid_item: - new_option_value = self.form_fields[option_changed].get_value() - if option_changed in tooluid_val: - tooluid_val[option_changed] = new_option_value - if option_changed in tooluid_val['data']: - tooluid_val['data'][option_changed] = new_option_value + for tooluid_key, tooluid_val in self.ncc_tools.items(): + if int(tooluid_key) == tooluid_item: + new_option_value = self.form_fields[option_changed].get_value() + if option_changed in tooluid_val: + tooluid_val[option_changed] = new_option_value + if option_changed in tooluid_val['data']: + tooluid_val['data'][option_changed] = new_option_value self.blockSignals(False) @@ -828,6 +822,8 @@ class NonCopperClear(FlatCAMTool, Gerber): self.ncc_tools = deepcopy(temp_tools) temp_tools.clear() + self.app.inform.emit('[success] %s' % _("Current Tool parameters were applied to all tools.")) + self.blockSignals(False) def on_add_tool_by_key(self): @@ -1027,16 +1023,16 @@ class NonCopperClear(FlatCAMTool, Gerber): dia.setFlags(QtCore.Qt.ItemIsEnabled) - tool_type_item = QtWidgets.QComboBox() - for item in self.tool_type_item_options: - tool_type_item.addItem(item) + tool_type_item = FCComboBox() + tool_type_item.addItems(self.tool_type_item_options) + # tool_type_item.setStyleSheet('background-color: rgb(255,255,255)') idx = tool_type_item.findText(tooluid_value['tool_type']) tool_type_item.setCurrentIndex(idx) tool_uid_item = QtWidgets.QTableWidgetItem(str(int(tooluid_key))) - operation_type = QtWidgets.QComboBox() + operation_type = FCComboBox() operation_type.addItem('iso_op') # operation_type.setStyleSheet('background-color: rgb(255,255,255)') operation_type.addItem('clear_op') @@ -1082,6 +1078,16 @@ class NonCopperClear(FlatCAMTool, Gerber): self.ui_connect() + # set the text on tool_data_label after loading the object + sel_rows = list() + sel_items = self.tools_table.selectedItems() + for it in sel_items: + sel_rows.append(it.row()) + if len(sel_rows) > 1: + self.tool_data_label.setText( + "%s: %s" % (_('Parameters for'), _("Multiple Tools")) + ) + def ui_connect(self): self.tools_table.itemChanged.connect(self.on_tool_edit) @@ -1222,15 +1228,6 @@ class NonCopperClear(FlatCAMTool, Gerber): self.box_combo_type.show() self.box_combo_type_label.show() - def on_offset_choice(self, state): - # if state: - # self.ncc_offset_label.show() - # self.ncc_offset_spinner.show() - # else: - # self.ncc_offset_label.hide() - # self.ncc_offset_spinner.hide() - self.ncc_offset_spinner.setEnabled(state) - def on_order_changed(self, order): if order != 'no': self.build_ui() diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index d1524a96..21eaf8a0 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -205,7 +205,7 @@ class ToolPaint(FlatCAMTool, Gerber): "- 'V-shape'\n" "- Circular") ) - self.tool_type_radio.setObjectName(_("Tool Type")) + self.tool_type_radio.setObjectName('p_tool_type') self.grid3.addWidget(self.tool_type_label, 2, 0) self.grid3.addWidget(self.tool_type_radio, 2, 1) @@ -218,7 +218,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.tipdia_entry.set_precision(self.decimals) self.tipdia_entry.set_range(0.0000, 9999.9999) self.tipdia_entry.setSingleStep(0.1) - self.tipdia_entry.setObjectName(_("V-Tip Dia")) + self.tipdia_entry.setObjectName('p_vtip_dia') self.grid3.addWidget(self.tipdialabel, 3, 0) self.grid3.addWidget(self.tipdia_entry, 3, 1) @@ -232,7 +232,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.tipangle_entry.set_precision(self.decimals) self.tipangle_entry.set_range(0.0000, 180.0000) self.tipangle_entry.setSingleStep(5) - self.tipangle_entry.setObjectName(_("V-Tip Angle")) + self.tipangle_entry.setObjectName('p_vtip_angle') self.grid3.addWidget(self.tipanglelabel, 4, 0) self.grid3.addWidget(self.tipangle_entry, 4, 1) @@ -246,7 +246,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.cutz_entry = FCDoubleSpinner(callback=self.confirmation_message) self.cutz_entry.set_precision(self.decimals) self.cutz_entry.set_range(-99999.9999, 0.0000) - self.cutz_entry.setObjectName(_("Cut Z")) + self.cutz_entry.setObjectName('p_cutz') self.cutz_entry.setToolTip( _("Depth of cut into material. Negative value.\n" @@ -265,7 +265,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.addtool_entry = FCDoubleSpinner(callback=self.confirmation_message) self.addtool_entry.set_precision(self.decimals) self.addtool_entry.set_range(0.000, 9999.9999) - self.addtool_entry.setObjectName(_("Tool Dia")) + self.addtool_entry.setObjectName('p_tool_dia') self.grid3.addWidget(self.addtool_entry_lbl, 6, 0) self.grid3.addWidget(self.addtool_entry, 6, 1) @@ -339,7 +339,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.paintoverlap_entry.setWrapping(True) self.paintoverlap_entry.setRange(0.0000, 99.9999) self.paintoverlap_entry.setSingleStep(0.1) - self.paintoverlap_entry.setObjectName(_("Overlap")) + self.paintoverlap_entry.setObjectName('p_overlap') grid4.addWidget(ovlabel, 1, 0) grid4.addWidget(self.paintoverlap_entry, 1, 1) @@ -354,7 +354,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.paintmargin_entry = FCDoubleSpinner(callback=self.confirmation_message) self.paintmargin_entry.set_precision(self.decimals) self.paintmargin_entry.set_range(-9999.9999, 9999.9999) - self.paintmargin_entry.setObjectName(_("Margin")) + self.paintmargin_entry.setObjectName('p_margin') grid4.addWidget(marginlabel, 2, 0) grid4.addWidget(self.paintmargin_entry, 2, 1) @@ -373,45 +373,38 @@ class ToolPaint(FlatCAMTool, Gerber): ) # self.paintmethod_combo = RadioSet([ # {"label": _("Standard"), "value": "standard"}, - # {"label": _("Seed-based"), "value": "seed"}, - # {"label": _("Straight lines"), "value": "lines"}, - # {"label": _("Laser lines"), "value": "laser_lines"}, - # {"label": _("Combo"), "value": "combo"} + # {"label": _("Seed-based"), "value": _("Seed")}, + # {"label": _("Straight lines"), "value": _("Lines")}, + # {"label": _("Laser lines"), "value": _("Laser_lines")}, + # {"label": _("Combo"), "value": _("Combo")} # ], orientation='vertical', stretch=False) # for choice in self.paintmethod_combo.choices: - # if choice['value'] == "laser_lines": + # if choice['value'] == _("Laser_lines"): # choice["radio"].setEnabled(False) self.paintmethod_combo = FCComboBox() self.paintmethod_combo.addItems( - [_("Standard"), _("Seed-based"), _("Straight lines"), _("Laser lines"), _("Combo")] + [_("Standard"), _("Seed"), _("Lines"), _("Laser_lines"), _("Combo")] ) - self.p_mth = { - _("Standard"): "standard", - _("Seed-based"): "seed", - _("Straight lines"): "lines", - _("Laser lines"): "laser_lines", - _("Combo"): "combo" - } - idx = self.paintmethod_combo.findText(_("Laser lines")) + idx = self.paintmethod_combo.findText(_("Laser_lines")) self.paintmethod_combo.model().item(idx).setEnabled(False) - self.paintmethod_combo.setObjectName(_("Method")) + self.paintmethod_combo.setObjectName('p_method') grid4.addWidget(methodlabel, 7, 0) grid4.addWidget(self.paintmethod_combo, 7, 1) # Connect lines self.pathconnect_cb = FCCheckBox('%s' % _("Connect")) - self.pathconnect_cb.setObjectName(_("Connect")) + self.pathconnect_cb.setObjectName('p_connect') self.pathconnect_cb.setToolTip( _("Draw lines between resulting\n" "segments to minimize tool lifts.") ) self.paintcontour_cb = FCCheckBox('%s' % _("Contour")) - self.paintcontour_cb.setObjectName(_("Contour")) + self.paintcontour_cb.setObjectName('p_contour') self.paintcontour_cb.setToolTip( _("Cut around the perimeter of the polygon\n" "to trim rough edges.") @@ -445,7 +438,7 @@ class ToolPaint(FlatCAMTool, Gerber): grid4.addWidget(self.gen_param_label, 15, 0, 1, 2) self.rest_cb = FCCheckBox('%s' % _("Rest Machining")) - self.rest_cb.setObjectName(_("Rest Machining")) + self.rest_cb.setObjectName('p_rest_machining') self.rest_cb.setToolTip( _("If checked, use 'rest machining'.\n" "Basically it will clear copper outside PCB features,\n" @@ -476,7 +469,7 @@ class ToolPaint(FlatCAMTool, Gerber): {"label": _("All Polygons"), "value": "all"}, {"label": _("Reference Object"), "value": "ref"} ], orientation='vertical', stretch=False) - self.selectmethod_combo.setObjectName(_("Selection")) + self.selectmethod_combo.setObjectName('p_selection') self.selectmethod_combo.setToolTip( _("How to select Polygons to be painted.\n" "- 'Polygon Selection' - left mouse click to add/remove polygons to be painted.\n" @@ -574,7 +567,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.select_method = None self.units = '' - self.paint_tools = {} + self.paint_tools = dict() self.tooluid = 0 self.first_click = False self.cursor_pos = None @@ -584,7 +577,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.mp = None self.mr = None - self.sel_rect = [] + self.sel_rect = list() # store here if the grid snapping is active self.grid_status_memory = False @@ -606,11 +599,11 @@ class ToolPaint(FlatCAMTool, Gerber): } self.name2option = { - _('Overlap'): "paintoverlap", - _('Margin'): "paintmargin", - _('Method'): "paintmethod", - _("Connect"): "pathconnect", - _("Contour"): "paintcontour", + 'p_overlap': "paintoverlap", + 'p_margin': "paintmargin", + 'p_method': "paintmethod", + 'p_connect': "pathconnect", + 'p_contour': "paintcontour", } self.old_tool_dia = None @@ -628,7 +621,7 @@ class ToolPaint(FlatCAMTool, Gerber): # self.copytool_btn.clicked.connect(lambda: self.on_tool_copy()) # self.tools_table.itemChanged.connect(self.on_tool_edit) - self.tools_table.currentItemChanged.connect(self.on_row_selection_change) + self.tools_table.clicked.connect(self.on_row_selection_change) self.generate_paint_button.clicked.connect(self.on_paint_button_click) self.selectmethod_combo.activated_custom.connect(self.on_radio_selection) @@ -637,6 +630,9 @@ class ToolPaint(FlatCAMTool, Gerber): self.box_combo_type.currentIndexChanged.connect(self.on_combo_box_type) self.type_obj_combo.activated_custom.connect(self.on_type_obj_changed) + + self.apply_param_to_all.clicked.connect(self.on_apply_param_to_all_clicked) + self.reset_button.clicked.connect(self.set_tool_ui) # ############################################################################# @@ -660,13 +656,13 @@ class ToolPaint(FlatCAMTool, Gerber): self.obj_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) self.obj_combo.setCurrentIndex(0) - idx = self.paintmethod_combo.findText(_("Laser lines")) + idx = self.paintmethod_combo.findText(_("Laser_lines")) if self.type_obj_combo.get_value().lower() == 'gerber': self.paintmethod_combo.model().item(idx).setEnabled(True) else: self.paintmethod_combo.model().item(idx).setEnabled(False) - if self.paintmethod_combo.get_value() == _("Laser lines"): - self.paintmethod_combo.set_value(_("Straight lines")) + if self.paintmethod_combo.get_value() == _("Laser_lines"): + self.paintmethod_combo.set_value(_("Lines")) def install(self, icon=None, separator=None, **kwargs): FlatCAMTool.install(self, icon, separator, shortcut='ALT+P', **kwargs) @@ -700,48 +696,46 @@ class ToolPaint(FlatCAMTool, Gerber): self.app.ui.notebook.setTabText(2, _("Paint Tool")) def on_row_selection_change(self): - self.update_ui() - - def update_ui(self, row=None): self.blockSignals(True) - if row is None: + sel_rows = [it.row() for it in self.tools_table.selectedItems()] + # sel_rows = sorted(set(index.row() for index in self.tools_table.selectedIndexes())) + + if not sel_rows: + sel_rows = [0] + + for current_row in sel_rows: + # populate the form with the data from the tool associated with the row parameter try: - current_row = self.tools_table.currentRow() - except Exception: - current_row = 0 - else: - current_row = row - - if current_row < 0: - current_row = 0 - - # populate the form with the data from the tool associated with the row parameter - try: - item = self.tools_table.item(current_row, 3) - if item is not None: + item = self.tools_table.item(current_row, 3) + if item is None: + return 'fail' tooluid = int(item.text()) - else: + except Exception as e: + log.debug("Tool missing. Add a tool in the Tool Table. %s" % str(e)) return - except Exception as e: - log.debug("Tool missing. Add a tool in the Tool Table. %s" % str(e)) - return - # update the QLabel that shows for which Tool we have the parameters in the UI form - self.tool_data_label.setText( - "%s: %s %d" % (_('Parameters for'), _("Tool"), (current_row + 1)) - ) + # update the QLabel that shows for which Tool we have the parameters in the UI form + if len(sel_rows) == 1: + cr = self.tools_table.item(current_row, 0).text() + self.tool_data_label.setText( + "%s: %s %s" % (_('Parameters for'), _("Tool"), cr) + ) - try: - # set the form with data from the newly selected tool - for tooluid_key, tooluid_value in list(self.paint_tools.items()): - if int(tooluid_key) == tooluid: - for key, value in tooluid_value.items(): - if key == 'data': - form_value_storage = tooluid_value[key] - self.storage_to_form(form_value_storage) - except Exception as e: - log.debug("ToolPaint ---> update_ui() " + str(e)) + try: + # set the form with data from the newly selected tool + for tooluid_key, tooluid_value in list(self.paint_tools.items()): + if int(tooluid_key) == tooluid: + for key, value in tooluid_value.items(): + if key == 'data': + form_value_storage = tooluid_value[key] + self.storage_to_form(form_value_storage) + except Exception as e: + log.debug("ToolPaint ---> update_ui() " + str(e)) + else: + self.tool_data_label.setText( + "%s: %s" % (_('Parameters for'), _("Multiple Tools")) + ) self.blockSignals(False) @@ -765,18 +759,20 @@ class ToolPaint(FlatCAMTool, Gerber): wdg_objname = widget_changed.objectName() option_changed = self.name2option[wdg_objname] - row = self.tools_table.currentRow() - if row < 0: - row = 0 - tooluid_item = int(self.tools_table.item(row, 3).text()) + # row = self.tools_table.currentRow() + rows = sorted(set(index.row() for index in self.tools_table.selectedIndexes())) + for row in rows: + if row < 0: + row = 0 + tooluid_item = int(self.tools_table.item(row, 3).text()) - for tooluid_key, tooluid_val in self.paint_tools.items(): - if int(tooluid_key) == tooluid_item: - new_option_value = self.form_fields[option_changed].get_value() - if option_changed in tooluid_val: - tooluid_val[option_changed] = new_option_value - if option_changed in tooluid_val['data']: - tooluid_val['data'][option_changed] = new_option_value + for tooluid_key, tooluid_val in self.paint_tools.items(): + if int(tooluid_key) == tooluid_item: + new_option_value = self.form_fields[option_changed].get_value() + if option_changed in tooluid_val: + tooluid_val[option_changed] = new_option_value + if option_changed in tooluid_val['data']: + tooluid_val['data'][option_changed] = new_option_value self.blockSignals(False) @@ -788,40 +784,24 @@ class ToolPaint(FlatCAMTool, Gerber): self.blockSignals(True) - # row = self.tools_table.currentRow() - # if row < 0: - # row = 0 + row = self.tools_table.currentRow() + if row < 0: + row = 0 - # this new dict will hold the actual useful data, another dict that is the value of key 'data' - temp_tools = {} - temp_dia = {} - temp_data = {} + tooluid_item = int(self.tools_table.item(row, 3).text()) + temp_tool_data = dict() - for tooluid_key, tooluid_value in self.paint_tools.items(): - for key, value in tooluid_value.items(): - if key == 'data': - # update the 'data' section - for data_key in tooluid_value[key].keys(): - for form_key, form_value in self.form_fields.items(): - if form_key == data_key: - temp_data[data_key] = form_value.get_value() - # make sure we make a copy of the keys not in the form (we may use 'data' keys that are - # updated from self.app.defaults - if data_key not in self.form_fields: - temp_data[data_key] = value[data_key] - temp_dia[key] = deepcopy(temp_data) - temp_data.clear() + for tooluid_key, tooluid_val in self.paint_tools.items(): + if int(tooluid_key) == tooluid_item: + # this will hold the 'data' key of the self.tools[tool] dictionary that corresponds to + # the current row in the tool table + temp_tool_data = tooluid_val['data'] + break - elif key == 'solid_geometry': - temp_dia[key] = deepcopy(self.tools[tooluid_key]['solid_geometry']) - else: - temp_dia[key] = deepcopy(value) + for tooluid_key, tooluid_val in self.paint_tools.items(): + tooluid_val['data'] = deepcopy(temp_tool_data) - temp_tools[tooluid_key] = deepcopy(temp_dia) - - self.paint_tools.clear() - self.paint_tools = deepcopy(temp_tools) - temp_tools.clear() + self.app.inform.emit('[success] %s' % _("Current Tool parameters were applied to all tools.")) self.blockSignals(False) @@ -1682,7 +1662,7 @@ class ToolPaint(FlatCAMTool, Gerber): :param outname: Name of the resulting Geometry Object. :param connect: Connect lines to avoid tool lifts. :param contour: Paint around the edges. - :param method: choice out of 'seed', 'normal', 'lines' + :param method: choice out of _("Seed"), 'normal', 'lines' :param tools_storage: whether to use the current tools_storage self.paints_tools or a different one. Usage of the different one is related to when this function is called from a TcL command. :return: None @@ -1717,7 +1697,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.app.inform.emit('[WARNING] %s' % _('No polygon found.')) return - paint_method = method if method is not None else self.p_mth[self.paintmethod_combo.get_value()] + paint_method = method if method is not None else self.paintmethod_combo.get_value() paint_margin = float(self.paintmargin_entry.get_value()) if margin is None else margin # determine if to use the progressive plotting prog_plot = True if self.app.defaults["tools_paint_plotting"] == 'progressive' else False @@ -1757,7 +1737,17 @@ class ToolPaint(FlatCAMTool, Gerber): def paint_p(polyg, tooldiameter): cpoly = None try: - if paint_method == "seed": + if paint_method == _("Standard"): + # Type(cp) == FlatCAMRTreeStorage | None + cpoly = self.clear_polygon(polyg, + tooldia=tooldiameter, + steps_per_circle=self.app.defaults["geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + + elif paint_method == _("Seed"): # Type(cp) == FlatCAMRTreeStorage | None cpoly = self.clear_polygon2(polyg, tooldia=tooldiameter, @@ -1767,7 +1757,7 @@ class ToolPaint(FlatCAMTool, Gerber): connect=conn, prog_plot=prog_plot) - elif paint_method == "lines": + elif paint_method == _("Lines"): # Type(cp) == FlatCAMRTreeStorage | None cpoly = self.clear_polygon3(polyg, tooldia=tooldiameter, @@ -1777,16 +1767,7 @@ class ToolPaint(FlatCAMTool, Gerber): connect=conn, prog_plot=prog_plot) - elif paint_method == "standard": - # Type(cp) == FlatCAMRTreeStorage | None - cpoly = self.clear_polygon(polyg, - tooldia=tooldiameter, - steps_per_circle=self.app.defaults["geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - elif paint_method == "laser_lines": + elif paint_method == _("Laser_lines"): # line = None # aperture_size = None @@ -1833,7 +1814,7 @@ class ToolPaint(FlatCAMTool, Gerber): pads_lines_list = list() # process the flashes found in the selected polygon with the 'lines' method for rectangular - # flashes and with 'seed' for oblong and circular flashes + # flashes and with _("Seed") for oblong and circular flashes # and pads (flahes) need the contour therefore I override the GUI settings with always True for ap_type in flash_el_dict: for elem in flash_el_dict[ap_type]: @@ -1933,7 +1914,7 @@ class ToolPaint(FlatCAMTool, Gerber): # connect=conn, # prog_plot=prog_plot) - elif paint_method == "combo": + elif paint_method == _("Combo"): self.app.inform.emit(_("Painting polygon with method: lines.")) cpoly = self.clear_polygon3(polyg, tooldia=tooldiameter, @@ -2127,12 +2108,12 @@ class ToolPaint(FlatCAMTool, Gerber): :param outname: name of the resulting object :param connect: Connect lines to avoid tool lifts. :param contour: Paint around the edges. - :param method: choice out of 'seed', 'normal', 'lines' + :param method: choice out of _("Seed"), 'normal', 'lines' :param tools_storage: whether to use the current tools_storage self.paints_tools or a different one. Usage of the different one is related to when this function is called from a TcL command. :return: """ - paint_method = method if method is not None else self.p_mth[self.paintmethod_combo.get_value()] + paint_method = method if method is not None else self.paintmethod_combo.get_value() if margin is not None: paint_margin = margin @@ -2306,7 +2287,7 @@ class ToolPaint(FlatCAMTool, Gerber): for pol in poly_buf: if pol is not None and isinstance(pol, Polygon): cp = None - if paint_method == 'standard': + if paint_method == _("Standard"): cp = self.clear_polygon(pol, tooldia=tool_dia, steps_per_circle=self.app.defaults[ @@ -2315,7 +2296,7 @@ class ToolPaint(FlatCAMTool, Gerber): contour=cont, connect=conn, prog_plot=prog_plot) - elif paint_method == 'seed': + elif paint_method == _("Seed"): cp = self.clear_polygon2(pol, tooldia=tool_dia, steps_per_circle=self.app.defaults[ @@ -2324,7 +2305,7 @@ class ToolPaint(FlatCAMTool, Gerber): contour=cont, connect=conn, prog_plot=prog_plot) - elif paint_method == "standard": + elif paint_method == _("Lines"): cp = self.clear_polygon3(pol, tooldia=tool_dia, steps_per_circle=self.app.defaults[ @@ -2333,7 +2314,7 @@ class ToolPaint(FlatCAMTool, Gerber): contour=cont, connect=conn, prog_plot=prog_plot) - elif paint_method == "laser_lines": + elif paint_method == _("Laser_lines"): # line = None # aperture_size = None @@ -2381,7 +2362,7 @@ class ToolPaint(FlatCAMTool, Gerber): pads_lines_list = list() # process the flashes found in the selected polygon with the 'lines' method - # for rectangular flashes and with 'seed' for oblong and circular flashes + # for rectangular flashes and with _("Seed") for oblong and circular flashes # and pads (flahes) need the contour therefore I override the GUI settings # with always True for ap_type in flash_el_dict: @@ -2459,7 +2440,7 @@ class ToolPaint(FlatCAMTool, Gerber): cp.insert(lin) except TypeError: cp.insert(lines_union) - elif paint_method == "combo": + elif paint_method == _("Combo"): self.app.inform.emit(_("Painting polygons with method: lines.")) cp = self.clear_polygon3(pol, tooldia=tool_dia, @@ -2508,7 +2489,7 @@ class ToolPaint(FlatCAMTool, Gerber): except TypeError: if isinstance(poly_buf, Polygon): cp = None - if paint_method == 'standard': + if paint_method == _("Standard"): cp = self.clear_polygon(poly_buf, tooldia=tool_dia, steps_per_circle=self.app.defaults[ @@ -2517,7 +2498,7 @@ class ToolPaint(FlatCAMTool, Gerber): contour=cont, connect=conn, prog_plot=prog_plot) - elif paint_method == 'seed': + elif paint_method == _("Seed"): cp = self.clear_polygon2(poly_buf, tooldia=tool_dia, steps_per_circle=self.app.defaults[ @@ -2526,7 +2507,7 @@ class ToolPaint(FlatCAMTool, Gerber): contour=cont, connect=conn, prog_plot=prog_plot) - elif paint_method == 'standard': + elif paint_method == _("Lines"): cp = self.clear_polygon3(poly_buf, tooldia=tool_dia, steps_per_circle=self.app.defaults[ @@ -2535,7 +2516,7 @@ class ToolPaint(FlatCAMTool, Gerber): contour=cont, connect=conn, prog_plot=prog_plot) - elif paint_method == "laser_lines": + elif paint_method == _("Laser_lines"): # line = None # aperture_size = None @@ -2583,7 +2564,7 @@ class ToolPaint(FlatCAMTool, Gerber): pads_lines_list = list() # process the flashes found in the selected polygon with the 'lines' method - # for rectangular flashes and with 'seed' for oblong and circular flashes + # for rectangular flashes and with _("Seed") for oblong and circular flashes # and pads (flahes) need the contour therefore I override the GUI settings # with always True for ap_type in flash_el_dict: @@ -2661,7 +2642,7 @@ class ToolPaint(FlatCAMTool, Gerber): cp.insert(lin) except TypeError: cp.insert(lines_union) - elif paint_method == "combo": + elif paint_method == _("Combo"): self.app.inform.emit(_("Painting polygons with method: lines.")) cp = self.clear_polygon3(poly_buf, tooldia=tool_dia, @@ -2721,7 +2702,7 @@ class ToolPaint(FlatCAMTool, Gerber): # continue # poly_buf = geo.buffer(-paint_margin) # - # if paint_method == "seed": + # if paint_method == _("Seed"): # # Type(cp) == FlatCAMRTreeStorage | None # cp = self.clear_polygon2(poly_buf, # tooldia=tool_dia, @@ -2731,7 +2712,7 @@ class ToolPaint(FlatCAMTool, Gerber): # connect=conn, # prog_plot=prog_plot) # - # elif paint_method == "lines": + # elif paint_method == _("Lines"): # # Type(cp) == FlatCAMRTreeStorage | None # cp = self.clear_polygon3(poly_buf, # tooldia=tool_dia, @@ -2893,27 +2874,27 @@ class ToolPaint(FlatCAMTool, Gerber): poly_buf = geo.buffer(-paint_margin) cp = None - if paint_method == "standard": + if paint_method == _("Standard"): # Type(cp) == FlatCAMRTreeStorage | None cp = self.clear_polygon(poly_buf, tooldia=tool_dia, steps_per_circle=self.app.defaults["geometry_circle_steps"], overlap=over, contour=cont, connect=conn, prog_plot=prog_plot) - elif paint_method == "seed": + elif paint_method == _("Seed"): # Type(cp) == FlatCAMRTreeStorage | None cp = self.clear_polygon2(poly_buf, tooldia=tool_dia, steps_per_circle=self.app.defaults["geometry_circle_steps"], overlap=over, contour=cont, connect=conn, prog_plot=prog_plot) - elif paint_method == "lines": + elif paint_method == _("Lines"): # Type(cp) == FlatCAMRTreeStorage | None cp = self.clear_polygon3(poly_buf, tooldia=tool_dia, steps_per_circle=self.app.defaults["geometry_circle_steps"], overlap=over, contour=cont, connect=conn, prog_plot=prog_plot) - elif paint_method == "laser_lines": + elif paint_method == _("Laser_lines"): # line = None # aperture_size = None @@ -2961,7 +2942,7 @@ class ToolPaint(FlatCAMTool, Gerber): pads_lines_list = list() # process the flashes found in the selected polygon with the 'lines' method - # for rectangular flashes and with 'seed' for oblong and circular flashes + # for rectangular flashes and with _("Seed") for oblong and circular flashes # and pads (flahes) need the contour therefore I override the GUI settings # with always True for ap_type in flash_el_dict: @@ -3039,7 +3020,7 @@ class ToolPaint(FlatCAMTool, Gerber): cp.insert(lin) except TypeError: cp.insert(lines_union) - elif paint_method == "combo": + elif paint_method == _("Combo"): self.app.inform.emit(_("Painting polygons with method: lines.")) cp = self.clear_polygon3(poly_buf, tooldia=tool_dia, @@ -3192,12 +3173,12 @@ class ToolPaint(FlatCAMTool, Gerber): :param outname: name of the resulting object :param connect: Connect lines to avoid tool lifts. :param contour: Paint around the edges. - :param method: choice out of 'seed', 'normal', 'lines' + :param method: choice out of _("Seed"), 'normal', 'lines' :param tools_storage: whether to use the current tools_storage self.paints_tools or a different one. Usage of the different one is related to when this function is called from a TcL command. :return: """ - paint_method = method if method is not None else self.p_mth[self.paintmethod_combo.get_value()] + paint_method = method if method is not None else self.paintmethod_combo.get_value() if margin is not None: paint_margin = margin @@ -3364,7 +3345,7 @@ class ToolPaint(FlatCAMTool, Gerber): poly_buf = geo.buffer(-paint_margin) cp = None - if paint_method == "seed": + if paint_method == _("Seed"): # Type(cp) == FlatCAMRTreeStorage | None cp = self.clear_polygon2(poly_buf, tooldia=tool_dia, @@ -3374,7 +3355,7 @@ class ToolPaint(FlatCAMTool, Gerber): connect=conn, prog_plot=prog_plot) - elif paint_method == "lines": + elif paint_method == _("Lines"): # Type(cp) == FlatCAMRTreeStorage | None cp = self.clear_polygon3(poly_buf, tooldia=tool_dia, @@ -3384,7 +3365,7 @@ class ToolPaint(FlatCAMTool, Gerber): connect=conn, prog_plot=prog_plot) - elif paint_method == 'standard': + elif paint_method == _("Standard"): # Type(cp) == FlatCAMRTreeStorage | None cp = self.clear_polygon(poly_buf, tooldia=tool_dia, @@ -3393,7 +3374,7 @@ class ToolPaint(FlatCAMTool, Gerber): contour=cont, connect=conn, prog_plot=prog_plot) - elif paint_method == "laser_lines": + elif paint_method == _("Laser_lines"): # line = None # aperture_size = None @@ -3441,7 +3422,7 @@ class ToolPaint(FlatCAMTool, Gerber): pads_lines_list = list() # process the flashes found in the selected polygon with the 'lines' method - # for rectangular flashes and with 'seed' for oblong and circular flashes + # for rectangular flashes and with _("Seed") for oblong and circular flashes # and pads (flahes) need the contour therefore I override the GUI settings # with always True for ap_type in flash_el_dict: @@ -3519,7 +3500,7 @@ class ToolPaint(FlatCAMTool, Gerber): cp.insert(lin) except TypeError: cp.insert(lines_union) - elif paint_method == "combo": + elif paint_method == _("Combo"): self.app.inform.emit(_("Painting polygons with method: lines.")) cp = self.clear_polygon3(poly_buf, tooldia=tool_dia, @@ -3693,27 +3674,27 @@ class ToolPaint(FlatCAMTool, Gerber): poly_buf = geo.buffer(-paint_margin) cp = None - if paint_method == "standard": + if paint_method == _("Standard"): # Type(cp) == FlatCAMRTreeStorage | None cp = self.clear_polygon(poly_buf, tooldia=tool_dia, steps_per_circle=self.app.defaults["geometry_circle_steps"], overlap=over, contour=cont, connect=conn, prog_plot=prog_plot) - elif paint_method == "seed": + elif paint_method == _("Seed"): # Type(cp) == FlatCAMRTreeStorage | None cp = self.clear_polygon2(poly_buf, tooldia=tool_dia, steps_per_circle=self.app.defaults["geometry_circle_steps"], overlap=over, contour=cont, connect=conn, prog_plot=prog_plot) - elif paint_method == "lines": + elif paint_method == _("Lines"): # Type(cp) == FlatCAMRTreeStorage | None cp = self.clear_polygon3(poly_buf, tooldia=tool_dia, steps_per_circle=self.app.defaults["geometry_circle_steps"], overlap=over, contour=cont, connect=conn, prog_plot=prog_plot) - elif paint_method == "laser_lines": + elif paint_method == _("Laser_lines"): # line = None # aperture_size = None @@ -3761,7 +3742,7 @@ class ToolPaint(FlatCAMTool, Gerber): pads_lines_list = list() # process the flashes found in the selected polygon with the 'lines' method - # for rectangular flashes and with 'seed' for oblong and circular flashes + # for rectangular flashes and with _("Seed") for oblong and circular flashes # and pads (flahes) need the contour therefore I override the GUI settings # with always True for ap_type in flash_el_dict: @@ -3839,7 +3820,7 @@ class ToolPaint(FlatCAMTool, Gerber): cp.insert(lin) except TypeError: cp.insert(lines_union) - elif paint_method == "combo": + elif paint_method == _("Combo"): self.app.inform.emit(_("Painting polygons with method: lines.")) cp = self.clear_polygon3(poly_buf, tooldia=tool_dia, @@ -3989,7 +3970,7 @@ class ToolPaint(FlatCAMTool, Gerber): :param outname: name of the resulting object :param connect: Connect lines to avoid tool lifts. :param contour: Paint around the edges. - :param method: choice out of 'seed', 'normal', 'lines' + :param method: choice out of _("Seed"), 'normal', 'lines' :param tools_storage: whether to use the current tools_storage self.paints_tools or a different one. Usage of the different one is related to when this function is called from a TcL command. :return: @@ -4027,6 +4008,10 @@ class ToolPaint(FlatCAMTool, Gerber): def ui_connect(self): self.tools_table.itemChanged.connect(self.on_tool_edit) + # rows selected + self.tools_table.clicked.connect(self.on_row_selection_change) + self.tools_table.horizontalHeader().sectionClicked.connect(self.on_row_selection_change) + for row in range(self.tools_table.rowCount()): try: self.tools_table.cellWidget(row, 2).currentIndexChanged.connect(self.on_tooltable_cellwidget_change) @@ -4068,6 +4053,8 @@ class ToolPaint(FlatCAMTool, Gerber): current_widget.activated_custom.connect(self.form_to_storage) elif isinstance(current_widget, FCDoubleSpinner): current_widget.returnPressed.connect(self.form_to_storage) + elif isinstance(current_widget, FCComboBox): + current_widget.currentIndexChanged.connect(self.form_to_storage) self.rest_cb.stateChanged.connect(self.on_rest_machining_check) self.order_radio.activated_custom[str].connect(self.on_order_changed) @@ -4079,6 +4066,17 @@ class ToolPaint(FlatCAMTool, Gerber): except (TypeError, AttributeError): pass + # rows selected + try: + self.tools_table.clicked.disconnect(self.on_row_selection_change) + except (TypeError, AttributeError): + pass + + try: + self.tools_table.horizontalHeader().sectionClicked.disconnect(self.on_row_selection_change) + except (TypeError, AttributeError): + pass + try: # if connected, disconnect the signal from the slot on item_changed as it creates issues self.tool_type_radio.activated_custom.disconnect() @@ -4096,17 +4094,22 @@ class ToolPaint(FlatCAMTool, Gerber): current_widget = self.form_fields[opt] if isinstance(current_widget, FCCheckBox): try: - current_widget.stateChanged.disconnect() + current_widget.stateChanged.disconnect(self.form_to_storage) except (TypeError, ValueError): pass if isinstance(current_widget, RadioSet): try: - current_widget.activated_custom.disconnect() + current_widget.activated_custom.disconnect(self.form_to_storage) except (TypeError, ValueError): pass elif isinstance(current_widget, FCDoubleSpinner): try: - current_widget.returnPressed.disconnect() + current_widget.returnPressed.disconnect(self.form_to_storage) + except (TypeError, ValueError): + pass + elif isinstance(current_widget, FCComboBox): + try: + current_widget.currentIndexChanged.connect(self.form_to_storage) except (TypeError, ValueError): pass From 042dc26cfa69eddb086d09d23b4f010137036f14 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Tue, 18 Feb 2020 04:26:53 +0200 Subject: [PATCH 106/209] - fixed the Offset spinbox not being controller by offset checkbox in NCC Tool --- README.md | 1 + flatcamTools/ToolNonCopperClear.py | 42 +++++++----------------------- 2 files changed, 11 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 6a9c7726..4be267f1 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ CAD program, and create G-Code for Isolation routing. - when multiple tools are selected in Excellon UI and parameters are modified it will applied to all selected - in Excellon UI, Paint Tool and NCC Tool finished the "Apply parameters to all tools" functionality - updated Paint Tool and NCC Tool in the UI functionality +- fixed the Offset spinbox not being controller by offset checkbox in NCC Tool 16.02.2020 diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNonCopperClear.py index 89889a5d..d07b9b63 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/flatcamTools/ToolNonCopperClear.py @@ -1108,35 +1108,6 @@ class NonCopperClear(FlatCAMTool, Gerber): self.tool_type_radio.activated_custom.connect(self.on_tool_type) - # first disconnect - for opt in self.form_fields: - current_widget = self.form_fields[opt] - if isinstance(current_widget, FCCheckBox): - try: - current_widget.stateChanged.disconnect() - except (TypeError, ValueError): - pass - if isinstance(current_widget, RadioSet): - try: - current_widget.activated_custom.disconnect() - except (TypeError, ValueError): - pass - elif isinstance(current_widget, FCDoubleSpinner): - try: - current_widget.returnPressed.disconnect() - except (TypeError, ValueError): - pass - - try: - self.ncc_rest_cb.stateChanged.disconnect() - except (TypeError, ValueError): - pass - try: - self.ncc_order_radio.activated_custom[str].disconnect() - except (TypeError, ValueError): - pass - - # then reconnect for opt in self.form_fields: current_widget = self.form_fields[opt] if isinstance(current_widget, FCCheckBox): @@ -1145,6 +1116,8 @@ class NonCopperClear(FlatCAMTool, Gerber): current_widget.activated_custom.connect(self.form_to_storage) elif isinstance(current_widget, FCDoubleSpinner): current_widget.returnPressed.connect(self.form_to_storage) + elif isinstance(current_widget, FCComboBox): + current_widget.currentIndexChanged.connect(self.form_to_storage) self.ncc_rest_cb.stateChanged.connect(self.on_rest_machining_check) self.ncc_order_radio.activated_custom[str].connect(self.on_order_changed) @@ -1174,17 +1147,22 @@ class NonCopperClear(FlatCAMTool, Gerber): current_widget = self.form_fields[opt] if isinstance(current_widget, FCCheckBox): try: - current_widget.stateChanged.disconnect() + current_widget.stateChanged.disconnect(self.form_to_storage) except (TypeError, ValueError): pass if isinstance(current_widget, RadioSet): try: - current_widget.activated_custom.disconnect() + current_widget.activated_custom.disconnect(self.form_to_storage) except (TypeError, ValueError): pass elif isinstance(current_widget, FCDoubleSpinner): try: - current_widget.returnPressed.disconnect() + current_widget.returnPressed.disconnect(self.form_to_storage) + except (TypeError, ValueError): + pass + elif isinstance(current_widget, FCComboBox): + try: + current_widget.currentIndexChanged.disconnect(self.form_to_storage) except (TypeError, ValueError): pass From f8f337526d07a1cd87e8a417f83b6e9e2470e7af Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 19 Feb 2020 14:15:06 +0200 Subject: [PATCH 107/209] - fixed some issues in the Geometry Editor; the jump sigmal disconnect was failing for repeated Editor tool operation --- README.md | 4 ++ camlib.py | 18 ++++--- flatcamEditors/FlatCAMGeoEditor.py | 83 ++++++++++++++++++++++++------ 3 files changed, 84 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 4be267f1..8b646712 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +19.02.2020 + +- fixed some issues in the Geometry Editor; the jump sigmal disconnect was failing for repeated Editor tool operation + 17.02.2020 - updated the Excellon UI to hold data for each tool diff --git a/camlib.py b/camlib.py index 46877405..bb402eb8 100644 --- a/camlib.py +++ b/camlib.py @@ -2850,14 +2850,16 @@ class CNCjob(Geometry): self.app.inform.emit('[WARNING] %s' % _("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 " + "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] %s: %s' % (_( - "The Cut Z parameter is zero. There will be no cut, skipping file"), + "The Cut Z parameter is zero. There will be no cut, " + "skipping file"), exobj.options['name'])) return 'fail' @@ -3063,14 +3065,16 @@ class CNCjob(Geometry): self.app.inform.emit('[WARNING] %s' % _("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 " + "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] %s: %s' % (_( - "The Cut Z parameter is zero. There will be no cut, skipping file"), + "The Cut Z parameter is zero. There will be no cut, " + "skipping file"), exobj.options['name'])) return 'fail' @@ -3269,14 +3273,16 @@ class CNCjob(Geometry): self.app.inform.emit('[WARNING] %s' % _("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 " + "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] %s: %s' % (_( - "The Cut Z parameter is zero. There will be no cut, skipping file"), + "The Cut Z parameter is zero. There will be no cut, " + "skipping file"), exobj.options['name'])) return 'fail' diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index 604227b1..26fb2615 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -1924,6 +1924,12 @@ class FCCircle(FCShapeTool): self.steps_per_circ = self.draw_app.app.defaults["geometry_circle_steps"] def click(self, point): + try: + self.draw_app.app.jump_signal.disconnect() + except (TypeError, AttributeError): + pass + self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x)) + self.points.append(point) if len(self.points) == 1: @@ -2003,6 +2009,12 @@ class FCArc(FCShapeTool): self.steps_per_circ = self.draw_app.app.defaults["geometry_circle_steps"] def click(self, point): + try: + self.draw_app.app.jump_signal.disconnect() + except (TypeError, AttributeError): + pass + self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x)) + self.points.append(point) if len(self.points) == 1: @@ -2227,6 +2239,12 @@ class FCRectangle(FCShapeTool): self.draw_app.app.inform.emit(_("Click on 1st corner ...")) def click(self, point): + try: + self.draw_app.app.jump_signal.disconnect() + except (TypeError, AttributeError): + pass + self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x)) + self.points.append(point) if len(self.points) == 1: @@ -2294,6 +2312,12 @@ class FCPolygon(FCShapeTool): self.draw_app.app.inform.emit(_("Click on 1st corner ...")) def click(self, point): + try: + self.draw_app.app.jump_signal.disconnect() + except (TypeError, AttributeError): + pass + self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x)) + self.draw_app.in_action = True self.points.append(point) @@ -2609,6 +2633,7 @@ class FCMove(FCShapeTool): return else: self.draw_app.app.inform.emit(_(" MOVE: Click on reference point ...")) + self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x)) def set_origin(self, origin): @@ -2616,6 +2641,12 @@ class FCMove(FCShapeTool): self.origin = origin def click(self, point): + try: + self.draw_app.app.jump_signal.disconnect() + except (TypeError, AttributeError): + pass + self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x)) + if len(self.draw_app.get_selected()) == 0: # self.complete = True # self.draw_app.app.inform.emit(_("[WARNING_NOTCL] Move cancelled. No shape selected.")) @@ -2647,7 +2678,10 @@ class FCMove(FCShapeTool): self.draw_app.delete_selected() self.complete = True self.draw_app.app.inform.emit('[success] %s' % _("Done. Geometry(s) Move completed.")) - self.draw_app.app.jump_signal.disconnect() + try: + self.draw_app.app.jump_signal.disconnect() + except TypeError: + pass def selection_bbox(self): geo_list = [] @@ -2777,7 +2811,10 @@ class FCCopy(FCMove): for geom in self.draw_app.get_selected()] self.complete = True self.draw_app.app.inform.emit('[success] %s' % _("Done. Geometry(s) Copy completed.")) - self.draw_app.app.jump_signal.disconnect() + try: + self.draw_app.app.jump_signal.disconnect() + except (TypeError, AttributeError): + pass def clean_up(self): self.draw_app.selected = list() @@ -2812,6 +2849,12 @@ class FCText(FCShapeTool): self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x)) def click(self, point): + try: + self.draw_app.app.jump_signal.disconnect() + except (TypeError, AttributeError): + pass + self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x)) + # Create new geometry dx = point[0] dy = point[1] @@ -2831,7 +2874,10 @@ class FCText(FCShapeTool): return else: self.draw_app.app.inform.emit('[WARNING_NOTCL] %s' % _("No text to add.")) - self.draw_app.app.jump_signal.disconnect() + try: + self.draw_app.app.jump_signal.disconnect() + except (TypeError, AttributeError): + pass return self.text_gui.text_path = [] @@ -2909,13 +2955,11 @@ class FCBuffer(FCShapeTool): self.disactivate() if ret_val == 'fail': return - self.draw_app.app.inform.emit('[success] %s' % - _("Done. Buffer Tool completed.")) + self.draw_app.app.inform.emit('[success] %s' % _("Done. Buffer Tool completed.")) def on_buffer_int(self): if not self.draw_app.selected: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Buffer cancelled. No shape selected.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Buffer cancelled. No shape selected.")) return try: @@ -2939,13 +2983,11 @@ class FCBuffer(FCShapeTool): self.disactivate() if ret_val == 'fail': return - self.draw_app.app.inform.emit('[success] %s' % - _("Done. Buffer Int Tool completed.")) + self.draw_app.app.inform.emit('[success] %s' % _("Done. Buffer Int Tool completed.")) def on_buffer_ext(self): if not self.draw_app.selected: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Buffer cancelled. No shape selected.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Buffer cancelled. No shape selected.")) return try: @@ -2969,8 +3011,7 @@ class FCBuffer(FCShapeTool): self.disactivate() if ret_val == 'fail': return - self.draw_app.app.inform.emit('[success] %s' % - _("Done. Buffer Ext Tool completed.")) + self.draw_app.app.inform.emit('[success] %s' % _("Done. Buffer Ext Tool completed.")) def activate(self): self.buff_tool.buffer_button.clicked.disconnect() @@ -2992,6 +3033,10 @@ class FCBuffer(FCShapeTool): self.complete = True self.draw_app.select_tool("select") self.buff_tool.hide_tool() + try: + self.draw_app.app.jump_signal.disconnect() + except (TypeError, AttributeError): + pass def clean_up(self): self.draw_app.selected = list() @@ -3003,7 +3048,6 @@ class FCBuffer(FCShapeTool): pass - class FCEraser(FCShapeTool): def __init__(self, draw_app): DrawTool.__init__(self, draw_app) @@ -3031,6 +3075,12 @@ class FCEraser(FCShapeTool): self.origin = origin def click(self, point): + try: + self.draw_app.app.jump_signal.disconnect() + except (TypeError, AttributeError): + pass + self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x)) + if len(self.draw_app.get_selected()) == 0: for obj_shape in self.storage.get_objects(): try: @@ -3078,7 +3128,10 @@ class FCEraser(FCShapeTool): self.draw_app.delete_utility_geometry() self.draw_app.plot_all() self.draw_app.app.inform.emit('[success] %s' % _("Done. Eraser tool action completed.")) - self.draw_app.app.jump_signal.disconnect() + try: + self.draw_app.app.jump_signal.disconnect() + except (TypeError, AttributeError): + pass def utility_geometry(self, data=None): """ From 6a24c8e20432a8c649a4aab078679af5dd6c87f6 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 19 Feb 2020 16:57:36 +0200 Subject: [PATCH 108/209] - fixed an issue in Gerber Editor where the multiprocessing pool was reported as closed and an ValueError exception was raised in a certain scneraio --- README.md | 1 + flatcamEditors/FlatCAMGrbEditor.py | 189 +++++++++++++++++------------ 2 files changed, 112 insertions(+), 78 deletions(-) diff --git a/README.md b/README.md index 8b646712..4d15d52e 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 19.02.2020 - fixed some issues in the Geometry Editor; the jump sigmal disconnect was failing for repeated Editor tool operation +- fixed an issue in Gerber Editor where the multiprocessing pool was reported as closed and an ValueError exception was raised in a certain scneraio 17.02.2020 diff --git a/flatcamEditors/FlatCAMGrbEditor.py b/flatcamEditors/FlatCAMGrbEditor.py index e1006725..c10c98a1 100644 --- a/flatcamEditors/FlatCAMGrbEditor.py +++ b/flatcamEditors/FlatCAMGrbEditor.py @@ -3045,6 +3045,9 @@ class FlatCAMGrbEditor(QtCore.QObject): # A QTimer self.plot_thread = None + # a QThread for the edit process + self.thread = QtCore.QThread() + # store the status of the editor so the Delete at object level will not work until the edit is finished self.editor_active = False @@ -3106,6 +3109,7 @@ class FlatCAMGrbEditor(QtCore.QObject): def pool_recreated(self, pool): self.shapes.pool = pool self.tool_shape.pool = pool + self.pool = pool def set_ui(self): # updated units @@ -3927,96 +3931,125 @@ class FlatCAMGrbEditor(QtCore.QObject): # # and add the first aperture to have something to play with # self.on_aperture_add('10') - def worker_job(app_obj): - with app_obj.app.proc_container.new('%s ...' % _("Loading Gerber into Editor")): - # ############################################################# ## - # APPLY CLEAR_GEOMETRY on the SOLID_GEOMETRY - # ############################################################# ## + # self.app.worker_task.emit({'fcn': worker_job, 'params': [self]}) - # list of clear geos that are to be applied to the entire file - global_clear_geo = [] + class Execute_Edit(QtCore.QObject): - # create one big geometry made out of all 'negative' (clear) polygons - for apid in app_obj.gerber_obj.apertures: - # first check if we have any clear_geometry (LPC) and if yes added it to the global_clear_geo - if 'geometry' in app_obj.gerber_obj.apertures[apid]: - for elem in app_obj.gerber_obj.apertures[apid]['geometry']: - if 'clear' in elem: - global_clear_geo.append(elem['clear']) - log.warning("Found %d clear polygons." % len(global_clear_geo)) + start = QtCore.pyqtSignal(str) - global_clear_geo = MultiPolygon(global_clear_geo) - if isinstance(global_clear_geo, Polygon): - global_clear_geo = list(global_clear_geo) + def __init__(self, app): + super(Execute_Edit, self).__init__() + self.app = app + self.start.connect(self.run) - # we subtract the big "negative" (clear) geometry from each solid polygon but only the part of - # clear geometry that fits inside the solid. otherwise we may loose the solid - for apid in app_obj.gerber_obj.apertures: - temp_solid_geometry = [] - if 'geometry' in app_obj.gerber_obj.apertures[apid]: - # for elem in self.gerber_obj.apertures[apid]['geometry']: - # if 'solid' in elem: - # solid_geo = elem['solid'] - # for clear_geo in global_clear_geo: - # # Make sure that the clear_geo is within the solid_geo otherwise we loose - # # the solid_geometry. We want for clear_geometry just to cut into solid_geometry not to - # # delete it - # if clear_geo.within(solid_geo): - # solid_geo = solid_geo.difference(clear_geo) - # try: - # for poly in solid_geo: - # new_elem = dict() - # - # new_elem['solid'] = poly - # if 'clear' in elem: - # new_elem['clear'] = poly - # if 'follow' in elem: - # new_elem['follow'] = poly - # temp_elem.append(deepcopy(new_elem)) - # except TypeError: - # new_elem = dict() - # new_elem['solid'] = solid_geo - # if 'clear' in elem: - # new_elem['clear'] = solid_geo - # if 'follow' in elem: - # new_elem['follow'] = solid_geo - # temp_elem.append(deepcopy(new_elem)) - for elem in app_obj.gerber_obj.apertures[apid]['geometry']: - new_elem = dict() - if 'solid' in elem: - solid_geo = elem['solid'] + @staticmethod + def worker_job(app_obj): + with app_obj.app.proc_container.new('%s ...' % _("Loading Gerber into Editor")): + # ############################################################# ## + # APPLY CLEAR_GEOMETRY on the SOLID_GEOMETRY + # ############################################################# ## - for clear_geo in global_clear_geo: - # Make sure that the clear_geo is within the solid_geo otherwise we loose - # the solid_geometry. We want for clear_geometry just to cut into solid_geometry - # not to delete it - if clear_geo.within(solid_geo): - solid_geo = solid_geo.difference(clear_geo) + # list of clear geos that are to be applied to the entire file + global_clear_geo = list() - new_elem['solid'] = solid_geo - if 'clear' in elem: - new_elem['clear'] = elem['clear'] - if 'follow' in elem: - new_elem['follow'] = elem['follow'] - temp_solid_geometry.append(deepcopy(new_elem)) + # create one big geometry made out of all 'negative' (clear) polygons + for apid in app_obj.gerber_obj.apertures: + # first check if we have any clear_geometry (LPC) and if yes added it to the global_clear_geo + if 'geometry' in app_obj.gerber_obj.apertures[apid]: + for elem in app_obj.gerber_obj.apertures[apid]['geometry']: + if 'clear' in elem: + global_clear_geo.append(elem['clear']) + log.warning("Found %d clear polygons." % len(global_clear_geo)) - app_obj.gerber_obj.apertures[apid]['geometry'] = deepcopy(temp_solid_geometry) - log.warning("Polygon difference done for %d apertures." % len(app_obj.gerber_obj.apertures)) + if global_clear_geo: + global_clear_geo = MultiPolygon(global_clear_geo) + if isinstance(global_clear_geo, Polygon): + global_clear_geo = list(global_clear_geo) - # Loading the Geometry into Editor Storage - for ap_id, ap_dict in app_obj.gerber_obj.apertures.items(): - app_obj.results.append(app_obj.pool.apply_async(app_obj.add_apertures, args=(ap_id, ap_dict))) + # we subtract the big "negative" (clear) geometry from each solid polygon but only the part of + # clear geometry that fits inside the solid. otherwise we may loose the solid + for apid in app_obj.gerber_obj.apertures: + temp_solid_geometry = list() + if 'geometry' in app_obj.gerber_obj.apertures[apid]: + # for elem in self.gerber_obj.apertures[apid]['geometry']: + # if 'solid' in elem: + # solid_geo = elem['solid'] + # for clear_geo in global_clear_geo: + # # Make sure that the clear_geo is within the solid_geo otherwise we loose + # # the solid_geometry. We want for clear_geometry just to cut into solid_geometry not to + # # delete it + # if clear_geo.within(solid_geo): + # solid_geo = solid_geo.difference(clear_geo) + # try: + # for poly in solid_geo: + # new_elem = dict() + # + # new_elem['solid'] = poly + # if 'clear' in elem: + # new_elem['clear'] = poly + # if 'follow' in elem: + # new_elem['follow'] = poly + # temp_elem.append(deepcopy(new_elem)) + # except TypeError: + # new_elem = dict() + # new_elem['solid'] = solid_geo + # if 'clear' in elem: + # new_elem['clear'] = solid_geo + # if 'follow' in elem: + # new_elem['follow'] = solid_geo + # temp_elem.append(deepcopy(new_elem)) + for elem in app_obj.gerber_obj.apertures[apid]['geometry']: + new_elem = dict() + if 'solid' in elem: + solid_geo = elem['solid'] + if not global_clear_geo or global_clear_geo.is_empty: + pass + else: + for clear_geo in global_clear_geo: + # Make sure that the clear_geo is within the solid_geo otherwise we loose + # the solid_geometry. We want for clear_geometry just to cut into + # solid_geometry not to delete it + if clear_geo.within(solid_geo): + solid_geo = solid_geo.difference(clear_geo) - output = list() - for p in app_obj.results: - output.append(p.get()) + new_elem['solid'] = solid_geo + if 'clear' in elem: + new_elem['clear'] = elem['clear'] + if 'follow' in elem: + new_elem['follow'] = elem['follow'] + temp_solid_geometry.append(deepcopy(new_elem)) - for elem in output: - app_obj.storage_dict[elem[0]] = deepcopy(elem[1]) + app_obj.gerber_obj.apertures[apid]['geometry'] = deepcopy(temp_solid_geometry) + log.warning("Polygon difference done for %d apertures." % len(app_obj.gerber_obj.apertures)) - app_obj.mp_finished.emit(output) + try: + # Loading the Geometry into Editor Storage + for ap_id, ap_dict in app_obj.gerber_obj.apertures.items(): + app_obj.results.append( + app_obj.pool.apply_async(app_obj.add_apertures, args=(ap_id, ap_dict)) + ) + except Exception as e: + log.debug( + "FlatCAMGrbEditor.edit_fcgerber.worker_job() Adding processes to pool --> %s" % str(e)) + traceback.print_exc() - self.app.worker_task.emit({'fcn': worker_job, 'params': [self]}) + output = list() + for p in app_obj.results: + output.append(p.get()) + + for elem in output: + app_obj.storage_dict[elem[0]] = deepcopy(elem[1]) + + app_obj.mp_finished.emit(output) + + def run(self): + self.worker_job(self.app) + + self.thread.start(QtCore.QThread.NormalPriority) + + executable_edit = Execute_Edit(app=self) + executable_edit.moveToThread(self.thread) + executable_edit.start.emit("Started") @staticmethod def add_apertures(aperture_id, aperture_dict): From 72ce53182dabe614606a4d8142bb1d3fd28a51af Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 19 Feb 2020 21:26:08 +0200 Subject: [PATCH 109/209] - on Set Origin, Move to Origin and Move actions for Gerber and Excellon objects the source file will be also updated (the export functions will export an updated object) --- FlatCAMApp.py | 26 +++++++++++++++++++++++++- README.md | 1 + flatcamTools/ToolMove.py | 10 ++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index e1be9814..e06a211e 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -7307,7 +7307,9 @@ class App(QtCore.QObject): def worker_task(): with self.proc_container.new(_("Setting Origin...")): - for obj in self.collection.get_list(): + obj_list = self.collection.get_list() + + for obj in obj_list: obj.offset((x, y)) self.object_changed.emit(obj) @@ -7318,6 +7320,17 @@ class App(QtCore.QObject): obj.options['xmax'] = c obj.options['ymax'] = d self.inform.emit('[success] %s...' % _('Origin set')) + + for obj in obj_list: + out_name = obj.options["name"] + + if obj.kind == 'gerber': + obj.source_file = self.export_gerber( + obj_name=out_name, filename=None, local_use=obj, use_thread=False) + elif obj.kind == 'excellon': + obj.source_file = self.export_excellon( + obj_name=out_name, filename=None, local_use=obj, use_thread=False) + if noplot_sig is False: self.replot_signal.emit([]) @@ -7400,6 +7413,17 @@ class App(QtCore.QObject): for obj in obj_list: obj.plot() + + for obj in obj_list: + out_name = obj.options["name"] + + if obj.kind == 'gerber': + obj.source_file = self.export_gerber( + obj_name=out_name, filename=None, local_use=obj, use_thread=False) + elif obj.kind == 'excellon': + obj.source_file = self.export_excellon( + obj_name=out_name, filename=None, local_use=obj, use_thread=False) + self.inform.emit('[success] %s...' % _('Origin set')) if use_thread is True: diff --git a/README.md b/README.md index 4d15d52e..c4358a4f 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ CAD program, and create G-Code for Isolation routing. - fixed some issues in the Geometry Editor; the jump sigmal disconnect was failing for repeated Editor tool operation - fixed an issue in Gerber Editor where the multiprocessing pool was reported as closed and an ValueError exception was raised in a certain scneraio +- on Set Origin, Move to Origin and Move actions for Gerber and Excellon objects the source file will be also updated (the export functions will export an updated object) 17.02.2020 diff --git a/flatcamTools/ToolMove.py b/flatcamTools/ToolMove.py index 7b6f9079..9b21c2da 100644 --- a/flatcamTools/ToolMove.py +++ b/flatcamTools/ToolMove.py @@ -188,6 +188,16 @@ class ToolMove(FlatCAMTool): sel_obj.options['ymin'] = b sel_obj.options['xmax'] = c sel_obj.options['ymax'] = d + + # update the source_file with the new positions + for sel_obj in obj_list: + out_name = sel_obj.options["name"] + if sel_obj.kind == 'gerber': + sel_obj.source_file = self.app.export_gerber( + obj_name=out_name, filename=None, local_use=sel_obj, use_thread=False) + elif sel_obj.kind == 'excellon': + sel_obj.source_file = self.app.export_excellon( + obj_name=out_name, filename=None, local_use=sel_obj, use_thread=False) except Exception as e: log.debug('[ERROR_NOTCL] %s --> %s' % ('ToolMove.on_left_click()', str(e))) return "fail" From dab46ef3aef9acf442e96046ca8f3bbf072891c9 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 19 Feb 2020 22:09:32 +0200 Subject: [PATCH 110/209] - in FlatCAMObj.export_gerber() method took into account the possibility of polygons of type 'clear' (the ones found in the Gerber files under the LPC command) --- FlatCAMObj.py | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 1 + 2 files changed, 58 insertions(+) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 8073b9da..6d8f640a 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -2233,6 +2233,63 @@ class FlatCAMGerber(FlatCAMObj, Gerber): x_formatted, y_formatted = lz_format(geo.x, geo.y, factor) gerber_code += "X{xform}Y{yform}D03*\n".format(xform=x_formatted, yform=y_formatted) + elif isinstance(geo, Polygon): + geo_coords = list(geo.exterior.coords) + # first command is a move with pen-up D02 at the beginning of the geo + if g_zeros == 'T': + x_formatted, y_formatted = tz_format( + geo_coords[0][0], geo_coords[0][1], factor) + gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted, + yform=y_formatted) + else: + x_formatted, y_formatted = lz_format( + geo_coords[0][0], geo_coords[0][1], factor) + gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted, + yform=y_formatted) + + prev_coord = geo_coords[0] + for coord in geo_coords[1:]: + if coord != prev_coord: + if g_zeros == 'T': + x_formatted, y_formatted = tz_format(coord[0], coord[1], factor) + gerber_code += "X{xform}Y{yform}D01*\n".format(xform=x_formatted, + yform=y_formatted) + else: + x_formatted, y_formatted = lz_format(coord[0], coord[1], factor) + gerber_code += "X{xform}Y{yform}D01*\n".format(xform=x_formatted, + yform=y_formatted) + + prev_coord = coord + + for geo_int in geo.interiors: + geo_coords = list(geo_int.coords) + # first command is a move with pen-up D02 at the beginning of the geo + if g_zeros == 'T': + x_formatted, y_formatted = tz_format( + geo_coords[0][0], geo_coords[0][1], factor) + gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted, + yform=y_formatted) + else: + x_formatted, y_formatted = lz_format( + geo_coords[0][0], geo_coords[0][1], factor) + gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted, + yform=y_formatted) + + prev_coord = geo_coords[0] + for coord in geo_coords[1:]: + if coord != prev_coord: + if g_zeros == 'T': + x_formatted, y_formatted = tz_format(coord[0], coord[1], factor) + gerber_code += "X{xform}Y{yform}D01*\n".format( + xform=x_formatted, + yform=y_formatted) + else: + x_formatted, y_formatted = lz_format(coord[0], coord[1], factor) + gerber_code += "X{xform}Y{yform}D01*\n".format( + xform=x_formatted, + yform=y_formatted) + + prev_coord = coord else: geo_coords = list(geo.coords) # first command is a move with pen-up D02 at the beginning of the geo diff --git a/README.md b/README.md index c4358a4f..128613cd 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ CAD program, and create G-Code for Isolation routing. - fixed some issues in the Geometry Editor; the jump sigmal disconnect was failing for repeated Editor tool operation - fixed an issue in Gerber Editor where the multiprocessing pool was reported as closed and an ValueError exception was raised in a certain scneraio - on Set Origin, Move to Origin and Move actions for Gerber and Excellon objects the source file will be also updated (the export functions will export an updated object) +- in FlatCAMObj.export_gerber() method took into account the possibility of polygons of type 'clear' (the ones found in the Gerber files under the LPC command) 17.02.2020 From a2c0244e1884f51b056451543d3ba9c44ff5e954 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 20 Feb 2020 05:14:48 +0200 Subject: [PATCH 111/209] - in Paint Tool replaced the Selection radio with a combobox GUI element that is more compact --- FlatCAMApp.py | 2 +- README.md | 6 +++- flatcamGUI/PreferencesUI.py | 23 ++++++++------ flatcamTools/ToolPaint.py | 60 ++++++++++++++++++++----------------- 4 files changed, 53 insertions(+), 38 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index e06a211e..6c3b07b3 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -807,7 +807,7 @@ class App(QtCore.QObject): "tools_paintoverlap": 20, "tools_paintmargin": 0.0, "tools_paintmethod": _("Seed"), - "tools_selectmethod": "all", + "tools_selectmethod": _("All Polygons"), "tools_pathconnect": True, "tools_paintcontour": True, "tools_paint_plotting": 'normal', diff --git a/README.md b/README.md index 128613cd..1dd45c89 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,13 @@ CAD program, and create G-Code for Isolation routing. ================================================= +20.02.2020 + +- in Paint Tool replaced the Selection radio with a combobox GUI element that is more compact + 19.02.2020 -- fixed some issues in the Geometry Editor; the jump sigmal disconnect was failing for repeated Editor tool operation +- fixed some issues in the Geometry Editor; the jump signal disconnect was failing for repeated Editor tool operation - fixed an issue in Gerber Editor where the multiprocessing pool was reported as closed and an ValueError exception was raised in a certain scneraio - on Set Origin, Move to Origin and Move actions for Gerber and Excellon objects the source file will be also updated (the export functions will export an updated object) - in FlatCAMObj.export_gerber() method took into account the possibility of polygons of type 'clear' (the ones found in the Gerber files under the LPC command) diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index 7f8f9ec6..44de467e 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -5877,16 +5877,21 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI): "- 'Reference Object' - will do non copper clearing within the area\n" "specified by another object.") ) - self.selectmethod_combo = RadioSet( - [ - {"label": _("Polygon Selection"), "value": "single"}, - {"label": _("Area Selection"), "value": "area"}, - {"label": _("All Polygons"), "value": "all"}, - {"label": _("Reference Object"), "value": "ref"} - ], - orientation='vertical', - stretch=None + # self.selectmethod_combo = RadioSet( + # [ + # {"label": _("Polygon Selection"), "value": "single"}, + # {"label": _("Area Selection"), "value": "area"}, + # {"label": _("All Polygons"), "value": "all"}, + # {"label": _("Reference Object"), "value": "ref"} + # ], + # orientation='vertical', + # stretch=None + # ) + self.selectmethod_combo = FCComboBox() + self.selectmethod_combo.addItems( + [_("Polygon Selection"), _("Area Selection"), _("All Polygons"), _("Reference Object")] ) + grid0.addWidget(selectlabel, 15, 0) grid0.addWidget(self.selectmethod_combo, 15, 1) diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 21eaf8a0..2e633d1e 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -463,25 +463,31 @@ class ToolPaint(FlatCAMTool, Gerber): ) # grid3 = QtWidgets.QGridLayout() - self.selectmethod_combo = RadioSet([ - {"label": _("Polygon Selection"), "value": "single"}, - {"label": _("Area Selection"), "value": "area"}, - {"label": _("All Polygons"), "value": "all"}, - {"label": _("Reference Object"), "value": "ref"} - ], orientation='vertical', stretch=False) - self.selectmethod_combo.setObjectName('p_selection') - self.selectmethod_combo.setToolTip( - _("How to select Polygons to be painted.\n" - "- 'Polygon Selection' - left mouse click to add/remove polygons to be painted.\n" - "- 'Area Selection' - left mouse click to start selection of the area to be painted.\n" - "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple areas.\n" - "- 'All Polygons' - the Paint will start after click.\n" - "- 'Reference Object' - will do non copper clearing within the area\n" - "specified by another object.") - ) + # self.selectmethod_combo = RadioSet([ + # {"label": _("Polygon Selection"), "value": "single"}, + # {"label": _("Area Selection"), "value": "area"}, + # {"label": _("All Polygons"), "value": "all"}, + # {"label": _("Reference Object"), "value": "ref"} + # ], orientation='vertical', stretch=False) + # self.selectmethod_combo.setObjectName('p_selection') + # self.selectmethod_combo.setToolTip( + # _("How to select Polygons to be painted.\n" + # "- 'Polygon Selection' - left mouse click to add/remove polygons to be painted.\n" + # "- 'Area Selection' - left mouse click to start selection of the area to be painted.\n" + # "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple areas.\n" + # "- 'All Polygons' - the Paint will start after click.\n" + # "- 'Reference Object' - will do non copper clearing within the area\n" + # "specified by another object.") + # ) - grid4.addWidget(selectlabel, 18, 0, 1, 2) - grid4.addWidget(self.selectmethod_combo, 19, 0, 1, 2) + self.selectmethod_combo = FCComboBox() + self.selectmethod_combo.addItems( + [_("Polygon Selection"), _("Area Selection"), _("All Polygons"), _("Reference Object")] + ) + self.selectmethod_combo.setObjectName('p_selection') + + grid4.addWidget(selectlabel, 18, 0) + grid4.addWidget(self.selectmethod_combo, 18, 1) form1 = QtWidgets.QFormLayout() grid4.addLayout(form1, 20, 0, 1, 2) @@ -624,7 +630,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.tools_table.clicked.connect(self.on_row_selection_change) self.generate_paint_button.clicked.connect(self.on_paint_button_click) - self.selectmethod_combo.activated_custom.connect(self.on_radio_selection) + self.selectmethod_combo.currentIndexChanged.connect(self.on_selection) self.order_radio.activated_custom[str].connect(self.on_order_changed) self.rest_cb.stateChanged.connect(self.on_rest_machining_check) @@ -881,8 +887,8 @@ class ToolPaint(FlatCAMTool, Gerber): else: return float(self.addtool_entry.get_value()) - def on_radio_selection(self): - if self.selectmethod_combo.get_value() == "ref": + def on_selection(self): + if self.selectmethod_combo.get_value() == _("Reference Object"): self.box_combo.show() self.box_combo_label.show() self.box_combo_type.show() @@ -893,11 +899,11 @@ class ToolPaint(FlatCAMTool, Gerber): self.box_combo_type.hide() self.box_combo_type_label.hide() - if self.selectmethod_combo.get_value() == 'single': + if self.selectmethod_combo.get_value() == _("Polygon Selection"): # disable rest-machining for single polygon painting self.rest_cb.set_value(False) self.rest_cb.setDisabled(True) - if self.selectmethod_combo.get_value() == 'area': + if self.selectmethod_combo.get_value() == _("Area Selection"): # disable rest-machining for single polygon painting self.rest_cb.set_value(False) self.rest_cb.setDisabled(True) @@ -1362,7 +1368,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.app.inform.emit('[ERROR_NOTCL] %s' % _("No selected tools in Tool Table.")) return - if self.select_method == "all": + if self.select_method == _("All Polygons"): self.paint_poly_all(self.paint_obj, tooldia=self.tooldia_list, outname=self.o_name, @@ -1370,7 +1376,7 @@ class ToolPaint(FlatCAMTool, Gerber): connect=self.connect, contour=self.contour) - elif self.select_method == "single": + elif self.select_method == _("Polygon Selection"): self.app.inform.emit('[WARNING_NOTCL] %s' % _("Click on a polygon to paint it.")) # disengage the grid snapping since it may be hard to click on polygons with grid snapping on @@ -1389,7 +1395,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.app.plotcanvas.graph_event_disconnect(self.app.mr) self.app.plotcanvas.graph_event_disconnect(self.app.mp) - elif self.select_method == "area": + elif self.select_method == _("Area Selection"): self.app.inform.emit('[WARNING_NOTCL] %s' % _("Click the start point of the paint area.")) if self.app.is_legacy is False: @@ -1403,7 +1409,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.mr = self.app.plotcanvas.graph_event_connect('mouse_release', self.on_mouse_release) self.mm = self.app.plotcanvas.graph_event_connect('mouse_move', self.on_mouse_move) - elif self.select_method == 'ref': + elif self.select_method == _("Reference Object"): self.bound_obj_name = self.box_combo.currentText() # Get source object. try: From b6663ddd43814801201bed9224f84186cf620de7 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 20 Feb 2020 06:14:17 +0200 Subject: [PATCH 112/209] - in NCC Tool modified the UI --- FlatCAMApp.py | 1 + README.md | 1 + flatcamTools/ToolNonCopperClear.py | 276 +++++++++++++++++------------ 3 files changed, 167 insertions(+), 111 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 6c3b07b3..b242074c 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -773,6 +773,7 @@ class App(QtCore.QObject): # NCC Tool "tools_ncctools": "1.0, 0.5", "tools_nccorder": 'rev', + "tools_nccoperation": 'clear', "tools_nccoverlap": 40, "tools_nccmargin": 1.0, "tools_nccmethod": "seed", diff --git a/README.md b/README.md index 1dd45c89..ece4cbd9 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 20.02.2020 - in Paint Tool replaced the Selection radio with a combobox GUI element that is more compact +- in NCC Tool modified the UI 19.02.2020 diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNonCopperClear.py index d07b9b63..d497c81b 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/flatcamTools/ToolNonCopperClear.py @@ -124,8 +124,8 @@ class NonCopperClear(FlatCAMTool, Gerber): self.tools_table = FCTable() self.tools_box.addWidget(self.tools_table) - self.tools_table.setColumnCount(5) - self.tools_table.setHorizontalHeaderLabels(['#', _('Diameter'), _('TT'), '', _("Operation")]) + self.tools_table.setColumnCount(4) + self.tools_table.setHorizontalHeaderLabels(['#', _('Diameter'), _('TT'), '']) self.tools_table.setColumnHidden(3, True) self.tools_table.setSortingEnabled(False) # self.tools_table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) @@ -155,37 +155,17 @@ class NonCopperClear(FlatCAMTool, Gerber): "Choosing the 'V-Shape' Tool Type automatically will select the Operation Type\n" "in the resulting geometry as Isolation.")) - self.tools_table.horizontalHeaderItem(4).setToolTip( - _("The 'Operation' can be:\n" - "- Isolation -> will ensure that the non-copper clearing is always complete.\n" - "If it's not successful then the non-copper clearing will fail, too.\n" - "- Clear -> the regular non-copper clearing.")) + # self.tools_table.horizontalHeaderItem(4).setToolTip( + # _("The 'Operation' can be:\n" + # "- Isolation -> will ensure that the non-copper clearing is always complete.\n" + # "If it's not successful then the non-copper clearing will fail, too.\n" + # "- Clear -> the regular non-copper clearing.")) grid1 = QtWidgets.QGridLayout() self.tools_box.addLayout(grid1) grid1.setColumnStretch(0, 0) grid1.setColumnStretch(1, 1) - # Milling Type Radio Button - self.milling_type_label = QtWidgets.QLabel('%s:' % _('Milling Type')) - self.milling_type_label.setToolTip( - _("Milling type when the selected tool is of type: 'iso_op':\n" - "- climb / best for precision milling and to reduce tool usage\n" - "- conventional / useful when there is no backlash compensation") - ) - - self.milling_type_radio = RadioSet([{'label': _('Climb'), 'value': 'cl'}, - {'label': _('Conventional'), 'value': 'cv'}]) - self.milling_type_radio.setToolTip( - _("Milling type when the selected tool is of type: 'iso_op':\n" - "- climb / best for precision milling and to reduce tool usage\n" - "- conventional / useful when there is no backlash compensation") - ) - self.milling_type_radio.setObjectName(_("Milling Type")) - - grid1.addWidget(self.milling_type_label, 0, 0) - grid1.addWidget(self.milling_type_radio, 0, 1) - # Tool order self.ncc_order_label = QtWidgets.QLabel('%s:' % _('Tool order')) self.ncc_order_label.setToolTip(_("This set the way that the tools in the tools table are used.\n" @@ -213,9 +193,6 @@ class NonCopperClear(FlatCAMTool, Gerber): separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) grid1.addWidget(separator_line, 2, 0, 1, 2) - self.milling_type_label.hide() - self.milling_type_radio.hide() - # ############################################################# # ############### Tool selection ############################## # ############################################################# @@ -356,6 +333,47 @@ class NonCopperClear(FlatCAMTool, Gerber): ) self.grid3.addWidget(self.tool_data_label, 12, 0, 1, 2) + # Operation + op_label = QtWidgets.QLabel('%s:' % _('Operation')) + op_label.setToolTip( + _("The 'Operation' can be:\n" + "- Isolation -> will ensure that the non-copper clearing is always complete.\n" + "If it's not successful then the non-copper clearing will fail, too.\n" + "- Clear -> the regular non-copper clearing.") + ) + + self.op_radio = RadioSet([ + {"label": _("Clear"), "value": "clear"}, + {"label": _("Isolation"), "value": "iso"} + ], orientation='horizontal', stretch=False) + self.op_radio.setObjectName("n_operation") + + self.grid3.addWidget(op_label, 13, 0) + self.grid3.addWidget(self.op_radio, 13, 1) + + # Milling Type Radio Button + self.milling_type_label = QtWidgets.QLabel('%s:' % _('Milling Type')) + self.milling_type_label.setToolTip( + _("Milling type when the selected tool is of type: 'iso_op':\n" + "- climb / best for precision milling and to reduce tool usage\n" + "- conventional / useful when there is no backlash compensation") + ) + + self.milling_type_radio = RadioSet([{'label': _('Climb'), 'value': 'cl'}, + {'label': _('Conventional'), 'value': 'cv'}]) + self.milling_type_radio.setToolTip( + _("Milling type when the selected tool is of type: 'iso_op':\n" + "- climb / best for precision milling and to reduce tool usage\n" + "- conventional / useful when there is no backlash compensation") + ) + self.milling_type_radio.setObjectName("n_milling_type") + + self.milling_type_label.setEnabled(False) + self.milling_type_radio.setEnabled(False) + + self.grid3.addWidget(self.milling_type_label, 14, 0) + self.grid3.addWidget(self.milling_type_radio, 14, 1) + # Overlap Entry nccoverlabel = QtWidgets.QLabel('%s:' % _('Overlap')) nccoverlabel.setToolTip( @@ -372,10 +390,10 @@ class NonCopperClear(FlatCAMTool, Gerber): self.ncc_overlap_entry.setWrapping(True) self.ncc_overlap_entry.setRange(0.000, 99.9999) self.ncc_overlap_entry.setSingleStep(0.1) - self.ncc_overlap_entry.setObjectName(_("Overlap")) + self.ncc_overlap_entry.setObjectName("n_overlap") - self.grid3.addWidget(nccoverlabel, 13, 0) - self.grid3.addWidget(self.ncc_overlap_entry, 13, 1) + self.grid3.addWidget(nccoverlabel, 15, 0) + self.grid3.addWidget(self.ncc_overlap_entry, 15, 1) # Margin nccmarginlabel = QtWidgets.QLabel('%s:' % _('Margin')) @@ -385,10 +403,10 @@ class NonCopperClear(FlatCAMTool, Gerber): self.ncc_margin_entry = FCDoubleSpinner(callback=self.confirmation_message) self.ncc_margin_entry.set_precision(self.decimals) self.ncc_margin_entry.set_range(-9999.9999, 9999.9999) - self.ncc_margin_entry.setObjectName(_("Margin")) + self.ncc_margin_entry.setObjectName("n_margin") - self.grid3.addWidget(nccmarginlabel, 14, 0) - self.grid3.addWidget(self.ncc_margin_entry, 14, 1) + self.grid3.addWidget(nccmarginlabel, 16, 0) + self.grid3.addWidget(self.ncc_margin_entry, 16, 1) # Method methodlabel = QtWidgets.QLabel('%s:' % _('Method')) @@ -403,34 +421,34 @@ class NonCopperClear(FlatCAMTool, Gerber): {"label": _("Seed-based"), "value": "seed"}, {"label": _("Straight lines"), "value": "lines"} ], orientation='vertical', stretch=False) - self.ncc_method_radio.setObjectName(_("Method")) + self.ncc_method_radio.setObjectName("n_method") - self.grid3.addWidget(methodlabel, 15, 0) - self.grid3.addWidget(self.ncc_method_radio, 15, 1) + self.grid3.addWidget(methodlabel, 17, 0) + self.grid3.addWidget(self.ncc_method_radio, 17, 1) # Connect lines self.ncc_connect_cb = FCCheckBox('%s' % _("Connect")) - self.ncc_connect_cb.setObjectName(_("Connect")) + self.ncc_connect_cb.setObjectName("n_connect") self.ncc_connect_cb.setToolTip( _("Draw lines between resulting\n" "segments to minimize tool lifts.") ) - self.grid3.addWidget(self.ncc_connect_cb, 16, 0) + self.grid3.addWidget(self.ncc_connect_cb, 18, 0) # Contour self.ncc_contour_cb = FCCheckBox('%s' % _("Contour")) - self.ncc_contour_cb.setObjectName(_("Contour")) + self.ncc_contour_cb.setObjectName("n_contour") self.ncc_contour_cb.setToolTip( _("Cut around the perimeter of the polygon\n" "to trim rough edges.") ) - self.grid3.addWidget(self.ncc_contour_cb, 16, 1) + self.grid3.addWidget(self.ncc_contour_cb, 18, 1) # ## NCC Offset choice self.ncc_choice_offset_cb = FCCheckBox('%s' % _("Offset")) - self.ncc_choice_offset_cb.setObjectName(_("Offset")) + self.ncc_choice_offset_cb.setObjectName("n_offset") self.ncc_choice_offset_cb.setToolTip( _("If used, it will add an offset to the copper features.\n" @@ -445,7 +463,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.ncc_offset_spinner.set_range(0.00, 10.00) self.ncc_offset_spinner.set_precision(4) self.ncc_offset_spinner.setWrapping(True) - self.ncc_offset_spinner.setObjectName(_("Offset value")) + self.ncc_offset_spinner.setObjectName("n_offset_value") units = self.app.defaults['units'].upper() if units == 'MM': @@ -483,7 +501,7 @@ class NonCopperClear(FlatCAMTool, Gerber): # Rest Machining self.ncc_rest_cb = FCCheckBox('%s' % _("Rest Machining")) - self.ncc_rest_cb.setObjectName(_("Rest Machining")) + self.ncc_rest_cb.setObjectName("n_rest_machining") self.ncc_rest_cb.setToolTip( _("If checked, use 'rest machining'.\n" @@ -503,7 +521,7 @@ class NonCopperClear(FlatCAMTool, Gerber): {"label": _("Area Selection"), "value": "area"}, {'label': _("Reference Object"), 'value': 'box'} ], orientation='vertical', stretch=False) - self.reference_radio.setObjectName(_("Reference")) + self.reference_radio.setObjectName("n_reference") self.reference_label = QtWidgets.QLabel('%s:' % _("Reference")) self.reference_label.setToolTip( @@ -638,6 +656,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.tooldia = None self.form_fields = { + "nccoperation":self.op_radio, "nccoverlap": self.ncc_overlap_entry, "nccmargin": self.ncc_margin_entry, "nccmethod": self.ncc_method_radio, @@ -649,14 +668,15 @@ class NonCopperClear(FlatCAMTool, Gerber): } self.name2option = { - _('Overlap'): "nccoverlap", - _('Margin'): "nccmargin", - _('Method'): "nccmethod", - _("Connect"): "nccconnect", - _("Contour"): "ncccontour", - _("Offset"): "nccoffset", - _("Offset value"): "nccoffset_value", - _('Milling Type'): "milling_type", + "n_operation": "nccoperation", + "n_overlap": "nccoverlap", + "n_margin": "nccmargin", + "n_method": "nccmethod", + "n_connect": "nccconnect", + "n_contour": "ncccontour", + "n_offset": "nccoffset", + "n_offset_value": "nccoffset_value", + "n_milling_type": "milling_type", } self.old_tool_dia = None @@ -673,6 +693,8 @@ class NonCopperClear(FlatCAMTool, Gerber): self.tipangle_entry.returnPressed.connect(self.on_calculate_tooldia) self.cutz_entry.returnPressed.connect(self.on_calculate_tooldia) + self.op_radio.activated_custom.connect(self.on_operation_change) + self.box_combo_type.currentIndexChanged.connect(self.on_combo_box_type) self.reference_radio.group_toggle_fn = self.on_toggle_reference @@ -690,6 +712,21 @@ class NonCopperClear(FlatCAMTool, Gerber): self.object_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) self.object_combo.setCurrentIndex(0) + def on_operation_change(self, val): + if val == 'iso': + self.milling_type_label.setEnabled(True) + self.milling_type_radio.setEnabled(True) + else: + self.milling_type_label.setEnabled(False) + self.milling_type_radio.setEnabled(False) + + current_row = self.tools_table.currentRow() + try: + current_uid = int(self.tools_table.item(current_row, 3).text()) + self.ncc_tools[current_uid]['data']['nccoperation'] = val + except AttributeError: + return + def on_row_selection_change(self): self.blockSignals(True) @@ -740,7 +777,8 @@ class NonCopperClear(FlatCAMTool, Gerber): if form_key == storage_key: try: self.form_fields[form_key].set_value(dict_storage[form_key]) - except Exception: + except Exception as e: + log.debug("NonCopperClear.storage_to_form() --> %s" % str(e)) pass def form_to_storage(self): @@ -783,6 +821,20 @@ class NonCopperClear(FlatCAMTool, Gerber): if row < 0: row = 0 + tooluid_item = int(self.tools_table.item(row, 3).text()) + temp_tool_data = dict() + + for tooluid_key, tooluid_val in self.ncc_tools.items(): + if int(tooluid_key) == tooluid_item: + # this will hold the 'data' key of the self.tools[tool] dictionary that corresponds to + # the current row in the tool table + temp_tool_data = tooluid_val['data'] + break + + for tooluid_key, tooluid_val in self.ncc_tools.items(): + tooluid_val['data'] = deepcopy(temp_tool_data) + + # store all the data associated with the row parameter to the self.tools storage tooldia_item = float(self.tools_table.item(row, 1).text()) type_item = self.tools_table.cellWidget(row, 2).currentText() @@ -792,35 +844,35 @@ class NonCopperClear(FlatCAMTool, Gerber): nccoffset_value_item = float(self.ncc_offset_spinner.get_value()) # this new dict will hold the actual useful data, another dict that is the value of key 'data' - temp_tools = {} - temp_dia = {} - temp_data = {} - - for tooluid_key, tooluid_value in self.ncc_tools.items(): - for key, value in tooluid_value.items(): - if key == 'data': - # update the 'data' section - for data_key in tooluid_value[key].keys(): - for form_key, form_value in self.form_fields.items(): - if form_key == data_key: - temp_data[data_key] = form_value.get_value() - # make sure we make a copy of the keys not in the form (we may use 'data' keys that are - # updated from self.app.defaults - if data_key not in self.form_fields: - temp_data[data_key] = value[data_key] - temp_dia[key] = deepcopy(temp_data) - temp_data.clear() - - elif key == 'solid_geometry': - temp_dia[key] = deepcopy(self.tools[tooluid_key]['solid_geometry']) - else: - temp_dia[key] = deepcopy(value) - - temp_tools[tooluid_key] = deepcopy(temp_dia) - - self.ncc_tools.clear() - self.ncc_tools = deepcopy(temp_tools) - temp_tools.clear() + # temp_tools = {} + # temp_dia = {} + # temp_data = {} + # + # for tooluid_key, tooluid_value in self.ncc_tools.items(): + # for key, value in tooluid_value.items(): + # if key == 'data': + # # update the 'data' section + # for data_key in tooluid_value[key].keys(): + # for form_key, form_value in self.form_fields.items(): + # if form_key == data_key: + # temp_data[data_key] = form_value.get_value() + # # make sure we make a copy of the keys not in the form (we may use 'data' keys that are + # # updated from self.app.defaults + # if data_key not in self.form_fields: + # temp_data[data_key] = value[data_key] + # temp_dia[key] = deepcopy(temp_data) + # temp_data.clear() + # + # elif key == 'solid_geometry': + # temp_dia[key] = deepcopy(self.tools[tooluid_key]['solid_geometry']) + # else: + # temp_dia[key] = deepcopy(value) + # + # temp_tools[tooluid_key] = deepcopy(temp_dia) + # + # self.ncc_tools.clear() + # self.ncc_tools = deepcopy(temp_tools) + # temp_tools.clear() self.app.inform.emit('[success] %s' % _("Current Tool parameters were applied to all tools.")) @@ -887,6 +939,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.type_obj_combo.set_value('gerber') + self.op_radio.set_value(self.app.defaults["tools_nccoperation"]) self.ncc_order_radio.set_value(self.app.defaults["tools_nccorder"]) self.ncc_overlap_entry.set_value(self.app.defaults["tools_nccoverlap"]) self.ncc_margin_entry.set_value(self.app.defaults["tools_nccmargin"]) @@ -935,6 +988,7 @@ class NonCopperClear(FlatCAMTool, Gerber): "toolchangexy": self.app.defaults["geometry_toolchangexy"], "startz": self.app.defaults["geometry_startz"], + "nccoperation": self.app.defaults["tools_nccoperation"], "nccmargin": self.app.defaults["tools_nccmargin"], "nccmethod": self.app.defaults["tools_nccmethod"], "nccconnect": self.app.defaults["tools_nccconnect"], @@ -968,7 +1022,6 @@ class NonCopperClear(FlatCAMTool, Gerber): 'offset_value': 0.0, 'type': 'Iso', 'tool_type': self.tool_type_radio.get_value(), - 'operation': 'clear_op', 'data': deepcopy(self.default_data), 'solid_geometry': [] } @@ -1032,13 +1085,12 @@ class NonCopperClear(FlatCAMTool, Gerber): tool_uid_item = QtWidgets.QTableWidgetItem(str(int(tooluid_key))) - operation_type = FCComboBox() - operation_type.addItem('iso_op') - # operation_type.setStyleSheet('background-color: rgb(255,255,255)') - operation_type.addItem('clear_op') - # operation_type.setStyleSheet('background-color: rgb(255,255,255)') - op_idx = operation_type.findText(tooluid_value['operation']) - operation_type.setCurrentIndex(op_idx) + # operation_type = FCComboBox() + # operation_type.addItems(['iso_op', 'clear_op']) + # + # # operation_type.setStyleSheet('background-color: rgb(255,255,255)') + # op_idx = operation_type.findText(tooluid_value['operation']) + # operation_type.setCurrentIndex(op_idx) self.tools_table.setItem(row_no, 1, dia) # Diameter self.tools_table.setCellWidget(row_no, 2, tool_type_item) @@ -1046,7 +1098,7 @@ class NonCopperClear(FlatCAMTool, Gerber): # ## REMEMBER: THIS COLUMN IS HIDDEN IN OBJECTUI.PY # ## self.tools_table.setItem(row_no, 3, tool_uid_item) # Tool unique ID - self.tools_table.setCellWidget(row_no, 4, operation_type) + # self.tools_table.setCellWidget(row_no, 4, operation_type) # make the diameter column editable for row in range(tool_id): @@ -1237,19 +1289,19 @@ class NonCopperClear(FlatCAMTool, Gerber): 'tool_type': tt, }) - if cw_col == 4: - op = cw.currentText() - - if op == 'iso_op': - self.milling_type_label.show() - self.milling_type_radio.show() - else: - self.milling_type_label.hide() - self.milling_type_radio.hide() - - self.ncc_tools[current_uid].update({ - 'operation': op - }) + # if cw_col == 4: + # op = cw.currentText() + # + # if op == 'iso_op': + # self.milling_type_label.show() + # self.milling_type_radio.show() + # else: + # self.milling_type_label.hide() + # self.milling_type_radio.hide() + # + # self.ncc_tools[current_uid].update({ + # 'operation': op + # }) def on_tool_type(self, val): if val == 'V': @@ -1350,7 +1402,6 @@ class NonCopperClear(FlatCAMTool, Gerber): 'offset_value': 0.0, 'type': 'Iso', 'tool_type': self.tool_type_radio.get_value(), - 'operation': 'clear_op', 'data': deepcopy(self.default_data), 'solid_geometry': [] } @@ -2022,9 +2073,12 @@ class NonCopperClear(FlatCAMTool, Gerber): else: sorted_tools = ncctooldia else: - for row in range(self.tools_table.rowCount()): - if self.tools_table.cellWidget(row, 1).currentText() == 'clear_op': - sorted_tools.append(float(self.tools_table.item(row, 1).text())) + # for row in range(self.tools_table.rowCount()): + # if self.tools_table.cellWidget(row, 1).currentText() == 'clear_op': + # sorted_tools.append(float(self.tools_table.item(row, 1).text())) + for tooluid in self.ncc_tools: + if self.ncc_tools[tooluid]['data']['nccoperation'] == 'clear': + sorted_tools.append(self.ncc_tools[tooluid]['tooldia']) # ######################################################################################################## # set the name for the future Geometry object From 522b98fef330aa621271c277835165dea5e27ca0 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Tue, 25 Feb 2020 21:22:51 +0200 Subject: [PATCH 113/209] - fixed bug in Gerber parser: it tried to calculate a len() for a single element and not a list - a Gerber generated by Eagle exhibited this --- README.md | 4 ++ flatcamParsers/ParseGerber.py | 93 +++++++++++++++++++++++++++++------ 2 files changed, 83 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index ece4cbd9..96d1605c 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +25.02.2020 + +- fixed bug in Gerber parser: it tried to calculate a len() for a single element and not a list - a Gerber generated by Eagle exhibited this + 20.02.2020 - in Paint Tool replaced the Selection radio with a combobox GUI element that is more compact diff --git a/flatcamParsers/ParseGerber.py b/flatcamParsers/ParseGerber.py index 235521b4..bfa36a4b 100644 --- a/flatcamParsers/ParseGerber.py +++ b/flatcamParsers/ParseGerber.py @@ -456,7 +456,12 @@ class Gerber(Geometry): new_polarity = match.group(1) # log.info("Polarity CHANGE, LPC = %s, poly_buff = %s" % (self.is_lpc, poly_buffer)) self.is_lpc = True if new_polarity == 'C' else False - if len(path) > 1 and current_polarity != new_polarity: + try: + path_length = len(path) + except TypeError: + path_length = 1 + + if path_length > 1 and current_polarity != new_polarity: # finish the current path and add it to the storage # --- Buffered ---- @@ -491,7 +496,12 @@ class Gerber(Geometry): # --- Apply buffer --- # If added for testing of bug #83 # TODO: Remove when bug fixed - if len(poly_buffer) > 0: + try: + buff_length = len(poly_buffer) + except TypeError: + buff_length = 1 + + if buff_length > 0: if current_polarity == 'D': self.solid_geometry = self.solid_geometry.union(cascaded_union(poly_buffer)) @@ -714,7 +724,12 @@ class Gerber(Geometry): # log.debug(self.apertures[current_aperture]) # Take care of the current path with the previous tool - if len(path) > 1: + try: + path_length = len(path) + except TypeError: + path_length = 1 + + if path_length > 1: if self.apertures[last_path_aperture]["type"] == 'R': # do nothing because 'R' type moving aperture is none at once pass @@ -751,7 +766,12 @@ class Gerber(Geometry): # ################ G36* - Begin region ######################## # ################################################################ if self.regionon_re.search(gline): - if len(path) > 1: + try: + path_length = len(path) + except TypeError: + path_length = 1 + + if path_length > 1: # Take care of what is left in the path geo_dict = dict() @@ -799,7 +819,12 @@ class Gerber(Geometry): # if D02 happened before G37 we now have a path with 1 element only; we have to add the current # geo to the poly_buffer otherwise we loose it if current_operation_code == 2: - if len(path) == 1: + try: + path_length = len(path) + except TypeError: + path_length = 1 + + if path_length == 1: # this means that the geometry was prepared previously and we just need to add it geo_dict = dict() if geo_f: @@ -825,7 +850,12 @@ class Gerber(Geometry): # Only one path defines region? # This can happen if D02 happened before G37 and # is not and error. - if len(path) < 3: + try: + path_length = len(path) + except TypeError: + path_length = 1 + + if path_length < 3: # print "ERROR: Path contains less than 3 points:" # path = [[current_x, current_y]] continue @@ -974,7 +1004,12 @@ class Gerber(Geometry): _("GERBER file might be CORRUPT. Check the file !!!")) elif current_operation_code == 2: - if len(path) > 1: + try: + path_length = len(path) + except TypeError: + path_length = 1 + + if path_length > 1: geo_s = None geo_dict = dict() @@ -1073,7 +1108,12 @@ class Gerber(Geometry): elif current_operation_code == 3: # Create path draw so far. - if len(path) > 1: + try: + path_length = len(path) + except TypeError: + path_length = 1 + + if path_length > 1: # --- Buffered ---- geo_dict = dict() @@ -1229,7 +1269,12 @@ class Gerber(Geometry): # Nothing created! Pen Up. if current_operation_code == 2: log.warning("Arc with D2. (%d)" % line_num) - if len(path) > 1: + try: + path_length = len(path) + except TypeError: + path_length = 1 + + if path_length > 1: geo_dict = dict() if last_path_aperture is None: @@ -1372,7 +1417,12 @@ class Gerber(Geometry): # ################################################################ log.warning("Line ignored (%d): %s" % (line_num, gline)) - if len(path) > 1: + try: + path_length = len(path) + except TypeError: + path_length = 1 + + if path_length > 1: # In case that G01 (moving) aperture is rectangular, there is no need to still create # another geo since we already created a shapely box using the start and end coordinates found in # path variable. We do it only for other apertures than 'R' type @@ -1415,15 +1465,25 @@ class Gerber(Geometry): # this treats the case when we are storing geometry as solids try: - if len(poly_buffer) == 0 and len(self.solid_geometry) == 0: + buff_length = len(poly_buffer) + except TypeError: + buff_length = 1 + + try: + sol_geo_length = len(self.solid_geometry) + except TypeError: + sol_geo_length = 1 + + try: + if buff_length == 0 and sol_geo_length == 0: log.error("Object is not Gerber file or empty. Aborting Object creation.") return 'fail' except TypeError as e: log.error("Object is not Gerber file or empty. Aborting Object creation. %s" % str(e)) return 'fail' - log.warning("Joining %d polygons." % len(poly_buffer)) - self.app.inform.emit('%s: %d.' % (_("Gerber processing. Joining polygons"), len(poly_buffer))) + log.warning("Joining %d polygons." % buff_length) + self.app.inform.emit('%s: %d.' % (_("Gerber processing. Joining polygons"), buff_length)) if self.use_buffer_for_union: log.debug("Union by buffer...") @@ -1729,7 +1789,12 @@ class Gerber(Geometry): if type(geos) == list: # HACK for importing QRCODE exported by FlatCAM - if len(geos) == 1: + try: + geos_length = len(geos) + except TypeError: + geos_length = 1 + + if geos_length == 1: geo_qrcode = list() geo_qrcode.append(Polygon(geos[0].exterior)) for i_el in geos[0].interiors: From 8a6ada1984cc4821a20e51e319257c88d018a354 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 26 Feb 2020 04:43:54 +0200 Subject: [PATCH 114/209] - added a new parameter named 'End Move X,Y' for the Geometry and Excellon objects. Adding a tuple of coordinates in this field will control the X,Y position of the final move; not entering a value there will cause not to make an end move --- FlatCAMApp.py | 26 ++++++- FlatCAMObj.py | 18 ++++- README.md | 1 + camlib.py | 27 ++++++- flatcamEditors/FlatCAMExcEditor.py | 1 + flatcamGUI/GUIElements.py | 2 + flatcamGUI/ObjectUI.py | 42 ++++++++--- flatcamGUI/PreferencesUI.py | 70 +++++++++++++------ flatcamParsers/ParseHPGL2.py | 2 + flatcamTools/ToolNonCopperClear.py | 2 + flatcamTools/ToolPaint.py | 2 + preprocessors/Berta_CNC.py | 4 +- preprocessors/GRBL_laser.py | 4 +- preprocessors/ISEL_CNC.py | 4 +- preprocessors/Marlin.py | 4 +- preprocessors/Marlin_laser_use_FAN_pin.py | 4 +- preprocessors/Marlin_laser_use_Spindle_pin.py | 4 +- preprocessors/Paste_1.py | 4 +- preprocessors/Repetier.py | 4 +- preprocessors/Toolchange_Custom.py | 4 +- preprocessors/Toolchange_Probe_MACH3.py | 4 +- preprocessors/Toolchange_manual.py | 7 +- preprocessors/default.py | 6 +- preprocessors/grbl_11.py | 4 +- preprocessors/line_xyz.py | 4 +- tclCommands/TclCommandCopperClear.py | 1 + tclCommands/TclCommandPaint.py | 2 + 27 files changed, 189 insertions(+), 68 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index b242074c..a9d4cbca 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -643,6 +643,7 @@ class App(QtCore.QObject): "excellon_depthperpass": 0.7, "excellon_travelz": 2, "excellon_endz": 0.5, + "excellon_endxy": None, "excellon_feedrate_z": 300, "excellon_spindlespeed": 0, "excellon_dwell": False, @@ -710,6 +711,8 @@ class App(QtCore.QObject): "geometry_toolchange": False, "geometry_toolchangez": 15.0, "geometry_endz": 15.0, + "geometry_endxy": None, + "geometry_feedrate": 120, "geometry_feedrate_z": 60, "geometry_spindlespeed": 0, @@ -1326,6 +1329,8 @@ class App(QtCore.QObject): "excellon_depthperpass": self.ui.excellon_defaults_form.excellon_opt_group.maxdepth_entry, "excellon_travelz": self.ui.excellon_defaults_form.excellon_opt_group.travelz_entry, "excellon_endz": self.ui.excellon_defaults_form.excellon_opt_group.endz_entry, + "excellon_endxy": self.ui.excellon_defaults_form.excellon_opt_group.endxy_entry, + "excellon_feedrate_z": self.ui.excellon_defaults_form.excellon_opt_group.feedrate_z_entry, "excellon_spindlespeed": self.ui.excellon_defaults_form.excellon_opt_group.spindlespeed_entry, "excellon_dwell": self.ui.excellon_defaults_form.excellon_opt_group.dwell_cb, @@ -1404,6 +1409,7 @@ class App(QtCore.QObject): "geometry_toolchange": self.ui.geometry_defaults_form.geometry_opt_group.toolchange_cb, "geometry_toolchangez": self.ui.geometry_defaults_form.geometry_opt_group.toolchangez_entry, "geometry_endz": self.ui.geometry_defaults_form.geometry_opt_group.endz_entry, + "geometry_endxy": self.ui.geometry_defaults_form.geometry_opt_group.endxy_entry, "geometry_depthperpass": self.ui.geometry_defaults_form.geometry_opt_group.depthperpass_entry, "geometry_multidepth": self.ui.geometry_defaults_form.geometry_opt_group.multidepth_cb, @@ -5959,13 +5965,15 @@ class App(QtCore.QObject): 'excellon_cutz', 'excellon_travelz', "excellon_toolchangexy", 'excellon_offset', 'excellon_feedrate', 'excellon_feedrate_rapid', 'excellon_toolchangez', - 'excellon_tooldia', 'excellon_slot_tooldia', 'excellon_endz', "excellon_feedrate_probe", + 'excellon_tooldia', 'excellon_slot_tooldia', 'excellon_endz', 'excellon_endxy', + "excellon_feedrate_probe", "excellon_z_pdepth", "excellon_editor_newdia", "excellon_editor_lin_pitch", "excellon_editor_slot_lin_pitch", 'geometry_cutz', "geometry_depthperpass", 'geometry_travelz', 'geometry_feedrate', 'geometry_feedrate_rapid', "geometry_toolchangez", "geometry_feedrate_z", - "geometry_toolchangexy", 'geometry_cnctooldia', 'geometry_endz', "geometry_z_pdepth", + "geometry_toolchangexy", 'geometry_cnctooldia', 'geometry_endz', 'geometry_endxy', + "geometry_z_pdepth", "geometry_feedrate_probe", "geometry_startz", 'cncjob_tooldia', @@ -6013,6 +6021,20 @@ class App(QtCore.QObject): coords_xy[1] *= sfactor self.defaults['geometry_toolchangexy'] = "%.*f, %.*f" % (self.decimals, coords_xy[0], self.decimals, coords_xy[1]) + elif dim == 'excellon_endxy': + coordinates = self.defaults["excellon_endxy"].split(",") + end_coords_xy = [float(eval(a)) for a in coordinates if a != ''] + end_coords_xy[0] *= sfactor + end_coords_xy[1] *= sfactor + self.defaults['excellon_endxy'] = "%.*f, %.*f" % (self.decimals, end_coords_xy[0], + self.decimals, end_coords_xy[1]) + elif dim == 'geometry_endxy': + coordinates = self.defaults["geometry_endxy"].split(",") + end_coords_xy = [float(eval(a)) for a in coordinates if a != ''] + end_coords_xy[0] *= sfactor + end_coords_xy[1] *= sfactor + self.defaults['geometry_endxy'] = "%.*f, %.*f" % (self.decimals, end_coords_xy[0], + self.decimals, end_coords_xy[1]) elif dim == 'geometry_cnctooldia': if type(self.defaults["geometry_cnctooldia"]) == float: tools_diameters = [self.defaults["geometry_cnctooldia"]] diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 6d8f640a..7734e4b5 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -2401,6 +2401,8 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): "extracut": self.app.defaults["geometry_extracut"], "extracut_length":self.app.defaults["geometry_extracut_length"], "endz": 2.0, + "endxy": '', + "startz": None, "offset": 0.0, "spindlespeed": 0, @@ -2887,6 +2889,8 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): "startz": self.ui.estartz_entry, "endz": self.ui.endz_entry, + "endxy": self.ui.endxy_entry, + "offset": self.ui.offset_entry, "ppname_e": self.ui.pp_excellon_name_cb, @@ -3744,6 +3748,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): job_obj.z_toolchange = float(self.options["toolchangez"]) job_obj.startz = float(self.options["startz"]) if self.options["startz"] else None job_obj.endz = float(self.options["endz"]) + job_obj.xy_end = self.options["endxy"] job_obj.excellon_optimization_type = self.app.defaults["excellon_optimization_type"] tools_csv = ','.join(tools) @@ -3987,6 +3992,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): "extracut": False, "extracut_length": 0.1, "endz": 2.0, + "endxy": '', + "startz": None, "toolchange": False, "toolchangez": 1.0, @@ -4259,6 +4266,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): "toolchange": self.ui.toolchangeg_cb, "toolchangez": self.ui.toolchangez_entry, "endz": self.ui.endz_entry, + "endxy": self.ui.endxy_entry, "cnctooldia": self.ui.addtool_entry }) @@ -4298,6 +4306,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): "toolchange": None, "toolchangez": None, "endz": None, + "endxy": '', "spindlespeed": 0, "toolchangexy": None, "startz": None @@ -5645,6 +5654,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): toolchangexy = tools_dict[tooluid_key]['data']["toolchangexy"] startz = tools_dict[tooluid_key]['data']["startz"] endz = tools_dict[tooluid_key]['data']["endz"] + endxy = self.options["endxy"] spindlespeed = tools_dict[tooluid_key]['data']["spindlespeed"] dwell = tools_dict[tooluid_key]['data']["dwell"] dwelltime = tools_dict[tooluid_key]['data']["dwelltime"] @@ -5670,7 +5680,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): feedrate=feedrate, feedrate_z=feedrate_z, feedrate_rapid=feedrate_rapid, spindlespeed=spindlespeed, spindledir=spindledir, dwell=dwell, dwelltime=dwelltime, multidepth=multidepth, depthpercut=depthpercut, - extracut=extracut, extracut_length=extracut_length, startz=startz, endz=endz, + extracut=extracut, extracut_length=extracut_length, startz=startz, endz=endz, endxy=endxy, toolchange=toolchange, toolchangez=toolchangez, toolchangexy=toolchangexy, pp_geometry_name=pp_geometry_name, tool_no=tool_cnt) @@ -5797,6 +5807,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): toolchangexy = tools_dict[tooluid_key]['data']["toolchangexy"] startz = tools_dict[tooluid_key]['data']["startz"] endz = tools_dict[tooluid_key]['data']["endz"] + endxy = self.options["endxy"] spindlespeed = tools_dict[tooluid_key]['data']["spindlespeed"] dwell = tools_dict[tooluid_key]['data']["dwell"] dwelltime = tools_dict[tooluid_key]['data']["dwelltime"] @@ -5822,7 +5833,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): feedrate=feedrate, feedrate_z=feedrate_z, feedrate_rapid=feedrate_rapid, spindlespeed=spindlespeed, spindledir=spindledir, dwell=dwell, dwelltime=dwelltime, multidepth=multidepth, depthpercut=depthpercut, - extracut=extracut, extracut_length=extracut_length, startz=startz, endz=endz, + extracut=extracut, extracut_length=extracut_length, startz=startz, endz=endz, endxy=endxy, toolchange=toolchange, toolchangez=toolchangez, toolchangexy=toolchangexy, pp_geometry_name=pp_geometry_name, tool_no=tool_cnt) @@ -5932,6 +5943,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): startz = startz if startz is not None else self.options["startz"] endz = endz if endz is not None else float(self.options["endz"]) + endxy = self.options["endxy"] toolchangez = toolchangez if toolchangez else float(self.options["toolchangez"]) toolchangexy = toolchangexy if toolchangexy else self.options["toolchangexy"] @@ -5981,7 +5993,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): spindlespeed=spindlespeed, dwell=dwell, dwelltime=dwelltime, multidepth=multidepth, depthpercut=depthperpass, toolchange=toolchange, toolchangez=toolchangez, toolchangexy=toolchangexy, - extracut=extracut, extracut_length=extracut_length, startz=startz, endz=endz, + extracut=extracut, extracut_length=extracut_length, startz=startz, endz=endz, endxy=endxy, pp_geometry_name=ppname_g ) diff --git a/README.md b/README.md index 96d1605c..3c172ff0 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 25.02.2020 - fixed bug in Gerber parser: it tried to calculate a len() for a single element and not a list - a Gerber generated by Eagle exhibited this +- added a new parameter named 'End Move X,Y' for the Geometry and Excellon objects. Adding a tuple of coordinates in this field will control the X,Y position of the final move; not entering a value there will cause not to make an end move 20.02.2020 diff --git a/camlib.py b/camlib.py index bb402eb8..b56d65f5 100644 --- a/camlib.py +++ b/camlib.py @@ -2415,7 +2415,7 @@ class CNCjob(Geometry): depthpercut=0.1, z_pdepth=-0.02, spindlespeed=None, spindledir='CW', dwell=True, dwelltime=1000, toolchangez=0.787402, toolchange_xy=[0.0, 0.0], - endz=2.0, + endz=2.0, endxy='', segx=None, segy=None, steps_per_circle=None): @@ -2447,6 +2447,7 @@ class CNCjob(Geometry): self.startz = None self.z_end = endz + self.xy_end = endxy self.multidepth = False self.z_depthpercut = depthpercut @@ -2656,6 +2657,12 @@ class CNCjob(Geometry): log.debug("camlib.CNCJob.generate_from_excellon_by_tool() --> %s" % str(e)) pass + self.xy_end = [float(eval(a)) for a in self.xy_end.split(",")] + if len(self.xy_end) < 2: + self.app.inform.emit('[ERROR] %s' % _("The End Move X,Y field in Edit -> Preferences has to be " + "in the format (x, y) but now there is only one value, not two.")) + return 'fail' + self.pp_excellon = self.app.preprocessors[self.pp_excellon_name] p = self.pp_excellon @@ -3438,7 +3445,7 @@ class CNCjob(Geometry): spindlespeed=None, spindledir='CW', dwell=False, dwelltime=1.0, multidepth=False, depthpercut=None, toolchange=False, toolchangez=1.0, toolchangexy="0.0, 0.0", extracut=False, extracut_length=0.2, - startz=None, endz=2.0, pp_geometry_name=None, tool_no=1): + startz=None, endz=2.0, endxy='', pp_geometry_name=None, tool_no=1): """ Algorithm to generate from multitool Geometry. @@ -3472,6 +3479,7 @@ class CNCjob(Geometry): :param extracut_length: Extra cut legth at the end of the path :param startz: :param endz: + :param endxy: :param pp_geometry_name: :param tool_no: :return: GCode - string @@ -3511,6 +3519,12 @@ class CNCjob(Geometry): self.startz = float(startz) if startz is not None else None self.z_end = float(endz) if endz is not None else None + self.xy_end = [float(eval(a)) for a in endxy.split(",")] + if len(self.xy_end) < 2: + self.app.inform.emit('[ERROR] %s' % _("The End Move X,Y field in Edit -> Preferences has to be " + "in the format (x, y) but now there is only one value, not two.")) + return 'fail' + self.z_depthpercut = float(depthpercut) if depthpercut else None self.multidepth = multidepth @@ -3747,7 +3761,7 @@ class CNCjob(Geometry): spindlespeed=None, spindledir='CW', dwell=False, dwelltime=None, multidepth=False, depthpercut=None, toolchange=False, toolchangez=None, toolchangexy="0.0, 0.0", - extracut=False, extracut_length=None, startz=None, endz=None, + extracut=False, extracut_length=None, startz=None, endz=None, endxy='', pp_geometry_name=None, tool_no=1): """ Second algorithm to generate from Geometry. @@ -3872,6 +3886,13 @@ class CNCjob(Geometry): self.startz = float(startz) if startz is not None else self.app.defaults["geometry_startz"] self.z_end = float(endz) if endz is not None else self.app.defaults["geometry_endz"] + self.xy_end = endxy if endxy != '' else self.app.defaults["geometry_endxy"] + self.xy_end = [float(eval(a)) for a in self.xy_end.split(",")] + if len(self.xy_end) < 2: + self.app.inform.emit('[ERROR] %s' % _("The End Move X,Y field in Edit -> Preferences has to be " + "in the format (x, y) but now there is only one value, not two.")) + return 'fail' + self.z_depthpercut = float(depthpercut) if depthpercut is not None else 0.0 self.multidepth = multidepth self.z_toolchange = float(toolchangez) if toolchangez is not None else self.app.defaults["geometry_toolchangez"] diff --git a/flatcamEditors/FlatCAMExcEditor.py b/flatcamEditors/FlatCAMExcEditor.py index 5897b9cb..1be311ba 100644 --- a/flatcamEditors/FlatCAMExcEditor.py +++ b/flatcamEditors/FlatCAMExcEditor.py @@ -2209,6 +2209,7 @@ class FlatCAMExcEditor(QtCore.QObject): "extracut": self.app.defaults["geometry_extracut"], "extracut_length": self.app.defaults["geometry_extracut_length"], "endz": self.app.defaults["excellon_endz"], + "endxy": self.app.defaults["excellon_endxy"], "startz": self.app.defaults["excellon_startz"], "offset": self.app.defaults["excellon_offset"], "spindlespeed": self.app.defaults["excellon_spindlespeed"], diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index d53575d2..fd144564 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -444,6 +444,8 @@ class FCEntry(QtWidgets.QLineEdit): decimal_digits = decimals if decimals is not None else self.decimals if type(val) is float: self.setText('%.*f' % (decimal_digits, val)) + elif val is None: + self.setText('') else: self.setText(str(val)) diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index c4204765..e819f4a3 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -1220,6 +1220,18 @@ class ExcellonObjectUI(ObjectUI): self.grid5.addWidget(self.endz_label, 11, 0) self.grid5.addWidget(self.endz_entry, 11, 1) + # End Move X,Y + endmove_xy_label = QtWidgets.QLabel('%s:' % _('End move X,Y')) + endmove_xy_label.setToolTip( + _("End move X,Y position.\n" + "If no value is entered then there is no move\n" + "on X,Y plane at the end of the job.") + ) + self.endxy_entry = FCEntry() + + self.grid5.addWidget(endmove_xy_label, 12, 0) + self.grid5.addWidget(self.endxy_entry, 12, 1) + # Probe depth self.pdepth_label = QtWidgets.QLabel('%s:' % _("Probe Z depth")) self.pdepth_label.setToolTip( @@ -1232,8 +1244,8 @@ class ExcellonObjectUI(ObjectUI): self.pdepth_entry.set_range(-9999.9999, 9999.9999) self.pdepth_entry.setSingleStep(0.1) - self.grid5.addWidget(self.pdepth_label, 12, 0) - self.grid5.addWidget(self.pdepth_entry, 12, 1) + self.grid5.addWidget(self.pdepth_label, 13, 0) + self.grid5.addWidget(self.pdepth_entry, 13, 1) self.pdepth_label.hide() self.pdepth_entry.setVisible(False) @@ -1250,8 +1262,8 @@ class ExcellonObjectUI(ObjectUI): self.feedrate_probe_entry.setSingleStep(0.1) self.feedrate_probe_entry.setObjectName(_("e_fr_probe")) - self.grid5.addWidget(self.feedrate_probe_label, 13, 0) - self.grid5.addWidget(self.feedrate_probe_entry, 13, 1) + self.grid5.addWidget(self.feedrate_probe_label, 14, 0) + self.grid5.addWidget(self.feedrate_probe_entry, 14, 1) self.feedrate_probe_label.hide() self.feedrate_probe_entry.setVisible(False) @@ -1265,8 +1277,8 @@ class ExcellonObjectUI(ObjectUI): self.pp_excellon_name_cb = FCComboBox() self.pp_excellon_name_cb.setFocusPolicy(QtCore.Qt.StrongFocus) - self.grid5.addWidget(pp_excellon_label, 14, 0) - self.grid5.addWidget(self.pp_excellon_name_cb, 14, 1) + self.grid5.addWidget(pp_excellon_label, 15, 0) + self.grid5.addWidget(self.pp_excellon_name_cb, 15, 1) # Preprocessor Geometry selection pp_geo_label = QtWidgets.QLabel('%s:' % _("Preprocessor G")) @@ -1277,13 +1289,13 @@ class ExcellonObjectUI(ObjectUI): self.pp_geo_name_cb = FCComboBox() self.pp_geo_name_cb.setFocusPolicy(QtCore.Qt.StrongFocus) - self.grid5.addWidget(pp_geo_label, 15, 0) - self.grid5.addWidget(self.pp_geo_name_cb, 15, 1) + self.grid5.addWidget(pp_geo_label, 16, 0) + self.grid5.addWidget(self.pp_geo_name_cb, 16, 1) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - self.grid5.addWidget(separator_line, 16, 0, 1, 2) + self.grid5.addWidget(separator_line, 17, 0, 1, 2) # ################################################################# # ################# GRID LAYOUT 6 ############################### @@ -1974,6 +1986,18 @@ class GeometryObjectUI(ObjectUI): self.grid4.addWidget(self.endz_label, 9, 0) self.grid4.addWidget(self.endz_entry, 9, 1) + # End Move X,Y + endmove_xy_label = QtWidgets.QLabel('%s:' % _('End move X,Y')) + endmove_xy_label.setToolTip( + _("End move X,Y position.\n" + "If no value is entered then there is no move\n" + "on X,Y plane at the end of the job.") + ) + self.endxy_entry = FCEntry() + + self.grid4.addWidget(endmove_xy_label, 10, 0) + self.grid4.addWidget(self.endxy_entry, 10, 1) + # preprocessor selection pp_label = QtWidgets.QLabel('%s:' % _("Preprocessor")) pp_label.setToolTip( diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index 44de467e..6c7781b7 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -3229,6 +3229,18 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): grid2.addWidget(endz_label, 8, 0) grid2.addWidget(self.endz_entry, 8, 1) + # End Move X,Y + endmove_xy_label = QtWidgets.QLabel('%s:' % _('End move X,Y')) + endmove_xy_label.setToolTip( + _("End move X,Y position.\n" + "If no value is entered then there is no move\n" + "on X,Y plane at the end of the job.") + ) + self.endxy_entry = FCEntry() + + grid2.addWidget(endmove_xy_label, 9, 0) + grid2.addWidget(self.endxy_entry, 9, 1) + # Feedrate Z frlabel = QtWidgets.QLabel('%s:' % _('Feedrate Z')) frlabel.setToolTip( @@ -3241,8 +3253,8 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): self.feedrate_z_entry.set_precision(self.decimals) self.feedrate_z_entry.set_range(0, 99999.9999) - grid2.addWidget(frlabel, 9, 0) - grid2.addWidget(self.feedrate_z_entry, 9, 1) + grid2.addWidget(frlabel, 10, 0) + grid2.addWidget(self.feedrate_z_entry, 10, 1) # Spindle speed spdlabel = QtWidgets.QLabel('%s:' % _('Spindle Speed')) @@ -3255,8 +3267,8 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): self.spindlespeed_entry.set_range(0, 1000000) self.spindlespeed_entry.set_step(100) - grid2.addWidget(spdlabel, 10, 0) - grid2.addWidget(self.spindlespeed_entry, 10, 1) + grid2.addWidget(spdlabel, 11, 0) + grid2.addWidget(self.spindlespeed_entry, 11, 1) # Dwell self.dwell_cb = FCCheckBox('%s' % _('Enable Dwell')) @@ -3265,7 +3277,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): "speed before cutting.") ) - grid2.addWidget(self.dwell_cb, 11, 0, 1, 2) + grid2.addWidget(self.dwell_cb, 12, 0, 1, 2) # Dwell Time dwelltime = QtWidgets.QLabel('%s:' % _('Duration')) @@ -3274,8 +3286,8 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): self.dwelltime_entry.set_precision(self.decimals) self.dwelltime_entry.set_range(0, 99999.9999) - grid2.addWidget(dwelltime, 12, 0) - grid2.addWidget(self.dwelltime_entry, 12, 1) + grid2.addWidget(dwelltime, 13, 0) + grid2.addWidget(self.dwelltime_entry, 13, 1) self.ois_dwell_exc = OptionalInputSection(self.dwell_cb, [self.dwelltime_entry]) @@ -3367,6 +3379,7 @@ class ExcellonAdvOptPrefGroupUI(OptionsGroupUI): grid1 = QtWidgets.QGridLayout() self.layout.addLayout(grid1) + # Offset Z offsetlabel = QtWidgets.QLabel('%s:' % _('Offset Z')) offsetlabel.setToolTip( _("Some drill bits (the larger ones) need to drill deeper\n" @@ -3379,21 +3392,25 @@ class ExcellonAdvOptPrefGroupUI(OptionsGroupUI): grid1.addWidget(offsetlabel, 0, 0) grid1.addWidget(self.offset_entry, 0, 1) + # ToolChange X,Y toolchange_xy_label = QtWidgets.QLabel('%s:' % _('Toolchange X,Y')) toolchange_xy_label.setToolTip( _("Toolchange X,Y position.") ) - grid1.addWidget(toolchange_xy_label, 1, 0) self.toolchangexy_entry = FCEntry() + + grid1.addWidget(toolchange_xy_label, 1, 0) grid1.addWidget(self.toolchangexy_entry, 1, 1) + # Start Z startzlabel = QtWidgets.QLabel('%s:' % _('Start Z')) startzlabel.setToolTip( _("Height of the tool just after start.\n" "Delete the value if you don't need this feature.") ) - grid1.addWidget(startzlabel, 2, 0) self.estartz_entry = FloatEntry() + + grid1.addWidget(startzlabel, 2, 0) grid1.addWidget(self.estartz_entry, 2, 1) # Feedrate Rapids @@ -4165,6 +4182,18 @@ class GeometryOptPrefGroupUI(OptionsGroupUI): grid1.addWidget(endz_label, 6, 0) grid1.addWidget(self.endz_entry, 6, 1) + # End Move X,Y + endmove_xy_label = QtWidgets.QLabel('%s:' % _('End move X,Y')) + endmove_xy_label.setToolTip( + _("End move X,Y position.\n" + "If no value is entered then there is no move\n" + "on X,Y plane at the end of the job.") + ) + self.endxy_entry = FCEntry() + + grid1.addWidget(endmove_xy_label, 7, 0) + grid1.addWidget(self.endxy_entry, 7, 1) + # Feedrate X-Y frlabel = QtWidgets.QLabel('%s:' % _('Feedrate X-Y')) frlabel.setToolTip( @@ -4177,8 +4206,8 @@ class GeometryOptPrefGroupUI(OptionsGroupUI): self.cncfeedrate_entry.setSingleStep(0.1) self.cncfeedrate_entry.setWrapping(True) - grid1.addWidget(frlabel, 7, 0) - grid1.addWidget(self.cncfeedrate_entry, 7, 1) + grid1.addWidget(frlabel, 8, 0) + grid1.addWidget(self.cncfeedrate_entry, 8, 1) # Feedrate Z (Plunge) frz_label = QtWidgets.QLabel('%s:' % _('Feedrate Z')) @@ -4193,8 +4222,8 @@ class GeometryOptPrefGroupUI(OptionsGroupUI): self.feedrate_z_entry.setSingleStep(0.1) self.feedrate_z_entry.setWrapping(True) - grid1.addWidget(frz_label, 8, 0) - grid1.addWidget(self.feedrate_z_entry, 8, 1) + grid1.addWidget(frz_label, 9, 0) + grid1.addWidget(self.feedrate_z_entry, 9, 1) # Spindle Speed spdlabel = QtWidgets.QLabel('%s:' % _('Spindle speed')) @@ -4205,12 +4234,12 @@ class GeometryOptPrefGroupUI(OptionsGroupUI): "this value is the power of laser." ) ) - grid1.addWidget(spdlabel, 9, 0) self.cncspindlespeed_entry = FCSpinner() self.cncspindlespeed_entry.set_range(0, 1000000) self.cncspindlespeed_entry.set_step(100) - grid1.addWidget(self.cncspindlespeed_entry, 9, 1) + grid1.addWidget(spdlabel, 10, 0) + grid1.addWidget(self.cncspindlespeed_entry, 10, 1) # Dwell self.dwell_cb = FCCheckBox(label='%s' % _('Enable Dwell')) @@ -4228,9 +4257,9 @@ class GeometryOptPrefGroupUI(OptionsGroupUI): self.dwelltime_entry.setSingleStep(0.1) self.dwelltime_entry.setWrapping(True) - grid1.addWidget(self.dwell_cb, 10, 0) - grid1.addWidget(dwelltime, 11, 0) - grid1.addWidget(self.dwelltime_entry, 11, 1) + grid1.addWidget(self.dwell_cb, 11, 0) + grid1.addWidget(dwelltime, 12, 0) + grid1.addWidget(self.dwelltime_entry, 12, 1) self.ois_dwell = OptionalInputSection(self.dwell_cb, [self.dwelltime_entry]) @@ -4240,10 +4269,11 @@ class GeometryOptPrefGroupUI(OptionsGroupUI): _("The Preprocessor file that dictates\n" "the Machine Code (like GCode, RML, HPGL) output.") ) - grid1.addWidget(pp_label, 12, 0) self.pp_geometry_name_cb = FCComboBox() self.pp_geometry_name_cb.setFocusPolicy(Qt.StrongFocus) - grid1.addWidget(self.pp_geometry_name_cb, 12, 1) + + grid1.addWidget(pp_label, 13, 0) + grid1.addWidget(self.pp_geometry_name_cb, 13, 1) self.layout.addStretch() diff --git a/flatcamParsers/ParseHPGL2.py b/flatcamParsers/ParseHPGL2.py index d2b96d48..546825c4 100644 --- a/flatcamParsers/ParseHPGL2.py +++ b/flatcamParsers/ParseHPGL2.py @@ -72,6 +72,8 @@ class HPGL2: "toolchange": self.app.defaults["geometry_toolchange"], "toolchangez": self.app.defaults["geometry_toolchangez"], "endz": self.app.defaults["geometry_endz"], + "endxy": self.app.defaults["geometry_endxy"], + "spindlespeed": self.app.defaults["geometry_spindlespeed"], "toolchangexy": self.app.defaults["geometry_toolchangexy"], "startz": self.app.defaults["geometry_startz"], diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNonCopperClear.py index d497c81b..45ea96e8 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/flatcamTools/ToolNonCopperClear.py @@ -984,6 +984,8 @@ class NonCopperClear(FlatCAMTool, Gerber): "toolchange": self.app.defaults["geometry_toolchange"], "toolchangez": self.app.defaults["geometry_toolchangez"], "endz": self.app.defaults["geometry_endz"], + "endxy": self.app.defaults["geometry_endxy"], + "spindlespeed": self.app.defaults["geometry_spindlespeed"], "toolchangexy": self.app.defaults["geometry_toolchangexy"], "startz": self.app.defaults["geometry_startz"], diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 2e633d1e..310a6208 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -961,6 +961,8 @@ class ToolPaint(FlatCAMTool, Gerber): "toolchange": self.app.defaults["geometry_toolchange"], "toolchangez": float(self.app.defaults["geometry_toolchangez"]), "endz": float(self.app.defaults["geometry_endz"]), + "endxy": self.app.defaults["geometry_endxy"], + "spindlespeed": self.app.defaults["geometry_spindlespeed"], "toolchangexy": self.app.defaults["geometry_toolchangexy"], "startz": self.app.defaults["geometry_startz"], diff --git a/preprocessors/Berta_CNC.py b/preprocessors/Berta_CNC.py index 18f84578..59ed4e20 100644 --- a/preprocessors/Berta_CNC.py +++ b/preprocessors/Berta_CNC.py @@ -227,10 +227,10 @@ M0""".format(z_toolchange=self.coordinate_format % (p.coords_decimals, z_toolcha return ('G01 ' + self.position_code(p)).format(**p) def end_code(self, p): - coords_xy = p['xy_toolchange'] + coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy is not None: + if coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" gcode += '(Berta)\n' diff --git a/preprocessors/GRBL_laser.py b/preprocessors/GRBL_laser.py index 6c7a7c34..c6ddb280 100644 --- a/preprocessors/GRBL_laser.py +++ b/preprocessors/GRBL_laser.py @@ -83,10 +83,10 @@ class GRBL_laser(FlatCAMPostProc): ' F' + str(self.feedrate_format % (p.fr_decimals, p.feedrate)) def end_code(self, p): - coords_xy = p['xy_toolchange'] + coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy is not None: + if coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" return gcode diff --git a/preprocessors/ISEL_CNC.py b/preprocessors/ISEL_CNC.py index e8225b8e..805cf35a 100644 --- a/preprocessors/ISEL_CNC.py +++ b/preprocessors/ISEL_CNC.py @@ -157,10 +157,10 @@ M01""".format(tool=int(p.tool), toolC=toolC_formatted) return ('G01 ' + self.position_code(p)).format(**p) def end_code(self, p): - coords_xy = p['xy_toolchange'] + coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy is not None: + if coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" return gcode diff --git a/preprocessors/Marlin.py b/preprocessors/Marlin.py index aaf9079d..2f46183f 100644 --- a/preprocessors/Marlin.py +++ b/preprocessors/Marlin.py @@ -215,10 +215,10 @@ G0 Z{z_toolchange} return ('G1 ' + self.position_code(p)).format(**p) + " " + self.inline_feedrate_code(p) def end_code(self, p): - coords_xy = p['xy_toolchange'] + coords_xy = p['xy_end'] gcode = ('G0 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + " " + self.feedrate_rapid_code(p) + "\n") - if coords_xy is not None: + if coords_xy != '': gcode += 'G0 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + " " + self.feedrate_rapid_code(p) + "\n" return gcode diff --git a/preprocessors/Marlin_laser_use_FAN_pin.py b/preprocessors/Marlin_laser_use_FAN_pin.py index 36d958a4..9e5f33a7 100644 --- a/preprocessors/Marlin_laser_use_FAN_pin.py +++ b/preprocessors/Marlin_laser_use_FAN_pin.py @@ -85,10 +85,10 @@ class Marlin_laser_use_FAN_pin(FlatCAMPostProc): return ('G1 ' + self.position_code(p)).format(**p) + " " + self.inline_feedrate_code(p) def end_code(self, p): - coords_xy = p['xy_toolchange'] + coords_xy = p['xy_end'] gcode = ('G0 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + " " + self.feedrate_rapid_code(p) + "\n") - if coords_xy is not None: + if coords_xy != '': gcode += 'G0 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + " " + self.feedrate_rapid_code(p) + "\n" return gcode diff --git a/preprocessors/Marlin_laser_use_Spindle_pin.py b/preprocessors/Marlin_laser_use_Spindle_pin.py index a1f7fb1e..7f40bca4 100644 --- a/preprocessors/Marlin_laser_use_Spindle_pin.py +++ b/preprocessors/Marlin_laser_use_Spindle_pin.py @@ -86,10 +86,10 @@ class Marlin_laser_use_Spindle_pin(FlatCAMPostProc): return ('G1 ' + self.position_code(p)).format(**p) + " " + self.inline_feedrate_code(p) def end_code(self, p): - coords_xy = p['xy_toolchange'] + coords_xy = p['xy_end'] gcode = ('G0 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + " " + self.feedrate_rapid_code(p) + "\n") - if coords_xy is not None: + if coords_xy != '': gcode += 'G0 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + " " + self.feedrate_rapid_code(p) + "\n" return gcode diff --git a/preprocessors/Paste_1.py b/preprocessors/Paste_1.py index 87403017..b12d0f67 100644 --- a/preprocessors/Paste_1.py +++ b/preprocessors/Paste_1.py @@ -122,10 +122,10 @@ G00 Z{z_toolchange} return ('G01 ' + self.position_code(p)).format(**p) def end_code(self, p): - coords_xy = [float(eval(a)) for a in p['xy_toolchange'].split(",") if a != ''] + coords_xy = [float(eval(a)) for a in p['xy_end'].split(",") if a != ''] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, float(p['z_toolchange'])) + "\n") - if coords_xy is not None: + if coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" return gcode diff --git a/preprocessors/Repetier.py b/preprocessors/Repetier.py index ea15317e..4bdca261 100644 --- a/preprocessors/Repetier.py +++ b/preprocessors/Repetier.py @@ -206,10 +206,10 @@ G0 Z{z_toolchange} return ('G1 ' + self.position_code(p)).format(**p) + " " + self.inline_feedrate_code(p) def end_code(self, p): - coords_xy = p['xy_toolchange'] + coords_xy = p['xy_end'] gcode = ('G0 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + " " + self.feedrate_rapid_code(p) + "\n") - if coords_xy is not None: + if coords_xy != '': gcode += 'G0 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + " " + self.feedrate_rapid_code(p) + "\n" return gcode diff --git a/preprocessors/Toolchange_Custom.py b/preprocessors/Toolchange_Custom.py index 5c22b85a..39468d5d 100644 --- a/preprocessors/Toolchange_Custom.py +++ b/preprocessors/Toolchange_Custom.py @@ -173,10 +173,10 @@ M6 return ('G01 ' + self.position_code(p)).format(**p) def end_code(self, p): - coords_xy = p['xy_toolchange'] + coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy is not None: + if coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" return gcode diff --git a/preprocessors/Toolchange_Probe_MACH3.py b/preprocessors/Toolchange_Probe_MACH3.py index 3d4c95f8..1cfa0baa 100644 --- a/preprocessors/Toolchange_Probe_MACH3.py +++ b/preprocessors/Toolchange_Probe_MACH3.py @@ -272,10 +272,10 @@ M0 return ('G01 ' + self.position_code(p)).format(**p) def end_code(self, p): - coords_xy = p['xy_toolchange'] + coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy is not None: + if coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" return gcode diff --git a/preprocessors/Toolchange_manual.py b/preprocessors/Toolchange_manual.py index fceef14c..7b2eb561 100644 --- a/preprocessors/Toolchange_manual.py +++ b/preprocessors/Toolchange_manual.py @@ -235,12 +235,11 @@ M0 return ('G01 ' + self.position_code(p)).format(**p) def end_code(self, p): - coords_xy = p['xy_toolchange'] + coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy is not None: + + if coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" - else: - gcode += 'G00 X0 Y0' + "\n" return gcode def feedrate_code(self, p): diff --git a/preprocessors/default.py b/preprocessors/default.py index f46ff824..f7fadddc 100644 --- a/preprocessors/default.py +++ b/preprocessors/default.py @@ -217,11 +217,11 @@ G00 Z{z_toolchange} return ('G01 ' + self.position_code(p)).format(**p) def end_code(self, p): - coords_xy = p['xy_toolchange'] + end_coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy is not None: - gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" + if end_coords_xy != '': + gcode += 'G00 X{x} Y{y}'.format(x=end_coords_xy[0], y=end_coords_xy[1]) + "\n" return gcode def feedrate_code(self, p): diff --git a/preprocessors/grbl_11.py b/preprocessors/grbl_11.py index 0d4cf868..1bd28189 100644 --- a/preprocessors/grbl_11.py +++ b/preprocessors/grbl_11.py @@ -218,10 +218,10 @@ G00 Z{z_toolchange} ' F' + str(self.feedrate_format % (p.fr_decimals, p.feedrate)) def end_code(self, p): - coords_xy = p['xy_toolchange'] + coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy is not None: + if coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" return gcode diff --git a/preprocessors/line_xyz.py b/preprocessors/line_xyz.py index d7cebb7f..6187c1ae 100644 --- a/preprocessors/line_xyz.py +++ b/preprocessors/line_xyz.py @@ -206,8 +206,8 @@ M0""".format(x_toolchange=self.coordinate_format % (p.coords_decimals, x_toolcha return g def end_code(self, p): - coords_xy = p['xy_toolchange'] - if coords_xy is not None: + coords_xy = p['xy_end'] + if coords_xy != '': g = 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" else: g = ('G00 ' + self.position_code(p)).format(**p) diff --git a/tclCommands/TclCommandCopperClear.py b/tclCommands/TclCommandCopperClear.py index c57aa8a2..d6f58989 100644 --- a/tclCommands/TclCommandCopperClear.py +++ b/tclCommands/TclCommandCopperClear.py @@ -175,6 +175,7 @@ class TclCommandCopperClear(TclCommand): "toolchange": self.app.defaults["geometry_toolchange"], "toolchangez": self.app.defaults["geometry_toolchangez"], "endz": self.app.defaults["geometry_endz"], + "endxy": self.app.defaults["geometry_endxy"], "spindlespeed": self.app.defaults["geometry_spindlespeed"], "toolchangexy": self.app.defaults["geometry_toolchangexy"], "startz": self.app.defaults["geometry_startz"], diff --git a/tclCommands/TclCommandPaint.py b/tclCommands/TclCommandPaint.py index 2594904a..f44dcef2 100644 --- a/tclCommands/TclCommandPaint.py +++ b/tclCommands/TclCommandPaint.py @@ -164,6 +164,8 @@ class TclCommandPaint(TclCommand): "toolchange": self.app.defaults["geometry_toolchange"], "toolchangez": self.app.defaults["geometry_toolchangez"], "endz": self.app.defaults["geometry_endz"], + "endxy": self.app.defaults["geometry_endxy"], + "spindlespeed": self.app.defaults["geometry_spindlespeed"], "toolchangexy": self.app.defaults["geometry_toolchangexy"], "startz": self.app.defaults["geometry_startz"], From 84570bf6fe057c96ee581cf0d7f21b03f06cd18c Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 26 Feb 2020 05:00:23 +0200 Subject: [PATCH 115/209] - some tooltip changes --- flatcamGUI/ObjectUI.py | 4 ++-- flatcamGUI/PreferencesUI.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index e819f4a3..ca99e6c4 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -1223,7 +1223,7 @@ class ExcellonObjectUI(ObjectUI): # End Move X,Y endmove_xy_label = QtWidgets.QLabel('%s:' % _('End move X,Y')) endmove_xy_label.setToolTip( - _("End move X,Y position.\n" + _("End move X,Y position. In format (x,y).\n" "If no value is entered then there is no move\n" "on X,Y plane at the end of the job.") ) @@ -1989,7 +1989,7 @@ class GeometryObjectUI(ObjectUI): # End Move X,Y endmove_xy_label = QtWidgets.QLabel('%s:' % _('End move X,Y')) endmove_xy_label.setToolTip( - _("End move X,Y position.\n" + _("End move X,Y position. In format (x,y).\n" "If no value is entered then there is no move\n" "on X,Y plane at the end of the job.") ) diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index 6c7781b7..fdd29b3b 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -3232,7 +3232,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): # End Move X,Y endmove_xy_label = QtWidgets.QLabel('%s:' % _('End move X,Y')) endmove_xy_label.setToolTip( - _("End move X,Y position.\n" + _("End move X,Y position. In format (x,y).\n" "If no value is entered then there is no move\n" "on X,Y plane at the end of the job.") ) @@ -4185,7 +4185,7 @@ class GeometryOptPrefGroupUI(OptionsGroupUI): # End Move X,Y endmove_xy_label = QtWidgets.QLabel('%s:' % _('End move X,Y')) endmove_xy_label.setToolTip( - _("End move X,Y position.\n" + _("End move X,Y position. In format (x,y).\n" "If no value is entered then there is no move\n" "on X,Y plane at the end of the job.") ) From 69607816d0aea3341365f1159c675581d37c59ee Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 28 Feb 2020 01:12:39 +0200 Subject: [PATCH 116/209] - some small changes in preprocessors --- README.md | 4 ++++ ...{Marlin_laser_use_FAN_pin.py => Marlin_laser_FAN_pin.py} | 6 +++--- ...laser_use_Spindle_pin.py => Marlin_laser_Spindle_pin.py} | 2 +- .../{Toolchange_manual.py => Toolchange_Manual.py} | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) rename preprocessors/{Marlin_laser_use_FAN_pin.py => Marlin_laser_FAN_pin.py} (96%) rename preprocessors/{Marlin_laser_use_Spindle_pin.py => Marlin_laser_Spindle_pin.py} (98%) rename preprocessors/{Toolchange_manual.py => Toolchange_Manual.py} (99%) diff --git a/README.md b/README.md index 3c172ff0..df9ef53c 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +28.02.2020 + +- some small changes in preprocessors + 25.02.2020 - fixed bug in Gerber parser: it tried to calculate a len() for a single element and not a list - a Gerber generated by Eagle exhibited this diff --git a/preprocessors/Marlin_laser_use_FAN_pin.py b/preprocessors/Marlin_laser_FAN_pin.py similarity index 96% rename from preprocessors/Marlin_laser_use_FAN_pin.py rename to preprocessors/Marlin_laser_FAN_pin.py index 9e5f33a7..fb515d5f 100644 --- a/preprocessors/Marlin_laser_use_FAN_pin.py +++ b/preprocessors/Marlin_laser_FAN_pin.py @@ -9,7 +9,7 @@ from FlatCAMPostProc import * -class Marlin_laser_use_FAN_pin(FlatCAMPostProc): +class Marlin_laser_FAN_pin(FlatCAMPostProc): include_header = True coordinate_format = "%.*f" @@ -107,7 +107,7 @@ class Marlin_laser_use_FAN_pin(FlatCAMPostProc): def spindle_code(self, p): if p.spindlespeed: - return '%s S%s' % ('M106 ', str(p.spindlespeed)) + return 'M106 S%s' % str(p.spindlespeed) else: return 'M106' @@ -116,5 +116,5 @@ class Marlin_laser_use_FAN_pin(FlatCAMPostProc): def spindle_stop_code(self, p): gcode = 'M400\n' - gcode += 'M107' + gcode += 'M106 S0' return gcode diff --git a/preprocessors/Marlin_laser_use_Spindle_pin.py b/preprocessors/Marlin_laser_Spindle_pin.py similarity index 98% rename from preprocessors/Marlin_laser_use_Spindle_pin.py rename to preprocessors/Marlin_laser_Spindle_pin.py index 7f40bca4..370d0c33 100644 --- a/preprocessors/Marlin_laser_use_Spindle_pin.py +++ b/preprocessors/Marlin_laser_Spindle_pin.py @@ -9,7 +9,7 @@ from FlatCAMPostProc import * -class Marlin_laser_use_Spindle_pin(FlatCAMPostProc): +class Marlin_laser_Spindle_pin(FlatCAMPostProc): include_header = True coordinate_format = "%.*f" diff --git a/preprocessors/Toolchange_manual.py b/preprocessors/Toolchange_Manual.py similarity index 99% rename from preprocessors/Toolchange_manual.py rename to preprocessors/Toolchange_Manual.py index 7b2eb561..432a0013 100644 --- a/preprocessors/Toolchange_manual.py +++ b/preprocessors/Toolchange_Manual.py @@ -9,7 +9,7 @@ from FlatCAMPostProc import * -class Toolchange_manual(FlatCAMPostProc): +class Toolchange_Manual(FlatCAMPostProc): include_header = True coordinate_format = "%.*f" From c5e4d72db8689aaeb9c18bd9552c8ff32fc77000 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 28 Feb 2020 17:59:15 +0200 Subject: [PATCH 117/209] - solved issue #381 where there was an error when trying to generate CNCJob out of an Excellon file that have a tool with only slots and no drills - solved some issues in the preprocessors regarding the newly introduced feature that allow control of the final move X,Y positions --- README.md | 2 + camlib.py | 88 +++++++++++++++-------- preprocessors/Berta_CNC.py | 2 +- preprocessors/GRBL_laser.py | 2 +- preprocessors/ISEL_CNC.py | 2 +- preprocessors/Marlin.py | 2 +- preprocessors/Marlin_laser_FAN_pin.py | 2 +- preprocessors/Marlin_laser_Spindle_pin.py | 2 +- preprocessors/Paste_1.py | 2 +- preprocessors/Repetier.py | 2 +- preprocessors/Toolchange_Custom.py | 2 +- preprocessors/Toolchange_Manual.py | 2 +- preprocessors/Toolchange_Probe_MACH3.py | 2 +- preprocessors/default.py | 2 +- preprocessors/grbl_11.py | 2 +- preprocessors/line_xyz.py | 2 +- 16 files changed, 73 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index df9ef53c..b0e69180 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ CAD program, and create G-Code for Isolation routing. 28.02.2020 - some small changes in preprocessors +- solved issue #381 where there was an error when trying to generate CNCJob out of an Excellon file that have a tool with only slots and no drills +- solved some issues in the preprocessors regarding the newly introduced feature that allow control of the final move X,Y positions 25.02.2020 diff --git a/camlib.py b/camlib.py index b56d65f5..a1ca1375 100644 --- a/camlib.py +++ b/camlib.py @@ -2647,8 +2647,8 @@ class CNCjob(Geometry): if self.xy_toolchange == '': self.xy_toolchange = None else: - self.xy_toolchange = [float(eval(a)) for a in self.xy_toolchange.split(",")] - if len(self.xy_toolchange) < 2: + self.xy_toolchange = [float(eval(a)) for a in self.xy_toolchange.split(",") if self.xy_toolchange != ''] + if self.xy_toolchange and len(self.xy_toolchange) < 2: self.app.inform.emit('[ERROR]%s' % _("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. ")) @@ -2657,8 +2657,8 @@ class CNCjob(Geometry): log.debug("camlib.CNCJob.generate_from_excellon_by_tool() --> %s" % str(e)) pass - self.xy_end = [float(eval(a)) for a in self.xy_end.split(",")] - if len(self.xy_end) < 2: + self.xy_end = [float(eval(a)) for a in self.xy_end.split(",") if self.xy_end != ''] + if self.xy_end and len(self.xy_end) < 2: self.app.inform.emit('[ERROR] %s' % _("The End Move X,Y field in Edit -> Preferences has to be " "in the format (x, y) but now there is only one value, not two.")) return 'fail' @@ -2783,23 +2783,25 @@ class CNCjob(Geometry): class CreateDistanceCallback(object): """Create callback to calculate distances between points.""" - def __init__(self): + def __init__(self, tool): """Initialize distance array.""" - locations = create_data_array() - size = len(locations) + locations = create_data_array(tool) self.matrix = dict() - for from_node in range(size): - self.matrix[from_node] = {} - for to_node in range(size): - if from_node == to_node: - self.matrix[from_node][to_node] = 0 - else: - x1 = locations[from_node][0] - y1 = locations[from_node][1] - x2 = locations[to_node][0] - y2 = locations[to_node][1] - self.matrix[from_node][to_node] = distance_euclidian(x1, y1, x2, y2) + if locations: + size = len(locations) + + for from_node in range(size): + self.matrix[from_node] = {} + for to_node in range(size): + if from_node == to_node: + self.matrix[from_node][to_node] = 0 + else: + x1 = locations[from_node][0] + y1 = locations[from_node][1] + x2 = locations[to_node][0] + y2 = locations[to_node][1] + self.matrix[from_node][to_node] = distance_euclidian(x1, y1, x2, y2) # def Distance(self, from_node, to_node): # return int(self.matrix[from_node][to_node]) @@ -2810,11 +2812,15 @@ class CNCjob(Geometry): return self.matrix[from_node][to_node] # Create the data. - def create_data_array(): - locations = [] + def create_data_array(tool): + loc_list = list() + + if tool not in points: + return None + for point in points[tool]: - locations.append((point.coords.xy[0][0], point.coords.xy[1][0])) - return locations + loc_list.append((point.coords.xy[0][0], point.coords.xy[1][0])) + return loc_list if self.xy_toolchange is not None: self.oldx = self.xy_toolchange[0] @@ -2884,7 +2890,12 @@ class CNCjob(Geometry): # ############################################### node_list = [] - locations = create_data_array() + locations = create_data_array(tool=tool) + + # if there are no locations then go to the next tool + if not locations: + continue + tsp_size = len(locations) num_routes = 1 # The number of routes, which is 1 in the TSP. # Nodes are indexed from 0 to tsp_size - 1. The depot is the starting node of the route. @@ -2906,7 +2917,12 @@ class CNCjob(Geometry): # Callback to the distance function. The callback takes two # arguments (the from and to node indices) and returns the distance between them. - dist_between_locations = CreateDistanceCallback() + dist_between_locations = CreateDistanceCallback(tool=tool) + + # if there are no distances then go to the next tool + if not dist_between_locations: + continue + dist_callback = dist_between_locations.Distance transit_callback_index = routing.RegisterTransitCallback(dist_callback) routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index) @@ -3088,7 +3104,7 @@ class CNCjob(Geometry): old_zcut = deepcopy(self.z_cut) self.z_move = exobj.tools[tool]['data']['travelz'] - print(self.z_move) + self.spindlespeed = exobj.tools[tool]['data']['spindlespeed'] self.dwell = exobj.tools[tool]['data']['dwell'] self.dwelltime = exobj.tools[tool]['data']['dwelltime'] @@ -3100,7 +3116,12 @@ class CNCjob(Geometry): # ############################################### node_list = [] - locations = create_data_array() + locations = create_data_array(tool=tool) + + # if there are no locations then go to the next tool + if not locations: + continue + tsp_size = len(locations) num_routes = 1 # The number of routes, which is 1 in the TSP. @@ -3115,7 +3136,12 @@ class CNCjob(Geometry): # Callback to the distance function. The callback takes two # arguments (the from and to node indices) and returns the distance between them. - dist_between_locations = CreateDistanceCallback() + dist_between_locations = CreateDistanceCallback(tool=tool) + + # if there are no distances then go to the next tool + if not dist_between_locations: + continue + dist_callback = dist_between_locations.Distance transit_callback_index = routing.RegisterTransitCallback(dist_callback) routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index) @@ -3519,8 +3545,8 @@ class CNCjob(Geometry): self.startz = float(startz) if startz is not None else None self.z_end = float(endz) if endz is not None else None - self.xy_end = [float(eval(a)) for a in endxy.split(",")] - if len(self.xy_end) < 2: + self.xy_end = [float(eval(a)) for a in endxy.split(",") if endxy != ''] + if self.xy_end and len(self.xy_end) < 2: self.app.inform.emit('[ERROR] %s' % _("The End Move X,Y field in Edit -> Preferences has to be " "in the format (x, y) but now there is only one value, not two.")) return 'fail' @@ -3887,8 +3913,8 @@ class CNCjob(Geometry): self.startz = float(startz) if startz is not None else self.app.defaults["geometry_startz"] self.z_end = float(endz) if endz is not None else self.app.defaults["geometry_endz"] self.xy_end = endxy if endxy != '' else self.app.defaults["geometry_endxy"] - self.xy_end = [float(eval(a)) for a in self.xy_end.split(",")] - if len(self.xy_end) < 2: + self.xy_end = [float(eval(a)) for a in self.xy_end.split(",") if self.xy_end != ''] + if self.xy_end and len(self.xy_end) < 2: self.app.inform.emit('[ERROR] %s' % _("The End Move X,Y field in Edit -> Preferences has to be " "in the format (x, y) but now there is only one value, not two.")) return 'fail' diff --git a/preprocessors/Berta_CNC.py b/preprocessors/Berta_CNC.py index 59ed4e20..8239d0e9 100644 --- a/preprocessors/Berta_CNC.py +++ b/preprocessors/Berta_CNC.py @@ -230,7 +230,7 @@ M0""".format(z_toolchange=self.coordinate_format % (p.coords_decimals, z_toolcha coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy != '': + if coords_xy and coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" gcode += '(Berta)\n' diff --git a/preprocessors/GRBL_laser.py b/preprocessors/GRBL_laser.py index c6ddb280..9caf4f39 100644 --- a/preprocessors/GRBL_laser.py +++ b/preprocessors/GRBL_laser.py @@ -86,7 +86,7 @@ class GRBL_laser(FlatCAMPostProc): coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy != '': + if coords_xy and coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" return gcode diff --git a/preprocessors/ISEL_CNC.py b/preprocessors/ISEL_CNC.py index 805cf35a..8c7c9ed0 100644 --- a/preprocessors/ISEL_CNC.py +++ b/preprocessors/ISEL_CNC.py @@ -160,7 +160,7 @@ M01""".format(tool=int(p.tool), toolC=toolC_formatted) coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy != '': + if coords_xy and coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" return gcode diff --git a/preprocessors/Marlin.py b/preprocessors/Marlin.py index 2f46183f..d53a257f 100644 --- a/preprocessors/Marlin.py +++ b/preprocessors/Marlin.py @@ -218,7 +218,7 @@ G0 Z{z_toolchange} coords_xy = p['xy_end'] gcode = ('G0 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + " " + self.feedrate_rapid_code(p) + "\n") - if coords_xy != '': + if coords_xy and coords_xy != '': gcode += 'G0 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + " " + self.feedrate_rapid_code(p) + "\n" return gcode diff --git a/preprocessors/Marlin_laser_FAN_pin.py b/preprocessors/Marlin_laser_FAN_pin.py index fb515d5f..2d06d23d 100644 --- a/preprocessors/Marlin_laser_FAN_pin.py +++ b/preprocessors/Marlin_laser_FAN_pin.py @@ -88,7 +88,7 @@ class Marlin_laser_FAN_pin(FlatCAMPostProc): coords_xy = p['xy_end'] gcode = ('G0 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + " " + self.feedrate_rapid_code(p) + "\n") - if coords_xy != '': + if coords_xy and coords_xy != '': gcode += 'G0 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + " " + self.feedrate_rapid_code(p) + "\n" return gcode diff --git a/preprocessors/Marlin_laser_Spindle_pin.py b/preprocessors/Marlin_laser_Spindle_pin.py index 370d0c33..151e9dc4 100644 --- a/preprocessors/Marlin_laser_Spindle_pin.py +++ b/preprocessors/Marlin_laser_Spindle_pin.py @@ -89,7 +89,7 @@ class Marlin_laser_Spindle_pin(FlatCAMPostProc): coords_xy = p['xy_end'] gcode = ('G0 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + " " + self.feedrate_rapid_code(p) + "\n") - if coords_xy != '': + if coords_xy and coords_xy != '': gcode += 'G0 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + " " + self.feedrate_rapid_code(p) + "\n" return gcode diff --git a/preprocessors/Paste_1.py b/preprocessors/Paste_1.py index b12d0f67..cbb0b19f 100644 --- a/preprocessors/Paste_1.py +++ b/preprocessors/Paste_1.py @@ -125,7 +125,7 @@ G00 Z{z_toolchange} coords_xy = [float(eval(a)) for a in p['xy_end'].split(",") if a != ''] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, float(p['z_toolchange'])) + "\n") - if coords_xy != '': + if coords_xy and coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" return gcode diff --git a/preprocessors/Repetier.py b/preprocessors/Repetier.py index 4bdca261..bb17f9ee 100644 --- a/preprocessors/Repetier.py +++ b/preprocessors/Repetier.py @@ -209,7 +209,7 @@ G0 Z{z_toolchange} coords_xy = p['xy_end'] gcode = ('G0 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + " " + self.feedrate_rapid_code(p) + "\n") - if coords_xy != '': + if coords_xy and coords_xy != '': gcode += 'G0 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + " " + self.feedrate_rapid_code(p) + "\n" return gcode diff --git a/preprocessors/Toolchange_Custom.py b/preprocessors/Toolchange_Custom.py index 39468d5d..1c2eeffc 100644 --- a/preprocessors/Toolchange_Custom.py +++ b/preprocessors/Toolchange_Custom.py @@ -176,7 +176,7 @@ M6 coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy != '': + if coords_xy and coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" return gcode diff --git a/preprocessors/Toolchange_Manual.py b/preprocessors/Toolchange_Manual.py index 432a0013..27aaec22 100644 --- a/preprocessors/Toolchange_Manual.py +++ b/preprocessors/Toolchange_Manual.py @@ -238,7 +238,7 @@ M0 coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy != '': + if coords_xy and coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" return gcode diff --git a/preprocessors/Toolchange_Probe_MACH3.py b/preprocessors/Toolchange_Probe_MACH3.py index 1cfa0baa..f5f8c9c3 100644 --- a/preprocessors/Toolchange_Probe_MACH3.py +++ b/preprocessors/Toolchange_Probe_MACH3.py @@ -275,7 +275,7 @@ M0 coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy != '': + if coords_xy and coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" return gcode diff --git a/preprocessors/default.py b/preprocessors/default.py index f7fadddc..7c5cf1c6 100644 --- a/preprocessors/default.py +++ b/preprocessors/default.py @@ -220,7 +220,7 @@ G00 Z{z_toolchange} end_coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if end_coords_xy != '': + if end_coords_xy and end_coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=end_coords_xy[0], y=end_coords_xy[1]) + "\n" return gcode diff --git a/preprocessors/grbl_11.py b/preprocessors/grbl_11.py index 1bd28189..b002b2b2 100644 --- a/preprocessors/grbl_11.py +++ b/preprocessors/grbl_11.py @@ -221,7 +221,7 @@ G00 Z{z_toolchange} coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy != '': + if coords_xy and coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" return gcode diff --git a/preprocessors/line_xyz.py b/preprocessors/line_xyz.py index 6187c1ae..900d7fab 100644 --- a/preprocessors/line_xyz.py +++ b/preprocessors/line_xyz.py @@ -207,7 +207,7 @@ M0""".format(x_toolchange=self.coordinate_format % (p.coords_decimals, x_toolcha def end_code(self, p): coords_xy = p['xy_end'] - if coords_xy != '': + if coords_xy and coords_xy != '': g = 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" else: g = ('G00 ' + self.position_code(p)).format(**p) From 2c7dff5dbe9b01998df63204dccbdfa1cd97d965 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 29 Feb 2020 19:05:00 +0200 Subject: [PATCH 118/209] - compacted the NCC Tool UI by replacing some Radio buttons with Combo boxes due of too many elements --- FlatCAMApp.py | 8 +- README.md | 4 + flatcamEditors/FlatCAMGeoEditor.py | 43 +++---- flatcamGUI/PreferencesUI.py | 54 +++++---- .../{ToolNonCopperClear.py => ToolNCC.py} | 106 ++++++++++-------- flatcamTools/__init__.py | 2 +- 6 files changed, 119 insertions(+), 98 deletions(-) rename flatcamTools/{ToolNonCopperClear.py => ToolNCC.py} (98%) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index a9d4cbca..285e8315 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -779,13 +779,13 @@ class App(QtCore.QObject): "tools_nccoperation": 'clear', "tools_nccoverlap": 40, "tools_nccmargin": 1.0, - "tools_nccmethod": "seed", + "tools_nccmethod": _("Seed"), "tools_nccconnect": True, "tools_ncccontour": True, "tools_nccrest": False, "tools_ncc_offset_choice": False, "tools_ncc_offset_value": 0.0000, - "tools_nccref": 'itself', + "tools_nccref": _('Itself'), "tools_ncc_plotting": 'normal', "tools_nccmilling_type": 'cl', "tools_ncctool_type": 'C1', @@ -1461,13 +1461,13 @@ class App(QtCore.QObject): "tools_nccorder": self.ui.tools_defaults_form.tools_ncc_group.ncc_order_radio, "tools_nccoverlap": self.ui.tools_defaults_form.tools_ncc_group.ncc_overlap_entry, "tools_nccmargin": self.ui.tools_defaults_form.tools_ncc_group.ncc_margin_entry, - "tools_nccmethod": self.ui.tools_defaults_form.tools_ncc_group.ncc_method_radio, + "tools_nccmethod": self.ui.tools_defaults_form.tools_ncc_group.ncc_method_combo, "tools_nccconnect": self.ui.tools_defaults_form.tools_ncc_group.ncc_connect_cb, "tools_ncccontour": self.ui.tools_defaults_form.tools_ncc_group.ncc_contour_cb, "tools_nccrest": self.ui.tools_defaults_form.tools_ncc_group.ncc_rest_cb, "tools_ncc_offset_choice": self.ui.tools_defaults_form.tools_ncc_group.ncc_choice_offset_cb, "tools_ncc_offset_value": self.ui.tools_defaults_form.tools_ncc_group.ncc_offset_spinner, - "tools_nccref": self.ui.tools_defaults_form.tools_ncc_group.reference_radio, + "tools_nccref": self.ui.tools_defaults_form.tools_ncc_group.select_combo, "tools_ncc_plotting": self.ui.tools_defaults_form.tools_ncc_group.ncc_plotting_radio, "tools_nccmilling_type": self.ui.tools_defaults_form.tools_ncc_group.milling_type_radio, "tools_ncctool_type": self.ui.tools_defaults_form.tools_ncc_group.tool_type_radio, diff --git a/README.md b/README.md index b0e69180..28be59a2 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +29.02.2020 + +- compacted the NCC Tool UI by replacing some Radio buttons with Combo boxes due of too many elements + 28.02.2020 - some small changes in preprocessors diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index 26fb2615..17027775 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -487,15 +487,20 @@ class PaintOptionsTool(FlatCAMTool): # Method methodlabel = QtWidgets.QLabel('%s:' % _('Method')) methodlabel.setToolTip( - _("Algorithm to paint the polygon:
" - "Standard: Fixed step inwards.
" - "Seed-based: Outwards from seed.") + _("Algorithm to paint the polygons:\n" + "- Standard: Fixed step inwards.\n" + "- Seed-based: Outwards from seed.\n" + "- Line-based: Parallel lines.") + ) + # self.paintmethod_combo = RadioSet([ + # {"label": _("Standard"), "value": "standard"}, + # {"label": _("Seed-based"), "value": "seed"}, + # {"label": _("Straight lines"), "value": "lines"} + # ], orientation='vertical', stretch=False) + self.paintmethod_combo = FCComboBox() + self.paintmethod_combo.addItems( + [_("Standard"), _("Seed"), _("Lines")] ) - self.paintmethod_combo = RadioSet([ - {"label": _("Standard"), "value": "standard"}, - {"label": _("Seed-based"), "value": "seed"}, - {"label": _("Straight lines"), "value": "lines"} - ], orientation='vertical', stretch=False) grid.addWidget(methodlabel, 3, 0) grid.addWidget(self.paintmethod_combo, 3, 1) @@ -564,7 +569,7 @@ class PaintOptionsTool(FlatCAMTool): if self.app.defaults["tools_paintmethod"]: self.paintmethod_combo.set_value(self.app.defaults["tools_paintmethod"]) else: - self.paintmethod_combo.set_value("seed") + self.paintmethod_combo.set_value(_("Seed")) if self.app.defaults["tools_pathconnect"]: self.pathconnect_cb.set_value(self.app.defaults["tools_pathconnect"]) @@ -578,8 +583,7 @@ class PaintOptionsTool(FlatCAMTool): def on_paint(self): if not self.fcdraw.selected: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Paint cancelled. No shape selected.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Paint cancelled. No shape selected.")) return tooldia = self.painttooldia_entry.get_value() @@ -5037,11 +5041,11 @@ class FlatCAMGeoEditor(QtCore.QObject): else: poly_buf = Polygon(geo_obj).buffer(-margin) - if method == "seed": + if method == _("Seed"): cp = Geometry.clear_polygon2(self, polygon_to_clear=poly_buf, tooldia=tooldia, steps_per_circle=self.app.defaults["geometry_circle_steps"], overlap=overlap, contour=contour, connect=connect) - elif method == "lines": + elif method == _("Lines"): cp = Geometry.clear_polygon3(self, polygon=poly_buf, tooldia=tooldia, steps_per_circle=self.app.defaults["geometry_circle_steps"], overlap=overlap, contour=contour, connect=connect) @@ -5054,12 +5058,10 @@ class FlatCAMGeoEditor(QtCore.QObject): local_results += list(cp.get_objects()) except Exception as e: log.debug("Could not Paint the polygons. %s" % str(e)) - self.app.inform.emit('[ERROR] %s\n%s' % - (_("Could not do Paint. Try a different combination of" - " parameters. Or a different method of Paint"), - str(e) - ) - ) + self.app.inform.emit( + '[ERROR] %s\n%s' % (_("Could not do Paint. Try a different combination of parameters. " + "Or a different method of Paint"), str(e)) + ) return # add the result to the results list @@ -5068,8 +5070,7 @@ class FlatCAMGeoEditor(QtCore.QObject): # This is a dirty patch: for r in results: self.add_shape(DrawToolShape(r)) - self.app.inform.emit( - '[success] %s' % _("Paint done.")) + self.app.inform.emit('[success] %s' % _("Paint done.")) self.replot() def flatten(self, geometry, orient_val=1, reset=True, pathonly=False): diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index fdd29b3b..7d6767cd 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -5313,20 +5313,24 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): # Method methodlabel = QtWidgets.QLabel('%s:' % _('Method')) methodlabel.setToolTip( - _("Algorithm for non-copper clearing:
" - "Standard: Fixed step inwards.
" - "Seed-based: Outwards from seed.
" - "Line-based: Parallel lines.") + _("Algorithm for copper clearing:\n" + "- Standard: Fixed step inwards.\n" + "- Seed-based: Outwards from seed.\n" + "- Line-based: Parallel lines.") ) - self.ncc_method_radio = RadioSet([ - {"label": _("Standard"), "value": "standard"}, - {"label": _("Seed-based"), "value": "seed"}, - {"label": _("Straight lines"), "value": "lines"} - ], orientation='vertical', stretch=False) + # self.ncc_method_radio = RadioSet([ + # {"label": _("Standard"), "value": "standard"}, + # {"label": _("Seed-based"), "value": "seed"}, + # {"label": _("Straight lines"), "value": "lines"} + # ], orientation='vertical', stretch=False) + self.ncc_method_combo = FCComboBox() + self.ncc_method_combo.addItems( + [_("Standard"), _("Seed"), _("Lines")] + ) grid0.addWidget(methodlabel, 12, 0) - grid0.addWidget(self.ncc_method_radio, 12, 1) + grid0.addWidget(self.ncc_method_combo, 12, 1) # Connect lines self.ncc_connect_cb = FCCheckBox('%s' % _("Connect")) @@ -5394,23 +5398,25 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): grid0.addWidget(self.ncc_rest_cb, 17, 0, 1, 2) # ## Reference - self.reference_radio = RadioSet([{'label': _('Itself'), 'value': 'itself'}, - {"label": _("Area Selection"), "value": "area"}, - {'label': _('Reference Object'), 'value': 'box'}], - orientation='vertical', - stretch=None) - reference_label = QtWidgets.QLabel('%s:' % _("Reference")) - reference_label.setToolTip( - _("- 'Itself' - the non copper clearing extent\n" - "is based on the object that is copper cleared.\n " + # self.reference_radio = RadioSet([{'label': _('Itself'), 'value': 'itself'}, + # {"label": _("Area Selection"), "value": "area"}, + # {'label': _('Reference Object'), 'value': 'box'}], + # orientation='vertical', + # stretch=None) + self.select_combo = FCComboBox() + self.select_combo.addItems( + [_("Itself"), _("Area Selection"), _("Reference Object")] + ) + select_label = QtWidgets.QLabel('%s:' % _("Reference")) + select_label.setToolTip( + _("Selection of area to be cleared of copper." + "- 'Itself' - the non copper clearing extent is based on the object that is copper cleared.\n " "- 'Area Selection' - left mouse click to start selection of the area to be painted.\n" - "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple areas.\n" - "- 'Reference Object' - will do non copper clearing within the area\n" - "specified by another object.") + "- 'Reference Object' - will do non copper clearing within the area specified by another object.") ) - grid0.addWidget(reference_label, 18, 0) - grid0.addWidget(self.reference_radio, 18, 1) + grid0.addWidget(select_label, 18, 0) + grid0.addWidget(self.select_combo, 18, 1) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNCC.py similarity index 98% rename from flatcamTools/ToolNonCopperClear.py rename to flatcamTools/ToolNCC.py index 45ea96e8..9caddcc3 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/flatcamTools/ToolNCC.py @@ -411,20 +411,25 @@ class NonCopperClear(FlatCAMTool, Gerber): # Method methodlabel = QtWidgets.QLabel('%s:' % _('Method')) methodlabel.setToolTip( - _("Algorithm for non-copper clearing:
" - "Standard: Fixed step inwards.
" - "Seed-based: Outwards from seed.
" - "Line-based: Parallel lines.") + _("Algorithm for copper clearing:\n" + "- Standard: Fixed step inwards.\n" + "- Seed-based: Outwards from seed.\n" + "- Line-based: Parallel lines.") ) - self.ncc_method_radio = RadioSet([ - {"label": _("Standard"), "value": "standard"}, - {"label": _("Seed-based"), "value": "seed"}, - {"label": _("Straight lines"), "value": "lines"} - ], orientation='vertical', stretch=False) - self.ncc_method_radio.setObjectName("n_method") + # self.ncc_method_radio = RadioSet([ + # {"label": _("Standard"), "value": "standard"}, + # {"label": _("Seed-based"), "value": "seed"}, + # {"label": _("Straight lines"), "value": "lines"} + # ], orientation='vertical', stretch=False) + + self.ncc_method_combo = FCComboBox() + self.ncc_method_combo.addItems( + [_("Standard"), _("Seed"), _("Lines")] + ) + self.ncc_method_combo.setObjectName("n_method") self.grid3.addWidget(methodlabel, 17, 0) - self.grid3.addWidget(self.ncc_method_radio, 17, 1) + self.grid3.addWidget(self.ncc_method_combo, 17, 1) # Connect lines self.ncc_connect_cb = FCCheckBox('%s' % _("Connect")) @@ -516,21 +521,26 @@ class NonCopperClear(FlatCAMTool, Gerber): self.grid3.addWidget(self.ncc_rest_cb, 25, 0, 1, 2) # ## Reference - self.reference_radio = RadioSet([ - {'label': _('Itself'), 'value': 'itself'}, - {"label": _("Area Selection"), "value": "area"}, - {'label': _("Reference Object"), 'value': 'box'} - ], orientation='vertical', stretch=False) - self.reference_radio.setObjectName("n_reference") + # self.select_radio = RadioSet([ + # {'label': _('Itself'), 'value': 'itself'}, + # {"label": _("Area Selection"), "value": "area"}, + # {'label': _("Reference Object"), 'value': 'box'} + # ], orientation='vertical', stretch=False) + self.select_combo = FCComboBox() + self.select_combo.addItems( + [_("Itself"), _("Area Selection"), _("Reference Object")] + ) + self.select_combo.setObjectName("n_selection") - self.reference_label = QtWidgets.QLabel('%s:' % _("Reference")) - self.reference_label.setToolTip( - _("- 'Itself' - the non copper clearing extent is based on the object that is copper cleared.\n " + self.select_label = QtWidgets.QLabel('%s:' % _("Selection")) + self.select_label.setToolTip( + _("Selection of area to be cleared of copper." + "- 'Itself' - the non copper clearing extent is based on the object that is copper cleared.\n " "- 'Area Selection' - left mouse click to start selection of the area to be painted.\n" "- 'Reference Object' - will do non copper clearing within the area specified by another object.") ) - self.grid3.addWidget(self.reference_label, 26, 0, 1, 2) - self.grid3.addWidget(self.reference_radio, 27, 0, 1, 2) + self.grid3.addWidget(self.select_label, 26, 0,) + self.grid3.addWidget(self.select_combo, 26, 1) form1 = QtWidgets.QFormLayout() self.grid3.addLayout(form1, 28, 0, 1, 2) @@ -659,7 +669,7 @@ class NonCopperClear(FlatCAMTool, Gerber): "nccoperation":self.op_radio, "nccoverlap": self.ncc_overlap_entry, "nccmargin": self.ncc_margin_entry, - "nccmethod": self.ncc_method_radio, + "nccmethod": self.ncc_method_combo, "nccconnect": self.ncc_connect_cb, "ncccontour": self.ncc_contour_cb, "nccoffset": self.ncc_choice_offset_cb, @@ -696,7 +706,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.op_radio.activated_custom.connect(self.on_operation_change) self.box_combo_type.currentIndexChanged.connect(self.on_combo_box_type) - self.reference_radio.group_toggle_fn = self.on_toggle_reference + self.select_combo.group_toggle_fn = self.on_toggle_reference self.ncc_rest_cb.stateChanged.connect(self.on_rest_machining_check) self.ncc_order_radio.activated_custom[str].connect(self.on_order_changed) @@ -943,14 +953,14 @@ class NonCopperClear(FlatCAMTool, Gerber): self.ncc_order_radio.set_value(self.app.defaults["tools_nccorder"]) self.ncc_overlap_entry.set_value(self.app.defaults["tools_nccoverlap"]) self.ncc_margin_entry.set_value(self.app.defaults["tools_nccmargin"]) - self.ncc_method_radio.set_value(self.app.defaults["tools_nccmethod"]) + self.ncc_method_combo.set_value(self.app.defaults["tools_nccmethod"]) self.ncc_connect_cb.set_value(self.app.defaults["tools_nccconnect"]) self.ncc_contour_cb.set_value(self.app.defaults["tools_ncccontour"]) self.ncc_rest_cb.set_value(self.app.defaults["tools_nccrest"]) self.ncc_choice_offset_cb.set_value(self.app.defaults["tools_ncc_offset_choice"]) self.ncc_offset_spinner.set_value(self.app.defaults["tools_ncc_offset_value"]) - self.reference_radio.set_value(self.app.defaults["tools_nccref"]) + self.select_combo.set_value(self.app.defaults["tools_nccref"]) self.milling_type_radio.set_value(self.app.defaults["tools_nccmilling_type"]) self.cutz_entry.set_value(self.app.defaults["tools_ncccutz"]) self.tool_type_radio.set_value(self.app.defaults["tools_ncctool_type"]) @@ -1249,7 +1259,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.box_combo.setCurrentIndex(0) def on_toggle_reference(self): - if self.reference_radio.get_value() == "itself" or self.reference_radio.get_value() == "area": + if self.select_combo.get_value() == _("Itself") or self.select_combo.get_value() == _("Area Selection"): self.box_combo.hide() self.box_combo_label.hide() self.box_combo_type.hide() @@ -1566,8 +1576,8 @@ class NonCopperClear(FlatCAMTool, Gerber): self.o_name = '%s_ncc' % self.obj_name - self.select_method = self.reference_radio.get_value() - if self.select_method == 'itself': + self.select_method = self.select_combo.get_value() + if self.select_method == _('Itself'): self.bound_obj_name = self.object_combo.currentText() # Get source object. try: @@ -1580,7 +1590,7 @@ class NonCopperClear(FlatCAMTool, Gerber): ncctooldia=self.ncc_dia_list, isotooldia=self.iso_dia_list, outname=self.o_name) - elif self.select_method == 'area': + elif self.select_method == _("Area Selection"): self.app.inform.emit('[WARNING_NOTCL] %s' % _("Click the start point of the area.")) if self.app.is_legacy is False: @@ -1743,7 +1753,7 @@ class NonCopperClear(FlatCAMTool, Gerber): box_kind = box_obj.kind if box_obj is not None else None env_obj = None - if ncc_select == 'itself': + if ncc_select == _('Itself'): geo_n = ncc_obj.solid_geometry try: @@ -1759,13 +1769,13 @@ class NonCopperClear(FlatCAMTool, Gerber): log.debug("NonCopperClear.envelope_object() 'itself' --> %s" % str(e)) self.app.inform.emit('[ERROR_NOTCL] %s' % _("No object available.")) return None - elif ncc_select == 'area': + elif ncc_select == _("Area Selection"): env_obj = cascaded_union(self.sel_rect) try: __ = iter(env_obj) except Exception: env_obj = [env_obj] - elif ncc_select == 'box': + elif ncc_select == _("Reference Object"): if box_obj is None: return None, None @@ -1807,14 +1817,14 @@ class NonCopperClear(FlatCAMTool, Gerber): return 'fail' bounding_box = None - if ncc_select == 'itself': + if ncc_select == _('Itself'): try: bounding_box = env_obj.buffer(distance=ncc_margin, join_style=base.JOIN_STYLE.mitre) except Exception as e: log.debug("NonCopperClear.envelope_object_to_tool_bounding_box() 'itself' --> %s" % str(e)) self.app.inform.emit('[ERROR_NOTCL] %s' % _("No object available.")) return 'fail' - elif ncc_select == 'area': + elif ncc_select == _("Area Selection"): geo_buff_list = [] for poly in env_obj: if self.app.abort_flag: @@ -1822,7 +1832,7 @@ class NonCopperClear(FlatCAMTool, Gerber): raise FlatCAMApp.GracefulException geo_buff_list.append(poly.buffer(distance=ncc_margin, join_style=base.JOIN_STYLE.mitre)) bounding_box = cascaded_union(geo_buff_list) - elif ncc_select == 'box': + elif ncc_select == _("Reference Object"): if box_kind == 'geometry': geo_buff_list = list() for poly in env_obj: @@ -2055,7 +2065,7 @@ class NonCopperClear(FlatCAMTool, Gerber): units = self.app.defaults['units'] order = order if order else self.ncc_order_radio.get_value() - ncc_select = self.reference_radio.get_value() + ncc_select = self.select_combo.get_value() rest_machining_choice = self.ncc_rest_cb.get_value() # determine if to use the progressive plotting @@ -2217,13 +2227,13 @@ class NonCopperClear(FlatCAMTool, Gerber): try: for pol in p: if pol is not None and isinstance(pol, Polygon): - if ncc_method == 'standard': + if ncc_method == _("Standard"): cp = self.clear_polygon(pol, tool, self.grb_circle_steps, overlap=ncc_overlap, contour=ncc_contour, connect=ncc_connect, prog_plot=prog_plot) - elif ncc_method == 'seed': + elif ncc_method == _("Seed"): cp = self.clear_polygon2(pol, tool, self.grb_circle_steps, overlap=ncc_overlap, contour=ncc_contour, @@ -2246,12 +2256,12 @@ class NonCopperClear(FlatCAMTool, Gerber): "It is: %s" % str(type(pol))) except TypeError: if isinstance(p, Polygon): - if ncc_method == 'standard': + if ncc_method == _("Standard"): cp = self.clear_polygon(p, tool, self.grb_circle_steps, overlap=ncc_overlap, contour=ncc_contour, connect=ncc_connect, prog_plot=prog_plot) - elif ncc_method == 'seed': + elif ncc_method == _("Seed"): cp = self.clear_polygon2(p, tool, self.grb_circle_steps, overlap=ncc_overlap, contour=ncc_contour, connect=ncc_connect, @@ -2515,13 +2525,13 @@ class NonCopperClear(FlatCAMTool, Gerber): if isinstance(p, Polygon): try: - if ncc_method == 'standard': + if ncc_method == _("Standard"): cp = self.clear_polygon(p, tool_used, self.grb_circle_steps, overlap=ncc_overlap, contour=ncc_contour, connect=ncc_connect, prog_plot=prog_plot) - elif ncc_method == 'seed': + elif ncc_method == _("Seed"): cp = self.clear_polygon2(p, tool_used, self.grb_circle_steps, overlap=ncc_overlap, contour=ncc_contour, @@ -2547,13 +2557,13 @@ class NonCopperClear(FlatCAMTool, Gerber): QtWidgets.QApplication.processEvents() try: - if ncc_method == 'standard': + if ncc_method == _("Standard"): cp = self.clear_polygon(poly, tool_used, self.grb_circle_steps, overlap=ncc_overlap, contour=ncc_contour, connect=ncc_connect, prog_plot=prog_plot) - elif ncc_method == 'seed': + elif ncc_method == _("Seed"): cp = self.clear_polygon2(poly, tool_used, self.grb_circle_steps, overlap=ncc_overlap, contour=ncc_contour, @@ -2789,7 +2799,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.app.inform.emit(_("NCC Tool. Preparing non-copper polygons.")) try: - if sel_obj is None or sel_obj == 'itself': + if sel_obj is None or sel_obj == _('Itself'): ncc_sel_obj = ncc_obj else: ncc_sel_obj = sel_obj @@ -2798,7 +2808,7 @@ class NonCopperClear(FlatCAMTool, Gerber): return 'fail' bounding_box = None - if ncc_select == 'itself': + if ncc_select == _('Itself'): geo_n = ncc_sel_obj.solid_geometry try: @@ -2951,7 +2961,7 @@ class NonCopperClear(FlatCAMTool, Gerber): milling_type = self.app.defaults["tools_nccmilling_type"] for tool_iso in isotooldia: - new_geometry = [] + new_geometry = list() if milling_type == 'cl': isolated_geo = self.generate_envelope(tool_iso / 2, 1) diff --git a/flatcamTools/__init__.py b/flatcamTools/__init__.py index 74d1aff5..bdd7e58b 100644 --- a/flatcamTools/__init__.py +++ b/flatcamTools/__init__.py @@ -17,7 +17,7 @@ from flatcamTools.ToolDistanceMin import DistanceMin from flatcamTools.ToolMove import ToolMove -from flatcamTools.ToolNonCopperClear import NonCopperClear +from flatcamTools.ToolNCC import NonCopperClear from flatcamTools.ToolPaint import ToolPaint from flatcamTools.ToolOptimal import ToolOptimal From acc61d460b75799a57d3d616a450edf192334984 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 29 Feb 2020 22:21:09 +0200 Subject: [PATCH 119/209] - fixed error in CutOut Tool when trying to create a FreeFrom Cutout out of a Gerber object with the Convex Shape checked --- README.md | 1 + flatcamGUI/PreferencesUI.py | 22 +++++++++++----------- flatcamTools/ToolCutOut.py | 16 +++++++++++----- flatcamTools/ToolNCC.py | 8 ++++---- flatcamTools/ToolPaint.py | 11 +++++------ 5 files changed, 32 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 28be59a2..9d3bab8c 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 29.02.2020 - compacted the NCC Tool UI by replacing some Radio buttons with Combo boxes due of too many elements +- fixed error in CutOut Tool when trying to create a FreeFrom Cutout out of a Gerber object with the Convex Shape checked 28.02.2020 diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index 7d6767cd..89dcbfd0 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -5407,12 +5407,12 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): self.select_combo.addItems( [_("Itself"), _("Area Selection"), _("Reference Object")] ) - select_label = QtWidgets.QLabel('%s:' % _("Reference")) + select_label = QtWidgets.QLabel('%s:' % _("Selection")) select_label.setToolTip( - _("Selection of area to be cleared of copper." - "- 'Itself' - the non copper clearing extent is based on the object that is copper cleared.\n " - "- 'Area Selection' - left mouse click to start selection of the area to be painted.\n" - "- 'Reference Object' - will do non copper clearing within the area specified by another object.") + _("Selection of area to be processed.\n" + "- 'Itself' - the processing extent is based on the object that is processed.\n " + "- 'Area Selection' - left mouse click to start selection of the area to be processed.\n" + "- 'Reference Object' - will process the area specified by another object.") ) grid0.addWidget(select_label, 18, 0) @@ -5905,14 +5905,14 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI): # Polygon selection selectlabel = QtWidgets.QLabel('%s:' % _('Selection')) selectlabel.setToolTip( - _("How to select Polygons to be painted.\n" - "- 'Polygon Selection' - left mouse click to add/remove polygons to be painted.\n" - "- 'Area Selection' - left mouse click to start selection of the area to be painted.\n" + _("Selection of area to be processed.\n" + "- 'Polygon Selection' - left mouse click to add/remove polygons to be processed.\n" + "- 'Area Selection' - left mouse click to start selection of the area to be processed.\n" "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple areas.\n" - "- 'All Polygons' - the Paint will start after click.\n" - "- 'Reference Object' - will do non copper clearing within the area\n" - "specified by another object.") + "- 'All Polygons' - the process will start after click.\n" + "- 'Reference Object' - will process the area specified by another object.") ) + # self.selectmethod_combo = RadioSet( # [ # {"label": _("Polygon Selection"), "value": "single"}, diff --git a/flatcamTools/ToolCutOut.py b/flatcamTools/ToolCutOut.py index 32e799b1..87ebafc3 100644 --- a/flatcamTools/ToolCutOut.py +++ b/flatcamTools/ToolCutOut.py @@ -521,13 +521,19 @@ class CutOut(FlatCAMTool): gapsize = gapsize / 2 + (dia / 2) def geo_init(geo_obj, app_obj): - solid_geo = [] + solid_geo = list() if isinstance(cutout_obj, FlatCAMGerber): - if convex_box: - object_geo = cutout_obj.solid_geometry.convex_hull - else: - object_geo = cutout_obj.solid_geometry + if isinstance(cutout_obj.solid_geometry, list): + cutout_obj.solid_geometry = MultiPolygon(cutout_obj.solid_geometry) + + try: + if convex_box: + object_geo = cutout_obj.solid_geometry.convex_hull + else: + object_geo = cutout_obj.solid_geometry + except Exception as e: + log.debug("CutOut.on_freeform_cutout().geo_init() --> %s" % str(e)) else: object_geo = cutout_obj.solid_geometry diff --git a/flatcamTools/ToolNCC.py b/flatcamTools/ToolNCC.py index 9caddcc3..021788eb 100644 --- a/flatcamTools/ToolNCC.py +++ b/flatcamTools/ToolNCC.py @@ -534,10 +534,10 @@ class NonCopperClear(FlatCAMTool, Gerber): self.select_label = QtWidgets.QLabel('%s:' % _("Selection")) self.select_label.setToolTip( - _("Selection of area to be cleared of copper." - "- 'Itself' - the non copper clearing extent is based on the object that is copper cleared.\n " - "- 'Area Selection' - left mouse click to start selection of the area to be painted.\n" - "- 'Reference Object' - will do non copper clearing within the area specified by another object.") + _("Selection of area to be processed.\n" + "- 'Itself' - the processing extent is based on the object that is processed.\n " + "- 'Area Selection' - left mouse click to start selection of the area to be processed.\n" + "- 'Reference Object' - will process the area specified by another object.") ) self.grid3.addWidget(self.select_label, 26, 0,) self.grid3.addWidget(self.select_combo, 26, 1) diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 310a6208..8cb957b9 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -453,13 +453,12 @@ class ToolPaint(FlatCAMTool, Gerber): # Polygon selection selectlabel = QtWidgets.QLabel('%s:' % _('Selection')) selectlabel.setToolTip( - _("How to select Polygons to be painted.\n" - "- 'Polygon Selection' - left mouse click to add/remove polygons to be painted.\n" - "- 'Area Selection' - left mouse click to start selection of the area to be painted.\n" + _("Selection of area to be processed.\n" + "- 'Polygon Selection' - left mouse click to add/remove polygons to be processed.\n" + "- 'Area Selection' - left mouse click to start selection of the area to be processed.\n" "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple areas.\n" - "- 'All Polygons' - the Paint will start after click.\n" - "- 'Reference Object' - will do non copper clearing within the area\n" - "specified by another object.") + "- 'All Polygons' - the process will start after click.\n" + "- 'Reference Object' - will process the area specified by another object.") ) # grid3 = QtWidgets.QGridLayout() From 70d3895799c41131995637755595712b08121317 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 1 Mar 2020 00:52:24 +0200 Subject: [PATCH 120/209] - working on a new type of database --- FlatCAMApp.py | 42 +- FlatCAMCommon.py | 964 ++++++++++++++++++++++++++- FlatCAMObj.py | 62 +- README.md | 1 + camlib.py | 36 +- flatcamEditors/FlatCAMExcEditor.py | 46 +- flatcamEditors/FlatCAMGeoEditor.py | 38 +- flatcamEditors/FlatCAMGrbEditor.py | 130 ++-- flatcamGUI/GUIElements.py | 36 +- flatcamGUI/PlotCanvas.py | 2 +- flatcamGUI/PlotCanvasLegacy.py | 6 +- flatcamGUI/PreferencesUI.py | 4 +- flatcamParsers/ParseExcellon.py | 14 +- flatcamParsers/ParseGerber.py | 72 +- flatcamParsers/ParseHPGL2.py | 8 +- flatcamParsers/ParseSVG.py | 4 +- flatcamTools/ToolAlignObjects.py | 6 +- flatcamTools/ToolCalibration.py | 2 +- flatcamTools/ToolCopperThieving.py | 60 +- flatcamTools/ToolCutOut.py | 6 +- flatcamTools/ToolDblSided.py | 8 +- flatcamTools/ToolDistance.py | 2 +- flatcamTools/ToolExtractDrills.py | 10 +- flatcamTools/ToolFiducials.py | 48 +- flatcamTools/ToolFilm.py | 4 +- flatcamTools/ToolImage.py | 2 +- flatcamTools/ToolInvertGerber.py | 18 +- flatcamTools/ToolNCC.py | 38 +- flatcamTools/ToolOptimal.py | 6 +- flatcamTools/ToolPDF.py | 80 +-- flatcamTools/ToolPaint.py | 70 +- flatcamTools/ToolPanelize.py | 10 +- flatcamTools/ToolProperties.py | 4 +- flatcamTools/ToolPunchGerber.py | 40 +- flatcamTools/ToolQRCode.py | 20 +- flatcamTools/ToolRulesCheck.py | 124 ++-- flatcamTools/ToolSub.py | 18 +- tclCommands/TclCommand.py | 2 +- tclCommands/TclCommandBounds.py | 4 +- tclCommands/TclCommandCopperClear.py | 2 +- tclCommands/TclCommandPaint.py | 2 +- tclCommands/TclCommandPanelize.py | 2 +- tclCommands/TclCommandSetOrigin.py | 2 +- 43 files changed, 1515 insertions(+), 540 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 285e8315..e4c098c4 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -54,7 +54,7 @@ from flatcamGUI.PlotCanvas import * from flatcamGUI.PlotCanvasLegacy import * from flatcamGUI.FlatCAMGUI import * -from FlatCAMCommon import LoudDict, BookmarkManager, ToolsDB, color_variant +from FlatCAMCommon import LoudDict, BookmarkManager, ToolsDB, ToolsDB2, color_variant from FlatCAMPostProc import load_preprocessors from flatcamEditors.FlatCAMGeoEditor import FlatCAMGeoEditor @@ -1076,7 +1076,7 @@ class App(QtCore.QObject): self.current_units = self.defaults['units'] # store here the current self.defaults so it can be restored if Preferences changes are cancelled - self.current_defaults = dict() + self.current_defaults = {} self.current_defaults.update(self.defaults) # ########################################################################## @@ -1755,7 +1755,7 @@ class App(QtCore.QObject): # make sure that always the 'default' preprocessor is the first item in the dictionary if 'default' in self.preprocessors.keys(): - new_ppp_dict = dict() + new_ppp_dict = {} # add the 'default' name first in the dict after removing from the preprocessor's dictionary default_pp = self.preprocessors.pop('default') @@ -2673,10 +2673,10 @@ class App(QtCore.QObject): # List to store the objects that are currently loaded in FlatCAM # This list is updated on each object creation or object delete - self.all_objects_list = list() + self.all_objects_list = [] # List to store the objects that are selected - self.sel_objects_list = list() + self.sel_objects_list = [] # holds the key modifier if pressed (CTRL, SHIFT or ALT) self.key_modifiers = None @@ -2752,7 +2752,7 @@ class App(QtCore.QObject): # this holds a widget that is installed in the Plot Area when View Source option is used self.source_editor_tab = None - self.pagesize = dict() + self.pagesize = {} # Storage for shapes, storage that can be used by FlatCAm tools for utility geometry # VisPy visuals @@ -7410,8 +7410,8 @@ class App(QtCore.QObject): self.inform.emit('[ERROR_NOTCL] %s' % _("Failed. No object(s) selected...")) return - xminlist = list() - yminlist = list() + xminlist = [] + yminlist = [] # first get a bounding box to fit all for obj in obj_list: @@ -7896,7 +7896,7 @@ class App(QtCore.QObject): apertures[str(apid)] = {} apertures[str(apid)]['geometry'] = [] for obj_orig in obj.solid_geometry: - new_elem = dict() + new_elem = {} new_elem['solid'] = obj_orig try: new_elem['follow'] = obj_orig.exterior @@ -7917,7 +7917,7 @@ class App(QtCore.QObject): apertures[str(apid)] = {} apertures[str(apid)]['geometry'] = [] for geo in obj.tools[tool]['solid_geometry']: - new_el = dict() + new_el = {} new_el['solid'] = geo new_el['follow'] = geo.exterior apertures[str(apid)]['geometry'].append(deepcopy(new_el)) @@ -8072,7 +8072,7 @@ class App(QtCore.QObject): # there can be only one instance of Tools Database at one time return - self.tools_db_tab = ToolsDB( + self.tools_db_tab = ToolsDB2( app=self, parent=self.ui, callback_on_edited=self.on_tools_db_edited, @@ -8458,7 +8458,7 @@ class App(QtCore.QObject): return # get the name of the selected objects and add them to a list - name_list = list() + name_list = [] for obj in self.collection.get_selected(): name_list.append(obj.options['name']) @@ -8495,12 +8495,12 @@ class App(QtCore.QObject): pass self.ui.menuobjects.clear() - gerber_list = list() - exc_list = list() - cncjob_list = list() - geo_list = list() - script_list = list() - doc_list = list() + gerber_list = [] + exc_list = [] + cncjob_list = [] + geo_list = [] + script_list = [] + doc_list = [] for name in self.collection.get_names(): obj_named = self.collection.get_by_name(name) @@ -8780,7 +8780,7 @@ class App(QtCore.QObject): was clicked, the pixel coordinates and the axes coordinates. :return: None """ - self.pos = list() + self.pos = [] if self.is_legacy is False: event_pos = event.pos @@ -10631,7 +10631,7 @@ class App(QtCore.QObject): color = 'black' transparency_level = 1.0 - self.pagesize = dict() + self.pagesize = {} self.pagesize.update( { 'Bounds': None, @@ -10685,7 +10685,7 @@ class App(QtCore.QObject): } ) - exported_svg = list() + exported_svg = [] for obj in obj_selection: svg_obj = obj.export_svg(scale_stroke_factor=0.0, scale_factor_x=None, scale_factor_y=None, diff --git a/FlatCAMCommon.py b/FlatCAMCommon.py index 2bc95131..4a68cdaa 100644 --- a/FlatCAMCommon.py +++ b/FlatCAMCommon.py @@ -12,7 +12,8 @@ # ########################################################## from PyQt5 import QtGui, QtCore, QtWidgets -from flatcamGUI.GUIElements import FCTable, FCEntry, FCButton, FCDoubleSpinner, FCComboBox, FCCheckBox, FCSpinner +from flatcamGUI.GUIElements import FCTable, FCEntry, FCButton, FCDoubleSpinner, FCComboBox, FCCheckBox, FCSpinner, \ + FCTree from camlib import to_dict import sys @@ -332,7 +333,7 @@ class BookmarkManager(QtWidgets.QWidget): # house keeping: it pays to have keys increased by one new_key = 0 - new_dict = dict() + new_dict = {} for k, v in self.bm_dict.items(): # we start with key 1 so we can use the len(self.bm_dict) # when adding bookmarks (keys in bm_dict) @@ -492,7 +493,7 @@ class ToolsDB(QtWidgets.QWidget): } } ''' - self.db_tool_dict = dict() + self.db_tool_dict = {} # layouts layout = QtWidgets.QVBoxLayout() @@ -994,7 +995,7 @@ class ToolsDB(QtWidgets.QWidget): :return: None """ - default_data = dict() + default_data = {} default_data.update({ "cutz": float(self.app.defaults["geometry_cutz"]), "multidepth": self.app.defaults["geometry_multidepth"], @@ -1018,7 +1019,7 @@ class ToolsDB(QtWidgets.QWidget): "endz": float(self.app.defaults["geometry_endz"]) }) - dict_elem = dict() + dict_elem = {} dict_elem['name'] = 'new_tool' if type(self.app.defaults["geometry_cnctooldia"]) == float: dict_elem['tooldia'] = self.app.defaults["geometry_cnctooldia"] @@ -1266,8 +1267,955 @@ class ToolsDB(QtWidgets.QWidget): # update the dictionary storage self.db_tool_dict self.db_tool_dict.clear() - dict_elem = dict() - default_data = dict() + dict_elem = {} + default_data = {} + + for row in range(self.table_widget.rowCount()): + new_toolid = row + 1 + for col in range(self.table_widget.columnCount()): + column_header_text = self.table_widget.horizontalHeaderItem(col).text() + if column_header_text == _('Tool Name'): + dict_elem['name'] = self.table_widget.item(row, col).text() + elif column_header_text == _('Tool Dia'): + dict_elem['tooldia'] = self.table_widget.cellWidget(row, col).get_value() + elif column_header_text == _('Tool Offset'): + dict_elem['offset'] = self.table_widget.cellWidget(row, col).get_value() + elif column_header_text == _('Custom Offset'): + dict_elem['offset_value'] = self.table_widget.cellWidget(row, col).get_value() + elif column_header_text == _('Tool Type'): + dict_elem['type'] = self.table_widget.cellWidget(row, col).get_value() + elif column_header_text == _('Tool Shape'): + dict_elem['tool_type'] = self.table_widget.cellWidget(row, col).get_value() + else: + if column_header_text == _('Cut Z'): + default_data['cutz'] = self.table_widget.cellWidget(row, col).get_value() + elif column_header_text == _('MultiDepth'): + default_data['multidepth'] = self.table_widget.cellWidget(row, col).get_value() + elif column_header_text == _('DPP'): + default_data['depthperpass'] = self.table_widget.cellWidget(row, col).get_value() + elif column_header_text == _('V-Dia'): + default_data['vtipdia'] = self.table_widget.cellWidget(row, col).get_value() + elif column_header_text == _('V-Angle'): + default_data['vtipangle'] = self.table_widget.cellWidget(row, col).get_value() + elif column_header_text == _('Travel Z'): + default_data['travelz'] = self.table_widget.cellWidget(row, col).get_value() + elif column_header_text == _('FR'): + default_data['feedrate'] = self.table_widget.cellWidget(row, col).get_value() + elif column_header_text == _('FR Z'): + default_data['feedrate_z'] = self.table_widget.cellWidget(row, col).get_value() + elif column_header_text == _('FR Rapids'): + default_data['feedrate_rapid'] = self.table_widget.cellWidget(row, col).get_value() + elif column_header_text == _('Spindle Speed'): + default_data['spindlespeed'] = self.table_widget.cellWidget(row, col).get_value() + elif column_header_text == _('Dwell'): + default_data['dwell'] = self.table_widget.cellWidget(row, col).get_value() + elif column_header_text == _('Dwelltime'): + default_data['dwelltime'] = self.table_widget.cellWidget(row, col).get_value() + elif column_header_text == _('Preprocessor'): + default_data['ppname_g'] = self.table_widget.cellWidget(row, col).get_value() + elif column_header_text == _('ExtraCut'): + default_data['extracut'] = self.table_widget.cellWidget(row, col).get_value() + elif column_header_text == _("E-Cut Length"): + default_data['extracut_length'] = self.table_widget.cellWidget(row, col).get_value() + elif column_header_text == _('Toolchange'): + default_data['toolchange'] = self.table_widget.cellWidget(row, col).get_value() + elif column_header_text == _('Toolchange XY'): + default_data['toolchangexy'] = self.table_widget.item(row, col).text() + elif column_header_text == _('Toolchange Z'): + default_data['toolchangez'] = self.table_widget.cellWidget(row, col).get_value() + elif column_header_text == _('Start Z'): + default_data['startz'] = float(self.table_widget.item(row, col).text()) \ + if self.table_widget.item(row, col).text() is not '' else None + elif column_header_text == _('End Z'): + default_data['endz'] = self.table_widget.cellWidget(row, col).get_value() + + dict_elem['data'] = default_data + self.db_tool_dict.update( + { + new_toolid: deepcopy(dict_elem) + } + ) + + self.callback_app() + + def on_tool_requested_from_app(self): + if not self.table_widget.selectionModel().selectedRows(): + self.app.inform.emit('[WARNING_NOTCL] %s...' % _("No Tool/row selected in the Tools Database table")) + return + + model_index_list = self.table_widget.selectionModel().selectedRows() + for model_index in model_index_list: + selected_row = model_index.row() + tool_uid = selected_row + 1 + for key in self.db_tool_dict.keys(): + if str(key) == str(tool_uid): + selected_tool = self.db_tool_dict[key] + self.on_tool_request(tool=selected_tool) + + def on_cancel_tool(self): + for idx in range(self.app.ui.plot_tab_area.count()): + if self.app.ui.plot_tab_area.tabText(idx) == _("Tools Database"): + wdg = self.app.ui.plot_tab_area.widget(idx) + wdg.deleteLater() + self.app.ui.plot_tab_area.removeTab(idx) + self.app.inform.emit('%s' % _("Cancelled adding tool from DB.")) + + def resize_new_tool_table_widget(self, min_size, max_size): + """ + Resize the table widget responsible for adding new tool in the Tool Database + + :param min_size: passed by rangeChanged signal or the self.new_tool_table_widget.horizontalScrollBar() + :param max_size: passed by rangeChanged signal or the self.new_tool_table_widget.horizontalScrollBar() + :return: + """ + t_height = self.t_height + if max_size > min_size: + t_height = self.t_height + self.new_tool_table_widget.verticalScrollBar().height() + + self.new_tool_table_widget.setMaximumHeight(t_height) + + def closeEvent(self, QCloseEvent): + super().closeEvent(QCloseEvent) + + +class ToolsDB2(QtWidgets.QWidget): + + mark_tools_rows = QtCore.pyqtSignal() + + def __init__(self, app, callback_on_edited, callback_on_tool_request, parent=None): + super(ToolsDB2, self).__init__(parent) + + self.app = app + self.decimals = self.app.decimals + self.callback_app = callback_on_edited + + self.on_tool_request = callback_on_tool_request + + self.offset_item_options = ["Path", "In", "Out", "Custom"] + self.type_item_options = ["Iso", "Rough", "Finish"] + self.tool_type_item_options = ["C1", "C2", "C3", "C4", "B", "V"] + + ''' + dict to hold all the tools in the Tools DB + format: + { + tool_id: { + 'name': 'new_tool' + 'tooldia': self.app.defaults["geometry_cnctooldia"] + 'offset': 'Path' + 'offset_value': 0.0 + 'type': _('Rough'), + 'tool_type': 'C1' + 'data': dict() + } + } + ''' + self.db_tool_dict = {} + + # layouts + grid_layout = QtWidgets.QGridLayout() + grid_layout.setColumnStretch(0, 0) + grid_layout.setColumnStretch(1, 1) + + self.setLayout(grid_layout) + + tree_layout = QtWidgets.QVBoxLayout() + grid_layout.addLayout(tree_layout, 0, 0) + + self.tree_widget = FCTree(columns=2, header_hidden=False) + self.tree_widget.setHeaderLabels(["ID", "Tool Name"]) + self.tree_widget.setIndentation(0) + self.tree_widget.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding) + tree_layout.addWidget(self.tree_widget) + + table_hlay = QtWidgets.QHBoxLayout() + grid_layout.addLayout(table_hlay, 0, 1) + + self.table_widget = FCTable(drag_drop=True) + self.table_widget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) + table_hlay.addWidget(self.table_widget) + + # set the number of columns and the headers tool tips + self.configure_table() + + new_vlay = QtWidgets.QVBoxLayout() + grid_layout.addLayout(new_vlay, 1, 0, 1, 2) + + # new_tool_lbl = QtWidgets.QLabel('%s' % _("New Tool")) + # new_vlay.addWidget(new_tool_lbl, alignment=QtCore.Qt.AlignBottom) + + self.buttons_frame = QtWidgets.QFrame() + self.buttons_frame.setContentsMargins(0, 0, 0, 0) + new_vlay.addWidget(self.buttons_frame) + self.buttons_box = QtWidgets.QHBoxLayout() + self.buttons_box.setContentsMargins(0, 0, 0, 0) + self.buttons_frame.setLayout(self.buttons_box) + self.buttons_frame.show() + + add_entry_btn = FCButton(_("Add Geometry Tool in DB")) + add_entry_btn.setToolTip( + _("Add a new tool in the Tools Database.\n" + "It will be used in the Geometry UI.\n" + "You can edit it after it is added.") + ) + self.buttons_box.addWidget(add_entry_btn) + + # add_fct_entry_btn = FCButton(_("Add Paint/NCC Tool in DB")) + # add_fct_entry_btn.setToolTip( + # _("Add a new tool in the Tools Database.\n" + # "It will be used in the Paint/NCC Tools UI.\n" + # "You can edit it after it is added.") + # ) + # self.buttons_box.addWidget(add_fct_entry_btn) + + remove_entry_btn = FCButton(_("Delete Tool from DB")) + remove_entry_btn.setToolTip( + _("Remove a selection of tools in the Tools Database.") + ) + self.buttons_box.addWidget(remove_entry_btn) + + export_db_btn = FCButton(_("Export DB")) + export_db_btn.setToolTip( + _("Save the Tools Database to a custom text file.") + ) + self.buttons_box.addWidget(export_db_btn) + + import_db_btn = FCButton(_("Import DB")) + import_db_btn.setToolTip( + _("Load the Tools Database information's from a custom text file.") + ) + self.buttons_box.addWidget(import_db_btn) + + self.add_tool_from_db = FCButton(_("Add Tool from Tools DB")) + self.add_tool_from_db.setToolTip( + _("Add a new tool in the Tools Table of the\n" + "active Geometry object after selecting a tool\n" + "in the Tools Database.") + ) + self.add_tool_from_db.hide() + + self.cancel_tool_from_db = FCButton(_("Cancel")) + self.cancel_tool_from_db.hide() + + hlay = QtWidgets.QHBoxLayout() + tree_layout.addLayout(hlay) + hlay.addWidget(self.add_tool_from_db) + hlay.addWidget(self.cancel_tool_from_db) + hlay.addStretch() + + # ############################################################################## + # ######################## SIGNALS ############################################# + # ############################################################################## + + add_entry_btn.clicked.connect(self.on_tool_add) + remove_entry_btn.clicked.connect(self.on_tool_delete) + export_db_btn.clicked.connect(self.on_export_tools_db_file) + import_db_btn.clicked.connect(self.on_import_tools_db_file) + # closebtn.clicked.connect(self.accept) + + self.add_tool_from_db.clicked.connect(self.on_tool_requested_from_app) + self.cancel_tool_from_db.clicked.connect(self.on_cancel_tool) + + self.tree_widget.selectionModel().selectionChanged.connect(self.on_list_selection_change) + self.tree_widget.itemChanged.connect(self.on_list_item_edited) + self.setup_db_ui() + + def on_list_selection_change(self, current): + return + for idx in current.indexes(): + print(idx.data()) + + def on_list_item_edited(self, item, idx): + row = int(item.text(0)) - 1 + self.table_widget.item(row, 1).setText(item.text(1)) + + def configure_table(self): + self.table_widget.setColumnCount(27) + # self.table_widget.setColumnWidth(0, 20) + self.table_widget.setHorizontalHeaderLabels( + [ + '#', + _("Tool Name"), + _("Tool Dia"), + _("Tool Offset"), + _("Custom Offset"), + _("Tool Type"), + _("Tool Shape"), + _("Cut Z"), + _("MultiDepth"), + _("DPP"), + _("V-Dia"), + _("V-Angle"), + _("Travel Z"), + _("FR"), + _("FR Z"), + _("FR Rapids"), + _("Spindle Speed"), + _("Dwell"), + _("Dwelltime"), + _("Preprocessor"), + _("ExtraCut"), + _("E-Cut Length"), + _("Toolchange"), + _("Toolchange XY"), + _("Toolchange Z"), + _("Start Z"), + _("End Z"), + ] + ) + self.table_widget.horizontalHeaderItem(0).setToolTip( + _("Tool Index.")) + self.table_widget.horizontalHeaderItem(1).setToolTip( + _("Tool name.\n" + "This is not used in the app, it's function\n" + "is to serve as a note for the user.")) + self.table_widget.horizontalHeaderItem(2).setToolTip( + _("Tool Diameter.")) + self.table_widget.horizontalHeaderItem(3).setToolTip( + _("Tool Offset.\n" + "Can be of a few types:\n" + "Path = zero offset\n" + "In = offset inside by half of tool diameter\n" + "Out = offset outside by half of tool diameter\n" + "Custom = custom offset using the Custom Offset value")) + self.table_widget.horizontalHeaderItem(4).setToolTip( + _("Custom Offset.\n" + "A value to be used as offset from the current path.")) + self.table_widget.horizontalHeaderItem(5).setToolTip( + _("Tool Type.\n" + "Can be:\n" + "Iso = isolation cut\n" + "Rough = rough cut, low feedrate, multiple passes\n" + "Finish = finishing cut, high feedrate")) + self.table_widget.horizontalHeaderItem(6).setToolTip( + _("Tool Shape. \n" + "Can be:\n" + "C1 ... C4 = circular tool with x flutes\n" + "B = ball tip milling tool\n" + "V = v-shape milling tool")) + self.table_widget.horizontalHeaderItem(7).setToolTip( + _("Cutting Depth.\n" + "The depth at which to cut into material.")) + self.table_widget.horizontalHeaderItem(8).setToolTip( + _("Multi Depth.\n" + "Selecting this will allow cutting in multiple passes,\n" + "each pass adding a DPP parameter depth.")) + self.table_widget.horizontalHeaderItem(9).setToolTip( + _("DPP. Depth per Pass.\n" + "The value used to cut into material on each pass.")) + self.table_widget.horizontalHeaderItem(10).setToolTip( + _("V-Dia.\n" + "Diameter of the tip for V-Shape Tools.")) + self.table_widget.horizontalHeaderItem(11).setToolTip( + _("V-Agle.\n" + "Angle at the tip for the V-Shape Tools.")) + self.table_widget.horizontalHeaderItem(12).setToolTip( + _("Clearance Height.\n" + "Height at which the milling bit will travel between cuts,\n" + "above the surface of the material, avoiding all fixtures.")) + self.table_widget.horizontalHeaderItem(13).setToolTip( + _("FR. Feedrate\n" + "The speed on XY plane used while cutting into material.")) + self.table_widget.horizontalHeaderItem(14).setToolTip( + _("FR Z. Feedrate Z\n" + "The speed on Z plane.")) + self.table_widget.horizontalHeaderItem(15).setToolTip( + _("FR Rapids. Feedrate Rapids\n" + "Speed used while moving as fast as possible.\n" + "This is used only by some devices that can't use\n" + "the G0 g-code command. Mostly 3D printers.")) + self.table_widget.horizontalHeaderItem(16).setToolTip( + _("Spindle Speed.\n" + "If it's left empty it will not be used.\n" + "The speed of the spindle in RPM.")) + self.table_widget.horizontalHeaderItem(17).setToolTip( + _("Dwell.\n" + "Check this if a delay is needed to allow\n" + "the spindle motor to reach it's set speed.")) + self.table_widget.horizontalHeaderItem(18).setToolTip( + _("Dwell Time.\n" + "A delay used to allow the motor spindle reach it's set speed.")) + self.table_widget.horizontalHeaderItem(19).setToolTip( + _("Preprocessor.\n" + "A selection of files that will alter the generated G-code\n" + "to fit for a number of use cases.")) + self.table_widget.horizontalHeaderItem(20).setToolTip( + _("Extra Cut.\n" + "If checked, after a isolation is finished an extra cut\n" + "will be added where the start and end of isolation meet\n" + "such as that this point is covered by this extra cut to\n" + "ensure a complete isolation.")) + self.table_widget.horizontalHeaderItem(21).setToolTip( + _("Extra Cut length.\n" + "If checked, after a isolation is finished an extra cut\n" + "will be added where the start and end of isolation meet\n" + "such as that this point is covered by this extra cut to\n" + "ensure a complete isolation. This is the length of\n" + "the extra cut.")) + self.table_widget.horizontalHeaderItem(22).setToolTip( + _("Toolchange.\n" + "It will create a toolchange event.\n" + "The kind of toolchange is determined by\n" + "the preprocessor file.")) + self.table_widget.horizontalHeaderItem(23).setToolTip( + _("Toolchange XY.\n" + "A set of coordinates in the format (x, y).\n" + "Will determine the cartesian position of the point\n" + "where the tool change event take place.")) + self.table_widget.horizontalHeaderItem(24).setToolTip( + _("Toolchange Z.\n" + "The position on Z plane where the tool change event take place.")) + self.table_widget.horizontalHeaderItem(25).setToolTip( + _("Start Z.\n" + "If it's left empty it will not be used.\n" + "A position on Z plane to move immediately after job start.")) + self.table_widget.horizontalHeaderItem(26).setToolTip( + _("End Z.\n" + "A position on Z plane to move immediately after job stop.")) + + def setup_db_ui(self): + filename = self.app.data_path + '/geo_tools_db.FlatDB' + + # load the database tools from the file + try: + with open(filename) as f: + tools = f.read() + except IOError: + self.app.log.error("Could not load tools DB file.") + self.app.inform.emit('[ERROR] %s' % _("Could not load Tools DB file.")) + return + + try: + self.db_tool_dict = json.loads(tools) + except Exception: + e = sys.exc_info()[0] + self.app.log.error(str(e)) + self.app.inform.emit('[ERROR] %s' % _("Failed to parse Tools DB file.")) + return + + self.app.inform.emit('[success] %s: %s' % (_("Loaded FlatCAM Tools DB from"), filename)) + + self.build_db_ui() + + self.table_widget.setupContextMenu() + self.table_widget.addContextMenu( + _("Add to DB"), self.on_tool_add, icon=QtGui.QIcon(self.app.resource_location + "/plus16.png")) + self.table_widget.addContextMenu( + _("Copy from DB"), self.on_tool_copy, icon=QtGui.QIcon(self.app.resource_location + "/copy16.png")) + self.table_widget.addContextMenu( + _("Delete from DB"), self.on_tool_delete, icon=QtGui.QIcon(self.app.resource_location + "/delete32.png")) + + def build_db_ui(self): + self.ui_disconnect() + self.table_widget.setRowCount(len(self.db_tool_dict)) + + nr_crt = 0 + + parent = self.tree_widget + self.tree_widget.blockSignals(True) + self.tree_widget.clear() + self.tree_widget.blockSignals(False) + + for toolid, dict_val in self.db_tool_dict.items(): + row = nr_crt + nr_crt += 1 + + t_name = dict_val['name'] + try: + self.add_tool_table_line(row, name=t_name, widget=self.table_widget, tooldict=dict_val) + self.tree_widget.blockSignals(True) + try: + self.tree_widget.addParentEditable(parent=parent, title=[str(row+1), t_name], editable=True) + except Exception as e: + print('FlatCAMCoomn.ToolDB2.build_db_ui() -> ', str(e)) + self.tree_widget.blockSignals(False) + except Exception as e: + self.app.log.debug("ToolDB.build_db_ui.add_tool_table_line() --> %s" % str(e)) + vertical_header = self.table_widget.verticalHeader() + vertical_header.hide() + + horizontal_header = self.table_widget.horizontalHeader() + horizontal_header.setMinimumSectionSize(10) + horizontal_header.setDefaultSectionSize(70) + + self.table_widget.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents) + for x in range(27): + self.table_widget.resizeColumnToContents(x) + + horizontal_header.setSectionResizeMode(0, QtWidgets.QHeaderView.Fixed) + # horizontal_header.setSectionResizeMode(1, QtWidgets.QHeaderView.Stretch) + # horizontal_header.setSectionResizeMode(13, QtWidgets.QHeaderView.Fixed) + + horizontal_header.resizeSection(0, 20) + # horizontal_header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents) + # horizontal_header.setSectionResizeMode(2, QtWidgets.QHeaderView.Stretch) + + self.ui_connect() + + def add_tool_table_line(self, row, name, widget, tooldict): + data = tooldict['data'] + + nr_crt = row + 1 + id_item = QtWidgets.QTableWidgetItem('%d' % int(nr_crt)) + # id_item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + flags = id_item.flags() & ~QtCore.Qt.ItemIsEditable + id_item.setFlags(flags) + widget.setItem(row, 0, id_item) # Tool name/id + + tool_name_item = QtWidgets.QTableWidgetItem(name) + widget.setItem(row, 1, tool_name_item) + + dia_item = FCDoubleSpinner() + dia_item.set_precision(self.decimals) + dia_item.setSingleStep(0.1) + dia_item.set_range(0.0, 9999.9999) + dia_item.set_value(float(tooldict['tooldia'])) + widget.setCellWidget(row, 2, dia_item) + + tool_offset_item = FCComboBox() + for item in self.offset_item_options: + tool_offset_item.addItem(item) + tool_offset_item.set_value(tooldict['offset']) + widget.setCellWidget(row, 3, tool_offset_item) + + c_offset_item = FCDoubleSpinner() + c_offset_item.set_precision(self.decimals) + c_offset_item.setSingleStep(0.1) + c_offset_item.set_range(-9999.9999, 9999.9999) + c_offset_item.set_value(float(tooldict['offset_value'])) + widget.setCellWidget(row, 4, c_offset_item) + + tt_item = FCComboBox() + for item in self.type_item_options: + tt_item.addItem(item) + tt_item.set_value(tooldict['type']) + widget.setCellWidget(row, 5, tt_item) + + tshape_item = FCComboBox() + for item in self.tool_type_item_options: + tshape_item.addItem(item) + tshape_item.set_value(tooldict['tool_type']) + widget.setCellWidget(row, 6, tshape_item) + + cutz_item = FCDoubleSpinner() + cutz_item.set_precision(self.decimals) + cutz_item.setSingleStep(0.1) + if self.app.defaults['global_machinist_setting']: + cutz_item.set_range(-9999.9999, 9999.9999) + else: + cutz_item.set_range(-9999.9999, -0.0000) + + cutz_item.set_value(float(data['cutz'])) + widget.setCellWidget(row, 7, cutz_item) + + multidepth_item = FCCheckBox() + multidepth_item.set_value(data['multidepth']) + widget.setCellWidget(row, 8, multidepth_item) + + # to make the checkbox centered but it can no longer have it's value accessed - needs a fix using findchild() + # multidepth_item = QtWidgets.QWidget() + # cb = FCCheckBox() + # cb.set_value(data['multidepth']) + # qhboxlayout = QtWidgets.QHBoxLayout(multidepth_item) + # qhboxlayout.addWidget(cb) + # qhboxlayout.setAlignment(QtCore.Qt.AlignCenter) + # qhboxlayout.setContentsMargins(0, 0, 0, 0) + # widget.setCellWidget(row, 8, multidepth_item) + + depth_per_pass_item = FCDoubleSpinner() + depth_per_pass_item.set_precision(self.decimals) + depth_per_pass_item.setSingleStep(0.1) + depth_per_pass_item.set_range(0.0, 9999.9999) + depth_per_pass_item.set_value(float(data['depthperpass'])) + widget.setCellWidget(row, 9, depth_per_pass_item) + + vtip_dia_item = FCDoubleSpinner() + vtip_dia_item.set_precision(self.decimals) + vtip_dia_item.setSingleStep(0.1) + vtip_dia_item.set_range(0.0, 9999.9999) + vtip_dia_item.set_value(float(data['vtipdia'])) + widget.setCellWidget(row, 10, vtip_dia_item) + + vtip_angle_item = FCDoubleSpinner() + vtip_angle_item.set_precision(self.decimals) + vtip_angle_item.setSingleStep(0.1) + vtip_angle_item.set_range(-360.0, 360.0) + vtip_angle_item.set_value(float(data['vtipangle'])) + widget.setCellWidget(row, 11, vtip_angle_item) + + travelz_item = FCDoubleSpinner() + travelz_item.set_precision(self.decimals) + travelz_item.setSingleStep(0.1) + if self.app.defaults['global_machinist_setting']: + travelz_item.set_range(-9999.9999, 9999.9999) + else: + travelz_item.set_range(0.0000, 9999.9999) + + travelz_item.set_value(float(data['travelz'])) + widget.setCellWidget(row, 12, travelz_item) + + fr_item = FCDoubleSpinner() + fr_item.set_precision(self.decimals) + fr_item.set_range(0.0, 9999.9999) + fr_item.set_value(float(data['feedrate'])) + widget.setCellWidget(row, 13, fr_item) + + frz_item = FCDoubleSpinner() + frz_item.set_precision(self.decimals) + frz_item.set_range(0.0, 9999.9999) + frz_item.set_value(float(data['feedrate_z'])) + widget.setCellWidget(row, 14, frz_item) + + frrapids_item = FCDoubleSpinner() + frrapids_item.set_precision(self.decimals) + frrapids_item.set_range(0.0, 9999.9999) + frrapids_item.set_value(float(data['feedrate_rapid'])) + widget.setCellWidget(row, 15, frrapids_item) + + spindlespeed_item = FCSpinner() + spindlespeed_item.set_range(0, 1000000) + spindlespeed_item.set_value(int(data['spindlespeed'])) + spindlespeed_item.set_step(100) + widget.setCellWidget(row, 16, spindlespeed_item) + + dwell_item = FCCheckBox() + dwell_item.set_value(data['dwell']) + widget.setCellWidget(row, 17, dwell_item) + + dwelltime_item = FCDoubleSpinner() + dwelltime_item.set_precision(self.decimals) + dwelltime_item.set_range(0.0000, 9999.9999) + dwelltime_item.set_value(float(data['dwelltime'])) + widget.setCellWidget(row, 18, dwelltime_item) + + pp_item = FCComboBox() + for item in self.app.preprocessors: + pp_item.addItem(item) + pp_item.set_value(data['ppname_g']) + widget.setCellWidget(row, 19, pp_item) + + ecut_item = FCCheckBox() + ecut_item.set_value(data['extracut']) + widget.setCellWidget(row, 20, ecut_item) + + ecut_length_item = FCDoubleSpinner() + ecut_length_item.set_precision(self.decimals) + ecut_length_item.set_range(0.0000, 9999.9999) + ecut_length_item.set_value(data['extracut_length']) + widget.setCellWidget(row, 21, ecut_length_item) + + toolchange_item = FCCheckBox() + toolchange_item.set_value(data['toolchange']) + widget.setCellWidget(row, 22, toolchange_item) + + toolchangexy_item = QtWidgets.QTableWidgetItem(str(data['toolchangexy']) if data['toolchangexy'] else '') + widget.setItem(row, 23, toolchangexy_item) + + toolchangez_item = FCDoubleSpinner() + toolchangez_item.set_precision(self.decimals) + toolchangez_item.setSingleStep(0.1) + if self.app.defaults['global_machinist_setting']: + toolchangez_item.set_range(-9999.9999, 9999.9999) + else: + toolchangez_item.set_range(0.0000, 9999.9999) + + toolchangez_item.set_value(float(data['toolchangez'])) + widget.setCellWidget(row, 24, toolchangez_item) + + startz_item = QtWidgets.QTableWidgetItem(str(data['startz']) if data['startz'] else '') + widget.setItem(row, 25, startz_item) + + endz_item = FCDoubleSpinner() + endz_item.set_precision(self.decimals) + endz_item.setSingleStep(0.1) + if self.app.defaults['global_machinist_setting']: + endz_item.set_range(-9999.9999, 9999.9999) + else: + endz_item.set_range(0.0000, 9999.9999) + + endz_item.set_value(float(data['endz'])) + widget.setCellWidget(row, 26, endz_item) + + def on_tool_add(self): + """ + Add a tool in the DB Tool Table + :return: None + """ + + default_data = {} + default_data.update({ + "cutz": float(self.app.defaults["geometry_cutz"]), + "multidepth": self.app.defaults["geometry_multidepth"], + "depthperpass": float(self.app.defaults["geometry_depthperpass"]), + "vtipdia": float(self.app.defaults["geometry_vtipdia"]), + "vtipangle": float(self.app.defaults["geometry_vtipangle"]), + "travelz": float(self.app.defaults["geometry_travelz"]), + "feedrate": float(self.app.defaults["geometry_feedrate"]), + "feedrate_z": float(self.app.defaults["geometry_feedrate_z"]), + "feedrate_rapid": float(self.app.defaults["geometry_feedrate_rapid"]), + "spindlespeed": self.app.defaults["geometry_spindlespeed"], + "dwell": self.app.defaults["geometry_dwell"], + "dwelltime": float(self.app.defaults["geometry_dwelltime"]), + "ppname_g": self.app.defaults["geometry_ppname_g"], + "extracut": self.app.defaults["geometry_extracut"], + "extracut_length": float(self.app.defaults["geometry_extracut_length"]), + "toolchange": self.app.defaults["geometry_toolchange"], + "toolchangexy": self.app.defaults["geometry_toolchangexy"], + "toolchangez": float(self.app.defaults["geometry_toolchangez"]), + "startz": self.app.defaults["geometry_startz"], + "endz": float(self.app.defaults["geometry_endz"]) + }) + + dict_elem = {} + dict_elem['name'] = 'new_tool' + if type(self.app.defaults["geometry_cnctooldia"]) == float: + dict_elem['tooldia'] = self.app.defaults["geometry_cnctooldia"] + else: + try: + tools_string = self.app.defaults["geometry_cnctooldia"].split(",") + tools_diameters = [eval(a) for a in tools_string if a != ''] + dict_elem['tooldia'] = tools_diameters[0] if tools_diameters else 0.0 + except Exception as e: + self.app.log.debug("ToolDB.on_tool_add() --> %s" % str(e)) + return + + dict_elem['offset'] = 'Path' + dict_elem['offset_value'] = 0.0 + dict_elem['type'] = 'Rough' + dict_elem['tool_type'] = 'C1' + dict_elem['data'] = default_data + + new_toolid = len(self.db_tool_dict) + 1 + self.db_tool_dict[new_toolid] = deepcopy(dict_elem) + + # add the new entry to the Tools DB table + self.build_db_ui() + self.callback_on_edited() + self.app.inform.emit('[success] %s' % _("Tool added to DB.")) + + def on_tool_copy(self): + """ + Copy a selection of Tools in the Tools DB table + :return: + """ + new_tool_id = self.table_widget.rowCount() + 1 + for model_index in self.table_widget.selectionModel().selectedRows(): + # index = QtCore.QPersistentModelIndex(model_index) + old_tool_id = self.table_widget.item(model_index.row(), 0).text() + new_tool_id += 1 + + for toolid, dict_val in list(self.db_tool_dict.items()): + if int(old_tool_id) == int(toolid): + self.db_tool_dict.update({ + new_tool_id: deepcopy(dict_val) + }) + + self.build_db_ui() + self.callback_on_edited() + self.app.inform.emit('[success] %s' % _("Tool copied from Tools DB.")) + + def on_tool_delete(self): + """ + Delete a selection of Tools in the Tools DB table + :return: + """ + for model_index in self.table_widget.selectionModel().selectedRows(): + # index = QtCore.QPersistentModelIndex(model_index) + toolname_to_remove = self.table_widget.item(model_index.row(), 0).text() + + for toolid, dict_val in list(self.db_tool_dict.items()): + if int(toolname_to_remove) == int(toolid): + # remove from the storage + self.db_tool_dict.pop(toolid, None) + + self.build_db_ui() + self.callback_on_edited() + self.app.inform.emit('[success] %s' % _("Tool removed from Tools DB.")) + + def on_export_tools_db_file(self): + self.app.report_usage("on_export_tools_db_file") + self.app.log.debug("on_export_tools_db_file()") + + date = str(datetime.today()).rpartition('.')[0] + date = ''.join(c for c in date if c not in ':-') + date = date.replace(' ', '_') + + filter__ = "Text File (*.TXT);;All Files (*.*)" + filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Export Tools Database"), + directory='{l_save}/FlatCAM_{n}_{date}'.format( + l_save=str(self.app.get_last_save_folder()), + n=_("Tools_Database"), + date=date), + filter=filter__) + + filename = str(filename) + + if filename == "": + self.app.inform.emit('[WARNING_NOTCL] %s' % _("FlatCAM Tools DB export cancelled.")) + return + else: + try: + f = open(filename, 'w') + f.close() + except PermissionError: + self.app.inform.emit('[WARNING] %s' % + _("Permission denied, saving not possible.\n" + "Most likely another app is holding the file open and not accessible.")) + return + except IOError: + self.app.log.debug('Creating a new Tools DB file ...') + f = open(filename, 'w') + f.close() + except Exception: + e = sys.exc_info()[0] + self.app.log.error("Could not load Tools DB file.") + self.app.log.error(str(e)) + self.app.inform.emit('[ERROR_NOTCL] %s' % _("Could not load Tools DB file.")) + return + + # Save update options + try: + # Save Tools DB in a file + try: + with open(filename, "w") as f: + json.dump(self.db_tool_dict, f, default=to_dict, indent=2) + except Exception as e: + self.app.log.debug("App.on_save_tools_db() --> %s" % str(e)) + self.inform.emit('[ERROR_NOTCL] %s' % _("Failed to write Tools DB to file.")) + return + except Exception: + self.app.inform.emit('[ERROR_NOTCL] %s' % _("Failed to write Tools DB to file.")) + return + + self.app.inform.emit('[success] %s: %s' % (_("Exported Tools DB to"), filename)) + + def on_import_tools_db_file(self): + self.app.report_usage("on_import_tools_db_file") + self.app.log.debug("on_import_tools_db_file()") + + filter__ = "Text File (*.TXT);;All Files (*.*)" + filename, _f = QtWidgets.QFileDialog.getOpenFileName(caption=_("Import FlatCAM Tools DB"), filter=filter__) + + if filename == "": + self.app.inform.emit('[WARNING_NOTCL] %s' % _("FlatCAM Tools DB import cancelled.")) + else: + try: + with open(filename) as f: + tools_in_db = f.read() + except IOError: + self.app.log.error("Could not load Tools DB file.") + self.app.inform.emit('[ERROR_NOTCL] %s' % _("Could not load Tools DB file.")) + return + + try: + self.db_tool_dict = json.loads(tools_in_db) + except Exception: + e = sys.exc_info()[0] + self.app.log.error(str(e)) + self.app.inform.emit('[ERROR] %s' % _("Failed to parse Tools DB file.")) + return + + self.app.inform.emit('[success] %s: %s' % (_("Loaded FlatCAM Tools DB from"), filename)) + self.build_db_ui() + self.callback_on_edited() + + def on_save_tools_db(self, silent=False): + self.app.log.debug("ToolsDB.on_save_button() --> Saving Tools Database to file.") + + filename = self.app.data_path + "/geo_tools_db.FlatDB" + + # Preferences save, update the color of the Tools DB Tab text + for idx in range(self.app.ui.plot_tab_area.count()): + if self.app.ui.plot_tab_area.tabText(idx) == _("Tools Database"): + self.app.ui.plot_tab_area.tabBar.setTabTextColor(idx, QtGui.QColor('black')) + + # Save Tools DB in a file + try: + f = open(filename, "w") + json.dump(self.db_tool_dict, f, default=to_dict, indent=2) + f.close() + except Exception as e: + self.app.log.debug("ToolsDB.on_save_tools_db() --> %s" % str(e)) + self.app.inform.emit('[ERROR_NOTCL] %s' % _("Failed to write Tools DB to file.")) + return + + if not silent: + self.app.inform.emit('[success] %s' % _("Saved Tools DB.")) + + def ui_connect(self): + try: + try: + self.table_widget.itemChanged.disconnect(self.callback_on_edited) + except (TypeError, AttributeError): + pass + self.table_widget.itemChanged.connect(self.callback_on_edited) + except AttributeError: + pass + + for row in range(self.table_widget.rowCount()): + for col in range(self.table_widget.columnCount()): + # ComboBox + try: + try: + self.table_widget.cellWidget(row, col).currentIndexChanged.disconnect(self.callback_on_edited) + except (TypeError, AttributeError): + pass + self.table_widget.cellWidget(row, col).currentIndexChanged.connect(self.callback_on_edited) + except AttributeError: + pass + + # CheckBox + try: + try: + self.table_widget.cellWidget(row, col).toggled.disconnect(self.callback_on_edited) + except (TypeError, AttributeError): + pass + self.table_widget.cellWidget(row, col).toggled.connect(self.callback_on_edited) + except AttributeError: + pass + + # SpinBox, DoubleSpinBox + try: + try: + self.table_widget.cellWidget(row, col).valueChanged.disconnect(self.callback_on_edited) + except (TypeError, AttributeError): + pass + self.table_widget.cellWidget(row, col).valueChanged.connect(self.callback_on_edited) + except AttributeError: + pass + + def ui_disconnect(self): + try: + self.table_widget.itemChanged.disconnect(self.callback_on_edited) + except (TypeError, AttributeError): + pass + + for row in range(self.table_widget.rowCount()): + for col in range(self.table_widget.columnCount()): + # ComboBox + try: + self.table_widget.cellWidget(row, col).currentIndexChanged.disconnect(self.callback_on_edited) + except (TypeError, AttributeError): + pass + + # CheckBox + try: + self.table_widget.cellWidget(row, col).toggled.disconnect(self.callback_on_edited) + except (TypeError, AttributeError): + pass + + # SpinBox, DoubleSpinBox + try: + self.table_widget.cellWidget(row, col).valueChanged.disconnect(self.callback_on_edited) + except (TypeError, AttributeError): + pass + + def callback_on_edited(self): + + # update the dictionary storage self.db_tool_dict + self.db_tool_dict.clear() + dict_elem = {} + default_data = {} for row in range(self.table_widget.rowCount()): new_toolid = row + 1 @@ -1396,7 +2344,7 @@ def color_variant(hex_color, bright_factor=1): bright_factor = 0.0 rgb_hex = [hex_color[x:x + 2] for x in [1, 3, 5]] - new_rgb = list() + new_rgb = [] for hex_value in rgb_hex: # adjust each color channel and turn it into a INT suitable as argument for hex() mod_color = round(int(hex_value, 16) * bright_factor) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 7734e4b5..2c4dcfdc 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -114,7 +114,7 @@ class FlatCAMObj(QtCore.QObject): else: self.shapes = ShapeCollectionLegacy(obj=self, app=self.app, name=name) - self.mark_shapes = dict() + self.mark_shapes = {} self.item = None # Link with project view item @@ -654,7 +654,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber): self.mp = None # dict to store the polygons selected for isolation; key is the shape added to be plotted and value is the poly - self.poly_dict = dict() + self.poly_dict = {} # store the status of grid snapping self.grid_status_memory = None @@ -1331,7 +1331,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber): geo_obj.options["cnctooldia"] = str(self.options["isotooldia"]) geo_obj.tool_type = self.ui.tool_type_radio.get_value().upper() - geo_obj.solid_geometry = list() + geo_obj.solid_geometry = [] # transfer the Cut Z and Vtip and VAngle values in case that we use the V-Shape tool in Gerber UI if self.ui.tool_type_radio.get_value() == 'v': @@ -1372,8 +1372,8 @@ class FlatCAMGerber(FlatCAMObj, Gerber): "startz": self.app.defaults['geometry_startz'] }) - geo_obj.tools = dict() - geo_obj.tools['1'] = dict() + geo_obj.tools = {} + geo_obj.tools['1'] = {} geo_obj.tools.update({ '1': { 'tooldia': float(self.options["isotooldia"]), @@ -1520,8 +1520,8 @@ class FlatCAMGerber(FlatCAMObj, Gerber): "startz": self.app.defaults['geometry_startz'] }) - geo_obj.tools = dict() - geo_obj.tools['1'] = dict() + geo_obj.tools = {} + geo_obj.tools['1'] = {} geo_obj.tools.update({ '1': { 'tooldia': float(self.options["isotooldia"]), @@ -2416,15 +2416,15 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): }) # TODO: Document this. - self.tool_cbs = dict() + self.tool_cbs = {} # dict that holds the object names and the option name # the key is the object name (defines in ObjectUI) for each UI element that is a parameter # particular for a tool and the value is the actual name of the option that the UI element is changing - self.name2option = dict() + self.name2option = {} # default set of data to be added to each tool in self.tools as self.tools[tool]['data'] = self.default_data - self.default_data = dict() + self.default_data = {} # fill in self.default_data values from self.options for opt_key, opt_val in self.app.options.items(): @@ -2629,7 +2629,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): ) # delete the exc_final tools, drills and slots - exc_final.tools = dict() + exc_final.tools = {} exc_final.drills[:] = [] exc_final.slots[:] = [] @@ -2669,7 +2669,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): sorted_tools = sorted(sort, key=lambda t1: t1[1]) tools = [i[0] for i in sorted_tools] - new_options = dict() + new_options = {} for opt in self.options: new_options[opt] = self.options[opt] @@ -3046,7 +3046,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): def on_row_selection_change(self): self.ui_disconnect() - sel_rows = list() + sel_rows = [] sel_items = self.ui.tools_table.selectedItems() for it in sel_items: sel_rows.append(it.row()) @@ -3181,7 +3181,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): # from the columnCount we subtract a value of 1 which represent the last column (plot column) # which does not have text txt = '' - elem = list() + elem = [] for column in range(0, self.ui.tools_table.columnCount() - 1): try: @@ -3940,7 +3940,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): row = 0 tooluid_item = int(self.ui.tools_table.item(row, 0).text()) - temp_tool_data = dict() + temp_tool_data = {} for tooluid_key, tooluid_val in self.tools.items(): if int(tooluid_key) == tooluid_item: @@ -4220,7 +4220,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ui.e_cut_entry.setDisabled(True) # set the text on tool_data_label after loading the object - sel_rows = list() + sel_rows = [] sel_items = self.ui.geo_tools_table.selectedItems() for it in sel_items: sel_rows.append(it.row()) @@ -4285,7 +4285,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ui.cutz_entry.setDisabled(False) # store here the default data for Geometry Data - self.default_data = dict() + self.default_data = {} self.default_data.update({ "name": None, "plot": None, @@ -4603,7 +4603,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ui_disconnect() if row is None: - sel_rows = list() + sel_rows = [] sel_items = self.ui.geo_tools_table.selectedItems() for it in sel_items: sel_rows.append(it.row()) @@ -4684,7 +4684,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): tooldia = float(self.ui.addtool_entry.get_value()) # construct a list of all 'tooluid' in the self.tools - # tool_uid_list = list() + # tool_uid_list = [] # for tooluid_key in self.tools: # tool_uid_list.append(int(tooluid_key)) tool_uid_list = [int(tooluid_key) for tooluid_key in self.tools] @@ -5329,7 +5329,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): table_tools_items = [] if self.multigeo: for x in self.ui.geo_tools_table.selectedItems(): - elem = list() + elem = [] txt = '' for column in range(0, self.ui.geo_tools_table.columnCount()): @@ -5482,7 +5482,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): # this reads the values in the UI form to the self.options dictionary self.read_form() - self.sel_tools = dict() + self.sel_tools = {} try: if self.special_group: @@ -5588,7 +5588,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): # count the tools tool_cnt = 0 - dia_cnc_dict = dict() + dia_cnc_dict = {} # this turn on the FlatCAMCNCJob plot for multiple tools job_obj.multitool = True @@ -5731,7 +5731,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): # count the tools tool_cnt = 0 - dia_cnc_dict = dict() + dia_cnc_dict = {} # this turn on the FlatCAMCNCJob plot for multiple tools job_obj.multitool = True @@ -6065,7 +6065,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): def scale_recursion(geom): if type(geom) is list: - geoms = list() + geoms = [] for local_geom in geom: geoms.append(scale_recursion(local_geom)) return geoms @@ -6142,7 +6142,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): def translate_recursion(geom): if type(geom) is list: - geoms = list() + geoms = [] for local_geom in geom: geoms.append(translate_recursion(local_geom)) return geoms @@ -6419,16 +6419,16 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): """ if geo_final.solid_geometry is None: - geo_final.solid_geometry = list() + geo_final.solid_geometry = [] try: __ = iter(geo_final.solid_geometry) except TypeError: geo_final.solid_geometry = [geo_final.solid_geometry] - new_solid_geometry = list() - new_options = dict() - new_tools = dict() + new_solid_geometry = [] + new_options = {} + new_tools = {} for geo_obj in geo_list: for option in geo_obj.options: @@ -6564,7 +6564,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): It is populated in the FlatCAMGeometry.mtool_gen_cncjob() BEWARE: I rely on the ordered nature of the Python 3.7 dictionary. Things might change ... ''' - self.cnc_tools = dict() + self.cnc_tools = {} ''' This is a dict of dictionaries. Each dict is associated with a tool present in the file. The key is the @@ -6585,7 +6585,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): it's done in camlib.CNCJob.generate_from_excellon_by_tool() BEWARE: I rely on the ordered nature of the Python 3.7 dictionary. Things might change ... ''' - self.exc_cnc_tools = dict() + self.exc_cnc_tools = {} # flag to store if the CNCJob is part of a special group of CNCJob objects that can't be processed by the # default engine of FlatCAM. They generated by some of tools and are special cases of CNCJob objects. diff --git a/README.md b/README.md index 9d3bab8c..3ebe0a9e 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ CAD program, and create G-Code for Isolation routing. - compacted the NCC Tool UI by replacing some Radio buttons with Combo boxes due of too many elements - fixed error in CutOut Tool when trying to create a FreeFrom Cutout out of a Gerber object with the Convex Shape checked +- working on a new type of database 28.02.2020 diff --git a/camlib.py b/camlib.py index a1ca1375..88a62488 100644 --- a/camlib.py +++ b/camlib.py @@ -917,7 +917,7 @@ class Geometry(object): # graceful abort requested by the user raise FlatCAMApp.GracefulException - geo_iso = list() + geo_iso = [] if follow: return geometry @@ -1016,7 +1016,7 @@ class Geometry(object): # Add to object if self.solid_geometry is None: - self.solid_geometry = list() + self.solid_geometry = [] if type(self.solid_geometry) is list: if type(geos) is list: @@ -1031,7 +1031,7 @@ class Geometry(object): geos_text = getsvgtext(svg_root, object_type, units=units) if geos_text is not None: - geos_text_f = list() + geos_text_f = [] if flip: # Change origin to bottom left for i in geos_text: @@ -1100,8 +1100,8 @@ class Geometry(object): scale_factor = 25.4 / dpi if units.lower() == 'mm' else 1 / dpi - geos = list() - unscaled_geos = list() + geos = [] + unscaled_geos = [] with rasterio.open(filename) as src: # if filename.lower().rpartition('.')[-1] == 'bmp': @@ -1148,7 +1148,7 @@ class Geometry(object): # Add to object if self.solid_geometry is None: - self.solid_geometry = list() + self.solid_geometry = [] if type(self.solid_geometry) is list: # self.solid_geometry.append(cascaded_union(geos)) @@ -2694,7 +2694,7 @@ class CNCjob(Geometry): # running this method from a Tcl Command build_tools_in_use_list = False if 'Tools_in_use' not in self.options: - self.options['Tools_in_use'] = list() + self.options['Tools_in_use'] = [] # if the list is empty (either we just added the key or it was already there but empty) signal to build it if not self.options['Tools_in_use']: @@ -2705,7 +2705,7 @@ class CNCjob(Geometry): for to_ol in tools: if to_ol == it[0]: drill_no = 0 - sol_geo = list() + sol_geo = [] for dr in exobj.drills: if dr['tool'] == it[0]: drill_no += 1 @@ -2725,11 +2725,11 @@ class CNCjob(Geometry): except KeyError: z_off = 0 - default_data = dict() + default_data = {} for k, v in list(self.options.items()): default_data[k] = deepcopy(v) - self.exc_cnc_tools[it[1]] = dict() + self.exc_cnc_tools[it[1]] = {} self.exc_cnc_tools[it[1]]['tool'] = it[0] self.exc_cnc_tools[it[1]]['nr_drills'] = drill_no self.exc_cnc_tools[it[1]]['nr_slots'] = slot_no @@ -2747,7 +2747,7 @@ class CNCjob(Geometry): self.app.inform.emit(_("Creating a list of points to drill...")) # Points (Group by tool) - points = dict() + points = {} for drill in exobj.drills: if self.app.abort_flag: # graceful abort requested by the user @@ -2761,7 +2761,7 @@ class CNCjob(Geometry): # log.debug("Found %d drills." % len(points)) - self.gcode = list() + self.gcode = [] self.f_plunge = self.app.defaults["excellon_f_plunge"] self.f_retract = self.app.defaults["excellon_f_retract"] @@ -2786,7 +2786,7 @@ class CNCjob(Geometry): def __init__(self, tool): """Initialize distance array.""" locations = create_data_array(tool) - self.matrix = dict() + self.matrix = {} if locations: size = len(locations) @@ -2813,7 +2813,7 @@ class CNCjob(Geometry): # Create the data. def create_data_array(tool): - loc_list = list() + loc_list = [] if tool not in points: return None @@ -3820,7 +3820,7 @@ class CNCjob(Geometry): '[ERROR_NOTCL] %s' % _("Trying to generate a CNC Job from a Geometry object without solid_geometry.") ) - temp_solid_geometry = list() + temp_solid_geometry = [] def bounds_rec(obj): if type(obj) is list: @@ -4725,8 +4725,8 @@ class CNCjob(Geometry): if geo['kind'][0] == 'C': obj.add_shape(shape=geo['geom'], color=color['C'][1], visible=visible) else: - text = list() - pos = list() + text = [] + pos = [] self.coordinates_type = self.app.defaults["cncjob_coords_type"] if self.coordinates_type == "G90": # For Absolute coordinates type G90 @@ -6156,7 +6156,7 @@ def dict2obj(d): # cells[pIdx].append((startIdx, endIdx)) # # # then, form polygons by storing vertex indices in (counter-)clockwise order -# polys = dict() +# polys = {} # for pIdx, lineIndices_ in cells.items(): # # get a directed graph which contains both directions and arbitrarily follow one of both # directedGraph = lineIndices_ + [(i2, i1) for (i1, i2) in lineIndices_] diff --git a/flatcamEditors/FlatCAMExcEditor.py b/flatcamEditors/FlatCAMExcEditor.py index 1be311ba..b53c0006 100644 --- a/flatcamEditors/FlatCAMExcEditor.py +++ b/flatcamEditors/FlatCAMExcEditor.py @@ -124,7 +124,7 @@ class FCDrillAdd(FCShapeTool): self.draw_app.app.jump_signal.disconnect() def clean_up(self): - self.draw_app.selected = list() + self.draw_app.selected = [] self.draw_app.tools_table_exc.clearSelection() self.draw_app.plot_all() @@ -359,7 +359,7 @@ class FCDrillArray(FCShapeTool): self.draw_app.app.jump_signal.disconnect() def clean_up(self): - self.draw_app.selected = list() + self.draw_app.selected = [] self.draw_app.tools_table_exc.clearSelection() self.draw_app.plot_all() @@ -562,7 +562,7 @@ class FCSlot(FCShapeTool): self.draw_app.app.jump_signal.disconnect() def clean_up(self): - self.draw_app.selected = list() + self.draw_app.selected = [] self.draw_app.tools_table_exc.clearSelection() self.draw_app.plot_all() @@ -888,7 +888,7 @@ class FCSlotArray(FCShapeTool): self.draw_app.app.jump_signal.disconnect() def clean_up(self): - self.draw_app.selected = list() + self.draw_app.selected = [] self.draw_app.tools_table_exc.clearSelection() self.draw_app.plot_all() @@ -1128,7 +1128,7 @@ class FCDrillResize(FCShapeTool): self.draw_app.select_tool("drill_select") def clean_up(self): - self.draw_app.selected = list() + self.draw_app.selected = [] self.draw_app.tools_table_exc.clearSelection() self.draw_app.plot_all() @@ -1268,7 +1268,7 @@ class FCDrillMove(FCShapeTool): return DrawToolUtilityShape(ss_el) def clean_up(self): - self.draw_app.selected = list() + self.draw_app.selected = [] self.draw_app.tools_table_exc.clearSelection() self.draw_app.plot_all() @@ -1323,7 +1323,7 @@ class FCDrillCopy(FCDrillMove): self.draw_app.app.jump_signal.disconnect() def clean_up(self): - self.draw_app.selected = list() + self.draw_app.selected = [] self.draw_app.tools_table_exc.clearSelection() self.draw_app.plot_all() @@ -1371,7 +1371,7 @@ class FCDrillSelect(DrawTool): if mod_key == self.exc_editor_app.app.defaults["global_mselect_key"]: pass else: - self.exc_editor_app.selected = list() + self.exc_editor_app.selected = [] def click_release(self, pos): self.exc_editor_app.tools_table_exc.clearSelection() @@ -1425,7 +1425,7 @@ class FCDrillSelect(DrawTool): else: self.exc_editor_app.selected.append(closest_shape) else: - self.exc_editor_app.selected = list() + self.exc_editor_app.selected = [] self.exc_editor_app.selected.append(closest_shape) # select the diameter of the selected shape in the tool table @@ -2060,31 +2060,31 @@ class FlatCAMExcEditor(QtCore.QObject): self.in_action = False - self.storage_dict = dict() + self.storage_dict = {} - self.current_storage = list() + self.current_storage = [] # build the data from the Excellon point into a dictionary # {tool_dia: [geometry_in_points]} - self.points_edit = dict() - self.slot_points_edit = dict() + self.points_edit = {} + self.slot_points_edit = {} - self.sorted_diameters = list() + self.sorted_diameters = [] - self.new_drills = list() - self.new_tools = dict() - self.new_slots = list() + self.new_drills = [] + self.new_tools = {} + self.new_slots = [] # dictionary to store the tool_row and diameters in Tool_table # it will be updated everytime self.build_ui() is called - self.olddia_newdia = dict() + self.olddia_newdia = {} - self.tool2tooldia = dict() + self.tool2tooldia = {} # this will store the value for the last selected tool, for use after clicking on canvas when the selection # is cleared but as a side effect also the selected tool is cleared self.last_tool_selected = None - self.utility = list() + self.utility = [] # this will flag if the Editor "tools" are launched from key shortcuts (True) or from menu toolbar (False) self.launched_from_shortcuts = False @@ -3069,8 +3069,8 @@ class FlatCAMExcEditor(QtCore.QObject): self.exc_obj = exc_obj exc_obj.visible = False - self.points_edit = dict() - self.slot_points_edit = dict() + self.points_edit = {} + self.slot_points_edit = {} # Set selection tolerance # DrawToolShape.tolerance = fc_excellon.drawing_tolerance * 10 @@ -3353,7 +3353,7 @@ class FlatCAMExcEditor(QtCore.QObject): # add a 'data' dict for each tool with the default values for tool in excellon_obj.tools: - excellon_obj.tools[tool]['data'] = dict() + excellon_obj.tools[tool]['data'] = {} excellon_obj.tools[tool]['data'].update(deepcopy(self.data_defaults)) try: diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index 17027775..a1a13b9b 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -1755,7 +1755,7 @@ class DrawToolShape(object): def translate_recursion(geom): if type(geom) == list: - geoms = list() + geoms = [] for local_geom in geom: geoms.append(translate_recursion(local_geom)) return geoms @@ -1802,7 +1802,7 @@ class DrawToolShape(object): def scale_recursion(geom): if type(geom) == list: - geoms = list() + geoms = [] for local_geom in geom: geoms.append(scale_recursion(local_geom)) return geoms @@ -1972,7 +1972,7 @@ class FCCircle(FCShapeTool): self.draw_app.app.inform.emit('[success] %s' % _("Done. Adding Circle completed.")) def clean_up(self): - self.draw_app.selected = list() + self.draw_app.selected = [] self.draw_app.plot_all() try: @@ -2212,7 +2212,7 @@ class FCArc(FCShapeTool): self.draw_app.app.inform.emit('[success] %s' % _("Done. Arc completed.")) def clean_up(self): - self.draw_app.selected = list() + self.draw_app.selected = [] self.draw_app.plot_all() try: @@ -2285,7 +2285,7 @@ class FCRectangle(FCShapeTool): self.draw_app.app.inform.emit('[success] %s' % _("Done. Rectangle completed.")) def clean_up(self): - self.draw_app.selected = list() + self.draw_app.selected = [] self.draw_app.plot_all() try: @@ -2374,7 +2374,7 @@ class FCPolygon(FCShapeTool): return _("Backtracked one point ...") def clean_up(self): - self.draw_app.selected = list() + self.draw_app.selected = [] self.draw_app.plot_all() try: @@ -2439,7 +2439,7 @@ class FCPath(FCPolygon): return _("Backtracked one point ...") def clean_up(self): - self.draw_app.selected = list() + self.draw_app.selected = [] self.draw_app.plot_all() try: @@ -2573,8 +2573,8 @@ class FCExplode(FCShapeTool): self.make() def make(self): - to_be_deleted_list = list() - lines = list() + to_be_deleted_list = [] + lines = [] for shape in self.draw_app.get_selected(): to_be_deleted_list.append(shape) @@ -2596,7 +2596,7 @@ class FCExplode(FCShapeTool): if shape in self.draw_app.selected: self.draw_app.selected.remove(shape) - geo_list = list() + geo_list = [] for line in lines: geo_list.append(DrawToolShape(line)) self.geometry = geo_list @@ -2604,7 +2604,7 @@ class FCExplode(FCShapeTool): self.draw_app.app.inform.emit('[success] %s...' % _("Done. Polygons exploded into lines.")) def clean_up(self): - self.draw_app.selected = list() + self.draw_app.selected = [] self.draw_app.plot_all() try: @@ -2793,7 +2793,7 @@ class FCMove(FCShapeTool): raise def clean_up(self): - self.draw_app.selected = list() + self.draw_app.selected = [] self.draw_app.plot_all() try: @@ -2821,7 +2821,7 @@ class FCCopy(FCMove): pass def clean_up(self): - self.draw_app.selected = list() + self.draw_app.selected = [] self.draw_app.plot_all() try: @@ -2906,7 +2906,7 @@ class FCText(FCShapeTool): return def clean_up(self): - self.draw_app.selected = list() + self.draw_app.selected = [] self.draw_app.plot_all() try: @@ -3043,7 +3043,7 @@ class FCBuffer(FCShapeTool): pass def clean_up(self): - self.draw_app.selected = list() + self.draw_app.selected = [] self.draw_app.plot_all() try: @@ -3165,7 +3165,7 @@ class FCEraser(FCShapeTool): return DrawToolUtilityShape(geo_list) def clean_up(self): - self.draw_app.selected = list() + self.draw_app.selected = [] self.draw_app.plot_all() try: @@ -3484,7 +3484,7 @@ class FlatCAMGeoEditor(QtCore.QObject): # pass iterator = QtWidgets.QTreeWidgetItemIterator(self.geo_parent) - to_delete = list() + to_delete = [] while iterator.value(): item = iterator.value() to_delete.append(item) @@ -3521,7 +3521,7 @@ class FlatCAMGeoEditor(QtCore.QObject): pass def on_tree_selection_change(self): - self.selected = list() + self.selected = [] selected_tree_items = self.tw.selectedItems() for sel in selected_tree_items: for obj_shape in self.storage.get_objects(): @@ -4528,7 +4528,7 @@ class FlatCAMGeoEditor(QtCore.QObject): log.debug("FlatCAMGeoEditor.on_shape_complete() Error --> %s" % str(e)) return 'fail' - shape_list = list() + shape_list = [] try: for geo in geom: shape_list.append(DrawToolShape(geo)) diff --git a/flatcamEditors/FlatCAMGrbEditor.py b/flatcamEditors/FlatCAMGrbEditor.py index c10c98a1..73fc0afa 100644 --- a/flatcamEditors/FlatCAMGrbEditor.py +++ b/flatcamEditors/FlatCAMGrbEditor.py @@ -288,14 +288,14 @@ class FCPad(FCShapeTool): ap_type = self.draw_app.storage_dict[self.draw_app.last_aperture_selected]['type'] if ap_type == 'C': - new_geo_el = dict() + new_geo_el = {} center = Point([point_x, point_y]) new_geo_el['solid'] = center.buffer(self.radius) new_geo_el['follow'] = center return new_geo_el elif ap_type == 'R': - new_geo_el = dict() + new_geo_el = {} p1 = (point_x - self.half_width, point_y - self.half_height) p2 = (point_x + self.half_width, point_y - self.half_height) @@ -307,7 +307,7 @@ class FCPad(FCShapeTool): return new_geo_el elif ap_type == 'O': geo = [] - new_geo_el = dict() + new_geo_el = {} if self.half_height > self.half_width: p1 = (point_x - self.half_width, point_y - self.half_height + self.half_width) @@ -545,7 +545,7 @@ class FCPadArray(FCShapeTool): ) if static is None or static is False: - new_geo_el = dict() + new_geo_el = {} if 'solid' in geo_el: new_geo_el['solid'] = affinity.translate( @@ -602,14 +602,14 @@ class FCPadArray(FCShapeTool): ap_type = self.draw_app.storage_dict[self.draw_app.last_aperture_selected]['type'] if ap_type == 'C': - new_geo_el = dict() + new_geo_el = {} center = Point([point_x, point_y]) new_geo_el['solid'] = center.buffer(self.radius) new_geo_el['follow'] = center return new_geo_el elif ap_type == 'R': - new_geo_el = dict() + new_geo_el = {} p1 = (point_x - self.half_width, point_y - self.half_height) p2 = (point_x + self.half_width, point_y - self.half_height) @@ -620,7 +620,7 @@ class FCPadArray(FCShapeTool): return new_geo_el elif ap_type == 'O': geo = [] - new_geo_el = dict() + new_geo_el = {} if self.half_height > self.half_width: p1 = (point_x - self.half_width, point_y - self.half_height + self.half_width) @@ -812,7 +812,7 @@ class FCPoligonize(FCShapeTool): except KeyError: self.draw_app.on_aperture_add(apid='0') current_storage = self.draw_app.storage_dict['0']['geometry'] - new_el = dict() + new_el = {} new_el['solid'] = geo new_el['follow'] = geo.exterior self.draw_app.on_grb_shape_complete(current_storage, specific_shape=DrawToolShape(deepcopy(new_el))) @@ -827,7 +827,7 @@ class FCPoligonize(FCShapeTool): self.draw_app.on_aperture_add(apid='0') current_storage = self.draw_app.storage_dict['0']['geometry'] - new_el = dict() + new_el = {} new_el['solid'] = fused_geo new_el['follow'] = fused_geo.exterior self.draw_app.on_grb_shape_complete(current_storage, specific_shape=DrawToolShape(deepcopy(new_el))) @@ -915,7 +915,7 @@ class FCRegion(FCShapeTool): self.gridy_size = float(self.draw_app.app.ui.grid_gap_y_entry.get_value()) def utility_geometry(self, data=None): - new_geo_el = dict() + new_geo_el = {} x = data[0] y = data[1] @@ -983,7 +983,7 @@ class FCRegion(FCShapeTool): self.inter_point = data self.temp_points.append(data) - new_geo_el = dict() + new_geo_el = {} if len(self.temp_points) > 1: try: @@ -1049,7 +1049,7 @@ class FCRegion(FCShapeTool): self.temp_points.append(self.inter_point) self.temp_points.append(data) - new_geo_el = dict() + new_geo_el = {} new_geo_el['solid'] = LinearRing(self.temp_points).buffer(self.buf_val, resolution=int(self.steps_per_circle / 4), @@ -1070,7 +1070,7 @@ class FCRegion(FCShapeTool): else: self.draw_app.last_aperture_selected = '0' - new_geo_el = dict() + new_geo_el = {} new_geo_el['solid'] = Polygon(self.points).buffer(self.buf_val, resolution=int(self.steps_per_circle / 4), @@ -1183,7 +1183,7 @@ class FCTrack(FCRegion): self.draw_app.app.inform.emit(_('Track Mode 1: 45 degrees ...')) def make(self): - new_geo_el = dict() + new_geo_el = {} if len(self.temp_points) == 1: new_geo_el['solid'] = Point(self.temp_points).buffer(self.buf_val, resolution=int(self.steps_per_circle / 4)) @@ -1219,7 +1219,7 @@ class FCTrack(FCRegion): except IndexError: self.points.append(point) - new_geo_el = dict() + new_geo_el = {} if len(self.temp_points) == 1: new_geo_el['solid'] = Point(self.temp_points).buffer(self.buf_val, @@ -1242,7 +1242,7 @@ class FCTrack(FCRegion): def utility_geometry(self, data=None): self.update_grid_info() - new_geo_el = dict() + new_geo_el = {} if len(self.points) == 0: new_geo_el['solid'] = Point(data).buffer(self.buf_val, @@ -1427,10 +1427,10 @@ class FCDisc(FCShapeTool): if '0' in self.draw_app.storage_dict: self.storage_obj = self.draw_app.storage_dict['0']['geometry'] else: - self.draw_app.storage_dict['0'] = dict() + self.draw_app.storage_dict['0'] = {} self.draw_app.storage_dict['0']['type'] = 'C' self.draw_app.storage_dict['0']['size'] = 0.0 - self.draw_app.storage_dict['0']['geometry'] = list() + self.draw_app.storage_dict['0']['geometry'] = [] self.storage_obj = self.draw_app.storage_dict['0']['geometry'] self.draw_app.app.inform.emit(_("Click on Center point ...")) @@ -1453,7 +1453,7 @@ class FCDisc(FCShapeTool): return "" def utility_geometry(self, data=None): - new_geo_el = dict() + new_geo_el = {} if len(self.points) == 1: p1 = self.points[0] p2 = data @@ -1464,7 +1464,7 @@ class FCDisc(FCShapeTool): return None def make(self): - new_geo_el = dict() + new_geo_el = {} try: QtGui.QGuiApplication.restoreOverrideCursor() @@ -1530,10 +1530,10 @@ class FCSemiDisc(FCShapeTool): if '0' in self.draw_app.storage_dict: self.storage_obj = self.draw_app.storage_dict['0']['geometry'] else: - self.draw_app.storage_dict['0'] = dict() + self.draw_app.storage_dict['0'] = {} self.draw_app.storage_dict['0']['type'] = 'C' self.draw_app.storage_dict['0']['size'] = 0.0 - self.draw_app.storage_dict['0']['geometry'] = list() + self.draw_app.storage_dict['0']['geometry'] = [] self.storage_obj = self.draw_app.storage_dict['0']['geometry'] self.steps_per_circ = self.draw_app.app.defaults["gerber_circle_steps"] @@ -1592,10 +1592,10 @@ class FCSemiDisc(FCShapeTool): return _('Mode: Center -> Start -> Stop. Click on Center point ...') def utility_geometry(self, data=None): - new_geo_el = dict() - new_geo_el_pt1 = dict() - new_geo_el_pt2 = dict() - new_geo_el_pt3 = dict() + new_geo_el = {} + new_geo_el_pt1 = {} + new_geo_el_pt2 = {} + new_geo_el_pt3 = {} if len(self.points) == 1: # Show the radius center = self.points[0] @@ -1681,7 +1681,7 @@ class FCSemiDisc(FCShapeTool): def make(self): self.draw_app.current_storage = self.storage_obj - new_geo_el = dict() + new_geo_el = {} if self.mode == 'c12': center = self.points[0] @@ -2031,7 +2031,7 @@ class FCApertureMove(FCShapeTool): for select_shape in self.draw_app.get_selected(): if select_shape in self.current_storage: geometric_data = select_shape.geo - new_geo_el = dict() + new_geo_el = {} if 'solid' in geometric_data: new_geo_el['solid'] = affinity.translate(geometric_data['solid'], xoff=dx, yoff=dy) if 'follow' in geometric_data: @@ -2084,7 +2084,7 @@ class FCApertureMove(FCShapeTool): if len(self.draw_app.get_selected()) <= self.sel_limit: for geom in self.draw_app.get_selected(): - new_geo_el = dict() + new_geo_el = {} if 'solid' in geom.geo: new_geo_el['solid'] = affinity.translate(geom.geo['solid'], xoff=dx, yoff=dy) if 'follow' in geom.geo: @@ -2094,7 +2094,7 @@ class FCApertureMove(FCShapeTool): geo_list.append(deepcopy(new_geo_el)) return DrawToolUtilityShape(geo_list) else: - ss_el = dict() + ss_el = {} ss_el['solid'] = affinity.translate(self.selection_shape, xoff=dx, yoff=dy) return DrawToolUtilityShape(ss_el) @@ -2115,7 +2115,7 @@ class FCApertureCopy(FCApertureMove): for select_shape in self.draw_app.get_selected(): if select_shape in self.current_storage: geometric_data = select_shape.geo - new_geo_el = dict() + new_geo_el = {} if 'solid' in geometric_data: new_geo_el['solid'] = affinity.translate(geometric_data['solid'], xoff=dx, yoff=dy) if 'follow' in geometric_data: @@ -2274,7 +2274,7 @@ class FCEraser(FCShapeTool): dy = data[1] - self.origin[1] for geom in self.draw_app.get_selected(): - new_geo_el = dict() + new_geo_el = {} if 'solid' in geom.geo: new_geo_el['solid'] = affinity.translate(geom.geo['solid'], xoff=dx, yoff=dy) if 'follow' in geom.geo: @@ -2303,7 +2303,7 @@ class FCApertureSelect(DrawTool): self.grb_editor_app.bend_mode = 1 # here store the selected apertures - self.sel_aperture = list() + self.sel_aperture = [] try: self.grb_editor_app.apertures_table.clearSelection() @@ -2922,30 +2922,30 @@ class FlatCAMGrbEditor(QtCore.QObject): # # ## Data self.active_tool = None - self.storage_dict = dict() - self.current_storage = list() + self.storage_dict = {} + self.current_storage = [] - self.sorted_apid = list() + self.sorted_apid = [] - self.new_apertures = dict() - self.new_aperture_macros = dict() + self.new_apertures = {} + self.new_aperture_macros = {} # store here the plot promises, if empty the delayed plot will be activated - self.grb_plot_promises = list() + self.grb_plot_promises = [] # dictionary to store the tool_row and aperture codes in Tool_table # it will be updated everytime self.build_ui() is called - self.olddia_newdia = dict() + self.olddia_newdia = {} - self.tool2tooldia = dict() + self.tool2tooldia = {} # this will store the value for the last selected tool, for use after clicking on canvas when the selection # is cleared but as a side effect also the selected tool is cleared self.last_aperture_selected = None - self.utility = list() + self.utility = [] # this will store the polygons marked by mark are to be perhaps deleted - self.geo_to_delete = list() + self.geo_to_delete = [] # this will flag if the Editor "tools" are launched from key shortcuts (True) or from menu toolbar (False) self.launched_from_shortcuts = False @@ -2957,7 +2957,7 @@ class FlatCAMGrbEditor(QtCore.QObject): self.apdim_lbl.hide() self.apdim_entry.hide() self.gerber_obj = None - self.gerber_obj_options = dict() + self.gerber_obj_options = {} # VisPy Visuals if self.app.is_legacy is False: @@ -3040,7 +3040,7 @@ class FlatCAMGrbEditor(QtCore.QObject): self.pool = self.app.pool # Multiprocessing results - self.results = list() + self.results = [] # A QTimer self.plot_thread = None @@ -3434,7 +3434,7 @@ class FlatCAMGrbEditor(QtCore.QObject): # I've added this flag_del variable because dictionary don't like # having keys deleted while iterating through them - flag_del = list() + flag_del = [] for deleted_tool in self.tool2tooldia: if self.tool2tooldia[deleted_tool] == deleted_aperture: flag_del.append(deleted_tool) @@ -3504,7 +3504,7 @@ class FlatCAMGrbEditor(QtCore.QObject): geometry = [] for geo_el in self.storage_dict[dia_changed]: geometric_data = geo_el.geo - new_geo_el = dict() + new_geo_el = {} if 'solid' in geometric_data: new_geo_el['solid'] = deepcopy(affinity.scale(geometric_data['solid'], xfact=factor, yfact=factor)) @@ -3950,7 +3950,7 @@ class FlatCAMGrbEditor(QtCore.QObject): # ############################################################# ## # list of clear geos that are to be applied to the entire file - global_clear_geo = list() + global_clear_geo = [] # create one big geometry made out of all 'negative' (clear) polygons for apid in app_obj.gerber_obj.apertures: @@ -3969,7 +3969,7 @@ class FlatCAMGrbEditor(QtCore.QObject): # we subtract the big "negative" (clear) geometry from each solid polygon but only the part of # clear geometry that fits inside the solid. otherwise we may loose the solid for apid in app_obj.gerber_obj.apertures: - temp_solid_geometry = list() + temp_solid_geometry = [] if 'geometry' in app_obj.gerber_obj.apertures[apid]: # for elem in self.gerber_obj.apertures[apid]['geometry']: # if 'solid' in elem: @@ -3982,7 +3982,7 @@ class FlatCAMGrbEditor(QtCore.QObject): # solid_geo = solid_geo.difference(clear_geo) # try: # for poly in solid_geo: - # new_elem = dict() + # new_elem = {} # # new_elem['solid'] = poly # if 'clear' in elem: @@ -3991,7 +3991,7 @@ class FlatCAMGrbEditor(QtCore.QObject): # new_elem['follow'] = poly # temp_elem.append(deepcopy(new_elem)) # except TypeError: - # new_elem = dict() + # new_elem = {} # new_elem['solid'] = solid_geo # if 'clear' in elem: # new_elem['clear'] = solid_geo @@ -3999,7 +3999,7 @@ class FlatCAMGrbEditor(QtCore.QObject): # new_elem['follow'] = solid_geo # temp_elem.append(deepcopy(new_elem)) for elem in app_obj.gerber_obj.apertures[apid]['geometry']: - new_elem = dict() + new_elem = {} if 'solid' in elem: solid_geo = elem['solid'] if not global_clear_geo or global_clear_geo.is_empty: @@ -4033,7 +4033,7 @@ class FlatCAMGrbEditor(QtCore.QObject): "FlatCAMGrbEditor.edit_fcgerber.worker_job() Adding processes to pool --> %s" % str(e)) traceback.print_exc() - output = list() + output = [] for p in app_obj.results: output.append(p.get()) @@ -4053,8 +4053,8 @@ class FlatCAMGrbEditor(QtCore.QObject): @staticmethod def add_apertures(aperture_id, aperture_dict): - storage_elem = list() - storage_dict = dict() + storage_elem = [] + storage_dict = {} for k, v in list(aperture_dict.items()): try: @@ -4113,7 +4113,7 @@ class FlatCAMGrbEditor(QtCore.QObject): def update_options(obj): try: if not obj.options: - obj.options = dict() + obj.options = {} obj.options['xmin'] = 0 obj.options['ymin'] = 0 obj.options['xmax'] = 0 @@ -4122,7 +4122,7 @@ class FlatCAMGrbEditor(QtCore.QObject): else: return False except AttributeError: - obj.options = dict() + obj.options = {} return True def new_edited_gerber(self, outname, aperture_storage): @@ -4141,7 +4141,7 @@ class FlatCAMGrbEditor(QtCore.QObject): out_name = outname storage_dict = aperture_storage - local_storage_dict = dict() + local_storage_dict = {} for aperture in storage_dict: if 'geometry' in storage_dict[aperture]: # add aperture only if it has geometry @@ -4162,7 +4162,7 @@ class FlatCAMGrbEditor(QtCore.QObject): grb_obj.apertures[storage_apid][k] = [] for geo_el in val: geometric_data = geo_el.geo - new_geo_el = dict() + new_geo_el = {} if 'solid' in geometric_data: new_geo_el['solid'] = geometric_data['solid'] poly_buffer.append(deepcopy(new_geo_el['solid'])) @@ -4237,12 +4237,12 @@ class FlatCAMGrbEditor(QtCore.QObject): except Exception as e: log.error("Error on Edited object creation: %s" % str(e)) # make sure to clean the previous results - self.results = list() + self.results = [] return self.app.inform.emit('[success] %s' % _("Done. Gerber editing finished.")) # make sure to clean the previous results - self.results = list() + self.results = [] def on_tool_select(self, tool): """ @@ -4952,14 +4952,14 @@ class FlatCAMGrbEditor(QtCore.QObject): def buffer_recursion(geom_el, selection): if type(geom_el) == list: - geoms = list() + geoms = [] for local_geom in geom_el: geoms.append(buffer_recursion(local_geom, selection=selection)) return geoms else: if geom_el in selection: geometric_data = geom_el.geo - buffered_geom_el = dict() + buffered_geom_el = {} if 'solid' in geometric_data: buffered_geom_el['solid'] = geometric_data['solid'].buffer(buff_value, join_style=join_style) if 'follow' in geometric_data: @@ -5008,14 +5008,14 @@ class FlatCAMGrbEditor(QtCore.QObject): def scale_recursion(geom_el, selection): if type(geom_el) == list: - geoms = list() + geoms = [] for local_geom in geom_el: geoms.append(scale_recursion(local_geom, selection=selection)) return geoms else: if geom_el in selection: geometric_data = geom_el.geo - scaled_geom_el = dict() + scaled_geom_el = {} if 'solid' in geometric_data: scaled_geom_el['solid'] = affinity.scale( geometric_data['solid'], scale_factor, scale_factor, origin='center' diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index fd144564..144280c9 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -176,8 +176,34 @@ class FCTree(QtWidgets.QTreeWidget): item.setFont(0, font) return item - def addChild(self, parent, title, column1=None, font=None, font_items=None): + def addParentEditable(self, parent, title, color=None, font=None, font_items=None, editable=False): item = QtWidgets.QTreeWidgetItem(parent) + item.setChildIndicatorPolicy(QtWidgets.QTreeWidgetItem.DontShowIndicator) + if editable: + item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable) + + for t in range(len(title)): + item.setText(t, title[t]) + + if color is not None: + # item.setTextColor(0, color) # PyQt4 + item.setForeground(0, QtGui.QBrush(color)) + + if font and font_items: + try: + for fi in font_items: + item.setFont(fi, font) + except TypeError: + item.setFont(font_items, font) + elif font: + item.setFont(0, font) + return item + + def addChild(self, parent, title, column1=None, font=None, font_items=None, editable=False): + item = QtWidgets.QTreeWidgetItem(parent) + if editable: + item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable) + item.setText(0, str(title[0])) if column1 is not None: item.setText(1, str(title[1])) @@ -2108,7 +2134,7 @@ class FCTable(QtWidgets.QTableWidget): self.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) self.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove) - self.rows_not_for_drag_and_drop = list() + self.rows_not_for_drag_and_drop = [] if protected_rows: try: for r in protected_rows: @@ -2116,7 +2142,7 @@ class FCTable(QtWidgets.QTableWidget): except TypeError: self.rows_not_for_drag_and_drop = [protected_rows] - self.rows_to_move = list() + self.rows_to_move = [] def sizeHint(self): default_hint_size = super(FCTable, self).sizeHint() @@ -2172,7 +2198,7 @@ class FCTable(QtWidgets.QTableWidget): # # ] # self.rows_to_move[:] = [] # for row_index in rows: - # row_items = list() + # row_items = [] # for column_index in range(self.columnCount()): # r_item = self.item(row_index, column_index) # w_item = self.cellWidget(row_index, column_index) @@ -2253,7 +2279,7 @@ class FCTable(QtWidgets.QTableWidget): for _ in range(len(rows)): self.insertRow(targetRow) - rowMapping = dict() # Src row to target row. + rowMapping = {} # Src row to target row. for idx, row in enumerate(rows): if row < targetRow: rowMapping[row] = targetRow + idx diff --git a/flatcamGUI/PlotCanvas.py b/flatcamGUI/PlotCanvas.py index b2fd945a..cfb24039 100644 --- a/flatcamGUI/PlotCanvas.py +++ b/flatcamGUI/PlotCanvas.py @@ -62,7 +62,7 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas): # self.b_line, self.r_line, self.t_line, self.l_line = None, None, None, None self.workspace_line = None - self.pagesize_dict = dict() + self.pagesize_dict = {} self.pagesize_dict.update( { 'A0': (841, 1189), diff --git a/flatcamGUI/PlotCanvasLegacy.py b/flatcamGUI/PlotCanvasLegacy.py index c49d3ebe..ed62d9a0 100644 --- a/flatcamGUI/PlotCanvasLegacy.py +++ b/flatcamGUI/PlotCanvasLegacy.py @@ -158,7 +158,7 @@ class PlotCanvasLegacy(QtCore.QObject): # self.b_line, self.r_line, self.t_line, self.l_line = None, None, None, None self.workspace_line = None - self.pagesize_dict = dict() + self.pagesize_dict = {} self.pagesize_dict.update( { 'A0': (841, 1189), @@ -959,8 +959,8 @@ class ShapeCollectionLegacy: self.app = app self.annotation_job = annotation_job - self._shapes = dict() - self.shape_dict = dict() + self._shapes = {} + self.shape_dict = {} self.shape_id = 0 self._color = None diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index 89dcbfd0..acca4dfc 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -1037,7 +1037,7 @@ class GeneralAPPSetGroupUI(OptionsGroupUI): grid0.addWidget(self.workspace_type_lbl, 7, 0) grid0.addWidget(self.wk_cb, 7, 1) - self.pagesize = dict() + self.pagesize = {} self.pagesize.update( { 'A0': (841, 1189), @@ -6184,7 +6184,7 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI): self.pagesize_combo = FCComboBox() - self.pagesize = dict() + self.pagesize = {} self.pagesize.update( { 'Bounds': None, diff --git a/flatcamParsers/ParseExcellon.py b/flatcamParsers/ParseExcellon.py index 059e09f3..7dc9ee35 100644 --- a/flatcamParsers/ParseExcellon.py +++ b/flatcamParsers/ParseExcellon.py @@ -95,11 +95,11 @@ class Excellon(Geometry): Geometry.__init__(self, geo_steps_per_circle=int(geo_steps_per_circle)) # dictionary to store tools, see above for description - self.tools = dict() + self.tools = {} # list to store the drills, see above for description - self.drills = list() + self.drills = [] # self.slots (list) to store the slots; each is a dictionary - self.slots = list() + self.slots = [] self.source_file = '' @@ -110,8 +110,8 @@ class Excellon(Geometry): self.match_routing_start = None self.match_routing_stop = None - self.num_tools = list() # List for keeping the tools sorted - self.index_per_tool = dict() # Dictionary to store the indexed points for each tool + self.num_tools = [] # List for keeping the tools sorted + self.index_per_tool = {} # Dictionary to store the indexed points for each tool # ## IN|MM -> Units are inherited from Geometry self.units = self.app.defaults['units'] @@ -962,8 +962,8 @@ class Excellon(Geometry): try: # clear the solid_geometry in self.tools for tool in self.tools: - self.tools[tool]['solid_geometry'] = list() - self.tools[tool]['data'] = dict() + self.tools[tool]['solid_geometry'] = [] + self.tools[tool]['data'] = {} for drill in self.drills: # poly = drill['point'].buffer(self.tools[drill['tool']]["C"]/2.0) diff --git a/flatcamParsers/ParseGerber.py b/flatcamParsers/ParseGerber.py index bfa36a4b..54091259 100644 --- a/flatcamParsers/ParseGerber.py +++ b/flatcamParsers/ParseGerber.py @@ -467,7 +467,7 @@ class Gerber(Geometry): # --- Buffered ---- width = self.apertures[last_path_aperture]["size"] - geo_dict = dict() + geo_dict = {} geo_f = LineString(path) if not geo_f.is_empty: follow_buffer.append(geo_f) @@ -486,7 +486,7 @@ class Gerber(Geometry): geo_dict['solid'] = geo_s if last_path_aperture not in self.apertures: - self.apertures[last_path_aperture] = dict() + self.apertures[last_path_aperture] = {} if 'geometry' not in self.apertures[last_path_aperture]: self.apertures[last_path_aperture]['geometry'] = [] self.apertures[last_path_aperture]['geometry'].append(deepcopy(geo_dict)) @@ -677,7 +677,7 @@ class Gerber(Geometry): # --- Buffered --- try: # log.debug("Bare op-code %d." % current_operation_code) - geo_dict = dict() + geo_dict = {} flash = self.create_flash_geometry( Point(current_x, current_y), self.apertures[current_aperture], self.steps_per_circle) @@ -695,7 +695,7 @@ class Gerber(Geometry): geo_dict['solid'] = flash if current_aperture not in self.apertures: - self.apertures[current_aperture] = dict() + self.apertures[current_aperture] = {} if 'geometry' not in self.apertures[current_aperture]: self.apertures[current_aperture]['geometry'] = [] self.apertures[current_aperture]['geometry'].append(deepcopy(geo_dict)) @@ -734,7 +734,7 @@ class Gerber(Geometry): # do nothing because 'R' type moving aperture is none at once pass else: - geo_dict = dict() + geo_dict = {} geo_f = LineString(path) if not geo_f.is_empty: follow_buffer.append(geo_f) @@ -754,7 +754,7 @@ class Gerber(Geometry): geo_dict['solid'] = geo_s if last_path_aperture not in self.apertures: - self.apertures[last_path_aperture] = dict() + self.apertures[last_path_aperture] = {} if 'geometry' not in self.apertures[last_path_aperture]: self.apertures[last_path_aperture]['geometry'] = [] self.apertures[last_path_aperture]['geometry'].append(deepcopy(geo_dict)) @@ -774,7 +774,7 @@ class Gerber(Geometry): if path_length > 1: # Take care of what is left in the path - geo_dict = dict() + geo_dict = {} geo_f = LineString(path) if not geo_f.is_empty: follow_buffer.append(geo_f) @@ -794,7 +794,7 @@ class Gerber(Geometry): geo_dict['solid'] = geo_s if last_path_aperture not in self.apertures: - self.apertures[last_path_aperture] = dict() + self.apertures[last_path_aperture] = {} if 'geometry' not in self.apertures[last_path_aperture]: self.apertures[last_path_aperture]['geometry'] = [] self.apertures[last_path_aperture]['geometry'].append(deepcopy(geo_dict)) @@ -814,7 +814,7 @@ class Gerber(Geometry): self.apertures['0'] = {} self.apertures['0']['type'] = 'REG' self.apertures['0']['size'] = 0.0 - self.apertures['0']['geometry'] = list() + self.apertures['0']['geometry'] = [] # if D02 happened before G37 we now have a path with 1 element only; we have to add the current # geo to the poly_buffer otherwise we loose it @@ -826,7 +826,7 @@ class Gerber(Geometry): if path_length == 1: # this means that the geometry was prepared previously and we just need to add it - geo_dict = dict() + geo_dict = {} if geo_f: if not geo_f.is_empty: follow_buffer.append(geo_f) @@ -863,7 +863,7 @@ class Gerber(Geometry): # For regions we may ignore an aperture that is None # --- Buffered --- - geo_dict = dict() + geo_dict = {} if current_aperture in self.apertures: # the following line breaks loading of Circuit Studio Gerber files # buff_value = float(self.apertures[current_aperture]['size']) / 2.0 @@ -965,7 +965,7 @@ class Gerber(Geometry): maxy = max(path[0][1], path[1][1]) + height / 2 log.debug("Coords: %s - %s - %s - %s" % (minx, miny, maxx, maxy)) - geo_dict = dict() + geo_dict = {} geo_f = Point([current_x, current_y]) follow_buffer.append(geo_f) geo_dict['follow'] = geo_f @@ -982,7 +982,7 @@ class Gerber(Geometry): geo_dict['solid'] = geo_s if current_aperture not in self.apertures: - self.apertures[current_aperture] = dict() + self.apertures[current_aperture] = {} if 'geometry' not in self.apertures[current_aperture]: self.apertures[current_aperture]['geometry'] = [] self.apertures[current_aperture]['geometry'].append(deepcopy(geo_dict)) @@ -1012,7 +1012,7 @@ class Gerber(Geometry): if path_length > 1: geo_s = None - geo_dict = dict() + geo_dict = {} # --- BUFFERED --- # this treats the case when we are storing geometry as paths only if making_region: @@ -1089,7 +1089,7 @@ class Gerber(Geometry): geo_dict['solid'] = geo_s if last_path_aperture not in self.apertures: - self.apertures[last_path_aperture] = dict() + self.apertures[last_path_aperture] = {} if 'geometry' not in self.apertures[last_path_aperture]: self.apertures[last_path_aperture]['geometry'] = [] self.apertures[last_path_aperture]['geometry'].append(deepcopy(geo_dict)) @@ -1115,7 +1115,7 @@ class Gerber(Geometry): if path_length > 1: # --- Buffered ---- - geo_dict = dict() + geo_dict = {} # this treats the case when we are storing geometry as paths geo_f = LineString(path) @@ -1156,7 +1156,7 @@ class Gerber(Geometry): geo_dict['solid'] = geo_s if last_path_aperture not in self.apertures: - self.apertures[last_path_aperture] = dict() + self.apertures[last_path_aperture] = {} if 'geometry' not in self.apertures[last_path_aperture]: self.apertures[last_path_aperture]['geometry'] = [] self.apertures[last_path_aperture]['geometry'].append(deepcopy(geo_dict)) @@ -1167,7 +1167,7 @@ class Gerber(Geometry): # --- BUFFERED --- # Draw the flash # this treats the case when we are storing geometry as paths - geo_dict = dict() + geo_dict = {} geo_flash = Point([linear_x, linear_y]) follow_buffer.append(geo_flash) geo_dict['follow'] = geo_flash @@ -1190,7 +1190,7 @@ class Gerber(Geometry): geo_dict['solid'] = flash if current_aperture not in self.apertures: - self.apertures[current_aperture] = dict() + self.apertures[current_aperture] = {} if 'geometry' not in self.apertures[current_aperture]: self.apertures[current_aperture]['geometry'] = [] self.apertures[current_aperture]['geometry'].append(deepcopy(geo_dict)) @@ -1275,7 +1275,7 @@ class Gerber(Geometry): path_length = 1 if path_length > 1: - geo_dict = dict() + geo_dict = {} if last_path_aperture is None: log.warning("No aperture defined for curent path. (%d)" % line_num) @@ -1303,7 +1303,7 @@ class Gerber(Geometry): geo_dict['solid'] = buffered if last_path_aperture not in self.apertures: - self.apertures[last_path_aperture] = dict() + self.apertures[last_path_aperture] = {} if 'geometry' not in self.apertures[last_path_aperture]: self.apertures[last_path_aperture]['geometry'] = [] self.apertures[last_path_aperture]['geometry'].append(deepcopy(geo_dict)) @@ -1432,7 +1432,7 @@ class Gerber(Geometry): # EOF, create shapely LineString if something still in path # ## --- Buffered --- - geo_dict = dict() + geo_dict = {} # this treats the case when we are storing geometry as paths geo_f = LineString(path) if not geo_f.is_empty: @@ -1454,7 +1454,7 @@ class Gerber(Geometry): geo_dict['solid'] = geo_s if last_path_aperture not in self.apertures: - self.apertures[last_path_aperture] = dict() + self.apertures[last_path_aperture] = {} if 'geometry' not in self.apertures[last_path_aperture]: self.apertures[last_path_aperture]['geometry'] = [] self.apertures[last_path_aperture]['geometry'].append(deepcopy(geo_dict)) @@ -1525,7 +1525,7 @@ class Gerber(Geometry): # it use a filled bounding box polygon to which add clear polygons (negative) to isolate the copper # features if self.app.defaults['gerber_extra_buffering']: - candidate_geo = list() + candidate_geo = [] try: for p in self.solid_geometry: candidate_geo.append(p.buffer(-0.0000001)) @@ -1777,7 +1777,7 @@ class Gerber(Geometry): # Add to object if self.solid_geometry is None: - self.solid_geometry = list() + self.solid_geometry = [] # if type(self.solid_geometry) == list: # if type(geos) == list: @@ -1795,7 +1795,7 @@ class Gerber(Geometry): geos_length = 1 if geos_length == 1: - geo_qrcode = list() + geo_qrcode = [] geo_qrcode.append(Polygon(geos[0].exterior)) for i_el in geos[0].interiors: geo_qrcode.append(Polygon(i_el).buffer(0)) @@ -1822,13 +1822,13 @@ class Gerber(Geometry): self.solid_geometry = [self.solid_geometry] if '0' not in self.apertures: - self.apertures['0'] = dict() + self.apertures['0'] = {} self.apertures['0']['type'] = 'REG' self.apertures['0']['size'] = 0.0 - self.apertures['0']['geometry'] = list() + self.apertures['0']['geometry'] = [] for pol in self.solid_geometry: - new_el = dict() + new_el = {} new_el['solid'] = pol new_el['follow'] = pol.exterior self.apertures['0']['geometry'].append(deepcopy(new_el)) @@ -1917,10 +1917,10 @@ class Gerber(Geometry): # we need to scale the geometry stored in the Gerber apertures, too try: for apid in self.apertures: - new_geometry = list() + new_geometry = [] if 'geometry' in self.apertures[apid]: for geo_el in self.apertures[apid]['geometry']: - new_geo_el = dict() + new_geo_el = {} if 'solid' in geo_el: new_geo_el['solid'] = scale_geom(geo_el['solid']) if 'follow' in geo_el: @@ -2313,10 +2313,10 @@ class Gerber(Geometry): # we need to buffer the geometry stored in the Gerber apertures, too try: for apid in self.apertures: - new_geometry = list() + new_geometry = [] if 'geometry' in self.apertures[apid]: for geo_el in self.apertures[apid]['geometry']: - new_geo_el = dict() + new_geo_el = {} if 'solid' in geo_el: new_geo_el['solid'] = buffer_geom(geo_el['solid']) if 'follow' in geo_el: @@ -2364,10 +2364,10 @@ class Gerber(Geometry): except KeyError: pass - new_geometry = list() + new_geometry = [] if 'geometry' in self.apertures[apid]: for geo_el in self.apertures[apid]['geometry']: - new_geo_el = dict() + new_geo_el = {} if 'follow' in geo_el: new_geo_el['follow'] = geo_el['follow'] size = float(self.apertures[apid]['size']) @@ -2405,7 +2405,7 @@ class Gerber(Geometry): return 'fail' # make the new solid_geometry - new_solid_geo = list() + new_solid_geo = [] for apid in self.apertures: if 'geometry' in self.apertures[apid]: new_solid_geo += [geo_el['solid'] for geo_el in self.apertures[apid]['geometry']] diff --git a/flatcamParsers/ParseHPGL2.py b/flatcamParsers/ParseHPGL2.py index 546825c4..ead2a67c 100644 --- a/flatcamParsers/ParseHPGL2.py +++ b/flatcamParsers/ParseHPGL2.py @@ -49,9 +49,9 @@ class HPGL2: self.units = 'MM' # storage for the tools - self.tools = dict() + self.tools = {} - self.default_data = dict() + self.default_data = {} self.default_data.update({ "name": '_ncc', "plot": self.app.defaults["geometry_plot"], @@ -153,7 +153,7 @@ class HPGL2: """ # Coordinates of the current path, each is [x, y] - path = list() + path = [] geo_buffer = [] @@ -209,7 +209,7 @@ class HPGL2: match = self.sp_re.search(gline) if match: tool = match.group(1) - # self.tools[tool] = dict() + # self.tools[tool] = {} self.tools.update({ tool: { 'tooldia': float('%.*f' % diff --git a/flatcamParsers/ParseSVG.py b/flatcamParsers/ParseSVG.py index 2aa5db2d..edff621f 100644 --- a/flatcamParsers/ParseSVG.py +++ b/flatcamParsers/ParseSVG.py @@ -135,7 +135,7 @@ def path2shapely(path, object_type, res=1.0): try: geo_element = Polygon(rings[0], rings[1:]) except Exception: - coords = list() + coords = [] for line in rings: coords.append(line.coords[0]) coords.append(line.coords[1]) @@ -305,7 +305,7 @@ def getsvggeo(node, object_type, root=None): root = node kind = re.search('(?:\{.*\})?(.*)$', node.tag).group(1) - geo = list() + geo = [] # Recurse if len(node) > 0: diff --git a/flatcamTools/ToolAlignObjects.py b/flatcamTools/ToolAlignObjects.py index 9cc4c196..1ffbe1e5 100644 --- a/flatcamTools/ToolAlignObjects.py +++ b/flatcamTools/ToolAlignObjects.py @@ -206,7 +206,7 @@ class AlignObjects(FlatCAMTool): self.target_obj = None # here store the alignment points - self.clicked_points = list() + self.clicked_points = [] self.align_type = None @@ -249,7 +249,7 @@ class AlignObjects(FlatCAMTool): def set_tool_ui(self): self.reset_fields() - self.clicked_points = list() + self.clicked_points = [] self.target_obj = None self.aligned_obj = None self.aligner_obj = None @@ -373,7 +373,7 @@ class AlignObjects(FlatCAMTool): elif event.button == right_button and self.app.event_is_dragging is False: self.reset_color() - self.clicked_points = list() + self.clicked_points = [] self.disconnect_cal_events() self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled by user request.")) diff --git a/flatcamTools/ToolCalibration.py b/flatcamTools/ToolCalibration.py index ae83edb6..6f9b015c 100644 --- a/flatcamTools/ToolCalibration.py +++ b/flatcamTools/ToolCalibration.py @@ -926,7 +926,7 @@ class ToolCalibration(FlatCAMTool): self.disconnect_cal_events() def reset_calibration_points(self): - self.click_points = list() + self.click_points = [] self.bottom_left_coordx_tgt.set_value('') self.bottom_left_coordy_tgt.set_value('') diff --git a/flatcamTools/ToolCopperThieving.py b/flatcamTools/ToolCopperThieving.py index aa9ab7f1..295aed5a 100644 --- a/flatcamTools/ToolCopperThieving.py +++ b/flatcamTools/ToolCopperThieving.py @@ -494,11 +494,11 @@ class ToolCopperThieving(FlatCAMTool): # Objects involved in Copper thieving self.grb_object = None self.ref_obj = None - self.sel_rect = list() + self.sel_rect = [] self.sm_object = None # store the flattened geometry here: - self.flat_geometry = list() + self.flat_geometry = [] # Events ID self.mr = None @@ -517,7 +517,7 @@ class ToolCopperThieving(FlatCAMTool): self.geo_steps_per_circle = 128 # Thieving geometry storage - self.new_solid_geometry = list() + self.new_solid_geometry = [] # Robber bar geometry storage self.robber_geo = None @@ -681,7 +681,7 @@ class ToolCopperThieving(FlatCAMTool): break if aperture_found: - geo_elem = dict() + geo_elem = {} geo_elem['solid'] = self.robber_geo geo_elem['follow'] = self.robber_line self.grb_object.apertures[aperture_found]['geometry'].append(deepcopy(geo_elem)) @@ -692,19 +692,19 @@ class ToolCopperThieving(FlatCAMTool): else: new_apid = '10' - self.grb_object.apertures[new_apid] = dict() + self.grb_object.apertures[new_apid] = {} self.grb_object.apertures[new_apid]['type'] = 'C' self.grb_object.apertures[new_apid]['size'] = self.rb_thickness - self.grb_object.apertures[new_apid]['geometry'] = list() + self.grb_object.apertures[new_apid]['geometry'] = [] - geo_elem = dict() + geo_elem = {} geo_elem['solid'] = self.robber_geo geo_elem['follow'] = self.robber_line self.grb_object.apertures[new_apid]['geometry'].append(deepcopy(geo_elem)) geo_obj = self.grb_object.solid_geometry if isinstance(geo_obj, MultiPolygon): - s_list = list() + s_list = [] for pol in geo_obj.geoms: s_list.append(pol) s_list.append(self.robber_geo) @@ -1127,7 +1127,7 @@ class ToolCopperThieving(FlatCAMTool): if fill_type == 'dot' or fill_type == 'square': # build the MultiPolygon of dots/squares that will fill the entire bounding box - thieving_list = list() + thieving_list = [] if fill_type == 'dot': radius = dot_dia / 2.0 @@ -1169,7 +1169,7 @@ class ToolCopperThieving(FlatCAMTool): except TypeError: thieving_box_geo = [thieving_box_geo] - thieving_geo = list() + thieving_geo = [] for dot_geo in thieving_box_geo: for geo_t in app_obj.new_solid_geometry: if dot_geo.within(geo_t): @@ -1212,7 +1212,7 @@ class ToolCopperThieving(FlatCAMTool): app_obj.app.proc_container.update_view_text(' %s' % _("Buffering")) outline_geometry = unary_union(outline_geometry) - outline_line = list() + outline_line = [] try: for geo_o in outline_geometry: outline_line.append( @@ -1238,7 +1238,7 @@ class ToolCopperThieving(FlatCAMTool): ) bx0, by0, bx1, by1 = box_outline_geo.bounds - thieving_lines_geo = list() + thieving_lines_geo = [] new_x = bx0 new_y = by0 while new_x <= x1 - half_thick_line: @@ -1258,7 +1258,7 @@ class ToolCopperThieving(FlatCAMTool): new_y += line_size + line_spacing # merge everything together - diff_lines_geo = list() + diff_lines_geo = [] for line_poly in thieving_lines_geo: rest_line = line_poly.difference(clearance_geometry) diff_lines_geo.append(rest_line) @@ -1271,8 +1271,8 @@ class ToolCopperThieving(FlatCAMTool): geo_list = list(app_obj.grb_object.solid_geometry.geoms) if '0' not in app_obj.grb_object.apertures: - app_obj.grb_object.apertures['0'] = dict() - app_obj.grb_object.apertures['0']['geometry'] = list() + app_obj.grb_object.apertures['0'] = {} + app_obj.grb_object.apertures['0']['geometry'] = [] app_obj.grb_object.apertures['0']['type'] = 'REG' app_obj.grb_object.apertures['0']['size'] = 0.0 @@ -1282,7 +1282,7 @@ class ToolCopperThieving(FlatCAMTool): geo_list.append(poly) # append into the '0' aperture - geo_elem = dict() + geo_elem = {} geo_elem['solid'] = poly geo_elem['follow'] = poly.exterior app_obj.grb_object.apertures['0']['geometry'].append(deepcopy(geo_elem)) @@ -1291,7 +1291,7 @@ class ToolCopperThieving(FlatCAMTool): geo_list.append(app_obj.new_solid_geometry) # append into the '0' aperture - geo_elem = dict() + geo_elem = {} geo_elem['solid'] = app_obj.new_solid_geometry geo_elem['follow'] = app_obj.new_solid_geometry.exterior app_obj.grb_object.apertures['0']['geometry'].append(deepcopy(geo_elem)) @@ -1350,7 +1350,7 @@ class ToolCopperThieving(FlatCAMTool): # if the clearance is negative apply it to the original soldermask too if ppm_clearance < 0: - temp_geo_list = list() + temp_geo_list = [] for geo in geo_list: temp_geo_list.append(geo.buffer(ppm_clearance)) geo_list = temp_geo_list @@ -1372,11 +1372,11 @@ class ToolCopperThieving(FlatCAMTool): def obj_init(grb_obj, app_obj): grb_obj.multitool = False - grb_obj.source_file = list() + grb_obj.source_file = [] grb_obj.multigeo = False grb_obj.follow = False - grb_obj.apertures = dict() - grb_obj.solid_geometry = list() + grb_obj.apertures = {} + grb_obj.solid_geometry = [] # try: # grb_obj.options['xmin'] = 0 @@ -1389,8 +1389,8 @@ class ToolCopperThieving(FlatCAMTool): # if we have copper thieving geometry, add it if thieving_solid_geo: if '0' not in grb_obj.apertures: - grb_obj.apertures['0'] = dict() - grb_obj.apertures['0']['geometry'] = list() + grb_obj.apertures['0'] = {} + grb_obj.apertures['0']['geometry'] = [] grb_obj.apertures['0']['type'] = 'REG' grb_obj.apertures['0']['size'] = 0.0 @@ -1402,7 +1402,7 @@ class ToolCopperThieving(FlatCAMTool): geo_list.append(poly_b) # append into the '0' aperture - geo_elem = dict() + geo_elem = {} geo_elem['solid'] = poly_b geo_elem['follow'] = poly_b.exterior grb_obj.apertures['0']['geometry'].append(deepcopy(geo_elem)) @@ -1411,7 +1411,7 @@ class ToolCopperThieving(FlatCAMTool): geo_list.append(thieving_solid_geo.buffer(ppm_clearance)) # append into the '0' aperture - geo_elem = dict() + geo_elem = {} geo_elem['solid'] = thieving_solid_geo.buffer(ppm_clearance) geo_elem['follow'] = thieving_solid_geo.buffer(ppm_clearance).exterior grb_obj.apertures['0']['geometry'].append(deepcopy(geo_elem)) @@ -1425,7 +1425,7 @@ class ToolCopperThieving(FlatCAMTool): break if aperture_found: - geo_elem = dict() + geo_elem = {} geo_elem['solid'] = robber_solid_geo geo_elem['follow'] = robber_line grb_obj.apertures[aperture_found]['geometry'].append(deepcopy(geo_elem)) @@ -1437,12 +1437,12 @@ class ToolCopperThieving(FlatCAMTool): else: new_apid = '10' - grb_obj.apertures[new_apid] = dict() + grb_obj.apertures[new_apid] = {} grb_obj.apertures[new_apid]['type'] = 'C' grb_obj.apertures[new_apid]['size'] = rb_thickness + ppm_clearance - grb_obj.apertures[new_apid]['geometry'] = list() + grb_obj.apertures[new_apid]['geometry'] = [] - geo_elem = dict() + geo_elem = {} geo_elem['solid'] = robber_solid_geo.buffer(ppm_clearance) geo_elem['follow'] = Polygon(robber_line).buffer(ppm_clearance / 2.0).exterior grb_obj.apertures[new_apid]['geometry'].append(deepcopy(geo_elem)) @@ -1510,7 +1510,7 @@ class ToolCopperThieving(FlatCAMTool): self.grb_object = None self.sm_object = None self.ref_obj = None - self.sel_rect = list() + self.sel_rect = [] # Events ID self.mr = None diff --git a/flatcamTools/ToolCutOut.py b/flatcamTools/ToolCutOut.py index 87ebafc3..0033d149 100644 --- a/flatcamTools/ToolCutOut.py +++ b/flatcamTools/ToolCutOut.py @@ -521,7 +521,7 @@ class CutOut(FlatCAMTool): gapsize = gapsize / 2 + (dia / 2) def geo_init(geo_obj, app_obj): - solid_geo = list() + solid_geo = [] if isinstance(cutout_obj, FlatCAMGerber): if isinstance(cutout_obj.solid_geometry, list): @@ -639,7 +639,7 @@ class CutOut(FlatCAMTool): cutout_obj.plot() self.app.inform.emit('[success] %s' % _("Any form CutOut operation finished.")) - self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab) + # self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab) self.app.should_we_save = True def on_rectangular_cutout(self): @@ -798,7 +798,7 @@ class CutOut(FlatCAMTool): # cutout_obj.plot() self.app.inform.emit('[success] %s' % _("Any form CutOut operation finished.")) - self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab) + # self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab) self.app.should_we_save = True def on_manual_gap_click(self): diff --git a/flatcamTools/ToolDblSided.py b/flatcamTools/ToolDblSided.py index b7c975d9..56602125 100644 --- a/flatcamTools/ToolDblSided.py +++ b/flatcamTools/ToolDblSided.py @@ -606,10 +606,10 @@ class DblSidedTool(FlatCAMTool): _("No value or wrong format in Drill Dia entry. Add it and retry.")) return - tools = dict() - tools["1"] = dict() + tools = {} + tools["1"] = {} tools["1"]["C"] = dia - tools["1"]['solid_geometry'] = list() + tools["1"]['solid_geometry'] = [] # holes = self.alignment_holes.get_value() holes = eval('[{}]'.format(self.alignment_holes.text())) @@ -618,7 +618,7 @@ class DblSidedTool(FlatCAMTool): "Add them and retry.")) return - drills = list() + drills = [] for hole in holes: point = Point(hole) diff --git a/flatcamTools/ToolDistance.py b/flatcamTools/ToolDistance.py index 84a6c547..59f6f9d4 100644 --- a/flatcamTools/ToolDistance.py +++ b/flatcamTools/ToolDistance.py @@ -433,7 +433,7 @@ class Distance(FlatCAMTool): pos = (center_pt.x, center_pt.y) elif self.original_call_source == 'grb_editor': - clicked_pads = list() + clicked_pads = [] for storage in self.app.grb_editor.storage_dict: try: for shape_stored in self.app.grb_editor.storage_dict[storage]['geometry']: diff --git a/flatcamTools/ToolExtractDrills.py b/flatcamTools/ToolExtractDrills.py index 5a693300..287a1571 100644 --- a/flatcamTools/ToolExtractDrills.py +++ b/flatcamTools/ToolExtractDrills.py @@ -423,8 +423,8 @@ class ToolExtractDrills(FlatCAMTool): prop_factor = self.factor_entry.get_value() / 100.0 - drills = list() - tools = dict() + drills = [] + tools = {} selection_index = self.gerber_object_combo.currentIndex() model_index = self.app.collection.index(selection_index, 0, self.gerber_object_combo.rootModelIndex()) @@ -469,7 +469,7 @@ class ToolExtractDrills(FlatCAMTool): if 'follow' in geo_el and isinstance(geo_el['follow'], Point): drills.append({"point": geo_el['follow'], "tool": "1"}) if 'solid_geometry' not in tools["1"]: - tools["1"]['solid_geometry'] = list() + tools["1"]['solid_geometry'] = [] else: tools["1"]['solid_geometry'].append(geo_el['follow']) @@ -548,7 +548,7 @@ class ToolExtractDrills(FlatCAMTool): drills.append({"point": geo_el['follow'], "tool": tool_in_drills}) if 'solid_geometry' not in tools[tool_in_drills]: - tools[tool_in_drills]['solid_geometry'] = list() + tools[tool_in_drills]['solid_geometry'] = [] else: tools[tool_in_drills]['solid_geometry'].append(geo_el['follow']) @@ -633,7 +633,7 @@ class ToolExtractDrills(FlatCAMTool): drills.append({"point": geo_el['follow'], "tool": tool_in_drills}) if 'solid_geometry' not in tools[tool_in_drills]: - tools[tool_in_drills]['solid_geometry'] = list() + tools[tool_in_drills]['solid_geometry'] = [] else: tools[tool_in_drills]['solid_geometry'].append(geo_el['follow']) diff --git a/flatcamTools/ToolFiducials.py b/flatcamTools/ToolFiducials.py index 33113dac..342f1d5c 100644 --- a/flatcamTools/ToolFiducials.py +++ b/flatcamTools/ToolFiducials.py @@ -333,7 +333,7 @@ class ToolFiducials(FlatCAMTool): self.sm_obj_set = set() # store the flattened geometry here: - self.flat_geometry = list() + self.flat_geometry = [] # Events ID self.mr = None @@ -353,7 +353,7 @@ class ToolFiducials(FlatCAMTool): self.sec_position = None self.geo_steps_per_circle = 128 - self.click_points = list() + self.click_points = [] # SIGNALS self.add_cfid_button.clicked.connect(self.add_fiducials) @@ -404,7 +404,7 @@ class ToolFiducials(FlatCAMTool): self.fid_type_radio.set_value(self.app.defaults["tools_fiducials_type"]) self.line_thickness_entry.set_value(float(self.app.defaults["tools_fiducials_line_thickness"])) - self.click_points = list() + self.click_points = [] self.bottom_left_coords_entry.set_value('') self.top_right_coords_entry.set_value('') self.sec_points_coords_entry.set_value('') @@ -429,7 +429,7 @@ class ToolFiducials(FlatCAMTool): :return: None """ if val == 'auto': - self.click_points = list() + self.click_points = [] try: self.disconnect_event_handlers() @@ -451,7 +451,7 @@ class ToolFiducials(FlatCAMTool): self.sec_position = self.pos_radio.get_value() fid_type = self.fid_type_radio.get_value() - self.click_points = list() + self.click_points = [] # get the Gerber object on which the Fiducial will be inserted selection_index = self.grb_object_combo.currentIndex() @@ -547,7 +547,7 @@ class ToolFiducials(FlatCAMTool): if aperture_found: for geo in geo_list: - dict_el = dict() + dict_el = {} dict_el['follow'] = geo.centroid dict_el['solid'] = geo g_obj.apertures[aperture_found]['geometry'].append(deepcopy(dict_el)) @@ -558,18 +558,18 @@ class ToolFiducials(FlatCAMTool): else: new_apid = '10' - g_obj.apertures[new_apid] = dict() + g_obj.apertures[new_apid] = {} g_obj.apertures[new_apid]['type'] = 'C' g_obj.apertures[new_apid]['size'] = fid_size - g_obj.apertures[new_apid]['geometry'] = list() + g_obj.apertures[new_apid]['geometry'] = [] for geo in geo_list: - dict_el = dict() + dict_el = {} dict_el['follow'] = geo.centroid dict_el['solid'] = geo g_obj.apertures[new_apid]['geometry'].append(deepcopy(dict_el)) - s_list = list() + s_list = [] if g_obj.solid_geometry: try: for poly in g_obj.solid_geometry: @@ -580,7 +580,7 @@ class ToolFiducials(FlatCAMTool): s_list += geo_list g_obj.solid_geometry = MultiPolygon(s_list) elif fid_type == 'cross': - geo_list = list() + geo_list = [] for pt in points_list: x = pt[0] @@ -599,7 +599,7 @@ class ToolFiducials(FlatCAMTool): aperture_found = ap_id break - geo_buff_list = list() + geo_buff_list = [] if aperture_found: for geo in geo_list: geo_buff_h = geo[0].buffer(line_thickness / 2.0) @@ -607,7 +607,7 @@ class ToolFiducials(FlatCAMTool): geo_buff_list.append(geo_buff_h) geo_buff_list.append(geo_buff_v) - dict_el = dict() + dict_el = {} dict_el['follow'] = geo_buff_h.centroid dict_el['solid'] = geo_buff_h g_obj.apertures[aperture_found]['geometry'].append(deepcopy(dict_el)) @@ -621,10 +621,10 @@ class ToolFiducials(FlatCAMTool): else: new_apid = '10' - g_obj.apertures[new_apid] = dict() + g_obj.apertures[new_apid] = {} g_obj.apertures[new_apid]['type'] = 'C' g_obj.apertures[new_apid]['size'] = line_thickness - g_obj.apertures[new_apid]['geometry'] = list() + g_obj.apertures[new_apid]['geometry'] = [] for geo in geo_list: geo_buff_h = geo[0].buffer(line_thickness / 2.0) @@ -632,7 +632,7 @@ class ToolFiducials(FlatCAMTool): geo_buff_list.append(geo_buff_h) geo_buff_list.append(geo_buff_v) - dict_el = dict() + dict_el = {} dict_el['follow'] = geo_buff_h.centroid dict_el['solid'] = geo_buff_h g_obj.apertures[new_apid]['geometry'].append(deepcopy(dict_el)) @@ -640,7 +640,7 @@ class ToolFiducials(FlatCAMTool): dict_el['solid'] = geo_buff_v g_obj.apertures[new_apid]['geometry'].append(deepcopy(dict_el)) - s_list = list() + s_list = [] if g_obj.solid_geometry: try: for poly in g_obj.solid_geometry: @@ -655,7 +655,7 @@ class ToolFiducials(FlatCAMTool): g_obj.solid_geometry = MultiPolygon(s_list) else: # chess pattern fiducial type - geo_list = list() + geo_list = [] def make_square_poly(center_pt, side_size): half_s = side_size / 2 @@ -684,12 +684,12 @@ class ToolFiducials(FlatCAMTool): aperture_found = ap_id break - geo_buff_list = list() + geo_buff_list = [] if aperture_found: for geo in geo_list: geo_buff_list.append(geo) - dict_el = dict() + dict_el = {} dict_el['follow'] = geo.centroid dict_el['solid'] = geo g_obj.apertures[aperture_found]['geometry'].append(deepcopy(dict_el)) @@ -700,22 +700,22 @@ class ToolFiducials(FlatCAMTool): else: new_apid = '10' - g_obj.apertures[new_apid] = dict() + g_obj.apertures[new_apid] = {} g_obj.apertures[new_apid]['type'] = 'R' g_obj.apertures[new_apid]['size'] = new_ap_size g_obj.apertures[new_apid]['width'] = fid_size g_obj.apertures[new_apid]['height'] = fid_size - g_obj.apertures[new_apid]['geometry'] = list() + g_obj.apertures[new_apid]['geometry'] = [] for geo in geo_list: geo_buff_list.append(geo) - dict_el = dict() + dict_el = {} dict_el['follow'] = geo.centroid dict_el['solid'] = geo g_obj.apertures[new_apid]['geometry'].append(deepcopy(dict_el)) - s_list = list() + s_list = [] if g_obj.solid_geometry: try: for poly in g_obj.solid_geometry: diff --git a/flatcamTools/ToolFilm.py b/flatcamTools/ToolFilm.py index 4772d0ad..bf3af64a 100644 --- a/flatcamTools/ToolFilm.py +++ b/flatcamTools/ToolFilm.py @@ -434,7 +434,7 @@ class Film(FlatCAMTool): self.pagesize_combo = FCComboBox() - self.pagesize = dict() + self.pagesize = {} self.pagesize.update( { 'Bounds': None, @@ -786,7 +786,7 @@ class Film(FlatCAMTool): punch_size = float(self.punch_size_spinner.get_value()) - punching_geo = list() + punching_geo = [] for apid in film_obj.apertures: if film_obj.apertures[apid]['type'] == 'C': if punch_size >= float(film_obj.apertures[apid]['size']): diff --git a/flatcamTools/ToolImage.py b/flatcamTools/ToolImage.py index 3e8f2d57..8ac9ed89 100644 --- a/flatcamTools/ToolImage.py +++ b/flatcamTools/ToolImage.py @@ -223,7 +223,7 @@ class ToolImage(FlatCAMTool): :type type_of_obj: str :return: None """ - mask = list() + mask = [] self.app.log.debug("on_file_importimage()") _filter = "Image Files(*.BMP *.PNG *.JPG *.JPEG);;" \ diff --git a/flatcamTools/ToolInvertGerber.py b/flatcamTools/ToolInvertGerber.py index c4338b79..4d8e62c8 100644 --- a/flatcamTools/ToolInvertGerber.py +++ b/flatcamTools/ToolInvertGerber.py @@ -227,19 +227,19 @@ class ToolInvertGerber(FlatCAMTool): for poly in grb_obj.solid_geometry: new_solid_geometry = new_solid_geometry.difference(poly) - new_options = dict() + new_options = {} for opt in grb_obj.options: new_options[opt] = deepcopy(grb_obj.options[opt]) - new_apertures = dict() + new_apertures = {} # for apid, val in grb_obj.apertures.items(): - # new_apertures[apid] = dict() + # new_apertures[apid] = {} # for key in val: # if key == 'geometry': - # new_apertures[apid]['geometry'] = list() + # new_apertures[apid]['geometry'] = [] # for elem in val['geometry']: - # geo_elem = dict() + # geo_elem = {} # if 'follow' in elem: # try: # geo_elem['clear'] = elem['follow'].buffer(val['size'] / 2.0).exterior @@ -260,19 +260,19 @@ class ToolInvertGerber(FlatCAMTool): # new_apertures[apid][key] = deepcopy(val[key]) if '0' not in new_apertures: - new_apertures['0'] = dict() + new_apertures['0'] = {} new_apertures['0']['type'] = 'C' new_apertures['0']['size'] = 0.0 - new_apertures['0']['geometry'] = list() + new_apertures['0']['geometry'] = [] try: for poly in new_solid_geometry: - new_el = dict() + new_el = {} new_el['solid'] = poly new_el['follow'] = poly.exterior new_apertures['0']['geometry'].append(new_el) except TypeError: - new_el = dict() + new_el = {} new_el['solid'] = new_solid_geometry new_el['follow'] = new_solid_geometry.exterior new_apertures['0']['geometry'].append(new_el) diff --git a/flatcamTools/ToolNCC.py b/flatcamTools/ToolNCC.py index 021788eb..4b7c7253 100644 --- a/flatcamTools/ToolNCC.py +++ b/flatcamTools/ToolNCC.py @@ -625,22 +625,22 @@ class NonCopperClear(FlatCAMTool, Gerber): # ########################## VARIABLES ######################################## # ############################################################################# self.units = '' - self.ncc_tools = dict() + self.ncc_tools = {} self.tooluid = 0 # store here the default data for Geometry Data - self.default_data = dict() + self.default_data = {} self.obj_name = "" self.ncc_obj = None - self.sel_rect = list() + self.sel_rect = [] self.bound_obj_name = "" self.bound_obj = None - self.ncc_dia_list = list() - self.iso_dia_list = list() + self.ncc_dia_list = [] + self.iso_dia_list = [] self.has_offset = None self.o_name = None self.overlap = None @@ -656,10 +656,10 @@ class NonCopperClear(FlatCAMTool, Gerber): self.mr = None # store here solid_geometry when there are tool with isolation job - self.solid_geometry = list() + self.solid_geometry = [] self.select_method = None - self.tool_type_item_options = list() + self.tool_type_item_options = [] self.grb_circle_steps = int(self.app.defaults["gerber_circle_steps"]) @@ -832,7 +832,7 @@ class NonCopperClear(FlatCAMTool, Gerber): row = 0 tooluid_item = int(self.tools_table.item(row, 3).text()) - temp_tool_data = dict() + temp_tool_data = {} for tooluid_key, tooluid_val in self.ncc_tools.items(): if int(tooluid_key) == tooluid_item: @@ -1143,7 +1143,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.ui_connect() # set the text on tool_data_label after loading the object - sel_rows = list() + sel_rows = [] sel_items = self.tools_table.selectedItems() for it in sel_items: sel_rows.append(it.row()) @@ -1550,9 +1550,9 @@ class NonCopperClear(FlatCAMTool, Gerber): return # use the selected tools in the tool table; get diameters for non-copper clear - self.iso_dia_list = list() + self.iso_dia_list = [] # use the selected tools in the tool table; get diameters for non-copper clear - self.ncc_dia_list = list() + self.ncc_dia_list = [] if self.tools_table.selectedItems(): for x in self.tools_table.selectedItems(): try: @@ -1834,7 +1834,7 @@ class NonCopperClear(FlatCAMTool, Gerber): bounding_box = cascaded_union(geo_buff_list) elif ncc_select == _("Reference Object"): if box_kind == 'geometry': - geo_buff_list = list() + geo_buff_list = [] for poly in env_obj: if self.app.abort_flag: # graceful abort requested by the user @@ -2223,7 +2223,7 @@ class NonCopperClear(FlatCAMTool, Gerber): p = p.buffer(0) if p is not None and p.is_valid: - poly_processed = list() + poly_processed = [] try: for pol in p: if pol is not None and isinstance(pol, Polygon): @@ -2368,7 +2368,7 @@ class NonCopperClear(FlatCAMTool, Gerber): return # create the solid_geometry - geo_obj.solid_geometry = list() + geo_obj.solid_geometry = [] for tooluid in geo_obj.tools: if geo_obj.tools[tooluid]['solid_geometry']: try: @@ -2653,7 +2653,7 @@ class NonCopperClear(FlatCAMTool, Gerber): return # create the solid_geometry - geo_obj.solid_geometry = list() + geo_obj.solid_geometry = [] for tooluid in geo_obj.tools: if geo_obj.tools[tooluid]['solid_geometry']: try: @@ -2961,7 +2961,7 @@ class NonCopperClear(FlatCAMTool, Gerber): milling_type = self.app.defaults["tools_nccmilling_type"] for tool_iso in isotooldia: - new_geometry = list() + new_geometry = [] if milling_type == 'cl': isolated_geo = self.generate_envelope(tool_iso / 2, 1) @@ -3129,7 +3129,7 @@ class NonCopperClear(FlatCAMTool, Gerber): p = p.buffer(0) if p is not None and p.is_valid: - poly_processed = list() + poly_processed = [] try: for pol in p: if pol is not None and isinstance(pol, Polygon): @@ -3267,7 +3267,7 @@ class NonCopperClear(FlatCAMTool, Gerber): return # create the solid_geometry - geo_obj.solid_geometry = list() + geo_obj.solid_geometry = [] for tooluid in geo_obj.tools: if geo_obj.tools[tooluid]['solid_geometry']: try: @@ -3650,7 +3650,7 @@ class NonCopperClear(FlatCAMTool, Gerber): return # create the solid_geometry - geo_obj.solid_geometry = list() + geo_obj.solid_geometry = [] for tooluid in geo_obj.tools: if geo_obj.tools[tooluid]['solid_geometry']: try: diff --git a/flatcamTools/ToolOptimal.py b/flatcamTools/ToolOptimal.py index 5160fc81..16c00efa 100644 --- a/flatcamTools/ToolOptimal.py +++ b/flatcamTools/ToolOptimal.py @@ -259,7 +259,7 @@ class ToolOptimal(FlatCAMTool): # dict to hold the distances between every two elements in Gerber as keys and the actual locations where that # distances happen as values - self.min_dict = dict() + self.min_dict = {} # ############################################################################ # ############################ Signals ####################################### @@ -354,7 +354,7 @@ class ToolOptimal(FlatCAMTool): old_disp_number = 0 pol_nr = 0 app_obj.proc_container.update_view_text(' %d%%' % 0) - total_geo = list() + total_geo = [] for ap in list(fcobj.apertures.keys()): if 'geometry' in fcobj.apertures[ap]: @@ -388,7 +388,7 @@ class ToolOptimal(FlatCAMTool): '%s: %s' % (_("Optimal Tool. Finding the distances between each two elements. Iterations"), str(geo_len))) - self.min_dict = dict() + self.min_dict = {} idx = 1 for geo in total_geo: for s_geo in total_geo[idx:]: diff --git a/flatcamTools/ToolPDF.py b/flatcamTools/ToolPDF.py index 9c8c1812..e5db0001 100644 --- a/flatcamTools/ToolPDF.py +++ b/flatcamTools/ToolPDF.py @@ -105,7 +105,7 @@ class ToolPDF(FlatCAMTool): self.restore_gs_re = re.compile(r'^.*Q.*$') # graphic stack where we save parameters like transformation, line_width - self.gs = dict() + self.gs = {} # each element is a list composed of sublist elements # (each sublist has 2 lists each having 2 elements: first is offset like: # offset_geo = [off_x, off_y], second element is scale list with 2 elements, like: scale_geo = [sc_x, sc_yy]) @@ -434,12 +434,12 @@ class ToolPDF(FlatCAMTool): traceback.print_exc() def parse_pdf(self, pdf_content): - path = dict() + path = {} path['lines'] = [] # it's a list of lines subpaths path['bezier'] = [] # it's a list of bezier arcs subpaths path['rectangle'] = [] # it's a list of rectangle subpaths - subpath = dict() + subpath = {} subpath['lines'] = [] # it's a list of points subpath['bezier'] = [] # it's a list of sublists each like this [start, c1, c2, stop] subpath['rectangle'] = [] # it's a list of sublists of points @@ -473,9 +473,9 @@ class ToolPDF(FlatCAMTool): # store the apertures with clear geometry here # we are interested only in the circular geometry (drill holes) therefore we target only Bezier subpaths - clear_apertures_dict = dict() + clear_apertures_dict = {} # everything will be stored in the '0' aperture since we are dealing with clear polygons not strokes - clear_apertures_dict['0'] = dict() + clear_apertures_dict['0'] = {} clear_apertures_dict['0']['size'] = 0.0 clear_apertures_dict['0']['type'] = 'C' clear_apertures_dict['0']['geometry'] = [] @@ -515,7 +515,7 @@ class ToolPDF(FlatCAMTool): apertures_dict.clear() layer_nr += 1 - object_dict[layer_nr] = dict() + object_dict[layer_nr] = {} old_color = copy(color) # we make sure that the following geometry is added to the right storage flag_clear_geo = False @@ -778,7 +778,7 @@ class ToolPDF(FlatCAMTool): if match: # scale the size here; some PDF printers apply transformation after the size is declared applied_size = size * scale_geo[0] * self.point_to_unit_factor - path_geo = list() + path_geo = [] if current_subpath == 'lines': if path['lines']: for subp in path['lines']: @@ -859,12 +859,12 @@ class ToolPDF(FlatCAMTool): for pdf_geo in path_geo: if isinstance(pdf_geo, MultiPolygon): for poly in pdf_geo: - new_el = dict() + new_el = {} new_el['solid'] = poly new_el['follow'] = poly.exterior apertures_dict[copy(found_aperture)]['geometry'].append(deepcopy(new_el)) else: - new_el = dict() + new_el = {} new_el['solid'] = pdf_geo new_el['follow'] = pdf_geo.exterior apertures_dict[copy(found_aperture)]['geometry'].append(deepcopy(new_el)) @@ -879,12 +879,12 @@ class ToolPDF(FlatCAMTool): for pdf_geo in path_geo: if isinstance(pdf_geo, MultiPolygon): for poly in pdf_geo: - new_el = dict() + new_el = {} new_el['solid'] = poly new_el['follow'] = poly.exterior apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el)) else: - new_el = dict() + new_el = {} new_el['solid'] = pdf_geo new_el['follow'] = pdf_geo.exterior apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el)) @@ -896,12 +896,12 @@ class ToolPDF(FlatCAMTool): for pdf_geo in path_geo: if isinstance(pdf_geo, MultiPolygon): for poly in pdf_geo: - new_el = dict() + new_el = {} new_el['solid'] = poly new_el['follow'] = poly.exterior apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el)) else: - new_el = dict() + new_el = {} new_el['solid'] = pdf_geo new_el['follow'] = pdf_geo.exterior apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el)) @@ -913,7 +913,7 @@ class ToolPDF(FlatCAMTool): if match: # scale the size here; some PDF printers apply transformation after the size is declared applied_size = size * scale_geo[0] * self.point_to_unit_factor - path_geo = list() + path_geo = [] if current_subpath == 'lines': if path['lines']: @@ -1007,11 +1007,11 @@ class ToolPDF(FlatCAMTool): if path_geo: try: for g in path_geo: - new_el = dict() + new_el = {} new_el['clear'] = g clear_apertures_dict['0']['geometry'].append(new_el) except TypeError: - new_el = dict() + new_el = {} new_el['clear'] = path_geo clear_apertures_dict['0']['geometry'].append(new_el) @@ -1022,11 +1022,11 @@ class ToolPDF(FlatCAMTool): for pdf_geo in path_geo: if isinstance(pdf_geo, MultiPolygon): for poly in pdf_geo: - new_el = dict() + new_el = {} new_el['clear'] = poly apertures_dict['0']['geometry'].append(deepcopy(new_el)) else: - new_el = dict() + new_el = {} new_el['clear'] = pdf_geo apertures_dict['0']['geometry'].append(deepcopy(new_el)) except KeyError: @@ -1038,11 +1038,11 @@ class ToolPDF(FlatCAMTool): for pdf_geo in path_geo: if isinstance(pdf_geo, MultiPolygon): for poly in pdf_geo: - new_el = dict() + new_el = {} new_el['clear'] = poly apertures_dict['0']['geometry'].append(deepcopy(new_el)) else: - new_el = dict() + new_el = {} new_el['clear'] = pdf_geo apertures_dict['0']['geometry'].append(deepcopy(new_el)) else: @@ -1051,12 +1051,12 @@ class ToolPDF(FlatCAMTool): for pdf_geo in path_geo: if isinstance(pdf_geo, MultiPolygon): for poly in pdf_geo: - new_el = dict() + new_el = {} new_el['solid'] = poly new_el['follow'] = poly.exterior apertures_dict['0']['geometry'].append(deepcopy(new_el)) else: - new_el = dict() + new_el = {} new_el['solid'] = pdf_geo new_el['follow'] = pdf_geo.exterior apertures_dict['0']['geometry'].append(deepcopy(new_el)) @@ -1069,12 +1069,12 @@ class ToolPDF(FlatCAMTool): for pdf_geo in path_geo: if isinstance(pdf_geo, MultiPolygon): for poly in pdf_geo: - new_el = dict() + new_el = {} new_el['solid'] = poly new_el['follow'] = poly.exterior apertures_dict['0']['geometry'].append(deepcopy(new_el)) else: - new_el = dict() + new_el = {} new_el['solid'] = pdf_geo new_el['follow'] = pdf_geo.exterior apertures_dict['0']['geometry'].append(deepcopy(new_el)) @@ -1085,8 +1085,8 @@ class ToolPDF(FlatCAMTool): if match: # scale the size here; some PDF printers apply transformation after the size is declared applied_size = size * scale_geo[0] * self.point_to_unit_factor - path_geo = list() - fill_geo = list() + path_geo = [] + fill_geo = [] if current_subpath == 'lines': if path['lines']: @@ -1222,12 +1222,12 @@ class ToolPDF(FlatCAMTool): for pdf_geo in path_geo: if isinstance(pdf_geo, MultiPolygon): for poly in pdf_geo: - new_el = dict() + new_el = {} new_el['solid'] = poly new_el['follow'] = poly.exterior apertures_dict[copy(found_aperture)]['geometry'].append(deepcopy(new_el)) else: - new_el = dict() + new_el = {} new_el['solid'] = pdf_geo new_el['follow'] = pdf_geo.exterior apertures_dict[copy(found_aperture)]['geometry'].append(deepcopy(new_el)) @@ -1242,12 +1242,12 @@ class ToolPDF(FlatCAMTool): for pdf_geo in path_geo: if isinstance(pdf_geo, MultiPolygon): for poly in pdf_geo: - new_el = dict() + new_el = {} new_el['solid'] = poly new_el['follow'] = poly.exterior apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el)) else: - new_el = dict() + new_el = {} new_el['solid'] = pdf_geo new_el['follow'] = pdf_geo.exterior apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el)) @@ -1259,12 +1259,12 @@ class ToolPDF(FlatCAMTool): for pdf_geo in path_geo: if isinstance(pdf_geo, MultiPolygon): for poly in pdf_geo: - new_el = dict() + new_el = {} new_el['solid'] = poly new_el['follow'] = poly.exterior apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el)) else: - new_el = dict() + new_el = {} new_el['solid'] = pdf_geo new_el['follow'] = pdf_geo.exterior apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el)) @@ -1279,11 +1279,11 @@ class ToolPDF(FlatCAMTool): for pdf_geo in path_geo: if isinstance(pdf_geo, MultiPolygon): for poly in fill_geo: - new_el = dict() + new_el = {} new_el['clear'] = poly apertures_dict['0']['geometry'].append(deepcopy(new_el)) else: - new_el = dict() + new_el = {} new_el['clear'] = pdf_geo apertures_dict['0']['geometry'].append(deepcopy(new_el)) except KeyError: @@ -1295,11 +1295,11 @@ class ToolPDF(FlatCAMTool): for pdf_geo in fill_geo: if isinstance(pdf_geo, MultiPolygon): for poly in pdf_geo: - new_el = dict() + new_el = {} new_el['clear'] = poly apertures_dict['0']['geometry'].append(deepcopy(new_el)) else: - new_el = dict() + new_el = {} new_el['clear'] = pdf_geo apertures_dict['0']['geometry'].append(deepcopy(new_el)) else: @@ -1307,12 +1307,12 @@ class ToolPDF(FlatCAMTool): for pdf_geo in path_geo: if isinstance(pdf_geo, MultiPolygon): for poly in fill_geo: - new_el = dict() + new_el = {} new_el['solid'] = poly new_el['follow'] = poly.exterior apertures_dict['0']['geometry'].append(deepcopy(new_el)) else: - new_el = dict() + new_el = {} new_el['solid'] = pdf_geo new_el['follow'] = pdf_geo.exterior apertures_dict['0']['geometry'].append(deepcopy(new_el)) @@ -1325,12 +1325,12 @@ class ToolPDF(FlatCAMTool): for pdf_geo in fill_geo: if isinstance(pdf_geo, MultiPolygon): for poly in pdf_geo: - new_el = dict() + new_el = {} new_el['solid'] = poly new_el['follow'] = poly.exterior apertures_dict['0']['geometry'].append(deepcopy(new_el)) else: - new_el = dict() + new_el = {} new_el['solid'] = pdf_geo new_el['follow'] = pdf_geo.exterior apertures_dict['0']['geometry'].append(deepcopy(new_el)) diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 8cb957b9..7f9a8c27 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -561,7 +561,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.bound_obj_name = "" self.bound_obj = None - self.tooldia_list = list() + self.tooldia_list = [] self.tooldia = None self.sel_rect = None @@ -572,7 +572,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.select_method = None self.units = '' - self.paint_tools = dict() + self.paint_tools = {} self.tooluid = 0 self.first_click = False self.cursor_pos = None @@ -582,16 +582,16 @@ class ToolPaint(FlatCAMTool, Gerber): self.mp = None self.mr = None - self.sel_rect = list() + self.sel_rect = [] # store here if the grid snapping is active self.grid_status_memory = False # dict to store the polygons selected for painting; key is the shape added to be plotted and value is the poly - self.poly_dict = dict() + self.poly_dict = {} # store here the default data for Geometry Data - self.default_data = dict() + self.default_data = {} self.tool_type_item_options = ["C1", "C2", "C3", "C4", "B", "V"] @@ -794,7 +794,7 @@ class ToolPaint(FlatCAMTool, Gerber): row = 0 tooluid_item = int(self.tools_table.item(row, 3).text()) - temp_tool_data = dict() + temp_tool_data = {} for tooluid_key, tooluid_val in self.paint_tools.items(): if int(tooluid_key) == tooluid_item: @@ -1352,7 +1352,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.o_name = '%s_mt_paint' % self.obj_name # use the selected tools in the tool table; get diameters - self.tooldia_list = list() + self.tooldia_list = [] if self.tools_table.selectedItems(): for x in self.tools_table.selectedItems(): try: @@ -1739,7 +1739,7 @@ class ToolPaint(FlatCAMTool, Gerber): # Initializes the new geometry object def gen_paintarea(geo_obj, app_obj): - geo_obj.solid_geometry = list() + geo_obj.solid_geometry = [] def paint_p(polyg, tooldiameter): cpoly = None @@ -1779,9 +1779,9 @@ class ToolPaint(FlatCAMTool, Gerber): # aperture_size = None # the key is the aperture type and the val is a list of geo elements - flash_el_dict = dict() + flash_el_dict = {} # the key is the aperture size, the val is a list of geo elements - traces_el_dict = dict() + traces_el_dict = {} # find the flashes and the lines that are in the selected polygon and store them separately for apid, apval in obj.apertures.items(): @@ -1818,7 +1818,7 @@ class ToolPaint(FlatCAMTool, Gerber): traces_el_dict[aperture_size] = [geo_el] cpoly = FlatCAMRTreeStorage() - pads_lines_list = list() + pads_lines_list = [] # process the flashes found in the selected polygon with the 'lines' method for rectangular # flashes and with _("Seed") for oblong and circular flashes @@ -1868,7 +1868,7 @@ class ToolPaint(FlatCAMTool, Gerber): except TypeError: cpoly.insert(pads_lines_list) - copper_lines_list = list() + copper_lines_list = [] # process the traces found in the selected polygon using the 'laser_lines' method, # method which will follow the 'follow' line therefore use the longer path possible for the # laser, therefore the acceleration will play a smaller factor @@ -1976,14 +1976,14 @@ class ToolPaint(FlatCAMTool, Gerber): try: poly_buf = [pol.buffer(-paint_margin) for pol in polygon_list] - cp = list() + cp = [] try: for pp in poly_buf: cp.append(paint_p(pp, tooldiameter=tool_dia)) except TypeError: cp = paint_p(poly_buf, tooldiameter=tool_dia) - total_geometry = list() + total_geometry = [] if cp: try: for x in cp: @@ -2289,7 +2289,7 @@ class ToolPaint(FlatCAMTool, Gerber): poly_buf = geo.buffer(-paint_margin) if geo is not None and geo.is_valid: - poly_processed = list() + poly_processed = [] try: for pol in poly_buf: if pol is not None and isinstance(pol, Polygon): @@ -2326,9 +2326,9 @@ class ToolPaint(FlatCAMTool, Gerber): # aperture_size = None # the key is the aperture type and the val is a list of geo elements - flash_el_dict = dict() + flash_el_dict = {} # the key is the aperture size, the val is a list of geo elements - traces_el_dict = dict() + traces_el_dict = {} # find the flashes and the lines that are in the selected polygon and store # them separately @@ -2366,7 +2366,7 @@ class ToolPaint(FlatCAMTool, Gerber): traces_el_dict[aperture_size] = [geo_el] cp = FlatCAMRTreeStorage() - pads_lines_list = list() + pads_lines_list = [] # process the flashes found in the selected polygon with the 'lines' method # for rectangular flashes and with _("Seed") for oblong and circular flashes @@ -2417,7 +2417,7 @@ class ToolPaint(FlatCAMTool, Gerber): except TypeError: cp.insert(pads_lines_list) - copper_lines_list = list() + copper_lines_list = [] # process the traces found in the selected polygon using the 'laser_lines' # method, method which will follow the 'follow' line therefore use the longer # path possible for the laser, therefore the acceleration will play @@ -2528,9 +2528,9 @@ class ToolPaint(FlatCAMTool, Gerber): # aperture_size = None # the key is the aperture type and the val is a list of geo elements - flash_el_dict = dict() + flash_el_dict = {} # the key is the aperture size, the val is a list of geo elements - traces_el_dict = dict() + traces_el_dict = {} # find the flashes and the lines that are in the selected polygon and store # them separately @@ -2568,7 +2568,7 @@ class ToolPaint(FlatCAMTool, Gerber): traces_el_dict[aperture_size] = [geo_el] cp = FlatCAMRTreeStorage() - pads_lines_list = list() + pads_lines_list = [] # process the flashes found in the selected polygon with the 'lines' method # for rectangular flashes and with _("Seed") for oblong and circular flashes @@ -2619,7 +2619,7 @@ class ToolPaint(FlatCAMTool, Gerber): except TypeError: cp.insert(pads_lines_list) - copper_lines_list = list() + copper_lines_list = [] # process the traces found in the selected polygon using the 'laser_lines' # method, method which will follow the 'follow' line therefore use the longer # path possible for the laser, therefore the acceleration will play @@ -2906,9 +2906,9 @@ class ToolPaint(FlatCAMTool, Gerber): # aperture_size = None # the key is the aperture type and the val is a list of geo elements - flash_el_dict = dict() + flash_el_dict = {} # the key is the aperture size, the val is a list of geo elements - traces_el_dict = dict() + traces_el_dict = {} # find the flashes and the lines that are in the selected polygon and store # them separately @@ -2946,7 +2946,7 @@ class ToolPaint(FlatCAMTool, Gerber): traces_el_dict[aperture_size] = [geo_el] cp = FlatCAMRTreeStorage() - pads_lines_list = list() + pads_lines_list = [] # process the flashes found in the selected polygon with the 'lines' method # for rectangular flashes and with _("Seed") for oblong and circular flashes @@ -2997,7 +2997,7 @@ class ToolPaint(FlatCAMTool, Gerber): except TypeError: cp.insert(pads_lines_list) - copper_lines_list = list() + copper_lines_list = [] # process the traces found in the selected polygon using the 'laser_lines' # method, method which will follow the 'follow' line therefore use the longer # path possible for the laser, therefore the acceleration will play @@ -3386,9 +3386,9 @@ class ToolPaint(FlatCAMTool, Gerber): # aperture_size = None # the key is the aperture type and the val is a list of geo elements - flash_el_dict = dict() + flash_el_dict = {} # the key is the aperture size, the val is a list of geo elements - traces_el_dict = dict() + traces_el_dict = {} # find the flashes and the lines that are in the selected polygon and store # them separately @@ -3426,7 +3426,7 @@ class ToolPaint(FlatCAMTool, Gerber): traces_el_dict[aperture_size] = [geo_el] cp = FlatCAMRTreeStorage() - pads_lines_list = list() + pads_lines_list = [] # process the flashes found in the selected polygon with the 'lines' method # for rectangular flashes and with _("Seed") for oblong and circular flashes @@ -3477,7 +3477,7 @@ class ToolPaint(FlatCAMTool, Gerber): except TypeError: cp.insert(pads_lines_list) - copper_lines_list = list() + copper_lines_list = [] # process the traces found in the selected polygon using the 'laser_lines' # method, method which will follow the 'follow' line therefore use the longer # path possible for the laser, therefore the acceleration will play @@ -3706,9 +3706,9 @@ class ToolPaint(FlatCAMTool, Gerber): # aperture_size = None # the key is the aperture type and the val is a list of geo elements - flash_el_dict = dict() + flash_el_dict = {} # the key is the aperture size, the val is a list of geo elements - copper_el_dict = dict() + copper_el_dict = {} # find the flashes and the lines that are in the selected polygon and store # them separately @@ -3746,7 +3746,7 @@ class ToolPaint(FlatCAMTool, Gerber): copper_el_dict[aperture_size] = [geo_el] cp = FlatCAMRTreeStorage() - pads_lines_list = list() + pads_lines_list = [] # process the flashes found in the selected polygon with the 'lines' method # for rectangular flashes and with _("Seed") for oblong and circular flashes @@ -3797,7 +3797,7 @@ class ToolPaint(FlatCAMTool, Gerber): except TypeError: cp.insert(pads_lines_list) - copper_lines_list = list() + copper_lines_list = [] # process the traces found in the selected polygon using the 'laser_lines' # method, method which will follow the 'follow' line therefore use the longer # path possible for the laser, therefore the acceleration will play diff --git a/flatcamTools/ToolPanelize.py b/flatcamTools/ToolPanelize.py index 8aeddabf..9494c2d0 100644 --- a/flatcamTools/ToolPanelize.py +++ b/flatcamTools/ToolPanelize.py @@ -473,13 +473,13 @@ class Panelize(FlatCAMTool): if isinstance(panel_obj, FlatCAMExcellon) or isinstance(panel_obj, FlatCAMGeometry): # make a copy of the panelized Excellon or Geometry tools - copied_tools = dict() + copied_tools = {} for tt, tt_val in list(panel_obj.tools.items()): copied_tools[tt] = deepcopy(tt_val) if isinstance(panel_obj, FlatCAMGerber): # make a copy of the panelized Gerber apertures - copied_apertures = dict() + copied_apertures = {} for tt, tt_val in list(panel_obj.apertures.items()): copied_apertures[tt] = deepcopy(tt_val) @@ -577,7 +577,7 @@ class Panelize(FlatCAMTool): def translate_recursion(geom): if type(geom) == list: - geoms = list() + geoms = [] for local_geom in geom: res_geo = translate_recursion(local_geom) try: @@ -600,7 +600,7 @@ class Panelize(FlatCAMTool): elif isinstance(panel_obj, FlatCAMGerber): obj_fin.apertures = copied_apertures for ap in obj_fin.apertures: - obj_fin.apertures[ap]['geometry'] = list() + obj_fin.apertures[ap]['geometry'] = [] # find the number of polygons in the source solid_geometry geo_len = 0 @@ -736,7 +736,7 @@ class Panelize(FlatCAMTool): # graceful abort requested by the user raise FlatCAMApp.GracefulException - new_el = dict() + new_el = {} if 'solid' in el: geo_aper = translate_recursion(el['solid']) new_el['solid'] = geo_aper diff --git a/flatcamTools/ToolProperties.py b/flatcamTools/ToolProperties.py index 78e48afc..b09d6e19 100644 --- a/flatcamTools/ToolProperties.py +++ b/flatcamTools/ToolProperties.py @@ -277,7 +277,7 @@ class Properties(FlatCAMTool): # calculate copper area # create a complete solid_geometry from the tools - geo_tools = list() + geo_tools = [] for tool_k in obj_prop.tools: if 'solid_geometry' in obj_prop.tools[tool_k]: for geo_el in obj_prop.tools[tool_k]['solid_geometry']: @@ -351,7 +351,7 @@ class Properties(FlatCAMTool): # Items that depend on the object type if obj.kind.lower() == 'gerber': - temp_ap = dict() + temp_ap = {} for ap in obj.apertures: temp_ap.clear() temp_ap = deepcopy(obj.apertures[ap]) diff --git a/flatcamTools/ToolPunchGerber.py b/flatcamTools/ToolPunchGerber.py index b0f5c326..660dae7f 100644 --- a/flatcamTools/ToolPunchGerber.py +++ b/flatcamTools/ToolPunchGerber.py @@ -515,7 +515,7 @@ class ToolPunchGerber(FlatCAMTool): punch_method = self.method_punch.get_value() - new_options = dict() + new_options = {} for opt in grb_obj.options: new_options[opt] = deepcopy(grb_obj.options[opt]) @@ -549,7 +549,7 @@ class ToolPunchGerber(FlatCAMTool): new_apid = max([int(x) for x, __ in new_apertures_items]) # store here the clear geometry, the key is the drill size - holes_apertures = dict() + holes_apertures = {} for apid, val in new_apertures_items: for elem in val['geometry']: @@ -560,14 +560,14 @@ class ToolPunchGerber(FlatCAMTool): # since there may be drills that do not drill into a pad we test only for drills in a pad if drill['point'].within(elem['solid']): - geo_elem = dict() + geo_elem = {} geo_elem['clear'] = drill['point'] if clear_apid_size not in holes_apertures: - holes_apertures[clear_apid_size] = dict() + holes_apertures[clear_apid_size] = {} holes_apertures[clear_apid_size]['type'] = 'C' holes_apertures[clear_apid_size]['size'] = clear_apid_size - holes_apertures[clear_apid_size]['geometry'] = list() + holes_apertures[clear_apid_size]['geometry'] = [] holes_apertures[clear_apid_size]['geometry'].append(deepcopy(geo_elem)) @@ -597,7 +597,7 @@ class ToolPunchGerber(FlatCAMTool): self.app.inform.emit('[WARNING_NOTCL] %s' % _("The value of the fixed diameter is 0.0. Aborting.")) return 'fail' - punching_geo = list() + punching_geo = [] for apid in grb_obj.apertures: if grb_obj.apertures[apid]['type'] == 'C' and self.circular_cb.get_value(): if punch_size >= float(grb_obj.apertures[apid]['size']): @@ -663,7 +663,7 @@ class ToolPunchGerber(FlatCAMTool): new_apid = max([int(x) for x, __ in new_apertures_items]) # store here the clear geometry, the key is the drill size - holes_apertures = dict() + holes_apertures = {} for apid, val in new_apertures_items: for elem in val['geometry']: @@ -674,14 +674,14 @@ class ToolPunchGerber(FlatCAMTool): # since there may be drills that do not drill into a pad we test only for drills in a pad if geo.within(elem['solid']): - geo_elem = dict() + geo_elem = {} geo_elem['clear'] = geo.centroid if clear_apid_size not in holes_apertures: - holes_apertures[clear_apid_size] = dict() + holes_apertures[clear_apid_size] = {} holes_apertures[clear_apid_size]['type'] = 'C' holes_apertures[clear_apid_size]['size'] = clear_apid_size - holes_apertures[clear_apid_size]['geometry'] = list() + holes_apertures[clear_apid_size]['geometry'] = [] holes_apertures[clear_apid_size]['geometry'].append(deepcopy(geo_elem)) @@ -727,11 +727,11 @@ class ToolPunchGerber(FlatCAMTool): new_apid = max([int(x) for x, __ in new_apertures_items]) # store here the clear geometry, the key is the new aperture size - holes_apertures = dict() + holes_apertures = {} for apid, apid_value in grb_obj.apertures.items(): ap_type = apid_value['type'] - punching_geo = list() + punching_geo = [] if ap_type == 'C' and self.circular_cb.get_value(): dia = float(apid_value['size']) - (2 * circ_r_val) @@ -816,14 +816,14 @@ class ToolPunchGerber(FlatCAMTool): # since there may be drills that do not drill into a pad we test only for geos in a pad if geo.within(elem['solid']): - geo_elem = dict() + geo_elem = {} geo_elem['clear'] = geo.centroid if clear_apid_size not in holes_apertures: - holes_apertures[clear_apid_size] = dict() + holes_apertures[clear_apid_size] = {} holes_apertures[clear_apid_size]['type'] = 'C' holes_apertures[clear_apid_size]['size'] = clear_apid_size - holes_apertures[clear_apid_size]['geometry'] = list() + holes_apertures[clear_apid_size]['geometry'] = [] holes_apertures[clear_apid_size]['geometry'].append(deepcopy(geo_elem)) @@ -866,11 +866,11 @@ class ToolPunchGerber(FlatCAMTool): new_apid = max([int(x) for x, __ in new_apertures_items]) # store here the clear geometry, the key is the new aperture size - holes_apertures = dict() + holes_apertures = {} for apid, apid_value in grb_obj.apertures.items(): ap_type = apid_value['type'] - punching_geo = list() + punching_geo = [] if ap_type == 'C' and self.circular_cb.get_value(): dia = float(apid_value['size']) * prop_factor @@ -955,14 +955,14 @@ class ToolPunchGerber(FlatCAMTool): # since there may be drills that do not drill into a pad we test only for geos in a pad if geo.within(elem['solid']): - geo_elem = dict() + geo_elem = {} geo_elem['clear'] = geo.centroid if clear_apid_size not in holes_apertures: - holes_apertures[clear_apid_size] = dict() + holes_apertures[clear_apid_size] = {} holes_apertures[clear_apid_size]['type'] = 'C' holes_apertures[clear_apid_size]['size'] = clear_apid_size - holes_apertures[clear_apid_size]['geometry'] = list() + holes_apertures[clear_apid_size]['geometry'] = [] holes_apertures[clear_apid_size]['geometry'].append(deepcopy(geo_elem)) diff --git a/flatcamTools/ToolQRCode.py b/flatcamTools/ToolQRCode.py index 5e9b8ff0..2486ba7f 100644 --- a/flatcamTools/ToolQRCode.py +++ b/flatcamTools/ToolQRCode.py @@ -496,7 +496,7 @@ class QRCode(FlatCAMTool): mask_geo = box(a, b, c, d).buffer(buff_val, join_style=2) # update the solid geometry with the cutout (if it is the case) - new_solid_geometry = list() + new_solid_geometry = [] offset_mask_geo = translate(mask_geo, xoff=pos[0], yoff=pos[1]) for poly in geo_list: if poly.contains(offset_mask_geo): @@ -523,7 +523,7 @@ class QRCode(FlatCAMTool): box_size = float(self.bsize_entry.get_value()) / 10.0 - sort_apid = list() + sort_apid = [] new_apid = '10' if self.grb_object.apertures: for k, v in list(self.grb_object.apertures.items()): @@ -537,8 +537,8 @@ class QRCode(FlatCAMTool): # don't know if the condition is required since I already made sure above that the new_apid is a new one if new_apid not in self.grb_object.apertures: - self.grb_object.apertures[new_apid] = dict() - self.grb_object.apertures[new_apid]['geometry'] = list() + self.grb_object.apertures[new_apid] = {} + self.grb_object.apertures[new_apid]['geometry'] = [] self.grb_object.apertures[new_apid]['type'] = 'R' # TODO: HACK # I've artificially added 1% to the height and width because otherwise after loading the @@ -549,14 +549,14 @@ class QRCode(FlatCAMTool): self.grb_object.apertures[new_apid]['size'] = deepcopy(math.sqrt(box_size ** 2 + box_size ** 2)) if '0' not in self.grb_object.apertures: - self.grb_object.apertures['0'] = dict() - self.grb_object.apertures['0']['geometry'] = list() + self.grb_object.apertures['0'] = {} + self.grb_object.apertures['0']['geometry'] = [] self.grb_object.apertures['0']['type'] = 'REG' self.grb_object.apertures['0']['size'] = 0.0 # in case that the QRCode geometry is dropped onto a copper region (found in the '0' aperture) # make sure that I place a cutout there - zero_elem = dict() + zero_elem = {} zero_elem['clear'] = offset_mask_geo self.grb_object.apertures['0']['geometry'].append(deepcopy(zero_elem)) @@ -571,12 +571,12 @@ class QRCode(FlatCAMTool): try: for geo in self.qrcode_geometry: - geo_elem = dict() + geo_elem = {} geo_elem['solid'] = translate(geo, xoff=pos[0], yoff=pos[1]) geo_elem['follow'] = translate(geo.centroid, xoff=pos[0], yoff=pos[1]) self.grb_object.apertures[new_apid]['geometry'].append(deepcopy(geo_elem)) except TypeError: - geo_elem = dict() + geo_elem = {} geo_elem['solid'] = self.qrcode_geometry self.grb_object.apertures[new_apid]['geometry'].append(deepcopy(geo_elem)) @@ -592,7 +592,7 @@ class QRCode(FlatCAMTool): # face = '#0000FF' + str(hex(int(0.2 * 255)))[2:] outline = '#0000FFAF' - offset_geo = list() + offset_geo = [] # I use the len of self.qrcode_geometry instead of the utility one because the complexity of the polygons is # better seen in this (bit what if the sel.qrcode_geometry is just one geo element? len will fail ... diff --git a/flatcamTools/ToolRulesCheck.py b/flatcamTools/ToolRulesCheck.py index 39561ef2..ffd5844d 100644 --- a/flatcamTools/ToolRulesCheck.py +++ b/flatcamTools/ToolRulesCheck.py @@ -655,8 +655,8 @@ class RulesCheck(FlatCAMTool): rule_title = rule - violations = list() - obj_violations = dict() + violations = [] + obj_violations = {} obj_violations.update({ 'name': '', 'points': list() @@ -667,8 +667,8 @@ class RulesCheck(FlatCAMTool): obj_violations['name'] = gerber_obj['name'] - solid_geo = list() - clear_geo = list() + solid_geo = [] + clear_geo = [] for apid in gerber_obj['apertures']: if 'geometry' in gerber_obj['apertures'][apid]: geometry = gerber_obj['apertures'][apid]['geometry'] @@ -679,7 +679,7 @@ class RulesCheck(FlatCAMTool): clear_geo.append(geo_el['clear']) if clear_geo: - total_geo = list() + total_geo = [] for geo_c in clear_geo: for geo_s in solid_geo: if geo_c.within(geo_s): @@ -696,7 +696,7 @@ class RulesCheck(FlatCAMTool): iterations = (iterations * (iterations - 1)) / 2 log.debug("RulesCheck.check_gerber_clearance(). Iterations: %s" % str(iterations)) - min_dict = dict() + min_dict = {} idx = 1 for geo in total_geo: for s_geo in total_geo[idx:]: @@ -729,8 +729,8 @@ class RulesCheck(FlatCAMTool): log.debug("RulesCheck.check_gerber_clearance()") rule_title = rule - violations = list() - obj_violations = dict() + violations = [] + obj_violations = {} obj_violations.update({ 'name': '', 'points': list() @@ -739,7 +739,7 @@ class RulesCheck(FlatCAMTool): if len(gerber_list) == 2: gerber_1 = gerber_list[0] # added it so I won't have errors of using before declaring - gerber_2 = dict() + gerber_2 = {} gerber_3 = gerber_list[1] elif len(gerber_list) == 3: @@ -749,7 +749,7 @@ class RulesCheck(FlatCAMTool): else: return 'Fail. Not enough Gerber objects to check Gerber 2 Gerber clearance' - total_geo_grb_1 = list() + total_geo_grb_1 = [] for apid in gerber_1['apertures']: if 'geometry' in gerber_1['apertures'][apid]: geometry = gerber_1['apertures'][apid]['geometry'] @@ -766,7 +766,7 @@ class RulesCheck(FlatCAMTool): if 'solid' in geo_el and geo_el['solid'] is not None: total_geo_grb_1.append(geo_el['solid']) - total_geo_grb_3 = list() + total_geo_grb_3 = [] for apid in gerber_3['apertures']: if 'geometry' in gerber_3['apertures'][apid]: geometry = gerber_3['apertures'][apid]['geometry'] @@ -795,7 +795,7 @@ class RulesCheck(FlatCAMTool): iterations = len_1 * len_3 log.debug("RulesCheck.check_gerber_clearance(). Iterations: %s" % str(iterations)) - min_dict = dict() + min_dict = {} for geo in total_geo_grb_1: for s_geo in total_geo_grb_3: # minimize the number of distances by not taking into considerations those that are too small @@ -817,7 +817,7 @@ class RulesCheck(FlatCAMTool): for location in min_dict[dist]: points_list.add(location) - name_list = list() + name_list = [] if gerber_1: name_list.append(gerber_1['name']) if gerber_2: @@ -837,8 +837,8 @@ class RulesCheck(FlatCAMTool): rule = _("Hole Size") - violations = list() - obj_violations = dict() + violations = [] + obj_violations = {} obj_violations.update({ 'name': '', 'dia': list() @@ -863,14 +863,14 @@ class RulesCheck(FlatCAMTool): log.debug("RulesCheck.check_holes_clearance()") rule = _("Hole to Hole Clearance") - violations = list() - obj_violations = dict() + violations = [] + obj_violations = {} obj_violations.update({ 'name': '', 'points': list() }) - total_geo = list() + total_geo = [] for elem in elements: for tool in elem['tools']: if 'solid_geometry' in elem['tools'][tool]: @@ -878,7 +878,7 @@ class RulesCheck(FlatCAMTool): for geo in geometry: total_geo.append(geo) - min_dict = dict() + min_dict = {} idx = 1 for geo in total_geo: for s_geo in total_geo[idx:]: @@ -903,7 +903,7 @@ class RulesCheck(FlatCAMTool): for location in min_dict[dist]: points_list.add(location) - name_list = list() + name_list = [] for elem in elements: name_list.append(elem['name']) @@ -919,8 +919,8 @@ class RulesCheck(FlatCAMTool): rule = _("Trace Size") - violations = list() - obj_violations = dict() + violations = [] + obj_violations = {} obj_violations.update({ 'name': '', 'size': list(), @@ -957,18 +957,18 @@ class RulesCheck(FlatCAMTool): def check_gerber_annular_ring(obj_list, size, rule): rule_title = rule - violations = list() - obj_violations = dict() + violations = [] + obj_violations = {} obj_violations.update({ 'name': '', 'points': list() }) # added it so I won't have errors of using before declaring - gerber_obj = dict() - gerber_extra_obj = dict() - exc_obj = dict() - exc_extra_obj = dict() + gerber_obj = {} + gerber_extra_obj = {} + exc_obj = {} + exc_extra_obj = {} if len(obj_list) == 2: gerber_obj = obj_list[0] @@ -997,7 +997,7 @@ class RulesCheck(FlatCAMTool): else: return 'Fail. Not enough objects to check Minimum Annular Ring' - total_geo_grb = list() + total_geo_grb = [] for apid in gerber_obj['apertures']: if 'geometry' in gerber_obj['apertures'][apid]: geometry = gerber_obj['apertures'][apid]['geometry'] @@ -1017,7 +1017,7 @@ class RulesCheck(FlatCAMTool): total_geo_grb = MultiPolygon(total_geo_grb) total_geo_grb = total_geo_grb.buffer(0) - total_geo_exc = list() + total_geo_exc = [] for tool in exc_obj['tools']: if 'solid_geometry' in exc_obj['tools'][tool]: geometry = exc_obj['tools'][tool]['solid_geometry'] @@ -1047,7 +1047,7 @@ class RulesCheck(FlatCAMTool): iterations = len_1 * len_2 log.debug("RulesCheck.check_gerber_annular_ring(). Iterations: %s" % str(iterations)) - min_dict = dict() + min_dict = {} dist = None for geo in total_geo_grb: for s_geo in total_geo_exc: @@ -1075,12 +1075,12 @@ class RulesCheck(FlatCAMTool): else: min_dict[dist] = [s_geo.representative_point()] - points_list = list() + points_list = [] for dist in min_dict.keys(): for location in min_dict[dist]: points_list.append(location) - name_list = list() + name_list = [] try: if gerber_obj: name_list.append(gerber_obj['name']) @@ -1110,7 +1110,7 @@ class RulesCheck(FlatCAMTool): return rule_title, violations def execute(self): - self.results = list() + self.results = [] log.debug("RuleCheck() executing") @@ -1119,17 +1119,17 @@ class RulesCheck(FlatCAMTool): # RULE: Check Trace Size if self.trace_size_cb.get_value(): - copper_list = list() + copper_list = [] copper_name_1 = self.copper_t_object.currentText() if copper_name_1 is not '' and self.copper_t_cb.get_value(): - elem_dict = dict() + elem_dict = {} elem_dict['name'] = deepcopy(copper_name_1) elem_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_name_1).apertures) copper_list.append(elem_dict) copper_name_2 = self.copper_b_object.currentText() if copper_name_2 is not '' and self.copper_b_cb.get_value(): - elem_dict = dict() + elem_dict = {} elem_dict['name'] = deepcopy(copper_name_2) elem_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_name_2).apertures) copper_list.append(elem_dict) @@ -1151,7 +1151,7 @@ class RulesCheck(FlatCAMTool): if self.copper_t_cb.get_value(): copper_t_obj = self.copper_t_object.currentText() - copper_t_dict = dict() + copper_t_dict = {} if copper_t_obj is not '': copper_t_dict['name'] = deepcopy(copper_t_obj) @@ -1163,7 +1163,7 @@ class RulesCheck(FlatCAMTool): _("TOP -> Copper to Copper clearance")))) if self.copper_b_cb.get_value(): copper_b_obj = self.copper_b_object.currentText() - copper_b_dict = dict() + copper_b_dict = {} if copper_b_obj is not '': copper_b_dict['name'] = deepcopy(copper_b_obj) copper_b_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_b_obj).apertures) @@ -1181,9 +1181,9 @@ class RulesCheck(FlatCAMTool): # RULE: Check Copper to Outline Clearance if self.clearance_copper2ol_cb.get_value() and self.out_cb.get_value(): - top_dict = dict() - bottom_dict = dict() - outline_dict = dict() + top_dict = {} + bottom_dict = {} + outline_dict = {} copper_top = self.copper_t_object.currentText() if copper_top is not '' and self.copper_t_cb.get_value(): @@ -1235,7 +1235,7 @@ class RulesCheck(FlatCAMTool): # RULE: Check Silk to Silk Clearance if self.clearance_silk2silk_cb.get_value(): - silk_dict = dict() + silk_dict = {} try: silk_silk_clearance = float(self.clearance_silk2silk_entry.get_value()) @@ -1275,10 +1275,10 @@ class RulesCheck(FlatCAMTool): # RULE: Check Silk to Solder Mask Clearance if self.clearance_silk2sm_cb.get_value(): - silk_t_dict = dict() - sm_t_dict = dict() - silk_b_dict = dict() - sm_b_dict = dict() + silk_t_dict = {} + sm_t_dict = {} + silk_b_dict = {} + sm_b_dict = {} top_ss = False bottom_ss = False @@ -1344,9 +1344,9 @@ class RulesCheck(FlatCAMTool): # RULE: Check Silk to Outline Clearance if self.clearance_silk2ol_cb.get_value(): - top_dict = dict() - bottom_dict = dict() - outline_dict = dict() + top_dict = {} + bottom_dict = {} + outline_dict = {} silk_top = self.ss_t_object.currentText() if silk_top is not '' and self.ss_t_cb.get_value(): @@ -1399,7 +1399,7 @@ class RulesCheck(FlatCAMTool): # RULE: Check Minimum Solder Mask Sliver if self.clearance_silk2silk_cb.get_value(): - sm_dict = dict() + sm_dict = {} try: sm_sm_clearance = float(self.clearance_sm2sm_entry.get_value()) @@ -1439,10 +1439,10 @@ class RulesCheck(FlatCAMTool): # RULE: Check Minimum Annular Ring if self.ring_integrity_cb.get_value(): - top_dict = dict() - bottom_dict = dict() - exc_1_dict = dict() - exc_2_dict = dict() + top_dict = {} + bottom_dict = {} + exc_1_dict = {} + exc_2_dict = {} copper_top = self.copper_t_object.currentText() if copper_top is not '' and self.copper_t_cb.get_value(): @@ -1504,17 +1504,17 @@ class RulesCheck(FlatCAMTool): # RULE: Check Hole to Hole Clearance if self.clearance_d2d_cb.get_value(): - exc_list = list() + exc_list = [] exc_name_1 = self.e1_object.currentText() if exc_name_1 is not '' and self.e1_cb.get_value(): - elem_dict = dict() + elem_dict = {} elem_dict['name'] = deepcopy(exc_name_1) elem_dict['tools'] = deepcopy(self.app.collection.get_by_name(exc_name_1).tools) exc_list.append(elem_dict) exc_name_2 = self.e2_object.currentText() if exc_name_2 is not '' and self.e2_cb.get_value(): - elem_dict = dict() + elem_dict = {} elem_dict['name'] = deepcopy(exc_name_2) elem_dict['tools'] = deepcopy(self.app.collection.get_by_name(exc_name_2).tools) exc_list.append(elem_dict) @@ -1524,17 +1524,17 @@ class RulesCheck(FlatCAMTool): # RULE: Check Holes Size if self.drill_size_cb.get_value(): - exc_list = list() + exc_list = [] exc_name_1 = self.e1_object.currentText() if exc_name_1 is not '' and self.e1_cb.get_value(): - elem_dict = dict() + elem_dict = {} elem_dict['name'] = deepcopy(exc_name_1) elem_dict['tools'] = deepcopy(self.app.collection.get_by_name(exc_name_1).tools) exc_list.append(elem_dict) exc_name_2 = self.e2_object.currentText() if exc_name_2 is not '' and self.e2_cb.get_value(): - elem_dict = dict() + elem_dict = {} elem_dict['name'] = deepcopy(exc_name_2) elem_dict['tools'] = deepcopy(self.app.collection.get_by_name(exc_name_2).tools) exc_list.append(elem_dict) @@ -1542,7 +1542,7 @@ class RulesCheck(FlatCAMTool): drill_size = float(self.drill_size_entry.get_value()) self.results.append(self.pool.apply_async(self.check_holes_size, args=(exc_list, drill_size))) - output = list() + output = [] for p in self.results: output.append(p.get()) diff --git a/flatcamTools/ToolSub.py b/flatcamTools/ToolSub.py index 99cc9fa8..9d547ed5 100644 --- a/flatcamTools/ToolSub.py +++ b/flatcamTools/ToolSub.py @@ -303,14 +303,14 @@ class ToolSub(FlatCAMTool): # crate the new_apertures dict structure for apid in self.target_grb_obj.apertures: - self.new_apertures[apid] = dict() + self.new_apertures[apid] = {} self.new_apertures[apid]['type'] = 'C' self.new_apertures[apid]['size'] = self.target_grb_obj.apertures[apid]['size'] - self.new_apertures[apid]['geometry'] = list() + self.new_apertures[apid]['geometry'] = [] - geo_solid_union_list = list() - geo_follow_union_list = list() - geo_clear_union_list = list() + geo_solid_union_list = [] + geo_follow_union_list = [] + geo_clear_union_list = [] for apid1 in self.sub_grb_obj.apertures: if 'geometry' in self.sub_grb_obj.apertures[apid1]: @@ -339,14 +339,14 @@ class ToolSub(FlatCAMTool): self.app.worker_task.emit({'fcn': self.aperture_intersection, 'params': [apid, geo]}) def aperture_intersection(self, apid, geo): - new_geometry = list() + new_geometry = [] log.debug("Working on promise: %s" % str(apid)) with self.app.proc_container.new('%s: %s...' % (_("Parsing geometry for aperture"), str(apid))): for geo_el in geo: - new_el = dict() + new_el = {} if 'solid' in geo_el: work_geo = geo_el['solid'] @@ -513,14 +513,14 @@ class ToolSub(FlatCAMTool): return # create the target_options obj - # self.target_options = dict() + # self.target_options = {} # for k, v in self.target_geo_obj.options.items(): # if k != 'name': # self.target_options[k] = v # crate the new_tools dict structure for tool in self.target_geo_obj.tools: - self.new_tools[tool] = dict() + self.new_tools[tool] = {} for key in self.target_geo_obj.tools[tool]: if key == 'solid_geometry': self.new_tools[tool][key] = [] diff --git a/tclCommands/TclCommand.py b/tclCommands/TclCommand.py index 719b3c71..fd3058c9 100644 --- a/tclCommands/TclCommand.py +++ b/tclCommands/TclCommand.py @@ -78,7 +78,7 @@ class TclCommand(object): :return: current command """ - command_string = list() + command_string = [] command_string.append(self.aliases[0]) if self.original_args is not None: diff --git a/tclCommands/TclCommandBounds.py b/tclCommands/TclCommandBounds.py index 6736f458..e4d53c7b 100644 --- a/tclCommands/TclCommandBounds.py +++ b/tclCommands/TclCommandBounds.py @@ -52,7 +52,7 @@ class TclCommandBounds(TclCommand): :return: """ - obj_list = list() + obj_list = [] if 'objects' in args: try: obj_list = [str(obj_name) for obj_name in str(args['objects']).split(",") if obj_name != ''] @@ -68,7 +68,7 @@ class TclCommandBounds(TclCommand): _("Expected a list of objects names separated by comma. Got"), str(args['objects']))) return 'fail' - result_list = list() + result_list = [] for name in obj_list: obj = self.app.collection.get_by_name(name) diff --git a/tclCommands/TclCommandCopperClear.py b/tclCommands/TclCommandCopperClear.py index d6f58989..f80bc5a9 100644 --- a/tclCommands/TclCommandCopperClear.py +++ b/tclCommands/TclCommandCopperClear.py @@ -188,7 +188,7 @@ class TclCommandCopperClear(TclCommand): "paintcontour": self.app.defaults["tools_paintcontour"], "paintoverlap": self.app.defaults["tools_paintoverlap"] }) - ncc_tools = dict() + ncc_tools = {} tooluid = 0 for tool in tools: diff --git a/tclCommands/TclCommandPaint.py b/tclCommands/TclCommandPaint.py index f44dcef2..e300e0c5 100644 --- a/tclCommands/TclCommandPaint.py +++ b/tclCommands/TclCommandPaint.py @@ -178,7 +178,7 @@ class TclCommandPaint(TclCommand): "paintcontour": self.app.defaults["tools_paintcontour"], "paintoverlap": self.app.defaults["tools_paintoverlap"] }) - paint_tools = dict() + paint_tools = {} tooluid = 0 for tool in tools: diff --git a/tclCommands/TclCommandPanelize.py b/tclCommands/TclCommandPanelize.py index 2a8c7c05..140c5e55 100644 --- a/tclCommands/TclCommandPanelize.py +++ b/tclCommands/TclCommandPanelize.py @@ -228,7 +228,7 @@ class TclCommandPanelize(TclCommand): def translate_recursion(geom): if type(geom) == list: - geoms = list() + geoms = [] for local_geom in geom: geoms.append(translate_recursion(local_geom)) return geoms diff --git a/tclCommands/TclCommandSetOrigin.py b/tclCommands/TclCommandSetOrigin.py index 27f883ce..52974dd2 100644 --- a/tclCommands/TclCommandSetOrigin.py +++ b/tclCommands/TclCommandSetOrigin.py @@ -66,7 +66,7 @@ class TclCommandSetOrigin(TclCommand): :return: """ - loc = list() + loc = [] if 'auto' in args: if bool(args['auto']) is True: objs = self.app.collection.get_list() From 77e01825c2d10c7e6692e73d507995c0cc2fabd6 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 1 Mar 2020 01:55:35 +0200 Subject: [PATCH 121/209] - wip on the new tools database --- FlatCAMCommon.py | 26 +++++++++++++++++++------- flatcamGUI/GUIElements.py | 16 +++++++++++++++- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/FlatCAMCommon.py b/FlatCAMCommon.py index 4a68cdaa..f324fe4c 100644 --- a/FlatCAMCommon.py +++ b/FlatCAMCommon.py @@ -1422,9 +1422,16 @@ class ToolsDB2(QtWidgets.QWidget): tree_layout = QtWidgets.QVBoxLayout() grid_layout.addLayout(tree_layout, 0, 0) - self.tree_widget = FCTree(columns=2, header_hidden=False) + self.tree_widget = FCTree(columns=2, header_hidden=False, protected_column=[0]) self.tree_widget.setHeaderLabels(["ID", "Tool Name"]) self.tree_widget.setIndentation(0) + + # set alternating colors + # self.tree_widget.setAlternatingRowColors(True) + # p = QtGui.QPalette() + # p.setColor(QtGui.QPalette.AlternateBase, QtGui.QColor(226, 237, 253) ) + # self.tree_widget.setPalette(p) + self.tree_widget.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding) tree_layout.addWidget(self.tree_widget) @@ -1516,16 +1523,21 @@ class ToolsDB2(QtWidgets.QWidget): self.add_tool_from_db.clicked.connect(self.on_tool_requested_from_app) self.cancel_tool_from_db.clicked.connect(self.on_cancel_tool) - self.tree_widget.selectionModel().selectionChanged.connect(self.on_list_selection_change) + # self.tree_widget.selectionModel().selectionChanged.connect(self.on_list_selection_change) + self.tree_widget.currentItemChanged.connect(self.on_list_selection_change) self.tree_widget.itemChanged.connect(self.on_list_item_edited) + self.setup_db_ui() - def on_list_selection_change(self, current): - return - for idx in current.indexes(): - print(idx.data()) + def on_list_selection_change(self, current, previous): + # for idx in current.indexes(): + # print(idx.data()) + print(current.text(0)) + self.table_widget.selectRow(int(current.text(0))-1) - def on_list_item_edited(self, item, idx): + def on_list_item_edited(self, item, column): + if column == 0: + return row = int(item.text(0)) - 1 self.table_widget.item(row, 1).setText(item.text(1)) diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index 144280c9..da536279 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -154,7 +154,7 @@ class RadioSet(QtWidgets.QWidget): class FCTree(QtWidgets.QTreeWidget): - def __init__(self, parent=None, columns=2, header_hidden=True, extended_sel=False): + def __init__(self, parent=None, columns=2, header_hidden=True, extended_sel=False, protected_column=None): super(FCTree, self).__init__(parent) self.setColumnCount(columns) @@ -165,6 +165,20 @@ class FCTree(QtWidgets.QTreeWidget): if extended_sel: self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) + self.protected_column = protected_column + self.itemDoubleClicked.connect(self.on_double_click) + + def on_double_click(self, item, column): + # from here: https://stackoverflow.com/questions/2801959/making-only-one-column-of-a-qtreewidgetitem-editable + tmp_flags = item.flags() + if self.is_editable(column): + item.setFlags(tmp_flags | QtCore.Qt.ItemIsEditable) + elif tmp_flags & QtCore.Qt.ItemIsEditable: + item.setFlags(tmp_flags ^ QtCore.Qt.ItemIsEditable) + + def is_editable(self, tested_col): + return False if tested_col in self.protected_column else True + def addParent(self, parent, title, expanded=False, color=None, font=None): item = QtWidgets.QTreeWidgetItem(parent, [title]) item.setChildIndicatorPolicy(QtWidgets.QTreeWidgetItem.ShowIndicator) From 5b10e9faf0e0d0a7d7b9004cca88ccdfb3091d3f Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 1 Mar 2020 19:23:06 +0200 Subject: [PATCH 122/209] - updated the CutOut Tool such that while adding manual gaps, the cutting geometry is updated on-the-fly if the gap size or tool diameter parameters are adjusted --- README.md | 4 ++++ flatcamTools/ToolCutOut.py | 11 +++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3ebe0a9e..11b4b213 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +01.03.2020 + +- updated the CutOut Tool such that while adding manual gaps, the cutting geometry is updated on-the-fly if the gap size or tool diameter parameters are adjusted + 29.02.2020 - compacted the NCC Tool UI by replacing some Radio buttons with Combo boxes due of too many elements diff --git a/flatcamTools/ToolCutOut.py b/flatcamTools/ToolCutOut.py index 0033d149..38f4ae7c 100644 --- a/flatcamTools/ToolCutOut.py +++ b/flatcamTools/ToolCutOut.py @@ -532,8 +532,8 @@ class CutOut(FlatCAMTool): object_geo = cutout_obj.solid_geometry.convex_hull else: object_geo = cutout_obj.solid_geometry - except Exception as e: - log.debug("CutOut.on_freeform_cutout().geo_init() --> %s" % str(e)) + except Exception as err: + log.debug("CutOut.on_freeform_cutout().geo_init() --> %s" % str(err)) else: object_geo = cutout_obj.solid_geometry @@ -939,6 +939,9 @@ class CutOut(FlatCAMTool): self.app.new_object('geometry', outname, geo_init) def cutting_geo(self, pos): + self.cutting_dia = float(self.dia.get_value()) + self.cutting_gapsize = float(self.gapsize.get_value()) + offset = self.cutting_dia / 2 + self.cutting_gapsize / 2 # cutting area definition @@ -1034,7 +1037,7 @@ class CutOut(FlatCAMTool): except TypeError: return - if self.app.grid_status() == True: + if self.app.grid_status(): snap_x, snap_y = self.app.geo_editor.snap(x, y) else: snap_x, snap_y = x, y @@ -1064,7 +1067,7 @@ class CutOut(FlatCAMTool): else: radian = math.atan(dx / dy) angle = radian * 180 / math.pi - except Exception as e: + except Exception: angle = 0 return angle From bac37865e934ba4139319238b192f5e63f648f92 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 1 Mar 2020 20:40:07 +0200 Subject: [PATCH 123/209] - updated the UI in Geometry Editor --- README.md | 1 + flatcamEditors/FlatCAMGeoEditor.py | 42 ++++++++++++++++-------------- flatcamGUI/GUIElements.py | 24 +++++++++++++++++ 3 files changed, 48 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 11b4b213..4b42bb5c 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 01.03.2020 - updated the CutOut Tool such that while adding manual gaps, the cutting geometry is updated on-the-fly if the gap size or tool diameter parameters are adjusted +- updated the UI in Geometry Editor 29.02.2020 diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index a1a13b9b..6b5c3cc5 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -3252,15 +3252,17 @@ class FlatCAMGeoEditor(QtCore.QObject): self.title_box.addWidget(self.title_label, stretch=1) self.title_box.addWidget(QtWidgets.QLabel('')) - self.tw = FCTree(extended_sel=True) + self.tw = FCTree(columns=3, header_hidden=False, protected_column=[0, 1], extended_sel=True) + self.tw.setHeaderLabels(["ID", _("Type"), _("Name")]) + self.tw.setIndentation(0) + self.tw.header().setStretchLastSection(True) + self.tw.header().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents) self.tools_box.addWidget(self.tw) self.geo_font = QtGui.QFont() self.geo_font.setBold(True) - parent = self.tw.invisibleRootItem() - self.geo_parent = self.tw.addParent( - parent, _('Geometry Elements'), expanded=True, color=QtGui.QColor("#000000"), font=self.geo_font) + self.geo_parent = self.tw.invisibleRootItem() # ## Toolbar events and properties self.tools = { @@ -3494,29 +3496,33 @@ class FlatCAMGeoEditor(QtCore.QObject): for elem in self.storage.get_objects(): geo_type = type(elem.geo) - title = None + el_type = None if geo_type is LinearRing: - title = _('ID Ring') + el_type = _('Ring') elif geo_type is LineString: - title = _('ID Line') + el_type = _('Line') elif geo_type is Polygon: - title = _('ID Polygon') + el_type = _('Polygon') elif geo_type is MultiLineString: - title = _('ID Multi-Line') + el_type = _('Multi-Line') elif geo_type is MultiPolygon: - title = _('ID Multi-Polygon') + el_type = _('Multi-Polygon') - self.tw.addChild( + self.tw.addParentEditable( self.geo_parent, [ - '%s:' % title, - str(id(elem)) + str(id(elem)), + '%s' % el_type, + _("Geo Elem") ], - True, font=self.geo_font, - font_items=1 + font_items=2, + # color=QtGui.QColor("#FF0000"), + editable=True ) + self.tw.resize_sig.emit() + def on_geo_elem_selected(self): pass @@ -3526,7 +3532,7 @@ class FlatCAMGeoEditor(QtCore.QObject): for sel in selected_tree_items: for obj_shape in self.storage.get_objects(): try: - if id(obj_shape) == int(sel.text(1)): + if id(obj_shape) == int(sel.text(0)): self.selected.append(obj_shape) except ValueError: pass @@ -3686,9 +3692,7 @@ class FlatCAMGeoEditor(QtCore.QObject): # clear the Tree self.tw.clear() - parent = self.tw.invisibleRootItem() - self.geo_parent = self.tw.addParent( - parent, _('Geometry Elements'), expanded=True, color=QtGui.QColor("#000000"), font=self.geo_font) + self.geo_parent = self.tw.invisibleRootItem() # hide the UI self.geo_frame.hide() diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index da536279..18c46b55 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -153,6 +153,7 @@ class RadioSet(QtWidgets.QWidget): class FCTree(QtWidgets.QTreeWidget): + resize_sig = QtCore.pyqtSignal() def __init__(self, parent=None, columns=2, header_hidden=True, extended_sel=False, protected_column=None): super(FCTree, self).__init__(parent) @@ -167,6 +168,8 @@ class FCTree(QtWidgets.QTreeWidget): self.protected_column = protected_column self.itemDoubleClicked.connect(self.on_double_click) + self.header().sectionDoubleClicked.connect(self.on_header_double_click) + self.resize_sig.connect(self.on_resize) def on_double_click(self, item, column): # from here: https://stackoverflow.com/questions/2801959/making-only-one-column-of-a-qtreewidgetitem-editable @@ -176,6 +179,13 @@ class FCTree(QtWidgets.QTreeWidget): elif tmp_flags & QtCore.Qt.ItemIsEditable: item.setFlags(tmp_flags ^ QtCore.Qt.ItemIsEditable) + def on_header_double_click(self, column): + header = self.header() + header.setSectionResizeMode(column, QtWidgets.QHeaderView.ResizeToContents) + width = header.sectionSize(column) + header.setSectionResizeMode(column, QtWidgets.QHeaderView.Interactive) + header.resizeSection(column, width) + def is_editable(self, tested_col): return False if tested_col in self.protected_column else True @@ -228,6 +238,20 @@ class FCTree(QtWidgets.QTreeWidget): except TypeError: item.setFont(font_items, font) + def resizeEvent(self, event): + """ Resize all sections to content and user interactive """ + + super(FCTree, self).resizeEvent(event) + self.on_resize() + + def on_resize(self): + header = self.header() + for column in range(header.count()): + header.setSectionResizeMode(column, QtWidgets.QHeaderView.ResizeToContents) + width = header.sectionSize(column) + header.setSectionResizeMode(column, QtWidgets.QHeaderView.Interactive) + header.resizeSection(column, width) + class LengthEntry(QtWidgets.QLineEdit): def __init__(self, output_units='IN', decimals=None, parent=None): From 0477a9860ab747096521d0b38d9934065c03a58e Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 2 Mar 2020 06:17:18 +0200 Subject: [PATCH 124/209] - added property that allow the FCComboBox to update the view with the last item loaded; updated the app to use this property --- FlatCAMObj.py | 8 +++--- README.md | 5 +++- flatcamGUI/GUIElements.py | 23 +++++++++++++++--- flatcamGUI/ObjectUI.py | 16 ++++++------ flatcamTools/ToolAlignObjects.py | 4 +-- flatcamTools/ToolCalibration.py | 4 +-- flatcamTools/ToolCopperThieving.py | 16 ++++++------ flatcamTools/ToolCutOut.py | 12 ++++----- flatcamTools/ToolDblSided.py | 18 +++++++------- flatcamTools/ToolExtractDrills.py | 6 ++--- flatcamTools/ToolFiducials.py | 10 ++++---- flatcamTools/ToolFilm.py | 39 ++++++++++++++++-------------- flatcamTools/ToolInvertGerber.py | 6 ++--- flatcamTools/ToolNCC.py | 5 ++-- flatcamTools/ToolOptimal.py | 6 ++--- flatcamTools/ToolPaint.py | 12 ++++----- flatcamTools/ToolPanelize.py | 25 ++++++++++--------- flatcamTools/ToolPunchGerber.py | 10 ++++---- flatcamTools/ToolQRCode.py | 6 ++--- flatcamTools/ToolRulesCheck.py | 38 ++++++++++++++--------------- flatcamTools/ToolSolderPaste.py | 6 ++--- flatcamTools/ToolSub.py | 14 +++++------ 22 files changed, 157 insertions(+), 132 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 2c4dcfdc..963e64a6 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -733,7 +733,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber): # set the model for the Area Exception comboboxes self.ui.obj_combo.setModel(self.app.collection) self.ui.obj_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.ui.obj_combo.setCurrentIndex(1) + self.ui.obj_combo.set_last = True self.ui.type_obj_combo.currentIndexChanged.connect(self.on_type_obj_index_changed) self.ui.tool_type_radio.activated_custom.connect(self.on_tool_type_change) @@ -4101,21 +4101,21 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): dia_item.setFlags(QtCore.Qt.ItemIsEnabled) - offset_item = QtWidgets.QComboBox() + offset_item = FCComboBox() for item in self.offset_item_options: offset_item.addItem(item) # offset_item.setStyleSheet('background-color: rgb(255,255,255)') idx = offset_item.findText(tooluid_value['offset']) offset_item.setCurrentIndex(idx) - type_item = QtWidgets.QComboBox() + type_item = FCComboBox() for item in self.type_item_options: type_item.addItem(item) # type_item.setStyleSheet('background-color: rgb(255,255,255)') idx = type_item.findText(tooluid_value['type']) type_item.setCurrentIndex(idx) - tool_type_item = QtWidgets.QComboBox() + tool_type_item = FCComboBox() for item in self.tool_type_item_options: tool_type_item.addItem(item) # tool_type_item.setStyleSheet('background-color: rgb(255,255,255)') diff --git a/README.md b/README.md index 4b42bb5c..dd227f7c 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +02.03.2020 + +- added property that allow the FCComboBox to update the view with the last item loaded; updated the app to use this property + 01.03.2020 - updated the CutOut Tool such that while adding manual gaps, the cutting geometry is updated on-the-fly if the gap size or tool diameter parameters are adjusted @@ -42,7 +46,6 @@ CAD program, and create G-Code for Isolation routing. - fixed an issue in Gerber Editor where the multiprocessing pool was reported as closed and an ValueError exception was raised in a certain scneraio - on Set Origin, Move to Origin and Move actions for Gerber and Excellon objects the source file will be also updated (the export functions will export an updated object) - in FlatCAMObj.export_gerber() method took into account the possibility of polygons of type 'clear' (the ones found in the Gerber files under the LPC command) - 17.02.2020 - updated the Excellon UI to hold data for each tool diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index 18c46b55..9e3094ec 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -302,7 +302,7 @@ class LengthEntry(QtWidgets.QLineEdit): units = raw[-2:] units = self.scales[self.output_units][units.upper()] value = raw[:-2] - return float(eval(value))* units + return float(eval(value)) * units except IndexError: value = raw return float(eval(value)) @@ -334,7 +334,7 @@ class FloatEntry(QtWidgets.QLineEdit): def mousePressEvent(self, e, Parent=None): super(FloatEntry, self).mousePressEvent(e) # required to deselect on 2e click - if self.readyToEdit == True: + if self.readyToEdit is True: self.selectAll() self.readyToEdit = False @@ -1285,6 +1285,8 @@ class FCComboBox(QtWidgets.QComboBox): self.view.viewport().installEventFilter(self) self.view.setContextMenuPolicy(Qt.CustomContextMenu) + self._set_last = False + # the callback() will be called on customcontextmenu event and will be be passed 2 parameters: # pos = mouse right click click position # self = is the combobox object itself @@ -1306,6 +1308,19 @@ class FCComboBox(QtWidgets.QComboBox): def set_value(self, val): self.setCurrentIndex(self.findText(str(val))) + @property + def set_last(self): + return self._set_last + + @set_last.setter + def set_last(self, val): + self._set_last = val + if self._set_last is True: + self.model().rowsInserted.connect(self.on_model_changed) + + def on_model_changed(self, first, last): + self.setCurrentIndex(last) + class FCInputDialog(QtWidgets.QInputDialog): def __init__(self, parent=None, ok=False, val=None, title=None, text=None, min=None, max=None, decimals=None, @@ -1436,7 +1451,7 @@ class FCDetachableTab(QtWidgets.QTabWidget): self.protect_by_name = protect_by_name if isinstance(protect_by_name, list) else None # Close all detached tabs if the application is closed explicitly - QtWidgets.qApp.aboutToQuit.connect(self.closeDetachedTabs) # @UndefinedVariable + QtWidgets.qApp.aboutToQuit.connect(self.closeDetachedTabs) # @UndefinedVariable # used by the property self.useOldIndex(param) self.use_old_index = None @@ -1916,7 +1931,7 @@ class FCDetachableTab(QtWidgets.QTabWidget): self.dragInitiated = True # If the current movement is a drag initiated by the left button - if ((event.buttons() & QtCore.Qt.LeftButton)) and self.dragInitiated and self.can_be_dragged: + if (event.buttons() & QtCore.Qt.LeftButton) and self.dragInitiated and self.can_be_dragged: # Stop the move event finishMoveEvent = QtGui.QMouseEvent( diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index ca99e6c4..1b298f29 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -445,15 +445,17 @@ class GerberObjectUI(ObjectUI): # ################################################ # ##### Type of object to be excepted ############ # ################################################ - self.type_obj_combo = QtWidgets.QComboBox() - self.type_obj_combo.addItem("Gerber") - self.type_obj_combo.addItem("Excellon") - self.type_obj_combo.addItem("Geometry") + self.type_obj_combo = FCComboBox() + self.type_obj_combo.addItems(["Gerber", "Geometry"]) + + # self.type_obj_combo.addItem("Gerber") + # self.type_obj_combo.addItem("Excellon") + # self.type_obj_combo.addItem("Geometry") # we get rid of item1 ("Excellon") as it is not suitable - self.type_obj_combo.view().setRowHidden(1, True) + # self.type_obj_combo.view().setRowHidden(1, True) self.type_obj_combo.setItemIcon(0, QtGui.QIcon(self.resource_loc + "/flatcam_icon16.png")) - self.type_obj_combo.setItemIcon(2, QtGui.QIcon(self.resource_loc + "/geometry16.png")) + self.type_obj_combo.setItemIcon(1, QtGui.QIcon(self.resource_loc + "/geometry16.png")) self.type_obj_combo_label = QtWidgets.QLabel('%s:' % _("Obj Type")) self.type_obj_combo_label.setToolTip( @@ -468,7 +470,7 @@ class GerberObjectUI(ObjectUI): # ################################################ # ##### The object to be excepted ################ # ################################################ - self.obj_combo = QtWidgets.QComboBox() + self.obj_combo = FCComboBox() self.obj_label = QtWidgets.QLabel('%s:' % _("Object")) self.obj_label.setToolTip(_("Object whose area will be removed from isolation geometry.")) diff --git a/flatcamTools/ToolAlignObjects.py b/flatcamTools/ToolAlignObjects.py index 1ffbe1e5..f8f6d14f 100644 --- a/flatcamTools/ToolAlignObjects.py +++ b/flatcamTools/ToolAlignObjects.py @@ -80,7 +80,7 @@ class AlignObjects(FlatCAMTool): self.object_combo = FCComboBox() self.object_combo.setModel(self.app.collection) self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.object_combo.setCurrentIndex(1) + self.object_combo.set_last = True self.object_combo.setToolTip( _("Object to be aligned.") @@ -116,7 +116,7 @@ class AlignObjects(FlatCAMTool): self.aligner_object_combo = FCComboBox() self.aligner_object_combo.setModel(self.app.collection) self.aligner_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.aligner_object_combo.setCurrentIndex(1) + self.aligner_object_combo.set_last = True self.aligner_object_combo.setToolTip( _("Object to be aligned to. Aligner.") diff --git a/flatcamTools/ToolCalibration.py b/flatcamTools/ToolCalibration.py index 6f9b015c..2a3956e3 100644 --- a/flatcamTools/ToolCalibration.py +++ b/flatcamTools/ToolCalibration.py @@ -206,7 +206,7 @@ class ToolCalibration(FlatCAMTool): self.object_combo = FCComboBox() self.object_combo.setModel(self.app.collection) self.object_combo.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex())) - self.object_combo.setCurrentIndex(1) + self.object_combo.set_last = True self.object_label = QtWidgets.QLabel("%s:" % _("Source object selection")) self.object_label.setToolTip( @@ -628,7 +628,7 @@ class ToolCalibration(FlatCAMTool): ) grid_lay.addWidget(step_5, 45, 0, 1, 3) - self.adj_object_type_combo = QtWidgets.QComboBox() + self.adj_object_type_combo = FCComboBox() self.adj_object_type_combo.addItems([_("Gerber"), _("Excellon"), _("Geometry")]) self.adj_object_type_combo.setCurrentIndex(0) diff --git a/flatcamTools/ToolCopperThieving.py b/flatcamTools/ToolCopperThieving.py index 295aed5a..3949cdda 100644 --- a/flatcamTools/ToolCopperThieving.py +++ b/flatcamTools/ToolCopperThieving.py @@ -9,7 +9,7 @@ from PyQt5 import QtWidgets, QtCore import FlatCAMApp from FlatCAMTool import FlatCAMTool -from flatcamGUI.GUIElements import FCDoubleSpinner, RadioSet, FCEntry +from flatcamGUI.GUIElements import FCDoubleSpinner, RadioSet, FCEntry, FCComboBox from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry, FlatCAMExcellon import shapely.geometry.base as base @@ -66,10 +66,10 @@ class ToolCopperThieving(FlatCAMTool): i_grid_lay.setColumnStretch(0, 0) i_grid_lay.setColumnStretch(1, 1) - self.grb_object_combo = QtWidgets.QComboBox() + self.grb_object_combo = FCComboBox() self.grb_object_combo.setModel(self.app.collection) self.grb_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.grb_object_combo.setCurrentIndex(1) + self.grb_object_combo.set_last = True self.grbobj_label = QtWidgets.QLabel("%s:" % _("GERBER")) self.grbobj_label.setToolTip( @@ -140,7 +140,7 @@ class ToolCopperThieving(FlatCAMTool): _("The type of FlatCAM object to be used as copper thieving reference.\n" "It can be Gerber, Excellon or Geometry.") ) - self.box_combo_type = QtWidgets.QComboBox() + self.box_combo_type = FCComboBox() self.box_combo_type.addItem(_("Reference Gerber")) self.box_combo_type.addItem(_("Reference Excellon")) self.box_combo_type.addItem(_("Reference Geometry")) @@ -152,10 +152,10 @@ class ToolCopperThieving(FlatCAMTool): self.box_combo_label.setToolTip( _("The FlatCAM object to be used as non copper clearing reference.") ) - self.box_combo = QtWidgets.QComboBox() + self.box_combo = FCComboBox() self.box_combo.setModel(self.app.collection) self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.box_combo.setCurrentIndex(1) + self.box_combo.set_last = True grid_lay.addWidget(self.box_combo_label, 5, 0) grid_lay.addWidget(self.box_combo, 5, 1) @@ -417,10 +417,10 @@ class ToolCopperThieving(FlatCAMTool): "the pattern plating mask.") ) - self.sm_object_combo = QtWidgets.QComboBox() + self.sm_object_combo = FCComboBox() self.sm_object_combo.setModel(self.app.collection) self.sm_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.sm_object_combo.setCurrentIndex(1) + self.sm_object_combo.set_last = True grid_lay_1.addWidget(self.sm_obj_label, 7, 0, 1, 3) grid_lay_1.addWidget(self.sm_object_combo, 8, 0, 1, 3) diff --git a/flatcamTools/ToolCutOut.py b/flatcamTools/ToolCutOut.py index 38f4ae7c..a94d7fa5 100644 --- a/flatcamTools/ToolCutOut.py +++ b/flatcamTools/ToolCutOut.py @@ -73,7 +73,7 @@ class CutOut(FlatCAMTool): grid0.addWidget(self.object_label, 0, 0, 1, 2) # Object kind - self.kindlabel = QtWidgets.QLabel('%s:' % _('Object kind')) + self.kindlabel = QtWidgets.QLabel('%s:' % _('Kind')) self.kindlabel.setToolTip( _("Choice of what kind the object we want to cutout is.
" "- Single: contain a single PCB Gerber outline object.
" @@ -93,7 +93,7 @@ class CutOut(FlatCAMTool): {"label": _("Geometry"), "value": "geo"}, ]) - self.type_obj_combo_label = QtWidgets.QLabel('%s:' % _("Object Type")) + self.type_obj_combo_label = QtWidgets.QLabel('%s:' % _("Type")) self.type_obj_combo_label.setToolTip( _("Specify the type of object to be cutout.\n" "It can be of type: Gerber or Geometry.\n" @@ -105,10 +105,10 @@ class CutOut(FlatCAMTool): grid0.addWidget(self.type_obj_radio, 2, 1) # Object to be cutout - self.obj_combo = QtWidgets.QComboBox() + self.obj_combo = FCComboBox() self.obj_combo.setModel(self.app.collection) self.obj_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.obj_combo.setCurrentIndex(1) + self.obj_combo.set_last = True grid0.addWidget(self.obj_combo, 3, 0, 1, 2) @@ -318,10 +318,10 @@ class CutOut(FlatCAMTool): self.layout.addLayout(form_layout_3) # Manual Geo Object - self.man_object_combo = QtWidgets.QComboBox() + self.man_object_combo = FCComboBox() self.man_object_combo.setModel(self.app.collection) self.man_object_combo.setRootModelIndex(self.app.collection.index(2, 0, QtCore.QModelIndex())) - self.man_object_combo.setCurrentIndex(1) + self.man_object_combo.set_last = True self.man_object_label = QtWidgets.QLabel('%s:' % _("Geometry Object")) self.man_object_label.setToolTip( diff --git a/flatcamTools/ToolDblSided.py b/flatcamTools/ToolDblSided.py index 56602125..8612932c 100644 --- a/flatcamTools/ToolDblSided.py +++ b/flatcamTools/ToolDblSided.py @@ -2,7 +2,7 @@ from PyQt5 import QtWidgets, QtCore from FlatCAMTool import FlatCAMTool -from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, EvalEntry, FCEntry, FCButton +from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, EvalEntry, FCEntry, FCButton, FCComboBox from FlatCAMObj import FlatCAMGerber, FlatCAMExcellon, FlatCAMGeometry from numpy import Inf @@ -56,10 +56,10 @@ class DblSidedTool(FlatCAMTool): grid_lay.addWidget(self.m_objects_label, 0, 0, 1, 2) # ## Gerber Object to mirror - self.gerber_object_combo = QtWidgets.QComboBox() + self.gerber_object_combo = FCComboBox() self.gerber_object_combo.setModel(self.app.collection) self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.gerber_object_combo.setCurrentIndex(1) + self.gerber_object_combo.set_last = True self.botlay_label = QtWidgets.QLabel("%s:" % _("GERBER")) self.botlay_label.setToolTip('%s.' % _("Gerber to be mirrored")) @@ -83,10 +83,10 @@ class DblSidedTool(FlatCAMTool): grid_lay.addWidget(self.mirror_gerber_button, 2, 1) # ## Excellon Object to mirror - self.exc_object_combo = QtWidgets.QComboBox() + self.exc_object_combo = FCComboBox() self.exc_object_combo.setModel(self.app.collection) self.exc_object_combo.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex())) - self.exc_object_combo.setCurrentIndex(1) + self.exc_object_combo.set_last = True self.excobj_label = QtWidgets.QLabel("%s:" % _("EXCELLON")) self.excobj_label.setToolTip(_("Excellon Object to be mirrored.")) @@ -110,10 +110,10 @@ class DblSidedTool(FlatCAMTool): grid_lay.addWidget(self.mirror_exc_button, 4, 1) # ## Geometry Object to mirror - self.geo_object_combo = QtWidgets.QComboBox() + self.geo_object_combo = FCComboBox() self.geo_object_combo.setModel(self.app.collection) self.geo_object_combo.setRootModelIndex(self.app.collection.index(2, 0, QtCore.QModelIndex())) - self.geo_object_combo.setCurrentIndex(1) + self.geo_object_combo.set_last = True self.geoobj_label = QtWidgets.QLabel("%s:" % _("GEOMETRY")) self.geoobj_label.setToolTip( @@ -229,10 +229,10 @@ class DblSidedTool(FlatCAMTool): grid_lay2.addWidget(self.box_type_radio, 1, 0, 1, 2) # Object used as BOX reference - self.box_combo = QtWidgets.QComboBox() + self.box_combo = FCComboBox() self.box_combo.setModel(self.app.collection) self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.box_combo.setCurrentIndex(1) + self.box_combo.set_last = True self.box_combo.hide() diff --git a/flatcamTools/ToolExtractDrills.py b/flatcamTools/ToolExtractDrills.py index 287a1571..39e287a4 100644 --- a/flatcamTools/ToolExtractDrills.py +++ b/flatcamTools/ToolExtractDrills.py @@ -8,7 +8,7 @@ from PyQt5 import QtWidgets, QtCore from FlatCAMTool import FlatCAMTool -from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox +from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox, FCComboBox from shapely.geometry import Point @@ -52,10 +52,10 @@ class ToolExtractDrills(FlatCAMTool): grid_lay.setColumnStretch(1, 0) # ## Gerber Object - self.gerber_object_combo = QtWidgets.QComboBox() + self.gerber_object_combo = FCComboBox() self.gerber_object_combo.setModel(self.app.collection) self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.gerber_object_combo.setCurrentIndex(1) + self.gerber_object_combo.set_last = True self.grb_label = QtWidgets.QLabel("%s:" % _("GERBER")) self.grb_label.setToolTip('%s.' % _("Gerber from which to extract drill holes")) diff --git a/flatcamTools/ToolFiducials.py b/flatcamTools/ToolFiducials.py index 342f1d5c..1586f010 100644 --- a/flatcamTools/ToolFiducials.py +++ b/flatcamTools/ToolFiducials.py @@ -8,7 +8,7 @@ from PyQt5 import QtWidgets, QtCore from FlatCAMTool import FlatCAMTool -from flatcamGUI.GUIElements import FCDoubleSpinner, RadioSet, EvalEntry, FCTable +from flatcamGUI.GUIElements import FCDoubleSpinner, RadioSet, EvalEntry, FCTable, FCComboBox from shapely.geometry import Point, Polygon, MultiPolygon, LineString from shapely.geometry import box as box @@ -250,10 +250,10 @@ class ToolFiducials(FlatCAMTool): grid_lay.addWidget(separator_line_1, 8, 0, 1, 2) # Copper Gerber object - self.grb_object_combo = QtWidgets.QComboBox() + self.grb_object_combo = FCComboBox() self.grb_object_combo.setModel(self.app.collection) self.grb_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.grb_object_combo.setCurrentIndex(1) + self.grb_object_combo.set_last = True self.grbobj_label = QtWidgets.QLabel("%s:" % _("Copper Gerber")) self.grbobj_label.setToolTip( @@ -286,10 +286,10 @@ class ToolFiducials(FlatCAMTool): self.sm_object_label.setToolTip( _("The Soldermask Gerber object.") ) - self.sm_object_combo = QtWidgets.QComboBox() + self.sm_object_combo = FCComboBox() self.sm_object_combo.setModel(self.app.collection) self.sm_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.sm_object_combo.setCurrentIndex(1) + self.sm_object_combo.set_last = True grid_lay.addWidget(self.sm_object_label, 13, 0, 1, 2) grid_lay.addWidget(self.sm_object_combo, 14, 0, 1, 2) diff --git a/flatcamTools/ToolFilm.py b/flatcamTools/ToolFilm.py index bf3af64a..98a9f1d3 100644 --- a/flatcamTools/ToolFilm.py +++ b/flatcamTools/ToolFilm.py @@ -65,15 +65,16 @@ class Film(FlatCAMTool): grid0.setColumnStretch(1, 1) # Type of object for which to create the film - self.tf_type_obj_combo = QtWidgets.QComboBox() - self.tf_type_obj_combo.addItem("Gerber") - self.tf_type_obj_combo.addItem("Excellon") - self.tf_type_obj_combo.addItem("Geometry") + self.tf_type_obj_combo = FCComboBox() + self.tf_type_obj_combo.addItems(["Gerber", "Geometry"]) + # self.tf_type_obj_combo.addItem("Gerber") + # self.tf_type_obj_combo.addItem("Excellon") + # self.tf_type_obj_combo.addItem("Geometry") # we get rid of item1 ("Excellon") as it is not suitable for creating film - self.tf_type_obj_combo.view().setRowHidden(1, True) + # self.tf_type_obj_combo.view().setRowHidden(1, True) self.tf_type_obj_combo.setItemIcon(0, QtGui.QIcon(self.app.resource_location + "/flatcam_icon16.png")) - self.tf_type_obj_combo.setItemIcon(2, QtGui.QIcon(self.app.resource_location + "/geometry16.png")) + self.tf_type_obj_combo.setItemIcon(1, QtGui.QIcon(self.app.resource_location + "/geometry16.png")) self.tf_type_obj_combo_label = QtWidgets.QLabel('%s:' % _("Object Type")) self.tf_type_obj_combo_label.setToolTip( @@ -86,10 +87,10 @@ class Film(FlatCAMTool): grid0.addWidget(self.tf_type_obj_combo, 0, 1) # List of objects for which we can create the film - self.tf_object_combo = QtWidgets.QComboBox() + self.tf_object_combo = FCComboBox() self.tf_object_combo.setModel(self.app.collection) self.tf_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.tf_object_combo.setCurrentIndex(1) + self.tf_object_combo.set_last = True self.tf_object_label = QtWidgets.QLabel('%s:' % _("Film Object")) self.tf_object_label.setToolTip( @@ -100,15 +101,17 @@ class Film(FlatCAMTool): # Type of Box Object to be used as an envelope for film creation # Within this we can create negative - self.tf_type_box_combo = QtWidgets.QComboBox() - self.tf_type_box_combo.addItem("Gerber") - self.tf_type_box_combo.addItem("Excellon") - self.tf_type_box_combo.addItem("Geometry") + self.tf_type_box_combo = FCComboBox() + self.tf_type_box_combo.addItems(["Gerber", "Geometry"]) + + # self.tf_type_box_combo.addItem("Gerber") + # self.tf_type_box_combo.addItem("Excellon") + # self.tf_type_box_combo.addItem("Geometry") # we get rid of item1 ("Excellon") as it is not suitable for box when creating film - self.tf_type_box_combo.view().setRowHidden(1, True) + # self.tf_type_box_combo.view().setRowHidden(1, True) self.tf_type_box_combo.setItemIcon(0, QtGui.QIcon(self.app.resource_location + "/flatcam_icon16.png")) - self.tf_type_box_combo.setItemIcon(2, QtGui.QIcon(self.app.resource_location + "/geometry16.png")) + self.tf_type_box_combo.setItemIcon(1, QtGui.QIcon(self.app.resource_location + "/geometry16.png")) self.tf_type_box_combo_label = QtWidgets.QLabel(_("Box Type:")) self.tf_type_box_combo_label.setToolTip( @@ -121,10 +124,10 @@ class Film(FlatCAMTool): grid0.addWidget(self.tf_type_box_combo, 2, 1) # Box - self.tf_box_combo = QtWidgets.QComboBox() + self.tf_box_combo = FCComboBox() self.tf_box_combo.setModel(self.app.collection) self.tf_box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.tf_box_combo.setCurrentIndex(1) + self.tf_box_combo.set_last = True self.tf_box_combo_label = QtWidgets.QLabel('%s:' % _("Box Object")) self.tf_box_combo_label.setToolTip( @@ -366,10 +369,10 @@ class Film(FlatCAMTool): self.exc_label.setToolTip( _("Remove the geometry of Excellon from the Film to create the holes in pads.") ) - self.exc_combo = QtWidgets.QComboBox() + self.exc_combo = FCComboBox() self.exc_combo.setModel(self.app.collection) self.exc_combo.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex())) - self.exc_combo.setCurrentIndex(1) + self.exc_combo.set_last = True punch_grid.addWidget(self.exc_label, 1, 0) punch_grid.addWidget(self.exc_combo, 1, 1) diff --git a/flatcamTools/ToolInvertGerber.py b/flatcamTools/ToolInvertGerber.py index 4d8e62c8..46124730 100644 --- a/flatcamTools/ToolInvertGerber.py +++ b/flatcamTools/ToolInvertGerber.py @@ -8,7 +8,7 @@ from PyQt5 import QtWidgets, QtCore from FlatCAMTool import FlatCAMTool -from flatcamGUI.GUIElements import FCButton, FCDoubleSpinner, RadioSet +from flatcamGUI.GUIElements import FCButton, FCDoubleSpinner, RadioSet, FCComboBox from shapely.geometry import box @@ -63,10 +63,10 @@ class ToolInvertGerber(FlatCAMTool): grid0.addWidget(QtWidgets.QLabel(''), 0, 0, 1, 2) # Target Gerber Object - self.gerber_combo = QtWidgets.QComboBox() + self.gerber_combo = FCComboBox() self.gerber_combo.setModel(self.app.collection) self.gerber_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.gerber_combo.setCurrentIndex(1) + self.gerber_combo.set_last = True self.gerber_label = QtWidgets.QLabel('%s:' % _("GERBER")) self.gerber_label.setToolTip( diff --git a/flatcamTools/ToolNCC.py b/flatcamTools/ToolNCC.py index 4b7c7253..1203a3c5 100644 --- a/flatcamTools/ToolNCC.py +++ b/flatcamTools/ToolNCC.py @@ -101,7 +101,8 @@ class NonCopperClear(FlatCAMTool, Gerber): self.object_combo = FCComboBox() self.object_combo.setModel(self.app.collection) self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.object_combo.setCurrentIndex(1) + # self.object_combo.setCurrentIndex(1) + self.object_combo.set_last = True self.object_label = QtWidgets.QLabel('%s:' % _("Object")) self.object_label.setToolTip(_("Object to be cleared of excess copper.")) @@ -563,7 +564,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.box_combo = FCComboBox() self.box_combo.setModel(self.app.collection) self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.box_combo.setCurrentIndex(1) + self.box_combo.set_last = True form1.addRow(self.box_combo_label, self.box_combo) self.box_combo.hide() diff --git a/flatcamTools/ToolOptimal.py b/flatcamTools/ToolOptimal.py index 16c00efa..0cbbf0f6 100644 --- a/flatcamTools/ToolOptimal.py +++ b/flatcamTools/ToolOptimal.py @@ -8,7 +8,7 @@ from PyQt5 import QtWidgets, QtCore, QtGui from FlatCAMTool import FlatCAMTool -from flatcamGUI.GUIElements import OptionalHideInputSection, FCTextArea, FCEntry, FCSpinner, FCCheckBox +from flatcamGUI.GUIElements import OptionalHideInputSection, FCTextArea, FCEntry, FCSpinner, FCCheckBox, FCComboBox from FlatCAMObj import FlatCAMGerber import FlatCAMApp @@ -63,10 +63,10 @@ class ToolOptimal(FlatCAMTool): form_lay.addRow(QtWidgets.QLabel("")) # ## Gerber Object to mirror - self.gerber_object_combo = QtWidgets.QComboBox() + self.gerber_object_combo = FCComboBox() self.gerber_object_combo.setModel(self.app.collection) self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.gerber_object_combo.setCurrentIndex(1) + self.gerber_object_combo.set_last = True self.gerber_object_label = QtWidgets.QLabel("%s:" % _("GERBER")) self.gerber_object_label.setToolTip( diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 7f9a8c27..0c436f58 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -94,10 +94,10 @@ class ToolPaint(FlatCAMTool, Gerber): # ################################################ # ##### The object to be painted ################# # ################################################ - self.obj_combo = QtWidgets.QComboBox() + self.obj_combo = FCComboBox() self.obj_combo.setModel(self.app.collection) self.obj_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.obj_combo.setCurrentIndex(1) + self.obj_combo.set_last = True self.object_label = QtWidgets.QLabel('%s:' % _("Object")) self.object_label.setToolTip(_("Object to be painted.")) @@ -496,7 +496,7 @@ class ToolPaint(FlatCAMTool, Gerber): _("The type of FlatCAM object to be used as paint reference.\n" "It can be Gerber, Excellon or Geometry.") ) - self.box_combo_type = QtWidgets.QComboBox() + self.box_combo_type = FCComboBox() self.box_combo_type.addItem(_("Reference Gerber")) self.box_combo_type.addItem(_("Reference Excellon")) self.box_combo_type.addItem(_("Reference Geometry")) @@ -506,10 +506,10 @@ class ToolPaint(FlatCAMTool, Gerber): self.box_combo_label.setToolTip( _("The FlatCAM object to be used as non copper clearing reference.") ) - self.box_combo = QtWidgets.QComboBox() + self.box_combo = FCComboBox() self.box_combo.setModel(self.app.collection) self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.box_combo.setCurrentIndex(1) + self.box_combo.set_last = True form1.addRow(self.box_combo_label, self.box_combo) self.box_combo.hide() @@ -1058,7 +1058,7 @@ class ToolPaint(FlatCAMTool, Gerber): dia.setFlags(QtCore.Qt.ItemIsEnabled) - tool_type_item = QtWidgets.QComboBox() + tool_type_item = FCComboBox() for item in self.tool_type_item_options: tool_type_item.addItem(item) # tool_type_item.setStyleSheet('background-color: rgb(255,255,255)') diff --git a/flatcamTools/ToolPanelize.py b/flatcamTools/ToolPanelize.py index 9494c2d0..0b7f5fec 100644 --- a/flatcamTools/ToolPanelize.py +++ b/flatcamTools/ToolPanelize.py @@ -8,7 +8,7 @@ from PyQt5 import QtWidgets, QtGui, QtCore from FlatCAMTool import FlatCAMTool -from flatcamGUI.GUIElements import FCSpinner, FCDoubleSpinner, RadioSet, FCCheckBox, OptionalInputSection +from flatcamGUI.GUIElements import FCSpinner, FCDoubleSpinner, RadioSet, FCCheckBox, OptionalInputSection, FCComboBox from FlatCAMObj import FlatCAMGeometry, FlatCAMGerber, FlatCAMExcellon import FlatCAMApp from copy import deepcopy @@ -66,7 +66,7 @@ class Panelize(FlatCAMTool): self.layout.addLayout(form_layout_0) # Type of object to be panelized - self.type_obj_combo = QtWidgets.QComboBox() + self.type_obj_combo = FCComboBox() self.type_obj_combo.addItem("Gerber") self.type_obj_combo.addItem("Excellon") self.type_obj_combo.addItem("Geometry") @@ -80,10 +80,10 @@ class Panelize(FlatCAMTool): form_layout_0.addRow(self.type_object_label, self.type_obj_combo) # Object to be panelized - self.object_combo = QtWidgets.QComboBox() + self.object_combo = FCComboBox() self.object_combo.setModel(self.app.collection) self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.object_combo.setCurrentIndex(1) + self.object_combo.set_last = True self.object_combo.setToolTip( _("Object to be panelized. This means that it will\n" @@ -114,15 +114,16 @@ class Panelize(FlatCAMTool): form_layout.addRow(self.reference_radio) # Type of Box Object to be used as an envelope for panelization - self.type_box_combo = QtWidgets.QComboBox() - self.type_box_combo.addItem("Gerber") - self.type_box_combo.addItem("Excellon") - self.type_box_combo.addItem("Geometry") + self.type_box_combo = FCComboBox() + self.type_box_combo.addItems(["Gerber", "Geometry"]) + # self.type_box_combo.addItem("Gerber") + # self.type_box_combo.addItem("Excellon") + # self.type_box_combo.addItem("Geometry") # we get rid of item1 ("Excellon") as it is not suitable for use as a "box" for panelizing - self.type_box_combo.view().setRowHidden(1, True) + # self.type_box_combo.view().setRowHidden(1, True) self.type_box_combo.setItemIcon(0, QtGui.QIcon(self.app.resource_location + "/flatcam_icon16.png")) - self.type_box_combo.setItemIcon(2, QtGui.QIcon(self.app.resource_location + "/geometry16.png")) + self.type_box_combo.setItemIcon(1, QtGui.QIcon(self.app.resource_location + "/geometry16.png")) self.type_box_combo_label = QtWidgets.QLabel('%s:' % _("Box Type")) self.type_box_combo_label.setToolTip( @@ -134,10 +135,10 @@ class Panelize(FlatCAMTool): form_layout.addRow(self.type_box_combo_label, self.type_box_combo) # Box - self.box_combo = QtWidgets.QComboBox() + self.box_combo = FCComboBox() self.box_combo.setModel(self.app.collection) self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.box_combo.setCurrentIndex(1) + self.box_combo.set_last = True self.box_combo.setToolTip( _("The actual object that is used a container for the\n " diff --git a/flatcamTools/ToolPunchGerber.py b/flatcamTools/ToolPunchGerber.py index 660dae7f..c4c9ae61 100644 --- a/flatcamTools/ToolPunchGerber.py +++ b/flatcamTools/ToolPunchGerber.py @@ -8,7 +8,7 @@ from PyQt5 import QtCore, QtWidgets from FlatCAMTool import FlatCAMTool -from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox +from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox, FCComboBox from copy import deepcopy import logging @@ -55,10 +55,10 @@ class ToolPunchGerber(FlatCAMTool): grid_lay.setColumnStretch(1, 0) # ## Gerber Object - self.gerber_object_combo = QtWidgets.QComboBox() + self.gerber_object_combo = FCComboBox() self.gerber_object_combo.setModel(self.app.collection) self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.gerber_object_combo.setCurrentIndex(1) + self.gerber_object_combo.set_last = True self.grb_label = QtWidgets.QLabel("%s:" % _("GERBER")) self.grb_label.setToolTip('%s.' % _("Gerber into which to punch holes")) @@ -165,10 +165,10 @@ class ToolPunchGerber(FlatCAMTool): _("Remove the geometry of Excellon from the Gerber to create the holes in pads.") ) - self.exc_combo = QtWidgets.QComboBox() + self.exc_combo = FCComboBox() self.exc_combo.setModel(self.app.collection) self.exc_combo.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex())) - self.exc_combo.setCurrentIndex(1) + self.exc_combo.set_last = True grid0.addWidget(self.exc_label, 3, 0, 1, 2) grid0.addWidget(self.exc_combo, 4, 0, 1, 2) diff --git a/flatcamTools/ToolQRCode.py b/flatcamTools/ToolQRCode.py index 2486ba7f..67add5c9 100644 --- a/flatcamTools/ToolQRCode.py +++ b/flatcamTools/ToolQRCode.py @@ -9,7 +9,7 @@ from PyQt5 import QtWidgets, QtCore, QtGui from PyQt5.QtCore import Qt from FlatCAMTool import FlatCAMTool -from flatcamGUI.GUIElements import RadioSet, FCTextArea, FCSpinner, FCEntry, FCCheckBox +from flatcamGUI.GUIElements import RadioSet, FCTextArea, FCSpinner, FCEntry, FCCheckBox, FCComboBox from flatcamParsers.ParseSVG import * from shapely.geometry.base import * @@ -69,10 +69,10 @@ class QRCode(FlatCAMTool): i_grid_lay.setColumnStretch(0, 0) i_grid_lay.setColumnStretch(1, 1) - self.grb_object_combo = QtWidgets.QComboBox() + self.grb_object_combo = FCComboBox() self.grb_object_combo.setModel(self.app.collection) self.grb_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.grb_object_combo.setCurrentIndex(1) + self.grb_object_combo.set_last = True self.grbobj_label = QtWidgets.QLabel("%s:" % _("GERBER")) self.grbobj_label.setToolTip( diff --git a/flatcamTools/ToolRulesCheck.py b/flatcamTools/ToolRulesCheck.py index ffd5844d..9deb26be 100644 --- a/flatcamTools/ToolRulesCheck.py +++ b/flatcamTools/ToolRulesCheck.py @@ -8,7 +8,7 @@ from PyQt5 import QtWidgets from FlatCAMTool import FlatCAMTool -from flatcamGUI.GUIElements import FCDoubleSpinner, FCCheckBox, OptionalInputSection +from flatcamGUI.GUIElements import FCDoubleSpinner, FCCheckBox, OptionalInputSection, FCComboBox from copy import deepcopy from FlatCAMPool import * @@ -69,10 +69,10 @@ class RulesCheck(FlatCAMTool): self.grid_layout.addWidget(self.all_obj_cb, 0, 2) # Copper Top object - self.copper_t_object = QtWidgets.QComboBox() + self.copper_t_object = FCComboBox() self.copper_t_object.setModel(self.app.collection) self.copper_t_object.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.copper_t_object.setCurrentIndex(1) + self.copper_t_object.set_last = True self.copper_t_object_lbl = QtWidgets.QLabel('%s:' % _("Top")) self.copper_t_object_lbl.setToolTip( @@ -86,10 +86,10 @@ class RulesCheck(FlatCAMTool): self.grid_layout.addWidget(self.copper_t_cb, 1, 2) # Copper Bottom object - self.copper_b_object = QtWidgets.QComboBox() + self.copper_b_object = FCComboBox() self.copper_b_object.setModel(self.app.collection) self.copper_b_object.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.copper_b_object.setCurrentIndex(1) + self.copper_b_object.set_last = True self.copper_b_object_lbl = QtWidgets.QLabel('%s:' % _("Bottom")) self.copper_b_object_lbl.setToolTip( @@ -103,10 +103,10 @@ class RulesCheck(FlatCAMTool): self.grid_layout.addWidget(self.copper_b_cb, 2, 2) # SolderMask Top object - self.sm_t_object = QtWidgets.QComboBox() + self.sm_t_object = FCComboBox() self.sm_t_object.setModel(self.app.collection) self.sm_t_object.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.sm_t_object.setCurrentIndex(1) + self.sm_t_object.set_last = True self.sm_t_object_lbl = QtWidgets.QLabel('%s:' % _("SM Top")) self.sm_t_object_lbl.setToolTip( @@ -120,10 +120,10 @@ class RulesCheck(FlatCAMTool): self.grid_layout.addWidget(self.sm_t_cb, 3, 2) # SolderMask Bottom object - self.sm_b_object = QtWidgets.QComboBox() + self.sm_b_object = FCComboBox() self.sm_b_object.setModel(self.app.collection) self.sm_b_object.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.sm_b_object.setCurrentIndex(1) + self.sm_b_object.set_last = True self.sm_b_object_lbl = QtWidgets.QLabel('%s:' % _("SM Bottom")) self.sm_b_object_lbl.setToolTip( @@ -137,10 +137,10 @@ class RulesCheck(FlatCAMTool): self.grid_layout.addWidget(self.sm_b_cb, 4, 2) # SilkScreen Top object - self.ss_t_object = QtWidgets.QComboBox() + self.ss_t_object = FCComboBox() self.ss_t_object.setModel(self.app.collection) self.ss_t_object.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.ss_t_object.setCurrentIndex(1) + self.ss_t_object.set_last = True self.ss_t_object_lbl = QtWidgets.QLabel('%s:' % _("Silk Top")) self.ss_t_object_lbl.setToolTip( @@ -154,10 +154,10 @@ class RulesCheck(FlatCAMTool): self.grid_layout.addWidget(self.ss_t_cb, 5, 2) # SilkScreen Bottom object - self.ss_b_object = QtWidgets.QComboBox() + self.ss_b_object = FCComboBox() self.ss_b_object.setModel(self.app.collection) self.ss_b_object.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.ss_b_object.setCurrentIndex(1) + self.ss_b_object.set_last = True self.ss_b_object_lbl = QtWidgets.QLabel('%s:' % _("Silk Bottom")) self.ss_b_object_lbl.setToolTip( @@ -171,10 +171,10 @@ class RulesCheck(FlatCAMTool): self.grid_layout.addWidget(self.ss_b_cb, 6, 2) # Outline object - self.outline_object = QtWidgets.QComboBox() + self.outline_object = FCComboBox() self.outline_object.setModel(self.app.collection) self.outline_object.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.outline_object.setCurrentIndex(1) + self.outline_object.set_last = True self.outline_object_lbl = QtWidgets.QLabel('%s:' % _("Outline")) self.outline_object_lbl.setToolTip( @@ -197,10 +197,10 @@ class RulesCheck(FlatCAMTool): self.grid_layout.addWidget(self.excellon_title_lbl, 9, 0, 1, 3) # Excellon 1 object - self.e1_object = QtWidgets.QComboBox() + self.e1_object = FCComboBox() self.e1_object.setModel(self.app.collection) self.e1_object.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex())) - self.e1_object.setCurrentIndex(1) + self.e1_object.set_last = True self.e1_object_lbl = QtWidgets.QLabel('%s:' % _("Excellon 1")) self.e1_object_lbl.setToolTip( @@ -215,10 +215,10 @@ class RulesCheck(FlatCAMTool): self.grid_layout.addWidget(self.e1_cb, 10, 2) # Excellon 2 object - self.e2_object = QtWidgets.QComboBox() + self.e2_object = FCComboBox() self.e2_object.setModel(self.app.collection) self.e2_object.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex())) - self.e2_object.setCurrentIndex(1) + self.e2_object.set_last = True self.e2_object_lbl = QtWidgets.QLabel('%s:' % _("Excellon 2")) self.e2_object_lbl.setToolTip( diff --git a/flatcamTools/ToolSolderPaste.py b/flatcamTools/ToolSolderPaste.py index 655ab3aa..568f164e 100644 --- a/flatcamTools/ToolSolderPaste.py +++ b/flatcamTools/ToolSolderPaste.py @@ -61,7 +61,7 @@ class SolderPaste(FlatCAMTool): self.obj_combo = FCComboBox(callback=self.on_rmb_combo) self.obj_combo.setModel(self.app.collection) self.obj_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.obj_combo.setCurrentIndex(1) + self.obj_combo.set_last = True self.object_label = QtWidgets.QLabel("Gerber: ") self.object_label.setToolTip( @@ -383,7 +383,7 @@ class SolderPaste(FlatCAMTool): self.geo_obj_combo = FCComboBox(callback=self.on_rmb_combo) self.geo_obj_combo.setModel(self.app.collection) self.geo_obj_combo.setRootModelIndex(self.app.collection.index(2, 0, QtCore.QModelIndex())) - self.geo_obj_combo.setCurrentIndex(1) + self.geo_obj_combo.set_last = True self.geo_object_label = QtWidgets.QLabel('%s:' % _("Geo Result")) self.geo_object_label.setToolTip( @@ -416,7 +416,7 @@ class SolderPaste(FlatCAMTool): self.cnc_obj_combo = FCComboBox(callback=self.on_rmb_combo) self.cnc_obj_combo.setModel(self.app.collection) self.cnc_obj_combo.setRootModelIndex(self.app.collection.index(3, 0, QtCore.QModelIndex())) - self.cnc_obj_combo.setCurrentIndex(1) + self.cnc_obj_combo.set_last = True self.cnc_object_label = QtWidgets.QLabel('%s:' % _("CNC Result")) self.cnc_object_label.setToolTip( diff --git a/flatcamTools/ToolSub.py b/flatcamTools/ToolSub.py index 9d547ed5..c63ff5e2 100644 --- a/flatcamTools/ToolSub.py +++ b/flatcamTools/ToolSub.py @@ -8,7 +8,7 @@ from PyQt5 import QtWidgets, QtCore from FlatCAMTool import FlatCAMTool -from flatcamGUI.GUIElements import FCCheckBox, FCButton +from flatcamGUI.GUIElements import FCCheckBox, FCButton, FCComboBox from shapely.geometry import Polygon, MultiPolygon, MultiLineString, LineString from shapely.ops import cascaded_union @@ -66,7 +66,7 @@ class ToolSub(FlatCAMTool): form_layout.addRow(self.gerber_title) # Target Gerber Object - self.target_gerber_combo = QtWidgets.QComboBox() + self.target_gerber_combo = FCComboBox() self.target_gerber_combo.setModel(self.app.collection) self.target_gerber_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.target_gerber_combo.setCurrentIndex(1) @@ -80,10 +80,10 @@ class ToolSub(FlatCAMTool): form_layout.addRow(self.target_gerber_label, self.target_gerber_combo) # Substractor Gerber Object - self.sub_gerber_combo = QtWidgets.QComboBox() + self.sub_gerber_combo = FCComboBox() self.sub_gerber_combo.setModel(self.app.collection) self.sub_gerber_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.sub_gerber_combo.setCurrentIndex(1) + self.sub_gerber_combo.set_last = True self.sub_gerber_label = QtWidgets.QLabel('%s:' % _("Subtractor")) self.sub_gerber_label.setToolTip( @@ -118,7 +118,7 @@ class ToolSub(FlatCAMTool): form_geo_layout.addRow(self.geo_title) # Target Geometry Object - self.target_geo_combo = QtWidgets.QComboBox() + self.target_geo_combo = FCComboBox() self.target_geo_combo.setModel(self.app.collection) self.target_geo_combo.setRootModelIndex(self.app.collection.index(2, 0, QtCore.QModelIndex())) self.target_geo_combo.setCurrentIndex(1) @@ -132,10 +132,10 @@ class ToolSub(FlatCAMTool): form_geo_layout.addRow(self.target_geo_label, self.target_geo_combo) # Substractor Geometry Object - self.sub_geo_combo = QtWidgets.QComboBox() + self.sub_geo_combo = FCComboBox() self.sub_geo_combo.setModel(self.app.collection) self.sub_geo_combo.setRootModelIndex(self.app.collection.index(2, 0, QtCore.QModelIndex())) - self.sub_geo_combo.setCurrentIndex(1) + self.sub_geo_combo.set_last = True self.sub_geo_label = QtWidgets.QLabel('%s:' % _("Subtractor")) self.sub_geo_label.setToolTip( From 15ee54d0571301b79e30ce6b549f749bb3a7123d Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 4 Mar 2020 00:27:51 +0200 Subject: [PATCH 125/209] - updated all the FlatCAM Tools and the Gerber UI FCComboBoxes to update the box value with the latest object loaded in the App - some fixes in the NCC Tool - modified some strings --- FlatCAMObj.py | 13 +++- README.md | 6 ++ flatcamGUI/GUIElements.py | 21 ++++-- flatcamGUI/ObjectUI.py | 6 +- flatcamTools/ToolAlignObjects.py | 6 +- flatcamTools/ToolCalibration.py | 31 ++++++--- flatcamTools/ToolCopperThieving.py | 78 +++++++++++---------- flatcamTools/ToolCutOut.py | 6 +- flatcamTools/ToolDblSided.py | 23 ++++--- flatcamTools/ToolExtractDrills.py | 3 +- flatcamTools/ToolFiducials.py | 6 +- flatcamTools/ToolFilm.py | 29 +++++--- flatcamTools/ToolImage.py | 13 ++-- flatcamTools/ToolInvertGerber.py | 3 +- flatcamTools/ToolNCC.py | 105 ++++++++++++++++------------- flatcamTools/ToolOptimal.py | 3 +- flatcamTools/ToolPaint.py | 76 +++++++++++---------- flatcamTools/ToolPanelize.py | 20 ++++-- flatcamTools/ToolPunchGerber.py | 6 +- flatcamTools/ToolQRCode.py | 5 +- flatcamTools/ToolRulesCheck.py | 27 +++++--- flatcamTools/ToolSolderPaste.py | 9 ++- flatcamTools/ToolSub.py | 14 ++-- 23 files changed, 309 insertions(+), 200 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 963e64a6..610df50d 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -733,7 +733,12 @@ class FlatCAMGerber(FlatCAMObj, Gerber): # set the model for the Area Exception comboboxes self.ui.obj_combo.setModel(self.app.collection) self.ui.obj_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.ui.obj_combo.set_last = True + self.ui.obj_combo.is_last = True + self.ui.obj_combo.obj_type = { + _("Gerber"): "Gerber", _("Geometry"): "Geometry" + }[self.ui.type_obj_combo.get_value()] + self.on_type_obj_index_changed() + self.ui.type_obj_combo.currentIndexChanged.connect(self.on_type_obj_index_changed) self.ui.tool_type_radio.activated_custom.connect(self.on_tool_type_change) @@ -813,10 +818,12 @@ class FlatCAMGerber(FlatCAMObj, Gerber): tool_diameter = tdia + (2 * cutz * math.tan(math.radians(half_tip_angle))) self.ui.iso_tool_dia_entry.set_value(tool_diameter) - def on_type_obj_index_changed(self, index): - obj_type = self.ui.type_obj_combo.currentIndex() + def on_type_obj_index_changed(self): + val = self.ui.type_obj_combo.get_value() + obj_type = {"Gerber": 0, "Geometry": 2}[val] self.ui.obj_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) self.ui.obj_combo.setCurrentIndex(0) + self.ui.obj_combo.obj_type = {_("Gerber"): "Gerber", _("Geometry"): "Geometry"}[val] def on_tool_type_change(self, state): if state == 'circular': diff --git a/README.md b/README.md index dd227f7c..924856e7 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,12 @@ CAD program, and create G-Code for Isolation routing. ================================================= +4.03.2020 + +- updated all the FlatCAM Tools and the Gerber UI FCComboBoxes to update the box value with the latest object loaded in the App +- some fixes in the NCC Tool +- modified some strings + 02.03.2020 - added property that allow the FCComboBox to update the view with the last item loaded; updated the app to use this property diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index 9e3094ec..f9c7b814 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -1286,6 +1286,7 @@ class FCComboBox(QtWidgets.QComboBox): self.view.setContextMenuPolicy(Qt.CustomContextMenu) self._set_last = False + self._obj_type = None # the callback() will be called on customcontextmenu event and will be be passed 2 parameters: # pos = mouse right click click position @@ -1309,17 +1310,27 @@ class FCComboBox(QtWidgets.QComboBox): self.setCurrentIndex(self.findText(str(val))) @property - def set_last(self): + def is_last(self): return self._set_last - @set_last.setter - def set_last(self, val): + @is_last.setter + def is_last(self, val): self._set_last = val if self._set_last is True: self.model().rowsInserted.connect(self.on_model_changed) + self.setCurrentIndex(1) - def on_model_changed(self, first, last): - self.setCurrentIndex(last) + @property + def obj_type(self): + return self._obj_type + + @obj_type.setter + def obj_type(self, val): + self._obj_type = val + + def on_model_changed(self, parent, first, last): + if self.model().data(parent, QtCore.Qt.DisplayRole) == self.obj_type: + self.setCurrentIndex(first) class FCInputDialog(QtWidgets.QInputDialog): diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index 1b298f29..39de3558 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -446,11 +446,7 @@ class GerberObjectUI(ObjectUI): # ##### Type of object to be excepted ############ # ################################################ self.type_obj_combo = FCComboBox() - self.type_obj_combo.addItems(["Gerber", "Geometry"]) - - # self.type_obj_combo.addItem("Gerber") - # self.type_obj_combo.addItem("Excellon") - # self.type_obj_combo.addItem("Geometry") + self.type_obj_combo.addItems([_("Gerber"), _("Geometry")]) # we get rid of item1 ("Excellon") as it is not suitable # self.type_obj_combo.view().setRowHidden(1, True) diff --git a/flatcamTools/ToolAlignObjects.py b/flatcamTools/ToolAlignObjects.py index f8f6d14f..863f27c3 100644 --- a/flatcamTools/ToolAlignObjects.py +++ b/flatcamTools/ToolAlignObjects.py @@ -80,7 +80,7 @@ class AlignObjects(FlatCAMTool): self.object_combo = FCComboBox() self.object_combo.setModel(self.app.collection) self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.object_combo.set_last = True + self.object_combo.is_last = True self.object_combo.setToolTip( _("Object to be aligned.") @@ -116,7 +116,7 @@ class AlignObjects(FlatCAMTool): self.aligner_object_combo = FCComboBox() self.aligner_object_combo.setModel(self.app.collection) self.aligner_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.aligner_object_combo.set_last = True + self.aligner_object_combo.is_last = True self.aligner_object_combo.setToolTip( _("Object to be aligned to. Aligner.") @@ -270,11 +270,13 @@ class AlignObjects(FlatCAMTool): obj_type = {'grb': 0, 'exc': 1}[val] self.object_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) self.object_combo.setCurrentIndex(0) + self.object_combo.obj_type = {'grb': "Gerber", 'exc': "Excellon"}[val] def on_type_aligner_changed(self, val): obj_type = {'grb': 0, 'exc': 1}[val] self.aligner_object_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) self.aligner_object_combo.setCurrentIndex(0) + self.aligner_object_combo.obj_type = {'grb': "Gerber", 'exc': "Excellon"}[val] def on_align(self): self.app.delete_selection_shape() diff --git a/flatcamTools/ToolCalibration.py b/flatcamTools/ToolCalibration.py index 2a3956e3..b2a879fe 100644 --- a/flatcamTools/ToolCalibration.py +++ b/flatcamTools/ToolCalibration.py @@ -195,7 +195,6 @@ class ToolCalibration(FlatCAMTool): self.obj_type_combo = FCComboBox() self.obj_type_combo.addItem(_("Gerber")) self.obj_type_combo.addItem(_("Excellon")) - self.obj_type_combo.setCurrentIndex(1) self.obj_type_combo.setItemIcon(0, QtGui.QIcon(self.app.resource_location + "/flatcam_icon16.png")) self.obj_type_combo.setItemIcon(1, QtGui.QIcon(self.app.resource_location + "/drill16.png")) @@ -206,7 +205,7 @@ class ToolCalibration(FlatCAMTool): self.object_combo = FCComboBox() self.object_combo.setModel(self.app.collection) self.object_combo.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex())) - self.object_combo.set_last = True + self.object_combo.is_last = True self.object_label = QtWidgets.QLabel("%s:" % _("Source object selection")) self.object_label.setToolTip( @@ -630,16 +629,13 @@ class ToolCalibration(FlatCAMTool): self.adj_object_type_combo = FCComboBox() self.adj_object_type_combo.addItems([_("Gerber"), _("Excellon"), _("Geometry")]) - self.adj_object_type_combo.setCurrentIndex(0) self.adj_object_type_combo.setItemIcon(0, QtGui.QIcon(self.app.resource_location + "/flatcam_icon16.png")) self.adj_object_type_combo.setItemIcon(1, QtGui.QIcon(self.app.resource_location + "/drill16.png")) self.adj_object_type_combo.setItemIcon(2, QtGui.QIcon(self.app.resource_location + "/geometry16.png")) self.adj_object_type_label = QtWidgets.QLabel("%s:" % _("Adjusted object type")) - self.adj_object_type_label.setToolTip( - _("Type of the FlatCAM Object to be adjusted.") - ) + self.adj_object_type_label.setToolTip(_("Type of the FlatCAM Object to be adjusted.")) grid_lay.addWidget(self.adj_object_type_label, 46, 0, 1, 3) grid_lay.addWidget(self.adj_object_type_combo, 47, 0, 1, 3) @@ -647,7 +643,10 @@ class ToolCalibration(FlatCAMTool): self.adj_object_combo = FCComboBox() self.adj_object_combo.setModel(self.app.collection) self.adj_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.adj_object_combo.setCurrentIndex(0) + self.adj_object_combo.is_last = True + self.adj_object_combo.obj_type = { + _("Gerber"): "Gerber", _("Excellon"): "Excellon", _("Geometry"): "Geometry" + }[self.adj_object_type_combo.get_value()] self.adj_object_label = QtWidgets.QLabel("%s:" % _("Adjusted object selection")) self.adj_object_label.setToolTip( @@ -787,6 +786,14 @@ class ToolCalibration(FlatCAMTool): self.skewx_entry.set_value(0.0) self.skewy_entry.set_value(0.0) + # default object selection is Excellon = index_1 + self.obj_type_combo.setCurrentIndex(1) + self.on_obj_type_combo() + + self.adj_object_type_combo.setCurrentIndex(0) + self.on_adj_obj_type_combo() + # self.adj_object_combo.setCurrentIndex(0) + # calibrated object self.cal_object = None @@ -795,12 +802,18 @@ class ToolCalibration(FlatCAMTool): def on_obj_type_combo(self): obj_type = self.obj_type_combo.currentIndex() self.object_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) - self.object_combo.setCurrentIndex(0) + # self.object_combo.setCurrentIndex(0) + self.object_combo.obj_type = { + _("Gerber"): "Gerber", _("Excellon"): "Excellon" + }[self.obj_type_combo.get_value()] def on_adj_obj_type_combo(self): obj_type = self.adj_object_type_combo.currentIndex() self.adj_object_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) - self.adj_object_combo.setCurrentIndex(0) + # self.adj_object_combo.setCurrentIndex(0) + self.adj_object_combo.obj_type = { + _("Gerber"): "Gerber", _("Excellon"): "Excellon", _("Geometry"): "Geometry" + }[self.adj_object_type_combo.get_value()] def on_cal_source_radio(self, val): if val == 'object': diff --git a/flatcamTools/ToolCopperThieving.py b/flatcamTools/ToolCopperThieving.py index 3949cdda..7000ca0e 100644 --- a/flatcamTools/ToolCopperThieving.py +++ b/flatcamTools/ToolCopperThieving.py @@ -69,7 +69,8 @@ class ToolCopperThieving(FlatCAMTool): self.grb_object_combo = FCComboBox() self.grb_object_combo.setModel(self.app.collection) self.grb_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.grb_object_combo.set_last = True + self.grb_object_combo.is_last = True + self.grb_object_combo.obj_type = 'Gerber' self.grbobj_label = QtWidgets.QLabel("%s:" % _("GERBER")) self.grbobj_label.setToolTip( @@ -135,35 +136,36 @@ class ToolCopperThieving(FlatCAMTool): grid_lay.addWidget(self.reference_label, 3, 0) grid_lay.addWidget(self.reference_radio, 3, 1) - self.box_combo_type_label = QtWidgets.QLabel('%s:' % _("Ref. Type")) - self.box_combo_type_label.setToolTip( + self.ref_combo_type_label = QtWidgets.QLabel('%s:' % _("Ref. Type")) + self.ref_combo_type_label.setToolTip( _("The type of FlatCAM object to be used as copper thieving reference.\n" "It can be Gerber, Excellon or Geometry.") ) - self.box_combo_type = FCComboBox() - self.box_combo_type.addItem(_("Reference Gerber")) - self.box_combo_type.addItem(_("Reference Excellon")) - self.box_combo_type.addItem(_("Reference Geometry")) + self.ref_combo_type = FCComboBox() + self.ref_combo_type.addItems([_("Gerber"), _("Excellon"), _("Geometry")]) - grid_lay.addWidget(self.box_combo_type_label, 4, 0) - grid_lay.addWidget(self.box_combo_type, 4, 1) + grid_lay.addWidget(self.ref_combo_type_label, 4, 0) + grid_lay.addWidget(self.ref_combo_type, 4, 1) - self.box_combo_label = QtWidgets.QLabel('%s:' % _("Ref. Object")) - self.box_combo_label.setToolTip( + self.ref_combo_label = QtWidgets.QLabel('%s:' % _("Ref. Object")) + self.ref_combo_label.setToolTip( _("The FlatCAM object to be used as non copper clearing reference.") ) - self.box_combo = FCComboBox() - self.box_combo.setModel(self.app.collection) - self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.box_combo.set_last = True + self.ref_combo = FCComboBox() + self.ref_combo.setModel(self.app.collection) + self.ref_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) + self.ref_combo.is_last = True + self.ref_combo.obj_type = { + _("Gerber"): "Gerber", _("Excellon"): "Excellon", _("Geometry"): "Geometry" + }[self.ref_combo_type.get_value()] - grid_lay.addWidget(self.box_combo_label, 5, 0) - grid_lay.addWidget(self.box_combo, 5, 1) + grid_lay.addWidget(self.ref_combo_label, 5, 0) + grid_lay.addWidget(self.ref_combo, 5, 1) - self.box_combo.hide() - self.box_combo_label.hide() - self.box_combo_type.hide() - self.box_combo_type_label.hide() + self.ref_combo.hide() + self.ref_combo_label.hide() + self.ref_combo_type.hide() + self.ref_combo_type_label.hide() # Bounding Box Type # self.bbox_type_radio = RadioSet([ @@ -420,7 +422,8 @@ class ToolCopperThieving(FlatCAMTool): self.sm_object_combo = FCComboBox() self.sm_object_combo.setModel(self.app.collection) self.sm_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.sm_object_combo.set_last = True + self.sm_object_combo.is_last = True + self.sm_object_combo.obj_type = 'Gerber' grid_lay_1.addWidget(self.sm_obj_label, 7, 0, 1, 3) grid_lay_1.addWidget(self.sm_object_combo, 8, 0, 1, 3) @@ -526,7 +529,7 @@ class ToolCopperThieving(FlatCAMTool): self.rb_thickness = None # SIGNALS - self.box_combo_type.currentIndexChanged.connect(self.on_combo_box_type) + self.ref_combo_type.currentIndexChanged.connect(self.on_ref_combo_type_change) self.reference_radio.group_toggle_fn = self.on_toggle_reference self.fill_type_radio.activated_custom.connect(self.on_thieving_type) @@ -594,22 +597,25 @@ class ToolCopperThieving(FlatCAMTool): self.robber_line = None self.new_solid_geometry = None - def on_combo_box_type(self): - obj_type = self.box_combo_type.currentIndex() - self.box_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) - self.box_combo.setCurrentIndex(0) + def on_ref_combo_type_change(self): + obj_type = self.ref_combo_type.currentIndex() + self.ref_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) + self.ref_combo.setCurrentIndex(0) + self.ref_combo.obj_type = { + _("Gerber"): "Gerber", _("Excellon"): "Excellon", _("Geometry"): "Geometry" + }[self.ref_combo_type.get_value()] def on_toggle_reference(self): if self.reference_radio.get_value() == "itself" or self.reference_radio.get_value() == "area": - self.box_combo.hide() - self.box_combo_label.hide() - self.box_combo_type.hide() - self.box_combo_type_label.hide() + self.ref_combo.hide() + self.ref_combo_label.hide() + self.ref_combo_type.hide() + self.ref_combo_type_label.hide() else: - self.box_combo.show() - self.box_combo_label.show() - self.box_combo_type.show() - self.box_combo_type_label.show() + self.ref_combo.show() + self.ref_combo_label.show() + self.ref_combo_type.show() + self.ref_combo_type_label.show() if self.reference_radio.get_value() == "itself": self.bbox_type_label.show() @@ -778,7 +784,7 @@ class ToolCopperThieving(FlatCAMTool): self.mm = self.app.plotcanvas.graph_event_connect('mouse_move', self.on_mouse_move) elif reference_method == 'box': - bound_obj_name = self.box_combo.currentText() + bound_obj_name = self.ref_combo.currentText() # Get reference object. try: diff --git a/flatcamTools/ToolCutOut.py b/flatcamTools/ToolCutOut.py index a94d7fa5..9b0ecb3d 100644 --- a/flatcamTools/ToolCutOut.py +++ b/flatcamTools/ToolCutOut.py @@ -108,7 +108,7 @@ class CutOut(FlatCAMTool): self.obj_combo = FCComboBox() self.obj_combo.setModel(self.app.collection) self.obj_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.obj_combo.set_last = True + self.obj_combo.is_last = True grid0.addWidget(self.obj_combo, 3, 0, 1, 2) @@ -321,7 +321,8 @@ class CutOut(FlatCAMTool): self.man_object_combo = FCComboBox() self.man_object_combo.setModel(self.app.collection) self.man_object_combo.setRootModelIndex(self.app.collection.index(2, 0, QtCore.QModelIndex())) - self.man_object_combo.set_last = True + self.man_object_combo.is_last = True + self.man_object_combo.obj_type = "Geometry" self.man_object_label = QtWidgets.QLabel('%s:' % _("Geometry Object")) self.man_object_label.setToolTip( @@ -416,6 +417,7 @@ class CutOut(FlatCAMTool): obj_type = {'grb': 0, 'geo': 2}[val] self.obj_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) self.obj_combo.setCurrentIndex(0) + self.obj_combo.obj_type = {"grb": "Gerber", "geo": "Geometry"}[val] def run(self, toggle=True): self.app.report_usage("ToolCutOut()") diff --git a/flatcamTools/ToolDblSided.py b/flatcamTools/ToolDblSided.py index 8612932c..75071e88 100644 --- a/flatcamTools/ToolDblSided.py +++ b/flatcamTools/ToolDblSided.py @@ -59,7 +59,8 @@ class DblSidedTool(FlatCAMTool): self.gerber_object_combo = FCComboBox() self.gerber_object_combo.setModel(self.app.collection) self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.gerber_object_combo.set_last = True + self.gerber_object_combo.is_last = True + self.gerber_object_combo.obj_type = "Gerber" self.botlay_label = QtWidgets.QLabel("%s:" % _("GERBER")) self.botlay_label.setToolTip('%s.' % _("Gerber to be mirrored")) @@ -86,7 +87,8 @@ class DblSidedTool(FlatCAMTool): self.exc_object_combo = FCComboBox() self.exc_object_combo.setModel(self.app.collection) self.exc_object_combo.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex())) - self.exc_object_combo.set_last = True + self.exc_object_combo.is_last = True + self.exc_object_combo.obj_type = "Excellon" self.excobj_label = QtWidgets.QLabel("%s:" % _("EXCELLON")) self.excobj_label.setToolTip(_("Excellon Object to be mirrored.")) @@ -113,7 +115,8 @@ class DblSidedTool(FlatCAMTool): self.geo_object_combo = FCComboBox() self.geo_object_combo.setModel(self.app.collection) self.geo_object_combo.setRootModelIndex(self.app.collection.index(2, 0, QtCore.QModelIndex())) - self.geo_object_combo.set_last = True + self.geo_object_combo.is_last = True + self.geo_object_combo.obj_type = "Geometry" self.geoobj_label = QtWidgets.QLabel("%s:" % _("GEOMETRY")) self.geoobj_label.setToolTip( @@ -232,7 +235,7 @@ class DblSidedTool(FlatCAMTool): self.box_combo = FCComboBox() self.box_combo.setModel(self.app.collection) self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.box_combo.set_last = True + self.box_combo.is_last = True self.box_combo.hide() @@ -555,14 +558,16 @@ class DblSidedTool(FlatCAMTool): self.align_ref_label_val.set_value('%.*f' % (self.decimals, 0.0)) + # run once to make sure that the obj_type attribute is updated in the FCComboBox + self.box_type_radio.set_value('grb') + self.on_combo_box_type('grb') + def on_combo_box_type(self, val): - obj_type = { - 'grb': 0, - 'exc': 1, - 'geo': 2 - }[val] + obj_type = {'grb': 0, 'exc': 1, 'geo': 2}[val] self.box_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) self.box_combo.setCurrentIndex(0) + self.box_combo.obj_type = { + "grb": "Gerber", "exc": "Excellon", "geo": "Geometry"}[val] def on_create_alignment_holes(self): axis = self.align_axis_radio.get_value() diff --git a/flatcamTools/ToolExtractDrills.py b/flatcamTools/ToolExtractDrills.py index 39e287a4..aa4a7adc 100644 --- a/flatcamTools/ToolExtractDrills.py +++ b/flatcamTools/ToolExtractDrills.py @@ -55,7 +55,8 @@ class ToolExtractDrills(FlatCAMTool): self.gerber_object_combo = FCComboBox() self.gerber_object_combo.setModel(self.app.collection) self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.gerber_object_combo.set_last = True + self.gerber_object_combo.is_last = True + self.gerber_object_combo.obj_type = "Gerber" self.grb_label = QtWidgets.QLabel("%s:" % _("GERBER")) self.grb_label.setToolTip('%s.' % _("Gerber from which to extract drill holes")) diff --git a/flatcamTools/ToolFiducials.py b/flatcamTools/ToolFiducials.py index 1586f010..4c9070e9 100644 --- a/flatcamTools/ToolFiducials.py +++ b/flatcamTools/ToolFiducials.py @@ -253,7 +253,8 @@ class ToolFiducials(FlatCAMTool): self.grb_object_combo = FCComboBox() self.grb_object_combo.setModel(self.app.collection) self.grb_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.grb_object_combo.set_last = True + self.grb_object_combo.is_last = True + self.grb_object_combo.obj_type = "Gerber" self.grbobj_label = QtWidgets.QLabel("%s:" % _("Copper Gerber")) self.grbobj_label.setToolTip( @@ -289,7 +290,8 @@ class ToolFiducials(FlatCAMTool): self.sm_object_combo = FCComboBox() self.sm_object_combo.setModel(self.app.collection) self.sm_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.sm_object_combo.set_last = True + self.sm_object_combo.is_last = True + self.sm_object_combo.obj_type = "Gerber" grid_lay.addWidget(self.sm_object_label, 13, 0, 1, 2) grid_lay.addWidget(self.sm_object_combo, 14, 0, 1, 2) diff --git a/flatcamTools/ToolFilm.py b/flatcamTools/ToolFilm.py index 98a9f1d3..252cb0fb 100644 --- a/flatcamTools/ToolFilm.py +++ b/flatcamTools/ToolFilm.py @@ -66,10 +66,7 @@ class Film(FlatCAMTool): # Type of object for which to create the film self.tf_type_obj_combo = FCComboBox() - self.tf_type_obj_combo.addItems(["Gerber", "Geometry"]) - # self.tf_type_obj_combo.addItem("Gerber") - # self.tf_type_obj_combo.addItem("Excellon") - # self.tf_type_obj_combo.addItem("Geometry") + self.tf_type_obj_combo.addItems([_("Gerber"), _("Geometry")]) # we get rid of item1 ("Excellon") as it is not suitable for creating film # self.tf_type_obj_combo.view().setRowHidden(1, True) @@ -90,7 +87,7 @@ class Film(FlatCAMTool): self.tf_object_combo = FCComboBox() self.tf_object_combo.setModel(self.app.collection) self.tf_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.tf_object_combo.set_last = True + self.tf_object_combo.is_last = True self.tf_object_label = QtWidgets.QLabel('%s:' % _("Film Object")) self.tf_object_label.setToolTip( @@ -102,7 +99,7 @@ class Film(FlatCAMTool): # Type of Box Object to be used as an envelope for film creation # Within this we can create negative self.tf_type_box_combo = FCComboBox() - self.tf_type_box_combo.addItems(["Gerber", "Geometry"]) + self.tf_type_box_combo.addItems([_("Gerber"), _("Geometry")]) # self.tf_type_box_combo.addItem("Gerber") # self.tf_type_box_combo.addItem("Excellon") @@ -127,7 +124,7 @@ class Film(FlatCAMTool): self.tf_box_combo = FCComboBox() self.tf_box_combo.setModel(self.app.collection) self.tf_box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.tf_box_combo.set_last = True + self.tf_box_combo.is_last = True self.tf_box_combo_label = QtWidgets.QLabel('%s:' % _("Box Object")) self.tf_box_combo_label.setToolTip( @@ -372,7 +369,9 @@ class Film(FlatCAMTool): self.exc_combo = FCComboBox() self.exc_combo.setModel(self.app.collection) self.exc_combo.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex())) - self.exc_combo.set_last = True + self.exc_combo.is_last = True + self.exc_combo.obj_type = "Excellon" + punch_grid.addWidget(self.exc_label, 1, 0) punch_grid.addWidget(self.exc_combo, 1, 1) @@ -542,15 +541,21 @@ class Film(FlatCAMTool): self.file_type_radio.activated_custom.connect(self.on_file_type) self.reset_button.clicked.connect(self.set_tool_ui) - def on_type_obj_index_changed(self, index): + def on_type_obj_index_changed(self): obj_type = self.tf_type_obj_combo.currentIndex() self.tf_object_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) self.tf_object_combo.setCurrentIndex(0) + self.tf_object_combo.obj_type = { + _("Gerber"): "Gerber", _("Geometry"): "Geometry" + }[self.tf_type_obj_combo.get_value()] - def on_type_box_index_changed(self, index): + def on_type_box_index_changed(self): obj_type = self.tf_type_box_combo.currentIndex() self.tf_box_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) self.tf_box_combo.setCurrentIndex(0) + self.tf_box_combo.obj_type = { + _("Gerber"): "Gerber", _("Geometry"): "Geometry" + }[self.tf_type_obj_combo.get_value()] def run(self, toggle=True): self.app.report_usage("ToolFilm()") @@ -613,6 +618,10 @@ class Film(FlatCAMTool): self.orientation_radio.set_value(self.app.defaults["tools_film_orientation"]) self.pagesize_combo.set_value(self.app.defaults["tools_film_pagesize"]) + # run once to update the obj_type attribute in the FCCombobox so the last object is showed in cb + self.on_type_obj_index_changed() + self.on_type_box_index_changed() + def on_film_type(self, val): type_of_film = val diff --git a/flatcamTools/ToolImage.py b/flatcamTools/ToolImage.py index 8ac9ed89..603fb9e1 100644 --- a/flatcamTools/ToolImage.py +++ b/flatcamTools/ToolImage.py @@ -46,8 +46,7 @@ class ToolImage(FlatCAMTool): # Type of object to create for the image self.tf_type_obj_combo = FCComboBox() - self.tf_type_obj_combo.addItem("Gerber") - self.tf_type_obj_combo.addItem("Geometry") + self.tf_type_obj_combo.addItems([_("Gerber"), _("Geometry")]) self.tf_type_obj_combo.setItemIcon(0, QtGui.QIcon(self.app.resource_location + "/flatcam_icon16.png")) self.tf_type_obj_combo.setItemIcon(1, QtGui.QIcon(self.app.resource_location + "/geometry16.png")) @@ -238,7 +237,7 @@ class ToolImage(FlatCAMTool): filename, _f = QtWidgets.QFileDialog.getOpenFileName(caption=_("Import IMAGE"), filter=filter) filename = str(filename) - type_obj = self.tf_type_obj_combo.get_value().lower() + type_obj = self.tf_type_obj_combo.get_value() dpi = self.dpi_entry.get_value() mode = self.image_type.get_value() mask = [self.mask_bw_entry.get_value(), self.mask_r_entry.get_value(), self.mask_g_entry.get_value(), @@ -250,7 +249,7 @@ class ToolImage(FlatCAMTool): self.app.worker_task.emit({'fcn': self.import_image, 'params': [filename, type_obj, dpi, mode, mask]}) - def import_image(self, filename, o_type='gerber', dpi=96, mode='black', mask=None, outname=None): + def import_image(self, filename, o_type=_("Gerber"), dpi=96, mode='black', mask=None, outname=None): """ Adds a new Geometry Object to the projects and populates it with shapes extracted from the SVG file. @@ -269,10 +268,10 @@ class ToolImage(FlatCAMTool): if mask is None: mask = [250, 250, 250, 250] - if o_type is None or o_type == "geometry": + if o_type is None or o_type == _("Geometry"): obj_type = "geometry" - elif o_type == "gerber": - obj_type = o_type + elif o_type == _("Gerber"): + obj_type = "gerber" else: self.app.inform.emit('[ERROR_NOTCL] %s' % _("Not supported type is picked as parameter. " diff --git a/flatcamTools/ToolInvertGerber.py b/flatcamTools/ToolInvertGerber.py index 46124730..ffacf098 100644 --- a/flatcamTools/ToolInvertGerber.py +++ b/flatcamTools/ToolInvertGerber.py @@ -66,7 +66,8 @@ class ToolInvertGerber(FlatCAMTool): self.gerber_combo = FCComboBox() self.gerber_combo.setModel(self.app.collection) self.gerber_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.gerber_combo.set_last = True + self.gerber_combo.is_last = True + self.gerber_combo.obj_type = "Gerber" self.gerber_label = QtWidgets.QLabel('%s:' % _("GERBER")) self.gerber_label.setToolTip( diff --git a/flatcamTools/ToolNCC.py b/flatcamTools/ToolNCC.py index 1203a3c5..2873be89 100644 --- a/flatcamTools/ToolNCC.py +++ b/flatcamTools/ToolNCC.py @@ -71,15 +71,15 @@ class NonCopperClear(FlatCAMTool, Gerber): # ################################################ # ##### Type of object to be copper cleaned ###### # ################################################ - # self.type_obj_combo = FCComboBox() - # self.type_obj_combo.addItem("Gerber") - # self.type_obj_combo.addItem("Excellon") - # self.type_obj_combo.addItem("Geometry") + # self.type_obj_radio = FCComboBox() + # self.type_obj_radio.addItem("Gerber") + # self.type_obj_radio.addItem("Excellon") + # self.type_obj_radio.addItem("Geometry") # # # we get rid of item1 ("Excellon") as it is not suitable - # self.type_obj_combo.view().setRowHidden(1, True) - # self.type_obj_combo.setItemIcon(0, QtGui.QIcon(self.app.resource_location + "/flatcam_icon16.png")) - # self.type_obj_combo.setItemIcon(2, QtGui.QIcon(self.app.resource_location + "/geometry16.png")) + # self.type_obj_radio.view().setRowHidden(1, True) + # self.type_obj_radio.setItemIcon(0, QtGui.QIcon(self.app.resource_location + "/flatcam_icon16.png")) + # self.type_obj_radio.setItemIcon(2, QtGui.QIcon(self.app.resource_location + "/geometry16.png")) self.type_obj_combo_label = QtWidgets.QLabel('%s:' % _("Obj Type")) self.type_obj_combo_label.setToolTip( @@ -90,10 +90,10 @@ class NonCopperClear(FlatCAMTool, Gerber): ) self.type_obj_combo_label.setMinimumWidth(60) - self.type_obj_combo = RadioSet([{'label': "Geometry", 'value': 'geometry'}, - {'label': "Gerber", 'value': 'gerber'}]) + self.type_obj_radio = RadioSet([{'label': _("Geometry"), 'value': 'geometry'}, + {'label': _("Gerber"), 'value': 'gerber'}]) - form_layout.addRow(self.type_obj_combo_label, self.type_obj_combo) + form_layout.addRow(self.type_obj_combo_label, self.type_obj_radio) # ################################################ # ##### The object to be copper cleaned ########## @@ -102,7 +102,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.object_combo.setModel(self.app.collection) self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) # self.object_combo.setCurrentIndex(1) - self.object_combo.set_last = True + self.object_combo.is_last = True self.object_label = QtWidgets.QLabel('%s:' % _("Object")) self.object_label.setToolTip(_("Object to be cleared of excess copper.")) @@ -546,31 +546,30 @@ class NonCopperClear(FlatCAMTool, Gerber): form1 = QtWidgets.QFormLayout() self.grid3.addLayout(form1, 28, 0, 1, 2) - self.box_combo_type_label = QtWidgets.QLabel('%s:' % _("Ref. Type")) - self.box_combo_type_label.setToolTip( + self.reference_combo_type_label = QtWidgets.QLabel('%s:' % _("Ref. Type")) + self.reference_combo_type_label.setToolTip( _("The type of FlatCAM object to be used as non copper clearing reference.\n" "It can be Gerber, Excellon or Geometry.") ) - self.box_combo_type = FCComboBox() - self.box_combo_type.addItem(_("Reference Gerber")) - self.box_combo_type.addItem(_("Reference Excellon")) - self.box_combo_type.addItem(_("Reference Geometry")) - form1.addRow(self.box_combo_type_label, self.box_combo_type) + self.reference_combo_type = FCComboBox() + self.reference_combo_type.addItems([_("Gerber"), _("Excellon"), _("Geometry")]) - self.box_combo_label = QtWidgets.QLabel('%s:' % _("Ref. Object")) - self.box_combo_label.setToolTip( + form1.addRow(self.reference_combo_type_label, self.reference_combo_type) + + self.reference_combo_label = QtWidgets.QLabel('%s:' % _("Ref. Object")) + self.reference_combo_label.setToolTip( _("The FlatCAM object to be used as non copper clearing reference.") ) - self.box_combo = FCComboBox() - self.box_combo.setModel(self.app.collection) - self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.box_combo.set_last = True - form1.addRow(self.box_combo_label, self.box_combo) + self.reference_combo = FCComboBox() + self.reference_combo.setModel(self.app.collection) + self.reference_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) + self.reference_combo.is_last = True + form1.addRow(self.reference_combo_label, self.reference_combo) - self.box_combo.hide() - self.box_combo_label.hide() - self.box_combo_type.hide() - self.box_combo_type_label.hide() + self.reference_combo.hide() + self.reference_combo_label.hide() + self.reference_combo_type.hide() + self.reference_combo_type_label.hide() separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) @@ -706,13 +705,13 @@ class NonCopperClear(FlatCAMTool, Gerber): self.op_radio.activated_custom.connect(self.on_operation_change) - self.box_combo_type.currentIndexChanged.connect(self.on_combo_box_type) - self.select_combo.group_toggle_fn = self.on_toggle_reference + self.reference_combo_type.currentIndexChanged.connect(self.on_reference_combo_changed) + self.select_combo.currentIndexChanged.connect(self.on_toggle_reference) self.ncc_rest_cb.stateChanged.connect(self.on_rest_machining_check) self.ncc_order_radio.activated_custom[str].connect(self.on_order_changed) - self.type_obj_combo.activated_custom.connect(self.on_type_obj_index_changed) + self.type_obj_radio.activated_custom.connect(self.on_type_obj_index_changed) self.apply_param_to_all.clicked.connect(self.on_apply_param_to_all_clicked) @@ -722,6 +721,9 @@ class NonCopperClear(FlatCAMTool, Gerber): obj_type = 0 if val == 'gerber' else 2 self.object_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) self.object_combo.setCurrentIndex(0) + self.object_combo.obj_type = { + "gerber": "Gerber", "geometry": "Geometry" + }[self.type_obj_radio.get_value()] def on_operation_change(self, val): if val == 'iso': @@ -910,6 +912,7 @@ class NonCopperClear(FlatCAMTool, Gerber): def run(self, toggle=True): self.app.report_usage("ToolNonCopperClear()") + log.debug("ToolNCC().run() was launched ...") if toggle: # if the splitter is hidden, display it, else hide it but only if the current widget is the same @@ -948,7 +951,12 @@ class NonCopperClear(FlatCAMTool, Gerber): self.tools_frame.show() - self.type_obj_combo.set_value('gerber') + self.type_obj_radio.set_value('gerber') + + # run those once so the obj_type attribute is updated for the FCComboboxes + # so the last loaded object is displayed + self.on_type_obj_index_changed(val="gerber") + self.on_reference_combo_changed() self.op_radio.set_value(self.app.defaults["tools_nccoperation"]) self.ncc_order_radio.set_value(self.app.defaults["tools_nccorder"]) @@ -1254,22 +1262,25 @@ class NonCopperClear(FlatCAMTool, Gerber): if self.tool_type_radio.get_value() == 'C1': self.old_tool_dia = self.addtool_entry.get_value() - def on_combo_box_type(self): - obj_type = self.box_combo_type.currentIndex() - self.box_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) - self.box_combo.setCurrentIndex(0) + def on_reference_combo_changed(self): + obj_type = self.reference_combo_type.currentIndex() + self.reference_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) + self.reference_combo.setCurrentIndex(0) + self.reference_combo.obj_type = { + _("Gerber"): "Gerber", _("Excellon"): "Excellon", _("Geometry"): "Geometry" + }[self.reference_combo_type.get_value()] def on_toggle_reference(self): if self.select_combo.get_value() == _("Itself") or self.select_combo.get_value() == _("Area Selection"): - self.box_combo.hide() - self.box_combo_label.hide() - self.box_combo_type.hide() - self.box_combo_type_label.hide() + self.reference_combo.hide() + self.reference_combo_label.hide() + self.reference_combo_type.hide() + self.reference_combo_type_label.hide() else: - self.box_combo.show() - self.box_combo_label.show() - self.box_combo_type.show() - self.box_combo_type_label.show() + self.reference_combo.show() + self.reference_combo_label.show() + self.reference_combo_type.show() + self.reference_combo_type_label.show() def on_order_changed(self, order): if order != 'no': @@ -1567,7 +1578,7 @@ class NonCopperClear(FlatCAMTool, Gerber): "use a number.")) continue - if self.tools_table.cellWidget(x.row(), 4).currentText() == 'iso_op': + if self.op_radio.get_value() == _("Isolation"): self.iso_dia_list.append(self.tooldia) else: self.ncc_dia_list.append(self.tooldia) @@ -1606,7 +1617,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.mr = self.app.plotcanvas.graph_event_connect('mouse_release', self.on_mouse_release) self.mm = self.app.plotcanvas.graph_event_connect('mouse_move', self.on_mouse_move) elif self.select_method == 'box': - self.bound_obj_name = self.box_combo.currentText() + self.bound_obj_name = self.reference_combo.currentText() # Get source object. try: self.bound_obj = self.app.collection.get_by_name(self.bound_obj_name) diff --git a/flatcamTools/ToolOptimal.py b/flatcamTools/ToolOptimal.py index 0cbbf0f6..7dcbf121 100644 --- a/flatcamTools/ToolOptimal.py +++ b/flatcamTools/ToolOptimal.py @@ -66,7 +66,8 @@ class ToolOptimal(FlatCAMTool): self.gerber_object_combo = FCComboBox() self.gerber_object_combo.setModel(self.app.collection) self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.gerber_object_combo.set_last = True + self.gerber_object_combo.is_last = True + self.gerber_object_combo.obj_type = "Gerber" self.gerber_object_label = QtWidgets.QLabel("%s:" % _("GERBER")) self.gerber_object_label.setToolTip( diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 0c436f58..3951a5cc 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -97,7 +97,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.obj_combo = FCComboBox() self.obj_combo.setModel(self.app.collection) self.obj_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.obj_combo.set_last = True + self.obj_combo.is_last = True self.object_label = QtWidgets.QLabel('%s:' % _("Object")) self.object_label.setToolTip(_("Object to be painted.")) @@ -491,31 +491,30 @@ class ToolPaint(FlatCAMTool, Gerber): form1 = QtWidgets.QFormLayout() grid4.addLayout(form1, 20, 0, 1, 2) - self.box_combo_type_label = QtWidgets.QLabel('%s:' % _("Ref. Type")) - self.box_combo_type_label.setToolTip( + self.reference_type_label = QtWidgets.QLabel('%s:' % _("Ref. Type")) + self.reference_type_label.setToolTip( _("The type of FlatCAM object to be used as paint reference.\n" "It can be Gerber, Excellon or Geometry.") ) - self.box_combo_type = FCComboBox() - self.box_combo_type.addItem(_("Reference Gerber")) - self.box_combo_type.addItem(_("Reference Excellon")) - self.box_combo_type.addItem(_("Reference Geometry")) - form1.addRow(self.box_combo_type_label, self.box_combo_type) + self.reference_type_combo = FCComboBox() + self.reference_type_combo.addItems([_("Gerber"), _("Excellon"), _("Geometry")]) - self.box_combo_label = QtWidgets.QLabel('%s:' % _("Ref. Object")) - self.box_combo_label.setToolTip( + form1.addRow(self.reference_type_label, self.reference_type_combo) + + self.reference_combo_label = QtWidgets.QLabel('%s:' % _("Ref. Object")) + self.reference_combo_label.setToolTip( _("The FlatCAM object to be used as non copper clearing reference.") ) - self.box_combo = FCComboBox() - self.box_combo.setModel(self.app.collection) - self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.box_combo.set_last = True - form1.addRow(self.box_combo_label, self.box_combo) + self.reference_combo = FCComboBox() + self.reference_combo.setModel(self.app.collection) + self.reference_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) + self.reference_combo.is_last = True + form1.addRow(self.reference_combo_label, self.reference_combo) - self.box_combo.hide() - self.box_combo_label.hide() - self.box_combo_type.hide() - self.box_combo_type_label.hide() + self.reference_combo.hide() + self.reference_combo_label.hide() + self.reference_type_combo.hide() + self.reference_type_label.hide() # GO Button self.generate_paint_button = QtWidgets.QPushButton(_('Generate Geometry')) @@ -633,7 +632,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.order_radio.activated_custom[str].connect(self.on_order_changed) self.rest_cb.stateChanged.connect(self.on_rest_machining_check) - self.box_combo_type.currentIndexChanged.connect(self.on_combo_box_type) + self.reference_type_combo.currentIndexChanged.connect(self.on_reference_combo_changed) self.type_obj_combo.activated_custom.connect(self.on_type_obj_changed) self.apply_param_to_all.clicked.connect(self.on_apply_param_to_all_clicked) @@ -660,6 +659,7 @@ class ToolPaint(FlatCAMTool, Gerber): obj_type = 0 if val == 'gerber' else 2 self.obj_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) self.obj_combo.setCurrentIndex(0) + self.obj_combo.obj_type = {"gerber": "Gerber", "geometry": "Geometry"}[val] idx = self.paintmethod_combo.findText(_("Laser_lines")) if self.type_obj_combo.get_value().lower() == 'gerber': @@ -669,6 +669,14 @@ class ToolPaint(FlatCAMTool, Gerber): if self.paintmethod_combo.get_value() == _("Laser_lines"): self.paintmethod_combo.set_value(_("Lines")) + def on_reference_combo_changed(self): + obj_type = self.reference_type_combo.currentIndex() + self.reference_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) + self.reference_combo.setCurrentIndex(0) + self.reference_combo.obj_type = { + _("Gerber"): "Gerber", _("Excellon"): "Excellon", _("Geometry"): "Geometry" + }[self.reference_type_combo.get_value()] + def install(self, icon=None, separator=None, **kwargs): FlatCAMTool.install(self, icon, separator, shortcut='ALT+P', **kwargs) @@ -888,15 +896,15 @@ class ToolPaint(FlatCAMTool, Gerber): def on_selection(self): if self.selectmethod_combo.get_value() == _("Reference Object"): - self.box_combo.show() - self.box_combo_label.show() - self.box_combo_type.show() - self.box_combo_type_label.show() + self.reference_combo.show() + self.reference_combo_label.show() + self.reference_type_combo.show() + self.reference_type_label.show() else: - self.box_combo.hide() - self.box_combo_label.hide() - self.box_combo_type.hide() - self.box_combo_type_label.hide() + self.reference_combo.hide() + self.reference_combo_label.hide() + self.reference_type_combo.hide() + self.reference_type_label.hide() if self.selectmethod_combo.get_value() == _("Polygon Selection"): # disable rest-machining for single polygon painting @@ -997,6 +1005,11 @@ class ToolPaint(FlatCAMTool, Gerber): # make the default object type, "Geometry" self.type_obj_combo.set_value("geometry") + # run those once so the obj_type attribute is updated in the FCComboBoxes + # to make sure that the last loaded object is displayed in the combobox + self.on_type_obj_changed(val="geometry") + self.on_reference_combo_changed() + try: diameters = [float(self.app.defaults["tools_painttooldia"])] except (ValueError, TypeError): @@ -1103,11 +1116,6 @@ class ToolPaint(FlatCAMTool, Gerber): self.ui_connect() - def on_combo_box_type(self): - obj_type = self.box_combo_type.currentIndex() - self.box_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) - self.box_combo.setCurrentIndex(0) - def on_tool_add(self, dia=None, muted=None): self.blockSignals(True) @@ -1411,7 +1419,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.mr = self.app.plotcanvas.graph_event_connect('mouse_release', self.on_mouse_release) self.mm = self.app.plotcanvas.graph_event_connect('mouse_move', self.on_mouse_move) elif self.select_method == _("Reference Object"): - self.bound_obj_name = self.box_combo.currentText() + self.bound_obj_name = self.reference_combo.currentText() # Get source object. try: self.bound_obj = self.app.collection.get_by_name(self.bound_obj_name) diff --git a/flatcamTools/ToolPanelize.py b/flatcamTools/ToolPanelize.py index 0b7f5fec..fe381fc0 100644 --- a/flatcamTools/ToolPanelize.py +++ b/flatcamTools/ToolPanelize.py @@ -83,7 +83,7 @@ class Panelize(FlatCAMTool): self.object_combo = FCComboBox() self.object_combo.setModel(self.app.collection) self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.object_combo.set_last = True + self.object_combo.is_last = True self.object_combo.setToolTip( _("Object to be panelized. This means that it will\n" @@ -115,10 +115,7 @@ class Panelize(FlatCAMTool): # Type of Box Object to be used as an envelope for panelization self.type_box_combo = FCComboBox() - self.type_box_combo.addItems(["Gerber", "Geometry"]) - # self.type_box_combo.addItem("Gerber") - # self.type_box_combo.addItem("Excellon") - # self.type_box_combo.addItem("Geometry") + self.type_box_combo.addItems([_("Gerber"), _("Geometry")]) # we get rid of item1 ("Excellon") as it is not suitable for use as a "box" for panelizing # self.type_box_combo.view().setRowHidden(1, True) @@ -138,7 +135,7 @@ class Panelize(FlatCAMTool): self.box_combo = FCComboBox() self.box_combo.setModel(self.app.collection) self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.box_combo.set_last = True + self.box_combo.is_last = True self.box_combo.setToolTip( _("The actual object that is used a container for the\n " @@ -364,10 +361,18 @@ class Panelize(FlatCAMTool): self.app.defaults["tools_panelize_panel_type"] else 'gerber' self.panel_type_radio.set_value(panel_type) + # run once the following so the obj_type attribute is updated in the FCComboBoxes + # such that the last loaded object is populated in the combo boxes + self.on_type_obj_index_changed() + self.on_type_box_index_changed() + def on_type_obj_index_changed(self): obj_type = self.type_obj_combo.currentIndex() self.object_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) self.object_combo.setCurrentIndex(0) + self.object_combo.obj_type = { + _("Gerber"): "Gerber", _("Excellon"): "Excellon", _("Geometry"): "Geometry" + }[self.type_obj_combo.get_value()] # hide the panel type for Excellons, the panel can be only of type Geometry if self.type_obj_combo.currentText() != 'Excellon': @@ -382,6 +387,9 @@ class Panelize(FlatCAMTool): obj_type = self.type_box_combo.currentIndex() self.box_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) self.box_combo.setCurrentIndex(0) + self.box_combo.obj_type = { + _("Gerber"): "Gerber", _("Geometry"): "Geometry" + }[self.type_box_combo.get_value()] def on_reference_radio_changed(self, current_val): if current_val == 'object': diff --git a/flatcamTools/ToolPunchGerber.py b/flatcamTools/ToolPunchGerber.py index c4c9ae61..8c094dbf 100644 --- a/flatcamTools/ToolPunchGerber.py +++ b/flatcamTools/ToolPunchGerber.py @@ -58,7 +58,8 @@ class ToolPunchGerber(FlatCAMTool): self.gerber_object_combo = FCComboBox() self.gerber_object_combo.setModel(self.app.collection) self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.gerber_object_combo.set_last = True + self.gerber_object_combo.is_last = True + self.gerber_object_combo.obj_type = "Gerber" self.grb_label = QtWidgets.QLabel("%s:" % _("GERBER")) self.grb_label.setToolTip('%s.' % _("Gerber into which to punch holes")) @@ -168,7 +169,8 @@ class ToolPunchGerber(FlatCAMTool): self.exc_combo = FCComboBox() self.exc_combo.setModel(self.app.collection) self.exc_combo.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex())) - self.exc_combo.set_last = True + self.exc_combo.is_last = True + self.exc_combo.obj_type = "Excellon" grid0.addWidget(self.exc_label, 3, 0, 1, 2) grid0.addWidget(self.exc_combo, 4, 0, 1, 2) diff --git a/flatcamTools/ToolQRCode.py b/flatcamTools/ToolQRCode.py index 67add5c9..b71d477e 100644 --- a/flatcamTools/ToolQRCode.py +++ b/flatcamTools/ToolQRCode.py @@ -72,9 +72,10 @@ class QRCode(FlatCAMTool): self.grb_object_combo = FCComboBox() self.grb_object_combo.setModel(self.app.collection) self.grb_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.grb_object_combo.set_last = True + self.grb_object_combo.is_last = True + self.grb_object_combo.obj_type = "Gerber" - self.grbobj_label = QtWidgets.QLabel("%s:" % _("GERBER")) + self.grbobj_label = QtWidgets.QLabel("%s:" % _("Object")) self.grbobj_label.setToolTip( _("Gerber Object to which the QRCode will be added.") ) diff --git a/flatcamTools/ToolRulesCheck.py b/flatcamTools/ToolRulesCheck.py index 9deb26be..eb236381 100644 --- a/flatcamTools/ToolRulesCheck.py +++ b/flatcamTools/ToolRulesCheck.py @@ -72,7 +72,8 @@ class RulesCheck(FlatCAMTool): self.copper_t_object = FCComboBox() self.copper_t_object.setModel(self.app.collection) self.copper_t_object.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.copper_t_object.set_last = True + self.copper_t_object.is_last = True + self.copper_t_object.obj_type = "Gerber" self.copper_t_object_lbl = QtWidgets.QLabel('%s:' % _("Top")) self.copper_t_object_lbl.setToolTip( @@ -89,7 +90,8 @@ class RulesCheck(FlatCAMTool): self.copper_b_object = FCComboBox() self.copper_b_object.setModel(self.app.collection) self.copper_b_object.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.copper_b_object.set_last = True + self.copper_b_object.is_last = True + self.copper_b_object.obj_type = "Gerber" self.copper_b_object_lbl = QtWidgets.QLabel('%s:' % _("Bottom")) self.copper_b_object_lbl.setToolTip( @@ -106,7 +108,8 @@ class RulesCheck(FlatCAMTool): self.sm_t_object = FCComboBox() self.sm_t_object.setModel(self.app.collection) self.sm_t_object.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.sm_t_object.set_last = True + self.sm_t_object.is_last = True + self.sm_t_object.obj_type = "Gerber" self.sm_t_object_lbl = QtWidgets.QLabel('%s:' % _("SM Top")) self.sm_t_object_lbl.setToolTip( @@ -123,7 +126,8 @@ class RulesCheck(FlatCAMTool): self.sm_b_object = FCComboBox() self.sm_b_object.setModel(self.app.collection) self.sm_b_object.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.sm_b_object.set_last = True + self.sm_b_object.is_last = True + self.sm_b_object.obj_type = "Gerber" self.sm_b_object_lbl = QtWidgets.QLabel('%s:' % _("SM Bottom")) self.sm_b_object_lbl.setToolTip( @@ -140,7 +144,8 @@ class RulesCheck(FlatCAMTool): self.ss_t_object = FCComboBox() self.ss_t_object.setModel(self.app.collection) self.ss_t_object.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.ss_t_object.set_last = True + self.ss_t_object.is_last = True + self.ss_t_object.obj_type = "Gerber" self.ss_t_object_lbl = QtWidgets.QLabel('%s:' % _("Silk Top")) self.ss_t_object_lbl.setToolTip( @@ -157,7 +162,8 @@ class RulesCheck(FlatCAMTool): self.ss_b_object = FCComboBox() self.ss_b_object.setModel(self.app.collection) self.ss_b_object.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.ss_b_object.set_last = True + self.ss_b_object.is_last = True + self.ss_b_object.obj_type = "Gerber" self.ss_b_object_lbl = QtWidgets.QLabel('%s:' % _("Silk Bottom")) self.ss_b_object_lbl.setToolTip( @@ -174,7 +180,8 @@ class RulesCheck(FlatCAMTool): self.outline_object = FCComboBox() self.outline_object.setModel(self.app.collection) self.outline_object.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.outline_object.set_last = True + self.outline_object.is_last = True + self.outline_object.obj_type = "Gerber" self.outline_object_lbl = QtWidgets.QLabel('%s:' % _("Outline")) self.outline_object_lbl.setToolTip( @@ -200,7 +207,8 @@ class RulesCheck(FlatCAMTool): self.e1_object = FCComboBox() self.e1_object.setModel(self.app.collection) self.e1_object.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex())) - self.e1_object.set_last = True + self.e1_object.is_last = True + self.e1_object.obj_type = "Excellon" self.e1_object_lbl = QtWidgets.QLabel('%s:' % _("Excellon 1")) self.e1_object_lbl.setToolTip( @@ -218,7 +226,8 @@ class RulesCheck(FlatCAMTool): self.e2_object = FCComboBox() self.e2_object.setModel(self.app.collection) self.e2_object.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex())) - self.e2_object.set_last = True + self.e2_object.is_last = True + self.e2_object.obj_type = "Excellon" self.e2_object_lbl = QtWidgets.QLabel('%s:' % _("Excellon 2")) self.e2_object_lbl.setToolTip( diff --git a/flatcamTools/ToolSolderPaste.py b/flatcamTools/ToolSolderPaste.py index 568f164e..2dfd5d97 100644 --- a/flatcamTools/ToolSolderPaste.py +++ b/flatcamTools/ToolSolderPaste.py @@ -61,7 +61,8 @@ class SolderPaste(FlatCAMTool): self.obj_combo = FCComboBox(callback=self.on_rmb_combo) self.obj_combo.setModel(self.app.collection) self.obj_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.obj_combo.set_last = True + self.obj_combo.is_last = True + self.obj_combo.obj_type = "Gerber" self.object_label = QtWidgets.QLabel("Gerber: ") self.object_label.setToolTip( @@ -383,7 +384,8 @@ class SolderPaste(FlatCAMTool): self.geo_obj_combo = FCComboBox(callback=self.on_rmb_combo) self.geo_obj_combo.setModel(self.app.collection) self.geo_obj_combo.setRootModelIndex(self.app.collection.index(2, 0, QtCore.QModelIndex())) - self.geo_obj_combo.set_last = True + self.geo_obj_combo.is_last = True + self.geo_obj_combo.obj_type = "Geometry" self.geo_object_label = QtWidgets.QLabel('%s:' % _("Geo Result")) self.geo_object_label.setToolTip( @@ -416,7 +418,8 @@ class SolderPaste(FlatCAMTool): self.cnc_obj_combo = FCComboBox(callback=self.on_rmb_combo) self.cnc_obj_combo.setModel(self.app.collection) self.cnc_obj_combo.setRootModelIndex(self.app.collection.index(3, 0, QtCore.QModelIndex())) - self.cnc_obj_combo.set_last = True + self.cnc_obj_combo.is_last = True + self.geo_obj_combo.obj_type = "CNCJob" self.cnc_object_label = QtWidgets.QLabel('%s:' % _("CNC Result")) self.cnc_object_label.setToolTip( diff --git a/flatcamTools/ToolSub.py b/flatcamTools/ToolSub.py index c63ff5e2..1471bd70 100644 --- a/flatcamTools/ToolSub.py +++ b/flatcamTools/ToolSub.py @@ -69,7 +69,9 @@ class ToolSub(FlatCAMTool): self.target_gerber_combo = FCComboBox() self.target_gerber_combo.setModel(self.app.collection) self.target_gerber_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.target_gerber_combo.setCurrentIndex(1) + # self.target_gerber_combo.setCurrentIndex(1) + self.target_gerber_combo.is_last = True + self.target_gerber_combo.obj_type = "Gerber" self.target_gerber_label = QtWidgets.QLabel('%s:' % _("Target")) self.target_gerber_label.setToolTip( @@ -83,7 +85,8 @@ class ToolSub(FlatCAMTool): self.sub_gerber_combo = FCComboBox() self.sub_gerber_combo.setModel(self.app.collection) self.sub_gerber_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.sub_gerber_combo.set_last = True + self.sub_gerber_combo.is_last = True + self.sub_gerber_combo.obj_type = "Gerber" self.sub_gerber_label = QtWidgets.QLabel('%s:' % _("Subtractor")) self.sub_gerber_label.setToolTip( @@ -121,7 +124,9 @@ class ToolSub(FlatCAMTool): self.target_geo_combo = FCComboBox() self.target_geo_combo.setModel(self.app.collection) self.target_geo_combo.setRootModelIndex(self.app.collection.index(2, 0, QtCore.QModelIndex())) - self.target_geo_combo.setCurrentIndex(1) + # self.target_geo_combo.setCurrentIndex(1) + self.target_geo_combo.is_last = True + self.target_geo_combo.obj_type = "Geometry" self.target_geo_label = QtWidgets.QLabel('%s:' % _("Target")) self.target_geo_label.setToolTip( @@ -135,7 +140,8 @@ class ToolSub(FlatCAMTool): self.sub_geo_combo = FCComboBox() self.sub_geo_combo.setModel(self.app.collection) self.sub_geo_combo.setRootModelIndex(self.app.collection.index(2, 0, QtCore.QModelIndex())) - self.sub_geo_combo.set_last = True + self.sub_geo_combo.is_last = True + self.sub_geo_combo.obj_type = "Geometry" self.sub_geo_label = QtWidgets.QLabel('%s:' % _("Subtractor")) self.sub_geo_label.setToolTip( From 1a06ce6a2d3745090b44ac064253a05fd79b0761 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 12 Mar 2020 18:20:22 +0200 Subject: [PATCH 126/209] - working on the new database - fix a bug in the TextInputTool in FlatCAM Geometry Editor that crashed the sw when some fonts are not loaded correctly --- FlatCAMCommon.py | 597 +++++++++++++++++++++-------- README.md | 6 + flatcamEditors/FlatCAMGeoEditor.py | 18 +- flatcamGUI/PreferencesUI.py | 2 +- 4 files changed, 453 insertions(+), 170 deletions(-) diff --git a/FlatCAMCommon.py b/FlatCAMCommon.py index f324fe4c..c8a3860b 100644 --- a/FlatCAMCommon.py +++ b/FlatCAMCommon.py @@ -13,7 +13,7 @@ from PyQt5 import QtGui, QtCore, QtWidgets from flatcamGUI.GUIElements import FCTable, FCEntry, FCButton, FCDoubleSpinner, FCComboBox, FCCheckBox, FCSpinner, \ - FCTree + FCTree, RadioSet from camlib import to_dict import sys @@ -1435,22 +1435,358 @@ class ToolsDB2(QtWidgets.QWidget): self.tree_widget.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding) tree_layout.addWidget(self.tree_widget) - table_hlay = QtWidgets.QHBoxLayout() - grid_layout.addLayout(table_hlay, 0, 1) + param_hlay = QtWidgets.QHBoxLayout() + grid_layout.addLayout(param_hlay, 0, 1) - self.table_widget = FCTable(drag_drop=True) - self.table_widget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) - table_hlay.addWidget(self.table_widget) + # ########################################################################### + # ############## The UI form ################################################ + # ########################################################################### + self.basic_box = QtWidgets.QGroupBox() + self.basic_box.setStyleSheet(""" + QGroupBox + { + font-size: 16px; + font-weight: bold; + } + """) + self.basic_vlay = QtWidgets.QVBoxLayout() + self.basic_box.setLayout(self.basic_vlay) + self.basic_box.setTitle(_("Basic Parameters")) + self.basic_box.setMinimumWidth(250) - # set the number of columns and the headers tool tips - self.configure_table() + self.advanced_box = QtWidgets.QGroupBox() + self.advanced_box.setStyleSheet(""" + QGroupBox + { + font-size: 16px; + font-weight: bold; + } + """) + self.advanced_vlay = QtWidgets.QVBoxLayout() + self.advanced_box.setLayout(self.advanced_vlay) + self.advanced_box.setTitle(_("Advanced Parameters")) + self.advanced_box.setMinimumWidth(250) + + param_hlay.addLayout(self.basic_vlay) + param_hlay.addLayout(self.advanced_vlay) + + # ########################################################################### + # ############### BASIC UI form ############################################# + # ########################################################################### + + grid0 = QtWidgets.QGridLayout() + self.advanced_vlay.addLayout(grid0) + grid0.setColumnStretch(0, 0) + grid0.setColumnStretch(1, 1) + + # Tool Name + self.name_label = QtWidgets.QLabel('%s:' % _('Tool Name')) + self.name_label.setToolTip( + _("Tool name.\n" + "This is not used in the app, it's function\n" + "is to serve as a note for the user.")) + + self.name_entry = FCEntry() + self.name_entry.setObjectName('gdb_name') + + grid0.addWidget(self.name_label, 0, 0) + grid0.addWidget(self.name_entry, 0, 1) + + # Tool Dia + self.dia_label = QtWidgets.QLabel('%s:' % _('Tool Dia')) + self.dia_label.setToolTip( + _("Tool Diameter.")) + + self.dia_entry = FCDoubleSpinner() + self.dia_entry.set_range(-9999.9999, 9999.9999) + self.dia_entry.set_precision(self.decimals) + self.dia_entry.setObjectName('gdb_dia') + + grid0.addWidget(self.dia_label, 1, 0) + grid0.addWidget(self.dia_entry, 1, 1) + + # Tool Shape + self.shape_label = QtWidgets.QLabel('%s:' % _('Tool Shape')) + self.shape_label.setToolTip( + _("Tool Shape. \n" + "Can be:\n" + "C1 ... C4 = circular tool with x flutes\n" + "B = ball tip milling tool\n" + "V = v-shape milling tool")) + + self.shape_combo = FCComboBox() + self.shape_combo.addItems(["C1", "C2", "C3", "C4", "B", "V"]) + self.shape_combo.setObjectName('gdb_shape') + + grid0.addWidget(self.shape_label, 2, 0) + grid0.addWidget(self.shape_combo, 2, 1) + + # Cut Z + self.cutz_label = QtWidgets.QLabel('%s:' % _("Cut Z")) + self.cutz_label.setToolTip( + _("Cutting Depth.\n" + "The depth at which to cut into material.")) + + self.cutz_entry = FCDoubleSpinner() + self.cutz_entry.set_range(-9999.9999, 9999.9999) + self.cutz_entry.set_precision(self.decimals) + self.cutz_entry.setObjectName('gdb_cutz') + + grid0.addWidget(self.cutz_label, 4, 0) + grid0.addWidget(self.cutz_entry, 4, 1) + + # Multi Depth + self.multidepth_label = QtWidgets.QLabel('%s:' % _("MultiDepth")) + self.multidepth_label.setToolTip( + _("Multi Depth.\n" + "Selecting this will allow cutting in multiple passes,\n" + "each pass adding a DPP parameter depth.")) + + self.multidepth_cb = FCCheckBox() + self.multidepth_cb.setObjectName('gdb_multidepth') + + grid0.addWidget(self.multidepth_label, 5, 0) + grid0.addWidget(self.multidepth_cb, 5, 1) + + # Depth Per Pass + self.dpp_label = QtWidgets.QLabel('%s:' % _("DPP")) + self.dpp_label.setToolTip( + _("DPP. Depth per Pass.\n" + "The value used to cut into material on each pass.")) + + self.multidepth_entry = FCDoubleSpinner() + self.multidepth_entry.set_range(-9999.9999, 9999.9999) + self.multidepth_entry.set_precision(self.decimals) + self.multidepth_entry.setObjectName('gdb_multidepth_entry') + + grid0.addWidget(self.dpp_label, 7, 0) + grid0.addWidget(self.multidepth_entry, 7, 1) + + # Travel Z + self.travelz_label = QtWidgets.QLabel('%s:' % _("Travel Z")) + self.travelz_label.setToolTip( + _("Clearance Height.\n" + "Height at which the milling bit will travel between cuts,\n" + "above the surface of the material, avoiding all fixtures.")) + + self.travelz_entry = FCDoubleSpinner() + self.travelz_entry.set_range(-9999.9999, 9999.9999) + self.travelz_entry.set_precision(self.decimals) + self.travelz_entry.setObjectName('gdb_travel') + + grid0.addWidget(self.travelz_label, 9, 0) + grid0.addWidget(self.travelz_entry, 9, 1) + + # Feedrate X-Y + self.frxy_label = QtWidgets.QLabel('%s:' % _("Feedrate X-Y")) + self.frxy_label.setToolTip( + _("Feedrate X-Y. Feedrate\n" + "The speed on XY plane used while cutting into material.")) + + self.frxy_entry = FCEntry() + self.frxy_entry.setObjectName('gdb_frxy') + + grid0.addWidget(self.frxy_label, 12, 0) + grid0.addWidget(self.frxy_entry, 12, 1) + + # Feedrate Z + self.frz_label = QtWidgets.QLabel('%s:' % _("Feedrate Z")) + self.frz_label.setToolTip( + _("Feedrate Z\n" + "The speed on Z plane.")) + + self.frz_entry = FCDoubleSpinner() + self.frz_entry.set_range(-9999.9999, 9999.9999) + self.frz_entry.set_precision(self.decimals) + self.frz_entry.setObjectName('gdb_frz') + + grid0.addWidget(self.frz_label, 14, 0) + grid0.addWidget(self.frz_entry, 14, 1) + + # Spindle Spped + self.spindle_label = QtWidgets.QLabel('%s:' % _("Spindle Speed")) + self.spindle_label.setToolTip( + _("Spindle Speed.\n" + "If it's left empty it will not be used.\n" + "The speed of the spindle in RPM.")) + + self.spindle_entry = FCDoubleSpinner() + self.spindle_entry.set_range(-9999.9999, 9999.9999) + self.spindle_entry.set_precision(self.decimals) + self.frz_entry.setObjectName('gdb_spindle') + + grid0.addWidget(self.spindle_label, 15, 0) + grid0.addWidget(self.spindle_entry, 15, 1) + + # Dwell + self.dwell_label = QtWidgets.QLabel('%s:' % _("Dwell")) + self.dwell_label.setToolTip( + _("Dwell.\n" + "Check this if a delay is needed to allow\n" + "the spindle motor to reach it's set speed.")) + + self.dwell_cb = FCCheckBox() + self.dwell_cb.setObjectName('gdb_dwell') + + grid0.addWidget(self.dwell_label, 16, 0) + grid0.addWidget(self.dwell_cb, 16, 1) + + # Dwell Time + self.dwelltime_label = QtWidgets.QLabel('%s:' % _("Dwelltime")) + self.dwelltime_label.setToolTip( + _("Dwell Time.\n" + "A delay used to allow the motor spindle reach it's set speed.")) + + self.dwelltime_entry = FCDoubleSpinner() + self.dwelltime_entry.set_range(0.0000, 9999.9999) + self.dwelltime_entry.set_precision(self.decimals) + self.dwelltime_entry.setObjectName('gdb_dwelltime') + + grid0.addWidget(self.dwelltime_label, 17, 0) + grid0.addWidget(self.dwelltime_entry, 17, 1) + + # ########################################################################### + # ############### ADVANCED UI form ########################################## + # ########################################################################### + + grid1 = QtWidgets.QGridLayout() + self.advanced_vlay.addLayout(grid1) + grid1.setColumnStretch(0, 0) + grid1.setColumnStretch(1, 1) + + # Tool Type + self.type_label = QtWidgets.QLabel('%s:' % _("Tool Type")) + self.type_label.setToolTip( + _("Tool Type.\n" + "Can be:\n" + "Iso = isolation cut\n" + "Rough = rough cut, low feedrate, multiple passes\n" + "Finish = finishing cut, high feedrate")) + + self.type_combo = FCComboBox() + self.type_combo.addItems(["Iso", "Rough", "Finish"]) + self.type_combo.setObjectName('gdb_type') + + grid1.addWidget(self.type_label, 0, 0) + grid1.addWidget(self.type_combo, 0, 1) + + # Tool Offset + self.tooloffset_label = QtWidgets.QLabel('%s:' % _('Tool Offset')) + self.tooloffset_label.setToolTip( + _("Tool Offset.\n" + "Can be of a few types:\n" + "Path = zero offset\n" + "In = offset inside by half of tool diameter\n" + "Out = offset outside by half of tool diameter\n" + "Custom = custom offset using the Custom Offset value")) + + self.tooloffset_combo = FCComboBox() + self.tooloffset_combo.addItems(["Path", "In", "Out", "Custom"]) + self.tooloffset_combo.setObjectName('gdb_tool_offset') + + grid1.addWidget(self.tooloffset_label, 2, 0) + grid1.addWidget(self.tooloffset_combo, 2, 1) + + # Custom Offset + self.custom_offset_label = QtWidgets.QLabel('%s:' % _("Custom Offset")) + self.custom_offset_label.setToolTip( + _("Custom Offset.\n" + "A value to be used as offset from the current path.")) + + self.custom_offset_entry = FCDoubleSpinner() + self.custom_offset_entry.set_range(-9999.9999, 9999.9999) + self.custom_offset_entry.set_precision(self.decimals) + self.custom_offset_entry.setObjectName('gdb_custom_offset') + + grid1.addWidget(self.custom_offset_label, 5, 0) + grid1.addWidget(self.custom_offset_entry, 5, 1) + + # V-Dia + self.vdia_label = QtWidgets.QLabel('%s:' % _("V-Dia")) + self.vdia_label.setToolTip( + _("V-Dia.\n" + "Diameter of the tip for V-Shape Tools.")) + + self.vdia_entry = FCDoubleSpinner() + self.vdia_entry.set_range(0.0000, 9999.9999) + self.vdia_entry.set_precision(self.decimals) + self.vdia_entry.setObjectName('gdb_vdia') + + grid1.addWidget(self.vdia_label, 7, 0) + grid1.addWidget(self.vdia_entry, 7, 1) + + # V-Angle + self.vangle_label = QtWidgets.QLabel('%s:' % _("V-Angle")) + self.vangle_label.setToolTip( + _("V-Agle.\n" + "Angle at the tip for the V-Shape Tools.")) + + self.vangle_entry = FCDoubleSpinner() + self.vangle_entry.set_range(-360.0, 360.0) + self.vangle_entry.set_precision(self.decimals) + self.vangle_entry.setObjectName('gdb_vangle') + + grid1.addWidget(self.vangle_label, 8, 0) + grid1.addWidget(self.vangle_entry, 8, 1) + + # Feedrate Rapids + self.frapids_label = QtWidgets.QLabel('%s:' % _("FR Rapids")) + self.frapids_label.setToolTip( + _("FR Rapids. Feedrate Rapids\n" + "Speed used while moving as fast as possible.\n" + "This is used only by some devices that can't use\n" + "the G0 g-code command. Mostly 3D printers.")) + + self.frapids_entry = FCDoubleSpinner() + self.frapids_entry.set_range(0.0000, 9999.9999) + self.frapids_entry.set_precision(self.decimals) + self.frapids_entry.setObjectName('gdb_frapids') + + grid1.addWidget(self.frapids_label, 10, 0) + grid1.addWidget(self.frapids_entry, 10, 1) + + # Extra Cut + self.ecut_label = QtWidgets.QLabel('%s:' % _("ExtraCut")) + self.ecut_label.setToolTip( + _("Extra Cut.\n" + "If checked, after a isolation is finished an extra cut\n" + "will be added where the start and end of isolation meet\n" + "such as that this point is covered by this extra cut to\n" + "ensure a complete isolation.")) + + self.ecut_cb = FCCheckBox() + self.ecut_cb.setObjectName('gdb_ecut') + + grid1.addWidget(self.ecut_label, 12, 0) + grid1.addWidget(self.ecut_cb, 12, 1) + + # Extra Cut Length + self.ecut_length_label = QtWidgets.QLabel('%s:' % _("E-Cut Length")) + self.ecut_length_label.setToolTip( + _("Extra Cut length.\n" + "If checked, after a isolation is finished an extra cut\n" + "will be added where the start and end of isolation meet\n" + "such as that this point is covered by this extra cut to\n" + "ensure a complete isolation. This is the length of\n" + "the extra cut.")) + + self.ecut_length_entry = FCDoubleSpinner() + self.ecut_length_entry.set_range(0.0000, 9999.9999) + self.ecut_length_entry.set_precision(self.decimals) + self.ecut_length_entry.setObjectName('gdb_ecut_length') + + grid1.addWidget(self.ecut_length_label, 13, 0) + grid1.addWidget(self.ecut_length_entry, 13, 1) + + # #################################################################### + # #################################################################### + # GUI for the lower part of the window + # #################################################################### + # #################################################################### new_vlay = QtWidgets.QVBoxLayout() grid_layout.addLayout(new_vlay, 1, 0, 1, 2) - # new_tool_lbl = QtWidgets.QLabel('%s' % _("New Tool")) - # new_vlay.addWidget(new_tool_lbl, alignment=QtCore.Qt.AlignBottom) - self.buttons_frame = QtWidgets.QFrame() self.buttons_frame.setContentsMargins(0, 0, 0, 0) new_vlay.addWidget(self.buttons_frame) @@ -1459,7 +1795,7 @@ class ToolsDB2(QtWidgets.QWidget): self.buttons_frame.setLayout(self.buttons_box) self.buttons_frame.show() - add_entry_btn = FCButton(_("Add Geometry Tool in DB")) + add_entry_btn = FCButton(_("Add Tool in DB")) add_entry_btn.setToolTip( _("Add a new tool in the Tools Database.\n" "It will be used in the Geometry UI.\n" @@ -1510,6 +1846,64 @@ class ToolsDB2(QtWidgets.QWidget): hlay.addWidget(self.cancel_tool_from_db) hlay.addStretch() + # ############################################################################## + # ############################################################################## + # ########## SETUP THE DICTIONARIES THAT HOLD THE WIDGETS ##################### + # ############################################################################## + # ############################################################################## + + self.form_fields = { + # Basic + "name": self.name_entry, + "tooldia": self.dia_entry, + "tool_type": self.shape_combo, + "cutz": self.cutz_entry, + "multidepth": self.multidepth_cb, + "depthperpass": self.multidepth_entry, + "travelz": self.travelz_entry, + "feedrate": self.frxy_entry, + "feedrate_z": self.frxy_entry, + "spindlespeed": self.spindle_entry, + "dwell": self.dwell_cb, + "dwelltime": self.dwelltime_entry, + + # Advanced + "type": self.type_combo, + "offset": self.tooloffset_combo, + "offset_value": self.custom_offset_entry, + "vtipdia": self.vdia_entry, + "vtipangle": self.vangle_entry, + "feedrate_rapid": self.frapids_entry, + "extracut": self.ecut_cb, + "extracut_length": self.ecut_length_entry + } + + self.name2option = { + # Basic + "gdb_name": "name", + "gdb_dia": "tooldia", + "gdb_shape": "tool_type", + "gdb_cutz": "cutz", + "gdb_multidepth": "multidepth", + "gdb_multidepth_entry": "depthperpass", + "gdb_travel": "travelz", + "gdb_frxy": "feedrate", + "gdb_frz": "feedrate_z", + "gdb_spindle": "spindlespeed", + "gdb_dwell": "dwell", + "gdb_dwelltime": "dwelltime", + + # Advanced + "gdb_type": "type", + "gdb_tool_offset": "offset", + "gdb_custom_offset": "offset_value", + "gdb_vdia": "vtipdia", + "gdb_vangle": "vtipangle", + "gdb_frapids": "feedrate_rapid", + "gdb_ecut": "extracut", + "gdb_ecut_length": "extracut_length" + } + # ############################################################################## # ######################## SIGNALS ############################################# # ############################################################################## @@ -1541,149 +1935,34 @@ class ToolsDB2(QtWidgets.QWidget): row = int(item.text(0)) - 1 self.table_widget.item(row, 1).setText(item.text(1)) - def configure_table(self): - self.table_widget.setColumnCount(27) - # self.table_widget.setColumnWidth(0, 20) - self.table_widget.setHorizontalHeaderLabels( - [ - '#', - _("Tool Name"), - _("Tool Dia"), - _("Tool Offset"), - _("Custom Offset"), - _("Tool Type"), - _("Tool Shape"), - _("Cut Z"), - _("MultiDepth"), - _("DPP"), - _("V-Dia"), - _("V-Angle"), - _("Travel Z"), - _("FR"), - _("FR Z"), - _("FR Rapids"), - _("Spindle Speed"), - _("Dwell"), - _("Dwelltime"), - _("Preprocessor"), - _("ExtraCut"), - _("E-Cut Length"), - _("Toolchange"), - _("Toolchange XY"), - _("Toolchange Z"), - _("Start Z"), - _("End Z"), - ] - ) - self.table_widget.horizontalHeaderItem(0).setToolTip( - _("Tool Index.")) - self.table_widget.horizontalHeaderItem(1).setToolTip( - _("Tool name.\n" - "This is not used in the app, it's function\n" - "is to serve as a note for the user.")) - self.table_widget.horizontalHeaderItem(2).setToolTip( - _("Tool Diameter.")) - self.table_widget.horizontalHeaderItem(3).setToolTip( - _("Tool Offset.\n" - "Can be of a few types:\n" - "Path = zero offset\n" - "In = offset inside by half of tool diameter\n" - "Out = offset outside by half of tool diameter\n" - "Custom = custom offset using the Custom Offset value")) - self.table_widget.horizontalHeaderItem(4).setToolTip( - _("Custom Offset.\n" - "A value to be used as offset from the current path.")) - self.table_widget.horizontalHeaderItem(5).setToolTip( - _("Tool Type.\n" - "Can be:\n" - "Iso = isolation cut\n" - "Rough = rough cut, low feedrate, multiple passes\n" - "Finish = finishing cut, high feedrate")) - self.table_widget.horizontalHeaderItem(6).setToolTip( - _("Tool Shape. \n" - "Can be:\n" - "C1 ... C4 = circular tool with x flutes\n" - "B = ball tip milling tool\n" - "V = v-shape milling tool")) - self.table_widget.horizontalHeaderItem(7).setToolTip( - _("Cutting Depth.\n" - "The depth at which to cut into material.")) - self.table_widget.horizontalHeaderItem(8).setToolTip( - _("Multi Depth.\n" - "Selecting this will allow cutting in multiple passes,\n" - "each pass adding a DPP parameter depth.")) - self.table_widget.horizontalHeaderItem(9).setToolTip( - _("DPP. Depth per Pass.\n" - "The value used to cut into material on each pass.")) - self.table_widget.horizontalHeaderItem(10).setToolTip( - _("V-Dia.\n" - "Diameter of the tip for V-Shape Tools.")) - self.table_widget.horizontalHeaderItem(11).setToolTip( - _("V-Agle.\n" - "Angle at the tip for the V-Shape Tools.")) - self.table_widget.horizontalHeaderItem(12).setToolTip( - _("Clearance Height.\n" - "Height at which the milling bit will travel between cuts,\n" - "above the surface of the material, avoiding all fixtures.")) - self.table_widget.horizontalHeaderItem(13).setToolTip( - _("FR. Feedrate\n" - "The speed on XY plane used while cutting into material.")) - self.table_widget.horizontalHeaderItem(14).setToolTip( - _("FR Z. Feedrate Z\n" - "The speed on Z plane.")) - self.table_widget.horizontalHeaderItem(15).setToolTip( - _("FR Rapids. Feedrate Rapids\n" - "Speed used while moving as fast as possible.\n" - "This is used only by some devices that can't use\n" - "the G0 g-code command. Mostly 3D printers.")) - self.table_widget.horizontalHeaderItem(16).setToolTip( - _("Spindle Speed.\n" - "If it's left empty it will not be used.\n" - "The speed of the spindle in RPM.")) - self.table_widget.horizontalHeaderItem(17).setToolTip( - _("Dwell.\n" - "Check this if a delay is needed to allow\n" - "the spindle motor to reach it's set speed.")) - self.table_widget.horizontalHeaderItem(18).setToolTip( - _("Dwell Time.\n" - "A delay used to allow the motor spindle reach it's set speed.")) - self.table_widget.horizontalHeaderItem(19).setToolTip( - _("Preprocessor.\n" - "A selection of files that will alter the generated G-code\n" - "to fit for a number of use cases.")) - self.table_widget.horizontalHeaderItem(20).setToolTip( - _("Extra Cut.\n" - "If checked, after a isolation is finished an extra cut\n" - "will be added where the start and end of isolation meet\n" - "such as that this point is covered by this extra cut to\n" - "ensure a complete isolation.")) - self.table_widget.horizontalHeaderItem(21).setToolTip( - _("Extra Cut length.\n" - "If checked, after a isolation is finished an extra cut\n" - "will be added where the start and end of isolation meet\n" - "such as that this point is covered by this extra cut to\n" - "ensure a complete isolation. This is the length of\n" - "the extra cut.")) - self.table_widget.horizontalHeaderItem(22).setToolTip( - _("Toolchange.\n" - "It will create a toolchange event.\n" - "The kind of toolchange is determined by\n" - "the preprocessor file.")) - self.table_widget.horizontalHeaderItem(23).setToolTip( - _("Toolchange XY.\n" - "A set of coordinates in the format (x, y).\n" - "Will determine the cartesian position of the point\n" - "where the tool change event take place.")) - self.table_widget.horizontalHeaderItem(24).setToolTip( - _("Toolchange Z.\n" - "The position on Z plane where the tool change event take place.")) - self.table_widget.horizontalHeaderItem(25).setToolTip( - _("Start Z.\n" - "If it's left empty it will not be used.\n" - "A position on Z plane to move immediately after job start.")) - self.table_widget.horizontalHeaderItem(26).setToolTip( - _("End Z.\n" - "A position on Z plane to move immediately after job stop.")) + def storage_to_form(self, dict_storage): + for form_key in self.form_fields: + for storage_key in dict_storage: + if form_key == storage_key: + try: + self.form_fields[form_key].set_value(dict_storage[form_key]) + except Exception: + pass + + def form_to_storage(self, tool): + self.blockSignals(True) + + widget_changed = self.sender() + wdg_objname = widget_changed.objectName() + option_changed = self.name2option[wdg_objname] + + + tooluid_item = int(tool) + + for tooluid_key, tooluid_val in self.db_tool_dict.items(): + if int(tooluid_key) == tooluid_item: + new_option_value = self.form_fields[option_changed].get_value() + if option_changed in tooluid_val: + tooluid_val[option_changed] = new_option_value + if option_changed in tooluid_val['data']: + tooluid_val['data'][option_changed] = new_option_value + + self.blockSignals(False) def setup_db_ui(self): filename = self.app.data_path + '/geo_tools_db.FlatDB' @@ -1709,12 +1988,12 @@ class ToolsDB2(QtWidgets.QWidget): self.build_db_ui() - self.table_widget.setupContextMenu() - self.table_widget.addContextMenu( + self.tree_widget.setupContextMenu() + self.tree_widget.addContextMenu( _("Add to DB"), self.on_tool_add, icon=QtGui.QIcon(self.app.resource_location + "/plus16.png")) - self.table_widget.addContextMenu( + self.tree_widget.addContextMenu( _("Copy from DB"), self.on_tool_copy, icon=QtGui.QIcon(self.app.resource_location + "/copy16.png")) - self.table_widget.addContextMenu( + self.tree_widget.addContextMenu( _("Delete from DB"), self.on_tool_delete, icon=QtGui.QIcon(self.app.resource_location + "/delete32.png")) def build_db_ui(self): diff --git a/README.md b/README.md index 924856e7..f46213c8 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,11 @@ CAD program, and create G-Code for Isolation routing. ================================================= +12.03.2020 + +- working on the new database +- fix a bug in the TextInputTool in FlatCAM Geometry Editor that crashed the sw when some fonts are not loaded correctly + 4.03.2020 - updated all the FlatCAM Tools and the Gerber UI FCComboBoxes to update the box value with the latest object loaded in the App @@ -52,6 +57,7 @@ CAD program, and create G-Code for Isolation routing. - fixed an issue in Gerber Editor where the multiprocessing pool was reported as closed and an ValueError exception was raised in a certain scneraio - on Set Origin, Move to Origin and Move actions for Gerber and Excellon objects the source file will be also updated (the export functions will export an updated object) - in FlatCAMObj.export_gerber() method took into account the possibility of polygons of type 'clear' (the ones found in the Gerber files under the LPC command) + 17.02.2020 - updated the Excellon UI to hold data for each tool diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index 6b5c3cc5..23d47e06 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -202,7 +202,7 @@ class TextInputTool(FlatCAMTool): self.text_path = [] self.decimals = self.app.decimals - self.f_parse = ParseFont(self) + self.f_parse = ParseFont(self.app) self.f_parse.get_fonts_by_types() # this way I can hide/show the frame @@ -364,12 +364,10 @@ class TextInputTool(FlatCAMTool): string_to_geo = self.text_input_entry.get_value() font_to_geo_size = self.font_size_cb.get_value() - self.text_path = self.f_parse.font_to_geometry( - char_string=string_to_geo, - font_name=self.font_name, - font_size=font_to_geo_size, - font_type=font_to_geo_type, - units=self.app.defaults['units'].upper()) + self.text_path = self.f_parse.font_to_geometry(char_string=string_to_geo, font_name=self.font_name, + font_size=font_to_geo_size, + font_type=font_to_geo_type, + units=self.app.defaults['units'].upper()) def font_family(self, font): self.text_input_entry.selectAll() @@ -403,8 +401,8 @@ class TextInputTool(FlatCAMTool): def hide_tool(self): self.text_tool_frame.hide() - self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab) - self.app.ui.splitter.setSizes([0, 1]) + self.app.ui.notebook.setCurrentWidget(self.app.ui.selected_tab) + # self.app.ui.splitter.setSizes([0, 1]) self.app.ui.notebook.setTabText(2, _("Tool")) @@ -2848,7 +2846,7 @@ class FCText(FCShapeTool): self.draw_app.app.inform.emit(_("Click on 1st point ...")) self.origin = (0, 0) - self.text_gui = TextInputTool(self.app) + self.text_gui = TextInputTool(app=self.app) self.text_gui.run() self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x)) diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index acca4dfc..1cd46b4d 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -1414,7 +1414,7 @@ class GeneralAppPrefGroupUI(OptionsGroupUI): def __init__(self, decimals=4, parent=None): super(GeneralAppPrefGroupUI, self).__init__(self) - self.setTitle(str(_("App Preferences"))) + self.setTitle(_("App Preferences")) self.decimals = decimals # Create a form layout for the Application general settings From 98f4a82ad4be193b5bde16ba6cb14a68e359b25a Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 13 Mar 2020 13:29:59 +0200 Subject: [PATCH 127/209] - fixed a bug in CNCJob generation out of a Excellon object; the plot failed in case some of the geometry of the CNCJob was invalid --- README.md | 4 ++++ camlib.py | 3 +++ 2 files changed, 7 insertions(+) diff --git a/README.md b/README.md index f46213c8..b57d51ea 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +13.03.2020 + +- fixed a bug in CNCJob generation out of a Excellon object; the plot failed in case some of the geometry of the CNCJob was invalid + 12.03.2020 - working on the new database diff --git a/camlib.py b/camlib.py index 88a62488..7e322deb 100644 --- a/camlib.py +++ b/camlib.py @@ -4752,6 +4752,9 @@ class CNCjob(Geometry): # if the geos are travel lines it will enter into Exception poly = geo['geom'].buffer(distance=(tooldia / 1.99999999), resolution=self.steps_per_circle) poly = poly.simplify(tool_tolerance) + except Exception: + # deal here with unexpected plot errors due of LineStrings not valid + continue else: # plot the geometry of any objects other than Excellon poly = geo['geom'].buffer(distance=(tooldia / 1.99999999), resolution=self.steps_per_circle) From e6917ba1abcf91421f138e5a06722c30c8538c20 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 13 Mar 2020 15:43:26 +0200 Subject: [PATCH 128/209] - fixed Properties Tool due of recent changes to the FCTree widget --- FlatCAMApp.py | 2 +- README.md | 1 + flatcamGUI/FlatCAMGUI.py | 2 +- flatcamGUI/GUIElements.py | 6 +++++- flatcamTools/ToolProperties.py | 4 ++++ 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index e4c098c4..7245a1e0 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -12727,7 +12727,7 @@ class App(QtCore.QObject): ) return - if act_name == _("Transparency"): + if act_name == _("Opacity"): alpha_level, ok_button = QtWidgets.QInputDialog.getInt( self.ui, _("Set alpha level ..."), '%s:' % _("Value"), min=0, max=255, step=1, value=191) diff --git a/README.md b/README.md index b57d51ea..458acf99 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 13.03.2020 - fixed a bug in CNCJob generation out of a Excellon object; the plot failed in case some of the geometry of the CNCJob was invalid +- fixed Properties Tool due of recent changes to the FCTree widget 12.03.2020 diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index 82d55bcf..35b9ae2a 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -703,7 +703,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.menuprojectcolor.addSeparator() self.menuproject_custom = self.menuprojectcolor.addAction( - QtGui.QIcon(self.app.resource_location + '/set_color32.png'), _('Transparency')) + QtGui.QIcon(self.app.resource_location + '/set_color32.png'), _('Opacity')) self.menuproject_custom = self.menuprojectcolor.addAction( QtGui.QIcon(self.app.resource_location + '/set_color32.png'), _('Default')) diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index f9c7b814..fbfd739e 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -187,7 +187,11 @@ class FCTree(QtWidgets.QTreeWidget): header.resizeSection(column, width) def is_editable(self, tested_col): - return False if tested_col in self.protected_column else True + try: + ret_val = False if tested_col in self.protected_column else True + except TypeError: + ret_val = False + return ret_val def addParent(self, parent, title, expanded=False, color=None, font=None): item = QtWidgets.QTreeWidgetItem(parent, [title]) diff --git a/flatcamTools/ToolProperties.py b/flatcamTools/ToolProperties.py index b09d6e19..da783097 100644 --- a/flatcamTools/ToolProperties.py +++ b/flatcamTools/ToolProperties.py @@ -129,6 +129,10 @@ class Properties(FlatCAMTool): for obj in obj_list: self.addItems(obj) self.app.inform.emit('[success] %s' % _("Object Properties are displayed.")) + + # make sure that the FCTree widget columns are resized to content + self.treeWidget.resize_sig.emit() + self.app.ui.notebook.setTabText(2, _("Properties Tool")) def addItems(self, obj): From f4f87eb2a77be4dc4b1f2a8fbc28a9744886c927 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 20 Mar 2020 05:04:52 +0200 Subject: [PATCH 129/209] - updated the "re-cut" feature in Geometry object; now if the re-cut parameter is non zero it will cut half of the entered distance before the isolation end and half of it after the isolation end --- README.md | 4 +++ camlib.py | 87 +++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 73 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 458acf99..dd05995f 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +20.03.2020 + +- updated the "re-cut" feature in Geometry object; now if the re-cut parameter is non zero it will cut half of the entered distance before the isolation end and half of it after the isolation end + 13.03.2020 - fixed a bug in CNCJob generation out of a Excellon object; the plot failed in case some of the geometry of the CNCJob was invalid diff --git a/camlib.py b/camlib.py index 7e322deb..c2e04a22 100644 --- a/camlib.py +++ b/camlib.py @@ -26,7 +26,7 @@ from lxml import etree as ET from shapely.geometry import Polygon, LineString, Point, LinearRing, MultiLineString, MultiPoint, MultiPolygon from shapely.geometry import box as shply_box -from shapely.ops import cascaded_union, unary_union, polygonize +from shapely.ops import cascaded_union, unary_union, substring import shapely.affinity as affinity from shapely.wkt import loads as sloads from shapely.wkt import dumps as sdumps @@ -5166,8 +5166,8 @@ class CNCjob(Geometry): next_y = pt[1] gcode += self.doformat(p.linear_code, x=next_x, y=next_y, z=z_cut) # Linear motion to point - prev_x = pt[0] - prev_y = pt[1] + prev_x = next_x + prev_y = next_y # this line is added to create an extra cut over the first point in patch # to make sure that we remove the copper leftovers @@ -5186,23 +5186,74 @@ class CNCjob(Geometry): # between point 0 and point 1 is more than the distance we set for the extra cut then make an interpolation # along the path and find the point at the distance extracut_length + # this is an extra line therefore lift the milling bit + gcode += self.doformat(p.lift_code, x=prev_x, y=prev_y, z_move=z_move) # lift + if extracut_length == 0.0: - gcode += self.doformat(p.linear_code, x=path[1][0], y=path[1][1]) - last_pt = path[1] - else: - if abs(distance(path[1], path[0])) > extracut_length: - i_point = LineString([path[0], path[1]]).interpolate(extracut_length) - gcode += self.doformat(p.linear_code, x=i_point.x, y=i_point.y) - last_pt = (i_point.x, i_point.y) + extra_path = [path[-1], path[0], path[1]] + new_x = path[-1][0] + new_y = path[-1][1] + + # move fast to the new first point + gcode += self.doformat(p.rapid_code, x=new_x, y=new_y) + + # lower the milling bit + # Different feedrate for vertical cut? + if self.z_feedrate is not None: + gcode += self.doformat(p.z_feedrate_code) + gcode += self.doformat(p.down_code, x=new_x, y=new_y, z_cut=z_cut) + gcode += self.doformat(p.feedrate_code, feedrate=feedrate) else: - last_pt = path[0] - for pt in path[1:]: - extracut_distance = abs(distance(pt, last_pt)) - if extracut_distance <= extracut_length: - gcode += self.doformat(p.linear_code, x=pt[0], y=pt[1]) - last_pt = pt - else: - break + gcode += self.doformat(p.down_code, x=new_x, y=new_y, z_cut=z_cut) # Start cutting + + # start cutting the extra line + last_pt = extra_path[0] + for pt in extra_path[1:]: + gcode += self.doformat(p.linear_code, x=pt[0], y=pt[1]) + last_pt = pt + else: + # go to the point that is 5% in length before the end (therefore 95% length from start of the line), + # along the line to be cut + extra_line = substring(target_linear, (-extracut_length * 0.5), (extracut_length * 0.5)) + extra_path = list(extra_line.coords) + new_x = extra_path[0][0] + new_y = extra_path[0][1] + + # move fast to the new first point + gcode += self.doformat(p.rapid_code, x=new_x, y=new_y) + + # lower the milling bit + # Different feedrate for vertical cut? + if self.z_feedrate is not None: + gcode += self.doformat(p.z_feedrate_code) + gcode += self.doformat(p.down_code, x=new_x, y=new_y, z_cut=z_cut) + gcode += self.doformat(p.feedrate_code, feedrate=feedrate) + else: + gcode += self.doformat(p.down_code, x=new_x, y=new_y, z_cut=z_cut) # Start cutting + + # start cutting the extra line + last_pt = extra_path[0] + for pt in extra_path[1:]: + gcode += self.doformat(p.linear_code, x=pt[0], y=pt[1]) + last_pt = pt + + # if extracut_length == 0.0: + # gcode += self.doformat(p.linear_code, x=path[1][0], y=path[1][1]) + # last_pt = path[1] + # else: + # if abs(distance(path[1], path[0])) > extracut_length: + # i_point = LineString([path[0], path[1]]).interpolate(extracut_length) + # gcode += self.doformat(p.linear_code, x=i_point.x, y=i_point.y) + # last_pt = (i_point.x, i_point.y) + # else: + # last_pt = path[0] + # for pt in path[1:]: + # extracut_distance = abs(distance(pt, last_pt)) + # if extracut_distance <= extracut_length: + # gcode += self.doformat(p.linear_code, x=pt[0], y=pt[1]) + # last_pt = pt + # else: + # break # Up to travelling height. if up: From 22f74edfab7101b0fda2852907af8c4cfe8a1712 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 20 Mar 2020 13:25:14 +0200 Subject: [PATCH 130/209] - added to Paint and NCC Tool a feature that allow polygon area selection when the reference is selected as Area Selection - in Paint Tool and NCC Tool added ability to use Escape Tool to cancel Area Selection and for Paint Tool to cancel Polygon Selection --- FlatCAMApp.py | 4 + FlatCAMTool.py | 94 +++++++++++++- README.md | 2 + flatcamGUI/PreferencesUI.py | 50 ++++++-- flatcamTools/ToolNCC.py | 221 ++++++++++++++++++++++++++++----- flatcamTools/ToolPaint.py | 240 ++++++++++++++++++++++++++++++------ 6 files changed, 527 insertions(+), 84 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 7245a1e0..0564f774 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -786,6 +786,7 @@ class App(QtCore.QObject): "tools_ncc_offset_choice": False, "tools_ncc_offset_value": 0.0000, "tools_nccref": _('Itself'), + "tools_ncc_area_shape": "square", "tools_ncc_plotting": 'normal', "tools_nccmilling_type": 'cl', "tools_ncctool_type": 'C1', @@ -812,6 +813,7 @@ class App(QtCore.QObject): "tools_paintmargin": 0.0, "tools_paintmethod": _("Seed"), "tools_selectmethod": _("All Polygons"), + "tools_paint_area_shape": "square", "tools_pathconnect": True, "tools_paintcontour": True, "tools_paint_plotting": 'normal', @@ -1468,6 +1470,7 @@ class App(QtCore.QObject): "tools_ncc_offset_choice": self.ui.tools_defaults_form.tools_ncc_group.ncc_choice_offset_cb, "tools_ncc_offset_value": self.ui.tools_defaults_form.tools_ncc_group.ncc_offset_spinner, "tools_nccref": self.ui.tools_defaults_form.tools_ncc_group.select_combo, + "tools_ncc_area_shape": self.ui.tools_defaults_form.tools_ncc_group.area_shape_radio, "tools_ncc_plotting": self.ui.tools_defaults_form.tools_ncc_group.ncc_plotting_radio, "tools_nccmilling_type": self.ui.tools_defaults_form.tools_ncc_group.milling_type_radio, "tools_ncctool_type": self.ui.tools_defaults_form.tools_ncc_group.tool_type_radio, @@ -1494,6 +1497,7 @@ class App(QtCore.QObject): "tools_paintmargin": self.ui.tools_defaults_form.tools_paint_group.paintmargin_entry, "tools_paintmethod": self.ui.tools_defaults_form.tools_paint_group.paintmethod_combo, "tools_selectmethod": self.ui.tools_defaults_form.tools_paint_group.selectmethod_combo, + "tools_paint_area_shape": self.ui.tools_defaults_form.tools_paint_group.area_shape_radio, "tools_pathconnect": self.ui.tools_defaults_form.tools_paint_group.pathconnect_cb, "tools_paintcontour": self.ui.tools_defaults_form.tools_paint_group.contour_cb, "tools_paint_plotting": self.ui.tools_defaults_form.tools_paint_group.paint_plotting_radio, diff --git a/FlatCAMTool.py b/FlatCAMTool.py index 02bd08bd..3343c06c 100644 --- a/FlatCAMTool.py +++ b/FlatCAMTool.py @@ -9,7 +9,7 @@ from PyQt5 import QtGui, QtCore, QtWidgets, QtWidgets from PyQt5.QtCore import Qt -from shapely.geometry import Polygon +from shapely.geometry import Polygon, LineString import gettext import FlatCAMTranslation as fcTranslate @@ -106,6 +106,7 @@ class FlatCAMTool(QtWidgets.QWidget): :param old_coords: old coordinates :param coords: new coordinates + :param kwargs: :return: """ @@ -143,10 +144,101 @@ class FlatCAMTool(QtWidgets.QWidget): if self.app.is_legacy is True: self.app.tool_shapes.redraw() + def draw_selection_shape_polygon(self, points, **kwargs): + """ + + :param points: a list of points from which to create a Polygon + :param kwargs: + :return: + """ + if 'color' in kwargs: + color = kwargs['color'] + else: + color = self.app.defaults['global_sel_line'] + + if 'face_color' in kwargs: + face_color = kwargs['face_color'] + else: + face_color = self.app.defaults['global_sel_fill'] + + if 'face_alpha' in kwargs: + face_alpha = kwargs['face_alpha'] + else: + face_alpha = 0.3 + if len(points) < 3: + sel_rect = LineString(points) + else: + sel_rect = Polygon(points) + + # color_t = Color(face_color) + # color_t.alpha = face_alpha + + color_t = face_color[:-2] + str(hex(int(face_alpha * 255)))[2:] + + self.app.tool_shapes.add(sel_rect, color=color, face_color=color_t, update=True, + layer=0, tolerance=None) + if self.app.is_legacy is True: + self.app.tool_shapes.redraw() + def delete_tool_selection_shape(self): self.app.tool_shapes.clear() self.app.tool_shapes.redraw() + def draw_moving_selection_shape_poly(self, points, data, **kwargs): + """ + + :param points: + :param data: + :param kwargs: + :return: + """ + if 'color' in kwargs: + color = kwargs['color'] + else: + color = self.app.defaults['global_sel_line'] + + if 'face_color' in kwargs: + face_color = kwargs['face_color'] + else: + face_color = self.app.defaults['global_sel_fill'] + + if 'face_alpha' in kwargs: + face_alpha = kwargs['face_alpha'] + else: + face_alpha = 0.3 + + temp_points = [x for x in points] + try: + if data != temp_points[-1]: + temp_points.append(data) + except IndexError: + return + + l_points = len(temp_points) + if l_points == 2: + geo = LineString(temp_points) + elif l_points > 2: + geo = Polygon(temp_points) + else: + return + + color_t = face_color[:-2] + str(hex(int(face_alpha * 255)))[2:] + color_t_error = "#00000000" + + if geo.is_valid and not geo.is_empty: + self.app.move_tool.sel_shapes.add(geo, color=color, face_color=color_t, update=True, + layer=0, tolerance=None) + elif not geo.is_valid: + self.app.move_tool.sel_shapes.add(geo, color="red", face_color=color_t_error, update=True, + layer=0, tolerance=None) + + if self.app.is_legacy is True: + self.app.move_tool.sel_shapes.redraw() + + def delete_moving_selection_shape(self): + self.app.move_tool.sel_shapes.clear() + self.app.move_tool.sel_shapes.redraw() + def confirmation_message(self, accepted, minval, maxval): if accepted is False: self.app.inform.emit('[WARNING_NOTCL] %s: [%.*f, %.*f]' % diff --git a/README.md b/README.md index dd05995f..012292c8 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ CAD program, and create G-Code for Isolation routing. 20.03.2020 - updated the "re-cut" feature in Geometry object; now if the re-cut parameter is non zero it will cut half of the entered distance before the isolation end and half of it after the isolation end +- added to Paint and NCC Tool a feature that allow polygon area selection when the reference is selected as Area Selection +- in Paint Tool and NCC Tool added ability to use Escape Tool to cancel Area Selection and for Paint Tool to cancel Polygon Selection 13.03.2020 diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index 1cd46b4d..239b6fbb 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -2521,7 +2521,7 @@ class GerberEditorPrefGroupUI(OptionsGroupUI): self.adddim_label = QtWidgets.QLabel('%s:' % _('Aperture Dimensions')) self.adddim_label.setToolTip( - _("Diameters of the cutting tools, separated by comma.\n" + _("Diameters of the tools, separated by comma.\n" "The value of the diameter has to use the dot decimals separator.\n" "Valid values: 0.3, 1.0") ) @@ -3970,9 +3970,9 @@ class GeometryGenPrefGroupUI(OptionsGroupUI): grid0.addWidget(self.tools_label, 2, 0, 1, 2) # Tooldia - tdlabel = QtWidgets.QLabel('%s:' % _('Tool dia')) + tdlabel = QtWidgets.QLabel('%s:' % _('Tools Dia')) tdlabel.setToolTip( - _("Diameters of the cutting tools, separated by comma.\n" + _("Diameters of the tools, separated by comma.\n" "The value of the diameter has to use the dot decimals separator.\n" "Valid values: 0.3, 1.0") ) @@ -5139,7 +5139,7 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): ncctdlabel = QtWidgets.QLabel('%s:' % _('Tools Dia')) ncctdlabel.setToolTip( - _("Diameters of the cutting tools, separated by comma.\n" + _("Diameters of the tools, separated by comma.\n" "The value of the diameter has to use the dot decimals separator.\n" "Valid values: 0.3, 1.0") ) @@ -5418,10 +5418,21 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): grid0.addWidget(select_label, 18, 0) grid0.addWidget(self.select_combo, 18, 1) + self.area_shape_label = QtWidgets.QLabel('%s:' % _("Shape")) + self.area_shape_label.setToolTip( + _("The kind of selection shape used for area selection.") + ) + + self.area_shape_radio = RadioSet([{'label': _("Square"), 'value': 'square'}, + {'label': _("Polygon"), 'value': 'polygon'}]) + + grid0.addWidget(self.area_shape_label, 19, 0) + grid0.addWidget(self.area_shape_radio, 19, 1) + separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - grid0.addWidget(separator_line, 19, 0, 1, 2) + grid0.addWidget(separator_line, 20, 0, 1, 2) # ## Plotting type self.ncc_plotting_radio = RadioSet([{'label': _('Normal'), 'value': 'normal'}, @@ -5431,8 +5442,8 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): _("- 'Normal' - normal plotting, done at the end of the NCC job\n" "- 'Progressive' - after each shape is generated it will be plotted.") ) - grid0.addWidget(plotting_label, 20, 0) - grid0.addWidget(self.ncc_plotting_radio, 20, 1) + grid0.addWidget(plotting_label, 21, 0) + grid0.addWidget(self.ncc_plotting_radio, 21, 1) self.layout.addStretch() @@ -5695,7 +5706,7 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI): # Tool dia ptdlabel = QtWidgets.QLabel('%s:' % _('Tools Dia')) ptdlabel.setToolTip( - _("Diameters of the cutting tools, separated by comma.\n" + _("Diameters of the tools, separated by comma.\n" "The value of the diameter has to use the dot decimals separator.\n" "Valid values: 0.3, 1.0") ) @@ -5931,10 +5942,21 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI): grid0.addWidget(selectlabel, 15, 0) grid0.addWidget(self.selectmethod_combo, 15, 1) + self.area_shape_label = QtWidgets.QLabel('%s:' % _("Shape")) + self.area_shape_label.setToolTip( + _("The kind of selection shape used for area selection.") + ) + + self.area_shape_radio = RadioSet([{'label': _("Square"), 'value': 'square'}, + {'label': _("Polygon"), 'value': 'polygon'}]) + + grid0.addWidget(self.area_shape_label, 18, 0) + grid0.addWidget(self.area_shape_radio, 18, 1) + separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - grid0.addWidget(separator_line, 16, 0, 1, 2) + grid0.addWidget(separator_line, 19, 0, 1, 2) # ## Plotting type self.paint_plotting_radio = RadioSet([{'label': _('Normal'), 'value': 'normal'}, @@ -5944,8 +5966,8 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI): _("- 'Normal' - normal plotting, done at the end of the Paint job\n" "- 'Progressive' - after each shape is generated it will be plotted.") ) - grid0.addWidget(plotting_label, 17, 0) - grid0.addWidget(self.paint_plotting_radio, 17, 1) + grid0.addWidget(plotting_label, 20, 0) + grid0.addWidget(self.paint_plotting_radio, 20, 1) self.layout.addStretch() @@ -6748,9 +6770,11 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI): self.layout.addLayout(grid0) # Nozzle Tool Diameters - nozzletdlabel = QtWidgets.QLabel('%s:' % _('Tools dia')) + nozzletdlabel = QtWidgets.QLabel('%s:' % _('Tools Dia')) nozzletdlabel.setToolTip( - _("Diameters of nozzle tools, separated by ','") + _("Diameters of the tools, separated by comma.\n" + "The value of the diameter has to use the dot decimals separator.\n" + "Valid values: 0.3, 1.0") ) self.nozzle_tool_dia_entry = FCEntry() diff --git a/flatcamTools/ToolNCC.py b/flatcamTools/ToolNCC.py index 2873be89..630e87b5 100644 --- a/flatcamTools/ToolNCC.py +++ b/flatcamTools/ToolNCC.py @@ -22,6 +22,8 @@ from shapely.geometry import base from shapely.ops import cascaded_union from shapely.geometry import MultiPolygon, Polygon, MultiLineString, LineString, LinearRing +from matplotlib.backend_bases import KeyEvent as mpl_key_event + import logging import traceback import gettext @@ -571,10 +573,25 @@ class NonCopperClear(FlatCAMTool, Gerber): self.reference_combo_type.hide() self.reference_combo_type_label.hide() + # Area Selection shape + self.area_shape_label = QtWidgets.QLabel('%s:' % _("Shape")) + self.area_shape_label.setToolTip( + _("The kind of selection shape used for area selection.") + ) + + self.area_shape_radio = RadioSet([{'label': _("Square"), 'value': 'square'}, + {'label': _("Polygon"), 'value': 'polygon'}]) + + self.grid3.addWidget(self.area_shape_label, 29, 0) + self.grid3.addWidget(self.area_shape_radio, 29, 1) + + self.area_shape_label.hide() + self.area_shape_radio.hide() + separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - self.grid3.addWidget(separator_line, 29, 0, 1, 2) + self.grid3.addWidget(separator_line, 30, 0, 1, 2) self.generate_ncc_button = QtWidgets.QPushButton(_('Generate Geometry')) self.generate_ncc_button.setToolTip( @@ -652,9 +669,17 @@ class NonCopperClear(FlatCAMTool, Gerber): self.cursor_pos = None self.mouse_is_dragging = False + # store here the points for the "Polygon" area selection shape + self.points = [] + # set this as True when in middle of drawing a "Polygon" area selection shape + # it is made False by first click to signify that the shape is complete + self.poly_drawn = False + self.mm = None self.mr = None + self.kp = None + # store here solid_geometry when there are tool with isolation job self.solid_geometry = [] @@ -666,7 +691,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.tooldia = None self.form_fields = { - "nccoperation":self.op_radio, + "nccoperation": self.op_radio, "nccoverlap": self.ncc_overlap_entry, "nccmargin": self.ncc_margin_entry, "nccmethod": self.ncc_method_combo, @@ -970,6 +995,8 @@ class NonCopperClear(FlatCAMTool, Gerber): self.ncc_offset_spinner.set_value(self.app.defaults["tools_ncc_offset_value"]) self.select_combo.set_value(self.app.defaults["tools_nccref"]) + self.area_shape_radio.set_value(self.app.defaults["tools_ncc_area_shape"]) + self.milling_type_radio.set_value(self.app.defaults["tools_nccmilling_type"]) self.cutz_entry.set_value(self.app.defaults["tools_ncccutz"]) self.tool_type_radio.set_value(self.app.defaults["tools_ncctool_type"]) @@ -1271,16 +1298,39 @@ class NonCopperClear(FlatCAMTool, Gerber): }[self.reference_combo_type.get_value()] def on_toggle_reference(self): - if self.select_combo.get_value() == _("Itself") or self.select_combo.get_value() == _("Area Selection"): + sel_combo = self.select_combo.get_value() + + if sel_combo == _("Itself"): self.reference_combo.hide() self.reference_combo_label.hide() self.reference_combo_type.hide() self.reference_combo_type_label.hide() + self.area_shape_label.hide() + self.area_shape_radio.hide() + + # disable rest-machining for area painting + self.ncc_rest_cb.setDisabled(False) + elif sel_combo == _("Area Selection"): + self.reference_combo.hide() + self.reference_combo_label.hide() + self.reference_combo_type.hide() + self.reference_combo_type_label.hide() + self.area_shape_label.show() + self.area_shape_radio.show() + + # disable rest-machining for area painting + self.ncc_rest_cb.set_value(False) + self.ncc_rest_cb.setDisabled(True) else: self.reference_combo.show() self.reference_combo_label.show() self.reference_combo_type.show() self.reference_combo_type_label.show() + self.area_shape_label.hide() + self.area_shape_radio.hide() + + # disable rest-machining for area painting + self.ncc_rest_cb.setDisabled(False) def on_order_changed(self, order): if order != 'no': @@ -1616,6 +1666,8 @@ class NonCopperClear(FlatCAMTool, Gerber): self.mr = self.app.plotcanvas.graph_event_connect('mouse_release', self.on_mouse_release) self.mm = self.app.plotcanvas.graph_event_connect('mouse_move', self.on_mouse_move) + self.kp = self.app.plotcanvas.graph_event_connect('key_press', self.on_key_press) + elif self.select_method == 'box': self.bound_obj_name = self.reference_combo.currentText() # Get source object. @@ -1643,52 +1695,94 @@ class NonCopperClear(FlatCAMTool, Gerber): right_button = 3 event_pos = self.app.plotcanvas.translate_coords(event_pos) + if self.app.grid_status(): + curr_pos = self.app.geo_editor.snap(event_pos[0], event_pos[1]) + else: + curr_pos = (event_pos[0], event_pos[1]) + + x1, y1 = curr_pos[0], curr_pos[1] + + shape_type = self.area_shape_radio.get_value() # do clear area only for left mouse clicks if event.button == 1: - if self.first_click is False: - self.first_click = True - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Click the end point of the paint area.")) + if shape_type == "square": + if self.first_click is False: + self.first_click = True + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Click the end point of the paint area.")) - self.cursor_pos = self.app.plotcanvas.translate_coords(event_pos) - if self.app.grid_status(): - self.cursor_pos = self.app.geo_editor.snap(event_pos[0], event_pos[1]) - else: - self.app.inform.emit(_("Zone added. Click to start adding next zone or right click to finish.")) - self.app.delete_selection_shape() - - if self.app.grid_status(): - curr_pos = self.app.geo_editor.snap(event_pos[0], event_pos[1]) + self.cursor_pos = self.app.plotcanvas.translate_coords(event_pos) + if self.app.grid_status(): + self.cursor_pos = self.app.geo_editor.snap(event_pos[0], event_pos[1]) else: - curr_pos = (event_pos[0], event_pos[1]) + self.app.inform.emit(_("Zone added. Click to start adding next zone or right click to finish.")) + self.app.delete_selection_shape() - x0, y0 = self.cursor_pos[0], self.cursor_pos[1] - x1, y1 = curr_pos[0], curr_pos[1] - pt1 = (x0, y0) - pt2 = (x1, y0) - pt3 = (x1, y1) - pt4 = (x0, y1) + x0, y0 = self.cursor_pos[0], self.cursor_pos[1] - new_rectangle = Polygon([pt1, pt2, pt3, pt4]) - self.sel_rect.append(new_rectangle) + pt1 = (x0, y0) + pt2 = (x1, y0) + pt3 = (x1, y1) + pt4 = (x0, y1) - # add a temporary shape on canvas - self.draw_tool_selection_shape(old_coords=(x0, y0), coords=(x1, y1)) + new_rectangle = Polygon([pt1, pt2, pt3, pt4]) + self.sel_rect.append(new_rectangle) - self.first_click = False - return + # add a temporary shape on canvas + self.draw_tool_selection_shape(old_coords=(x0, y0), coords=(x1, y1)) + self.first_click = False + return + else: + self.points.append((x1, y1)) + + if len(self.points) > 1: + self.poly_drawn = True + self.app.inform.emit(_("Click on next Point or click right mouse button to complete ...")) + + return "" elif event.button == right_button and self.mouse_is_dragging is False: - self.first_click = False + + shape_type = self.area_shape_radio.get_value() + + if shape_type == "square": + self.first_click = False + else: + # if we finish to add a polygon + if self.poly_drawn is True: + try: + # try to add the point where we last clicked if it is not already in the self.points + last_pt = (x1, y1) + if last_pt != self.points[-1]: + self.points.append(last_pt) + except IndexError: + pass + + # we need to add a Polygon and a Polygon can be made only from at least 3 points + if len(self.points) > 2: + self.delete_moving_selection_shape() + pol = Polygon(self.points) + # do not add invalid polygons even if they are drawn by utility geometry + if pol.is_valid: + self.sel_rect.append(pol) + self.draw_selection_shape_polygon(points=self.points) + self.app.inform.emit( + _("Zone added. Click to start adding next zone or right click to finish.")) + + self.points = [] + self.poly_drawn = False + return self.delete_tool_selection_shape() if self.app.is_legacy is False: self.app.plotcanvas.graph_event_disconnect('mouse_release', self.on_mouse_release) self.app.plotcanvas.graph_event_disconnect('mouse_move', self.on_mouse_move) + self.app.plotcanvas.graph_event_disconnect('key_press', self.on_key_press) else: self.app.plotcanvas.graph_event_disconnect(self.mr) self.app.plotcanvas.graph_event_disconnect(self.mm) + self.app.plotcanvas.graph_event_disconnect(self.kp) self.app.mp = self.app.plotcanvas.graph_event_connect('mouse_press', self.app.on_mouse_click_over_plot) @@ -1710,6 +1804,8 @@ class NonCopperClear(FlatCAMTool, Gerber): # called on mouse move def on_mouse_move(self, event): + shape_type = self.area_shape_radio.get_value() + if self.app.is_legacy is False: event_pos = event.pos event_is_dragging = event.is_dragging @@ -1749,10 +1845,69 @@ class NonCopperClear(FlatCAMTool, Gerber): "%.4f    " % (dx, dy)) # draw the utility geometry - if self.first_click: - self.app.delete_selection_shape() - self.app.draw_moving_selection_shape(old_coords=(self.cursor_pos[0], self.cursor_pos[1]), - coords=(curr_pos[0], curr_pos[1])) + if shape_type == "square": + if self.first_click: + self.app.delete_selection_shape() + self.app.draw_moving_selection_shape(old_coords=(self.cursor_pos[0], self.cursor_pos[1]), + coords=(curr_pos[0], curr_pos[1])) + else: + self.delete_moving_selection_shape() + self.draw_moving_selection_shape_poly(points=self.points, data=(curr_pos[0], curr_pos[1])) + + def on_key_press(self, event): + modifiers = QtWidgets.QApplication.keyboardModifiers() + matplotlib_key_flag = False + + # events out of the self.app.collection view (it's about Project Tab) are of type int + if type(event) is int: + key = event + # events from the GUI are of type QKeyEvent + elif type(event) == QtGui.QKeyEvent: + key = event.key() + elif isinstance(event, mpl_key_event): # MatPlotLib key events are trickier to interpret than the rest + matplotlib_key_flag = True + + key = event.key + key = QtGui.QKeySequence(key) + + # check for modifiers + key_string = key.toString().lower() + if '+' in key_string: + mod, __, key_text = key_string.rpartition('+') + if mod.lower() == 'ctrl': + modifiers = QtCore.Qt.ControlModifier + elif mod.lower() == 'alt': + modifiers = QtCore.Qt.AltModifier + elif mod.lower() == 'shift': + modifiers = QtCore.Qt.ShiftModifier + else: + modifiers = QtCore.Qt.NoModifier + key = QtGui.QKeySequence(key_text) + + # events from Vispy are of type KeyEvent + else: + key = event.key + + if key == QtCore.Qt.Key_Escape or key == 'Escape': + if self.app.is_legacy is False: + self.app.plotcanvas.graph_event_disconnect('mouse_release', self.on_mouse_release) + self.app.plotcanvas.graph_event_disconnect('mouse_move', self.on_mouse_move) + self.app.plotcanvas.graph_event_disconnect('key_press', self.on_key_press) + else: + self.app.plotcanvas.graph_event_disconnect(self.mr) + self.app.plotcanvas.graph_event_disconnect(self.mm) + self.app.plotcanvas.graph_event_disconnect(self.kp) + + self.app.mp = self.app.plotcanvas.graph_event_connect('mouse_press', + self.app.on_mouse_click_over_plot) + self.app.mm = self.app.plotcanvas.graph_event_connect('mouse_move', + self.app.on_mouse_move_over_plot) + self.app.mr = self.app.plotcanvas.graph_event_connect('mouse_release', + self.app.on_mouse_click_release_over_plot) + self.points = [] + self.poly_drawn = False + self.delete_moving_selection_shape() + self.delete_tool_selection_shape() def envelope_object(self, ncc_obj, ncc_select, box_obj=None): """ diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 3951a5cc..8837651e 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -20,6 +20,8 @@ import FlatCAMApp from shapely.geometry import base, Polygon, MultiPolygon, LinearRing, Point, MultiLineString from shapely.ops import cascaded_union, unary_union, linemerge +from matplotlib.backend_bases import KeyEvent as mpl_key_event + import numpy as np import math from numpy import Inf @@ -516,6 +518,21 @@ class ToolPaint(FlatCAMTool, Gerber): self.reference_type_combo.hide() self.reference_type_label.hide() + # Area Selection shape + self.area_shape_label = QtWidgets.QLabel('%s:' % _("Shape")) + self.area_shape_label.setToolTip( + _("The kind of selection shape used for area selection.") + ) + + self.area_shape_radio = RadioSet([{'label': _("Square"), 'value': 'square'}, + {'label': _("Polygon"), 'value': 'polygon'}]) + + grid4.addWidget(self.area_shape_label, 21, 0) + grid4.addWidget(self.area_shape_radio, 21, 1) + + self.area_shape_label.hide() + self.area_shape_radio.hide() + # GO Button self.generate_paint_button = QtWidgets.QPushButton(_('Generate Geometry')) self.generate_paint_button.setToolTip( @@ -573,6 +590,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.units = '' self.paint_tools = {} self.tooluid = 0 + self.first_click = False self.cursor_pos = None self.mouse_is_dragging = False @@ -580,6 +598,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.mm = None self.mp = None self.mr = None + self.kp = None self.sel_rect = [] @@ -612,6 +631,12 @@ class ToolPaint(FlatCAMTool, Gerber): self.old_tool_dia = None + # store here the points for the "Polygon" area selection shape + self.points = [] + # set this as True when in middle of drawing a "Polygon" area selection shape + # it is made False by first click to signify that the shape is complete + self.poly_drawn = False + # ############################################################################# # ################################# Signals ################################### # ############################################################################# @@ -895,7 +920,9 @@ class ToolPaint(FlatCAMTool, Gerber): return float(self.addtool_entry.get_value()) def on_selection(self): - if self.selectmethod_combo.get_value() == _("Reference Object"): + sel_combo = self.selectmethod_combo.get_value() + + if sel_combo == _("Reference Object"): self.reference_combo.show() self.reference_combo_label.show() self.reference_type_combo.show() @@ -906,14 +933,17 @@ class ToolPaint(FlatCAMTool, Gerber): self.reference_type_combo.hide() self.reference_type_label.hide() - if self.selectmethod_combo.get_value() == _("Polygon Selection"): + if sel_combo == _("Polygon Selection"): # disable rest-machining for single polygon painting self.rest_cb.set_value(False) self.rest_cb.setDisabled(True) - if self.selectmethod_combo.get_value() == _("Area Selection"): - # disable rest-machining for single polygon painting + if sel_combo == _("Area Selection"): + # disable rest-machining for area painting self.rest_cb.set_value(False) self.rest_cb.setDisabled(True) + + self.area_shape_label.show() + self.area_shape_radio.show() else: self.rest_cb.setDisabled(False) self.addtool_entry.setDisabled(False) @@ -921,6 +951,9 @@ class ToolPaint(FlatCAMTool, Gerber): self.deltool_btn.setDisabled(False) self.tools_table.setContextMenuPolicy(Qt.ActionsContextMenu) + self.area_shape_label.hide() + self.area_shape_radio.hide() + def on_order_changed(self, order): if order != 'no': self.build_ui() @@ -989,6 +1022,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.paintmargin_entry.set_value(self.app.defaults["tools_paintmargin"]) self.paintmethod_combo.set_value(self.app.defaults["tools_paintmethod"]) self.selectmethod_combo.set_value(self.app.defaults["tools_selectmethod"]) + self.area_shape_radio.set_value(self.app.defaults["tools_paint_area_shape"]) self.pathconnect_cb.set_value(self.app.defaults["tools_pathconnect"]) self.paintcontour_cb.set_value(self.app.defaults["tools_paintcontour"]) self.paintoverlap_entry.set_value(self.app.defaults["tools_paintoverlap"]) @@ -1396,6 +1430,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.grid_status_memory = False self.mr = self.app.plotcanvas.graph_event_connect('mouse_release', self.on_single_poly_mouse_release) + self.kp = self.app.plotcanvas.graph_event_connect('key_press', self.on_key_press) if self.app.is_legacy is False: self.app.plotcanvas.graph_event_disconnect('mouse_release', self.app.on_mouse_click_release_over_plot) @@ -1418,6 +1453,8 @@ class ToolPaint(FlatCAMTool, Gerber): self.mr = self.app.plotcanvas.graph_event_connect('mouse_release', self.on_mouse_release) self.mm = self.app.plotcanvas.graph_event_connect('mouse_move', self.on_mouse_move) + self.kp = self.app.plotcanvas.graph_event_connect('key_press', self.on_key_press) + elif self.select_method == _("Reference Object"): self.bound_obj_name = self.reference_combo.currentText() # Get source object. @@ -1498,8 +1535,10 @@ class ToolPaint(FlatCAMTool, Gerber): if self.app.is_legacy is False: self.app.plotcanvas.graph_event_disconnect('mouse_release', self.on_single_poly_mouse_release) + self.app.plotcanvas.graph_event_disconnect('key_press', self.on_key_press) else: self.app.plotcanvas.graph_event_disconnect(self.mr) + self.app.plotcanvas.graph_event_disconnect(self.kp) self.app.mp = self.app.plotcanvas.graph_event_connect('mouse_press', self.app.on_mouse_click_over_plot) @@ -1540,51 +1579,93 @@ class ToolPaint(FlatCAMTool, Gerber): event_pos = (x, y) + shape_type = self.area_shape_radio.get_value() + + curr_pos = self.app.plotcanvas.translate_coords(event_pos) + if self.app.grid_status(): + curr_pos = self.app.geo_editor.snap(curr_pos[0], curr_pos[1]) + + x1, y1 = curr_pos[0], curr_pos[1] + # do paint single only for left mouse clicks if event.button == 1: - if not self.first_click: - self.first_click = True - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Click the end point of the paint area.")) + if shape_type == "square": + if not self.first_click: + self.first_click = True + self.app.inform.emit('[WARNING_NOTCL] %s' % + _("Click the end point of the paint area.")) - self.cursor_pos = self.app.plotcanvas.translate_coords(event_pos) - if self.app.grid_status(): - self.cursor_pos = self.app.geo_editor.snap(self.cursor_pos[0], self.cursor_pos[1]) + self.cursor_pos = self.app.plotcanvas.translate_coords(event_pos) + if self.app.grid_status(): + self.cursor_pos = self.app.geo_editor.snap(self.cursor_pos[0], self.cursor_pos[1]) + else: + self.app.inform.emit(_("Zone added. Click to start adding next zone or right click to finish.")) + self.app.delete_selection_shape() + + x0, y0 = self.cursor_pos[0], self.cursor_pos[1] + pt1 = (x0, y0) + pt2 = (x1, y0) + pt3 = (x1, y1) + pt4 = (x0, y1) + + new_rectangle = Polygon([pt1, pt2, pt3, pt4]) + self.sel_rect.append(new_rectangle) + + # add a temporary shape on canvas + self.draw_tool_selection_shape(old_coords=(x0, y0), coords=(x1, y1)) + + self.first_click = False + return else: - self.app.inform.emit(_("Zone added. Click to start adding next zone or right click to finish.")) - self.app.delete_selection_shape() + self.points.append((x1, y1)) - curr_pos = self.app.plotcanvas.translate_coords(event_pos) - if self.app.grid_status(): - curr_pos = self.app.geo_editor.snap(curr_pos[0], curr_pos[1]) - - x0, y0 = self.cursor_pos[0], self.cursor_pos[1] - x1, y1 = curr_pos[0], curr_pos[1] - pt1 = (x0, y0) - pt2 = (x1, y0) - pt3 = (x1, y1) - pt4 = (x0, y1) - - new_rectangle = Polygon([pt1, pt2, pt3, pt4]) - self.sel_rect.append(new_rectangle) - - # add a temporary shape on canvas - self.draw_tool_selection_shape(old_coords=(x0, y0), coords=(x1, y1)) - - self.first_click = False - return + if len(self.points) > 1: + self.poly_drawn = True + self.app.inform.emit(_("Click on next Point or click right mouse button to complete ...")) + return "" elif event.button == right_button and self.mouse_is_dragging is False: - self.first_click = False + + shape_type = self.area_shape_radio.get_value() + + if shape_type == "square": + self.first_click = False + else: + # if we finish to add a polygon + if self.poly_drawn is True: + try: + # try to add the point where we last clicked if it is not already in the self.points + last_pt = (x1, y1) + if last_pt != self.points[-1]: + self.points.append(last_pt) + except IndexError: + pass + + # we need to add a Polygon and a Polygon can be made only from at least 3 points + if len(self.points) > 2: + self.delete_moving_selection_shape() + pol = Polygon(self.points) + # do not add invalid polygons even if they are drawn by utility geometry + if pol.is_valid: + self.sel_rect.append(pol) + self.draw_selection_shape_polygon(points=self.points) + self.app.inform.emit( + _("Zone added. Click to start adding next zone or right click to finish.")) + + self.points = [] + self.poly_drawn = False + return self.delete_tool_selection_shape() if self.app.is_legacy is False: self.app.plotcanvas.graph_event_disconnect('mouse_release', self.on_mouse_release) self.app.plotcanvas.graph_event_disconnect('mouse_move', self.on_mouse_move) + self.app.plotcanvas.graph_event_disconnect('key_press', self.on_key_press) else: self.app.plotcanvas.graph_event_disconnect(self.mr) self.app.plotcanvas.graph_event_disconnect(self.mm) + self.app.plotcanvas.graph_event_disconnect(self.kp) self.app.mp = self.app.plotcanvas.graph_event_connect('mouse_press', self.app.on_mouse_click_over_plot) @@ -1607,6 +1688,8 @@ class ToolPaint(FlatCAMTool, Gerber): # called on mouse move def on_mouse_move(self, event): + shape_type = self.area_shape_radio.get_value() + if self.app.is_legacy is False: event_pos = event.pos event_is_dragging = event.is_dragging @@ -1652,10 +1735,93 @@ class ToolPaint(FlatCAMTool, Gerber): "%.4f    " % (dx, dy)) # draw the utility geometry - if self.first_click: - self.app.delete_selection_shape() - self.app.draw_moving_selection_shape(old_coords=(self.cursor_pos[0], self.cursor_pos[1]), - coords=(curr_pos[0], curr_pos[1])) + if shape_type == "square": + if self.first_click: + self.app.delete_selection_shape() + self.app.draw_moving_selection_shape(old_coords=(self.cursor_pos[0], self.cursor_pos[1]), + coords=(curr_pos[0], curr_pos[1])) + else: + self.delete_moving_selection_shape() + self.draw_moving_selection_shape_poly(points=self.points, data=(curr_pos[0], curr_pos[1])) + + def on_key_press(self, event): + modifiers = QtWidgets.QApplication.keyboardModifiers() + matplotlib_key_flag = False + + # events out of the self.app.collection view (it's about Project Tab) are of type int + if type(event) is int: + key = event + # events from the GUI are of type QKeyEvent + elif type(event) == QtGui.QKeyEvent: + key = event.key() + elif isinstance(event, mpl_key_event): # MatPlotLib key events are trickier to interpret than the rest + matplotlib_key_flag = True + + key = event.key + key = QtGui.QKeySequence(key) + + # check for modifiers + key_string = key.toString().lower() + if '+' in key_string: + mod, __, key_text = key_string.rpartition('+') + if mod.lower() == 'ctrl': + modifiers = QtCore.Qt.ControlModifier + elif mod.lower() == 'alt': + modifiers = QtCore.Qt.AltModifier + elif mod.lower() == 'shift': + modifiers = QtCore.Qt.ShiftModifier + else: + modifiers = QtCore.Qt.NoModifier + key = QtGui.QKeySequence(key_text) + + # events from Vispy are of type KeyEvent + else: + key = event.key + + print(key) + if key == QtCore.Qt.Key_Escape or key == 'Escape': + try: + if self.app.is_legacy is False: + self.app.plotcanvas.graph_event_disconnect('mouse_release', self.on_mouse_release) + self.app.plotcanvas.graph_event_disconnect('mouse_move', self.on_mouse_move) + self.app.plotcanvas.graph_event_disconnect('key_press', self.on_key_press) + else: + self.app.plotcanvas.graph_event_disconnect(self.mr) + self.app.plotcanvas.graph_event_disconnect(self.mm) + self.app.plotcanvas.graph_event_disconnect(self.kp) + except Exception as e: + log.debug("ToolPaint.on_key_press() _1 --> %s" % str(e)) + + try: + # restore the Grid snapping if it was active before + if self.grid_status_memory is True: + self.app.ui.grid_snap_btn.trigger() + + if self.app.is_legacy is False: + self.app.plotcanvas.graph_event_disconnect('mouse_release', self.on_single_poly_mouse_release) + self.app.plotcanvas.graph_event_disconnect('key_press', self.on_key_press) + else: + self.app.plotcanvas.graph_event_disconnect(self.mr) + self.app.plotcanvas.graph_event_disconnect(self.kp) + + self.app.tool_shapes.clear(update=True) + except Exception as e: + log.debug("ToolPaint.on_key_press() _2 --> %s" % str(e)) + + self.app.mp = self.app.plotcanvas.graph_event_connect('mouse_press', + self.app.on_mouse_click_over_plot) + self.app.mm = self.app.plotcanvas.graph_event_connect('mouse_move', + self.app.on_mouse_move_over_plot) + self.app.mr = self.app.plotcanvas.graph_event_connect('mouse_release', + self.app.on_mouse_click_release_over_plot) + + self.points = [] + self.poly_drawn = False + + self.poly_dict.clear() + + self.delete_moving_selection_shape() + self.delete_tool_selection_shape() def paint_poly(self, obj, inside_pt=None, poly_list=None, tooldia=None, overlap=None, order=None, margin=None, method=None, outname=None, connect=None, contour=None, tools_storage=None, From ffaea546db3251486995b8ad2e55441d402b3132 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 20 Mar 2020 16:28:59 +0200 Subject: [PATCH 131/209] - fixed issue in "re-cut" feature when combined with multi-depth feature --- README.md | 1 + camlib.py | 48 ++++++++++++++++++++++++++++++++++----- flatcamTools/ToolPaint.py | 1 - 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 012292c8..6a72b728 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ CAD program, and create G-Code for Isolation routing. - updated the "re-cut" feature in Geometry object; now if the re-cut parameter is non zero it will cut half of the entered distance before the isolation end and half of it after the isolation end - added to Paint and NCC Tool a feature that allow polygon area selection when the reference is selected as Area Selection - in Paint Tool and NCC Tool added ability to use Escape Tool to cancel Area Selection and for Paint Tool to cancel Polygon Selection +- fixed issue in "re-cut" feature when combined with multi-depth feature 13.03.2020 diff --git a/camlib.py b/camlib.py index c2e04a22..bcf3c68e 100644 --- a/camlib.py +++ b/camlib.py @@ -5186,13 +5186,13 @@ class CNCjob(Geometry): # between point 0 and point 1 is more than the distance we set for the extra cut then make an interpolation # along the path and find the point at the distance extracut_length - # this is an extra line therefore lift the milling bit - gcode += self.doformat(p.lift_code, x=prev_x, y=prev_y, z_move=z_move) # lift - if extracut_length == 0.0: extra_path = [path[-1], path[0], path[1]] - new_x = path[-1][0] - new_y = path[-1][1] + new_x = extra_path[0][0] + new_y = extra_path[0][1] + + # this is an extra line therefore lift the milling bit + gcode += self.doformat(p.lift_code, x=prev_x, y=prev_y, z_move=z_move) # lift # move fast to the new first point gcode += self.doformat(p.rapid_code, x=new_x, y=new_y) @@ -5211,14 +5211,28 @@ class CNCjob(Geometry): for pt in extra_path[1:]: gcode += self.doformat(p.linear_code, x=pt[0], y=pt[1]) last_pt = pt + + # go back to the original point + gcode += self.doformat(p.linear_code, x=path[0][0], y=path[0][1]) + last_pt = path[0] else: # go to the point that is 5% in length before the end (therefore 95% length from start of the line), # along the line to be cut - extra_line = substring(target_linear, (-extracut_length * 0.5), (extracut_length * 0.5)) + if extracut_length >= target_linear.length: + extracut_length = target_linear.length + + # --------------------------------------------- + # first half + # --------------------------------------------- + start_length = target_linear.length - (extracut_length * 0.5) + extra_line = substring(target_linear, start_length, target_linear.length) extra_path = list(extra_line.coords) new_x = extra_path[0][0] new_y = extra_path[0][1] + # this is an extra line therefore lift the milling bit + gcode += self.doformat(p.lift_code, x=prev_x, y=prev_y, z_move=z_move) # lift + # move fast to the new first point gcode += self.doformat(p.rapid_code, x=new_x, y=new_y) @@ -5231,6 +5245,28 @@ class CNCjob(Geometry): else: gcode += self.doformat(p.down_code, x=new_x, y=new_y, z_cut=z_cut) # Start cutting + # start cutting the extra line + for pt in extra_path[1:]: + gcode += self.doformat(p.linear_code, x=pt[0], y=pt[1]) + + # --------------------------------------------- + # second half + # --------------------------------------------- + extra_line = substring(target_linear, 0, (extracut_length * 0.5)) + extra_path = list(extra_line.coords) + + # start cutting the extra line + last_pt = extra_path[0] + for pt in extra_path[1:]: + gcode += self.doformat(p.linear_code, x=pt[0], y=pt[1]) + last_pt = pt + + # --------------------------------------------- + # back to original start point, cutting + # --------------------------------------------- + extra_line = substring(target_linear, 0, (extracut_length * 0.5)) + extra_path = list(extra_line.coords)[::-1] + # start cutting the extra line last_pt = extra_path[0] for pt in extra_path[1:]: diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 8837651e..0881cbe2 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -1778,7 +1778,6 @@ class ToolPaint(FlatCAMTool, Gerber): else: key = event.key - print(key) if key == QtCore.Qt.Key_Escape or key == 'Escape': try: if self.app.is_legacy is False: From 7415ebc8af5e73e0b658cf99c0174d37be115d69 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 20 Mar 2020 17:12:20 +0200 Subject: [PATCH 132/209] - fixed bugs in cncjob TclCommand --- README.md | 1 + camlib.py | 4 ++-- tclCommands/TclCommandCncjob.py | 7 ++++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6a72b728..75711dbf 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ CAD program, and create G-Code for Isolation routing. - added to Paint and NCC Tool a feature that allow polygon area selection when the reference is selected as Area Selection - in Paint Tool and NCC Tool added ability to use Escape Tool to cancel Area Selection and for Paint Tool to cancel Polygon Selection - fixed issue in "re-cut" feature when combined with multi-depth feature +- fixed bugs in cncjob TclCommand 13.03.2020 diff --git a/camlib.py b/camlib.py index bcf3c68e..96587a0e 100644 --- a/camlib.py +++ b/camlib.py @@ -3905,7 +3905,7 @@ class CNCjob(Geometry): self.feedrate_rapid = float(feedrate_rapid) if feedrate_rapid is not None else \ self.app.defaults["geometry_feedrate_rapid"] - self.spindlespeed = int(spindlespeed) if spindlespeed != 0 else None + self.spindlespeed = int(spindlespeed) if spindlespeed != 0 and spindlespeed is not None else None self.spindledir = spindledir self.dwell = dwell self.dwelltime = float(dwelltime) if dwelltime is not None else self.app.defaults["geometry_dwelltime"] @@ -3919,7 +3919,7 @@ class CNCjob(Geometry): "in the format (x, y) but now there is only one value, not two.")) return 'fail' - self.z_depthpercut = float(depthpercut) if depthpercut is not None else 0.0 + self.z_depthpercut = float(depthpercut) if depthpercut is not None and depthpercut != 0 else abs(self.z_cut) self.multidepth = multidepth self.z_toolchange = float(toolchangez) if toolchangez is not None else self.app.defaults["geometry_toolchangez"] self.extracut_length = float(extracut_length) if extracut_length is not None else \ diff --git a/tclCommands/TclCommandCncjob.py b/tclCommands/TclCommandCncjob.py index eeaa4321..ffb91ba7 100644 --- a/tclCommands/TclCommandCncjob.py +++ b/tclCommands/TclCommandCncjob.py @@ -213,7 +213,12 @@ class TclCommandCncjob(TclCommandSignaled): local_tools_dict[tool_uid]['data']['feedrate_rapid'] = args["feedrate_rapid"] local_tools_dict[tool_uid]['data']['multidepth'] = args["multidepth"] local_tools_dict[tool_uid]['data']['extracut'] = args["extracut"] - local_tools_dict[tool_uid]['data']['extracut_length'] = args["extracut_length"] + + if args["extracut"] is True: + local_tools_dict[tool_uid]['data']['extracut_length'] = args["extracut_length"] + else: + local_tools_dict[tool_uid]['data']['extracut_length'] = None + local_tools_dict[tool_uid]['data']['depthperpass'] = args["depthperpass"] local_tools_dict[tool_uid]['data']['toolchange'] = args["toolchange"] local_tools_dict[tool_uid]['data']['toolchangez'] = args["toolchangez"] From 91884a57e068755b9425021a045ae3651defdfae Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 21 Mar 2020 09:12:15 +0200 Subject: [PATCH 133/209] - fixed Cutout Tool to work with negative values for Margin parameter --- README.md | 4 +++ flatcamTools/ToolCutOut.py | 62 +++++++++++++++++++++++++++----------- 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 75711dbf..7ace08cb 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +21.03.2020 + +- fixed Cutout Tool to work with negative values for Margin parameter + 20.03.2020 - updated the "re-cut" feature in Geometry object; now if the re-cut parameter is non zero it will cut half of the entered distance before the isolation end and half of it after the isolation end diff --git a/flatcamTools/ToolCutOut.py b/flatcamTools/ToolCutOut.py index 9b0ecb3d..17663890 100644 --- a/flatcamTools/ToolCutOut.py +++ b/flatcamTools/ToolCutOut.py @@ -536,6 +536,7 @@ class CutOut(FlatCAMTool): object_geo = cutout_obj.solid_geometry except Exception as err: log.debug("CutOut.on_freeform_cutout().geo_init() --> %s" % str(err)) + object_geo = cutout_obj.solid_geometry else: object_geo = cutout_obj.solid_geometry @@ -606,12 +607,14 @@ class CutOut(FlatCAMTool): if isinstance(object_geo, MultiPolygon): x0, y0, x1, y1 = object_geo.bounds object_geo = box(x0, y0, x1, y1) + if margin >= 0: + geo_buf = object_geo.buffer(margin + abs(dia / 2)) + else: + geo_buf = object_geo.buffer(margin - abs(dia / 2)) - geo_buf = object_geo.buffer(margin + abs(dia / 2)) geo = geo_buf.exterior else: geo = object_geo - solid_geo = cutout_handler(geom=geo) else: try: @@ -621,7 +624,11 @@ class CutOut(FlatCAMTool): for geom_struct in object_geo: if isinstance(cutout_obj, FlatCAMGerber): - geom_struct = (geom_struct.buffer(margin + abs(dia / 2))).exterior + if margin >= 0: + geom_struct = (geom_struct.buffer(margin + abs(dia / 2))).exterior + else: + geom_struct_buff = geom_struct.buffer(-margin + abs(dia / 2)) + geom_struct = geom_struct_buff.interiors solid_geo += cutout_handler(geom=geom_struct) @@ -769,24 +776,43 @@ class CutOut(FlatCAMTool): # if Gerber create a buffer at a distance # if Geometry then cut through the geometry if isinstance(cutout_obj, FlatCAMGerber): - geo = geo.buffer(margin + abs(dia / 2)) + if margin >= 0: + geo = geo.buffer(margin + abs(dia / 2)) + else: + geo = geo.buffer(margin - abs(dia / 2)) solid_geo = cutout_rect_handler(geom=geo) else: - try: - __ = iter(object_geo) - except TypeError: - object_geo = [object_geo] + if cutout_obj.kind == 'geometry': + try: + __ = iter(object_geo) + except TypeError: + object_geo = [object_geo] - for geom_struct in object_geo: - geom_struct = unary_union(geom_struct) - xmin, ymin, xmax, ymax = geom_struct.bounds - geom_struct = box(xmin, ymin, xmax, ymax) + for geom_struct in object_geo: + geom_struct = unary_union(geom_struct) + xmin, ymin, xmax, ymax = geom_struct.bounds + geom_struct = box(xmin, ymin, xmax, ymax) + + solid_geo += cutout_rect_handler(geom=geom_struct) + elif cutout_obj.kind == 'gerber' and margin >= 0: + try: + __ = iter(object_geo) + except TypeError: + object_geo = [object_geo] + + for geom_struct in object_geo: + geom_struct = unary_union(geom_struct) + xmin, ymin, xmax, ymax = geom_struct.bounds + geom_struct = box(xmin, ymin, xmax, ymax) - if isinstance(cutout_obj, FlatCAMGerber): geom_struct = geom_struct.buffer(margin + abs(dia / 2)) - solid_geo += cutout_rect_handler(geom=geom_struct) + solid_geo += cutout_rect_handler(geom=geom_struct) + elif cutout_obj.kind == 'gerber' and margin < 0: + self.app.inform.emit('[WARNING_NOTCL] %s' % + _("Rectangular cutout with negative margin is not possible.")) + return "fail" geo_obj.solid_geometry = deepcopy(solid_geo) geo_obj.options['cnctooldia'] = str(dia) @@ -795,11 +821,11 @@ class CutOut(FlatCAMTool): geo_obj.options['depthperpass'] = self.maxdepth_entry.get_value() outname = cutout_obj.options["name"] + "_cutout" - self.app.new_object('geometry', outname, geo_init) + ret = self.app.new_object('geometry', outname, geo_init) - # cutout_obj.plot() - self.app.inform.emit('[success] %s' % - _("Any form CutOut operation finished.")) + if ret != 'fail': + # cutout_obj.plot() + self.app.inform.emit('[success] %s' % _("Any form CutOut operation finished.")) # self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab) self.app.should_we_save = True From 5554cf0afac606d57f3524f43f2f13b4eae47a40 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 28 Mar 2020 22:22:53 +0200 Subject: [PATCH 134/209] - finished the new database based on a QTreeWidget --- FlatCAMCommon.py | 624 +++++++++++++++++------------------------------ README.md | 4 + requirements.txt | 2 +- 3 files changed, 229 insertions(+), 401 deletions(-) diff --git a/FlatCAMCommon.py b/FlatCAMCommon.py index c8a3860b..644f7ca4 100644 --- a/FlatCAMCommon.py +++ b/FlatCAMCommon.py @@ -1425,6 +1425,8 @@ class ToolsDB2(QtWidgets.QWidget): self.tree_widget = FCTree(columns=2, header_hidden=False, protected_column=[0]) self.tree_widget.setHeaderLabels(["ID", "Tool Name"]) self.tree_widget.setIndentation(0) + self.tree_widget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) + self.tree_widget.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) # set alternating colors # self.tree_widget.setAlternatingRowColors(True) @@ -1436,7 +1438,14 @@ class ToolsDB2(QtWidgets.QWidget): tree_layout.addWidget(self.tree_widget) param_hlay = QtWidgets.QHBoxLayout() - grid_layout.addLayout(param_hlay, 0, 1) + param_area = QtWidgets.QScrollArea() + param_widget = QtWidgets.QWidget() + param_widget.setLayout(param_hlay) + + param_area.setWidget(param_widget) + param_area.setWidgetResizable(True) + + grid_layout.addWidget(param_area, 0, 1) # ########################################################################### # ############## The UI form ################################################ @@ -1450,7 +1459,6 @@ class ToolsDB2(QtWidgets.QWidget): } """) self.basic_vlay = QtWidgets.QVBoxLayout() - self.basic_box.setLayout(self.basic_vlay) self.basic_box.setTitle(_("Basic Parameters")) self.basic_box.setMinimumWidth(250) @@ -1463,21 +1471,25 @@ class ToolsDB2(QtWidgets.QWidget): } """) self.advanced_vlay = QtWidgets.QVBoxLayout() - self.advanced_box.setLayout(self.advanced_vlay) self.advanced_box.setTitle(_("Advanced Parameters")) self.advanced_box.setMinimumWidth(250) - param_hlay.addLayout(self.basic_vlay) - param_hlay.addLayout(self.advanced_vlay) + self.basic_box.setLayout(self.basic_vlay) + self.advanced_box.setLayout(self.advanced_vlay) + + param_hlay.addWidget(self.basic_box) + param_hlay.addWidget(self.advanced_box) + param_hlay.addStretch() # ########################################################################### # ############### BASIC UI form ############################################# # ########################################################################### - grid0 = QtWidgets.QGridLayout() - self.advanced_vlay.addLayout(grid0) - grid0.setColumnStretch(0, 0) - grid0.setColumnStretch(1, 1) + self.grid0 = QtWidgets.QGridLayout() + self.basic_vlay.addLayout(self.grid0) + self.grid0.setColumnStretch(0, 0) + self.grid0.setColumnStretch(1, 1) + self.basic_vlay.addStretch() # Tool Name self.name_label = QtWidgets.QLabel('%s:' % _('Tool Name')) @@ -1489,8 +1501,8 @@ class ToolsDB2(QtWidgets.QWidget): self.name_entry = FCEntry() self.name_entry.setObjectName('gdb_name') - grid0.addWidget(self.name_label, 0, 0) - grid0.addWidget(self.name_entry, 0, 1) + self.grid0.addWidget(self.name_label, 0, 0) + self.grid0.addWidget(self.name_entry, 0, 1) # Tool Dia self.dia_label = QtWidgets.QLabel('%s:' % _('Tool Dia')) @@ -1502,8 +1514,8 @@ class ToolsDB2(QtWidgets.QWidget): self.dia_entry.set_precision(self.decimals) self.dia_entry.setObjectName('gdb_dia') - grid0.addWidget(self.dia_label, 1, 0) - grid0.addWidget(self.dia_entry, 1, 1) + self.grid0.addWidget(self.dia_label, 1, 0) + self.grid0.addWidget(self.dia_entry, 1, 1) # Tool Shape self.shape_label = QtWidgets.QLabel('%s:' % _('Tool Shape')) @@ -1518,8 +1530,8 @@ class ToolsDB2(QtWidgets.QWidget): self.shape_combo.addItems(["C1", "C2", "C3", "C4", "B", "V"]) self.shape_combo.setObjectName('gdb_shape') - grid0.addWidget(self.shape_label, 2, 0) - grid0.addWidget(self.shape_combo, 2, 1) + self.grid0.addWidget(self.shape_label, 2, 0) + self.grid0.addWidget(self.shape_combo, 2, 1) # Cut Z self.cutz_label = QtWidgets.QLabel('%s:' % _("Cut Z")) @@ -1532,8 +1544,8 @@ class ToolsDB2(QtWidgets.QWidget): self.cutz_entry.set_precision(self.decimals) self.cutz_entry.setObjectName('gdb_cutz') - grid0.addWidget(self.cutz_label, 4, 0) - grid0.addWidget(self.cutz_entry, 4, 1) + self.grid0.addWidget(self.cutz_label, 4, 0) + self.grid0.addWidget(self.cutz_entry, 4, 1) # Multi Depth self.multidepth_label = QtWidgets.QLabel('%s:' % _("MultiDepth")) @@ -1545,8 +1557,8 @@ class ToolsDB2(QtWidgets.QWidget): self.multidepth_cb = FCCheckBox() self.multidepth_cb.setObjectName('gdb_multidepth') - grid0.addWidget(self.multidepth_label, 5, 0) - grid0.addWidget(self.multidepth_cb, 5, 1) + self.grid0.addWidget(self.multidepth_label, 5, 0) + self.grid0.addWidget(self.multidepth_cb, 5, 1) # Depth Per Pass self.dpp_label = QtWidgets.QLabel('%s:' % _("DPP")) @@ -1559,8 +1571,8 @@ class ToolsDB2(QtWidgets.QWidget): self.multidepth_entry.set_precision(self.decimals) self.multidepth_entry.setObjectName('gdb_multidepth_entry') - grid0.addWidget(self.dpp_label, 7, 0) - grid0.addWidget(self.multidepth_entry, 7, 1) + self.grid0.addWidget(self.dpp_label, 7, 0) + self.grid0.addWidget(self.multidepth_entry, 7, 1) # Travel Z self.travelz_label = QtWidgets.QLabel('%s:' % _("Travel Z")) @@ -1574,8 +1586,8 @@ class ToolsDB2(QtWidgets.QWidget): self.travelz_entry.set_precision(self.decimals) self.travelz_entry.setObjectName('gdb_travel') - grid0.addWidget(self.travelz_label, 9, 0) - grid0.addWidget(self.travelz_entry, 9, 1) + self.grid0.addWidget(self.travelz_label, 9, 0) + self.grid0.addWidget(self.travelz_entry, 9, 1) # Feedrate X-Y self.frxy_label = QtWidgets.QLabel('%s:' % _("Feedrate X-Y")) @@ -1583,11 +1595,13 @@ class ToolsDB2(QtWidgets.QWidget): _("Feedrate X-Y. Feedrate\n" "The speed on XY plane used while cutting into material.")) - self.frxy_entry = FCEntry() + self.frxy_entry = FCDoubleSpinner() + self.frxy_entry.set_range(-9999.9999, 9999.9999) + self.frxy_entry.set_precision(self.decimals) self.frxy_entry.setObjectName('gdb_frxy') - grid0.addWidget(self.frxy_label, 12, 0) - grid0.addWidget(self.frxy_entry, 12, 1) + self.grid0.addWidget(self.frxy_label, 12, 0) + self.grid0.addWidget(self.frxy_entry, 12, 1) # Feedrate Z self.frz_label = QtWidgets.QLabel('%s:' % _("Feedrate Z")) @@ -1600,8 +1614,8 @@ class ToolsDB2(QtWidgets.QWidget): self.frz_entry.set_precision(self.decimals) self.frz_entry.setObjectName('gdb_frz') - grid0.addWidget(self.frz_label, 14, 0) - grid0.addWidget(self.frz_entry, 14, 1) + self.grid0.addWidget(self.frz_label, 14, 0) + self.grid0.addWidget(self.frz_entry, 14, 1) # Spindle Spped self.spindle_label = QtWidgets.QLabel('%s:' % _("Spindle Speed")) @@ -1615,8 +1629,8 @@ class ToolsDB2(QtWidgets.QWidget): self.spindle_entry.set_precision(self.decimals) self.frz_entry.setObjectName('gdb_spindle') - grid0.addWidget(self.spindle_label, 15, 0) - grid0.addWidget(self.spindle_entry, 15, 1) + self.grid0.addWidget(self.spindle_label, 15, 0) + self.grid0.addWidget(self.spindle_entry, 15, 1) # Dwell self.dwell_label = QtWidgets.QLabel('%s:' % _("Dwell")) @@ -1628,8 +1642,8 @@ class ToolsDB2(QtWidgets.QWidget): self.dwell_cb = FCCheckBox() self.dwell_cb.setObjectName('gdb_dwell') - grid0.addWidget(self.dwell_label, 16, 0) - grid0.addWidget(self.dwell_cb, 16, 1) + self.grid0.addWidget(self.dwell_label, 16, 0) + self.grid0.addWidget(self.dwell_cb, 16, 1) # Dwell Time self.dwelltime_label = QtWidgets.QLabel('%s:' % _("Dwelltime")) @@ -1642,17 +1656,18 @@ class ToolsDB2(QtWidgets.QWidget): self.dwelltime_entry.set_precision(self.decimals) self.dwelltime_entry.setObjectName('gdb_dwelltime') - grid0.addWidget(self.dwelltime_label, 17, 0) - grid0.addWidget(self.dwelltime_entry, 17, 1) + self.grid0.addWidget(self.dwelltime_label, 17, 0) + self.grid0.addWidget(self.dwelltime_entry, 17, 1) # ########################################################################### # ############### ADVANCED UI form ########################################## # ########################################################################### - grid1 = QtWidgets.QGridLayout() - self.advanced_vlay.addLayout(grid1) - grid1.setColumnStretch(0, 0) - grid1.setColumnStretch(1, 1) + self.grid1 = QtWidgets.QGridLayout() + self.advanced_vlay.addLayout(self.grid1) + self.grid1.setColumnStretch(0, 0) + self.grid1.setColumnStretch(1, 1) + self.advanced_vlay.addStretch() # Tool Type self.type_label = QtWidgets.QLabel('%s:' % _("Tool Type")) @@ -1667,8 +1682,8 @@ class ToolsDB2(QtWidgets.QWidget): self.type_combo.addItems(["Iso", "Rough", "Finish"]) self.type_combo.setObjectName('gdb_type') - grid1.addWidget(self.type_label, 0, 0) - grid1.addWidget(self.type_combo, 0, 1) + self.grid1.addWidget(self.type_label, 0, 0) + self.grid1.addWidget(self.type_combo, 0, 1) # Tool Offset self.tooloffset_label = QtWidgets.QLabel('%s:' % _('Tool Offset')) @@ -1684,8 +1699,8 @@ class ToolsDB2(QtWidgets.QWidget): self.tooloffset_combo.addItems(["Path", "In", "Out", "Custom"]) self.tooloffset_combo.setObjectName('gdb_tool_offset') - grid1.addWidget(self.tooloffset_label, 2, 0) - grid1.addWidget(self.tooloffset_combo, 2, 1) + self.grid1.addWidget(self.tooloffset_label, 2, 0) + self.grid1.addWidget(self.tooloffset_combo, 2, 1) # Custom Offset self.custom_offset_label = QtWidgets.QLabel('%s:' % _("Custom Offset")) @@ -1698,8 +1713,8 @@ class ToolsDB2(QtWidgets.QWidget): self.custom_offset_entry.set_precision(self.decimals) self.custom_offset_entry.setObjectName('gdb_custom_offset') - grid1.addWidget(self.custom_offset_label, 5, 0) - grid1.addWidget(self.custom_offset_entry, 5, 1) + self.grid1.addWidget(self.custom_offset_label, 5, 0) + self.grid1.addWidget(self.custom_offset_entry, 5, 1) # V-Dia self.vdia_label = QtWidgets.QLabel('%s:' % _("V-Dia")) @@ -1712,8 +1727,8 @@ class ToolsDB2(QtWidgets.QWidget): self.vdia_entry.set_precision(self.decimals) self.vdia_entry.setObjectName('gdb_vdia') - grid1.addWidget(self.vdia_label, 7, 0) - grid1.addWidget(self.vdia_entry, 7, 1) + self.grid1.addWidget(self.vdia_label, 7, 0) + self.grid1.addWidget(self.vdia_entry, 7, 1) # V-Angle self.vangle_label = QtWidgets.QLabel('%s:' % _("V-Angle")) @@ -1726,8 +1741,8 @@ class ToolsDB2(QtWidgets.QWidget): self.vangle_entry.set_precision(self.decimals) self.vangle_entry.setObjectName('gdb_vangle') - grid1.addWidget(self.vangle_label, 8, 0) - grid1.addWidget(self.vangle_entry, 8, 1) + self.grid1.addWidget(self.vangle_label, 8, 0) + self.grid1.addWidget(self.vangle_entry, 8, 1) # Feedrate Rapids self.frapids_label = QtWidgets.QLabel('%s:' % _("FR Rapids")) @@ -1742,8 +1757,8 @@ class ToolsDB2(QtWidgets.QWidget): self.frapids_entry.set_precision(self.decimals) self.frapids_entry.setObjectName('gdb_frapids') - grid1.addWidget(self.frapids_label, 10, 0) - grid1.addWidget(self.frapids_entry, 10, 1) + self.grid1.addWidget(self.frapids_label, 10, 0) + self.grid1.addWidget(self.frapids_entry, 10, 1) # Extra Cut self.ecut_label = QtWidgets.QLabel('%s:' % _("ExtraCut")) @@ -1757,8 +1772,8 @@ class ToolsDB2(QtWidgets.QWidget): self.ecut_cb = FCCheckBox() self.ecut_cb.setObjectName('gdb_ecut') - grid1.addWidget(self.ecut_label, 12, 0) - grid1.addWidget(self.ecut_cb, 12, 1) + self.grid1.addWidget(self.ecut_label, 12, 0) + self.grid1.addWidget(self.ecut_cb, 12, 1) # Extra Cut Length self.ecut_length_label = QtWidgets.QLabel('%s:' % _("E-Cut Length")) @@ -1775,8 +1790,8 @@ class ToolsDB2(QtWidgets.QWidget): self.ecut_length_entry.set_precision(self.decimals) self.ecut_length_entry.setObjectName('gdb_ecut_length') - grid1.addWidget(self.ecut_length_label, 13, 0) - grid1.addWidget(self.ecut_length_entry, 13, 1) + self.grid1.addWidget(self.ecut_length_label, 13, 0) + self.grid1.addWidget(self.ecut_length_entry, 13, 1) # #################################################################### # #################################################################### @@ -1862,7 +1877,7 @@ class ToolsDB2(QtWidgets.QWidget): "depthperpass": self.multidepth_entry, "travelz": self.travelz_entry, "feedrate": self.frxy_entry, - "feedrate_z": self.frxy_entry, + "feedrate_z": self.frz_entry, "spindlespeed": self.spindle_entry, "dwell": self.dwell_cb, "dwelltime": self.dwelltime_entry, @@ -1904,6 +1919,8 @@ class ToolsDB2(QtWidgets.QWidget): "gdb_ecut_length": "extracut_length" } + self.current_toolid = None + # ############################################################################## # ######################## SIGNALS ############################################# # ############################################################################## @@ -1920,20 +1937,38 @@ class ToolsDB2(QtWidgets.QWidget): # self.tree_widget.selectionModel().selectionChanged.connect(self.on_list_selection_change) self.tree_widget.currentItemChanged.connect(self.on_list_selection_change) self.tree_widget.itemChanged.connect(self.on_list_item_edited) + self.tree_widget.customContextMenuRequested.connect(self.on_menu_request) self.setup_db_ui() + def on_menu_request(self, pos): + + menu = QtWidgets.QMenu() + add_tool = menu.addAction(QtGui.QIcon(self.app.resource_location + '/plus16.png'), _("Add to DB")) + add_tool.triggered.connect(self.on_tool_add) + + copy_tool = menu.addAction(QtGui.QIcon(self.app.resource_location + '/copy16.png'), _("Copy from DB")) + copy_tool.triggered.connect(self.on_tool_copy) + + delete_tool = menu.addAction(QtGui.QIcon(self.app.resource_location + '/delete32.png'), _("Delete from DB")) + delete_tool.triggered.connect(self.on_tool_delete) + + # tree_item = self.tree_widget.itemAt(pos) + menu.exec(self.tree_widget.viewport().mapToGlobal(pos)) + def on_list_selection_change(self, current, previous): # for idx in current.indexes(): # print(idx.data()) - print(current.text(0)) - self.table_widget.selectRow(int(current.text(0))-1) + # print(current.text(0)) + self.current_toolid = int(current.text(0)) + + self.storage_to_form(self.db_tool_dict[current.text(0)]) def on_list_item_edited(self, item, column): if column == 0: return - row = int(item.text(0)) - 1 - self.table_widget.item(row, 1).setText(item.text(1)) + + self.name_entry.set_value(item.text(1)) def storage_to_form(self, dict_storage): for form_key in self.form_fields: @@ -1941,8 +1976,15 @@ class ToolsDB2(QtWidgets.QWidget): if form_key == storage_key: try: self.form_fields[form_key].set_value(dict_storage[form_key]) - except Exception: - pass + except Exception as e: + print(str(e)) + if storage_key == 'data': + for data_key in dict_storage[storage_key]: + if form_key == data_key: + try: + self.form_fields[form_key].set_value(dict_storage['data'][data_key]) + except Exception as e: + print(str(e)) def form_to_storage(self, tool): self.blockSignals(True) @@ -1988,18 +2030,8 @@ class ToolsDB2(QtWidgets.QWidget): self.build_db_ui() - self.tree_widget.setupContextMenu() - self.tree_widget.addContextMenu( - _("Add to DB"), self.on_tool_add, icon=QtGui.QIcon(self.app.resource_location + "/plus16.png")) - self.tree_widget.addContextMenu( - _("Copy from DB"), self.on_tool_copy, icon=QtGui.QIcon(self.app.resource_location + "/copy16.png")) - self.tree_widget.addContextMenu( - _("Delete from DB"), self.on_tool_delete, icon=QtGui.QIcon(self.app.resource_location + "/delete32.png")) - def build_db_ui(self): self.ui_disconnect() - self.table_widget.setRowCount(len(self.db_tool_dict)) - nr_crt = 0 parent = self.tree_widget @@ -2013,7 +2045,7 @@ class ToolsDB2(QtWidgets.QWidget): t_name = dict_val['name'] try: - self.add_tool_table_line(row, name=t_name, widget=self.table_widget, tooldict=dict_val) + # self.add_tool_table_line(row, name=t_name, tooldict=dict_val) self.tree_widget.blockSignals(True) try: self.tree_widget.addParentEditable(parent=parent, title=[str(row+1), t_name], editable=True) @@ -2022,211 +2054,18 @@ class ToolsDB2(QtWidgets.QWidget): self.tree_widget.blockSignals(False) except Exception as e: self.app.log.debug("ToolDB.build_db_ui.add_tool_table_line() --> %s" % str(e)) - vertical_header = self.table_widget.verticalHeader() - vertical_header.hide() - horizontal_header = self.table_widget.horizontalHeader() - horizontal_header.setMinimumSectionSize(10) - horizontal_header.setDefaultSectionSize(70) - - self.table_widget.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents) - for x in range(27): - self.table_widget.resizeColumnToContents(x) - - horizontal_header.setSectionResizeMode(0, QtWidgets.QHeaderView.Fixed) - # horizontal_header.setSectionResizeMode(1, QtWidgets.QHeaderView.Stretch) - # horizontal_header.setSectionResizeMode(13, QtWidgets.QHeaderView.Fixed) - - horizontal_header.resizeSection(0, 20) - # horizontal_header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents) - # horizontal_header.setSectionResizeMode(2, QtWidgets.QHeaderView.Stretch) + if self.current_toolid is None or self.current_toolid < 1: + if self.db_tool_dict: + self.storage_to_form(self.db_tool_dict['1']) + else: + self.storage_to_form(self.db_tool_dict[str(self.current_toolid)]) self.ui_connect() - def add_tool_table_line(self, row, name, widget, tooldict): + def add_tool_table_line(self, row, name, tooldict): data = tooldict['data'] - nr_crt = row + 1 - id_item = QtWidgets.QTableWidgetItem('%d' % int(nr_crt)) - # id_item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - flags = id_item.flags() & ~QtCore.Qt.ItemIsEditable - id_item.setFlags(flags) - widget.setItem(row, 0, id_item) # Tool name/id - - tool_name_item = QtWidgets.QTableWidgetItem(name) - widget.setItem(row, 1, tool_name_item) - - dia_item = FCDoubleSpinner() - dia_item.set_precision(self.decimals) - dia_item.setSingleStep(0.1) - dia_item.set_range(0.0, 9999.9999) - dia_item.set_value(float(tooldict['tooldia'])) - widget.setCellWidget(row, 2, dia_item) - - tool_offset_item = FCComboBox() - for item in self.offset_item_options: - tool_offset_item.addItem(item) - tool_offset_item.set_value(tooldict['offset']) - widget.setCellWidget(row, 3, tool_offset_item) - - c_offset_item = FCDoubleSpinner() - c_offset_item.set_precision(self.decimals) - c_offset_item.setSingleStep(0.1) - c_offset_item.set_range(-9999.9999, 9999.9999) - c_offset_item.set_value(float(tooldict['offset_value'])) - widget.setCellWidget(row, 4, c_offset_item) - - tt_item = FCComboBox() - for item in self.type_item_options: - tt_item.addItem(item) - tt_item.set_value(tooldict['type']) - widget.setCellWidget(row, 5, tt_item) - - tshape_item = FCComboBox() - for item in self.tool_type_item_options: - tshape_item.addItem(item) - tshape_item.set_value(tooldict['tool_type']) - widget.setCellWidget(row, 6, tshape_item) - - cutz_item = FCDoubleSpinner() - cutz_item.set_precision(self.decimals) - cutz_item.setSingleStep(0.1) - if self.app.defaults['global_machinist_setting']: - cutz_item.set_range(-9999.9999, 9999.9999) - else: - cutz_item.set_range(-9999.9999, -0.0000) - - cutz_item.set_value(float(data['cutz'])) - widget.setCellWidget(row, 7, cutz_item) - - multidepth_item = FCCheckBox() - multidepth_item.set_value(data['multidepth']) - widget.setCellWidget(row, 8, multidepth_item) - - # to make the checkbox centered but it can no longer have it's value accessed - needs a fix using findchild() - # multidepth_item = QtWidgets.QWidget() - # cb = FCCheckBox() - # cb.set_value(data['multidepth']) - # qhboxlayout = QtWidgets.QHBoxLayout(multidepth_item) - # qhboxlayout.addWidget(cb) - # qhboxlayout.setAlignment(QtCore.Qt.AlignCenter) - # qhboxlayout.setContentsMargins(0, 0, 0, 0) - # widget.setCellWidget(row, 8, multidepth_item) - - depth_per_pass_item = FCDoubleSpinner() - depth_per_pass_item.set_precision(self.decimals) - depth_per_pass_item.setSingleStep(0.1) - depth_per_pass_item.set_range(0.0, 9999.9999) - depth_per_pass_item.set_value(float(data['depthperpass'])) - widget.setCellWidget(row, 9, depth_per_pass_item) - - vtip_dia_item = FCDoubleSpinner() - vtip_dia_item.set_precision(self.decimals) - vtip_dia_item.setSingleStep(0.1) - vtip_dia_item.set_range(0.0, 9999.9999) - vtip_dia_item.set_value(float(data['vtipdia'])) - widget.setCellWidget(row, 10, vtip_dia_item) - - vtip_angle_item = FCDoubleSpinner() - vtip_angle_item.set_precision(self.decimals) - vtip_angle_item.setSingleStep(0.1) - vtip_angle_item.set_range(-360.0, 360.0) - vtip_angle_item.set_value(float(data['vtipangle'])) - widget.setCellWidget(row, 11, vtip_angle_item) - - travelz_item = FCDoubleSpinner() - travelz_item.set_precision(self.decimals) - travelz_item.setSingleStep(0.1) - if self.app.defaults['global_machinist_setting']: - travelz_item.set_range(-9999.9999, 9999.9999) - else: - travelz_item.set_range(0.0000, 9999.9999) - - travelz_item.set_value(float(data['travelz'])) - widget.setCellWidget(row, 12, travelz_item) - - fr_item = FCDoubleSpinner() - fr_item.set_precision(self.decimals) - fr_item.set_range(0.0, 9999.9999) - fr_item.set_value(float(data['feedrate'])) - widget.setCellWidget(row, 13, fr_item) - - frz_item = FCDoubleSpinner() - frz_item.set_precision(self.decimals) - frz_item.set_range(0.0, 9999.9999) - frz_item.set_value(float(data['feedrate_z'])) - widget.setCellWidget(row, 14, frz_item) - - frrapids_item = FCDoubleSpinner() - frrapids_item.set_precision(self.decimals) - frrapids_item.set_range(0.0, 9999.9999) - frrapids_item.set_value(float(data['feedrate_rapid'])) - widget.setCellWidget(row, 15, frrapids_item) - - spindlespeed_item = FCSpinner() - spindlespeed_item.set_range(0, 1000000) - spindlespeed_item.set_value(int(data['spindlespeed'])) - spindlespeed_item.set_step(100) - widget.setCellWidget(row, 16, spindlespeed_item) - - dwell_item = FCCheckBox() - dwell_item.set_value(data['dwell']) - widget.setCellWidget(row, 17, dwell_item) - - dwelltime_item = FCDoubleSpinner() - dwelltime_item.set_precision(self.decimals) - dwelltime_item.set_range(0.0000, 9999.9999) - dwelltime_item.set_value(float(data['dwelltime'])) - widget.setCellWidget(row, 18, dwelltime_item) - - pp_item = FCComboBox() - for item in self.app.preprocessors: - pp_item.addItem(item) - pp_item.set_value(data['ppname_g']) - widget.setCellWidget(row, 19, pp_item) - - ecut_item = FCCheckBox() - ecut_item.set_value(data['extracut']) - widget.setCellWidget(row, 20, ecut_item) - - ecut_length_item = FCDoubleSpinner() - ecut_length_item.set_precision(self.decimals) - ecut_length_item.set_range(0.0000, 9999.9999) - ecut_length_item.set_value(data['extracut_length']) - widget.setCellWidget(row, 21, ecut_length_item) - - toolchange_item = FCCheckBox() - toolchange_item.set_value(data['toolchange']) - widget.setCellWidget(row, 22, toolchange_item) - - toolchangexy_item = QtWidgets.QTableWidgetItem(str(data['toolchangexy']) if data['toolchangexy'] else '') - widget.setItem(row, 23, toolchangexy_item) - - toolchangez_item = FCDoubleSpinner() - toolchangez_item.set_precision(self.decimals) - toolchangez_item.setSingleStep(0.1) - if self.app.defaults['global_machinist_setting']: - toolchangez_item.set_range(-9999.9999, 9999.9999) - else: - toolchangez_item.set_range(0.0000, 9999.9999) - - toolchangez_item.set_value(float(data['toolchangez'])) - widget.setCellWidget(row, 24, toolchangez_item) - - startz_item = QtWidgets.QTableWidgetItem(str(data['startz']) if data['startz'] else '') - widget.setItem(row, 25, startz_item) - - endz_item = FCDoubleSpinner() - endz_item.set_precision(self.decimals) - endz_item.setSingleStep(0.1) - if self.app.defaults['global_machinist_setting']: - endz_item.set_range(-9999.9999, 9999.9999) - else: - endz_item.set_range(0.0000, 9999.9999) - - endz_item.set_value(float(data['endz'])) - widget.setCellWidget(row, 26, endz_item) - def on_tool_add(self): """ Add a tool in the DB Tool Table @@ -2277,11 +2116,11 @@ class ToolsDB2(QtWidgets.QWidget): dict_elem['data'] = default_data new_toolid = len(self.db_tool_dict) + 1 - self.db_tool_dict[new_toolid] = deepcopy(dict_elem) + self.db_tool_dict[str(new_toolid)] = deepcopy(dict_elem) # add the new entry to the Tools DB table + self.update_storage() self.build_db_ui() - self.callback_on_edited() self.app.inform.emit('[success] %s' % _("Tool added to DB.")) def on_tool_copy(self): @@ -2289,20 +2128,23 @@ class ToolsDB2(QtWidgets.QWidget): Copy a selection of Tools in the Tools DB table :return: """ - new_tool_id = self.table_widget.rowCount() + 1 - for model_index in self.table_widget.selectionModel().selectedRows(): - # index = QtCore.QPersistentModelIndex(model_index) - old_tool_id = self.table_widget.item(model_index.row(), 0).text() - new_tool_id += 1 + new_tool_id = len(self.db_tool_dict) + for item in self.tree_widget.selectedItems(): + old_tool_id = item.data(0, QtCore.Qt.DisplayRole) for toolid, dict_val in list(self.db_tool_dict.items()): if int(old_tool_id) == int(toolid): + new_tool_id += 1 + new_key = str(new_tool_id) + self.db_tool_dict.update({ - new_tool_id: deepcopy(dict_val) + new_key: deepcopy(dict_val) }) + self.current_toolid = new_tool_id + + self.update_storage() self.build_db_ui() - self.callback_on_edited() self.app.inform.emit('[success] %s' % _("Tool copied from Tools DB.")) def on_tool_delete(self): @@ -2310,17 +2152,18 @@ class ToolsDB2(QtWidgets.QWidget): Delete a selection of Tools in the Tools DB table :return: """ - for model_index in self.table_widget.selectionModel().selectedRows(): - # index = QtCore.QPersistentModelIndex(model_index) - toolname_to_remove = self.table_widget.item(model_index.row(), 0).text() + for item in self.tree_widget.selectedItems(): + toolname_to_remove = item.data(0, QtCore.Qt.DisplayRole) for toolid, dict_val in list(self.db_tool_dict.items()): if int(toolname_to_remove) == int(toolid): # remove from the storage self.db_tool_dict.pop(toolid, None) + self.current_toolid -= 1 + + self.update_storage() self.build_db_ui() - self.callback_on_edited() self.app.inform.emit('[success] %s' % _("Tool removed from Tools DB.")) def on_export_tools_db_file(self): @@ -2408,7 +2251,7 @@ class ToolsDB2(QtWidgets.QWidget): self.app.inform.emit('[success] %s: %s' % (_("Loaded FlatCAM Tools DB from"), filename)) self.build_db_ui() - self.callback_on_edited() + self.update_storage() def on_save_tools_db(self, silent=False): self.app.log.debug("ToolsDB.on_save_button() --> Saving Tools Database to file.") @@ -2434,145 +2277,126 @@ class ToolsDB2(QtWidgets.QWidget): self.app.inform.emit('[success] %s' % _("Saved Tools DB.")) def ui_connect(self): - try: - try: - self.table_widget.itemChanged.disconnect(self.callback_on_edited) - except (TypeError, AttributeError): - pass - self.table_widget.itemChanged.connect(self.callback_on_edited) - except AttributeError: - pass + # make sure that we don't make multiple connections to the widgets + self.ui_disconnect() - for row in range(self.table_widget.rowCount()): - for col in range(self.table_widget.columnCount()): - # ComboBox - try: - try: - self.table_widget.cellWidget(row, col).currentIndexChanged.disconnect(self.callback_on_edited) - except (TypeError, AttributeError): - pass - self.table_widget.cellWidget(row, col).currentIndexChanged.connect(self.callback_on_edited) - except AttributeError: - pass + self.name_entry.editingFinished.connect(self.update_tree_name) - # CheckBox - try: - try: - self.table_widget.cellWidget(row, col).toggled.disconnect(self.callback_on_edited) - except (TypeError, AttributeError): - pass - self.table_widget.cellWidget(row, col).toggled.connect(self.callback_on_edited) - except AttributeError: - pass + for key in self.form_fields: + wdg = self.form_fields[key] - # SpinBox, DoubleSpinBox - try: - try: - self.table_widget.cellWidget(row, col).valueChanged.disconnect(self.callback_on_edited) - except (TypeError, AttributeError): - pass - self.table_widget.cellWidget(row, col).valueChanged.connect(self.callback_on_edited) - except AttributeError: - pass + # FCEntry + if isinstance(wdg, FCEntry): + wdg.textChanged.connect(self.update_storage) + + # ComboBox + if isinstance(wdg, FCComboBox): + wdg.currentIndexChanged.connect(self.update_storage) + + # CheckBox + if isinstance(wdg, FCCheckBox): + wdg.toggled.connect(self.update_storage) + + # SpinBox, DoubleSpinBox + if isinstance(wdg, FCSpinner) or isinstance(wdg, FCDoubleSpinner): + wdg.valueChanged.connect(self.update_storage) def ui_disconnect(self): try: - self.table_widget.itemChanged.disconnect(self.callback_on_edited) + self.name_entry.editingFinished.disconnect(self.update_tree_name) except (TypeError, AttributeError): pass - for row in range(self.table_widget.rowCount()): - for col in range(self.table_widget.columnCount()): - # ComboBox + for key in self.form_fields: + wdg = self.form_fields[key] + + # FCEntry + if isinstance(wdg, FCEntry): try: - self.table_widget.cellWidget(row, col).currentIndexChanged.disconnect(self.callback_on_edited) + wdg.textChanged.disconnect(self.update_storage) except (TypeError, AttributeError): pass - # CheckBox + # ComboBox + if isinstance(wdg, FCComboBox): try: - self.table_widget.cellWidget(row, col).toggled.disconnect(self.callback_on_edited) + wdg.currentIndexChanged.disconnect(self.update_storage) except (TypeError, AttributeError): pass - # SpinBox, DoubleSpinBox + # CheckBox + if isinstance(wdg, FCCheckBox): try: - self.table_widget.cellWidget(row, col).valueChanged.disconnect(self.callback_on_edited) + wdg.toggled.disconnect(self.update_storage) except (TypeError, AttributeError): pass - def callback_on_edited(self): + # SpinBox, DoubleSpinBox + if isinstance(wdg, FCSpinner) or isinstance(wdg, FCDoubleSpinner): + try: + wdg.valueChanged.disconnect(self.update_storage) + except (TypeError, AttributeError): + pass - # update the dictionary storage self.db_tool_dict - self.db_tool_dict.clear() - dict_elem = {} - default_data = {} + def update_tree_name(self): + val = self.name_entry.get_value() - for row in range(self.table_widget.rowCount()): - new_toolid = row + 1 - for col in range(self.table_widget.columnCount()): - column_header_text = self.table_widget.horizontalHeaderItem(col).text() - if column_header_text == _('Tool Name'): - dict_elem['name'] = self.table_widget.item(row, col).text() - elif column_header_text == _('Tool Dia'): - dict_elem['tooldia'] = self.table_widget.cellWidget(row, col).get_value() - elif column_header_text == _('Tool Offset'): - dict_elem['offset'] = self.table_widget.cellWidget(row, col).get_value() - elif column_header_text == _('Custom Offset'): - dict_elem['offset_value'] = self.table_widget.cellWidget(row, col).get_value() - elif column_header_text == _('Tool Type'): - dict_elem['type'] = self.table_widget.cellWidget(row, col).get_value() - elif column_header_text == _('Tool Shape'): - dict_elem['tool_type'] = self.table_widget.cellWidget(row, col).get_value() - else: - if column_header_text == _('Cut Z'): - default_data['cutz'] = self.table_widget.cellWidget(row, col).get_value() - elif column_header_text == _('MultiDepth'): - default_data['multidepth'] = self.table_widget.cellWidget(row, col).get_value() - elif column_header_text == _('DPP'): - default_data['depthperpass'] = self.table_widget.cellWidget(row, col).get_value() - elif column_header_text == _('V-Dia'): - default_data['vtipdia'] = self.table_widget.cellWidget(row, col).get_value() - elif column_header_text == _('V-Angle'): - default_data['vtipangle'] = self.table_widget.cellWidget(row, col).get_value() - elif column_header_text == _('Travel Z'): - default_data['travelz'] = self.table_widget.cellWidget(row, col).get_value() - elif column_header_text == _('FR'): - default_data['feedrate'] = self.table_widget.cellWidget(row, col).get_value() - elif column_header_text == _('FR Z'): - default_data['feedrate_z'] = self.table_widget.cellWidget(row, col).get_value() - elif column_header_text == _('FR Rapids'): - default_data['feedrate_rapid'] = self.table_widget.cellWidget(row, col).get_value() - elif column_header_text == _('Spindle Speed'): - default_data['spindlespeed'] = self.table_widget.cellWidget(row, col).get_value() - elif column_header_text == _('Dwell'): - default_data['dwell'] = self.table_widget.cellWidget(row, col).get_value() - elif column_header_text == _('Dwelltime'): - default_data['dwelltime'] = self.table_widget.cellWidget(row, col).get_value() - elif column_header_text == _('Preprocessor'): - default_data['ppname_g'] = self.table_widget.cellWidget(row, col).get_value() - elif column_header_text == _('ExtraCut'): - default_data['extracut'] = self.table_widget.cellWidget(row, col).get_value() - elif column_header_text == _("E-Cut Length"): - default_data['extracut_length'] = self.table_widget.cellWidget(row, col).get_value() - elif column_header_text == _('Toolchange'): - default_data['toolchange'] = self.table_widget.cellWidget(row, col).get_value() - elif column_header_text == _('Toolchange XY'): - default_data['toolchangexy'] = self.table_widget.item(row, col).text() - elif column_header_text == _('Toolchange Z'): - default_data['toolchangez'] = self.table_widget.cellWidget(row, col).get_value() - elif column_header_text == _('Start Z'): - default_data['startz'] = float(self.table_widget.item(row, col).text()) \ - if self.table_widget.item(row, col).text() is not '' else None - elif column_header_text == _('End Z'): - default_data['endz'] = self.table_widget.cellWidget(row, col).get_value() + item = self.tree_widget.currentItem() + # I'm setting the value for the second column (designated by 1) because first column holds the ID + # and second column holds the Name (this behavior is set in the build_ui method) + item.setData(1, QtCore.Qt.DisplayRole, val) - dict_elem['data'] = default_data - self.db_tool_dict.update( - { - new_toolid: deepcopy(dict_elem) - } - ) + def update_storage(self): + + tool_id = str(self.current_toolid) + wdg = self.sender() + if wdg is None: + return + wdg_name = wdg.objectName() + + if wdg_name == "gdb_name": + self.db_tool_dict[tool_id]['name'] = wdg.get_value() + elif wdg_name == "gdb_dia": + self.db_tool_dict[tool_id]['tooldia'] = wdg.get_value() + elif wdg_name == "gdb_tool_offset": + self.db_tool_dict[tool_id]['offset'] = wdg.get_value() + elif wdg_name == "gdb_custom_offset": + self.db_tool_dict[tool_id]['offset_value'] = wdg.get_value() + elif wdg_name == "gdb_type": + self.db_tool_dict[tool_id]['type'] = wdg.get_value() + elif wdg_name == "gdb_shape": + self.db_tool_dict[tool_id]['tool_type'] = wdg.get_value() + else: + if wdg_name == "gdb_cutz": + self.db_tool_dict[tool_id]['data']['cutz'] = wdg.get_value() + elif wdg_name == "gdb_multidepth": + self.db_tool_dict[tool_id]['data']['multidepth'] = wdg.get_value() + elif wdg_name == "gdb_multidepth_entry": + self.db_tool_dict[tool_id]['data']['depthperpass'] = wdg.get_value() + + elif wdg_name == "gdb_travel": + self.db_tool_dict[tool_id]['data']['travelz'] = wdg.get_value() + elif wdg_name == "gdb_frxy": + self.db_tool_dict[tool_id]['data']['feedrate'] = wdg.get_value() + elif wdg_name == "gdb_frz": + self.db_tool_dict[tool_id]['data']['feedrate_z'] = wdg.get_value() + elif wdg_name == "gdb_spindle": + self.db_tool_dict[tool_id]['data']['spindlespeed'] = wdg.get_value() + elif wdg_name == "gdb_dwell": + self.db_tool_dict[tool_id]['data']['dwell'] = wdg.get_value() + elif wdg_name == "gdb_dwelltime": + self.db_tool_dict[tool_id]['data']['dwelltime'] = wdg.get_value() + + elif wdg_name == "gdb_vdia": + self.db_tool_dict[tool_id]['data']['vtipdia'] = wdg.get_value() + elif wdg_name == "gdb_vangle": + self.db_tool_dict[tool_id]['data']['vtipangle'] = wdg.get_value() + elif wdg_name == "gdb_frapids": + self.db_tool_dict[tool_id]['data']['feedrate_rapid'] = wdg.get_value() + elif wdg_name == "gdb_ecut": + self.db_tool_dict[tool_id]['data']['extracut'] = wdg.get_value() + elif wdg_name == "gdb_ecut_length": + self.db_tool_dict[tool_id]['data']['extracut_length'] = wdg.get_value() self.callback_app() diff --git a/README.md b/README.md index 7ace08cb..0137a92f 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +28.03.2020 + +- finished the new database based on a QTreeWidget + 21.03.2020 - fixed Cutout Tool to work with negative values for Margin parameter diff --git a/requirements.txt b/requirements.txt index 6e58e3f7..ee962276 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ # This file contains python only requirements to be installed with pip # Python packages that cannot be installed with pip (e.g. PyQt5, GDAL) are not included. # Usage: pip3 install -r requirements.txt -pyqt5==5.12 +pyqt5==5.12.1 numpy>=1.16 matplotlib>=3.1 cycler>=0.10 From 1ca650e883fc31956a2b76301a5d20f23647acc3 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 29 Mar 2020 14:22:11 +0300 Subject: [PATCH 135/209] - modified the new database to accept data from NCC and Paint Tools --- FlatCAMApp.py | 18 +- FlatCAMCommon.py | 411 ++++++++++++++++++++++++++++++++++---- README.md | 4 + flatcamGUI/GUIElements.py | 13 ++ 4 files changed, 402 insertions(+), 44 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 0564f774..0306632b 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -140,7 +140,7 @@ class App(QtCore.QObject): # ################## Version and VERSION DATE ############################## # ########################################################################## version = 8.992 - version_date = "2020/02/22" + version_date = "2020/03/27" beta = True engine = '3D' @@ -353,14 +353,14 @@ class App(QtCore.QObject): f.close() # create fctool_tools_db.FlatDB file if there is none - try: - f = open(self.data_path + '/fctool_tools_db.FlatDB') - f.close() - except IOError: - App.log.debug('Creating empty fctool_tool_db.FlatDB') - f = open(self.data_path + '/fctool_tools_db.FlatDB', 'w') - json.dump({}, f) - f.close() + # try: + # f = open(self.data_path + '/fctool_tools_db.FlatDB') + # f.close() + # except IOError: + # App.log.debug('Creating empty fctool_tool_db.FlatDB') + # f = open(self.data_path + '/fctool_tools_db.FlatDB', 'w') + # json.dump({}, f) + # f.close() # create current_defaults.FlatConfig file if there is none try: diff --git a/FlatCAMCommon.py b/FlatCAMCommon.py index 644f7ca4..f80106e3 100644 --- a/FlatCAMCommon.py +++ b/FlatCAMCommon.py @@ -1459,8 +1459,8 @@ class ToolsDB2(QtWidgets.QWidget): } """) self.basic_vlay = QtWidgets.QVBoxLayout() - self.basic_box.setTitle(_("Basic Parameters")) - self.basic_box.setMinimumWidth(250) + self.basic_box.setTitle(_("Basic Geo Parameters")) + self.basic_box.setFixedWidth(250) self.advanced_box = QtWidgets.QGroupBox() self.advanced_box.setStyleSheet(""" @@ -1471,14 +1471,50 @@ class ToolsDB2(QtWidgets.QWidget): } """) self.advanced_vlay = QtWidgets.QVBoxLayout() - self.advanced_box.setTitle(_("Advanced Parameters")) - self.advanced_box.setMinimumWidth(250) + self.advanced_box.setTitle(_("Advanced Geo Parameters")) + self.advanced_box.setFixedWidth(250) + + self.ncc_box = QtWidgets.QGroupBox() + self.ncc_box.setStyleSheet(""" + QGroupBox + { + font-size: 16px; + font-weight: bold; + } + """) + self.ncc_vlay = QtWidgets.QVBoxLayout() + self.ncc_box.setTitle(_("NCC Parameters")) + self.ncc_box.setFixedWidth(250) + + self.paint_box = QtWidgets.QGroupBox() + self.paint_box.setStyleSheet(""" + QGroupBox + { + font-size: 16px; + font-weight: bold; + } + """) + self.paint_vlay = QtWidgets.QVBoxLayout() + self.paint_box.setTitle(_("Paint Parameters")) + self.paint_box.setFixedWidth(250) self.basic_box.setLayout(self.basic_vlay) self.advanced_box.setLayout(self.advanced_vlay) + self.ncc_box.setLayout(self.ncc_vlay) + self.paint_box.setLayout(self.paint_vlay) - param_hlay.addWidget(self.basic_box) - param_hlay.addWidget(self.advanced_box) + geo_vlay = QtWidgets.QVBoxLayout() + geo_vlay.addWidget(self.basic_box) + geo_vlay.addWidget(self.advanced_box) + geo_vlay.addStretch() + + tools_vlay = QtWidgets.QVBoxLayout() + tools_vlay.addWidget(self.ncc_box) + tools_vlay.addWidget(self.paint_box) + tools_vlay.addStretch() + + param_hlay.addLayout(geo_vlay) + param_hlay.addLayout(tools_vlay) param_hlay.addStretch() # ########################################################################### @@ -1492,7 +1528,7 @@ class ToolsDB2(QtWidgets.QWidget): self.basic_vlay.addStretch() # Tool Name - self.name_label = QtWidgets.QLabel('%s:' % _('Tool Name')) + self.name_label = QtWidgets.QLabel('%s:' % _('Tool Name')) self.name_label.setToolTip( _("Tool name.\n" "This is not used in the app, it's function\n" @@ -1731,7 +1767,7 @@ class ToolsDB2(QtWidgets.QWidget): self.grid1.addWidget(self.vdia_entry, 7, 1) # V-Angle - self.vangle_label = QtWidgets.QLabel('%s:' % _("V-Angle")) + self.vangle_label = QtWidgets.QLabel('%s:' % _("V-Angle")) self.vangle_label.setToolTip( _("V-Agle.\n" "Angle at the tip for the V-Shape Tools.")) @@ -1745,7 +1781,7 @@ class ToolsDB2(QtWidgets.QWidget): self.grid1.addWidget(self.vangle_entry, 8, 1) # Feedrate Rapids - self.frapids_label = QtWidgets.QLabel('%s:' % _("FR Rapids")) + self.frapids_label = QtWidgets.QLabel('%s:' % _("FR Rapids")) self.frapids_label.setToolTip( _("FR Rapids. Feedrate Rapids\n" "Speed used while moving as fast as possible.\n" @@ -1793,6 +1829,245 @@ class ToolsDB2(QtWidgets.QWidget): self.grid1.addWidget(self.ecut_length_label, 13, 0) self.grid1.addWidget(self.ecut_length_entry, 13, 1) + # ########################################################################### + # ############### NCC UI form ############################################### + # ########################################################################### + + self.grid2 = QtWidgets.QGridLayout() + self.ncc_vlay.addLayout(self.grid2) + self.grid2.setColumnStretch(0, 0) + self.grid2.setColumnStretch(1, 1) + self.ncc_vlay.addStretch() + + # Operation + op_label = QtWidgets.QLabel('%s:' % _('Operation')) + op_label.setToolTip( + _("The 'Operation' can be:\n" + "- Isolation -> will ensure that the non-copper clearing is always complete.\n" + "If it's not successful then the non-copper clearing will fail, too.\n" + "- Clear -> the regular non-copper clearing.") + ) + + self.op_radio = RadioSet([ + {"label": _("Clear"), "value": "clear"}, + {"label": _("Isolation"), "value": "iso"} + ], orientation='horizontal', stretch=False) + self.op_radio.setObjectName("gdb_n_operation") + + self.grid2.addWidget(op_label, 13, 0) + self.grid2.addWidget(self.op_radio, 13, 1) + + # Milling Type Radio Button + self.milling_type_label = QtWidgets.QLabel('%s:' % _('Milling Type')) + self.milling_type_label.setToolTip( + _("Milling type when the selected tool is of type: 'iso_op':\n" + "- climb / best for precision milling and to reduce tool usage\n" + "- conventional / useful when there is no backlash compensation") + ) + + self.milling_type_radio = RadioSet([{'label': _('Climb'), 'value': 'cl'}, + {'label': _('Conventional'), 'value': 'cv'}]) + self.milling_type_radio.setToolTip( + _("Milling type when the selected tool is of type: 'iso_op':\n" + "- climb / best for precision milling and to reduce tool usage\n" + "- conventional / useful when there is no backlash compensation") + ) + self.milling_type_radio.setObjectName("gdb_n_milling_type") + + self.milling_type_label.setEnabled(False) + self.milling_type_radio.setEnabled(False) + + self.grid2.addWidget(self.milling_type_label, 14, 0) + self.grid2.addWidget(self.milling_type_radio, 14, 1) + + # Overlap Entry + nccoverlabel = QtWidgets.QLabel('%s:' % _('Overlap')) + nccoverlabel.setToolTip( + _("How much (percentage) of the tool width to overlap each tool pass.\n" + "Adjust the value starting with lower values\n" + "and increasing it if areas that should be cleared are still \n" + "not cleared.\n" + "Lower values = faster processing, faster execution on CNC.\n" + "Higher values = slow processing and slow execution on CNC\n" + "due of too many paths.") + ) + self.ncc_overlap_entry = FCDoubleSpinner(suffix='%') + self.ncc_overlap_entry.set_precision(self.decimals) + self.ncc_overlap_entry.setWrapping(True) + self.ncc_overlap_entry.setRange(0.000, 99.9999) + self.ncc_overlap_entry.setSingleStep(0.1) + self.ncc_overlap_entry.setObjectName("gdb_n_overlap") + + self.grid2.addWidget(nccoverlabel, 15, 0) + self.grid2.addWidget(self.ncc_overlap_entry, 15, 1) + + # Margin + nccmarginlabel = QtWidgets.QLabel('%s:' % _('Margin')) + nccmarginlabel.setToolTip( + _("Bounding box margin.") + ) + self.ncc_margin_entry = FCDoubleSpinner() + self.ncc_margin_entry.set_precision(self.decimals) + self.ncc_margin_entry.set_range(-9999.9999, 9999.9999) + self.ncc_margin_entry.setObjectName("gdb_n_margin") + + self.grid2.addWidget(nccmarginlabel, 16, 0) + self.grid2.addWidget(self.ncc_margin_entry, 16, 1) + + # Method + methodlabel = QtWidgets.QLabel('%s:' % _('Method')) + methodlabel.setToolTip( + _("Algorithm for copper clearing:\n" + "- Standard: Fixed step inwards.\n" + "- Seed-based: Outwards from seed.\n" + "- Line-based: Parallel lines.") + ) + + self.ncc_method_combo = FCComboBox() + self.ncc_method_combo.addItems( + [_("Standard"), _("Seed"), _("Lines")] + ) + self.ncc_method_combo.setObjectName("gdb_n_method") + + self.grid2.addWidget(methodlabel, 17, 0) + self.grid2.addWidget(self.ncc_method_combo, 17, 1) + + # Connect lines + self.ncc_connect_cb = FCCheckBox('%s' % _("Connect")) + self.ncc_connect_cb.setObjectName("gdb_n_connect") + + self.ncc_connect_cb.setToolTip( + _("Draw lines between resulting\n" + "segments to minimize tool lifts.") + ) + self.grid2.addWidget(self.ncc_connect_cb, 18, 0) + + # Contour + self.ncc_contour_cb = FCCheckBox('%s' % _("Contour")) + self.ncc_contour_cb.setObjectName("gdb_n_contour") + + self.ncc_contour_cb.setToolTip( + _("Cut around the perimeter of the polygon\n" + "to trim rough edges.") + ) + self.grid2.addWidget(self.ncc_contour_cb, 18, 1) + + # ## NCC Offset choice + self.ncc_choice_offset_cb = FCCheckBox('%s' % _("Offset")) + self.ncc_choice_offset_cb.setObjectName("gdb_n_offset") + + self.ncc_choice_offset_cb.setToolTip( + _("If used, it will add an offset to the copper features.\n" + "The copper clearing will finish to a distance\n" + "from the copper features.\n" + "The value can be between 0 and 10 FlatCAM units.") + ) + self.grid2.addWidget(self.ncc_choice_offset_cb, 19, 0) + + # ## NCC Offset Entry + self.ncc_offset_spinner = FCDoubleSpinner() + self.ncc_offset_spinner.set_range(0.00, 10.00) + self.ncc_offset_spinner.set_precision(4) + self.ncc_offset_spinner.setWrapping(True) + self.ncc_offset_spinner.setObjectName("gdb_n_offset_value") + + units = self.app.defaults['units'].upper() + if units == 'MM': + self.ncc_offset_spinner.setSingleStep(0.1) + else: + self.ncc_offset_spinner.setSingleStep(0.01) + + self.grid2.addWidget(self.ncc_offset_spinner, 19, 1) + + # ########################################################################### + # ############### Paint UI form ############################################# + # ########################################################################### + + self.grid3 = QtWidgets.QGridLayout() + self.paint_vlay.addLayout(self.grid3) + self.grid3.setColumnStretch(0, 0) + self.grid3.setColumnStretch(1, 1) + self.paint_vlay.addStretch() + + # Overlap + ovlabel = QtWidgets.QLabel('%s:' % _('Overlap')) + ovlabel.setToolTip( + _("How much (percentage) of the tool width to overlap each tool pass.\n" + "Adjust the value starting with lower values\n" + "and increasing it if areas that should be painted are still \n" + "not painted.\n" + "Lower values = faster processing, faster execution on CNC.\n" + "Higher values = slow processing and slow execution on CNC\n" + "due of too many paths.") + ) + self.paintoverlap_entry = FCDoubleSpinner(suffix='%') + self.paintoverlap_entry.set_precision(3) + self.paintoverlap_entry.setWrapping(True) + self.paintoverlap_entry.setRange(0.0000, 99.9999) + self.paintoverlap_entry.setSingleStep(0.1) + self.paintoverlap_entry.setObjectName('gdb_p_overlap') + + self.grid3.addWidget(ovlabel, 1, 0) + self.grid3.addWidget(self.paintoverlap_entry, 1, 1) + + # Margin + marginlabel = QtWidgets.QLabel('%s:' % _('Margin')) + marginlabel.setToolTip( + _("Distance by which to avoid\n" + "the edges of the polygon to\n" + "be painted.") + ) + self.paintmargin_entry = FCDoubleSpinner() + self.paintmargin_entry.set_precision(self.decimals) + self.paintmargin_entry.set_range(-9999.9999, 9999.9999) + self.paintmargin_entry.setObjectName('gdb_p_margin') + + self.grid3.addWidget(marginlabel, 2, 0) + self.grid3.addWidget(self.paintmargin_entry, 2, 1) + + # Method + methodlabel = QtWidgets.QLabel('%s:' % _('Method')) + methodlabel.setToolTip( + _("Algorithm for painting:\n" + "- Standard: Fixed step inwards.\n" + "- Seed-based: Outwards from seed.\n" + "- Line-based: Parallel lines.\n" + "- Laser-lines: Active only for Gerber objects.\n" + "Will create lines that follow the traces.\n" + "- Combo: In case of failure a new method will be picked from the above\n" + "in the order specified.") + ) + + self.paintmethod_combo = FCComboBox() + self.paintmethod_combo.addItems( + [_("Standard"), _("Seed"), _("Lines"), _("Laser_lines"), _("Combo")] + ) + idx = self.paintmethod_combo.findText(_("Laser_lines")) + self.paintmethod_combo.model().item(idx).setEnabled(False) + + self.paintmethod_combo.setObjectName('gdb_p_method') + + self.grid3.addWidget(methodlabel, 7, 0) + self.grid3.addWidget(self.paintmethod_combo, 7, 1) + + # Connect lines + self.pathconnect_cb = FCCheckBox('%s' % _("Connect")) + self.pathconnect_cb.setObjectName('gdb_p_connect') + self.pathconnect_cb.setToolTip( + _("Draw lines between resulting\n" + "segments to minimize tool lifts.") + ) + + self.paintcontour_cb = FCCheckBox('%s' % _("Contour")) + self.paintcontour_cb.setObjectName('gdb_p_contour') + self.paintcontour_cb.setToolTip( + _("Cut around the perimeter of the polygon\n" + "to trim rough edges.") + ) + + self.grid3.addWidget(self.pathconnect_cb, 10, 0) + self.grid3.addWidget(self.paintcontour_cb, 10, 1) + # #################################################################### # #################################################################### # GUI for the lower part of the window @@ -1890,7 +2165,25 @@ class ToolsDB2(QtWidgets.QWidget): "vtipangle": self.vangle_entry, "feedrate_rapid": self.frapids_entry, "extracut": self.ecut_cb, - "extracut_length": self.ecut_length_entry + "extracut_length": self.ecut_length_entry, + + # NCC + "tools_nccoperation": self.op_radio, + "tools_nccmilling_type": self.milling_type_radio, + "tools_nccoverlap": self.ncc_overlap_entry, + "tools_nccmargin": self.ncc_margin_entry, + "tools_nccmethod": self.ncc_method_combo, + "tools_nccconnect": self.ncc_connect_cb, + "tools_ncccontour": self.ncc_contour_cb, + "tools_ncc_offset_choice": self.ncc_choice_offset_cb, + "tools_ncc_offset_value": self.ncc_offset_spinner, + + # Paint + "paintoverlap": self.paintoverlap_entry, + "paintmargin": self.paintmargin_entry, + "paintmethod": self.paintmethod_combo, + "pathconnect": self.pathconnect_cb, + "paintcontour": self.paintcontour_cb, } self.name2option = { @@ -1916,7 +2209,25 @@ class ToolsDB2(QtWidgets.QWidget): "gdb_vangle": "vtipangle", "gdb_frapids": "feedrate_rapid", "gdb_ecut": "extracut", - "gdb_ecut_length": "extracut_length" + "gdb_ecut_length": "extracut_length", + + # NCC + "gdb_n_operation": "nccoperation", + "gdb_n_overlap": "nccoverlap", + "gdb_n_margin": "nccmargin", + "gdb_n_method": "nccmethod", + "gdb_n_connect": "nccconnect", + "gdb_n_contour": "ncccontour", + "gdb_n_offset": "nccoffset", + "gdb_n_offset_value": "nccoffset_value", + "gdb_n_milling_type": "milling_type", + + # Paint + 'gdb_p_overlap': "paintoverlap", + 'gdb_p_margin': "paintmargin", + 'gdb_p_method': "paintmethod", + 'gdb_p_connect': "pathconnect", + 'gdb_p_contour': "paintcontour", } self.current_toolid = None @@ -1993,7 +2304,6 @@ class ToolsDB2(QtWidgets.QWidget): wdg_objname = widget_changed.objectName() option_changed = self.name2option[wdg_objname] - tooluid_item = int(tool) for tooluid_key, tooluid_val in self.db_tool_dict.items(): @@ -2058,14 +2368,27 @@ class ToolsDB2(QtWidgets.QWidget): if self.current_toolid is None or self.current_toolid < 1: if self.db_tool_dict: self.storage_to_form(self.db_tool_dict['1']) + + # Enable GUI + self.basic_box.setEnabled(True) + self.advanced_box.setEnabled(True) + self.ncc_box.setEnabled(True) + self.paint_box.setEnabled(True) + + self.tree_widget.setCurrentItem(self.tree_widget.topLevelItem(0)) + self.tree_widget.setFocus() + + else: + # Disable GUI + self.basic_box.setEnabled(False) + self.advanced_box.setEnabled(False) + self.ncc_box.setEnabled(False) + self.paint_box.setEnabled(False) else: self.storage_to_form(self.db_tool_dict[str(self.current_toolid)]) self.ui_connect() - def add_tool_table_line(self, row, name, tooldict): - data = tooldict['data'] - def on_tool_add(self): """ Add a tool in the DB Tool Table @@ -2074,26 +2397,44 @@ class ToolsDB2(QtWidgets.QWidget): default_data = {} default_data.update({ - "cutz": float(self.app.defaults["geometry_cutz"]), - "multidepth": self.app.defaults["geometry_multidepth"], - "depthperpass": float(self.app.defaults["geometry_depthperpass"]), - "vtipdia": float(self.app.defaults["geometry_vtipdia"]), - "vtipangle": float(self.app.defaults["geometry_vtipangle"]), - "travelz": float(self.app.defaults["geometry_travelz"]), - "feedrate": float(self.app.defaults["geometry_feedrate"]), - "feedrate_z": float(self.app.defaults["geometry_feedrate_z"]), - "feedrate_rapid": float(self.app.defaults["geometry_feedrate_rapid"]), - "spindlespeed": self.app.defaults["geometry_spindlespeed"], - "dwell": self.app.defaults["geometry_dwell"], - "dwelltime": float(self.app.defaults["geometry_dwelltime"]), - "ppname_g": self.app.defaults["geometry_ppname_g"], - "extracut": self.app.defaults["geometry_extracut"], - "extracut_length": float(self.app.defaults["geometry_extracut_length"]), - "toolchange": self.app.defaults["geometry_toolchange"], - "toolchangexy": self.app.defaults["geometry_toolchangexy"], - "toolchangez": float(self.app.defaults["geometry_toolchangez"]), - "startz": self.app.defaults["geometry_startz"], - "endz": float(self.app.defaults["geometry_endz"]) + "cutz": float(self.app.defaults["geometry_cutz"]), + "multidepth": self.app.defaults["geometry_multidepth"], + "depthperpass": float(self.app.defaults["geometry_depthperpass"]), + "vtipdia": float(self.app.defaults["geometry_vtipdia"]), + "vtipangle": float(self.app.defaults["geometry_vtipangle"]), + "travelz": float(self.app.defaults["geometry_travelz"]), + "feedrate": float(self.app.defaults["geometry_feedrate"]), + "feedrate_z": float(self.app.defaults["geometry_feedrate_z"]), + "feedrate_rapid": float(self.app.defaults["geometry_feedrate_rapid"]), + "spindlespeed": self.app.defaults["geometry_spindlespeed"], + "dwell": self.app.defaults["geometry_dwell"], + "dwelltime": float(self.app.defaults["geometry_dwelltime"]), + "ppname_g": self.app.defaults["geometry_ppname_g"], + "extracut": self.app.defaults["geometry_extracut"], + "extracut_length": float(self.app.defaults["geometry_extracut_length"]), + "toolchange": self.app.defaults["geometry_toolchange"], + "toolchangexy": self.app.defaults["geometry_toolchangexy"], + "toolchangez": float(self.app.defaults["geometry_toolchangez"]), + "startz": self.app.defaults["geometry_startz"], + "endz": float(self.app.defaults["geometry_endz"]), + + # NCC + "tools_nccoperation": self.app.defaults["tools_nccoperation"], + "tools_nccmilling_type": self.app.defaults["tools_nccmilling_type"], + "tools_nccoverlap": float(self.app.defaults["tools_nccoverlap"]), + "tools_nccmargin": float(self.app.defaults["tools_nccmargin"]), + "tools_nccmethod": self.app.defaults["tools_nccmethod"], + "tools_nccconnect": self.app.defaults["tools_nccconnect"], + "tools_ncccontour": self.app.defaults["tools_ncccontour"], + "tools_ncc_offset_choice": self.app.defaults["tools_ncc_offset_choice"], + "tools_ncc_offset_value": float(self.app.defaults["tools_ncc_offset_value"]), + + # Paint + "paintoverlap": float(self.app.defaults["tools_paintoverlap"]), + "paintmargin": float(self.app.defaults["tools_paintmargin"]), + "paintmethod": self.app.defaults["tools_paintmethod"], + "pathconnect": self.app.defaults["tools_pathconnect"], + "paintcontour": self.app.defaults["tools_paintcontour"], }) dict_elem = {} diff --git a/README.md b/README.md index 0137a92f..bc228160 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +29.03.2020 + +- modified the new database to accept data from NCC and Paint Tools + 28.03.2020 - finished the new database based on a QTreeWidget diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index fbfd739e..c9fdc607 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -163,9 +163,20 @@ class FCTree(QtWidgets.QTreeWidget): self.header().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents) self.setSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Expanding) + palette = QtGui.QPalette() + palette.setColor(QtGui.QPalette.Inactive, QtGui.QPalette.Highlight, + palette.color(QtGui.QPalette.Active, QtGui.QPalette.Highlight)) + + # make inactive rows text some color as active; may be useful in the future + # palette.setColor(QtGui.QPalette.Inactive, QtGui.QPalette.HighlightedText, + # palette.color(QtGui.QPalette.Active, QtGui.QPalette.HighlightedText)) + self.setPalette(palette) + if extended_sel: self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) + self.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) + self.protected_column = protected_column self.itemDoubleClicked.connect(self.on_double_click) self.header().sectionDoubleClicked.connect(self.on_header_double_click) @@ -210,6 +221,8 @@ class FCTree(QtWidgets.QTreeWidget): if editable: item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable) + item.setFlags(item.flags() | QtCore.Qt.ItemIsSelectable) + for t in range(len(title)): item.setText(t, title[t]) From e8adcb0c10e00557f88da6eb1ae2064a364b151c Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 29 Mar 2020 15:07:18 +0300 Subject: [PATCH 136/209] - fixed issues in the new database when adding the tool in a Geometry object --- FlatCAMCommon.py | 165 ++++++++++++++++++++++++++++++----------------- README.md | 1 + 2 files changed, 108 insertions(+), 58 deletions(-) diff --git a/FlatCAMCommon.py b/FlatCAMCommon.py index f80106e3..c0cb24db 100644 --- a/FlatCAMCommon.py +++ b/FlatCAMCommon.py @@ -1632,7 +1632,7 @@ class ToolsDB2(QtWidgets.QWidget): "The speed on XY plane used while cutting into material.")) self.frxy_entry = FCDoubleSpinner() - self.frxy_entry.set_range(-9999.9999, 9999.9999) + self.frxy_entry.set_range(-999999.9999, 999999.9999) self.frxy_entry.set_precision(self.decimals) self.frxy_entry.setObjectName('gdb_frxy') @@ -1646,7 +1646,7 @@ class ToolsDB2(QtWidgets.QWidget): "The speed on Z plane.")) self.frz_entry = FCDoubleSpinner() - self.frz_entry.set_range(-9999.9999, 9999.9999) + self.frz_entry.set_range(-999999.9999, 999999.9999) self.frz_entry.set_precision(self.decimals) self.frz_entry.setObjectName('gdb_frz') @@ -1661,9 +1661,9 @@ class ToolsDB2(QtWidgets.QWidget): "The speed of the spindle in RPM.")) self.spindle_entry = FCDoubleSpinner() - self.spindle_entry.set_range(-9999.9999, 9999.9999) + self.spindle_entry.set_range(-999999.9999, 999999.9999) self.spindle_entry.set_precision(self.decimals) - self.frz_entry.setObjectName('gdb_spindle') + self.spindle_entry.setObjectName('gdb_spindle') self.grid0.addWidget(self.spindle_label, 15, 0) self.grid0.addWidget(self.spindle_entry, 15, 1) @@ -1874,9 +1874,6 @@ class ToolsDB2(QtWidgets.QWidget): ) self.milling_type_radio.setObjectName("gdb_n_milling_type") - self.milling_type_label.setEnabled(False) - self.milling_type_radio.setEnabled(False) - self.grid2.addWidget(self.milling_type_label, 14, 0) self.grid2.addWidget(self.milling_type_radio, 14, 1) @@ -2179,11 +2176,11 @@ class ToolsDB2(QtWidgets.QWidget): "tools_ncc_offset_value": self.ncc_offset_spinner, # Paint - "paintoverlap": self.paintoverlap_entry, - "paintmargin": self.paintmargin_entry, - "paintmethod": self.paintmethod_combo, - "pathconnect": self.pathconnect_cb, - "paintcontour": self.paintcontour_cb, + "tools_paintoverlap": self.paintoverlap_entry, + "tools_paintmargin": self.paintmargin_entry, + "tools_paintmethod": self.paintmethod_combo, + "tools_pathconnect": self.pathconnect_cb, + "tools_paintcontour": self.paintcontour_cb, } self.name2option = { @@ -2212,22 +2209,22 @@ class ToolsDB2(QtWidgets.QWidget): "gdb_ecut_length": "extracut_length", # NCC - "gdb_n_operation": "nccoperation", - "gdb_n_overlap": "nccoverlap", - "gdb_n_margin": "nccmargin", - "gdb_n_method": "nccmethod", - "gdb_n_connect": "nccconnect", - "gdb_n_contour": "ncccontour", - "gdb_n_offset": "nccoffset", - "gdb_n_offset_value": "nccoffset_value", - "gdb_n_milling_type": "milling_type", + "gdb_n_operation": "tools_nccoperation", + "gdb_n_overlap": "tools_nccoverlap", + "gdb_n_margin": "tools_nccmargin", + "gdb_n_method": "tools_nccmethod", + "gdb_n_connect": "tools_nccconnect", + "gdb_n_contour": "tools_ncccontour", + "gdb_n_offset": "tools_ncc_offset_choice", + "gdb_n_offset_value": "tools_ncc_offset_value", + "gdb_n_milling_type": "tools_nccmilling_type", # Paint - 'gdb_p_overlap': "paintoverlap", - 'gdb_p_margin': "paintmargin", - 'gdb_p_method': "paintmethod", - 'gdb_p_connect': "pathconnect", - 'gdb_p_contour': "paintcontour", + 'gdb_p_overlap': "tools_paintoverlap", + 'gdb_p_margin': "tools_paintmargin", + 'gdb_p_method': "tools_paintmethod", + 'gdb_p_connect': "tools_pathconnect", + 'gdb_p_contour': "tools_paintcontour", } self.current_toolid = None @@ -2376,7 +2373,7 @@ class ToolsDB2(QtWidgets.QWidget): self.paint_box.setEnabled(True) self.tree_widget.setCurrentItem(self.tree_widget.topLevelItem(0)) - self.tree_widget.setFocus() + # self.tree_widget.setFocus() else: # Disable GUI @@ -2430,11 +2427,11 @@ class ToolsDB2(QtWidgets.QWidget): "tools_ncc_offset_value": float(self.app.defaults["tools_ncc_offset_value"]), # Paint - "paintoverlap": float(self.app.defaults["tools_paintoverlap"]), - "paintmargin": float(self.app.defaults["tools_paintmargin"]), - "paintmethod": self.app.defaults["tools_paintmethod"], - "pathconnect": self.app.defaults["tools_pathconnect"], - "paintcontour": self.app.defaults["tools_paintcontour"], + "tools_paintoverlap": float(self.app.defaults["tools_paintoverlap"]), + "tools_paintmargin": float(self.app.defaults["tools_paintmargin"]), + "tools_paintmethod": self.app.defaults["tools_paintmethod"], + "tools_pathconnect": self.app.defaults["tools_pathconnect"], + "tools_paintcontour": self.app.defaults["tools_paintcontour"], }) dict_elem = {} @@ -2638,6 +2635,10 @@ class ToolsDB2(QtWidgets.QWidget): if isinstance(wdg, FCCheckBox): wdg.toggled.connect(self.update_storage) + # FCRadio + if isinstance(wdg, RadioSet): + wdg.activated_custom.connect(self.update_storage) + # SpinBox, DoubleSpinBox if isinstance(wdg, FCSpinner) or isinstance(wdg, FCDoubleSpinner): wdg.valueChanged.connect(self.update_storage) @@ -2672,6 +2673,13 @@ class ToolsDB2(QtWidgets.QWidget): except (TypeError, AttributeError): pass + # FCRadio + if isinstance(wdg, RadioSet): + try: + wdg.activated_custom.disconnect(self.update_storage) + except (TypeError, AttributeError): + pass + # SpinBox, DoubleSpinBox if isinstance(wdg, FCSpinner) or isinstance(wdg, FCDoubleSpinner): try: @@ -2688,68 +2696,109 @@ class ToolsDB2(QtWidgets.QWidget): item.setData(1, QtCore.Qt.DisplayRole, val) def update_storage(self): - + """ + Update the dictionary that is the storage of the tools 'database' + :return: + """ tool_id = str(self.current_toolid) + wdg = self.sender() if wdg is None: return + wdg_name = wdg.objectName() + try: + val = wdg.get_value() + except AttributeError: + return + if wdg_name == "gdb_name": - self.db_tool_dict[tool_id]['name'] = wdg.get_value() + self.db_tool_dict[tool_id]['name'] = val elif wdg_name == "gdb_dia": - self.db_tool_dict[tool_id]['tooldia'] = wdg.get_value() + self.db_tool_dict[tool_id]['tooldia'] = val elif wdg_name == "gdb_tool_offset": - self.db_tool_dict[tool_id]['offset'] = wdg.get_value() + self.db_tool_dict[tool_id]['offset'] = val elif wdg_name == "gdb_custom_offset": - self.db_tool_dict[tool_id]['offset_value'] = wdg.get_value() + self.db_tool_dict[tool_id]['offset_value'] = val elif wdg_name == "gdb_type": - self.db_tool_dict[tool_id]['type'] = wdg.get_value() + self.db_tool_dict[tool_id]['type'] = val elif wdg_name == "gdb_shape": - self.db_tool_dict[tool_id]['tool_type'] = wdg.get_value() + self.db_tool_dict[tool_id]['tool_type'] = val else: if wdg_name == "gdb_cutz": - self.db_tool_dict[tool_id]['data']['cutz'] = wdg.get_value() + self.db_tool_dict[tool_id]['data']['cutz'] = val elif wdg_name == "gdb_multidepth": - self.db_tool_dict[tool_id]['data']['multidepth'] = wdg.get_value() + self.db_tool_dict[tool_id]['data']['multidepth'] = val elif wdg_name == "gdb_multidepth_entry": - self.db_tool_dict[tool_id]['data']['depthperpass'] = wdg.get_value() + self.db_tool_dict[tool_id]['data']['depthperpass'] = val elif wdg_name == "gdb_travel": - self.db_tool_dict[tool_id]['data']['travelz'] = wdg.get_value() + self.db_tool_dict[tool_id]['data']['travelz'] = val elif wdg_name == "gdb_frxy": - self.db_tool_dict[tool_id]['data']['feedrate'] = wdg.get_value() + self.db_tool_dict[tool_id]['data']['feedrate'] = val elif wdg_name == "gdb_frz": - self.db_tool_dict[tool_id]['data']['feedrate_z'] = wdg.get_value() + self.db_tool_dict[tool_id]['data']['feedrate_z'] = val elif wdg_name == "gdb_spindle": - self.db_tool_dict[tool_id]['data']['spindlespeed'] = wdg.get_value() + self.db_tool_dict[tool_id]['data']['spindlespeed'] = val elif wdg_name == "gdb_dwell": - self.db_tool_dict[tool_id]['data']['dwell'] = wdg.get_value() + self.db_tool_dict[tool_id]['data']['dwell'] = val elif wdg_name == "gdb_dwelltime": - self.db_tool_dict[tool_id]['data']['dwelltime'] = wdg.get_value() + self.db_tool_dict[tool_id]['data']['dwelltime'] = val elif wdg_name == "gdb_vdia": - self.db_tool_dict[tool_id]['data']['vtipdia'] = wdg.get_value() + self.db_tool_dict[tool_id]['data']['vtipdia'] = val elif wdg_name == "gdb_vangle": - self.db_tool_dict[tool_id]['data']['vtipangle'] = wdg.get_value() + self.db_tool_dict[tool_id]['data']['vtipangle'] = val elif wdg_name == "gdb_frapids": - self.db_tool_dict[tool_id]['data']['feedrate_rapid'] = wdg.get_value() + self.db_tool_dict[tool_id]['data']['feedrate_rapid'] = val elif wdg_name == "gdb_ecut": - self.db_tool_dict[tool_id]['data']['extracut'] = wdg.get_value() + self.db_tool_dict[tool_id]['data']['extracut'] = val elif wdg_name == "gdb_ecut_length": - self.db_tool_dict[tool_id]['data']['extracut_length'] = wdg.get_value() + self.db_tool_dict[tool_id]['data']['extracut_length'] = val + + # NCC Tool + elif wdg_name == "gdb_n_operation": + self.db_tool_dict[tool_id]['data']['tools_nccoperation'] = val + elif wdg_name == "gdb_n_overlap": + self.db_tool_dict[tool_id]['data']['tools_nccoverlap'] = val + elif wdg_name == "gdb_n_margin": + self.db_tool_dict[tool_id]['data']['tools_nccmargin'] = val + elif wdg_name == "gdb_n_method": + self.db_tool_dict[tool_id]['data']['tools_nccmethod'] = val + elif wdg_name == "gdb_n_connect": + self.db_tool_dict[tool_id]['data']['tools_nccconnect'] = val + elif wdg_name == "gdb_n_contour": + self.db_tool_dict[tool_id]['data']['tools_ncccontour'] = val + elif wdg_name == "gdb_n_offset": + self.db_tool_dict[tool_id]['data']['tools_ncc_offset_choice'] = val + elif wdg_name == "gdb_n_offset_value": + self.db_tool_dict[tool_id]['data']['tools_ncc_offset_value'] = val + elif wdg_name == "gdb_n_milling_type": + self.db_tool_dict[tool_id]['data']['tools_nccmilling_type'] = val + + # Paint Tool + elif wdg_name == "gdb_p_overlap": + self.db_tool_dict[tool_id]['data']['tools_paintoverlap'] = val + elif wdg_name == "gdb_p_margin": + self.db_tool_dict[tool_id]['data']['tools_paintmargin'] = val + elif wdg_name == "gdb_p_method": + self.db_tool_dict[tool_id]['data']['tools_paintmethod'] = val + elif wdg_name == "gdb_p_connect": + self.db_tool_dict[tool_id]['data']['tools_pathconnect'] = val + elif wdg_name == "gdb_p_contour": + self.db_tool_dict[tool_id]['data']['tools_paintcontour'] = val self.callback_app() def on_tool_requested_from_app(self): - if not self.table_widget.selectionModel().selectedRows(): + if not self.tree_widget.selectedItems(): self.app.inform.emit('[WARNING_NOTCL] %s...' % _("No Tool/row selected in the Tools Database table")) return - model_index_list = self.table_widget.selectionModel().selectedRows() - for model_index in model_index_list: - selected_row = model_index.row() - tool_uid = selected_row + 1 + for item in self.tree_widget.selectedItems(): + tool_uid = item.data(0, QtCore.Qt.DisplayRole) + for key in self.db_tool_dict.keys(): if str(key) == str(tool_uid): selected_tool = self.db_tool_dict[key] diff --git a/README.md b/README.md index bc228160..f02c95aa 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 29.03.2020 - modified the new database to accept data from NCC and Paint Tools +- fixed issues in the new database when adding the tool in a Geometry object 28.03.2020 From d6adb99ec8eebd59f14eeb0488568ca9ede3fd07 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 29 Mar 2020 15:09:30 +0300 Subject: [PATCH 137/209] - fixed a bug in Geometry object that generated a change of dictionary while iterating over it --- FlatCAMObj.py | 4 ++-- README.md | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 610df50d..a28e2c73 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -4658,9 +4658,9 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): try: # set the form with data from the newly selected tool - for tooluid_key, tooluid_value in self.tools.items(): + for tooluid_key, tooluid_value in list(self.tools.items()): if int(tooluid_key) == tooluid: - for key, value in tooluid_value.items(): + for key, value in list(tooluid_value.items()): if key == 'data': form_value_storage = tooluid_value['data'] self.update_form(form_value_storage) diff --git a/README.md b/README.md index f02c95aa..65d35d41 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ CAD program, and create G-Code for Isolation routing. - modified the new database to accept data from NCC and Paint Tools - fixed issues in the new database when adding the tool in a Geometry object +- fixed a bug in Geometry object that generated a change of dictionary while iterating over it 28.03.2020 From 4aeadde3dae9191254fec28ab6e020a14b0e693c Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 29 Mar 2020 17:48:46 +0300 Subject: [PATCH 138/209] - started to add the new database links in the NCC and Paint Tools --- FlatCAMApp.py | 29 +++++++++--- FlatCAMCommon.py | 1 + README.md | 1 + flatcamTools/ToolNCC.py | 99 ++++++++++++++++++++++++++++++++++++++- flatcamTools/ToolPaint.py | 96 +++++++++++++++++++++++++++++++++++++ 5 files changed, 217 insertions(+), 9 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 0306632b..aec238e4 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -8066,7 +8066,7 @@ class App(QtCore.QObject): self.preferences_changed_flag = True - def on_tools_database(self): + def on_tools_database(self, source='app'): """ Adds the Tools Database in a Tab in Plot Area :return: @@ -8076,12 +8076,27 @@ class App(QtCore.QObject): # there can be only one instance of Tools Database at one time return - self.tools_db_tab = ToolsDB2( - app=self, - parent=self.ui, - callback_on_edited=self.on_tools_db_edited, - callback_on_tool_request=self.on_geometry_tool_add_from_db_executed - ) + if source == 'app': + self.tools_db_tab = ToolsDB2( + app=self, + parent=self.ui, + callback_on_edited=self.on_tools_db_edited, + callback_on_tool_request=self.on_geometry_tool_add_from_db_executed + ) + elif source == 'ncc': + self.tools_db_tab = ToolsDB2( + app=self, + parent=self.ui, + callback_on_edited=self.on_tools_db_edited, + callback_on_tool_request=self.ncclear_tool.on_ncc_tool_add_from_db_executed + ) + elif source == 'paint': + self.tools_db_tab = ToolsDB2( + app=self, + parent=self.ui, + callback_on_edited=self.on_tools_db_edited, + callback_on_tool_request=self.paint_tool.on_paint_tool_add_from_db_executed + ) # add the tab if it was closed self.ui.plot_tab_area.addTab(self.tools_db_tab, _("Tools Database")) diff --git a/FlatCAMCommon.py b/FlatCAMCommon.py index c0cb24db..9d02b94e 100644 --- a/FlatCAMCommon.py +++ b/FlatCAMCommon.py @@ -2394,6 +2394,7 @@ class ToolsDB2(QtWidgets.QWidget): default_data = {} default_data.update({ + "plot": True, "cutz": float(self.app.defaults["geometry_cutz"]), "multidepth": self.app.defaults["geometry_multidepth"], "depthperpass": float(self.app.defaults["geometry_depthperpass"]), diff --git a/README.md b/README.md index 65d35d41..88c30ba0 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ CAD program, and create G-Code for Isolation routing. - modified the new database to accept data from NCC and Paint Tools - fixed issues in the new database when adding the tool in a Geometry object - fixed a bug in Geometry object that generated a change of dictionary while iterating over it +- started to add the new database links in the NCC and Paint Tools 28.03.2020 diff --git a/flatcamTools/ToolNCC.py b/flatcamTools/ToolNCC.py index 630e87b5..af81fb95 100644 --- a/flatcamTools/ToolNCC.py +++ b/flatcamTools/ToolNCC.py @@ -737,8 +737,8 @@ class NonCopperClear(FlatCAMTool, Gerber): self.ncc_order_radio.activated_custom[str].connect(self.on_order_changed) self.type_obj_radio.activated_custom.connect(self.on_type_obj_index_changed) - self.apply_param_to_all.clicked.connect(self.on_apply_param_to_all_clicked) + self.addtool_from_db_btn.clicked.connect(self.on_ncc_tool_add_from_db_clicked) self.reset_button.clicked.connect(self.set_tool_ui) @@ -1127,7 +1127,7 @@ class NonCopperClear(FlatCAMTool, Gerber): tool_type_item = FCComboBox() tool_type_item.addItems(self.tool_type_item_options) - # tool_type_item.setStyleSheet('background-color: rgb(255,255,255)') + # tool_type_item.setStyleSheet('background-color: rgb(255,255,255)') idx = tool_type_item.findText(tooluid_value['tool_type']) tool_type_item.setCurrentIndex(idx) @@ -3965,3 +3965,98 @@ class NonCopperClear(FlatCAMTool, Gerber): log.debug("NonCopperClear.generate_envelope() Error --> %s" % str(e)) return 'fail' return geom + + def on_ncc_tool_add_from_db_executed(self, tool): + """ + Here add the tool from DB in the selected geometry object + :return: + """ + tool_from_db = deepcopy(tool) + + res = self.on_ncc_tool_from_db_inserted(tool=tool_from_db) + + for idx in range(self.app.ui.plot_tab_area.count()): + if self.app.ui.plot_tab_area.tabText(idx) == _("Tools Database"): + wdg = self.app.ui.plot_tab_area.widget(idx) + wdg.deleteLater() + self.app.ui.plot_tab_area.removeTab(idx) + + if res == 'fail': + return + self.app.inform.emit('[success] %s' % _("Tool from DB added in Tool Table.")) + + def on_ncc_tool_from_db_inserted(self, tool): + """ + Called from the Tools DB object through a App method when adding a tool from Tools Database + :param tool: a dict with the tool data + :return: None + """ + + self.ui_disconnect() + self.units = self.app.defaults['units'].upper() + + tooldia = float(tool['tooldia']) + + # construct a list of all 'tooluid' in the self.tools + tool_uid_list = [] + for tooluid_key in self.ncc_tools: + tool_uid_item = int(tooluid_key) + tool_uid_list.append(tool_uid_item) + + # find maximum from the temp_uid, add 1 and this is the new 'tooluid' + if not tool_uid_list: + max_uid = 0 + else: + max_uid = max(tool_uid_list) + tooluid = max_uid + 1 + + tooldia = float('%.*f' % (self.decimals, tooldia)) + + tool_dias = [] + for k, v in self.ncc_tools.items(): + for tool_v in v.keys(): + if tool_v == 'tooldia': + tool_dias.append(float('%.*f' % (self.decimals, (v[tool_v])))) + + if float('%.*f' % (self.decimals, tooldia)) in tool_dias: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Adding tool cancelled. Tool already in Tool Table.")) + self.ui_connect() + return 'fail' + + self.ncc_tools.update({ + tooluid: { + 'tooldia': float('%.*f' % (self.decimals, tooldia)), + 'offset': 'Path', + 'offset_value': 0.0, + 'type': 'Iso', + 'tool_type': tool['tool_type'], + 'data': deepcopy(tool['data']), + 'solid_geometry': [] + } + }) + self.ncc_tools[tooluid]['data']['name'] = '_ncc' + + self.app.inform.emit('[success] %s' % _("New tool added to Tool Table.")) + + self.ui_connect() + self.build_ui() + + # if self.tools_table.rowCount() != 0: + # self.param_frame.setDisabled(False) + + def on_ncc_tool_add_from_db_clicked(self): + """ + Called when the user wants to add a new tool from Tools Database. It will create the Tools Database object + and display the Tools Database tab in the form needed for the Tool adding + :return: None + """ + + # if the Tools Database is already opened focus on it + for idx in range(self.app.ui.plot_tab_area.count()): + if self.app.ui.plot_tab_area.tabText(idx) == _("Tools Database"): + self.app.ui.plot_tab_area.setCurrentWidget(self.app.tools_db_tab) + break + self.app.on_tools_database(source='ncc') + self.app.tools_db_tab.buttons_frame.hide() + self.app.tools_db_tab.add_tool_from_db.show() + self.app.tools_db_tab.cancel_tool_from_db.show() diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 0881cbe2..0b930c4c 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -661,6 +661,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.type_obj_combo.activated_custom.connect(self.on_type_obj_changed) self.apply_param_to_all.clicked.connect(self.on_apply_param_to_all_clicked) + self.addtool_from_db_btn.clicked.connect(self.on_paint_tool_add_from_db_clicked) self.reset_button.clicked.connect(self.set_tool_ui) @@ -4331,5 +4332,100 @@ class ToolPaint(FlatCAMTool, Gerber): return bounds_rec(geometry) + def on_paint_tool_add_from_db_executed(self, tool): + """ + Here add the tool from DB in the selected geometry object + :return: + """ + tool_from_db = deepcopy(tool) + + res = self.on_paint_tool_from_db_inserted(tool=tool_from_db) + + for idx in range(self.app.ui.plot_tab_area.count()): + if self.app.ui.plot_tab_area.tabText(idx) == _("Tools Database"): + wdg = self.app.ui.plot_tab_area.widget(idx) + wdg.deleteLater() + self.app.ui.plot_tab_area.removeTab(idx) + + if res == 'fail': + return + self.app.inform.emit('[success] %s' % _("Tool from DB added in Tool Table.")) + + def on_paint_tool_from_db_inserted(self, tool): + """ + Called from the Tools DB object through a App method when adding a tool from Tools Database + :param tool: a dict with the tool data + :return: None + """ + + self.ui_disconnect() + self.units = self.app.defaults['units'].upper() + + tooldia = float(tool['tooldia']) + + # construct a list of all 'tooluid' in the self.tools + tool_uid_list = [] + for tooluid_key in self.paint_tools: + tool_uid_item = int(tooluid_key) + tool_uid_list.append(tool_uid_item) + + # find maximum from the temp_uid, add 1 and this is the new 'tooluid' + if not tool_uid_list: + max_uid = 0 + else: + max_uid = max(tool_uid_list) + tooluid = max_uid + 1 + + tooldia = float('%.*f' % (self.decimals, tooldia)) + + tool_dias = [] + for k, v in self.paint_tools.items(): + for tool_v in v.keys(): + if tool_v == 'tooldia': + tool_dias.append(float('%.*f' % (self.decimals, (v[tool_v])))) + + if float('%.*f' % (self.decimals, tooldia)) in tool_dias: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Adding tool cancelled. Tool already in Tool Table.")) + self.ui_connect() + return 'fail' + + self.paint_tools.update({ + tooluid: { + 'tooldia': float('%.*f' % (self.decimals, tooldia)), + 'offset': 'Path', + 'offset_value': 0.0, + 'type': 'Iso', + 'tool_type': tool['tool_type'], + 'data': deepcopy(tool['data']), + 'solid_geometry': [] + } + }) + self.paint_tools[tooluid]['data']['name'] = '_paint' + + self.app.inform.emit('[success] %s' % _("New tool added to Tool Table.")) + + self.ui_connect() + self.build_ui() + + # if self.tools_table.rowCount() != 0: + # self.param_frame.setDisabled(False) + + def on_paint_tool_add_from_db_clicked(self): + """ + Called when the user wants to add a new tool from Tools Database. It will create the Tools Database object + and display the Tools Database tab in the form needed for the Tool adding + :return: None + """ + + # if the Tools Database is already opened focus on it + for idx in range(self.app.ui.plot_tab_area.count()): + if self.app.ui.plot_tab_area.tabText(idx) == _("Tools Database"): + self.app.ui.plot_tab_area.setCurrentWidget(self.app.tools_db_tab) + break + self.app.on_tools_database(source='paint') + self.app.tools_db_tab.buttons_frame.hide() + self.app.tools_db_tab.add_tool_from_db.show() + self.app.tools_db_tab.cancel_tool_from_db.show() + def reset_fields(self): self.obj_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) From a872a958cacb7e6e0c6dc21e747b5bec1e5a7952 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 29 Mar 2020 21:10:30 +0300 Subject: [PATCH 139/209] - in the new Tools DB added ability to double click on the ID in the tree widget to execute adding a tool from DB --- FlatCAMCommon.py | 10 ++++++++++ FlatCAMObj.py | 1 + README.md | 1 + flatcamTools/ToolNCC.py | 29 +++++++++++++++-------------- flatcamTools/ToolPaint.py | 1 + 5 files changed, 28 insertions(+), 14 deletions(-) diff --git a/FlatCAMCommon.py b/FlatCAMCommon.py index 9d02b94e..08142a9e 100644 --- a/FlatCAMCommon.py +++ b/FlatCAMCommon.py @@ -2229,6 +2229,9 @@ class ToolsDB2(QtWidgets.QWidget): self.current_toolid = None + # variable to show if double clicking and item will trigger adding a tool from DB + self.ok_to_add = False + # ############################################################################## # ######################## SIGNALS ############################################# # ############################################################################## @@ -2247,6 +2250,8 @@ class ToolsDB2(QtWidgets.QWidget): self.tree_widget.itemChanged.connect(self.on_list_item_edited) self.tree_widget.customContextMenuRequested.connect(self.on_menu_request) + self.tree_widget.itemDoubleClicked.connect(self.on_item_double_clicked) + self.setup_db_ui() def on_menu_request(self, pos): @@ -2264,6 +2269,11 @@ class ToolsDB2(QtWidgets.QWidget): # tree_item = self.tree_widget.itemAt(pos) menu.exec(self.tree_widget.viewport().mapToGlobal(pos)) + def on_item_double_clicked(self, item, column): + if column == 0 and self.ok_to_add is True: + self.ok_to_add = False + self.on_tool_requested_from_app() + def on_list_selection_change(self, current, previous): # for idx in current.indexes(): # print(idx.data()) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index a28e2c73..a267856f 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -4774,6 +4774,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.app.ui.plot_tab_area.setCurrentWidget(self.app.tools_db_tab) break self.app.on_tools_database() + self.app.tools_db_tab.ok_to_add = True self.app.tools_db_tab.buttons_frame.hide() self.app.tools_db_tab.add_tool_from_db.show() self.app.tools_db_tab.cancel_tool_from_db.show() diff --git a/README.md b/README.md index 88c30ba0..ec435ee2 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ CAD program, and create G-Code for Isolation routing. - fixed issues in the new database when adding the tool in a Geometry object - fixed a bug in Geometry object that generated a change of dictionary while iterating over it - started to add the new database links in the NCC and Paint Tools +- in the new Tools DB added ability to double click on the ID in the tree widget to execute adding a tool from DB 28.03.2020 diff --git a/flatcamTools/ToolNCC.py b/flatcamTools/ToolNCC.py index af81fb95..11be5cbe 100644 --- a/flatcamTools/ToolNCC.py +++ b/flatcamTools/ToolNCC.py @@ -3911,20 +3911,6 @@ class NonCopperClear(FlatCAMTool, Gerber): return ret_val - def reset_fields(self): - self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - - def reset_usage(self): - self.obj_name = "" - self.ncc_obj = None - self.bound_obj = None - - self.first_click = False - self.cursor_pos = None - self.mouse_is_dragging = False - - self.sel_rect = [] - @staticmethod def poly2rings(poly): return [poly.exterior] + [interior for interior in poly.interiors] @@ -4057,6 +4043,21 @@ class NonCopperClear(FlatCAMTool, Gerber): self.app.ui.plot_tab_area.setCurrentWidget(self.app.tools_db_tab) break self.app.on_tools_database(source='ncc') + self.app.tools_db_tab.ok_to_add = True self.app.tools_db_tab.buttons_frame.hide() self.app.tools_db_tab.add_tool_from_db.show() self.app.tools_db_tab.cancel_tool_from_db.show() + + def reset_fields(self): + self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) + + def reset_usage(self): + self.obj_name = "" + self.ncc_obj = None + self.bound_obj = None + + self.first_click = False + self.cursor_pos = None + self.mouse_is_dragging = False + + self.sel_rect = [] diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 0b930c4c..3f7c1e48 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -4423,6 +4423,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.app.ui.plot_tab_area.setCurrentWidget(self.app.tools_db_tab) break self.app.on_tools_database(source='paint') + self.app.tools_db_tab.ok_to_add = True self.app.tools_db_tab.buttons_frame.hide() self.app.tools_db_tab.add_tool_from_db.show() self.app.tools_db_tab.cancel_tool_from_db.show() From 70dd9aecaea4627a6d7fabf1bd5f428e69ac56e4 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 29 Mar 2020 21:39:20 +0300 Subject: [PATCH 140/209] - working in updating NCC Tool --- README.md | 1 + flatcamTools/ToolNCC.py | 86 ++++++++++++++++++++--------------------- 2 files changed, 44 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index ec435ee2..c7a7f84f 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ CAD program, and create G-Code for Isolation routing. - fixed a bug in Geometry object that generated a change of dictionary while iterating over it - started to add the new database links in the NCC and Paint Tools - in the new Tools DB added ability to double click on the ID in the tree widget to execute adding a tool from DB +- working in updating NCC Tool 28.03.2020 diff --git a/flatcamTools/ToolNCC.py b/flatcamTools/ToolNCC.py index 11be5cbe..6ace005f 100644 --- a/flatcamTools/ToolNCC.py +++ b/flatcamTools/ToolNCC.py @@ -691,27 +691,27 @@ class NonCopperClear(FlatCAMTool, Gerber): self.tooldia = None self.form_fields = { - "nccoperation": self.op_radio, - "nccoverlap": self.ncc_overlap_entry, - "nccmargin": self.ncc_margin_entry, - "nccmethod": self.ncc_method_combo, - "nccconnect": self.ncc_connect_cb, - "ncccontour": self.ncc_contour_cb, - "nccoffset": self.ncc_choice_offset_cb, - "nccoffset_value": self.ncc_offset_spinner, - "milling_type": self.milling_type_radio + "tools_nccoperation": self.op_radio, + "tools_nccoverlap": self.ncc_overlap_entry, + "tools_nccmargin": self.ncc_margin_entry, + "tools_nccmethod": self.ncc_method_combo, + "tools_nccconnect": self.ncc_connect_cb, + "tools_ncccontour": self.ncc_contour_cb, + "tools_ncc_offset_choice": self.ncc_choice_offset_cb, + "tools_ncc_offset_value": self.ncc_offset_spinner, + "tools_nccmilling_type": self.milling_type_radio } self.name2option = { - "n_operation": "nccoperation", - "n_overlap": "nccoverlap", - "n_margin": "nccmargin", - "n_method": "nccmethod", - "n_connect": "nccconnect", - "n_contour": "ncccontour", - "n_offset": "nccoffset", - "n_offset_value": "nccoffset_value", - "n_milling_type": "milling_type", + "n_operation": "tools_nccoperation", + "n_overlap": "tools_nccoverlap", + "n_margin": "tools_nccmargin", + "n_method": "tools_nccmethod", + "n_connect": "tools_nccconnect", + "n_contour": "tools_ncccontour", + "n_offset": "tools_ncc_offset_choice", + "n_offset_value": "tools_ncc_offset_value", + "n_milling_type": "tools_nccmilling_type", } self.old_tool_dia = None @@ -761,7 +761,7 @@ class NonCopperClear(FlatCAMTool, Gerber): current_row = self.tools_table.currentRow() try: current_uid = int(self.tools_table.item(current_row, 3).text()) - self.ncc_tools[current_uid]['data']['nccoperation'] = val + self.ncc_tools[current_uid]['data']['tools_nccoperation'] = val except AttributeError: return @@ -1036,17 +1036,17 @@ class NonCopperClear(FlatCAMTool, Gerber): "toolchangexy": self.app.defaults["geometry_toolchangexy"], "startz": self.app.defaults["geometry_startz"], - "nccoperation": self.app.defaults["tools_nccoperation"], - "nccmargin": self.app.defaults["tools_nccmargin"], - "nccmethod": self.app.defaults["tools_nccmethod"], - "nccconnect": self.app.defaults["tools_nccconnect"], - "ncccontour": self.app.defaults["tools_ncccontour"], - "nccoverlap": self.app.defaults["tools_nccoverlap"], + "tools_nccoperation": self.app.defaults["tools_nccoperation"], + "tools_nccmargin": self.app.defaults["tools_nccmargin"], + "tools_nccmethod": self.app.defaults["tools_nccmethod"], + "tools_nccconnect": self.app.defaults["tools_nccconnect"], + "tools_ncccontour": self.app.defaults["tools_ncccontour"], + "tools_nccoverlap": self.app.defaults["tools_nccoverlap"], "nccrest": self.app.defaults["tools_nccrest"], "nccref": self.app.defaults["tools_nccref"], - "nccoffset": self.app.defaults["tools_ncc_offset_choice"], - "nccoffset_value": self.app.defaults["tools_ncc_offset_value"], - + "tools_ncc_offset_choice": self.app.defaults["tools_ncc_offset_choice"], + "tools_ncc_offset_value": self.app.defaults["tools_ncc_offset_value"], + "tools_nccmilling_type": self.app.defaults["tools_nccmilling_type"], } try: @@ -2256,7 +2256,7 @@ class NonCopperClear(FlatCAMTool, Gerber): # if self.tools_table.cellWidget(row, 1).currentText() == 'clear_op': # sorted_tools.append(float(self.tools_table.item(row, 1).text())) for tooluid in self.ncc_tools: - if self.ncc_tools[tooluid]['data']['nccoperation'] == 'clear': + if self.ncc_tools[tooluid]['data']['tools_nccoperation'] == 'clear': sorted_tools.append(self.ncc_tools[tooluid]['tooldia']) # ######################################################################################################## @@ -2335,13 +2335,13 @@ class NonCopperClear(FlatCAMTool, Gerber): tooluid = int(k) break - ncc_overlap = float(self.ncc_tools[tooluid]["data"]["nccoverlap"]) / 100.0 - ncc_margin = float(self.ncc_tools[tooluid]["data"]["nccmargin"]) - ncc_method = self.ncc_tools[tooluid]["data"]["nccmethod"] - ncc_connect = self.ncc_tools[tooluid]["data"]["nccconnect"] - ncc_contour = self.ncc_tools[tooluid]["data"]["ncccontour"] - has_offset = self.ncc_tools[tooluid]["data"]["nccoffset"] - ncc_offset = float(self.ncc_tools[tooluid]["data"]["nccoffset_value"]) + ncc_overlap = float(self.ncc_tools[tooluid]["data"]["tools_nccoverlap"]) / 100.0 + ncc_margin = float(self.ncc_tools[tooluid]["data"]["tools_nccmargin"]) + ncc_method = self.ncc_tools[tooluid]["data"]["tools_nccmethod"] + ncc_connect = self.ncc_tools[tooluid]["data"]["tools_nccconnect"] + ncc_contour = self.ncc_tools[tooluid]["data"]["tools_ncccontour"] + has_offset = self.ncc_tools[tooluid]["data"]["tools_ncc_offset_choice"] + ncc_offset = float(self.ncc_tools[tooluid]["data"]["tools_ncc_offset_value"]) cleared_geo[:] = [] @@ -2620,13 +2620,13 @@ class NonCopperClear(FlatCAMTool, Gerber): tooluid = int(k) break - ncc_overlap = float(self.ncc_tools[tooluid]["data"]["nccoverlap"]) / 100.0 - ncc_margin = float(self.ncc_tools[tooluid]["data"]["nccmargin"]) - ncc_method = self.ncc_tools[tooluid]["data"]["nccmethod"] - ncc_connect = self.ncc_tools[tooluid]["data"]["nccconnect"] - ncc_contour = self.ncc_tools[tooluid]["data"]["ncccontour"] - has_offset = self.ncc_tools[tooluid]["data"]["nccoffset"] - ncc_offset = float(self.ncc_tools[tooluid]["data"]["nccoffset_value"]) + ncc_overlap = float(self.ncc_tools[tooluid]["data"]["tools_nccoverlap"]) / 100.0 + ncc_margin = float(self.ncc_tools[tooluid]["data"]["tools_nccmargin"]) + ncc_method = self.ncc_tools[tooluid]["data"]["tools_nccmethod"] + ncc_connect = self.ncc_tools[tooluid]["data"]["tools_nccconnect"] + ncc_contour = self.ncc_tools[tooluid]["data"]["tools_ncccontour"] + has_offset = self.ncc_tools[tooluid]["data"]["tools_ncc_offset_choice"] + ncc_offset = float(self.ncc_tools[tooluid]["data"]["tools_ncc_offset_value"]) tool_used = tool - 1e-12 cleared_geo[:] = [] From 8a2f5fed0568b865d3abbe1670d15ad7f9e17734 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 30 Mar 2020 23:12:27 +0300 Subject: [PATCH 141/209] - working to update the Paint Tool --- README.md | 4 + camlib.py | 18 +- flatcamTools/ToolNCC.py | 14 +- flatcamTools/ToolPaint.py | 1649 +++++++++++++++---------------------- 4 files changed, 700 insertions(+), 985 deletions(-) diff --git a/README.md b/README.md index c7a7f84f..01845106 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +30.03.2020 + +- working to update the Paint Tool + 29.03.2020 - modified the new database to accept data from NCC and Paint Tools diff --git a/camlib.py b/camlib.py index 96587a0e..2770021c 100644 --- a/camlib.py +++ b/camlib.py @@ -1470,8 +1470,13 @@ class Geometry(object): line = LineString([(left, y), (right, y)]) line = line.intersection(margin_poly) - for ll in line: - lines_trimmed.append(ll) + try: + for ll in line: + lines_trimmed.append(ll) + if prog_plot: + self.plot_temp_shapes(ll) + except TypeError: + lines_trimmed.append(line) if prog_plot: self.plot_temp_shapes(line) except Exception as e: @@ -1502,8 +1507,13 @@ class Geometry(object): line = LineString([(x, top), (x, bot)]) line = line.intersection(margin_poly) - for ll in line: - lines_trimmed.append(ll) + try: + for ll in line: + lines_trimmed.append(ll) + if prog_plot: + self.plot_temp_shapes(ll) + except TypeError: + lines_trimmed.append(line) if prog_plot: self.plot_temp_shapes(line) except Exception as e: diff --git a/flatcamTools/ToolNCC.py b/flatcamTools/ToolNCC.py index 6ace005f..e2e5adfd 100644 --- a/flatcamTools/ToolNCC.py +++ b/flatcamTools/ToolNCC.py @@ -128,6 +128,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.tools_box.addWidget(self.tools_table) self.tools_table.setColumnCount(4) + # 3rd column is reserved (and hidden) for the tool ID self.tools_table.setHorizontalHeaderLabels(['#', _('Diameter'), _('TT'), '']) self.tools_table.setColumnHidden(3, True) self.tools_table.setSortingEnabled(False) @@ -3971,6 +3972,13 @@ class NonCopperClear(FlatCAMTool, Gerber): return self.app.inform.emit('[success] %s' % _("Tool from DB added in Tool Table.")) + # select last tool added + toolid = res + for row in range(self.tools_table.rowCount()): + if int(self.tools_table.item(row, 3).text()) == toolid: + self.tools_table.selectRow(row) + self.on_row_selection_change() + def on_ncc_tool_from_db_inserted(self, tool): """ Called from the Tools DB object through a App method when adding a tool from Tools Database @@ -4012,9 +4020,9 @@ class NonCopperClear(FlatCAMTool, Gerber): self.ncc_tools.update({ tooluid: { 'tooldia': float('%.*f' % (self.decimals, tooldia)), - 'offset': 'Path', - 'offset_value': 0.0, - 'type': 'Iso', + 'offset': tool['offset'], + 'offset_value': tool['offset_value'], + 'type': tool['type'], 'tool_type': tool['tool_type'], 'data': deepcopy(tool['data']), 'solid_geometry': [] diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 3f7c1e48..51e6c9e3 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -120,6 +120,7 @@ class ToolPaint(FlatCAMTool, Gerber): ) self.tools_table = FCTable() + # self.tools_table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) grid0.addWidget(self.tools_table_label, 6, 0, 1, 2) grid0.addWidget(self.tools_table, 7, 0, 1, 2) @@ -614,19 +615,19 @@ class ToolPaint(FlatCAMTool, Gerber): self.tool_type_item_options = ["C1", "C2", "C3", "C4", "B", "V"] self.form_fields = { - "paintoverlap": self.paintoverlap_entry, - "paintmargin": self.paintmargin_entry, - "paintmethod": self.paintmethod_combo, - "pathconnect": self.pathconnect_cb, - "paintcontour": self.paintcontour_cb, + "tools_paintoverlap": self.paintoverlap_entry, + "tools_paintmargin": self.paintmargin_entry, + "tools_paintmethod": self.paintmethod_combo, + "tools_pathconnect": self.pathconnect_cb, + "tools_paintcontour": self.paintcontour_cb, } self.name2option = { - 'p_overlap': "paintoverlap", - 'p_margin': "paintmargin", - 'p_method': "paintmethod", - 'p_connect': "pathconnect", - 'p_contour': "paintcontour", + 'p_overlap': "tools_paintoverlap", + 'p_margin': "tools_paintmargin", + 'p_method': "tools_paintmethod", + 'p_connect': "tools_pathconnect", + 'p_contour': "tools_paintcontour", } self.old_tool_dia = None @@ -737,10 +738,13 @@ class ToolPaint(FlatCAMTool, Gerber): def on_row_selection_change(self): self.blockSignals(True) - sel_rows = [it.row() for it in self.tools_table.selectedItems()] - # sel_rows = sorted(set(index.row() for index in self.tools_table.selectedIndexes())) - - if not sel_rows: + sel_rows = set() + table_items = self.tools_table.selectedItems() + if table_items: + for it in table_items: + sel_rows.add(it.row()) + # sel_rows = sorted(set(index.row() for index in self.tools_table.selectedIndexes())) + else: sel_rows = [0] for current_row in sel_rows: @@ -765,10 +769,7 @@ class ToolPaint(FlatCAMTool, Gerber): # set the form with data from the newly selected tool for tooluid_key, tooluid_value in list(self.paint_tools.items()): if int(tooluid_key) == tooluid: - for key, value in tooluid_value.items(): - if key == 'data': - form_value_storage = tooluid_value[key] - self.storage_to_form(form_value_storage) + self.storage_to_form(tooluid_value['data']) except Exception as e: log.debug("ToolPaint ---> update_ui() " + str(e)) else: @@ -779,13 +780,11 @@ class ToolPaint(FlatCAMTool, Gerber): self.blockSignals(False) def storage_to_form(self, dict_storage): - for form_key in self.form_fields: - for storage_key in dict_storage: - if form_key == storage_key: - try: - self.form_fields[form_key].set_value(dict_storage[form_key]) - except Exception: - pass + for k in self.form_fields: + try: + self.form_fields[k].set_value(dict_storage[k]) + except Exception as err: + log.debug("ToolPaint.storage.form() --> %s" % str(err)) def form_to_storage(self): if self.tools_table.rowCount() == 0: @@ -1009,13 +1008,13 @@ class ToolPaint(FlatCAMTool, Gerber): "startz": self.app.defaults["geometry_startz"], "tooldia": self.app.defaults["tools_painttooldia"], - "paintmargin": self.app.defaults["tools_paintmargin"], - "paintmethod": self.app.defaults["tools_paintmethod"], - "selectmethod": self.app.defaults["tools_selectmethod"], - "pathconnect": self.app.defaults["tools_pathconnect"], - "paintcontour": self.app.defaults["tools_paintcontour"], - "paintoverlap": self.app.defaults["tools_paintoverlap"], - "paintrest": self.app.defaults["tools_paintrest"], + "tools_paintmargin": self.app.defaults["tools_paintmargin"], + "tools_paintmethod": self.app.defaults["tools_paintmethod"], + "tools_selectmethod": self.app.defaults["tools_selectmethod"], + "tools_pathconnect": self.app.defaults["tools_pathconnect"], + "tools_paintcontour": self.app.defaults["tools_paintcontour"], + "tools_paintoverlap": self.app.defaults["tools_paintoverlap"], + "tools_paintrest": self.app.defaults["tools_paintrest"], }) # ## Init the GUI interface @@ -1054,7 +1053,7 @@ class ToolPaint(FlatCAMTool, Gerber): log.error("At least one tool diameter needed. Verify in Edit -> Preferences -> TOOLS -> NCC Tools.") self.build_ui() # if the Paint Method is "Single" disable the tool table context menu - if self.default_data["selectmethod"] == "single": + if self.default_data["tools_selectmethod"] == "single": self.tools_table.setContextMenuPolicy(Qt.NoContextMenu) return @@ -1064,7 +1063,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.on_tool_add(dia, muted=True) # if the Paint Method is "Single" disable the tool table context menu - if self.default_data["selectmethod"] == "single": + if self.default_data["tools_selectmethod"] == "single": self.tools_table.setContextMenuPolicy(Qt.NoContextMenu) def build_ui(self): @@ -1151,6 +1150,16 @@ class ToolPaint(FlatCAMTool, Gerber): self.ui_connect() + # set the text on tool_data_label after loading the object + sel_rows = set() + sel_items = self.tools_table.selectedItems() + for it in sel_items: + sel_rows.add(it.row()) + if len(sel_rows) > 1: + self.tool_data_label.setText( + "%s: %s" % (_('Parameters for'), _("Multiple Tools")) + ) + def on_tool_add(self, dia=None, muted=None): self.blockSignals(True) @@ -1362,15 +1371,6 @@ class ToolPaint(FlatCAMTool, Gerber): self.app.report_usage("on_paint_button_click") # self.app.call_source = 'paint' - # ##################################################### - # ######### Reading Parameters ######################## - # ##################################################### - self.app.inform.emit(_("Paint Tool. Reading parameters.")) - - self.overlap = float(self.paintoverlap_entry.get_value()) / 100.0 - - self.connect = self.pathconnect_cb.get_value() - self.contour = self.paintcontour_cb.get_value() self.select_method = self.selectmethod_combo.get_value() self.obj_name = self.obj_combo.currentText() @@ -1396,8 +1396,9 @@ class ToolPaint(FlatCAMTool, Gerber): # use the selected tools in the tool table; get diameters self.tooldia_list = [] - if self.tools_table.selectedItems(): - for x in self.tools_table.selectedItems(): + table_items = self.tools_table.selectedItems() + if table_items: + for x in table_items: try: self.tooldia = float(self.tools_table.item(x.row(), 1).text()) except ValueError: @@ -1415,10 +1416,7 @@ class ToolPaint(FlatCAMTool, Gerber): if self.select_method == _("All Polygons"): self.paint_poly_all(self.paint_obj, tooldia=self.tooldia_list, - outname=self.o_name, - overlap=self.overlap, - connect=self.connect, - contour=self.contour) + outname=self.o_name) elif self.select_method == _("Polygon Selection"): self.app.inform.emit('[WARNING_NOTCL] %s' % _("Click on a polygon to paint it.")) @@ -1468,10 +1466,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.paint_poly_ref(obj=self.paint_obj, sel_obj=self.bound_obj, tooldia=self.tooldia_list, - overlap=self.overlap, - outname=self.o_name, - connect=self.connect, - contour=self.contour) + outname=self.o_name) # To be called after clicking on the plot. def on_single_poly_mouse_release(self, event): @@ -1553,10 +1548,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.paint_poly(self.paint_obj, inside_pt=(curr_pos[0], curr_pos[1]), poly_list=poly_list, - tooldia=self.tooldia_list, - overlap=self.overlap, - connect=self.connect, - contour=self.contour) + tooldia=self.tooldia_list) self.poly_dict.clear() else: self.app.inform.emit('[ERROR_NOTCL] %s' % _("List of single polygons is empty. Aborting.")) @@ -1682,10 +1674,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.paint_poly_area(obj=self.paint_obj, tooldia=self.tooldia_list, sel_obj=self.sel_rect, - outname=self.o_name, - overlap=self.overlap, - connect=self.connect, - contour=self.contour) + outname=self.o_name) # called on mouse move def on_mouse_move(self, event): @@ -1823,8 +1812,249 @@ class ToolPaint(FlatCAMTool, Gerber): self.delete_moving_selection_shape() self.delete_tool_selection_shape() - def paint_poly(self, obj, inside_pt=None, poly_list=None, tooldia=None, overlap=None, order=None, - margin=None, method=None, outname=None, connect=None, contour=None, tools_storage=None, + def paint_polygon_worker(self, polyg, tooldiameter, paint_method, over, conn, cont, prog_plot, obj): + + cpoly = None + + if paint_method == _("Standard"): + try: + # Type(cp) == FlatCAMRTreeStorage | None + cpoly = self.clear_polygon(polyg, + tooldia=tooldiameter, + steps_per_circle=self.app.defaults["geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + except FlatCAMApp.GracefulException: + return "fail" + except Exception as ee: + log.debug("ToolPaint.paint_polygon_worker() Standard --> %s" % str(ee)) + elif paint_method == _("Seed"): + try: + # Type(cp) == FlatCAMRTreeStorage | None + cpoly = self.clear_polygon2(polyg, + tooldia=tooldiameter, + steps_per_circle=self.app.defaults["geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + except FlatCAMApp.GracefulException: + return "fail" + except Exception as ee: + log.debug("ToolPaint.paint_polygon_worker() Seed --> %s" % str(ee)) + elif paint_method == _("Lines"): + try: + # Type(cp) == FlatCAMRTreeStorage | None + cpoly = self.clear_polygon3(polyg, + tooldia=tooldiameter, + steps_per_circle=self.app.defaults["geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + except FlatCAMApp.GracefulException: + return "fail" + except Exception as ee: + log.debug("ToolPaint.paint_polygon_worker() Lines --> %s" % str(ee)) + elif paint_method == _("Laser_lines"): + try: + # line = None + # aperture_size = None + + # the key is the aperture type and the val is a list of geo elements + flash_el_dict = {} + # the key is the aperture size, the val is a list of geo elements + traces_el_dict = {} + + # find the flashes and the lines that are in the selected polygon and store them separately + for apid, apval in obj.apertures.items(): + for geo_el in apval['geometry']: + if apval["size"] == 0.0: + if apval["size"] in traces_el_dict: + traces_el_dict[apval["size"]].append(geo_el) + else: + traces_el_dict[apval["size"]] = [geo_el] + + if 'follow' in geo_el and geo_el['follow'].within(polyg): + if isinstance(geo_el['follow'], Point): + if apval["type"] == 'C': + if 'C' in flash_el_dict: + flash_el_dict['C'].append(geo_el) + else: + flash_el_dict['C'] = [geo_el] + elif apval["type"] == 'O': + if 'O' in flash_el_dict: + flash_el_dict['O'].append(geo_el) + else: + flash_el_dict['O'] = [geo_el] + elif apval["type"] == 'R': + if 'R' in flash_el_dict: + flash_el_dict['R'].append(geo_el) + else: + flash_el_dict['R'] = [geo_el] + else: + aperture_size = apval['size'] + + if aperture_size in traces_el_dict: + traces_el_dict[aperture_size].append(geo_el) + else: + traces_el_dict[aperture_size] = [geo_el] + + cpoly = FlatCAMRTreeStorage() + pads_lines_list = [] + + # process the flashes found in the selected polygon with the 'lines' method for rectangular + # flashes and with _("Seed") for oblong and circular flashes + # and pads (flahes) need the contour therefore I override the GUI settings with always True + for ap_type in flash_el_dict: + for elem in flash_el_dict[ap_type]: + if 'solid' in elem: + if ap_type == 'C': + f_o = self.clear_polygon2(elem['solid'], + tooldia=tooldiameter, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=True, + connect=conn, + prog_plot=prog_plot) + pads_lines_list += [p for p in f_o.get_objects() if p] + + elif ap_type == 'O': + f_o = self.clear_polygon2(elem['solid'], + tooldia=tooldiameter, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=True, + connect=conn, + prog_plot=prog_plot) + pads_lines_list += [p for p in f_o.get_objects() if p] + + elif ap_type == 'R': + f_o = self.clear_polygon3(elem['solid'], + tooldia=tooldiameter, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=True, + connect=conn, + prog_plot=prog_plot) + + pads_lines_list += [p for p in f_o.get_objects() if p] + + # add the lines from pads to the storage + try: + for lin in pads_lines_list: + if lin: + cpoly.insert(lin) + except TypeError: + cpoly.insert(pads_lines_list) + + copper_lines_list = [] + # process the traces found in the selected polygon using the 'laser_lines' method, + # method which will follow the 'follow' line therefore use the longer path possible for the + # laser, therefore the acceleration will play a smaller factor + for aperture_size in traces_el_dict: + for elem in traces_el_dict[aperture_size]: + line = elem['follow'] + if line: + t_o = self.fill_with_lines(line, aperture_size, + tooldia=tooldiameter, + steps_per_circle=self.app.defaults[ + "geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + + copper_lines_list += [p for p in t_o.get_objects() if p] + + # add the lines from copper features to storage but first try to make as few lines as possible + # by trying to fuse them + lines_union = linemerge(unary_union(copper_lines_list)) + try: + for lin in lines_union: + if lin: + cpoly.insert(lin) + except TypeError: + cpoly.insert(lines_union) + # # determine the Gerber follow line + # for apid, apval in obj.apertures.items(): + # for geo_el in apval['geometry']: + # if 'solid' in geo_el: + # if Point(inside_pt).within(geo_el['solid']): + # if not isinstance(geo_el['follow'], Point): + # line = geo_el['follow'] + # + # if apval['type'] == 'C': + # aperture_size = apval['size'] + # else: + # if apval['width'] > apval['height']: + # aperture_size = apval['height'] + # else: + # aperture_size = apval['width'] + # + # if line: + # cpoly = self.fill_with_lines(line, aperture_size, + # tooldia=tooldiameter, + # steps_per_circle=self.app.defaults["geometry_circle_steps"], + # overlap=over, + # contour=cont, + # connect=conn, + # prog_plot=prog_plot) + except FlatCAMApp.GracefulException: + return "fail" + except Exception as ee: + log.debug("ToolPaint.paint_polygon_worker() Laser Lines --> %s" % str(ee)) + elif paint_method == _("Combo"): + try: + self.app.inform.emit(_("Painting polygon with method: lines.")) + cpoly = self.clear_polygon3(polyg, + tooldia=tooldiameter, + steps_per_circle=self.app.defaults["geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + + if cpoly and cpoly.objects: + pass + else: + self.app.inform.emit(_("Failed. Painting polygon with method: seed.")) + cpoly = self.clear_polygon2(polyg, + tooldia=tooldiameter, + steps_per_circle=self.app.defaults["geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + if cpoly and cpoly.objects: + pass + else: + self.app.inform.emit(_("Failed. Painting polygon with method: standard.")) + cpoly = self.clear_polygon(polyg, + tooldia=tooldiameter, + steps_per_circle=self.app.defaults["geometry_circle_steps"], + overlap=over, + contour=cont, + connect=conn, + prog_plot=prog_plot) + except FlatCAMApp.GracefulException: + return "fail" + except Exception as ee: + log.debug("ToolPaint.paint_polygon_worker() Combo --> %s" % str(ee)) + + if cpoly and cpoly.objects: + return cpoly + else: + self.app.inform.emit('[ERROR_NOTCL] %s' % _('Geometry could not be painted completely')) + return None + + def paint_poly(self, obj, inside_pt=None, poly_list=None, tooldia=None, order=None, + method=None, outname=None, tools_storage=None, plot=True, run_threaded=True): """ Paints a polygon selected by clicking on its interior or by having a point coordinates given @@ -1837,12 +2067,8 @@ class ToolPaint(FlatCAMTool, Gerber): :param obj: painted object :param inside_pt: [x, y] :param tooldia: Diameter of the painting tool - :param overlap: Overlap of the tool between passes. :param order: if the tools are ordered and how - :param margin: a border around painting area :param outname: Name of the resulting Geometry Object. - :param connect: Connect lines to avoid tool lifts. - :param contour: Paint around the edges. :param method: choice out of _("Seed"), 'normal', 'lines' :param tools_storage: whether to use the current tools_storage self.paints_tools or a different one. Usage of the different one is related to when this function is called from a TcL command. @@ -1850,27 +2076,29 @@ class ToolPaint(FlatCAMTool, Gerber): """ if isinstance(obj, FlatCAMGerber): + # I don't do anything here, like buffering when the Gerber is loaded without buffering????!!!! if self.app.defaults["gerber_buffering"] == 'no': self.app.inform.emit('%s %s %s' % (_("Paint Tool."), _("Normal painting polygon task started."), _("Buffering geometry..."))) else: self.app.inform.emit('%s %s' % (_("Paint Tool."), _("Normal painting polygon task started."))) - else: - self.app.inform.emit('%s %s' % (_("Paint Tool."), _("Normal painting polygon task started."))) - if isinstance(obj, FlatCAMGerber): if self.app.defaults["tools_paint_plotting"] == 'progressive': if isinstance(obj.solid_geometry, list): obj.solid_geometry = MultiPolygon(obj.solid_geometry).buffer(0) else: obj.solid_geometry = obj.solid_geometry.buffer(0) + else: + self.app.inform.emit('%s %s' % (_("Paint Tool."), _("Normal painting polygon task started."))) polygon_list = None if inside_pt and poly_list is None: polygon_list = [self.find_polygon(point=inside_pt, geoset=obj.solid_geometry)] elif (inside_pt is None and poly_list) or (inside_pt and poly_list): polygon_list = poly_list + else: + return # No polygon? if polygon_list is None: @@ -1879,14 +2107,10 @@ class ToolPaint(FlatCAMTool, Gerber): return paint_method = method if method is not None else self.paintmethod_combo.get_value() - paint_margin = float(self.paintmargin_entry.get_value()) if margin is None else margin # determine if to use the progressive plotting prog_plot = True if self.app.defaults["tools_paint_plotting"] == 'progressive' else False name = outname if outname is not None else self.obj_name + "_paint" - over = overlap if overlap is not None else float(self.app.defaults["tools_paintoverlap"]) / 100.0 - conn = connect if connect is not None else self.app.defaults["tools_pathconnect"] - cont = contour if contour is not None else self.app.defaults["tools_paintcontour"] order = order if order is not None else self.order_radio.get_value() tools_storage = self.paint_tools if tools_storage is None else tools_storage @@ -1911,287 +2135,104 @@ class ToolPaint(FlatCAMTool, Gerber): proc = self.app.proc_container.new(_("Painting polygon...")) - # Initializes the new geometry object - def gen_paintarea(geo_obj, app_obj): - geo_obj.solid_geometry = [] + tool_dia = None + current_uid = None + final_solid_geometry = [] - def paint_p(polyg, tooldiameter): - cpoly = None - try: - if paint_method == _("Standard"): - # Type(cp) == FlatCAMRTreeStorage | None - cpoly = self.clear_polygon(polyg, - tooldia=tooldiameter, - steps_per_circle=self.app.defaults["geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) + for tool_dia in sorted_tools: + log.debug("Starting geometry processing for tool: %s" % str(tool_dia)) + self.app.inform.emit( + '[success] %s %s%s %s' % (_('Painting with tool diameter = '), str(tool_dia), self.units.lower(), + _('started')) + ) + self.app.proc_container.update_view_text(' %d%%' % 0) - elif paint_method == _("Seed"): - # Type(cp) == FlatCAMRTreeStorage | None - cpoly = self.clear_polygon2(polyg, - tooldia=tooldiameter, - steps_per_circle=self.app.defaults["geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) + # find the tooluid associated with the current tool_dia so we know what tool to use + for k, v in tools_storage.items(): + if float('%.*f' % (self.decimals, v['tooldia'])) == float('%.*f' % (self.decimals, tool_dia)): + current_uid = int(k) - elif paint_method == _("Lines"): - # Type(cp) == FlatCAMRTreeStorage | None - cpoly = self.clear_polygon3(polyg, - tooldia=tooldiameter, - steps_per_circle=self.app.defaults["geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) + if not current_uid: + return "fail" - elif paint_method == _("Laser_lines"): - # line = None - # aperture_size = None + # determine the tool parameters to use + over = float(tools_storage[current_uid]['data']['tools_paintoverlap']) / 100.0 + conn = tools_storage[current_uid]['data']['tools_pathconnect'] + cont = tools_storage[current_uid]['data']['tools_paintcontour'] - # the key is the aperture type and the val is a list of geo elements - flash_el_dict = {} - # the key is the aperture size, the val is a list of geo elements - traces_el_dict = {} + paint_margin = float(tools_storage[current_uid]['data']['tools_paintmargin']) + poly_buf = [] + for pol in polygon_list: + buffered_pol = pol.buffer(-paint_margin) + if buffered_pol and not buffered_pol.is_empty: + poly_buf.append(buffered_pol) - # find the flashes and the lines that are in the selected polygon and store them separately - for apid, apval in obj.apertures.items(): - for geo_el in apval['geometry']: - if apval["size"] == 0.0: - if apval["size"] in traces_el_dict: - traces_el_dict[apval["size"]].append(geo_el) - else: - traces_el_dict[apval["size"]] = [geo_el] + if not poly_buf: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Margin parameter too big. Tool is not used")) + continue - if 'follow' in geo_el and geo_el['follow'].within(polyg): - if isinstance(geo_el['follow'], Point): - if apval["type"] == 'C': - if 'C' in flash_el_dict: - flash_el_dict['C'].append(geo_el) - else: - flash_el_dict['C'] = [geo_el] - elif apval["type"] == 'O': - if 'O' in flash_el_dict: - flash_el_dict['O'].append(geo_el) - else: - flash_el_dict['O'] = [geo_el] - elif apval["type"] == 'R': - if 'R' in flash_el_dict: - flash_el_dict['R'].append(geo_el) - else: - flash_el_dict['R'] = [geo_el] - else: - aperture_size = apval['size'] + # variables to display the percentage of work done + geo_len = len(poly_buf) - if aperture_size in traces_el_dict: - traces_el_dict[aperture_size].append(geo_el) - else: - traces_el_dict[aperture_size] = [geo_el] + log.warning("Total number of polygons to be cleared. %s" % str(geo_len)) - cpoly = FlatCAMRTreeStorage() - pads_lines_list = [] - - # process the flashes found in the selected polygon with the 'lines' method for rectangular - # flashes and with _("Seed") for oblong and circular flashes - # and pads (flahes) need the contour therefore I override the GUI settings with always True - for ap_type in flash_el_dict: - for elem in flash_el_dict[ap_type]: - if 'solid' in elem: - if ap_type == 'C': - f_o = self.clear_polygon2(elem['solid'], - tooldia=tooldiameter, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=True, - connect=conn, - prog_plot=prog_plot) - pads_lines_list += [p for p in f_o.get_objects() if p] - - elif ap_type == 'O': - f_o = self.clear_polygon2(elem['solid'], - tooldia=tooldiameter, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=True, - connect=conn, - prog_plot=prog_plot) - pads_lines_list += [p for p in f_o.get_objects() if p] - - elif ap_type == 'R': - f_o = self.clear_polygon3(elem['solid'], - tooldia=tooldiameter, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=True, - connect=conn, - prog_plot=prog_plot) - - pads_lines_list += [p for p in f_o.get_objects() if p] - - # add the lines from pads to the storage - try: - for lin in pads_lines_list: - if lin: - cpoly.insert(lin) - except TypeError: - cpoly.insert(pads_lines_list) - - copper_lines_list = [] - # process the traces found in the selected polygon using the 'laser_lines' method, - # method which will follow the 'follow' line therefore use the longer path possible for the - # laser, therefore the acceleration will play a smaller factor - for aperture_size in traces_el_dict: - for elem in traces_el_dict[aperture_size]: - line = elem['follow'] - if line: - t_o = self.fill_with_lines(line, aperture_size, - tooldia=tooldiameter, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - - copper_lines_list += [p for p in t_o.get_objects() if p] - - # add the lines from copper features to storage but first try to make as few lines as possible - # by trying to fuse them - lines_union = linemerge(unary_union(copper_lines_list)) - try: - for lin in lines_union: - if lin: - cpoly.insert(lin) - except TypeError: - cpoly.insert(lines_union) - # # determine the Gerber follow line - # for apid, apval in obj.apertures.items(): - # for geo_el in apval['geometry']: - # if 'solid' in geo_el: - # if Point(inside_pt).within(geo_el['solid']): - # if not isinstance(geo_el['follow'], Point): - # line = geo_el['follow'] - # - # if apval['type'] == 'C': - # aperture_size = apval['size'] - # else: - # if apval['width'] > apval['height']: - # aperture_size = apval['height'] - # else: - # aperture_size = apval['width'] - # - # if line: - # cpoly = self.fill_with_lines(line, aperture_size, - # tooldia=tooldiameter, - # steps_per_circle=self.app.defaults["geometry_circle_steps"], - # overlap=over, - # contour=cont, - # connect=conn, - # prog_plot=prog_plot) - - elif paint_method == _("Combo"): - self.app.inform.emit(_("Painting polygon with method: lines.")) - cpoly = self.clear_polygon3(polyg, - tooldia=tooldiameter, - steps_per_circle=self.app.defaults["geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - - if cpoly and cpoly.objects: - pass - else: - self.app.inform.emit(_("Failed. Painting polygon with method: seed.")) - cpoly = self.clear_polygon2(polyg, - tooldia=tooldiameter, - steps_per_circle=self.app.defaults["geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - if cpoly and cpoly.objects: - pass - else: - self.app.inform.emit(_("Failed. Painting polygon with method: standard.")) - cpoly = self.clear_polygon(polyg, - tooldia=tooldiameter, - steps_per_circle=self.app.defaults["geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - except FlatCAMApp.GracefulException: - return "fail" - except Exception as ee: - log.debug("ToolPaint.paint_poly().gen_paintarea().paint_p() --> %s" % str(ee)) - - if cpoly and cpoly.objects: - geo_obj.solid_geometry += list(cpoly.get_objects()) - return cpoly - else: - app_obj.inform.emit('[ERROR_NOTCL] %s' % _('Geometry could not be painted completely')) - return None - - current_uid = int(1) - tool_dia = None - for tool_dia in sorted_tools: - # find the tooluid associated with the current tool_dia so we know where to add the tool solid_geometry - for k, v in tools_storage.items(): - if float('%.*f' % (self.decimals, v['tooldia'])) == float('%.*f' % (self.decimals, tool_dia)): - current_uid = int(k) - break + pol_nr = 0 + # ----------------------------- + # effective polygon clearing job + # ----------------------------- try: - poly_buf = [pol.buffer(-paint_margin) for pol in polygon_list] cp = [] try: for pp in poly_buf: - cp.append(paint_p(pp, tooldiameter=tool_dia)) + geo_res = self.paint_polygon_worker(pp, tooldiameter=tool_dia, over=over, conn=conn, + cont=cont, paint_method=paint_method, obj=obj, + prog_plot=prog_plot) + if geo_res: + cp.append(geo_res) except TypeError: - cp = paint_p(poly_buf, tooldiameter=tool_dia) + geo_res = self.paint_polygon_worker(poly_buf, tooldiameter=tool_dia, over=over, conn=conn, + cont=cont, paint_method=paint_method, obj=obj, + prog_plot=prog_plot) + if geo_res: + cp.append(geo_res) total_geometry = [] if cp: - try: - for x in cp: - total_geometry += list(x.get_objects()) - except TypeError: - total_geometry = list(cp.get_objects()) + for x in cp: + total_geometry += list(x.get_objects()) + final_solid_geometry += total_geometry except FlatCAMApp.GracefulException: return "fail" except Exception as e: log.debug("Could not Paint the polygons. %s" % str(e)) - app_obj.inform.emit('[ERROR] %s\n%s' % - (_("Could not do Paint. Try a different combination of parameters. " - "Or a different strategy of paint"), - str(e) - ) - ) - return "fail" + self.app.inform.emit( + '[ERROR] %s\n%s' % + (_("Could not do Paint. Try a different combination of parameters. " + "Or a different strategy of paint"), str(e) + ) + ) + continue # add the solid_geometry to the current too in self.paint_tools (tools_storage) # dictionary and then reset the temporary list that stored that solid_geometry tools_storage[current_uid]['solid_geometry'] = deepcopy(total_geometry) - tools_storage[current_uid]['data']['name'] = name - # clean the progressive plotted shapes if it was used - if self.app.defaults["tools_paint_plotting"] == 'progressive': - self.temp_shapes.clear(update=True) + # clean the progressive plotted shapes if it was used + if self.app.defaults["tools_paint_plotting"] == 'progressive': + self.temp_shapes.clear(update=True) - # delete tools with empty geometry - # look for keys in the tools_storage dict that have 'solid_geometry' values empty - for uid in list(tools_storage.keys()): - # if the solid_geometry (type=list) is empty - if not tools_storage[uid]['solid_geometry']: - tools_storage.pop(uid, None) + # delete tools with empty geometry + # look for keys in the tools_storage dict that have 'solid_geometry' values empty + for uid in list(tools_storage.keys()): + # if the solid_geometry (type=list) is empty + if not tools_storage[uid]['solid_geometry']: + tools_storage.pop(uid, None) + + def job_init(geo_obj, app_obj): + if not tools_storage: + return 'fail' geo_obj.options["cnctooldia"] = str(tool_dia) @@ -2201,7 +2242,7 @@ class ToolPaint(FlatCAMTool, Gerber): geo_obj.tools.clear() geo_obj.tools = dict(tools_storage) - geo_obj.solid_geometry = cascaded_union(tools_storage[current_uid]['solid_geometry']) + geo_obj.solid_geometry = cascaded_union(final_solid_geometry) try: if isinstance(geo_obj.solid_geometry, list): @@ -2213,8 +2254,8 @@ class ToolPaint(FlatCAMTool, Gerber): geo_obj.options['ymin'] = b geo_obj.options['xmax'] = c geo_obj.options['ymax'] = d - except Exception as e: - log.debug("ToolPaint.paint_poly.gen_paintarea() bounds error --> %s" % str(e)) + except Exception as ee: + log.debug("ToolPaint.paint_poly.gen_paintarea() bounds error --> %s" % str(ee)) return # test if at least one tool has solid_geometry. If no tool has solid_geometry we raise an Exception @@ -2228,10 +2269,7 @@ class ToolPaint(FlatCAMTool, Gerber): _("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 - - total_geometry[:] = [] - self.app.inform.emit('[success] %s' % _("Paint Single Done.")) + return "fail" # Experimental... # print("Indexing...", end=' ') @@ -2249,19 +2287,24 @@ class ToolPaint(FlatCAMTool, Gerber): def job_thread(app_obj): try: - app_obj.new_object("geometry", name, gen_paintarea, plot=plot) + ret = app_obj.new_object("geometry", name, job_init, plot=plot) except FlatCAMApp.GracefulException: proc.done() return - except Exception as e: + except Exception as er: proc.done() - self.app.inform.emit('[ERROR_NOTCL] %s --> %s' % - ('PaintTool.paint_poly()', - str(e))) + app_obj.inform.emit('[ERROR_NOTCL] %s --> %s' % ('PaintTool.paint_poly()', str(er))) return proc.done() + + if ret == 'fail': + self.app.inform.emit('[ERROR] %s' % _("Paint Single failed.")) + return + # focus on Selected Tab - self.app.ui.notebook.setCurrentWidget(self.app.ui.selected_tab) + # self.app.ui.notebook.setCurrentWidget(self.app.ui.selected_tab) + + self.app.inform.emit('[success] %s' % _("Paint Single Done.")) self.app.inform.emit(_("Polygon Paint started ...")) @@ -2274,8 +2317,8 @@ class ToolPaint(FlatCAMTool, Gerber): else: job_thread(app_obj=self.app) - def paint_poly_all(self, obj, tooldia=None, overlap=None, order=None, margin=None, method=None, outname=None, - connect=None, contour=None, tools_storage=None, plot=True, run_threaded=True): + def paint_poly_all(self, obj, tooldia=None, order=None, method=None, outname=None, + tools_storage=None, plot=True, run_threaded=True): """ Paints all polygons in this object. @@ -2296,11 +2339,6 @@ class ToolPaint(FlatCAMTool, Gerber): """ paint_method = method if method is not None else self.paintmethod_combo.get_value() - if margin is not None: - paint_margin = margin - else: - paint_margin = float(self.paintmargin_entry.get_value()) - # determine if to use the progressive plotting if self.app.defaults["tools_paint_plotting"] == 'progressive': prog_plot = True @@ -2309,11 +2347,8 @@ class ToolPaint(FlatCAMTool, Gerber): proc = self.app.proc_container.new(_("Painting polygons...")) name = outname if outname is not None else self.obj_name + "_paint" - - over = overlap if overlap is not None else float(self.app.defaults["tools_paintoverlap"]) / 100.0 - conn = connect if connect is not None else self.app.defaults["tools_pathconnect"] - cont = contour if contour is not None else self.app.defaults["tools_paintcontour"] order = order if order is not None else self.order_radio.get_value() + tools_storage = self.paint_tools if tools_storage is None else tools_storage sorted_tools = [] if tooldia is not None: @@ -2328,10 +2363,6 @@ class ToolPaint(FlatCAMTool, Gerber): for row in range(self.tools_table.rowCount()): sorted_tools.append(float(self.tools_table.item(row, 1).text())) - if tools_storage is not None: - tools_storage = tools_storage - else: - tools_storage = self.paint_tools # This is a recursive generator of individual Polygons. # Note: Double check correct implementation. Might exit # early if it finds something that is not a Polygon? @@ -2423,8 +2454,13 @@ class ToolPaint(FlatCAMTool, Gerber): total_geometry = [] current_uid = int(1) + old_disp_number = 0 geo_obj.solid_geometry = [] + final_solid_geometry = [] + + painted_area = recurse(obj.solid_geometry) + for tool_dia in sorted_tools: log.debug("Starting geometry processing for tool: %s" % str(tool_dia)) app_obj.inform.emit( @@ -2440,523 +2476,116 @@ class ToolPaint(FlatCAMTool, Gerber): if float('%.*f' % (self.decimals, v['tooldia'])) == float('%.*f' % (self.decimals, tool_dia)): current_uid = int(k) break + if not current_uid: + return "fail" + + # determine the tool parameters to use + over = float(tools_storage[current_uid]['data']['tools_paintoverlap']) / 100.0 + conn = tools_storage[current_uid]['data']['tools_pathconnect'] + cont = tools_storage[current_uid]['data']['tools_paintcontour'] + + paint_margin = float(tools_storage[current_uid]['data']['tools_paintmargin']) + poly_buf = [] + for pol in painted_area: + buffered_pol = pol.buffer(-paint_margin) + if buffered_pol and not buffered_pol.is_empty: + poly_buf.append(buffered_pol) + + if not poly_buf: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Margin parameter too big. Tool is not used")) + continue - painted_area = recurse(obj.solid_geometry) # variables to display the percentage of work done - geo_len = len(painted_area) + geo_len = len(poly_buf) - old_disp_number = 0 log.warning("Total number of polygons to be cleared. %s" % str(geo_len)) pol_nr = 0 - for geo in painted_area: - # provide the app with a way to process the GUI events when in a blocking loop - QtWidgets.QApplication.processEvents() + # ----------------------------- + # effective polygon clearing job + # ----------------------------- + poly_processed = [] - if self.app.abort_flag: - # graceful abort requested by the user - raise FlatCAMApp.GracefulException + try: + cp = [] + geo_res = None + try: + for pp in poly_buf: - # try to clean the Polygon but it may result into a MultiPolygon - geo = geo.buffer(0) - poly_buf = geo.buffer(-paint_margin) + # provide the app with a way to process the GUI events when in a blocking loop + QtWidgets.QApplication.processEvents() + if self.app.abort_flag: + # graceful abort requested by the user + raise FlatCAMApp.GracefulException - if geo is not None and geo.is_valid: - poly_processed = [] - try: - for pol in poly_buf: - if pol is not None and isinstance(pol, Polygon): - cp = None - if paint_method == _("Standard"): - cp = self.clear_polygon(pol, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, + geo_res = self.paint_polygon_worker(pp, tooldiameter=tool_dia, over=over, conn=conn, + cont=cont, paint_method=paint_method, obj=obj, prog_plot=prog_plot) - elif paint_method == _("Seed"): - cp = self.clear_polygon2(pol, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - elif paint_method == _("Lines"): - cp = self.clear_polygon3(pol, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - elif paint_method == _("Laser_lines"): - # line = None - # aperture_size = None - - # the key is the aperture type and the val is a list of geo elements - flash_el_dict = {} - # the key is the aperture size, the val is a list of geo elements - traces_el_dict = {} - - # find the flashes and the lines that are in the selected polygon and store - # them separately - for apid, apval in obj.apertures.items(): - for geo_el in apval['geometry']: - if apval["size"] == 0.0: - if apval["size"] in traces_el_dict: - traces_el_dict[apval["size"]].append(geo_el) - else: - traces_el_dict[apval["size"]] = [geo_el] - - if 'follow' in geo_el and geo_el['follow'].within(pol): - if isinstance(geo_el['follow'], Point): - if apval["type"] == 'C': - if 'C' in flash_el_dict: - flash_el_dict['C'].append(geo_el) - else: - flash_el_dict['C'] = [geo_el] - elif apval["type"] == 'O': - if 'O' in flash_el_dict: - flash_el_dict['O'].append(geo_el) - else: - flash_el_dict['O'] = [geo_el] - elif apval["type"] == 'R': - if 'R' in flash_el_dict: - flash_el_dict['R'].append(geo_el) - else: - flash_el_dict['R'] = [geo_el] - else: - aperture_size = apval['size'] - - if aperture_size in traces_el_dict: - traces_el_dict[aperture_size].append(geo_el) - else: - traces_el_dict[aperture_size] = [geo_el] - - cp = FlatCAMRTreeStorage() - pads_lines_list = [] - - # process the flashes found in the selected polygon with the 'lines' method - # for rectangular flashes and with _("Seed") for oblong and circular flashes - # and pads (flahes) need the contour therefore I override the GUI settings - # with always True - for ap_type in flash_el_dict: - for elem in flash_el_dict[ap_type]: - if 'solid' in elem: - if ap_type == 'C': - f_o = self.clear_polygon2(elem['solid'], - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=True, - connect=conn, - prog_plot=prog_plot) - pads_lines_list += [p for p in f_o.get_objects() if p] - - elif ap_type == 'O': - f_o = self.clear_polygon2(elem['solid'], - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=True, - connect=conn, - prog_plot=prog_plot) - pads_lines_list += [p for p in f_o.get_objects() if p] - - elif ap_type == 'R': - f_o = self.clear_polygon3(elem['solid'], - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=True, - connect=conn, - prog_plot=prog_plot) - - pads_lines_list += [p for p in f_o.get_objects() if p] - - # add the lines from pads to the storage - try: - for lin in pads_lines_list: - if lin: - cp.insert(lin) - except TypeError: - cp.insert(pads_lines_list) - - copper_lines_list = [] - # process the traces found in the selected polygon using the 'laser_lines' - # method, method which will follow the 'follow' line therefore use the longer - # path possible for the laser, therefore the acceleration will play - # a smaller factor - for aperture_size in traces_el_dict: - for elem in traces_el_dict[aperture_size]: - line = elem['follow'] - if line: - t_o = self.fill_with_lines(line, aperture_size, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - - copper_lines_list += [p for p in t_o.get_objects() if p] - - # add the lines from copper features to storage but first try to make as few - # lines as possible - # by trying to fuse them - lines_union = linemerge(unary_union(copper_lines_list)) - try: - for lin in lines_union: - if lin: - cp.insert(lin) - except TypeError: - cp.insert(lines_union) - elif paint_method == _("Combo"): - self.app.inform.emit(_("Painting polygons with method: lines.")) - cp = self.clear_polygon3(pol, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - - if cp and cp.objects: - pass - else: - self.app.inform.emit(_("Failed. Painting polygons with method: seed.")) - cp = self.clear_polygon2(pol, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - if cp and cp.objects: - pass - else: - self.app.inform.emit( - _("Failed. Painting polygons with method: standard.")) - - cp = self.clear_polygon(pol, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - if cp and cp.objects: - total_geometry += list(cp.get_objects()) - poly_processed.append(True) - else: - poly_processed.append(False) - log.warning("Polygon in MultiPolygon can not be cleared.") - else: - log.warning("Geo in Iterable can not be cleared because it is not Polygon. " - "It is: %s" % str(type(pol))) - except TypeError: - if isinstance(poly_buf, Polygon): - cp = None - if paint_method == _("Standard"): - cp = self.clear_polygon(poly_buf, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - elif paint_method == _("Seed"): - cp = self.clear_polygon2(poly_buf, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - elif paint_method == _("Lines"): - cp = self.clear_polygon3(poly_buf, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - elif paint_method == _("Laser_lines"): - # line = None - # aperture_size = None - - # the key is the aperture type and the val is a list of geo elements - flash_el_dict = {} - # the key is the aperture size, the val is a list of geo elements - traces_el_dict = {} - - # find the flashes and the lines that are in the selected polygon and store - # them separately - for apid, apval in obj.apertures.items(): - for geo_el in apval['geometry']: - if apval["size"] == 0.0: - if apval["size"] in traces_el_dict: - traces_el_dict[apval["size"]].append(geo_el) - else: - traces_el_dict[apval["size"]] = [geo_el] - - if 'follow' in geo_el and geo_el['follow'].within(poly_buf): - if isinstance(geo_el['follow'], Point): - if apval["type"] == 'C': - if 'C' in flash_el_dict: - flash_el_dict['C'].append(geo_el) - else: - flash_el_dict['C'] = [geo_el] - elif apval["type"] == 'O': - if 'O' in flash_el_dict: - flash_el_dict['O'].append(geo_el) - else: - flash_el_dict['O'] = [geo_el] - elif apval["type"] == 'R': - if 'R' in flash_el_dict: - flash_el_dict['R'].append(geo_el) - else: - flash_el_dict['R'] = [geo_el] - else: - aperture_size = apval['size'] - - if aperture_size in traces_el_dict: - traces_el_dict[aperture_size].append(geo_el) - else: - traces_el_dict[aperture_size] = [geo_el] - - cp = FlatCAMRTreeStorage() - pads_lines_list = [] - - # process the flashes found in the selected polygon with the 'lines' method - # for rectangular flashes and with _("Seed") for oblong and circular flashes - # and pads (flahes) need the contour therefore I override the GUI settings - # with always True - for ap_type in flash_el_dict: - for elem in flash_el_dict[ap_type]: - if 'solid' in elem: - if ap_type == 'C': - f_o = self.clear_polygon2(elem['solid'], - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=True, - connect=conn, - prog_plot=prog_plot) - pads_lines_list += [p for p in f_o.get_objects() if p] - - elif ap_type == 'O': - f_o = self.clear_polygon2(elem['solid'], - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=True, - connect=conn, - prog_plot=prog_plot) - pads_lines_list += [p for p in f_o.get_objects() if p] - - elif ap_type == 'R': - f_o = self.clear_polygon3(elem['solid'], - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=True, - connect=conn, - prog_plot=prog_plot) - - pads_lines_list += [p for p in f_o.get_objects() if p] - - # add the lines from pads to the storage - try: - for lin in pads_lines_list: - if lin: - cp.insert(lin) - except TypeError: - cp.insert(pads_lines_list) - - copper_lines_list = [] - # process the traces found in the selected polygon using the 'laser_lines' - # method, method which will follow the 'follow' line therefore use the longer - # path possible for the laser, therefore the acceleration will play - # a smaller factor - for aperture_size in traces_el_dict: - for elem in traces_el_dict[aperture_size]: - line = elem['follow'] - if line: - t_o = self.fill_with_lines(line, aperture_size, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - - copper_lines_list += [p for p in t_o.get_objects() if p] - - # add the lines from copper features to storage but first try to make as few - # lines as possible - # by trying to fuse them - lines_union = linemerge(unary_union(copper_lines_list)) - try: - for lin in lines_union: - if lin: - cp.insert(lin) - except TypeError: - cp.insert(lines_union) - elif paint_method == _("Combo"): - self.app.inform.emit(_("Painting polygons with method: lines.")) - cp = self.clear_polygon3(poly_buf, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - - if cp and cp.objects: - pass - else: - self.app.inform.emit(_("Failed. Painting polygons with method: seed.")) - cp = self.clear_polygon2(poly_buf, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - if cp and cp.objects: - pass - else: - self.app.inform.emit(_("Failed. Painting polygons with method: standard.")) - cp = self.clear_polygon(poly_buf, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - if cp: - total_geometry += list(cp.get_objects()) - poly_processed.append(True) - else: - poly_processed.append(False) - log.warning("Polygon can not be cleared.") + if geo_res: + cp.append(geo_res) + poly_processed.append(True) else: - log.warning("Geo can not be cleared because it is: %s" % str(type(poly_buf))) + poly_processed.append(False) + except TypeError: + # provide the app with a way to process the GUI events when in a blocking loop + QtWidgets.QApplication.processEvents() + if self.app.abort_flag: + # graceful abort requested by the user + raise FlatCAMApp.GracefulException - p_cleared = poly_processed.count(True) - p_not_cleared = poly_processed.count(False) + geo_res = self.paint_polygon_worker(poly_buf, tooldiameter=tool_dia, over=over, conn=conn, + cont=cont, paint_method=paint_method, obj=obj, + prog_plot=prog_plot) + if geo_res: + cp.append(geo_res) + poly_processed.append(True) + else: + poly_processed.append(False) - if p_not_cleared: - app_obj.poly_not_cleared = True + total_geometry = [] + if cp: + for x in cp: + total_geometry += list(x.get_objects()) + final_solid_geometry += total_geometry - if p_cleared == 0: - continue + pol_nr += 1 + disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100])) + # log.debug("Polygons cleared: %d" % pol_nr) - # try: - # # Polygons are the only really paintable geometries, - # # lines in theory have no area to be painted - # if not isinstance(geo, Polygon): - # continue - # poly_buf = geo.buffer(-paint_margin) - # - # if paint_method == _("Seed"): - # # Type(cp) == FlatCAMRTreeStorage | None - # cp = self.clear_polygon2(poly_buf, - # tooldia=tool_dia, - # steps_per_circle=self.app.defaults["geometry_circle_steps"], - # overlap=over, - # contour=cont, - # connect=conn, - # prog_plot=prog_plot) - # - # elif paint_method == _("Lines"): - # # Type(cp) == FlatCAMRTreeStorage | None - # cp = self.clear_polygon3(poly_buf, - # tooldia=tool_dia, - # steps_per_circle=self.app.defaults["geometry_circle_steps"], - # overlap=over, - # contour=cont, - # connect=conn, - # prog_plot=prog_plot) - # - # else: - # # Type(cp) == FlatCAMRTreeStorage | None - # cp = self.clear_polygon(poly_buf, - # tooldia=tool_dia, - # steps_per_circle=self.app.defaults["geometry_circle_steps"], - # overlap=over, - # contour=cont, - # connect=conn, - # prog_plot=prog_plot) - # - # if cp is not None: - # total_geometry += list(cp.get_objects()) - # except FlatCAMApp.GracefulException: - # return "fail" - # except Exception as e: - # log.debug("Could not Paint the polygons. %s" % str(e)) - # self.app.inform.emit('[ERROR] %s\n%s' % - # (_("Could not do Paint All. Try a different combination of parameters. " - # "Or a different Method of paint"), - # str(e))) - # return "fail" + if old_disp_number < disp_number <= 100: + app_obj.proc_container.update_view_text(' %d%%' % disp_number) + old_disp_number = disp_number + # log.debug("Polygons cleared: %d. Percentage done: %d%%" % (pol_nr, disp_number)) - pol_nr += 1 - disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100])) - # log.debug("Polygons cleared: %d" % pol_nr) + except Exception as err: + log.debug("Could not Paint the polygons. %s" % str(err)) + self.app.inform.emit( + '[ERROR] %s\n%s' % + (_("Could not do Paint. Try a different combination of parameters. " + "Or a different strategy of paint"), str(err) + ) + ) + continue - if old_disp_number < disp_number <= 100: - app_obj.proc_container.update_view_text(' %d%%' % disp_number) - old_disp_number = disp_number - # log.debug("Polygons cleared: %d. Percentage done: %d%%" % (pol_nr, disp_number)) + p_cleared = poly_processed.count(True) + p_not_cleared = poly_processed.count(False) + + if p_not_cleared: + app_obj.poly_not_cleared = True + + if p_cleared == 0: + continue # add the solid_geometry to the current too in self.paint_tools (tools_storage) # dictionary and then reset the temporary list that stored that solid_geometry tools_storage[current_uid]['solid_geometry'] = deepcopy(total_geometry) - tools_storage[current_uid]['data']['name'] = name - total_geometry[:] = [] # clean the progressive plotted shapes if it was used if self.app.defaults["tools_paint_plotting"] == 'progressive': self.temp_shapes.clear(update=True) - # # delete tools with empty geometry - # keys_to_delete = [] - # # look for keys in the tools_storage dict that have 'solid_geometry' values empty - # for uid in tools_storage: - # # if the solid_geometry (type=list) is empty - # if not tools_storage[uid]['solid_geometry']: - # keys_to_delete.append(uid) - # - # # actual delete of keys from the tools_storage dict - # for k in keys_to_delete: - # tools_storage.pop(k, None) - # delete tools with empty geometry # look for keys in the tools_storage dict that have 'solid_geometry' values empty for uid in list(tools_storage.keys()): @@ -2964,6 +2593,9 @@ class ToolPaint(FlatCAMTool, Gerber): if not tools_storage[uid]['solid_geometry']: tools_storage.pop(uid, None) + if not tools_storage: + return 'fail' + geo_obj.options["cnctooldia"] = str(tool_dia) # this turn on the FlatCAMCNCJob plot for multiple tools geo_obj.multigeo = True @@ -2971,6 +2603,8 @@ class ToolPaint(FlatCAMTool, Gerber): geo_obj.tools.clear() geo_obj.tools = dict(tools_storage) + geo_obj.solid_geometry = cascaded_union(final_solid_geometry) + # test if at least one tool has solid_geometry. If no tool has solid_geometry we raise an Exception has_solid_geo = 0 for tooluid in geo_obj.tools: @@ -2981,7 +2615,7 @@ class ToolPaint(FlatCAMTool, Gerber): _("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 + return "fail" # Experimental... # print("Indexing...", end=' ') @@ -2991,8 +2625,8 @@ class ToolPaint(FlatCAMTool, Gerber): # Initializes the new geometry object def gen_paintarea_rest_machining(geo_obj, app_obj): - assert isinstance(geo_obj, FlatCAMGeometry), \ - "Initializer expected a FlatCAMGeometry, got %s" % type(geo_obj) + # assert isinstance(geo_obj, FlatCAMGeometry), \ + # "Initializer expected a FlatCAMGeometry, got %s" % type(geo_obj) log.debug("Paint Tool. Rest machining painting all task started.") if isinstance(obj, FlatCAMGerber): @@ -3010,10 +2644,6 @@ class ToolPaint(FlatCAMTool, Gerber): tool_dia = None sorted_tools.sort(reverse=True) - cleared_geo = [] - current_uid = int(1) - geo_obj.solid_geometry = [] - if isinstance(obj, FlatCAMGerber): if self.app.defaults["tools_paint_plotting"] == 'progressive': if isinstance(obj.solid_geometry, list): @@ -3031,6 +2661,14 @@ class ToolPaint(FlatCAMTool, Gerber): log.debug("ToolPaint.paint_poly.gen_paintarea() bounds error --> %s" % str(e)) return + cleared_geo = [] + current_uid = int(1) + geo_obj.solid_geometry = [] + final_solid_geometry = [] + old_disp_number = 0 + + painted_area = recurse(obj.solid_geometry) + for tool_dia in sorted_tools: log.debug("Starting geometry processing for tool: %s" % str(tool_dia)) app_obj.inform.emit( @@ -3041,37 +2679,57 @@ class ToolPaint(FlatCAMTool, Gerber): ) app_obj.proc_container.update_view_text(' %d%%' % 0) - painted_area = recurse(obj.solid_geometry) - # variables to display the percentage of work done - geo_len = int(len(painted_area) / 100) + # find the tooluid associated with the current tool_dia so we know where to add the tool solid_geometry + for k, v in tools_storage.items(): + if float('%.*f' % (self.decimals, v['tooldia'])) == float('%.*f' % (self.decimals, tool_dia)): + current_uid = int(k) + break + if not current_uid: + return "fail" + + # determine the tool parameters to use + over = float(tools_storage[current_uid]['data']['tools_paintoverlap']) / 100.0 + conn = tools_storage[current_uid]['data']['tools_pathconnect'] + cont = tools_storage[current_uid]['data']['tools_paintcontour'] + + paint_margin = float(tools_storage[current_uid]['data']['tools_paintmargin']) + poly_buf = [] + for pol in painted_area: + pol = Polygon(pol) if not isinstance(pol, Polygon) else pol + buffered_pol = pol.buffer(-paint_margin) + if buffered_pol and not buffered_pol.is_empty: + poly_buf.append(buffered_pol) + + if not poly_buf: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Margin parameter too big. Tool is not used")) + continue + + # variables to display the percentage of work done + geo_len = len(poly_buf) - old_disp_number = 0 log.warning("Total number of polygons to be cleared. %s" % str(geo_len)) pol_nr = 0 - for geo in painted_area: + + for geo in poly_buf: try: - geo = Polygon(geo) if not isinstance(geo, Polygon) else geo - poly_buf = geo.buffer(-paint_margin) cp = None if paint_method == _("Standard"): # Type(cp) == FlatCAMRTreeStorage | None - cp = self.clear_polygon(poly_buf, tooldia=tool_dia, + cp = self.clear_polygon(geo, tooldia=tool_dia, steps_per_circle=self.app.defaults["geometry_circle_steps"], overlap=over, contour=cont, connect=conn, prog_plot=prog_plot) - elif paint_method == _("Seed"): # Type(cp) == FlatCAMRTreeStorage | None - cp = self.clear_polygon2(poly_buf, tooldia=tool_dia, + cp = self.clear_polygon2(geo, tooldia=tool_dia, steps_per_circle=self.app.defaults["geometry_circle_steps"], overlap=over, contour=cont, connect=conn, prog_plot=prog_plot) - elif paint_method == _("Lines"): # Type(cp) == FlatCAMRTreeStorage | None - cp = self.clear_polygon3(poly_buf, tooldia=tool_dia, + cp = self.clear_polygon3(geo, tooldia=tool_dia, steps_per_circle=self.app.defaults["geometry_circle_steps"], overlap=over, contour=cont, connect=conn, prog_plot=prog_plot) @@ -3094,7 +2752,7 @@ class ToolPaint(FlatCAMTool, Gerber): else: traces_el_dict[apval["size"]] = [geo_el] - if 'follow' in geo_el and geo_el['follow'].within(poly_buf): + if 'follow' in geo_el and geo_el['follow'].within(geo): if isinstance(geo_el['follow'], Point): if apval["type"] == 'C': if 'C' in flash_el_dict: @@ -3203,7 +2861,7 @@ class ToolPaint(FlatCAMTool, Gerber): cp.insert(lines_union) elif paint_method == _("Combo"): self.app.inform.emit(_("Painting polygons with method: lines.")) - cp = self.clear_polygon3(poly_buf, + cp = self.clear_polygon3(geo, tooldia=tool_dia, steps_per_circle=self.app.defaults[ "geometry_circle_steps"], @@ -3216,7 +2874,7 @@ class ToolPaint(FlatCAMTool, Gerber): pass else: self.app.inform.emit(_("Failed. Painting polygons with method: seed.")) - cp = self.clear_polygon2(poly_buf, + cp = self.clear_polygon2(geo, tooldia=tool_dia, steps_per_circle=self.app.defaults[ "geometry_circle_steps"], @@ -3228,7 +2886,7 @@ class ToolPaint(FlatCAMTool, Gerber): pass else: self.app.inform.emit(_("Failed. Painting polygons with method: standard.")) - cp = self.clear_polygon(poly_buf, + cp = self.clear_polygon(geo, tooldia=tool_dia, steps_per_circle=self.app.defaults[ "geometry_circle_steps"], @@ -3258,19 +2916,27 @@ class ToolPaint(FlatCAMTool, Gerber): old_disp_number = disp_number # log.debug("Polygons cleared: %d. Percentage done: %d%%" % (pol_nr, disp_number)) - # find the tooluid associated with the current tool_dia so we know where to add the tool solid_geometry - for k, v in tools_storage.items(): - if float('%.*f' % (self.decimals, v['tooldia'])) == float('%.*f' % (self.decimals, tool_dia)): - current_uid = int(k) - break - + final_solid_geometry += cleared_geo # add the solid_geometry to the current too in self.paint_tools (or tools_storage) dictionary and # then reset the temporary list that stored that solid_geometry tools_storage[current_uid]['solid_geometry'] = deepcopy(cleared_geo) - tools_storage[current_uid]['data']['name'] = name cleared_geo[:] = [] + # clean the progressive plotted shapes if it was used + if self.app.defaults["tools_paint_plotting"] == 'progressive': + self.temp_shapes.clear(update=True) + + # delete tools with empty geometry + # look for keys in the tools_storage dict that have 'solid_geometry' values empty + for uid in list(tools_storage.keys()): + # if the solid_geometry (type=list) is empty + if not tools_storage[uid]['solid_geometry']: + tools_storage.pop(uid, None) + + if not tools_storage: + return 'fail' + geo_obj.options["cnctooldia"] = str(tool_dia) # this turn on the FlatCAMCNCJob plot for multiple tools geo_obj.multigeo = True @@ -3278,9 +2944,7 @@ class ToolPaint(FlatCAMTool, Gerber): geo_obj.tools.clear() geo_obj.tools = dict(tools_storage) - # clean the progressive plotted shapes if it was used - if self.app.defaults["tools_paint_plotting"] == 'progressive': - self.temp_shapes.clear(update=True) + geo_obj.solid_geometry = cascaded_union(final_solid_geometry) # test if at least one tool has solid_geometry. If no tool has solid_geometry we raise an Exception has_solid_geo = 0 @@ -3328,18 +2992,8 @@ class ToolPaint(FlatCAMTool, Gerber): else: job_thread(app_obj=self.app) - def paint_poly_area(self, obj, sel_obj, - tooldia=None, - overlap=None, - order=None, - margin=None, - method=None, - outname=None, - connect=None, - contour=None, - tools_storage=None, - plot=True, - run_threaded=True): + def paint_poly_area(self, obj, sel_obj, tooldia=None, order=None, method=None, + outname=None, tools_storage=None, plot=True, run_threaded=True): """ Paints all polygons in this object that are within the sel_obj object @@ -3361,20 +3015,6 @@ class ToolPaint(FlatCAMTool, Gerber): """ paint_method = method if method is not None else self.paintmethod_combo.get_value() - if margin is not None: - paint_margin = margin - else: - try: - paint_margin = float(self.paintmargin_entry.get_value()) - except ValueError: - # try to convert comma to decimal point. if it's still not working error message and return - try: - paint_margin = float(self.paintmargin_entry.get_value().replace(',', '.')) - except ValueError: - self.app.inform.emit('[ERROR_NOTCL] %s' % - _("Wrong value format entered, use a number.")) - return - # determine if to use the progressive plotting if self.app.defaults["tools_paint_plotting"] == 'progressive': prog_plot = True @@ -3383,11 +3023,8 @@ class ToolPaint(FlatCAMTool, Gerber): proc = self.app.proc_container.new(_("Painting polygons...")) name = outname if outname is not None else self.obj_name + "_paint" - - over = overlap if overlap is not None else float(self.app.defaults["tools_paintoverlap"]) / 100.0 - conn = connect if connect is not None else self.app.defaults["tools_pathconnect"] - cont = contour if contour is not None else self.app.defaults["tools_paintcontour"] order = order if order is not None else self.order_radio.get_value() + tools_storage = self.paint_tools if tools_storage is None else tools_storage sorted_tools = [] if tooldia is not None: @@ -3402,11 +3039,6 @@ class ToolPaint(FlatCAMTool, Gerber): for row in range(self.tools_table.rowCount()): sorted_tools.append(float(self.tools_table.item(row, 1).text())) - if tools_storage is not None: - tools_storage = tools_storage - else: - tools_storage = self.paint_tools - def recurse(geometry, reset=True): """ Creates a list of non-iterable linear geometry objects. @@ -3449,16 +3081,13 @@ class ToolPaint(FlatCAMTool, Gerber): log.debug("Paint Tool. Normal painting area task started.") if isinstance(obj, FlatCAMGerber): if app_obj.defaults["gerber_buffering"] == 'no': - app_obj.inform.emit('%s %s %s' % - (_("Paint Tool."), - _("Normal painting area task started."), + app_obj.inform.emit('%s %s' % + (_("Paint Tool. Normal painting area task started."), _("Buffering geometry..."))) else: - app_obj.inform.emit('%s %s' % - (_("Paint Tool."), _("Normal painting area task started."))) + app_obj.inform.emit(_("Paint Tool. Normal painting area task started.")) else: - app_obj.inform.emit('%s %s' % - (_("Paint Tool."), _("Normal painting area task started."))) + app_obj.inform.emit(_("Paint Tool. Normal painting area task started.")) tool_dia = None if order == 'fwd': @@ -3478,8 +3107,8 @@ class ToolPaint(FlatCAMTool, Gerber): else: target_geo = target_geo.buffer(0) - geo_to_paint = target_geo.intersection(sel_obj) + geo_to_paint = target_geo.intersection(sel_obj) painted_area = recurse(geo_to_paint) try: @@ -3496,6 +3125,9 @@ class ToolPaint(FlatCAMTool, Gerber): current_uid = int(1) geo_obj.solid_geometry = [] + final_solid_geometry = [] + old_disp_number = 0 + for tool_dia in sorted_tools: log.debug("Starting geometry processing for tool: %s" % str(tool_dia)) app_obj.inform.emit( @@ -3512,23 +3144,42 @@ class ToolPaint(FlatCAMTool, Gerber): current_uid = int(k) break + if not current_uid: + return "fail" + + # determine the tool parameters to use + over = float(tools_storage[current_uid]['data']['tools_paintoverlap']) / 100.0 + conn = tools_storage[current_uid]['data']['tools_pathconnect'] + cont = tools_storage[current_uid]['data']['tools_paintcontour'] + + paint_margin = float(tools_storage[current_uid]['data']['tools_paintmargin']) + poly_buf = [] + for pol in painted_area: + buffered_pol = pol.buffer(-paint_margin) + if buffered_pol and not buffered_pol.is_empty: + poly_buf.append(buffered_pol) + + if not poly_buf: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Margin parameter too big. Tool is not used")) + continue + # variables to display the percentage of work done - geo_len = len(painted_area) - old_disp_number = 0 + geo_len = len(poly_buf) + log.warning("Total number of polygons to be cleared. %s" % str(geo_len)) pol_nr = 0 - for geo in painted_area: + + for geo in poly_buf: try: # Polygons are the only really paintable geometries, lines in theory have no area to be painted if not isinstance(geo, Polygon): continue - poly_buf = geo.buffer(-paint_margin) cp = None if paint_method == _("Seed"): # Type(cp) == FlatCAMRTreeStorage | None - cp = self.clear_polygon2(poly_buf, + cp = self.clear_polygon2(geo, tooldia=tool_dia, steps_per_circle=self.app.defaults["geometry_circle_steps"], overlap=over, @@ -3538,7 +3189,7 @@ class ToolPaint(FlatCAMTool, Gerber): elif paint_method == _("Lines"): # Type(cp) == FlatCAMRTreeStorage | None - cp = self.clear_polygon3(poly_buf, + cp = self.clear_polygon3(geo, tooldia=tool_dia, steps_per_circle=self.app.defaults["geometry_circle_steps"], overlap=over, @@ -3548,7 +3199,7 @@ class ToolPaint(FlatCAMTool, Gerber): elif paint_method == _("Standard"): # Type(cp) == FlatCAMRTreeStorage | None - cp = self.clear_polygon(poly_buf, + cp = self.clear_polygon(geo, tooldia=tool_dia, steps_per_circle=self.app.defaults["geometry_circle_steps"], overlap=over, @@ -3574,7 +3225,7 @@ class ToolPaint(FlatCAMTool, Gerber): else: traces_el_dict[apval["size"]] = [geo_el] - if 'follow' in geo_el and geo_el['follow'].within(poly_buf): + if 'follow' in geo_el and geo_el['follow'].within(geo): if isinstance(geo_el['follow'], Point): if apval["type"] == 'C': if 'C' in flash_el_dict: @@ -3683,7 +3334,7 @@ class ToolPaint(FlatCAMTool, Gerber): cp.insert(lines_union) elif paint_method == _("Combo"): self.app.inform.emit(_("Painting polygons with method: lines.")) - cp = self.clear_polygon3(poly_buf, + cp = self.clear_polygon3(geo, tooldia=tool_dia, steps_per_circle=self.app.defaults[ "geometry_circle_steps"], @@ -3696,7 +3347,7 @@ class ToolPaint(FlatCAMTool, Gerber): pass else: self.app.inform.emit(_("Failed. Painting polygons with method: seed.")) - cp = self.clear_polygon2(poly_buf, + cp = self.clear_polygon2(geo, tooldia=tool_dia, steps_per_circle=self.app.defaults[ "geometry_circle_steps"], @@ -3708,7 +3359,7 @@ class ToolPaint(FlatCAMTool, Gerber): pass else: self.app.inform.emit(_("Failed. Painting polygons with method: standard.")) - cp = self.clear_polygon(poly_buf, + cp = self.clear_polygon(geo, tooldia=tool_dia, steps_per_circle=self.app.defaults[ "geometry_circle_steps"], @@ -3718,14 +3369,18 @@ class ToolPaint(FlatCAMTool, Gerber): prog_plot=prog_plot) if cp and cp.objects: total_geometry += list(cp.get_objects()) + final_solid_geometry += total_geometry except FlatCAMApp.GracefulException: return "fail" - except Exception as e: - log.debug("Could not Paint the polygons. %s" % str(e)) - self.app.inform.emit('[ERROR] %s\n%s' % - (_("Could not do Paint All. Try a different combination of parameters. " - "Or a different Method of paint"), str(e))) - return + except Exception as err: + log.debug("Could not Paint the polygons. %s" % str(err)) + self.app.inform.emit( + '[ERROR] %s\n%s' % + (_("Could not do Paint. Try a different combination of parameters. " + "Or a different strategy of paint"), str(err) + ) + ) + continue pol_nr += 1 disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100])) @@ -3739,7 +3394,6 @@ class ToolPaint(FlatCAMTool, Gerber): # add the solid_geometry to the current too in self.paint_tools (tools_storage) # dictionary and then reset the temporary list that stored that solid_geometry tools_storage[current_uid]['solid_geometry'] = deepcopy(total_geometry) - tools_storage[current_uid]['data']['name'] = name total_geometry[:] = [] @@ -3748,16 +3402,14 @@ class ToolPaint(FlatCAMTool, Gerber): self.temp_shapes.clear(update=True) # delete tools with empty geometry - keys_to_delete = [] # look for keys in the tools_storage dict that have 'solid_geometry' values empty - for uid in tools_storage: + for uid in list(tools_storage.keys()): # if the solid_geometry (type=list) is empty if not tools_storage[uid]['solid_geometry']: - keys_to_delete.append(uid) + tools_storage.pop(uid, None) - # actual delete of keys from the tools_storage dict - for k in keys_to_delete: - tools_storage.pop(k, None) + if not tools_storage: + return 'fail' geo_obj.options["cnctooldia"] = str(tool_dia) # this turn on the FlatCAMCNCJob plot for multiple tools @@ -3766,6 +3418,8 @@ class ToolPaint(FlatCAMTool, Gerber): geo_obj.tools.clear() geo_obj.tools = dict(tools_storage) + geo_obj.solid_geometry = cascaded_union(final_solid_geometry) + # test if at least one tool has solid_geometry. If no tool has solid_geometry we raise an Exception has_solid_geo = 0 for tooluid in geo_obj.tools: @@ -3786,18 +3440,18 @@ class ToolPaint(FlatCAMTool, Gerber): # Initializes the new geometry object def gen_paintarea_rest_machining(geo_obj, app_obj): - assert isinstance(geo_obj, FlatCAMGeometry), \ - "Initializer expected a FlatCAMGeometry, got %s" % type(geo_obj) + # assert isinstance(geo_obj, FlatCAMGeometry), \ + # "Initializer expected a FlatCAMGeometry, got %s" % type(geo_obj) log.debug("Paint Tool. Rest machining painting area task started.") if isinstance(obj, FlatCAMGerber): if app_obj.defaults["gerber_buffering"] == 'no': app_obj.inform.emit('%s %s %s' % - (_("Paint Tool."), - _("Rest machining painting area task started."), + (_("Paint Tool."), _("Rest machining painting area task started."), _("Buffering geometry..."))) else: - app_obj.inform.emit(_("Paint Tool. Rest machining painting area task started.")) + app_obj.inform.emit('%s %s' % + (_("Paint Tool."), _("Rest machining painting area task started."))) else: app_obj.inform.emit('%s %s' % (_("Paint Tool."), _("Rest machining painting area task started."))) @@ -3808,6 +3462,8 @@ class ToolPaint(FlatCAMTool, Gerber): cleared_geo = [] current_uid = int(1) geo_obj.solid_geometry = [] + final_solid_geometry = [] + old_disp_number = 0 # this is were heavy lifting is done and creating the geometry to be painted target_geo = obj.solid_geometry @@ -3820,7 +3476,6 @@ class ToolPaint(FlatCAMTool, Gerber): target_geo = target_geo.buffer(0) geo_to_paint = target_geo.intersection(sel_obj) - painted_area = recurse(geo_to_paint) try: @@ -3843,35 +3498,61 @@ class ToolPaint(FlatCAMTool, Gerber): ) app_obj.proc_container.update_view_text(' %d%%' % 0) + # find the tooluid associated with the current tool_dia so we know where to add the tool solid_geometry + for k, v in tools_storage.items(): + if float('%.*f' % (self.decimals, v['tooldia'])) == float('%.*f' % (self.decimals, tool_dia)): + current_uid = int(k) + break + + if not current_uid: + return "fail" + + painted_area = recurse(obj.solid_geometry) + + # determine the tool parameters to use + over = float(tools_storage[current_uid]['data']['tools_paintoverlap']) / 100.0 + conn = tools_storage[current_uid]['data']['tools_pathconnect'] + cont = tools_storage[current_uid]['data']['tools_paintcontour'] + + paint_margin = float(tools_storage[current_uid]['data']['tools_paintmargin']) + poly_buf = [] + for pol in painted_area: + pol = Polygon(pol) if not isinstance(pol, Polygon) else pol + buffered_pol = pol.buffer(-paint_margin) + if buffered_pol and not buffered_pol.is_empty: + poly_buf.append(buffered_pol) + + if not poly_buf: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Margin parameter too big. Tool is not used")) + continue + # variables to display the percentage of work done - geo_len = len(painted_area) - old_disp_number = 0 + geo_len = len(poly_buf) + log.warning("Total number of polygons to be cleared. %s" % str(geo_len)) pol_nr = 0 - for geo in painted_area: + + + for geo in poly_buf: try: - geo = Polygon(geo) if not isinstance(geo, Polygon) else geo - poly_buf = geo.buffer(-paint_margin) cp = None if paint_method == _("Standard"): # Type(cp) == FlatCAMRTreeStorage | None - cp = self.clear_polygon(poly_buf, tooldia=tool_dia, + cp = self.clear_polygon(geo, tooldia=tool_dia, steps_per_circle=self.app.defaults["geometry_circle_steps"], overlap=over, contour=cont, connect=conn, prog_plot=prog_plot) - elif paint_method == _("Seed"): # Type(cp) == FlatCAMRTreeStorage | None - cp = self.clear_polygon2(poly_buf, tooldia=tool_dia, + cp = self.clear_polygon2(geo, tooldia=tool_dia, steps_per_circle=self.app.defaults["geometry_circle_steps"], overlap=over, contour=cont, connect=conn, prog_plot=prog_plot) - elif paint_method == _("Lines"): # Type(cp) == FlatCAMRTreeStorage | None - cp = self.clear_polygon3(poly_buf, tooldia=tool_dia, + cp = self.clear_polygon3(geo, tooldia=tool_dia, steps_per_circle=self.app.defaults["geometry_circle_steps"], overlap=over, contour=cont, connect=conn, prog_plot=prog_plot) @@ -3894,7 +3575,7 @@ class ToolPaint(FlatCAMTool, Gerber): else: copper_el_dict[apval["size"]] = [geo_el] - if 'follow' in geo_el and geo_el['follow'].within(poly_buf): + if 'follow' in geo_el and geo_el['follow'].within(geo): if isinstance(geo_el['follow'], Point): if apval["type"] == 'C': if 'C' in flash_el_dict: @@ -4003,7 +3684,7 @@ class ToolPaint(FlatCAMTool, Gerber): cp.insert(lines_union) elif paint_method == _("Combo"): self.app.inform.emit(_("Painting polygons with method: lines.")) - cp = self.clear_polygon3(poly_buf, + cp = self.clear_polygon3(geo, tooldia=tool_dia, steps_per_circle=self.app.defaults["geometry_circle_steps"], overlap=over, @@ -4015,7 +3696,7 @@ class ToolPaint(FlatCAMTool, Gerber): pass else: self.app.inform.emit(_("Failed. Painting polygons with method: seed.")) - cp = self.clear_polygon2(poly_buf, + cp = self.clear_polygon2(geo, tooldia=tool_dia, steps_per_circle=self.app.defaults[ "geometry_circle_steps"], @@ -4027,7 +3708,7 @@ class ToolPaint(FlatCAMTool, Gerber): pass else: self.app.inform.emit(_("Failed. Painting polygons with method: standard.")) - cp = self.clear_polygon(poly_buf, + cp = self.clear_polygon(geo, tooldia=tool_dia, steps_per_circle=self.app.defaults[ "geometry_circle_steps"], @@ -4055,29 +3736,33 @@ class ToolPaint(FlatCAMTool, Gerber): old_disp_number = disp_number # log.debug("Polygons cleared: %d. Percentage done: %d%%" % (pol_nr, disp_number)) - # find the tooluid associated with the current tool_dia so we know where to add the tool solid_geometry - for k, v in tools_storage.items(): - if float('%.*f' % (self.decimals, v['tooldia'])) == float('%.*f' % (self.decimals, tool_dia)): - current_uid = int(k) - break - + final_solid_geometry += cleared_geo # add the solid_geometry to the current too in self.paint_tools (or tools_storage) dictionary and # then reset the temporary list that stored that solid_geometry tools_storage[current_uid]['solid_geometry'] = deepcopy(cleared_geo) - tools_storage[current_uid]['data']['name'] = name cleared_geo[:] = [] + # clean the progressive plotted shapes if it was used + if self.app.defaults["tools_paint_plotting"] == 'progressive': + self.temp_shapes.clear(update=True) + + # delete tools with empty geometry + # look for keys in the tools_storage dict that have 'solid_geometry' values empty + for uid in list(tools_storage.keys()): + # if the solid_geometry (type=list) is empty + if not tools_storage[uid]['solid_geometry']: + tools_storage.pop(uid, None) + + if not tools_storage: + return 'fail' + geo_obj.options["cnctooldia"] = str(tool_dia) # this turn on the FlatCAMCNCJob plot for multiple tools geo_obj.multigeo = True geo_obj.multitool = True geo_obj.tools.clear() - geo_obj.tools = dict(self.paint_tools) - - # clean the progressive plotted shapes if it was used - if self.app.defaults["tools_paint_plotting"] == 'progressive': - self.temp_shapes.clear(update=True) + geo_obj.tools = dict(tools_storage) # test if at least one tool has solid_geometry. If no tool has solid_geometry we raise an Exception has_solid_geo = 0 @@ -4351,6 +4036,13 @@ class ToolPaint(FlatCAMTool, Gerber): return self.app.inform.emit('[success] %s' % _("Tool from DB added in Tool Table.")) + # select last tool added + toolid = res + for row in range(self.tools_table.rowCount()): + if int(self.tools_table.item(row, 3).text()) == toolid: + self.tools_table.selectRow(row) + self.on_row_selection_change() + def on_paint_tool_from_db_inserted(self, tool): """ Called from the Tools DB object through a App method when adding a tool from Tools Database @@ -4392,9 +4084,9 @@ class ToolPaint(FlatCAMTool, Gerber): self.paint_tools.update({ tooluid: { 'tooldia': float('%.*f' % (self.decimals, tooldia)), - 'offset': 'Path', - 'offset_value': 0.0, - 'type': 'Iso', + 'offset': tool['offset'], + 'offset_value': tool['offset_value'], + 'type': tool['type'], 'tool_type': tool['tool_type'], 'data': deepcopy(tool['data']), 'solid_geometry': [] @@ -4407,6 +4099,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.ui_connect() self.build_ui() + return tooluid # if self.tools_table.rowCount() != 0: # self.param_frame.setDisabled(False) From 9a741394979a4b82389826afd264d68e77d12dc5 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 30 Mar 2020 23:56:38 +0300 Subject: [PATCH 142/209] - fixed some issues in Paint Tool --- README.md | 1 + flatcamTools/ToolPaint.py | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 01845106..e75e8fd6 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 30.03.2020 - working to update the Paint Tool +- fixed some issues in Paint Tool 29.03.2020 diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 51e6c9e3..9cf45655 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -984,9 +984,9 @@ class ToolPaint(FlatCAMTool, Gerber): self.default_data.update({ "name": '_paint', "plot": self.app.defaults["geometry_plot"], - "cutz": float(self.cutz_entry.get_value()), - "vtipdia": float(self.tipdia_entry.get_value()), - "vtipangle": float(self.tipangle_entry.get_value()), + "cutz": float(self.app.defaults["tools_paintcutz"],), + "vtipdia": float(self.app.defaults["tools_painttipdia"],), + "vtipangle": float(self.app.defaults["tools_painttipangle"],), "travelz": float(self.app.defaults["geometry_travelz"]), "feedrate": float(self.app.defaults["geometry_feedrate"]), "feedrate_z": float(self.app.defaults["geometry_feedrate_z"]), From 1d13b997f2a1751d96da846b6f4f893b62ecbe0c Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 1 Apr 2020 00:09:50 +0300 Subject: [PATCH 143/209] - updated the SVG parser to take into consideration the 'Close' svg element and paths that are made from a single line (we may need to switch to svgpathtools module) --- FlatCAMApp.py | 4 ++-- README.md | 4 ++++ flatcamParsers/ParseSVG.py | 35 +++++++++++++++++++++++++++++++---- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index aec238e4..157d9f6b 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -5323,8 +5323,8 @@ class App(QtCore.QObject): # try to quit the Socket opened by ArgsThread class try: self.new_launch.listener.close() - except Exception: - pass + except Exception as err: + log.debug("App.quit_application() --> %s" % str(err)) # quit app by signalling for self.kill_app() method self.close_app_signal.emit() diff --git a/README.md b/README.md index e75e8fd6..97b4b23d 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +1.04.2020 + +- updated the SVG parser to take into consideration the 'Close' svg element and paths that are made from a single line (we may need to switch to svgpathtools module) + 30.03.2020 - working to update the Paint Tool diff --git a/flatcamParsers/ParseSVG.py b/flatcamParsers/ParseSVG.py index edff621f..d5634944 100644 --- a/flatcamParsers/ParseSVG.py +++ b/flatcamParsers/ParseSVG.py @@ -21,7 +21,7 @@ # import xml.etree.ElementTree as ET from svg.path import Line, Arc, CubicBezier, QuadraticBezier, parse_path -from svg.path.path import Move +from svg.path.path import Move, Close from shapely.geometry import LineString, LinearRing, MultiLineString from shapely.affinity import skew, affine_transform, rotate import numpy as np @@ -69,6 +69,7 @@ def path2shapely(path, object_type, res=1.0): geometry = [] geo_element = None rings = [] + closed = False for component in path: # Line @@ -88,7 +89,8 @@ def path2shapely(path, object_type, res=1.0): # How many points to use in the discrete representation. length = component.length(res / 10.0) - steps = int(length / res + 0.5) + # steps = int(length / res + 0.5) + steps = int(length) * 2 # solve error when step is below 1, # it may cause other problems, but LineString needs at least two points @@ -109,11 +111,29 @@ def path2shapely(path, object_type, res=1.0): # Move if isinstance(component, Move): + if not points: + continue + else: + rings.append(points) + if closed is False: + points = [] + else: + closed = False + start = component.start + x, y = start.real, start.imag + points = [(x, y)] + continue + + closed = False + + # Close + if isinstance(component, Close): if not points: continue else: rings.append(points) points = [] + closed = True continue log.warning("I don't know what this is: %s" % str(component)) continue @@ -122,8 +142,12 @@ def path2shapely(path, object_type, res=1.0): if points: rings.append(points) + try: + rings = MultiLineString(rings) + except Exception as e: + log.debug("ParseSVG.path2shapely() MString --> %s" % str(e)) + return None - rings = MultiLineString(rings) if len(rings) > 0: if len(rings) == 1 and not isinstance(rings, MultiLineString): # Polygons are closed and require more than 2 points @@ -139,7 +163,10 @@ def path2shapely(path, object_type, res=1.0): for line in rings: coords.append(line.coords[0]) coords.append(line.coords[1]) - geo_element = Polygon(coords) + try: + geo_element = Polygon(coords) + except Exception: + geo_element = LineString(coords) geometry.append(geo_element) return geometry From 3d39916b5feee6155df329f5359947fc272662f1 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 1 Apr 2020 18:45:20 +0300 Subject: [PATCH 144/209] - minor changes to increase compatibility with Python 3.8 --- FlatCAMApp.py | 14 +++++--- FlatCAMCommon.py | 4 +-- FlatCAMObj.py | 6 ++-- ObjectCollection.py | 2 +- README.md | 1 + flatcamEditors/FlatCAMExcEditor.py | 2 +- flatcamEditors/FlatCAMGeoEditor.py | 12 +++---- flatcamEditors/FlatCAMGrbEditor.py | 14 ++++---- flatcamGUI/GUIElements.py | 8 ++--- flatcamParsers/ParseExcellon.py | 2 +- flatcamParsers/ParseGerber.py | 2 +- flatcamTools/ToolDblSided.py | 2 +- flatcamTools/ToolPanelize.py | 2 +- flatcamTools/ToolProperties.py | 2 +- flatcamTools/ToolRulesCheck.py | 52 +++++++++++++++--------------- flatcamTools/ToolTransform.py | 12 +++---- tclCommands/TclCommandPanelize.py | 2 +- 17 files changed, 72 insertions(+), 67 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 157d9f6b..e95e6085 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -5317,8 +5317,8 @@ class App(QtCore.QObject): # try to quit the QThread that run ArgsThread class try: self.th.quit() - except Exception: - pass + except Exception as e: + log.debug("App.final_save() --> %s" % str(e)) # try to quit the Socket opened by ArgsThread class try: @@ -5327,7 +5327,11 @@ class App(QtCore.QObject): log.debug("App.quit_application() --> %s" % str(err)) # quit app by signalling for self.kill_app() method - self.close_app_signal.emit() + # self.close_app_signal.emit() + QtWidgets.qApp.quit() + # When the main event loop is not started yet in which case the qApp.quit() will do nothing + # we use the following command + sys.exit(0) def kill_app(self): QtWidgets.qApp.quit() @@ -10178,7 +10182,7 @@ class App(QtCore.QObject): filenames, _f = QtWidgets.QFileDialog.getOpenFileNames(caption=_("Import SVG"), filter=_filter_) - if type_of_obj is not "geometry" and type_of_obj is not "gerber": + if type_of_obj != "geometry" and type_of_obj != "gerber": type_of_obj = "geometry" filenames = [str(filename) for filename in filenames] @@ -10211,7 +10215,7 @@ class App(QtCore.QObject): filenames, _f = QtWidgets.QFileDialog.getOpenFileNames(caption=_("Import DXF"), filter=_filter_) - if type_of_obj is not "geometry" and type_of_obj is not "gerber": + if type_of_obj != "geometry" and type_of_obj != "gerber": type_of_obj = "geometry" filenames = [str(filename) for filename in filenames] diff --git a/FlatCAMCommon.py b/FlatCAMCommon.py index 08142a9e..8940542f 100644 --- a/FlatCAMCommon.py +++ b/FlatCAMCommon.py @@ -261,7 +261,7 @@ class BookmarkManager(QtWidgets.QWidget): self.app.inform.emit('[ERROR_NOTCL] %s' % _("Title entry is empty.")) return 'fail' - if 'link' is kwargs: + if 'link' in kwargs: link = kwargs['link'] else: link = self.link_entry.get_value() @@ -1325,7 +1325,7 @@ class ToolsDB(QtWidgets.QWidget): default_data['toolchangez'] = self.table_widget.cellWidget(row, col).get_value() elif column_header_text == _('Start Z'): default_data['startz'] = float(self.table_widget.item(row, col).text()) \ - if self.table_widget.item(row, col).text() is not '' else None + if self.table_widget.item(row, col).text() != '' else None elif column_header_text == _('End Z'): default_data['endz'] = self.table_widget.cellWidget(row, col).get_value() diff --git a/FlatCAMObj.py b/FlatCAMObj.py index a267856f..ed31bb98 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -567,7 +567,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber): FlatCAMGerber.merge(grb, grb_final) else: # If not list, just append for option in grb.options: - if option is not 'name': + if option != 'name': try: grb_final.options[option] = grb.options[option] except KeyError: @@ -2507,7 +2507,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): for exc in flattened_list: # copy options of the current excellon obj to the final excellon obj for option in exc.options: - if option is not 'name': + if option != 'name': try: exc_final.options[option] = exc.options[option] except Exception: @@ -6440,7 +6440,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): for geo_obj in geo_list: for option in geo_obj.options: - if option is not 'name': + if option != 'name': try: new_options[option] = deepcopy(geo_obj.options[option]) except Exception as e: diff --git a/ObjectCollection.py b/ObjectCollection.py index e0f0bd4c..f015b031 100644 --- a/ObjectCollection.py +++ b/ObjectCollection.py @@ -518,7 +518,7 @@ class ObjectCollection(QtCore.QAbstractItemModel): self.endInsertRows() # Expand group - if group.child_count() is 1: + if group.child_count() == 1: self.view.setExpanded(group_index, True) self.app.should_we_save = True diff --git a/README.md b/README.md index 97b4b23d..840a9b4a 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 1.04.2020 - updated the SVG parser to take into consideration the 'Close' svg element and paths that are made from a single line (we may need to switch to svgpathtools module) +- minor changes to increase compatibility with Python 3.8 30.03.2020 diff --git a/flatcamEditors/FlatCAMExcEditor.py b/flatcamEditors/FlatCAMExcEditor.py index b53c0006..60ce3d6a 100644 --- a/flatcamEditors/FlatCAMExcEditor.py +++ b/flatcamEditors/FlatCAMExcEditor.py @@ -3393,7 +3393,7 @@ class FlatCAMExcEditor(QtCore.QObject): self.app.log.debug("on_tool_select('%s')" % tool) - if self.last_tool_selected is None and current_tool is not 'drill_select': + if self.last_tool_selected is None and current_tool != 'drill_select': # self.draw_app.select_tool('drill_select') self.complete = True current_tool = 'drill_select' diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index 23d47e06..cac6918a 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -1327,11 +1327,11 @@ class TransformEditorTool(FlatCAMTool): # execute mirroring for sha in shape_list: - if axis is 'X': + if axis == 'X': sha.mirror('X', (px, py)) self.app.inform.emit('[success] %s...' % _('Flip on the Y axis done')) - elif axis is 'Y': + elif axis == 'Y': sha.mirror('Y', (px, py)) self.app.inform.emit('[success] %s' % _('Flip on the X axis done')) @@ -1368,9 +1368,9 @@ class TransformEditorTool(FlatCAMTool): yminimal = min(yminlist) for sha in shape_list: - if axis is 'X': + if axis == 'X': sha.skew(num, 0, point=(xminimal, yminimal)) - elif axis is 'Y': + elif axis == 'Y': sha.skew(0, num, point=(xminimal, yminimal)) self.draw_app.replot() @@ -1449,9 +1449,9 @@ class TransformEditorTool(FlatCAMTool): with self.app.proc_container.new(_("Applying Offset")): try: for sha in shape_list: - if axis is 'X': + if axis == 'X': sha.offset((num, 0)) - elif axis is 'Y': + elif axis == 'Y': sha.offset((0, num)) self.draw_app.replot() diff --git a/flatcamEditors/FlatCAMGrbEditor.py b/flatcamEditors/FlatCAMGrbEditor.py index 73fc0afa..d1cbb789 100644 --- a/flatcamEditors/FlatCAMGrbEditor.py +++ b/flatcamEditors/FlatCAMGrbEditor.py @@ -4254,7 +4254,7 @@ class FlatCAMGrbEditor(QtCore.QObject): self.app.log.debug("on_tool_select('%s')" % tool) - if self.last_aperture_selected is None and current_tool is not 'select': + if self.last_aperture_selected is None and current_tool != 'select': # self.draw_app.select_tool('select') self.complete = True current_tool = 'select' @@ -5867,7 +5867,7 @@ class TransformEditorTool(FlatCAMTool): # execute mirroring for sel_el_shape in elem_list: sel_el = sel_el_shape.geo - if axis is 'X': + if axis == 'X': if 'solid' in sel_el: sel_el['solid'] = affinity.scale(sel_el['solid'], xfact=1, yfact=-1, origin=(px, py)) if 'follow' in sel_el: @@ -5876,7 +5876,7 @@ class TransformEditorTool(FlatCAMTool): sel_el['clear'] = affinity.scale(sel_el['clear'], xfact=1, yfact=-1, origin=(px, py)) self.app.inform.emit('[success] %s...' % _('Flip on the Y axis done')) - elif axis is 'Y': + elif axis == 'Y': if 'solid' in sel_el: sel_el['solid'] = affinity.scale(sel_el['solid'], xfact=-1, yfact=1, origin=(px, py)) if 'follow' in sel_el: @@ -5924,14 +5924,14 @@ class TransformEditorTool(FlatCAMTool): for sel_el_shape in elem_list: sel_el = sel_el_shape.geo - if axis is 'X': + if axis == 'X': if 'solid' in sel_el: sel_el['solid'] = affinity.skew(sel_el['solid'], num, 0, origin=(xminimal, yminimal)) if 'follow' in sel_el: sel_el['follow'] = affinity.skew(sel_el['follow'], num, 0, origin=(xminimal, yminimal)) if 'clear' in sel_el: sel_el['clear'] = affinity.skew(sel_el['clear'], num, 0, origin=(xminimal, yminimal)) - elif axis is 'Y': + elif axis == 'Y': if 'solid' in sel_el: sel_el['solid'] = affinity.skew(sel_el['solid'], 0, num, origin=(xminimal, yminimal)) if 'follow' in sel_el: @@ -6031,14 +6031,14 @@ class TransformEditorTool(FlatCAMTool): try: for sel_el_shape in elem_list: sel_el = sel_el_shape.geo - if axis is 'X': + if axis == 'X': if 'solid' in sel_el: sel_el['solid'] = affinity.translate(sel_el['solid'], num, 0) if 'follow' in sel_el: sel_el['follow'] = affinity.translate(sel_el['follow'], num, 0) if 'clear' in sel_el: sel_el['clear'] = affinity.translate(sel_el['clear'], num, 0) - elif axis is 'Y': + elif axis == 'Y': if 'solid' in sel_el: sel_el['solid'] = affinity.translate(sel_el['solid'], 0, num) if 'follow' in sel_el: diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index c9fdc607..1b34118a 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -376,7 +376,7 @@ class FloatEntry(QtWidgets.QLineEdit): evaled = eval(raw) return float(evaled) except Exception as e: - if raw is not '': + if raw != '': log.error("Could not evaluate val: %s, error: %s" % (str(raw), str(e))) return None @@ -422,7 +422,7 @@ class FloatEntry2(QtWidgets.QLineEdit): evaled = eval(raw) return float(evaled) except Exception as e: - if raw is not '': + if raw != '': log.error("Could not evaluate val: %s, error: %s" % (str(raw), str(e))) return None @@ -602,7 +602,7 @@ class EvalEntry(QtWidgets.QLineEdit): try: evaled = eval(raw) except Exception as e: - if raw is not '': + if raw != '': log.error("Could not evaluate val: %s, error: %s" % (str(raw), str(e))) return None return evaled @@ -642,7 +642,7 @@ class EvalEntry2(QtWidgets.QLineEdit): try: evaled = eval(raw) except Exception as e: - if raw is not '': + if raw != '': log.error("Could not evaluate val: %s, error: %s" % (str(raw), str(e))) return None return evaled diff --git a/flatcamParsers/ParseExcellon.py b/flatcamParsers/ParseExcellon.py index 7dc9ee35..1e7f2565 100644 --- a/flatcamParsers/ParseExcellon.py +++ b/flatcamParsers/ParseExcellon.py @@ -967,7 +967,7 @@ class Excellon(Geometry): for drill in self.drills: # poly = drill['point'].buffer(self.tools[drill['tool']]["C"]/2.0) - if drill['tool'] is '': + if drill['tool'] == '': self.app.inform.emit('[WARNING] %s' % _("Excellon.create_geometry() -> a drill location was skipped " "due of not having a tool associated.\n" diff --git a/flatcamParsers/ParseGerber.py b/flatcamParsers/ParseGerber.py index 54091259..deba943e 100644 --- a/flatcamParsers/ParseGerber.py +++ b/flatcamParsers/ParseGerber.py @@ -718,7 +718,7 @@ class Gerber(Geometry): # so it can be processed by FlatCAM. # But first test to see if the aperture type is "aperture macro". In that case # we should not test for "size" key as it does not exist in this case. - if self.apertures[current_aperture]["type"] is not "AM": + if self.apertures[current_aperture]["type"] != "AM": if self.apertures[current_aperture]["size"] == 0: self.apertures[current_aperture]["size"] = 1e-12 # log.debug(self.apertures[current_aperture]) diff --git a/flatcamTools/ToolDblSided.py b/flatcamTools/ToolDblSided.py index 75071e88..89014940 100644 --- a/flatcamTools/ToolDblSided.py +++ b/flatcamTools/ToolDblSided.py @@ -606,7 +606,7 @@ class DblSidedTool(FlatCAMTool): xscale, yscale = {"X": (1.0, -1.0), "Y": (-1.0, 1.0)}[axis] dia = float(self.drill_dia.get_value()) - if dia is '': + if dia == '': self.app.inform.emit('[WARNING_NOTCL] %s' % _("No value or wrong format in Drill Dia entry. Add it and retry.")) return diff --git a/flatcamTools/ToolPanelize.py b/flatcamTools/ToolPanelize.py index fe381fc0..2cab2448 100644 --- a/flatcamTools/ToolPanelize.py +++ b/flatcamTools/ToolPanelize.py @@ -504,7 +504,7 @@ class Panelize(FlatCAMTool): obj_fin.solid_geometry = [] for option in panel_obj.options: - if option is not 'name': + if option != 'name': try: obj_fin.options[option] = panel_obj.options[option] except KeyError: diff --git a/flatcamTools/ToolProperties.py b/flatcamTools/ToolProperties.py index da783097..97ba0e04 100644 --- a/flatcamTools/ToolProperties.py +++ b/flatcamTools/ToolProperties.py @@ -349,7 +349,7 @@ class Properties(FlatCAMTool): # Options items for option in obj.options: - if option is 'name': + if option == 'name': continue self.treeWidget.addChild(options, [str(option), str(obj.options[option])], True) diff --git a/flatcamTools/ToolRulesCheck.py b/flatcamTools/ToolRulesCheck.py index eb236381..9ee387fc 100644 --- a/flatcamTools/ToolRulesCheck.py +++ b/flatcamTools/ToolRulesCheck.py @@ -1130,14 +1130,14 @@ class RulesCheck(FlatCAMTool): if self.trace_size_cb.get_value(): copper_list = [] copper_name_1 = self.copper_t_object.currentText() - if copper_name_1 is not '' and self.copper_t_cb.get_value(): + if copper_name_1 != '' and self.copper_t_cb.get_value(): elem_dict = {} elem_dict['name'] = deepcopy(copper_name_1) elem_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_name_1).apertures) copper_list.append(elem_dict) copper_name_2 = self.copper_b_object.currentText() - if copper_name_2 is not '' and self.copper_b_cb.get_value(): + if copper_name_2 !='' and self.copper_b_cb.get_value(): elem_dict = {} elem_dict['name'] = deepcopy(copper_name_2) elem_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_name_2).apertures) @@ -1162,7 +1162,7 @@ class RulesCheck(FlatCAMTool): copper_t_obj = self.copper_t_object.currentText() copper_t_dict = {} - if copper_t_obj is not '': + if copper_t_obj != '': copper_t_dict['name'] = deepcopy(copper_t_obj) copper_t_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_t_obj).apertures) @@ -1173,7 +1173,7 @@ class RulesCheck(FlatCAMTool): if self.copper_b_cb.get_value(): copper_b_obj = self.copper_b_object.currentText() copper_b_dict = {} - if copper_b_obj is not '': + if copper_b_obj != '': copper_b_dict['name'] = deepcopy(copper_b_obj) copper_b_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_b_obj).apertures) @@ -1195,17 +1195,17 @@ class RulesCheck(FlatCAMTool): outline_dict = {} copper_top = self.copper_t_object.currentText() - if copper_top is not '' and self.copper_t_cb.get_value(): + if copper_top != '' and self.copper_t_cb.get_value(): top_dict['name'] = deepcopy(copper_top) top_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_top).apertures) copper_bottom = self.copper_b_object.currentText() - if copper_bottom is not '' and self.copper_b_cb.get_value(): + if copper_bottom != '' and self.copper_b_cb.get_value(): bottom_dict['name'] = deepcopy(copper_bottom) bottom_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_bottom).apertures) copper_outline = self.outline_object.currentText() - if copper_outline is not '' and self.out_cb.get_value(): + if copper_outline != '' and self.out_cb.get_value(): outline_dict['name'] = deepcopy(copper_outline) outline_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_outline).apertures) @@ -1257,7 +1257,7 @@ class RulesCheck(FlatCAMTool): if self.ss_t_cb.get_value(): silk_obj = self.ss_t_object.currentText() - if silk_obj is not '': + if silk_obj != '': silk_dict['name'] = deepcopy(silk_obj) silk_dict['apertures'] = deepcopy(self.app.collection.get_by_name(silk_obj).apertures) @@ -1267,7 +1267,7 @@ class RulesCheck(FlatCAMTool): _("TOP -> Silk to Silk clearance")))) if self.ss_b_cb.get_value(): silk_obj = self.ss_b_object.currentText() - if silk_obj is not '': + if silk_obj != '': silk_dict['name'] = deepcopy(silk_obj) silk_dict['apertures'] = deepcopy(self.app.collection.get_by_name(silk_obj).apertures) @@ -1295,25 +1295,25 @@ class RulesCheck(FlatCAMTool): bottom_sm = False silk_top = self.ss_t_object.currentText() - if silk_top is not '' and self.ss_t_cb.get_value(): + if silk_top != '' and self.ss_t_cb.get_value(): silk_t_dict['name'] = deepcopy(silk_top) silk_t_dict['apertures'] = deepcopy(self.app.collection.get_by_name(silk_top).apertures) top_ss = True silk_bottom = self.ss_b_object.currentText() - if silk_bottom is not '' and self.ss_b_cb.get_value(): + if silk_bottom != '' and self.ss_b_cb.get_value(): silk_b_dict['name'] = deepcopy(silk_bottom) silk_b_dict['apertures'] = deepcopy(self.app.collection.get_by_name(silk_bottom).apertures) bottom_ss = True sm_top = self.sm_t_object.currentText() - if sm_top is not '' and self.sm_t_cb.get_value(): + if sm_top != '' and self.sm_t_cb.get_value(): sm_t_dict['name'] = deepcopy(sm_top) sm_t_dict['apertures'] = deepcopy(self.app.collection.get_by_name(sm_top).apertures) top_sm = True sm_bottom = self.sm_b_object.currentText() - if sm_bottom is not '' and self.sm_b_cb.get_value(): + if sm_bottom != '' and self.sm_b_cb.get_value(): sm_b_dict['name'] = deepcopy(sm_bottom) sm_b_dict['apertures'] = deepcopy(self.app.collection.get_by_name(sm_bottom).apertures) bottom_sm = True @@ -1358,17 +1358,17 @@ class RulesCheck(FlatCAMTool): outline_dict = {} silk_top = self.ss_t_object.currentText() - if silk_top is not '' and self.ss_t_cb.get_value(): + if silk_top != '' and self.ss_t_cb.get_value(): top_dict['name'] = deepcopy(silk_top) top_dict['apertures'] = deepcopy(self.app.collection.get_by_name(silk_top).apertures) silk_bottom = self.ss_b_object.currentText() - if silk_bottom is not '' and self.ss_b_cb.get_value(): + if silk_bottom != '' and self.ss_b_cb.get_value(): bottom_dict['name'] = deepcopy(silk_bottom) bottom_dict['apertures'] = deepcopy(self.app.collection.get_by_name(silk_bottom).apertures) copper_outline = self.outline_object.currentText() - if copper_outline is not '' and self.out_cb.get_value(): + if copper_outline != '' and self.out_cb.get_value(): outline_dict['name'] = deepcopy(copper_outline) outline_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_outline).apertures) @@ -1421,7 +1421,7 @@ class RulesCheck(FlatCAMTool): if self.sm_t_cb.get_value(): solder_obj = self.sm_t_object.currentText() - if solder_obj is not '': + if solder_obj != '': sm_dict['name'] = deepcopy(solder_obj) sm_dict['apertures'] = deepcopy(self.app.collection.get_by_name(solder_obj).apertures) @@ -1431,7 +1431,7 @@ class RulesCheck(FlatCAMTool): _("TOP -> Minimum Solder Mask Sliver")))) if self.sm_b_cb.get_value(): solder_obj = self.sm_b_object.currentText() - if solder_obj is not '': + if solder_obj != '': sm_dict['name'] = deepcopy(solder_obj) sm_dict['apertures'] = deepcopy(self.app.collection.get_by_name(solder_obj).apertures) @@ -1454,23 +1454,23 @@ class RulesCheck(FlatCAMTool): exc_2_dict = {} copper_top = self.copper_t_object.currentText() - if copper_top is not '' and self.copper_t_cb.get_value(): + if copper_top != '' and self.copper_t_cb.get_value(): top_dict['name'] = deepcopy(copper_top) top_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_top).apertures) copper_bottom = self.copper_b_object.currentText() - if copper_bottom is not '' and self.copper_b_cb.get_value(): + if copper_bottom != '' and self.copper_b_cb.get_value(): bottom_dict['name'] = deepcopy(copper_bottom) bottom_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_bottom).apertures) excellon_1 = self.e1_object.currentText() - if excellon_1 is not '' and self.e1_cb.get_value(): + if excellon_1 != '' and self.e1_cb.get_value(): exc_1_dict['name'] = deepcopy(excellon_1) exc_1_dict['tools'] = deepcopy( self.app.collection.get_by_name(excellon_1).tools) excellon_2 = self.e2_object.currentText() - if excellon_2 is not '' and self.e2_cb.get_value(): + if excellon_2 != '' and self.e2_cb.get_value(): exc_2_dict['name'] = deepcopy(excellon_2) exc_2_dict['tools'] = deepcopy( self.app.collection.get_by_name(excellon_2).tools) @@ -1515,14 +1515,14 @@ class RulesCheck(FlatCAMTool): if self.clearance_d2d_cb.get_value(): exc_list = [] exc_name_1 = self.e1_object.currentText() - if exc_name_1 is not '' and self.e1_cb.get_value(): + if exc_name_1 != '' and self.e1_cb.get_value(): elem_dict = {} elem_dict['name'] = deepcopy(exc_name_1) elem_dict['tools'] = deepcopy(self.app.collection.get_by_name(exc_name_1).tools) exc_list.append(elem_dict) exc_name_2 = self.e2_object.currentText() - if exc_name_2 is not '' and self.e2_cb.get_value(): + if exc_name_2 != '' and self.e2_cb.get_value(): elem_dict = {} elem_dict['name'] = deepcopy(exc_name_2) elem_dict['tools'] = deepcopy(self.app.collection.get_by_name(exc_name_2).tools) @@ -1535,14 +1535,14 @@ class RulesCheck(FlatCAMTool): if self.drill_size_cb.get_value(): exc_list = [] exc_name_1 = self.e1_object.currentText() - if exc_name_1 is not '' and self.e1_cb.get_value(): + if exc_name_1 != '' and self.e1_cb.get_value(): elem_dict = {} elem_dict['name'] = deepcopy(exc_name_1) elem_dict['tools'] = deepcopy(self.app.collection.get_by_name(exc_name_1).tools) exc_list.append(elem_dict) exc_name_2 = self.e2_object.currentText() - if exc_name_2 is not '' and self.e2_cb.get_value(): + if exc_name_2 != '' and self.e2_cb.get_value(): elem_dict = {} elem_dict['name'] = deepcopy(exc_name_2) elem_dict['tools'] = deepcopy(self.app.collection.get_by_name(exc_name_2).tools) diff --git a/flatcamTools/ToolTransform.py b/flatcamTools/ToolTransform.py index 8ce0eff5..72955eee 100644 --- a/flatcamTools/ToolTransform.py +++ b/flatcamTools/ToolTransform.py @@ -760,7 +760,7 @@ class ToolTransform(FlatCAMTool): if isinstance(sel_obj, FlatCAMCNCjob): self.app.inform.emit(_("CNCJob objects can't be mirrored/flipped.")) else: - if axis is 'X': + if axis == 'X': sel_obj.mirror('X', (px, py)) # add information to the object that it was changed and how much # the axis is reversed because of the reference @@ -770,7 +770,7 @@ class ToolTransform(FlatCAMTool): sel_obj.options['mirror_y'] = True self.app.inform.emit('[success] %s...' % _('Flip on the Y axis done')) - elif axis is 'Y': + elif axis == 'Y': sel_obj.mirror('Y', (px, py)) # add information to the object that it was changed and how much # the axis is reversed because of the reference @@ -820,11 +820,11 @@ class ToolTransform(FlatCAMTool): if isinstance(sel_obj, FlatCAMCNCjob): self.app.inform.emit(_("CNCJob objects can't be skewed.")) else: - if axis is 'X': + if axis == 'X': sel_obj.skew(num, 0, point=(xminimal, yminimal)) # add information to the object that it was changed and how much sel_obj.options['skew_x'] = num - elif axis is 'Y': + elif axis == 'Y': sel_obj.skew(0, num, point=(xminimal, yminimal)) # add information to the object that it was changed and how much sel_obj.options['skew_y'] = num @@ -906,11 +906,11 @@ class ToolTransform(FlatCAMTool): if isinstance(sel_obj, FlatCAMCNCjob): self.app.inform.emit(_("CNCJob objects can't be offset.")) else: - if axis is 'X': + if axis == 'X': sel_obj.offset((num, 0)) # add information to the object that it was changed and how much sel_obj.options['offset_x'] = num - elif axis is 'Y': + elif axis == 'Y': sel_obj.offset((0, num)) # add information to the object that it was changed and how much sel_obj.options['offset_y'] = num diff --git a/tclCommands/TclCommandPanelize.py b/tclCommands/TclCommandPanelize.py index 140c5e55..b40cc434 100644 --- a/tclCommands/TclCommandPanelize.py +++ b/tclCommands/TclCommandPanelize.py @@ -185,7 +185,7 @@ class TclCommandPanelize(TclCommand): obj_fin.solid_geometry = [] for option in obj.options: - if option is not 'name': + if option != 'name': try: obj_fin.options[option] = obj.options[option] except Exception as e: From 280eb1dc3a2cf086cdb9a88187daaeb0894c00a4 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 1 Apr 2020 18:59:53 +0300 Subject: [PATCH 145/209] - PEP8 changes --- README.md | 1 + flatcamEditors/FlatCAMExcEditor.py | 67 +++++++++++++----------------- flatcamEditors/FlatCAMGeoEditor.py | 46 ++++++++------------ flatcamEditors/FlatCAMGrbEditor.py | 48 +++++++++++---------- 4 files changed, 72 insertions(+), 90 deletions(-) diff --git a/README.md b/README.md index 840a9b4a..094cef18 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ CAD program, and create G-Code for Isolation routing. - updated the SVG parser to take into consideration the 'Close' svg element and paths that are made from a single line (we may need to switch to svgpathtools module) - minor changes to increase compatibility with Python 3.8 +- PEP8 changes 30.03.2020 diff --git a/flatcamEditors/FlatCAMExcEditor.py b/flatcamEditors/FlatCAMExcEditor.py index 60ce3d6a..65f9e497 100644 --- a/flatcamEditors/FlatCAMExcEditor.py +++ b/flatcamEditors/FlatCAMExcEditor.py @@ -398,7 +398,7 @@ class FCSlot(FCShapeTool): try: QtGui.QGuiApplication.restoreOverrideCursor() - except Exception as e: + except Exception: pass self.cursor = QtGui.QCursor(QtGui.QPixmap(self.draw_app.app.resource_location + '/aero_slot.png')) QtGui.QGuiApplication.setOverrideCursor(self.cursor) @@ -538,7 +538,7 @@ class FCSlot(FCShapeTool): try: QtGui.QGuiApplication.restoreOverrideCursor() - except Exception as e: + except Exception: pass try: @@ -600,7 +600,7 @@ class FCSlotArray(FCShapeTool): try: QtGui.QGuiApplication.restoreOverrideCursor() - except Exception as e: + except Exception: pass self.cursor = QtGui.QCursor(QtGui.QPixmap(self.draw_app.app.resource_location + '/aero_array.png')) QtGui.QGuiApplication.setOverrideCursor(self.cursor) @@ -677,9 +677,8 @@ class FCSlotArray(FCShapeTool): self.draw_app.app.inform.emit('[ERROR_NOTCL] %s' % _("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] %s' % - _("The value is mistyped. Check the value.")) + except Exception: + self.draw_app.app.inform.emit('[ERROR_NOTCL] %s' % _("The value is mistyped. Check the value.")) return if self.slot_array == 'Linear': @@ -829,7 +828,7 @@ class FCSlotArray(FCShapeTool): try: QtGui.QGuiApplication.restoreOverrideCursor() - except Exception as e: + except Exception: pass # add the point to slots if the diameter is a key in the dict, if not, create it add the drill location @@ -1340,7 +1339,7 @@ class FCDrillSelect(DrawTool): try: QtGui.QGuiApplication.restoreOverrideCursor() - except Exception as e: + except Exception: pass self.exc_editor_app = draw_app @@ -1739,7 +1738,7 @@ class FlatCAMExcEditor(QtCore.QObject): self.linear_box.addLayout(self.linear_form) # Linear Drill Array direction - self.drill_axis_label = QtWidgets.QLabel('%s:'% _('Direction')) + self.drill_axis_label = QtWidgets.QLabel('%s:' % _('Direction')) self.drill_axis_label.setToolTip( _("Direction on which the linear array is oriented:\n" "- 'X' - horizontal axis \n" @@ -2037,22 +2036,14 @@ class FlatCAMExcEditor(QtCore.QObject): # ## Toolbar events and properties self.tools_exc = { - "drill_select": {"button": self.app.ui.select_drill_btn, - "constructor": FCDrillSelect}, - "drill_add": {"button": self.app.ui.add_drill_btn, - "constructor": FCDrillAdd}, - "drill_array": {"button": self.app.ui.add_drill_array_btn, - "constructor": FCDrillArray}, - "slot_add": {"button": self.app.ui.add_slot_btn, - "constructor": FCSlot}, - "slot_array": {"button": self.app.ui.add_slot_array_btn, - "constructor": FCSlotArray}, - "drill_resize": {"button": self.app.ui.resize_drill_btn, - "constructor": FCDrillResize}, - "drill_copy": {"button": self.app.ui.copy_drill_btn, - "constructor": FCDrillCopy}, - "drill_move": {"button": self.app.ui.move_drill_btn, - "constructor": FCDrillMove}, + "drill_select": {"button": self.app.ui.select_drill_btn, "constructor": FCDrillSelect}, + "drill_add": {"button": self.app.ui.add_drill_btn, "constructor": FCDrillAdd}, + "drill_array": {"button": self.app.ui.add_drill_array_btn, "constructor": FCDrillArray}, + "slot_add": {"button": self.app.ui.add_slot_btn, "constructor": FCSlot}, + "slot_array": {"button": self.app.ui.add_slot_array_btn, "constructor": FCSlotArray}, + "drill_resize": {"button": self.app.ui.resize_drill_btn, "constructor": FCDrillResize}, + "drill_copy": {"button": self.app.ui.copy_drill_btn, "constructor": FCDrillCopy}, + "drill_move": {"button": self.app.ui.move_drill_btn, "constructor": FCDrillMove}, } # ## Data @@ -2192,7 +2183,7 @@ class FlatCAMExcEditor(QtCore.QObject): "operation": self.app.defaults["excellon_operation"], "milling_type": self.app.defaults["excellon_milling_type"], - "milling_dia":self.app.defaults["excellon_milling_dia"], + "milling_dia": self.app.defaults["excellon_milling_dia"], "cutz": self.app.defaults["excellon_cutz"], "multidepth": self.app.defaults["excellon_multidepth"], @@ -2579,9 +2570,8 @@ 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] %s' % - _("Tool already in the original or actual tool list.\n" - "Save and reedit Excellon if you need to add this tool. ")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Tool already in the original or actual tool list.\n" + "Save and reedit Excellon if you need to add this tool. ")) return # since we add a new tool, we update also the initial state of the tool_table through it's dictionary @@ -2621,9 +2611,8 @@ class FlatCAMExcEditor(QtCore.QObject): deleted_tool_dia_list.append(float('%.*f' % (self.decimals, dd))) else: deleted_tool_dia_list.append(float('%.*f' % (self.decimals, dia))) - except Exception as e: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Select a tool in Tool Table")) + except Exception: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Select a tool in Tool Table")) return for deleted_tool_dia in deleted_tool_dia_list: @@ -2871,7 +2860,7 @@ class FlatCAMExcEditor(QtCore.QObject): def deactivate(self): try: QtGui.QGuiApplication.restoreOverrideCursor() - except Exception as e: + except Exception: pass # adjust the status of the menu entries related to the editor @@ -3468,7 +3457,7 @@ class FlatCAMExcEditor(QtCore.QObject): self.pos = self.canvas.translate_coords(event_pos) - if self.app.grid_status() == True: + if self.app.grid_status(): self.pos = self.app.geo_editor.snap(self.pos[0], self.pos[1]) else: self.pos = (self.pos[0], self.pos[1]) @@ -3613,7 +3602,7 @@ class FlatCAMExcEditor(QtCore.QObject): pos_canvas = self.canvas.translate_coords(event_pos) - if self.app.grid_status() == True: + if self.app.grid_status(): pos = self.app.geo_editor.snap(pos_canvas[0], pos_canvas[1]) else: pos = (pos_canvas[0], pos_canvas[1]) @@ -3625,7 +3614,7 @@ class FlatCAMExcEditor(QtCore.QObject): if self.app.ui.popMenu.mouse_is_panning is False: try: QtGui.QGuiApplication.restoreOverrideCursor() - except Exception as e: + except Exception: pass if self.active_tool.complete is False and not isinstance(self.active_tool, FCDrillSelect): self.active_tool.complete = True @@ -3704,7 +3693,7 @@ class FlatCAMExcEditor(QtCore.QObject): for storage in self.storage_dict: for obj in self.storage_dict[storage].get_objects(): if (sel_type is True and poly_selection.contains(obj.geo)) or \ - (sel_type is False and poly_selection.intersects(obj.geo)): + (sel_type is False and poly_selection.intersects(obj.geo)): if obj in self.selected: # remove the shape object from the selected shapes storage @@ -3724,7 +3713,7 @@ class FlatCAMExcEditor(QtCore.QObject): try: self.tools_table_exc.cellPressed.disconnect() - except Exception as e: + except Exception: pass # first deselect all rows (tools) in the Tools Table @@ -3801,7 +3790,7 @@ class FlatCAMExcEditor(QtCore.QObject): return # ## Snap coordinates - if self.app.grid_status() == True: + if self.app.grid_status(): x, y = self.app.geo_editor.snap(x, y) # Update cursor diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index cac6918a..9d6be36b 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -1805,7 +1805,7 @@ class DrawToolShape(object): geoms.append(scale_recursion(local_geom)) return geoms else: - return affinity.scale(geom, xfactor, yfactor, origin=(px, py)) + return affinity.scale(geom, xfactor, yfactor, origin=(px, py)) try: self.geo = scale_recursion(self.geo) @@ -3264,34 +3264,20 @@ class FlatCAMGeoEditor(QtCore.QObject): # ## Toolbar events and properties self.tools = { - "select": {"button": self.app.ui.geo_select_btn, - "constructor": FCSelect}, - "arc": {"button": self.app.ui.geo_add_arc_btn, - "constructor": FCArc}, - "circle": {"button": self.app.ui.geo_add_circle_btn, - "constructor": FCCircle}, - "path": {"button": self.app.ui.geo_add_path_btn, - "constructor": FCPath}, - "rectangle": {"button": self.app.ui.geo_add_rectangle_btn, - "constructor": FCRectangle}, - "polygon": {"button": self.app.ui.geo_add_polygon_btn, - "constructor": FCPolygon}, - "text": {"button": self.app.ui.geo_add_text_btn, - "constructor": FCText}, - "buffer": {"button": self.app.ui.geo_add_buffer_btn, - "constructor": FCBuffer}, - "paint": {"button": self.app.ui.geo_add_paint_btn, - "constructor": FCPaint}, - "eraser": {"button": self.app.ui.geo_eraser_btn, - "constructor": FCEraser}, - "move": {"button": self.app.ui.geo_move_btn, - "constructor": FCMove}, - "transform": {"button": self.app.ui.geo_transform_btn, - "constructor": FCTransform}, - "copy": {"button": self.app.ui.geo_copy_btn, - "constructor": FCCopy}, - "explode": {"button": self.app.ui.geo_explode_btn, - "constructor": FCExplode} + "select": {"button": self.app.ui.geo_select_btn, "constructor": FCSelect}, + "arc": {"button": self.app.ui.geo_add_arc_btn, "constructor": FCArc}, + "circle": {"button": self.app.ui.geo_add_circle_btn, "constructor": FCCircle}, + "path": {"button": self.app.ui.geo_add_path_btn, "constructor": FCPath}, + "rectangle": {"button": self.app.ui.geo_add_rectangle_btn, "constructor": FCRectangle}, + "polygon": {"button": self.app.ui.geo_add_polygon_btn, "constructor": FCPolygon}, + "text": {"button": self.app.ui.geo_add_text_btn, "constructor": FCText}, + "buffer": {"button": self.app.ui.geo_add_buffer_btn, "constructor": FCBuffer}, + "paint": {"button": self.app.ui.geo_add_paint_btn, "constructor": FCPaint}, + "eraser": {"button": self.app.ui.geo_eraser_btn, "constructor": FCEraser}, + "move": {"button": self.app.ui.geo_move_btn, "constructor": FCMove}, + "transform": {"button": self.app.ui.geo_transform_btn, "constructor": FCTransform}, + "copy": {"button": self.app.ui.geo_copy_btn, "constructor": FCCopy}, + "explode": {"button": self.app.ui.geo_explode_btn, "constructor": FCExplode} } # # ## Data @@ -3343,6 +3329,8 @@ class FlatCAMGeoEditor(QtCore.QObject): # signal that there is an action active like polygon or path self.in_action = False + self.units = None + # this will flag if the Editor "tools" are launched from key shortcuts (True) or from menu toolbar (False) self.launched_from_shortcuts = False diff --git a/flatcamEditors/FlatCAMGrbEditor.py b/flatcamEditors/FlatCAMGrbEditor.py index d1cbb789..b655656b 100644 --- a/flatcamEditors/FlatCAMGrbEditor.py +++ b/flatcamEditors/FlatCAMGrbEditor.py @@ -423,7 +423,7 @@ class FCPadArray(FCShapeTool): try: QtGui.QGuiApplication.restoreOverrideCursor() - except Exception as e: + except Exception: pass self.cursor = QtGui.QCursor(QtGui.QPixmap(self.draw_app.app.resource_location + '/aero_array.png')) QtGui.QGuiApplication.setOverrideCursor(self.cursor) @@ -515,9 +515,8 @@ class FCPadArray(FCShapeTool): self.draw_app.app.inform.emit('[ERROR_NOTCL] %s' % _("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] %s' % - _("The value is mistyped. Check the value.")) + except Exception: + self.draw_app.app.inform.emit('[ERROR_NOTCL] %s' % _("The value is mistyped. Check the value.")) return if self.pad_array == 'Linear': @@ -3103,6 +3102,10 @@ class FlatCAMGrbEditor(QtCore.QObject): self.conversion_factor = 1 + self.apertures_row = 0 + + self.complete = True + self.set_ui() log.debug("Initialization of the FlatCAM Gerber Editor is finished ...") @@ -3332,8 +3335,8 @@ class FlatCAMGrbEditor(QtCore.QObject): self.storage_dict[ap_id]['geometry'] = [] - # self.olddia_newdia dict keeps the evidence on current aperture codes as keys and gets updated on values - # each time a aperture code is edited or added + # self.olddia_newdia dict keeps the evidence on current aperture codes as keys and + # gets updated on values each time a aperture code is edited or added self.olddia_newdia[ap_id] = ap_id else: if ap_id not in self.olddia_newdia: @@ -3945,9 +3948,9 @@ class FlatCAMGrbEditor(QtCore.QObject): @staticmethod def worker_job(app_obj): with app_obj.app.proc_container.new('%s ...' % _("Loading Gerber into Editor")): - # ############################################################# ## + # ############################################################### # APPLY CLEAR_GEOMETRY on the SOLID_GEOMETRY - # ############################################################# ## + # ############################################################### # list of clear geos that are to be applied to the entire file global_clear_geo = [] @@ -3968,9 +3971,9 @@ class FlatCAMGrbEditor(QtCore.QObject): # we subtract the big "negative" (clear) geometry from each solid polygon but only the part of # clear geometry that fits inside the solid. otherwise we may loose the solid - for apid in app_obj.gerber_obj.apertures: + for ap_id in app_obj.gerber_obj.apertures: temp_solid_geometry = [] - if 'geometry' in app_obj.gerber_obj.apertures[apid]: + if 'geometry' in app_obj.gerber_obj.apertures[ap_id]: # for elem in self.gerber_obj.apertures[apid]['geometry']: # if 'solid' in elem: # solid_geo = elem['solid'] @@ -3998,7 +4001,7 @@ class FlatCAMGrbEditor(QtCore.QObject): # if 'follow' in elem: # new_elem['follow'] = solid_geo # temp_elem.append(deepcopy(new_elem)) - for elem in app_obj.gerber_obj.apertures[apid]['geometry']: + for elem in app_obj.gerber_obj.apertures[ap_id]['geometry']: new_elem = {} if 'solid' in elem: solid_geo = elem['solid'] @@ -4019,7 +4022,8 @@ class FlatCAMGrbEditor(QtCore.QObject): new_elem['follow'] = elem['follow'] temp_solid_geometry.append(deepcopy(new_elem)) - app_obj.gerber_obj.apertures[apid]['geometry'] = deepcopy(temp_solid_geometry) + app_obj.gerber_obj.apertures[ap_id]['geometry'] = deepcopy(temp_solid_geometry) + log.warning("Polygon difference done for %d apertures." % len(app_obj.gerber_obj.apertures)) try: @@ -4028,9 +4032,9 @@ class FlatCAMGrbEditor(QtCore.QObject): app_obj.results.append( app_obj.pool.apply_async(app_obj.add_apertures, args=(ap_id, ap_dict)) ) - except Exception as e: + except Exception as ee: log.debug( - "FlatCAMGrbEditor.edit_fcgerber.worker_job() Adding processes to pool --> %s" % str(e)) + "FlatCAMGrbEditor.edit_fcgerber.worker_job() Adding processes to pool --> %s" % str(ee)) traceback.print_exc() output = [] @@ -4222,7 +4226,7 @@ class FlatCAMGrbEditor(QtCore.QObject): except KeyError: self.app.inform.emit('[ERROR_NOTCL] %s' % _("There are no Aperture definitions in the file. Aborting Gerber creation.")) - except Exception as e: + except Exception: msg = '[ERROR] %s' % \ _("An internal error has occurred. See shell.\n") msg += traceback.format_exc() @@ -4240,7 +4244,7 @@ class FlatCAMGrbEditor(QtCore.QObject): self.results = [] return - self.app.inform.emit('[success] %s' % _("Done. Gerber editing finished.")) + self.app.inform.emit('[success] %s' % _("Done. Gerber editing finished.")) # make sure to clean the previous results self.results = [] @@ -4395,7 +4399,7 @@ class FlatCAMGrbEditor(QtCore.QObject): self.pos = self.canvas.translate_coords(event_pos) - if self.app.grid_status() == True: + if self.app.grid_status(): self.pos = self.app.geo_editor.snap(self.pos[0], self.pos[1]) else: self.pos = (self.pos[0], self.pos[1]) @@ -4462,7 +4466,7 @@ class FlatCAMGrbEditor(QtCore.QObject): right_button = 3 pos_canvas = self.canvas.translate_coords(event_pos) - if self.app.grid_status() == True: + if self.app.grid_status(): pos = self.app.geo_editor.snap(pos_canvas[0], pos_canvas[1]) else: pos = (pos_canvas[0], pos_canvas[1]) @@ -4625,7 +4629,7 @@ class FlatCAMGrbEditor(QtCore.QObject): return # # ## Snap coordinates - if self.app.grid_status() == True: + if self.app.grid_status(): x, y = self.app.geo_editor.snap(x, y) # Update cursor @@ -4755,7 +4759,7 @@ class FlatCAMGrbEditor(QtCore.QObject): try: self.shapes.add(shape=geometry.geo, color=color, face_color=color, layer=0, tolerance=self.tolerance) - except AttributeError as e: + except AttributeError: if type(geometry) == Point: return if len(color) == 9: @@ -5069,12 +5073,12 @@ class FlatCAMGrbEditor(QtCore.QObject): area = geo_el.geo['solid'].area try: upper_threshold_val = self.ma_upper_threshold_entry.get_value() - except Exception as e: + except Exception: return try: lower_threshold_val = self.ma_lower_threshold_entry.get_value() - except Exception as e: + except Exception: lower_threshold_val = 0.0 if float(upper_threshold_val) > area > float(lower_threshold_val): From 376c8058d96b8bbfeafd4d188d8be743bad5b3b7 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 4 Apr 2020 18:02:40 +0300 Subject: [PATCH 146/209] - fixed the Repeated code parsing in Excellon Parse --- README.md | 4 + flatcamParsers/ParseExcellon.py | 126 +++++++++++++++++--------------- 2 files changed, 72 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index 094cef18..d8ff21c6 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +4.04.2020 + +- fixed the Repeated code parsing in Excellon Parse + 1.04.2020 - updated the SVG parser to take into consideration the 'Close' svg element and paths that are made from a single line (we may need to switch to svgpathtools module) diff --git a/flatcamParsers/ParseExcellon.py b/flatcamParsers/ParseExcellon.py index 1e7f2565..406bbb16 100644 --- a/flatcamParsers/ParseExcellon.py +++ b/flatcamParsers/ParseExcellon.py @@ -618,82 +618,92 @@ class Excellon(Geometry): match = self.coordsnoperiod_re.search(eline) if match: matchr = self.repeat_re.search(eline) - if matchr: + if matchr: # if we have a repeat command repeat = int(matchr.group(1)) - try: - x = self.parse_number(match.group(1)) - repeating_x = current_x - current_x = x - except TypeError: - x = current_x - repeating_x = 0 - except Exception: - return + if match.group(1): + repeating_x = self.parse_number(match.group(1)) + else: + repeating_x = 0 - try: - y = self.parse_number(match.group(2)) - repeating_y = current_y - current_y = y - except TypeError: - y = current_y - repeating_y = 0 - except Exception: - return + if match.group(2): + repeating_y = self.parse_number(match.group(2)) + else: + repeating_y = 0 - if x is None or y is None: - log.error("Missing coordinates") + coordx = current_x + coordy = current_y + + while repeat > 0: + if repeating_x: + coordx += repeating_x + if repeating_y: + coordy += repeating_y + self.drills.append({'point': Point((coordx, coordy)), 'tool': current_tool}) + + repeat -= 1 + current_x = coordx + current_y = coordy continue - # ## Excellon Routing parse - if len(re.findall("G00", eline)) > 0: - self.match_routing_start = 'G00' + else: # those are normal coordinates + try: + x = self.parse_number(match.group(1)) + current_x = x + except TypeError: + x = current_x + except Exception: + return - # signal that there are milling slots operations - self.defaults['excellon_drills'] = False + try: + y = self.parse_number(match.group(2)) + current_y = y + except TypeError: + y = current_y + except Exception: + return - self.routing_flag = 0 - slot_start_x = x - slot_start_y = y - continue + if x is None or y is None: + log.error("Missing coordinates") + continue - if self.routing_flag == 0: - if len(re.findall("G01", eline)) > 0: - self.match_routing_stop = 'G01' + # ## Excellon Routing parse + if len(re.findall("G00", eline)) > 0: + self.match_routing_start = 'G00' # signal that there are milling slots operations self.defaults['excellon_drills'] = False - self.routing_flag = 1 - slot_stop_x = x - slot_stop_y = y - self.slots.append( - { - 'start': Point(slot_start_x, slot_start_y), - 'stop': Point(slot_stop_x, slot_stop_y), - 'tool': current_tool - } - ) + self.routing_flag = 0 + slot_start_x = x + slot_start_y = y continue - if self.match_routing_start is None and self.match_routing_stop is None: - if repeat == 0: + if self.routing_flag == 0: + if len(re.findall("G01", eline)) > 0: + self.match_routing_stop = 'G01' + + # signal that there are milling slots operations + self.defaults['excellon_drills'] = False + + self.routing_flag = 1 + slot_stop_x = x + slot_stop_y = y + self.slots.append( + { + 'start': Point(slot_start_x, slot_start_y), + 'stop': Point(slot_stop_x, slot_stop_y), + 'tool': current_tool + } + ) + continue + + if self.match_routing_start is None and self.match_routing_stop is None: # signal that there are drill operations self.defaults['excellon_drills'] = True self.drills.append({'point': Point((x, y)), 'tool': current_tool}) - else: - coordx = x - coordy = y - while repeat > 0: - if repeating_x: - coordx = (repeat * x) + repeating_x - if repeating_y: - coordy = (repeat * y) + repeating_y - self.drills.append({'point': Point((coordx, coordy)), 'tool': current_tool}) - repeat -= 1 - repeating_x = repeating_y = 0 - # log.debug("{:15} {:8} {:8}".format(eline, x, y)) - continue + # log.debug("{:15} {:8} {:8}".format(eline, x, y)) + continue # ## Coordinates with period: Use literally. # ## match = self.coordsperiod_re.search(eline) From bee2a9dddca45afe2946cdbc7e0ae0786d629004 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 5 Apr 2020 13:48:47 +0300 Subject: [PATCH 147/209] - made sure that the HDPI scaling attribute is set before the QApplication is started - made sure that when saving a project, the app will try to update the active object from UI form only if there is an active object --- FlatCAM.py | 10 +++++----- FlatCAMApp.py | 4 +++- README.md | 5 +++++ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/FlatCAM.py b/FlatCAM.py index 02c56c9d..eb7410b2 100644 --- a/FlatCAM.py +++ b/FlatCAM.py @@ -55,6 +55,11 @@ if __name__ == '__main__': # else: # QGuiApplication.setAttribute(Qt.AA_EnableHighDpiScaling, False) + if hdpi_support == 2: + QtWidgets.QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True) + else: + QtWidgets.QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, False) + app = QtWidgets.QApplication(sys.argv) # apply style @@ -63,11 +68,6 @@ if __name__ == '__main__': style = settings.value('style', type=str) app.setStyle(style) - if hdpi_support == 2: - app.setAttribute(Qt.AA_EnableHighDpiScaling, True) - else: - app.setAttribute(Qt.AA_EnableHighDpiScaling, False) - fc = App() sys.exit(app.exec_()) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index e95e6085..f23c700a 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -12809,7 +12809,9 @@ class App(QtCore.QObject): # Capture the latest changes # Current object try: - self.collection.get_active().read_form() + current_object = self.collection.get_active() + if current_object: + current_object.read_form() except Exception as e: self.log.debug("save_project() --> There was no active object. Skipping read_form. %s" % str(e)) pass diff --git a/README.md b/README.md index d8ff21c6..f540a075 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,11 @@ CAD program, and create G-Code for Isolation routing. ================================================= +5.04.2020 + +- made sure that the HDPI scaling attribute is set before the QApplication is started +- made sure that when saving a project, the app will try to update the active object from UI form only if there is an active object + 4.04.2020 - fixed the Repeated code parsing in Excellon Parse From b53c1c403a32a807278c14579cd035f545988c65 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 5 Apr 2020 16:32:16 +0300 Subject: [PATCH 148/209] - fix for contextual menus on canvas when using PyQt versions > 5.12.1 - decision on which mouse button to use for panning is done now once when setting the plotcanvas --- FlatCAM.py | 4 ++-- FlatCAMApp.py | 28 +++++++++++++++++++++------- README.md | 2 ++ flatcamGUI/GUIElements.py | 4 +++- 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/FlatCAM.py b/FlatCAM.py index eb7410b2..546877a3 100644 --- a/FlatCAM.py +++ b/FlatCAM.py @@ -69,5 +69,5 @@ if __name__ == '__main__': app.setStyle(style) fc = App() - - sys.exit(app.exec_()) + # sys.exit(app.exec_()) + app.exec_() \ No newline at end of file diff --git a/FlatCAMApp.py b/FlatCAMApp.py index f23c700a..d7e17179 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -5328,12 +5328,14 @@ class App(QtCore.QObject): # quit app by signalling for self.kill_app() method # self.close_app_signal.emit() + QtWidgets.qApp.quit() # When the main event loop is not started yet in which case the qApp.quit() will do nothing # we use the following command sys.exit(0) def kill_app(self): + # QtCore.QCoreApplication.quit() QtWidgets.qApp.quit() # When the main event loop is not started yet in which case the qApp.quit() will do nothing # we use the following command @@ -8667,8 +8669,8 @@ class App(QtCore.QObject): def populate_cmenu_grids(self): units = self.defaults['units'].lower() - for act in self.ui.cmenu_gridmenu.actions(): - act.triggered.disconnect() + # for act in self.ui.cmenu_gridmenu.actions(): + # act.triggered.disconnect() self.ui.cmenu_gridmenu.clear() sorted_list = sorted(self.defaults["global_grid_context_menu"][str(units)]) @@ -8807,13 +8809,13 @@ class App(QtCore.QObject): if self.is_legacy is False: event_pos = event.pos - pan_button = 2 if self.defaults["global_pan_button"] == '2'else 3 - # Set the mouse button for panning - self.plotcanvas.view.camera.pan_button_setting = pan_button + # pan_button = 2 if self.defaults["global_pan_button"] == '2'else 3 + # # Set the mouse button for panning + # self.plotcanvas.view.camera.pan_button_setting = pan_button else: event_pos = (event.xdata, event.ydata) # Matplotlib has the middle and right buttons mapped in reverse compared with VisPy - pan_button = 3 if self.defaults["global_pan_button"] == '2' else 2 + # pan_button = 3 if self.defaults["global_pan_button"] == '2' else 2 # So it can receive key presses self.plotcanvas.native.setFocus() @@ -8873,9 +8875,14 @@ class App(QtCore.QObject): self.ui.popMenu.mouse_is_panning = False - if not origin_click: + if origin_click is None: # if the RMB is clicked and mouse is moving over plot then 'panning_action' is True if event.button == pan_button and self.event_is_dragging == 1: + + # if a popup menu is active don't change mouse_is_panning variable because is not True + if self.ui.popMenu.popup_active: + self.ui.popMenu.popup_active = False + return self.ui.popMenu.mouse_is_panning = True return @@ -8977,6 +8984,8 @@ class App(QtCore.QObject): # if the released mouse button was RMB then test if it was a panning motion or not, if not it was a context # canvas menu if event.button == right_button and self.ui.popMenu.mouse_is_panning is False: # right click + self.ui.popMenu.mouse_is_panning = False + self.cursor = QtGui.QCursor() self.populate_cmenu_grids() self.ui.popMenu.popup(self.cursor.pos()) @@ -12465,6 +12474,11 @@ class App(QtCore.QObject): # So it can receive key presses self.plotcanvas.native.setFocus() + if self.is_legacy is False: + pan_button = 2 if self.defaults["global_pan_button"] == '2'else 3 + # Set the mouse button for panning + self.plotcanvas.view.camera.pan_button_setting = pan_button + self.mm = self.plotcanvas.graph_event_connect('mouse_move', self.on_mouse_move_over_plot) self.mp = self.plotcanvas.graph_event_connect('mouse_press', self.on_mouse_click_over_plot) self.mr = self.plotcanvas.graph_event_connect('mouse_release', self.on_mouse_click_release_over_plot) diff --git a/README.md b/README.md index f540a075..9ff2dce0 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ CAD program, and create G-Code for Isolation routing. - made sure that the HDPI scaling attribute is set before the QApplication is started - made sure that when saving a project, the app will try to update the active object from UI form only if there is an active object +- fix for contextual menus on canvas when using PyQt versions > 5.12.1 +- decision on which mouse button to use for panning is done now once when setting the plotcanvas 4.04.2020 diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index 1b34118a..f851d16e 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -1419,10 +1419,12 @@ class FCMenu(QtWidgets.QMenu): def __init__(self): super().__init__() self.mouse_is_panning = False + self.popup_active = False def popup(self, pos, action=None): - self.mouse_is_panning = False super().popup(pos) + self.mouse_is_panning = False + self.popup_active = True class FCTab(QtWidgets.QTabWidget): From 836122ca2481adcb36688c7432198d9d397ea7ac Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 5 Apr 2020 16:53:10 +0300 Subject: [PATCH 149/209] - fix to work with Python 3.8 (closing the application) --- FlatCAMApp.py | 9 +++++---- README.md | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index d7e17179..e3d570d2 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -5280,7 +5280,7 @@ class App(QtCore.QObject): :return: None """ self.save_defaults(silent=True) - log.debug("App.final_save() --> App Defaults saved.") + log.debug("App.quit_application() --> App Defaults saved.") if self.cmd_line_headless != 1: # save app state to file @@ -5312,13 +5312,13 @@ class App(QtCore.QObject): # This will write the setting to the platform specific storage. del stgs - log.debug("App.final_save() --> App UI state saved.") + log.debug("App.quit_application() --> App UI state saved.") # try to quit the QThread that run ArgsThread class try: self.th.quit() except Exception as e: - log.debug("App.final_save() --> %s" % str(e)) + log.debug("App.quit_application() --> %s" % str(e)) # try to quit the Socket opened by ArgsThread class try: @@ -5332,7 +5332,8 @@ class App(QtCore.QObject): QtWidgets.qApp.quit() # When the main event loop is not started yet in which case the qApp.quit() will do nothing # we use the following command - sys.exit(0) + # sys.exit(0) + os._exit(0) # fix to work with Python 3.8 def kill_app(self): # QtCore.QCoreApplication.quit() diff --git a/README.md b/README.md index 9ff2dce0..e38cf11e 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ CAD program, and create G-Code for Isolation routing. - made sure that when saving a project, the app will try to update the active object from UI form only if there is an active object - fix for contextual menus on canvas when using PyQt versions > 5.12.1 - decision on which mouse button to use for panning is done now once when setting the plotcanvas +- fix to work with Python 3.8 (closing the application) 4.04.2020 From fdd5344581cfdb0c696d8cf8fe5a8eb764ce5544 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 5 Apr 2020 21:11:48 +0300 Subject: [PATCH 150/209] - fixed bug in Gerber parser that allowed loading as Gerber of a file that is not a Gerber - fixed a bug in extension detection for Gerber files that allowed in the filtered list files that extension *.gb* - added a processEvents method in the Gerber parser parse_lines() method --- FlatCAM.py | 2 +- FlatCAMApp.py | 5 ++--- README.md | 3 +++ flatcamParsers/ParseGerber.py | 6 ++++-- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/FlatCAM.py b/FlatCAM.py index 546877a3..33b2b7c7 100644 --- a/FlatCAM.py +++ b/FlatCAM.py @@ -1,7 +1,7 @@ import sys import os -from PyQt5 import QtWidgets, QtGui +from PyQt5 import QtWidgets from PyQt5.QtCore import QSettings, Qt from FlatCAMApp import App from flatcamGUI import VisPyPatches diff --git a/FlatCAMApp.py b/FlatCAMApp.py index e3d570d2..cc33ca1b 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -9543,7 +9543,7 @@ class App(QtCore.QObject): _filter_ = "Gerber Files (*.gbr *.ger *.gtl *.gbl *.gts *.gbs *.gtp *.gbp *.gto *.gbo *.gm1 *.gml *.gm3 *" \ ".gko *.cmp *.sol *.stc *.sts *.plc *.pls *.crc *.crs *.tsm *.bsm *.ly2 *.ly15 *.dim *.mil *.grb" \ - "*.top *.bot *.smt *.smb *.sst *.ssb *.spt *.spb *.pho *.gdo *.art *.gbd *.gb*);;" \ + "*.top *.bot *.smt *.smb *.sst *.ssb *.spt *.spb *.pho *.gdo *.art *.gbd);;" \ "Protel Files (*.gtl *.gbl *.gts *.gbs *.gto *.gbo *.gtp *.gbp *.gml *.gm1 *.gm3 *.gko);;" \ "Eagle Files (*.cmp *.sol *.stc *.sts *.plc *.pls *.crc *.crs *.tsm *.bsm *.ly2 *.ly15 *.dim " \ "*.mil);;" \ @@ -9570,8 +9570,7 @@ class App(QtCore.QObject): color=QtGui.QColor("gray")) if len(filenames) == 0: - self.inform.emit('[WARNING_NOTCL] %s' % - _("Open Gerber cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Open Gerber cancelled.")) else: for filename in filenames: if filename != '': diff --git a/README.md b/README.md index e38cf11e..8fe6e57d 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,9 @@ CAD program, and create G-Code for Isolation routing. - fix for contextual menus on canvas when using PyQt versions > 5.12.1 - decision on which mouse button to use for panning is done now once when setting the plotcanvas - fix to work with Python 3.8 (closing the application) +- fixed bug in Gerber parser that allowed loading as Gerber of a file that is not a Gerber +- fixed a bug in extension detection for Gerber files that allowed in the filtered list files that extension *.gb* +- added a processEvents method in the Gerber parser parse_lines() method 4.04.2020 diff --git a/flatcamParsers/ParseGerber.py b/flatcamParsers/ParseGerber.py index deba943e..bad7b97d 100644 --- a/flatcamParsers/ParseGerber.py +++ b/flatcamParsers/ParseGerber.py @@ -1,4 +1,4 @@ - +from PyQt5 import QtWidgets from camlib import Geometry, arc, arc_angle, ApertureMacro import FlatCAMApp @@ -1416,6 +1416,8 @@ class Gerber(Geometry): # ######### Line did not match any pattern. Warn user. ########## # ################################################################ log.warning("Line ignored (%d): %s" % (line_num, gline)) + # provide the app with a way to process the GUI events when in a blocking loop + QtWidgets.QApplication.processEvents() try: path_length = len(path) @@ -1475,7 +1477,7 @@ class Gerber(Geometry): sol_geo_length = 1 try: - if buff_length == 0 and sol_geo_length == 0: + if buff_length == 0 and sol_geo_length in [0, 1]: log.error("Object is not Gerber file or empty. Aborting Object creation.") return 'fail' except TypeError as e: From 139baaff6468a0d85fd062c6b7d058c74ea860b4 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 5 Apr 2020 21:50:32 +0300 Subject: [PATCH 151/209] - fixed issue #386 - multiple Cut operation on a edited object created a crash due of the bounds() method --- FlatCAMApp.py | 2 +- README.md | 2 ++ camlib.py | 16 ++++++++++++++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index cc33ca1b..3d225531 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -3520,7 +3520,7 @@ class App(QtCore.QObject): # update the geo object options so it is including the bounding box values try: - xmin, ymin, xmax, ymax = edited_obj.bounds() + xmin, ymin, xmax, ymax = edited_obj.bounds(flatten=True) edited_obj.options['xmin'] = xmin edited_obj.options['ymin'] = ymin edited_obj.options['xmax'] = xmax diff --git a/README.md b/README.md index 8fe6e57d..aa96371a 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,8 @@ CAD program, and create G-Code for Isolation routing. - fixed bug in Gerber parser that allowed loading as Gerber of a file that is not a Gerber - fixed a bug in extension detection for Gerber files that allowed in the filtered list files that extension *.gb* - added a processEvents method in the Gerber parser parse_lines() method +- fixed issue #386 - multiple Cut operation on a edited object created a crash due of the bounds() method + 4.04.2020 diff --git a/camlib.py b/camlib.py index 2770021c..bb192a4b 100644 --- a/camlib.py +++ b/camlib.py @@ -614,10 +614,12 @@ class Geometry(object): log.warning("Not implemented.") self.solid_geometry = cascaded_union(diffs) - def bounds(self): + def bounds(self, flatten=False): """ Returns coordinates of rectangular bounds of geometry: (xmin, ymin, xmax, ymax). + :param flatten: will flatten the solid_geometry if True + :return: """ # fixed issue of getting bounds only for one level lists of objects # now it can get bounds for nested lists of objects @@ -661,7 +663,13 @@ class Geometry(object): maxy_list = [] for tool in self.tools: - minx, miny, maxx, maxy = bounds_rec(self.tools[tool]['solid_geometry']) + working_geo = self.tools[tool]['solid_geometry'] + + if flatten: + self.flatten(geometry=working_geo, reset=True) + working_geo = self.flat_geometry + + minx, miny, maxx, maxy = bounds_rec(working_geo) minx_list.append(minx) miny_list.append(miny) maxx_list.append(maxx) @@ -669,6 +677,10 @@ class Geometry(object): return(min(minx_list), min(miny_list), max(maxx_list), max(maxy_list)) else: + if flatten: + self.flatten(reset=True) + self.solid_geometry = self.flat_geometry + bounds_coords = bounds_rec(self.solid_geometry) return bounds_coords From 8a2ed1c72604cdff9a251cffe802b5dc6011d52a Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 6 Apr 2020 01:56:38 +0300 Subject: [PATCH 152/209] - some changes in the Geometry UI --- FlatCAMObj.py | 41 ++++++-- README.md | 2 +- flatcamGUI/FlatCAMGUI.py | 4 + flatcamGUI/GUIElements.py | 6 +- flatcamGUI/ObjectUI.py | 200 ++++++++++++++++++++------------------ 5 files changed, 149 insertions(+), 104 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index ed31bb98..68edd0a2 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -233,7 +233,10 @@ class FlatCAMObj(QtCore.QObject): # self.ui.scale_entry.returnPressed.connect(self.on_scale_button_click) except Exception as e: self.app.log.debug("FlatCAMObj.build_ui() --> Nothing to remove: %s" % str(e)) + self.app.ui.selected_scroll_area.setWidget(self.ui) + # self.ui.setMinimumWidth(100) + # self.ui.setMaximumWidth(self.app.ui.selected_tab.sizeHint().width()) self.muted_ui = False @@ -4076,6 +4079,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.outline_color = self.app.defaults['geometry_plot_line'] self.alpha_level = 'FF' + self.param_fields = {} + # Attributes to be included in serialization # Always append to it because it carries contents # from predecessors. @@ -4244,6 +4249,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): assert isinstance(self.ui, GeometryObjectUI), \ "Expected a GeometryObjectUI, got %s" % type(self.ui) + self.units = self.app.defaults['units'].upper() self.units_found = self.app.defaults['units'] @@ -4277,6 +4283,24 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): "cnctooldia": self.ui.addtool_entry }) + self.param_fields.update({ + "vtipdia": self.ui.tipdia_entry, + "vtipangle": self.ui.tipangle_entry, + "cutz": self.ui.cutz_entry, + "depthperpass": self.ui.maxdepth_entry, + "multidepth": self.ui.mpass_cb, + "travelz": self.ui.travelz_entry, + "feedrate": self.ui.cncfeedrate_entry, + "feedrate_z": self.ui.feedrate_z_entry, + "feedrate_rapid": self.ui.feedrate_rapid_entry, + "extracut": self.ui.extracut_cb, + "extracut_length": self.ui.e_cut_entry, + "spindlespeed": self.ui.cncspindlespeed_entry, + "dwelltime": self.ui.dwelltime_entry, + "dwell": self.ui.dwell_cb, + "pdepth": self.ui.pdepth_entry, + "pfeedrate": self.ui.feedrate_probe_entry, + }) # Fill form fields only on object create self.to_form() @@ -4486,8 +4510,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): def ui_connect(self): # on any change to the widgets that matter it will be called self.gui_form_to_storage which will save the # changes in geometry UI - for i in range(self.ui.grid3.count()): - current_widget = self.ui.grid3.itemAt(i).widget() + for i in self.param_fields: + current_widget = self.param_fields[i] if isinstance(current_widget, FCCheckBox): current_widget.stateChanged.connect(self.gui_form_to_storage) elif isinstance(current_widget, FCComboBox): @@ -4527,27 +4551,28 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): # on any change to the widgets that matter it will be called self.gui_form_to_storage which will save the # changes in geometry UI - for i in range(self.ui.grid3.count()): - current_widget = self.ui.grid3.itemAt(i).widget() + for i in self.param_fields: + # current_widget = self.ui.grid3.itemAt(i).widget() + current_widget = self.param_fields[i] if isinstance(current_widget, FCCheckBox): try: - self.ui.grid3.itemAt(i).widget().stateChanged.disconnect(self.gui_form_to_storage) + current_widget.stateChanged.disconnect(self.gui_form_to_storage) except (TypeError, AttributeError): pass elif isinstance(current_widget, FCComboBox): try: - self.ui.grid3.itemAt(i).widget().currentIndexChanged.disconnect(self.gui_form_to_storage) + current_widget.currentIndexChanged.disconnect(self.gui_form_to_storage) except (TypeError, AttributeError): pass elif isinstance(current_widget, LengthEntry) or isinstance(current_widget, IntEntry) or \ isinstance(current_widget, FCEntry) or isinstance(current_widget, FloatEntry): try: - self.ui.grid3.itemAt(i).widget().editingFinished.disconnect(self.gui_form_to_storage) + current_widget.editingFinished.disconnect(self.gui_form_to_storage) except (TypeError, AttributeError): pass elif isinstance(current_widget, FCSpinner) or isinstance(current_widget, FCDoubleSpinner): try: - self.ui.grid3.itemAt(i).widget().returnPressed.disconnect(self.gui_form_to_storage) + current_widget.returnPressed.disconnect(self.gui_form_to_storage) except TypeError: pass diff --git a/README.md b/README.md index aa96371a..95a692dc 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ CAD program, and create G-Code for Isolation routing. - fixed a bug in extension detection for Gerber files that allowed in the filtered list files that extension *.gb* - added a processEvents method in the Gerber parser parse_lines() method - fixed issue #386 - multiple Cut operation on a edited object created a crash due of the bounds() method - +- some changes in the Geometry UI 4.04.2020 diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index 35b9ae2a..9fdd90fd 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -1112,10 +1112,13 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # ########################## SELECTED Tab # ############################## # ######################################################################## self.selected_tab = QtWidgets.QWidget() + # self.selected_tab.setMinimumWidth(270) self.selected_tab.setObjectName("selected_tab") self.selected_tab_layout = QtWidgets.QVBoxLayout(self.selected_tab) self.selected_tab_layout.setContentsMargins(2, 2, 2, 2) + self.selected_scroll_area = VerticalScrollArea() + # self.selected_scroll_area.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents) self.selected_tab_layout.addWidget(self.selected_scroll_area) self.notebook.addTab(self.selected_tab, _("Selected")) @@ -1128,6 +1131,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.tool_tab_layout.setContentsMargins(2, 2, 2, 2) self.notebook.addTab(self.tool_tab, _("Tool")) self.tool_scroll_area = VerticalScrollArea() + # self.tool_scroll_area.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents) self.tool_tab_layout.addWidget(self.tool_scroll_area) # ######################################################################## diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index f851d16e..4965b954 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -898,6 +898,10 @@ class FCDoubleSpinner(QtWidgets.QDoubleSpinBox): self.setRange(min_val, max_val) + # def sizeHint(self): + # default_hint_size = super(FCDoubleSpinner, self).sizeHint() + # return QtCore.QSize(EDIT_SIZE_HINT, default_hint_size.height()) + class FCCheckBox(QtWidgets.QCheckBox): def __init__(self, label='', parent=None): @@ -2076,7 +2080,7 @@ class FCDetachableTab2(FCDetachableTab): class VerticalScrollArea(QtWidgets.QScrollArea): """ This widget extends QtGui.QScrollArea to make a vertical-only - scroll area that also expands horizontally to accomodate + scroll area that also expands horizontally to accommodate its contents. """ def __init__(self, parent=None): diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index 39de3558..3b91514c 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -37,7 +37,7 @@ class ObjectUI(QtWidgets.QWidget): def __init__(self, app, icon_file='share/flatcam_icon32.png', title=_('FlatCAM Object'), parent=None, common=True): QtWidgets.QWidget.__init__(self, parent=parent) - + self.app = app self.decimals = app.decimals @@ -1427,6 +1427,7 @@ class GeometryObjectUI(ObjectUI): # ## Object name self.name_hlay = QtWidgets.QHBoxLayout() self.custom_box.addLayout(self.name_hlay) + name_label = QtWidgets.QLabel("%s:" % _("Name")) self.name_entry = FCEntry() self.name_entry.setFocusPolicy(QtCore.Qt.StrongFocus) @@ -1438,12 +1439,25 @@ class GeometryObjectUI(ObjectUI): self.geo_tools_frame = QtWidgets.QFrame() self.geo_tools_frame.setContentsMargins(0, 0, 0, 0) self.custom_box.addWidget(self.geo_tools_frame) + self.geo_tools_box = QtWidgets.QVBoxLayout() self.geo_tools_box.setContentsMargins(0, 0, 0, 0) self.geo_tools_frame.setLayout(self.geo_tools_box) - hlay_plot = QtWidgets.QHBoxLayout() - self.geo_tools_box.addLayout(hlay_plot) + # ************************************************************************ + # ************** TABLE BOX FRAME ***************************************** + # ************************************************************************ + self.geo_table_frame = QtWidgets.QFrame() + self.geo_table_frame.setContentsMargins(0, 0, 0, 0) + self.geo_tools_box.addWidget(self.geo_table_frame) + self.geo_table_box = QtWidgets.QVBoxLayout() + self.geo_table_box.setContentsMargins(0, 0, 0, 0) + self.geo_table_frame.setLayout(self.geo_table_box) + + grid0 = QtWidgets.QGridLayout() + self.geo_table_box.addLayout(grid0) + grid0.setColumnStretch(0, 0) + grid0.setColumnStretch(1, 1) # ### Tools #### self.tools_table_label = QtWidgets.QLabel('%s:' % _('Tools Table')) @@ -1461,7 +1475,7 @@ class GeometryObjectUI(ObjectUI): "grayed out and Cut Z is automatically calculated from the newly \n" "showed UI form entries named V-Tip Dia and V-Tip Angle.") ) - hlay_plot.addWidget(self.tools_table_label) + grid0.addWidget(self.tools_table_label, 0, 0) # Plot CB # self.plot_cb = QtWidgets.QCheckBox('Plot') @@ -1470,11 +1484,10 @@ class GeometryObjectUI(ObjectUI): _("Plot (show) this object.") ) self.plot_cb.setLayoutDirection(QtCore.Qt.RightToLeft) - hlay_plot.addStretch() - hlay_plot.addWidget(self.plot_cb) + grid0.addWidget(self.plot_cb, 0, 1) self.geo_tools_table = FCTable() - self.geo_tools_box.addWidget(self.geo_tools_table) + grid0.addWidget(self.geo_tools_table, 1, 0, 1, 2) self.geo_tools_table.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents) self.geo_tools_table.setColumnCount(7) @@ -1535,10 +1548,10 @@ class GeometryObjectUI(ObjectUI): # self.geo_tools_table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) # Tool Offset - self.grid1 = QtWidgets.QGridLayout() - self.geo_tools_box.addLayout(self.grid1) - self.grid1.setColumnStretch(0, 0) - self.grid1.setColumnStretch(1, 1) + grid1 = QtWidgets.QGridLayout() + self.geo_table_box.addLayout(grid1) + grid1.setColumnStretch(0, 0) + grid1.setColumnStretch(1, 1) self.tool_offset_lbl = QtWidgets.QLabel('%s:' % _('Tool Offset')) self.tool_offset_lbl.setToolTip( @@ -1554,16 +1567,16 @@ class GeometryObjectUI(ObjectUI): self.tool_offset_entry.set_range(-9999.9999, 9999.9999) self.tool_offset_entry.setSingleStep(0.1) - self.grid1.addWidget(self.tool_offset_lbl, 0, 0) - self.grid1.addWidget(self.tool_offset_entry, 0, 1, 1, 2) + grid1.addWidget(self.tool_offset_lbl, 0, 0) + grid1.addWidget(self.tool_offset_entry, 0, 1) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - self.grid1.addWidget(separator_line, 1, 0, 1, 3) + grid1.addWidget(separator_line, 1, 0, 1, 2) self.tool_sel_label = QtWidgets.QLabel('%s' % _("New Tool")) - self.grid1.addWidget(self.tool_sel_label, 2, 0, 1, 3) + grid1.addWidget(self.tool_sel_label, 2, 0, 1, 2) self.addtool_entry_lbl = QtWidgets.QLabel('%s:' % _('Tool Dia')) self.addtool_entry_lbl.setToolTip( @@ -1574,30 +1587,30 @@ class GeometryObjectUI(ObjectUI): self.addtool_entry.set_range(0.00001, 9999.9999) self.addtool_entry.setSingleStep(0.1) + grid1.addWidget(self.addtool_entry_lbl, 3, 0) + grid1.addWidget(self.addtool_entry, 3, 1) + self.addtool_btn = QtWidgets.QPushButton(_('Add')) self.addtool_btn.setToolTip( _("Add a new tool to the Tool Table\n" "with the specified diameter.") ) - - self.grid1.addWidget(self.addtool_entry_lbl, 3, 0) - self.grid1.addWidget(self.addtool_entry, 3, 1) - self.grid1.addWidget(self.addtool_btn, 3, 2) + grid1.addWidget(self.addtool_btn, 4, 0, 1, 2) self.addtool_from_db_btn = QtWidgets.QPushButton(_('Add from DB')) self.addtool_from_db_btn.setToolTip( _("Add a new tool to the Tool Table\n" "from the Tool DataBase.") ) - self.grid1.addWidget(self.addtool_from_db_btn, 4, 0, 1, 3) + grid1.addWidget(self.addtool_from_db_btn, 7, 0, 1, 2) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - self.grid1.addWidget(separator_line, 5, 0, 1, 3) + grid1.addWidget(separator_line, 9, 0, 1, 2) grid2 = QtWidgets.QGridLayout() - self.geo_tools_box.addLayout(grid2) + self.geo_table_box.addLayout(grid2) self.copytool_btn = QtWidgets.QPushButton(_('Copy')) self.copytool_btn.setToolTip( @@ -1614,17 +1627,33 @@ class GeometryObjectUI(ObjectUI): grid2.addWidget(self.copytool_btn, 0, 0) grid2.addWidget(self.deltool_btn, 0, 1) - self.empty_label = QtWidgets.QLabel('') - self.geo_tools_box.addWidget(self.empty_label) + self.geo_table_box.addWidget(QtWidgets.QLabel('')) # ########################################################### # ############# Create CNC Job ############################## # ########################################################### + self.geo_param_frame = QtWidgets.QFrame() + self.geo_param_frame.setContentsMargins(0, 0, 0, 0) + self.geo_tools_box.addWidget(self.geo_param_frame) + + self.geo_param_box = QtWidgets.QVBoxLayout() + self.geo_param_box.setContentsMargins(0, 0, 0, 0) + self.geo_param_frame.setLayout(self.geo_param_box) + separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - self.geo_tools_box.addWidget(separator_line) + self.geo_param_box.addWidget(separator_line) + + # ################################################################# + # ################# GRID LAYOUT 3 ############################### + # ################################################################# + + grid3 = QtWidgets.QGridLayout() + grid3.setColumnStretch(0, 0) + grid3.setColumnStretch(1, 1) + self.geo_param_box.addLayout(grid3) # ### Tools Data ## ## self.tool_data_label = QtWidgets.QLabel( @@ -1635,24 +1664,7 @@ class GeometryObjectUI(ObjectUI): "Each tool store it's own set of such data." ) ) - self.geo_tools_box.addWidget(self.tool_data_label) - - self.geo_param_frame = QtWidgets.QFrame() - self.geo_param_frame.setContentsMargins(0, 0, 0, 0) - self.geo_tools_box.addWidget(self.geo_param_frame) - - self.geo_param_box = QtWidgets.QVBoxLayout() - self.geo_param_box.setContentsMargins(0, 0, 0, 0) - self.geo_param_frame.setLayout(self.geo_param_box) - - # ################################################################# - # ################# GRID LAYOUT 3 ############################### - # ################################################################# - - self.grid3 = QtWidgets.QGridLayout() - self.grid3.setColumnStretch(0, 0) - self.grid3.setColumnStretch(1, 1) - self.geo_param_box.addLayout(self.grid3) + grid3.addWidget(self.tool_data_label, 0, 0, 1, 2) # Tip Dia self.tipdialabel = QtWidgets.QLabel('%s:' % _('V-Tip Dia')) @@ -1666,8 +1678,8 @@ class GeometryObjectUI(ObjectUI): self.tipdia_entry.set_range(0.00001, 9999.9999) self.tipdia_entry.setSingleStep(0.1) - self.grid3.addWidget(self.tipdialabel, 1, 0) - self.grid3.addWidget(self.tipdia_entry, 1, 1) + grid3.addWidget(self.tipdialabel, 1, 0) + grid3.addWidget(self.tipdia_entry, 1, 1) # Tip Angle self.tipanglelabel = QtWidgets.QLabel('%s:' % _('V-Tip Angle')) @@ -1682,8 +1694,8 @@ class GeometryObjectUI(ObjectUI): self.tipangle_entry.set_range(1.0, 180.0) self.tipangle_entry.setSingleStep(1) - self.grid3.addWidget(self.tipanglelabel, 2, 0) - self.grid3.addWidget(self.tipangle_entry, 2, 1) + grid3.addWidget(self.tipanglelabel, 2, 0) + grid3.addWidget(self.tipangle_entry, 2, 1) # Cut Z self.cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z')) @@ -1703,8 +1715,8 @@ class GeometryObjectUI(ObjectUI): self.cutz_entry.setSingleStep(0.1) - self.grid3.addWidget(self.cutzlabel, 3, 0) - self.grid3.addWidget(self.cutz_entry, 3, 1) + grid3.addWidget(self.cutzlabel, 3, 0) + grid3.addWidget(self.cutz_entry, 3, 1) # Multi-pass self.mpass_cb = FCCheckBox('%s:' % _("Multi-Depth")) @@ -1729,8 +1741,8 @@ class GeometryObjectUI(ObjectUI): ) self.ois_mpass_geo = OptionalInputSection(self.mpass_cb, [self.maxdepth_entry]) - self.grid3.addWidget(self.mpass_cb, 4, 0) - self.grid3.addWidget(self.maxdepth_entry, 4, 1) + grid3.addWidget(self.mpass_cb, 4, 0) + grid3.addWidget(self.maxdepth_entry, 4, 1) # Travel Z self.travelzlabel = QtWidgets.QLabel('%s:' % _('Travel Z')) @@ -1748,8 +1760,8 @@ class GeometryObjectUI(ObjectUI): self.travelz_entry.setSingleStep(0.1) - self.grid3.addWidget(self.travelzlabel, 5, 0) - self.grid3.addWidget(self.travelz_entry, 5, 1) + grid3.addWidget(self.travelzlabel, 5, 0) + grid3.addWidget(self.travelz_entry, 5, 1) # Feedrate X-Y self.frlabel = QtWidgets.QLabel('%s:' % _('Feedrate X-Y')) @@ -1762,8 +1774,8 @@ class GeometryObjectUI(ObjectUI): self.cncfeedrate_entry.set_range(0, 99999.9999) self.cncfeedrate_entry.setSingleStep(0.1) - self.grid3.addWidget(self.frlabel, 10, 0) - self.grid3.addWidget(self.cncfeedrate_entry, 10, 1) + grid3.addWidget(self.frlabel, 10, 0) + grid3.addWidget(self.cncfeedrate_entry, 10, 1) # Feedrate Z (Plunge) self.frzlabel = QtWidgets.QLabel('%s:' % _('Feedrate Z')) @@ -1777,8 +1789,8 @@ class GeometryObjectUI(ObjectUI): self.feedrate_z_entry.set_range(0, 99999.9999) self.feedrate_z_entry.setSingleStep(0.1) - self.grid3.addWidget(self.frzlabel, 11, 0) - self.grid3.addWidget(self.feedrate_z_entry, 11, 1) + grid3.addWidget(self.frzlabel, 11, 0) + grid3.addWidget(self.feedrate_z_entry, 11, 1) # Feedrate rapids self.fr_rapidlabel = QtWidgets.QLabel('%s:' % _('Feedrate Rapids')) @@ -1794,8 +1806,8 @@ class GeometryObjectUI(ObjectUI): self.feedrate_rapid_entry.set_range(0, 99999.9999) self.feedrate_rapid_entry.setSingleStep(0.1) - self.grid3.addWidget(self.fr_rapidlabel, 12, 0) - self.grid3.addWidget(self.feedrate_rapid_entry, 12, 1) + grid3.addWidget(self.fr_rapidlabel, 12, 0) + grid3.addWidget(self.feedrate_rapid_entry, 12, 1) # default values is to hide self.fr_rapidlabel.hide() self.feedrate_rapid_entry.hide() @@ -1820,8 +1832,8 @@ class GeometryObjectUI(ObjectUI): "meet with last cut, we generate an\n" "extended cut over the first cut section.") ) - self.grid3.addWidget(self.extracut_cb, 13, 0) - self.grid3.addWidget(self.e_cut_entry, 13, 1) + grid3.addWidget(self.extracut_cb, 13, 0) + grid3.addWidget(self.e_cut_entry, 13, 1) # Spindlespeed self.spindle_label = QtWidgets.QLabel('%s:' % _('Spindle speed')) @@ -1836,8 +1848,8 @@ class GeometryObjectUI(ObjectUI): self.cncspindlespeed_entry.set_range(0, 1000000) self.cncspindlespeed_entry.set_step(100) - self.grid3.addWidget(self.spindle_label, 14, 0) - self.grid3.addWidget(self.cncspindlespeed_entry, 14, 1) + grid3.addWidget(self.spindle_label, 14, 0) + grid3.addWidget(self.cncspindlespeed_entry, 14, 1) # Dwell self.dwell_cb = FCCheckBox('%s:' % _('Dwell')) @@ -1857,8 +1869,8 @@ class GeometryObjectUI(ObjectUI): ) self.ois_dwell_geo = OptionalInputSection(self.dwell_cb, [self.dwelltime_entry]) - self.grid3.addWidget(self.dwell_cb, 15, 0) - self.grid3.addWidget(self.dwelltime_entry, 15, 1) + grid3.addWidget(self.dwell_cb, 15, 0) + grid3.addWidget(self.dwelltime_entry, 15, 1) # Probe depth self.pdepth_label = QtWidgets.QLabel('%s:' % _("Probe Z depth")) @@ -1871,8 +1883,8 @@ class GeometryObjectUI(ObjectUI): self.pdepth_entry.set_range(-9999.9999, 9999.9999) self.pdepth_entry.setSingleStep(0.1) - self.grid3.addWidget(self.pdepth_label, 17, 0) - self.grid3.addWidget(self.pdepth_entry, 17, 1) + grid3.addWidget(self.pdepth_label, 17, 0) + grid3.addWidget(self.pdepth_entry, 17, 1) self.pdepth_label.hide() self.pdepth_entry.setVisible(False) @@ -1887,8 +1899,8 @@ class GeometryObjectUI(ObjectUI): self.feedrate_probe_entry.set_range(0.0, 9999.9999) self.feedrate_probe_entry.setSingleStep(0.1) - self.grid3.addWidget(self.feedrate_probe_label, 18, 0) - self.grid3.addWidget(self.feedrate_probe_entry, 18, 1) + grid3.addWidget(self.feedrate_probe_label, 18, 0) + grid3.addWidget(self.feedrate_probe_entry, 18, 1) self.feedrate_probe_label.hide() self.feedrate_probe_entry.setVisible(False) @@ -1897,34 +1909,34 @@ class GeometryObjectUI(ObjectUI): # ################# GRID LAYOUT 4 ############################### # ################################################################# - self.grid4 = QtWidgets.QGridLayout() - self.grid4.setColumnStretch(0, 0) - self.grid4.setColumnStretch(1, 1) - self.geo_param_box.addLayout(self.grid4) + grid4 = QtWidgets.QGridLayout() + grid4.setColumnStretch(0, 0) + grid4.setColumnStretch(1, 1) + self.geo_param_box.addLayout(grid4) separator_line2 = QtWidgets.QFrame() separator_line2.setFrameShape(QtWidgets.QFrame.HLine) separator_line2.setFrameShadow(QtWidgets.QFrame.Sunken) - self.grid4.addWidget(separator_line2, 0, 0, 1, 2) + grid4.addWidget(separator_line2, 0, 0, 1, 2) self.apply_param_to_all = FCButton(_("Apply parameters to all tools")) self.apply_param_to_all.setToolTip( _("The parameters in the current form will be applied\n" "on all the tools from the Tool Table.") ) - self.grid4.addWidget(self.apply_param_to_all, 1, 0, 1, 2) + grid4.addWidget(self.apply_param_to_all, 1, 0, 1, 2) separator_line2 = QtWidgets.QFrame() separator_line2.setFrameShape(QtWidgets.QFrame.HLine) separator_line2.setFrameShadow(QtWidgets.QFrame.Sunken) - self.grid4.addWidget(separator_line2, 2, 0, 1, 2) + grid4.addWidget(separator_line2, 2, 0, 1, 2) # General Parameters self.gen_param_label = QtWidgets.QLabel('%s' % _("Common Parameters")) self.gen_param_label.setToolTip( _("Parameters that are common for all tools.") ) - self.grid4.addWidget(self.gen_param_label, 3, 0, 1, 2) + grid4.addWidget(self.gen_param_label, 3, 0, 1, 2) # Tool change Z self.toolchangeg_cb = FCCheckBox('%s:' % _("Tool change Z")) @@ -1951,8 +1963,8 @@ class GeometryObjectUI(ObjectUI): self.toolchangez_entry.setSingleStep(0.1) self.ois_tcz_geo = OptionalInputSection(self.toolchangeg_cb, [self.toolchangez_entry]) - self.grid4.addWidget(self.toolchangeg_cb, 6, 0) - self.grid4.addWidget(self.toolchangez_entry, 6, 1) + grid4.addWidget(self.toolchangeg_cb, 6, 0) + grid4.addWidget(self.toolchangez_entry, 6, 1) # The Z value for the start move # startzlabel = QtWidgets.QLabel('Start move Z:') @@ -1961,9 +1973,9 @@ class GeometryObjectUI(ObjectUI): # "Delete the value if you don't need this feature." # # ) - # self.grid3.addWidget(startzlabel, 8, 0) + # grid3.addWidget(startzlabel, 8, 0) # self.gstartz_entry = FloatEntry() - # self.grid3.addWidget(self.gstartz_entry, 8, 1) + # grid3.addWidget(self.gstartz_entry, 8, 1) # The Z value for the end move self.endz_label = QtWidgets.QLabel('%s:' % _('End move Z')) @@ -1981,8 +1993,8 @@ class GeometryObjectUI(ObjectUI): self.endz_entry.setSingleStep(0.1) - self.grid4.addWidget(self.endz_label, 9, 0) - self.grid4.addWidget(self.endz_entry, 9, 1) + grid4.addWidget(self.endz_label, 9, 0) + grid4.addWidget(self.endz_entry, 9, 1) # End Move X,Y endmove_xy_label = QtWidgets.QLabel('%s:' % _('End move X,Y')) @@ -1993,8 +2005,8 @@ class GeometryObjectUI(ObjectUI): ) self.endxy_entry = FCEntry() - self.grid4.addWidget(endmove_xy_label, 10, 0) - self.grid4.addWidget(self.endxy_entry, 10, 1) + grid4.addWidget(endmove_xy_label, 10, 0) + grid4.addWidget(self.endxy_entry, 10, 1) # preprocessor selection pp_label = QtWidgets.QLabel('%s:' % _("Preprocessor")) @@ -2005,17 +2017,17 @@ class GeometryObjectUI(ObjectUI): self.pp_geometry_name_cb = FCComboBox() self.pp_geometry_name_cb.setFocusPolicy(QtCore.Qt.StrongFocus) - self.grid4.addWidget(pp_label, 11, 0) - self.grid4.addWidget(self.pp_geometry_name_cb, 11, 1) + grid4.addWidget(pp_label, 11, 0) + grid4.addWidget(self.pp_geometry_name_cb, 11, 1) - self.grid4.addWidget(QtWidgets.QLabel(''), 12, 0, 1, 2) + grid4.addWidget(QtWidgets.QLabel(''), 12, 0, 1, 2) warning_lbl = QtWidgets.QLabel( _( "Add / Select at least one tool in the tool-table.\n" "Click the # header to select all, or Ctrl + LMB\n" "for custom selection of tools." )) - self.grid4.addWidget(warning_lbl, 13, 0, 1, 2) + grid4.addWidget(warning_lbl, 13, 0, 1, 2) # Button self.generate_cnc_button = QtWidgets.QPushButton(_('Generate CNCJob object')) @@ -2028,9 +2040,9 @@ class GeometryObjectUI(ObjectUI): font-weight: bold; } """) - self.grid4.addWidget(self.generate_cnc_button, 14, 0, 1, 2) + grid4.addWidget(self.generate_cnc_button, 14, 0, 1, 2) - self.grid4.addWidget(QtWidgets.QLabel(''), 15, 0, 1, 2) + grid4.addWidget(QtWidgets.QLabel(''), 15, 0, 1, 2) # ############## # Paint area ## @@ -2039,7 +2051,7 @@ class GeometryObjectUI(ObjectUI): self.tools_label.setToolTip( _("Launch Paint Tool in Tools Tab.") ) - self.grid4.addWidget(self.tools_label, 16, 0, 1, 2) + grid4.addWidget(self.tools_label, 16, 0, 1, 2) # Paint Button self.paint_tool_button = QtWidgets.QPushButton(_('Paint Tool')) @@ -2057,7 +2069,7 @@ class GeometryObjectUI(ObjectUI): font-weight: bold; } """) - self.grid4.addWidget(self.paint_tool_button, 17, 0, 1, 2) + grid4.addWidget(self.paint_tool_button, 17, 0, 1, 2) # NCC Tool self.generate_ncc_button = QtWidgets.QPushButton(_('NCC Tool')) @@ -2071,7 +2083,7 @@ class GeometryObjectUI(ObjectUI): font-weight: bold; } """) - self.grid4.addWidget(self.generate_ncc_button, 18, 0, 1, 2) + grid4.addWidget(self.generate_ncc_button, 18, 0, 1, 2) class CNCObjectUI(ObjectUI): From 69b39e293750b2cdcd9c61c9c4964c0fce3464ce Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 6 Apr 2020 06:28:55 +0300 Subject: [PATCH 153/209] - added key shortcuts (arrow up/down) that will select the objects in the Project tab if the focus is in that tab --- README.md | 4 ++++ flatcamGUI/FlatCAMGUI.py | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/README.md b/README.md index 95a692dc..2ba2b6c0 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +6.04.2020 + +- added key shortcuts (arrow up/down) that will select the objects in the Project tab if the focus is in that tab + 5.04.2020 - made sure that the HDPI scaling attribute is set before the QApplication is started diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index 9fdd90fd..064d3d76 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -2778,6 +2778,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): modifiers = QtWidgets.QApplication.keyboardModifiers() active = self.app.collection.get_active() selected = self.app.collection.get_selected() + names_list = self.app.collection.get_names() matplotlib_key_flag = False @@ -3131,6 +3132,27 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.app.collection.update_view() self.app.delete_selection_shape() + # Select the object in the Tree above the current one + if key == QtCore.Qt.Key_Up: + self.app.collection.set_all_inactive() + active_name = active.options['name'] + active_index = names_list.index(active_name) + if active_index == 0: + self.app.collection.set_active(names_list[-1]) + else: + self.app.collection.set_active(names_list[active_index-1]) + + # Select the object in the Tree bellow the current one + if key == QtCore.Qt.Key_Down: + self.app.collection.set_all_inactive() + active_name = active.options['name'] + active_index = names_list.index(active_name) + if active_index == len(names_list) - 1: + self.app.collection.set_active(names_list[0]) + else: + self.app.collection.set_active(names_list[active_index+1]) + + # New Geometry if key == QtCore.Qt.Key_B: self.app.new_gerber_object() From b11ac0ca4d188ef46da5e0603ab238c05129b6f6 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 6 Apr 2020 19:04:32 +0300 Subject: [PATCH 154/209] - added a minor change to the ListSys Tcl command --- README.md | 1 + tclCommands/TclCommandListSys.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2ba2b6c0..9cda4dcb 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 6.04.2020 - added key shortcuts (arrow up/down) that will select the objects in the Project tab if the focus is in that tab +- added a minor change to the ListSys Tcl command 5.04.2020 diff --git a/tclCommands/TclCommandListSys.py b/tclCommands/TclCommandListSys.py index 39fc6e22..58d8c8e3 100644 --- a/tclCommands/TclCommandListSys.py +++ b/tclCommands/TclCommandListSys.py @@ -60,4 +60,6 @@ class TclCommandListSys(TclCommand): argument = args['selection'] return str([k for k in self.app.defaults.keys() if str(k).startswith(str(argument))]) else: - return str([*self.app.defaults]) \ No newline at end of file + ret_val = list(self.app.defaults.keys()) + return str(ret_val) + # return str([*self.app.defaults]) From ee6ac2593fe94af88d81c9d32d68ae52b89fa85e Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 6 Apr 2020 20:31:42 +0300 Subject: [PATCH 155/209] - fixed an crash generated when running the Tool Database from the Menu -> Options menu entry --- FlatCAMApp.py | 10 +++++++--- README.md | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 3d225531..4bdbc575 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -2065,7 +2065,7 @@ class App(QtCore.QObject): self.ui.menuoptions_transform_flipx.triggered.connect(self.on_flipx) self.ui.menuoptions_transform_flipy.triggered.connect(self.on_flipy) self.ui.menuoptions_view_source.triggered.connect(self.on_view_source) - self.ui.menuoptions_tools_db.triggered.connect(self.on_tools_database) + self.ui.menuoptions_tools_db.triggered.connect(lambda: self.on_tools_database(source='app')) self.ui.menuviewdisableall.triggered.connect(self.disable_all_plots) self.ui.menuviewdisableother.triggered.connect(self.disable_other_plots) @@ -8106,8 +8106,12 @@ class App(QtCore.QObject): ) # add the tab if it was closed - self.ui.plot_tab_area.addTab(self.tools_db_tab, _("Tools Database")) - self.tools_db_tab.setObjectName("database_tab") + try: + self.ui.plot_tab_area.addTab(self.tools_db_tab, _("Tools Database")) + self.tools_db_tab.setObjectName("database_tab") + except Exception as e: + log.debug("App.on_tools_database() --> %s" % str(e)) + return # delete the absolute and relative position and messages in the infobar self.ui.position_label.setText("") diff --git a/README.md b/README.md index 9cda4dcb..5104b726 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ CAD program, and create G-Code for Isolation routing. - added key shortcuts (arrow up/down) that will select the objects in the Project tab if the focus is in that tab - added a minor change to the ListSys Tcl command +- fixed an crash generated when running the Tool Database from the Menu -> Options menu entry 5.04.2020 From d14e5d9445560f31e5b02ef180e5439347ab2351 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 6 Apr 2020 20:52:00 +0300 Subject: [PATCH 156/209] - fixed a bug in handling the UP/DOWN key shortcuts that caused a crash when no object was selected in the Project Tab; also made sure that the said keys are handled only for the Project Tab --- README.md | 1 + flatcamGUI/FlatCAMGUI.py | 41 ++++++++++++++++++++++++---------------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 5104b726..5e9d55b8 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ CAD program, and create G-Code for Isolation routing. - added key shortcuts (arrow up/down) that will select the objects in the Project tab if the focus is in that tab - added a minor change to the ListSys Tcl command - fixed an crash generated when running the Tool Database from the Menu -> Options menu entry +- fixed a bug in handling the UP/DOWN key shortcuts that caused a crash when no object was selected in the Project Tab; also made sure that the said keys are handled only for the Project Tab 5.04.2020 diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index 064d3d76..27c80913 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -16,8 +16,7 @@ from flatcamEditors.FlatCAMGeoEditor import FCShapeTool from matplotlib.backend_bases import KeyEvent as mpl_key_event import webbrowser -from copy import deepcopy -from datetime import datetime +from ObjectCollection import KeySensitiveListView import subprocess import os @@ -3134,23 +3133,33 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # Select the object in the Tree above the current one if key == QtCore.Qt.Key_Up: - self.app.collection.set_all_inactive() - active_name = active.options['name'] - active_index = names_list.index(active_name) - if active_index == 0: - self.app.collection.set_active(names_list[-1]) - else: - self.app.collection.set_active(names_list[active_index-1]) + # make sure it works only for the Project Tab who is an instance of KeySensitiveListView + focused_wdg = QtWidgets.QApplication.focusWidget() + if isinstance(focused_wdg, KeySensitiveListView): + self.app.collection.set_all_inactive() + if active is None: + return + active_name = active.options['name'] + active_index = names_list.index(active_name) + if active_index == 0: + self.app.collection.set_active(names_list[-1]) + else: + self.app.collection.set_active(names_list[active_index-1]) # Select the object in the Tree bellow the current one if key == QtCore.Qt.Key_Down: - self.app.collection.set_all_inactive() - active_name = active.options['name'] - active_index = names_list.index(active_name) - if active_index == len(names_list) - 1: - self.app.collection.set_active(names_list[0]) - else: - self.app.collection.set_active(names_list[active_index+1]) + # make sure it works only for the Project Tab who is an instance of KeySensitiveListView + focused_wdg = QtWidgets.QApplication.focusWidget() + if isinstance(focused_wdg, KeySensitiveListView): + self.app.collection.set_all_inactive() + if active is None: + return + active_name = active.options['name'] + active_index = names_list.index(active_name) + if active_index == len(names_list) - 1: + self.app.collection.set_active(names_list[0]) + else: + self.app.collection.set_active(names_list[active_index+1]) # New Geometry From 573070f154d4fd11e9981b124313b5f77c6561d3 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 6 Apr 2020 21:10:02 +0300 Subject: [PATCH 157/209] - some PEP8 changes and other minor changes --- FlatCAMObj.py | 138 ++++++++++++++++++++++++++++---------------------- README.md | 1 + 2 files changed, 78 insertions(+), 61 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 68edd0a2..d803cea1 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -16,7 +16,7 @@ from shapely.ops import cascaded_union import shapely.affinity as affinity from copy import deepcopy -from copy import copy +# from copy import copy from io import StringIO import traceback @@ -32,7 +32,7 @@ from flatcamParsers.ParseGerber import Gerber from camlib import Geometry, CNCjob import FlatCAMApp -from flatcamGUI.VisPyVisuals import ShapeCollection +# from flatcamGUI.VisPyVisuals import ShapeCollection import tkinter as tk import os @@ -63,6 +63,7 @@ class ValidationError(Exception): self.errors = errors + # ####################################### # # FlatCAMObj ## # ####################################### @@ -496,7 +497,7 @@ class FlatCAMObj(QtCore.QObject): # Not all object types has annotations try: self.annotation.visible = value - except Exception as e: + except Exception: pass if threaded is False: @@ -1069,12 +1070,12 @@ class FlatCAMGerber(FlatCAMObj, Gerber): if self.ui.iso_type_radio.get_value() == 'int': self.iso_type = 1 - def worker_task(obj, app_obj): + def worker_task(iso_obj, app_obj): with self.app.proc_container.new(_("Isolating...")): if self.ui.follow_cb.get_value() is True: - obj.follow_geo() + iso_obj.follow_geo() # in the end toggle the visibility of the origin object so we can see the generated Geometry - obj.ui.plot_cb.toggle() + iso_obj.ui.plot_cb.toggle() else: app_obj.report_usage("gerber_on_iso_button") self.read_form() @@ -1999,7 +2000,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber): self.ui.mark_all_cb.setChecked(True) self.ui_connect() - def on_mark_all_click(self, signal): + def on_mark_all_click(self): self.ui_disconnect() mark_all = self.ui.mark_all_cb.isChecked() for row in range(self.ui.apertures_table.rowCount()): @@ -2409,7 +2410,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): "toolchangez": 1.0, "toolchangexy": "0.0, 0.0", "extracut": self.app.defaults["geometry_extracut"], - "extracut_length":self.app.defaults["geometry_extracut_length"], + "extracut_length": self.app.defaults["geometry_extracut_length"], "endz": 2.0, "endxy": '', @@ -2914,20 +2915,20 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): "e_operation": "operation", "e_milling_type": "milling_type", "e_milling_dia": "milling_dia", - "e_cutz" : "cutz", - "e_multidepth" : "multidepth", - "e_depthperpass" : "depthperpass", + "e_cutz": "cutz", + "e_multidepth": "multidepth", + "e_depthperpass": "depthperpass", - "e_travelz" : "travelz", - "e_feedratexy" : "feedrate", - "e_feedratez" : "feedrate_z", - "e_fr_rapid" : "feedrate_rapid", - "e_extracut" : "extracut", - "e_extracut_length" : "extracut_length", - "e_spindlespeed" : "spindlespeed", - "e_dwell" : "dwell", - "e_dwelltime" : "dwelltime", - "e_offset" : "offset", + "e_travelz": "travelz", + "e_feedratexy": "feedrate", + "e_feedratez": "feedrate_z", + "e_fr_rapid": "feedrate_rapid", + "e_extracut": "extracut", + "e_extracut_length": "extracut_length", + "e_spindlespeed": "spindlespeed", + "e_dwell": "dwell", + "e_dwelltime": "dwelltime", + "e_offset": "offset", } # populate Excellon preprocessor combobox list @@ -4249,7 +4250,6 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): assert isinstance(self.ui, GeometryObjectUI), \ "Expected a GeometryObjectUI, got %s" % type(self.ui) - self.units = self.app.defaults['units'].upper() self.units_found = self.app.defaults['units'] @@ -4413,7 +4413,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): _("Copy"), self.on_tool_copy, icon=QtGui.QIcon(self.app.resource_location + "/copy16.png")) self.ui.geo_tools_table.addContextMenu( - _("Delete"), lambda: self.on_tool_delete(all=None), + _("Delete"), lambda: self.on_tool_delete(all_tools=None), icon=QtGui.QIcon(self.app.resource_location + "/delete32.png")) # Show/Hide Advanced Options @@ -4862,7 +4862,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): if self.ui.geo_tools_table.rowCount() != 0: self.ui.geo_param_frame.setDisabled(False) - def on_tool_copy(self, all=None): + def on_tool_copy(self, all_tools=None): self.ui_disconnect() # find the tool_uid maximum value in the self.tools @@ -4874,7 +4874,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): except ValueError: max_uid = 0 - if all is None: + if all_tools is None: if self.ui.geo_tools_table.selectedItems(): for current_row in self.ui.geo_tools_table.selectedItems(): # sometime the header get selected and it has row number -1 @@ -4956,10 +4956,10 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ui_connect() self.build_ui() - def on_tool_delete(self, all=None): + def on_tool_delete(self, all_tools=None): self.ui_disconnect() - if all is None: + if all_tools is None: if self.ui.geo_tools_table.selectedItems(): for current_row in self.ui.geo_tools_table.selectedItems(): # sometime the header get selected and it has row number -1 @@ -5307,29 +5307,28 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ui.geo_tools_table.setCurrentItem(self.ui.geo_tools_table.item(row, 0)) def export_dxf(self): - units = self.app.defaults['units'].upper() dwg = None try: dwg = ezdxf.new('R2010') msp = dwg.modelspace() - def g2dxf(dxf_space, geo): - if isinstance(geo, MultiPolygon): - for poly in geo: + def g2dxf(dxf_space, geo_obj): + if isinstance(geo_obj, MultiPolygon): + for poly in geo_obj: ext_points = list(poly.exterior.coords) dxf_space.add_lwpolyline(ext_points) for interior in poly.interiors: dxf_space.add_lwpolyline(list(interior.coords)) - if isinstance(geo, Polygon): - ext_points = list(geo.exterior.coords) + if isinstance(geo_obj, Polygon): + ext_points = list(geo_obj.exterior.coords) dxf_space.add_lwpolyline(ext_points) - for interior in geo.interiors: + for interior in geo_obj.interiors: dxf_space.add_lwpolyline(list(interior.coords)) - if isinstance(geo, MultiLineString): - for line in geo: + if isinstance(geo_obj, MultiLineString): + for line in geo_obj: dxf_space.add_lwpolyline(list(line.coords)) - if isinstance(geo, LineString) or isinstance(geo, LinearRing): - dxf_space.add_lwpolyline(list(geo.coords)) + if isinstance(geo_obj, LineString) or isinstance(geo_obj, LinearRing): + dxf_space.add_lwpolyline(list(geo_obj.coords)) multigeo_solid_geometry = [] if self.multigeo: @@ -5577,11 +5576,14 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): :param tools_in_use: the tools that are used, needed by some preprocessors :type list of lists, each list in the list is made out of row elements of tools table from GUI - :param segx: number of segments on the X axis, for auto-levelling - :param segy: number of segments on the Y axis, for auto-levelling - :param plot: if True the generated object will be plotted; if False will not be plotted - :param use_thread: if True use threading - :return: None + :param outname: + :param tools_dict: + :param tools_in_use: + :param segx: number of segments on the X axis, for auto-levelling + :param segy: number of segments on the Y axis, for auto-levelling + :param plot: if True the generated object will be plotted; if False will not be plotted + :param use_thread: if True use threading + :return: None """ # use the name of the first tool selected in self.geo_tools_table which has the diameter passed as tool_dia @@ -5890,8 +5892,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): try: dia_cnc_dict['solid_geometry'] = deepcopy(tool_solid_geometry) self.app.inform.emit('[success] %s' % _("Finished G-Code processing...")) - except Exception as e: - self.app.inform.emit('[ERROR] %s: %s' % (_("G-Code processing failed with error"), str(e))) + except Exception as ee: + self.app.inform.emit('[ERROR] %s: %s' % (_("G-Code processing failed with error"), str(ee))) # tell gcode_parse from which point to start drawing the lines depending on what kind of # object is the source of gcode @@ -5943,15 +5945,31 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): work is done by the target camlib.CNCjob `generate_from_geometry_2()` method. - :param z_cut: Cut depth (negative) - :param z_move: Hight of the tool when travelling (not cutting) - :param feedrate: Feed rate while cutting on X - Y plane - :param feedrate_z: Feed rate while cutting on Z plane - :param feedrate_rapid: Feed rate while moving with rapids - :param dia: Tool diameter - :param outname: Name of the new object - :param spindlespeed: Spindle speed (RPM) - :param pp Name of the preprocessor + :param outname: Name of the new object + :param dia: Tool diameter + :param offset: + :param z_cut: Cut depth (negative value) + :param z_move: Height of the tool when travelling (not cutting) + :param feedrate: Feed rate while cutting on X - Y plane + :param feedrate_z: Feed rate while cutting on Z plane + :param feedrate_rapid: Feed rate while moving with rapids + :param spindlespeed: Spindle speed (RPM) + :param dwell: + :param dwelltime: + :param multidepth: + :param depthperpass: + :param toolchange: + :param toolchangez: + :param toolchangexy: + :param extracut: + :param extracut_length: + :param startz: + :param endz: + :param pp: Name of the preprocessor + :param segx: + :param segy: + :param use_thread: + :param plot: :return: None """ @@ -6050,7 +6068,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): else: self.app.new_object("cncjob", outname, job_init, plot=plot) - # def on_plot_cb_click(self, *args): # TODO: args not needed + # def on_plot_cb_click(self, *args): # if self.muted_ui: # return # self.read_form_item('plot') @@ -6119,8 +6137,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): # variables to display the percentage of work done self.geo_len = 0 try: - for g in self.tools[tool]['solid_geometry']: - self.geo_len += 1 + self.geo_len = len(self.tools[tool]['solid_geometry']) except TypeError: self.geo_len = 1 self.old_disp_number = 0 @@ -6196,8 +6213,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): # variables to display the percentage of work done self.geo_len = 0 try: - for g in self.tools[tool]['solid_geometry']: - self.geo_len += 1 + self.geo_len = len(self.tools[tool]['solid_geometry']) except TypeError: self.geo_len = 1 self.old_disp_number = 0 @@ -6208,10 +6224,10 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): # variables to display the percentage of work done self.geo_len = 0 try: - for g in self.solid_geometry: - self.geo_len += 1 + self.geo_len = len(self.solid_geometry) except TypeError: self.geo_len = 1 + self.old_disp_number = 0 self.el_count = 0 diff --git a/README.md b/README.md index 5e9d55b8..dd6c3e21 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ CAD program, and create G-Code for Isolation routing. - added a minor change to the ListSys Tcl command - fixed an crash generated when running the Tool Database from the Menu -> Options menu entry - fixed a bug in handling the UP/DOWN key shortcuts that caused a crash when no object was selected in the Project Tab; also made sure that the said keys are handled only for the Project Tab +- some PEP8 changes and other minor changes 5.04.2020 From e1269cdb341e412d43a3a24945c86770101a8c5f Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 6 Apr 2020 21:39:23 +0300 Subject: [PATCH 158/209] - updated the requirements file --- README.md | 1 + requirements.txt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dd6c3e21..5ee4f317 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ CAD program, and create G-Code for Isolation routing. - fixed an crash generated when running the Tool Database from the Menu -> Options menu entry - fixed a bug in handling the UP/DOWN key shortcuts that caused a crash when no object was selected in the Project Tab; also made sure that the said keys are handled only for the Project Tab - some PEP8 changes and other minor changes +- updated the requirements file 5.04.2020 diff --git a/requirements.txt b/requirements.txt index ee962276..0f1f6d04 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ # This file contains python only requirements to be installed with pip # Python packages that cannot be installed with pip (e.g. PyQt5, GDAL) are not included. # Usage: pip3 install -r requirements.txt -pyqt5==5.12.1 +pyqt5>=5.12.1 numpy>=1.16 matplotlib>=3.1 cycler>=0.10 From ecba1a9232ac321ba7b047c7b926f14fdb27d534 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 6 Apr 2020 22:28:18 +0300 Subject: [PATCH 159/209] - updated the 2Sided Tool by not allowing the Gerber file to be mirrored without a valid reference and added some placeholder texts --- README.md | 1 + flatcamTools/ToolDblSided.py | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5ee4f317..e115e7a8 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ CAD program, and create G-Code for Isolation routing. - fixed a bug in handling the UP/DOWN key shortcuts that caused a crash when no object was selected in the Project Tab; also made sure that the said keys are handled only for the Project Tab - some PEP8 changes and other minor changes - updated the requirements file +- updated the 2Sided Tool by not allowing the Gerber file to be mirrored without a valid reference and added some placeholder texts 5.04.2020 diff --git a/flatcamTools/ToolDblSided.py b/flatcamTools/ToolDblSided.py index 89014940..29261cc5 100644 --- a/flatcamTools/ToolDblSided.py +++ b/flatcamTools/ToolDblSided.py @@ -187,6 +187,7 @@ class DblSidedTool(FlatCAMTool): # ## Point/Box self.point_entry = EvalEntry() + self.point_entry.setPlaceholderText(_("Point coordinates")) # Add a reference self.add_point_button = QtWidgets.QPushButton(_("Add")) @@ -416,6 +417,7 @@ class DblSidedTool(FlatCAMTool): ) self.alignment_holes = EvalEntry() + self.alignment_holes.setPlaceholderText(_("Drill coordinates")) grid_lay4.addWidget(self.ah_label, 0, 0, 1, 2) grid_lay4.addWidget(self.alignment_holes, 1, 0, 1, 2) @@ -667,9 +669,9 @@ class DblSidedTool(FlatCAMTool): try: px, py = self.point_entry.get_value() except TypeError: - self.app.inform.emit('[WARNING_NOTCL] %s' % _("'Point' coordinates missing. " - "Using Origin (0, 0) as mirroring reference.")) - px, py = (0, 0) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("There are no Point coordinates in the Point field. " + "Add coords and try again ...")) + return else: selection_index_box = self.box_combo.currentIndex() From 42949021b1fcd101b662a591f075724e6dfc3b91 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 9 Apr 2020 04:13:04 +0300 Subject: [PATCH 160/209] - fixed the Tcl Command Delete to have an argument -f that will force deletion evading the popup (if the popup is enabled). The sme command without a name now will delete all objects - fixed the Tcl Command JoinExcellons - fixed the Tcl Command JoinGeometry - fixed the Tcl Command Mirror - updated the Tcl Command Mirror to use a (X,Y) origin parameter. Works if the -box parameter is not used. - updated the Tcl Command Offset. Now it can use only -x or -y parameter no longer is mandatory to have both. The one that is not present will be assumed 0.0 - updated the Tcl Command Panelize. The -rows and -columns parameters are no longer both required. If one is not present then it is assumed to be zero. - updated the Tcl Command Scale. THe -origin parameter can now be a tuple of (x,y) coordinates. - updated the Tcl Command Skew. Now it can use only -x or -y parameter no longer is mandatory to have both. The one that is not present will be assumed 0.0 - updated the help for all the Tcl Commands --- FlatCAMApp.py | 23 +++++++--- README.md | 13 ++++++ tclCommands/TclCommandAddCircle.py | 2 +- tclCommands/TclCommandAddRectangle.py | 2 +- tclCommands/TclCommandAlignDrill.py | 2 +- tclCommands/TclCommandAlignDrillGrid.py | 2 +- tclCommands/TclCommandBbox.py | 2 +- tclCommands/TclCommandBounds.py | 1 + tclCommands/TclCommandClearShell.py | 2 +- tclCommands/TclCommandCutout.py | 2 +- tclCommands/TclCommandDelete.py | 52 ++++++++++++++++------ tclCommands/TclCommandExportGcode.py | 4 +- tclCommands/TclCommandExportGerber.py | 2 +- tclCommands/TclCommandExportSVG.py | 2 +- tclCommands/TclCommandExteriors.py | 4 +- tclCommands/TclCommandFollow.py | 4 +- tclCommands/TclCommandGeoCutout.py | 4 +- tclCommands/TclCommandGeoUnion.py | 6 +-- tclCommands/TclCommandGetNames.py | 4 +- tclCommands/TclCommandGetSys.py | 4 +- tclCommands/TclCommandImportSvg.py | 4 +- tclCommands/TclCommandInteriors.py | 6 +-- tclCommands/TclCommandIsolate.py | 12 +++-- tclCommands/TclCommandJoinExcellon.py | 21 ++++----- tclCommands/TclCommandJoinGeometry.py | 18 ++++---- tclCommands/TclCommandListSys.py | 2 +- tclCommands/TclCommandMillDrills.py | 16 ++++--- tclCommands/TclCommandMillSlots.py | 14 +++--- tclCommands/TclCommandMirror.py | 43 +++++++++++------- tclCommands/TclCommandNew.py | 2 +- tclCommands/TclCommandNewExcellon.py | 2 +- tclCommands/TclCommandNewGeometry.py | 5 ++- tclCommands/TclCommandNewGerber.py | 2 +- tclCommands/TclCommandNregions.py | 4 +- tclCommands/TclCommandOffset.py | 23 ++++++---- tclCommands/TclCommandOpenExcellon.py | 10 ++++- tclCommands/TclCommandOpenGCode.py | 10 +++-- tclCommands/TclCommandOpenGerber.py | 11 +++-- tclCommands/TclCommandOpenProject.py | 10 +++-- tclCommands/TclCommandOptions.py | 6 +-- tclCommands/TclCommandPanelize.py | 28 +++++++++--- tclCommands/TclCommandPlotAll.py | 2 +- tclCommands/TclCommandPlotObjects.py | 8 ++-- tclCommands/TclCommandSaveProject.py | 7 ++- tclCommands/TclCommandSaveSys.py | 4 +- tclCommands/TclCommandScale.py | 29 ++++++++---- tclCommands/TclCommandSetActive.py | 4 +- tclCommands/TclCommandSetOrigin.py | 8 ++-- tclCommands/TclCommandSetSys.py | 4 +- tclCommands/TclCommandSkew.py | 31 ++++++++----- tclCommands/TclCommandSubtractPoly.py | 8 ++-- tclCommands/TclCommandSubtractRectangle.py | 5 ++- tclCommands/TclCommandWriteGCode.py | 4 +- 53 files changed, 322 insertions(+), 178 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 4bdbc575..6f6d0919 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -1033,7 +1033,7 @@ class App(QtCore.QObject): 'Toolchange_manual, Users, all, angle_x, angle_y, axis, auto, axisoffset, ' 'box, center_x, center_y, columns, combine, connect, contour, default, ' 'depthperpass, dia, diatol, dist, drilled_dias, drillz, dwelltime, ' - 'extracut_length, ' + 'extracut_length, f, ' 'feedrate_z, grbl_11, GRBL_laser, gridoffsety, gridx, gridy, has_offset, ' 'holes, hpgl, iso_type, line_xyz, margin, marlin, method, milled_dias, ' 'minoffset, name, offset, opt_type, order, outname, overlap, ' @@ -2305,7 +2305,8 @@ class App(QtCore.QObject): # ##################################################################################### self.tcl_commands_list = ['add_circle', 'add_poly', 'add_polygon', 'add_polyline', 'add_rectangle', 'aligndrill', 'aligndrillgrid', 'bbox', 'bounding_box', 'clear', 'cncjob', 'cutout', - 'delete', 'drillcncjob', 'export_dxf', 'edxf', 'export_excellon', 'ee', 'export_exc', + 'del', 'delete', 'drillcncjob', 'export_dxf', 'edxf', 'export_excellon', 'ee', + 'export_exc', 'export_gcode', 'export_gerber', 'egr', 'export_svg', 'ext', 'exteriors', 'follow', 'geo_union', 'geocutout', 'get_names', 'get_sys', 'getsys', 'help', 'import_svg', 'interiors', 'isolate', 'join_excellon', 'join_excellons', 'join_geometries', @@ -2326,7 +2327,7 @@ class App(QtCore.QObject): 'axisoffset', 'box', 'center_x', 'center_y', 'columns', 'combine', 'connect', 'contour', 'default', 'depthperpass', 'dia', 'diatol', 'dist', 'drilled_dias', 'drillz', - 'dwelltime', 'extracut_length', + 'dwelltime', 'extracut_length', 'f', 'feedrate_z', 'grbl_11', 'GRBL_laser', 'gridoffsety', 'gridx', 'gridy', 'has_offset', 'holes', 'hpgl', 'iso_type', 'line_xyz', 'margin', 'marlin', 'method', 'milled_dias', 'minoffset', 'name', 'offset', 'opt_type', 'order', @@ -7201,10 +7202,11 @@ class App(QtCore.QObject): # Hovering over Selected tab, if the selected tab is a Geometry it will delete tools in tool table. But even if # there is a Selected tab in focus with a Geometry inside, if you hover over canvas it will delete an object. # Complicated, I know :) - def on_delete(self): + def on_delete(self, force_deletion=False): """ Delete the currently selected FlatCAMObjs. + :param force_deletion: used by Tcl command :return: None """ self.report_usage("on_delete()") @@ -7216,7 +7218,7 @@ class App(QtCore.QObject): # a geometry object before we update it. if self.geo_editor.editor_active is False and self.exc_editor.editor_active is False \ and self.grb_editor.editor_active is False: - if self.defaults["global_delete_confirmation"] is True: + if self.defaults["global_delete_confirmation"] is True and force_deletion is False: msgbox = QtWidgets.QMessageBox() msgbox.setWindowTitle(_("Delete objects")) msgbox.setWindowIcon(QtGui.QIcon(self.resource_location + '/deleteshape32.png')) @@ -7230,7 +7232,10 @@ class App(QtCore.QObject): msgbox.exec_() response = msgbox.clickedButton() - if response == bt_ok or self.defaults["global_delete_confirmation"] is False: + if self.defaults["global_delete_confirmation"] is False or force_deletion is True: + response = bt_ok + + if response == bt_ok: if self.collection.get_active(): self.log.debug("App.on_delete()") @@ -9539,6 +9544,7 @@ class App(QtCore.QObject): File menu callback for opening a Gerber. :param signal: required because clicking the entry will generate a checked signal which needs a container + :param name: :return: None """ @@ -9585,6 +9591,7 @@ class App(QtCore.QObject): File menu callback for opening an Excellon file. :param signal: required because clicking the entry will generate a checked signal which needs a container + :param name: :return: None """ @@ -9619,10 +9626,12 @@ class App(QtCore.QObject): def on_fileopengcode(self, signal: bool = None, name=None): """ + File menu call back for opening gcode. :param signal: required because clicking the entry will generate a checked signal which needs a container - :return: None + :param name: + :return: """ self.report_usage("on_fileopengcode") diff --git a/README.md b/README.md index e115e7a8..678a9953 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,19 @@ CAD program, and create G-Code for Isolation routing. ================================================= +9.4.2020 + +- fixed the Tcl Command Delete to have an argument -f that will force deletion evading the popup (if the popup is enabled). The sme command without a name now will delete all objects +- fixed the Tcl Command JoinExcellons +- fixed the Tcl Command JoinGeometry +- fixed the Tcl Command Mirror +- updated the Tcl Command Mirror to use a (X,Y) origin parameter. Works if the -box parameter is not used. +- updated the Tcl Command Offset. Now it can use only -x or -y parameter no longer is mandatory to have both. The one that is not present will be assumed 0.0 +- updated the Tcl Command Panelize. The -rows and -columns parameters are no longer both required. If one is not present then it is assumed to be zero. +- updated the Tcl Command Scale. THe -origin parameter can now be a tuple of (x,y) coordinates. +- updated the Tcl Command Skew. Now it can use only -x or -y parameter no longer is mandatory to have both. The one that is not present will be assumed 0.0 +- updated the help for all the Tcl Commands + 6.04.2020 - added key shortcuts (arrow up/down) that will select the objects in the Project tab if the focus is in that tab diff --git a/tclCommands/TclCommandAddCircle.py b/tclCommands/TclCommandAddCircle.py index 181484d6..f48ece80 100644 --- a/tclCommands/TclCommandAddCircle.py +++ b/tclCommands/TclCommandAddCircle.py @@ -38,7 +38,7 @@ class TclCommandAddCircle(TclCommand): ('center_y', 'Y coordinates of the center of the circle.'), ('radius', 'Radius of the circle.') ]), - 'examples': [] + 'examples': ['add_circle geo_name 1.0 2.0 3'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandAddRectangle.py b/tclCommands/TclCommandAddRectangle.py index fa26ae02..0fa7096e 100644 --- a/tclCommands/TclCommandAddRectangle.py +++ b/tclCommands/TclCommandAddRectangle.py @@ -37,7 +37,7 @@ class TclCommandAddRectangle(TclCommandSignaled): ('x0 y0', 'Bottom left corner coordinates.'), ('x1 y1', 'Top right corner coordinates.') ]), - 'examples': [] + 'examples': ["add_rectangle geo_name 0 0 10 10"] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandAlignDrill.py b/tclCommands/TclCommandAlignDrill.py index e34c8afd..1659b2a4 100644 --- a/tclCommands/TclCommandAlignDrill.py +++ b/tclCommands/TclCommandAlignDrill.py @@ -41,7 +41,7 @@ class TclCommandAlignDrill(TclCommandSignaled): # structured help for current command, args needs to be ordered help = { - 'main': "Create excellon with drills for aligment.", + 'main': "Create an Excellon object with drills for alignment.", 'args': collections.OrderedDict([ ('name', 'Name of the object (Gerber or Excellon) to mirror.'), ('dia', 'Tool diameter'), diff --git a/tclCommands/TclCommandAlignDrillGrid.py b/tclCommands/TclCommandAlignDrillGrid.py index e15bd840..ac86f198 100644 --- a/tclCommands/TclCommandAlignDrillGrid.py +++ b/tclCommands/TclCommandAlignDrillGrid.py @@ -39,7 +39,7 @@ class TclCommandAlignDrillGrid(TclCommandSignaled): # structured help for current command, args needs to be ordered help = { - 'main': "Create excellon with drills for aligment grid.", + 'main': "Create an Excellon object with drills for alignment arranged in a grid.", 'args': collections.OrderedDict([ ('outname', 'Name of the object to create.'), ('dia', 'Tool diameter.'), diff --git a/tclCommands/TclCommandBbox.py b/tclCommands/TclCommandBbox.py index 06cef7d8..a3df3d16 100644 --- a/tclCommands/TclCommandBbox.py +++ b/tclCommands/TclCommandBbox.py @@ -38,7 +38,7 @@ class TclCommandBbox(TclCommand): # structured help for current command, args needs to be ordered help = { - 'main': "Creates a Geometry object that surrounds the object.", + 'main': "Creates a rectangular Geometry object that surrounds the object.", 'args': collections.OrderedDict([ ('name', 'Object name for which to create bounding box. String'), ('outname', 'Name of the resulting Geometry object. String.'), diff --git a/tclCommands/TclCommandBounds.py b/tclCommands/TclCommandBounds.py index e4d53c7b..a03a97c0 100644 --- a/tclCommands/TclCommandBounds.py +++ b/tclCommands/TclCommandBounds.py @@ -12,6 +12,7 @@ if '_' not in builtins.__dict__: log = logging.getLogger('base') + class TclCommandBounds(TclCommand): """ Tcl shell command to return the bounds values for a supplied list of objects (identified by their names). diff --git a/tclCommands/TclCommandClearShell.py b/tclCommands/TclCommandClearShell.py index d765367a..4672ecae 100644 --- a/tclCommands/TclCommandClearShell.py +++ b/tclCommands/TclCommandClearShell.py @@ -38,7 +38,7 @@ class TclCommandClearShell(TclCommand): 'main': "Clear the text in the Tcl Shell browser.", 'args': collections.OrderedDict([ ]), - 'examples': [] + 'examples': ['clear'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandCutout.py b/tclCommands/TclCommandCutout.py index 3df71efb..c074fa8e 100644 --- a/tclCommands/TclCommandCutout.py +++ b/tclCommands/TclCommandCutout.py @@ -48,7 +48,7 @@ class TclCommandCutout(TclCommand): ('gapsize', 'Size of gap. Default = 0.1'), ('gaps', "Type of gaps. Can be: 'tb' = top-bottom, 'lr' = left-right and '4' = one each side. Default = 4"), ]), - 'examples': [] + 'examples': ['cutout new_geo -dia 1.2 -margin 0.1 -gapsize 1 -gaps "tb" '] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandDelete.py b/tclCommands/TclCommandDelete.py index c5deb08d..43a69693 100644 --- a/tclCommands/TclCommandDelete.py +++ b/tclCommands/TclCommandDelete.py @@ -12,7 +12,7 @@ class TclCommandDelete(TclCommand): """ # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) - aliases = ['delete'] + aliases = ['delete', 'del'] # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ @@ -21,19 +21,23 @@ class TclCommandDelete(TclCommand): # Dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value option_types = collections.OrderedDict([ - + ('f', bool) ]) # array of mandatory options for current Tcl command: required = {'name','outname'} - required = ['name'] + required = [] # structured help for current command, args needs to be ordered help = { - 'main': 'Deletes the given object.', + 'main': 'Deletes the given object. If no name is given will delete all objects.', 'args': collections.OrderedDict([ ('name', 'Name of the Object.'), + ('f', 'Use this parameter to force deletion.') ]), - 'examples': [] + 'examples': ['del new_geo -f True\n' + 'delete new_geo -f 1\n' + 'del new_geo -f\n' + 'del new_geo'] } def execute(self, args, unnamed_args): @@ -43,13 +47,35 @@ class TclCommandDelete(TclCommand): :param unnamed_args: :return: """ - - obj_name = args['name'] + obj_name = None try: - # deselect all to avoid delete selected object when run delete from shell - self.app.collection.set_all_inactive() - self.app.collection.set_active(str(obj_name)) - self.app.on_delete() # Todo: This is an event handler for the GUI... bad? - except Exception as e: - return "Command failed: %s" % str(e) + obj_name = args['name'] + delete_all = False + except KeyError: + delete_all = True + + is_forced = False + if 'f' in args: + try: + if args['f'] is None: + is_forced = True + else: + is_forced = True if eval(str(args['f'])) else False + except KeyError: + is_forced = True + + if delete_all is False: + try: + # deselect all to avoid delete selected object when run delete from shell + self.app.collection.set_all_inactive() + self.app.collection.set_active(str(obj_name)) + self.app.on_delete(force_deletion=is_forced) + except Exception as e: + return "Command failed: %s" % str(e) + else: + try: + self.app.collection.set_all_active() + self.app.on_delete(force_deletion=is_forced) + except Exception as e: + return "Command failed: %s" % str(e) diff --git a/tclCommands/TclCommandExportGcode.py b/tclCommands/TclCommandExportGcode.py index 23842c91..2981e272 100644 --- a/tclCommands/TclCommandExportGcode.py +++ b/tclCommands/TclCommandExportGcode.py @@ -48,11 +48,11 @@ class TclCommandExportGcode(TclCommandSignaled): help = { 'main': "Export gcode into console output.", 'args': collections.OrderedDict([ - ('name', 'Name of the source Geometry object.'), + ('name', 'Name of the source Geometry object. Required.'), ('preamble', 'Prepend GCODE.'), ('postamble', 'Append GCODE.') ]), - 'examples': [] + 'examples': ['export_gcode geo_name -preamble "G01 X10 Y10" -postamble "G00 X20 Y20\nM04"'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandExportGerber.py b/tclCommands/TclCommandExportGerber.py index a4d27152..0fc7b0aa 100644 --- a/tclCommands/TclCommandExportGerber.py +++ b/tclCommands/TclCommandExportGerber.py @@ -31,7 +31,7 @@ class TclCommandExportGerber(TclCommand): help = { 'main': "Export a Gerber Object as a Gerber File.", 'args': collections.OrderedDict([ - ('obj_name', 'Name of the object to export.'), + ('obj_name', 'Name of the object to export. Required.'), ('filename', 'Path to the file to export.') ]), 'examples': ['export_gerber my_gerber path/my_file.gbr'] diff --git a/tclCommands/TclCommandExportSVG.py b/tclCommands/TclCommandExportSVG.py index ebe95bc6..bc6efce9 100644 --- a/tclCommands/TclCommandExportSVG.py +++ b/tclCommands/TclCommandExportSVG.py @@ -33,7 +33,7 @@ class TclCommandExportSVG(TclCommand): help = { 'main': "Export a Geometry Object as a SVG File.", 'args': collections.OrderedDict([ - ('name', 'Name of the object export.'), + ('name', 'Name of the object export. Required.'), ('filename', 'Path to the file to export.'), ('scale_factor', 'Multiplication factor used for scaling line widths during export.') ]), diff --git a/tclCommands/TclCommandExteriors.py b/tclCommands/TclCommandExteriors.py index e6a65503..cb3f041a 100644 --- a/tclCommands/TclCommandExteriors.py +++ b/tclCommands/TclCommandExteriors.py @@ -29,10 +29,10 @@ class TclCommandExteriors(TclCommandSignaled): help = { 'main': "Get exteriors of polygons.", 'args': collections.OrderedDict([ - ('name', 'Name of the source Geometry object.'), + ('name', 'Name of the source Geometry object. Required.'), ('outname', 'Name of the resulting Geometry object.') ]), - 'examples': [] + 'examples': ['ext geo_source_name -outname "final_geo"'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandFollow.py b/tclCommands/TclCommandFollow.py index 59ad53ee..0ca8ab5e 100644 --- a/tclCommands/TclCommandFollow.py +++ b/tclCommands/TclCommandFollow.py @@ -29,10 +29,10 @@ class TclCommandFollow(TclCommandSignaled): help = { 'main': "Creates a geometry object following gerber paths.", 'args': collections.OrderedDict([ - ('name', 'Object name to follow.'), + ('name', 'Object name to follow. Required.'), ('outname', 'Name of the resulting Geometry object.') ]), - 'examples': ['follow name -outname name_follow'] + 'examples': ['follow name -outname "name_follow"'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandGeoCutout.py b/tclCommands/TclCommandGeoCutout.py index f7df8108..c138d4ad 100644 --- a/tclCommands/TclCommandGeoCutout.py +++ b/tclCommands/TclCommandGeoCutout.py @@ -45,14 +45,14 @@ class TclCommandGeoCutout(TclCommandSignaled): help = { 'main': 'Creates board cutout from an object (Gerber or Geometry) of any shape', 'args': collections.OrderedDict([ - ('name', 'Name of the object.'), + ('name', 'Name of the object to be cutout. Required'), ('dia', 'Tool diameter.'), ('margin', 'Margin over bounds.'), ('gapsize', 'size of gap.'), ('gaps', "type of gaps. Can be: 'tb' = top-bottom, 'lr' = left-right, '2tb' = 2top-2bottom, " "'2lr' = 2left-2right, '4' = 4 cuts, '8' = 8 cuts") ]), - 'examples': [" #isolate margin for example from fritzing arduino shield or any svg etc\n" + + 'examples': [" #isolate margin for example from Fritzing arduino shield or any svg etc\n" + " isolate BCu_margin -dia 3 -overlap 1\n" + "\n" + " #create exteriors from isolated object\n" + diff --git a/tclCommands/TclCommandGeoUnion.py b/tclCommands/TclCommandGeoUnion.py index b0be4734..ac4fa4ea 100644 --- a/tclCommands/TclCommandGeoUnion.py +++ b/tclCommands/TclCommandGeoUnion.py @@ -32,12 +32,12 @@ class TclCommandGeoUnion(TclCommand): help = { 'main': ('Runs a union operation (addition) on the components ' 'of the geometry object. For example, if it contains ' - '2 intersecting polygons, this opperation adds them into' + '2 intersecting polygons, this operation adds them into' 'a single larger polygon.'), 'args': collections.OrderedDict([ - ('name', 'Name of the Geometry Object.'), + ('name', 'Name of the Geometry Object that contain the components to be joined. Required.'), ]), - 'examples': [] + 'examples': ['geo_union target_geo'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandGetNames.py b/tclCommands/TclCommandGetNames.py index 6b597f6f..7cca9a46 100644 --- a/tclCommands/TclCommandGetNames.py +++ b/tclCommands/TclCommandGetNames.py @@ -29,11 +29,11 @@ class TclCommandGetNames(TclCommand): # structured help for current command, args needs to be ordered help = { - 'main': 'Lists the names of objects in the project.', + 'main': 'Lists the names of objects in the project. It returns a string with names separated by \n', 'args': collections.OrderedDict([ ]), - 'examples': [] + 'examples': ['get_names'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandGetSys.py b/tclCommands/TclCommandGetSys.py index 915ac18e..f98c3315 100644 --- a/tclCommands/TclCommandGetSys.py +++ b/tclCommands/TclCommandGetSys.py @@ -36,9 +36,9 @@ class TclCommandGetSys(TclCommand): # structured help for current command, args needs to be ordered help = { - 'main': "Returns the value of the system variable.", + 'main': "Returns the value of the targeted system variable.", 'args': collections.OrderedDict([ - ('name', 'Name of the system variable.'), + ('name', 'Name of the system variable. Required.'), ]), 'examples': ['get_sys excellon_zeros'] } diff --git a/tclCommands/TclCommandImportSvg.py b/tclCommands/TclCommandImportSvg.py index 6489db15..0617090e 100644 --- a/tclCommands/TclCommandImportSvg.py +++ b/tclCommands/TclCommandImportSvg.py @@ -30,11 +30,11 @@ class TclCommandImportSvg(TclCommandSignaled): help = { 'main': "Import an SVG file as a Geometry Object..", 'args': collections.OrderedDict([ - ('filename', 'Path to file to open.'), + ('filename', 'Absolute path to file to open. Required.'), ('type', 'Import as gerber or geometry(default).'), ('outname', 'Name of the resulting Geometry object.') ]), - 'examples': [] + 'examples': ['import_svg D:\\my_beautiful_svg_file.SVG'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandInteriors.py b/tclCommands/TclCommandInteriors.py index d4a1adb3..f22ef1db 100644 --- a/tclCommands/TclCommandInteriors.py +++ b/tclCommands/TclCommandInteriors.py @@ -27,12 +27,12 @@ class TclCommandInteriors(TclCommandSignaled): # structured help for current command, args needs to be ordered help = { - 'main': "Get interiors of polygons.", + 'main': "Return the interiors of polygons as a list of Shapely geometry elements.", 'args': collections.OrderedDict([ - ('name', 'Name of the source Geometry object.'), + ('name', 'Name of the source Geometry object. Required.'), ('outname', 'Name of the resulting Geometry object.') ]), - 'examples': [] + 'examples': ['interiors my_geo_name -outname "outputed_geo"'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandIsolate.py b/tclCommands/TclCommandIsolate.py index f2864303..542dd3c3 100644 --- a/tclCommands/TclCommandIsolate.py +++ b/tclCommands/TclCommandIsolate.py @@ -29,7 +29,7 @@ class TclCommandIsolate(TclCommandSignaled): ('dia', float), ('passes', int), ('overlap', float), - ('combine', int), + ('combine', bool), ('outname', str), ('follow', str), ('iso_type', int) @@ -43,18 +43,18 @@ class TclCommandIsolate(TclCommandSignaled): help = { 'main': "Creates isolation routing geometry for the given Gerber.", 'args': collections.OrderedDict([ - ('name', 'Name of the source object.'), + ('name', 'Name of the source object. Required.'), ('dia', 'Tool diameter.'), ('passes', 'Passes of tool width.'), ('overlap', 'Percentage of tool diameter to overlap current pass over previous pass. Float [0, 99.9999]\n' 'E.g: for a 25% from tool diameter overlap use -overlap 25'), - ('combine', 'Combine all passes into one geometry.'), + ('combine', 'Combine all passes into one geometry. Can be True or False, 1 or 0'), ('outname', 'Name of the resulting Geometry object.'), ('follow', 'Create a Geometry that follows the Gerber path.'), ('iso_type', 'A value of 0 will isolate exteriors, a value of 1 will isolate interiors ' 'and a value of 2 will do full isolation.') ]), - 'examples': [] + 'examples': ['isolate my_geo -dia 0.1 -passes 2 -overlap 10 -combine True -iso_type 2 -outname out_geo'] } def execute(self, args, unnamed_args): @@ -80,6 +80,10 @@ class TclCommandIsolate(TclCommandSignaled): if 'follow' not in args: args['follow'] = None + # evaluate this parameter so True, False, 0 and 1 works + if "combine" in args: + args['combine'] = eval(args['combine']) + obj = self.app.collection.get_by_name(name) if obj is None: self.raise_tcl_error("Object not found: %s" % name) diff --git a/tclCommands/TclCommandJoinExcellon.py b/tclCommands/TclCommandJoinExcellon.py index efe6290e..c385b55c 100644 --- a/tclCommands/TclCommandJoinExcellon.py +++ b/tclCommands/TclCommandJoinExcellon.py @@ -22,7 +22,6 @@ class TclCommandJoinExcellon(TclCommand): # Dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value option_types = collections.OrderedDict([ - ]) # array of mandatory options for current Tcl command: required = {'name','outname'} @@ -30,14 +29,14 @@ class TclCommandJoinExcellon(TclCommand): # structured help for current command, args needs to be ordered help = { - 'main': "Runs a merge operation (join) on the Excellon objects.", + 'main': "Runs a merge operation (join) on the Excellon objects.\n" + "The names of the Excellon objects to be merged will be entered after the outname,\n" + "separated by spaces. See the example bellow.\n" + "WARNING: if the name of an Excellon objects has spaces, enclose the name with quotes.", 'args': collections.OrderedDict([ - ('name', 'Name of the new Excellon Object.'), - ('obj_name_0', 'Name of the first object'), - ('obj_name_1', 'Name of the second object.'), - ('obj_name_2...', 'Additional object names') + ('outname', 'Name of the new Excellon Object made by joining of other Excellon objects. Required'), ]), - 'examples': [] + 'examples': ['join_excellons merged_new_excellon exc_name_1 "exc name_2"'] } def execute(self, args, unnamed_args): @@ -48,7 +47,7 @@ class TclCommandJoinExcellon(TclCommand): :return: """ - outname = args['name'] + outname = args['outname'] obj_names = unnamed_args objs = [] @@ -60,7 +59,9 @@ class TclCommandJoinExcellon(TclCommand): objs.append(obj) def initialize(obj_, app): - FlatCAMExcellon.merge(objs, obj_) + FlatCAMExcellon.merge(self, objs, obj_) - if objs is not None: + if objs: self.app.new_object("excellon", outname, initialize, plot=False) + else: + return "No Excellon objects to be joined." diff --git a/tclCommands/TclCommandJoinGeometry.py b/tclCommands/TclCommandJoinGeometry.py index 74036d80..d3208877 100644 --- a/tclCommands/TclCommandJoinGeometry.py +++ b/tclCommands/TclCommandJoinGeometry.py @@ -30,14 +30,14 @@ class TclCommandJoinGeometry(TclCommand): # structured help for current command, args needs to be ordered help = { - 'main': "Runs a merge operation (join) on the Excellon objects.", + 'main': "Runs a merge operation (join) on the Geometry objects.\n" + "The names of the Geometry objects to be merged will be entered after the outname,\n" + "separated by spaces. See the example bellow.\n" + "WARNING: if the name of an Geometry objects has spaces, enclose the name with quotes.", 'args': collections.OrderedDict([ - ('outname', 'Name of the new Geometry Object.'), - ('obj_name_0', 'Name of the first object'), - ('obj_name_1', 'Name of the second object.'), - ('obj_name_2...', 'Additional object names') + ('outname', 'Name of the new Geometry Object made by joining of other Geometry objects. Required'), ]), - 'examples': [] + 'examples': ['join_geometry merged_new_geo geo_name_1 "geo name_2"'] } def execute(self, args, unnamed_args): @@ -60,7 +60,9 @@ class TclCommandJoinGeometry(TclCommand): objs.append(obj) def initialize(obj_, app): - FlatCAMGeometry.merge(objs, obj_) + FlatCAMGeometry.merge(self, objs, obj_) - if objs is not None: + if objs: self.app.new_object("geometry", outname, initialize, plot=False) + else: + return "No Geometry objects to be joined." diff --git a/tclCommands/TclCommandListSys.py b/tclCommands/TclCommandListSys.py index 58d8c8e3..cff9ca06 100644 --- a/tclCommands/TclCommandListSys.py +++ b/tclCommands/TclCommandListSys.py @@ -40,7 +40,7 @@ class TclCommandListSys(TclCommand): "of the system variable.\n" "In that case it will list only the system variables that starts with that string.\n" "Main categories start with: gerber or excellon or geometry or cncjob or global.\n" - "Note: Use get_sys TclCommand to get the value and set_sys TclCommand to set it.\n", + "Note: Use 'get_sys system variable' to get the value and 'set_sys system variable value' to set it.\n", 'args': collections.OrderedDict([ ]), 'examples': ['list_sys', diff --git a/tclCommands/TclCommandMillDrills.py b/tclCommands/TclCommandMillDrills.py index a7d607c2..1e8684d0 100644 --- a/tclCommands/TclCommandMillDrills.py +++ b/tclCommands/TclCommandMillDrills.py @@ -34,7 +34,7 @@ class TclCommandMillDrills(TclCommandSignaled): ('milled_dias', str), ('outname', str), ('tooldia', float), - ('use_threads', bool), + ('use_thread', bool), ('diatol', float) ]) @@ -45,10 +45,13 @@ class TclCommandMillDrills(TclCommandSignaled): help = { 'main': "Create Geometry Object for milling drill holes from Excellon.", 'args': collections.OrderedDict([ - ('name', 'Name of the Excellon Object.'), - ('milled_dias', 'Comma separated tool diameters of the drills to be milled (example: 0.6, 1.0 or 3.125).'), + ('name', 'Name of the Excellon Object. Required.'), + ('milled_dias', 'Comma separated tool diameters of the drills to be milled (example: 0.6, 1.0 or 3.125).\n' + 'Exception: if you enter "all" then the drills for all tools will be milled.\n' + 'WARNING: no spaces are allowed in the list of tools.\n' + 'As a precaution you can enclose them with quotes.'), ('tooldia', 'Diameter of the milling tool (example: 0.1).'), - ('outname', 'Name of object to create.'), + ('outname', 'Name of object to be created holding the milled geometries.'), ('use_thread', 'If to use multithreading: True or False.'), ('diatol', 'Tolerance. Percentange (0.0 ... 100.0) within which dias in milled_dias will be judged to be ' 'the same as the ones in the tools from the Excellon object. E.g: if in milled_dias we have a ' @@ -56,7 +59,8 @@ class TclCommandMillDrills(TclCommandSignaled): 'diatol = 5.0 then the drills with the dia = (0.95 ... 1.05) ' 'in Excellon will be processed. Float number.') ]), - 'examples': ['milldrills mydrills', 'milld my_excellon.drl'] + 'examples': ['milldrills mydrills -milled_dias "0.6,0.8" -tooldia 0.1 -diatol 10 -outname milled_holes', + 'milld my_excellon.drl'] } def execute(self, args, unnamed_args): @@ -85,8 +89,6 @@ class TclCommandMillDrills(TclCommandSignaled): if not obj.drills: self.raise_tcl_error("The Excellon object has no drills: %s" % name) - units = self.app.defaults['units'].upper() - try: if 'milled_dias' in args and args['milled_dias'] != 'all': diameters = [x.strip() for x in args['milled_dias'].split(",") if x != ''] diff --git a/tclCommands/TclCommandMillSlots.py b/tclCommands/TclCommandMillSlots.py index 9665c91d..af6070be 100644 --- a/tclCommands/TclCommandMillSlots.py +++ b/tclCommands/TclCommandMillSlots.py @@ -34,7 +34,7 @@ class TclCommandMillSlots(TclCommandSignaled): ('milled_dias', str), ('outname', str), ('tooldia', float), - ('use_threads', bool), + ('use_thread', bool), ('diatol', float) ]) @@ -45,10 +45,13 @@ class TclCommandMillSlots(TclCommandSignaled): help = { 'main': "Create Geometry Object for milling slot holes from Excellon.", 'args': collections.OrderedDict([ - ('name', 'Name of the Excellon Object.'), - ('milled_dias', 'Comma separated tool diameters of the slots to be milled (example: 0.6, 1.0 or 3.125).'), + ('name', 'Name of the Excellon Object. Required.'), + ('milled_dias', 'Comma separated tool diameters of the slots to be milled (example: 0.6, 1.0 or 3.125).\n' + 'Exception: if you enter "all" then the slots for all tools will be milled.\n' + 'WARNING: no spaces are allowed in the list of tools.\n' + 'As a precaution you can enclose them with quotes.'), ('tooldia', 'Diameter of the milling tool (example: 0.1).'), - ('outname', 'Name of object to create.'), + ('outname', 'Name of object to be created holding the milled geometries.'), ('use_thread', 'If to use multithreading: True or False.'), ('diatol', 'Tolerance. Percentange (0.0 ... 100.0) within which dias in milled_dias will be judged to be ' 'the same as the ones in the tools from the Excellon object. E.g: if in milled_dias we have a ' @@ -56,7 +59,8 @@ class TclCommandMillSlots(TclCommandSignaled): 'diatol = 5.0 then the slots with the dia = (0.95 ... 1.05) ' 'in Excellon will be processed. Float number.') ]), - 'examples': ['millslots mydrills', 'mills my_excellon.drl'] + 'examples': ['millslots myslots -milled_dias "0.6,0.8" -tooldia 0.1 -diatol 10 -outname milled_slots', + 'mills my_excellon.drl'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandMirror.py b/tclCommands/TclCommandMirror.py index 819f26ef..cc29852f 100644 --- a/tclCommands/TclCommandMirror.py +++ b/tclCommands/TclCommandMirror.py @@ -24,22 +24,25 @@ class TclCommandMirror(TclCommandSignaled): option_types = collections.OrderedDict([ ('axis', str), ('box', str), - ('dist', float) + ('origin', str) ]) # array of mandatory options for current Tcl command: required = {'name','outname'} - required = ['name', 'axis'] + required = ['name'] # structured help for current command, args needs to be ordered help = { - 'main': "Opens an Excellon file.", + 'main': "Will mirror an named object.", 'args': collections.OrderedDict([ - ('name', 'Name of the object (Gerber or Excellon) to mirror.'), - ('box', 'Name of object which act as box (cutout for example.)'), + ('name', 'Name of the object (Gerber, Geometry or Excellon) to be mirrored. Required.'), ('axis', 'Mirror axis parallel to the X or Y axis.'), - ('dist', 'Distance of the mirror axis to the X or Y axis.') + ('box', 'Name of object which act as box (cutout for example.)'), + ('origin', 'Reference point . It is used only if the box is not used. Format (x,y).\n' + 'Comma will separate the X and Y coordinates.\n' + 'WARNING: no spaces are allowed. If uncertain enclose the two values inside parenthesis.\n' + 'See the example.') ]), - 'examples': [] + 'examples': ['mirror obj_name -box box_geo -axis X -origin 3.2,4.7'] } def execute(self, args, unnamed_args): @@ -69,10 +72,13 @@ class TclCommandMirror(TclCommandSignaled): return "ERROR: Only Gerber, Excellon and Geometry objects can be mirrored." # Axis - try: - axis = args['axis'].upper() - except KeyError: - return "ERROR: Specify -axis X or -axis Y" + if 'axis' in args: + try: + axis = args['axis'].upper() + except KeyError: + axis = 'Y' + else: + axis = 'Y' # Box if 'box' in args: @@ -91,19 +97,22 @@ class TclCommandMirror(TclCommandSignaled): obj.mirror(axis, [px, py]) obj.plot() - + return except Exception as e: return "Operation failed: %s" % str(e) - else: + # Origin + if 'origin' in args: try: - dist = float(args['dist']) + origin_val = eval(args['origin']) + x = float(origin_val[0]) + y = float(origin_val[1]) except KeyError: - dist = 0.0 + x, y = (0, 0) except ValueError: - return "Invalid distance: %s" % args['dist'] + return "Invalid distance: %s" % str(args['origin']) try: - obj.mirror(axis, [dist, dist]) + obj.mirror(axis, [x, y]) except Exception as e: return "Operation failed: %s" % str(e) diff --git a/tclCommands/TclCommandNew.py b/tclCommands/TclCommandNew.py index 757412d3..66ff83b9 100644 --- a/tclCommands/TclCommandNew.py +++ b/tclCommands/TclCommandNew.py @@ -24,7 +24,7 @@ class TclCommandNew(TclCommand): help = { 'main': "Starts a new project. Clears objects from memory.", 'args': collections.OrderedDict(), - 'examples': [] + 'examples': ['new'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandNewExcellon.py b/tclCommands/TclCommandNewExcellon.py index 2c540fe1..c1322133 100644 --- a/tclCommands/TclCommandNewExcellon.py +++ b/tclCommands/TclCommandNewExcellon.py @@ -39,7 +39,7 @@ class TclCommandNewExcellon(TclCommandSignaled): 'args': collections.OrderedDict([ ('name', 'New object name.'), ]), - 'examples': [] + 'examples': ['new_excellon my_excellon', 'new_excellon'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandNewGeometry.py b/tclCommands/TclCommandNewGeometry.py index 089b2c50..4af616c6 100644 --- a/tclCommands/TclCommandNewGeometry.py +++ b/tclCommands/TclCommandNewGeometry.py @@ -28,11 +28,12 @@ class TclCommandNewGeometry(TclCommandSignaled): # structured help for current command, args needs to be ordered help = { - 'main': "Creates a new empty geometry object.", + 'main': "Creates a new empty Geometry object.", 'args': collections.OrderedDict([ ('name', 'New object name.'), ]), - 'examples': [] + 'examples': ['new_geometry\n' + 'new_geometry my_new_geo'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandNewGerber.py b/tclCommands/TclCommandNewGerber.py index bccbd923..7a667813 100644 --- a/tclCommands/TclCommandNewGerber.py +++ b/tclCommands/TclCommandNewGerber.py @@ -39,7 +39,7 @@ class TclCommandNewGerber(TclCommandSignaled): 'args': collections.OrderedDict([ ('name', 'New object name.'), ]), - 'examples': [] + 'examples': ['new_gerber', 'new_gerber my_new_gerber_name'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandNregions.py b/tclCommands/TclCommandNregions.py index 6dbb22d5..a4146792 100644 --- a/tclCommands/TclCommandNregions.py +++ b/tclCommands/TclCommandNregions.py @@ -41,13 +41,13 @@ class TclCommandNregions(TclCommand): help = { 'main': "Creates a geometry object with the non-copper regions.", 'args': collections.OrderedDict([ - ('name', 'Object name for which to create non-copper regions. String'), + ('name', 'Object name for which to create non-copper regions. String. Required.'), ('outname', 'Name of the resulting Geometry object. String.'), ('margin', "Specify the edge of the PCB by drawing a box around all objects with this minimum distance. " "Float number."), ('rounded', "Resulting geometry will have rounded corners. True or False.") ]), - 'examples': ['ncr name -outname name_ncr'] + 'examples': ['ncr name -margin 0.1 -rounded True -outname name_ncr'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandOffset.py b/tclCommands/TclCommandOffset.py index a7306db9..6f5fd1c7 100644 --- a/tclCommands/TclCommandOffset.py +++ b/tclCommands/TclCommandOffset.py @@ -23,21 +23,22 @@ class TclCommandOffset(TclCommand): # Dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value option_types = collections.OrderedDict([ - + ('x', float), + ('y', float) ]) # array of mandatory options for current Tcl command: required = {'name','outname'} - required = ['name', 'x', 'y'] + required = ['name'] # structured help for current command, args needs to be ordered help = { - 'main': "Changes the position of the object.", + 'main': "Changes the position of the object on X and/or Y axis.", 'args': collections.OrderedDict([ - ('name', 'Name of the object to offset.'), - ('x', 'Offset distance in the X axis.'), - ('y', 'Offset distance in the Y axis') + ('name', 'Name of the object to offset. Required.'), + ('x', 'Offset distance in the X axis. If it is not used it will be assumed to be 0.0'), + ('y', 'Offset distance in the Y axis. If it is not used it will be assumed to be 0.0') ]), - 'examples': ['offset my_geometry 1.2 -0.3'] + 'examples': ['offset my_geometry -x 1.2 -y -0.3', 'offset my_geometry -x 1.0'] } def execute(self, args, unnamed_args): @@ -49,6 +50,12 @@ class TclCommandOffset(TclCommand): """ name = args['name'] - x, y = float(args['x']), float(args['y']) + off_x = args['x'] if 'x' in args else 0.0 + off_y = args['y'] if 'y' in args else 0.0 + + x, y = float(off_x), float(off_y) + + if (x, y) == (0.0, 0.0): + return self.app.collection.get_by_name(name).offset((x, y)) diff --git a/tclCommands/TclCommandOpenExcellon.py b/tclCommands/TclCommandOpenExcellon.py index c9f32409..167db227 100644 --- a/tclCommands/TclCommandOpenExcellon.py +++ b/tclCommands/TclCommandOpenExcellon.py @@ -30,10 +30,13 @@ class TclCommandOpenExcellon(TclCommandSignaled): help = { 'main': "Opens an Excellon file.", 'args': collections.OrderedDict([ - ('filename', 'Path to file to open.'), + ('filename', 'Absolute path to file to open. Required.\n' + 'WARNING: no spaces are allowed. If unsure enclose the entire path with quotes.'), ('outname', 'Name of the resulting Excellon object.') ]), - 'examples': [] + 'examples': ['open_excellon D:\\my_excellon_file.DRL', + 'open_excellon "D:\\my_excellon_file with spaces in the name.DRL"', + 'open_excellon path_to_file'] } def execute(self, args, unnamed_args): @@ -48,6 +51,9 @@ class TclCommandOpenExcellon(TclCommandSignaled): filename = args.pop('filename') # filename = filename.replace(' ', '') + if ' ' in filename: + return "The absolute path to the project file contain spaces which is not allowed.\n" \ + "Please enclose the path within quotes." args['plot'] = False self.app.open_excellon(filename, **args) diff --git a/tclCommands/TclCommandOpenGCode.py b/tclCommands/TclCommandOpenGCode.py index d4da1423..5eaa83c9 100644 --- a/tclCommands/TclCommandOpenGCode.py +++ b/tclCommands/TclCommandOpenGCode.py @@ -31,10 +31,12 @@ class TclCommandOpenGCode(TclCommandSignaled): help = { 'main': "Opens a G-Code file.", 'args': collections.OrderedDict([ - ('filename', 'Path to file to open.'), + ('filename', 'Absolute path to file to open. Required.\n' + 'WARNING: no spaces are allowed. If unsure enclose the entire path with quotes.'), ('outname', 'Name of the resulting CNCJob object.') ]), - 'examples': [] + 'examples': ['open_gcode D:\\my_gcode_file.NC', + 'open_gcode "D:\\my_gcode_file with spaces in the name.TXT"'] } def execute(self, args, unnamed_args): @@ -48,6 +50,8 @@ class TclCommandOpenGCode(TclCommandSignaled): """ args['plot'] = False filename = args["filename"] - # filename = filename.replace(' ', '') + if ' ' in filename: + return "The absolute path to the project file contain spaces which is not allowed.\n" \ + "Please enclose the path within quotes." self.app.open_gcode(filename, **args) diff --git a/tclCommands/TclCommandOpenGerber.py b/tclCommands/TclCommandOpenGerber.py index 0b67f83c..037882a1 100644 --- a/tclCommands/TclCommandOpenGerber.py +++ b/tclCommands/TclCommandOpenGerber.py @@ -30,10 +30,12 @@ class TclCommandOpenGerber(TclCommandSignaled): help = { 'main': "Opens a Gerber file.", 'args': collections.OrderedDict([ - ('filename', 'Path to file to open.'), + ('filename', 'Absolute path to file to open. Required.\n' + 'WARNING: no spaces are allowed. If unsure enclose the entire path with quotes.'), ('outname', 'Name of the resulting Gerber object.') ]), - 'examples': ["open_gerber gerber_object_path -outname bla"] + 'examples': ["open_gerber gerber_object_path -outname bla", + 'open_gerber "D:\\my_gerber_file with spaces in the name.GRB"'] } def execute(self, args, unnamed_args): @@ -65,7 +67,10 @@ class TclCommandOpenGerber(TclCommandSignaled): return filename = args['filename'] - # filename = filename.replace(' ', '') + + if ' ' in filename: + return "The absolute path to the project file contain spaces which is not allowed.\n" \ + "Please enclose the path within quotes." if 'outname' in args: outname = args['outname'] diff --git a/tclCommands/TclCommandOpenProject.py b/tclCommands/TclCommandOpenProject.py index ef0775af..3dddad61 100644 --- a/tclCommands/TclCommandOpenProject.py +++ b/tclCommands/TclCommandOpenProject.py @@ -30,9 +30,11 @@ class TclCommandOpenProject(TclCommandSignaled): help = { 'main': "Opens a FlatCAM project.", 'args': collections.OrderedDict([ - ('filename', 'Path to file to open.'), + ('filename', 'Absolute path to file to open. Required.\n' + 'WARNING: no spaces are allowed. If unsure enclose the entire path with quotes.'), ]), - 'examples': [] + 'examples': ['open_project D:\\my_project_file.FlatPrj', + 'open_project "D:\\my_project_file with spaces in the name.FlatPrj"'] } def execute(self, args, unnamed_args): @@ -45,6 +47,8 @@ class TclCommandOpenProject(TclCommandSignaled): :return: None or exception """ filename = args['filename'] - filename = filename.replace(' ', '') + if ' ' in filename: + return "The absolute path to the project file contain spaces which is not allowed.\n" \ + "Please enclose the path within quotes." self.app.open_project(filename, cli=True, plot=False) diff --git a/tclCommands/TclCommandOptions.py b/tclCommands/TclCommandOptions.py index 4bc90b84..ab22599e 100644 --- a/tclCommands/TclCommandOptions.py +++ b/tclCommands/TclCommandOptions.py @@ -28,11 +28,11 @@ class TclCommandOptions(TclCommandSignaled): # structured help for current command, args needs to be ordered help = { - 'main': "Shows the settings for an object.", + 'main': "Will return the options (settings) for an object as a string with values separated by \\n.", 'args': collections.OrderedDict([ - ('name', 'Object name.'), + ('name', 'Object name for which to return the options. Required.'), ]), - 'examples': [] + 'examples': ['options obj_name'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandPanelize.py b/tclCommands/TclCommandPanelize.py index b40cc434..71d50199 100644 --- a/tclCommands/TclCommandPanelize.py +++ b/tclCommands/TclCommandPanelize.py @@ -38,7 +38,7 @@ class TclCommandPanelize(TclCommand): ]) # array of mandatory options for current Tcl command: required = {'name','outname'} - required = ['name', 'rows', 'columns'] + required = ['name'] # structured help for current command, args needs to be ordered help = { @@ -54,7 +54,14 @@ class TclCommandPanelize(TclCommand): ('outname', 'Name of the new geometry object.'), ('run_threaded', 'False = non-threaded || True = threaded') ]), - 'examples': [] + 'examples': [ + 'panelize obj_name', + + 'panel obj_name -rows 2 -columns 2 -spacing_columns 0.4 -spacing_rows 1.3 -box box_obj_name ' + '-outname panelized_name', + + 'panel obj_name -columns 2 -box box_obj_name -outname panelized_name', + ] } def execute(self, args, unnamed_args): @@ -85,8 +92,18 @@ class TclCommandPanelize(TclCommand): else: box = obj - if 'columns' not in args or 'rows' not in args: - return "ERROR: Specify -columns and -rows" + if 'columns' in args: + columns = int(args['columns']) + else: + columns = int(0) + + if 'rows' in args: + rows = int(args['rows']) + else: + rows = int(0) + + if 'columns' not in args and 'rows' not in args: + return "ERROR: Specify either -columns or -rows. The one not specified it will assumed to be 0" if 'outname' in args: outname = args['outname'] @@ -108,9 +125,6 @@ class TclCommandPanelize(TclCommand): else: spacing_rows = 5 - rows = int(args['rows']) - columns = int(args['columns']) - xmin, ymin, xmax, ymax = box.bounds() lenghtx = xmax - xmin + spacing_columns lenghty = ymax - ymin + spacing_rows diff --git a/tclCommands/TclCommandPlotAll.py b/tclCommands/TclCommandPlotAll.py index 2e8ead22..d3833dd0 100644 --- a/tclCommands/TclCommandPlotAll.py +++ b/tclCommands/TclCommandPlotAll.py @@ -33,7 +33,7 @@ class TclCommandPlotAll(TclCommand): 'args': collections.OrderedDict([ ]), - 'examples': [] + 'examples': ['plot_all'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandPlotObjects.py b/tclCommands/TclCommandPlotObjects.py index bc3978a3..1df57886 100644 --- a/tclCommands/TclCommandPlotObjects.py +++ b/tclCommands/TclCommandPlotObjects.py @@ -32,15 +32,15 @@ class TclCommandPlotObjects(TclCommand): ]) # array of mandatory options for current Tcl command: required = {'name','outname'} - required = [] + required = ['names'] # structured help for current command, args needs to be ordered help = { 'main': "Plot a list of objects.", 'args': collections.OrderedDict([ - ('names', "UA list of object names to be plotted.") + ('names', "A list of object names to be plotted separated by comma. Required.") ]), - 'examples': ["plot_objects"] + 'examples': ["plot_objects gerber_obj.GRB, excellon_obj.DRL"] } def execute(self, args, unnamed_args): @@ -51,7 +51,7 @@ class TclCommandPlotObjects(TclCommand): :return: """ if self.app.cmd_line_headless != 1: - names = [x.strip() for x in args['names'].split(",")] + names = [x.strip() for x in args['names'].split(",") if x != ''] objs = [] for name in names: objs.append(self.app.collection.get_by_name(name)) diff --git a/tclCommands/TclCommandSaveProject.py b/tclCommands/TclCommandSaveProject.py index 9eaa1bbe..899247a2 100644 --- a/tclCommands/TclCommandSaveProject.py +++ b/tclCommands/TclCommandSaveProject.py @@ -30,9 +30,12 @@ class TclCommandSaveProject(TclCommandSignaled): help = { 'main': "Saves the FlatCAM project to file.", 'args': collections.OrderedDict([ - ('filename', 'Path to file.'), + ('filename', 'Absolute path to file to open. Required.\n' + 'WARNING: no spaces are allowed. If unsure enclose the entire path with quotes.'), ]), - 'examples': [] + 'examples': ['save_project D:\\my_project_file.FlatPrj', + 'save_project "D:\\my_project_file with spaces in the name.FlatPrj"', + 'save_project path_to_where_the_file_is_stored'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandSaveSys.py b/tclCommands/TclCommandSaveSys.py index 9b18ba80..5712515b 100644 --- a/tclCommands/TclCommandSaveSys.py +++ b/tclCommands/TclCommandSaveSys.py @@ -33,9 +33,9 @@ class TclCommandSaveSys(TclCommandSignaled): # structured help for current command, args needs to be ordered help = { - 'main': "Saves the FlatCAM system paramaters to defaults file.", + 'main': "Saves the FlatCAM system parameters to defaults file.", 'args': collections.OrderedDict([]), - 'examples': [] + 'examples': ['save_sys'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandScale.py b/tclCommands/TclCommandScale.py index 8f68ee92..aa5ebc3e 100644 --- a/tclCommands/TclCommandScale.py +++ b/tclCommands/TclCommandScale.py @@ -45,18 +45,22 @@ class TclCommandScale(TclCommand): help = { 'main': "Resizes the object by a factor on X axis and a factor on Y axis, having as scale origin the point ", 'args': collections.OrderedDict([ - ('name', 'Name of the object to resize.'), - ('factor', 'Fraction by which to scale on both axis. '), + ('name', 'Name of the object (Gerber, Geometry or Excellon) to be resized. Required.'), + ('factor', 'Fraction by which to scale on both axis.'), ('x', 'Fraction by which to scale on X axis. If "factor" is used then this parameter is ignored'), ('y', 'Fraction by which to scale on Y axis. If "factor" is used then this parameter is ignored'), - ('origin', 'Reference used for scale. It can be: "origin" which means point (0, 0) or "min_bounds" which ' - 'means the lower left point of the bounding box or it can be "center" which means the center ' - 'of the bounding box.') + ('origin', 'Reference used for scale.\n' + 'The reference point can be:\n' + '- "origin" which means point (0, 0)\n' + '- "min_bounds" which means the lower left point of the bounding box\n' + '- "center" which means the center point of the bounding box of the object.\n' + '- a tuple in format (x,y) with the X and Y coordinates separated by a comma. NO SPACES ALLOWED') ]), 'examples': ['scale my_geometry 4.2', 'scale my_geo -x 3.1 -y 2.8', - 'scale my_geo 1.2 -origin min_bounds'] + 'scale my_geo 1.2 -origin min_bounds', + 'scale my_geometry -x 2 -origin 3.0,2.1'] } def execute(self, args, unnamed_args): @@ -92,8 +96,17 @@ class TclCommandScale(TclCommand): c_y = ymin + (ymax - ymin) / 2 point = (c_x, c_y) else: - self.raise_tcl_error('%s' % _("Expected -origin or -origin or -origin
.")) - return 'fail' + try: + point = eval(args['origin']) + if not isinstance(point, tuple): + raise Exception + except Exception as e: + self.raise_tcl_error('%s\n%s' % (_("Expected -origin or " + "-origin or " + "-origin
or " + "- origin 3.0,4.2."), str(e)) + ) + return 'fail' if 'factor' in args: factor = float(args['factor']) diff --git a/tclCommands/TclCommandSetActive.py b/tclCommands/TclCommandSetActive.py index 2c51b72c..5144289a 100644 --- a/tclCommands/TclCommandSetActive.py +++ b/tclCommands/TclCommandSetActive.py @@ -31,9 +31,9 @@ class TclCommandSetActive(TclCommand): help = { 'main': 'Sets an object as active.', 'args': collections.OrderedDict([ - ('name', 'Name of the Object.'), + ('name', 'Name of the FlatCAM object to be set as active (selected). Required.'), ]), - 'examples': [] + 'examples': ['set_active object_name'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandSetOrigin.py b/tclCommands/TclCommandSetOrigin.py index 52974dd2..895338e4 100644 --- a/tclCommands/TclCommandSetOrigin.py +++ b/tclCommands/TclCommandSetOrigin.py @@ -49,13 +49,15 @@ class TclCommandSetOrigin(TclCommand): # structured help for current command, args needs to be ordered help = { - 'main': "Will set the origin at the specified x,y location.", + 'main': "Will set the origin at the specified x,y location.\n" + "If it is called without arguments it will set origin at (0, 0)", 'args': collections.OrderedDict([ - ('loc', 'Location to offset all the selected objects. No spaces between x and y pair. Use like this: 2,3'), + ('loc', 'Location to offset all the selected objects. NO SPACES ALLOWED in X and Y pair.\n' + 'Use like this: 2,3'), ('auto', 'If set to True it will set the origin to the minimum x, y of the object selection bounding box.' '-auto=True is not correct but -auto 1 or -auto True is correct.') ]), - 'examples': ['set_origin 3,2', 'set_origin -auto 1'] + 'examples': ['set_origin 3,2', 'set_origin -auto 1', 'origin'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandSetSys.py b/tclCommands/TclCommandSetSys.py index 9d477e27..a8133317 100644 --- a/tclCommands/TclCommandSetSys.py +++ b/tclCommands/TclCommandSetSys.py @@ -32,10 +32,10 @@ class TclCommandSetSys(TclCommand): help = { 'main': "Sets the value of the system variable.", 'args': collections.OrderedDict([ - ('name', 'Name of the system variable.'), + ('name', 'Name of the system variable. Required.'), ('value', 'Value to set.') ]), - 'examples': [] + 'examples': ['set_sys global_gridx 1.0'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandSkew.py b/tclCommands/TclCommandSkew.py index 60902b10..28da6e1c 100644 --- a/tclCommands/TclCommandSkew.py +++ b/tclCommands/TclCommandSkew.py @@ -17,28 +17,27 @@ class TclCommandSkew(TclCommand): # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str), - ('angle_x', float), - ('angle_y', float) ]) # Dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value option_types = collections.OrderedDict([ - + ('x', float), + ('y', float) ]) # array of mandatory options for current Tcl command: required = {'name','outname'} - required = ['name', 'angle_x', 'angle_y'] + required = ['name'] # structured help for current command, args needs to be ordered help = { 'main': "Shear/Skew an object by angles along x and y dimensions. The reference point is the left corner of " "the bounding box of the object.", 'args': collections.OrderedDict([ - ('name', 'Name of the object to skew.'), - ('angle_x', 'Angle in degrees by which to skew on the X axis.'), - ('angle_y', 'Angle in degrees by which to skew on the Y axis.') + ('name', 'Name of the object (Gerber, Geometry or Excellon) to be deformed (skewed). Required.'), + ('x', 'Angle in degrees by which to skew on the X axis. If it is not used it will be assumed to be 0.0'), + ('y', 'Angle in degrees by which to skew on the Y axis. If it is not used it will be assumed to be 0.0') ]), - 'examples': ['skew my_geometry 10.2 3.5'] + 'examples': ['skew my_geometry -x 10.2 -y 3.5', 'skew my_geo -x 3.0'] } def execute(self, args, unnamed_args): @@ -50,8 +49,20 @@ class TclCommandSkew(TclCommand): """ name = args['name'] - angle_x = float(args['angle_x']) - angle_y = float(args['angle_y']) + + if 'x' in args: + angle_x = float(args['x']) + else: + angle_x = 0.0 + + if 'y' in args: + angle_y = float(args['y']) + else: + angle_y = 0.0 + + if angle_x == 0.0 and angle_y == 0.0: + # nothing to be done + return obj_to_skew = self.app.collection.get_by_name(name) xmin, ymin, xmax, ymax = obj_to_skew.bounds() diff --git a/tclCommands/TclCommandSubtractPoly.py b/tclCommands/TclCommandSubtractPoly.py index f5b08fd1..98c43c66 100644 --- a/tclCommands/TclCommandSubtractPoly.py +++ b/tclCommands/TclCommandSubtractPoly.py @@ -28,12 +28,14 @@ class TclCommandSubtractPoly(TclCommandSignaled): # structured help for current command, args needs to be ordered help = { - 'main': "Subtract polygon from the given Geometry object.", + 'main': "Subtract polygon from the given Geometry object. The coordinates are provided in X Y pairs.\n" + "If the number of coordinates is not even then the 'Incomplete coordinate' error is raised.\n" + "If last coordinates are not the same as the first ones, the polygon will be completed automatically.", 'args': collections.OrderedDict([ - ('name', 'Name of the Geometry object from which to subtract.'), + ('name', 'Name of the Geometry object from which to subtract. Required.'), ('x0 y0 x1 y1 x2 y2 ...', 'Points defining the polygon.') ]), - 'examples': [] + 'examples': ['subtract_poly my_geo 0 0 2 1 3 3 4 4 0 0'] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandSubtractRectangle.py b/tclCommands/TclCommandSubtractRectangle.py index 53f99bf6..2453c584 100644 --- a/tclCommands/TclCommandSubtractRectangle.py +++ b/tclCommands/TclCommandSubtractRectangle.py @@ -36,9 +36,10 @@ class TclCommandSubtractRectangle(TclCommandSignaled): # structured help for current command, args needs to be ordered help = { - 'main': "Subtract rectange from the given Geometry object.", + 'main': "Subtract a rectangle from the given Geometry object. The coordinates are provided in X Y pairs.\n" + "If the number of coordinates is not even then the 'Incomplete coordinates' error is raised.", 'args': collections.OrderedDict([ - ('name', 'Name of the Geometry object from which to subtract.'), + ('name', 'Name of the Geometry object from which to subtract. Required.'), ('x0 y0', 'Bottom left corner coordinates.'), ('x1 y1', 'Top right corner coordinates.') ]), diff --git a/tclCommands/TclCommandWriteGCode.py b/tclCommands/TclCommandWriteGCode.py index 7125706e..655f00cb 100644 --- a/tclCommands/TclCommandWriteGCode.py +++ b/tclCommands/TclCommandWriteGCode.py @@ -34,8 +34,8 @@ class TclCommandWriteGCode(TclCommandSignaled): help = { 'main': "Saves G-code of a CNC Job object to file.", 'args': collections.OrderedDict([ - ('name', 'Source CNC Job object.'), - ('filename', 'Output filename.'), + ('name', 'Source CNC Job object. Required.'), + ('filename', 'Output filename. Required.'), ('preamble', 'Text to append at the beginning.'), ('postamble', 'Text to append at the end.'), ('muted', 'It will not put errors in the Shell or status bar.') From c13721184c977eb70a5319f90fe224e82e2c445c Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 9 Apr 2020 04:36:41 +0300 Subject: [PATCH 161/209] - if FlatCAM is not run with Python version >= 3.5 it will exit. --- FlatCAM.py | 13 +++++++++++++ README.md | 4 ++++ 2 files changed, 17 insertions(+) diff --git a/FlatCAM.py b/FlatCAM.py index 33b2b7c7..cd961119 100644 --- a/FlatCAM.py +++ b/FlatCAM.py @@ -32,6 +32,19 @@ if __name__ == '__main__': # NOTE: Never talk to the GUI from threads! This is why I commented the above. freeze_support() + # Supported Python version is >= 3.5 + if sys.version_info.major >= 3: + if sys.version_info.minor >= 5: + pass + else: + print("FlatCAM BETA uses PYTHON 3. The version minimum is 3.5\n" + "Your Python version is: %s" % str(sys.version_info)) + os._exit(0) + else: + print("FlatCAM BETA uses PYTHON 3. The version minimum is 3.5\n" + "Your Python version is: %s" % str(sys.version_info)) + os._exit(0) + debug_trace() VisPyPatches.apply_patches() diff --git a/README.md b/README.md index 678a9953..b896f620 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +10.04.2020 + +- if FlatCAM is not run with Python version >= 3.5 it will exit. + 9.4.2020 - fixed the Tcl Command Delete to have an argument -f that will force deletion evading the popup (if the popup is enabled). The sme command without a name now will delete all objects From d80de538e3a69f5e8ef1dbe105a1aa0b75ebee12 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 9 Apr 2020 05:16:48 +0300 Subject: [PATCH 162/209] - modified all CTRL+ with Ctrl+ and all ALT+ with Alt+ and all SHIFT+ with Shift+. Fixed issue #387. --- README.md | 59 ++-- flatcamEditors/FlatCAMGeoEditor.py | 2 +- flatcamEditors/FlatCAMGrbEditor.py | 2 +- flatcamGUI/FlatCAMGUI.py | 188 ++++++------- flatcamTools/ToolAlignObjects.py | 2 +- flatcamTools/ToolCalculators.py | 2 +- flatcamTools/ToolCalibration.py | 2 +- flatcamTools/ToolCopperThieving.py | 2 +- flatcamTools/ToolCutOut.py | 2 +- flatcamTools/ToolDblSided.py | 4 +- flatcamTools/ToolDistance.py | 2 +- flatcamTools/ToolDistanceMin.py | 2 +- flatcamTools/ToolExtractDrills.py | 2 +- flatcamTools/ToolFiducials.py | 2 +- flatcamTools/ToolFilm.py | 2 +- flatcamTools/ToolNCC.py | 2 +- flatcamTools/ToolOptimal.py | 2 +- flatcamTools/ToolPDF.py | 2 +- flatcamTools/ToolPaint.py | 2 +- flatcamTools/ToolPanelize.py | 2 +- flatcamTools/ToolPunchGerber.py | 2 +- flatcamTools/ToolQRCode.py | 2 +- flatcamTools/ToolRulesCheck.py | 2 +- flatcamTools/ToolSolderPaste.py | 2 +- flatcamTools/ToolSub.py | 2 +- flatcamTools/ToolTransform.py | 2 +- locale/de/LC_MESSAGES/strings.po | 286 ++++++++++---------- locale/en/LC_MESSAGES/strings.po | 404 ++++++++++++++-------------- locale/es/LC_MESSAGES/strings.po | 114 ++++---- locale/fr/LC_MESSAGES/strings.po | 110 ++++---- locale/it/LC_MESSAGES/strings.po | 64 ++--- locale/pt_BR/LC_MESSAGES/strings.po | 300 ++++++++++----------- locale/ro/LC_MESSAGES/strings.po | 338 +++++++++++------------ locale/ru/LC_MESSAGES/strings.po | 300 ++++++++++----------- locale_template/strings.pot | 56 ++-- 35 files changed, 1135 insertions(+), 1134 deletions(-) diff --git a/README.md b/README.md index b896f620..1aeb53f8 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 10.04.2020 - if FlatCAM is not run with Python version >= 3.5 it will exit. +- modified all CTRL+ with Ctrl+ and all ALT+ with Alt+ and all SHIFT+ with Shift+. Fixed issue #387. 9.4.2020 @@ -306,8 +307,8 @@ CAD program, and create G-Code for Isolation routing. 15.01.2020 -- added key shortcuts and toolbar icons for the new tools: Align Object Tool (ALT+A) and Extract Drills (ALT+I) -- added new functionality (key shortcut SHIFT+J) to locate the corners of the bounding box (and center) in a selected object +- added key shortcuts and toolbar icons for the new tools: Align Object Tool (Alt+A) and Extract Drills (Alt+I) +- added new functionality (key shortcut Shift+J) to locate the corners of the bounding box (and center) in a selected object - modified the NCC Tool GUI to prepare for accepting a tool from a tool database - started to modify the Paint Tool to be similar to NCC Tool and to accept a tool from a database - work in Paint Tool GUI functionality @@ -403,7 +404,7 @@ CAD program, and create G-Code for Isolation routing. - the Apply button text in Preferences is now made red when changes were made and require to be applied - the Gerber UI is built only once now so the process is lighter on CPU - the Gerber apertures marking shapes storage is now built only once because the more are built the more sluggish is the interface -- added a new function called by shortcut key combo CTRL+G when the current widget in Plot Area is an Code Editor. It will jump to the specified line in the text. +- added a new function called by shortcut key combo Ctrl+G when the current widget in Plot Area is an Code Editor. It will jump to the specified line in the text. - fixed a small bug where the app tried to hide a label that I've removed previously - in Paint Tool Preferences is allowed to add a list of initial tools separated by comma - in Geometry Paint Tool fixed the Overlap rate to work between 0 and 99.9999% @@ -505,7 +506,7 @@ CAD program, and create G-Code for Isolation routing. - added Preferences values for PDF margins when saving text in Code Editor as PDF - when clicking Cancel in Preferences now the values are reverted to what they used to be before opening Preferences tab and start changing values - starting to work to a general Print function; for now it will generate PDF files; currently it works only for one object not for a selection -- added shortcut key CTRL+P for printing to PDF method +- added shortcut key Ctrl+P for printing to PDF method 18.12.2019 @@ -681,7 +682,7 @@ CAD program, and create G-Code for Isolation routing. 3.12.2019 -- in Preferences added an Apply button which apply the modified preferences but does not save to a file, minimizing the file IO operations; CTRL+S key combo does the Apply now. +- in Preferences added an Apply button which apply the modified preferences but does not save to a file, minimizing the file IO operations; Ctrl+S key combo does the Apply now. - updated some of the default values to metric, values that were missed previously - remade the Gerber Editor way to import an Gerber object into the editor in such a way to use the multiprocessing - various small fixes @@ -809,7 +810,7 @@ CAD program, and create G-Code for Isolation routing. 11.11.2019 -- in Tools Database added a contextual menu to add/copy/delete tool; CTRL+C, DEL keys work too; key T for adding a tool is now only partially working +- in Tools Database added a contextual menu to add/copy/delete tool; Ctrl+C, DEL keys work too; key T for adding a tool is now only partially working - in Tools Database made the status bar messages show when adding/copying/deleting tools in DB - changed all Except statements that were single to except Exception as recommended in some PEP - renamed the Copper Fill Tool to Copper Thieving Tool as this is a more appropriate name; started to add ability for more types of copper thieving besides solid @@ -900,7 +901,7 @@ CAD program, and create G-Code for Isolation routing. - QRCode Tool: added ability to save the generated QRCode as SVG file or PNG file - QRCode Tool: added the feature to save the PNG file with transparent background - QRCode Tool: added GUI category in Preferences window -- QRCode Tool: shortcut key for this tool is now ALT+Q while PDF import Tool was relegated to CTRL+Q combo key shortcut +- QRCode Tool: shortcut key for this tool is now Alt+Q while PDF import Tool was relegated to Ctrl+Q combo key shortcut - added a new FlatCAM Tool: Copper Fill Tool. It will pour copper into a Gerber filling all empty space with copper, at a clearance distance of the Gerber features - Copper Fill Tool: added possibility to select between a bounding box rectangular or convex hull when the reference is the geometry of the source Gerber object - Copper Fill Tool: cleanup on not regular tool exit @@ -998,7 +999,7 @@ CAD program, and create G-Code for Isolation routing. - fixed a bug in the Merge functions - fixed the Export PNG function when using the 2D legacy graphic engine -- added a new capability to toggle the grid lines for both graphic engines: menu link in View and key shortcut combo ALT+G +- added a new capability to toggle the grid lines for both graphic engines: menu link in View and key shortcut combo Alt+G - changed the grid colors for 3D graphic engine when in Dark mode - enhanced the Tool Film adding the Film adjustments and added the GUI in Preferences - set the GUI layout in Preferences for a new category named Tools 2 @@ -1843,7 +1844,7 @@ CAD program, and create G-Code for Isolation routing. - fixed a possible issue in Gerber Object class - added a new tool in Gerber Editor: Mark Area Tool. It will mark the polygons in a edited Gerber object with areas within a defined range, allowing to delete some of the not necessary copper features - added new menu links in the Gerber Editor menu for Eraser Tool and Mark Area Tool -- added key shortcuts for Eraser Tool (CTRL+E) and Mark Area Tool (ALT+A) and updated the shortcuts list +- added key shortcuts for Eraser Tool (Ctrl+E) and Mark Area Tool (Alt+A) and updated the shortcuts list 9.07.2019 @@ -2223,7 +2224,7 @@ CAD program, and create G-Code for Isolation routing. - fixed the PDF import tool to work with files generated by the Microsoft PDF printer (chained subpaths) - in PDF import tool added support for paths filled and at the same time stroked ('B' and 'B*'commands) -- added a shortcut key for PDF Import Tool (ALT+Q) and updated the Shortcut list (also with the 'T' and 'R' keys for Gerber Editor where they control the bend in Track and Region tool and the 'M' and 'D' keys for Add Arc tool in Geometry Editor) +- added a shortcut key for PDF Import Tool (Alt+Q) and updated the Shortcut list (also with the 'T' and 'R' keys for Gerber Editor where they control the bend in Track and Region tool and the 'M' and 'D' keys for Add Arc tool in Geometry Editor) 20.04.2019 @@ -2268,7 +2269,7 @@ CAD program, and create G-Code for Isolation routing. - Excellon Editor: update so always there is a tool selected even after the Excellon object was just edited; before it always required a click inside of the tool table, not you do it only if needed. - fixed the menu File -> Edit -> Edit/Close Editor entry to reflect the status of the app (Editor active or not) - added support in Excellon parser for autodetection of Excellon file format for the Excellon files generated by the following ECAD sw: DipTrace, Eagle, Altium, Sprint Layout -- Gerber Editor: finished a new tool: Poligonize Tool (ALT+N in Editor). It will fuse a selection of tracks into a polygon. It will fill a selection of polygons if they are apart and it will make a single polygon if the selection is overlapped. All the newly created filled polygons will be stored in aperture '0' (if it does not exist it will be automatically created) +- Gerber Editor: finished a new tool: Poligonize Tool (Alt+N in Editor). It will fuse a selection of tracks into a polygon. It will fill a selection of polygons if they are apart and it will make a single polygon if the selection is overlapped. All the newly created filled polygons will be stored in aperture '0' (if it does not exist it will be automatically created) - fixed a bug in Move command in context menu who crashed the app when triggered - Gerber Editor: when adding a new aperture it will be store as the last selected and it will be used for any tools that are triggered until a new aperture is selected. @@ -2460,7 +2461,7 @@ CAD program, and create G-Code for Isolation routing. - added ability to create new scripts and open scripts in FlatCAM Script Editor - the Code Editor tab name is changed according to the task; 'save' and 'open' buttons will have filters installed for the QOpenDialog fit to the task - added ability to run a FlatCAM Tcl script by double-clicking on the file -- in Code Editor added shortcut combo key CTRL+SHIFT+V to function as a Special Paste that will replace the '\' char with '/' so the Windows paths will be pasted correctly for TCL Shell. Also doing SHIFT + LMB on the Paste in contextual menu is doing the same. +- in Code Editor added shortcut combo key Ctrl+Shift+V to function as a Special Paste that will replace the '\' char with '/' so the Windows paths will be pasted correctly for TCL Shell. Also doing SHIFT + LMB on the Paste in contextual menu is doing the same. 17.03.2019 @@ -2692,7 +2693,7 @@ CAD program, and create G-Code for Isolation routing. - added support for FlatCAM usage with High DPI monitors (4k). It is applied on the next app startup after change in Preferences -> General -> Gui Settings -> HDPI Support Checkbox - made the app not remember the window size if the app is maximized and remember in QSettings if it was maximized. This way we can restore the maximized state but restore the windows size unmaximized - added a button to clear the GUI preferences in Preferences -> General -> Gui Settings -> Clear GUI Settings -- added key shortcuts for the shape transformations within Geometry Editor: X, Y keys for Flip(mirror), SHIFT+X, SHIFT+Y combo keys for Skew and ALT+X, ALT+Y combo keys for Offset +- added key shortcuts for the shape transformations within Geometry Editor: X, Y keys for Flip(mirror), Shift+X, Shift+Y combo keys for Skew and Alt+X, Alt+Y combo keys for Offset - adjusted the plotcanvas.zomm_fit() function so the objects are better fit into view (with a border around) - modified the GUI in Objects Selected Tab to accommodate 2 different modes: basic and Advanced. In Basic mode, some of the functionality's are hidden from the user. - added Tool Transform preferences in Edit -> Preferences and used them through out the app @@ -2811,7 +2812,7 @@ CAD program, and create G-Code for Isolation routing. - in Excellon Editor added a protection for Tool_dia field in case numbers using comma as decimal separator are used. Also added a QDoubleValidator forcing a number with max 4 decimals and from 0.0000 to 9.9999 - in Excellon Editor added a shortcut key 'T' that popup a window allowing to enter a new Tool with the set diameter - in App added a shortcut key 'T' that popup a windows allowing to enter a new Tool with set diameter only when the Selected tab is on focus and only if a Geometry object is selected -- changed the shortcut key for Transform Tool from 'T' to 'ALT+T' +- changed the shortcut key for Transform Tool from 'T' to 'Alt+T' - fixed bug in Geometry Selected tab that generated error when used tool offset was less than half of either total length or half of total width. Now the app signal the issue with a status bar message - added Double Validator for the Offset value so only float numbers can be entered. - in App added a shortcut key 'T' that popup a windows allowing to enter a new Tool with set diameter only when the Tool tab is on focus and only if a NCC Tool or Paint Area Tool object is installed in the Tool Tab @@ -2918,7 +2919,7 @@ CAD program, and create G-Code for Isolation routing. - updated the camlib.CNCJob.scale() function so now the GCode is scaled also (quite a HACK :( it will need to be replaced at some point)). Units change work now on the GCODE also. - added the bounds coordinates to the GCODE header - FlatCAM saves now to a file in self.data_path the toolbar positions and the position of TCL Shell -- Plot Area Tab view can now be toggled, added entry in View Menu and shortcut key CTRL+F10 +- Plot Area Tab view can now be toggled, added entry in View Menu and shortcut key Ctrl+F10 - All the tabs in the GUI right side are (Plot Are, Preferences etc) are now detachable to a separate windows which when closed it returns in the previous location in the toolbar. Those detached tabs can be also reattached by drag and drop. 30.01.2019 @@ -2965,7 +2966,7 @@ CAD program, and create G-Code for Isolation routing. - redesigned the messagebox that is showed when quiting ot creating a New Project: now it has an option ('Cancel') to abort the process returning to the app - added options for trace segmentation that can be useful for auto-levelling (code snippet from Lei Zheng from a rejected pull request on FlatCAM https://bitbucket.org/realthunder/ ) - added shortcut key 'L' for creating 'New Excellon' -- added shortcut key combo 'SHIFT+S' for Running a Script. +- added shortcut key combo 'Shift+S' for Running a Script. - modified GRBL_laser preprocessor file so it includes a Sxxxx command on the line with M03 (laser active) whenever a value is enter in the Spindlespeed entry field - remade the EDIT -> PREFERENCES window, the Excellon and Gerber sections. Created a new section named TOOLS @@ -3830,7 +3831,7 @@ also the Project tab). Replaced it with the Preferences Tab launched with Menu -> Edit -> Preferences - when FlatCAM is used under MacOS, multiple selection of shapes in Editor mode is done using SHIFT key instead of CTRL key due of MacOS interpreting -CTRL+LMB_click as a RMB click +Ctrl+LMB_click as a RMB click - when in Editor, clicking not on a shape, reset the index of selected shapes to zero - added a new Tab in the Plot Area named Gcode Editor. It allow the user to @@ -3889,7 +3890,7 @@ because the value has to be positive. This may have solved for some use cases the user complaints that on clearing the areas of copper there is still copper leftovers. -- added shortcut "SHIFT+G" to toggle the axis presence. Useful when one +- added shortcut "Shift+G" to toggle the axis presence. Useful when one wants to save a PNG file. - changed color of the grid from 'gray' to 'dimgray' @@ -3918,7 +3919,7 @@ in a intermediary state on canvas. - added selection shape drawing in Geometry Editor preserving the current behavior: click to select, click on canvas clear selection, -CTRL+click add to selection new shape but remove from selection +Ctrl+click add to selection new shape but remove from selection if already selected. Drag LMB from left to right select enclosed shapes, drag LMB from right to left select touching shapes. Now the selection is made based on @@ -4019,7 +4020,7 @@ crash - remade the bounds() function to work with nested lists of objects as per advice from JP which made the operation less performance taxing. - added shortcut Shift+R that is complement to 'R' -- shorcuts 'R' and 'SHIFT+R' are working now in steps of 90 degrees +- shorcuts 'R' and 'Shift+R' are working now in steps of 90 degrees instead of previous 45 degrees. - added filters in the open ... FlatCAM projects are saved automatically as *.flat, the Gerber files have few categories. So the Excellons and @@ -4184,13 +4185,13 @@ Y Flip on Y_axis ~ Show Shortcut List Space: En(Dis)able Obj Plot -CTRL+A Select All -CTRL+C Copy Obj -CTRL+E Open Excellon File -CTRL+G Open Gerber File -CTRL+M Measurement Tool -CTRL+O Open Project -CTRL+S Save Project As +Ctrl+A Select All +Ctrl+C Copy Obj +Ctrl+E Open Excellon File +Ctrl+G Open Gerber File +Ctrl+M Measurement Tool +Ctrl+O Open Project +Ctrl+S Save Project As Delete Delete Obj''' @@ -4255,8 +4256,8 @@ promises and raise an Tcl error if there are any. Actually I reversed them to reflect reality. - for the rotate command a positive angle now rotates CW. It was reversed. - added shortcuts (for outside CANVAS; the CANVAS has it's own set of shortcuts) -CTRL+C will copy to clipboard the name of the selected object -CTRL+A will Select All objects +Ctrl+C will copy to clipboard the name of the selected object +Ctrl+A will Select All objects "X" key will flip the selected objects on X axis diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index 9d6be36b..74dd0892 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -992,7 +992,7 @@ class TransformEditorTool(FlatCAMTool): self.app.ui.notebook.setTabText(2, _("Transform Tool")) def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+T', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Alt+T', **kwargs) def set_tool_ui(self): # Initialize form diff --git a/flatcamEditors/FlatCAMGrbEditor.py b/flatcamEditors/FlatCAMGrbEditor.py index b655656b..f72f7c39 100644 --- a/flatcamEditors/FlatCAMGrbEditor.py +++ b/flatcamEditors/FlatCAMGrbEditor.py @@ -5538,7 +5538,7 @@ class TransformEditorTool(FlatCAMTool): self.app.ui.notebook.setTabText(2, _("Transform Tool")) def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+T', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Alt+T', **kwargs) def set_tool_ui(self): # Initialize form diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index 27c80913..09bdb939 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -68,7 +68,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # New Project self.menufilenewproject = QtWidgets.QAction(QtGui.QIcon(self.app.resource_location + '/file16.png'), - _('&New Project ...\tCTRL+N'), self) + _('&New Project ...\tCtrl+N'), self) self.menufilenewproject.setToolTip( _("Will create a new, blank project") ) @@ -113,12 +113,12 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # Open Gerber ... self.menufileopengerber = QtWidgets.QAction(QtGui.QIcon(self.app.resource_location + '/flatcam_icon24.png'), - _('Open &Gerber ...\tCTRL+G'), self) + _('Open &Gerber ...\tCtrl+G'), self) self.menufile_open.addAction(self.menufileopengerber) # Open Excellon ... self.menufileopenexcellon = QtWidgets.QAction(QtGui.QIcon(self.app.resource_location + '/open_excellon32.png'), - _('Open &Excellon ...\tCTRL+E'), self) + _('Open &Excellon ...\tCtrl+E'), self) self.menufile_open.addAction(self.menufileopenexcellon) # Open G-Code ... @@ -152,7 +152,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.menufileopenscript = QtWidgets.QAction( QtGui.QIcon(self.app.resource_location + '/open_script32.png'), _('Open Script ...'), self) self.menufilerunscript = QtWidgets.QAction( - QtGui.QIcon(self.app.resource_location + '/script16.png'), '%s\tSHIFT+S' % _('Run Script ...'), self) + QtGui.QIcon(self.app.resource_location + '/script16.png'), '%s\tShift+S' % _('Run Script ...'), self) self.menufilerunscript.setToolTip( _("Will run the opened Tcl Script thus\n" "enabling the automation of certain\n" @@ -262,7 +262,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # Separator self.menufile.addSeparator() self.menufile_print = QtWidgets.QAction( - QtGui.QIcon(self.app.resource_location + '/printer32.png'), '%s\tCTRL+P' % _('Print (PDF)')) + QtGui.QIcon(self.app.resource_location + '/printer32.png'), '%s\tCtrl+P' % _('Print (PDF)')) self.menufile.addAction(self.menufile_print) self.menufile_save = self.menufile.addMenu(QtGui.QIcon(self.app.resource_location + '/save_as.png'), _('Save')) @@ -274,7 +274,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # Save Project As ... self.menufilesaveprojectas = QtWidgets.QAction( - QtGui.QIcon(self.app.resource_location + '/save_as.png'), _('Save Project &As ...\tCTRL+S'), self) + QtGui.QIcon(self.app.resource_location + '/save_as.png'), _('Save Project &As ...\tCtrl+S'), self) self.menufile_save.addAction(self.menufilesaveprojectas) # Save Project Copy ... @@ -303,7 +303,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.menueditedit = self.menuedit.addAction( QtGui.QIcon(self.app.resource_location + '/edit16.png'), _('Edit Object\tE')) self.menueditok = self.menuedit.addAction( - QtGui.QIcon(self.app.resource_location + '/edit_ok16.png'), _('Close Editor\tCTRL+S')) + QtGui.QIcon(self.app.resource_location + '/edit_ok16.png'), _('Close Editor\tCtrl+S')) # adjust the initial state of the menu entries related to the editor self.menueditedit.setDisabled(False) @@ -359,7 +359,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # Separator self.menuedit.addSeparator() self.menueditcopyobject = self.menuedit.addAction( - QtGui.QIcon(self.app.resource_location + '/copy.png'), _('&Copy\tCTRL+C')) + QtGui.QIcon(self.app.resource_location + '/copy.png'), _('&Copy\tCtrl+C')) # Separator self.menuedit.addSeparator() @@ -371,24 +371,24 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.menueditorigin = self.menuedit.addAction( QtGui.QIcon(self.app.resource_location + '/origin16.png'), _('Se&t Origin\tO')) self.menuedit_move2origin = self.menuedit.addAction( - QtGui.QIcon(self.app.resource_location + '/origin2_16.png'), _('Move to Origin\tSHIFT+O')) + QtGui.QIcon(self.app.resource_location + '/origin2_16.png'), _('Move to Origin\tShift+O')) self.menueditjump = self.menuedit.addAction( QtGui.QIcon(self.app.resource_location + '/jump_to16.png'), _('Jump to Location\tJ')) self.menueditlocate = self.menuedit.addAction( - QtGui.QIcon(self.app.resource_location + '/locate16.png'), _('Locate in Object\tSHIFT+J')) + QtGui.QIcon(self.app.resource_location + '/locate16.png'), _('Locate in Object\tShift+J')) # Separator self.menuedit.addSeparator() self.menuedittoggleunits = self.menuedit.addAction( QtGui.QIcon(self.app.resource_location + '/toggle_units16.png'), _('Toggle Units\tQ')) self.menueditselectall = self.menuedit.addAction( - QtGui.QIcon(self.app.resource_location + '/select_all.png'), _('&Select All\tCTRL+A')) + QtGui.QIcon(self.app.resource_location + '/select_all.png'), _('&Select All\tCtrl+A')) # Separator self.menuedit.addSeparator() self.menueditpreferences = self.menuedit.addAction( - QtGui.QIcon(self.app.resource_location + '/pref.png'), _('&Preferences\tSHIFT+P')) + QtGui.QIcon(self.app.resource_location + '/pref.png'), _('&Preferences\tShift+P')) # ######################################################################## # ########################## OPTIONS # ################################### @@ -396,14 +396,14 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.menuoptions = self.menu.addMenu(_('Options')) self.menuoptions_transform_rotate = self.menuoptions.addAction( - QtGui.QIcon(self.app.resource_location + '/rotate.png'), _("&Rotate Selection\tSHIFT+(R)")) + QtGui.QIcon(self.app.resource_location + '/rotate.png'), _("&Rotate Selection\tShift+(R)")) # Separator self.menuoptions.addSeparator() self.menuoptions_transform_skewx = self.menuoptions.addAction( - QtGui.QIcon(self.app.resource_location + '/skewX.png'), _("&Skew on X axis\tSHIFT+X")) + QtGui.QIcon(self.app.resource_location + '/skewX.png'), _("&Skew on X axis\tShift+X")) self.menuoptions_transform_skewy = self.menuoptions.addAction( - QtGui.QIcon(self.app.resource_location + '/skewY.png'), _("S&kew on Y axis\tSHIFT+Y")) + QtGui.QIcon(self.app.resource_location + '/skewY.png'), _("S&kew on Y axis\tShift+Y")) # Separator self.menuoptions.addSeparator() @@ -415,9 +415,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.menuoptions.addSeparator() self.menuoptions_view_source = self.menuoptions.addAction( - QtGui.QIcon(self.app.resource_location + '/source32.png'), _("View source\tALT+S")) + QtGui.QIcon(self.app.resource_location + '/source32.png'), _("View source\tAlt+S")) self.menuoptions_tools_db = self.menuoptions.addAction( - QtGui.QIcon(self.app.resource_location + '/database32.png'), _("Tools DataBase\tCTRL+D")) + QtGui.QIcon(self.app.resource_location + '/database32.png'), _("Tools DataBase\tCtrl+D")) # Separator self.menuoptions.addSeparator() @@ -426,11 +426,11 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # ######################################################################## self.menuview = self.menu.addMenu(_('View')) self.menuviewenable = self.menuview.addAction( - QtGui.QIcon(self.app.resource_location + '/replot16.png'), _('Enable all plots\tALT+1')) + QtGui.QIcon(self.app.resource_location + '/replot16.png'), _('Enable all plots\tAlt+1')) self.menuviewdisableall = self.menuview.addAction( - QtGui.QIcon(self.app.resource_location + '/clear_plot16.png'), _('Disable all plots\tALT+2')) + QtGui.QIcon(self.app.resource_location + '/clear_plot16.png'), _('Disable all plots\tAlt+2')) self.menuviewdisableother = self.menuview.addAction( - QtGui.QIcon(self.app.resource_location + '/clear_plot16.png'), _('Disable non-selected\tALT+3')) + QtGui.QIcon(self.app.resource_location + '/clear_plot16.png'), _('Disable non-selected\tAlt+3')) # Separator self.menuview.addSeparator() self.menuview_zoom_fit = self.menuview.addAction( @@ -447,12 +447,12 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.menuview.addSeparator() self.menuview_toggle_code_editor = self.menuview.addAction( - QtGui.QIcon(self.app.resource_location + '/code_editor32.png'), _('Toggle Code Editor\tSHIFT+E')) + QtGui.QIcon(self.app.resource_location + '/code_editor32.png'), _('Toggle Code Editor\tShift+E')) self.menuview.addSeparator() self.menuview_toggle_fscreen = self.menuview.addAction( - QtGui.QIcon(self.app.resource_location + '/fscreen32.png'), _("&Toggle FullScreen\tALT+F10")) + QtGui.QIcon(self.app.resource_location + '/fscreen32.png'), _("&Toggle FullScreen\tAlt+F10")) self.menuview_toggle_parea = self.menuview.addAction( - QtGui.QIcon(self.app.resource_location + '/plot32.png'), _("&Toggle Plot Area\tCTRL+F10")) + QtGui.QIcon(self.app.resource_location + '/plot32.png'), _("&Toggle Plot Area\tCtrl+F10")) self.menuview_toggle_notebook = self.menuview.addAction( QtGui.QIcon(self.app.resource_location + '/notebook32.png'), _("&Toggle Project/Sel/Tool\t`")) @@ -460,11 +460,11 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.menuview_toggle_grid = self.menuview.addAction( QtGui.QIcon(self.app.resource_location + '/grid32.png'), _("&Toggle Grid Snap\tG")) self.menuview_toggle_grid_lines = self.menuview.addAction( - QtGui.QIcon(self.app.resource_location + '/grid32.png'), _("&Toggle Grid Lines\tALT+G")) + QtGui.QIcon(self.app.resource_location + '/grid32.png'), _("&Toggle Grid Lines\tAlt+G")) self.menuview_toggle_axis = self.menuview.addAction( - QtGui.QIcon(self.app.resource_location + '/axis32.png'), _("&Toggle Axis\tSHIFT+G")) + QtGui.QIcon(self.app.resource_location + '/axis32.png'), _("&Toggle Axis\tShift+G")) self.menuview_toggle_workspace = self.menuview.addAction( - QtGui.QIcon(self.app.resource_location + '/workspace24.png'), _("Toggle Workspace\tSHIFT+W")) + QtGui.QIcon(self.app.resource_location + '/workspace24.png'), _("Toggle Workspace\tShift+W")) # ######################################################################## # ########################## Objects # ################################### @@ -566,7 +566,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): QtGui.QIcon(self.app.resource_location + '/paint16.png'), _("Paint Tool\tI") ) self.geo_transform_menuitem = self.geo_editor_menu.addAction( - QtGui.QIcon(self.app.resource_location + '/transform.png'), _("Transform Tool\tALT+R") + QtGui.QIcon(self.app.resource_location + '/transform.png'), _("Transform Tool\tAlt+R") ) self.geo_editor_menu.addSeparator() self.geo_cornersnap_menuitem = self.geo_editor_menu.addAction( @@ -621,7 +621,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.grb_editor_menu.addSeparator() self.grb_convert_poly_menuitem = self.grb_editor_menu.addAction( - QtGui.QIcon(self.app.resource_location + '/poligonize32.png'), _("Poligonize\tALT+N")) + QtGui.QIcon(self.app.resource_location + '/poligonize32.png'), _("Poligonize\tAlt+N")) self.grb_add_semidisc_menuitem = self.grb_editor_menu.addAction( QtGui.QIcon(self.app.resource_location + '/semidisc32.png'), _("Add SemiDisc\tE")) self.grb_add_disc_menuitem = self.grb_editor_menu.addAction( @@ -631,11 +631,11 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.grb_add_scale_menuitem = self.grb_editor_menu.addAction( QtGui.QIcon(self.app.resource_location + '/scale32.png'), _('Scale\tS')) self.grb_add_markarea_menuitem = self.grb_editor_menu.addAction( - QtGui.QIcon(self.app.resource_location + '/markarea32.png'), _('Mark Area\tALT+A')) + QtGui.QIcon(self.app.resource_location + '/markarea32.png'), _('Mark Area\tAlt+A')) self.grb_add_eraser_menuitem = self.grb_editor_menu.addAction( - QtGui.QIcon(self.app.resource_location + '/eraser26.png'), _('Eraser\tCTRL+E')) + QtGui.QIcon(self.app.resource_location + '/eraser26.png'), _('Eraser\tCtrl+E')) self.grb_transform_menuitem = self.grb_editor_menu.addAction( - QtGui.QIcon(self.app.resource_location + '/transform.png'), _("Transform\tALT+R")) + QtGui.QIcon(self.app.resource_location + '/transform.png'), _("Transform\tAlt+R")) self.grb_editor_menu.addSeparator() self.grb_copy_menuitem = self.grb_editor_menu.addAction( @@ -1449,51 +1449,51 @@ class FlatCAMGUI(QtWidgets.QMainWindow):   - CTRL+A + Ctrl+A  %s - CTRL+C + Ctrl+C  %s - CTRL+D + Ctrl+D  %s - CTRL+E + Ctrl+E  %s - CTRL+G + Ctrl+G  %s - CTRL+M + Ctrl+M  %s - CTRL+N + Ctrl+N  %s - CTRL+O + Ctrl+O  %s - CTRL+P + Ctrl+P  %s - CTRL+Q + Ctrl+Q  %s - CTRL+S + Ctrl+S  %s - CTRL+F10 + Ctrl+F10  %s @@ -1501,47 +1501,47 @@ class FlatCAMGUI(QtWidgets.QMainWindow):   - SHIFT+C + Shift+C  %s - SHIFT+E + Shift+E  %s - SHIFT+G + Shift+G  %s - SHIFT+J + Shift+J  %s - SHIFT+M + Shift+M  %s - SHIFT+P + Shift+P  %s - SHIFT+R + Shift+R  %s - SHIFT+S + Shift+S  %s - SHIFT+W + Shift+W  %s - SHIFT+X + Shift+X  %s - SHIFT+Y + Shift+Y  %s @@ -1549,83 +1549,83 @@ class FlatCAMGUI(QtWidgets.QMainWindow):   - ALT+A + Alt+A  %s - ALT+C + Alt+C  %s - ALT+D + Alt+D  %s - ALT+E + Alt+E  %s - ALT+H + Alt+H  %s - ALT+I + Alt+I  %s - ALT+J + Alt+J  %s - ALT+K + Alt+K  %s - ALT+L + Alt+L  %s - ALT+N + Alt+N  %s - ALT+O + Alt+O  %s - ALT+P + Alt+P  %s - ALT+Q + Alt+Q  %s - ALT+R + Alt+R  %s - ALT+S + Alt+S  %s - ALT+U + Alt+U  %s - ALT+1 + Alt+1  %s - ALT+2 + Alt+2  %s - ALT+3 + Alt+3  %s - ALT+F10 + Alt+F10  %s @@ -1633,7 +1633,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):   - CTRL+ALT+X + Ctrl+Alt+X  %s @@ -1813,15 +1813,15 @@ class FlatCAMGUI(QtWidgets.QMainWindow):   - SHIFT+M + Shift+M  %s - SHIFT+X + Shift+X  %s - SHIFT+Y + Shift+Y  %s @@ -1829,15 +1829,15 @@ class FlatCAMGUI(QtWidgets.QMainWindow):   - ALT+R + Alt+R  %s - ALT+X + Alt+X  %s - ALT+Y + Alt+Y  %s @@ -1845,15 +1845,15 @@ class FlatCAMGUI(QtWidgets.QMainWindow):   - CTRL+M + Ctrl+M  %s - CTRL+S + Ctrl+S  %s - CTRL+X + Ctrl+X  %s @@ -1939,7 +1939,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):   - SHIFT+M + Shift+M  %s @@ -1963,7 +1963,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):  %s - CTRL+S + Ctrl+S  %s @@ -2055,7 +2055,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):   - SHIFT+M + Shift+M  %s @@ -2063,11 +2063,11 @@ class FlatCAMGUI(QtWidgets.QMainWindow):   - CTRL+E + Ctrl+E  %s - CTRL+S + Ctrl+S  %s @@ -2075,15 +2075,15 @@ class FlatCAMGUI(QtWidgets.QMainWindow):   - ALT+A + Alt+A  %s - ALT+N + Alt+N  %s - ALT+R + Alt+R  %s @@ -4308,12 +4308,12 @@ class FlatCAMSystemTray(QtWidgets.QSystemTrayIcon): # Open Gerber ... menu_opengerber = QtWidgets.QAction(QtGui.QIcon(self.app.resource_location + '/flatcam_icon24.png'), - _('Open &Gerber ...\tCTRL+G'), self) + _('Open &Gerber ...\tCtrl+G'), self) self.menu_open.addAction(menu_opengerber) # Open Excellon ... menu_openexcellon = QtWidgets.QAction(QtGui.QIcon(self.app.resource_location + '/open_excellon32.png'), - _('Open &Excellon ...\tCTRL+E'), self) + _('Open &Excellon ...\tCtrl+E'), self) self.menu_open.addAction(menu_openexcellon) # Open G-Code ... diff --git a/flatcamTools/ToolAlignObjects.py b/flatcamTools/ToolAlignObjects.py index 863f27c3..efb7e1b3 100644 --- a/flatcamTools/ToolAlignObjects.py +++ b/flatcamTools/ToolAlignObjects.py @@ -244,7 +244,7 @@ class AlignObjects(FlatCAMTool): self.app.ui.notebook.setTabText(2, _("Align Tool")) def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+A', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Alt+A', **kwargs) def set_tool_ui(self): self.reset_fields() diff --git a/flatcamTools/ToolCalculators.py b/flatcamTools/ToolCalculators.py index 086ab83e..5b57be84 100644 --- a/flatcamTools/ToolCalculators.py +++ b/flatcamTools/ToolCalculators.py @@ -299,7 +299,7 @@ class ToolCalculator(FlatCAMTool): self.app.ui.notebook.setTabText(2, _("Calc. Tool")) def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+C', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Alt+C', **kwargs) def set_tool_ui(self): self.units = self.app.defaults['units'].upper() diff --git a/flatcamTools/ToolCalibration.py b/flatcamTools/ToolCalibration.py index b2a879fe..e1e884aa 100644 --- a/flatcamTools/ToolCalibration.py +++ b/flatcamTools/ToolCalibration.py @@ -759,7 +759,7 @@ class ToolCalibration(FlatCAMTool): self.app.ui.notebook.setTabText(2, _("Calibration Tool")) def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+E', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Alt+E', **kwargs) def set_tool_ui(self): self.units = self.app.defaults['units'].upper() diff --git a/flatcamTools/ToolCopperThieving.py b/flatcamTools/ToolCopperThieving.py index 7000ca0e..9b1bc968 100644 --- a/flatcamTools/ToolCopperThieving.py +++ b/flatcamTools/ToolCopperThieving.py @@ -569,7 +569,7 @@ class ToolCopperThieving(FlatCAMTool): self.app.ui.notebook.setTabText(2, _("Copper Thieving Tool")) def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+F', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Alt+F', **kwargs) def set_tool_ui(self): self.units = self.app.defaults['units'] diff --git a/flatcamTools/ToolCutOut.py b/flatcamTools/ToolCutOut.py index 17663890..da366c0b 100644 --- a/flatcamTools/ToolCutOut.py +++ b/flatcamTools/ToolCutOut.py @@ -447,7 +447,7 @@ class CutOut(FlatCAMTool): self.app.ui.notebook.setTabText(2, _("Cutout Tool")) def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+X', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Alt+X', **kwargs) def set_tool_ui(self): self.reset_fields() diff --git a/flatcamTools/ToolDblSided.py b/flatcamTools/ToolDblSided.py index 29261cc5..50ca4632 100644 --- a/flatcamTools/ToolDblSided.py +++ b/flatcamTools/ToolDblSided.py @@ -428,7 +428,7 @@ class DblSidedTool(FlatCAMTool): "on one side of the alignment axis.\n\n" "The coordinates set can be obtained:\n" "- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" - "- press SHIFT key and left mouse clicking on canvas. Then CTRL+V in the field.\n" + "- press SHIFT key and left mouse clicking on canvas. Then Ctrl+V in the field.\n" "- press SHIFT key and left mouse clicking on canvas. Then RMB click in the field and click Paste.\n" "- by entering the coords manually in the format: (x1, y1), (x2, y2), ...") ) @@ -512,7 +512,7 @@ class DblSidedTool(FlatCAMTool): self.drill_values = "" def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+D', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Alt+D', **kwargs) def run(self, toggle=True): self.app.report_usage("Tool2Sided()") diff --git a/flatcamTools/ToolDistance.py b/flatcamTools/ToolDistance.py index 59f6f9d4..43bae37c 100644 --- a/flatcamTools/ToolDistance.py +++ b/flatcamTools/ToolDistance.py @@ -207,7 +207,7 @@ class Distance(FlatCAMTool): self.deactivate_measure_tool() def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='CTRL+M', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Ctrl+M', **kwargs) def set_tool_ui(self): # Remove anything else in the GUI diff --git a/flatcamTools/ToolDistanceMin.py b/flatcamTools/ToolDistanceMin.py index 485fca3b..1769f8aa 100644 --- a/flatcamTools/ToolDistanceMin.py +++ b/flatcamTools/ToolDistanceMin.py @@ -155,7 +155,7 @@ class DistanceMin(FlatCAMTool): _("Select two objects and no more, to measure the distance between them ...")) def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='SHIFT+M', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Shift+M', **kwargs) def set_tool_ui(self): # Remove anything else in the GUI diff --git a/flatcamTools/ToolExtractDrills.py b/flatcamTools/ToolExtractDrills.py index aa4a7adc..e3354978 100644 --- a/flatcamTools/ToolExtractDrills.py +++ b/flatcamTools/ToolExtractDrills.py @@ -363,7 +363,7 @@ class ToolExtractDrills(FlatCAMTool): ) def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+I', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Alt+I', **kwargs) def run(self, toggle=True): self.app.report_usage("Extract Drills()") diff --git a/flatcamTools/ToolFiducials.py b/flatcamTools/ToolFiducials.py index 4c9070e9..cfd3b71f 100644 --- a/flatcamTools/ToolFiducials.py +++ b/flatcamTools/ToolFiducials.py @@ -395,7 +395,7 @@ class ToolFiducials(FlatCAMTool): self.app.ui.notebook.setTabText(2, _("Fiducials Tool")) def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+J', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Alt+J', **kwargs) def set_tool_ui(self): self.units = self.app.defaults['units'] diff --git a/flatcamTools/ToolFilm.py b/flatcamTools/ToolFilm.py index 252cb0fb..4baae1a6 100644 --- a/flatcamTools/ToolFilm.py +++ b/flatcamTools/ToolFilm.py @@ -586,7 +586,7 @@ class Film(FlatCAMTool): self.app.ui.notebook.setTabText(2, _("Film Tool")) def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+L', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Alt+L', **kwargs) def set_tool_ui(self): self.reset_fields() diff --git a/flatcamTools/ToolNCC.py b/flatcamTools/ToolNCC.py index e2e5adfd..8fcaedf2 100644 --- a/flatcamTools/ToolNCC.py +++ b/flatcamTools/ToolNCC.py @@ -934,7 +934,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.app.inform.emit('[WARNING_NOTCL] %s...' % _("Adding Tool cancelled")) def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+N', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Alt+N', **kwargs) def run(self, toggle=True): self.app.report_usage("ToolNonCopperClear()") diff --git a/flatcamTools/ToolOptimal.py b/flatcamTools/ToolOptimal.py index 7dcbf121..f67d9941 100644 --- a/flatcamTools/ToolOptimal.py +++ b/flatcamTools/ToolOptimal.py @@ -278,7 +278,7 @@ class ToolOptimal(FlatCAMTool): self.reset_button.clicked.connect(self.set_tool_ui) def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+O', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Alt+O', **kwargs) def run(self, toggle=True): self.app.report_usage("ToolOptimal()") diff --git a/flatcamTools/ToolPDF.py b/flatcamTools/ToolPDF.py index e5db0001..9f91260f 100644 --- a/flatcamTools/ToolPDF.py +++ b/flatcamTools/ToolPDF.py @@ -135,7 +135,7 @@ class ToolPDF(FlatCAMTool): self.on_open_pdf_click() def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='CTRL+Q', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Ctrl+Q', **kwargs) def set_tool_ui(self): pass diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 9cf45655..842b6c56 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -705,7 +705,7 @@ class ToolPaint(FlatCAMTool, Gerber): }[self.reference_type_combo.get_value()] def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+P', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Alt+P', **kwargs) def run(self, toggle=True): self.app.report_usage("ToolPaint()") diff --git a/flatcamTools/ToolPanelize.py b/flatcamTools/ToolPanelize.py index 2cab2448..bbe57c18 100644 --- a/flatcamTools/ToolPanelize.py +++ b/flatcamTools/ToolPanelize.py @@ -322,7 +322,7 @@ class Panelize(FlatCAMTool): self.app.ui.notebook.setTabText(2, _("Panel. Tool")) def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+Z', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Alt+Z', **kwargs) def set_tool_ui(self): self.reset_fields() diff --git a/flatcamTools/ToolPunchGerber.py b/flatcamTools/ToolPunchGerber.py index 8c094dbf..2f984f5f 100644 --- a/flatcamTools/ToolPunchGerber.py +++ b/flatcamTools/ToolPunchGerber.py @@ -425,7 +425,7 @@ class ToolPunchGerber(FlatCAMTool): self.app.ui.notebook.setTabText(2, _("Punch Tool")) def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+H', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Alt+H', **kwargs) def set_tool_ui(self): self.reset_fields() diff --git a/flatcamTools/ToolQRCode.py b/flatcamTools/ToolQRCode.py index b71d477e..438349d3 100644 --- a/flatcamTools/ToolQRCode.py +++ b/flatcamTools/ToolQRCode.py @@ -382,7 +382,7 @@ class QRCode(FlatCAMTool): self.app.ui.notebook.setTabText(2, _("QRCode Tool")) def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+Q', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Alt+Q', **kwargs) def set_tool_ui(self): self.units = self.app.defaults['units'] diff --git a/flatcamTools/ToolRulesCheck.py b/flatcamTools/ToolRulesCheck.py index 9ee387fc..53f634c2 100644 --- a/flatcamTools/ToolRulesCheck.py +++ b/flatcamTools/ToolRulesCheck.py @@ -616,7 +616,7 @@ class RulesCheck(FlatCAMTool): self.app.ui.notebook.setTabText(2, _("Rules Tool")) def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+R', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Alt+R', **kwargs) def set_tool_ui(self): diff --git a/flatcamTools/ToolSolderPaste.py b/flatcamTools/ToolSolderPaste.py index 2dfd5d97..d42b39d6 100644 --- a/flatcamTools/ToolSolderPaste.py +++ b/flatcamTools/ToolSolderPaste.py @@ -552,7 +552,7 @@ class SolderPaste(FlatCAMTool): self.app.ui.notebook.setTabText(2, _("SolderPaste Tool")) def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+K', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Alt+K', **kwargs) def on_add_tool_by_key(self): tool_add_popup = FCInputDialog(title='%s...' % _("New Tool"), diff --git a/flatcamTools/ToolSub.py b/flatcamTools/ToolSub.py index 1471bd70..adf44dd7 100644 --- a/flatcamTools/ToolSub.py +++ b/flatcamTools/ToolSub.py @@ -233,7 +233,7 @@ class ToolSub(FlatCAMTool): self.reset_button.clicked.connect(self.set_tool_ui) def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+W', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Alt+W', **kwargs) def run(self, toggle=True): self.app.report_usage("ToolSub()") diff --git a/flatcamTools/ToolTransform.py b/flatcamTools/ToolTransform.py index 72955eee..69a1189b 100644 --- a/flatcamTools/ToolTransform.py +++ b/flatcamTools/ToolTransform.py @@ -463,7 +463,7 @@ class ToolTransform(FlatCAMTool): self.app.ui.notebook.setTabText(2, _("Transform Tool")) def install(self, icon=None, separator=None, **kwargs): - FlatCAMTool.install(self, icon, separator, shortcut='ALT+T', **kwargs) + FlatCAMTool.install(self, icon, separator, shortcut='Alt+T', **kwargs) def set_tool_ui(self): self.rotate_button.set_value(_("Rotate")) diff --git a/locale/de/LC_MESSAGES/strings.po b/locale/de/LC_MESSAGES/strings.po index 48cf9797..7341ac7f 100644 --- a/locale/de/LC_MESSAGES/strings.po +++ b/locale/de/LC_MESSAGES/strings.po @@ -5318,7 +5318,7 @@ msgid "File" msgstr "Datei" #: flatcamGUI/FlatCAMGUI.py:69 -msgid "&New Project ...\tCTRL+N" +msgid "&New Project ...\tCtrl+N" msgstr "&Neues Projekt ...\\STRG+N" #: flatcamGUI/FlatCAMGUI.py:71 @@ -5371,11 +5371,11 @@ msgid "Open &Project ..." msgstr "&Projekt öffnen..." #: flatcamGUI/FlatCAMGUI.py:109 flatcamGUI/FlatCAMGUI.py:4121 -msgid "Open &Gerber ...\tCTRL+G" +msgid "Open &Gerber ...\tCtrl+G" msgstr "&Gerber öffnen...\\STRG+G" #: flatcamGUI/FlatCAMGUI.py:114 flatcamGUI/FlatCAMGUI.py:4126 -msgid "Open &Excellon ...\tCTRL+E" +msgid "Open &Excellon ...\tCtrl+E" msgstr "&Excellon öffnen...\\STRG+E" #: flatcamGUI/FlatCAMGUI.py:118 flatcamGUI/FlatCAMGUI.py:4131 @@ -5527,7 +5527,7 @@ msgid "&Save Project ..." msgstr "Projekt speichern ..." #: flatcamGUI/FlatCAMGUI.py:256 -msgid "Save Project &As ...\tCTRL+S" +msgid "Save Project &As ...\tCtrl+S" msgstr "Projekt speichern als ...\\STRG+S" #: flatcamGUI/FlatCAMGUI.py:261 @@ -5548,7 +5548,7 @@ msgid "Edit Object\tE" msgstr "Objekt bearbeiten\tE" #: flatcamGUI/FlatCAMGUI.py:285 -msgid "Close Editor\tCTRL+S" +msgid "Close Editor\tCtrl+S" msgstr "Schließen Sie Editor\tSTRG+S" #: flatcamGUI/FlatCAMGUI.py:294 @@ -5626,7 +5626,7 @@ msgid "Convert Any to Gerber" msgstr "Konvertieren Sie Any zu Gerber" #: flatcamGUI/FlatCAMGUI.py:341 -msgid "&Copy\tCTRL+C" +msgid "&Copy\tCtrl+C" msgstr "Kopieren\tSTRG+C" #: flatcamGUI/FlatCAMGUI.py:346 @@ -5646,28 +5646,28 @@ msgid "Toggle Units\tQ" msgstr "Einheiten umschalten\tQ" #: flatcamGUI/FlatCAMGUI.py:360 -msgid "&Select All\tCTRL+A" +msgid "&Select All\tCtrl+A" msgstr "Alles auswählen\tSTRG+A" #: flatcamGUI/FlatCAMGUI.py:365 -msgid "&Preferences\tSHIFT+P" -msgstr "Einstellungen\tSHIFT+P" +msgid "&Preferences\tShift+P" +msgstr "Einstellungen\tShift+P" #: flatcamGUI/FlatCAMGUI.py:371 flatcamTools/ToolProperties.py:153 msgid "Options" msgstr "Optionen" #: flatcamGUI/FlatCAMGUI.py:373 -msgid "&Rotate Selection\tSHIFT+(R)" -msgstr "Auswahl drehen\tSHIFT+(R)" +msgid "&Rotate Selection\tShift+(R)" +msgstr "Auswahl drehen\tShift+(R)" #: flatcamGUI/FlatCAMGUI.py:378 -msgid "&Skew on X axis\tSHIFT+X" -msgstr "Neigung auf der X-Achse\tSHIFT+X" +msgid "&Skew on X axis\tShift+X" +msgstr "Neigung auf der X-Achse\tShift+X" #: flatcamGUI/FlatCAMGUI.py:380 -msgid "S&kew on Y axis\tSHIFT+Y" -msgstr "Neigung auf der Y-Achse\tSHIFT+Y" +msgid "S&kew on Y axis\tShift+Y" +msgstr "Neigung auf der Y-Achse\tShift+Y" #: flatcamGUI/FlatCAMGUI.py:385 msgid "Flip on &X axis\tX" @@ -5678,11 +5678,11 @@ msgid "Flip on &Y axis\tY" msgstr "Y-Achse kippen\tY" #: flatcamGUI/FlatCAMGUI.py:392 -msgid "View source\tALT+S" -msgstr "Quelltext anzeigen\tALT+S" +msgid "View source\tAlt+S" +msgstr "Quelltext anzeigen\tAlt+S" #: flatcamGUI/FlatCAMGUI.py:394 -msgid "Tools DataBase\tCTRL+D" +msgid "Tools DataBase\tCtrl+D" msgstr "Werkzeugdatenbank\tSTRG+D" #: flatcamGUI/FlatCAMGUI.py:401 flatcamGUI/FlatCAMGUI.py:2060 @@ -5690,16 +5690,16 @@ msgid "View" msgstr "Aussicht" #: flatcamGUI/FlatCAMGUI.py:403 -msgid "Enable all plots\tALT+1" -msgstr "Alle Diagramme aktivieren\tALT+1" +msgid "Enable all plots\tAlt+1" +msgstr "Alle Diagramme aktivieren\tAlt+1" #: flatcamGUI/FlatCAMGUI.py:405 -msgid "Disable all plots\tALT+2" -msgstr "Alle Diagramme deaktivieren\tALT+2" +msgid "Disable all plots\tAlt+2" +msgstr "Alle Diagramme deaktivieren\tAlt+2" #: flatcamGUI/FlatCAMGUI.py:407 -msgid "Disable non-selected\tALT+3" -msgstr "Nicht ausgewählte Diagramme deaktivieren\tALT+3" +msgid "Disable non-selected\tAlt+3" +msgstr "Nicht ausgewählte Diagramme deaktivieren\tAlt+3" #: flatcamGUI/FlatCAMGUI.py:411 msgid "&Zoom Fit\tV" @@ -5718,15 +5718,15 @@ msgid "Redraw All\tF5" msgstr "Alles neu zeichnen\tF5" #: flatcamGUI/FlatCAMGUI.py:424 -msgid "Toggle Code Editor\tSHIFT+E" -msgstr "Code-Editor umschalten\tSHIFT+E" +msgid "Toggle Code Editor\tShift+E" +msgstr "Code-Editor umschalten\tShift+E" #: flatcamGUI/FlatCAMGUI.py:427 -msgid "&Toggle FullScreen\tALT+F10" -msgstr "FullScreen umschalten\tALT+F10" +msgid "&Toggle FullScreen\tAlt+F10" +msgstr "FullScreen umschalten\tAlt+F10" #: flatcamGUI/FlatCAMGUI.py:429 -msgid "&Toggle Plot Area\tCTRL+F10" +msgid "&Toggle Plot Area\tCtrl+F10" msgstr "Plotbereich umschalten\tSTRG+F10" #: flatcamGUI/FlatCAMGUI.py:431 @@ -5738,16 +5738,16 @@ msgid "&Toggle Grid Snap\tG" msgstr "Schaltet den Rasterfang ein\tG" #: flatcamGUI/FlatCAMGUI.py:437 -msgid "&Toggle Grid Lines\tALT+G" -msgstr "Gitterlinien umschalten\tALT+G" +msgid "&Toggle Grid Lines\tAlt+G" +msgstr "Gitterlinien umschalten\tAlt+G" #: flatcamGUI/FlatCAMGUI.py:439 -msgid "&Toggle Axis\tSHIFT+G" -msgstr "Achse umschalten\tSHIFT+G" +msgid "&Toggle Axis\tShift+G" +msgstr "Achse umschalten\tShift+G" #: flatcamGUI/FlatCAMGUI.py:441 -msgid "Toggle Workspace\tSHIFT+W" -msgstr "Arbeitsbereich umschalten\tSHIFT+W" +msgid "Toggle Workspace\tShift+W" +msgstr "Arbeitsbereich umschalten\tShift+W" #: flatcamGUI/FlatCAMGUI.py:446 msgid "Objects" @@ -5846,8 +5846,8 @@ msgid "Paint Tool\tI" msgstr "Malenwerkzeug\tI" #: flatcamGUI/FlatCAMGUI.py:543 -msgid "Transform Tool\tALT+R" -msgstr "Transformationswerkzeug\tALT+R" +msgid "Transform Tool\tAlt+R" +msgstr "Transformationswerkzeug\tAlt+R" #: flatcamGUI/FlatCAMGUI.py:547 msgid "Toggle Corner Snap\tK" @@ -5910,8 +5910,8 @@ msgid "Add Region\tN" msgstr "Region hinzufügen\tN" #: flatcamGUI/FlatCAMGUI.py:598 -msgid "Poligonize\tALT+N" -msgstr "Polygonisieren\tALT+N" +msgid "Poligonize\tAlt+N" +msgstr "Polygonisieren\tAlt+N" #: flatcamGUI/FlatCAMGUI.py:600 msgid "Add SemiDisc\tE" @@ -5930,15 +5930,15 @@ msgid "Scale\tS" msgstr "Skalieren\tS" #: flatcamGUI/FlatCAMGUI.py:608 -msgid "Mark Area\tALT+A" -msgstr "Bereich markieren\tALT+A" +msgid "Mark Area\tAlt+A" +msgstr "Bereich markieren\tAlt+A" #: flatcamGUI/FlatCAMGUI.py:610 -msgid "Eraser\tCTRL+E" +msgid "Eraser\tCtrl+E" msgstr "Radiergummi\tSTRG+E" #: flatcamGUI/FlatCAMGUI.py:612 -msgid "Transform\tALT+R" +msgid "Transform\tAlt+R" msgstr "Transformationswerkzeug\tSTRG+R" #: flatcamGUI/FlatCAMGUI.py:639 @@ -14096,7 +14096,7 @@ msgid "" "\n" "The coordinates set can be obtained:\n" "- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" -"- press SHIFT key and left mouse clicking on canvas. Then CTRL+V in the " +"- press SHIFT key and left mouse clicking on canvas. Then Ctrl+V in the " "field.\n" "- press SHIFT key and left mouse clicking on canvas. Then RMB click in the " "field and click Paste.\n" @@ -17831,8 +17831,8 @@ msgstr "" #~ "> Verknüpfungsliste oder über eine eigene Tastenkombination: " #~ "F3.

\n" -#~ msgid "Run Script ...\tSHIFT+S" -#~ msgstr "Skript ausführen ...\tSHIFT+S" +#~ msgid "Run Script ...\tShift+S" +#~ msgstr "Skript ausführen ...\tShift+S" #~ msgid "" #~ "FlatCAM
Version {version} {beta} ({date}) - " @@ -18001,39 +18001,39 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+A\n" +#~ " Ctrl+A\n" #~ "  Select All\n" #~ " \n" #~ " \n" -#~ " CTRL+C\n" +#~ " Ctrl+C\n" #~ "  Copy Obj\n" #~ " \n" #~ " \n" -#~ " CTRL+E\n" +#~ " Ctrl+E\n" #~ "  Open Excellon File\n" #~ " \n" #~ " \n" -#~ " CTRL+G\n" +#~ " Ctrl+G\n" #~ "  Open Gerber File\n" #~ " \n" #~ " \n" -#~ " CTRL+N\n" +#~ " Ctrl+N\n" #~ "  New Project\n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Measurement Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+O\n" +#~ " Ctrl+O\n" #~ "  Open Project\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Project As\n" #~ " \n" #~ " \n" -#~ " CTRL+F10\n" +#~ " Ctrl+F10\n" #~ "  Toggle Plot Area\n" #~ " \n" #~ " \n" @@ -18041,39 +18041,39 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+C\n" +#~ " Shift+C\n" #~ "  Copy Obj_Name\n" #~ " \n" #~ " \n" -#~ " SHIFT+E\n" +#~ " Shift+E\n" #~ "  Toggle Code Editor\n" #~ " \n" #~ " \n" -#~ " SHIFT+G\n" +#~ " Shift+G\n" #~ "  Toggle the axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+P\n" +#~ " Shift+P\n" #~ "  Open Preferences Window\n" #~ " \n" #~ " \n" -#~ " SHIFT+R\n" +#~ " Shift+R\n" #~ "  Rotate by 90 degree CCW\n" #~ " \n" #~ " \n" -#~ " SHIFT+S\n" +#~ " Shift+S\n" #~ "  Run a Script\n" #~ " \n" #~ " \n" -#~ " SHIFT+W\n" +#~ " Shift+W\n" #~ "  Toggle the workspace\n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Skew on X axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Skew on Y axis\n" #~ " \n" #~ " \n" @@ -18081,59 +18081,59 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+C\n" +#~ " Alt+C\n" #~ "  Calculators Tool\n" #~ " \n" #~ " \n" -#~ " ALT+D\n" +#~ " Alt+D\n" #~ "  2-Sided PCB Tool\n" #~ " \n" #~ " \n" -#~ " ALT+K\n" +#~ " Alt+K\n" #~ "  Solder Paste Dispensing Tool\n" #~ " \n" #~ " \n" -#~ " ALT+L\n" +#~ " Alt+L\n" #~ "  Film PCB Tool\n" #~ " \n" #~ " \n" -#~ " ALT+N\n" +#~ " Alt+N\n" #~ "  Non-Copper Clearing Tool\n" #~ " \n" #~ " \n" -#~ " ALT+P\n" +#~ " Alt+P\n" #~ "  Paint Area Tool\n" #~ " \n" #~ " \n" -#~ " ALT+Q\n" +#~ " Alt+Q\n" #~ "  PDF Import Tool\n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Transformations Tool\n" #~ " \n" #~ " \n" -#~ " ALT+S\n" +#~ " Alt+S\n" #~ "  View File Source\n" #~ " \n" #~ " \n" -#~ " ALT+U\n" +#~ " Alt+U\n" #~ "  Cutout PCB Tool\n" #~ " \n" #~ " \n" -#~ " ALT+1\n" +#~ " Alt+1\n" #~ "  Enable all Plots\n" #~ " \n" #~ " \n" -#~ " ALT+2\n" +#~ " Alt+2\n" #~ "  Disable all Plots\n" #~ " \n" #~ " \n" -#~ " ALT+3\n" +#~ " Alt+3\n" #~ "  Disable Non-selected Plots\n" #~ " \n" #~ " \n" -#~ " ALT+F10\n" +#~ " Alt+F10\n" #~ "  Toggle Full Screen\n" #~ " \n" #~ " \n" @@ -18141,7 +18141,7 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+ALT+XCtrl+Alt+X\n" #~ "  Abort current task (gracefully)\n" #~ " \n" @@ -18339,40 +18339,40 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+C\n" +#~ " Shift+C\n" #~ "  Objektnamen kopieren\n" #~ " \n" #~ " \n" -#~ " SHIFT+E\n" +#~ " Shift+E\n" #~ "  Code-Editor umschalten\n" #~ " \n" #~ " \n" -#~ " SHIFT+G\n" +#~ " Shift+G\n" #~ "  Toggle the axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+P\n" +#~ " Shift+P\n" #~ "  Öffnen Sie das Einstellungsfenster\n" #~ " \n" #~ " \n" -#~ " SHIFT+R\n" +#~ " Shift+R\n" #~ "  Um 90 Grad nach links drehen\n" #~ " \n" #~ " \n" -#~ " SHIFT+S\n" +#~ " Shift+S\n" #~ "  Führen Sie ein Skript aus\n" #~ " \n" #~ " \n" -#~ " SHIFT+W\n" +#~ " Shift+W\n" #~ "  Arbeitsbereich umschalten\n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Neigung auf der X-Achse\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Neigung auf der Y-Achse\n" #~ " \n" #~ " \n" @@ -18380,60 +18380,60 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+C\n" +#~ " Alt+C\n" #~ "  Rechnerwerzeug\n" #~ " \n" #~ " \n" -#~ " ALT+D\n" +#~ " Alt+D\n" #~ "  2-seitiges PCBwerkzeug\n" #~ " \n" #~ " \n" -#~ " ALT+K\n" +#~ " Alt+K\n" #~ "  Lötpastenwerkzeug\n" #~ " \n" #~ " \n" -#~ " ALT+L\n" +#~ " Alt+L\n" #~ "  Film PCB Werkzeug\n" #~ " \n" #~ " \n" -#~ " ALT+N\n" +#~ " Alt+N\n" #~ "  Nicht-Kupfer löschen Werkzeug\n" #~ " \n" #~ " \n" -#~ " ALT+P\n" +#~ " Alt+P\n" #~ "  Paint Werkzeug\n" #~ " \n" #~ " \n" -#~ " ALT+Q\n" +#~ " Alt+Q\n" #~ "  PDF-Importwerkzeug\n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Transformationen\" Werkzeug\n" #~ " \n" #~ " \n" -#~ " ALT+S\n" +#~ " Alt+S\n" #~ "  Dateiquelle anzeigen\n" #~ " \n" #~ " \n" -#~ " ALT+U\n" +#~ " Alt+U\n" #~ "  PCB-Werkzeug ausschneiden\n" #~ " \n" #~ " \n" -#~ " ALT+1\n" +#~ " Alt+1\n" #~ "  Alle Plots aktivieren\n" #~ " \n" #~ " \n" -#~ " ALT+2\n" +#~ " Alt+2\n" #~ "  Deaktivieren Sie alle Plots\n" #~ " \n" #~ " \n" -#~ " ALT+3\n" +#~ " Alt+3\n" #~ "  Deaktivieren Sie nicht ausgewählte " #~ "Plots\n" #~ " \n" #~ " \n" -#~ " ALT+F10\n" +#~ " Alt+F10\n" #~ "  Vollbild umschalten\n" #~ " \n" #~ " \n" @@ -18441,7 +18441,7 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " STRG+ALT+XSTRG+Alt+X\n" #~ "  Aktuelle Aufgabe abbrechen " #~ "(ordnungsgemäß)\n" @@ -18579,11 +18579,11 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Skew shape on X axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Skew shape on Y axis\n" #~ " \n" #~ " \n" @@ -18591,15 +18591,15 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Editor Transformation Tool\n" #~ " \n" #~ " \n" -#~ " ALT+X\n" +#~ " Alt+X\n" #~ "  Offset shape on X axis\n" #~ " \n" #~ " \n" -#~ " ALT+Y\n" +#~ " Alt+Y\n" #~ "  Offset shape on Y axis\n" #~ " \n" #~ " \n" @@ -18607,15 +18607,15 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Measurement Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" -#~ " CTRL+X\n" +#~ " Ctrl+X\n" #~ "  Polygon Cut Tool\n" #~ " \n" #~ " \n" @@ -18707,7 +18707,7 @@ msgstr "" #~ "  Abort and return to Select\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" @@ -18795,11 +18795,11 @@ msgstr "" #~ "  Abort and return to Select\n" #~ " \n" #~ " \n" -#~ " CTRL+E\n" +#~ " Ctrl+E\n" #~ "  Eraser Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" @@ -18807,15 +18807,15 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+A\n" +#~ " Alt+A\n" #~ "  Mark Area Tool\n" #~ " \n" #~ " \n" -#~ " ALT+N\n" +#~ " Alt+N\n" #~ "  Poligonize Tool\n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Transformation Tool\n" #~ " \n" #~ " \n" @@ -18914,11 +18914,11 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Neigung auf der X-Achse\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Neigung auf der Y-Achse\n" #~ " \n" #~ " \n" @@ -18926,15 +18926,15 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Editor-Umwandlungstool\n" #~ " \n" #~ " \n" -#~ " ALT+X\n" +#~ " Alt+X\n" #~ "  Versatzform auf der X-Achse\n" #~ " \n" #~ " \n" -#~ " ALT+Y\n" +#~ " Alt+Y\n" #~ "  Versatzform auf der Y-Achse\n" #~ " \n" #~ " \n" @@ -19151,15 +19151,15 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+A\n" +#~ " Alt+A\n" #~ "  Bereichswerkzeug markieren\n" #~ " \n" #~ " \n" -#~ " ALT+N\n" +#~ " Alt+N\n" #~ "  Werkzeug \"Polygonisieren\"\n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Transformations Werkzeug\n" #~ " \n" #~ " \n" @@ -20271,11 +20271,11 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Skew shape on X axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Skew shape on Y axis\n" #~ " \n" #~ " \n" @@ -20283,15 +20283,15 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Editor Transformation Tool\n" #~ " \n" #~ " \n" -#~ " ALT+X\n" +#~ " Alt+X\n" #~ "  Offset shape on X axis\n" #~ " \n" #~ " \n" -#~ " ALT+Y\n" +#~ " Alt+Y\n" #~ "  Offset shape on Y axis\n" #~ " \n" #~ " \n" @@ -20299,15 +20299,15 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Measurement Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" -#~ " CTRL+X\n" +#~ " Ctrl+X\n" #~ "  Polygon Cut Tool\n" #~ " \n" #~ " \n" @@ -20389,7 +20389,7 @@ msgstr "" #~ "  Abort and return to Select\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" @@ -20478,11 +20478,11 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Skew shape on X axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Skew shape on Y axis\n" #~ " \n" #~ " \n" @@ -20490,15 +20490,15 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Editor Transformation Tool\n" #~ " \n" #~ " \n" -#~ " ALT+X\n" +#~ " Alt+X\n" #~ "  Offset shape on X axis\n" #~ " \n" #~ " \n" -#~ " ALT+Y\n" +#~ " Alt+Y\n" #~ "  Offset shape on Y axis\n" #~ " \n" #~ " \n" @@ -20506,15 +20506,15 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Measurement Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" -#~ " CTRL+X\n" +#~ " Ctrl+X\n" #~ "  Polygon Cut Tool\n" #~ " \n" #~ " \n" @@ -20596,7 +20596,7 @@ msgstr "" #~ "  Abort and return to Select\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" diff --git a/locale/en/LC_MESSAGES/strings.po b/locale/en/LC_MESSAGES/strings.po index f4300b66..ee2bf8a9 100644 --- a/locale/en/LC_MESSAGES/strings.po +++ b/locale/en/LC_MESSAGES/strings.po @@ -5159,8 +5159,8 @@ msgid "File" msgstr "File" #: flatcamGUI/FlatCAMGUI.py:69 -msgid "&New Project ...\tCTRL+N" -msgstr "&New Project ...\tCTRL+N" +msgid "&New Project ...\tCtrl+N" +msgstr "&New Project ...\tCtrl+N" #: flatcamGUI/FlatCAMGUI.py:71 msgid "Will create a new, blank project" @@ -5212,12 +5212,12 @@ msgid "Open &Project ..." msgstr "Open &Project ..." #: flatcamGUI/FlatCAMGUI.py:109 flatcamGUI/FlatCAMGUI.py:4121 -msgid "Open &Gerber ...\tCTRL+G" -msgstr "Open &Gerber ...\tCTRL+G" +msgid "Open &Gerber ...\tCtrl+G" +msgstr "Open &Gerber ...\tCtrl+G" #: flatcamGUI/FlatCAMGUI.py:114 flatcamGUI/FlatCAMGUI.py:4126 -msgid "Open &Excellon ...\tCTRL+E" -msgstr "Open &Excellon ...\tCTRL+E" +msgid "Open &Excellon ...\tCtrl+E" +msgstr "Open &Excellon ...\tCtrl+E" #: flatcamGUI/FlatCAMGUI.py:118 flatcamGUI/FlatCAMGUI.py:4131 msgid "Open G-&Code ..." @@ -5368,8 +5368,8 @@ msgid "&Save Project ..." msgstr "&Save Project ..." #: flatcamGUI/FlatCAMGUI.py:256 -msgid "Save Project &As ...\tCTRL+S" -msgstr "Save Project &As ...\tCTRL+S" +msgid "Save Project &As ...\tCtrl+S" +msgstr "Save Project &As ...\tCtrl+S" #: flatcamGUI/FlatCAMGUI.py:261 msgid "Save Project C&opy ..." @@ -5389,8 +5389,8 @@ msgid "Edit Object\tE" msgstr "Edit Object\tE" #: flatcamGUI/FlatCAMGUI.py:285 -msgid "Close Editor\tCTRL+S" -msgstr "Close Editor\tCTRL+S" +msgid "Close Editor\tCtrl+S" +msgstr "Close Editor\tCtrl+S" #: flatcamGUI/FlatCAMGUI.py:294 msgid "Conversion" @@ -5464,8 +5464,8 @@ msgid "Convert Any to Gerber" msgstr "Convert Any to Gerber" #: flatcamGUI/FlatCAMGUI.py:341 -msgid "&Copy\tCTRL+C" -msgstr "&Copy\tCTRL+C" +msgid "&Copy\tCtrl+C" +msgstr "&Copy\tCtrl+C" #: flatcamGUI/FlatCAMGUI.py:346 msgid "&Delete\tDEL" @@ -5484,28 +5484,28 @@ msgid "Toggle Units\tQ" msgstr "Toggle Units\tQ" #: flatcamGUI/FlatCAMGUI.py:360 -msgid "&Select All\tCTRL+A" -msgstr "&Select All\tCTRL+A" +msgid "&Select All\tCtrl+A" +msgstr "&Select All\tCtrl+A" #: flatcamGUI/FlatCAMGUI.py:365 -msgid "&Preferences\tSHIFT+P" -msgstr "&Preferences\tSHIFT+P" +msgid "&Preferences\tShift+P" +msgstr "&Preferences\tShift+P" #: flatcamGUI/FlatCAMGUI.py:371 flatcamTools/ToolProperties.py:153 msgid "Options" msgstr "Options" #: flatcamGUI/FlatCAMGUI.py:373 -msgid "&Rotate Selection\tSHIFT+(R)" -msgstr "&Rotate Selection\tSHIFT+(R)" +msgid "&Rotate Selection\tShift+(R)" +msgstr "&Rotate Selection\tShift+(R)" #: flatcamGUI/FlatCAMGUI.py:378 -msgid "&Skew on X axis\tSHIFT+X" -msgstr "&Skew on X axis\tSHIFT+X" +msgid "&Skew on X axis\tShift+X" +msgstr "&Skew on X axis\tShift+X" #: flatcamGUI/FlatCAMGUI.py:380 -msgid "S&kew on Y axis\tSHIFT+Y" -msgstr "S&kew on Y axis\tSHIFT+Y" +msgid "S&kew on Y axis\tShift+Y" +msgstr "S&kew on Y axis\tShift+Y" #: flatcamGUI/FlatCAMGUI.py:385 msgid "Flip on &X axis\tX" @@ -5516,28 +5516,28 @@ msgid "Flip on &Y axis\tY" msgstr "Flip on &Y axis\tY" #: flatcamGUI/FlatCAMGUI.py:392 -msgid "View source\tALT+S" -msgstr "View source\tALT+S" +msgid "View source\tAlt+S" +msgstr "View source\tAlt+S" #: flatcamGUI/FlatCAMGUI.py:394 -msgid "Tools DataBase\tCTRL+D" -msgstr "Tools DataBase\tCTRL+D" +msgid "Tools DataBase\tCtrl+D" +msgstr "Tools DataBase\tCtrl+D" #: flatcamGUI/FlatCAMGUI.py:401 flatcamGUI/FlatCAMGUI.py:2060 msgid "View" msgstr "View" #: flatcamGUI/FlatCAMGUI.py:403 -msgid "Enable all plots\tALT+1" -msgstr "Enable all plots\tALT+1" +msgid "Enable all plots\tAlt+1" +msgstr "Enable all plots\tAlt+1" #: flatcamGUI/FlatCAMGUI.py:405 -msgid "Disable all plots\tALT+2" -msgstr "Disable all plots\tALT+2" +msgid "Disable all plots\tAlt+2" +msgstr "Disable all plots\tAlt+2" #: flatcamGUI/FlatCAMGUI.py:407 -msgid "Disable non-selected\tALT+3" -msgstr "Disable non-selected\tALT+3" +msgid "Disable non-selected\tAlt+3" +msgstr "Disable non-selected\tAlt+3" #: flatcamGUI/FlatCAMGUI.py:411 msgid "&Zoom Fit\tV" @@ -5556,16 +5556,16 @@ msgid "Redraw All\tF5" msgstr "Redraw All\tF5" #: flatcamGUI/FlatCAMGUI.py:424 -msgid "Toggle Code Editor\tSHIFT+E" -msgstr "Toggle Code Editor\tSHIFT+E" +msgid "Toggle Code Editor\tShift+E" +msgstr "Toggle Code Editor\tShift+E" #: flatcamGUI/FlatCAMGUI.py:427 -msgid "&Toggle FullScreen\tALT+F10" -msgstr "&Toggle FullScreen\tALT+F10" +msgid "&Toggle FullScreen\tAlt+F10" +msgstr "&Toggle FullScreen\tAlt+F10" #: flatcamGUI/FlatCAMGUI.py:429 -msgid "&Toggle Plot Area\tCTRL+F10" -msgstr "&Toggle Plot Area\tCTRL+F10" +msgid "&Toggle Plot Area\tCtrl+F10" +msgstr "&Toggle Plot Area\tCtrl+F10" #: flatcamGUI/FlatCAMGUI.py:431 msgid "&Toggle Project/Sel/Tool\t`" @@ -5576,16 +5576,16 @@ msgid "&Toggle Grid Snap\tG" msgstr "&Toggle Grid Snap\tG" #: flatcamGUI/FlatCAMGUI.py:437 -msgid "&Toggle Grid Lines\tALT+G" -msgstr "&Toggle Grid Lines\tALT+G" +msgid "&Toggle Grid Lines\tAlt+G" +msgstr "&Toggle Grid Lines\tAlt+G" #: flatcamGUI/FlatCAMGUI.py:439 -msgid "&Toggle Axis\tSHIFT+G" -msgstr "&Toggle Axis\tSHIFT+G" +msgid "&Toggle Axis\tShift+G" +msgstr "&Toggle Axis\tShift+G" #: flatcamGUI/FlatCAMGUI.py:441 -msgid "Toggle Workspace\tSHIFT+W" -msgstr "Toggle Workspace\tSHIFT+W" +msgid "Toggle Workspace\tShift+W" +msgstr "Toggle Workspace\tShift+W" #: flatcamGUI/FlatCAMGUI.py:446 msgid "Objects" @@ -5684,8 +5684,8 @@ msgid "Paint Tool\tI" msgstr "Paint Tool\tI" #: flatcamGUI/FlatCAMGUI.py:543 -msgid "Transform Tool\tALT+R" -msgstr "Transform Tool\tALT+R" +msgid "Transform Tool\tAlt+R" +msgstr "Transform Tool\tAlt+R" #: flatcamGUI/FlatCAMGUI.py:547 msgid "Toggle Corner Snap\tK" @@ -5748,8 +5748,8 @@ msgid "Add Region\tN" msgstr "Add Region\tN" #: flatcamGUI/FlatCAMGUI.py:598 -msgid "Poligonize\tALT+N" -msgstr "Poligonize\tALT+N" +msgid "Poligonize\tAlt+N" +msgstr "Poligonize\tAlt+N" #: flatcamGUI/FlatCAMGUI.py:600 msgid "Add SemiDisc\tE" @@ -5768,16 +5768,16 @@ msgid "Scale\tS" msgstr "Scale\tS" #: flatcamGUI/FlatCAMGUI.py:608 -msgid "Mark Area\tALT+A" -msgstr "Mark Area\tALT+A" +msgid "Mark Area\tAlt+A" +msgstr "Mark Area\tAlt+A" #: flatcamGUI/FlatCAMGUI.py:610 -msgid "Eraser\tCTRL+E" -msgstr "Eraser\tCTRL+E" +msgid "Eraser\tCtrl+E" +msgstr "Eraser\tCtrl+E" #: flatcamGUI/FlatCAMGUI.py:612 -msgid "Transform\tALT+R" -msgstr "Transform\tALT+R" +msgid "Transform\tAlt+R" +msgstr "Transform\tAlt+R" #: flatcamGUI/FlatCAMGUI.py:639 msgid "Enable Plot" @@ -13800,7 +13800,7 @@ msgid "" "\n" "The coordinates set can be obtained:\n" "- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" -"- press SHIFT key and left mouse clicking on canvas. Then CTRL+V in the " +"- press SHIFT key and left mouse clicking on canvas. Then Ctrl+V in the " "field.\n" "- press SHIFT key and left mouse clicking on canvas. Then RMB click in the " "field and click Paste.\n" @@ -13811,7 +13811,7 @@ msgstr "" "\n" "The coordinates set can be obtained:\n" "- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" -"- press SHIFT key and left mouse clicking on canvas. Then CTRL+V in the " +"- press SHIFT key and left mouse clicking on canvas. Then Ctrl+V in the " "field.\n" "- press SHIFT key and left mouse clicking on canvas. Then RMB click in the " "field and click Paste.\n" @@ -17529,8 +17529,8 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "\n" #~ " " -#~ msgid "Run Script ...\tSHIFT+S" -#~ msgstr "Run Script ...\tSHIFT+S" +#~ msgid "Run Script ...\tShift+S" +#~ msgstr "Run Script ...\tShift+S" #~| msgid "" #~| "FlatCAM
Version {version} {beta} ({date}) " @@ -17714,39 +17714,39 @@ msgstr "No Geometry name in args. Provide a name and try again." #~| "  \n" #~| " \n" #~| " \n" -#~| " CTRL+A\n" +#~| " Ctrl+A\n" #~| "  Select All\n" #~| " \n" #~| " \n" -#~| " CTRL+C\n" +#~| " Ctrl+C\n" #~| "  Copy Obj\n" #~| " \n" #~| " \n" -#~| " CTRL+E\n" +#~| " Ctrl+E\n" #~| "  Open Excellon File\n" #~| " \n" #~| " \n" -#~| " CTRL+G\n" +#~| " Ctrl+G\n" #~| "  Open Gerber File\n" #~| " \n" #~| " \n" -#~| " CTRL+N\n" +#~| " Ctrl+N\n" #~| "  New Project\n" #~| " \n" #~| " \n" -#~| " CTRL+M\n" +#~| " Ctrl+M\n" #~| "  Measurement Tool\n" #~| " \n" #~| " \n" -#~| " CTRL+O\n" +#~| " Ctrl+O\n" #~| "  Open Project\n" #~| " \n" #~| " \n" -#~| " CTRL+S\n" +#~| " Ctrl+S\n" #~| "  Save Project As\n" #~| " \n" #~| " \n" -#~| " CTRL+F10Ctrl+F10\n" #~| "  Toggle Plot Area\n" #~| " \n" @@ -17755,39 +17755,39 @@ msgstr "No Geometry name in args. Provide a name and try again." #~| "  \n" #~| " \n" #~| " \n" -#~| " SHIFT+C\n" +#~| " Shift+C\n" #~| "  Copy Obj_Name\n" #~| " \n" #~| " \n" -#~| " SHIFT+E\n" +#~| " Shift+E\n" #~| "  Toggle Code Editor\n" #~| " \n" #~| " \n" -#~| " SHIFT+G\n" +#~| " Shift+G\n" #~| "  Toggle the axis\n" #~| " \n" #~| " \n" -#~| " SHIFT+P\n" +#~| " Shift+P\n" #~| "  Open Preferences Window\n" #~| " \n" #~| " \n" -#~| " SHIFT+R\n" +#~| " Shift+R\n" #~| "  Rotate by 90 degree CCW\n" #~| " \n" #~| " \n" -#~| " SHIFT+S\n" +#~| " Shift+S\n" #~| "  Run a Script\n" #~| " \n" #~| " \n" -#~| " SHIFT+W\n" +#~| " Shift+W\n" #~| "  Toggle the workspace\n" #~| " \n" #~| " \n" -#~| " SHIFT+X\n" +#~| " Shift+X\n" #~| "  Skew on X axis\n" #~| " \n" #~| " \n" -#~| " SHIFT+Y\n" +#~| " Shift+Y\n" #~| "  Skew on Y axis\n" #~| " \n" #~| " \n" @@ -17795,59 +17795,59 @@ msgstr "No Geometry name in args. Provide a name and try again." #~| "  \n" #~| " \n" #~| " \n" -#~| " ALT+C\n" +#~| " Alt+C\n" #~| "  Calculators Tool\n" #~| " \n" #~| " \n" -#~| " ALT+D\n" +#~| " Alt+D\n" #~| "  2-Sided PCB Tool\n" #~| " \n" #~| " \n" -#~| " ALT+K\n" +#~| " Alt+K\n" #~| "  Solder Paste Dispensing Tool\n" #~| " \n" #~| " \n" -#~| " ALT+L\n" +#~| " Alt+L\n" #~| "  Film PCB Tool\n" #~| " \n" #~| " \n" -#~| " ALT+N\n" +#~| " Alt+N\n" #~| "  Non-Copper Clearing Tool\n" #~| " \n" #~| " \n" -#~| " ALT+P\n" +#~| " Alt+P\n" #~| "  Paint Area Tool\n" #~| " \n" #~| " \n" -#~| " ALT+Q\n" +#~| " Alt+Q\n" #~| "  PDF Import Tool\n" #~| " \n" #~| " \n" -#~| " ALT+R\n" +#~| " Alt+R\n" #~| "  Transformations Tool\n" #~| " \n" #~| " \n" -#~| " ALT+S\n" +#~| " Alt+S\n" #~| "  View File Source\n" #~| " \n" #~| " \n" -#~| " ALT+U\n" +#~| " Alt+U\n" #~| "  Cutout PCB Tool\n" #~| " \n" #~| " \n" -#~| " ALT+1\n" +#~| " Alt+1\n" #~| "  Enable all Plots\n" #~| " \n" #~| " \n" -#~| " ALT+2\n" +#~| " Alt+2\n" #~| "  Disable all Plots\n" #~| " \n" #~| " \n" -#~| " ALT+3\n" +#~| " Alt+3\n" #~| "  Disable Non-selected Plots\n" #~| " \n" #~| " \n" -#~| " ALT+F10\n" +#~| " Alt+F10\n" #~| "  Toggle Full Screen\n" #~| " \n" #~| " \n" @@ -17998,39 +17998,39 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+A\n" +#~ " Ctrl+A\n" #~ "  Select All\n" #~ " \n" #~ " \n" -#~ " CTRL+C\n" +#~ " Ctrl+C\n" #~ "  Copy Obj\n" #~ " \n" #~ " \n" -#~ " CTRL+E\n" +#~ " Ctrl+E\n" #~ "  Open Excellon File\n" #~ " \n" #~ " \n" -#~ " CTRL+G\n" +#~ " Ctrl+G\n" #~ "  Open Gerber File\n" #~ " \n" #~ " \n" -#~ " CTRL+N\n" +#~ " Ctrl+N\n" #~ "  New Project\n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Measurement Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+O\n" +#~ " Ctrl+O\n" #~ "  Open Project\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Project As\n" #~ " \n" #~ " \n" -#~ " CTRL+F10\n" +#~ " Ctrl+F10\n" #~ "  Toggle Plot Area\n" #~ " \n" #~ " \n" @@ -18038,39 +18038,39 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+C\n" +#~ " Shift+C\n" #~ "  Copy Obj_Name\n" #~ " \n" #~ " \n" -#~ " SHIFT+E\n" +#~ " Shift+E\n" #~ "  Toggle Code Editor\n" #~ " \n" #~ " \n" -#~ " SHIFT+G\n" +#~ " Shift+G\n" #~ "  Toggle the axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+P\n" +#~ " Shift+P\n" #~ "  Open Preferences Window\n" #~ " \n" #~ " \n" -#~ " SHIFT+R\n" +#~ " Shift+R\n" #~ "  Rotate by 90 degree CCW\n" #~ " \n" #~ " \n" -#~ " SHIFT+S\n" +#~ " Shift+S\n" #~ "  Run a Script\n" #~ " \n" #~ " \n" -#~ " SHIFT+W\n" +#~ " Shift+W\n" #~ "  Toggle the workspace\n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Skew on X axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Skew on Y axis\n" #~ " \n" #~ " \n" @@ -18078,59 +18078,59 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+C\n" +#~ " Alt+C\n" #~ "  Calculators Tool\n" #~ " \n" #~ " \n" -#~ " ALT+D\n" +#~ " Alt+D\n" #~ "  2-Sided PCB Tool\n" #~ " \n" #~ " \n" -#~ " ALT+K\n" +#~ " Alt+K\n" #~ "  Solder Paste Dispensing Tool\n" #~ " \n" #~ " \n" -#~ " ALT+L\n" +#~ " Alt+L\n" #~ "  Film PCB Tool\n" #~ " \n" #~ " \n" -#~ " ALT+N\n" +#~ " Alt+N\n" #~ "  Non-Copper Clearing Tool\n" #~ " \n" #~ " \n" -#~ " ALT+P\n" +#~ " Alt+P\n" #~ "  Paint Area Tool\n" #~ " \n" #~ " \n" -#~ " ALT+Q\n" +#~ " Alt+Q\n" #~ "  PDF Import Tool\n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Transformations Tool\n" #~ " \n" #~ " \n" -#~ " ALT+S\n" +#~ " Alt+S\n" #~ "  View File Source\n" #~ " \n" #~ " \n" -#~ " ALT+U\n" +#~ " Alt+U\n" #~ "  Cutout PCB Tool\n" #~ " \n" #~ " \n" -#~ " ALT+1\n" +#~ " Alt+1\n" #~ "  Enable all Plots\n" #~ " \n" #~ " \n" -#~ " ALT+2\n" +#~ " Alt+2\n" #~ "  Disable all Plots\n" #~ " \n" #~ " \n" -#~ " ALT+3\n" +#~ " Alt+3\n" #~ "  Disable Non-selected Plots\n" #~ " \n" #~ " \n" -#~ " ALT+F10\n" +#~ " Alt+F10\n" #~ "  Toggle Full Screen\n" #~ " \n" #~ " \n" @@ -18138,7 +18138,7 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+ALT+XCtrl+Alt+X\n" #~ "  Abort current task (gracefully)\n" #~ " \n" @@ -18290,39 +18290,39 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+A\n" +#~ " Ctrl+A\n" #~ "  Select All\n" #~ " \n" #~ " \n" -#~ " CTRL+C\n" +#~ " Ctrl+C\n" #~ "  Copy Obj\n" #~ " \n" #~ " \n" -#~ " CTRL+E\n" +#~ " Ctrl+E\n" #~ "  Open Excellon File\n" #~ " \n" #~ " \n" -#~ " CTRL+G\n" +#~ " Ctrl+G\n" #~ "  Open Gerber File\n" #~ " \n" #~ " \n" -#~ " CTRL+N\n" +#~ " Ctrl+N\n" #~ "  New Project\n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Measurement Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+O\n" +#~ " Ctrl+O\n" #~ "  Open Project\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Project As\n" #~ " \n" #~ " \n" -#~ " CTRL+F10\n" +#~ " Ctrl+F10\n" #~ "  Toggle Plot Area\n" #~ " \n" #~ " \n" @@ -18330,39 +18330,39 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+C\n" +#~ " Shift+C\n" #~ "  Copy Obj_Name\n" #~ " \n" #~ " \n" -#~ " SHIFT+E\n" +#~ " Shift+E\n" #~ "  Toggle Code Editor\n" #~ " \n" #~ " \n" -#~ " SHIFT+G\n" +#~ " Shift+G\n" #~ "  Toggle the axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+P\n" +#~ " Shift+P\n" #~ "  Open Preferences Window\n" #~ " \n" #~ " \n" -#~ " SHIFT+R\n" +#~ " Shift+R\n" #~ "  Rotate by 90 degree CCW\n" #~ " \n" #~ " \n" -#~ " SHIFT+S\n" +#~ " Shift+S\n" #~ "  Run a Script\n" #~ " \n" #~ " \n" -#~ " SHIFT+W\n" +#~ " Shift+W\n" #~ "  Toggle the workspace\n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Skew on X axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Skew on Y axis\n" #~ " \n" #~ " \n" @@ -18370,59 +18370,59 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+C\n" +#~ " Alt+C\n" #~ "  Calculators Tool\n" #~ " \n" #~ " \n" -#~ " ALT+D\n" +#~ " Alt+D\n" #~ "  2-Sided PCB Tool\n" #~ " \n" #~ " \n" -#~ " ALT+K\n" +#~ " Alt+K\n" #~ "  Solder Paste Dispensing Tool\n" #~ " \n" #~ " \n" -#~ " ALT+L\n" +#~ " Alt+L\n" #~ "  Film PCB Tool\n" #~ " \n" #~ " \n" -#~ " ALT+N\n" +#~ " Alt+N\n" #~ "  Non-Copper Clearing Tool\n" #~ " \n" #~ " \n" -#~ " ALT+P\n" +#~ " Alt+P\n" #~ "  Paint Area Tool\n" #~ " \n" #~ " \n" -#~ " ALT+Q\n" +#~ " Alt+Q\n" #~ "  PDF Import Tool\n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Transformations Tool\n" #~ " \n" #~ " \n" -#~ " ALT+S\n" +#~ " Alt+S\n" #~ "  View File Source\n" #~ " \n" #~ " \n" -#~ " ALT+U\n" +#~ " Alt+U\n" #~ "  Cutout PCB Tool\n" #~ " \n" #~ " \n" -#~ " ALT+1\n" +#~ " Alt+1\n" #~ "  Enable all Plots\n" #~ " \n" #~ " \n" -#~ " ALT+2\n" +#~ " Alt+2\n" #~ "  Disable all Plots\n" #~ " \n" #~ " \n" -#~ " ALT+3\n" +#~ " Alt+3\n" #~ "  Disable Non-selected Plots\n" #~ " \n" #~ " \n" -#~ " ALT+F10\n" +#~ " Alt+F10\n" #~ "  Toggle Full Screen\n" #~ " \n" #~ " \n" @@ -18430,7 +18430,7 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+ALT+XCtrl+Alt+X\n" #~ "  Abort current task (gracefully)\n" #~ " \n" @@ -18565,11 +18565,11 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Skew shape on X axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Skew shape on Y axis\n" #~ " \n" #~ " \n" @@ -18577,15 +18577,15 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Editor Transformation Tool\n" #~ " \n" #~ " \n" -#~ " ALT+X\n" +#~ " Alt+X\n" #~ "  Offset shape on X axis\n" #~ " \n" #~ " \n" -#~ " ALT+Y\n" +#~ " Alt+Y\n" #~ "  Offset shape on Y axis\n" #~ " \n" #~ " \n" @@ -18593,15 +18593,15 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Measurement Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" -#~ " CTRL+X\n" +#~ " Ctrl+X\n" #~ "  Polygon Cut Tool\n" #~ " \n" #~ " \n" @@ -18693,7 +18693,7 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  Abort and return to Select\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" @@ -18781,11 +18781,11 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  Abort and return to Select\n" #~ " \n" #~ " \n" -#~ " CTRL+E\n" +#~ " Ctrl+E\n" #~ "  Eraser Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" @@ -18793,15 +18793,15 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+A\n" +#~ " Alt+A\n" #~ "  Mark Area Tool\n" #~ " \n" #~ " \n" -#~ " ALT+N\n" +#~ " Alt+N\n" #~ "  Poligonize Tool\n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Transformation Tool\n" #~ " \n" #~ " \n" @@ -18900,11 +18900,11 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Skew shape on X axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Skew shape on Y axis\n" #~ " \n" #~ " \n" @@ -18912,15 +18912,15 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Editor Transformation Tool\n" #~ " \n" #~ " \n" -#~ " ALT+X\n" +#~ " Alt+X\n" #~ "  Offset shape on X axis\n" #~ " \n" #~ " \n" -#~ " ALT+Y\n" +#~ " Alt+Y\n" #~ "  Offset shape on Y axis\n" #~ " \n" #~ " \n" @@ -18928,15 +18928,15 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Measurement Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" -#~ " CTRL+X\n" +#~ " Ctrl+X\n" #~ "  Polygon Cut Tool\n" #~ " \n" #~ " \n" @@ -19028,7 +19028,7 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  Abort and return to Select\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" @@ -19116,11 +19116,11 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  Abort and return to Select\n" #~ " \n" #~ " \n" -#~ " CTRL+E\n" +#~ " Ctrl+E\n" #~ "  Eraser Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" @@ -19128,15 +19128,15 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+A\n" +#~ " Alt+A\n" #~ "  Mark Area Tool\n" #~ " \n" #~ " \n" -#~ " ALT+N\n" +#~ " Alt+N\n" #~ "  Poligonize Tool\n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Transformation Tool\n" #~ " \n" #~ " \n" @@ -20035,11 +20035,11 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Skew shape on X axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Skew shape on Y axis\n" #~ " \n" #~ " \n" @@ -20047,15 +20047,15 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Editor Transformation Tool\n" #~ " \n" #~ " \n" -#~ " ALT+X\n" +#~ " Alt+X\n" #~ "  Offset shape on X axis\n" #~ " \n" #~ " \n" -#~ " ALT+Y\n" +#~ " Alt+Y\n" #~ "  Offset shape on Y axis\n" #~ " \n" #~ " \n" @@ -20063,15 +20063,15 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Measurement Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" -#~ " CTRL+X\n" +#~ " Ctrl+X\n" #~ "  Polygon Cut Tool\n" #~ " \n" #~ " \n" @@ -20153,7 +20153,7 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  Abort and return to Select\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" @@ -20242,11 +20242,11 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Skew shape on X axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Skew shape on Y axis\n" #~ " \n" #~ " \n" @@ -20254,15 +20254,15 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Editor Transformation Tool\n" #~ " \n" #~ " \n" -#~ " ALT+X\n" +#~ " Alt+X\n" #~ "  Offset shape on X axis\n" #~ " \n" #~ " \n" -#~ " ALT+Y\n" +#~ " Alt+Y\n" #~ "  Offset shape on Y axis\n" #~ " \n" #~ " \n" @@ -20270,15 +20270,15 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Measurement Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" -#~ " CTRL+X\n" +#~ " Ctrl+X\n" #~ "  Polygon Cut Tool\n" #~ " \n" #~ " \n" @@ -20360,7 +20360,7 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ "  Abort and return to Select\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" diff --git a/locale/es/LC_MESSAGES/strings.po b/locale/es/LC_MESSAGES/strings.po index 40d3783a..64592b0a 100644 --- a/locale/es/LC_MESSAGES/strings.po +++ b/locale/es/LC_MESSAGES/strings.po @@ -5267,8 +5267,8 @@ msgid "File" msgstr "Archivo" #: flatcamGUI/FlatCAMGUI.py:69 -msgid "&New Project ...\tCTRL+N" -msgstr "&Nuevo proyecto ...\tCTRL+N" +msgid "&New Project ...\tCtrl+N" +msgstr "&Nuevo proyecto ...\tCtrl+N" #: flatcamGUI/FlatCAMGUI.py:71 msgid "Will create a new, blank project" @@ -5320,12 +5320,12 @@ msgid "Open &Project ..." msgstr "Abierto &Project ..." #: flatcamGUI/FlatCAMGUI.py:109 flatcamGUI/FlatCAMGUI.py:4121 -msgid "Open &Gerber ...\tCTRL+G" -msgstr "Abierto &Gerber ...\tCTRL+G" +msgid "Open &Gerber ...\tCtrl+G" +msgstr "Abierto &Gerber ...\tCtrl+G" #: flatcamGUI/FlatCAMGUI.py:114 flatcamGUI/FlatCAMGUI.py:4126 -msgid "Open &Excellon ...\tCTRL+E" -msgstr "Abierto &Excellon ...\tCTRL+E" +msgid "Open &Excellon ...\tCtrl+E" +msgstr "Abierto &Excellon ...\tCtrl+E" #: flatcamGUI/FlatCAMGUI.py:118 flatcamGUI/FlatCAMGUI.py:4131 msgid "Open G-&Code ..." @@ -5476,8 +5476,8 @@ msgid "&Save Project ..." msgstr "Salvar proyecto ..." #: flatcamGUI/FlatCAMGUI.py:256 -msgid "Save Project &As ...\tCTRL+S" -msgstr "Guardar proyecto como...\tCTRL+S" +msgid "Save Project &As ...\tCtrl+S" +msgstr "Guardar proyecto como...\tCtrl+S" #: flatcamGUI/FlatCAMGUI.py:261 msgid "Save Project C&opy ..." @@ -5497,8 +5497,8 @@ msgid "Edit Object\tE" msgstr "Editar objeto\tE" #: flatcamGUI/FlatCAMGUI.py:285 -msgid "Close Editor\tCTRL+S" -msgstr "Cerrar Editor\tCTRL+S" +msgid "Close Editor\tCtrl+S" +msgstr "Cerrar Editor\tCtrl+S" #: flatcamGUI/FlatCAMGUI.py:294 msgid "Conversion" @@ -5574,8 +5574,8 @@ msgid "Convert Any to Gerber" msgstr "Convertir cualquiera a Gerber" #: flatcamGUI/FlatCAMGUI.py:341 -msgid "&Copy\tCTRL+C" -msgstr "Dupdo\tCTRL+C" +msgid "&Copy\tCtrl+C" +msgstr "Dupdo\tCtrl+C" #: flatcamGUI/FlatCAMGUI.py:346 msgid "&Delete\tDEL" @@ -5594,28 +5594,28 @@ msgid "Toggle Units\tQ" msgstr "Unidades de palanca\tQ" #: flatcamGUI/FlatCAMGUI.py:360 -msgid "&Select All\tCTRL+A" -msgstr "Seleccionar todo\tCTRL+A" +msgid "&Select All\tCtrl+A" +msgstr "Seleccionar todo\tCtrl+A" #: flatcamGUI/FlatCAMGUI.py:365 -msgid "&Preferences\tSHIFT+P" -msgstr "Preferencias\tSHIFT+P" +msgid "&Preferences\tShift+P" +msgstr "Preferencias\tShift+P" #: flatcamGUI/FlatCAMGUI.py:371 flatcamTools/ToolProperties.py:153 msgid "Options" msgstr "Opciones" #: flatcamGUI/FlatCAMGUI.py:373 -msgid "&Rotate Selection\tSHIFT+(R)" -msgstr "Rotar selección\tSHIFT+(R)" +msgid "&Rotate Selection\tShift+(R)" +msgstr "Rotar selección\tShift+(R)" #: flatcamGUI/FlatCAMGUI.py:378 -msgid "&Skew on X axis\tSHIFT+X" -msgstr "Sesgo en el eje X\tSHIFT+X" +msgid "&Skew on X axis\tShift+X" +msgstr "Sesgo en el eje X\tShift+X" #: flatcamGUI/FlatCAMGUI.py:380 -msgid "S&kew on Y axis\tSHIFT+Y" -msgstr "Sesgo en el eje Y\tSHIFT+Y" +msgid "S&kew on Y axis\tShift+Y" +msgstr "Sesgo en el eje Y\tShift+Y" #: flatcamGUI/FlatCAMGUI.py:385 msgid "Flip on &X axis\tX" @@ -5626,28 +5626,28 @@ msgid "Flip on &Y axis\tY" msgstr "Voltear en el ejeY\tY" #: flatcamGUI/FlatCAMGUI.py:392 -msgid "View source\tALT+S" -msgstr "Ver fuente\tALT+S" +msgid "View source\tAlt+S" +msgstr "Ver fuente\tAlt+S" #: flatcamGUI/FlatCAMGUI.py:394 -msgid "Tools DataBase\tCTRL+D" -msgstr "DB de Herramientas\tCTRL+D" +msgid "Tools DataBase\tCtrl+D" +msgstr "DB de Herramientas\tCtrl+D" #: flatcamGUI/FlatCAMGUI.py:401 flatcamGUI/FlatCAMGUI.py:2060 msgid "View" msgstr "Ver" #: flatcamGUI/FlatCAMGUI.py:403 -msgid "Enable all plots\tALT+1" -msgstr "Habilitar todas las parcelas\tALT+1" +msgid "Enable all plots\tAlt+1" +msgstr "Habilitar todas las parcelas\tAlt+1" #: flatcamGUI/FlatCAMGUI.py:405 -msgid "Disable all plots\tALT+2" -msgstr "Deshabilitar todas las parcelas\tALT+2" +msgid "Disable all plots\tAlt+2" +msgstr "Deshabilitar todas las parcelas\tAlt+2" #: flatcamGUI/FlatCAMGUI.py:407 -msgid "Disable non-selected\tALT+3" -msgstr "Deshabilitar no seleccionado\tALT+3" +msgid "Disable non-selected\tAlt+3" +msgstr "Deshabilitar no seleccionado\tAlt+3" #: flatcamGUI/FlatCAMGUI.py:411 msgid "&Zoom Fit\tV" @@ -5666,16 +5666,16 @@ msgid "Redraw All\tF5" msgstr "Redibujar todo\tF5" #: flatcamGUI/FlatCAMGUI.py:424 -msgid "Toggle Code Editor\tSHIFT+E" -msgstr "Alternar Editor de Código\tSHIFT+E" +msgid "Toggle Code Editor\tShift+E" +msgstr "Alternar Editor de Código\tShift+E" #: flatcamGUI/FlatCAMGUI.py:427 -msgid "&Toggle FullScreen\tALT+F10" -msgstr "Alternar pantalla completa\tALT+F10" +msgid "&Toggle FullScreen\tAlt+F10" +msgstr "Alternar pantalla completa\tAlt+F10" #: flatcamGUI/FlatCAMGUI.py:429 -msgid "&Toggle Plot Area\tCTRL+F10" -msgstr "Alternar área de la parcela\tCTRL+F10" +msgid "&Toggle Plot Area\tCtrl+F10" +msgstr "Alternar área de la parcela\tCtrl+F10" #: flatcamGUI/FlatCAMGUI.py:431 msgid "&Toggle Project/Sel/Tool\t`" @@ -5686,16 +5686,16 @@ msgid "&Toggle Grid Snap\tG" msgstr "Activar cuadrícula\tG" #: flatcamGUI/FlatCAMGUI.py:437 -msgid "&Toggle Grid Lines\tALT+G" -msgstr "Alternar Líneas de Cuadrícula\tALT+G" +msgid "&Toggle Grid Lines\tAlt+G" +msgstr "Alternar Líneas de Cuadrícula\tAlt+G" #: flatcamGUI/FlatCAMGUI.py:439 -msgid "&Toggle Axis\tSHIFT+G" -msgstr "Eje de palanca\tSHIFT+G" +msgid "&Toggle Axis\tShift+G" +msgstr "Eje de palanca\tShift+G" #: flatcamGUI/FlatCAMGUI.py:441 -msgid "Toggle Workspace\tSHIFT+W" -msgstr "Alternar espacio de trabajo\tSHIFT+W" +msgid "Toggle Workspace\tShift+W" +msgstr "Alternar espacio de trabajo\tShift+W" #: flatcamGUI/FlatCAMGUI.py:446 msgid "Objects" @@ -5794,8 +5794,8 @@ msgid "Paint Tool\tI" msgstr "Herramienta de pintura\tI" #: flatcamGUI/FlatCAMGUI.py:543 -msgid "Transform Tool\tALT+R" -msgstr "Herramienta de transformación\tALT+R" +msgid "Transform Tool\tAlt+R" +msgstr "Herramienta de transformación\tAlt+R" #: flatcamGUI/FlatCAMGUI.py:547 msgid "Toggle Corner Snap\tK" @@ -5858,8 +5858,8 @@ msgid "Add Region\tN" msgstr "Añadir región\tN" #: flatcamGUI/FlatCAMGUI.py:598 -msgid "Poligonize\tALT+N" -msgstr "Poligonize\tALT+N" +msgid "Poligonize\tAlt+N" +msgstr "Poligonize\tAlt+N" #: flatcamGUI/FlatCAMGUI.py:600 msgid "Add SemiDisc\tE" @@ -5878,16 +5878,16 @@ msgid "Scale\tS" msgstr "Escalar\tS" #: flatcamGUI/FlatCAMGUI.py:608 -msgid "Mark Area\tALT+A" -msgstr "Marcar area\tALT+A" +msgid "Mark Area\tAlt+A" +msgstr "Marcar area\tAlt+A" #: flatcamGUI/FlatCAMGUI.py:610 -msgid "Eraser\tCTRL+E" -msgstr "Borrador\tCTRL+E" +msgid "Eraser\tCtrl+E" +msgstr "Borrador\tCtrl+E" #: flatcamGUI/FlatCAMGUI.py:612 -msgid "Transform\tALT+R" -msgstr "Transformar\tALT+R" +msgid "Transform\tAlt+R" +msgstr "Transformar\tAlt+R" #: flatcamGUI/FlatCAMGUI.py:639 msgid "Enable Plot" @@ -14007,7 +14007,7 @@ msgid "" "\n" "The coordinates set can be obtained:\n" "- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" -"- press SHIFT key and left mouse clicking on canvas. Then CTRL+V in the " +"- press SHIFT key and left mouse clicking on canvas. Then Ctrl+V in the " "field.\n" "- press SHIFT key and left mouse clicking on canvas. Then RMB click in the " "field and click Paste.\n" @@ -17788,8 +17788,8 @@ msgstr "" #~ "\n" #~ " " -#~ msgid "Run Script ...\tSHIFT+S" -#~ msgstr "Ejecutar Script ...\tSHIFT+S" +#~ msgid "Run Script ...\tShift+S" +#~ msgstr "Ejecutar Script ...\tShift+S" #~ msgid "" #~ "FlatCAM
Version {version} {beta} ({date}) - " diff --git a/locale/fr/LC_MESSAGES/strings.po b/locale/fr/LC_MESSAGES/strings.po index a58e7f3c..ad897b9b 100644 --- a/locale/fr/LC_MESSAGES/strings.po +++ b/locale/fr/LC_MESSAGES/strings.po @@ -5282,8 +5282,8 @@ msgid "File" msgstr "Fichier" #: flatcamGUI/FlatCAMGUI.py:69 -msgid "&New Project ...\tCTRL+N" -msgstr "Nouveau projet ...\tCTRL+N" +msgid "&New Project ...\tCtrl+N" +msgstr "Nouveau projet ...\tCtrl+N" #: flatcamGUI/FlatCAMGUI.py:71 msgid "Will create a new, blank project" @@ -5335,12 +5335,12 @@ msgid "Open &Project ..." msgstr "Projet ouvert ..." #: flatcamGUI/FlatCAMGUI.py:109 flatcamGUI/FlatCAMGUI.py:4121 -msgid "Open &Gerber ...\tCTRL+G" -msgstr "Gerber ouvert...\tCTRL+G" +msgid "Open &Gerber ...\tCtrl+G" +msgstr "Gerber ouvert...\tCtrl+G" #: flatcamGUI/FlatCAMGUI.py:114 flatcamGUI/FlatCAMGUI.py:4126 -msgid "Open &Excellon ...\tCTRL+E" -msgstr "Excellon ouvert ...\tCTRL+E" +msgid "Open &Excellon ...\tCtrl+E" +msgstr "Excellon ouvert ...\tCtrl+E" #: flatcamGUI/FlatCAMGUI.py:118 flatcamGUI/FlatCAMGUI.py:4131 msgid "Open G-&Code ..." @@ -5491,8 +5491,8 @@ msgid "&Save Project ..." msgstr "Sauvegarder le projet ..." #: flatcamGUI/FlatCAMGUI.py:256 -msgid "Save Project &As ...\tCTRL+S" -msgstr "Enregistrer le projet sous...\tCTRL+S" +msgid "Save Project &As ...\tCtrl+S" +msgstr "Enregistrer le projet sous...\tCtrl+S" #: flatcamGUI/FlatCAMGUI.py:261 msgid "Save Project C&opy ..." @@ -5512,8 +5512,8 @@ msgid "Edit Object\tE" msgstr "Editer un objet\tE" #: flatcamGUI/FlatCAMGUI.py:285 -msgid "Close Editor\tCTRL+S" -msgstr "Fermer l'éditeur\tCTRL+S" +msgid "Close Editor\tCtrl+S" +msgstr "Fermer l'éditeur\tCtrl+S" #: flatcamGUI/FlatCAMGUI.py:294 msgid "Conversion" @@ -5589,8 +5589,8 @@ msgid "Convert Any to Gerber" msgstr "Convertir n'importe lequel en gerber" #: flatcamGUI/FlatCAMGUI.py:341 -msgid "&Copy\tCTRL+C" -msgstr "Copie\tCTRL+C" +msgid "&Copy\tCtrl+C" +msgstr "Copie\tCtrl+C" #: flatcamGUI/FlatCAMGUI.py:346 msgid "&Delete\tDEL" @@ -5609,28 +5609,28 @@ msgid "Toggle Units\tQ" msgstr "Basculer les Unités\tQ" #: flatcamGUI/FlatCAMGUI.py:360 -msgid "&Select All\tCTRL+A" -msgstr "Tout sélectionner\tCTRL+A" +msgid "&Select All\tCtrl+A" +msgstr "Tout sélectionner\tCtrl+A" #: flatcamGUI/FlatCAMGUI.py:365 -msgid "&Preferences\tSHIFT+P" -msgstr "Préférences\tSHIFT+P" +msgid "&Preferences\tShift+P" +msgstr "Préférences\tShift+P" #: flatcamGUI/FlatCAMGUI.py:371 flatcamTools/ToolProperties.py:153 msgid "Options" msgstr "Les options" #: flatcamGUI/FlatCAMGUI.py:373 -msgid "&Rotate Selection\tSHIFT+(R)" -msgstr "Faire pivoter la sélection\tSHIFT+(R)" +msgid "&Rotate Selection\tShift+(R)" +msgstr "Faire pivoter la sélection\tShift+(R)" #: flatcamGUI/FlatCAMGUI.py:378 -msgid "&Skew on X axis\tSHIFT+X" -msgstr "Fausser sur l'axe X\tSHIFT+X" +msgid "&Skew on X axis\tShift+X" +msgstr "Fausser sur l'axe X\tShift+X" #: flatcamGUI/FlatCAMGUI.py:380 -msgid "S&kew on Y axis\tSHIFT+Y" -msgstr "Fausser sur l'axe Y\tSHIFT+Y" +msgid "S&kew on Y axis\tShift+Y" +msgstr "Fausser sur l'axe Y\tShift+Y" #: flatcamGUI/FlatCAMGUI.py:385 msgid "Flip on &X axis\tX" @@ -5641,28 +5641,28 @@ msgid "Flip on &Y axis\tY" msgstr "Miroir sur l'axe Y\tY" #: flatcamGUI/FlatCAMGUI.py:392 -msgid "View source\tALT+S" -msgstr "Voir la source\tALT+S" +msgid "View source\tAlt+S" +msgstr "Voir la source\tAlt+S" #: flatcamGUI/FlatCAMGUI.py:394 -msgid "Tools DataBase\tCTRL+D" -msgstr "Base de Données d'outils\tCTRL+D" +msgid "Tools DataBase\tCtrl+D" +msgstr "Base de Données d'outils\tCtrl+D" #: flatcamGUI/FlatCAMGUI.py:401 flatcamGUI/FlatCAMGUI.py:2060 msgid "View" msgstr "Vue" #: flatcamGUI/FlatCAMGUI.py:403 -msgid "Enable all plots\tALT+1" -msgstr "Activer tous les dessins\tALT+1" +msgid "Enable all plots\tAlt+1" +msgstr "Activer tous les dessins\tAlt+1" #: flatcamGUI/FlatCAMGUI.py:405 -msgid "Disable all plots\tALT+2" -msgstr "Désactiver tous les dessins\tALT+2" +msgid "Disable all plots\tAlt+2" +msgstr "Désactiver tous les dessins\tAlt+2" #: flatcamGUI/FlatCAMGUI.py:407 -msgid "Disable non-selected\tALT+3" -msgstr "Désactiver les non sélectionnés\tALT+3" +msgid "Disable non-selected\tAlt+3" +msgstr "Désactiver les non sélectionnés\tAlt+3" #: flatcamGUI/FlatCAMGUI.py:411 msgid "&Zoom Fit\tV" @@ -5681,16 +5681,16 @@ msgid "Redraw All\tF5" msgstr "Tout redessiner\tF5" #: flatcamGUI/FlatCAMGUI.py:424 -msgid "Toggle Code Editor\tSHIFT+E" -msgstr "Basculer l'éditeur de code\tSHIFT+E" +msgid "Toggle Code Editor\tShift+E" +msgstr "Basculer l'éditeur de code\tShift+E" #: flatcamGUI/FlatCAMGUI.py:427 -msgid "&Toggle FullScreen\tALT+F10" -msgstr "Passer en plein écran\tALT+F10" +msgid "&Toggle FullScreen\tAlt+F10" +msgstr "Passer en plein écran\tAlt+F10" #: flatcamGUI/FlatCAMGUI.py:429 -msgid "&Toggle Plot Area\tCTRL+F10" -msgstr "Basculer la zone de tracé\tCTRL+F10" +msgid "&Toggle Plot Area\tCtrl+F10" +msgstr "Basculer la zone de tracé\tCtrl+F10" #: flatcamGUI/FlatCAMGUI.py:431 msgid "&Toggle Project/Sel/Tool\t`" @@ -5701,16 +5701,16 @@ msgid "&Toggle Grid Snap\tG" msgstr "Basculer la grille\tG" #: flatcamGUI/FlatCAMGUI.py:437 -msgid "&Toggle Grid Lines\tALT+G" -msgstr "Basculer les lignes de la grille\tALT+G" +msgid "&Toggle Grid Lines\tAlt+G" +msgstr "Basculer les lignes de la grille\tAlt+G" #: flatcamGUI/FlatCAMGUI.py:439 -msgid "&Toggle Axis\tSHIFT+G" -msgstr "Basculer l'axe\tSHIFT+G" +msgid "&Toggle Axis\tShift+G" +msgstr "Basculer l'axe\tShift+G" #: flatcamGUI/FlatCAMGUI.py:441 -msgid "Toggle Workspace\tSHIFT+W" -msgstr "Basculer l'espace de travail\tSHIFT+W" +msgid "Toggle Workspace\tShift+W" +msgstr "Basculer l'espace de travail\tShift+W" #: flatcamGUI/FlatCAMGUI.py:446 msgid "Objects" @@ -5809,8 +5809,8 @@ msgid "Paint Tool\tI" msgstr "Outil de Peinture\tI" #: flatcamGUI/FlatCAMGUI.py:543 -msgid "Transform Tool\tALT+R" -msgstr "Outil de Transformation\tALT+R" +msgid "Transform Tool\tAlt+R" +msgstr "Outil de Transformation\tAlt+R" #: flatcamGUI/FlatCAMGUI.py:547 msgid "Toggle Corner Snap\tK" @@ -5873,8 +5873,8 @@ msgid "Add Region\tN" msgstr "Ajouter une Région\tN" #: flatcamGUI/FlatCAMGUI.py:598 -msgid "Poligonize\tALT+N" -msgstr "Polygoniser\tALT+N" +msgid "Poligonize\tAlt+N" +msgstr "Polygoniser\tAlt+N" #: flatcamGUI/FlatCAMGUI.py:600 msgid "Add SemiDisc\tE" @@ -5893,16 +5893,16 @@ msgid "Scale\tS" msgstr "Échelle\tS" #: flatcamGUI/FlatCAMGUI.py:608 -msgid "Mark Area\tALT+A" -msgstr "Zone de Marque\tALT+A" +msgid "Mark Area\tAlt+A" +msgstr "Zone de Marque\tAlt+A" #: flatcamGUI/FlatCAMGUI.py:610 -msgid "Eraser\tCTRL+E" -msgstr "La Gomme\tCTRL+E" +msgid "Eraser\tCtrl+E" +msgstr "La Gomme\tCtrl+E" #: flatcamGUI/FlatCAMGUI.py:612 -msgid "Transform\tALT+R" -msgstr "Transformation\tALT+R" +msgid "Transform\tAlt+R" +msgstr "Transformation\tAlt+R" #: flatcamGUI/FlatCAMGUI.py:639 msgid "Enable Plot" @@ -14014,7 +14014,7 @@ msgid "" "\n" "The coordinates set can be obtained:\n" "- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" -"- press SHIFT key and left mouse clicking on canvas. Then CTRL+V in the " +"- press SHIFT key and left mouse clicking on canvas. Then Ctrl+V in the " "field.\n" "- press SHIFT key and left mouse clicking on canvas. Then RMB click in the " "field and click Paste.\n" diff --git a/locale/it/LC_MESSAGES/strings.po b/locale/it/LC_MESSAGES/strings.po index 118af3b2..5a2bdbdf 100644 --- a/locale/it/LC_MESSAGES/strings.po +++ b/locale/it/LC_MESSAGES/strings.po @@ -4787,8 +4787,8 @@ msgid "File" msgstr "File" #: flatcamGUI/FlatCAMGUI.py:69 -msgid "&New Project ...\tCTRL+N" -msgstr "&Nuovo progetto ...\tCTRL+N" +msgid "&New Project ...\tCtrl+N" +msgstr "&Nuovo progetto ...\tCtrl+N" #: flatcamGUI/FlatCAMGUI.py:71 msgid "Will create a new, blank project" @@ -4840,12 +4840,12 @@ msgid "Open &Project ..." msgstr "Progetto aperto ..." #: flatcamGUI/FlatCAMGUI.py:109 flatcamGUI/FlatCAMGUI.py:4121 -msgid "Open &Gerber ...\tCTRL+G" -msgstr "Apri Gerber...\tCTRL+G" +msgid "Open &Gerber ...\tCtrl+G" +msgstr "Apri Gerber...\tCtrl+G" #: flatcamGUI/FlatCAMGUI.py:114 flatcamGUI/FlatCAMGUI.py:4126 -msgid "Open &Excellon ...\tCTRL+E" -msgstr "Apri Excellon ...\tCTRL+E" +msgid "Open &Excellon ...\tCtrl+E" +msgstr "Apri Excellon ...\tCtrl+E" #: flatcamGUI/FlatCAMGUI.py:118 flatcamGUI/FlatCAMGUI.py:4131 msgid "Open G-&Code ..." @@ -4984,8 +4984,8 @@ msgid "&Save Project ..." msgstr "Salva il progetto ..." #: flatcamGUI/FlatCAMGUI.py:256 -msgid "Save Project &As ...\tCTRL+S" -msgstr "Salva progetto con nome ...\tCTRL+S" +msgid "Save Project &As ...\tCtrl+S" +msgstr "Salva progetto con nome ...\tCtrl+S" #: flatcamGUI/FlatCAMGUI.py:261 msgid "Save Project C&opy ..." @@ -5005,7 +5005,7 @@ msgid "Edit Object\tE" msgstr "" #: flatcamGUI/FlatCAMGUI.py:285 -msgid "Close Editor\tCTRL+S" +msgid "Close Editor\tCtrl+S" msgstr "" #: flatcamGUI/FlatCAMGUI.py:294 @@ -5070,7 +5070,7 @@ msgid "Convert Any to Gerber" msgstr "" #: flatcamGUI/FlatCAMGUI.py:341 -msgid "&Copy\tCTRL+C" +msgid "&Copy\tCtrl+C" msgstr "" #: flatcamGUI/FlatCAMGUI.py:346 @@ -5090,11 +5090,11 @@ msgid "Toggle Units\tQ" msgstr "" #: flatcamGUI/FlatCAMGUI.py:360 -msgid "&Select All\tCTRL+A" +msgid "&Select All\tCtrl+A" msgstr "" #: flatcamGUI/FlatCAMGUI.py:365 -msgid "&Preferences\tSHIFT+P" +msgid "&Preferences\tShift+P" msgstr "" #: flatcamGUI/FlatCAMGUI.py:371 flatcamTools/ToolProperties.py:153 @@ -5102,15 +5102,15 @@ msgid "Options" msgstr "" #: flatcamGUI/FlatCAMGUI.py:373 -msgid "&Rotate Selection\tSHIFT+(R)" +msgid "&Rotate Selection\tShift+(R)" msgstr "" #: flatcamGUI/FlatCAMGUI.py:378 -msgid "&Skew on X axis\tSHIFT+X" +msgid "&Skew on X axis\tShift+X" msgstr "" #: flatcamGUI/FlatCAMGUI.py:380 -msgid "S&kew on Y axis\tSHIFT+Y" +msgid "S&kew on Y axis\tShift+Y" msgstr "" #: flatcamGUI/FlatCAMGUI.py:385 @@ -5122,11 +5122,11 @@ msgid "Flip on &Y axis\tY" msgstr "" #: flatcamGUI/FlatCAMGUI.py:392 -msgid "View source\tALT+S" +msgid "View source\tAlt+S" msgstr "" #: flatcamGUI/FlatCAMGUI.py:394 -msgid "Tools DataBase\tCTRL+D" +msgid "Tools DataBase\tCtrl+D" msgstr "" #: flatcamGUI/FlatCAMGUI.py:401 flatcamGUI/FlatCAMGUI.py:2060 @@ -5134,15 +5134,15 @@ msgid "View" msgstr "" #: flatcamGUI/FlatCAMGUI.py:403 -msgid "Enable all plots\tALT+1" +msgid "Enable all plots\tAlt+1" msgstr "" #: flatcamGUI/FlatCAMGUI.py:405 -msgid "Disable all plots\tALT+2" +msgid "Disable all plots\tAlt+2" msgstr "" #: flatcamGUI/FlatCAMGUI.py:407 -msgid "Disable non-selected\tALT+3" +msgid "Disable non-selected\tAlt+3" msgstr "" #: flatcamGUI/FlatCAMGUI.py:411 @@ -5162,15 +5162,15 @@ msgid "Redraw All\tF5" msgstr "" #: flatcamGUI/FlatCAMGUI.py:424 -msgid "Toggle Code Editor\tSHIFT+E" +msgid "Toggle Code Editor\tShift+E" msgstr "" #: flatcamGUI/FlatCAMGUI.py:427 -msgid "&Toggle FullScreen\tALT+F10" +msgid "&Toggle FullScreen\tAlt+F10" msgstr "" #: flatcamGUI/FlatCAMGUI.py:429 -msgid "&Toggle Plot Area\tCTRL+F10" +msgid "&Toggle Plot Area\tCtrl+F10" msgstr "" #: flatcamGUI/FlatCAMGUI.py:431 @@ -5182,15 +5182,15 @@ msgid "&Toggle Grid Snap\tG" msgstr "" #: flatcamGUI/FlatCAMGUI.py:437 -msgid "&Toggle Grid Lines\tALT+G" +msgid "&Toggle Grid Lines\tAlt+G" msgstr "" #: flatcamGUI/FlatCAMGUI.py:439 -msgid "&Toggle Axis\tSHIFT+G" +msgid "&Toggle Axis\tShift+G" msgstr "" #: flatcamGUI/FlatCAMGUI.py:441 -msgid "Toggle Workspace\tSHIFT+W" +msgid "Toggle Workspace\tShift+W" msgstr "" #: flatcamGUI/FlatCAMGUI.py:446 @@ -5290,7 +5290,7 @@ msgid "Paint Tool\tI" msgstr "" #: flatcamGUI/FlatCAMGUI.py:543 -msgid "Transform Tool\tALT+R" +msgid "Transform Tool\tAlt+R" msgstr "" #: flatcamGUI/FlatCAMGUI.py:547 @@ -5354,7 +5354,7 @@ msgid "Add Region\tN" msgstr "" #: flatcamGUI/FlatCAMGUI.py:598 -msgid "Poligonize\tALT+N" +msgid "Poligonize\tAlt+N" msgstr "" #: flatcamGUI/FlatCAMGUI.py:600 @@ -5374,15 +5374,15 @@ msgid "Scale\tS" msgstr "" #: flatcamGUI/FlatCAMGUI.py:608 -msgid "Mark Area\tALT+A" +msgid "Mark Area\tAlt+A" msgstr "" #: flatcamGUI/FlatCAMGUI.py:610 -msgid "Eraser\tCTRL+E" +msgid "Eraser\tCtrl+E" msgstr "" #: flatcamGUI/FlatCAMGUI.py:612 -msgid "Transform\tALT+R" +msgid "Transform\tAlt+R" msgstr "" #: flatcamGUI/FlatCAMGUI.py:639 @@ -12253,7 +12253,7 @@ msgid "" "\n" "The coordinates set can be obtained:\n" "- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" -"- press SHIFT key and left mouse clicking on canvas. Then CTRL+V in the " +"- press SHIFT key and left mouse clicking on canvas. Then Ctrl+V in the " "field.\n" "- press SHIFT key and left mouse clicking on canvas. Then RMB click in the " "field and click Paste.\n" diff --git a/locale/pt_BR/LC_MESSAGES/strings.po b/locale/pt_BR/LC_MESSAGES/strings.po index 9e753cf7..15a1b23f 100644 --- a/locale/pt_BR/LC_MESSAGES/strings.po +++ b/locale/pt_BR/LC_MESSAGES/strings.po @@ -5241,8 +5241,8 @@ msgid "File" msgstr "Arquivo" #: flatcamGUI/FlatCAMGUI.py:69 -msgid "&New Project ...\tCTRL+N" -msgstr "&Novo Projeto ...\tCTRL+N" +msgid "&New Project ...\tCtrl+N" +msgstr "&Novo Projeto ...\tCtrl+N" #: flatcamGUI/FlatCAMGUI.py:71 msgid "Will create a new, blank project" @@ -5294,12 +5294,12 @@ msgid "Open &Project ..." msgstr "Abrir &Projeto ..." #: flatcamGUI/FlatCAMGUI.py:109 flatcamGUI/FlatCAMGUI.py:4121 -msgid "Open &Gerber ...\tCTRL+G" -msgstr "Abrir &Gerber ...\tCTRL+G" +msgid "Open &Gerber ...\tCtrl+G" +msgstr "Abrir &Gerber ...\tCtrl+G" #: flatcamGUI/FlatCAMGUI.py:114 flatcamGUI/FlatCAMGUI.py:4126 -msgid "Open &Excellon ...\tCTRL+E" -msgstr "Abrir &Excellon ...\tCTRL+E" +msgid "Open &Excellon ...\tCtrl+E" +msgstr "Abrir &Excellon ...\tCtrl+E" #: flatcamGUI/FlatCAMGUI.py:118 flatcamGUI/FlatCAMGUI.py:4131 msgid "Open G-&Code ..." @@ -5450,8 +5450,8 @@ msgid "&Save Project ..." msgstr "&Salvar Projeto ..." #: flatcamGUI/FlatCAMGUI.py:256 -msgid "Save Project &As ...\tCTRL+S" -msgstr "S&alvar Projeto Como ...\tCTRL+S" +msgid "Save Project &As ...\tCtrl+S" +msgstr "S&alvar Projeto Como ...\tCtrl+S" #: flatcamGUI/FlatCAMGUI.py:261 msgid "Save Project C&opy ..." @@ -5471,8 +5471,8 @@ msgid "Edit Object\tE" msgstr "Editar Objeto\tE" #: flatcamGUI/FlatCAMGUI.py:285 -msgid "Close Editor\tCTRL+S" -msgstr "Fechar Editor\tCTRL+S" +msgid "Close Editor\tCtrl+S" +msgstr "Fechar Editor\tCtrl+S" #: flatcamGUI/FlatCAMGUI.py:294 msgid "Conversion" @@ -5545,8 +5545,8 @@ msgid "Convert Any to Gerber" msgstr "Converter Qualquer para Gerber" #: flatcamGUI/FlatCAMGUI.py:341 -msgid "&Copy\tCTRL+C" -msgstr "&Copiar\tCTRL+C" +msgid "&Copy\tCtrl+C" +msgstr "&Copiar\tCtrl+C" #: flatcamGUI/FlatCAMGUI.py:346 msgid "&Delete\tDEL" @@ -5565,28 +5565,28 @@ msgid "Toggle Units\tQ" msgstr "Alternar Unidades\tQ" #: flatcamGUI/FlatCAMGUI.py:360 -msgid "&Select All\tCTRL+A" -msgstr "&Selecionar Tudo\tCTRL+A" +msgid "&Select All\tCtrl+A" +msgstr "&Selecionar Tudo\tCtrl+A" #: flatcamGUI/FlatCAMGUI.py:365 -msgid "&Preferences\tSHIFT+P" -msgstr "&Preferências\tSHIFT+P" +msgid "&Preferences\tShift+P" +msgstr "&Preferências\tShift+P" #: flatcamGUI/FlatCAMGUI.py:371 flatcamTools/ToolProperties.py:153 msgid "Options" msgstr "Opções" #: flatcamGUI/FlatCAMGUI.py:373 -msgid "&Rotate Selection\tSHIFT+(R)" -msgstr "Gi&rar Seleção\tSHIFT+(R)" +msgid "&Rotate Selection\tShift+(R)" +msgstr "Gi&rar Seleção\tShift+(R)" #: flatcamGUI/FlatCAMGUI.py:378 -msgid "&Skew on X axis\tSHIFT+X" -msgstr "Inclinar no eixo X\tSHIFT+X" +msgid "&Skew on X axis\tShift+X" +msgstr "Inclinar no eixo X\tShift+X" #: flatcamGUI/FlatCAMGUI.py:380 -msgid "S&kew on Y axis\tSHIFT+Y" -msgstr "Inclinar no eixo Y\tSHIFT+Y" +msgid "S&kew on Y axis\tShift+Y" +msgstr "Inclinar no eixo Y\tShift+Y" #: flatcamGUI/FlatCAMGUI.py:385 msgid "Flip on &X axis\tX" @@ -5597,28 +5597,28 @@ msgid "Flip on &Y axis\tY" msgstr "Espelhar no eixo &Y\tY" #: flatcamGUI/FlatCAMGUI.py:392 -msgid "View source\tALT+S" -msgstr "Ver fonte\tALT+S" +msgid "View source\tAlt+S" +msgstr "Ver fonte\tAlt+S" #: flatcamGUI/FlatCAMGUI.py:394 -msgid "Tools DataBase\tCTRL+D" -msgstr "Banco de Dados de Ferramentas\tCTRL+D" +msgid "Tools DataBase\tCtrl+D" +msgstr "Banco de Dados de Ferramentas\tCtrl+D" #: flatcamGUI/FlatCAMGUI.py:401 flatcamGUI/FlatCAMGUI.py:2060 msgid "View" msgstr "Ver" #: flatcamGUI/FlatCAMGUI.py:403 -msgid "Enable all plots\tALT+1" -msgstr "Habilitar todos os gráficos\tALT+1" +msgid "Enable all plots\tAlt+1" +msgstr "Habilitar todos os gráficos\tAlt+1" #: flatcamGUI/FlatCAMGUI.py:405 -msgid "Disable all plots\tALT+2" -msgstr "Desabilitar todos os gráficos\tALT+2" +msgid "Disable all plots\tAlt+2" +msgstr "Desabilitar todos os gráficos\tAlt+2" #: flatcamGUI/FlatCAMGUI.py:407 -msgid "Disable non-selected\tALT+3" -msgstr "Desabilitar os não selecionados\tALT+3" +msgid "Disable non-selected\tAlt+3" +msgstr "Desabilitar os não selecionados\tAlt+3" #: flatcamGUI/FlatCAMGUI.py:411 msgid "&Zoom Fit\tV" @@ -5637,16 +5637,16 @@ msgid "Redraw All\tF5" msgstr "Redesenha Todos\tF5" #: flatcamGUI/FlatCAMGUI.py:424 -msgid "Toggle Code Editor\tSHIFT+E" -msgstr "Alternar o Editor de Códigos\tSHIFT+E" +msgid "Toggle Code Editor\tShift+E" +msgstr "Alternar o Editor de Códigos\tShift+E" #: flatcamGUI/FlatCAMGUI.py:427 -msgid "&Toggle FullScreen\tALT+F10" -msgstr "Alternar &Tela Cheia\tALT+F10" +msgid "&Toggle FullScreen\tAlt+F10" +msgstr "Alternar &Tela Cheia\tAlt+F10" #: flatcamGUI/FlatCAMGUI.py:429 -msgid "&Toggle Plot Area\tCTRL+F10" -msgstr "Al&ternar Área de Gráficos\tCTRL+F10" +msgid "&Toggle Plot Area\tCtrl+F10" +msgstr "Al&ternar Área de Gráficos\tCtrl+F10" #: flatcamGUI/FlatCAMGUI.py:431 msgid "&Toggle Project/Sel/Tool\t`" @@ -5657,16 +5657,16 @@ msgid "&Toggle Grid Snap\tG" msgstr "Al&ternar Encaixe na Grade\tG" #: flatcamGUI/FlatCAMGUI.py:437 -msgid "&Toggle Grid Lines\tALT+G" -msgstr "Al&ternar Encaixe na Grade\tALT+G" +msgid "&Toggle Grid Lines\tAlt+G" +msgstr "Al&ternar Encaixe na Grade\tAlt+G" #: flatcamGUI/FlatCAMGUI.py:439 -msgid "&Toggle Axis\tSHIFT+G" -msgstr "Al&ternar Eixo\tSHIFT+G" +msgid "&Toggle Axis\tShift+G" +msgstr "Al&ternar Eixo\tShift+G" #: flatcamGUI/FlatCAMGUI.py:441 -msgid "Toggle Workspace\tSHIFT+W" -msgstr "Alternar Área de Trabalho\tSHIFT+W" +msgid "Toggle Workspace\tShift+W" +msgstr "Alternar Área de Trabalho\tShift+W" #: flatcamGUI/FlatCAMGUI.py:446 msgid "Objects" @@ -5765,8 +5765,8 @@ msgid "Paint Tool\tI" msgstr "Ferramenta de Pintura\tI" #: flatcamGUI/FlatCAMGUI.py:543 -msgid "Transform Tool\tALT+R" -msgstr "Ferramenta de Transformação\tALT+R" +msgid "Transform Tool\tAlt+R" +msgstr "Ferramenta de Transformação\tAlt+R" #: flatcamGUI/FlatCAMGUI.py:547 msgid "Toggle Corner Snap\tK" @@ -5829,8 +5829,8 @@ msgid "Add Region\tN" msgstr "Adicionar Região\tN" #: flatcamGUI/FlatCAMGUI.py:598 -msgid "Poligonize\tALT+N" -msgstr "Poligonizar\tALT+N" +msgid "Poligonize\tAlt+N" +msgstr "Poligonizar\tAlt+N" #: flatcamGUI/FlatCAMGUI.py:600 msgid "Add SemiDisc\tE" @@ -5849,16 +5849,16 @@ msgid "Scale\tS" msgstr "Escala\tS" #: flatcamGUI/FlatCAMGUI.py:608 -msgid "Mark Area\tALT+A" -msgstr "Marcar Área\tALT+A" +msgid "Mark Area\tAlt+A" +msgstr "Marcar Área\tAlt+A" #: flatcamGUI/FlatCAMGUI.py:610 -msgid "Eraser\tCTRL+E" -msgstr "Borracha\tCTRL+E" +msgid "Eraser\tCtrl+E" +msgstr "Borracha\tCtrl+E" #: flatcamGUI/FlatCAMGUI.py:612 -msgid "Transform\tALT+R" -msgstr "Transformar\tALT+R" +msgid "Transform\tAlt+R" +msgstr "Transformar\tAlt+R" #: flatcamGUI/FlatCAMGUI.py:639 msgid "Enable Plot" @@ -13846,7 +13846,7 @@ msgid "" "\n" "The coordinates set can be obtained:\n" "- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" -"- press SHIFT key and left mouse clicking on canvas. Then CTRL+V in the " +"- press SHIFT key and left mouse clicking on canvas. Then Ctrl+V in the " "field.\n" "- press SHIFT key and left mouse clicking on canvas. Then RMB click in the " "field and click Paste.\n" @@ -17554,8 +17554,8 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente." #~ "\n" #~ " " -#~ msgid "Run Script ...\tSHIFT+S" -#~ msgstr "Executar Script ...\tSHIFT+S" +#~ msgid "Run Script ...\tShift+S" +#~ msgstr "Executar Script ...\tShift+S" #~ msgid "" #~ "FlatCAM
Version {version} {beta} ({date}) - " @@ -17724,39 +17724,39 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente." #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+A\n" +#~ " Ctrl+A\n" #~ "  Select All\n" #~ " \n" #~ " \n" -#~ " CTRL+C\n" +#~ " Ctrl+C\n" #~ "  Copy Obj\n" #~ " \n" #~ " \n" -#~ " CTRL+E\n" +#~ " Ctrl+E\n" #~ "  Open Excellon File\n" #~ " \n" #~ " \n" -#~ " CTRL+G\n" +#~ " Ctrl+G\n" #~ "  Open Gerber File\n" #~ " \n" #~ " \n" -#~ " CTRL+N\n" +#~ " Ctrl+N\n" #~ "  New Project\n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Measurement Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+O\n" +#~ " Ctrl+O\n" #~ "  Open Project\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Project As\n" #~ " \n" #~ " \n" -#~ " CTRL+F10\n" +#~ " Ctrl+F10\n" #~ "  Toggle Plot Area\n" #~ " \n" #~ " \n" @@ -17764,39 +17764,39 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente." #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+C\n" +#~ " Shift+C\n" #~ "  Copy Obj_Name\n" #~ " \n" #~ " \n" -#~ " SHIFT+E\n" +#~ " Shift+E\n" #~ "  Toggle Code Editor\n" #~ " \n" #~ " \n" -#~ " SHIFT+G\n" +#~ " Shift+G\n" #~ "  Toggle the axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+P\n" +#~ " Shift+P\n" #~ "  Open Preferences Window\n" #~ " \n" #~ " \n" -#~ " SHIFT+R\n" +#~ " Shift+R\n" #~ "  Rotate by 90 degree CCW\n" #~ " \n" #~ " \n" -#~ " SHIFT+S\n" +#~ " Shift+S\n" #~ "  Run a Script\n" #~ " \n" #~ " \n" -#~ " SHIFT+W\n" +#~ " Shift+W\n" #~ "  Toggle the workspace\n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Skew on X axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Skew on Y axis\n" #~ " \n" #~ " \n" @@ -17804,59 +17804,59 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente." #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+C\n" +#~ " Alt+C\n" #~ "  Calculators Tool\n" #~ " \n" #~ " \n" -#~ " ALT+D\n" +#~ " Alt+D\n" #~ "  2-Sided PCB Tool\n" #~ " \n" #~ " \n" -#~ " ALT+K\n" +#~ " Alt+K\n" #~ "  Solder Paste Dispensing Tool\n" #~ " \n" #~ " \n" -#~ " ALT+L\n" +#~ " Alt+L\n" #~ "  Film PCB Tool\n" #~ " \n" #~ " \n" -#~ " ALT+N\n" +#~ " Alt+N\n" #~ "  Non-Copper Clearing Tool\n" #~ " \n" #~ " \n" -#~ " ALT+P\n" +#~ " Alt+P\n" #~ "  Paint Area Tool\n" #~ " \n" #~ " \n" -#~ " ALT+Q\n" +#~ " Alt+Q\n" #~ "  PDF Import Tool\n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Transformations Tool\n" #~ " \n" #~ " \n" -#~ " ALT+S\n" +#~ " Alt+S\n" #~ "  View File Source\n" #~ " \n" #~ " \n" -#~ " ALT+U\n" +#~ " Alt+U\n" #~ "  Cutout PCB Tool\n" #~ " \n" #~ " \n" -#~ " ALT+1\n" +#~ " Alt+1\n" #~ "  Enable all Plots\n" #~ " \n" #~ " \n" -#~ " ALT+2\n" +#~ " Alt+2\n" #~ "  Disable all Plots\n" #~ " \n" #~ " \n" -#~ " ALT+3\n" +#~ " Alt+3\n" #~ "  Disable Non-selected Plots\n" #~ " \n" #~ " \n" -#~ " ALT+F10\n" +#~ " Alt+F10\n" #~ "  Toggle Full Screen\n" #~ " \n" #~ " \n" @@ -17864,7 +17864,7 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente." #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+ALT+XCtrl+Alt+X\n" #~ "  Abort current task (gracefully)\n" #~ " \n" @@ -18016,39 +18016,39 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente." #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+A\n" +#~ " Ctrl+A\n" #~ "  Seleciona Todos\n" #~ " \n" #~ " \n" -#~ " CTRL+C\n" +#~ " Ctrl+C\n" #~ "  Copiar Objeto\n" #~ " \n" #~ " \n" -#~ " CTRL+E\n" +#~ " Ctrl+E\n" #~ "  Abrir Arquivo Excellon\n" #~ " \n" #~ " \n" -#~ " CTRL+G\n" +#~ " Ctrl+G\n" #~ "  Abrir Arquivo Gerber\n" #~ " \n" #~ " \n" -#~ " CTRL+N\n" +#~ " Ctrl+N\n" #~ "  Novo Projeto\n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Ferramenta de Medição\n" #~ " \n" #~ " \n" -#~ " CTRL+O\n" +#~ " Ctrl+O\n" #~ "  Abrir Projeto\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Salvar Projeto Como\n" #~ " \n" #~ " \n" -#~ " CTRL+F10\n" +#~ " Ctrl+F10\n" #~ "  Alternar Área de Gráfico\n" #~ " \n" #~ " \n" @@ -18056,39 +18056,39 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente." #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+C\n" +#~ " Shift+C\n" #~ "  Copiar Obj_Name\n" #~ " \n" #~ " \n" -#~ " SHIFT+E\n" +#~ " Shift+E\n" #~ "  Alterna Editor de Código\n" #~ " \n" #~ " \n" -#~ " SHIFT+G\n" +#~ " Shift+G\n" #~ "  Alterna o Eixo\n" #~ " \n" #~ " \n" -#~ " SHIFT+P\n" +#~ " Shift+P\n" #~ "  Abre Janela de Preferências\n" #~ " \n" #~ " \n" -#~ " SHIFT+R\n" +#~ " Shift+R\n" #~ "  Gira 90 graus antihorário\n" #~ " \n" #~ " \n" -#~ " SHIFT+S\n" +#~ " Shift+S\n" #~ "  Executa um Script\n" #~ " \n" #~ " \n" -#~ " SHIFT+W\n" +#~ " Shift+W\n" #~ "  Alterna o Local de Trabalho\n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Inclina no Eixo X\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Inclina no Eixo Y\n" #~ " \n" #~ " \n" @@ -18096,60 +18096,60 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente." #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+C\n" +#~ " Alt+C\n" #~ "  Calculadoras\n" #~ " \n" #~ " \n" -#~ " ALT+D\n" +#~ " Alt+D\n" #~ "  Ferramenta PCB 2-Faces\n" #~ " \n" #~ " \n" -#~ " ALT+K\n" +#~ " Alt+K\n" #~ "  Ferramenta Pasta de Solda\n" #~ " \n" #~ " \n" -#~ " ALT+L\n" +#~ " Alt+L\n" #~ "  Ferramenta Filme PCB\n" #~ " \n" #~ " \n" -#~ " ALT+N\n" +#~ " Alt+N\n" #~ "  Ferramenta Retirar Cobre (NCC)\n" #~ " \n" #~ " \n" -#~ " ALT+P\n" +#~ " Alt+P\n" #~ "  Ferramenta Pintura de Área\n" #~ " \n" #~ " \n" -#~ " ALT+Q\n" +#~ " Alt+Q\n" #~ "  Ferramenta Importar PDF\n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Ferramenta Transformações\n" #~ " \n" #~ " \n" -#~ " ALT+S\n" +#~ " Alt+S\n" #~ "  Ver Arquivo Fonte\n" #~ " \n" #~ " \n" -#~ " ALT+U\n" +#~ " Alt+U\n" #~ "  Ferramenta Recorte PCB\n" #~ " \n" #~ " \n" -#~ " ALT+1\n" +#~ " Alt+1\n" #~ "  Habilita todos os Gráficos\n" #~ " \n" #~ " \n" -#~ " ALT+2\n" +#~ " Alt+2\n" #~ "  Desabilita todos os Gráficos\n" #~ " \n" #~ " \n" -#~ " ALT+3\n" +#~ " Alt+3\n" #~ "  Desabilita todos os Gráficos não " #~ "selecionados\n" #~ " \n" #~ " \n" -#~ " ALT+F10\n" +#~ " Alt+F10\n" #~ "  Alterna Tela Cheia\n" #~ " \n" #~ " \n" @@ -18283,11 +18283,11 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente." #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Skew shape on X axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Skew shape on Y axis\n" #~ " \n" #~ " \n" @@ -18295,15 +18295,15 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente." #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Editor Transformation Tool\n" #~ " \n" #~ " \n" -#~ " ALT+X\n" +#~ " Alt+X\n" #~ "  Offset shape on X axis\n" #~ " \n" #~ " \n" -#~ " ALT+Y\n" +#~ " Alt+Y\n" #~ "  Offset shape on Y axis\n" #~ " \n" #~ " \n" @@ -18311,15 +18311,15 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente." #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Measurement Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" -#~ " CTRL+X\n" +#~ " Ctrl+X\n" #~ "  Polygon Cut Tool\n" #~ " \n" #~ " \n" @@ -18411,7 +18411,7 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente." #~ "  Abort and return to Select\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" @@ -18499,11 +18499,11 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente." #~ "  Abort and return to Select\n" #~ " \n" #~ " \n" -#~ " CTRL+E\n" +#~ " Ctrl+E\n" #~ "  Eraser Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" @@ -18511,15 +18511,15 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente." #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+A\n" +#~ " Alt+A\n" #~ "  Mark Area Tool\n" #~ " \n" #~ " \n" -#~ " ALT+N\n" +#~ " Alt+N\n" #~ "  Poligonize Tool\n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Transformation Tool\n" #~ " \n" #~ " \n" @@ -18620,11 +18620,11 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente." #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Inclina a forma no eixo X\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Inclina a forma no eixo Y\n" #~ " \n" #~ " \n" @@ -18632,16 +18632,16 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente." #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Ferramenta Editor de Transformação\n" #~ " \n" #~ " \n" -#~ " ALT+X\n" +#~ " Alt+X\n" #~ "  Desloca a forma no eixo X\n" #~ " \n" #~ " \n" -#~ " ALT+Y\n" +#~ " Alt+Y\n" #~ "  Desloca a forma no eixo Y\n" #~ " \n" #~ " \n" @@ -18649,15 +18649,15 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente." #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Ferramenta de Medição\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Salvar Objeto e Sair do Editor\n" #~ " \n" #~ " \n" -#~ " CTRL+X\n" +#~ " Ctrl+X\n" #~ "  Ferramenta de Corte de Polígono\n" #~ " \n" #~ " \n" @@ -18754,7 +18754,7 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente." #~ "  Abortar e retornar para a Seleção\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Salvar Objeto e Sair do Editor\n" #~ " \n" #~ " \n" @@ -18843,11 +18843,11 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente." #~ "  Abortar e retornar para a Seleção\n" #~ " \n" #~ " \n" -#~ " CTRL+E\n" +#~ " Ctrl+E\n" #~ "  Ferramenta Apagador\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Salvar Objeto e Sair do Editor\n" #~ " \n" #~ " \n" @@ -18855,15 +18855,15 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente." #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+A\n" +#~ " Alt+A\n" #~ "  Ferramenta Marcar Área\n" #~ " \n" #~ " \n" -#~ " ALT+N\n" +#~ " Alt+N\n" #~ "  Ferramenta Poligonizar\n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Ferramenta Transformação\n" #~ " \n" #~ " \n" diff --git a/locale/ro/LC_MESSAGES/strings.po b/locale/ro/LC_MESSAGES/strings.po index 214423d2..c357e24a 100644 --- a/locale/ro/LC_MESSAGES/strings.po +++ b/locale/ro/LC_MESSAGES/strings.po @@ -5275,8 +5275,8 @@ msgid "File" msgstr "Fişiere" #: flatcamGUI/FlatCAMGUI.py:69 -msgid "&New Project ...\tCTRL+N" -msgstr "&Proiect Nou...\tCTRL+N" +msgid "&New Project ...\tCtrl+N" +msgstr "&Proiect Nou...\tCtrl+N" #: flatcamGUI/FlatCAMGUI.py:71 msgid "Will create a new, blank project" @@ -5328,12 +5328,12 @@ msgid "Open &Project ..." msgstr "Încarcă &Project ..." #: flatcamGUI/FlatCAMGUI.py:109 flatcamGUI/FlatCAMGUI.py:4121 -msgid "Open &Gerber ...\tCTRL+G" -msgstr "Încarcă &Gerber ...\tCTRL+G" +msgid "Open &Gerber ...\tCtrl+G" +msgstr "Încarcă &Gerber ...\tCtrl+G" #: flatcamGUI/FlatCAMGUI.py:114 flatcamGUI/FlatCAMGUI.py:4126 -msgid "Open &Excellon ...\tCTRL+E" -msgstr "Încarcă &Excellon ...\tCTRL+E" +msgid "Open &Excellon ...\tCtrl+E" +msgstr "Încarcă &Excellon ...\tCtrl+E" #: flatcamGUI/FlatCAMGUI.py:118 flatcamGUI/FlatCAMGUI.py:4131 msgid "Open G-&Code ..." @@ -5484,8 +5484,8 @@ msgid "&Save Project ..." msgstr "&Salvează Proiect ..." #: flatcamGUI/FlatCAMGUI.py:256 -msgid "Save Project &As ...\tCTRL+S" -msgstr "Salvează Proiect &ca ...\tCTRL+S" +msgid "Save Project &As ...\tCtrl+S" +msgstr "Salvează Proiect &ca ...\tCtrl+S" #: flatcamGUI/FlatCAMGUI.py:261 msgid "Save Project C&opy ..." @@ -5505,8 +5505,8 @@ msgid "Edit Object\tE" msgstr "Editare Obiect\tE" #: flatcamGUI/FlatCAMGUI.py:285 -msgid "Close Editor\tCTRL+S" -msgstr "Salvează Editor\tCTRL+S" +msgid "Close Editor\tCtrl+S" +msgstr "Salvează Editor\tCtrl+S" #: flatcamGUI/FlatCAMGUI.py:294 msgid "Conversion" @@ -5582,8 +5582,8 @@ msgid "Convert Any to Gerber" msgstr "Converteste Oricare in Gerber" #: flatcamGUI/FlatCAMGUI.py:341 -msgid "&Copy\tCTRL+C" -msgstr "&Copiază\tCTRL+C" +msgid "&Copy\tCtrl+C" +msgstr "&Copiază\tCtrl+C" #: flatcamGUI/FlatCAMGUI.py:346 msgid "&Delete\tDEL" @@ -5602,28 +5602,28 @@ msgid "Toggle Units\tQ" msgstr "Comută Unitati\tQ" #: flatcamGUI/FlatCAMGUI.py:360 -msgid "&Select All\tCTRL+A" -msgstr "&Selectează Tot\tCTRL+A" +msgid "&Select All\tCtrl+A" +msgstr "&Selectează Tot\tCtrl+A" #: flatcamGUI/FlatCAMGUI.py:365 -msgid "&Preferences\tSHIFT+P" -msgstr "&Preferințe\tSHIFT+P" +msgid "&Preferences\tShift+P" +msgstr "&Preferințe\tShift+P" #: flatcamGUI/FlatCAMGUI.py:371 flatcamTools/ToolProperties.py:153 msgid "Options" msgstr "Opțiuni" #: flatcamGUI/FlatCAMGUI.py:373 -msgid "&Rotate Selection\tSHIFT+(R)" -msgstr "&Roteste Selectia\tSHIFT+(R)" +msgid "&Rotate Selection\tShift+(R)" +msgstr "&Roteste Selectia\tShift+(R)" #: flatcamGUI/FlatCAMGUI.py:378 -msgid "&Skew on X axis\tSHIFT+X" -msgstr "&Deformează pe axa X\tSHIFT+X" +msgid "&Skew on X axis\tShift+X" +msgstr "&Deformează pe axa X\tShift+X" #: flatcamGUI/FlatCAMGUI.py:380 -msgid "S&kew on Y axis\tSHIFT+Y" -msgstr "Deformează pe axa Y\tSHIFT+Y" +msgid "S&kew on Y axis\tShift+Y" +msgstr "Deformează pe axa Y\tShift+Y" #: flatcamGUI/FlatCAMGUI.py:385 msgid "Flip on &X axis\tX" @@ -5634,28 +5634,28 @@ msgid "Flip on &Y axis\tY" msgstr "Oglindește pe axa &Y\tY" #: flatcamGUI/FlatCAMGUI.py:392 -msgid "View source\tALT+S" -msgstr "Vezi sursa\tALT+S" +msgid "View source\tAlt+S" +msgstr "Vezi sursa\tAlt+S" #: flatcamGUI/FlatCAMGUI.py:394 -msgid "Tools DataBase\tCTRL+D" -msgstr "Baza de data Unelte\tCTRL+D" +msgid "Tools DataBase\tCtrl+D" +msgstr "Baza de data Unelte\tCtrl+D" #: flatcamGUI/FlatCAMGUI.py:401 flatcamGUI/FlatCAMGUI.py:2060 msgid "View" msgstr "Vizualizare" #: flatcamGUI/FlatCAMGUI.py:403 -msgid "Enable all plots\tALT+1" -msgstr "Activează toate afişările\tALT+1" +msgid "Enable all plots\tAlt+1" +msgstr "Activează toate afişările\tAlt+1" #: flatcamGUI/FlatCAMGUI.py:405 -msgid "Disable all plots\tALT+2" -msgstr "Dezactivează toate afişările\tALT+2" +msgid "Disable all plots\tAlt+2" +msgstr "Dezactivează toate afişările\tAlt+2" #: flatcamGUI/FlatCAMGUI.py:407 -msgid "Disable non-selected\tALT+3" -msgstr "Dezactivează non-selectate\tALT+3" +msgid "Disable non-selected\tAlt+3" +msgstr "Dezactivează non-selectate\tAlt+3" #: flatcamGUI/FlatCAMGUI.py:411 msgid "&Zoom Fit\tV" @@ -5674,16 +5674,16 @@ msgid "Redraw All\tF5" msgstr "Reafisare Toate\tF5" #: flatcamGUI/FlatCAMGUI.py:424 -msgid "Toggle Code Editor\tSHIFT+E" -msgstr "Comută Editorul de cod\tSHIFT+E" +msgid "Toggle Code Editor\tShift+E" +msgstr "Comută Editorul de cod\tShift+E" #: flatcamGUI/FlatCAMGUI.py:427 -msgid "&Toggle FullScreen\tALT+F10" -msgstr "Comută FullScreen\tALT+F10" +msgid "&Toggle FullScreen\tAlt+F10" +msgstr "Comută FullScreen\tAlt+F10" #: flatcamGUI/FlatCAMGUI.py:429 -msgid "&Toggle Plot Area\tCTRL+F10" -msgstr "Comută Aria de Afișare\tCTRL+F10" +msgid "&Toggle Plot Area\tCtrl+F10" +msgstr "Comută Aria de Afișare\tCtrl+F10" #: flatcamGUI/FlatCAMGUI.py:431 msgid "&Toggle Project/Sel/Tool\t`" @@ -5694,16 +5694,16 @@ msgid "&Toggle Grid Snap\tG" msgstr "Comută Grid\tG" #: flatcamGUI/FlatCAMGUI.py:437 -msgid "&Toggle Grid Lines\tALT+G" -msgstr "Comută Linii Grid\tALT+G" +msgid "&Toggle Grid Lines\tAlt+G" +msgstr "Comută Linii Grid\tAlt+G" #: flatcamGUI/FlatCAMGUI.py:439 -msgid "&Toggle Axis\tSHIFT+G" -msgstr "Comută Axe\tSHIFT+G" +msgid "&Toggle Axis\tShift+G" +msgstr "Comută Axe\tShift+G" #: flatcamGUI/FlatCAMGUI.py:441 -msgid "Toggle Workspace\tSHIFT+W" -msgstr "Comută Suprafata de lucru\tSHIFT+W" +msgid "Toggle Workspace\tShift+W" +msgstr "Comută Suprafata de lucru\tShift+W" #: flatcamGUI/FlatCAMGUI.py:446 msgid "Objects" @@ -5802,8 +5802,8 @@ msgid "Paint Tool\tI" msgstr "Unealta Paint\tI" #: flatcamGUI/FlatCAMGUI.py:543 -msgid "Transform Tool\tALT+R" -msgstr "Unealta Transformare\tALT+R" +msgid "Transform Tool\tAlt+R" +msgstr "Unealta Transformare\tAlt+R" #: flatcamGUI/FlatCAMGUI.py:547 msgid "Toggle Corner Snap\tK" @@ -5866,8 +5866,8 @@ msgid "Add Region\tN" msgstr "Adaugă Regiune\tN" #: flatcamGUI/FlatCAMGUI.py:598 -msgid "Poligonize\tALT+N" -msgstr "Poligonizare\tALT+N" +msgid "Poligonize\tAlt+N" +msgstr "Poligonizare\tAlt+N" #: flatcamGUI/FlatCAMGUI.py:600 msgid "Add SemiDisc\tE" @@ -5886,16 +5886,16 @@ msgid "Scale\tS" msgstr "Scalare\tS" #: flatcamGUI/FlatCAMGUI.py:608 -msgid "Mark Area\tALT+A" -msgstr "Marchează aria\tALT+A" +msgid "Mark Area\tAlt+A" +msgstr "Marchează aria\tAlt+A" #: flatcamGUI/FlatCAMGUI.py:610 -msgid "Eraser\tCTRL+E" -msgstr "Radieră\tCTRL+E" +msgid "Eraser\tCtrl+E" +msgstr "Radieră\tCtrl+E" #: flatcamGUI/FlatCAMGUI.py:612 -msgid "Transform\tALT+R" -msgstr "Unealta Transformare\tALT+R" +msgid "Transform\tAlt+R" +msgstr "Unealta Transformare\tAlt+R" #: flatcamGUI/FlatCAMGUI.py:639 msgid "Enable Plot" @@ -14024,7 +14024,7 @@ msgid "" "\n" "The coordinates set can be obtained:\n" "- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" -"- press SHIFT key and left mouse clicking on canvas. Then CTRL+V in the " +"- press SHIFT key and left mouse clicking on canvas. Then Ctrl+V in the " "field.\n" "- press SHIFT key and left mouse clicking on canvas. Then RMB click in the " "field and click Paste.\n" @@ -17836,8 +17836,8 @@ msgstr "" #~ "\n" #~ " " -#~ msgid "Run Script ...\tSHIFT+S" -#~ msgstr "Rulează Script ...\tSHIFT+S" +#~ msgid "Run Script ...\tShift+S" +#~ msgstr "Rulează Script ...\tShift+S" #~ msgid "" #~ "FlatCAM
Version {version} {beta} ({date}) - " @@ -18010,39 +18010,39 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+A\n" +#~ " Ctrl+A\n" #~ "  Select All\n" #~ " \n" #~ " \n" -#~ " CTRL+C\n" +#~ " Ctrl+C\n" #~ "  Copy Obj\n" #~ " \n" #~ " \n" -#~ " CTRL+E\n" +#~ " Ctrl+E\n" #~ "  Open Excellon File\n" #~ " \n" #~ " \n" -#~ " CTRL+G\n" +#~ " Ctrl+G\n" #~ "  Open Gerber File\n" #~ " \n" #~ " \n" -#~ " CTRL+N\n" +#~ " Ctrl+N\n" #~ "  New Project\n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Measurement Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+O\n" +#~ " Ctrl+O\n" #~ "  Open Project\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Project As\n" #~ " \n" #~ " \n" -#~ " CTRL+F10\n" +#~ " Ctrl+F10\n" #~ "  Toggle Plot Area\n" #~ " \n" #~ " \n" @@ -18050,39 +18050,39 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+C\n" +#~ " Shift+C\n" #~ "  Copy Obj_Name\n" #~ " \n" #~ " \n" -#~ " SHIFT+E\n" +#~ " Shift+E\n" #~ "  Toggle Code Editor\n" #~ " \n" #~ " \n" -#~ " SHIFT+G\n" +#~ " Shift+G\n" #~ "  Toggle the axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+P\n" +#~ " Shift+P\n" #~ "  Open Preferences Window\n" #~ " \n" #~ " \n" -#~ " SHIFT+R\n" +#~ " Shift+R\n" #~ "  Rotate by 90 degree CCW\n" #~ " \n" #~ " \n" -#~ " SHIFT+S\n" +#~ " Shift+S\n" #~ "  Run a Script\n" #~ " \n" #~ " \n" -#~ " SHIFT+W\n" +#~ " Shift+W\n" #~ "  Toggle the workspace\n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Skew on X axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Skew on Y axis\n" #~ " \n" #~ " \n" @@ -18090,59 +18090,59 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+C\n" +#~ " Alt+C\n" #~ "  Calculators Tool\n" #~ " \n" #~ " \n" -#~ " ALT+D\n" +#~ " Alt+D\n" #~ "  2-Sided PCB Tool\n" #~ " \n" #~ " \n" -#~ " ALT+K\n" +#~ " Alt+K\n" #~ "  Solder Paste Dispensing Tool\n" #~ " \n" #~ " \n" -#~ " ALT+L\n" +#~ " Alt+L\n" #~ "  Film PCB Tool\n" #~ " \n" #~ " \n" -#~ " ALT+N\n" +#~ " Alt+N\n" #~ "  Non-Copper Clearing Tool\n" #~ " \n" #~ " \n" -#~ " ALT+P\n" +#~ " Alt+P\n" #~ "  Paint Area Tool\n" #~ " \n" #~ " \n" -#~ " ALT+Q\n" +#~ " Alt+Q\n" #~ "  PDF Import Tool\n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Transformations Tool\n" #~ " \n" #~ " \n" -#~ " ALT+S\n" +#~ " Alt+S\n" #~ "  View File Source\n" #~ " \n" #~ " \n" -#~ " ALT+U\n" +#~ " Alt+U\n" #~ "  Cutout PCB Tool\n" #~ " \n" #~ " \n" -#~ " ALT+1\n" +#~ " Alt+1\n" #~ "  Enable all Plots\n" #~ " \n" #~ " \n" -#~ " ALT+2\n" +#~ " Alt+2\n" #~ "  Disable all Plots\n" #~ " \n" #~ " \n" -#~ " ALT+3\n" +#~ " Alt+3\n" #~ "  Disable Non-selected Plots\n" #~ " \n" #~ " \n" -#~ " ALT+F10\n" +#~ " Alt+F10\n" #~ "  Toggle Full Screen\n" #~ " \n" #~ " \n" @@ -18150,7 +18150,7 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+ALT+XCtrl+Alt+X\n" #~ "  Abort current task (gracefully)\n" #~ " \n" @@ -18304,39 +18304,39 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+A\n" +#~ " Ctrl+A\n" #~ "  Selectează Tot\n" #~ " \n" #~ " \n" -#~ " CTRL+C\n" +#~ " Ctrl+C\n" #~ "  Copiază Obiect\n" #~ " \n" #~ " \n" -#~ " CTRL+E\n" +#~ " Ctrl+E\n" #~ "  Deschide fişier Excellon\n" #~ " \n" #~ " \n" -#~ " CTRL+G\n" +#~ " Ctrl+G\n" #~ "  Deschide fişier Gerber\n" #~ " \n" #~ " \n" -#~ " CTRL+N\n" +#~ " Ctrl+N\n" #~ "  Proiect Nou\n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Unealta de Masurare\n" #~ " \n" #~ " \n" -#~ " CTRL+O\n" +#~ " Ctrl+O\n" #~ "  Deschide Proiect\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Salvează Proiect ca\n" #~ " \n" #~ " \n" -#~ " CTRL+F10\n" +#~ " Ctrl+F10\n" #~ "  Comută Aria de Afișare\n" #~ " \n" #~ " \n" @@ -18344,39 +18344,39 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+C\n" +#~ " Shift+C\n" #~ "  Copiază Nume Obiect\n" #~ " \n" #~ " \n" -#~ " SHIFT+E\n" +#~ " Shift+E\n" #~ "  Comută Editor Cod\n" #~ " \n" #~ " \n" -#~ " SHIFT+G\n" +#~ " Shift+G\n" #~ "  Comută Axele\n" #~ " \n" #~ " \n" -#~ " SHIFT+P\n" +#~ " Shift+P\n" #~ "  Deschide Preferințe\n" #~ " \n" #~ " \n" -#~ " SHIFT+R\n" +#~ " Shift+R\n" #~ "  Rotește cu 90 grade CCW\n" #~ " \n" #~ " \n" -#~ " SHIFT+S\n" +#~ " Shift+S\n" #~ "  Rulează un Script\n" #~ " \n" #~ " \n" -#~ " SHIFT+W\n" +#~ " Shift+W\n" #~ "  Comută Spatiul de Lucru\n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Deformează pe axa X\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Deformează pe axa Y\n" #~ " \n" #~ " \n" @@ -18384,60 +18384,60 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+C\n" +#~ " Alt+C\n" #~ "  Unealta Calculatoare\n" #~ " \n" #~ " \n" -#~ " ALT+D\n" +#~ " Alt+D\n" #~ "  Unealta 2-Layer\n" #~ " \n" #~ " \n" -#~ " ALT+K\n" +#~ " Alt+K\n" #~ "  Unealta Dispensare Pasta Fludor\n" #~ " \n" #~ " \n" -#~ " ALT+L\n" +#~ " Alt+L\n" #~ "  Unealta Film PCB\n" #~ " \n" #~ " \n" -#~ " ALT+N\n" +#~ " Alt+N\n" #~ "  Unealta de curățare zone cupru\n" #~ " \n" #~ " \n" -#~ " ALT+P\n" +#~ " Alt+P\n" #~ "  Unealta Paint\n" #~ " \n" #~ " \n" -#~ " ALT+Q\n" +#~ " Alt+Q\n" #~ "  Unealta de import PDF\n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Unealta Transformări\n" #~ " \n" #~ " \n" -#~ " ALT+S\n" +#~ " Alt+S\n" #~ "  Vizualiz. Codul Sursa\n" #~ " \n" #~ " \n" -#~ " ALT+U\n" +#~ " Alt+U\n" #~ "  Unealta de Decupare\n" #~ " \n" #~ " \n" -#~ " ALT+1\n" +#~ " Alt+1\n" #~ "  Activează toate Afișările\n" #~ " \n" #~ " \n" -#~ " ALT+2\n" +#~ " Alt+2\n" #~ "  Dezactivează toate afişările/td>\n" #~ " \n" #~ " \n" -#~ " ALT+3\n" +#~ " Alt+3\n" #~ "  Dezactivează toate afişările " #~ "neselectate\n" #~ " \n" #~ " \n" -#~ " ALT+F10\n" +#~ " Alt+F10\n" #~ "  Comută Full Screen\n" #~ " \n" #~ " \n" @@ -18445,7 +18445,7 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+ALT+XCtrl+Alt+X\n" #~ "  Anuleaza taskul curent\n" #~ " \n" @@ -18580,11 +18580,11 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Skew shape on X axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Skew shape on Y axis\n" #~ " \n" #~ " \n" @@ -18592,15 +18592,15 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Editor Transformation Tool\n" #~ " \n" #~ " \n" -#~ " ALT+X\n" +#~ " Alt+X\n" #~ "  Offset shape on X axis\n" #~ " \n" #~ " \n" -#~ " ALT+Y\n" +#~ " Alt+Y\n" #~ "  Offset shape on Y axis\n" #~ " \n" #~ " \n" @@ -18608,15 +18608,15 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Measurement Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" -#~ " CTRL+X\n" +#~ " Ctrl+X\n" #~ "  Polygon Cut Tool\n" #~ " \n" #~ " \n" @@ -18708,7 +18708,7 @@ msgstr "" #~ "  Abort and return to Select\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" @@ -18796,11 +18796,11 @@ msgstr "" #~ "  Abort and return to Select\n" #~ " \n" #~ " \n" -#~ " CTRL+E\n" +#~ " Ctrl+E\n" #~ "  Eraser Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" @@ -18808,15 +18808,15 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+A\n" +#~ " Alt+A\n" #~ "  Mark Area Tool\n" #~ " \n" #~ " \n" -#~ " ALT+N\n" +#~ " Alt+N\n" #~ "  Poligonize Tool\n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Transformation Tool\n" #~ " \n" #~ " \n" @@ -18915,11 +18915,11 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Deformeaza pe axa X\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Deformeaza pe axa Y\n" #~ " \n" #~ " \n" @@ -18927,15 +18927,15 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Unealta Transformare din Editor\n" #~ " \n" #~ " \n" -#~ " ALT+X\n" +#~ " Alt+X\n" #~ "  Deplaseaza pe axa X\n" #~ " \n" #~ " \n" -#~ " ALT+Y\n" +#~ " Alt+Y\n" #~ "  Deplaseaza pe axa Y\n" #~ " \n" #~ " \n" @@ -18943,15 +18943,15 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Unealta de masurare\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Inchide Editorul\n" #~ " \n" #~ " \n" -#~ " CTRL+X\n" +#~ " Ctrl+X\n" #~ "  Unealta de Decupare Poligoane\n" #~ " \n" #~ " \n" @@ -19048,7 +19048,7 @@ msgstr "" #~ "Selectie\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Inchide Editorul\n" #~ " \n" #~ " \n" @@ -19134,11 +19134,11 @@ msgstr "" #~ "td>\n" #~ " \n" #~ " \n" -#~ " CTRL+E\n" +#~ " Ctrl+E\n" #~ "  Unealta Radieră\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Inchide Editorul\n" #~ " \n" #~ " \n" @@ -19146,15 +19146,15 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+A\n" +#~ " Alt+A\n" #~ "  Unealta Marcare Arii\n" #~ " \n" #~ " \n" -#~ " ALT+N\n" +#~ " Alt+N\n" #~ "  Unealta Poligonizare\n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Unealta Transformare\n" #~ " \n" #~ " \n" @@ -20087,11 +20087,11 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Skew shape on X axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Skew shape on Y axis\n" #~ " \n" #~ " \n" @@ -20099,15 +20099,15 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Editor Transformation Tool\n" #~ " \n" #~ " \n" -#~ " ALT+X\n" +#~ " Alt+X\n" #~ "  Offset shape on X axis\n" #~ " \n" #~ " \n" -#~ " ALT+Y\n" +#~ " Alt+Y\n" #~ "  Offset shape on Y axis\n" #~ " \n" #~ " \n" @@ -20115,15 +20115,15 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Measurement Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" -#~ " CTRL+X\n" +#~ " Ctrl+X\n" #~ "  Polygon Cut Tool\n" #~ " \n" #~ " \n" @@ -20205,7 +20205,7 @@ msgstr "" #~ "  Abort and return to Select\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" @@ -20294,11 +20294,11 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Deformează forma geo pe axa X/td>\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Deformează forma geo pe axa Y\n" #~ " \n" #~ " \n" @@ -20306,15 +20306,15 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Unealta de Trasformări din Editor\n" #~ " \n" #~ " \n" -#~ " ALT+X\n" +#~ " Alt+X\n" #~ "  Deplasează forma geo pe axa X\n" #~ " \n" #~ " \n" -#~ " ALT+Y\n" +#~ " Alt+Y\n" #~ "  Deplasează forma geo pe axa Y\n" #~ " \n" #~ " \n" @@ -20322,16 +20322,16 @@ msgstr "" #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Unealta de Masurare\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Salvează obiectul și ieși din Editor\n" #~ " \n" #~ " \n" -#~ " CTRL+X\n" +#~ " Ctrl+X\n" #~ "  Unealta de tăiere Poligoane\n" #~ " \n" #~ " \n" @@ -20415,7 +20415,7 @@ msgstr "" #~ "  Renunta și intoarce-te la Select\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Salvează obiectul și ieși din Editor\n" #~ " \n" diff --git a/locale/ru/LC_MESSAGES/strings.po b/locale/ru/LC_MESSAGES/strings.po index 77055d4e..e56f7930 100644 --- a/locale/ru/LC_MESSAGES/strings.po +++ b/locale/ru/LC_MESSAGES/strings.po @@ -5208,8 +5208,8 @@ msgid "File" msgstr "Файл" #: flatcamGUI/FlatCAMGUI.py:69 -msgid "&New Project ...\tCTRL+N" -msgstr "&Новый проект ...\tCTRL+N" +msgid "&New Project ...\tCtrl+N" +msgstr "&Новый проект ...\tCtrl+N" #: flatcamGUI/FlatCAMGUI.py:71 msgid "Will create a new, blank project" @@ -5261,12 +5261,12 @@ msgid "Open &Project ..." msgstr "Открыть &проект..." #: flatcamGUI/FlatCAMGUI.py:109 flatcamGUI/FlatCAMGUI.py:4121 -msgid "Open &Gerber ...\tCTRL+G" -msgstr "Открыть &Gerber...\tCTRL+G" +msgid "Open &Gerber ...\tCtrl+G" +msgstr "Открыть &Gerber...\tCtrl+G" #: flatcamGUI/FlatCAMGUI.py:114 flatcamGUI/FlatCAMGUI.py:4126 -msgid "Open &Excellon ...\tCTRL+E" -msgstr "Открыть &Excellon ...\tCTRL+E" +msgid "Open &Excellon ...\tCtrl+E" +msgstr "Открыть &Excellon ...\tCtrl+E" #: flatcamGUI/FlatCAMGUI.py:118 flatcamGUI/FlatCAMGUI.py:4131 msgid "Open G-&Code ..." @@ -5417,8 +5417,8 @@ msgid "&Save Project ..." msgstr "&Сохранить проект ..." #: flatcamGUI/FlatCAMGUI.py:256 -msgid "Save Project &As ...\tCTRL+S" -msgstr "Сохранить проект &как ...\tCTRL+S" +msgid "Save Project &As ...\tCtrl+S" +msgstr "Сохранить проект &как ...\tCtrl+S" #: flatcamGUI/FlatCAMGUI.py:261 msgid "Save Project C&opy ..." @@ -5438,8 +5438,8 @@ msgid "Edit Object\tE" msgstr "Редактировать объект\tE" #: flatcamGUI/FlatCAMGUI.py:285 -msgid "Close Editor\tCTRL+S" -msgstr "Закрыть редактор\tCTRL+S" +msgid "Close Editor\tCtrl+S" +msgstr "Закрыть редактор\tCtrl+S" #: flatcamGUI/FlatCAMGUI.py:294 msgid "Conversion" @@ -5515,8 +5515,8 @@ msgid "Convert Any to Gerber" msgstr "Конвертировать любой объект в Gerber" #: flatcamGUI/FlatCAMGUI.py:341 -msgid "&Copy\tCTRL+C" -msgstr "&Копировать\tCTRL+C" +msgid "&Copy\tCtrl+C" +msgstr "&Копировать\tCtrl+C" #: flatcamGUI/FlatCAMGUI.py:346 msgid "&Delete\tDEL" @@ -5535,28 +5535,28 @@ msgid "Toggle Units\tQ" msgstr "Единицы измерения\tQ" #: flatcamGUI/FlatCAMGUI.py:360 -msgid "&Select All\tCTRL+A" -msgstr "&Выбрать все\tCTRL+A" +msgid "&Select All\tCtrl+A" +msgstr "&Выбрать все\tCtrl+A" #: flatcamGUI/FlatCAMGUI.py:365 -msgid "&Preferences\tSHIFT+P" -msgstr "&Настройки\tSHIFT+P" +msgid "&Preferences\tShift+P" +msgstr "&Настройки\tShift+P" #: flatcamGUI/FlatCAMGUI.py:371 flatcamTools/ToolProperties.py:153 msgid "Options" msgstr "Опции" #: flatcamGUI/FlatCAMGUI.py:373 -msgid "&Rotate Selection\tSHIFT+(R)" -msgstr "&Вращение\tSHIFT+(R)" +msgid "&Rotate Selection\tShift+(R)" +msgstr "&Вращение\tShift+(R)" #: flatcamGUI/FlatCAMGUI.py:378 -msgid "&Skew on X axis\tSHIFT+X" -msgstr "&Наклон по оси X\tSHIFT+X" +msgid "&Skew on X axis\tShift+X" +msgstr "&Наклон по оси X\tShift+X" #: flatcamGUI/FlatCAMGUI.py:380 -msgid "S&kew on Y axis\tSHIFT+Y" -msgstr "Н&аклон по оси Y\tSHIFT+Y" +msgid "S&kew on Y axis\tShift+Y" +msgstr "Н&аклон по оси Y\tShift+Y" #: flatcamGUI/FlatCAMGUI.py:385 msgid "Flip on &X axis\tX" @@ -5567,28 +5567,28 @@ msgid "Flip on &Y axis\tY" msgstr "Отразить по оси &Y\tY" #: flatcamGUI/FlatCAMGUI.py:392 -msgid "View source\tALT+S" -msgstr "Просмотреть код\tALT+S" +msgid "View source\tAlt+S" +msgstr "Просмотреть код\tAlt+S" #: flatcamGUI/FlatCAMGUI.py:394 -msgid "Tools DataBase\tCTRL+D" -msgstr "База данных\tCTRL+D" +msgid "Tools DataBase\tCtrl+D" +msgstr "База данных\tCtrl+D" #: flatcamGUI/FlatCAMGUI.py:401 flatcamGUI/FlatCAMGUI.py:2060 msgid "View" msgstr "Вид" #: flatcamGUI/FlatCAMGUI.py:403 -msgid "Enable all plots\tALT+1" -msgstr "Включить все участки\tALT+1" +msgid "Enable all plots\tAlt+1" +msgstr "Включить все участки\tAlt+1" #: flatcamGUI/FlatCAMGUI.py:405 -msgid "Disable all plots\tALT+2" -msgstr "Отключить все участки\tALT+2" +msgid "Disable all plots\tAlt+2" +msgstr "Отключить все участки\tAlt+2" #: flatcamGUI/FlatCAMGUI.py:407 -msgid "Disable non-selected\tALT+3" -msgstr "Отключить не выбранные\tALT+3" +msgid "Disable non-selected\tAlt+3" +msgstr "Отключить не выбранные\tAlt+3" #: flatcamGUI/FlatCAMGUI.py:411 msgid "&Zoom Fit\tV" @@ -5607,16 +5607,16 @@ msgid "Redraw All\tF5" msgstr "Перерисовать всё\tF5" #: flatcamGUI/FlatCAMGUI.py:424 -msgid "Toggle Code Editor\tSHIFT+E" -msgstr "Переключить редактор кода\tSHIFT+E" +msgid "Toggle Code Editor\tShift+E" +msgstr "Переключить редактор кода\tShift+E" #: flatcamGUI/FlatCAMGUI.py:427 -msgid "&Toggle FullScreen\tALT+F10" -msgstr "&Во весь экран\tALT+F10" +msgid "&Toggle FullScreen\tAlt+F10" +msgstr "&Во весь экран\tAlt+F10" #: flatcamGUI/FlatCAMGUI.py:429 -msgid "&Toggle Plot Area\tCTRL+F10" -msgstr "&Рабочая область\tCTRL+F10" +msgid "&Toggle Plot Area\tCtrl+F10" +msgstr "&Рабочая область\tCtrl+F10" #: flatcamGUI/FlatCAMGUI.py:431 msgid "&Toggle Project/Sel/Tool\t`" @@ -5627,16 +5627,16 @@ msgid "&Toggle Grid Snap\tG" msgstr "&Привязка к сетке\tG" #: flatcamGUI/FlatCAMGUI.py:437 -msgid "&Toggle Grid Lines\tALT+G" -msgstr "&Переключить линии сетки \tALT+G" +msgid "&Toggle Grid Lines\tAlt+G" +msgstr "&Переключить линии сетки \tAlt+G" #: flatcamGUI/FlatCAMGUI.py:439 -msgid "&Toggle Axis\tSHIFT+G" -msgstr "&Оси\tSHIFT+G" +msgid "&Toggle Axis\tShift+G" +msgstr "&Оси\tShift+G" #: flatcamGUI/FlatCAMGUI.py:441 -msgid "Toggle Workspace\tSHIFT+W" -msgstr "Границы рабочего пространства\tSHIFT+W" +msgid "Toggle Workspace\tShift+W" +msgstr "Границы рабочего пространства\tShift+W" #: flatcamGUI/FlatCAMGUI.py:446 msgid "Objects" @@ -5735,8 +5735,8 @@ msgid "Paint Tool\tI" msgstr "Рисование\tI" #: flatcamGUI/FlatCAMGUI.py:543 -msgid "Transform Tool\tALT+R" -msgstr "Трансформация\tALT+R" +msgid "Transform Tool\tAlt+R" +msgstr "Трансформация\tAlt+R" #: flatcamGUI/FlatCAMGUI.py:547 msgid "Toggle Corner Snap\tK" @@ -5799,8 +5799,8 @@ msgid "Add Region\tN" msgstr "Добавить регион\tN" #: flatcamGUI/FlatCAMGUI.py:598 -msgid "Poligonize\tALT+N" -msgstr "Полигонизация\tALT+N" +msgid "Poligonize\tAlt+N" +msgstr "Полигонизация\tAlt+N" #: flatcamGUI/FlatCAMGUI.py:600 msgid "Add SemiDisc\tE" @@ -5819,16 +5819,16 @@ msgid "Scale\tS" msgstr "Масштабировать\tS" #: flatcamGUI/FlatCAMGUI.py:608 -msgid "Mark Area\tALT+A" -msgstr "Обозначить области\tALT+A" +msgid "Mark Area\tAlt+A" +msgstr "Обозначить области\tAlt+A" #: flatcamGUI/FlatCAMGUI.py:610 -msgid "Eraser\tCTRL+E" -msgstr "Ластик\tCTRL+E" +msgid "Eraser\tCtrl+E" +msgstr "Ластик\tCtrl+E" #: flatcamGUI/FlatCAMGUI.py:612 -msgid "Transform\tALT+R" -msgstr "Трансформировать\tALT+R" +msgid "Transform\tAlt+R" +msgstr "Трансформировать\tAlt+R" #: flatcamGUI/FlatCAMGUI.py:639 msgid "Enable Plot" @@ -13901,7 +13901,7 @@ msgid "" "\n" "The coordinates set can be obtained:\n" "- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" -"- press SHIFT key and left mouse clicking on canvas. Then CTRL+V in the " +"- press SHIFT key and left mouse clicking on canvas. Then Ctrl+V in the " "field.\n" "- press SHIFT key and left mouse clicking on canvas. Then RMB click in the " "field and click Paste.\n" @@ -17736,8 +17736,8 @@ msgstr "Нет имени геометрии в аргументах. Укажи #~ msgid "[success] Paint done." #~ msgstr "[success] Окраска выполнена." -#~ msgid "Run Script ...\tSHIFT+S" -#~ msgstr "Выполнить сценарий ...\tSHIFT+S" +#~ msgid "Run Script ...\tShift+S" +#~ msgstr "Выполнить сценарий ...\tShift+S" #~ msgid "About" #~ msgstr "О программе" @@ -17853,39 +17853,39 @@ msgstr "Нет имени геометрии в аргументах. Укажи #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+A\n" +#~ " Ctrl+A\n" #~ "  Select All\n" #~ " \n" #~ " \n" -#~ " CTRL+C\n" +#~ " Ctrl+C\n" #~ "  Copy Obj\n" #~ " \n" #~ " \n" -#~ " CTRL+E\n" +#~ " Ctrl+E\n" #~ "  Open Excellon File\n" #~ " \n" #~ " \n" -#~ " CTRL+G\n" +#~ " Ctrl+G\n" #~ "  Open Gerber File\n" #~ " \n" #~ " \n" -#~ " CTRL+N\n" +#~ " Ctrl+N\n" #~ "  New Project\n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Measurement Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+O\n" +#~ " Ctrl+O\n" #~ "  Open Project\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Project As\n" #~ " \n" #~ " \n" -#~ " CTRL+F10\n" +#~ " Ctrl+F10\n" #~ "  Toggle Plot Area\n" #~ " \n" #~ " \n" @@ -17893,39 +17893,39 @@ msgstr "Нет имени геометрии в аргументах. Укажи #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+C\n" +#~ " Shift+C\n" #~ "  Copy Obj_Name\n" #~ " \n" #~ " \n" -#~ " SHIFT+E\n" +#~ " Shift+E\n" #~ "  Toggle Code Editor\n" #~ " \n" #~ " \n" -#~ " SHIFT+G\n" +#~ " Shift+G\n" #~ "  Toggle the axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+P\n" +#~ " Shift+P\n" #~ "  Open Preferences Window\n" #~ " \n" #~ " \n" -#~ " SHIFT+R\n" +#~ " Shift+R\n" #~ "  Rotate by 90 degree CCW\n" #~ " \n" #~ " \n" -#~ " SHIFT+S\n" +#~ " Shift+S\n" #~ "  Run a Script\n" #~ " \n" #~ " \n" -#~ " SHIFT+W\n" +#~ " Shift+W\n" #~ "  Toggle the workspace\n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Skew on X axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Skew on Y axis\n" #~ " \n" #~ " \n" @@ -17933,59 +17933,59 @@ msgstr "Нет имени геометрии в аргументах. Укажи #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+C\n" +#~ " Alt+C\n" #~ "  Calculators Tool\n" #~ " \n" #~ " \n" -#~ " ALT+D\n" +#~ " Alt+D\n" #~ "  2-Sided PCB Tool\n" #~ " \n" #~ " \n" -#~ " ALT+K\n" +#~ " Alt+K\n" #~ "  Solder Paste Dispensing Tool\n" #~ " \n" #~ " \n" -#~ " ALT+L\n" +#~ " Alt+L\n" #~ "  Film PCB Tool\n" #~ " \n" #~ " \n" -#~ " ALT+N\n" +#~ " Alt+N\n" #~ "  Non-Copper Clearing Tool\n" #~ " \n" #~ " \n" -#~ " ALT+P\n" +#~ " Alt+P\n" #~ "  Paint Area Tool\n" #~ " \n" #~ " \n" -#~ " ALT+Q\n" +#~ " Alt+Q\n" #~ "  PDF Import Tool\n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Transformations Tool\n" #~ " \n" #~ " \n" -#~ " ALT+S\n" +#~ " Alt+S\n" #~ "  View File Source\n" #~ " \n" #~ " \n" -#~ " ALT+U\n" +#~ " Alt+U\n" #~ "  Cutout PCB Tool\n" #~ " \n" #~ " \n" -#~ " ALT+1\n" +#~ " Alt+1\n" #~ "  Enable all Plots\n" #~ " \n" #~ " \n" -#~ " ALT+2\n" +#~ " Alt+2\n" #~ "  Disable all Plots\n" #~ " \n" #~ " \n" -#~ " ALT+3\n" +#~ " Alt+3\n" #~ "  Disable Non-selected Plots\n" #~ " \n" #~ " \n" -#~ " ALT+F10\n" +#~ " Alt+F10\n" #~ "  Toggle Full Screen\n" #~ " \n" #~ " \n" @@ -17993,7 +17993,7 @@ msgstr "Нет имени геометрии в аргументах. Укажи #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+ALT+XCtrl+Alt+X\n" #~ "  Abort current task (gracefully)\n" #~ " \n" @@ -18151,39 +18151,39 @@ msgstr "Нет имени геометрии в аргументах. Укажи #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+A\n" +#~ " Ctrl+A\n" #~ "  Выбрать всё\n" #~ " \n" #~ " \n" -#~ " CTRL+C\n" +#~ " Ctrl+C\n" #~ "  Копировать\n" #~ " \n" #~ " \n" -#~ " CTRL+E\n" +#~ " Ctrl+E\n" #~ "  Открыть Excellon\n" #~ " \n" #~ " \n" -#~ " CTRL+G\n" +#~ " Ctrl+G\n" #~ "  Открыть Gerber\n" #~ " \n" #~ " \n" -#~ " CTRL+N\n" +#~ " Ctrl+N\n" #~ "  Новый проект\n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Измеритель\n" #~ " \n" #~ " \n" -#~ " CTRL+O\n" +#~ " Ctrl+O\n" #~ "  Открыть проект\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Сохранить проект как\n" #~ " \n" #~ " \n" -#~ " CTRL+F10\n" +#~ " Ctrl+F10\n" #~ "  Переключить рабочую область\n" #~ " \n" #~ " \n" @@ -18191,40 +18191,40 @@ msgstr "Нет имени геометрии в аргументах. Укажи #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+C\n" +#~ " Shift+C\n" #~ "  Копировать имя объекта\n" #~ " \n" #~ " \n" -#~ " SHIFT+E\n" +#~ " Shift+E\n" #~ "  Редактор кода\n" #~ " \n" #~ " \n" -#~ " SHIFT+G\n" +#~ " Shift+G\n" #~ "  Оси\n" #~ " \n" #~ " \n" -#~ " SHIFT+P\n" +#~ " Shift+P\n" #~ "  Настройки\n" #~ " \n" #~ " \n" -#~ " SHIFT+R\n" +#~ " Shift+R\n" #~ "  Поворот на 90 градусов против часовой " #~ "стрелки\n" #~ " \n" #~ " \n" -#~ " SHIFT+S\n" +#~ " Shift+S\n" #~ "  Выполнить сценарий\n" #~ " \n" #~ " \n" -#~ " SHIFT+W\n" +#~ " Shift+W\n" #~ "  Границы рабочего пространства\n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Наклон по оси X\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Наклон по оси Y\n" #~ " \n" #~ " \n" @@ -18232,59 +18232,59 @@ msgstr "Нет имени геометрии в аргументах. Укажи #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+C\n" +#~ " Alt+C\n" #~ "  Калькуляторы\n" #~ " \n" #~ " \n" -#~ " ALT+D\n" +#~ " Alt+D\n" #~ "  2-х сторонняя плата\n" #~ " \n" #~ " \n" -#~ " ALT+K\n" +#~ " Alt+K\n" #~ "  Паяльная паста\n" #~ " \n" #~ " \n" -#~ " ALT+L\n" +#~ " Alt+L\n" #~ "  Плёнка\n" #~ " \n" #~ " \n" -#~ " ALT+N\n" +#~ " Alt+N\n" #~ "  Очистка от меди\n" #~ " \n" #~ " \n" -#~ " ALT+P\n" +#~ " Alt+P\n" #~ "  Область рисования\n" #~ " \n" #~ " \n" -#~ " ALT+Q\n" +#~ " Alt+Q\n" #~ "  Импорт PDF\n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Трансформация\n" #~ " \n" #~ " \n" -#~ " ALT+S\n" +#~ " Alt+S\n" #~ "  Просмотреть код\n" #~ " \n" #~ " \n" -#~ " ALT+U\n" +#~ " Alt+U\n" #~ "  Обрезка платы\n" #~ " \n" #~ " \n" -#~ " ALT+1\n" +#~ " Alt+1\n" #~ "  Включить все участки\n" #~ " \n" #~ " \n" -#~ " ALT+2\n" +#~ " Alt+2\n" #~ "  Отключить все участки\n" #~ " \n" #~ " \n" -#~ " ALT+3\n" +#~ " Alt+3\n" #~ "  Отключить не выбранные\n" #~ " \n" #~ " \n" -#~ " ALT+F10\n" +#~ " Alt+F10\n" #~ "  Во весь экран\n" #~ " \n" #~ " \n" @@ -18418,11 +18418,11 @@ msgstr "Нет имени геометрии в аргументах. Укажи #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Skew shape on X axis\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Skew shape on Y axis\n" #~ " \n" #~ " \n" @@ -18430,15 +18430,15 @@ msgstr "Нет имени геометрии в аргументах. Укажи #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Editor Transformation Tool\n" #~ " \n" #~ " \n" -#~ " ALT+X\n" +#~ " Alt+X\n" #~ "  Offset shape on X axis\n" #~ " \n" #~ " \n" -#~ " ALT+Y\n" +#~ " Alt+Y\n" #~ "  Offset shape on Y axis\n" #~ " \n" #~ " \n" @@ -18446,15 +18446,15 @@ msgstr "Нет имени геометрии в аргументах. Укажи #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Measurement Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" -#~ " CTRL+X\n" +#~ " Ctrl+X\n" #~ "  Polygon Cut Tool\n" #~ " \n" #~ " \n" @@ -18546,7 +18546,7 @@ msgstr "Нет имени геометрии в аргументах. Укажи #~ "  Abort and return to Select\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" @@ -18634,11 +18634,11 @@ msgstr "Нет имени геометрии в аргументах. Укажи #~ "  Abort and return to Select\n" #~ " \n" #~ " \n" -#~ " CTRL+E\n" +#~ " Ctrl+E\n" #~ "  Eraser Tool\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Save Object and Exit Editor\n" #~ " \n" #~ " \n" @@ -18646,15 +18646,15 @@ msgstr "Нет имени геометрии в аргументах. Укажи #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+A\n" +#~ " Alt+A\n" #~ "  Mark Area Tool\n" #~ " \n" #~ " \n" -#~ " ALT+N\n" +#~ " Alt+N\n" #~ "  Poligonize Tool\n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Transformation Tool\n" #~ " \n" #~ " \n" @@ -18753,11 +18753,11 @@ msgstr "Нет имени геометрии в аргументах. Укажи #~ "  \n" #~ " \n" #~ " \n" -#~ " SHIFT+X\n" +#~ " Shift+X\n" #~ "  Наклонить форму по оси X\n" #~ " \n" #~ " \n" -#~ " SHIFT+Y\n" +#~ " Shift+Y\n" #~ "  Наклонить форму по оси Y\n" #~ " \n" #~ " \n" @@ -18765,15 +18765,15 @@ msgstr "Нет имени геометрии в аргументах. Укажи #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Трансформация\n" #~ " \n" #~ " \n" -#~ " ALT+X\n" +#~ " Alt+X\n" #~ "  Смещение формы по оси X\n" #~ " \n" #~ " \n" -#~ " ALT+Y\n" +#~ " Alt+Y\n" #~ "  Смещение формы по оси Y\n" #~ " \n" #~ " \n" @@ -18781,16 +18781,16 @@ msgstr "Нет имени геометрии в аргументах. Укажи #~ "  \n" #~ " \n" #~ " \n" -#~ " CTRL+M\n" +#~ " Ctrl+M\n" #~ "  Измеритель\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Сохранить объект и закрыть редактор\n" #~ " \n" #~ " \n" -#~ " CTRL+X\n" +#~ " Ctrl+X\n" #~ "  Обрезка полигонов\n" #~ " \n" #~ " \n" @@ -18886,7 +18886,7 @@ msgstr "Нет имени геометрии в аргументах. Укажи #~ "  Прервать и вернуться к выбору\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Сохранить объект и закрыть редактор\n" #~ " \n" @@ -18976,11 +18976,11 @@ msgstr "Нет имени геометрии в аргументах. Укажи #~ "  Прервать и вернуться к выбору\n" #~ " \n" #~ " \n" -#~ " CTRL+E\n" +#~ " Ctrl+E\n" #~ "  Ластик\n" #~ " \n" #~ " \n" -#~ " CTRL+S\n" +#~ " Ctrl+S\n" #~ "  Сохранить объект и закрыть редактор\n" #~ " \n" @@ -18989,15 +18989,15 @@ msgstr "Нет имени геометрии в аргументах. Укажи #~ "  \n" #~ " \n" #~ " \n" -#~ " ALT+A\n" +#~ " Alt+A\n" #~ "  Обозначить области\n" #~ " \n" #~ " \n" -#~ " ALT+N\n" +#~ " Alt+N\n" #~ "  Полигонизация\n" #~ " \n" #~ " \n" -#~ " ALT+R\n" +#~ " Alt+R\n" #~ "  Трансформация\n" #~ " \n" #~ " \n" diff --git a/locale_template/strings.pot b/locale_template/strings.pot index 50ee46f4..1b9bc7d7 100644 --- a/locale_template/strings.pot +++ b/locale_template/strings.pot @@ -4542,7 +4542,7 @@ msgid "File" msgstr "" #: flatcamGUI/FlatCAMGUI.py:69 -msgid "&New Project ...\tCTRL+N" +msgid "&New Project ...\tCtrl+N" msgstr "" #: flatcamGUI/FlatCAMGUI.py:71 @@ -4595,11 +4595,11 @@ msgid "Open &Project ..." msgstr "" #: flatcamGUI/FlatCAMGUI.py:109 flatcamGUI/FlatCAMGUI.py:4121 -msgid "Open &Gerber ...\tCTRL+G" +msgid "Open &Gerber ...\tCtrl+G" msgstr "" #: flatcamGUI/FlatCAMGUI.py:114 flatcamGUI/FlatCAMGUI.py:4126 -msgid "Open &Excellon ...\tCTRL+E" +msgid "Open &Excellon ...\tCtrl+E" msgstr "" #: flatcamGUI/FlatCAMGUI.py:118 flatcamGUI/FlatCAMGUI.py:4131 @@ -4736,7 +4736,7 @@ msgid "&Save Project ..." msgstr "" #: flatcamGUI/FlatCAMGUI.py:256 -msgid "Save Project &As ...\tCTRL+S" +msgid "Save Project &As ...\tCtrl+S" msgstr "" #: flatcamGUI/FlatCAMGUI.py:261 @@ -4756,7 +4756,7 @@ msgid "Edit Object\tE" msgstr "" #: flatcamGUI/FlatCAMGUI.py:285 -msgid "Close Editor\tCTRL+S" +msgid "Close Editor\tCtrl+S" msgstr "" #: flatcamGUI/FlatCAMGUI.py:294 @@ -4821,7 +4821,7 @@ msgid "Convert Any to Gerber" msgstr "" #: flatcamGUI/FlatCAMGUI.py:341 -msgid "&Copy\tCTRL+C" +msgid "&Copy\tCtrl+C" msgstr "" #: flatcamGUI/FlatCAMGUI.py:346 @@ -4841,11 +4841,11 @@ msgid "Toggle Units\tQ" msgstr "" #: flatcamGUI/FlatCAMGUI.py:360 -msgid "&Select All\tCTRL+A" +msgid "&Select All\tCtrl+A" msgstr "" #: flatcamGUI/FlatCAMGUI.py:365 -msgid "&Preferences\tSHIFT+P" +msgid "&Preferences\tShift+P" msgstr "" #: flatcamGUI/FlatCAMGUI.py:371 flatcamTools/ToolProperties.py:153 @@ -4853,15 +4853,15 @@ msgid "Options" msgstr "" #: flatcamGUI/FlatCAMGUI.py:373 -msgid "&Rotate Selection\tSHIFT+(R)" +msgid "&Rotate Selection\tShift+(R)" msgstr "" #: flatcamGUI/FlatCAMGUI.py:378 -msgid "&Skew on X axis\tSHIFT+X" +msgid "&Skew on X axis\tShift+X" msgstr "" #: flatcamGUI/FlatCAMGUI.py:380 -msgid "S&kew on Y axis\tSHIFT+Y" +msgid "S&kew on Y axis\tShift+Y" msgstr "" #: flatcamGUI/FlatCAMGUI.py:385 @@ -4873,11 +4873,11 @@ msgid "Flip on &Y axis\tY" msgstr "" #: flatcamGUI/FlatCAMGUI.py:392 -msgid "View source\tALT+S" +msgid "View source\tAlt+S" msgstr "" #: flatcamGUI/FlatCAMGUI.py:394 -msgid "Tools DataBase\tCTRL+D" +msgid "Tools DataBase\tCtrl+D" msgstr "" #: flatcamGUI/FlatCAMGUI.py:401 flatcamGUI/FlatCAMGUI.py:2060 @@ -4885,15 +4885,15 @@ msgid "View" msgstr "" #: flatcamGUI/FlatCAMGUI.py:403 -msgid "Enable all plots\tALT+1" +msgid "Enable all plots\tAlt+1" msgstr "" #: flatcamGUI/FlatCAMGUI.py:405 -msgid "Disable all plots\tALT+2" +msgid "Disable all plots\tAlt+2" msgstr "" #: flatcamGUI/FlatCAMGUI.py:407 -msgid "Disable non-selected\tALT+3" +msgid "Disable non-selected\tAlt+3" msgstr "" #: flatcamGUI/FlatCAMGUI.py:411 @@ -4913,15 +4913,15 @@ msgid "Redraw All\tF5" msgstr "" #: flatcamGUI/FlatCAMGUI.py:424 -msgid "Toggle Code Editor\tSHIFT+E" +msgid "Toggle Code Editor\tShift+E" msgstr "" #: flatcamGUI/FlatCAMGUI.py:427 -msgid "&Toggle FullScreen\tALT+F10" +msgid "&Toggle FullScreen\tAlt+F10" msgstr "" #: flatcamGUI/FlatCAMGUI.py:429 -msgid "&Toggle Plot Area\tCTRL+F10" +msgid "&Toggle Plot Area\tCtrl+F10" msgstr "" #: flatcamGUI/FlatCAMGUI.py:431 @@ -4933,15 +4933,15 @@ msgid "&Toggle Grid Snap\tG" msgstr "" #: flatcamGUI/FlatCAMGUI.py:437 -msgid "&Toggle Grid Lines\tALT+G" +msgid "&Toggle Grid Lines\tAlt+G" msgstr "" #: flatcamGUI/FlatCAMGUI.py:439 -msgid "&Toggle Axis\tSHIFT+G" +msgid "&Toggle Axis\tShift+G" msgstr "" #: flatcamGUI/FlatCAMGUI.py:441 -msgid "Toggle Workspace\tSHIFT+W" +msgid "Toggle Workspace\tShift+W" msgstr "" #: flatcamGUI/FlatCAMGUI.py:446 @@ -5041,7 +5041,7 @@ msgid "Paint Tool\tI" msgstr "" #: flatcamGUI/FlatCAMGUI.py:543 -msgid "Transform Tool\tALT+R" +msgid "Transform Tool\tAlt+R" msgstr "" #: flatcamGUI/FlatCAMGUI.py:547 @@ -5105,7 +5105,7 @@ msgid "Add Region\tN" msgstr "" #: flatcamGUI/FlatCAMGUI.py:598 -msgid "Poligonize\tALT+N" +msgid "Poligonize\tAlt+N" msgstr "" #: flatcamGUI/FlatCAMGUI.py:600 @@ -5125,15 +5125,15 @@ msgid "Scale\tS" msgstr "" #: flatcamGUI/FlatCAMGUI.py:608 -msgid "Mark Area\tALT+A" +msgid "Mark Area\tAlt+A" msgstr "" #: flatcamGUI/FlatCAMGUI.py:610 -msgid "Eraser\tCTRL+E" +msgid "Eraser\tCtrl+E" msgstr "" #: flatcamGUI/FlatCAMGUI.py:612 -msgid "Transform\tALT+R" +msgid "Transform\tAlt+R" msgstr "" #: flatcamGUI/FlatCAMGUI.py:639 @@ -11925,7 +11925,7 @@ msgid "" "\n" "The coordinates set can be obtained:\n" "- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" -"- press SHIFT key and left mouse clicking on canvas. Then CTRL+V in the field.\n" +"- press SHIFT key and left mouse clicking on canvas. Then Ctrl+V in the field.\n" "- press SHIFT key and left mouse clicking on canvas. Then RMB click in the field and " "click Paste.\n" "- by entering the coords manually in the format: (x1, y1), (x2, y2), ..." From 13644187e44b79976a0a11722d58becd35431238 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 9 Apr 2020 22:40:43 +0300 Subject: [PATCH 163/209] - removed some packages from setup_ubuntu.sh as they are not needed in FlatCAM beta --- README.md | 5 +++-- setup_ubuntu.sh | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 1aeb53f8..b33cb69b 100644 --- a/README.md +++ b/README.md @@ -9,12 +9,13 @@ CAD program, and create G-Code for Isolation routing. ================================================= -10.04.2020 +9.04.2020 - if FlatCAM is not run with Python version >= 3.5 it will exit. - modified all CTRL+ with Ctrl+ and all ALT+ with Alt+ and all SHIFT+ with Shift+. Fixed issue #387. +- removed some packages from setup_ubuntu.sh as they are not needed in FlatCAM beta -9.4.2020 +8.4.2020 - fixed the Tcl Command Delete to have an argument -f that will force deletion evading the popup (if the popup is enabled). The sme command without a name now will delete all objects - fixed the Tcl Command JoinExcellons diff --git a/setup_ubuntu.sh b/setup_ubuntu.sh index 9054a57c..50da3fdf 100644 --- a/setup_ubuntu.sh +++ b/setup_ubuntu.sh @@ -1,9 +1,9 @@ #!/bin/bash sudo apt install --reinstall libpng-dev libfreetype6 libfreetype6-dev libgeos-dev libspatialindex-dev sudo apt install --reinstall python3-dev python3-pyqt5 python3-pyqt5.qtopengl python3-gdal python3-simplejson -sudo apt install --reinstall python3-pip python3-tk python3-imaging +sudo apt install --reinstall python3-pip python3-tk -sudo python3 -m pip install --upgrade pyqt5==5.12 -sudo python3 -m pip install --upgrade pip numpy scipy shapely rtree tk lxml cycler python-dateutil kiwisolver dill +sudo python3 -m pip install --upgrade pyqt5 +sudo python3 -m pip install --upgrade pip numpy shapely rtree tk lxml cycler python-dateutil kiwisolver dill sudo python3 -m pip install --upgrade vispy pyopengl setuptools svg.path ortools freetype-py fontTools rasterio ezdxf sudo python3 -m pip install --upgrade matplotlib qrcode reportlab svglib \ No newline at end of file From 496be49027a03ae10d999a59709546e4b1511f6b Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 10 Apr 2020 18:54:04 +0300 Subject: [PATCH 164/209] - made sure that the timeout parameter used by some Tcl Commands is seen as an integer in all cases - minor changes in Paint Tool --- README.md | 6 ++++++ flatcamTools/ToolPaint.py | 25 +++++++++++-------------- tclCommands/TclCommand.py | 3 ++- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index b33cb69b..a85ea37d 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,12 @@ CAD program, and create G-Code for Isolation routing. ================================================= +10.04.2020 + +- made sure that the timeout parameter used by some Tcl Commands is seen as an integer in all cases +- minor changes in Paint Tool + + 9.04.2020 - if FlatCAM is not run with Python version >= 3.5 it will exit. diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 842b6c56..9e955766 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -12,12 +12,11 @@ from FlatCAMTool import FlatCAMTool from copy import deepcopy # from ObjectCollection import * from flatcamParsers.ParseGerber import Gerber -from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry from camlib import Geometry, FlatCAMRTreeStorage from flatcamGUI.GUIElements import FCTable, FCDoubleSpinner, FCCheckBox, FCInputDialog, RadioSet, FCButton, FCComboBox import FlatCAMApp -from shapely.geometry import base, Polygon, MultiPolygon, LinearRing, Point, MultiLineString +from shapely.geometry import base, Polygon, MultiPolygon, LinearRing, Point from shapely.ops import cascaded_union, unary_union, linemerge from matplotlib.backend_bases import KeyEvent as mpl_key_event @@ -2075,7 +2074,7 @@ class ToolPaint(FlatCAMTool, Gerber): :return: None """ - if isinstance(obj, FlatCAMGerber): + if obj.kind == 'gerber': # I don't do anything here, like buffering when the Gerber is loaded without buffering????!!!! if self.app.defaults["gerber_buffering"] == 'no': self.app.inform.emit('%s %s %s' % @@ -2417,7 +2416,7 @@ class ToolPaint(FlatCAMTool, Gerber): # "Initializer expected a FlatCAMGeometry, got %s" % type(geo_obj) log.debug("Paint Tool. Normal painting all task started.") - if isinstance(obj, FlatCAMGerber): + if obj.kind == 'gerber': if app_obj.defaults["gerber_buffering"] == 'no': app_obj.inform.emit('%s %s' % (_("Paint Tool. Normal painting all task started."), @@ -2435,7 +2434,7 @@ class ToolPaint(FlatCAMTool, Gerber): else: pass - if isinstance(obj, FlatCAMGerber): + if obj.kind == 'gerber': if self.app.defaults["tools_paint_plotting"] == 'progressive': if isinstance(obj.solid_geometry, list): obj.solid_geometry = MultiPolygon(obj.solid_geometry).buffer(0) @@ -2629,7 +2628,7 @@ class ToolPaint(FlatCAMTool, Gerber): # "Initializer expected a FlatCAMGeometry, got %s" % type(geo_obj) log.debug("Paint Tool. Rest machining painting all task started.") - if isinstance(obj, FlatCAMGerber): + if obj.kind == 'gerber': if app_obj.defaults["gerber_buffering"] == 'no': app_obj.inform.emit('%s %s %s' % (_("Paint Tool."), _("Rest machining painting all task started."), @@ -2644,7 +2643,7 @@ class ToolPaint(FlatCAMTool, Gerber): tool_dia = None sorted_tools.sort(reverse=True) - if isinstance(obj, FlatCAMGerber): + if obj.kind == 'gerber': if self.app.defaults["tools_paint_plotting"] == 'progressive': if isinstance(obj.solid_geometry, list): obj.solid_geometry = MultiPolygon(obj.solid_geometry).buffer(0) @@ -3079,7 +3078,7 @@ class ToolPaint(FlatCAMTool, Gerber): # "Initializer expected a FlatCAMGeometry, got %s" % type(geo_obj) log.debug("Paint Tool. Normal painting area task started.") - if isinstance(obj, FlatCAMGerber): + if obj.kind == 'gerber': if app_obj.defaults["gerber_buffering"] == 'no': app_obj.inform.emit('%s %s' % (_("Paint Tool. Normal painting area task started."), @@ -3100,14 +3099,13 @@ class ToolPaint(FlatCAMTool, Gerber): # this is were heavy lifting is done and creating the geometry to be painted target_geo = MultiPolygon(obj.solid_geometry) - if isinstance(obj, FlatCAMGerber): + if obj.kind == 'gerber': if self.app.defaults["tools_paint_plotting"] == 'progressive': if isinstance(target_geo, list): target_geo = MultiPolygon(target_geo).buffer(0) else: target_geo = target_geo.buffer(0) - geo_to_paint = target_geo.intersection(sel_obj) painted_area = recurse(geo_to_paint) @@ -3444,7 +3442,7 @@ class ToolPaint(FlatCAMTool, Gerber): # "Initializer expected a FlatCAMGeometry, got %s" % type(geo_obj) log.debug("Paint Tool. Rest machining painting area task started.") - if isinstance(obj, FlatCAMGerber): + if obj.kind == 'gerber': if app_obj.defaults["gerber_buffering"] == 'no': app_obj.inform.emit('%s %s %s' % (_("Paint Tool."), _("Rest machining painting area task started."), @@ -3468,7 +3466,7 @@ class ToolPaint(FlatCAMTool, Gerber): # this is were heavy lifting is done and creating the geometry to be painted target_geo = obj.solid_geometry - if isinstance(obj, FlatCAMGerber): + if obj.kind == 'gerber': if self.app.defaults["tools_paint_plotting"] == 'progressive': if isinstance(target_geo, list): target_geo = MultiPolygon(target_geo).buffer(0) @@ -3533,7 +3531,6 @@ class ToolPaint(FlatCAMTool, Gerber): pol_nr = 0 - for geo in poly_buf: try: cp = None @@ -3952,7 +3949,7 @@ class ToolPaint(FlatCAMTool, Gerber): for row in range(self.tools_table.rowCount()): for col in [2, 4]: try: - self.ui.geo_tools_table.cellWidget(row, col).currentIndexChanged.disconnect() + self.tools_table.cellWidget(row, col).currentIndexChanged.disconnect() except (TypeError, AttributeError): pass diff --git a/tclCommands/TclCommand.py b/tclCommands/TclCommand.py index fd3058c9..0e5e6bab 100644 --- a/tclCommands/TclCommand.py +++ b/tclCommands/TclCommand.py @@ -387,7 +387,8 @@ class TclCommandSignaled(TclCommand): # Terminate on timeout if timeout is not None: - QtCore.QTimer.singleShot(timeout, report_quit) + time_val = int(timeout) + QtCore.QTimer.singleShot(time_val, report_quit) # Block loop.exec_() From 418ebd66062648a7e681c4a513c6822d888ea3bf Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 11 Apr 2020 01:51:43 +0300 Subject: [PATCH 165/209] - minor changes in GUI (Save locations in Menu -> File) and the key shortcuts --- FlatCAMApp.py | 2 +- README.md | 1 + flatcamGUI/FlatCAMGUI.py | 68 ++++++++++++++++++++++++---------------- 3 files changed, 43 insertions(+), 28 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 6f6d0919..ef6c9357 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -2016,7 +2016,7 @@ class App(QtCore.QObject): self.ui.menufilesaveproject.triggered.connect(self.on_file_saveproject) self.ui.menufilesaveprojectas.triggered.connect(self.on_file_saveprojectas) - self.ui.menufilesaveprojectcopy.triggered.connect(lambda: self.on_file_saveprojectas(make_copy=True)) + # self.ui.menufilesaveprojectcopy.triggered.connect(lambda: self.on_file_saveprojectas(make_copy=True)) self.ui.menufilesavedefaults.triggered.connect(self.on_file_savedefaults) self.ui.menufileexportpref.triggered.connect(self.on_export_preferences) diff --git a/README.md b/README.md index a85ea37d..6bcade76 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ CAD program, and create G-Code for Isolation routing. - made sure that the timeout parameter used by some Tcl Commands is seen as an integer in all cases - minor changes in Paint Tool +- minor changes in GUI (Save locations in Menu -> File) and the key shortcuts 9.04.2020 diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index 09bdb939..0401b164 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -51,7 +51,8 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # ######### ## self.menu = self.menuBar() - self.menu_toggle_nb = QtWidgets.QAction(QtGui.QIcon(self.app.resource_location + '/notebook32.png'), _("Toggle Panel")) + self.menu_toggle_nb = QtWidgets.QAction( + QtGui.QIcon(self.app.resource_location + '/notebook32.png'), _("Toggle Panel")) self.menu_toggle_nb.setToolTip( _("Toggle Panel") ) @@ -139,6 +140,26 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.recent = self.menufile.addMenu( QtGui.QIcon(self.app.resource_location + '/recent_files.png'), _("Recent files")) + # SAVE category + self.menufile_save = self.menufile.addMenu(QtGui.QIcon(self.app.resource_location + '/save_as.png'), _('Save')) + + # Save Project + self.menufilesaveproject = QtWidgets.QAction( + QtGui.QIcon(self.app.resource_location + '/floppy16.png'), _('&Save Project ...\tCtrl+S'), self) + self.menufile_save.addAction(self.menufilesaveproject) + + # Save Project As ... + self.menufilesaveprojectas = QtWidgets.QAction( + QtGui.QIcon(self.app.resource_location + '/floppy16.png'), _('Save Project &As ...\tCtrl+Shift+S'), self) + self.menufile_save.addAction(self.menufilesaveprojectas) + + # Save Project Copy ... + # self.menufilesaveprojectcopy = QtWidgets.QAction( + # QtGui.QIcon(self.app.resource_location + '/floppy16.png'), _('Save Project C&opy ...'), self) + # self.menufile_save.addAction(self.menufilesaveprojectcopy) + + self.menufile_save.addSeparator() + # Separator self.menufile.addSeparator() @@ -265,25 +286,6 @@ class FlatCAMGUI(QtWidgets.QMainWindow): QtGui.QIcon(self.app.resource_location + '/printer32.png'), '%s\tCtrl+P' % _('Print (PDF)')) self.menufile.addAction(self.menufile_print) - self.menufile_save = self.menufile.addMenu(QtGui.QIcon(self.app.resource_location + '/save_as.png'), _('Save')) - - # Save Project - self.menufilesaveproject = QtWidgets.QAction( - QtGui.QIcon(self.app.resource_location + '/floppy16.png'), _('&Save Project ...'), self) - self.menufile_save.addAction(self.menufilesaveproject) - - # Save Project As ... - self.menufilesaveprojectas = QtWidgets.QAction( - QtGui.QIcon(self.app.resource_location + '/save_as.png'), _('Save Project &As ...\tCtrl+S'), self) - self.menufile_save.addAction(self.menufilesaveprojectas) - - # Save Project Copy ... - self.menufilesaveprojectcopy = QtWidgets.QAction( - QtGui.QIcon(self.app.resource_location + '/floppy16.png'), _('Save Project C&opy ...'), self) - self.menufile_save.addAction(self.menufilesaveprojectcopy) - - self.menufile_save.addSeparator() - # Separator self.menufile.addSeparator() @@ -541,7 +543,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): QtGui.QIcon(self.app.resource_location + '/text32.png'), _('Add Text\tT')) self.geo_editor_menu.addSeparator() self.geo_union_menuitem = self.geo_editor_menu.addAction( - QtGui.QIcon(self.app.resource_location + '/union16.png'),_('Polygon Union\tU')) + QtGui.QIcon(self.app.resource_location + '/union16.png'), _('Polygon Union\tU')) self.geo_intersection_menuitem = self.geo_editor_menu.addAction( QtGui.QIcon(self.app.resource_location + '/intersection16.png'), _('Polygon Intersection\tE')) self.geo_subtract_menuitem = self.geo_editor_menu.addAction( @@ -550,7 +552,8 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.geo_editor_menu.addSeparator() self.geo_cutpath_menuitem = self.geo_editor_menu.addAction( QtGui.QIcon(self.app.resource_location + '/cutpath16.png'), _('Cut Path\tX')) - # self.move_menuitem = self.menu.addAction(QtGui.QIcon(self.app.resource_location + '/move16.png'), "Move Objects 'm'") + # self.move_menuitem = self.menu.addAction( + # QtGui.QIcon(self.app.resource_location + '/move16.png'), "Move Objects 'm'") self.geo_copy_menuitem = self.geo_editor_menu.addAction( QtGui.QIcon(self.app.resource_location + '/copy16.png'), _("Copy Geom\tC")) self.geo_delete_menuitem = self.geo_editor_menu.addAction( @@ -1640,6 +1643,14 @@ class FlatCAMGUI(QtWidgets.QMainWindow):     + + Ctrl+Shift+S +  %s + + +   +   + F1  %s @@ -1687,7 +1698,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # CTRL section _("Select All"), _("Copy Obj"), _("Open Tools Database"), _("Open Excellon File"), _("Open Gerber File"), _("Distance Tool"), _("New Project"), - _("Open Project"), _("Print (PDF)"), _("PDF Import Tool"), _("Save Project As"), _("Toggle Plot Area"), + _("Open Project"), _("Print (PDF)"), _("PDF Import Tool"), _("Save Project"), _("Toggle Plot Area"), # SHIFT section _("Copy Obj_Name"), @@ -1708,6 +1719,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # CTRL + ALT section _("Abort current task (gracefully)"), + # CTRL + SHIFT section + _("Save Project As"), + # F keys section _("Open Online Manual"), _("Open Online Tutorials"), _("Refresh Plots"), _("Delete Object"), _("Alternate: Delete Tool"), @@ -2816,7 +2830,10 @@ class FlatCAMGUI(QtWidgets.QMainWindow): if key == QtCore.Qt.Key_X: self.app.abort_all_tasks() return - + if modifiers == QtCore.Qt.ControlModifier | QtCore.Qt.ShiftModifier: + if key == QtCore.Qt.Key_S: + self.app.on_file_saveprojectas() + return elif modifiers == QtCore.Qt.ControlModifier: # Select All if key == QtCore.Qt.Key_A: @@ -2942,7 +2959,6 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.app.on_skewy() return elif modifiers == QtCore.Qt.AltModifier: - # Eanble all plots if key == Qt.Key_1: self.app.enable_all_plots() @@ -3161,7 +3177,6 @@ class FlatCAMGUI(QtWidgets.QMainWindow): else: self.app.collection.set_active(names_list[active_index+1]) - # New Geometry if key == QtCore.Qt.Key_B: self.app.new_gerber_object() @@ -3350,7 +3365,6 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # Abort the current action if key == QtCore.Qt.Key_Escape or key == 'Escape': - # TODO: ...? # self.on_tool_select("select") self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) From abce81d802df19e74b71b462bfece696c19197bb Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 11 Apr 2020 02:55:32 +0300 Subject: [PATCH 166/209] - fixed issue #394 - the saveDialog in Linux did not added the selected extension - fixed issue #389 - in previous commits - fixed issue #391 - in previous commits --- FlatCAMApp.py | 49 +++++++++++++++-------------- FlatCAMCommon.py | 8 ++--- FlatCAMObj.py | 5 +-- README.md | 8 +++-- flatcamEditors/FlatCAMTextEditor.py | 12 +++---- flatcamGUI/GUIElements.py | 24 ++++++++++++++ flatcamTools/ToolFilm.py | 10 +++--- flatcamTools/ToolQRCode.py | 10 +++--- flatcamTools/ToolSolderPaste.py | 7 +++-- 9 files changed, 82 insertions(+), 51 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index ef6c9357..001d8007 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -53,6 +53,7 @@ from camlib import to_dict, dict2obj, ET, ParseError from flatcamGUI.PlotCanvas import * from flatcamGUI.PlotCanvasLegacy import * from flatcamGUI.FlatCAMGUI import * +from flatcamGUI.GUIElements import FCFileSaveDialog from FlatCAMCommon import LoudDict, BookmarkManager, ToolsDB, ToolsDB2, color_variant from FlatCAMPostProc import load_preprocessors @@ -4134,13 +4135,13 @@ class App(QtCore.QObject): filter__ = "Config File (*.FlatConfig);;All Files (*.*)" try: - filename, _f = QtWidgets.QFileDialog.getSaveFileName( + filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Export FlatCAM Preferences"), directory=self.data_path + '/preferences_' + self.date, filter=filter__ ) except TypeError: - filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Export FlatCAM Preferences"), + filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Export FlatCAM Preferences"), filter=filter__) filename = str(filename) @@ -9800,12 +9801,12 @@ class App(QtCore.QObject): _filter = "SVG File (*.svg);;All Files (*.*)" try: - filename, _f = QtWidgets.QFileDialog.getSaveFileName( + filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Export SVG"), directory=self.get_last_save_folder() + '/' + str(name) + '_svg', filter=_filter) except TypeError: - filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Export SVG"), filter=_filter) + filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Export SVG"), filter=_filter) filename = str(filename) @@ -9837,12 +9838,12 @@ class App(QtCore.QObject): filter_ = "PNG File (*.png);;All Files (*.*)" try: - filename, _f = QtWidgets.QFileDialog.getSaveFileName( + filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Export PNG Image"), directory=self.get_last_save_folder() + '/png_' + self.date, filter=filter_) except TypeError: - filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Export PNG Image"), filter=filter_) + filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Export PNG Image"), filter=filter_) filename = str(filename) @@ -9884,12 +9885,12 @@ class App(QtCore.QObject): _filter = "Gerber File (*.GBR);;Gerber File (*.GRB);;All Files (*.*)" try: - filename, _f = QtWidgets.QFileDialog.getSaveFileName( + filename, _f = FCFileSaveDialog.get_saved_filename( caption="Save Gerber source file", directory=self.get_last_save_folder() + '/' + name, filter=_filter) except TypeError: - filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Save Gerber source file"), filter=_filter) + filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Save Gerber source file"), filter=_filter) filename = str(filename) @@ -9928,12 +9929,12 @@ class App(QtCore.QObject): _filter = "FlatCAM Scripts (*.FlatScript);;All Files (*.*)" try: - filename, _f = QtWidgets.QFileDialog.getSaveFileName( + filename, _f = FCFileSaveDialog.get_saved_filename( caption="Save Script source file", directory=self.get_last_save_folder() + '/' + name, filter=_filter) except TypeError: - filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Save Script source file"), filter=_filter) + filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Save Script source file"), filter=_filter) filename = str(filename) @@ -9972,12 +9973,12 @@ class App(QtCore.QObject): _filter = "FlatCAM Documents (*.FlatDoc);;All Files (*.*)" try: - filename, _f = QtWidgets.QFileDialog.getSaveFileName( + filename, _f = FCFileSaveDialog.get_saved_filename( caption="Save Document source file", directory=self.get_last_save_folder() + '/' + name, filter=_filter) except TypeError: - filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Save Document source file"), filter=_filter) + filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Save Document source file"), filter=_filter) filename = str(filename) @@ -10016,12 +10017,12 @@ class App(QtCore.QObject): _filter = "Excellon File (*.DRL);;Excellon File (*.TXT);;All Files (*.*)" try: - filename, _f = QtWidgets.QFileDialog.getSaveFileName( + filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Save Excellon source file"), directory=self.get_last_save_folder() + '/' + name, filter=_filter) except TypeError: - filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Save Excellon source file"), filter=_filter) + filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Save Excellon source file"), filter=_filter) filename = str(filename) @@ -10060,12 +10061,12 @@ class App(QtCore.QObject): _filter = self.defaults["excellon_save_filters"] try: - filename, _f = QtWidgets.QFileDialog.getSaveFileName( + filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Export Excellon"), directory=self.get_last_save_folder() + '/' + name, filter=_filter) except TypeError: - filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Export Excellon"), filter=_filter) + filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Export Excellon"), filter=_filter) filename = str(filename) @@ -10107,12 +10108,12 @@ class App(QtCore.QObject): _filter_ = self.defaults['gerber_save_filters'] try: - filename, _f = QtWidgets.QFileDialog.getSaveFileName( + filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Export Gerber"), directory=self.get_last_save_folder() + '/' + name, filter=_filter_) except TypeError: - filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Export Gerber"), filter=_filter_) + filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Export Gerber"), filter=_filter_) filename = str(filename) @@ -10166,12 +10167,12 @@ class App(QtCore.QObject): _filter_ = "DXF File (*.DXF);;All Files (*.*)" try: - filename, _f = QtWidgets.QFileDialog.getSaveFileName( + filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Export DXF"), directory=self.get_last_save_folder() + '/' + name, filter=_filter_) except TypeError: - filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Export DXF"), + filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Export DXF"), filter=_filter_) filename = str(filename) @@ -10588,14 +10589,14 @@ class App(QtCore.QObject): filter_ = "FlatCAM Project (*.FlatPrj);; All Files (*.*)" try: - filename, _f = QtWidgets.QFileDialog.getSaveFileName( + filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Save Project As ..."), directory='{l_save}/{proj}_{date}'.format(l_save=str(self.get_last_save_folder()), date=self.date, proj=_("Project")), filter=filter_ ) except TypeError: - filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Save Project As ..."), filter=filter_) + filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Save Project As ..."), filter=filter_) filename = str(filename) @@ -10642,7 +10643,7 @@ class App(QtCore.QObject): filter_ = "PDF File (*.PDF);; All Files (*.*)" try: - filename, _f = QtWidgets.QFileDialog.getSaveFileName( + filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Save Object as PDF ..."), directory='{l_save}/{obj_name}_{date}'.format(l_save=str(self.get_last_save_folder()), obj_name=obj_name, @@ -10650,7 +10651,7 @@ class App(QtCore.QObject): filter=filter_ ) except TypeError: - filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Save Object as PDF ..."), filter=filter_) + filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Save Object as PDF ..."), filter=filter_) filename = str(filename) diff --git a/FlatCAMCommon.py b/FlatCAMCommon.py index 8940542f..52c42d92 100644 --- a/FlatCAMCommon.py +++ b/FlatCAMCommon.py @@ -13,7 +13,7 @@ from PyQt5 import QtGui, QtCore, QtWidgets from flatcamGUI.GUIElements import FCTable, FCEntry, FCButton, FCDoubleSpinner, FCComboBox, FCCheckBox, FCSpinner, \ - FCTree, RadioSet + FCTree, RadioSet, FCFileSaveDialog from camlib import to_dict import sys @@ -358,7 +358,7 @@ class BookmarkManager(QtWidgets.QWidget): date = date.replace(' ', '_') filter__ = "Text File (*.TXT);;All Files (*.*)" - filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Export FlatCAM Bookmarks"), + filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Export FlatCAM Bookmarks"), directory='{l_save}/FlatCAM_{n}_{date}'.format( l_save=str(self.app.get_last_save_folder()), n=_("Bookmarks"), @@ -1094,7 +1094,7 @@ class ToolsDB(QtWidgets.QWidget): date = date.replace(' ', '_') filter__ = "Text File (*.TXT);;All Files (*.*)" - filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Export Tools Database"), + filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Export Tools Database"), directory='{l_save}/FlatCAM_{n}_{date}'.format( l_save=str(self.app.get_last_save_folder()), n=_("Tools_Database"), @@ -2524,7 +2524,7 @@ class ToolsDB2(QtWidgets.QWidget): date = date.replace(' ', '_') filter__ = "Text File (*.TXT);;All Files (*.*)" - filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Export Tools Database"), + filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Export Tools Database"), directory='{l_save}/FlatCAM_{n}_{date}'.format( l_save=str(self.app.get_last_save_folder()), n=_("Tools_Database"), diff --git a/FlatCAMObj.py b/FlatCAMObj.py index d803cea1..48480a5f 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -25,6 +25,7 @@ from datetime import datetime from flatcamEditors.FlatCAMTextEditor import TextEditor from flatcamGUI.ObjectUI import * +from flatcamGUI.GUIElements import FCFileSaveDialog from FlatCAMCommon import LoudDict from flatcamGUI.PlotCanvasLegacy import ShapeCollectionLegacy from flatcamParsers.ParseExcellon import Excellon @@ -7024,13 +7025,13 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): try: dir_file_to_save = self.app.get_last_save_folder() + '/' + str(name) - filename, _f = QtWidgets.QFileDialog.getSaveFileName( + filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Export Machine Code ..."), directory=dir_file_to_save, filter=_filter_ ) except TypeError: - filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Export Machine Code ..."), filter=_filter_) + filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Export Machine Code ..."), filter=_filter_) filename = str(filename) diff --git a/README.md b/README.md index 6bcade76..bc4273d6 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,15 @@ CAD program, and create G-Code for Isolation routing. ================================================= +11.04.2020 + +- fixed issue #394 - the saveDialog in Linux did not added the selected extension + 10.04.2020 -- made sure that the timeout parameter used by some Tcl Commands is seen as an integer in all cases +- made sure that the timeout parameter used by some Tcl Commands is seen as an integer in all cases - fixed issue #389 - minor changes in Paint Tool -- minor changes in GUI (Save locations in Menu -> File) and the key shortcuts +- minor changes in GUI (Save locations in Menu -> File) and the key shortcuts - fixed issue #391 9.04.2020 diff --git a/flatcamEditors/FlatCAMTextEditor.py b/flatcamEditors/FlatCAMTextEditor.py index fe0b847e..9159d823 100644 --- a/flatcamEditors/FlatCAMTextEditor.py +++ b/flatcamEditors/FlatCAMTextEditor.py @@ -5,14 +5,14 @@ # MIT Licence # # ########################################################## -from flatcamGUI.GUIElements import * -from PyQt5 import QtPrintSupport +from flatcamGUI.GUIElements import FCFileSaveDialog, FCEntry, FCTextAreaExtended, FCTextAreaLineNumber +from PyQt5 import QtPrintSupport, QtWidgets, QtCore, QtGui from reportlab.platypus import SimpleDocTemplate, Paragraph from reportlab.lib.styles import getSampleStyleSheet from reportlab.lib.units import inch, mm -from io import StringIO +# from io import StringIO import gettext import FlatCAMTranslation as fcTranslate @@ -211,13 +211,13 @@ class TextEditor(QtWidgets.QWidget): _filter_ = "FlatConfig Files (*.FlatConfig);;PDF Files (*.pdf);;All Files (*.*)" try: - filename = str(QtWidgets.QFileDialog.getSaveFileName( + filename = str(FCFileSaveDialog.get_saved_filename( caption=_("Export Code ..."), directory=self.app.defaults["global_last_folder"] + '/' + str(obj_name), filter=_filter_ )[0]) except TypeError: - filename = str(QtWidgets.QFileDialog.getSaveFileName(caption=_("Export Code ..."), filter=_filter_)[0]) + filename = str(FCFileSaveDialog.get_saved_filename(caption=_("Export Code ..."), filter=_filter_)[0]) if filename == "": self.app.inform.emit('[WARNING_NOTCL] %s' % _("Export Code cancelled.")) @@ -236,7 +236,7 @@ class TextEditor(QtWidgets.QWidget): styles = getSampleStyleSheet() styleN = styles['Normal'] - styleH = styles['Heading1'] + # styleH = styles['Heading1'] story = [] if self.app.defaults['units'].lower() == 'mm': diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index 4965b954..a3560bf2 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -2853,6 +2853,30 @@ class FCTextAreaLineNumber(QtWidgets.QFrame): self.edit.setLineWrapMode(mode) +class FCFileSaveDialog(QtWidgets.QFileDialog): + + def __init__(self, *args): + super(FCFileSaveDialog, self).__init__(*args) + + @staticmethod + def get_saved_filename(parent=None, caption='', directory='', filter='', initialFilter=''): + filename, _filter = QtWidgets.QFileDialog.getSaveFileName(parent=parent, caption=caption, + directory=directory, filter=filter, + initialFilter=initialFilter) + + filename = str(filename) + if filename == '': + return filename, _filter + + extension = '.' + _filter.strip(')').rpartition('.')[2] + + if filename.endswith(extension) or extension == '.*': + return filename, _filter + else: + filename += extension + return filename, _filter + + def rreplace(s, old, new, occurrence): """ Credits go here: diff --git a/flatcamTools/ToolFilm.py b/flatcamTools/ToolFilm.py index 4baae1a6..42787e5a 100644 --- a/flatcamTools/ToolFilm.py +++ b/flatcamTools/ToolFilm.py @@ -9,7 +9,7 @@ from PyQt5 import QtGui, QtCore, QtWidgets from FlatCAMTool import FlatCAMTool from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox, \ - OptionalHideInputSection, OptionalInputSection, FCComboBox + OptionalHideInputSection, OptionalInputSection, FCComboBox, FCFileSaveDialog from copy import deepcopy import logging @@ -741,12 +741,12 @@ class Film(FlatCAMTool): "All Files (*.*)" try: - filename, _f = QtWidgets.QFileDialog.getSaveFileName( + filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Export positive film"), directory=self.app.get_last_save_folder() + '/' + name + '_film', filter=filter_ext) except TypeError: - filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Export positive film")) + filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Export positive film")) filename = str(filename) @@ -887,12 +887,12 @@ class Film(FlatCAMTool): "All Files (*.*)" try: - filename, _f = QtWidgets.QFileDialog.getSaveFileName( + filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Export negative film"), directory=self.app.get_last_save_folder() + '/' + name + '_film', filter=filter_ext) except TypeError: - filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Export negative film")) + filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Export negative film")) filename = str(filename) diff --git a/flatcamTools/ToolQRCode.py b/flatcamTools/ToolQRCode.py index 438349d3..bc5c1fd1 100644 --- a/flatcamTools/ToolQRCode.py +++ b/flatcamTools/ToolQRCode.py @@ -9,7 +9,7 @@ from PyQt5 import QtWidgets, QtCore, QtGui from PyQt5.QtCore import Qt from FlatCAMTool import FlatCAMTool -from flatcamGUI.GUIElements import RadioSet, FCTextArea, FCSpinner, FCEntry, FCCheckBox, FCComboBox +from flatcamGUI.GUIElements import RadioSet, FCTextArea, FCSpinner, FCEntry, FCCheckBox, FCComboBox, FCFileSaveDialog from flatcamParsers.ParseSVG import * from shapely.geometry.base import * @@ -778,12 +778,12 @@ class QRCode(FlatCAMTool): _filter = "PNG File (*.png);;All Files (*.*)" try: - filename, _f = QtWidgets.QFileDialog.getSaveFileName( + filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Export PNG"), directory=self.app.get_last_save_folder() + '/' + str(name) + '_png', filter=_filter) except TypeError: - filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Export PNG"), filter=_filter) + filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Export PNG"), filter=_filter) filename = str(filename) @@ -825,12 +825,12 @@ class QRCode(FlatCAMTool): _filter = "SVG File (*.svg);;All Files (*.*)" try: - filename, _f = QtWidgets.QFileDialog.getSaveFileName( + filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Export SVG"), directory=self.app.get_last_save_folder() + '/' + str(name) + '_svg', filter=_filter) except TypeError: - filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Export SVG"), filter=_filter) + filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Export SVG"), filter=_filter) filename = str(filename) diff --git a/flatcamTools/ToolSolderPaste.py b/flatcamTools/ToolSolderPaste.py index d42b39d6..3da208a0 100644 --- a/flatcamTools/ToolSolderPaste.py +++ b/flatcamTools/ToolSolderPaste.py @@ -7,7 +7,8 @@ from FlatCAMTool import FlatCAMTool from FlatCAMCommon import LoudDict -from flatcamGUI.GUIElements import FCComboBox, FCEntry, FCTable, FCInputDialog, FCDoubleSpinner, FCSpinner +from flatcamGUI.GUIElements import FCComboBox, FCEntry, FCTable, \ + FCInputDialog, FCDoubleSpinner, FCSpinner, FCFileSaveDialog from FlatCAMApp import log from camlib import distance from FlatCAMObj import FlatCAMCNCjob @@ -1492,13 +1493,13 @@ class SolderPaste(FlatCAMTool): try: dir_file_to_save = self.app.get_last_save_folder() + '/' + str(name) - filename, _f = QtWidgets.QFileDialog.getSaveFileName( + filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Export GCode ..."), directory=dir_file_to_save, filter=_filter_ ) except TypeError: - filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Export Machine Code ..."), filter=_filter_) + filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Export Machine Code ..."), filter=_filter_) if filename == '': self.app.inform.emit('[WARNING_NOTCL] %s' % From 45a2890850d1bdc41ce25de371decfe1001dc074 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 11 Apr 2020 04:37:37 +0300 Subject: [PATCH 167/209] - when the Save button is clicked in the Edit -> Preferences the Preferences tab is closed. --- FlatCAMApp.py | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 001d8007..5de1325e 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -7087,6 +7087,14 @@ class App(QtCore.QObject): # This will write the setting to the platform specific storage. del settgs + if save_to_file: + # close the tab and delete it + for idx in range(self.ui.plot_tab_area.count()): + if self.ui.plot_tab_area.tabText(idx) == _("Preferences"): + self.ui.plot_tab_area.tabBar.setTabTextColor(idx, QtGui.QColor('black')) + self.ui.plot_tab_area.closeTab(idx) + break + def on_pref_close_button(self): # Preferences saved, update flag self.preferences_changed_flag = False @@ -8149,6 +8157,7 @@ class App(QtCore.QObject): if isinstance(obj, FlatCAMGeometry): obj.on_tool_from_db_inserted(tool=tool_from_db) + # close the tab and delete it for idx in range(self.ui.plot_tab_area.count()): if self.ui.plot_tab_area.tabText(idx) == _("Tools Database"): wdg = self.ui.plot_tab_area.widget(idx) diff --git a/README.md b/README.md index bc4273d6..ce3daf76 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 11.04.2020 - fixed issue #394 - the saveDialog in Linux did not added the selected extension +- when the Save button is clicked in the Edit -> Preferences the Preferences tab is closed. 10.04.2020 From 5dcddb168ed223d0e4fca7ecce4ff6fd59f2f967 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 13 Apr 2020 05:50:59 +0300 Subject: [PATCH 168/209] - added the outname parameter for the geocutout Tcl command --- README.md | 4 ++++ tclCommands/TclCommandGeoCutout.py | 15 ++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ce3daf76..4dfeb150 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +13.04.2020 + +- added the outname parameter for the geocutout Tcl command + 11.04.2020 - fixed issue #394 - the saveDialog in Linux did not added the selected extension diff --git a/tclCommands/TclCommandGeoCutout.py b/tclCommands/TclCommandGeoCutout.py index c138d4ad..555c38bc 100644 --- a/tclCommands/TclCommandGeoCutout.py +++ b/tclCommands/TclCommandGeoCutout.py @@ -35,7 +35,8 @@ class TclCommandGeoCutout(TclCommandSignaled): ('dia', float), ('margin', float), ('gapsize', float), - ('gaps', str) + ('gaps', str), + ('outname', str) ]) # array of mandatory options for current Tcl command: required = {'name','outname'} @@ -50,7 +51,8 @@ class TclCommandGeoCutout(TclCommandSignaled): ('margin', 'Margin over bounds.'), ('gapsize', 'size of gap.'), ('gaps', "type of gaps. Can be: 'tb' = top-bottom, 'lr' = left-right, '2tb' = 2top-2bottom, " - "'2lr' = 2left-2right, '4' = 4 cuts, '8' = 8 cuts") + "'2lr' = 2left-2right, '4' = 4 cuts, '8' = 8 cuts"), + ('outname', 'Name of the resulting Geometry object.'), ]), 'examples': [" #isolate margin for example from Fritzing arduino shield or any svg etc\n" + " isolate BCu_margin -dia 3 -overlap 1\n" + @@ -62,7 +64,7 @@ class TclCommandGeoCutout(TclCommandSignaled): " delete BCu_margin_iso\n" + "\n" + " #finally cut holding gaps\n" + - " geocutout BCu_margin_iso_exterior -dia 3 -gapsize 0.6 -gaps 4\n"] + " geocutout BCu_margin_iso_exterior -dia 3 -gapsize 0.6 -gaps 4 -outname cutout_geo\n"] } flat_geometry = [] @@ -156,6 +158,11 @@ class TclCommandGeoCutout(TclCommandSignaled): else: gapsize = 0.1 + if 'outname' in args: + outname = args['outname'] + else: + outname = str(name) + "_cutout" + # Get source object. try: cutout_obj = self.app.collection.get_by_name(str(name)) @@ -283,7 +290,6 @@ class TclCommandGeoCutout(TclCommandSignaled): app_obj.inform.emit("[success] Any-form Cutout operation finished.") - outname = cutout_obj.options["name"] + "_cutout" self.app.new_object('geometry', outname, geo_init, plot=False) # cutout_obj.plot() @@ -342,7 +348,6 @@ class TclCommandGeoCutout(TclCommandSignaled): geo_obj.options['ymax'] = cutout_obj.options['ymax'] app_obj.inform.emit("[success] Any-form Cutout operation finished.") - outname = cutout_obj.options["name"] + "_cutout" self.app.new_object('geometry', outname, geo_init, plot=False) cutout_obj = self.app.collection.get_by_name(outname) From 8a299e8fc8b203535e37a74ec8b84c224d2ec6b0 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 13 Apr 2020 19:15:20 +0300 Subject: [PATCH 169/209] - multiple fixes in the Tcl commands (especially regarding the interchange between True/false and 1/0 values) - updated the help for all Tcl Commands - in Tcl Shell, the 'help' command will add also a brief description for each command in the list --- FlatCAMApp.py | 22 +++++++++--- FlatCAMObj.py | 2 +- README.md | 3 ++ tclCommands/TclCommand.py | 2 ++ tclCommands/TclCommandAddCircle.py | 2 ++ tclCommands/TclCommandAddPolygon.py | 2 ++ tclCommands/TclCommandAddPolyline.py | 2 ++ tclCommands/TclCommandAddRectangle.py | 4 ++- tclCommands/TclCommandAlignDrill.py | 2 ++ tclCommands/TclCommandAlignDrillGrid.py | 4 ++- tclCommands/TclCommandBbox.py | 12 ++++--- tclCommands/TclCommandBounds.py | 4 ++- tclCommands/TclCommandClearShell.py | 4 ++- tclCommands/TclCommandCncjob.py | 20 ++++++----- tclCommands/TclCommandCopperClear.py | 40 ++++++++++++---------- tclCommands/TclCommandCutout.py | 33 +++++++++++------- tclCommands/TclCommandDelete.py | 2 ++ tclCommands/TclCommandDrillcncjob.py | 18 +++++----- tclCommands/TclCommandExportDXF.py | 19 +++++----- tclCommands/TclCommandExportExcellon.py | 21 +++++++----- tclCommands/TclCommandExportGcode.py | 13 ++++--- tclCommands/TclCommandExportGerber.py | 13 ++++--- tclCommands/TclCommandExportSVG.py | 8 +++-- tclCommands/TclCommandExteriors.py | 5 ++- tclCommands/TclCommandFollow.py | 6 ++-- tclCommands/TclCommandGeoCutout.py | 12 ++++--- tclCommands/TclCommandGeoUnion.py | 2 ++ tclCommands/TclCommandGetNames.py | 6 +++- tclCommands/TclCommandGetSys.py | 4 ++- tclCommands/TclCommandImportSvg.py | 13 ++++--- tclCommands/TclCommandInteriors.py | 6 +++- tclCommands/TclCommandIsolate.py | 12 ++++--- tclCommands/TclCommandJoinExcellon.py | 7 ++-- tclCommands/TclCommandJoinGeometry.py | 6 ++-- tclCommands/TclCommandListSys.py | 2 ++ tclCommands/TclCommandMillDrills.py | 14 +++++--- tclCommands/TclCommandMillSlots.py | 14 +++++--- tclCommands/TclCommandMirror.py | 4 ++- tclCommands/TclCommandNew.py | 2 ++ tclCommands/TclCommandNewExcellon.py | 2 ++ tclCommands/TclCommandNewGeometry.py | 2 ++ tclCommands/TclCommandNewGerber.py | 2 ++ tclCommands/TclCommandNregions.py | 10 +++--- tclCommands/TclCommandOffset.py | 2 ++ tclCommands/TclCommandOpenExcellon.py | 4 ++- tclCommands/TclCommandOpenGCode.py | 4 ++- tclCommands/TclCommandOpenGerber.py | 2 ++ tclCommands/TclCommandOpenProject.py | 4 ++- tclCommands/TclCommandOptions.py | 3 ++ tclCommands/TclCommandPaint.py | 35 ++++++++++--------- tclCommands/TclCommandPanelize.py | 15 ++++---- tclCommands/TclCommandPlotAll.py | 4 ++- tclCommands/TclCommandPlotObjects.py | 9 +++-- tclCommands/TclCommandQuit.py | 2 ++ tclCommands/TclCommandSaveProject.py | 4 ++- tclCommands/TclCommandSaveSys.py | 2 ++ tclCommands/TclCommandScale.py | 2 ++ tclCommands/TclCommandSetActive.py | 4 ++- tclCommands/TclCommandSetOrigin.py | 6 ++-- tclCommands/TclCommandSetSys.py | 4 ++- tclCommands/TclCommandSkew.py | 4 ++- tclCommands/TclCommandSubtractPoly.py | 3 ++ tclCommands/TclCommandSubtractRectangle.py | 3 ++ tclCommands/TclCommandVersion.py | 2 ++ tclCommands/TclCommandWriteGCode.py | 14 ++++---- tclCommands/__init__.py | 7 +++- 66 files changed, 350 insertions(+), 172 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 5de1325e..1d4dde99 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -11927,9 +11927,22 @@ class App(QtCore.QObject): def shelp(p=None): if not p: - return _("Available commands:\n") + \ - '\n'.join([' ' + cmd for cmd in sorted(commands)]) + \ - _("\n\nType help for usage.\n Example: help open_gerber") + cmd_enum = _("Available commands:\n") + + displayed_text = [] + try: + for cmd_name in sorted(commands): + cmd_description = commands[cmd_name]['description'] + + cmd_line_txt = ' %s\t\t%s' % (str(cmd_name), cmd_description) + displayed_text.append(cmd_line_txt) + except Exception as err: + log.debug("App.setup_shell.shelp() when run as 'help' --> %s" % str(err)) + displayed_text = [' %s' % cmd for cmd in sorted(commands)] + + cmd_enum += '\n'.join(displayed_text) + cmd_enum += '\n\n%s\n%s' % (_("Type help for usage."), _("Example: help open_gerber")) + return cmd_enum if p not in commands: return "Unknown command: %s" % p @@ -12079,7 +12092,8 @@ class App(QtCore.QObject): commands = { 'help': { 'fcn': shelp, - 'help': _("Shows list of commands.") + 'help': _("Shows list of commands."), + 'description': '' }, } diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 48480a5f..a8b388bf 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -7505,7 +7505,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): self.app.inform.emit('[ERROR] %s' % _("There is no preprocessor file.")) def get_gcode(self, preamble='', postamble=''): - # we need this to be able get_gcode separatelly for shell command export_gcode + # we need this to be able get_gcode separately for shell command export_gcode return preamble + '\n' + self.gcode + "\n" + postamble def get_svg(self): diff --git a/README.md b/README.md index 4dfeb150..2b0ed24a 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,9 @@ CAD program, and create G-Code for Isolation routing. 13.04.2020 - added the outname parameter for the geocutout Tcl command +- multiple fixes in the Tcl commands (especially regarding the interchange between True/false and 1/0 values) +- updated the help for all Tcl Commands +- in Tcl Shell, the 'help' command will add also a brief description for each command in the list 11.04.2020 diff --git a/tclCommands/TclCommand.py b/tclCommands/TclCommand.py index 0e5e6bab..9971eeaf 100644 --- a/tclCommands/TclCommand.py +++ b/tclCommands/TclCommand.py @@ -58,6 +58,8 @@ class TclCommand(object): raise TypeError('Expected FlatCAMApp, got %s.' % type(app)) self.log = self.app.log + self.error_info = None + self.error = None def raise_tcl_error(self, text): """ diff --git a/tclCommands/TclCommandAddCircle.py b/tclCommands/TclCommandAddCircle.py index f48ece80..f0cd87aa 100644 --- a/tclCommands/TclCommandAddCircle.py +++ b/tclCommands/TclCommandAddCircle.py @@ -13,6 +13,8 @@ class TclCommandAddCircle(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['add_circle'] + description = '%s %s' % ("--", "Creates a circle in the given Geometry object.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str), diff --git a/tclCommands/TclCommandAddPolygon.py b/tclCommands/TclCommandAddPolygon.py index 08ec3798..88fea588 100644 --- a/tclCommands/TclCommandAddPolygon.py +++ b/tclCommands/TclCommandAddPolygon.py @@ -10,6 +10,8 @@ class TclCommandAddPolygon(TclCommandSignaled): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['add_polygon', 'add_poly'] + description = '%s %s' % ("--", "Creates a polygon in the given Geometry object.") + # dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str) diff --git a/tclCommands/TclCommandAddPolyline.py b/tclCommands/TclCommandAddPolyline.py index b7c0a47b..79de3790 100644 --- a/tclCommands/TclCommandAddPolyline.py +++ b/tclCommands/TclCommandAddPolyline.py @@ -11,6 +11,8 @@ class TclCommandAddPolyline(TclCommandSignaled): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['add_polyline'] + description = '%s %s' % ("--", "Creates a polyline in the given Geometry object.") + # dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str) diff --git a/tclCommands/TclCommandAddRectangle.py b/tclCommands/TclCommandAddRectangle.py index 0fa7096e..eff36327 100644 --- a/tclCommands/TclCommandAddRectangle.py +++ b/tclCommands/TclCommandAddRectangle.py @@ -10,6 +10,8 @@ class TclCommandAddRectangle(TclCommandSignaled): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['add_rectangle'] + description = '%s %s' % ("--", "Creates a rectangle in the given Geometry object.") + # Dictionary of types from Tcl command, needs to be ordered. # For positional arguments arg_names = collections.OrderedDict([ @@ -31,7 +33,7 @@ class TclCommandAddRectangle(TclCommandSignaled): # structured help for current command, args needs to be ordered help = { - 'main': "Add a rectange to the given Geometry object.", + 'main': "Creates a rectangle in the given Geometry object.", 'args': collections.OrderedDict([ ('name', 'Name of the Geometry object in which to add the rectangle.'), ('x0 y0', 'Bottom left corner coordinates.'), diff --git a/tclCommands/TclCommandAlignDrill.py b/tclCommands/TclCommandAlignDrill.py index 1659b2a4..8ed877eb 100644 --- a/tclCommands/TclCommandAlignDrill.py +++ b/tclCommands/TclCommandAlignDrill.py @@ -15,6 +15,8 @@ class TclCommandAlignDrill(TclCommandSignaled): # backward compatibility (add_poly, add_polygon) aliases = ['aligndrill'] + description = '%s %s' % ("--", "Create an Excellon object with drills for alignment.") + # Dictionary of types from Tcl command, needs to be ordered. # For positional arguments arg_names = collections.OrderedDict([ diff --git a/tclCommands/TclCommandAlignDrillGrid.py b/tclCommands/TclCommandAlignDrillGrid.py index ac86f198..6fe6188b 100644 --- a/tclCommands/TclCommandAlignDrillGrid.py +++ b/tclCommands/TclCommandAlignDrillGrid.py @@ -15,6 +15,8 @@ class TclCommandAlignDrillGrid(TclCommandSignaled): # backward compatibility (add_poly, add_polygon) aliases = ['aligndrillgrid'] + description = '%s %s' % ("--", "Create an Excellon object with drills for alignment arranged in a grid.") + # Dictionary of types from Tcl command, needs to be ordered. # For positional arguments arg_names = collections.OrderedDict([ @@ -41,7 +43,6 @@ class TclCommandAlignDrillGrid(TclCommandSignaled): help = { 'main': "Create an Excellon object with drills for alignment arranged in a grid.", 'args': collections.OrderedDict([ - ('outname', 'Name of the object to create.'), ('dia', 'Tool diameter.'), ('gridx', 'Grid size in X axis.'), ('gridoffsetx', 'Move grid from origin.'), @@ -49,6 +50,7 @@ class TclCommandAlignDrillGrid(TclCommandSignaled): ('gridoffsety', 'Move grid from origin.'), ('colums', 'Number of grid holes on X axis.'), ('rows', 'Number of grid holes on Y axis.'), + ('outname', 'Name of the object to create.') ]), 'examples': ['aligndrillgrid -rows 2 -columns 2 -gridoffsetx 10 -gridoffsety 10 -gridx 2.54 -gridy 5.08'] } diff --git a/tclCommands/TclCommandBbox.py b/tclCommands/TclCommandBbox.py index a3df3d16..dd6ab627 100644 --- a/tclCommands/TclCommandBbox.py +++ b/tclCommands/TclCommandBbox.py @@ -21,6 +21,8 @@ class TclCommandBbox(TclCommand): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['bounding_box', 'bbox'] + description = '%s %s' % ("--", "Creates a rectangular Geometry object that surrounds the object.") + # dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str) @@ -30,7 +32,7 @@ class TclCommandBbox(TclCommand): option_types = collections.OrderedDict([ ('outname', str), ('margin', float), - ('rounded', bool) + ('rounded', str) ]) # array of mandatory options for current Tcl command: required = {'name','outname'} @@ -41,11 +43,11 @@ class TclCommandBbox(TclCommand): 'main': "Creates a rectangular Geometry object that surrounds the object.", 'args': collections.OrderedDict([ ('name', 'Object name for which to create bounding box. String'), - ('outname', 'Name of the resulting Geometry object. String.'), ('margin', "Distance of the edges of the box to the nearest polygon." "Float number."), ('rounded', "If the bounding box is to have rounded corners their radius is equal to the margin. " - "True or False.") + "True (1) or False (0)."), + ('outname', 'Name of the resulting Geometry object. String.') ]), 'examples': ['bbox name -outname name_bbox'] } @@ -78,8 +80,8 @@ class TclCommandBbox(TclCommand): margin = args['margin'] if 'rounded' not in args: - args['rounded'] = self.app.defaults["gerber_bboxrounded"] - rounded = bool(args['rounded']) + args['rounded'] = bool(eval(self.app.defaults["gerber_bboxrounded"])) + rounded = bool(eval(args['rounded'])) del args['name'] diff --git a/tclCommands/TclCommandBounds.py b/tclCommands/TclCommandBounds.py index a03a97c0..0401938e 100644 --- a/tclCommands/TclCommandBounds.py +++ b/tclCommands/TclCommandBounds.py @@ -23,6 +23,8 @@ class TclCommandBounds(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['get_bounds', 'bounds'] + description = '%s %s' % ("--", "Return in the console a list of bounds values for a list of objects.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('objects', str) @@ -38,7 +40,7 @@ class TclCommandBounds(TclCommand): # structured help for current command, args needs to be ordered help = { 'main': "Will return a list of bounds values, each set of bound values is " - "a list itself: [xmin, ymin, xmax, ymax].", + "a list itself: [xmin, ymin, xmax, ymax] corresponding to each of the provided objects.", 'args': collections.OrderedDict([ ('objects', 'A list of object names separated by comma without spaces.'), ]), diff --git a/tclCommands/TclCommandClearShell.py b/tclCommands/TclCommandClearShell.py index 4672ecae..3297017f 100644 --- a/tclCommands/TclCommandClearShell.py +++ b/tclCommands/TclCommandClearShell.py @@ -20,6 +20,8 @@ class TclCommandClearShell(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['clear'] + description = '%s %s' % ("--", "Clear the text in the Tcl Shell.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ @@ -35,7 +37,7 @@ class TclCommandClearShell(TclCommand): # structured help for current command, args needs to be ordered help = { - 'main': "Clear the text in the Tcl Shell browser.", + 'main': "Clear the text in the Tcl Shell.", 'args': collections.OrderedDict([ ]), 'examples': ['clear'] diff --git a/tclCommands/TclCommandCncjob.py b/tclCommands/TclCommandCncjob.py index ffb91ba7..70bfbcbc 100644 --- a/tclCommands/TclCommandCncjob.py +++ b/tclCommands/TclCommandCncjob.py @@ -20,6 +20,8 @@ class TclCommandCncjob(TclCommandSignaled): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['cncjob'] + description = '%s %s' % ("--", "Generates a CNC Job object from a Geometry Object.") + # dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str) @@ -42,7 +44,7 @@ class TclCommandCncjob(TclCommandSignaled): ('spindlespeed', int), ('dwelltime', float), ('pp', str), - ('muted', int), + ('muted', str), ('outname', str) ]) @@ -51,7 +53,7 @@ class TclCommandCncjob(TclCommandSignaled): # structured help for current command, args needs to be ordered help = { - 'main': "Generates a CNC Job from a Geometry Object.", + 'main': "Generates a CNC Job object from a Geometry Object.", 'args': collections.OrderedDict([ ('name', 'Name of the source object.'), ('dia', 'Tool diameter to show on screen.'), @@ -72,7 +74,7 @@ class TclCommandCncjob(TclCommandSignaled): 'If it is not used in command then it will not be included'), ('outname', 'Name of the resulting Geometry object.'), ('pp', 'Name of the Geometry preprocessor. No quotes, case sensitive'), - ('muted', 'It will not put errors in the Shell.') + ('muted', 'It will not put errors in the Shell. Can be True (1) or False (0)') ]), 'examples': ['cncjob geo_name -dia 0.5 -z_cut -1.7 -z_move 2 -feedrate 120 -pp default'] } @@ -90,14 +92,14 @@ class TclCommandCncjob(TclCommandSignaled): name = '' if 'muted' in args: - muted = args['muted'] + muted = bool(eval(args['muted'])) else: - muted = 0 + muted = False try: name = args['name'] except KeyError: - if muted == 0: + if muted is False: self.raise_tcl_error("Object name is missing") else: return "fail" @@ -108,13 +110,13 @@ class TclCommandCncjob(TclCommandSignaled): obj = self.app.collection.get_by_name(str(name), isCaseSensitive=False) if obj is None: - if muted == 0: + if muted is False: self.raise_tcl_error("Object not found: %s" % str(name)) else: return "fail" if not isinstance(obj, FlatCAMGeometry): - if muted == 0: + if muted is False: self.raise_tcl_error('Expected FlatCAMGeometry, got %s %s.' % (str(name), type(obj))) else: return @@ -187,7 +189,7 @@ class TclCommandCncjob(TclCommandSignaled): else: if args[arg] is None: print(arg, args[arg]) - if muted == 0: + if muted is False: self.raise_tcl_error('One of the command parameters that have to be not None, is None.\n' 'The parameter that is None is in the default values found in the list \n' 'generated by the TclCommand "list_sys geom". or in the arguments.') diff --git a/tclCommands/TclCommandCopperClear.py b/tclCommands/TclCommandCopperClear.py index f80bc5a9..62eeb19e 100644 --- a/tclCommands/TclCommandCopperClear.py +++ b/tclCommands/TclCommandCopperClear.py @@ -22,6 +22,8 @@ class TclCommandCopperClear(TclCommand): # Array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['ncc_clear', 'ncc'] + description = '%s %s' % ("--", "Clear excess copper.") + # dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str), @@ -34,13 +36,13 @@ class TclCommandCopperClear(TclCommand): ('order', str), ('margin', float), ('method', str), - ('connect', bool), - ('contour', bool), - ('has_offset', bool), + ('connect', str), + ('contour', str), + ('has_offset', str), ('offset', float), - ('rest', bool), + ('rest', str), ('all', int), - ('ref', int), + ('ref', str), ('box', str), ('outname', str), ]) @@ -64,15 +66,15 @@ class TclCommandCopperClear(TclCommand): '"fwd" -> tools are ordered from smallest to biggest.' '"rev" -> tools are ordered from biggest to smallest.'), ('method', 'Algorithm for copper clearing. Can be: "standard", "seed" or "lines".'), - ('connect', 'Draw lines to minimize tool lifts. True or False'), - ('contour', 'Cut around the perimeter of the painting. True or False'), - ('rest', 'Use rest-machining. True or False'), - ('has_offset', 'The offset will used only if this is set True or present in args. True or False.'), + ('connect', 'Draw lines to minimize tool lifts. True (1) or False (0)'), + ('contour', 'Cut around the perimeter of the painting. True (1) or False (0)'), + ('rest', 'Use rest-machining. True (1) or False (0)'), + ('has_offset', 'The offset will used only if this is set True or present in args. True (1) or False (0).'), ('offset', 'The copper clearing will finish to a distance from copper features. Float number.'), ('all', 'Will copper clear the whole object. 1 or True = enabled, anything else = disabled'), ('ref', 'Will clear of extra copper all polygons within a specified object with the name in "box" ' - 'parameter. 1 or True = enabled, anything else = disabled'), - ('box', 'Name of the object to be used as reference. Required when selecting "ref" = 1. String.'), + 'parameter. 1 or True = enabled, 0 or False = disabled'), + ('box', 'Name of the object to be used as reference. Required when selecting "ref" = 1 or True. String.'), ('outname', 'Name of the resulting Geometry object. String.'), ]), 'examples': ["ncc obj_name -tooldia 0.3,1 -overlap 10 -margin 1.0 -method 'lines' -all True"] @@ -127,18 +129,18 @@ class TclCommandCopperClear(TclCommand): method = str(self.app.defaults["tools_nccmethod"]) if 'connect' in args: - connect = bool(args['connect']) + connect = bool(eval(args['connect'])) else: - connect = eval(str(self.app.defaults["tools_nccconnect"])) + connect = bool(eval(str(self.app.defaults["tools_nccconnect"]))) if 'contour' in args: - contour = bool(args['contour']) + contour = bool(eval(args['contour'])) else: - contour = eval(str(self.app.defaults["tools_ncccontour"])) + contour = bool(eval(str(self.app.defaults["tools_ncccontour"]))) offset = 0.0 if 'has_offset' in args: - has_offset = bool(args['has_offset']) + has_offset = bool(eval(args['has_offset'])) if args['has_offset'] is True: if 'offset' in args: offset = float(args['margin']) @@ -206,9 +208,9 @@ class TclCommandCopperClear(TclCommand): }) if 'rest' in args: - rest = bool(args['rest']) + rest = bool(eval(args['rest'])) else: - rest = eval(str(self.app.defaults["tools_nccrest"])) + rest = bool(eval(str(self.app.defaults["tools_nccrest"]))) if 'outname' in args: outname = args['outname'] @@ -239,7 +241,7 @@ class TclCommandCopperClear(TclCommand): return # Non-Copper clear all polygons found within the box object from the the non_copper cleared object - elif 'ref' in args and bool(args['ref']): + elif 'ref' in args and bool(eval(args['ref'])): if 'box' not in args: self.raise_tcl_error('%s' % _("Expected -box .")) else: diff --git a/tclCommands/TclCommandCutout.py b/tclCommands/TclCommandCutout.py index c074fa8e..f780a8cf 100644 --- a/tclCommands/TclCommandCutout.py +++ b/tclCommands/TclCommandCutout.py @@ -21,6 +21,8 @@ class TclCommandCutout(TclCommand): # names for backward compatibility (add_poly, add_polygon) aliases = ['cutout'] + description = '%s %s' % ("--", "Creates board cutout from an object (Gerber or Geometry) with a rectangular shape.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str), @@ -32,7 +34,8 @@ class TclCommandCutout(TclCommand): ('dia', float), ('margin', float), ('gapsize', float), - ('gaps', str) + ('gaps', str), + ('outname', str) ]) # array of mandatory options for current Tcl command: required = {'name','outname'} @@ -40,15 +43,16 @@ class TclCommandCutout(TclCommand): # structured help for current command, args needs to be ordered help = { - 'main': 'Creates board cutout from an object (Gerber or Geometry) with a rectangular shape', + 'main': 'Creates board cutout from an object (Gerber or Geometry) with a rectangular shape.', 'args': collections.OrderedDict([ ('name', 'Name of the object.'), - ('dia', 'Tool diameter. Default = 0.1'), - ('margin', 'Margin over bounds. Default = 0.001'), - ('gapsize', 'Size of gap. Default = 0.1'), - ('gaps', "Type of gaps. Can be: 'tb' = top-bottom, 'lr' = left-right and '4' = one each side. Default = 4"), + ('dia', 'Tool diameter.'), + ('margin', 'Margin over bounds.'), + ('gapsize', 'Size of gap.'), + ('gaps', "Type of gaps. Can be: 'tb' = top-bottom, 'lr' = left-right and '4' = one each side."), + ('outname', 'Name of the object to create.') ]), - 'examples': ['cutout new_geo -dia 1.2 -margin 0.1 -gapsize 1 -gaps "tb" '] + 'examples': ['cutout new_geo -dia 1.2 -margin 0.1 -gapsize 1 -gaps "tb" -outname cut_geo'] } def execute(self, args, unnamed_args): @@ -69,22 +73,27 @@ class TclCommandCutout(TclCommand): if 'margin' in args: margin_par = float(args['margin']) else: - margin_par = 0.001 + margin_par = float(self.app.defaults["tools_cutoutmargin"]) if 'dia' in args: dia_par = float(args['dia']) else: - dia_par = 0.1 + dia_par = float(self.app.defaults["tools_cutouttooldia"]) if 'gaps' in args: gaps_par = args['gaps'] else: - gaps_par = "4" + gaps_par = str(self.app.defaults["tools_gaps_ff"]) if 'gapsize' in args: gapsize_par = float(args['gapsize']) else: - gapsize_par = 0.1 + gapsize_par = float(self.app.defaults["tools_cutoutgapsize"]) + + if 'outname' in args: + outname = args['outname'] + else: + outname = name + "_cutout" try: obj = self.app.collection.get_by_name(str(name)) @@ -128,7 +137,7 @@ class TclCommandCutout(TclCommand): geo_obj.solid_geometry = cascaded_union([LineString(segment) for segment in cuts]) try: - self.app.new_object("geometry", name + "_cutout", geo_init_me, plot=False) + self.app.new_object("geometry", outname, geo_init_me, plot=False) self.app.inform.emit("[success] Rectangular-form Cutout operation finished.") except Exception as e: return "Operation failed: %s" % str(e) diff --git a/tclCommands/TclCommandDelete.py b/tclCommands/TclCommandDelete.py index 43a69693..1c482598 100644 --- a/tclCommands/TclCommandDelete.py +++ b/tclCommands/TclCommandDelete.py @@ -14,6 +14,8 @@ class TclCommandDelete(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['delete', 'del'] + description = '%s %s' % ("--", "Deletes the given object. If no name is given will delete all objects.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str), diff --git a/tclCommands/TclCommandDrillcncjob.py b/tclCommands/TclCommandDrillcncjob.py index 64404fde..e0fd5dae 100644 --- a/tclCommands/TclCommandDrillcncjob.py +++ b/tclCommands/TclCommandDrillcncjob.py @@ -13,6 +13,8 @@ class TclCommandDrillcncjob(TclCommandSignaled): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['drillcncjob'] + description = '%s %s' % ("--", "Generates a Drill CNC Job object from a Excellon Object.") + # dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str) @@ -31,10 +33,10 @@ class TclCommandDrillcncjob(TclCommandSignaled): ('endz', float), ('dwelltime', float), ('pp', str), - ('outname', str), ('opt_type', str), ('diatol', float), - ('muted', int) + ('muted', str), + ('outname', str) ]) # array of mandatory options for current Tcl command: required = {'name','outname'} @@ -60,7 +62,6 @@ class TclCommandDrillcncjob(TclCommandSignaled): ('dwelltime', 'Time to pause to allow the spindle to reach the full speed.\n' 'If it is not used in command then it will not be included'), ('pp', 'This is the Excellon preprocessor name: case_sensitive, no_quotes'), - ('outname', 'Name of the resulting Geometry object.'), ('opt_type', 'Name of move optimization type. B by default for Basic OR-Tools, M for Metaheuristic OR-Tools' 'T from Travelling Salesman Algorithm. B and M works only for 64bit version of FlatCAM and ' 'T works only for 32bit version of FlatCAM'), @@ -69,7 +70,8 @@ class TclCommandDrillcncjob(TclCommandSignaled): 'diameter with value 1.0, in the Excellon we have a tool with dia = 1.05 and we set a tolerance ' 'diatol = 5.0 then the drills with the dia = (0.95 ... 1.05) ' 'in Excellon will be processed. Float number.'), - ('muted', 'It will not put errors in the Shell or status bar.') + ('muted', 'It will not put errors in the Shell or status bar. Can be True (1) or False (0).'), + ('outname', 'Name of the resulting Geometry object.') ]), 'examples': ['drillcncjob test.TXT -drillz -1.5 -travelz 14 -feedrate 222 -feedrate_rapid 456 -spindlespeed 777' ' -toolchangez 33 -endz 22 -pp default\n' @@ -94,7 +96,7 @@ class TclCommandDrillcncjob(TclCommandSignaled): args['outname'] = name + "_cnc" if 'muted' in args: - muted = bool(args['muted']) + muted = bool(eval(args['muted'])) else: muted = False @@ -105,7 +107,7 @@ class TclCommandDrillcncjob(TclCommandSignaled): return "fail" if not isinstance(obj, FlatCAMExcellon): - if muted == 0: + if muted is False: self.raise_tcl_error('Expected FlatCAMExcellon, got %s %s.' % (name, type(obj))) else: return "fail" @@ -143,7 +145,7 @@ class TclCommandDrillcncjob(TclCommandSignaled): nr_diameters -= 1 if nr_diameters > 0: - if muted == 0: + if muted is False: self.raise_tcl_error("One or more tool diameters of the drills to be drilled passed to the " "TclCommand are not actual tool diameters in the Excellon object.") else: @@ -164,7 +166,7 @@ class TclCommandDrillcncjob(TclCommandSignaled): except Exception as e: tools = 'all' - if muted == 0: + if muted is False: self.raise_tcl_error("Bad tools: %s" % str(e)) else: return "fail" diff --git a/tclCommands/TclCommandExportDXF.py b/tclCommands/TclCommandExportDXF.py index 58aab483..1fe4a361 100644 --- a/tclCommands/TclCommandExportDXF.py +++ b/tclCommands/TclCommandExportDXF.py @@ -14,9 +14,11 @@ class TclCommandExportDXF(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['export_dxf', 'edxf'] + description = '%s %s' % ("--", "Export a Geometry object as a DXF File.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ - ('obj_name', str), + ('name', str), ('filename', str) ]) @@ -29,12 +31,13 @@ class TclCommandExportDXF(TclCommand): # structured help for current command, args needs to be ordered help = { - 'main': "Export a Geometry Object as a DXF File.", + 'main': "Export a Geometry object as a DXF File.", 'args': collections.OrderedDict([ - ('obj_name', 'Name of the object to export.'), - ('filename', 'Path to the file to export.') + ('name', 'Name of the Geometry object to export.'), + ('filename', 'Absolute path to file to export.\n' + 'WARNING: no spaces are allowed. If unsure enclose the entire path with quotes.'), ]), - 'examples': ['export_dxf my_geo path/my_file.dxf'] + 'examples': ['export_dxf my_geo path/my_file.dxf', 'export_dxf my_geo D:/my_file.dxf'] } def execute(self, args, unnamed_args): @@ -44,6 +47,6 @@ class TclCommandExportDXF(TclCommand): :param unnamed_args: :return: """ - if 'filename' not in args: - args['filename'] = self.app.defaults["global_last_save_folder"] + '/' + args['obj_name'] - self.app.export_dxf(use_thread=False,**args) + if 'filename' not in args: + args['filename'] = self.app.defaults["global_last_save_folder"] + '/' + args['name'] + self.app.export_dxf(use_thread=False, **args) diff --git a/tclCommands/TclCommandExportExcellon.py b/tclCommands/TclCommandExportExcellon.py index 36e6e24c..a97ac054 100644 --- a/tclCommands/TclCommandExportExcellon.py +++ b/tclCommands/TclCommandExportExcellon.py @@ -14,9 +14,11 @@ class TclCommandExportExcellon(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['export_exc', 'ee', 'export_excellon'] + description = '%s %s' % ("--", "Export a Excellon object as a Excellon File.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ - ('obj_name', str), + ('name', str), ('filename', str) ]) @@ -25,16 +27,17 @@ class TclCommandExportExcellon(TclCommand): ]) # array of mandatory options for current Tcl command: required = ['name','outname'] - required = ['obj_name'] + required = ['name'] # structured help for current command, args needs to be ordered help = { - 'main': "Export a Excellon Object as a Excellon File.", + 'main': "Export a Excellon object as a Excellon File.", 'args': collections.OrderedDict([ - ('obj_name', 'Name of the object to export.'), - ('filename', 'Path to the file to export.') + ('name', 'Name of the Excellon object to export.'), + ('filename', 'Absolute path to file to export.\n' + 'WARNING: no spaces are allowed. If unsure enclose the entire path with quotes.'), ]), - 'examples': ['export_excellon my_excellon path/my_file.drl'] + 'examples': ['export_excellon my_excellon path/my_file.drl', 'export_excellon My_Excellon D:/drill_file.DRL'] } def execute(self, args, unnamed_args): @@ -44,6 +47,6 @@ class TclCommandExportExcellon(TclCommand): :param unnamed_args: :return: """ - if 'filename' not in args: - args['filename'] = self.app.defaults["global_last_save_folder"] + '/' + args['obj_name'] - self.app.export_excellon(use_thread=False,**args) + if 'filename' not in args: + args['filename'] = self.app.defaults["global_last_save_folder"] + '/' + args['name'] + self.app.export_excellon(use_thread=False, **args) diff --git a/tclCommands/TclCommandExportGcode.py b/tclCommands/TclCommandExportGcode.py index 2981e272..5572a285 100644 --- a/tclCommands/TclCommandExportGcode.py +++ b/tclCommands/TclCommandExportGcode.py @@ -13,7 +13,7 @@ class TclCommandExportGcode(TclCommandSignaled): promises and send to background if there are promises. - This export may be captured and passed as preable + This export may be captured and passed as preamble to another "export_gcode" or "write_gcode" call to join G-Code. example: @@ -31,11 +31,13 @@ class TclCommandExportGcode(TclCommandSignaled): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['export_gcode'] + description = '%s %s' % ("--", "Return Gcode into console output.") + # dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str), ('preamble', str), - ('postamble', str) + ('postamble', str), ]) # dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value @@ -49,8 +51,8 @@ class TclCommandExportGcode(TclCommandSignaled): 'main': "Export gcode into console output.", 'args': collections.OrderedDict([ ('name', 'Name of the source Geometry object. Required.'), - ('preamble', 'Prepend GCODE.'), - ('postamble', 'Append GCODE.') + ('preamble', 'Prepend GCode to the original GCode.'), + ('postamble', 'Append GCode o the original GCode.'), ]), 'examples': ['export_gcode geo_name -preamble "G01 X10 Y10" -postamble "G00 X20 Y20\nM04"'] } @@ -78,4 +80,5 @@ class TclCommandExportGcode(TclCommandSignaled): self.raise_tcl_error('!!!Promises exists, but should not here!!!') del args['name'] - return obj.get_gcode(**args) + modified_gcode = obj.get_gcode(**args) + return diff --git a/tclCommands/TclCommandExportGerber.py b/tclCommands/TclCommandExportGerber.py index 0fc7b0aa..a4f143d9 100644 --- a/tclCommands/TclCommandExportGerber.py +++ b/tclCommands/TclCommandExportGerber.py @@ -14,9 +14,11 @@ class TclCommandExportGerber(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['export_grb', 'egr', 'export_gerber'] + description = '%s %s' % ("--", "Export a Gerber object as a Gerber File.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ - ('obj_name', str), + ('name', str), ('filename', str) ]) @@ -31,8 +33,9 @@ class TclCommandExportGerber(TclCommand): help = { 'main': "Export a Gerber Object as a Gerber File.", 'args': collections.OrderedDict([ - ('obj_name', 'Name of the object to export. Required.'), - ('filename', 'Path to the file to export.') + ('name', 'Name of the object to export. Required.'), + ('filename', 'Absolute path to file to export.\n' + 'WARNING: no spaces are allowed. If unsure enclose the entire path with quotes.'), ]), 'examples': ['export_gerber my_gerber path/my_file.gbr'] } @@ -44,6 +47,6 @@ class TclCommandExportGerber(TclCommand): :param unnamed_args: :return: """ - if 'filename' not in args: - args['filename'] = self.app.defaults["global_last_save_folder"] + '/' + args['obj_name'] + if 'filename' not in args: + args['filename'] = self.app.defaults["global_last_save_folder"] + '/' + args['name'] self.app.export_gerber(use_thread=False,**args) diff --git a/tclCommands/TclCommandExportSVG.py b/tclCommands/TclCommandExportSVG.py index bc6efce9..ae5179c4 100644 --- a/tclCommands/TclCommandExportSVG.py +++ b/tclCommands/TclCommandExportSVG.py @@ -1,6 +1,7 @@ from tclCommands.TclCommand import TclCommand import collections +from copy import copy class TclCommandExportSVG(TclCommand): @@ -14,6 +15,8 @@ class TclCommandExportSVG(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['export_svg'] + description = '%s %s' % ("--", "Export a Geometry object as a SVG File.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str), @@ -31,10 +34,11 @@ class TclCommandExportSVG(TclCommand): # structured help for current command, args needs to be ordered help = { - 'main': "Export a Geometry Object as a SVG File.", + 'main': "Export a Geometry object as a SVG File.", 'args': collections.OrderedDict([ ('name', 'Name of the object export. Required.'), - ('filename', 'Path to the file to export.'), + ('filename', 'Absolute path to file to export.\n' + 'WARNING: no spaces are allowed. If unsure enclose the entire path with quotes.'), ('scale_factor', 'Multiplication factor used for scaling line widths during export.') ]), 'examples': ['export_svg my_geometry my_file.svg'] diff --git a/tclCommands/TclCommandExteriors.py b/tclCommands/TclCommandExteriors.py index cb3f041a..de4e6901 100644 --- a/tclCommands/TclCommandExteriors.py +++ b/tclCommands/TclCommandExteriors.py @@ -12,6 +12,9 @@ class TclCommandExteriors(TclCommandSignaled): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['exteriors', 'ext'] + description = '%s %s' % ("--", "Get exteriors of polygons from a Geometry object and " + "from them create a new Geometry object.") + # dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str) @@ -27,7 +30,7 @@ class TclCommandExteriors(TclCommandSignaled): # structured help for current command, args needs to be ordered help = { - 'main': "Get exteriors of polygons.", + 'main': "Get exteriors of polygons from a Geometry object and from them create a new Geometry object.", 'args': collections.OrderedDict([ ('name', 'Name of the source Geometry object. Required.'), ('outname', 'Name of the resulting Geometry object.') diff --git a/tclCommands/TclCommandFollow.py b/tclCommands/TclCommandFollow.py index 0ca8ab5e..e4e13359 100644 --- a/tclCommands/TclCommandFollow.py +++ b/tclCommands/TclCommandFollow.py @@ -12,6 +12,8 @@ class TclCommandFollow(TclCommandSignaled): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['follow'] + description = '%s %s' % ("--", "Creates a Geometry object following Gerber paths.") + # dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str) @@ -27,7 +29,7 @@ class TclCommandFollow(TclCommandSignaled): # structured help for current command, args needs to be ordered help = { - 'main': "Creates a geometry object following gerber paths.", + 'main': "Creates a Geometry object following Gerber paths.", 'args': collections.OrderedDict([ ('name', 'Object name to follow. Required.'), ('outname', 'Name of the resulting Geometry object.') @@ -64,4 +66,4 @@ class TclCommandFollow(TclCommandSignaled): return "Operation failed: %s" % str(e) # in the end toggle the visibility of the origin object so we can see the generated Geometry - self.app.collection.get_by_name(name).ui.plot_cb.toggle() \ No newline at end of file + # self.app.collection.get_by_name(name).ui.plot_cb.toggle() \ No newline at end of file diff --git a/tclCommands/TclCommandGeoCutout.py b/tclCommands/TclCommandGeoCutout.py index 555c38bc..40118c53 100644 --- a/tclCommands/TclCommandGeoCutout.py +++ b/tclCommands/TclCommandGeoCutout.py @@ -24,6 +24,8 @@ class TclCommandGeoCutout(TclCommandSignaled): # names for backward compatibility (add_poly, add_polygon) aliases = ['geocutout', 'geoc'] + description = '%s %s' % ("--", "Creates board cutout from an object (Gerber or Geometry) of any shape.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str), @@ -44,7 +46,7 @@ class TclCommandGeoCutout(TclCommandSignaled): # structured help for current command, args needs to be ordered help = { - 'main': 'Creates board cutout from an object (Gerber or Geometry) of any shape', + 'main': 'Creates board cutout from an object (Gerber or Geometry) of any shape.', 'args': collections.OrderedDict([ ('name', 'Name of the object to be cutout. Required'), ('dia', 'Tool diameter.'), @@ -141,22 +143,22 @@ class TclCommandGeoCutout(TclCommandSignaled): if 'margin' in args: margin = float(args['margin']) else: - margin = 0.001 + margin = float(self.app.defaults["tools_cutoutmargin"]) if 'dia' in args: dia = float(args['dia']) else: - dia = 0.1 + dia = float(self.app.defaults["tools_cutouttooldia"]) if 'gaps' in args: gaps = args['gaps'] else: - gaps = 4 + gaps = str(self.app.defaults["tools_gaps_ff"]) if 'gapsize' in args: gapsize = float(args['gapsize']) else: - gapsize = 0.1 + gapsize = float(self.app.defaults["tools_cutoutgapsize"]) if 'outname' in args: outname = args['outname'] diff --git a/tclCommands/TclCommandGeoUnion.py b/tclCommands/TclCommandGeoUnion.py index ac4fa4ea..4a698a2d 100644 --- a/tclCommands/TclCommandGeoUnion.py +++ b/tclCommands/TclCommandGeoUnion.py @@ -15,6 +15,8 @@ class TclCommandGeoUnion(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['geo_union'] + description = '%s %s' % ("--", "Run the Union (join) geometry operation on the elements of a Geometry object.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str), diff --git a/tclCommands/TclCommandGetNames.py b/tclCommands/TclCommandGetNames.py index 7cca9a46..6bb45e14 100644 --- a/tclCommands/TclCommandGetNames.py +++ b/tclCommands/TclCommandGetNames.py @@ -14,6 +14,9 @@ class TclCommandGetNames(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['get_names'] + description = '%s %s' % ("--", "Return to TCL the list of the project objects names " + "as a string with names separated by the '\\n' char.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ @@ -29,7 +32,8 @@ class TclCommandGetNames(TclCommand): # structured help for current command, args needs to be ordered help = { - 'main': 'Lists the names of objects in the project. It returns a string with names separated by \n', + 'main': 'Lists the names of objects in the project. ' + 'It returns a string with names separated by "\\n" character', 'args': collections.OrderedDict([ ]), diff --git a/tclCommands/TclCommandGetSys.py b/tclCommands/TclCommandGetSys.py index f98c3315..d5032464 100644 --- a/tclCommands/TclCommandGetSys.py +++ b/tclCommands/TclCommandGetSys.py @@ -21,6 +21,8 @@ class TclCommandGetSys(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['get_sys', 'getsys'] + description = '%s %s' % ("--", "Returns to TCL the value for the entered system variable.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str) @@ -36,7 +38,7 @@ class TclCommandGetSys(TclCommand): # structured help for current command, args needs to be ordered help = { - 'main': "Returns the value of the targeted system variable.", + 'main': "Returns to TCL the value for the entered system variable.", 'args': collections.OrderedDict([ ('name', 'Name of the system variable. Required.'), ]), diff --git a/tclCommands/TclCommandImportSvg.py b/tclCommands/TclCommandImportSvg.py index 0617090e..9ef67e27 100644 --- a/tclCommands/TclCommandImportSvg.py +++ b/tclCommands/TclCommandImportSvg.py @@ -12,6 +12,8 @@ class TclCommandImportSvg(TclCommandSignaled): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['import_svg'] + description = '%s %s' % ("--", "Import a SVG file as a Geometry (or Gerber) Object.") + # dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('filename', str) @@ -28,10 +30,11 @@ class TclCommandImportSvg(TclCommandSignaled): # structured help for current command, args needs to be ordered help = { - 'main': "Import an SVG file as a Geometry Object..", + 'main': "Import a SVG file as a Geometry (or Gerber) Object.", 'args': collections.OrderedDict([ - ('filename', 'Absolute path to file to open. Required.'), - ('type', 'Import as gerber or geometry(default).'), + ('filename', 'Absolute path to file to open. Required.\n' + 'WARNING: no spaces are allowed. If unsure enclose the entire path with quotes.'), + ('type', 'Import as a Gerber or Geometry (default) object. Values can be: "geometry" or "gerber"'), ('outname', 'Name of the resulting Geometry object.') ]), 'examples': ['import_svg D:\\my_beautiful_svg_file.SVG'] @@ -63,12 +66,12 @@ class TclCommandImportSvg(TclCommandSignaled): outname = filename.split('/')[-1].split('\\')[-1] if 'type' in args: - obj_type = args['type'] + obj_type = args['type'].lower() else: obj_type = 'geometry' if obj_type != "geometry" and obj_type != "gerber": - self.raise_tcl_error("Option type can be 'geopmetry' or 'gerber' only, got '%s'." % obj_type) + self.raise_tcl_error("Option type can be 'geometry' or 'gerber' only, got '%s'." % obj_type) with self.app.proc_container.new("Import SVG"): diff --git a/tclCommands/TclCommandInteriors.py b/tclCommands/TclCommandInteriors.py index f22ef1db..a7655204 100644 --- a/tclCommands/TclCommandInteriors.py +++ b/tclCommands/TclCommandInteriors.py @@ -12,6 +12,9 @@ class TclCommandInteriors(TclCommandSignaled): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['interiors'] + description = '%s %s' % ("--", "Create a new Geometry object with the 'interiors' geo " + "elements of the source object.") + # dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str) @@ -27,7 +30,8 @@ class TclCommandInteriors(TclCommandSignaled): # structured help for current command, args needs to be ordered help = { - 'main': "Return the interiors of polygons as a list of Shapely geometry elements.", + 'main': "Create a new Geometry object with the 'interiors' geometric elements of " + "the specified source Geometry object.", 'args': collections.OrderedDict([ ('name', 'Name of the source Geometry object. Required.'), ('outname', 'Name of the resulting Geometry object.') diff --git a/tclCommands/TclCommandIsolate.py b/tclCommands/TclCommandIsolate.py index 542dd3c3..337280df 100644 --- a/tclCommands/TclCommandIsolate.py +++ b/tclCommands/TclCommandIsolate.py @@ -19,6 +19,8 @@ class TclCommandIsolate(TclCommandSignaled): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['isolate'] + description = '%s %s' % ("--", "Creates isolation routing Geometry for the specified Gerber object.") + # dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str) @@ -29,7 +31,7 @@ class TclCommandIsolate(TclCommandSignaled): ('dia', float), ('passes', int), ('overlap', float), - ('combine', bool), + ('combine', str), ('outname', str), ('follow', str), ('iso_type', int) @@ -41,14 +43,14 @@ class TclCommandIsolate(TclCommandSignaled): # structured help for current command, args needs to be ordered help = { - 'main': "Creates isolation routing geometry for the given Gerber.", + 'main': "Creates isolation routing Geometry for the specified Gerber object.", 'args': collections.OrderedDict([ ('name', 'Name of the source object. Required.'), ('dia', 'Tool diameter.'), ('passes', 'Passes of tool width.'), ('overlap', 'Percentage of tool diameter to overlap current pass over previous pass. Float [0, 99.9999]\n' 'E.g: for a 25% from tool diameter overlap use -overlap 25'), - ('combine', 'Combine all passes into one geometry. Can be True or False, 1 or 0'), + ('combine', 'Combine all passes into one geometry. Can be True (1) or False (0)'), ('outname', 'Name of the resulting Geometry object.'), ('follow', 'Create a Geometry that follows the Gerber path.'), ('iso_type', 'A value of 0 will isolate exteriors, a value of 1 will isolate interiors ' @@ -82,7 +84,9 @@ class TclCommandIsolate(TclCommandSignaled): # evaluate this parameter so True, False, 0 and 1 works if "combine" in args: - args['combine'] = eval(args['combine']) + args['combine'] = bool(eval(args['combine'])) + else: + args['combine'] = bool(eval(self.app.defaults["gerber_combine_passes"])) obj = self.app.collection.get_by_name(name) if obj is None: diff --git a/tclCommands/TclCommandJoinExcellon.py b/tclCommands/TclCommandJoinExcellon.py index c385b55c..efea9e7d 100644 --- a/tclCommands/TclCommandJoinExcellon.py +++ b/tclCommands/TclCommandJoinExcellon.py @@ -15,6 +15,9 @@ class TclCommandJoinExcellon(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['join_excellon', 'join_excellons'] + description = '%s %s' % ("--", "Merge two or more Excellon objects drills and create " + "a new Excellon object with them.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('outname', str), @@ -61,7 +64,7 @@ class TclCommandJoinExcellon(TclCommand): def initialize(obj_, app): FlatCAMExcellon.merge(self, objs, obj_) - if objs: + if objs and len(objs) >= 2: self.app.new_object("excellon", outname, initialize, plot=False) else: - return "No Excellon objects to be joined." + return "No Excellon objects to be joined or less than two Excellon objects specified for merging." diff --git a/tclCommands/TclCommandJoinGeometry.py b/tclCommands/TclCommandJoinGeometry.py index d3208877..25dcc26d 100644 --- a/tclCommands/TclCommandJoinGeometry.py +++ b/tclCommands/TclCommandJoinGeometry.py @@ -15,6 +15,8 @@ class TclCommandJoinGeometry(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['join_geometries', 'join_geometry'] + description = '%s %s' % ("--", "Merge two or more Geometry objects and create a new Geometry object.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('outname', str), @@ -62,7 +64,7 @@ class TclCommandJoinGeometry(TclCommand): def initialize(obj_, app): FlatCAMGeometry.merge(self, objs, obj_) - if objs: + if objs and len(objs) >= 2: self.app.new_object("geometry", outname, initialize, plot=False) else: - return "No Geometry objects to be joined." + return "No Geometry objects to be joined or less than two Geometry objects specified for merging." diff --git a/tclCommands/TclCommandListSys.py b/tclCommands/TclCommandListSys.py index cff9ca06..d9e359c8 100644 --- a/tclCommands/TclCommandListSys.py +++ b/tclCommands/TclCommandListSys.py @@ -19,6 +19,8 @@ class TclCommandListSys(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['list_sys', 'listsys'] + description = '%s %s' % ("--", "Outputs in Tcl Shell the list with the names of system variables.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('selection', str), diff --git a/tclCommands/TclCommandMillDrills.py b/tclCommands/TclCommandMillDrills.py index 1e8684d0..e4e3df07 100644 --- a/tclCommands/TclCommandMillDrills.py +++ b/tclCommands/TclCommandMillDrills.py @@ -23,6 +23,8 @@ class TclCommandMillDrills(TclCommandSignaled): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['milldrills', 'milld'] + description = '%s %s' % ("--", "Create a Geometry Object for milling drill holes from Excellon.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str) @@ -34,7 +36,7 @@ class TclCommandMillDrills(TclCommandSignaled): ('milled_dias', str), ('outname', str), ('tooldia', float), - ('use_thread', bool), + ('use_thread', str), ('diatol', float) ]) @@ -43,7 +45,7 @@ class TclCommandMillDrills(TclCommandSignaled): # structured help for current command, args needs to be ordered help = { - 'main': "Create Geometry Object for milling drill holes from Excellon.", + 'main': "Create a Geometry Object for milling drill holes from Excellon.", 'args': collections.OrderedDict([ ('name', 'Name of the Excellon Object. Required.'), ('milled_dias', 'Comma separated tool diameters of the drills to be milled (example: 0.6, 1.0 or 3.125).\n' @@ -51,8 +53,8 @@ class TclCommandMillDrills(TclCommandSignaled): 'WARNING: no spaces are allowed in the list of tools.\n' 'As a precaution you can enclose them with quotes.'), ('tooldia', 'Diameter of the milling tool (example: 0.1).'), - ('outname', 'Name of object to be created holding the milled geometries.'), - ('use_thread', 'If to use multithreading: True or False.'), + ('outname', 'Name of Geometry object to be created holding the milled geometries.'), + ('use_thread', 'If to use multithreading: True (1) or False (0).'), ('diatol', 'Tolerance. Percentange (0.0 ... 100.0) within which dias in milled_dias will be judged to be ' 'the same as the ones in the tools from the Excellon object. E.g: if in milled_dias we have a ' 'diameter with value 1.0, in the Excellon we have a tool with dia = 1.05 and we set a tolerance ' @@ -84,7 +86,9 @@ class TclCommandMillDrills(TclCommandSignaled): args['outname'] = name + "_mill_drills" if 'use_thread' in args: - args['use_thread'] = bool(args['use_thread']) + args['use_thread'] = bool(eval(args['use_thread'])) + else: + args['use_thread'] = False if not obj.drills: self.raise_tcl_error("The Excellon object has no drills: %s" % name) diff --git a/tclCommands/TclCommandMillSlots.py b/tclCommands/TclCommandMillSlots.py index af6070be..7d6b1f0c 100644 --- a/tclCommands/TclCommandMillSlots.py +++ b/tclCommands/TclCommandMillSlots.py @@ -23,6 +23,8 @@ class TclCommandMillSlots(TclCommandSignaled): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['millslots', 'mills'] + description = '%s %s' % ("--", "Create a Geometry Object for milling slot holes from Excellon.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str) @@ -34,7 +36,7 @@ class TclCommandMillSlots(TclCommandSignaled): ('milled_dias', str), ('outname', str), ('tooldia', float), - ('use_thread', bool), + ('use_thread', str), ('diatol', float) ]) @@ -43,7 +45,7 @@ class TclCommandMillSlots(TclCommandSignaled): # structured help for current command, args needs to be ordered help = { - 'main': "Create Geometry Object for milling slot holes from Excellon.", + 'main': "Create a Geometry Object for milling slot holes from Excellon.", 'args': collections.OrderedDict([ ('name', 'Name of the Excellon Object. Required.'), ('milled_dias', 'Comma separated tool diameters of the slots to be milled (example: 0.6, 1.0 or 3.125).\n' @@ -52,7 +54,7 @@ class TclCommandMillSlots(TclCommandSignaled): 'As a precaution you can enclose them with quotes.'), ('tooldia', 'Diameter of the milling tool (example: 0.1).'), ('outname', 'Name of object to be created holding the milled geometries.'), - ('use_thread', 'If to use multithreading: True or False.'), + ('use_thread', 'If to use multithreading: True (1) or False (0).'), ('diatol', 'Tolerance. Percentange (0.0 ... 100.0) within which dias in milled_dias will be judged to be ' 'the same as the ones in the tools from the Excellon object. E.g: if in milled_dias we have a ' 'diameter with value 1.0, in the Excellon we have a tool with dia = 1.05 and we set a tolerance ' @@ -84,12 +86,14 @@ class TclCommandMillSlots(TclCommandSignaled): args['outname'] = name + "_mill_slots" if 'use_thread' in args: - args['use_thread'] = bool(args['use_thread']) + args['use_thread'] = bool(eval(args['use_thread'])) + else: + args['use_thread'] = False if not obj.slots: self.raise_tcl_error("The Excellon object has no slots: %s" % name) - units = self.app.defaults['units'].upper() + # units = self.app.defaults['units'].upper() try: if 'milled_dias' in args and args['milled_dias'] != 'all': diameters = [x.strip() for x in args['milled_dias'].split(",")] diff --git a/tclCommands/TclCommandMirror.py b/tclCommands/TclCommandMirror.py index cc29852f..5d4425ab 100644 --- a/tclCommands/TclCommandMirror.py +++ b/tclCommands/TclCommandMirror.py @@ -13,6 +13,8 @@ class TclCommandMirror(TclCommandSignaled): # old names for backward compatibility (add_poly, add_polygon) aliases = ['mirror'] + description = '%s %s' % ("--", "Will mirror the geometry of a named object. Does not create a new object.") + # Dictionary of types from Tcl command, needs to be ordered. # For positional arguments arg_names = collections.OrderedDict([ @@ -32,7 +34,7 @@ class TclCommandMirror(TclCommandSignaled): # structured help for current command, args needs to be ordered help = { - 'main': "Will mirror an named object.", + 'main': "Will mirror the geometry of a named object. Does not create a new object.", 'args': collections.OrderedDict([ ('name', 'Name of the object (Gerber, Geometry or Excellon) to be mirrored. Required.'), ('axis', 'Mirror axis parallel to the X or Y axis.'), diff --git a/tclCommands/TclCommandNew.py b/tclCommands/TclCommandNew.py index 66ff83b9..9a2af1f2 100644 --- a/tclCommands/TclCommandNew.py +++ b/tclCommands/TclCommandNew.py @@ -11,6 +11,8 @@ class TclCommandNew(TclCommand): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['new'] + description = '%s %s' % ("--", "Starts a new project. Clears objects from memory.") + # dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict() diff --git a/tclCommands/TclCommandNewExcellon.py b/tclCommands/TclCommandNewExcellon.py index c1322133..61689d6f 100644 --- a/tclCommands/TclCommandNewExcellon.py +++ b/tclCommands/TclCommandNewExcellon.py @@ -18,6 +18,8 @@ class TclCommandNewExcellon(TclCommandSignaled): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['new_excellon'] + description = '%s %s' % ("--", "Creates a new empty Excellon object.") + # Dictionary of types from Tcl command, needs to be ordered. # For positional arguments arg_names = collections.OrderedDict([ diff --git a/tclCommands/TclCommandNewGeometry.py b/tclCommands/TclCommandNewGeometry.py index 4af616c6..8fee996e 100644 --- a/tclCommands/TclCommandNewGeometry.py +++ b/tclCommands/TclCommandNewGeometry.py @@ -11,6 +11,8 @@ class TclCommandNewGeometry(TclCommandSignaled): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['new_geometry'] + description = '%s %s' % ("--", "Creates a new empty Geometry object.") + # Dictionary of types from Tcl command, needs to be ordered. # For positional arguments arg_names = collections.OrderedDict([ diff --git a/tclCommands/TclCommandNewGerber.py b/tclCommands/TclCommandNewGerber.py index 7a667813..9c162965 100644 --- a/tclCommands/TclCommandNewGerber.py +++ b/tclCommands/TclCommandNewGerber.py @@ -18,6 +18,8 @@ class TclCommandNewGerber(TclCommandSignaled): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['new_gerber'] + description = '%s %s' % ("--", "Creates a new empty Gerber object.") + # Dictionary of types from Tcl command, needs to be ordered. # For positional arguments arg_names = collections.OrderedDict([ diff --git a/tclCommands/TclCommandNregions.py b/tclCommands/TclCommandNregions.py index a4146792..f4b2a228 100644 --- a/tclCommands/TclCommandNregions.py +++ b/tclCommands/TclCommandNregions.py @@ -22,6 +22,8 @@ class TclCommandNregions(TclCommand): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['non_copper_regions', 'ncr'] + description = '%s %s' % ("--", "Creates a Geometry object with the non-copper regions.") + # dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str) @@ -31,7 +33,7 @@ class TclCommandNregions(TclCommand): option_types = collections.OrderedDict([ ('outname', str), ('margin', float), - ('rounded', bool) + ('rounded', str) ]) # array of mandatory options for current Tcl command: required = {'name','outname'} @@ -39,13 +41,13 @@ class TclCommandNregions(TclCommand): # structured help for current command, args needs to be ordered help = { - 'main': "Creates a geometry object with the non-copper regions.", + 'main': "Creates a Geometry object with the non-copper regions.", 'args': collections.OrderedDict([ ('name', 'Object name for which to create non-copper regions. String. Required.'), ('outname', 'Name of the resulting Geometry object. String.'), ('margin', "Specify the edge of the PCB by drawing a box around all objects with this minimum distance. " "Float number."), - ('rounded', "Resulting geometry will have rounded corners. True or False.") + ('rounded', "Resulting geometry will have rounded corners. True (1) or False (0).") ]), 'examples': ['ncr name -margin 0.1 -rounded True -outname name_ncr'] } @@ -78,7 +80,7 @@ class TclCommandNregions(TclCommand): if 'rounded' not in args: args['rounded'] = self.app.defaults["gerber_noncopperrounded"] - rounded = bool(args['rounded']) + rounded = bool(eval(args['rounded'])) del args['name'] diff --git a/tclCommands/TclCommandOffset.py b/tclCommands/TclCommandOffset.py index 6f5fd1c7..91fd46fc 100644 --- a/tclCommands/TclCommandOffset.py +++ b/tclCommands/TclCommandOffset.py @@ -14,6 +14,8 @@ class TclCommandOffset(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['offset'] + description = '%s %s' % ("--", "Will offset the geometry of a named object. Does not create a new object.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str), diff --git a/tclCommands/TclCommandOpenExcellon.py b/tclCommands/TclCommandOpenExcellon.py index 167db227..5fc7cc64 100644 --- a/tclCommands/TclCommandOpenExcellon.py +++ b/tclCommands/TclCommandOpenExcellon.py @@ -11,6 +11,8 @@ class TclCommandOpenExcellon(TclCommandSignaled): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['open_excellon'] + description = '%s %s' % ("--", "Opens an Excellon file, parse it and create a Excellon object from it.") + # Dictionary of types from Tcl command, needs to be ordered. # For positional arguments arg_names = collections.OrderedDict([ @@ -28,7 +30,7 @@ class TclCommandOpenExcellon(TclCommandSignaled): # structured help for current command, args needs to be ordered help = { - 'main': "Opens an Excellon file.", + 'main': "Opens an Excellon file, parse it and create a Excellon object from it.", 'args': collections.OrderedDict([ ('filename', 'Absolute path to file to open. Required.\n' 'WARNING: no spaces are allowed. If unsure enclose the entire path with quotes.'), diff --git a/tclCommands/TclCommandOpenGCode.py b/tclCommands/TclCommandOpenGCode.py index 5eaa83c9..9b5db715 100644 --- a/tclCommands/TclCommandOpenGCode.py +++ b/tclCommands/TclCommandOpenGCode.py @@ -12,6 +12,8 @@ class TclCommandOpenGCode(TclCommandSignaled): # backward compatibility (add_poly, add_polygon) aliases = ['open_gcode'] + description = '%s %s' % ("--", "Opens an GCode file, parse it and create a GCode object from it.") + # Dictionary of types from Tcl command, needs to be ordered. # For positional arguments arg_names = collections.OrderedDict([ @@ -29,7 +31,7 @@ class TclCommandOpenGCode(TclCommandSignaled): # structured help for current command, args needs to be ordered help = { - 'main': "Opens a G-Code file.", + 'main': "Opens an GCode file, parse it and create a GCode object from it.", 'args': collections.OrderedDict([ ('filename', 'Absolute path to file to open. Required.\n' 'WARNING: no spaces are allowed. If unsure enclose the entire path with quotes.'), diff --git a/tclCommands/TclCommandOpenGerber.py b/tclCommands/TclCommandOpenGerber.py index 037882a1..c473d0de 100644 --- a/tclCommands/TclCommandOpenGerber.py +++ b/tclCommands/TclCommandOpenGerber.py @@ -13,6 +13,8 @@ class TclCommandOpenGerber(TclCommandSignaled): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['open_gerber'] + description = '%s %s' % ("--", "Opens an Gerber file, parse it and create a Gerber object from it.") + # dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('filename', str) diff --git a/tclCommands/TclCommandOpenProject.py b/tclCommands/TclCommandOpenProject.py index 3dddad61..e1e1cd05 100644 --- a/tclCommands/TclCommandOpenProject.py +++ b/tclCommands/TclCommandOpenProject.py @@ -11,6 +11,8 @@ class TclCommandOpenProject(TclCommandSignaled): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['open_project'] + description = '%s %s' % ("--", "Opens an FlatCAm project file, parse it and recreate all the objects.") + # Dictionary of types from Tcl command, needs to be ordered. # For positional arguments arg_names = collections.OrderedDict([ @@ -28,7 +30,7 @@ class TclCommandOpenProject(TclCommandSignaled): # structured help for current command, args needs to be ordered help = { - 'main': "Opens a FlatCAM project.", + 'main': "Opens an FlatCAm project file, parse it and recreate all the objects.", 'args': collections.OrderedDict([ ('filename', 'Absolute path to file to open. Required.\n' 'WARNING: no spaces are allowed. If unsure enclose the entire path with quotes.'), diff --git a/tclCommands/TclCommandOptions.py b/tclCommands/TclCommandOptions.py index ab22599e..a6057bdc 100644 --- a/tclCommands/TclCommandOptions.py +++ b/tclCommands/TclCommandOptions.py @@ -11,6 +11,9 @@ class TclCommandOptions(TclCommandSignaled): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['options'] + description = '%s %s' % ("--", "Will return the options (settings) for an object as a string " + "with values separated by \\n.") + # Dictionary of types from Tcl command, needs to be ordered. # For positional arguments arg_names = collections.OrderedDict([ diff --git a/tclCommands/TclCommandPaint.py b/tclCommands/TclCommandPaint.py index e300e0c5..d0b099be 100644 --- a/tclCommands/TclCommandPaint.py +++ b/tclCommands/TclCommandPaint.py @@ -22,6 +22,8 @@ class TclCommandPaint(TclCommand): # Array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['paint'] + description = '%s %s' % ("--", "Paint polygons in the specified object by covering them with toolpaths.") + # dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str), @@ -34,12 +36,12 @@ class TclCommandPaint(TclCommand): ('order', str), ('margin', float), ('method', str), - ('connect', bool), - ('contour', bool), + ('connect', str), + ('contour', str), - ('all', bool), - ('single', bool), - ('ref', bool), + ('all', str), + ('single', str), + ('ref', str), ('box', str), ('x', float), ('y', float), @@ -51,7 +53,7 @@ class TclCommandPaint(TclCommand): # structured help for current command, args needs to be ordered help = { - 'main': "Paint polygons", + 'main': "Paint polygons in the specified object by covering them with toolpaths.", 'args': collections.OrderedDict([ ('name', 'Name of the source Geometry object. String.'), ('tooldia', 'Diameter of the tool to be used. Can be a comma separated list of diameters. No space is ' @@ -65,11 +67,12 @@ class TclCommandPaint(TclCommand): '"fwd" -> tools are ordered from smallest to biggest.' '"rev" -> tools are ordered from biggest to smallest.'), ('method', 'Algorithm for painting. Can be: "standard", "seed" or "lines".'), - ('connect', 'Draw lines to minimize tool lifts. True or False'), - ('contour', 'Cut around the perimeter of the painting. True or False'), - ('all', 'Paint all polygons in the object. True or False'), - ('single', 'Paint a single polygon specified by "x" and "y" parameters. True or False'), - ('ref', 'Paint all polygons within a specified object with the name in "box" parameter. True or False'), + ('connect', 'Draw lines to minimize tool lifts. True (1) or False (0)'), + ('contour', 'Cut around the perimeter of the painting. True (1) or False (0)'), + ('all', 'Paint all polygons in the object. True (1) or False (0)'), + ('single', 'Paint a single polygon specified by "x" and "y" parameters. True (1) or False (0)'), + ('ref', 'Paint all polygons within a specified object with the name in "box" parameter. ' + 'True (1) or False (0)'), ('box', 'name of the object to be used as paint reference when selecting "ref"" True. String.'), ('x', 'X value of coordinate for the selection of a single polygon. Float number.'), ('y', 'Y value of coordinate for the selection of a single polygon. Float number.'), @@ -124,12 +127,12 @@ class TclCommandPaint(TclCommand): method = str(self.app.defaults["tools_paintmethod"]) if 'connect' in args: - connect = bool(args['connect']) + connect = bool(eval(args['connect'])) else: connect = eval(str(self.app.defaults["tools_pathconnect"])) if 'contour' in args: - contour = bool(args['contour']) + contour = bool(eval(args['contour'])) else: contour = eval(str(self.app.defaults["tools_paintcontour"])) @@ -199,7 +202,7 @@ class TclCommandPaint(TclCommand): return "Object not found: %s" % name # Paint all polygons in the painted object - if 'all' in args and bool(args['all']) is True: + if 'all' in args and bool(eval(args['all'])) is True: self.app.paint_tool.paint_poly_all(obj=obj, tooldia=tooldia, overlap=overlap, @@ -215,7 +218,7 @@ class TclCommandPaint(TclCommand): return # Paint single polygon in the painted object - elif 'single' in args and bool(args['single']) is True: + elif 'single' in args and bool(eval(args['single'])) is True: if 'x' not in args or 'y' not in args: self.raise_tcl_error('%s' % _("Expected -x and -y .")) else: @@ -238,7 +241,7 @@ class TclCommandPaint(TclCommand): return # Paint all polygons found within the box object from the the painted object - elif 'ref' in args and bool(args['ref']) is True: + elif 'ref' in args and bool(eval(args['ref'])) is True: if 'box' not in args: self.raise_tcl_error('%s' % _("Expected -box .")) else: diff --git a/tclCommands/TclCommandPanelize.py b/tclCommands/TclCommandPanelize.py index 71d50199..e2c64dbc 100644 --- a/tclCommands/TclCommandPanelize.py +++ b/tclCommands/TclCommandPanelize.py @@ -19,7 +19,10 @@ class TclCommandPanelize(TclCommand): """ # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) - aliases = ['panelize','pan', 'panel'] + aliases = ['panelize', 'pan', 'panel'] + + description = '%s %s' % ("--", "Create a new object with an array of duplicates of the original geometry, " + "arranged in a grid.") # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ @@ -34,7 +37,7 @@ class TclCommandPanelize(TclCommand): ('spacing_rows', float), ('box', str), ('outname', str), - ('run_threaded', bool) + ('run_threaded', str) ]) # array of mandatory options for current Tcl command: required = {'name','outname'} @@ -42,7 +45,7 @@ class TclCommandPanelize(TclCommand): # structured help for current command, args needs to be ordered help = { - 'main': 'Rectangular panelizing.', + 'main': 'Create a new object with an array of duplicates of the original geometry, arranged in a grid.', 'args': collections.OrderedDict([ ('name', 'Name of the object to panelize.'), ('box', 'Name of object which acts as box (cutout for example.)' @@ -52,7 +55,7 @@ class TclCommandPanelize(TclCommand): ('columns', 'Number of columns.'), ('rows', 'Number of rows;'), ('outname', 'Name of the new geometry object.'), - ('run_threaded', 'False = non-threaded || True = threaded') + ('run_threaded', 'False (0) = non-threaded execution or True (1) = threaded execution') ]), 'examples': [ 'panelize obj_name', @@ -77,7 +80,7 @@ class TclCommandPanelize(TclCommand): # Get source object. try: obj = self.app.collection.get_by_name(str(name)) - except Exception as e: + except Exception: return "Could not retrieve object: %s" % name if obj is None: @@ -111,7 +114,7 @@ class TclCommandPanelize(TclCommand): outname = name + '_panelized' if 'run_threaded' in args: - threaded = bool(args['run_threaded']) + threaded = bool(eval(args['run_threaded'])) else: threaded = False diff --git a/tclCommands/TclCommandPlotAll.py b/tclCommands/TclCommandPlotAll.py index d3833dd0..8efae5fb 100644 --- a/tclCommands/TclCommandPlotAll.py +++ b/tclCommands/TclCommandPlotAll.py @@ -14,6 +14,8 @@ class TclCommandPlotAll(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['plot_all'] + description = '%s %s' % ("--", "Plots all objects on GUI.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ @@ -29,7 +31,7 @@ class TclCommandPlotAll(TclCommand): # structured help for current command, args needs to be ordered help = { - 'main': "Updates the plot on the user interface.", + 'main': "Plots all objects on GUI.", 'args': collections.OrderedDict([ ]), diff --git a/tclCommands/TclCommandPlotObjects.py b/tclCommands/TclCommandPlotObjects.py index 1df57886..34585efb 100644 --- a/tclCommands/TclCommandPlotObjects.py +++ b/tclCommands/TclCommandPlotObjects.py @@ -21,6 +21,8 @@ class TclCommandPlotObjects(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['plot_objects'] + description = '%s %s' % ("--", "Plot a specified list of objects in GUI.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('names', str) @@ -36,11 +38,12 @@ class TclCommandPlotObjects(TclCommand): # structured help for current command, args needs to be ordered help = { - 'main': "Plot a list of objects.", + 'main': "Plot a specified list of objects in GUI.", 'args': collections.OrderedDict([ - ('names', "A list of object names to be plotted separated by comma. Required.") + ('names', "A list of object names to be plotted separated by comma. Required.\n" + "WARNING: no spaces are allowed. If unsure enclose the entire list with quotes.") ]), - 'examples': ["plot_objects gerber_obj.GRB, excellon_obj.DRL"] + 'examples': ["plot_objects gerber_obj.GRB,excellon_obj.DRL"] } def execute(self, args, unnamed_args): diff --git a/tclCommands/TclCommandQuit.py b/tclCommands/TclCommandQuit.py index e0470bdb..34e5f687 100644 --- a/tclCommands/TclCommandQuit.py +++ b/tclCommands/TclCommandQuit.py @@ -21,6 +21,8 @@ class TclCommandQuit(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['quit_flatcam'] + description = '%s %s' % ("--", "Tcl shell command to quit FlatCAM from Tcl shell.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ diff --git a/tclCommands/TclCommandSaveProject.py b/tclCommands/TclCommandSaveProject.py index 899247a2..049d7e74 100644 --- a/tclCommands/TclCommandSaveProject.py +++ b/tclCommands/TclCommandSaveProject.py @@ -11,6 +11,8 @@ class TclCommandSaveProject(TclCommandSignaled): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['save_project'] + description = '%s %s' % ("--", "Saves the FlatCAM project to file.") + # Dictionary of types from Tcl command, needs to be ordered. # For positional arguments arg_names = collections.OrderedDict([ @@ -30,7 +32,7 @@ class TclCommandSaveProject(TclCommandSignaled): help = { 'main': "Saves the FlatCAM project to file.", 'args': collections.OrderedDict([ - ('filename', 'Absolute path to file to open. Required.\n' + ('filename', 'Absolute path to file to save. Required.\n' 'WARNING: no spaces are allowed. If unsure enclose the entire path with quotes.'), ]), 'examples': ['save_project D:\\my_project_file.FlatPrj', diff --git a/tclCommands/TclCommandSaveSys.py b/tclCommands/TclCommandSaveSys.py index 5712515b..137ca8e7 100644 --- a/tclCommands/TclCommandSaveSys.py +++ b/tclCommands/TclCommandSaveSys.py @@ -16,6 +16,8 @@ class TclCommandSaveSys(TclCommandSignaled): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['save_sys', 'save'] + description = '%s %s' % ("--", "Saves the FlatCAM system parameters to defaults file.") + # Dictionary of types from Tcl command, needs to be ordered. # For positional arguments arg_names = collections.OrderedDict([ diff --git a/tclCommands/TclCommandScale.py b/tclCommands/TclCommandScale.py index aa5ebc3e..ac790842 100644 --- a/tclCommands/TclCommandScale.py +++ b/tclCommands/TclCommandScale.py @@ -25,6 +25,8 @@ class TclCommandScale(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['scale'] + description = '%s %s' % ("--", "Will scale the geometry of a named object. Does not create a new object.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str), diff --git a/tclCommands/TclCommandSetActive.py b/tclCommands/TclCommandSetActive.py index 5144289a..6dfecd00 100644 --- a/tclCommands/TclCommandSetActive.py +++ b/tclCommands/TclCommandSetActive.py @@ -14,6 +14,8 @@ class TclCommandSetActive(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['set_active'] + description = '%s %s' % ("--", "Sets a FlatCAM object as active (selected).") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str), @@ -29,7 +31,7 @@ class TclCommandSetActive(TclCommand): # structured help for current command, args needs to be ordered help = { - 'main': 'Sets an object as active.', + 'main': 'Sets a FlatCAM object as active (selected).', 'args': collections.OrderedDict([ ('name', 'Name of the FlatCAM object to be set as active (selected). Required.'), ]), diff --git a/tclCommands/TclCommandSetOrigin.py b/tclCommands/TclCommandSetOrigin.py index 895338e4..e801fd13 100644 --- a/tclCommands/TclCommandSetOrigin.py +++ b/tclCommands/TclCommandSetOrigin.py @@ -34,6 +34,8 @@ class TclCommandSetOrigin(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['set_origin', 'origin'] + description = '%s %s' % ("--", "Set the origin at the specified x,y location.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('loc', str) @@ -41,7 +43,7 @@ class TclCommandSetOrigin(TclCommand): # Dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value option_types = collections.OrderedDict([ - ('auto', bool) + ('auto', str) ]) # array of mandatory options for current Tcl command: required = {'name','outname'} @@ -55,7 +57,7 @@ class TclCommandSetOrigin(TclCommand): ('loc', 'Location to offset all the selected objects. NO SPACES ALLOWED in X and Y pair.\n' 'Use like this: 2,3'), ('auto', 'If set to True it will set the origin to the minimum x, y of the object selection bounding box.' - '-auto=True is not correct but -auto 1 or -auto True is correct.') + '-auto=True is not correct but -auto 1 or -auto True is correct. True (1) or False (0).') ]), 'examples': ['set_origin 3,2', 'set_origin -auto 1', 'origin'] } diff --git a/tclCommands/TclCommandSetSys.py b/tclCommands/TclCommandSetSys.py index a8133317..8ef911bd 100644 --- a/tclCommands/TclCommandSetSys.py +++ b/tclCommands/TclCommandSetSys.py @@ -14,6 +14,8 @@ class TclCommandSetSys(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['set_sys', 'setsys'] + description = '%s %s' % ("--", "Sets the value of the specified system variable.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str), @@ -30,7 +32,7 @@ class TclCommandSetSys(TclCommand): # structured help for current command, args needs to be ordered help = { - 'main': "Sets the value of the system variable.", + 'main': "Sets the value of the specified system variable.", 'args': collections.OrderedDict([ ('name', 'Name of the system variable. Required.'), ('value', 'Value to set.') diff --git a/tclCommands/TclCommandSkew.py b/tclCommands/TclCommandSkew.py index 28da6e1c..b181d9a2 100644 --- a/tclCommands/TclCommandSkew.py +++ b/tclCommands/TclCommandSkew.py @@ -14,6 +14,8 @@ class TclCommandSkew(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['skew'] + description = '%s %s' % ("--", "Will deform (skew) the geometry of a named object. Does not create a new object.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ ('name', str), @@ -30,7 +32,7 @@ class TclCommandSkew(TclCommand): # structured help for current command, args needs to be ordered help = { - 'main': "Shear/Skew an object by angles along x and y dimensions. The reference point is the left corner of " + 'main': "Shear/Skew an object along x and y dimensions. The reference point is the left corner of " "the bounding box of the object.", 'args': collections.OrderedDict([ ('name', 'Name of the object (Gerber, Geometry or Excellon) to be deformed (skewed). Required.'), diff --git a/tclCommands/TclCommandSubtractPoly.py b/tclCommands/TclCommandSubtractPoly.py index 98c43c66..74020f24 100644 --- a/tclCommands/TclCommandSubtractPoly.py +++ b/tclCommands/TclCommandSubtractPoly.py @@ -11,6 +11,9 @@ class TclCommandSubtractPoly(TclCommandSignaled): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['subtract_poly'] + description = '%s %s' % ("--", "Subtract polygon from the given Geometry object. " + "The coordinates are provided in X Y pairs.") + # Dictionary of types from Tcl command, needs to be ordered. # For positional arguments arg_names = collections.OrderedDict([ diff --git a/tclCommands/TclCommandSubtractRectangle.py b/tclCommands/TclCommandSubtractRectangle.py index 2453c584..b50a2467 100644 --- a/tclCommands/TclCommandSubtractRectangle.py +++ b/tclCommands/TclCommandSubtractRectangle.py @@ -19,6 +19,9 @@ class TclCommandSubtractRectangle(TclCommandSignaled): # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['subtract_rectangle'] + description = '%s %s' % ("--", "Subtract a rectangle from the given Geometry object. " + "The coordinates are provided in X Y pairs.") + # Dictionary of types from Tcl command, needs to be ordered. # For positional arguments arg_names = collections.OrderedDict([ diff --git a/tclCommands/TclCommandVersion.py b/tclCommands/TclCommandVersion.py index 86dcc24a..e5653dad 100644 --- a/tclCommands/TclCommandVersion.py +++ b/tclCommands/TclCommandVersion.py @@ -14,6 +14,8 @@ class TclCommandVersion(TclCommand): # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) aliases = ['version'] + description = '%s %s' % ("--", "Checks the program version.") + # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ diff --git a/tclCommands/TclCommandWriteGCode.py b/tclCommands/TclCommandWriteGCode.py index 655f00cb..b96fdfd8 100644 --- a/tclCommands/TclCommandWriteGCode.py +++ b/tclCommands/TclCommandWriteGCode.py @@ -12,6 +12,8 @@ class TclCommandWriteGCode(TclCommandSignaled): # old names for backward compatibility (add_poly, add_polygon) aliases = ['write_gcode'] + description = '%s %s' % ("--", "Saves G-code of a CNC Job object to file.") + # Dictionary of types from Tcl command, needs to be ordered. # For positional arguments arg_names = collections.OrderedDict([ @@ -24,7 +26,7 @@ class TclCommandWriteGCode(TclCommandSignaled): option_types = collections.OrderedDict([ ('preamble', str), ('postamble', str), - ('muted', int) + ('muted', str) ]) # array of mandatory options for current Tcl command: required = {'name','outname'} @@ -38,7 +40,7 @@ class TclCommandWriteGCode(TclCommandSignaled): ('filename', 'Output filename. Required.'), ('preamble', 'Text to append at the beginning.'), ('postamble', 'Text to append at the end.'), - ('muted', 'It will not put errors in the Shell or status bar.') + ('muted', 'It will not put errors in the Shell or status bar. True (1) or False (0)') ]), 'examples': ["write_gcode name c:\\\\gcode_repo"] @@ -67,9 +69,9 @@ class TclCommandWriteGCode(TclCommandSignaled): postamble = args['postamble'] if 'postamble' in args else '' if 'muted' in args: - muted = args['muted'] + muted = bool(eval(args['muted'])) else: - muted = 0 + muted = False # TODO: This is not needed any more? All targets should be present. # If there are promised objects, wait until all promises have been fulfilled. @@ -91,7 +93,7 @@ class TclCommandWriteGCode(TclCommandSignaled): try: obj = self.app.collection.get_by_name(str(obj_name)) except Exception: - if muted == 0: + if muted is False: return "Could not retrieve object: %s" % obj_name else: return "fail" @@ -99,7 +101,7 @@ class TclCommandWriteGCode(TclCommandSignaled): try: obj.export_gcode(str(filename), str(preamble), str(postamble)) except Exception as e: - if not muted: + if muted is False: return "Operation failed: %s" % str(e) else: return diff --git a/tclCommands/__init__.py b/tclCommands/__init__.py index a143eb30..e34cd733 100644 --- a/tclCommands/__init__.py +++ b/tclCommands/__init__.py @@ -99,7 +99,12 @@ def register_all_commands(app, commands): command_instance = class_type(app) for alias in command_instance.aliases: + try: + description = command_instance.description + except AttributeError: + description = '' commands[alias] = { 'fcn': command_instance.execute_wrapper, - 'help': command_instance.get_decorated_help() + 'help': command_instance.get_decorated_help(), + 'description': description } From 1b14e9d4510d1f76fdbbc003472006da339e4c77 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 13 Apr 2020 20:04:44 +0300 Subject: [PATCH 170/209] - updated the App.plot_all() method giving it the possibility to be run as threaded or not - updated the Tcl command PlotAll to be able to run threaded or not --- FlatCAMApp.py | 15 ++++++++++----- README.md | 2 ++ tclCommands/TclCommandDelete.py | 8 +++++--- tclCommands/TclCommandPlotAll.py | 16 +++++++++++----- 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 1d4dde99..5d895528 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -11888,11 +11888,13 @@ class App(QtCore.QObject): if silent is False: self.log.debug(" " + param + " OK!") - def plot_all(self, zoom=True): + def plot_all(self, fit_view=True, use_thread=True): """ Re-generates all plots from all objects. - :return: None + :param fit_view: if True will plot the objects and will adjust the zoom to fit all plotted objects into view + :param use_thread: if True will use threading for plotting the objects + :return: """ self.log.debug("Plot_all()") self.inform.emit('[success] %s...' % _("Redrawing all objects")) @@ -11901,11 +11903,14 @@ class App(QtCore.QObject): def worker_task(obj): with self.proc_container.new("Plotting"): obj.plot(kind=self.defaults["cncjob_plot_kind"]) - if zoom: + if fit_view is True: self.object_plotted.emit(obj) - # Send to worker - self.worker_task.emit({'fcn': worker_task, 'params': [obj]}) + if use_thread is True: + # Send to worker + self.worker_task.emit({'fcn': worker_task, 'params': [obj]}) + else: + worker_task(obj) def register_folder(self, filename): self.defaults["global_last_folder"] = os.path.split(str(filename))[0] diff --git a/README.md b/README.md index 2b0ed24a..c10a265e 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ CAD program, and create G-Code for Isolation routing. - multiple fixes in the Tcl commands (especially regarding the interchange between True/false and 1/0 values) - updated the help for all Tcl Commands - in Tcl Shell, the 'help' command will add also a brief description for each command in the list +- updated the App.plot_all() method giving it the possibility to be run as threaded or not +- updated the Tcl command PlotAll to be able to run threaded or not 11.04.2020 diff --git a/tclCommands/TclCommandDelete.py b/tclCommands/TclCommandDelete.py index 1c482598..339a1120 100644 --- a/tclCommands/TclCommandDelete.py +++ b/tclCommands/TclCommandDelete.py @@ -23,7 +23,7 @@ class TclCommandDelete(TclCommand): # Dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value option_types = collections.OrderedDict([ - ('f', bool) + ('f', str) ]) # array of mandatory options for current Tcl command: required = {'name','outname'} @@ -34,7 +34,9 @@ class TclCommandDelete(TclCommand): 'main': 'Deletes the given object. If no name is given will delete all objects.', 'args': collections.OrderedDict([ ('name', 'Name of the Object.'), - ('f', 'Use this parameter to force deletion.') + ('f', 'Use this parameter to force deletion.\n' + 'Can be used without value which will be auto assumed to be True.\n' + 'Or it can have a value: True (1) or False (0).') ]), 'examples': ['del new_geo -f True\n' 'delete new_geo -f 1\n' @@ -63,7 +65,7 @@ class TclCommandDelete(TclCommand): if args['f'] is None: is_forced = True else: - is_forced = True if eval(str(args['f'])) else False + is_forced = True if bool(eval(str(args['f']))) else False except KeyError: is_forced = True diff --git a/tclCommands/TclCommandPlotAll.py b/tclCommands/TclCommandPlotAll.py index 8efae5fb..d4194f4f 100644 --- a/tclCommands/TclCommandPlotAll.py +++ b/tclCommands/TclCommandPlotAll.py @@ -1,9 +1,9 @@ -from tclCommands.TclCommand import TclCommand +from tclCommands.TclCommand import TclCommandSignaled import collections -class TclCommandPlotAll(TclCommand): +class TclCommandPlotAll(TclCommandSignaled): """ Tcl shell command to update the plot on the user interface. @@ -23,7 +23,7 @@ class TclCommandPlotAll(TclCommand): # Dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value option_types = collections.OrderedDict([ - + ('use_thread', str) ]) # array of mandatory options for current Tcl command: required = {'name','outname'} @@ -33,7 +33,7 @@ class TclCommandPlotAll(TclCommand): help = { 'main': "Plots all objects on GUI.", 'args': collections.OrderedDict([ - + ('use_thread', 'If to use multithreading: True (1) or False (0).') ]), 'examples': ['plot_all'] } @@ -45,5 +45,11 @@ class TclCommandPlotAll(TclCommand): :param unnamed_args: :return: """ + + if 'use_thread' in args: + threaded = bool(eval(args['use_thread'])) + else: + threaded = False + if self.app.cmd_line_headless != 1: - self.app.plot_all() + self.app.plot_all(use_thread=threaded) From 742180d6e38a6605b3e8730aa4235f4614727e21 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 13 Apr 2020 20:28:39 +0300 Subject: [PATCH 171/209] - updated the Tcl commands PlotAll and PlotObjects to have a parameter that control if the objects are to be plotted or not on canvas; it serve as a disable/enable --- FlatCAMApp.py | 34 ++++++++++++++++------------ ObjectCollection.py | 5 ++++ README.md | 1 + tclCommands/TclCommandPlotAll.py | 15 +++++++++++- tclCommands/TclCommandPlotObjects.py | 18 ++++++++++++--- 5 files changed, 54 insertions(+), 19 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 5d895528..5e4ea70b 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -1029,8 +1029,10 @@ class App(QtCore.QObject): 'gbl, gbo, gbp, gbr, gbs, gdo, ger, gko, gm1, gm2, gm3, grb, gtl, gto, gtp, gts, ly15, ly2, ' 'mil, pho, plc, pls, smb, smt, sol, spb, spt, ssb, sst, stc, sts, top, tsm', # Keyword list - "util_autocomplete_keywords": 'Desktop, Documents, FlatConfig, FlatPrj, Marius, My Documents, Paste_1, ' - 'Repetier, Roland_MDX_20, Users, Toolchange_Custom, Toolchange_Probe_MACH3, ' + "util_autocomplete_keywords": 'Desktop, Documents, FlatConfig, FlatPrj, False, ' + 'Marius, My Documents, Paste_1, ' + 'Repetier, Roland_MDX_20, True, Users, Toolchange_Custom, ' + 'Toolchange_Probe_MACH3, ' 'Toolchange_manual, Users, all, angle_x, angle_y, axis, auto, axisoffset, ' 'box, center_x, center_y, columns, combine, connect, contour, default, ' 'depthperpass, dia, diatol, dist, drilled_dias, drillz, dwelltime, ' @@ -2305,28 +2307,30 @@ class App(QtCore.QObject): # ######################### Auto-complete KEYWORDS #################################### # ##################################################################################### self.tcl_commands_list = ['add_circle', 'add_poly', 'add_polygon', 'add_polyline', 'add_rectangle', - 'aligndrill', 'aligndrillgrid', 'bbox', 'bounding_box', 'clear', 'cncjob', 'cutout', - 'del', 'delete', 'drillcncjob', 'export_dxf', 'edxf', 'export_excellon', 'ee', + 'aligndrill', 'aligndrillgrid', 'bbox', 'clear', 'cncjob', 'cutout', + 'del', 'drillcncjob', 'export_dxf', 'edxf', 'export_excellon', 'export_exc', - 'export_gcode', 'export_gerber', 'egr', 'export_svg', 'ext', 'exteriors', 'follow', - 'geo_union', 'geocutout', 'get_names', 'get_sys', 'getsys', 'help', 'import_svg', - 'interiors', 'isolate', 'join_excellon', 'join_excellons', 'join_geometries', - 'join_geometry', 'list_sys', 'listsys', 'milld', 'mills', 'milldrills', 'millslots', + 'export_gcode', 'export_gerber', 'export_svg', 'ext', 'exteriors', 'follow', + 'geo_union', 'geocutout', 'get_bounds', 'get_names', 'get_sys', 'help', 'import_svg', + 'interiors', 'isolate', 'join_excellon', + 'join_geometry', 'list_sys', 'milld', 'mills', 'milldrills', 'millslots', 'mirror', 'ncc', - 'ncc_clear', 'ncr', 'new', 'new_geometry', 'non_copper_regions', 'offset', + 'ncr', 'new', 'new_geometry', 'non_copper_regions', 'offset', 'open_excellon', 'open_gcode', 'open_gerber', 'open_project', 'options', 'origin', - 'paint', 'pan', 'panel', 'panelize', 'plot_all', 'plot_objects', 'quit_flatcam', + 'paint', 'panelize', 'plot_all', 'plot_objects', 'plot_status', 'quit_flatcam', 'save', 'save_project', 'save_sys', 'scale', 'set_active', 'set_origin', 'set_sys', - 'setsys', 'skew', 'subtract_poly', 'subtract_rectangle', + 'skew', 'subtract_poly', 'subtract_rectangle', 'version', 'write_gcode' ] - self.default_keywords = ['Desktop', 'Documents', 'FlatConfig', 'FlatPrj', 'Marius', 'My Documents', 'Paste_1', + self.default_keywords = ['Desktop', 'Documents', 'FlatConfig', 'FlatPrj', 'False', 'Marius', 'My Documents', + 'Paste_1', 'Repetier', 'Roland_MDX_20', 'Users', 'Toolchange_Custom', 'Toolchange_Probe_MACH3', - 'Toolchange_manual', 'Users', 'all', 'angle_x', 'angle_y', 'auto', 'axis', - 'axisoffset', - 'box', 'center_x', 'center_y', 'columns', 'combine', 'connect', 'contour', 'default', + 'Toolchange_manual', 'True', 'Users', + 'all', 'angle_x', 'angle_y', 'auto', 'axis', + 'axisoffset', 'box', 'center_x', 'center_y', 'columns', 'combine', 'connect', + 'contour', 'default', 'depthperpass', 'dia', 'diatol', 'dist', 'drilled_dias', 'drillz', 'dwelltime', 'extracut_length', 'f', 'feedrate_z', 'grbl_11', 'GRBL_laser', 'gridoffsety', 'gridx', 'gridy', diff --git a/ObjectCollection.py b/ObjectCollection.py index f015b031..62d6304d 100644 --- a/ObjectCollection.py +++ b/ObjectCollection.py @@ -912,6 +912,11 @@ class ObjectCollection(QtCore.QAbstractItemModel): raise def get_list(self): + """ + Will return a list of all objects currently opened. + + :return: + """ obj_list = [] for group in self.root_item.child_items: for item in group.child_items: diff --git a/README.md b/README.md index c10a265e..99d47851 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ CAD program, and create G-Code for Isolation routing. - in Tcl Shell, the 'help' command will add also a brief description for each command in the list - updated the App.plot_all() method giving it the possibility to be run as threaded or not - updated the Tcl command PlotAll to be able to run threaded or not +- updated the Tcl commands PlotAll and PlotObjects to have a parameter that control if the objects are to be plotted or not on canvas; it serve as a disable/enable 11.04.2020 diff --git a/tclCommands/TclCommandPlotAll.py b/tclCommands/TclCommandPlotAll.py index d4194f4f..53da1e8f 100644 --- a/tclCommands/TclCommandPlotAll.py +++ b/tclCommands/TclCommandPlotAll.py @@ -23,6 +23,7 @@ class TclCommandPlotAll(TclCommandSignaled): # Dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value option_types = collections.OrderedDict([ + ('plot_status', str), ('use_thread', str) ]) @@ -33,9 +34,10 @@ class TclCommandPlotAll(TclCommandSignaled): help = { 'main': "Plots all objects on GUI.", 'args': collections.OrderedDict([ + ('plot_status', 'If to display or not the objects: True (1) or False (0).'), ('use_thread', 'If to use multithreading: True (1) or False (0).') ]), - 'examples': ['plot_all'] + 'examples': ['plot_all', 'plot_all -plot_status False'] } def execute(self, args, unnamed_args): @@ -51,5 +53,16 @@ class TclCommandPlotAll(TclCommandSignaled): else: threaded = False + if 'plot_status' in args: + if args['plot_status'] is None: + plot_status = True + else: + plot_status = bool(eval(args['plot_status'])) + else: + plot_status = True + + for obj in self.app.collection.get_list(): + obj.options["plot"] = True if plot_status is True else False + if self.app.cmd_line_headless != 1: self.app.plot_all(use_thread=threaded) diff --git a/tclCommands/TclCommandPlotObjects.py b/tclCommands/TclCommandPlotObjects.py index 34585efb..8a26e36c 100644 --- a/tclCommands/TclCommandPlotObjects.py +++ b/tclCommands/TclCommandPlotObjects.py @@ -30,7 +30,7 @@ class TclCommandPlotObjects(TclCommand): # Dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value option_types = collections.OrderedDict([ - + ('plot_status', str) ]) # array of mandatory options for current Tcl command: required = {'name','outname'} @@ -41,7 +41,8 @@ class TclCommandPlotObjects(TclCommand): 'main': "Plot a specified list of objects in GUI.", 'args': collections.OrderedDict([ ('names', "A list of object names to be plotted separated by comma. Required.\n" - "WARNING: no spaces are allowed. If unsure enclose the entire list with quotes.") + "WARNING: no spaces are allowed. If unsure enclose the entire list with quotes."), + ('plot_status', 'If to display or not the objects: True (1) or False (0).') ]), 'examples': ["plot_objects gerber_obj.GRB,excellon_obj.DRL"] } @@ -53,11 +54,22 @@ class TclCommandPlotObjects(TclCommand): :param unnamed_args: :return: """ + + if 'plot_status' in args: + if args['plot_status'] is None: + plot_status = True + else: + plot_status = bool(eval(args['plot_status'])) + else: + plot_status = True + if self.app.cmd_line_headless != 1: names = [x.strip() for x in args['names'].split(",") if x != ''] objs = [] for name in names: - objs.append(self.app.collection.get_by_name(name)) + obj= self.app.collection.get_by_name(name) + obj.options["plot"] = True if plot_status is True else False + objs.append(obj) for obj in objs: obj.plot() From 7e98365885ea833e0ea0ac029398c4ba2103b435 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 13 Apr 2020 20:31:32 +0300 Subject: [PATCH 172/209] - minor update to the autocomplete dictionary --- FlatCAMApp.py | 4 ++-- README.md | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 5e4ea70b..61769ce8 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -1033,7 +1033,7 @@ class App(QtCore.QObject): 'Marius, My Documents, Paste_1, ' 'Repetier, Roland_MDX_20, True, Users, Toolchange_Custom, ' 'Toolchange_Probe_MACH3, ' - 'Toolchange_manual, Users, all, angle_x, angle_y, axis, auto, axisoffset, ' + 'Toolchange_manual, Users, all, axis, auto, axisoffset, ' 'box, center_x, center_y, columns, combine, connect, contour, default, ' 'depthperpass, dia, diatol, dist, drilled_dias, drillz, dwelltime, ' 'extracut_length, f, ' @@ -2328,7 +2328,7 @@ class App(QtCore.QObject): 'Paste_1', 'Repetier', 'Roland_MDX_20', 'Users', 'Toolchange_Custom', 'Toolchange_Probe_MACH3', 'Toolchange_manual', 'True', 'Users', - 'all', 'angle_x', 'angle_y', 'auto', 'axis', + 'all', 'auto', 'axis', 'axisoffset', 'box', 'center_x', 'center_y', 'columns', 'combine', 'connect', 'contour', 'default', 'depthperpass', 'dia', 'diatol', 'dist', 'drilled_dias', 'drillz', diff --git a/README.md b/README.md index 99d47851..fb03c75d 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ CAD program, and create G-Code for Isolation routing. - updated the App.plot_all() method giving it the possibility to be run as threaded or not - updated the Tcl command PlotAll to be able to run threaded or not - updated the Tcl commands PlotAll and PlotObjects to have a parameter that control if the objects are to be plotted or not on canvas; it serve as a disable/enable +- minor update to the autocomplete dictionary 11.04.2020 From 4c196f6baeae85084f75df320625257502dd871c Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 13 Apr 2020 20:44:51 +0300 Subject: [PATCH 173/209] - the Show Shell in Edit -> Preferences will now toggle the Tcl shell based on the current status of the Tcl Shell - updated the Tcl command Isolate help for follow parameter --- FlatCAMApp.py | 15 +++++++++++++++ README.md | 2 ++ flatcamGUI/PreferencesUI.py | 2 +- tclCommands/TclCommandIsolate.py | 2 +- 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 61769ce8..21aad659 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -5453,6 +5453,21 @@ class App(QtCore.QObject): else: self.ui.shell_dock.show() + def on_toggle_shell_from_settings(self, state): + """ + Toggle shell: if is visible close it, if it is closed then open it + :return: None + """ + + self.report_usage("on_toggle_shell_from_settings()") + + if state is True: + if not self.ui.shell_dock.isVisible(): + self.ui.shell_dock.show() + else: + if self.ui.shell_dock.isVisible(): + self.ui.shell_dock.hide() + def on_register_files(self, obj_type=None): """ Called whenever there is a need to register file extensions with FlatCAM. diff --git a/README.md b/README.md index fb03c75d..4996be13 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,8 @@ CAD program, and create G-Code for Isolation routing. - updated the Tcl command PlotAll to be able to run threaded or not - updated the Tcl commands PlotAll and PlotObjects to have a parameter that control if the objects are to be plotted or not on canvas; it serve as a disable/enable - minor update to the autocomplete dictionary +- the Show Shell in Edit -> Preferences will now toggle the Tcl shell based on the current status of the Tcl Shell +- updated the Tcl command Isolate help for follow parameter 11.04.2020 diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index 239b6fbb..33661845 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -1736,7 +1736,7 @@ class GeneralAppPrefGroupUI(OptionsGroupUI): self.splash_cb.stateChanged.connect(self.on_splash_changed) # Monitor the checkbox from the Application Defaults Tab and show the TCL shell or not depending on it's value - self.shell_startup_cb.clicked.connect(self.app.on_toggle_shell) + self.shell_startup_cb.clicked.connect(self.app.on_toggle_shell_from_settings) self.language_apply_btn.clicked.connect(lambda: fcTranslate.on_language_apply_click(app=self.app, restart=True)) diff --git a/tclCommands/TclCommandIsolate.py b/tclCommands/TclCommandIsolate.py index 337280df..9fc4d214 100644 --- a/tclCommands/TclCommandIsolate.py +++ b/tclCommands/TclCommandIsolate.py @@ -52,7 +52,7 @@ class TclCommandIsolate(TclCommandSignaled): 'E.g: for a 25% from tool diameter overlap use -overlap 25'), ('combine', 'Combine all passes into one geometry. Can be True (1) or False (0)'), ('outname', 'Name of the resulting Geometry object.'), - ('follow', 'Create a Geometry that follows the Gerber path.'), + ('follow', 'Create a Geometry that follows the Gerber path. Can be True (1) or False (0).'), ('iso_type', 'A value of 0 will isolate exteriors, a value of 1 will isolate interiors ' 'and a value of 2 will do full isolation.') ]), From e64c7060e57538fe7248119122432b9e1e2f749c Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 13 Apr 2020 23:43:48 +0300 Subject: [PATCH 174/209] - updated DrillCncJob Tcl Command with new parameters and fixed it to work in the new format of the Excellon methods - changed CncJob Tcl Command parameter 'depthperpass' to a shorter 'dpp' --- FlatCAMApp.py | 15 ++-- FlatCAMObj.py | 2 - README.md | 2 + camlib.py | 35 +++++--- tclCommands/TclCommandCncjob.py | 14 +-- tclCommands/TclCommandDrillcncjob.py | 128 +++++++++++++++++++++------ 6 files changed, 143 insertions(+), 53 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 21aad659..3821dd84 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -1035,15 +1035,15 @@ class App(QtCore.QObject): 'Toolchange_Probe_MACH3, ' 'Toolchange_manual, Users, all, axis, auto, axisoffset, ' 'box, center_x, center_y, columns, combine, connect, contour, default, ' - 'depthperpass, dia, diatol, dist, drilled_dias, drillz, dwelltime, ' - 'extracut_length, f, ' + 'depthperpass, dia, diatol, dist, drilled_dias, drillz, dpp, dwelltime, ' + 'endxy, endz, extracut_length, f, feedrate, ' 'feedrate_z, grbl_11, GRBL_laser, gridoffsety, gridx, gridy, has_offset, ' 'holes, hpgl, iso_type, line_xyz, margin, marlin, method, milled_dias, ' 'minoffset, name, offset, opt_type, order, outname, overlap, ' 'passes, postamble, pp, ppname_e, ppname_g, preamble, radius, ref, rest, ' 'rows, shellvar_, scale_factor, spacing_columns, spacing_rows, spindlespeed, ' - 'toolchange_xy, toolchangez, ' - 'tooldia, use_threads, value, x, x0, x1, y, y0, y1, z_cut, ' + 'startz, startxy, toolchange_xy, toolchangez, ' + 'tooldia, travelz, use_threads, value, x, x0, x1, y, y0, y1, z_cut, ' 'z_move', "script_autocompleter": True, "script_text": "", @@ -2331,15 +2331,16 @@ class App(QtCore.QObject): 'all', 'auto', 'axis', 'axisoffset', 'box', 'center_x', 'center_y', 'columns', 'combine', 'connect', 'contour', 'default', - 'depthperpass', 'dia', 'diatol', 'dist', 'drilled_dias', 'drillz', - 'dwelltime', 'extracut_length', 'f', + 'depthperpass', 'dia', 'diatol', 'dist', 'drilled_dias', 'drillz', 'dpp', + 'dwelltime', 'extracut_length', 'endxy', 'enz', 'f', 'feedrate', 'feedrate_z', 'grbl_11', 'GRBL_laser', 'gridoffsety', 'gridx', 'gridy', 'has_offset', 'holes', 'hpgl', 'iso_type', 'line_xyz', 'margin', 'marlin', 'method', 'milled_dias', 'minoffset', 'name', 'offset', 'opt_type', 'order', 'outname', 'overlap', 'passes', 'postamble', 'pp', 'ppname_e', 'ppname_g', 'preamble', 'radius', 'ref', 'rest', 'rows', 'shellvar_', 'scale_factor', 'spacing_columns', - 'spacing_rows', 'spindlespeed', 'toolchange_xy', 'toolchangez', + 'spacing_rows', 'spindlespeed', 'startz', 'startxy', + 'toolchange_xy', 'toolchangez', 'travelz', 'tooldia', 'use_threads', 'value', 'x', 'x0', 'x1', 'y', 'y0', 'y1', 'z_cut', 'z_move' ] diff --git a/FlatCAMObj.py b/FlatCAMObj.py index a8b388bf..0256853a 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -3725,8 +3725,6 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): job_obj.options['type'] = 'Excellon' job_obj.options['ppname_e'] = pp_excellon_name - job_obj.z_cut = float(self.options["cutz"]) - job_obj.multidepth = self.options["multidepth"] job_obj.z_depthpercut = self.options["depthperpass"] diff --git a/README.md b/README.md index 4996be13..4c787ef8 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ CAD program, and create G-Code for Isolation routing. - minor update to the autocomplete dictionary - the Show Shell in Edit -> Preferences will now toggle the Tcl shell based on the current status of the Tcl Shell - updated the Tcl command Isolate help for follow parameter +- updated DrillCncJob Tcl Command with new parameters and fixed it to work in the new format of the Excellon methods +- changed CncJob Tcl Command parameter 'depthperpass' to a shorter 'dpp' 11.04.2020 diff --git a/camlib.py b/camlib.py index bb192a4b..40d84cc0 100644 --- a/camlib.py +++ b/camlib.py @@ -2742,9 +2742,12 @@ class CNCjob(Geometry): LineString([start, stop]).buffer((it[1] / 2.0), resolution=self.geo_steps_per_circle) ) - try: - z_off = float(exobj.tools[it[0]]['data']['offset']) * (-1) - except KeyError: + if self.use_ui: + try: + z_off = float(exobj.tools[it[0]]['data']['offset']) * (-1) + except KeyError: + z_off = 0 + else: z_off = 0 default_data = {} @@ -2790,7 +2793,7 @@ class CNCjob(Geometry): # Initialization gcode = self.doformat(p.start_code) - if not use_ui: + if use_ui is False: gcode += self.doformat(p.z_feedrate_code) if self.toolchange is False: @@ -2873,7 +2876,7 @@ class CNCjob(Geometry): self.postdata['toolC'] = exobj.tools[tool]["C"] self.tooldia = exobj.tools[tool]["C"] - if use_ui: + if self.use_ui: self.z_feedrate = exobj.tools[tool]['data']['feedrate_z'] self.feedrate = exobj.tools[tool]['data']['feedrate'] gcode += self.doformat(p.z_feedrate_code) @@ -2906,6 +2909,8 @@ class CNCjob(Geometry): self.dwelltime = exobj.tools[tool]['data']['dwelltime'] self.multidepth = exobj.tools[tool]['data']['multidepth'] self.z_depthpercut = exobj.tools[tool]['data']['depthperpass'] + else: + old_zcut = deepcopy(self.z_cut) # ############################################### # ############ Create the data. ################# @@ -3000,8 +3005,10 @@ class CNCjob(Geometry): str(self.units)) ) - # TODO apply offset only when using the GUI, for TclCommand this will create an error + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + # APPLY Offset only when using the GUI, for TclCommand this will create an error # because the values for Z offset are created in build_ui() + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! try: z_offset = float(exobj.tools[tool]['data']['offset']) * (-1) except KeyError: @@ -3099,7 +3106,7 @@ class CNCjob(Geometry): self.postdata['toolC']=exobj.tools[tool]["C"] self.tooldia = exobj.tools[tool]["C"] - if use_ui: + if self.use_ui: self.z_feedrate = exobj.tools[tool]['data']['feedrate_z'] self.feedrate = exobj.tools[tool]['data']['feedrate'] gcode += self.doformat(p.z_feedrate_code) @@ -3132,6 +3139,8 @@ class CNCjob(Geometry): self.dwelltime = exobj.tools[tool]['data']['dwelltime'] self.multidepth = exobj.tools[tool]['data']['multidepth'] self.z_depthpercut = exobj.tools[tool]['data']['depthperpass'] + else: + old_zcut = deepcopy(self.z_cut) # ############################################### # ############ Create the data. ################# @@ -3215,8 +3224,10 @@ class CNCjob(Geometry): str(self.units)) ) - # TODO apply offset only when using the GUI, for TclCommand this will create an error + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + # APPLY Offset only when using the GUI, for TclCommand this will create an error # because the values for Z offset are created in build_ui() + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! try: z_offset = float(exobj.tools[tool]['data']['offset']) * (-1) except KeyError: @@ -3316,7 +3327,7 @@ class CNCjob(Geometry): self.postdata['toolC'] = exobj.tools[tool]["C"] self.tooldia = exobj.tools[tool]["C"] - if use_ui: + if self.use_ui: self.z_feedrate = exobj.tools[tool]['data']['feedrate_z'] self.feedrate = exobj.tools[tool]['data']['feedrate'] gcode += self.doformat(p.z_feedrate_code) @@ -3349,6 +3360,8 @@ class CNCjob(Geometry): self.dwelltime = exobj.tools[tool]['data']['dwelltime'] self.multidepth = exobj.tools[tool]['data']['multidepth'] self.z_depthpercut = exobj.tools[tool]['data']['depthperpass'] + else: + old_zcut = deepcopy(self.z_cut) # Only if tool has points. if tool in points: @@ -3375,8 +3388,10 @@ class CNCjob(Geometry): str(self.units)) ) - # TODO apply offset only when using the GUI, for TclCommand this will create an error + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + # APPLY Offset only when using the GUI, for TclCommand this will create an error # because the values for Z offset are created in build_ui() + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! try: z_offset = float(exobj.tools[tool]['data']['offset']) * (-1) except KeyError: diff --git a/tclCommands/TclCommandCncjob.py b/tclCommands/TclCommandCncjob.py index 70bfbcbc..6f41e1df 100644 --- a/tclCommands/TclCommandCncjob.py +++ b/tclCommands/TclCommandCncjob.py @@ -36,7 +36,7 @@ class TclCommandCncjob(TclCommandSignaled): ('feedrate_z', float), ('feedrate_rapid', float), ('extracut_length', float), - ('depthperpass', float), + ('dpp', float), ('toolchangez', float), ('toolchangexy', tuple), ('startz', float), @@ -63,7 +63,7 @@ class TclCommandCncjob(TclCommandSignaled): ('feedrate_z', 'Moving speed on Z plane when cutting.'), ('feedrate_rapid', 'Rapid moving at speed when cutting.'), ('extracut_length', 'The value for extra cnccut over the first point in path,in the job end; float'), - ('depthperpass', 'If present then use multidepth cnc cut. Height of one layer for multidepth.'), + ('dpp', 'If present then use multidepth cnc cut. Height of one layer for multidepth.'), ('toolchangez', 'Z distance for toolchange (example: 30.0).\n' 'If used in the command then a toolchange event will be included in gcode'), ('toolchangexy', 'X, Y coordonates for toolchange in format (x, y) (example: (2.0, 3.1) ).'), @@ -141,12 +141,12 @@ class TclCommandCncjob(TclCommandSignaled): else: args["extracut"] = False - if "depthperpass" in args: + if "dpp" in args: args["multidepth"] = True - if args["depthperpass"] is None: - args["depthperpass"] = obj.options["depthperpass"] + if args["dpp"] is None: + args["dpp"] = obj.options["dpp"] else: - args["depthperpass"] = float(args["depthperpass"]) + args["dpp"] = float(args["dpp"]) else: args["multidepth"] = False @@ -221,7 +221,7 @@ class TclCommandCncjob(TclCommandSignaled): else: local_tools_dict[tool_uid]['data']['extracut_length'] = None - local_tools_dict[tool_uid]['data']['depthperpass'] = args["depthperpass"] + local_tools_dict[tool_uid]['data']['depthperpass'] = args["dpp"] local_tools_dict[tool_uid]['data']['toolchange'] = args["toolchange"] local_tools_dict[tool_uid]['data']['toolchangez'] = args["toolchangez"] local_tools_dict[tool_uid]['data']['toolchangexy'] = args["toolchangexy"] diff --git a/tclCommands/TclCommandDrillcncjob.py b/tclCommands/TclCommandDrillcncjob.py index e0fd5dae..d2f31021 100644 --- a/tclCommands/TclCommandDrillcncjob.py +++ b/tclCommands/TclCommandDrillcncjob.py @@ -4,6 +4,14 @@ from FlatCAMObj import FlatCAMExcellon import collections import math +import gettext +import FlatCAMTranslation as fcTranslate +import builtins + +fcTranslate.apply_language('strings') +if '_' not in builtins.__dict__: + _ = gettext.gettext + class TclCommandDrillcncjob(TclCommandSignaled): """ @@ -24,13 +32,16 @@ class TclCommandDrillcncjob(TclCommandSignaled): option_types = collections.OrderedDict([ ('drilled_dias', str), ('drillz', float), + ('dpp', float), ('travelz', float), - ('feedrate', float), + ('feedrate_z', float), ('feedrate_rapid', float), ('spindlespeed', int), ('toolchangez', float), ('toolchangexy', tuple), + ('startz', float), ('endz', float), + ('endxy', tuple), ('dwelltime', float), ('pp', str), ('opt_type', str), @@ -50,15 +61,18 @@ class TclCommandDrillcncjob(TclCommandSignaled): ('drilled_dias', 'Comma separated tool diameters of the drills to be drilled (example: 0.6,1.0 or 3.125). ' 'No space allowed'), - ('drillz', 'Drill depth into material (example: -2.0).'), + ('drillz', 'Drill depth into material (example: -2.0). Negative value.'), + ('dpp', 'Progressive drilling into material with a specified step (example: 0.7). Positive value.'), ('travelz', 'Travel distance above material (example: 2.0).'), - ('feedrate', 'Drilling feed rate.'), + ('feedrate_z', 'Drilling feed rate. It is the speed on the Z axis.'), ('feedrate_rapid', 'Rapid drilling feed rate.'), ('spindlespeed', 'Speed of the spindle in rpm (example: 4000).'), ('toolchangez', 'Z distance for toolchange (example: 30.0).\n' 'If used in the command then a toolchange event will be included in gcode'), ('toolchangexy', 'X, Y coordonates for toolchange in format (x, y) (example: (2.0, 3.1) ).'), - ('endz', 'Z distance at job end (example: 30.0).'), + ('startz', 'The Z coordinate at job start (example: 30.0).'), + ('endz', 'The Z coordinate at job end (example: 30.0).'), + ('endxy', 'The X,Y coordinates at job end in format (x, y) (example: (30.0, 15.2)).'), ('dwelltime', 'Time to pause to allow the spindle to reach the full speed.\n' 'If it is not used in command then it will not be included'), ('pp', 'This is the Excellon preprocessor name: case_sensitive, no_quotes'), @@ -73,9 +87,10 @@ class TclCommandDrillcncjob(TclCommandSignaled): ('muted', 'It will not put errors in the Shell or status bar. Can be True (1) or False (0).'), ('outname', 'Name of the resulting Geometry object.') ]), - 'examples': ['drillcncjob test.TXT -drillz -1.5 -travelz 14 -feedrate 222 -feedrate_rapid 456 -spindlespeed 777' - ' -toolchangez 33 -endz 22 -pp default\n' - 'Usage of -feedrate_rapid matter only when the preprocessor is using it, like -marlin-.'] + 'examples': ['drillcncjob test.TXT -drillz -1.5 -travelz 14 -feedrate_z 222 -feedrate_rapid 456 ' + '-spindlespeed 777 -toolchangez 33 -endz 22 -pp default\n' + 'Usage of -feedrate_rapid matter only when the preprocessor is using it, like -marlin-.', + 'drillcncjob test.DRL -drillz -1.7 -dpp 0.5 -travelz 2 -feedrate_z 800 -endxy 3,3'] } def execute(self, args, unnamed_args): @@ -171,6 +186,35 @@ class TclCommandDrillcncjob(TclCommandSignaled): else: return "fail" + used_tools_info = [] + used_tools_info.insert(0, [_("Tool_nr"), _("Diameter"), _("Drills_Nr"), _("Slots_Nr")]) + + # populate the information's list for used tools + if tools == 'all': + sort = [] + for k, v in list(obj.tools.items()): + sort.append((k, v.get('C'))) + sorted_tools = sorted(sort, key=lambda t1: t1[1]) + use_tools = [i[0] for i in sorted_tools] + + for tool_no in use_tools: + tool_dia_used = obj.tools[tool_no]['C'] + + drill_cnt = 0 # variable to store the nr of drills per tool + slot_cnt = 0 # variable to store the nr of slots per tool + + # Find no of drills for the current tool + for drill in obj.drills: + if drill['tool'] == tool_no: + drill_cnt += 1 + + # Find no of slots for the current tool + for slot in obj.slots: + if slot['tool'] == tool_no: + slot_cnt += 1 + + used_tools_info.append([str(tool_no), str(tool_dia_used), str(drill_cnt), str(slot_cnt)]) + drillz = args["drillz"] if "drillz" in args and args["drillz"] is not None else obj.options["cutz"] if "toolchangez" in args: @@ -183,17 +227,48 @@ class TclCommandDrillcncjob(TclCommandSignaled): toolchange = False toolchangez = 0.0 + xy_toolchange = args["toolchangexy"] if "toolchangexy" in args and args["toolchangexy"] else \ + obj.options["toolchangexy"] + xy_toolchange = ','.join([xy_toolchange[0], xy_toolchange[2]]) + endz = args["endz"] if "endz" in args and args["endz"] is not None else obj.options["endz"] + xy_end = args["endxy"] if "endxy" in args and args["endxy"] else '0,0' + xy_end = ','.join([xy_end[0], xy_end[2]]) + print(xy_end) opt_type = args["opt_type"] if "opt_type" in args and args["opt_type"] else 'B' - job_obj.z_move = args["travelz"] if "travelz" in args and args["travelz"] else obj.options["travelz"] + # ########################################################################################## + # ################# Set parameters ######################################################### + # ########################################################################################## + job_obj.origin_kind = 'excellon' - job_obj.feedrate = args["feedrate"] if "feedrate" in args and args["feedrate"] else obj.options["feedrate"] - job_obj.z_feedrate = args["feedrate"] if "feedrate" in args and args["feedrate"] else \ - obj.options["feedrate"] - job_obj.feedrate_rapid = args["feedrate_rapid"] \ + job_obj.options['Tools_in_use'] = used_tools_info + job_obj.options['type'] = 'Excellon' + + pp_excellon_name = args["pp"] if "pp" in args and args["pp"] else obj.options["ppname_e"] + job_obj.pp_excellon_name = pp_excellon_name + job_obj.options['ppname_e'] = pp_excellon_name + + if 'dpp' in args: + job_obj.multidepth = True + if args['dpp'] is not None: + job_obj.z_depthpercut = float(args['dpp']) + else: + job_obj.z_depthpercut = float(obj.options["dpp"]) + else: + job_obj.multidepth = False + job_obj.z_depthpercut = 0.0 + + job_obj.z_move = float(args["travelz"]) if "travelz" in args and args["travelz"] else obj.options["travelz"] + job_obj.feedrate = float(args["feedrate_z"]) if "feedrate_z" in args and args["feedrate_z"] else \ + obj.options["feedrate_z"] + job_obj.z_feedrate = float(args["feedrate_z"]) if "feedrate_z" in args and args["feedrate_z"] else \ + obj.options["feedrate_z"] + job_obj.feedrate_rapid = float(args["feedrate_rapid"]) \ if "feedrate_rapid" in args and args["feedrate_rapid"] else obj.options["feedrate_rapid"] + job_obj.spindlespeed = float(args["spindlespeed"]) if "spindlespeed" in args else None + job_obj.spindledir = self.app.defaults['excellon_spindledir'] if 'dwelltime' in args: job_obj.dwell = True if args['dwelltime'] is not None: @@ -204,35 +279,34 @@ class TclCommandDrillcncjob(TclCommandSignaled): job_obj.dwell = False job_obj.dwelltime = 0.0 - job_obj.spindlespeed = args["spindlespeed"] if "spindlespeed" in args else None - job_obj.pp_excellon_name = args["pp"] if "pp" in args and args["pp"] \ - else obj.options["ppname_e"] - + job_obj.toolchange_xy_type = "excellon" job_obj.coords_decimals = int(self.app.defaults["cncjob_coords_decimals"]) job_obj.fr_decimals = int(self.app.defaults["cncjob_fr_decimals"]) - job_obj.options['type'] = 'Excellon' - - job_obj.toolchangexy = args["toolchangexy"] if "toolchangexy" in args and args["toolchangexy"] else \ - obj.options["toolchangexy"] - - job_obj.toolchange_xy_type = "excellon" - job_obj.options['xmin'] = xmin job_obj.options['ymin'] = ymin job_obj.options['xmax'] = xmax job_obj.options['ymax'] = ymax - job_obj.generate_from_excellon_by_tool(obj, tools, drillz=drillz, toolchangez=toolchangez, endz=endz, - toolchange=toolchange, excellon_optimization_type=opt_type) + job_obj.z_cut = float(drillz) + job_obj.toolchange = toolchange + job_obj.xy_toolchange = xy_toolchange + job_obj.z_toolchange = float(toolchangez) + job_obj.startz = float(args["startz"]) if "endz" in args and args["endz"] is not None else (0, 0) + job_obj.endz = float(endz) + job_obj.xy_end = xy_end + job_obj.excellon_optimization_type = opt_type + + ret_val = job_obj.generate_from_excellon_by_tool(obj, tools, use_ui=False) + + if ret_val == 'fail': + return 'fail' for t_item in job_obj.exc_cnc_tools: job_obj.exc_cnc_tools[t_item]['data']['offset'] = \ float(job_obj.exc_cnc_tools[t_item]['offset_z']) + float(drillz) job_obj.exc_cnc_tools[t_item]['data']['ppname_e'] = obj.options['ppname_e'] - job_obj.origin_kind = 'excellon' - job_obj.gcode_parse() job_obj.create_geometry() From cb52f1c10aa290fb42521b2447f4894716f71589 Mon Sep 17 00:00:00 2001 From: Marius Date: Tue, 14 Apr 2020 04:30:47 +0300 Subject: [PATCH 175/209] - lightened the hue of the color for 'success' messages printed in the Tcl Shell browser --- README.md | 5 +++++ flatcamTools/ToolShell.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4c787ef8..54b7e758 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +14.04.2020 + +- lightened the hue of the color for 'success' messages printed in the Tcl Shell browser + 13.04.2020 - added the outname parameter for the geocutout Tcl command @@ -22,6 +26,7 @@ CAD program, and create G-Code for Isolation routing. - the Show Shell in Edit -> Preferences will now toggle the Tcl shell based on the current status of the Tcl Shell - updated the Tcl command Isolate help for follow parameter - updated DrillCncJob Tcl Command with new parameters and fixed it to work in the new format of the Excellon methods +- fixed issue #399 - changed CncJob Tcl Command parameter 'depthperpass' to a shorter 'dpp' 11.04.2020 diff --git a/flatcamTools/ToolShell.py b/flatcamTools/ToolShell.py index 9c216bc7..92c3f45c 100644 --- a/flatcamTools/ToolShell.py +++ b/flatcamTools/ToolShell.py @@ -102,7 +102,7 @@ class TermWidget(QWidget): elif style == 'warning': text = '%s' % text elif style == 'success': - text = '%s' % text + text = '%s' % text elif style == 'selected': text = '' else: From c5926ae99f24185f5172b406243682385a490069 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Tue, 14 Apr 2020 13:42:49 +0300 Subject: [PATCH 176/209] - modified the extensions all over such the names include also the extension name. For Linux who does not display the extensions in the native FileDialog. - added descriptions for some of the methods in the app. - added lightened icons for the dark theme from Leandro Heck --- FlatCAMApp.py | 218 ++++++++++-------- FlatCAMObj.py | 94 ++++++-- README.md | 3 + share/dark_resources/about32.png | Bin 1996 -> 0 bytes share/dark_resources/active_static.png | Bin 234 -> 424 bytes share/dark_resources/addarray16.png | Bin 157 -> 378 bytes share/dark_resources/addarray20.png | Bin 176 -> 540 bytes share/dark_resources/addarray32.png | Bin 251 -> 423 bytes share/dark_resources/aero.png | Bin 468 -> 1140 bytes share/dark_resources/aero_arc.png | Bin 479 -> 1151 bytes share/dark_resources/aero_array.png | Bin 482 -> 1157 bytes share/dark_resources/aero_buffer.png | Bin 512 -> 1159 bytes share/dark_resources/aero_circle.png | Bin 505 -> 1158 bytes share/dark_resources/aero_circle_geo.png | Bin 505 -> 1160 bytes share/dark_resources/aero_disc.png | Bin 481 -> 1143 bytes share/dark_resources/aero_drill.png | Bin 461 -> 1142 bytes share/dark_resources/aero_drill_array.png | Bin 492 -> 1162 bytes share/dark_resources/aero_path1.png | Bin 516 -> 1152 bytes share/dark_resources/aero_path2.png | Bin 500 -> 1154 bytes share/dark_resources/aero_path3.png | Bin 482 -> 1145 bytes share/dark_resources/aero_path4.png | Bin 481 -> 1145 bytes share/dark_resources/aero_path5.png | Bin 553 -> 1194 bytes share/dark_resources/aero_semidisc.png | Bin 469 -> 1143 bytes share/dark_resources/aero_slot.png | Bin 460 -> 1136 bytes share/dark_resources/aero_text.png | Bin 508 -> 1164 bytes share/dark_resources/align_center32.png | Bin 168 -> 387 bytes share/dark_resources/align_justify32.png | Bin 123 -> 347 bytes share/dark_resources/align_left32.png | Bin 165 -> 373 bytes share/dark_resources/align_right32.png | Bin 168 -> 363 bytes share/dark_resources/aperture16.png | Bin 150 -> 554 bytes share/dark_resources/aperture32.png | Bin 296 -> 920 bytes share/dark_resources/arc16.png | Bin 326 -> 525 bytes share/dark_resources/arc24.png | Bin 445 -> 653 bytes share/dark_resources/arc32.png | Bin 625 -> 786 bytes share/dark_resources/axis32.png | Bin 297 -> 645 bytes share/dark_resources/backup24.png | Bin 199 -> 504 bytes share/dark_resources/backup_export24.png | Bin 177 -> 356 bytes share/dark_resources/backup_import24.png | Bin 186 -> 374 bytes share/dark_resources/blocked16.png | Bin 2188 -> 2935 bytes share/dark_resources/bold32.png | Bin 589 -> 622 bytes share/dark_resources/bookmarks16.png | Bin 136 -> 377 bytes share/dark_resources/bookmarks32.png | Bin 226 -> 431 bytes share/dark_resources/buffer16-2.png | Bin 148 -> 493 bytes share/dark_resources/buffer16.png | Bin 466 -> 579 bytes share/dark_resources/buffer20.png | Bin 170 -> 509 bytes share/dark_resources/buffer24.png | Bin 191 -> 565 bytes share/dark_resources/bug16.png | Bin 189 -> 504 bytes share/dark_resources/bug32.png | Bin 341 -> 958 bytes share/dark_resources/calculator16.png | Bin 340 -> 549 bytes share/dark_resources/calculator24.png | Bin 499 -> 679 bytes share/dark_resources/calibrate_16.png | Bin 242 -> 380 bytes share/dark_resources/calibrate_32.png | Bin 366 -> 459 bytes share/dark_resources/cancel_edit16.png | Bin 453 -> 520 bytes share/dark_resources/cancel_edit32.png | Bin 696 -> 625 bytes share/dark_resources/circle32.png | Bin 271 -> 601 bytes share/dark_resources/clear_plot16.png | Bin 640 -> 675 bytes share/dark_resources/clear_plot32.png | Bin 1439 -> 1047 bytes share/dark_resources/close_edit_file16.png | Bin 289 -> 494 bytes share/dark_resources/close_edit_file32.png | Bin 252 -> 690 bytes share/dark_resources/cnc16.png | Bin 431 -> 538 bytes share/dark_resources/cnc32.png | Bin 967 -> 716 bytes share/dark_resources/code.png | Bin 237 -> 676 bytes share/dark_resources/code_editor32.png | Bin 214 -> 414 bytes share/dark_resources/convert24.png | Bin 194 -> 565 bytes share/dark_resources/copperfill16.png | Bin 187 -> 602 bytes share/dark_resources/copperfill32.png | Bin 344 -> 1051 bytes share/dark_resources/copy.png | Bin 170 -> 600 bytes share/dark_resources/copy16.png | Bin 288 -> 526 bytes share/dark_resources/copy32.png | Bin 832 -> 743 bytes share/dark_resources/copy_16.png | Bin 288 -> 395 bytes share/dark_resources/copy_file16.png | Bin 156 -> 462 bytes share/dark_resources/copy_file32.png | Bin 227 -> 617 bytes share/dark_resources/copy_geo.png | Bin 582 -> 605 bytes share/dark_resources/corner32.png | Bin 913 -> 815 bytes share/dark_resources/cut16.png | Bin 166 -> 504 bytes share/dark_resources/cut16_bis.png | Bin 175 -> 578 bytes share/dark_resources/cut32.png | Bin 268 -> 705 bytes share/dark_resources/cut32_bis.png | Bin 335 -> 1122 bytes share/dark_resources/cutpath16.png | Bin 465 -> 536 bytes share/dark_resources/cutpath24.png | Bin 691 -> 675 bytes share/dark_resources/cutpath32.png | Bin 853 -> 778 bytes share/dark_resources/database32.png | Bin 296 -> 959 bytes share/dark_resources/defaults.png | Bin 211 -> 834 bytes share/dark_resources/delete32.png | Bin 943 -> 745 bytes share/dark_resources/delete_file16.png | Bin 171 -> 547 bytes share/dark_resources/delete_file32.png | Bin 281 -> 848 bytes share/dark_resources/deleteshape16.png | Bin 386 -> 578 bytes share/dark_resources/deleteshape24.png | Bin 493 -> 656 bytes share/dark_resources/deleteshape32.png | Bin 600 -> 766 bytes share/dark_resources/deselect_all32.png | Bin 267 -> 712 bytes share/dark_resources/disable16.png | Bin 180 -> 522 bytes share/dark_resources/disable32.png | Bin 320 -> 843 bytes share/dark_resources/disc32.png | Bin 234 -> 650 bytes share/dark_resources/distance16.png | Bin 169 -> 479 bytes share/dark_resources/distance32.png | Bin 242 -> 612 bytes share/dark_resources/distance_min16.png | Bin 133 -> 400 bytes share/dark_resources/distance_min32.png | Bin 200 -> 408 bytes share/dark_resources/doubleside16.png | Bin 350 -> 501 bytes share/dark_resources/doubleside32.png | Bin 614 -> 661 bytes share/dark_resources/draw32.png | Bin 279 -> 684 bytes share/dark_resources/drill16.png | Bin 175 -> 509 bytes share/dark_resources/drill32.png | Bin 251 -> 740 bytes share/dark_resources/dxf16.png | Bin 344 -> 688 bytes share/dark_resources/edit16.png | Bin 482 -> 537 bytes share/dark_resources/edit32.png | Bin 912 -> 748 bytes share/dark_resources/edit_file16.png | Bin 307 -> 510 bytes share/dark_resources/edit_file32.png | Bin 277 -> 716 bytes share/dark_resources/edit_ok16.png | Bin 486 -> 524 bytes share/dark_resources/edit_ok32.png | Bin 843 -> 647 bytes share/dark_resources/edit_ok32_bis.png | Bin 1581 -> 1235 bytes share/dark_resources/eraser26.png | Bin 928 -> 1395 bytes share/dark_resources/explode32.png | Bin 338 -> 830 bytes share/dark_resources/export.png | Bin 203 -> 546 bytes share/dark_resources/export_png32.png | Bin 275 -> 796 bytes share/dark_resources/fiducials_32.png | Bin 191 -> 455 bytes share/dark_resources/file16.png | Bin 479 -> 694 bytes share/dark_resources/file32.png | Bin 200 -> 502 bytes share/dark_resources/film16.png | Bin 258 -> 441 bytes share/dark_resources/film32.png | Bin 179 -> 0 bytes share/dark_resources/flatcam_icon128.png | Bin 1735 -> 1761 bytes share/dark_resources/flatcam_icon16.png | Bin 219 -> 464 bytes share/dark_resources/flatcam_icon24.png | Bin 314 -> 591 bytes share/dark_resources/flatcam_icon256.png | Bin 4401 -> 3820 bytes share/dark_resources/flatcam_icon32.png | Bin 359 -> 703 bytes share/dark_resources/flatcam_icon32_green.png | Bin 994 -> 994 bytes share/dark_resources/flatcam_icon48.png | Bin 614 -> 906 bytes share/dark_resources/flipx.png | Bin 514 -> 515 bytes share/dark_resources/flipy.png | Bin 522 -> 496 bytes share/dark_resources/floppy16.png | Bin 458 -> 749 bytes share/dark_resources/floppy32.png | Bin 373 -> 531 bytes share/dark_resources/folder16.png | Bin 367 -> 615 bytes share/dark_resources/folder32.png | Bin 391 -> 525 bytes share/dark_resources/folder32_Excellon.png | Bin 453 -> 585 bytes share/dark_resources/folder32_bis.png | Bin 208 -> 604 bytes share/dark_resources/folder32_gerber.png | Bin 456 -> 593 bytes share/dark_resources/fscreen32.png | Bin 10536 -> 3398 bytes share/dark_resources/gear32.png | Bin 452 -> 876 bytes share/dark_resources/gear48.png | Bin 727 -> 1146 bytes share/dark_resources/geometry16.png | Bin 693 -> 617 bytes share/dark_resources/globe16.png | Bin 884 -> 1152 bytes share/dark_resources/goemetry32.png | Bin 1015 -> 658 bytes share/dark_resources/grid16.png | Bin 499 -> 631 bytes share/dark_resources/grid32.png | Bin 850 -> 877 bytes share/dark_resources/grid32_menu.png | Bin 175 -> 444 bytes share/dark_resources/help.png | Bin 422 -> 1144 bytes share/dark_resources/home16.png | Bin 396 -> 629 bytes share/dark_resources/image16.png | Bin 170 -> 468 bytes share/dark_resources/image32.png | Bin 305 -> 677 bytes share/dark_resources/import.png | Bin 213 -> 550 bytes share/dark_resources/info16.png | Bin 603 -> 821 bytes share/dark_resources/intersection16.png | Bin 476 -> 514 bytes share/dark_resources/intersection24.png | Bin 639 -> 589 bytes share/dark_resources/intersection32.png | Bin 829 -> 723 bytes share/dark_resources/italic32.png | Bin 203 -> 463 bytes share/dark_resources/join16.png | Bin 541 -> 548 bytes share/dark_resources/join32.png | Bin 1275 -> 945 bytes share/dark_resources/jump_to16.png | Bin 159 -> 478 bytes share/dark_resources/jump_to32.png | Bin 296 -> 711 bytes share/dark_resources/language32.png | Bin 262 -> 583 bytes share/dark_resources/letter_t_32.png | Bin 135 -> 368 bytes share/dark_resources/link16.png | Bin 168 -> 0 bytes share/dark_resources/machine16.png | Bin 669 -> 932 bytes share/dark_resources/markarea32.png | Bin 221 -> 745 bytes share/dark_resources/move16.png | Bin 151 -> 489 bytes share/dark_resources/move32.png | Bin 906 -> 772 bytes share/dark_resources/move32_bis.png | Bin 253 -> 595 bytes share/dark_resources/ncc16.png | Bin 161 -> 443 bytes share/dark_resources/new_exc32.png | Bin 1235 -> 1064 bytes share/dark_resources/new_file16.png | Bin 132 -> 405 bytes share/dark_resources/new_file32.png | Bin 183 -> 487 bytes share/dark_resources/new_file_exc16.png | Bin 642 -> 642 bytes share/dark_resources/new_file_exc32.png | Bin 842 -> 842 bytes share/dark_resources/new_file_geo16.png | Bin 605 -> 605 bytes share/dark_resources/new_file_geo32.png | Bin 640 -> 640 bytes share/dark_resources/new_file_grb16.png | Bin 679 -> 679 bytes share/dark_resources/new_file_grb32.png | Bin 777 -> 777 bytes share/dark_resources/new_geo16.png | Bin 255 -> 430 bytes share/dark_resources/new_geo32.png | Bin 352 -> 523 bytes share/dark_resources/new_geo32_bis.png | Bin 1504 -> 1201 bytes share/dark_resources/notebook16.png | Bin 122 -> 400 bytes share/dark_resources/notebook32.png | Bin 160 -> 433 bytes share/dark_resources/notes16.png | Bin 148 -> 463 bytes share/dark_resources/notes16_1.png | Bin 148 -> 438 bytes share/dark_resources/offset32.png | Bin 195 -> 361 bytes share/dark_resources/offsetx32.png | Bin 195 -> 399 bytes share/dark_resources/offsety32.png | Bin 229 -> 436 bytes share/dark_resources/open_excellon32.png | Bin 167 -> 737 bytes share/dark_resources/open_script32.png | Bin 560 -> 831 bytes share/dark_resources/origin.png | Bin 511 -> 610 bytes share/dark_resources/origin16.png | Bin 182 -> 586 bytes share/dark_resources/origin32.png | Bin 260 -> 804 bytes share/dark_resources/padarray32.png | Bin 193 -> 409 bytes share/dark_resources/paint16.png | Bin 168 -> 479 bytes share/dark_resources/paint20.png | Bin 203 -> 569 bytes share/dark_resources/paint20_1.png | Bin 167 -> 495 bytes share/dark_resources/panel16.png | Bin 124 -> 534 bytes share/dark_resources/panel32.png | Bin 279 -> 1108 bytes share/dark_resources/panelize16.png | Bin 137 -> 449 bytes share/dark_resources/panelize32.png | Bin 210 -> 554 bytes share/dark_resources/path32.png | Bin 282 -> 724 bytes share/dark_resources/pdf32.png | Bin 1539 -> 1884 bytes share/dark_resources/pdf_link16.png | Bin 171 -> 412 bytes share/dark_resources/plot32.png | Bin 226 -> 438 bytes share/dark_resources/plus16.png | Bin 116 -> 338 bytes share/dark_resources/plus32.png | Bin 152 -> 403 bytes share/dark_resources/pointer.png | Bin 25986 -> 5167 bytes share/dark_resources/pointer32.png | Bin 250 -> 616 bytes share/dark_resources/poligonize32.png | Bin 218 -> 568 bytes share/dark_resources/polygon32.png | Bin 282 -> 744 bytes share/dark_resources/power16.png | Bin 669 -> 835 bytes share/dark_resources/pref.png | Bin 237 -> 793 bytes share/dark_resources/printer16.png | Bin 559 -> 565 bytes share/dark_resources/printer32.png | Bin 325 -> 870 bytes share/dark_resources/project16.png | Bin 204 -> 534 bytes share/dark_resources/project_save16.png | Bin 496 -> 504 bytes share/dark_resources/project_save32.png | Bin 217 -> 629 bytes share/dark_resources/properties32.png | Bin 206 -> 413 bytes share/dark_resources/qrcode32.png | Bin 765 -> 618 bytes share/dark_resources/recent_files.png | Bin 265 -> 755 bytes share/dark_resources/rectangle32.png | Bin 147 -> 442 bytes share/dark_resources/recycle16.png | Bin 621 -> 890 bytes share/dark_resources/replot16.png | Bin 547 -> 648 bytes share/dark_resources/replot32.png | Bin 1102 -> 1008 bytes share/dark_resources/resize16.png | Bin 161 -> 428 bytes share/dark_resources/rotate.png | Bin 426 -> 1066 bytes share/dark_resources/rules32.png | Bin 170 -> 423 bytes share/dark_resources/save_as.png | Bin 246 -> 683 bytes share/dark_resources/scale32.png | Bin 232 -> 680 bytes share/dark_resources/script14.png | Bin 141 -> 418 bytes share/dark_resources/script16.png | Bin 164 -> 509 bytes share/dark_resources/script_new16.png | Bin 175 -> 449 bytes share/dark_resources/script_new24.png | Bin 223 -> 455 bytes share/dark_resources/script_open16.png | Bin 160 -> 501 bytes share/dark_resources/script_open18.png | Bin 170 -> 423 bytes share/dark_resources/script_open24.png | Bin 195 -> 525 bytes share/dark_resources/select_all.png | Bin 650 -> 647 bytes share/dark_resources/semidisc32.png | Bin 253 -> 645 bytes share/dark_resources/shell16.png | Bin 150 -> 479 bytes share/dark_resources/shell32.png | Bin 233 -> 597 bytes share/dark_resources/shortcuts24.png | Bin 177 -> 726 bytes share/dark_resources/skewX.png | Bin 296 -> 692 bytes share/dark_resources/skewY.png | Bin 286 -> 655 bytes share/dark_resources/slot26.png | Bin 131 -> 1023 bytes share/dark_resources/slot_array26.png | Bin 143 -> 1025 bytes share/dark_resources/snap_16.png | Bin 426 -> 557 bytes share/dark_resources/snap_filled_16.png | Bin 176 -> 337 bytes share/dark_resources/solderpaste32.png | Bin 315 -> 879 bytes share/dark_resources/solderpastebis32.png | Bin 303 -> 602 bytes share/dark_resources/source32.png | Bin 12171 -> 9304 bytes share/dark_resources/sub32.png | Bin 243 -> 779 bytes share/dark_resources/subtract16.png | Bin 461 -> 517 bytes share/dark_resources/subtract24.png | Bin 766 -> 665 bytes share/dark_resources/subtract32.png | Bin 954 -> 804 bytes share/dark_resources/svg16.png | Bin 13012 -> 10390 bytes share/dark_resources/svg32.png | Bin 296 -> 809 bytes share/dark_resources/text32.png | Bin 167 -> 352 bytes share/dark_resources/toggle_units16.png | Bin 191 -> 476 bytes share/dark_resources/toggle_units32.png | Bin 349 -> 655 bytes share/dark_resources/track32.png | Bin 246 -> 553 bytes share/dark_resources/transform.png | Bin 202 -> 571 bytes share/dark_resources/trash16.png | Bin 512 -> 791 bytes share/dark_resources/trash32.png | Bin 297 -> 565 bytes share/dark_resources/tv16.png | Bin 480 -> 761 bytes share/dark_resources/underline32.png | Bin 204 -> 528 bytes share/dark_resources/union16.png | Bin 466 -> 512 bytes share/dark_resources/union32.png | Bin 849 -> 755 bytes share/dark_resources/videohelp24.png | Bin 222 -> 684 bytes share/dark_resources/view64.png | Bin 693 -> 1610 bytes share/dark_resources/workspace24.png | Bin 146 -> 460 bytes share/dark_resources/zoom_fit32.png | Bin 441 -> 790 bytes share/dark_resources/zoom_in32.png | Bin 422 -> 772 bytes share/dark_resources/zoom_out32.png | Bin 316 -> 723 bytes 272 files changed, 204 insertions(+), 111 deletions(-) delete mode 100644 share/dark_resources/about32.png delete mode 100644 share/dark_resources/film32.png delete mode 100644 share/dark_resources/link16.png diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 3821dd84..dd8f0e61 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -545,23 +545,24 @@ class App(QtCore.QObject): "gerber_def_units": 'IN', "gerber_def_zeros": 'L', - "gerber_save_filters": "Gerber File (*.gbr);;Gerber File (*.bot);;Gerber File (*.bsm);;" - "Gerber File (*.cmp);;Gerber File (*.crc);;Gerber File (*.crs);;" - "Gerber File (*.gb0);;Gerber File (*.gb1);;Gerber File (*.gb2);;" - "Gerber File (*.gb3);;Gerber File (*.gb4);;Gerber File (*.gb5);;" - "Gerber File (*.gb6);;Gerber File (*.gb7);;Gerber File (*.gb8);;" - "Gerber File (*.gb9);;Gerber File (*.gbd);;Gerber File (*.gbl);;" - "Gerber File (*.gbo);;Gerber File (*.gbp);;Gerber File (*.gbs);;" - "Gerber File (*.gdo);;Gerber File (*.ger);;Gerber File (*.gko);;" - "Gerber File (*.gm1);;Gerber File (*.gm2);;Gerber File (*.gm3);;" - "Gerber File (*.grb);;Gerber File (*.gtl);;Gerber File (*.gto);;" - "Gerber File (*.gtp);;Gerber File (*.gts);;Gerber File (*.ly15);;" - "Gerber File (*.ly2);;Gerber File (*.mil);;Gerber File (*.pho);;" - "Gerber File (*.plc);;Gerber File (*.pls);;Gerber File (*.smb);;" - "Gerber File (*.smt);;Gerber File (*.sol);;Gerber File (*.spb);;" - "Gerber File (*.spt);;Gerber File (*.ssb);;Gerber File (*.sst);;" - "Gerber File (*.stc);;Gerber File (*.sts);;Gerber File (*.top);;" - "Gerber File (*.tsm);;Gerber File (*.art)" + "gerber_save_filters": "Gerber File .gbr (*.gbr);;Gerber File .bot (*.bot);;Gerber File .bsm (*.bsm);;" + "Gerber File .cmp (*.cmp);;Gerber File .crc (*.crc);;Gerber File .crs (*.crs);;" + "Gerber File .gb0 (*.gb0);;Gerber File .gb1 (*.gb1);;Gerber File .gb2 (*.gb2);;" + "Gerber File .gb3 (*.gb3);;Gerber File .gb4 (*.gb4);;Gerber File .gb5 (*.gb5);;" + "Gerber File .gb6 (*.gb6);;Gerber File .gb7 (*.gb7);;Gerber File .gb8 (*.gb8);;" + "Gerber File .gb9 (*.gb9);;Gerber File .gbd (*.gbd);;Gerber File .gbl (*.gbl);;" + "Gerber File .gbo (*.gbo);;Gerber File .gbp (*.gbp);;Gerber File .gbs (*.gbs);;" + "Gerber File .gdo (*.gdo);;Gerber File .ger (*.ger);;Gerber File .gko (*.gko);;" + "Gerber File .gm1 (*.gm1);;Gerber File .gm2 (*.gm2);;Gerber File .gm3 (*.gm3);;" + "Gerber File .grb (*.grb);;Gerber File .gtl (*.gtl);;Gerber File .gto (*.gto);;" + "Gerber File .gtp (*.gtp);;Gerber File .gts (*.gts);;Gerber File .ly15 (*.ly15);;" + "Gerber File .ly2 (*.ly2);;Gerber File .mil (*.mil);;" + "Gerber File .outline (*.outline);;Gerber File .pho (*.pho);;" + "Gerber File .plc (*.plc);;Gerber File .pls (*.pls);;Gerber File .smb (*.smb);;" + "Gerber File .smt (*.smt);;Gerber File .sol (*.sol);;Gerber File .spb (*.spb);;" + "Gerber File .spt (*.spt);;Gerber File .ssb (*.ssb);;Gerber File .sst (*.sst);;" + "Gerber File .stc (*.stc);;Gerber File .sts (*.sts);;Gerber File .top (*.top);;" + "Gerber File .tsm (*.tsm);;Gerber File .art (*.art)" "All Files (*.*)", # Gerber Options @@ -627,9 +628,11 @@ class App(QtCore.QObject): "excellon_optimization_type": 'B', "excellon_search_time": 3, - "excellon_save_filters": "Excellon File (*.txt);;Excellon File (*.drd);;Excellon File (*.drl);;" - "Excellon File (*.exc);;Excellon File (*.ncd);;Excellon File (*.tap);;" - "Excellon File (*.xln);;All Files (*.*)", + "excellon_save_filters": "Excellon File .txt (*.txt);;Excellon File .drd (*.drd);;" + "Excellon File .drill (*.drill);;" + "Excellon File .drl (*.drl);;Excellon File .exc (*.exc);;" + "Excellon File .ncd (*.ncd);;Excellon File .tap (*.tap);;" + "Excellon File .xln (*.xln);;All Files (*.*)", "excellon_plot_fill": '#C40000BF', "excellon_plot_line": '#750000BF', @@ -749,15 +752,15 @@ class App(QtCore.QObject): "cncjob_steps_per_circle": 64, "cncjob_footer": False, "cncjob_line_ending": False, - "cncjob_save_filters": "G-Code Files (*.nc);;G-Code Files (*.din);;G-Code Files (*.dnc);;" - "G-Code Files (*.ecs);;G-Code Files (*.eia);;G-Code Files (*.fan);;" - "G-Code Files (*.fgc);;G-Code Files (*.fnc);;G-Code Files (*.gc);;" - "G-Code Files (*.gcd);;G-Code Files (*.gcode);;G-Code Files (*.h);;" - "G-Code Files (*.hnc);;G-Code Files (*.i);;G-Code Files (*.min);;" - "G-Code Files (*.mpf);;G-Code Files (*.mpr);;G-Code Files (*.cnc);;" - "G-Code Files (*.ncc);;G-Code Files (*.ncg);;G-Code Files (*.ncp);;" - "G-Code Files (*.ngc);;G-Code Files (*.out);;G-Code Files (*.ply);;" - "G-Code Files (*.sbp);;G-Code Files (*.tap);;G-Code Files (*.xpi);;" + "cncjob_save_filters": "G-Code Files .nc (*.nc);;G-Code Files .din (*.din);;G-Code Files .dnc (*.dnc);;" + "G-Code Files .ecs (*.ecs);;G-Code Files .eia (*.eia);;G-Code Files .fan (*.fan);;" + "G-Code Files .fgc (*.fgc);;G-Code Files .fnc (*.fnc);;G-Code Files . gc (*.gc);;" + "G-Code Files .gcd (*.gcd);;G-Code Files .gcode (*.gcode);;G-Code Files .h (*.h);;" + "G-Code Files .hnc (*.hnc);;G-Code Files .i (*.i);;G-Code Files .min (*.min);;" + "G-Code Files .mpf (*.mpf);;G-Code Files .mpr (*.mpr);;G-Code Files .cnc (*.cnc);;" + "G-Code Files .ncc (*.ncc);;G-Code Files .ncg (*.ncg);;G-Code Files .ncp (*.ncp);;" + "G-Code Files .ngc (*.ngc);;G-Code Files .out (*.out);;G-Code Files .ply (*.ply);;" + "G-Code Files .sbp (*.sbp);;G-Code Files .tap (*.tap);;G-Code Files .xpi (*.xpi);;" "All Files (*.*)", "cncjob_plot_line": '#4650BDFF', "cncjob_plot_fill": '#5E6CFFFF', @@ -1022,12 +1025,12 @@ class App(QtCore.QObject): # Utilities # file associations - "fa_excellon": 'drd, drl, exc, ncd, tap, xln', + "fa_excellon": 'drd, drill, drl, exc, ncd, tap, xln', "fa_gcode": 'cnc, din, dnc, ecs, eia, fan, fgc, fnc, gc, gcd, gcode, h, hnc, i, min, mpf, mpr, nc, ncc, ' 'ncg, ncp, ngc, out, ply, rol, sbp, tap, xpi', "fa_gerber": 'art, bot, bsm, cmp, crc, crs, dim, gb0, gb1, gb2, gb3, gb4, gb5, gb6, gb7, gb8, gb9, gbd, ' 'gbl, gbo, gbp, gbr, gbs, gdo, ger, gko, gm1, gm2, gm3, grb, gtl, gto, gtp, gts, ly15, ly2, ' - 'mil, pho, plc, pls, smb, smt, sol, spb, spt, ssb, sst, stc, sts, top, tsm', + 'mil, outline, pho, plc, pls, smb, smt, sol, spb, spt, ssb, sst, stc, sts, top, tsm', # Keyword list "util_autocomplete_keywords": 'Desktop, Documents, FlatConfig, FlatPrj, False, ' 'Marius, My Documents, Paste_1, ' @@ -2726,10 +2729,11 @@ class App(QtCore.QObject): self.grb_list = ['art', 'bot', 'bsm', 'cmp', 'crc', 'crs', 'dim', 'g4', 'gb0', 'gb1', 'gb2', 'gb3', 'gb5', 'gb6', 'gb7', 'gb8', 'gb9', 'gbd', 'gbl', 'gbo', 'gbp', 'gbr', 'gbs', 'gdo', 'ger', 'gko', - 'gml', 'gm1', 'gm2', 'gm3', 'grb', 'gtl', 'gto', 'gtp', 'gts', 'ly15', 'ly2', 'mil', 'pho', - 'plc', 'pls', 'smb', 'smt', 'sol', 'spb', 'spt', 'ssb', 'sst', 'stc', 'sts', 'top', 'tsm'] + 'gml', 'gm1', 'gm2', 'gm3', 'grb', 'gtl', 'gto', 'gtp', 'gts', 'ly15', 'ly2', 'mil', 'outline', + 'pho', 'plc', 'pls', 'smb', 'smt', 'sol', 'spb', 'spt', 'ssb', 'sst', 'stc', 'sts', 'top', + 'tsm'] - self.exc_list = ['drd', 'drl', 'exc', 'ncd', 'tap', 'txt', 'xln'] + self.exc_list = ['drd', 'drl', 'drill', 'exc', 'ncd', 'tap', 'txt', 'xln'] self.gcode_list = ['cnc', 'din', 'dnc', 'ecs', 'eia', 'fan', 'fgc', 'fnc', 'gc', 'gcd', 'gcode', 'h', 'hnc', 'i', 'min', 'mpf', 'mpr', 'nc', 'ncc', 'ncg', 'ngc', 'ncp', 'out', 'ply', 'rol', @@ -10082,8 +10086,7 @@ class App(QtCore.QObject): # Check for more compatible types and add as required if not isinstance(obj, FlatCAMExcellon): - self.inform.emit('[ERROR_NOTCL] %s' % - _("Failed. Only Excellon objects can be saved as Excellon files...")) + self.inform.emit('[ERROR_NOTCL] %s' % _("Failed. Only Excellon objects can be saved as Excellon files...")) return name = self.collection.get_active().options["name"] @@ -10100,8 +10103,7 @@ class App(QtCore.QObject): filename = str(filename) if filename == "": - self.inform.emit('[WARNING_NOTCL] %s' % - _("Export Excellon cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Export Excellon cancelled.")) return else: used_extension = filename.rpartition('.')[2] @@ -10147,8 +10149,7 @@ class App(QtCore.QObject): filename = str(filename) if filename == "": - self.inform.emit('[WARNING_NOTCL] %s' % - _("Export Gerber cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Export Gerber cancelled.")) return else: used_extension = filename.rpartition('.')[2] @@ -10170,8 +10171,7 @@ class App(QtCore.QObject): obj = self.collection.get_active() if obj is None: - self.inform.emit('[WARNING_NOTCL] %s' % - _("No object selected.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("No object selected.")) msg = _("Please Select a Geometry object to export") msgbox = QtWidgets.QMessageBox() msgbox.setInformativeText(msg) @@ -10182,8 +10182,7 @@ class App(QtCore.QObject): # Check for more compatible types and add as required if not isinstance(obj, FlatCAMGeometry): - msg = '[ERROR_NOTCL] %s' % \ - _("Only Geometry objects can be used.") + msg = '[ERROR_NOTCL] %s' % _("Only Geometry objects can be used.") msgbox = QtWidgets.QMessageBox() msgbox.setInformativeText(msg) bt_ok = msgbox.addButton(_('Ok'), QtWidgets.QMessageBox.AcceptRole) @@ -10194,21 +10193,19 @@ class App(QtCore.QObject): name = self.collection.get_active().options["name"] - _filter_ = "DXF File (*.DXF);;All Files (*.*)" + _filter_ = "DXF File .dxf (*.DXF);;All Files (*.*)" try: filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Export DXF"), directory=self.get_last_save_folder() + '/' + name, filter=_filter_) except TypeError: - filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Export DXF"), - filter=_filter_) + filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Export DXF"), filter=_filter_) filename = str(filename) if filename == "": - self.inform.emit('[WARNING_NOTCL] %s' % - _("Export DXF cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Export DXF cancelled.")) return else: self.export_dxf(name, filename) @@ -10226,7 +10223,7 @@ class App(QtCore.QObject): self.report_usage("on_file_importsvg") App.log.debug("on_file_importsvg()") - _filter_ = "SVG File (*.svg);;All Files (*.*)" + _filter_ = "SVG File .svg (*.svg);;All Files (*.*)" try: filenames, _f = QtWidgets.QFileDialog.getOpenFileNames(caption=_("Import SVG"), directory=self.get_last_folder(), filter=_filter_) @@ -10240,8 +10237,7 @@ class App(QtCore.QObject): filenames = [str(filename) for filename in filenames] if len(filenames) == 0: - self.inform.emit('[WARNING_NOTCL] %s' % - _("Open SVG cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Open SVG cancelled.")) else: for filename in filenames: if filename != '': @@ -10258,7 +10254,7 @@ class App(QtCore.QObject): self.report_usage("on_file_importdxf") App.log.debug("on_file_importdxf()") - _filter_ = "DXF File (*.DXF);;All Files (*.*)" + _filter_ = "DXF File .dxf (*.DXF);;All Files (*.*)" try: filenames, _f = QtWidgets.QFileDialog.getOpenFileNames(caption=_("Import DXF"), directory=self.get_last_folder(), @@ -10273,8 +10269,7 @@ class App(QtCore.QObject): filenames = [str(filename) for filename in filenames] if len(filenames) == 0: - self.inform.emit('[WARNING_NOTCL] %s' % - _("Open DXF cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Open DXF cancelled.")) else: for filename in filenames: if filename != '': @@ -10332,11 +10327,11 @@ class App(QtCore.QObject): flt = "All Files (*.*)" if obj.kind == 'gerber': - flt = "Gerber Files (*.GBR);;PDF Files (*.PDF);;All Files (*.*)" + flt = "Gerber Files .gbr (*.GBR);;PDF Files .pdf (*.PDF);;All Files (*.*)" elif obj.kind == 'excellon': - flt = "Excellon Files (*.DRL);;PDF Files (*.PDF);;All Files (*.*)" + flt = "Excellon Files .drl (*.DRL);;PDF Files .pdf (*.PDF);;All Files (*.*)" elif obj.kind == 'cncjob': - flt = "GCode Files (*.NC);;PDF Files (*.PDF);;All Files (*.*)" + flt = "GCode Files .nc (*.NC);;PDF Files .pdf (*.PDF);;All Files (*.*)" self.source_editor_tab = TextEditor(app=self, plain_text=True) @@ -10497,7 +10492,8 @@ class App(QtCore.QObject): self.report_usage("on_fileopenscript") App.log.debug("on_fileopenscript()") - _filter_ = "TCL script (*.FlatScript);;TCL script (*.TCL);;TCL script (*.TXT);;All Files (*.*)" + _filter_ = "TCL script .FlatScript (*.FlatScript);;TCL script .tcl (*.TCL);;TCL script .txt (*.TXT);;" \ + "All Files (*.*)" if name: filenames = [name] @@ -10539,7 +10535,8 @@ class App(QtCore.QObject): alignment=Qt.AlignBottom | Qt.AlignLeft, color=QtGui.QColor("gray")) else: - _filter_ = "TCL script (*.FlatScript);;TCL script (*.TCL);;TCL script (*.TXT);;All Files (*.*)" + _filter_ = "TCL script .FlatScript (*.FlatScript);;TCL script .tcl (*.TCL);;TCL script .txt (*.TXT);;" \ + "All Files (*.*)" try: filename, _f = QtWidgets.QFileDialog.getOpenFileName(caption=_("Run TCL script"), directory=self.get_last_folder(), filter=_filter_) @@ -10616,7 +10613,7 @@ class App(QtCore.QObject): self.date = ''.join(c for c in self.date if c not in ':-') self.date = self.date.replace(' ', '_') - filter_ = "FlatCAM Project (*.FlatPrj);; All Files (*.*)" + filter_ = "FlatCAM Project .FlatPrj (*.FlatPrj);; All Files (*.*)" try: filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Save Project As ..."), @@ -10670,7 +10667,7 @@ class App(QtCore.QObject): self.inform.emit('[ERROR_NOTCL] %s' % _("No object selected.")) return - filter_ = "PDF File (*.PDF);; All Files (*.*)" + filter_ = "PDF File .pdf (*.PDF);; All Files (*.*)" try: filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Save Object as PDF ..."), @@ -11542,10 +11539,11 @@ class App(QtCore.QObject): Opens a G-gcode file, parses it and creates a new object for it in the program. Thread-safe. - :param outname: Name of the resulting object. None causes the name to be that of the file. - :param filename: G-code file filename - :type filename: str - :return: None + :param filename: G-code file filename + :param outname: Name of the resulting object. None causes the name to be that of the file. + :param force_parsing: + :param plot: + :return: None """ App.log.debug("open_gcode()") @@ -11605,11 +11603,9 @@ class App(QtCore.QObject): Opens a HPGL2 file, parses it and creates a new object for it in the program. Thread-safe. - :param outname: Name of the resulting object. None causes the - name to be that of the file. - :param filename: HPGL2 file filename - :type filename: str - :return: None + :param outname: Name of the resulting object. None causes the name to be that of the file. + :param filename: HPGL2 file filename + :return: None """ filename = filename @@ -11672,10 +11668,9 @@ class App(QtCore.QObject): Opens a Script file, parses it and creates a new object for it in the program. Thread-safe. - :param outname: Name of the resulting object. None causes the name to be that of the file. - :param filename: Script file filename - :type filename: str - :return: None + :param outname: Name of the resulting object. None causes the name to be that of the file. + :param filename: Script file filename + :return: None """ App.log.debug("open_script()") @@ -11709,9 +11704,9 @@ class App(QtCore.QObject): """ Loads a config file from the specified file. - :param filename: Name of the file from which to load. - :type filename: str - :return: None + :param filename: Name of the file from which to load. + :param run_from_arg: if True the FlatConfig file will be open as an command line argument + :return: None """ App.log.debug("Opening config file: " + filename) @@ -11760,12 +11755,11 @@ class App(QtCore.QObject): 5) Calls new_object() with the object's from_dict() as init method. 6) Calls plot_all() if plot=True - :param filename: Name of the file from which to load. - :type filename: str - :param run_from_arg: True if run for arguments - :param plot: If True plot all objects in the project - :param cli: run from command line - :return: None + :param filename: Name of the file from which to load. + :param run_from_arg: True if run for arguments + :param plot: If True plot all objects in the project + :param cli: Run from command line + :return: None """ App.log.debug("Opening project: " + filename) @@ -11870,7 +11864,8 @@ class App(QtCore.QObject): an alternative to project options but allows the use of values invisible to the user. - :return: None + :param silent: No messages + :return: None """ if silent is False: @@ -11914,7 +11909,7 @@ class App(QtCore.QObject): :param fit_view: if True will plot the objects and will adjust the zoom to fit all plotted objects into view :param use_thread: if True will use threading for plotting the objects - :return: + :return: None """ self.log.debug("Plot_all()") self.inform.emit('[success] %s...' % _("Redrawing all objects")) @@ -11933,12 +11928,31 @@ class App(QtCore.QObject): worker_task(obj) def register_folder(self, filename): + """ + Register the last folder used by the app to open something + + :param filename: the last folder is extracted from the filename + :return: None + """ self.defaults["global_last_folder"] = os.path.split(str(filename))[0] def register_save_folder(self, filename): + """ + Register the last folder used by the app to save something + + :param filename: the last folder is extracted from the filename + :return: None + """ self.defaults["global_last_save_folder"] = os.path.split(str(filename))[0] def set_progress_bar(self, percentage, text=""): + """ + Set a progress bar to a value (percentage) + + :param percentage: Value set to the progressbar + :param text: Not used + :return: None + """ self.ui.progress_bar.setValue(int(percentage)) def setup_shell(self): @@ -12143,7 +12157,11 @@ class App(QtCore.QObject): ''') def setup_recent_items(self): + """ + Setup a dictionary with the recent files accessed, organized by type + :return: + """ # TODO: Move this to constructor icons = { "gerber": self.resource_location + "/flatcam_icon16.png", @@ -12309,6 +12327,11 @@ class App(QtCore.QObject): self.log.debug("Recent items list has been populated.") def setup_component_editor(self): + """ + Default text for the Selected tab when is not taken by the Object UI. + + :return: + """ # label = QtWidgets.QLabel("Choose an item from Project") # label.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) @@ -12423,7 +12446,8 @@ class App(QtCore.QObject): def setup_obj_classes(self): """ - Sets up application specifics on the FlatCAMObj class. + Sets up application specifics on the FlatCAMObj class. This way the object.app attribute will point to the App + class. :return: None """ @@ -12504,10 +12528,10 @@ class App(QtCore.QObject): def on_plotcanvas_setup(self, container=None): """ - This is doing the setup for the plot area (canvas) + This is doing the setup for the plot area (canvas). - :param container: widget where to install the canvas - :return: None + :param container: QT Widget where to install the canvas + :return: None """ if container: plot_container = container @@ -12571,8 +12595,8 @@ class App(QtCore.QObject): toolbar button or the '1' key when the canvas is focused. Calls ``self.adjust_axes()`` with axes limits from the geometry bounds of all objects. - :param event: Ignored. - :return: None + :param event: Ignored. + :return: None """ if self.is_legacy is False: self.plotcanvas.fit_view() @@ -12723,8 +12747,9 @@ class App(QtCore.QObject): def toggle_plots(self, objects): """ Toggle plots visibility - :param objects: list of Objects for which to be toggled the visibility - :return: + + :param objects: list of Objects for which to be toggled the visibility + :return: None """ # if no objects selected then do nothing @@ -12741,6 +12766,11 @@ class App(QtCore.QObject): self.plots_updated.emit() def clear_plots(self): + """ + Clear the plots + + :return: None + """ objects = self.collection.get_list() diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 0256853a..5176ea16 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -447,10 +447,10 @@ class FlatCAMObj(QtCore.QObject): Will modify the filter string that is used when saving a file (a list of file extensions) to have the last used file extension as the first one in the special string - :param last_ext: the file extension that was last used to save a file - :param filter_string: a key in self.app.defaults that holds a string with the filter from QFileDialog + :param last_ext: The file extension that was last used to save a file + :param filter_string: A key in self.app.defaults that holds a string with the filter from QFileDialog used when saving a file - :return: None + :return: None """ filters = copy(self.app.defaults[filter_string]) @@ -7007,6 +7007,12 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): self.app.worker_task.emit({'fcn': worker_task, 'params': []}) def on_exportgcode_button_click(self, *args): + """ + Handler activated by a button clicked when exporting GCode. + + :param args: + :return: + """ self.app.report_usage("cncjob_on_exportgcode_button") self.read_form() @@ -7014,9 +7020,9 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): save_gcode = False if 'Roland' in self.pp_excellon_name or 'Roland' in self.pp_geometry_name: - _filter_ = "RML1 Files (*.rol);;All Files (*.*)" + _filter_ = "RML1 Files .rol (*.rol);;All Files (*.*)" elif 'hpgl' in self.pp_geometry_name: - _filter_ = "HPGL Files (*.plt);;All Files (*.*)" + _filter_ = "HPGL Files .plt (*.plt);;All Files (*.*)" else: save_gcode = True _filter_ = self.app.defaults['cncjob_save_filters'] @@ -7055,10 +7061,16 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): if self.app.defaults["global_open_style"] is False: self.app.file_opened.emit("gcode", filename) self.app.file_saved.emit("gcode", filename) - self.app.inform.emit('[success] %s: %s' % - (_("Machine Code file saved to"), filename)) + self.app.inform.emit('[success] %s: %s' % (_("Machine Code file saved to"), filename)) def on_edit_code_click(self, *args): + """ + Handler activated by a button clicked when editing GCode. + + :param args: + :return: + """ + self.app.proc_container.view.set_busy(_("Loading...")) preamble = str(self.ui.prepend_text.get_value()) @@ -7116,9 +7128,9 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): """ Will create a header to be added to all GCode files generated by FlatCAM - :param comment_start_symbol: a symbol to be used as the first symbol in a comment - :param comment_stop_symbol: a symbol to be used as the last symbol in a comment - :return: a string with a GCode header + :param comment_start_symbol: A symbol to be used as the first symbol in a comment + :param comment_stop_symbol: A symbol to be used as the last symbol in a comment + :return: A string with a GCode header """ log.debug("FlatCAMCNCJob.gcode_header()") @@ -7219,6 +7231,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): def gcode_footer(self, end_command=None): """ + Will add the M02 to the end of GCode, if requested. :param end_command: 'M02' or 'M30' - String :return: @@ -7232,11 +7245,11 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): """ This will save the GCode from the Gcode object to a file on the OS filesystem - :param filename: filename for the GCode file - :param preamble: a custom Gcode block to be added at the beginning of the Gcode file - :param postamble: a custom Gcode block to be added at the end of the Gcode file - :param to_file: if False then no actual file is saved but the app will know that a file was created - :return: None + :param filename: filename for the GCode file + :param preamble: a custom Gcode block to be added at the beginning of the Gcode file + :param postamble: a custom Gcode block to be added at the end of the Gcode file + :param to_file: if False then no actual file is saved but the app will know that a file was created + :return: None """ # gcode = '' # roland = False @@ -7482,6 +7495,13 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): return lines def on_toolchange_custom_clicked(self, signal): + """ + Handler for clicking toolchange custom. + + :param signal: + :return: + """ + try: if 'toolchange_custom' not in str(self.options['ppname_e']).lower(): if self.ui.toolchange_cb.get_value(): @@ -7503,7 +7523,13 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): self.app.inform.emit('[ERROR] %s' % _("There is no preprocessor file.")) def get_gcode(self, preamble='', postamble=''): - # we need this to be able get_gcode separately for shell command export_gcode + """ + We need this to be able to get_gcode separately for shell command export_gcode + + :param preamble: Extra GCode added to the beginning of the GCode + :param postamble: Extra GCode added at the end of the GCode + :return: The modified GCode + """ return preamble + '\n' + self.gcode + "\n" + postamble def get_svg(self): @@ -7511,6 +7537,12 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): pass def on_plot_cb_click(self, *args): + """ + Handler for clicking on the Plot checkbox. + + :param args: + :return: + """ if self.muted_ui: return kind = self.ui.cncplot_method_combo.get_value() @@ -7528,6 +7560,12 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): self.ui_connect() def on_plot_cb_click_table(self): + """ + Handler for clicking the plot checkboxes added into a Table on each row. Purpose: toggle visibility for the + tool/aperture found on that row. + :return: + """ + # self.ui.cnc_tools_table.cellWidget(row, 2).widget().setCheckState(QtCore.Qt.Unchecked) self.ui_disconnect() # cw = self.sender() @@ -7566,9 +7604,14 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): self.ui_connect() def plot(self, visible=None, kind='all'): - + """ # Does all the required setup and returns False # if the 'ptint' option is set to False. + + :param visible: Boolean to decide if the object will be plotted as visible or disabled on canvas + :param kind: String. Can be "all" or "travel" or "cut". For CNCJob plotting + :return: None + """ if not FlatCAMObj.plot(self): return @@ -7612,6 +7655,11 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): self.annotation.clear(update=True) def on_annotation_change(self): + """ + Handler for toggling the annotation display by clicking a checkbox. + :return: + """ + if self.app.is_legacy is False: if self.ui.annotation_cb.get_value(): self.text_col.enabled = True @@ -7625,6 +7673,13 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): self.plot(kind=kind) def convert_units(self, units): + """ + Units conversion used by the CNCJob objects. + + :param units: Can be "MM" or "IN" + :return: + """ + log.debug("FlatCAMObj.FlatCAMECNCjob.convert_units()") factor = CNCjob.convert_units(self, units) @@ -7723,6 +7778,11 @@ class FlatCAMScript(FlatCAMObj): self.script_editor_tab = TextEditor(app=self.app, plain_text=True) def set_ui(self, ui): + """ + Sets the Object UI in Selected Tab for the FlatCAM Script type of object. + :param ui: + :return: + """ FlatCAMObj.set_ui(self, ui) FlatCAMApp.App.log.debug("FlatCAMScript.set_ui()") diff --git a/README.md b/README.md index 54b7e758..84ca08fc 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,9 @@ CAD program, and create G-Code for Isolation routing. 14.04.2020 - lightened the hue of the color for 'success' messages printed in the Tcl Shell browser +- modified the extensions all over such the names include also the extension name. For Linux who does not display the extensions in the native FileDialog. +- added descriptions for some of the methods in the app. +- added lightened icons for the dark theme from Leandro Heck 13.04.2020 diff --git a/share/dark_resources/about32.png b/share/dark_resources/about32.png deleted file mode 100644 index 91c2caf1c3c32a52dc722f3900addb264a9c7260..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1996 zcmV;-2Q&DIP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 zVoOIv0RI600RN!9r;`8x2IEOYK~z}7otIl|9aj~GzqR+woSTnN9GW<`vY#wIL%p9L%2tCr4XRJN@|JT3%wf5e^ZT`j|KD-yq11Q-k z=&iY2W(x>~Vr9k{Gh=Yid9B(zQ*S(d1ZV-??W`;R19TnmooqJs-01Kfx#3L%WHTvh zO(<1eT-QS@FkXw5VwL=@5=+a4LZe=KxqSWffw@z^Tm;-tL}2{OzulY7rVsACXDl~5 zvVqwfb>^3wEZ%B$%rn8?zLb!*A!);{l_CpE`9iHY_w3ZMXC{HhT8c<-@ZTNUv2Ezd z`*&^UU-J#7=IS(CrW;tKa{&PnpGZP^EZtnDSeSqH%Io`{0?NJAkY3=s?;C$|WOx&2 zu9R3QyOv4uN+%Kl!_@Jz9OQcw21$%we47`je7aR zKb-{XfUy9w+0=8JM>cTcpDSIF6M_dyh)}9|ym4wJl-mD)oMbq?!$5YrkL1AE~5?;iwe7VyCE-~coEW@kNjMD8y*u{p_S#xtucmvYTRl%N6=O88AQr|B8Q zfRZGM+~{s#5-2JZI|tVFg&ocS60hq(_FBW^hlgj`_u^C+0c|NPOQGAt)>yXxY}p#i z)@Vy1mLlaOu+r&v*vMG3_8UpsYf%GNZ+8 zX-B_YXi{yMFbXA|k*$>i6{w@M|4qCr`sy2u2bq+iRxK^IzqJfzM#OAE;Kt1c^`?nB znIg=o3ObuoYZGWIAxfcCOo2dt;~5eO7t^XQ;BQKvWsH07=1Tcnuj2d9fnFAwOBGE`WO z#e0~MgDfL6U$c)3=u(4UI(CJ}=u`ZW}2n=`J06+~|bN^Ba? z6o*72k7!V!4o+oPQR+4e31$GO1vuwzvP^iAyj{UJNOWv?q)T9yRH($QvPM<&yu z*>se1TVXjC**?w0kmlNSiIc}qpE&pH2loT>z#LE_IHt!Br3Pr_FCTep{rE$7Y1{cU zl7My#)={40tyw9BXcZdKvJ`_kVWi*V?E5!4{qETl=YR9ieqaH(9tU4dpiQEgzx3Lh znZbKLPGtH&k7!4x9B`nRowjz5L!UuCf&hy;v#blKy93Tq}Y~AzYM-uBscU!4}aqXlxCDZ+bq7=1idC|D_ zg=RHBRa?4xHr8ZT0=F0Wf3Ide)JOm+{4;$zcz0qcbOVq&QIn|#@1N{)x`rYaU05UK!IV~_bEipAz zF*rIiH99pkD=;)VFfe?iwD|x403~!qSaf7zbY(hiZ)9m^c>ppnF*z+TIV~|YR53U@ eGc`IjG%GMPIxsK|`3yw>0000s1M_&9clSI#|s4Pek_^5?0bS`iLkl| zQ$v78Uo4kozl*@p+^c53khf>R8pkBwKR7*`(w>VpBD@F&ukTvVZZZ<^0oaN*x^J zpBe+*u3F+6QIe8al4_M)lnSI6j0}tnbPY^&4NXD}46F=ItxSz{4UDY}47$QszeCZG bo1c=IR*74~Z!Td_TrhaL`njxgN@xNA1LTTq delta 217 zcmV;~04D#a1L^^g8Gi-<0036bj#mHx0I^9#K~y+TwUprz1Q85{vmIzf1(cu@Eu;mV zD1i=?q60U~?T)oMa&sGItwAZ(ierorLb$cGS2hLB6jF_Sn}X_L?|oBYjCnjT zsc5vt9g7ooDcS~ldu}ts4R*6v!2g53u{Tclaz!Y6tQ8pxe_GmAld1gj8{tARQ79%kR8 zC+6RpfAIXF`G?-|tuR>_^6G|xg1lc6V^`41B?8ZQxKiD(znyB76rwDa%A>jFjNw(i zpslrScHe)?+}>iexMG9vdG@j=<<1NO0y49WQpDyzboR((ky6b2;9LLUs`|vBS%SJ1 z!kIveRZCnWN>UO_QmvAUQh^kMk%5tcu7QcJp-G5=ft8_|m64&Yfw7f=L6k2us)pSB al+3hB+#0k6c3%bBz~JfX=d#Wzp$Pz#6>fk4 delta 140 zcmV;70CWHP0-XVn8Gi-<001BJ|6u?C0Axu-K~y+TV{B+>_|Jd_8X6iH(ZxV~Y-$-n zg2)=s`N#%gQ;XFAY_`M1&@H2m3n&T$B&VT-1p#ls)xtv?Tj0S$9X(c%)#5Y&J<4#! u6zvQ^PB>(Ff#^USP0Ihld4ZCo3;?{tsRxjZ9L4|u002ovP6b4+LSTXbemAWE diff --git a/share/dark_resources/addarray20.png b/share/dark_resources/addarray20.png index f5892d5c084e5cba2cc427eb3105c46165133107..ce121e3487106922c644b93152f1f1945dfb3a86 100644 GIT binary patch literal 540 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc0wmQNuC@UwmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^+ z;1OBOz`!jG!i)^F=12eq*-JcqUD=fWgDYg`bDIOk~oIVpcnS}H>mvL-bugi3QrQO`` ze>}gt$uIT#xbpa|lU>hmed&0AX5kFZt_cGC2R#dKAFknkbSRNwS;)-Waf{v6a?5gh z_)3CH8}6)O6x;eYXG*Tds+wqoFF1m8Y#!b{ zwP)|+uyp$b=eg75C8Z@Kr2q213#tBc<%-1h|BW9$R3Glzqa85mUWFw{fQkei>9nO2Eg1J~2eNk9z@p00i_>zopr0Jr7G(EtDd delta 159 zcmV;Q0AT-|1h4^+8Gi-<0051N9Sr~g0C!15K~y+T%~U}Sz#s@4Kkv`CWC?~SbkTs* zqlQx2iU7E;-~bTsiPcCMpk>3FSjJvWW4HzIOGC;q5dQ#El$jdgjXCqyMw%(=oPKkx zL?~bsAJ2?`09W+Q*Rbp_rw5xk*EjPbrgwXnL$r8}`-7=<3m7)bln1>Z!v`U(mo5MR N002ovPDHLkV1f%&LXH3c diff --git a/share/dark_resources/addarray32.png b/share/dark_resources/addarray32.png index 7e855a71b13cc200253a229314874f50dba1290f..b4682112842c0c74cb60ef22d4bb51a4f88936ed 100644 GIT binary patch literal 423 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1Gg{;GcwGYBLNg-FY)wsWq-oLD=Hv9RlHgSC^XB{#WBR=_}dUez6J#zotBCB zB_97*SAJ+-ww_r?^p=975PM$Mp{;jhmvqUT`_NFjfq}n2_*AI%Q=8R4>QZ*7Yl1~6zEFT z64!{5l*E!$tK_0oAjM#0U}T_cV4`bi5@KLrWoTw)WUOmoY-M0@_L7hTiiX_$l+3hB W+#2@uulfVjz~JfX=d#Wzp$P!~hlue2 delta 234 zcmVfa)F!P@)|m)Bn$0+L)|>9l+j# zb^wyN3P5%JKClv2zkAy0uI`t;UJ4)s+oHgK0?_G6*1N{jLt|(MSPq)^WkxZndk9+; zAoo++l^(*(q7nd2^(>+c+S!5x>^}|3PAR_IA-y-_@}02S0&+$ffO`2uiPJx-v;uYj kdkfkDNa890)wTP;3;k(Q95vAPaR2}S07*qoM6N<$f+=@t;{X5v diff --git a/share/dark_resources/aero.png b/share/dark_resources/aero.png index 4b17865e8b5475482ba5f8ba2275ed42ad2d8285..ad251cc0ece79a2bf520847ce9f70101e5fbc64f 100644 GIT binary patch literal 1140 zcmeAS@N?(olHy`uVBq!ia0vp^hCpn=!VDyr?d5&Wz`$6O>FgYknVihPpfRy_qOHea z2brVsm%A2;3UYT@q^$50b8(ef+U2?-;1<_fs~IuBSbe1?iHN%&-1^|b@uaHG zhdT=VVJIvt4Jw%^^nbcY)RBsUJN@O~<;vePER0KAB{_p35Skd>g&2^8X&F0LPbG~;vuhGyv z^8CnSw%7?jCcfTuI)4r~AGeKh%96>Sk0>T>yl|{Ydh?=%LjJ<-qM?gx6d!LoRN1{b zYTc%1wm-R>Ept_mmd;Y{NaQS3QE+k-Rh^Qk=(O6ct5fBzyX~LDefExeGh7&H|6fVg?31We{epSZZGe z6l5>)^mS!_!on*mAU$WHIX_S+$J50z#NzbZ3yORV20X0~Pu&t!u;p?;_{f53lj(+J z;|qVA)ouzK-=9_LzhwDy_rfV%LKY%zK{7`JGFEghp{#bpct`N_;Qe_0~kk8br-c5&vRaul{5H`#S;ra#=HuuKNhISGB}7q9i4;B-JXp zC>2OC7#SED=o*;l8k&R{7+4vaSs9t@8W>v{7+B6V1Nju8AvZrIGp!Q029E=M?|~Ym zKsKaSWTsg;WtJ2Nq!tAy<`(3nGFa#+fRNBzJ9VHcMYt*#pesT$b3raKw6roXu`)DQ zFf_3;HMcUh*r6(T1E^RSuGlj-F+J5MH7~s+gTd5H=F*ZCKxrXV>F~@Hpsb0d{iJ{L zDDDZ)Pb(=;EJ|f?_w)@=Fw!$L03u!6tBgQZ(jYT{+14sKzo4=xGd-h(A)quVCo@^W zB|kSYGjH2O!)Tx~C7805)Z*l#%z~24{5*(pNu`-NCAyh;3dKS0PCn_5!a&ucFx9z< wd8KKI$t9&lsYPJrKJzA=0xIBxE67ht&0zp(jZW}%2Ffsay85}Sb4q9e0HaZzN&o-= delta 454 zcmV;%0XhEk2-E|R7=H)`0000~lMvJZ00EmxL_t(&L+zNcY63wJhQ}`8gM_OSthBjQ z5^KqW2q|x`2uVP}DqJJB;tPqbq!BA2LJ|TAb7bKN2KIJlc8_DW5#)Bx@Bj90cI`k5 zMyCY~pb$;5s3z0|V*37$>U<#xO~x)C4I$#(&9bf-y`|DK$Zgk8!e^ zU<{K~N==aBW1Ore7{er$QWGxm8DqYUF`{9K7Dq^g`27^SmsnwI2_dp9gFMd>NaTJZ zMXSrqLg05&AVDFdK!QU^fJA}d28jm22@)0J8=J5q}T}vfI7Fa=GvV2@Y{Oy+gNqQT9V@et(BgR}Tt-0MqF+TwV8JbbG_r z!Gl3q08H9$MJP+CYA^`IWO82`uuBCY(sT%eL65~o5QuYIacg6<*}{6g@_L}H4RMJ7 z4o(O$9^XNdT#{`>gWx=ShWg6?8{e^{M)Ka?8mIqvf7AOHXW07*qoM6N<$f_d=6E&u=k diff --git a/share/dark_resources/aero_arc.png b/share/dark_resources/aero_arc.png index 729f65236bd161914d3c7564f6a01d0e7d26f267..612858ac9f775725da8e22dddf373dae581266eb 100644 GIT binary patch literal 1151 zcmeAS@N?(olHy`uVBq!ia0vp^hCpn=!VDyr?d5&Wz`$6W>FgYknVihPpfRy_qP552 z0Fk!;%eq`&F~3oGG-07tq(HodmuPpw!Y!gvr3O1+a?dhR(bVf}%077Tc+%B_MHQnfdy3l#UyBj*pJJQW`=YF;;>=0FL z{V}KF%mQv9`=Z#gpS{Hg6C2apdP<7sS-9wk-HOOd4l@aPr1@yWqO2+UDKTLd`GsMp zL$B>ouTL~szIMqDzibIZ9mPHtmlG=%wHWERWL)wAJtE&PF~I8*2fyM zz^UlZgZdBE+tTWa4*7DqHJ%f{{ZE2%S6QRm*=_s#b9Waq{g~gVz4qz)D~&h(FJwAw`ue{-)daRL(`=`r7pDG{x?b)Zv&2xw8ZuYx7vz}YjGF&oQ{Z#tF z0|5!$fN#5w?`D2m{CoRy%l-1X*+olNZ9bz3j1Prmk04(LhAK4%hK3dfhF?ITh8GMB zr3MTPuM!v-tY$DUh!@P+6=(yLkPGk$asB`QKak1J#=_6fBQ7o~Cnv+r&7rBO{`vD~ zptx{s;c_6wQ4-`A45Yze`}3fMKn7!yx4R4Deg6vfL(m zWTkz_4i39pdh$yj22QlEw-a&Z6glp_PUB{PNUNS`;FMz?pBgSndCI*u$_&x|WS6nc zvh?fCFz!S#VKdST7*d=dCuG$yCuL^X5YKdz^ zNlIc#s#S7PDv)9@GB7gGH89aNGzl>dX5O(MCyw7I8TF`)} z)c^)Ch+Hh12{R#>fDI?XFj=L{1S>wl&SpX|Ojao~!HQ3?vwxWo43kyLOt9h;>})0k z!(^2*6Rh|IJDUl?Fj=L{L`Zzjxew=@YFMhp5fUN3KGoi(R+uayL{St_mL&qIyicX5 zKg1omya-=-q!+&4zbz1K)b!ST@P{bt3GvB^{5aCFdE&!!QnBSpPh)U z;L#um0F$Pz2xkcS2BSa>hZkD|G*l3x*E@x7_ejJ>6o{X;;$&k!U%+hkQ0os(Hq;@0 zJ2)XkzdwLZXP<2&8HD74DJewA@iwH5L4>5VYn#xE1xmkNb|xAF@!#!8^#&z76Eti6 zwTG(O$`-=A^7;OaWT0v)O9=nYDrA?NHALvlW)PuCX}9|X9!A(XpWh~100000NkvXX Hu0mjfT8hf5 diff --git a/share/dark_resources/aero_array.png b/share/dark_resources/aero_array.png index b8efdcb2371be838c3d67398f2822efe53616fe1..011f5c7503d0e63f1a676b80c72a3dffe433c8f4 100644 GIT binary patch literal 1157 zcmeAS@N?(olHy`uVBq!ia0vp^hCpn=!VDyr?d5&Wz`$6W>FgYknVihPpfRy_qP552 z0Fk!;%eq`&F~3oGG-07tq(HodmuPpw!Y!gvr3O1+a?dhR(bVf}%077Tc+%B_MHQnfdy3l#UyBj*pJJQW`=YF;;>=0FL z{V}KF%mQv9`=Z#gpS{Hg6C2apdP<7sS-9wk-HOOd4l@aPr1@yWqO2+UDKTLd`GsMp zL$B>ouTL~szIMqDzibIZ9mPHtmlG=%wHWERWL)wAJtE&PF~I8*2fyM zz^UlZgZdBE+tTWa4*7DqHJ%f{{ZE2%S6QRm*=_s#b9Waq{g~gVz4qz)D~&h(FJwAw`ue{-)daRL(`=`r7pDG{x?b)Zv&2xw8ZuYx7vz}YjGF&oQ{Z#tF z0|5!$fN#5w?`D2m{CoRy%l-1X*+olNZ9bz3j1Prmk04(LhAK4%hK3dfhF?ITh8GMB zr3MTPuM!v-tY$DUh!@P+6=(yLkPGk$ah*MRGLXs6#=_6fBQ7o~Cnv+r&7rBO{`vFg z(3vv>cmLQ3l;$W2@(TviV6gpp&_W=CG0EHAh4bUhrEh>7&H|6fVg?312@qz~TBWW4 z6l5>)^mS!_!on-cZ=B*cF&ijU*kacemBi1R#9gA~Yy)QZeBE2qqo;(*km;Kba5oKyx29R&~)dTXZ+RHX=4 zzKt=WVTm?JNQC%(6}y*MV`~W^vMhr<&k;!Eej-iX zF|!c(o)kz_2q}>05E39sAh#{M1Scfi^aq4;YPJNFd1}5M;f6 zhw=C|800J<5PxK~dV}e75(E+*V!Qo>di~_Xh)ZR1l)mxrKJS#bP50#Hp>gwXs+%VLqP){h_T5afrVT zP6*NK^`X(YB-=;^!Fgax3Q^{GTjo0oQ6?qdckKE5zfEWGAwrG#=AP>_(Q)FOd*AL>A&N$<5+>ZO1$8a(1@;32e)qO-_kyMX0000< KMNUMnLSTa6tI`kv diff --git a/share/dark_resources/aero_buffer.png b/share/dark_resources/aero_buffer.png index 41f26dd74baed6b0bf1ac630e71c7553cc6add28..95778e3a8a9ae3bb836a823827b9ef8c6f105e20 100644 GIT binary patch literal 1159 zcmeAS@N?(olHy`uVBq!ia0vp^wm|I0!VDyPS2o^YU|_7xbaoENOipHC(3n^|(c0s1 zfJoc_WnHeXnBOQony}C+QXt;KOSC&-;TF-TQiGi@xo4TEXzKMfWgk3vJn8Deqmkk4 z;f?||4Lf#NY3}mqe6H3iW+=DgPXGUT|DWG0W?UGTw(6!K--=nOD#?L{lVe49#|b*< z|9W_M%Ml;jc~L%xH}8A5vj3Idq0M`K|63!cnr?JJUFf{w-3=Y)9qDGeb3fY^c8IFB z{+Ls7W&yX5eNk-L&)(vLiH+%PJtal+EL?QNZbjrJhna*t(tNaGQPvdwl$bD!{KBx) zq1X1P*C!e*U%O<7U$%syj$$8+%ZU|>T8wmDGOl|VPF(VNMSJ~;kLo8>C$DC4>thXB z;8gVILH&p7ZE1ByhkUu*8qbN}{wKk>tE|!O?6&>=xw{LQe#~#wUi)LqiJ#!!Mvv!wUw6 zQUeBtR|yOZRx=nF#0%!^3bX-A$OZU>xc>kDAIM~9W8vrL5f>Mglat}*=Frqs|NQwg zP+T~+a5<3TC<*cl2GU@#{dv$rAcHZ<+ueonKa=h~AcwQSBeIx*K~DmN8MRiaD*y%A zOFVsD*`KiRiVCo%t>el83e|bKIEHu}e>-U-Z-W63OYAOQrYC_Ct<(AhHRiI}m^Cu~ zn<&6K$^WI^ru&61lTH%= zpU0Ov{45XOvFO^aJSNK%TvuBc3x1e2Y5lVAl}`(6=kcGbH2r_$@jsRS@fM6d>t%&L z-|n3Xbct$-YeY#(Vo9o1a#1RfVlXl=GSD?J(KR#)F)*+)G_x`=)ip4-GB9|fuE36> zAvZrIGp!Q0hPhQUb^|p?fow>v$V{_x$}A}kNG%FZ%q_@CWw6ju03o5bcIrS?if~mf zKv#rh=7L;eXlZ3&VP$Bd0Ad(h8JVX=x`_i73&RzA<|d}6`lRNimt-)Q8ys&>mIq1; zp-P8mrT}Hl44Lai)}y#5I6tkVJh3R1!QIn0K*31Q&;W>ZZLcx{RY`-)0On+?H6Ahz*%9LQrQc{bPi!uvJGV}8w#wC?z=9K7W<|z~h zxjXr!I|>6;i^5drCgzo_gGr7r*g delta 498 zcmZqYY+#unQP07~z`#)7KIb(91LJW|7srr_xVJOyy_p>aj;ha{z^}AYRQvJ~uPuCa z6B?er6%02(vc>C_oo8`U=kvD#yt^S>tcWEKV zdcT%4EH5HL+Ajq}6|yGeAAR)Cu^G-*I+2inBf792ETObF5yZj5ZoYY2;&W~f=cf7z zzBjXZ{{DXXS8h*!2EVwox~Eg-tRlue_u8+Y{dW0?)93Pi2VEV0vxzgm6^;?vqF+#W z!R~;oQ+-X{#k+5NH;0IGp3TZP%Qu;6W5FoSefGiYuiC!L`|Ep~yW7$}Tz%F0>~rMe z2T2RI-!6Yu#$WcA+g$tR>XYkySxlJwkAE*IsqvaFo_@}H%YzGIGp24?yOP`cy|uc= zmyD9V!8f9&FJx~ne)Zjd&MH|EtM^wgt=b!7cRA_fm5heSt<8@A&1WUOc=(~KYOiy8 zR(JC^!vq1&*iwhg<@%-a+4*bR&)Mx?-LvqDqNbX6Cuy61lJf1>ODl_9%y4o36K##V*fvfV6Q8zyzZREuG0w#e$M e-it$iv2V3z2)kZB`xP*989ZJ6T-G@yGywp-@A1O` diff --git a/share/dark_resources/aero_circle.png b/share/dark_resources/aero_circle.png index 63e0c9bad96fd838c6c0c99d920876626d80a20a..73d4f76d972eae9cc2a290d37b0dc0f8cc468f29 100644 GIT binary patch literal 1158 zcmeAS@N?(olHy`uVBq!ia0vp^hCpn=!VDyr?d5&Wz`$6W>FgYknVihPpfRy_qP552 z0Fk!;%eq`&F~3oGG-07tq(HodmuPpw!Y!gvr3O1+a?dhR(bVf}%077Tc+%B_MHQnfdy3l#UyBj*pJJQW`=YF;;>=0FL z{V}KF%mQv9`=Z#gpS{Hg6C2apdP<7sS-9wk-HOOd4l@aPr1@yWqO2+UDKTLd`GsMp zL$B>ouTL~szIMqDzibIZ9mPHtmlG=%wHWERWL)wAJtE&PF~I8*2fyM zz^UlZgZdBE+tTWa4*7DqHJ%f{{ZE2%S6QRm*=_s#b9Waq{g~gVz4qz)D~&h(FJwAw`ue{-)daRL(`=`r7pDG{x?b)Zv&2xw8ZuYx7vz}YjGF&oQ{Z#tF z0|5!$fN#5w?`D2m{CoRy%l-1X*+olNZ9bz3j1Prmk04(LhAK4%hK3dfhF?ITh8GMB zr3MTPuM!v-tY$DUh!@P+6=(yLkPGk$asB`QKak1J#=_6fBQ7o~Cnv+r&7rBO{`vD~ zptx{s;c_6wQ4-`A45Yze`}3fMKn7!yx4R4De7d=d6G#bNP%oft;kHXa>^_z4oEEuPRuRHNoBCmQ2-&Kw|444Rf=#` zEAp>EalY;rw=ntv9oyK%4s9 z3GzZg+F{E&r)J3hQDi)QTid0TW2K6(hxSkBgJw5aRy#0ta-3ojpLX`?zO--6$?Gh4 z+@5>;d2M=m*?Lyq9Z|dq42>N}T??J&B!oCz>J0P=(kN_Fkxx!9Y$BSysHetjW&F}9 z!5inWxqGzy*l+!N+U5hdR9ieIv0O57RZzcQEOf=kn78qKOk+iB0qY~#L#!SG9C;HG z1m-9>Dt^0f|KZOUkGQQ(P79=8e`P!NI9$l1fP*D+?Y;z~%GJC=tSn7B)8`w^_RVgr zXupwHej#tZ>?=hv``@dAukLkHIFRv$>A84#L3#Dru!DOYGZ;dm@?AAFQ>^`r3ST{FVV2=}xA68` znVpGz_vXAx$VLksMhLZ&a&vt{k~PXZ)(oZesXK0 z#$1hG)hTv#1;PfqLC)srz*x$cYB2)lk({nZuA67aOPM0oe92c@^&9R4tx|KadB T>>D)&7^MuJu6{1-oD!MFgYknVihPpfRy_qP552 z0Fk!;%eq`&F~3oGG-07tq(HodmuPpw!Y!gvr3O1+a?dhR(bVf}%077Tc+%B_MHQnfdy3l#UyBj*pJJQW`=YF;;>=0FL z{V}KF%mQv9`=Z#gpS{Hg6C2apdP<7sS-9wk-HOOd4l@aPr1@yWqO2+UDKTLd`GsMp zL$B>ouTL~szIMqDzibIZ9mPHtmlG=%wHWERWL)wAJtE&PF~I8*2fyM zz^UlZgZdBE+tTWa4*7DqHJ%f{{ZE2%S6QRm*=_s#b9Waq{g~gVz4qz)D~&h(FJwAw`ue{-)daRL(`=`r7pDG{x?b)Zv&2xw8ZuYx7vz}YjGF&oQ{Z#tF z0|5!$fN#5w?`D2m{CoRy%l-1X*+olNZ9bz3j1Prmk04(LhAK4%hK3dfhF?ITh8GMB zr3MTPuM!v-tY$DUh!@P+6=(yLkPGk$asB`QKak1J#=_6fBQ7o~Cnv+r&7rBO{`vD~ zptx{s;c_6wQ4-`A45Yze`}3fMKn7!yx4R4DeC{*w1;uvCa`t2n{zGefS*2Mm}V8%~@7GB|IeFrl1bNhT3 zdBuL%uOOx}FF<0SikX;_|GYaIeL;at{H+T`+zmynt{e%7^9xFwa?taX_4K1zR*Pn6 zeckqI#`kZ9tqZpaZS2g5dY#SttGHuVM*YRPwa!BS^}{)?KfL##y6(vSCpX{lt(9Z? z)4P@%=oHlw*NBpo#FA92BVB8Vqv&q&)mfHRG-wm^pXq)Q!|-MOI84- zg;1r#GgE-FCYJV-{>h`bCpbT?q&%@GmBHQ9H$cHi&(HvfbZxIP0#!+a%m8L(tK|HG z%A(Blj1q=`(xjZsWCfS}+{DbhZ4(Wnfy$I%%2HB`lZ!G7N;32FAjTz?X6BUWX67jr z2e~`>q&o@&Rg1z@=O*TrrX?nqloq8HftCBrn{W!KfDf)9KP5GX0i-oL!P6Ni!{F)a K=d#Wzp$PybF{iKq literal 505 zcmeAS@N?(olHy`uVBq!ia0vp^hCpn=!3HElCJS6)U|>Ap>EalY;rw>SelKQ6fn(}( zC$LYv;-z)@h}RZAJC6gOzHtRAI%# zK&?0O>=)j(yLr`Fr|w(m@>T4u4hSZ2@67wz-hn=Q%`isrJt{T`^;6{A%wwB@!6XW+818F?HoGxy7e-rn))pv~^= zotEY U&7M}40Hc(_)78&qol`;+0F+zY5dZ)H diff --git a/share/dark_resources/aero_disc.png b/share/dark_resources/aero_disc.png index 59f32773d8d94a015844404db7ff4de385441f62..0f75fe5377287190cde69cfd66f68710181d4fc9 100644 GIT binary patch literal 1143 zcmeAS@N?(olHy`uVBq!ia0vp^hCpn=!VDyr?d5&Wz`$6W>FgYknVihPpfRy_qP552 z0Fk!;%eq`&F~3oGG-07tq(HodmuPpw!Y!gvr3O1+a?dhR(bVf}%077Tc+%B_MHQnfdy3l#UyBj*pJJQW`=YF;;>=0FL z{V}KF%mQv9`=Z#gpS{Hg6C2apdP<7sS-9wk-HOOd4l@aPr1@yWqO2+UDKTLd`GsMp zL$B>ouTL~szIMqDzibIZ9mPHtmlG=%wHWERWL)wAJtE&PF~I8*2fyM zz^UlZgZdBE+tTWa4*7DqHJ%f{{ZE2%S6QRm*=_s#b9Waq{g~gVz4qz)D~&h(FJwAw`ue{-)daRL(`=`r7pDG{x?b)Zv&2xw8ZuYx7vz}YjGF&oQ{Z#tF z0|5!$fN#5w?`D2m{CoRy%l-1X*+olNZ9bz3j1Prmk04(LhAK4%hK3dfhF?ITh8GMB zr3MTPuM!v-tY$DUh!@P+6=(yLkPGk$asB`QKak1J#=_6fBQ7o~Cnv+r&7rBO{`vD~ zptx{s;c_6wQ4-`A45Yze`}3fMKn7!yx4R4DegHKtBE?JZm(Bfj z-!EKa>)Z}!m&?)9OHX*rUGo0TNAuSDXv6X>A(N=yt6b-rgDVb@NxHT}p*xm%xAO*4^ zwIVak$|%CzZiMM*)O{-rA`HRVl(%xd2@el9>x~iJ_&HfrXW!i2{gW zVr6K4VXbP0l+XkKt$m(n delta 467 zcmV;^0WALa2;l>e7=H)`0000~lMvJZ00F2;L_t(&L+zL`Yr;Sj$Ddol4^o_4oa$ny zVrTJ#2pw}7N-bD$5|`py{6gX?U8Ivxp%tO!#U31*hM4!>T?{XaAi037#phz#xO~x)C4I$#(&0Yf-y`|DK$ZgkFl|u zU<{K~N==aBV{EJ@7{er$QWJUNGsgTFV?@IeEsl@~@%JnCEV07Y5<)~#1aTZAkjV2y zin_zhLg0T=AYLJ)K)gdpfCPcy1_=hi2@(|Id%J_d(GZV_hRbXtkOwHoQQjZN;sP`FsJh*<0#_w%hoF z4dqdv#UcJXIAI67-5xX=mq#|zI-m6d2nLaLU^**^G)zl*0GtC?A|a>=h1j3p)kL1J zHHGe}#GG*7T3IQ$d#ut;?8-p6->mZNa!YCA)XAg}rzR$K|1Y(P*g1#cQabFgYknVihPpfRy_qP552 z0Fk!;%eq`&F~3oGG-07tq(HodmuPpw!Y!gvr3O1+a?dhR(bVf}%077Tc+%B_MHQnfdy3l#UyBj*pJJQW`=YF;;>=0FL z{V}KF%mQv9`=Z#gpS{Hg6C2apdP<7sS-9wk-HOOd4l@aPr1@yWqO2+UDKTLd`GsMp zL$B>ouTL~szIMqDzibIZ9mPHtmlG=%wHWERWL)wAJtE&PF~I8*2fyM zz^UlZgZdBE+tTWa4*7DqHJ%f{{ZE2%S6QRm*=_s#b9Waq{g~gVz4qz)D~&h(FJwAw`ue{-)daRL(`=`r7pDG{x?b)Zv&2xw8ZuYx7vz}YjGF&oQ{Z#tF z0|5!$fN#5w?`D2m{CoRy%l-1X*+olNZ9bz3j1Prmk04(LhAK4%hK3dfhF?ITh8GMB zr3MTPuM!v-tY$DUh!@P+6=(yLkPGk$asB`QKak1J#=_6fBQ7o~Cnv+r&7rBO{`vD~ zptx{s;c_6wQ4-`A45Yze`}3fMKn7!yx4R4De%&tw1r=<$+z&poVA^DQA$jwH z@7yPNPR{##>Fv|bFJJy>v86eWy*QIePL8a1BvR7q&=}nVW!arrMnC}Q!>*kaclU=>%Ic0K?-C; zYDH$6l~ZO(aX@NOaAIyjPAY?ijsge?y|q&Zs#1ijasj#`Br_M}5<^QX0}Crd69o{% z#LC$C>5uMjK*hpv#h$r|>8U=cdFdq?45nr>mzIER6hf5_&rAWznpoOT`X`U#p5Xkn zlJdl&R0elX-v9+8JwpQ^(zU(H2vj8vG6R@#t&;N#DvL7HGfEf&N|SOjlNDU@a}zW3 zwoNpQ1}am6DN9K$PAlvuW6%1nWy>~nI|8WOv_W^xAB95`8@#)MTIDttnCe(}58 zmdmB4Wfiuibll&3Yws1VYHyy2%QRCXk2z?457yjuJ58=>eP$y|>jfrGzJ-iJtW3N@ zyiA-zqDh~By88F?KiVD^!m({*gwD$Q^@5Eq?Fkcp{%LMI?3g$q$iblgM9w$A#~)V+ zcocM8&GOxP>t>nllcV|nH8!ncZ%t^3dp}c8PrBsxzP7aw4l39%sK2#$Rngs&ZNTBO zy?VdtgXmVpsI}5rX6qHqnjB<)iF`L(cG-NEPaL=Hg?nvQM>h5fJC|6MhpeC9o$J!< zkT+wI)03O`o=GMPR0cWqS#FE}ZxOD>!*o+<`L$0k|9@QN=XKw2YQv5He~UA|>hI-j gw)o1}WBHH0RN;&z%jUHkfHB43>FVdQ&MBb@0DT+9s{jB1 diff --git a/share/dark_resources/aero_drill_array.png b/share/dark_resources/aero_drill_array.png index 0cd39bc340d8744ed2bab075b833f7d4eb763adc..f8203bad31436518d12a0e742bce7d5538b3d647 100644 GIT binary patch literal 1162 zcmeAS@N?(olHy`uVBq!ia0vp^hCpn=!VDyr?d5&Wz`$6W>FgYknVihPpfRy_qP552 z0Fk!;%eq`&F~3oGG-07tq(HodmuPpw!Y!gvr3O1+a?dhR(bVf}%077Tc+%B_MHQnfdy3l#UyBj*pJJQW`=YF;;>=0FL z{V}KF%mQv9`=Z#gpS{Hg6C2apdP<7sS-9wk-HOOd4l@aPr1@yWqO2+UDKTLd`GsMp zL$B>ouTL~szIMqDzibIZ9mPHtmlG=%wHWERWL)wAJtE&PF~I8*2fyM zz^UlZgZdBE+tTWa4*7DqHJ%f{{ZE2%S6QRm*=_s#b9Waq{g~gVz4qz)D~&h(FJwAw`ue{-)daRL(`=`r7pDG{x?b)Zv&2xw8ZuYx7vz}YjGF&oQ{Z#tF z0|5!$fN#5w?`D2m{CoRy%l-1X*+olNZ9bz3j1Prmk04(LhAK4%hK3dfhF?ITh8GMB zr3MTPuM!v-tY$DUh!@P+6=(yLkPGk$asB`QKak1J#=_6fBQ7o~Cnv+r&7rBO{`vD~ zptx{s;c_6wQ4-`A45Yze`}3fMKn7!yx4R4De`PZ^ zEjsdI1;{a~C9V-ADTyViR>?)FK#IZ0z{o(?z(m*3B*ehL%FxWp&`{UF*vi1*$|066 z6b-rgDVb@NxHT-DzsC%yK?-C;YDH$6l~ZO(aX@NOaAIyjPAY?ijsge?y|q&Zs#1ij zasj#`Br_M}5<^QX0}Crd69o{%#LC2c?UkDvK*hpv#h$r|>8U=cdFdq?45nr>mzJym zN(-S%hi9e$Wlb#YC;gL0aZhl5T1k0gQ7VJGr*D9Qk)ELe5b4@pWdy2{2AKiO%vQ7AF^F7L;V>=Ru51D$UF((ap?L zC=POW@=13T2C5c?sm@KzD@{vGE-5WaEdnd|nK$7SPyruYL4HbV4g*MQbb_ZdP=>+N L)z4*}Q$iB})k&qa delta 478 zcmV<40U`d13G4%q7=H)`0000~lMvJZ00FZ}L_t(&L+zNqY63wJ#>YP*d_(GCa(nu;HLJ|TABUzBelewLlU6Hxw;Mke<_kFW}#s(b0 z(>MYKFo;8O(VQ?R1QoDy5)_k_%A8=yCm3u_2#U!{Wlpf<6MqagCj`Z0r7|a2@(Bi; z6M|y0QkfGh`2>T_2|+PgsmuwAe9pOF=bWlos>u-&A^zWLbEzfvE+Irw6i}8W0;$ZW zl61SwJOqBz0!a#?1(F;>10)NCG)OiGNsz1%U*A9QaDT_%wX#B>8>`g^j7Co^kn9i$ zvRuByc>EjT8wmDGOl|VPF(VNMSJ~;kLo8>C$DC4>thXB z;8gVILH&p7ZE1ByhkUu*8qbN}{wKk>tE|!O?6&>=xw{LQe#~#wUi)LqiJ#!!Mvv!wUw6 zQUeBtR|yOZRx=nF#0%!^3bX-A$OZU>xc>kDAIM~9W8vrL5f>Mglat}*=Frqs|NQwg zP+T~+a5<3TC<*cl2GU@#{dv$rAcHZ<+ueonKa=h~AcwQSBeIx*K~DmN8MRiaD*y%A zOFVsD*`KiRiVBEUOG9nO2Eg zgSNo#t3VA>ARAIEGSjS_GE0gBQj3BUa|?1(87y=ZKuGAVojOpJB3zXV&=nz>xgeJq zT3Q)cSQ(lqfEcDgH@r`H_X?<37_QheH!(fcCp9mqPu`DrEPiAAXl?w-B@3PyT{20)~1dzBHWN*ZJaFbi8H=ND8KWu|A8Fa(q) zChwYB;8cwvr{Z)-pQwcfs4H|xRG zECpl6U7FVtrIzuAGki4D`OYrob9l=`E`@t-PZv#8yw|b)Ay++^Q>_f*= zY$=}lN29sun#8Z)!G9!=uz#7{y>PP1LKEMe42#YyTHPo!|9IigT$3GK8JPv97bZPe zwP5LitB&3ct6S=-|1X&RdUZl~-*}!}{y%ujIYYy{5k>;%9B>&a7a@vj+}8)RmQyyZrN}=LgZKk_`ScYJV@8 zxGdQ|Sy;5nV8Tv#J!)g>+a$O+ZH>e=j!f#`}5Dlw9V~a(lfTp^8Q-CShMZj zcl{NYZ}O)_%WgTs*zEP<0{fH(zSzW*zw`f>f5^D>W!>bk;tRVQEOVDF_$;SAyZPK^ zLqq1d>esTuQ&O#J1QUddt=`*&Z9J`&Z1URPRrmV663GWq&eK`@_})HGzPaLgrETin q+h?>_dpu-_T@qFLFIU;Op0Q-n9e0PRPxb>Nn8DN4&t;ucLK6VdOz|NA diff --git a/share/dark_resources/aero_path2.png b/share/dark_resources/aero_path2.png index 80a83881f9310c289f5742813e481637426e3ea4..cd95994c39fe1f2cf5ea0b1528dd2359d7ce26d5 100644 GIT binary patch literal 1154 zcmeAS@N?(olHy`uVBq!ia0vp^wm|I0!VDyPS2o^YU|_7xbaoENOipHC(3n^|(c0s1 zfJoc_WnHeXnBOQony}C+QXt;KOSC&-;TF-TQiGi@xo4TEXzKMfWgk3vJn8Deqmkk4 z;f?||4Lf#NY3}mqe6H3iW+=DgPXGUT|DWG0W?UGTw(6!K--=nOD#?L{lVe49#|b*< z|9W_M%Ml;jc~L%xH}8A5vj3Idq0M`K|63!cnr?JJUFf{w-3=Y)9qDGeb3fY^c8IFB z{+Ls7W&yX5eNk-L&)(vLiH+%PJtal+EL?QNZbjrJhna*t(tNaGQPvdwl$bD!{KBx) zq1X1P*C!e*U%O<7U$%syj$$8+%ZU|>T8wmDGOl|VPF(VNMSJ~;kLo8>C$DC4>thXB z;8gVILH&p7ZE1ByhkUu*8qbN}{wKk>tE|!O?6&>=xw{LQe#~#wUi)LqiJ#!!Mvv!wUw6 zQUeBtR|yOZRx=nF#0%!^3bX-A$OZU>xc-0rAIM~9W8vrL5f>Mglat}*=Frqs|NQwg z!zzYp!lwj)(i|m0e!)N*47NWHS_ot?CV9KNaDKeG^bL^1S>O>_%)p>00m6)0tJD>M zg6t)pzOL*~Sa?MRgr3&+uLcTLdb&7>Z6(i1D(?#(X@7KNI@F=>w@0v_d6xMj_T&3>j`a7{MozrHrfE|0 zx{Cj?>RbN5 z9idv{8c~vxSdwa$T$Bo=7>o>z40H`lbPY{H3=FIc&8!S9bPbHH3=ABj93xRQIt27|f5@%ChSptKOGba-Y8 zP}aFQ_caOwTA` z2q;a;$xK#o$#38pM1wK%ybv!En1KM!JDQfX#RiEd_|LUEA0lTW&% zFi^E9Om%KzUTIola!F}XY7tnu&%6nzfC~8F3i4A@a~MEcqZ2%xfieu9u6{1-oD!M< DjbEW! delta 486 zcmV+3G@Sy7=H)`0001ghn(vG00Fy6L_t(|UhUaIO9DX@2k_@D@PmZs!c$)C z6m^z9h|qCo4^e@Er|=?P!!IOWrHgbD5-Nh?Ne{L~H<6v0$D6+w!Gp8E`TutuXB(8@ ztC66YfKDZKB#opE&j9LeINU!pB#opE&j9LeI9x1bs5k0ucz*^^Z^PkY^+vr>Z^JWy zdK(TGt2gS6dK;br)Z1{lSiPgw+d22`oQpDkltH;`jQ)KOeht9~l$(puS(Z_r=R5&H zuOsMS#nnX6{8?zY3Up|=8gxjwDs(8gI&=uQO7zF)7v108dRx_1qB-r=>WzlOM=x-- zXofGBuQVDx)qf6Gjb`{_@j{cyxK_9t^m_eH&F0Z&|H7M<@~h5Wn+i082ZIMXIX$DR z%X9BLwCHF7bCR+(^-<|!bE2aA{hLj~Qe8%OyBE~yw7sSs6}|1RrKCNZ&1pJ)u5|&E zw4)2b`>d+w$7*wKtA5a4Adxo`qKVOp8l7#Q;P?xkE4Ic{MXOFH9 zeJECb>XJk63pbT?@j*gW;%3oRkBm&B|EsxKbQRn*dKWwibou@^kKUGc66i8K8FUez c6k0YfKip8T8wmDGOl|VPF(VNMSJ~;kLo8>C$DC4>thXB z;8gVILH&p7ZE1ByhkUu*8qbN}{wKk>tE|!O?6&>=xw{LQe#~#wUi)LqiJ#!!Mvv!wUw6 zQUeBtR|yOZRx=nF#0%!^3bX-A$OZU>xc>kDAIM~9W8vrL5f>Mglat}*=Frqs|NQwg zP+T~+a5<3TC<*cl2GU@#{dv$rAcHZ<+ueonKa=h~AcwQSBeIx*K~DmN8MRiaD*y%A zOFVsD*`KiRiVAQ@$d_FN3Ke*|IEHu}e|u4pufc$)_2J1|f(o`=?gt-PFl{ouki40t zS>b)6hrr*r(@W2Wc}+{bxx1%Apxo%d)C$u_UNZa{>yB6-j#GcMH*vl3Cs$^hP5q7E z<5L}ezgPRvee3Ez(Hn))4>G4ne5-!>zob*U?B8drvbj zoS#-wo>-L1;O^-gpkSnDXaGdIwpST}s-!_?0Q0U@a(+Q&QD%BZ2}3|>Qch;Ff=hmG zVrJg9iH6ZYWlAt*DXGQDMVSR9nfZAT~-mR*C%MMfD3Vn)q6;V|e^FLQh)q@!1L>yB@^ZZ4TjJu*pUXO@ GgeCyLz2gM{ diff --git a/share/dark_resources/aero_path4.png b/share/dark_resources/aero_path4.png index 5cca6e2efc28e8255674b754604f08c31e3d3db7..155b03292776f7dcc69495116a9a030e30ee4027 100644 GIT binary patch literal 1145 zcmeAS@N?(olHy`uVBq!ia0vp^wm|I0!VDyPS2o^YU|_7xbaoENOipHC(3n^|(c0s1 zfJoc_WnHeXnBOQony}C+QXt;KOSC&-;TF-TQiGi@xo4TEXzKMfWgk3vJn8Deqmkk4 z;f?||4Lf#NY3}mqe6H3iW+=DgPXGUT|DWG0W?UGTw(6!K--=nOD#?L{lVe49#|b*< z|9W_M%Ml;jc~L%xH}8A5vj3Idq0M`K|63!cnr?JJUFf{w-3=Y)9qDGeb3fY^c8IFB z{+Ls7W&yX5eNk-L&)(vLiH+%PJtal+EL?QNZbjrJhna*t(tNaGQPvdwl$bD!{KBx) zq1X1P*C!e*U%O<7U$%syj$$8+%ZU|>T8wmDGOl|VPF(VNMSJ~;kLo8>C$DC4>thXB z;8gVILH&p7ZE1ByhkUu*8qbN}{wKk>tE|!O?6&>=xw{LQe#~#wUi)LqiJ#!!Mvv!wUw6 zQUeBtR|yOZRx=nF#0%!^3bX-A$OZU>xc>kDAIM~9W8vrL5f>Mglat}*=Frqs|NQwg zP+T~+a5<3TC<*cl2GU@#{dv$rAcHZ<+ueonKa=h~AcwQSBeIx*K~DmN8MRiaD*y%A zOFVsD*`KiRiV6r%s@e}qGzFe6jv*e$-(FPYYcSwxeR%4Ypn@%z`@u&ROq+}^ByVnE zIbJOxVnv|27tl*NL zo0yrmZK7c`P?-`;SxRbga#3bMNoIZ?#JHr=%$yS4%shqSAa^I9bVp&JYEhW#+{C=n uw8Z3+(xTKNuyUVy6HWmY@WB=2r=;dEfV4&@csc`R7(8A5T-G@yGywp^b)VY+ delta 467 zcmV;^0WALc2;l>e7=H)`0001ghn(vG00F2;L_t(|UhSB%N&`U;3e7Yeq)CRhaws0hjg7ouo0?#@o;{%Zn(y}R%KzYLpgQ3J15 z1DOfXO=%rXqiM$pKySz8enUgkXxecC(A#mj7-Y~JdOJ=4dVf1E7t%Oz&cPhY&tO2t}S>tE!^9t~mhJ_fUP< z<}``W{GB$q321F_Gtipgrl7UJ%|UB`n}mLSd#9_*i)>TfBs90ZTt3ribdv?#EHr~J z7Ed%D-zEn)4S&tx^Z6r9CU;4}%|NeKFVt@DtoJXxS^0UT+_jm2X5iuQn)db&>Gb3% z`wp!*bOh!m2Jv z#i0K>nqugF|BO1F-E3`}gVs1;FbSRefD+KT6Hayicuc+~z28HeXhoJlZ$a$PTM$~2CD2T8wmDGOl|VPF(VNMSJ~;kLo8>C$DC4>thXB z;8gVILH&p7ZE1ByhkUu*8qbN}{wKk>tE|!O?6&>=xw{LQe#~#wUi)LqiJ#!!Mvv!wUw6 zQUeBtR|yOZRx=nF#0%!^3bX-A$OZU>xc>kDAIM~9W8vrL5f>Mglat}*=Frqs|NQwg zP+T~+a5<3TC<*cl2GU@#{dv$rAcHZ<+ueonKa=h~AcwQSBeIx*K~DmN8MRiaD*y%A zOFVsD*`KiRiVAQyim7J6 z&N-{!{qLLns$TJ)cGK(Em!E#L{8^dDyWu;}j;Z0fChaBvo*Vp~uAE-(|MZ5{W`{>WSKhL(lk6&)gxcBD#Jq(3s6lV3Z94-JlR<*=6q9i4;B-JXp zC>2OC7#SED=o*;l8k&R{7+4vaSs5DY8W>v{7+g8T(uJZSH$NpatrE9}rStcg0X0a0 zY)GxhOtW&zEGZ61EecM|Eyzh_u+UKeA)&W+>OfVBa8)iqSA=Bdf?Q%~X=PwxWoV)R zVwhT)nEpir+Q-Uc=Ni9w;$}A|!%+G@umsFaWQ=*%hr%)W^?&Op1C=66B3R9h%m{*#X sm|Rj?lv)HmdKI;Vst00mOC`~Uy| delta 540 zcmV+%0^|Lv38@5-7=H)`0001ghn(vG00HnxL_t(|UhSDNOT$1E$6q(0A4EDUPIjr2 z=v@3D1;<Tj4L4VW-M14nZ#S-&40K85^u(GrF%=fCEkoH zAn|4_SGu>vTjI^Q0upb=a;19*i?>qhM=2F#{2+s3))4yd)%!JgA5c#&giewK(lo^a zc)bpX%mq)lM@trG`ijz*3m`i!QdSF{gXUhmM!wzgcxHaX}j4}Ta;(AGk`KA_Bk7J-vA?E-BB z6lhBYTWxxm(OsVjw98xyeQwdb)pr5gn!UBAqk}F3%+7RK=sfV&#oGlqT4)M?l0000FgYknVihPpfRy_qP552 z0Fk!;%eq`&F~3oGG-07tq(HodmuPpw!Y!gvr3O1+a?dhR(bVf}%077Tc+%B_MHQnfdy3l#UyBj*pJJQW`=YF;;>=0FL z{V}KF%mQv9`=Z#gpS{Hg6C2apdP<7sS-9wk-HOOd4l@aPr1@yWqO2+UDKTLd`GsMp zL$B>ouTL~szIMqDzibIZ9mPHtmlG=%wHWERWL)wAJtE&PF~I8*2fyM zz^UlZgZdBE+tTWa4*7DqHJ%f{{ZE2%S6QRm*=_s#b9Waq{g~gVz4qz)D~&h(FJwAw`ue{-)daRL(`=`r7pDG{x?b)Zv&2xw8ZuYx7vz}YjGF&oQ{Z#tF z0|5!$fN#5w?`D2m{CoRy%l-1X*+olNZ9bz3j1Prmk04(LhAK4%hK3dfhF?ITh8GMB zr3MTPuM!v-tY$DUh!@P+6=(yLkPGk$asB`QKak1J#=_6fBQ7o~Cnv+r&7rBO{`vD~ zptx{s;c_6wQ4-`A45Yze`}3fMKn7!yx4R4De^XjNhbh+hoMfc72j6xxLc+ z_qN-jUb@OfVBa8)iqSA=Bdf?Q%~X=PwxWoV)R zVwhT)TE0HLh#RO_7_QheH!(fcCp9m16IqA=CDiFu`I tiOD6UMX5z#Wc)I$ztaD0e0swTUphW-x delta 455 zcmV;&0XY8m2-O3S7=H)`0000~lMvJZ00EpyL_t(&L+zNqY63wJhsQ49g9PgYtJs(- zB(>y0gp{{egcvYj6>P*d_(EbUX(W}PU_u~a#DOIwVee*Ucagb9kli`H-#6|b8*l_q z;|LhQAab#2Cd`Cj0@hA~VX{h@308c9lg)%+n5r1g6 zJQ@T6VA6CH;k1x%FbYJ!f44V4t%4BU?iF-8Z4nz$AbvZFla2X&0khdltsgYmP>1;I z;)D>r-Yv9Rr)(R^AS5qLNg+b6w;^K;A|$1%W9UvEGC+@3yX;IDM2NmvV?u2BXRPen x$zOW^3oUyH|39mcQ*M?fsFgYknVihPpfRy_qP552 z0Fk!;%eq`&F~3oGG-07tq(HodmuPpw!Y!gvr3O1+a?dhR(bVf}%077Tc+%B_MHQnfdy3l#UyBj*pJJQW`=YF;;>=0FL z{V}KF%mQv9`=Z#gpS{Hg6C2apdP<7sS-9wk-HOOd4l@aPr1@yWqO2+UDKTLd`GsMp zL$B>ouTL~szIMqDzibIZ9mPHtmlG=%wHWERWL)wAJtE&PF~I8*2fyM zz^UlZgZdBE+tTWa4*7DqHJ%f{{ZE2%S6QRm*=_s#b9Waq{g~gVz4qz)D~&h(FJwAw`ue{-)daRL(`=`r7pDG{x?b)Zv&2xw8ZuYx7vz}YjGF&oQ{Z#tF z0|5!$fN#5w?`D2m{CoRy%l-1X*+olNZ9bz3j1Prmk04(LhAK4%hK3dfhF?ITh8GMB zr3MTPuM!v-tY$DUh!@P+6=(yLkPGk$asB@v$YNk;W8vrL5f>Mglat}*=Frqs|NQwg z1H=EdGwc+B(i|m0e!(DhAh7*;&_W=^nB?v5!uj#$(l{rCvOQV*mAiad}P72$u#+R z8q4kL4-|g;9G(1ciRRZYH5zR}fikmW0yizx;4(E0oO00PQzm0Xkxq!^40 zj0|)QOmq!RLJSP749%200kpGLjxevwY|y+R3!~E1DIv4lJg5Hi!#$QN*Dr4lX5bX6(P=Kpc z00vNqSS+duHNlvGwi9ERq*7{v6d&VYHNhArsg#-^#m6{UO@AEYac!i4gyHv3H3Tww4egNfJoY6oEwECsH)q zW)=dUNr8BUkOJ`zApsHuf*T|l1Sd#Ph~NDIK6>xuuU1e9w6WcO!*KXX0tpU*AnWx8 z#^X_LkSHJ!WPiC_!E`#w1>zlIxBG!|`Qfx4;^KFHc(pKEsSS-F^KA&Bk&~__-YdbFv zaqZxQf3DqrgG%M`rj4i}Tn|jqL%1GqGY71TofE8`TsHu+wxXO93UQWzwv%g1P=2Rh oCrWypV+&!zC6MSR_T4}n0WO)?Ibv*4=>Px#07*qoM6N<$g8m)C6951J diff --git a/share/dark_resources/aero_text.png b/share/dark_resources/aero_text.png index 62862d14202808fa6ca7a30674bd981e5ca96cd8..59fd5a1b8c337622bcc1a5bba09d2e0ad1ee8d54 100644 GIT binary patch literal 1164 zcmeAS@N?(olHy`uVBq!ia0vp^hCpn=!VDyr?d5&Wz`$6W>FgYknVihPpfRy_qP552 z0Fk!;%eq`&F~3oGG-07tq(HodmuPpw!Y!gvr3O1+a?dhR(bVf}%077Tc+%B_MHQnfdy3l#UyBj*pJJQW`=YF;;>=0FL z{V}KF%mQv9`=Z#gpS{Hg6C2apdP<7sS-9wk-HOOd4l@aPr1@yWqO2+UDKTLd`GsMp zL$B>ouTL~szIMqDzibIZ9mPHtmlG=%wHWERWL)wAJtE&PF~I8*2fyM zz^UlZgZdBE+tTWa4*7DqHJ%f{{ZE2%S6QRm*=_s#b9Waq{g~gVz4qz)D~&h(FJwAw`ue{-)daRL(`=`r7pDG{x?b)Zv&2xw8ZuYx7vz}YjGF&oQ{Z#tF z0|5!$fN#5w?`D2m{CoRy%l-1X*+olNZ9bz3j1Prmk04(LhAK4%hK3dfhF?ITh8GMB zr3MTPuM!v-tY$DUh!@P+6=(yLkPGk$asB`QKak1J#=_6fBQ7o~Cnv+r&7rBO{`vD~ zptx{s;c_6wQ4-`A45Yze`}3fMKn7!yx4R4De|nI`LC!G=p5A&*NBpo#FA92n)jwVXWq3KT$hpAUHtv;|2J>nY#PxSLJ-QT+;Eu<`9KQ#h}KNb`QoyOp3gV*c3Szaee&y zmzn>2`J4UIv{-g+jH*45@#P3pV7tSFr=MhxJ$`&w9oR%ZVERQuf6uq z*xtYDuYmdf4_TX5r?)yZJp3T&=Xd_$uUAev?C04W8CIA~RhlF6N%jnrp~RgqzJOH< zF6+xV@4lPaAswmk%B!#_*{;6z=9{G#o7BuFIpuuv~c^MhqvUza3R2S1s0-E*Z+K&n9nj93OwS3j3^P6k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKpuOE zr>`sf6Bb@k0kKB{-kX3z-JULvAs)xihFbGAD2Ti^R?*9Ok!jPlc>71Wd44k!3J-aD z%xIbP;P&k=&dn?Z<`XJ3-pDjsTxxDo6)oZ4=*a!PH-fu>{hdwo$@%v`Rvo)~!YN3> zfYqXVf^bM&vzV9>a~U^pRD$lG1+6QVzEf0Xx}3@F*?2jc@to`PyU`DfKZv_K^m{V> z-ddXfknzPkrQH_KJdAcptHiBA>c>J4paup{S3j3^P6Lz8Gi-<0047(dh`GQ0B=b|K~z{r?UgYO03Zm&L diff --git a/share/dark_resources/align_justify32.png b/share/dark_resources/align_justify32.png index a2e329a30043e30030f689fab74a6658d3478c64..be35b0e557aca96a6310ec6329325530f6c04d46 100644 GIT binary patch literal 347 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKpuOE zr>`sf6Bb@k0k;3kqptyll097T-E z?|ymBhRqNEN)$#m))*e{V7JbYf5g%%oW6idMlt(3(~W~Ht<1_g3l<291zd2Aa&Vkq zyt~P`&itH%@3O~4RgVDNPHb6Mw<&;$SuwP>sW delta 104 zcmcc3R6Rj5iH(7Qp}4B*3y^a1ba4!caDO}bpdbSSM^jO;`TA@wyDbfJiER50{G7ba zd)fwu_Y6P(pMS==g9(UaCp2hZU<5MeGzdLnDPVuW#O`dV%iqJm&IL4$!PC{xWt~$( F69A?pBmDpX diff --git a/share/dark_resources/align_left32.png b/share/dark_resources/align_left32.png index 14aafdf8b74f07ae267c0fc9c065b34d27b8a193..9cd3ca91ae74e9323510864a4a42f260c8115131 100644 GIT binary patch literal 373 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKpuOE zr>`sf6Bb@ke(S8Ml9526T2B|p5Rc=@f6hBdCM*iDXXbVmPh~TxTXun8hbLdNUTNN)UO@Z(dP5wpfQpPv7kYj3gHh%toRQ`q^Y^ISjB zA*v;=5hW>!C8<`)MX5lF!N|bKK-a)T*U%)yz`)AT)XLOS*TC4yz@Q`GzX*zk-29Zx Yv`X9>e)77n0BT_HboFyt=akR{0F}UT-~a#s delta 148 zcmey$w3KmzWIY=L14D6D)fXU@PA5ZMV`Yap56QNKcR8Q#hr$_GJO2EtqI!f2q_^U?#sdZbz ydd)ecp@OMoa_;Zvx;HppR)#pU?_&9MQvA)AJYF-P#SEUVelF{r5}E)C`#LEA diff --git a/share/dark_resources/align_right32.png b/share/dark_resources/align_right32.png index 3044f6ac5c8dc0fb75c79fac0eb89ea988b04a49..480b1d5923315347f8142ef1016e44eecbc960eb 100644 GIT binary patch literal 363 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKpuOE zr>`sf6Bb@k0imb0{i}gO#hxyXAs)w*|D1P_Ojs0P&&=&Cp2}uWx9kGH4o|*j$-xG8 zCD9~C;SYu_0b*>g;`1(Cn82ecnQst$Lrg(>T0P~-`)Q(ken1`pa8mo<>&pIwg;!KSghx(m9s>iTtfz}(h{pM)6W4n;CyKPr zKlvjpF2F7z#ZCMVbBuxBEZ!!z$Up(fE=L_U$8HH7rAPe=Gukqf1aqXhlbg7dq>e05 zvbtFvDezFjZu?A^5BG{JzdtOpFjuQv&-agq<%!1ZnSn~~7cPmG&OaCW$#kh`*5UoD zSEX#})KjrgJU?N!y8nsAw-+5KEKy}zwr0A&*o$W~je|N=?PlaKC$Do5Z{FtB+LYS3 zhS%WUrw6_ZgQ_kp6NtLL^xf2NrHYU4$NfI}`AX3}&$jIuJ2S82qu~xQn78H$NpatrE9}-t-NLKn)C@u6{1-oD!M< DmI%n} delta 132 zcmZ3*GL3P9WGx#51B3kM|A{~<*3-o?#KJ#0Wr2V}(2Dttha1}3+W!CG$<4@cxY&G1 zafxJ_!6wB5<_V_FA_7J{X&hn99h~C7Bp5cc&MxmLVm!(wAUwBOL%{Kzs>t^WVWCMX kKRsv8U};&`_UH}=gZn=lLB%&8LH03ty85}Sb4q9e0Po2zl>h($ diff --git a/share/dark_resources/aperture32.png b/share/dark_resources/aperture32.png index c155cf1a9d491681a424bf08d429fcf950c9349a..3c9156ab0630839fed62ee1c762634f0db648897 100644 GIT binary patch delta 909 zcmZ3%G=qJDWIYQ51H;YYP4z&ECEd~2k%3`jKlh(RRv=#?*(1o8fuTx`fuW&=f#DZW zsNn?zL#Y7+!>a@a2CEqi4B`cIb_Lo1C76=D-CY>|xA&jf59DzcctjR6Fz_7)VaDV6 zD^h@h>?NMQuIx`(ct!awKF{%Z4Aj)^S?}T);&J@w)U*DS?_*vys4Gw$|&r+ z<&l?ir$$Z>TiCDq9~+Gf-8OV`Kfcb!#5nzs+hS?W))jxaHC}mfn|9>-_#X}ZxpRTW z()W_W;%8#doSr-L^Rs)^?`BH;+Q0F+{rS~~S8lI#{JL`M9W_=OIB$x426M6Un6y2F8g(e2mka{QlPJHF8o=!YvpRDm3UlgT2g#$%$TKvkB^rV)R-B~m<^Krh4;P%5S_FVP3Ti+ok-g7-` zR_56s(#r*o?|sMRzWDY|(TOSh*3EsM;l5>}@g45#&1{?6WR43gnl307Th!_5X3;Bf z{G_B&V3U$iO3!u4MN9QMb?ibfMzniBE0n@8$ ziEBhjN@7W>RdP`(kYX@0Ff!0JFwr$M2{ACRGBmX^HPbaPwlXlNlj#48q9HdwB{QuO Xw+4P!b6`eeVDNNh^K)6}l+XkKdwGOi delta 280 zcmV+z0q6dh2dDy&8Gi-<0047(dh`GQ0PjgeK~z{r?UvyVgfIw$_04(nGfQp;xw3Y< zC2BJND)gf`#=hPB>^JLgGJu(V6j(EpbC!JcV^ui9sURu9sBkX`1jxi$RU>gf04PZn zX0Eip%it+M31q^^_821pprBsy3WLBA#Ki$GmQ|irlC>`8jDK#O07~_}KcV6R1W*FA zp~MP_MMwZXNI7b)RxW_$z&jl%M~=+^HvunuLp;)w165F+=c+g=gU_`b2LdCEe9T=2HG+MwJM>2(aY8fgt@{{=g~&t1z$9bpyAEnwEpdQV$0 eODM~;01jx6ND(kWy?ki^0000)-zW^51U;*P3^C_Dnr_;J|?o@vrLd{Ga@P`d@M9 z;7PM)yD3U$mOdd>9|wAM51#$us-^YDLW-wY&=(8iAnjvG`B@ z=l{45i|YJ1aG-yJpP1LoV;|-}R6iWwBFe*4|5`EU*cOpxSN~7{RP>q4xGo_fp;3Fs zcc+;T%XXdIzwLjt{f@Q&xVQ5htEg-YUQqhqTJ74WO#KaP*Pc(G|9?%-LE$_5mH$2Y zm%h~R%0ecFv-?78U2D>TLBOC|;u=wsl30>zm0Xkxq!^40j0|)QOmq!RLJSP73{9;} z%ykWntqcrAj<#G!(U6;;l9^VCTSMv$n{1#4NstY}`DrEPiAAXl<>lpinR(g8$%zH2 Ydih1^v)|cB0TnTLy85}Sb4q9e0G{H_!2kdN delta 310 zcmV-60m=T21jYi88Gi-<001BJ|6u?C0S!q+K~y+TrP8rV#6S=R;F+ybhCGXv%{_sQ zML^K%;t zf$!lLkWy+BlTuC=_!H=ZHf#W7S++yOhq5d;?c+JA1`(P05`O?biRjs=K4`C>#srQ5 zU_nH8W5ewy>W~4Drm3rxS`*Q^?eCb#-jtd7g@{f}AW0HWYkgBy)m8VcO)&;+>$*Ob zQa0^Htu-?95)sdY5Z6Hvy!G)h;J#^^O&EsnaU35BA#MTS)pgyq@B3e7vOS>d(Q%wd z&+~**Y86G%hc9g=R-h<~i#*StrdHhw{4CP^Ri3IeyM_Nk-$rM05%JHl-v9sr07*qo IM6N<$f~}d4hyVZp diff --git a/share/dark_resources/arc24.png b/share/dark_resources/arc24.png index a6e15d91e4cd42f57886fdadd49150fda87ee63e..202cbb068d524c81c8038d6382a27c547008a2d5 100644 GIT binary patch literal 653 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^+ z;1LNlk>v;oGuoWF(hL-2FY)wsWq-oLD=NU=u^`)lfq^mF)5S5w;`G^x_8v}wBFFZx z7E4m<>h_3k?)q4eos*U2+o6yV@LVc-mQqwv=A@Q34Jqj&t;LEuTrM7}s}?SF;+SOR z@6q#pYsxR5qZjjceZTYh_qqApJaa=nA7I@P5F*aZbmfb*guxu?4+nay=P0i4v6E2_ z66X4ONJ;;xvqq>~;V$zBsg6=bf2ubZb* zVvbb5)>|IS^IvPvm9Yi{P5xgN6d3q?VcmfX45I%;oMX=$JG;Br6#BfncrmZ#O6#Yi z3Jf=*9`2p>_p0!L+~vKsyvl3kH_wdo=9%5-GR5=Bm(=<4?<-!gZRwrMQ8fGUw51_s z%YR2PhK4;%Q~r2%t&HE)X{TmIn}p7&_|O8Y+9Dw&Dx((bmZw`?a&#fg!J2;u=ws zl30>zm0Xkxq!^40j0|)QOmq!RLJSP749%lpinR(g8$%zH2dih1^v)|cB0TnTLy85}Sb4q9e034q5 AbN~PV delta 430 zcmV;f0a5;q1-%218Gi-<007{3J@^0s0fb3JK~zXf)s??X12GiG-^(h};%vcDoZX!Z zB099I)62D>phKNJImbE_#K9(uayU3R>LiZ-*!=^fAUC=R#U70u^yEB}G}ltW%rEcr zzTbS4Ak28-jQhji1A-t>sj46drXJu|gKTq~bw$7v0g5QJ0)MiT+SJ(;X+4%w-XY=z z5#8vl(!op+EkFoy!WjD`qT?}V@e_!oP6sgowh?iib6#_~C${8i0o`tQl`$4_&R2>8 z@&V8S!Z4ic_xm5^a(TX9uYXMfN$oOTBq`;aQfkBVyjL4wG|W*HMF-hB7r-q5Tyf5? zO#mT84G}v4@PFj{{$sP*Jaw`tDUwpQ5ph67hk1YyVi^(70AO)A9PTt4jR(^ZMvH_H zNs=}>=UeIKksUq&Z~$m4r8=JH4Qv(~0j*YRtyC&q#&Nuq_?fZe1rhg&=-uV;jeu;n z<2Zhb^s@U=_eU*QQ`zB^8V+cQ~y}wRQ!Ly YH@6$68RBv40{{R307*qoM6N<$g0{ZHRsaA1 diff --git a/share/dark_resources/arc32.png b/share/dark_resources/arc32.png index 391325ed3e9d3eaaa29ac6dfb803c3a8c9e2a038..29f355a6f71c4762624a24f2521c504ad58d0e47 100644 GIT binary patch literal 786 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr16wo*Gj6g|ZU+jomw5WRvOi(r6&2u+kT1K)z`*#x)5S5w1;^O8>YC1ukdga&Yrs7+(8D zKQTsQitoJJ^H-*6x9?Dyq7(nIM_$21x^_Zs&GFQyX7wDYb949Uo!KN=(3)*GeanRW zm7l^-@xAR?U3ERoa+Q1hreM^5Mpv=gv3#Zwm(o`I<_GJMRy6MZ9Ns-yoH3A$>Jb_L|_=)34=jsazI5XP##- zbbL*eu7=w(zYKG^p7&<6T|H+mpF7ocDRWss&@yB3`_}pUg=Yo6E}D3f;lS#{_RH-z zuC`CH6*0`7_Mh2`C1TQ=lve%lldzUc54VBQuUg_7QIe8al4_M)lnSI6j0}tnbPY^& z4NXD}46F>ztPCu44UDY}40=B}9!JrTo1c=IR*74~pS3@$ff^)1HU#IVm6RtIr81P4 im+NKbWfvzW7NqLs7p2dBXCnnv#Ng@b=d#Wzp$PzJ<0sGn delta 611 zcmV-p0-XJl2Jr-t8Gi-<0047(dh`GQ0ys%TK~z{r?bW}F6G0RQ@b6nt1Ns*jD}R6> zL_tznYL`Y4IZkvzWM+ySkxLmtmus|95sO@Aizo+*aIvuzEK@2RikygrkZlYEBx1}$ zo-AA-hRx1w_B73@*aSS!Jb&+>C1nMOo0Hu_%?+4F z%?sK!z!;PkVhxxsJUu7#CNdMyYPF8JuKOhn!yC0)?U`v`#DQ$mNSto1^;ZBJQp&p~ zKy*GUl_ZD>@S2&2N~y~>fQdP<{u?I(eBZw}8jUU~rB0>+#HBGS1ry*JGd~>+1_vvZ z%I~a*9oSzzO@CK#2EcnFIxU3QN(-1Z7n5lu0-DWcE)2sy5nUHTy!h{csG-(+o0&J2 zQn%9p8jZ$2BB};Ka6f5B7#|s}^(z35l=7l2Kx=&gz!LyRgCN+S3E=zw8Z$3TDNmRH zzV9Ca@Q|6W0C)pnB?yA;q?gs0fbaWD%>2CH?;omGtAD@Z5K-I!R*C2ifF2R83L!R4 z;ON{4&|04Y@PV1nDy7~{7hPXpKkqnB6!&oek8-)(n(MkhZJJvFc7`b`cvDKbF)m!M z*Yl3!JRqVa0B?zCMF{c9w(jDvtmF002ovPDHLkV1f*`60!gQ diff --git a/share/dark_resources/axis32.png b/share/dark_resources/axis32.png index 2d4259ebac4ae0fc5f0b9e0d7b541c9ce24ea1c1..03ec180675727fd4ee364649614f651403bc25a6 100644 GIT binary patch literal 645 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1K(i~W;~w1A_XYOUgGKN%Kn6fS5!dkk%0Fm1_s6oPZ!4!kK;?HSbH-&inQ*x zIlwNhC?+Npl%c#xDQThEB8`p*{TnU@@!W`t=(IoJcF-XpI3n83B}p+%Y|+$?)*C-& zx%xcb7@*R*dvavavdA{e`*Vxm8yQ}l^T=V23Fj>j#tDl|wGn- zjNjJiAGq^=4O4Xk+m&=*n-n|Ku-)O@8`ihzZOP3}QeOK*GJjj0@w=S-&*pp7w?%CB zRgB==Ct&zq!sGUAi8*@~_->ci+);He{zKZD$6N0xENrU0x+2%itfBcXTfwGwW|_B% z4C&Pd2lD(^u83Qhx|WSuD*XQSc~)n4t2Hy|O@D7JD*Hl3qbd7av9j(z_8qr=`?|8u zy~cdUx_(9M(zCOdtztZU?i-)zRpl*9VoVpjvHJc?R5;~t^@p+@Js+$XZHie89nI4P z*V^w&{l|V`%ANa11ZtW86n5NM!uH=A7%i$Lt`Q|Ei6yC4$wjF^iowXh$UxV?MAy(H x#K6GH(9FunNY}vF%D^CdspJ{Ay^cMgC delta 281 zcmV+!0p|XN1*rm%8Gi-<0047(dh`GQ0PsmfK~z{r)tA{4gCGn=>!0V(?cm5vq}jPt z^{p0iPd13#=jLZ?`b4yk97J^aum48#ssI|$a)9RP7?D-pH)nn#@CX227c0G2BQOJC z6|_`8VhUaj(7oi5u+peTV5Z%o;${uJ764X+nFw@I=?pmw`hQ4ustck3nS8?m5Jz^o z3lQSvENS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^> z;_2(k{)B~Bl;28rlID2^21W)?7sn8b(_1HQ^gC=I(Dr|UQDT~ez!L5^4wcLftxqIFHZ^<0(XpnqFO!--xu7wA~l#DEc?ngTh=88Yy^;`Vo z%!94TUJI`*EB>`g`1Znpn}(|2HD7v6wkp)v*}tUm#23*=#~v)rGkI+J@qmR}g~OX$ ztjQ)1c*14sQac_l-=6<$E$-v-IEpd$~Nl7e8wMs5Z z1yT$~21W+D1}3_OCLsm}R)(flrWU#e##ROfdg@;mplHa=PsvQH#H}H|%0~vMfx*+& K&t;ucLK6V8*1X&R delta 182 zcmV;n07?J&1IGc78Gi-<007{3J@^0s0FFsSK~zXf?N(b3z#s_In{)Fme6TRaOEzP& z=%*;PEuy_m9({8D_5c8Y;|(YP+;Xl1kSB>)5%V;I4M38vGdVKVif@yLl`~Dw+yk$z z(Ed^t;pR-w!ga#{+2r9p@Fe1=*VgfP$%B6Zpw?2Rltf-DkS`U)0c7lxDk1=_bW4xE k#Xy@c0XXtq9|mG|0`Cr`lIy*mq5uE@07*qoM6N<$f=^yhjQ{`u diff --git a/share/dark_resources/backup_export24.png b/share/dark_resources/backup_export24.png index 5e12a21ce4699092d785d479eba06ee2d9057dd0..0dd0cbe3783b2a9b4780150dbc5b5400d620a563 100644 GIT binary patch literal 356 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1mUKs7M+SzC{oH>NS%G|}ByV>Y zhX3vTXZ8bm>?NMQuIx`(ctr(-CspmY1q#jZba4!^IDK}qBVV(Eh>JY0ci)9CcFWk4 zGW#Fz{lNC`Z^=ck`rcVmrZ0UW1k!%YXKcFBcG_*P@tv2xpO;+d*%T11RTg{CTr^L( znKNj{^xs=$(=AR5EZ;jXI#G9NvX;)la67xDB4zi!_-j`Fc^JK_?aJZn`mZ}2%=T_F zo|(ben-juTxhh!XROvk~%fm*W-SxgNzy6_u{{g4c*XD08A4G}*-KbjP8c~vxSdwa$ zT$Bo=7>o>z40H`lbPY{H3=FIc&8!S9bq$QI3=E#@dc8%_kei>9nO2Eg!?c1=fj|um Mp00i_>zopr08+SqG5`Po delta 160 zcmV;R0AK&)0{65(~ZQCuc%!`UlYrw+#JW$-6NS%G|}ByV>Y zhX3vTXZ8bm>?NMQuIx`(ctr&m6Azy&1q!Y5ba4!^IK6kWBiA7V0oQm{X+?K|_rZG_ z#a~{^+3R^Qd8v8Ef!+^yGkl$INh~=RfA-1$nLjx*U1Hy8{havVh`Cfe^ethQfYfeqs3*3v{I(1^^ zOl8fB)8~wdGG8qgvqQ&jj;zA3WLvf!>9c$eNBso>z40H`lbPY{H3=FIc&8!Rzbq$QI3=AYP gSVT}XmdKI;Vst0MB8BLI3~& delta 169 zcmV;a09OC@0=fZ^8Gi-<007{3J@^0s0D(zFK~zXf?Uhjuz#s@i_2#|#7M7Vfmkv;g z`_Nw#o^3&L3O+fwetH1_93xNwkDBWM?MpOOMY&nQ1{6!zg{+0j?sv%4x&O_9H)J-L zQ`+=v>M6kURfzv?1y%qHSDj=FpxzzR6<8NjSIF|(P=NT`LL$r-b@czW!@~e~aoVOQ XoL!9<8%Con00000NkvXXu0mjf!iPzK diff --git a/share/dark_resources/blocked16.png b/share/dark_resources/blocked16.png index 79e31c3faafd1742b7b27e9945e3c39fbe7fca0a..270a727a1abba5ca4d4ac510dbcfa8add0522866 100644 GIT binary patch literal 2935 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 delta 2176 zcmV-`2!HqY7K{;)BYy}}NklCB8AG2b+HiYC{o7Mx+60PNGm^N+0p=7RxGl+ zgp#oE2F4_k_pur;8i!YmqKslv^n77IcfV7Y}a6@(VRN{cs!p}HfK0A8kWx)7uQ|1a?d z5VD=H3P4xVNFI7aS7Y?d7YFbtcCB ziV(w^h=>T6o}QjtX=!OeRPA68&>bMl{?n&Vulf7?|Cz~TcBH4L&rlU$^kR~Z8U zLo5LB@bK_UNlB4ga?sn`+pu%z&QCB5dwBHdQSHkVUtV4wt57H!jAJeUc#Zd3d1_kf zA($|kOn=syoSgijN~LNA0K9ma;w^P06M*30VArs)u%9dmLlESMUazkK0IXQqD3!`u z*)3T>$_FW%VLBQb8UlNJd%FzJOaKA`0z^?!QB^R*j*gCosHmvp85tQru2kkx6fO4h z@~ZFd?iPA_dZxqT)YsR4ESJl(7XT11Ze3m7wSV~d_ym|CgTYAT@pyHqsj0Jc0LU7G z!5506m-u}C6*?v)Ba_KwCIE49aghRn z;A@zHN~QW>?b@|f005i{01feTWiv4`(QocMH#he;I-RZ!7O$(T>-e2Jcjn;cOX$FX z10pXkFX#(AJ3ISUUS8h)l@M>7d1L<0H z&o6};Xs5M4`G3rROa?$B^9#zx+;>h+jD-AmF$Oz~SE=PJGqA`XQo%83<&n0{QB?bUEH8eEbjERW}g&8$9HMzC5wJC^aG{n;?8$(=cQ$bl- z*${eY}su0Hjjs=_gN~6wnZF@gqgnj<;^zx_>J+Hg@hy zYyN9(ZLJRv4^KIL`ZQ{?1H^eXH#av5!?3R`1t=*g@fM54KadG93}$4l66R;imMykI zq0r(%X>wvRlk3d=%y5J?8K;Yiiq=b|(yP(Y(a)YsSd zLqqwPl#n67rAwFmYN~6>qIX4yPzh=-elcZ3r7=`psTz=ENzzdiy>C4DEjSYc0N6N= zCovd|5~=`8EgQ1T6FQViWr3HM*T-2|S^qZH1-(|ec<~~?qod;^AAcX8_sAerDxk&(ebK1qG`e92^2iM@M(bWU^49P)Pf|um*JX>ea#MsOWFKU-yb2;p!3_RYTS{@YtvELIzv&3>GeltihU z(b@rH5TZk27=N~j#bRwA85!9o|6cAhFfic$zUY1EeWrOPD=RC9d|vla_zC<5H*MPV zHyaz9o)<4(3`isrl&oaTebL$hV`E}^t*EGQ(CKt;Ha0dJ84SiRQ50P_Ha6z2QmLG# zr>7lo9nRDvdW4BEG4?BL4VTNEba!`GI5|1}Q?J(#>v?p#Cu+6&AE!>8nxQM)pk>hj z#xOT-++aR?_RQYV(a}+>)pD6k<}WY|V>6jd7J?uMj^jE6LDV>oqk6r5lEdMkt5>gn zPFy2WsdH;{N diff --git a/share/dark_resources/bold32.png b/share/dark_resources/bold32.png index 46a46d9a0ec5573d70b858b1ec75a7e4f5707465..774d0f93c04dc2b15da3bb0f080fbdfea335e5bc 100644 GIT binary patch literal 622 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKpuOE zr>`sf6Bb@k0k;3kqpvYAFqV0`IEHu}KN{lbci4faL`*|OMJVKou+zhkgPM<+ed{mC z2gEtl9}xDa7pR*czoC*rX{wfrUyF3RlX(|c%!?w<6xpP=&zQa){d8mVHw&%<^|M3U zwsRMp*d=1Yvi$P>T&{z2uh@wnJaM`}npySAuL&QumOCZP++n_3#dOBYa0UkNId24| z?yP2Enxs^8aBablu-Tr`$F{>5} zNj)e@Z@TEZUy<=Zy3;}y#(Rd_uiJ2$&Pd4Iyr5~>)|3}LO@Ddze)@2K*3#SVTkS-<~dw`{6j zZr-`q6BsF~C9V-ADTyViR>?)FK#IZ0z{o(?z(m*3B*ehL%FxWpz)aV`*vi1*?s=nC}Q!>*kacfvJsR@`!7#KWV{an^LB{Ts5(97?b delta 575 zcmV-F0>J(51kD7H8Gi-<0047(dh`GQ0u)I^K~z{r?UzrA;!qIA>%{}~=vpKs1Qk&n zPmsPr-=Lkfpxrk}?_9XZfFQV;Il}Y_+BtyOEh7Gjv0G3OgieDCSJv=gghuPd#ChUo z9%Pf$tM8Yu>QxAX3omwIeINk}g~B@kd^rK`6#!a@Xm>iDmwzDpNq~Glk3lvciTM?Y zM2hWp`@=7e1jyxbG61;lbGO_58X6#*&B_7*M6`On-h&8&bRd(-$OQ2E{eCnQKsuck z0eIZjy<{o?@JqN5(Hsm0zo`Jyfn+i%0%#3~!|VM-sZ{C~5r2vZco{~c5m^Qjz%UFU zz<4}90N}!gVShXUfJs4c0LO8H1L(Rg1ei=FB!I5#KLDU80&rb7IDn>UBmg3|rqk&G zfTn3zi1^AFBZrrwC^wGdJO=IoRaHd*&y2CV&xy9%ZJys_jENf2QxrvYU6&k4WDg_~ z32Da=0Pbe9+4oS#FdmOf0pKTNKA(RJJqaz#`e%S>2Z%N zE_4a}rZ}44GigouAK(-RME3JsXYT<&@v{OP6ZZWYo?`QT^&wCLRu}*P N002ovPDHLkV1gps05$*s diff --git a/share/dark_resources/bookmarks16.png b/share/dark_resources/bookmarks16.png index 63304362d976cadedfce2e9f31743ee3e1021f1c..71e829147a44ed34a1d4b1f212367201c2615baf 100644 GIT binary patch literal 377 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{Xiaj ziKnkC`x6#kQ2`$LqD?1&LXDm-jv*T7k507ba|qyRx33pdFA$Wz+`Xgoh^|HV5!E9q zF^4#Byfw9{tmI&8F3Y%Fw|`lt?8BRPrrZ6K6Mht&p0c5FN{D!mf(6rsz{rM^@#Q}l z16EWYSiEG}vLn0YxSXOCn53fArd@6^U9O&-rnWe~SXtz4tH!}1)z))!&fmYopf_Lb zul&q<37}(COI#yLQW8s2t&)pUffR$0fsui(fr+l6Nr-`gm7$rHp^>hEv6X?rQ!P1h e6b-rgDVb@NxHU{EU$z>kfx*+&&t;ucLK6V2;C8J5 delta 118 zcmey#)WJAGGM|lsfkFQB|3o0=@9E+gV&R{hvOvHfXvKWSqYZ6sZU2u*+_-Ro;kvst z^MqW7GQl&gEU^Yz49v_rJQtXIUpS~t5#u<dD W5WxvMPsjs}X7F_Nb6Mw<&;$UH7$@ie diff --git a/share/dark_resources/bookmarks32.png b/share/dark_resources/bookmarks32.png index 5bf9f69830a0feee9e702759ff220556d9d392ea..1394db58dd8b43e62a196fb6dfa35a46a6b2adde 100644 GIT binary patch literal 431 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKpuOE zr>`sf6Bb@ke&ZCsiP=D*?Vc`^r1?6o zqs@QBrk{6JoRpQjq(k9se9O#}d;XkJlQhd;oA&KLbAoJp?jfJ;H_c^j?i)P)@ZC9v zfm?y~!I`s+Ps+A+Pt89s;MpNixz%aK(fw$GMw8K+#K3$|@yCs%tje94y$^s{ArV6nk&%43Q2O;7W; zSoi&Q+W+udh&|8?swJ)wB`Jv|saDBFsX&Us$iT=z*T6*A&?Lmbz{=3n%G6NTz}U*b jVE6uw#V8tb^HVa@DsgK#^@#I4Py>UftDnm{r-UW|$t;ym delta 209 zcmV;?051Qp1L6UY8Gi-<0047(dh`GQ0I5ktK~z{r?U&6803is3>&<=hT{;*c{tPJ8 z!M$cVerVIqarv8<^N$wrHUT2~Dtd&7%tBoP&j|1;@Cb1MX#y>v2{eHw&;%?3(N!C* zuWKAKBTaxbDlewo3oMtEiOLC}_RK;`1!&1-qSKn!TA2XN^GYq;NbDH{HK9B-nhG=? zo&r7)y^xRz;WJ?ZX!1kse$bYWA^K8IHzArR6ZiIyNv1M%?{xw{opi_{9S<>&pIwg;$i{v{%<84k+}%)5S4F<9zKzLvN=*nWOdR zLwMEB{Db&6${ly*MQt!-OY*1ql9f}0053nqjWPCTG5@KEmJqh|_txC1keKa89I z-Zp;T|02Hc1^>R^>AtXVS=h?Rmyx0m*%x-7*|=uSmqnY*r*Ind*RV+K)-F%Bd&zK{ zWvki3Rj=-PIj{G6^Jx0bFcHbVyQ&}Fx)!mUCrM_oGJh#zd$n^;w%VU1Jj+gpFA&`R z?#kVn!jB$_z3^BcR`xNTJHp`Jb*1Jc=U%f9({n!_uz8rijx%jT<*Q@w(j!-{XI4~l z>{LHj?0s)XI_m~D_r}TlqeUh>2l`dD#5JNMC9x#cD!C{XNHG{07#ZjqnCKdsgculD t8Jb#|8tWPuTNxPWC@hFV(U6;;l9^VCTSIKE#514<22WQ%mvv4FO#tDNvk(9P delta 130 zcmV-|0Db@M1C#-f8G8l*001BJ|6u?C09#2!K~y+TwUI#z03Zki?dSXRqKFVlRtvp^ zB*W@75fK1=zL5gZ^xSGPfIWX8H2@paCe;7e1QuY|Oasyhm<^hM0knxH3lzYP_yq7w kgf)HxJe4&^EZ3+l4H*4g5g^zN=Kufz07*qoM6N<$f=x&;S^xk5 diff --git a/share/dark_resources/buffer16.png b/share/dark_resources/buffer16.png index 1e215e8513f90044e29e91bc17ca0780d31a9a17..ae5b80219591b9ebe04cfefa1cea915818c4601e 100644 GIT binary patch literal 579 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|Vb-5N14{zaj-F$X?><>&pIwg;$i{;II3Eiwq2mW}YsNAsXj>FB|PCVk8XsD*<)3!8mv6^Y- z;ufcd6Dd`(^A>&QG5=q^tlCfTlS*#v($0nRCgzA#>Q^m$+Mev0d9vL4m_o~oV`Vm7 zJ12y8f2|OHE6@_r^L9sluHROn^^3(O9h$YC&tUP(X}g$e%2K9wSx4P#>=S2u^{s|s z_coJB>l(ccmcO6+U2avw{ByeDQ~EwHUYP8BeV_eIf0N0bCcTFu&WnG)Vl1vCskQ#& zm4)*z<@Bw~47vE(;jrepJ0C9f^t(OSwrZb%^hPYo+x`Ac4c)xz@tugG;H&1<>;B~nOHJGA)AJ?Pr@x-@ z{^I)YQGP4_0RvUF#5JNMC9x#cD!C{XNHG{07#ZjqnCKdsgculD8Jb#|Sm+uUTNxNU i>iuGeq9HdwB{QuOw}#0Ve42n77(8A5T-G@yGywo8xZ?`| delta 451 zcmV;!0X+W01kwYL8Gi-<001BJ|6u?C0hvieK~y+Tb<<0zh*1;;;P1K&m|TzKSrQYE zGBILCNg>IcO$-Pv?O&%Kr~djoXYaN4 z+I#H*f1h!fhozW_A9#-Y7{kvtWuTWo2b(biPw@%?4A5LW!ha~N<~h<6pY8$1opIV!#A8u@_g*X zaeOL(WjIu22Ix92H)YH!(vbjc!0gi1#jL~{9K(ugYyiJkK=KZ!SNRG1Yg}p=l5_w! zYMi&LKW#5|;D1E`wwK0>J%BAZiQn#V}U$WD|ej^HSsRZP5* zyQ=}n2=~-j-d4b3>?>)R$Q`7@xH2bB-4%k)2Px+Z&NmDbF<6buC_4*>eRtV=v;&xi zgVnUS@P8-Co3IEcL)u!oE9(KS;bo6CyRZ>MI9>AoSUkC7jNjKIJ@`;d6V~aNgu7*` t$o+l#+t}St#lo6E8kaSGh>v}3zW{b*STD{&{;>c6002ovPDHLkV1lF6&+GsI diff --git a/share/dark_resources/buffer20.png b/share/dark_resources/buffer20.png index 27208f5ce8aa97cdfc91d3b034b058808fcb4600..0b1685c7f67fa257917e5990bc3edcfd4ad01152 100644 GIT binary patch literal 509 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc0wmQNuC@UwmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^+ z;1OBOz`%DHgc* zo2l{4FCl&Fw4d`Vu+U^ZlznsA!MmGcIqx0MVS6Xlpu_a*^sTVM@8u>A-HOp$d-G1| zG?dkd|FN5Ct>FK?BkI-7Ln)VBgZmZO@;GY#M}O{>|NnC1BDD(_`^4`hu4Re)Y0EHg zb?beX>)$GM7Turxvi9BK7t!X&UAd%;e;LmI&|iEmfB8LWpx;$XTq8Dyr(~v8;?@v#>(hCl1_n=8 KKbLh*2~7Z-Xtx0X delta 153 zcmV;K0A~OF1F8X#8Gi-<0051N9Sr~g0C7n~K~y+TV`PAWhK7d!Fg7uCLqh{2Hg#}8 zQVj$dhRsll48&$AP6M&oj?EY7>PRvW>LQe|9!3TdlXOUmlmRmk-IWxlL!_JrHjCn9 zL$QIl@;)p*lI+5vVIaOdO}|(sHepje9THvI5aU8@WhMZ$@)C3v!~&2r00000NkvXX Hu0mjfJ!m(q diff --git a/share/dark_resources/buffer24.png b/share/dark_resources/buffer24.png index 1f71ecb29bd49fdfee5a4bd8098c6970e00261d0..8b05a9497fcf549dedc7fa1b59556ea0deeb8d89 100644 GIT binary patch literal 565 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^+ z;1LNlk?$}FGak=hkpdKCFY)wsWq-oLE6T55;D1(yfq_xO)5S5w;`G)jhThDM0En z@rT)$EJ}RmH*IXU>1~$Ner9LUFvoPy#~J(iIe)M>dY6hdp5Cd${Na`Qo7EQ=PF9jB z5Gem~?t|nEw&{fjb>k&3pLcrnUuwg_yf3SCYA!rdTV(HeV20YJAN^l|!Khl|8c~vx zSdwa$T$Bo=7>o>z40H`lbPY{H3=FIcO|4AKbq$QI3=Bk$wp>Tikei>9nO2EgL+T8h QY@h}PPgg&ebxsLQ0Ej%zBLDyZ delta 174 zcmV;f08#(71it~08Gi-<007{3J@^0s0ES6KK~zXf?UvCBz#s@k*Pq`%-v~-tQz^XQ z9_pna^q_gQaT$tXpm9O2T%u%+wejuS|@22xjOirlC=T#`ffyi c7S{B80N3D<8F*{6XaE2J07*qoM6N<$g2lQ?6951J diff --git a/share/dark_resources/bug16.png b/share/dark_resources/bug16.png index 3fb1429ad516b5b5d5468c2d98836e4bebda0143..5261297fd468e2a92b5e2eeb02ceb5daf011914b 100644 GIT binary patch literal 504 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCik>lDyqr z82-2SpV<%Ov6p!Iy0SlE;T7dK6H!Th!oa|&9nO2Eg!;D*M Q89)sTp00i_>zopr09}UGEC2ui delta 172 zcmV;d08{_?1HA!|8Gi-<001BJ|6u?C0E9_IK~y+Tty5bLz#s@4H|OSCFvHZ!!zJ@m zpslUQRUB2lt*ok&wWS3g_Q4E9A{HKwK)h!Iz+q>t?ot4j%t~7Y#{jR(!|kufNM;Hs zu`-dLGCk!E< at@{J{rJjg|AIL%g0000dx@v7 zEBg}`UQvFXmu_?B0p&k=x;Tb-9A7%sKO-ho;EZUnR4lpQm(_yY- zUF*(e|85qzvTM3(`uff8f#18b-pzl|VZ2)Y>za9&`OmHCTO-wOagb4Dle%T9ciYY$ zKj{LEYmjGcstMdRGr-CiN`b3&OEEo75T1uzlvr4W#NYHw`}4A zW^JFPvH0|}mAne+KSW$reY3q6EK5rdVxOwF;%i^j98FX93A(esxyY0VN4-B>7^^)= z&olGysvYlbpS-)0FL&^~*2V6BNA}DK6cpIh^?>Qam{dw2)otxa6;-a^Bwyan%Q_k(j?PWP#^%6^` zJ6};u(TskeUZ(rJb@iW?V%OFDw^ZxxxPCp1>v-As&QxrR-W;V+tx2D+Y5%X)oVaC5 zxwK5~C+SQ#6G`o375Ccwi;Vbx8jIW)x$LU`Q2f)hxU;tp9%~X(I(OV^>hE(|7H94y zM9T3gdQMWT-<-NKKK4j<)D`XWsT%^hrFfVUo2;Jiy7k`c!n>Xo>nt4i{<`xzZ|d(Y zarF_Ve^b9}ZoefPI{#IzPWb7-(-(Z1KAI+5xSFnbP`=Me<;OXrE$sP8tCvram@vwZE#^6t(WwlI!)B);Y#GUpQ{Pi9hAs z9(uUp?8SqAe#Nt5OK!>h4QWj}_0~Shw&}c6|Elz*^?MF)sK4JPs!9ttHiA% Tq(JQ(PzQsjtDnm{r-UW|wUMnD delta 325 zcmV-L0lNOa2h{?Q8Gi-<0047(dh`GQ0USw0K~z{r$9ZU>8UYoyT1z$wY7B3>xd8Pt8uq8i3q)Z?J?_{bZoq|FjH={12zr*G70-6RH z(R^Ti-(IN2!9In=TeFxc7#Uc)5uu$AxhDH_qNRgdF=JHK|HE4dFft(WqX$-!t;W6q Xnf_%i*Jmq+00000NkvXXu0mjfYEz8j diff --git a/share/dark_resources/calculator16.png b/share/dark_resources/calculator16.png index 2ed0b8cef034a432462dc80a5ce4acb653d5aab3..3bfb06dd327838db4accf780f6922bb59fd63b43 100644 GIT binary patch literal 549 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+uenMVO6iP5s=4O z;1OBOz`%C|gc+x5^GO2**-JcqUD=FDza<0a&QYS_UtiR$$cR0-Gz0rJV}WepZ!y}d$cBJxL$n_ zd%pPIliz+q8}d#rzkjmgk^*3d~seT-U#tUt_+k{J{AVW;47;^2K3bZM&6TC3hrX{jjR<` z!pM81!IprX2e>v2tj9$bAnkUFcC2C`0O_=0?4valWSaPjmq=m(QvsO87*YZiahCu_ zv4{pd;TbgnNZwSU8aEivN+AvR{zXA5Qu5#sU06qVDA+|6PVi$7iYYwc_FD>l*vbPG zdr*#LOoxIQ3_V6mbDOw^5$vEX07vM-5{7=N@-{kghGX;xU^8H;SbJf1NsPbxoj(8u W;ZG3;Cz>+=0000NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VW5Sk`z#DMFkiW51%V#U|=luba4!^I6d{sdGC-wiDMtn zSD4;uiIZGoqITvVvojNCQRH8BjwsExG+%l*4;j+{~>F5@Y zcehjmyR&^;q8=V{h;6wyTaNvC?A*hZ`=3|F&-*;@(6VETD$}pNoi?p@(?2cm|GM1P zT>X2utkj&auW_~9yReLd#qXI9G%WPlZCM`h;nrdXgJlzPom8*%wl&sx?*FoarHJom zo*~PcT^rADomj5;V8g2OeLLUu)zt)i^IGNpXxZ=T>I`%3kIZ}9c&%G!9a;0OfPep7 z(}mKek39)Fxb*Qx66%(cAs%IhYjYjY1S8?q zi=t!F*9))DvHb3|?0KU{);%pHZZVf9^55d*gL1X(5^o9bIk2e9{`TXO|CO!Yt}d9e zN$_lg-gfEVEPN8tC-}o-CmJc50pmoq#5JNMC9x#cD!C{XNHG{07#ZjqnCKdsgculD z8Jbxc80s1rTNxNgWUz>!Xvob^$xN%nts&EN&kCRhNstY}`DrEPiAAXl<>lpinR(g8 c$%zH2dih1^v)|cB0TnTLy85}Sb4q9e05=T;=l}o! delta 484 zcmV7# zpXa{r=f1A{dIpSg4D`uA9h)((BldTk#fPEi`T-opZT!NRMt_i>wQn^J3| zBvSPt9^eJ$Vt)%Zw#qad{J=zf#MeqZv(|UDPQYY*K{(je0HL1yc z4G(b~lMt)OP;PGlh@S*tO&uB)4zAR7v&LgqR<%)2BDdU&d3c7-B!`0-*c80Rqxz0N zCGHkCk!IxlPXL+90KCE-gy6I-aTD)HBGaoiSdnW8UR_nPyk7uIv3n!{L+$!9*8gSD zdjC4N=yX*Wok#P>u&{t~i6nkf1~;STB!jo3MW%T&Z&i=G_+5aSp3G@A_M`Ubcd2^V ay}tp64ucsxva=xo0000p!wd zSwU-NIb}Ni_x>gAU}n^jv_W)P|AVOY)y)FU`5zX$J`e8C7c858a1Bdpzm$ zR>bW;v!GE&dC6((j|R@?KHcD%#JzrD#X+qq*R%X*?T(>E zOh3N|zdhczEf44()e_f;l9a@fRIB8oR3OD*WME{VYha>lXcA&zU}b1(Wn!*tU~FYz jAabfKZ{7#UX};24CZlV^!rt%`Ky9wW(P1+N8KBnTzESgc z066U{2?aoF{ZLAsu_TrfVvL+pdIx@d;>tA;vIqUA00000NkvXXu0mjfP#t6{ diff --git a/share/dark_resources/calibrate_32.png b/share/dark_resources/calibrate_32.png index 182e8a9966990f792c3b38103f6d55c5527eaf42..d90df948488aa7e39482aad4e1d9ae0528192c5d 100644 GIT binary patch literal 459 zcmeAS@N?(olHy`uVBq!ia0vp^azL!W!2%@Ldop|hQY`6?zK#qG8~eHcB(j1elRbib z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{Xiaj ziKnkC`x6#kQ33Xj1=$Wjq062wjv*GO_fByXJEXwl!d?<-Zrj}cAxZA=T=&mvo5aNT z*lBpGZTUJg^mfUQ$pRdbWlMN`4xV$D>2Q9OaMREC&?dRs%>QN?)m&?0+jdOo`mq15 z-j+lDDFWwmQq@$pU7wnFXO-Ye<+^is_82CXZoctQ;mPmA*>k+|+FLfVx4WdfzdnBI z)}6Q0A7thP7N7Q=d0qD2IgU*~o|<0C588Tbd*Foh6Y|q8>|1x@)+-(DtZn6?X;K@@ zzoeF=)J5wpKeJ`;>@zzV3M>V0$35v+{03z1z4}}~JI5{Xr0E<`yIsL%ia delta 350 zcmV-k0ipiO1MUKl8Gi-<000F*$bSF;0X0cPK~z{r<(4}Vf-n$=tih>V`VKLPs`$LZy! zoRw+}>Vx3G#b6H!gINWf0!TWXtavkUI6~q4uAb@`3@wdSYJVJb?qhL$b(}EO9Hl;B za&yIs=Xu_jWoaZc>}*(IsF5V2BnDSib#9vGgmpUQT9FlRHpd>Ulq%Y`eG6DJ%Ou4V z$J|=8z{4;U<2XKS94H(kN^oKAvtZ0&4CcN{RPM%7I#lw{cHmUBxew;nMELd`RC>;)hm#C$tI|-JmrNDm=yi~1IZLQsP wU3Y_gp^85NhIYF6>BC)*(=;9Hy1vAAcP~uqAIS{W(*OVf07*qoM6N<$g2gGEkpKVy diff --git a/share/dark_resources/cancel_edit16.png b/share/dark_resources/cancel_edit16.png index 6e20773ff6eb7dab382f90425b95a74f23d2697a..5185e04a0903d7824beea794ba23ae2ddd3908e0 100644 GIT binary patch literal 520 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|T=z2s1ie{+A9EWH0gbb!C6T!Yj(J$L{fW6Hw@yr;B5V#`)v~1qKPlE0;Uh z|E>R@nvjt2AVKu6R^EXh!oGLkigE>9d;Wj^f18Nz35kc2v^H^Y z*J{cSE_}eq37iM$tusZQL@$m4xmvE6ZmCTi_|9c={!;k;-{yXu=@JRp5|KBf= z=BS~OX!EuH{{QVfX+Wj_H~f5L)hxT%s96$dioSAKev!eJ|LH(y>^Q4%q#^X+r2p4| z%EWqB@mSn>z-M}A(#Ie5Yw{kXw%n*?J<1y(yrXVS?Z3zRPBYr4W^*zZGB7lGn(Kb# z`U47N)e_f;l9a@fRIB8oR3OD*WME{VYha>lXcA&zU}b1(Wn!jlU~FYzuxV3&GKz-W z{FKbJO57R_zc;@R)F276Aviy+q&%@Gm7%=6TrV>(yEr+qAXP8FD1G)j8!4b722WQ% Jmvv4FO#t^5utop? delta 438 zcmV;n0ZIOd1jPf88Gi-<001BJ|6u?C0gOpRK~y+TrISBs!ax+pKZk${Iw*mVNkO5z zi>p%?p+XRG?;`0|Cnw1)lnzB4DiJz#tsoA@!NEZXbqKhLiV{%?9V{M5uv|cirI^q@ zI1b+3{qB4JT==KCtnYcAe`Z5JHp_#1^3II_mX048y>5I)yCDuZzXv{wl!l_nYT|K)~DyA=qxW<`M+qWipvO zTm^`t2u;(>*nhoVFH)%#mdhn-wHngtv^`+I-y@Mofa5p>gF*CqJv5t5_yRaG$_j}eVVohh)kvbF1MbHMYw%r9}=t=sKB50e$J+wGY3di}Oq gtsZ~vgTGAnH`&$a5w_x&$N&HU07*qoM6N<$f=?>ZTmS$7 diff --git a/share/dark_resources/cancel_edit32.png b/share/dark_resources/cancel_edit32.png index 64a2a7eb338dbaf37d278a1da50e355b64e3d5e3..99cc1e08b89307be6615a3e90dfa6735d575c222 100644 GIT binary patch literal 625 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr16wo*Gj6g|ZU+jomw5WRvOi(r6%}9+TxkU~j?v!J#WBR=_|Yl*{SF%l9J9Zz z(8wZmD#S3=aY^v$GaUTQ5|xr+a*UmlA6Xni+g52wa|`o?H?kNW7Z9?pe`B#ED8J)L z_x}0k@84v*CVNP(V9vda(AmmMZ`cTzD>kH9uJ)gqz_aIl&k^rz%Q*tV;hV*MeD25h z@A>M_VE9o`<7&7q!_DdEs~H%QyngO@R*)U(>XOv;)b#!I&C-dF7Oi{nT@5Vl4IGrZNSh~Epd$~Nl7e8wMs5Z1yT$~21W+D1}3_OCLsm}R)%I)K(>Lg zm4Sg*fc9n-4Y~O#nQ4`{HCXdb<_Bt!1lbUrpH@mmtT}V T`<;yxP!WTttDnm{r-UW|4kF<% delta 683 zcmV;c0#yC+1h@r|8Gi-<0047(dh`GQ0)I(FK~z{r#g{Q`X;B=;KP63?Cginmut*xx zXE4;JqjnLK$t<;5upn_o?_j{tq(c*8sKjJLJCGO*m59XF#DbJTnBHU%TrdBdkmm-E zzN5W~NY1^^_d8#{@7zO%Z@y&TtdETVJkQS~k;uDTE|>2Bd4D7bf{f$1Up&w6wWzHC zB;0H^p;oK6GBg?u)M_<)=65I*`mqnhKLIQj3$CxPw*ovoJRlN@;Pmu#Ivft)IgT^# z3c&>6@$nJia2SO4Qz(CKbAk!L^Yb%$y&k&VE~vHi zAvdzwtPltUjt&k`EEW-sMlqYsAPB2z+*0uu)|bu^t$i>@5pfiDAid3mAD z2Di7jYc)SUK9I}h;PraN`%E1u6bi80?NBHbAP^}8iGQ2TX58J~VLqRe?Q8*P;){z5 zab@v%d2Y+!uDo&lJP#O$|we4W)z`CkY;8ZHr+IG-B!4$x1wJwil(!fcBnM@|doG{%7 z27>`^Zf2#mb$J^T*G#btS9Y{Wk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr16wo*Gj6g|ZU+jomw5WRvOi(r6&2w6CMf=wfq_xo)5S5w8MJUAwno>ypi%s!#6y zHu2tvsquNs%(rYla>Y7e**vBF7MIpNt*Kk_?_9+H08-nxGO3D+9QW?t2%k?tzvWt@w3sUv+i_&MmvylQSV(@hJb6Mw<&;$U~+TQE{ delta 254 zcmV>|FyT3Mj3kwj#CQErI`3J({e9;j^Ni`zq)ZQ=Bl%87%FdfCXEvT(-Px`%-*fwfFwNPwe$+Lc zs?;lMpWE-}yXV|H6U%2OYqV~BIxir-v;6VvWt=S$Q)lZZ*B-uH&&w6E_v3~QiAl_8O}c1`L>Jed}EaL(!v=Yyid9Ir|>^W zd;9l)3)fQb@0YFLWu8tIi)-5lA@u6Dc8c~vxSdwa$T$Bo=7>o>z40H`lbPY{H3=FIc z&8!T}bPbHH3=Hm`x0;2bAvZrIGp!Q0hBcF#fQg1d5@bVgep*R+Vo@qXd3m{BW?pu2 ba$-TMUVc&f>~}U&Kt&9mu6{1-oD!M4RK^XH9? zjWR_=Man2HSh8eE#B;cp$B!*-ZEdYgOiT_@ zQBfTzE@*FWUw_-)-rguGDjK|e`Eof|SJ#Mwf&$Kq7cVjd1Ozbj_4P4yc6PoD3k$1| zl$6wc`t<3->gwv|s;VkKm=`WIH8mX&5)#r{y?V7wQc{v8KR-WXTwEN(qD6}s?CtFt zf`fyg($*N=iy}!7k|N=vXmv;=~$mZte&sCZ;EhjEo20zkfe} z%9JT*S!-BW?v|C61u-)-r~du>*N};c$>RO{_p=KN3p=Z-s)A4w(!qlV7c($0+_$&4 zuiLk8-)$!+Csj~7fU)=N*;ByI&hBVyYwM4ZkjPEWlxHS#ZHDOs0Q~X~6#rJ1o&W#< M07*qoM6N<$f>TgAxc~qF diff --git a/share/dark_resources/clear_plot32.png b/share/dark_resources/clear_plot32.png index 10274a2f0599c4426ccd5b970218b800181f57a9..9c2054ce367b0d87eaa6ac887dcd97079b341218 100644 GIT binary patch delta 1037 zcmbQwJ)L8MWIYQ51H;YYP4z&ECEd~2k%3`jKlh(RRv=#?*(1o8fuTx`fuW&=f#DZW zsNn?zL#Y7+!>a@a2CEqi4B`cIb_Lo1C76=D-CY>|xA&jf59DzcctjR6FtGW7Fyple zVY`8X>?NMQuIx`(ctr&`B;?C3GB7Z6dDgo)hIkx*JJmZQBwXTneR`VJN5fg-#+{+b zLNzRlmU(s`vFqU4H_P?7)}xrCDT47A8kQ<76yb^8sWB@`w^L(Rzy-TU$9kKhvNKsP zE?Xq2>L#Rl_Nd0>C(^3MGk3;|U%#Z*7xrk~mpNzu*Ub5U+;act=W&bo-1@L*(f|Dy z4zT~wte0KBd$yo_fK-3qd3lY6$G?Y|6>uy3J1oDq_%%b``&k>+LMKmV>4<;#dd_BE zgg?6u-c4Mxx}|?>;el*K6&qL`riHX-u*l=rq|&rw?0ZY@7Hj( z`e52WpL^r(M-gxGn0n@~oVaeWc(8Z<60;Tjy@?Z;UT&6+zyF+l@zHrUK1(FT{BDKJ z`>oXR{L0z+FVwZPs-o?$oe}7DinO^^fBVzhpYJS|@XzKu&)D$&)%`WI#g(VK{93m? z<9BAUh{N@*d3QH5i9KnVzW1Jl#zOVrDS;x{%^81L&W83UeT_Jq_cdNoZ&r|GNoXoZ zg9P6e-T@z delta 1432 zcmV;J1!ww~2%ig(8Gi-<0047(dh`GQ1!hS^K~z{r?N?z;Q&$u|_qBtSj0sw?CT2@U z*`Nx}7!x*r5S<$k$jC_1(&t(_7Ma9Jsm02VhHgnslY;P&7z2bY(iSS&1fnyNxY)2M zfdEF_H0#!YH6s+IHOxR?@!jP%eMAgVa3t_!@7KHEJNMl0eShaW_uYqJjW4vu>%;#9 z)`tQnlL@bd7fdD-3M;T~2{bk~1~+cpIIdJG-{lqR=;*kpP$)jDudmP4YPBvNXBcK) zEEfMx({vh-Ih{_I$K%PYs;XL2;3X9xARm47=uwYAAQ)g6M!{oRtyVibJ6o5Yo-Wd8 zG;`0y`Y4LJ*niN_P|9N!6&03XFsM6w_G}c7J*)Oh2{;^%TNvZ(G)-&y1a`Y!5eNj@ z^?H4Q!C?52$E8x~I6~-qnx;)WX0zF}2q6ni)2}a!fYa&hS11&&q@<((nSe1q1^^y} z&?PeV`Fx_*)>d^vLBZQ(Tvu1eRa8_^{uX$G0p&hY=n@J#EguL zBy@FkrPDP1LBxBDO=z`RIh{@yNKQ@;MHp`a02TmdJRXm*wzf8&qA2S0>C=#vm8F(Q zB=(t^nYiKM;fDr;0djJ3U~q8oiBhTjCo(?%nW+U}oaS2{T;MA#8 z+{nmCr%Wa*B8x^!MC323uCBIG6h%q`+qP|c>UO)`EX$^>8Uc+)vsbNFr!_S-i2&d= zgwPDen8=uLHvO$edS5kdz@zTx5F&E4JI`)HaDxAl^3I6prRDJdxnwG0FTFf}y=yLRn@{QUed zfqzGj9=$1-%O7WEWg9{zaqF6d8@i4Mw98`Fy?uSy@@m{QP`yxm?iG(~}Sz z8#~2ky?5_kXGceeoaC}tEIScG)hx?O$bWOc-%nXAmdvuUvT&;|dm~b*R4IG*?D?pz zt!-ycPR^Y}hYrE$=qNZGj>4#@sGku+)1(ss;7LP6L&)#3^M02NM$$ z(Ae1ciBKrKMvMpmlK>#TfB(KuCX+p_tgIBgQX96lwS84wTzp+Bl?EgA{0U>+Pk&L= zw;GM6_2kKudj|#v;PU0mn-M|}F~+2XWSiYEI5;?=R4Ta#4<1bD_4<#uZ{I%4aoiUG zV4x`KJ(BPC?b|Unn{97NNlD|fO~}_a6bgaeZikGF3}QOizkffZrKN$_>m@rJ$Ye5T zZ*M1^0$a9hS!6zb@KO_Yc6Qbm7Jn9AOH51*Z>0i(pao-mi{rR3V{-NN^%V~d4XN+m zz3V@5;zYdJYz~SvSQk+IAP5d_!rz~^ASJ8d@J7o0000x;TbtoZowXp}$k1$kC7I zt1VVfJs|HmC4u2T6SK%a#$Ero!)DErZT-mRW+v3=&~&P8V%inUXKnV(cK0gyS3h62 zx%R#7cNa#vDR19|UfnQJljD$q#TlI*XVuS!GTRp5}*N&|Vst#kg*E7W^ zde4N*_6$GOUt1}O#_awa$YK@uCZ}-yb2V1IIlq}EPF+{NabK3$#}_}hSD!s5Tyd8< z(4tSmBWBj(&TB8liaVdI7vtW(&oppzi+p^e+2l~`-LHZEP%UwdC`m~yNwrEYN(E93 zMg~R(x&|h?h9)5f23CfqR;I?f2F6wf20980qEIyC=BH$)RpQnVTPyJls6i5BLvVgt pNqJ&XDnogBxn5>oc5!lIL8@MUQTpt6Hc~)E44$rjF6*2UngFRis4xHk delta 273 zcmV+s0q*|p1EB(t8Gi-<001BJ|6u?C0O(0XK~y+T?bE$3g+UO2;pcD-5`~MPBch=9 z7a=;8#04n007{*UKtxTVlh8@jbP7F%NQlhIZcIKKIj1+(?(F2v%90)8jRH1%#@E0J?s(}HG7znV36?~MiivUn015yANkvXXu0mjf96WdV diff --git a/share/dark_resources/close_edit_file32.png b/share/dark_resources/close_edit_file32.png index 1b3f477798e672cf87db71044ebffa01d79411da..a137a6628b7a549b31bda708c349e20d03bd07b3 100644 GIT binary patch literal 690 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`KiRit_8ub6ms0z`)qx>EamTas2Jn{rW6{0>|yU zT~w6AR|a^9NKNc`;}%dALb&z(ydNKoLT=5P3mCkY;jW*PVJ(rnzvNM5?5Ba}GmL%3Kv! zmE_WUrOko1CZVxDrxuu9@MriDWw1)sd_l9wNnK~1?)31dy<6vdd7N}0l_#5MWs@s+9!jE+A_HEf$j{xbh#+|T6kdusK`OLFUeGs;^$T^8!F zey>vSbIu0#nGZH?721@t#M>-2*yiIBoz#yETibiKuw}5vJ-*Ap%&LKc z6D8z#u%$Ito8>56%)AqQt~7eL^snChkc)ojQ} z<8dR8X}?a)(PavLl3nwD${mJ^l>3#Q^9ubI_0F9*SH)qI-;BQNQT1Q0-#=t*AilrR z!*W+v+Xw%}(blEcYb@OMU2N5O#{IoQJ7Q7#qD8>yQ7v(eC`m~yNwrEYN(E93Mg~R( zx&|h?h9)5f23CfqRwkyp2F6wf2F+1Z|DkBe%}>cptHiD06T7YxP=h4MhT#0PlJdl& mREF~Ma=pyF?Be9af>gcyqV(DCY@~pS7(8A5T-G@yGywodiv2oqC z09pVd5NUuzxq5OQ1F(*A0hEC7Bg3cOQ@c+ l4Ez%SjT!5AoZf;gzy=&q956+C7heDX002ovPDHLkV1jALVT}L) diff --git a/share/dark_resources/cnc16.png b/share/dark_resources/cnc16.png index 3e4f15832143d9755d8b430cac2bc2d0695488a6..66704cbd6f1a99fc8847682c9d51dc32d1ff8cda 100644 GIT binary patch literal 538 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|T=z2s1ie{+A9EWH0gbb!C6T!YeAkBVV-X1W@ROr;B5V#`&caZM~feMUK_i zzi-{snV~mL{Gg_QOHW32a92TI26vQ8K~DyM4D*2rC!ct!^f4Soz&$V-@leb(wX<~LhNiX4+(w43&BkRpwKkGGi zgnvIEp!es@Ea`uX7nw&gW^FcaVMy_qcIVmGPsRfCAGNkKK2fZ#{-b)k;v=61%bGX6 z*LNz{YH)q~I9dIb_|1LnWu^h<*I5*NUk7ii<6Noj+MmXIV&17GA{BODUcR|wlJs7u zS154rlaDNpdupy{pHANL!T2Xz(6qpP>mJ%W1O2R8;u=wsl30>zm0Xkxq!^40j0|)Q zOmq!RLJSP749%j&2Z$%k@pG;3So?ljC=4J z@c;jRX+}oIryxcD|Nj@7K7IOQFE1~yGiT0h@$~de=jP^q_J9BXe-1`Q#vd?);4XOb zKY`}gmkEMB~r>(r@Jg0;1^3)I!s6F+?TuGT{FG`;Gtq|Mw6P5ozb;<=xE4$oQ8wnHhk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr16wo*Gj6g|ZU+jomw5WRvOi(r73DYVa`@oRz`!`m)5S5w+8dQ<IaH~i%PWt@4yd$fYZWH|) zWTU@$o1`_{?7N4S-wHL@ZpLAEE$v`??ylpfMKptsy#5v~@$p86G}~QcJ?mX>8Mj77 z#J!!i@%en-UkO#Wi}vmJGVGbNn=jwh@ZGarZ~h1vX@=dKc~G<9*t@e&CR_5DZ1xUW z645Dg|K62o_2d$rSDKUM&o5;=7Z@_PdRNpLh1#RS1rzOLW$tL$PxS5;Iedrt_=~zY zp2GNpH~90udl{}eb)@QNh@$_*MZcK7RAjum_B*b`bN=iiIn&DCIh%EVI=J3V3e0)3 zwm#j!dAWUf<@B^*Lxto`4!d&pG%6=_en~wXeWFNnp6jofrz1CfFBcA7Zku6u z_VtVf_xoSY=>IvR|E5}YhhNC_m|*SQon4dPS+sEP_;kIpzV-L9ZJUC6a(chXAJKmk zx%m1ipXp4%h*K?bjVMV;EJ?LWE=mPb3`Pb<2D%0&x`rkp1_oA!rdB4Fx(3Ep1_my_ z{&%5h$jwj5OsmAL!F0L18Bl{H$cEtjw370~qEv?R@^Zb*yzJuS#DY}4{G#;P?`))i PiWody{an^LB{Ts5BAXb= delta 956 zcmV;t14I1G1;+=F8Gi-<0047(dh`GQ1CB{VK~z{r?Nnb#WMv#Z$9u1?1}hWk;;zjU z=u;FX*}u()9*l5&bJ8~L60XJ&^kU26K+4pHw3#Gr zVL1`Zm`h~1v*W$@7oUt`)3lCTtOU->Fn7*(&iT&${SI-=AAcURK28k$e-a1=gL2e) z2?m3QUhq)Bp6H2zlLSr@IQ9hcJD`xEV)j0tr|2Fi#=y|f(8B;;2k;8XZ;L6e|I~or z@4rw{QQ-y9Me_Z7YG8JDc0G|uoGULc&yYMz^7ngUARG>(r>6&lgM(6CU9A!gkQ^;W zTw(6|6&Qwby??8#>#>1>0k~W)Se7N4ro92+Lz373wE+=n0`LOKSM$k4q-vi%zt}UeZ$L!O zTb4B!kH^c}+S;^0Ab`5MI&^k+E*OUKT#oPo0B-?!Clm@@_IkZFRaI5UWHN|Gqc?kd zd+YbabNEZ~c)VkNeqK{4#bPn5xw+ZYG_8Z=$A9}8I(n7ae%?+@* zxvAp4t!9Cwl_PynL_Q{z-ewD*s1MoyF7Tfmud==f@ z-GBS9^q>I|p=DXO`uh6HR##V*LEG(iE4_@SX&(Uall(1z26O<=1Mrxp>Ctul{v5lP zX9>bia**AsvIZ3YVLdI^AL z)dc{eByWg_2f$?jFO!TG+Uo=Bdd9Zxt2HGhC8`hJBe`634;(`L5Xm3!ggMH8cU{Ft e5xEog#K50DtfMd(`3#Hz0000z@OS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>lBSEK+1*-JcqUD=${?`6JNT`eRSHJuJ;kldA?^ChP&P|W!%0KnnRkZ!Mc9_!M z?~iBZ)a_huX+Py-u3@ufl=1c}lNe05&);^>`j!G?4|}HTx)`~HZ{-C}OF!^`C1 z_ll4Cf##Q8mcOvvz;GwI?MKYqlYOlMS}zVP+1MaAbBk`vHlJC%ITx4QG+u7Adfx-P zjWN$ZGd6gh@&E8?Q}7zo$zHpp^Ul0HP`65V0pseZP-gMDyK3Y&xL7`ji!YG3viSeE_kY@O1TaS?83{1OO(<50d}@ delta 220 zcmV<203-jT1?>Tl8Gi-<005~iUHC@oe*#Hsuw_%6~Eg(wd2c_-2OGk#KRg4#TqoqJxzzgtOATMh9%sM;G zNDeVCk0zP|X`5mNM13*Nn;ES@xZrjFSY-qYgJefVeH%fz9#yUSqh%8UMamEA+SkR~1wxZt3)WVXZl+%<%j* W=IRFy9&Bs?0000k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1K(i~W;~w1A_XYOUgGKN%Kn6fS5$!M$Eo?}fkG2KT^vI^j=!B`%h#YF(%fB` zQoHV;;*EdV_{`kOddMrXHBIEM+M#W20RDb3qAquMmbSD{=Wi3! zI^H8+s}>$Ie4kOk^6dNrPqwPn{02LUT2yVK7rQV!1eCUlCG5zW=jyPzI_%1{3tN|b z-ktIN3xmAi_T$VB3%hSy8U?5_%(~IKw!v5Rf3w_*-z_gAmS-~o9j9928c~vxSdwa$ zT$Bo=7>o>z40H`lbPY{H3=FIc&8!TJbPbHH3=A|ImdKI;Vst08&+mmjD0& delta 197 zcmV;$06PDk1J(hM8Gi-<0047(dh`GQ0G&xhK~z{r?UqpvfFKM*;pV%!h7Syqkd{K2 zCgWFJA6=*9VS0b0VHj#P)C0|C%GpoVi)XSxOM0K0r>%yNA3!v^B0zNPW(P_~r_8QW)d;~Eo zUSK4E@?sC6h%W)O5UThx0FxQCM{WTs%s#&X8eF^~>v{4f00000NkvXXu0mjf+t^U` diff --git a/share/dark_resources/convert24.png b/share/dark_resources/convert24.png index ccfb3255d2d9a924fe0faaa278c02167f582403d..ba5b33275bf5af3f460d27efb67a7676c52a9757 100644 GIT binary patch literal 565 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM3?#3wJbMaAv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkphS3pPl)UP|NsB|`%OIh z3Pb4s@9)zU7uejF%XnbsJtqnJY|NfsJAhXHhlIj=VtE!o8FU(HJluQ(to8=UF)wg<< z(ZO<^JNyf@TAMv&)P<%R+?IaEZ+z8s2agy30r8*FduA<;eN`Hq$7g-|@yp8sCcPhf z&f2fci%c{iy2BH`0OtzJlF+vg=&dwL`h0wNvc(HQ7VvPFfuSQ z&^0j8H8cq^Ft9Q-vobQ#H88d^FyJWFIftSlH$NpatrE9}N{uN+Kn;>08-nxGO3D+9 mQW?t2%k?tzvWt@w3sUv+i_&MmvylQSV(@hJb6Mw<&;$Tpn(WO0 delta 177 zcmV;i08an41i}H38Gi-<007{3J@^0s0EtONK~zXf?Uhjuz#s@i<>uUc3nUm43Cc$Q z^xOC-rAPyO2>kwN0Wk9;g);NmA^G_QUfDGHs!PXwU2X4LUr{T}(m?~y6mLz}4K?&f;7NTJ5 fTJb{5vdfq+<5x@(!3{3H00000NkvXXu0mjf0J2Rg diff --git a/share/dark_resources/copperfill16.png b/share/dark_resources/copperfill16.png index 15fec13ea31042dd22dc04156a7d7b4fe6e821db..83cddef8e37ed8489164b01cc7ba57af07ab9b3d 100644 GIT binary patch literal 602 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+uenMVO6iP5s=4O z;1OBOz`%C|gc+x5^GO2**-JcqUD=z)2>Uu7Su{FrBw>dD}pX%BqgRn6C*vEjC%zReaj2c{i2 zdjk7ESz34V7B9;cSSgUuZ!A`!;M4W`(F@IIGj-Q`RK8ht2_TYS93yiZL1h!2}m|Jx1sSO00hohMvKfRpZQSRV_YZ##d1U-8jZ{mhQN?{?>33Fc(f-?Q<{^F@2FOg$vPpnYaTMBC#doF7l9w+cP% z=B(PG;?`oSCaHKx_i##GUE_^s%hcCJ=$2JJ*mZSj@c-od#%K2@9&*y^0S2RLiEBhj zN@7W>RdP`(kYX@0Ff!0JFwr$M2{ACRGBmX^vCuUzwlXky)ceH_MMG|WN@iLmZVi(! z_%s1ENP=t#&QB{TPb^AhC@(M9%goCzPEIUH)ypqRpZ(583aE&|)78&qol`;+0H=%L A0{{R3 delta 170 zcmV;b09F6m1iJx{8Gi-<001BJ|6u?C0D?(GK~y+TrBgu;z#s^lKj-ILn8RQxOru9A zr3Gx);cHpFh}@VHk$|59tcW%6M1vqJ_F#{(_!fbxF_Mx%lL+)yeC}1iq+vXpMIb1) z66~tdWr9!9gbxHZ7_?MvC@}6G7WI`3j9wk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`KiRit?NG>YBs>HNEt7aSZV|espSV$COZs-60l4jNr7(%skAicQoo`~QB&W~;sX_0s0toLL#a_rs#^clJE5pZC0c-@MN@k|l-l zw_Sg&{>${(@~h^HC3Tl>if~_wdQdj+^BTir|3AppdX}xdl+^aKqv^kCo2OhF^WmCD zlajw}dh(~itjxk_-c#x0ZO$p#$)_vsrp`}Lke%=}`7q1umk+s9zRl#o z=eFw^%V!%Ne`9>->ZXIDe_jav^=wF;mpn)3Zq3UX%Og@H{4BPe{&`h>=PJ<+cQ?#C zpm^M-^Tbb)-@@;gpa0ymjj3#>3;*N3n{lCTF-r40Ze;FQEV<#htD1~{#J8_{pA(f9 z98b%Cx?isI@~f_2hc}d6pQ8Nm?u(5D+1_uC&f+q@xOZW2anQ0~Gn)9^ULR(!+Hmko zP_6va!+~c_gciNt62tZSORVjb?-psNmPYN^RxDh3MC$w}>2UMhh25NopZ${5DV@3f z8)_xaqLy~-CSDkrJhOZ-17c$m9q=NY9V3%X_UclF;s z$Efvlf%BzIPu8{E&JT-Ay?;fjPr0f(>DZxZFN}Iun*X(2Z)$VzgVOTehjV8cy-*5{ zxw)&!%l!HNpKB63yCojw8F5c>JpWNt$yxknT0_O@&tI0QP4}w4xuHv%x8G!b z`@(Pi^%%L2CMQlVy0~N8)`;A$Z>=*wv@GHKD>(0BVyTzbwZ{wYg#{Vxi9c`Ap{o~| zz#49mRvub?vB0+|>isj`>9I*u+IO@v#(jErERK(!v>gTe~ HDWM4fh`!Ss delta 328 zcmV-O0k{5}2-pIU8Gi-<0047(dh`GQ0Ut?3K~z{r&6iOQ!!QU#+naOqO`V#F5x|CQ z%KDv#hXI$K$L8nU9RFAX5Rr#XKtxJ+mJVORyr7W(14gApARz!7*aoPU#RcdF z*DBaMA|-wX;Ps0KF#)jI-vP=!WFblb*UK6ZHP|Rg_6`l8gMWP!f&$1oeN_br5Cy38 zN@i3a0PN^g91$5*3Sc|k)_w(eDEkKJNNT47ji%SUE`WD&CMByx34pEhkdlEY17zOr z$&DbE09bEFjjG)7RsL`aSc3^>eA<+v&FQ}Ytjt{%n30}*!25Ecx$erZ@1+(JRtYBa zvt*aS85kJVJY5_^G|uNvH1s~~Akj8| zS$b!I$%`e;o1N4Idzus?91nV4x#(D;9mFoUt5n#fMD!1{-m3@l1(y~+c(9D4Ng+(e zYtQR|oKKb+vt4SYHBW!O18>xTa zG>L=jgT;~S=^`sHA3Qv1aeGojZH-w(k{E;HaV5sT4IdsABwVjdX%rG<5-E7A7JTFg z&&^qzvUmAS6pEiC{4nU?)$=h0JS=ClTeP-ov~WzIpK1b1zo1c=IR*74~yX~#f yKn;>08-nxGO3D+9QW?t2%k?tzvWt@w3sUv+i_&MmvylQSV(@hJb6Mw<&;$T-&D}Nt delta 153 zcmV;K0A~N#1gZg$8Gi-<001BJ|6u?C0C7n~K~y+T&680Mz#s@i=goWbEgCUE3jJ7? z%rC|CK?TR<7J%EI^B%y+u@g|@DJ%h%cnbU-1$3D+fY}Qfm}h0J1XS70hJg>j3%b%< zfLT!QvOBU`9xC`Jfc2hQs7CmE0L!e#H&{@B?su*>z6Ct%!V-9d#l*DS00000NkvXX Hu0mjf7k)xd diff --git a/share/dark_resources/copy16.png b/share/dark_resources/copy16.png index fec837b78d52569f14be4970bbf12be95a13e61a..86743c9a5246ad38d2172f610ce1e36e71aa7448 100644 GIT binary patch literal 526 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|T=z2s1ie{+A9EWH0gbb!C6T!YeAkAa>;6W1!F-PZ!4!jq}L~3xrmrA5uNc zw6N~f)HR8o?=61EPdF&&`AzJxshEZP*Ykas=6)B~`eyv5rE7)poRk#_i3te_8h*bg z|DQj*adzP6IkO(Q9^>iw^Ph!{myJ!0t!)xV+mrvSJ^qqXJA9hYClxpA2A`j={Dw{T zy`+TH2Fpnw1r9&|_nzne#@|g78yg!R?ze7MWCnu6m2Lez#gbyqPkSWa8HG8BoJn|) zVsSp<#D}>H8x@&6e`g+BEb#r@5BY-!KG;9{&*P(=pt$1G{U%4&a*w!#4+#c9huv^o zyTX}`VM(FoH|N6F?}7eQEpd$~Nl7e8wMs5Z1yT$~21W+D1}3_OCLsm}R)%I)20*Sc zklZKFzW_x;ZhlH;S|x4`=bg6805wR0YzWRzD=AMbN@XZ7FW1Y=%Pvk%EJ)SMFG`>N S&PEETh{4m<&t;ucLK6UT*1Ass delta 272 zcmV+r0q_2f1fT+t8Gi-<001BJ|6u?C0Ov_WK~y+TtjkIiB}^_rLczgq9z+tcL(eZ zo1g{2w(Xt}VwWVzSW0;zBCf)S2z5XR0C#3S`o6z4P4iTS6n_BE^G3`(LBzf)NYgY7 zf?#79#zJk(BcEg$;JWS*5vKq!W9Bs?uA(TK1HeNS{sJtS`7DIk$8p@1QeNMMuO8F_ zj^hjf;AUCYp)6|U74oMw8DXJ`btBWkT0kx4yIhwj8;>r*ck^`E|A4xvW&c~h#wRNI WdJ*nCsQv%|00{s|MNUMnLSTZoHFy;O diff --git a/share/dark_resources/copy32.png b/share/dark_resources/copy32.png index ec949509cd4ddc590b6e17a20e621578be8d7f31..1c43766e682997c992b22fa121815fabae3987c0 100644 GIT binary patch literal 743 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1DhWRGhUkzwi_tOUgGKN%Kn6fS5$!SW6k9!3=E97JY5_^JdVGedfq!EP~^D% zbK8sNU)z#`PPB4!id!AhVdGgCs~hDautmaf>Hh)(@ZZ?MSBaKY4~185tix zO5buib(Y~B`}vPj&%ZvOv0-|_Wih^kbJKWO?oC@Zy<>-i$21;+qN!Z1(dU=#p7_l6 z!S5HhydS6+s5C9u#h%l{`(eks)Y*qbJRIFpB4TRXPI&9SkIN2baIsk8!>W4W>*URs zX1=@ezHzbq*9hg%-uyjU(Jy(dPF#;ZJk|cg!^*Iw?JpUm9qqPu*fH7mlJB@TstpWYvzg2b;bAM^1MUW}jB+(zo^d)>)fH3Ipo`7V^kkIJ!bK;lEx(3DcLP zeHTK4j%n=u!z8iksO!fCLI?XEi+%U~x!N}O#rb2|YgeXUS#eR+bfZzHyV&%TrKYR= zrTy}_hz?}u5gFQ)OxSx%AGogTmvcgC3i^bF>xNy2P_wVN1>pWCi3V-x+anY=tM zImmAFguDs=}NbxJU3y|=KsL-#GqQ@8c~vxSdwa$T$Bo=7>o>z40H`lbPY{H x3=FIc&8!SfbPbHH3=GUUIt(&@LpBb5z_$x9071q%^73gD`5;nS^?bU zoPSkSwX}U<7gUoyeZ)|}4&b-pdUAdPfCm8F#=AQJQhxv*bIw224A9=*4xi8WQP=fX zHk++U*Y(KM)Kr_>?Jfhf0C)m`vLplkG|X5j#5VxXIOlI_2I%SOL0@0r@uU<&G>nan zX-=mTD=RCQnVGq){KxyLR0?)G306Z1DglHLP5_4!6BB#Q&COK@KI@NFdw>9XdwWS< zwz;`^6n~9ILC?rY$;@@HssUUs7Zw&4u(Pv+{r!FT{r*zWgM$MEgTYY%9{}7krr@wF z%kKsT2F{fEBHDjW!^$q`?(W9?{CqZPnW(C3Wcz`x(ct?>jm(cF-9h%Y1bml z@)uJ9j1t%!4#&~>_;?8*5{Y1Ucef2djxnYi!GD`*7Ra)kHWi?&s|(?9csm}Cw|P9C zY$lUw?d(Dd}l2p2LoLX~pa~K^ZZ=UY;x=dJipIrsO ype?Wa)?0=?>-KwILN#4VucFEgz>NauDexC{j)5=^*ftpe0000ujv*T7lmDD=kT)nj{=9E?|aX4f8+0_kM_*WhsEbCJbKu}U_pdH*8V@~ z2@N}Cy#pR^YFi-MBXV4gVK1l2HR0OyRY2#dmbgZgq$HN4S|t~y0x1R~10w@n0~1|C ylMn*~D?>9YLvvjNV=DuL?LvkdP&DM`r(~v8;?{7?zmo^3fx*+&&t;ucLK6Vi5Q91Z delta 272 zcmV+r0q_2c1E2zs8Gi-<001BJ|6u?C0Ov_WK~y+TtjkIiB}^_rLczgq9z+tcL(eZ zo1g{2w(Xt}VwWVzSW0;zBCf)S2z5XR0C#3S`o6z4P4iTS6n_BE^G3`(LBzf)NYgY7 zf?#79#zJk(BcEg$;JWS*5vKq!W9Bs?uA(TK1HeNS{sJtS`7DIk$8p@1QeNMMuO8F_ zj^hjf;AUCYp)6|U74oMw8DXJ`btBWkT0kx4yIhwj8;>r*ck^`E|A4xvW&c~h#wRNI WdJ*nCsQv%|00{s|MNUMnLSTZj_IMEh diff --git a/share/dark_resources/copy_file16.png b/share/dark_resources/copy_file16.png index e2440052ea089d20f9ce00164d4a73e4d47f62a7..9fff7ccef19b2daaf494c530b531efcf5d43a387 100644 GIT binary patch literal 462 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+uenMVO6iP5s=4O z;1OBOz`%C|gc+x5^GO2**-JcqUD=$&mrZRcB6 zycd4n7#FdWb7IG#?Loh~S^hh51nJusEvpwjcFU|VarN@gMS8ET5AxbJ$awwU6txfN zPSq0Eh?11Vl2ohYqEsNoU}Ruqple{FYiJT;U|?lvW@TWeYhY|;U~u=m)hrYZx%nxX zX_dG&teMmV3||IGkPX54X(i=}MX3zs<>h*rdD+Fui3O>8`9Jm-qj~pDj0lbWe|g>kpG=k)+KW zc?^bT%F;~1{fP{_d=;W6^0uFxoXc>xM&kq%=GsI;y2u82);{;mA;OXk;!m`dOp$Pz%2QGa8 diff --git a/share/dark_resources/copy_file32.png b/share/dark_resources/copy_file32.png index 480325ad9be18fb4c62813f61cd6a10c25c598c6..d1f08ddf7be87b082069585fd6d43d3bd87a1147 100644 GIT binary patch literal 617 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`KiRiVARj6BPf;z`$tk>EamTas2I6TW@AZfwuX( zWg;wEduKFEZC&eXb-D9VzDIhdGKW%<@QI~cMHQDOBr2CZ5>HZP%+*OwRqk+f+LT~0 zaqAA5lXJ^&etuQG{6=Ehx0^F{%XEDmD*Zw`WhP&pY;5*|*<#_9eOg|<^B5^!qqfB+ zvB-@}_@-zdQLJg`eWtc4iQ$t#e}TuMSWWG4ojY3?&Q4pf>QKCk(E*kg$q#MMCWs|` zT)gVj!HX5Q%$R0vI=TCL>z#{J|Yp2=ES6KfzmZpF38`JuO4W@tYiSG>H=46;3^eoHf1NY&g z%*Cs3H|zw4s%nXAL`h0wNvc(HQ7VvPFfuSQ&^0j8H8cq^Ft9Q-voZv7jjap}inj9G zp=ij>PsvQH#I1q(#r7tk21$?&!TD(=<%vb94CUqJdYO6I#mR{Use1WE>9gP2NC6cw Nc)I$ztaD0e0swM_-Vp!* delta 210 zcmV;@04@LN1mgja8Gi-<0047(dh`GQ0IEquK~z{r?U&IGfFKA(^UwM7S}htmE;hFf0*;6gSrpzyJ`O49DhCE?YcWde1G@eMRVsZJvv3b-c!wdZ5Oli$CdN* zrY9Gkp4FZuCwS>>(ano-c{T4hCSGTeE)uu-U>R)KQ|ow}yF1G2ob~hO=X$>;DIVeF z6^&KC7W*|S@5&nOdsR~vPtFxFc)2?D_}bZ1=jgsadbR8DE33Eryv^ns#`dk2IwkNX zW7U`a>tUO_QmvAUQiFgr zgOP!efv$mxuAxbYfq|8wnU#@=u7Rp>2mnUQ B(a8V+ delta 454 zcmcc1a*Sm{Z2eleoT4xZ)5j zEYy5xQ>d=aMtg^FPQB=2Zx5%%dV`-_2b%jr6sYME#_9*`$e>S|>IZL-G z(_7EX*sf~jUFL&*S9JAjJY8-D3Ww}9UA`vo3h(WEJKknDCAbHwTu!`P`#Q*0?at?e zzi)J?8*TK~lNOD>nC8E{OIt3w``nv}lHbnA?q0WhrT?0>jVm-Vd!Ft3x;k25cY@b6 zh3o2qQJUJ%cpuJgYIZxc?|uEEWw(p2Pl>e&`le}Be)dkIr>b$<6rX?2ONwciN%{+uOL zA~uXMo^2rm1A}UbYeY#(Vo9o1a#1RfVlXl=wA3}Q)HO5>F|@EUHnlP}vDP*)u`)2I dS+eCPijLg;l+3hBY&swscz^P^PS#;E1ONx~!R7z} diff --git a/share/dark_resources/corner32.png b/share/dark_resources/corner32.png index a89981829fdd0c7eb38b27fddbcea63b53466025..f2697135eb89e4c52741f76aa2a22d79049e0616 100644 GIT binary patch literal 815 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr16wo*Gj6g|ZU+jomw5WRvOi(r6%`PkRJGrhfr0U_r;B5V$MLt5eKUjuMOx2S zZ(Jx)ziNx#83i`Sz%|TDK>`~WcormvaV=E{>3#2ebX{84=`}}RdbwO_y3jiNos@u& z?!N}{;dC80(<{#nVz~+S}N?={Pz(D>~_3h zdf?hpVYlDIg|vb5~`Exo6b z&KnsRX8clIzh3&$)*1<+Me#>%Z=70HH$Cl*@!OXzOgs2Yt}~x{@v~&nRnGt7CE1yu zHs9Y9|FnBe!*WBb1glkz?5T5lO_@r>I1-G%#Z?*z6=ZhLUFhI&-T2QUCl!TCi5_;Q zysKxA?@8^LAmDlY)H&Au)|W1?RrKAT&v)gwT+K_4hP=JWd!4*9@@8c(adf_QZ2}X+ zj%%~e+ACWf$onmEZCb?ktb!TN`M&LzXB^+&zO?1GP}YaPNoo_*`(B%5*GJzC*b&B9 zoU?9Arl-VgVA@bEag8WRNi0dVN-jzTQVd20Mh3bDCc1_uAqECkhGtfVmbwPURt5&o zb-muAXvob^$xN%ntzlZhr$C?vNstY}`DrEPiAAXl<>lpinR(g8$%zH2dih1^v)|cB Q0TnTLy85}Sb4q9e03EJN)&Kwi delta 901 zcmV;01A6?g29XDl8Gi-<0047(dh`GQ16WB!K~z{r?UqewTvZgu|L48Qq*e-s7?|2@ zDlRH26hRPDtf*}w#3C++7z9aReCK5mP_$S`=`BsgDo9LB-n~haS-8=`55z@liwuIU z#1=P#h#zP|Mr?^)q)aEid*p@`LOy2ZWdhygz%T>%-2eIAbAQh{cL;ab=nlun4#2i$ zKq(~~U8hp2YK$F#hB7cdKK@`Tl{z9KM@L3Rx_Wwg{I%Dxtyf@-xz}3zjOTgFK>@S_ zxG5svD5ds?VR*m+3=a=uXlQ7er6GVqp^#o!Sm+RuBSdsmL>_gbM0CYkd)f26OD!!e z-(|De%IYF47JrL37Z(?=ba!_jN(?YFGt*Y7RC)op6CMU|H-NtYTmo>Jh`tVj;99i- zrnNo~;BjVtxYnRsR|8t>aR37=C;c#v%cEyf1v;zdx7D{a$VF zI)HpWzpGp>zwCM5>mu?1fTD<;3&ZfMdLfK4yG7(WfPXic`Taxyx1E(zUM7=yK}3!d z(PIF9B%*ib=jRJbssC!hXsy2lu$!5m-V(s-O;Hp*3BZ9o3*Zj`?=?3!PxbZnl{XVN z#=IgT9}rPn5Ck_i^Gh@bj4_V@ctb>biRera1gAF>9vd6Guc@hN*7=5E_|diiI1v#c zW6Zw*-hX1|b2Yl*djP*Mv+Jr2El~!X!qn8%{y2_*6Opc3g=vgADI%|xN~N~V>LxLO zG3I#@`P}#YOfHxEyIKY&CnpbDYp)W~Q$Y|EH}c&Iz$p=7X5L$?6WqGi`cD9#GV`n3 z0-&}248UE?>^h>RtqitKW_B}Woh8nI*7{cwDSw1vc%o)>08tcm646Bf4>9vkYxg7q zn4X^Av$VA2diq6X{14Zu6(;^{IJtO bI{^O!8kT1;ih6K500000NkvXXu0mjfSGk<& diff --git a/share/dark_resources/cut16.png b/share/dark_resources/cut16.png index a33fe87f15613a09f2c2d34cf274d1b2ee949108..7a4a4419932cf7e39661e182c99442f8db29d7f2 100644 GIT binary patch literal 504 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|U1(2s1Lwnj--eWH0gbb!C6T!Ye8u!Xu|O4=D87)5S4F5HUBN$)q;I8Fw$x*XT=nqPb<<@D=4M)v~r?b2r&C=^q6|^%h+jIP?Q`eP-3E3_0g6%6+b*4FGH5ygeu%+i6nDp4z zd!4i9j)MDg+}9WLihO6z4sv6X?rA1jW#C>nC}Q!>*kack&J-;fB@z~JfX=d#Wzp$Pzu C>#)cG delta 149 zcmV;G0BZmE1Ev9x8Gi-<001BJ|6u?C0BuP`K~y+T-IGxY03irOx0}z+3nRmww1S|I z`jIS0d`$^J{@MbNWG_*3Hrg|-s|9>{Cct-VCl<>&pIwg;!KSdd@;~eg+0cQ%@Ji5RLP-6MZ!f7s?#7 z-~V6dSN9st;v0^q^ltYa;VUYfB-?RmN|0WWq9&h^=P4a`{gcx+O?fYn;@U%;UTiuM)bs zVYbmc-8nU%opiM(-R|6c*2rw5(WH`sv*KoKjC^SYh7L0n67Tgc=q${U<1p~=;)sqB zc-qCwFvYf?@9Iiz)sW?BvZv=iHf+t9T|CL=(ZZ>Mmnv^*iDW;V6uZka`Qq2x=Gg_t z?j6g^XRi?&wF0=lmCBY7XDg& z@qgg4nZPhrEpd$~Nl7e8wMs5Z1yT$~21W+D1}3_OCLsm}R)%I)M&`N(##ROfmUGR5 eQ8eV{r(~v8;@04Cpzl3U1B0ilpUXO@geCw%s?p;B delta 158 zcmV;P0Ac^a1g`;*8Gi-<001BJ|6u?C0Cq`4K~y+Tty9qofItY-Ki{7hMuN%in$gqA z;pUv`W@Z46c<k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1Gg{;GcwGYBLNg-FY)wsWq-oLE6Q*2d5*_p1_s70o-U3d9>?EK_4N)3lsI1h z-N@OvNMog09hZ1skK)7yQ*UvLoCy%wtGF)qjL5r~40(l%3&aCw_X!rrE3RPchzjIIL+%C%kMF0+TBU8f4`VZiA^YP2QSm%+J{Wl0?Z#~zYSpCmwdrw#gCT( zd-r>9%`|v2Uzjz#Vg5p%i4SDdqyPPRWY)@aRL|eyuG6=O{wwo#oVj^s-jo}Ut~t&) z?V+>5*RpwiP)>W{k30Q5eLT06v(?`joylU8e^P7R!!n&uX0H65Gq<+9+29e+{qrPy zi`KM~;-xqH*rdaw?%KXc`qa7m*z+{u^t+b>_OAX^R4-a3$+0eBM$P2~?WOnSSAAF3 z5pwpKXBy8`u>S6qdeQw4_A&n8>Sx&NQN4f7oC~tQi(hD|%o4F$=)W>ctarB0tl%kX zvDY%(o4fy?>Aqz$GsJbpvYC2v-}i)>=>22*tkjb6JUg%e7^SKut`Q|Ei6yC4$wjF^ ziowXh$UxV?MAy(H#K6GH(A3J*OxM8J%D|vbqW>?7hTQy=%(P0}8u(q!foYL}!PC{x JWt~$(69C6k6b1kQ delta 251 zcmVD|ZWwf@QVk7{0)*1}V65*u*3v_@xHTSG%B5WPd3(%q) zQ*5Kz5ZUhloB?OR8Tc0iXudb6;@(`30xI`IzoF$eMGe`ku( zfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u00Lr5M??VshmXv^00009a7bBm z000id000id0mpBsWB>pF2XskIMF->r4HXYLgqwJE000A3NqwfO*zMuOEq3L}QNm8NK zs6cVm>43VYMt=~NR2tN&P%Vn<>EO7Erg#Kad59Hcu!5UNp~Br{p$l3D`9u&BM|ht+ zcleB9C#h~{>v^GRY@pE?pXOaM4JxES zS1PIoN$E;U2%Ajs7lUu~UGzFVuNoBv>!a1$BtD{&On*-JByH4_?hal^8atO7pJFva zMA`2lHWNnTM#m{5gA&#eqkG$pAr|l}tt=V!2(jF~H1QNM#9sfyI>O_? zGuiJUwvMXKlkVeFuK3?O`paUwI~}l#0=78LPb@kMznR}@p$H+;sdPUZ2#wK?#Yv%< zV?M((h ziRzpyS00W0NE)j>!VlypQatQ{$C6biS;1!0N|T4##v0NPOWi>OHzaSZr@rf`1HZXds4Iz2J@GNayMUG(sdnO%em$AnqY$t*Uv&BQ~CmPW#^=Xcp)ux4# z2Gp(GNk&>+CDFsdd(r#!hN|^eG#r#h2Y*E^yP0p(>^?puLNjHPwQb_2l)K9qkMJ4! zqQreH<{F;hF2a;Mm{{o~7GW-hqf<$QsPF&>*~ClKInLb|gpacjl5~%Xm9Ku)>K&b! z+RGN2?&}<$CSLymq%`M2TV(Xc0000bbVXQnWMOn=I%9HWVRU5xGB7eQEig1KF;O&B zFfckXH99pnEif}WFfiC}gh>DZ03~!qSaf7zbY(hiZ)9m^c>ppnGB7PLG%YbSR4_0) eF*Q0hH!UzTIxsM)GCcJF0000CJO<(54l2A+DV% z5qv^bzh&u58LvNo#>_Xfcf?|5-!&bq=jJGUfop>pEW8q8&6<^M2Vf7_3c$jT>b3wx z!L#K4w{id|RX!uE=

^LvBrv98TZA)HU5O>$1hDXnuie0UhWN-1DZ4oZ)V)(`N zq&g;r|9wru(H&_wdS^7P~@;pKVr=RW(+D6S=W{_~$o=l{p9eaqQ% zLsas_>=)BReYgU3U9YWOaEyP)gF2nqyT3I(mtV8c4PaPdy3Bp8jcCH8WT9)b0v;Wd z`*Ggfp7Fj@mivt^6o(6+KJP#R< z$1oTSo>f&nTmWdAwvbq>)tZK3ymB0O4ghZQBLMhq+rB{v`BhatSPIZ}edG#(K!8CA z$vn^3-56ucP!#oTS(bzlx+DTbQG`e&Vz%3DB@_x3d7e+rw_sV;EkYv+a8Z+uh;86l*?r>4C5k`$=rLr-uG-a`$+Vnzms5EcmxEkw`!^8Z7|8%R6*BeWPhQ*6;VPE0xN60Mj%- smi<0OQFhjP!K&RLwy>&@q;I^9zsYL25sa%&dH?_b07*qoM6N<$fz>% diff --git a/share/dark_resources/cutpath24.png b/share/dark_resources/cutpath24.png index 68d283def90227b8e00029ac89abf99d47d49399..a6df309e77ca89f27c27709c694131f9867f6baa 100644 GIT binary patch literal 675 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^+ z;1LNlk>v;oGuoWF(hL-2FY)wsWq-oLD=NU>R{gk$fq`+Fr;B5V#p$h6_IuAx6gY1G zJ;|U;q{MKWcdxgs$Ql-L_k(=0IfYslC4%iiRwb7lO9U43t!t`pXm0Kfo-Wpvy>iLg z2Vs|_yoDC#C!L-B^8a~k{nuVBtUZ64iHnv%oL|p|%&W^K z&Z`{VIM>fgNQb$eBt(|IA`h41ETwj}N_zWZOjfK%c6j0p+B z@gIPZrdr|}QIe8al4_M)lnSI6j0}tnbPY^&4NXD}46F>ztPD+c4UDY}3>115W};}w b%}>cptHiA#@WKpLpaup{S3j3^P6=%w~TK87^`J1Uqz!h)`?^lzN-pRj$cp=n~D4p$?iWg+g62nAjQ` zuGc2_lsB9bMZ*~gv^PFH_x(K2_x-*v!!>{Gn)UJT0CKt9jDKMmw=Ub5F=olK+`8D~ zXoE~9^N@(D0Nf5NO{}i2ZuI&b0oK>omjD#w@%T4E5WWk7aMQA^uUv#Nb_}2aU`AEd zM7P_`CzHvQv4C_sO~X@eZf@oxk;sZH%fi6=jGgxq5o3%|p-?c}?e?3ofKlQ-!QI_m zsH(~>vbY!#O@9Hn2jB*P4uB&?QGPfE6pO|FupW;Gp->3fY<9p>BH|ly&>aBXi2$>+ zvj_%*hXA$@4i1*;^*SU;;)2``%eIDZa0GzYe@z7N`FtDEX!Hpe(seymE|*`}fGNh< zZ+m)f8Q*}P#hIcg$Br!u1Og#Z6t_8`*=#4$?rL|#QvJ~;*igTedZ zaJb12RM++8QmOQAZf=hIv)>ap4C6f!eVm@2J|&{JtyXKnG|g9zQsnphABdt@w-duu zRkcjh><`}QbRf$zot&JQsZ>gHyWRX;c*52sNzzB&gNrfs`FxLJvDgQmaR3WLmK;~B z)i0W+-GA=Y)9LicOFK}!2nYlM&qPstZKvffpN=O8z#qog&z+r}mzt)nT^Zo_`#+1K z=(Pnrwm1iz0XVJIYWc0Lt;Cf9^YimqTwFXPqQ@?mi)X!WD-k_!G#bl$dwc!j#1`%E z_ro&w0rh%&3jz}Z96ZYdEsg;EkINpsanNz%=O54cq?1nC|NjI20!Mm3C|2~p2LJ#7 M07*qoM6N<$f`hn6M*si- diff --git a/share/dark_resources/cutpath32.png b/share/dark_resources/cutpath32.png index e0d7a6fb12fde855089f87df3a3aecdd5a165978..41ec263c491a8247dc54ba968599887ccf6120f3 100644 GIT binary patch literal 778 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1DhWRGhUkzwi_tOUgGKN%Kn6fS5$yUzG%}41_s8zo-U3d9>?!a-J2bpDAGQ^ zIRDZ$vxRD|E>XcQ7q0LJxNPw@U0qVB^Gp22vKJ~-%0y+4ER9wdFT8Xzkju@ngvX0j zTjWpMy_(EPzl%M5lB)9cW;uTNuBShzc;5G#J>U1Lu}wBk`17BkqgC?Ey1Q3uItu^( zJ~VeN$APcR|E^w0=I7JjAjFt4W246>14+9_N<1Gbj_(xaFPg+UeL~Wo>)+nYQ)iGC z5m;=|p~$x~f&XxI!ODu+56v1R8?+{^;h8k^T7zI+i|<1xb(sY72JSQq6&=23x3;Y; zO@F|owPjVXakEM4wksP}WjP#9`f}%Q?vd)0lao^0mZnMVRtZ@9Hol8NXY!rtJ?f7y zYp-=Fn>91JZ|U1TMramU|W zz+`dcZAyi3{q;D8eBBdUL>MPne)9e<9===l`H8L0p;uSeG02PWkCK}`r@=(>*$%_s zHsvyJRKppzRK6~KzT@1f>Q6QPJKhLb9O-zR<^Apd?i@TdJ44jLIWbR&c*O{b|*G8sL53pnw(d*oBWh#^8s_U`F`z; zYhK?zA@09bu1`R9UZK^h7Q2TRZ7YOd{@qv4862Z_Rs9ch`Oho-AHsiquV2>4XwMkk zw@u$H>c$yh+E6WVjVMV;EJ?LWE=mPb3`Pb<2D%0&x`rkp1_oA!W>$tqx(3Ep1_n>H g1gYtqlVM1D64u2k;qy5dZ^w z#$E&P0l-bA)RX!7c@WXv@$vD8B>`xfCJ+0gEiEneI2?{=?d|OXa0LAMgWj(N zU?ZaE%v`IK`hQjyz~74JX=Y|-;Pd(5a=B^%Y!MNQH{}0(Uw-ADnJr4GOjQBo!8V%> zLqkI+0esiNWc8xL27n(0YBW>?5Q#*7*#;tl-EN1|>69&K*0*3)UwI7?ZRRI1^9cZT zN~zTYD`2r$(B0j=2a(I=5R1j2o3IPOIuX4s<`>z2QGY`zwRK>Crluyi-R_G3K1q>u zI(szv34FHp@gow6NsnnG~An;NL=m78@fOtVnC#NDU z#?HyaOyeN=gPJ-ltNH2ZygIy^VttP(xe3KEG#=|NPO1G)#ya=b)NX0D%}p3Y`6nWDuP78VeVM$y;T2dmY( zH-?C0{tb`Ev$$^(76GW!183)mWwY7lR4OIiGejg&e7&Wm#TyERq9Y?CU6YfO@caES zP1Ek>ix~`tgvaA~^E-9Xmr)S_InT93lw)QI9DliF?zUX{)SH`|>+J9Ek9ob`ojRJP z?fbGT6+nt_GIPUj+LF9zBxa?bk6fCao$YYBT=ByI5D%Qy&-_OKIUPh45D;OfxroQucf z7eYoyM^ROPY<4GqN^WMe?AC6piU~`uTx8%ez=0L0MD}v$?weHQKCs;J#{fS8c`=nR T_S+?u00000NkvXXu0mjf^s0(2 diff --git a/share/dark_resources/database32.png b/share/dark_resources/database32.png index 131dc8ac23416118afb69b7d2a36bf0e3b015395..6f054e9f43ffcd0155f8cf1d25c8a88770e3667a 100644 GIT binary patch literal 959 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`KiRit_8ub6mp#)YR+g;uzv_eCbqQk1LKM2kKvI zxt?7$^XROlVP70~AAB}xNy>`S%{;gD1S29Y99%s8+{=@bOE~${mY)hxIuhNnLHzU; zr=^FTcCXo;DVF_B-uT7i(t`4@@9n=g--~H8f4_HT<^Ib2oJ0RT{brR~f4joAQ|v6~ zxkpbmet(tYdbBHbt49li@Q=!Tv+cP%4(YwSu!{RC$K*3YX>w=z6Ri2>OnJO0$b5wa z|I3Hjm%N1@Z`!EPzcj3 zQ!8?(Ett@+u3feKg!%IW`D;!v-<*5#-O)?QYdY@NFokeeT6xHyJ$WNcbHPmaU(97! zlWN($?}UBNc)0FexZ<*z$&IRYj5|dhK4HkK4e&Kua;GKp$9HG0%bv@Fc3ApJE|p1E z-_Z2TIJjh`0pRbI+l6Q#K&(7B<{ zM1AFwW`?V)&dzEUu=6YKeST}9TBUb~YtqN9PC%btj7v2*5qdAjHE~Yitx(pym>rrf z4;f5msXE;WH*UFcrE!f&i-Kd@rsV||+Fb2xMD}&+KaTn$d76`}v+qf|guMOBr>yZo zZ(`1*M%_Hd(0gT8@rPM@>k4AaS2GCjQ9hw$$g&~uNSxM(2Up#%c<+*2(&wh#YR_Y^ zKqPdBg{LrUAs5@M)Fz+LA$xDd@LpTDMlw<5bB>yZ#GBJyPMU2q53zQ7l^zqxQqkgl zwyev}MBWddoBL&oslYogABe3{TCud1urfgC&=6PYCJ9#7JiFQo_iZOHv;|{9@*a8o9v@JbnKmum~Ykw`K0`0I$YamO;RxM3{ z-6e|Khrn_!7cx-F-azWMsUK{rjVYcVfY*-z$f}{L7zFF*W9?&4!ibVQ>E{# diff --git a/share/dark_resources/defaults.png b/share/dark_resources/defaults.png index a4402b82d0df02d9dbdf0a2289428bc97b91077c..423ff50cc298a63d442fedec4943f00e6fa77269 100644 GIT binary patch literal 834 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI10wkH8TU>z@OS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>lBSEK+1*-JcqUD=DT4XcnL5F>6LWf*H(OD=^vXhoh7wK(&;JR@r<)|w`9_7t)CjG`x@V~InZOX zV0z@c%kQ1C&Yf0NYEe0v_v(g^X7&&7ru9A_X7N{W7GKMm?0Vu-wHnKTJv;_SEQJ54 zIC3ui!7<^9-pqxOzN(WWH8SKjZgbG}yy?Va|Jvizyd}3g#BORkvs#(C^)$>hS^SLG zJZ8VIbg0Y}w?oTB?+azgeF$W7DAk){mdNL!E?d+T1@y2?VxxV{!`y#7Imd1|E`9lE z)}E9J8p>ykT=(4Ac=Jw*{M3eAsmzkBmFj-F(u_CW{du`q^|H*og>$2p{@rQrVXwU_ zQ!nyC-O9L+8|LSo^Jp&dzH-x;Z;Iv9=fSPMr?ycgEwlRBDzD&OR@c5UgXxanmoTH!e{VOGDTZe#&-KYhZ k85nc~{1-vdkei>9nO2Eg!%trK6+jIPp00i_>zopr03R4eVE_OC delta 194 zcmV;z06qW02GaqM8Gi-<005~gQSkq2NspB>K#hm|3Q-WNaEbmX;LBE1?*7-;ydbS3rL%d$k_!;hxqVS w;{t_J7r8UI26k-M>%lU}3rzu`=A%2q4Z5iTmS$7 diff --git a/share/dark_resources/delete32.png b/share/dark_resources/delete32.png index 76ab5ce9fb6cbd36624ee8980df470ed2f321971..736330af8c93de9940d5193faafb8dbd4739e4a7 100644 GIT binary patch literal 745 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr16wo*Gj6g|ZU+jomw5WRvOi(r6%`PzmXzXPU|`(t>EamTas2I+{n;XcBCY$) zjjcO(w23q+sCaa(Fi1M0x}sNUi4cq6o1^syPaUg2?54vaoxGGo$Z&@XGuI*&6{U@L zkEs>)o;=6jcXZvmb5dV86GS_dqnecm69^cvnENZ7q3M*K9cDnAf zy_8bf(VEJXU^6@YTR-FTyWV$?JuIAg^P{5Ci|ZRVo0YH~{kom8Xx9xT-31PwH8aCQAUdXfzs1{ zf}dQ}`mN5+KOb%^%2S9e5^Y=gOK!#&fo{|m&l z8Rk5(W{C9svY+AM>#HKKY_4*KG5*lvpT9z@;pqwMb9H>58ZECEeCU#zJykAP{fI$a z_57ZKj=t}jZZnU3ak{qsSvkL;N%F_4s$KdU7EN9Ar2Of=QrDBsWmmlTuZx*X7kpFw z?*60G2P`*czvW`My5rc*Cq1{hrbU*V*HZtWf1RIi;m;{*cV`FyV^y`pHKHUXu_VKYhZ85l(QGH0S_$jwj5OsmALL0e$=RiFk* vkPX54X(i=}MX3zs<>h*rdD+Fui3O>8`9OCM3kbV@f~xC|HW-1FW4oO{kO;6D$;f3}Zj0DnyiSS%K`qoZTTXfzt{ zbD65DM!(looNs^);QbIR?&dyGFJRbD* z^}%2;u-VwyNNTu!K40#A@t_;P=H@2W*4CKxqyT-FmX;_UK6^Z#m;W3fkb&mrW^&8! z?d@&KGeA%Z+-1PKpPf!83JMC?%*)GrG|&8%3&^-E%YPq4QG7i(IOr7wfxEf6!PeFm znwpx}d++J#L3DKVy&ypY+}+$}vw0^cCpo(D&trUioI%9K#xkJ$>O)Wf-*3K^n3$O6 zcDuQ-urP2OhmepE#z1eK=Xvby?I9;82US&77#SG}s6x;HbXs|NIZ{(oQCV4uxVSjj zY&Iy0f`78IG87dRQJ%-}@G#EL&nfF6Gc)rKh@b)NcKcVi+Z}p(dW!t~e3(oo9336u z@bD1D#l=`zS;6Y+DpMsgG7{b0-7uTY`T+1ezgt^dn?zNO#{T|3i~72{I<_X`4u=B~ z5fN;io12S_j0~p6?;|J$c%I)ko6RqJdwbb=*MHa7C@CpHX=y22lL}*FV?Sbo6iQA` z#^~s%J^&Pi4u`|*bUHaQPCh5u>DKi0>g(%SXGAeUIiFrYS63Gr8XEKikY(Awy}cb0 z6BC2N!a~rO0I1ZGJ4o`y#YN1`&EeqSfI$j^pew*`N=nL$jg1ZN^70bl;o(1gPA-U# zkAJ7u3+d_U$jZt>TU%SeXE-o00K47(^kQ_Eh-PMHd{a|X#_a6uUkofPETE>Q23J>C zkR<8BluX^U*XvDtaxM6tkUoi`m^M8<{Z$ZzP(@Kxm&@fdnM|D3YJK0@+WPjA_wA diff --git a/share/dark_resources/delete_file16.png b/share/dark_resources/delete_file16.png index b2391fbd5afff81e22313f4cb52df2e1d67a41a4..4f8605d9ae2945918f554caeb3bcc42cabe5313e 100644 GIT binary patch literal 547 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+uenMVO6iP5s=4O z;1OBOz`%C|gc+x5^GO2**-JcqUD=EaloalZ7TuXanI#IcX} z_o&R8DRS0H%uK9?k=u0l$#a*w`VCaMHMvbAB|7)4`M`MNCxecPw6>0^QR@^n>qS$N z4L_$mtNdg?yZG+&`=RCPqGdI&QqIg>+9#9cczq`4=Y_wfU!D|W724~h;-jUl-N3om z=-Td9d%Y`#c{@Zmzx}vaPDJ$MgOl5fwg+Tg-)?cSXWhhtC-O>(7ZZ+`T=$N-@uK3~ z3JIfxv(wV{JUqTi^myLI{9x6a29K`JX1)Gt+u5Vie7(Cru1UB#Wy;MIXTOts6V7kh z<@RZFOS6F#%R+%~&U&l;b+`Sx{yX%ak8{-3}$cLz55#11m!_DgcyqV(DCY@~pS7(8A5T-G@yGywn=H91gim%8Gi-<001BJ|6u?C0CGu0K~y+Ty^~Q2z%U3y=go8T4M&Ak;!xPu zuR?A5G^qhNkH!LEs?1!VI`j+tfT|k_EWwRr6UgoOi>gH?`BoqgEr{9#V}XX7w=4e> zRAFr83)c^nh diff --git a/share/dark_resources/delete_file32.png b/share/dark_resources/delete_file32.png index 9eeaa32de640bbfffdbcaae241be518b88ab4685..d1c7cb172e72e59bb1d5837a592805511ac92a7b 100644 GIT binary patch literal 848 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`KiRit<~0p5yTts7cP##WBR=_}VGH9wC7u$Lo!G zI7$;I*tM`7Ub0DvBWTktmlu}~Z1mkayEWL6$1#v4P?tGYqEW>)Xm*oHhUU^s>$R^_A74)ZZ_Mz?8W+Ndl@FF zc)Q#_Rahpx$+5VxPE7l9g01tN)IRN!85+K2vpS+#?!Gx`{i9o>IOKDe_?FMS4dylm zXL*E{sLOxo_-J#$|B-`!ey7!&$6Ib0exBp0e{_rT#wDdrxmLO@Stagu3r|Z;S)R3L z#c!vK=tq;!t#%9ErP<=t85(LCY;h{=_&?S4jc;ex8RYWa4m>yW_z{L5C&JCF8Mod% zH(5@eVTIDy=ejdecemcm+3fkSoT(~ieL>q?hMbg^z{`p5JuleI1XAvGvz_hSagA$k z!1Nj?-YT{I0Y1+6TwD&n(%R4}#BKFNG+=ti>q#~B(O>L%c^T?fowj)*D*R0G?H8kC zTwhyquiSZ%^-S}&)xL^V?NQ$tJ&n(AusjiR>xcBr@I;%h7n&vj6OU?%YeY#(Vo9o1 za#1RfVlXl=GSD?J(KR#)F)*+)G_^7{(={-*GBBu<=>LnNAvZrIGp!Q027Xs_V5(=3 v1lbUrpH@mmtT}V`<;yxP!WTttDnm{r-UW|BcV^; delta 265 zcmV+k0rvjT2AKko8Gi-<0047(dh`GQ0N_bPK~z{r?U%t0gfIw1?Vt1KyD<^NA|U8= z@u1gMd^1prgNQy0@FAj62{+IH>&Gh)J3!?ntjV^FRju7Pa{>;qDgP<# z2x1CA1;Pc0PKQ>MIZ2)i&jqM7lV~ryQ+A*oAd^=QQmVb|Kz}=T#n0%Iad%>fdSA>aUK1Bixzq(BGN?KfJ70 zwf;8%Z;ED8!m|lc(3T`=u*)cq9L>0>sdk>uu5i}D+r|1imer7D&@b;Ae P0000;6V+ICB0Z$jl5RLO|C)#^EC5jxI zKYROu*W6Ae?50^+J^LK1omnp432LcjV_&MUXr*UQ0T26jg+&LXrFhpSCJC5CcuY~- zw_g0Ty?^(0@s$^i=YF0eKj--z<{njx~N`PGE)Y+&JH#W!L{~&gkfP*!RO?M|P;n%+$C~t3~uH zezic9VIX!zwQ%n*=W{y);R@V18crUQ$f{I1n`|8kz^!Z^Va z?UlvZM!WiEzB=x7;{~64zyqO!*KVIIy}ib`w6W@hTiY_b5T{9&QHO6mYgXBAy5WfJ zT{(r{bL7t}*E8B~tr2@t$JPc6F4Yp(h?11Vl2ohYqEsNoU}Ruqple{FYiJT;U|?lv zW@P~68Ux9F^85=>H00)|WTsW()^Ofwy9`i+B*=!~{Irtt#G+J&^73-M%)IR4h3-ler-E#m zJbCih+}vF5`Sa)BOifMQ`Rms&=IPU?`)6lo%gmWG=R-oELUQBiSp(xgdp zWo2bD$N}8n-+#TZu<%VoLxUZ%IEDf3?d=DiKYzYfNJwZBvcliLf2Z^C@I+NsRyq(g z;M1p1%h}o4XCNzNVq!{WWo3;cXh3~^{ox4{CWsam7OEo~Fm2kjQ+auLKWb`f>~XpP z6o|8C&H9*@mTSg8b?Vf|nVFfJzJLGDI&0Rfpu)mJk)=zQzK)KL7R4Hf$niXV`t+x% zsi`}-xVZj+YNS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^+ z;1LNlk>v;oGuoWF(hL-2FY)wsWq-oLD=HwuBd0Zwfq^m3)5S5w;`G@dTW@AZf!f*D zd(z&rOm#3&h?0)J_&|Kw<)D^^GNrc5ZYTK#bpAAmgh_G8WT`LVycOXcaK!DPQ;x`+ zJIxy9X*%!vZohfzG5c;(dD^|%b1SVKzUz4j_V@Az&wnK)&YO7IDSC(ItViApFHBN! ze5CHB7(7AYVbK0`N6GlPEMJA zJw>V^*nWjA)6We-mWLIJ#z% z$-;d>S|5xU?q-+%XPL`!-qG3eoIh)F{t$yvv*DsPCpP)#-EU4YA9mWI{^a(~QrRCS+csXaW_&PR ze^XTUw~a3Z7%m+!(YPr!Bb$A?1|RQ=#>`ngFMBWQ9Q6%0UsKz*jAC zjVMV;EJ?LWE=mPb3`Pb<2D%0&x`rkp1_oA!W>z4sv6X?rA1jW#C>nC}Q!>*kack&J z-;fB@APKS|I6tkVJh3R1p}f3YFEcN@I61K(RWH9NefB#WDWD<-Pgg&ebxsLQ0ELwA Ac>n+a delta 478 zcmV<40U`d71?>Zn8Gi-<007{3J@^0s0kla(K~zXfV`QK)V5G764D`34p`qbF$X5*w z4J28POCO3MFh#InBi0gp`tVvnj8D)FN7qBpf`bPS_PM#aUB;FemMvT6791QLi7bci zYm9J4cTr1A3qx#dEQ6Yw8j2l9j~-<(F)=|A!xp4iBNAlE@_*&a??*;PD#A=SaNt0P zhlj^S5P$LF#h#&|p>Z&|ef##EKXmAj5jJ1qOew9ctt;29TNmc*>x(z5oH=ub!P?q- zWo2b$1W6XOx3{nO|Nnn@eSQ7X>gwufY??bdI;!gH>)RL@7|64Lfq^0X)vH&+{QUfH zad<7=rqJmJtg>DHp^&}N`#1z+r9EG#6BgSx~dIMZZp}QW$C#lxLTPWd>9Qqaj07zcY U8O-PqYXATM07*qoM6N<$fk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr16wo*Gj6g|ZU+jomw5WRvOi(r6&2vjmvD1uU|>As>EamTas2J%{rb*z;cPw?*RjT88l>W%wrD?*J zMGs??>b^+atImzDj=z2I*vxmf&ui@8-+OP%|D*pt&%8w(=Zh<^%?q=8R4f-THLIhu zv+}s)K`Yme&Yxy8wLR9D>|t*BqOinmgWlm4Obm0BT&LxHIOQtB)bQHEqD=Sgr+aOE zmLUubixx#&2Qn~xJITsCQFYNGck8fu2V7V#7jLT&p1bl>2tUugOZRqd)w7Gpp1p4V zy8SN>Po5ebx$U&*!}+SqDn7aDJnwwje8YbBz4!%9IddM~u9@h&Gto+(S8i3+)P}bm z5@v!{TDq_E;y$x6+?pieX0x$&i}ieVh692^lNIC&9$$IJkPzGUa9deW`7A$nhuFxZ zjQE~z4}Pbmu9eJew{@SpPM6pemlAWH`$7oo0ak{JT@pM23EgTuEO#1qTO5AZv-|ym zD;Fbb?uDCVpYKx#nzi{PV|ebaxlyz3?5NJEHz~=S-uETkUuwSa?iX9w}e0TM!Z_>WvY0M1Onr?;j0>w@9QW|9rs@|Ef`uX~!{I^y; zC^+7IZ!0jWRZCnWN>UO_QmvAUQh^kMk%5tcu7QcJp-G5=ft8_|m4T(Mfw7f=fp)tW zFrgr6$jwj5OsmALA?ntr^FR%fARB`7(@M${i&7cN%ggmL^RkPR6AM!H@{7`Ezq647 PDq`?-^>bP0l+XkKL;okJ delta 586 zcmV-Q0=51A1=s|T8Gi-<0047(dh`GQ0v}04K~z{rV`La$z&OD6GmJW5aE3rbL&JaM zw9(MeK$b&^F$cq7bWJdakm?9*=3p~}Xa|5CLaZZ5@dVbO#b!Wzd;8`1`1mY&dHFB+ zvhJ>3yHp(=9amvfLsSSL1vyGO0Ey3?JC`9TDT#rDg9ED@UVprJ!7yje9EQ@;QVe-q zp@%ndVG9Xdj=*MlTU*<=s;Vk3d{IX*bvrpZZL+ho^F{VjYisL;u&}T=9UYy|Ao10! zSF8K^`Rzbf)7{<85E>dfZ^42E$@rp-paa_5+dD2?xKOUCsY!IH-PzgsJ1s4ZRYF3d zv$C?Xf?@|SFn=(VA3JvJy0Nh_QLcFP>eU%pSy>YX1_tUmfPsPG;Lo2w?THBnc6RoI z3=9k)wbXS$Wo4xUt~`!hV70fm9~hnv7|pt*o*=q91{t(}|NbyHH@DmPf^^QDIbQMc@vUT6 z$M^~wxaGFj~>`>i_@%07*qoM6N<$f~5uxGXMYp diff --git a/share/dark_resources/deselect_all32.png b/share/dark_resources/deselect_all32.png index 9071fac14b844641a76ef14e45eadd80245aad1f..762e2fd0de51ee262c9a6a7c272223416cc883b5 100644 GIT binary patch literal 712 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`KiRiVCp(Umkspfq`+Fr;B5V$MLgMZM~Tt1={9Y zuiqfy-O6$~;>ay01C1Zzi)M5rEd0UR)Vp;7N7%Gwfyu94gmz8vd#j{z>lgDM=1GAe zUy=#~-|Mx!VdY*vOZHoBTHgKS>#M{|`}7{QoYGl-pL_K;!C*d*nKR$tS;+ll;;O>m zGAz+n3?V0_x36!XUUui>;)g7s7|jHfL)(NI>@2rsl?qI^3Apt02J@As`3cu-Wo-Sn zC{5e=!=<>spyR)^!MTDZlM=e}f)DJ7duhtucuHaWt4-Nl6$cMrV-~A_B0h^{o-d>M zrYjC>m@?z_M9mK0mWgur%(;8~n(fQf$jJ)nPb$pW9Rh7^k6hDbSUI8p)a~05lXC4R zT5sB8nxDb$vH6X#`r3-=kyN(vE&i|vOSN8?ykWF!{_i+5DrTolEn{JON#45X zx3R!TQ!R0gC`m~yNwrEYN(E93Mg~R(x&|h?h9)5f23Cet)x7$D3zhSyj(9cFS|H7u^?41zbJk7I~ysWA_h-a KKbLh*2~7YXV+&mX delta 250 zcmVn#fFKN$pYP`y6E$;gbU20{ z@QTu=?FtqmT9-i&5fuqlCIPO1CQ;NKwExY5-w+s?3sr$h00pOKFrfw6!JGtMDR5?_ zW=}0ge65*)98rw~dZ#OaeIhsstwSWq5P<{mafI(6R)KXVU~`es`T<$goBy&?Ue!^@Ds3m2+^pe_dqLvW<_WUP|Y&wud+%hqR6GhRKVM0 z5pda}@Xu)Ijp&yOMCC@`KmJx*PCB%?XZ>>m8#Rhol^y%#SO5S307*qoM6N<$f(ZO) A_5c6? diff --git a/share/dark_resources/disable16.png b/share/dark_resources/disable16.png index fe65737acf932a9e5088c68d7d8a8238f34b0fa3..926583fec95ab6875ec950b87e47073480d770e1 100644 GIT binary patch literal 522 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|Vb-5N14{zaj-F$X?><>&pIwg;$hczrg>j3Q*{;r;B5V#`)HXw)%$)MOx?A zFMhSOnm=Rt9YOJxrXHFBG* z(rtHsxB2dNDV8&#@#MQkEAP<~MDk!H*^!ypigi7gcm1>||W`y{cc4ryuM!&yy}q zI>ckW=97cVv{=3yk5=~HEZe{G{pD8uGxueC&X%tGu~Nr(-s1oF{xVwZ*~DIWFQfz* z5UM4v5hW>!C8<`)MX5lF!N|bKK-a)T*U%)yz`)AT)XKzM*TC4yz(C|^%XJhDx%nxX YX_dG&q|UI(25MmNboFyt=akR{0CM2MGXMYp delta 163 zcmV;U09^ly1hfH=8Gi-<001BJ|6u?C0DDP9K~y+Tt&>p>z#s@i$IW~5Ets)D2QKLN zF-CY`t#WLJXgz@QUdO%@0k8sjI@%Nl@%tG#jLb#ZRRDyVbOI~1D`(-Ka%x?+IGatIw7t)eHXMLI-x9# diff --git a/share/dark_resources/disable32.png b/share/dark_resources/disable32.png index 762a9270cf19e677495dc1c86a1e2e1d45a755a6..f004b13aa8544e1aacb3358d3c5464f199c6d5c3 100644 GIT binary patch literal 843 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1K(i~W;~w1A_XYOUgGKN%Kn6fSCrqfWp+g=P?Mdfi(`n#@vBpPJwgISj`x2) zwxE!uRIn~YCHGX1K$B8ulq8Fyu8xPeTgn52yr`BPoI(p1xE@V-awsEM;Gx=^)3Q1>Cw-M)6L|0U))~(&jQjZda(9&%pWFHT-@Dz<=TyfDZrdgp@%Udo`-|aVUUDUtR{z`&u(9xoR6y$H_upq{Z^T_`SoRQ7W+Qyc6=6oFs4B1Mbib?FBCo<*H%}D%7HbGU zFjx>7W$0z%9j!H|mZzX|mdK*{>Jmp|F5A5AZeVEsb<~mPal--|?Kz95{G67i`iJAo ziN(o`7qmAXFSlGcQ%2JA*=yb=ulT-GOF6k`+*Iej8Mj~O*%{BN9^H5O+;7cV5Li~_v~ecJwkHXlVV>+W`s65I$6x} z+9|y>=k$pa0_6r-m4`LH-ptIo!Xkg;AnP%Wvw;uhnw(fVQS9#nP3a=hAXEM+3d`Q# zIU3n@f#v*;^_EqdaqFgZTP!V9lvt*ftUBQghyIP3?+sgDUfglPe_inut8ayq-1mIB z?_qM=zI=9p#TkY7Qv{s$SDsIORkVH1)Ze}nd{-{fySz2*=7DKSVf-hYM3_93`qZB; z5H(7As44B)<@*2s`LFtWgAya3DZai7OkAoZt`Q|Ei6yC4$wjF^iowXh$UxV?MAy(H x#K6GH(A3J*T-U(Z%D~`8ev2oHhTQy=%(P0}8de(Fd+~#iV-`Ode(M~Eh z6o?sJ7N%5t2BATiGYFb$fxnEhn*k|B7?Ee?9fe58&~K*2%{MDvZZLr&ECDnK+hZ*?YuhwHFctd`Y$i?y zVj6%czqk2F3n{k)R1hry8AKa^g|Mw?1&DO>2Y3VbGxQ-@k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1K(i~W;~w1A_XYOUgGKN%Kn6fS5!cJs(7^u0|R5Nr;B5V$MK_6_Xizv5IDBq zB5CW?7JIGGj0~A_)?ltFl3Z&yJe=Qr;R%;;_g0Px z%AAJcT<>?C{Jn!WVSH2!Owi#=B9xa&roNc>rnfd;r=Fg5B z|1CC&pS6ugf7?;RwVz?OoBc{HpJoj^6s zk8k*QWdF)n=ahf6Wd+`8k*fAcwb7sZxGB5hW>!C8<`)MX5lF!N|bK zK-a)T*U%)yz`)AT%*x1E*TC4yz~Jm9AqNx;M1& delta 217 zcmV;~04D#61?mBi8Gi-<0047(dh`GQ0I^9#K~z{r?Uz9gz#s?&_2>M&O%EDtK?D^^ zYOjs#xDs7r*!;!K`auN%02c-h0OESx3n)>_!Cn{^Kq_1VaUe~AQSk)Rf*=8AiE|Jr zz-;jr#0OxNI0fMgVD;`X7hVqh8^CJ!^)cilH~`0i?G8NMX;KAIzK-W2^7R;5^g*4D z`~{NYu12G`c8;KOq2EwC%ZZ^_UfM0aq&VSJn;lGu5zKxx(>5QsPUQesRPz4@CFF1+ TJJ0IP00000NkvXXu0mjfP!(J= diff --git a/share/dark_resources/distance16.png b/share/dark_resources/distance16.png index 8355b17bb357729ac9b8030f06ecf372198688da..ec805d90805d4f84781b9d3f53bd230467cc5c2b 100644 GIT binary patch literal 479 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+uenMVO6iP5s=4O z;1OBOz`%C|gc+x5^GO2**-JcqUD=;s*{fw7s_fq!dt4+Ee$ay7e3xh^P zaDwISw6u4{Z@oDjd_FH`cNbz8SAQOve2VYE?Gi0LnYOSma=C9JrmjfY>^b+U`D|Og zocli|R$OFMusy$WI!m{*xc((Op~5$pRO~G|W1sNJ9J=hEFyZyRGiS;qJ6dMEd%Q?` z-F&IV_3!sF)}}1EANV1AFVNwtC9V-ADTyViR>?)FK#IZ0z{o(?z(m*3B*ehL%Fxux z#8TJ5*vi1b<=6i%6b-rgDVb@NxHXtAcQ*rSkObKfoS#-wo>-L1P+nfHmzkGcoSayY Ys+V7sKKq@G6i^X^r>mdKI;Vst0I(vQeEGV~QWZ$#ekhAHb}hlgJ4iz}k=j(d?#qmjKxu)3g9CW}7It5M%CEeF3tV z#jYR^K*#LR1rV!LJ?A78pqjS{?%BLP^|FN)K>3lCW&mOyND&cE{g+Sx0000k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`KiRit_8Rd;HzRz`$ta>EamTas2F*{a(zD0>|ph zk2u|MxDyqy`-;=N1NQt6q&c|CCLOzEmY*Q4e1mhF630E}IZL)|Ge4^rl_Ar;`*h`` z-DjT8dSi0>Or8AZ``b4+UdUQu3{jOe+lwi*V7T@sd>ZF5vbbJ>|cACqFZ zHeZ0@b*Af0N3pOZ^}JUuzdV=C>yVZEvrcmM>ZdU;KD?+-J7f3$w7{9x*PLDtqL@xk zem_(EThI@FgR8p}RLhh$-iTbL?R?Ygn^e;a`8@)&w0(SzFi!q?G@?aGt;kEZ|GQ$! zrKcCQN|cYpFnlnU delta 225 zcmV<703QG31o8op8Gi-<0047(dh`GQ0J%v-K~z{r?UvgPfFKM*<jD%&5@*5sJ`6w; z=V;&nmN*>16Mr3`&e%H{Q%*uHUr(H$rvOBRv^C!Ycw)EYLRyytZQFaw7K*@{F0$3` zbm8QH27nU3>;ee@DeeNG#Z3Sy&y3Qw?^Qb>{M~fzm}ntG0Eo$Vzz_h^jR^oLR_yPSYcim^I=Kg`yjFs0#3S-o3KGj%jBrm&gCk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1Gg{;GcwGYBLNg-FY)wsWq-oLD=NVDe|hvZpisA`i(`n#@wZc~g<2E@Sml#m zDDDyZ{&B;-M2@wudPR72?4394R#kDn5c`>t>C;*}W!{I9b0%7)Gp&Ch&+7ScN{83( z&4~&vGjeV|I-Gms(3Ybj2UTml#^VenIlEqn@dBNtTH+c}l9E`GYL#4+3Zxi} z42%qP4NPgTe~ HDWM4falnJ< delta 183 zcmV;o07(Cs1IPi88Gi-<0047(dh`GQ0FOyTK~z{r?Uum~fG`L{<uY>3c@pT>^qjMqLehdHr002ovPDHLkV1lClO=JK7 diff --git a/share/dark_resources/doubleside16.png b/share/dark_resources/doubleside16.png index 92e873fcb9ec3e7df8bb230f487b2bef15a4cf35..cea43331055beff16bb28c7bc35a1c08dd85cdf3 100644 GIT binary patch literal 501 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>qtTZ-CslU;tDAVF1N}2&m;9P|dq{Km|bZ{p;5tm2cjBc>Nlv9moZ; zfocj(FJ89~qOp z-CYMn;Kilfis7=5;tsgW@J|vk7$@H9or!5%k9&^o~Gf$z*q58qJXiEQNmlmce4Qh zs)h|68eI)DcCcJYy(7RF=*KtXv8tlh(ugG&*CbDJ+`yQV&un1W(wPdhMYY5=q9i4; zB-JXpC>2OC7#SED=o*;l8k&R{7+4vaTA7;Y8W>v{7`$wscLha5ZhlH;S|x4`Gj6G6 Q05vdpy85}Sb4q9e02VRDMF0Q* delta 334 zcmV-U0kQt|1Kt9V8Gi-<001BJ|6u?C0VPR9K~y+Tm69<|12GUqXLeF}*G|qsLqi7$ zDGCJ=1vH35K!ub8_yVBZfeKO4B2b_J1Pv|RB845VvWf>KA|bHrUE_NGv*&#yL>?i; zClQ@kYwuSh7?}s9RM!JsCjiIBnBgL~1Y}vZ0ZDRD2lUL_Jb#^TC5S!e-0N)i2cVQj z<}M>XgdmN8S#WHOt^zc#pwv7V0tg{Ki0CvZF>3&X)>=A9)AS4g*f}?dZRVH6*ib5E ze}0j*=Rtthnzh!If8_6~rJ=0T+4qylMV{wtRj;ZANGbQ2`I4CropUe$0*H2dhl}Et zh=zdp7PS8T*+&+2uePx1neUM3IYE4?lUlS|H^pf5UXrMk>Un@G4{($l^BB`iNurc; gmjMQ2Yu94{UuMya5hL1Dga7~l07*qoM6N<$f_RmaMgRZ+ diff --git a/share/dark_resources/doubleside32.png b/share/dark_resources/doubleside32.png index a159a4c5377d3b155ad3188d73366434330f2e9e..fa79cdf8f83a85356b457b84f37f64e6381661b4 100644 GIT binary patch literal 661 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10Vp@Pti0l9V|KGlS`~J-v z2>JfqyVtK@fByXW?VC41_N!N~K0kjBWWRj*5~v0!^5Vq{AQuQgTEM#Ay?X~V1PDI9 zdIb`B^X9{c4?q$q{{H=Y2m{Clnhz8QGJpW67ia|#0NFr|pFVv8G9Y?^fFdh=goRgB zfJJbn6)3D$d%8G=Se#ya`KHhz1s>K5B5TU>*G7G>UAg=F|NVaQ-UlrD?wLP0qhio< zLeM``=yKD2F-LU=iB2WI1wnyJxIFJfq!*~EwPZbn?{AKqzwi8lU-j{aC-NMdypkiWSVv_;jAA@@!e-a4!n3Ya%iP$>nf0I|$?(9< zuj-rGD$X{p*Vl1#v|}$@ByccP)xur=1@@EAMCaU=xo&z*NBpo#FA92 zl1!>R#I{~wCumyg!gZhzRgG))(@)?dr!XdNI) z5|aw?ffBM}g@q6&l~UiPL9`Aq6pG`c9b+~rA(-Ri)JTNf7%3006)kA0Gg) zxlYLWRETX2;VO{w=U#}301?Ko9};q{ssB~ulO*{^Zz6#8v1&4x|BV4A1=JOe!^ zOwZ;)V+)EMaDN8)n}k;UqD{hs5Z;ke{-~XVJ^-y8Lmz-v3Xu;$QHn!j?rE*RROL+R zDR9n#D%G+7{{f~|!dC%=yIRVd4R+IM=)TV}Ln~ zx7P`|FzoGx$N>OeEgB^x9D&s92@yhe)t8!jT{ixS5O01fb-i9C9P8^xHk>XjafO;@ z;nYf4w^6Tm1uEi7OEJdy1R-Sjwkw`nKFL_SDcy6EEl^5_uiSKFk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1Gg{;GcwGYBLNg-FY)wsWq-oLE6Q*3ON-?M0|VoHPZ!4!kK;$D?Dk@I6lvSv z(QDBwB`UUuRY!!UY3kCsQi~U?jrhT^ujRY~N0?aIHZHF+X0E2W;wEg|7mq#QHGM4l zFyh6rH))gJWIeq3is$p+|1;+wc5B%mdRG2tJV(SDA>CK1chWu0{;RNGdNZ$O_5r1{ zy{{fkGSPjgzCmTSxTMGuzn~(OwM_zo4W&tL$1UE=eJ|E43F0mE*=-l9ea1Fh z+@6Ud{XM%XN*VR{j`U;n{z**r<@ zqo+A5K5FoptL*=1mS$7V+a0pU%p>I6QN5BA1$N<6_{1vdSQKX6vzT!BNzm0Xkxq!^40j0|)QOmq!RLJSP73{9;}jdTr+tqcsh h!dJgT(U6;;l9^VCTf=WIVNiNx@O1TaS?83{1OOW@{|^8F delta 262 zcmV+h0r~!{1(yPl8Gi-<0047(dh`GQ0NzPNK~z{r?U%_CfFKA!_0Re98k=k!17yuh z9b0@)6rox+Uv)FTqzeGR(I*K2FJ7v^2&W{{1TZ)zks>g|Tj;TSP3RHejH!)^ttmCm zEYZIW70^tA6u@RBNmVMutBv@IfJK0UH*xM6x(BoZ9=Kb;3x9VBM8M4gQE-z$BwQ^J z4OaS00yQ19yDitqF0(*0Sme7Ye?}U?6BXMeFpJra4*&oF M07*qoM6N<$f)9dfKmY&$ diff --git a/share/dark_resources/drill16.png b/share/dark_resources/drill16.png index 496fa44e04cac5f6f5afc0cce29685be5f9a7f5a..1b6992e627e3ae9b7f747026c0f95636b4e0c018 100644 GIT binary patch literal 509 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|T=z2s1ie{+A9EWH0gbb!C6T!Yj&eoZ>ez8z^+z)5S4F%D7T?ROc6i7%$twMF}5#bHolRvE4tiXu(6CZOq;35q`&tPRzZ-x?E?s zwT|&-hK8&q3c_LSB^v7&@=0mP&n`Q}eah%qWmutv`!%tn8n-WbT-&a_YW3Xu>n?8t znmH?GJUCrn_$=&$MR9N3$-f$}kH;Q(w}FpkGXCVKxLFmKlNnrf82Hy7wF z)e_f;l9a@fRIB8oR3OD*WME{VYha>lXcA&zU}b1(WooEvU~FYzuzUYTU^pRZ$jwj5 zOsmAL;nX9}^FR%fARB`7(@M${i&7cN%ggmL^RkPR6AM!H@{7`Ezq647Dq`?-^>bP0 Hl+XkKV~4PE delta 158 zcmV;P0Ac_A1Fr#)8Gi-<001BJ|6u?C0Cq`4K~y+Tol`*$z#s@4Kkv`Cn2d!%MZl9$ zTA&oU%mHu%5c_tz|ANN^3+OZLD)C8#ffpGg&{+HTwP1-nI7?E}piJHq)$ diff --git a/share/dark_resources/drill32.png b/share/dark_resources/drill32.png index 6b0696b35569de6a4a99cb6ded16b1d45526b115..5e4514696bbdceb21fd2c93d8f61ab2326a4e491 100644 GIT binary patch literal 740 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr16wo*Gj6g|ZU+jomw5WRvOi(r73H`1JjdfP0|VnGPZ!4!kK<=2*?UAMiX5$< ze>Ljs(KaqWC&win-5gFQuQ*<4Y7X$yUAnos`G)V33rBrp@5*u=UAlT{@*Jib8x$wSlyYOU6NYL7{45OQkHmXy3RDZnvZpt9L#PjoyOOIwG%>8O1v`sg^ zvbMix=iwFy z&9`o&;RpRk()kukyM<>7%wF?x^4w2W&9A!WIBbrKc9g#=oO~o)#dw#f?1X^yCI4qx ze@LEk^8}Z@#pnLDZaWUFoG$!_$#VG)<){rkvKij%UiGaDioba1_nl~=1M&Hj>Jl!# z4Oi0ey75e{-a?7dqHHJcoTgh7v_teCcD{{v^H!ZE=^K9iVCy2$+=Av6C*2A;^$m7%HfzM`C zT$q!pv-;!$2qsC1Y)=&RtL?-uMAw=Q$Mn(M#|j8N4Q*NBpo#FA92yhd delta 234 zcmVccd z7uEw@Svd&TF&ycoZvm9OWG;b+&6XpsYCm zivYcyjIxyCFMtsQ)kK#!698^Gh<0DS;080+14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>VAXgJ3j80+#CrODXEm!5u|{R(IjW0JSK3quF1tOt<8 zS>O>_%)r1c48n{Iv*t(u1=&kHeO=j~u<(is2tBRsUkwzR=;`7ZB5^tP+;yQt3IYxn zMY(6K*r=M+>XK}J?B4(X+n21F@$uY;1BvMo3=J}YPq`aJy+cCRS#Y$x;&h6A&b=#( zH>N8=?$x~O8Ce-yQ)Mgv9PlZbx#oI$&V<&7FZeeJC$AHl)86=3^%JAo6_ zW`85cb(8nxy{*nAHgkVImAY@z@te6?X!B?7qxU|2VqB3YFpV*ZXD!fiswJ)wB`Jv| zsaDBFsX&Us$iT=z*T6*A&?Lmbz{=3f%FsgBz}U*bz%j}(5=BF9eoAIqC2kD{>_49Z PH86O(`njxgN@xNAxOreM delta 328 zcmV-O0k{6J1=s?R8Gi-<001BJ|6u?C0Ut?3K~y+TmD4dRhfx&A@y{QHg(M_pU=U)E z#6rrVEXwW$7>(WmQQm}v*-Nm?V8CDy78y{K=;%K6c)I%koqC4zJNJC=Ip?0I=C_R@ zzN+0~9=p{*tt50~1D6@V06x)5M=5a;BZwAe>H$`OEfJ4e?WrV-9=OJ(x~wdiuvE7V;2!aZ&|@zmADIfJf{U aXTAY0895Pv0|40o0000w%$&O5^d|h zM`*Z<$V4?AX{&2Yj!q8Pze07^FL_h0x(437K#%6ei&up5g%&R1Js&WwYP(F|bDq+7 zZ+Fh`{{6Fo$1)W;YGtA4%5xZ( zu}@Wg|58q&qbxS8e|fTS%%@dPW*+=C=RM<{fxis8r-jhCfVf`l0GAdkuPlUREt}jVMV;EJ?LWE=mPb3`Pb<2D%0& zx`rkp1_oA!W>!Wh*rdD+Fui3O>8`9Y6Czmc=YW(^0=RcX5naBVB{rle7*w~tbgX14e@$uuw`IwlP zIv+lK*o_TWe^k;WJpg>XL$MYCBxUR zUl}f5ym;yL>wnk!AcIi?1!~Ba^73-etgI~N=H_OG)vH%C9654?fsc<5?j1EXwez=c z-!{T902U+j=g)uUf`30U%YXs;ZkzO-+5@y?e(XDJjXI zrKQDCQc^;i0f!D9^8NYqC&Qyhk3a@8NJvPKZUC|-l+i z6l=Dyv$Mk;jUXM8l9DMrJUo85GS!bCKTbY={J0fsIv_Q70{{hR$q}XQ8HNA=002ov JPDHLkV1m3dk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr16wo*Gj6g|ZU+jomw5WRvOi(r6%}AjTgR2dz`(f6)5S5w;2*W!(HE~!XhqZKS@o+ca7(W=j>gg zJpWSp-8QxzGFHu#f`5Do{2lm3eMj5R3|D6<^VYU`ZEq#_$9-GQAaS@Rv=6DYDILYvf>ff|40A)jNsiIb(_CJDVXnbV5GZq zM{(fMKN)Mz1x$Kbb-d4VW&+ddtMl8n4Mo<@+Ap+PhP5>9Vu;#gxpu+ji}|0aCzs9% zm+iQ=|A$8Qi?m|9tJj32|88gR%Kx)2b2j@s-3v~8mLD*3UBz&@#rgQ3?A4~el5rXJ zmIrHI3#~k-`rWv;zM%8ix|b8v9)Ec$^>VN9yXkU#dT*Xg_UU9Oh%275&}nKkpV-#R z(hMsOdw+81(@l$bFUjzPF+%u2WSkPPyCDoPKsn)merGF4qp$Bnbw~82n@A zV^&zmFElSWI{t4gTkTqZ@u={&iS`QncAjmH`xk#SKa%hBZQcxt9gP2NC6cwc)I$ztaD0e0sv8MBcT8Q delta 900 zcmV-~1AF}J1&{}j8Gi-<0047(dh`GQ16N5zK~z{r?U&6<+h82We_bL)d?6FuCRkyv z;Akn)2~J@uE!674iwgb)f@fb)Ne-17Q3PKP9=wSMMbKXAq?2OxHuPX+&}ww(NCnNH z6@%c~Ii80$sBLQN?A*Zza>?`Xd_R1DZ;1+?c&VOPA7TKkR)6dDz`#Hd0K6>AezaPx zX@$IXc|<%w({v8c^VgCjePdacMi6K(RkxCXmjNQ;qQPLG*4Nj`JS7!-MCW@cb^ zb{4w2y6~C%Ab+p}5r8wTR{PTBa*+iE1+u`=(Gi09B?!V#mSx{qEEcG&tW*RT8XAJ} z@o^|GFaPayIwh86a}q(^4S}H1XkMcb6crW8A}1#&C>-H~g9Bo2ZVp;oTNMFDMn+(G zco=w|htks0kl*k3F$|+uf`~~%j^n=P=jUtOZa1mbYJX)RQ53;sGJzln;BvWurs=p4 zV`F2`-`@{`Kmc}kccG%9BHY{COC$vl4F|_@K8m8=At!V?oh*bdt*@_#y}dnHU0p?& z$3RR?O+jB@A6#5q;Jx|zdGPssiun+?#!*gi9Ouc(%F>~nC@U+Ih0w)~jg7Fqy$ueB z1FEa5Z+}5dPfx??=_wW^2m(lwgsrVDXlZGQ3!&I#A`oBIYV`-F(@9oURmnn^mzU7o z+zf8F8|-#Fn9XK+Z)If#CMPE$91hD*C=`Oay1LW=Zd8XmBO~LJ!{H!|Mx!irb#(>W!NyaYV@Z70000NXVC61PYz;ba4#PIA3~Uqh52O$gz*| z@k_gBXDn)-v8z<1TDg#0MU9jB&;vOaj`(V3vCU`obY|$3vfd4SC1H2-9X@%&=pBc)h)}&!smXn^U_sKd02pOPEXimz}J|IrTY`zc%IHw%{+> zvgW4eTdRWCS7*Qfbv0O_q~^t|e@k6uB`gC~y8GQUFO*HLtdOo_n8?)FK#IZ0z{o(?z(m*3B*ehL%FxWpz(Uu+*vi15_k-hc6b-rgDVb@N zxHbG)`?DITK@wy`aDG}zd16s2LwR|*US?i)adKios$PCk`s{Z$Qb0uvp00i_>zopr E0G@QNEC2ui delta 291 zcmV+;0o?xn1G55<8Gi-<001BJ|6u?C0QyNpK~y+TmD9f~hEWv2@z0z5Ar_@1vqAU| zSd|F_F;LDy7jHvzzNBG1P-g5!#*ux1v5OOn( zjauX!t}0^~ra^?- px07!?plv618XV^o*o)C{@CzybN)ae$k469h002ovPDHLkV1ltdgy8@H diff --git a/share/dark_resources/edit_file32.png b/share/dark_resources/edit_file32.png index 8a78241bfb25bdd111d2e8360c88189e0d2eaa2e..98f49fde3a1a904d23d925b0b9d439c9fc1d2213 100644 GIT binary patch literal 716 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`KiRiVEEamTaeVGndvB*eiDUIy z3$HjXS)kb4l)<&gzB+A!M&pHm0NvV#ea=5PvobQWxejF&Xup~7>gaq$DorrNg!Sdd z2?o+a-g}?lsjgl&z53ke>iOSWPZv&EsiC<1qSqavXZ!xGUd(0jc#dyxy`x?iyVKW> zW%gf{r%O3R#C$kvn7oxk{o2&@rs_*y{)scNs_lIILjRE50fvhyH>0LF#xZ8Nb%ZV| zW6XZEYgT!e<8RJ;mTRv4-OsSwIwPQ#=^&f#Et$_AvIq2&lR6h2dN-}`;d3{3h6u&w z3>BTTdlQy~iM>=h*m-f`PodkEsf}hcl~PhWd%xA*c;i?@oZ=Mml z5m4JCG-2729dB3Nxxla~No@VD`6nh`Wj=N5`^A(N24%6>#`~8N|5mP-OzoaI|CMxE zVvhXf13n9Z5vN+>8c~vxSdwa$T$Bo=7>o>z40H`lbPY{H3=FIc&8!Sfbq$QI3=9-{ z6=tGn$jwj5OsmALA@ITsRiFk*kPX54X(i=}MX3zs<>h*rdD+Fui3O>8`9U1(gDj8Gi-<0047(dh`GQ0NhDLK~z{r-IrMofFKM+_2#{~#zYL(Zs@cj z`lkWrb;osK4-swr+uL^{TD`rG1xSEH+=Ea7yp5V=k^$CPB>ulSvIHR7 zo*_v%^)QkWv?K&xWk6>^R7~;4)iZ`>!52~Or#B3M6z|WP4qykg6QnSRPwwvk0000< KMNUMnLSTY9_cK?!?Yo|{<4wL&!(ykmf4_Jg5;5Ot-K`)0_if3P8a|^ae(k$I6~td~ z6d3J}{a)0d$q-gqx|w-OCesCh;GCZvK?hdvd)fV~YJFdn%?tm$KkMojF~vN{n)J8u z#}S5CJ8n$kgD93jrs-U+ z?f=h;Uv#iqczc@LAD}N)OI#yLQW8s2t&)pUffR$0fsui(fr+l6Nr-`gm7%GXDUfSy zWndtCV%KpL4Y~O#nQ4`{HRMcXss?J11lbUrpH@mmtT}V T`<;yxP!WTttDnm{r-UW|8pOGr delta 471 zcmV;|0Vw{A1m**f8Gi-<001BJ|6u?C0j)_yK~y+TrIRsh!f+79pF%K#hznpblSaS$B@QBV?$N<|9+iIl%!NlR;> zz45sFaqsS(0sjnxwx4C$2Zmv8D2h_gc|}nuS(e|U(dbnok$?D7Pinp-+-~o6QELQVFW6Vmh6oSS&ux=kwc(0ISuC?RE>7%LM{38jY~oZ0Ps< z2m}I;lgZ@nSARe@o8>uDACO9=_|a&DTrLN{-;eQljMZvIMu*4aK|CJ6EKq?skz8Q0SitM`VmKV07EW>` zB9VwbKx<{K>vYe^vTV`ea9qk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr16wo*Gj6g|ZU+jomw5WRvOi(r6&2u-FWPj1fq^m9)5S5wv4yQQPd6tZVixx>oEi`4mxI$SWed_WvYj3r7Eb}h1 zvS3}ncff1+Ge0|-22X}>j5mCe+8J!b^$%W?>^`=dC7S(O<@uQtnKvBYca=Bcrj`6} zCOO$m{{un`8Ix|x|L1u;Vq>>s&{l9ShEv6X?rQ!P1h6b-rgDVb@NxHU{EU$z>kK@wy` saDG}zd16s2LwR|*US?i)adKios$PCk`s{Z$Qb0uvp00i_>zopr0237DH~;_u delta 831 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 Z{sxTbbA6>0TR8v#002ovPDHLkV1n>v$BX~~ diff --git a/share/dark_resources/eraser26.png b/share/dark_resources/eraser26.png index 561a36051aa8ef855d16bc84e9c4a4bde8aeca35..c69973c1105ee5895445d3c2e98b37e74c997042 100644 GIT binary patch delta 1387 zcmV-x1(f=r2lEP$8Gi%-007$SUEcrz00d`2O+f$vv5yP zfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u00Lr5M??VshmXv^00009a7bBm z000id000id0mpBsWB>pF2XskIMF->r4HXYE6G@@{000DLNqIUtnhd-SS&(OBG_y zaHNER*fE?aAs|h(Eg23Jeu&9Gl?Mtp#GPSD;e}LVSbtGCA=Mcc6uujxAIAS>R&2vB zaUeb!0K_z&h1AvHIkh}90NKRb`WhTP;++8ixG5UAr4IY=5grDx3PZZEZ%BiQ0RX#o zLBFR~1CwkFfW&%SQU!hX2rmPuVY@o$55mm=fEW28AsE1BZb%r0_Go=TLNQ#8i-}Pk zk_e+JB!3x3HAq5?Dv*MQ5%H5ayVxKNwB=I^80WEF_k5Znq?pl)$8dur$Z&blqdKW( zVlwP|BvFPfq=<1Y1%@4@n9)jsVFO8;VScgqDNd>^HsF3S>ybW8b}-JS#4v*tGg>Jz zOdu&SX4RpxYeaQYNyI3Bszdr7c`PXg)U#T8$bWKt)xkJZ!l<)CPP;)qkS}yFS|z<9 z7#Vl*y$hsYzG2N^E#j!|*VT|wEXy@Bg&i>&n86`kSOr-ocjoqI@k-S328q{k!v!*k zN9ON}WB5HH1LA#rp|7EWJiTE5!>EiSc(<&M3euZv=pwE}W$Z)gYaA71O>XZ(>I~DT zUw`w<{I56+Q^;N8Umo^3MQ6_N|1vZ~%NNCl!SQ<96UC0fllkC*V$0x4;iyQlXYi#t zRiL;qIPd?f3Lzy$AbW=M#LkHQ_aX2QF2Wcz@LkFqR&(@SKIu(bZgMgmNGAl|K zeG`kJhk$lw_lzk^>0~@c83eS~kW!~FV=~Gippin#{#>1IIv$r{0s##dP>9B;MJovO zIE~O$Yz7&wdK;F+0(!h9DmD1WBQ_x8w-%_-p-=Hro1#fa&l#bDSisC-R+Qr;_Z z7c`kJ*34fH;6_9iQJ8heb0U!*$Vd z9b3`DdOU$TuHiCHV*+>LA>1JemT;5U%;i5cYntTmld+Ki001R)MObuXVPte=I%9HW zVRU5xGB7eQEig1KF*H;#Fgh_cIyEpYFf%$ZFdfLc#{d8TC3HntbYx+4WjbwdWNBu3 t05UK#FfA}NEip7yFfckXH99pgEif}WFfeSD0($@e002ovPDHLkV1mRaT)qGR delta 917 zcmV;G18V&93ZMs&8Gi-<003~}l~e!#17}G@K~#8N?cD25>o5=mV0iPqIY$*lr;1Y8 z*_(I9G)1_})b3&sN_@-mVFgb5?MO2&gQVnkNSXb@Hm zNf2g?$hI|dg(zTnSIIaK6$}XwB@B8HH4JJHMGRUHRSZfHWehqHbqp$y9WZD>cEO+k z*$HDj2#WFeOn(8rrt41|tmAk-7ioEQf(Cm|1ij80R9Cx^AZV!1lR&TS3fel(I1n_@ z>jcp2twD9Q8wG-fc~?BzM_16+amIk4LB1*+?Z+BaSGy4)Xo$ZRjrP?Qv~`^2AZUPp z6^!<04XUf%U-P@GBki^q4bM_6+GkhL)^RLzy!Mp>f`0~QEfnq78dO(1>pY+934@@a zAw{BncLi-72bt^HX9xrh3@s4t-x^d`J9NH}y4)aWSf1k0F}i}bj^mlL3j__yQ`pbj z(%XL$V+~|=JI}n!K|DpBL89=h0j}eF<_?1(A$baVo)j{c0*31hv4#}IVBfO5^M_VQ zCk8W!7k>j@Ar_EGF*kcK-Ju?xfBFiE7Q}vrMCYFh5-o;(g=EbC4U%+wmVuFehGZ4R z_8gKq@AnD`u8>TO@hfEdt#3941;|vC3Je;MX(&|~R3KAODlzClR-;s7P=c&N>A;`` z=|<_opa$te>BOK1sYdC>kN~MdS%Dz~l8v$oLw^b+3uPsS97q&pHHIXJ7i9v5B#7m6 z|LYs~DHw7f>=;rY3K%jVDi{(VN*MGYY8ccYiWsyYsu+|Y${6V&KTpZf?|NMy(ti71 z9fJyF2aFPsidC`;1`L9{xXXG!v=c@tNXAOp4Wk?+g0drq3k2D=&O0V_``Q)54N{4+ zGk-=1qylAkj4((h${XW*gHL&?_JnyJ_>pUor+k*SDIlJe5(x;sNr;TqeQg>@7m6}Q z+LrbFQ{>%(EI*0r7$qQ8D`f|aGLUSPT`)>PGEjDcIJfN7L;da?@SZ6N^pa)x(@4+00000NkvXXu0mjf)rWy) diff --git a/share/dark_resources/explode32.png b/share/dark_resources/explode32.png index d175311351194f63f2372af19c664b73ca11dae4..38d35576a246b1815c7b8559bd36a18fabd9fb7d 100644 GIT binary patch literal 830 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`KiRiV6r%s@iW0)WqZI;uzv_{Owfl4BNT!2~J5m5X9AW#dRh3YS)k}BFT;iA1#jMU=&&rx0MOn6TtZNE# zWMMV;Vm-({O^uP8jmaumJnBbmN>ZBI<+26bu@&!=p4q4Wdv9m)-Ooj5jjQ;J|LhDK zD?fEhE?B4bt5fEE!)5XH? zJl5tme|~diN!ahA-(TXcms|>bExML9WzBl06|R+Ae-^zxwK~$7Z^7wbE7R;BOo@wj zUHJ6Zg1q^*3q5niq=NPbw13iCag_VTW$U$Dx}2V`m0bPg_5G3n4&GJqYqeIyuHVxz zMQuvJ9WAS>{&y^SZx`rkFQ2=JXT_C+Ve2+E%Y3Z#_WxFR`EYW+;?~01BJz#8I#2Bw zR%evlJM~ucu!HUIvxaVam&TlT=KILj;QLIBpXpfa>A1GWxVWOb^NB`cDc-wOqqa0eU-Q2fr`)$?TDe3=M_=4RJ^6yAcPiLNCcsW7pOr*Qo$qlnJ z-`5t*;wx6Y^2FT8N!;?i(61MYC;J7ymG%@heB89+%!1j*B|%(?`A-Bh<3dt+4&)h4 zzi}*N#?9OAX9YKf%CgpN>=2pny!PK(&*JN{9gMiOKJZ@iD%;aS z*H{=r_MX_Q`|1Dv6Z!1FLhO$@)&Nr$gKCLuL`h0wNvc(HQ7VvPFfuSQ&^0j8H8cq^ zFt9Q-vof^QH88d^FnF%(^%g}#ZhlH;S|x4`(+WNX0yRj2YzWRzD=AMbN@XZ7FW1Y= e%Pvk%EJ)SMFG`>N&PEETh{4m<&t;ucLK6TWYDm=p delta 322 zcmV-I0logd2GRnM8Gi-<0047(dh`GQ0U1d|K~z{r?Uum~#2^Sn+dt>ecjKlSiZdw6 zrkD1t@El;uc|81`59dE#fGq_?JOolRcO4NFjx zY4VliR{k2J#B~Am!7E5>x>?zk8oylj0TjRm707g#eO@sIILgi?`W0sVSCxaLP(1ir~wXWH2 z3D`OY70B>?);okqxwa43&Bu1_j1#gtdv~WcqDXR2ZdZY5lC1N?r8FxMi}M0}0V>p7 UFi)gc=l}o!07*qoM6N<$f`B58egFUf diff --git a/share/dark_resources/export.png b/share/dark_resources/export.png index c1034ac75af57fe54d59e2e691eecd47cbd1fe50..a1a51d1e0ab35fb663ac53b182685651aa7793f4 100644 GIT binary patch literal 546 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI10wkH8TU>z@OS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>lBSEK+1*-JcqUD=lFzu{gbV@K{8qEEar=72eJs2)floCC38>M_Qk2FHU0?C0{*zd zMz^_cRlhdx-T881?#s(F#iEoZSL?ZZMiuQiXCoOJ<)9?K?4+ht)4H1nl8z>+&ppv8 zS@g_bf3i*79hslDyb>-m=eXa$xBKOWw#11&tXU>20@GcilVnp-;NNKQf4 z5BppCamSGoGvAl+npmY#Ym8@D8h^%djkdF^YIvt$UJTuce4=60&eGzE`J5s-F o-8uO3t(%FllC~dSw{|Of0Mhoc8Fpa@+yDRo07*qoM6N<$g1}x;umAu6 diff --git a/share/dark_resources/export_png32.png b/share/dark_resources/export_png32.png index 9bff090f458802783d0d48fce6bfc4c0ac938d7d..b27a11624777aff4a67dc58a42a5ee9cf465504d 100644 GIT binary patch literal 796 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1Gg{;GcwGYBLNg-FY)wsWq-oLD=NU6wvH+FwLzSHwb*Z`h&r>SAj8k>C`}h zDIFV}Qd|>j6TZbMWy>8;`ewML7qqX$>$#89^*3fW6Nx3(H?Q+hUPhHSjeJA?g9@ieDe<+WFM=NqMpXeYh@urIsw zWsd0fI|efhFFm<&h)Fi*Dc5U>g5O@RS7$G|oF~zcY8K#dX2N6k*pwGp=Q{aMPQPRR zVjZ*k&i04gnR4#`TQ{)n{gtycJS^;2!rFVc=2tDB{Vm+Hd2XGu>-%H9Rr%u15t}x3 zm-)@k=8XCp*vuQ-@XgI~Kvy@T!aC73) zHrM|K(YAMNn!MAxQW+*cuGl1IqkeAV>6Y(KHMiTYJ>Z(;+Af`V`@ew8mViFLYv$|t z9cH~f^U1bi{Y%W0Vt~PKkQ8=>ECieD|#%?!6$fcHkJl-$nP;g~m!{TSa)S_DA8c~vxSdwa$T$Bo=7>o>z40H`l zbPY{H3=FIc&8!Sebq$QI3=H0=E3l(z$jwj5OsmALVQ$ro-9QZtp00i_>zopr01zfj A)Bpeg delta 258 zcmV+d0sa1*29pAi8Gi-<0047(dh`GQ0NP1JK~z{r?Uz{&fFKM+<>tM)hC~cDT?Ps& ziGCuskLf096CNVkrFC?Th!VP2+!zJO&QS;x05wuh%fXTFrve~KOb75FZU9>B5h+hc zYVv9}E&wa>mI1Iz`Vj>}09Fjq5QG7EJ!_7mjjFcWT!vBSyn8I007f|f0YVCR-3}eW zp(GpuVFL7wRO{r$-uFA|ifI=U z59n0@cNTc`$a}Q0!IwzHDc>VOKxNqDtfvd+Z>B0xHzI8s9+vLhA%P2B1ONa407*qo IM6N<$f=se#TL1t6 diff --git a/share/dark_resources/fiducials_32.png b/share/dark_resources/fiducials_32.png index 8df8779ca6453e8201b7c8e6a0fa6005b5da6f9b..b7ffcae87831b949d4ebca59b2fb06668f557480 100644 GIT binary patch literal 455 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1K$x4W}K?cCk+&2FY)wsWq-oLE6Q&q?78qSP-vH@i(`n#@wXv{d`yNsr%RI? zr?P+GF8jf_|AFC$1-B(mGyA&?>o zKBE(nVS2L*6D(eMCms;x=3smpq5bmj?I4W;mB)O?{cfDt6;bMat=!^ev3um3T-iR( zJ5K^l^j!`-7HBRya3p4yhQON(uR9pkbzbf`{4(m-srp7W7NyQ3tCS{cJnDR+FwbMM zoQqIqkisMnQMG4P!izgyE;uOdWjydS;X_(?`d*+fR7+eVN>UO_QmvAUQh^kMk%5tc zu7QcJp-G5=ft8`Dl_`*GY-L~|dt%pd6b-rgDVb@NxHaTVWvT{hVDNPHb6Mw<&;$Ux CKAHFc delta 174 zcmV;f08#(P1HS=~8Gi-<0047(dh`GQ0ES6KK~z{r?Uqpvz#s@i_2#|#7L&QS%w;q| z;iGz%g?L00nE+d5C^p>OfWqM&}0jyVM{o0IZGx@;Gq4@w5ZB z6ycC0t_>rmA~jrA017}3$N@R14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>Yu6q|3C=3Jj~MA)RJzF*B$m1S1d(o&Z4MT?4^VjSAG zHRevuH1jf<$;>jVvMRQ=gexQ|h@*mi&JUn*j7i?^E({&4vK~MVXMsm#F^~qaJs8|h zX4?T7>?NMQuIx`(ctr&`B;?C30)?7AT^vIsE+;1(VCnHWqj2C5mvBPza|T8~y}T6+ z{Q5HEKFf!@ zl?5wVS#EhSS?zLI(5|u|pMj;#gURifLjseqfoXH)p*u`Ikx`M(jlH@N2hQDN0XT|<))0|P5VGb;lNT?1n) k1B2cVj>l0n0Wbcx1>XaZ8Gi-<001BJ|6u?C0j5brK~y+TV`QKZFv9e6aB$ek%gfgZ2nfK% zU~+%|{$)CU{`|DRfB&vVw-2sZUr&E}U{GNFvuDrVqbp)#V-sDvWa;7jf_$Zhh6WT1 z;2bkEvl;U8^4Y6bul|c}fTyRY=ldT5M@9}NJ!iJ_wNmm4dCJ9 zJH2uJ`g)=aurRa8efQy=2C@PC{QOr=pFTaEC<8h>JI#Lm`Xz#F03##gtD2gcGdK+} zH8q{7prDY2EhQow1Tx_Br_a;Qo;!;gjgeuImFqXHXGyH6sA$EPK|4A+>H-1+zOPuZ zq6Z}%G&D4DF)%QA{rLKW51#=X+#DYm7#OxSG&KAGsRIE2?e!7vKn$V)0000k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1Gf+eGhVt|_XjA*UgGKN%Kn6fSCrpMc9Q0KpwMAY7sn8f<8Onl`3@O~6bmvt zIVL@2(|OZl$tE2Bkj-FI5%0EnjT2Y;$Q%$13{*8%wByZ{P}Vh6f1RC zo)0l@(YJqf^#4=88P_MRn85C<8K+UD%d%BKB4Elkk)^)ej1B2t-fL$D-^z}We59et z{o+Ad|Erl7`+W?K9+4?zos%n=B)a&Z)M1W3h3*X(V<)+C9@rJSBKMNg=Rl^FoWIWo zv_DfUlla{cTPsHj1y`x&<8c~vxSdwa$ zT$Bo=7>o>z40H`lbPY{H3=FIcO|48VbPbHH3=H(tzbrt}kei>9nO2EgLwuEw3{Zm< v$cEtjw370~qEv=}#LT=BJwMkFg)(D3Q$0gN_s>q|KvfK$u6{1-oD!M&@@YHyRE0qf#_G z81^^Ruk$jhg}f@ceo26(0st;+ivXz94FhQ48VD7DCechSDK;EHQeqoGFSPW`NR49v zvsU~IV02|)a~@G36u>f++NrlGkN}Q1;h7C?6J`tO3Zw_`{X+6Wa+-R=fvQ}?^o>47vjVMV;EJ?LWE=mPb3`Pb<2D%0&x`rkp1_oA! sW>yA794jnjw69rbWvXe zcPQW}5*Xka7XkRh4#ucO0{6&az8>NWvS?$LGQ?e6;SDDN_{JG-(2oR4XyEa04$6^V r=>6xwuN-V{;WqM^E;qNZ)j6*K7Xe0mtyqal00000NkvXXu0mjf_6}yC diff --git a/share/dark_resources/film32.png b/share/dark_resources/film32.png deleted file mode 100644 index 8b5bf3232332febe4d883e21688396bff2b5d64f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJDo+>3kO=p;(+_eTP~dUCZhwA$ z{+k6Jno3^2{2w*8*-ehRDEG;LL4Wc>J_d&0Qzb+*i_}4MA6+eH&f9x6%?N+WGaf@9+sk}W=Sd%q?wYNnP$-~TPn;l zG<IcL7}&pCy}kU%}{ zZQ1|;Jp$f8T!qZft_f4cWY=nM6~K~wf_(sZ#L`)dRafN}@%Zpy0J5xAedhsCswn0h z0H;s@ERX>}-vq!ot+Xx7Lsd|V3kviH>jkW*-KtD04Sz5LfGydd9immk8B~!PG(s>= z<26jr$N=>*Q1Bc8^@jw1pNP}qx1~`j@JK{&cdi{=4i77V<66(}?Sx0PQCzAWt*v`) z3#%eE9~AD@4Ol8K++u^PQr;sN5^6f|`*gdA4vs!nQ;-2NJ3PwHdPC&{%Siw0bOT{i z)F*7i=sRiu)BgVcm5IvPQTA9yf9Z#=iGFv?uzK-tmRN@udvBDemBi}jJeZQQ?Mn9C zCCT!ud|)?}_BO!p$9$XnZhN~47*3H)eeICcx0n*0p2MES|DuEW``*JgBPP>Li^?CLcmjip(4+I7i+7hTJv9rQgr_(h~H?*K>9NI1=;W=hRs)>1GkKUuA~ zl+rxWy25KDH%1}d)g}YRwi}v*4N}i3zY{+BD(ZX4k5!ECMBOYj;`ke`YvxwnnoMCx z=WD=ho_C#*@L20d56(g&_wq^)Db3Xem&W+W`W%n<4~?4@QI*qB=oOA!J7Pz!l=q1V zk^Q5SgvO=`AH8Wg1rUrykp>udGLt}E4#Y*3(RT`rykBB`J8OI9i-tiwUwgF_@Cqk?dF(77nnkCOiDD`-`L=l z0)!*XmPV-tR_JICv+Sj0J5k~yICC+>*!rUNZ~T6^SX0^b?KG?X*h@Y7%*UoDaW$8n zQrKk>*`kv2L=pNTiDZbJd^I=Fd?qD3WGo9fTSL?Nri#JRjuTEtu_hiJ3H!+p-aO6FE|A^fIMUX&L$TRGD)2C=C0 zYxS_;(^dwMG|O!(LDds=oDgoDq#W62c6YVF*vlClzIZl^Lhsv^FTcf$91?+hsZ()9 z`RW!W?t;+l$?=jP)9%o$jxXyJt;>a?GQp6?c5qWT2~TXnRSShT-gMz|od9}Y}c2Q;cgf6{2AFKDy;?ge8nB4}D- z5U&?lnbLwJXNyPENrMl0=)9LG2+SQu|K*awu;G4*Tyclzn>_s((^v1oT0Vk55B^=omK(FDEbaWOd>zI~RT)FYr=#)!4O+%tbtg zASP>x?sVVnGSefz8dvMiNvBzUTLnId(%Wxe|me#Pw@AY{%5EE$^uIcU$Hf_eMUqI5^m0pNF301W&_{-ZiIDcHvgaq$y&-& zeRC@s?f~s*EG+>YPfbt(a6&nu>`=~jj?NJ%6xz`R?d)cU+Kon`B$rpP|2IHMJ(`@D z`R4=I2ljndF!`)NN=>9OVyOv$!C=@YpFEKfADfn7pGr;Qyz|(mY61jYi2uKQ$$7s5 DsEh>s literal 1735 zcmcgt>pRp57=3?3a*5Dosv#6bBkLYXhD9_oB1X9lWf;`XgDxK8S8Fh>ma3PmaI z<~2v3^Z89Io8y&L4=a`NdN`uO<_vX(FX!KVc4>-9_|wQ_QEjoqq|LGU0N6cg9Y1U;`tZg7XMh7r7J|{CBn?Y0TNz*%G|CT8i=}}F1YpxRQb2g2VQ)Bv==<;anv;o*ME+B-Wvh(v|pQ>R)!N#^Em zq@}0RA|mt~_glpAMS>TSJI?-MwOV0jLRhKB_U(PuUxY%ID~a@3S~F#|v!kQy?OXMU z@$pck(Ccz_wei%i1y5#UyuvN5~a#@*NL}v+y zi^+P3X3k}oPDk3i-YMS4^;VEOc9(&#(g01PO|AI=cLr362rx?x7o=fJdzQC6IJq#Y zb^|Yz+u{y{pgpP92sqa0WMM$nBk+?P7~b4lwGmj^@+V1v3L=0}aQGht-9&O2U)21H*R)}AAkG=r}oPf8mV170_ z+ReeiK{PoK=8>F~l$3p5G2TxuP654T;x)NTJT-Ntr?a}Ix_U*4ES}%1um8Haxw-CJ zj5^u6f9$}(6Z}@OSR5T6@0yd7W8_&n{1v-#qhxM7PypQ-r*r4ty_DtU<*_{tj~^H3 z<*DPnkYQiUBR;vb>}pQ0t3T7fzP{en*mz9r$-@FYsX~>*;S@DAG(1{rYHCW}7nz-# zD-CVP4b-I~bJw%JMtMsmkA1Pfy6MhXJY@Vf*r&4`T-IKtl7!qQqsI~}4v=vce!jkL zG}^~H*@FiU^2HKvU7dL46B*NjVU-DYmX>ok*OtS>!j^HhgPfYWI`%dkj$cysDFVcgcucwsukdtyVDay{k)X2ereyl7LAD~>O9`BaiS-)5i+EHU34{|nUi}R~Z7#}` zf-cp-nYCbuGvKHJD@!)Y=0Be3*aTfIg&I+7|3yEkHp|z$%1w%XlK!?5;OyXPUv5Xa F{14J$3XT8( diff --git a/share/dark_resources/flatcam_icon16.png b/share/dark_resources/flatcam_icon16.png index 0bcc34abf767eb8fba2413036252e1b5e10f2e79..21a7c2f044c9d4845fe5129f67e057ffd9264e67 100644 GIT binary patch literal 464 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L91A}c12s3`*h~EknWH0gbb!C6T!YeAkn^D>n2NXK&>EaloalUopSuV#yfur@; zufK}gkn(bx`G(N0pediU!py?r4l{droV+gWA@)hA>{Y#YM{;4lUg6BkCZ=;UpUv5L z+&SP;n#if}{@oipWu5wekNg z&s?oiXZc}cVaocq1v6qBIq9={D{e)=r+O@~qZ!JpoQzt!KF{j2lOZa%{M6zCn*64!{5l*E!$ ztK_0oAjM#0U}T_cV4`bi5@KLrWoTw)Xsl~sY-M2J94opQMMG|WN@iLmZVg5ZYvq9& O7(8A5T-G@yGywpuHlMQq delta 202 zcmV;*05$*61KRpG%++aH8G^6rC~P! z<}_?BLAC_L3ouE124FK3!wcvJ5Hc960mx20cI?NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^+ z;1LNlk;NQ@87D;ZdI1I5OFVsD*`KiRiV6rlt?ggUz`!W$>Eak-aeC_nLw)B!iMIK{ zxypq{Te>{*js$deE@b0m=B_{R%Dm&|dI9FeEsgRC4o*oKPDd{2iFG>ixa`}^aXtHj zM}D;Va?bbPYAfd#-+SM>f4bML3!91-eq;S@G0}7S{mt2RozC`G-M++$ix;17TJdPr zg#1nOe;V~)jK1}reR*a2rK?8+tkUl;vHiNmHOlnn^SLGScR5AReXFosRW>tt>6c#z zmK1q#E=+A@ka~CJ@A`&E)3wWPPn_1uR+48l^G|N#mGv9%aXktC#&ld{v8B+0klX$F zH_ow0e4mlpinR(g8$%zH2dih1^v)|cB0TnTLy85}Sb4q9e0EFAw+yDRo delta 298 zcmV+_0oDG`1iAu{8Gi-<007{3J@^0s0Rc%wK~zXf?UXMLgD@1vU(eBtEO^2xP#ge5 z(7gg4fyQD90tseEAc1-0To;y=w5;u;`-W9a5_t0>uh3_Vaao5kw(33& z5aMmyLf3VWBnhB^?Ts*(P1EqYu1Vkb5Cnk&xpUwuzQD(Epnzz84^J-{aCbqD4H*vQr$# zbep#>GAqC|vcB&_Q4~NaRUVZSz}CRBEYHI*9Md#CU@@WZKo`SHdSLpz_Kc=n^N<4< w$mamIPY!FO%_Gt3;14jx^g|K3%(hGI1uIXW8RI_^o&W#<07*qoM6N<$f~Km9KmY&$ diff --git a/share/dark_resources/flatcam_icon256.png b/share/dark_resources/flatcam_icon256.png index 77d3840f8bf7f733996e7a674e8f1d7d30140af4..2cd088e657b9be8a809f95a8527bd9fe3ac0db08 100644 GIT binary patch literal 3820 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 PKt2Nk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSrgKZ56Gk)NR-wG6DFY)wsWq-oLD=NSscI4k<1_s7Wo-U3d9>EhYo3#ee2S25)+N&ejB8@EOOBi zCC86;jyKO*i)~JxlX7fsBJaImp7;B9roY=+FQIUJJL|`W$2(7(P86^+ z-o9|Yj>W!ZYZnH)`eYm})1Brdrpt7vOYQDCr7j`03aM!ycLXuyzAv!(cwnZEie}4w z?r?>-o96C~GcXj@+uu_xx6bv!*E-J0uV(l}O%@le$g5gkZuBzu-R<3b@;0s5dg{R& zW&W)zeQmEzY-aIR`+DVvsf}&JXz^ zK7&y~P5jz){{u(AaQADi`s6NdW}@42OU%de9Fv-@_IvM0wznUe)|Pa3IM3O&xR_ye zsjAP$S>G})pYD66S8C}y-Mp03W}dFy)8mU5IWNx?k2z^%s+5uNe?kHShlGMjkvgA% zOtPR;w`X2k=Chqq)~yd6=9ovCyi75(*=3!ywqE&sf_QyA3t}&3@C(pkCMMG|WN@iLmZVl(1w#xuDFnGH9xvXgo;9NsK*TK#Ankx`WQbypyr-dq|Q5!Z3s=itYv2+qd6k pA=Cic0qub7N_|tW?B7rn<_TTw!y%W4;}ZY?002ovPDHLkV1fX5l%D_q diff --git a/share/dark_resources/flatcam_icon32_green.png b/share/dark_resources/flatcam_icon32_green.png index e100c6aaade366de8a7c8624e045bbcd5bd9f8fd..e52b756ac1862d98fcf11ffa32adf926345ba04f 100644 GIT binary patch delta 483 zcmaFF{)l}-YW;s8(EI;S_a6{J7++Pseo_7c=R%}jO1!+taPgVwGYI#u&R+-vnS3tx z9LR+j0yh(`04@S#KoCfAJztPCx64UDY} x44&(Hy=7ovP%UwdC`m~yNwvz&PsvQHWH2(opNS%G|oWRD45dJguM!v-tY$DUh!@P+6=(yLU`q0KcVYP7-hXC4kjGiz z5n0T@U|R#ij2}4Sw*m#(OFVsD*`KiRit?NG>YBs>HPw2$IEF+VemniVcSxYfar^M) zXP&A4opeY;NF*z9;lysS*6ur7Htkoqm2y%3!lJ2H)C^)=@>cn-?&#o{870mVB)CH$ z@RV3u;IfkSFJGLgiMFu6XR-M6vgZNJ^G;Xqsowv5?)%-(=M}%Jbqfj0(#olK=FHM| zFX*WD(|dTtIVvoX>%QO3_hDgXsi~>ySKqq({%|ep(~vUE<+-fM!+Z?ny_+SbWL)J)Xh&8V>A`8lnAxv+%Xs+9uda_i!TaUUhUaeL&RqI%lhMOvb2oBo&)#5fs<63C zu4G3!$K$mgoSURBp9ueD-Zc+HL)WeDexOh~ zRoUY3jOzDx#fBY4Dh+Mx$L_1>I!$4sh!cE8I{tvsMe zf&Yh3?fYJ`w^c5?`YJH!n!3fqdrXDv=kI)z_4diFDN$!y8X_3jpNp>b)7IX-gxhJw z*>h1hBj=vh&t18%#Ia`GuS=~3dnM-_Nj|vyNWi}hFF(r_v}hiS`XOuuetQB0lupkDdJn@GquAlvZ zPtEI>t5-YC4%|EUyxfv?ZHgauYq+Ydo#ddDzb8tpa`JPYeY#(Vo9o1a#1Rf zVlXl=GSD?J(KR#)F)*+)G_^7{)-^D;GBD6lSP+GxAvZrIGp!Q0hS*w(XFv@Mp00i_ I>zopr0Kgk_SpWb4 delta 600 zcmV-e0;m0o2j&Ej8Gi-<00374`G)`i0xd~IK~!i%?U+BW0YMbS@2H9Ipde8xG#ZUc zlp2Xzt)XJsyhv1{(C9=|N~K2BB%A0YzJto2sODwl?FMgm&E1(@E1B2Hn_1^~&zU>d z68Q2z^5yy=lmNP}Q(f1&v~ev8!X+l!>3iH@LIL0=-h^_32!9>Ga=C2R zLI8e>XW|x%1*}#ph{xj=!0B{?QmF)mLO~3`Z}CiBuh*m7?UrOR87ngT{T{N}ENwQM z_o#bvz-xQsJ%0y}&!0>tRMRw)PN(5;I6%MOr@I;Us=zr{ba$frACFc`q~dWCko z?RtROKOMV}lX%`6lGgzzh}Zq-dmw0lzl{I8jo%dv<-og#VXH12x|8?|_DhktYXU0p3Lc3miHCj3DgVKpen|!mL*SPCvFW zRTNpP98pjXh~x+RR>JJ}*n2=wqw99tGk_fvJ{cng@bF>^{irDu$E*0000+HKFxFt7N@4&IJ*$Y;M7uBD6 zv65}$nN=cdQXVB_DCx4U>`YXZuKv8X>B`)4n;#+*R#yIFd~?tAvhDKOsgv^=#iWf4 rbPY^&4NXD}46F>ztPG5G4UDY}4En!|+D=}8TmIjwwT+W6G8zH^xgLTm delta 306 zcmZo>X=0hsS^t=mUr5<3{g{d`0|UbaPZ!4!jq|w|*7`doim*RupDumDwH8~cm1?sFYVl^FvI(b{=vzevNvW{*s!OYnlIZQYf!qnjH@bb z+yBgHWA+1SPZ1sP)R2(n9_vCNzA@LbIDtOM^N$*sX zZDF0Nv(Rg{nESIMDixVchnBfF>l%MM5&V*mx!un6nvdnnumkmnmUg=y>H6HhU~}s>-Kib_AU`8+^t-TdwSf1wW_qXL+rkxkYQ97^f{cI%mZdvGn?d62YN-d#5JNMC9x#cD!C{XNHG{07#ZjqnCKds ugculD8Jbxcn(G=ETUZ$wY!@=zfTANeKP5A*5{C|;hGYJnJd1_p*3o-U3d8s}RtZuD|0lsWqG{M$IqMHw9qw_Mr_ zI@&rkqMcYK&O5YJ{Y7k5gWMv+js==JD^z2olss}LbSV7iRjb&$-RklC?@!Cm^$Y*> z?Oe5Mu}b;Qgv;w5910SP*qH2nf2Vu=tIG~cGU8pY&rDBzWD-`t=E;Fs(aYIhYKVlq z)!cFIqhYdykgo5+rR?)h&2%|>Vxz0Aa`DdpXP);5OU^TyTBq~q%s$z_!k<)*o#>Wc zzfCsknz!TDlNT4PU%Yxz;@txUViMUe?#&J5mAKa(;8k&X}T38vITA7+?8<14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>>H5h(us`}ZS9j=X;J8i*c0dAxP&))gyOym|X(=FFKu z^4are8#itQGL|h{He<$&Cr_Vj+qUh+%NIa%)~{cG_{iZSM~^I8wCLlB6ycx&^TDNi2#@)Mj-@bGE z>b0u}4jx#uW)0AMpt9}Tx36Bkde^R9K=z$Gch+xM548Hx<3~U(4<0<2JbCh*Ide+D zptQ7f?%cURKbn2(mj`;;rzFTPn8EA9c}9-;3nlKHv1h#g>;|*MGsCAR*`G@o-e$hf zFL3y%*~6PR@7#TKy>n96?W()aFE{5sDXhMFx`pk|oxaHv9$a85y7%;MDwDFV0;Bud zEl+^vGA4PuyD)UH%6b4foCO|{#XuUw_F!;3nQaGTu$OrHy0SlE;T7e#_&mqsF;Hll zr;B5V#O36K0}MSrXLKC8ruNQlp4>gVv9W!6e>{VRf`*EU&LQl7gH?Zie{jnxD=iq^J^Ufcf*m&^d&7-ayJTWmbcN_A`zJF+8*3V~S zIR02FJWYE>I?#oxC9V-ADTyViR>?)FK#IZ0z{o(?z(m*3B*ehL%Fxux)J)gF*vi15 iPNM%WiiX_$l+3hB+#2{@&4KBbfx*+&&t;ucLK6VLS!T}w delta 443 zcmV;s0Yv`o1q35z~UgFprF8!kdW{l#6ED~fTV+i!*iG%NF5_gGe~gSlxa8Z9qqMOuU`EZrYJNt zR6<)@8?5QYix)-`5)$V??8y@*pL+Y@tvREorzg9)x%m%L4S$$2dCDC}Cr1qw119uM zc%ZDRY;gAM*^e+61Ox;Kyn69!^M8i_OsZCQeSy9|!jz3{1;NQ^9J$*|TS>jg5_4ae1Y` zxBrT@t@Q>oGk>!htOlGve?H&P&~PHYv~~8>`66R8!@fakz@bBjYVO{?8FDo_!K79D_*VfiHA0#(_ z{``xHiHSzwOp~6TUbKGQ`kbunEJb26=ggTi?}dbfbTmw!Jb5-OH!^W?aVfH}uy7G$ lz|WsQKmYvs^FAmy0s#6N;-?;CM*9E&002ovPDHLkV1jfX%;Eq5 diff --git a/share/dark_resources/floppy32.png b/share/dark_resources/floppy32.png index 0c1e48527f3499a08d4b804366c48df960f30911..2b49aca66d2f90e8dc256037c0a0d9bb8c619c82 100644 GIT binary patch literal 531 zcmeAS@N?(olHy`uVBq!ia0vp^GC-`r!2%>#@40XiNU@|l`Z_W&Z0zU$lgJ8^O!f%! zWnidMV_;}#VPNKtmXxp6BNXwi!a-*aGmu_sPVpoR5fcIQ@Oi+Lv!=2;BMzaJrR|8ZRtPc ze#}#H^7wnc!1DV%`S105-;0Eg72S%M6s>MxD%rpCv!9s7;)8Ju9?fCfeL$AAE99fv z=V!-P+D4q(l{M|^!doUe@%OJ>S(DswJ)wB`Jv|saDBFsX&Us$iT=z*T6*A&?Lmbz{=3n%EVOHz}U*b jpgC&lKNJnQ`6-!cmAEy0V%K#7YGCkm^>bP0l+XkK$YsC0 delta 357 zcmV-r0h<1k1oZ-t8Gi-<0005C7(xI50X#`WK~zXf?bp96MPVGr@z)*6&tx@N3`Q1Z zVpbA^m?;)ki$%&H8yQRnB!iOODEuz?(!QLCU-lR*yQv^q&T< zqdg^uE7(M9wC^DlPRL=d2-onIu|MW9loyzhRd;))9R6S6C!U)KudQYnG$d(g{^cfs zeRzug4FR`tonD-U4Zc7ai{p673cSTpgOJ*70T_mQ2^6lU>hKOZEG12=r?P0il_|Vv z2CyITC%DH(j>dn)BF>}l6~ZN6etG8*^9Ps0e`dY_hn9CC5osu{00000NkvXXu0mjf Dr_!Gs diff --git a/share/dark_resources/folder16.png b/share/dark_resources/folder16.png index 3da9da26e4bcc553a515408d69394c8a621b6aa3..31c0e7422927ca199768d5599feed89019a1297a 100644 GIT binary patch literal 615 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>x300>n7(z*&K1WU?SsxTA7|5V?{GZ8&&Vpky2DjM z=PZZK{tM@iN3n5pvG4J*Py(93nB?v5!qCAg>jC6&7I;J!18ET3gTd`&wjGecUgGKN z%Kn6fS5$zzQA|A>D3syp;us=vIXOXr%fQIcP`N^9P0kw`nK?0c91a}j7J2YkTtGxf zNK8;vSXg-agp`B{lcr6aI(hPBcJ1(hlz>S=ZbrV2tzJy4Rxt5oy^<*x|)$Le7LQ+!K(ZvjM*1TVJUuT^J+NoON8c~vxSdwa$T$Bo=7>o>z40H`l zbPY{H3=FIc&8!R!bq$QI3=FOuV(CKBkei>9nO2Eg!_xVC%zzpgJYD@<);T3K0RV#H B0A2t9 delta 351 zcmV-l0igcp1n&Zn8Gi-<001BJ|6u?C0X9iQK~y+TV`QKZFjA}4U0wZv zo}QjRBgpv+<}Wzm=I&-UYu2pa#0DzJ08LHJfKdae5eA@8*Vi-L@%qin-n6u|UBtw~ z#EBDi`FQyjI#@b6T7%=ezP{dO&z?QaU%q@1BwzqI#j>-r|FE;Oo7~gWvkabKLPJB@ xI5;?1@fpC$$q6&y@8rpoe}eN1F;2#(1^`1?mq`*Mn?L{n002ovPDHLkV1g)Mt6=~D diff --git a/share/dark_resources/folder32.png b/share/dark_resources/folder32.png index 10eb3f360b117a5d4c917140a05678d603f39f52..af0da2d8d52d988adde3eb34282127bafcbfa0d3 100644 GIT binary patch literal 525 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1Gg{;GcwGYBLNg-FY)wsWq-oLD=NVBzE}JXUX~eo__Mcfe(U_ zUOk^hr4L`Pm(ud*kSe&|@zI1?_;MVpc*@FZKb~qyi5cJi-EInf{Qm#ysd0|HJN7@^ zzyHSj?Y}-<4-~x{|IePO|LN+fhZbx+pmFHHhgTN6%GlVZCAFnj@CZ0}va;!T27Qxk zzT+I1Q}sXpXL_#?x5dHupZqsk-XBz+?xi`gNyhX;Wuq0_A8Fp^iSzgbc3ymTk6q}? z#|07xzC4v@W;SNF@0?cOB>iFkgojef+MT!R|IR*ofI)xiNp@y=ZV_n)hUb}{GxfyV zfT78tTH+c}l9E`GYL#4+3Zxi}42%qP4NP!Xz6S8h>ymP-SIhr`Xuoy)d^0>IT2x2Wp zR=0TZVvqws=?uFA@cABQkgTk%RC03iQ*s;t(gU*tYX}hI0H`7V7c5vHNUS3g5)$5{ zM=?bXAl70eOK{=QOqCEAb--u{jE2By2#kinXb8|O1V}ZQ9QAl>LvjoxMbDx|i#Ff8 zch3){MWm#pq{hg|nELk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1K(i~W;~w1A_XYOUgGKN%Kn6fSCrp6YpP@<0|TRtr;B5V$MNJp=N%*y76trQ zFlb;sR*~`1yhrftj{oQ7zu)?=c&fp@>A$&QM-tl#9cE|sI%WyQS#mzVr=L7<;DcbK zSI=ir>BHCSrL_DxqzbNgd^BMez8uFYp0cvqkEdEvV#c?Bx0^yAzyH5_YMdkQj{Oh! z@4xYW`>#*e14Zw~|FdW6f4X|=p#>WcXdF85;g!X%GB&npNp0yBJOa+0tZX`-LEj{s z?>NWhRQ=EYncgeJZE-OEC;yF>_Xm~5+Zp3G>}YQnob9ESbMAkWX?vo$s-k9cIV1N< zDUAZgvIB<>0A1LxVgH!hWzm5IUY8C=mlj67#~t4eP5-ab!dQ0OgNymmpZ=_dvwQiE zWF;jeJa9B@czN2MjV+C>PKYM~2!61bKd4tcZ0Z&!wDtcl^X^8*IIYS2Z2Phn-(XHiK}D2?#=8(JG$lv7A(Y!3Va%`JK$6hTAn6&xVvH{cA(x`{ zO?5Q@RaLKD*FEba7{{@aW!ZC|J=NM0z%Yyh%d#H%B0^|mKy_U|vTgf;*J6y%MFA+K zUjTr+JkQ_Qp3(#%M7c;11p7r%Jhh2xns)0rjwxzft&5_F0kE7k1GL>e7g7{u*Z2LG zApmR-_h{^Z2!Fs@goa_b5`}PG_v817w*n9~u9%i%9@GKTG)sXt^CU?c16<8nZvatq z4%P(mZvc~bV3R>tCPwSP>;PSNI{65?0NDBx!lo{b7Q!Ki5I?#HAH}mDM2uV%Vv?so zB>7!6!Wrli8e_fnWi*CCn+C@Co)B_e`y$dbZBLfvQ!h&C&XfR@(oX=uO`hjj4PZ*s gHtprtZ1xWP09@Y#Fsi*W=Kufz07*qoM6N<$f|(4$c>n+a diff --git a/share/dark_resources/folder32_bis.png b/share/dark_resources/folder32_bis.png index ce7b57206a616ff97945ddcf36139ad4c979e058..2ebb9f7bdacd40efb8a1443ed53ca66670b22b47 100644 GIT binary patch literal 604 zcmeAS@N?(olHy`uVBq!ia0vp^l0YoN!2%>N)y0_sDVB6cUq=Rpjs4tz5?O(Kg=CK) zUj~LMH3o);76yi2K%s^g3=E|P3=FRl7#OT(FffQ0%-I!a1C(G&@^*J&_}|`tWO>_%)r2R1cVumDr>> zU2E;X`B^=$V+`(gb~u~gHeA(Hru5e6(X9Oh@aF zYuK!|yZdV`J(*Ioeqo;RqUB#cmh-BoFniB1U*d6YeVbE3zI)r-77^aHPmerZUoc%?amt z%}*##StykM?OVX2+O?iR^*^=cDola8jv*P=BH$)RpQnV zb?ei4paw~h4Z-BuF?hQAxvXM*nWB9562q70S{7UJD1=mW`@2~hyZs!~Y@ t1a5o?MCpT~vWpEurfwPaOfy>(ArD?fn2-oDEWrQ(002ovPDHLkV1fcqOn?9Y diff --git a/share/dark_resources/folder32_gerber.png b/share/dark_resources/folder32_gerber.png index a3a0763b3b33158df542ca7c190ed093324be2e2..4d63db6d846976290e6cab4bb4d72f8ff4584761 100644 GIT binary patch literal 593 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1K(i~W;~w1A_XYOUgGKN%Kn6fSCn7prQ4i&3=E7eo-U3d9>zE}JXUX~eo__Mcfe(U_ zUOk^hr4L`Pm(ud*kSe&|@zI1?_;MVpc*@FZKb~qyi5cJi-EInf{Qm#ysd0|HJN7@^ zzyHSj?Y}-<4-~x{|IePO|LN+fhZbx+pmFHHhgTN6%GlVZCAFnj@CZ0}va;!T27Qxk zzT+I1Q}sXpXL_#?_lpPIcPtV$&K~X%vioo%_0W3R{St>5l!`=FaZfnZS)zL*#(^>6 zpnmTMOTF&~h6V-(e}4OWSTA%~q9DRi!I*SJ+-9T8Qimg1hs772ie96qpvU^)E7LMT zmE|r;v5f`?p50@ABzx{aa}vYl>GeE3XL$aoNE`ry51e@i{yVj0_pDLL`u{awjG1{) zh?+c4%~iLJj0{PK!;egGJ@gqE#HuB(5hW>!C8<`)MX5lF!N|bKK-a)T*U%)yz`)AT s)XKy}*TC4yz(7@Zo)?OS-29Zxv`X9>LJHKr0W~mqy85}Sb4q9e02t}o&;S4c delta 441 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 R;$GwcQLEy@KM9rZ{SUqz+?D_U literal 10536 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 MF6W&E+kJlhFTUg|p#T5? diff --git a/share/dark_resources/gear32.png b/share/dark_resources/gear32.png index 0977265ba4c3b0c6573989be7a862df12d81a4b0..a40b09e9018f2bf1190b7349d49511f7532ab421 100644 GIT binary patch literal 876 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10;&Xsch%1m*R#RhOX66$V zWMpB{)X`z(;E<4(=HTZ3j{|)E{25aQE(l~m0HzwC2v7=59FJl&m1tZ{qmUIqjJYlxO_wL(w?b@|Xn>XLRdl#t2t?0oDptn6sg8YJkGz4rqA7&H|6fVg?4bXb@)HWT)H?6l5>)^mS!_!on-cZ}LlveqVTtGxfj8RiSRCxM?BU7eN`u1hY zM;7Ktg<}DV>aRPwo?H~s&~Q@SqcCNX(Jn!)RSt>yZfa_28<5U|8bd zEF2o=Ev<5jYg&2|^X!F-yVp4I>l|ZY6-a+Ed0~U>ssrM|jg1Qh4{->bjyS<`R(hF2 zepS%{9fQLhS;ZYk>*oDSxWyEEFNocAN$A=OA`!P2Xg%2EYVLIZ*yVHg7*(FXc+%r4 zx8l&f)`Kid4op4hE7xr!v7?$nw8QWLewWA0|F>AgTNtCqM%l%yn< zq*^5xr2;7iBLgD?T>}$cLz55#11m#QD^nv~17j-#gRbz^?@%=4=BH$)RpQq0n@bp! xRU|<+1m~xflqVLYGL)B>>t*I;7bhncr0V4trO$q6BL!5%;OXk;vd$@?2>{ZfrN96H delta 437 zcmV;m0ZRVt2E+r98Gi-<0047(dh`GQ0gFjQK~z{r?Uuhv!$2IzzuB@x2Me9VP!M8Y zqCP}HZ8J$q%{!!!k~Kre5Q^A7N3m7~6Ym#=5q|>6669@R5eP0oQSm(- z4}u9$R$K(46oBV>I8_wf_4~{;SS}Qb;AOSK)c4V9wSI&@!w}YJgtJB?1#<8RR?8)x z7Yj&Intkjz0HwW<16ldsbi2?rjcR!mML1Vgn5IeXr-5WfKm(XeCivKHnR(y#dbn!0 zs{!zRAMcwD6Mx{|FmR!&)c}xL9|i+7o6Ss!OHG5W>(v3g1pywXQ>wshK1Yz@P*x!p z+J;|Y2xmNoEX#i&PqP^Y!yzoo`Uh8P8~$D}saubm5n1800000NkvXXu0mjfrAod% diff --git a/share/dark_resources/gear48.png b/share/dark_resources/gear48.png index 9f6ab714116a8deabfc3402eb9ad4daef22fe9ae..c6319fb10fdba98286dd7c9ca5abc54ebccef21b 100644 GIT binary patch literal 1146 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)pT}UnMXwSj}Ky5HFasE6|34fiXM4C&U$~fSrqrftguN zQ7cO)F7)wX2Z2%3c^L;47g%4 z7-)vz=OUYrrV?2S$VQU|a?hMSyKDFEO`A7w*}8T0nl+a$Up{*5*tKidPMkcsYW3=! zyLJ_ol-#|07pPZa@v~-NaA%bS`2_=MIA~fS_cnyPQQ5qWEnx>s?XQU+E~Vdkb86C5 zMzh}Eu{EohuYVEd`m4j9veKgA;?)xZ_LWN?J?M)!R1Mp8{*TEu4(*>ULg$peD;!8V z`=o?F8OY%*@Q5r1QXL@7SUB|! zA5f6J#M9T6{Rs=Nr~q$9X;U0fPmHIFV~EG`x0A1jA2JYWUmsZ5{JsgSzdZN%SXuRRZM&Uy{*clkeO=}M zhq;v2tn2*g!L!8eiqrK{yS{qWw45Vm+b#C(-Mo9d{!`P(4?b`_n8B@n>&VNSmL7}e zXUyRiUoh*yQoR^W?tXOQO=tXwgLq7P}WQNy%m?goAFa((0C>xTGB9 z%Jsa+fFb_Ab(0gumjNu2{ur;Jdgx5 zP3yXmX__W=PpOMp&;w(@1a)@Q3*I!?PcM>+?*yEn76hvSw|d?~;mZI8$qQi{J#HTE zf}r5-rg=t+%Rm_L{mzM3qIb(cuRE@Hyt7jukB*QU9Yw8PM?RltIvPCVV=l;*0E>Zg zxs0l=%E?}hYHo+b2Cai5Dv?B)lo;bUJu6F#%OoNj;T_Gy`u` z70G0h1hNFrS64ALJx%IEF>rWrfN!l931b($+up{Xn|~X!CKLmoPfk!jJ0oH2g38Vg zeqUdcHK72@agy% zjam({Sd4^vuj}}Ec}ePeFHX;khUpfv@8or*-Wwjq+pR56uy(tRshJrR3WdHps^iWg zZUeopxPSg1YMq~Bw^BhWmHKb5Znulwy*>Q8x{~q&vliht!17Wn7K>PzpGPK>!2?A> zv)RO#(^KSfIdW_QPk_Y$Nl6HJOmHO-20Y8bwfnzY2B-rpIy$`FH}zZzSb#x|63^`W zzJ=UO@O~F^rs)UXcLH`3qF?4j$IjOXd2LFKmqXu9yX`66fY(8n4KF-GqVdb9470W1wPlt*e_ZfNVdDEAd-gwn`n1yLPkqq;3rcOXZfZ9c2kx!-Z04r0 z;lV|>P?qD93ie)~m*f{E_(1rafc9>8D9m zOCJ4tQx~qrvg_ggPFBUp>wmf4Hk~U9UCY7oBf@t_CY#KGUO_QmvAUQh^kMk%5tcu7QcJp-G5=ft8_|m4T72fw7f=fo6kTCyIvL{FKbJ XO57SE?k+P0YGCkm^>bP0l+XkK_Kfvr delta 680 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 R8-W@aJYD@<);T3K0RY9$1+oAD delta 1004 zcmV{ACoA8kbeSc*CcmeqTMSwB(C4e*l zUjR4+uunvPd#kmeMSwAuWV6}y5{V?8JF{A?4yjZc!k?W^=P!aFv=EWyeGs1jYPFg@ zMJ0E4cRL!5Ce36rQFnJYZEkL&p`ig&Q&Y&x%Y#;{wTFd;SwvARAR?o?&42->r>9{w z8nL*zh}zm(bboesK4PAjn85P#vLhiO;SY&K@--1zA0`D1kei!}n3x!(q@YxDVbUNJJ+@PkW2J!LnezO%97l*2e(tM@Q{~AbdhZHohRB6dWBLVRm*FGJly2DwWDF!2bR|3x>FL4N)|TsgU0oeAGczAS+}_@zx3`x|@JAwgg#9hE}TuZ!G2I<>>G42hZ#H__*s`QGZbpR#sN9y}gZ#iwh(tC!?UCz>%1k zC=ihrzz+}A?==F9u{;1PdcB@CHa3!bzTL@rNCyW8F*Y^^i{;-IZ#J8uP$-a*kpa0} zj;pJy8@XKmD}bMfXwy@E9?6g~mIYvwhqtt})MsIFXFEGPI6pssG;d&F03972yy|^Q z-G38+V7J@<(r7dhf*^PWn3z)hnJ!5P>HZ~UZ_4OVZxa5wHk8yHx;xkRp1^CqIbXt^3rO4&={+OJc zboB$3O0_DJ$#~HQHwE09&1PHO-QE30r)AUent=Po<<`{HWDN-ki6Ej|pCRz`(QAb= z#uSXPSt9aSi4KS3ttg7G198sR`jiM`ObUP(q6mPW@7(Wy648^6Y`!3ab|`&rBwhes aBJd9-&4n;MDMOzC0000;pV_8I{&+xeICA1NmU9wGG$BLBAJ*wg{6fL-fc_eJKcNPPc1m;l(Uad^xB+l zraJF!#pg|#{r+e4{qx^{xBmBHka)aB`q9dxrQsVg#j4q~g%cLE z2fteJK+b&o-lw1Qc7GOMBE*s!5y_N#`a0M3lk-)bSIknie|F<+X{K4aim{UX>6L#L z-Tj!Gap2!^-uFu1-fK7dyLFcRdP`(kYX@0Ff!0JFwr$M z2{ACRGBmR?GSf9MwlXl7|H}3`iiX_$l+3hB+#23(Z;b|OkObKfoS#-wo>-L1P+nfH gmzkGcoSayYs+V7sKKq@G6i^X^r>mdKI;Vst0L5|gQvd(} delta 484 zcmV-w421<2)cFTGxGF&d5fOw;_PD9S=45_xBu=AY4Mw3|#O^Nw&TU^pBuheDx$%)H6W zAEcBo06Zq5iV)&65$(2Gt&@7a{@b?ghb{-bUT-fP4*vzP0$?A&699Jsv;a7;X0zG6 zWf;cme!qX;1%GgCl}e>KMNz)Twfag3;Y%bEJC#ahiVjnyb}nt5Y3}$Kz+gVDLXPZxGQ(B6==_ctk`$ zrIhQ;{KK~GlXAJdKXnH)kI?CK8mg)u5z$jAWdpziB3-&8r91?%1mM83tlNfREDZ*O zdsi-TGMSXq>Gb=2KL3`PeVV3i7Yc=KkH_;hl}dH|e*f{*5pHtUS6D?n8{rY~>@-LK0000k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr16wo*Gj6g|ZU+jomw5WRvOi(r6&2vjmvD0jYO?lpaSZV|{&teDM@XVb+x++E zdVH&Tt0Q_RE^J#>xKvN|qAx?DImf#YziOLxXps|$L&1g|PxTwtHn zvSr}{jng7))L7mgKVscuZ+vh4QS-$&V-6jR{IyPw@A;lNpX=n;WE~aCoS>c*E|z8Y z=nUfnH|2S&tY^A2Jt*2+bbU#8=F{LunQSw@or&*oHT%ZUGhh3HZ7xIb(pxuouH)5b zNLt(ZswXt%Ldd%%^b^GV{7l$t&JFv&6%3;dy?~DOW?h|!b%YLUncp&y&>a^OCgf+F5 zJL{8{o0@H0d?Ky+dHcH>Kd; z&*?il^G=&Y-rm1zny!w|&$gZ3!y@3g?c`?$k#;L-{Zroy5~>q7_r8DR&+}rLP1y1q z_aD9w4~b7Z_4sNR`#!$^Cn7tv%_5{09ragfN>ZE2dZ2qUCxeX0r`eVjuh*9J`rc~$ z@vgAiB9pT`-P>7Qp20pR7&HW8~RkM1%)<26ssa_Ws|6TSbJ22N&PEETh{4m<&t;ucLK6V_$!mB3 delta 838 zcmV-M1G)U|2GRzQ8Gi-<0047(dh`GQ0~tv~K~z{r?U!FjQ&Akpf4_V0W-I?xWTP}$ zf=GtaLk}VJ5HS$qLiu1aCLtEOTL$`&>>;}J6g@0ZnMN=l8f-9(V5Adgq`51~h?44Q zwW2pE?QM2*=NC6TaWjmS*bF?6AMW|x@9%rQ=iGA<@;orl?|+AF0b9=jRaI#-bD^s0 zPfh>g!0!YM4h}x;=;%1f1r7`hEOFpRc#OyZdTiUthGdvr}H%OwIz#4|=`c z(&_2xh4S+9o=_-sn-^_tY<#@Dyj(RhGIEHsuCA`yWHLElR#w&)4u=Dr+wJyG9*<}5 zUkMl*8rp5OT7Q=i@tn)$ddQ0ggTX-nIOcY{PjD6rg&d5rG-K>kOH0cW&TDFF-s`%) zGnGn}nq66U31((yF1cK;SE49VHk&P!Bx#(8dH`UG7eK@wBB}y_i>9In5b*&KT?T+> z29L#J6`H2?3W6Z!EWnuPa5%tXv1~Y#KA#U{S%zRR_cg~*Vs`xJCOGbYztTo;ewF?fbTaaV{JbJz!%feSPTFX04$oA2mt#4U7BHjal zw+0^`9zL2#B;>-v!ms~l2>pJ)(bb|PNloqT?GfH>e}8{K5QI8KQI2yK2m~rKnamqR zbSjDx=e)YQ`h%|PwsbmeEYFXT(~T$^jn>JsJU>1@e#hx_cJbNaa5$C8WbCc2two$^ znm=~BzP^4U7K^D34GrqrPif8($+Q{{`C){A&lk0pPbNKbEmU Q@Bjb+07*qoM6N<$fk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1K(i~W;~w1A_XYOUgGKN%Kn6fS5$!SW6k9!K%w=XE{-7{$KOtM zvz@UwmQ0N}-aG4hdk@38g{P{o$63_$J5@Yiy0+u?>D5c^_4a=0NMT`VG+k@o&fadp zd{F<$9n+`|*ZUlq_bsB>x)WYDM{>?{m>Cn?R4T~DaJxn8&hG8M_FjCP?e36!)Gm30 ziH!2hlj)DYG?|;^$8K>gN^=1^UA4qDq9i4;B-JXpC>2OC7#SED=o*;l8k&R{7+4va sSs9w>8W>v{7_|M;)1q!-C z*WZ8{$3&uc#Z^SjD?55P%HqehbVl zpaZA|WIzV!ZAb@D4afl9K%U>a|H84Ml-`CkfZd5_```07{1>f(2tA}gFsG?Q0RR91 M07*qoM6N<$f=!G=C;$Ke diff --git a/share/dark_resources/help.png b/share/dark_resources/help.png index 0bf6b9be5aff85c55a13a29675e3c075a6323ba2..58a70814eb82e753561a71cdd60652c3e19d0f4d 100644 GIT binary patch delta 1134 zcmV-!1d;ou1NaD#8Gi%-008|9F$@3z00d`2O+f$vv5yP zfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u00Lr5M??VshmXv^00009a7bBm z000XU000XU0RWnu7ytkO2XskIMF->r4HXYLgqwJE000APNqAj$}$XjXy?VGu-=5!4LAESvHD0Er@qiVKanGT^|V zq7qDer8VG$pbK#!(UBoJags@5xky!YRZ_R>+LDE*7j1q2(a6(W2`WkHn)m?a z76(XwEkQAV=uYbj4a;d7=(i^*=ejPo1oz@dvxP1@f@;0V^sj>l;DfBEHJ%`;e=#Ws zcz`}xMO$`)a&5`U`%Dxy;Y5WAifJ?FUf%MW|0ra(E`KnWU(zH)<#vLferP^ph1J^Noa(LCnv4;!ytR) zTqHq0si+!M>7z*X9+|}_cU;d}`nbqrcV41zm>TKSQon)t**b5?=nY?Ek9%*xsqyb! zGFUZw8h>6=3U#w#S#)>~k3Jc!rjZ;O zc;ADSm}EPvL#_aUhA`J?SI4~|LBgb`i80SU;3aDU8;t~saEcaUDbgmjymcqLbiPrs zJVc}ME&e1B4UIqMgF^2o*Jqwm50$uW00k1LwA zv+@XfEt>RMKia!GCsw;Blp^W2aORqMOJV>NKmNnq8o3>sDnXWLcRt5N14eWWNI)VO)(}tQp-q6@36Hqe&C-h(VEO zY$4(mjNT=8k(3iz7j0OE07*qoM6N<$f+Qg8 AlK=n! delta 407 zcmV;I0cigC2&My&8Gi-<00374`G)`i0c}Y{K~!i%?U>;X!ypKR+c)>kw=`K3XF*Rm zv^L#uhxc)ym3>?Mw=b@LdjSpyQ%WC;lPM*40$l;D!b?~WhzWotoB`4W5GC9L0t1W^ zf5M<;1p$l}-viMEm?a*Cr~=Fuk3gsZcM;!$2mz29(3=pgseeTP>t@KwVU7K}@h^I5 z0EqbfytjZzdt3l4fu-z}amvkE`%nN-ap=0*hhZ7x4}g^wEe->qbej%POTujd(6_*& z0IcO2QbLFWtn5z#V2U3Kz!olj7g0_jsf41$4|5;~@HA{IIYS(H0SX&(cf%Y&j#lfM z7r>f1*8fxoJb!aeZ8#O#z{j4H_dsj1#)PQ82eO;aG;P)<2rK~TNy#Xqs9P8YU_wM@ zU+e)^8L>_r^I(hN0t=!xvU&D!cXl};!?LCWvmg-h)h1TH!(I0S+7qbwZh&YvdW4@^ z;1Y^-#3Gym;B~|!oC<)}cEmbY2}KC%jk!F)7t(1AKoIMN;!pqp002ovPDHLkV1lYv Bs+Ir% diff --git a/share/dark_resources/home16.png b/share/dark_resources/home16.png index ac795df43aaf3de5d2dfee0010acc9cdc5bf98c2..63993fb8c919844c777dadefd5ba1fce5cacfecb 100644 GIT binary patch literal 629 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>TM>zj^)b+czM&YSpThD_6dL{d(o9l@A|1eDd_ks@1FByag%&sd@6`$&MX6X3m=V z;NgSEPaaR7F@4kKP1C1OFDWT0uPA@{>LpNPO-)U2Z|~Z*YcE~C)Y;kD(a~}7(nX-L z>(;G1aq`5GqeoV+UVZA+siVh^zIy!%$eufQE|8oxd)ADZGv>{kw{YP?pxctz+Pr~I zH7N=53uZ902z~M-^6`Y;$5Sp|n)vM5vrCd?XU`YPvRJa;f5gGcav~||7%R)PiL6s6 zK4NTIn4Z$g^yQ3FA5cGIlDE4HLkFv@2av;A;1O92q(N*C2Dg*hc0dMuiKnkC`x6#k zQ2_z&;&<&pp*l|&#}J9j$q5G-C1wWvJfpKFN28{U&ri=R#m<~xU*3u3$a8Urj)tF2 zO-xP!f*SIAN@w(xxSlb)9yzj8MM7oil2n$34q<*?ax2^!H5RN`vW7_{fK_@Gn@B)< z!UYDdj6v{7zn0Xv7l(k%}>cptHiA#!J=sg PPy>UftDnm{r-UW|_@Mrq delta 380 zcmV-?0fYYa1dIca8Gi-<001BJ|6u?C0aHmtK~y+TV`QKZFyhnS(9rN7B;U}`fKwe# z37BS>1-J~sY5+|0)vH%0GBGjz)zs81!sQYS17Mo3UAZ>((BVV2zkmN`baZmuucM=r zhs_Wa1JE^RWM=4rG)*n(-OJ=XZZ*-((+wPrAV8D>n>KBlcJAD{Y>)42TSU a3}pareZW$~fSIZQ0000WI&r8MG9O}fd9L{EIq3^k-QtFArb)^p$*`ZRUHASDr6WlM=h6#%^*WfVZtC zNq)Lr@U{6eIW=M;ngNUo_39HD<}u5~9tcS8J}!B|Wm}b&{WX(MTc-rN?&~?mcETuG z?#7{H_lcU?Mh$L7@qDGFC%G23{F)YY#o51hN$%gjXSv@T4LzdPx3drECDjtwh?11V zl2ohYqEsNoU}Ruqple{FYiJT;U|?lvYGq=kYhY|;V6bUZe=>@O-29Zxv`X9>4!<|Q Q57fZm>FVdQ&MBb@01pe5XaE2J delta 153 zcmV;K0A~Nx1F8X#8Gi-<001BJ|6u?C0C7n~K~y+TwUgTpz#s@i<k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1Gg{;GcwGYBLNg-FY)wsWq-oLD=NU7QQ8#8z`!`e)5S5wEBk>c9xXP2x+);DYEu9uM_Ku<$=d)%sHNF&v#^X_{^@3SW9)xjE>!Qwh_br@1YAKFv`(Sh%uY zX-`AKPxVDd*X+(x-qWxsWF{A9@5xD5GInZvztSmTYMa?{V(w$tOR=h!PZ*Nk8O&Ew zzJ6rSz3lyS&cEd_P)^ymUOm_K#1zK`3HdJR_tt;0+s4Dx(0bACi>M95vH$x8<=1K7 zUN8DOuof6?swJ)wB`Jv|saDBFsX&Us$iT=z*T6*A&?Lmbz{=3f%FtNXz}U*bz&TcQ fF^Y!V{FKbJO57TZ7}m-IH86O(`njxgN@xNATp|MY delta 289 zcmV++0p9+l1+fB<8Gi-<0047(dh`GQ0QgBnK~z{r?UzvxgCGoq<)8PTZ_$W3u=HAj zkQn!{moe|_aV?m(#h*9o@+ z+N2yYJzW5n5QAWOp#V%kOMl)DPhLy_k2suY?qeMD(gcWzGYA~bcm$(+#q918Z$W6) zB82Jy3y!z9>uT$~pfjoiy}fM(6Ms_yJZCs_K-&(j81+J;+2$3Dth-&wmS0L)D@Ce{ ntSzqPkw1=J`x?EPEqCA#*Q**F9;2Be00000NkvXXu0mjfBOQOn diff --git a/share/dark_resources/import.png b/share/dark_resources/import.png index f42002d7c4b24faecaddf3c6a7cf584ee70ed06e..1e3a26a7beb446e7a902f6bf18a683f61b3cccc1 100644 GIT binary patch literal 550 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI10wkH8TU>z@OS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>lBSEK+1*-JcqUD=rek(0q5(6ov_>gBUzZ14L*4S@4f_mXVvb z8SmDP<+mnBl`c&Eb>~X6mCZ}Lw*pftw&dO;Gr#T^KC=FL_mb@n<^}gT z9gW4lT7CL(hWR9?wcwE*I^Oa;63x#iEc*}z3^&yh*NBpo#FA92;`IJ@O1TaS?83{1OS~F Bz-Ise delta 196 zcmV;#06YJt1l0kM8Gi-<005~Koi{q^y65SmI(+zyD=J`|y!e^Bedly#nz4uNtAy!+__ zc~U0TnnCicg($KfXblb(Ss_|5@&GDm1*BA*4qDlRdstU}?>$)14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>mU4y?X8Hsne%`c1@i+b??5tj~_n=epc}# zBr>`sf z6Bb@k0kKB{-kX3z(>z@qLnJOICmdjun0bL^Mr6RxH92o&PSp76<;lg_sW8?tIw~d# zvc!k@#5g$xc}eLhC~K>)U$9~c&*RlAR;|p=$jW^E!s$oVFE$>YHa8xgV`>77!Nv-S zd5kJLYaME`rK8!{tgG1-E?+z;>9K1E6Q_AOzrVuMr)Lj5c>Magynuj&h>VbcfRvcr zK>1M#5JNMC9x#cD!C{XNHG{07#ZjqnCKdsgculD t8Jbxc8R;4rTNxN+FO~d)q9HdwB{QuOw+5*n3qj$-;OXk;vd$@?2>>uacSryL delta 589 zcmV-T0)@6&Kugwp_FVc|e`cX#bCU%rSOK74rf`}gmUVlxD*0WvZ&oSf{O ztCLfcqksJP!98croT(`(DFN8Lg4F;)e!)@?FOT=fjvWKrYJY5O?7MH@zE>YUd{}_) z3Je2;g@vV6lvF0l%F7~)#hnFTd9HIG3Gyu7^H zxw*MtuU@^n55#Y3YSNxKabnrqw{PPy4B+GAiw+J97Ms6tem_hyGc(hciHYgm)TvXi z!o)&DL)-W6-MjDIyLY=mVqh1Dh=}ltii$1|4-b!MXn$z<0u6cAt5>gXV_;x-|KrDx zFqi>tZEd16rq7rwDkd6y_Uzf;U<3Gg`07*AQqK4F^=*PFjEag9+`D`4X%0?~?}|!_ zh6fHD_ydzmPft%?v0??=$B!SUGdepv3*WeLV=pf+@0^H;h{-TTQ>IMGG%_+WWME+U zdHVF}YexC``O{%?Yu2nOc=_^Wl7oYTDPwMKE;}zTZ|I*te^^P$n5?X<-)`NywFYly bBE~=fmU-3~EvoiS00000NkvXXu0mjf{~sbg diff --git a/share/dark_resources/intersection16.png b/share/dark_resources/intersection16.png index f05e252f6f607ea45a3113b34c9b11d674c6c33a..ab41f3c58b5fec9ac28aa8023cb054753ea85341 100644 GIT binary patch literal 514 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|T=)2s3scS!D(kWH0gbb!C6T!YeAknzoKB2PpK_)5S4F<9za;^9}L_f)mmc z9G^}3{O@_2_n+MAvj>2nBgge+aNG5QKAmR&?}aA95;J%6Jm?ZP_@o>em~&!@-1|87 zZ%>(-nGe^`JIhm;(f4QX(zF8|xI-{E8gbfciCOi)Ms~Qq^a6$JoU%q9(n0Lli+Zh`e{Q3WFN@HW8<#ol5hdlo! z{~15olkhwtaZ19J2h%T{t-hcBaXurPpyJ8@zyE*!f8KuIj+?*U|KvY2q2}webJPFx z0Kt68SCKRAlv;UJRHSd%6&-A;`#bX&t1~0(Moxw^^1=0t8-KY113KYhZ85q1#S71lckei>9nO2Eg!`!MFyMY=Q NJYD@<);T3K0RSe*z(N23 delta 461 zcmV;;0W$uA1l$9V8Gi-<001BJ|6u?C0i#JoK~y+TV`QKZFjAt*x!C%D;dA*1&7Pn1ez+RjYAl400000NkvXXu0mjf DRFLvc diff --git a/share/dark_resources/intersection24.png b/share/dark_resources/intersection24.png index d89dd33dcc77eae41baf5ee3cbb3bf8ac88c867d..43675e8571b3487ff8918fb131a55eda2e431e95 100644 GIT binary patch literal 589 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^+ z;1LNlk>v;oGuoWF(hL-2FY)wsWq-oLE6Q)!K({}}_D3+BOuhO#wqO&_WnhqQ|xz|yvM`M-hoAfNMgKX^` z9UNYN^SUR@3NOigk@tM(_r~Az4h#BLAHVwSx4pof{TIEa1lUeK+*`X?A=+lrdPirU zBr$=#dv`|jhUv~b6ED@bGq1@fd==C31MbZ{N~b?RYQCYAW%EgHWkN3NNi&|kB9rDu z2=?xJutKDq!BO#x)U8_!54_s4*rU_u#-|(i4#a2|Td+M~DVZ6fU0lJqLH$p7$#;H+ z6!)O@HnUreZY()pf8fPDwjIWt=S&a2`t>=->r=oPQxTnmoc%xd-eI~mZ>Nt+x;Wn< zUn7mbNB4GIQ@Av}NBzm#%IQpx#JcqY7Zp6tyr;^}#UG--;7H*qH^u3aG11?z#(6DN z57s|nf8%97%aI_r8QDo%z~EIaag8WRNi0dVN-jzTQVd20Mh3bDCc1_uAqECkhNe~~ pmbwPURt5$xzy5cjXvob^$xN%nt-*A;yBSaegQu&X%Q~loCIFgb+dlvR delta 625 zcmV-%0*?L71pfq(8Gi-<007{3J@^0s0!B$hK~zXf?UYTZQb82Q&(W^Fv_%rc(58im zAOs1n#6U|fwP~r)#zhna2?;ai@(Ql}*mh8dFWvo`u8V+sgn& zQRXTriej?c?cX*6IOkX>6z*}(&x?cUboxG}^xQiA1!QYLp-{MH7{*Jx-9AM`o=hes zzu%9tEbEda8Giy~7zQ?*P041n&AB@Pvf1o)M10N|L(X}O5c1UL^Fbz)k-c8;5$D|8 z>-A!}T<)>OV))HIQkoa1476|08**cl|Ufys?+J5 z9t;MgR4Tm}fLg6~CmM~u=A3^unN06Ce)5t;5+UT+?SFQI$K(0spNGRCxLhu1x7*-! zIu~ni8Dp2%+H?tE4uwK`Fc@5EqI$i4GZYHV3s91zkBLO0w-ta=Y7!eqqtT^Krz7n0 zM$C0x=ab3gR;5xY_51y(s;bp>7XGbOEM7n7n*E#1mlF8(Y zy#Voe+-hmHS~UPT007}0eUYfuYDwjCd9*J;M#Mvh!!b3R>C?$80vkZnrBTqD(10 z+UW(=YSpZ1+C#%I=B;8)w8!IdR#B9Bb+3x8+Vuv|+U5U%jq3dXA9Nxp&DVWp00000 LNkvXXu0mjfoq;TT diff --git a/share/dark_resources/intersection32.png b/share/dark_resources/intersection32.png index 4ac94675d537cc91f839031035ecff4f16bf965e..de6f4c61e7bde6ef92407bdb1b2f96adcaeb43c3 100644 GIT binary patch literal 723 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1DhWRGhUkzwi_tOUgGKN%Kn6fSCrqhSJxztfr0Uur;B5V$ML&U?LDFcMcVg& zP7?A=)^Ks05+>l4oO#gK{C~qPk9NOYhZh$DxsPs}qL<5MH6uvi;MtS979Cc*N>?a& zyi_}TVcM)9gRHC^k+^#=6BI9&$0rF0+FaiIyu4oi`<>$ZyBE#TUsL>RJ=217-WAe6 zs*kU^@st1MC7(UJKGa0E*{Za=pA5MwdxC*oN1`RI?Zt8{h8uo%W$N)?j6&@8Z*ZPd z@p$>nt((p$`g?>k?%9>Oe>%e!ceh^+3Hw&Z@a|WRV|{SuL~VoM1MThq(wFbspQH37 z^c`mdo8r}p_ha(oJ#RbAw$FCg{jyj`eDApfu4n(A%X)YGW5sffjk0I679LW6eJ@Nv zLvq^=wro>IuAoz_CGnpxy#35}MRI}|(}aXKpD**WsY{15{`izocmC~%J)N>PEfR(| zjwrckhXwL6mYg;Z<_tLUGc7ga;Wy2P?_ONF6X~^MU46^D^jz&fiyD+7zF$kXo__2x z+ip&U1${p6<@%*R1ai0uPw1Ter%msPi-TxLU`>lf)ZT}8SI{>L*o2d!mPy*pWL*BQbN%9N_c?C(%gx~osE+w}xaem?eMDB>4b#;O zkAab_TH+c}l9E`GYL#4+3Zxi}42%qP4NP aPsvQH#H}H=R^k~@1B0ilpUXO@geCxL02{&p delta 817 zcmV-11J3-@1-%B48Gi-<0047(dh`GQ0|ZG#K~z{r?Uqky6G0Tlze%T!#9%hjwx*y4 zFGUZw66#xJRfS@Rf>BfC61IV(x58wbm#v;UJ0QUi;L{W^{1)zzd z7_b5$%kmun`Tqkzk|Z`eJ8Kw*QH@5U&Sn{qB&lBB-_F3y%*<6vX_7J4!5tNg#S7it z-FK~|o!gumAb*iaWCZ<=cHGnM3uef># z1_o{f0)h3##l`E2qHHWIEFcsLAr_0Z6G9FcV-5gpYHEt;x?bauwgN<>QJ)|PpI28` z+jF_xHx3YqL@+u!$^-WTSSN%q#u$mm6~jhH1E92|tx z>3qi+D-c5N0k~AF)le#x>O!5LpRW!N4_6N1D1h@V4g(&<;{pUgxIQ*FH{TQrg%x$l-82Z>W1y3PMO3!0m~NiMnR2tfo)0>FMck4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKpuOE zr>`sf6Bb@ke)DAI&?2DFbx#+^5Rc<$FP!E*WWd9gaM&`)+R1!@^cLw7R=0%az5^Tv zTz3_uC-8bry>oUU$I+m;GQI~fpS;gaKf+KS`C>iid@Q*9yHMwR znq8{s#D~UtDrecN3Qr8cg`| zfZ5iwNxY)LXv4?GbGM}#%pM%u#CfD4_$5n{Lp0x?efJ{YM_0P7&;JJWqH2k2L`h0w zNvc(HQ7VvPFfuSQ&^0j8H8cq^Ft9Q-wK6r;H88d^F!28{H33CKZhlH;S|x4`c58L- Q05vdpy85}Sb4q9e00yg`FaQ7m delta 186 zcmV;r07d`L1Iq!B8Gi-<0047(dh`GQ0Fp^WK~z{r?Uq3fz#s?&_2>KZHXclR&<1c3 z+u&Jc7{FLd@T$S_%Q66fYm@{4(cPj=GfT7JZGQr!fh`7lb3U6<8n~ZbngYffVg_K0 zU`ybe0B_lA9wD=VqXD)|0jmLBO5kpQS$~s(qXD$~=>`(O-7^5Y0o6TlG=N1v)xiG& oJnFA1K{x>813J3H{3m1q-Pd+(Aw5p5+W-In07*qoM6N<$f(@NbWdHyG diff --git a/share/dark_resources/join16.png b/share/dark_resources/join16.png index 720e86e4b66447ff02c5981851c2d0ad09384746..191ea56090469d25c45e64870f992fb5d96dac44 100644 GIT binary patch literal 548 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|T=)2s3scS!D(kWH0gbb!C6T!Yj&eB|Ay;JOcxxxTlL_h{pM)6K%bl0wvnk z7gycC&UVyjm80hJtd4zkP8R~4>lZpk$@~#@{K9_7E+aDo2y%N@I4X50Xg7!ZXmZ#j z&8nK$red(T?cK|^=Z_w>xpVG!|6h2VafRN`+spV2SLW?gmDXMD^0lh=^+gi}j;Eo@ zE;H=TrhivUU}<+%-pT7|$IGxMDAT;(a9!Q4goCwKS~E634D`C&;HJYoePM~g*8Qh* zj-Mz?IhLp{Q@2OX-cbB*8-q~S@ir&zrwPI5SLQV@yFW#1`?2EfuR3?HY@OYl-zIkM zp?AvJm8Q>x-%olR=e_*kBTW@63(2@`=QB=)l`?7S>^RGIZE>6XoIm0hg1>Y>_w3mE z#rfcQ8D^Fkb?ycK{+{Ju9-ee0e#swqV5q5P^)CxhH00)|WTsW()(~IiBLmdH;OXk;vd$@?2>{C-#asXY delta 527 zcmV+q0`UE$1f2ws8Gi-<001BJ|6u?C0pv+UK~y+TrPEJ{5^)p<@UQ0R&d5&>OCSsq z1c9AA296%R1c3xOO zgcQwS0 zfX7KKkw|=OwSQWd1A)LvUDt0mo6TOM(MS=|tHS`hMAS1)b1fE&1@rm*&SJ56Q>)cB z=JPq00e%4A0r&tc0Gx|PqqoN6@e9*5&kqKJr2un2%rwm}LWp;aG4E_PEBbuC3+;CM zED=>X=kZYUOSG3F~kLAP6|5 RhyVZp00>D%PDHLkV1m-&`(FS6 diff --git a/share/dark_resources/join32.png b/share/dark_resources/join32.png index 266b104af49e103dda303a00290885de7913e688..bc1d0a3a25a2bc4408a48de0fb77e2be1cc7bf91 100644 GIT binary patch delta 934 zcmey(xsiQ>WIYQ51H;YYP4z&ECEd~2k%3`jKlh(RRv=#?*(1o8fuTx`fuW&=f#DZW zsNn?zL#Y7+!>a@a2CEqi4B`cIb_Lo1C76=D-CY>|xA&jf59DzcctjR6FtGW7Fyple zVY`8X>?NMQuIx`(ct!bj=Q*z70BTy|S?}T);&J@#)aVZ1K$&Cp|F?d(e0=7p!s9Tf zV^1|iE~OM@%GvaoxJXS8lC!CB^qMz?UH_9qpv{DEu9K>6ax-Qw5j=L6XVRq8J5uMK zEBN;G{X?1bb2oe69_(h%-kSY=?cdtJ|L_00c5Bg}y9V_q|Fg5)X}q4WdH?DX&wRd{ z0`EAb>kF^QRumNM2-sNrVDqChr8WW4bDm#W#kcuZWYg2Nsw*)_ z83;AZDNcSl`$+J<{W;qgo^fD&-tQ>X=(I2~tI*Z^=%-g3uO2^Wr}aZvU!n2|JHzX} z_s+ca=`Ww5J9Rln+k1vR91CsOx!4v5L~p z73TS9ZoQ9ue9`5`EiPq>vySZ1op2;Ks`wqpIqUaRFDIouI*LvagF;-G7#IBCPdR5x*sE{iAW^6N%R8_F-xcYI9a(uPU@J5efQb zwvVY@u4P}6cb)Wn^Oa&Jdha~Su3?>D;nUTAEB=LP!NCqeWzJWDQHy#qScAW8ODRk} zIb$wE%eqZnQfd<(O76Y0SkdhPYyCFuV7aXcg5OdspK`uD$ok~XlS`sPwI#(mmOBf) zMUUs~h&c4?fBqA7!4I*Izsz_Y0!+xNC9V-ADTyViR>?)FK#IZ0z{o(?z(m*3B*ehL x%Fxux#8lV7*vi15Icn-Z6b-rgDVb@NNE+nPbbMmhbpq;O@O1TaS?83{1OP!Fi!}fM delta 1266 zcmVEtV4~*+tO`CL0MWcJm+04jxH6@)q&!flmVyH z=_)TTU&k;pF@fUZ;kj}k0N&-Cch}d~TLQ2###Sks z5P~M%tn2!n6o6x@sva|l2=o~M=>T2>a2LRjob$U@0VKwlFaVwfkfH1PYzn|BRaF}p zWAP-=WTi7W=YLuSAaj`$)7NF|x;~WxFrljIE>g-+iGSXU8_yDeEYA7wmH^J5Kfh*D zAq2Vk1zp#tlL3Z?hLD$+hn$=ocs!mxcDwyMQcVa!>ct6)a~`(>@VusJJIxdr@)qg3 zK4t>={r>)VJe~(2=Jk4C_WS*-r%#`jtE;Pb0+=vBY@GA^j|D(qVNAAL*Y#^AKub#t zYiVgocz-1MC@d_*fddB;{t-f?bI$Ks1~8Ts5zu6X7cXA?;rjLKiFhYYoVe-p`Cc^c zKk@l|9=dODZ(p6Bo^H&_$~q;4P&ntyRsdY&0m>y!YUDFxet!N#hr@BCwzgIt8yj1# ztE-c5+_-_Msi}XduzmaX`O3=5tu%P%%o*`G0DojeI(IO}eicG&zIE%?{a7rPpP!%q z7l5AuxQ-q@+Am27R-8O}a`fQAgRh=DcP_DtECXnomRtvl0E8K1E2%jbLZpR4p~cbB zQ4?USqN3uJvuDq4W{kxi2SA~KMj8qU06?NLMk0|978e(334Tgr9*<|dySsbq;lqa$ zvVUi0W}>F1rUbwc=X}Ld3N%eK0VoB#0NkX$aQX7(_xJDL-__92AYZs};eKvzu3TDL z`apl^C_6iwIx3lP$r6BJLem4Jz%Kyy78MnR!r}1M=H_N$+Qvup;g+d`}!Dde&-;i?TooxWV=A6f@D)2gE?3xgQ0?=6+jYeAofxufP zz~JDZ=?Z)f0c&`ZbAIW60~8b#xZG~{I0KQ6Cn6951J07*qoM6N<$f<1g#mH+?% diff --git a/share/dark_resources/jump_to16.png b/share/dark_resources/jump_to16.png index e0417351ccbc5ddd18b635c5ee1e4414f98c279b..8df33fe18d011b82f396e189c261d68513007241 100644 GIT binary patch literal 478 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|Va?5N4dJ%_j{MWH0gbb!C6T!Ye8u!MY-CD^Td7r;B5V#`)HM>nx{4f!6)n zO^)gcjT3lp>}Hs(b<>%J+gyReEKi|Vx`26^M`H41CFu>DxH5xWbZRH0{reYjXZ7{t z{pU2FeLXnG^T<;TnJc2de11Ni96sr9i1ppqx3^Aq(^~RbX2z53>E3sf7d$KaxnD|a z<@2JE_4jz0|w&B(vRa3kfeP{XH};^Fsw9yf}=W2jgp$DDV_;tJy-_I|^J z#JOj#i67q4US7Rz=GII_jd|~z-%K;_O3d{X*`T6vb^^2XZ|1Ox%~q3N8{{);O=)|g zIsF_n&~vIKt`Q|Ei6yC4$wjF^iowXh$UxV?MAy(H#K6GH(9FunMAyLB%D{l5ROcLu dhTQy=%(P0}8Y(rW6ah6bc)I$ztaD0e0s!V8q?iBz delta 142 zcmV;90CE4`1D^qq8Gi-<001BJ|6u?C0A@)k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1K$x4W}K?cCk+&2FY)wsWq-oLD=NVEvF7p<1_s7mo-U3d9>?!a-R~{qD019> zwl$B6vXa=(#NyT#XK7DG&&=szN41s+xOx`;WZn{T!S8=VK~tzecSw^5Q&dONM0^e-isdo@@Wp2 zd(Nl1tJ?xE?RcJgSA4a+x1-U?6USaU|C=AN>&K(+9FKIHYuO5qI^uGd_1;RI@VZ2> z`b$x9=2z)yQK5-_W!W*uW-XbwK)+XExqC0?`jvZL1>DVQt5=+{a6(vXlj6-)6^eFQ z5BBrgIBrN{`4%xx_V8uVhaXkXscaevObgO@M-lKwnL`rG3zT6Z@8WoLD12u`MaZH#T(|3 zhqZqzc7`Ro)*9~n-#NeZ_TC=((3R8vO-*9iEs(;n;{mhz0nK2BFYFcGOuD;PwQfJK zEz0GJ#BzpT?d!4>3*}vw|69`6x}D*Y+WRaI*Seod9jD!b zRdP`(kYX@0Ff!0JFwr$M2{ACRGBmR?G|@FMwlXki`=zamq9HdwB{QuOw}$V_Cr<=w OVDNPHb6Mw<&;$VEofeH)SdlLR=ie zmPu=06V;~{?mah|5gLyB$fKW zYyLI7Sh^Q@J-#v#l~OQsan;3TxnVhy-U~8_NZ7b5 ezMB*~@&p|+@DU+>@{{=h0000k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1K(i~W;~w1A_XYOUgGKN%Kn6fS5$yUzG%}41_nkePZ!4!kK=bkH+nHUip=3< zH}iL4YGm#fiF?YwgjO85y{zop-Fb@JoU^_E)eCgoIc;_#=!~B1ldi-Qvj3erCeFPXdGY2lrrIqR z-S+Q1Q2Fp@?)86@jbd7r*c?v#2{KnqRj!%FTr3bgWB;=S?GZtqf{U-`aEmwi<~(w{ z*_HGpXxAjBqOD~&SR6H`vK;KZB&vR7Ro;|e3!fM-zVv4k^X*dYT^EJgXE5JjHgH?6 z=fXct@m%2q*B`+hc6&}wj`4P9Giov`2zZ+HJwExKK@x*X#Rm1SOrd<|-XwF#GI%cy z`Q#_=buYMM*C#HG(u2{ns;Z_QkoI>zA<9(quu$W!@&U!~hhLtNT6rVt#)~fV`v1>= zu|BSo{(0@A@M&Pcs+PD$l%yn}$cLz55#11m!_D?=k)17j-# jgQr?@;wTz&^HVa@DsgL=Qod|8Py>UftDnm{r-UW|vaZ%m delta 245 zcmVGp*E-v!7ePOomN)-VNpK%`vF09*~Z;OAQGwr*+wv^0pt+Np6LJwR>kBYuCd!C00000NkvXXu0mjfnOk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1K(i~W;~w1A_XYOUgGKN%Kn6fS5$z#V?nk9P$=2c#WBR=c=Dg~2S7mJYpNzQ zXTx*BW}B9yE?s6h2@iM^8ZX6Hyj$p9E13MC@z)Q|!}=yC(+jTE-zj+c{J+4Dc=7G4 z8u^<8nca9LOcSm&1TwcxWz?y7V)oglZByLiFcyYRWyB~x(3Ep1_sqT4E0bnNw! Mr>mdKI;Vst0Q_xny#N3J delta 117 zcmeys)Xq3TGLMacfuXpn>I;za^K@|xiEw{=$&iadfyX(p`tzNbLT^^Z?(RQ+x*3}N zS2j#Csja){t#$u48=r#$?_J+lJQ17Lw;KH1aKC_oi9?|QPJEbpfN6(UgW~K0(JMfc O89ZJ6T-G@yGywpaAt{Rh diff --git a/share/dark_resources/link16.png b/share/dark_resources/link16.png deleted file mode 100644 index 5c9c0046b1b4a811b296ce67b1147adc9b6eac10..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 168 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%``JOJ0Ar}5iCr9%gP~c#B`mFl1 zl#rp_Hk&B>UgJkfmnLx^D3)VYnDkIGCr0B#!qgp2+c#bRJIUdGjh8pmwCnl@ueNGz z*vizpU10x#V1a{W(q|Q#M7200R$pRbo35R}{P^tYubU%Q#~jp{*q4JeJYD@<);T3K0Ra85J14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>@Wy?FUz_3G98_wWDk@dHrm<;#~qUFR>HpF4N%w(Z-l zUB7nn)XDDd?$*{;pqA$^o$PXb z^Ka=2apwDnoqTv-LG9kG#HU+a)?eJ6$|3Ub!NaFBu2&iHY}j-+PgSG#VY1z$XK9Re z_j#DJp9rX5_LEsEsC7Hir?}^`B0G0X$Fo)=^C{2o8~R*dc*W4>kWb;W8YW3DfdXx* z+%=%I!&pIwg;$hczrg>j3Q%aH zr;B5V#O34!2d17AGHhyTVqs<}jAeX&dU{kdhetLhh9Tf(}D8#`Cd+}XNRwB7UwgLJfYwZhW}FP`uS z78I5ivtN|^GcPWIF<-teUf}KV_wo#498aF}GhIBWxG*uH@k7Un6)$Go*zu#qWrp(P zA3Gx=CkF>zPGEW|IWzL6<<3fu`X|OBB4Um=8D{ZG8NBJTZvZ-8wZt`|BqgyV)hf9t z6-Y4{85kMp8kp!BnuHh_SQ(mHnV9Pu7+V<_h#YOXj-nwqKP5A*61Rrb88+EK4Gf;H KelF{r5}E)#snY=f delta 656 zcmV;B0&o4K2b~3w8Gi-<001BJ|6u?C0%S=glU5_@R{T3 z>B(+xZvF$NX7Ap;VuueOehuOiWq^#NOmIqi%9=TI=G;k1Nl^i5T(xSI-L-4i4ihvW zEiH|8=k}c!6O$7)-@SWha_ZEnoQL-xTBoF?1UEM~U&b&1> zdryg_HIw*|TTqvu4ej1yckHhugPr*Q=_kHeS7Ym3Q^( z)n70S2n`Ko=HlYYP*hZ$^5Me=!3h&4d_Y!|pP#QTD1Rt;10=R_<3|7U=g)6K@q&<$ zkPJI3duMuPderIDr-im|-TEHc08dX(Epv18t8-@0x#R5UT(@w^!sRFiWMpLcNJvO* z1_@4>FrnnbhY!8T1_P4`n`Jf>e=MUlYgQZP*PID&Bn$S_~gkG9VI2D za$L!J{(t=WMh_o8JdY6uFaa-TFCQ~oGq6iwV8OfvHw=vpPhGlr$v7%HDz>?~8MguD z<>fX9_8(~T^z!U_@#2N5goH%jv17+-t*ort`1$$83kwUMqq`0xDW|2Sam|`F>sv!Z qgTRNk9}k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr19v9~Gn$_~y%s3QUgGKN%Kn6fS5!cPbw%1%1_s7Eo-U3d9>J%i+76*$Ej4vdS!dPzmXh^R zX|Kg6$Ak&?olpLtqxfk>09#tvq0(0!MH6l}&D?72ZYtPzZqkNc)<-=;%O=0Fe>fwm zC->b(FPW+b(F?>WSj_tG?PzIuQcL%Wn-60_))K)3zx7IsZ%X^fIu@x49b zqzcoWCoPqWY?e-qO$(7XlPr7i<$&e9ug<%i-+r2wC+oJ_chRo+P@@BZd7H|)#o{HO zDe7y4O5b_f7^GM)>&)1*L`AhCvu%_=e6FhPF-^_-m z}}Y5e}m@->6b3fXTytdo3pUt~X&x8=yC`m_XPsvQH#I2!HV@eTF1B0ilpUXO@geCwB!YgzD delta 204 zcmV;-05kvT1>FIV8Gi-<0047(dh`GQ0HjGoK~z{r?U&ICz#s@k*Pr|6jRrvz%|OjI z>}|yIc)MDaD|nPKJ^FU~Un#>}lUT~+W=AOQyBecyz5J0&leR{`ax8N~kp zsH$oTa7}KT0%`!RSK#cZMy6Ik+o(bSu=7=0K-IRS%2t3LY(;jQyDE?Xseroz7S}XY z6(m520v17~HJW+Z`+)Sb#r$~yo{yBJGPIDDTO%BR1G@pV;4m=yk)tsH0000EaloalUn;Azzb&fUEqG zNx~VA1bL2yWhX6+J8(+CDmQay^Fy|{BNbx&32jH1&Te-|QFM7`zB@m?E-l^WVwdov zJ4!`cw_Un-Yv-BTd9!Ewq;W~VvQ9g#z|K(=#{1=#tw_^>V$Y`rj~&c~#7dn)?#u`? z`B3-u@uO2>0ZB_&2HlOQ-99~N{{N3I8k^dUE(WHxnthdVI@NMJhoWA*w)wq=mpgh*NBpo#FA92mmtT}V`<;yxP!WTttDnm{r-UW|u|T5( delta 133 zcmV;00DAxF1D64i8GZ%;001BJ|6u?C0A5K%K~y+TwUbc_03ZlM^X9vGQ6NM(SxJ4S zPWG7Ak_VvAG5}+3wBW-&$V5Vcb2tH=j88F3jR ni|KQeRj_mMza*B9=_bkpX#!mjqD`yG00000NkvXXu0mjft+O@k diff --git a/share/dark_resources/move32.png b/share/dark_resources/move32.png index 60f1063c7cd7569a8c8f0ba230014187bce333e5..0375598906c868520f293cc125534083ed377191 100644 GIT binary patch literal 772 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1DhWRGhUkzwi_tOUgGKN%Kn6fS5$zzQA|CXfr0V6r;B5V$MLsQ4KsujMUL0M ze`mtE_sFz_UJh9q8KKOK*H13E3JQulx-R6?d$fX&HTvM1M_~m;TNdxI3~`y@rzPUJ zCP+gnWK~DVr=?$gs=mu~t(^W$Pd!qm=KiO<-|zjdz5jcE|9h90XV=Jm{?FJT{Ial6 zxz;XzH>2P6_Y?c>U7!2ZsfN@2(WQlTn`W~yaTl_@T*tUNrM=)rvp~Yd1zy63O^dB( zb}(rFs8MM?Tka4LS}DWVng3YtoWY@8>yjorhq_Aqk!A>qOkjV(W*WLtGnk)!i`NQ^ zxRZIF#xu8@FRki7@3+w;fR!o8M2Vqyy17^M>249mDU5#)?Xpl}SrwrXcU(y8Q^H5EAcT*$#tPyYpvgdxl=b@p=}H*2jpZhTUeMaP(L%^Cjqd1t;b>z!;Ouf2B9VVX0wl_vdK-t7gBC{5{9_^MCeh*$>=*qSmjJ-zDM& zOckmnt`Q|Ei6yC4$wjF^iowXh$UxV?MAy(H#K6GH(9FuvP}jiN%D~{tA(k!_4Y~O# ZnQ4`{H7uRK#|)@}!PC{xWt~$(69ClvDnbAN delta 894 zcmV-^1A+X628sue8Gi-<0047(dh`GQ15rstK~z{r?Uq4ER8bU$|6`84rVJN}S~&Bf z7KTQNq7=BXB6LU)1kDi)TBM?o8KE;oFUSGSZA;-T0&g;ex)27$jphhp61m70H43?~ zjU_rUI&zx1(==^IzJvhw zl6(vLcZmNJV0?TWJv}{^J25skhG;Zu#3x08+1XhP4GlQ}qyoqSjBSbmNC6N5umE5K zz$$?ILWpPc^YcjuumRw*7~&{^BLG%RSr|wXk(5$i5<<-G2f#@HR{?|oyd|PdDJ8=k z1MuBU&LG!?5PyOF0yqa?27rx-!d$(ST)0s=D{=vVT?p~oGJvLOsfwcHN2Adl8`9g` z>uqmuuQ6vJ)0BPLY{3sA;yEx5g8(SuHVGl#SO)O-Ck8yedaK+w6|MY zTApWRv48LE{`}Pm;{odH>nBuIZ3D18GcyzP`~6P8-;aidhTUgRM1i8BBE#=Pp%5Ay z8@H3LuCAi5ukVJr|7^GXyQ%B?%cZ3yj(g(udNr$*zwCOv0(EtD_gY(9@0OO9o{zt* zqM`yNB_(zqG9ucLQXU83)OCF>sQ^5LPN(y6c7JyEMssts!O-8|kHy8s(?n#HY7Xcb zevous4<;3$wzd|Xot-EsD8R_b2&$^85C{Y?H8te~pb*hVDWwA7BClXl0b;Qjg25n5 zjpE|s1((ZJP+nf%<#M?K9UUDL>~!&Mky4(}b^Tk?6c`*FM0IsFGBPqyR#x^xO8HJo zd3P!t4hy^8{wWfPtfi%;vDr9?=o)~^>FMb!D=Wrpyr&^dV=EpQ7)U8BEJR*jp4DOA zjw7N+9*^g#)em>Pc-`IIJ^;7ktkvpW9LKhO$K&xB50sUY(4SH(7bY5W2ym#tPk{Zp UFmSlV0000007*qoM6N<$g1VZRkpKVy diff --git a/share/dark_resources/move32_bis.png b/share/dark_resources/move32_bis.png index f464fa5367e609a56ba8856e1609e5cb07f1ef41..66760b515c594013c664f4ea846b50f7720bca4e 100644 GIT binary patch literal 595 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`KiRiV8@uu1MR;z`&^J>EamTas2Jng?Wb!1lsn8 zF*8qFlaxZl_8S7b3w;bqUV=Q->9y7$nE{5L1hT;II^-I+VP#HaUZp5N8-X~nNzAL(`0qA$W~9v|tv z(LASD_+$&m`8gg%Q$DY5+P&k})TfdeCo1n1_f1=>Q++FQf&T9Y_9_x_ulXC;9<<6- zbjQA4raJ41{(dvzW$kPyTV4dM-=etrclw1o24$Y7CLz-UWr5+RTH+c}l9E`GYL#4+ z3Zxi}42%qP4NPPsvQH#I2!HV@eTFgCxj? t;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq=1STJYD@<);T3K0RRtG&2BK!_l(nE> zg8y3|b#xl0f=5K=SS})gZ9^As;+rrFK>?h_OCVr?J8>2Q0?3Io5DSQ0000<>&pIwg;!L7LqfjnB2Z|Zr;B5V#`)F>Yq^*b1zgYX zN|F+ofAEd8j@fMA8m7qylQu=X5nC)aJM#0lw`vC$C6qsuZeGxHbbe@={rlYMhvz;_ zia0#exVxvv{aj3zgzCQ+%vb(1SS^2@zv4yLJpLVmubL7S6>2R7Urg}~JlyB;Z9#Gx zOC^I$<|(m~1Cu_?{l^o!`N&M;>0-R4%Tx^m&RTzzY1y{sbA822FLyILhIcA;3X6>v z2r<75ubVJ~`v7yOl=t`3>lge5x?HuyHKHUXu_VK~y+T&680Iz#t4m>&$3#cy+7kWJ zA5qF9ZPI3D2B5$9Ish8K>Hn)+HKXu8z*O~XgO!#oWV6@?cqK;wh8zPDOUH~-8@;t2 yBITfhNPsA0-XST8krG)!v*8o|0J>k`3lJ%LB0$ORcZ_j4J`}|zkosw zFBlj~4Hy_+B``2p&0t^q2a2@sFSd5()z#3b*HLKL)u6SA$<4XvhuJO#wPSNTJL_Ae zdnW97ct2qKt}x-`7!7IP4wo9i9;|C! z+~3lWG5i0dDAhyka%0`;qn#cNisvq8 zsLgu$P=%dy7n4H6dA5dw!EFo`S#IB68GpH)^!ENSfg9ltjO<6wqI`MZa~DU4%UkU$T3I;NPAzaS-rK|U{;O|oEI;$^1otN# ze@ixLhlj_8Ff8Do@klK5(wU1)0j}I{Ymz2~a5DCt46U8zR`Vl(V?o3d{;ejCroC^} zVuDzo?U=mysk&l-bjVWXh((S(B27+a>m<4~ZT&TTyGqu*JfYg)b56G2ry0dh2NQQ|0z?%_UhU1*tq{{YRM&}TxRIE`1G)nCxoG^ zt8wklfaIxP@|bhZH67=(d!Hp{VSGM$0n-CZhd{@QYHumKY5GrDCGJ$M=bq0g!(=hD zXw&THh5?K#7(y6wn5L}Tl)|jQT>p)K|MrzHVzCH#_+;hrdiLBogGtyy87&-hwv z7-pG@eeIY1>bpvDrL0O*M`l=RNrYI(Q?2T!;R#dM|5_?&CgSNnQ)5Pok@2UAt-bY& zE`M|X^viVR(msZy^?xQE6`5tBts{K?owL@_?DdTQ7%v#y@i5K&t_{ppswJ)wB`Jv| zsaDBFsX&Us$iT=z*T6*A&?Lmbz{=3f%E(aHz}U*bAj+3H6GcOAeoAIqB^C|hP#xL= SyRQOuFnGH9xvXMXI_0 delta 1226 zcmV;*1U37p2-69W8Gi-<0063Kaozv`1e!@iK~#8N?VHOhe190n-{Te`845e)5+WN5 zxh!15!X?VM50ee?M;yi829emHEC{(QkozS`7`ZQGVWFg?#29`(pMJ-eukZJJE^`iN z%=y%5YI^3(d0wCQ^E{v1F~G%}!NvWD4nS9cOadIoy~_Nlq<^1r9H**EW!?O%oaafY z3Bf4<5D2v(CFMc6 zOiYBozyF&9FE1~G@oq2};O*@VvOPLF!s6m0^7Hfm_&d!47#kZyO-&7Qa&izH94s5a z>gp=``uec7wSUEwM9QeGt^EW;Nf3%CU}|a#4Gj$_EG+y0K(PCNGgw|;Mn^{n_V)G= z8X5{OFE1P)AEUm${)46F08CF$qp`6OMMXsj3=EX&_nZC7$_fKOPDe*aGYFTLm#|u` zHnZ9ME4e6`6ctf`QUE9f2*BatA>!iVkd&0fRA9AQF@HNdYpbiPQyhXK0F(@YuC6ZZ z@9!fvHWmd11q{T+#RZ0khmnwwpm;ve6aWeV0hk#b2!cF1I{KQC zk@4x79mxrr1JK>wjh&qxmIF*C6LNEN+4$n%-~ba76Br*KXUX<``!N702k-zQBO_5# zQi8m^Jb#3Qgy7-f0qg7Q7#bSF{QUg0#bWVL0)nO#u(q~_o}M0TZ*Lro13fzW@cux96$i58c;5vvbeOg1gbm~ z9*(L&a{xL!JE`Qckswt7N`_%!VQ_bMXBW*GPJd5NLE%zXR_5@KSyKQ=)>H*Z{(PgM zv5$`rXwJYxxWB)L*=$y1(xfQ>CnqN?%ag>fudiXZ+u21EC4Oc}ASfK%+}zmgv9hw# zp|OFc0Nmc*;_U2<#X0q|&1S>%^E1160QBkS=f?oh2ytd+2Ib}DvU7o^08mdqJv}jp z`F~#LKgn_aqL85PsUozuw<9Yn>t_IvI*X#UgVxqoRw?9G15GJFDgeqA1RyOfO$XqT z3RqZJKwDdz>xO{S0T>({#QFKTV5o0wY=CTof`a~O>$Cs}LVSGuU!9}rZ*_GwtM~tE zP78phx>Z$Gf=UoF&;dAG66AA$t^ijL0e_*`&d$z8YHF&G8Jso;2vq@E3yg}2`ndq~ z9N_9XKv#gS02dz#3RMA0|6(eE)0RQO`UXJESitE3h;dwsjSj%sCPPwsSB$N$09^t4 zqNu(qtS^geX$6McrfLZ|P7(F#QEJdS1+C}=--C_Fkfq?H;Soe1BH@3T^vI+&cD5|k(bF(z~v(Q zB2javyg;^#ty7qUu8BI8*~V1toiptKi`ynut_S%>m+E{C+8d58dz$m<*Asz7E$e3| z_r-h;?7w@}^_WA1?VG%US6t-*$9Q?`AG$B}n`>jepCy08GFh1=O2s#U)~S}bMwFx^ zmZVxG7o`Fz1|tI_16>0XT|<))0|P5VGb=+wT?1n)1A{AvSh`R&h*rdD+Fui3O>8`93PGMkNofkFQB|3o0=?djqeV&R{h($Lh_*7o1P%x>4hg^hxda_1N&8}vHY z2;5{!DNT`NFp@~)_{-z)o$sWcgeik*rs8tRMT-kf1Uh+Kk~SF!ePefLV7UIaLh!*o RF-D-V44$rjF6*2UngEDKCOQBB diff --git a/share/dark_resources/new_file32.png b/share/dark_resources/new_file32.png index 5e403c245a2ac019ed28543d0b7324701a49db37..80421e92b183bf41b1cb7780d801d89dd03d0257 100644 GIT binary patch literal 487 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`KiRit?L@sH8pt3T^dtaSZV|p8V%L1MBL2Ek+Mm zZOSF?NW5FzZFGp&;#5ITBCFhA&iJAVIU|cj(g&N4)Ez1i>u1cfQJ4H@D3eg&VA|B# zSn*-z!Kn}J4m+}?7V#z|{5bXCY(amb{U*UBk_|^W#1?J+_b2K6hrUJ-nA+H$&eg2G zlI_fcoebsq3eAi!^?n@Nz<=(Vn}kD_L_$L#vm393X~GpCLx5pt$h1TQwV>%dO(#8S zzV`7{gc-LuMlh6XsplOzoCXXA2GtVRh?11Vl2ohYqEsNoU}Ruqple{FYiJT;U|?lv zYGrDoYhY|;VDPei-W3!Lx%nxXX_dG&%($hN0n{J~vLQG>t)x7$D3zhSyj(9cFS|H7 au^?41zbJk7I~ysWA_h-aKbLh*2~7Z6>zqCS delta 166 zcmaFPyq$4^WIY=L14D6D)fXUD=jq}Y65;-K`a!M+10LtQ^Piue+Bp5_+KHR0CRALG z{QYUogIkX54U^ZWo@X=({kYM3`G_l(aJraLFw z7p8R>H6*yT&HK+B5byp|+n|B>1`^6KUQo7G{^r-~^+#{At?Fac`&Iozv39EH7NAoY NJYD@<);T3K0RSA=N&)}? diff --git a/share/dark_resources/new_file_exc16.png b/share/dark_resources/new_file_exc16.png index 4053f6dd31eb98c82290e11711ed2f0532d56f22..77d80ef2a6a574cfbee065ec76c98d79a98f425e 100644 GIT binary patch delta 295 zcmZo-ZDO5}TL1t5|NA8m9u_}j_=s_r~51_lPz64!{5 kl*E!$tK9sQ%(O}dBLf^7LJHKr0W~mqy85}Sb4q9e0Ebhtf&c&j delta 295 zcmZo-ZDO5}TF=11pwKNZ*CY3zK>^4n0{}J70c)GX$S{|IVI~Wse78JM1ZXA@$@j?5 z1&c#OfFwi~s8X(5Zmt#s15gNP1jH1eD3A+8Kn5KA|NmdkZMxfJK1MHAGxz-+7bnLu z%5gpB5)sr8=UV#n{Nz@~r4fdfx`qb2Mg}2<=2j*KRz}9!1}0Vp1}B|YOa&UGTH+c} jl9E`GYL%Oxl9^V?U}S(p!wxwCO_0r=u6{1-oD!M<(ilDb diff --git a/share/dark_resources/new_file_exc32.png b/share/dark_resources/new_file_exc32.png index 4252d051123dedab660832db0c87acb40f3ff8c6..2c3949c04c5a5e37432e5c0b36f76b8239987ffe 100644 GIT binary patch delta 350 zcmX@bc8YC6YW;sO_zVVcHW~xS1R7+eVN>UO_Qmu0HQ!>*k8H@~YXh^VV+5yzS N;OXk;vd$@?2>?%b-TeRn delta 350 zcmX@bc8YC6YCQv0!G8vYISdSQVQ3B`!(>h-`5t-sZh3`nd7!vlkKAkq2A~L#0p!j} z019=>0r?<3j0`}{KsJyBN(1!(5l9wH0*!{44q*V*0~wf(hg#3b`2YX^yo^}A$u5i$ ztR5ejuDqJOkWr57F_(y-hB(*KpXWE9WYlDgFtpS)G|)9N2r)FbGBL0+GS)UQu`)0? u>AYep&}`Kb*NBpo#FA92-29Zxv`Pje0~{K5$O&kI9OLQg=d#Wzp$P!lG)GJT diff --git a/share/dark_resources/new_file_geo16.png b/share/dark_resources/new_file_geo16.png index da9bcbede625896b1494ad92001ec2bc33132186..0f9c48303012164ae8b03829d4f2c39bf50a596f 100644 GIT binary patch delta 284 zcmcc1a+hU7YW;t50mJ|MKm^py@c$l!jf2E1D*-kIVi4RVr^}0PPyFMe%h16p>%qXl zz**oCS_16>0XT|<))0|P5VGb;mQT?1n) y1B3qWqP7eS45}rr5hW>!C8<`q`6-!cl?+A(I5hlQwYCwcfx*+&&t;ucLK6T)@R|4k delta 258 zcmZo*ZD5^{TF*dL@Si~e11bJz03wh$rd9vh{{KHRJ<(v|D_d5r;C)x-P1a$Q<9f^` zBB&wGwe;ut$svqaA`C5c4GnaS3_=XetxOE8jEuDnOsotHPCBoc3N%r*#5JNMC9x#c fDmOnRGp&-r$N-0i9dZJiASZab`njxgN@xNACX+MV diff --git a/share/dark_resources/new_file_grb16.png b/share/dark_resources/new_file_grb16.png index 49840289900cc4372a75511fcb64f624b176cded..4777955fff93f917572c8236eb41b1015bafa293 100644 GIT binary patch delta 316 zcmZ3^x}0@FYW@HJ{~7+@2a;p}h{gxS4<3{}0Ff}pz0wCa%O5-}eh5VOz*6^0AKou{ z_z;4?;y^Y~{X=`05YPyy5Lg<*y${q376(cJEkkptQDyl1$;ym@tPCBjvL2Hw8RfX1 zu<(lVnfQlrVDNPHb6Mw<&;$Tu^1c56 delta 316 zcmZ3^x}0@FYCQu3!+!<^AV~&*Xq4}fm+zJbkuZj0m%Lhsyj+hQ5GjJC6uaaUy5-~` z2rLd{1J%pf!-RlFK!w245Uv7HGgurb1+)y=q5uE?56;^YJ6V}Akk$4=ZeZl(N=7-Z z$6O+U8sc0_f1aPbka1mvp{1^&fv%B3h@rWaiGh`ov9^JUm4U%Y=M__d-c>DejVMV; iEJ?M>%}>cpt7I@Tz@cG>oPZ`Md^}zKT-G@yGywpPJx6!| diff --git a/share/dark_resources/new_file_grb32.png b/share/dark_resources/new_file_grb32.png index a47b28a2336e53a0fab9872df3fc6a02d1251095..d2298aa63b5c0af6ea4f2b86bee46f9213f19a9d 100644 GIT binary patch delta 308 zcmeBV>tvgdTK^vmK7#?Ajm7|Sf$|VRTqMKmdKI;Vst0O>lrw*UYD delta 308 zcmeBV>tvgdTF*dL@Si~eh~#_Z<-6q}q(Zm6T#p5UX1bs0X4B z(@8+HfI5L{{{R2~kN-o{WGO~3Rx3ZwBflnRGRkp1<`NOq5a(L@^Ze$Cj0%hqhL*a9 z2D(NDA%^BwCI(hU#@YrZRt5$qomWf+nyp&m8c~vxSdwa$o1c=IR>@#wfJ4I$IRQ5P)5S4F<9u?00)vF&mHK_^ z#rroq->Bhv^swjt#VdcO-}vFw#K`3Tr+SB|;$fELKR>=VF>*;RziqRswR3aAty2d# zOu7H>>+WKw=)g4*KY5P*`}62D? ZNY%?PN}v7CMhd8i!PC{xWt~$(69B1qjm`i7 delta 238 zcmV9(olmQ+d9t^W*&t^zVOJ{p?^5n^c_wV0tg&9JW z0kyTY3?Dy!Wcc~>C&Q*qo36ij@j{Cv1CX7ptgL+I-o1OKqXrD`Fqko8#$9o7@jtjS o>D#w&&pmnaBnoRfASY)70DSMj5$l)SNB{r;07*qoM6N<$f*`|k4FCWD diff --git a/share/dark_resources/new_geo32.png b/share/dark_resources/new_geo32.png index 8030150ce62d20e64792e3bd1b4b46f74b06ef7b..c2adcf5cd949b5dc532d279e27a53095d2c09aa8 100644 GIT binary patch literal 523 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr16wo*Gj6g|ZU+jomw5WRvOi(r73J42@IR{p6uRl@;uzv_{Oy#DSxkWfuIJwv zvxxj{GvQoml90T3sgu;~8lQa%bK{c|6VsCuADS-_-LgU8p{~Y`hs!p0R=(K9rS#_Q zv$JO&-qV!36ZLI-$i(Rn?wm?Xba=R6-LcCL?u6xko6E-F@cF=X7n?V2t7hBJ^x$28 zy?%XMT-|gYC+Wah&bo|Tv)9=fGu1V0O8hwe)=UOY22pA4cds>%3Oe)cVbD-jzM3;x z@lage?=#15^4)tY*sgrYQ1o5Sfkz(tp)5rXd?y&o894s1+iulkSmV98Pd2*a$e*C= z*RSedQa8V}k-2;U(37eqt`Q|Ei6yC4$wjF^iowXh$UxV?MAy(H#K6GH(A3JrT-U(Z z%D_P6Xv=jJ4Y~O#nQ4`{HKfk4$p&hW1lbUrpH@mmtT}V T`<;yxP!WTttDnm{r-UW|mx#5) delta 336 zcmV-W0k8gx1mFUY8Gi-<0047(dh`GQ0VhdBK~z{r?Uy@>hAfme3H&f55K`oEPfl)e^TC(f=gaYN2|x(h zXaNZ!RF`57umjUTJOZ$78;YV_%J6-EpI?fi5NIGC0VGKRU4Pdv0c2T56h)9E=~(yF z0y6+rRgtDCJkLYl_m3f%0ce_rIF8XY4eGkavMi4vm;soki698jwk@`8Ll}mu>$*R8 z&%q49vMd;efwC+i2m+>QLY8Gqp68cI$qc}8oFfU(+F4RE0~p5<^E@AKzxQ=rkFo2z z%UoavaCY;ms!2EiH^2>W1Ka>NzzzHZ1H&*t6h+!k(y@Lo)2`~mM+M2N$bUAyD#=&` izB_~JBYAh&oB3ZFNaZ0#I1AhW0000 zfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u00Lr5M??VshmXv^00007bV*G` z2jm0|6%Y+*b%I_100X&6L_t(&-tC$3Z&Oti$3N$`uf?^igMYCG){H48tcVj~21BL{ zQHcJqm>7RH@&CZc68{qMSASMaMEGG~q9#P*9D<8g3u9Y=^|fnX*Vp3@tJTTc_xgD4 zqS@_lz3-m)x!-s1x#ylE%Jw$1&F|jHr|e z9LwP;(9a7@Gk@mOmZ~e?@fp`TQK7v8afUfoJPZr0Hz)ei@lM-LE7!Cjmz9v&)0)P05@xAd^tP;zVu)Rlx=!gWk zz#F73C&O_jd7fk_00KmO07SXO1pqEt#b@+1rx@|J@8c8rSHJ*=CC&}~{^^OM$r5*Y z$bH%#xS^f}1}Kx`HJOl~ch`<_mJ{shnF5LcQEJ=*4pB+RU$@qH!1Z=(I8+6qKoTf3 zCP36VP=A}^EH9Gii2@N4zzsbjRV)B*GJY`mHVzJRJy0OS1lNHd^?iL$XMh3NRXoZm zjxf+_sv#->a1zM#0WK~}i~z(K;SjgDL#>MdFUvbRMVbf^3<4M)@qiS=&_|jgQ|M~s|-mLgJ6)xuZ$tD%Vb?@xPPtOQAhywmJvwRV`SH(Vy}zOwuj|i z2M~|`|GxrV1Q^8D&(&62=haqQgKemQ0D`Tv3aA>m;hxa`KBq|Q!H&dZ#rEG0RS9el>LoFhzooS!1-P&-~#)Z)s4AU zn{z%NDCHQ)4?HKAxyrskGY$n{i8D-bTlf9LjIGxK0R(i#DJf{4+fC800He_GhdlsL z`Xxoa32+)XA%)&408j|%d^flMazL^Juzv&4Q-JPOmV5xz!GH4mvE~(|`cxpe$MG8J zovx4c0r&K{bPBRjWJyA_b$Y^=D}I(Qc#C%xItw~x0Pwo3c-0HmDN}n%=GOdMUI6P}X^*zwg>JY=){DU?YfFR;;c$S)tsj?A2a@H5T-0G#52g1ApyA z!J=MYlzCPfMW@FfX=~Ra#cmRazw*l#&7f4UDNxzkhU^rtw;SM34J8$CKeVwZ0000b zbVXQnWMOn=I%9HWVRU5xGB7eQEig1KF*H;#Fgh_dIx#aXFf%$ZFhgAxqW}N^C3Hnt zbYx+4WjbwdWNBu305UK#FfA}NEg>;9R4_0)F*Z6eGc7PPIxsLY0IeSY0000&K)IAg%o_LD7gHj1fbLaDGB7{chZR7<7$ z;}0b~M@p6ugjYio<5qN1)f5m`Xs z1ptJ1b#Cd4+PjL13O#-LlyL9t>?{oq4pLxX;6I-eEP&S5R{HSa z1Nr#)(6eXHq<;o5GBQGym6i1K=TD|d(2S2CKZ?QN69g|B(An8Z2?+@l92|TJz^&VV z<%X|czfy5=G5!Ain@mkj>B*BPG&eU#pFVxMbf@3|bai#n=g*%hBqW3k3=AZd`~3dl z;b8^OAVbrcg5^Ph9!(JAtx0ek^~34Z{<%*+hg+uM_ag9Foosi`UI z?d?5^jg93U0xtmgG=b96QktBcr036{Q&3P41F^ikObrbU^z!9P-u;1~0KfzQU}9o| z?Ck6)A|irCmxF@?0_5iA<}(iu53%ojAD9yxj{5uikK^Lv)cJrQ zC=D1L9i{T}avB>OBP%N_mJlJgu(q~lvaYVKQeR&mb#!#FTp=zl?%tXpC;-@D0Qm9a z2Md9oo}SDH005!^d;!AZ(9jSe^1wXqs|A7sP=8WVf{@2DK|}yJLo+ioQd3i77ixw- zfBq26B{DMd-YK)706?t~1)%=iLTap~rA4S2I0!pCI}{TW!%NX5C;;>G^UTXb#n;x> z=;Y*tT_}{e$`T-84yvlEta^-&j=ooJASeKvo13(-u)ypbyL@zXM90U+?BW36Q%6UK z0e?V-*xlVtZ{NO^+7}240CxKD@Q?}2?K<}f!MO`2fuAEH6crVbmzUS$03c}&em4ku^c#)X)&UZONSmAdaJhoPVC4PW$`&Yz6>fwY9YgSs zkc^FuZ)6~M01&pY!zgj#ysip}O-*I_|8+~Q03f%IkB_JA?QN>At|ki$ zi+{?6k~cFmlL?-dmUd&8S*`$}oi#o_PL`IIVtxMGY+dd(02N(URu(ljHnQv0tAAJ0 z%6#cLxzPah^HNe$n4_z$ttE4FbHxIHu=noWJ0>&$7#SHU7J%K|T}nzyVgn9%`HSA4 z(+;$~t}btHZ*q2amj5VllMg`skE94q5N=@xfVTLf0RX|8o10k&=PpqIX0o`r__zRY zc>uJbqN0Mey{}u35&(qdGC?;tH-9Q9C=i2yOb}zSjEoF&a&mfH8UO&O1$ugVC^*Vk6FIEenFv`x(rtt7^($v(He%jzC#egFO)$LLwwd~r!~YK)iRC;)u<@`VAw?Eaw^4prsm=8E+U9vlGb zdF1vu)MRLAcrO24-xrV+7!F5ZK?884=01m|c+miqx0vwYc^CL0?Ysv?m{Y=-vWCLpN*vc6vlK!R88r1AmS z!H0fzP7EaloaX$Ia`389d!3pUJ zi3vc^k^JGH()QLwL1yO1^=xcxZKd%{iHmIJ2DIrO_HI*{!FgfWJ}Eak-;h&tcK)@hq#eBv*2WRKQ^+7z@85s<(m+oaW zn4Pe$dFPZ2@gAuI2Ml-)F@(QTv62S_W;4g&)!%A4P)?h^>bP0 Hl+XkK7{??G diff --git a/share/dark_resources/notebook32.png b/share/dark_resources/notebook32.png index 4f8ad4bb09173db7411454836778bdd57cda5651..7537b94b2e7d41463667ac412d90a0419d57fecc 100644 GIT binary patch literal 433 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`KiRit-!$bw6+sC{*w1;uzv_Jo(Rg2g!s*0sj>Y z8dy8uo>cH&vd*2yI>E=SLSa|^O~)l=Y;0_D0u7x{pQp!heiDto*O#Ez?N?YwyZgiey z*mU5)ai*he3=H;4LQ)1LpRNL(qFUk_QIe8al4_M)lnSI6j0}tnbPY^&4NXD}46F=I ztxPO*4UDY}3?B708-nxGO3D+9QW?t2%k?tzvWt@w a3sUv+i_&MmvylQSV(@hJb6Mw<&;$U0A%Qvo delta 143 zcmV;A0C4}Y1E2wr8Gi-<0047(dh`GQ0B1==K~z{r?U%t001ymA`SbocagfM35L*naY7x;$+Vr-KDDgRvHGzR|0;gQp_hTbD%PDHLkV1idDHv#|v diff --git a/share/dark_resources/notes16.png b/share/dark_resources/notes16.png index ac73e890a3e58275f1a116bfc6b84f1bc3ef44df..c3ebad9b48bcf2e4da595e21ee3ae6b0f45043d2 100644 GIT binary patch literal 463 zcmeAS@N?(olHy`uVBq!ia0vp@KrFz)0wmK{*=_<-Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8ZEE?e4Eak7ak=)~Mla?>f!2$g zAMz{ZC`Pyli?y%>abMfU__bB!pzq_$5$}XOs-(TSPnRfdynHqy=T447Mfc1^yLWR1 zo$hQawf20c${d{CYTddrD)HU!Kn3b{_mT(cG}NNalzqa85nFAGTeZoAvZrIGp!Q0hGYJnJU|T$ Mp00i_>zopr03>Xj&Hw-a delta 130 zcmV-|0Db?@1C#-f8G8l*007OS^*I0l09#2!K~y+TV`PAWhK7d!4Gj&9ATErJO$;Q@ z2$FzlB$fti0@;AB8J`$+HK98d*}ph#qMasULk<*RL^}@}e_-`QYobp;z-)mfF}U+c k4hUj3z|@hSU`e$J0HoTDg54j6!Th9==x;Wi4b?`(h?CV*{(Sur_yj z^IYx)3zjT2I>;JvA^MV_qM{HF8?PuY5AU59)dzfvjfy{=KYRAjJ|jip{~W0WPcJUb zmo|;pYRlVGX}**tO6}P)v14{;bN#r?*e^b`pM7GRz&oH%R7+eVN>UO_QmvAUQh^kMk%5tcu7QcJp-G5=ft8_| rm4T(Mfw7f=fp)uBF^Y!V{FKbJO57TvZhblr)WG2B>gTe~DWM4f2U?a4 delta 130 zcmdnSJcV(BWHlQD1B3kM|A{~<+SA1`#KJ#0#etcZm-oN4l$1oGiHFo|2_I?Y9>$=S zJPA9y6G9VgN_iV*dYw=`anHGsF_h93|L9*dHB`cF+)2O4ob! ijCICImt72Ue;JM>Oc2aFQoa~y4TGnvpUXO@geCy_1Sz=y diff --git a/share/dark_resources/offset32.png b/share/dark_resources/offset32.png index b32b117cb5f8a327c8d590119e4b98eef99e1be7..6f32dad24788434554649fa658ca3072826fa109 100644 GIT binary patch literal 361 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKpuOE zr>`sf6Bb@k0T#iPRv?{)o-U3d9>?EKKFD`Kfy3GT{O|wzU(fNW@g;Va#cX5gyJfd@ z#fypBDt}ou99T?pPq)7`-4MNdd6eq2qrqX%*6k2{@J5jF+B?BTF7N$Ue35XC-;yBP zvC-h0AuF5V{qmFz-5=i061ZtNOThT+#`iG|`MYeY#(Vo9o1 za#1RfVlXl=GSD?J(KR#)F)*+)G_wM-4UDY}47>ugH=}6C%}>cptHiCrns+ikPy>Uf LtDnm{r-UW|cOY{{ delta 178 zcmV;j08Rht0>c528Gi-<0047(dh`GQ0E$UOK~z{r?UhRoz#s@j_2zT)Ha4;82c-t7 zET-$qygUJOTKwh3`H28DKm#<;Gyq^LOA3I=l2%77UJuO#Xw`ZF%nYw}9^bdR1jJv5_X g(*FdY0UDrz9r^lLA$jUKu>b%707*qoM6N<$f&*nso&W#< diff --git a/share/dark_resources/offsetx32.png b/share/dark_resources/offsetx32.png index b32b117cb5f8a327c8d590119e4b98eef99e1be7..08e0a6f172fc42050fce4de5c836aad0c42fa212 100644 GIT binary patch literal 399 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1Gg{;GcwGYBLNg-FY)wsWq-oLD=HxLw6=dWP^ih%#WBR=_}eKPc^ec2TRYTjxKj$1Jw<@Rgtd(i46P>>j`-Z%Yq{Gl~rZ_cLY$Su4qWIbo&VP_^s z=SWeHSvK7twfPU~vxx87>#C#B*d_*ajcSQ&L`h0wNvc(HQ7VvPFfuSQ&^0j8H8cq^ vFt9Q-vof^MH88d^FmQ}=j6~6po1c=IR*74K0sGIVKn)C@u6{1-oD!M}9^bdR1jJv5_X g(*FdY0UDrz9r^lLA$jUKu>b%707*qoM6N<$g2i)7MF0Q* diff --git a/share/dark_resources/offsety32.png b/share/dark_resources/offsety32.png index 9174daadfba2df737ff6357edd697521b3a8baaf..954b3b36903db53846eb97009b7ae177d52d986a 100644 GIT binary patch literal 436 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1Gg{;GcwGYBLNg-FY)wsWq-oLD=NU;e|CK&P-wZQi(`n#@wZbA`I-%QTX2+%8ajs(mUV$zn^saT}Sc9f>%t1B3tH(hz05N z=EhqV>#c6x@V0a2%#%(x$_$K!#hkYD&#q;!5p=dyFv#04%izZ5`#U81^Rbc>zE$FT zEiG(4crP&Ueu#H)uz8~7WV;~VZOMF}D7P=GzRg=&bueoGgAF0`ww>E~j_E-vr%i*j zd|+1zv%!(seLyFxmbgZgq$HN4S|t~y0x1R~10w@n0~1|ClMn*~D?>9Y17lqSV=DuL i{_mo;C>nC}Q!>*kaclUuYHcG>1B0ilpUXO@geCx^fs4HW delta 212 zcmV;_04x8r1LXmb8Gi-<0047(dh`GQ0IW$wK~z{r?U&&SfG`Mz+nf95g^?lRN>6A6 z_P4qFc5~p3ZSglM`b4yIJrTkCz=a|%2S6bp04rXBNCV8oQHT_P7H7+K57>Xv-U~Le zB#eAIlq%sHVlt+MUFG`J;x`B+9YFy0Ix6`P2G9`5$;HhQKs5b4tvdjJ#i${1)^Ga& O0000k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1HT^#Gy2@rcn%a~FY)wsWq-oLD=Hwtx*}~W0|VoFPZ!4!kK;=x+j=NFO0>=Y zYshJ(&~?c3f(M_AtH9Ayhy2bR^3vHNcu`m+=lr2lQ5(hjy%+YjE^YOQvOI0#F5vi~ zJ>y~g!zTiTEy}%oRMJ=0^5aa&l)RwCCkjR25HHG*fA^O-na}=c}2I`TbJ0ZP!e=GW+Uu zXZF0Oay6SoBQzXly6@EC`Y*M~Uqmx|t5>~Ss3WgNxN3;g&MXJfD=Xqw#w%H@ne>eP zyhD?zm(I(7OiYXu)ZE*Q0*+g5p7Lc=0>hRKjuTblBOh3Kq_CeaKFb?h^H{Iq4iCfZ zy1b9RLgK}Lm$aFEHurgItoHmYpI!F{B|Zf!hHn)n*>>Fq`s$B#E?pp#i;Nq* zHP0n~nz^`t?F;K4r#ZXl%ureXa#g>k;iVpJU~H39=zLKdq!Zu_%?H jyu4g5GcUV1Ik6yBFTW^#_B$IXpdtoOS3j3^P61*ZX!8Gi-<0047(dh`GQ0B%V{K~z{r?Uum`fG`Y0-Jj>rl^#4zXi^YC z-p*MYUfQvB7)R1+$To?j)!l0aRR9B@6PU!{R`d9YTO1aS!QEIsgCw07*qoM6N<$ Ef^oq(+5i9m diff --git a/share/dark_resources/open_script32.png b/share/dark_resources/open_script32.png index f8b02677b580d9bdbc5c3d55ad248ed29afffaea..478e77a59b89c51186da361ffb9c8a4496d7c02e 100644 GIT binary patch literal 831 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1J?%-W^`I(0#wStUgGKN%Kn6fS5$!M$Eo?}85kIAJY5_^JdU58ve)~tgT%4< z-isCHh#VA~J|jwI7w4-58XQV@kF5Q{Zt+56U7sG`IzGKVzSt!p1uIu~Y?kl-yUfdB zO%-2M@$&>;Pv3Q&f?v)S$ye5Wulp#}Sg@?+%75mDUt3rB%#^&;D7<~^+@0m|4X+wb zD1NhDD78VCeS&{r<@EK86q-K|x7BOmrhK~^zWv5KKFZ#~NIJ9};6S<5nT*f|puY8WoUS#QTifK zu`pb*XKrG8s!wWOdPxR@v61i78Gi-<0047(dh`GQ0ryEnK~z{r?Uy}k8$l3;XGT~MNTVW+L8sN8 zFzyVl0{M^$sa!Z+$R9|Ne~|K87j9j+Qs=^rA#rJtlyv$5#-Lpx2pHTM?8Z)Z!U~_b zQ|@DRiX;qDqhj8D_t|%5?<9mJe{jkB!wTS^1cVSTiRdE$P=8K)t~}2>Xt&$HXK7;$ z!1KHc5nU3|3rEwhTI+pBZK5m&AcQz1qA!oin>1r%%rhb?1Hc^-ZT9>9UqvCt0F6dt z+ZfZc(KGY;U@&-}X6pO?JFBsE`;Ca-T>+T+frw6&QrC9P7@%ISpCaN1W6T3HZw-gT zi!4(qv`JAIwE$IQagzN z(PEx)5Cq(6wJLeKux?vr5Bc8!TsIDNzVEl0xw$X^n~>c+2!he9WdhV{wI8KY>2*jK zE>1gTXquJ6OaM{iNh8(AG2{2kv;Z9dc#;*0J0RRAh z0N~d3R8#7n13)S9Z775|Bck0Y4U5XZX|4BSKS-pM8;JOsnb(TCx~ya7dm=hgO7&v^ kE{o@(SsVQ|TY3V20T^17FuXwxj{pDw07*qoM6N<$g5I9=M*si- diff --git a/share/dark_resources/origin.png b/share/dark_resources/origin.png index b8b4e317674185a32b22d19e73c6aed3a45c3169..46faa1fcda34053bffd791a18c0850aac32c707e 100644 GIT binary patch literal 610 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L9(5CAk%;=;sy8qcVmajOP1~{LM)Eb(T*Foeq6pmP?u>EyT`(%tx-RP#P&6;Sh7Jt@lJz+ z#51moD(|-5kiPz6X4VhB^ft-!MgiP4Tp2zdTK~o6(r4T5lL!iseV}vv)eGaaF3HPg zNhj3!x?LB$mz@35V|p#(^7ZdkvFuXass~?~D)Xsdy(TTyTWbB}h9dWuC5qci8f4gA zUQXg(#d9QRxsxm3%Lc8D9J=Wm28@@UOcB3lG1>aS@+oRZ7%J9%{`l|S!-?eqm1QT5 z&rX}go+QOEZz*e+_Ew%RPiM}XmCEy^QFNA~Bty$Akx&=6vpb*YshiyG5O~n$yYt!M zMD6D>Dn~Xq2Om~R?b2Bpx-(_|b;ZNy4>PSQS*fh|bAIBK4)tFz5ASDWI$OuvFy)~r zFgR69Tq8!z*`mn1J6REO_`Z^32jeBJggvs5(?@eyE6tvidX*wsp3D;gS3#&WEVnkl{PT! zkg|sjyZJ@t_U3)xXTI}z4`@@4X_^B{>7ta9ce~xkX*w_|k$=zUpDLxWrfG`+fGGVP(k=P}Kd=82jV>^Sv;0^$A%Q^ou3W_->m&*yqaZH5J_M{gnrRx~u3)3`* zbumCTn_a^gUrw_d+}pPOzSHS^4>dzTu~>XwsZ{P~6^A*?vR*rm^E-%#fLt!OiV(UA zMU>Kp@B58pGJh$RQkw{&Z()ux_JMPLHVPmJAuAL$o6Vx@y1#;W)E%YtKnU?Q27nME zLI@23tyb$zyWPGEV#6?AR;$%s#N9X`lgX^qYPBB`(Fp+H(D!|*>-tAR$bRGt8=Uj= zn1fU*^{ig6d-F7rQfdex+A%;7KnULvLT+Y37-L(U^J!tP#zq-JxJ(GSo-#;4^^gJ?maPL^7f$3-Ty)IoHTM;9!Pcf(Q!+BUJC03Tw&1F1MrRwxqNB?n z)&_UKi{<-X^xpRS9EJT#OnL0wFBxSbQba4CPP`ZMVj-96J4wcSk6)ymQPG)Q9qoRz_ef5j zvmx*Fw$kHAFQ|8_eiybqHBC6ASG4o}y$K85820^OVq)hxI`7NUxa4kiBNn@vPbcl( zAIIRckvHbT&-=bFJ}@-r{$LBeF+;}f0X zT|<))0|P5VGbh*rdD+Fui3O>8`9p>z#s@i$IW~5Eto($256l7 zbIKFiDp&IXxOE$VRL9Z{D~v@M=mV&V4Hh9UKx}!oR;UBAc~|}oKy_24fu6TfwgKjj z%tY&K9vb`x>}ud6kiRZW7o;fo85_9^P8{FHU2z)EMwu;(Iv!LnvV5kQJ6R?kh&g=^ Twy81|00000NkvXXu0mjf5`I9! diff --git a/share/dark_resources/origin32.png b/share/dark_resources/origin32.png index 423af08d80cc778719c290434b9798009aec1b96..5cfd7cb56ace575b06806a37da5b39a0f6f1faae 100644 GIT binary patch literal 804 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VW5Sk`z#DMfnZ>x*xd6z`*#))5S5w;`G!h))^v!B5nJ3 zzhiSe&hfEvP1!z$){G_=Ayd01Uk67HF+-t6tNWFE)HQu%2POPFW6Bf^&b@7{pmZaTk z<%{t%8Uog*P5p1IxLoq9nxD7Yf@Cet+Z(RO@Za8XV9MGeWl&G zOa~HgDwR&-2$)vgkf=LvZYkgSpkvJIKHX5#d;h^HE5ss2yY_&FlXcA&zU}b1(Wn!UgU~FYz@Tm8T9g2qB{FKbJO57SI zU+`%HYLEok5S*V@Ql40p%1~Zju9umYU7Va)kgAtols@~NjTBH3gQu&X%Q~loCIEU} BEerqv delta 243 zcmV;Z8TyKXBezj z`)2~2;c=m3I`K2J&ungHqwCf-Tm#<^aMet)%7$j30%srtK|l`f&bbH7F2WCh=#*8l zCRaW?KxL?!%zPn$DOYtz8EyckKs7sxK`{=1${{LLf;>(OplqfHiP`|F1l^Uu?8e^# zPDT^J9u_MZ8s%0Ge1l$UGJ8m>gjIv*n9n`5m;pN~)xl}43I(~m?D9l~@1>NttZN2Q t5AM{#0b6sq#cG=(oA-}?RQ1c>mM_)~?H47D@y`GN002ovPDHLkV1jNuXa@iQ diff --git a/share/dark_resources/padarray32.png b/share/dark_resources/padarray32.png index 6a2078bd48aed17e9e01b7e61b6a7aa09e9639f5..eb9ffcb9702e8b7ceffca6663e6b3f40f3c98934 100644 GIT binary patch literal 409 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1K(i~W;~w1A_XYOUgGKN%Kn6fS5$yO?8v{zK%pK_7sn8f<8LP$@*Oe|U{M!Y z_etr~z9T~aODY;J^Rq^raO&y~U`dJJp1i)~`CiAqxu*|)*Ka=1yXB{z(8LQV3`)n| zq)X1`na@^vwn}$WNAR^PNlMKJ)OwunMqm7PL%jV4?*l%csdfi(@KPGQp!4Rl&@0rrOmH&Y5QY~?fC`m~yNwrEYN(E93 zMg~R(x&|h?h9)5f23CeF_7FR&%XdgLvDUbW?Cg~4dQ5xFNln=2^x|T zx8L48KQ?cU;xmi;kIMjnEn)`1p?#~9UOf%SbehP0+7*F_&Lm)6A_6g?4McS`KmvUU zoXcgoAwT(s-fj55P3WCGyN+qdG<*<ycV@G(ZCV2q`cPy edou5RLz8Gi-<001BJ|6u?C0B=b|K~y+T&680Iz#t4m_2#+xq(Vh&q9S9= z&sv^s5_1vo#F^K>_*|7<2$Akybf*7jU|F zOlM2t%4;HC%f$q6L8B%r+D8E9l0Ps2)bG0j>_qhm3gsGb5fG3#=D+{|002ovPDHLk FV1k@sJ8A#` diff --git a/share/dark_resources/paint20.png b/share/dark_resources/paint20.png index 4f6ee1f9e6498858606a8ab938ec45877e8947e4..093ce61e9a164c79ad14fdaebf239563f9b75517 100644 GIT binary patch literal 569 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc0wmQNuC@UwmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^+ z;1OBOz`!jG!i)^F=12eq*-JcqUD=g_sjb@YDy)R83X(RkiiTd;IVsRzYTF0T zNe`#FTuE`|dzmmn{nClHuMajiE}SlP`2^dy!oxy`mYzvc{w_c5(Y(r*!jzvgxT>NU&pN?aN5ZvoANNezmt1 zUQ^U)FlFbW-|ye}uHF9hrQhOH+DrA$zEW0EbMkrgSixw|2C;p*KhE%3wn#ibqn3Ht z_U|h1S69~ct+jJXS$XN0gy^)laYAzILsk~}nw@&icJgAwy{}?#ALM(U@cO~x<;)HY zO4SnAh?11Vl2ohYqEsNoU}Ruqple{FYiJT;U|?lvYGrDnYhY|;V4$b|WdVwY-29Zx Yv`X9>;;VdQfEpM)UHx3vIVCg!0AEbn5&!@I delta 186 zcmV;r07d_~1j_-C8Gi-<0051N9Sr~g0Fp^WK~y+Tt&~9yfG`LI?a%qShC~R(b}67Y z6En^(wB!2WA)=cxL^MX1Coti(fF8!s5^x178zNY`!w8m&Y+-ET-&2uKVMm4tCc9@> z4^DX%YZo<)><55)3k}gUS1}Y1PlsKzEs)E9do$82DRU!fWP7JYtATzn o+4v8|Hf6XQLdAqwX{BQ3+vmeOg zEbxddW?*^xZ@0#&%LVV3 zzWe&`gZ1g3_ufC8)BjnH{r2OS8&d;CmKr}oNjUa(?)6CtxG$fHn!VvI@<3@ zPgJkrI;atJX=9t1(}$+n?Dw*CS(3f#U+I|%I2k;Bv47r?U5aLlh3Y$#`Qn{E94p)u zJVnOfNwf929}gQpy*t17iDgb@?{qtZ>u1jB{q@VJziTGh-T3f>)RoI!QPYCk4kvdw z>fbJ3d^Tp%`IfMIO@El)&rL3$`uZ_23>j2QTq80B%V{K~y+Tt&&1PGl3rL3VN|47{MlR zhsa6v=dt@?!(m6Odc1)dSetyBYMD6{W@3L~)>Nsi*3v-`{SPdL%K!iX07*qoM6N<$ Eg3b{>qW}N^ diff --git a/share/dark_resources/panel16.png b/share/dark_resources/panel16.png index 60878d09736586ce16840f3bf6ac503746b84429..a775f53957eef011ca449cf72921225ccad9e68c 100644 GIT binary patch literal 534 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{Xiaj ziKnkC`x6#kQ32seRr_rj7#QU|T^vI+&exvZ?dm{SQ{n zJwYGVFYI@T_!efN=<)Z9<)KOYZ{6B-&h}vI@?&DUQMYh$zSFptTbWjMWb)7;ny2CPU~6I;Bn659C!OEv62sG92Rxi%e5xm z|0-&_Mq4=K~SH2(q>~XZ$<<*&u3(eZ>Ds`sL5NuBh_gfPc9Iz=r-t*wBQ1x|3 z7jAM`v_eyV@iH~#^(!?TEj`M6b2Vpv^Y#~Ye|A>t#jOtp9_4RV%y_ffe4_O2fA33| zJU?uEFmuAL`?|iKp Ti_8WFo@$9}L`h0wNvc(HQ7VvPFfuSQ&^0j8H8cq^Ft9Q- svof^QH88d^FnF%(^%g}#ZhlH;S|x4`(+WNX0yQvry85}Sb4q9e0G|iY8UO$Q delta 105 zcmbQnQZqp^nT>&gLH_gqL?Gqt>Eak-;h&t+(A3t}_TRwFu*BJ!S=mE&hC-hLwC}usCGYv9`p65ojEPr>mdK II;Vst097U=od5s; diff --git a/share/dark_resources/panel32.png b/share/dark_resources/panel32.png index 4f0aadff6ee377d3df02b916076d50a191040dac..330b9a22d0f2273aff6adee5f58cefb72f0b4c40 100644 GIT binary patch delta 1098 zcmV-Q1hxB@0@MhQ8Gi%-007x@vVQ;o00d`2O+f$vv5yP zfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u00Lr5M??VshmXv^00007bV*G` z2jm0|6%Q=wMx34i00Ue}L_t(Y$EDR>h*eb>2H@w6$C=DE8RI7Uzy1zmLQWuO;f(S>wVP#S?C6lsKn1^p03sZwZUT48D;Ad$>`C{BqyAnd{PuKz zsCj=W!S?W*Z-2eGOoG?K1GZ-bgB!HB;+ zu-MbR0-x zY>%Rre10zJGKO+E9M*-?Qf-8-VJq4s;dEFR4l83!mw!uSJ!J&F<`pnXT5h-APQYB#mS)jz)1`vXC^AMzRq1MR7ElOB%_QB*yM2 zj>QAJj<78?Y^del&| zV1EMLX3*vuxTXy=x-nrv2{k>21oyS5;#^wJO`Oz3mpay%&v*SA)ODd5CUYaphS5{h zt8P(;8aAfuH4wrfNVnzLcbH0_(m;FIh?)-bX7v^IhI1+y!CPS{*Zotx9mezQbG#Y; z$g{8W>Pi^0xe!kobt-)?yr8*^FM7iupBLi6$)_80S~|{Vkw|~EB)aD$Rjw~ zA9Diq4jyEERRJVHZ|q}U_a;Nuv-uamJRU&$H!}9|XEZW#G}q?OV diff --git a/share/dark_resources/panelize16.png b/share/dark_resources/panelize16.png index fdd3a40ef14005546b7041c18c239b09cb675db5..ce6afdeec14e4649075b950da3db87524ced6163 100644 GIT binary patch literal 449 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+uenMVO6iP5s=4O z;1OBOz`%C|gc+x5^GO2**-JcqUD=BuF?hQAxvX_|Jd?G&D3Yf~4@NVIr~#B^ ZX8^FqqXQukqDcS%002ovPDHLkV1gNLD<=Q| diff --git a/share/dark_resources/panelize32.png b/share/dark_resources/panelize32.png index c9ce43a60416b0c5a43091279afe1b8640dfbeed..aa3479b2cd64183ca4b9c369c80cf8f8e6b89c58 100644 GIT binary patch literal 554 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`KiRit<}$O_huU3jOeOaSZV|{&wnlF2+EKqxGMU z-u&M8mo@SC zUuyBapZe=rbxHgjj;@00l)1L%-! zC8<`)MX5lF!N|bKK-a)T*U%)yz`)AT)XLOS*TC4yz@Q`GzX*zk-29Zxv`X9>e)77n y0BVo~*$|wcR#Ki=l*&+EUaps!mtCBkSdglhUz9%kosASw5re0zpUXO@geCw2lfWYY delta 193 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 F`@fy)H-7*C delta 1532 zcmV>mHBCcSzvmpeaSnV)~Ic-9ZQkU}p2TKy(Em z41iUP?+!r-04tjR2BBLga0g&z^E*P|3INUjTM)W*0yh9?{(tfLtvU!U0MPvF!+T{2 z2td-sOH~NW0C>#)isE?GwP&khox=dAD8|W6pX=3iwYp6JXlF?^5w2DNZH+fEO}cxo zTBbxa;&d{9bFO#o0?)WrbVvoDO3~;H(ts{`M+H670H{!`#FUJEK&9^oY5>q#K>%uA z6cGSHTR>qKgn#^aWYh#n0bo>d8Y8lofYHkV0T57<(E&z%NhAQp0LVTf5`cmLWI{jy ziUN=Y0RbosKn4T^pf~{05D9YEkjwN0Ss z@sI!z0D%IFF9EL&*ObcuJAjb?S(gCNH!??bp#+<;Rf*$2-pEG3_TN4D_Ryi1i(RQiHKD}kmUZBNL$0yrvRydTJaqC zybK}D-+%IHcv=7u@hk#HLV(nug_r=m9MlR(00at*5Eq#}>;M82557T*zm9bPpdtha z#9ED)TLPX!bvYIi07Ylo9E%P+6an~ORCa)k9@;i);FQO}Z1LCu7ViLOz*U?5uT5$A zMtiv>fB-Dg0kURL)Do7J|Fj(-OF#l3P+-*hntySQ7L>1kBqRT+I{?xJMnQT-2LVve zoxgz+5i6RHz-zh2p1uP}gd_lpnI@T8n`>D$Xo}Q6hTP>!02C_UiMkD0LEx)=E97@% zL59ZanVFHCg3Hq(1mIX20`StMVi(AmWJ>@b5t0Ca{Z=AsmrY=mJogr4Xv_|BhYYcVjqlE*DBdFL_CwBv09XjcZwP_9W9*5Mf1zjytMsmnIW;1{3Q-Id^Hw4<*;5~z_@em!fHJ9rENYT+d ze5--h@rV{v0Du&HCazWpt634_5q~|jb(iV@NWrtu{^j-nH2)K6M3eR%04a8cOCHIR zfoMViB#JhBh5!f*(~>U;J^T>@aAU#D<}bGi%qn>Jv<4Dbssn6p@k;)h7T}xPqe}vC z2Ey#^{^VYRe;>eYIyDTmbO&hYmwUzG?t?bsOUQZ%_mP%OzPF0G2itD|Nl-i1}7s zQvt9hThA*0j8OBfnx+F_P1s-ZIuSMITlF*nfbIjfQd`!oI+pomGQ#|4_QL=m3}0Vb z(>=8_17PU_e)DI|NFH630ChBGrwjn>0{IkqnD4R&*sVw6pJ2(CY@RoInePq&J3%~T zp5})DKnUU>@HRgT07BpoL4^6C0K6seIP3b$*(YL@@oxoOj)8Y_5`sI0j{iT}{FDx` iFO4ulDyqr z82-2SpV<%Ov6p!Iy0SlE;T08-ELtC?3>3QH>EaloalZDVqBo19MEl44a!PaFO?7UT zKagi{fL zd5QNj38>%LoLX(QA>-)ELwQm^ zik9aeZeH|_^`Xw6GiwV(c75Ho?pWK+PX~&0dK%CFxp%wX;rNM-^FkxJPRK-k$_t2l zb*#7P&ers7txuZaF*gGL)|Mt~%vG5c#+>{2NTl?pBjx{}9p$}0;e=JH>$k7&K)H21FHd$8Gi-<001BJ|6u?C0CGu0K~y+TwUgTpz#s@i=b!h_x3Gv|q|!{I zFB&c<6tG?W0J#0lZUBwhhfx76nL$1P7LdU?<~JZ$vIK~bbAYHl>o%X;rWI@hy3Thu zwkwDWWH2eAS}F-pi{sL!O{|(1|Bal2_*i_5RZ{lR3RVCQ-V^SO5$pxxx&QzG07*qo IM6N<$f*kBXfdBvi diff --git a/share/dark_resources/plot32.png b/share/dark_resources/plot32.png index 4e61b5afa387e15320e0890e73565671232ee593..e4170a5d119dafa69c7b9abd1b2794830f7ccf8b 100644 GIT binary patch literal 438 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1K(i~W;~w1A_XYOUgGKN%Kn6fS5!dgX>I>%pwLQB7sn8f<8P-r@-Zp$xY`R( zKO)>KK4ZuCLq$rF!RE;#Twj#~(+%rceYyT`<+V6CW7)w!y0QYQo1Sv)sC)FFCpA`e zPs~%f*BTAwZ~s&@|5)57AHn>uDWv-{U(_#8>CLOetyi&~yivQEt@Y}(TO6I9?_D_r z&geMts!2a8=P;cSEbnx5!!$Po-t0`4%LVdGs;jxLXhg;?aC`axyvtIlqe0(dU@L(2TGI`L0E~uAyHyke z;Q&_cWxd&erql}aKLGTEs42677J&8jJ2e9+0BXu*0M&~?s7e4cdY1tp!Dx+Y01fii zxd67#0DJ1|JeL8l?$*BV0x(ZmX4PNYT?1hNs~Y!mX+Ixc@B?rIIVQ9r>fM;S00000 LNkvXXu0mjfi4|KC diff --git a/share/dark_resources/plus16.png b/share/dark_resources/plus16.png index bc2b71e1781d486de1cac10b656814a966604cf9..c6c42b21a59dde93e7788416985e08aae3a3bb29 100644 GIT binary patch literal 338 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|U1(2s1Lwnj--eWH0gbb!C6T!Ye8uz+L>V9Vq1L>EaloaX$Ia`38A|g&+Nm z<~WEZxR^dXUC+iQ=T@U8u%*e3%dhSyf3raQp-OcHt^)R>_Z1)ciiPN%_iWq0LaC=^ zku*c@KBZ1e)hpdV16500BT7;dOH!?pi&B9UgOP!efv$mxuAxbYfq|8w84&3j7+V<_ j2&P(rypGV2o1c=IR*73ff<@B~paup{S3j3^P6hLH_gqL?C7D>Eak-;h&tcK)~S9<@*;de2`ZGk`2LkS1|JMT;XJn z$e1j(c)<|11vhPG@d-3q7gRRRC}CuHl5Qb5S*vaz&=>|!S3j3^P6k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1Gg{;GcwGYBLNg-FY)wsWq-oLD=Hv8XQ4SiP^it*#WBR=_}i(5d<_Z$EZ^6x zKNc?eSoz1~`yayPrd&u?%z7%h<$}w!Nq0T-idnoWmOV@S$7JBr$+tI6F}Fp-fI((^ zIpfbsFSqh(JhgUB%)>;?ISs%d|yc4?Oc{!g6x;>F-Grrv}1#0X zT|<))0|P5VGbLa`RI%(<*Um@Ho)-9;kuA)78&qol`;+0AL?{ AdjJ3c delta 134 zcmV;10D1qD1DFAj8Gi-<0047(dh`GQ0AEQ&K~z{r?Uz9c03Zki^XL2XqC*iuhs2Oz zI-3qtuxKUuSn~Yh29Q)&cuB5au1kF|02sgk1~3qAU~l+3q(*kkEC3+g!0nrde?kB- ofB_6(;5!4iz^8imZWsm701NkUA!l&}UjP6A07*qoM6N<$f>wSqtpET3 diff --git a/share/dark_resources/pointer.png b/share/dark_resources/pointer.png index c1f410e4f44c6830a725d1245081a7b995f7adc3..8df14501e08699ef783642abc2087a1fb0af148e 100644 GIT binary patch literal 5167 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 TVEBKlNUd3Avoe|E^v!<&?hRzq diff --git a/share/dark_resources/pointer32.png b/share/dark_resources/pointer32.png index 99e0ce519d9f9b1aae701a94924c7abed75f0d78..61b134afa6a8ec97cd63457a716bf91a25a00583 100644 GIT binary patch literal 616 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr16wo*Gj6g|ZU+jomw5WRvOi(r6%`PBB;dV?fq~J?)5S5w4o99nUZS<5l7#ZH0zJ~wD0a?G)@(tP|pXQpLOJ~mEIQ;Qs z@VXt$UCs=xPWLuCJ!P69$;#1M^Q`XI(_=3_H98&IInVBJXVq4Q51JZFMWkP7zgfBd z;u3M|YktP7Yh`8^u{Z2HwyLV<`SQ06zgR=B`rq1EA|MjzUzT>)Dd7392!@Is2?yC8 zBny12&98_!wDaofCHhnJwll^Zi+j3|cfmom>5L7P+jx$cU;oFRV`x5S`qSedJ{;TA z+Rd>pt>VRoCu{+Gdavw%*fd#&VTZ=t4gZyw?^kTPF~u%gCtaw$L+kmm3I31X|6sLt zfBH)(Ds%}jP*qD@BT7;dOH!?pi&B9UgOP!efv$mxuAxbYfq|8wnU#@|u7RSkP5#p4`r88N8W53PM5vZjfI1@#7!yE&i3D*0M1l+fM6@Riz-vWKc%B5$ zvO;r013-;X0T2r`0Hk=fL;*mH{}&+N47EUM0XhM+7Faf})^ jKk`qg0T0Lmm~P+zOLAx-(9THR00000NkvXXu0mjfVk=-n diff --git a/share/dark_resources/poligonize32.png b/share/dark_resources/poligonize32.png index 2f454536f4304d793c8ba53fb589b4bab8f5e80b..4bfd14825904631595b9ef430220fb538c5df9a8 100644 GIT binary patch literal 568 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKpuOE zr>`sf6Bb@k0S2)n{~j|iFgkd;IEHu}zdLoe7qg>C+y03fY{#R8HyCg<-MGoIug(8q zvu0T(hqrDptBK>{j6}sm+efMoZXAhyzAw>w`OUcx=e(cu|NdOb)C@B*sb~M)9kSz= z6zx0IDzo7sTV|-Vf`3lyp+_9c6Yp}jcdq1ou*K!;YsD$s?IzT!tyx^LOjzX7)I!tG zw)V_CUFKFbJ7YT@2E7XsdLVOHZNsADI+0)38z{I(wEYq~lyz3;?bOidfH&J`?urX! z2zgn^$sn&&m7V?2EAfEQ%!Trk7;H~5rtH2VW>_dC@Nin^j0&a+KKlRsqQYVuzQ?5A z_A58$&3JuW=h5yeUE2wked)H7?%wB(<5zewp;1vdKJ9#`ti1R6(tsD)mOScJ40);S zKdw0EJ+WA1%lTr{@d>|ACGKBtqVQ(kNk*gX4Ph&l_p&MQXVz@}%aHOoy7unG*Y3dJ zRV{IiC`m~yNwrEYN(E93Mg~R(x&|h?h9)5f23CeF_7FR&%XdgLvDUbW?Cg~ V4d; zZTi}#C%Pdy1+N@@e%gS!D*yn;l@S1NgR&bJKu=J$NHc)8Ql70@;!bsz9J5M$Wi@Ivk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr16wo*Gj6g|ZU+jomw5WRvOi(r6%`PyDY+-ez`(f8)5S5wA?QT0OMQUMpofE69xe6cL%f7wMGTl#J(aq%@-Oz%1x_(6P5 zlaf-3!P1{HSGCSQzF?AhqPAHj@0Z{Ad)4QQ-~YbH|FZti+XV-9{bMnn_dG?Osou2h zwaebJg3}U*mCe4X-Po;UuqS1S`BCe~mDhWAIp*Gd~JFmVLo} zz4u|Ahry#=4_S8qOyMz)xZh{ywntJf>DY&eB<{_}40f}vH9T4v&injuQ{m(JJf1lT zn<~$`Y9)AulHK_in+;iLohtyJb=rMB1nD9L@88)R?Fju{Y<(o>@=#{1h=& zd+C0`Uh8G4c%#~8*-^9VXE2BN;o>+G8_s&4DLsig`z=mH9~L(& zkNhC`IF&8@vs3ifvTfd{tz>IoAK0c97@4YiOZlk$;-fN*>6?m!YILjAJb6qfY?_pl zF1G#WvgmeSM$a<$pitIjQ&OJh1iOEq`eSd<(kfBg+_^b=-Oq0}@+}ct9@QAMG*CBR zeXZa&&q>oB@n=uy`e&n2IOA>YzsdhE{@`URFqkL(b1EoORZCnWN>UO_QmvAUQh^kM zk%5tcu7QcJp-G5=ft8_|m7%$=fw7f=!FD0T4JaCN^HVa@DsgK#=HJN!)F276Aviy+ pq&%@Gm7%=6TrV>(yEr+qAXP8FD1G)j8!4b722WQ%mvv4FO#sM#95?^~ delta 266 zcmV+l0rmdq1)2ho8Gi-<0047(dh`GQ0O3hQK~z{r?UhjugfIw1_2%5%O^w|Uq%agr zcN6`toyRcHeOvtPi}kk`;I|zhqN8Pmh#mtqFYW+OLcjohTB_X$15~>)1yBj$hKuJw zE-kbj@(%uA3czv#1y2L;a9X0=y^sS}mFGU_6{A9%NZA-N@xTDtzu-{X3x9;%N_UtcT}7q-^eun Q00000NkvXXt^-0~g2T0JcmMzZ diff --git a/share/dark_resources/power16.png b/share/dark_resources/power16.png index 04cc2c6bb763ebbb49966259702072f3f93c79dd..5946e231ccd3c3f3da22c4c71a7598330be30b2a 100644 GIT binary patch literal 835 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>{Phz^zI*@f#mg5C&akS1vz%^l(&*Q z6i=EoDL+5IqN1X_yu6^G0BATcWFqVJdw?MrR}$nG%&>JD)Aii~yr%m)m#$ZJd;GY# z_vsx2kz4m7I5=}pvK2imU}EeIS^H3kaocR2{(V=N1bFxsu6`n@*PB;5<(a?e#V7I1 z<KZ%jLw=BOgTDh z-gw0D`RR#;<;lfK%O_|n99t3LR-T~gON8hEHHqT zd&SCZgN&?9V}lnOFPd1teBqUl;OUi+=n?ffz_cvwnZRKk5uJlurZ$AE=y*_3abe;^j_vL)Zm!3VG|gmaJS~)3^vTZ~ z=w8(l*NBpo#FA92;`IJ@O1TaS?83{1OQ^bidp~w delta 656 zcmV;B0&o4p2Au_v8Gi-<001BJ|6u?C0%S=BI5;>6T)%$(ILLs1|NjNuym|98HbXF6(9qEE zzqz@2zm=8M>07sM`GE{zWMX`E>*g)4n%bIxhK2?dJt!O&7Jn8u7G{>Y>>TV2K0ZDZ z_Uze{0y02eLH^Q_!$%_i{Q2|!@4vqxzkmO}0CNr805vr=k;ji7ALHTWVM$F*tzu(i z+c16l^z$GCQqxlX9z1xEvT)(TvY$VHK2uUsvb}cg+AokH$OaTWef+c}JTkm%-n@Ae z&;t?VwF?(6^ndN%xjRx>RXOj{rAup23{X~5Ui;?F8I+}08x(zo})m3+2xNspJ#Q+l%lhrq_-+!>Qcd*ypx^?S&Y*FUy?5ua< z*ohq`W+uxI9z0l#Vn9?>RNlt*8!On@*!tgpeBX`D009AkDZhXJ4oXN!$ecQL>P8d; z+S=Mg=ggk7=f(3E!aslitp5A=??RX%pzvsFYN}voXD?7wQ@aru80gv1(C`Dr01&6H zuFiSxoPW8~-@SXs`}_Crdo{H+Rv_`#me%uZtZWieQc|xIk`iL8tE(?zqyv~hXJ@C$ z{{8!_&YnGM`2E{=c91wfAOCj~Gm|6M*48a$Wo5UKy@xe3rKP2@s;jFj{`vDqo`Hek q9~&Fn-DAg&Jzl+f^}G)n*g00{s|MNUMnLSTZ!Zb?S~ diff --git a/share/dark_resources/pref.png b/share/dark_resources/pref.png index 3bd655edc5b4ad530af7b22f098df4492663cedf..fe15f4bf1cdaf92c406e484a2a42f8046ccb31d5 100644 GIT binary patch literal 793 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKpuOE zr>`sf6Bb@ke&ZCsiP;PcjDI{`978;gzn!`_J2+6{Sp9dk%uC;vWi(~*vIrJth&l?o zwmSV~5IwR~RI@~YOYa}EpPtqZt)_rEB|2mQzRx^oIcNI!pC4uVly_-wKmGf^Q}c^i>a{%r2B-V^WUpwsbI4wd7A<+u zKX+T!yaP`Kl=mz+p=!^3PsOe6uuY<1>&yl5{A+UNznvWFqo#eET{|*z`_xP2-MNw{_uuw;FD`StJFWWTtAGCR(&9vxW8k<%0 zjdhx5XX{+pVxu_alJaEMs#Tmzt)m_Kj;+nvl)r2BW2?pOVP-SeUruah5sXoI>2KKR zY_Ip=(ZenLLB)JkmY!QKRyC;TF-}OB;&MagOjV|srqMfjX8q&Io8G8y51SAbdvvQW z=R(8iZK-pGy)r!(?^@bprg@9=(W*-9s5@w33YI|bpQR{ z&uJE1z2ckJwWhtjv?tVb<&1SV%kKu?|FwSO)_ofsdSz2iR;fN)kyFBCk|v*fvTNHC z%eOq|6Si{Q<88AzXd-$_I{kxpv(?gw-NMiRU%yt{Jb&)J`_q5al`Q}!4b>9Yh?11V zl2ohYqEsNoU}Ruqple{FYiJT;U|?lvYGrDuYhY|;V6c1t#$pr=x%nxXX_dG&oO;B0 y9;iVQWJ7R%T1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y88!W$<+Mb6Mw<&;$VZ>qN}} delta 220 zcmV<203-jI2JHcm8Gi-<0047(dh`GQ0JKR&K~z{r?UqXpz#s@j_2%5X4GR-uReq*Q zLf5toZ(wXKho5@5en|oG2mruC=LP^=O^9B`qOH(O06n7_?4^LdnDoOMDk*@S0j&)h z{AlS^fVOZyA5tME0ke&;tfyK4?QBIUJ^{pOnFDF(&92OWyHyGFbAbMiE+fx2ut_)w zn9p_ms{l%6M*Z6gl?sytRnTtCW8XtfrjF zKbTD{4Rko0jv6#8oS1Y_<%hTgYqQP_9Vu2vmV+tbTXrm2(~(i&V~`;+`(dqmGwRyVLmkmA&H7h3=9l^JzX3_G|snPwDoRE6gl>Be%KP1#;||@-$oC8 zXA=z*6HZ6(W?tWiA{VcOXXJCVFI%>)Nr7qMN`8ecPeOLMT$x~D@AtMA{MqZT4R@89ks{W`{`bLPSSDtA@@gF>~$HKHUXu_Vk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`KiRit?K$D~A>VHJNz2IEHu}zdF_5V{)Oyar@cp zJoh*%Eb&!Z!*o&^NePdR?d}c^4r(Gt*x)_J*fA!TF-u;&H3lGb?3j=)~|OD*|taYS~%Z|drte0 z1Uk=rwl8|o@lrOspcu0)iF}(Q^Vs9Ac}U!v^}F!@Ud3z0)2vp-6faKk{M_>8nyiUn z`dpUB>lzA$)=XY-a^Wfo-d}6d6rWu0F-UT&QxpmDs_w43cr5BsOd?YQyUFen17~># z**gm-r>3*tHeGpd((*h}!M)R;zEPMZxnY`Sb!yhy-7(vDZ#euawNL*k(;9>2Ua>pE z!`>P$dr`jqV@YE992M>}x04$Cw=fs;`5o~(@}czao0)TJTPwp>CU^SQiKbdB@HEU1 z^)v9e#L%+in3kzSb8S&Q!|NYE;{u{RKObh$5j^!?szIvGit+K6&sO?u7Ux6Fcn+v+ z|J=UEk++t|nsL3w33juF+?mc{{D#LkZk!VDoN#u}mSaVhJp#qIB6=KMTdhpAL_)fw zL`15Vl`WjTEA`pzr*~%sY`ws}_2ly7Qdd{Vom@U)9(Snb!j8>{_DoG)5_!a3`>oAW zhq$?qdGb9rc{aqB+~oE-Aa|>wyGALGXX9jL8%B<_sSp_0s1&;S45 z`H#(VyXUgXwOpHkNlLZEHKHUXu_VKYhZ z85sC~n3{m1AvZrIGp!Q02D`PocYqosK{f>ErERK(!v>gTe~DWM4fpCeig delta 309 zcmV-50m}a72E_u98Gi-<0047(dh`GQ0Srk*K~z{r?U&&WgD?n$_04(n8JE>C#=+5c zHcRF&W1xJ{gVudp{OpV4Z@&c~A`hlwB0?ud8?wP0APZ3j$QEv(nOy_@1B4au_B|_Y z)dvC~(e(hF`;Giu03EzJvf{FK-dehqKLC)!NE=2FZvYuBGk=7T4O$xlj0DSkwH|J( zz)OhFQGP2x)|PYydPO(|pdwCdI}A_>u1>=1*gp5$LXh-`vwMnt)kr z1^r*IfG!c6^;7`et1|%f3<&3dHMCiIf~wlsQ!%{}c_Kv0Mz)cD=nDyxy}ppL?Mnlo z#dUTFGP=Z+0WNylu^Yf-NBxw1?Z2QWbH*p_0%nmBo8EaloalUoJUOy&Bk=Ff@ zKeg4oGIBfk6P%ZB+;A}9)@k7crwTSNYboJchUAxvXGG*|+puV%$~|7iP46~F#N6PO zJ|9y4Yb#Dk{1(=~mnelfP}{kHRuD~?UCS7Kct*uUcE!s@@T-$f)X zJH7Wm+qR1};bp#6+I?GEbs3rdU6fl;C-o{eoMG33vr-GTF<*KfD*mV2uCTCw+5BmZ zYz{SNOh3F;f44CuX!|ygXS*(T-pUf4zQuQ;^3F{sb6jLOM0U*Y()eXC(_}?oB)irw z;{@lRtt-wPZnkG#w^IJ;EjEr6*AZrAtuJo#{p)x1VXVcwcYBXp`w7>%%d7}c zKG?e1$iMi|F;3AMK?d_o=gq=O^ZXS9nd_Fn%n2j_7b>%O{MzAn$SQ1S9I380r$OI#yLQW8s2t&)pUffR$0 zfsui(fr+l6Nr-`g6~CdWm8qewfw7f=!S4MVizoLnib*3YK$1W8i1Ym9{fveH6X1G< delta 323 zcmeyt{DFBwXZ>R?5kU=cuBAWEGcYjh^K@|x(KtVKqCWQ_2Z>|#e1dGkvJqiCO*ghk z>M~FE%rX1RQpa=pfXXsFt`!l%ynk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`KiRiVBEN6|YudU|@9iba4#vIR19(UN2@x5jX#o ziz3W=+rsi#w5<;w^SYvzpxDv0c0=!6eT5%v*Oa)L>Tj%h!g?e;fKy75U!c>9yEAf+ z*v+Feb{KO;FZt+ac*nXXJ#F7k153r|o|G$(k9;qV z`7=Fd*8bstQP*0$H*xw3ZnMh_8uPWg>*gN)BJALCWSe81N5(Fv-H#+0u7$OUeP?qx z%_ot1j$y|Z=2>?n8GNl3&TnEYNM^rsBdI~6PW%6_h%L)s?THc*z7?v!V~S=O)35)x zCRIG%DQsZFzmL)IVyXl4&l}vp5LPX5jVMV;EJ?LWE=mPb3`Pb<2D%0&x`rkp1_oA! zW>!YVx(3Ep1_oy@2|1u>$jwj5OsmALVNd_6KR^wVARB`7(@M${i&7cN%ggmL^RkPR b6AM!H@{7`Ezq647Dq`?-^>bP0l+XkK&8Ok^ delta 200 zcmV;(05|{j1la+Q8Gi-<0047(dh`GQ0H8@kK~z{r?Uzdqz#s@j_2%5XO&288KniF( zHNiEX$Ecvafma9TZ#MuUI^F^zBDL7h0JyLbLk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1K(i~W;~w1A_XYOUgGKN%Kn6fS5!cJs(7^uP-udui(`n#@wcIdTnz>S-mVu8 z@?Q=A*{`?n?Ah`dcSAoX+Z@*{$0NHpX3p~FO7GaS%IN)c^^6No1R{K9Buth#wrlBR zSB)vHeYrg8heY=DrMz`Jz#o;KuEf=nSe)iB@WyiW?g-5>11#JboO|`@|q9i4;B-JXp zC>2OC7#SED=o*;l8k&R{7+4vaSs5AY8W>v{7@WN%4PrrEzCmD08uz*hy@t}AR#uqBd{d^FFFI8 z24F3{Xvu9*p#uf*8VBO1gMt?Wx*S3|0Q>GwKjcqdfxHEBfHum2yajTA%7Dy)tnlot r2nP}wz*EAg4n3Bmg6w_)$Q{@LR#?~}DWIA>00000NkvXXu0mjf)gn)2 diff --git a/share/dark_resources/qrcode32.png b/share/dark_resources/qrcode32.png index 80c1c65c4e6778371cbd1e0bb89b41c76e92db27..acc56384b8c7254ded6ce2dcd8c245003540a013 100644 GIT binary patch literal 618 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1Gg{;GcwGYBLNg-FY)wsWq-oLE6Q&q?78qS0|R5Mr;B5V$MK~hyQdye;F0+_ z=h8vb2M3PsWMsd6K-7H$Zw$N00oI6VEiKpIubm@tA>U2@fwy8pzJB>!PKK<@=D)5y zJ)l1^l)0fP_tAoc;zlvqjotl6)<-Xx{$t1Xs=7ZqeQ$Dex4yl8n={enh2U{1aTfi^ zjf;ilRUf+TN>t;0zPNenyO>|sSr}Xm|J(hq6L787PU^O}QLx-x}Vwwo19CElI>l&oNdjK++A9?SYmQ{P9Lhh;t|td_`$eUro*#l zQ&r}%9qZh3^4dICY-G;9uJKu=#x^FiT)=Lf$vv-KQ@{Q%S^70e^o=jq@tO~Q_huIr zJlLGWc=yTdYehzWk2%ym5B>S6@p#4CwG9td=htje6ntTGv0CAORdP`(kYX@0Ff!0JFwr$M2{ACRGBmX^1#*q83=CvX>^hF3AvZrIGp!Q0 UhMcKP)j$mlp00i_>zopr0EjyA!vFvP delta 752 zcmVnu~K~z{r#g}c-;y@6D_f>!aFaQcrfC5l} z0TfUuzyJzB0SdqX7ytt(;Oa?Lr#h3}EY#gww||oTn(dvQ=}CUx@Ao_X$Myq&{eGV= zmrE7K@px?4tX8YE*=(9V`)Ty&^Lb*f)>y~-1^^oXz+kRDpMTG^SS-?ZyKSd;yIp#{ zUQK^A8l~Iq)&gMed_Je~c$~GTv$#+TfR%nj-+4Nn(*1t#0q`{u+;lok%jGf)Kpx5h zh;-m4JRks|XU%Lj8}tAG@POz6iQGO2fJuz2VThIk;B%1zpOY=taO=MUAYb>7=+9#by<@GpuMt1On91hf{;U%*D-WCh*TreSx29n z4gnxVOKDAD0;U7N1Fs|^0PvI?qM#;33dlwWYKwE4z*vm*q1-Q>(Ey0Niz{whqJ#0M zgt%Pl=kGCI+-9qUPJ!G*V13%4$2BB+!|Cb)h=+)0xqn%b3Lpnpa=CzOtx`63$!rWb z052*SI2;a5bo1^2R2`WUb;=m2UlBlz0i_+tV^vdSbm`R%RgM7wkjLZE)B*tTWSpu> z>tsRHf2Sn6Iae7Yg)T~^4C3Y33k&Qw6>-D;o=n{x*F_OD#<=6pW$kWOJcr0Pt`-1>#pJcg=;DDSIGtPHJq${ff z@<0uM+*-zL-6LRbjvWH7fyd3UUCv7&&!c|C}lYxUs4q?+zgTxGDzx i2e|WdT2rmxoc{yzm%+}f2*DBn0000z@OS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>lBSEK+1*-JcqUD=(g8Cim)&NLPVb_225NN(v?y_G zcQiTD)8ui{-mmZMnd?dO_L;9&7oNL&_y3>w>fh~rZnyAA>AdIF8cv?G_u3RUPpxmi zbmwb%a*uXRTA!fRZR^;@2|d~C%oDkKw&|~*?Y?f4Q(N7!2(z}EE8=HVwQ&o6P%&P( z-JGX;$>R%&`)hN<*y2o5&Y}4oL&%3@kzt$+GFR^*uj&nCPO785BU8wJ|BfaAL zbx(Dk&w(2G6`QonD@_lsK3>+_thgm*hlr>D(H3B#(a`9^}4;rkR{ws+|UEMM|TZ;Gzg(#3))ely?r zeA{v@YC)Z+s;8rJoW!xFQ^ohpd{ld`yB|Kfq53-S>Bf@dy)G#ic-Nb+k3aaJ#`Fo( z&lsjl2el8Uyq4&d$~V~X{P1b%=`T9{f38`$!8q1%I(yy@sknNLx9JxvCVOtuJt4q- z?DieL?^Ybqv#ym?#%SiIiGOiaEqy&>-IR9KwQ2dUa+mzv7}PeST=$2&$#pCK0k8+sDZ)L)z4*} HQ$iB}`9CV* delta 248 zcmV6@;v|#|o;mbiDz*J=LRM9F}3c7o8^+x?7brXm+9IZvF zJ?smFny$DlGfWATS)0Kg5DR**W$r?;A;=$=mE~;`6f1$e^Km+=TA)g=Mp6@qWviAj z>Qh@0Q`H737ZMo)md3U{zd)wJ*C~^7S;Gn2fhlHzW5UlKR5}F$ y-wc(hswPAyY!%21vt*Pjj+8*^TY<&>4fFxwiPRh9u=9Zc0000k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr16wo*Gj6g|ZU+jomw5WRvOi(r73DV)_FVWEDAeKU;uzv_JUKyv^)Q2h(~AF_ zc+T<&sl2E@A8_QyoJJsE)tc}}b)L!W%5_Ft6r>LvJaFK{oOI#BS^Iw&dKi6hxS`{b zb}#9S!nub3Qt>K@Ici?ag;yE^nc3PIJt`k|-}*0kB=gszw#)oc5!lIL8@MUQTpt6Hc~)E44$rjF6*2UngH3ti~9fo delta 129 zcmV-{0Dk|v1Cs%e8F~f)0047(dh`GQ09r{zK~z{r?bb0801ymBQEt9Br!!G(7n0&T zz>1d%<|tmXc>h5G2=o$=w0=y5q;v2~fC8dGWXfoZ%eF0`00a;~0D*FWjQihZ@Elu# jm+UUP*Pjpp1S$kJr)PK}jU`4~00000NkvXXu0mjfF3T{o diff --git a/share/dark_resources/recycle16.png b/share/dark_resources/recycle16.png index cc32de8e2b8a250efb83cef77184699cfd9a8749..1d15d0abb831d474b800c58f360e3b5c72883933 100644 GIT binary patch literal 890 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>k*ZripE$i030_UF%^-vGheHy=NK{PE+*@87?_eftJvA3b)oprD|;yZiiw z^FVa<+Et*MFJHa@)d01>d-v|j)ho5NwWXz{Kr%l+f9<-ppFVwh`SRuCCy#4tY8o3G zckkZ)_U+p%SFY^YvuDG`4Rv*OFJHa9b?eraEnB8cnX+uzvWu54UcGu1$X&E(QA0yR zYisMeb?Y8IdUWd4sr&cu19br%`Retn*Kb}=n>G#TFrd}%KfGVPdUaoa-;<|LR|z>I@Kb-O^wXy zr>`sf6Bb@ke)DAI&?2DFdQTU}5Q)pl2@Q;HY$6AaoH^9>V58xN;)0^W&mWwA*8E{= zayq26DCv<TF9Swq zXJv)VGpS75&t2j1m{A-VafoHj8cB(qoVPpPD8{h6tEVeGeRS$6n_$8B4WC(p;_lh) zOV~Gmzic?e3{eRY86hb#xrM@#qP(U$YG!(N2h|NVCG+CFvZAWkX0S4(?G~Gn5YDmz z=ycT**NBpo#FA92#HJLhAWR`h zBaD6e^l7cFTen_EHw41~m~9FQ3W*5`3G=YoitHK`17J38-@ZK{CMM?e!-o%jcWmF0 z!oa}r|L4!2oY67SI!LYq>xCP@%F1e5U0r=@+0tbfqN1ZB8-E%aZh#bYc6Q2q|NdP} zSXlVQzCHUI^$qnw1~R~00XG0-`_w5@@8#y@hSk;8oyFmFj>Cr!&$qR;jaas9nc1yd zw@!l%aB*?bw6U?dcIM2Pt}R=(l;ew-=H_P2zkmN;Td-h3|APk)iogbVczDEESXeB6 z_3D+=v}x1!<9{;%gqn&zJ2>A#?a7E zPHk=NZ!it7UcFMCHf`D+9DxW=SXZxJbzZ%C^**o*3V#X;QkE`WTAiJnt#I|~RgKlF zSKq{DfPsO*{D6Rf1d!bQ`}f@!E?l?^Yyc==*x1+{4(>l#Bq=UAWxJ>3liu3B4)*u2Rk*0RF_LO*) zN=jT?@z+W6&MTIiDl9$!@%av!vV5l%HWL5LEEJ|)zWyh`<67y{sVm>=0_Rhc3>8ZbdOn9MU&Ev_${vv%dx8m2z%sE%iUWt2|c4oFv zVDu+LTl-M9{YsP1Ciu?ezFk<8d%xtrFz3Omw(BJhezl*N;{9ODy|TTBTnm@Y|Gu%w z v1lbUrpH@mmtT}V`<;yxP!WTttDnm{r-UW|i^KG? delta 533 zcmV+w0_y#U1)~Iz8Gi-<001BJ|6u?C0qRLaK~y+TV`QKZFjAITTf1Z0v}tv@xw$756cjcmB!49MEnK+Jl97?oBQ7qk z9_Dhm0fK^pJ48iACIA2b|BZox;njfy2kfM!r3FDY9X@>cTT)WeZUzPh5MTVoix&?* zfBx(al0$L9k|j$rn3$Lz+`4sZJF?SdWo5S{Cnx(ZS+c|eIuuoVLX!<*Z;Zx@|AckXdmSXeV7BjfL*M~~KS-MaNzTU*-!1_lP*7cXAy{QUXz zG=g5}>+AC>Dk|DGefso|nVFgVDk>`AK*Z_=ot?e6CRn?8r(a`~T0}*7?iWMu?|NHmvX;f5H z&Z0$&?!0*MqOh#2Z1dv9i|@t8#wsmdyttK}o!u%dEX)xjArYH&(bZ9&naH&nrVjw# XNBjjb3l8W700000NkvXXu0mjfbtDf? diff --git a/share/dark_resources/replot32.png b/share/dark_resources/replot32.png index 7d4f47ddea56f66ee85e3b351acfa0fb2f1844ad..052f61faec2729d1c7169ad360a6dfb0a83cd6c7 100644 GIT binary patch delta 997 zcmX@d@qvAUWIYQ51H;YYP4z&ECEd~2k%3`jKlh(RRv=#?*(1o8fuTx`fuW&=f#DZW zsNn?zL#Y7+!>a@a2CEqi4B`cIb_Lo1C76=D-CY>|xA&jf59DzcctjR6FtGW7Fyple zVY`8X>?NMQuIx`(ct!awKF{%Z4Ak`4v);uq#N+teslFZ}i89CPC%=C6Y?A!WtT4BQ z%hKX+w0oAWSimB@P$^b@g|p_9g?z5dyEtA-l%Cl7ML<(@o{E+0f|+U^yQKmZJtbYU zG|hHr?SB2w`plcOci$NAE&4C>Y-aks@0ICw?|+}uIP@p$pv~|9+>B}pox%rCpYKe& zuk<~>{`6MJ*~^ixE>lTey@OSb5@cY zr)fb@J)8Ppo?2d(-8*YNjxcTBzGtzNSiHR$25a^c7C*PUk^SZORI}V$4KqXql|C>u+*WbEI_{~_Z~ zht6v4J1@S?PrtOQzB^9g_Kw}!SMq-P^W58RQf~X7>FeoLQdiE+TKjXs&Tm(KO`o#0 z`uzisRaqg`3?~jRxpwf`6=qh>&CEiNYb`4nx(|o#O-y9t(Ky26!#l-zson}>>oAMy z`##$I($Un&VYt7jh2^p5A%!r`B2VG-?9A#-e{ zvLfM)_oDK1KlskyVkXO?spMtL`Z`zD^_L0D_RR*J@*5tdOEDDhPrcjUxX0(Eo|sxg zhK`2dw&K>)bypd}*PT4BzB?`$0M$HtxU-r z67k11&amycxsG!(qvQjF_f!7w-}aNehW-Bj=o@}!FAo6ofoh3sL`h0wNvc(HQED8J zW-u}^GSD?J(KR#)F)*+)G_^7{(={-*GBBu<=>LnNBR4-KGp!Q027Xs_U=C(r@O1Ta JS?83{1OTCqp;Z6? delta 1092 zcmV-K1iSn22hIqP8Gi-<0047(dh`GQ1Qkg{K~z{r?U!FjTUQ*%&jDK#uiK=e!%^eV zM#Dr63@OzLgDYZQ7A6w)-o!s4V!5RtLLa(4EDpv%e3%-!3X81jy^Gd>f_*6nEyFc! zmZ`DGC{%1qst;A$UbD!J=8PM1xK@SY#|p7#eI z1e}fxSglqRj|H2})+dT$u&1ZzyHv1ZwOU~~1IGzS#inwfaRo?5yhx=|`LnXJo_M|9 za%`)qsbNWyyi!n5pzP@A*vIzV+*~m~KmVb}s^-n|~P@8BqdQmVJg0nq(N}TfBB;WaL^X6zXRfCLP;OB!K7nWrWaOnx?zu z0vry43iOI zFB-y$iHVJtmX?Pajb=9@pb-G@0wMGVcDl8-Rcf=@F1NS0|A$e6ARguANFaSZaKYvzyAS25Eo@& zg&~9xeoax7R|X*oA-tWm0K47pqbTZrSy|b3ECWMBLl<>Aopy9|R2Uc-_-t)$?O=0r z^Hz0r^^Mln)<+!2Nw7Xf2>p2+18%qbQ>WAUrGLd@$&br`-EQA&YirxkXf*!VQ_$Df zr*3FyI5#&px7Xd>{kc-9e6_#7uUKDS50|I7xcDEh*DEY8E*=yW75QsxYhOYLqfWu{ z^76+HhvU4(V)-a(2mt^rMNy;j5~$T`0|paEE0v(Xzu%|V>#MNy6Ze655DJ1&+11q* zlz$7@-Q5LRtv0F?4h{}J-`UwYFX!T&2sk`E)R|1C%|xdlwkb&6@x%hArl#&SHa6ZX zDJj8?=sJY(2SE_VGBYzTt*)-tDHMwTy_#Jv*M!k%{42tcRE}>DLf577%F0U4{QP`X zQ&ZDd$1)HI1pMXYJfJbCs2qJJ^}jh~D}#iU;9w0z^@a zg7BT(hOq*4I^7mQ5KA*NGddh;b93|eKA+EOHk+da)YsR)A_(G+)9EzewFZM>U_E<# z`|85NLYge?N1uPE^OG$0IHhuYlz~)klF0Yz_%BGLGL`cmGVm|!*l|DeajJ^|0000< KMNUMnLSTZg(+G$F diff --git a/share/dark_resources/resize16.png b/share/dark_resources/resize16.png index 2694b84a82e8cc6e670dc12e67093e14b88f6def..f9d71f11c31437c4df685e9cbead451398a2f189 100644 GIT binary patch literal 428 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|U1(2s1Lwnj--eWH0gbb!C6T!YeAk-mxIt0Vp)z)5S4F<9zD`L#{&s0xrjA zlnCkC_CDY6jYCW=B8oH0L#khqE z&v52e`LycV?$@#HixVSkw>=%ZBf?YY$bhWDhP;|Jq%--*O!$R4&jVMV;EJ?LWE=mPb3`Pb<2D%0&x`rkp1_oA!W>yB~x(3Ep1_sqT4E0bn cNw!r>mdKI;Vst04)NF$N&HU delta 144 zcmV;B0B`@S1EB$s8Gi-<001BJ|6u?C0BA`>K~y+TrIAq%z#s@i<>tNl7K|8T?5x92 zLmzFiCOiNS8#6)QM;Jr~Fo+B&IVg9q0svV2T}NojP(C9CxQ*4;IGN;bmXV7| y8IO<&*jdcZJ|p}UyKd`1*&Iu01Qk;5;01F>J&FVWj-mhn00{s|MNUMnLSTZtqBXbx diff --git a/share/dark_resources/rotate.png b/share/dark_resources/rotate.png index 21efb72a50cd274798d1af5ba1cd454ccd87117b..755a0b2069745ab660874864a83c5b303b4978f5 100644 GIT binary patch delta 1056 zcmZ3*yozIjWIYQ51H)f#LmnW-lJ4m1$iT3%pZiZDE0C{{>=ES4z)+>ez|hdb!0-zw z)bN6Vq11qZ;Z*_ygVhWM2JwP9y8>;15==?n?k)@rt9q4 zBv6}iv4$zh+m(r~c?I*VpGmguePR+H_;kBg&V>CN)!FJNFP+Ew z=Fv7$-s*E@YA(zI@x`-ym)y&q{IjvTP1N%6l?(>XP4yw+XG|_8)v|@p6l6_!QGYz_ zGmoCJs$7G|rjv1!a}r`~7$zny{~9fSe{u)A!mA9^iV(?84aP^_)oCBJ{bCr}YuRLd z^v}A^=4ZRINIY)wv?kZ zzUC^I_wqYwCpWvU6KQVRrRw{k^kVYcu<;p^FbqnD%1D z?UnhV>)Ep|+BYVLm(9^-iAA7>WGEQ`3OaJ+ugr(X;c(|kl2CN8_Vi}!VszOlVnQ0be;<;UC^ z1^8BH81q>D=ygpgh{&##e!#FbkfG&APyCyei8r)wS)6pN&Wo^bZ`$6VEE*SjCXxSb zm_{no;jTAJ)ie}5`prCxP5h0oKJdL<;c1(ZT>q!dHhw$hFF_A5*49GqPL zPkQOz!dHdnuTOZa&Hl-8`IuGITCKS}pMMlI1oqz8zikg|qfTvW@e0G!z$~O%;u=ws zl30>zm0Xkxq!^40j0|)QOmq!RLJSP749%=STw^N(gFjXrcTqIt=BH$)Rbpt6gzM-{ S-;fB@!QkoY=d#Wzp$PzAzPzXa delta 411 zcmV;M0c8HF2&w~+8Gi-<00374`G)`i0dYx0K~!i%?U`8)gD?z4;pVw{E2L7TA&%D} zPDOv&=Hc<+r2Dq`Z(m&h1_vmmyv~YmKd-0H3D)fvCledPNFxD*z?RlYdxn0I7AX5NQBYtPV8i)r#nlhI2+GOh4C~XC#HcAb^eaVmGFo3AV3}+(K(!BqSj4yYWGi6V3bD@ioLzdyyD8+gQ5%7p z)X_pf0kmQ)=YNX;EH<);v0U??0Mbd&^2VaCAxDX*VJuoO8>96JD?qTrTy_W(K&Dh; z0Y-Z@BapLl$d8z6MaE5;qfJ{Rgs1}4>PV9?C8QZB0Sf>0Tg~flDyqr z82-2SpV<%Ov6p!Iy0SlE;T08-ELtC?3>3QU>EaloalZHbZm+`$A`B1KD=KlkV{|MC zDcI~?SXwH;5-2c#!4D=o2l0z<^wvFkqLd;a6T?-@=o%n0M}$>>fp2V+?^*trGx^%z z-;rWYVh=lVsBpb(a%@VR97FoIyS9- zQXfuLRZ2b*k+EZ4?(UHDYb#eQ3W>7MJRUZ&_V$KXhmu9-?$FsJpYK=OsPsvQH#I50e{QP4;4Gf;HelF{r5}E+_bC`kv delta 153 zcmV;K0A~NE1F8X#8Gi-<0036bj#mHx0C7n~K~y+T&6H6Jz#t4m>&hhr@+CxLlUAC{%mCzaeu=~&0QcP}xcCcHLpYHOOoJZfp;iW|)?8`V+J8XGS15KoZ@;x= zih3ZnbI#gm?Ebz_kk^s|CuBw;00000NkvXX Hu0mjf&5S^R diff --git a/share/dark_resources/save_as.png b/share/dark_resources/save_as.png index 10a630914063ac4db311772c853945009d82e5f6..2d3ae02b19cd40c18df3d8faa9439cac5ae6514b 100644 GIT binary patch literal 683 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI10wkH8TU>z@OS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>lBSEK+1*-JcqUD=`RJ2{X2ye|P51nYVxS^sluKZh!ix zHaT|H%Q$XZ?Mq?FYLmqleK=>SZSi%b{j&*~RTU-2t7PV1mKWdTGt0k4MN9ukxZVuK zr_nccj(FL>D;KMHbNs;eoxE{{Q73(^V}5hKVyIz%ZNi+n?(ssI+Pv>!ALr^YMZdG% zrCYh|$PDvr^I6$TuP)Wk67b5hk#pi~t$gB8T(wr6>q&$Tn4qexdnO3bFSKf!OEZrEM)BT7;dOH!?pi&B9UgOP!efv$mxuAxbYfq|8wsgK~zXf?UqXtgfIw1&CR*F7M56qB6PmG z(Ak>wBhWA;BHFhFKO#z6HkCm3Ad1D)(HbtO24aQzP6S&H;!JQ5kAN8VgKqQHnn5nS zn>y4pJ>QEB+ang;`2YxwA9fo$b4`P6SZAq20xbjBo^1kokzR@cY>?AH-n7=RX`qso z1-2X{e+$E)s7|(C8rEzEB?fm5UB_-v&C80*3F;%y0BDO6&7l`*Fly#0Lltd6=g!cY f>!^S9t85t#1FGQ(Mu&y_00000NkvXXu0mjf5ba?_ diff --git a/share/dark_resources/scale32.png b/share/dark_resources/scale32.png index c959b49c936f320f62a01526297f9ad2f5283425..079fe53951b7b3b07a4cc49e82bd688e6e11af6a 100644 GIT binary patch literal 680 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`KiRit-x?doKLTz`$7M>EamTas2Akjb6--0&V-P zU1y6{J8l%Y)aCLtNl;#Kr(bYn*2Gh8tgAzmW{C?(`!?-sNa#pViJ9tUy*B7{uAr!~ z*u@#%dfjSH1WD7BGQY#jeb1*ujhd%jHmqA78aMZ~=CxnSGXiJZ zJYH?GdGBN&sW;4q56-Au{$PIbU03j%FK6y4UX2vwk=3#~?CjsfK6hc$Wxm>O3nxGI z%3#(lrmX+uyf(vy?Gfwx>J6MmF;9dklOdR&Z^?laUY|F{FNpt ztj8ouqHXrSyM9!7_v^^)o@IPeIfln9UOsqGw~q17DyA9#I^MDb9?ILvtsvRtZq39nO2EgL(WvDYM=&5kPX54X(i=}MX3zs<>h*rdD+Fu bi3O>8`9c1?T~g8Gi-<0047(dh`GQ0Ix|zK~z{r?UvyVfFKBj_04(nnp-w%+M&$O zIs2>7=W&8DkiSU&f0zqEM2zxzZ59NmiAZsfaRWB0j_dIGr;J108noM9Uu`>OOPd^n$S{) z_4@!)fu_J7$8-hsBvhjrKJm@17(K0qzXy=}z3cPN0`JLs;-PVRlD5Rq0ZwS_C@{7? ROFaMp002ovPDHLkV1j2mV!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8ZEE?e4>pWN1C5 zwBpDK4ZGI1#Rh4gJa??GHvg_}{=}S%p-J@ix9zE}3<{5wLeDMP8M!K^gLmiW8$liJ zePQJGeJGqxQ9N{>qZx%nxXX_dG& UoOjwT1JuCa>FVdQ&MBb@0C_u*3IG5A delta 123 zcmV->0EGXd1C0TY8FU5!0019IEztk~08~jtK~y+TV`Lx`Fv9dTG&KB2V#CEjV%X%U zr?H`-0mU|S7s2E)Y$Qn|KL6ng14d*`(15_}RG2~JYs3}Y=+TSr9m)a+*;bN5m5_63 dlX6H+>i{y3T@4eIvX}q>002ovPDHLkV1jFgF=PM$ diff --git a/share/dark_resources/script16.png b/share/dark_resources/script16.png index e4e5c545b89e0f771d142f81dd7c97d1b3b085ed..2f03cdd9ffd374247f68d027baac3c97a4fbaac4 100644 GIT binary patch literal 509 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|U1(2s1Lwnj--eWH0gbb!C6T!Ye8u^t85rHBjh-r;B5V#`)BX8@-qv1&)2R z7e9Jr&RNaQ1qx=BjNF2!JNgwG8}b)FD!%bUDk)p>+M*6e50;NJI^Nx#cs}X8!yMUd zH~$)*`JmYHYuEN5=D_O*v}|8QaJ1Z-cDw)FmD$bn&gss`)NQhzyzbfj`qJD>`#c%~ z?jIFy(D!HvPq^MFn;_!o=X$-7ukk#GS>}g#2U=9k80OxZEm!)W&F0EvHz~C#nTENS zOJrwVp3)?=uDMiL0Q5Xu1J>K2R1Y79|&VP?QpvB z>aVSQ+Aoq6*LZ8|gi9TEa{vFxZe#x4mHJ2YfA+29_`vsUKG5%~C9V-ADTyViR>?)F zK#IZ0z{o(?z(m*3B*ehL%FxWp&_dV1*vi1bG0HI#MMG|WN@iLmZVd+PKc50MFnGH9 KxvXoSw~(*MuN-Zu9qi2rQftlhHiq!Aj=}2POCgYh?#>NoRSj+Eko+!%$w3ort)z4*}Q$iB}j07|< diff --git a/share/dark_resources/script_new16.png b/share/dark_resources/script_new16.png index 3b583fba62324059551e824cd9e4111d70b420c9..d6e1a45c7e08c5edaf0b90f13ea3a7d6ace2daf8 100644 GIT binary patch literal 449 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|Vb-5N14{zaj-F$X?><>&pIwg;$i{I%}$ABv5FJr;B5V#`&ca9r+jodD`|H zYMWOSa;R^p=9G3%=u1fL-x^)OCG_qApU)fF2b*U+msAqEm^bTN{{Q{CiuczZKHs3X z*}vh0i7WH515<9Wv6x-qG)UpUlEcB!vDAI~q(3R~N0z#KJH}LQ@OfIWS~uqw-#V7X z>CW%w?>JldA*bek(vf$%pPd5lyt2^^-s1YrHnnM*2TxqjqdTQq?)qofxE-F_6}OMk zp}*_3^Wn?lWwmDm{`@^_t;0LXFVl5K4AA|mC9V-ADTyViR>?)FK#IZ0z{o(?z(m*3 yB*ehL%Fxux)Kb^L*vi15BjCRXiiX_$l+3hB+!}uJx~~9gVDNPHb6Mw<&;$V8QNS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^> z;_2(k{)B~BRDdz@@VQc;(0NZ6#}JFtPbV949dZzGO%GnN^al4m2d6xRC7m-$l5*dQ zvaDD57AEJkr)h#T%jtyV&FmFs2Yt>g@lfA!`_2D7_HWL;vs!YWqw3Rsc@LG~ER|Ls zmB~vE2Asb#y~Qhkhf>SFl+fM2HcsL@Ho6HY#c%qu^dZRVhv@W%Bv-f$`D#cbD zXs$fGQpqXjfzz42PhIz^@Ew`?_TH(RU*_&z+F5UC_G)=-`@O=AAJ=Vrrjv7L-;N1P z>5pglKRyz-bK$YsjEaiRCuVBtD_`vSeO&(+8_!1nnNGi>yntR)Epd$~Nl7e8wMs5Z z1yT$~21W+D1}3_OCLsm}R)%I)28Ox@##ROf5*aKaC>nC}Q!>*kacjsl-LnFyfx*+& K&t;ucLK6Vv(4;N^ delta 206 zcmV;<05Si^1K$CV8Gi-<007{3J@^0s0H#SqK~zXf?Nu=nz#s_IpY!wf^t4A2NF3bk z3MMf`TFc?D9>y=106H96BqC2cEh0; z)>-?avmXHit_jd=X1x>af=9#mu;7qPQo>|;eLY32dSp*Xz(-od3bB3kkh6!UQne(E zjwvF5G0jvUd+3K2k+6HodmGfUV+gjE9o)ei4fl@*%{p$;3nMI{7s@nW%>V!Z07*qo IM6N<$f^8#Mv;Y7A diff --git a/share/dark_resources/script_open16.png b/share/dark_resources/script_open16.png index 190cd041651d3358c24bf19a2b204773fce5d897..a41dbce0eb5df1f2e2b0fdf0a9bba394373384da 100644 GIT binary patch literal 501 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|Vb-5N14{zaj-F$X?><>&pIwg;$i{vSoHfDNyKzr;B5V#`)Tdir&tNBF8@7 zpUcMT=+o8VD8bX5AbCSg;;4Rt(BY;8ql~@FN&|0*8$^kVAASCAzWmBw zrK_JG+&msHKf|DX+U)#|sV>pivJ zEY1C_D__n1B)6px9`8M^WZ)40H^hAMj2np(KtHRNxJHzuB$lLFB^RXvDF!10BLiIn z6J0}-5Ca1%LsKhLb6o>tD+7ZY`7NF(8glbfGSez?YglPy^A)Ip!PC{xWt~$(698o5 BvY-F} delta 143 zcmV;A0C4~H1E2wr8Gi-<001BJ|6u?C0B1==K~y+TwUbc}z#s@i_2#|#7EGEjBw8`^ zn?7qTyD%PDHLkV1h4tH!=VK diff --git a/share/dark_resources/script_open18.png b/share/dark_resources/script_open18.png index 6df220b75d85196abc8fa568c978eadd761baabf..d7406d21a62cf1620e495f40c6834ac8993fd3fe 100644 GIT binary patch literal 423 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|mSkfJR9T^xl_H+M9WCik>lDyqr z82-2SpV<%Ov6p!Iy0SlE;T07SpDJFh0u;LK>EaloalZHbZm+`$A`B1KD=KlkV{|MC zDcI~?SXwH;5-2c#!4D=o2l0z<^wvFkqLd;a6T?-@=o%n0M}$>>fp2V+?^*trGx^%z z-;rWYVh=lVsBpb(a%@VR97FoIyS9- zQXfuLRZ2b*k+EZ4?(UHDYb#eQ3W>7MJRUZ&_V$KXhmu9-?$FsJpYK=Os+jI9g|&R!C7 fK+%w!pOTqYiCe>-{#Ac~8W=oX{an^LB{Ts5wsn~s delta 153 zcmV;K0A~NE1F8X#8Gi-<0036bj#mHx0C7n~K~y+T&6H6Jz#t4m>&hhr@+CxLlUAC{%mCzaeu=~&0QcP}xcCcHLpYHOOoJZfp;iW|)?8`V+J8XGS15KoZ@;x= zih3ZnbI#gm?Ebz_kk^s|CuBw;00000NkvXX Hu0mjf&5S^R diff --git a/share/dark_resources/script_open24.png b/share/dark_resources/script_open24.png index 28c5b15e9083dfe5d185d6ae73fc0950cee690aa..e7f97b6a8be7f04c313077f6ac6a577df043fd29 100644 GIT binary patch literal 525 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^> z;_2(k{)B~BRDi#&`f(8h1EZ*?i(`nz>8F!7`W<%QY1>~cWO{hxCDE^n4>ARUc2Co_ zVU-rnX0_%IoDfjS!4}3MB(CVU;-};!wo7VBu7~!Qe7c$b+y4H|PB*tX(~rNosLyx& z*8SopvmFJz4QQ2b@CGrnJv6Qx-(dPXt9!ymwbXavvt>Mg zOvw~W;yr66n)QD1v{@y-Tjspvbm%Bqp#9BxeVdGd_G7&nW$P~QaSp2cAt>tUzqRyr ztE|@}@t>ckEc@R%DbeAQcjoCyMu~xPNjpB(KHqTor#jy*&S_dxG+!Q_%eD0Gd*6;z z?QX^{y)73k_T=O|3qNzRp!Ng*oJoeyF2&cEXC7K)b4cL9t*zI17C$;0U+A`mc^|{Q zLspSDw%myThM8)KYeY#(Vo9o1a#1RfVlXl=GSD?J(KR#)F)*+)G_x`^)ip4-GB8l+ hRhWsQAvZrIGp!Q0hQJFmRDl{8JYD@<);T3K0RVhs#BKlp delta 178 zcmV;j08Rgm1j7N48Gi-<007{3J@^0s0E$UOK~zXf?Ug|efG`LI+n?{xH6Cav76eJE z2fWo#hFt}E6AyqxzRR5ZX8-^f(VhgHSs{*uYHAoo1Wkwb7B0?5f zs-(RX8@9;v%l<>b>Kl|r?WxhqqOxc#s%0l<>&pIwg;!KS?2&-?CI$w^Do+>35RLP>efHVGfii9L zi;I>zYaRQ?7~Q$;l77IM1s5V?t)@+Kjh*^Pr)&O!{D%s=%=zM^=W@9k$R4?*sH!NY z-0OSRcKc5A=YP%>3JHIxyf*!NZRjq!YZvBxatr_2^L$$US+&h9qOX5+oLK+y#J@#H z+YiMG*?fOuTOP5`K%VW0v(oy%C*QaKoo1(bC!Cq%_NUAC8nL_ocxgABnA__2aYcm< ze=ftX3$Gt6dCV^5xHWvn=ie#be-``BxU{+?^tJVp^Ott*%;HFvI^z`OKc6R4U?y9n z$3ly12@hg&KZi~hh~1Q;XyC}nBpGJhJneSS)XbS297ejKD>*b@9p@@ej86?e#uPgv zY3jN>)5I?&BG0>j9yvLuCQ;;hbf2w~>1m@>-J)e_9*s#BSCzm&HrsY~Nq+y^h1GI1tq!}a-uM2c)cp@vYW(+J_O3cCo3eYA;l{t= z?b@doRtv5W{3tJE@JctHE9MD*XYz#!%H^)Nff1ux;u=wsl30>zm0Xkxq!^40j0|)Q zOmq!RLJSP749%>JjC2i*tqcsZmr8y?(U6;;l9^VCTZ7b(g&sf+44$rjF6*2UngD3V B0dD{R delta 636 zcmV-?0)zdB1&Rfb8Gi-<001BJ|6u?C0#QjsK~y+TjgwDk6HySxzj=L&$p#Edb`hnB zLJ&OmAXe~Z6?*WX_@^SG;HiiQrKn9-35iQA6-3diNI|QpRS%vDy$Dh%NI~$t7bPL= z8n)?f+HT*-rqn~hrSCX1{P@0a-jJ^ACyD4N00F>XUtfO>;C})$FA$LeFbLpPUtiyO z00jUHV0L+Vc@_XDm&;8EAx5Q?9spMeaVw7Fhs^vAKmr)iH0`ERY68IiIF2o5e$eT3 z?)L!se14LMP8)`C#WYQ~)oQh}+3YSUWsnTSalA8%qNZh8mhby}J;-B3z>3xeQt(*Fy@ WS`U;KNjk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1K(i~W;~w1A_XYOUgGKN%Kn6fSCrpMc9Q0K1_s6oPZ!4!kKST=6hyx+|=TeMX{ zvn=_Mpk()viupTlvvB8k&7M8;`^~+wGg4dL$u0H%d!Mmt7o*Puk=+xwJNN~kcrbsC zhHppOx$_ot3m>`Y2R`*{@OnPSqHt073x?m45=xi9%(HrVXvvA~f4tNgn4?bnpI~M? zx=Pndhd*M=T7E;`P%(q&9efF4Vg|3e)}LnjH79XnYoTSs?m|PErjrbDcR42>?BjWG zakkL!8$Em)zn;vnIOrJR99gWU^+?jWj`f#r(GDKA71h1wnWot{*B|hTh|J~n3<+@M zZRiqt_VK|zMuEe7JzD=1h|0fUy}Z5f2`fWpVROZgjW5F^4o?3qzw>^*(d&; zy6e1kf&RifVRgN%d#s)2DVn;q9!vNfF|%mN7Wq~7X3od=q=;XZeY*1g`f059dbO4r zG^xDOICvyFK=Swh>95TrjQ=l)6S%n;7%i$Lt`Q|Ei6yC4$wjF^iowXh$UxV?MAy(H x#K6GH(A3J*Lf639%D_NR{mTLr4Y~O#nQ4`{HN;o>$N)7kc)I$ztaD0e0sw_Z^TPlD delta 236 zcmVD@x0jE{&xbL?LN$b zp#WFnAr2sbCm?pW;0ItF@Q%S8f%lXAT>!5rZaYwSQayi!3uQo$8;9SJy$Pt7EUvWm zTDKkp&;YflO#J}bHJYaZ)=alP5EW+T&kpKkQ|f&lG*H+T_d=j63IVF8*Axj7E_G=D m280!@qc8(72hOtQ2Uq|~s%#;1js4~T0000V{0L{dl`ONs+LGhNG`8bRcb@7pGaqOb_ItNKW+C&`KUuq1>s|d}y3^6D>}{Ay zt@FH#D`($OG?iu4zgf+8ZksB9>;?9DKiGCMdicoP5D2>_kZF2^XTmPa&5O49ZVGq5 z!u)q-%_+4huetwkRo}3<+UhgV;i@IB5hW>!C8<`)MX5lF!N|bKK-a)T*U%)yz`)AT z%*wz_*TC4yz~JtAt63--a`RI%(<*UmSTm^!7~l+&ARB`7(@M${i&7cN%ggmL^RkPR b6AM!H@{7`Ezq647Dq`?-^>bP0l+XkKjJBb8 delta 132 zcmV-~0DJ%61C{}h8GQx-001BJ|6u?C09{E$K~y+TwUf~f01ylV?a%w?gqVn+n}uh+ zTxTQ&j|B6n0RZF|5CHiDsN|cG8dHN4=m@BRc^+;6(H^yEh1I0L6bG>3so`}7mVKZV mED){rXOY|n*1+yw_%{|<`BV{K<$7rV0000k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr16wo*Gj6g|ZU+jomw5WRvOi(r6%~*yS|6s&z`&^N>EamTas2I+h2GAABFE~} zb>c)*7BwaBU^SGuCgz)D+#z=GjeWuv4rX7ogGv&ti{FN}OZYUi8+UXZRO*nEP%7fN z{QP#sgIe+K4eRezTh{FVeE0Oz0|A$!bNZ_Mo;SxZh%l~MX4txC?^?z1c!pCV4dQ2R z+jbfFGcgSn!L%EO~lalJG$Wty>p-dvk3C6m++@23-oa-W=q? z^yGx@4zU+nza1GCtO{jV*UYeOwczCywz@AS^ss+4}$cLz55#11m!_DmRVW&A^HVa@DsgMLA3y&XP=h4M uhT#0PlJdl&REF~Ma=pyF?Be9af>gcyqV(DCY@~pS7(8A5T-G@yGywnzJ*pa@+EI`Lcp^o&tO|gNgaa^B zV6@VEW7|Z5nZ4iu-%?;E*OG6C29e}osm*x+)aH{$q_IQ)iZusV+WO7N6}SOd1-Kz< S5+w%!0000NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^+ z;1LNlk?$}FGak=hkpdKCFY)wsWq-oLD=Hvav_4Fkfr0U)r;B5V#p$h6{5`G&3LLk$ zk3Dl&Ek?yKDYAvh)u^ktV+D`UsaFpcI#<5f#VThLrM|l*U^(9xh$?)>zr-3($=};`x)n_-78Pqm(R3uV{mArzxs1Cv4WO1(OK6f zudQ1AY?9nh?`LIw8*j^R(%z#b*=*V^m&m@@CV9^K)o-#HGOy2A^}j@T#Vo&V)1TV= z@$#Qqqc6#A;-matOXg7By9Z9L*WX^*v?a@i>CEM$jBOTP!pt!We)fM`crJR+lS!}i zIl<}n(?vv_i`VMq6gf-Hm73~TEi=7x{Z6g8?b-aQ_>!yY*F6^PyQe*7y`D2eQg5bV zex{AQ?pc%dx@T4HrJb0z;-VA#^~}^sw~zcd!|}eeaI(706RqzrpBc%jFw{9}RsS=e zae4xic+?y*p#$PvZyqsozftL*sNgPKxarMeu@k|r%Oae`(_buYx1IA$>~>g*-D&4d zcNRPFGy8m)T;n-^lhv%+Q&}0GPfpq|y5hU$Y=-%p*cz0UNX-6lMJREa?&^Ohgt~K{ zN#E}@a#x<&QTgrD6w3t8hMPuCI!qfFWYVlIc;@~1b!tUQzNP%1e$@~8jP?xdDvW!+ z-IVAA#c)I$ztaD0e0stxq6IlQN delta 160 zcmV;R0AK&s1+f8;8Gi-<007{3J@^0s0C-76K~zXf?UmsQz#s^O=bPV~Zx{$|a~+bx z#_F$ir=M1`6)(xq2e7LSfSca?4J`ZA3VKmP?BUT^7*Rw#Y`}1M10!BW8Ixr_DK%(_ zMl(E9iRm^2oq#G-%Ye3NA^HoVr?;HeKiF`($umOiZ1_K5f*IHN_YDq6qG*gL%ScK9 O0000!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8ZEE?e4&@&a(3algo3NTgvp6+pO_J~iFVzT6 zMn!uUfi<7vMVJ^JMOZGn8TMxKbWPi7lpw{vjw`uv=Zm-R?w-3>82tA5hY$OV@4Qj8 zXp;TD;_dbrhx-oUOxs@uGX=%(m>qP2|IXGlIqs#gnbTIf>(?BXRsQI~vFEDJ|23=E zA2T>|)2+N&EI|0dv{jv}ryT0NWViPt>-Ounodx->#P*ziVZ{4lZu08dg%1li8R#%G ztPte+$lUPy3vVf-UXZoK(bKuke@y4(XWbBf=wPd6!Moz!L!RaT`E0D`Y&zp#&^5V4 z?)*yCAc=$whO-a&_I4En-}!(0Y3=EIvSp0iAqK~dwrA)W$s{QRM|i}`T_`?fq4S%c zb-L60g%6m-)+Ds0uDi%2#dOEZv`{m!Lg7$jRol|KH1>HMy!~gCcc*>~XbAYA_j#Ux zdGiIEt&w_n9(pyn@ji8CWRgA*65$ok>fpQa{9(?CM>hR<*m9z7F*Cc<;pvg$nn&%N z6@PYp)-7*!PE6uswce1@uFbgX|3=yGehxQ(u&T*buRZj686Pm#R7+eVN>UO_QmvAU zQh^kMk%5tcu7QcJp-G5=ft8_|m63_Afw7f=0Y|CMITQ`K`6-!cmAExjYD_5tYLEok t5S*V@Ql40p%HWuipOmWLnVXoN8kCxtQdxL16_k`1JYD@<);T3K0RTSl0hRy& delta 280 zcmV+z0q6d-1*ig$8Gi-<004~sxNQIc0PjgeK~z{r?UvyV!ypKR+c)RUw{(e(Vah=# zU>5qXX^o$E9C#j^Kj-Fr$IpO7^jdvLBD%T00NaNBPZB^HV1q)S>3|Zb2i&!v%Ho-= z{bCP5?%1>jLEU}UZ3);;=mE#=z24Oda_Kz)M}dTZvlOQTW`DPrmVrl;Buc$u4Qj?# z0d^{xEsj+0k;MhbLSVAkL%q@T=o!-iQNR5kzzlm$DfR$F_7)%-o68i;vR7?!0SdJM z`(UPeDvJvcL|wGlLp^jk;Jo30n%<|r&3Gud4A2A4YOk1L4?wGW1;`V*R6%qTiTVyl eT@=V{pEte|v=J$7^@bh*0000!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8ZEE?e4^T3d3xuSjqi3zyej!)_2kOwpY3-fHClhCc^_*3 zpz6-2@i~3rchRNnd*^a*GfL3jD-qbwwCagUeDIwM5njv0MJ6p+W%^>d!+(Jl$N70* z&U+R1#QTu#`)4!QzMFsMR8g5dk40LGiQ(RvH^#3`SN&V&zRT{Op6%L>LtoBZ6qbto zB&gz+vy(k;RY&~B$hZLYXURMYH}5F0PX6hivCX>GWqz$(oGydf8yO*? zf4wY|bO<==ICn<9LsG*`?Sf!tX1zNByQd^@im_Hsw*SDHB(A``ZGLAv-@6d$YwNwt z=FD8+Cz{K_k@|JjjfUAQ0s^ZZ@?BZ!{2+{VL)GS72U&huj;oF7thd^9! z21bZ#iEBhjN@7W>RdP`(kYX@0Ff!0JFwr$M2{ACRGBmR?GSoFNwlXk?@@39M(U6;; zl9^VCTZ6X1?yEozk{}y`^V3So6N^$A98>a>QWZRN6Vp?JQWH}u3s0tkQVD~ntDnm{ Hr-UW|=GgQg delta 270 zcmV+p0rCEi1)c(s8Gi-<004~sxNQIc0Od(UK~z{r?by){gD?mMQ2lfMe9InYnyv+I zp_C=~TCu0MsL}gMe%#4@R{^a%6rLavy(BadJ+A)&_A6^wA*~o4=ThwFeG){9P*8t9 zGM5V2PT-a72syeo4D`Z=00&zK-E=K-wlk&#xn9(?!cm~M6@NZRZZX>uoTaNtwyg~Z zqJ4WDD78W=;0Rm5)z{+pW~u}$!PNw;b=8BFpfv$&{Z9{euNm>v&h($ diff --git a/share/dark_resources/slot26.png b/share/dark_resources/slot26.png index 58168047b053a9afa849e9abee9b9543e871846a..1c83ef0a9b026d4843cf40df039df85874bdeaae 100644 GIT binary patch literal 1023 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI43?#3pEQw`cV64q_b`Ho)PG(@xm{>c}*5j~) z%+dJhrLL>^!UPIW1ROoslp*N8GD%Qp$~LFfd}`C{94EJ_96cIXplk7CV?=2|;kBy= zLj_pu9b#hUio`BC@?W)8%ur6|`{TQNkKeUEaC?Qp(HFB=M6O;5{y1a8*|l8%!dWh~ zJN77R8993|5jQT7jsO1P!&kjSo9~?eYgzSl&q0QM2b<$2cUA5w%)4n~dhYiT#W11N zN5zjg=jwUYaUS~|IL6Ob^ zF4jeF+5b1+zbn=HQd3=1f_YcG&g*265AT`I?n*{bh~i-mTvXe=(%2Sp8J` z!2=h-#^B*<72Z~%)p?h48n{ROYO^mg6t)pzOL*~Sa?PGjZ^$4W&?$UJY5_^ zIIbrrC`cK!@#y%9FfeG=u?Fhy{FeZfRV{IiC`m~yNwrEYN(E93Mg~R(x&|h?h9)5f z23CfqR;Gr!2F6wf2D|rf1X_orAvZrIGp!Q0hEtC?&jU3`fow>v$V{_x$}A}kNG%FZ z%q_@CWw6ju03o5bcIrS?if~mfKv#rh=7L;eXlZ3&0d#``&?P2DR;I>Rcm9?KDi($- z_RLL8PxVR7OE1Y_Fft3CY?Kd_7DAN{&rAW!{w#OlKygoSep*R+Vo@rCyQgn}f{~t~ z0TAihUS$NTk_MRp%t2Pk`303lnduoN3<0G{Ihn}{F8R5MnR(kL8b$+^DZ!Mbq!uR^ zWfqiV=I23-ODfIGDbdZ$Qz#B{ck)Sh6b7mmg{jU>%qvYxOfD%cN-Y8__n9~06i@*l cTtR+HY7PTPYjlFAGf;-X)78&qol`;+0Kn>R&Hw-a delta 114 zcmV-&0FD3u2ZI5S7;6Xy0001~N=(iG002r!L_t(YOYN003IH$&#PsL)b4!=vs1}^k z*%Am5-Iks&aSYJdbW5G2$RtVS|K-680F*VOj_O_y#6S$hFur#)bw9Y)!UD<$4(*&k U8w3WT`v3p{07*qoM6N<$f)5Za_W%F@ diff --git a/share/dark_resources/slot_array26.png b/share/dark_resources/slot_array26.png index 6bef0951355ac2c8447e7c3b8e794f7e25bdb572..a88716847eed7f33dcc3ebfbc749570788816089 100644 GIT binary patch literal 1025 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI43?#3pEQw`cV64e>b`Ho)PG(@xm{>c}*5j~) z%+dJZrAtF(-zYqqu+S<}K=+YGs7_PsrLc^v2cKNh&q(qJijiTx-qbAL9m+1A9xEHe z>iB{A$kD5w7hS#n#0O;vK0a7zfA4PfoxRL0X}v4c&a*7Ynl{l>?MO|cE6*OKj=B~B zx0s}5^G@kKd0@Hk-NVPPV|&so=l?GLqUk!B(QabJw3ltJd;DznX1<*By;FIOlID@; zM;^1qPWUnL^`_JLb58Sd+ZZQ3F)BVHn6&ZE(IWB9T?>VdcP{Q)6}WFgdE~=AM zjr=|DPwT@)+vYsAIxDEMu|wpNfa2mlt*i|Ki$j%0miw1@e7@RrpLJRimd`da zicWgW{=fPD-C0XldYWs_VW^7F`JF7n@rG$_TW-Dl?XuS_AMBaKqmJ*t$dYE~nP0Ny zg`mL(-k6wjlS=*_cNp8|m7JU)bJ9OpV`{^9<6p~|3@W%=!tUO?_1mJBq3FuhOS}aI z96eJttIs~Zd+^=8f3}z3y=O0vEn1nGqG*+W$ZF^XJc@467_0XT|<)) z0|P5VGb#38pM1wK%yb zv!En1KM!JDQfX#RiEd_|LUEA0lTW&%Fi^E9Om%KzUTIola!F}XY7tnu&%6nzfC~8F b3i4A@a~MEcqZ2%xfieu9u6{1-oD!Mww&{5lPWb;NXB0F?PgKjkF;2|)~6T@g#-q6rMbbUs&LPCuX gLh_>)k=-}}0F;5K8;z2{K>z>%07*qoM6N<$g3J>!lK=n! diff --git a/share/dark_resources/snap_16.png b/share/dark_resources/snap_16.png index 25bf01ddd00d86c5d76f847166a9dcf80ad5ce97..c8666a1a9039807ed5555eefbdae52553b2c7a23 100644 GIT binary patch literal 557 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{Xiaj ziKnkC`x6#kQ31)K^#`WIaYsa?}M!!3WiMG3nnaJTfRUk zLp!s7ff7eomH~&9l#$e;t32Wh6*Yvm%lu|Obn@&kW~n9m9T#M_%xn7{XIypu!#w?Y z#q*y3aJk(rqdGc3HvOfAtfj9NzkE2R&goZa`dengLO Nc)I$ztaD0e0s#FS$Nm5S delta 411 zcmV;M0c8HI1gZm&8Gi-<001BJ|6u?C00v@9M??Vs0RI60puMM)0004BNkl&iZg)f8oGF<1O+l%|@z{P#eb>9BhIsdy(ZRv`01%E%Vfs;I_p(ODM=Fo=U zI71J{(2jMS*XlZsX*7j>4Xp+LGb|Pp8VmYEbYKFVn89J3+xUXdfno?NdG}>pMKiwP zX6BzqZ^V4h5wu_rNAZmJ_>~oSiv=79swRb@4&X)TOQ_G`)siZLR_ugcFHOEGV|Y}O zJCD`I5=SMoAAevlyX(ijVu7Ey75aG~`y2Lwv;o-0YuWor6aNtUs6?hR`4r#hc$_;| zB-&P_HMV8`mlzKHBW`e+NDG+4Bwk?_r}!h0XH8;Zx3tRrGKg>R&Oa(wTqe|ge8u(Z zMO{gerx?K&Hl-o9qYt~$;NX7+s&WT+1I4!VJ0Isk7ZlYTLG0N{WG(;z002ovPDHLk FV1ghTyDtC$ diff --git a/share/dark_resources/snap_filled_16.png b/share/dark_resources/snap_filled_16.png index 0db6956a91ebea1319b88038a44ac571863630aa..229c91fe1fa716320352acd1d6449403a3ef799f 100644 GIT binary patch literal 337 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8U)v6XNAn4SpGd^Vfp)is$p7M(j>7xjGBfkKe$#3rusfP;qkR!TkWOz`yBpvR~g@S z^Gr+LAUhXmhH8mxL`h0wNvc(HQ7VvPFfuSQ&^0j8H8cq^Ft9Q-wK6r;H88d^F!28{ gH33CKZhlH;S|x4`c58L-05vdpy85}Sb4q9e0BI9rR{#J2 delta 160 zcmV;R0AK&n0)_th9k{a0Vc3QaS`$k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1K(i~W;~w1A_XYOUgGKN%Kn6fSCrqd%i)7NNRy|FV~EG`rBnPpLLEhp)&KMK zUAAe7h|%xQ3SCD!jG7mPxqfLEP${^$Oo7QTOO#bjchUBW*=4P1dOBLA!65=cD*ZZI zIxlsn2pw|bsW~-UbL*wc&wlMOPoEccKj+yT%kPh8Ti&*5rZvR@@ zVD--#XSU5!`=n`-YjS46i-jld9m}b!-W{B_UQ3y6)tQnNW$#!xj-A}7^gJV%5J7t;E~S6w9B~h=4>RxtpG(b}`9x7%lF4YsjPuHe7>;YE@m}TG*z-GWO5C>_ zT+fXrt`i7yuSmNU@gtw*_KuUuuTH3&L`%P|ILcYI;z9JKmBk?&nmI%dR3 zw?+YE?vMeFoQ}%@M%FVFtHe?OFQhD=HbCTS1dwe!1(45GR#qBgYvlx&si!TSK} z8OnGbN@m@11r(2edi!;Ojc!b*0?b3#c0siQ`~T5yI1RuLo?lqYTHv#chVy4Lkck2N xy@zy31^xiu_avE9vJ>;3s~By!?is-DgfDlTBrxCN(PaPt002ovPDHLkV1girf_(r0 diff --git a/share/dark_resources/solderpastebis32.png b/share/dark_resources/solderpastebis32.png index 8e1ea1301eaaa5203fdf9dad4984d92edcbd0582..41ba7c51a5ee731a74cbed6b9ab0825debd048b2 100644 GIT binary patch literal 602 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1K(i~W;~w1A_XYOUgGKN%Kn6fSCn6Op5q!01_nl7PZ!4!kK<3L?)5t2AkgrA zO-_iwB=5?CEY+er*)LajxN;pmcBp-Wu>8XvF+v+Q1bRPAaPTOe@A~c2=5u*n%+i~E z%gXlYZ$7OenOL^_TiKKUP7`K`8}qLbmg8Ki5PzmtGO@--(L*$d=aGm{#V74Q6+U_a z6B2HG*FIEn?#8*jT(bQUUq3V)>R;b6cgLy=AAFA5a+yCp@JO)Dds1TS>;ml#YYH2S zA|C41bNSqs3lSAw$uh5<#jaJjlr?iRYiyuGwwfK*|qxFy8Cgq zjw$oa7MF;`-g(LIJK@HYu#HEjetYHD7s0jaQ1^G%a;AJ=QR8Z{;AJUHk;~;m3-qK{ z?#MWIS1#SQ>h?#DJQg{FITNB+Jn5Ojf6vqM%ExsHiUnu))^P6$TIDMvbYhq0_le0# zUrYJ8CYW*u{b!GnU;O_=zRZp~h9ig9>@J`7BmfxJswJ)wB`Jv|saDBFsX&Us$iT=z z*T6*A&?Lmbz{=3n%EVOHz}U*bpgC&lKNJnQ`6-!cmAEy0V%K#7YGCkm^>bP0l+XkK D+8Gi-<0047(dh`GQ0QN~lK~z{r)t1{1!ypVp+dt2rZ$cUs$`Wh` zCbYhi+9&3EUx&Z@u>bY{0A}{;DVmwwko?0qWuti&q6`q3S0G9NGjkO}2FPNsPKN}5 zOwf3=>m0#^MXc?f1 zD-fub2KX31^+=cnl>ih72C(U+0PJNG%`a=70;rcwua9<#Pt7mTFaZW25>`5&9>pxc z2vIR#ngaBgMF&)xfYN;i!J3B&_(!G+q?kj1S#37-;Uy=X-002ovPDHLkV1n6&e5n8c diff --git a/share/dark_resources/source32.png b/share/dark_resources/source32.png index b04fab9b634b30efa9ae3d80f8e715ca02c09fcb..7c01c7bbe38bdb4737a52eafa3dae551d1754ffd 100644 GIT binary patch literal 9304 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 Jp`LTZe*s|zzefN7 literal 12171 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�))2% zgJDfVGugdhnyQx}7z~Xfz&usNJMUCi@Xz4JjxU0~Ap=Z7NqQO5@RMe^MB;7$a?)V1 zOS;yxnGuXt3D#vZ!4NL=^pJ~@Z{jjQ8`muc6O;kTIB1PWY6e_e2JD8v_%jJz9<)(V z!#u@7No5H&6KY@^0lSktbq_H(;u)}ie>X7c=H>;1=-srzi*VD+a6SyQMgd3qf~T*U z-QY3rzx=3P<-rjd!3>39aj*;R$!yrp@j1oINO(Emru_GprAn|G0Snpy*nZ`4k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1K(i~W;~w1A_XYOUgGKN%Kn6fS5!cRM^0-V0|VnfPZ!4!kK;$D?#&hn6ggTy z`7GC?%QHMuJ}M_1xho;^CqjVb=n4+8n|?~3%Wp(-HvMnd;H$HxyE{oaOSvPoOC!b6 z>r_lW|@eZ8}9em#3G@6Ms>*_Hg~W){DfaYhd(4Q?$Nh-%%*&mBaQLKVdkP4E6R6q^aWAGAz4}r#`x-}T>20s) ziXm-qJQnI}8p1-@cUc+Hx+yR@>`=HX2`N-<7x9C>DS2%&z2Y-2tLM` z@tsp|m-klI8L#X2O|hK6pwEC+?la4eV^jPK?(gY$)i*j=yl#iijOafavF&y@e8Y7d z9oYZo>Cce-_W5e~g?NAd1A7*mx2!MNIy16(rp{&2L({x($YehF^y7?seLTzmTI>I8 zfA6^eNM}F#6qqdeb)~0yQvry85}Sb4q9e06g$Cy8r+H delta 226 zcmV<803H8}2J-=s8Gi-<0047(dh`GQ0J=#;K~z{r?Un%!z#s?%_2>M2i^)tD1wo~n zE$#z7yB3IH^A|Vk2Ni&bE)Pf|Vzop7FX0T|1>h~7Aie{Dczu@x2S9Q_3ejvus~VO7 zDB%pQ0%$#kJ1{GtIcRnO1+ol4ng#4G@R$Y3dP|^T0MaijGh4B28%k|jb`J~#jHaK< z5m!mofl+`b_0=_H&cKZD%kF*vj|#TnRR<0L(g9NoehXke%MlK=ZUX2!){c=>SLh_P c472S3H_KFXA>Mf+u>b%707*qoM6N<$f`cbkm;e9( diff --git a/share/dark_resources/subtract16.png b/share/dark_resources/subtract16.png index 8fd86055d6914f4eda262a59f55674537be69b0a..8f7a9a04a588d1f1e609d9502a35f7be27858068 100644 GIT binary patch literal 517 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|T=)2s3scS!D(kWH0gbb!C6T!Ye8u!Xu|O4=D7*)5S4F<9za;^9}L_f)mmc z9G{7-H2AGh(bK-`oS}iiANQunV*CGp{~UkTb$06cdb|H8ExycuXdlve^MCSx|3CH{ zfA4V9^Vzth;Mm0fJpUJlxzt|V_0_fad{glM?fGiVhp(D{fBS#`S(m~m;mR|Q*6K(0 z-Hg2wwQl915AyFURpM)+ezrd}Jerv2c#_;dEbd5uf|FwAPY zZT`^b+WpPD(l+i-Noc4nKJ> zJo(4z16^{H?#vaR7<0Ji0!O0G^Nps7Zb2XV6IpEzX!iLs+)+!5SehaG5*P-mC9V-A zDTyViR>?)FK#IZ0z{o(?z(m*3B*ehL%FxUT#5J}8hK3c#T@($u`6-!cmAEzZrf*0D PYGCkm^>bP0l+XkKSeeFD delta 446 zcmV;v0YUzS1kD4G8Gi-<001BJ|6u?C0hCEZK~y+TV`QKZFjA^%%NK?R4;~!L%*?byF`%KL z0i+NPjvP61V)Eq4%QQ7LCnJkLdGbVf^XAPPGcz-7uo|#w(|@L?Po6yC`~Uwx=j6$g zk8^W#i+~hrYiqwzR8+KQWMuq5efsnxSPkgu>3R0$%NOaatgMEeJ9pOa-@hMh`J+dV z7`}i1e%RI373^$+29%YRX>Q!O@!E|W5U+#i$B!Scb9Hsidj0w} zIfx#G6DLk=FDomX#m>(DvZ$!&J5B>Y6951Ihea{t!Gi~_0|ElJ6ciNjH8eD!L_M4X zibjwNwr$&HVry&r0%|++ix)2hA3l6&=k4u1J2y915I3&@AWd7gY^NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^+ z;1LNlk>v;oGuoWF(hL-2FY)wsWq-oLD=NU=u^`)lfq}8d)5S5w;`G)jyS8NuOu*`!st--qDpC?!RB7v9l)Ebx}q8 zOS!^FMHhZ#?K#47v2UAkwi?F-wkC;?`La4?7MiS)i*9nMuQuBed(P4=J$2sPr;B%K zmE<~1EU)?HUUIkVE$7q)?_4gQzjZv2L2Sju+X=_zN8dgdTRHP~lKK5dEF2vsWy_bI=aAGr zRw@25de1etcMaUCl`KUmI|UcH?Vdg{-nLK0;M%kWT>5J3Q=(Tpuidm_xk9FjoO0V` zqaSmo^RUz+xb87Tce42&w(64!{5 zl*E!$tK_0oAjM#0U}T_cV4`bi5@KLrWoTw)V6JOmY-M0jy~9usMMG|WN@iLmZVg;d SJ0}4(FnGH9xvXw#0K~zXf&6Q6`8$lGt->lh~7znimTPO__ z4?<48l&ny&DU_H!tbfrU;zdX*vNQ)>f*#z9rx;xbr4$9%Q;)@-Qn0pA+mJ&f!BRq6 zFCm3gy~MTIM3bE|VoHV7Y%D?t_A>k4_nYs%c?^OpUg(PT;eY=DNRo6@RaNsvjuApy zAP~s>8KcX=!otFRjPWM`Fz6`hlj-T{7u7gjfM77_0f3i-gM%{^MXe)*S`b2cB7!l# zrfFIkA!La}BJc9~{4+ri{51ihDB@ZtTv=Ip!}GjL5CjS#R5OO;t*)+?_V@RnHw+-j zxm*sy;qU{Rrhh-yIt0eJS(fEPU4T$1^qpnd+eBz%V*_}ehiocc$E`-Aab|aSSJ>Oz1FzRh z08IdJBFl17H$al4dp$ipKO7DRcDvos)zw8iozC)EV}Ge=G|KJl?7Z^%dxX%p3R0zOsx3>%p4XM={#bU7=iA3VS>-Dw*0J%}9p%N`FF1mYrdy@>q zXavA8%p;e}l>mSe032^^ZMnC%w_n?Aw%>ipWHMT*R0`L`Av7~JHI=$>4$eySkmI2zLElxB;?(n{0x9g3p9C6h^*ot@2&kB`%Y z-Y_5#2-ti+-^pKw3dQ4bgU91hMn^}RF9n#NpK2F7J3H3_z@%v!Z7>)rnx+*Bg~E~9 zY__CQsk?r^|NY3wNaKK|rKMbVclWJ&h2PxVJe-`Iv^MOZo^Y-I4fWv40GAQ2m!s>! jsV8#bGx{&ddUAgOn3QiQBv!Ee00000NkvXXu0mjf$-ri? diff --git a/share/dark_resources/subtract32.png b/share/dark_resources/subtract32.png index b460e0d2c0a7d3f0a87579c3bd3a7f72beed657c..8bb30d491ab792d662865ea941f3e465405e6e42 100644 GIT binary patch literal 804 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1DhWRGhUkzwi_tOUgGKN%Kn6fSCn7B!2hfYP?NZ)i(`n#@wZdGvxNgi8um}l zoE2uwlAU=pNM~(E%eAIZfjbcbTW7TPw>}ZyQLsF;K=jsB{+JhD;dwEgH+sDT%?meJ$}W)i zuzUJ#q1NRi+`sGgToHf8uysQ43Gr|5GS@uwSX$t(bohY!^*#110e&_~_pW-UWVC(l z+nKe{^6~m^lYUE!nzeie$Iq^iG+ms=)WB<=q9DRBrQ%&Khx_&!OSlfK%HDgMbHSgI zt)?PBUWrxt{ZdgAlxz92fOo=^W)3lN#<24n-hEY;Nw~7yFm3u?vwe?j-p?or{yJT+ z_1%JhQ>8MkT7$o4)*gTAD{WH$-&^8Tzto@qe=ViLm(>FV+ zTfV-yRq=ntSGP++-uLsOx)v&M#Y%82(pY(OO;pxOKFzg<^VtJ)LNBaUi$3?UCifAu zguS(3;uIa>CqLZGvt^=Ven<%1PwNPO85{HAb$oyCL-vf_orh~#PONws@5KCJF4x>6 zd9}jP-WtdC3lHvYWqf&FW1IBT|NAG}&z`a2-j9qk%YdmywZt`|BqgyV)hf9t6-Y4{ z85kMp8kp!BnuHh_SQ(mHnV9Pu7+V<_h#YOXj-nwqKP5A*61Rrb88+EK4Gf;HelF{r G5}E+&vqLNZ delta 943 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 diff --git a/share/dark_resources/svg32.png b/share/dark_resources/svg32.png index 3e9e6d21f0ed77e365ca14a47f85886e92763a91..f43d60380c89aaef811f8a850f7ee49a0883e7aa 100644 GIT binary patch literal 809 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1Gg{;GcwGYBLNg-FY)wsWq-oLD=HxNNWgm&P?L zt?I~d6j&X`A?m2&dsA_(>dDU&&YGP}+kEy__4La8XSHYE%$_@6(IV|qN8|R?i|byH**=5C)<3=W)H!f?6myCkSf9`k`s_`Htwe&f`J0S+6BQcV?uK(rSyj*ee<}BW z4vSN)>bK5@Zo9^Akg|W??H&DD)8sxmFuQkDgdMFoZ8PD~Ohto5?r%BQ?uuY}V5M90 zokiyI+b0apv5pfa?Adrk$Xn%^jmY{XdyhT-v|z)%OGbH2k!&X#yr#saD*DW^P~Yjn z&bGa?XnNtV)uoA!vB`5Ij=J5>NSeU2-tt`BG|RKj=LFW>JI49-+*fs-g89{347|lXcA&zU}b1#Wn`plU~FYzkiAs$3yOx^{FKbJO57Txek}9=YGCkm L^>bP0l+XkK)UP{e delta 280 zcmV+z0q6dy2B-p%8Gi-<0047(dh`GQ0PjgeK~z{r?U&&W!ypKR*Ei?Qw{)2eV|RL3 zHBHw2o1yw~fWr0wKQnux^~{=?ZHoPm(TKy#!3x9|fInRMn0c7l2LhZqe20oE*7jQh z@PUFku?&DgECoOiQvgsNu*#SQ5G$l4W=zOy0I%k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1Gg{;GcwGYBLNg-FY)wsWq-oLE6Q&rJ4y3AP$<~b#WBR=c=Dg~4w4Cr0_>T& zS4!y7}$&d!!7q z4y<52e2ihz>(+yT#(}0h46P6Ne2N4P<^hdYEpd$~Nl7e8wMs5Z1yT$~21W+D1}3_O yCLsm}R)(flrWU#e##ROfdg@;mplHa=PsvQH#H}H|%0~vMfx*+&&t;ucLK6V*t71j~ delta 150 zcmV;H0BQf=0;d6x8Gi-<0047(dh`GQ0B%V{K~z{r?Uz9cz#t3+_2>I@g+eZ&A-13? zWjrd9*-0+xt@!lf`fWRaq;VHg(pCHa0G8fNSaQ4HZs0LM)U&t4YKfN(08nlq>$L~; zQyu+Zo&f+bfB_6(00S7nz~>EQfc~A$C^L3!Gm1baNw3HulMm%OssI2007*qoM6N<$ Eg41k2NdN!< diff --git a/share/dark_resources/toggle_units16.png b/share/dark_resources/toggle_units16.png index 2da61f42840cb23da7f861b9200c859429641af6..892b5808afb0bbd27aba5177b85ea5def97e721f 100644 GIT binary patch literal 476 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|Vb-5N14{zaj-F$X?><>&pIwg;$i{vSoHfDNyLVr;B5V#`)X}>w}maWe$9N zKesP=p@msnu0_Uz$URK~C2c-tpE+z;k1jMwQahMwW|jPrwc{7hmGuv8cI>=;chm0q z_vhbrRWkk&vCcoU?|||CEfLI11nVBQYnJ;k%sN`0cCVweSUu>ufAzC6SD%>b+1IM} z7oQXkXW+T!C8<`)MX5lF!N|bKK-a)T*U%)yz`)AT)XLOc*TC4yz~DxHizkYP c-29Zxv`X9>RvOuS1!`dMboFyt=akR{02bu2H~;_u delta 174 zcmV;f08#(k1HS=~8Gi-<001BJ|6u?C0ES6KK~y+Tom0^gfFKCVKj+Wu@Wcb!!0OFp zV{ACC!%swREftaBA>qKd3~cwFq$SAUOi~h{&ik4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1K(i~W;~w1A_XYOUgGKN%Kn6fSCrqfWp+g=0|R4|r;B5V$MLCCcl#YSkZ_Z= zy1;9u(b1|XbY|`^mRgoP|9}YzE061aU=ZPSn|A1$WJIH2njZg!&ZSrRS4_Pm*QR13 zu3q@&?dJ0vzaB4>3F+LnAnoOeeOveM53!w^bbD)s&FKkMHu}x)10R~L+;H^aL@uqh z8)E;4xP2+O#3fyG%&v>A-BBnwVvSz%E{lyOi#BM+US6@|qp0iB*NX$(j?Vg1G*|t? zqe4}=xekUY+D5w$N$cyRa{oE2U1q^I>FJ3VSsm$|TPlqHuCLnUUaCti|F;zjh`py@*9Wgf^Yb?L={_cf;3^~k7;*4MZyaYy&YKdz^NlIc#s#S7PDv)9@ zGB7gGH89aNGzl>FLW8Gi-<0047(dh`GQ0VGL8K~z{rwU*lw!ypJmn?Lu@+p*JRj0Mi3 zq;HKE4(kdYuZMoEwRdanpzU!2ZD5V};OBROC8)?`k(B^= znJW<60JGuF|D*XLCAI)EhVvkn0agrWK`a4S_gpbtH{iTB4Sx{HP6cRN0o8C;_1pG< zDlwJj-!WXuOGgmhbLtfYjsRr1sM%2P4j%$k8_rV81$e@6GJqnTclOz}e+oQlI8?xs zoqGCQ;pVFr-IPlK&v1&Q${Y{k3qZ14Ep|}ldjDlIKiB^O&?9opWG8bMK+U2e_^l9S zHq6YWQhmFI%0|Y@911#)V;xZ6cA20dfOn^>GryTo>EV<6v5TsTEO$dS0L{Zp=$%Ia fXdD4(gWd5DsJ9F-r5v~=00000NkvXXu0mjf`o)y< diff --git a/share/dark_resources/track32.png b/share/dark_resources/track32.png index d9ae2ebee8187319ea5a308780234a4dca4e5fbb..0a6c25d84b6200e4708a9ef70397eb5f9dda7266 100644 GIT binary patch literal 553 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1K(i~W;~w1A_XYOUgGKN%Kn6fS5!cRM^0-V0|TRsr;B5V$MLIEZ2g!G1zPRh z1GUZ_V6*Q`_NV2{bBH#3);+si5I zO+MNBv7T$ep`?|5ZWrSA&z+Of8l_vmm3^+7!EZscg9|224HaFKZkq5=a!;|f)%%9l zozE1`RxDn;I8AKt7M*reiLAF+Z}Ooy&6%vosq@y*;;j-IjW$4XhV*YXc8U8UaI|LAAs+q9i4;B-JXpC>2OC7#SED z=o*;l8k&R{7+4vaS%J95Rt5%ttT^tXXvob^$xN%nt)Vx4Ln2TEgQu&X%Q~loCICW+ B#smNW delta 229 zcmVK~z{r?N-qafFKCeKj+VDwQS5pKq0f) zQ(KDH-N6~d;3p0~KP&(b1^{5gvH*Z9OCkUX)B&dFz2vt!09bSiW)9bL)i?9f>8;#T zuK}P~YyyyXN-AFK7*h$R1h6C+?ty!?dk$!JxKzcy$y6?4N f?;mOR4`*Np6-fjzRFK#100000NkvXXu0mjfmd#y$ diff --git a/share/dark_resources/transform.png b/share/dark_resources/transform.png index b8950bf12006b9a9f05a17a6d26b83102daa94cc..d3846d0c8925166df36767531bf4d11786967ea0 100644 GIT binary patch literal 571 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^> z;_2(k{)B~Bl;1eTZ(=qB1EaI2i(`nz>8(>7{SF%lxXy2$7&TG0RqSFM<3`tx;3>ji zctn4{6KJa5pdtQ1LS})`6o>9xp*(U~5qDHu(ldC4+)tO24r(8*;!eA;Eiz+fvYcYv`N-UIdLPSG2HuQY z89GTJ8I@0)mECWvdmjN7aj3Z3nGn;TaoO!&ENX~?$!>@RqKue953o8TrtBb=#+uiw*V5$A=o zi_UI5Rryt{|JjtA>s{1lUTV;s?(!~{JMYl)g17D_v6oHx_@9Q(Nt$o#U)0aO;JnD( zpiib8++u#G_ycabPW%4G`dY~K`L3bt1*f-7{9VJFnr+~+LtE;wn#0PkHO!kA-nWP_ z^f(6$Vbv1Xh?11Vl2ohYqEsNoU}Ruqple{FYiJT;U|?lvYGrDuYhY|;V6c1tMo{D; dH00)|WTsW()^O?(=Xsz822WQ%mvv4FO#tbX)2{#k delta 185 zcmV;q07n121j+%B8Gi-<007{3J@^0s0Fg;VK~zXf?UvyVfFKBj^UZnlnr=EW4{yR+ zZuQfUuMN0*>8izBu?z(RRtQz&6 nSyG@zX!-N7Myd;-l_0lYF9CQNir$#%00000NkvXXu0mjf0dP@d diff --git a/share/dark_resources/trash16.png b/share/dark_resources/trash16.png index 137f8392a167c5dd5ca349e11764d0c3966b5d38..eb76cf269dcc603c3b1018a31a08d867540e0a29 100644 GIT binary patch literal 791 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>3c2g6{6_jhi;!xOoGp=F{g-Kofrb`n6!eg3{8` zy1Ke0OP8EJbNc10mv7#@dGzSfx^?T`zJ2@q&u^fbr%#_=zI=Jl-aSCUEnBusn>KC# zf&Djc-F*D`@uSC&4jn$Uci-OD)>fchYuBw^v2w+gt5+Hu8xJ2j3{-jP(xq+Nwyj&g z?(&t(Kxb^)yy?J!1Gn$oK7Zjn(7L;K@9y2ZcjvC1KnL7^a3ARG2M-?r^_G;BOqe)f z(&R}%EkHIf93F2I4+Vx-L`jfeFoQ6+Ub)})C#$Qr`L>rbuDJi~*^5JsJDAwi(^g!6 zdVPuulcfLT(@&mVWzr4`3JOl>S)SK$^TGYr2AxBdrN=Z{MR#SU?&Gg8I#FMJMz2Qi z*2~+5`h}&1hM!s7d4P5>CV9KNFm$lWdH^|`1s;*bKpMpMU~oH`Z3kqqmw5WRvOi(r z6%}AjTgR0H6q?}a;us=vIXM9cQj!u9(h^e}n9a)g{PgnV;w0wx$2$agM7V_b$fzkP zYO3lgYpbZJuV=Wvbj6Z2i&iaLw~+H$W@dKw>ld$HN=ryNF6nLcVeviN;?r_w;Va!1 zowaLnbKbVRdC0`q=XXwTU5IFbaMAYk{M5?z<0m@@CpR}M3)?{%IT;}?mc)k& zW(-Ve(tOju?wbsBn`((`L`h0wNvc(HQ7VvPFfuSQ&^0j8H8cq^Ft9Q-vobK%H88d^ kFnFV`z>cCJH$NpatrE9}xm7cE12r&sy85}Sb4q9e0AOKu$N&HU delta 497 zcmV}&;OMGF=zXyV}DFpr3ca7Q-;#RUxw4Qv7e0*a3xKeoSl^M9t(wX4_koI5;@e|N8Yycm3M+(=;_Tx3jXc z{<(1JLSSTMWD)}d!}VRecC{Tlb_~A(Z{NNZ+p}lSQdwEq_1xUtf39D<9%*N97bqnq z^lSZ!p8FF^=jLV?j2A niHYftoSfW&;^JbsW{^Apmr@TPt-b#%00000NkvXXu0mjfIhFC) diff --git a/share/dark_resources/trash32.png b/share/dark_resources/trash32.png index b9a4f14b1d5c15a711c11d789f20c5b57ac8d809..8ba6f690be42c879d8b7982ce5bdf42850d7483e 100644 GIT binary patch literal 565 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`KiRiV6tUl-v_!U|?kSba4#vIDU1iHD9v|*BT`7di5?rh(dD>_xX$SrTR8T(Y>sS#=cj&HJN zI#_%@b>8v$hrrPVWdy$j zP3@%h8|;@5T=wnaZ@<`oyDxy5J&x{}*%GAE8H%?}?RcsXMCSv*Z>mC2oi~7JQx+nl zlL8!Qd1W=5hvn+vssn^WOrX)n{WH%|O;X10eyb<`iNIuxd^qLI7g^wJ6S* zcU9tlM}NKV^*gRqUJ0u{s8TN?nsBO+5MY-1)LhMk*Fi6$ta$`6(vjD&YVIK-9hrpW f#j~>J5AXzR0}`kqJF|if00000NkvXXu0mjfIMI8P diff --git a/share/dark_resources/tv16.png b/share/dark_resources/tv16.png index d21417f7623e1ee7db9200d6ea791790989351cb..501ad7d7ce78c340d8417ae6462fe3b5b6a59438 100644 GIT binary patch literal 761 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>rtg0EkmJb6-IU%ztI z$~$-OJb&^0(&bCPfB*jR^9K;Te*Jpy-o1N(aPQuC@7@6gfByUllzspH{p&Zc4IOeOyzAH#yMwJ9%*@=gRxw@kO4`rl zm3V;ZihugvCA-YDY>xM;?tAv~>1IhDeKQ@71Fe5Ffu=JidAqwXbg;^L06Clm9+AaB z8pQTsa66f82V}69c>21sKVjh&6%ehKl;Qvib$PlthDcmaPB_3MG4p_kF}HR|L+@N> zkD{W&&j+r4`1FyRgG(_}NK8;vwE6Q9Rh6YnQd3f%J`ojhtWixB4b=z;zRtjvk(K%S zMN?znynT$!%?l?Q9?}sGW@9r}E^cXPRW)P^yJp707;UYP`2N8Q7S?lm>l_%(%lZ8^ zK79JdxbpMY&+SbO4s2`;9kaxn*M%{x1G-AJ#5JNMC9x#cD!C{XNHG{07#ZjqnCKds xgculD8Jbxc8R{AsTNxNc`7&psXvob^$xN%ntwCF0_f?<<22WQ%mvv4FO#sP3UYP&@ delta 465 zcmV;?0WSXe1>gga8Gi-<001BJ|6u?C0jEhsK~y+TV`QKZFe2-ZiHXtQwryMRyLa#E z(9LaVX!t*E>a=N2&Q7f>R;+jilSeV2p`n54_wV2SQ>RXq`|#nzM3^G5=4sQKa&mI^ z{rmUtKtn?VTpx-7Fb$QJl>yVHO|vO1EG!0zO`be?Vt#)9+JCyby2I!$!)gG?#(8t+ zok>bgG688=xnkwk>o>0ZU<)p|0U%8<1--q!ohBwGDvbXbnL%Rz8UO#Xx3>>NHUQ=g zumLd5yLRn5!ok7u9bd$J`TT{)%iGJcqoc$A$B!R}zy?T&NgT9uusfoqrPX}(>eb)) z43L+X=eTI+;^zW-n{7u zH^9x!tz_Aw0*3^{!0@D?X$ zr?l$o>gUKQkw-{KNcqp7KkWDnVPk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKpuOE zr>`sf6Bb@kem!=Nznd5s7$rPi978;gznyC6$80FzIzL=Naf?dkwuRpA!YTo`LUuBw zH|##3DK=5MfJJF3183(nJyC5&-UqHCBJ-Kp6WTjJ;WKl#;5W*RExrgr`* zY3zMqvxNVE>iov^$;u4R?o{pg6B`v7xpMV|%f<699S@)1y!Akog4%|^{7XU~oW1F% zT-3Pd7^_w~J8xrcx;&H3ik;5k#o?!HY%X7^zixJ+ZZa&yWcswzv03SyW0EWZ`^xlU(97%abf0Ko1&$`qPZK@E?xWm z<|1?4j`V#xCzhOR-JmW0=FhdlZ*0tTCEiEBhjN@7W>RdP`(kYX@0Ff!0JFwr$M2{ACRGBmX^G1E0LwlXl- iw5dNCMMG|WN@iLmZViXuo8Jd&VDNPHb6Mw<&;$VIF~TAM delta 187 zcmV;s07U&<=hjbK4UspkgC zxc+9|=SgTShfh7MUvdM8$Td48A}Tcc=F?;imH>2s4$uKQKnMQsz%%idQ*>3m7T@mR zaoqQVc`w+BzXI6JcVvyT78ut`rd6lGSmI_2#^fl3M;rq1z%+P8$6T%!AU#K8!@mF# p(wrecZU>M)M`LsUf@oF9yBk9os39YOi7A!`yhDbSkwm5ZV@>Sv8JOsj^FeoyPx#sO!#yA z&6|HU|KIdU%)T0V^L^ojJHDEZQBB>cZ&cfM?tfyLecI;RF-_aYJ31wb{MfVhc<@O? zubTg5w%j4*yXDI^ZBUT@0WuIyBRAY&ql6_e)Fd9-kyrazklYZ|8q-{ zU}2tdWb?zzR*Vm}IG$f0FQ3*Ppf0cK^w4$AwUqGkDH`7!5;Fp{Wtt>9X3dI~=-#Sw z=R+(rOG&Pnq(j`jWy?k5b2sQ7E14ou_rrr%`U`uxx!>%CA1?s|l|i+{HKHUXu_Vlzqa85mg3H48@3kei>9nO2EggU5ls_dpE{ Mp00i_>zopr0JbE!lmGw# delta 451 zcmV;!0X+VI1kwYL8Gi-<001BJ|6u?C0hvieK~y+TrIWvE!cY{(&msS+5vL;3)x{R1 zo3G#lIEbT*AVxvKA-DuYA&ZKGj}Y7ieTA-7$dFk&bhI5JZF9=GG-7I6Db03s_I`r= z9AG+~LakPd0>0Z$r_<2wc9DpbFA9%!wO+4ZI-L$wtJNq#QIzLwHhZ1PWVm}!E|;ZJ zsU)(4y8y*34UBCA{?{PRBp5FnF zzz#xy>$oheJMX?;uSeDz$w3G( z3_}KhK%@+Li-eBj1R)?yU`RR!i2=54>xo2yg^^Ca?>xg`Fo1TuEo`3_j|WZDT+=jf tZQG8GuW6dc_{IYM@_=FimtNmb^-m~Z!V#fIy6*r0002ovPDHLkV1i!>(A59{ diff --git a/share/dark_resources/union32.png b/share/dark_resources/union32.png index 07d4bd69f9a90fbe8079a24556bbcbb7ef65e3eb..6a12eb38f93c8fd54678885a7d339d951d5bc10e 100644 GIT binary patch literal 755 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 delta 205 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 I>zopr0BClC0ssI2 delta 128 zcmV-`0Du3?1Cjxd8F>Z(007{3J@^0s09i>yK~zXfV`QK)V5G763?smThK7d!go3f5 zp#f(|5DX%^S%A%zFw3dpgHa1`CKP<(JQ@e!U>gl0qKk^5pV9D@s8lJ7Xl4PSx`2>8 i!AK@#03rFIZvg0000k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1DhWRGhUkzwi_tOUgGKN%Kn6fSCrqhSJxyCsEO0l#WBR=_}wYq9wCJy$Lhnc z9NMYt7RV`n$?NtP2{xq+!H0|3w{~*e-okN<<)F(B!4iXT(+L-?1h^LF>ai_46y|Cn zI91TrrA6+Xis$oJUnG7BX=-XJXslx+mXw@(QO_FkRU^-{bJwf86&R&)hxcQz1Nik6pofzB6C$ z`koEenDyLzDPLjBbCcp}#Sa@~O&G*q&uX}P^17?B<)Jvc9m@9vK4w)5uovxF%v!Pg z*%j3fWo+-yth&kh?#-#3zo85;6Pl*) zzgX_&JYArmYxtqfA9mlm={iT^=>LN%kG5@ZcS|_9_e?+pzgA|mT*SeYO_g&w|F?K` zz1XNb+h^M4&L{?rRV#zy?Or+PGF({~u6ksS*)=AIxwFhN!#3W^YY5nWZ^iCg5{FNJ zZ2$Y7QS|Yj^$hzNSSG5>UhbS&0!$~WC9V-ADTyViR>?)FK#IZ0z{o(?z(m*3B*ehL u%Fxux)L7TR*vh~_M`1w}iiX_$l+3hB+!|tQC7uB_FnGH9xvX+|H(=ku~D!|DF}9g z3ffuv2EKr$uMjei;Ir7Cg`I^6Rw9aGlSZ&r4Bn2coREuq$z<7Z2$v?!X6BoJ{+$V7 z&JWEwKNbN0Ljh)%Hm@*qa3QT9b|tPug+j~(=#%^xBm}|>;D1Z*3$8ua);<*g5uE^d zPm<);1rw1a5jhf(<*KUA(=@#aZO0z~PgNTLok4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1DhWRGhUkzwi_tOUgGKN%Kn6fS5!c-rsSR=0|VoCPZ!4!kK=Er`g@2ZN*t@- zyxZ+yf-b9|v};IPixXEhx6<$8j|wFmTnkxWi)4Ry-L+%;A{$XhxmQ9L4NtxZnyzti z+X4*^D~@cwY1w<4zq!}goC%qI&T4j?)fc<=hrjpztUL34-}}$K%Gbm?P2c@*XOzC- zyh*QV+A7cMUk}yIICDMu>*~NYOYGbGs&cP|==Q$O_}fseHo0=wn#reDxi^2in-a9o z&f#3jrPy4-=Thg^?4Kc&b=7bm zc|#Ud^t2@`o1w^jhVAo`WQM$x_Ab)RtV; zm9%T$&bhbb+zu@pmU?^fRX09A{A}jgv%E00;>kV6{qvO>eg%EF!Fxb-Kl2^IWslEp zxvA#6Z9(=e)fS;s87f~~Tx-8pEDT**a9F+f@20CwCsXE^+Q~Hpz1qA}%iQn9l(^Oo z&AD-W1xk8XOSfD&$9K=*SoIOLc|U(M%qS}6xq8kqH}`7$hi)6$n4cV5w*)^{e6*Nv z4O_#kP`>voHqBZjrKxxCQY-rd^GUyN%lrvxuQXfRcvV*MLg!N6r+@yNZ{qm9JIZsC zMe;dds!%O)jVMV;EJ?LWE=mPb3`Pb<2D%0&x`rkp1_oA!W>$vgx(3Ep1_s-O3^$-? c$jwj5OsmAL;h29X4^RVxr>mdKI;Vst038iKg#Z8m delta 407 zcmV;I0cie&2Brg$8Gi-<0047(dh`GQ0c}Y{K~z{r?UuVu#6S>+{}G%MIv^*c2`V5V zL4t(b;}SNYfi;&nA%K7eXn-CFNFC4u0)#ZkCm&jwecP)`&XN;Lp84jVCt=4A?btu| z07(icrDU5jrBu?tu2ct&m`+_r=D;`sVjP=5xe$v13@|wmR(}9n^n>xP>sD1&9rS(w zqm&xnznaLcjeh`Bqh?fE>jwZ=0PdOjW{i3k#B2Z?L`o{W08>LY1q|u4S~LitwSFd| z!@-e=oB}uo@J>Xpl!OTY`0oEe2QGkff0Gt4L6Ooq@>Z@rQ zE&?#^ZKDRRnSc4wmjBdwkkti5bXnK+QxO1PTeWR_Cn6U_w65#=c5Vx9(rPO%*B;om zWoS>#ngcFbQ!l4j2=6)$MH+&Nfe79Mu6b`RA0KE4A_^cBX$)lcMHJ&arfytHET%v% z#Nq(Hbl6lV0+2GGiUF7qzD_6#5L3W=fSoJw3oc>UArMmPBU%6e002ovPDHLkV1j}V BrL6z} diff --git a/share/dark_resources/zoom_out32.png b/share/dark_resources/zoom_out32.png index 38c13e2b971a2b349f17028354b46af4f3145322..3f3ce4ca381bf1f49e7f60b316aab076ce420957 100644 GIT binary patch literal 723 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr16wo*Gj6g|ZU+jomw5WRvOi(r6%`QRE`A3TVqECy;uzv_{OuHbk12%`$M?Ul zRBF;-F<&8bQ6Okpb651m1vlhacBKeBTzgf3t+m?Zm6}YiZ=TZ*O}=}b0#}q~n5WKK z8UJBN$8VF8Ta|l%?%SJt@pH7?yyrjbe*CSRH~-81rVR?2v6m;T%kXy1WqE3!QgomF zSxIPxUvW*LdbjCALDu(wKSVA!pJ#Kl%TVWnvw~;JOw%?Y*+Pc?Ud8JIvc*Ry^iM0_ zol_w?sWOYld=W!=&;BAsmC4VVA4bm5iha)Sm7CxESH1sA`8JIiDX!wC608yvLMBLD zjc~rYglpCX2MLAH=kL8v{drb1GwRQIOXE=uEe$b3STDOm3UuhDx~o7Lg-_z%A%O(a>e%S-MM;4 z9eV;+&35gnWlEfU&Z2`at>Q8BVaI>KFVcRdP`(kYX@0Ff!0JFwr$M2{ACRGBg7sT?1n) z0|UWSD^RjRXvob^$xN%nts%jpX$Me)B*=!~{Irtt#G+J&^73-M%)IR4(LAyKnI7~TvbiP=3bZ$94qG11^}8XTW?0N4R*?Y)#PYb~skYCs3M;9Efr z2n&D)Zhwrc~a|Qy4c7J;BuS9g>rslFNmn{UE zhN=TmD1@*Q(U}7<#!UYU;G8?o^L(hJ;MT=~7!=88w<3JqS~3Sv=wcT<1wNKf4x)7$ zetj26_d<0WY8H|Nq6$z-hvX^8)ei)a+~{2!sW7rZRSy#3ZAC99u>%N<#EC8dT-~H; y>jr?%lCA(LL?x~peg;r##qI#LqTK<8JMaL2F`ywDI(wV|0000 Date: Wed, 15 Apr 2020 05:42:38 +0300 Subject: [PATCH 177/209] - made sure that the Tcl commands descriptions listed on help command are aligned --- FlatCAMApp.py | 26 +++++++++++++++++++++++++- README.md | 4 ++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index dd8f0e61..6740bf68 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -11970,10 +11970,34 @@ class App(QtCore.QObject): displayed_text = [] try: + # find the maximum length of a command name + max_len = 0 + for cmd_name in commands: + curr_len = len(cmd_name) + if curr_len > max_len: + max_len = curr_len + for cmd_name in sorted(commands): cmd_description = commands[cmd_name]['description'] - cmd_line_txt = ' %s\t\t%s' % (str(cmd_name), cmd_description) + curr_len = len(cmd_name) + tabs = '\t' + + # make sure to add the right number of tabs (1 tab = 8 spaces) so all the commands + # descriptions are aligned + if curr_len == max_len: + cmd_line_txt = ' %s%s%s' % (str(cmd_name), tabs, cmd_description) + else: + max_tabs = math.ceil(max_len/8) + nr_tabs = 0 + + for x in range(max_tabs): + if curr_len <= (x*8): + nr_tabs += 1 + + # nr_tabs = 2 if curr_len <= 8 else 1 + cmd_line_txt = ' %s%s%s' % (str(cmd_name), nr_tabs*tabs, cmd_description) + displayed_text.append(cmd_line_txt) except Exception as err: log.debug("App.setup_shell.shelp() when run as 'help' --> %s" % str(err)) diff --git a/README.md b/README.md index 84ca08fc..f8d2641c 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +15.04.2020 + +- made sure that the Tcl commands descriptions listed on help command are aligned + 14.04.2020 - lightened the hue of the color for 'success' messages printed in the Tcl Shell browser From 03940110469b82ef7f3ebdefa9c9889b20c7b00c Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 15 Apr 2020 05:43:39 +0300 Subject: [PATCH 178/209] - added to GIT some missed files --- share/dark_resources/Makefile | 296 +++++++++++++++++++++++++++++++ share/dark_resources/black32.png | Bin 0 -> 183 bytes 2 files changed, 296 insertions(+) create mode 100644 share/dark_resources/Makefile create mode 100644 share/dark_resources/black32.png diff --git a/share/dark_resources/Makefile b/share/dark_resources/Makefile new file mode 100644 index 00000000..460545c0 --- /dev/null +++ b/share/dark_resources/Makefile @@ -0,0 +1,296 @@ +#addarray16.png +#addarray20.png +#addarray32.png +#aero_arc.png +#aero_array.png +#aero_buffer.png +#aero_circle_geo.png +#aero_circle.png +#aero_disc.png +#aero_drill_array.png +#aero_drill.png +#aero_path1.png +#aero_path2.png +#aero_path3.png +#aero_path4.png +#aero_path5.png +#aero.png +#aero_semidisc.png +#aero_slot.png +#aero_text.png +#align_center32.png +#align_justify32.png +#align_left32.png +#align_right32.png +#aperture16.png +#aperture32.png +#arc16.png +#arc24.png +#arc32.png +#axis32.png +#backup24.png +#backup_export24.png +#backup_import24.png +#blocked16.png +#bold32.png +#bookmarks16.png +#bookmarks32.png +#buffer16-2.png +#buffer16.png +#buffer20.png +#buffer24.png +#bug16.png +#bug32.png +#calculator16.png +#calculator24.png +#calibrate_16.png +#calibrate_32.png +#cancel_edit16.png +#cancel_edit32.png +#circle32.png +#clear_plot16.png +#clear_plot32.png +#close_edit_file16.png +#close_edit_file32.png +#cnc16.png +#cnc32.png +#code_editor32.png +#code.png +#convert24.png +#copperfill16.png +#copperfill32.png +#copy_16.png +#copy16.png +#copy32.png +#copy_file16.png +#copy_file32.png +#copy_geo.png +#copy.png +#corner32.png +#cut16_bis.png +#cut16.png +#cut32_bis.png +#cut32.png +#cutpath16.png +#cutpath24.png +#cutpath32.png +#database32.png +#defaults.png +#delete32.png +#delete_file16.png +#delete_file32.png +#deleteshape16.png +#deleteshape24.png +#deleteshape32.png +#deselect_all32.png +#disable16.png +#disable32.png +#disc32.png +#distance16.png +#distance32.png +#distance_min16.png +#distance_min32.png +#doubleside16.png +#doubleside32.png +#draw32.png +#drill16.png +#drill32.png +#dxf16.png +#edit16.png +#edit32.png +#edit_file16.png +#edit_file32.png +#edit_ok16.png +#edit_ok32_bis.png +#edit_ok32.png +#eraser26.png +#explode32.png +#export.png +#export_png32.png +#fiducials_32.png +#file16.png +#file32.png +#film16.png +#film32.png +#flatcam_icon128.png +#flatcam_icon16.png +#flatcam_icon24.png +#flatcam_icon256.png +#flatcam_icon32.png +#flatcam_icon48.png +#flipx.png +#flipy.png +#floppy16.png +#floppy32.png +#folder16.png +#folder32_bis.png +#folder32_Excellon.png +#folder32_gerber.png +#folder32.png +#fscreen32.png +#gear32.png +#gear48.png +#geometry16.png +#globe16.png +#goemetry32.png +#graylight12.png +#grid16.png +#grid32_menu.png +#grid32.png +#help.png +#home16.png +#icons.txt +#image16.png +#image32.png +#import.png +#info16.png +#intersection16.png +#intersection24.png +#intersection32.png +#italic32.png +#join16.png +#join32.png +#jump_to16.png +#jump_to32.png +#language32.png +#letter_t_32.png +#link16.png +#machine16.png +#markarea32.png +#move16.png +#move32_bis.png +#move32.png +#ncc16.png +#new_exc32.png +#new_file16.png +#new_file32.png +#new_file_exc16.png +#new_file_exc32.png +#new_file_geo16.png +#new_file_geo32.png +#new_file_grb16.png +#new_file_grb32.png +#new_geo16.png +#new_geo32_bis.png +#new_geo32.png +#notebook16.png +#notebook32.png +#notes16_1.png +#notes16.png +#offset32.png +#offsetx32.png +#offsety32.png +#open_excellon32.png +#open_script32.png +#origin16.png +#origin32.png +#origin.png +#padarray32.png +#paint16.png +#paint20_1.png +#paint20.png +#panel16.png +#panel32.png +#panelize16.png +#panelize32.png +#path32.png +#pdf32.png +#pdf_link16.png +#plot32.png +#plus16.png +#plus32.png +#pointer32.png +#pointer.png +#poligonize32.png +#polygon32.png +#power16.png +#pref.png +#printer16.png +#printer32.png +#project16.png +#project_save16.png +#project_save32.png +#properties32.png +#qrcode32.png +#recent_files.png +#rectangle32.png +#recycle16.png +#replot16.png +#replot32.png +#resize16.png +#rotate.png +#rules32.png +#save_as.png +#scale32.png +#script14.png +#script16.png +#script_new16.png +#script_new24.png +#script_open16.png +#script_open18.png +#script_open24.png +#select_all.png +#semidisc32.png +#shell16.png +#shell32.png +#shortcuts24.png +#skewX.png +#skewY.png +#slot26.png +#slot_array26.png +#snap_16.png +#solderpaste32.png +#solderpastebis32.png +#source32.png +#splash.png +#sub32.png +#subtract16.png +#subtract24.png +#subtract32.png +#svg16.png +#svg32.png +#text32.png +#toggle_units16.png +#toggle_units32.png +#track32.png +#transform.png +#trash16.png +#trash32.png +#tv16.png +#underline32.png +#union16.png +#union32.png +#videohelp24.png +#view64.png +#workspace24.png +#zoom_fit32.png +#zoom_in32.png +#zoom_out32.png + +images = $(shell find -name "*.png") + +ls: + @ echo $(images) | tr " " "\n" + +.PHONY: all + +all: $(images) + +%.png: + @ echo "\nProcessing $@ $(prefix ../,$@)" + @ convert $(addprefix ../,$@) -fuzz 20% -transparent white $@ + @ convert $@ -channel RGB -negate $@ + @ convert $@ -fuzz 10% -fill "#F3F3F3" -opaque white $@ + @ convert $@ -fuzz 10% -fill "#F3F3F3" -opaque "#f7f7f7" $@ + # # teste converte cinzas intermediarias + @ convert $@ -fuzz 10% -fill "#F3F3F3" -opaque "#000000" $@ + @ convert $@ -fuzz 10% -fill "#F3F3F3" -opaque "#040404" $@ + @ convert $@ -fuzz 10% -fill "#F3F3F3" -opaque "#212121" $@ + @ convert $@ -fuzz 10% -fill "#F3F3F3" -opaque "#262626" $@ + @ convert $@ -fuzz 10% -fill "#F3F3F3" -opaque "#3b3b3b" $@ + @ convert $@ -fuzz 10% -fill "#F3F3F3" -opaque "#3e3e3e" $@ + @ convert $@ -fuzz 10% -fill "#F3F3F3" -opaque "#4c4c4c" $@ + @ convert $@ -fuzz 10% -fill "#F3F3F3" -opaque "#505050" $@ + @ convert $@ -fuzz 10% -fill "#F3F3F3" -opaque "#555555" $@ + @ convert $@ -fuzz 10% -fill "#F3F3F3" -opaque "#575757" $@ + @ convert $@ -fuzz 10% -fill "#F3F3F3" -opaque "#919191" $@ diff --git a/share/dark_resources/black32.png b/share/dark_resources/black32.png new file mode 100644 index 0000000000000000000000000000000000000000..ff19e7adb4a0102433789276f5a234b5953bf55c GIT binary patch literal 183 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJI!_nJkO=p;(@zUFDDbdOX7UmB z`v3OFN+#}(#S+KQztEj{crnAhO>?Hbe13R(?ZrML{&ha7$(wqO8+P&8>)+qT?Xb8r z?VU5Di*TykS%)vL`{fxJcn%;V2URwuNpIq8s~3e%N^?`cwQlE=SsC($uXg<|`^mI< Xx{=~J-so Date: Wed, 15 Apr 2020 05:45:09 +0300 Subject: [PATCH 179/209] - minor optimization --- FlatCAMApp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 6740bf68..3f6aa22f 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -11976,6 +11976,7 @@ class App(QtCore.QObject): curr_len = len(cmd_name) if curr_len > max_len: max_len = curr_len + max_tabs = math.ceil(max_len / 8) for cmd_name in sorted(commands): cmd_description = commands[cmd_name]['description'] @@ -11988,7 +11989,6 @@ class App(QtCore.QObject): if curr_len == max_len: cmd_line_txt = ' %s%s%s' % (str(cmd_name), tabs, cmd_description) else: - max_tabs = math.ceil(max_len/8) nr_tabs = 0 for x in range(max_tabs): From 49fa926d5039660107a4764279750463f09ba553 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 19 Apr 2020 04:41:58 +0300 Subject: [PATCH 180/209] - fixed a bug that did not allow to edit GUI elements of type FCDoubleSpinner if it contained the percent symbol - some small optimizations in the GUI of Cutout Tool --- README.md | 5 +++++ flatcamGUI/GUIElements.py | 10 +++++++++- flatcamTools/ToolCutOut.py | 20 ++++++++++---------- flatcamTools/ToolSolderPaste.py | 4 ++-- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index f8d2641c..9cf02595 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,11 @@ CAD program, and create G-Code for Isolation routing. ================================================= +19.04.2020 + +- fixed a bug that did not allow to edit GUI elements of type FCDoubleSpinner if it contained the percent symbol +- some small optimizations in the GUI of Cutout Tool + 15.04.2020 - made sure that the Tcl commands descriptions listed on help command are aligned diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index a3560bf2..e3139318 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -726,6 +726,14 @@ class FCSpinner(QtWidgets.QSpinBox): self.readyToEdit = True self.prev_readyToEdit = True + def valueFromText(self, text: str) -> int: + txt = text.strip('%%') + try: + ret_val = int(txt) + except ValueError: + ret_val = 0 + return ret_val + def get_value(self): return int(self.value()) @@ -847,11 +855,11 @@ class FCDoubleSpinner(QtWidgets.QDoubleSpinBox): def valueFromText(self, p_str): text = p_str.replace(',', '.') + text = text.strip('%%') try: ret_val = float(text) except ValueError: ret_val = 0.0 - return ret_val def validate(self, p_str, p_int): diff --git a/flatcamTools/ToolCutOut.py b/flatcamTools/ToolCutOut.py index da366c0b..86f750fb 100644 --- a/flatcamTools/ToolCutOut.py +++ b/flatcamTools/ToolCutOut.py @@ -240,11 +240,11 @@ class CutOut(FlatCAMTool): title_param_label.setToolTip( _("This section handle creation of automatic bridge gaps.") ) - self.layout.addWidget(title_param_label) + grid0.addWidget(title_param_label, 18, 0, 1, 2) # Form Layout form_layout_2 = QtWidgets.QFormLayout() - self.layout.addLayout(form_layout_2) + grid0.addLayout(form_layout_2, 19, 0, 1, 2) # Gaps gaps_label = QtWidgets.QLabel('%s:' % _('Gaps')) @@ -260,7 +260,7 @@ class CutOut(FlatCAMTool): "- 2tb - 2*top + 2*bottom\n" "- 8 - 2*left + 2*right +2*top + 2*bottom") ) - gaps_label.setMinimumWidth(60) + # gaps_label.setMinimumWidth(60) self.gaps = FCComboBox() gaps_items = ['None', 'LR', 'TB', '4', '2LR', '2TB', '8'] @@ -282,7 +282,7 @@ class CutOut(FlatCAMTool): font-weight: bold; } """) - self.layout.addWidget(self.ff_cutout_object_btn) + grid0.addWidget(self.ff_cutout_object_btn, 20, 0, 1, 2) self.rect_cutout_object_btn = QtWidgets.QPushButton(_("Generate Rectangular Geometry")) self.rect_cutout_object_btn.setToolTip( @@ -302,7 +302,7 @@ class CutOut(FlatCAMTool): separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - self.layout.addWidget(separator_line) + grid0.addWidget(separator_line, 21, 0, 1, 2) # Title5 title_manual_label = QtWidgets.QLabel("%s" % _('B. Manual Bridge Gaps')) @@ -311,11 +311,11 @@ class CutOut(FlatCAMTool): "This is done by mouse clicking on the perimeter of the\n" "Geometry object that is used as a cutout object. ") ) - self.layout.addWidget(title_manual_label) + grid0.addWidget(title_manual_label, 22, 0, 1, 2) # Form Layout form_layout_3 = QtWidgets.QFormLayout() - self.layout.addLayout(form_layout_3) + grid0.addLayout(form_layout_3, 23, 0, 1, 2) # Manual Geo Object self.man_object_combo = FCComboBox() @@ -328,7 +328,7 @@ class CutOut(FlatCAMTool): self.man_object_label.setToolTip( _("Geometry object used to create the manual cutout.") ) - self.man_object_label.setMinimumWidth(60) + # self.man_object_label.setMinimumWidth(60) form_layout_3.addRow(self.man_object_label) form_layout_3.addRow(self.man_object_combo) @@ -348,7 +348,7 @@ class CutOut(FlatCAMTool): font-weight: bold; } """) - self.layout.addWidget(self.man_geo_creation_btn) + grid0.addWidget(self.man_geo_creation_btn, 24, 0, 1, 2) self.man_gaps_creation_btn = QtWidgets.QPushButton(_("Manual Add Bridge Gaps")) self.man_gaps_creation_btn.setToolTip( @@ -364,7 +364,7 @@ class CutOut(FlatCAMTool): font-weight: bold; } """) - self.layout.addWidget(self.man_gaps_creation_btn) + grid0.addWidget(self.man_gaps_creation_btn, 27, 0, 1, 2) self.layout.addStretch() diff --git a/flatcamTools/ToolSolderPaste.py b/flatcamTools/ToolSolderPaste.py index 3da208a0..76582402 100644 --- a/flatcamTools/ToolSolderPaste.py +++ b/flatcamTools/ToolSolderPaste.py @@ -343,8 +343,8 @@ class SolderPaste(FlatCAMTool): self.gcode_form_layout.addRow(pp_label, self.pp_combo) # ## Buttons - grid1 = QtWidgets.QGridLayout() - self.gcode_box.addLayout(grid1) + # grid1 = QtWidgets.QGridLayout() + # self.gcode_box.addLayout(grid1) self.solder_gcode_btn = QtWidgets.QPushButton(_("Generate GCode")) self.solder_gcode_btn.setToolTip( From 2dfcdc95e4b0c1f38749fbad3d166cc43f2e81c5 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 19 Apr 2020 22:22:19 +0300 Subject: [PATCH 181/209] - fixed more issues (new) in NCC Tool - added a new layout named 'minimal' --- FlatCAMApp.py | 200 ++++++----------------------- README.md | 2 + flatcamEditors/FlatCAMExcEditor.py | 2 +- flatcamEditors/FlatCAMGeoEditor.py | 2 +- flatcamEditors/FlatCAMGrbEditor.py | 2 +- flatcamGUI/FlatCAMGUI.py | 78 +++++------ flatcamGUI/PreferencesUI.py | 154 ++++++++++++++++++++++ flatcamTools/ToolNCC.py | 97 +++++++------- 8 files changed, 283 insertions(+), 254 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 3f6aa22f..1f28ca31 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -1733,7 +1733,7 @@ class App(QtCore.QObject): # ONLY AT FIRST STARTUP INIT THE GUI LAYOUT TO 'COMPACT' initial_lay = 'compact' - self.on_layout(lay=initial_lay) + self.ui.general_defaults_form.general_gui_group.on_layout(lay=initial_lay) # Set the combobox in Preferences to the current layout idx = self.ui.general_defaults_form.general_gui_group.layout_combo.findText(initial_lay) @@ -2173,8 +2173,6 @@ class App(QtCore.QObject): self.ui.general_defaults_form.general_app_set_group.workspace_cb.stateChanged.connect(self.on_workspace) - self.ui.general_defaults_form.general_gui_group.layout_combo.activated.connect(self.on_layout) - # ############################################################################# # ############################# GUI SETTINGS SIGNALS ########################## # ############################################################################# @@ -2905,6 +2903,13 @@ class App(QtCore.QObject): "Please reboot the application to update.")) self.old_defaults_found = False + # ######################################### INIT FINISHED ####################################################### + # ################################################################################################################# + # ################################################################################################################# + # ################################################################################################################# + # ################################################################################################################# + # ################################################################################################################# + @staticmethod def copy_and_overwrite(from_path, to_path): """ @@ -5097,10 +5102,11 @@ class App(QtCore.QObject): Save the toolbars visibility status to the preferences file (current_defaults.FlatConfig) to be used at the next launch of the application. - :param silent: whether to display a message in status bar or not; boolean - :param data_path: the path where to save the preferences file (current_defaults.FlatConfig) + :param silent: Whether to display a message in status bar or not; boolean + :param data_path: The path where to save the preferences file (current_defaults.FlatConfig) When the application is portable it should be a mobile location. - :return: None + :param first_time: Boolean. If True will execute some code when the app is run first time + :return: None """ self.report_usage("save_defaults") @@ -5133,6 +5139,30 @@ class App(QtCore.QObject): defaults.update(self.defaults) self.propagate_defaults(silent=True) + if first_time is False: + self.save_toolbar_view() + + # Save update options + filename = data_path + "/current_defaults.FlatConfig" + try: + f = open(filename, "w") + json.dump(defaults, f, default=to_dict, indent=2, sort_keys=True) + f.close() + except Exception as e: + log.debug("App.save_defaults() --> %s" % str(e)) + self.inform.emit('[ERROR_NOTCL] %s %s' % (_("Failed to write defaults to file."), str(filename))) + return + + if not silent: + self.inform.emit('[success] %s' % _("Preferences saved.")) + + def save_toolbar_view(self): + """ + Will save the toolbar view state to the defaults + + :return: None + """ + # Save the toolbar view tb_status = 0 if self.ui.toolbarfile.isVisible(): @@ -5162,22 +5192,7 @@ class App(QtCore.QObject): if self.ui.toolbarshell.isVisible(): tb_status += 256 - if first_time is False: - self.defaults["global_toolbar_view"] = tb_status - - # Save update options - filename = data_path + "/current_defaults.FlatConfig" - try: - f = open(filename, "w") - json.dump(defaults, f, default=to_dict, indent=2, sort_keys=True) - f.close() - except Exception as e: - log.debug("App.save_defaults() --> %s" % str(e)) - self.inform.emit('[ERROR_NOTCL] %s %s' % (_("Failed to write defaults to file."), str(filename))) - return - - if not silent: - self.inform.emit('[success] %s' % _("Preferences saved.")) + self.defaults["global_toolbar_view"] = tb_status def save_factory_defaults(self, silent_message=False, data_path=None): """ @@ -6899,147 +6914,6 @@ class App(QtCore.QObject): self.ui.general_defaults_form.general_app_set_group.workspace_cb.stateChanged.connect(self.on_workspace) self.on_workspace() - def on_layout(self, index=None, lay=None): - """ - Set the toolbars layout (location) - - :param index: - :param lay: type of layout to be set on the toolbard - :return: None - """ - self.report_usage("on_layout()") - if lay: - current_layout = lay - else: - current_layout = self.ui.general_defaults_form.general_gui_group.layout_combo.get_value() - - lay_settings = QSettings("Open Source", "FlatCAM") - lay_settings.setValue('layout', current_layout) - - # This will write the setting to the platform specific storage. - del lay_settings - - # first remove the toolbars: - try: - self.ui.removeToolBar(self.ui.toolbarfile) - self.ui.removeToolBar(self.ui.toolbargeo) - self.ui.removeToolBar(self.ui.toolbarview) - self.ui.removeToolBar(self.ui.toolbarshell) - self.ui.removeToolBar(self.ui.toolbartools) - self.ui.removeToolBar(self.ui.exc_edit_toolbar) - self.ui.removeToolBar(self.ui.geo_edit_toolbar) - self.ui.removeToolBar(self.ui.grb_edit_toolbar) - self.ui.removeToolBar(self.ui.snap_toolbar) - self.ui.removeToolBar(self.ui.toolbarshell) - except Exception: - pass - - if current_layout == 'standard': - # ## TOOLBAR INSTALLATION # ## - self.ui.toolbarfile = QtWidgets.QToolBar('File Toolbar') - self.ui.toolbarfile.setObjectName('File_TB') - self.ui.addToolBar(self.ui.toolbarfile) - - self.ui.toolbargeo = QtWidgets.QToolBar('Edit Toolbar') - self.ui.toolbargeo.setObjectName('Edit_TB') - self.ui.addToolBar(self.ui.toolbargeo) - - self.ui.toolbarview = QtWidgets.QToolBar('View Toolbar') - self.ui.toolbarview.setObjectName('View_TB') - self.ui.addToolBar(self.ui.toolbarview) - - self.ui.toolbarshell = QtWidgets.QToolBar('Shell Toolbar') - self.ui.toolbarshell.setObjectName('Shell_TB') - self.ui.addToolBar(self.ui.toolbarshell) - - self.ui.toolbartools = QtWidgets.QToolBar('Tools Toolbar') - self.ui.toolbartools.setObjectName('Tools_TB') - self.ui.addToolBar(self.ui.toolbartools) - - self.ui.exc_edit_toolbar = QtWidgets.QToolBar('Excellon Editor Toolbar') - # self.ui.exc_edit_toolbar.setVisible(False) - self.ui.exc_edit_toolbar.setObjectName('ExcEditor_TB') - self.ui.addToolBar(self.ui.exc_edit_toolbar) - - self.ui.addToolBarBreak() - - self.ui.geo_edit_toolbar = QtWidgets.QToolBar('Geometry Editor Toolbar') - # self.ui.geo_edit_toolbar.setVisible(False) - self.ui.geo_edit_toolbar.setObjectName('GeoEditor_TB') - self.ui.addToolBar(self.ui.geo_edit_toolbar) - - self.ui.grb_edit_toolbar = QtWidgets.QToolBar('Gerber Editor Toolbar') - # self.ui.grb_edit_toolbar.setVisible(False) - self.ui.grb_edit_toolbar.setObjectName('GrbEditor_TB') - self.ui.addToolBar(self.ui.grb_edit_toolbar) - - self.ui.snap_toolbar = QtWidgets.QToolBar('Grid Toolbar') - self.ui.snap_toolbar.setObjectName('Snap_TB') - # self.ui.snap_toolbar.setMaximumHeight(30) - self.ui.addToolBar(self.ui.snap_toolbar) - - self.ui.corner_snap_btn.setVisible(False) - self.ui.snap_magnet.setVisible(False) - elif current_layout == 'compact': - # ## TOOLBAR INSTALLATION # ## - self.ui.toolbarfile = QtWidgets.QToolBar('File Toolbar') - self.ui.toolbarfile.setObjectName('File_TB') - self.ui.addToolBar(Qt.LeftToolBarArea, self.ui.toolbarfile) - - self.ui.toolbargeo = QtWidgets.QToolBar('Edit Toolbar') - self.ui.toolbargeo.setObjectName('Edit_TB') - self.ui.addToolBar(Qt.LeftToolBarArea, self.ui.toolbargeo) - - self.ui.toolbarshell = QtWidgets.QToolBar('Shell Toolbar') - self.ui.toolbarshell.setObjectName('Shell_TB') - self.ui.addToolBar(Qt.LeftToolBarArea, self.ui.toolbarshell) - - self.ui.toolbartools = QtWidgets.QToolBar('Tools Toolbar') - self.ui.toolbartools.setObjectName('Tools_TB') - self.ui.addToolBar(Qt.LeftToolBarArea, self.ui.toolbartools) - - self.ui.geo_edit_toolbar = QtWidgets.QToolBar('Geometry Editor Toolbar') - # self.ui.geo_edit_toolbar.setVisible(False) - self.ui.geo_edit_toolbar.setObjectName('GeoEditor_TB') - self.ui.addToolBar(Qt.RightToolBarArea, self.ui.geo_edit_toolbar) - - self.ui.toolbarview = QtWidgets.QToolBar('View Toolbar') - self.ui.toolbarview.setObjectName('View_TB') - self.ui.addToolBar(Qt.RightToolBarArea, self.ui.toolbarview) - - self.ui.addToolBarBreak(area=Qt.RightToolBarArea) - - self.ui.grb_edit_toolbar = QtWidgets.QToolBar('Gerber Editor Toolbar') - # self.ui.grb_edit_toolbar.setVisible(False) - self.ui.grb_edit_toolbar.setObjectName('GrbEditor_TB') - self.ui.addToolBar(Qt.RightToolBarArea, self.ui.grb_edit_toolbar) - - self.ui.exc_edit_toolbar = QtWidgets.QToolBar('Excellon Editor Toolbar') - self.ui.exc_edit_toolbar.setObjectName('ExcEditor_TB') - self.ui.addToolBar(Qt.RightToolBarArea, self.ui.exc_edit_toolbar) - - self.ui.snap_toolbar = QtWidgets.QToolBar('Grid Toolbar') - self.ui.snap_toolbar.setObjectName('Snap_TB') - self.ui.snap_toolbar.setMaximumHeight(30) - self.ui.splitter_left.addWidget(self.ui.snap_toolbar) - - self.ui.corner_snap_btn.setVisible(True) - self.ui.snap_magnet.setVisible(True) - - # add all the actions to the toolbars - self.ui.populate_toolbars() - - # reconnect all the signals to the toolbar actions - self.connect_toolbar_signals() - - self.ui.grid_snap_btn.setChecked(True) - self.on_grid_snap_triggered(state=True) - - self.ui.grid_gap_x_entry.setText(str(self.defaults["global_gridx"])) - self.ui.grid_gap_y_entry.setText(str(self.defaults["global_gridy"])) - self.ui.snap_max_dist_entry.setText(str(self.defaults["global_snap_max"])) - self.ui.grid_gap_link_cb.setChecked(True) - def on_cursor_type(self, val): """ diff --git a/README.md b/README.md index 9cf02595..b78eec30 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ CAD program, and create G-Code for Isolation routing. - fixed a bug that did not allow to edit GUI elements of type FCDoubleSpinner if it contained the percent symbol - some small optimizations in the GUI of Cutout Tool +- fixed more issues (new) in NCC Tool +- added a new layout named 'minimal' 15.04.2020 diff --git a/flatcamEditors/FlatCAMExcEditor.py b/flatcamEditors/FlatCAMExcEditor.py index 65f9e497..02afac5c 100644 --- a/flatcamEditors/FlatCAMExcEditor.py +++ b/flatcamEditors/FlatCAMExcEditor.py @@ -2884,7 +2884,7 @@ class FlatCAMExcEditor(QtCore.QObject): self.app.ui.corner_snap_btn.setEnabled(False) self.app.ui.snap_magnet.setVisible(False) self.app.ui.corner_snap_btn.setVisible(False) - elif layout == 'compact': + else: # self.app.ui.exc_edit_toolbar.setVisible(True) self.app.ui.snap_max_dist_entry.setEnabled(False) diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index 74dd0892..b15d4b6a 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -3612,7 +3612,7 @@ class FlatCAMGeoEditor(QtCore.QObject): self.app.ui.corner_snap_btn.setEnabled(False) self.app.ui.snap_magnet.setVisible(False) self.app.ui.corner_snap_btn.setVisible(False) - elif layout == 'compact': + else: # self.app.ui.geo_edit_toolbar.setVisible(True) self.app.ui.snap_max_dist_entry.setEnabled(False) diff --git a/flatcamEditors/FlatCAMGrbEditor.py b/flatcamEditors/FlatCAMGrbEditor.py index f72f7c39..1d797d34 100644 --- a/flatcamEditors/FlatCAMGrbEditor.py +++ b/flatcamEditors/FlatCAMGrbEditor.py @@ -3626,7 +3626,7 @@ class FlatCAMGrbEditor(QtCore.QObject): self.app.ui.corner_snap_btn.setEnabled(False) self.app.ui.snap_magnet.setVisible(False) self.app.ui.corner_snap_btn.setVisible(False) - elif layout == 'compact': + else: # self.app.ui.exc_edit_toolbar.setVisible(True) self.app.ui.snap_max_dist_entry.setEnabled(False) diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index 0401b164..89c13eca 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -798,9 +798,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): settings = QSettings("Open Source", "FlatCAM") if settings.contains("layout"): layout = settings.value('layout', type=str) - if layout == 'standard': - pass - elif layout == 'compact': + if layout == 'compact': self.removeToolBar(self.snap_toolbar) self.snap_toolbar.setMaximumHeight(30) self.splitter_left.addWidget(self.snap_toolbar) @@ -2347,41 +2345,34 @@ class FlatCAMGUI(QtWidgets.QMainWindow): QtWidgets.qApp.installEventFilter(self) - # restore the Toolbar State from file + # ######################################################################## + # ################## RESTORE THE TOOLBAR STATE from file ################# + # ######################################################################## + settings = QSettings("Open Source", "FlatCAM") if settings.contains("saved_gui_state"): saved_gui_state = settings.value('saved_gui_state') self.restoreState(saved_gui_state) - log.debug("FlatCAMGUI.__init__() --> UI state restored.") + log.debug("FlatCAMGUI.__init__() --> UI state restored from QSettings.") if settings.contains("layout"): layout = settings.value('layout', type=str) - if layout == 'standard': - # self.exc_edit_toolbar.setVisible(False) - self.exc_edit_toolbar.setDisabled(True) - # self.geo_edit_toolbar.setVisible(False) - self.geo_edit_toolbar.setDisabled(True) - # self.grb_edit_toolbar.setVisible(False) - self.grb_edit_toolbar.setDisabled(True) + self.exc_edit_toolbar.setDisabled(True) + self.geo_edit_toolbar.setDisabled(True) + self.grb_edit_toolbar.setDisabled(True) + if layout == 'standard': self.corner_snap_btn.setVisible(False) self.snap_magnet.setVisible(False) - elif layout == 'compact': - self.exc_edit_toolbar.setDisabled(True) - self.geo_edit_toolbar.setDisabled(True) - self.grb_edit_toolbar.setDisabled(True) - + else: self.snap_magnet.setVisible(True) self.corner_snap_btn.setVisible(True) self.snap_magnet.setDisabled(True) self.corner_snap_btn.setDisabled(True) - log.debug("FlatCAMGUI.__init__() --> UI layout restored from QSettings.") + log.debug("FlatCAMGUI.__init__() --> UI layout restored from QSettings. Layout = %s" % str(layout)) else: - # self.exc_edit_toolbar.setVisible(False) self.exc_edit_toolbar.setDisabled(True) - # self.geo_edit_toolbar.setVisible(False) self.geo_edit_toolbar.setDisabled(True) - # self.grb_edit_toolbar.setVisible(False) self.grb_edit_toolbar.setDisabled(True) self.corner_snap_btn.setVisible(False) @@ -2483,11 +2474,14 @@ class FlatCAMGUI(QtWidgets.QMainWindow): def populate_toolbars(self): """ - Will populate the App Toolbars with theie actions + Will populate the App Toolbars with their actions + :return: None """ + # ######################################################################## # ## File Toolbar # ## + # ######################################################################## self.file_open_gerber_btn = self.toolbarfile.addAction( QtGui.QIcon(self.app.resource_location + '/flatcam_icon32.png'), _("Open Gerber")) self.file_open_excellon_btn = self.toolbarfile.addAction( @@ -2498,7 +2492,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.file_save_btn = self.toolbarfile.addAction( QtGui.QIcon(self.app.resource_location + '/project_save32.png'), _("Save project")) + # ######################################################################## # ## Edit Toolbar # ## + # ######################################################################## self.newgeo_btn = self.toolbargeo.addAction( QtGui.QIcon(self.app.resource_location + '/new_file_geo32.png'), _("New Blank Geometry")) self.newgrb_btn = self.toolbargeo.addAction( @@ -2556,7 +2552,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.run_script_btn = self.toolbarshell.addAction( QtGui.QIcon(self.app.resource_location + '/script16.png'), _('Run Script ...')) + # ######################################################################## # ## Tools Toolbar # ## + # ######################################################################## self.dblsided_btn = self.toolbartools.addAction( QtGui.QIcon(self.app.resource_location + '/doubleside32.png'), _("2Sided Tool")) self.align_btn = self.toolbartools.addAction( @@ -2601,7 +2599,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.cal_btn = self.toolbartools.addAction( QtGui.QIcon(self.app.resource_location + '/calibrate_32.png'), _("Calibration Tool")) + # ######################################################################## # ## Excellon Editor Toolbar # ## + # ######################################################################## self.select_drill_btn = self.exc_edit_toolbar.addAction( QtGui.QIcon(self.app.resource_location + '/pointer32.png'), _("Select")) self.add_drill_btn = self.exc_edit_toolbar.addAction( @@ -2625,7 +2625,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.move_drill_btn = self.exc_edit_toolbar.addAction( QtGui.QIcon(self.app.resource_location + '/move32.png'), _("Move Drill")) + # ######################################################################## # ## Geometry Editor Toolbar # ## + # ######################################################################## self.geo_select_btn = self.geo_edit_toolbar.addAction( QtGui.QIcon(self.app.resource_location + '/pointer32.png'), _("Select 'Esc'")) self.geo_add_circle_btn = self.geo_edit_toolbar.addAction( @@ -2675,7 +2677,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.geo_move_btn = self.geo_edit_toolbar.addAction( QtGui.QIcon(self.app.resource_location + '/move32.png'), _("Move Objects")) + # ######################################################################## # ## Gerber Editor Toolbar # ## + # ######################################################################## self.grb_select_btn = self.grb_edit_toolbar.addAction( QtGui.QIcon(self.app.resource_location + '/pointer32.png'), _("Select")) self.grb_add_pad_btn = self.grb_edit_toolbar.addAction( @@ -2715,10 +2719,12 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.aperture_move_btn = self.grb_edit_toolbar.addAction( QtGui.QIcon(self.app.resource_location + '/move32.png'), _("Move")) + # ######################################################################## # ## Snap Toolbar # ## + # ######################################################################## + # Snap GRID toolbar is always active to facilitate usage of measurements done on GRID # self.addToolBar(self.snap_toolbar) - self.grid_snap_btn = self.snap_toolbar.addAction( QtGui.QIcon(self.app.resource_location + '/grid32.png'), _('Snap to grid')) self.grid_gap_x_entry = FCEntry2() @@ -2757,29 +2763,25 @@ class FlatCAMGUI(QtWidgets.QMainWindow): settings = QSettings("Open Source", "FlatCAM") if settings.contains("layout"): layout = settings.value('layout', type=str) - if layout == 'standard': - self.exc_edit_toolbar.setVisible(True) - self.exc_edit_toolbar.setDisabled(True) - self.geo_edit_toolbar.setVisible(True) - self.geo_edit_toolbar.setDisabled(True) - self.grb_edit_toolbar.setVisible(True) - self.grb_edit_toolbar.setDisabled(True) + if layout == 'standard': self.corner_snap_btn.setVisible(False) self.snap_magnet.setVisible(False) - elif layout == 'compact': - self.exc_edit_toolbar.setVisible(True) - self.exc_edit_toolbar.setDisabled(True) - self.geo_edit_toolbar.setVisible(True) - self.geo_edit_toolbar.setDisabled(True) - self.grb_edit_toolbar.setVisible(True) - self.grb_edit_toolbar.setDisabled(True) - + else: self.corner_snap_btn.setVisible(True) self.snap_magnet.setVisible(True) self.corner_snap_btn.setDisabled(True) self.snap_magnet.setDisabled(True) + # on 'minimal' layout only some toolbars are active + if layout != 'minimal': + self.exc_edit_toolbar.setVisible(True) + self.exc_edit_toolbar.setDisabled(True) + self.geo_edit_toolbar.setVisible(True) + self.geo_edit_toolbar.setDisabled(True) + self.grb_edit_toolbar.setVisible(True) + self.grb_edit_toolbar.setDisabled(True) + def keyPressEvent(self, event): """ Key event handler for the entire app. diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index 33661845..d8659eeb 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -396,6 +396,7 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI): # don't translate the QCombo items as they are used in QSettings and identified by name self.layout_combo.addItem("standard") self.layout_combo.addItem("compact") + self.layout_combo.addItem("minimal") grid0.addWidget(self.layout_label, 4, 0) grid0.addWidget(self.layout_combo, 4, 1) @@ -732,6 +733,9 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI): self.proj_color_dis_entry.editingFinished.connect(self.on_proj_color_dis_entry) self.proj_color_dis_button.clicked.connect(self.on_proj_color_dis_button) + self.layout_combo.activated.connect(self.on_layout) + + def on_theme_change(self): val = self.theme_radio.get_value() t_settings = QSettings("Open Source", "FlatCAM") @@ -947,6 +951,156 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI): self.proj_color_dis_entry.set_value(new_val_sel) self.app.defaults['global_proj_item_dis_color'] = new_val_sel + def on_layout(self, index=None, lay=None): + """ + Set the toolbars layout (location) + + :param index: + :param lay: Type of layout to be set on the toolbard + :return: None + """ + self.app.report_usage("on_layout()") + if lay: + current_layout = lay + else: + current_layout = self.layout_combo.get_value() + + lay_settings = QSettings("Open Source", "FlatCAM") + lay_settings.setValue('layout', current_layout) + + # This will write the setting to the platform specific storage. + del lay_settings + + # first remove the toolbars: + try: + self.app.ui.removeToolBar(self.app.ui.toolbarfile) + self.app.ui.removeToolBar(self.app.ui.toolbargeo) + self.app.ui.removeToolBar(self.app.ui.toolbarview) + self.app.ui.removeToolBar(self.app.ui.toolbarshell) + self.app.ui.removeToolBar(self.app.ui.toolbartools) + self.app.ui.removeToolBar(self.app.ui.exc_edit_toolbar) + self.app.ui.removeToolBar(self.app.ui.geo_edit_toolbar) + self.app.ui.removeToolBar(self.app.ui.grb_edit_toolbar) + self.app.ui.removeToolBar(self.app.ui.snap_toolbar) + self.app.ui.removeToolBar(self.app.ui.toolbarshell) + except Exception: + pass + + if current_layout == 'compact': + # ## TOOLBAR INSTALLATION # ## + self.app.ui.toolbarfile = QtWidgets.QToolBar('File Toolbar') + self.app.ui.toolbarfile.setObjectName('File_TB') + self.app.ui.addToolBar(Qt.LeftToolBarArea, self.app.ui.toolbarfile) + + self.app.ui.toolbargeo = QtWidgets.QToolBar('Edit Toolbar') + self.app.ui.toolbargeo.setObjectName('Edit_TB') + self.app.ui.addToolBar(Qt.LeftToolBarArea, self.app.ui.toolbargeo) + + self.app.ui.toolbarshell = QtWidgets.QToolBar('Shell Toolbar') + self.app.ui.toolbarshell.setObjectName('Shell_TB') + self.app.ui.addToolBar(Qt.LeftToolBarArea, self.app.ui.toolbarshell) + + self.app.ui.toolbartools = QtWidgets.QToolBar('Tools Toolbar') + self.app.ui.toolbartools.setObjectName('Tools_TB') + self.app.ui.addToolBar(Qt.LeftToolBarArea, self.app.ui.toolbartools) + + self.app.ui.geo_edit_toolbar = QtWidgets.QToolBar('Geometry Editor Toolbar') + # self.app.ui.geo_edit_toolbar.setVisible(False) + self.app.ui.geo_edit_toolbar.setObjectName('GeoEditor_TB') + self.app.ui.addToolBar(Qt.RightToolBarArea, self.app.ui.geo_edit_toolbar) + + self.app.ui.toolbarview = QtWidgets.QToolBar('View Toolbar') + self.app.ui.toolbarview.setObjectName('View_TB') + self.app.ui.addToolBar(Qt.RightToolBarArea, self.app.ui.toolbarview) + + self.app.ui.addToolBarBreak(area=Qt.RightToolBarArea) + + self.app.ui.grb_edit_toolbar = QtWidgets.QToolBar('Gerber Editor Toolbar') + # self.app.ui.grb_edit_toolbar.setVisible(False) + self.app.ui.grb_edit_toolbar.setObjectName('GrbEditor_TB') + self.app.ui.addToolBar(Qt.RightToolBarArea, self.app.ui.grb_edit_toolbar) + + self.app.ui.exc_edit_toolbar = QtWidgets.QToolBar('Excellon Editor Toolbar') + self.app.ui.exc_edit_toolbar.setObjectName('ExcEditor_TB') + self.app.ui.addToolBar(Qt.RightToolBarArea, self.app.ui.exc_edit_toolbar) + + self.app.ui.snap_toolbar = QtWidgets.QToolBar('Grid Toolbar') + self.app.ui.snap_toolbar.setObjectName('Snap_TB') + self.app.ui.snap_toolbar.setMaximumHeight(30) + self.app.ui.splitter_left.addWidget(self.app.ui.snap_toolbar) + + self.app.ui.corner_snap_btn.setVisible(True) + self.app.ui.snap_magnet.setVisible(True) + else: + # ## TOOLBAR INSTALLATION # ## + self.app.ui.toolbarfile = QtWidgets.QToolBar('File Toolbar') + self.app.ui.toolbarfile.setObjectName('File_TB') + self.app.ui.addToolBar(self.app.ui.toolbarfile) + + self.app.ui.toolbargeo = QtWidgets.QToolBar('Edit Toolbar') + self.app.ui.toolbargeo.setObjectName('Edit_TB') + self.app.ui.addToolBar(self.app.ui.toolbargeo) + + self.app.ui.toolbarview = QtWidgets.QToolBar('View Toolbar') + self.app.ui.toolbarview.setObjectName('View_TB') + self.app.ui.addToolBar(self.app.ui.toolbarview) + + self.app.ui.toolbarshell = QtWidgets.QToolBar('Shell Toolbar') + self.app.ui.toolbarshell.setObjectName('Shell_TB') + self.app.ui.addToolBar(self.app.ui.toolbarshell) + + self.app.ui.toolbartools = QtWidgets.QToolBar('Tools Toolbar') + self.app.ui.toolbartools.setObjectName('Tools_TB') + self.app.ui.addToolBar(self.app.ui.toolbartools) + + self.app.ui.exc_edit_toolbar = QtWidgets.QToolBar('Excellon Editor Toolbar') + # self.app.ui.exc_edit_toolbar.setVisible(False) + self.app.ui.exc_edit_toolbar.setObjectName('ExcEditor_TB') + self.app.ui.addToolBar(self.app.ui.exc_edit_toolbar) + + self.app.ui.addToolBarBreak() + + self.app.ui.geo_edit_toolbar = QtWidgets.QToolBar('Geometry Editor Toolbar') + # self.app.ui.geo_edit_toolbar.setVisible(False) + self.app.ui.geo_edit_toolbar.setObjectName('GeoEditor_TB') + self.app.ui.addToolBar(self.app.ui.geo_edit_toolbar) + + self.app.ui.grb_edit_toolbar = QtWidgets.QToolBar('Gerber Editor Toolbar') + # self.app.ui.grb_edit_toolbar.setVisible(False) + self.app.ui.grb_edit_toolbar.setObjectName('GrbEditor_TB') + self.app.ui.addToolBar(self.app.ui.grb_edit_toolbar) + + self.app.ui.snap_toolbar = QtWidgets.QToolBar('Grid Toolbar') + self.app.ui.snap_toolbar.setObjectName('Snap_TB') + # self.app.ui.snap_toolbar.setMaximumHeight(30) + self.app.ui.addToolBar(self.app.ui.snap_toolbar) + + self.app.ui.corner_snap_btn.setVisible(False) + self.app.ui.snap_magnet.setVisible(False) + + if current_layout == 'minimal': + self.app.ui.toolbarview.setVisible(False) + self.app.ui.toolbarshell.setVisible(False) + self.app.ui.snap_toolbar.setVisible(False) + self.app.ui.geo_edit_toolbar.setVisible(False) + self.app.ui.grb_edit_toolbar.setVisible(False) + self.app.ui.exc_edit_toolbar.setVisible(False) + self.app.ui.lock_toolbar(lock=True) + + # add all the actions to the toolbars + self.app.ui.populate_toolbars() + + # reconnect all the signals to the toolbar actions + self.app.connect_toolbar_signals() + + self.app.ui.grid_snap_btn.setChecked(True) + self.app.on_grid_snap_triggered(state=True) + + self.app.ui.grid_gap_x_entry.setText(str(self.app.defaults["global_gridx"])) + self.app.ui.grid_gap_y_entry.setText(str(self.app.defaults["global_gridy"])) + self.app.ui.snap_max_dist_entry.setText(str(self.app.defaults["global_snap_max"])) + self.app.ui.grid_gap_link_cb.setChecked(True) + class GeneralAPPSetGroupUI(OptionsGroupUI): def __init__(self, decimals=4, parent=None): diff --git a/flatcamTools/ToolNCC.py b/flatcamTools/ToolNCC.py index 8fcaedf2..7b44ebdf 100644 --- a/flatcamTools/ToolNCC.py +++ b/flatcamTools/ToolNCC.py @@ -875,12 +875,12 @@ class NonCopperClear(FlatCAMTool, Gerber): # store all the data associated with the row parameter to the self.tools storage - tooldia_item = float(self.tools_table.item(row, 1).text()) - type_item = self.tools_table.cellWidget(row, 2).currentText() - operation_type_item = self.ui.geo_tools_table.cellWidget(row, 4).currentText() - - nccoffset_item = self.ncc_choice_offset_cb.get_value() - nccoffset_value_item = float(self.ncc_offset_spinner.get_value()) + # tooldia_item = float(self.tools_table.item(row, 1).text()) + # type_item = self.tools_table.cellWidget(row, 2).currentText() + # operation_type_item = self.tools_table.cellWidget(row, 4).currentText() + # + # nccoffset_item = self.ncc_choice_offset_cb.get_value() + # nccoffset_value_item = float(self.ncc_offset_spinner.get_value()) # this new dict will hold the actual useful data, another dict that is the value of key 'data' # temp_tools = {} @@ -1202,11 +1202,6 @@ class NonCopperClear(FlatCAMTool, Gerber): except AttributeError: pass - try: - self.tools_table.cellWidget(row, 4).currentIndexChanged.connect(self.on_tooltable_cellwidget_change) - except AttributeError: - pass - self.tool_type_radio.activated_custom.connect(self.on_tool_type) for opt in self.form_fields: @@ -1238,11 +1233,11 @@ class NonCopperClear(FlatCAMTool, Gerber): pass for row in range(self.tools_table.rowCount()): - for col in [2, 4]: - try: - self.ui.geo_tools_table.cellWidget(row, col).currentIndexChanged.disconnect() - except (TypeError, AttributeError): - pass + + try: + self.tools_table.cellWidget(row, 2).currentIndexChanged.disconnect() + except (TypeError, AttributeError): + pass for opt in self.form_fields: current_widget = self.form_fields[opt] @@ -1669,7 +1664,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.mm = self.app.plotcanvas.graph_event_connect('mouse_move', self.on_mouse_move) self.kp = self.app.plotcanvas.graph_event_connect('key_press', self.on_key_press) - elif self.select_method == 'box': + elif self.select_method == _("Reference Object"): self.bound_obj_name = self.reference_combo.currentText() # Get source object. try: @@ -2221,6 +2216,8 @@ class NonCopperClear(FlatCAMTool, Gerber): run non-threaded for TclShell usage :return: """ + log.debug("Executing the handler ...") + if run_threaded: proc = self.app.proc_container.new(_("Non-Copper clearing ...")) else: @@ -2306,7 +2303,7 @@ class NonCopperClear(FlatCAMTool, Gerber): except TypeError: tool = eval(self.app.defaults["tools_ncctools"]) - if ncc_select == 'box': + if ncc_select == _("Reference Object"): env_obj, box_obj_kind = self.envelope_object(ncc_obj=ncc_obj, box_obj=sel_obj, ncc_select=ncc_select) else: env_obj, box_obj_kind = self.envelope_object(ncc_obj=ncc_obj, ncc_select=ncc_select) @@ -2330,19 +2327,19 @@ class NonCopperClear(FlatCAMTool, Gerber): ) app_obj.proc_container.update_view_text(' %d%%' % 0) - tooluid = 0 + tool_uid = 0 for k, v in self.ncc_tools.items(): if float('%.*f' % (self.decimals, v['tooldia'])) == float('%.*f' % (self.decimals, tool)): - tooluid = int(k) + tool_uid = int(k) break - ncc_overlap = float(self.ncc_tools[tooluid]["data"]["tools_nccoverlap"]) / 100.0 - ncc_margin = float(self.ncc_tools[tooluid]["data"]["tools_nccmargin"]) - ncc_method = self.ncc_tools[tooluid]["data"]["tools_nccmethod"] - ncc_connect = self.ncc_tools[tooluid]["data"]["tools_nccconnect"] - ncc_contour = self.ncc_tools[tooluid]["data"]["tools_ncccontour"] - has_offset = self.ncc_tools[tooluid]["data"]["tools_ncc_offset_choice"] - ncc_offset = float(self.ncc_tools[tooluid]["data"]["tools_ncc_offset_value"]) + ncc_overlap = float(self.ncc_tools[tool_uid]["data"]["tools_nccoverlap"]) / 100.0 + ncc_margin = float(self.ncc_tools[tool_uid]["data"]["tools_nccmargin"]) + ncc_method = self.ncc_tools[tool_uid]["data"]["tools_nccmethod"] + ncc_connect = self.ncc_tools[tool_uid]["data"]["tools_nccconnect"] + ncc_contour = self.ncc_tools[tool_uid]["data"]["tools_ncccontour"] + has_offset = self.ncc_tools[tool_uid]["data"]["tools_ncc_offset_choice"] + ncc_offset = float(self.ncc_tools[tool_uid]["data"]["tools_ncc_offset_value"]) cleared_geo[:] = [] @@ -2513,8 +2510,8 @@ class NonCopperClear(FlatCAMTool, Gerber): # test if at least one tool has solid_geometry. If no tool has solid_geometry we raise an Exception has_solid_geo = 0 - for tooluid in geo_obj.tools: - if geo_obj.tools[tooluid]['solid_geometry']: + for tid in geo_obj.tools: + if geo_obj.tools[tid]['solid_geometry']: has_solid_geo += 1 if has_solid_geo == 0: app_obj.inform.emit('[ERROR] %s' % @@ -2537,13 +2534,13 @@ class NonCopperClear(FlatCAMTool, Gerber): # create the solid_geometry geo_obj.solid_geometry = [] - for tooluid in geo_obj.tools: - if geo_obj.tools[tooluid]['solid_geometry']: + for tool_id in geo_obj.tools: + if geo_obj.tools[tool_id]['solid_geometry']: try: - for geo in geo_obj.tools[tooluid]['solid_geometry']: + for geo in geo_obj.tools[tool_id]['solid_geometry']: geo_obj.solid_geometry.append(geo) except TypeError: - geo_obj.solid_geometry.append(geo_obj.tools[tooluid]['solid_geometry']) + geo_obj.solid_geometry.append(geo_obj.tools[tool_id]['solid_geometry']) else: # I will use this variable for this purpose although it was meant for something else # signal that we have no geo in the object therefore don't create it @@ -2586,7 +2583,7 @@ class NonCopperClear(FlatCAMTool, Gerber): # repurposed flag for final object, geo_obj. True if it has any solid_geometry, False if not. app_obj.poly_not_cleared = True - if ncc_select == 'box': + if ncc_select == _("Reference Object"): env_obj, box_obj_kind = self.envelope_object(ncc_obj=ncc_obj, box_obj=sel_obj, ncc_select=ncc_select) else: env_obj, box_obj_kind = self.envelope_object(ncc_obj=ncc_obj, ncc_select=ncc_select) @@ -2615,19 +2612,19 @@ class NonCopperClear(FlatCAMTool, Gerber): tool = sorted_tools.pop(0) - tooluid = 0 + tool_uid = 0 for k, v in self.ncc_tools.items(): if float('%.*f' % (self.decimals, v['tooldia'])) == float('%.*f' % (self.decimals, tool)): - tooluid = int(k) + tool_uid = int(k) break - ncc_overlap = float(self.ncc_tools[tooluid]["data"]["tools_nccoverlap"]) / 100.0 - ncc_margin = float(self.ncc_tools[tooluid]["data"]["tools_nccmargin"]) - ncc_method = self.ncc_tools[tooluid]["data"]["tools_nccmethod"] - ncc_connect = self.ncc_tools[tooluid]["data"]["tools_nccconnect"] - ncc_contour = self.ncc_tools[tooluid]["data"]["tools_ncccontour"] - has_offset = self.ncc_tools[tooluid]["data"]["tools_ncc_offset_choice"] - ncc_offset = float(self.ncc_tools[tooluid]["data"]["tools_ncc_offset_value"]) + ncc_overlap = float(self.ncc_tools[tool_uid]["data"]["tools_nccoverlap"]) / 100.0 + ncc_margin = float(self.ncc_tools[tool_uid]["data"]["tools_nccmargin"]) + ncc_method = self.ncc_tools[tool_uid]["data"]["tools_nccmethod"] + ncc_connect = self.ncc_tools[tool_uid]["data"]["tools_nccconnect"] + ncc_contour = self.ncc_tools[tool_uid]["data"]["tools_ncccontour"] + has_offset = self.ncc_tools[tool_uid]["data"]["tools_ncc_offset_choice"] + ncc_offset = float(self.ncc_tools[tool_uid]["data"]["tools_ncc_offset_value"]) tool_used = tool - 1e-12 cleared_geo[:] = [] @@ -2784,7 +2781,7 @@ class NonCopperClear(FlatCAMTool, Gerber): poly = p.buffer(buffer_value) cleared_by_last_tool.append(poly) - # find the tooluid associated with the current tool_dia so we know + # find the tool uid associated with the current tool_dia so we know # where to add the tool solid_geometry for k, v in tools_storage.items(): if float('%.*f' % (self.decimals, v['tooldia'])) == float('%.*f' % (self.decimals, @@ -2822,13 +2819,13 @@ class NonCopperClear(FlatCAMTool, Gerber): # create the solid_geometry geo_obj.solid_geometry = [] - for tooluid in geo_obj.tools: - if geo_obj.tools[tooluid]['solid_geometry']: + for tool_uid in geo_obj.tools: + if geo_obj.tools[tool_uid]['solid_geometry']: try: - for geo in geo_obj.tools[tooluid]['solid_geometry']: + for geo in geo_obj.tools[tool_uid]['solid_geometry']: geo_obj.solid_geometry.append(geo) except TypeError: - geo_obj.solid_geometry.append(geo_obj.tools[tooluid]['solid_geometry']) + geo_obj.solid_geometry.append(geo_obj.tools[tool_uid]['solid_geometry']) else: # I will use this variable for this purpose although it was meant for something else # signal that we have no geo in the object therefore don't create it @@ -3012,13 +3009,13 @@ class NonCopperClear(FlatCAMTool, Gerber): bounding_box = cascaded_union(geo_buff_list) - elif ncc_select == 'box': + elif ncc_select == _("Reference Object"): geo_n = ncc_sel_obj.solid_geometry if ncc_sel_obj.kind == 'geometry': try: __ = iter(geo_n) except Exception as e: - log.debug("NonCopperClear.clear_copper() 'box' --> %s" % str(e)) + log.debug("NonCopperClear.clear_copper() 'Reference Object' --> %s" % str(e)) geo_n = [geo_n] geo_buff_list = [] From 5a5a18ef439c6cbbf59fcf8dd804e5c223372c62 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 20 Apr 2020 00:12:58 +0300 Subject: [PATCH 182/209] - some PEP8 changes in Geometry Editor and other minor changes --- FlatCAMApp.py | 4 +- README.md | 1 + camlib.py | 3 + flatcamEditors/FlatCAMGeoEditor.py | 275 +++++++++++++++++++++-------- flatcamGUI/FlatCAMGUI.py | 43 +++-- 5 files changed, 224 insertions(+), 102 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 1f28ca31..c176ab56 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -2788,7 +2788,7 @@ class App(QtCore.QObject): # watch out for the position of the editors instantiation ... if it is done before a save of the default values # at the first launch of the App , the editors will not be functional. try: - self.geo_editor = FlatCAMGeoEditor(self, disabled=True) + self.geo_editor = FlatCAMGeoEditor(self) except AttributeError: pass @@ -9350,7 +9350,7 @@ class App(QtCore.QObject): if self.call_source != 'app': self.editor2object(cleanup=True) # ## EDITOR section - self.geo_editor = FlatCAMGeoEditor(self, disabled=True) + self.geo_editor = FlatCAMGeoEditor(self) self.exc_editor = FlatCAMExcEditor(self) self.grb_editor = FlatCAMGrbEditor(self) diff --git a/README.md b/README.md index b78eec30..6fb305b0 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ CAD program, and create G-Code for Isolation routing. - some small optimizations in the GUI of Cutout Tool - fixed more issues (new) in NCC Tool - added a new layout named 'minimal' +- some PEP8 changes in Geometry Editor 15.04.2020 diff --git a/camlib.py b/camlib.py index 40d84cc0..44ba0106 100644 --- a/camlib.py +++ b/camlib.py @@ -467,6 +467,9 @@ class Geometry(object): self.units = self.app.defaults["units"] self.decimals = self.app.decimals + self.drawing_tolerance = 0.0 + self.tools = None + # Final geometry: MultiPolygon or list (of geometry constructs) self.solid_geometry = None diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index b15d4b6a..cdea92b5 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -1052,9 +1052,8 @@ class TransformEditorTool(FlatCAMTool): self.flip_ref_entry.set_value((0, 0)) def template(self): - if not self.fcdraw.selected: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Transformation cancelled. No shape selected.")) + if not self.draw_app.selected: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Transformation cancelled. No shape selected.")) return self.draw_app.select_tool("select") @@ -1098,6 +1097,14 @@ class TransformEditorTool(FlatCAMTool): self.flip_ref_entry.set_value(val) def on_skewx(self, sig=None, val=None): + """ + Skew on X axis + + :param sig: Signal value sent by the signal that is connected to this slot + :param val: Skew with a known value, val + :return: + """ + if val: value = val else: @@ -1108,8 +1115,7 @@ class TransformEditorTool(FlatCAMTool): try: value = float(self.skewx_entry.get_value().replace(',', '.')) except ValueError: - self.app.inform.emit('[ERROR_NOTCL] %s' % - _("Wrong value format entered, use a number.")) + self.app.inform.emit('[ERROR_NOTCL] %s' % _("Wrong value format entered, use a number.")) return # self.on_skew("X", value) @@ -1119,6 +1125,14 @@ class TransformEditorTool(FlatCAMTool): return def on_skewy(self, sig=None, val=None): + """ + Skew on Y axis + + :param sig: Signal value sent by the signal that is connected to this slot + :param val: Skew with a known value, val + :return: + """ + if val: value = val else: @@ -1129,8 +1143,7 @@ class TransformEditorTool(FlatCAMTool): try: value = float(self.skewy_entry.get_value().replace(',', '.')) except ValueError: - self.app.inform.emit('[ERROR_NOTCL] %s' % - _("Wrong value format entered, use a number.")) + self.app.inform.emit('[ERROR_NOTCL] %s' % _("Wrong value format entered, use a number.")) return # self.on_skew("Y", value) @@ -1140,6 +1153,14 @@ class TransformEditorTool(FlatCAMTool): return def on_scalex(self, sig=None, val=None): + """ + Scale on X axis + + :param sig: Signal value sent by the signal that is connected to this slot + :param val: Scale with a known value, val + :return: + """ + if val: xvalue = val else: @@ -1150,8 +1171,7 @@ class TransformEditorTool(FlatCAMTool): try: xvalue = float(self.scalex_entry.get_value().replace(',', '.')) except ValueError: - self.app.inform.emit('[ERROR_NOTCL] %s' % - _("Wrong value format entered, use a number.")) + self.app.inform.emit('[ERROR_NOTCL] %s' % _("Wrong value format entered, use a number.")) return # scaling to zero has no sense so we remove it, because scaling with 1 does nothing @@ -1176,6 +1196,14 @@ class TransformEditorTool(FlatCAMTool): return def on_scaley(self, sig=None, val=None): + """ + Scale on Y axis + + :param sig: Signal value sent by the signal that is connected to this slot + :param val: Scale with a known value, val + :return: + """ + xvalue = 1 if val: yvalue = val @@ -1187,8 +1215,7 @@ class TransformEditorTool(FlatCAMTool): try: yvalue = float(self.scaley_entry.get_value().replace(',', '.')) except ValueError: - self.app.inform.emit('[ERROR_NOTCL] %s' % - _("Wrong value format entered, use a number.")) + self.app.inform.emit('[ERROR_NOTCL] %s' % _("Wrong value format entered, use a number.")) return # scaling to zero has no sense so we remove it, because scaling with 1 does nothing @@ -1205,6 +1232,14 @@ class TransformEditorTool(FlatCAMTool): return def on_offx(self, sig=None, val=None): + """ + Offset on X axis + + :param sig: Signal value sent by the signal that is connected to this slot + :param val: Offset with a known value, val + :return: + """ + if val: value = val else: @@ -1215,8 +1250,7 @@ class TransformEditorTool(FlatCAMTool): try: value = float(self.offx_entry.get_value().replace(',', '.')) except ValueError: - self.app.inform.emit('[ERROR_NOTCL] %s' % - _("Wrong value format entered, use a number.")) + self.app.inform.emit('[ERROR_NOTCL] %s' % _("Wrong value format entered, use a number.")) return # self.on_offset("X", value) @@ -1226,6 +1260,14 @@ class TransformEditorTool(FlatCAMTool): return def on_offy(self, sig=None, val=None): + """ + Offset on Y axis + + :param sig: Signal value sent by the signal that is connected to this slot + :param val: Offset with a known value, val + :return: + """ + if val: value = val else: @@ -1236,8 +1278,7 @@ class TransformEditorTool(FlatCAMTool): try: value = float(self.offy_entry.get_value().replace(',', '.')) except ValueError: - self.app.inform.emit('[ERROR_NOTCL] %s' % - _("Wrong value format entered, use a number.")) + self.app.inform.emit('[ERROR_NOTCL] %s' % _("Wrong value format entered, use a number.")) return # self.on_offset("Y", value) @@ -1247,6 +1288,13 @@ class TransformEditorTool(FlatCAMTool): return def on_rotate_action(self, num): + """ + Rotate geometry + + :param num: Rotate with a known angle value, num + :return: + """ + shape_list = self.draw_app.selected xminlist = [] yminlist = [] @@ -1254,8 +1302,7 @@ class TransformEditorTool(FlatCAMTool): ymaxlist = [] if not shape_list: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("No shape selected. Please Select a shape to rotate!")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("No shape selected. Please Select a shape to rotate!")) return else: with self.app.proc_container.new(_("Appying Rotate")): @@ -1290,6 +1337,13 @@ class TransformEditorTool(FlatCAMTool): return def on_flip(self, axis): + """ + Mirror (flip) geometry + + :param axis: Miror on a known axis given by the axis parameter + :return: + """ + shape_list = self.draw_app.selected xminlist = [] yminlist = [] @@ -1346,6 +1400,14 @@ class TransformEditorTool(FlatCAMTool): return def on_skew(self, axis, num): + """ + Skew geometry + + :param num: Rotate with a known angle value, num + :param axis: Axis on which to deform, skew + :return: + """ + shape_list = self.draw_app.selected xminlist = [] yminlist = [] @@ -1387,6 +1449,17 @@ class TransformEditorTool(FlatCAMTool): return def on_scale(self, axis, xfactor, yfactor, point=None): + """ + Scale geometry + + :param axis: Axis on which to scale + :param xfactor: Factor for scaling on X axis + :param yfactor: Factor for scaling on Y axis + :param point: Point of origin for scaling + + :return: + """ + shape_list = self.draw_app.selected xminlist = [] yminlist = [] @@ -1437,13 +1510,18 @@ class TransformEditorTool(FlatCAMTool): return def on_offset(self, axis, num): + """ + Offset geometry + + :param axis: Axis on which to apply offset + :param num: The translation factor + + :return: + """ shape_list = self.draw_app.selected - xminlist = [] - yminlist = [] if not shape_list: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("No shape selected. Please Select a shape to offset!")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("No shape selected. Please Select a shape to offset!")) return else: with self.app.proc_container.new(_("Applying Offset")): @@ -1646,11 +1724,11 @@ class DrawToolShape(object): Mirrors the shape around a specified axis passing through the given point. - :param axis: "X" or "Y" indicates around which axis to mirror. - :type axis: str - :param point: [x, y] point belonging to the mirror axis. - :type point: list - :return: None + :param axis: "X" or "Y" indicates around which axis to mirror. + :type axis: str + :param point: [x, y] point belonging to the mirror axis. + :type point: list + :return: None """ px, py = point @@ -1674,8 +1752,7 @@ class DrawToolShape(object): """ Rotate a shape by an angle (in degrees) around the provided coordinates. - Parameters - ---------- + The angle of rotation are specified in degrees (default). Positive angles are counter-clockwise and negative are clockwise rotations. @@ -1683,8 +1760,11 @@ class DrawToolShape(object): center (default), 'centroid' for the geometry's centroid, a Point object or a coordinate tuple (x0, y0). - See shapely manual for more information: - http://toblerity.org/shapely/manual.html#affine-transformations + See shapely manual for more information: http://toblerity.org/shapely/manual.html#affine-transformations + + :param angle: The angle of rotation + :param point: The point of origin + :return: None """ px, py = point @@ -1707,16 +1787,17 @@ class DrawToolShape(object): """ Shear/Skew a shape by angles along x and y dimensions. - Parameters - ---------- angle_x, angle_y : float, float The shear angle(s) for the x and y axes respectively. These can be specified in either degrees (default) or radians by setting use_radians=True. - point: tuple of coordinates (x,y) - See shapely manual for more information: - http://toblerity.org/shapely/manual.html#affine-transformations + See shapely manual for more information: http://toblerity.org/shapely/manual.html#affine-transformations + + :param angle_x: + :param angle_y: + :param point: tuple of coordinates (x,y) + :return: """ px, py = point @@ -1736,12 +1817,12 @@ class DrawToolShape(object): def offset(self, vect): """ - Offsets all shapes by a given vector/ + Offsets all shapes by a given vector - :param vect: (x, y) vector by which to offset the shape geometry - :type vect: tuple - :return: None - :rtype: None + :param vect: (x, y) vector by which to offset the shape geometry + :type vect: tuple + :return: None + :rtype: None """ try: @@ -1769,10 +1850,11 @@ class DrawToolShape(object): """ Scales all shape geometry by a given factor. - :param xfactor: Factor by which to scale the shape's geometry/ - :type xfactor: float - :param yfactor: Factor by which to scale the shape's geometry/ - :type yfactor: float + :param xfactor: Factor by which to scale the shape's geometry/ + :type xfactor: float + :param yfactor: Factor by which to scale the shape's geometry/ + :type yfactor: float + :param point: Point of origin; tuple :return: None :rtype: None """ @@ -1898,6 +1980,8 @@ class FCShapeTool(DrawTool): def __init__(self, draw_app): DrawTool.__init__(self, draw_app) + self.name = None + def make(self): pass @@ -2454,7 +2538,7 @@ class FCSelect(DrawTool): try: QtGui.QGuiApplication.restoreOverrideCursor() - except Exception as e: + except Exception: pass self.storage = self.draw_app.storage @@ -2462,12 +2546,17 @@ class FCSelect(DrawTool): # self.selected = self.draw_app.selected def click_release(self, point): + """ + + :param point: The point for which to find the neasrest shape + :return: + """ # list where we store the overlapped shapes under our mouse left click position over_shape_list = [] # pos[0] and pos[1] are the mouse click coordinates (x, y) - for obj_shape in self.storage.get_objects(): + for ____ in self.storage.get_objects(): # first method of click selection -> inconvenient # minx, miny, maxx, maxy = obj_shape.geo.bounds # if (minx <= pos[0] <= maxx) and (miny <= pos[1] <= maxy): @@ -2482,7 +2571,7 @@ class FCSelect(DrawTool): # 3rd method of click selection -> inconvenient try: - _, closest_shape = self.storage.nearest(point) + __, closest_shape = self.storage.nearest(point) except StopIteration: return "" @@ -2566,7 +2655,7 @@ class FCExplode(FCShapeTool): self.draw_app.active_tool = self if len(self.draw_app.get_selected()) == 0: - self.draw_app.app.inform.emit('[WARNING_NOTCL] %s...' % ("No shape selected. Select a shape to explode")) + self.draw_app.app.inform.emit('[WARNING_NOTCL] %s...' % _("No shape selected. Select a shape to explode")) else: self.make() @@ -2619,7 +2708,7 @@ class FCMove(FCShapeTool): try: QtGui.QGuiApplication.restoreOverrideCursor() - except Exception as e: + except Exception: pass self.storage = self.draw_app.storage @@ -3084,7 +3173,7 @@ class FCEraser(FCShapeTool): self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x)) if len(self.draw_app.get_selected()) == 0: - for obj_shape in self.storage.get_objects(): + for ____ in self.storage.get_objects(): try: __, closest_shape = self.storage.nearest(point) self.draw_app.selected.append(closest_shape) @@ -3234,6 +3323,9 @@ class FlatCAMGeoEditor(QtCore.QObject): self.tools_box.setContentsMargins(0, 0, 0, 0) self.geo_frame.setLayout(self.tools_box) + if disabled: + self.geo_frame.setDisabled(True) + # ## Page Title box (spacing between children) self.title_box = QtWidgets.QHBoxLayout() self.tools_box.addLayout(self.title_box) @@ -3368,23 +3460,33 @@ class FlatCAMGeoEditor(QtCore.QObject): self.rtree_index = rtindex.Index() - def entry2option(option, entry): + def entry2option(opt, entry): + """ + + :param opt: A option from the self.options dictionary + :param entry: A GUI element which text value is used + :return: + """ try: - self.options[option] = float(entry.text()) + self.options[opt] = float(entry.text()) except Exception as e: log.debug("FlatCAMGeoEditor.__init__().entry2option() --> %s" % str(e)) return def gridx_changed(goption, gentry): - entry2option(option=goption, entry=gentry) + """ + + :param goption: String. Can be either 'global_gridx' or 'global_gridy' + :param gentry: A GUI element which text value is read and used + :return: + """ + entry2option(opt=goption, entry=gentry) # if the grid link is checked copy the value in the GridX field to GridY try: - val = float(self.app.ui.grid_gap_x_entry.get_value()) + val = float(gentry.get_value()) except ValueError: return - units = self.app.defaults['units'].upper() - if self.app.ui.grid_gap_link_cb.isChecked(): self.app.ui.grid_gap_y_entry.set_value(val, decimals=self.decimals) @@ -3463,13 +3565,12 @@ class FlatCAMGeoEditor(QtCore.QObject): # Switch notebook to Selected page self.app.ui.notebook.setCurrentWidget(self.app.ui.selected_tab) - def build_ui(self, first_run=None): + def build_ui(self): + """ + Build the GUI in the Selected Tab for this editor - # try: - # # if connected, disconnect the signal from the slot on item_changed as it creates issues - # self.apertures_table.itemChanged.disconnect() - # except (TypeError, AttributeError): - # pass + :return: + """ iterator = QtWidgets.QTreeWidgetItemIterator(self.geo_parent) to_delete = [] @@ -3861,9 +3962,9 @@ class FlatCAMGeoEditor(QtCore.QObject): """ Adds a shape to the shape storage. - :param shape: Shape to be added. - :type shape: DrawToolShape - :return: None + :param shape: Shape to be added. + :type shape: DrawToolShape + :return: None """ if shape is None: @@ -3877,8 +3978,8 @@ class FlatCAMGeoEditor(QtCore.QObject): assert isinstance(shape, DrawToolShape), "Expected a DrawToolShape, got %s" % type(shape) assert shape.geo is not None, "Shape object has empty geometry (None)" - assert (isinstance(shape.geo, list) and len(shape.geo) > 0) or \ - not isinstance(shape.geo, list), "Shape objects has empty geometry ([])" + assert (isinstance(shape.geo, list) and len(shape.geo) > 0) or not isinstance(shape.geo, list), \ + "Shape objects has empty geometry ([])" if isinstance(shape, DrawToolUtilityShape): self.utility.append(shape) @@ -3887,6 +3988,12 @@ class FlatCAMGeoEditor(QtCore.QObject): self.build_ui() def delete_utility_geometry(self): + """ + Will delete the shapes in the utility shapes storage. + + :return: None + """ + # for_deletion = [shape for shape in self.shape_buffer if shape.utility] # for_deletion = [shape for shape in self.storage.get_objects() if shape.utility] for_deletion = [shape for shape in self.utility] @@ -3897,10 +4004,23 @@ class FlatCAMGeoEditor(QtCore.QObject): self.tool_shape.redraw() def toolbar_tool_toggle(self, key): - self.options[key] = self.sender().isChecked() - return 1 if self.options[key] == True else 0 + """ + It is used as a slot by the Snap buttons. + + :param key: Key in the self.options dictionary that is to be updated + :return: Boolean. Status of the checkbox that toggled the Editor Tool + """ + cb_widget = self.sender() + self.options[key] = cb_widget.isChecked() + + return 1 if self.options[key] is True else 0 def clear(self): + """ + Will clear the storage for the Editor shapes, the selected shapes storage and replot. Clean up method. + + :return: None + """ self.active_tool = None # self.shape_buffer = [] self.selected = [] @@ -3915,12 +4035,11 @@ class FlatCAMGeoEditor(QtCore.QObject): Imports the geometry from the given FlatCAM Geometry object into the editor. - :param fcgeometry: FlatCAMGeometry - :param multigeo_tool: a tool for the case of multigeo - :return: None + :param fcgeometry: FlatCAMGeometry + :param multigeo_tool: A tool for the case of the edited geometry being of type 'multigeo' + :return: None """ - assert isinstance(fcgeometry, Geometry), \ - "Expected a Geometry, got %s" % type(fcgeometry) + assert isinstance(fcgeometry, Geometry), "Expected a Geometry, got %s" % type(fcgeometry) self.deactivate() self.activate() @@ -3964,7 +4083,7 @@ class FlatCAMGeoEditor(QtCore.QObject): geo_to_edit = self.flatten(geometry=fcgeometry.solid_geometry, orient_val=milling_type) for shape in geo_to_edit: - if shape is not None: # TODO: Make flatten never create a None + if shape is not None: if type(shape) == Polygon: self.add_shape(DrawToolShape(shape.exterior)) for inter in shape.interiors: @@ -4186,16 +4305,16 @@ class FlatCAMGeoEditor(QtCore.QObject): def on_geo_click_release(self, event): if self.app.is_legacy is False: event_pos = event.pos - event_is_dragging = event.is_dragging + # event_is_dragging = event.is_dragging right_button = 2 else: event_pos = (event.xdata, event.ydata) - event_is_dragging = self.app.plotcanvas.is_dragging + # event_is_dragging = self.app.plotcanvas.is_dragging right_button = 3 pos_canvas = self.canvas.translate_coords(event_pos) - if self.app.grid_status() == True: + if self.app.grid_status(): pos = self.snap(pos_canvas[0], pos_canvas[1]) else: pos = (pos_canvas[0], pos_canvas[1]) diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index 89c13eca..67abf105 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -795,9 +795,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.snap_toolbar.setObjectName('Snap_TB') self.addToolBar(self.snap_toolbar) - settings = QSettings("Open Source", "FlatCAM") - if settings.contains("layout"): - layout = settings.value('layout', type=str) + flat_settings = QSettings("Open Source", "FlatCAM") + if flat_settings.contains("layout"): + layout = flat_settings.value('layout', type=str) if layout == 'compact': self.removeToolBar(self.snap_toolbar) self.snap_toolbar.setMaximumHeight(30) @@ -2349,14 +2349,14 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # ################## RESTORE THE TOOLBAR STATE from file ################# # ######################################################################## - settings = QSettings("Open Source", "FlatCAM") - if settings.contains("saved_gui_state"): - saved_gui_state = settings.value('saved_gui_state') + flat_settings = QSettings("Open Source", "FlatCAM") + if flat_settings.contains("saved_gui_state"): + saved_gui_state = flat_settings.value('saved_gui_state') self.restoreState(saved_gui_state) log.debug("FlatCAMGUI.__init__() --> UI state restored from QSettings.") - if settings.contains("layout"): - layout = settings.value('layout', type=str) + if flat_settings.contains("layout"): + layout = flat_settings.value('layout', type=str) self.exc_edit_toolbar.setDisabled(True) self.geo_edit_toolbar.setDisabled(True) self.grb_edit_toolbar.setDisabled(True) @@ -2378,9 +2378,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.corner_snap_btn.setVisible(False) self.snap_magnet.setVisible(False) - settings.setValue('layout', "standard") + flat_settings.setValue('layout', "standard") # This will write the setting to the platform specific storage. - del settings + del flat_settings log.debug("FlatCAMGUI.__init__() --> UI layout restored from defaults. QSettings set to 'standard'") # construct the Toolbar Lock menu entry to the context menu of the QMainWindow @@ -2388,8 +2388,8 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.lock_action.setText(_("Lock Toolbars")) self.lock_action.setCheckable(True) - settings = QSettings("Open Source", "FlatCAM") - if settings.contains("toolbar_lock"): + qsettings = QSettings("Open Source", "FlatCAM") + if qsettings.contains("toolbar_lock"): lock_val = settings.value('toolbar_lock') if lock_val == 'true': lock_state = True @@ -2400,10 +2400,10 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.lock_action.setChecked(False) else: lock_state = False - settings.setValue('toolbar_lock', lock_state) + qsettings.setValue('toolbar_lock', lock_state) # This will write the setting to the platform specific storage. - del settings + del qsettings self.lock_toolbar(lock=lock_state) self.lock_action.triggered[bool].connect(self.lock_toolbar) @@ -2466,11 +2466,11 @@ class FlatCAMGUI(QtWidgets.QMainWindow): response = msgbox.clickedButton() if response == bt_yes: - settings = QSettings("Open Source", "FlatCAM") - for key in settings.allKeys(): - settings.remove(key) + qsettings = QSettings("Open Source", "FlatCAM") + for key in qsettings.allKeys(): + qsettings.remove(key) # This will write the setting to the platform specific storage. - del settings + del qsettings def populate_toolbars(self): """ @@ -2760,9 +2760,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # start with GRID activated self.grid_snap_btn.trigger() - settings = QSettings("Open Source", "FlatCAM") - if settings.contains("layout"): - layout = settings.value('layout', type=str) + qsettings = QSettings("Open Source", "FlatCAM") + if qsettings.contains("layout"): + layout = qsettings.value('layout', type=str) if layout == 'standard': self.corner_snap_btn.setVisible(False) @@ -3892,7 +3892,6 @@ class FlatCAMGUI(QtWidgets.QMainWindow): return # Propagate to tool - response = None # Show Shortcut list if key == QtCore.Qt.Key_F3 or key == 'F3': From ecf61fdf6dfaf3a75fd898ad89044ec584eff9fd Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 20 Apr 2020 00:57:13 +0300 Subject: [PATCH 183/209] - made the Grid icon in the status bar clickable and it will toggle the snap to grid function --- FlatCAMApp.py | 69 +++++++++++++++++++++++++++++++-------- README.md | 4 +++ flatcamGUI/FlatCAMGUI.py | 2 +- flatcamGUI/GUIElements.py | 10 ++++++ 4 files changed, 70 insertions(+), 15 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index c176ab56..e0c904f9 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -2276,6 +2276,7 @@ class App(QtCore.QObject): self.ui.plot_tab_area.tab_closed_signal.connect(self.on_plot_area_tab_closed) self.ui.grid_snap_btn.triggered.connect(self.on_grid_snap_triggered) + self.ui.snap_infobar_label.clicked.connect(self.on_grid_icon_snap_clicked) # signal to close the application self.close_app_signal.connect(self.kill_app) @@ -12489,7 +12490,7 @@ class App(QtCore.QObject): def on_zoom_fit(self, event): """ - Callback for zoom-out request. This can be either from the corresponding + Callback for zoom-fit request. This can be either from the corresponding toolbar button or the '1' key when the canvas is focused. Calls ``self.adjust_axes()`` with axes limits from the geometry bounds of all objects. @@ -12509,9 +12510,18 @@ class App(QtCore.QObject): self.plotcanvas.adjust_axes(xmin, ymin, xmax, ymax) def on_zoom_in(self): + """ + Callback for zoom-in request. + :return: + """ self.plotcanvas.zoom(1 / float(self.defaults['global_zoom_ratio'])) def on_zoom_out(self): + """ + Callback for zoom-out request. + + :return: + """ self.plotcanvas.zoom(float(self.defaults['global_zoom_ratio'])) def disable_all_plots(self): @@ -12551,7 +12561,7 @@ class App(QtCore.QObject): def enable_plots(self, objects): """ - Disables plots + Enable plots :param objects: list of Objects to be enabled :return: @@ -12679,8 +12689,16 @@ class App(QtCore.QObject): self.clear_pool() def on_set_color_action_triggered(self): + """ + This slot gets called by clicking on the menu entry in the Set Color submenu of the context menu in Project Tab + + :return: + """ new_color = self.defaults['gerber_plot_fill'] - act_name = self.sender().text() + clicked_action = self.sender() + + assert isinstance(clicked_action, QAction), "Expected a QAction, got %s" % isinstance(clicked_action, QAction) + act_name = clicked_action.text() sel_obj_list = self.collection.get_selected() if not sel_obj_list: @@ -12783,12 +12801,35 @@ class App(QtCore.QObject): ) def on_grid_snap_triggered(self, state): + """ + + :param state: A parameter with the state of the grid, boolean + + :return: + """ if state: self.ui.snap_infobar_label.setPixmap(QtGui.QPixmap(self.resource_location + '/snap_filled_16.png')) else: self.ui.snap_infobar_label.setPixmap(QtGui.QPixmap(self.resource_location + '/snap_16.png')) + self.ui.snap_infobar_label.clicked_state = state + + def on_grid_icon_snap_clicked(self): + """ + Slot called by clicking a GUI element, in this case a FCLabel + + :return: + """ + if isinstance(self.sender(), FCLabel): + self.ui.grid_snap_btn.trigger() + def generate_cnc_job(self, objects): + """ + Slot that will be called by clicking an entry in the contextual menu generated in the Project Tab tree + + :param objects: Selected objects in the Project Tab + :return: + """ self.report_usage("generate_cnc_job()") # for obj in objects: @@ -12800,11 +12841,11 @@ class App(QtCore.QObject): """ Saves the current project to the specified file. - :param filename: Name of the file in which to save. - :type filename: str - :param quit_action: if the project saving will be followed by an app quit; boolean - :param silent: if True will not display status messages - :return: None + :param filename: Name of the file in which to save. + :type filename: str + :param quit_action: if the project saving will be followed by an app quit; boolean + :param silent: if True will not display status messages + :return: None """ self.log.debug("save_project()") self.save_in_progress = True @@ -12887,9 +12928,9 @@ class App(QtCore.QObject): def start_delayed_quit(self, delay, filename, should_quit=None): """ - :param delay: period of checking if project file size is more than zero; in seconds - :param filename: the name of the project file to be checked periodically for size more than zero - :param should_quit: if the task finished will be followed by an app quit; boolean + :param delay: period of checking if project file size is more than zero; in seconds + :param filename: the name of the project file to be checked periodically for size more than zero + :param should_quit: if the task finished will be followed by an app quit; boolean :return: """ to_quit = should_quit @@ -12901,8 +12942,8 @@ class App(QtCore.QObject): def check_project_file_size(self, filename, should_quit=None): """ - :param filename: the name of the project file to be checked periodically for size more than zero - :param should_quit: will quit the app if True; boolean + :param filename: the name of the project file to be checked periodically for size more than zero + :param should_quit: will quit the app if True; boolean :return: """ @@ -12927,7 +12968,7 @@ class App(QtCore.QObject): Callback for Options->Transfer Options->App=>Project. Copies options from application defaults to project defaults. - :return: None + :return: None """ self.report_usage("on_options_app2project") diff --git a/README.md b/README.md index 6fb305b0..354e4e58 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +20.04.2020 + +- made the Grid icon in the status bar clickable and it will toggle the snap to grid function + 19.04.2020 - fixed a bug that did not allow to edit GUI elements of type FCDoubleSpinner if it contained the percent symbol diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index 67abf105..8c9f41e2 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -2268,7 +2268,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.fcinfo = FlatCAMInfoBar(app=self.app) self.infobar.addWidget(self.fcinfo, stretch=1) - self.snap_infobar_label = QtWidgets.QLabel() + self.snap_infobar_label = FCLabel() self.snap_infobar_label.setPixmap(QtGui.QPixmap(self.app.resource_location + '/snap_16.png')) self.infobar.addWidget(self.snap_infobar_label) diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index e3139318..94fa88e2 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -1417,9 +1417,19 @@ class FCButton(QtWidgets.QPushButton): class FCLabel(QtWidgets.QLabel): + + clicked = QtCore.pyqtSignal(bool) + def __init__(self, parent=None): super(FCLabel, self).__init__(parent) + # for the usage of this label as a clickable label, to know that current state + self.clicked_state = False + + def mousePressEvent(self, ev: QtGui.QMouseEvent) -> None: + self.clicked_state = not self.clicked_state + self.clicked.emit(self.clicked_state) + def get_value(self): return self.text() From 26ec98d64b3770013d61dfada398bceda4df971e Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 20 Apr 2020 01:48:12 +0300 Subject: [PATCH 184/209] - some mods in the Distance Tool --- README.md | 1 + flatcamTools/ToolDistance.py | 14 +++++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 354e4e58..c20af0e9 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 20.04.2020 - made the Grid icon in the status bar clickable and it will toggle the snap to grid function +- some mods in the Distance Tool 19.04.2020 diff --git a/flatcamTools/ToolDistance.py b/flatcamTools/ToolDistance.py index 43bae37c..09c4cce7 100644 --- a/flatcamTools/ToolDistance.py +++ b/flatcamTools/ToolDistance.py @@ -178,7 +178,6 @@ class Distance(FlatCAMTool): self.sel_shapes = ShapeCollectionLegacy(obj=self, app=self.app, name='measurement') self.measure_btn.clicked.connect(self.activate_measure_tool) - self.snap_center_cb.toggled.connect(self.on_snap_toggled) def run(self, toggle=False): self.app.report_usage("ToolDistance()") @@ -236,8 +235,16 @@ class Distance(FlatCAMTool): # snap center works only for Gerber and Execellon Editor's if self.original_call_source == 'exc_editor' or self.original_call_source == 'grb_editor': self.snap_center_cb.show() + snap_center = self.app.defaults['tools_dist_snap_center'] + self.on_snap_toggled(snap_center) + + self.snap_center_cb.toggled.connect(self.on_snap_toggled) else: self.snap_center_cb.hide() + try: + self.snap_center_cb.toggled.disconnect(self.on_snap_toggled) + except (TypeError, AttributeError): + pass # this is a hack; seems that triggering the grid will make the visuals better # trigger it twice to return to the original state @@ -267,9 +274,6 @@ class Distance(FlatCAMTool): self.clicked_meas = 0 self.original_call_source = copy(self.app.call_source) - snap_center = self.app.defaults['tools_dist_snap_center'] - self.on_snap_toggled(snap_center) - self.app.inform.emit(_("MEASURING: Click on the Start point ...")) self.units = self.app.defaults['units'].lower() @@ -480,7 +484,7 @@ class Distance(FlatCAMTool): self.start_entry.set_value("(%.*f, %.*f)" % (self.decimals, pos[0], self.decimals, pos[1])) self.app.inform.emit(_("MEASURING: Click on the Destination point ...")) elif len(self.points) == 2: - self.app.app_cursor.enabled = False + # self.app.app_cursor.enabled = False dx = self.points[1][0] - self.points[0][0] dy = self.points[1][1] - self.points[0][1] d = math.sqrt(dx ** 2 + dy ** 2) From dc1a19823564ae0e5bb76c0362041e05a3fee016 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 20 Apr 2020 04:18:12 +0300 Subject: [PATCH 185/209] - added ability to use line width when adding shapes for both Legacy and OpenGL graphic engines - added the linewidth=2 parameter for the Tool Distance utility geometry - fixed a selection issue in Legacy graphic mode for single click --- FlatCAMApp.py | 29 ++-- README.md | 3 + flatcamEditors/FlatCAMExcEditor.py | 6 +- flatcamEditors/FlatCAMGeoEditor.py | 6 +- flatcamEditors/FlatCAMGrbEditor.py | 6 +- flatcamGUI/PlotCanvasLegacy.py | 207 ++++++++++++++++++----------- flatcamGUI/VisPyVisuals.py | 13 +- flatcamTools/ToolCopperThieving.py | 6 +- flatcamTools/ToolDistance.py | 2 +- flatcamTools/ToolNCC.py | 6 +- flatcamTools/ToolPaint.py | 6 +- 11 files changed, 178 insertions(+), 112 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index e0c904f9..e7d1d430 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -2670,6 +2670,10 @@ class App(QtCore.QObject): # variable to store mouse coordinates self.mouse = [0, 0] + # variable to store the delta positions on cavnas + self.dx = 0 + self.dy = 0 + # decide if we have a double click or single click self.doubleclick = False @@ -7635,10 +7639,10 @@ class App(QtCore.QObject): self.ui.position_label.setText("    X: %.4f   " "Y: %.4f" % (location[0], location[1])) # Set the relative position label - dx = location[0] - float(self.rel_point1[0]) - dy = location[1] - float(self.rel_point1[1]) + self.dx = location[0] - float(self.rel_point1[0]) + self.dy = location[1] - float(self.rel_point1[1]) self.ui.rel_position_label.setText("Dx: %.4f   Dy: " - "%.4f    " % (dx, dy)) + "%.4f    " % (self.dx, self.dy)) self.inform.emit('[success] %s' % _("Done.")) return location @@ -8823,24 +8827,26 @@ class App(QtCore.QObject): self.ui.position_label.setText("    X: %.4f   " "Y: %.4f" % (pos[0], pos[1])) - dx = pos[0] - float(self.rel_point1[0]) - dy = pos[1] - float(self.rel_point1[1]) + self.dx = pos[0] - float(self.rel_point1[0]) + self.dy = pos[1] - float(self.rel_point1[1]) self.ui.rel_position_label.setText("Dx: %.4f   Dy: " - "%.4f    " % (dx, dy)) + "%.4f    " % (self.dx, self.dy)) self.mouse = [pos[0], pos[1]] # if the mouse is moved and the LMB is clicked then the action is a selection if self.event_is_dragging == 1 and event.button == 1: self.delete_selection_shape() - if dx < 0: + if self.dx < 0: self.draw_moving_selection_shape(self.pos, pos, color=self.defaults['global_alt_sel_line'], face_color=self.defaults['global_alt_sel_fill']) self.selection_type = False - elif dx >= 0: + elif self.dx >= 0: self.draw_moving_selection_shape(self.pos, pos) self.selection_type = True else: self.selection_type = None + else: + self.selection_type = None # hover effect - enabled in Preferences -> General -> GUI Settings if self.defaults['global_hover']: @@ -8940,6 +8946,12 @@ class App(QtCore.QObject): log.warning("FlatCAMApp.on_mouse_click_release_over_plot() double click --> Error: %s" % str(e)) return else: + # WORKAROUND for LEGACY MODE + if self.is_legacy is True: + # if there is no move on canvas then we have no dragging selection + if self.dx == 0 or self.dy == 0: + self.selection_type = None + if self.selection_type is not None: try: self.selection_area_handler(self.pos, pos, self.selection_type) @@ -8948,6 +8960,7 @@ class App(QtCore.QObject): log.warning("FlatCAMApp.on_mouse_click_release_over_plot() select area --> Error: %s" % str(e)) return else: + key_modifier = QtWidgets.QApplication.keyboardModifiers() if key_modifier == QtCore.Qt.ShiftModifier: diff --git a/README.md b/README.md index c20af0e9..c682b260 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,9 @@ CAD program, and create G-Code for Isolation routing. - made the Grid icon in the status bar clickable and it will toggle the snap to grid function - some mods in the Distance Tool +- added ability to use line width when adding shapes for both Legacy and OpenGL graphic engines +- added the linewidth=2 parameter for the Tool Distance utility geometry +- fixed a selection issue in Legacy graphic mode for single click 19.04.2020 diff --git a/flatcamEditors/FlatCAMExcEditor.py b/flatcamEditors/FlatCAMExcEditor.py index 02afac5c..313c59a2 100644 --- a/flatcamEditors/FlatCAMExcEditor.py +++ b/flatcamEditors/FlatCAMExcEditor.py @@ -3807,12 +3807,12 @@ class FlatCAMExcEditor(QtCore.QObject): if self.pos is None: self.pos = (0, 0) - dx = x - self.pos[0] - dy = y - self.pos[1] + self.app.dx = x - self.pos[0] + self.app.dy = y - self.pos[1] # update the reference position label in the infobar since the APP mouse event handlers are disconnected self.app.ui.rel_position_label.setText("Dx: %.4f   Dy: " - "%.4f    " % (dx, dy)) + "%.4f    " % (self.app.dx, self.app.dy)) # ## Utility geometry (animated) self.update_utility_geometry(data=(x, y)) diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index cdea92b5..7601cc24 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -4267,12 +4267,12 @@ class FlatCAMGeoEditor(QtCore.QObject): if self.pos is None: self.pos = (0, 0) - dx = x - self.pos[0] - dy = y - self.pos[1] + self.app.dx = x - self.pos[0] + self.app.dy = y - self.pos[1] # update the reference position label in the infobar since the APP mouse event handlers are disconnected self.app.ui.rel_position_label.setText("Dx: %.4f   Dy: " - "%.4f    " % (dx, dy)) + "%.4f    " % (self.app.dx, self.app.dy)) if event.button == 1 and event_is_dragging and isinstance(self.active_tool, FCEraser): pass diff --git a/flatcamEditors/FlatCAMGrbEditor.py b/flatcamEditors/FlatCAMGrbEditor.py index 1d797d34..c6cd2ed0 100644 --- a/flatcamEditors/FlatCAMGrbEditor.py +++ b/flatcamEditors/FlatCAMGrbEditor.py @@ -4648,12 +4648,12 @@ class FlatCAMGrbEditor(QtCore.QObject): if self.pos is None: self.pos = (0, 0) - dx = x - self.pos[0] - dy = y - self.pos[1] + self.app.dx = x - self.pos[0] + self.app.dy = y - self.pos[1] # update the reference position label in the infobar since the APP mouse event handlers are disconnected self.app.ui.rel_position_label.setText("Dx: %.4f   Dy: " - "%.4f    " % (dx, dy)) + "%.4f    " % (self.app.dx, self.app.dy)) self.update_utility_geometry(data=(x, y)) diff --git a/flatcamGUI/PlotCanvasLegacy.py b/flatcamGUI/PlotCanvasLegacy.py index ed62d9a0..d2136784 100644 --- a/flatcamGUI/PlotCanvasLegacy.py +++ b/flatcamGUI/PlotCanvasLegacy.py @@ -14,7 +14,7 @@ from PyQt5.QtCore import pyqtSignal # Used for solid polygons in Matplotlib from descartes.patch import PolygonPatch -from shapely.geometry import Polygon, LineString, LinearRing, Point, MultiPolygon, MultiLineString +from shapely.geometry import Polygon, LineString, LinearRing import FlatCAMApp @@ -219,7 +219,7 @@ class PlotCanvasLegacy(QtCore.QObject): self.container = container # Plots go onto a single matplotlib.figure - self.figure = Figure(dpi=50) # TODO: dpi needed? + self.figure = Figure(dpi=50) self.figure.patch.set_visible(True) self.figure.set_facecolor(theme_color) @@ -254,7 +254,7 @@ class PlotCanvasLegacy(QtCore.QObject): # self.canvas.set_can_focus(True) # For key press # Attach to parent - # self.container.attach(self.canvas, 0, 0, 600, 400) # TODO: Height and width are num. columns?? + # self.container.attach(self.canvas, 0, 0, 600, 400) self.container.addWidget(self.canvas) # Qt # Copy a bitmap of the canvas for quick animation. @@ -430,7 +430,7 @@ class PlotCanvasLegacy(QtCore.QObject): # Pointer (snapped) # The size of the cursor is multiplied by 1.65 because that value made the cursor similar with the # one in the OpenGL(3D) graphic engine - pointer_size = int(float(self.app.defaults["global_cursor_size"] ) * 1.65) + pointer_size = int(float(self.app.defaults["global_cursor_size"]) * 1.65) elements = self.axes.plot(x, y, '+', color=color, ms=pointer_size, mew=self.app.defaults["global_cursor_width"], animated=True) for el in elements: @@ -946,14 +946,16 @@ class ShapeCollectionLegacy: hold the collection of shapes into a dict self._shapes. This handles the shapes redraw on canvas. """ - def __init__(self, obj, app, name=None, annotation_job=None): + def __init__(self, obj, app, name=None, annotation_job=None, linewidth=1): """ - :param obj: this is the object to which the shapes collection is attached and for + :param obj: This is the object to which the shapes collection is attached and for which it will have to draw shapes - :param app: this is the FLatCAM.App usually, needed because we have to access attributes there - :param name: this is the name given to the Matplotlib axes; it needs to be unique due of Matplotlib requurements - :param annotation_job: make this True if the job needed is just for annotation + :param app: This is the FLatCAM.App usually, needed because we have to access attributes there + :param name: This is the name given to the Matplotlib axes; it needs to be unique due of + Matplotlib requurements + :param annotation_job: Make this True if the job needed is just for annotation + :param linewidth: THe width of the line (outline where is the case) """ self.obj = obj self.app = app @@ -974,6 +976,8 @@ class ShapeCollectionLegacy: self._obj = None self._gcode_parsed = None + self._linewidth = linewidth + if name is None: axes_name = self.obj.options['name'] else: @@ -1005,14 +1009,21 @@ class ShapeCollectionLegacy: :return: """ self._color = color if color is not None else "#006E20" - self._face_color = face_color if face_color is not None else "#BBF268" + # self._face_color = face_color if face_color is not None else "#BBF268" + self._face_color = face_color + + if linewidth is None: + line_width = self._linewidth + else: + line_width = linewidth if len(self._color) > 7: self._color = self._color[:7] - if len(self._face_color) > 7: - self._face_color = self._face_color[:7] - # self._alpha = int(self._face_color[-2:], 16) / 255 + if self._face_color is not None: + if len(self._face_color) > 7: + self._face_color = self._face_color[:7] + # self._alpha = int(self._face_color[-2:], 16) / 255 self._alpha = 0.75 @@ -1037,7 +1048,7 @@ class ShapeCollectionLegacy: self.shape_dict.update({ 'color': self._color, 'face_color': self._face_color, - 'linewidth': linewidth, + 'linewidth': line_width, 'alpha': self._alpha, 'shape': sh }) @@ -1050,7 +1061,7 @@ class ShapeCollectionLegacy: self.shape_dict.update({ 'color': self._color, 'face_color': self._face_color, - 'linewidth': linewidth, + 'linewidth': line_width, 'alpha': self._alpha, 'shape': shape }) @@ -1112,36 +1123,50 @@ class ShapeCollectionLegacy: if obj_type == 'excellon': # Plot excellon (All polygons?) if self.obj.options["solid"] and isinstance(local_shapes[element]['shape'], Polygon): - patch = PolygonPatch(local_shapes[element]['shape'], - facecolor="#C40000", - edgecolor="#750000", - alpha=local_shapes[element]['alpha'], - zorder=3) - self.axes.add_patch(patch) + try: + patch = PolygonPatch(local_shapes[element]['shape'], + facecolor="#C40000", + edgecolor="#750000", + alpha=local_shapes[element]['alpha'], + zorder=3, + linewidth=local_shapes[element]['linewidth'] + ) + self.axes.add_patch(patch) + except Exception as e: + log.debug("ShapeCollectionLegacy.redraw() excellon poly --> %s" % str(e)) else: - x, y = local_shapes[element]['shape'].exterior.coords.xy - self.axes.plot(x, y, 'r-') - for ints in local_shapes[element]['shape'].interiors: - x, y = ints.coords.xy - self.axes.plot(x, y, 'o-') + try: + x, y = local_shapes[element]['shape'].exterior.coords.xy + self.axes.plot(x, y, 'r-', linewidth=local_shapes[element]['linewidth']) + for ints in local_shapes[element]['shape'].interiors: + x, y = ints.coords.xy + self.axes.plot(x, y, 'o-', linewidth=local_shapes[element]['linewidth']) + except Exception as e: + log.debug("ShapeCollectionLegacy.redraw() excellon no poly --> %s" % str(e)) elif obj_type == 'geometry': if type(local_shapes[element]['shape']) == Polygon: - x, y = local_shapes[element]['shape'].exterior.coords.xy - self.axes.plot(x, y, local_shapes[element]['color'], - linestyle='-', - linewidth=local_shapes[element]['linewidth']) - for ints in local_shapes[element]['shape'].interiors: - x, y = ints.coords.xy + try: + x, y = local_shapes[element]['shape'].exterior.coords.xy self.axes.plot(x, y, local_shapes[element]['color'], linestyle='-', linewidth=local_shapes[element]['linewidth']) + for ints in local_shapes[element]['shape'].interiors: + x, y = ints.coords.xy + self.axes.plot(x, y, local_shapes[element]['color'], + linestyle='-', + linewidth=local_shapes[element]['linewidth']) + except Exception as e: + log.debug("ShapeCollectionLegacy.redraw() geometry poly --> %s" % str(e)) elif type(local_shapes[element]['shape']) == LineString or \ type(local_shapes[element]['shape']) == LinearRing: - x, y = local_shapes[element]['shape'].coords.xy - self.axes.plot(x, y, local_shapes[element]['color'], - linestyle='-', - linewidth=local_shapes[element]['linewidth']) + try: + x, y = local_shapes[element]['shape'].coords.xy + self.axes.plot(x, y, local_shapes[element]['color'], + linestyle='-', + linewidth=local_shapes[element]['linewidth']) + except Exception as e: + log.debug("ShapeCollectionLegacy.redraw() geometry no poly --> %s" % str(e)) elif obj_type == 'gerber': if self.obj.options["multicolored"]: linespec = '-' @@ -1161,47 +1186,60 @@ class ShapeCollectionLegacy: facecolor=gerber_fill_color, edgecolor=gerber_outline_color, alpha=local_shapes[element]['alpha'], - zorder=2) + zorder=2, + linewidth=local_shapes[element]['linewidth']) self.axes.add_patch(patch) except AssertionError: FlatCAMApp.App.log.warning("A geometry component was not a polygon:") FlatCAMApp.App.log.warning(str(element)) except Exception as e: - FlatCAMApp.App.log.debug("PlotCanvasLegacy.ShepeCollectionLegacy.redraw() --> %s" % str(e)) + FlatCAMApp.App.log.debug( + "PlotCanvasLegacy.ShepeCollectionLegacy.redraw() gerber 'solid' --> %s" % str(e)) else: - x, y = local_shapes[element]['shape'].exterior.xy - self.axes.plot(x, y, linespec) - for ints in local_shapes[element]['shape'].interiors: - x, y = ints.coords.xy - self.axes.plot(x, y, linespec) + try: + x, y = local_shapes[element]['shape'].exterior.xy + self.axes.plot(x, y, linespec, linewidth=local_shapes[element]['linewidth']) + for ints in local_shapes[element]['shape'].interiors: + x, y = ints.coords.xy + self.axes.plot(x, y, linespec, linewidth=local_shapes[element]['linewidth']) + except Exception as e: + log.debug("ShapeCollectionLegacy.redraw() gerber no 'solid' --> %s" % str(e)) elif obj_type == 'cncjob': if local_shapes[element]['face_color'] is None: - linespec = '--' - linecolor = local_shapes[element]['color'] - # if geo['kind'][0] == 'C': - # linespec = 'k-' - x, y = local_shapes[element]['shape'].coords.xy - self.axes.plot(x, y, linespec, color=linecolor) + try: + linespec = '--' + linecolor = local_shapes[element]['color'] + # if geo['kind'][0] == 'C': + # linespec = 'k-' + x, y = local_shapes[element]['shape'].coords.xy + self.axes.plot(x, y, linespec, color=linecolor, + linewidth=local_shapes[element]['linewidth']) + except Exception as e: + log.debug("ShapeCollectionLegacy.redraw() cncjob with face_color --> %s" % str(e)) else: - path_num += 1 - if self.obj.ui.annotation_cb.get_value(): - if isinstance(local_shapes[element]['shape'], Polygon): - self.axes.annotate( - str(path_num), - xy=local_shapes[element]['shape'].exterior.coords[0], - xycoords='data', fontsize=20) - else: - self.axes.annotate( - str(path_num), - xy=local_shapes[element]['shape'].coords[0], - xycoords='data', fontsize=20) + try: + path_num += 1 + if self.obj.ui.annotation_cb.get_value(): + if isinstance(local_shapes[element]['shape'], Polygon): + self.axes.annotate( + str(path_num), + xy=local_shapes[element]['shape'].exterior.coords[0], + xycoords='data', fontsize=20) + else: + self.axes.annotate( + str(path_num), + xy=local_shapes[element]['shape'].coords[0], + xycoords='data', fontsize=20) - patch = PolygonPatch(local_shapes[element]['shape'], - facecolor=local_shapes[element]['face_color'], - edgecolor=local_shapes[element]['color'], - alpha=local_shapes[element]['alpha'], zorder=2) - self.axes.add_patch(patch) + patch = PolygonPatch(local_shapes[element]['shape'], + facecolor=local_shapes[element]['face_color'], + edgecolor=local_shapes[element]['color'], + alpha=local_shapes[element]['alpha'], zorder=2, + linewidth=local_shapes[element]['linewidth']) + self.axes.add_patch(patch) + except Exception as e: + log.debug("ShapeCollectionLegacy.redraw() cncjob no face_color --> %s" % str(e)) elif obj_type == 'utility': # not a FlatCAM object, must be utility if local_shapes[element]['face_color']: @@ -1210,26 +1248,35 @@ class ShapeCollectionLegacy: facecolor=local_shapes[element]['face_color'], edgecolor=local_shapes[element]['color'], alpha=local_shapes[element]['alpha'], - zorder=2) + zorder=2, + linewidth=local_shapes[element]['linewidth']) self.axes.add_patch(patch) except Exception as e: - log.debug("ShapeCollectionLegacy.redraw() --> %s" % str(e)) + log.debug("ShapeCollectionLegacy.redraw() utility poly with face_color --> %s" % str(e)) else: if isinstance(local_shapes[element]['shape'], Polygon): - ext_shape = local_shapes[element]['shape'].exterior - if ext_shape is not None: - x, y = ext_shape.xy - self.axes.plot(x, y, local_shapes[element]['color'], linestyle='-') - for ints in local_shapes[element]['shape'].interiors: - if ints is not None: - x, y = ints.coords.xy - self.axes.plot(x, y, local_shapes[element]['color'], linestyle='-') + try: + ext_shape = local_shapes[element]['shape'].exterior + if ext_shape is not None: + x, y = ext_shape.xy + self.axes.plot(x, y, local_shapes[element]['color'], linestyle='-', + linewidth=local_shapes[element]['linewidth']) + for ints in local_shapes[element]['shape'].interiors: + if ints is not None: + x, y = ints.coords.xy + self.axes.plot(x, y, local_shapes[element]['color'], linestyle='-', + linewidth=local_shapes[element]['linewidth']) + except Exception as e: + log.debug("ShapeCollectionLegacy.redraw() utility poly no face_color --> %s" % str(e)) else: - if local_shapes[element]['shape'] is not None: - x, y = local_shapes[element]['shape'].coords.xy - self.axes.plot(x, y, local_shapes[element]['color'], linestyle='-') - + try: + if local_shapes[element]['shape'] is not None: + x, y = local_shapes[element]['shape'].coords.xy + self.axes.plot(x, y, local_shapes[element]['color'], linestyle='-', + linewidth=local_shapes[element]['linewidth']) + except Exception as e: + log.debug("ShapeCollectionLegacy.redraw() utility lines no face_color --> %s" % str(e)) self.app.plotcanvas.auto_adjust_axes() def set(self, text, pos, visible=True, font_size=16, color=None): diff --git a/flatcamGUI/VisPyVisuals.py b/flatcamGUI/VisPyVisuals.py index e881e5c9..d6f19d3b 100644 --- a/flatcamGUI/VisPyVisuals.py +++ b/flatcamGUI/VisPyVisuals.py @@ -193,10 +193,10 @@ class ShapeGroup(object): class ShapeCollectionVisual(CompoundVisual): - def __init__(self, line_width=1, triangulation='vispy', layers=3, pool=None, **kwargs): + def __init__(self, linewidth=1, triangulation='vispy', layers=3, pool=None, **kwargs): """ Represents collection of shapes to draw on VisPy scene - :param line_width: float + :param linewidth: float Width of lines/edges :param triangulation: str Triangulation method used for polygons translation @@ -223,7 +223,7 @@ class ShapeCollectionVisual(CompoundVisual): # self._lines = [LineVisual(antialias=True) for _ in range(0, layers)] self._lines = [FlatCAMLineVisual(antialias=True) for _ in range(0, layers)] - self._line_width = line_width + self._line_width = linewidth self._triangulation = triangulation visuals_ = [self._lines[i // 2] if i % 2 else self._meshes[i // 2] for i in range(0, layers * 2)] @@ -262,7 +262,7 @@ class ShapeCollectionVisual(CompoundVisual): :param tolerance: float Geometry simplifying tolerance :param linewidth: int - Not used, for compatibility + Width of the line :return: int Index of shape """ @@ -276,6 +276,9 @@ class ShapeCollectionVisual(CompoundVisual): self.data[key] = {'geometry': shape, 'color': color, 'alpha': alpha, 'face_color': face_color, 'visible': visible, 'layer': layer, 'tolerance': tolerance} + if linewidth: + self._line_width = linewidth + # Add data to process pool if pool exists try: self.results[key] = self.pool.map_async(_update_shape_buffers, [self.data[key]]) @@ -459,7 +462,7 @@ class ShapeCollectionVisual(CompoundVisual): self.update_lock.acquire(True) # Merge shapes buffers - for data in list(self.data.values()): + for data in self.data.values(): if data['visible'] and 'line_pts' in data: try: line_pts[data['layer']] += data['line_pts'] diff --git a/flatcamTools/ToolCopperThieving.py b/flatcamTools/ToolCopperThieving.py index 9b1bc968..99c2a443 100644 --- a/flatcamTools/ToolCopperThieving.py +++ b/flatcamTools/ToolCopperThieving.py @@ -917,10 +917,10 @@ class ToolCopperThieving(FlatCAMTool): if self.cursor_pos is None: self.cursor_pos = (0, 0) - dx = curr_pos[0] - float(self.cursor_pos[0]) - dy = curr_pos[1] - float(self.cursor_pos[1]) + self.app.dx = curr_pos[0] - float(self.cursor_pos[0]) + self.app.dy = curr_pos[1] - float(self.cursor_pos[1]) self.app.ui.rel_position_label.setText("Dx: %.4f   Dy: " - "%.4f    " % (dx, dy)) + "%.4f    " % (self.app.dx, self.app.dy)) # draw the utility geometry if self.first_click: diff --git a/flatcamTools/ToolDistance.py b/flatcamTools/ToolDistance.py index 09c4cce7..61c4df42 100644 --- a/flatcamTools/ToolDistance.py +++ b/flatcamTools/ToolDistance.py @@ -598,7 +598,7 @@ class Distance(FlatCAMTool): else: color = '#FFFFFFFF' - self.sel_shapes.add(meas_line, color=color, update=True, layer=0, tolerance=None) + self.sel_shapes.add(meas_line, color=color, update=True, layer=0, tolerance=None, linewidth=2) if self.app.is_legacy is True: self.sel_shapes.redraw() diff --git a/flatcamTools/ToolNCC.py b/flatcamTools/ToolNCC.py index 7b44ebdf..ed43f9f3 100644 --- a/flatcamTools/ToolNCC.py +++ b/flatcamTools/ToolNCC.py @@ -1835,10 +1835,10 @@ class NonCopperClear(FlatCAMTool, Gerber): if self.cursor_pos is None: self.cursor_pos = (0, 0) - dx = curr_pos[0] - float(self.cursor_pos[0]) - dy = curr_pos[1] - float(self.cursor_pos[1]) + self.app.dx = curr_pos[0] - float(self.cursor_pos[0]) + self.app.dy = curr_pos[1] - float(self.cursor_pos[1]) self.app.ui.rel_position_label.setText("Dx: %.4f   Dy: " - "%.4f    " % (dx, dy)) + "%.4f    " % (self.app.dx, self.app.dy)) # draw the utility geometry if shape_type == "square": diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 9e955766..f0179501 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -1718,10 +1718,10 @@ class ToolPaint(FlatCAMTool, Gerber): if self.cursor_pos is None: self.cursor_pos = (0, 0) - dx = curr_pos[0] - float(self.cursor_pos[0]) - dy = curr_pos[1] - float(self.cursor_pos[1]) + self.app.dx = curr_pos[0] - float(self.cursor_pos[0]) + self.app.dy = curr_pos[1] - float(self.cursor_pos[1]) self.app.ui.rel_position_label.setText("Dx: %.4f   Dy: " - "%.4f    " % (dx, dy)) + "%.4f    " % (self.app.dx, self.app.dy)) # draw the utility geometry if shape_type == "square": From 9761e5e6fa0faaf47d50a60587a4ab2c34b72322 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 20 Apr 2020 05:12:36 +0300 Subject: [PATCH 186/209] - added a CHANGELOG file and changed the README file to contain the installation instructions --- CHANGELOG.md | 4520 +++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 4541 +------------------------------------------------- 2 files changed, 4556 insertions(+), 4505 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..fd8f483b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,4520 @@ +FlatCAM BETA (c) 2019 - by Marius Stanciu +Based on FlatCAM: 2D Computer-Aided PCB Manufacturing by (c) 2014-2016 Juan Pablo Caram +================================================= + +CHANGELOG for FlatCAM beta + +================================================= + +20.04.2020 + +- made the Grid icon in the status bar clickable and it will toggle the snap to grid function +- some mods in the Distance Tool +- added ability to use line width when adding shapes for both Legacy and OpenGL graphic engines +- added the linewidth=2 parameter for the Tool Distance utility geometry +- fixed a selection issue in Legacy graphic mode for single click +- added a CHANGELOG file and changed the README file to contain the installation instructions + +19.04.2020 + +- fixed a bug that did not allow to edit GUI elements of type FCDoubleSpinner if it contained the percent symbol +- some small optimizations in the GUI of Cutout Tool +- fixed more issues (new) in NCC Tool +- added a new layout named 'minimal' +- some PEP8 changes in Geometry Editor + +15.04.2020 + +- made sure that the Tcl commands descriptions listed on help command are aligned + +14.04.2020 + +- lightened the hue of the color for 'success' messages printed in the Tcl Shell browser +- modified the extensions all over such the names include also the extension name. For Linux who does not display the extensions in the native FileDialog. +- added descriptions for some of the methods in the app. +- added lightened icons for the dark theme from Leandro Heck + +13.04.2020 + +- added the outname parameter for the geocutout Tcl command +- multiple fixes in the Tcl commands (especially regarding the interchange between True/false and 1/0 values) +- updated the help for all Tcl Commands +- in Tcl Shell, the 'help' command will add also a brief description for each command in the list +- updated the App.plot_all() method giving it the possibility to be run as threaded or not +- updated the Tcl command PlotAll to be able to run threaded or not +- updated the Tcl commands PlotAll and PlotObjects to have a parameter that control if the objects are to be plotted or not on canvas; it serve as a disable/enable +- minor update to the autocomplete dictionary +- the Show Shell in Edit -> Preferences will now toggle the Tcl shell based on the current status of the Tcl Shell +- updated the Tcl command Isolate help for follow parameter +- updated DrillCncJob Tcl Command with new parameters and fixed it to work in the new format of the Excellon methods +- fixed issue #399 +- changed CncJob Tcl Command parameter 'depthperpass' to a shorter 'dpp' + +11.04.2020 + +- fixed issue #394 - the saveDialog in Linux did not added the selected extension +- when the Save button is clicked in the Edit -> Preferences the Preferences tab is closed. + +10.04.2020 + +- made sure that the timeout parameter used by some Tcl Commands is seen as an integer in all cases - fixed issue #389 +- minor changes in Paint Tool +- minor changes in GUI (Save locations in Menu -> File) and the key shortcuts - fixed issue #391 + + +9.04.2020 + +- if FlatCAM is not run with Python version >= 3.5 it will exit. +- modified all CTRL+ with Ctrl+ and all ALT+ with Alt+ and all SHIFT+ with Shift+. Fixed issue #387. +- removed some packages from setup_ubuntu.sh as they are not needed in FlatCAM beta + +8.4.2020 + +- fixed the Tcl Command Delete to have an argument -f that will force deletion evading the popup (if the popup is enabled). The sme command without a name now will delete all objects +- fixed the Tcl Command JoinExcellons +- fixed the Tcl Command JoinGeometry +- fixed the Tcl Command Mirror +- updated the Tcl Command Mirror to use a (X,Y) origin parameter. Works if the -box parameter is not used. +- updated the Tcl Command Offset. Now it can use only -x or -y parameter no longer is mandatory to have both. The one that is not present will be assumed 0.0 +- updated the Tcl Command Panelize. The -rows and -columns parameters are no longer both required. If one is not present then it is assumed to be zero. +- updated the Tcl Command Scale. THe -origin parameter can now be a tuple of (x,y) coordinates. +- updated the Tcl Command Skew. Now it can use only -x or -y parameter no longer is mandatory to have both. The one that is not present will be assumed 0.0 +- updated the help for all the Tcl Commands + +6.04.2020 + +- added key shortcuts (arrow up/down) that will select the objects in the Project tab if the focus is in that tab +- added a minor change to the ListSys Tcl command +- fixed an crash generated when running the Tool Database from the Menu -> Options menu entry +- fixed a bug in handling the UP/DOWN key shortcuts that caused a crash when no object was selected in the Project Tab; also made sure that the said keys are handled only for the Project Tab +- some PEP8 changes and other minor changes +- updated the requirements file +- updated the 2Sided Tool by not allowing the Gerber file to be mirrored without a valid reference and added some placeholder texts + +5.04.2020 + +- made sure that the HDPI scaling attribute is set before the QApplication is started +- made sure that when saving a project, the app will try to update the active object from UI form only if there is an active object +- fix for contextual menus on canvas when using PyQt versions > 5.12.1 +- decision on which mouse button to use for panning is done now once when setting the plotcanvas +- fix to work with Python 3.8 (closing the application) +- fixed bug in Gerber parser that allowed loading as Gerber of a file that is not a Gerber +- fixed a bug in extension detection for Gerber files that allowed in the filtered list files that extension *.gb* +- added a processEvents method in the Gerber parser parse_lines() method +- fixed issue #386 - multiple Cut operation on a edited object created a crash due of the bounds() method +- some changes in the Geometry UI + +4.04.2020 + +- fixed the Repeated code parsing in Excellon Parse + +1.04.2020 + +- updated the SVG parser to take into consideration the 'Close' svg element and paths that are made from a single line (we may need to switch to svgpathtools module) +- minor changes to increase compatibility with Python 3.8 +- PEP8 changes + +30.03.2020 + +- working to update the Paint Tool +- fixed some issues in Paint Tool + +29.03.2020 + +- modified the new database to accept data from NCC and Paint Tools +- fixed issues in the new database when adding the tool in a Geometry object +- fixed a bug in Geometry object that generated a change of dictionary while iterating over it +- started to add the new database links in the NCC and Paint Tools +- in the new Tools DB added ability to double click on the ID in the tree widget to execute adding a tool from DB +- working in updating NCC Tool + +28.03.2020 + +- finished the new database based on a QTreeWidget + +21.03.2020 + +- fixed Cutout Tool to work with negative values for Margin parameter + +20.03.2020 + +- updated the "re-cut" feature in Geometry object; now if the re-cut parameter is non zero it will cut half of the entered distance before the isolation end and half of it after the isolation end +- added to Paint and NCC Tool a feature that allow polygon area selection when the reference is selected as Area Selection +- in Paint Tool and NCC Tool added ability to use Escape Tool to cancel Area Selection and for Paint Tool to cancel Polygon Selection +- fixed issue in "re-cut" feature when combined with multi-depth feature +- fixed bugs in cncjob TclCommand + +13.03.2020 + +- fixed a bug in CNCJob generation out of a Excellon object; the plot failed in case some of the geometry of the CNCJob was invalid +- fixed Properties Tool due of recent changes to the FCTree widget + +12.03.2020 + +- working on the new database +- fix a bug in the TextInputTool in FlatCAM Geometry Editor that crashed the sw when some fonts are not loaded correctly + +4.03.2020 + +- updated all the FlatCAM Tools and the Gerber UI FCComboBoxes to update the box value with the latest object loaded in the App +- some fixes in the NCC Tool +- modified some strings + +02.03.2020 + +- added property that allow the FCComboBox to update the view with the last item loaded; updated the app to use this property + +01.03.2020 + +- updated the CutOut Tool such that while adding manual gaps, the cutting geometry is updated on-the-fly if the gap size or tool diameter parameters are adjusted +- updated the UI in Geometry Editor + +29.02.2020 + +- compacted the NCC Tool UI by replacing some Radio buttons with Combo boxes due of too many elements +- fixed error in CutOut Tool when trying to create a FreeFrom Cutout out of a Gerber object with the Convex Shape checked +- working on a new type of database + +28.02.2020 + +- some small changes in preprocessors +- solved issue #381 where there was an error when trying to generate CNCJob out of an Excellon file that have a tool with only slots and no drills +- solved some issues in the preprocessors regarding the newly introduced feature that allow control of the final move X,Y positions + +25.02.2020 + +- fixed bug in Gerber parser: it tried to calculate a len() for a single element and not a list - a Gerber generated by Eagle exhibited this +- added a new parameter named 'End Move X,Y' for the Geometry and Excellon objects. Adding a tuple of coordinates in this field will control the X,Y position of the final move; not entering a value there will cause not to make an end move + +20.02.2020 + +- in Paint Tool replaced the Selection radio with a combobox GUI element that is more compact +- in NCC Tool modified the UI + +19.02.2020 + +- fixed some issues in the Geometry Editor; the jump signal disconnect was failing for repeated Editor tool operation +- fixed an issue in Gerber Editor where the multiprocessing pool was reported as closed and an ValueError exception was raised in a certain scneraio +- on Set Origin, Move to Origin and Move actions for Gerber and Excellon objects the source file will be also updated (the export functions will export an updated object) +- in FlatCAMObj.export_gerber() method took into account the possibility of polygons of type 'clear' (the ones found in the Gerber files under the LPC command) + +17.02.2020 + +- updated the Excellon UI to hold data for each tool +- in Excellon UI removed the tools table column for Offset Z and used the UI form parameter +- updated the Excellon Editor to add for each tool a 'data' dictionary +- updated all FlatCAM tools to use the new confirmation message that show if the entered value is within range or outside +- updated all FlatCAM tools to use the new confirmation message for QSpinBoxes, too +- in Excellon UI protected the values that are common parameters from change on tool selection change +- fixed some issues related to the usage of the new confirmation message in FlatCAM Tools +- made sure that the FlatCAM Tools UI initialization is done only in set_tool_ui() method and not in the constructor +- adapted the GCode generation from Excellon to work with multiple tools data and modified the preprocessors header +- when multiple tools are selected in Excellon UI and parameters are modified it will applied to all selected +- in Excellon UI, Paint Tool and NCC Tool finished the "Apply parameters to all tools" functionality +- updated Paint Tool and NCC Tool in the UI functionality +- fixed the Offset spinbox not being controller by offset checkbox in NCC Tool + +16.02.2020 + +- small update to NCC Tool UI + +15.02.2020 + +- in Paint Tool added a new method of painting named Combo who will pass through all the methods until the polygon is cleared +- in Paint Tool attempting to add a new mode suitable for Laser usage +- more work in the new Laser Mode in the Paint Tool +- modified the Paint Tool UI + +14.02.2020 + +- adjusted the UI for Excellon and Geometry objects +- added a new FlatCAM Tool: Gerber Invert Tool. It will invert the copper features in a Gerber file: where is copper there will be empty and where is empty it will be copper +- added the Preferences entries for the Gerber Invert Tool + +13.02.2020 + +- finished Punch Gerber Tool +- minor changes in the Tool Transform and Tool Calculators UI to bring them up2date with the other tools + +12.02.2020 + +- working on fixing a bug in FlatCAMGeometry.merge() - FIXED issue #380 +- fixed bug: when deleting a FlatCAMCNCJob with annotations enabled, the annotations are not deleted from canvas; fixed issue #379 +- fixed bug: creating a new project while a project is open and it contain CNCJob annotations and/or Gerber mark shapes, did not delete them from canvas + +11.02.2020 + +- working on Tool Punch; finished the geometry update with the clear geometry for the case of Excellon method +- working on Tool Punch; finished the geometry update with the clear geometry for the case of Fixed Diameter method + +10.02.2020 + +- optimized the Paint and NCC Tools. When the Lines type of painting/clearing is used, the lines will try to arrange themselves on the direction that the lines length clearing the polygon are bigger +- solved bug that made drilling with Marlin preprocessor very slow +- applied the fix for above bug to the TclCommand Drillcncjob too +- started a new way to clear the Gerber polygons based on the 'follow' lines +- some cleanup and bug fixes for the Paint Tool + + +8.02.2020 + +- added a new preprocessor for using laser on a Marlin 3D printer named 'Marlin_laser_use_Spindle_pin' +- modified the Geometry UI when using laser preprocessors +- added a new preprocessor file for using laser on a Marlin motion controller but with the laser connected to one of the FAN pins, named 'Marlin_laser_use_FAN_pin' +- modified the Excellon GCode generation so now it can use multi depth drilling; modified the preprocessors to show the number of passes + +5.02.2020 + +- Modified the Distance Tool such that the Measure button can't be clicked while measuring is in progress +- optimized selection of drills in the Excellon Editor +- fixed bugs in multiple selection in Excellon Editor +- fixed selection problems in Gerber Editor +- in Distance Tool, when run in the Excellon or Gerber Editor, added a new option to snap to center of the geometry (drill for Excellon, pad for Gerber) + +3.02.2020 + +- modified Spinbox and DoubleSpinbox Custom UI elements such that they issue a warning status message when the typed value is out of range +- fixed the preprocessors with 'laser' in the name to use the spindle direction set in the Preferences +- increased the upper limit for feedrates by an order of magnitude + +2.02.2020 + +- fixed issue #376 where the V-Shape parameters from Gerber UI are not transferred to the resulting Geometry object if the 'combine' checkbox is not checked in the Gerber UI +- in Excellon UI, if Basic application mode is selected in Preferences, the Plot column 'P' is hidden now because some inexperienced users mistake this column checkboxes for tool selection +- fixed an error in Gerber Parser; the initial values for current_x, current_y were None but should have been 0.0 +- limited the lower limit of angle of V-tip to a value of 1 because 0 makes no sense +- small changes in Gerber UI +- in Geometry Editor make sure that after an edit is finished (correctly or forced) the QTree in the Editor UI is cleared of items + +31.01.2020 + +- added a new functionality, a variation of Set Origin named Move to Origin. It will move a selection of objects to origin such as the bottom left corner of the bounding box that fit them all is in origin. +- fixed some bugs +- fixed a division by zero error: fixed #377 + +30.01.2020 + +- remade GUI in Tool Cutout, Tool Align Objects, Tool Panelize +- some changed in the Excellon UI +- some UI changes in the common object UI + +29.01.2020 + +- changes in how the Editor exit is handled +- small fix in some pywin32 imports +- remade the GUI + small fixes in 2Sided Tool +- updated 2Sided Tool + +28.01.2020 + +- some changes in Excellon Editor + +27.01.2020 + +- in Geometry Editor made sure that on final save, for MultiLineString geometry all the connected lines are merged into one LineString to minimize the number of vertical movements in GCode +- more work in Punch Gerber Tool +- the Jump To popup window will now autoselect the LineEdit therefore no more need for an extra click after launching the function +- made some structural changes in Properties Tool +- started to make some changes in Geometry Editor +- finished adding in Geometry Editor a TreeWidget with the geometry shapes found in the edited object + +24.02.2020 + +- small changes to the Toolchange manual preprocessor +- fix for plotting Excellon objects if the color is changed and then the object is moved +- laying the GUI for a new Tool: Punch Gerber Tool which will add holes in the Gerber apertures +- fixed bugs in Minimum Distance Tool +- update in the GUI for the Punch Gerber Tool + +22.01.2020 + +- fixed a bug in the bounding box generation + +19.01.2020 + +- fixed some bugs that are visible in Linux regarding the ArgsThread class: on app close we need to quit the QThread running the ArgsThread class and also close the opened Socket +- make sure that the fixes above apply when rebooting app for theme change or for language change +- fixed and issue that made setting colors for the Gerber file not possible if using a translation +- made possible to set the colors for Excellon objects too +- added to the possible colors the fundamentals: black and white +- in the project context menu for setting colors added the option to set the transparency and also a default option which revert the color to the default value set in the Preferences + +17.01.2020 + +- more changes to Excellon UI +- changes to Geometry UI +- more work in NCC Tool upgrade; each tool now work with it's own set of parameters +- some updates in NCC Tool +- optimized the object envelope generation in the redesigned NCC Tool + +16.01.2020 + +- updated/optimized the GUI in Preferences for Paint Tool and for NCC Tool +- work in Paint Tool to bring it up to date with NCC Tool +- updated the GUI in preferences for Calculator Tool +- a small change in the Excellon UI +- updated the Excellon and Geometry UI to be similar +- put bases for future changes to Excellon Object UI such that each tool will hold it's own parameters +- in ParseExcellon.Excellon the self.tools dict has now a key 'data' which holds a dict with all the default values for Excellon and Geometry +- Excellon and Geometry objects, when started with multiple tools selected, the parameters tool name reflect this situation +- moved default_data data update from Excellon parser to the Excellon object constructor + +15.01.2020 + +- added key shortcuts and toolbar icons for the new tools: Align Object Tool (Alt+A) and Extract Drills (Alt+I) +- added new functionality (key shortcut Shift+J) to locate the corners of the bounding box (and center) in a selected object +- modified the NCC Tool GUI to prepare for accepting a tool from a tool database +- started to modify the Paint Tool to be similar to NCC Tool and to accept a tool from a database +- work in Paint Tool GUI functionality + +14.01.2020 + +- in Extract Drill Tool added a new method of drills extraction. The methods are: fixed diameter, fixed annular ring and proportional +- in Align Objects Tool finished the Single Point method of alignment +- working on the Dual Point option in Align Objects Tool - angle has to be recalculated +- finished Dual Point option in Align Objects Tool + +13.01.2020 + +- fixed a small GUI issue in Excellon UI when Basic mode is active +- started the add of a new Tool: Align Objects Tool which will align (sync) objects of Gerber or Excellon type +- fixed an issue in Gerber parser introduced recently due of changes made to make Gerber files produced by Sprint Layout +- working on the Align Objects Tool + +12.01.2020 + +- improved the circle approximation resolution +- fixed an issue in Gerber parser with detecting old kind of units +- if CTRL key is pressed during app startup the app will start in the Legacy(2D) graphic engine compatibility mode + +11.01.2020 + +- fixed an issue in the Distance Tool +- expanded the Extract Drills Tool to use a particular annular ring for each type of aperture flash (pad) +- Extract Drills Tool: fixed issue with oblong pads and with pads made from aperture macros +- Extract Drills Tool: added controls in Edit -> Preferences + +10.02.2020 + +- working on a new tool: Extract Drills Tool who will create a Excellon object out of the apertures of a Gerber object +- finished the GUI in the Extract Drills Tool +- fixed issue in Film Tool where some parameters names in calls of method export_positive() were not matching the actual parameters name +- finished the Extract Drills Tool +- fixed a small issue in the DoubleSided Tool + +8.01.2020 + +- working in NCC Tool +- selected rows in the Tools Tables will stay colored in blue after loosing focus instead of the default gray +- in NCC Tool the Tool name in the Parameters section will be the Tool ID in the Tool Table +- added an exception catch in case the plotcanvas init failed for the OpenGL graphic engine and warn user about what happened + +7.01.2020 + +- solved issue #368 - when using the Enable/Disable prj context menu entries the plotted status is not updated in the object properties +- updates in NCC Tool + +6.01.2020 + +- working on new NCC Tool + +2.01.2020 + +- started to rework the NCC Tool GUI in preparation for adding a Tool DB feature +- for auto-completer, now clicking an entry in the completer popup will select that entry and insert it +- made available only for Linux and Windows (not OSX) the starting of the thread that checks if another instance of FlatCAM is already running at the launch of FLatCAM +- modified Toggle Workspace function to work in the new Preferences UI configuration +- cleaned the app from progress signal usage since it is not used anymore + +1.01.2020 + +- fixed bug in NCC Tool: after trying to add a tool already in the Tool Table when trying to change the Tool Type the GUI does not change +- final fix for app not quiting when running a script as argument, script that has the quit_flatcam Tcl command; fixed issue #360 +- fixed issue #363. The Tcl command drillcncjob does not create tool cut, does not allow creation of gcode, it forces the usage of dwell and dwelltime parameters +- in NCC Tool I've added a warning so the user is warned that the NCC margin has to have a value of at least the tool diameter that is doing an iso_op job in the Tool Table +- modified the Drillcncjob and Cncjob Tcl commands to be allowed to work without the 'dwell' and 'toolchange' arguments. If 'dwelltime' argument is present it will be assumed that the 'dwell' is True and the same for 'toolchangez' parameter, if present then 'toolchange' will be assumed to be True, else False +- modified the extracut and multidepth parameters in Cncjob Tcl command like for dwell and toolchange +- added ability for Tcl commands to have optional arguments with None value (meaning missing value). This case should be treated for each Tcl command in execute() method +- fixed the Drillcncjob Tcl command by adding an custom self.options key "Tools_in_use" and build it's value, in case it does not exist, to make the toolchange command work +- middle mouse click on closable tabs will close them + +30.12.2019 + +- Buffer sub-tool in Transform Tool: added the possibility to apply a factor effectively scaling the aperture size thus the copper features sizes +- in Transform Tool adjusted the GUI +- fixed some decimals issues in NCC Tool, Paint Tool and Excellon Editor (they were still using the hardcoded values) +- some small updates in the NCC Tool +- changes in the Preferences UI for NCC and Paint Tool in Tool Dia entry field +- fixed Tcl commands that use the overlap parameter to switch from fraction to percentage +- in Transform Tool made sure that the buffer sub-tool parameters are better explained in tooltips +- attempt to make TclCommand quit_flatcam work under Linux +- some fixes in the NCC Tcl command (using the bool() method on some params) +- another attempt to make TclCommand quit_flatcam work under Linux +- another attempt to make TclCommand quit_flatcam work under Linux - use signal to call a hard exit when in Linux +- TclCommand quit_flatcam work under Linux + +29.12.2019 + +- the Apply button text in Preferences is now made red when changes were made and require to be applied +- the Gerber UI is built only once now so the process is lighter on CPU +- the Gerber apertures marking shapes storage is now built only once because the more are built the more sluggish is the interface +- added a new function called by shortcut key combo Ctrl+G when the current widget in Plot Area is an Code Editor. It will jump to the specified line in the text. +- fixed a small bug where the app tried to hide a label that I've removed previously +- in Paint Tool Preferences is allowed to add a list of initial tools separated by comma +- in Geometry Paint Tool fixed the Overlap rate to work between 0 and 99.9999% + +28.12.2019 + +- more updates to the Preferences window and in some other parts of the GUI +- updated the translations (less Russian) +- fixed a minor issue that when saving a project with CNCJob objects, the variable that holds the origin of the CNCJob object was not saved in the project. Added to the serializable objects also the exc_cnc_tools dictionary +- some changes in the File menu + +28.12.2019 + +- updated all the translations files +- fixed the big mouse cursor in OpenGL(3D) graphic mode to get the set color +- fixed the cursor to have the set color and set cursor width in the Legacy(2D) graphic engine +- in Legacy(2D) graphic mode fixed the cursor toggle when the big cursor is activated +- in Legacy(2D) fixed big mouse cursor to snap to the grid +- RELEASE 8.991 + +27.12.2019 + +- updated the POT file and the translation files for German, Spanish and French languages +- fixed some typos + +26.12.2019 + +- modified the ToolDB class and changed some strings +- Preferences classes now have access to the App attributes through app.setup_obj_classes() method +- moved app.setup_obj_classes() upper in the App.__init__() +- added a new Preferences setting allowing to modify the mouse cursor color +- remade the GUI in Preferences -> General grouping the settings in a more clear way +- made available the Jump To function in Excellon Editor +- added a clean_up() method in all the Editor Tools that need it, to be run when aborting using the ESC key +- fixed an error in the Gerber parser; it did not took into consideration the aperture size declared before the beginning of a Gerber region. Detected for Gerber files generated by KiCAD 5.x +- in Panelize Tool made sure that for Gerber objects if one of the apertures is without geometry then it is ignored +- further modifications in Preferences -> General GUI +- further modifications in Preferences -> General GUI - extended the changes +- in Legacy(2D) graphic engine made to work the mouse color change +- theme changing is no longer auto-reboot upon change; it require now to press a button +- cleaned the Preferences classes and added the signals and signal slots in those classes, removing them from the main app class +- each FlatCAM object found in Preferences has it's own set of controls for changing the colors +- added a set of gray icons to be used when the theme is complete dark (for now it is useful only for MacOS with dark theme because at the moment the app is not styled to dark UI except the plot area) + +25.12.2019 + +- fixed an issue in old default file detection and in saving the factory defaults file +- in Preferences window removed the Import/Export Preferences buttons because they are redundant with the entries in the File -> Menu -> Backup. and added a button to Restore Defaults +- when in Basic mode the Tool type of the tool in the Geometry UI Tool Table after isolating a Gerber object is automatically selected as 'C1' +- let the multiprocessing Pool have as many processes as needed +- added a new Preferences setting allowing a custom mouse line width (to make it thicker or thinner) +- changed the extension of the Tool Database file to FlatDB for easy recognition (in the future double clicking such a file might import the new tools in the FC database) + +24.12.2019 + +- edited some icons so they don't contain white background +- fixed an incorrect usage of object in the app.select_objects() method +- fixed a typo in ToolDB.on_tool_add() + +23.12.2019 + +- some fixes in the Legacy(2D) graphic mode regarding the possibility of changing the color of the Gerber objects +- added a method to darken the outline color for Gerber objects when they have the color set +- when Printing as PDF Gerber objects now the rendered color is the print color +- speed up the plotting in OpenGL(3D) graphic mode +- speed up the color setting for Gerber object when using the OpenGL(3D) graphic mode +- setting color for Gerber objects work on a selection of Gerber objects +- ~~when the selection is changed in the Project Tree the selection shape on canvas is deleted~~ +- if an object is selected on Project Tree and it does not have the selection shape drawn, first click on canvas over it will draw the selection shape +- in Tool Transform added a new feature named 'Buffer'. For Geometry and Gerber objects will create (and replace) a geometry at a distance from the original geometry and for Excellon will adjust the Tool diameters +- solved issue #355 - when the tool diameter field in the Edit → Preferences → Geometry → Geometry General → Tools → Tool dia is only one the app failed to read it +- solved issue #356 - in Tools DB can not be added more than one tool if a translation is active +- some changes related to the fact that the geometry default tool diameter value can be comma separated string of tool diameters + +22.12.2019 + +- added a new option for the Gerber objects: on the project context menu now can be chosen a color for the selected Gerber object +- fixed issue in Gerber UI where a label was not hidden when in Basic mode +- added the color parameters of the objects to the serializable attributes +- fixed Gerber object color set for Legacy(2D) graphic engine; glitch on the OpenGL(3D) graphic engine +- fixed the above mentioned glitch in the OpenGL(3D) graphic engine when an Gerber object has been set with a color + +21.12.2019 + +- fixed a typo in Distance Tool + +20.12.2019 + +- fixed a rare issue in the generation of non-copper-region geometry started from the Gerber Object UI (selected tab) +- Print function is now printing a PDF file for a selection of objects in the colors from canvas +- added an icon in the infobar that will show more clearly the status of the grid snapping +- in Geometry Object UI (selected tab) when a tool type is changed from no matter what to V-shape, the cut_z value is saved and when the tool type is changed back to something different than V-shape, this saved cut-z value is restored +- fixed re-cut length entry not staying disabled when the re-cut cb is not checked + +19.12.2019 + +- in 2-Sided Tool added a way to calculate the bounding box values for a selection of objects, and also the centroid +- in 2-Sided Tool fixed the Reset Tool button handler to reset the bounds value too; changed a string +- added Preferences values for PDF margins when saving text in Code Editor as PDF +- when clicking Cancel in Preferences now the values are reverted to what they used to be before opening Preferences tab and start changing values +- starting to work to a general Print function; for now it will generate PDF files; currently it works only for one object not for a selection +- added shortcut key Ctrl+P for printing to PDF method + +18.12.2019 + +- added new parameters to improve Gerber parsing +- small optimizations in the Preferences UI +- the Jump To function reference is now saving it's last used value +- added the ability to use the Jump To method in the Gerber Editor +- improved the loading of Config File by using the advanced code editor +- fixed a bug in the new feature 'extra buffering' +- fixed the creation of CNCJob objects out of multigeo Geometry objects (objects with multiple tools) +- optimized the NCC Tool + +17.12.2019 + +- more optimizations in NCC Tool +- optimizations in Paint Tool +- maximum range for Cut Z is now zero to deal with the situation when using V-shape with tip-dia same value with cut width +- modified QValidator in FCDoubleSpinner() GUI element to allow entering the minus sign when the range maximum is set as 0.0; also for positive numbers allowed entering the symbol plus +- made sure that if in Gerber UI the isolation is made with a V-Shape tool then the tool type is automatically updated on the generated Geometry Object +- added ability to save the Source File as PDF (still have to adjust the page size) +- fixed the generate_from_geometry_2() method to use the default values in case the parameters are None +- added ability to save the Source File as PDF - fixed page size and added line breaks +- more mods to generate_from_geometry_2() method +- fixed bug saving the FlatCAM project saying the file is used by another application +- fixed issue #347 - a Gerber generated by Sprint Layout with copper pour ON will not have rendered the copper pour + +16.12.2019 + +- in Geometry Editor added support for Jump To function such as that it works within the Editor Tools themselves. For now it works only in absolute jumps +- modified the Jump To method such that now allows relative jump from the current mouse location +- fixed the Defaults upgrade overwriting the new version number with the old one +- fixed issue with clear_polygon3() - the one who makes 'lines' and fixed the NCC Tool +- some small changes in the FlatCAMGeometry.on_tool_add() method +- made sure that in Geometry Editor the self.app.mouse attribute is updated with the current mouse position (x, y) +- updated the preprocessor files +- fixed the HPGL preprocessor +- fixed the CNCJob geometry created with HPGL preprocessor +- fixed GCode generated with HPGL preprocessor to output only integer coordinates +- fixed the HPGL2 import parsing for absolute linear movements +- fixed the line endings for setup_ubuntu.sh + +15.12.2019 + +- fixed a bug that created a crash in special conditions; it's related to the QSettings in FlatCAMGui.py +- added a script to remove the bad profiles from resource pictures. From here: https://stackoverflow.com/questions/22745076/libpng-warning-iccp-known-incorrect-srgb-profile/43415650, link mentioned by @camellan (Andrey Kultyapov) +- prepared the application for usage of dark icons in case of using the dark theme +- updated the languages +- fixed a typo +- fixed layout on first launch of the app +- fixed some issues with the recent preparation for dark icons resource usage +- added a new preprocessor file contributed by Daniel Friderich and added fixes for it +- modified the export_gcode() method and the preprocessors such that the preprocessors now have the information if to include the gcode header +- updated all the translation PO files and the POT file +- RELEASE 8.99 + +14.12.2019 + +- finished the strings update in the Google-translated Spanish +- finished the strings update in the Google-translated French + +13.12.2019 + +- HPGL2 import: added support for circles, arcs and 3-point arcs. Everything works only for absolute coordinates. +- removed the .plt extension from Gcode extensions +- some strings updated; update on the Romanian translate +- more strings updated; finished the Romanian translation update +- some work in updating the Spanish Google-translation +- small updates (Google Translate) in Russian and Brazilian-PT languages + +12.12.2019 + +- finished the Calibration Tool +- changed the Scale Entry in Object UI to FCEntry() GUI element in order to allow expressions to be entered. E.g: 1/25.4 +- some small changes in the Scale button handler in FlatCAMObj() class +- added option to save objects as PDF files in File -> Save menu +- optimized the FlatCAMGerber.clear_plot_apertures() method +- some changes in the ObjectUI and for the Geometry UI +- finished a very rough and limited HPGL2 file import + +11.12.2019 + +- started work in HPGL2 parser +- some more work in Calibration Tool + +10.12.2019 + +- small changes in the Geometry UI +- now extracut option in the Geometry Object will recut as many points as many they are within the specified re-cut length +- if extracut_length is zero then the extracut will cut up until the first point in path no matter what the distance is +- in Gerber isolation, when selection mode is checked, now area selection works too +- in CNCJob UI, now the CNCJob objects made out of Excellon objects will display their CNC tools (drill bits) +- fixed a cumulative error when using the Tool Offset for Excellon objects +- added the display of the real depth of cut (cut z + offset_z) for CNC tools made out of an Excellon object +- for OpenGL graphic mode added a fit_view() execution on canvas initialization +- fixed Excellon scaling the UI values +- replaced the SpindleSpeed entry with a FCSpinner() GUI element; if speed is set to 0 it will amount to None + +9.12.2019 + +- updated the border for fit view on OpenGL graphic mode +- Calibration Tool - added preferences values +- Calibration Tool - more work on it +- reverted this change: "selected object in Project used to ask twice for UI build" because it will not build the UI when a tab is closed for Document object and the object is selected +- fixed issue after Geometry object edit; the GCode made from an edited object did not reflect the changes in the object +- in Object UI, the Scale FCDoubleSpinner will no longer work for Return key press due of issues of unwanted scaling on focusOut event +- in FlatCAMGeometry fixed the scale and offset methods to always process the self.solid_geometry +- Calibration Tool - finished the calibrated object creation method +- updated the POT file +- fixed an error in the German PO file +- updated the languages PO files +- some fixes on the app.jump_to() method +- made sure that the ToolFilm will not start saving a file if there are no objects loaded +- some fixes on the app.jump_to() method for the Legacy(2D) graphic mode + +8.12.2019 + +- Calibrate Tool - rearranged the GUI +- in Geometry UI made sure that the Label that points to the Tool parameters show clearly that those parameters apply only for the selected tool +- fixed an small issue in Object UI +- small fixes: selected object in Project used to ask twice for UI build; if scale factor in Object UI is 1 do nothing as there is no point in scaling with a factor of 1 +- in Geometry UI added a button that allow updating all the tools in the Tool Table with the current values in the UI form +- updated Tcl commands to make use of either 0 or False for False value or 1 or True for True in case of a parameter with type Bool + +7.12.2019 + +- renamed Calibrate Excellon Tool to a simpler Calibrate Tool +- Calibrate Tool - when generating verification GCode it will always load into an Editor from which it can be edited and/or saved. On save the editor will close. +- updated the CNCJob and Drillcncjob Tcl Commands to use 0 and 1 as values for the parameters that are stated as of bool type, beside the normal keywords of False and True +- Calibrate Tool - working on it + +6.12.2019 + +- fixed the toggle_units() method so now the grid values are accurate to the decimal +- cleaned up the Excellon parser and fixed some bugs (old and new); Excellon parser has it's own convert_units() method no longer inheriting from Geometry +- in Excellon UI fixed bug that did not allow editing of the Offset Z parameter from the Tool table +- in Properties Tool added new information's for the tools in the CNCjob objects +- few bugs solved regarding the newly created empty objects +- changed everywhere the name "preprocessor" with "preprocessor" +- updated the preprocessor files in the toolchange section in order to avoid a graphical representation of travel lines glitch +- fixed a GUI glitch in the Excellon tool table +- added units to some of the parameters in the Properties Tool + +5.12.2019 + +- in NCC Tool, the new Geometry object that is created on copper clear now has the solid_geometry attribute where the geometry is stored not only in the obj.tools attribute +- Copper Thieving Tool - added units label for the pattern plated area +- Properties Tool - added a new parameter, the copper area which show the area of the copper features for the Gerber objects +- Copper Thieving Tool - added a default value for the mask clearance when generating pattern plating mask +- application wide change: introduced the precision parameters in Edit -> Preferences who will control how many decimals to use in the app parameters +- changed the FCDoubleSpinner, FCSpinner and FCEntry GUI elements to allow passing an alignment value: left, right or center (not yet available in the app) +- fixed the GUI of the Geometry Editor Tool Transform and adapted it to use the precision setting +- updated Gerber Editor to use the precision setting and the Gerber Editor Transform Tool to use the FCDoubleSpinner GUI element +- in Properties Tool added more information's regarding the Excellon tools, about travelled distance and job time; fixed issues when doing Properties on the CNCjob objects +- TODO: I need to solve the mess in units conversion: it's too convoluted + +4.12.2019 + +- made sure that if an older preferences file is detected then there are no errors and only the parameters that are currently active are loaded; the factory defaults file is deleted and recreated in the new format +- in Preferences added a new button: 'Close' to close the Preferences window without saving +- fixed bug in FCSpinner and FCDoubleSpinner GUI elements, that are now the main GUI element in FlatCAM, that made partial selection difficult +- updated the Paint Tool in Geometry Editor to use the FCDoubleSpinner +- added the possibility for suffix presence on the FCSpinner and FCDoubleSpinner GUI Elements +- added the '%' symbol for overlap fields; I still need to divide the content by 100 to get the original (0 ... 1) value +- fixed the overlap parameter all over the app to reflect the change to percentage +- in Copper Thieving Tool added the display of the patterned plated area (approximate area) +- Copper Thieving Tool - updated the way plated area is calculated making it a bit more precise but still it is a bit bigger than the actual area +- fixed the Copy Object function to copy also the source_file content +- Copper Thieving Tool - when the clearance value for the pattern plating mask is negative it will be applied to the origin soldermask too +- modified the GUI in all tools making the text of the buttons bold and adding a new button named Reset Tool which have to reset the tool GUI and variables (need to check all tools to see if happen) +- when the Tool tab is in focus, clicking on canvas will no longer change the focus to Project tab +- Copper Thieving Tool - when creating the pattern platting mask will make a new Gerber object with it +- small fix in the GUI layout in Gerber Editor + +3.12.2019 + +- in Preferences added an Apply button which apply the modified preferences but does not save to a file, minimizing the file IO operations; Ctrl+S key combo does the Apply now. +- updated some of the default values to metric, values that were missed previously +- remade the Gerber Editor way to import an Gerber object into the editor in such a way to use the multiprocessing +- various small fixes +- fix for toggle grid lines updating canvas only after moving the mouse (hack, actually) +- some changes in the UI layout in Cutout Tool +- added some geometry parameters in Cutout Tool as a convenience, to be passed to the generated Geometry objects + +2.12.2019 + +- fixed issue #343; updated the Image Tool +- improvements in Importing SVG as Gerber - added an automatic source generation (it is not infallible) +- a hack to import correctly the QRCode exported as SVG from FlatCAM +- added 3 new tcl commands: export dxf, export excellon and export gerber +- added a Cancel button in Tools DB when requesting to add a tool in the Geometry Tool Table +- modified the default values for the METRIC system; the app now starts in the METRIC units since the majority of the world use the METRIC units system +- small changes, updated the estimated release date +- Tool Copper Thieving - added pattern plating mask generation feature + +28.11.2019 + +- small fixes in NCC Tool and in the FlatCAMGeometry class + +27.11.2019 + +- in Tool Film added the page size and page orientation in case of saving the film as PDF file +- the application workspace has now a lot more options selectable in the Edit -> Preferences -> General -> GUI Preferences +- updated the drawing of the workspace such that the application overall start time is improved and after first turn on of the workspace, toggling it will have no performance penalty +- updated the workspace functions to work in Legacy(2D) graphic mode +- adjusted the selection color transparency for the Legacy(2D) graphic mode because it was too transparent for the fill + +26.11.2019 + +- updated the Film Tool to allow exporting PDF and PNG file (besides the SVG file) + +25.11.2019 + +- In Gerber isolation changed the UI +- in Gerber isolation added the option to selectively isolate only certain polygons +- made some optimizations in FlatCAMGerber.isolate() method +- updated the 'single' isolation of Gerber polygons to remove the polygon if clicked on it and it is already in the list of single polygons to be isolated +- clicking to add a polygon when doing Single type isolation will add a blue shape marking the selected polygon, second click will remove that shape +- fixed bugs in Paint Tool when painting single polygon +- in Gerber isolation added the option to selectively isolate only certain polygons - made it to work for Legacy(2D) graphic mode +- remade the Paint Tool - single polygon painting; now it can single paint a list of polygons that are clicked onto (right click will start the actual painting) + +23.11.2019 + +- in Tool Fiducials added a new fiducial type: chess pattern +- work in Calibrate Excellon Tool +- fixed the line numbers in the TextPlainEdit to fit all digits of the line number; activated the line numbers for FlatCAMScript objects too +- line numbers in the TextPlainEdit for the selected line are bold +- made sure that the self.defaults dictionary is deepcopy-ed in the self.options dictionary +- made sure that the units are read from the self.defaults and not from the GUI +- added Robber Bar option to Copper Thieving Tool + +22.11.2019 + +- Tool Fiducials - added GUI in Preferences and entries in self.defaults dict +- Tool Fiducials - updated the source_file object for the modified Gerber files +- working on adding line numbers to the TextPlainEdit +- GCode view now has line numbers +- solved a bug that made selection of objects on canvas impossible if there is an object of type FlatCAMScript or FlatCAMDocument opened + +21.11.2019 + +- Tool Fiducials - finished the part with adding copper fiducials: manual and auto +- Tool Fiducials - added choice of shapes: circular or non-standard cross +- Tool Fiducials - finished the work on adding soldermask openings +- Tool Fiducials - finished the tool +- updated requirements.txt and setup_ubuntu.sh files + +20.11.2019 + +- Tool Fiducials - added the GUI and the shortcut key +- Tool Fiducials - updated the icon + +19.11.2019 + +- removed the f-strings replacing them with the traditional string formatting due of not being supported by older versions of Python 3 +- fixed some TclCommands: MillDrills and OpenGerber +- fixed bug in Tool Subtract that did not allow subtracting Gerber objects +- starting to work on Tool Fiducials - created the file + +18.11.2019 + +- finished the Dots and Squares options in the Copper Thieving Tool +- working on the Lines option in Copper Thieving Tool +- finished the Lines option in the Copper Thieving Tool; still have to add threading to maximize performance +- finished Copper Thieving Tool improvements +- working on the Calibrate Excellon Tool - remade the UI + +17.11.2019 + +- optimized the storage of the Gerber mark shapes by making them one layer only +- optimized the Distance Tool such that the distance utility geometry will be shown even when the mark shapes are plotted. +- updated the make_freezed.py file to make sure that all the required files are included +- updated the setup_ubuntu.sh to include the sudo command (courtesy of Krishna Torque on bitbucket) + +16.11.2019 + +- fixed issue #341 that affected both preprocessors that have inlined feedrate: marlin and repetier. The used feedrate was the Feedrate X-Y and instead had to be Feedrate Z. + +15.11.2019 + +- added all the recognized extensions to the save dialog filters; latest extension used will be preselected next time a save operation occur +- fixed issue #335. The FCDoubleSPinBox (and FCSpinBox) value was not used when the user entered data but just hovered away the mouse expecting the data to be already confirmed +- converted setup_ubuntu.sh to Linux line endings + +14.11.2019 + +- made sure that the 'default' preprocessor file is always loaded first such that this name is always first in the GUI comboboxes +- added a class in GUIElements for a TextEdit box with line numbers and highlight + +13.11.2019 + +- trying to improve the performance of View CNC Code command by using QPlainTextEdit; made the mods for it +- when using the Find function in the TextEditor and the result reach the bottom of the document, the next find will be the first in the document (before it defaulted to the beginning of the document) +- finished improving the show of text files in FlatCAM (CNC Code, Source files) +- fixed an issue in the FlatCAMObj.FlatCAMGerber.convert_units() which needed to be updated after changes elsewhere + +12.11.2019 + +- added two new preprocessor files for ISEL CNC and for BERTA CNC +- clicking on a FCTable GUI element empty space will also clear the focus now + +11.11.2019 + +- in Tools Database added a contextual menu to add/copy/delete tool; Ctrl+C, DEL keys work too; key T for adding a tool is now only partially working +- in Tools Database made the status bar messages show when adding/copying/deleting tools in DB +- changed all Except statements that were single to except Exception as recommended in some PEP +- renamed the Copper Fill Tool to Copper Thieving Tool as this is a more appropriate name; started to add ability for more types of copper thieving besides solid +- fixed some issues recently introduced in ParseSVG +- updated POT file +- fixed GUI in 2Sided Tool +- extending the Copper Thieving Tool - wip + +9.11.2019 + +- fixed a new bug that did not allow to open the FlatCAM Preferences files by doubleclick in Windows +- added a new feature: Tools Database for Geometry objects; resolved issue #308 +- added tooltips for the Tools Database table headers and buttons + +8.11.2019 + +- updated the make file for frozen executable + +7.11.2019 + +- added the '.ngc' file extension to the GCode Save file dialog filter +- made the 'M2' Gcode command footer optional, default is False (can be set using the TclCommand: set_sys cncjob_footer True) +- added a setting in Preferences to force the GCode output to have the Windows line-endings even for non-Windows OS's + +6.11.2019 + +- the "CRTL+S" key combo when the Preferences Tab is in focus will save the Preferences instead of saving the Project +- fixed bug in the Paint Tool that did not allow choosing a Paint Method that was not Standard +- made sure that in the FlatCAMGeometry.merge() all the source data is deepcopy-ed in the final object +- the font color of the Preferences tab will change to red if settings are not saved and it will revert to default when saved +- fixed issue #333. The Geometry Editor Paint tool was not working and using it resulted in an error + +5.11.2019 + +- added a new setting named 'Allow Machinist Unsafe Settings' that will allow the Travel Z and Cut Z to take both positive and negative values +- fixed some issues when editing a multigeo geometry + +4.11.2019 + +- wip +- getting rid of all the Options GUI and related functions as it is no longer supported +- updated the UI in Geometry UI +- optimized the order of the defaults storage declaration and the update of the Preferences GUI from the defaults +- started to add a Tool Database + +3.11.2019 + +- fixed the V-shape tool diameter calculation in NCC Tool +- in NCC Tool made the new tool dia (circular type) a parameter in Preferences +- fixed a small issue with clicking in a disabled FCDoubleSpinner or FCSpinner still doing a selection + +30.10.2019 + +- converted SolderPaste Tool to usage of SpinBoxes; changed the SolderPaste Tool UI in Preferences too +- fixed a bug in SolderPaste Tool that did not allow to view the GCode + +29.10.2019 + +- a bug fix in Geometry Object +- fixed some missing properties in Tool Calculators + +28.10.2019 + +- in Tools: Paint, NCC and Copper Fill, when using the Area Selection, now the selected areas will stay drawn as markers until the user click RMB +- in legacy2D graphic engine, adding an utility geometry no longer draw the older ones, overwriting them +- fixed some issues in the Gerber Editor (Aperture add was double adding an aperture) +- converted Gerber Editor to usage of SpinBoxes +- working on the Calibrate Excellon Tool +- converted Excellon Editor to usage of SpinBoxes +- Calibrate Excellon Tool: working on self.calculate_factors() method + +27.10.2019 + +- Copper Fill Tool: some PEP8 corrections + +26.10.2019 + +- fixed an error in the FCDoubleSpinner class when FlatCAM is run on system with locale that use the comma as decimal separator + +25.10.2019 + +- QRCode Tool: added ability to add negative QRCodes (perhaps they can be isolated on copper?); added a clear area surrounding the QRCode in case it is dropped on a copper pour (region); fixed the Gerber export +- QRCode Tool: all parameters are hard-coded for now +- small update +- fixed imports in all TclCommands +- fixed the requirements.txt and setup_ubuntu.sh files +- QRCode Tool: change the plot method parameter +- QRCode Tool: added ability to save the generated QRCode as SVG file or PNG file +- QRCode Tool: added the feature to save the PNG file with transparent background +- QRCode Tool: added GUI category in Preferences window +- QRCode Tool: shortcut key for this tool is now Alt+Q while PDF import Tool was relegated to Ctrl+Q combo key shortcut +- added a new FlatCAM Tool: Copper Fill Tool. It will pour copper into a Gerber filling all empty space with copper, at a clearance distance of the Gerber features +- Copper Fill Tool: added possibility to select between a bounding box rectangular or convex hull when the reference is the geometry of the source Gerber object +- Copper Fill Tool: cleanup on not regular tool exit +- Copper Fill Tool: added GUI category in Edit -> Preferences window +- QRCode Tool: added a selection limit parameter to control the selection shape vs utility geo + +24.10.2019 + +- added some placeholder texts in the TextBoxes. +- working on QRCode Tool; added the utility geometry and initial functional layout +- working on QRCode Tool; finished adding the QRCode geometry to the selected Gerber object and also finished adding the 'follow' geometry needed when exporting the Gerber object as a Gerber file in addition to the 'solid' geometry in the obj.apertures +- working on QRCode Tool; finished offsetting the geometry both in apertures and in solid_geometry; updated the source_file of the source object + +23.10.2019 + +- QRCode Tool - a SVG object is generated and plotted on screen having the QRCode data +- fixed an import error in Distance Tool +- fixed the Toggle Grid Lines functionality + +22.10.2019 + +- working on the Calibrate Excellon Tool +- finished the GUI layout for the Calibrate Excellon Tool +- start working on QRCode Tool - not working yet +- start working on QRCode Tool - searching for alternatives + +21.10.2019 + +- the context menu for the Tabs in notebook and PlotTabArea is launched now on right mouse click on tabs themselves +- fixed an error when trying to view the source file and there is no object selected +- updated the Objects menu signals so whenever an object is (de)selected in the Project Tab, it's state will reflect the (un)checked state of the actions in the Object menu +- fixed issue in Gerber Object UI of not updating the value of CutZ entry on TipDia or TipAngle entries change. Fixed issue #324 + +18.10.2019 + +- fixed a small bug in BETA status change +- updated the About FlatCAM window +- reverted change in tool dia being able to take only positive values in Gerber Object UI +- started to work to a new tool: Calibrate Excellon Tool +- solved the issue #329 + +18.10.2019 + +- finished the update on the Google translated Spanish translation. +- updated the new objects icons for Gerber, Geometry and Excellon +- small import problem fixed +- RELEASE 8.98 + +17.10.2019 + +- fixed a bug in milling holes due of a message wrongly formatted +- added an translator email address +- finished the update on German Google translation. Part of it was corrected by Jens Karstedt +- finished the update of the Romanian translation. +- finished the Objects menu by adding the ability of actions to be checked so they will show the selected status of the objects and by adding to actions to (de)select all objects +- fixed and optimized the click selection on canvas +- fixed Gerber parsing for very simple Gerber files that have only one Polygon but many LPC zones +- fixed SVG export; fix bug #327 +- finished the update on French Google translation. + +16.10.2019 + +- small update to Romanian translation files + +15.10.2019 + +- adjusted the layout in NCC Tool +- fixed bug in Panelization Tool for which in case of Excellon objects, the panel kept a reference to the source object which created issues when moving or disabling/enabling the plots +- cleaned up the module imports throughout the app (the TclCommands are not yet verified) +- removed the styling on the comboboxes cellWidget's in the Tool Tables +- replaced some of the icons that did not looked Ok on the dark theme +- added a new toolbar button for the Copy object functionality +- changed the Panelize tool icon +- corrected some strings + +14.10.2019 + +- modified the result highlight color in Check Rules Tool +- added the Check Rules Tool parameters to the unit conversion list +- converted more of the Preferences entries to FCDoubleSpinner and FCSpinner +- converted all ObjectUI entries to FCDoubleSpinner and FCSpinner +- updated the translation files (~ 89% translation level) +- changed the splash screen as it seems that FlatCAM beta will never be more than beta +- changed some of the signals from returnPressed to editingFinished due of now using the SpinBoxes +- fixed an issue that caused the impossibility to load a GCode file that contained the % symbol even when was loaded in a regular way from the File menu +- re-added the CNC tool diameter entry for the CNCjob object in Selected tab.FCSpinner +- since the CNCjob geometry creation is only useful for graphical purposes and have no impact on the GCode creation I have removed the cascaded union on the GCode geometry therefore speeding up the Gcode display by many factors (perhaps hundreds of times faster) +- added a secondary link in the bookmark manager +- fixed the bookmark manager order of bookmark links; first two links are always protected from deletion or drag-and-drop to other positions +- fixed a whole load of PyQT signal problems generated by recent changes to the usage of SpinBoxes; added a signal returnPressed for the FCSpinner and for FCDoubleSpinner +- fixed issue in Paint Tool where the first added tool was expected to have a float diameter but it was a string +- updated the translation files to the latest state in the app + +13.10.2019 + +- fixed a bug in the Merge functions +- fixed the Export PNG function when using the 2D legacy graphic engine +- added a new capability to toggle the grid lines for both graphic engines: menu link in View and key shortcut combo Alt+G +- changed the grid colors for 3D graphic engine when in Dark mode +- enhanced the Tool Film adding the Film adjustments and added the GUI in Preferences +- set the GUI layout in Preferences for a new category named Tools 2 +- added the Preferences for Check Rules Tool and for Optimal Tool and also updated the Film Tool to use the default settings in Preferences + +12.10.2019 + +- fixed the Gerber Parser convert units unnecessary usage. The only units conversion should be done when creating the new object, after the parsing +- more fixes in Rules Check Tool +- optimized the Move Tool +- added support for key-based panning in 3D graphic engine. Moving the mouse wheel while pressing the CTRL key will pan up-down and while pressing SHIFT key will pan left-right +- fixed a bug in NCC Tool and start trying to make the App responsive while the NCC tool is run in a non-threaded way +- fixed a GUI bug with the QMenuBar recently introduced + +11.10.2019 + +- added a Bookmark Manager and a Bookmark menu in the Help Menu +- added an initial support for rows drag and drop in FCTable in GUIElements; it crashes for CellWidgets for now, if CellWidgetsare in the table rows +- fixed some issues in the Bookmark Manager +- modified the Bookmark manager to be installed as a widget tab in Plot Area; fixed the drag & drop function for the table rows that have CellWidgets inside +- marked in gray color the rows in the Bookmark Manager table that will populate the BookMark menu +- made sure that only one instance of the BookmarkManager class is active at one time + +10.10.2019 + +- fixed Tool Move to work only for objects that are selected but also plotted, therefore disabled objects will not be moved even if selected + +9.10.2019 + +- updated the Rules Check Tool - solved some issues +- made FCDoubleSpinner to use either comma or dot as a decimal separator +- fixed the FCDoubleSpinner to only allow the amount of decimals already set with set_precision() +- fixed ToolPanelize to use FCDoubleSpinner in some places + +8.10.2019 + +- modified the FCSpinner and FCDoubleSpinner GUI elements such that the wheel event will not change the values inside unless there is a focus in the lineedit of the SpinBox +- in Preferences General, Gerber, Geometry, Excellon, CNCJob sections made all the input fields of type SpinBox (where possible) +- updated the Distance Tool utility geometry color to adapt to the dark theme canvas +- Toggle Code Editor now works as expected even when the user is closing the Editor tab and not using the command Toggle Code Editor +- more changes in Preferences GUI, replacing the FCEntries with Spinners +- some small fixes in toggle units conversion +- small GUI changes + +7.10.2019 + +- fixed an conflict in a signal usage that was triggered by Tool SolderPaste when a new project was created +- updated Optimal Tool to display both points coordinates that made a distance (and the minimum) not only the middle point (which is still the place where the jump happen) +- added a dark theme to FlatCAM (only for canvas). The selection is done in Edit -> Preferences -> General -> GUI Settings +- updated the .POT file and worked a bit in the romanian translation +- small changes: reduced the thickness of the axis in 3D mode from 3 pixels to 1 pixel +- made sure that is the text in the source file of a FlatCAMDocument is HTML is loaded as such +- added inverted icons + +6.10.2019 + +- remade the Mark area Tool in Gerber Editor to be able to clear the markings and also to delete the marked polygons (Gerber apertures) +- working in adding to the Optimal Tool the rest of the distances found in the Gerber and the locations associated; added GUI +- added display of the results for the Rules Check Tool in a formatted way +- made the Rules Check Tool document window Read Only +- made Excellon and Gerber classes from camlib into their own files in the flatcamParser folder +- moved the ApertureMacro class from camlib to ParseGerber file +- moved back the ApertureMacro class to camlib for now and made some import changes in the new ParseGerber and ParseExcellon classes +- some changes to the tests - perhaps I will try adding a few tests in the future +- changed the Jump To icon and reverted some changes to the parseGerber and ParseExcellon classes +- updated Tool Optimal with display of all distances (and locations of the middle point between where they happen) found in the Gerber Object + +5.10.2019 + +- remade the Tool Calculators to use the QSpinBox in order to simplify the user interaction and remove possible errors +- remade: Tool Cutout, Tool 2Sided, Tool Image, Panelize Tool, NCC Tool, Paint Tool to use the QSpinBox GUI elements +- optimized the Transformation Tool both in GUI and in functionality and replaced the entries with QSpinBox +- fixed an issue with the tool table context menu in Paint Tool +- made some changes in the GUI in Paint Tool, NCC Tool and SolderPaste Tool +- changed some of the icons; added attributions for icons source in the About FlatCAM window +- added a new tool in the Geometry Editor named Explode which is the opposite of Union Tool: it will explode the polygons into lines + +4.10.2019 + +- updated the Film Tool and added the ability to generate Punched Positive films (holes in the pads) when a Gerber file is the film's source. The punch holes source can be either an Excellon file or the pads center +- optimized Rules Check Tool so it runs faster when doing Copper 2 Copper rule +- small GUI changes in Optimal Tool and in Film Tool +- some PEP8 corrections +- some code annotations to make it easier to navigate in the FlatCAMGUI.py +- fixed exit FullScreen with Escape key +- added a new menu category in the MenuBar named 'Objects'. It will hold the objects found in the Project tab. Useful when working in FullScreen +- disabled a log.debug in ObjectColection.get_by_name() +- added a Toggle Notebook button named 'NB' in the QMenBar which toggle the notebook +- in Gerber isolation section, the tool dia value is updated when changing from Circular to V-shape and reverse +- in Tool Film, when punching holes in a positive film, if the resulting object geometry is the same as the source object geometry, the film will not ge generated +- fixed a bug that when a Gerber object is edited and it has as solid_geometry a single Polygon, saving the result was failing due of len() function not working on a single Polygon +- added the Distance Tool, Distance Min Tool, Jump To and Set Origin functions to the Edit Toolbar + +3.10.2019 + +- previously I've added the initial layout for the FlatCAMDocument object +- added more editing features in the Selected Tab for the FlatCAMDocument object + +2.10.2019 + +- fixed bug in Geometry Editor that did not allow the copy of geometric elements +- created a new class that holds all the Code Editor functionality and integrated as a Editor in FlatCAM, the location is in flatcamEditors folder +- remade all the functions for view_source, scripts and view_code to use the new TextEditor class; now all the Code Editor tabs are being kept alive, before only one could be in an open state +- changed the name of the new object FlatCAMNotes to a more general one FlatCAMDocument +- changed the way a new FlatCAMScript object is made, the method that is processing the Tcl commands when the Run button is clicked is moved to the FlatCAMObj.FlatCAMScript() class +- reused the Multiprocessing Pool declared in the App for the ToolRulesCheck() class +- adapted the Project context menu for the new types of FLatCAM objects +- modified the setup_recent_files to accommodate the new FlatCAM objects +- made sure that when an FlatCAMScript object is deleted, it's associated Tab is closed +- fixed the FlatCMAScript object saving when project is saved (loading a project with this script object is not working yet) +- fixed the FlatCMAScript object when loading it from a project + +1.10.2019 + +- fixed the FCSpinner and FCDoubleSpinner GUI elements to select all on first click and deselect on second click in the Spinbox LineEdit +- for Gerber object in Selected Tab added ability to chose a V-Shape tool and therefore control the isolation better by adjusting the cut width of the isolation in function of the cut depth, tip width of the tool and the tip angle of the tool +- when in Gerber UI is selected the V-Shape tool, all those parameters (tip dia, tip angle, tool_type = 'V' and cut Z) are transferred to the generated Geometry and prefilled in the Geoemtry UI +- added a fix in the Gerber parser to work even when there is no information about zero suppression in the Gerber file +- added new settings in Edit -> Preferences -> Gerber for Gerber Units and Gerber Zeros to be used as defaults in case that those informations are missing from the Gerber file +- added new settings for the Gerber newly introduced feature to isolate with the V-Shape tools (tip dia, tip angle, tool_type and cut Z) in Edit -> Preferences -> Gerber Advanced +- made those settings just added for Gerber, to be updated on object creation +- added the Geo Tolerance parameter to those that are converted from MM to INCH +- added two new FlatCAM objects: FlatCAMScript and FlatCAMNotes + +30.09.2019 + +- modified the Distance Tool such that the number of decimals all over the tool is set in one place by the self.decimals +- added a new tool named Minimum Distance Tool who will calculate the minimum distance between two objects; key shortcut: SHIFT + M +- finished the Minimum Distance Tool in case of using it at the object level (not in Editors) +- completed the Minimum Distance Tool by adding the usage in Editors +- made the Minimum Distance Tool more precise for the Excellon Editor since in the Excellon Editor the holes shape are represented as a cross line but in reality they should be evaluated as circles +- small change in the UI layout for Check Rules Tool by adding a new rule (Check trace size) +- changed a tooltip in Optimal Tool +- in Optimal Tool added display of how frequent that minimum distance is found +- in Tool Distance and Tool Minimal Distance made the entry fields read-only +- in Optimal Tool added the display of the locations where the minimum distance was detected +- added support to use Multi Processing (multi core usage, not simple threading) in Rules Check Tool +- in Rules Check Tool added the functionality for the following rules: Hole Size, Trace Size, Hole to Hole Clearance +- in Rules Check Tool added the functionality for Copper to Copper Clearance +- in Rules Check Tool added the functionality for Copper to Outline Clearance, Silk to Silk Clearance, Silk to Solder Mask Clearance, Silk to Outline Clearance, Minimum Solder Mask Sliver, Minimum Annular Ring +- fixes to cover all possible situations for the Minimum Annular Ring Rule in Rules Check Tool +- some fixes in Rules Check Tool and added a QSignal that is fired at the end of the job + +29.09.2019 + +- work done for the GUI layout of the Rule Check Tool +- setup signals in the Rules Check Tool GUI +- changed the name of the Measurement Tool to Distance Tool. Moved it's location to the Edit Menu +- added Angle parameter which is continuously updated to the Distance Tool + +28.09.2019 + +- changed the icon for Open Script and reused it for the Check Rules Tool +- added a new tool named "Optimal Tool" which will determine the minimum distance between the copper features for a Gerber object, in fact determining the maximum diameter for a isolation tool that can be used for a complete isolation +- fixed the ToolMeasurement geometry not being displayed +- fixed a bug in Excellon Editor that crashed the app when editing the first tool added automatically into a new black Excellon file +- made sure that if the big mouse cursor is selected, the utility geometry in Excellon Editor has a thicker line width (2 pixels now) so it is visible over the geometry of the mouse cursor +- fixed issue #319 where generating a CNCJob from a geometry made with NCC Tool made the app crash; also #328 which is the same +- replaced in FlatCAM Tools and in FLatCAMObj.py and in Editors all references to hardcoded decimals in string formats for tools with a variable declared in the __init__() +- fixed a small bug that made app crash when the splash screen is disabled: it was trying to close it without being open + +27.09.2019 + +- optimized the toggle axis command +- added possibility of using a big mouse cursor or a small mouse cursor. The big mouse cursor is made from 2 infinite lines. This was implemented for both graphic engines +- added ability to change the cursor size when the small mouse cursor is selected in Preferences -> General +- removed the line that remove the spaces from the path parameter in the Tcl commands that open something (Gerber, Gcode, Excellon) +- fixed issue with the old SysTray icon not hidden when the application is restarted programmatically +- if an object is edited but the result is not saved, the app will reload the edited object UI and set the Selected tab as active +- made the mouse cursor (big, small) change in real time for both graphic engines +- started to work on a new FlatCAM tool: Rules Check +- created the GUI for the Rule Check Tool +- if there are (x, y) coordinates in the clipboard, when launching the "Jump to" function, those coordinates will be preloaded in the Dialog box. +- when the combo SHIFT + LMB is executed there is no longer a deselection of objects +- when the "Jump to" function is called, the mouse cursor (if active) will be moved to the new position and the screen position labels will be updated accordingly + + +27.09.2019 + +- RELEASE FlatCAM 8.97 + +26.09.2019 + +- added a Copy All button in the Code Editor, clicking this button will copy all text in the editor to the clipboard +- added a 'Milling Type' radio button in Geometry Editor Preferences to contorl the type of geometry will be generated in the Geo Editor (for conventional milling or for the climb milling) +- added the functionality to allow climb/conventional milling selection for the geometry created in the Geometry Editor +- now any Geometry that is edited in Geometry editor will have coordinates ordered such that the resulting Gcode will allow the selected milling type in the 'Milling Type' radio button in Geometry Editor Preferences (which depends also of the spindle direction) +- some strings update +- French Google-translation at 100% +- German Google-translation update to 100% +- updated the other languages and the .POT file +- changed some strings (that should not have been included for translation) and updated language files and the .POT file +- fixed issue when rebooting from within in cx_freezed state (it issued a startup arg with the path to FlatCAM.exe but that triggered the last sys.exit(2) that I had in the App.args_at_startup()) +- modified the make_win script for the presence of MatPlotLib + +25.09.2019 + +- French translation at 33% +- fixed the 'Jump To' function to work in legacy graphic engine +- in legacy graphic engine fixed the mouse cursor shape when grid snapping is ON, such that it fits with the shape from the OpenGL graphic engine +- in legacy graphic engine fixed the axis toggle +- French Google-translation at 48% + +24.09.2019 + +- fixed the fullscreen method to show the application window in fullscreen wherever the mouse pointer it is therefore on the screen we are working on; before it was showing always on the primary screen +- fixed setup_ubuntu.sh to include the matplotlib package required by the Legacy (2D) graphic engine +- in legacy graphic engine, fixed issue where immediately after changing the mouse cursor snapping the mouse cursor shape was not updated +- in legacy graphic engine, fixed issue where while zooming the mouse cursor shape was not updated +- in legacy graphic engine, fixed issue where immediately after panning finished the mouse cursor shape was not updated +- unfortunately the fix for issue where while zooming the mouse cursor shape was not updated braked something in way that Matplotlib work with PyQt5, therefore I removed it +- fixed a bug in legacy graphic engine: when doing the self.app.collection.delete_all() in new_project an app crash occurred +- implemented the Annotation change in CNCJob Selected Tab for the legacy graphic engine + +23.09.2019 + +- in legacy graphic engine, fixed bug that made the old object disappear when a new object was loaded +- in legacy graphic engine, fixed bug that crashed the app when creating a new project +- in legacy graphic engine, fixed a bug that when deleting an object all objects where deleted +- added a new TclCommand named "set_origin" which will set the origin for all loaded objects to zero if the -auto True argument is used and to a certain x,y location if the format is: set_origin 5,7 +- added a new TclCommand named "bounds" which will return a list of bounds values from a supplied list of objects names. For use in Tcl Scripts +- updated strings in the translations and the .POT file +- added the new keywords to the default keywords list +- fixed the FullScreen option not working for the 3D graphic engine (due bug of Qt5 when OpenGL window is fullscreen) by creating a sort of fullscreen +- added a final fix that allow full coverage of the screen in FullScreen in Windows and still the menus are working +- optimized the Gerber mark shapes display +- fixed a color format bug in Tool Move for 3D engine +- made sure that when the Tool Move is used on a Gerber file with mark shapes active, those mark shapes are deleted before the actual move +- in legacy graphic engine, fixed issue with Delete shortcut key trying to delete twice +- 26% in Google-translated French translation and updated some strings too + +22.09.2019 + +- fixed zoom directions legacy graphic engine (previous commit) +- fixed display of MultiGeo geometries in legacy graphic engine +- fixed Paint tool to work in legacy graphic engine +- fixed CutOut Tool to work in legacy graphic engine +- fixed display of distance labels and code optimizations in ToolPaint and NCC Tool +- adjusted axis at startup for legacy graphic engine plotcanvas +- when the graphic engine is changed in Edit -> Preferences -> General -> App Preferences, the application will restart +- made hover shapes work in legacy graphic engine +- fixed bug in display of the apertures marked in the Aperture table found in the Gerber Selected tab and through this made it to also work with the legacy graphic engine +- fixed annotation in Mark Area Tool in Gerber Editor to work in legacy graphic engine +- fixed the MultiColor plot option Gerber selected tab to work in legacy graphic engine +- documented some methods in the ShapeCollectionLegacy class +- updated the files: setup_ubuntu.sh and requirements.txt +- some strings changed to be easier for translation +- updated the .POT file and the translation files +- updated and corrected the Romanian and Spanish translations +- updated the .PO files for the rest of the translations, they need to be filled in. +- fixed crash when trying to set a workspace in FlatCAM in the Legacy engine 2D mode by disabling this function for the case of 2D mode +- fixed exception when trying to Fit View (shortcut key 'V') with no object loaded, in legacy graphic engine + +21.09.2019 + +- fixed Measuring Tool in legacy graphic engine +- fixed Gerber plotting in legacy graphic engine +- fixed Geometry plotting in legacy graphic engine +- fixed CNCJob and Excellon plotting in legacy graphic engine +- in legacy graphic engine fixed the travel vs cut lines in CNCJob objects +- final fix for key shortcuts with modifier in legacy graphic engine +- refactored some of the code in the legacy graphic engine +- fixed drawing of selection box when dragging mouse on screen and the selection shape drawing on the selected objects +- fixed the moving drawing shape in Tool Move in legacy graphic engine +- fixed moving geometry in Tool Measurement in legacy graphic engine +- fixed Geometry Editor to work in legacy graphic engine +- fixed Excellon Editor to work in legacy graphic engine +- fixed Gerber Editor to work in legacy graphic engine +- fixed NCC tool to work in legacy graphic engine + +20.09.2019 + +- final fix for the --shellvar having spaces within the assigned value; now they are retained +- legacy graphic engine - made the mouse events work (click, release, doubleclick, dragging) +- legacy graphic engine - made the key events work (simple or with modifiers) +- legacy graphic engine - made the mouse cursor work (enabled/disabled, position report); snapping is not moving the cursor yet +- made the mouse cursor snap to the grid when grid snapping is active +- changed the axis color to the one used in the OpenGL graphic engine +- work on ShapeCollectionLegacy +- fixed mouse cursor to work for all objects +- fixed event signals to work in both graphic engines: 2D and 3D + +19.09.2019 + +- made sure that if FlatCAM is registered with a file extension that it does not recognize it will exit +- added some fixes in the the file extension detection +- added some status messages for the Tcl script related methods +- made sure that optionally, when a script is run then it is also loaded into the code editor +- added control over the display of Sys Tray Icon in Edit -> Preferences -> General -> GUI Settings -> Sys Tray Icon checkbox +- updated some of the default values to more reasonable ones +- FlatCAM can be run in HEADLESS mode now. This mode can be selected by using the --headless=1 command line argument or by changing the line headless=False to True in config/configuration.txt file. In this mod the Sys Tray Icon menu will hold only the Run Scrip menu entry and Exit entry. +- added a new TclCommand named quit_flatcam which will ... quit FlatCAM from Tcl Shell or from a script +- fixed the command line argument --shellvar to work when there are spaces in the argument value +- fixed bug in Gerber editor that did not allow to display all shapes after it encountered one shape without 'solid' geometry +- fixed bug in Gerber Editor -> selection area handler where if some of the selected shapes did not had the 'solid' geometry will silently abort selection of further shapes +- added new control in Edit -> Preferences -> General -> Gui Preferences -> Activity Icon. Will select a GIF from a selection, the one used to show that FlatCAM is working. +- changed the script icon to a smaller one in the sys tray menu +- fixed bug with losing the visibility of toolbars if at first startup the user tries to change something in the Preferences before doing a first save of Preferences +- changed a bit the splash PNG file +- moved all the GUI Preferences classes into it's own file flatcamGUI.PreferencesUI.py +- changed the default method for Paint Tool to 'all' + +18.09.2019 + +- added more functionality to the Extension registration with FLatCAM and added to the GUI in Edit -> Preferences -> Utilities +- fixed the parsing of the Manufacturing files when double clicking them and they are registered with FlatCAM +- fixed showing the GUI when some settings (maximized_GUI) are missing from QSettings +- added sys tray menu +- added possibility to edit the custom keywords used by the autocompleter (in Tcl Shell and in the Code Editor). It is done in the Edit -> Preferences -> Utilities +- added a new setting in Edit -> Preferences -> General -> GUI Settings -> Textbox Font which control the font on the Textbox GUI elements +- fixed issue with the sys tray icon not hiding after application close +- added option to run a script from the context menu of the sys tray icon. Changed the color of the sys tray icon to a green one so it will be visible on light and dark themes + +17.09.2019 + +- added more programmers that contributed to FlatCAM over the years, in the "About FlatCAM" -> Programmers window +- fixed issue #315 where a script run with the --shellfile argument crashed the program if it contained a TclCommand New +- added messages in the Splash Screen when running FlatCAM with arguments at startup +- fixed issue #313 where TclCommand drillcncjob is spitting errors in Tcl Shell which should be ignored +- fixed an bug where the pywrapcp name from Google OR-Tools is not defined; fix issue #316 +- if FlatCAM is started with the 'quit' or 'exit' as argument it will close immediately and it will close also another instance of FlatCAM that may be running +- added a new command line parameter for FlatCAM named '--shellvars' which can load a text file with variables for Tcl Shell in the format: one variable assignment per line and looking like: 'a=3' without quotes +- made --shellvars into --shellvar and make it only one list of commands passed to the Tcl. The list is separated by comma but without spaces. The variables are accessed in Tcl with the names shellvar_x where x is the index in the list of command comma separated values +- fixed an issue in the TclShell that generated an exception IndexError which crashed the software +- fixed the --shellvar and --shellfile FlatCAM arguments to work together but the --shellvar has precedence over --shellfile as it is most likely that whatever variable set by --shellvar will be used in the script file run by --shellfile + +16.09.2019 + +- modified the TclCommand New so it will no longer close all tabs when called (it closed the Code Editor tab which may have been holding the code that run) +- fixed the App.on_view_source() method for CNCJob objects: the Gcode will now contain the Prepend and Append code from the Edit -> Preferences -> CNCJob -> CNCJob Options +- added a new parameter named 'muted' for the TclCommands: cncjob, drillcncjob and write_gcode. Setting it as -muted 1 will disable the error reporting in TCL Shell +- some GUI optimizations +- more GUI optimizations related to being part of the Advanced category or not +- added possibility to change the positive SVG exported file color in Tool Film +- fixed some issues recently introduced in the TclCommands CNCJob, DrillCNCJob and write_gcode; changed some parameters names +- fixed issue in the Laser preprocessor where the laser was turned on as soon as the GCode started creating an unwanted cut up until the job start +- added new links in Menu -> Help (Excellon, Gerber specifications and a Report Bug) +- made the splashscreen to be showed on the current monitor on systems with multiple monitors +- added a new entry in Menu -> View -> Redraw All which is doing what the name says: redraw all loaded objects +- fixed issue where in TCl Shell the Windows paths were not understood due of backslash symbol understood as escape symbol instead of path separator +- made sure that in for the TclCommand cncjob and for the drillcncjob if one of the args is stated but no value then the value used will be the default one +- made available the TSA algorithm for drill path optimization when the used OS is 64bit. When used OS is 32bit the only available algorithm is TSA + +15.09.2019 + +- refactored FlatCAMGeometry.mtool_gen_cncjob() method +- fixed the TclCommandCncjob to work for multigeometry Geometry objects; still I had to fix the list of tools parameter, right now I am setting it to an empty list +- update the Tcl Command isolate to be able to isolate exteriors, interiors besides the full isolation, using the iso_type parameter +- fixed issue in ToolPaint that could not allow area painting of a geometry that was a list and not a Geometric element (polygon or MultiPolygon) +- fixed UI showing before the initialization of FlatCAM is finished when the last state of GUI was maximized +- finished updating the TclCommand cncjob to work for multi-geo Geometry objects with the parameters from the args +- fixed the TclCommand cncjob to use the -outname parameter +- added some more keywords in the data_model for auto-completer +- fixed isolate TclCommand to use correctly the -outname parameter +- added possibility to see the GCode when right clicking on the Project tab on a CNCJob object and then clicking View Source +- added a new TclCommand named PlotObjects which will plot a list of FlatCAM objects +- made that after opening an object in FlatCAM it is not automatically plotted. If the user wants to plot it can use the TclCommands PlotAll or PlotObjects +- modified the TclCommands so that open files do not plot the opened files automatically +- made all TclCommands not to be plotted automatically +- made sure that all TclCommands are not threaded +- added new TclCommands: NewExcellon, NewGerber +- fixed the TclCommand open_project +- added the outname parameter (and established an default name when outname not used) for the AlignDrillGrid and AlignDrill TclCommands +- fixed Scripts repeating multiple time when the Code Editor is used. This repetition was correlated with multiple openings of the Code Editor window (especially after an error) +- added the autocomplete keywords that can be changed to the defaults dictionary + +14.09.2019 + +- more string changes +- updated translation files +- fixed a small bug +- minor changes in the Code Editor GUI +- minor changes in the 'FlatCAM About' GUI +- added a new shortcut key F5 for doing the 'Plot All' +- updated the google-translated Spanish translation strings +- fixed the layouts to include toolbars breaks where it was needed +- whenever the user changes the Excellon format values for loading files, the Export Excellon Format values will be updated +- made optional the behavior of Excellon Export values following the values in the Excellon Loading section +- updated the translations (except RU) and the POT file +- added to the NonCopperClear.clear_copper() a parameter to be able to run it non-threaded + +13.09.2019 + +- added control for simplification when loading a Gerber file in Preferences -> Gerber -> Gerber General -> Simplify +- added some messages for the Edit -> Conversions -> Join methods() to make sure that there are at least 2 objects selected for join +- added a grid layout in on_about() +- upgraded the Script Editor to be able to run Tcl commands in batches +- added some ToolTips for the buttons in the Code Editor +- converted the big strings that hold the shortcut keys descriptions to smaller string to make translations easier +- fixed some of the strings that were left in the old way +- updated the POT file +- updated Romanian language partially +- added a new way to handle scripts with repeating Tcl commands +- added new buttons in the Tools toolbar for running, opening and adding new scripts +- finished the Romanian translation update and updated the POT file + +12.09.2019 + +- small changes in the TclCommands: MillDrills, MillSlots, DrillCNCJob: the new parameter for tolerance is now named: diatol +- cleaned up the 'About FlatCAM' window, started to give credits for the translation team +- started to add an application splash screen +- now, Excellon and Gerber edited objects will have the source_code updated and ready to be saved +- the edited Gerber (or Excellon) object now is kept in the app after editing and the edited object is a new object +- added a message to the splash screen +- remade the splash screen to show multiple messages on app initialization +- added a new splash image +- added a control in Preferences -> General -> GUI Settings -> Splash Screen that control if the splash screen is shown at startup + +11.09.2019 + +- added the Gerber code as source for the panelized object in Panelize Tool +- whenever a Gerber file is deleted, the mark_shapes objects are deleted also +- made faster the Gerber parser for the case of having a not valid geometry when loading a Gerber file without buffering +- updated code in self.on_view_source() to make it more responsive +- fixed the TclCommand MillHoles +- changed the name of TclCommand MillHoles to MillDrills and added a new TclCommand named MillSlots +- modified the MillDrills and MillSlots TclCommands to accept as parameter a list of tool diameters to be milled instead of tool indexes +- fixed issue #302 where a copied object lost all the tools +- modified the TclCommand DrillCncJob to have as parameter a list of tool diameters to be drilled instead of tool indexes +- updated the Spanish translation (Google-translation) +- added a new parameter in the TclCommands: DrillCNCJob, MillDrills, MillSlots named tol (from tolerance). If the diameters of the milled (drilled) dias are within the tolerance specified of the diameters in the Excellon object than those diameters will be processed. This is to help account for rounding errors when having units conversion + +10.09.2019 + +- made isolation threaded +- fixed a small typo in TclCommandCopperCLear +- made changing the Plot kind in CNCJob selected tab, threaded +- fixed an object used before declaring it in NCC Tool - Area option +- added progress for the generation of Isolation geometry +- added progress and possibility of graceful exit in Panel Tool +- added graceful exit possibility when creating Isolation +- changed the workers thread priority back to Normal +- when disabling plots, if the selection shape is visible, it will be deleted +- small changes in Tool Panel (eliminating some deepcopy() calls) +- made sure that all the progress counters count to 100% + +9.09.2019 + +- changed the triangulation type in VisPyVisuals for ShapeCollectionVisual class +- added a setting in Preferences -> Gerber -> Gerber General named Buffering. If set to 'no' the Gerber objects load a lot more faster (perhaps 10 times faster than when set to 'full') but the visual look is not so great as all the aperture polygons can be seen +- added for NCC Tool and Paint Tool a setting in the Preferences -> Tools --> (NCC Tool/ Paint Tool) that can set a progressive plotting (plot shapes as they are processed) +- some fixes in Paint Tool when done over the Gerber objects in case that the progressive plotting is selected +- some fixes in Gerber isolation in case that the progressive plotting is selected; added a 'Buffer solid geometry' button shown only when progressive plotting for Gerber object is selected. It will buffer the entire geometry of the object and plot it, in a threaded way. +- modified FlatCAMObj.py file to the new string format that will allow easier translations +- modified camlib.py, FlatCAMAPp.py and ObjectCollection.py files to the new string format that will allow easier translations +- updated the POT file and the German language +- fixed issue when loading unbuffered a Gerber file that has negative regions +- fixed Panelize Tool to save the aperture geometries into the panel apertures. Also made the tool faster by removing the buffering at the end of the job +- modified FlatCAMEditor's files to the new string format that will allow easier translations +- updated POT file and the Romanian translation + +8.09.2019 + +- added some documentation strings for methods in FlatCAMApp.App class +- removed some @pyqtSlot() decorators as they interfere with the current way the program works + +7.09.2019 + +- added a method to gracefully exit from threaded tasks and implemented it for the NCC Tool and for the Paint Tool +- modified the on_about() function to reflect the reality in 2019 - FlatCAM it is an Open Source contributed software +- remade the handlers for the Enable/Disable Project Tree context menu so they are threaded and activity is shown in the lower right corner of the main window +- added to GUI new options for the Gerber object related to area subtraction +- added new feature in the Gerber object isolation allowing for the isolation to avoid an area defined by another object (Gerber or Geometry) +- all transformation functions show now the progress (rotate, mirror, scale, offset, skew) +- made threaded the Offset and Scale operations found in the Selected tab of the object +- corrected some issues and made Move Tool to show correctly when it is plotting and when it is offsetting the objects position +- made Set Origin feature, threaded +- updated German language translation files +- separated the Plotting thread from the transformations threads + +6.09.2019 + +- remade visibility threaded +- reimplemented the thread listening for new FlatCAM process starting with args so it is no longer subclassed but using the moveToThread function +- added percentage display for work done in NCC Tool +- added percentage display for work done in Paint Tool +- some fixes and prepared the activity monitor area to receive updated texts +- added progress display in status bar for generating CNCJob from Excellon objects +- added progress display in status bar for generating CNCJob from Geometry objects +- modified all the FlatCAM tools strings to the new format in which the status is no longer included in the translated strings to make it easier for the future translations +- more customization for the progress display in case of NCC Tool, Paint Tool and for the Gcode generation +- updated POT file with the new strings +- made the objects offset (therefore the Move Tool) show progress display + +5.09.2019 + +- fixed issue with loading files at start-up +- fixed issue with generating bounding box geometry for CNCJob objects +- added some more infobar messages and log.debug +- increased the priority for the worker tasks +- hidden the configuration for G91 coordinates due of deciding to leave this development for another time; it require too much refactoring +- added some messages for the G-code generation so the user know in which stage the process is + +4.09.2019 + +- started to work on support for G91 in Gcode (relative coordinates) +- added support for G91 coordinates +- working in plotting the CNCjob generated with G91 coordinates + +3.09.2019 + +- in NCC tool there is now a depth of cut parameter named 'Cut Z' which will dictate how deep the tool will enter into the PCB material +- in NCC tool added possibility to choose between the type of tools to be used and when V-shape is used then the tool diameter is calculated from the desired depth of cut and from the V-tip parameters +- small changes in NCC tool regarding the usage of the V-shape tool +- fixed the isolation distance in NCC Tool for the tools with iso_op type +- in NCC Tool now the Area adding is continuous until RMB is clicked (no key modifier is needed anymore) +- fixed German language translation +- in NCC Tool added a warning in case there are isolation tools and if those isolation's are interrupted by an area or a box +- in Paint Tool made that the area selection is repeated until RMB click +- in Paint Tool and NCC Tool fixed the RMB click detection when Area selection is used +- finished the work on file extensions registration with FlatCAM. If the file extensions are deleted in the Preferences -> File Associations then those extensions are unregistered with FlatCAM +- fixed bug in NCC Tools and in SolderPaste Tool if in Edit -> Preferences only one tool is entered +- fixed bug in camblib.clear_polygon3() which caused that some copper clearing / paintings were not complete (some polygons were not processed) when the Straight Lines method was used +- some changes in NCC Tools regarding of the clearing itself + +2.09.2019 + +- fixed issue in NCC Tool when using area option +- added formatting for some strings in the app strings, making the future translations easier +- made changes in the Excellon Tools Table to make it more clear that the tools are selected in the # column and not in the Plot column +- in Excellon and Gerber Selected tab made the Plot (mark) columns not selectable +- some ToolTips were modified +- in Properties Tool made threaded the calculation of convex_hull area and also made it to work for multi-geo objects +- in NCC tool the type of tool that is used is transferred to the Geometry object +- in NCC tool the type of isolation done with the tools selected as isolation tools can now be selected and it has also an Edit -> Preferences entry +- in Properties Tool fixed the dimensions calculations (length, width, area) to work for multi-geo objects + +1.09.2019 + +- fixed open handlers +- fixed issue in NCC Tool where the tool table context menu could be installed multiple times +- added new ability to create simple isolation's in the NCC Tool +- fixed an issue when multi depth step is larger than the depth of cut + +27.08.2019 + +- made FlatCAM so that whenever an associated file is double clicked, if there is an opened instance of FlatCAM, the file will be opened in the first instance without launching a new instance of FlatCAM. If FlatCAM is launched again it will spawn a new process (hopefully it will work when freezed). + +26.08.2019 + +- added support for file associations with FlatCAM, for Windows + +25.08.2019 + +- initial add of a new Tcl Command named CopperClear +- remade the NCC Tool in preparation for the newly added TclCommand CopperClear +- finished adding the TclCommandCopperClear that can be called with alias: 'ncc' +- added new capability in NCC Tool when the reference object is of Gerber type and fixed some newly introduced errors +- fixed issue #298. The changes in preprocessors done in Preferences dis not update the object UI layout as it was supposed to. The selection of Marlin postproc. did not unhidden the Feedrate Rapids entry. +- fixed minor issues +- fixed Tcl Command AddPolygon, AddPolyline +- fixed Tcl Command CncJob +- fixed crash due of Properties Tool trying to have a convex hull area on FlatCAMCNCJob objects which is not possible due of their nature +- modified Tcl Command SubtractRectangle +- fixed and modernized the Tcl Command Scale to be able to scale on X axis or on Y axis or on both and having as scale reference either the (0, 0) point or the minimum point of the bounding box or the center of the bounding box. +- fixed and modernized the Tcl Command Skew + +24.08.2019 + +- modified CutOut Tool so now the manual gaps adding will continue until the user is clicking the RMB +- added ability to turn on/off the grid snapping and to jump to a location while in CutOut Tool manual gap adding action +- made PlotCanvas class inherit from VisPy Canvas instead of creating an instance of it (work of JP) +- fixed selection by dragging a selection shape in Geometry Editor +- modified the Paint Tool. Now the Single Polygon and Area/Reference Object painting works with multiple tools too. The tools have to be selected in the Tool Table. +- remade the TclCommand Paint to work in the new configuration of the the app (the painting functions are now in their own tool, Paint Tool) +- fixed a bug in the Properties Tool +- added a new TcL Command named Nregions who generate non-copper regions +- added a new TclCommand named Bbox who generate a bounding box. + +23.08.2019 + +- in Tool Cutout for the manual gaps, right mouse button click will exit from the action of adding gaps +- in Tool Cutout tool I've added the possibility to create a cutout without bridge gaps; added the 'None' option in the Gaps combobox +- in NCC Tool added ability to add multiple zones to clear when Area option is checked and the modifier key is pressed (either CTRL or SHIFT as set in Preferences). Right click of the mouse is an additional way to finish the job. +- fixed a bug in Excellon Editor that made that the selection of drills is always cumulative +- in Paint Tool added ability to add multiple zones to paint when Area option is checked and the modifier key is pressed (either CTRL or SHIFT as set in Preferences). Right click of the mouse is an additional way to finish the job. +- in Paint Tool and NCC Tool, for the Area option, now mouse panning is allowed while adding areas to process +- for all the FlatCAM tools launched from toolbar the behavior is modified: first click it will launch the tool; second click: if the Tool tab has focus it will close the tool but if another tab is selected, the tool will have focus +- modified the NCC Tool and Paint Tool to work multiple times after first launch +- fixed the issue with GUI entries content being deselected on right click in the box in order to copy the value +- some changes in GUI tooltips +- modified the way key modifiers are detected in Gerber Editor Selection class and in Excellon Editor Selection class +- updated the translations +- fixed aperture move in Gerber Editor +- fixed drills/slots move in Excellon Editor +- RELEASE 8.96 + +22.08.2019 + +- added ability to turn ON/OFF the detachable capability of the tabs in Notebook through a context menu activated by right mouse button click on the Notebook header +- added ability to turn ON/OFF the detachable capability of the tabs in Plot Tab Area through a context menu activated by right mouse button click on the Notebook header +- added possibility to turn application portable from the Edit -> Preferences -> General -> App. Preferences -> Portable checkbox +- moved the canvas setup into it's own function and called it in the init() function +- fixed the Buffer Tool in Geometry Editor; made the Buffer entry field a QDoubleSpinner and set the lower limit to zero. +- fixed Tool Cutout so when the target Gerber is a single Polygon then the created manual geometry will follow the shape if shape is freeform +- fixed TclCommandFollow command; an older function name was used who yielded wrong results +- in Tool Cutout for the manual gaps, now the moving geometry that cuts gaps will orient itself to fit the angle of the cutout geometry + +21.08.2019 + +- added feature in Paint Tool allowing the painting to be done on Gerber objects +- added feature in Paint Tool to set how (and if) the tools are sorted +- added Edit -> Preferences GUI entries for the above just added features +- added new entry in Properties Tool which is the calculated Convex Hull Area (should give a more precise area for the irregular shapes than the box area) +- added some more strings in Properties Tool for the translation +- in NCC Tool added area selection feature +- fixed bug in Excellon parser for the Excellon files that do not put the type of zero suppression they use in the file (like DipTrace eCAD) +- fixed some issues introduced in NCC Tool + +20.08.2019 + +- added ability to do copper clearing through NCC Tool on Geometry objects +- replaced the layout from Grid to Form for the Reference objects comboboxes in Paint Tool and in NCC Tool + +19.08.2019 + +- updated the Edit -> Preferences to include also the Gerber Editor complete Preferences +- started to update the app strings to make it easier for future translations +- fixed the POT file and the German translation +- some mods in the Tool Sub +- fixed bug in Tool Sub that created issues when toggling visibility of the plots +- fixed the Spanish, Brazilian Portuguese and Romanian translations + +18.08.2019 + +- made the exported preferences formatted therefore more easily read +- projects at startup don't work in another thread so there is no multithreading if I want to double click an project and to load it +- added messages in the application window title which show the progress in loading a project (which is not thread-safe therefore keeping the app from fully initialize until finished) +- 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 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 so it is not included in the translated string +- updated the translation files for the modified strings (and for the newly added strings) +- added ability to lock toolbars within the context menu that is popped up on any toolbars right mouse click. The value is saved in QSettings and it is persistent between application startup's. + +17.08.2019 + +- added estimated time of routing for the CNCJob and added travelled distance parameter for geometry, too +- fixed error when creating CNCJob due of having the annotations disabled from preferences but the plot2() function from camlib.CNCJob class still performed operations who yielded TypeError exceptions +- coded a more accurate way to estimate the job time in CNCJob, taking into consideration if there is a usage of multi depth which generate more passes +- another fix (final one) for the Exception generated by the annotations set not to show in Preferences +- updated translations and changed version +- fixed installer issue for the x64 version due of the used CX_FREEZE python package which was in unofficial version (obviously not ready to be used) +- fixed bug in Geometry Editor, in disconnect_canvas_event_handlers() where I left some part of code without adding a try - except block which was required +- moved the initialization of the FlatCAM editors after a read of the default values. If I don't do this then only at the first start of the application the Editors are not functional as the Editor objects are most likely destroyed +- fixed bug in FlatCAM editors that caused the shapes to be drawn without resolution when the app units where INCH +- modified the transformation functions in all classes in camlib.py and FlatCAMObj.py to work with empty geometries +- RELEASE 8.95 + +17.08.2019 + +- updated the translations for the new strings +- RELEASE 8.94 + +16.08.2019 + +- working in Excellon Editor to Tool Resize to consider the slots, too +- fixed a weird error that created a crash in the following scenario: create a new excellon, edit it, add some drills/slots, delete it without saving, create a new excellon, try to edit and a crash is issued due of a wrapped C++ error +- fixed bug selection in Excellon editor that caused not to select the corresponding row (tool dia) in the tool table when a selection rectangle selected an even number of geometric elements +- updated the default values to more convenient ones +- remade the enable/disable plots functions to work only where it needs to (no sense in disabling a plot already disabled) +- made sure that if multi depth is choosed when creating GCode then if the multidepth is more than the depth of cut only one cut is made (to the depth of cut) +- each CNCJob object has now it's own text_collection for the annotations which allow for the individual enabling and disabling of the annotations +- added new menu category in File -> Backup with two menu entries that duplicate the functions of the export/import preferences buttons from the bottom of the Preferences window +- in Excellon Editor fixed the display of the number of slots in the Tool Table after the resize done with the Resize tool +- in Excellon Editor -> Resize tool, made sure that when the slot is resized, it's length remain the same, because the tool should influence only the 'thickness' of the slot. Since I don't know anything but the geometry and tool diameters (old and new), this is only an approximation and computationally intensive +- in Excellon Editor -> remade the Tool edit made by editing the diameter values in the Tools Table to work for slots too +- In Excellon Editor -> fixed bug that caused incorrect display of the relative coordinates in the status bar + +15.08.2019 + +- added Edit -> Preferences GUI and storage for the Excellon Editor Add Slots +- added a confirmation message for objects delete and a setting to activate it in Edit -> Preferences -> Global +- merged pull request from Mike Smith which fix an application crash when attempting to open a not-a-FlatCAM-project file as project +- merged pull request from Mike Smith that add support for a new SVG element: +- stored inside FlatCAM app the VisPy data files and at the first start the application will try to copy those files to the APPDATA (roaming) folder in case of running under Windows OS +- created a configuration file in the root/config/configuration.txt with a configuration line for portability. Set portable to True to run the app as portable +- working on the Slots Array in Excellon Editor - building the GUI +- added a failsafe path to the source folder from which to copy the VisPy data +- fixed the GUI for Slot Arrays in Excellon Editor +- finished the Slot Array tool in Excellon Editor +- added the key shortcut handlers for Add Slot and Add Slot Array tools in Excellon Editor +- started to work on the Resize tool for the case of Excellon slots in Excellon Editor +- final fix for the VisPy data files; the defaults files are saved to the Config folder when the app is set to be portable +- added the Slot Type parameter for exporting Excellon in Edit -> Preferences -> Excellon -> Export Excellon. Now the Excellon object can be exported also with drilled slot command G85 +- fixed bug in Excellon export when there are no zero suppression (coordinates with decimals) + +14.08.2019 + +- fixed the loading of Excellon with slots and the saving of edited Excellon object in regard of slots, in Excellon Editor +- fixed the Delete tool, Select tool in Excellon Editor to work for Slots too +- changes in the way the edited Excellon with added slots is saved +- added more icons and cursor in Excellon Editor for Slots related functions +- in Excellon Editor fixed the selection issue which in a certain step created a failure in the Copy and Move tools. +- in Excellon Editor fixed the selection with key modifier pressed +- edited the mouse cursors and saved them without included thumbnail in a bid to remove some CRC warnings made by libpng + +13.08.2019 + +- added new option in ToolSub: the ability to close (or not) the resulting paths when using tool on Geometry objects. Added also a new category in the Edit -> Preferences -> Tools, the Substractor Tool Options +- some PEP8 changes in FlatCAMApp.py +- added new settings in Edit -> Preferences -> General for Notebook Font size (set font size for the items in Project Tree and for text in Selected Tab) and for canvas Axis font size. The values are stored in QSettings. +- updated translations +- fixed a bug in FCDoubleSpinner GUI element +- added a new parameter in NCC tool named offset. If the offset is used then the copper clearing will finish to a set distance of the copper features +- fixed bugs in Geometry Editor +- added protection's against the 'bowtie' geometries for Subtract Tool in Geometry Editor +- added all the tools from Geometry Editor to the the contextual menu +- fixed bug in Add Text Tool in Geometry Editor that gave error when clicking to place text without having text in the box +- added all the tools from Gerber Editor to the the contextual menu +- added the menu entry "Edit" in the Project contextual menu for Gerber objects +- started to work in adding slots and slots array in Excellon Editor +- in FCSlot finished the utility geometry and the GUI for it + +12.08.2019 + +- done regression to solve the bug with multiple passes cutting from the copper features (I should remember not to make mods here) +- if 'combine' is checked in Gerber isolation but there is only one pass, the resulting geometry will still be single geo +- the 'passes' entry was changed to a IntSpinner so it will allow passes to be entered only in range (1, 999) - it will not allow entry of 0 which may create some issues +- improved the FlatCAMGerber.isolate() function to work for geometry in the form of list and also in case that the elements of the list are LinearRings (like when doing the Exterior Isolation) +- in NCC Tool made sure that at each run the old objects are deleted +- fixed bug in camlib.Gerber.parse_lines() Gerber parser where for Allegro Gerber files the Gerber units were incorrectly detected +- improved Mark Area Tool in Gerber Editor such that at each launch the previous markings are deleted + +11.08.2019 + +- small changes regarding the Project Title +- trying to fix reported bugs +- made sure that the annotations are deleted when the object that contain them is deleted +- fixed issue where the annotations for all the CNCJob objects are toggled together whenever the ones for an single object are toggled +- optimizations in GeoEditor +- updated translations + +10.08.2019 + +- added new feature in NCC Tool: now another object can be used as reference for the area extent to be cleared of copper +- fixed issue in the latest feature in NCC Tool: now it works also with reference objects made out of LineStrings (tool 'Path' in Geometry Editor) +- translation files updated for the new strings (Google Translate) +- RELEASE 8.93 + +9.08.2019 + +- added Exception handing for the case when the user is trying to save & overwrite a file already opened in another file +- finished added 'Area' type of Paint in Paint Tool +- fixed bug that created a choppy geometry for CNCJob when working in INCH +- fixed bug that did not asked the user to save the preferences after importing a new set of preferences, after the user is trying to close the Preferences tab window + +7.08.2019 + +- replaced setFixedWidth calls with setMinimumWidth +- recoded the camlib.Geometry.isolation_geometry() function +- started to work on Paint Area in Paint Tool + +6.08.2019 + +- fixed bug that crashed the app after creating a new geometry, if a new object is loaded and the new geometry is deleted and then trying to select the just loaded new object +- made some GUI elements in Edit -> Preferences to have a minimum width as opposed to the previous fixed one +- fixed issue in the isolation function, if the isolation can't be done there will be generated no Geometry object +- some minor UI changes +- strings added and translations updated + +5.08.2019 + +- made sure that if using an negative Gerber isolation diameter, the resulting Geometry object will use a tool with positive diameter +- fixed bug that when isolating a Gerber file made out of a single polygon, an RecursionException was issued together with inability to create tbe isolation +- when applying a new language if there are any changes in the current project, the app will offer to save the project before the reboot + +3.08.2019 + +- added project name to the window title +- fulfilled request: When saving a CNC file, if the file name is changed in the OS window, the new name does appear in the “Selected” (in name) and “Project” tabs (in cnc_job) +- solved bug such that the app is not crashing when some apertures in the Gerber file have no geometry. More than that, now the apertures that have geometry elements are bolded as opposed to the ones without geometry for which the text is unbolded +- merged a pull request with language changes for Russian translate +- updated the other translations + +31.07.2019 + +- changed the order of the menu entries in the FIle -> Open ... +- organized the list of recent files so the Project entries are to the top and separated from the other types of file +- work on identification of changes in Preferences tab +- added categories names for the recent files +- added a detection if any values are changed in the Edit -> Preferences window and on close it will ask the user if he wants to save the changes or not +- created a new menu entry in the File menu named Recent projects that will hold the recent projects and the previous "Recent files" will hold only the previous loaded files +- updated all translations for the new strings +- fixed bug recently introduced that when changing the units in the Edit -> Preferences it did not converted the values +- fixed another bug that when selecting an Excellon object after disabling it it crashed the app +- RELEASE 8.92 + +30.07.2019 + +- fixed bug that crashed the software when trying to edit a GUI value in Geometry selected tab without having a tool in the Tools Table +- fixed bug that crashed the app when trying to add a tool without a tool diameter value +- Spanish Google translation at 77% +- changed the Disable plots menu entry in the context menu, into a Toggle Visibility menu entry +- Spanish Google translation 100% but two strings (big ones) - needs review +- added two more strings to translation strings (due of German language) +- completed the Russian translation using the Google and Yandex translation engines (minus two big strings) - needs review + +28.07.2019 + +- fixed issue with not using the current units in the tool tables after unit conversion +- after unit conversion from Preferences, the default values are automatically saved by the app +- in Basic mode, the tool type column is no longer hidden as it may create issues when using an painted geometry +- some PEP8 clean-up in FlatCAMGui.py +- fixed Panelize Tool to do panelization for multiple passes type of geometry that comes out of the isolation done with multiple passes + +20.07.2019 + +- updated the CutOut tool so it will work on single PCB Gerbers or on PCB panel Gerbers +- updated languages +- 70% progress in Spanish Google translation + +19.07.2019 + +- fixed bug in FlatCAMObj.FlatCAMGeometry.ui_disconnect(); the widgets signals were not disconnected from handlers when required therefore the signals were connected in an exponential way +- some changes in the widgets used in the Selected tab for Geometry object +- some PEP8 cleanup in FlatCAMObj.py +- updated languages +- 60% progress in Spanish Google translation + +17.07.2019 + +- added some more strings to the translatable ones, especially the radio button labels +- updated the .POT file and the available translations +- 51% progress in Spanish Google translation +- version date change + +16.07.2019 + +- PEP8 correction in flatcamTools +- merged the Brazilian-portuguese language from a pull request made by Carlos Stein +- more PEP8 corrections + +15.07.2019 + +- some PEP8 corrections + +13.07.2019 + +- fixed a possible issue in Gerber Object class +- added a new tool in Gerber Editor: Mark Area Tool. It will mark the polygons in a edited Gerber object with areas within a defined range, allowing to delete some of the not necessary copper features +- added new menu links in the Gerber Editor menu for Eraser Tool and Mark Area Tool +- added key shortcuts for Eraser Tool (Ctrl+E) and Mark Area Tool (Alt+A) and updated the shortcuts list + +9.07.2019 + +- some changes in the app.on_togle_units() to make sure we don't try to convert empty parameters which may cause crashes on FlatCAM units change +- updated setup_ubuntu.sh file +- made sure to import certain libraries in some of the FlatCAM files and not to rely on chained imports + +8.07.2019 + +- fixed bug that allowed empty tool in the tools generated in Geometry object +- fixed bug in Tool Cutout that did not allow the transfer of used cutout tool diameter to the cutout geometry object + +5.07.2019 + +- fixed bug in CutOut Tool +- some other bug in CutOut tool fixed + +1.07.2019 + +- Spanish translation at 36% + +28.06.2019 + +- Spanish translation (Google Translate) at 21% + +27.06.2019 + +- added new translation: Spanish. Finished 10% + +23.06.2019 + +- fixes issues with units conversion when the tool diameters are a list of comma separated values (NCC Tool, SolderPaste Tool and Geometry Object) +- fixed a "typo" kind of bug in SolderPaste Tool +- RELEASE 8.919 + +22.06.2019 + +- some GUI layout optimizations in Edit -> Preferences +- added the possibility for multiple tool diameters in the Edit -> Preferences -> Geometry -> Geometry General -> Tool dia separated by comma +- fixed scaling for the multiple tool diameters in Edit -> Preferences -> Geometry -> Geometry General -> Tool dia, for NCC tools more than 2 and for Solderpaste nozzles more than 2 +- fixed bug in CNCJob where the CNC Tools table will show always only 2 decimals for Tool diameters regardless of the current measuring units +- made the tools diameters decimals in case of INCH FlatCAM units to be 4 instead of 3 +- fixed bug in updating Grid values whenever toggling the FlatCAM units and the X, Y Grid values are linked, bugs which caused the Y value to be scaled incorrectly +- set the decimals for Grid values to be set to 6 if the units of FlatCAM is INCH and to set to 4 if FlatCAM units are METRIC +- updated translations +- updated the Russian translation from 51% complete to 69% complete using the Yandex translation engine +- fixed recently introduced bug in milling drills/slots functions +- moved Substract Tool from Menu -> Edit -> Conversions to Menu -> Tool +- fixed bug in Gerber isolation (Geometry expects now a value in string format and not float) +- fixed bug in Paint tool: now it is possible to paint geometry generated by External Isolation (or Internal isolation) +- fixed bug in editing a multigeo Geometry object if previously a tool was deleted +- optimized the toggle of annotations; now there is no need to replot the entire CNCJob object too on toggling of the annotations +- on toggling off the plot visibility the annotations are turned off too +- updated translations; Russian translation at 76% (using Yandex translator engine - needs verification by a native speaker of Russian) + +20.06.2019 + +- fixed Scale and Buffer Tool in Gerber Editor +- fixed Editor Transform Tool in Gerber Editor +- added a message in the status bar when copying coordinates to clipboard with SHIFT + LMB click combo +- languages update + +19.06.2019 + +- milling an Excellon file (holes and/or slots) will now transfer the chosen milling bit diameter to the resulting Geometry object + +17.06.2019 + +- fixed bug where for Geometry objects after a successful object rename done in the Object collection view (Project tab), deselect the object and reselect it and then in the Selected tab the name is not the new one but the old one +- for Geometry objects, adding a new tool to the Tools table after a successful rename will now store the new name in the tool data + +15.06.2019 + +- fixed bug in Gerber parser that made the Gerber files generated by Altium Designer 18 not to be loaded +- fixed bug in Gerber editor - on multiple edits on the same object, the aperture size and dims were continuously multiplied due of the file units not being updated +- restored the FlatCAMObj.visible() to a non-threaded default + +11.06.2019 + +- fixed the Edit -> Conversion -> Join ... functions (merge() functions) +- updated translations +- Russian translate by @camellan is not finished yet +- some PEP8 cleanup in camlib.py +- RELEASE 8.918 + +9.06.2019 + +- updated translations +- fixed the the labels for shortcut keys for zoom in and zoom out both in the Menu links and in the Shortcut list +- made sure the zoom functions use the global_zoom_ratio parameter from App.self.defaults dictionary. +- some PEP8 cleanup + +8.06.2019 + +- make sure that the annotation shapes are deleted on creation of a new project +- added folder for the Russian translation +- made sure that visibility for TextGroup is set only if index is not None in VisPyVisuals.TextGroup.visible() setter + +7.06.2019 + +- fixed bug in ToolCutout where creating a cutout object geometry from another external isolation geometry failed +- fixed bug in cncjob TclCommand where the gcode could not be correctly generated due of missing bounds params in obj.options dict +- fixed a hardcoded tolerance in FlatCAMGeometry.generatecncjob() and in FlatCAMGeometry.mtool_gen_cncjob() to use the parameter from Preferences +- updated translations + +5.06.2019 + +- updated translations +- some layout changes in Edit -> Preferences such that the German translation (longer words than English) to fit correctly +- after editing an parameter the focus is lost so the user knows that something happened + +4.06.2019 + +- PEP8 updates in FlatCAMExcEditor.py +- added the Excellon Editor parameters to the Edit -> Preferences -> Excellon GUI +- fixed a small bug in Excellon Editor +- PEP8 cleanup in FlatCAMGui +- finished adding the Excellon Editor parameters into the app logic and added a selection limit within Excellon Editor just like in the other editors + +3.06.2019 + +- TclCommand Geocutout is now creating a new geometry object when working on a geometry, preserving also the origin object +- added a new parameter in Edit -> Preferences -> CNCJob named Annotation Color; it controls the color of the font used for annotations +- added a new parameter in Edit -> Preferences -> CNCJob named Annotation Size; it controls the size of the font used for annotations +- made visibility change threaded in FlatCAMObj() + +2.06.2019 + +- fixed issue with geometry name not being updated immediately after change while doing geocutout TclCommand +- some changes to enable/disable project context menu entry handlers + +1.06.2019 + +- fixed text annotation for CNC job so there are no overlapping numbers when 2 lines meet on the same point +- fixed issue in CNC job plotting where some of the isolation polygons are painted incorrectly +- fixed issue in CNCJob where the set circle steps is not used + +31.05.2019 + +- added the possibility to display text annotation for the CNC travel lines. The setting is both in Preferences and in the CNC object properties + +30.05.2019 + +- editing a multi geometry will no longer pop-up a Tcl window +- solved issue #292 where a new geometry renamed with many underscores failed to store the name in a saved project +- the name for the saved projects are updated to the current time and not to the time of the app startup +- some PEP8 changes related to comments starting with only one '#' symbol +- more PEP8 cleanup +- solved issue where after the opening of an object the file path is not saved for further open operations + +24.05.2019 + +- added a toggle Grid button to the canvas context menu in the Grids submenu +- added a toggle left panel button to the canvas context menu + +23.05.2019 + +- fixed bug in Gerber editor FCDisk and FCSemiDisc that the resulting geometry was not stored into the '0' aperture where all the solids are stored +- fixed minor issue in Gerber Editor where apertures were included in the saved object even if there was no geometric data for that aperture +- some PEP8 cleanup in FlatCAMApp.py + +22.05.2019 + +- Geo Editor - added a new editor tool, Eraser +- some PEP8 cleanup of the Geo Editor +- fixed some selection issues in the new tool Eraser in Geometry Editor +- updated the translation files +- RELEASE 8.917 + +21.05.2019 + +- added the file extension .ncd to the Excellon file extension list +- solved parsing issue for Excellon files generated by older Eagle versions (v6.x) +- Gerber Editor: finished a new tool: Eraser. It will erase certain parts of Gerber geometries having the shape of a selected shape. + +20.05.2019 + +- more PEP8 changes in Gerber editor +- Gerber Editor - started to work on a new editor tool: Eraser + +19.05.2019 + +- fixed the Circle Steps parameter for both Gerber and Geometry objects not being applied and instead the app internal defaults were used. +- fixed the Tcl command Geocutout issue that gave an error when using the 4 or 8 value for gaps parameter +- made wider the '#' column for Apertures Table for Gerber Object and for Gerber Editor; in this way numbers with 3 digits can be seen +- PEP8 corrections in FlatCAMGrbEditor.py +- added a selection limit parameter for Geometry Editor +- added entries in Edit -> Preferences for the new parameter Selection limit for both the Gerber and Geometry Editors. +- set the buttons in the lower part of the Preferences Window to have a preferred minimum width instead of fixed width +- updated the translation files + +18.05.2019 + +- added a new toggle option in Edit -> Preferences -> General Tab -> App Preferences -> "Open" Behavior. It controls which path is used when opening a new file. If checked the last saved path is used when saving files and the last opened path is used when opening files. If unchecked then the path for the last action (either open or save) is used. +- fixed App.convert_any2gerber to work with the new Gerber apertures data structure +- fixed Tool Sub to work with the new Gerber apertures data structure +- fixed Tool PDF to work with the new Gerber apertures data structure + +17.05.2019 + +- remade the Tool Cutout to work on panels +- remade the Tool Cutout such that on multiple applications on the same object it will yield the same result +- fixed an issue in the remade Cutout Tool where when applied on a single Gerber object, the Freeform Cutout produced no cutout Geometry object +- remade the Properties Tool such that it works with the new Gerber data structure in the obj.apertures. Also changed the view for the Gerber object in Properties +- fixed issue with false warning that the Gerber object has no geometry after an empty Gerber was edited and added geometry elements + +16.05.2019 + +- Gerber Export: made sure that if some of the coordinates in a Gerber object geometry are repeating then the resulting Gerber code include only one copy +- added a new parameter/feature: now the spindle can work in clockwise mode (CW) or counter clockwise mode (CCW) + +15.05.2019 + +- rewrited the Gerber Parser in camlib - success +- moved the self.apertures[aperture]['geometry'] processing for clear_geometry (geometry made with Gerber LPC command) in Gerber Editor +- Gerber Editor: fixed the Poligonize Tool to work with new geometric structure and took care of a special case +- Gerber Export is fixed to work with the new Gerber object data structure and it now works also for Gerber objects edited in Gerber Editor +- Gerber Editor: fixed units conversion for obj.apertures keys that require it +- camlib Gerber parser - made sure that we don't loose goemetry in regions +- Gerber Editor - made sure that for some tools the added geometry is clean (the coordinates are non repeating) +- covered some possible issues in Gerber Export + +12.05.2019 + +- some modifications to ToolCutout + +11.05.2019 + +- fixed issue in camlib.CNCjob.generate_from_excellon_by_tool() in the drill path optimization algorithm selection when selecting the MH algorithm. The new API's for Google OR-tools required some changes and also the time parameter can be now just an integer therefore I modified the GUI +- made the Feedrate Rapids parameter to depend on the type of preprocessor choosed. It will be showed only for a preprocessor which the name contain 'marlin' and for any preprocessor's that have 'custom' in the name +- fixed the camlib.Gerber functions of mirror, scale, offset, skew and rotate to work with the new data structure for apertures geometry +- fixed Gerber Editor selection to work with the new Gerber data structure in self.apertures +- fixed Gerber Editor FCPad class to work with the new Gerber data structure in self.apertures +- fixed camlib.Gerber issues related to what happen after parsing rectangular apertures +- wip in camblib.Gerber +- completely converted the Gerber editor to the new data structure +- Gerber Editor: added a threshold limit for how many elements a move selection can have. If above the threshold only a bounding box Poly will be painted on canvas as utility geometry. + +10.05.2019 + +- Gerber Editor - working in conversion to the new data format +- made sure that only units toggle done in Edit -> Preferences will toggle the data in Preferences. The menu entry Edit -> Toggle Units and the shortcut key 'Q' will change only the display units in the app +- optimized Transform tool +- RELEASE 8.916 + +9.05.2019 + +- reworked the Gerber parser + +8.05.2019 + +- added zoom fit for Set Origin command +- added move action for solid_geometry stored in the gerber_obj.apertures +- fixed camlib.Gerber skew, rotate, offset, mirror functions to work for geometry stored in the Gerber apertures +- fixed Gerber Editor follow_geometry reconstruction +- Geometry Editor: made the tool to be able to continuously move until the tool is exited either by ESC key or by right mouse button click +- Geometry Editor Move Tool: if no shape is selected when triggering this tool, now it is possible to make the selection inside the tool +- Gerber editor Move Tool: fixed a bug that repeated the plotting function unnecessarily +- Gerber editor Move Tool: if no shape is selected the tool will exit + +7.05.2019 + +- remade the Tool Panelize GUI +- work in Gerber Export: finished the header export +- fixed the Gerber Object and Gerber Editor Apertures Table to not show extra rows when there are aperture macros in the object +- work in Gerber Export: finished the body export but have some errors with clear geometry (LPC) +- Gerber Export - finished + +6.05.2019 + +- made units change from shortcut key 'Q' not to affect the preferences +- made units change from Edit -> Toggle Units not to affect the preferences +- remade the way the aperture marks are plotted in Gerber Object +- fixed some bugs related to moving an Gerber object with the aperture table in view +- added a new parameter in the Edit -> Preferences -> App Preferences named Geo Tolerance. This parameter control the level of geometric detail throughout FlatCAM. It directly influence the effect of Circle Steps parameter. +- solved a bug in Excellon Editor that caused app crash when trying to edit a tool in Tool Table due of missing a tool offset +- updated the ToolPanelize tool so the Gerber panel of type FlatCAMGerber can be isolated like any other FlatCAMGerber object +- updated the ToolPanelize tool so it can be edited +- modified the default values for toolchangez and endz parameters so they are now safe in all cases + +5.05.2019 + +- another fix for bug in clear geometry processing for Gerber apertures +- added a protection for the case that the aperture table is part of a deleted object +- in Script Editor added support for auto-add closing parenthesis, brace and bracket +- in Script Editor added support for "CTRL + / " key combo to comment/uncomment line + +4.05.2019 + +- fixed bug in camlib.parse_lines() in the clear_geometry processing section for self.apertures +- fixed bug in parsing Gerber regions (a point was added unnecessary) +- renamed the menu entry Edit -> Copy as Geo to Convert Any to Geo and moved it in the Edit -> Conversion +- created a new function named Convert Any to Gerber and installed it in Edit -> Conversion. It's doing what the name say: it will convert an Geometry or Excellon FlatCAM object to a Gerber object. + +01.05.2019 + +- the project items color is now controlled from Foreground Role in ObjectCollection.data() +- made again plot functions threaded but moved the dataChanged signal (update_view() ) to the main thread by using an already existing signal (plots_updated signal) to avoid the errors with register QVector +- Enable/Disable Object toggle key ("Space" key) will trigger also the datChanged signal for the Project MVC +- added a new setting for the color of the Project items, the color when they are disabled. +- fixed a crash when triggering 'Jump To' menu action (shortcut key 'J' worked ok) +- made some mods to what can be translated as some of the translations interfered with the correct functioning of FlatCAM +- updated the translations +- fixed bugs in Excellon Editor +- Excellon Editor: made Add Pad tool to work until right click +- Excellon Editor: fixed mouse right click was always doing popup context menu +- GUIElements.FCEntry2(): added a try-except clause +- made sure that the Tools Tab is cleared on Editors exit +- Geometry Editor: restored the old behavior: a tool is active until it is voluntarily exited: either by using the 'ESC' key, or selecting the Select tool or new: right click on canvas +- RELEASE 8.915 + +30.04.2019 + +- in ObjectCollection class, made sure that renaming an object in Project View does not result in an empty name. If new name is blank the rename is cancelled. +- made ObjectCollection.TreeItem() inherit KeySensitiveListVIew and implicitly QTreeView (in the hope that the theme applied on app will be applied on the tree items, too (for MacOs new DarkUI theme) +- renamed SilkScreen Tool to Substract Tool and move it's menu location in Edit -> Conversion +- started to modify the Substract Tool to work on Geometry objects too +- progress in the new Substract Tool for Geometry Objects +- finished the new Substract Tool +- added new setting for the color of the Project Tree items; it helps in providing contrast when using dark theme like the one in MacOS + +29.04.2019 + +- solved bug in Gerber Editor: the '0' aperture (the region aperture) had no size which created errors. Made the size to be zero. +- solved bug in editors: the canvas selection shape was not deleted on mouse release if the grid snap was OFF +- solved bug in Excellon Editor: when selecting a drill hole on canvas the selected row in the Tools Table was not the correct one but the next highest row +- finished the Silkscreen Tool but there are some limitations (some wires fragments from silkscreen are lost) +- solved the issue in Silkscreen Tool with losing some fragments of wires from silkscreen + +26.04.2019 + +- small changes in GUI; optimized contextual menu display +- made sure that the Project Tab is disabled while one of the Editors is active and it is restored after returning to app +- fixed some bugs recently introduced in Editors due of the changes done to the way mouse panning is detected +- cleaned up the context menu's when in Editors; made some structural changes +- updated the code in camlib.CNCJob.generate_from_excellon_by_tools() to work with the new API from Google OR-Tools +- all Gerber regions (G36 G37) are stored in the '0' aperture +- fixed a bug that added geometry with clear polarity in the apertures where was not supposed to be + +25.04.2019 + +- Geometry Editor: modified the intersection (if the selected shapes don't intersects preserve them) and substract functions (delete all shapes that were used in the process) +- work in the ToolSub +- for all objects, if in Selected the object name is changed to the same name, the rename is not done (because there is nothing changed) +- fixed Edit -> Copy as Geom function handler to work for Excellon objects, too +- made sure that the mouse pointer is restored to default on Editor exit +- added a toggle button in Preferences to toggle on/off the display of the selection box on canvas when the user is clicking an object or selecting it by mouse dragging. + +24.04.2019 + +- PDF import tool: working in making the PDF layer rendering multithreaded in itself (one layer rendered on each worker) +- PDF import tool: solved a bug in parsing the rectangle subpath (an extra point was added to the subpath creating nonexisting geometry) +- PDF import tool: finished layer rendering multithreading +- New tool: Silkscreen Tool: I am trying to remove the overlapped geo with the soldermask layer from overlay layer; layed out the class and functions - not working yet + +23.04.2019 + +- Gerber Editor: added two new tools: Add Disc and Add SemiDisc (porting of Circle and Arc from Geometry Editor) +- Gerber Editor: made Add Pad repeat until user exits the Add Pad through either mouse right click, or ESC key or deselecting the Add Pad menu item +- Gerber and Geometry Editors: fixed some issues with the Add Arc/Add Semidisc; in mode 132, the norm() function was not the one from numpy but from a FlatCAM Class. Also fixed some of the texts and made sure that when changing the mode, the current points are reset to prepare for the newly selected mode. +- Fixed Measurement Tool to show the mouse coordinates on the status bar (it was broken at some point) +- updated the translation files +- added more custom mouse cursors in Geometry and Gerber Editors +- RELEASE 8.914 + +22.04.2019 + +- added PDF file as type in the Recent File list and capability to load it from there +- PDF's can be drag & dropped on the GUI to be loaded +- PDF import tool: added support for save/restore Graphics stack. Only for scale and offset transformations and for the linewidth. This is the final fix for Microsoft PDF printer who saves in PDF format 1.7 +- PDF Import tool: added support for PDF files that embed multiple Gerber layers (top, bottom, outline, silkscreen etc). Each will be opened in it's own Gerber file. The requirement is that each one is drawn in a different color +- PDF Import tool: fixed bugs when drag & dropping PDF files on canvas the files geometry previously opened was added to the new one. Also scaling issues. Solved. +- PDF Import tool: added support for detection of circular geometry drawn with white color which means actually invisible color. When detected, FlatCAM will build an Excellon file out of those geoms. +- PDF Import tool: fixed storing geometries in apertures with the right size (before they were all stored in aperture D10) + +21.04.2019 + +- fixed the PDF import tool to work with files generated by the Microsoft PDF printer (chained subpaths) +- in PDF import tool added support for paths filled and at the same time stroked ('B' and 'B*'commands) +- added a shortcut key for PDF Import Tool (Alt+Q) and updated the Shortcut list (also with the 'T' and 'R' keys for Gerber Editor where they control the bend in Track and Region tool and the 'M' and 'D' keys for Add Arc tool in Geometry Editor) + +20.04.2019 + +- finished adding the PDF import tool although it does not support all kinds of outputs from PDF printers. Microsoft PDF printer is not supported. + +19.04.2019 + +- started to work on PDF import tool + + +18.04.2019 + +- Gerber Editor: added custom mouse cursors for each mode in Add Track Tool +- Gerber Editor: Poligonize Tool will first fuse polygons that touch each other and at a second try will create a polygon. The polygon will be automatically moved to Aperture '0' (regions). +- Gerber Editor: Region Tool will add regions only in '0' aperture +- Gerber Editor: the bending mode will now survive until the tool is exited +- Gerber Editor: solved some bugs related with deleting an aperture and updating the last_selected_aperture + +17.04.2019 + +- Gerber Editor: added some messages to warn user if no selection exists when trying to do aperture deletion or aperture geometry deletion +- fixed version check +- added custom mouse cursors for some tools in Gerber Editor +- Gerber Editor: added multiple modes to lay a Region: 45-degrees, reverse 45-degrees, 90-degrees, reverse 90-degrees and free-angle. Added also key shortcuts 'T' and 'R' to cycle forward, respectively in reverse through the modes. +- Excellon Editor: fixed issue not remembering last tool after adding a new tool +- added custom mouse cursors for Excellon and Geometry Editors in some of their tools + +16.04.2019 + +- added ability to use ENTER key to finish tool adding in Editors, NCC Tool, Paint Tool and SolderPaste Tool. +- Gerber Editor: started to add modes of laying a track +- Gerber Editor: Add Track Tool: added 5 modes for laying a track: 45-degrees, reverse-45 degrees, 90-degrees, reverse 90-degrees and free angle. Key 'T' will cycle forward through the modes and key 'R' will cycle in reverse through the track laying modes. +- Gerber Editor: Add Track Tool: first right click will finish the track. Second right click will exit the Track Tool and return to Select Tool. +- Gerber Editor: added protections for the Pad Array and Pad Tool for the case when the aperture size is zero (the aperture where to store the regions) + +15.04.2019 + +- working on a new tool to process automatically PcbWizard Excellon files which are generated in 2 files +- finished ToolPcbWizard; it will autodetect the Excellon format, units from the INF file +- Gerber Editor: reduced the delay to show UI when editing an empty Gerber object +- update the order of event handlers connection in Editors to first connect new handlers then disconnect old handlers. It seems that if nothing is connected some VispY functions like canvas panning no longer works if there is at least once nothing connected to the 'mouse_move' event +- Excellon Editor: update so always there is a tool selected even after the Excellon object was just edited; before it always required a click inside of the tool table, not you do it only if needed. +- fixed the menu File -> Edit -> Edit/Close Editor entry to reflect the status of the app (Editor active or not) +- added support in Excellon parser for autodetection of Excellon file format for the Excellon files generated by the following ECAD sw: DipTrace, Eagle, Altium, Sprint Layout +- Gerber Editor: finished a new tool: Poligonize Tool (Alt+N in Editor). It will fuse a selection of tracks into a polygon. It will fill a selection of polygons if they are apart and it will make a single polygon if the selection is overlapped. All the newly created filled polygons will be stored in aperture '0' (if it does not exist it will be automatically created) +- fixed a bug in Move command in context menu who crashed the app when triggered +- Gerber Editor: when adding a new aperture it will be store as the last selected and it will be used for any tools that are triggered until a new aperture is selected. + +14.04.2019 + +- Gerber Editor: Remade the processing of 'clear_geometry' (geometry generated by polygons made with Gerber LPC command) to work if more than one such polygon exists +- Gerber Editor: a disabled/enabled sequence for the VisPy cursor on Gerber edit make the graphics better +- Editors: activated an old function that was no longer active: each tool can have it's own set of shortcut keys, the Editor general shortcut keys that are letters are overridden +- Gerber and Geometry editors, when using the Backspace keys for certain tools, they will backtrack one point but now the utility geometry is immediately updated +- In Geometry Editor I fixed bug in Arc modes. Arc mode shortcut key is now key 'M' and arc direction change shortcut key is 'D' +- moved the key handler out of the Measurement tool to flatcamGUI.FlatCAMGui.keyPressEvent() +- Gerber Editor: started to add new function of poligonize which should make a filled polygon out of a shape +- cleaned up Measuring Tool +- solved bug in Gerber apertures size and dimensions values conversion when file units are different than app units + +13.04.2019 + +- updating the German translation +- Gerber Editor: added ability to change on the fly the aperture after one of the tools: Add Pad or Add Pad Array is activated +- Gerber Editor: if a tool is cancelled via key shortcut ESCAPE, the selection is now deleted and any other action require a new selection +- finished German translation (Google translated with some adjustments) +- final fix for issue #277. Previous fix was applied only for one case out of three. +- RELEASE 8.913 + +12.04.2019 + +- Gerber Editor: added support for Oblong type of aperture +- fixed an issue with automatically filled in aperture code when the edited Gerber file has no apertures; established an default with value 10 (according to Gerber specifications) +- fixed a bug in editing a blank Gerber object +- added handlers for the Gerber Editor context menu +- updated the translation template POT file and the EN PO/MO files +- Gerber Editor: added toggle effect to the Transform Tool +- Gerber Editor: added shortcut for Transform Tool and also toggle effect here, too +- updated the shortcut list with the Gerber Editor shortcut keys +- Gerber Editor: fixed error when adding an aperture with code value lower than the ones that already exists +- when adding an aperture with code '0' (zero) it will automatically be set with size zero and type: 'REG' (from region); here we store all the regions from a Gerber file, the ones without a declared aperture +- Gerber Editor: added support for Gerber polarity change commands (LPD, LPC) +- moved the polarity change processing from FlatCAMGrbEditor() class to camlib.Gerber().parse_lines() +- made optional the saving of an edited object. Now the user can cancel the changes to the object. +- replaced the standard buttons in the QMessageBox's used in the app with custom ones that can have text translated +- updated the POT translation file and the MO/PO files for English and Romanian language + +11.04.2019 + +- changed the color of the marked apertures to the global_selection_color +- Gerber Editor: added Transformation Tool and Rotation key shortcut +- in all Editors, manually deactivating a button in the editor toolbar will automatically select the 'Select' button +- fixed Excellon Editor selection: when a tool is selected in Tools Table, all the drills belonging to that tool are selected. When a drill is selected on canvas, the associated tool will be selected without automatically selecting all other drills with same tool +- Gerber Editor: added Add Pad Array tool +- Gerber Editor: in Add Pad Array tool, if the pad is not circular type, for circular array the pad will be rotated to match the array angle +- Gerber Editor: fixed multiple selection with key modifier such that first click selects, second deselects + +10.04.2019 + +- Gerber Editor: added Add Track and Add Region functions +- Gerber Editor: fixed key shortcuts +- fixed setting the Layout combobox in Preferences according to the current layout +- created menu links and shortcut keys for adding a new empty Gerber objects; on update of the edited Gerber, if the source object was an empty one (new blank one) this source obj will be deleted +- removed the old apertures editing from Gerber Obj selected tab +- Gerber Editor: added Add Pad (circular or rectangular type only) +- Gerber Editor: autoincrement aperture code when adding new apertures +- Gerber Editor: automatically calculate the size of the rectangular aperture + +9.04.2019 + +- Gerber Editor: added buffer and scale tools +- Gerber Editor: working on aperture selection to show on Aperture Table +- Gerber Editor: finished the selection on canvas; should be used as an template for the other Editors +- Gerber Editor: finished the Copy, Aperture Add, Buffer, Scale, Move including the Utility geometry +- Trying to fix bug in Measurement Tool: the mouse events don't disconnect +- fixed above bug in Measurement Tool (but there is a TODO there) + +7.04.2019 + +- default values for Jump To function is jumping to origin (0, 0) + +6.04.2019 + +- fixed bug in Geometry Editor in buffer_int() function that created an Circular Reference Error when applying buffer interior on a geometry. +- fixed issue with not possible to close the app after a project save. +- preliminary Gerber Editor.on_aperture_delete() +- fixed 'circular reference' error when creating the new Gerber file in Gerber Editor +- preliminary Gerber Editor.on_aperture_add() + +5.04.2019 + +- Gerber Editor: made geometry transfer (which is slow) to Editor to be multithreaded +- Gerber Editor: plotting process is showed in the status bar +- increased the number of workers in FlatCAM and made the number of workers customizable from Preferences +- WIP in Gerber Editor: geometry is no longer stored in a Rtree storage as it is not needed +- changed the way delayed plot is working in Gerber Editor to use a Qtimer instead of python threading module +- WIP in Gerber Editor +- fixed bug in saving the maximized state +- fixed bug in applying default language on first start +~~- on activating 'V' key shortcut (zoom fit) the mouse cursor is now jumping to origin (0, 0)~~ +- fixed bug in saving toolbars state; the file was saved before setting the self.defaults['global_toolbar_view] + +4.04.2019 + +- added support for Gerber format specification D (no zero suppression) - PCBWizard Gerber files support +- added support for Excellon file with no info about tool diameters - PCB Wizard Excellon file support +- modified the bogus diameters series for Excellon objects that do not have tool diameter info +- made Excellon Editor aware of the fact that the Excellon object that is edited has fake (bogus) tool diameters and therefore it will not sort the tools based on diameter but based on tool number +- fixed bug on Excellon Editor: when diameter is edited in Tools Table and the target diameter is already in the tool table, the drills from current tool are moved to the new tool (with new dia) - before it crashed +- fixed offset after editing drill diameters in Excellon Editor. + +3.04.2019 + +- fixed plotting in Gerber Editor +- working on GUI in Gerber Editor +- added a Gcode end_command: default is M02 +- modified the calling of the editor2object() slot function to fix an issue with updating geometry imported from SVG file, after edit +- working on Gerber Editor - added the key shortcuts: wip +- made saving of the project file non-blocking and also while saving the project file, if the user tries again to close the app while project file is being saved, the app will close only after saving is complete (the project file size is non zero) +- fixed the camlib.Geometry.import_svg() and camlib.Gerber.bounds() to work when importing SVG files as Gerber + +31.03.2019 + +- fixed issue #281 by making generation of a convex shape for the freeform cutout in Tool Cutout a choice rather than the default +- fixed bug in Tool Cutout, now in manual cutout mode the gap size reflect the value set +- changed Measuring Tool to use the mouse click release instead of mouse click press; also fixed a bug when using the ESC key. +- fixed errors when the File -> New Project is initiated while an Editor is still active. +- the File->Exit action handler is now self.final_save() +- wip in Gerber editor + +29.03.2019 + +- update the TCL keyword list +- fix on the Gerber parser that makes searching for '%%' char optional when doing regex search for mode, units or image polarity. This allow loading Gerber files generated by the ECAD software TCl4.4 +- fix error in plotting Excellon when toggling units +- FlatCAM editors now are separated each in it's own file +- fixed TextTool in Geometry Editor so it will open the notebook on activation and close it after finishing text adding +- started to work on a Gerber Editor +- added a fix in the Excellon parser by allowing a comma in the tool definitions between the diameter and the rest + +28.03.2019 + +- About 45% progress in German translation +- new feature: added ability to edit MultiGeo geometry (geometry from Paint Tool) +- changed all the info messages that are of type warning, error or success so they have a space added after the keyword +- changed the Romanian translation by adding more diacritics +- modified Gerber parser to copy the follow_geometry in the self.apertures +- modified the Properties Tool to show the number of elements in the follow_geometry for each aperture +- modified the copy functions to copy the follow_geometry and also the apertures if it's possible (only for Gerber objects) + +27.03.2019 + +- added new feature: user can delete apertures in Advanced mode and then create a new FlatCAM Gerber object +- progress in German translation. About 27% done. +- fixed issue #278. Crash on name change in the Name field in the Selected Tab. + +26.03.2019 + +- fixed an issue where the Geometry plot function protested that it does not have an parameter that is used by the CNCJob plot function. But both inherit from FaltCAMObj plot function which does not have that parameter so something may need to be changed. Until then I provided a phony keyboard parameter to make that function 'shut up' +- fixed bug: after using Paint Tool shortcut keys are disabled +- added CNCJob geometry for the holes created by the drills from Excellon objects + +25.03.2019 + +- in the TCL completer if the word is already complete don't add it again but add a space +- added all the TCL keywords in the completer keyword list +- work in progress in German translation ~7% +- after any autocomplete in TCL completer, a space is added +- fixed an module import issue in NCC Tool +- minor change (optimization) of the CNCJob UI +- work in progress in German translation ~20% + +22.03.2019 + +- fixed an error that created a situation that when saving a project with some of the CNCJob objects disabled, on project reload the CNCJob objects are no longer loaded +- fixed the Gerber.merge() function. When some of the Gerber files have apertures with same id, create a new aperture id for the object that is fused because each aperture id may hold different geometries. +- changed the autoname for saving Preferences, Project and PNG file + +20.03.2019 + +- added autocomplete finish with ENTER key for the TCL Shell +- made sure that the autocomplete function works only for FlatCAM Scripts +- ESC key will trigger normal view if in full screen and the ESC key is pressed +- added an icon and title text for the Toggle Units QMessageBox + +19.03.2019 + +- added autocomplete for Code editor; +- autocomplete in Code Editor is finished by hitting either TAB key or ENTER key +- fixed the Gerber.merge() to work for the case when one of the merged Gerber objects solid_geometry type is Polygon and not a list + +18.03.2019 + +- added ability to create new scripts and open scripts in FlatCAM Script Editor +- the Code Editor tab name is changed according to the task; 'save' and 'open' buttons will have filters installed for the QOpenDialog fit to the task +- added ability to run a FlatCAM Tcl script by double-clicking on the file +- in Code Editor added shortcut combo key Ctrl+Shift+V to function as a Special Paste that will replace the '\' char with '/' so the Windows paths will be pasted correctly for TCL Shell. Also doing SHIFT + LMB on the Paste in contextual menu is doing the same. + +17.03.2019 + +- remade the layout in 2Sided Tool +- work in progress for translation in Romanian - 91% +- changed some of the app strings formatting to work better with Poedit translation software +- fixed bug in Drillcncjob TclCommand +- finished translation in Romanian +- made the translations work when the app is frozen with CX_freeze +- some formatting changes for the application strings +- some changes on how the first layout is applied +- minor bug fixes (typos from copy/paste from another part of the program) + +16.03.2019 + +- fixed bug in Paint Tool - Single Poly: no geometry was generated +- work in progress for translation in Romanian - 70% + +13.03.2019 + +- made the layout combobox current item from Preferences -> General window to reflect the current layout +- remade the POT translate file +- work in progress in translation for Romanian language 44% +- fix for showing tools by activating them from the Menu - final fix. + +11.03.2019 + +- changed some icons here and there +- fixed the Properties Project menu entry to work on the new way +- in Properties tool now the Gerber apertures show the number of polygons in 'solid_geometry' instead of listing the objects +- added a visual cue in Menu -> Edit about the entries to enter the Editor and to Save & Exit Editor. When one is enabled the other is disabled. +- grouped all the UI files in flatcamGUI folder +- grouped all parser files in flatcamParsers folder +- another changes to the final_save() function +- some strings were left outside the translation formatting - fixed +- finished the replacement of '_' symbols throughout the app which conflicted with the _() function used by the i18n +- reverted changes in Tools regarding the toggle effect - now they work as expected + +10.03.2019 + +- added a fix in the Gerber parser when adding the geometry in the self.apertures dict for the case that the current aperture is None (Allegro does that) +- finished support for internationalization by adding a set of .po/.mo files for the English language. Unfortunately the final action can be done only when Beta will be out of Beta (no more changes) or when I will decide to stop working on this app. +- changed the tooltip for 'feedrate_rapids' parameter to point out that this parameter is useful only for the Marlin preprocessor +- fix app crash for the case that there are no translation files +- fixed some forgotten strings to be prepared for internationalization in ToolCalculators +- fixed Tools menu no longer working due of changes +- added some test translation for the ToolCalculators (in Romanian) +- fixed bug in ToolCutOut where for each tool invocation the signals were reconnected +- fixed some issues with ToolMeasurement due of above changes +- updated the App.final_save() function +- fixed an issue created by the fact that I used the '_' char inside the app to designate unused info and that conflicted with the _() function used by gettext +- made impossible to try to reapply current language that it's already applied (un-necessary) + +8.03.2019 + +- fixed issue when doing th CTRL (or SHIFT) + LMB, the focus is automatically moved to Project Tab +- further work in internationalization, added a fallback to English language in case there is no translation for a string +- fix for issue #262: when doing Edit-> Save & Close Editor on a Geometry that is not generated through first entering into an Editor, the geometry disappear +- finished preparing for internationalization for the files: camlib and objectCollection +- fixed tools shortcuts not working anymore due of the new toggle parameter for the .run(). +- finished preparing for internationalization for the files: FlatCAMEditor, FlatCAMGUI +- finished preparing for internationalization for the files: FlatCAMObj, ObjectUI +- sorted the languages in the Preferences combobox + +7.03.2019 + +- made showing a shape when hovering over objects, optional, by adding a Preferences -> General parameter +- starting to work in internationalization using gettext() +- Finished adding _() in FlatCAM Tools +- fixed Measuring Tool - after doing a measurement the Notebook was switching to Project Tab without letting the user see the results +- more work on the translation engine; the app now restarts after a language is applied +- added protection against using Travel Z parameter with negative or zero value (in Geometry). +- made sure that when the Measuring Tools is active after last click the Status bar is no longer deleted + +6.03.2019 + +- modified the way the FlatCAM Tools are run from toolbar as opposed of running them from other sources +- some Gerber UI changes + +5.03.2019 + +- modified the grbl-laser preprocessor lift_code() +- treated an error created by Z_Cut parameter being None +- changed the hover and selection box transparency + +4.03.2019 + +- finished work on object hovering +- fixed Excellon object move and all the other transformations +- starting to work on Manual Cutout Tool +- remade the CutOut Tool +- finished Manual Cutout Tool by adding utility geometry to the cutting geometry +- added CTRL + click behavior for adding manual bridge gaps in Cutout Tool +- in Tool Cutout added shortcut key 'Escape' to cancel the current adding of bridge gaps + +3.03.2019 + +- minor UI changes for Gerber UI +- ~~after an object move, the apertures plotted shapes are deleted from canvas and the 'mark all' button is deselected~~ +- after move tool action or any other transform (rotate, skew, scale, mirror, offset), the plotted apertures are kept plotted. +- changing units now will convert all the default values from one unit type to another +- prettified the selection shape and the moving shape +- initial work in object hovering shape + +02.03.2019 + +- fixed offset, rotate, scale, skew for follow_geometry. Fixed the move tool also. +- fixed offset, rotate, scale, skew for 'solid_geometry' inside the self.apertures. + +28.02.2019 + +- added a change that when a double click is performed in a object on canvas resulting in a selection, if the notebook is hidden then it will be displayed +- progress in ToolChange Custom commands replacement and rename + +27.02.2019 + +- made the Custom ToolChange Text area in CNCJob Selected Tab depend on the status of the ToolChange Enable Checkbox even in the init stage. +- added some parameters throughout camlib gcode generation functions; handled some possible errors (e.g like when attempting to use an empty Custom GCode Toolchange) +- added toggle effect for the tools in the toolbar. +- enhanced the toggle effect for the tools in the Tools Toolbar and also for Notebook Tab selection: if the current tool is activated it will toggle the notebook side but only if the installed widget is itself. If coming from another tool, the notebook will stay visible +- upgraded the Tool Cutout when done from Gerber file to create a convex_hull around the Gerber file rather than trying to isolate it +- added some protections for the FlatCAM Tools run after an object was loaded + +26.02.2019 + +- added a function to read the parameters from ToolChange macro Text Box (I need to move it from CNCJob to Excellon and Geometry) +- fixed the geometry adding to the self.apertures in the case when regions are done without declaring any aperture first (Allegro does that). Now, that geometry will be stored in the '0' aperture with type REG +- work in progress to Toolchange_Custom code replacement -> finished the parse and replace function +- fixed mouse selection on canvas, mouse drag, mouse click and mouse double click +- fixed Gerber Aperture Table dimensions +- added a Mark All button in the Gerber aperture table. +- because adding shapes to the shapes collection (when doing Mark or Mark All) is time consuming I made the plot_aperture() threaded. +- made the polygon fusing in modified Gerber creation, a list comprehension in an attempt for optimization +- when right clicking the files in Project tab, the Save option for Excellon no longer export it but really save the original. +- in ToolChange Custom Code replacement, the Text Box in the CNCJob Selected tab will be active only if there is a 'toolchange_custom' in the name of the preprocessor file. This assume that it is, or was created having as template the Toolchange Custom preprocessor file. + + +25.02.2019 + +- fixed the Gerber object UI layout +- added ability to mark individual apertures in Gerber file using the Gerber Aperture Table +- more modifications for the Gerber UI layout; made 'follow' an advanced Gerber option +- added in Preferences a new Category: Gerber Advanced Options. For now it controls the display of Gerber Aperture Table and the "follow" attribute4 +- fixed FlatCAMGerber.merge() to merge the self.apertures[ap]['solid_geometry'] too +- started to work on a new feature that allow adding a ToolChange GCode macro - GUI added both in CNCJob Selected tab and in CNCJob Preferences +- added a limited 'sort-of' Gerber Editor: it allows buffering and scaling of apertures + +24.02.2019 + +- fixed a small bug in the Tool Solder Paste: the App don't take into consideration pads already filled with solder paste. +- prettified the defaults files and the recent file. Now they are ordered and human readable +- added a Toggle Code Editor Menu and key shortcut +- added the ability to open FlatConfig configuration files in Code Editor, Modify them and then save them. +- added ability to double click the FlatConfig files and open them in the FlatCAM Code Editor (to be verified) +- when saving a file from Code Editor and there is no object active then the OpenFileDialog filters are reset to FlatConfig files. +- reverted a change in GCode that might affect Gerber polarity change in Gerber parser +- ability to double click the FlatConfig files and open them in the FlatCAM Code Editor - fixed and verified +- fixed the Set To Origin function when Escape was clicked +- added all the Tools in a new ToolBar +- fixed bug that after changing the layout all the toolbar actions are no longer working +- fixed bug in Set Origin function +- fixed a typo in Toolchange_Probe_MACH3 preprocessor + +23.02.2019 + +- remade the SolderPaste geometry generation function in ToolSoderPaste to work in certain scenarios where the Gerber pads in the SolderPaste mask Gerber may be just pads outlines +- updated the Properties Tool to include more information's, also details if a Geometry is of type MultiGeo or SingleGeo +- remade the Preferences GUI to include the Advanced Options in a separate way so it is obvious which are displayed when App Level is Advanced. +- added protection, not allowing the user to make a Paint job on a MultiGeo geometry (one that is converted in the Edit -> Conversion menu)) because it is not supported + +22.02.2019 + +- added Repetier preprocessor file +- removed "added ability to regenerate objects (it's actually deletion followed by recreation)" because of the way Python pass parameters to functions by reference instead of copy +- added ability to toggle globally the display of ToolTips. Edit -> Preferences -> General -> Enable ToolTips checkbox. +- added true fullscreen support (for Windows OS) +- added the ability of context menu inside the GuiElements.FCCombobox() object. +- remade the UI for ToolSolderPaste. The object comboboxes now have context menu's that allow object deletion. Also the last object created is set as current item in comboboxes. +- some GUI elements changes + +21.02.2019 + +- added protection against creating CNCJob from an empty Geometry object (with no geometry inside) +- changed the shortcut key for YouTube channel from F2 to key F4 +- changed the way APP LEVEL is showed both in Edit -> Preferences -> General tab and in each Selected Tab. Changed the ToolTips content for this. +- added the functions for GCode View and GCode Save in Tool SolderPaste +- some work in the Gcode generation function in Tool SolderPaste +- added protection against trying to create a CNCJob from a solder_paste dispenser geometry. This one is different than the default Geometry and can be handled only by SolderPaste Tool. +- ToolSolderPaste tools (nozzles) now have each it's own settings +- creating the camlib functions for the ToolSolderPaste gcode generation functions +- finished work in ToolSolderPaste +- fixed issue with not updating correctly the plot kind (all, cut, travel) when clicking in the CNC Tools Table plot buttons +- made the GCode Editor for ToolSolderPaste clear the text before updating the Code Editor tab +- all the Tabs in Plot Area are closed (except Plot Area itself) on New Project creation +- added ability to regenerate objects (it's actually deletion followed by recreation) + +20.02.2019 + +- finished added a Tool Table for Tool SolderPaste +- working on multi tool solder paste dispensing +- finished the Edit -> Preferences defaults section +- finished the UI, created the preprocessor file template +- finished the multi-tool solder paste dispensing: it will start using the biggest nozzle, fill the pads it can, and then go to the next smaller nozzle until there are no pads without solder. + +19.02.2019 + +- added the ability to compress the FlatCAM project on save with LZMA compression. There is a setting in Edit -> Preferences -> Compression Level between 0 and 9. 9 level yields best compression at the price of RAM usage and time spent. +- made FlatCAM able to load old type (uncompressed) FlatCAM projects +- fixed issue with not loading old projects that do not have certain information's required by the new versions of FlatCAM +- compacted a bit more the GUI for Gerber Object +- removed the Open Gerber with 'follow' menu entry and also the open_gerber Tcl Command attribute 'follow'. This is no longer required because now the follow_geometry is stored by default in a Gerber object attribute gerber_obj.follow_geometry +- added a new parameter for the Tcl CommandIsolate, named: 'follow'. When follow = 1 (True) the resulting geometry will follow the Gerber paths. +- added a new setting in Edit -> Preferences -> General that allow to select the type of saving for the FlatCAM project: either compressed or uncompressed. Compression introduce an time overhead to the saving/restoring of a FlatCAM project. +- started to work on Solder Paste Dispensing Tool +- fixed a bug in rotate from shortcut function +- finished generating the solder paste dispense geometry + +18.02.2019 + +- added protections again wrong values for the Buffer and Paint Tool in Geometry Editor +- the Paint Tool in Geometry Editor will load the default values from Tool Paint in Preferences +- when the Tools in Geometry Editor are activated, the notebook with the Tool Tab will be unhidden. After execution the notebook will hide again for the Buffer Tool. +- changed the font in Tool names +- added in Geometry Editor a new Tool: Transformation Tool. +- in Geometry Editor by selecting a shape with a selection shape, that object was added multiple times (one per each selection) to the selected list, which is not intended. Bug fixed. +- finished adding Transform Tool in Geometry Editor - everything is working as intended +- fixed a bug in Tool Transform that made the user to not be able to capture the click coordinates with SHIFT + LMB click combo +- added the ability to choose an App QStyle out of the offered choices (different for each OS) to be applied at the next app start (Preferences -> General -> Gui Pref -> Style Combobox) +- added support for FlatCAM usage with High DPI monitors (4k). It is applied on the next app startup after change in Preferences -> General -> Gui Settings -> HDPI Support Checkbox +- made the app not remember the window size if the app is maximized and remember in QSettings if it was maximized. This way we can restore the maximized state but restore the windows size unmaximized +- added a button to clear the GUI preferences in Preferences -> General -> Gui Settings -> Clear GUI Settings +- added key shortcuts for the shape transformations within Geometry Editor: X, Y keys for Flip(mirror), Shift+X, Shift+Y combo keys for Skew and Alt+X, Alt+Y combo keys for Offset +- adjusted the plotcanvas.zomm_fit() function so the objects are better fit into view (with a border around) +- modified the GUI in Objects Selected Tab to accommodate 2 different modes: basic and Advanced. In Basic mode, some of the functionality's are hidden from the user. +- added Tool Transform preferences in Edit -> Preferences and used them through out the app +- made the output of Panelization Tool a choice out of Gerber and Geometry type of objects. Useful for those who want to engrave multiple copies of the same design. + +17.02.2019 + +- changed some status bar messages +- New feature: added the capability to view the source code of the Gerber/Excellon file that was loaded into the app. The file is also stored as an object attribute for later use. The view option is in the project context menu and in Menu -> Options -> View Source +- Serialized the source_file of the Objects so it is saved in the FlatCAM project and restored. +- if there is a single tool in the tool list (Geometry , Excellon) and the user click the Generate GCode, use that tool even if it is not selected +- fixed issue where after loading a project, if the default kind of CNCjob view is only 'cuts' the plot will revert to the 'all' type +- in Editors, if the modifier key set in Preferences (CTRL or SHIFT key) is pressed at the end of one tool operation it will automatically continue to that action until the modifier is no longer pressed when Select tool will be automatically selected. +- in Geometry Editor, on entry the notebook is automatically hidden and restored on Geometry Editor exit. +- when pressing Escape in Geometry Editor it will automatically deselect any shape not only the currently selected tool. +- when deselecting an object in Project menu the status bar selection message is deleted +- added ability to save the Gerber file content that is stored in FlatCAM on Gerber file loading. It's useful to recover from saved FlatCAM projects when the source files are no longer available. +- fixed an issue where the function handler that changed the layout had a parameter changed accidentally by an index value passed by the 'activate' signal to which was connected +- fixed bug in paint function in Geometry Editor that didn't allow painting due of overlap value + +16.02.2019 + +- added the 'Save' menu entry to the Project context menu, for CNCJob: it will export the GCode. +- added messages in info bar when selecting objects in the Project View list +- fixed DblSided Tool so it correctly creates the Alignment Drills Excellon file using the new structure +- fixed DblSided Tool so it will not crash the app if the user tries to make a mirror using no coordinates +- added some relevant status bar messages in DblSided Tool +- fixed DblSided Tool to correctly use the Box object (until now it used as reference only Gerber object in spite of Excellon or Geometry objects being available) +- fixed DblSided Tool crash when trying to create Alignment Drills object without a Tool diameter specified +- fixed DblSided Tool issue when entering Tool diameter values with comma decimal separator instead of decimal dot separator +- fixed Cutout Tool Freeform to generate cutouts with options: LR, TB. 2LR, 2TB which didn't worked previously +- fixed Excellon parser to detect correctly the units and zeros for Excellon's generated by Eagle 9.3.0 +- modified the initial size of the canvas on startup +- modified the build file (make_win.py) to solve the issue with suddenly not accepting the version as Beta +- changed the initial layout to 'compact' +- updated the install scripts to uninstall a previously installed FlatCAM Beta (that has the same GUID) + +15.02.2019 + +- rearranged the File and Edit menu's and added some explanatory tooltips on certain menu items that could be seen as cryptic +- added Excellon Export Options in Edit -> Preferences +- started to work in using the Excellon Export parameters +- remade the Excellon export function to work with parameters entered in Edit -> Preferences -> Excellon Export +- added a new entry in the Project Context Menu named 'Save'. It will actually work for Geometry and it will do Export DXF and for Excellon and it will do Export Excellon +- reworked the offer to save a project so it is done only if there are objects in the project but those objects are new and/or are modified since last project load (if an old project was loaded.) +- updated the Excellon plot function so it can plot the Excellon's from old projects +- removed the message boxes that popup on Excellon Export errors and replaced them with status bar messages +- small change in tab width so the tabs looks good in Linux, too. + +14.02.2019 + +- added total travel distance for CNCJob object created from Excellon Object in the CNCJob Selected tab +- added 'FlatCAM ' prefix to any detached tab, for easy identification +- remade the Grids context menu (right mouse button click on canvas). Now it has values linked to the units type (inch or mm). Added ability to add or delete grid values and they are persistent. +- updated the function for the project context menu 'Generate CNC' menu entry (Action) to use the modernized function FlatCAMObj.FlatCAMGeometry.on_generatecnc_button_click() +- when linked, the grid snap on Y will copy the value in grid snap on X in real time +- in Gerber aperture table now the values are displayed in the current units set in FlatCAM +- added shortcut key 'J' (jump to location) in Editors and added an icon to the dialog popup window +- the notebook is automatically collapsed when there are no objects in the collection and it is showed when adding an object +- added new options in Edit -> Preferences -> General -> App Preferences to control if the Notebook is showed at startup and if the notebook is closed when there are no objects in the collection and showed when the collection has objects. + +13.02.2019 + +- added new parameter for Excellon Object in Preferences: Fast Retract. If the checkbox is checked then after reaching the drill depth, the drill bit will be raised out of the hole asap. +- started to work on GUI forms simplification +- changed the Preferences GUI for Geometry and Excellon Objects to make a difference between parameters that are changed often and those that are not. +- changed the layout in the Selected Tab UI +- started to add apertures table support +- finished Gerber aperture table display +- made the Gerber aperture table not visible as default and added a checkbox that can toggle the visibility +- fixed issue with plotting in CNCJob; with Plot kind set to something else than 'all' when toggling Plot, it was defaulting to kind = 'all' +- added (and commented) an experimental FlatCAMObj.FlatCAMGerber.plot_aperture() + +12.02.2019 + +- whenever a FlatCAM tool is activated, if the notebook side is hidden it will be unhidden +- reactivated the Voronoi classes +- added a new parameter named Offset in the Excellon tool table - work in progress +- finished work on Offset parameter in Excellon Object (Excellon Editor, camlib, FlatCAMObj updated to take this param in consideration) +- fixed a bug where in Excellon editor when editing a file, a tool was automatically added. That is supposed to happen only for empty newly created Excellon Objects. +- starting to work on storing the solid_geometry for each tool in part in Excellon Object +- stored solid_geometry of Excellon object in the self.tools dictionary +- finished the solid_geometry restore after edit in Excellon Editor +- finished plotting selection for each tool in the Excellon Tool Table +- fixed the camlib.Excellon.bounds() function for the new type of Excellon geometry therefore fixed the canvas selection, too + + +10.02.2019 + +- the SELECTED type of messages are no longer printed to shell from 2 reasons: first, too much spam and second, issue with displaying html +- on set_zero function and creation of new geometry or new excellon there is no longer a zoom fit +- repurposed shortcut key 'Delete' to delete tools in tooltable when the mouse is over the Seleted tab (with Geometry inside) or in Tools tab (when NCC Tool or Paint Tool is inside). Or in Excellon Editor when mouse is hovering the Selected tab selecting a tool, 'Delete' key will delete that tool, if on canvas 'Delete' key will delete a selected shape (drill). In rest, will delete selected objects. +- adjusted the preprocessor files so the Spindle Off command (M5) is done before the move to Toolchange Z +- adjusted the Toolchange Manual preprocessor file to have more descriptive messages on the toolchange event +- added a strong focus to the object_name entry in the Selected tab +- the keypad keyPressed are now detected correctly +- added a pause and message/warning to do a rough zero for the Z axis, in case of Toolchange_Probe_MACH3 preprocessor file +- changes in Toolchange_Probe_MACH3 preprocessor file + +9.02.2019 + +- added a protection for when saving a file first time, it require a saved path and if none then it use the current working directory +- added into Preferences the Calculator Tools +- made the Preferences window scrollable on the horizontal side (it was only vertically scrollable before) +- fixed an error in Excellon Editor -> add drill array that could appear by starting the function to add a drill array by shortcut before any mouse move is registered while in Editor +- changed the messages from status bar on new object creation/selection +- in Geometry Editor fixed the handler for the Rotate shortcut key ('R') + +8.02.2019 + +- when shortcut keys 1, 2, 3 (tab selection) are activated, if the splitter left side (the notebook) is hidden it will be made visible +- changed the menu entry Toggle Grid name to Toggle Grid Snap +- fixed errors in Toggle Axis +- fixed error with shortcut key triggering twice the keyPressEvent when in the Project List View +- moved all shortcut keys handlers from Editors to the keyPressEvent() handler from FLatCAMGUI +- in Excellon Editor added a protection for Tool_dia field in case numbers using comma as decimal separator are used. Also added a QDoubleValidator forcing a number with max 4 decimals and from 0.0000 to 9.9999 +- in Excellon Editor added a shortcut key 'T' that popup a window allowing to enter a new Tool with the set diameter +- in App added a shortcut key 'T' that popup a windows allowing to enter a new Tool with set diameter only when the Selected tab is on focus and only if a Geometry object is selected +- changed the shortcut key for Transform Tool from 'T' to 'Alt+T' +- fixed bug in Geometry Selected tab that generated error when used tool offset was less than half of either total length or half of total width. Now the app signal the issue with a status bar message +- added Double Validator for the Offset value so only float numbers can be entered. +- in App added a shortcut key 'T' that popup a windows allowing to enter a new Tool with set diameter only when the Tool tab is on focus and only if a NCC Tool or Paint Area Tool object is installed in the Tool Tab +- if trying to add a tool using shortcut key 'T' with value zero the app will react with a message telling to use a non-zero value. + +7.02.2019 + +- in Paint Tool, when painting single polygon, when clicking on canvas for the polygon there is no longer a selection of the entire object +- commented some debug messages +- imported speedups for shapely +- added a disable menu entry in the canvas contextual menu +- small changes in Tools layout +- added some new icons in the help menu and reorganized this menu +- added a new function and the shortcut 'leftquote' (left of Key 1) for toggle of the notebook section +- changed the Shortcut list shortcut key to F3 +- moved some graphical classes out of Tool Shell to GUIElements.py where they belong +- when selecting an object on canvas by single click, it's name is displayed in status bar. When nothing is selected a blank message (nothing) it's displayed +- in Move Tool I've added the type of object that was moved in the status bar message +- color coded the status bar bullet to blue for selection +- the name of the selected objects are displayed in the status bar color coded: green for Gerber objects, Brown for Excellon, Red for Geometry and Blue for CNCJobs. + +6.02.2019 + +- fixed the units calculators crash FlatCAM when using comma as decimal separator +- done a regression on Tool Tab default text. It somehow delete Tools in certain scenarios so I got rid of it +- fixed bug in multigeometry geometry not having the bounds in self.options and crashing the GCode generation +- fixed bug that crashed whole application in case that the GCode editor is activated on a Tool gcode that is defective. +- fixed bug in Excellon Slots milling: a value of a dict key was a string instead to be an int. A cast to integer solved it. +- fixed the name self-insert in save dialog file for GCode; added protection in case the save path is None +- fixed FlatCAM crash when trying to make drills GCode out of a file that have only slots. +- changed the messages for Units Conversion +- all key shortcuts work across the entire application; moved all the shortcuts definitions in FlatCAMGUI.keyPressEvent() +- renamed the theme to layout because it is really a layout change +- added plot kind for CNC Job in the App Preferences +- combined the geocutout and cutout_any TCL commands - work in progress +- added a new function (and shortcut key Escape) that when triggered it deselects all selected objects and delete the selection box(es) +- fixed bug in Excellon Gcode generation that made the toolchange X,Y always none regardless of the value in Preferences +- fixed the Tcl Command Geocutout to work with Gerber objects too (besides Geometry objects) + +5.02.3019 + +- added a text in the Selected Tab which is showed whenever the Selected Tab is selected but without having an object selected to display it's properties +- added an initial text in the Tools tab +- added possibility to use the shortcut key for shortcut list in the Notebook tabs +- added a way to set the Probe depth if Toolchange_Probe preprocessors are selected +- finished the preprocessor file for MACH3 tool probing on toolchange event +- added a new parameter to set the feedrate of the probing in case the used preprocessor does probing (has toolchange_probe in it's name) +- fixed bug in Marlin preprocessor for the Excellon files; the header and toolchange event always used the parenthesis witch is not compatible with GCode for Marlin +- fixed a issue with a move to Z_move before any toolchange + +4.02.2019 + +- modified the Toolchange_Probe_general preprocessor file to remove any Z moves before the actual toolchange event +- created a prototype preprocessor file for usage with tool probing in MACH3 +- added the default values for Tool Film and Tool Panelize to the Edit -> Preferences +- added a new parameter in the Tool Film which control the thickness of the stroke width in the resulting SVG. It's a scale parameter. +- whatever was the visibility of the corresponding toolbar when we enter in the Editor, it will be set after exit from the Editor (either Geometry Editor or Excellon Editor). +- added ability to be detached for the tabs in the Notebook section (Project, Selected and Tool) +- added ability for all detachable tabs to be restored to the same position from where they were detached. +- changed the shortcut keys for Zoom In, Zoom Out and Zoom Fit from 1, 2, 3 to '-', '=' respectively 'V'. Added new shortcut keys '1', '2', '3' for Select Project Tab, Select Selected Tab and Select Tool Tab. +- formatted the Shortcut List Tab into a HTML table + +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. +- added a remove_tools() function before install_tools() in the init_tools() that is called when creating a new project. Should solve the issue with having double menu entry's in the TOOLS menu +- fixed remove_tools() so the Tcl Shell action is readded to the Tools menu and reconnected to it's slot function +- added an automatic name on each save operation based on the object name and/or the current date +- added more information's for the statistics + +2.2.2019 + +- code cleanup in Tools +- some GUI structure optimization's +- added protection against entering float numbers with comma separator instead of decimal dot separator in key points of FlatCAM (not everywhere) +- added a choice of plotting the kind of geometry for the CNC plot (all, travel and cut kind of geometries) in CNCJob Selected Tab +- added a new preprocessor file named: 'probe_from_zmove' which allow probing to be done from z_move position on toolchange event +- fixed the snap magnet button in Geometry Editor, restored the checkable property to True +- some more changes in the Editors GUI in deactivate() function +- a fix for saving as empty an edited new and empty Excellon Object + +1.02.2019 + +- fixed preprocessor files so now the bounds values are right aligned (assuming max string length of 9 chars which means 4 digits and 4 decimals) +- corrected small type in list_sys Tcl command; added a protection of the Plot Area Tab after a successful edit. +- remade the way FlatCAM saves the GUI position data from a file (previously) to use PyQt QSettings +- added a 'theme' combo selection in Edit -> Preferences. Two themes are available: standard and compact. +- some code cleanup +- fixed a source of possible errors in DetachableTab Widget. +- fixed gcode conversion/scale (on units change) when multiple values are found on each line +- replaced the pop-up window for the shortcut list with a new detachable tab +- removed the pop-up messages from the rotate, skew, flip commands + +31.01.2019 + +- added a parameter ('Fast plunge' in Edit -> Preferences -> Geometry Options and Excellon Options) to control if the fast move to Z_move is done or not +- added new function to toggle fullscreen status in Menu -> View -> Toggle Full Screen. Shortcut key: Alt+F10 +- added key shortcuts for Enable Plots, Disable Plots and Disable other plots functions (Alt+1, Alt+2, Alt+3) +- hidden the snap magnet entry and snap magnet toggle from the main view; they are now active only in Editor Mode +- updated the camlib.CNCJob.scale() function so now the GCode is scaled also (quite a HACK :( it will need to be replaced at some point)). Units change work now on the GCODE also. +- added the bounds coordinates to the GCODE header +- FlatCAM saves now to a file in self.data_path the toolbar positions and the position of TCL Shell +- Plot Area Tab view can now be toggled, added entry in View Menu and shortcut key Ctrl+F10 +- All the tabs in the GUI right side are (Plot Are, Preferences etc) are now detachable to a separate windows which when closed it returns in the previous location in the toolbar. Those detached tabs can be also reattached by drag and drop. + +30.01.2019 + +- added a space before Y coordinate in end_code() function in some of the preprocessor files +- added in Calculators Tool an Electroplating Calculator. +- remade the App Menu for Editors: now they will be showed only when the respective Editor is active and hidden when the Editor is closed. +- added a traceback report in the TCL Shell for the errors that don't allow creation of an object; useful to trace exceptions/errors +- in case that the Toolchange X,Y parameter in Selected (or in Preferences) are deleted then the app will still do the job using the current coordinates for toolchange +- fixed an issue in camlib.CNCJob where tha variable self.toolchange_xy was used for 2 different purposes which created loss of information. +- fixed unit conversion functions in case the toolchange_xy parameter is None +- more fixes in camlib.CNCJob regarding usage of toolchange (in case it is None) +- fixed preprocessor files to work with toolchange_xy parameter value = None (no values in Edit - Preferences fields) +- fixed Tcl commands CncJob and DrillCncJob to work with toolchange +- added to the preprocessor files the command after toolchange to go with G00 (fastest) to "Z Move" value of Z pozition. + +29.01.2019 + +- fixed issue in Tool Calculators when a float value was entered starting only with the dot. +- added protection for entering incorrect values in Offset and Scale fields for Gerber and Geometry objects (in Selected Tab) +- added more shortcut keys in the Geometry Editor and in Excellon Editor; activated also the zoom (fit, in, out) shortcut keys ('1' , '2', '3') for the editors +- disabled the context menu in tools table on Paint Tool in case that the painting method is single. +- added protection when trying to do Intersection in Geometry Editor without having selected Geometry items. +- fixed the scale, mirror, rotate, skew functions to work with Geometry Objects of multi-geometry type. +- added a GUI for Excellon Search time for OR-TOOLS path optimization in Edit -> Preferences -> Excellon General -> Optimization Time +- more changes in Edit -> Preferences -> Geometry, Gerber and in CNCJob +- added new option for Cutout Tool Freeform Gaps in Edit -> Preferences -> Tools +- fixed Freeform Cutout gaps issue (it was double than the value set) +- added protection so the Cutout (either Freeform or Rectangular) cannot be done on a multigeo Geometry +- added 2Sided Tool default values in Edit -> Preferences -> Tools +- optimized the FlatCAMCNCJob.on_plot_cb_click_table() plot function and solved a bug regarding having tools numbers not in sync with the cnc tool table + +28.01.2018 + +- fixed the FlatCAMGerber.merge() function +- added a new menu entry for the Gerber Join function: Edit -> Conversions -> "Join Gerber(s) to Gerber" allowing joining Gerber objects into a final Gerber object +- moved Paint Tool defaults from Geometry section to the Tools section in Edit -> Preferences +- added key shortcuts for Open Manual = F1 and for Open Online VideoHelp = F2 + +27.01.2018 + +- added more key shortcuts into the application; they are now displayed in the GUI menu's +- reorganized the Edit -> Preferences -> Global +- redesigned the messagebox that is showed when quiting ot creating a New Project: now it has an option ('Cancel') to abort the process returning to the app +- added options for trace segmentation that can be useful for auto-levelling (code snippet from Lei Zheng from a rejected pull request on FlatCAM https://bitbucket.org/realthunder/ ) +- added shortcut key 'L' for creating 'New Excellon' +- added shortcut key combo 'Shift+S' for Running a Script. +- modified GRBL_laser preprocessor file so it includes a Sxxxx command on the line with M03 (laser active) whenever a value is enter in the Spindlespeed entry field +- remade the EDIT -> PREFERENCES window, the Excellon and Gerber sections. Created a new section named TOOLS + +26.01.2019 + +- fixed grbl_11 preprocessor in linear_code() function +- added icons to the Project Tab context menu +- added new entries to the Canvas context menu (Copy, Delete, Edit/Save, Move, New Excellon, New Geometry, New Project) +- fixed GRBL_laser preprocessor file +- updated function for copy of an Excellon object for the case when the object has slots +- updated FlatCAMExcellon.merge() function to work in case some (or all) of the merged objects have slots + +25.01.2019 + +- deleted junk folders +- remade the Panelize Tool: now it is much faster, it is multi-threaded, it works with multitool geometries and it works with multigeo geometries too. +- made sure to copy the options attribute to the final object in the case of: FlatCAMGeometry.merge(), FlatCAMGerber.merge() and for the Panelize Tool +- modified the panelize TclCommand to take advantage of the new panelize() function; added a 'threaded' parameter (default value is 1) which controls the execution of the panelize TclCommand: threaded or non-threaded +- fixed TclCommand Cutout +- added a new TclCommand named CutoutAny. Keyword: cutout_any + +24.01.2019 + +- trying to fix painting single when the actual painted object it's a MultiPolygon +- fixed the Copy Object function when the object is Gerber +- added the Copy entry to the Project context menu +- made the functions behind Disable and Enable project context menu entries, non-threaded to fix a possible issue +- added multiple object selection on Open ... and Import ... (idea and code snippet came from Travers Carter, BitBucket user https://bitbucket.org/travc/) +- fixed 'GRBL_laser' preprocessor bugs (missing functions) +- fixed display geometry for 'GRBL_laser' preprocessor +- Excellon Editor - added possibility to create an linear drill array rotated at an custom angle +- added the Edit and Properties entries to the Project context menu + +23.01.2019 + +- added a new preprocessor file named 'line_xyz' which have x, y, z values on the same GCode line +- fixed calculation of total path for Excellon Gcode file +- modified the way FlatCAM preferences are saved. Now they can be saved as new files with .FlatConfig extension by the user and shared. +- added possibility to open the folder where FlatCAM is saving the preferences files + +21.01.2019 + +- changed some tooltips +- added tooltips in Excellon tool table headers +- in Excellon Tool Table the columns are now only selectable by clicking on the header (sorting is done automatically) +- if CNCJob from Excellon then hide the CNC tools table in CNCJob Object + + +20.01.2019 + +- fixed the HPGL code geometry rendering when travel +- fixed the message box layout when asking to save the current work +- made sure that whenever the HPGL preprocessor is selected the Toolchange is always ON and the MultiDepth is OFF +- the HPGL preprocessor entry is not allowed in Excellon Object preprocessor selection combobox as it is only applicable for Geometry +- when saving HPGL code it will be saved as a file with extension .plt +- the units mentioned in HPGL format are only METRIC therefore if FlatCAM units are in INCH they will be transform to METRIC +- the minimum unit in HPGL is 0.025mm therefore the coordinates are rounded to a multiple of 0.025mm +- removed the raise statement in do_worker_task() function as this is fatal in conjunction with PyQt5 +- added a try - except clause for the situations when for a font can't be determined the family and name +- moved font parsing to the Geometry Editor: it is done everytime the Text tool is invoked +- made sure that the HPGL preprocessor is not populated in the Excellon preprocessors in Preferences as it make no sense (HPGL is useful only for Geometries) + +19.01.2019 + +- added initial implementation of HPGL preprocessor +- fixed display HPGL code geometry on canvas + +11.01.2019 + +- added a status message for font parsing + +9.01.2019 + +- added a fix to allow creating of Excellon geometry even when there are points with no tools by skipping those points and warning the user about this in a Tcl message +- added a message box asking users if they want to save the project in case that either New Project menu entry is clicked or if Exit menu entry is clicked or if the app is closed from the close button. The message box will be showed only if there are objects in the collection. +- modified the first line in the Gcode header to show the FlatCAM version and version_date + +8.01.2019 + +- added checkboxes in Preferences -> General -> Global Preferences to switch on/off version check at application startup and also to control if the app will send anonymous statistics about FlatCAM usage to help improve FlatCAM + +7.01.2019 + +- added tooltips in Edit->Convert menu +- fixed cutting from copper features when doing Gerber isolation with multiple passes + +6.01.2019 + +- fixed the Marlin preprocessor detection in GCode header +- the version date in GCode header is now the one set in FlatCAMApp.App.version_date +- fixed bug in preprocessor files: number of drills is now calculated only for the Excellon objects in toolchange function (only Excellon objects have drills) + +5.01.2019 + +- fixed cncjob TclCommand - it used the default values for parameters +- fixed the layout in ToolTransform +- fixed the initial text in the ToolShell +- reactivated the version check in case the release is not BETA; FlatCAMApp.App has now a beta object that when set True the application will show in the Title and help-> About that is Beta (and it disable version checking) +- added a new name (mine: for good and/or bad) to the contributors list +- fixed the Join function to work on Gerber and Excellon, Gerber and Gerber, Excellon and Excelon combination of objects. The merged property is the solid_geometry and the result is a FlatCAMGeometry object. + +3.01.2019 + +- initial merge into FlatCAM regular + +28.12.2018 + +- changed the workspace drawing from 'gl' to 'agg'. 'gl' has better performance but it messes with the overlapping graphics +- removed the initial obj.build_ui() in App.editor2object() + +25.12.2018 + +- fixed bugs in Excellon Editor due of PyQt5 port +- fixed bug when loading Gerber with follow +- fixed bug that when a Gerber was loaded with -follow parameter it could not be isolated external and full +- changed multiple status bar messages +- changed some assertions to (status error message + return) combo +- fixed issues in 32bit installers +- added protection against using Excellon joining on different kind of objects +- fixed bug in ToolCutout where the Rectangular Cutout used the Type of Gaps from Freeform Cutout +- fixed bug that didn't allowed saving SVG file from a Gerber file +- modified setup_ubuntu.sh file for PyQt5 packages + +23.12.2018 + +- added move (as in Tool Move) capability for CNCJob object and the GCode is updated on each move --> finished both for Gcode loaded and for CNCJob generated in the app +- fixed some errors related to DialogOpen widget that I've missed in PyQt5 porting +- added a bounds() method for CNCJob class in camlib (perhaps overdone as it worked well with the one inherited) +- small changes in Paint Tool - the rest machining is working only partially +- added more columns in CNCjob Tool Table showing more info about the present tools +- make the columns in CNCJob Tool Table not editable as it has no sense + +22.12.2018 + +- fixed issues in Transform Tool regarding the message boxes +- fixed more error in Double Sided Tool and added some more information's in ToolTips +- added more information's in CutOut Tool ToolTips +- updated the tooltips in amost all FlatCAM tools; in Tool Tables added column header ToolTips +- fixed NCC rest machining in NCC Tool; added status message and stop object creation if there is no geometry on any tool +- fixed version number: now it will made of a number in format main_version.secondary_version/working_version +- modified the makefile for windows builds to accommodate both 32bit and 64bit executable generation + +21.12.2018 + +- added shortcut "SHIFT + W" for workspace toggle +- updated the list of shortcuts +- forbid editing for the MultiGeo type of Geometry because the Geometry Editor is not prepared for this +- finished a "sort" of rest-machining for Non Copper Clearing Tool but it's time consuming operation +- reworked the NCC Tool as it was fundamental wrong - still has issues on the rest machining +- added a parameter reset for each run of Paint Tool and NCC Tool + +20.12.2018 + +- porting application to PyQt5 +- adjusted the level of many status bar messages +- created new bounds() methods for Excellon and Gerber objects as the one inherited from Geometry failed in conjunction with PyQt5 +- fixed some small bugs where a string was divided by a float finally casting the result to an integer +- removed the 'raise' conditions everywhere I could and make protections against loading files in the wrong place +- fixed a "PyCharm stupid paste on the previous tab level even after one free line " in Excellon.bounds() +- in Geometry object fixed error in tool_delete regarding deletion while iterating a dict +- started to rework the NCC Tool to generate one file only +- in Geometry Tool Table added checkboxes for individual plot of tools in case of MultiGeo Geometry +- rework of NCC Tool UI +- added a automatic selector: if the system is 32bit the OR-tools imports are not done and the OR-tools drill path optimizations are replaced by a default Travelling Salesman drill path optimization +- created a Win32 make file to generate a Win32 executable +- disabled the Plot column in Geometry Tool Table when the geometry is SingleGeo as it is not needed +- solved a issue when doing isolation, if the solid_geometry is not a list will make it a list +- added tooltips in the Geometry Tool Table headers explaining each column +- added a new Tcl Command: clear. It clears the Tcl Shell of all text and restore it to the original state +- fixed Properties Tool area calculation; added status bar messages if there is no object selected show an error and successful showing properties is confirmed in status bar +- when Preferences are saved, now the default values are instantly propagated within the application +- when a geometry is MultiGeo and all the tools are deleted, it will have no geometry at all therefore all that it's plotted on canvas that used to belong to it has to be deleted and because now it is an empty object we demote it to SingleGeo so it can be edited + +19.12.2018 + +- fixed SVG_export for MultiGeo Geometries +- fixed DXF_export for MultiGeo Geometries +- fixed SingleGeo to MultiGeo conversion plotting bug + +18.12.2018 + +- small changes in FlatCAMGeometry.plot() +- updated the FlatCAMGeometry.merge() function and the Join Geometry feature to accommodate the different types of geometries: singlegeo and multigeo type +- added Conversion submenu in Edit where I moved the Join features and added the Convert from MultiGeo to SingleGeo type and the reverse +- added Copy Tool (on a selection of tools) feature in Geometry Object UI +- fixed the bounds() method for the MultiGeo geometry object so the canvas selection is working and also the Properties Tool +- fixed Move Tool to support MultiGeo geometry objects moving +- added tool edit in Geometry Object Tool Table +- added Tool Table context menu in Geometry Object and in Paint Tool +- modified some Status Bar messages in Geometry Object + +17.12.2018 + +- added support for multiple solid_geometry in a geometry object; each tool can now have it's own geometry. Plot, project save/load are OK. +- added support for single GCode file generation from multi-tool PaintTool job +- added protection for results of Paint Tool job that do not have geometry at all. An Error will be issued. It can happen if the combination of Paint parameters is not good enough +- 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] +- fixed conflict with "space" keyboard shortcut for CNC job + +16.12.2018 + +- redone the Options menu; removed the Transfer Options as they were not used +- deleted some folders in the project structure that were never used +- Paint polygon Single works only for left mouse click allowing mouse panning +- added ability to print errors in status bar without raising Tcl Shell +- fixed small bug: when doing interiors isolation on a Gerber that don't allow it, no object is created now and an error in the status bar is issued +- fixed bug in Paint All for Geometry made from exteriors Gerber isolation +- fixed the join geometry: when the geometries has different tools the join will fail with a status bar message (as it should). Allow joining of geometries that have no tool. // Reverted on 18.12.2018 +- changed the error messages that are simple to the kind that do not open the TCl shell +- fixed some issues in Geometry Object +- Paint Tool - reworked the UI and made it compatible with the Geometry Object UI +- Paint Tool - tool edit functional +- added Clear action in the Context menu of the TCl Shell + +14.12.2018 + +- fixed typo in setup_ubuntu.sh +- minor changes in Excellon Object UI +- added Tool Table in Paint Tool +- now in Paint Tool and Non Copper Clearing Tool a selection of tools can be deleted (not only one by one) +- minor GUI changes (added/corrected tooltips) +- optimized vispy startup time from about >6 sec to ~3 seconds +- removed vispy text collection starting in plotcanvas as it did nothing // RESTORED 18.12.2018 as it messed the graphical presentation +- fixed cncjob TclCommand for the new type of Geometry +- make sure that when using the TclCommands, the object names are case insensitive +- updated the TCL Shell auto-complete function; now it will index also the names of objects created or loaded in the application +- on object removal the name is removed from the Shell auto-complete model + +13.12.2018 + +NEW Geometry Object and CNC Object architecture (3rd attempt) which allow multiple tools for one geometry + +- fixed issue with cumulative G-code after successive delete/create of a CNCJob on the same geometry (some references were kept after deletion of CNCJob object which kept the deleted tools data and added it to a new one) +- fixed plot and export G-code in new format +- fixed project save/load in the new format for geometry +- added new feature in CNCJob Object UI: since we may have multiple tools per CNCJob object due of having multiple tool in Geometry Object, +now there is a Tool Table in CNC Object UI and each tool GCode can be enabled or disabled + +12.12.2018 + +- Geometry Tool Table: when the Offset type is 'custom' each tool it's storing the value and it is updated on UI when that tool is selected in UI table +- Geometry Tool Table: fixed tool offset conversion when the Offset in Tool Table UI is set to Custom + +11.12.2018 + +- cleaned up the generatecncjob() function in FlatCAMObj +- created a new function for generating cncjob out of multitool geometry, mtool_generate_cncjob() +- cleaned up the generate_from_geometry_2() method in camlib +- Geometry Tool Table: new tool added copy all the form fields (data) from the last tool +- finished work on generation of a single CNC Job file (therefore a single GCODE file) even for multiple tools in Geo Tool Table +- GCode header is added only on saving the file therefore the time generation will be reflected in the file +- modified preprocessors to accommodate the new CNC Job file with multiple tools +- modified preprocessors so the last X,Y move will be to the toolchange X,Y pos (set in Preferences) +- save_project and load_project now work with the new type of multitool geometry and cncjob objects + +10.12.2018 + +- added new feature in Geometry Tool Table: if the Offset type in tool table is 'Offset' then a new entry is unhidden and the user can use custom offset +- Geometry Tool Table: fixed add new tool with diameter with many decimals +- Geometry Tool Table: when editing the tip dia or tip angle for the V Shape tool, the CutZ is automatically calculated + +9.12.2018 + +- new Geometry Tool Table has functional unit conversion +- when entering a float number in Spindle Speed now there is no error and only the integer part is used, the decimals are discarded +- finished the Geometry Tool Table in the form that generates only multiple files +- if tool type is V-Shape ('V') then the Cut Z entry is disabled and new 'Tip Dia' and 'Tip Angle' fields are showed. The values entered will calculate the Cut Z parameter + +5.12.2018 + +- remade the Geometry Tool Table, before this change each tool could not store it's own set of data in case of multiple tools with same diameter +- added a new column in Geo Tool Table where to specify which type of tool to use: C for circular, B for Ball and V for V-shape + +4.12.2018 + +- new geometry/excellon object name is now only "new_g"/"new_e" as the type is clear from the category is into (and the associated icon) +- always autoselect the first tool in the Geometry Tool table +- issue error message if the user is trying to generate CNCJob without a tool selected in Geometry Tool Table +- add the whole data from Geometry Object GUI as dict in the geometry tool dict so each tool (file) will have it's own set of data + +3.12.2018 + +- Geometry Tool table: delete multiple tools with same diameter = DONE +- Geometry Tool table: possibility to cut a path inside or outside or on path = DONE +- Geometry Tool table: fixed situation when user tries to add a tool but there is no tool diameter entered +- if a geometry is a closed shape then create a Polygon out of it +- some fixes in Non Copper Clearing Tool +- Geometry Tool table: added option to delete_tool function for delete_all +- Geometry Tool table: added ability to delete even the last tool in tool_table and added an warning if the user try to generate a CNC Job without a tool in tool table +- if a geometry is painted inside the Geometry Editor then it will store the tool diameter used for this painting. Only one tool cn be stored (the last one) so if multiple paintings are done with different tools in the same geometry it will store only the last used tool. +- if multiple geometries have different tool diameters associated (contain a paint geometry) they aren't allowed to be joined and a message is displayed letting the user know + +2.12.2018 + +- started to work on a geometry Tool Table +- renamed FlatCAMShell as ToolShell and moved it (and termwidget) to flatcamTools folder +- cleaned up the ToolShell by removing the termwidget separate file and added those classes to ToolShell +- added autocomplete for TCL Shell - the autocomplete key is 'TAB' +- covered some possible exceptions in rotate/skew/mirror functions +- Geometry Tool table: add/delete tools = DONE +- Geometry Tool table: add multiple tools with same diameter = DONE + +1.12.2018 + +- fixed Gerber parser so now the Gerber regions that have D02 operation code just before the end of the region will be processed correctly. Autotrax Dex Gerbers are now loaded +- fixed an issue with temporary geo storage "geo" being referenced before assignment +- moved all FlatCAM Tools into a single directory + +30.11.2018 + +- remade the CutOut Tool. I've put together the former Freeform Cutout tool and the Cutout Object fount in Gerber Object GUI and left only a link in the Gerber Object GUI. This tidy the GUI a bit. +- created a Paint Tool and replaced the Paint Area section in Geometry Object GUI with a link to this tool. +- fixed bug in former Paint Area and in the new Paint Tool that made the paint method not to be saved in App preferences +- solved a bug in Gerber parser: in case that an operation code D? was encountered alone it was not remembered - fixed +- fixed bug related to the newly entered toolchange feature for Geometry: it was trying to evaluate toolchange_z as a comma separated value like for toolchange x,y +- fixed bug in scaling units in CNC Job which made the unit change between INCH and MM not possible if a CNC Job was present in the project objects + +29.11.2018 + +- added checks for using a Z Cut with positive value. The Z Cut parameter has to be negative so if the app will detect a positive value it will automatically convert it to negative +- started to implement rest-machining for Non Copper clearing Tool - for now the results are not great +- added Toolchange X,Y position parameters and modified the default and manual_toolchange preprocessor file to use them +For now they are used only for Excellon objects who do have toolchange events +- added Toolchange event selection for Geometry objects; for now it is as before, single tool on each file +- remade the GUI for objects and in Preferences to have uniformity +- fixed bug: after editing a newly created excellon/geometry object the object UI used to not keep the original settings +- fixed some bugs in Tool Add feature of the new Non Copper Clear Tool +- added some messages in the Non Copper Clear Tool +- added parameters for coordinates no of decimals and for feedrate no of decimals used in the resulting GCODE. They are in EDIT -> Preferences -> CNC Job Options +- modified the preprocessors to use the "decimals" parameters + +28.11.2018 + +- added different methods of copper clearing (standard, seed, line_based) and "connect", "contour" options found in Paint function +- remake of the non-copper clearing tool as a separate tool +- modified the "About" menu entry to mention the main contributors to FlatCAM 3000 +- modified Marlin preprocessor according to modifications made by @redbull0174 user from FlatCAM.org forum +- modified Move Tool so it will detect if there is no object to move and issue a message + +27.11.2018 + +- fixed bug in isolation with multiple passes +- cosmetic changes in Buffer and Paint tool from Geometry Editor +- changed the way selection box is working in Geometry Editor; now cumulative selection is done with modifier key (SHIFT or CONTROL) - before it was done by default +- changed the default value for CNCJob tooldia to 1mm + +25.11.2018 + +- each Tool change the name of the Tools tab to it's name +- all open objects are no longer autoselected upon creation. Only on new Geometry/Excellon object creation it will be autoselected + +24.11.2018 + +- restored the selection method in Geometry Editor to the original one found in FlatCAM 8.5 +- minor changes in Clear Copper function +- minor changes in some preprocessors +- change Join Geometry menu entry to Join Geo/Gerber +- added menu entry for Toggle Axis in Menu -> View +- added menu entry for Toggle Workspace in Menu -> View +- added Bounding box area to the Properties (when metric units, in cm2) +- non-copper clearing function optimization +- fixed Z_toolchange value in the GCODE header + +21.11.2018 + +- not very precise jump to location function +- added shortcut key for jump to coordinates (J) and for Tool Transform (T) +- some work in shortcut key + +19.11.2018 + +- fixed issue with nested comment in preprocessors +- fixed issue in Paint All; reverted changes + +18.11.2018 + +- renamed FlatCAM 2018 to FlatCAM 3000 +- added new entries in the Help menu; one will show shortcut list and the other will start a YouTube webpage with a playlist where I will publish future training videos for this version of FlatCAM +- if a Gerber region has issues the file will be loaded bypassing the error but there will be a TCL message letting the user know that there are parser errors. + +17.11.2018 + +- added Excellon parser support for units defined outside header + + +12.11.2018 + +- fixed bug in Paint Single Polygon +- added spindle speed in laser preprocessor +- added Z start move parameter. It controls the height at which the tool travel on the fist move in the job. Leave it blank if you don't need it. + +9.11.2018 + +- fixed a reported bug generated by a typo for feedrate_z object in camlib.py. Because of that, the project could not be saved. +- fixed a G01 usage (should be G1) in Marlin preprocessor. +- changed the position of the Tool Dia entry in the Object UI and in FlatCAMGUI +- fixed issues in the installer + +30.10.2018 + +- fixed a bug in Freeform Cutout Tool - it was missing a change in the name of an object + +29.10.2018 + +- added Excellon export menu entry and functionality that can export in fixed format 2:4 LZ INCH (format that Altium can load and it is a more generic format). +It will be usefull for those who need FlatCAM to only convert the Excellon to a more useful format and visualize Gerbers. +The other Excellon Export menu entry is exporting in units either Metric or INCH depending on the current units in FlatCAM, but it will always use the decimal format which may not be loaded in all cases. +- disabled the Selected Tab while in Geometry Editor; the user is not supposed to have access to those functions while in Geometry Editor +- added an menu entry in Menu -> File -> Recent Files named Clear Recent files which does exactly that +- fixed issue: when a New Project is created but there is a Geometry still in Geometry Editor (or Excellon Editor) not saved, now that geometry is deleted +- fixed problem when doing Clear Copper with Cut over 1st point option active. When the shape is not closed then it may cut over copper features. Originally the feature was meant to be used only with isolation geometry which is closed. Fixed + +28.10.2018 + +- fixed Excellon Editor shortcut messages; also fixed differences in messages between usage by shortcuts and usage by menu toolbar actions +- fixed Excellon Editor bug: it was triggering exceptions when the user selected a tool in tooltable and then tried to add a drill (or array) by clicking on canvas +Clicking on canvas by default clear all the used tools, therefore the action could not be done. Fixed. +- fixed bug Excellon Editor: when all the drills from a tool are resized, after resize they can't be selected. +- Excellon Editor: added ability to delete multiple tools at once by doing multiple selection on the tooltable +- Excellon Editor: if there are no more drills to a tool after doing drills resize then delete that tool from the tooltable +- Excellon Editor: always select the last tool added to the tooltable +- Excellon Editor: added a small canvas context menu for Excellon Editor + +27.10.2018 + +- added a Paint tool toolbar icon and added shortcut key 'I' for Paint Tool +- fixed unreliable multiple selection in Geometry Editor; some clicks were not registered +- added utility geometry for Add Drill Array in Excellon Editor +- fixed bug Excellon Editor: drills in drill array start now from the array start point (x, y); previously array start point was used only for calculating the radius +- fixed bug Excellon Editor: Measurement Tool was not acting correctly in Exc Editor regarding connect/disconnect of events +- in Excellon Editor every time a tool is clicked (except Select which is the default) the focus will return to Selected tab +- added protection in Excellon Editor: if there is no tool/drill selected no operation over drills can be performed and a status bar message will be displayed +- Excellon Editor: added relevant messages for all actions +- fixed bug Excellon Editor: multiple selection with key modifier pressed (CTRL/SHIFT) either by simple click or through selection box is now working +- fixed dwell parameter for Excellon in Preferences to be default Off + +26.10.2018 + +- when objects are disabled they can't be selected +- added Feedrate_z (Plunge) parameter for Geometry Object +- fixed bug in units convert for Geometry Tab; added some missing parameters to the conversion list +- fixed bug in isolation Geometry when the isolated Gerber was a single Polygon +- updated the Paint function in Geometry Editor + +25.10.2018 + +- added a verification on project saving to make sure that the project was saved successfully. If not, a message will be displayed in the status bar saying so. + +20.10.2018 + +- fixed the SVG import as Gerber. But unfortunately, when there is a ground pour in a imported PCB SVG, the ground pour will be isolated inside +instead to be isolated outside like every other feature. That's no way around this. The end result will be thinner features +for the ground pour and if one is relying on those thin connections as GND links then it will not work as intended ,they may be broken. +Of course one can edit the isolation geometry and delete the isolation for the ground pour. +- delete selection shapes on double clicking on object as we may not want to have selection shape while Selected tab is active + +19.10.2018 + +- solved some value update bugs in tool_table in Excellon Editor when editing tools followed by deleting another tool, +and then re-adding the just-deleted tool. +- added support for chaining blocks in DXF Import +- fixed the DXF arc import +- added support for a type of Gerber files generated by OrCAD where the Number format is combined with G74 on the same line +- in Geometry Editor added the possibility for buffer to use different kinds of corners +- added protection against loading an GCODE file as Excellon through drag & drop on canvas or file open dialog +- added shortcut key 'B' for buffer operation inside Geometry Editor +- added shell message in case the Font used in Text Tool in Geometry editor is not supported. Only Regular, Bold, Italic adn BoldItalic are supported as of yet. +- added shortcut key 'T' for Text Tool inside Geometry Editor +- added possibility for Drag & Drop on FlatCAM GUI with multiple files at once + +18.10.2018 + +- fixed DXF arc import in case of extrusion enabled +- added on Geo Editor Toolbar the button for Buffer Geometry; added the possibility to create exterior and interior buffer +- fixed a numpy import error + +17.10.2018 + +- added Spline support and Ellipse (chord) support in DXF Import: chord might have issues +(borrowed from the work of Vasilis Vlachoudis, https://github.com/vlachoudis/bCNC) +- added Block support in DXF Import - no support yet for chained blocks (INSERT in block) +- support for repasted block insertions + +16.10.2018 + +- added persistent toolbar view: the enabled toolbars will be active at the next app startup while those that are not enabled will not be +enabled at the next app startup. To enable/disable toolbars right click on the toolbar. + +15.10.2018 + +- DXF Export works now also for Exteriors only and Interiors only geometry generated from Gerber Object +- when a Geometry is edited, now the interiors and exterior of a Polygon that is part of the Geometry can be selected individually. In practice, if +doing full isolation geometry, now both external and internal trace can be selected individually. + +13.10.2018 + +- solved issue in CNC Code Editor: it appended text to the previous one even if the CNC Code Editor was closed +- added .GBD Gerber extension to the lists +- added support for closed polylines/lwpolylines in Import DXF; now PCB patterns found in PDF format can be imported in INKSCAPE +and saved as DXF. FlatCAM can import DXF as Gerber and the user now can do isolation on it. + +12.10.2018 + +- added zoom in, zoom out and zoom fit buttons on the View toolbar +- fixed bug that on Double Sided Tool when a Excellon Alignment is created does not reset the list of Alignment drills +- added a message warning the user to add Point coordinates in case the reference used in Double Sided Tool is Point +- added new feature: DXF Export for Geometry + +10.10.2018 + +- fixed a small bug in Setup Recent Files +- small fix in Freeform Cutout Tool regarding objects populating the combo boxes +- Excellon object name will reflect the number of edits performed on it + +9.10.2018 + +- In Geometry Editor, now Path and Polygon draw mode can be finished not only with shortcut key Enter but also with right click on canvas +- fixes regarding of circle linear approximation - final touch +- fix for interference between Geo Editor and Excellon Editor +- fixed Cut action in Geometry Editor so it can now be done multiple times on the target geometry without need for saving in between. +- initial work on DXF import; made the GUI interface and functional structure +- added import functions for DXF import +- finished DXF Import (no blocks support, no SPLINE support for now) + +8.10.2018 + +- completed toggle canvas selection when there is only one object under click position for the case when clicking the object is done +while other object is already selected. +- added static utility geometry just upon activating an Editor function +- changed the way the canvas is showed on FlatCAM startup + +7.10.2018 + +- solved mouse click not setting relative measurement origin to zero +- solved bug that always added one drill when copying a selection of drills in the EXCELLON EDITOR +- solved bug that the number of copied drills in Excellon Editor was not updated in the tool table +- work in the Excellon Editor: found useful to change the diameter of one tool to another already in the list; +could help for all those tools that are a fraction difference that comes from imperial to mm (or reverse) conversion, +to reduce the tool changes - Done +- in Excellon Editor, always auto-select the last tool added +- in Excellon Editor fixed shortcuts for drill add and drill_array add: they were reversed. Now key 'A' is for array add +and key 'D' is for drill add +- solved a small bug in Excellon export: even when there were no slots in the file, it always added the tools list that +acted as unnecessary toolchanges +- after Move action, all objects are deselected + + +6.10.2018 + +- Added basic support for SVG text in SVG import. Will not work if some letters in a word have different style (italic bold or both) +- added toggle selection to the canvas selection if there is only one object under the click position +- added support for "repeat" command in Excellon file +- added support for Allegro Gerber and Excellon files +- Python 3.7 is used again; solved bug where the activity icon was not playing when FlatCAM active + +5.10.2018 + +- fixed undesired setting focus to Project Tab when doing the SHIFT + LMB combo (to capture the click coordinates) + +4.10.2018 + +- Excellon Editor: finished Add Drill Array - Linear type action +- Excellon Editor: finished Add Drill Array - Circular type action +- detected bug in shortcuts: Fixed +- Excellon Editor: added constrain for adding circular array, if the number of drills multiplied by angle is more than 360 +the app will return with an message +- solved sorting bug in the Excellon Editor tool table +- solved bug in Menu -> Edit -> Sort Origin ; the selection box was not updated after offset +- added Excellon Export in Menu -> File -> Export -> Export Excellon +- added support to save the slots in the Excellon file in case there were some in the original file +- fixed Double Sided Tool for the case of using the box as mirroring reference. + +2.10.2018 + +- made slots persistent after edit +- bug detected: in Excellon Editor if new tool added diameter is bigger than 10 it mess things up: SOLVED +- Excellon Editor: finished Drill Resize action +- after an object is deleted from the Project list, if the current tab in notebook is not Project, +always focus in the Project Tab (deletion can be done by shortcut key also) +- changed the initial view to include the possible enabled workspace guides + +1.10.2018 + +- added GUI for Excellon Editor in the Tool Tab +- Excellon Editor: created and populated the tool list +- Excellon Editor: added possibility to add new tools in the list +- Excellon Editor: added possibility to delete a tool (and the drills that it contain) by selecting a row in the tool table and +clicking the Delete Tool button +- Excellon Editor: added possibility to change the tool diameter in the tool list for existing tool diameters. +- Excellon Editor: when selecting a drill, it will highlight the tool in the Tool table +- Excellon Editor: optimized single click selection +- Excellon Editor: added selection for all drills with same diameter upon tool selection in tool table; fix in tool_edit +- Excellon Editor: added constrain to selection by single click, it will select if within a certain area around the drill +- Excellon Editor: finished Add Drill action +- Excellon Editor: finished Move Drill action +- Excellon Editor: finished Copy Drill action + +- fixed issue: when an object is selected before entering the Editor mode, now the selecting shape is deleted before entry +in the Editor (be it Geometry or Excellon). +- fixed a few glitches regarding the units change +- when an object is deselected on the Plot Area, the notebook will switch to Project Tab +- changed the selection behavior for the dragging rectangle selection box in Editor (Geometry, Excellon): by dragging a +selection box and selecting is cumulative: it just adds. To remove from selection press key Ctrl (or Shift depending of +the setting in the Preferences) and drag the rectangle across the objects you want to deselect. + +29.09.2018 + +- optimized the combobox item population in Panelization Tool and in Film Tool +- FlatCAM now remember the last path for saving files not only for opening +- small fix in GUI +- work on Excellon Editor. Excellon editor working functions are: loading an Excellon object into Editor, +saving an Excellon object from editor to FlatCAM, selecting drills by left click, selection of drills by dragging rectangle, deletion of drills. +- fixed Excellon merge +- added more Gcode details (depthperpass parameter in Gcode header) in preprocessors +- deleted the Tool informations from header in preprocessors due to Mach3 not liking the lot of square brackets +- more corrections in preprocessors + + +28.09.2018 + +- added a save_defaults() call on App exit from action on Menu -> File -> Exit +- solved a small bug in Measurement Tool +- disabled right mouse click functions when Measurement Tools is active so the user can do panning and find the destination point easily +- added a new button named "Measure" in Measurement Tool that allow easy access to Measurement Tool from within the tool +- fixed a bug in Gerber parser that when there was a rectangular aperture used within a region, some artifacts were generated. +- some more work on Excellon Editor + +27.09.2018 + +- fixed bug when creating a new project, if a previous object was selected on screen, the selection shape +survived the creation of a new project +- added compatibility with old type of FlatCAM projects +- reverted modifications to the way that Excellon geometry was stored to the old way. +- added exceptions for Paint functions so the user can know if something failed. +- modified confirmation messages to use the color coded messages (error = red, success = green, warning = yellow) +- restored activity icon + +26.09.2018 + +- disabled selection of objects in Project Tab when in Editor +- the Editor Toolbar is hidden in normal mode and it is showed when Editor +is activated. I may change this behaviour back. +- changed names in classes, functions to prepare for the Excellon editor + +- fixed bugs in Paint All function +- fixed a bug in ParseSVG module in parse_svg_transform(), related to 'scale' + +- moved all the Editor menu/toolbar creation to FlatCAMUI where they belong +- fixed a Gerber parse number issue when Gerber zeros are TZ (keep trailing zeros) + +- changed the way of how the solid_geometry for Excellon files is stored +and plotted. Before everything was put in the same "container". Now, +the geometries of drills and slots are organized into dictionaries having +as keys the tool diameters and as values list of Shapely objects (polygons) +- fix for Excellon plotting for newly created empty Excellon Object +- fixed geometry.bounds() in camlib to work with the new format of the Excellon geometry (list of dicts) + +24.09.2018 + +- added packages in the Requirements and setup_ubuntu.sh. Tested in Ubuntu and +it's OK +- added Replace (All) feature in the CNC Code Editor +- made CNC Code generation for Excellon to show progress +- added information about transforms in the object properties (like skew +and how much, if it was mirrored and so on) +- made all the transforms threaded and make them show progress in the progress bar +- made FlatCAM project saving, threaded. + +23.09.2018 + +- added support for "header-less" Excellon files. It seems that Mentor PADS does generate such +non-standard Excellon files. The user will have to guess: units (IN/MM), type of zero suppression LZ/TZ +(leading zeros or trailing zeros are kept) and Excellon number format(digits and decimals). +All of those can be adjusted in Menu -> Edit -> Preferences -> Excellon Object -> Excellon format +- fixed svgparse for Path. Now PCB rasted images can traced in Inkscape or PDF's can be converted +and then saved as SVG files which can be imported into FlatCAM. This is a convolute way to convert a PDF +to Gerber file. + +22.09.2018 + +- added Drag & Drop capability. Now the user can drag and drop to FlatCAM GUI interface a file +(with the right extension) that can be a FlatCAM project file (.FlatPrj) a Gerber file, +an Excellon file, a G-Code file or a SVG file. +- made the Move Tool command threaded +- added Image import into FlatCAM + +21.09.2018 + +- added new information's in the object properties: all used Tool-Table items +are included in a new entry in self.options dictionary +- modified the preprocessor files so they now include information's about +how many drills (or slots) are for each tool. The Gcode will have this +information displayed on the message from ToolChange. +- removed some log.debug and add new log.debug especially for moments when some process is finished +- fixed the utility geometry for Font geometry in Geometry Editor +- work on selection in Geometry Editor +- added multiple selection key as a Preference in Menu -> Edit -> Preferences +It can be either Shift or Ctrl. +- fixed bug in Gerber Object -> Copper Clearing. +- added more comprehensive tooltips in Non-copper Clearing as advice on how to proceed. +- adjusted make_win32.py file so it will work with Python 3.7 (cx_freeze can't copy OpenGL files, so +it has to be done manually) + +19.09.2018 + +- optimized loading FlatCAM project by double clicking on project file; there is no need to clean up everything by using +the function not Thread Safe: on_file_new() because there is nothing to clean since FlatCAM just started. + +- added a workspace delimitation with sizes A3, A4 and landscape or portrait format +- The Workspace checkbox in Preferences GUI is doing toggle on the workspace +- made the workspace app default state = False +- made the workspace to resize when units are changed +- disabled automatic defaults save (might create SSD wear) +- added an automatic defaults save on FlatCAM application close +- made the draw method for the Workspace lines 'agg' so the quality of the FC objects will not be affected + +- added Area constrain to the Panelization Tool: if the resulting area is too big to fit within constrains, the number +of columns and/or rows will be reduced to the maximum that still fits is. +- removed the Flip command from Panelization Tools because Flipping (Mirroring) should be done properly with the +Transform Tool or using the provided shortcut keys. + +- made Font parsing threaded so the application will not wait for the font parsing to complete therefore the app start +is faster + + +17.09.2018 + +- fixed Measuring Tool not working when grid is turned OFF +- fixed Roland MDX20 preprocessor +- added a .GBR extension in the open_gerber filter +- added ability to Scale and Offset (for all types of objects) to just +press Enter after entering a value in the Entry just like in Tool Transform +- added capability in Tool Transform to mirror(flip) around a certain Point. +The point coordinates can either be entered by hand or they can be captured +by left clicking while pressing key "SHIFT" and then clicking the Add button +- added the .ROL extension when saving Machine Code +- replaced strings that reference to G-Code from G-Code to CNC Code +- added capability to open a project by serving the path/project_name.FlatPrj as a parameter +to FlatCAM.py + +15.09.2018 + +- removed dwell line generator and included dwell generation in the preprocessor files +- added a proposed RML1 Roland_MDX20 preprocessor file. +- added a limit of 15mm/sec (900mm/min) to the feedrate and to the feedrate_rapid. Anything faster than this +will be capped to 900mm/min regardless what is entered in the program GUI. This is because Roland MDX-20 has +a mechanical limit of the speed to 15mm/sec (900mm/min in GUI) + +14.09.2018 +- remade the Double Sided Tool so it now include mirroring of Excellon and Geometry Objects along Gerber. +Made adding points easier by adding buttons to GUI that allow adding the coordinates captured by +left mouse click + SHIFT key +- added a few fixes in code to the other FlatCAM tools regarding reset_fields() function. The issue +was present when clicking New Project entry in Menu -> File. +- FIXED: fix adding/updating bounding box coords for the mirrored objects in Double side Tool. +- FIXED: fix the bounding box values from within FlatCAM objects, upon units change. +- fixed issue with running again the constructor of the drawing tools after the tool action was complete, +in Geometry Editor +- fixed issue with Tool tab not closed after Text Input tool is finished. +- fixed issue with TEXT to GEOMETRY tool, the resulting geometry was not scaled depending of current units +- fixed case when user is clicking on the canvas to place a Font Geometry without clicking apply button first +or the Font Geometry is empty, in Geometry Editor - > Text Input tool +- reworked Measuring Tool by adding more information's (START, STOP point coordinates) and remade the +strings +- added to Double Sided Tool the ability to use as reference box Excellon and Geometry Objects + +12.09.2018 + +- fixed Excellon Object class such that Excellon files that have both drills and slots are supported +- remade the GUI interface for the Excellon Object in a more compact way; added a column with slots numbers +(if any) along the drills numbers so now there is only one tool table for drills and slots. +- remade the GUI in Preferences and removed unwanted stretch that was broken the layout. +- if for a certain tool, the slots number is zero it will not be displayed +- reworked Text to Geometry feature to work in Linux and MacOS +- remade the Text to Geometry so font collection process is done once at app start-up improving the performance + + +09.09.2018 + +- added TEXT ENTRY SUPPORT in Geometry Editor. It will convert strings of True Type Fonts to geometry. +The actual dimensions are approximations because font size is in points and not in metric or inch units. +For now full support is limited to Windows. In Linux/MacOS only the fonts for which the font name is the same +as the font filename are supported. Italic and Bold functions may not work in Linux/MacOS. +- solved bug: some Drawing menu entries not having connected functions + +28.08.2018 + +- fixed Gerber parser so now G01 "moving" rectangular +aperture is supported. +- fixed import_svg function; it can import SVG as geometry (solved bug) +- fixed import_svg function; it can import SVG as Gerber (it did not work previously) +- added menu entry's for SVG import as Gerber and separated import as Geometry + +27.08.2018 + +- fixed Gerber parser so now FlatCAM can load Gerber files generated by Mentor Graphics EDA programs. + +26.08.2018 + +- added awareness for missing coordinates in Gerber parsing. It will try to use the previous coordinates but if there +are not any those lines will be ignored and an Warning will be printed in Tcl Shell. +- fixed TCL commands AlignDrillGrid and DrilCncJob +- added TCL script file load_and_run support in GUI +- made the tool_table in Excellon to automatically adjust the table height depending on the number of rows such that +all the rows will be displayed. +- structural changes in the Excellon build_ui() +- icon changes and menu compress + +23.08.2018 + +- added Excellon routing support +- solved a small bug that crippled Excellon slot G85 support when the coordinates +are with period. +- changed the way selection is done in Geometry Editor; now it should work +in all cases (although the method used may be computationally intensive, +because sometimes you have to click twice to make selection if you do it too fast) + +21.08.2018 + +- added Excellon slots support when using G85 command for generation of +the slots file. Inspired from the work of @mgix. Thanks. +Routing format support for slots will follow. +- minor bug solved: option "Cut over 1st pt" now has same name both in +Preferences -> Geometry Options and in Selected tab -> Geomety Object. +Solves #3 +- added option to select Climb or Conventional Milling in Gerber Object options +Solves #4 +- made "Combine passes" option to be saved as an app preference +- added Generate Exteriors Geo and Generate Interiors Geo buttons in the +Gerber Object properties +- added configuration for the number of steps used for Gerber circular aperture +linear approximation. The option is in Preferences -> Gerber Options +- added configuration for the number of steps used for Gcode circular aperture +linear approximation. The option is in Preferences -> CNCjob Options +- added configuration for the number of steps used for Geometry circular aperture +linear approximation. The option is in Preferences -> Geometry Options. It is used +on circles/arcs made in Geometry Editor and for other types of geometries generated in +the app. + + +17.07.2018 + +- added the required packages in Requirements.txt file +- added required packages in setup_ubuntu.sh file +- added color control over almost all the colors in the application; those +settings are in Menu -> Edit -> Preferences -> General Tab +- added configuration of which mouse button to be used when panning (MMB or RMB) +- fixed bug with missing 'drillz' parameter in function generate_from_excellon_by_tool() +(credits for finding it goes to Stefan Smith https://bitbucket.org/stefan064/) +- load Factory defaults in Preferences will load the defaults that are used just after +first install. Load Defaults option in Preferences will load the User saved Defaults. + +03.07.2018 + +- fixed bug in rotate function that didn't update the bounding box of the +modified object (rotated) due of not emitting the right signal parameter. +- removed the Options tab from the Notebook (the left area where is located +also the Project tab). Replaced it with the Preferences Tab launched with +Menu -> Edit -> Preferences +- when FlatCAM is used under MacOS, multiple selection of shapes in Editor +mode is done using SHIFT key instead of CTRL key due of MacOS interpreting +Ctrl+LMB_click as a RMB click +- when in Editor, clicking not on a shape, reset the index of selected shapes +to zero +- added a new Tab in the Plot Area named Gcode Editor. It allow the user to +edit the Gcode and then Save it or Print it. +- added a fix so the 'preamble' Gcode is correctly inserted between the +comments header and the actual GCODE +- added Find function in G-Code Editor + + +27.06.2018 + +- the Plot Area tab is changing name to "Editor Area" when the Editor is +activated and returns to the "Plot Area" name upon exiting the Editor +- made the labels shorter in Transform Tool in anticipation of +Options Tab removal from Notebook and replacing it with Preferences +- the Excellon Editor is not finished (not even started yet) so the +Plot Area title should stay "Plot Area" not change to "Editor Area" when +attempting to edit an Excellon file. Solved. +- added a header comment block in the generated Gcode with useful +information's +- fixed issue that did not allow the Nightly's to be run in +Windows 7 x64. The reason was an outdated DLL file (freetype.dll) used +by Vispy python module. + + +25.06.2018 + +- "New" menu entry in Menu -> File is renamed to "New Project" +- on "New Project" action, all the Tools are reinitialized so the Tools +tab will work as expected +- fixed issue in Film Tool when generating black film +- fixed Measurement Tool acquiring and releasing the mouse/key events +- fixed cursor shape is updated on grid_toggle +- added some infobar messages to show the user when the Editor was +activated and when it was closed (control returned to App). +- added thread usage for Film tool; now the App is no longer blocked on +film generation and there is a visual clue that the App is working + +22.06.2018 + +- added export PNG image functionality and menu entry in +Menu -> File -> Export PNG ... +- added a command to set focus on canvas inside the mouve move event +handler; once the mouse is moved the focus is moved to canvas so the +shortcuts work immediatly. +- solved a small bug when using the 'C' key to copy name of the selected +object to clipboard + +- fixed millholes() function and isolate() so now it works even when the +tool diameter is the same as the hole diameter. + +Actually if the passed value to the buffer() function is zero, I +artificially add a value of 0.0000001 (FlatCAM has a precision of +6 decimals so I use a tenth of that value as a pseudo "zero") +because the value has to be positive. This may have solved for some use +cases the user complaints that on clearing the areas of copper there is +still copper leftovers. + +- added shortcut "Shift+G" to toggle the axis presence. Useful when one +wants to save a PNG file. +- changed color of the grid from 'gray' to 'dimgray' + +- the selection shape is deleted when the object is deleted + +- the plot area is now in a TAB. +- solved bug that allowed middle button click to create selection +- fixed issue with main window geometry restore (hopefully). +- made view toolbar to be hidden by default as it is not really needed +(we have the functions in menu, zoom is done with mouse wheel, and there +is also the canvas context menu that holds the functionality) +- remade the GUIElements.FCInput() and made a GUIElements.FCTab() +- on visibility plot toogle the selection shape is deleted + +- made sure that on panning in Geometry editor, the context menu is not +displayed +- disabled App shortcut keys on entry in Geometry Editor so only the +local shortcut keys are working + +- deleted metric units in canvas context menu +- added protection so object deletion can't be done until Geometry +Editor session is finished. Solved bug when the shapes on Geometry +Editor were not transfered to the New_geometry object yet and the +New_Geometry object is deleted. In this case the drawn shapes are left +in a intermediary state on canvas. + +- added selection shape drawing in Geometry Editor preserving the +current behavior: click to select, click on canvas clear selection, +Ctrl+click add to selection new shape but remove from selection +if already selected. Drag LMB from left to right select enclosed +shapes, drag LMB from right to left select touching shapes. Now the +selection is made based on +- added info message to be displayed in infobar, when a object is +renamed + +20.06.2018 + +- there are two types of mouse drag selection (rectangle selection) +If there is a rectangle selection from left to right, the color of the +selection rectangle is blue and the selection is "enclosing" - this +means that the object to be selected has to be enclosed by the selecting +blue rectangle shape. +If there is a rectangle selection fro right to left, the color of the +selection rectangle is green and the selection is "touching" - this +means that it's enough to touch with the selecting green rectangle the +object(s) to be selected so they become selected +- changed the modifier key required to be pressed when LMB is ckicked +over canvas in order to copy to clipboard the coordinates of the click, +from CTRL to SHIFT. CTRL will be used for multiple selection. +- change the entry names in the canvas context menu +- disconnected the app mouse event functions while in geometry editor +since the geometry editor has it's own mouse event functions and there +was interference between object and geometry items. Exception for the +mouse release event so the canvas context menu still work. +- solved a bug that did not update the obj.options after a geometry +object was edited in geometry editor +- solved a bug in the signal that saved the position and dimensions of +the application window. +- solved a bug in app.on_preferences() that created an error when run +in Linux + +18.06.2018 Update 1 + +- reverted the 'units' parameter change to 'global_units' due of a bug +that did not allow saving of the project +- modified the camlib transform (rotate, mirror, scale etc) functions +so now they work with Gerber file loaded with 'follow' parameter + +18.06.2018 + +- reworked the Properties context menu option to a Tool that displays +more informations on the selected object(s) +- remade the FlatCAM project extension as .FlatPrj +- rearranged the toolbar menu entries to a more properly order +- objects can now be selected on canvas, a blue polygon is drawn around +when selected +- reworked the Tool Move so it will work with the new canvas selection +- reworked the Measurement Tool so it will work with the new canvas +selection +- canvas selection can now be done by dragging left mouse boutton and +creating a selection box over the objects +- when the objects are overlapped on canvas, the mouse click +selection works in a circular way, selecting the first, then the second, +then ..., then the last and then again the first and so on. +- double click on a object on canvas will open the Selected Tab +- each object store the bounding box coordinates in the options dict +- the bbox coordinates are updated on the obj options when the object +is modified by a transform function (rotate, scale etc) + + +15.06.2018 + +- the selection marker when moving is now a semitransparent Polygon +with a blue border +- rectified a small typo in the ToolTip for Excellon Format for +Diptrace excellon format; from 4:2 to 5:2 +- corrected an error that cause no Gcode could be saved + + +14.06.2018 + +- more work on the contextual menu +- added Draw context menu +- added a new tool that bring together all the transformations, named +Transformation Tool (Rotate, Skew, Scale, Offset, Flip) +- added shorcut key 'Q' which toggle the units between IN and MM +- remade the Move tool, there is now a selection box to show where the +move is done +- remade the Measurement tool, there is now a line between the start +point of measurement and the end point of the measurement. +- renamed most of the system variables that have a global app effect to +global_name where name is the parameter (variable) + + +9.06.2018 + +- reverted to PyQt4. PyQt5 require too much software rewrite +- added calculators: units_calculator and V-shape Tool calculator +- solved bug in Join Excellon +- added right click menu over canvas + +6.06.2018 Update + +- fixed bug: G-Code could not be saved +- fixed bug: double clicking a category in Project Tab made the app to +crash +- remade the bounds() function to work with nested lists of objects as +per advice from JP which made the operation less performance taxing. +- added shortcut Shift+R that is complement to 'R' +- shorcuts 'R' and 'Shift+R' are working now in steps of 90 degrees +instead of previous 45 degrees. +- added filters in the open ... FlatCAM projects are saved automatically +as *.flat, the Gerber files have few categories. So the Excellons and +G-Code and SVG. + +6.06.2018 + +- remade the transform functions (rotate, flip, skew) so they are now +working for joined objects, too +- modified the Skew and Rotate comamands: if they are applied over a +selection of objects than the origin point will be the center of the +biggest bounding box. That allow for perfect sync between the selected +objects +- started to modify the program so the exceptions are handled correctly +- solved bug where a crash occur when ObjCollection.setData didn't +return a bool value +- work in progress for handling situations when a different file is +loaded as another (like loading a Gerber file using Open Excellon + commands. +- added filters on open_gerber and open_excellon Dialogs. There is still +the ability to select All Files but this should reduce the cases when +the user is trying to oprn a file from a wrong place. + +4.06.2018 + +- finished PyQt4 to PyQt4 port on the Vispy variant (there were some changes +compared with the Matplotlib version for which the port was finished +some time ago) +- added Ctrl+S shortcut for the Geometry Editor. When is activated it will +save de geometry ("update") and return to the main App. +- modified the Mirror command for the case when multiple objects are +selected and we want to mirror all together. In this case they should mirror +around a bounding box to fill all. + +3.06.2018 + +- removed the current drill path optimizations as they are inefficient +- implemented Google OR-tools drill path optimization in 2 flavors; +Basic OR-tools TSP algorithm and OR-Tools Metaheuristics Guided Local Path +- Move tool is moved to Menu -> Edit under the name Move Object + +- solved some internal bugs (info command was creating an non-fatal +error in PyQt, regarding using QPixMaps outside GUI thread +- reworked camlib number parsing (still had some bugs) +- working in porting the application from usage of PyQt4 to PyQt4 +- added TclCommands save_sys and list_sys. save_sys is saving all the +system default parameters and list_sys is listing them by the first +letters. listsys with no arguments will list all the system parameters. + +29.05.2018 + +- modified the labels for the X,Y and Dx,Dy coordinates +- modified the menu entries, added more icons +- added initial work on a Excellon Editor +- modified the behavior of when clicking on canvas the coordinates were +copied to cliboard: now it is required to press CTRL key for this to +happen, and it will only happen just for left mouse button click +- removed the autocopy of the object name on new object creation +- remade the Tcl commands drillcncjob and cncjob +- added fix so the canvas is focused on the start of the program, +therefore the shortcuts work without the need for doing first a click +on canvas. + + + +28.05.2018 + +- added total drill count column in Excellon Tool Table which displays the +total number of drills +- added aliases in panelize Tool (pan and panel should work) +- modified generate_milling method which had issues from the Python3 port +(it could not sort the tools due of dict to dict comparison no longer +possible). +- modified the 'default' preprocessor in order to include a space +between the value of Xcoord and the following Y +- made optional the using of threads for the milling command; by default +it is OFF (False) because in the current configuration it creates issues +when it is using threads +- modified the Panelize function and Tcl command Panelize. It was having +issues due to multithreading (kept trying to modify a dictionary in +redraw() method)and automatically selecting the last created object +(feature introduced by me). I've added a parameter to +the new_object method, named autoselected (by default it is True) and +in the panelize method I initialized it with False. +By initializing the plot parameter with False for the temporary objects, +I have increased dramatically the generation speed of the panel because +now the temporary object are no longer ploted which consumed time. +- replaced log.warn() with log.warning() in camlib.py. Reason: deprecated +- fixed the issue that the "Defaults" button was having no effect when +clicked and Options Combo was in Project Options +- fixed issue with Tcl Shell loosing focus after each command, therefore +needing to click in the edit line before we type a new command (borrowed +from @brainstorm +- added a header in the preprocessor files mentioning that the GCODE +files were generated by FlatCAM. +- modified the number of decimals in some of the line entries to 4. +- added an alias for the millholes Tcl Command: 'mill' + +27.04.2018 + +- modified the Gerber.scale() function from camlib.py in order to +allow loading Gerber files with 'follow' parameter in other units +than the current ones +- snap_max_entry is disabled when the DRAW toolbar is disabled (previous +fix didn't work) +- added drill count column in Excellon Tool Table which displays the +total number of drills for each tool + +- added a new menu entry in Menu -> EDIT named "Join Excellon". It will +merge a selection of Excellon files into a new Excellon file +- added menu stubs for other Excellon based actions + +- solved bug that was not possible to generate film from joined geometry +- improved toggle active/inactive of the object through SPACE key. Now +the command works not only for one object but also for a selection + +26.05.2018 + +- made conversion to Python3 +- added Rtree Indexing drill path optimization +- added a checkbox in Options Tab -> App Defaults -> Excellon +Group named Excellon Optim. Type from which it can be selected +the default optimization type: TS stands for Travelling +Salesman algorithm and Rtree stands for Rtree Indexing +- added a checkbox on the Grid Toolbar that when checked +(default status is checked) whatever value entered in the GridX entry +will be used instead of the now disabled GridY entry +- modified the default behavior on when a line_entry is clicked. +Now, on each click on a line_entry, the content is automatically +selected. +- snap_max_entry is disabled when the DRAW toolbar is disabled + +24.05.2015 + +- in Geometry Editor added a initial form of Rotate Geometry command in +toolbar +- changed the way the geometry is finished if it requires a key: before +it was using key 'Space' now it uses 'Enter' +- added Shortcut for Rotate Geometry to key 'Space' +- after using a tool in Geometry Editor it automatically defaults to +'Select Tool' + +23.05.2018 + +Added key shortcut's in FlatCAMApp and in Geometry Editor. + +FlatCAMApp shortcut list: +1 Zoom Fit +2 Zoom Out +3 Zoom In +C Copy Obj_Name +E Edit Geometry (if selected) +G Grid On/Off +M Move Obj + +N New Geometry +R Rotate +S Shell Toggle +V View Fit +X Flip on X_axis +Y Flip on Y_axis +~ Show Shortcut List + +Space: En(Dis)able Obj Plot +Ctrl+A Select All +Ctrl+C Copy Obj +Ctrl+E Open Excellon File +Ctrl+G Open Gerber File +Ctrl+M Measurement Tool +Ctrl+O Open Project +Ctrl+S Save Project As +Delete Delete Obj''' + + +Geometry Editor Key shortcut list: +A Add an 'Arc' +C Copy Geo Item +G Grid Snap On/Off +K Corner Snap On/Off +M Move Geo Item + +N Add an 'Polygon' +O Add a 'Circle' +P Add a 'Path' +R Add an 'Rectangle' +S Select Tool Active + + +~ Show Shortcut List +Space: Rotate Geometry +Enter: Finish Current Action +Escape: Abort Current Action +Delete: Delete Obj + +22.05.2018 + +- Added Marlin preprocessor +- Added a new entry into the Geometry and Excellon Object's UI: +Feedrate rapid: the purpose is to set a feedrate for the G0 +command that some firmwares like Marlin don't intepret as +'move with highest speed' +- FlatCAM was not making the conversion from one type of units to +another for a lot of parameters. Corrected that. +- Modified the Marlin preprocessor so it will generate the required +GCODE. + +21.05.2018 + +- added new icons for menu entries +- added shortcuts that work on the Project tab but also over +Plot. Shorcut list is accesed with shortcut key '~' sau '`' +- small GUI modification: on each "New File" command it will switch to +the Project Tab regardless on which tab we were. + +- removed the global shear entries and checkbox as they can be +damaging and it will build effect upon effect, which is not good +- solved bug in that the Edit -> Shear on X (Y)axis could adjust +only in integers. Now the angle can be adjusted in float with +3 decimals. +- changed the tile of QInputDialog to a more general one +- changed the "follow" Tcl command to the new format +- added a new entry in the Menu -> File, to open a Gerber with +the follow parameter = True +- added a new checkbox in the Gerber Object Selection Tab that +when checked it will create a "follow" geometry +- added a few lines in Mill Holes Tcl command to check if there are +promises and raise an Tcl error if there are any. +- started to modify the Export_Svg Tcl command + +20.05.2018 + +- changed the interpretation of the axis for the rotate and skew commands. +Actually I reversed them to reflect reality. +- for the rotate command a positive angle now rotates CW. It was reversed. +- added shortcuts (for outside CANVAS; the CANVAS has it's own set of shortcuts) +Ctrl+C will copy to clipboard the name of the selected object +Ctrl+A will Select All objects + +"X" key will flip the selected objects on X axis + +"Y" key will flip the selected objects on Y axis + +"R" key will rotate CW with a 45 degrees step +- changed the layout for the top of th Options page. Added a checkbox and entries +for parameters for skew command. When the checkbox is checked it will save (and +load at the next startup of the program) the option that at each CNCJob generation +(be it from Excellon or Geometry) it will perform the Skew command with the +parametrs set in the nearby field boxes (Skew X and Skey Y angles). +It is useful in case the CNC router is not perfectly alligned between the X and Y axis + +- added some protection in case the skew command receive a None parameter + +- BUG solved: made an UGLY (really UGLY) HACK so now, when there is a panel geometry +generated from GUI, the project WILL save. I had to create a copy of the generated +panel geometry and delete the original panel geometry. This way there is no complain +from JSON module about circular reference. + +Supplimentary: +- removed the Save buttons previously added on each Group in Application Defaults. +Replaced them with a single Save button that stays always on top of the Options TAB +- added settings for defaults for the Grid that are persistent +- changed the default view at FlatCAM startup: now the origin is in the center of the screen + + +19.05.2018 + +- last object that is opened (created) is always automatically selected and +the name of the object is automatically copied to clipboard; useful when +using the TCL command :) + +- added new commands in MENU -> EDIT named: "Copy Object" and +"Copy Obj as Geom". The first command will duplicate any object (Geometry, +Gerber, Excellon). +The second command will duplicate the object as a geometry. For example, +holes in Excello now are just circles that can be "painted" if one wants it. + +- added new Tool named ToolFreeformCutout. It does what it says, it will +make a board cutout from a "any shape" Gerber or Geometry file + +- solved bug in the TCL command "drillcncjob" that always used the endz +parameter value as the toolchangez parameter value and for the endz value +used a default value = 1 + +- added preprocessor name into the TCL command "drillcncjob" parameters + +- when adding a new geometry the default name is now: "New_Geometry" instead +of "New Geometry". TCL commands don't handle the spaces inside the name and +require adding quotes. + +- solved bug in "cncjob" TCL command in which it used multidepth parameter as +always True regardless of the argument provided + +- added a checkbox for Multidepth in the Options Tab -> Application Defaults + + +18.05.2018 + +- added an "Defaults" button in Excellon Defaults Group; it loads the +following configuration (Excellon_format_in 2:4, Excellon_format_mm 3:3, +Excellon_zeros LZ) +- added Save buttons for each Defaults Group; in the future more +parameters will be propagated in the app, for now they are a few +- added functions for Skew on X axis and for Skew on Y menu stubs. +Now, clicking on those Menu -> Options -> Transform Object menu entries +will trigger those functions +- added a CheckBox button in the Options Tab -> Application Defaults that control +the behaviour of the TCL shell: checking it will make the TCL shell window visible +at each start-up, unchecking it the TCL shell window will be hidden until needed +- Depth/pass parameter from Geometry Object CNC Job is now in the +defaults and it will keep it's value until changed in the Application +Defaults. + +17.05.2018 + +- added messages box for the Flip commands to show error in case there +is no object selected when the command is executed +- added field entries in the Options TAB - > Application Defaults for the +following newly introduced parameters: +excellon_format_upper_in +excellon_format_lower_in +excellon_format_upper_mm +excellon_format_lower_mm + +The ones with upper indicate how many digits are allocated for the units +and the ones with lower indicate how many digits from coordinates are +alocated for the decimals. + +[ Eg: Excellon format 2:4 in INCH + excellon_format_upper_in = 2 + excellon_format_lower_in = 4 +where the first 2 digits are for units and the last 4 digits are +decimals so from a number like 235589 we will get a coordinate 23.5589 +] + +- added Radio button in the Options TAB - > Application Defaults for the +Excellon_zeros parameter + +After each change of those parameters the user will have to press +"Save defaults" from File menu in order to propagate the new values, or +wait for the autosave to kick in (each 20sec). + +Those parameters can be set in the set_sys TCL command. + +15.05.2018 +- modified SetSys TCL command: now it can change units +- modified SetSys TCL command: now it can set new parameters: +excellon_format_mm and excellon_format_in. the first one is when the +excellon units are MM and the second is for when the excellon units are +in INCH. Those parameters can be set with a number between 1 and 5 and it +signify how many digits are before coma. +- added new GUI command in EDIT -> Select All. It will select all +objects on the first mouse click and on the second will deselect all +(toggle action) +- added new GUI commands in Options -> Transform object. Added Rotate selection, +Flip on X axis of the selection and Flip on Y axis of the selection +For the Rotate selection command, negative numbers means rotation CCW and +positive numbers means rotation CW. + +- cleaned up a bit the module imports +- worked on the excellon parsing for the case of trailing zeros. +If there are more than 6digits in the +coordinates, in case that there is no period, now the software will +identify the issue and attempt to correct it by dividing the coordinate +further by 10 for each additional digit over 6. If the number of digits +is less than 6 then the software will multiply by 10 the coordinates + +14.05.2018 + +- fixed bug in Geometry CNCJob generation that prevented generating +the object +- added GRBL 1.1 preprocessor and Laser preprocessor (adapted from +the work of MARCO A QUEZADA) + + +13.05.2018 + +- added postprocessing in correct form +- added the possibility to select an preprocessor for Excellon Object +- added a new preprocessor, manual_toolchange.py. It allows to change +the tools and adjust the drill tip to touch the surface manually, always +in the X=0, Y=0, Z = toolchangeZ coordinates. +- fixed drillcncjob TCL command by adding toolchangeZ parameter +- fixed the preprocessor file template 'default.py' in the toolchange +command section +- after I created a feature that the message in infobar is cleared by +moving mouse on canvas, it generated a bug in TCL shell: everytime +mouse was moved it will add a space into the TCL read only section. +Now this bug is fixed. +- added an EndZ parameter for the drillcncjob and cncjob TCL commands: it +will specify at what Z value to park the CNC when job ends +- the spindle will be turned on after the toolchange and it will be turned off +just before the final end move. + +Previously: +- added GRID based working of FLATCAM +- added Set Origin command +- added FilmTool, PanelizeTool GUI, MoveTool +- and others + + +24.04.2018 + +- Remade the Measurement Tool: it now ask for the Start point of the measurement and then for the Stop point. After it will display the measurement until we left click again on the canvas and so on. Previously you clicked the start point and reset the X and Y coords displayed and then you moved the mouse pointer wherever you wanted to measure, but moving the mouse from there you lost the measurement. +- Added Relative measurement on the main plot +- Now both the measuring tool and the relative measurement will work only with the left click of the mouse button because middle mouse click and right mouse click are used for panning +- Renamed the tools files starting with Tool so they are grouped (in the future they may have their own folder like for TCL Commands) + +- Commented some shortcut keys and functions for features that are not present anymore or they are planned to be in the future but unfinished (like buffer tool, paint tool) +- minor corrections regarding PEP8 (Pycharm complains about the m) +- solved bug in TclCommandsSetSys.py Everytime that the command was executed it complain about the parameter not being in the list (something like this). There was a missing “else:” +- when using the command “set_sys excellon_zeros” with parameter in lower case (either ‘l’ or ‘t’) now it is always written in the defaults file as capital letter + +- solved a bug introduced by me: when apertures macros were detected in Excellon file, FlatCam will complain about missing dictionary key “size”. Now it first check if the aperture is a macro and perform the check for zero value only for apertures with “size” key +- solved a bug that didn't allowed FC to detect if Excellon file has leading zeros or trailing zeros +- solved a bug that FC was searching for char ‘%’ that signal end of Excellon header even in commented lines (latest versions of Eagle end the commented line with a ‘%’) + + +============================================ + +This fork features: + +- Added buttons in the menu bar for opening of Gerber and Excellon files; +- Reduced number of decimals for drill bits to two decimals; +- Updated make_win32.py so it will work with cx_freeze 5.0.1 +- Added capability so FlatCAM can now read Gerber files with traces having zero value (aperture size is zero); +- Added Paint All / Seed based Paint functions from the JP's FlatCAM; +- Added Excellon move optimization (travelling salesman algorithm) cherry-picked from David Kahler: https://bitbucket.org/dakahler/flatcam +- Updated make_win32.py so it will work with cx_freeze 5.0.1 Corrected small typo in DblSidedTool.py +- Added the TCL commands in the new format. Picked from FLATCAM master. +- Hack to fix the issue with geometry not being updated after a TCL command was executed. Now after each TCL command the plot_all() function is executed and the canvas is refreshed. +- Added GUI for panelization TCL command +- Added GUI tool for the panelization TCL command: Changed some ToolTips. + + +============================================ + +Previously added features by Dennis + +- "Clear non-copper" feature, supporting multi-tool work. +- Groups in Project view. +- Pan view by dragging in visualizer window with pressed MMB. +- OpenGL-based visualizer. + diff --git a/README.md b/README.md index c682b260..265a097e 100644 --- a/README.md +++ b/README.md @@ -1,4522 +1,53 @@ -FlatCAM: 2D Computer-Aided PCB Manufacturing +FlatCAM BETA (c) 2019 - by Marius Stanciu +Based on FlatCAM: 2D Computer-Aided PCB Manufacturing by (c) 2014-2016 Juan Pablo Caram ================================================= -(c) 2014-2016 Juan Pablo Caram - FlatCAM is a program for preparing CNC jobs for making PCBs on a CNC router. Among other things, it can take a Gerber file generated by your favorite PCB CAD program, and create G-Code for Isolation routing. ================================================= -20.04.2020 +------------ Installation instructions ------------ -- made the Grid icon in the status bar clickable and it will toggle the snap to grid function -- some mods in the Distance Tool -- added ability to use line width when adding shapes for both Legacy and OpenGL graphic engines -- added the linewidth=2 parameter for the Tool Distance utility geometry -- fixed a selection issue in Legacy graphic mode for single click +Works with Python version 3.5 or greater and PyQt5. -19.04.2020 +- Download sources from: https://bitbucket.org/jpcgt/flatcam/downloads/ +- Unzip them on a HDD location that your user has permissions for. -- fixed a bug that did not allow to edit GUI elements of type FCDoubleSpinner if it contained the percent symbol -- some small optimizations in the GUI of Cutout Tool -- fixed more issues (new) in NCC Tool -- added a new layout named 'minimal' -- some PEP8 changes in Geometry Editor +1. MacOS +- none (yet) -15.04.2020 +2. Linux +- make sure that Python 3.8 is installed on your OS and that the command: python3 -V confirm it +- verify that the file setup_ubuntu.sh has Linux line-endings (LF) and that it is executable (chmod +x setup_ubuntu.sh) +- run the file setup_ubuntu.sh and install all the dependencies with the command: ./setup_ubuntu.sh +- if the previous command is successful and has no errors, run FlatCAM with the command: python3 FlatCAM.py -- made sure that the Tcl commands descriptions listed on help command are aligned +3. Windows +- download the provided installer (for your OS flavor 64bit or 32bit) from https://bitbucket.org/jpcgt/flatcam/downloads/ +- execute the installer and install the program. It is recommended to install as a Local User. -14.04.2020 +or +- download the sources from the same location +- unzip them on a safe location on your HDD that your user has permissions for +- install WinPython e.g WinPython 3.8 downloaded from here: https://sourceforge.net/projects/winpython/files/WinPython_3.8/ +Use one of the versions (64bit or 32it) that are compatible with your OS. To save space use one of the versions that have the smaller size (they offer 2 versions: one with size of few hundred MB and one smaller with size of few tens of MB) -- lightened the hue of the color for 'success' messages printed in the Tcl Shell browser -- modified the extensions all over such the names include also the extension name. For Linux who does not display the extensions in the native FileDialog. -- added descriptions for some of the methods in the app. -- added lightened icons for the dark theme from Leandro Heck - -13.04.2020 - -- added the outname parameter for the geocutout Tcl command -- multiple fixes in the Tcl commands (especially regarding the interchange between True/false and 1/0 values) -- updated the help for all Tcl Commands -- in Tcl Shell, the 'help' command will add also a brief description for each command in the list -- updated the App.plot_all() method giving it the possibility to be run as threaded or not -- updated the Tcl command PlotAll to be able to run threaded or not -- updated the Tcl commands PlotAll and PlotObjects to have a parameter that control if the objects are to be plotted or not on canvas; it serve as a disable/enable -- minor update to the autocomplete dictionary -- the Show Shell in Edit -> Preferences will now toggle the Tcl shell based on the current status of the Tcl Shell -- updated the Tcl command Isolate help for follow parameter -- updated DrillCncJob Tcl Command with new parameters and fixed it to work in the new format of the Excellon methods -- fixed issue #399 -- changed CncJob Tcl Command parameter 'depthperpass' to a shorter 'dpp' - -11.04.2020 - -- fixed issue #394 - the saveDialog in Linux did not added the selected extension -- when the Save button is clicked in the Edit -> Preferences the Preferences tab is closed. - -10.04.2020 - -- made sure that the timeout parameter used by some Tcl Commands is seen as an integer in all cases - fixed issue #389 -- minor changes in Paint Tool -- minor changes in GUI (Save locations in Menu -> File) and the key shortcuts - fixed issue #391 - - -9.04.2020 - -- if FlatCAM is not run with Python version >= 3.5 it will exit. -- modified all CTRL+ with Ctrl+ and all ALT+ with Alt+ and all SHIFT+ with Shift+. Fixed issue #387. -- removed some packages from setup_ubuntu.sh as they are not needed in FlatCAM beta - -8.4.2020 - -- fixed the Tcl Command Delete to have an argument -f that will force deletion evading the popup (if the popup is enabled). The sme command without a name now will delete all objects -- fixed the Tcl Command JoinExcellons -- fixed the Tcl Command JoinGeometry -- fixed the Tcl Command Mirror -- updated the Tcl Command Mirror to use a (X,Y) origin parameter. Works if the -box parameter is not used. -- updated the Tcl Command Offset. Now it can use only -x or -y parameter no longer is mandatory to have both. The one that is not present will be assumed 0.0 -- updated the Tcl Command Panelize. The -rows and -columns parameters are no longer both required. If one is not present then it is assumed to be zero. -- updated the Tcl Command Scale. THe -origin parameter can now be a tuple of (x,y) coordinates. -- updated the Tcl Command Skew. Now it can use only -x or -y parameter no longer is mandatory to have both. The one that is not present will be assumed 0.0 -- updated the help for all the Tcl Commands - -6.04.2020 - -- added key shortcuts (arrow up/down) that will select the objects in the Project tab if the focus is in that tab -- added a minor change to the ListSys Tcl command -- fixed an crash generated when running the Tool Database from the Menu -> Options menu entry -- fixed a bug in handling the UP/DOWN key shortcuts that caused a crash when no object was selected in the Project Tab; also made sure that the said keys are handled only for the Project Tab -- some PEP8 changes and other minor changes -- updated the requirements file -- updated the 2Sided Tool by not allowing the Gerber file to be mirrored without a valid reference and added some placeholder texts - -5.04.2020 - -- made sure that the HDPI scaling attribute is set before the QApplication is started -- made sure that when saving a project, the app will try to update the active object from UI form only if there is an active object -- fix for contextual menus on canvas when using PyQt versions > 5.12.1 -- decision on which mouse button to use for panning is done now once when setting the plotcanvas -- fix to work with Python 3.8 (closing the application) -- fixed bug in Gerber parser that allowed loading as Gerber of a file that is not a Gerber -- fixed a bug in extension detection for Gerber files that allowed in the filtered list files that extension *.gb* -- added a processEvents method in the Gerber parser parse_lines() method -- fixed issue #386 - multiple Cut operation on a edited object created a crash due of the bounds() method -- some changes in the Geometry UI - -4.04.2020 - -- fixed the Repeated code parsing in Excellon Parse - -1.04.2020 - -- updated the SVG parser to take into consideration the 'Close' svg element and paths that are made from a single line (we may need to switch to svgpathtools module) -- minor changes to increase compatibility with Python 3.8 -- PEP8 changes - -30.03.2020 - -- working to update the Paint Tool -- fixed some issues in Paint Tool - -29.03.2020 - -- modified the new database to accept data from NCC and Paint Tools -- fixed issues in the new database when adding the tool in a Geometry object -- fixed a bug in Geometry object that generated a change of dictionary while iterating over it -- started to add the new database links in the NCC and Paint Tools -- in the new Tools DB added ability to double click on the ID in the tree widget to execute adding a tool from DB -- working in updating NCC Tool - -28.03.2020 - -- finished the new database based on a QTreeWidget - -21.03.2020 - -- fixed Cutout Tool to work with negative values for Margin parameter - -20.03.2020 - -- updated the "re-cut" feature in Geometry object; now if the re-cut parameter is non zero it will cut half of the entered distance before the isolation end and half of it after the isolation end -- added to Paint and NCC Tool a feature that allow polygon area selection when the reference is selected as Area Selection -- in Paint Tool and NCC Tool added ability to use Escape Tool to cancel Area Selection and for Paint Tool to cancel Polygon Selection -- fixed issue in "re-cut" feature when combined with multi-depth feature -- fixed bugs in cncjob TclCommand - -13.03.2020 - -- fixed a bug in CNCJob generation out of a Excellon object; the plot failed in case some of the geometry of the CNCJob was invalid -- fixed Properties Tool due of recent changes to the FCTree widget - -12.03.2020 - -- working on the new database -- fix a bug in the TextInputTool in FlatCAM Geometry Editor that crashed the sw when some fonts are not loaded correctly - -4.03.2020 - -- updated all the FlatCAM Tools and the Gerber UI FCComboBoxes to update the box value with the latest object loaded in the App -- some fixes in the NCC Tool -- modified some strings - -02.03.2020 - -- added property that allow the FCComboBox to update the view with the last item loaded; updated the app to use this property - -01.03.2020 - -- updated the CutOut Tool such that while adding manual gaps, the cutting geometry is updated on-the-fly if the gap size or tool diameter parameters are adjusted -- updated the UI in Geometry Editor - -29.02.2020 - -- compacted the NCC Tool UI by replacing some Radio buttons with Combo boxes due of too many elements -- fixed error in CutOut Tool when trying to create a FreeFrom Cutout out of a Gerber object with the Convex Shape checked -- working on a new type of database - -28.02.2020 - -- some small changes in preprocessors -- solved issue #381 where there was an error when trying to generate CNCJob out of an Excellon file that have a tool with only slots and no drills -- solved some issues in the preprocessors regarding the newly introduced feature that allow control of the final move X,Y positions - -25.02.2020 - -- fixed bug in Gerber parser: it tried to calculate a len() for a single element and not a list - a Gerber generated by Eagle exhibited this -- added a new parameter named 'End Move X,Y' for the Geometry and Excellon objects. Adding a tuple of coordinates in this field will control the X,Y position of the final move; not entering a value there will cause not to make an end move - -20.02.2020 - -- in Paint Tool replaced the Selection radio with a combobox GUI element that is more compact -- in NCC Tool modified the UI - -19.02.2020 - -- fixed some issues in the Geometry Editor; the jump signal disconnect was failing for repeated Editor tool operation -- fixed an issue in Gerber Editor where the multiprocessing pool was reported as closed and an ValueError exception was raised in a certain scneraio -- on Set Origin, Move to Origin and Move actions for Gerber and Excellon objects the source file will be also updated (the export functions will export an updated object) -- in FlatCAMObj.export_gerber() method took into account the possibility of polygons of type 'clear' (the ones found in the Gerber files under the LPC command) - -17.02.2020 - -- updated the Excellon UI to hold data for each tool -- in Excellon UI removed the tools table column for Offset Z and used the UI form parameter -- updated the Excellon Editor to add for each tool a 'data' dictionary -- updated all FlatCAM tools to use the new confirmation message that show if the entered value is within range or outside -- updated all FlatCAM tools to use the new confirmation message for QSpinBoxes, too -- in Excellon UI protected the values that are common parameters from change on tool selection change -- fixed some issues related to the usage of the new confirmation message in FlatCAM Tools -- made sure that the FlatCAM Tools UI initialization is done only in set_tool_ui() method and not in the constructor -- adapted the GCode generation from Excellon to work with multiple tools data and modified the preprocessors header -- when multiple tools are selected in Excellon UI and parameters are modified it will applied to all selected -- in Excellon UI, Paint Tool and NCC Tool finished the "Apply parameters to all tools" functionality -- updated Paint Tool and NCC Tool in the UI functionality -- fixed the Offset spinbox not being controller by offset checkbox in NCC Tool - -16.02.2020 - -- small update to NCC Tool UI - -15.02.2020 - -- in Paint Tool added a new method of painting named Combo who will pass through all the methods until the polygon is cleared -- in Paint Tool attempting to add a new mode suitable for Laser usage -- more work in the new Laser Mode in the Paint Tool -- modified the Paint Tool UI - -14.02.2020 - -- adjusted the UI for Excellon and Geometry objects -- added a new FlatCAM Tool: Gerber Invert Tool. It will invert the copper features in a Gerber file: where is copper there will be empty and where is empty it will be copper -- added the Preferences entries for the Gerber Invert Tool - -13.02.2020 - -- finished Punch Gerber Tool -- minor changes in the Tool Transform and Tool Calculators UI to bring them up2date with the other tools - -12.02.2020 - -- working on fixing a bug in FlatCAMGeometry.merge() - FIXED issue #380 -- fixed bug: when deleting a FlatCAMCNCJob with annotations enabled, the annotations are not deleted from canvas; fixed issue #379 -- fixed bug: creating a new project while a project is open and it contain CNCJob annotations and/or Gerber mark shapes, did not delete them from canvas - -11.02.2020 - -- working on Tool Punch; finished the geometry update with the clear geometry for the case of Excellon method -- working on Tool Punch; finished the geometry update with the clear geometry for the case of Fixed Diameter method - -10.02.2020 - -- optimized the Paint and NCC Tools. When the Lines type of painting/clearing is used, the lines will try to arrange themselves on the direction that the lines length clearing the polygon are bigger -- solved bug that made drilling with Marlin preprocessor very slow -- applied the fix for above bug to the TclCommand Drillcncjob too -- started a new way to clear the Gerber polygons based on the 'follow' lines -- some cleanup and bug fixes for the Paint Tool - - -8.02.2020 - -- added a new preprocessor for using laser on a Marlin 3D printer named 'Marlin_laser_use_Spindle_pin' -- modified the Geometry UI when using laser preprocessors -- added a new preprocessor file for using laser on a Marlin motion controller but with the laser connected to one of the FAN pins, named 'Marlin_laser_use_FAN_pin' -- modified the Excellon GCode generation so now it can use multi depth drilling; modified the preprocessors to show the number of passes - -5.02.2020 - -- Modified the Distance Tool such that the Measure button can't be clicked while measuring is in progress -- optimized selection of drills in the Excellon Editor -- fixed bugs in multiple selection in Excellon Editor -- fixed selection problems in Gerber Editor -- in Distance Tool, when run in the Excellon or Gerber Editor, added a new option to snap to center of the geometry (drill for Excellon, pad for Gerber) - -3.02.2020 - -- modified Spinbox and DoubleSpinbox Custom UI elements such that they issue a warning status message when the typed value is out of range -- fixed the preprocessors with 'laser' in the name to use the spindle direction set in the Preferences -- increased the upper limit for feedrates by an order of magnitude - -2.02.2020 - -- fixed issue #376 where the V-Shape parameters from Gerber UI are not transferred to the resulting Geometry object if the 'combine' checkbox is not checked in the Gerber UI -- in Excellon UI, if Basic application mode is selected in Preferences, the Plot column 'P' is hidden now because some inexperienced users mistake this column checkboxes for tool selection -- fixed an error in Gerber Parser; the initial values for current_x, current_y were None but should have been 0.0 -- limited the lower limit of angle of V-tip to a value of 1 because 0 makes no sense -- small changes in Gerber UI -- in Geometry Editor make sure that after an edit is finished (correctly or forced) the QTree in the Editor UI is cleared of items - -31.01.2020 - -- added a new functionality, a variation of Set Origin named Move to Origin. It will move a selection of objects to origin such as the bottom left corner of the bounding box that fit them all is in origin. -- fixed some bugs -- fixed a division by zero error: fixed #377 - -30.01.2020 - -- remade GUI in Tool Cutout, Tool Align Objects, Tool Panelize -- some changed in the Excellon UI -- some UI changes in the common object UI - -29.01.2020 - -- changes in how the Editor exit is handled -- small fix in some pywin32 imports -- remade the GUI + small fixes in 2Sided Tool -- updated 2Sided Tool - -28.01.2020 - -- some changes in Excellon Editor - -27.01.2020 - -- in Geometry Editor made sure that on final save, for MultiLineString geometry all the connected lines are merged into one LineString to minimize the number of vertical movements in GCode -- more work in Punch Gerber Tool -- the Jump To popup window will now autoselect the LineEdit therefore no more need for an extra click after launching the function -- made some structural changes in Properties Tool -- started to make some changes in Geometry Editor -- finished adding in Geometry Editor a TreeWidget with the geometry shapes found in the edited object - -24.02.2020 - -- small changes to the Toolchange manual preprocessor -- fix for plotting Excellon objects if the color is changed and then the object is moved -- laying the GUI for a new Tool: Punch Gerber Tool which will add holes in the Gerber apertures -- fixed bugs in Minimum Distance Tool -- update in the GUI for the Punch Gerber Tool - -22.01.2020 - -- fixed a bug in the bounding box generation - -19.01.2020 - -- fixed some bugs that are visible in Linux regarding the ArgsThread class: on app close we need to quit the QThread running the ArgsThread class and also close the opened Socket -- make sure that the fixes above apply when rebooting app for theme change or for language change -- fixed and issue that made setting colors for the Gerber file not possible if using a translation -- made possible to set the colors for Excellon objects too -- added to the possible colors the fundamentals: black and white -- in the project context menu for setting colors added the option to set the transparency and also a default option which revert the color to the default value set in the Preferences - -17.01.2020 - -- more changes to Excellon UI -- changes to Geometry UI -- more work in NCC Tool upgrade; each tool now work with it's own set of parameters -- some updates in NCC Tool -- optimized the object envelope generation in the redesigned NCC Tool - -16.01.2020 - -- updated/optimized the GUI in Preferences for Paint Tool and for NCC Tool -- work in Paint Tool to bring it up to date with NCC Tool -- updated the GUI in preferences for Calculator Tool -- a small change in the Excellon UI -- updated the Excellon and Geometry UI to be similar -- put bases for future changes to Excellon Object UI such that each tool will hold it's own parameters -- in ParseExcellon.Excellon the self.tools dict has now a key 'data' which holds a dict with all the default values for Excellon and Geometry -- Excellon and Geometry objects, when started with multiple tools selected, the parameters tool name reflect this situation -- moved default_data data update from Excellon parser to the Excellon object constructor - -15.01.2020 - -- added key shortcuts and toolbar icons for the new tools: Align Object Tool (Alt+A) and Extract Drills (Alt+I) -- added new functionality (key shortcut Shift+J) to locate the corners of the bounding box (and center) in a selected object -- modified the NCC Tool GUI to prepare for accepting a tool from a tool database -- started to modify the Paint Tool to be similar to NCC Tool and to accept a tool from a database -- work in Paint Tool GUI functionality - -14.01.2020 - -- in Extract Drill Tool added a new method of drills extraction. The methods are: fixed diameter, fixed annular ring and proportional -- in Align Objects Tool finished the Single Point method of alignment -- working on the Dual Point option in Align Objects Tool - angle has to be recalculated -- finished Dual Point option in Align Objects Tool - -13.01.2020 - -- fixed a small GUI issue in Excellon UI when Basic mode is active -- started the add of a new Tool: Align Objects Tool which will align (sync) objects of Gerber or Excellon type -- fixed an issue in Gerber parser introduced recently due of changes made to make Gerber files produced by Sprint Layout -- working on the Align Objects Tool - -12.01.2020 - -- improved the circle approximation resolution -- fixed an issue in Gerber parser with detecting old kind of units -- if CTRL key is pressed during app startup the app will start in the Legacy(2D) graphic engine compatibility mode - -11.01.2020 - -- fixed an issue in the Distance Tool -- expanded the Extract Drills Tool to use a particular annular ring for each type of aperture flash (pad) -- Extract Drills Tool: fixed issue with oblong pads and with pads made from aperture macros -- Extract Drills Tool: added controls in Edit -> Preferences - -10.02.2020 - -- working on a new tool: Extract Drills Tool who will create a Excellon object out of the apertures of a Gerber object -- finished the GUI in the Extract Drills Tool -- fixed issue in Film Tool where some parameters names in calls of method export_positive() were not matching the actual parameters name -- finished the Extract Drills Tool -- fixed a small issue in the DoubleSided Tool - -8.01.2020 - -- working in NCC Tool -- selected rows in the Tools Tables will stay colored in blue after loosing focus instead of the default gray -- in NCC Tool the Tool name in the Parameters section will be the Tool ID in the Tool Table -- added an exception catch in case the plotcanvas init failed for the OpenGL graphic engine and warn user about what happened - -7.01.2020 - -- solved issue #368 - when using the Enable/Disable prj context menu entries the plotted status is not updated in the object properties -- updates in NCC Tool - -6.01.2020 - -- working on new NCC Tool - -2.01.2020 - -- started to rework the NCC Tool GUI in preparation for adding a Tool DB feature -- for auto-completer, now clicking an entry in the completer popup will select that entry and insert it -- made available only for Linux and Windows (not OSX) the starting of the thread that checks if another instance of FlatCAM is already running at the launch of FLatCAM -- modified Toggle Workspace function to work in the new Preferences UI configuration -- cleaned the app from progress signal usage since it is not used anymore - -1.01.2020 - -- fixed bug in NCC Tool: after trying to add a tool already in the Tool Table when trying to change the Tool Type the GUI does not change -- final fix for app not quiting when running a script as argument, script that has the quit_flatcam Tcl command; fixed issue #360 -- fixed issue #363. The Tcl command drillcncjob does not create tool cut, does not allow creation of gcode, it forces the usage of dwell and dwelltime parameters -- in NCC Tool I've added a warning so the user is warned that the NCC margin has to have a value of at least the tool diameter that is doing an iso_op job in the Tool Table -- modified the Drillcncjob and Cncjob Tcl commands to be allowed to work without the 'dwell' and 'toolchange' arguments. If 'dwelltime' argument is present it will be assumed that the 'dwell' is True and the same for 'toolchangez' parameter, if present then 'toolchange' will be assumed to be True, else False -- modified the extracut and multidepth parameters in Cncjob Tcl command like for dwell and toolchange -- added ability for Tcl commands to have optional arguments with None value (meaning missing value). This case should be treated for each Tcl command in execute() method -- fixed the Drillcncjob Tcl command by adding an custom self.options key "Tools_in_use" and build it's value, in case it does not exist, to make the toolchange command work -- middle mouse click on closable tabs will close them - -30.12.2019 - -- Buffer sub-tool in Transform Tool: added the possibility to apply a factor effectively scaling the aperture size thus the copper features sizes -- in Transform Tool adjusted the GUI -- fixed some decimals issues in NCC Tool, Paint Tool and Excellon Editor (they were still using the hardcoded values) -- some small updates in the NCC Tool -- changes in the Preferences UI for NCC and Paint Tool in Tool Dia entry field -- fixed Tcl commands that use the overlap parameter to switch from fraction to percentage -- in Transform Tool made sure that the buffer sub-tool parameters are better explained in tooltips -- attempt to make TclCommand quit_flatcam work under Linux -- some fixes in the NCC Tcl command (using the bool() method on some params) -- another attempt to make TclCommand quit_flatcam work under Linux -- another attempt to make TclCommand quit_flatcam work under Linux - use signal to call a hard exit when in Linux -- TclCommand quit_flatcam work under Linux - -29.12.2019 - -- the Apply button text in Preferences is now made red when changes were made and require to be applied -- the Gerber UI is built only once now so the process is lighter on CPU -- the Gerber apertures marking shapes storage is now built only once because the more are built the more sluggish is the interface -- added a new function called by shortcut key combo Ctrl+G when the current widget in Plot Area is an Code Editor. It will jump to the specified line in the text. -- fixed a small bug where the app tried to hide a label that I've removed previously -- in Paint Tool Preferences is allowed to add a list of initial tools separated by comma -- in Geometry Paint Tool fixed the Overlap rate to work between 0 and 99.9999% - -28.12.2019 - -- more updates to the Preferences window and in some other parts of the GUI -- updated the translations (less Russian) -- fixed a minor issue that when saving a project with CNCJob objects, the variable that holds the origin of the CNCJob object was not saved in the project. Added to the serializable objects also the exc_cnc_tools dictionary -- some changes in the File menu - -28.12.2019 - -- updated all the translations files -- fixed the big mouse cursor in OpenGL(3D) graphic mode to get the set color -- fixed the cursor to have the set color and set cursor width in the Legacy(2D) graphic engine -- in Legacy(2D) graphic mode fixed the cursor toggle when the big cursor is activated -- in Legacy(2D) fixed big mouse cursor to snap to the grid -- RELEASE 8.991 - -27.12.2019 - -- updated the POT file and the translation files for German, Spanish and French languages -- fixed some typos - -26.12.2019 - -- modified the ToolDB class and changed some strings -- Preferences classes now have access to the App attributes through app.setup_obj_classes() method -- moved app.setup_obj_classes() upper in the App.__init__() -- added a new Preferences setting allowing to modify the mouse cursor color -- remade the GUI in Preferences -> General grouping the settings in a more clear way -- made available the Jump To function in Excellon Editor -- added a clean_up() method in all the Editor Tools that need it, to be run when aborting using the ESC key -- fixed an error in the Gerber parser; it did not took into consideration the aperture size declared before the beginning of a Gerber region. Detected for Gerber files generated by KiCAD 5.x -- in Panelize Tool made sure that for Gerber objects if one of the apertures is without geometry then it is ignored -- further modifications in Preferences -> General GUI -- further modifications in Preferences -> General GUI - extended the changes -- in Legacy(2D) graphic engine made to work the mouse color change -- theme changing is no longer auto-reboot upon change; it require now to press a button -- cleaned the Preferences classes and added the signals and signal slots in those classes, removing them from the main app class -- each FlatCAM object found in Preferences has it's own set of controls for changing the colors -- added a set of gray icons to be used when the theme is complete dark (for now it is useful only for MacOS with dark theme because at the moment the app is not styled to dark UI except the plot area) - -25.12.2019 - -- fixed an issue in old default file detection and in saving the factory defaults file -- in Preferences window removed the Import/Export Preferences buttons because they are redundant with the entries in the File -> Menu -> Backup. and added a button to Restore Defaults -- when in Basic mode the Tool type of the tool in the Geometry UI Tool Table after isolating a Gerber object is automatically selected as 'C1' -- let the multiprocessing Pool have as many processes as needed -- added a new Preferences setting allowing a custom mouse line width (to make it thicker or thinner) -- changed the extension of the Tool Database file to FlatDB for easy recognition (in the future double clicking such a file might import the new tools in the FC database) - -24.12.2019 - -- edited some icons so they don't contain white background -- fixed an incorrect usage of object in the app.select_objects() method -- fixed a typo in ToolDB.on_tool_add() - -23.12.2019 - -- some fixes in the Legacy(2D) graphic mode regarding the possibility of changing the color of the Gerber objects -- added a method to darken the outline color for Gerber objects when they have the color set -- when Printing as PDF Gerber objects now the rendered color is the print color -- speed up the plotting in OpenGL(3D) graphic mode -- speed up the color setting for Gerber object when using the OpenGL(3D) graphic mode -- setting color for Gerber objects work on a selection of Gerber objects -- ~~when the selection is changed in the Project Tree the selection shape on canvas is deleted~~ -- if an object is selected on Project Tree and it does not have the selection shape drawn, first click on canvas over it will draw the selection shape -- in Tool Transform added a new feature named 'Buffer'. For Geometry and Gerber objects will create (and replace) a geometry at a distance from the original geometry and for Excellon will adjust the Tool diameters -- solved issue #355 - when the tool diameter field in the Edit → Preferences → Geometry → Geometry General → Tools → Tool dia is only one the app failed to read it -- solved issue #356 - in Tools DB can not be added more than one tool if a translation is active -- some changes related to the fact that the geometry default tool diameter value can be comma separated string of tool diameters - -22.12.2019 - -- added a new option for the Gerber objects: on the project context menu now can be chosen a color for the selected Gerber object -- fixed issue in Gerber UI where a label was not hidden when in Basic mode -- added the color parameters of the objects to the serializable attributes -- fixed Gerber object color set for Legacy(2D) graphic engine; glitch on the OpenGL(3D) graphic engine -- fixed the above mentioned glitch in the OpenGL(3D) graphic engine when an Gerber object has been set with a color - -21.12.2019 - -- fixed a typo in Distance Tool - -20.12.2019 - -- fixed a rare issue in the generation of non-copper-region geometry started from the Gerber Object UI (selected tab) -- Print function is now printing a PDF file for a selection of objects in the colors from canvas -- added an icon in the infobar that will show more clearly the status of the grid snapping -- in Geometry Object UI (selected tab) when a tool type is changed from no matter what to V-shape, the cut_z value is saved and when the tool type is changed back to something different than V-shape, this saved cut-z value is restored -- fixed re-cut length entry not staying disabled when the re-cut cb is not checked - -19.12.2019 - -- in 2-Sided Tool added a way to calculate the bounding box values for a selection of objects, and also the centroid -- in 2-Sided Tool fixed the Reset Tool button handler to reset the bounds value too; changed a string -- added Preferences values for PDF margins when saving text in Code Editor as PDF -- when clicking Cancel in Preferences now the values are reverted to what they used to be before opening Preferences tab and start changing values -- starting to work to a general Print function; for now it will generate PDF files; currently it works only for one object not for a selection -- added shortcut key Ctrl+P for printing to PDF method - -18.12.2019 - -- added new parameters to improve Gerber parsing -- small optimizations in the Preferences UI -- the Jump To function reference is now saving it's last used value -- added the ability to use the Jump To method in the Gerber Editor -- improved the loading of Config File by using the advanced code editor -- fixed a bug in the new feature 'extra buffering' -- fixed the creation of CNCJob objects out of multigeo Geometry objects (objects with multiple tools) -- optimized the NCC Tool - -17.12.2019 - -- more optimizations in NCC Tool -- optimizations in Paint Tool -- maximum range for Cut Z is now zero to deal with the situation when using V-shape with tip-dia same value with cut width -- modified QValidator in FCDoubleSpinner() GUI element to allow entering the minus sign when the range maximum is set as 0.0; also for positive numbers allowed entering the symbol plus -- made sure that if in Gerber UI the isolation is made with a V-Shape tool then the tool type is automatically updated on the generated Geometry Object -- added ability to save the Source File as PDF (still have to adjust the page size) -- fixed the generate_from_geometry_2() method to use the default values in case the parameters are None -- added ability to save the Source File as PDF - fixed page size and added line breaks -- more mods to generate_from_geometry_2() method -- fixed bug saving the FlatCAM project saying the file is used by another application -- fixed issue #347 - a Gerber generated by Sprint Layout with copper pour ON will not have rendered the copper pour - -16.12.2019 - -- in Geometry Editor added support for Jump To function such as that it works within the Editor Tools themselves. For now it works only in absolute jumps -- modified the Jump To method such that now allows relative jump from the current mouse location -- fixed the Defaults upgrade overwriting the new version number with the old one -- fixed issue with clear_polygon3() - the one who makes 'lines' and fixed the NCC Tool -- some small changes in the FlatCAMGeometry.on_tool_add() method -- made sure that in Geometry Editor the self.app.mouse attribute is updated with the current mouse position (x, y) -- updated the preprocessor files -- fixed the HPGL preprocessor -- fixed the CNCJob geometry created with HPGL preprocessor -- fixed GCode generated with HPGL preprocessor to output only integer coordinates -- fixed the HPGL2 import parsing for absolute linear movements -- fixed the line endings for setup_ubuntu.sh - -15.12.2019 - -- fixed a bug that created a crash in special conditions; it's related to the QSettings in FlatCAMGui.py -- added a script to remove the bad profiles from resource pictures. From here: https://stackoverflow.com/questions/22745076/libpng-warning-iccp-known-incorrect-srgb-profile/43415650, link mentioned by @camellan (Andrey Kultyapov) -- prepared the application for usage of dark icons in case of using the dark theme -- updated the languages -- fixed a typo -- fixed layout on first launch of the app -- fixed some issues with the recent preparation for dark icons resource usage -- added a new preprocessor file contributed by Daniel Friderich and added fixes for it -- modified the export_gcode() method and the preprocessors such that the preprocessors now have the information if to include the gcode header -- updated all the translation PO files and the POT file -- RELEASE 8.99 - -14.12.2019 - -- finished the strings update in the Google-translated Spanish -- finished the strings update in the Google-translated French - -13.12.2019 - -- HPGL2 import: added support for circles, arcs and 3-point arcs. Everything works only for absolute coordinates. -- removed the .plt extension from Gcode extensions -- some strings updated; update on the Romanian translate -- more strings updated; finished the Romanian translation update -- some work in updating the Spanish Google-translation -- small updates (Google Translate) in Russian and Brazilian-PT languages - -12.12.2019 - -- finished the Calibration Tool -- changed the Scale Entry in Object UI to FCEntry() GUI element in order to allow expressions to be entered. E.g: 1/25.4 -- some small changes in the Scale button handler in FlatCAMObj() class -- added option to save objects as PDF files in File -> Save menu -- optimized the FlatCAMGerber.clear_plot_apertures() method -- some changes in the ObjectUI and for the Geometry UI -- finished a very rough and limited HPGL2 file import - -11.12.2019 - -- started work in HPGL2 parser -- some more work in Calibration Tool - -10.12.2019 - -- small changes in the Geometry UI -- now extracut option in the Geometry Object will recut as many points as many they are within the specified re-cut length -- if extracut_length is zero then the extracut will cut up until the first point in path no matter what the distance is -- in Gerber isolation, when selection mode is checked, now area selection works too -- in CNCJob UI, now the CNCJob objects made out of Excellon objects will display their CNC tools (drill bits) -- fixed a cumulative error when using the Tool Offset for Excellon objects -- added the display of the real depth of cut (cut z + offset_z) for CNC tools made out of an Excellon object -- for OpenGL graphic mode added a fit_view() execution on canvas initialization -- fixed Excellon scaling the UI values -- replaced the SpindleSpeed entry with a FCSpinner() GUI element; if speed is set to 0 it will amount to None - -9.12.2019 - -- updated the border for fit view on OpenGL graphic mode -- Calibration Tool - added preferences values -- Calibration Tool - more work on it -- reverted this change: "selected object in Project used to ask twice for UI build" because it will not build the UI when a tab is closed for Document object and the object is selected -- fixed issue after Geometry object edit; the GCode made from an edited object did not reflect the changes in the object -- in Object UI, the Scale FCDoubleSpinner will no longer work for Return key press due of issues of unwanted scaling on focusOut event -- in FlatCAMGeometry fixed the scale and offset methods to always process the self.solid_geometry -- Calibration Tool - finished the calibrated object creation method -- updated the POT file -- fixed an error in the German PO file -- updated the languages PO files -- some fixes on the app.jump_to() method -- made sure that the ToolFilm will not start saving a file if there are no objects loaded -- some fixes on the app.jump_to() method for the Legacy(2D) graphic mode - -8.12.2019 - -- Calibrate Tool - rearranged the GUI -- in Geometry UI made sure that the Label that points to the Tool parameters show clearly that those parameters apply only for the selected tool -- fixed an small issue in Object UI -- small fixes: selected object in Project used to ask twice for UI build; if scale factor in Object UI is 1 do nothing as there is no point in scaling with a factor of 1 -- in Geometry UI added a button that allow updating all the tools in the Tool Table with the current values in the UI form -- updated Tcl commands to make use of either 0 or False for False value or 1 or True for True in case of a parameter with type Bool - -7.12.2019 - -- renamed Calibrate Excellon Tool to a simpler Calibrate Tool -- Calibrate Tool - when generating verification GCode it will always load into an Editor from which it can be edited and/or saved. On save the editor will close. -- updated the CNCJob and Drillcncjob Tcl Commands to use 0 and 1 as values for the parameters that are stated as of bool type, beside the normal keywords of False and True -- Calibrate Tool - working on it - -6.12.2019 - -- fixed the toggle_units() method so now the grid values are accurate to the decimal -- cleaned up the Excellon parser and fixed some bugs (old and new); Excellon parser has it's own convert_units() method no longer inheriting from Geometry -- in Excellon UI fixed bug that did not allow editing of the Offset Z parameter from the Tool table -- in Properties Tool added new information's for the tools in the CNCjob objects -- few bugs solved regarding the newly created empty objects -- changed everywhere the name "preprocessor" with "preprocessor" -- updated the preprocessor files in the toolchange section in order to avoid a graphical representation of travel lines glitch -- fixed a GUI glitch in the Excellon tool table -- added units to some of the parameters in the Properties Tool - -5.12.2019 - -- in NCC Tool, the new Geometry object that is created on copper clear now has the solid_geometry attribute where the geometry is stored not only in the obj.tools attribute -- Copper Thieving Tool - added units label for the pattern plated area -- Properties Tool - added a new parameter, the copper area which show the area of the copper features for the Gerber objects -- Copper Thieving Tool - added a default value for the mask clearance when generating pattern plating mask -- application wide change: introduced the precision parameters in Edit -> Preferences who will control how many decimals to use in the app parameters -- changed the FCDoubleSpinner, FCSpinner and FCEntry GUI elements to allow passing an alignment value: left, right or center (not yet available in the app) -- fixed the GUI of the Geometry Editor Tool Transform and adapted it to use the precision setting -- updated Gerber Editor to use the precision setting and the Gerber Editor Transform Tool to use the FCDoubleSpinner GUI element -- in Properties Tool added more information's regarding the Excellon tools, about travelled distance and job time; fixed issues when doing Properties on the CNCjob objects -- TODO: I need to solve the mess in units conversion: it's too convoluted - -4.12.2019 - -- made sure that if an older preferences file is detected then there are no errors and only the parameters that are currently active are loaded; the factory defaults file is deleted and recreated in the new format -- in Preferences added a new button: 'Close' to close the Preferences window without saving -- fixed bug in FCSpinner and FCDoubleSpinner GUI elements, that are now the main GUI element in FlatCAM, that made partial selection difficult -- updated the Paint Tool in Geometry Editor to use the FCDoubleSpinner -- added the possibility for suffix presence on the FCSpinner and FCDoubleSpinner GUI Elements -- added the '%' symbol for overlap fields; I still need to divide the content by 100 to get the original (0 ... 1) value -- fixed the overlap parameter all over the app to reflect the change to percentage -- in Copper Thieving Tool added the display of the patterned plated area (approximate area) -- Copper Thieving Tool - updated the way plated area is calculated making it a bit more precise but still it is a bit bigger than the actual area -- fixed the Copy Object function to copy also the source_file content -- Copper Thieving Tool - when the clearance value for the pattern plating mask is negative it will be applied to the origin soldermask too -- modified the GUI in all tools making the text of the buttons bold and adding a new button named Reset Tool which have to reset the tool GUI and variables (need to check all tools to see if happen) -- when the Tool tab is in focus, clicking on canvas will no longer change the focus to Project tab -- Copper Thieving Tool - when creating the pattern platting mask will make a new Gerber object with it -- small fix in the GUI layout in Gerber Editor - -3.12.2019 - -- in Preferences added an Apply button which apply the modified preferences but does not save to a file, minimizing the file IO operations; Ctrl+S key combo does the Apply now. -- updated some of the default values to metric, values that were missed previously -- remade the Gerber Editor way to import an Gerber object into the editor in such a way to use the multiprocessing -- various small fixes -- fix for toggle grid lines updating canvas only after moving the mouse (hack, actually) -- some changes in the UI layout in Cutout Tool -- added some geometry parameters in Cutout Tool as a convenience, to be passed to the generated Geometry objects - -2.12.2019 - -- fixed issue #343; updated the Image Tool -- improvements in Importing SVG as Gerber - added an automatic source generation (it is not infallible) -- a hack to import correctly the QRCode exported as SVG from FlatCAM -- added 3 new tcl commands: export dxf, export excellon and export gerber -- added a Cancel button in Tools DB when requesting to add a tool in the Geometry Tool Table -- modified the default values for the METRIC system; the app now starts in the METRIC units since the majority of the world use the METRIC units system -- small changes, updated the estimated release date -- Tool Copper Thieving - added pattern plating mask generation feature - -28.11.2019 - -- small fixes in NCC Tool and in the FlatCAMGeometry class - -27.11.2019 - -- in Tool Film added the page size and page orientation in case of saving the film as PDF file -- the application workspace has now a lot more options selectable in the Edit -> Preferences -> General -> GUI Preferences -- updated the drawing of the workspace such that the application overall start time is improved and after first turn on of the workspace, toggling it will have no performance penalty -- updated the workspace functions to work in Legacy(2D) graphic mode -- adjusted the selection color transparency for the Legacy(2D) graphic mode because it was too transparent for the fill - -26.11.2019 - -- updated the Film Tool to allow exporting PDF and PNG file (besides the SVG file) - -25.11.2019 - -- In Gerber isolation changed the UI -- in Gerber isolation added the option to selectively isolate only certain polygons -- made some optimizations in FlatCAMGerber.isolate() method -- updated the 'single' isolation of Gerber polygons to remove the polygon if clicked on it and it is already in the list of single polygons to be isolated -- clicking to add a polygon when doing Single type isolation will add a blue shape marking the selected polygon, second click will remove that shape -- fixed bugs in Paint Tool when painting single polygon -- in Gerber isolation added the option to selectively isolate only certain polygons - made it to work for Legacy(2D) graphic mode -- remade the Paint Tool - single polygon painting; now it can single paint a list of polygons that are clicked onto (right click will start the actual painting) - -23.11.2019 - -- in Tool Fiducials added a new fiducial type: chess pattern -- work in Calibrate Excellon Tool -- fixed the line numbers in the TextPlainEdit to fit all digits of the line number; activated the line numbers for FlatCAMScript objects too -- line numbers in the TextPlainEdit for the selected line are bold -- made sure that the self.defaults dictionary is deepcopy-ed in the self.options dictionary -- made sure that the units are read from the self.defaults and not from the GUI -- added Robber Bar option to Copper Thieving Tool - -22.11.2019 - -- Tool Fiducials - added GUI in Preferences and entries in self.defaults dict -- Tool Fiducials - updated the source_file object for the modified Gerber files -- working on adding line numbers to the TextPlainEdit -- GCode view now has line numbers -- solved a bug that made selection of objects on canvas impossible if there is an object of type FlatCAMScript or FlatCAMDocument opened - -21.11.2019 - -- Tool Fiducials - finished the part with adding copper fiducials: manual and auto -- Tool Fiducials - added choice of shapes: circular or non-standard cross -- Tool Fiducials - finished the work on adding soldermask openings -- Tool Fiducials - finished the tool -- updated requirements.txt and setup_ubuntu.sh files - -20.11.2019 - -- Tool Fiducials - added the GUI and the shortcut key -- Tool Fiducials - updated the icon - -19.11.2019 - -- removed the f-strings replacing them with the traditional string formatting due of not being supported by older versions of Python 3 -- fixed some TclCommands: MillDrills and OpenGerber -- fixed bug in Tool Subtract that did not allow subtracting Gerber objects -- starting to work on Tool Fiducials - created the file - -18.11.2019 - -- finished the Dots and Squares options in the Copper Thieving Tool -- working on the Lines option in Copper Thieving Tool -- finished the Lines option in the Copper Thieving Tool; still have to add threading to maximize performance -- finished Copper Thieving Tool improvements -- working on the Calibrate Excellon Tool - remade the UI - -17.11.2019 - -- optimized the storage of the Gerber mark shapes by making them one layer only -- optimized the Distance Tool such that the distance utility geometry will be shown even when the mark shapes are plotted. -- updated the make_freezed.py file to make sure that all the required files are included -- updated the setup_ubuntu.sh to include the sudo command (courtesy of Krishna Torque on bitbucket) - -16.11.2019 - -- fixed issue #341 that affected both preprocessors that have inlined feedrate: marlin and repetier. The used feedrate was the Feedrate X-Y and instead had to be Feedrate Z. - -15.11.2019 - -- added all the recognized extensions to the save dialog filters; latest extension used will be preselected next time a save operation occur -- fixed issue #335. The FCDoubleSPinBox (and FCSpinBox) value was not used when the user entered data but just hovered away the mouse expecting the data to be already confirmed -- converted setup_ubuntu.sh to Linux line endings - -14.11.2019 - -- made sure that the 'default' preprocessor file is always loaded first such that this name is always first in the GUI comboboxes -- added a class in GUIElements for a TextEdit box with line numbers and highlight - -13.11.2019 - -- trying to improve the performance of View CNC Code command by using QPlainTextEdit; made the mods for it -- when using the Find function in the TextEditor and the result reach the bottom of the document, the next find will be the first in the document (before it defaulted to the beginning of the document) -- finished improving the show of text files in FlatCAM (CNC Code, Source files) -- fixed an issue in the FlatCAMObj.FlatCAMGerber.convert_units() which needed to be updated after changes elsewhere - -12.11.2019 - -- added two new preprocessor files for ISEL CNC and for BERTA CNC -- clicking on a FCTable GUI element empty space will also clear the focus now - -11.11.2019 - -- in Tools Database added a contextual menu to add/copy/delete tool; Ctrl+C, DEL keys work too; key T for adding a tool is now only partially working -- in Tools Database made the status bar messages show when adding/copying/deleting tools in DB -- changed all Except statements that were single to except Exception as recommended in some PEP -- renamed the Copper Fill Tool to Copper Thieving Tool as this is a more appropriate name; started to add ability for more types of copper thieving besides solid -- fixed some issues recently introduced in ParseSVG -- updated POT file -- fixed GUI in 2Sided Tool -- extending the Copper Thieving Tool - wip - -9.11.2019 - -- fixed a new bug that did not allow to open the FlatCAM Preferences files by doubleclick in Windows -- added a new feature: Tools Database for Geometry objects; resolved issue #308 -- added tooltips for the Tools Database table headers and buttons - -8.11.2019 - -- updated the make file for frozen executable - -7.11.2019 - -- added the '.ngc' file extension to the GCode Save file dialog filter -- made the 'M2' Gcode command footer optional, default is False (can be set using the TclCommand: set_sys cncjob_footer True) -- added a setting in Preferences to force the GCode output to have the Windows line-endings even for non-Windows OS's - -6.11.2019 - -- the "CRTL+S" key combo when the Preferences Tab is in focus will save the Preferences instead of saving the Project -- fixed bug in the Paint Tool that did not allow choosing a Paint Method that was not Standard -- made sure that in the FlatCAMGeometry.merge() all the source data is deepcopy-ed in the final object -- the font color of the Preferences tab will change to red if settings are not saved and it will revert to default when saved -- fixed issue #333. The Geometry Editor Paint tool was not working and using it resulted in an error - -5.11.2019 - -- added a new setting named 'Allow Machinist Unsafe Settings' that will allow the Travel Z and Cut Z to take both positive and negative values -- fixed some issues when editing a multigeo geometry - -4.11.2019 - -- wip -- getting rid of all the Options GUI and related functions as it is no longer supported -- updated the UI in Geometry UI -- optimized the order of the defaults storage declaration and the update of the Preferences GUI from the defaults -- started to add a Tool Database - -3.11.2019 - -- fixed the V-shape tool diameter calculation in NCC Tool -- in NCC Tool made the new tool dia (circular type) a parameter in Preferences -- fixed a small issue with clicking in a disabled FCDoubleSpinner or FCSpinner still doing a selection - -30.10.2019 - -- converted SolderPaste Tool to usage of SpinBoxes; changed the SolderPaste Tool UI in Preferences too -- fixed a bug in SolderPaste Tool that did not allow to view the GCode - -29.10.2019 - -- a bug fix in Geometry Object -- fixed some missing properties in Tool Calculators - -28.10.2019 - -- in Tools: Paint, NCC and Copper Fill, when using the Area Selection, now the selected areas will stay drawn as markers until the user click RMB -- in legacy2D graphic engine, adding an utility geometry no longer draw the older ones, overwriting them -- fixed some issues in the Gerber Editor (Aperture add was double adding an aperture) -- converted Gerber Editor to usage of SpinBoxes -- working on the Calibrate Excellon Tool -- converted Excellon Editor to usage of SpinBoxes -- Calibrate Excellon Tool: working on self.calculate_factors() method - -27.10.2019 - -- Copper Fill Tool: some PEP8 corrections - -26.10.2019 - -- fixed an error in the FCDoubleSpinner class when FlatCAM is run on system with locale that use the comma as decimal separator - -25.10.2019 - -- QRCode Tool: added ability to add negative QRCodes (perhaps they can be isolated on copper?); added a clear area surrounding the QRCode in case it is dropped on a copper pour (region); fixed the Gerber export -- QRCode Tool: all parameters are hard-coded for now -- small update -- fixed imports in all TclCommands -- fixed the requirements.txt and setup_ubuntu.sh files -- QRCode Tool: change the plot method parameter -- QRCode Tool: added ability to save the generated QRCode as SVG file or PNG file -- QRCode Tool: added the feature to save the PNG file with transparent background -- QRCode Tool: added GUI category in Preferences window -- QRCode Tool: shortcut key for this tool is now Alt+Q while PDF import Tool was relegated to Ctrl+Q combo key shortcut -- added a new FlatCAM Tool: Copper Fill Tool. It will pour copper into a Gerber filling all empty space with copper, at a clearance distance of the Gerber features -- Copper Fill Tool: added possibility to select between a bounding box rectangular or convex hull when the reference is the geometry of the source Gerber object -- Copper Fill Tool: cleanup on not regular tool exit -- Copper Fill Tool: added GUI category in Edit -> Preferences window -- QRCode Tool: added a selection limit parameter to control the selection shape vs utility geo - -24.10.2019 - -- added some placeholder texts in the TextBoxes. -- working on QRCode Tool; added the utility geometry and initial functional layout -- working on QRCode Tool; finished adding the QRCode geometry to the selected Gerber object and also finished adding the 'follow' geometry needed when exporting the Gerber object as a Gerber file in addition to the 'solid' geometry in the obj.apertures -- working on QRCode Tool; finished offsetting the geometry both in apertures and in solid_geometry; updated the source_file of the source object - -23.10.2019 - -- QRCode Tool - a SVG object is generated and plotted on screen having the QRCode data -- fixed an import error in Distance Tool -- fixed the Toggle Grid Lines functionality - -22.10.2019 - -- working on the Calibrate Excellon Tool -- finished the GUI layout for the Calibrate Excellon Tool -- start working on QRCode Tool - not working yet -- start working on QRCode Tool - searching for alternatives - -21.10.2019 - -- the context menu for the Tabs in notebook and PlotTabArea is launched now on right mouse click on tabs themselves -- fixed an error when trying to view the source file and there is no object selected -- updated the Objects menu signals so whenever an object is (de)selected in the Project Tab, it's state will reflect the (un)checked state of the actions in the Object menu -- fixed issue in Gerber Object UI of not updating the value of CutZ entry on TipDia or TipAngle entries change. Fixed issue #324 - -18.10.2019 - -- fixed a small bug in BETA status change -- updated the About FlatCAM window -- reverted change in tool dia being able to take only positive values in Gerber Object UI -- started to work to a new tool: Calibrate Excellon Tool -- solved the issue #329 - -18.10.2019 - -- finished the update on the Google translated Spanish translation. -- updated the new objects icons for Gerber, Geometry and Excellon -- small import problem fixed -- RELEASE 8.98 - -17.10.2019 - -- fixed a bug in milling holes due of a message wrongly formatted -- added an translator email address -- finished the update on German Google translation. Part of it was corrected by Jens Karstedt -- finished the update of the Romanian translation. -- finished the Objects menu by adding the ability of actions to be checked so they will show the selected status of the objects and by adding to actions to (de)select all objects -- fixed and optimized the click selection on canvas -- fixed Gerber parsing for very simple Gerber files that have only one Polygon but many LPC zones -- fixed SVG export; fix bug #327 -- finished the update on French Google translation. - -16.10.2019 - -- small update to Romanian translation files - -15.10.2019 - -- adjusted the layout in NCC Tool -- fixed bug in Panelization Tool for which in case of Excellon objects, the panel kept a reference to the source object which created issues when moving or disabling/enabling the plots -- cleaned up the module imports throughout the app (the TclCommands are not yet verified) -- removed the styling on the comboboxes cellWidget's in the Tool Tables -- replaced some of the icons that did not looked Ok on the dark theme -- added a new toolbar button for the Copy object functionality -- changed the Panelize tool icon -- corrected some strings - -14.10.2019 - -- modified the result highlight color in Check Rules Tool -- added the Check Rules Tool parameters to the unit conversion list -- converted more of the Preferences entries to FCDoubleSpinner and FCSpinner -- converted all ObjectUI entries to FCDoubleSpinner and FCSpinner -- updated the translation files (~ 89% translation level) -- changed the splash screen as it seems that FlatCAM beta will never be more than beta -- changed some of the signals from returnPressed to editingFinished due of now using the SpinBoxes -- fixed an issue that caused the impossibility to load a GCode file that contained the % symbol even when was loaded in a regular way from the File menu -- re-added the CNC tool diameter entry for the CNCjob object in Selected tab.FCSpinner -- since the CNCjob geometry creation is only useful for graphical purposes and have no impact on the GCode creation I have removed the cascaded union on the GCode geometry therefore speeding up the Gcode display by many factors (perhaps hundreds of times faster) -- added a secondary link in the bookmark manager -- fixed the bookmark manager order of bookmark links; first two links are always protected from deletion or drag-and-drop to other positions -- fixed a whole load of PyQT signal problems generated by recent changes to the usage of SpinBoxes; added a signal returnPressed for the FCSpinner and for FCDoubleSpinner -- fixed issue in Paint Tool where the first added tool was expected to have a float diameter but it was a string -- updated the translation files to the latest state in the app - -13.10.2019 - -- fixed a bug in the Merge functions -- fixed the Export PNG function when using the 2D legacy graphic engine -- added a new capability to toggle the grid lines for both graphic engines: menu link in View and key shortcut combo Alt+G -- changed the grid colors for 3D graphic engine when in Dark mode -- enhanced the Tool Film adding the Film adjustments and added the GUI in Preferences -- set the GUI layout in Preferences for a new category named Tools 2 -- added the Preferences for Check Rules Tool and for Optimal Tool and also updated the Film Tool to use the default settings in Preferences - -12.10.2019 - -- fixed the Gerber Parser convert units unnecessary usage. The only units conversion should be done when creating the new object, after the parsing -- more fixes in Rules Check Tool -- optimized the Move Tool -- added support for key-based panning in 3D graphic engine. Moving the mouse wheel while pressing the CTRL key will pan up-down and while pressing SHIFT key will pan left-right -- fixed a bug in NCC Tool and start trying to make the App responsive while the NCC tool is run in a non-threaded way -- fixed a GUI bug with the QMenuBar recently introduced - -11.10.2019 - -- added a Bookmark Manager and a Bookmark menu in the Help Menu -- added an initial support for rows drag and drop in FCTable in GUIElements; it crashes for CellWidgets for now, if CellWidgetsare in the table rows -- fixed some issues in the Bookmark Manager -- modified the Bookmark manager to be installed as a widget tab in Plot Area; fixed the drag & drop function for the table rows that have CellWidgets inside -- marked in gray color the rows in the Bookmark Manager table that will populate the BookMark menu -- made sure that only one instance of the BookmarkManager class is active at one time - -10.10.2019 - -- fixed Tool Move to work only for objects that are selected but also plotted, therefore disabled objects will not be moved even if selected - -9.10.2019 - -- updated the Rules Check Tool - solved some issues -- made FCDoubleSpinner to use either comma or dot as a decimal separator -- fixed the FCDoubleSpinner to only allow the amount of decimals already set with set_precision() -- fixed ToolPanelize to use FCDoubleSpinner in some places - -8.10.2019 - -- modified the FCSpinner and FCDoubleSpinner GUI elements such that the wheel event will not change the values inside unless there is a focus in the lineedit of the SpinBox -- in Preferences General, Gerber, Geometry, Excellon, CNCJob sections made all the input fields of type SpinBox (where possible) -- updated the Distance Tool utility geometry color to adapt to the dark theme canvas -- Toggle Code Editor now works as expected even when the user is closing the Editor tab and not using the command Toggle Code Editor -- more changes in Preferences GUI, replacing the FCEntries with Spinners -- some small fixes in toggle units conversion -- small GUI changes - -7.10.2019 - -- fixed an conflict in a signal usage that was triggered by Tool SolderPaste when a new project was created -- updated Optimal Tool to display both points coordinates that made a distance (and the minimum) not only the middle point (which is still the place where the jump happen) -- added a dark theme to FlatCAM (only for canvas). The selection is done in Edit -> Preferences -> General -> GUI Settings -- updated the .POT file and worked a bit in the romanian translation -- small changes: reduced the thickness of the axis in 3D mode from 3 pixels to 1 pixel -- made sure that is the text in the source file of a FlatCAMDocument is HTML is loaded as such -- added inverted icons - -6.10.2019 - -- remade the Mark area Tool in Gerber Editor to be able to clear the markings and also to delete the marked polygons (Gerber apertures) -- working in adding to the Optimal Tool the rest of the distances found in the Gerber and the locations associated; added GUI -- added display of the results for the Rules Check Tool in a formatted way -- made the Rules Check Tool document window Read Only -- made Excellon and Gerber classes from camlib into their own files in the flatcamParser folder -- moved the ApertureMacro class from camlib to ParseGerber file -- moved back the ApertureMacro class to camlib for now and made some import changes in the new ParseGerber and ParseExcellon classes -- some changes to the tests - perhaps I will try adding a few tests in the future -- changed the Jump To icon and reverted some changes to the parseGerber and ParseExcellon classes -- updated Tool Optimal with display of all distances (and locations of the middle point between where they happen) found in the Gerber Object - -5.10.2019 - -- remade the Tool Calculators to use the QSpinBox in order to simplify the user interaction and remove possible errors -- remade: Tool Cutout, Tool 2Sided, Tool Image, Panelize Tool, NCC Tool, Paint Tool to use the QSpinBox GUI elements -- optimized the Transformation Tool both in GUI and in functionality and replaced the entries with QSpinBox -- fixed an issue with the tool table context menu in Paint Tool -- made some changes in the GUI in Paint Tool, NCC Tool and SolderPaste Tool -- changed some of the icons; added attributions for icons source in the About FlatCAM window -- added a new tool in the Geometry Editor named Explode which is the opposite of Union Tool: it will explode the polygons into lines - -4.10.2019 - -- updated the Film Tool and added the ability to generate Punched Positive films (holes in the pads) when a Gerber file is the film's source. The punch holes source can be either an Excellon file or the pads center -- optimized Rules Check Tool so it runs faster when doing Copper 2 Copper rule -- small GUI changes in Optimal Tool and in Film Tool -- some PEP8 corrections -- some code annotations to make it easier to navigate in the FlatCAMGUI.py -- fixed exit FullScreen with Escape key -- added a new menu category in the MenuBar named 'Objects'. It will hold the objects found in the Project tab. Useful when working in FullScreen -- disabled a log.debug in ObjectColection.get_by_name() -- added a Toggle Notebook button named 'NB' in the QMenBar which toggle the notebook -- in Gerber isolation section, the tool dia value is updated when changing from Circular to V-shape and reverse -- in Tool Film, when punching holes in a positive film, if the resulting object geometry is the same as the source object geometry, the film will not ge generated -- fixed a bug that when a Gerber object is edited and it has as solid_geometry a single Polygon, saving the result was failing due of len() function not working on a single Polygon -- added the Distance Tool, Distance Min Tool, Jump To and Set Origin functions to the Edit Toolbar - -3.10.2019 - -- previously I've added the initial layout for the FlatCAMDocument object -- added more editing features in the Selected Tab for the FlatCAMDocument object - -2.10.2019 - -- fixed bug in Geometry Editor that did not allow the copy of geometric elements -- created a new class that holds all the Code Editor functionality and integrated as a Editor in FlatCAM, the location is in flatcamEditors folder -- remade all the functions for view_source, scripts and view_code to use the new TextEditor class; now all the Code Editor tabs are being kept alive, before only one could be in an open state -- changed the name of the new object FlatCAMNotes to a more general one FlatCAMDocument -- changed the way a new FlatCAMScript object is made, the method that is processing the Tcl commands when the Run button is clicked is moved to the FlatCAMObj.FlatCAMScript() class -- reused the Multiprocessing Pool declared in the App for the ToolRulesCheck() class -- adapted the Project context menu for the new types of FLatCAM objects -- modified the setup_recent_files to accommodate the new FlatCAM objects -- made sure that when an FlatCAMScript object is deleted, it's associated Tab is closed -- fixed the FlatCMAScript object saving when project is saved (loading a project with this script object is not working yet) -- fixed the FlatCMAScript object when loading it from a project - -1.10.2019 - -- fixed the FCSpinner and FCDoubleSpinner GUI elements to select all on first click and deselect on second click in the Spinbox LineEdit -- for Gerber object in Selected Tab added ability to chose a V-Shape tool and therefore control the isolation better by adjusting the cut width of the isolation in function of the cut depth, tip width of the tool and the tip angle of the tool -- when in Gerber UI is selected the V-Shape tool, all those parameters (tip dia, tip angle, tool_type = 'V' and cut Z) are transferred to the generated Geometry and prefilled in the Geoemtry UI -- added a fix in the Gerber parser to work even when there is no information about zero suppression in the Gerber file -- added new settings in Edit -> Preferences -> Gerber for Gerber Units and Gerber Zeros to be used as defaults in case that those informations are missing from the Gerber file -- added new settings for the Gerber newly introduced feature to isolate with the V-Shape tools (tip dia, tip angle, tool_type and cut Z) in Edit -> Preferences -> Gerber Advanced -- made those settings just added for Gerber, to be updated on object creation -- added the Geo Tolerance parameter to those that are converted from MM to INCH -- added two new FlatCAM objects: FlatCAMScript and FlatCAMNotes - -30.09.2019 - -- modified the Distance Tool such that the number of decimals all over the tool is set in one place by the self.decimals -- added a new tool named Minimum Distance Tool who will calculate the minimum distance between two objects; key shortcut: SHIFT + M -- finished the Minimum Distance Tool in case of using it at the object level (not in Editors) -- completed the Minimum Distance Tool by adding the usage in Editors -- made the Minimum Distance Tool more precise for the Excellon Editor since in the Excellon Editor the holes shape are represented as a cross line but in reality they should be evaluated as circles -- small change in the UI layout for Check Rules Tool by adding a new rule (Check trace size) -- changed a tooltip in Optimal Tool -- in Optimal Tool added display of how frequent that minimum distance is found -- in Tool Distance and Tool Minimal Distance made the entry fields read-only -- in Optimal Tool added the display of the locations where the minimum distance was detected -- added support to use Multi Processing (multi core usage, not simple threading) in Rules Check Tool -- in Rules Check Tool added the functionality for the following rules: Hole Size, Trace Size, Hole to Hole Clearance -- in Rules Check Tool added the functionality for Copper to Copper Clearance -- in Rules Check Tool added the functionality for Copper to Outline Clearance, Silk to Silk Clearance, Silk to Solder Mask Clearance, Silk to Outline Clearance, Minimum Solder Mask Sliver, Minimum Annular Ring -- fixes to cover all possible situations for the Minimum Annular Ring Rule in Rules Check Tool -- some fixes in Rules Check Tool and added a QSignal that is fired at the end of the job - -29.09.2019 - -- work done for the GUI layout of the Rule Check Tool -- setup signals in the Rules Check Tool GUI -- changed the name of the Measurement Tool to Distance Tool. Moved it's location to the Edit Menu -- added Angle parameter which is continuously updated to the Distance Tool - -28.09.2019 - -- changed the icon for Open Script and reused it for the Check Rules Tool -- added a new tool named "Optimal Tool" which will determine the minimum distance between the copper features for a Gerber object, in fact determining the maximum diameter for a isolation tool that can be used for a complete isolation -- fixed the ToolMeasurement geometry not being displayed -- fixed a bug in Excellon Editor that crashed the app when editing the first tool added automatically into a new black Excellon file -- made sure that if the big mouse cursor is selected, the utility geometry in Excellon Editor has a thicker line width (2 pixels now) so it is visible over the geometry of the mouse cursor -- fixed issue #319 where generating a CNCJob from a geometry made with NCC Tool made the app crash; also #328 which is the same -- replaced in FlatCAM Tools and in FLatCAMObj.py and in Editors all references to hardcoded decimals in string formats for tools with a variable declared in the __init__() -- fixed a small bug that made app crash when the splash screen is disabled: it was trying to close it without being open - -27.09.2019 - -- optimized the toggle axis command -- added possibility of using a big mouse cursor or a small mouse cursor. The big mouse cursor is made from 2 infinite lines. This was implemented for both graphic engines -- added ability to change the cursor size when the small mouse cursor is selected in Preferences -> General -- removed the line that remove the spaces from the path parameter in the Tcl commands that open something (Gerber, Gcode, Excellon) -- fixed issue with the old SysTray icon not hidden when the application is restarted programmatically -- if an object is edited but the result is not saved, the app will reload the edited object UI and set the Selected tab as active -- made the mouse cursor (big, small) change in real time for both graphic engines -- started to work on a new FlatCAM tool: Rules Check -- created the GUI for the Rule Check Tool -- if there are (x, y) coordinates in the clipboard, when launching the "Jump to" function, those coordinates will be preloaded in the Dialog box. -- when the combo SHIFT + LMB is executed there is no longer a deselection of objects -- when the "Jump to" function is called, the mouse cursor (if active) will be moved to the new position and the screen position labels will be updated accordingly - - -27.09.2019 - -- RELEASE FlatCAM 8.97 - -26.09.2019 - -- added a Copy All button in the Code Editor, clicking this button will copy all text in the editor to the clipboard -- added a 'Milling Type' radio button in Geometry Editor Preferences to contorl the type of geometry will be generated in the Geo Editor (for conventional milling or for the climb milling) -- added the functionality to allow climb/conventional milling selection for the geometry created in the Geometry Editor -- now any Geometry that is edited in Geometry editor will have coordinates ordered such that the resulting Gcode will allow the selected milling type in the 'Milling Type' radio button in Geometry Editor Preferences (which depends also of the spindle direction) -- some strings update -- French Google-translation at 100% -- German Google-translation update to 100% -- updated the other languages and the .POT file -- changed some strings (that should not have been included for translation) and updated language files and the .POT file -- fixed issue when rebooting from within in cx_freezed state (it issued a startup arg with the path to FlatCAM.exe but that triggered the last sys.exit(2) that I had in the App.args_at_startup()) -- modified the make_win script for the presence of MatPlotLib - -25.09.2019 - -- French translation at 33% -- fixed the 'Jump To' function to work in legacy graphic engine -- in legacy graphic engine fixed the mouse cursor shape when grid snapping is ON, such that it fits with the shape from the OpenGL graphic engine -- in legacy graphic engine fixed the axis toggle -- French Google-translation at 48% - -24.09.2019 - -- fixed the fullscreen method to show the application window in fullscreen wherever the mouse pointer it is therefore on the screen we are working on; before it was showing always on the primary screen -- fixed setup_ubuntu.sh to include the matplotlib package required by the Legacy (2D) graphic engine -- in legacy graphic engine, fixed issue where immediately after changing the mouse cursor snapping the mouse cursor shape was not updated -- in legacy graphic engine, fixed issue where while zooming the mouse cursor shape was not updated -- in legacy graphic engine, fixed issue where immediately after panning finished the mouse cursor shape was not updated -- unfortunately the fix for issue where while zooming the mouse cursor shape was not updated braked something in way that Matplotlib work with PyQt5, therefore I removed it -- fixed a bug in legacy graphic engine: when doing the self.app.collection.delete_all() in new_project an app crash occurred -- implemented the Annotation change in CNCJob Selected Tab for the legacy graphic engine - -23.09.2019 - -- in legacy graphic engine, fixed bug that made the old object disappear when a new object was loaded -- in legacy graphic engine, fixed bug that crashed the app when creating a new project -- in legacy graphic engine, fixed a bug that when deleting an object all objects where deleted -- added a new TclCommand named "set_origin" which will set the origin for all loaded objects to zero if the -auto True argument is used and to a certain x,y location if the format is: set_origin 5,7 -- added a new TclCommand named "bounds" which will return a list of bounds values from a supplied list of objects names. For use in Tcl Scripts -- updated strings in the translations and the .POT file -- added the new keywords to the default keywords list -- fixed the FullScreen option not working for the 3D graphic engine (due bug of Qt5 when OpenGL window is fullscreen) by creating a sort of fullscreen -- added a final fix that allow full coverage of the screen in FullScreen in Windows and still the menus are working -- optimized the Gerber mark shapes display -- fixed a color format bug in Tool Move for 3D engine -- made sure that when the Tool Move is used on a Gerber file with mark shapes active, those mark shapes are deleted before the actual move -- in legacy graphic engine, fixed issue with Delete shortcut key trying to delete twice -- 26% in Google-translated French translation and updated some strings too - -22.09.2019 - -- fixed zoom directions legacy graphic engine (previous commit) -- fixed display of MultiGeo geometries in legacy graphic engine -- fixed Paint tool to work in legacy graphic engine -- fixed CutOut Tool to work in legacy graphic engine -- fixed display of distance labels and code optimizations in ToolPaint and NCC Tool -- adjusted axis at startup for legacy graphic engine plotcanvas -- when the graphic engine is changed in Edit -> Preferences -> General -> App Preferences, the application will restart -- made hover shapes work in legacy graphic engine -- fixed bug in display of the apertures marked in the Aperture table found in the Gerber Selected tab and through this made it to also work with the legacy graphic engine -- fixed annotation in Mark Area Tool in Gerber Editor to work in legacy graphic engine -- fixed the MultiColor plot option Gerber selected tab to work in legacy graphic engine -- documented some methods in the ShapeCollectionLegacy class -- updated the files: setup_ubuntu.sh and requirements.txt -- some strings changed to be easier for translation -- updated the .POT file and the translation files -- updated and corrected the Romanian and Spanish translations -- updated the .PO files for the rest of the translations, they need to be filled in. -- fixed crash when trying to set a workspace in FlatCAM in the Legacy engine 2D mode by disabling this function for the case of 2D mode -- fixed exception when trying to Fit View (shortcut key 'V') with no object loaded, in legacy graphic engine - -21.09.2019 - -- fixed Measuring Tool in legacy graphic engine -- fixed Gerber plotting in legacy graphic engine -- fixed Geometry plotting in legacy graphic engine -- fixed CNCJob and Excellon plotting in legacy graphic engine -- in legacy graphic engine fixed the travel vs cut lines in CNCJob objects -- final fix for key shortcuts with modifier in legacy graphic engine -- refactored some of the code in the legacy graphic engine -- fixed drawing of selection box when dragging mouse on screen and the selection shape drawing on the selected objects -- fixed the moving drawing shape in Tool Move in legacy graphic engine -- fixed moving geometry in Tool Measurement in legacy graphic engine -- fixed Geometry Editor to work in legacy graphic engine -- fixed Excellon Editor to work in legacy graphic engine -- fixed Gerber Editor to work in legacy graphic engine -- fixed NCC tool to work in legacy graphic engine - -20.09.2019 - -- final fix for the --shellvar having spaces within the assigned value; now they are retained -- legacy graphic engine - made the mouse events work (click, release, doubleclick, dragging) -- legacy graphic engine - made the key events work (simple or with modifiers) -- legacy graphic engine - made the mouse cursor work (enabled/disabled, position report); snapping is not moving the cursor yet -- made the mouse cursor snap to the grid when grid snapping is active -- changed the axis color to the one used in the OpenGL graphic engine -- work on ShapeCollectionLegacy -- fixed mouse cursor to work for all objects -- fixed event signals to work in both graphic engines: 2D and 3D - -19.09.2019 - -- made sure that if FlatCAM is registered with a file extension that it does not recognize it will exit -- added some fixes in the the file extension detection -- added some status messages for the Tcl script related methods -- made sure that optionally, when a script is run then it is also loaded into the code editor -- added control over the display of Sys Tray Icon in Edit -> Preferences -> General -> GUI Settings -> Sys Tray Icon checkbox -- updated some of the default values to more reasonable ones -- FlatCAM can be run in HEADLESS mode now. This mode can be selected by using the --headless=1 command line argument or by changing the line headless=False to True in config/configuration.txt file. In this mod the Sys Tray Icon menu will hold only the Run Scrip menu entry and Exit entry. -- added a new TclCommand named quit_flatcam which will ... quit FlatCAM from Tcl Shell or from a script -- fixed the command line argument --shellvar to work when there are spaces in the argument value -- fixed bug in Gerber editor that did not allow to display all shapes after it encountered one shape without 'solid' geometry -- fixed bug in Gerber Editor -> selection area handler where if some of the selected shapes did not had the 'solid' geometry will silently abort selection of further shapes -- added new control in Edit -> Preferences -> General -> Gui Preferences -> Activity Icon. Will select a GIF from a selection, the one used to show that FlatCAM is working. -- changed the script icon to a smaller one in the sys tray menu -- fixed bug with losing the visibility of toolbars if at first startup the user tries to change something in the Preferences before doing a first save of Preferences -- changed a bit the splash PNG file -- moved all the GUI Preferences classes into it's own file flatcamGUI.PreferencesUI.py -- changed the default method for Paint Tool to 'all' - -18.09.2019 - -- added more functionality to the Extension registration with FLatCAM and added to the GUI in Edit -> Preferences -> Utilities -- fixed the parsing of the Manufacturing files when double clicking them and they are registered with FlatCAM -- fixed showing the GUI when some settings (maximized_GUI) are missing from QSettings -- added sys tray menu -- added possibility to edit the custom keywords used by the autocompleter (in Tcl Shell and in the Code Editor). It is done in the Edit -> Preferences -> Utilities -- added a new setting in Edit -> Preferences -> General -> GUI Settings -> Textbox Font which control the font on the Textbox GUI elements -- fixed issue with the sys tray icon not hiding after application close -- added option to run a script from the context menu of the sys tray icon. Changed the color of the sys tray icon to a green one so it will be visible on light and dark themes - -17.09.2019 - -- added more programmers that contributed to FlatCAM over the years, in the "About FlatCAM" -> Programmers window -- fixed issue #315 where a script run with the --shellfile argument crashed the program if it contained a TclCommand New -- added messages in the Splash Screen when running FlatCAM with arguments at startup -- fixed issue #313 where TclCommand drillcncjob is spitting errors in Tcl Shell which should be ignored -- fixed an bug where the pywrapcp name from Google OR-Tools is not defined; fix issue #316 -- if FlatCAM is started with the 'quit' or 'exit' as argument it will close immediately and it will close also another instance of FlatCAM that may be running -- added a new command line parameter for FlatCAM named '--shellvars' which can load a text file with variables for Tcl Shell in the format: one variable assignment per line and looking like: 'a=3' without quotes -- made --shellvars into --shellvar and make it only one list of commands passed to the Tcl. The list is separated by comma but without spaces. The variables are accessed in Tcl with the names shellvar_x where x is the index in the list of command comma separated values -- fixed an issue in the TclShell that generated an exception IndexError which crashed the software -- fixed the --shellvar and --shellfile FlatCAM arguments to work together but the --shellvar has precedence over --shellfile as it is most likely that whatever variable set by --shellvar will be used in the script file run by --shellfile - -16.09.2019 - -- modified the TclCommand New so it will no longer close all tabs when called (it closed the Code Editor tab which may have been holding the code that run) -- fixed the App.on_view_source() method for CNCJob objects: the Gcode will now contain the Prepend and Append code from the Edit -> Preferences -> CNCJob -> CNCJob Options -- added a new parameter named 'muted' for the TclCommands: cncjob, drillcncjob and write_gcode. Setting it as -muted 1 will disable the error reporting in TCL Shell -- some GUI optimizations -- more GUI optimizations related to being part of the Advanced category or not -- added possibility to change the positive SVG exported file color in Tool Film -- fixed some issues recently introduced in the TclCommands CNCJob, DrillCNCJob and write_gcode; changed some parameters names -- fixed issue in the Laser preprocessor where the laser was turned on as soon as the GCode started creating an unwanted cut up until the job start -- added new links in Menu -> Help (Excellon, Gerber specifications and a Report Bug) -- made the splashscreen to be showed on the current monitor on systems with multiple monitors -- added a new entry in Menu -> View -> Redraw All which is doing what the name says: redraw all loaded objects -- fixed issue where in TCl Shell the Windows paths were not understood due of backslash symbol understood as escape symbol instead of path separator -- made sure that in for the TclCommand cncjob and for the drillcncjob if one of the args is stated but no value then the value used will be the default one -- made available the TSA algorithm for drill path optimization when the used OS is 64bit. When used OS is 32bit the only available algorithm is TSA - -15.09.2019 - -- refactored FlatCAMGeometry.mtool_gen_cncjob() method -- fixed the TclCommandCncjob to work for multigeometry Geometry objects; still I had to fix the list of tools parameter, right now I am setting it to an empty list -- update the Tcl Command isolate to be able to isolate exteriors, interiors besides the full isolation, using the iso_type parameter -- fixed issue in ToolPaint that could not allow area painting of a geometry that was a list and not a Geometric element (polygon or MultiPolygon) -- fixed UI showing before the initialization of FlatCAM is finished when the last state of GUI was maximized -- finished updating the TclCommand cncjob to work for multi-geo Geometry objects with the parameters from the args -- fixed the TclCommand cncjob to use the -outname parameter -- added some more keywords in the data_model for auto-completer -- fixed isolate TclCommand to use correctly the -outname parameter -- added possibility to see the GCode when right clicking on the Project tab on a CNCJob object and then clicking View Source -- added a new TclCommand named PlotObjects which will plot a list of FlatCAM objects -- made that after opening an object in FlatCAM it is not automatically plotted. If the user wants to plot it can use the TclCommands PlotAll or PlotObjects -- modified the TclCommands so that open files do not plot the opened files automatically -- made all TclCommands not to be plotted automatically -- made sure that all TclCommands are not threaded -- added new TclCommands: NewExcellon, NewGerber -- fixed the TclCommand open_project -- added the outname parameter (and established an default name when outname not used) for the AlignDrillGrid and AlignDrill TclCommands -- fixed Scripts repeating multiple time when the Code Editor is used. This repetition was correlated with multiple openings of the Code Editor window (especially after an error) -- added the autocomplete keywords that can be changed to the defaults dictionary - -14.09.2019 - -- more string changes -- updated translation files -- fixed a small bug -- minor changes in the Code Editor GUI -- minor changes in the 'FlatCAM About' GUI -- added a new shortcut key F5 for doing the 'Plot All' -- updated the google-translated Spanish translation strings -- fixed the layouts to include toolbars breaks where it was needed -- whenever the user changes the Excellon format values for loading files, the Export Excellon Format values will be updated -- made optional the behavior of Excellon Export values following the values in the Excellon Loading section -- updated the translations (except RU) and the POT file -- added to the NonCopperClear.clear_copper() a parameter to be able to run it non-threaded - -13.09.2019 - -- added control for simplification when loading a Gerber file in Preferences -> Gerber -> Gerber General -> Simplify -- added some messages for the Edit -> Conversions -> Join methods() to make sure that there are at least 2 objects selected for join -- added a grid layout in on_about() -- upgraded the Script Editor to be able to run Tcl commands in batches -- added some ToolTips for the buttons in the Code Editor -- converted the big strings that hold the shortcut keys descriptions to smaller string to make translations easier -- fixed some of the strings that were left in the old way -- updated the POT file -- updated Romanian language partially -- added a new way to handle scripts with repeating Tcl commands -- added new buttons in the Tools toolbar for running, opening and adding new scripts -- finished the Romanian translation update and updated the POT file - -12.09.2019 - -- small changes in the TclCommands: MillDrills, MillSlots, DrillCNCJob: the new parameter for tolerance is now named: diatol -- cleaned up the 'About FlatCAM' window, started to give credits for the translation team -- started to add an application splash screen -- now, Excellon and Gerber edited objects will have the source_code updated and ready to be saved -- the edited Gerber (or Excellon) object now is kept in the app after editing and the edited object is a new object -- added a message to the splash screen -- remade the splash screen to show multiple messages on app initialization -- added a new splash image -- added a control in Preferences -> General -> GUI Settings -> Splash Screen that control if the splash screen is shown at startup - -11.09.2019 - -- added the Gerber code as source for the panelized object in Panelize Tool -- whenever a Gerber file is deleted, the mark_shapes objects are deleted also -- made faster the Gerber parser for the case of having a not valid geometry when loading a Gerber file without buffering -- updated code in self.on_view_source() to make it more responsive -- fixed the TclCommand MillHoles -- changed the name of TclCommand MillHoles to MillDrills and added a new TclCommand named MillSlots -- modified the MillDrills and MillSlots TclCommands to accept as parameter a list of tool diameters to be milled instead of tool indexes -- fixed issue #302 where a copied object lost all the tools -- modified the TclCommand DrillCncJob to have as parameter a list of tool diameters to be drilled instead of tool indexes -- updated the Spanish translation (Google-translation) -- added a new parameter in the TclCommands: DrillCNCJob, MillDrills, MillSlots named tol (from tolerance). If the diameters of the milled (drilled) dias are within the tolerance specified of the diameters in the Excellon object than those diameters will be processed. This is to help account for rounding errors when having units conversion - -10.09.2019 - -- made isolation threaded -- fixed a small typo in TclCommandCopperCLear -- made changing the Plot kind in CNCJob selected tab, threaded -- fixed an object used before declaring it in NCC Tool - Area option -- added progress for the generation of Isolation geometry -- added progress and possibility of graceful exit in Panel Tool -- added graceful exit possibility when creating Isolation -- changed the workers thread priority back to Normal -- when disabling plots, if the selection shape is visible, it will be deleted -- small changes in Tool Panel (eliminating some deepcopy() calls) -- made sure that all the progress counters count to 100% - -9.09.2019 - -- changed the triangulation type in VisPyVisuals for ShapeCollectionVisual class -- added a setting in Preferences -> Gerber -> Gerber General named Buffering. If set to 'no' the Gerber objects load a lot more faster (perhaps 10 times faster than when set to 'full') but the visual look is not so great as all the aperture polygons can be seen -- added for NCC Tool and Paint Tool a setting in the Preferences -> Tools --> (NCC Tool/ Paint Tool) that can set a progressive plotting (plot shapes as they are processed) -- some fixes in Paint Tool when done over the Gerber objects in case that the progressive plotting is selected -- some fixes in Gerber isolation in case that the progressive plotting is selected; added a 'Buffer solid geometry' button shown only when progressive plotting for Gerber object is selected. It will buffer the entire geometry of the object and plot it, in a threaded way. -- modified FlatCAMObj.py file to the new string format that will allow easier translations -- modified camlib.py, FlatCAMAPp.py and ObjectCollection.py files to the new string format that will allow easier translations -- updated the POT file and the German language -- fixed issue when loading unbuffered a Gerber file that has negative regions -- fixed Panelize Tool to save the aperture geometries into the panel apertures. Also made the tool faster by removing the buffering at the end of the job -- modified FlatCAMEditor's files to the new string format that will allow easier translations -- updated POT file and the Romanian translation - -8.09.2019 - -- added some documentation strings for methods in FlatCAMApp.App class -- removed some @pyqtSlot() decorators as they interfere with the current way the program works - -7.09.2019 - -- added a method to gracefully exit from threaded tasks and implemented it for the NCC Tool and for the Paint Tool -- modified the on_about() function to reflect the reality in 2019 - FlatCAM it is an Open Source contributed software -- remade the handlers for the Enable/Disable Project Tree context menu so they are threaded and activity is shown in the lower right corner of the main window -- added to GUI new options for the Gerber object related to area subtraction -- added new feature in the Gerber object isolation allowing for the isolation to avoid an area defined by another object (Gerber or Geometry) -- all transformation functions show now the progress (rotate, mirror, scale, offset, skew) -- made threaded the Offset and Scale operations found in the Selected tab of the object -- corrected some issues and made Move Tool to show correctly when it is plotting and when it is offsetting the objects position -- made Set Origin feature, threaded -- updated German language translation files -- separated the Plotting thread from the transformations threads - -6.09.2019 - -- remade visibility threaded -- reimplemented the thread listening for new FlatCAM process starting with args so it is no longer subclassed but using the moveToThread function -- added percentage display for work done in NCC Tool -- added percentage display for work done in Paint Tool -- some fixes and prepared the activity monitor area to receive updated texts -- added progress display in status bar for generating CNCJob from Excellon objects -- added progress display in status bar for generating CNCJob from Geometry objects -- modified all the FlatCAM tools strings to the new format in which the status is no longer included in the translated strings to make it easier for the future translations -- more customization for the progress display in case of NCC Tool, Paint Tool and for the Gcode generation -- updated POT file with the new strings -- made the objects offset (therefore the Move Tool) show progress display - -5.09.2019 - -- fixed issue with loading files at start-up -- fixed issue with generating bounding box geometry for CNCJob objects -- added some more infobar messages and log.debug -- increased the priority for the worker tasks -- hidden the configuration for G91 coordinates due of deciding to leave this development for another time; it require too much refactoring -- added some messages for the G-code generation so the user know in which stage the process is - -4.09.2019 - -- started to work on support for G91 in Gcode (relative coordinates) -- added support for G91 coordinates -- working in plotting the CNCjob generated with G91 coordinates - -3.09.2019 - -- in NCC tool there is now a depth of cut parameter named 'Cut Z' which will dictate how deep the tool will enter into the PCB material -- in NCC tool added possibility to choose between the type of tools to be used and when V-shape is used then the tool diameter is calculated from the desired depth of cut and from the V-tip parameters -- small changes in NCC tool regarding the usage of the V-shape tool -- fixed the isolation distance in NCC Tool for the tools with iso_op type -- in NCC Tool now the Area adding is continuous until RMB is clicked (no key modifier is needed anymore) -- fixed German language translation -- in NCC Tool added a warning in case there are isolation tools and if those isolation's are interrupted by an area or a box -- in Paint Tool made that the area selection is repeated until RMB click -- in Paint Tool and NCC Tool fixed the RMB click detection when Area selection is used -- finished the work on file extensions registration with FlatCAM. If the file extensions are deleted in the Preferences -> File Associations then those extensions are unregistered with FlatCAM -- fixed bug in NCC Tools and in SolderPaste Tool if in Edit -> Preferences only one tool is entered -- fixed bug in camblib.clear_polygon3() which caused that some copper clearing / paintings were not complete (some polygons were not processed) when the Straight Lines method was used -- some changes in NCC Tools regarding of the clearing itself - -2.09.2019 - -- fixed issue in NCC Tool when using area option -- added formatting for some strings in the app strings, making the future translations easier -- made changes in the Excellon Tools Table to make it more clear that the tools are selected in the # column and not in the Plot column -- in Excellon and Gerber Selected tab made the Plot (mark) columns not selectable -- some ToolTips were modified -- in Properties Tool made threaded the calculation of convex_hull area and also made it to work for multi-geo objects -- in NCC tool the type of tool that is used is transferred to the Geometry object -- in NCC tool the type of isolation done with the tools selected as isolation tools can now be selected and it has also an Edit -> Preferences entry -- in Properties Tool fixed the dimensions calculations (length, width, area) to work for multi-geo objects - -1.09.2019 - -- fixed open handlers -- fixed issue in NCC Tool where the tool table context menu could be installed multiple times -- added new ability to create simple isolation's in the NCC Tool -- fixed an issue when multi depth step is larger than the depth of cut - -27.08.2019 - -- made FlatCAM so that whenever an associated file is double clicked, if there is an opened instance of FlatCAM, the file will be opened in the first instance without launching a new instance of FlatCAM. If FlatCAM is launched again it will spawn a new process (hopefully it will work when freezed). - -26.08.2019 - -- added support for file associations with FlatCAM, for Windows - -25.08.2019 - -- initial add of a new Tcl Command named CopperClear -- remade the NCC Tool in preparation for the newly added TclCommand CopperClear -- finished adding the TclCommandCopperClear that can be called with alias: 'ncc' -- added new capability in NCC Tool when the reference object is of Gerber type and fixed some newly introduced errors -- fixed issue #298. The changes in preprocessors done in Preferences dis not update the object UI layout as it was supposed to. The selection of Marlin postproc. did not unhidden the Feedrate Rapids entry. -- fixed minor issues -- fixed Tcl Command AddPolygon, AddPolyline -- fixed Tcl Command CncJob -- fixed crash due of Properties Tool trying to have a convex hull area on FlatCAMCNCJob objects which is not possible due of their nature -- modified Tcl Command SubtractRectangle -- fixed and modernized the Tcl Command Scale to be able to scale on X axis or on Y axis or on both and having as scale reference either the (0, 0) point or the minimum point of the bounding box or the center of the bounding box. -- fixed and modernized the Tcl Command Skew - -24.08.2019 - -- modified CutOut Tool so now the manual gaps adding will continue until the user is clicking the RMB -- added ability to turn on/off the grid snapping and to jump to a location while in CutOut Tool manual gap adding action -- made PlotCanvas class inherit from VisPy Canvas instead of creating an instance of it (work of JP) -- fixed selection by dragging a selection shape in Geometry Editor -- modified the Paint Tool. Now the Single Polygon and Area/Reference Object painting works with multiple tools too. The tools have to be selected in the Tool Table. -- remade the TclCommand Paint to work in the new configuration of the the app (the painting functions are now in their own tool, Paint Tool) -- fixed a bug in the Properties Tool -- added a new TcL Command named Nregions who generate non-copper regions -- added a new TclCommand named Bbox who generate a bounding box. - -23.08.2019 - -- in Tool Cutout for the manual gaps, right mouse button click will exit from the action of adding gaps -- in Tool Cutout tool I've added the possibility to create a cutout without bridge gaps; added the 'None' option in the Gaps combobox -- in NCC Tool added ability to add multiple zones to clear when Area option is checked and the modifier key is pressed (either CTRL or SHIFT as set in Preferences). Right click of the mouse is an additional way to finish the job. -- fixed a bug in Excellon Editor that made that the selection of drills is always cumulative -- in Paint Tool added ability to add multiple zones to paint when Area option is checked and the modifier key is pressed (either CTRL or SHIFT as set in Preferences). Right click of the mouse is an additional way to finish the job. -- in Paint Tool and NCC Tool, for the Area option, now mouse panning is allowed while adding areas to process -- for all the FlatCAM tools launched from toolbar the behavior is modified: first click it will launch the tool; second click: if the Tool tab has focus it will close the tool but if another tab is selected, the tool will have focus -- modified the NCC Tool and Paint Tool to work multiple times after first launch -- fixed the issue with GUI entries content being deselected on right click in the box in order to copy the value -- some changes in GUI tooltips -- modified the way key modifiers are detected in Gerber Editor Selection class and in Excellon Editor Selection class -- updated the translations -- fixed aperture move in Gerber Editor -- fixed drills/slots move in Excellon Editor -- RELEASE 8.96 - -22.08.2019 - -- added ability to turn ON/OFF the detachable capability of the tabs in Notebook through a context menu activated by right mouse button click on the Notebook header -- added ability to turn ON/OFF the detachable capability of the tabs in Plot Tab Area through a context menu activated by right mouse button click on the Notebook header -- added possibility to turn application portable from the Edit -> Preferences -> General -> App. Preferences -> Portable checkbox -- moved the canvas setup into it's own function and called it in the init() function -- fixed the Buffer Tool in Geometry Editor; made the Buffer entry field a QDoubleSpinner and set the lower limit to zero. -- fixed Tool Cutout so when the target Gerber is a single Polygon then the created manual geometry will follow the shape if shape is freeform -- fixed TclCommandFollow command; an older function name was used who yielded wrong results -- in Tool Cutout for the manual gaps, now the moving geometry that cuts gaps will orient itself to fit the angle of the cutout geometry - -21.08.2019 - -- added feature in Paint Tool allowing the painting to be done on Gerber objects -- added feature in Paint Tool to set how (and if) the tools are sorted -- added Edit -> Preferences GUI entries for the above just added features -- added new entry in Properties Tool which is the calculated Convex Hull Area (should give a more precise area for the irregular shapes than the box area) -- added some more strings in Properties Tool for the translation -- in NCC Tool added area selection feature -- fixed bug in Excellon parser for the Excellon files that do not put the type of zero suppression they use in the file (like DipTrace eCAD) -- fixed some issues introduced in NCC Tool - -20.08.2019 - -- added ability to do copper clearing through NCC Tool on Geometry objects -- replaced the layout from Grid to Form for the Reference objects comboboxes in Paint Tool and in NCC Tool - -19.08.2019 - -- updated the Edit -> Preferences to include also the Gerber Editor complete Preferences -- started to update the app strings to make it easier for future translations -- fixed the POT file and the German translation -- some mods in the Tool Sub -- fixed bug in Tool Sub that created issues when toggling visibility of the plots -- fixed the Spanish, Brazilian Portuguese and Romanian translations - -18.08.2019 - -- made the exported preferences formatted therefore more easily read -- projects at startup don't work in another thread so there is no multithreading if I want to double click an project and to load it -- added messages in the application window title which show the progress in loading a project (which is not thread-safe therefore keeping the app from fully initialize until finished) -- 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 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 so it is not included in the translated string -- updated the translation files for the modified strings (and for the newly added strings) -- added ability to lock toolbars within the context menu that is popped up on any toolbars right mouse click. The value is saved in QSettings and it is persistent between application startup's. - -17.08.2019 - -- added estimated time of routing for the CNCJob and added travelled distance parameter for geometry, too -- fixed error when creating CNCJob due of having the annotations disabled from preferences but the plot2() function from camlib.CNCJob class still performed operations who yielded TypeError exceptions -- coded a more accurate way to estimate the job time in CNCJob, taking into consideration if there is a usage of multi depth which generate more passes -- another fix (final one) for the Exception generated by the annotations set not to show in Preferences -- updated translations and changed version -- fixed installer issue for the x64 version due of the used CX_FREEZE python package which was in unofficial version (obviously not ready to be used) -- fixed bug in Geometry Editor, in disconnect_canvas_event_handlers() where I left some part of code without adding a try - except block which was required -- moved the initialization of the FlatCAM editors after a read of the default values. If I don't do this then only at the first start of the application the Editors are not functional as the Editor objects are most likely destroyed -- fixed bug in FlatCAM editors that caused the shapes to be drawn without resolution when the app units where INCH -- modified the transformation functions in all classes in camlib.py and FlatCAMObj.py to work with empty geometries -- RELEASE 8.95 - -17.08.2019 - -- updated the translations for the new strings -- RELEASE 8.94 - -16.08.2019 - -- working in Excellon Editor to Tool Resize to consider the slots, too -- fixed a weird error that created a crash in the following scenario: create a new excellon, edit it, add some drills/slots, delete it without saving, create a new excellon, try to edit and a crash is issued due of a wrapped C++ error -- fixed bug selection in Excellon editor that caused not to select the corresponding row (tool dia) in the tool table when a selection rectangle selected an even number of geometric elements -- updated the default values to more convenient ones -- remade the enable/disable plots functions to work only where it needs to (no sense in disabling a plot already disabled) -- made sure that if multi depth is choosed when creating GCode then if the multidepth is more than the depth of cut only one cut is made (to the depth of cut) -- each CNCJob object has now it's own text_collection for the annotations which allow for the individual enabling and disabling of the annotations -- added new menu category in File -> Backup with two menu entries that duplicate the functions of the export/import preferences buttons from the bottom of the Preferences window -- in Excellon Editor fixed the display of the number of slots in the Tool Table after the resize done with the Resize tool -- in Excellon Editor -> Resize tool, made sure that when the slot is resized, it's length remain the same, because the tool should influence only the 'thickness' of the slot. Since I don't know anything but the geometry and tool diameters (old and new), this is only an approximation and computationally intensive -- in Excellon Editor -> remade the Tool edit made by editing the diameter values in the Tools Table to work for slots too -- In Excellon Editor -> fixed bug that caused incorrect display of the relative coordinates in the status bar - -15.08.2019 - -- added Edit -> Preferences GUI and storage for the Excellon Editor Add Slots -- added a confirmation message for objects delete and a setting to activate it in Edit -> Preferences -> Global -- merged pull request from Mike Smith which fix an application crash when attempting to open a not-a-FlatCAM-project file as project -- merged pull request from Mike Smith that add support for a new SVG element: -- stored inside FlatCAM app the VisPy data files and at the first start the application will try to copy those files to the APPDATA (roaming) folder in case of running under Windows OS -- created a configuration file in the root/config/configuration.txt with a configuration line for portability. Set portable to True to run the app as portable -- working on the Slots Array in Excellon Editor - building the GUI -- added a failsafe path to the source folder from which to copy the VisPy data -- fixed the GUI for Slot Arrays in Excellon Editor -- finished the Slot Array tool in Excellon Editor -- added the key shortcut handlers for Add Slot and Add Slot Array tools in Excellon Editor -- started to work on the Resize tool for the case of Excellon slots in Excellon Editor -- final fix for the VisPy data files; the defaults files are saved to the Config folder when the app is set to be portable -- added the Slot Type parameter for exporting Excellon in Edit -> Preferences -> Excellon -> Export Excellon. Now the Excellon object can be exported also with drilled slot command G85 -- fixed bug in Excellon export when there are no zero suppression (coordinates with decimals) - -14.08.2019 - -- fixed the loading of Excellon with slots and the saving of edited Excellon object in regard of slots, in Excellon Editor -- fixed the Delete tool, Select tool in Excellon Editor to work for Slots too -- changes in the way the edited Excellon with added slots is saved -- added more icons and cursor in Excellon Editor for Slots related functions -- in Excellon Editor fixed the selection issue which in a certain step created a failure in the Copy and Move tools. -- in Excellon Editor fixed the selection with key modifier pressed -- edited the mouse cursors and saved them without included thumbnail in a bid to remove some CRC warnings made by libpng - -13.08.2019 - -- added new option in ToolSub: the ability to close (or not) the resulting paths when using tool on Geometry objects. Added also a new category in the Edit -> Preferences -> Tools, the Substractor Tool Options -- some PEP8 changes in FlatCAMApp.py -- added new settings in Edit -> Preferences -> General for Notebook Font size (set font size for the items in Project Tree and for text in Selected Tab) and for canvas Axis font size. The values are stored in QSettings. -- updated translations -- fixed a bug in FCDoubleSpinner GUI element -- added a new parameter in NCC tool named offset. If the offset is used then the copper clearing will finish to a set distance of the copper features -- fixed bugs in Geometry Editor -- added protection's against the 'bowtie' geometries for Subtract Tool in Geometry Editor -- added all the tools from Geometry Editor to the the contextual menu -- fixed bug in Add Text Tool in Geometry Editor that gave error when clicking to place text without having text in the box -- added all the tools from Gerber Editor to the the contextual menu -- added the menu entry "Edit" in the Project contextual menu for Gerber objects -- started to work in adding slots and slots array in Excellon Editor -- in FCSlot finished the utility geometry and the GUI for it - -12.08.2019 - -- done regression to solve the bug with multiple passes cutting from the copper features (I should remember not to make mods here) -- if 'combine' is checked in Gerber isolation but there is only one pass, the resulting geometry will still be single geo -- the 'passes' entry was changed to a IntSpinner so it will allow passes to be entered only in range (1, 999) - it will not allow entry of 0 which may create some issues -- improved the FlatCAMGerber.isolate() function to work for geometry in the form of list and also in case that the elements of the list are LinearRings (like when doing the Exterior Isolation) -- in NCC Tool made sure that at each run the old objects are deleted -- fixed bug in camlib.Gerber.parse_lines() Gerber parser where for Allegro Gerber files the Gerber units were incorrectly detected -- improved Mark Area Tool in Gerber Editor such that at each launch the previous markings are deleted - -11.08.2019 - -- small changes regarding the Project Title -- trying to fix reported bugs -- made sure that the annotations are deleted when the object that contain them is deleted -- fixed issue where the annotations for all the CNCJob objects are toggled together whenever the ones for an single object are toggled -- optimizations in GeoEditor -- updated translations - -10.08.2019 - -- added new feature in NCC Tool: now another object can be used as reference for the area extent to be cleared of copper -- fixed issue in the latest feature in NCC Tool: now it works also with reference objects made out of LineStrings (tool 'Path' in Geometry Editor) -- translation files updated for the new strings (Google Translate) -- RELEASE 8.93 - -9.08.2019 - -- added Exception handing for the case when the user is trying to save & overwrite a file already opened in another file -- finished added 'Area' type of Paint in Paint Tool -- fixed bug that created a choppy geometry for CNCJob when working in INCH -- fixed bug that did not asked the user to save the preferences after importing a new set of preferences, after the user is trying to close the Preferences tab window - -7.08.2019 - -- replaced setFixedWidth calls with setMinimumWidth -- recoded the camlib.Geometry.isolation_geometry() function -- started to work on Paint Area in Paint Tool - -6.08.2019 - -- fixed bug that crashed the app after creating a new geometry, if a new object is loaded and the new geometry is deleted and then trying to select the just loaded new object -- made some GUI elements in Edit -> Preferences to have a minimum width as opposed to the previous fixed one -- fixed issue in the isolation function, if the isolation can't be done there will be generated no Geometry object -- some minor UI changes -- strings added and translations updated - -5.08.2019 - -- made sure that if using an negative Gerber isolation diameter, the resulting Geometry object will use a tool with positive diameter -- fixed bug that when isolating a Gerber file made out of a single polygon, an RecursionException was issued together with inability to create tbe isolation -- when applying a new language if there are any changes in the current project, the app will offer to save the project before the reboot - -3.08.2019 - -- added project name to the window title -- fulfilled request: When saving a CNC file, if the file name is changed in the OS window, the new name does appear in the “Selected” (in name) and “Project” tabs (in cnc_job) -- solved bug such that the app is not crashing when some apertures in the Gerber file have no geometry. More than that, now the apertures that have geometry elements are bolded as opposed to the ones without geometry for which the text is unbolded -- merged a pull request with language changes for Russian translate -- updated the other translations - -31.07.2019 - -- changed the order of the menu entries in the FIle -> Open ... -- organized the list of recent files so the Project entries are to the top and separated from the other types of file -- work on identification of changes in Preferences tab -- added categories names for the recent files -- added a detection if any values are changed in the Edit -> Preferences window and on close it will ask the user if he wants to save the changes or not -- created a new menu entry in the File menu named Recent projects that will hold the recent projects and the previous "Recent files" will hold only the previous loaded files -- updated all translations for the new strings -- fixed bug recently introduced that when changing the units in the Edit -> Preferences it did not converted the values -- fixed another bug that when selecting an Excellon object after disabling it it crashed the app -- RELEASE 8.92 - -30.07.2019 - -- fixed bug that crashed the software when trying to edit a GUI value in Geometry selected tab without having a tool in the Tools Table -- fixed bug that crashed the app when trying to add a tool without a tool diameter value -- Spanish Google translation at 77% -- changed the Disable plots menu entry in the context menu, into a Toggle Visibility menu entry -- Spanish Google translation 100% but two strings (big ones) - needs review -- added two more strings to translation strings (due of German language) -- completed the Russian translation using the Google and Yandex translation engines (minus two big strings) - needs review - -28.07.2019 - -- fixed issue with not using the current units in the tool tables after unit conversion -- after unit conversion from Preferences, the default values are automatically saved by the app -- in Basic mode, the tool type column is no longer hidden as it may create issues when using an painted geometry -- some PEP8 clean-up in FlatCAMGui.py -- fixed Panelize Tool to do panelization for multiple passes type of geometry that comes out of the isolation done with multiple passes - -20.07.2019 - -- updated the CutOut tool so it will work on single PCB Gerbers or on PCB panel Gerbers -- updated languages -- 70% progress in Spanish Google translation - -19.07.2019 - -- fixed bug in FlatCAMObj.FlatCAMGeometry.ui_disconnect(); the widgets signals were not disconnected from handlers when required therefore the signals were connected in an exponential way -- some changes in the widgets used in the Selected tab for Geometry object -- some PEP8 cleanup in FlatCAMObj.py -- updated languages -- 60% progress in Spanish Google translation - -17.07.2019 - -- added some more strings to the translatable ones, especially the radio button labels -- updated the .POT file and the available translations -- 51% progress in Spanish Google translation -- version date change - -16.07.2019 - -- PEP8 correction in flatcamTools -- merged the Brazilian-portuguese language from a pull request made by Carlos Stein -- more PEP8 corrections - -15.07.2019 - -- some PEP8 corrections - -13.07.2019 - -- fixed a possible issue in Gerber Object class -- added a new tool in Gerber Editor: Mark Area Tool. It will mark the polygons in a edited Gerber object with areas within a defined range, allowing to delete some of the not necessary copper features -- added new menu links in the Gerber Editor menu for Eraser Tool and Mark Area Tool -- added key shortcuts for Eraser Tool (Ctrl+E) and Mark Area Tool (Alt+A) and updated the shortcuts list - -9.07.2019 - -- some changes in the app.on_togle_units() to make sure we don't try to convert empty parameters which may cause crashes on FlatCAM units change -- updated setup_ubuntu.sh file -- made sure to import certain libraries in some of the FlatCAM files and not to rely on chained imports - -8.07.2019 - -- fixed bug that allowed empty tool in the tools generated in Geometry object -- fixed bug in Tool Cutout that did not allow the transfer of used cutout tool diameter to the cutout geometry object - -5.07.2019 - -- fixed bug in CutOut Tool -- some other bug in CutOut tool fixed - -1.07.2019 - -- Spanish translation at 36% - -28.06.2019 - -- Spanish translation (Google Translate) at 21% - -27.06.2019 - -- added new translation: Spanish. Finished 10% - -23.06.2019 - -- fixes issues with units conversion when the tool diameters are a list of comma separated values (NCC Tool, SolderPaste Tool and Geometry Object) -- fixed a "typo" kind of bug in SolderPaste Tool -- RELEASE 8.919 - -22.06.2019 - -- some GUI layout optimizations in Edit -> Preferences -- added the possibility for multiple tool diameters in the Edit -> Preferences -> Geometry -> Geometry General -> Tool dia separated by comma -- fixed scaling for the multiple tool diameters in Edit -> Preferences -> Geometry -> Geometry General -> Tool dia, for NCC tools more than 2 and for Solderpaste nozzles more than 2 -- fixed bug in CNCJob where the CNC Tools table will show always only 2 decimals for Tool diameters regardless of the current measuring units -- made the tools diameters decimals in case of INCH FlatCAM units to be 4 instead of 3 -- fixed bug in updating Grid values whenever toggling the FlatCAM units and the X, Y Grid values are linked, bugs which caused the Y value to be scaled incorrectly -- set the decimals for Grid values to be set to 6 if the units of FlatCAM is INCH and to set to 4 if FlatCAM units are METRIC -- updated translations -- updated the Russian translation from 51% complete to 69% complete using the Yandex translation engine -- fixed recently introduced bug in milling drills/slots functions -- moved Substract Tool from Menu -> Edit -> Conversions to Menu -> Tool -- fixed bug in Gerber isolation (Geometry expects now a value in string format and not float) -- fixed bug in Paint tool: now it is possible to paint geometry generated by External Isolation (or Internal isolation) -- fixed bug in editing a multigeo Geometry object if previously a tool was deleted -- optimized the toggle of annotations; now there is no need to replot the entire CNCJob object too on toggling of the annotations -- on toggling off the plot visibility the annotations are turned off too -- updated translations; Russian translation at 76% (using Yandex translator engine - needs verification by a native speaker of Russian) - -20.06.2019 - -- fixed Scale and Buffer Tool in Gerber Editor -- fixed Editor Transform Tool in Gerber Editor -- added a message in the status bar when copying coordinates to clipboard with SHIFT + LMB click combo -- languages update - -19.06.2019 - -- milling an Excellon file (holes and/or slots) will now transfer the chosen milling bit diameter to the resulting Geometry object - -17.06.2019 - -- fixed bug where for Geometry objects after a successful object rename done in the Object collection view (Project tab), deselect the object and reselect it and then in the Selected tab the name is not the new one but the old one -- for Geometry objects, adding a new tool to the Tools table after a successful rename will now store the new name in the tool data - -15.06.2019 - -- fixed bug in Gerber parser that made the Gerber files generated by Altium Designer 18 not to be loaded -- fixed bug in Gerber editor - on multiple edits on the same object, the aperture size and dims were continuously multiplied due of the file units not being updated -- restored the FlatCAMObj.visible() to a non-threaded default - -11.06.2019 - -- fixed the Edit -> Conversion -> Join ... functions (merge() functions) -- updated translations -- Russian translate by @camellan is not finished yet -- some PEP8 cleanup in camlib.py -- RELEASE 8.918 - -9.06.2019 - -- updated translations -- fixed the the labels for shortcut keys for zoom in and zoom out both in the Menu links and in the Shortcut list -- made sure the zoom functions use the global_zoom_ratio parameter from App.self.defaults dictionary. -- some PEP8 cleanup - -8.06.2019 - -- make sure that the annotation shapes are deleted on creation of a new project -- added folder for the Russian translation -- made sure that visibility for TextGroup is set only if index is not None in VisPyVisuals.TextGroup.visible() setter - -7.06.2019 - -- fixed bug in ToolCutout where creating a cutout object geometry from another external isolation geometry failed -- fixed bug in cncjob TclCommand where the gcode could not be correctly generated due of missing bounds params in obj.options dict -- fixed a hardcoded tolerance in FlatCAMGeometry.generatecncjob() and in FlatCAMGeometry.mtool_gen_cncjob() to use the parameter from Preferences -- updated translations - -5.06.2019 - -- updated translations -- some layout changes in Edit -> Preferences such that the German translation (longer words than English) to fit correctly -- after editing an parameter the focus is lost so the user knows that something happened - -4.06.2019 - -- PEP8 updates in FlatCAMExcEditor.py -- added the Excellon Editor parameters to the Edit -> Preferences -> Excellon GUI -- fixed a small bug in Excellon Editor -- PEP8 cleanup in FlatCAMGui -- finished adding the Excellon Editor parameters into the app logic and added a selection limit within Excellon Editor just like in the other editors - -3.06.2019 - -- TclCommand Geocutout is now creating a new geometry object when working on a geometry, preserving also the origin object -- added a new parameter in Edit -> Preferences -> CNCJob named Annotation Color; it controls the color of the font used for annotations -- added a new parameter in Edit -> Preferences -> CNCJob named Annotation Size; it controls the size of the font used for annotations -- made visibility change threaded in FlatCAMObj() - -2.06.2019 - -- fixed issue with geometry name not being updated immediately after change while doing geocutout TclCommand -- some changes to enable/disable project context menu entry handlers - -1.06.2019 - -- fixed text annotation for CNC job so there are no overlapping numbers when 2 lines meet on the same point -- fixed issue in CNC job plotting where some of the isolation polygons are painted incorrectly -- fixed issue in CNCJob where the set circle steps is not used - -31.05.2019 - -- added the possibility to display text annotation for the CNC travel lines. The setting is both in Preferences and in the CNC object properties - -30.05.2019 - -- editing a multi geometry will no longer pop-up a Tcl window -- solved issue #292 where a new geometry renamed with many underscores failed to store the name in a saved project -- the name for the saved projects are updated to the current time and not to the time of the app startup -- some PEP8 changes related to comments starting with only one '#' symbol -- more PEP8 cleanup -- solved issue where after the opening of an object the file path is not saved for further open operations - -24.05.2019 - -- added a toggle Grid button to the canvas context menu in the Grids submenu -- added a toggle left panel button to the canvas context menu - -23.05.2019 - -- fixed bug in Gerber editor FCDisk and FCSemiDisc that the resulting geometry was not stored into the '0' aperture where all the solids are stored -- fixed minor issue in Gerber Editor where apertures were included in the saved object even if there was no geometric data for that aperture -- some PEP8 cleanup in FlatCAMApp.py - -22.05.2019 - -- Geo Editor - added a new editor tool, Eraser -- some PEP8 cleanup of the Geo Editor -- fixed some selection issues in the new tool Eraser in Geometry Editor -- updated the translation files -- RELEASE 8.917 - -21.05.2019 - -- added the file extension .ncd to the Excellon file extension list -- solved parsing issue for Excellon files generated by older Eagle versions (v6.x) -- Gerber Editor: finished a new tool: Eraser. It will erase certain parts of Gerber geometries having the shape of a selected shape. - -20.05.2019 - -- more PEP8 changes in Gerber editor -- Gerber Editor - started to work on a new editor tool: Eraser - -19.05.2019 - -- fixed the Circle Steps parameter for both Gerber and Geometry objects not being applied and instead the app internal defaults were used. -- fixed the Tcl command Geocutout issue that gave an error when using the 4 or 8 value for gaps parameter -- made wider the '#' column for Apertures Table for Gerber Object and for Gerber Editor; in this way numbers with 3 digits can be seen -- PEP8 corrections in FlatCAMGrbEditor.py -- added a selection limit parameter for Geometry Editor -- added entries in Edit -> Preferences for the new parameter Selection limit for both the Gerber and Geometry Editors. -- set the buttons in the lower part of the Preferences Window to have a preferred minimum width instead of fixed width -- updated the translation files - -18.05.2019 - -- added a new toggle option in Edit -> Preferences -> General Tab -> App Preferences -> "Open" Behavior. It controls which path is used when opening a new file. If checked the last saved path is used when saving files and the last opened path is used when opening files. If unchecked then the path for the last action (either open or save) is used. -- fixed App.convert_any2gerber to work with the new Gerber apertures data structure -- fixed Tool Sub to work with the new Gerber apertures data structure -- fixed Tool PDF to work with the new Gerber apertures data structure - -17.05.2019 - -- remade the Tool Cutout to work on panels -- remade the Tool Cutout such that on multiple applications on the same object it will yield the same result -- fixed an issue in the remade Cutout Tool where when applied on a single Gerber object, the Freeform Cutout produced no cutout Geometry object -- remade the Properties Tool such that it works with the new Gerber data structure in the obj.apertures. Also changed the view for the Gerber object in Properties -- fixed issue with false warning that the Gerber object has no geometry after an empty Gerber was edited and added geometry elements - -16.05.2019 - -- Gerber Export: made sure that if some of the coordinates in a Gerber object geometry are repeating then the resulting Gerber code include only one copy -- added a new parameter/feature: now the spindle can work in clockwise mode (CW) or counter clockwise mode (CCW) - -15.05.2019 - -- rewrited the Gerber Parser in camlib - success -- moved the self.apertures[aperture]['geometry'] processing for clear_geometry (geometry made with Gerber LPC command) in Gerber Editor -- Gerber Editor: fixed the Poligonize Tool to work with new geometric structure and took care of a special case -- Gerber Export is fixed to work with the new Gerber object data structure and it now works also for Gerber objects edited in Gerber Editor -- Gerber Editor: fixed units conversion for obj.apertures keys that require it -- camlib Gerber parser - made sure that we don't loose goemetry in regions -- Gerber Editor - made sure that for some tools the added geometry is clean (the coordinates are non repeating) -- covered some possible issues in Gerber Export - -12.05.2019 - -- some modifications to ToolCutout - -11.05.2019 - -- fixed issue in camlib.CNCjob.generate_from_excellon_by_tool() in the drill path optimization algorithm selection when selecting the MH algorithm. The new API's for Google OR-tools required some changes and also the time parameter can be now just an integer therefore I modified the GUI -- made the Feedrate Rapids parameter to depend on the type of preprocessor choosed. It will be showed only for a preprocessor which the name contain 'marlin' and for any preprocessor's that have 'custom' in the name -- fixed the camlib.Gerber functions of mirror, scale, offset, skew and rotate to work with the new data structure for apertures geometry -- fixed Gerber Editor selection to work with the new Gerber data structure in self.apertures -- fixed Gerber Editor FCPad class to work with the new Gerber data structure in self.apertures -- fixed camlib.Gerber issues related to what happen after parsing rectangular apertures -- wip in camblib.Gerber -- completely converted the Gerber editor to the new data structure -- Gerber Editor: added a threshold limit for how many elements a move selection can have. If above the threshold only a bounding box Poly will be painted on canvas as utility geometry. - -10.05.2019 - -- Gerber Editor - working in conversion to the new data format -- made sure that only units toggle done in Edit -> Preferences will toggle the data in Preferences. The menu entry Edit -> Toggle Units and the shortcut key 'Q' will change only the display units in the app -- optimized Transform tool -- RELEASE 8.916 - -9.05.2019 - -- reworked the Gerber parser - -8.05.2019 - -- added zoom fit for Set Origin command -- added move action for solid_geometry stored in the gerber_obj.apertures -- fixed camlib.Gerber skew, rotate, offset, mirror functions to work for geometry stored in the Gerber apertures -- fixed Gerber Editor follow_geometry reconstruction -- Geometry Editor: made the tool to be able to continuously move until the tool is exited either by ESC key or by right mouse button click -- Geometry Editor Move Tool: if no shape is selected when triggering this tool, now it is possible to make the selection inside the tool -- Gerber editor Move Tool: fixed a bug that repeated the plotting function unnecessarily -- Gerber editor Move Tool: if no shape is selected the tool will exit - -7.05.2019 - -- remade the Tool Panelize GUI -- work in Gerber Export: finished the header export -- fixed the Gerber Object and Gerber Editor Apertures Table to not show extra rows when there are aperture macros in the object -- work in Gerber Export: finished the body export but have some errors with clear geometry (LPC) -- Gerber Export - finished - -6.05.2019 - -- made units change from shortcut key 'Q' not to affect the preferences -- made units change from Edit -> Toggle Units not to affect the preferences -- remade the way the aperture marks are plotted in Gerber Object -- fixed some bugs related to moving an Gerber object with the aperture table in view -- added a new parameter in the Edit -> Preferences -> App Preferences named Geo Tolerance. This parameter control the level of geometric detail throughout FlatCAM. It directly influence the effect of Circle Steps parameter. -- solved a bug in Excellon Editor that caused app crash when trying to edit a tool in Tool Table due of missing a tool offset -- updated the ToolPanelize tool so the Gerber panel of type FlatCAMGerber can be isolated like any other FlatCAMGerber object -- updated the ToolPanelize tool so it can be edited -- modified the default values for toolchangez and endz parameters so they are now safe in all cases - -5.05.2019 - -- another fix for bug in clear geometry processing for Gerber apertures -- added a protection for the case that the aperture table is part of a deleted object -- in Script Editor added support for auto-add closing parenthesis, brace and bracket -- in Script Editor added support for "CTRL + / " key combo to comment/uncomment line - -4.05.2019 - -- fixed bug in camlib.parse_lines() in the clear_geometry processing section for self.apertures -- fixed bug in parsing Gerber regions (a point was added unnecessary) -- renamed the menu entry Edit -> Copy as Geo to Convert Any to Geo and moved it in the Edit -> Conversion -- created a new function named Convert Any to Gerber and installed it in Edit -> Conversion. It's doing what the name say: it will convert an Geometry or Excellon FlatCAM object to a Gerber object. - -01.05.2019 - -- the project items color is now controlled from Foreground Role in ObjectCollection.data() -- made again plot functions threaded but moved the dataChanged signal (update_view() ) to the main thread by using an already existing signal (plots_updated signal) to avoid the errors with register QVector -- Enable/Disable Object toggle key ("Space" key) will trigger also the datChanged signal for the Project MVC -- added a new setting for the color of the Project items, the color when they are disabled. -- fixed a crash when triggering 'Jump To' menu action (shortcut key 'J' worked ok) -- made some mods to what can be translated as some of the translations interfered with the correct functioning of FlatCAM -- updated the translations -- fixed bugs in Excellon Editor -- Excellon Editor: made Add Pad tool to work until right click -- Excellon Editor: fixed mouse right click was always doing popup context menu -- GUIElements.FCEntry2(): added a try-except clause -- made sure that the Tools Tab is cleared on Editors exit -- Geometry Editor: restored the old behavior: a tool is active until it is voluntarily exited: either by using the 'ESC' key, or selecting the Select tool or new: right click on canvas -- RELEASE 8.915 - -30.04.2019 - -- in ObjectCollection class, made sure that renaming an object in Project View does not result in an empty name. If new name is blank the rename is cancelled. -- made ObjectCollection.TreeItem() inherit KeySensitiveListVIew and implicitly QTreeView (in the hope that the theme applied on app will be applied on the tree items, too (for MacOs new DarkUI theme) -- renamed SilkScreen Tool to Substract Tool and move it's menu location in Edit -> Conversion -- started to modify the Substract Tool to work on Geometry objects too -- progress in the new Substract Tool for Geometry Objects -- finished the new Substract Tool -- added new setting for the color of the Project Tree items; it helps in providing contrast when using dark theme like the one in MacOS - -29.04.2019 - -- solved bug in Gerber Editor: the '0' aperture (the region aperture) had no size which created errors. Made the size to be zero. -- solved bug in editors: the canvas selection shape was not deleted on mouse release if the grid snap was OFF -- solved bug in Excellon Editor: when selecting a drill hole on canvas the selected row in the Tools Table was not the correct one but the next highest row -- finished the Silkscreen Tool but there are some limitations (some wires fragments from silkscreen are lost) -- solved the issue in Silkscreen Tool with losing some fragments of wires from silkscreen - -26.04.2019 - -- small changes in GUI; optimized contextual menu display -- made sure that the Project Tab is disabled while one of the Editors is active and it is restored after returning to app -- fixed some bugs recently introduced in Editors due of the changes done to the way mouse panning is detected -- cleaned up the context menu's when in Editors; made some structural changes -- updated the code in camlib.CNCJob.generate_from_excellon_by_tools() to work with the new API from Google OR-Tools -- all Gerber regions (G36 G37) are stored in the '0' aperture -- fixed a bug that added geometry with clear polarity in the apertures where was not supposed to be - -25.04.2019 - -- Geometry Editor: modified the intersection (if the selected shapes don't intersects preserve them) and substract functions (delete all shapes that were used in the process) -- work in the ToolSub -- for all objects, if in Selected the object name is changed to the same name, the rename is not done (because there is nothing changed) -- fixed Edit -> Copy as Geom function handler to work for Excellon objects, too -- made sure that the mouse pointer is restored to default on Editor exit -- added a toggle button in Preferences to toggle on/off the display of the selection box on canvas when the user is clicking an object or selecting it by mouse dragging. - -24.04.2019 - -- PDF import tool: working in making the PDF layer rendering multithreaded in itself (one layer rendered on each worker) -- PDF import tool: solved a bug in parsing the rectangle subpath (an extra point was added to the subpath creating nonexisting geometry) -- PDF import tool: finished layer rendering multithreading -- New tool: Silkscreen Tool: I am trying to remove the overlapped geo with the soldermask layer from overlay layer; layed out the class and functions - not working yet - -23.04.2019 - -- Gerber Editor: added two new tools: Add Disc and Add SemiDisc (porting of Circle and Arc from Geometry Editor) -- Gerber Editor: made Add Pad repeat until user exits the Add Pad through either mouse right click, or ESC key or deselecting the Add Pad menu item -- Gerber and Geometry Editors: fixed some issues with the Add Arc/Add Semidisc; in mode 132, the norm() function was not the one from numpy but from a FlatCAM Class. Also fixed some of the texts and made sure that when changing the mode, the current points are reset to prepare for the newly selected mode. -- Fixed Measurement Tool to show the mouse coordinates on the status bar (it was broken at some point) -- updated the translation files -- added more custom mouse cursors in Geometry and Gerber Editors -- RELEASE 8.914 - -22.04.2019 - -- added PDF file as type in the Recent File list and capability to load it from there -- PDF's can be drag & dropped on the GUI to be loaded -- PDF import tool: added support for save/restore Graphics stack. Only for scale and offset transformations and for the linewidth. This is the final fix for Microsoft PDF printer who saves in PDF format 1.7 -- PDF Import tool: added support for PDF files that embed multiple Gerber layers (top, bottom, outline, silkscreen etc). Each will be opened in it's own Gerber file. The requirement is that each one is drawn in a different color -- PDF Import tool: fixed bugs when drag & dropping PDF files on canvas the files geometry previously opened was added to the new one. Also scaling issues. Solved. -- PDF Import tool: added support for detection of circular geometry drawn with white color which means actually invisible color. When detected, FlatCAM will build an Excellon file out of those geoms. -- PDF Import tool: fixed storing geometries in apertures with the right size (before they were all stored in aperture D10) - -21.04.2019 - -- fixed the PDF import tool to work with files generated by the Microsoft PDF printer (chained subpaths) -- in PDF import tool added support for paths filled and at the same time stroked ('B' and 'B*'commands) -- added a shortcut key for PDF Import Tool (Alt+Q) and updated the Shortcut list (also with the 'T' and 'R' keys for Gerber Editor where they control the bend in Track and Region tool and the 'M' and 'D' keys for Add Arc tool in Geometry Editor) - -20.04.2019 - -- finished adding the PDF import tool although it does not support all kinds of outputs from PDF printers. Microsoft PDF printer is not supported. - -19.04.2019 - -- started to work on PDF import tool - - -18.04.2019 - -- Gerber Editor: added custom mouse cursors for each mode in Add Track Tool -- Gerber Editor: Poligonize Tool will first fuse polygons that touch each other and at a second try will create a polygon. The polygon will be automatically moved to Aperture '0' (regions). -- Gerber Editor: Region Tool will add regions only in '0' aperture -- Gerber Editor: the bending mode will now survive until the tool is exited -- Gerber Editor: solved some bugs related with deleting an aperture and updating the last_selected_aperture - -17.04.2019 - -- Gerber Editor: added some messages to warn user if no selection exists when trying to do aperture deletion or aperture geometry deletion -- fixed version check -- added custom mouse cursors for some tools in Gerber Editor -- Gerber Editor: added multiple modes to lay a Region: 45-degrees, reverse 45-degrees, 90-degrees, reverse 90-degrees and free-angle. Added also key shortcuts 'T' and 'R' to cycle forward, respectively in reverse through the modes. -- Excellon Editor: fixed issue not remembering last tool after adding a new tool -- added custom mouse cursors for Excellon and Geometry Editors in some of their tools - -16.04.2019 - -- added ability to use ENTER key to finish tool adding in Editors, NCC Tool, Paint Tool and SolderPaste Tool. -- Gerber Editor: started to add modes of laying a track -- Gerber Editor: Add Track Tool: added 5 modes for laying a track: 45-degrees, reverse-45 degrees, 90-degrees, reverse 90-degrees and free angle. Key 'T' will cycle forward through the modes and key 'R' will cycle in reverse through the track laying modes. -- Gerber Editor: Add Track Tool: first right click will finish the track. Second right click will exit the Track Tool and return to Select Tool. -- Gerber Editor: added protections for the Pad Array and Pad Tool for the case when the aperture size is zero (the aperture where to store the regions) - -15.04.2019 - -- working on a new tool to process automatically PcbWizard Excellon files which are generated in 2 files -- finished ToolPcbWizard; it will autodetect the Excellon format, units from the INF file -- Gerber Editor: reduced the delay to show UI when editing an empty Gerber object -- update the order of event handlers connection in Editors to first connect new handlers then disconnect old handlers. It seems that if nothing is connected some VispY functions like canvas panning no longer works if there is at least once nothing connected to the 'mouse_move' event -- Excellon Editor: update so always there is a tool selected even after the Excellon object was just edited; before it always required a click inside of the tool table, not you do it only if needed. -- fixed the menu File -> Edit -> Edit/Close Editor entry to reflect the status of the app (Editor active or not) -- added support in Excellon parser for autodetection of Excellon file format for the Excellon files generated by the following ECAD sw: DipTrace, Eagle, Altium, Sprint Layout -- Gerber Editor: finished a new tool: Poligonize Tool (Alt+N in Editor). It will fuse a selection of tracks into a polygon. It will fill a selection of polygons if they are apart and it will make a single polygon if the selection is overlapped. All the newly created filled polygons will be stored in aperture '0' (if it does not exist it will be automatically created) -- fixed a bug in Move command in context menu who crashed the app when triggered -- Gerber Editor: when adding a new aperture it will be store as the last selected and it will be used for any tools that are triggered until a new aperture is selected. - -14.04.2019 - -- Gerber Editor: Remade the processing of 'clear_geometry' (geometry generated by polygons made with Gerber LPC command) to work if more than one such polygon exists -- Gerber Editor: a disabled/enabled sequence for the VisPy cursor on Gerber edit make the graphics better -- Editors: activated an old function that was no longer active: each tool can have it's own set of shortcut keys, the Editor general shortcut keys that are letters are overridden -- Gerber and Geometry editors, when using the Backspace keys for certain tools, they will backtrack one point but now the utility geometry is immediately updated -- In Geometry Editor I fixed bug in Arc modes. Arc mode shortcut key is now key 'M' and arc direction change shortcut key is 'D' -- moved the key handler out of the Measurement tool to flatcamGUI.FlatCAMGui.keyPressEvent() -- Gerber Editor: started to add new function of poligonize which should make a filled polygon out of a shape -- cleaned up Measuring Tool -- solved bug in Gerber apertures size and dimensions values conversion when file units are different than app units - -13.04.2019 - -- updating the German translation -- Gerber Editor: added ability to change on the fly the aperture after one of the tools: Add Pad or Add Pad Array is activated -- Gerber Editor: if a tool is cancelled via key shortcut ESCAPE, the selection is now deleted and any other action require a new selection -- finished German translation (Google translated with some adjustments) -- final fix for issue #277. Previous fix was applied only for one case out of three. -- RELEASE 8.913 - -12.04.2019 - -- Gerber Editor: added support for Oblong type of aperture -- fixed an issue with automatically filled in aperture code when the edited Gerber file has no apertures; established an default with value 10 (according to Gerber specifications) -- fixed a bug in editing a blank Gerber object -- added handlers for the Gerber Editor context menu -- updated the translation template POT file and the EN PO/MO files -- Gerber Editor: added toggle effect to the Transform Tool -- Gerber Editor: added shortcut for Transform Tool and also toggle effect here, too -- updated the shortcut list with the Gerber Editor shortcut keys -- Gerber Editor: fixed error when adding an aperture with code value lower than the ones that already exists -- when adding an aperture with code '0' (zero) it will automatically be set with size zero and type: 'REG' (from region); here we store all the regions from a Gerber file, the ones without a declared aperture -- Gerber Editor: added support for Gerber polarity change commands (LPD, LPC) -- moved the polarity change processing from FlatCAMGrbEditor() class to camlib.Gerber().parse_lines() -- made optional the saving of an edited object. Now the user can cancel the changes to the object. -- replaced the standard buttons in the QMessageBox's used in the app with custom ones that can have text translated -- updated the POT translation file and the MO/PO files for English and Romanian language - -11.04.2019 - -- changed the color of the marked apertures to the global_selection_color -- Gerber Editor: added Transformation Tool and Rotation key shortcut -- in all Editors, manually deactivating a button in the editor toolbar will automatically select the 'Select' button -- fixed Excellon Editor selection: when a tool is selected in Tools Table, all the drills belonging to that tool are selected. When a drill is selected on canvas, the associated tool will be selected without automatically selecting all other drills with same tool -- Gerber Editor: added Add Pad Array tool -- Gerber Editor: in Add Pad Array tool, if the pad is not circular type, for circular array the pad will be rotated to match the array angle -- Gerber Editor: fixed multiple selection with key modifier such that first click selects, second deselects - -10.04.2019 - -- Gerber Editor: added Add Track and Add Region functions -- Gerber Editor: fixed key shortcuts -- fixed setting the Layout combobox in Preferences according to the current layout -- created menu links and shortcut keys for adding a new empty Gerber objects; on update of the edited Gerber, if the source object was an empty one (new blank one) this source obj will be deleted -- removed the old apertures editing from Gerber Obj selected tab -- Gerber Editor: added Add Pad (circular or rectangular type only) -- Gerber Editor: autoincrement aperture code when adding new apertures -- Gerber Editor: automatically calculate the size of the rectangular aperture - -9.04.2019 - -- Gerber Editor: added buffer and scale tools -- Gerber Editor: working on aperture selection to show on Aperture Table -- Gerber Editor: finished the selection on canvas; should be used as an template for the other Editors -- Gerber Editor: finished the Copy, Aperture Add, Buffer, Scale, Move including the Utility geometry -- Trying to fix bug in Measurement Tool: the mouse events don't disconnect -- fixed above bug in Measurement Tool (but there is a TODO there) - -7.04.2019 - -- default values for Jump To function is jumping to origin (0, 0) - -6.04.2019 - -- fixed bug in Geometry Editor in buffer_int() function that created an Circular Reference Error when applying buffer interior on a geometry. -- fixed issue with not possible to close the app after a project save. -- preliminary Gerber Editor.on_aperture_delete() -- fixed 'circular reference' error when creating the new Gerber file in Gerber Editor -- preliminary Gerber Editor.on_aperture_add() - -5.04.2019 - -- Gerber Editor: made geometry transfer (which is slow) to Editor to be multithreaded -- Gerber Editor: plotting process is showed in the status bar -- increased the number of workers in FlatCAM and made the number of workers customizable from Preferences -- WIP in Gerber Editor: geometry is no longer stored in a Rtree storage as it is not needed -- changed the way delayed plot is working in Gerber Editor to use a Qtimer instead of python threading module -- WIP in Gerber Editor -- fixed bug in saving the maximized state -- fixed bug in applying default language on first start -~~- on activating 'V' key shortcut (zoom fit) the mouse cursor is now jumping to origin (0, 0)~~ -- fixed bug in saving toolbars state; the file was saved before setting the self.defaults['global_toolbar_view] - -4.04.2019 - -- added support for Gerber format specification D (no zero suppression) - PCBWizard Gerber files support -- added support for Excellon file with no info about tool diameters - PCB Wizard Excellon file support -- modified the bogus diameters series for Excellon objects that do not have tool diameter info -- made Excellon Editor aware of the fact that the Excellon object that is edited has fake (bogus) tool diameters and therefore it will not sort the tools based on diameter but based on tool number -- fixed bug on Excellon Editor: when diameter is edited in Tools Table and the target diameter is already in the tool table, the drills from current tool are moved to the new tool (with new dia) - before it crashed -- fixed offset after editing drill diameters in Excellon Editor. - -3.04.2019 - -- fixed plotting in Gerber Editor -- working on GUI in Gerber Editor -- added a Gcode end_command: default is M02 -- modified the calling of the editor2object() slot function to fix an issue with updating geometry imported from SVG file, after edit -- working on Gerber Editor - added the key shortcuts: wip -- made saving of the project file non-blocking and also while saving the project file, if the user tries again to close the app while project file is being saved, the app will close only after saving is complete (the project file size is non zero) -- fixed the camlib.Geometry.import_svg() and camlib.Gerber.bounds() to work when importing SVG files as Gerber - -31.03.2019 - -- fixed issue #281 by making generation of a convex shape for the freeform cutout in Tool Cutout a choice rather than the default -- fixed bug in Tool Cutout, now in manual cutout mode the gap size reflect the value set -- changed Measuring Tool to use the mouse click release instead of mouse click press; also fixed a bug when using the ESC key. -- fixed errors when the File -> New Project is initiated while an Editor is still active. -- the File->Exit action handler is now self.final_save() -- wip in Gerber editor - -29.03.2019 - -- update the TCL keyword list -- fix on the Gerber parser that makes searching for '%%' char optional when doing regex search for mode, units or image polarity. This allow loading Gerber files generated by the ECAD software TCl4.4 -- fix error in plotting Excellon when toggling units -- FlatCAM editors now are separated each in it's own file -- fixed TextTool in Geometry Editor so it will open the notebook on activation and close it after finishing text adding -- started to work on a Gerber Editor -- added a fix in the Excellon parser by allowing a comma in the tool definitions between the diameter and the rest - -28.03.2019 - -- About 45% progress in German translation -- new feature: added ability to edit MultiGeo geometry (geometry from Paint Tool) -- changed all the info messages that are of type warning, error or success so they have a space added after the keyword -- changed the Romanian translation by adding more diacritics -- modified Gerber parser to copy the follow_geometry in the self.apertures -- modified the Properties Tool to show the number of elements in the follow_geometry for each aperture -- modified the copy functions to copy the follow_geometry and also the apertures if it's possible (only for Gerber objects) - -27.03.2019 - -- added new feature: user can delete apertures in Advanced mode and then create a new FlatCAM Gerber object -- progress in German translation. About 27% done. -- fixed issue #278. Crash on name change in the Name field in the Selected Tab. - -26.03.2019 - -- fixed an issue where the Geometry plot function protested that it does not have an parameter that is used by the CNCJob plot function. But both inherit from FaltCAMObj plot function which does not have that parameter so something may need to be changed. Until then I provided a phony keyboard parameter to make that function 'shut up' -- fixed bug: after using Paint Tool shortcut keys are disabled -- added CNCJob geometry for the holes created by the drills from Excellon objects - -25.03.2019 - -- in the TCL completer if the word is already complete don't add it again but add a space -- added all the TCL keywords in the completer keyword list -- work in progress in German translation ~7% -- after any autocomplete in TCL completer, a space is added -- fixed an module import issue in NCC Tool -- minor change (optimization) of the CNCJob UI -- work in progress in German translation ~20% - -22.03.2019 - -- fixed an error that created a situation that when saving a project with some of the CNCJob objects disabled, on project reload the CNCJob objects are no longer loaded -- fixed the Gerber.merge() function. When some of the Gerber files have apertures with same id, create a new aperture id for the object that is fused because each aperture id may hold different geometries. -- changed the autoname for saving Preferences, Project and PNG file - -20.03.2019 - -- added autocomplete finish with ENTER key for the TCL Shell -- made sure that the autocomplete function works only for FlatCAM Scripts -- ESC key will trigger normal view if in full screen and the ESC key is pressed -- added an icon and title text for the Toggle Units QMessageBox - -19.03.2019 - -- added autocomplete for Code editor; -- autocomplete in Code Editor is finished by hitting either TAB key or ENTER key -- fixed the Gerber.merge() to work for the case when one of the merged Gerber objects solid_geometry type is Polygon and not a list - -18.03.2019 - -- added ability to create new scripts and open scripts in FlatCAM Script Editor -- the Code Editor tab name is changed according to the task; 'save' and 'open' buttons will have filters installed for the QOpenDialog fit to the task -- added ability to run a FlatCAM Tcl script by double-clicking on the file -- in Code Editor added shortcut combo key Ctrl+Shift+V to function as a Special Paste that will replace the '\' char with '/' so the Windows paths will be pasted correctly for TCL Shell. Also doing SHIFT + LMB on the Paste in contextual menu is doing the same. - -17.03.2019 - -- remade the layout in 2Sided Tool -- work in progress for translation in Romanian - 91% -- changed some of the app strings formatting to work better with Poedit translation software -- fixed bug in Drillcncjob TclCommand -- finished translation in Romanian -- made the translations work when the app is frozen with CX_freeze -- some formatting changes for the application strings -- some changes on how the first layout is applied -- minor bug fixes (typos from copy/paste from another part of the program) - -16.03.2019 - -- fixed bug in Paint Tool - Single Poly: no geometry was generated -- work in progress for translation in Romanian - 70% - -13.03.2019 - -- made the layout combobox current item from Preferences -> General window to reflect the current layout -- remade the POT translate file -- work in progress in translation for Romanian language 44% -- fix for showing tools by activating them from the Menu - final fix. - -11.03.2019 - -- changed some icons here and there -- fixed the Properties Project menu entry to work on the new way -- in Properties tool now the Gerber apertures show the number of polygons in 'solid_geometry' instead of listing the objects -- added a visual cue in Menu -> Edit about the entries to enter the Editor and to Save & Exit Editor. When one is enabled the other is disabled. -- grouped all the UI files in flatcamGUI folder -- grouped all parser files in flatcamParsers folder -- another changes to the final_save() function -- some strings were left outside the translation formatting - fixed -- finished the replacement of '_' symbols throughout the app which conflicted with the _() function used by the i18n -- reverted changes in Tools regarding the toggle effect - now they work as expected - -10.03.2019 - -- added a fix in the Gerber parser when adding the geometry in the self.apertures dict for the case that the current aperture is None (Allegro does that) -- finished support for internationalization by adding a set of .po/.mo files for the English language. Unfortunately the final action can be done only when Beta will be out of Beta (no more changes) or when I will decide to stop working on this app. -- changed the tooltip for 'feedrate_rapids' parameter to point out that this parameter is useful only for the Marlin preprocessor -- fix app crash for the case that there are no translation files -- fixed some forgotten strings to be prepared for internationalization in ToolCalculators -- fixed Tools menu no longer working due of changes -- added some test translation for the ToolCalculators (in Romanian) -- fixed bug in ToolCutOut where for each tool invocation the signals were reconnected -- fixed some issues with ToolMeasurement due of above changes -- updated the App.final_save() function -- fixed an issue created by the fact that I used the '_' char inside the app to designate unused info and that conflicted with the _() function used by gettext -- made impossible to try to reapply current language that it's already applied (un-necessary) - -8.03.2019 - -- fixed issue when doing th CTRL (or SHIFT) + LMB, the focus is automatically moved to Project Tab -- further work in internationalization, added a fallback to English language in case there is no translation for a string -- fix for issue #262: when doing Edit-> Save & Close Editor on a Geometry that is not generated through first entering into an Editor, the geometry disappear -- finished preparing for internationalization for the files: camlib and objectCollection -- fixed tools shortcuts not working anymore due of the new toggle parameter for the .run(). -- finished preparing for internationalization for the files: FlatCAMEditor, FlatCAMGUI -- finished preparing for internationalization for the files: FlatCAMObj, ObjectUI -- sorted the languages in the Preferences combobox - -7.03.2019 - -- made showing a shape when hovering over objects, optional, by adding a Preferences -> General parameter -- starting to work in internationalization using gettext() -- Finished adding _() in FlatCAM Tools -- fixed Measuring Tool - after doing a measurement the Notebook was switching to Project Tab without letting the user see the results -- more work on the translation engine; the app now restarts after a language is applied -- added protection against using Travel Z parameter with negative or zero value (in Geometry). -- made sure that when the Measuring Tools is active after last click the Status bar is no longer deleted - -6.03.2019 - -- modified the way the FlatCAM Tools are run from toolbar as opposed of running them from other sources -- some Gerber UI changes - -5.03.2019 - -- modified the grbl-laser preprocessor lift_code() -- treated an error created by Z_Cut parameter being None -- changed the hover and selection box transparency - -4.03.2019 - -- finished work on object hovering -- fixed Excellon object move and all the other transformations -- starting to work on Manual Cutout Tool -- remade the CutOut Tool -- finished Manual Cutout Tool by adding utility geometry to the cutting geometry -- added CTRL + click behavior for adding manual bridge gaps in Cutout Tool -- in Tool Cutout added shortcut key 'Escape' to cancel the current adding of bridge gaps - -3.03.2019 - -- minor UI changes for Gerber UI -- ~~after an object move, the apertures plotted shapes are deleted from canvas and the 'mark all' button is deselected~~ -- after move tool action or any other transform (rotate, skew, scale, mirror, offset), the plotted apertures are kept plotted. -- changing units now will convert all the default values from one unit type to another -- prettified the selection shape and the moving shape -- initial work in object hovering shape - -02.03.2019 - -- fixed offset, rotate, scale, skew for follow_geometry. Fixed the move tool also. -- fixed offset, rotate, scale, skew for 'solid_geometry' inside the self.apertures. - -28.02.2019 - -- added a change that when a double click is performed in a object on canvas resulting in a selection, if the notebook is hidden then it will be displayed -- progress in ToolChange Custom commands replacement and rename - -27.02.2019 - -- made the Custom ToolChange Text area in CNCJob Selected Tab depend on the status of the ToolChange Enable Checkbox even in the init stage. -- added some parameters throughout camlib gcode generation functions; handled some possible errors (e.g like when attempting to use an empty Custom GCode Toolchange) -- added toggle effect for the tools in the toolbar. -- enhanced the toggle effect for the tools in the Tools Toolbar and also for Notebook Tab selection: if the current tool is activated it will toggle the notebook side but only if the installed widget is itself. If coming from another tool, the notebook will stay visible -- upgraded the Tool Cutout when done from Gerber file to create a convex_hull around the Gerber file rather than trying to isolate it -- added some protections for the FlatCAM Tools run after an object was loaded - -26.02.2019 - -- added a function to read the parameters from ToolChange macro Text Box (I need to move it from CNCJob to Excellon and Geometry) -- fixed the geometry adding to the self.apertures in the case when regions are done without declaring any aperture first (Allegro does that). Now, that geometry will be stored in the '0' aperture with type REG -- work in progress to Toolchange_Custom code replacement -> finished the parse and replace function -- fixed mouse selection on canvas, mouse drag, mouse click and mouse double click -- fixed Gerber Aperture Table dimensions -- added a Mark All button in the Gerber aperture table. -- because adding shapes to the shapes collection (when doing Mark or Mark All) is time consuming I made the plot_aperture() threaded. -- made the polygon fusing in modified Gerber creation, a list comprehension in an attempt for optimization -- when right clicking the files in Project tab, the Save option for Excellon no longer export it but really save the original. -- in ToolChange Custom Code replacement, the Text Box in the CNCJob Selected tab will be active only if there is a 'toolchange_custom' in the name of the preprocessor file. This assume that it is, or was created having as template the Toolchange Custom preprocessor file. - - -25.02.2019 - -- fixed the Gerber object UI layout -- added ability to mark individual apertures in Gerber file using the Gerber Aperture Table -- more modifications for the Gerber UI layout; made 'follow' an advanced Gerber option -- added in Preferences a new Category: Gerber Advanced Options. For now it controls the display of Gerber Aperture Table and the "follow" attribute4 -- fixed FlatCAMGerber.merge() to merge the self.apertures[ap]['solid_geometry'] too -- started to work on a new feature that allow adding a ToolChange GCode macro - GUI added both in CNCJob Selected tab and in CNCJob Preferences -- added a limited 'sort-of' Gerber Editor: it allows buffering and scaling of apertures - -24.02.2019 - -- fixed a small bug in the Tool Solder Paste: the App don't take into consideration pads already filled with solder paste. -- prettified the defaults files and the recent file. Now they are ordered and human readable -- added a Toggle Code Editor Menu and key shortcut -- added the ability to open FlatConfig configuration files in Code Editor, Modify them and then save them. -- added ability to double click the FlatConfig files and open them in the FlatCAM Code Editor (to be verified) -- when saving a file from Code Editor and there is no object active then the OpenFileDialog filters are reset to FlatConfig files. -- reverted a change in GCode that might affect Gerber polarity change in Gerber parser -- ability to double click the FlatConfig files and open them in the FlatCAM Code Editor - fixed and verified -- fixed the Set To Origin function when Escape was clicked -- added all the Tools in a new ToolBar -- fixed bug that after changing the layout all the toolbar actions are no longer working -- fixed bug in Set Origin function -- fixed a typo in Toolchange_Probe_MACH3 preprocessor - -23.02.2019 - -- remade the SolderPaste geometry generation function in ToolSoderPaste to work in certain scenarios where the Gerber pads in the SolderPaste mask Gerber may be just pads outlines -- updated the Properties Tool to include more information's, also details if a Geometry is of type MultiGeo or SingleGeo -- remade the Preferences GUI to include the Advanced Options in a separate way so it is obvious which are displayed when App Level is Advanced. -- added protection, not allowing the user to make a Paint job on a MultiGeo geometry (one that is converted in the Edit -> Conversion menu)) because it is not supported - -22.02.2019 - -- added Repetier preprocessor file -- removed "added ability to regenerate objects (it's actually deletion followed by recreation)" because of the way Python pass parameters to functions by reference instead of copy -- added ability to toggle globally the display of ToolTips. Edit -> Preferences -> General -> Enable ToolTips checkbox. -- added true fullscreen support (for Windows OS) -- added the ability of context menu inside the GuiElements.FCCombobox() object. -- remade the UI for ToolSolderPaste. The object comboboxes now have context menu's that allow object deletion. Also the last object created is set as current item in comboboxes. -- some GUI elements changes - -21.02.2019 - -- added protection against creating CNCJob from an empty Geometry object (with no geometry inside) -- changed the shortcut key for YouTube channel from F2 to key F4 -- changed the way APP LEVEL is showed both in Edit -> Preferences -> General tab and in each Selected Tab. Changed the ToolTips content for this. -- added the functions for GCode View and GCode Save in Tool SolderPaste -- some work in the Gcode generation function in Tool SolderPaste -- added protection against trying to create a CNCJob from a solder_paste dispenser geometry. This one is different than the default Geometry and can be handled only by SolderPaste Tool. -- ToolSolderPaste tools (nozzles) now have each it's own settings -- creating the camlib functions for the ToolSolderPaste gcode generation functions -- finished work in ToolSolderPaste -- fixed issue with not updating correctly the plot kind (all, cut, travel) when clicking in the CNC Tools Table plot buttons -- made the GCode Editor for ToolSolderPaste clear the text before updating the Code Editor tab -- all the Tabs in Plot Area are closed (except Plot Area itself) on New Project creation -- added ability to regenerate objects (it's actually deletion followed by recreation) - -20.02.2019 - -- finished added a Tool Table for Tool SolderPaste -- working on multi tool solder paste dispensing -- finished the Edit -> Preferences defaults section -- finished the UI, created the preprocessor file template -- finished the multi-tool solder paste dispensing: it will start using the biggest nozzle, fill the pads it can, and then go to the next smaller nozzle until there are no pads without solder. - -19.02.2019 - -- added the ability to compress the FlatCAM project on save with LZMA compression. There is a setting in Edit -> Preferences -> Compression Level between 0 and 9. 9 level yields best compression at the price of RAM usage and time spent. -- made FlatCAM able to load old type (uncompressed) FlatCAM projects -- fixed issue with not loading old projects that do not have certain information's required by the new versions of FlatCAM -- compacted a bit more the GUI for Gerber Object -- removed the Open Gerber with 'follow' menu entry and also the open_gerber Tcl Command attribute 'follow'. This is no longer required because now the follow_geometry is stored by default in a Gerber object attribute gerber_obj.follow_geometry -- added a new parameter for the Tcl CommandIsolate, named: 'follow'. When follow = 1 (True) the resulting geometry will follow the Gerber paths. -- added a new setting in Edit -> Preferences -> General that allow to select the type of saving for the FlatCAM project: either compressed or uncompressed. Compression introduce an time overhead to the saving/restoring of a FlatCAM project. -- started to work on Solder Paste Dispensing Tool -- fixed a bug in rotate from shortcut function -- finished generating the solder paste dispense geometry - -18.02.2019 - -- added protections again wrong values for the Buffer and Paint Tool in Geometry Editor -- the Paint Tool in Geometry Editor will load the default values from Tool Paint in Preferences -- when the Tools in Geometry Editor are activated, the notebook with the Tool Tab will be unhidden. After execution the notebook will hide again for the Buffer Tool. -- changed the font in Tool names -- added in Geometry Editor a new Tool: Transformation Tool. -- in Geometry Editor by selecting a shape with a selection shape, that object was added multiple times (one per each selection) to the selected list, which is not intended. Bug fixed. -- finished adding Transform Tool in Geometry Editor - everything is working as intended -- fixed a bug in Tool Transform that made the user to not be able to capture the click coordinates with SHIFT + LMB click combo -- added the ability to choose an App QStyle out of the offered choices (different for each OS) to be applied at the next app start (Preferences -> General -> Gui Pref -> Style Combobox) -- added support for FlatCAM usage with High DPI monitors (4k). It is applied on the next app startup after change in Preferences -> General -> Gui Settings -> HDPI Support Checkbox -- made the app not remember the window size if the app is maximized and remember in QSettings if it was maximized. This way we can restore the maximized state but restore the windows size unmaximized -- added a button to clear the GUI preferences in Preferences -> General -> Gui Settings -> Clear GUI Settings -- added key shortcuts for the shape transformations within Geometry Editor: X, Y keys for Flip(mirror), Shift+X, Shift+Y combo keys for Skew and Alt+X, Alt+Y combo keys for Offset -- adjusted the plotcanvas.zomm_fit() function so the objects are better fit into view (with a border around) -- modified the GUI in Objects Selected Tab to accommodate 2 different modes: basic and Advanced. In Basic mode, some of the functionality's are hidden from the user. -- added Tool Transform preferences in Edit -> Preferences and used them through out the app -- made the output of Panelization Tool a choice out of Gerber and Geometry type of objects. Useful for those who want to engrave multiple copies of the same design. - -17.02.2019 - -- changed some status bar messages -- New feature: added the capability to view the source code of the Gerber/Excellon file that was loaded into the app. The file is also stored as an object attribute for later use. The view option is in the project context menu and in Menu -> Options -> View Source -- Serialized the source_file of the Objects so it is saved in the FlatCAM project and restored. -- if there is a single tool in the tool list (Geometry , Excellon) and the user click the Generate GCode, use that tool even if it is not selected -- fixed issue where after loading a project, if the default kind of CNCjob view is only 'cuts' the plot will revert to the 'all' type -- in Editors, if the modifier key set in Preferences (CTRL or SHIFT key) is pressed at the end of one tool operation it will automatically continue to that action until the modifier is no longer pressed when Select tool will be automatically selected. -- in Geometry Editor, on entry the notebook is automatically hidden and restored on Geometry Editor exit. -- when pressing Escape in Geometry Editor it will automatically deselect any shape not only the currently selected tool. -- when deselecting an object in Project menu the status bar selection message is deleted -- added ability to save the Gerber file content that is stored in FlatCAM on Gerber file loading. It's useful to recover from saved FlatCAM projects when the source files are no longer available. -- fixed an issue where the function handler that changed the layout had a parameter changed accidentally by an index value passed by the 'activate' signal to which was connected -- fixed bug in paint function in Geometry Editor that didn't allow painting due of overlap value - -16.02.2019 - -- added the 'Save' menu entry to the Project context menu, for CNCJob: it will export the GCode. -- added messages in info bar when selecting objects in the Project View list -- fixed DblSided Tool so it correctly creates the Alignment Drills Excellon file using the new structure -- fixed DblSided Tool so it will not crash the app if the user tries to make a mirror using no coordinates -- added some relevant status bar messages in DblSided Tool -- fixed DblSided Tool to correctly use the Box object (until now it used as reference only Gerber object in spite of Excellon or Geometry objects being available) -- fixed DblSided Tool crash when trying to create Alignment Drills object without a Tool diameter specified -- fixed DblSided Tool issue when entering Tool diameter values with comma decimal separator instead of decimal dot separator -- fixed Cutout Tool Freeform to generate cutouts with options: LR, TB. 2LR, 2TB which didn't worked previously -- fixed Excellon parser to detect correctly the units and zeros for Excellon's generated by Eagle 9.3.0 -- modified the initial size of the canvas on startup -- modified the build file (make_win.py) to solve the issue with suddenly not accepting the version as Beta -- changed the initial layout to 'compact' -- updated the install scripts to uninstall a previously installed FlatCAM Beta (that has the same GUID) - -15.02.2019 - -- rearranged the File and Edit menu's and added some explanatory tooltips on certain menu items that could be seen as cryptic -- added Excellon Export Options in Edit -> Preferences -- started to work in using the Excellon Export parameters -- remade the Excellon export function to work with parameters entered in Edit -> Preferences -> Excellon Export -- added a new entry in the Project Context Menu named 'Save'. It will actually work for Geometry and it will do Export DXF and for Excellon and it will do Export Excellon -- reworked the offer to save a project so it is done only if there are objects in the project but those objects are new and/or are modified since last project load (if an old project was loaded.) -- updated the Excellon plot function so it can plot the Excellon's from old projects -- removed the message boxes that popup on Excellon Export errors and replaced them with status bar messages -- small change in tab width so the tabs looks good in Linux, too. - -14.02.2019 - -- added total travel distance for CNCJob object created from Excellon Object in the CNCJob Selected tab -- added 'FlatCAM ' prefix to any detached tab, for easy identification -- remade the Grids context menu (right mouse button click on canvas). Now it has values linked to the units type (inch or mm). Added ability to add or delete grid values and they are persistent. -- updated the function for the project context menu 'Generate CNC' menu entry (Action) to use the modernized function FlatCAMObj.FlatCAMGeometry.on_generatecnc_button_click() -- when linked, the grid snap on Y will copy the value in grid snap on X in real time -- in Gerber aperture table now the values are displayed in the current units set in FlatCAM -- added shortcut key 'J' (jump to location) in Editors and added an icon to the dialog popup window -- the notebook is automatically collapsed when there are no objects in the collection and it is showed when adding an object -- added new options in Edit -> Preferences -> General -> App Preferences to control if the Notebook is showed at startup and if the notebook is closed when there are no objects in the collection and showed when the collection has objects. - -13.02.2019 - -- added new parameter for Excellon Object in Preferences: Fast Retract. If the checkbox is checked then after reaching the drill depth, the drill bit will be raised out of the hole asap. -- started to work on GUI forms simplification -- changed the Preferences GUI for Geometry and Excellon Objects to make a difference between parameters that are changed often and those that are not. -- changed the layout in the Selected Tab UI -- started to add apertures table support -- finished Gerber aperture table display -- made the Gerber aperture table not visible as default and added a checkbox that can toggle the visibility -- fixed issue with plotting in CNCJob; with Plot kind set to something else than 'all' when toggling Plot, it was defaulting to kind = 'all' -- added (and commented) an experimental FlatCAMObj.FlatCAMGerber.plot_aperture() - -12.02.2019 - -- whenever a FlatCAM tool is activated, if the notebook side is hidden it will be unhidden -- reactivated the Voronoi classes -- added a new parameter named Offset in the Excellon tool table - work in progress -- finished work on Offset parameter in Excellon Object (Excellon Editor, camlib, FlatCAMObj updated to take this param in consideration) -- fixed a bug where in Excellon editor when editing a file, a tool was automatically added. That is supposed to happen only for empty newly created Excellon Objects. -- starting to work on storing the solid_geometry for each tool in part in Excellon Object -- stored solid_geometry of Excellon object in the self.tools dictionary -- finished the solid_geometry restore after edit in Excellon Editor -- finished plotting selection for each tool in the Excellon Tool Table -- fixed the camlib.Excellon.bounds() function for the new type of Excellon geometry therefore fixed the canvas selection, too - - -10.02.2019 - -- the SELECTED type of messages are no longer printed to shell from 2 reasons: first, too much spam and second, issue with displaying html -- on set_zero function and creation of new geometry or new excellon there is no longer a zoom fit -- repurposed shortcut key 'Delete' to delete tools in tooltable when the mouse is over the Seleted tab (with Geometry inside) or in Tools tab (when NCC Tool or Paint Tool is inside). Or in Excellon Editor when mouse is hovering the Selected tab selecting a tool, 'Delete' key will delete that tool, if on canvas 'Delete' key will delete a selected shape (drill). In rest, will delete selected objects. -- adjusted the preprocessor files so the Spindle Off command (M5) is done before the move to Toolchange Z -- adjusted the Toolchange Manual preprocessor file to have more descriptive messages on the toolchange event -- added a strong focus to the object_name entry in the Selected tab -- the keypad keyPressed are now detected correctly -- added a pause and message/warning to do a rough zero for the Z axis, in case of Toolchange_Probe_MACH3 preprocessor file -- changes in Toolchange_Probe_MACH3 preprocessor file - -9.02.2019 - -- added a protection for when saving a file first time, it require a saved path and if none then it use the current working directory -- added into Preferences the Calculator Tools -- made the Preferences window scrollable on the horizontal side (it was only vertically scrollable before) -- fixed an error in Excellon Editor -> add drill array that could appear by starting the function to add a drill array by shortcut before any mouse move is registered while in Editor -- changed the messages from status bar on new object creation/selection -- in Geometry Editor fixed the handler for the Rotate shortcut key ('R') - -8.02.2019 - -- when shortcut keys 1, 2, 3 (tab selection) are activated, if the splitter left side (the notebook) is hidden it will be made visible -- changed the menu entry Toggle Grid name to Toggle Grid Snap -- fixed errors in Toggle Axis -- fixed error with shortcut key triggering twice the keyPressEvent when in the Project List View -- moved all shortcut keys handlers from Editors to the keyPressEvent() handler from FLatCAMGUI -- in Excellon Editor added a protection for Tool_dia field in case numbers using comma as decimal separator are used. Also added a QDoubleValidator forcing a number with max 4 decimals and from 0.0000 to 9.9999 -- in Excellon Editor added a shortcut key 'T' that popup a window allowing to enter a new Tool with the set diameter -- in App added a shortcut key 'T' that popup a windows allowing to enter a new Tool with set diameter only when the Selected tab is on focus and only if a Geometry object is selected -- changed the shortcut key for Transform Tool from 'T' to 'Alt+T' -- fixed bug in Geometry Selected tab that generated error when used tool offset was less than half of either total length or half of total width. Now the app signal the issue with a status bar message -- added Double Validator for the Offset value so only float numbers can be entered. -- in App added a shortcut key 'T' that popup a windows allowing to enter a new Tool with set diameter only when the Tool tab is on focus and only if a NCC Tool or Paint Area Tool object is installed in the Tool Tab -- if trying to add a tool using shortcut key 'T' with value zero the app will react with a message telling to use a non-zero value. - -7.02.2019 - -- in Paint Tool, when painting single polygon, when clicking on canvas for the polygon there is no longer a selection of the entire object -- commented some debug messages -- imported speedups for shapely -- added a disable menu entry in the canvas contextual menu -- small changes in Tools layout -- added some new icons in the help menu and reorganized this menu -- added a new function and the shortcut 'leftquote' (left of Key 1) for toggle of the notebook section -- changed the Shortcut list shortcut key to F3 -- moved some graphical classes out of Tool Shell to GUIElements.py where they belong -- when selecting an object on canvas by single click, it's name is displayed in status bar. When nothing is selected a blank message (nothing) it's displayed -- in Move Tool I've added the type of object that was moved in the status bar message -- color coded the status bar bullet to blue for selection -- the name of the selected objects are displayed in the status bar color coded: green for Gerber objects, Brown for Excellon, Red for Geometry and Blue for CNCJobs. - -6.02.2019 - -- fixed the units calculators crash FlatCAM when using comma as decimal separator -- done a regression on Tool Tab default text. It somehow delete Tools in certain scenarios so I got rid of it -- fixed bug in multigeometry geometry not having the bounds in self.options and crashing the GCode generation -- fixed bug that crashed whole application in case that the GCode editor is activated on a Tool gcode that is defective. -- fixed bug in Excellon Slots milling: a value of a dict key was a string instead to be an int. A cast to integer solved it. -- fixed the name self-insert in save dialog file for GCode; added protection in case the save path is None -- fixed FlatCAM crash when trying to make drills GCode out of a file that have only slots. -- changed the messages for Units Conversion -- all key shortcuts work across the entire application; moved all the shortcuts definitions in FlatCAMGUI.keyPressEvent() -- renamed the theme to layout because it is really a layout change -- added plot kind for CNC Job in the App Preferences -- combined the geocutout and cutout_any TCL commands - work in progress -- added a new function (and shortcut key Escape) that when triggered it deselects all selected objects and delete the selection box(es) -- fixed bug in Excellon Gcode generation that made the toolchange X,Y always none regardless of the value in Preferences -- fixed the Tcl Command Geocutout to work with Gerber objects too (besides Geometry objects) - -5.02.3019 - -- added a text in the Selected Tab which is showed whenever the Selected Tab is selected but without having an object selected to display it's properties -- added an initial text in the Tools tab -- added possibility to use the shortcut key for shortcut list in the Notebook tabs -- added a way to set the Probe depth if Toolchange_Probe preprocessors are selected -- finished the preprocessor file for MACH3 tool probing on toolchange event -- added a new parameter to set the feedrate of the probing in case the used preprocessor does probing (has toolchange_probe in it's name) -- fixed bug in Marlin preprocessor for the Excellon files; the header and toolchange event always used the parenthesis witch is not compatible with GCode for Marlin -- fixed a issue with a move to Z_move before any toolchange - -4.02.2019 - -- modified the Toolchange_Probe_general preprocessor file to remove any Z moves before the actual toolchange event -- created a prototype preprocessor file for usage with tool probing in MACH3 -- added the default values for Tool Film and Tool Panelize to the Edit -> Preferences -- added a new parameter in the Tool Film which control the thickness of the stroke width in the resulting SVG. It's a scale parameter. -- whatever was the visibility of the corresponding toolbar when we enter in the Editor, it will be set after exit from the Editor (either Geometry Editor or Excellon Editor). -- added ability to be detached for the tabs in the Notebook section (Project, Selected and Tool) -- added ability for all detachable tabs to be restored to the same position from where they were detached. -- changed the shortcut keys for Zoom In, Zoom Out and Zoom Fit from 1, 2, 3 to '-', '=' respectively 'V'. Added new shortcut keys '1', '2', '3' for Select Project Tab, Select Selected Tab and Select Tool Tab. -- formatted the Shortcut List Tab into a HTML table - -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. -- added a remove_tools() function before install_tools() in the init_tools() that is called when creating a new project. Should solve the issue with having double menu entry's in the TOOLS menu -- fixed remove_tools() so the Tcl Shell action is readded to the Tools menu and reconnected to it's slot function -- added an automatic name on each save operation based on the object name and/or the current date -- added more information's for the statistics - -2.2.2019 - -- code cleanup in Tools -- some GUI structure optimization's -- added protection against entering float numbers with comma separator instead of decimal dot separator in key points of FlatCAM (not everywhere) -- added a choice of plotting the kind of geometry for the CNC plot (all, travel and cut kind of geometries) in CNCJob Selected Tab -- added a new preprocessor file named: 'probe_from_zmove' which allow probing to be done from z_move position on toolchange event -- fixed the snap magnet button in Geometry Editor, restored the checkable property to True -- some more changes in the Editors GUI in deactivate() function -- a fix for saving as empty an edited new and empty Excellon Object - -1.02.2019 - -- fixed preprocessor files so now the bounds values are right aligned (assuming max string length of 9 chars which means 4 digits and 4 decimals) -- corrected small type in list_sys Tcl command; added a protection of the Plot Area Tab after a successful edit. -- remade the way FlatCAM saves the GUI position data from a file (previously) to use PyQt QSettings -- added a 'theme' combo selection in Edit -> Preferences. Two themes are available: standard and compact. -- some code cleanup -- fixed a source of possible errors in DetachableTab Widget. -- fixed gcode conversion/scale (on units change) when multiple values are found on each line -- replaced the pop-up window for the shortcut list with a new detachable tab -- removed the pop-up messages from the rotate, skew, flip commands - -31.01.2019 - -- added a parameter ('Fast plunge' in Edit -> Preferences -> Geometry Options and Excellon Options) to control if the fast move to Z_move is done or not -- added new function to toggle fullscreen status in Menu -> View -> Toggle Full Screen. Shortcut key: Alt+F10 -- added key shortcuts for Enable Plots, Disable Plots and Disable other plots functions (Alt+1, Alt+2, Alt+3) -- hidden the snap magnet entry and snap magnet toggle from the main view; they are now active only in Editor Mode -- updated the camlib.CNCJob.scale() function so now the GCode is scaled also (quite a HACK :( it will need to be replaced at some point)). Units change work now on the GCODE also. -- added the bounds coordinates to the GCODE header -- FlatCAM saves now to a file in self.data_path the toolbar positions and the position of TCL Shell -- Plot Area Tab view can now be toggled, added entry in View Menu and shortcut key Ctrl+F10 -- All the tabs in the GUI right side are (Plot Are, Preferences etc) are now detachable to a separate windows which when closed it returns in the previous location in the toolbar. Those detached tabs can be also reattached by drag and drop. - -30.01.2019 - -- added a space before Y coordinate in end_code() function in some of the preprocessor files -- added in Calculators Tool an Electroplating Calculator. -- remade the App Menu for Editors: now they will be showed only when the respective Editor is active and hidden when the Editor is closed. -- added a traceback report in the TCL Shell for the errors that don't allow creation of an object; useful to trace exceptions/errors -- in case that the Toolchange X,Y parameter in Selected (or in Preferences) are deleted then the app will still do the job using the current coordinates for toolchange -- fixed an issue in camlib.CNCJob where tha variable self.toolchange_xy was used for 2 different purposes which created loss of information. -- fixed unit conversion functions in case the toolchange_xy parameter is None -- more fixes in camlib.CNCJob regarding usage of toolchange (in case it is None) -- fixed preprocessor files to work with toolchange_xy parameter value = None (no values in Edit - Preferences fields) -- fixed Tcl commands CncJob and DrillCncJob to work with toolchange -- added to the preprocessor files the command after toolchange to go with G00 (fastest) to "Z Move" value of Z pozition. - -29.01.2019 - -- fixed issue in Tool Calculators when a float value was entered starting only with the dot. -- added protection for entering incorrect values in Offset and Scale fields for Gerber and Geometry objects (in Selected Tab) -- added more shortcut keys in the Geometry Editor and in Excellon Editor; activated also the zoom (fit, in, out) shortcut keys ('1' , '2', '3') for the editors -- disabled the context menu in tools table on Paint Tool in case that the painting method is single. -- added protection when trying to do Intersection in Geometry Editor without having selected Geometry items. -- fixed the scale, mirror, rotate, skew functions to work with Geometry Objects of multi-geometry type. -- added a GUI for Excellon Search time for OR-TOOLS path optimization in Edit -> Preferences -> Excellon General -> Optimization Time -- more changes in Edit -> Preferences -> Geometry, Gerber and in CNCJob -- added new option for Cutout Tool Freeform Gaps in Edit -> Preferences -> Tools -- fixed Freeform Cutout gaps issue (it was double than the value set) -- added protection so the Cutout (either Freeform or Rectangular) cannot be done on a multigeo Geometry -- added 2Sided Tool default values in Edit -> Preferences -> Tools -- optimized the FlatCAMCNCJob.on_plot_cb_click_table() plot function and solved a bug regarding having tools numbers not in sync with the cnc tool table - -28.01.2018 - -- fixed the FlatCAMGerber.merge() function -- added a new menu entry for the Gerber Join function: Edit -> Conversions -> "Join Gerber(s) to Gerber" allowing joining Gerber objects into a final Gerber object -- moved Paint Tool defaults from Geometry section to the Tools section in Edit -> Preferences -- added key shortcuts for Open Manual = F1 and for Open Online VideoHelp = F2 - -27.01.2018 - -- added more key shortcuts into the application; they are now displayed in the GUI menu's -- reorganized the Edit -> Preferences -> Global -- redesigned the messagebox that is showed when quiting ot creating a New Project: now it has an option ('Cancel') to abort the process returning to the app -- added options for trace segmentation that can be useful for auto-levelling (code snippet from Lei Zheng from a rejected pull request on FlatCAM https://bitbucket.org/realthunder/ ) -- added shortcut key 'L' for creating 'New Excellon' -- added shortcut key combo 'Shift+S' for Running a Script. -- modified GRBL_laser preprocessor file so it includes a Sxxxx command on the line with M03 (laser active) whenever a value is enter in the Spindlespeed entry field -- remade the EDIT -> PREFERENCES window, the Excellon and Gerber sections. Created a new section named TOOLS - -26.01.2019 - -- fixed grbl_11 preprocessor in linear_code() function -- added icons to the Project Tab context menu -- added new entries to the Canvas context menu (Copy, Delete, Edit/Save, Move, New Excellon, New Geometry, New Project) -- fixed GRBL_laser preprocessor file -- updated function for copy of an Excellon object for the case when the object has slots -- updated FlatCAMExcellon.merge() function to work in case some (or all) of the merged objects have slots - -25.01.2019 - -- deleted junk folders -- remade the Panelize Tool: now it is much faster, it is multi-threaded, it works with multitool geometries and it works with multigeo geometries too. -- made sure to copy the options attribute to the final object in the case of: FlatCAMGeometry.merge(), FlatCAMGerber.merge() and for the Panelize Tool -- modified the panelize TclCommand to take advantage of the new panelize() function; added a 'threaded' parameter (default value is 1) which controls the execution of the panelize TclCommand: threaded or non-threaded -- fixed TclCommand Cutout -- added a new TclCommand named CutoutAny. Keyword: cutout_any - -24.01.2019 - -- trying to fix painting single when the actual painted object it's a MultiPolygon -- fixed the Copy Object function when the object is Gerber -- added the Copy entry to the Project context menu -- made the functions behind Disable and Enable project context menu entries, non-threaded to fix a possible issue -- added multiple object selection on Open ... and Import ... (idea and code snippet came from Travers Carter, BitBucket user https://bitbucket.org/travc/) -- fixed 'GRBL_laser' preprocessor bugs (missing functions) -- fixed display geometry for 'GRBL_laser' preprocessor -- Excellon Editor - added possibility to create an linear drill array rotated at an custom angle -- added the Edit and Properties entries to the Project context menu - -23.01.2019 - -- added a new preprocessor file named 'line_xyz' which have x, y, z values on the same GCode line -- fixed calculation of total path for Excellon Gcode file -- modified the way FlatCAM preferences are saved. Now they can be saved as new files with .FlatConfig extension by the user and shared. -- added possibility to open the folder where FlatCAM is saving the preferences files - -21.01.2019 - -- changed some tooltips -- added tooltips in Excellon tool table headers -- in Excellon Tool Table the columns are now only selectable by clicking on the header (sorting is done automatically) -- if CNCJob from Excellon then hide the CNC tools table in CNCJob Object +- add Python folder and Python\Scripts folder to your Path (https://docs.microsoft.com/en-us/previous-versions/office/developer/sharepoint-2010/ee537574(v%3Doffice.14)) +- verify that the pip package can be run by opening Command Prompt(Admin) and running the command: pip -V +- look in the requirements.txt file (found in the sources folder) and install all the dependencies using the pip package. +The required wheels can be downloaded either from: +https://www.lfd.uci.edu/~gohlke/pythonlibs/ +or +https://pypi.org/ -20.01.2019 - -- fixed the HPGL code geometry rendering when travel -- fixed the message box layout when asking to save the current work -- made sure that whenever the HPGL preprocessor is selected the Toolchange is always ON and the MultiDepth is OFF -- the HPGL preprocessor entry is not allowed in Excellon Object preprocessor selection combobox as it is only applicable for Geometry -- when saving HPGL code it will be saved as a file with extension .plt -- the units mentioned in HPGL format are only METRIC therefore if FlatCAM units are in INCH they will be transform to METRIC -- the minimum unit in HPGL is 0.025mm therefore the coordinates are rounded to a multiple of 0.025mm -- removed the raise statement in do_worker_task() function as this is fatal in conjunction with PyQt5 -- added a try - except clause for the situations when for a font can't be determined the family and name -- moved font parsing to the Geometry Editor: it is done everytime the Text tool is invoked -- made sure that the HPGL preprocessor is not populated in the Excellon preprocessors in Preferences as it make no sense (HPGL is useful only for Geometries) - -19.01.2019 - -- added initial implementation of HPGL preprocessor -- fixed display HPGL code geometry on canvas - -11.01.2019 - -- added a status message for font parsing - -9.01.2019 - -- added a fix to allow creating of Excellon geometry even when there are points with no tools by skipping those points and warning the user about this in a Tcl message -- added a message box asking users if they want to save the project in case that either New Project menu entry is clicked or if Exit menu entry is clicked or if the app is closed from the close button. The message box will be showed only if there are objects in the collection. -- modified the first line in the Gcode header to show the FlatCAM version and version_date - -8.01.2019 - -- added checkboxes in Preferences -> General -> Global Preferences to switch on/off version check at application startup and also to control if the app will send anonymous statistics about FlatCAM usage to help improve FlatCAM - -7.01.2019 - -- added tooltips in Edit->Convert menu -- fixed cutting from copper features when doing Gerber isolation with multiple passes - -6.01.2019 - -- fixed the Marlin preprocessor detection in GCode header -- the version date in GCode header is now the one set in FlatCAMApp.App.version_date -- fixed bug in preprocessor files: number of drills is now calculated only for the Excellon objects in toolchange function (only Excellon objects have drills) - -5.01.2019 - -- fixed cncjob TclCommand - it used the default values for parameters -- fixed the layout in ToolTransform -- fixed the initial text in the ToolShell -- reactivated the version check in case the release is not BETA; FlatCAMApp.App has now a beta object that when set True the application will show in the Title and help-> About that is Beta (and it disable version checking) -- added a new name (mine: for good and/or bad) to the contributors list -- fixed the Join function to work on Gerber and Excellon, Gerber and Gerber, Excellon and Excelon combination of objects. The merged property is the solid_geometry and the result is a FlatCAMGeometry object. - -3.01.2019 - -- initial merge into FlatCAM regular - -28.12.2018 - -- changed the workspace drawing from 'gl' to 'agg'. 'gl' has better performance but it messes with the overlapping graphics -- removed the initial obj.build_ui() in App.editor2object() - -25.12.2018 - -- fixed bugs in Excellon Editor due of PyQt5 port -- fixed bug when loading Gerber with follow -- fixed bug that when a Gerber was loaded with -follow parameter it could not be isolated external and full -- changed multiple status bar messages -- changed some assertions to (status error message + return) combo -- fixed issues in 32bit installers -- added protection against using Excellon joining on different kind of objects -- fixed bug in ToolCutout where the Rectangular Cutout used the Type of Gaps from Freeform Cutout -- fixed bug that didn't allowed saving SVG file from a Gerber file -- modified setup_ubuntu.sh file for PyQt5 packages - -23.12.2018 - -- added move (as in Tool Move) capability for CNCJob object and the GCode is updated on each move --> finished both for Gcode loaded and for CNCJob generated in the app -- fixed some errors related to DialogOpen widget that I've missed in PyQt5 porting -- added a bounds() method for CNCJob class in camlib (perhaps overdone as it worked well with the one inherited) -- small changes in Paint Tool - the rest machining is working only partially -- added more columns in CNCjob Tool Table showing more info about the present tools -- make the columns in CNCJob Tool Table not editable as it has no sense - -22.12.2018 - -- fixed issues in Transform Tool regarding the message boxes -- fixed more error in Double Sided Tool and added some more information's in ToolTips -- added more information's in CutOut Tool ToolTips -- updated the tooltips in amost all FlatCAM tools; in Tool Tables added column header ToolTips -- fixed NCC rest machining in NCC Tool; added status message and stop object creation if there is no geometry on any tool -- fixed version number: now it will made of a number in format main_version.secondary_version/working_version -- modified the makefile for windows builds to accommodate both 32bit and 64bit executable generation - -21.12.2018 - -- added shortcut "SHIFT + W" for workspace toggle -- updated the list of shortcuts -- forbid editing for the MultiGeo type of Geometry because the Geometry Editor is not prepared for this -- finished a "sort" of rest-machining for Non Copper Clearing Tool but it's time consuming operation -- reworked the NCC Tool as it was fundamental wrong - still has issues on the rest machining -- added a parameter reset for each run of Paint Tool and NCC Tool - -20.12.2018 - -- porting application to PyQt5 -- adjusted the level of many status bar messages -- created new bounds() methods for Excellon and Gerber objects as the one inherited from Geometry failed in conjunction with PyQt5 -- fixed some small bugs where a string was divided by a float finally casting the result to an integer -- removed the 'raise' conditions everywhere I could and make protections against loading files in the wrong place -- fixed a "PyCharm stupid paste on the previous tab level even after one free line " in Excellon.bounds() -- in Geometry object fixed error in tool_delete regarding deletion while iterating a dict -- started to rework the NCC Tool to generate one file only -- in Geometry Tool Table added checkboxes for individual plot of tools in case of MultiGeo Geometry -- rework of NCC Tool UI -- added a automatic selector: if the system is 32bit the OR-tools imports are not done and the OR-tools drill path optimizations are replaced by a default Travelling Salesman drill path optimization -- created a Win32 make file to generate a Win32 executable -- disabled the Plot column in Geometry Tool Table when the geometry is SingleGeo as it is not needed -- solved a issue when doing isolation, if the solid_geometry is not a list will make it a list -- added tooltips in the Geometry Tool Table headers explaining each column -- added a new Tcl Command: clear. It clears the Tcl Shell of all text and restore it to the original state -- fixed Properties Tool area calculation; added status bar messages if there is no object selected show an error and successful showing properties is confirmed in status bar -- when Preferences are saved, now the default values are instantly propagated within the application -- when a geometry is MultiGeo and all the tools are deleted, it will have no geometry at all therefore all that it's plotted on canvas that used to belong to it has to be deleted and because now it is an empty object we demote it to SingleGeo so it can be edited - -19.12.2018 - -- fixed SVG_export for MultiGeo Geometries -- fixed DXF_export for MultiGeo Geometries -- fixed SingleGeo to MultiGeo conversion plotting bug - -18.12.2018 - -- small changes in FlatCAMGeometry.plot() -- updated the FlatCAMGeometry.merge() function and the Join Geometry feature to accommodate the different types of geometries: singlegeo and multigeo type -- added Conversion submenu in Edit where I moved the Join features and added the Convert from MultiGeo to SingleGeo type and the reverse -- added Copy Tool (on a selection of tools) feature in Geometry Object UI -- fixed the bounds() method for the MultiGeo geometry object so the canvas selection is working and also the Properties Tool -- fixed Move Tool to support MultiGeo geometry objects moving -- added tool edit in Geometry Object Tool Table -- added Tool Table context menu in Geometry Object and in Paint Tool -- modified some Status Bar messages in Geometry Object - -17.12.2018 - -- added support for multiple solid_geometry in a geometry object; each tool can now have it's own geometry. Plot, project save/load are OK. -- added support for single GCode file generation from multi-tool PaintTool job -- added protection for results of Paint Tool job that do not have geometry at all. An Error will be issued. It can happen if the combination of Paint parameters is not good enough -- 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] -- fixed conflict with "space" keyboard shortcut for CNC job - -16.12.2018 - -- redone the Options menu; removed the Transfer Options as they were not used -- deleted some folders in the project structure that were never used -- Paint polygon Single works only for left mouse click allowing mouse panning -- added ability to print errors in status bar without raising Tcl Shell -- fixed small bug: when doing interiors isolation on a Gerber that don't allow it, no object is created now and an error in the status bar is issued -- fixed bug in Paint All for Geometry made from exteriors Gerber isolation -- fixed the join geometry: when the geometries has different tools the join will fail with a status bar message (as it should). Allow joining of geometries that have no tool. // Reverted on 18.12.2018 -- changed the error messages that are simple to the kind that do not open the TCl shell -- fixed some issues in Geometry Object -- Paint Tool - reworked the UI and made it compatible with the Geometry Object UI -- Paint Tool - tool edit functional -- added Clear action in the Context menu of the TCl Shell - -14.12.2018 - -- fixed typo in setup_ubuntu.sh -- minor changes in Excellon Object UI -- added Tool Table in Paint Tool -- now in Paint Tool and Non Copper Clearing Tool a selection of tools can be deleted (not only one by one) -- minor GUI changes (added/corrected tooltips) -- optimized vispy startup time from about >6 sec to ~3 seconds -- removed vispy text collection starting in plotcanvas as it did nothing // RESTORED 18.12.2018 as it messed the graphical presentation -- fixed cncjob TclCommand for the new type of Geometry -- make sure that when using the TclCommands, the object names are case insensitive -- updated the TCL Shell auto-complete function; now it will index also the names of objects created or loaded in the application -- on object removal the name is removed from the Shell auto-complete model - -13.12.2018 - -NEW Geometry Object and CNC Object architecture (3rd attempt) which allow multiple tools for one geometry - -- fixed issue with cumulative G-code after successive delete/create of a CNCJob on the same geometry (some references were kept after deletion of CNCJob object which kept the deleted tools data and added it to a new one) -- fixed plot and export G-code in new format -- fixed project save/load in the new format for geometry -- added new feature in CNCJob Object UI: since we may have multiple tools per CNCJob object due of having multiple tool in Geometry Object, -now there is a Tool Table in CNC Object UI and each tool GCode can be enabled or disabled - -12.12.2018 - -- Geometry Tool Table: when the Offset type is 'custom' each tool it's storing the value and it is updated on UI when that tool is selected in UI table -- Geometry Tool Table: fixed tool offset conversion when the Offset in Tool Table UI is set to Custom - -11.12.2018 - -- cleaned up the generatecncjob() function in FlatCAMObj -- created a new function for generating cncjob out of multitool geometry, mtool_generate_cncjob() -- cleaned up the generate_from_geometry_2() method in camlib -- Geometry Tool Table: new tool added copy all the form fields (data) from the last tool -- finished work on generation of a single CNC Job file (therefore a single GCODE file) even for multiple tools in Geo Tool Table -- GCode header is added only on saving the file therefore the time generation will be reflected in the file -- modified preprocessors to accommodate the new CNC Job file with multiple tools -- modified preprocessors so the last X,Y move will be to the toolchange X,Y pos (set in Preferences) -- save_project and load_project now work with the new type of multitool geometry and cncjob objects - -10.12.2018 - -- added new feature in Geometry Tool Table: if the Offset type in tool table is 'Offset' then a new entry is unhidden and the user can use custom offset -- Geometry Tool Table: fixed add new tool with diameter with many decimals -- Geometry Tool Table: when editing the tip dia or tip angle for the V Shape tool, the CutZ is automatically calculated - -9.12.2018 - -- new Geometry Tool Table has functional unit conversion -- when entering a float number in Spindle Speed now there is no error and only the integer part is used, the decimals are discarded -- finished the Geometry Tool Table in the form that generates only multiple files -- if tool type is V-Shape ('V') then the Cut Z entry is disabled and new 'Tip Dia' and 'Tip Angle' fields are showed. The values entered will calculate the Cut Z parameter - -5.12.2018 - -- remade the Geometry Tool Table, before this change each tool could not store it's own set of data in case of multiple tools with same diameter -- added a new column in Geo Tool Table where to specify which type of tool to use: C for circular, B for Ball and V for V-shape - -4.12.2018 - -- new geometry/excellon object name is now only "new_g"/"new_e" as the type is clear from the category is into (and the associated icon) -- always autoselect the first tool in the Geometry Tool table -- issue error message if the user is trying to generate CNCJob without a tool selected in Geometry Tool Table -- add the whole data from Geometry Object GUI as dict in the geometry tool dict so each tool (file) will have it's own set of data - -3.12.2018 - -- Geometry Tool table: delete multiple tools with same diameter = DONE -- Geometry Tool table: possibility to cut a path inside or outside or on path = DONE -- Geometry Tool table: fixed situation when user tries to add a tool but there is no tool diameter entered -- if a geometry is a closed shape then create a Polygon out of it -- some fixes in Non Copper Clearing Tool -- Geometry Tool table: added option to delete_tool function for delete_all -- Geometry Tool table: added ability to delete even the last tool in tool_table and added an warning if the user try to generate a CNC Job without a tool in tool table -- if a geometry is painted inside the Geometry Editor then it will store the tool diameter used for this painting. Only one tool cn be stored (the last one) so if multiple paintings are done with different tools in the same geometry it will store only the last used tool. -- if multiple geometries have different tool diameters associated (contain a paint geometry) they aren't allowed to be joined and a message is displayed letting the user know - -2.12.2018 - -- started to work on a geometry Tool Table -- renamed FlatCAMShell as ToolShell and moved it (and termwidget) to flatcamTools folder -- cleaned up the ToolShell by removing the termwidget separate file and added those classes to ToolShell -- added autocomplete for TCL Shell - the autocomplete key is 'TAB' -- covered some possible exceptions in rotate/skew/mirror functions -- Geometry Tool table: add/delete tools = DONE -- Geometry Tool table: add multiple tools with same diameter = DONE - -1.12.2018 - -- fixed Gerber parser so now the Gerber regions that have D02 operation code just before the end of the region will be processed correctly. Autotrax Dex Gerbers are now loaded -- fixed an issue with temporary geo storage "geo" being referenced before assignment -- moved all FlatCAM Tools into a single directory - -30.11.2018 - -- remade the CutOut Tool. I've put together the former Freeform Cutout tool and the Cutout Object fount in Gerber Object GUI and left only a link in the Gerber Object GUI. This tidy the GUI a bit. -- created a Paint Tool and replaced the Paint Area section in Geometry Object GUI with a link to this tool. -- fixed bug in former Paint Area and in the new Paint Tool that made the paint method not to be saved in App preferences -- solved a bug in Gerber parser: in case that an operation code D? was encountered alone it was not remembered - fixed -- fixed bug related to the newly entered toolchange feature for Geometry: it was trying to evaluate toolchange_z as a comma separated value like for toolchange x,y -- fixed bug in scaling units in CNC Job which made the unit change between INCH and MM not possible if a CNC Job was present in the project objects - -29.11.2018 - -- added checks for using a Z Cut with positive value. The Z Cut parameter has to be negative so if the app will detect a positive value it will automatically convert it to negative -- started to implement rest-machining for Non Copper clearing Tool - for now the results are not great -- added Toolchange X,Y position parameters and modified the default and manual_toolchange preprocessor file to use them -For now they are used only for Excellon objects who do have toolchange events -- added Toolchange event selection for Geometry objects; for now it is as before, single tool on each file -- remade the GUI for objects and in Preferences to have uniformity -- fixed bug: after editing a newly created excellon/geometry object the object UI used to not keep the original settings -- fixed some bugs in Tool Add feature of the new Non Copper Clear Tool -- added some messages in the Non Copper Clear Tool -- added parameters for coordinates no of decimals and for feedrate no of decimals used in the resulting GCODE. They are in EDIT -> Preferences -> CNC Job Options -- modified the preprocessors to use the "decimals" parameters - -28.11.2018 - -- added different methods of copper clearing (standard, seed, line_based) and "connect", "contour" options found in Paint function -- remake of the non-copper clearing tool as a separate tool -- modified the "About" menu entry to mention the main contributors to FlatCAM 3000 -- modified Marlin preprocessor according to modifications made by @redbull0174 user from FlatCAM.org forum -- modified Move Tool so it will detect if there is no object to move and issue a message - -27.11.2018 - -- fixed bug in isolation with multiple passes -- cosmetic changes in Buffer and Paint tool from Geometry Editor -- changed the way selection box is working in Geometry Editor; now cumulative selection is done with modifier key (SHIFT or CONTROL) - before it was done by default -- changed the default value for CNCJob tooldia to 1mm - -25.11.2018 - -- each Tool change the name of the Tools tab to it's name -- all open objects are no longer autoselected upon creation. Only on new Geometry/Excellon object creation it will be autoselected - -24.11.2018 - -- restored the selection method in Geometry Editor to the original one found in FlatCAM 8.5 -- minor changes in Clear Copper function -- minor changes in some preprocessors -- change Join Geometry menu entry to Join Geo/Gerber -- added menu entry for Toggle Axis in Menu -> View -- added menu entry for Toggle Workspace in Menu -> View -- added Bounding box area to the Properties (when metric units, in cm2) -- non-copper clearing function optimization -- fixed Z_toolchange value in the GCODE header - -21.11.2018 - -- not very precise jump to location function -- added shortcut key for jump to coordinates (J) and for Tool Transform (T) -- some work in shortcut key - -19.11.2018 - -- fixed issue with nested comment in preprocessors -- fixed issue in Paint All; reverted changes - -18.11.2018 - -- renamed FlatCAM 2018 to FlatCAM 3000 -- added new entries in the Help menu; one will show shortcut list and the other will start a YouTube webpage with a playlist where I will publish future training videos for this version of FlatCAM -- if a Gerber region has issues the file will be loaded bypassing the error but there will be a TCL message letting the user know that there are parser errors. - -17.11.2018 - -- added Excellon parser support for units defined outside header - - -12.11.2018 - -- fixed bug in Paint Single Polygon -- added spindle speed in laser preprocessor -- added Z start move parameter. It controls the height at which the tool travel on the fist move in the job. Leave it blank if you don't need it. - -9.11.2018 - -- fixed a reported bug generated by a typo for feedrate_z object in camlib.py. Because of that, the project could not be saved. -- fixed a G01 usage (should be G1) in Marlin preprocessor. -- changed the position of the Tool Dia entry in the Object UI and in FlatCAMGUI -- fixed issues in the installer - -30.10.2018 - -- fixed a bug in Freeform Cutout Tool - it was missing a change in the name of an object - -29.10.2018 - -- added Excellon export menu entry and functionality that can export in fixed format 2:4 LZ INCH (format that Altium can load and it is a more generic format). -It will be usefull for those who need FlatCAM to only convert the Excellon to a more useful format and visualize Gerbers. -The other Excellon Export menu entry is exporting in units either Metric or INCH depending on the current units in FlatCAM, but it will always use the decimal format which may not be loaded in all cases. -- disabled the Selected Tab while in Geometry Editor; the user is not supposed to have access to those functions while in Geometry Editor -- added an menu entry in Menu -> File -> Recent Files named Clear Recent files which does exactly that -- fixed issue: when a New Project is created but there is a Geometry still in Geometry Editor (or Excellon Editor) not saved, now that geometry is deleted -- fixed problem when doing Clear Copper with Cut over 1st point option active. When the shape is not closed then it may cut over copper features. Originally the feature was meant to be used only with isolation geometry which is closed. Fixed - -28.10.2018 - -- fixed Excellon Editor shortcut messages; also fixed differences in messages between usage by shortcuts and usage by menu toolbar actions -- fixed Excellon Editor bug: it was triggering exceptions when the user selected a tool in tooltable and then tried to add a drill (or array) by clicking on canvas -Clicking on canvas by default clear all the used tools, therefore the action could not be done. Fixed. -- fixed bug Excellon Editor: when all the drills from a tool are resized, after resize they can't be selected. -- Excellon Editor: added ability to delete multiple tools at once by doing multiple selection on the tooltable -- Excellon Editor: if there are no more drills to a tool after doing drills resize then delete that tool from the tooltable -- Excellon Editor: always select the last tool added to the tooltable -- Excellon Editor: added a small canvas context menu for Excellon Editor - -27.10.2018 - -- added a Paint tool toolbar icon and added shortcut key 'I' for Paint Tool -- fixed unreliable multiple selection in Geometry Editor; some clicks were not registered -- added utility geometry for Add Drill Array in Excellon Editor -- fixed bug Excellon Editor: drills in drill array start now from the array start point (x, y); previously array start point was used only for calculating the radius -- fixed bug Excellon Editor: Measurement Tool was not acting correctly in Exc Editor regarding connect/disconnect of events -- in Excellon Editor every time a tool is clicked (except Select which is the default) the focus will return to Selected tab -- added protection in Excellon Editor: if there is no tool/drill selected no operation over drills can be performed and a status bar message will be displayed -- Excellon Editor: added relevant messages for all actions -- fixed bug Excellon Editor: multiple selection with key modifier pressed (CTRL/SHIFT) either by simple click or through selection box is now working -- fixed dwell parameter for Excellon in Preferences to be default Off - -26.10.2018 - -- when objects are disabled they can't be selected -- added Feedrate_z (Plunge) parameter for Geometry Object -- fixed bug in units convert for Geometry Tab; added some missing parameters to the conversion list -- fixed bug in isolation Geometry when the isolated Gerber was a single Polygon -- updated the Paint function in Geometry Editor - -25.10.2018 - -- added a verification on project saving to make sure that the project was saved successfully. If not, a message will be displayed in the status bar saying so. - -20.10.2018 - -- fixed the SVG import as Gerber. But unfortunately, when there is a ground pour in a imported PCB SVG, the ground pour will be isolated inside -instead to be isolated outside like every other feature. That's no way around this. The end result will be thinner features -for the ground pour and if one is relying on those thin connections as GND links then it will not work as intended ,they may be broken. -Of course one can edit the isolation geometry and delete the isolation for the ground pour. -- delete selection shapes on double clicking on object as we may not want to have selection shape while Selected tab is active - -19.10.2018 - -- solved some value update bugs in tool_table in Excellon Editor when editing tools followed by deleting another tool, -and then re-adding the just-deleted tool. -- added support for chaining blocks in DXF Import -- fixed the DXF arc import -- added support for a type of Gerber files generated by OrCAD where the Number format is combined with G74 on the same line -- in Geometry Editor added the possibility for buffer to use different kinds of corners -- added protection against loading an GCODE file as Excellon through drag & drop on canvas or file open dialog -- added shortcut key 'B' for buffer operation inside Geometry Editor -- added shell message in case the Font used in Text Tool in Geometry editor is not supported. Only Regular, Bold, Italic adn BoldItalic are supported as of yet. -- added shortcut key 'T' for Text Tool inside Geometry Editor -- added possibility for Drag & Drop on FlatCAM GUI with multiple files at once - -18.10.2018 - -- fixed DXF arc import in case of extrusion enabled -- added on Geo Editor Toolbar the button for Buffer Geometry; added the possibility to create exterior and interior buffer -- fixed a numpy import error - -17.10.2018 - -- added Spline support and Ellipse (chord) support in DXF Import: chord might have issues -(borrowed from the work of Vasilis Vlachoudis, https://github.com/vlachoudis/bCNC) -- added Block support in DXF Import - no support yet for chained blocks (INSERT in block) -- support for repasted block insertions - -16.10.2018 - -- added persistent toolbar view: the enabled toolbars will be active at the next app startup while those that are not enabled will not be -enabled at the next app startup. To enable/disable toolbars right click on the toolbar. - -15.10.2018 - -- DXF Export works now also for Exteriors only and Interiors only geometry generated from Gerber Object -- when a Geometry is edited, now the interiors and exterior of a Polygon that is part of the Geometry can be selected individually. In practice, if -doing full isolation geometry, now both external and internal trace can be selected individually. - -13.10.2018 - -- solved issue in CNC Code Editor: it appended text to the previous one even if the CNC Code Editor was closed -- added .GBD Gerber extension to the lists -- added support for closed polylines/lwpolylines in Import DXF; now PCB patterns found in PDF format can be imported in INKSCAPE -and saved as DXF. FlatCAM can import DXF as Gerber and the user now can do isolation on it. - -12.10.2018 - -- added zoom in, zoom out and zoom fit buttons on the View toolbar -- fixed bug that on Double Sided Tool when a Excellon Alignment is created does not reset the list of Alignment drills -- added a message warning the user to add Point coordinates in case the reference used in Double Sided Tool is Point -- added new feature: DXF Export for Geometry - -10.10.2018 - -- fixed a small bug in Setup Recent Files -- small fix in Freeform Cutout Tool regarding objects populating the combo boxes -- Excellon object name will reflect the number of edits performed on it - -9.10.2018 - -- In Geometry Editor, now Path and Polygon draw mode can be finished not only with shortcut key Enter but also with right click on canvas -- fixes regarding of circle linear approximation - final touch -- fix for interference between Geo Editor and Excellon Editor -- fixed Cut action in Geometry Editor so it can now be done multiple times on the target geometry without need for saving in between. -- initial work on DXF import; made the GUI interface and functional structure -- added import functions for DXF import -- finished DXF Import (no blocks support, no SPLINE support for now) - -8.10.2018 - -- completed toggle canvas selection when there is only one object under click position for the case when clicking the object is done -while other object is already selected. -- added static utility geometry just upon activating an Editor function -- changed the way the canvas is showed on FlatCAM startup - -7.10.2018 - -- solved mouse click not setting relative measurement origin to zero -- solved bug that always added one drill when copying a selection of drills in the EXCELLON EDITOR -- solved bug that the number of copied drills in Excellon Editor was not updated in the tool table -- work in the Excellon Editor: found useful to change the diameter of one tool to another already in the list; -could help for all those tools that are a fraction difference that comes from imperial to mm (or reverse) conversion, -to reduce the tool changes - Done -- in Excellon Editor, always auto-select the last tool added -- in Excellon Editor fixed shortcuts for drill add and drill_array add: they were reversed. Now key 'A' is for array add -and key 'D' is for drill add -- solved a small bug in Excellon export: even when there were no slots in the file, it always added the tools list that -acted as unnecessary toolchanges -- after Move action, all objects are deselected - - -6.10.2018 - -- Added basic support for SVG text in SVG import. Will not work if some letters in a word have different style (italic bold or both) -- added toggle selection to the canvas selection if there is only one object under the click position -- added support for "repeat" command in Excellon file -- added support for Allegro Gerber and Excellon files -- Python 3.7 is used again; solved bug where the activity icon was not playing when FlatCAM active - -5.10.2018 - -- fixed undesired setting focus to Project Tab when doing the SHIFT + LMB combo (to capture the click coordinates) - -4.10.2018 - -- Excellon Editor: finished Add Drill Array - Linear type action -- Excellon Editor: finished Add Drill Array - Circular type action -- detected bug in shortcuts: Fixed -- Excellon Editor: added constrain for adding circular array, if the number of drills multiplied by angle is more than 360 -the app will return with an message -- solved sorting bug in the Excellon Editor tool table -- solved bug in Menu -> Edit -> Sort Origin ; the selection box was not updated after offset -- added Excellon Export in Menu -> File -> Export -> Export Excellon -- added support to save the slots in the Excellon file in case there were some in the original file -- fixed Double Sided Tool for the case of using the box as mirroring reference. - -2.10.2018 - -- made slots persistent after edit -- bug detected: in Excellon Editor if new tool added diameter is bigger than 10 it mess things up: SOLVED -- Excellon Editor: finished Drill Resize action -- after an object is deleted from the Project list, if the current tab in notebook is not Project, -always focus in the Project Tab (deletion can be done by shortcut key also) -- changed the initial view to include the possible enabled workspace guides - -1.10.2018 - -- added GUI for Excellon Editor in the Tool Tab -- Excellon Editor: created and populated the tool list -- Excellon Editor: added possibility to add new tools in the list -- Excellon Editor: added possibility to delete a tool (and the drills that it contain) by selecting a row in the tool table and -clicking the Delete Tool button -- Excellon Editor: added possibility to change the tool diameter in the tool list for existing tool diameters. -- Excellon Editor: when selecting a drill, it will highlight the tool in the Tool table -- Excellon Editor: optimized single click selection -- Excellon Editor: added selection for all drills with same diameter upon tool selection in tool table; fix in tool_edit -- Excellon Editor: added constrain to selection by single click, it will select if within a certain area around the drill -- Excellon Editor: finished Add Drill action -- Excellon Editor: finished Move Drill action -- Excellon Editor: finished Copy Drill action - -- fixed issue: when an object is selected before entering the Editor mode, now the selecting shape is deleted before entry -in the Editor (be it Geometry or Excellon). -- fixed a few glitches regarding the units change -- when an object is deselected on the Plot Area, the notebook will switch to Project Tab -- changed the selection behavior for the dragging rectangle selection box in Editor (Geometry, Excellon): by dragging a -selection box and selecting is cumulative: it just adds. To remove from selection press key Ctrl (or Shift depending of -the setting in the Preferences) and drag the rectangle across the objects you want to deselect. - -29.09.2018 - -- optimized the combobox item population in Panelization Tool and in Film Tool -- FlatCAM now remember the last path for saving files not only for opening -- small fix in GUI -- work on Excellon Editor. Excellon editor working functions are: loading an Excellon object into Editor, -saving an Excellon object from editor to FlatCAM, selecting drills by left click, selection of drills by dragging rectangle, deletion of drills. -- fixed Excellon merge -- added more Gcode details (depthperpass parameter in Gcode header) in preprocessors -- deleted the Tool informations from header in preprocessors due to Mach3 not liking the lot of square brackets -- more corrections in preprocessors - - -28.09.2018 - -- added a save_defaults() call on App exit from action on Menu -> File -> Exit -- solved a small bug in Measurement Tool -- disabled right mouse click functions when Measurement Tools is active so the user can do panning and find the destination point easily -- added a new button named "Measure" in Measurement Tool that allow easy access to Measurement Tool from within the tool -- fixed a bug in Gerber parser that when there was a rectangular aperture used within a region, some artifacts were generated. -- some more work on Excellon Editor - -27.09.2018 - -- fixed bug when creating a new project, if a previous object was selected on screen, the selection shape -survived the creation of a new project -- added compatibility with old type of FlatCAM projects -- reverted modifications to the way that Excellon geometry was stored to the old way. -- added exceptions for Paint functions so the user can know if something failed. -- modified confirmation messages to use the color coded messages (error = red, success = green, warning = yellow) -- restored activity icon - -26.09.2018 - -- disabled selection of objects in Project Tab when in Editor -- the Editor Toolbar is hidden in normal mode and it is showed when Editor -is activated. I may change this behaviour back. -- changed names in classes, functions to prepare for the Excellon editor - -- fixed bugs in Paint All function -- fixed a bug in ParseSVG module in parse_svg_transform(), related to 'scale' - -- moved all the Editor menu/toolbar creation to FlatCAMUI where they belong -- fixed a Gerber parse number issue when Gerber zeros are TZ (keep trailing zeros) - -- changed the way of how the solid_geometry for Excellon files is stored -and plotted. Before everything was put in the same "container". Now, -the geometries of drills and slots are organized into dictionaries having -as keys the tool diameters and as values list of Shapely objects (polygons) -- fix for Excellon plotting for newly created empty Excellon Object -- fixed geometry.bounds() in camlib to work with the new format of the Excellon geometry (list of dicts) - -24.09.2018 - -- added packages in the Requirements and setup_ubuntu.sh. Tested in Ubuntu and -it's OK -- added Replace (All) feature in the CNC Code Editor -- made CNC Code generation for Excellon to show progress -- added information about transforms in the object properties (like skew -and how much, if it was mirrored and so on) -- made all the transforms threaded and make them show progress in the progress bar -- made FlatCAM project saving, threaded. - -23.09.2018 - -- added support for "header-less" Excellon files. It seems that Mentor PADS does generate such -non-standard Excellon files. The user will have to guess: units (IN/MM), type of zero suppression LZ/TZ -(leading zeros or trailing zeros are kept) and Excellon number format(digits and decimals). -All of those can be adjusted in Menu -> Edit -> Preferences -> Excellon Object -> Excellon format -- fixed svgparse for Path. Now PCB rasted images can traced in Inkscape or PDF's can be converted -and then saved as SVG files which can be imported into FlatCAM. This is a convolute way to convert a PDF -to Gerber file. - -22.09.2018 - -- added Drag & Drop capability. Now the user can drag and drop to FlatCAM GUI interface a file -(with the right extension) that can be a FlatCAM project file (.FlatPrj) a Gerber file, -an Excellon file, a G-Code file or a SVG file. -- made the Move Tool command threaded -- added Image import into FlatCAM - -21.09.2018 - -- added new information's in the object properties: all used Tool-Table items -are included in a new entry in self.options dictionary -- modified the preprocessor files so they now include information's about -how many drills (or slots) are for each tool. The Gcode will have this -information displayed on the message from ToolChange. -- removed some log.debug and add new log.debug especially for moments when some process is finished -- fixed the utility geometry for Font geometry in Geometry Editor -- work on selection in Geometry Editor -- added multiple selection key as a Preference in Menu -> Edit -> Preferences -It can be either Shift or Ctrl. -- fixed bug in Gerber Object -> Copper Clearing. -- added more comprehensive tooltips in Non-copper Clearing as advice on how to proceed. -- adjusted make_win32.py file so it will work with Python 3.7 (cx_freeze can't copy OpenGL files, so -it has to be done manually) - -19.09.2018 - -- optimized loading FlatCAM project by double clicking on project file; there is no need to clean up everything by using -the function not Thread Safe: on_file_new() because there is nothing to clean since FlatCAM just started. - -- added a workspace delimitation with sizes A3, A4 and landscape or portrait format -- The Workspace checkbox in Preferences GUI is doing toggle on the workspace -- made the workspace app default state = False -- made the workspace to resize when units are changed -- disabled automatic defaults save (might create SSD wear) -- added an automatic defaults save on FlatCAM application close -- made the draw method for the Workspace lines 'agg' so the quality of the FC objects will not be affected - -- added Area constrain to the Panelization Tool: if the resulting area is too big to fit within constrains, the number -of columns and/or rows will be reduced to the maximum that still fits is. -- removed the Flip command from Panelization Tools because Flipping (Mirroring) should be done properly with the -Transform Tool or using the provided shortcut keys. - -- made Font parsing threaded so the application will not wait for the font parsing to complete therefore the app start -is faster - - -17.09.2018 - -- fixed Measuring Tool not working when grid is turned OFF -- fixed Roland MDX20 preprocessor -- added a .GBR extension in the open_gerber filter -- added ability to Scale and Offset (for all types of objects) to just -press Enter after entering a value in the Entry just like in Tool Transform -- added capability in Tool Transform to mirror(flip) around a certain Point. -The point coordinates can either be entered by hand or they can be captured -by left clicking while pressing key "SHIFT" and then clicking the Add button -- added the .ROL extension when saving Machine Code -- replaced strings that reference to G-Code from G-Code to CNC Code -- added capability to open a project by serving the path/project_name.FlatPrj as a parameter -to FlatCAM.py - -15.09.2018 - -- removed dwell line generator and included dwell generation in the preprocessor files -- added a proposed RML1 Roland_MDX20 preprocessor file. -- added a limit of 15mm/sec (900mm/min) to the feedrate and to the feedrate_rapid. Anything faster than this -will be capped to 900mm/min regardless what is entered in the program GUI. This is because Roland MDX-20 has -a mechanical limit of the speed to 15mm/sec (900mm/min in GUI) - -14.09.2018 -- remade the Double Sided Tool so it now include mirroring of Excellon and Geometry Objects along Gerber. -Made adding points easier by adding buttons to GUI that allow adding the coordinates captured by -left mouse click + SHIFT key -- added a few fixes in code to the other FlatCAM tools regarding reset_fields() function. The issue -was present when clicking New Project entry in Menu -> File. -- FIXED: fix adding/updating bounding box coords for the mirrored objects in Double side Tool. -- FIXED: fix the bounding box values from within FlatCAM objects, upon units change. -- fixed issue with running again the constructor of the drawing tools after the tool action was complete, -in Geometry Editor -- fixed issue with Tool tab not closed after Text Input tool is finished. -- fixed issue with TEXT to GEOMETRY tool, the resulting geometry was not scaled depending of current units -- fixed case when user is clicking on the canvas to place a Font Geometry without clicking apply button first -or the Font Geometry is empty, in Geometry Editor - > Text Input tool -- reworked Measuring Tool by adding more information's (START, STOP point coordinates) and remade the -strings -- added to Double Sided Tool the ability to use as reference box Excellon and Geometry Objects - -12.09.2018 - -- fixed Excellon Object class such that Excellon files that have both drills and slots are supported -- remade the GUI interface for the Excellon Object in a more compact way; added a column with slots numbers -(if any) along the drills numbers so now there is only one tool table for drills and slots. -- remade the GUI in Preferences and removed unwanted stretch that was broken the layout. -- if for a certain tool, the slots number is zero it will not be displayed -- reworked Text to Geometry feature to work in Linux and MacOS -- remade the Text to Geometry so font collection process is done once at app start-up improving the performance - - -09.09.2018 - -- added TEXT ENTRY SUPPORT in Geometry Editor. It will convert strings of True Type Fonts to geometry. -The actual dimensions are approximations because font size is in points and not in metric or inch units. -For now full support is limited to Windows. In Linux/MacOS only the fonts for which the font name is the same -as the font filename are supported. Italic and Bold functions may not work in Linux/MacOS. -- solved bug: some Drawing menu entries not having connected functions - -28.08.2018 - -- fixed Gerber parser so now G01 "moving" rectangular -aperture is supported. -- fixed import_svg function; it can import SVG as geometry (solved bug) -- fixed import_svg function; it can import SVG as Gerber (it did not work previously) -- added menu entry's for SVG import as Gerber and separated import as Geometry - -27.08.2018 - -- fixed Gerber parser so now FlatCAM can load Gerber files generated by Mentor Graphics EDA programs. - -26.08.2018 - -- added awareness for missing coordinates in Gerber parsing. It will try to use the previous coordinates but if there -are not any those lines will be ignored and an Warning will be printed in Tcl Shell. -- fixed TCL commands AlignDrillGrid and DrilCncJob -- added TCL script file load_and_run support in GUI -- made the tool_table in Excellon to automatically adjust the table height depending on the number of rows such that -all the rows will be displayed. -- structural changes in the Excellon build_ui() -- icon changes and menu compress - -23.08.2018 - -- added Excellon routing support -- solved a small bug that crippled Excellon slot G85 support when the coordinates -are with period. -- changed the way selection is done in Geometry Editor; now it should work -in all cases (although the method used may be computationally intensive, -because sometimes you have to click twice to make selection if you do it too fast) - -21.08.2018 - -- added Excellon slots support when using G85 command for generation of -the slots file. Inspired from the work of @mgix. Thanks. -Routing format support for slots will follow. -- minor bug solved: option "Cut over 1st pt" now has same name both in -Preferences -> Geometry Options and in Selected tab -> Geomety Object. -Solves #3 -- added option to select Climb or Conventional Milling in Gerber Object options -Solves #4 -- made "Combine passes" option to be saved as an app preference -- added Generate Exteriors Geo and Generate Interiors Geo buttons in the -Gerber Object properties -- added configuration for the number of steps used for Gerber circular aperture -linear approximation. The option is in Preferences -> Gerber Options -- added configuration for the number of steps used for Gcode circular aperture -linear approximation. The option is in Preferences -> CNCjob Options -- added configuration for the number of steps used for Geometry circular aperture -linear approximation. The option is in Preferences -> Geometry Options. It is used -on circles/arcs made in Geometry Editor and for other types of geometries generated in -the app. - - -17.07.2018 - -- added the required packages in Requirements.txt file -- added required packages in setup_ubuntu.sh file -- added color control over almost all the colors in the application; those -settings are in Menu -> Edit -> Preferences -> General Tab -- added configuration of which mouse button to be used when panning (MMB or RMB) -- fixed bug with missing 'drillz' parameter in function generate_from_excellon_by_tool() -(credits for finding it goes to Stefan Smith https://bitbucket.org/stefan064/) -- load Factory defaults in Preferences will load the defaults that are used just after -first install. Load Defaults option in Preferences will load the User saved Defaults. - -03.07.2018 - -- fixed bug in rotate function that didn't update the bounding box of the -modified object (rotated) due of not emitting the right signal parameter. -- removed the Options tab from the Notebook (the left area where is located -also the Project tab). Replaced it with the Preferences Tab launched with -Menu -> Edit -> Preferences -- when FlatCAM is used under MacOS, multiple selection of shapes in Editor -mode is done using SHIFT key instead of CTRL key due of MacOS interpreting -Ctrl+LMB_click as a RMB click -- when in Editor, clicking not on a shape, reset the index of selected shapes -to zero -- added a new Tab in the Plot Area named Gcode Editor. It allow the user to -edit the Gcode and then Save it or Print it. -- added a fix so the 'preamble' Gcode is correctly inserted between the -comments header and the actual GCODE -- added Find function in G-Code Editor - - -27.06.2018 - -- the Plot Area tab is changing name to "Editor Area" when the Editor is -activated and returns to the "Plot Area" name upon exiting the Editor -- made the labels shorter in Transform Tool in anticipation of -Options Tab removal from Notebook and replacing it with Preferences -- the Excellon Editor is not finished (not even started yet) so the -Plot Area title should stay "Plot Area" not change to "Editor Area" when -attempting to edit an Excellon file. Solved. -- added a header comment block in the generated Gcode with useful -information's -- fixed issue that did not allow the Nightly's to be run in -Windows 7 x64. The reason was an outdated DLL file (freetype.dll) used -by Vispy python module. - - -25.06.2018 - -- "New" menu entry in Menu -> File is renamed to "New Project" -- on "New Project" action, all the Tools are reinitialized so the Tools -tab will work as expected -- fixed issue in Film Tool when generating black film -- fixed Measurement Tool acquiring and releasing the mouse/key events -- fixed cursor shape is updated on grid_toggle -- added some infobar messages to show the user when the Editor was -activated and when it was closed (control returned to App). -- added thread usage for Film tool; now the App is no longer blocked on -film generation and there is a visual clue that the App is working - -22.06.2018 - -- added export PNG image functionality and menu entry in -Menu -> File -> Export PNG ... -- added a command to set focus on canvas inside the mouve move event -handler; once the mouse is moved the focus is moved to canvas so the -shortcuts work immediatly. -- solved a small bug when using the 'C' key to copy name of the selected -object to clipboard - -- fixed millholes() function and isolate() so now it works even when the -tool diameter is the same as the hole diameter. - -Actually if the passed value to the buffer() function is zero, I -artificially add a value of 0.0000001 (FlatCAM has a precision of -6 decimals so I use a tenth of that value as a pseudo "zero") -because the value has to be positive. This may have solved for some use -cases the user complaints that on clearing the areas of copper there is -still copper leftovers. - -- added shortcut "Shift+G" to toggle the axis presence. Useful when one -wants to save a PNG file. -- changed color of the grid from 'gray' to 'dimgray' - -- the selection shape is deleted when the object is deleted - -- the plot area is now in a TAB. -- solved bug that allowed middle button click to create selection -- fixed issue with main window geometry restore (hopefully). -- made view toolbar to be hidden by default as it is not really needed -(we have the functions in menu, zoom is done with mouse wheel, and there -is also the canvas context menu that holds the functionality) -- remade the GUIElements.FCInput() and made a GUIElements.FCTab() -- on visibility plot toogle the selection shape is deleted - -- made sure that on panning in Geometry editor, the context menu is not -displayed -- disabled App shortcut keys on entry in Geometry Editor so only the -local shortcut keys are working - -- deleted metric units in canvas context menu -- added protection so object deletion can't be done until Geometry -Editor session is finished. Solved bug when the shapes on Geometry -Editor were not transfered to the New_geometry object yet and the -New_Geometry object is deleted. In this case the drawn shapes are left -in a intermediary state on canvas. - -- added selection shape drawing in Geometry Editor preserving the -current behavior: click to select, click on canvas clear selection, -Ctrl+click add to selection new shape but remove from selection -if already selected. Drag LMB from left to right select enclosed -shapes, drag LMB from right to left select touching shapes. Now the -selection is made based on -- added info message to be displayed in infobar, when a object is -renamed - -20.06.2018 - -- there are two types of mouse drag selection (rectangle selection) -If there is a rectangle selection from left to right, the color of the -selection rectangle is blue and the selection is "enclosing" - this -means that the object to be selected has to be enclosed by the selecting -blue rectangle shape. -If there is a rectangle selection fro right to left, the color of the -selection rectangle is green and the selection is "touching" - this -means that it's enough to touch with the selecting green rectangle the -object(s) to be selected so they become selected -- changed the modifier key required to be pressed when LMB is ckicked -over canvas in order to copy to clipboard the coordinates of the click, -from CTRL to SHIFT. CTRL will be used for multiple selection. -- change the entry names in the canvas context menu -- disconnected the app mouse event functions while in geometry editor -since the geometry editor has it's own mouse event functions and there -was interference between object and geometry items. Exception for the -mouse release event so the canvas context menu still work. -- solved a bug that did not update the obj.options after a geometry -object was edited in geometry editor -- solved a bug in the signal that saved the position and dimensions of -the application window. -- solved a bug in app.on_preferences() that created an error when run -in Linux - -18.06.2018 Update 1 - -- reverted the 'units' parameter change to 'global_units' due of a bug -that did not allow saving of the project -- modified the camlib transform (rotate, mirror, scale etc) functions -so now they work with Gerber file loaded with 'follow' parameter - -18.06.2018 - -- reworked the Properties context menu option to a Tool that displays -more informations on the selected object(s) -- remade the FlatCAM project extension as .FlatPrj -- rearranged the toolbar menu entries to a more properly order -- objects can now be selected on canvas, a blue polygon is drawn around -when selected -- reworked the Tool Move so it will work with the new canvas selection -- reworked the Measurement Tool so it will work with the new canvas -selection -- canvas selection can now be done by dragging left mouse boutton and -creating a selection box over the objects -- when the objects are overlapped on canvas, the mouse click -selection works in a circular way, selecting the first, then the second, -then ..., then the last and then again the first and so on. -- double click on a object on canvas will open the Selected Tab -- each object store the bounding box coordinates in the options dict -- the bbox coordinates are updated on the obj options when the object -is modified by a transform function (rotate, scale etc) - - -15.06.2018 - -- the selection marker when moving is now a semitransparent Polygon -with a blue border -- rectified a small typo in the ToolTip for Excellon Format for -Diptrace excellon format; from 4:2 to 5:2 -- corrected an error that cause no Gcode could be saved - - -14.06.2018 - -- more work on the contextual menu -- added Draw context menu -- added a new tool that bring together all the transformations, named -Transformation Tool (Rotate, Skew, Scale, Offset, Flip) -- added shorcut key 'Q' which toggle the units between IN and MM -- remade the Move tool, there is now a selection box to show where the -move is done -- remade the Measurement tool, there is now a line between the start -point of measurement and the end point of the measurement. -- renamed most of the system variables that have a global app effect to -global_name where name is the parameter (variable) - - -9.06.2018 - -- reverted to PyQt4. PyQt5 require too much software rewrite -- added calculators: units_calculator and V-shape Tool calculator -- solved bug in Join Excellon -- added right click menu over canvas - -6.06.2018 Update - -- fixed bug: G-Code could not be saved -- fixed bug: double clicking a category in Project Tab made the app to -crash -- remade the bounds() function to work with nested lists of objects as -per advice from JP which made the operation less performance taxing. -- added shortcut Shift+R that is complement to 'R' -- shorcuts 'R' and 'Shift+R' are working now in steps of 90 degrees -instead of previous 45 degrees. -- added filters in the open ... FlatCAM projects are saved automatically -as *.flat, the Gerber files have few categories. So the Excellons and -G-Code and SVG. - -6.06.2018 - -- remade the transform functions (rotate, flip, skew) so they are now -working for joined objects, too -- modified the Skew and Rotate comamands: if they are applied over a -selection of objects than the origin point will be the center of the -biggest bounding box. That allow for perfect sync between the selected -objects -- started to modify the program so the exceptions are handled correctly -- solved bug where a crash occur when ObjCollection.setData didn't -return a bool value -- work in progress for handling situations when a different file is -loaded as another (like loading a Gerber file using Open Excellon - commands. -- added filters on open_gerber and open_excellon Dialogs. There is still -the ability to select All Files but this should reduce the cases when -the user is trying to oprn a file from a wrong place. - -4.06.2018 - -- finished PyQt4 to PyQt4 port on the Vispy variant (there were some changes -compared with the Matplotlib version for which the port was finished -some time ago) -- added Ctrl+S shortcut for the Geometry Editor. When is activated it will -save de geometry ("update") and return to the main App. -- modified the Mirror command for the case when multiple objects are -selected and we want to mirror all together. In this case they should mirror -around a bounding box to fill all. - -3.06.2018 - -- removed the current drill path optimizations as they are inefficient -- implemented Google OR-tools drill path optimization in 2 flavors; -Basic OR-tools TSP algorithm and OR-Tools Metaheuristics Guided Local Path -- Move tool is moved to Menu -> Edit under the name Move Object - -- solved some internal bugs (info command was creating an non-fatal -error in PyQt, regarding using QPixMaps outside GUI thread -- reworked camlib number parsing (still had some bugs) -- working in porting the application from usage of PyQt4 to PyQt4 -- added TclCommands save_sys and list_sys. save_sys is saving all the -system default parameters and list_sys is listing them by the first -letters. listsys with no arguments will list all the system parameters. - -29.05.2018 - -- modified the labels for the X,Y and Dx,Dy coordinates -- modified the menu entries, added more icons -- added initial work on a Excellon Editor -- modified the behavior of when clicking on canvas the coordinates were -copied to cliboard: now it is required to press CTRL key for this to -happen, and it will only happen just for left mouse button click -- removed the autocopy of the object name on new object creation -- remade the Tcl commands drillcncjob and cncjob -- added fix so the canvas is focused on the start of the program, -therefore the shortcuts work without the need for doing first a click -on canvas. - - - -28.05.2018 - -- added total drill count column in Excellon Tool Table which displays the -total number of drills -- added aliases in panelize Tool (pan and panel should work) -- modified generate_milling method which had issues from the Python3 port -(it could not sort the tools due of dict to dict comparison no longer -possible). -- modified the 'default' preprocessor in order to include a space -between the value of Xcoord and the following Y -- made optional the using of threads for the milling command; by default -it is OFF (False) because in the current configuration it creates issues -when it is using threads -- modified the Panelize function and Tcl command Panelize. It was having -issues due to multithreading (kept trying to modify a dictionary in -redraw() method)and automatically selecting the last created object -(feature introduced by me). I've added a parameter to -the new_object method, named autoselected (by default it is True) and -in the panelize method I initialized it with False. -By initializing the plot parameter with False for the temporary objects, -I have increased dramatically the generation speed of the panel because -now the temporary object are no longer ploted which consumed time. -- replaced log.warn() with log.warning() in camlib.py. Reason: deprecated -- fixed the issue that the "Defaults" button was having no effect when -clicked and Options Combo was in Project Options -- fixed issue with Tcl Shell loosing focus after each command, therefore -needing to click in the edit line before we type a new command (borrowed -from @brainstorm -- added a header in the preprocessor files mentioning that the GCODE -files were generated by FlatCAM. -- modified the number of decimals in some of the line entries to 4. -- added an alias for the millholes Tcl Command: 'mill' - -27.04.2018 - -- modified the Gerber.scale() function from camlib.py in order to -allow loading Gerber files with 'follow' parameter in other units -than the current ones -- snap_max_entry is disabled when the DRAW toolbar is disabled (previous -fix didn't work) -- added drill count column in Excellon Tool Table which displays the -total number of drills for each tool - -- added a new menu entry in Menu -> EDIT named "Join Excellon". It will -merge a selection of Excellon files into a new Excellon file -- added menu stubs for other Excellon based actions - -- solved bug that was not possible to generate film from joined geometry -- improved toggle active/inactive of the object through SPACE key. Now -the command works not only for one object but also for a selection - -26.05.2018 - -- made conversion to Python3 -- added Rtree Indexing drill path optimization -- added a checkbox in Options Tab -> App Defaults -> Excellon -Group named Excellon Optim. Type from which it can be selected -the default optimization type: TS stands for Travelling -Salesman algorithm and Rtree stands for Rtree Indexing -- added a checkbox on the Grid Toolbar that when checked -(default status is checked) whatever value entered in the GridX entry -will be used instead of the now disabled GridY entry -- modified the default behavior on when a line_entry is clicked. -Now, on each click on a line_entry, the content is automatically -selected. -- snap_max_entry is disabled when the DRAW toolbar is disabled - -24.05.2015 - -- in Geometry Editor added a initial form of Rotate Geometry command in -toolbar -- changed the way the geometry is finished if it requires a key: before -it was using key 'Space' now it uses 'Enter' -- added Shortcut for Rotate Geometry to key 'Space' -- after using a tool in Geometry Editor it automatically defaults to -'Select Tool' - -23.05.2018 - -Added key shortcut's in FlatCAMApp and in Geometry Editor. - -FlatCAMApp shortcut list: -1 Zoom Fit -2 Zoom Out -3 Zoom In -C Copy Obj_Name -E Edit Geometry (if selected) -G Grid On/Off -M Move Obj - -N New Geometry -R Rotate -S Shell Toggle -V View Fit -X Flip on X_axis -Y Flip on Y_axis -~ Show Shortcut List - -Space: En(Dis)able Obj Plot -Ctrl+A Select All -Ctrl+C Copy Obj -Ctrl+E Open Excellon File -Ctrl+G Open Gerber File -Ctrl+M Measurement Tool -Ctrl+O Open Project -Ctrl+S Save Project As -Delete Delete Obj''' - - -Geometry Editor Key shortcut list: -A Add an 'Arc' -C Copy Geo Item -G Grid Snap On/Off -K Corner Snap On/Off -M Move Geo Item - -N Add an 'Polygon' -O Add a 'Circle' -P Add a 'Path' -R Add an 'Rectangle' -S Select Tool Active - - -~ Show Shortcut List -Space: Rotate Geometry -Enter: Finish Current Action -Escape: Abort Current Action -Delete: Delete Obj - -22.05.2018 - -- Added Marlin preprocessor -- Added a new entry into the Geometry and Excellon Object's UI: -Feedrate rapid: the purpose is to set a feedrate for the G0 -command that some firmwares like Marlin don't intepret as -'move with highest speed' -- FlatCAM was not making the conversion from one type of units to -another for a lot of parameters. Corrected that. -- Modified the Marlin preprocessor so it will generate the required -GCODE. - -21.05.2018 - -- added new icons for menu entries -- added shortcuts that work on the Project tab but also over -Plot. Shorcut list is accesed with shortcut key '~' sau '`' -- small GUI modification: on each "New File" command it will switch to -the Project Tab regardless on which tab we were. - -- removed the global shear entries and checkbox as they can be -damaging and it will build effect upon effect, which is not good -- solved bug in that the Edit -> Shear on X (Y)axis could adjust -only in integers. Now the angle can be adjusted in float with -3 decimals. -- changed the tile of QInputDialog to a more general one -- changed the "follow" Tcl command to the new format -- added a new entry in the Menu -> File, to open a Gerber with -the follow parameter = True -- added a new checkbox in the Gerber Object Selection Tab that -when checked it will create a "follow" geometry -- added a few lines in Mill Holes Tcl command to check if there are -promises and raise an Tcl error if there are any. -- started to modify the Export_Svg Tcl command - -20.05.2018 - -- changed the interpretation of the axis for the rotate and skew commands. -Actually I reversed them to reflect reality. -- for the rotate command a positive angle now rotates CW. It was reversed. -- added shortcuts (for outside CANVAS; the CANVAS has it's own set of shortcuts) -Ctrl+C will copy to clipboard the name of the selected object -Ctrl+A will Select All objects - -"X" key will flip the selected objects on X axis - -"Y" key will flip the selected objects on Y axis - -"R" key will rotate CW with a 45 degrees step -- changed the layout for the top of th Options page. Added a checkbox and entries -for parameters for skew command. When the checkbox is checked it will save (and -load at the next startup of the program) the option that at each CNCJob generation -(be it from Excellon or Geometry) it will perform the Skew command with the -parametrs set in the nearby field boxes (Skew X and Skey Y angles). -It is useful in case the CNC router is not perfectly alligned between the X and Y axis - -- added some protection in case the skew command receive a None parameter - -- BUG solved: made an UGLY (really UGLY) HACK so now, when there is a panel geometry -generated from GUI, the project WILL save. I had to create a copy of the generated -panel geometry and delete the original panel geometry. This way there is no complain -from JSON module about circular reference. - -Supplimentary: -- removed the Save buttons previously added on each Group in Application Defaults. -Replaced them with a single Save button that stays always on top of the Options TAB -- added settings for defaults for the Grid that are persistent -- changed the default view at FlatCAM startup: now the origin is in the center of the screen - - -19.05.2018 - -- last object that is opened (created) is always automatically selected and -the name of the object is automatically copied to clipboard; useful when -using the TCL command :) - -- added new commands in MENU -> EDIT named: "Copy Object" and -"Copy Obj as Geom". The first command will duplicate any object (Geometry, -Gerber, Excellon). -The second command will duplicate the object as a geometry. For example, -holes in Excello now are just circles that can be "painted" if one wants it. - -- added new Tool named ToolFreeformCutout. It does what it says, it will -make a board cutout from a "any shape" Gerber or Geometry file - -- solved bug in the TCL command "drillcncjob" that always used the endz -parameter value as the toolchangez parameter value and for the endz value -used a default value = 1 - -- added preprocessor name into the TCL command "drillcncjob" parameters - -- when adding a new geometry the default name is now: "New_Geometry" instead -of "New Geometry". TCL commands don't handle the spaces inside the name and -require adding quotes. - -- solved bug in "cncjob" TCL command in which it used multidepth parameter as -always True regardless of the argument provided - -- added a checkbox for Multidepth in the Options Tab -> Application Defaults - - -18.05.2018 - -- added an "Defaults" button in Excellon Defaults Group; it loads the -following configuration (Excellon_format_in 2:4, Excellon_format_mm 3:3, -Excellon_zeros LZ) -- added Save buttons for each Defaults Group; in the future more -parameters will be propagated in the app, for now they are a few -- added functions for Skew on X axis and for Skew on Y menu stubs. -Now, clicking on those Menu -> Options -> Transform Object menu entries -will trigger those functions -- added a CheckBox button in the Options Tab -> Application Defaults that control -the behaviour of the TCL shell: checking it will make the TCL shell window visible -at each start-up, unchecking it the TCL shell window will be hidden until needed -- Depth/pass parameter from Geometry Object CNC Job is now in the -defaults and it will keep it's value until changed in the Application -Defaults. - -17.05.2018 - -- added messages box for the Flip commands to show error in case there -is no object selected when the command is executed -- added field entries in the Options TAB - > Application Defaults for the -following newly introduced parameters: -excellon_format_upper_in -excellon_format_lower_in -excellon_format_upper_mm -excellon_format_lower_mm - -The ones with upper indicate how many digits are allocated for the units -and the ones with lower indicate how many digits from coordinates are -alocated for the decimals. - -[ Eg: Excellon format 2:4 in INCH - excellon_format_upper_in = 2 - excellon_format_lower_in = 4 -where the first 2 digits are for units and the last 4 digits are -decimals so from a number like 235589 we will get a coordinate 23.5589 -] - -- added Radio button in the Options TAB - > Application Defaults for the -Excellon_zeros parameter - -After each change of those parameters the user will have to press -"Save defaults" from File menu in order to propagate the new values, or -wait for the autosave to kick in (each 20sec). - -Those parameters can be set in the set_sys TCL command. - -15.05.2018 -- modified SetSys TCL command: now it can change units -- modified SetSys TCL command: now it can set new parameters: -excellon_format_mm and excellon_format_in. the first one is when the -excellon units are MM and the second is for when the excellon units are -in INCH. Those parameters can be set with a number between 1 and 5 and it -signify how many digits are before coma. -- added new GUI command in EDIT -> Select All. It will select all -objects on the first mouse click and on the second will deselect all -(toggle action) -- added new GUI commands in Options -> Transform object. Added Rotate selection, -Flip on X axis of the selection and Flip on Y axis of the selection -For the Rotate selection command, negative numbers means rotation CCW and -positive numbers means rotation CW. - -- cleaned up a bit the module imports -- worked on the excellon parsing for the case of trailing zeros. -If there are more than 6digits in the -coordinates, in case that there is no period, now the software will -identify the issue and attempt to correct it by dividing the coordinate -further by 10 for each additional digit over 6. If the number of digits -is less than 6 then the software will multiply by 10 the coordinates - -14.05.2018 - -- fixed bug in Geometry CNCJob generation that prevented generating -the object -- added GRBL 1.1 preprocessor and Laser preprocessor (adapted from -the work of MARCO A QUEZADA) - - -13.05.2018 - -- added postprocessing in correct form -- added the possibility to select an preprocessor for Excellon Object -- added a new preprocessor, manual_toolchange.py. It allows to change -the tools and adjust the drill tip to touch the surface manually, always -in the X=0, Y=0, Z = toolchangeZ coordinates. -- fixed drillcncjob TCL command by adding toolchangeZ parameter -- fixed the preprocessor file template 'default.py' in the toolchange -command section -- after I created a feature that the message in infobar is cleared by -moving mouse on canvas, it generated a bug in TCL shell: everytime -mouse was moved it will add a space into the TCL read only section. -Now this bug is fixed. -- added an EndZ parameter for the drillcncjob and cncjob TCL commands: it -will specify at what Z value to park the CNC when job ends -- the spindle will be turned on after the toolchange and it will be turned off -just before the final end move. - -Previously: -- added GRID based working of FLATCAM -- added Set Origin command -- added FilmTool, PanelizeTool GUI, MoveTool -- and others - - -24.04.2018 - -- Remade the Measurement Tool: it now ask for the Start point of the measurement and then for the Stop point. After it will display the measurement until we left click again on the canvas and so on. Previously you clicked the start point and reset the X and Y coords displayed and then you moved the mouse pointer wherever you wanted to measure, but moving the mouse from there you lost the measurement. -- Added Relative measurement on the main plot -- Now both the measuring tool and the relative measurement will work only with the left click of the mouse button because middle mouse click and right mouse click are used for panning -- Renamed the tools files starting with Tool so they are grouped (in the future they may have their own folder like for TCL Commands) - -- Commented some shortcut keys and functions for features that are not present anymore or they are planned to be in the future but unfinished (like buffer tool, paint tool) -- minor corrections regarding PEP8 (Pycharm complains about the m) -- solved bug in TclCommandsSetSys.py Everytime that the command was executed it complain about the parameter not being in the list (something like this). There was a missing “else:” -- when using the command “set_sys excellon_zeros” with parameter in lower case (either ‘l’ or ‘t’) now it is always written in the defaults file as capital letter - -- solved a bug introduced by me: when apertures macros were detected in Excellon file, FlatCam will complain about missing dictionary key “size”. Now it first check if the aperture is a macro and perform the check for zero value only for apertures with “size” key -- solved a bug that didn't allowed FC to detect if Excellon file has leading zeros or trailing zeros -- solved a bug that FC was searching for char ‘%’ that signal end of Excellon header even in commented lines (latest versions of Eagle end the commented line with a ‘%’) - - -============================================ - -This fork features: - -- Added buttons in the menu bar for opening of Gerber and Excellon files; -- Reduced number of decimals for drill bits to two decimals; -- Updated make_win32.py so it will work with cx_freeze 5.0.1 -- Added capability so FlatCAM can now read Gerber files with traces having zero value (aperture size is zero); -- Added Paint All / Seed based Paint functions from the JP's FlatCAM; -- Added Excellon move optimization (travelling salesman algorithm) cherry-picked from David Kahler: https://bitbucket.org/dakahler/flatcam -- Updated make_win32.py so it will work with cx_freeze 5.0.1 Corrected small typo in DblSidedTool.py -- Added the TCL commands in the new format. Picked from FLATCAM master. -- Hack to fix the issue with geometry not being updated after a TCL command was executed. Now after each TCL command the plot_all() function is executed and the canvas is refreshed. -- Added GUI for panelization TCL command -- Added GUI tool for the panelization TCL command: Changed some ToolTips. - - -============================================ - -Previously added features by Dennis - -- "Clear non-copper" feature, supporting multi-tool work. -- Groups in Project view. -- Pan view by dragging in visualizer window with pressed MMB. -- OpenGL-based visualizer. - +You can download all the required wheels files into a folder (e.g D:\my_folder) and install them from Command Prompt like this: +cd D:\my_folder +and for each wheel file (*.whl) run: +D:\my_folder\> pip install --upgrade package_from_requirements.whl + +Run FlatCAM beta from the installation folder (e.g D:\FlatCAM_beta) in the Command Prompt with the following command: +cd D:\FlatCAM_beta +python FlatCAM.py From c6ac6268ad05fdc6d5ea19a11206f5442a3abd1b Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 20 Apr 2020 05:38:57 +0300 Subject: [PATCH 187/209] - updated the README file --- CHANGELOG.md | 4 +++- README.md | 24 ++++++++++++++++++------ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd8f483b..74725a32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ FlatCAM BETA (c) 2019 - by Marius Stanciu -Based on FlatCAM: 2D Computer-Aided PCB Manufacturing by (c) 2014-2016 Juan Pablo Caram +Based on FlatCAM: +2D Computer-Aided PCB Manufacturing by (c) 2014-2016 Juan Pablo Caram ================================================= CHANGELOG for FlatCAM beta @@ -14,6 +15,7 @@ CHANGELOG for FlatCAM beta - added the linewidth=2 parameter for the Tool Distance utility geometry - fixed a selection issue in Legacy graphic mode for single click - added a CHANGELOG file and changed the README file to contain the installation instructions +- updated the README file 19.04.2020 diff --git a/README.md b/README.md index 265a097e..33f03121 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ FlatCAM BETA (c) 2019 - by Marius Stanciu -Based on FlatCAM: 2D Computer-Aided PCB Manufacturing by (c) 2014-2016 Juan Pablo Caram +Based on FlatCAM: +2D Computer-Aided PCB Manufacturing by (c) 2014-2016 Juan Pablo Caram ================================================= FlatCAM is a program for preparing CNC jobs for making PCBs on a CNC router. @@ -8,10 +9,14 @@ CAD program, and create G-Code for Isolation routing. ================================================= ------------- Installation instructions ------------ +------------ Installation instructions ---------- Works with Python version 3.5 or greater and PyQt5. +More on the YouTube channel: https://www.youtube.com/playlist?list=PLVvP2SYRpx-AQgNlfoxw93tXUXon7G94_ +You can contact me on my email address found in the app in: +Menu -> Help -> About FlatCAM -> Programmers -> Marius Stanciu +- Make sure that your OS is up-to-date - Download sources from: https://bitbucket.org/jpcgt/flatcam/downloads/ - Unzip them on a HDD location that your user has permissions for. @@ -20,21 +25,28 @@ Works with Python version 3.5 or greater and PyQt5. 2. Linux - make sure that Python 3.8 is installed on your OS and that the command: python3 -V confirm it +- verify that the pip package is installed for your Python installation (e.g 3.8) by running the command pip3 -V. +If it is not installed, install it. In Ubuntu-like OS's it is done like this: +sudo apt-get install python3-pip +or: +sudo apt-get install python3.8-pip - verify that the file setup_ubuntu.sh has Linux line-endings (LF) and that it is executable (chmod +x setup_ubuntu.sh) - run the file setup_ubuntu.sh and install all the dependencies with the command: ./setup_ubuntu.sh - if the previous command is successful and has no errors, run FlatCAM with the command: python3 FlatCAM.py 3. Windows -- download the provided installer (for your OS flavor 64bit or 32bit) from https://bitbucket.org/jpcgt/flatcam/downloads/ +- download the provided installer (for your OS flavor 64bit or 32bit) from: +https://bitbucket.org/jpcgt/flatcam/downloads/ - execute the installer and install the program. It is recommended to install as a Local User. -or +or from sources: - download the sources from the same location - unzip them on a safe location on your HDD that your user has permissions for - install WinPython e.g WinPython 3.8 downloaded from here: https://sourceforge.net/projects/winpython/files/WinPython_3.8/ -Use one of the versions (64bit or 32it) that are compatible with your OS. To save space use one of the versions that have the smaller size (they offer 2 versions: one with size of few hundred MB and one smaller with size of few tens of MB) +Use one of the versions (64bit or 32it) that are compatible with your OS. +To save space use one of the versions that have the smaller size (they offer 2 versions: one with size of few hundred MB and one smaller with size of few tens of MB) -- add Python folder and Python\Scripts folder to your Path (https://docs.microsoft.com/en-us/previous-versions/office/developer/sharepoint-2010/ee537574(v%3Doffice.14)) +- add Python folder and Python\Scripts folder to your Windows Path (https://docs.microsoft.com/en-us/previous-versions/office/developer/sharepoint-2010/ee537574(v%3Doffice.14)) - verify that the pip package can be run by opening Command Prompt(Admin) and running the command: pip -V - look in the requirements.txt file (found in the sources folder) and install all the dependencies using the pip package. From 3c291f259eb270ce9388aed22b73beb94f812b0d Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 20 Apr 2020 12:02:01 +0300 Subject: [PATCH 188/209] - fixed a bug in loading objects by drag&drop into the Project Tab where only one object in the selection was loaded --- CHANGELOG.md | 2 + ObjectCollection.py | 171 ++++++++++++++++++++++++++------------- flatcamGUI/FlatCAMGUI.py | 3 +- 3 files changed, 119 insertions(+), 57 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74725a32..72d64762 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ CHANGELOG for FlatCAM beta - fixed a selection issue in Legacy graphic mode for single click - added a CHANGELOG file and changed the README file to contain the installation instructions - updated the README file +- in Project Tab added tooltips for the loaded objects +- fixed a bug in loading objects by drag&drop into the Project Tab where only one object in the selection was loaded 19.04.2020 diff --git a/ObjectCollection.py b/ObjectCollection.py index 62d6304d..79a1326d 100644 --- a/ObjectCollection.py +++ b/ObjectCollection.py @@ -16,7 +16,8 @@ from PyQt5.QtCore import Qt, QSettings from PyQt5.QtGui import QColor # from PyQt5.QtCore import QModelIndex -from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry, FlatCAMExcellon, FlatCAMCNCjob, FlatCAMDocument, FlatCAMScript +from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry, FlatCAMExcellon, FlatCAMCNCjob, FlatCAMDocument, FlatCAMScript, \ + FlatCAMObj import inspect # TODO: Remove import FlatCAMApp @@ -55,6 +56,17 @@ class KeySensitiveListView(QtWidgets.QTreeView): self.filename = "" self.app = app + # Enabling Drag and Drop for the items in the Project Tab + # Example: https://github.com/d1vanov/PyQt5-reorderable-list-model/blob/master/reorderable_list_model.py + # https://github.com/jimmykuu/PyQt-PySide-Cookbook/blob/master/tree/drop_indicator.md + # self.setDragEnabled(True) + # self.viewport().setAcceptDrops(True) + # self.setDropIndicatorShown(True) + # self.DragDropMode(QtWidgets.QAbstractItemView.InternalMove) + # self.current_idx = None + # self.current_group = None + # self.dropped_obj = None + keyPressed = QtCore.pyqtSignal(int) def keyPressEvent(self, event): @@ -62,6 +74,11 @@ class KeySensitiveListView(QtWidgets.QTreeView): self.keyPressed.emit(event.key()) def dragEnterEvent(self, event): + # if event.source(): + # self.current_idx = self.currentIndex() + # self.current_group = self.model().group_items[self.current_idx.internalPointer().obj.kind] + # self.dropped_obj = self.current_idx.internalPointer().obj + if event.mimeData().hasUrls: event.accept() else: @@ -69,6 +86,7 @@ class KeySensitiveListView(QtWidgets.QTreeView): def dragMoveEvent(self, event): self.setDropIndicatorShown(True) + if event.mimeData().hasUrls: event.accept() else: @@ -77,6 +95,20 @@ class KeySensitiveListView(QtWidgets.QTreeView): def dropEvent(self, event): drop_indicator = self.dropIndicatorPosition() + # if event.source(): + # new_index = self.indexAt(event.pos()) + # new_group = self.model().group_items[new_index.internalPointer().obj.kind] + # if self.current_group == new_group: + # + # # delete it from the model + # deleted_obj_name = self.dropped_obj.options['name'] + # self.model().delete_by_name(deleted_obj_name) + # + # # add the object to the new index + # self.model().append(self.dropped_obj, to_index=new_index) + # + # return + m = event.mimeData() if m.hasUrls: event.accept() @@ -84,46 +116,46 @@ class KeySensitiveListView(QtWidgets.QTreeView): for url in m.urls(): self.filename = str(url.toLocalFile()) - # file drop from outside application - if drop_indicator == QtWidgets.QAbstractItemView.OnItem: - if self.filename == "": - self.app.inform.emit(_("Open cancelled.")) + # file drop from outside application + if drop_indicator == QtWidgets.QAbstractItemView.OnItem: + if self.filename == "": + self.app.inform.emit(_("Open cancelled.")) + else: + if self.filename.lower().rpartition('.')[-1] in self.app.grb_list: + self.app.worker_task.emit({'fcn': self.app.open_gerber, + 'params': [self.filename]}) + else: + event.ignore() + + if self.filename.lower().rpartition('.')[-1] in self.app.exc_list: + self.app.worker_task.emit({'fcn': self.app.open_excellon, + 'params': [self.filename]}) + else: + event.ignore() + + if self.filename.lower().rpartition('.')[-1] in self.app.gcode_list: + self.app.worker_task.emit({'fcn': self.app.open_gcode, + 'params': [self.filename]}) + else: + event.ignore() + + if self.filename.lower().rpartition('.')[-1] in self.app.svg_list: + object_type = 'geometry' + self.app.worker_task.emit({'fcn': self.app.import_svg, + 'params': [self.filename, object_type, None]}) + + if self.filename.lower().rpartition('.')[-1] in self.app.dxf_list: + object_type = 'geometry' + self.app.worker_task.emit({'fcn': self.app.import_dxf, + 'params': [self.filename, object_type, None]}) + + if self.filename.lower().rpartition('.')[-1] in self.app.prj_list: + # self.app.open_project() is not Thread Safe + self.app.open_project(self.filename) + else: + event.ignore() else: - if self.filename.lower().rpartition('.')[-1] in self.app.grb_list: - self.app.worker_task.emit({'fcn': self.app.open_gerber, - 'params': [self.filename]}) - else: - event.ignore() - - if self.filename.lower().rpartition('.')[-1] in self.app.exc_list: - self.app.worker_task.emit({'fcn': self.app.open_excellon, - 'params': [self.filename]}) - else: - event.ignore() - - if self.filename.lower().rpartition('.')[-1] in self.app.gcode_list: - self.app.worker_task.emit({'fcn': self.app.open_gcode, - 'params': [self.filename]}) - else: - event.ignore() - - if self.filename.lower().rpartition('.')[-1] in self.app.svg_list: - object_type = 'geometry' - self.app.worker_task.emit({'fcn': self.app.import_svg, - 'params': [self.filename, object_type, None]}) - - if self.filename.lower().rpartition('.')[-1] in self.app.dxf_list: - object_type = 'geometry' - self.app.worker_task.emit({'fcn': self.app.import_dxf, - 'params': [self.filename, object_type, None]}) - - if self.filename.lower().rpartition('.')[-1] in self.app.prj_list: - # self.app.open_project() is not Thread Safe - self.app.open_project(self.filename) - else: - event.ignore() - else: - pass + pass else: event.ignore() @@ -221,6 +253,7 @@ class ObjectCollection(QtCore.QAbstractItemModel): # will emit the name of the object that was just selected item_selected = QtCore.pyqtSignal(str) + update_list_signal = QtCore.pyqtSignal() root_item = None # app = None @@ -296,6 +329,8 @@ class ObjectCollection(QtCore.QAbstractItemModel): self.click_modifier = None + self.update_list_signal.connect(self.on_update_list_signal) + def promise(self, obj_name): FlatCAMApp.App.log.debug("Object %s has been promised." % obj_name) self.promises.add(obj_name) @@ -430,6 +465,18 @@ class ObjectCollection(QtCore.QAbstractItemModel): return icon else: return QtGui.QPixmap() + elif role == Qt.ToolTipRole: + try: + obj = index.internalPointer().obj + except AttributeError: + return None + + if obj: + text = obj.options['name'] + return text + else: + QtWidgets.QToolTip.hideText() + return None else: return None @@ -459,7 +506,10 @@ class ObjectCollection(QtCore.QAbstractItemModel): self.app.inform.emit(_("Object renamed from {old} to {new}").format(old=old_name, new=new_name)) - return True + self.dataChanged.emit(index, index) + return True + else: + return False def supportedDropActions(self): return Qt.MoveAction @@ -471,15 +521,17 @@ class ObjectCollection(QtCore.QAbstractItemModel): return Qt.ItemIsEnabled | default_flags # Prevent groups from selection - if not index.internalPointer().obj: + try: + if not index.internalPointer().obj: + return Qt.ItemIsEnabled + else: + return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable | \ + Qt.ItemIsDragEnabled | Qt.ItemIsDropEnabled + except AttributeError: return Qt.ItemIsEnabled - else: - return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable | \ - Qt.ItemIsDragEnabled | Qt.ItemIsDropEnabled - # return QtWidgets.QAbstractItemModel.flags(self, index) - def append(self, obj, active=False): + def append(self, obj, active=False, to_index=None): FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + " --> OC.append()") name = obj.options["name"] @@ -509,13 +561,19 @@ class ObjectCollection(QtCore.QAbstractItemModel): # Required before appending (Qt MVC) group = self.group_items[obj.kind] group_index = self.index(group.row(), 0, QtCore.QModelIndex()) - self.beginInsertRows(group_index, group.child_count(), group.child_count()) - # Append new item - obj.item = TreeItem(None, self.icons[obj.kind], obj, group) - - # Required after appending (Qt MVC) - self.endInsertRows() + if to_index is None: + self.beginInsertRows(group_index, group.child_count(), group.child_count()) + # Append new item + obj.item = TreeItem(None, self.icons[obj.kind], obj, group) + # Required after appending (Qt MVC) + self.endInsertRows() + else: + self.beginInsertRows(group_index, to_index.row()-1, to_index.row()-1) + # Append new item + obj.item = TreeItem(None, self.icons[obj.kind], obj, group) + # Required after appending (Qt MVC) + self.endInsertRows() # Expand group if group.child_count() == 1: @@ -671,7 +729,7 @@ class ObjectCollection(QtCore.QAbstractItemModel): # self.app.ui.code_editor.set_model_data(self.app.myKeywords) except Exception as e: log.debug( - "delete_active() --> Could not remove the old object name from auto-completer model list. %s" % str(e)) + "delete_by_name() --> Could not remove the old object name from auto-completer model list. %s" % str(e)) self.app.object_status_changed.emit(deleted.obj, 'delete', name) @@ -679,7 +737,7 @@ class ObjectCollection(QtCore.QAbstractItemModel): self.beginRemoveRows(self.index(group.row(), 0, QtCore.QModelIndex()), deleted.row(), deleted.row()) group.remove_child(deleted) # after deletion of object store the current list of objects into the self.app.all_objects_list - self.app.all_objects_list = self.get_list() + self.update_list_signal.emit() self.endRemoveRows() # ############ OBJECT DELETION FROM MODEL STOPS HERE #################### @@ -698,6 +756,9 @@ class ObjectCollection(QtCore.QAbstractItemModel): if not self.get_list(): self.app.ui.splitter.setSizes([0, 1]) + def on_update_list_signal(self): + self.app.all_objects_list = self.get_list() + def delete_all(self): FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.delete_all()") diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index 8c9f41e2..0b7c44cb 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -4163,8 +4163,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): def closeEvent(self, event): if self.app.save_in_progress: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Application is saving the project. Please wait ...")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Application is saving the project. Please wait ...")) else: grect = self.geometry() From f690c2b09d112e82029160c05594802a5d5cf494 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 22 Apr 2020 01:19:49 +0300 Subject: [PATCH 189/209] - added a new feature, project auto-saving controlled from Edit -> Preferences -> General -> APP. Preferences -> Enable Auto Save checkbox --- CHANGELOG.md | 4 +++ FlatCAMApp.py | 54 +++++++++++++++++++++++++++++++++++-- flatcamGUI/PreferencesUI.py | 46 ++++++++++++++++++++++++------- 3 files changed, 92 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72d64762..ad909e0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ CHANGELOG for FlatCAM beta ================================================= +22.04.2020 + +- added a new feature, project auto-saving controlled from Edit -> Preferences -> General -> APP. Preferences -> Enable Auto Save checkbox + 20.04.2020 - made the Grid icon in the status bar clickable and it will toggle the snap to grid function diff --git a/FlatCAMApp.py b/FlatCAMApp.py index e7d1d430..e9f4affc 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -437,6 +437,8 @@ class App(QtCore.QObject): "global_tpdf_bmargin": 10.0, "global_tpdf_lmargin": 20.0, "global_tpdf_rmargin": 20.0, + "global_autosave": False, + "global_autosave_timeout": 300000, # General "global_graphic_engine": '3D', @@ -1197,6 +1199,8 @@ class App(QtCore.QObject): "global_compression_level": self.ui.general_defaults_form.general_app_group.compress_spinner, "global_save_compressed": self.ui.general_defaults_form.general_app_group.save_type_cb, + "global_autosave": self.ui.general_defaults_form.general_app_group.autosave_cb, + "global_autosave_timeout": self.ui.general_defaults_form.general_app_group.autosave_entry, "global_tpdf_tmargin": self.ui.general_defaults_form.general_app_group.tmargin_entry, "global_tpdf_bmargin": self.ui.general_defaults_form.general_app_group.bmargin_entry, @@ -1956,6 +1960,15 @@ class App(QtCore.QObject): self.worker_task.connect(self.workers.add_task) self.log.debug("Finished creating Workers crew.") + # ############################################################################# + # ################################ AUTOSAVE SETUP ############################# + # ############################################################################# + + self.block_autosave = False + self.autosave_timer = QtCore.QTimer(self) + self.save_project_auto_update() + self.autosave_timer.timeout.connect(self.save_project_auto) + # ############################################################################# # ################################# Activity Monitor ########################## # ############################################################################# @@ -5161,6 +5174,9 @@ class App(QtCore.QObject): if not silent: self.inform.emit('[success] %s' % _("Preferences saved.")) + # update the autosave timer + self.save_project_auto_update() + def save_toolbar_view(self): """ Will save the toolbar view state to the defaults @@ -11651,6 +11667,9 @@ class App(QtCore.QObject): """ App.log.debug("Opening project: " + filename) + # block autosaving while a project is loaded + self.block_autosave = True + # for some reason, setting ui_title does not work when this method is called from Tcl Shell # it's because the TclCommand is run in another thread (it inherit TclCommandSignaled) if cli is None: @@ -11739,6 +11758,9 @@ class App(QtCore.QObject): self.should_we_save = False self.file_opened.emit("project", filename) + # restore autosaving after a project was loaded + self.block_autosave = False + # for some reason, setting ui_title does not work when this method is called from Tcl Shell # it's because the TclCommand is run in another thread (it inherit TclCommandSignaled) if cli is None: @@ -12920,8 +12942,7 @@ class App(QtCore.QObject): if silent is False: if 'version' in saved_d: - self.inform.emit('[success] %s: %s' % - (_("Project saved to"), filename)) + self.inform.emit('[success] %s: %s' % (_("Project saved to"), filename)) else: self.inform.emit('[ERROR_NOTCL] %s: %s %s' % (_("Failed to parse saved project file"), filename, _("Retry to save it."))) @@ -12969,7 +12990,36 @@ class App(QtCore.QObject): except Exception: traceback.print_exc() + def save_project_auto(self): + """ + Called periodically to save the project. + It will save if there is no block on the save, if the project was saved at least once and if there is no save in + # progress. + + :return: + """ + + if self.block_autosave is False and self.should_we_save is True and self.save_in_progress is False: + self.on_file_saveproject() + + def save_project_auto_update(self): + """ + Update the auto save time interval value. + :return: + """ + log.debug("App.save_project_auto_update() --> updated the interval timeout.") + if self.autosave_timer.isActive(): + self.autosave_timer.stop() + if self.defaults['global_autosave'] is True: + self.autosave_timer.setInterval(int(self.defaults['global_autosave_timeout'])) + self.autosave_timer.start() + def on_plotarea_tab_closed(self, tab_idx): + """ + + :param tab_idx: Index of the Tab from the plotarea that was closed + :return: + """ widget = self.ui.plot_tab_area.widget(tab_idx) if widget is not None: diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index d8659eeb..8ad23154 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -1818,16 +1818,42 @@ class GeneralAppPrefGroupUI(OptionsGroupUI): self.proj_ois = OptionalInputSection(self.save_type_cb, [self.compress_label, self.compress_spinner], True) + # Auto save CB + self.autosave_cb = FCCheckBox(_('Enable Auto Save')) + self.autosave_cb.setToolTip( + _("Check to enable the autosave feature.\n" + "When enabled, the application will try to save a project\n" + "at the set interval.") + ) + + grid0.addWidget(self.autosave_cb, 31, 0, 1, 2) + + # Auto Save Timeout Interval + self.autosave_entry = FCSpinner() + self.autosave_entry.set_range(0, 9999999) + self.autosave_label = QtWidgets.QLabel('%s:' % _('Interval')) + self.autosave_label.setToolTip( + _("Time interval for autosaving. In milliseconds.\n" + "The application will try to save periodically but only\n" + "if the project was saved manually at least once.\n" + "While active, some operations may block this feature.") + ) + + grid0.addWidget(self.autosave_label, 32, 0) + grid0.addWidget(self.autosave_entry, 32, 1) + + # self.as_ois = OptionalInputSection(self.autosave_cb, [self.autosave_label, self.autosave_entry], True) + separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - grid0.addWidget(separator_line, 31, 0, 1, 2) + grid0.addWidget(separator_line, 33, 0, 1, 2) self.pdf_param_label = QtWidgets.QLabel('%s:' % _("Text to PDF parameters")) self.pdf_param_label.setToolTip( _("Used when saving text in Code Editor or in FlatCAM Document objects.") ) - grid0.addWidget(self.pdf_param_label, 32, 0, 1, 2) + grid0.addWidget(self.pdf_param_label, 34, 0, 1, 2) # Top Margin value self.tmargin_entry = FCDoubleSpinner() @@ -1839,8 +1865,8 @@ class GeneralAppPrefGroupUI(OptionsGroupUI): _("Distance between text body and the top of the PDF file.") ) - grid0.addWidget(self.tmargin_label, 33, 0) - grid0.addWidget(self.tmargin_entry, 33, 1) + grid0.addWidget(self.tmargin_label, 35, 0) + grid0.addWidget(self.tmargin_entry, 35, 1) # Bottom Margin value self.bmargin_entry = FCDoubleSpinner() @@ -1852,8 +1878,8 @@ class GeneralAppPrefGroupUI(OptionsGroupUI): _("Distance between text body and the bottom of the PDF file.") ) - grid0.addWidget(self.bmargin_label, 34, 0) - grid0.addWidget(self.bmargin_entry, 34, 1) + grid0.addWidget(self.bmargin_label, 36, 0) + grid0.addWidget(self.bmargin_entry, 36, 1) # Left Margin value self.lmargin_entry = FCDoubleSpinner() @@ -1865,8 +1891,8 @@ class GeneralAppPrefGroupUI(OptionsGroupUI): _("Distance between text body and the left of the PDF file.") ) - grid0.addWidget(self.lmargin_label, 35, 0) - grid0.addWidget(self.lmargin_entry, 35, 1) + grid0.addWidget(self.lmargin_label, 37, 0) + grid0.addWidget(self.lmargin_entry, 37, 1) # Right Margin value self.rmargin_entry = FCDoubleSpinner() @@ -1878,8 +1904,8 @@ class GeneralAppPrefGroupUI(OptionsGroupUI): _("Distance between text body and the right of the PDF file.") ) - grid0.addWidget(self.rmargin_label, 36, 0) - grid0.addWidget(self.rmargin_entry, 36, 1) + grid0.addWidget(self.rmargin_label, 38, 0) + grid0.addWidget(self.rmargin_entry, 38, 1) self.layout.addStretch() From 66d9ddd40227e7bce03ee146d335c436a899f991 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 22 Apr 2020 14:37:03 +0300 Subject: [PATCH 190/209] - fixed some bugs in the Tcl Commands - modified the Tcl Commands to be able to use as boolean values keywords with lower case like 'false' instead of expected 'False' --- CHANGELOG.md | 2 + tclCommands/TclCommandBbox.py | 11 ++- tclCommands/TclCommandCncjob.py | 6 +- tclCommands/TclCommandCopperClear.py | 108 +++++++++++++-------------- tclCommands/TclCommandDelete.py | 6 +- tclCommands/TclCommandDrillcncjob.py | 6 +- tclCommands/TclCommandIsolate.py | 8 +- tclCommands/TclCommandMillDrills.py | 6 +- tclCommands/TclCommandMillSlots.py | 6 +- tclCommands/TclCommandNregions.py | 11 ++- tclCommands/TclCommandPaint.py | 86 +++++++++++---------- tclCommands/TclCommandPanelize.py | 12 ++- tclCommands/TclCommandPlotAll.py | 22 ++++-- tclCommands/TclCommandWriteGCode.py | 8 +- 14 files changed, 178 insertions(+), 120 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad909e0c..823be59e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ CHANGELOG for FlatCAM beta 22.04.2020 - added a new feature, project auto-saving controlled from Edit -> Preferences -> General -> APP. Preferences -> Enable Auto Save checkbox +- fixed some bugs in the Tcl Commands +- modified the Tcl Commands to be able to use as boolean values keywords with lower case like 'false' instead of expected 'False' 20.04.2020 diff --git a/tclCommands/TclCommandBbox.py b/tclCommands/TclCommandBbox.py index dd6ab627..ada78b4f 100644 --- a/tclCommands/TclCommandBbox.py +++ b/tclCommands/TclCommandBbox.py @@ -79,9 +79,14 @@ class TclCommandBbox(TclCommand): args['margin'] = float(self.app.defaults["gerber_bboxmargin"]) margin = args['margin'] - if 'rounded' not in args: - args['rounded'] = bool(eval(self.app.defaults["gerber_bboxrounded"])) - rounded = bool(eval(args['rounded'])) + if 'rounded' in args: + try: + par = args['rounded'].capitalize() + except AttributeError: + par = args['rounded'] + rounded = bool(eval(par)) + else: + rounded = bool(eval(self.app.defaults["gerber_bboxrounded"])) del args['name'] diff --git a/tclCommands/TclCommandCncjob.py b/tclCommands/TclCommandCncjob.py index 6f41e1df..0c897654 100644 --- a/tclCommands/TclCommandCncjob.py +++ b/tclCommands/TclCommandCncjob.py @@ -92,7 +92,11 @@ class TclCommandCncjob(TclCommandSignaled): name = '' if 'muted' in args: - muted = bool(eval(args['muted'])) + try: + par = args['muted'].capitalize() + except AttributeError: + par = args['muted'] + muted = bool(eval(par)) else: muted = False diff --git a/tclCommands/TclCommandCopperClear.py b/tclCommands/TclCommandCopperClear.py index 62eeb19e..29c73cd5 100644 --- a/tclCommands/TclCommandCopperClear.py +++ b/tclCommands/TclCommandCopperClear.py @@ -38,7 +38,6 @@ class TclCommandCopperClear(TclCommand): ('method', str), ('connect', str), ('contour', str), - ('has_offset', str), ('offset', float), ('rest', str), ('all', int), @@ -69,15 +68,13 @@ class TclCommandCopperClear(TclCommand): ('connect', 'Draw lines to minimize tool lifts. True (1) or False (0)'), ('contour', 'Cut around the perimeter of the painting. True (1) or False (0)'), ('rest', 'Use rest-machining. True (1) or False (0)'), - ('has_offset', 'The offset will used only if this is set True or present in args. True (1) or False (0).'), - ('offset', 'The copper clearing will finish to a distance from copper features. Float number.'), - ('all', 'Will copper clear the whole object. 1 or True = enabled, anything else = disabled'), - ('ref', 'Will clear of extra copper all polygons within a specified object with the name in "box" ' - 'parameter. 1 or True = enabled, 0 or False = disabled'), - ('box', 'Name of the object to be used as reference. Required when selecting "ref" = 1 or True. String.'), + ('offset', 'If used, the copper clearing will finish to a distance from copper features. Float number.'), + ('all', 'If used will copper clear the whole object. Either "-all" or "-box " has to be used.'), + ('box', 'Name of the object to be used as reference. Either "-all" or "-box " has to be used. ' + 'String.'), ('outname', 'Name of the resulting Geometry object. String.'), ]), - 'examples': ["ncc obj_name -tooldia 0.3,1 -overlap 10 -margin 1.0 -method 'lines' -all True"] + 'examples': ["ncc obj_name -tooldia 0.3,1 -overlap 10 -margin 1.0 -method 'lines' -all"] } def execute(self, args, unnamed_args): @@ -129,24 +126,27 @@ class TclCommandCopperClear(TclCommand): method = str(self.app.defaults["tools_nccmethod"]) if 'connect' in args: - connect = bool(eval(args['connect'])) + try: + par = args['connect'].capitalize() + except AttributeError: + par = args['connect'] + connect = bool(eval(par)) else: connect = bool(eval(str(self.app.defaults["tools_nccconnect"]))) if 'contour' in args: - contour = bool(eval(args['contour'])) + try: + par = args['contour'].capitalize() + except AttributeError: + par = args['contour'] + contour = bool(eval(par)) else: contour = bool(eval(str(self.app.defaults["tools_ncccontour"]))) offset = 0.0 - if 'has_offset' in args: - has_offset = bool(eval(args['has_offset'])) - if args['has_offset'] is True: - if 'offset' in args: - offset = float(args['margin']) - else: - # 'offset' has to be in args if 'has_offset' is and it is set True - self.raise_tcl_error("%s: %s" % (_("Could not retrieve object"), name)) + if 'offset' in args: + offset = float(args['offset']) + has_offset = True else: has_offset = False @@ -208,7 +208,11 @@ class TclCommandCopperClear(TclCommand): }) if 'rest' in args: - rest = bool(eval(args['rest'])) + try: + par = args['rest'].capitalize() + except AttributeError: + par = args['rest'] + rest = bool(eval(par)) else: rest = bool(eval(str(self.app.defaults["tools_nccrest"]))) @@ -221,7 +225,7 @@ class TclCommandCopperClear(TclCommand): outname = name + "_ncc_rm" # Non-Copper clear all polygons in the non-copper clear object - if 'all' in args and bool(args['all']): + if 'all' in args: self.app.ncclear_tool.clear_copper_tcl(ncc_obj=obj, select_method='itself', ncctooldia=tooldia, @@ -241,40 +245,36 @@ class TclCommandCopperClear(TclCommand): return # Non-Copper clear all polygons found within the box object from the the non_copper cleared object - elif 'ref' in args and bool(eval(args['ref'])): - if 'box' not in args: - self.raise_tcl_error('%s' % _("Expected -box .")) - else: - box_name = args['box'] + if 'box' in args: + box_name = args['box'] - # Get box source object. - try: - box_obj = self.app.collection.get_by_name(str(box_name)) - except Exception as e: - log.debug("TclCommandCopperClear.execute() --> %s" % str(e)) - self.raise_tcl_error("%s: %s" % (_("Could not retrieve box object"), name)) - return "Could not retrieve object: %s" % name + # Get box source object. + try: + box_obj = self.app.collection.get_by_name(str(box_name)) + except Exception as e: + log.debug("TclCommandCopperClear.execute() --> %s" % str(e)) + self.raise_tcl_error("%s: %s" % (_("Could not retrieve box object"), name)) + return "Could not retrieve object: %s" % name - self.app.ncclear_tool.clear_copper_tcl(ncc_obj=obj, - sel_obj=box_obj, - select_method='box', - ncctooldia=tooldia, - overlap=overlap, - order=order, - margin=margin, - has_offset=has_offset, - offset=offset, - method=method, - outname=outname, - connect=connect, - contour=contour, - rest=rest, - tools_storage=ncc_tools, - plot=False, - run_threaded=False) + self.app.ncclear_tool.clear_copper_tcl(ncc_obj=obj, + sel_obj=box_obj, + select_method='box', + ncctooldia=tooldia, + overlap=overlap, + order=order, + margin=margin, + has_offset=has_offset, + offset=offset, + method=method, + outname=outname, + connect=connect, + contour=contour, + rest=rest, + tools_storage=ncc_tools, + plot=False, + run_threaded=False) return - else: - self.raise_tcl_error("%s:" % _("None of the following args: 'ref', 'all' were found or none was set to 1.\n" - "Copper clearing failed.")) - return "None of the following args: 'ref', 'all' were found or none was set to 1.\n" \ - "Copper clearing failed." + + # if the program reached this then it's an error because neither -all or -box was used. + self.raise_tcl_error('%s' % _("Expected either -box or -all.")) + return "Expected either -box or -all. Copper clearing failed." diff --git a/tclCommands/TclCommandDelete.py b/tclCommands/TclCommandDelete.py index 339a1120..1d8a71c1 100644 --- a/tclCommands/TclCommandDelete.py +++ b/tclCommands/TclCommandDelete.py @@ -65,7 +65,11 @@ class TclCommandDelete(TclCommand): if args['f'] is None: is_forced = True else: - is_forced = True if bool(eval(str(args['f']))) else False + try: + par = args['f'].capitalize() + except AttributeError: + par = args['f'] + is_forced = bool(eval(par)) except KeyError: is_forced = True diff --git a/tclCommands/TclCommandDrillcncjob.py b/tclCommands/TclCommandDrillcncjob.py index d2f31021..fb114e1e 100644 --- a/tclCommands/TclCommandDrillcncjob.py +++ b/tclCommands/TclCommandDrillcncjob.py @@ -111,7 +111,11 @@ class TclCommandDrillcncjob(TclCommandSignaled): args['outname'] = name + "_cnc" if 'muted' in args: - muted = bool(eval(args['muted'])) + try: + par = args['muted'].capitalize() + except AttributeError: + par = args['muted'] + muted = bool(eval(par)) else: muted = False diff --git a/tclCommands/TclCommandIsolate.py b/tclCommands/TclCommandIsolate.py index 9fc4d214..9c1b874e 100644 --- a/tclCommands/TclCommandIsolate.py +++ b/tclCommands/TclCommandIsolate.py @@ -83,8 +83,12 @@ class TclCommandIsolate(TclCommandSignaled): args['follow'] = None # evaluate this parameter so True, False, 0 and 1 works - if "combine" in args: - args['combine'] = bool(eval(args['combine'])) + if 'combine' in args: + try: + par = args['combine'].capitalize() + except AttributeError: + par = args['combine'] + args['combine'] = bool(eval(par)) else: args['combine'] = bool(eval(self.app.defaults["gerber_combine_passes"])) diff --git a/tclCommands/TclCommandMillDrills.py b/tclCommands/TclCommandMillDrills.py index e4e3df07..c68117f1 100644 --- a/tclCommands/TclCommandMillDrills.py +++ b/tclCommands/TclCommandMillDrills.py @@ -86,7 +86,11 @@ class TclCommandMillDrills(TclCommandSignaled): args['outname'] = name + "_mill_drills" if 'use_thread' in args: - args['use_thread'] = bool(eval(args['use_thread'])) + try: + par = args['use_thread'].capitalize() + except AttributeError: + par = args['use_thread'] + args['use_thread'] = bool(eval(par)) else: args['use_thread'] = False diff --git a/tclCommands/TclCommandMillSlots.py b/tclCommands/TclCommandMillSlots.py index 7d6b1f0c..74c06659 100644 --- a/tclCommands/TclCommandMillSlots.py +++ b/tclCommands/TclCommandMillSlots.py @@ -86,7 +86,11 @@ class TclCommandMillSlots(TclCommandSignaled): args['outname'] = name + "_mill_slots" if 'use_thread' in args: - args['use_thread'] = bool(eval(args['use_thread'])) + try: + par = args['use_thread'].capitalize() + except AttributeError: + par = args['use_thread'] + args['use_thread'] = bool(eval(par)) else: args['use_thread'] = False diff --git a/tclCommands/TclCommandNregions.py b/tclCommands/TclCommandNregions.py index f4b2a228..871db83c 100644 --- a/tclCommands/TclCommandNregions.py +++ b/tclCommands/TclCommandNregions.py @@ -78,9 +78,14 @@ class TclCommandNregions(TclCommand): args['margin'] = float(self.app.defaults["gerber_noncoppermargin"]) margin = float(args['margin']) - if 'rounded' not in args: - args['rounded'] = self.app.defaults["gerber_noncopperrounded"] - rounded = bool(eval(args['rounded'])) + if 'rounded' in args: + try: + par = args['rounded'].capitalize() + except AttributeError: + par = args['rounded'] + rounded = bool(eval(par)) + else: + rounded = bool(eval(self.app.defaults["gerber_noncopperrounded"])) del args['name'] diff --git a/tclCommands/TclCommandPaint.py b/tclCommands/TclCommandPaint.py index d0b099be..7e54e1c6 100644 --- a/tclCommands/TclCommandPaint.py +++ b/tclCommands/TclCommandPaint.py @@ -69,16 +69,14 @@ class TclCommandPaint(TclCommand): ('method', 'Algorithm for painting. Can be: "standard", "seed" or "lines".'), ('connect', 'Draw lines to minimize tool lifts. True (1) or False (0)'), ('contour', 'Cut around the perimeter of the painting. True (1) or False (0)'), - ('all', 'Paint all polygons in the object. True (1) or False (0)'), + ('all', 'If used, paint all polygons in the object.'), + ('box', 'name of the object to be used as paint reference. String.'), ('single', 'Paint a single polygon specified by "x" and "y" parameters. True (1) or False (0)'), - ('ref', 'Paint all polygons within a specified object with the name in "box" parameter. ' - 'True (1) or False (0)'), - ('box', 'name of the object to be used as paint reference when selecting "ref"" True. String.'), ('x', 'X value of coordinate for the selection of a single polygon. Float number.'), ('y', 'Y value of coordinate for the selection of a single polygon. Float number.'), ('outname', 'Name of the resulting Geometry object. String.'), ]), - 'examples': ["paint obj_name -tooldia 0.3 -margin 0.1 -method 'seed' -all True"] + 'examples': ["paint obj_name -tooldia 0.3 -margin 0.1 -method 'seed' -all"] } def execute(self, args, unnamed_args): @@ -127,14 +125,22 @@ class TclCommandPaint(TclCommand): method = str(self.app.defaults["tools_paintmethod"]) if 'connect' in args: - connect = bool(eval(args['connect'])) + try: + par = args['connect'].capitalize() + except AttributeError: + par = args['connect'] + connect = bool(eval(par)) else: - connect = eval(str(self.app.defaults["tools_pathconnect"])) + connect = bool(eval(str(self.app.defaults["tools_pathconnect"]))) if 'contour' in args: - contour = bool(eval(args['contour'])) + try: + par = args['contour'].capitalize() + except AttributeError: + par = args['contour'] + contour = bool(eval(par)) else: - contour = eval(str(self.app.defaults["tools_paintcontour"])) + contour = bool(eval(str(self.app.defaults["tools_paintcontour"]))) if 'outname' in args: outname = args['outname'] @@ -202,7 +208,7 @@ class TclCommandPaint(TclCommand): return "Object not found: %s" % name # Paint all polygons in the painted object - if 'all' in args and bool(eval(args['all'])) is True: + if 'all' in args: self.app.paint_tool.paint_poly_all(obj=obj, tooldia=tooldia, overlap=overlap, @@ -218,8 +224,8 @@ class TclCommandPaint(TclCommand): return # Paint single polygon in the painted object - elif 'single' in args and bool(eval(args['single'])) is True: - if 'x' not in args or 'y' not in args: + if 'single' in args: + if 'x' not in args and 'y' not in args: self.raise_tcl_error('%s' % _("Expected -x and -y .")) else: x = args['x'] @@ -241,37 +247,35 @@ class TclCommandPaint(TclCommand): return # Paint all polygons found within the box object from the the painted object - elif 'ref' in args and bool(eval(args['ref'])) is True: - if 'box' not in args: + if 'box' in args: + box_name = args['box'] + + if box_name is None: self.raise_tcl_error('%s' % _("Expected -box .")) - else: - box_name = args['box'] - # Get box source object. - try: - box_obj = self.app.collection.get_by_name(str(box_name)) - except Exception as e: - log.debug("TclCommandPaint.execute() --> %s" % str(e)) - self.raise_tcl_error("%s: %s" % (_("Could not retrieve box object"), name)) - return "Could not retrieve object: %s" % name + # Get box source object. + try: + box_obj = self.app.collection.get_by_name(str(box_name)) + except Exception as e: + log.debug("TclCommandPaint.execute() --> %s" % str(e)) + self.raise_tcl_error("%s: %s" % (_("Could not retrieve box object"), name)) + return "Could not retrieve object: %s" % name - self.app.paint_tool.paint_poly_ref(obj=obj, - sel_obj=box_obj, - tooldia=tooldia, - overlap=overlap, - order=order, - margin=margin, - method=method, - outname=outname, - connect=connect, - contour=contour, - tools_storage=paint_tools, - plot=False, - run_threaded=False) + self.app.paint_tool.paint_poly_ref(obj=obj, + sel_obj=box_obj, + tooldia=tooldia, + overlap=overlap, + order=order, + margin=margin, + method=method, + outname=outname, + connect=connect, + contour=contour, + tools_storage=paint_tools, + plot=False, + run_threaded=False) return - else: - self.raise_tcl_error("%s:" % _("There was none of the following args: 'ref', 'single', 'all'.\n" - "Paint failed.")) - return "There was none of the following args: 'ref', 'single', 'all'.\n" \ - "Paint failed." + self.raise_tcl_error("%s:" % _("None of the following args: 'box', 'single', 'all' were used.\n" + "Paint failed.")) + return "None of the following args: 'box', 'single', 'all' were used. Paint failed." diff --git a/tclCommands/TclCommandPanelize.py b/tclCommands/TclCommandPanelize.py index e2c64dbc..142c1512 100644 --- a/tclCommands/TclCommandPanelize.py +++ b/tclCommands/TclCommandPanelize.py @@ -37,7 +37,7 @@ class TclCommandPanelize(TclCommand): ('spacing_rows', float), ('box', str), ('outname', str), - ('run_threaded', str) + ('use_thread', str) ]) # array of mandatory options for current Tcl command: required = {'name','outname'} @@ -55,7 +55,7 @@ class TclCommandPanelize(TclCommand): ('columns', 'Number of columns.'), ('rows', 'Number of rows;'), ('outname', 'Name of the new geometry object.'), - ('run_threaded', 'False (0) = non-threaded execution or True (1) = threaded execution') + ('use_thread', 'False (0) = non-threaded execution or True (1) = threaded execution') ]), 'examples': [ 'panelize obj_name', @@ -113,8 +113,12 @@ class TclCommandPanelize(TclCommand): else: outname = name + '_panelized' - if 'run_threaded' in args: - threaded = bool(eval(args['run_threaded'])) + if 'use_thread' in args: + try: + par = args['use_thread'].capitalize() + except AttributeError: + par = args['use_thread'] + threaded = bool(eval(par)) else: threaded = False diff --git a/tclCommands/TclCommandPlotAll.py b/tclCommands/TclCommandPlotAll.py index 53da1e8f..4e9f8277 100644 --- a/tclCommands/TclCommandPlotAll.py +++ b/tclCommands/TclCommandPlotAll.py @@ -49,17 +49,27 @@ class TclCommandPlotAll(TclCommandSignaled): """ if 'use_thread' in args: - threaded = bool(eval(args['use_thread'])) + try: + par = args['use_thread'].capitalize() + except AttributeError: + par = args['use_thread'] + threaded = bool(eval(par)) else: threaded = False + plot_status = True if 'plot_status' in args: - if args['plot_status'] is None: + try: + if args['plot_status'] is None: + plot_status = True + else: + try: + par = args['plot_status'].capitalize() + except AttributeError: + par = args['plot_status'] + plot_status = bool(eval(par)) + except KeyError: plot_status = True - else: - plot_status = bool(eval(args['plot_status'])) - else: - plot_status = True for obj in self.app.collection.get_list(): obj.options["plot"] = True if plot_status is True else False diff --git a/tclCommands/TclCommandWriteGCode.py b/tclCommands/TclCommandWriteGCode.py index b96fdfd8..85b83627 100644 --- a/tclCommands/TclCommandWriteGCode.py +++ b/tclCommands/TclCommandWriteGCode.py @@ -69,11 +69,15 @@ class TclCommandWriteGCode(TclCommandSignaled): postamble = args['postamble'] if 'postamble' in args else '' if 'muted' in args: - muted = bool(eval(args['muted'])) + try: + par = args['muted'].capitalize() + except AttributeError: + par = args['muted'] + muted = bool(eval(par)) else: muted = False - # TODO: This is not needed any more? All targets should be present. + # This is not needed any more? All targets should be present. # If there are promised objects, wait until all promises have been fulfilled. # if self.collection.has_promises(): # def write_gcode_on_object(new_object): From a1499158c257c95b95e407df5caf2770955b042a Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 22 Apr 2020 23:00:54 +0300 Subject: [PATCH 191/209] - refactored some of the code in the App class and created a new Tcl Command named Help --- CHANGELOG.md | 1 + FlatCAMApp.py | 737 ++++++++++++++-------------------- FlatCAMTool.py | 8 + flatcamGUI/FlatCAMGUI.py | 25 +- flatcamTools/ToolDblSided.py | 2 +- flatcamTools/ToolShell.py | 100 ++++- flatcamTools/ToolTransform.py | 14 +- tclCommands/TclCommand.py | 3 +- tclCommands/TclCommandHelp.py | 119 ++++++ tclCommands/__init__.py | 1 + 10 files changed, 551 insertions(+), 459 deletions(-) create mode 100644 tclCommands/TclCommandHelp.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 823be59e..00e3a33b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ CHANGELOG for FlatCAM beta - added a new feature, project auto-saving controlled from Edit -> Preferences -> General -> APP. Preferences -> Enable Auto Save checkbox - fixed some bugs in the Tcl Commands - modified the Tcl Commands to be able to use as boolean values keywords with lower case like 'false' instead of expected 'False' +- refactored some of the code in the App class and created a new Tcl Command named Help 20.04.2020 diff --git a/FlatCAMApp.py b/FlatCAMApp.py index e9f4affc..2b6e0cee 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -2556,6 +2556,9 @@ class App(QtCore.QObject): # this will hold the TCL instance self.tcl = None + # the actual variable will be redeclared in setup_tcl() + self.tcl_commands_storage = None + self.init_tcl() self.shell = FCShell(self, version=self.version) @@ -2566,14 +2569,7 @@ class App(QtCore.QObject): self.shell.append_output("FlatCAM %s - " % self.version) self.shell.append_output(_("Type >help< to get started\n\n")) - self.ui.shell_dock = QtWidgets.QDockWidget("FlatCAM TCL Shell") - self.ui.shell_dock.setObjectName('Shell_DockWidget') self.ui.shell_dock.setWidget(self.shell) - self.ui.shell_dock.setAllowedAreas(QtCore.Qt.AllDockWidgetAreas) - self.ui.shell_dock.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable | - QtWidgets.QDockWidget.DockWidgetFloatable | - QtWidgets.QDockWidget.DockWidgetClosable) - self.ui.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.ui.shell_dock) # show TCL shell at start-up based on the Menu -? Edit -> Preferences setting. if self.defaults["global_shell_at_startup"]: @@ -2883,7 +2879,7 @@ class App(QtCore.QObject): # if there are Windows paths then replace the path separator with a Unix like one if sys.platform == 'win32': command_tcl_formatted = command_tcl_formatted.replace('\\', '/') - self.shell._sysShell.exec_command(command_tcl_formatted, no_echo=True) + self.shell.exec_command(command_tcl_formatted, no_echo=True) except Exception as ext: print("ERROR: ", ext) sys.exit(2) @@ -2903,9 +2899,9 @@ class App(QtCore.QObject): # color=QtGui.QColor("gray")) cmd_line_shellfile_text = myfile.read() if self.cmd_line_headless != 1: - self.shell._sysShell.exec_command(cmd_line_shellfile_text) + self.shell.exec_command(cmd_line_shellfile_text) else: - self.shell._sysShell.exec_command(cmd_line_shellfile_text, no_echo=True) + self.shell.exec_command(cmd_line_shellfile_text, no_echo=True) except Exception as ext: print("ERROR: ", ext) @@ -3703,209 +3699,6 @@ class App(QtCore.QObject): else: self.defaults['global_stats'][resource] = 1 - def init_tcl(self): - """ - Initialize the TCL Shell. A dock widget that holds the GUI interface to the FlatCAM command line. - :return: None - """ - if hasattr(self, 'tcl') and self.tcl is not None: - # self.tcl = None - # TODO we need to clean non default variables and procedures here - # new object cannot be used here as it will not remember values created for next passes, - # because tcl was execudted in old instance of TCL - pass - else: - self.tcl = tk.Tcl() - self.setup_shell() - self.log.debug("TCL Shell has been initialized.") - - # TODO: This shouldn't be here. - class TclErrorException(Exception): - """ - this exception is defined here, to be able catch it if we successfully handle all errors from shell command - """ - pass - - def shell_message(self, msg, show=False, error=False, warning=False, success=False, selected=False): - """ - Shows a message on the FlatCAM Shell - - :param msg: Message to display. - :param show: Opens the shell. - :param error: Shows the message as an error. - :param warning: Shows the message as an warning. - :param success: Shows the message as an success. - :param selected: Indicate that something was selected on canvas - :return: None - """ - if show: - self.ui.shell_dock.show() - try: - if error: - self.shell.append_error(msg + "\n") - elif warning: - self.shell.append_warning(msg + "\n") - elif success: - self.shell.append_success(msg + "\n") - elif selected: - self.shell.append_selected(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)) - - def raise_tcl_unknown_error(self, unknownException): - """ - Raise exception if is different type than TclErrorException - this is here mainly to show unknown errors inside TCL shell console. - - :param unknownException: - :return: - """ - - if not isinstance(unknownException, self.TclErrorException): - self.raise_tcl_error("Unknown error: %s" % str(unknownException)) - else: - raise unknownException - - def display_tcl_error(self, error, error_info=None): - """ - Escape bracket [ with '\' otherwise there is error - "ERROR: missing close-bracket" instead of real error - - :param error: it may be text or exception - :param error_info: Some informations about the error - :return: None - """ - - if isinstance(error, Exception): - exc_type, exc_value, exc_traceback = error_info - if not isinstance(error, self.TclErrorException): - show_trace = 1 - else: - show_trace = int(self.defaults['global_verbose_error_level']) - - if show_trace > 0: - trc = traceback.format_list(traceback.extract_tb(exc_traceback)) - trc_formated = [] - for a in reversed(trc): - trc_formated.append(a.replace(" ", " > ").replace("\n", "")) - text = "%s\nPython traceback: %s\n%s" % (exc_value, exc_type, "\n".join(trc_formated)) - else: - text = "%s" % error - else: - text = error - - text = text.replace('[', '\\[').replace('"', '\\"') - self.tcl.eval('return -code error "%s"' % text) - - def raise_tcl_error(self, text): - """ - This method pass exception from python into TCL as error, so we get stacktrace and reason - - :param text: text of error - :return: raise exception - """ - - self.display_tcl_error(text) - raise self.TclErrorException(text) - - def exec_command(self, text, no_echo=False): - """ - Handles input from the shell. See FlatCAMApp.setup_shell for shell commands. - Also handles execution in separated threads - - :param text: FlatCAM TclCommand with parameters - :param no_echo: If True it will not try to print to the Shell because most likely the shell is hidden and it - will create crashes of the _Expandable_Edit widget - :return: output if there was any - """ - - self.report_usage('exec_command') - - result = self.exec_command_test(text, False, no_echo=no_echo) - - # MS: added this method call so the geometry is updated once the TCL command is executed - # if no_plot is None: - # self.plot_all() - - return result - - def exec_command_test(self, text, reraise=True, no_echo=False): - """ - Same as exec_command(...) with additional control over exceptions. - Handles input from the shell. See FlatCAMApp.setup_shell for shell commands. - - :param text: Input command - :param reraise: Re-raise TclError exceptions in Python (mostly for unittests). - :param no_echo: If True it will not try to print to the Shell because most likely the shell is hidden and it - will create crashes of the _Expandable_Edit widget - :return: Output from the command - """ - - tcl_command_string = str(text) - - try: - if no_echo is False: - self.shell.open_processing() # Disables input box. - - result = self.tcl.eval(str(tcl_command_string)) - if result != 'None' and no_echo is False: - self.shell.append_output(result + '\n') - - except tk.TclError as e: - - # This will display more precise answer if something in TCL shell fails - result = self.tcl.eval("set errorInfo") - self.log.error("Exec command Exception: %s" % (result + '\n')) - if no_echo is False: - self.shell.append_error('ERROR: ' + result + '\n') - # Show error in console and just return or in test raise exception - if reraise: - raise e - finally: - if no_echo is False: - self.shell.close_processing() - pass - return result - - # """ - # Code below is unsused. Saved for later. - # """ - - # parts = re.findall(r'([\w\\:\.]+|".*?")+', text) - # parts = [p.replace('\n', '').replace('"', '') for p in parts] - # self.log.debug(parts) - # try: - # if parts[0] not in commands: - # self.shell.append_error("Unknown command\n") - # return - # - # #import inspect - # #inspect.getargspec(someMethod) - # if (type(commands[parts[0]]["params"]) is not list and len(parts)-1 != commands[parts[0]]["params"]) or \ - # (type(commands[parts[0]]["params"]) is list and len(parts)-1 not in commands[parts[0]]["params"]): - # self.shell.append_error( - # "Command %s takes %d arguments. %d given.\n" % - # (parts[0], commands[parts[0]]["params"], len(parts)-1) - # ) - # return - # - # cmdfcn = commands[parts[0]]["fcn"] - # cmdconv = commands[parts[0]]["converters"] - # if len(parts) - 1 > 0: - # retval = cmdfcn(*[cmdconv[i](parts[i + 1]) for i in range(len(parts)-1)]) - # else: - # retval = cmdfcn() - # retfcn = commands[parts[0]]["retfcn"] - # if retval and retfcn(retval): - # self.shell.append_output(retfcn(retval) + "\n") - # - # except Exception as e: - # #self.shell.append_error(''.join(traceback.format_exc())) - # #self.shell.append_error("?\n") - # self.shell.append_error(str(e) + "\n") - def info(self, msg): """ Informs the user. Normally on the status bar, optionally @@ -10464,9 +10257,9 @@ class App(QtCore.QObject): with open(filename, "r") as tcl_script: cmd_line_shellfile_content = tcl_script.read() if self.cmd_line_headless != 1: - self.shell._sysShell.exec_command(cmd_line_shellfile_content) + self.shell.exec_command(cmd_line_shellfile_content) else: - self.shell._sysShell.exec_command(cmd_line_shellfile_content, no_echo=True) + self.shell.exec_command(cmd_line_shellfile_content, no_echo=True) if silent is False: self.inform.emit('[success] %s' % _("TCL script file opened in Code Editor and executed.")) @@ -11865,231 +11658,6 @@ class App(QtCore.QObject): """ self.ui.progress_bar.setValue(int(percentage)) - def setup_shell(self): - """ - Creates shell functions. Runs once at startup. - - :return: None - """ - - self.log.debug("setup_shell()") - - def shelp(p=None): - if not p: - cmd_enum = _("Available commands:\n") - - displayed_text = [] - try: - # find the maximum length of a command name - max_len = 0 - for cmd_name in commands: - curr_len = len(cmd_name) - if curr_len > max_len: - max_len = curr_len - max_tabs = math.ceil(max_len / 8) - - for cmd_name in sorted(commands): - cmd_description = commands[cmd_name]['description'] - - curr_len = len(cmd_name) - tabs = '\t' - - # make sure to add the right number of tabs (1 tab = 8 spaces) so all the commands - # descriptions are aligned - if curr_len == max_len: - cmd_line_txt = ' %s%s%s' % (str(cmd_name), tabs, cmd_description) - else: - nr_tabs = 0 - - for x in range(max_tabs): - if curr_len <= (x*8): - nr_tabs += 1 - - # nr_tabs = 2 if curr_len <= 8 else 1 - cmd_line_txt = ' %s%s%s' % (str(cmd_name), nr_tabs*tabs, cmd_description) - - displayed_text.append(cmd_line_txt) - except Exception as err: - log.debug("App.setup_shell.shelp() when run as 'help' --> %s" % str(err)) - displayed_text = [' %s' % cmd for cmd in sorted(commands)] - - cmd_enum += '\n'.join(displayed_text) - cmd_enum += '\n\n%s\n%s' % (_("Type help for usage."), _("Example: help open_gerber")) - return cmd_enum - - if p not in commands: - return "Unknown command: %s" % p - - return commands[p]["help"] - - # --- Migrated to new architecture --- - # def options(name): - # ops = self.collection.get_by_name(str(name)).options - # return '\n'.join(["%s: %s" % (o, ops[o]) for o in ops]) - - def h(*args): - """ - Pre-processes arguments to detect '-keyword value' pairs into dictionary - and standalone parameters into list. - """ - - kwa = {} - a = [] - n = len(args) - name = None - for i in range(n): - match = re.search(r'^-([a-zA-Z].*)', args[i]) - if match: - assert name is None - name = match.group(1) - continue - - if name is None: - a.append(args[i]) - else: - kwa[name] = args[i] - name = None - - return a, kwa - - @contextmanager - def wait_signal(signal, timeout=10000): - """ - Block loop until signal emitted, timeout (ms) elapses - or unhandled exception happens in a thread. - - :param timeout: time after which the loop is exited - :param signal: Signal to wait for. - """ - loop = QtCore.QEventLoop() - - # Normal termination - signal.connect(loop.quit) - - # Termination by exception in thread - self.thread_exception.connect(loop.quit) - - status = {'timed_out': False} - - def report_quit(): - status['timed_out'] = True - loop.quit() - - yield - - # Temporarily change how exceptions are managed. - oeh = sys.excepthook - ex = [] - - def except_hook(type_, value, traceback_): - ex.append(value) - oeh(type_, value, traceback_) - sys.excepthook = except_hook - - # Terminate on timeout - if timeout is not None: - QtCore.QTimer.singleShot(timeout, report_quit) - - # # ## Block ## ## - loop.exec_() - - # Restore exception management - sys.excepthook = oeh - if ex: - self.raiseTclError(str(ex[0])) - - if status['timed_out']: - raise Exception('Timed out!') - - def make_docs(): - output = '' - import collections - od = collections.OrderedDict(sorted(commands.items())) - for cmd_, val in od.items(): - output += cmd_ + ' \n' + ''.join(['~'] * len(cmd_)) + '\n' - - t = val['help'] - usage_i = t.find('>') - if usage_i < 0: - expl = t - output += expl + '\n\n' - continue - - expl = t[:usage_i - 1] - output += expl + '\n\n' - - end_usage_i = t[usage_i:].find('\n') - - if end_usage_i < 0: - end_usage_i = len(t[usage_i:]) - output += ' ' + t[usage_i:] + '\n No parameters.\n' - else: - extras = t[usage_i+end_usage_i+1:] - parts = [s.strip() for s in extras.split('\n')] - - output += ' ' + t[usage_i:usage_i+end_usage_i] + '\n' - for p in parts: - output += ' ' + p + '\n\n' - - return output - - ''' - Howto implement TCL shell commands: - - All parameters passed to command should be possible to set as None and test it afterwards. - This is because we need to see error caused in tcl, - if None value as default parameter is not allowed TCL will return empty error. - Use: - def mycommand(name=None,...): - - Test it like this: - if name is None: - - self.raise_tcl_error('Argument name is missing.') - - When error ocurre, always use raise_tcl_error, never return "sometext" on error, - otherwise we will miss it and processing will silently continue. - Method raise_tcl_error pass error into TCL interpreter, then raise python exception, - which is catched in exec_command and displayed in TCL shell console with red background. - Error in console is displayed with TCL trace. - - This behavior works only within main thread, - errors with promissed tasks can be catched and detected only with log. - TODO: this problem have to be addressed somehow, maybe rewrite promissing to be blocking somehow for - TCL shell. - - Kamil's comment: I will rewrite existing TCL commands from time to time to follow this rules. - - ''' - - commands = { - 'help': { - 'fcn': shelp, - 'help': _("Shows list of commands."), - 'description': '' - }, - } - - # Import/overwrite tcl commands as objects of TclCommand descendants - # This modifies the variable 'commands'. - tclCommands.register_all_commands(self, commands) - - # Add commands to the tcl interpreter - for cmd in commands: - self.tcl.createcommand(cmd, commands[cmd]['fcn']) - - # Make the tcl puts function return instead of print to stdout - self.tcl.eval(''' - rename puts original_puts - proc puts {args} { - if {[llength $args] == 1} { - return "[lindex $args 0]" - } else { - eval original_puts $args - } - } - ''') - def setup_recent_items(self): """ Setup a dictionary with the recent files accessed, organized by type @@ -13040,6 +12608,295 @@ class App(QtCore.QObject): self.options.update(self.defaults) # self.options_write_form() + def init_tcl(self): + """ + Initialize the TCL Shell. A dock widget that holds the GUI interface to the FlatCAM command line. + :return: None + """ + if hasattr(self, 'tcl') and self.tcl is not None: + # self.tcl = None + # TODO we need to clean non default variables and procedures here + # new object cannot be used here as it will not remember values created for next passes, + # because tcl was execudted in old instance of TCL + pass + else: + self.tcl = tk.Tcl() + self.setup_shell() + self.log.debug("TCL Shell has been initialized.") + + def setup_shell(self): + """ + Creates shell functions. Runs once at startup. + + :return: None + """ + + self.log.debug("setup_shell()") + + def shelp(p=None): + pass + + # --- Migrated to new architecture --- + # def options(name): + # ops = self.collection.get_by_name(str(name)).options + # return '\n'.join(["%s: %s" % (o, ops[o]) for o in ops]) + + def h(*args): + """ + Pre-processes arguments to detect '-keyword value' pairs into dictionary + and standalone parameters into list. + """ + + kwa = {} + a = [] + n = len(args) + name = None + for i in range(n): + match = re.search(r'^-([a-zA-Z].*)', args[i]) + if match: + assert name is None + name = match.group(1) + continue + + if name is None: + a.append(args[i]) + else: + kwa[name] = args[i] + name = None + + return a, kwa + + @contextmanager + def wait_signal(signal, timeout=10000): + """ + Block loop until signal emitted, timeout (ms) elapses + or unhandled exception happens in a thread. + + :param timeout: time after which the loop is exited + :param signal: Signal to wait for. + """ + loop = QtCore.QEventLoop() + + # Normal termination + signal.connect(loop.quit) + + # Termination by exception in thread + self.thread_exception.connect(loop.quit) + + status = {'timed_out': False} + + def report_quit(): + status['timed_out'] = True + loop.quit() + + yield + + # Temporarily change how exceptions are managed. + oeh = sys.excepthook + ex = [] + + def except_hook(type_, value, traceback_): + ex.append(value) + oeh(type_, value, traceback_) + + sys.excepthook = except_hook + + # Terminate on timeout + if timeout is not None: + QtCore.QTimer.singleShot(timeout, report_quit) + + # # ## Block ## ## + loop.exec_() + + # Restore exception management + sys.excepthook = oeh + if ex: + self.raise_tcl_error(str(ex[0])) + + if status['timed_out']: + raise Exception('Timed out!') + + def make_docs(): + output = '' + import collections + od = collections.OrderedDict(sorted(self.tcl_commands_storage.items())) + for cmd_, val in od.items(): + output += cmd_ + ' \n' + ''.join(['~'] * len(cmd_)) + '\n' + + t = val['help'] + usage_i = t.find('>') + if usage_i < 0: + expl = t + output += expl + '\n\n' + continue + + expl = t[:usage_i - 1] + output += expl + '\n\n' + + end_usage_i = t[usage_i:].find('\n') + + if end_usage_i < 0: + end_usage_i = len(t[usage_i:]) + output += ' ' + t[usage_i:] + '\n No parameters.\n' + else: + extras = t[usage_i + end_usage_i + 1:] + parts = [s.strip() for s in extras.split('\n')] + + output += ' ' + t[usage_i:usage_i + end_usage_i] + '\n' + for p in parts: + output += ' ' + p + '\n\n' + + return output + + ''' + Howto implement TCL shell commands: + + All parameters passed to command should be possible to set as None and test it afterwards. + This is because we need to see error caused in tcl, + if None value as default parameter is not allowed TCL will return empty error. + Use: + def mycommand(name=None,...): + + Test it like this: + if name is None: + + self.raise_tcl_error('Argument name is missing.') + + When error ocurre, always use raise_tcl_error, never return "sometext" on error, + otherwise we will miss it and processing will silently continue. + Method raise_tcl_error pass error into TCL interpreter, then raise python exception, + which is catched in exec_command and displayed in TCL shell console with red background. + Error in console is displayed with TCL trace. + + This behavior works only within main thread, + errors with promissed tasks can be catched and detected only with log. + TODO: this problem have to be addressed somehow, maybe rewrite promissing to be blocking somehow for + TCL shell. + + Kamil's comment: I will rewrite existing TCL commands from time to time to follow this rules. + + ''' + + self.tcl_commands_storage = {} + # commands = { + # 'help': { + # 'fcn': shelp, + # 'help': _("Shows list of commands."), + # 'description': '' + # }, + # } + + # Import/overwrite tcl commands as objects of TclCommand descendants + # This modifies the variable 'commands'. + tclCommands.register_all_commands(self, self.tcl_commands_storage) + + # Add commands to the tcl interpreter + for cmd in self.tcl_commands_storage: + self.tcl.createcommand(cmd, self.tcl_commands_storage[cmd]['fcn']) + + # Make the tcl puts function return instead of print to stdout + self.tcl.eval(''' + rename puts original_puts + proc puts {args} { + if {[llength $args] == 1} { + return "[lindex $args 0]" + } else { + eval original_puts $args + } + } + ''') + + # TODO: This shouldn't be here. + class TclErrorException(Exception): + """ + this exception is defined here, to be able catch it if we successfully handle all errors from shell command + """ + pass + + def shell_message(self, msg, show=False, error=False, warning=False, success=False, selected=False): + """ + Shows a message on the FlatCAM Shell + + :param msg: Message to display. + :param show: Opens the shell. + :param error: Shows the message as an error. + :param warning: Shows the message as an warning. + :param success: Shows the message as an success. + :param selected: Indicate that something was selected on canvas + :return: None + """ + if show: + self.ui.shell_dock.show() + try: + if error: + self.shell.append_error(msg + "\n") + elif warning: + self.shell.append_warning(msg + "\n") + elif success: + self.shell.append_success(msg + "\n") + elif selected: + self.shell.append_selected(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)) + + def raise_tcl_unknown_error(self, unknownException): + """ + Raise exception if is different type than TclErrorException + this is here mainly to show unknown errors inside TCL shell console. + + :param unknownException: + :return: + """ + + if not isinstance(unknownException, self.TclErrorException): + self.raise_tcl_error("Unknown error: %s" % str(unknownException)) + else: + raise unknownException + + def display_tcl_error(self, error, error_info=None): + """ + Escape bracket [ with '\' otherwise there is error + "ERROR: missing close-bracket" instead of real error + + :param error: it may be text or exception + :param error_info: Some informations about the error + :return: None + """ + + if isinstance(error, Exception): + exc_type, exc_value, exc_traceback = error_info + if not isinstance(error, self.TclErrorException): + show_trace = 1 + else: + show_trace = int(self.defaults['global_verbose_error_level']) + + if show_trace > 0: + trc = traceback.format_list(traceback.extract_tb(exc_traceback)) + trc_formated = [] + for a in reversed(trc): + trc_formated.append(a.replace(" ", " > ").replace("\n", "")) + text = "%s\nPython traceback: %s\n%s" % (exc_value, exc_type, "\n".join(trc_formated)) + else: + text = "%s" % error + else: + text = error + + text = text.replace('[', '\\[').replace('"', '\\"') + self.tcl.eval('return -code error "%s"' % text) + + def raise_tcl_error(self, text): + """ + This method pass exception from python into TCL as error, so we get stacktrace and reason + + :param text: text of error + :return: raise exception + """ + + self.display_tcl_error(text) + raise self.TclErrorException(text) + class ArgsThread(QtCore.QObject): open_signal = pyqtSignal(list) diff --git a/FlatCAMTool.py b/FlatCAMTool.py index 3343c06c..3b7f8d0f 100644 --- a/FlatCAMTool.py +++ b/FlatCAMTool.py @@ -252,3 +252,11 @@ class FlatCAMTool(QtWidgets.QWidget): (_("Edited value is out of range"), minval, maxval)) else: self.app.inform.emit('[success] %s' % _("Edited value is within limits.")) + + def sizeHint(self): + """ + I've overloaded this just in case I will need to make changes in the future to enforce dimensions + :return: + """ + default_hint_size = super(FlatCAMTool, self).sizeHint() + return QtCore.QSize(default_hint_size.width(), default_hint_size.height()) diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index 0b7c44cb..ded1d7c2 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -42,13 +42,24 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # Divine icon pack by Ipapun @ finicons.com - # ################################## ## - # ## BUILDING THE GUI IS DONE HERE # ## - # ################################## ## + # ####################################################################### + # ############ BUILDING THE GUI IS EXECUTED HERE ######################## + # ####################################################################### - # ######### ## - # ## Menu # ## - # ######### ## + # ####################################################################### + # ####################### TCL Shell DOCK ################################ + # ####################################################################### + self.shell_dock = QtWidgets.QDockWidget("FlatCAM TCL Shell") + self.shell_dock.setObjectName('Shell_DockWidget') + self.shell_dock.setAllowedAreas(QtCore.Qt.AllDockWidgetAreas) + self.shell_dock.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable | + QtWidgets.QDockWidget.DockWidgetFloatable | + QtWidgets.QDockWidget.DockWidgetClosable) + self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.shell_dock) + + # ####################################################################### + # ###################### Menu BUILDING ################################## + # ####################################################################### self.menu = self.menuBar() self.menu_toggle_nb = QtWidgets.QAction( @@ -735,7 +746,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # ######################################################################## # IMPORTANT # - # The order: SPITTER -> NOTEBOOK -> SNAP TOOLBAR is important and without it the GUI will not be initialized as + # The order: SPLITTER -> NOTEBOOK -> SNAP TOOLBAR is important and without it the GUI will not be initialized as # desired. self.splitter = QtWidgets.QSplitter() self.setCentralWidget(self.splitter) diff --git a/flatcamTools/ToolDblSided.py b/flatcamTools/ToolDblSided.py index 50ca4632..202e9d98 100644 --- a/flatcamTools/ToolDblSided.py +++ b/flatcamTools/ToolDblSided.py @@ -159,7 +159,7 @@ class DblSidedTool(FlatCAMTool): self.param_label = QtWidgets.QLabel("%s:" % _("Mirror Parameters")) self.param_label.setToolTip('%s.' % _("Parameters for the mirror operation")) - grid_lay1.addWidget(self.param_label, 0, 0, 1, 3) + grid_lay1.addWidget(self.param_label, 0, 0, 1, 2) # ## Axis self.mirax_label = QtWidgets.QLabel('%s:' % _("Mirror Axis")) diff --git a/flatcamTools/ToolShell.py b/flatcamTools/ToolShell.py index 92c3f45c..78f328d5 100644 --- a/flatcamTools/ToolShell.py +++ b/flatcamTools/ToolShell.py @@ -14,6 +14,8 @@ from flatcamGUI.GUIElements import _BrowserTextEdit, _ExpandableTextEdit import html import sys +import tkinter as tk + import gettext import FlatCAMTranslation as fcTranslate import builtins @@ -227,6 +229,12 @@ class TermWidget(QWidget): class FCShell(TermWidget): def __init__(self, sysShell, version, *args): + """ + + :param sysShell: When instantiated the sysShell will be actually the FlatCAMApp.App() class + :param version: FlatCAM version string + :param args: Parameters passed to the TermWidget parent class + """ TermWidget.__init__(self, version, *args) self._sysShell = sysShell @@ -246,4 +254,94 @@ class FCShell(TermWidget): return True def child_exec_command(self, text): - self._sysShell.exec_command(text) + self.exec_command(text) + + def exec_command(self, text, no_echo=False): + """ + Handles input from the shell. See FlatCAMApp.setup_shell for shell commands. + Also handles execution in separated threads + + :param text: FlatCAM TclCommand with parameters + :param no_echo: If True it will not try to print to the Shell because most likely the shell is hidden and it + will create crashes of the _Expandable_Edit widget + :return: output if there was any + """ + + self._sysShell.report_usage('exec_command') + + return self.exec_command_test(text, False, no_echo=no_echo) + + def exec_command_test(self, text, reraise=True, no_echo=False): + """ + Same as exec_command(...) with additional control over exceptions. + Handles input from the shell. See FlatCAMApp.setup_shell for shell commands. + + :param text: Input command + :param reraise: Re-raise TclError exceptions in Python (mostly for unittests). + :param no_echo: If True it will not try to print to the Shell because most likely the shell is hidden and it + will create crashes of the _Expandable_Edit widget + :return: Output from the command + """ + + tcl_command_string = str(text) + + try: + if no_echo is False: + self.open_processing() # Disables input box. + + result = self._sysShell.tcl.eval(str(tcl_command_string)) + if result != 'None' and no_echo is False: + self.append_output(result + '\n') + + except tk.TclError as e: + + # This will display more precise answer if something in TCL shell fails + result = self._sysShell.tcl.eval("set errorInfo") + self._sysShell.log.error("Exec command Exception: %s" % (result + '\n')) + if no_echo is False: + self.append_error('ERROR: ' + result + '\n') + # Show error in console and just return or in test raise exception + if reraise: + raise e + finally: + if no_echo is False: + self.close_processing() + pass + return result + + # """ + # Code below is unsused. Saved for later. + # """ + + # parts = re.findall(r'([\w\\:\.]+|".*?")+', text) + # parts = [p.replace('\n', '').replace('"', '') for p in parts] + # self.log.debug(parts) + # try: + # if parts[0] not in commands: + # self.shell.append_error("Unknown command\n") + # return + # + # #import inspect + # #inspect.getargspec(someMethod) + # if (type(commands[parts[0]]["params"]) is not list and len(parts)-1 != commands[parts[0]]["params"]) or \ + # (type(commands[parts[0]]["params"]) is list and len(parts)-1 not in commands[parts[0]]["params"]): + # self.shell.append_error( + # "Command %s takes %d arguments. %d given.\n" % + # (parts[0], commands[parts[0]]["params"], len(parts)-1) + # ) + # return + # + # cmdfcn = commands[parts[0]]["fcn"] + # cmdconv = commands[parts[0]]["converters"] + # if len(parts) - 1 > 0: + # retval = cmdfcn(*[cmdconv[i](parts[i + 1]) for i in range(len(parts)-1)]) + # else: + # retval = cmdfcn() + # retfcn = commands[parts[0]]["retfcn"] + # if retval and retfcn(retval): + # self.shell.append_output(retfcn(retval) + "\n") + # + # except Exception as e: + # #self.shell.append_error(''.join(traceback.format_exc())) + # #self.shell.append_error("?\n") + # self.shell.append_error(str(e) + "\n") diff --git a/flatcamTools/ToolTransform.py b/flatcamTools/ToolTransform.py index 69a1189b..416de316 100644 --- a/flatcamTools/ToolTransform.py +++ b/flatcamTools/ToolTransform.py @@ -33,8 +33,6 @@ class ToolTransform(FlatCAMTool): FlatCAMTool.__init__(self, app) self.decimals = self.app.decimals - self.transform_lay = QtWidgets.QVBoxLayout() - self.layout.addLayout(self.transform_lay) # ## Title title_label = QtWidgets.QLabel("%s" % self.toolName) title_label.setStyleSheet(""" @@ -44,12 +42,12 @@ class ToolTransform(FlatCAMTool): font-weight: bold; } """) - self.transform_lay.addWidget(title_label) - self.transform_lay.addWidget(QtWidgets.QLabel('')) + self.layout.addWidget(title_label) + self.layout.addWidget(QtWidgets.QLabel('')) # ## Layout grid0 = QtWidgets.QGridLayout() - self.transform_lay.addLayout(grid0) + self.layout.addLayout(grid0) grid0.setColumnStretch(0, 0) grid0.setColumnStretch(1, 1) grid0.setColumnStretch(2, 0) @@ -206,7 +204,7 @@ class ToolTransform(FlatCAMTool): self.ois_scale = OptionalInputSection(self.scale_link_cb, [self.scaley_entry, self.scaley_button], logic=False) grid0.addWidget(self.scale_link_cb, 10, 0) - grid0.addWidget(self.scale_zero_ref_cb, 10, 1) + grid0.addWidget(self.scale_zero_ref_cb, 10, 1, 1, 2) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) @@ -395,7 +393,7 @@ class ToolTransform(FlatCAMTool): grid0.addWidget(QtWidgets.QLabel(''), 26, 0, 1, 3) - self.transform_lay.addStretch() + self.layout.addStretch() # ## Reset Tool self.reset_button = QtWidgets.QPushButton(_("Reset Tool")) @@ -408,7 +406,7 @@ class ToolTransform(FlatCAMTool): font-weight: bold; } """) - self.transform_lay.addWidget(self.reset_button) + self.layout.addWidget(self.reset_button) # ## Signals self.rotate_button.clicked.connect(self.on_rotate) diff --git a/tclCommands/TclCommand.py b/tclCommands/TclCommand.py index 9971eeaf..72bb48c5 100644 --- a/tclCommands/TclCommand.py +++ b/tclCommands/TclCommand.py @@ -3,8 +3,7 @@ import re import FlatCAMApp import abc import collections -from PyQt5 import QtCore, QtGui -from PyQt5.QtCore import Qt +from PyQt5 import QtCore from contextlib import contextmanager diff --git a/tclCommands/TclCommandHelp.py b/tclCommands/TclCommandHelp.py new file mode 100644 index 00000000..a1af436e --- /dev/null +++ b/tclCommands/TclCommandHelp.py @@ -0,0 +1,119 @@ +# ########################################################## +# FlatCAM: 2D Post-processing for Manufacturing # +# File Author: Marius Adrian Stanciu (c) # +# Content was borrowed from FlatCAM proper # +# Date: 4/22/2020 # +# MIT Licence # +# ########################################################## + +from tclCommands.TclCommand import TclCommand + +import collections +import math + +import gettext +import FlatCAMTranslation as fcTranslate +import builtins + +fcTranslate.apply_language('strings') +if '_' not in builtins.__dict__: + _ = gettext.gettext + + +class TclCommandHelp(TclCommand): + """ + Tcl shell command to get the value of a system variable + + example: + get_sys excellon_zeros + """ + + # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) + aliases = ['help'] + + description = '%s %s' % ("--", "PRINTS to TCL the HELP.") + + # Dictionary of types from Tcl command, needs to be ordered + arg_names = collections.OrderedDict([ + ('name', str) + ]) + + # Dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value + option_types = collections.OrderedDict([ + + ]) + + # array of mandatory options for current Tcl command: required = {'name','outname'} + required = [] + + # structured help for current command, args needs to be ordered + help = { + 'main': "Returns to TCL the value for the entered system variable.", + 'args': collections.OrderedDict([ + ('name', 'Name of a Tcl Command for which to display the Help.'), + ]), + 'examples': ['help add_circle'] + } + + def execute(self, args, unnamed_args): + """ + + :param args: + :param unnamed_args: + :return: + """ + print(self.app.tcl_commands_storage) + + if 'name' in args: + name = args['name'] + if name not in self.app.tcl_commands_storage: + return "Unknown command: %s" % name + + print(self.app.tcl_commands_storage[name]["help"]) + else: + if args is None: + cmd_enum = _("Available commands:\n") + + displayed_text = [] + try: + # find the maximum length of a command name + max_len = 0 + for cmd_name in self.app.tcl_commands_storage: + curr_len = len(cmd_name) + if curr_len > max_len: + max_len = curr_len + max_tabs = math.ceil(max_len / 8) + + for cmd_name in sorted(self.app.tcl_commands_storage): + cmd_description = self.app.tcl_commands_storage[cmd_name]['description'] + + curr_len = len(cmd_name) + tabs = '\t' + + cmd_name_colored = "" + cmd_name_colored += str(cmd_name) + cmd_name_colored += "" + + # make sure to add the right number of tabs (1 tab = 8 spaces) so all the commands + # descriptions are aligned + if curr_len == max_len: + cmd_line_txt = ' %s%s%s' % (cmd_name_colored, tabs, cmd_description) + else: + nr_tabs = 0 + + for x in range(max_tabs): + if curr_len <= (x * 8): + nr_tabs += 1 + + # nr_tabs = 2 if curr_len <= 8 else 1 + cmd_line_txt = ' %s%s%s' % (cmd_name_colored, nr_tabs * tabs, cmd_description) + + displayed_text.append(cmd_line_txt) + except Exception as err: + self.app.log.debug("App.setup_shell.shelp() when run as 'help' --> %s" % str(err)) + displayed_text = [' %s' % cmd for cmd in sorted(self.app.tcl_commands_storage)] + + cmd_enum += '\n'.join(displayed_text) + cmd_enum += '\n\n%s\n%s' % (_("Type help for usage."), _("Example: help open_gerber")) + + print(cmd_enum) \ No newline at end of file diff --git a/tclCommands/__init__.py b/tclCommands/__init__.py index e34cd733..9a5b22cf 100644 --- a/tclCommands/__init__.py +++ b/tclCommands/__init__.py @@ -93,6 +93,7 @@ def register_all_commands(app, commands): tcl_modules = {k: v for k, v in list(sys.modules.items()) if k.startswith('tclCommands.TclCommand')} for key, mod in list(tcl_modules.items()): + print(key) if key != 'tclCommands.TclCommand': class_name = key.split('.')[1] class_type = getattr(mod, class_name) From 3735753a93809c1da90ed0125634166e903363c4 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 23 Apr 2020 02:07:55 +0300 Subject: [PATCH 192/209] - fixed the Tcl Command Help to work as expected; made the text of the commands to be colored in Red color and bold - added a 'Close' menu entry in the Tcl Shell context menu that will close (hide) the Tcl Shell Dock widget - on launching the Tcl Shell the Edit line will take focus immediately - in App.on_mouse_move_over_plot() method no longer will be done a setFocus() on every move, only when it is needed --- CHANGELOG.md | 7 +++ FlatCAMApp.py | 86 +++++++++++++++++++++-------------- flatcamGUI/FlatCAMGUI.py | 2 +- flatcamGUI/GUIElements.py | 9 +++- flatcamTools/ToolShell.py | 32 +++++++++---- tclCommands/TclCommandHelp.py | 30 ++++++------ tclCommands/__init__.py | 3 +- 7 files changed, 105 insertions(+), 64 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00e3a33b..617a38d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ CHANGELOG for FlatCAM beta ================================================= +23.04.2020 + +- fixed the Tcl Command Help to work as expected; made the text of the commands to be colored in Red color and bold +- added a 'Close' menu entry in the Tcl Shell context menu that will close (hide) the Tcl Shell Dock widget +- on launching the Tcl Shell the Edit line will take focus immediately +- in App.on_mouse_move_over_plot() method no longer will be done a setFocus() on every move, only when it is needed + 22.04.2020 - added a new feature, project auto-saving controlled from Edit -> Preferences -> General -> APP. Preferences -> Enable Auto Save checkbox diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 2b6e0cee..d366afa8 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -2105,7 +2105,7 @@ class App(QtCore.QObject): self.ui.menuview_toggle_axis.triggered.connect(self.on_toggle_axis) self.ui.menuview_toggle_workspace.triggered.connect(self.on_workspace_toggle) - self.ui.menutoolshell.triggered.connect(self.on_toggle_shell) + self.ui.menutoolshell.triggered.connect(self.toggle_shell) self.ui.menuhelp_about.triggered.connect(self.on_about) self.ui.menuhelp_manual.triggered.connect(lambda: webbrowser.open(self.manual_url)) @@ -3326,7 +3326,7 @@ class App(QtCore.QObject): # re-add the TCL Shell action to the Tools menu and reconnect it to ist slot function self.ui.menutoolshell = self.ui.menutool.addAction(QtGui.QIcon(self.resource_location + '/shell16.png'), '&Command Line\tS') - self.ui.menutoolshell.triggered.connect(self.on_toggle_shell) + self.ui.menutoolshell.triggered.connect(self.toggle_shell) # third install all of them try: @@ -3377,7 +3377,7 @@ class App(QtCore.QObject): self.ui.jmp_btn.triggered.connect(self.on_jump_to) self.ui.locate_btn.triggered.connect(lambda: self.on_locate(obj=self.collection.get_active())) - self.ui.shell_btn.triggered.connect(self.on_toggle_shell) + self.ui.shell_btn.triggered.connect(self.toggle_shell) self.ui.new_script_btn.triggered.connect(self.on_filenewscript) self.ui.open_script_btn.triggered.connect(self.on_fileopenscript) self.ui.run_script_btn.triggered.connect(self.on_filerunscript) @@ -5173,7 +5173,7 @@ class App(QtCore.QObject): # When the main event loop is not started yet in which case the qApp.quit() will do nothing # we use the following command # sys.exit(0) - os._exit(0) # fix to work with Python 3.8 + os._exit(0) # fix to work with Python 3.8 def kill_app(self): # QtCore.QCoreApplication.quit() @@ -5274,34 +5274,6 @@ class App(QtCore.QObject): with open(config_file, 'w') as f: f.writelines(data) - def on_toggle_shell(self): - """ - Toggle shell: if is visible close it, if it is closed then open it - :return: None - """ - - self.report_usage("on_toggle_shell()") - - if self.ui.shell_dock.isVisible(): - self.ui.shell_dock.hide() - else: - self.ui.shell_dock.show() - - def on_toggle_shell_from_settings(self, state): - """ - Toggle shell: if is visible close it, if it is closed then open it - :return: None - """ - - self.report_usage("on_toggle_shell_from_settings()") - - if state is True: - if not self.ui.shell_dock.isVisible(): - self.ui.shell_dock.show() - else: - if self.ui.shell_dock.isVisible(): - self.ui.shell_dock.hide() - def on_register_files(self, obj_type=None): """ Called whenever there is a need to register file extensions with FlatCAM. @@ -8601,8 +8573,11 @@ class App(QtCore.QObject): pan_button = 2 self.event_is_dragging = self.plotcanvas.is_dragging - # So it can receive key presses - self.plotcanvas.native.setFocus() + # So it can receive key presses but not when the Tcl Shell is active + if not self.ui.shell_dock.isVisible(): + if not self.plotcanvas.native.hasFocus(): + self.plotcanvas.native.setFocus() + self.pos_jump = event_pos self.ui.popMenu.mouse_is_panning = False @@ -12813,6 +12788,49 @@ class App(QtCore.QObject): """ pass + def toggle_shell(self): + """ + Toggle shell: if is visible close it, if it is closed then open it + :return: None + """ + + self.report_usage("toggle_shell()") + + if self.ui.shell_dock.isVisible(): + self.ui.shell_dock.hide() + self.plotcanvas.native.setFocus() + else: + self.ui.shell_dock.show() + + # I want to take the focus and give it to the Tcl Shell when the Tcl Shell is run + # self.shell._edit.setFocus() + QtCore.QTimer.singleShot(0, lambda: self.ui.shell_dock.widget()._edit.setFocus()) + + # HACK - simulate a mouse click - alternative + # no_km = QtCore.Qt.KeyboardModifier(QtCore.Qt.NoModifier) # no KB modifier + # pos = QtCore.QPoint((self.shell._edit.width() - 40), (self.shell._edit.height() - 2)) + # e = QtGui.QMouseEvent(QtCore.QEvent.MouseButtonPress, pos, QtCore.Qt.LeftButton, QtCore.Qt.LeftButton, + # no_km) + # QtWidgets.qApp.sendEvent(self.shell._edit, e) + # f = QtGui.QMouseEvent(QtCore.QEvent.MouseButtonRelease, pos, QtCore.Qt.LeftButton, QtCore.Qt.LeftButton, + # no_km) + # QtWidgets.qApp.sendEvent(self.shell._edit, f) + + def on_toggle_shell_from_settings(self, state): + """ + Toggle shell: if is visible close it, if it is closed then open it + :return: None + """ + + self.report_usage("on_toggle_shell_from_settings()") + + if state is True: + if not self.ui.shell_dock.isVisible(): + self.ui.shell_dock.show() + else: + if self.ui.shell_dock.isVisible(): + self.ui.shell_dock.hide() + def shell_message(self, msg, show=False, error=False, warning=False, success=False, selected=False): """ Shows a message on the FlatCAM Shell diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index ded1d7c2..6f1fe86e 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -3247,7 +3247,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # Shell toggle if key == QtCore.Qt.Key_S: - self.app.on_toggle_shell() + self.app.toggle_shell() # Add a Tool from shortcut if key == QtCore.Qt.Key_T: diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index 94fa88e2..0b243456 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -2560,10 +2560,11 @@ class DialogBoxRadio(QtWidgets.QDialog): class _BrowserTextEdit(QTextEdit): - def __init__(self, version): + def __init__(self, version, app=None): QTextEdit.__init__(self) self.menu = None self.version = version + self.app = app def contextMenuEvent(self, event): self.menu = self.createStandardContextMenu(event.pos()) @@ -2571,6 +2572,12 @@ class _BrowserTextEdit(QTextEdit): clear_action.setShortcut(QKeySequence(Qt.Key_Delete)) # it's not working, the shortcut self.menu.addAction(clear_action) clear_action.triggered.connect(self.clear) + + if self.app: + close_action = QAction("Close", self) + self.menu.addAction(close_action) + close_action.triggered.connect(lambda: self.app.ui.shell_dock.hide()) + self.menu.exec_(event.globalPos()) def clear(self): diff --git a/flatcamTools/ToolShell.py b/flatcamTools/ToolShell.py index 78f328d5..0f8a5f0f 100644 --- a/flatcamTools/ToolShell.py +++ b/flatcamTools/ToolShell.py @@ -33,10 +33,10 @@ class TermWidget(QWidget): User pressed Enter. Client class should decide, if command must be executed or user may continue edit it """ - def __init__(self, version, *args): + def __init__(self, version, app, *args): QWidget.__init__(self, *args) - self._browser = _BrowserTextEdit(version=version) + self._browser = _BrowserTextEdit(version=version, app=app) self._browser.setStyleSheet("font: 9pt \"Courier\";") self._browser.setReadOnly(True) self._browser.document().setDefaultStyleSheet( @@ -92,10 +92,14 @@ class TermWidget(QWidget): """ Convert text to HTML for inserting it to browser """ - assert style in ('in', 'out', 'err', 'warning', 'success', 'selected') + assert style in ('in', 'out', 'err', 'warning', 'success', 'selected', 'raw') - text = html.escape(text) - text = text.replace('\n', '
') + if style != 'raw': + text = html.escape(text) + text = text.replace('\n', '
') + else: + text = text.replace('\n', '
') + text = text.replace('\t', '        ') if style == 'in': text = '%s' % text @@ -107,6 +111,8 @@ class TermWidget(QWidget): text = '%s' % text elif style == 'selected': text = '' + elif style == 'raw': + text = text else: text = '%s' % text # without span
is ignored!!! @@ -177,23 +183,29 @@ class TermWidget(QWidget): """ self._append_to_browser('out', text) + def append_raw(self, text): + """ + Append text to output widget as it is + """ + self._append_to_browser('raw', text) + def append_success(self, text): - """Appent text to output widget + """Append text to output widget """ self._append_to_browser('success', text) def append_selected(self, text): - """Appent text to output widget + """Append text to output widget """ self._append_to_browser('selected', text) def append_warning(self, text): - """Appent text to output widget + """Append 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 + """Append error text to output widget. Text is drawn with red background """ self._append_to_browser('err', text) @@ -235,7 +247,7 @@ class FCShell(TermWidget): :param version: FlatCAM version string :param args: Parameters passed to the TermWidget parent class """ - TermWidget.__init__(self, version, *args) + TermWidget.__init__(self, version, *args, app=sysShell) self._sysShell = sysShell def is_command_complete(self, text): diff --git a/tclCommands/TclCommandHelp.py b/tclCommands/TclCommandHelp.py index a1af436e..d40ac267 100644 --- a/tclCommands/TclCommandHelp.py +++ b/tclCommands/TclCommandHelp.py @@ -22,10 +22,10 @@ if '_' not in builtins.__dict__: class TclCommandHelp(TclCommand): """ - Tcl shell command to get the value of a system variable + Tcl shell command to show Help example: - get_sys excellon_zeros + help add_circle """ # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) @@ -58,21 +58,21 @@ class TclCommandHelp(TclCommand): def execute(self, args, unnamed_args): """ - :param args: + :param args: Without any argument will display the list of commands. Can have as a argument + a tcl command name to display the help for that command. :param unnamed_args: :return: """ - print(self.app.tcl_commands_storage) if 'name' in args: name = args['name'] if name not in self.app.tcl_commands_storage: return "Unknown command: %s" % name - print(self.app.tcl_commands_storage[name]["help"]) + self.app.shell.append_output(self.app.tcl_commands_storage[name]["help"]) else: - if args is None: - cmd_enum = _("Available commands:\n") + if not args: + cmd_enum = '%s\n' % _("Available commands:") displayed_text = [] try: @@ -85,14 +85,12 @@ class TclCommandHelp(TclCommand): max_tabs = math.ceil(max_len / 8) for cmd_name in sorted(self.app.tcl_commands_storage): - cmd_description = self.app.tcl_commands_storage[cmd_name]['description'] + cmd_description = "%s" % self.app.tcl_commands_storage[cmd_name]['description'] curr_len = len(cmd_name) tabs = '\t' - cmd_name_colored = "" - cmd_name_colored += str(cmd_name) - cmd_name_colored += "" + cmd_name_colored = "%s" % str(cmd_name) # make sure to add the right number of tabs (1 tab = 8 spaces) so all the commands # descriptions are aligned @@ -102,7 +100,7 @@ class TclCommandHelp(TclCommand): nr_tabs = 0 for x in range(max_tabs): - if curr_len <= (x * 8): + if curr_len < (x * 8): nr_tabs += 1 # nr_tabs = 2 if curr_len <= 8 else 1 @@ -111,9 +109,9 @@ class TclCommandHelp(TclCommand): displayed_text.append(cmd_line_txt) except Exception as err: self.app.log.debug("App.setup_shell.shelp() when run as 'help' --> %s" % str(err)) - displayed_text = [' %s' % cmd for cmd in sorted(self.app.tcl_commands_storage)] + displayed_text = ['> %s\n' % cmd for cmd in sorted(self.app.tcl_commands_storage)] - cmd_enum += '\n'.join(displayed_text) - cmd_enum += '\n\n%s\n%s' % (_("Type help for usage."), _("Example: help open_gerber")) + cmd_enum += '
'.join(displayed_text) + cmd_enum += '

%s
%s' % (_("Type help for usage."), _("Example: help open_gerber")) - print(cmd_enum) \ No newline at end of file + self.app.shell.append_raw(cmd_enum) diff --git a/tclCommands/__init__.py b/tclCommands/__init__.py index 9a5b22cf..b4a8d324 100644 --- a/tclCommands/__init__.py +++ b/tclCommands/__init__.py @@ -1,7 +1,6 @@ import pkgutil import sys -# Todo: I think these imports are not needed. # allowed command modules (please append them alphabetically ordered) import tclCommands.TclCommandAddCircle import tclCommands.TclCommandAddPolygon @@ -27,6 +26,7 @@ import tclCommands.TclCommandGeoCutout import tclCommands.TclCommandGeoUnion import tclCommands.TclCommandGetNames import tclCommands.TclCommandGetSys +import tclCommands.TclCommandHelp import tclCommands.TclCommandImportSvg import tclCommands.TclCommandInteriors import tclCommands.TclCommandIsolate @@ -93,7 +93,6 @@ def register_all_commands(app, commands): tcl_modules = {k: v for k, v in list(sys.modules.items()) if k.startswith('tclCommands.TclCommand')} for key, mod in list(tcl_modules.items()): - print(key) if key != 'tclCommands.TclCommand': class_name = key.split('.')[1] class_type = getattr(mod, class_name) From 1f36ed9369c39981056c15c538610b63fe173921 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 23 Apr 2020 02:43:26 +0300 Subject: [PATCH 193/209] - added an extra check if old preferences files are detected, a check if the type of the values is the same with the type in the current preferences file. If the type is not the same then the current type is preferred. --- CHANGELOG.md | 1 + FlatCAMApp.py | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 617a38d1..4bfb98c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ CHANGELOG for FlatCAM beta - added a 'Close' menu entry in the Tcl Shell context menu that will close (hide) the Tcl Shell Dock widget - on launching the Tcl Shell the Edit line will take focus immediately - in App.on_mouse_move_over_plot() method no longer will be done a setFocus() on every move, only when it is needed +- added an extra check if old preferences files are detected, a check if the type of the values is the same with the type in the current preferences file. If the type is not the same then the current type is preferred. 22.04.2020 diff --git a/FlatCAMApp.py b/FlatCAMApp.py index d366afa8..fab021b4 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -3829,7 +3829,23 @@ class App(QtCore.QObject): if 'version' not in defaults or defaults['version'] != self.defaults['version']: for k, v in defaults.items(): if k in self.defaults and k != 'version': - self.defaults[k] = v + + # check if the types are the same. Because some types (tuple, float, int etc) + # may be stored as strings we check their types. + try: + target = eval(self.defaults[k]) + except NameError: + # it's an unknown string leave it as it is + target = deepcopy(self.defaults[k]) + + try: + source = eval(v) + except NameError: + # it's an unknown string leave it as it is + source = deepcopy(v) + + if type(target) == type(source): + self.defaults[k] = v # delete old factory defaults try: From bfd938e5778b81cf8033f8d8f0deeda665a2a73f Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 23 Apr 2020 03:10:03 +0300 Subject: [PATCH 194/209] - aligned the Tcl commands display when the Help Tcl command is run without parameters --- CHANGELOG.md | 1 + tclCommands/TclCommandHelp.py | 25 +++++++++++-------------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bfb98c3..3f331da4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ CHANGELOG for FlatCAM beta - on launching the Tcl Shell the Edit line will take focus immediately - in App.on_mouse_move_over_plot() method no longer will be done a setFocus() on every move, only when it is needed - added an extra check if old preferences files are detected, a check if the type of the values is the same with the type in the current preferences file. If the type is not the same then the current type is preferred. +- aligned the Tcl commands display when the Help Tcl command is run without parameters 22.04.2020 diff --git a/tclCommands/TclCommandHelp.py b/tclCommands/TclCommandHelp.py index d40ac267..d083f949 100644 --- a/tclCommands/TclCommandHelp.py +++ b/tclCommands/TclCommandHelp.py @@ -82,31 +82,28 @@ class TclCommandHelp(TclCommand): curr_len = len(cmd_name) if curr_len > max_len: max_len = curr_len - max_tabs = math.ceil(max_len / 8) + h_space = " " + cnt = 0 for cmd_name in sorted(self.app.tcl_commands_storage): cmd_description = "%s" % self.app.tcl_commands_storage[cmd_name]['description'] curr_len = len(cmd_name) - tabs = '\t' cmd_name_colored = "%s" % str(cmd_name) - # make sure to add the right number of tabs (1 tab = 8 spaces) so all the commands - # descriptions are aligned - if curr_len == max_len: - cmd_line_txt = ' %s%s%s' % (cmd_name_colored, tabs, cmd_description) - else: - nr_tabs = 0 + nr_chars = max_len - curr_len - for x in range(max_tabs): - if curr_len < (x * 8): - nr_tabs += 1 - - # nr_tabs = 2 if curr_len <= 8 else 1 - cmd_line_txt = ' %s%s%s' % (cmd_name_colored, nr_tabs * tabs, cmd_description) + cmd_line_txt = '%s%s  %s' % (cmd_name_colored, nr_chars * h_space, cmd_description) displayed_text.append(cmd_line_txt) + + # group commands by 4 adding a line break after 4 commands + if cnt == 3: + cnt = 0 + displayed_text.append(' ') + else: + cnt += 1 except Exception as err: self.app.log.debug("App.setup_shell.shelp() when run as 'help' --> %s" % str(err)) displayed_text = ['> %s\n' % cmd for cmd in sorted(self.app.tcl_commands_storage)] From 32ff35b4ff68b6e06671a45caa52fd63dc8ad344 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 23 Apr 2020 03:34:09 +0300 Subject: [PATCH 195/209] - fixed the Tcl command Plot_All that malfunctioned if there were any FlatCAM scripts (or FlatCAM documents) open - updated the shortcuts list --- CHANGELOG.md | 2 ++ FlatCAMObj.py | 11 ++++++----- flatcamGUI/FlatCAMGUI.py | 11 +++++++++-- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f331da4..1bde9477 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ CHANGELOG for FlatCAM beta - in App.on_mouse_move_over_plot() method no longer will be done a setFocus() on every move, only when it is needed - added an extra check if old preferences files are detected, a check if the type of the values is the same with the type in the current preferences file. If the type is not the same then the current type is preferred. - aligned the Tcl commands display when the Help Tcl command is run without parameters +- fixed the Tcl command Plot_All that malfunctioned if there were any FlatCAM scripts (or FlatCAM documents) open +- updated the shortcuts list 22.04.2020 diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 5176ea16..bf4d5aa8 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -384,13 +384,13 @@ class FlatCAMObj(QtCore.QObject): pass # self.app.log.warning("Failed to read option from field: %s" % option) - def plot(self): + def plot(self, kind=None) -> bool: """ Plot this object (Extend this method to implement the actual plotting). Call this in descendants before doing the plotting. - :return: Whether to continue plotting or not depending on the "plot" option. - :rtype: bool + :param kind: Used by only some of the FlatCAM objects + :return: Whether to continue plotting or not depending on the "plot" option. Boolean """ FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + " --> FlatCAMObj.plot()") @@ -1761,10 +1761,11 @@ class FlatCAMGerber(FlatCAMObj, Gerber): # self.options['isotooldia'] = float(self.options['isotooldia']) * factor # self.options['bboxmargin'] = float(self.options['bboxmargin']) * factor - def plot(self, **kwargs): + def plot(self, kind=None, **kwargs): """ - :param kwargs: color and face_color + :param kind: Not used, for compatibility with the plot method for other objects + :param kwargs: Color and face_color, visible :return: """ FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + " --> FlatCAMGerber.plot()") diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index 6f1fe86e..394af02e 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -53,8 +53,8 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.shell_dock.setObjectName('Shell_DockWidget') self.shell_dock.setAllowedAreas(QtCore.Qt.AllDockWidgetAreas) self.shell_dock.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable | - QtWidgets.QDockWidget.DockWidgetFloatable | - QtWidgets.QDockWidget.DockWidgetClosable) + QtWidgets.QDockWidget.DockWidgetFloatable | + QtWidgets.QDockWidget.DockWidgetClosable) self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.shell_dock) # ####################################################################### @@ -1656,6 +1656,11 @@ class FlatCAMGUI(QtWidgets.QMainWindow): Ctrl+Shift+S  %s + + + Ctrl+Shift+V +  %s +     @@ -1715,6 +1720,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): _("Open Preferences Window"), _("Rotate by 90 degree CCW"), _("Run a Script"), _("Toggle the workspace"), _("Skew on X axis"), _("Skew on Y axis"), + # ALT section _("Align Objects Tool"), _("Calculators Tool"), _("2-Sided PCB Tool"), _("Transformations Tool"), _("Punch Gerber Tool"), _("Extract Drills Tool"), _("Fiducials Tool"), @@ -1730,6 +1736,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # CTRL + SHIFT section _("Save Project As"), + _("Paste Special. Will convert a Windows path style to the one required in Tcl Shell"), # F keys section _("Open Online Manual"), From 495650fc7318944ac4d53356ef30615f68717f80 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 23 Apr 2020 03:41:58 +0300 Subject: [PATCH 196/209] - remove some method declaration with type hints that work only in Python > 3.8 --- FlatCAMObj.py | 2 +- flatcamGUI/GUIElements.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index bf4d5aa8..d23ea62b 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -384,7 +384,7 @@ class FlatCAMObj(QtCore.QObject): pass # self.app.log.warning("Failed to read option from field: %s" % option) - def plot(self, kind=None) -> bool: + def plot(self, kind=None): """ Plot this object (Extend this method to implement the actual plotting). Call this in descendants before doing the plotting. diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index 0b243456..7d5b4e49 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -726,7 +726,7 @@ class FCSpinner(QtWidgets.QSpinBox): self.readyToEdit = True self.prev_readyToEdit = True - def valueFromText(self, text: str) -> int: + def valueFromText(self, text): txt = text.strip('%%') try: ret_val = int(txt) @@ -1426,7 +1426,7 @@ class FCLabel(QtWidgets.QLabel): # for the usage of this label as a clickable label, to know that current state self.clicked_state = False - def mousePressEvent(self, ev: QtGui.QMouseEvent) -> None: + def mousePressEvent(self, event): self.clicked_state = not self.clicked_state self.clicked.emit(self.clicked_state) From ea4502b9658f50d0f8174ea1bdb6e3aa96b33180 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 24 Apr 2020 04:18:01 +0300 Subject: [PATCH 197/209] - some PEP changes, some method descriptions updated - added a placeholder text to 2Sided Tool --- CHANGELOG.md | 5 + FlatCAMApp.py | 842 +++++++++++++++++++---------------- flatcamTools/ToolDblSided.py | 2 +- 3 files changed, 476 insertions(+), 373 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bde9477..e9d0fc19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ CHANGELOG for FlatCAM beta ================================================= +24.04.2020 + +- some PEP changes, some method descriptions updated +- added a placeholder text to 2Sided Tool + 23.04.2020 - fixed the Tcl Command Help to work as expected; made the text of the commands to be colored in Red color and bold diff --git a/FlatCAMApp.py b/FlatCAMApp.py index fab021b4..cb5a7f0d 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -31,7 +31,7 @@ from reportlab.lib.units import inch, mm from reportlab.lib.pagesizes import landscape, portrait from svglib.svglib import svg2rlg -from contextlib import contextmanager +# from contextlib import contextmanager import gc from xml.dom.minidom import parseString as parse_xml_string @@ -88,15 +88,28 @@ if '_' not in builtins.__dict__: class App(QtCore.QObject): - # ######################################## - # # App ### - # ######################################## - """ The main application class. The constructor starts the GUI. """ - # Get Cmd Line Options + # ############################################################################################################### + # ########################################## App ################################################################ + # ############################################################################################################### + + # ############################################################################################################### + # ######################################### LOGGING ############################################################# + # ############################################################################################################### + log = logging.getLogger('base') + log.setLevel(logging.DEBUG) + # log.setLevel(logging.WARNING) + formatter = logging.Formatter('[%(levelname)s][%(threadName)s] %(message)s') + handler = logging.StreamHandler() + handler.setFormatter(formatter) + log.addHandler(handler) + + # ############################################################################################################### + # #################################### Get Cmd Line Options ##################################################### + # ############################################################################################################### cmd_line_shellfile = '' cmd_line_shellvar = '' cmd_line_headless = None @@ -128,18 +141,9 @@ class App(QtCore.QObject): except NameError: pass - # ## Logging ### - log = logging.getLogger('base') - log.setLevel(logging.DEBUG) - # log.setLevel(logging.WARNING) - formatter = logging.Formatter('[%(levelname)s][%(threadName)s] %(message)s') - handler = logging.StreamHandler() - handler.setFormatter(formatter) - log.addHandler(handler) - - # ########################################################################## - # ################## Version and VERSION DATE ############################## - # ########################################################################## + # ############################################################################################################### + # ################################### Version and VERSION DATE ################################################## + # ############################################################################################################### version = 8.992 version_date = "2020/03/27" beta = True @@ -150,6 +154,9 @@ class App(QtCore.QObject): date = ''.join(c for c in date if c not in ':-') date = date.replace(' ', '_') + # ############################################################################################################### + # ############################################ URLS's ########################################################### + # ############################################################################################################### # URL for update checks and statistics version_url = "http://flatcam.org/version" @@ -171,9 +178,9 @@ class App(QtCore.QObject): # flag is True if saving action has been triggered save_in_progress = False - # ########################################################################### - # ############################# Signals ################################ - # ########################################################################### + # ############################################################################################################### + # ####################################### APP Signals ###################################################### + # ############################################################################################################### # Inform the user # Handled by: @@ -258,10 +265,9 @@ class App(QtCore.QObject): self.main_thread = QtWidgets.QApplication.instance().thread() - # ######################################################################### - # Setup the listening thread for another instance launching with args ##### - # ######################################################################### - + # ############################################################################################################ + # ################# Setup the listening thread for another instance launching with args ###################### + # ############################################################################################################ if sys.platform == 'win32' or sys.platform == 'linux': # make sure the thread is stored by using a self. otherwise it's garbage collected self.th = QtCore.QThread() @@ -272,9 +278,9 @@ class App(QtCore.QObject): self.new_launch.moveToThread(self.th) self.new_launch.start.emit() - # ############################################################################ - # # ################# OS-specific ############################################ - # ############################################################################ + # ############################################################################################################ + # # ######################################## OS-specific ##################################################### + # ############################################################################################################ portable = False # Folder for user settings. @@ -328,9 +334,9 @@ class App(QtCore.QObject): self.data_path = os.path.expanduser('~') + '/.FlatCAM' self.os = 'unix' - # ########################################################################## - # ################## Setup folders and files ############################### - # ########################################################################## + # ############################################################################################################ + # ################################# Setup folders and files ################################################## + # ############################################################################################################ if not os.path.exists(self.data_path): os.makedirs(self.data_path) @@ -353,16 +359,6 @@ class App(QtCore.QObject): json.dump({}, f) f.close() - # create fctool_tools_db.FlatDB file if there is none - # try: - # f = open(self.data_path + '/fctool_tools_db.FlatDB') - # f.close() - # except IOError: - # App.log.debug('Creating empty fctool_tool_db.FlatDB') - # f = open(self.data_path + '/fctool_tools_db.FlatDB', 'w') - # json.dump({}, f) - # f.close() - # create current_defaults.FlatConfig file if there is none try: f = open(self.data_path + '/current_defaults.FlatConfig') @@ -417,9 +413,9 @@ class App(QtCore.QObject): os.chdir(self.app_home) - # ################################################################################# - # #################### DEFAULTS - PREFERENCES STORAGE ############################# - # ################################################################################# + # ############################################################################################################ + # ################################# DEFAULTS - PREFERENCES STORAGE ########################################### + # ############################################################################################################ self.defaults = LoudDict() self.defaults.update({ # Global APP Preferences @@ -695,7 +691,7 @@ class App(QtCore.QObject): "excellon_editor_slot_length": 5.0, # Excellon Slot Array "excellon_editor_slot_array_size": 5, - "excellon_editor_slot_lin_dir": 'X', + "excellon_editor_slot_lin_dir": 'X', "excellon_editor_slot_lin_pitch": 2.54, "excellon_editor_slot_lin_angle": 0.0, "excellon_editor_slot_circ_dir": 'CW', @@ -1452,7 +1448,7 @@ class App(QtCore.QObject): "cncjob_coords_decimals": self.ui.cncjob_defaults_form.cncjob_gen_group.coords_dec_entry, "cncjob_fr_decimals": self.ui.cncjob_defaults_form.cncjob_gen_group.fr_dec_entry, "cncjob_steps_per_circle": self.ui.cncjob_defaults_form.cncjob_gen_group.steps_per_circle_entry, - "cncjob_line_ending": self.ui.cncjob_defaults_form.cncjob_gen_group.line_ending_cb, + "cncjob_line_ending": self.ui.cncjob_defaults_form.cncjob_gen_group.line_ending_cb, "cncjob_plot_line": self.ui.cncjob_defaults_form.cncjob_gen_group.line_color_entry, "cncjob_plot_fill": self.ui.cncjob_defaults_form.cncjob_gen_group.fill_color_entry, "cncjob_travel_line": self.ui.cncjob_defaults_form.cncjob_gen_group.tline_color_entry, @@ -1729,7 +1725,6 @@ class App(QtCore.QObject): # ############################################################################## if self.defaults["first_run"] is True: - self.save_factory_defaults(silent_message=False) # and then make the factory_defaults.FlatConfig file read_only so it can't be modified after creation. filename_factory = self.data_path + '/factory_defaults.FlatConfig' @@ -1909,7 +1904,7 @@ class App(QtCore.QObject): "Canvas initialization started."), alignment=Qt.AlignBottom | Qt.AlignLeft, color=QtGui.QColor("gray")) - start_plot_time = time.time() # debug + start_plot_time = time.time() # debug self.plotcanvas = None self.app_cursor = None @@ -2701,6 +2696,8 @@ class App(QtCore.QObject): # This list is updated on each object creation or object delete self.all_objects_list = [] + self.objects_under_the_click_list = [] + # List to store the objects that are selected self.sel_objects_list = [] @@ -3982,8 +3979,7 @@ class App(QtCore.QObject): filter=filter__ ) except TypeError: - filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Export FlatCAM Preferences"), - filter=filter__) + filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Export FlatCAM Preferences"), filter=filter__) filename = str(filename) defaults_from_file = {} @@ -4159,7 +4155,7 @@ class App(QtCore.QObject): :param fit: :param plot: If to plot the resulting object :param autoselected: if the resulting object is autoselected in the Project tab and therefore in the - self.colleaction + self.collection :return: None :rtype: None """ @@ -4265,7 +4261,6 @@ class App(QtCore.QObject): # Move the object to the main thread and let the app know that it is available. obj.moveToThread(self.main_thread) - self.object_created.emit(obj, obj_plot, obj_autoselected) return obj @@ -4332,13 +4327,13 @@ class App(QtCore.QObject): new_source_file = text else: commands_list = "# AddCircle, AddPolygon, AddPolyline, AddRectangle, AlignDrill, " \ - "AlignDrillGrid, Bbox, Bounds, ClearShell, CopperClear,\n"\ + "AlignDrillGrid, Bbox, Bounds, ClearShell, CopperClear,\n" \ "# Cncjob, Cutout, Delete, Drillcncjob, ExportDXF, ExportExcellon, ExportGcode,\n" \ - "# ExportGerber, ExportSVG, Exteriors, Follow, GeoCutout, GeoUnion, GetNames,\n"\ + "# ExportGerber, ExportSVG, Exteriors, Follow, GeoCutout, GeoUnion, GetNames,\n" \ "# GetSys, ImportSvg, Interiors, Isolate, JoinExcellon, JoinGeometry, " \ - "ListSys, MillDrills,\n"\ + "ListSys, MillDrills,\n" \ "# MillSlots, Mirror, New, NewExcellon, NewGeometry, NewGerber, Nregions, " \ - "Offset, OpenExcellon, OpenGCode, OpenGerber, OpenProject,\n"\ + "Offset, OpenExcellon, OpenGCode, OpenGerber, OpenProject,\n" \ "# Options, Paint, Panelize, PlotAl, PlotObjects, SaveProject, " \ "SaveSys, Scale, SetActive, SetSys, SetOrigin, Skew, SubtractPoly,\n" \ "# SubtractRectangle, Version, WriteGCode\n" @@ -4568,10 +4563,10 @@ class App(QtCore.QObject): 'to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n' 'copies of the Software, and to permit persons to whom the Software is\n' 'furnished to do so, subject to the following conditions:\n\n' - + 'The above copyright notice and this permission notice shall be included in\n' 'all copies or substantial portions of the Software.\n\n' - + 'THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n' 'IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n' 'FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n' @@ -4746,7 +4741,7 @@ class App(QtCore.QObject): self.translator_grid_lay.addWidget(QtWidgets.QLabel('%s' % _("E-mail")), 0, 3) self.translator_grid_lay.addWidget(QtWidgets.QLabel('%s' % "BR - Portuguese"), 1, 0) self.translator_grid_lay.addWidget(QtWidgets.QLabel('%s' % "Carlos Stein"), 1, 1) - self.translator_grid_lay.addWidget(QtWidgets.QLabel('%s' % ""), 1, 3) + self.translator_grid_lay.addWidget(QtWidgets.QLabel('%s' % ""), 1, 3) self.translator_grid_lay.addWidget(QtWidgets.QLabel('%s' % "French"), 2, 0) self.translator_grid_lay.addWidget(QtWidgets.QLabel('%s' % "Marius Stanciu (Google-Tr)"), 2, 1) self.translator_grid_lay.addWidget(QtWidgets.QLabel('%s' % ""), 2, 2) @@ -5189,9 +5184,10 @@ class App(QtCore.QObject): # When the main event loop is not started yet in which case the qApp.quit() will do nothing # we use the following command # sys.exit(0) - os._exit(0) # fix to work with Python 3.8 + os._exit(0) # fix to work with Python 3.8 - def kill_app(self): + @staticmethod + def kill_app(): # QtCore.QCoreApplication.quit() QtWidgets.qApp.quit() # When the main event loop is not started yet in which case the qApp.quit() will do nothing @@ -5621,6 +5617,7 @@ class App(QtCore.QObject): # rename all the ['name] key in obj.tools[tooluid]['data'] to the obj_name_multi for v in geo_obj.tools.values(): v['data']['name'] = obj_name_single + self.new_object("geometry", obj_name_single, initialize) self.should_we_save = True @@ -5817,14 +5814,14 @@ class App(QtCore.QObject): dimensions = ['gerber_isotooldia', 'gerber_noncoppermargin', 'gerber_bboxmargin', "gerber_isooverlap", "gerber_editor_newsize", "gerber_editor_lin_pitch", "gerber_editor_buff_f", - 'excellon_cutz', 'excellon_travelz', "excellon_toolchangexy", 'excellon_offset', + 'excellon_cutz', 'excellon_travelz', "excellon_toolchangexy", 'excellon_offset', 'excellon_feedrate', 'excellon_feedrate_rapid', 'excellon_toolchangez', 'excellon_tooldia', 'excellon_slot_tooldia', 'excellon_endz', 'excellon_endxy', "excellon_feedrate_probe", "excellon_z_pdepth", "excellon_editor_newdia", "excellon_editor_lin_pitch", "excellon_editor_slot_lin_pitch", - 'geometry_cutz', "geometry_depthperpass", 'geometry_travelz', 'geometry_feedrate', + 'geometry_cutz', "geometry_depthperpass", 'geometry_travelz', 'geometry_feedrate', 'geometry_feedrate_rapid', "geometry_toolchangez", "geometry_feedrate_z", "geometry_toolchangexy", 'geometry_cnctooldia', 'geometry_endz', 'geometry_endxy', "geometry_z_pdepth", @@ -5974,7 +5971,7 @@ class App(QtCore.QObject): self.defaults[dim] = val # The scaling factor depending on choice of units. - factor = 25.4 if new_units == 'MM' else 1/25.4 + factor = 25.4 if new_units == 'MM' else 1 / 25.4 # Changing project units. Warn user. msgbox = QtWidgets.QMessageBox() @@ -6457,33 +6454,33 @@ class App(QtCore.QObject): if state: # first try to disconnect try: - self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_upper_in_entry.returnPressed.\ + self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_upper_in_entry.returnPressed. \ disconnect(self.on_excellon_format_changed) except TypeError: pass try: - self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_lower_in_entry.returnPressed.\ + self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_lower_in_entry.returnPressed. \ disconnect(self.on_excellon_format_changed) except TypeError: pass try: - self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_upper_mm_entry.returnPressed.\ + self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_upper_mm_entry.returnPressed. \ disconnect(self.on_excellon_format_changed) except TypeError: pass try: - self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_lower_mm_entry.returnPressed.\ + self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_lower_mm_entry.returnPressed. \ disconnect(self.on_excellon_format_changed) except TypeError: pass try: - self.ui.excellon_defaults_form.excellon_gen_group.excellon_zeros_radio.activated_custom.\ + self.ui.excellon_defaults_form.excellon_gen_group.excellon_zeros_radio.activated_custom. \ disconnect(self.on_excellon_zeros_changed) except TypeError: pass try: - self.ui.excellon_defaults_form.excellon_gen_group.excellon_units_radio.activated_custom.\ + self.ui.excellon_defaults_form.excellon_gen_group.excellon_units_radio.activated_custom. \ disconnect(self.on_excellon_zeros_changed) except TypeError: pass @@ -7119,11 +7116,8 @@ class App(QtCore.QObject): def on_move2origin(self, use_thread=True): """ - - :param event: - :param location: - :param noplot: - :param use_thread: + Move selected objects to origin. + :param use_thread: Control if to use threaded operation. Boolean. :return: """ @@ -7182,7 +7176,10 @@ class App(QtCore.QObject): def on_jump_to(self, custom_location=None, fit_center=True): """ - Jump to a location by setting the mouse cursor location + Jump to a location by setting the mouse cursor location. + + :param custom_location: Jump to a specified point. (x, y) tuple. + :param fit_center: If to fit view. Boolean. :return: """ @@ -7301,7 +7298,10 @@ class App(QtCore.QObject): def on_locate(self, obj, fit_center=True): """ Jump to one of the corners (or center) of an object by setting the mouse cursor location - :return: + + :param obj: The object on which to locate certain points + :param fit_center: If to fit view. Boolean. + :return: A point location. (x, y) tuple. """ self.report_usage("on_locate()") @@ -7445,6 +7445,10 @@ class App(QtCore.QObject): return location def on_copy_command(self): + """ + Will copy a selection of objects, creating new objects. + :return: + """ self.report_usage("on_copy_command()") def initialize(obj_init, app): @@ -7462,8 +7466,8 @@ class App(QtCore.QObject): try: if obj.tools: obj_init.tools = deepcopy(obj.tools) - except Exception as e: - log.debug("App.on_copy_command() --> %s" % str(e)) + except Exception as err: + log.debug("App.on_copy_command() --> %s" % str(err)) try: obj_init.source_file = deepcopy(obj.source_file) @@ -7553,6 +7557,12 @@ class App(QtCore.QObject): return "Operation failed: %s" % str(er) def on_rename_object(self, text): + """ + Will rename an object. + + :param text: New name for the object. + :return: + """ self.report_usage("on_rename_object()") named_obj = self.collection.get_active() @@ -7566,6 +7576,10 @@ class App(QtCore.QObject): log.warning("App.on_rename_object() --> Could not rename the object in the list. --> %s" % str(e)) def convert_any2geo(self): + """ + Will convert any object out of Gerber, Excellon, Geometry to Geometry object. + :return: + """ self.report_usage("convert_any2geo()") def initialize(obj_init, app): @@ -7612,6 +7626,12 @@ class App(QtCore.QObject): return "Operation failed: %s" % str(e) def convert_any2gerber(self): + """ + Will convert any object out of Gerber, Excellon, Geometry to Gerber object. + + :return: + """ + self.report_usage("convert_any2gerber()") def initialize_geometry(obj_init, app): @@ -7687,17 +7707,27 @@ class App(QtCore.QObject): return "Operation failed: %s" % str(e) def abort_all_tasks(self): + """ + Executed when a certain key combo is pressed (Ctrl+Alt+X). Will abort current task + on the first possible occasion. + + :return: + """ if self.abort_flag is False: self.inform.emit(_("Aborting. The current task will be gracefully closed as soon as possible...")) self.abort_flag = True def app_is_idle(self): if self.abort_flag: - self.inform.emit('[WARNING_NOTCL] %s' % - _("The current task was gracefully closed on user request...")) + self.inform.emit('[WARNING_NOTCL] %s' % _("The current task was gracefully closed on user request...")) self.abort_flag = False def on_selectall(self): + """ + Will draw a selection box shape around the selected objects. + + :return: + """ self.report_usage("on_selectall()") # delete the possible selection box around a possible selected object @@ -7776,6 +7806,11 @@ class App(QtCore.QObject): pass def on_preferences_edited(self): + """ + Executed when a preference was changed in the Edit -> Preferences tab. + Will color the Preferences tab text to Red color. + :return: + """ if self.preferences_changed_flag is False: self.inform.emit('[WARNING_NOTCL] %s' % _("Preferences edited but not saved.")) @@ -7789,7 +7824,8 @@ class App(QtCore.QObject): def on_tools_database(self, source='app'): """ - Adds the Tools Database in a Tab in Plot Area + Adds the Tools Database in a Tab in Plot Area. + :return: """ for idx in range(self.ui.plot_tab_area.count()): @@ -7838,6 +7874,13 @@ class App(QtCore.QObject): self.tools_db_tab.ui_connect() def on_tools_db_edited(self): + """ + Executed whenever a tool is edited in Tools Database. + Will color the text of the Tools Database tab to Red color. + + :return: + """ + self.inform.emit('[WARNING_NOTCL] %s' % _("Tools in Tools Database edited but not saved.")) for idx in range(self.ui.plot_tab_area.count()): @@ -7848,7 +7891,8 @@ class App(QtCore.QObject): def on_geometry_tool_add_from_db_executed(self, tool): """ - Here add the tool from DB in the selected geometry object + Here add the tool from DB in the selected geometry object. + :return: """ tool_from_db = deepcopy(tool) @@ -7868,6 +7912,13 @@ class App(QtCore.QObject): self.inform.emit('[ERROR_NOTCL] %s' % _("Adding tool from DB is not allowed for this object.")) def on_plot_area_tab_closed(self, title): + """ + Executed whenever a tab is closed in the Plot Area. + + :param title: The name of the tab that was closed. + :return: + """ + if title == _("Preferences"): # disconnect for idx in range(self.ui.pref_tab_area.count()): @@ -7954,6 +8005,11 @@ class App(QtCore.QObject): self.book_dialog_tab.deleteLater() def on_flipy(self): + """ + Executed when the menu entry in Options -> Flip on Y axis is clicked. + + :return: + """ self.report_usage("on_flipy()") obj_list = self.collection.get_selected() @@ -7963,8 +8019,7 @@ class App(QtCore.QObject): ymaxlist = [] if not obj_list: - self.inform.emit('[WARNING_NOTCL] %s' % - _("No object selected to Flip on Y axis.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("No object selected to Flip on Y axis.")) else: try: # first get a bounding box to fit all @@ -7996,6 +8051,12 @@ class App(QtCore.QObject): return def on_flipx(self): + """ + Executed when the menu entry in Options -> Flip on X axis is clicked. + + :return: + """ + self.report_usage("on_flipx()") obj_list = self.collection.get_selected() @@ -8038,6 +8099,13 @@ class App(QtCore.QObject): return def on_rotate(self, silent=False, preset=None): + """ + Executed when Options -> Rotate Selection menu entry is clicked. + + :param silent: If silent is True then use the preset value for the angle of the rotation. + :param preset: A value to be used as predefined angle for rotation. + :return: + """ self.report_usage("on_rotate()") obj_list = self.collection.get_selected() @@ -8047,8 +8115,7 @@ class App(QtCore.QObject): ymaxlist = [] if not obj_list: - self.inform.emit('[WARNING_NOTCL] %s' % - _("No object selected to Rotate.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("No object selected to Rotate.")) else: if silent is False: rotatebox = FCInputDialog(title=_("Transform"), text=_("Enter the Angle value:"), @@ -8088,6 +8155,12 @@ class App(QtCore.QObject): return def on_skewx(self): + """ + Executed when the menu entry in Options -> Skew on X axis is clicked. + + :return: + """ + self.report_usage("on_skewx()") obj_list = self.collection.get_selected() @@ -8121,6 +8194,12 @@ class App(QtCore.QObject): _("Skew on X axis done.")) def on_skewy(self): + """ + Executed when the menu entry in Options -> Skew on Y axis is clicked. + + :return: + """ + self.report_usage("on_skewy()") obj_list = self.collection.get_selected() @@ -8161,7 +8240,7 @@ class App(QtCore.QObject): :return: None """ if self.is_legacy is False: - self.plotcanvas.update() # TODO: Need update canvas? + self.plotcanvas.update() # TODO: Need update canvas? else: self.plotcanvas.auto_adjust_axes() @@ -8195,8 +8274,13 @@ class App(QtCore.QObject): self.collection.on_item_activated(index) def on_row_selected(self, obj_name): - # this is a special string; when received it will make all entries unchecked - # it mean we clicked outside of the items and deselected all + """ + This is a special string; when received it will make all Menu -> Objects entries unchecked + It mean we clicked outside of the items and deselected all + + :param obj_name: + :return: + """ if obj_name == 'none': for act in self.ui.menuobjects.actions(): act.setChecked(False) @@ -8218,10 +8302,10 @@ class App(QtCore.QObject): Create a menu from the object loaded in the collection. TODO: should use the collection model to do this - :param obj: object that was changd (added, deleted, renamed) - :param state: what was done with the objectCand be: added, deleted, delete_all, renamed - :param old_name: the old name of the object before the action that triggered this slot happened - :return: None + :param obj: object that was changed (added, deleted, renamed) + :param state: what was done with the object. Can be: added, deleted, delete_all, renamed + :param old_name: the old name of the object before the action that triggered this slot happened + :return: None """ icon_files = { "gerber": self.resource_location + "/flatcam_icon16.png", @@ -8777,7 +8861,7 @@ class App(QtCore.QObject): # If there is no active command (self.command_active is None) then we check if we clicked # on a object by checking the bounding limits against mouse click position if self.command_active is None: - self.select_objects(key='CTRL') + self.select_objects(key='multisel') self.delete_hover_shape() else: # If there is no active command (self.command_active is None) then we check if we clicked @@ -8803,7 +8887,7 @@ class App(QtCore.QObject): # make all objects inactive self.collection.set_all_inactive() - + for obj in self.collection.get_list(): try: # select the object(s) only if it is enabled (plotted) @@ -8840,7 +8924,8 @@ class App(QtCore.QObject): """ # list where we store the overlapped objects under our mouse left click position - objects_under_the_click_list = [] + if key is None: + self.objects_under_the_click_list = [] # Populate the list with the overlapped objects on the click position curr_x, curr_y = self.pos @@ -8850,21 +8935,24 @@ class App(QtCore.QObject): if isinstance(obj, FlatCAMScript) or isinstance(obj, FlatCAMDocument): continue + if key == 'multisel' and obj.options['name'] in self.objects_under_the_click_list: + continue + if (curr_x >= obj.options['xmin']) and (curr_x <= obj.options['xmax']) and \ (curr_y >= obj.options['ymin']) and (curr_y <= obj.options['ymax']): - if obj.options['name'] not in objects_under_the_click_list: + if obj.options['name'] not in self.objects_under_the_click_list: if obj.options['plot']: # add objects to the objects_under_the_click list only if the object is plotted # (active and not disabled) - objects_under_the_click_list.append(obj.options['name']) + self.objects_under_the_click_list.append(obj.options['name']) try: - if objects_under_the_click_list: + if self.objects_under_the_click_list: curr_sel_obj = self.collection.get_active() # case when there is only an object under the click and we toggle it - if len(objects_under_the_click_list) == 1: + if len(self.objects_under_the_click_list) == 1: if curr_sel_obj is None: - self.collection.set_active(objects_under_the_click_list[0]) + self.collection.set_active(self.objects_under_the_click_list[0]) curr_sel_obj = self.collection.get_active() # create the selection box around the selected object @@ -8872,12 +8960,12 @@ class App(QtCore.QObject): self.draw_selection_shape(curr_sel_obj) curr_sel_obj.selection_shape_drawn = True - elif curr_sel_obj.options['name'] not in objects_under_the_click_list: + elif curr_sel_obj.options['name'] not in self.objects_under_the_click_list: self.on_objects_selection(False) self.delete_selection_shape() curr_sel_obj.selection_shape_drawn = False - self.collection.set_active(objects_under_the_click_list[0]) + self.collection.set_active(self.objects_under_the_click_list[0]) curr_sel_obj = self.collection.get_active() # create the selection box around the selected object if self.defaults['global_selection_shape'] is True: @@ -8903,21 +8991,21 @@ class App(QtCore.QObject): # If there is no selected object # make active the first element of the overlapped objects list if self.collection.get_active() is None: - self.collection.set_active(objects_under_the_click_list[0]) - self.collection.get_by_name(objects_under_the_click_list[0]).selection_shape_drawn = True + self.collection.set_active(self.objects_under_the_click_list[0]) + self.collection.get_by_name(self.objects_under_the_click_list[0]).selection_shape_drawn = True name_sel_obj = self.collection.get_active().options['name'] # In case that there is a selected object but it is not in the overlapped object list # make that object inactive and activate the first element in the overlapped object list - if name_sel_obj not in objects_under_the_click_list: + if name_sel_obj not in self.objects_under_the_click_list: self.collection.set_inactive(name_sel_obj) - name_sel_obj = objects_under_the_click_list[0] + name_sel_obj = self.objects_under_the_click_list[0] self.collection.set_active(name_sel_obj) else: - sel_idx = objects_under_the_click_list.index(name_sel_obj) + sel_idx = self.objects_under_the_click_list.index(name_sel_obj) self.collection.set_all_inactive() - self.collection.set_active(objects_under_the_click_list[(sel_idx + 1) % - len(objects_under_the_click_list)]) + self.collection.set_active( + self.objects_under_the_click_list[(sel_idx + 1) % len(self.objects_under_the_click_list)]) curr_sel_obj = self.collection.get_active() # delete the possible selection box around a possible selected object @@ -8992,8 +9080,9 @@ class App(QtCore.QObject): def draw_hover_shape(self, sel_obj, color=None): """ - :param sel_obj: the object for which the hover shape must be drawn - :return: + :param sel_obj: The object for which the hover shape must be drawn + :param color: The color of the hover shape + :return: None """ pt1 = (float(sel_obj.options['xmin']), float(sel_obj.options['ymin'])) @@ -9037,9 +9126,11 @@ class App(QtCore.QObject): def draw_selection_shape(self, sel_obj, color=None): """ + Will draw a selection shape around the selected object. - :param sel_obj: the object for which the selection shape must be drawn - :return: + :param sel_obj: The object for which the selection shape must be drawn + :param color: The color for the selection shape. + :return: None """ if sel_obj is None: @@ -9081,9 +9172,11 @@ class App(QtCore.QObject): def draw_moving_selection_shape(self, old_coords, coords, **kwargs): """ + Will draw a selection shape when dragging mouse on canvas. - :param old_coords: old coordinates - :param coords: new coordinates + :param old_coords: Old coordinates + :param coords: New coordinates + :param kwargs: Keyword arguments :return: """ @@ -9122,6 +9215,13 @@ class App(QtCore.QObject): self.move_tool.sel_shapes.redraw() def on_file_new_click(self): + """ + Callback for menu item File -> New. + Executed on clicking the Menu -> File -> New Project + + :return: + """ + if self.collection.get_list() and self.should_we_save: msgbox = QtWidgets.QMessageBox() # msgbox.setText("Save changes ...") @@ -9150,8 +9250,7 @@ class App(QtCore.QObject): def on_file_new(self, cli=None): """ - Callback for menu item File -> New. Returns the application to its - startup state. This method is thread-safe. + Returns the application to its startup state. This method is thread-safe. :return: None """ @@ -9231,6 +9330,7 @@ class App(QtCore.QObject): def obj_properties(self): """ Will launch the object Properties Tool + :return: """ @@ -9240,6 +9340,7 @@ class App(QtCore.QObject): def on_project_context_save(self): """ Wrapper, will save the object function of it's type + :return: """ @@ -9258,6 +9359,12 @@ class App(QtCore.QObject): self.on_file_savedocument() def obj_move(self): + """ + Callback for the Move menu entry in various Context Menu's. + + :return: + """ + self.report_usage("obj_move()") self.move_tool.run(toggle=False) @@ -10395,53 +10502,53 @@ class App(QtCore.QObject): self.pagesize.update( { 'Bounds': None, - 'A0': (841*mm, 1189*mm), - 'A1': (594*mm, 841*mm), - 'A2': (420*mm, 594*mm), - 'A3': (297*mm, 420*mm), - 'A4': (210*mm, 297*mm), - 'A5': (148*mm, 210*mm), - 'A6': (105*mm, 148*mm), - 'A7': (74*mm, 105*mm), - 'A8': (52*mm, 74*mm), - 'A9': (37*mm, 52*mm), - 'A10': (26*mm, 37*mm), + 'A0': (841 * mm, 1189 * mm), + 'A1': (594 * mm, 841 * mm), + 'A2': (420 * mm, 594 * mm), + 'A3': (297 * mm, 420 * mm), + 'A4': (210 * mm, 297 * mm), + 'A5': (148 * mm, 210 * mm), + 'A6': (105 * mm, 148 * mm), + 'A7': (74 * mm, 105 * mm), + 'A8': (52 * mm, 74 * mm), + 'A9': (37 * mm, 52 * mm), + 'A10': (26 * mm, 37 * mm), - 'B0': (1000*mm, 1414*mm), - 'B1': (707*mm, 1000*mm), - 'B2': (500*mm, 707*mm), - 'B3': (353*mm, 500*mm), - 'B4': (250*mm, 353*mm), - 'B5': (176*mm, 250*mm), - 'B6': (125*mm, 176*mm), - 'B7': (88*mm, 125*mm), - 'B8': (62*mm, 88*mm), - 'B9': (44*mm, 62*mm), - 'B10': (31*mm, 44*mm), + 'B0': (1000 * mm, 1414 * mm), + 'B1': (707 * mm, 1000 * mm), + 'B2': (500 * mm, 707 * mm), + 'B3': (353 * mm, 500 * mm), + 'B4': (250 * mm, 353 * mm), + 'B5': (176 * mm, 250 * mm), + 'B6': (125 * mm, 176 * mm), + 'B7': (88 * mm, 125 * mm), + 'B8': (62 * mm, 88 * mm), + 'B9': (44 * mm, 62 * mm), + 'B10': (31 * mm, 44 * mm), - 'C0': (917*mm, 1297*mm), - 'C1': (648*mm, 917*mm), - 'C2': (458*mm, 648*mm), - 'C3': (324*mm, 458*mm), - 'C4': (229*mm, 324*mm), - 'C5': (162*mm, 229*mm), - 'C6': (114*mm, 162*mm), - 'C7': (81*mm, 114*mm), - 'C8': (57*mm, 81*mm), - 'C9': (40*mm, 57*mm), - 'C10': (28*mm, 40*mm), + 'C0': (917 * mm, 1297 * mm), + 'C1': (648 * mm, 917 * mm), + 'C2': (458 * mm, 648 * mm), + 'C3': (324 * mm, 458 * mm), + 'C4': (229 * mm, 324 * mm), + 'C5': (162 * mm, 229 * mm), + 'C6': (114 * mm, 162 * mm), + 'C7': (81 * mm, 114 * mm), + 'C8': (57 * mm, 81 * mm), + 'C9': (40 * mm, 57 * mm), + 'C10': (28 * mm, 40 * mm), # American paper sizes - 'LETTER': (8.5*inch, 11*inch), - 'LEGAL': (8.5*inch, 14*inch), - 'ELEVENSEVENTEEN': (11*inch, 17*inch), + 'LETTER': (8.5 * inch, 11 * inch), + 'LEGAL': (8.5 * inch, 14 * inch), + 'ELEVENSEVENTEEN': (11 * inch, 17 * inch), # From https://en.wikipedia.org/wiki/Paper_size - 'JUNIOR_LEGAL': (5*inch, 8*inch), - 'HALF_LETTER': (5.5*inch, 8*inch), - 'GOV_LETTER': (8*inch, 10.5*inch), - 'GOV_LEGAL': (8.5*inch, 13*inch), - 'LEDGER': (17*inch, 11*inch), + 'JUNIOR_LEGAL': (5 * inch, 8 * inch), + 'HALF_LETTER': (5.5 * inch, 8 * inch), + 'GOV_LETTER': (8 * inch, 10.5 * inch), + 'GOV_LEGAL': (8.5 * inch, 13 * inch), + 'LEDGER': (17 * inch, 11 * inch), } ) @@ -10621,8 +10728,7 @@ class App(QtCore.QObject): if self.defaults["global_open_style"] is False: self.file_opened.emit("SVG", filename) self.file_saved.emit("SVG", filename) - self.inform.emit('[success] %s: %s' % - (_("SVG file exported to"), filename)) + self.inform.emit('[success] %s: %s' % (_("SVG file exported to"), filename)) def save_source_file(self, obj_name, filename, use_thread=True): """ @@ -10796,8 +10902,7 @@ class App(QtCore.QObject): if self.defaults["global_open_style"] is False: self.file_opened.emit("Excellon", filename) self.file_saved.emit("Excellon", filename) - self.inform.emit('[success] %s: %s' % - (_("Excellon file exported to"), filename)) + self.inform.emit('[success] %s: %s' % (_("Excellon file exported to"), filename)) else: return exported_excellon except Exception as e: @@ -10811,19 +10916,17 @@ class App(QtCore.QObject): def job_thread_exc(app_obj): ret = make_excellon() if ret == 'fail': - self.inform.emit('[ERROR_NOTCL] %s' % - _('Could not export Excellon file.')) + self.inform.emit('[ERROR_NOTCL] %s' % _('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] %s' % - _('Could not export Excellon file.')) + eret = make_excellon() + if eret == 'fail': + self.inform.emit('[ERROR_NOTCL] %s' % _('Could not export Excellon file.')) return 'fail' if local_use is not None: - return ret + return eret def export_gerber(self, obj_name, filename, local_use=None, use_thread=True): """ @@ -10936,8 +11039,7 @@ class App(QtCore.QObject): if self.defaults["global_open_style"] is False: self.file_opened.emit("Gerber", filename) self.file_saved.emit("Gerber", filename) - self.inform.emit('[success] %s: %s' % - (_("Gerber file exported to"), filename)) + self.inform.emit('[success] %s: %s' % (_("Gerber file exported to"), filename)) else: return exported_gerber except Exception as e: @@ -10950,19 +11052,17 @@ class App(QtCore.QObject): def job_thread_grb(app_obj): ret = make_gerber() if ret == 'fail': - self.inform.emit('[ERROR_NOTCL] %s' % - _('Could not export Gerber file.')) + self.inform.emit('[ERROR_NOTCL] %s' % _('Could not export Gerber file.')) return self.worker_task.emit({'fcn': job_thread_grb, 'params': [self]}) else: - ret = make_gerber() - if ret == 'fail': - self.inform.emit('[ERROR_NOTCL] %s' % - _('Could not export Gerber file.')) + gret = make_gerber() + if gret == 'fail': + self.inform.emit('[ERROR_NOTCL] %s' % _('Could not export Gerber file.')) return 'fail' if local_use is not None: - return ret + return gret def export_dxf(self, obj_name, filename, use_thread=True): """ @@ -11063,10 +11163,9 @@ class App(QtCore.QObject): Adds a new Geometry Object to the projects and populates it with shapes extracted from the DXF file. - :param filename: Path to the DXF file. - :param geo_type: Type of FlatCAM object that will be created from DXF - :param outname: - :type putname: str + :param filename: Path to the DXF file. + :param geo_type: Type of FlatCAM object that will be created from DXF + :param outname: Name for the imported Geometry :return: """ self.report_usage("import_dxf()") @@ -11105,7 +11204,7 @@ class App(QtCore.QObject): it in the program. Thread-safe. :param outname: Name of the resulting object. None causes the - name to be that of the file. + name to be that of the file. Str. :param filename: Gerber file filename :type filename: str :return: None @@ -11608,7 +11707,7 @@ class App(QtCore.QObject): self.log.debug("Plot_all()") self.inform.emit('[success] %s...' % _("Redrawing all objects")) - for obj in self.collection.get_list(): + for plot_obj in self.collection.get_list(): def worker_task(obj): with self.proc_container.new("Plotting"): obj.plot(kind=self.defaults["cncjob_plot_kind"]) @@ -11617,9 +11716,9 @@ class App(QtCore.QObject): if use_thread is True: # Send to worker - self.worker_task.emit({'fcn': worker_task, 'params': [obj]}) + self.worker_task.emit({'fcn': worker_task, 'params': [plot_obj]}) else: - worker_task(obj) + worker_task(plot_obj) def register_folder(self, filename): """ @@ -11639,15 +11738,15 @@ class App(QtCore.QObject): """ self.defaults["global_last_save_folder"] = os.path.split(str(filename))[0] - def set_progress_bar(self, percentage, text=""): - """ - Set a progress bar to a value (percentage) - - :param percentage: Value set to the progressbar - :param text: Not used - :return: None - """ - self.ui.progress_bar.setValue(int(percentage)) + # def set_progress_bar(self, percentage, text=""): + # """ + # Set a progress bar to a value (percentage) + # + # :param percentage: Value set to the progressbar + # :param text: Not used + # :return: None + # """ + # self.ui.progress_bar.setValue(int(percentage)) def setup_recent_items(self): """ @@ -11695,16 +11794,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] %s' % - _("Failed to load recent item list.")) + self.inform.emit('[ERROR_NOTCL] %s' % _("Failed to load recent item list.")) return try: self.recent = json.load(f) - except json.scanner.JSONDecodeError: + except json.errors.JSONDecodeError: App.log.error("Failed to parse recent item list.") - self.inform.emit('[ERROR_NOTCL] %s' % - _("Failed to parse recent item list.")) + self.inform.emit('[ERROR_NOTCL] %s' % _("Failed to parse recent item list.")) f.close() return f.close() @@ -11714,16 +11811,14 @@ class App(QtCore.QObject): fp = open(self.data_path + '/recent_projects.json') except IOError: App.log.error("Failed to load recent project item list.") - self.inform.emit('[ERROR_NOTCL] %s' % - _("Failed to load recent projects item list.")) + self.inform.emit('[ERROR_NOTCL] %s' % _("Failed to load recent projects item list.")) return try: self.recent_projects = json.load(fp) - except json.scanner.JSONDecodeError: + except json.errors.JSONDecodeError: App.log.error("Failed to parse recent project item list.") - self.inform.emit('[ERROR_NOTCL] %s' % - _("Failed to parse recent project item list.")) + self.inform.emit('[ERROR_NOTCL] %s' % _("Failed to parse recent project item list.")) fp.close() return fp.close() @@ -11733,6 +11828,7 @@ class App(QtCore.QObject): def make_callback(func, fname): def opener(): func(fname) + return opener def reset_recent_files(): @@ -11753,12 +11849,12 @@ class App(QtCore.QObject): self.recent_projects = [] try: - fp = open(self.data_path + '/recent_projects.json', 'w') + frp = open(self.data_path + '/recent_projects.json', 'w') except IOError: App.log.error("Failed to open recent projects items file for writing.") return - json.dump(self.recent, fp) + json.dump(self.recent, frp) # Reset menu self.ui.recent.clear() @@ -11833,51 +11929,51 @@ class App(QtCore.QObject): sel_title.setTextInteractionFlags(QtCore.Qt.NoTextInteraction) sel_title.setFrameStyle(QtWidgets.QFrame.NoFrame) - settings = QSettings("Open Source", "FlatCAM") - if settings.contains("notebook_font_size"): - fsize = settings.value('notebook_font_size', type=int) + f_settings = QSettings("Open Source", "FlatCAM") + if f_settings.contains("notebook_font_size"): + fsize = f_settings.value('notebook_font_size', type=int) else: fsize = 12 tsize = fsize + int(fsize / 2) -# selected_text = (_(''' -#

Selected Tab - Choose an Item from Project Tab

-# -#

Details:
-# The normal flow when working in FlatCAM is the following:

-# -#
    -#
  1. Loat/Import a Gerber, Excellon, Gcode, DXF, Raster Image or SVG file into + # selected_text = (_(''' + #

    Selected Tab - Choose an Item from Project Tab

    + # + #

    Details:
    + # The normal flow when working in FlatCAM is the following:

    + # + #
      + #
    1. Loat/Import a Gerber, Excellon, Gcode, DXF, Raster Image or SVG file into # FlatCAM using either the menu's, toolbars, key shortcuts or # even dragging and dropping the files on the GUI.
      -#
      -# You can also load a FlatCAM project by double clicking on the project file, drag & drop of the + #
      + # You can also load a FlatCAM project by double clicking on the project file, drag & drop of the # file into the FLATCAM GUI or through the menu/toolbar links offered within the app.

      -#  
    2. -#
    3. Once an object is available in the Project Tab, by selecting it and then + #  
    4. + #
    5. Once an object is available in the Project Tab, by selecting it and then # focusing on SELECTED TAB (more simpler is to double click the object name in the # Project Tab), SELECTED TAB will be updated with the object properties according to # it's kind: Gerber, Excellon, Geometry or CNCJob object.
      -#
      -# If the selection of the object is done on the canvas by single click instead, and the SELECTED TAB + #
      + # If the selection of the object is done on the canvas by single click instead, and the SELECTED TAB # is in focus, again the object properties will be displayed into the Selected Tab. Alternatively, # double clicking on the object on the canvas will bring the SELECTED TAB and populate # it even if it was out of focus.
      -#
      -# You can change the parameters in this screen and the flow direction is like this:
      -#
      -# Gerber/Excellon Object -> Change Param -> Generate Geometry -> Geometry Object + #
      + # You can change the parameters in this screen and the flow direction is like this:
      + #
      + # Gerber/Excellon Object -> Change Param -> Generate Geometry -> Geometry Object # -> Add tools (change param in Selected Tab) -> Generate CNCJob -> CNCJob Object # -> Verify GCode (through Edit CNC Code) and/or append/prepend to GCode (again, done in # SELECTED TAB) -> Save GCode
    6. -#
    -# -#

    A list of key shortcuts is available through an menu entry in + #

+ # + #

A list of key shortcuts is available through an menu entry in # Help -> Shortcuts List or through it's own key shortcut: # F3.

-# -# ''').format(fsize=fsize, tsize=tsize)) + # + # ''').format(fsize=fsize, tsize=tsize)) selected_text = '''

{title}

@@ -11966,20 +12062,22 @@ class App(QtCore.QObject): self.log.debug("version_check()") if self.ui.general_defaults_form.general_app_group.send_stats_cb.get_value() is True: - full_url = App.version_url + \ - "?s=" + str(self.defaults['global_serial']) + \ - "&v=" + str(self.version) + \ - "&os=" + str(self.os) + \ - "&" + urllib.parse.urlencode(self.defaults["global_stats"]) + full_url = "%s?s=%s&v=%s&os=%s&%s" % ( + App.version_url, + str(self.defaults['global_serial']), + str(self.version), + str(self.os), + urllib.parse.urlencode(self.defaults["global_stats"]) + ) + # full_url = App.version_url + "?s=" + str(self.defaults['global_serial']) + \ + # "&v=" + str(self.version) + "&os=" + str(self.os) + "&" + \ + # urllib.parse.urlencode(self.defaults["global_stats"]) else: # no_stats dict; just so it won't break things on website no_ststs_dict = {} no_ststs_dict["global_ststs"] = {} - full_url = App.version_url + \ - "?s=" + str(self.defaults['global_serial']) + \ - "&v=" + str(self.version) + \ - "&os=" + str(self.os) + \ - "&" + urllib.parse.urlencode(no_ststs_dict["global_ststs"]) + full_url = App.version_url + "?s=" + str(self.defaults['global_serial']) + "&v=" + str(self.version) + \ + "&os=" + str(self.os) + "&" + urllib.parse.urlencode(no_ststs_dict["global_ststs"]) App.log.debug("Checking for updates @ %s" % full_url) # ## Get the data @@ -11988,16 +12086,14 @@ class App(QtCore.QObject): except Exception: # 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] %s' % - _("Failed checking for latest version. Could not connect.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("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] %s' % - _("Could not parse information about latest version.")) + self.inform.emit('[ERROR_NOTCL] %s' % _("Could not parse information about latest version.")) App.log.debug("json.load(): %s" % str(e)) f.close() return @@ -12007,15 +12103,17 @@ class App(QtCore.QObject): # ## Latest version? if self.version >= data["version"]: App.log.debug("FlatCAM is up to date!") - self.inform.emit('[success] %s' % - _("FlatCAM is up to date!")) + self.inform.emit('[success] %s' % _("FlatCAM is up to date!")) return App.log.debug("Newer version available.") self.message.emit( _("Newer Version Available"), - _("There is a newer version of FlatCAM available for download:\n\n") + - "%s" % str(data["name"]) + "\n%s" % str(data["message"]), + '%s

>%s
%s' % ( + _("There is a newer version of FlatCAM available for download:"), + str(data["name"]), + str(data["message"]) + ), _("info") ) @@ -12054,7 +12152,7 @@ class App(QtCore.QObject): self.plotcanvas.native.setFocus() if self.is_legacy is False: - pan_button = 2 if self.defaults["global_pan_button"] == '2'else 3 + pan_button = 2 if self.defaults["global_pan_button"] == '2' else 3 # Set the mouse button for panning self.plotcanvas.view.camera.pan_button_setting = pan_button @@ -12185,12 +12283,12 @@ class App(QtCore.QObject): def worker_task(objs): with self.proc_container.new(_("Enabling plots ...")): - for obj in objs: + for plot_obj in objs: # obj.options['plot'] = True - if isinstance(obj, FlatCAMCNCjob): - obj.plot(visible=True, kind=self.defaults["cncjob_plot_kind"]) + if isinstance(plot_obj, FlatCAMCNCjob): + plot_obj.plot(visible=True, kind=self.defaults["cncjob_plot_kind"]) else: - obj.plot(visible=True) + plot_obj.plot(visible=True) self.worker_task.emit({'fcn': worker_task, 'params': [objects]}) @@ -12237,12 +12335,12 @@ class App(QtCore.QObject): # self.plots_updated.emit() def worker_task(objs): with self.proc_container.new(_("Disabling plots ...")): - for obj in objs: + for plot_obj in objs: # obj.options['plot'] = True - if isinstance(obj, FlatCAMCNCjob): - obj.plot(visible=False, kind=self.defaults["cncjob_plot_kind"]) + if isinstance(plot_obj, FlatCAMCNCjob): + plot_obj.plot(visible=False, kind=self.defaults["cncjob_plot_kind"]) else: - obj.plot(visible=False) + plot_obj.plot(visible=False) self.worker_task.emit({'fcn': worker_task, 'params': [objects]}) @@ -12514,8 +12612,8 @@ class App(QtCore.QObject): del tb_settings # if quit: - # t = threading.Thread(target=lambda: self.check_project_file_size(1, filename=filename)) - # t.start() + # t = threading.Thread(target=lambda: self.check_project_file_size(1, filename=filename)) + # t.start() self.start_delayed_quit(delay=500, filename=filename, should_quit=quit_action) def start_delayed_quit(self, delay, filename, should_quit=None): @@ -12608,7 +12706,7 @@ class App(QtCore.QObject): # self.tcl = None # TODO we need to clean non default variables and procedures here # new object cannot be used here as it will not remember values created for next passes, - # because tcl was execudted in old instance of TCL + # because tcl was executed in old instance of TCL pass else: self.tcl = tk.Tcl() @@ -12624,120 +12722,120 @@ class App(QtCore.QObject): self.log.debug("setup_shell()") - def shelp(p=None): - pass + # def shelp(p=None): + # pass # --- Migrated to new architecture --- # def options(name): # ops = self.collection.get_by_name(str(name)).options # return '\n'.join(["%s: %s" % (o, ops[o]) for o in ops]) - def h(*args): - """ - Pre-processes arguments to detect '-keyword value' pairs into dictionary - and standalone parameters into list. - """ + # def h(*args): + # """ + # Pre-processes arguments to detect '-keyword value' pairs into dictionary + # and standalone parameters into list. + # """ + # + # kwa = {} + # a = [] + # n = len(args) + # name = None + # for i in range(n): + # match = re.search(r'^-([a-zA-Z].*)', args[i]) + # if match: + # assert name is None + # name = match.group(1) + # continue + # + # if name is None: + # a.append(args[i]) + # else: + # kwa[name] = args[i] + # name = None + # + # return a, kwa - kwa = {} - a = [] - n = len(args) - name = None - for i in range(n): - match = re.search(r'^-([a-zA-Z].*)', args[i]) - if match: - assert name is None - name = match.group(1) - continue - - if name is None: - a.append(args[i]) - else: - kwa[name] = args[i] - name = None - - return a, kwa - - @contextmanager - def wait_signal(signal, timeout=10000): - """ - Block loop until signal emitted, timeout (ms) elapses - or unhandled exception happens in a thread. - - :param timeout: time after which the loop is exited - :param signal: Signal to wait for. - """ - loop = QtCore.QEventLoop() - - # Normal termination - signal.connect(loop.quit) - - # Termination by exception in thread - self.thread_exception.connect(loop.quit) - - status = {'timed_out': False} - - def report_quit(): - status['timed_out'] = True - loop.quit() - - yield - - # Temporarily change how exceptions are managed. - oeh = sys.excepthook - ex = [] - - def except_hook(type_, value, traceback_): - ex.append(value) - oeh(type_, value, traceback_) - - sys.excepthook = except_hook - - # Terminate on timeout - if timeout is not None: - QtCore.QTimer.singleShot(timeout, report_quit) - - # # ## Block ## ## - loop.exec_() - - # Restore exception management - sys.excepthook = oeh - if ex: - self.raise_tcl_error(str(ex[0])) - - if status['timed_out']: - raise Exception('Timed out!') - - def make_docs(): - output = '' - import collections - od = collections.OrderedDict(sorted(self.tcl_commands_storage.items())) - for cmd_, val in od.items(): - output += cmd_ + ' \n' + ''.join(['~'] * len(cmd_)) + '\n' - - t = val['help'] - usage_i = t.find('>') - if usage_i < 0: - expl = t - output += expl + '\n\n' - continue - - expl = t[:usage_i - 1] - output += expl + '\n\n' - - end_usage_i = t[usage_i:].find('\n') - - if end_usage_i < 0: - end_usage_i = len(t[usage_i:]) - output += ' ' + t[usage_i:] + '\n No parameters.\n' - else: - extras = t[usage_i + end_usage_i + 1:] - parts = [s.strip() for s in extras.split('\n')] - - output += ' ' + t[usage_i:usage_i + end_usage_i] + '\n' - for p in parts: - output += ' ' + p + '\n\n' - - return output + # @contextmanager + # def wait_signal(signal, timeout=10000): + # """ + # Block loop until signal emitted, timeout (ms) elapses + # or unhandled exception happens in a thread. + # + # :param timeout: time after which the loop is exited + # :param signal: Signal to wait for. + # """ + # loop = QtCore.QEventLoop() + # + # # Normal termination + # signal.connect(loop.quit) + # + # # Termination by exception in thread + # self.thread_exception.connect(loop.quit) + # + # status = {'timed_out': False} + # + # def report_quit(): + # status['timed_out'] = True + # loop.quit() + # + # yield + # + # # Temporarily change how exceptions are managed. + # oeh = sys.excepthook + # ex = [] + # + # def except_hook(type_, value, traceback_): + # ex.append(value) + # oeh(type_, value, traceback_) + # + # sys.excepthook = except_hook + # + # # Terminate on timeout + # if timeout is not None: + # QtCore.QTimer.singleShot(timeout, report_quit) + # + # # # ## Block ## ## + # loop.exec_() + # + # # Restore exception management + # sys.excepthook = oeh + # if ex: + # self.raise_tcl_error(str(ex[0])) + # + # if status['timed_out']: + # raise Exception('Timed out!') + # + # def make_docs(): + # output = '' + # import collections + # od = collections.OrderedDict(sorted(self.tcl_commands_storage.items())) + # for cmd_, val in od.items(): + # output += cmd_ + ' \n' + ''.join(['~'] * len(cmd_)) + '\n' + # + # t = val['help'] + # usage_i = t.find('>') + # if usage_i < 0: + # expl = t + # output += expl + '\n\n' + # continue + # + # expl = t[:usage_i - 1] + # output += expl + '\n\n' + # + # end_usage_i = t[usage_i:].find('\n') + # + # if end_usage_i < 0: + # end_usage_i = len(t[usage_i:]) + # output += ' ' + t[usage_i:] + '\n No parameters.\n' + # else: + # extras = t[usage_i + end_usage_i + 1:] + # parts = [s.strip() for s in extras.split('\n')] + # + # output += ' ' + t[usage_i:usage_i + end_usage_i] + '\n' + # for p in parts: + # output += ' ' + p + '\n\n' + # + # return output ''' Howto implement TCL shell commands: diff --git a/flatcamTools/ToolDblSided.py b/flatcamTools/ToolDblSided.py index 202e9d98..26aba20c 100644 --- a/flatcamTools/ToolDblSided.py +++ b/flatcamTools/ToolDblSided.py @@ -315,6 +315,7 @@ class DblSidedTool(FlatCAMTool): # Center point value self.center_entry = FCEntry() + self.center_entry.setPlaceholderText(_("Center point coordinates")) self.center_btn = FCButton('%s:' % _("Centroid")) self.center_btn.setToolTip( @@ -503,7 +504,6 @@ class DblSidedTool(FlatCAMTool): lambda: self.point_entry.set_value(self.center_entry.get_value()) ) - self.create_alignment_hole_button.clicked.connect(self.on_create_alignment_holes) self.calculate_bb_button.clicked.connect(self.on_bbox_coordinates) From b569fa174897017e1f59326d9eda791030b52023 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 24 Apr 2020 04:51:55 +0300 Subject: [PATCH 198/209] - added a new menu entry in the context menu of the Tcl Shell: 'Save Log' which will save the content of the Tcl Shell browser window to a file --- CHANGELOG.md | 2 ++ FlatCAMApp.py | 63 ++++++++++++++++++++++++++++++++++- flatcamGUI/GUIElements.py | 14 ++++++-- flatcamTools/ToolShell.py | 11 +++--- tclCommands/TclCommandHelp.py | 4 +-- 5 files changed, 84 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e9d0fc19..4800f47c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ CHANGELOG for FlatCAM beta - some PEP changes, some method descriptions updated - added a placeholder text to 2Sided Tool +- added a new menu entry in the context menu of the Tcl Shell: 'Save Log' which will save the content of the Tcl Shell browser window to a file + 23.04.2020 diff --git a/FlatCAMApp.py b/FlatCAMApp.py index cb5a7f0d..eeddfbfd 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -3971,7 +3971,7 @@ class App(QtCore.QObject): self.date = ''.join(c for c in self.date if c not in ':-') self.date = self.date.replace(' ', '_') - filter__ = "Config File (*.FlatConfig);;All Files (*.*)" + filter__ = "Config File .FlatConfig (*.FlatConfig);;All Files (*.*)" try: filename, _f = FCFileSaveDialog.get_saved_filename( caption=_("Export FlatCAM Preferences"), @@ -4032,6 +4032,67 @@ class App(QtCore.QObject): self.file_saved.emit("preferences", filename) self.inform.emit('[success] %s: %s' % (_("Exported preferences to"), filename)) + def save_to_file(self, content_to_save): + """ + Save something to a file. + + :return: None + """ + self.report_usage("save_to_file") + App.log.debug("save_to_file()") + + self.date = str(datetime.today()).rpartition('.')[0] + self.date = ''.join(c for c in self.date if c not in ':-') + self.date = self.date.replace(' ', '_') + + filter__ = "HTML File .html (*.html);;All Files (*.*)" + path_to_save = self.defaults["global_last_save_folder"] if\ + self.defaults["global_last_save_folder"] is not None else self.data_path + try: + filename, _f = FCFileSaveDialog.get_saved_filename( + caption=_("Save to file"), + directory=path_to_save + '/file_' + self.date, + filter=filter__ + ) + except TypeError: + filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Save to file"), filter=filter__) + + filename = str(filename) + + if filename == "": + self.inform.emit('[WARNING_NOTCL] %s' % _("Saving to file cancelled.")) + return + else: + try: + f = open(filename, 'w') + defaults_file_content = f.read() + f.close() + except PermissionError: + self.inform.emit('[WARNING] %s' % + _("Permission denied, saving not possible.\n" + "Most likely another app is holding the file open and not accessible.")) + return + except IOError: + App.log.debug('Creating a new file ...') + f = open(filename, 'w') + f.close() + except Exception: + e = sys.exc_info()[0] + App.log.error("Could not load the file.") + App.log.error(str(e)) + self.inform.emit('[ERROR_NOTCL] %s' % _("Could not load the file.")) + return + + # Save content + try: + with open(filename, "w") as f: + f.write(content_to_save) + except Exception: + self.inform.emit('[ERROR_NOTCL] %s %s' % (_("Failed to write defaults to file."), str(filename))) + return + + self.inform.emit('[success] %s: %s' % (_("Exported file to"), filename)) + def save_geometry(self, x, y, width, height, notebook_width): """ Will save the application geometry and positions in the defaults discitionary to be restored at the next diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index 7d5b4e49..08abd842 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -2568,13 +2568,19 @@ class _BrowserTextEdit(QTextEdit): def contextMenuEvent(self, event): self.menu = self.createStandardContextMenu(event.pos()) - clear_action = QAction("Clear", self) + + if self.app: + save_action = QAction(_("Save Log"), self) + self.menu.addAction(save_action) + save_action.triggered.connect(lambda: self.save_log(app=self.app)) + + clear_action = QAction(_("Clear"), self) clear_action.setShortcut(QKeySequence(Qt.Key_Delete)) # it's not working, the shortcut self.menu.addAction(clear_action) clear_action.triggered.connect(self.clear) if self.app: - close_action = QAction("Close", self) + close_action = QAction(_("Close"), self) self.menu.addAction(close_action) close_action.triggered.connect(lambda: self.app.ui.shell_dock.hide()) @@ -2588,6 +2594,10 @@ class _BrowserTextEdit(QTextEdit): self.moveCursor(QTextCursor.End) self.insertHtml(text) + def save_log(self, app): + html_content = self.toHtml() + app.save_to_file(content_to_save=html_content) + class _ExpandableTextEdit(QTextEdit): """ diff --git a/flatcamTools/ToolShell.py b/flatcamTools/ToolShell.py index 0f8a5f0f..e5fb0af1 100644 --- a/flatcamTools/ToolShell.py +++ b/flatcamTools/ToolShell.py @@ -118,7 +118,7 @@ class TermWidget(QWidget): scrollbar = self._browser.verticalScrollBar() old_value = scrollbar.value() - scrollattheend = old_value == scrollbar.maximum() + # scrollattheend = old_value == scrollbar.maximum() self._browser.moveCursor(QTextCursor.End) self._browser.insertHtml(text) @@ -251,11 +251,12 @@ class FCShell(TermWidget): self._sysShell = sysShell def is_command_complete(self, text): - def skipQuotes(text): - quote = text[0] - text = text[1:] - endIndex = str(text).index(quote) + def skipQuotes(txt): + quote = txt[0] + text_val = txt[1:] + endIndex = str(text_val).index(quote) return text[endIndex:] + while text: if text[0] in ('"', "'"): try: diff --git a/tclCommands/TclCommandHelp.py b/tclCommands/TclCommandHelp.py index d083f949..35348be0 100644 --- a/tclCommands/TclCommandHelp.py +++ b/tclCommands/TclCommandHelp.py @@ -9,7 +9,6 @@ from tclCommands.TclCommand import TclCommand import collections -import math import gettext import FlatCAMTranslation as fcTranslate @@ -109,6 +108,7 @@ class TclCommandHelp(TclCommand): displayed_text = ['> %s\n' % cmd for cmd in sorted(self.app.tcl_commands_storage)] cmd_enum += '
'.join(displayed_text) - cmd_enum += '

%s
%s' % (_("Type help for usage."), _("Example: help open_gerber")) + cmd_enum += '

%s
%s
' % ( + _("Type help for usage."), _("Example: help open_gerber")) self.app.shell.append_raw(cmd_enum) From 26dd29e7ddebce0f1259643af11f1598dcfb1882 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 24 Apr 2020 06:59:49 +0300 Subject: [PATCH 199/209] - the status bar messages that are echoed in the Tcl Shell will no longer have all text colored but only the identifier --- CHANGELOG.md | 2 +- FlatCAMApp.py | 4 ++-- flatcamGUI/GUIElements.py | 8 ++++++-- flatcamTools/ToolShell.py | 21 +++++++++++++++++---- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4800f47c..52148964 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ CHANGELOG for FlatCAM beta - some PEP changes, some method descriptions updated - added a placeholder text to 2Sided Tool - added a new menu entry in the context menu of the Tcl Shell: 'Save Log' which will save the content of the Tcl Shell browser window to a file - +- the status bar messages that are echoed in the Tcl Shell will no longer have all text colored but only the identifier 23.04.2020 diff --git a/FlatCAMApp.py b/FlatCAMApp.py index eeddfbfd..7bbf3518 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -2561,8 +2561,8 @@ class App(QtCore.QObject): self.shell.setWindowIcon(self.ui.app_icon) self.shell.setWindowTitle("FlatCAM Shell") self.shell.resize(*self.defaults["global_shell_shape"]) - self.shell.append_output("FlatCAM %s - " % self.version) - self.shell.append_output(_("Type >help< to get started\n\n")) + self.shell._append_to_browser('in', "FlatCAM %s - " % self.version) + self.shell.append_output('%s\n\n' % _("Type >help< to get started")) self.ui.shell_dock.setWidget(self.shell) diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index 08abd842..040cf540 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -2588,9 +2588,13 @@ class _BrowserTextEdit(QTextEdit): def clear(self): QTextEdit.clear(self) - text = "FlatCAM %s - Type >help< to get started\n\n" % self.version + + text = "!FlatCAM %s? - %s" % (self.version, _("Type >help< to get started")) text = html.escape(text) - text = text.replace('\n', '
') + # hack so I can make text bold because the escape method will replace the '<' and '>' signs with html code + text = text.replace('!', '') + text = text.replace('?', '') + text += '

' self.moveCursor(QTextCursor.End) self.insertHtml(text) diff --git a/flatcamTools/ToolShell.py b/flatcamTools/ToolShell.py index e5fb0af1..edbb3c7d 100644 --- a/flatcamTools/ToolShell.py +++ b/flatcamTools/ToolShell.py @@ -101,20 +101,33 @@ class TermWidget(QWidget): text = text.replace('\n', '
') text = text.replace('\t', '        ') + idx = text.find(']') + mtype = text[:idx+1].upper() + mtype = mtype.replace('_NOTCL', '') + body = text[idx+1:] if style == 'in': text = '%s' % text elif style == 'err': - text = '%s' % text + text = '%s'\ + '%s'\ + %(mtype, body) elif style == 'warning': - text = '%s' % text + # text = '%s' % text + text = '%s' \ + '%s' \ + % (mtype, body) elif style == 'success': - text = '%s' % text + # text = '%s' % text + text = '%s' \ + '%s' \ + % (mtype, body) elif style == 'selected': text = '' elif style == 'raw': text = text else: - text = '%s' % text # without span
is ignored!!! + # without span
is ignored!!! + text = '%s' % text scrollbar = self._browser.verticalScrollBar() old_value = scrollbar.value() From 7df7e17569fad0df5060b38ee751a63caf78caf7 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 24 Apr 2020 07:23:14 +0300 Subject: [PATCH 200/209] - some message strings cleanup --- CHANGELOG.md | 1 + FlatCAMApp.py | 98 ++++++++++++----------------- FlatCAMCommon.py | 12 ++-- ObjectCollection.py | 2 +- flatcamEditors/FlatCAMExcEditor.py | 6 +- flatcamEditors/FlatCAMGeoEditor.py | 13 ++-- flatcamEditors/FlatCAMGrbEditor.py | 6 +- flatcamEditors/FlatCAMTextEditor.py | 2 +- flatcamGUI/FlatCAMGUI.py | 20 +++--- flatcamTools/ToolFilm.py | 4 +- flatcamTools/ToolImage.py | 2 +- flatcamTools/ToolMove.py | 4 +- flatcamTools/ToolNCC.py | 6 +- flatcamTools/ToolPaint.py | 6 +- flatcamTools/ToolPcbWizard.py | 4 +- flatcamTools/ToolProperties.py | 2 +- flatcamTools/ToolQRCode.py | 4 +- flatcamTools/ToolSolderPaste.py | 14 ++--- tclCommands/TclCommandGeoCutout.py | 23 ++++--- 19 files changed, 102 insertions(+), 127 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52148964..957a38fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ CHANGELOG for FlatCAM beta - added a placeholder text to 2Sided Tool - added a new menu entry in the context menu of the Tcl Shell: 'Save Log' which will save the content of the Tcl Shell browser window to a file - the status bar messages that are echoed in the Tcl Shell will no longer have all text colored but only the identifier +- some message strings cleanup 23.04.2020 diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 7bbf3518..401f5655 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -2961,7 +2961,7 @@ class App(QtCore.QObject): if project_name == "": if silent is False: - self.inform.emit(_("Open cancelled.")) + self.inform.emit(_("Cancelled.")) else: # self.open_project(project_name) run_from_arg = True @@ -3881,7 +3881,7 @@ class App(QtCore.QObject): filename = self.data_path + '/factory_defaults.FlatConfig' if filename == "": - self.inform.emit('[WARNING_NOTCL] %s' % _("Preferences default restore was cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) else: try: f = open(filename) @@ -3930,7 +3930,7 @@ class App(QtCore.QObject): filename = str(filename) if filename == "": - self.inform.emit('[WARNING_NOTCL] %s' % _("FlatCAM preferences import cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) else: try: f = open(filename) @@ -3985,7 +3985,7 @@ class App(QtCore.QObject): defaults_from_file = {} if filename == "": - self.inform.emit('[WARNING_NOTCL] %s' % _("FlatCAM preferences export cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) return else: try: @@ -4060,7 +4060,7 @@ class App(QtCore.QObject): filename = str(filename) if filename == "": - self.inform.emit('[WARNING_NOTCL] %s' % _("Saving to file cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) return else: try: @@ -6104,7 +6104,7 @@ class App(QtCore.QObject): val_x = float(self.defaults['global_gridx']) val_y = float(self.defaults['global_gridy']) - self.inform.emit('[WARNING_NOTCL]%s' % _("Units conversion cancelled.")) + self.inform.emit('[WARNING_NOTCL]%s' % _("Cancelled.")) self.defaults_read_form() @@ -7368,7 +7368,7 @@ class App(QtCore.QObject): self.report_usage("on_locate()") if obj is None: - self.inform.emit('[WARNING_NOTCL] %s' % _("There is no object selected...")) + self.inform.emit('[WARNING_NOTCL] %s' % _("No object selected.")) return 'fail' class DialogBoxChoice(QtWidgets.QDialog): @@ -9470,7 +9470,7 @@ class App(QtCore.QObject): color=QtGui.QColor("gray")) if len(filenames) == 0: - self.inform.emit('[WARNING_NOTCL] %s' % _("Open Gerber cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) else: for filename in filenames: if filename != '': @@ -9507,8 +9507,7 @@ class App(QtCore.QObject): color=QtGui.QColor("gray")) if len(filenames) == 0: - self.inform.emit('[WARNING_NOTCL]%s' % - _(" Open Excellon cancelled.")) + self.inform.emit('[WARNING_NOTCL]%s' % _("Cancelled.")) else: for filename in filenames: if filename != '': @@ -9550,8 +9549,7 @@ class App(QtCore.QObject): color=QtGui.QColor("gray")) if len(filenames) == 0: - self.inform.emit('[WARNING_NOTCL] %s' % - _("Open G-Code cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) else: for filename in filenames: if filename != '': @@ -9580,8 +9578,7 @@ class App(QtCore.QObject): filename = str(filename) if filename == "": - self.inform.emit('[WARNING_NOTCL] %s' % - _("Open Project cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) else: # self.worker_task.emit({'fcn': self.open_project, # 'params': [filename]}) @@ -9621,7 +9618,7 @@ class App(QtCore.QObject): color=QtGui.QColor("gray")) if len(filenames) == 0: - self.inform.emit('[WARNING_NOTCL] %s' % _("Open HPGL2 file cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) else: for filename in filenames: if filename != '': @@ -9646,8 +9643,7 @@ class App(QtCore.QObject): filter=_filter_) if filename == "": - self.inform.emit('[WARNING_NOTCL] %s' % - _("Open Config cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) else: self.open_config_file(filename) @@ -9662,8 +9658,7 @@ class App(QtCore.QObject): obj = self.collection.get_active() if obj is None: - self.inform.emit('[WARNING_NOTCL] %s' % - _("No object selected.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("No object selected.")) msg = _("Please Select a Geometry object to export") msgbox = QtWidgets.QMessageBox() msgbox.setInformativeText(msg) @@ -9700,8 +9695,7 @@ class App(QtCore.QObject): filename = str(filename) if filename == "": - self.inform.emit('[WARNING_NOTCL]%s' % - _(" Export SVG cancelled.")) + self.inform.emit('[WARNING_NOTCL]%s' % _("Cancelled.")) return else: self.export_svg(name, filename) @@ -9737,7 +9731,7 @@ class App(QtCore.QObject): filename = str(filename) if filename == "": - self.inform.emit(_("Export PNG cancelled.")) + self.inform.emit(_("Cancelled.")) return else: if self.is_legacy is False: @@ -9760,8 +9754,7 @@ class App(QtCore.QObject): obj = self.collection.get_active() if obj is None: - self.inform.emit('[WARNING_NOTCL] %s' % - _("No object selected. Please select an Gerber object to export.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("No object selected.")) return # Check for more compatible types and add as required @@ -9784,8 +9777,7 @@ class App(QtCore.QObject): filename = str(filename) if filename == "": - self.inform.emit('[WARNING_NOTCL] %s' % - _("Save Gerber source file cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) return else: self.save_source_file(name, filename) @@ -9804,14 +9796,12 @@ class App(QtCore.QObject): obj = self.collection.get_active() if obj is None: - self.inform.emit('[WARNING_NOTCL] %s' % - _("No object selected. Please select an Script object to export.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("No object selected.")) return # Check for more compatible types and add as required if not isinstance(obj, FlatCAMScript): - self.inform.emit('[ERROR_NOTCL] %s' % - _("Failed. Only Script objects can be saved as TCL Script files...")) + self.inform.emit('[ERROR_NOTCL] %s' % _("Failed. Only Script objects can be saved as TCL Script files...")) return name = self.collection.get_active().options["name"] @@ -9828,8 +9818,7 @@ class App(QtCore.QObject): filename = str(filename) if filename == "": - self.inform.emit('[WARNING_NOTCL] %s' % - _("Save Script source file cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) return else: self.save_source_file(name, filename) @@ -9848,14 +9837,12 @@ class App(QtCore.QObject): obj = self.collection.get_active() if obj is None: - self.inform.emit('[WARNING_NOTCL] %s' % - _("No object selected. Please select an Document object to export.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("No object selected.")) return # Check for more compatible types and add as required if not isinstance(obj, FlatCAMScript): - self.inform.emit('[ERROR_NOTCL] %s' % - _("Failed. Only Document objects can be saved as Document files...")) + self.inform.emit('[ERROR_NOTCL] %s' % _("Failed. Only Document objects can be saved as Document files...")) return name = self.collection.get_active().options["name"] @@ -9872,8 +9859,7 @@ class App(QtCore.QObject): filename = str(filename) if filename == "": - self.inform.emit('[WARNING_NOTCL] %s' % - _("Save Document source file cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) return else: self.save_source_file(name, filename) @@ -9892,14 +9878,12 @@ class App(QtCore.QObject): obj = self.collection.get_active() if obj is None: - self.inform.emit('[WARNING_NOTCL] %s' % - _("No object selected. Please select an Excellon object to export.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("No object selected.")) return # Check for more compatible types and add as required if not isinstance(obj, FlatCAMExcellon): - self.inform.emit('[ERROR_NOTCL] %s' % - _("Failed. Only Excellon objects can be saved as Excellon files...")) + self.inform.emit('[ERROR_NOTCL] %s' % _("Failed. Only Excellon objects can be saved as Excellon files...")) return name = self.collection.get_active().options["name"] @@ -9916,8 +9900,7 @@ class App(QtCore.QObject): filename = str(filename) if filename == "": - self.inform.emit('[WARNING_NOTCL] %s' % - _("Saving Excellon source file cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) return else: self.save_source_file(name, filename) @@ -9936,8 +9919,7 @@ class App(QtCore.QObject): obj = self.collection.get_active() if obj is None: - self.inform.emit('[WARNING_NOTCL] %s' % - _("No object selected. Please Select an Excellon object to export.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("No object selected.")) return # Check for more compatible types and add as required @@ -9959,7 +9941,7 @@ class App(QtCore.QObject): filename = str(filename) if filename == "": - self.inform.emit('[WARNING_NOTCL] %s' % _("Export Excellon cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) return else: used_extension = filename.rpartition('.')[2] @@ -9981,14 +9963,12 @@ class App(QtCore.QObject): obj = self.collection.get_active() if obj is None: - self.inform.emit('[WARNING_NOTCL] %s' % - _("No object selected. Please Select an Gerber object to export.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("No object selected.")) return # Check for more compatible types and add as required if not isinstance(obj, FlatCAMGerber): - self.inform.emit('[ERROR_NOTCL] %s' % - _("Failed. Only Gerber objects can be saved as Gerber files...")) + self.inform.emit('[ERROR_NOTCL] %s' % _("Failed. Only Gerber objects can be saved as Gerber files...")) return name = self.collection.get_active().options["name"] @@ -10005,7 +9985,7 @@ class App(QtCore.QObject): filename = str(filename) if filename == "": - self.inform.emit('[WARNING_NOTCL] %s' % _("Export Gerber cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) return else: used_extension = filename.rpartition('.')[2] @@ -10061,7 +10041,7 @@ class App(QtCore.QObject): filename = str(filename) if filename == "": - self.inform.emit('[WARNING_NOTCL] %s' % _("Export DXF cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) return else: self.export_dxf(name, filename) @@ -10093,7 +10073,7 @@ class App(QtCore.QObject): filenames = [str(filename) for filename in filenames] if len(filenames) == 0: - self.inform.emit('[WARNING_NOTCL] %s' % _("Open SVG cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) else: for filename in filenames: if filename != '': @@ -10125,7 +10105,7 @@ class App(QtCore.QObject): filenames = [str(filename) for filename in filenames] if len(filenames) == 0: - self.inform.emit('[WARNING_NOTCL] %s' % _("Open DXF cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) else: for filename in filenames: if filename != '': @@ -10362,7 +10342,7 @@ class App(QtCore.QObject): if len(filenames) == 0: if silent is False: - self.inform.emit('[WARNING_NOTCL] %s' % _("Open TCL script cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) else: for filename in filenames: if filename != '': @@ -10406,7 +10386,7 @@ class App(QtCore.QObject): if filename == "": if silent is False: - self.inform.emit('[WARNING_NOTCL] %s' % _("Run TCL script cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) else: if self.cmd_line_headless != 1: if self.ui.shell_dock.isHidden(): @@ -10483,7 +10463,7 @@ class App(QtCore.QObject): filename = str(filename) if filename == '': - self.inform.emit('[WARNING_NOTCL] %s' % _("Save Project cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) return if use_thread is True: @@ -10538,7 +10518,7 @@ class App(QtCore.QObject): filename = str(filename) if filename == '': - self.inform.emit('[WARNING_NOTCL] %s' % _("Save Object PDF cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) return if use_thread is True: diff --git a/FlatCAMCommon.py b/FlatCAMCommon.py index 52c42d92..cabf0e47 100644 --- a/FlatCAMCommon.py +++ b/FlatCAMCommon.py @@ -368,7 +368,7 @@ class BookmarkManager(QtWidgets.QWidget): filename = str(filename) if filename == "": - self.app.inform.emit('[WARNING_NOTCL] %s' % _("FlatCAM bookmarks export cancelled.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) return else: try: @@ -410,7 +410,7 @@ class BookmarkManager(QtWidgets.QWidget): filename = str(filename) if filename == "": - self.app.inform.emit('[WARNING_NOTCL] %s' % _("FlatCAM bookmarks import cancelled.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) else: try: with open(filename) as f: @@ -1104,7 +1104,7 @@ class ToolsDB(QtWidgets.QWidget): filename = str(filename) if filename == "": - self.app.inform.emit('[WARNING_NOTCL] %s' % _("FlatCAM Tools DB export cancelled.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) return else: try: @@ -1150,7 +1150,7 @@ class ToolsDB(QtWidgets.QWidget): filename, _f = QtWidgets.QFileDialog.getOpenFileName(caption=_("Import FlatCAM Tools DB"), filter=filter__) if filename == "": - self.app.inform.emit('[WARNING_NOTCL] %s' % _("FlatCAM Tools DB import cancelled.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) else: try: with open(filename) as f: @@ -2534,7 +2534,7 @@ class ToolsDB2(QtWidgets.QWidget): filename = str(filename) if filename == "": - self.app.inform.emit('[WARNING_NOTCL] %s' % _("FlatCAM Tools DB export cancelled.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) return else: try: @@ -2580,7 +2580,7 @@ class ToolsDB2(QtWidgets.QWidget): filename, _f = QtWidgets.QFileDialog.getOpenFileName(caption=_("Import FlatCAM Tools DB"), filter=filter__) if filename == "": - self.app.inform.emit('[WARNING_NOTCL] %s' % _("FlatCAM Tools DB import cancelled.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) else: try: with open(filename) as f: diff --git a/ObjectCollection.py b/ObjectCollection.py index 79a1326d..1108683a 100644 --- a/ObjectCollection.py +++ b/ObjectCollection.py @@ -119,7 +119,7 @@ class KeySensitiveListView(QtWidgets.QTreeView): # file drop from outside application if drop_indicator == QtWidgets.QAbstractItemView.OnItem: if self.filename == "": - self.app.inform.emit(_("Open cancelled.")) + self.app.inform.emit(_("Cancelled.")) else: if self.filename.lower().rpartition('.')[-1] in self.app.grb_list: self.app.worker_task.emit({'fcn': self.app.open_gerber, diff --git a/flatcamEditors/FlatCAMExcEditor.py b/flatcamEditors/FlatCAMExcEditor.py index 313c59a2..2baaac5d 100644 --- a/flatcamEditors/FlatCAMExcEditor.py +++ b/flatcamEditors/FlatCAMExcEditor.py @@ -1021,8 +1021,7 @@ class FCDrillResize(FCShapeTool): self.geometry.append(DrawToolShape(new_poly)) else: # unexpected geometry so we cancel - self.draw_app.app.inform.emit('[ERROR_NOTCL] %s' % - _("Cancelled.")) + self.draw_app.app.inform.emit('[ERROR_NOTCL] %s' % _("Cancelled.")) return # remove the geometry with the old size @@ -1090,8 +1089,7 @@ class FCDrillResize(FCShapeTool): except KeyError: # if the exception happen here then we are not dealing with slots neither # therefore something else is not OK so we return - self.draw_app.app.inform.emit('[ERROR_NOTCL] %s' % - _("Cancelled.")) + self.draw_app.app.inform.emit('[ERROR_NOTCL] %s' % _("Cancelled.")) return # this simple hack is used so we can delete form self.draw_app.selected but diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index 7601cc24..a3761201 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -581,7 +581,7 @@ class PaintOptionsTool(FlatCAMTool): def on_paint(self): if not self.fcdraw.selected: - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Paint cancelled. No shape selected.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. No shape selected.")) return tooldia = self.painttooldia_entry.get_value() @@ -1053,7 +1053,7 @@ class TransformEditorTool(FlatCAMTool): def template(self): if not self.draw_app.selected: - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Transformation cancelled. No shape selected.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. No shape selected.")) return self.draw_app.select_tool("select") @@ -3022,7 +3022,7 @@ class FCBuffer(FCShapeTool): def on_buffer(self): if not self.draw_app.selected: - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Buffer cancelled. No shape selected.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. No shape selected.")) return try: @@ -3050,7 +3050,7 @@ class FCBuffer(FCShapeTool): def on_buffer_int(self): if not self.draw_app.selected: - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Buffer cancelled. No shape selected.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. No shape selected.")) return try: @@ -3078,7 +3078,7 @@ class FCBuffer(FCShapeTool): def on_buffer_ext(self): if not self.draw_app.selected: - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Buffer cancelled. No shape selected.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. No shape selected.")) return try: @@ -4499,8 +4499,7 @@ class FlatCAMGeoEditor(QtCore.QObject): def on_copy_click(self): if not self.selected: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Copy cancelled. No shape selected.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. No shape selected.")) return self.app.ui.geo_copy_btn.setChecked(True) diff --git a/flatcamEditors/FlatCAMGrbEditor.py b/flatcamEditors/FlatCAMGrbEditor.py index c6cd2ed0..a1052495 100644 --- a/flatcamEditors/FlatCAMGrbEditor.py +++ b/flatcamEditors/FlatCAMGrbEditor.py @@ -4262,8 +4262,7 @@ class FlatCAMGrbEditor(QtCore.QObject): # self.draw_app.select_tool('select') self.complete = True current_tool = 'select' - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Cancelled. No aperture is selected")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. No aperture is selected")) # This is to make the group behave as radio group if current_tool in self.tools_gerber: @@ -5599,8 +5598,7 @@ class TransformEditorTool(FlatCAMTool): def template(self): if not self.fcdraw.selected: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Transformation cancelled. No shape selected.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. No shape selected.")) return self.draw_app.select_tool("select") diff --git a/flatcamEditors/FlatCAMTextEditor.py b/flatcamEditors/FlatCAMTextEditor.py index 9159d823..d65dfd7c 100644 --- a/flatcamEditors/FlatCAMTextEditor.py +++ b/flatcamEditors/FlatCAMTextEditor.py @@ -220,7 +220,7 @@ class TextEditor(QtWidgets.QWidget): filename = str(FCFileSaveDialog.get_saved_filename(caption=_("Export Code ..."), filter=_filter_)[0]) if filename == "": - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Export Code cancelled.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) return else: try: diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index 394af02e..905ad9fe 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -3614,8 +3614,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.app.grb_editor.delete_selected() self.app.grb_editor.plot_all() else: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Cancelled. Nothing selected to delete.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. Nothing selected to delete.")) return # Delete aperture in apertures table if delete key event comes from the Selected Tab @@ -3699,8 +3698,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.app.grb_editor.active_tool.set_origin( (self.app.grb_editor.snap_x, self.app.grb_editor.snap_y)) else: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Cancelled. Nothing selected to copy.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. Nothing selected to copy.")) return # Add Disc Tool @@ -3746,8 +3744,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.app.grb_editor.active_tool.set_origin( (self.app.grb_editor.snap_x, self.app.grb_editor.snap_y)) else: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Cancelled. Nothing selected to move.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. Nothing selected to move.")) return # Add Region Tool @@ -3828,8 +3825,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.app.exc_editor.delete_selected() self.app.exc_editor.replot() else: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Cancelled. Nothing selected to delete.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. Nothing selected to delete.")) return # Delete tools in tools table if delete key event comes from the Selected Tab @@ -3945,8 +3941,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.app.exc_editor.active_tool.set_origin( (self.app.exc_editor.snap_x, self.app.exc_editor.snap_y)) else: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Cancelled. Nothing selected to copy.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. Nothing selected to copy.")) return # Add Drill Hole Tool @@ -3975,8 +3970,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.app.exc_editor.active_tool.set_origin( (self.app.exc_editor.snap_x, self.app.exc_editor.snap_y)) else: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Cancelled. Nothing selected to move.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. Nothing selected to move.")) return # Add Array of Slots Hole Tool @@ -4131,7 +4125,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.filename = str(url.toLocalFile()) if self.filename == "": - self.app.inform.emit("Open cancelled.") + self.app.inform.emit("Cancelled.") else: extension = self.filename.lower().rpartition('.')[-1] diff --git a/flatcamTools/ToolFilm.py b/flatcamTools/ToolFilm.py index 42787e5a..68dfadd4 100644 --- a/flatcamTools/ToolFilm.py +++ b/flatcamTools/ToolFilm.py @@ -751,7 +751,7 @@ class Film(FlatCAMTool): filename = str(filename) if str(filename) == "": - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Export positive film cancelled.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) return else: pagesize = self.pagesize_combo.get_value() @@ -897,7 +897,7 @@ class Film(FlatCAMTool): filename = str(filename) if str(filename) == "": - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Export negative film cancelled.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) return else: self.export_negative(name, boxname, filename, border, diff --git a/flatcamTools/ToolImage.py b/flatcamTools/ToolImage.py index 603fb9e1..f984d7a0 100644 --- a/flatcamTools/ToolImage.py +++ b/flatcamTools/ToolImage.py @@ -244,7 +244,7 @@ class ToolImage(FlatCAMTool): self.mask_b_entry.get_value()] if filename == "": - self.app.inform.emit(_("Open cancelled.")) + self.app.inform.emit(_("Cancelled.")) else: self.app.worker_task.emit({'fcn': self.import_image, 'params': [filename, type_obj, dpi, mode, mask]}) diff --git a/flatcamTools/ToolMove.py b/flatcamTools/ToolMove.py index 9b21c2da..0e89764c 100644 --- a/flatcamTools/ToolMove.py +++ b/flatcamTools/ToolMove.py @@ -111,7 +111,7 @@ class ToolMove(FlatCAMTool): self.draw_sel_bbox() else: self.toggle() - self.app.inform.emit('[WARNING_NOTCL] %s' % _("MOVE action cancelled. No object(s) to move.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. No object(s) to move.")) def on_left_click(self, event): # mouse click will be accepted only if the left button is clicked @@ -267,7 +267,7 @@ class ToolMove(FlatCAMTool): def on_key_press(self, event): if event.key == 'escape': # abort the move action - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Move action cancelled.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled.")) self.toggle() return diff --git a/flatcamTools/ToolNCC.py b/flatcamTools/ToolNCC.py index ed43f9f3..4b4f4e0f 100644 --- a/flatcamTools/ToolNCC.py +++ b/flatcamTools/ToolNCC.py @@ -1457,7 +1457,7 @@ class NonCopperClear(FlatCAMTool, Gerber): if float('%.*f' % (self.decimals, tool_dia)) in tool_dias: if muted is None: - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Adding tool cancelled. Tool already in Tool Table.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. Tool already in Tool Table.")) # self.tools_table.itemChanged.connect(self.on_tool_edit) self.blockSignals(False) @@ -1520,7 +1520,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] %s' % _("Edit cancelled. " + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. " "New diameter value is already in the Tool Table.")) self.blockSignals(False) self.build_ui() @@ -4010,7 +4010,7 @@ class NonCopperClear(FlatCAMTool, Gerber): tool_dias.append(float('%.*f' % (self.decimals, (v[tool_v])))) if float('%.*f' % (self.decimals, tooldia)) in tool_dias: - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Adding tool cancelled. Tool already in Tool Table.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. Tool already in Tool Table.")) self.ui_connect() return 'fail' diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index f0179501..4ad2890f 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -1193,7 +1193,7 @@ class ToolPaint(FlatCAMTool, Gerber): if float('%.*f' % (self.decimals, tool_dia)) in tool_dias: if muted is None: - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Adding tool cancelled. Tool already in Tool Table.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. Tool already in Tool Table.")) self.tools_table.itemChanged.connect(self.on_tool_edit) return else: @@ -1254,7 +1254,7 @@ class ToolPaint(FlatCAMTool, Gerber): restore_dia_item = self.tools_table.item(row, 1) restore_dia_item.setText(str(old_tool_dia)) self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Edit cancelled. New diameter value is already in the Tool Table.")) + _("Cancelled. New diameter value is already in the Tool Table.")) self.blockSignals(False) self.build_ui() @@ -4074,7 +4074,7 @@ class ToolPaint(FlatCAMTool, Gerber): tool_dias.append(float('%.*f' % (self.decimals, (v[tool_v])))) if float('%.*f' % (self.decimals, tooldia)) in tool_dias: - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Adding tool cancelled. Tool already in Tool Table.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. Tool already in Tool Table.")) self.ui_connect() return 'fail' diff --git a/flatcamTools/ToolPcbWizard.py b/flatcamTools/ToolPcbWizard.py index fbd57896..fe72dccc 100644 --- a/flatcamTools/ToolPcbWizard.py +++ b/flatcamTools/ToolPcbWizard.py @@ -298,7 +298,7 @@ class PcbWizard(FlatCAMTool): filename = str(filename) if filename == "": - self.app.inform.emit(_("Open cancelled.")) + self.app.inform.emit(_("Cancelled.")) else: self.app.worker_task.emit({'fcn': self.load_excellon, 'params': [filename]}) @@ -321,7 +321,7 @@ class PcbWizard(FlatCAMTool): filename = str(filename) if filename == "": - self.app.inform.emit(_("Open cancelled.")) + self.app.inform.emit(_("Cancelled.")) else: self.app.worker_task.emit({'fcn': self.load_inf, 'params': [filename]}) diff --git a/flatcamTools/ToolProperties.py b/flatcamTools/ToolProperties.py index 97ba0e04..3cd2656b 100644 --- a/flatcamTools/ToolProperties.py +++ b/flatcamTools/ToolProperties.py @@ -113,7 +113,7 @@ class Properties(FlatCAMTool): def properties(self): obj_list = self.app.collection.get_selected() if not obj_list: - self.app.inform.emit('[ERROR_NOTCL] %s' % _("Properties Tool was not displayed. No object selected.")) + self.app.inform.emit('[ERROR_NOTCL] %s' % _("No object selected.")) self.app.ui.notebook.setTabText(2, _("Tools")) self.properties_frame.hide() self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab) diff --git a/flatcamTools/ToolQRCode.py b/flatcamTools/ToolQRCode.py index bc5c1fd1..fdf01a08 100644 --- a/flatcamTools/ToolQRCode.py +++ b/flatcamTools/ToolQRCode.py @@ -788,7 +788,7 @@ class QRCode(FlatCAMTool): filename = str(filename) if filename == "": - self.app.inform.emit('[WARNING_NOTCL]%s' % _(" Export PNG cancelled.")) + self.app.inform.emit('[WARNING_NOTCL]%s' % _("Cancelled.")) return else: self.app.worker_task.emit({'fcn': job_thread_qr_png, 'params': [self.app, filename]}) @@ -835,7 +835,7 @@ class QRCode(FlatCAMTool): filename = str(filename) if filename == "": - self.app.inform.emit('[WARNING_NOTCL]%s' % _(" Export SVG cancelled.")) + self.app.inform.emit('[WARNING_NOTCL]%s' % _("Cancelled.")) return else: self.app.worker_task.emit({'fcn': job_thread_qr_svg, 'params': [self.app, filename]}) diff --git a/flatcamTools/ToolSolderPaste.py b/flatcamTools/ToolSolderPaste.py index 76582402..f471fd7f 100644 --- a/flatcamTools/ToolSolderPaste.py +++ b/flatcamTools/ToolSolderPaste.py @@ -914,14 +914,12 @@ class SolderPaste(FlatCAMTool): if float('%.*f' % (self.decimals, tool_dia)) in tool_dias: if muted is None: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Adding Nozzle tool cancelled. Tool already in Tool Table.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. Tool already in Tool Table.")) self.tools_table.itemChanged.connect(self.on_tool_edit) return else: if muted is None: - self.app.inform.emit('[success] %s' % - _("New Nozzle tool added to Tool Table.")) + self.app.inform.emit('[success] %s' % _("New Nozzle tool added to Tool Table.")) self.tooltable_tools.update({ int(self.tooluid): { 'tooldia': float('%.*f' % (self.decimals, tool_dia)), @@ -976,7 +974,7 @@ class SolderPaste(FlatCAMTool): restore_dia_item = self.tools_table.item(row, 1) restore_dia_item.setText(str(old_tool_dia)) self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Edit cancelled. New diameter value is already in the Tool Table.")) + _("Cancelled. New diameter value is already in the Tool Table.")) self.build_ui() def on_tool_delete(self, rows_to_delete=None, all=None): @@ -1241,12 +1239,10 @@ class SolderPaste(FlatCAMTool): if not geo_obj.tools[tooluid_key]['solid_geometry']: a += 1 if a == len(geo_obj.tools): - self.app.inform.emit('[ERROR_NOTCL] %s' % - _('Cancelled. Empty file, it has no geometry...')) + self.app.inform.emit('[ERROR_NOTCL] %s' % _('Cancelled. Empty file, it has no geometry...')) return 'fail' - app_obj.inform.emit('[success] %s...' % - _("Solder Paste geometry generated successfully")) + app_obj.inform.emit('[success] %s...' % _("Solder Paste geometry generated successfully")) return # if we still have geometry not processed at the end of the tools then we failed diff --git a/tclCommands/TclCommandGeoCutout.py b/tclCommands/TclCommandGeoCutout.py index 40118c53..7081be2c 100644 --- a/tclCommands/TclCommandGeoCutout.py +++ b/tclCommands/TclCommandGeoCutout.py @@ -7,8 +7,16 @@ from copy import deepcopy from shapely.ops import cascaded_union from shapely.geometry import Polygon, LineString, LinearRing +import gettext +import FlatCAMTranslation as fcTranslate +import builtins + log = logging.getLogger('base') +fcTranslate.apply_language('strings') +if '_' not in builtins.__dict__: + _ = gettext.gettext + class TclCommandGeoCutout(TclCommandSignaled): """ @@ -137,7 +145,7 @@ class TclCommandGeoCutout(TclCommandSignaled): 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] %s" % _("The name of the object for which cutout is done is missing. Add it and retry.")) return if 'margin' in args: @@ -173,12 +181,13 @@ class TclCommandGeoCutout(TclCommandSignaled): 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 real number.") + self.app.inform.emit( + "[WARNING] %s" % _("Tool Diameter is zero value. Change it to a positive real number.")) return "Tool Diameter is zero value. Change it to a positive real number." 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. " - "Fill in a correct value and retry. ") + self.app.inform.emit( + "[WARNING] %s" % _("Gaps value can be only one of: 'lr', 'tb', '2lr', '2tb', 4 or 8.")) return # Get min and max data for each object as we just cut rectangles across X or Y @@ -290,7 +299,7 @@ class TclCommandGeoCutout(TclCommandSignaled): app_obj.disable_plots(objects=[cutout_obj]) - app_obj.inform.emit("[success] Any-form Cutout operation finished.") + app_obj.inform.emit("[success] %s" % _("Any-form Cutout operation finished.")) self.app.new_object('geometry', outname, geo_init, plot=False) @@ -348,11 +357,11 @@ class TclCommandGeoCutout(TclCommandSignaled): geo_obj.options['ymin'] = cutout_obj.options['ymin'] geo_obj.options['xmax'] = cutout_obj.options['xmax'] geo_obj.options['ymax'] = cutout_obj.options['ymax'] - app_obj.inform.emit("[success] Any-form Cutout operation finished.") + app_obj.inform.emit("[success] %s" % _("Any-form Cutout operation finished.")) self.app.new_object('geometry', outname, geo_init, plot=False) 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] %s" % _("Cancelled. Object type is not supported.")) return From 527dcf62705eaecfbcd6e51666bbcd21a906ae50 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 24 Apr 2020 08:12:21 +0300 Subject: [PATCH 201/209] - added possibility to save as text file the content in Tcl Shell browser window when clicking the Save log context menu entry --- CHANGELOG.md | 640 ++++++++++---------------------------- FlatCAMApp.py | 16 +- flatcamGUI/GUIElements.py | 3 +- make_freezed.py | 4 +- 4 files changed, 183 insertions(+), 480 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 957a38fd..4c2e6796 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ CHANGELOG for FlatCAM beta - added a new menu entry in the context menu of the Tcl Shell: 'Save Log' which will save the content of the Tcl Shell browser window to a file - the status bar messages that are echoed in the Tcl Shell will no longer have all text colored but only the identifier - some message strings cleanup +- added possibility to save as text file the content in Tcl Shell browser window when clicking the Save log context menu entry 23.04.2020 @@ -3683,8 +3684,7 @@ saving an Excellon object from editor to FlatCAM, selecting drills by left click 27.09.2018 -- fixed bug when creating a new project, if a previous object was selected on screen, the selection shape -survived the creation of a new project +- fixed bug when creating a new project, if a previous object was selected on screen, the selection shape survived the creation of a new project - added compatibility with old type of FlatCAM projects - reverted modifications to the way that Excellon geometry was stored to the old way. - added exceptions for Paint functions so the user can know if something failed. @@ -3694,8 +3694,7 @@ survived the creation of a new project 26.09.2018 - disabled selection of objects in Project Tab when in Editor -- the Editor Toolbar is hidden in normal mode and it is showed when Editor -is activated. I may change this behaviour back. +- the Editor Toolbar is hidden in normal mode and it is showed when Editor is activated. I may change this behaviour back. - changed names in classes, functions to prepare for the Excellon editor - fixed bugs in Paint All function @@ -3704,63 +3703,45 @@ is activated. I may change this behaviour back. - moved all the Editor menu/toolbar creation to FlatCAMUI where they belong - fixed a Gerber parse number issue when Gerber zeros are TZ (keep trailing zeros) -- changed the way of how the solid_geometry for Excellon files is stored -and plotted. Before everything was put in the same "container". Now, -the geometries of drills and slots are organized into dictionaries having -as keys the tool diameters and as values list of Shapely objects (polygons) +- changed the way of how the solid_geometry for Excellon files is stored and plotted. Before everything was put in the same "container". Now, the geometries of drills and slots are organized into dictionaries having as keys the tool diameters and as values list of Shapely objects (polygons) - fix for Excellon plotting for newly created empty Excellon Object - fixed geometry.bounds() in camlib to work with the new format of the Excellon geometry (list of dicts) 24.09.2018 -- added packages in the Requirements and setup_ubuntu.sh. Tested in Ubuntu and -it's OK +- added packages in the Requirements and setup_ubuntu.sh. Tested in Ubuntu and it's OK - added Replace (All) feature in the CNC Code Editor - made CNC Code generation for Excellon to show progress -- added information about transforms in the object properties (like skew -and how much, if it was mirrored and so on) +- added information about transforms in the object properties (like skew and how much, if it was mirrored and so on) - made all the transforms threaded and make them show progress in the progress bar - made FlatCAM project saving, threaded. 23.09.2018 -- added support for "header-less" Excellon files. It seems that Mentor PADS does generate such -non-standard Excellon files. The user will have to guess: units (IN/MM), type of zero suppression LZ/TZ -(leading zeros or trailing zeros are kept) and Excellon number format(digits and decimals). -All of those can be adjusted in Menu -> Edit -> Preferences -> Excellon Object -> Excellon format -- fixed svgparse for Path. Now PCB rasted images can traced in Inkscape or PDF's can be converted -and then saved as SVG files which can be imported into FlatCAM. This is a convolute way to convert a PDF -to Gerber file. +- added support for "header-less" Excellon files. It seems that Mentor PADS does generate such non-standard Excellon files. The user will have to guess: units (IN/MM), type of zero suppression LZ/TZ (leading zeros or trailing zeros are kept) and Excellon number format(digits and decimals). All of those can be adjusted in Menu -> Edit -> Preferences -> Excellon Object -> Excellon format +- fixed svgparse for Path. Now PCB rasted images can traced in Inkscape or PDF's can be converted and then saved as SVG files which can be imported into FlatCAM. This is a convolute way to convert a PDF to Gerber file. 22.09.2018 -- added Drag & Drop capability. Now the user can drag and drop to FlatCAM GUI interface a file -(with the right extension) that can be a FlatCAM project file (.FlatPrj) a Gerber file, -an Excellon file, a G-Code file or a SVG file. +- added Drag & Drop capability. Now the user can drag and drop to FlatCAM GUI interface a file (with the right extension) that can be a FlatCAM project file (.FlatPrj) a Gerber file, an Excellon file, a G-Code file or a SVG file. - made the Move Tool command threaded - added Image import into FlatCAM 21.09.2018 -- added new information's in the object properties: all used Tool-Table items -are included in a new entry in self.options dictionary -- modified the preprocessor files so they now include information's about -how many drills (or slots) are for each tool. The Gcode will have this -information displayed on the message from ToolChange. +- added new information's in the object properties: all used Tool-Table items are included in a new entry in self.options dictionary +- modified the preprocessor files so they now include information's about how many drills (or slots) are for each tool. The Gcode will have this information displayed on the message from ToolChange. - removed some log.debug and add new log.debug especially for moments when some process is finished - fixed the utility geometry for Font geometry in Geometry Editor - work on selection in Geometry Editor -- added multiple selection key as a Preference in Menu -> Edit -> Preferences -It can be either Shift or Ctrl. +- added multiple selection key as a Preference in Menu -> Edit -> Preferences It can be either Shift or Ctrl. - fixed bug in Gerber Object -> Copper Clearing. - added more comprehensive tooltips in Non-copper Clearing as advice on how to proceed. -- adjusted make_win32.py file so it will work with Python 3.7 (cx_freeze can't copy OpenGL files, so -it has to be done manually) +- adjusted make_win32.py file so it will work with Python 3.7 (cx_freeze can't copy OpenGL files, so it has to be done manually) 19.09.2018 -- optimized loading FlatCAM project by double clicking on project file; there is no need to clean up everything by using -the function not Thread Safe: on_file_new() because there is nothing to clean since FlatCAM just started. +- optimized loading FlatCAM project by double clicking on project file; there is no need to clean up everything by using the function not Thread Safe: on_file_new() because there is nothing to clean since FlatCAM just started. - added a workspace delimitation with sizes A3, A4 and landscape or portrait format - The Workspace checkbox in Preferences GUI is doing toggle on the workspace @@ -3770,13 +3751,10 @@ the function not Thread Safe: on_file_new() because there is nothing to clean si - added an automatic defaults save on FlatCAM application close - made the draw method for the Workspace lines 'agg' so the quality of the FC objects will not be affected -- added Area constrain to the Panelization Tool: if the resulting area is too big to fit within constrains, the number -of columns and/or rows will be reduced to the maximum that still fits is. -- removed the Flip command from Panelization Tools because Flipping (Mirroring) should be done properly with the -Transform Tool or using the provided shortcut keys. +- added Area constrain to the Panelization Tool: if the resulting area is too big to fit within constrains, the number of columns and/or rows will be reduced to the maximum that still fits is. +- removed the Flip command from Panelization Tools because Flipping (Mirroring) should be done properly with the Transform Tool or using the provided shortcut keys. -- made Font parsing threaded so the application will not wait for the font parsing to complete therefore the app start -is faster +- made Font parsing threaded so the application will not wait for the font parsing to complete therefore the app start is faster 17.09.2018 @@ -3784,47 +3762,34 @@ is faster - fixed Measuring Tool not working when grid is turned OFF - fixed Roland MDX20 preprocessor - added a .GBR extension in the open_gerber filter -- added ability to Scale and Offset (for all types of objects) to just -press Enter after entering a value in the Entry just like in Tool Transform -- added capability in Tool Transform to mirror(flip) around a certain Point. -The point coordinates can either be entered by hand or they can be captured -by left clicking while pressing key "SHIFT" and then clicking the Add button +- added ability to Scale and Offset (for all types of objects) to just press Enter after entering a value in the Entry just like in Tool Transform +- added capability in Tool Transform to mirror(flip) around a certain Point. The point coordinates can either be entered by hand or they can be captured by left clicking while pressing key "SHIFT" and then clicking the Add button - added the .ROL extension when saving Machine Code - replaced strings that reference to G-Code from G-Code to CNC Code -- added capability to open a project by serving the path/project_name.FlatPrj as a parameter -to FlatCAM.py +- added capability to open a project by serving the path/project_name.FlatPrj as a parameter to FlatCAM.py 15.09.2018 - removed dwell line generator and included dwell generation in the preprocessor files - added a proposed RML1 Roland_MDX20 preprocessor file. -- added a limit of 15mm/sec (900mm/min) to the feedrate and to the feedrate_rapid. Anything faster than this -will be capped to 900mm/min regardless what is entered in the program GUI. This is because Roland MDX-20 has -a mechanical limit of the speed to 15mm/sec (900mm/min in GUI) +- added a limit of 15mm/sec (900mm/min) to the feedrate and to the feedrate_rapid. Anything faster than this will be capped to 900mm/min regardless what is entered in the program GUI. This is because Roland MDX-20 has a mechanical limit of the speed to 15mm/sec (900mm/min in GUI) 14.09.2018 -- remade the Double Sided Tool so it now include mirroring of Excellon and Geometry Objects along Gerber. -Made adding points easier by adding buttons to GUI that allow adding the coordinates captured by -left mouse click + SHIFT key -- added a few fixes in code to the other FlatCAM tools regarding reset_fields() function. The issue -was present when clicking New Project entry in Menu -> File. +- remade the Double Sided Tool so it now include mirroring of Excellon and Geometry Objects along Gerber. Made adding points easier by adding buttons to GUI that allow adding the coordinates captured by left mouse click + SHIFT key +- added a few fixes in code to the other FlatCAM tools regarding reset_fields() function. The issue was present when clicking New Project entry in Menu -> File. - FIXED: fix adding/updating bounding box coords for the mirrored objects in Double side Tool. - FIXED: fix the bounding box values from within FlatCAM objects, upon units change. -- fixed issue with running again the constructor of the drawing tools after the tool action was complete, -in Geometry Editor +- fixed issue with running again the constructor of the drawing tools after the tool action was complete, in Geometry Editor - fixed issue with Tool tab not closed after Text Input tool is finished. - fixed issue with TEXT to GEOMETRY tool, the resulting geometry was not scaled depending of current units -- fixed case when user is clicking on the canvas to place a Font Geometry without clicking apply button first -or the Font Geometry is empty, in Geometry Editor - > Text Input tool -- reworked Measuring Tool by adding more information's (START, STOP point coordinates) and remade the -strings +- fixed case when user is clicking on the canvas to place a Font Geometry without clicking apply button first or the Font Geometry is empty, in Geometry Editor - > Text Input tool +- reworked Measuring Tool by adding more information's (START, STOP point coordinates) and remade the strings - added to Double Sided Tool the ability to use as reference box Excellon and Geometry Objects 12.09.2018 - fixed Excellon Object class such that Excellon files that have both drills and slots are supported -- remade the GUI interface for the Excellon Object in a more compact way; added a column with slots numbers -(if any) along the drills numbers so now there is only one tool table for drills and slots. +- remade the GUI interface for the Excellon Object in a more compact way; added a column with slots numbers (if any) along the drills numbers so now there is only one tool table for drills and slots. - remade the GUI in Preferences and removed unwanted stretch that was broken the layout. - if for a certain tool, the slots number is zero it will not be displayed - reworked Text to Geometry feature to work in Linux and MacOS @@ -3833,16 +3798,12 @@ strings 09.09.2018 -- added TEXT ENTRY SUPPORT in Geometry Editor. It will convert strings of True Type Fonts to geometry. -The actual dimensions are approximations because font size is in points and not in metric or inch units. -For now full support is limited to Windows. In Linux/MacOS only the fonts for which the font name is the same -as the font filename are supported. Italic and Bold functions may not work in Linux/MacOS. +- added TEXT ENTRY SUPPORT in Geometry Editor. It will convert strings of True Type Fonts to geometry. The actual dimensions are approximations because font size is in points and not in metric or inch units. For now full support is limited to Windows. In Linux/MacOS only the fonts for which the font name is the same as the font filename are supported. Italic and Bold functions may not work in Linux/MacOS. - solved bug: some Drawing menu entries not having connected functions 28.08.2018 -- fixed Gerber parser so now G01 "moving" rectangular -aperture is supported. +- fixed Gerber parser so now G01 "moving" rectangular aperture is supported. - fixed import_svg function; it can import SVG as geometry (solved bug) - fixed import_svg function; it can import SVG as Gerber (it did not work previously) - added menu entry's for SVG import as Gerber and separated import as Geometry @@ -3853,119 +3814,73 @@ aperture is supported. 26.08.2018 -- added awareness for missing coordinates in Gerber parsing. It will try to use the previous coordinates but if there -are not any those lines will be ignored and an Warning will be printed in Tcl Shell. +- added awareness for missing coordinates in Gerber parsing. It will try to use the previous coordinates but if there are not any those lines will be ignored and an Warning will be printed in Tcl Shell. - fixed TCL commands AlignDrillGrid and DrilCncJob - added TCL script file load_and_run support in GUI -- made the tool_table in Excellon to automatically adjust the table height depending on the number of rows such that -all the rows will be displayed. +- made the tool_table in Excellon to automatically adjust the table height depending on the number of rows such that all the rows will be displayed. - structural changes in the Excellon build_ui() - icon changes and menu compress 23.08.2018 - added Excellon routing support -- solved a small bug that crippled Excellon slot G85 support when the coordinates -are with period. -- changed the way selection is done in Geometry Editor; now it should work -in all cases (although the method used may be computationally intensive, -because sometimes you have to click twice to make selection if you do it too fast) +- solved a small bug that crippled Excellon slot G85 support when the coordinates are with period. +- changed the way selection is done in Geometry Editor; now it should work in all cases (although the method used may be computationally intensive, because sometimes you have to click twice to make selection if you do it too fast) 21.08.2018 -- added Excellon slots support when using G85 command for generation of -the slots file. Inspired from the work of @mgix. Thanks. -Routing format support for slots will follow. -- minor bug solved: option "Cut over 1st pt" now has same name both in -Preferences -> Geometry Options and in Selected tab -> Geomety Object. -Solves #3 -- added option to select Climb or Conventional Milling in Gerber Object options -Solves #4 +- added Excellon slots support when using G85 command for generation of the slots file. Inspired from the work of @mgix. Thanks. Routing format support for slots will follow. +- minor bug solved: option "Cut over 1st pt" now has same name both in Preferences -> Geometry Options and in Selected tab -> Geomety Object. Solves #3 +- added option to select Climb or Conventional Milling in Gerber Object options Solves #4 - made "Combine passes" option to be saved as an app preference -- added Generate Exteriors Geo and Generate Interiors Geo buttons in the -Gerber Object properties -- added configuration for the number of steps used for Gerber circular aperture -linear approximation. The option is in Preferences -> Gerber Options -- added configuration for the number of steps used for Gcode circular aperture -linear approximation. The option is in Preferences -> CNCjob Options -- added configuration for the number of steps used for Geometry circular aperture -linear approximation. The option is in Preferences -> Geometry Options. It is used -on circles/arcs made in Geometry Editor and for other types of geometries generated in -the app. - +- added Generate Exteriors Geo and Generate Interiors Geo buttons in the Gerber Object properties +- added configuration for the number of steps used for Gerber circular aperture linear approximation. The option is in Preferences -> Gerber Options +- added configuration for the number of steps used for Gcode circular aperture linear approximation. The option is in Preferences -> CNCjob Options +- added configuration for the number of steps used for Geometry circular aperture linear approximation. The option is in Preferences -> Geometry Options. It is used on circles/arcs made in Geometry Editor and for other types of geometries generated in the app. 17.07.2018 - added the required packages in Requirements.txt file - added required packages in setup_ubuntu.sh file -- added color control over almost all the colors in the application; those -settings are in Menu -> Edit -> Preferences -> General Tab +- added color control over almost all the colors in the application; those settings are in Menu -> Edit -> Preferences -> General Tab - added configuration of which mouse button to be used when panning (MMB or RMB) -- fixed bug with missing 'drillz' parameter in function generate_from_excellon_by_tool() -(credits for finding it goes to Stefan Smith https://bitbucket.org/stefan064/) -- load Factory defaults in Preferences will load the defaults that are used just after -first install. Load Defaults option in Preferences will load the User saved Defaults. +- fixed bug with missing 'drillz' parameter in function generate_from_excellon_by_tool() (credits for finding it goes to Stefan Smith https://bitbucket.org/stefan064/) +- load Factory defaults in Preferences will load the defaults that are used just after first install. Load Defaults option in Preferences will load the User saved Defaults. 03.07.2018 -- fixed bug in rotate function that didn't update the bounding box of the -modified object (rotated) due of not emitting the right signal parameter. -- removed the Options tab from the Notebook (the left area where is located -also the Project tab). Replaced it with the Preferences Tab launched with -Menu -> Edit -> Preferences -- when FlatCAM is used under MacOS, multiple selection of shapes in Editor -mode is done using SHIFT key instead of CTRL key due of MacOS interpreting -Ctrl+LMB_click as a RMB click -- when in Editor, clicking not on a shape, reset the index of selected shapes -to zero -- added a new Tab in the Plot Area named Gcode Editor. It allow the user to -edit the Gcode and then Save it or Print it. -- added a fix so the 'preamble' Gcode is correctly inserted between the -comments header and the actual GCODE +- fixed bug in rotate function that didn't update the bounding box of the modified object (rotated) due of not emitting the right signal parameter. +- removed the Options tab from the Notebook (the left area where is located also the Project tab). Replaced it with the Preferences Tab launched with Menu -> Edit -> Preferences +- when FlatCAM is used under MacOS, multiple selection of shapes in Editor mode is done using SHIFT key instead of CTRL key due of MacOS interpreting Ctrl+LMB_click as a RMB click +- when in Editor, clicking not on a shape, reset the index of selected shapes to zero +- added a new Tab in the Plot Area named Gcode Editor. It allow the user to edit the Gcode and then Save it or Print it. +- added a fix so the 'preamble' Gcode is correctly inserted between the comments header and the actual GCODE - added Find function in G-Code Editor - 27.06.2018 -- the Plot Area tab is changing name to "Editor Area" when the Editor is -activated and returns to the "Plot Area" name upon exiting the Editor -- made the labels shorter in Transform Tool in anticipation of -Options Tab removal from Notebook and replacing it with Preferences -- the Excellon Editor is not finished (not even started yet) so the -Plot Area title should stay "Plot Area" not change to "Editor Area" when -attempting to edit an Excellon file. Solved. -- added a header comment block in the generated Gcode with useful -information's -- fixed issue that did not allow the Nightly's to be run in -Windows 7 x64. The reason was an outdated DLL file (freetype.dll) used -by Vispy python module. - +- the Plot Area tab is changing name to "Editor Area" when the Editor is activated and returns to the "Plot Area" name upon exiting the Editor +- made the labels shorter in Transform Tool in anticipation of Options Tab removal from Notebook and replacing it with Preferences +- the Excellon Editor is not finished (not even started yet) so the Plot Area title should stay "Plot Area" not change to "Editor Area" when attempting to edit an Excellon file. Solved. +- added a header comment block in the generated Gcode with useful information's +- fixed issue that did not allow the Nightly's to be run in Windows 7 x64. The reason was an outdated DLL file (freetype.dll) used by Vispy python module. 25.06.2018 - "New" menu entry in Menu -> File is renamed to "New Project" -- on "New Project" action, all the Tools are reinitialized so the Tools -tab will work as expected +- on "New Project" action, all the Tools are reinitialized so the Tools tab will work as expected - fixed issue in Film Tool when generating black film - fixed Measurement Tool acquiring and releasing the mouse/key events - fixed cursor shape is updated on grid_toggle -- added some infobar messages to show the user when the Editor was -activated and when it was closed (control returned to App). -- added thread usage for Film tool; now the App is no longer blocked on -film generation and there is a visual clue that the App is working +- added some infobar messages to show the user when the Editor was activated and when it was closed (control returned to App). +- added thread usage for Film tool; now the App is no longer blocked on film generation and there is a visual clue that the App is working 22.06.2018 -- added export PNG image functionality and menu entry in -Menu -> File -> Export PNG ... -- added a command to set focus on canvas inside the mouve move event -handler; once the mouse is moved the focus is moved to canvas so the -shortcuts work immediatly. -- solved a small bug when using the 'C' key to copy name of the selected -object to clipboard - -- fixed millholes() function and isolate() so now it works even when the -tool diameter is the same as the hole diameter. +- added export PNG image functionality and menu entry in Menu -> File -> Export PNG ... +- added a command to set focus on canvas inside the mouve move event handler; once the mouse is moved the focus is moved to canvas so the shortcuts work immediatly. +- solved a small bug when using the 'C' key to copy name of the selected object to clipboard +- fixed millholes() function and isolate() so now it works even when the tool diameter is the same as the hole diameter. Actually if the passed value to the buffer() function is zero, I artificially add a value of 0.0000001 (FlatCAM has a precision of @@ -3974,120 +3889,67 @@ because the value has to be positive. This may have solved for some use cases the user complaints that on clearing the areas of copper there is still copper leftovers. -- added shortcut "Shift+G" to toggle the axis presence. Useful when one -wants to save a PNG file. +- added shortcut "Shift+G" to toggle the axis presence. Useful when one wants to save a PNG file. - changed color of the grid from 'gray' to 'dimgray' - - the selection shape is deleted when the object is deleted - - the plot area is now in a TAB. - solved bug that allowed middle button click to create selection - fixed issue with main window geometry restore (hopefully). -- made view toolbar to be hidden by default as it is not really needed -(we have the functions in menu, zoom is done with mouse wheel, and there -is also the canvas context menu that holds the functionality) +- made view toolbar to be hidden by default as it is not really needed (we have the functions in menu, zoom is done with mouse wheel, and there is also the canvas context menu that holds the functionality) - remade the GUIElements.FCInput() and made a GUIElements.FCTab() - on visibility plot toogle the selection shape is deleted - -- made sure that on panning in Geometry editor, the context menu is not -displayed -- disabled App shortcut keys on entry in Geometry Editor so only the -local shortcut keys are working - +- made sure that on panning in Geometry editor, the context menu is not displayed +- disabled App shortcut keys on entry in Geometry Editor so only the local shortcut keys are working - deleted metric units in canvas context menu -- added protection so object deletion can't be done until Geometry -Editor session is finished. Solved bug when the shapes on Geometry -Editor were not transfered to the New_geometry object yet and the -New_Geometry object is deleted. In this case the drawn shapes are left -in a intermediary state on canvas. - -- added selection shape drawing in Geometry Editor preserving the -current behavior: click to select, click on canvas clear selection, -Ctrl+click add to selection new shape but remove from selection -if already selected. Drag LMB from left to right select enclosed -shapes, drag LMB from right to left select touching shapes. Now the -selection is made based on -- added info message to be displayed in infobar, when a object is -renamed +- added protection so object deletion can't be done until Geometry Editor session is finished. Solved bug when the shapes on Geometry Editor were not transferred to the New_geometry object yet and the New_Geometry object is deleted. In this case the drawn shapes are left in a intermediary state on canvas. +- added selection shape drawing in Geometry Editor preserving the current behavior: click to select, click on canvas clear selection, Ctrl+click add to selection new shape but remove from selection if already selected. Drag LMB from left to right select enclosed shapes, drag LMB from right to left select touching shapes. Now the selection is made based on +- added info message to be displayed in infobar, when a object is renamed 20.06.2018 -- there are two types of mouse drag selection (rectangle selection) -If there is a rectangle selection from left to right, the color of the -selection rectangle is blue and the selection is "enclosing" - this -means that the object to be selected has to be enclosed by the selecting -blue rectangle shape. -If there is a rectangle selection fro right to left, the color of the -selection rectangle is green and the selection is "touching" - this -means that it's enough to touch with the selecting green rectangle the -object(s) to be selected so they become selected -- changed the modifier key required to be pressed when LMB is ckicked -over canvas in order to copy to clipboard the coordinates of the click, -from CTRL to SHIFT. CTRL will be used for multiple selection. +- there are two types of mouse drag selection (rectangle selection). If there is a rectangle selection from left to right, the color of the selection rectangle is blue and the selection is "enclosing" - this means that the object to be selected has to be enclosed by the selecting blue rectangle shape. If there is a rectangle selection fro right to left, the color of the selection rectangle is green and the selection is "touching" - this means that it's enough to touch with the selecting green rectangle the object(s) to be selected so they become selected +- changed the modifier key required to be pressed when LMB is ckicked over canvas in order to copy to clipboard the coordinates of the click, from CTRL to SHIFT. CTRL will be used for multiple selection. - change the entry names in the canvas context menu -- disconnected the app mouse event functions while in geometry editor -since the geometry editor has it's own mouse event functions and there -was interference between object and geometry items. Exception for the -mouse release event so the canvas context menu still work. -- solved a bug that did not update the obj.options after a geometry -object was edited in geometry editor -- solved a bug in the signal that saved the position and dimensions of -the application window. -- solved a bug in app.on_preferences() that created an error when run -in Linux +- disconnected the app mouse event functions while in geometry editor since the geometry editor has it's own mouse event functions and there was interference between object and geometry items. Exception for the mouse release event so the canvas context menu still work. +- solved a bug that did not update the obj.options after a geometry object was edited in geometry editor +- solved a bug in the signal that saved the position and dimensions of the application window. +- solved a bug in app.on_preferences() that created an error when run in Linux 18.06.2018 Update 1 -- reverted the 'units' parameter change to 'global_units' due of a bug -that did not allow saving of the project -- modified the camlib transform (rotate, mirror, scale etc) functions -so now they work with Gerber file loaded with 'follow' parameter +- reverted the 'units' parameter change to 'global_units' due of a bug that did not allow saving of the project +- modified the camlib transform (rotate, mirror, scale etc) functions so now they work with Gerber file loaded with 'follow' parameter 18.06.2018 -- reworked the Properties context menu option to a Tool that displays -more informations on the selected object(s) +- reworked the Properties context menu option to a Tool that displays more informations on the selected object(s) - remade the FlatCAM project extension as .FlatPrj - rearranged the toolbar menu entries to a more properly order -- objects can now be selected on canvas, a blue polygon is drawn around -when selected +- objects can now be selected on canvas, a blue polygon is drawn around when selected - reworked the Tool Move so it will work with the new canvas selection -- reworked the Measurement Tool so it will work with the new canvas -selection -- canvas selection can now be done by dragging left mouse boutton and -creating a selection box over the objects -- when the objects are overlapped on canvas, the mouse click -selection works in a circular way, selecting the first, then the second, -then ..., then the last and then again the first and so on. +- reworked the Measurement Tool so it will work with the new canvas selection +- canvas selection can now be done by dragging left mouse boutton and creating a selection box over the objects +- when the objects are overlapped on canvas, the mouse click selection works in a circular way, selecting the first, then the second, then ..., then the last and then again the first and so on. - double click on a object on canvas will open the Selected Tab - each object store the bounding box coordinates in the options dict -- the bbox coordinates are updated on the obj options when the object -is modified by a transform function (rotate, scale etc) +- the bbox coordinates are updated on the obj options when the object is modified by a transform function (rotate, scale etc) 15.06.2018 -- the selection marker when moving is now a semitransparent Polygon -with a blue border -- rectified a small typo in the ToolTip for Excellon Format for -Diptrace excellon format; from 4:2 to 5:2 +- the selection marker when moving is now a semitransparent Polygon with a blue border +- rectified a small typo in the ToolTip for Excellon Format for Diptrace excellon format; from 4:2 to 5:2 - corrected an error that cause no Gcode could be saved - 14.06.2018 - more work on the contextual menu - added Draw context menu -- added a new tool that bring together all the transformations, named -Transformation Tool (Rotate, Skew, Scale, Offset, Flip) +- added a new tool that bring together all the transformations, named Transformation Tool (Rotate, Skew, Scale, Offset, Flip) - added shorcut key 'Q' which toggle the units between IN and MM -- remade the Move tool, there is now a selection box to show where the -move is done -- remade the Measurement tool, there is now a line between the start -point of measurement and the end point of the measurement. -- renamed most of the system variables that have a global app effect to -global_name where name is the parameter (variable) - +- remade the Move tool, there is now a selection box to show where the move is done +- remade the Measurement tool, there is now a line between the start point of measurement and the end point of the measurement. +- renamed most of the system variables that have a global app effect to global_name where name is the parameter (variable) 9.06.2018 @@ -4099,153 +3961,89 @@ global_name where name is the parameter (variable) 6.06.2018 Update - fixed bug: G-Code could not be saved -- fixed bug: double clicking a category in Project Tab made the app to -crash -- remade the bounds() function to work with nested lists of objects as -per advice from JP which made the operation less performance taxing. +- fixed bug: double clicking a category in Project Tab made the app to crash +- remade the bounds() function to work with nested lists of objects as per advice from JP which made the operation less performance taxing. - added shortcut Shift+R that is complement to 'R' -- shorcuts 'R' and 'Shift+R' are working now in steps of 90 degrees -instead of previous 45 degrees. -- added filters in the open ... FlatCAM projects are saved automatically -as *.flat, the Gerber files have few categories. So the Excellons and -G-Code and SVG. +- shorcuts 'R' and 'Shift+R' are working now in steps of 90 degrees instead of previous 45 degrees. +- added filters in the open ... FlatCAM projects are saved automatically as *.flat, the Gerber files have few categories. So the Excellons and G-Code and SVG. 6.06.2018 -- remade the transform functions (rotate, flip, skew) so they are now -working for joined objects, too -- modified the Skew and Rotate comamands: if they are applied over a -selection of objects than the origin point will be the center of the -biggest bounding box. That allow for perfect sync between the selected -objects +- remade the transform functions (rotate, flip, skew) so they are now working for joined objects, too +- modified the Skew and Rotate comamands: if they are applied over a selection of objects than the origin point will be the center of the biggest bounding box. That allow for perfect sync between the selected objects - started to modify the program so the exceptions are handled correctly -- solved bug where a crash occur when ObjCollection.setData didn't -return a bool value -- work in progress for handling situations when a different file is -loaded as another (like loading a Gerber file using Open Excellon - commands. -- added filters on open_gerber and open_excellon Dialogs. There is still -the ability to select All Files but this should reduce the cases when -the user is trying to oprn a file from a wrong place. +- solved bug where a crash occur when ObjCollection.setData didn't return a bool value +- work in progress for handling situations when a different file is loaded as another (like loading a Gerber file using Open Excellon commands. +- added filters on open_gerber and open_excellon Dialogs. There is still the ability to select All Files but this should reduce the cases when the user is trying to oprn a file from a wrong place. 4.06.2018 -- finished PyQt4 to PyQt4 port on the Vispy variant (there were some changes -compared with the Matplotlib version for which the port was finished -some time ago) -- added Ctrl+S shortcut for the Geometry Editor. When is activated it will -save de geometry ("update") and return to the main App. -- modified the Mirror command for the case when multiple objects are -selected and we want to mirror all together. In this case they should mirror -around a bounding box to fill all. +- finished PyQt4 to PyQt4 port on the Vispy variant (there were some changes compared with the Matplotlib version for which the port was finished some time ago) +- added Ctrl+S shortcut for the Geometry Editor. When is activated it will save de geometry ("update") and return to the main App. +- modified the Mirror command for the case when multiple objects are selected and we want to mirror all together. In this case they should mirror around a bounding box to fill all. 3.06.2018 - removed the current drill path optimizations as they are inefficient -- implemented Google OR-tools drill path optimization in 2 flavors; -Basic OR-tools TSP algorithm and OR-Tools Metaheuristics Guided Local Path +- implemented Google OR-tools drill path optimization in 2 flavors; Basic OR-tools TSP algorithm and OR-Tools Metaheuristics Guided Local Path - Move tool is moved to Menu -> Edit under the name Move Object -- solved some internal bugs (info command was creating an non-fatal -error in PyQt, regarding using QPixMaps outside GUI thread +- solved some internal bugs (info command was creating an non-fatal error in PyQt, regarding using QPixMaps outside GUI thread - reworked camlib number parsing (still had some bugs) - working in porting the application from usage of PyQt4 to PyQt4 -- added TclCommands save_sys and list_sys. save_sys is saving all the -system default parameters and list_sys is listing them by the first -letters. listsys with no arguments will list all the system parameters. +- added TclCommands save_sys and list_sys. save_sys is saving all the system default parameters and list_sys is listing them by the first letters. listsys with no arguments will list all the system parameters. 29.05.2018 - modified the labels for the X,Y and Dx,Dy coordinates - modified the menu entries, added more icons - added initial work on a Excellon Editor -- modified the behavior of when clicking on canvas the coordinates were -copied to cliboard: now it is required to press CTRL key for this to -happen, and it will only happen just for left mouse button click +- modified the behavior of when clicking on canvas the coordinates were copied to cliboard: now it is required to press CTRL key for this to happen, and it will only happen just for left mouse button click - removed the autocopy of the object name on new object creation - remade the Tcl commands drillcncjob and cncjob -- added fix so the canvas is focused on the start of the program, -therefore the shortcuts work without the need for doing first a click -on canvas. - - +- added fix so the canvas is focused on the start of the program, therefore the shortcuts work without the need for doing first a click on canvas. 28.05.2018 -- added total drill count column in Excellon Tool Table which displays the -total number of drills +- added total drill count column in Excellon Tool Table which displays the total number of drills - added aliases in panelize Tool (pan and panel should work) -- modified generate_milling method which had issues from the Python3 port -(it could not sort the tools due of dict to dict comparison no longer -possible). -- modified the 'default' preprocessor in order to include a space -between the value of Xcoord and the following Y -- made optional the using of threads for the milling command; by default -it is OFF (False) because in the current configuration it creates issues -when it is using threads -- modified the Panelize function and Tcl command Panelize. It was having -issues due to multithreading (kept trying to modify a dictionary in -redraw() method)and automatically selecting the last created object -(feature introduced by me). I've added a parameter to -the new_object method, named autoselected (by default it is True) and -in the panelize method I initialized it with False. -By initializing the plot parameter with False for the temporary objects, -I have increased dramatically the generation speed of the panel because -now the temporary object are no longer ploted which consumed time. +- modified generate_milling method which had issues from the Python3 port (it could not sort the tools due of dict to dict comparison no longer possible). +- modified the 'default' preprocessor in order to include a space between the value of Xcoord and the following Y +- made optional the using of threads for the milling command; by default it is OFF (False) because in the current configuration it creates issues when it is using threads +- modified the Panelize function and Tcl command Panelize. It was having issues due to multithreading (kept trying to modify a dictionary in redraw() method)and automatically selecting the last created object (feature introduced by me). I've added a parameter to the new_object method, named autoselected (by default it is True) and in the panelize method I initialized it with False. +By initializing the plot parameter with False for the temporary objects, I have increased dramatically the generation speed of the panel because now the temporary object are no longer ploted which consumed time. - replaced log.warn() with log.warning() in camlib.py. Reason: deprecated -- fixed the issue that the "Defaults" button was having no effect when -clicked and Options Combo was in Project Options -- fixed issue with Tcl Shell loosing focus after each command, therefore -needing to click in the edit line before we type a new command (borrowed -from @brainstorm -- added a header in the preprocessor files mentioning that the GCODE -files were generated by FlatCAM. +- fixed the issue that the "Defaults" button was having no effect when clicked and Options Combo was in Project Options +- fixed issue with Tcl Shell loosing focus after each command, therefore needing to click in the edit line before we type a new command (borrowed from @brainstorm +- added a header in the preprocessor files mentioning that the GCODE files were generated by FlatCAM. - modified the number of decimals in some of the line entries to 4. - added an alias for the millholes Tcl Command: 'mill' 27.04.2018 -- modified the Gerber.scale() function from camlib.py in order to -allow loading Gerber files with 'follow' parameter in other units -than the current ones -- snap_max_entry is disabled when the DRAW toolbar is disabled (previous -fix didn't work) -- added drill count column in Excellon Tool Table which displays the -total number of drills for each tool - -- added a new menu entry in Menu -> EDIT named "Join Excellon". It will -merge a selection of Excellon files into a new Excellon file +- modified the Gerber.scale() function from camlib.py in order to allow loading Gerber files with 'follow' parameter in other units than the current ones +- snap_max_entry is disabled when the DRAW toolbar is disabled (previous fix didn't work) +- added drill count column in Excellon Tool Table which displays the total number of drills for each tool +- added a new menu entry in Menu -> EDIT named "Join Excellon". It will merge a selection of Excellon files into a new Excellon file - added menu stubs for other Excellon based actions - - solved bug that was not possible to generate film from joined geometry -- improved toggle active/inactive of the object through SPACE key. Now -the command works not only for one object but also for a selection +- improved toggle active/inactive of the object through SPACE key. Now the command works not only for one object but also for a selection 26.05.2018 - made conversion to Python3 - added Rtree Indexing drill path optimization -- added a checkbox in Options Tab -> App Defaults -> Excellon -Group named Excellon Optim. Type from which it can be selected -the default optimization type: TS stands for Travelling -Salesman algorithm and Rtree stands for Rtree Indexing -- added a checkbox on the Grid Toolbar that when checked -(default status is checked) whatever value entered in the GridX entry -will be used instead of the now disabled GridY entry -- modified the default behavior on when a line_entry is clicked. -Now, on each click on a line_entry, the content is automatically -selected. +- added a checkbox in Options Tab -> App Defaults -> Excellon Group named Excellon Optim. Type from which it can be selected the default optimization type: TS stands for Travelling Salesman algorithm and Rtree stands for Rtree Indexing +- added a checkbox on the Grid Toolbar that when checked (default status is checked) whatever value entered in the GridX entry will be used instead of the now disabled GridY entry +- modified the default behavior on when a line_entry is clicked. Now, on each click on a line_entry, the content is automatically selected. - snap_max_entry is disabled when the DRAW toolbar is disabled 24.05.2015 -- in Geometry Editor added a initial form of Rotate Geometry command in -toolbar -- changed the way the geometry is finished if it requires a key: before -it was using key 'Space' now it uses 'Enter' +- in Geometry Editor added a initial form of Rotate Geometry command in toolbar +- changed the way the geometry is finished if it requires a key: before it was using key 'Space' now it uses 'Enter' - added Shortcut for Rotate Geometry to key 'Space' -- after using a tool in Geometry Editor it automatically defaults to -'Select Tool' +- after using a tool in Geometry Editor it automatically defaults to 'Select Tool' 23.05.2018 @@ -4302,135 +4100,69 @@ Delete: Delete Obj 22.05.2018 - Added Marlin preprocessor -- Added a new entry into the Geometry and Excellon Object's UI: -Feedrate rapid: the purpose is to set a feedrate for the G0 -command that some firmwares like Marlin don't intepret as -'move with highest speed' -- FlatCAM was not making the conversion from one type of units to -another for a lot of parameters. Corrected that. -- Modified the Marlin preprocessor so it will generate the required -GCODE. +- Added a new entry into the Geometry and Excellon Object's UI: Feedrate rapid: the purpose is to set a feedrate for the G0 command that some firmwares like Marlin don't intepret as 'move with highest speed' +- FlatCAM was not making the conversion from one type of units to another for a lot of parameters. Corrected that. +- Modified the Marlin preprocessor so it will generate the required GCODE. 21.05.2018 - added new icons for menu entries -- added shortcuts that work on the Project tab but also over -Plot. Shorcut list is accesed with shortcut key '~' sau '`' -- small GUI modification: on each "New File" command it will switch to -the Project Tab regardless on which tab we were. - -- removed the global shear entries and checkbox as they can be -damaging and it will build effect upon effect, which is not good -- solved bug in that the Edit -> Shear on X (Y)axis could adjust -only in integers. Now the angle can be adjusted in float with -3 decimals. +- added shortcuts that work on the Project tab but also over Plot. Shorcut list is accesed with shortcut key '~' sau '`' +- small GUI modification: on each "New File" command it will switch to the Project Tab regardless on which tab we were. +- removed the global shear entries and checkbox as they can be damaging and it will build effect upon effect, which is not good +- solved bug in that the Edit -> Shear on X (Y)axis could adjust only in integers. Now the angle can be adjusted in float with 3 decimals. - changed the tile of QInputDialog to a more general one - changed the "follow" Tcl command to the new format -- added a new entry in the Menu -> File, to open a Gerber with -the follow parameter = True -- added a new checkbox in the Gerber Object Selection Tab that -when checked it will create a "follow" geometry -- added a few lines in Mill Holes Tcl command to check if there are -promises and raise an Tcl error if there are any. +- added a new entry in the Menu -> File, to open a Gerber with the follow parameter = True +- added a new checkbox in the Gerber Object Selection Tab that when checked it will create a "follow" geometry +- added a few lines in Mill Holes Tcl command to check if there are promises and raise an Tcl error if there are any. - started to modify the Export_Svg Tcl command 20.05.2018 -- changed the interpretation of the axis for the rotate and skew commands. -Actually I reversed them to reflect reality. +- changed the interpretation of the axis for the rotate and skew commands. Actually I reversed them to reflect reality. - for the rotate command a positive angle now rotates CW. It was reversed. -- added shortcuts (for outside CANVAS; the CANVAS has it's own set of shortcuts) -Ctrl+C will copy to clipboard the name of the selected object -Ctrl+A will Select All objects - +- added shortcuts (for outside CANVAS; the CANVAS has it's own set of shortcuts) Ctrl+C will copy to clipboard the name of the selected object Ctrl+A will Select All objects "X" key will flip the selected objects on X axis - "Y" key will flip the selected objects on Y axis - "R" key will rotate CW with a 45 degrees step -- changed the layout for the top of th Options page. Added a checkbox and entries -for parameters for skew command. When the checkbox is checked it will save (and -load at the next startup of the program) the option that at each CNCJob generation -(be it from Excellon or Geometry) it will perform the Skew command with the -parametrs set in the nearby field boxes (Skew X and Skey Y angles). -It is useful in case the CNC router is not perfectly alligned between the X and Y axis +- changed the layout for the top of th Options page. Added a checkbox and entries for parameters for skew command. When the checkbox is checked it will save (and load at the next startup of the program) the option that at each CNCJob generation (be it from Excellon or Geometry) it will perform the Skew command with the parametrs set in the nearby field boxes (Skew X and Skey Y angles). It is useful in case the CNC router is not perfectly alligned between the X and Y axis - added some protection in case the skew command receive a None parameter - -- BUG solved: made an UGLY (really UGLY) HACK so now, when there is a panel geometry -generated from GUI, the project WILL save. I had to create a copy of the generated -panel geometry and delete the original panel geometry. This way there is no complain -from JSON module about circular reference. - -Supplimentary: -- removed the Save buttons previously added on each Group in Application Defaults. -Replaced them with a single Save button that stays always on top of the Options TAB +- BUG solved: made an UGLY (really UGLY) HACK so now, when there is a panel geometry generated from GUI, the project WILL save. I had to create a copy of the generated panel geometry and delete the original panel geometry. This way there is no complain from JSON module about circular reference. +- removed the Save buttons previously added on each Group in Application Defaults. Replaced them with a single Save button that stays always on top of the Options TAB - added settings for defaults for the Grid that are persistent - changed the default view at FlatCAM startup: now the origin is in the center of the screen - 19.05.2018 -- last object that is opened (created) is always automatically selected and -the name of the object is automatically copied to clipboard; useful when -using the TCL command :) - -- added new commands in MENU -> EDIT named: "Copy Object" and -"Copy Obj as Geom". The first command will duplicate any object (Geometry, -Gerber, Excellon). -The second command will duplicate the object as a geometry. For example, -holes in Excello now are just circles that can be "painted" if one wants it. - -- added new Tool named ToolFreeformCutout. It does what it says, it will -make a board cutout from a "any shape" Gerber or Geometry file - -- solved bug in the TCL command "drillcncjob" that always used the endz -parameter value as the toolchangez parameter value and for the endz value -used a default value = 1 - +- last object that is opened (created) is always automatically selected and the name of the object is automatically copied to clipboard; useful when using the TCL command :) +- added new commands in MENU -> EDIT named: "Copy Object" and "Copy Obj as Geom". The first command will duplicate any object (Geometry, Gerber, Excellon). The second command will duplicate the object as a geometry. For example, holes in Excello now are just circles that can be "painted" if one wants it. +- added new Tool named ToolFreeformCutout. It does what it says, it will make a board cutout from a "any shape" Gerber or Geometry file +- solved bug in the TCL command "drillcncjob" that always used the endz parameter value as the toolchangez parameter value and for the endz value used a default value = 1 - added preprocessor name into the TCL command "drillcncjob" parameters - -- when adding a new geometry the default name is now: "New_Geometry" instead -of "New Geometry". TCL commands don't handle the spaces inside the name and -require adding quotes. - -- solved bug in "cncjob" TCL command in which it used multidepth parameter as -always True regardless of the argument provided - +- when adding a new geometry the default name is now: "New_Geometry" instead of "New Geometry". TCL commands don't handle the spaces inside the name and require adding quotes. +- solved bug in "cncjob" TCL command in which it used multidepth parameter as always True regardless of the argument provided - added a checkbox for Multidepth in the Options Tab -> Application Defaults - 18.05.2018 -- added an "Defaults" button in Excellon Defaults Group; it loads the -following configuration (Excellon_format_in 2:4, Excellon_format_mm 3:3, -Excellon_zeros LZ) -- added Save buttons for each Defaults Group; in the future more -parameters will be propagated in the app, for now they are a few -- added functions for Skew on X axis and for Skew on Y menu stubs. -Now, clicking on those Menu -> Options -> Transform Object menu entries -will trigger those functions -- added a CheckBox button in the Options Tab -> Application Defaults that control -the behaviour of the TCL shell: checking it will make the TCL shell window visible -at each start-up, unchecking it the TCL shell window will be hidden until needed -- Depth/pass parameter from Geometry Object CNC Job is now in the -defaults and it will keep it's value until changed in the Application -Defaults. +- added an "Defaults" button in Excellon Defaults Group; it loads the following configuration (Excellon_format_in 2:4, Excellon_format_mm 3:3, Excellon_zeros LZ) +- added Save buttons for each Defaults Group; in the future more parameters will be propagated in the app, for now they are a few +- added functions for Skew on X axis and for Skew on Y menu stubs. Now, clicking on those Menu -> Options -> Transform Object menu entries will trigger those functions +- added a CheckBox button in the Options Tab -> Application Defaults that control the behaviour of the TCL shell: checking it will make the TCL shell window visible at each start-up, unchecking it the TCL shell window will be hidden until needed +- Depth/pass parameter from Geometry Object CNC Job is now in the defaults and it will keep it's value until changed in the Application Defaults. 17.05.2018 -- added messages box for the Flip commands to show error in case there -is no object selected when the command is executed -- added field entries in the Options TAB - > Application Defaults for the -following newly introduced parameters: +- added messages box for the Flip commands to show error in case there is no object selected when the command is executed +- added field entries in the Options TAB - > Application Defaults for the following newly introduced parameters: excellon_format_upper_in excellon_format_lower_in excellon_format_upper_mm excellon_format_lower_mm -The ones with upper indicate how many digits are allocated for the units -and the ones with lower indicate how many digits from coordinates are -alocated for the decimals. +The ones with upper indicate how many digits are allocated for the units and the ones with lower indicate how many digits from coordinates are alocated for the decimals. [ Eg: Excellon format 2:4 in INCH excellon_format_upper_in = 2 @@ -4439,64 +4171,33 @@ where the first 2 digits are for units and the last 4 digits are decimals so from a number like 235589 we will get a coordinate 23.5589 ] -- added Radio button in the Options TAB - > Application Defaults for the -Excellon_zeros parameter - -After each change of those parameters the user will have to press -"Save defaults" from File menu in order to propagate the new values, or -wait for the autosave to kick in (each 20sec). - +- added Radio button in the Options TAB - > Application Defaults for the Excellon_zeros parameter +After each change of those parameters the user will have to press "Save defaults" from File menu in order to propagate the new values, or wait for the autosave to kick in (each 20sec). Those parameters can be set in the set_sys TCL command. 15.05.2018 - modified SetSys TCL command: now it can change units -- modified SetSys TCL command: now it can set new parameters: -excellon_format_mm and excellon_format_in. the first one is when the -excellon units are MM and the second is for when the excellon units are -in INCH. Those parameters can be set with a number between 1 and 5 and it -signify how many digits are before coma. -- added new GUI command in EDIT -> Select All. It will select all -objects on the first mouse click and on the second will deselect all -(toggle action) -- added new GUI commands in Options -> Transform object. Added Rotate selection, -Flip on X axis of the selection and Flip on Y axis of the selection -For the Rotate selection command, negative numbers means rotation CCW and -positive numbers means rotation CW. - +- modified SetSys TCL command: now it can set new parameters: excellon_format_mm and excellon_format_in. the first one is when the excellon units are MM and the second is for when the excellon units are in INCH. Those parameters can be set with a number between 1 and 5 and it signify how many digits are before coma. +- added new GUI command in EDIT -> Select All. It will select all objects on the first mouse click and on the second will deselect all (toggle action) +- added new GUI commands in Options -> Transform object. Added Rotate selection, Flip on X axis of the selection and Flip on Y axis of the selection For the Rotate selection command, negative numbers means rotation CCW and positive numbers means rotation CW. - cleaned up a bit the module imports -- worked on the excellon parsing for the case of trailing zeros. -If there are more than 6digits in the -coordinates, in case that there is no period, now the software will -identify the issue and attempt to correct it by dividing the coordinate -further by 10 for each additional digit over 6. If the number of digits -is less than 6 then the software will multiply by 10 the coordinates +- worked on the excellon parsing for the case of trailing zeros. If there are more than 6digits in the coordinates, in case that there is no period, now the software will identify the issue and attempt to correct it by dividing the coordinate further by 10 for each additional digit over 6. If the number of digits is less than 6 then the software will multiply by 10 the coordinates 14.05.2018 -- fixed bug in Geometry CNCJob generation that prevented generating -the object -- added GRBL 1.1 preprocessor and Laser preprocessor (adapted from -the work of MARCO A QUEZADA) - +- fixed bug in Geometry CNCJob generation that prevented generating the object +- added GRBL 1.1 preprocessor and Laser preprocessor (adapted from the work of MARCO A QUEZADA) 13.05.2018 - added postprocessing in correct form - added the possibility to select an preprocessor for Excellon Object -- added a new preprocessor, manual_toolchange.py. It allows to change -the tools and adjust the drill tip to touch the surface manually, always -in the X=0, Y=0, Z = toolchangeZ coordinates. +- added a new preprocessor, manual_toolchange.py. It allows to change the tools and adjust the drill tip to touch the surface manually, always in the X=0, Y=0, Z = toolchangeZ coordinates. - fixed drillcncjob TCL command by adding toolchangeZ parameter -- fixed the preprocessor file template 'default.py' in the toolchange -command section -- after I created a feature that the message in infobar is cleared by -moving mouse on canvas, it generated a bug in TCL shell: everytime -mouse was moved it will add a space into the TCL read only section. -Now this bug is fixed. -- added an EndZ parameter for the drillcncjob and cncjob TCL commands: it -will specify at what Z value to park the CNC when job ends -- the spindle will be turned on after the toolchange and it will be turned off -just before the final end move. +- fixed the preprocessor file template 'default.py' in the toolchange command section +- after I created a feature that the message in infobar is cleared by moving mouse on canvas, it generated a bug in TCL shell: everytime mouse was moved it will add a space into the TCL read only section. Now this bug is fixed. +- added an EndZ parameter for the drillcncjob and cncjob TCL commands: it will specify at what Z value to park the CNC when job ends +- the spindle will be turned on after the toolchange and it will be turned off just before the final end move. Previously: - added GRID based working of FLATCAM @@ -4504,7 +4205,6 @@ Previously: - added FilmTool, PanelizeTool GUI, MoveTool - and others - 24.04.2018 - Remade the Measurement Tool: it now ask for the Start point of the measurement and then for the Stop point. After it will display the measurement until we left click again on the canvas and so on. Previously you clicked the start point and reset the X and Y coords displayed and then you moved the mouse pointer wherever you wanted to measure, but moving the mouse from there you lost the measurement. @@ -4523,7 +4223,6 @@ Previously: ============================================ - This fork features: - Added buttons in the menu bar for opening of Gerber and Excellon files; @@ -4532,13 +4231,12 @@ This fork features: - Added capability so FlatCAM can now read Gerber files with traces having zero value (aperture size is zero); - Added Paint All / Seed based Paint functions from the JP's FlatCAM; - Added Excellon move optimization (travelling salesman algorithm) cherry-picked from David Kahler: https://bitbucket.org/dakahler/flatcam -- Updated make_win32.py so it will work with cx_freeze 5.0.1 Corrected small typo in DblSidedTool.py +- Updated make_win32.py so it will work with cx_freeze 5.0.1 +- Corrected small typo in DblSidedTool.py - Added the TCL commands in the new format. Picked from FLATCAM master. - Hack to fix the issue with geometry not being updated after a TCL command was executed. Now after each TCL command the plot_all() function is executed and the canvas is refreshed. - Added GUI for panelization TCL command - Added GUI tool for the panelization TCL command: Changed some ToolTips. - - ============================================ Previously added features by Dennis diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 401f5655..fb9b9871 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -4032,7 +4032,7 @@ class App(QtCore.QObject): self.file_saved.emit("preferences", filename) self.inform.emit('[success] %s: %s' % (_("Exported preferences to"), filename)) - def save_to_file(self, content_to_save): + def save_to_file(self, content_to_save, txt_content): """ Save something to a file. @@ -4045,7 +4045,7 @@ class App(QtCore.QObject): self.date = ''.join(c for c in self.date if c not in ':-') self.date = self.date.replace(' ', '_') - filter__ = "HTML File .html (*.html);;All Files (*.*)" + filter__ = "HTML File .html (*.html);;TXT File .txt (*.txt);;All Files (*.*)" path_to_save = self.defaults["global_last_save_folder"] if\ self.defaults["global_last_save_folder"] is not None else self.data_path try: @@ -4064,9 +4064,8 @@ class App(QtCore.QObject): return else: try: - f = open(filename, 'w') - defaults_file_content = f.read() - f.close() + with open(filename, 'w') as f: + ___ = f.read() except PermissionError: self.inform.emit('[WARNING] %s' % _("Permission denied, saving not possible.\n" @@ -4084,9 +4083,14 @@ class App(QtCore.QObject): return # Save content + if filename.rpartition('.')[2].lower() == 'html': + file_content = content_to_save + else: + file_content = txt_content + try: with open(filename, "w") as f: - f.write(content_to_save) + f.write(file_content) except Exception: self.inform.emit('[ERROR_NOTCL] %s %s' % (_("Failed to write defaults to file."), str(filename))) return diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index 040cf540..6a5d06a2 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -2600,7 +2600,8 @@ class _BrowserTextEdit(QTextEdit): def save_log(self, app): html_content = self.toHtml() - app.save_to_file(content_to_save=html_content) + txt_content = self.toPlainText() + app.save_to_file(content_to_save=html_content, txt_content=txt_content) class _ExpandableTextEdit(QTextEdit): diff --git a/make_freezed.py b/make_freezed.py index 72c86be4..75f1c7eb 100644 --- a/make_freezed.py +++ b/make_freezed.py @@ -108,9 +108,9 @@ exe = Executable("FlatCAM.py", icon='share/flatcam_icon48.ico', base=base, targe setup( name="FlatCAM", - author="Juan Pablo Caram", + author="Community effort", version="8.9", - description="FlatCAM: 2D Computer Aided PCB Manufacturing", + description="FlatCAM Evo: 2D Computer Aided PCB Manufacturing", options=dict(build_exe=buildOptions), executables=[exe] ) From 3b8b4254b9104e12be35e13516ac37d4c8127296 Mon Sep 17 00:00:00 2001 From: Marius Date: Fri, 24 Apr 2020 08:37:47 +0300 Subject: [PATCH 202/209] - fixed an issue regarding the statusbar pixmap selection --- CHANGELOG.md | 1 + FlatCAMApp.py | 2 +- tclCommands/TclCommand.py | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c2e6796..1b0852b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ CHANGELOG for FlatCAM beta - the status bar messages that are echoed in the Tcl Shell will no longer have all text colored but only the identifier - some message strings cleanup - added possibility to save as text file the content in Tcl Shell browser window when clicking the Save log context menu entry +- fixed an issue regarding the statusbar pixmap selection 23.04.2020 diff --git a/FlatCAMApp.py b/FlatCAMApp.py index fb9b9871..21af0c26 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -3706,7 +3706,7 @@ class App(QtCore.QObject): """ # Type of message in brackets at the beginning of the message. - match = re.search("\[([^\]]+)\](.*)", msg) + match = re.search(r"\[(.*)\](.*)", msg) if match: level = match.group(1) msg_ = match.group(2) diff --git a/tclCommands/TclCommand.py b/tclCommands/TclCommand.py index 72bb48c5..45378180 100644 --- a/tclCommands/TclCommand.py +++ b/tclCommands/TclCommand.py @@ -289,7 +289,7 @@ class TclCommand(object): # self.worker_task.emit({'fcn': self.exec_command_test, 'params': [text, False]}) try: - self.log.debug("TCL command '%s' executed." % str(self.__class__)) + self.log.debug("TCL command '%s' executed." % str(type(self).__name__)) self.original_args = args args, unnamed_args = self.check_args(args) return self.execute(args, unnamed_args) @@ -405,7 +405,7 @@ class TclCommandSignaled(TclCommand): "'set_sys global_background_timeout '.") try: - self.log.debug("TCL command '%s' executed." % str(self.__class__)) + self.log.debug("TCL command '%s' executed." % str(type(self).__name__)) self.original_args = args args, unnamed_args = self.check_args(args) if 'timeout' in args: From b67c00fef60c252f967ce38d5e059cd5f30eb377 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 24 Apr 2020 11:25:21 +0300 Subject: [PATCH 203/209] - update the language template strings.pot and updated the Romanian translation - updated the Readme file with the steps for installation for MacOS - updated the requirements.txt file --- CHANGELOG.md | 3 + README.md | 52 +- locale/en/LC_MESSAGES/strings.mo | Bin 338020 -> 352042 bytes locale/en/LC_MESSAGES/strings.po | 11993 ++++++++++++++++------------- locale/ro/LC_MESSAGES/strings.mo | Bin 366073 -> 380697 bytes locale/ro/LC_MESSAGES/strings.po | 10539 ++++++++++++++----------- locale_template/strings.pot | 9309 ++++++++++++---------- requirements.txt | 7 +- 8 files changed, 17727 insertions(+), 14176 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b0852b4..8bef25d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,9 @@ CHANGELOG for FlatCAM beta - some message strings cleanup - added possibility to save as text file the content in Tcl Shell browser window when clicking the Save log context menu entry - fixed an issue regarding the statusbar pixmap selection +- update the language template strings.pot and updated the Romanian translation +- updated the Readme file with the steps for installation for MacOS +- updated the requirements.txt file 23.04.2020 diff --git a/README.md b/README.md index 33f03121..c7756920 100644 --- a/README.md +++ b/README.md @@ -20,21 +20,7 @@ Menu -> Help -> About FlatCAM -> Programmers -> Marius Stanciu - Download sources from: https://bitbucket.org/jpcgt/flatcam/downloads/ - Unzip them on a HDD location that your user has permissions for. -1. MacOS -- none (yet) - -2. Linux -- make sure that Python 3.8 is installed on your OS and that the command: python3 -V confirm it -- verify that the pip package is installed for your Python installation (e.g 3.8) by running the command pip3 -V. -If it is not installed, install it. In Ubuntu-like OS's it is done like this: -sudo apt-get install python3-pip -or: -sudo apt-get install python3.8-pip -- verify that the file setup_ubuntu.sh has Linux line-endings (LF) and that it is executable (chmod +x setup_ubuntu.sh) -- run the file setup_ubuntu.sh and install all the dependencies with the command: ./setup_ubuntu.sh -- if the previous command is successful and has no errors, run FlatCAM with the command: python3 FlatCAM.py - -3. Windows +1. Windows - download the provided installer (for your OS flavor 64bit or 32bit) from: https://bitbucket.org/jpcgt/flatcam/downloads/ - execute the installer and install the program. It is recommended to install as a Local User. @@ -63,3 +49,39 @@ D:\my_folder\> pip install --upgrade package_from_requirements.whl Run FlatCAM beta from the installation folder (e.g D:\FlatCAM_beta) in the Command Prompt with the following command: cd D:\FlatCAM_beta python FlatCAM.py + +2. Linux +- make sure that Python 3.8 is installed on your OS and that the command: python3 -V confirm it +- verify that the pip package is installed for your Python installation (e.g 3.8) by running the command pip3 -V. +If it is not installed, install it. In Ubuntu-like OS's it is done like this: +sudo apt-get install python3-pip +or: +sudo apt-get install python3.8-pip +- verify that the file setup_ubuntu.sh has Linux line-endings (LF) and that it is executable (chmod +x setup_ubuntu.sh) +- run the file setup_ubuntu.sh and install all the dependencies with the command: ./setup_ubuntu.sh +- if the previous command is successful and has no errors, run FlatCAM with the command: python3 FlatCAM.py + +3. MacOS +Instructions from here: https://gist.github.com/natevw/3e6fc929aff358b38c0a#gistcomment-3111878 + +- create a folder to hold the sources somewhere on your HDD: +mkdir FlatCAM + +- unzip in this folder the sources downloaded from https://bitbucket.org/jpcgt/flatcam/downloads/ +Using commands (e.g using the sources for FlatCAM beta 8.991): +cd ~/FlatCAM +wget https://bitbucket.org/jpcgt/flatcam/downloads/FlatCAM_beta_8.991_sources.zip +unzip FlatCAM_beta_8.991_sources.zip +cd FlatCAM_beta_8.991_sources + +- check if Homebrew is installed: +xcode-select --install +ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" + +- install dependencies: +brew install pyqt +python3 -m ensurepip +python3 -m pip install -r requirements.txt + +- run FlatCAM +python3 FlatCAM.py diff --git a/locale/en/LC_MESSAGES/strings.mo b/locale/en/LC_MESSAGES/strings.mo index e569bb65e7e44fbc85ef965a3441e710b37f445e..a6bb163f94d2d616151c1638ec924bd41df10961 100644 GIT binary patch delta 84230 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⪻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 to get started\n" -"\n" -msgstr "" -"Type >help< to get started\n" -"\n" +#: FlatCAMApp.py:2565 flatcamGUI/GUIElements.py:2592 +#| msgid "" +#| "Type >help< to get started\n" +#| "\n" +msgid "Type >help< to get started" +msgstr "Type >help< to get started" -#: FlatCAMApp.py:2627 FlatCAMApp.py:9020 +#: FlatCAMApp.py:2817 FlatCAMApp.py:9393 msgid "New Project - Not saved" msgstr "New Project - Not saved" -#: FlatCAMApp.py:2702 FlatCAMApp.py:9088 FlatCAMApp.py:9125 FlatCAMApp.py:9166 -#: FlatCAMApp.py:9237 FlatCAMApp.py:9991 FlatCAMApp.py:11174 -#: FlatCAMApp.py:11233 -msgid "" -"Canvas initialization started.\n" -"Canvas initialization finished in" -msgstr "" -"Canvas initialization started.\n" -"Canvas initialization finished in" - -#: FlatCAMApp.py:2704 -msgid "Executing Tcl Script ..." -msgstr "Executing Tcl Script ..." - -#: FlatCAMApp.py:2719 +#: FlatCAMApp.py:2913 msgid "" "Found old default preferences files. Please reboot the application to update." msgstr "" "Found old default preferences files. Please reboot the application to update." -#: FlatCAMApp.py:2763 ObjectCollection.py:90 flatcamTools/ToolImage.py:248 +#: FlatCAMApp.py:2964 FlatCAMApp.py:3884 FlatCAMApp.py:3933 FlatCAMApp.py:3988 +#: FlatCAMApp.py:4063 FlatCAMApp.py:6111 FlatCAMApp.py:9477 FlatCAMApp.py:9514 +#: FlatCAMApp.py:9556 FlatCAMApp.py:9585 FlatCAMApp.py:9625 FlatCAMApp.py:9650 +#: FlatCAMApp.py:9702 FlatCAMApp.py:9738 FlatCAMApp.py:9784 FlatCAMApp.py:9825 +#: FlatCAMApp.py:9866 FlatCAMApp.py:9907 FlatCAMApp.py:9948 FlatCAMApp.py:9992 +#: FlatCAMApp.py:10048 FlatCAMApp.py:10080 FlatCAMApp.py:10112 +#: FlatCAMApp.py:10349 FlatCAMApp.py:10393 FlatCAMApp.py:10470 +#: FlatCAMApp.py:10525 FlatCAMCommon.py:371 FlatCAMCommon.py:413 +#: FlatCAMCommon.py:1107 FlatCAMCommon.py:1153 FlatCAMCommon.py:2537 +#: FlatCAMCommon.py:2583 ObjectCollection.py:122 +#: flatcamEditors/FlatCAMExcEditor.py:1024 +#: flatcamEditors/FlatCAMExcEditor.py:1092 +#: flatcamEditors/FlatCAMTextEditor.py:223 flatcamGUI/FlatCAMGUI.py:3389 +#: flatcamGUI/FlatCAMGUI.py:3601 flatcamGUI/FlatCAMGUI.py:3812 +#: flatcamTools/ToolFilm.py:754 flatcamTools/ToolFilm.py:900 +#: flatcamTools/ToolImage.py:247 flatcamTools/ToolMove.py:270 #: flatcamTools/ToolPcbWizard.py:301 flatcamTools/ToolPcbWizard.py:324 -msgid "Open cancelled." -msgstr "Open cancelled." +#: flatcamTools/ToolQRCode.py:791 flatcamTools/ToolQRCode.py:838 +msgid "Cancelled." +msgstr "Cancelled." -#: FlatCAMApp.py:2779 +#: FlatCAMApp.py:2980 msgid "Open Config file failed." msgstr "Open Config file failed." -#: FlatCAMApp.py:2794 +#: FlatCAMApp.py:2995 msgid "Open Script file failed." msgstr "Open Script file failed." -#: FlatCAMApp.py:2820 +#: FlatCAMApp.py:3021 msgid "Open Excellon file failed." msgstr "Open Excellon file failed." -#: FlatCAMApp.py:2833 +#: FlatCAMApp.py:3034 msgid "Open GCode file failed." msgstr "Open GCode file failed." -#: FlatCAMApp.py:2846 +#: FlatCAMApp.py:3047 msgid "Open Gerber file failed." msgstr "Open Gerber file failed." -#: FlatCAMApp.py:3201 +#: FlatCAMApp.py:3424 msgid "Select a Geometry, Gerber or Excellon Object to edit." msgstr "Select a Geometry, Gerber or Excellon Object to edit." -#: FlatCAMApp.py:3216 +#: FlatCAMApp.py:3439 msgid "" "Simultaneous editing of tools geometry in a MultiGeo Geometry is not " "possible.\n" @@ -119,98 +147,96 @@ msgstr "" "possible.\n" "Edit only one geometry at a time." -#: FlatCAMApp.py:3271 +#: FlatCAMApp.py:3497 msgid "Editor is activated ..." msgstr "Editor is activated ..." -#: FlatCAMApp.py:3292 +#: FlatCAMApp.py:3518 msgid "Do you want to save the edited object?" msgstr "Do you want to save the edited object?" -#: FlatCAMApp.py:3293 flatcamGUI/FlatCAMGUI.py:2165 +#: FlatCAMApp.py:3519 flatcamGUI/FlatCAMGUI.py:2273 msgid "Close Editor" msgstr "Close Editor" -#: FlatCAMApp.py:3296 FlatCAMApp.py:4014 FlatCAMApp.py:5067 FlatCAMApp.py:7724 -#: FlatCAMApp.py:7750 FlatCAMApp.py:8927 FlatCAMTranslation.py:108 -#: FlatCAMTranslation.py:193 +#: FlatCAMApp.py:3522 FlatCAMApp.py:5163 FlatCAMApp.py:8023 FlatCAMApp.py:8049 +#: FlatCAMApp.py:9298 FlatCAMTranslation.py:108 FlatCAMTranslation.py:199 +#: flatcamGUI/FlatCAMGUI.py:2479 msgid "Yes" msgstr "Yes" -#: FlatCAMApp.py:3297 FlatCAMApp.py:4015 FlatCAMApp.py:5068 FlatCAMApp.py:7725 -#: FlatCAMApp.py:7751 FlatCAMApp.py:8928 FlatCAMTranslation.py:109 -#: FlatCAMTranslation.py:194 flatcamGUI/PreferencesUI.py:5139 -#: flatcamGUI/PreferencesUI.py:5554 flatcamTools/ToolNonCopperClear.py:189 -#: flatcamTools/ToolPaint.py:161 +#: FlatCAMApp.py:3523 FlatCAMApp.py:5164 FlatCAMApp.py:8024 FlatCAMApp.py:8050 +#: FlatCAMApp.py:9299 FlatCAMTranslation.py:109 FlatCAMTranslation.py:200 +#: flatcamGUI/FlatCAMGUI.py:2480 flatcamGUI/PreferencesUI.py:5443 +#: flatcamGUI/PreferencesUI.py:5989 flatcamTools/ToolNCC.py:182 +#: flatcamTools/ToolPaint.py:166 msgid "No" msgstr "No" -#: FlatCAMApp.py:3298 FlatCAMApp.py:5069 FlatCAMApp.py:5925 FlatCAMApp.py:7006 -#: FlatCAMApp.py:8929 FlatCAMCommon.py:571 flatcamGUI/FlatCAMGUI.py:1260 +#: FlatCAMApp.py:3524 FlatCAMApp.py:5165 FlatCAMApp.py:6049 FlatCAMApp.py:7000 +#: FlatCAMApp.py:9300 FlatCAMCommon.py:572 FlatCAMCommon.py:2127 +#: flatcamGUI/FlatCAMGUI.py:1332 msgid "Cancel" msgstr "Cancel" -#: FlatCAMApp.py:3326 +#: FlatCAMApp.py:3556 msgid "Object empty after edit." msgstr "Object empty after edit." -#: FlatCAMApp.py:3375 FlatCAMApp.py:3395 FlatCAMApp.py:3410 +#: FlatCAMApp.py:3560 FlatCAMApp.py:3581 FlatCAMApp.py:3603 +msgid "Editor exited. Editor content saved." +msgstr "Editor exited. Editor content saved." + +#: FlatCAMApp.py:3607 FlatCAMApp.py:3630 FlatCAMApp.py:3648 msgid "Select a Gerber, Geometry or Excellon Object to update." msgstr "Select a Gerber, Geometry or Excellon Object to update." -#: FlatCAMApp.py:3379 +#: FlatCAMApp.py:3610 msgid "is updated, returning to App..." msgstr "is updated, returning to App..." -#: FlatCAMApp.py:3774 FlatCAMApp.py:3888 FlatCAMApp.py:4929 +#: FlatCAMApp.py:3617 +msgid "Editor exited. Editor content was not saved." +msgstr "Editor exited. Editor content was not saved." + +#: FlatCAMApp.py:3810 FlatCAMApp.py:3941 FlatCAMApp.py:5012 msgid "Could not load defaults file." msgstr "Could not load defaults file." -#: FlatCAMApp.py:3786 FlatCAMApp.py:3896 FlatCAMApp.py:4938 +#: FlatCAMApp.py:3822 FlatCAMApp.py:3949 FlatCAMApp.py:5021 msgid "Failed to parse defaults file." msgstr "Failed to parse defaults file." -#: FlatCAMApp.py:3831 -msgid "Preferences default restore was cancelled." -msgstr "Preferences default restore was cancelled." - -#: FlatCAMApp.py:3839 FlatCAMApp.py:5017 +#: FlatCAMApp.py:3892 FlatCAMApp.py:5113 msgid "Could not load factory defaults file." msgstr "Could not load factory defaults file." -#: FlatCAMApp.py:3847 FlatCAMApp.py:5027 +#: FlatCAMApp.py:3900 FlatCAMApp.py:5123 msgid "Failed to parse factory defaults file." msgstr "Failed to parse factory defaults file." -#: FlatCAMApp.py:3855 +#: FlatCAMApp.py:3908 msgid "Preferences default values are restored." msgstr "Preferences default values are restored." -#: FlatCAMApp.py:3870 FlatCAMApp.py:3874 +#: FlatCAMApp.py:3923 FlatCAMApp.py:3927 msgid "Import FlatCAM Preferences" msgstr "Import FlatCAM Preferences" -#: FlatCAMApp.py:3880 -msgid "FlatCAM preferences import cancelled." -msgstr "FlatCAM preferences import cancelled." - -#: FlatCAMApp.py:3904 +#: FlatCAMApp.py:3957 msgid "Imported Defaults from" msgstr "Imported Defaults from" -#: FlatCAMApp.py:3924 FlatCAMApp.py:3929 +#: FlatCAMApp.py:3977 FlatCAMApp.py:3982 msgid "Export FlatCAM Preferences" msgstr "Export FlatCAM Preferences" -#: FlatCAMApp.py:3936 -msgid "FlatCAM preferences export cancelled." -msgstr "FlatCAM preferences export cancelled." - -#: FlatCAMApp.py:3945 FlatCAMApp.py:10389 FlatCAMApp.py:10437 -#: FlatCAMApp.py:10560 FlatCAMApp.py:10699 FlatCAMCommon.py:378 -#: FlatCAMCommon.py:1114 FlatCAMObj.py:6903 -#: flatcamEditors/FlatCAMTextEditor.py:274 flatcamTools/ToolFilm.py:1019 -#: flatcamTools/ToolFilm.py:1195 flatcamTools/ToolSolderPaste.py:1544 +#: FlatCAMApp.py:3997 FlatCAMApp.py:4071 FlatCAMApp.py:10769 +#: FlatCAMApp.py:10817 FlatCAMApp.py:10943 FlatCAMApp.py:11080 +#: FlatCAMCommon.py:379 FlatCAMCommon.py:1115 FlatCAMCommon.py:2545 +#: FlatCAMObj.py:7484 flatcamEditors/FlatCAMTextEditor.py:276 +#: flatcamTools/ToolFilm.py:1031 flatcamTools/ToolFilm.py:1212 +#: flatcamTools/ToolSolderPaste.py:1533 msgid "" "Permission denied, saving not possible.\n" "Most likely another app is holding the file open and not accessible." @@ -218,45 +244,48 @@ msgstr "" "Permission denied, saving not possible.\n" "Most likely another app is holding the file open and not accessible." -#: FlatCAMApp.py:3957 +#: FlatCAMApp.py:4009 msgid "Could not load preferences file." msgstr "Could not load preferences file." -#: FlatCAMApp.py:3976 FlatCAMApp.py:4985 +#: FlatCAMApp.py:4028 FlatCAMApp.py:4095 FlatCAMApp.py:5040 msgid "Failed to write defaults to file." msgstr "Failed to write defaults to file." -#: FlatCAMApp.py:3981 +#: FlatCAMApp.py:4033 msgid "Exported preferences to" msgstr "Exported preferences to" -#: FlatCAMApp.py:3998 -msgid "FlatCAM Preferences Folder opened." -msgstr "FlatCAM Preferences Folder opened." +#: FlatCAMApp.py:4053 FlatCAMApp.py:4058 +#| msgid "Saved to" +msgid "Save to file" +msgstr "Save to file" -#: FlatCAMApp.py:4009 -msgid "Are you sure you want to delete the GUI Settings? \n" -msgstr "Are you sure you want to delete the GUI Settings? \n" +#: FlatCAMApp.py:4082 +#| msgid "Could not load defaults file." +msgid "Could not load the file." +msgstr "Could not load the file." -#: FlatCAMApp.py:4012 flatcamGUI/FlatCAMGUI.py:1230 -msgid "Clear GUI Settings" -msgstr "Clear GUI Settings" +#: FlatCAMApp.py:4098 +#| msgid "Exported Tools DB to" +msgid "Exported file to" +msgstr "Exported file to" -#: FlatCAMApp.py:4109 +#: FlatCAMApp.py:4181 msgid "Failed to open recent files file for writing." msgstr "Failed to open recent files file for writing." -#: FlatCAMApp.py:4120 +#: FlatCAMApp.py:4192 msgid "Failed to open recent projects file for writing." msgstr "Failed to open recent projects file for writing." -#: FlatCAMApp.py:4205 FlatCAMApp.py:10900 FlatCAMApp.py:10961 -#: FlatCAMApp.py:11090 FlatCAMObj.py:5050 -#: flatcamEditors/FlatCAMGrbEditor.py:4187 flatcamTools/ToolPcbWizard.py:437 +#: FlatCAMApp.py:4277 FlatCAMApp.py:11276 FlatCAMApp.py:11335 +#: FlatCAMApp.py:11463 FlatCAMApp.py:12189 FlatCAMObj.py:5605 +#: flatcamEditors/FlatCAMGrbEditor.py:4231 flatcamTools/ToolPcbWizard.py:433 msgid "An internal error has occurred. See shell.\n" msgstr "An internal error has occurred. See shell.\n" -#: FlatCAMApp.py:4206 +#: FlatCAMApp.py:4278 #, python-brace-format msgid "" "Object ({kind}) failed because: {error} \n" @@ -265,63 +294,63 @@ msgstr "" "Object ({kind}) failed because: {error} \n" "\n" -#: FlatCAMApp.py:4221 +#: FlatCAMApp.py:4293 msgid "Converting units to " msgstr "Converting units to " -#: FlatCAMApp.py:4324 +#: FlatCAMApp.py:4406 msgid "CREATE A NEW FLATCAM TCL SCRIPT" msgstr "CREATE A NEW FLATCAM TCL SCRIPT" -#: FlatCAMApp.py:4325 +#: FlatCAMApp.py:4407 msgid "TCL Tutorial is here" msgstr "TCL Tutorial is here" -#: FlatCAMApp.py:4327 +#: FlatCAMApp.py:4409 msgid "FlatCAM commands list" msgstr "FlatCAM commands list" -#: FlatCAMApp.py:4378 FlatCAMApp.py:4384 FlatCAMApp.py:4390 FlatCAMApp.py:4396 -#: FlatCAMApp.py:4402 FlatCAMApp.py:4408 +#: FlatCAMApp.py:4460 FlatCAMApp.py:4466 FlatCAMApp.py:4472 FlatCAMApp.py:4478 +#: FlatCAMApp.py:4484 FlatCAMApp.py:4490 msgid "created/selected" msgstr "created/selected" -#: FlatCAMApp.py:4423 FlatCAMApp.py:7086 FlatCAMObj.py:271 FlatCAMObj.py:302 -#: FlatCAMObj.py:318 FlatCAMObj.py:398 flatcamTools/ToolCopperThieving.py:1476 -#: flatcamTools/ToolFiducials.py:807 flatcamTools/ToolMove.py:220 -#: flatcamTools/ToolQRCode.py:726 +#: FlatCAMApp.py:4505 FlatCAMApp.py:7086 FlatCAMObj.py:278 FlatCAMObj.py:309 +#: FlatCAMObj.py:325 FlatCAMObj.py:405 flatcamTools/ToolCopperThieving.py:1482 +#: flatcamTools/ToolFiducials.py:809 flatcamTools/ToolMove.py:230 +#: flatcamTools/ToolQRCode.py:728 msgid "Plotting" msgstr "Plotting" -#: FlatCAMApp.py:4486 flatcamGUI/FlatCAMGUI.py:491 +#: FlatCAMApp.py:4568 flatcamGUI/FlatCAMGUI.py:530 msgid "About FlatCAM" msgstr "About FlatCAM" -#: FlatCAMApp.py:4512 +#: FlatCAMApp.py:4594 msgid "2D Computer-Aided Printed Circuit Board Manufacturing" msgstr "2D Computer-Aided Printed Circuit Board Manufacturing" -#: FlatCAMApp.py:4513 +#: FlatCAMApp.py:4595 msgid "Development" msgstr "Development" -#: FlatCAMApp.py:4514 +#: FlatCAMApp.py:4596 msgid "DOWNLOAD" msgstr "DOWNLOAD" -#: FlatCAMApp.py:4515 +#: FlatCAMApp.py:4597 msgid "Issue tracker" msgstr "Issue tracker" -#: FlatCAMApp.py:4519 FlatCAMApp.py:4860 +#: FlatCAMApp.py:4601 FlatCAMApp.py:4942 flatcamGUI/GUIElements.py:2583 msgid "Close" msgstr "Close" -#: FlatCAMApp.py:4534 +#: FlatCAMApp.py:4616 msgid "Licensed under the MIT license" msgstr "Licensed under the MIT license" -#: FlatCAMApp.py:4543 +#: FlatCAMApp.py:4625 msgid "" "Permission is hereby granted, free of charge, to any person obtaining a " "copy\n" @@ -369,7 +398,7 @@ msgstr "" "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n" "THE SOFTWARE." -#: FlatCAMApp.py:4565 +#: FlatCAMApp.py:4647 msgid "" "Some of the icons used are from the following sources:
Icons by oNline Web Fonts" -#: FlatCAMApp.py:4597 +#: FlatCAMApp.py:4679 msgid "Splash" msgstr "Splash" -#: FlatCAMApp.py:4603 +#: FlatCAMApp.py:4685 msgid "Programmers" msgstr "Programmers" -#: FlatCAMApp.py:4609 +#: FlatCAMApp.py:4691 msgid "Translators" msgstr "Translators" -#: FlatCAMApp.py:4615 +#: FlatCAMApp.py:4697 msgid "License" msgstr "License" -#: FlatCAMApp.py:4621 +#: FlatCAMApp.py:4703 msgid "Attributions" msgstr "Attributions" -#: FlatCAMApp.py:4644 +#: FlatCAMApp.py:4726 msgid "Programmer" msgstr "Programmer" -#: FlatCAMApp.py:4645 +#: FlatCAMApp.py:4727 msgid "Status" msgstr "Status" -#: FlatCAMApp.py:4646 FlatCAMApp.py:4724 +#: FlatCAMApp.py:4728 FlatCAMApp.py:4806 msgid "E-mail" msgstr "E-mail" -#: FlatCAMApp.py:4654 +#: FlatCAMApp.py:4736 msgid "BETA Maintainer >= 2019" msgstr "BETA Maintainer >= 2019" -#: FlatCAMApp.py:4721 +#: FlatCAMApp.py:4803 msgid "Language" msgstr "Language" -#: FlatCAMApp.py:4722 +#: FlatCAMApp.py:4804 msgid "Translator" msgstr "Translator" -#: FlatCAMApp.py:4723 +#: FlatCAMApp.py:4805 msgid "Corrections" msgstr "Corrections" -#: FlatCAMApp.py:4832 FlatCAMApp.py:4840 FlatCAMApp.py:7769 -#: flatcamGUI/FlatCAMGUI.py:473 +#: FlatCAMApp.py:4914 FlatCAMApp.py:4922 FlatCAMApp.py:8068 +#: flatcamGUI/FlatCAMGUI.py:512 msgid "Bookmarks Manager" msgstr "Bookmarks Manager" -#: FlatCAMApp.py:4851 +#: FlatCAMApp.py:4933 msgid "" "This entry will resolve to another website if:\n" "\n" @@ -458,27 +487,27 @@ msgstr "" "If you can't get any informations about FlatCAM beta\n" "use the YouTube channel link from the Help menu." -#: FlatCAMApp.py:4858 +#: FlatCAMApp.py:4940 msgid "Alternative website" msgstr "Alternative website" -#: FlatCAMApp.py:4989 FlatCAMApp.py:7733 +#: FlatCAMApp.py:5044 FlatCAMApp.py:8032 msgid "Preferences saved." msgstr "Preferences saved." -#: FlatCAMApp.py:5043 +#: FlatCAMApp.py:5139 msgid "Failed to write factory defaults to file." msgstr "Failed to write factory defaults to file." -#: FlatCAMApp.py:5047 +#: FlatCAMApp.py:5143 msgid "Factory defaults saved." msgstr "Factory defaults saved." -#: FlatCAMApp.py:5057 flatcamGUI/FlatCAMGUI.py:3962 +#: FlatCAMApp.py:5153 flatcamGUI/FlatCAMGUI.py:4178 msgid "Application is saving the project. Please wait ..." msgstr "Application is saving the project. Please wait ..." -#: FlatCAMApp.py:5062 FlatCAMTranslation.py:188 +#: FlatCAMApp.py:5158 FlatCAMTranslation.py:194 msgid "" "There are files/objects modified in FlatCAM. \n" "Do you want to Save the project?" @@ -486,27 +515,27 @@ msgstr "" "There are files/objects modified in FlatCAM. \n" "Do you want to Save the project?" -#: FlatCAMApp.py:5065 FlatCAMApp.py:8925 FlatCAMTranslation.py:191 +#: FlatCAMApp.py:5161 FlatCAMApp.py:9296 FlatCAMTranslation.py:197 msgid "Save changes" msgstr "Save changes" -#: FlatCAMApp.py:5306 +#: FlatCAMApp.py:5417 msgid "Selected Excellon file extensions registered with FlatCAM." msgstr "Selected Excellon file extensions registered with FlatCAM." -#: FlatCAMApp.py:5328 +#: FlatCAMApp.py:5439 msgid "Selected GCode file extensions registered with FlatCAM." msgstr "Selected GCode file extensions registered with FlatCAM." -#: FlatCAMApp.py:5350 +#: FlatCAMApp.py:5461 msgid "Selected Gerber file extensions registered with FlatCAM." msgstr "Selected Gerber file extensions registered with FlatCAM." -#: FlatCAMApp.py:5538 FlatCAMApp.py:5595 FlatCAMApp.py:5623 +#: FlatCAMApp.py:5649 FlatCAMApp.py:5708 FlatCAMApp.py:5736 msgid "At least two objects are required for join. Objects currently selected" msgstr "At least two objects are required for join. Objects currently selected" -#: FlatCAMApp.py:5547 +#: FlatCAMApp.py:5658 msgid "" "Failed join. The Geometry objects are of different types.\n" "At least one is MultiGeo type and the other is SingleGeo type. A possibility " @@ -522,51 +551,47 @@ msgstr "" "be lost and the result may not be what was expected. \n" "Check the generated GCODE." -#: FlatCAMApp.py:5559 -msgid "Multigeo. Geometry merging finished" -msgstr "Multigeo. Geometry merging finished" - -#: FlatCAMApp.py:5568 +#: FlatCAMApp.py:5670 FlatCAMApp.py:5680 msgid "Geometry merging finished" msgstr "Geometry merging finished" -#: FlatCAMApp.py:5590 +#: FlatCAMApp.py:5703 msgid "Failed. Excellon joining works only on Excellon objects." msgstr "Failed. Excellon joining works only on Excellon objects." -#: FlatCAMApp.py:5600 +#: FlatCAMApp.py:5713 msgid "Excellon merging finished" msgstr "Excellon merging finished" -#: FlatCAMApp.py:5618 +#: FlatCAMApp.py:5731 msgid "Failed. Gerber joining works only on Gerber objects." msgstr "Failed. Gerber joining works only on Gerber objects." -#: FlatCAMApp.py:5628 +#: FlatCAMApp.py:5741 msgid "Gerber merging finished" msgstr "Gerber merging finished" -#: FlatCAMApp.py:5648 FlatCAMApp.py:5683 +#: FlatCAMApp.py:5761 FlatCAMApp.py:5796 msgid "Failed. Select a Geometry Object and try again." msgstr "Failed. Select a Geometry Object and try again." -#: FlatCAMApp.py:5652 FlatCAMApp.py:5688 +#: FlatCAMApp.py:5765 FlatCAMApp.py:5801 msgid "Expected a FlatCAMGeometry, got" msgstr "Expected a FlatCAMGeometry, got" -#: FlatCAMApp.py:5665 +#: FlatCAMApp.py:5778 msgid "A Geometry object was converted to MultiGeo type." msgstr "A Geometry object was converted to MultiGeo type." -#: FlatCAMApp.py:5703 +#: FlatCAMApp.py:5816 msgid "A Geometry object was converted to SingleGeo type." msgstr "A Geometry object was converted to SingleGeo type." -#: FlatCAMApp.py:5919 +#: FlatCAMApp.py:6043 msgid "Toggle Units" msgstr "Toggle Units" -#: FlatCAMApp.py:5921 +#: FlatCAMApp.py:6045 msgid "" "Changing the units of the project\n" "will scale all objects.\n" @@ -578,48 +603,44 @@ msgstr "" "\n" "Do you want to continue?" -#: FlatCAMApp.py:5924 FlatCAMApp.py:6929 FlatCAMApp.py:7005 FlatCAMApp.py:9290 -#: FlatCAMApp.py:9304 FlatCAMApp.py:9658 FlatCAMApp.py:9669 +#: FlatCAMApp.py:6048 FlatCAMApp.py:6922 FlatCAMApp.py:6999 FlatCAMApp.py:9669 +#: FlatCAMApp.py:9683 FlatCAMApp.py:10018 FlatCAMApp.py:10028 msgid "Ok" msgstr "Ok" -#: FlatCAMApp.py:5973 +#: FlatCAMApp.py:6097 msgid "Converted units to" msgstr "Converted units to" -#: FlatCAMApp.py:5987 -msgid "Units conversion cancelled." -msgstr "Units conversion cancelled." - -#: FlatCAMApp.py:6613 +#: FlatCAMApp.py:6737 msgid "Detachable Tabs" msgstr "Detachable Tabs" -#: FlatCAMApp.py:6828 FlatCAMApp.py:6889 FlatCAMApp.py:7560 FlatCAMApp.py:7622 -#: FlatCAMApp.py:7688 +#: FlatCAMApp.py:6811 FlatCAMApp.py:6855 FlatCAMApp.py:6883 FlatCAMApp.py:7815 +#: FlatCAMApp.py:7883 FlatCAMApp.py:7987 msgid "Preferences" msgstr "Preferences" -#: FlatCAMApp.py:6831 +#: FlatCAMApp.py:6817 msgid "Preferences applied." msgstr "Preferences applied." -#: FlatCAMApp.py:6894 +#: FlatCAMApp.py:6888 msgid "Preferences closed without saving." msgstr "Preferences closed without saving." -#: FlatCAMApp.py:6917 flatcamTools/ToolNonCopperClear.py:591 -#: flatcamTools/ToolNonCopperClear.py:987 flatcamTools/ToolPaint.py:502 -#: flatcamTools/ToolSolderPaste.py:562 flatcamTools/ToolSolderPaste.py:892 +#: FlatCAMApp.py:6911 flatcamTools/ToolNCC.py:930 flatcamTools/ToolNCC.py:1435 +#: flatcamTools/ToolPaint.py:855 flatcamTools/ToolSolderPaste.py:568 +#: flatcamTools/ToolSolderPaste.py:893 msgid "Please enter a tool diameter with non-zero value, in Float format." msgstr "Please enter a tool diameter with non-zero value, in Float format." -#: FlatCAMApp.py:6922 flatcamTools/ToolNonCopperClear.py:595 -#: flatcamTools/ToolPaint.py:506 flatcamTools/ToolSolderPaste.py:566 +#: FlatCAMApp.py:6915 flatcamTools/ToolNCC.py:934 flatcamTools/ToolPaint.py:859 +#: flatcamTools/ToolSolderPaste.py:572 msgid "Adding Tool cancelled" msgstr "Adding Tool cancelled" -#: FlatCAMApp.py:6925 +#: FlatCAMApp.py:6918 msgid "" "Adding Tool works only when Advanced is checked.\n" "Go to Preferences -> General - Show Advanced Options." @@ -627,11 +648,11 @@ msgstr "" "Adding Tool works only when Advanced is checked.\n" "Go to Preferences -> General - Show Advanced Options." -#: FlatCAMApp.py:7000 +#: FlatCAMApp.py:6994 msgid "Delete objects" msgstr "Delete objects" -#: FlatCAMApp.py:7003 +#: FlatCAMApp.py:6997 msgid "" "Are you sure you want to permanently delete\n" "the selected objects?" @@ -639,15 +660,15 @@ msgstr "" "Are you sure you want to permanently delete\n" "the selected objects?" -#: FlatCAMApp.py:7034 +#: FlatCAMApp.py:7035 msgid "Object(s) deleted" msgstr "Object(s) deleted" -#: FlatCAMApp.py:7038 flatcamTools/ToolDblSided.py:713 +#: FlatCAMApp.py:7039 FlatCAMApp.py:7194 flatcamTools/ToolDblSided.py:819 msgid "Failed. No object(s) selected..." msgstr "Failed. No object(s) selected..." -#: FlatCAMApp.py:7040 +#: FlatCAMApp.py:7041 msgid "Save the work in Editor and try again ..." msgstr "Save the work in Editor and try again ..." @@ -663,627 +684,581 @@ msgstr "Click to set the origin ..." msgid "Setting Origin..." msgstr "Setting Origin..." -#: FlatCAMApp.py:7131 +#: FlatCAMApp.py:7132 FlatCAMApp.py:7234 msgid "Origin set" msgstr "Origin set" -#: FlatCAMApp.py:7138 +#: FlatCAMApp.py:7149 msgid "Origin coordinates specified but incomplete." msgstr "Origin coordinates specified but incomplete." -#: FlatCAMApp.py:7197 +#: FlatCAMApp.py:7190 +#| msgid "Setting Origin..." +msgid "Moving to Origin..." +msgstr "Moving to Origin..." + +#: FlatCAMApp.py:7271 msgid "Jump to ..." msgstr "Jump to ..." -#: FlatCAMApp.py:7198 +#: FlatCAMApp.py:7272 msgid "Enter the coordinates in format X,Y:" msgstr "Enter the coordinates in format X,Y:" -#: FlatCAMApp.py:7208 +#: FlatCAMApp.py:7282 msgid "Wrong coordinates. Enter coordinates in format: X,Y" msgstr "Wrong coordinates. Enter coordinates in format: X,Y" -#: FlatCAMApp.py:7288 flatcamEditors/FlatCAMExcEditor.py:3599 -#: flatcamEditors/FlatCAMExcEditor.py:3607 -#: flatcamEditors/FlatCAMGeoEditor.py:4036 -#: flatcamEditors/FlatCAMGeoEditor.py:4051 -#: flatcamEditors/FlatCAMGrbEditor.py:1086 -#: flatcamEditors/FlatCAMGrbEditor.py:1203 -#: flatcamEditors/FlatCAMGrbEditor.py:1489 -#: flatcamEditors/FlatCAMGrbEditor.py:1758 -#: flatcamEditors/FlatCAMGrbEditor.py:4445 -#: flatcamEditors/FlatCAMGrbEditor.py:4460 flatcamGUI/FlatCAMGUI.py:3145 -#: flatcamGUI/FlatCAMGUI.py:3157 +#: FlatCAMApp.py:7360 FlatCAMApp.py:7509 +#: flatcamEditors/FlatCAMExcEditor.py:3622 +#: flatcamEditors/FlatCAMExcEditor.py:3630 +#: flatcamEditors/FlatCAMGeoEditor.py:4349 +#: flatcamEditors/FlatCAMGeoEditor.py:4363 +#: flatcamEditors/FlatCAMGrbEditor.py:1085 +#: flatcamEditors/FlatCAMGrbEditor.py:1202 +#: flatcamEditors/FlatCAMGrbEditor.py:1488 +#: flatcamEditors/FlatCAMGrbEditor.py:1757 +#: flatcamEditors/FlatCAMGrbEditor.py:4489 +#: flatcamEditors/FlatCAMGrbEditor.py:4504 flatcamGUI/FlatCAMGUI.py:3370 +#: flatcamGUI/FlatCAMGUI.py:3382 flatcamTools/ToolAlignObjects.py:393 +#: flatcamTools/ToolAlignObjects.py:415 msgid "Done." msgstr "Done." -#: FlatCAMApp.py:7440 FlatCAMApp.py:7511 -msgid "No object is selected. Select an object and try again." -msgstr "No object is selected. Select an object and try again." - -#: FlatCAMApp.py:7531 -msgid "" -"Aborting. The current task will be gracefully closed as soon as possible..." -msgstr "" -"Aborting. The current task will be gracefully closed as soon as possible..." - -#: FlatCAMApp.py:7537 -msgid "The current task was gracefully closed on user request..." -msgstr "The current task was gracefully closed on user request..." - -#: FlatCAMApp.py:7619 -msgid "Preferences edited but not saved." -msgstr "Preferences edited but not saved." - -#: FlatCAMApp.py:7633 FlatCAMApp.py:7645 FlatCAMApp.py:7662 FlatCAMApp.py:7679 -#: FlatCAMApp.py:7739 FlatCAMCommon.py:1181 FlatCAMCommon.py:1356 -#: FlatCAMObj.py:4256 -msgid "Tools Database" -msgstr "Tools Database" - -#: FlatCAMApp.py:7659 -msgid "Tools in Tools Database edited but not saved." -msgstr "Tools in Tools Database edited but not saved." - -#: FlatCAMApp.py:7683 -msgid "Tool from DB added in Tool Table." -msgstr "Tool from DB added in Tool Table." - -#: FlatCAMApp.py:7685 -msgid "Adding tool from DB is not allowed for this object." -msgstr "Adding tool from DB is not allowed for this object." - -#: FlatCAMApp.py:7719 -msgid "" -"One or more values are changed.\n" -"Do you want to save the Preferences?" -msgstr "" -"One or more values are changed.\n" -"Do you want to save the Preferences?" - -#: FlatCAMApp.py:7721 flatcamGUI/FlatCAMGUI.py:222 -msgid "Save Preferences" -msgstr "Save Preferences" - -#: FlatCAMApp.py:7745 -msgid "" -"One or more Tools are edited.\n" -"Do you want to update the Tools Database?" -msgstr "" -"One or more Tools are edited.\n" -"Do you want to update the Tools Database?" - -#: FlatCAMApp.py:7747 -msgid "Save Tools Database" -msgstr "Save Tools Database" - -#: FlatCAMApp.py:7766 FlatCAMApp.py:9897 FlatCAMObj.py:6509 -msgid "Code Editor" -msgstr "Code Editor" - -#: FlatCAMApp.py:7784 -msgid "No object selected to Flip on Y axis." -msgstr "No object selected to Flip on Y axis." - -#: FlatCAMApp.py:7810 -msgid "Flip on Y axis done." -msgstr "Flip on Y axis done." - -#: FlatCAMApp.py:7812 FlatCAMApp.py:7854 -#: flatcamEditors/FlatCAMGrbEditor.py:5858 -msgid "Flip action was not executed." -msgstr "Flip action was not executed." - -#: FlatCAMApp.py:7826 -msgid "No object selected to Flip on X axis." -msgstr "No object selected to Flip on X axis." - -#: FlatCAMApp.py:7852 -msgid "Flip on X axis done." -msgstr "Flip on X axis done." - -#: FlatCAMApp.py:7868 -msgid "No object selected to Rotate." -msgstr "No object selected to Rotate." - -#: FlatCAMApp.py:7871 FlatCAMApp.py:7918 FlatCAMApp.py:7951 -msgid "Transform" -msgstr "Transform" - -#: FlatCAMApp.py:7871 FlatCAMApp.py:7918 FlatCAMApp.py:7951 -msgid "Enter the Angle value:" -msgstr "Enter the Angle value:" - -#: FlatCAMApp.py:7902 -msgid "Rotation done." -msgstr "Rotation done." - -#: FlatCAMApp.py:7904 -msgid "Rotation movement was not executed." -msgstr "Rotation movement was not executed." - -#: FlatCAMApp.py:7916 -msgid "No object selected to Skew/Shear on X axis." -msgstr "No object selected to Skew/Shear on X axis." - -#: FlatCAMApp.py:7938 -msgid "Skew on X axis done." -msgstr "Skew on X axis done." - -#: FlatCAMApp.py:7949 -msgid "No object selected to Skew/Shear on Y axis." -msgstr "No object selected to Skew/Shear on Y axis." - -#: FlatCAMApp.py:7971 -msgid "Skew on Y axis done." -msgstr "Skew on Y axis done." - -#: FlatCAMApp.py:8119 FlatCAMApp.py:8166 flatcamGUI/FlatCAMGUI.py:449 -#: flatcamGUI/FlatCAMGUI.py:1612 -msgid "Select All" -msgstr "Select All" - -#: FlatCAMApp.py:8123 FlatCAMApp.py:8170 flatcamGUI/FlatCAMGUI.py:451 -msgid "Deselect All" -msgstr "Deselect All" - -#: FlatCAMApp.py:8186 -msgid "All objects are selected." -msgstr "All objects are selected." - -#: FlatCAMApp.py:8196 -msgid "Objects selection is cleared." -msgstr "Objects selection is cleared." - -#: FlatCAMApp.py:8216 flatcamGUI/FlatCAMGUI.py:1605 -msgid "Grid On/Off" -msgstr "Grid On/Off" - -#: FlatCAMApp.py:8228 flatcamEditors/FlatCAMGeoEditor.py:940 -#: flatcamEditors/FlatCAMGrbEditor.py:2574 -#: flatcamEditors/FlatCAMGrbEditor.py:5431 flatcamGUI/ObjectUI.py:1304 -#: flatcamTools/ToolDblSided.py:187 flatcamTools/ToolDblSided.py:245 -#: flatcamTools/ToolNonCopperClear.py:286 flatcamTools/ToolPaint.py:188 -#: flatcamTools/ToolSolderPaste.py:121 flatcamTools/ToolSolderPaste.py:591 -#: flatcamTools/ToolTransform.py:310 -msgid "Add" -msgstr "Add" - -#: FlatCAMApp.py:8230 FlatCAMObj.py:3963 -#: flatcamEditors/FlatCAMGrbEditor.py:2579 -#: flatcamEditors/FlatCAMGrbEditor.py:2727 flatcamGUI/FlatCAMGUI.py:680 -#: flatcamGUI/FlatCAMGUI.py:991 flatcamGUI/FlatCAMGUI.py:2018 -#: flatcamGUI/FlatCAMGUI.py:2161 flatcamGUI/FlatCAMGUI.py:2559 -#: flatcamGUI/ObjectUI.py:1330 flatcamTools/ToolNonCopperClear.py:298 -#: flatcamTools/ToolPaint.py:200 flatcamTools/ToolSolderPaste.py:127 -#: flatcamTools/ToolSolderPaste.py:594 -msgid "Delete" -msgstr "Delete" - -#: FlatCAMApp.py:8243 -msgid "New Grid ..." -msgstr "New Grid ..." - -#: FlatCAMApp.py:8244 -msgid "Enter a Grid Value:" -msgstr "Enter a Grid Value:" - -#: FlatCAMApp.py:8252 FlatCAMApp.py:8279 -msgid "Please enter a grid value with non-zero value, in Float format." -msgstr "Please enter a grid value with non-zero value, in Float format." - -#: FlatCAMApp.py:8258 -msgid "New Grid added" -msgstr "New Grid added" - -#: FlatCAMApp.py:8261 -msgid "Grid already exists" -msgstr "Grid already exists" - -#: FlatCAMApp.py:8264 -msgid "Adding New Grid cancelled" -msgstr "Adding New Grid cancelled" - -#: FlatCAMApp.py:8286 -msgid " Grid Value does not exist" -msgstr " Grid Value does not exist" - -#: FlatCAMApp.py:8289 -msgid "Grid Value deleted" -msgstr "Grid Value deleted" - -#: FlatCAMApp.py:8292 -msgid "Delete Grid value cancelled" -msgstr "Delete Grid value cancelled" - -#: FlatCAMApp.py:8298 -msgid "Key Shortcut List" -msgstr "Key Shortcut List" - -#: FlatCAMApp.py:8332 -msgid " No object selected to copy it's name" -msgstr " No object selected to copy it's name" - -#: FlatCAMApp.py:8336 -msgid "Name copied on clipboard ..." -msgstr "Name copied on clipboard ..." - -#: FlatCAMApp.py:8534 flatcamEditors/FlatCAMGrbEditor.py:4377 -msgid "Coordinates copied to clipboard." -msgstr "Coordinates copied to clipboard." - -#: FlatCAMApp.py:8762 FlatCAMApp.py:8768 FlatCAMApp.py:8774 FlatCAMApp.py:8780 -#: ObjectCollection.py:797 ObjectCollection.py:803 ObjectCollection.py:809 -#: ObjectCollection.py:815 ObjectCollection.py:821 ObjectCollection.py:827 -msgid "selected" -msgstr "selected" - -#: FlatCAMApp.py:8922 -msgid "" -"There are files/objects opened in FlatCAM.\n" -"Creating a New project will delete them.\n" -"Do you want to Save the project?" -msgstr "" -"There are files/objects opened in FlatCAM.\n" -"Creating a New project will delete them.\n" -"Do you want to Save the project?" - -#: FlatCAMApp.py:8944 -msgid "New Project created" -msgstr "New Project created" - -#: FlatCAMApp.py:9079 FlatCAMApp.py:9083 flatcamGUI/FlatCAMGUI.py:767 -#: flatcamGUI/FlatCAMGUI.py:2352 -msgid "Open Gerber" -msgstr "Open Gerber" - -#: FlatCAMApp.py:9090 -msgid "Opening Gerber file." -msgstr "Opening Gerber file." - -#: FlatCAMApp.py:9096 -msgid "Open Gerber cancelled." -msgstr "Open Gerber cancelled." - -#: FlatCAMApp.py:9117 FlatCAMApp.py:9121 flatcamGUI/FlatCAMGUI.py:769 -#: flatcamGUI/FlatCAMGUI.py:2354 -msgid "Open Excellon" -msgstr "Open Excellon" - -#: FlatCAMApp.py:9127 -msgid "Opening Excellon file." -msgstr "Opening Excellon file." - -#: FlatCAMApp.py:9133 -msgid " Open Excellon cancelled." -msgstr " Open Excellon cancelled." - -#: FlatCAMApp.py:9157 FlatCAMApp.py:9161 -msgid "Open G-Code" -msgstr "Open G-Code" - -#: FlatCAMApp.py:9168 -msgid "Opening G-Code file." -msgstr "Opening G-Code file." - -#: FlatCAMApp.py:9174 -msgid "Open G-Code cancelled." -msgstr "Open G-Code cancelled." - -#: FlatCAMApp.py:9192 FlatCAMApp.py:9195 flatcamGUI/FlatCAMGUI.py:1614 -msgid "Open Project" -msgstr "Open Project" - -#: FlatCAMApp.py:9204 -msgid "Open Project cancelled." -msgstr "Open Project cancelled." - -#: FlatCAMApp.py:9228 FlatCAMApp.py:9232 -msgid "Open HPGL2" -msgstr "Open HPGL2" - -#: FlatCAMApp.py:9239 -msgid "Opening HPGL2 file." -msgstr "Opening HPGL2 file." - -#: FlatCAMApp.py:9244 -msgid "Open HPGL2 file cancelled." -msgstr "Open HPGL2 file cancelled." - -#: FlatCAMApp.py:9262 FlatCAMApp.py:9265 -msgid "Open Configuration File" -msgstr "Open Configuration File" - -#: FlatCAMApp.py:9270 -msgid "Open Config cancelled." -msgstr "Open Config cancelled." - -#: FlatCAMApp.py:9286 FlatCAMApp.py:9654 FlatCAMApp.py:10124 -#: FlatCAMApp.py:10128 +#: FlatCAMApp.py:7375 FlatCAMApp.py:9665 FlatCAMApp.py:9761 FlatCAMApp.py:9803 +#: FlatCAMApp.py:9844 FlatCAMApp.py:9885 FlatCAMApp.py:9926 FlatCAMApp.py:9970 +#: FlatCAMApp.py:10014 FlatCAMApp.py:10503 FlatCAMApp.py:10507 +#: flatcamTools/ToolProperties.py:116 msgid "No object selected." msgstr "No object selected." -#: FlatCAMApp.py:9287 FlatCAMApp.py:9655 +#: FlatCAMApp.py:7394 +#| msgid "Bottom Left" +msgid "Bottom-Left" +msgstr "Bottom-Left" + +#: FlatCAMApp.py:7395 flatcamGUI/PreferencesUI.py:8111 +#: flatcamTools/ToolCalibration.py:159 +msgid "Top-Left" +msgstr "Top-Left" + +#: FlatCAMApp.py:7396 flatcamGUI/PreferencesUI.py:8112 +#: flatcamTools/ToolCalibration.py:160 +msgid "Bottom-Right" +msgstr "Bottom-Right" + +#: FlatCAMApp.py:7397 +#| msgid "Top Right" +msgid "Top-Right" +msgstr "Top-Right" + +#: FlatCAMApp.py:7398 flatcamGUI/ObjectUI.py:2624 +msgid "Center" +msgstr "Center" + +#: FlatCAMApp.py:7418 +#| msgid "Rotate ..." +msgid "Locate ..." +msgstr "Locate ..." + +#: FlatCAMApp.py:7679 FlatCAMApp.py:7756 +msgid "No object is selected. Select an object and try again." +msgstr "No object is selected. Select an object and try again." + +#: FlatCAMApp.py:7782 +msgid "" +"Aborting. The current task will be gracefully closed as soon as possible..." +msgstr "" +"Aborting. The current task will be gracefully closed as soon as possible..." + +#: FlatCAMApp.py:7787 +msgid "The current task was gracefully closed on user request..." +msgstr "The current task was gracefully closed on user request..." + +#: FlatCAMApp.py:7880 +msgid "Preferences edited but not saved." +msgstr "Preferences edited but not saved." + +#: FlatCAMApp.py:7897 FlatCAMApp.py:7925 FlatCAMApp.py:7952 FlatCAMApp.py:7971 +#: FlatCAMApp.py:8038 FlatCAMCommon.py:1182 FlatCAMCommon.py:1357 +#: FlatCAMCommon.py:2612 FlatCAMCommon.py:2820 FlatCAMObj.py:4798 +#: flatcamTools/ToolNCC.py:3963 flatcamTools/ToolNCC.py:4047 +#: flatcamTools/ToolPaint.py:4027 flatcamTools/ToolPaint.py:4112 +msgid "Tools Database" +msgstr "Tools Database" + +#: FlatCAMApp.py:7949 +msgid "Tools in Tools Database edited but not saved." +msgstr "Tools in Tools Database edited but not saved." + +#: FlatCAMApp.py:7975 flatcamTools/ToolNCC.py:3970 +#: flatcamTools/ToolPaint.py:4034 +msgid "Tool from DB added in Tool Table." +msgstr "Tool from DB added in Tool Table." + +#: FlatCAMApp.py:7977 +msgid "Adding tool from DB is not allowed for this object." +msgstr "Adding tool from DB is not allowed for this object." + +#: FlatCAMApp.py:8018 +msgid "" +"One or more values are changed.\n" +"Do you want to save the Preferences?" +msgstr "" +"One or more values are changed.\n" +"Do you want to save the Preferences?" + +#: FlatCAMApp.py:8020 flatcamGUI/FlatCAMGUI.py:291 +msgid "Save Preferences" +msgstr "Save Preferences" + +#: FlatCAMApp.py:8044 +msgid "" +"One or more Tools are edited.\n" +"Do you want to update the Tools Database?" +msgstr "" +"One or more Tools are edited.\n" +"Do you want to update the Tools Database?" + +#: FlatCAMApp.py:8046 +msgid "Save Tools Database" +msgstr "Save Tools Database" + +#: FlatCAMApp.py:8065 FlatCAMApp.py:10252 FlatCAMObj.py:7089 +msgid "Code Editor" +msgstr "Code Editor" + +#: FlatCAMApp.py:8087 +msgid "No object selected to Flip on Y axis." +msgstr "No object selected to Flip on Y axis." + +#: FlatCAMApp.py:8113 +msgid "Flip on Y axis done." +msgstr "Flip on Y axis done." + +#: FlatCAMApp.py:8115 FlatCAMApp.py:8163 +#: flatcamEditors/FlatCAMGrbEditor.py:5893 +msgid "Flip action was not executed." +msgstr "Flip action was not executed." + +#: FlatCAMApp.py:8135 +msgid "No object selected to Flip on X axis." +msgstr "No object selected to Flip on X axis." + +#: FlatCAMApp.py:8161 +msgid "Flip on X axis done." +msgstr "Flip on X axis done." + +#: FlatCAMApp.py:8183 +msgid "No object selected to Rotate." +msgstr "No object selected to Rotate." + +#: FlatCAMApp.py:8186 FlatCAMApp.py:8239 FlatCAMApp.py:8278 +msgid "Transform" +msgstr "Transform" + +#: FlatCAMApp.py:8186 FlatCAMApp.py:8239 FlatCAMApp.py:8278 +msgid "Enter the Angle value:" +msgstr "Enter the Angle value:" + +#: FlatCAMApp.py:8217 +msgid "Rotation done." +msgstr "Rotation done." + +#: FlatCAMApp.py:8219 +msgid "Rotation movement was not executed." +msgstr "Rotation movement was not executed." + +#: FlatCAMApp.py:8237 +msgid "No object selected to Skew/Shear on X axis." +msgstr "No object selected to Skew/Shear on X axis." + +#: FlatCAMApp.py:8259 +msgid "Skew on X axis done." +msgstr "Skew on X axis done." + +#: FlatCAMApp.py:8276 +msgid "No object selected to Skew/Shear on Y axis." +msgstr "No object selected to Skew/Shear on Y axis." + +#: FlatCAMApp.py:8298 +msgid "Skew on Y axis done." +msgstr "Skew on Y axis done." + +#: FlatCAMApp.py:8451 FlatCAMApp.py:8498 flatcamGUI/FlatCAMGUI.py:488 +#: flatcamGUI/FlatCAMGUI.py:1713 +msgid "Select All" +msgstr "Select All" + +#: FlatCAMApp.py:8455 FlatCAMApp.py:8502 flatcamGUI/FlatCAMGUI.py:490 +msgid "Deselect All" +msgstr "Deselect All" + +#: FlatCAMApp.py:8518 +msgid "All objects are selected." +msgstr "All objects are selected." + +#: FlatCAMApp.py:8528 +msgid "Objects selection is cleared." +msgstr "Objects selection is cleared." + +#: FlatCAMApp.py:8548 flatcamGUI/FlatCAMGUI.py:1706 +msgid "Grid On/Off" +msgstr "Grid On/Off" + +#: FlatCAMApp.py:8560 flatcamEditors/FlatCAMGeoEditor.py:940 +#: flatcamEditors/FlatCAMGrbEditor.py:2580 +#: flatcamEditors/FlatCAMGrbEditor.py:5475 flatcamGUI/ObjectUI.py:1593 +#: flatcamTools/ToolDblSided.py:193 flatcamTools/ToolDblSided.py:426 +#: flatcamTools/ToolNCC.py:294 flatcamTools/ToolNCC.py:631 +#: flatcamTools/ToolPaint.py:277 flatcamTools/ToolPaint.py:673 +#: flatcamTools/ToolSolderPaste.py:123 flatcamTools/ToolSolderPaste.py:597 +#: flatcamTools/ToolTransform.py:479 +msgid "Add" +msgstr "Add" + +#: FlatCAMApp.py:8562 FlatCAMObj.py:4416 +#: flatcamEditors/FlatCAMGrbEditor.py:2585 +#: flatcamEditors/FlatCAMGrbEditor.py:2733 flatcamGUI/FlatCAMGUI.py:736 +#: flatcamGUI/FlatCAMGUI.py:1059 flatcamGUI/FlatCAMGUI.py:2126 +#: flatcamGUI/FlatCAMGUI.py:2269 flatcamGUI/FlatCAMGUI.py:2733 +#: flatcamGUI/ObjectUI.py:1621 flatcamTools/ToolNCC.py:316 +#: flatcamTools/ToolNCC.py:637 flatcamTools/ToolPaint.py:299 +#: flatcamTools/ToolPaint.py:679 flatcamTools/ToolSolderPaste.py:129 +#: flatcamTools/ToolSolderPaste.py:600 +msgid "Delete" +msgstr "Delete" + +#: FlatCAMApp.py:8575 +msgid "New Grid ..." +msgstr "New Grid ..." + +#: FlatCAMApp.py:8576 +msgid "Enter a Grid Value:" +msgstr "Enter a Grid Value:" + +#: FlatCAMApp.py:8584 FlatCAMApp.py:8611 +msgid "Please enter a grid value with non-zero value, in Float format." +msgstr "Please enter a grid value with non-zero value, in Float format." + +#: FlatCAMApp.py:8590 +msgid "New Grid added" +msgstr "New Grid added" + +#: FlatCAMApp.py:8593 +msgid "Grid already exists" +msgstr "Grid already exists" + +#: FlatCAMApp.py:8596 +msgid "Adding New Grid cancelled" +msgstr "Adding New Grid cancelled" + +#: FlatCAMApp.py:8618 +msgid " Grid Value does not exist" +msgstr " Grid Value does not exist" + +#: FlatCAMApp.py:8621 +msgid "Grid Value deleted" +msgstr "Grid Value deleted" + +#: FlatCAMApp.py:8624 +msgid "Delete Grid value cancelled" +msgstr "Delete Grid value cancelled" + +#: FlatCAMApp.py:8630 +msgid "Key Shortcut List" +msgstr "Key Shortcut List" + +#: FlatCAMApp.py:8664 +msgid " No object selected to copy it's name" +msgstr " No object selected to copy it's name" + +#: FlatCAMApp.py:8668 +msgid "Name copied on clipboard ..." +msgstr "Name copied on clipboard ..." + +#: FlatCAMApp.py:8881 flatcamEditors/FlatCAMGrbEditor.py:4421 +msgid "Coordinates copied to clipboard." +msgstr "Coordinates copied to clipboard." + +#: FlatCAMApp.py:9120 FlatCAMApp.py:9126 FlatCAMApp.py:9132 FlatCAMApp.py:9138 +#: ObjectCollection.py:911 ObjectCollection.py:917 ObjectCollection.py:923 +#: ObjectCollection.py:929 ObjectCollection.py:935 ObjectCollection.py:941 +msgid "selected" +msgstr "selected" + +#: FlatCAMApp.py:9293 +msgid "" +"There are files/objects opened in FlatCAM.\n" +"Creating a New project will delete them.\n" +"Do you want to Save the project?" +msgstr "" +"There are files/objects opened in FlatCAM.\n" +"Creating a New project will delete them.\n" +"Do you want to Save the project?" + +#: FlatCAMApp.py:9314 +msgid "New Project created" +msgstr "New Project created" + +#: FlatCAMApp.py:9461 FlatCAMApp.py:9465 flatcamGUI/FlatCAMGUI.py:821 +#: flatcamGUI/FlatCAMGUI.py:2504 +msgid "Open Gerber" +msgstr "Open Gerber" + +#: FlatCAMApp.py:9470 FlatCAMApp.py:9507 FlatCAMApp.py:9549 FlatCAMApp.py:9618 +#: FlatCAMApp.py:10371 FlatCAMApp.py:11546 FlatCAMApp.py:11607 +msgid "" +"Canvas initialization started.\n" +"Canvas initialization finished in" +msgstr "" +"Canvas initialization started.\n" +"Canvas initialization finished in" + +#: FlatCAMApp.py:9472 +msgid "Opening Gerber file." +msgstr "Opening Gerber file." + +#: FlatCAMApp.py:9499 FlatCAMApp.py:9503 flatcamGUI/FlatCAMGUI.py:823 +#: flatcamGUI/FlatCAMGUI.py:2506 +msgid "Open Excellon" +msgstr "Open Excellon" + +#: FlatCAMApp.py:9509 +msgid "Opening Excellon file." +msgstr "Opening Excellon file." + +#: FlatCAMApp.py:9540 FlatCAMApp.py:9544 +msgid "Open G-Code" +msgstr "Open G-Code" + +#: FlatCAMApp.py:9551 +msgid "Opening G-Code file." +msgstr "Opening G-Code file." + +#: FlatCAMApp.py:9574 FlatCAMApp.py:9577 flatcamGUI/FlatCAMGUI.py:1715 +msgid "Open Project" +msgstr "Open Project" + +#: FlatCAMApp.py:9609 FlatCAMApp.py:9613 +msgid "Open HPGL2" +msgstr "Open HPGL2" + +#: FlatCAMApp.py:9620 +msgid "Opening HPGL2 file." +msgstr "Opening HPGL2 file." + +#: FlatCAMApp.py:9643 FlatCAMApp.py:9646 +msgid "Open Configuration File" +msgstr "Open Configuration File" + +#: FlatCAMApp.py:9666 FlatCAMApp.py:10015 msgid "Please Select a Geometry object to export" msgstr "Please Select a Geometry object to export" -#: FlatCAMApp.py:9301 +#: FlatCAMApp.py:9680 msgid "Only Geometry, Gerber and CNCJob objects can be used." msgstr "Only Geometry, Gerber and CNCJob objects can be used." -#: FlatCAMApp.py:9314 FlatCAMApp.py:9318 flatcamTools/ToolQRCode.py:827 -#: flatcamTools/ToolQRCode.py:831 +#: FlatCAMApp.py:9693 FlatCAMApp.py:9697 flatcamTools/ToolQRCode.py:829 +#: flatcamTools/ToolQRCode.py:833 msgid "Export SVG" msgstr "Export SVG" -#: FlatCAMApp.py:9324 flatcamTools/ToolQRCode.py:836 -msgid " Export SVG cancelled." -msgstr " Export SVG cancelled." - -#: FlatCAMApp.py:9345 +#: FlatCAMApp.py:9723 msgid "Data must be a 3D array with last dimension 3 or 4" msgstr "Data must be a 3D array with last dimension 3 or 4" -#: FlatCAMApp.py:9351 FlatCAMApp.py:9355 +#: FlatCAMApp.py:9729 FlatCAMApp.py:9733 msgid "Export PNG Image" msgstr "Export PNG Image" -#: FlatCAMApp.py:9360 -msgid "Export PNG cancelled." -msgstr "Export PNG cancelled." - -#: FlatCAMApp.py:9384 -msgid "No object selected. Please select an Gerber object to export." -msgstr "No object selected. Please select an Gerber object to export." - -#: FlatCAMApp.py:9390 FlatCAMApp.py:9613 +#: FlatCAMApp.py:9767 FlatCAMApp.py:9975 msgid "Failed. Only Gerber objects can be saved as Gerber files..." msgstr "Failed. Only Gerber objects can be saved as Gerber files..." -#: FlatCAMApp.py:9402 +#: FlatCAMApp.py:9779 msgid "Save Gerber source file" msgstr "Save Gerber source file" -#: FlatCAMApp.py:9408 -msgid "Save Gerber source file cancelled." -msgstr "Save Gerber source file cancelled." - -#: FlatCAMApp.py:9428 -msgid "No object selected. Please select an Script object to export." -msgstr "No object selected. Please select an Script object to export." - -#: FlatCAMApp.py:9434 +#: FlatCAMApp.py:9808 msgid "Failed. Only Script objects can be saved as TCL Script files..." msgstr "Failed. Only Script objects can be saved as TCL Script files..." -#: FlatCAMApp.py:9446 +#: FlatCAMApp.py:9820 msgid "Save Script source file" msgstr "Save Script source file" -#: FlatCAMApp.py:9452 -msgid "Save Script source file cancelled." -msgstr "Save Script source file cancelled." - -#: FlatCAMApp.py:9472 -msgid "No object selected. Please select an Document object to export." -msgstr "No object selected. Please select an Document object to export." - -#: FlatCAMApp.py:9478 +#: FlatCAMApp.py:9849 msgid "Failed. Only Document objects can be saved as Document files..." msgstr "Failed. Only Document objects can be saved as Document files..." -#: FlatCAMApp.py:9490 +#: FlatCAMApp.py:9861 msgid "Save Document source file" msgstr "Save Document source file" -#: FlatCAMApp.py:9496 -msgid "Save Document source file cancelled." -msgstr "Save Document source file cancelled." - -#: FlatCAMApp.py:9516 -msgid "No object selected. Please select an Excellon object to export." -msgstr "No object selected. Please select an Excellon object to export." - -#: FlatCAMApp.py:9522 FlatCAMApp.py:9566 FlatCAMApp.py:10473 +#: FlatCAMApp.py:9890 FlatCAMApp.py:9931 FlatCAMApp.py:10856 msgid "Failed. Only Excellon objects can be saved as Excellon files..." msgstr "Failed. Only Excellon objects can be saved as Excellon files..." -#: FlatCAMApp.py:9530 FlatCAMApp.py:9534 +#: FlatCAMApp.py:9898 FlatCAMApp.py:9902 msgid "Save Excellon source file" msgstr "Save Excellon source file" -#: FlatCAMApp.py:9540 -msgid "Saving Excellon source file cancelled." -msgstr "Saving Excellon source file cancelled." - -#: FlatCAMApp.py:9560 -msgid "No object selected. Please Select an Excellon object to export." -msgstr "No object selected. Please Select an Excellon object to export." - -#: FlatCAMApp.py:9574 FlatCAMApp.py:9578 +#: FlatCAMApp.py:9939 FlatCAMApp.py:9943 msgid "Export Excellon" msgstr "Export Excellon" -#: FlatCAMApp.py:9584 -msgid "Export Excellon cancelled." -msgstr "Export Excellon cancelled." - -#: FlatCAMApp.py:9607 -msgid "No object selected. Please Select an Gerber object to export." -msgstr "No object selected. Please Select an Gerber object to export." - -#: FlatCAMApp.py:9621 FlatCAMApp.py:9625 +#: FlatCAMApp.py:9983 FlatCAMApp.py:9987 msgid "Export Gerber" msgstr "Export Gerber" -#: FlatCAMApp.py:9631 -msgid "Export Gerber cancelled." -msgstr "Export Gerber cancelled." - -#: FlatCAMApp.py:9666 +#: FlatCAMApp.py:10025 msgid "Only Geometry objects can be used." msgstr "Only Geometry objects can be used." -#: FlatCAMApp.py:9680 FlatCAMApp.py:9684 +#: FlatCAMApp.py:10039 FlatCAMApp.py:10043 msgid "Export DXF" msgstr "Export DXF" -#: FlatCAMApp.py:9691 -msgid "Export DXF cancelled." -msgstr "Export DXF cancelled." - -#: FlatCAMApp.py:9711 FlatCAMApp.py:9714 +#: FlatCAMApp.py:10068 FlatCAMApp.py:10071 msgid "Import SVG" msgstr "Import SVG" -#: FlatCAMApp.py:9724 -msgid "Open SVG cancelled." -msgstr "Open SVG cancelled." - -#: FlatCAMApp.py:9743 FlatCAMApp.py:9747 +#: FlatCAMApp.py:10099 FlatCAMApp.py:10103 msgid "Import DXF" msgstr "Import DXF" -#: FlatCAMApp.py:9757 -msgid "Open DXF cancelled." -msgstr "Open DXF cancelled." - -#: FlatCAMApp.py:9799 +#: FlatCAMApp.py:10154 msgid "Viewing the source code of the selected object." msgstr "Viewing the source code of the selected object." -#: FlatCAMApp.py:9800 FlatCAMObj.py:6495 FlatCAMObj.py:7225 +#: FlatCAMApp.py:10155 FlatCAMObj.py:7075 FlatCAMObj.py:7852 msgid "Loading..." msgstr "Loading..." -#: FlatCAMApp.py:9806 FlatCAMApp.py:9810 +#: FlatCAMApp.py:10161 FlatCAMApp.py:10165 msgid "Select an Gerber or Excellon file to view it's source file." msgstr "Select an Gerber or Excellon file to view it's source file." -#: FlatCAMApp.py:9824 +#: FlatCAMApp.py:10179 msgid "Source Editor" msgstr "Source Editor" -#: FlatCAMApp.py:9864 FlatCAMApp.py:9871 +#: FlatCAMApp.py:10219 FlatCAMApp.py:10226 msgid "There is no selected object for which to see it's source file code." msgstr "There is no selected object for which to see it's source file code." -#: FlatCAMApp.py:9883 +#: FlatCAMApp.py:10238 msgid "Failed to load the source code for the selected object" msgstr "Failed to load the source code for the selected object" -#: FlatCAMApp.py:9925 +#: FlatCAMApp.py:10274 +#| msgid "Plot Line" +msgid "Go to Line ..." +msgstr "Go to Line ..." + +#: FlatCAMApp.py:10275 +#| msgid "Line" +msgid "Line:" +msgstr "Line:" + +#: FlatCAMApp.py:10304 msgid "New TCL script file created in Code Editor." msgstr "New TCL script file created in Code Editor." -#: FlatCAMApp.py:9963 FlatCAMApp.py:9965 +#: FlatCAMApp.py:10343 FlatCAMApp.py:10345 msgid "Open TCL script" msgstr "Open TCL script" -#: FlatCAMApp.py:9969 -msgid "Open TCL script cancelled." -msgstr "Open TCL script cancelled." - -#: FlatCAMApp.py:9993 +#: FlatCAMApp.py:10373 msgid "Executing FlatCAMScript file." msgstr "Executing FlatCAMScript file." -#: FlatCAMApp.py:10000 FlatCAMApp.py:10003 +#: FlatCAMApp.py:10381 FlatCAMApp.py:10384 msgid "Run TCL script" msgstr "Run TCL script" -#: FlatCAMApp.py:10013 -msgid "Run TCL script cancelled." -msgstr "Run TCL script cancelled." - -#: FlatCAMApp.py:10029 +#: FlatCAMApp.py:10408 msgid "TCL script file opened in Code Editor and executed." msgstr "TCL script file opened in Code Editor and executed." -#: FlatCAMApp.py:10080 FlatCAMApp.py:10086 +#: FlatCAMApp.py:10459 FlatCAMApp.py:10465 msgid "Save Project As ..." msgstr "Save Project As ..." -#: FlatCAMApp.py:10082 flatcamGUI/FlatCAMGUI.py:1051 -#: flatcamGUI/FlatCAMGUI.py:2053 +#: FlatCAMApp.py:10461 flatcamGUI/FlatCAMGUI.py:1119 +#: flatcamGUI/FlatCAMGUI.py:2161 msgid "Project" msgstr "Project" -#: FlatCAMApp.py:10091 -msgid "Save Project cancelled." -msgstr "Save Project cancelled." - -#: FlatCAMApp.py:10121 +#: FlatCAMApp.py:10500 msgid "FlatCAM objects print" msgstr "FlatCAM objects print" -#: FlatCAMApp.py:10134 FlatCAMApp.py:10141 +#: FlatCAMApp.py:10513 FlatCAMApp.py:10520 msgid "Save Object as PDF ..." msgstr "Save Object as PDF ..." -#: FlatCAMApp.py:10146 -msgid "Save Object PDF cancelled." -msgstr "Save Object PDF cancelled." - -#: FlatCAMApp.py:10150 +#: FlatCAMApp.py:10529 msgid "Printing PDF ... Please wait." msgstr "Printing PDF ... Please wait." -#: FlatCAMApp.py:10329 +#: FlatCAMApp.py:10708 msgid "PDF file saved to" msgstr "PDF file saved to" -#: FlatCAMApp.py:10353 +#: FlatCAMApp.py:10733 msgid "Exporting SVG" msgstr "Exporting SVG" -#: FlatCAMApp.py:10397 +#: FlatCAMApp.py:10776 msgid "SVG file exported to" msgstr "SVG file exported to" -#: FlatCAMApp.py:10422 +#: FlatCAMApp.py:10802 msgid "" "Save cancelled because source file is empty. Try to export the Gerber file." msgstr "" "Save cancelled because source file is empty. Try to export the Gerber file." -#: FlatCAMApp.py:10568 +#: FlatCAMApp.py:10950 msgid "Excellon file exported to" msgstr "Excellon file exported to" -#: FlatCAMApp.py:10577 +#: FlatCAMApp.py:10959 msgid "Exporting Excellon" msgstr "Exporting Excellon" -#: FlatCAMApp.py:10583 FlatCAMApp.py:10591 +#: FlatCAMApp.py:10964 FlatCAMApp.py:10971 msgid "Could not export Excellon file." msgstr "Could not export Excellon file." -#: FlatCAMApp.py:10707 +#: FlatCAMApp.py:11087 msgid "Gerber file exported to" msgstr "Gerber file exported to" -#: FlatCAMApp.py:10715 +#: FlatCAMApp.py:11095 msgid "Exporting Gerber" msgstr "Exporting Gerber" -#: FlatCAMApp.py:10721 FlatCAMApp.py:10729 +#: FlatCAMApp.py:11100 FlatCAMApp.py:11107 msgid "Could not export Gerber file." msgstr "Could not export Gerber file." -#: FlatCAMApp.py:10763 +#: FlatCAMApp.py:11142 msgid "DXF file exported to" msgstr "DXF file exported to" -#: FlatCAMApp.py:10769 +#: FlatCAMApp.py:11148 msgid "Exporting DXF" msgstr "Exporting DXF" -#: FlatCAMApp.py:10774 FlatCAMApp.py:10781 +#: FlatCAMApp.py:11153 FlatCAMApp.py:11160 msgid "Could not export DXF file." msgstr "Could not export DXF file." -#: FlatCAMApp.py:10804 FlatCAMApp.py:10847 flatcamTools/ToolImage.py:278 +#: FlatCAMApp.py:11183 FlatCAMApp.py:11225 flatcamTools/ToolImage.py:277 msgid "" "Not supported type is picked as parameter. Only Geometry and Gerber are " "supported" @@ -1291,79 +1266,79 @@ msgstr "" "Not supported type is picked as parameter. Only Geometry and Gerber are " "supported" -#: FlatCAMApp.py:10814 +#: FlatCAMApp.py:11193 msgid "Importing SVG" msgstr "Importing SVG" -#: FlatCAMApp.py:10825 FlatCAMApp.py:10867 FlatCAMApp.py:10926 -#: FlatCAMApp.py:10993 FlatCAMApp.py:11056 FlatCAMApp.py:11123 -#: FlatCAMApp.py:11161 flatcamTools/ToolImage.py:298 +#: FlatCAMApp.py:11204 FlatCAMApp.py:11244 FlatCAMApp.py:11302 +#: FlatCAMApp.py:11367 FlatCAMApp.py:11431 FlatCAMApp.py:11496 +#: FlatCAMApp.py:11533 flatcamTools/ToolImage.py:297 #: flatcamTools/ToolPDF.py:225 msgid "Opened" msgstr "Opened" -#: FlatCAMApp.py:10856 +#: FlatCAMApp.py:11234 msgid "Importing DXF" msgstr "Importing DXF" -#: FlatCAMApp.py:10892 FlatCAMApp.py:11082 +#: FlatCAMApp.py:11268 FlatCAMApp.py:11455 msgid "Failed to open file" msgstr "Failed to open file" -#: FlatCAMApp.py:10895 FlatCAMApp.py:11085 +#: FlatCAMApp.py:11271 FlatCAMApp.py:11458 msgid "Failed to parse file" msgstr "Failed to parse file" -#: FlatCAMApp.py:10907 +#: FlatCAMApp.py:11283 msgid "Object is not Gerber file or empty. Aborting object creation." msgstr "Object is not Gerber file or empty. Aborting object creation." -#: FlatCAMApp.py:10912 +#: FlatCAMApp.py:11288 msgid "Opening Gerber" msgstr "Opening Gerber" -#: FlatCAMApp.py:10919 +#: FlatCAMApp.py:11295 msgid " Open Gerber failed. Probable not a Gerber file." msgstr " Open Gerber failed. Probable not a Gerber file." -#: FlatCAMApp.py:10951 flatcamTools/ToolPcbWizard.py:427 +#: FlatCAMApp.py:11326 flatcamTools/ToolPcbWizard.py:425 msgid "This is not Excellon file." msgstr "This is not Excellon file." -#: FlatCAMApp.py:10955 +#: FlatCAMApp.py:11330 msgid "Cannot open file" msgstr "Cannot open file" -#: FlatCAMApp.py:10975 flatcamTools/ToolPDF.py:275 -#: flatcamTools/ToolPcbWizard.py:451 +#: FlatCAMApp.py:11349 flatcamTools/ToolPDF.py:275 +#: flatcamTools/ToolPcbWizard.py:447 msgid "No geometry found in file" msgstr "No geometry found in file" -#: FlatCAMApp.py:10978 +#: FlatCAMApp.py:11352 msgid "Opening Excellon." msgstr "Opening Excellon." -#: FlatCAMApp.py:10985 +#: FlatCAMApp.py:11359 msgid "Open Excellon file failed. Probable not an Excellon file." msgstr "Open Excellon file failed. Probable not an Excellon file." -#: FlatCAMApp.py:11016 +#: FlatCAMApp.py:11391 msgid "Reading GCode file" msgstr "Reading GCode file" -#: FlatCAMApp.py:11023 +#: FlatCAMApp.py:11398 msgid "Failed to open" msgstr "Failed to open" -#: FlatCAMApp.py:11031 +#: FlatCAMApp.py:11406 msgid "This is not GCODE" msgstr "This is not GCODE" -#: FlatCAMApp.py:11036 +#: FlatCAMApp.py:11411 msgid "Opening G-Code." msgstr "Opening G-Code." -#: FlatCAMApp.py:11045 +#: FlatCAMApp.py:11420 msgid "" "Failed to create CNCJob Object. Probable not a GCode file. Try to load it " "from File menu.\n" @@ -1375,123 +1350,103 @@ msgstr "" " Attempting to create a FlatCAM CNCJob Object from G-Code file failed during " "processing" -#: FlatCAMApp.py:11104 +#: FlatCAMApp.py:11477 msgid "Object is not HPGL2 file or empty. Aborting object creation." msgstr "Object is not HPGL2 file or empty. Aborting object creation." -#: FlatCAMApp.py:11109 +#: FlatCAMApp.py:11482 msgid "Opening HPGL2" msgstr "Opening HPGL2" -#: FlatCAMApp.py:11116 +#: FlatCAMApp.py:11489 msgid " Open HPGL2 failed. Probable not a HPGL2 file." msgstr " Open HPGL2 failed. Probable not a HPGL2 file." -#: FlatCAMApp.py:11137 +#: FlatCAMApp.py:11509 msgid "Opening TCL Script..." msgstr "Opening TCL Script..." -#: FlatCAMApp.py:11145 +#: FlatCAMApp.py:11517 msgid "TCL script file opened in Code Editor." msgstr "TCL script file opened in Code Editor." -#: FlatCAMApp.py:11148 +#: FlatCAMApp.py:11520 msgid "Failed to open TCL Script." msgstr "Failed to open TCL Script." -#: FlatCAMApp.py:11176 +#: FlatCAMApp.py:11548 msgid "Opening FlatCAM Config file." msgstr "Opening FlatCAM Config file." -#: FlatCAMApp.py:11204 +#: FlatCAMApp.py:11576 msgid "Failed to open config file" msgstr "Failed to open config file" -#: FlatCAMApp.py:11230 +#: FlatCAMApp.py:11604 msgid "Loading Project ... Please Wait ..." msgstr "Loading Project ... Please Wait ..." -#: FlatCAMApp.py:11235 +#: FlatCAMApp.py:11609 msgid "Opening FlatCAM Project file." msgstr "Opening FlatCAM Project file." -#: FlatCAMApp.py:11245 FlatCAMApp.py:11263 +#: FlatCAMApp.py:11619 FlatCAMApp.py:11637 msgid "Failed to open project file" msgstr "Failed to open project file" -#: FlatCAMApp.py:11300 +#: FlatCAMApp.py:11674 msgid "Loading Project ... restoring" msgstr "Loading Project ... restoring" -#: FlatCAMApp.py:11310 +#: FlatCAMApp.py:11684 msgid "Project loaded from" msgstr "Project loaded from" -#: FlatCAMApp.py:11373 +#: FlatCAMApp.py:11753 msgid "Redrawing all objects" msgstr "Redrawing all objects" -#: FlatCAMApp.py:11405 -msgid "Available commands:\n" -msgstr "Available commands:\n" - -#: FlatCAMApp.py:11407 -msgid "" -"\n" -"\n" -"Type help for usage.\n" -" Example: help open_gerber" -msgstr "" -"\n" -"\n" -"Type help for usage.\n" -" Example: help open_gerber" - -#: FlatCAMApp.py:11557 -msgid "Shows list of commands." -msgstr "Shows list of commands." - -#: FlatCAMApp.py:11619 +#: FlatCAMApp.py:11842 msgid "Failed to load recent item list." msgstr "Failed to load recent item list." -#: FlatCAMApp.py:11627 +#: FlatCAMApp.py:11849 msgid "Failed to parse recent item list." msgstr "Failed to parse recent item list." -#: FlatCAMApp.py:11638 +#: FlatCAMApp.py:11859 msgid "Failed to load recent projects item list." msgstr "Failed to load recent projects item list." -#: FlatCAMApp.py:11646 +#: FlatCAMApp.py:11866 msgid "Failed to parse recent project item list." msgstr "Failed to parse recent project item list." -#: FlatCAMApp.py:11706 +#: FlatCAMApp.py:11927 msgid "Clear Recent projects" msgstr "Clear Recent projects" -#: FlatCAMApp.py:11730 +#: FlatCAMApp.py:11951 msgid "Clear Recent files" msgstr "Clear Recent files" -#: FlatCAMApp.py:11747 flatcamGUI/FlatCAMGUI.py:1276 +#: FlatCAMApp.py:11973 flatcamGUI/FlatCAMGUI.py:1348 msgid "Shortcut Key List" msgstr "Shortcut Key List" -#: FlatCAMApp.py:11821 +#: FlatCAMApp.py:12047 msgid "Selected Tab - Choose an Item from Project Tab" msgstr "Selected Tab - Choose an Item from Project Tab" -#: FlatCAMApp.py:11822 +#: FlatCAMApp.py:12048 msgid "Details" msgstr "Details" -#: FlatCAMApp.py:11824 +#: FlatCAMApp.py:12050 msgid "The normal flow when working in FlatCAM is the following:" msgstr "The normal flow when working in FlatCAM is the following:" -#: FlatCAMApp.py:11825 +#: FlatCAMApp.py:12051 msgid "" "Load/Import a Gerber, Excellon, Gcode, DXF, Raster Image or SVG file into " "FlatCAM using either the toolbars, key shortcuts or even dragging and " @@ -1501,7 +1456,7 @@ msgstr "" "FlatCAM using either the toolbars, key shortcuts or even dragging and " "dropping the files on the GUI." -#: FlatCAMApp.py:11828 +#: FlatCAMApp.py:12054 msgid "" "You can also load a FlatCAM project by double clicking on the project file, " "drag and drop of the file into the FLATCAM GUI or through the menu (or " @@ -1511,7 +1466,7 @@ msgstr "" "drag and drop of the file into the FLATCAM GUI or through the menu (or " "toolbar) actions offered within the app." -#: FlatCAMApp.py:11831 +#: FlatCAMApp.py:12057 msgid "" "Once an object is available in the Project Tab, by selecting it and then " "focusing on SELECTED TAB (more simpler is to double click the object name in " @@ -1523,7 +1478,7 @@ msgstr "" "the Project Tab, SELECTED TAB will be updated with the object properties " "according to its kind: Gerber, Excellon, Geometry or CNCJob object." -#: FlatCAMApp.py:11835 +#: FlatCAMApp.py:12061 msgid "" "If the selection of the object is done on the canvas by single click " "instead, and the SELECTED TAB is in focus, again the object properties will " @@ -1537,7 +1492,7 @@ msgstr "" "object on the canvas will bring the SELECTED TAB and populate it even if it " "was out of focus." -#: FlatCAMApp.py:11839 +#: FlatCAMApp.py:12065 msgid "" "You can change the parameters in this screen and the flow direction is like " "this:" @@ -1545,7 +1500,7 @@ msgstr "" "You can change the parameters in this screen and the flow direction is like " "this:" -#: FlatCAMApp.py:11840 +#: FlatCAMApp.py:12066 msgid "" "Gerber/Excellon Object --> Change Parameter --> Generate Geometry --> " "Geometry Object --> Add tools (change param in Selected Tab) --> Generate " @@ -1557,7 +1512,7 @@ msgstr "" "CNCJob --> CNCJob Object --> Verify GCode (through Edit CNC Code) and/or " "append/prepend to GCode (again, done in SELECTED TAB) --> Save GCode." -#: FlatCAMApp.py:11844 +#: FlatCAMApp.py:12070 msgid "" "A list of key shortcuts is available through an menu entry in Help --> " "Shortcuts List or through its own key shortcut: F3." @@ -1565,103 +1520,172 @@ msgstr "" "A list of key shortcuts is available through an menu entry in Help --> " "Shortcuts List or through its own key shortcut: F3." -#: FlatCAMApp.py:11906 +#: FlatCAMApp.py:12134 msgid "Failed checking for latest version. Could not connect." msgstr "Failed checking for latest version. Could not connect." -#: FlatCAMApp.py:11914 +#: FlatCAMApp.py:12141 msgid "Could not parse information about latest version." msgstr "Could not parse information about latest version." -#: FlatCAMApp.py:11925 +#: FlatCAMApp.py:12151 msgid "FlatCAM is up to date!" msgstr "FlatCAM is up to date!" -#: FlatCAMApp.py:11930 +#: FlatCAMApp.py:12156 msgid "Newer Version Available" msgstr "Newer Version Available" -#: FlatCAMApp.py:11931 -msgid "" -"There is a newer version of FlatCAM available for download:\n" -"\n" -msgstr "" -"There is a newer version of FlatCAM available for download:\n" -"\n" +#: FlatCAMApp.py:12158 +#| msgid "" +#| "There is a newer version of FlatCAM available for download:\n" +#| "\n" +msgid "There is a newer version of FlatCAM available for download:" +msgstr "There is a newer version of FlatCAM available for download:" -#: FlatCAMApp.py:11933 +#: FlatCAMApp.py:12162 msgid "info" msgstr "info" -#: FlatCAMApp.py:12012 +#: FlatCAMApp.py:12190 +msgid "" +"OpenGL canvas initialization failed. HW or HW configuration not supported." +"Change the graphic engine to Legacy(2D) in Edit -> Preferences -> General " +"tab.\n" +"\n" +msgstr "" +"OpenGL canvas initialization failed. HW or HW configuration not supported." +"Change the graphic engine to Legacy(2D) in Edit -> Preferences -> General " +"tab.\n" +"\n" + +#: FlatCAMApp.py:12269 msgid "All plots disabled." msgstr "All plots disabled." -#: FlatCAMApp.py:12019 +#: FlatCAMApp.py:12276 msgid "All non selected plots disabled." msgstr "All non selected plots disabled." -#: FlatCAMApp.py:12026 +#: FlatCAMApp.py:12283 msgid "All plots enabled." msgstr "All plots enabled." -#: FlatCAMApp.py:12033 +#: FlatCAMApp.py:12289 msgid "Selected plots enabled..." msgstr "Selected plots enabled..." -#: FlatCAMApp.py:12042 +#: FlatCAMApp.py:12297 msgid "Selected plots disabled..." msgstr "Selected plots disabled..." -#: FlatCAMApp.py:12061 +#: FlatCAMApp.py:12330 msgid "Enabling plots ..." msgstr "Enabling plots ..." -#: FlatCAMApp.py:12101 +#: FlatCAMApp.py:12382 msgid "Disabling plots ..." msgstr "Disabling plots ..." -#: FlatCAMApp.py:12123 +#: FlatCAMApp.py:12405 msgid "Working ..." msgstr "Working ..." -#: FlatCAMApp.py:12224 +#: FlatCAMApp.py:12460 flatcamGUI/FlatCAMGUI.py:688 +msgid "Red" +msgstr "Red" + +#: FlatCAMApp.py:12462 flatcamGUI/FlatCAMGUI.py:691 +msgid "Blue" +msgstr "Blue" + +#: FlatCAMApp.py:12465 flatcamGUI/FlatCAMGUI.py:694 +msgid "Yellow" +msgstr "Yellow" + +#: FlatCAMApp.py:12467 flatcamGUI/FlatCAMGUI.py:697 +msgid "Green" +msgstr "Green" + +#: FlatCAMApp.py:12469 flatcamGUI/FlatCAMGUI.py:700 +msgid "Purple" +msgstr "Purple" + +#: FlatCAMApp.py:12471 flatcamGUI/FlatCAMGUI.py:703 +msgid "Brown" +msgstr "Brown" + +#: FlatCAMApp.py:12473 FlatCAMApp.py:12529 flatcamGUI/FlatCAMGUI.py:706 +msgid "White" +msgstr "White" + +#: FlatCAMApp.py:12475 flatcamGUI/FlatCAMGUI.py:709 +msgid "Black" +msgstr "Black" + +#: FlatCAMApp.py:12478 flatcamGUI/FlatCAMGUI.py:714 +msgid "Custom" +msgstr "Custom" + +#: FlatCAMApp.py:12488 flatcamGUI/FlatCAMGUI.py:722 +#| msgid "Defaults" +msgid "Default" +msgstr "Default" + +#: FlatCAMApp.py:12512 flatcamGUI/FlatCAMGUI.py:719 +msgid "Opacity" +msgstr "Opacity" + +#: FlatCAMApp.py:12514 +msgid "Set alpha level ..." +msgstr "Set alpha level ..." + +#: FlatCAMApp.py:12514 flatcamGUI/PreferencesUI.py:6900 +#: flatcamGUI/PreferencesUI.py:8230 flatcamGUI/PreferencesUI.py:8444 +#: flatcamTools/ToolExtractDrills.py:164 flatcamTools/ToolExtractDrills.py:285 +#: flatcamTools/ToolPunchGerber.py:192 flatcamTools/ToolPunchGerber.py:308 +#: flatcamTools/ToolTransform.py:358 +#| msgid "Value X:" +msgid "Value" +msgstr "Value" + +#: FlatCAMApp.py:12590 msgid "Saving FlatCAM Project" msgstr "Saving FlatCAM Project" -#: FlatCAMApp.py:12243 FlatCAMApp.py:12280 +#: FlatCAMApp.py:12611 FlatCAMApp.py:12647 msgid "Project saved to" msgstr "Project saved to" -#: FlatCAMApp.py:12250 +#: FlatCAMApp.py:12618 msgid "The object is used by another application." msgstr "The object is used by another application." -#: FlatCAMApp.py:12264 +#: FlatCAMApp.py:12632 msgid "Failed to verify project file" msgstr "Failed to verify project file" -#: FlatCAMApp.py:12264 FlatCAMApp.py:12272 FlatCAMApp.py:12283 +#: FlatCAMApp.py:12632 FlatCAMApp.py:12640 FlatCAMApp.py:12650 msgid "Retry to save it." msgstr "Retry to save it." -#: FlatCAMApp.py:12272 FlatCAMApp.py:12283 +#: FlatCAMApp.py:12640 FlatCAMApp.py:12650 msgid "Failed to parse saved project file" msgstr "Failed to parse saved project file" -#: FlatCAMApp.py:12398 +#: FlatCAMApp.py:13132 msgid "The user requested a graceful exit of the current task." msgstr "The user requested a graceful exit of the current task." -#: FlatCAMCommon.py:136 FlatCAMCommon.py:163 +#: FlatCAMCommon.py:137 FlatCAMCommon.py:164 msgid "Title" msgstr "Title" -#: FlatCAMCommon.py:137 FlatCAMCommon.py:167 +#: FlatCAMCommon.py:138 FlatCAMCommon.py:168 msgid "Web Link" msgstr "Web Link" -#: FlatCAMCommon.py:141 +#: FlatCAMCommon.py:142 msgid "" "Index.\n" "The rows in gray color will populate the Bookmarks menu.\n" @@ -1671,7 +1695,7 @@ msgstr "" "The rows in gray color will populate the Bookmarks menu.\n" "The number of gray colored rows is set in Preferences." -#: FlatCAMCommon.py:145 +#: FlatCAMCommon.py:146 msgid "" "Description of the link that is set as an menu action.\n" "Try to keep it short because it is installed as a menu item." @@ -1679,95 +1703,87 @@ msgstr "" "Description of the link that is set as an menu action.\n" "Try to keep it short because it is installed as a menu item." -#: FlatCAMCommon.py:148 +#: FlatCAMCommon.py:149 msgid "Web Link. E.g: https://your_website.org " msgstr "Web Link. E.g: https://your_website.org " -#: FlatCAMCommon.py:157 +#: FlatCAMCommon.py:158 msgid "New Bookmark" msgstr "New Bookmark" -#: FlatCAMCommon.py:176 +#: FlatCAMCommon.py:177 msgid "Add Entry" msgstr "Add Entry" -#: FlatCAMCommon.py:177 +#: FlatCAMCommon.py:178 msgid "Remove Entry" msgstr "Remove Entry" -#: FlatCAMCommon.py:178 +#: FlatCAMCommon.py:179 msgid "Export List" msgstr "Export List" -#: FlatCAMCommon.py:179 +#: FlatCAMCommon.py:180 msgid "Import List" msgstr "Import List" -#: FlatCAMCommon.py:260 +#: FlatCAMCommon.py:261 msgid "Title entry is empty." msgstr "Title entry is empty." -#: FlatCAMCommon.py:269 +#: FlatCAMCommon.py:270 msgid "Web link entry is empty." msgstr "Web link entry is empty." -#: FlatCAMCommon.py:277 +#: FlatCAMCommon.py:278 msgid "Either the Title or the Weblink already in the table." msgstr "Either the Title or the Weblink already in the table." -#: FlatCAMCommon.py:297 +#: FlatCAMCommon.py:298 msgid "Bookmark added." msgstr "Bookmark added." -#: FlatCAMCommon.py:314 +#: FlatCAMCommon.py:315 msgid "This bookmark can not be removed" msgstr "This bookmark can not be removed" -#: FlatCAMCommon.py:345 +#: FlatCAMCommon.py:346 msgid "Bookmark removed." msgstr "Bookmark removed." -#: FlatCAMCommon.py:360 +#: FlatCAMCommon.py:361 msgid "Export FlatCAM Bookmarks" msgstr "Export FlatCAM Bookmarks" -#: FlatCAMCommon.py:363 flatcamGUI/FlatCAMGUI.py:470 +#: FlatCAMCommon.py:364 flatcamGUI/FlatCAMGUI.py:509 msgid "Bookmarks" msgstr "Bookmarks" -#: FlatCAMCommon.py:370 -msgid "FlatCAM bookmarks export cancelled." -msgstr "FlatCAM bookmarks export cancelled." - -#: FlatCAMCommon.py:389 FlatCAMCommon.py:419 +#: FlatCAMCommon.py:390 FlatCAMCommon.py:420 msgid "Could not load bookmarks file." msgstr "Could not load bookmarks file." -#: FlatCAMCommon.py:399 +#: FlatCAMCommon.py:400 msgid "Failed to write bookmarks to file." msgstr "Failed to write bookmarks to file." -#: FlatCAMCommon.py:401 +#: FlatCAMCommon.py:402 msgid "Exported bookmarks to" msgstr "Exported bookmarks to" -#: FlatCAMCommon.py:407 +#: FlatCAMCommon.py:408 msgid "Import FlatCAM Bookmarks" msgstr "Import FlatCAM Bookmarks" -#: FlatCAMCommon.py:412 -msgid "FlatCAM bookmarks import cancelled." -msgstr "FlatCAM bookmarks import cancelled." - -#: FlatCAMCommon.py:426 +#: FlatCAMCommon.py:427 msgid "Imported Bookmarks from" msgstr "Imported Bookmarks from" -#: FlatCAMCommon.py:529 +#: FlatCAMCommon.py:530 msgid "Add Geometry Tool in DB" msgstr "Add Geometry Tool in DB" -#: FlatCAMCommon.py:531 +#: FlatCAMCommon.py:532 FlatCAMCommon.py:2087 msgid "" "Add a new tool in the Tools Database.\n" "It will be used in the Geometry UI.\n" @@ -1777,35 +1793,35 @@ msgstr "" "It will be used in the Geometry UI.\n" "You can edit it after it is added." -#: FlatCAMCommon.py:545 +#: FlatCAMCommon.py:546 FlatCAMCommon.py:2101 msgid "Delete Tool from DB" msgstr "Delete Tool from DB" -#: FlatCAMCommon.py:547 +#: FlatCAMCommon.py:548 FlatCAMCommon.py:2103 msgid "Remove a selection of tools in the Tools Database." msgstr "Remove a selection of tools in the Tools Database." -#: FlatCAMCommon.py:551 +#: FlatCAMCommon.py:552 FlatCAMCommon.py:2107 msgid "Export DB" msgstr "Export DB" -#: FlatCAMCommon.py:553 +#: FlatCAMCommon.py:554 FlatCAMCommon.py:2109 msgid "Save the Tools Database to a custom text file." msgstr "Save the Tools Database to a custom text file." -#: FlatCAMCommon.py:557 +#: FlatCAMCommon.py:558 FlatCAMCommon.py:2113 msgid "Import DB" msgstr "Import DB" -#: FlatCAMCommon.py:559 +#: FlatCAMCommon.py:560 FlatCAMCommon.py:2115 msgid "Load the Tools Database information's from a custom text file." msgstr "Load the Tools Database information's from a custom text file." -#: FlatCAMCommon.py:563 +#: FlatCAMCommon.py:564 FlatCAMCommon.py:2119 msgid "Add Tool from Tools DB" msgstr "Add Tool from Tools DB" -#: FlatCAMCommon.py:565 +#: FlatCAMCommon.py:566 FlatCAMCommon.py:2121 msgid "" "Add a new tool in the Tools Table of the\n" "active Geometry object after selecting a tool\n" @@ -1815,135 +1831,144 @@ msgstr "" "active Geometry object after selecting a tool\n" "in the Tools Database." -#: FlatCAMCommon.py:601 FlatCAMCommon.py:1276 +#: FlatCAMCommon.py:602 FlatCAMCommon.py:1277 FlatCAMCommon.py:1531 msgid "Tool Name" msgstr "Tool Name" -#: FlatCAMCommon.py:602 FlatCAMCommon.py:1278 -#: flatcamEditors/FlatCAMExcEditor.py:1602 flatcamGUI/ObjectUI.py:1295 -#: flatcamTools/ToolNonCopperClear.py:271 flatcamTools/ToolPaint.py:176 +#: FlatCAMCommon.py:603 FlatCAMCommon.py:1279 FlatCAMCommon.py:1544 +#: flatcamEditors/FlatCAMExcEditor.py:1605 flatcamGUI/ObjectUI.py:1343 +#: flatcamGUI/ObjectUI.py:1581 flatcamGUI/PreferencesUI.py:5971 +#: flatcamTools/ToolNCC.py:278 flatcamTools/ToolNCC.py:287 +#: flatcamTools/ToolPaint.py:261 msgid "Tool Dia" msgstr "Tool Dia" -#: FlatCAMCommon.py:603 FlatCAMCommon.py:1280 flatcamGUI/ObjectUI.py:1278 +#: FlatCAMCommon.py:604 FlatCAMCommon.py:1281 FlatCAMCommon.py:1725 +#: flatcamGUI/ObjectUI.py:1556 msgid "Tool Offset" msgstr "Tool Offset" -#: FlatCAMCommon.py:604 FlatCAMCommon.py:1282 +#: FlatCAMCommon.py:605 FlatCAMCommon.py:1283 FlatCAMCommon.py:1742 msgid "Custom Offset" msgstr "Custom Offset" -#: FlatCAMCommon.py:605 FlatCAMCommon.py:1284 flatcamGUI/ObjectUI.py:304 -#: flatcamGUI/PreferencesUI.py:2217 flatcamGUI/PreferencesUI.py:5036 -#: flatcamTools/ToolNonCopperClear.py:213 +#: FlatCAMCommon.py:606 FlatCAMCommon.py:1285 FlatCAMCommon.py:1709 +#: flatcamGUI/ObjectUI.py:308 flatcamGUI/PreferencesUI.py:2397 +#: flatcamGUI/PreferencesUI.py:5332 flatcamGUI/PreferencesUI.py:5901 +#: flatcamGUI/PreferencesUI.py:5911 flatcamTools/ToolNCC.py:213 +#: flatcamTools/ToolNCC.py:227 flatcamTools/ToolPaint.py:196 msgid "Tool Type" msgstr "Tool Type" -#: FlatCAMCommon.py:606 FlatCAMCommon.py:1286 +#: FlatCAMCommon.py:607 FlatCAMCommon.py:1287 FlatCAMCommon.py:1557 msgid "Tool Shape" msgstr "Tool Shape" -#: FlatCAMCommon.py:607 FlatCAMCommon.py:1289 flatcamGUI/ObjectUI.py:345 -#: flatcamGUI/ObjectUI.py:820 flatcamGUI/ObjectUI.py:1405 -#: flatcamGUI/ObjectUI.py:1926 flatcamGUI/PreferencesUI.py:2257 -#: flatcamGUI/PreferencesUI.py:3082 flatcamGUI/PreferencesUI.py:3961 -#: flatcamGUI/PreferencesUI.py:5081 flatcamGUI/PreferencesUI.py:5327 -#: flatcamGUI/PreferencesUI.py:6145 flatcamTools/ToolCalculators.py:114 -#: flatcamTools/ToolCutOut.py:132 flatcamTools/ToolNonCopperClear.py:254 +#: FlatCAMCommon.py:608 FlatCAMCommon.py:1290 FlatCAMCommon.py:1573 +#: flatcamGUI/ObjectUI.py:349 flatcamGUI/ObjectUI.py:899 +#: flatcamGUI/ObjectUI.py:1701 flatcamGUI/ObjectUI.py:2254 +#: flatcamGUI/PreferencesUI.py:2437 flatcamGUI/PreferencesUI.py:3311 +#: flatcamGUI/PreferencesUI.py:4241 flatcamGUI/PreferencesUI.py:5377 +#: flatcamGUI/PreferencesUI.py:5666 flatcamGUI/PreferencesUI.py:5944 +#: flatcamGUI/PreferencesUI.py:5952 flatcamGUI/PreferencesUI.py:6635 +#: flatcamTools/ToolCalculators.py:114 flatcamTools/ToolCutOut.py:139 +#: flatcamTools/ToolNCC.py:260 flatcamTools/ToolNCC.py:268 +#: flatcamTools/ToolPaint.py:243 msgid "Cut Z" msgstr "Cut Z" -#: FlatCAMCommon.py:608 FlatCAMCommon.py:1291 +#: FlatCAMCommon.py:609 FlatCAMCommon.py:1292 FlatCAMCommon.py:1587 msgid "MultiDepth" msgstr "MultiDepth" -#: FlatCAMCommon.py:609 FlatCAMCommon.py:1293 +#: FlatCAMCommon.py:610 FlatCAMCommon.py:1294 FlatCAMCommon.py:1600 msgid "DPP" msgstr "DPP" -#: FlatCAMCommon.py:610 FlatCAMCommon.py:1295 +#: FlatCAMCommon.py:611 FlatCAMCommon.py:1296 FlatCAMCommon.py:1756 msgid "V-Dia" msgstr "V-Dia" -#: FlatCAMCommon.py:611 FlatCAMCommon.py:1297 +#: FlatCAMCommon.py:612 FlatCAMCommon.py:1298 FlatCAMCommon.py:1770 msgid "V-Angle" msgstr "V-Angle" -#: FlatCAMCommon.py:612 FlatCAMCommon.py:1299 flatcamGUI/ObjectUI.py:839 -#: flatcamGUI/ObjectUI.py:1452 flatcamGUI/PreferencesUI.py:3100 -#: flatcamGUI/PreferencesUI.py:4014 flatcamGUI/PreferencesUI.py:7535 +#: FlatCAMCommon.py:613 FlatCAMCommon.py:1300 FlatCAMCommon.py:1614 +#: FlatCAMObj.py:3661 FlatCAMObj.py:5486 flatcamGUI/ObjectUI.py:945 +#: flatcamGUI/ObjectUI.py:1748 flatcamGUI/PreferencesUI.py:3352 +#: flatcamGUI/PreferencesUI.py:4294 flatcamGUI/PreferencesUI.py:8041 #: flatcamTools/ToolCalibration.py:74 msgid "Travel Z" msgstr "Travel Z" -#: FlatCAMCommon.py:613 FlatCAMCommon.py:1301 +#: FlatCAMCommon.py:614 FlatCAMCommon.py:1302 msgid "FR" msgstr "FR" -#: FlatCAMCommon.py:614 FlatCAMCommon.py:1303 +#: FlatCAMCommon.py:615 FlatCAMCommon.py:1304 msgid "FR Z" msgstr "FR Z" -#: FlatCAMCommon.py:615 FlatCAMCommon.py:1305 +#: FlatCAMCommon.py:616 FlatCAMCommon.py:1306 FlatCAMCommon.py:1784 msgid "FR Rapids" msgstr "FR Rapids" -#: FlatCAMCommon.py:616 FlatCAMCommon.py:1307 flatcamGUI/PreferencesUI.py:3173 +#: FlatCAMCommon.py:617 FlatCAMCommon.py:1308 FlatCAMCommon.py:1657 +#: flatcamGUI/PreferencesUI.py:3440 msgid "Spindle Speed" msgstr "Spindle Speed" -#: FlatCAMCommon.py:617 FlatCAMCommon.py:1309 flatcamGUI/ObjectUI.py:963 -#: flatcamGUI/ObjectUI.py:1619 +#: FlatCAMCommon.py:618 FlatCAMCommon.py:1310 FlatCAMCommon.py:1672 +#: flatcamGUI/ObjectUI.py:1063 flatcamGUI/ObjectUI.py:1855 msgid "Dwell" msgstr "Dwell" -#: FlatCAMCommon.py:618 FlatCAMCommon.py:1311 +#: FlatCAMCommon.py:619 FlatCAMCommon.py:1312 FlatCAMCommon.py:1685 msgid "Dwelltime" msgstr "Dwelltime" -#: FlatCAMCommon.py:619 FlatCAMCommon.py:1313 flatcamGUI/ObjectUI.py:982 -#: flatcamGUI/ObjectUI.py:1640 flatcamGUI/PreferencesUI.py:3204 -#: flatcamGUI/PreferencesUI.py:4155 flatcamGUI/PreferencesUI.py:6642 -#: flatcamTools/ToolSolderPaste.py:334 +#: FlatCAMCommon.py:620 FlatCAMCommon.py:1314 flatcamGUI/ObjectUI.py:2012 +#: flatcamGUI/PreferencesUI.py:3475 flatcamGUI/PreferencesUI.py:4447 +#: flatcamGUI/PreferencesUI.py:7148 flatcamTools/ToolSolderPaste.py:336 msgid "Preprocessor" msgstr "Preprocessor" -#: FlatCAMCommon.py:620 FlatCAMCommon.py:1315 +#: FlatCAMCommon.py:621 FlatCAMCommon.py:1316 FlatCAMCommon.py:1800 msgid "ExtraCut" msgstr "ExtraCut" -#: FlatCAMCommon.py:621 FlatCAMCommon.py:1317 +#: FlatCAMCommon.py:622 FlatCAMCommon.py:1318 FlatCAMCommon.py:1815 msgid "E-Cut Length" msgstr "E-Cut Length" -#: FlatCAMCommon.py:622 FlatCAMCommon.py:1319 +#: FlatCAMCommon.py:623 FlatCAMCommon.py:1320 msgid "Toolchange" msgstr "Toolchange" -#: FlatCAMCommon.py:623 FlatCAMCommon.py:1321 +#: FlatCAMCommon.py:624 FlatCAMCommon.py:1322 msgid "Toolchange XY" msgstr "Toolchange XY" -#: FlatCAMCommon.py:624 FlatCAMCommon.py:1323 flatcamGUI/PreferencesUI.py:3124 -#: flatcamGUI/PreferencesUI.py:4044 flatcamGUI/PreferencesUI.py:7572 +#: FlatCAMCommon.py:625 FlatCAMCommon.py:1324 flatcamGUI/PreferencesUI.py:3378 +#: flatcamGUI/PreferencesUI.py:4324 flatcamGUI/PreferencesUI.py:8078 #: flatcamTools/ToolCalibration.py:111 msgid "Toolchange Z" msgstr "Toolchange Z" -#: FlatCAMCommon.py:625 FlatCAMCommon.py:1325 flatcamGUI/ObjectUI.py:886 -#: flatcamGUI/PreferencesUI.py:3309 flatcamGUI/PreferencesUI.py:4200 +#: FlatCAMCommon.py:626 FlatCAMCommon.py:1326 flatcamGUI/ObjectUI.py:1192 +#: flatcamGUI/PreferencesUI.py:3586 flatcamGUI/PreferencesUI.py:4493 msgid "Start Z" msgstr "Start Z" -#: FlatCAMCommon.py:626 FlatCAMCommon.py:1328 +#: FlatCAMCommon.py:627 FlatCAMCommon.py:1329 msgid "End Z" msgstr "End Z" -#: FlatCAMCommon.py:630 +#: FlatCAMCommon.py:631 msgid "Tool Index." msgstr "Tool Index." -#: FlatCAMCommon.py:632 +#: FlatCAMCommon.py:633 FlatCAMCommon.py:1533 msgid "" "Tool name.\n" "This is not used in the app, it's function\n" @@ -1953,11 +1978,11 @@ msgstr "" "This is not used in the app, it's function\n" "is to serve as a note for the user." -#: FlatCAMCommon.py:636 +#: FlatCAMCommon.py:637 FlatCAMCommon.py:1546 msgid "Tool Diameter." msgstr "Tool Diameter." -#: FlatCAMCommon.py:638 +#: FlatCAMCommon.py:639 FlatCAMCommon.py:1727 msgid "" "Tool Offset.\n" "Can be of a few types:\n" @@ -1973,7 +1998,7 @@ msgstr "" "Out = offset outside by half of tool diameter\n" "Custom = custom offset using the Custom Offset value" -#: FlatCAMCommon.py:645 +#: FlatCAMCommon.py:646 FlatCAMCommon.py:1744 msgid "" "Custom Offset.\n" "A value to be used as offset from the current path." @@ -1981,7 +2006,7 @@ msgstr "" "Custom Offset.\n" "A value to be used as offset from the current path." -#: FlatCAMCommon.py:648 +#: FlatCAMCommon.py:649 FlatCAMCommon.py:1711 msgid "" "Tool Type.\n" "Can be:\n" @@ -1995,7 +2020,7 @@ msgstr "" "Rough = rough cut, low feedrate, multiple passes\n" "Finish = finishing cut, high feedrate" -#: FlatCAMCommon.py:654 +#: FlatCAMCommon.py:655 FlatCAMCommon.py:1559 msgid "" "Tool Shape. \n" "Can be:\n" @@ -2009,7 +2034,7 @@ msgstr "" "B = ball tip milling tool\n" "V = v-shape milling tool" -#: FlatCAMCommon.py:660 +#: FlatCAMCommon.py:661 FlatCAMCommon.py:1575 msgid "" "Cutting Depth.\n" "The depth at which to cut into material." @@ -2017,7 +2042,7 @@ msgstr "" "Cutting Depth.\n" "The depth at which to cut into material." -#: FlatCAMCommon.py:663 +#: FlatCAMCommon.py:664 FlatCAMCommon.py:1589 msgid "" "Multi Depth.\n" "Selecting this will allow cutting in multiple passes,\n" @@ -2027,7 +2052,7 @@ msgstr "" "Selecting this will allow cutting in multiple passes,\n" "each pass adding a DPP parameter depth." -#: FlatCAMCommon.py:667 +#: FlatCAMCommon.py:668 FlatCAMCommon.py:1602 msgid "" "DPP. Depth per Pass.\n" "The value used to cut into material on each pass." @@ -2035,7 +2060,7 @@ msgstr "" "DPP. Depth per Pass.\n" "The value used to cut into material on each pass." -#: FlatCAMCommon.py:670 +#: FlatCAMCommon.py:671 FlatCAMCommon.py:1758 msgid "" "V-Dia.\n" "Diameter of the tip for V-Shape Tools." @@ -2043,7 +2068,7 @@ msgstr "" "V-Dia.\n" "Diameter of the tip for V-Shape Tools." -#: FlatCAMCommon.py:673 +#: FlatCAMCommon.py:674 FlatCAMCommon.py:1772 msgid "" "V-Agle.\n" "Angle at the tip for the V-Shape Tools." @@ -2051,7 +2076,7 @@ msgstr "" "V-Agle.\n" "Angle at the tip for the V-Shape Tools." -#: FlatCAMCommon.py:676 +#: FlatCAMCommon.py:677 FlatCAMCommon.py:1616 msgid "" "Clearance Height.\n" "Height at which the milling bit will travel between cuts,\n" @@ -2061,7 +2086,7 @@ msgstr "" "Height at which the milling bit will travel between cuts,\n" "above the surface of the material, avoiding all fixtures." -#: FlatCAMCommon.py:680 +#: FlatCAMCommon.py:681 msgid "" "FR. Feedrate\n" "The speed on XY plane used while cutting into material." @@ -2069,7 +2094,7 @@ msgstr "" "FR. Feedrate\n" "The speed on XY plane used while cutting into material." -#: FlatCAMCommon.py:683 +#: FlatCAMCommon.py:684 msgid "" "FR Z. Feedrate Z\n" "The speed on Z plane." @@ -2077,7 +2102,7 @@ msgstr "" "FR Z. Feedrate Z\n" "The speed on Z plane." -#: FlatCAMCommon.py:686 +#: FlatCAMCommon.py:687 FlatCAMCommon.py:1786 msgid "" "FR Rapids. Feedrate Rapids\n" "Speed used while moving as fast as possible.\n" @@ -2089,7 +2114,7 @@ msgstr "" "This is used only by some devices that can't use\n" "the G0 g-code command. Mostly 3D printers." -#: FlatCAMCommon.py:691 +#: FlatCAMCommon.py:692 FlatCAMCommon.py:1659 msgid "" "Spindle Speed.\n" "If it's left empty it will not be used.\n" @@ -2099,7 +2124,7 @@ msgstr "" "If it's left empty it will not be used.\n" "The speed of the spindle in RPM." -#: FlatCAMCommon.py:695 +#: FlatCAMCommon.py:696 FlatCAMCommon.py:1674 msgid "" "Dwell.\n" "Check this if a delay is needed to allow\n" @@ -2109,7 +2134,7 @@ msgstr "" "Check this if a delay is needed to allow\n" "the spindle motor to reach it's set speed." -#: FlatCAMCommon.py:699 +#: FlatCAMCommon.py:700 FlatCAMCommon.py:1687 msgid "" "Dwell Time.\n" "A delay used to allow the motor spindle reach it's set speed." @@ -2117,7 +2142,7 @@ msgstr "" "Dwell Time.\n" "A delay used to allow the motor spindle reach it's set speed." -#: FlatCAMCommon.py:702 +#: FlatCAMCommon.py:703 msgid "" "Preprocessor.\n" "A selection of files that will alter the generated G-code\n" @@ -2127,7 +2152,7 @@ msgstr "" "A selection of files that will alter the generated G-code\n" "to fit for a number of use cases." -#: FlatCAMCommon.py:706 +#: FlatCAMCommon.py:707 FlatCAMCommon.py:1802 msgid "" "Extra Cut.\n" "If checked, after a isolation is finished an extra cut\n" @@ -2141,7 +2166,7 @@ msgstr "" "such as that this point is covered by this extra cut to\n" "ensure a complete isolation." -#: FlatCAMCommon.py:712 +#: FlatCAMCommon.py:713 FlatCAMCommon.py:1817 msgid "" "Extra Cut length.\n" "If checked, after a isolation is finished an extra cut\n" @@ -2157,7 +2182,7 @@ msgstr "" "ensure a complete isolation. This is the length of\n" "the extra cut." -#: FlatCAMCommon.py:719 +#: FlatCAMCommon.py:720 msgid "" "Toolchange.\n" "It will create a toolchange event.\n" @@ -2169,7 +2194,7 @@ msgstr "" "The kind of toolchange is determined by\n" "the preprocessor file." -#: FlatCAMCommon.py:724 +#: FlatCAMCommon.py:725 msgid "" "Toolchange XY.\n" "A set of coordinates in the format (x, y).\n" @@ -2181,7 +2206,7 @@ msgstr "" "Will determine the cartesian position of the point\n" "where the tool change event take place." -#: FlatCAMCommon.py:729 +#: FlatCAMCommon.py:730 msgid "" "Toolchange Z.\n" "The position on Z plane where the tool change event take place." @@ -2189,7 +2214,7 @@ msgstr "" "Toolchange Z.\n" "The position on Z plane where the tool change event take place." -#: FlatCAMCommon.py:732 +#: FlatCAMCommon.py:733 msgid "" "Start Z.\n" "If it's left empty it will not be used.\n" @@ -2199,7 +2224,7 @@ msgstr "" "If it's left empty it will not be used.\n" "A position on Z plane to move immediately after job start." -#: FlatCAMCommon.py:736 +#: FlatCAMCommon.py:737 msgid "" "End Z.\n" "A position on Z plane to move immediately after job stop." @@ -2207,345 +2232,760 @@ msgstr "" "End Z.\n" "A position on Z plane to move immediately after job stop." -#: FlatCAMCommon.py:748 FlatCAMCommon.py:1125 FlatCAMCommon.py:1159 +#: FlatCAMCommon.py:749 FlatCAMCommon.py:1126 FlatCAMCommon.py:1160 +#: FlatCAMCommon.py:2335 FlatCAMCommon.py:2556 FlatCAMCommon.py:2590 msgid "Could not load Tools DB file." msgstr "Could not load Tools DB file." -#: FlatCAMCommon.py:756 FlatCAMCommon.py:1167 +#: FlatCAMCommon.py:757 FlatCAMCommon.py:1168 FlatCAMCommon.py:2343 +#: FlatCAMCommon.py:2598 msgid "Failed to parse Tools DB file." msgstr "Failed to parse Tools DB file." -#: FlatCAMCommon.py:759 FlatCAMCommon.py:1170 +#: FlatCAMCommon.py:760 FlatCAMCommon.py:1171 FlatCAMCommon.py:2346 +#: FlatCAMCommon.py:2601 msgid "Loaded FlatCAM Tools DB from" msgstr "Loaded FlatCAM Tools DB from" -#: FlatCAMCommon.py:765 +#: FlatCAMCommon.py:766 FlatCAMCommon.py:2260 msgid "Add to DB" msgstr "Add to DB" -#: FlatCAMCommon.py:767 +#: FlatCAMCommon.py:768 FlatCAMCommon.py:2263 msgid "Copy from DB" msgstr "Copy from DB" -#: FlatCAMCommon.py:769 +#: FlatCAMCommon.py:770 FlatCAMCommon.py:2266 msgid "Delete from DB" msgstr "Delete from DB" -#: FlatCAMCommon.py:1046 +#: FlatCAMCommon.py:1047 FlatCAMCommon.py:2473 msgid "Tool added to DB." msgstr "Tool added to DB." -#: FlatCAMCommon.py:1067 +#: FlatCAMCommon.py:1068 FlatCAMCommon.py:2497 msgid "Tool copied from Tools DB." msgstr "Tool copied from Tools DB." -#: FlatCAMCommon.py:1085 +#: FlatCAMCommon.py:1086 FlatCAMCommon.py:2516 msgid "Tool removed from Tools DB." msgstr "Tool removed from Tools DB." -#: FlatCAMCommon.py:1096 +#: FlatCAMCommon.py:1097 FlatCAMCommon.py:2527 msgid "Export Tools Database" msgstr "Export Tools Database" -#: FlatCAMCommon.py:1099 +#: FlatCAMCommon.py:1100 FlatCAMCommon.py:2530 msgid "Tools_Database" msgstr "Tools_Database" -#: FlatCAMCommon.py:1106 -msgid "FlatCAM Tools DB export cancelled." -msgstr "FlatCAM Tools DB export cancelled." - -#: FlatCAMCommon.py:1136 FlatCAMCommon.py:1139 FlatCAMCommon.py:1191 +#: FlatCAMCommon.py:1137 FlatCAMCommon.py:1140 FlatCAMCommon.py:1192 +#: FlatCAMCommon.py:2567 FlatCAMCommon.py:2570 FlatCAMCommon.py:2622 msgid "Failed to write Tools DB to file." msgstr "Failed to write Tools DB to file." -#: FlatCAMCommon.py:1142 +#: FlatCAMCommon.py:1143 FlatCAMCommon.py:2573 msgid "Exported Tools DB to" msgstr "Exported Tools DB to" -#: FlatCAMCommon.py:1149 +#: FlatCAMCommon.py:1150 FlatCAMCommon.py:2580 msgid "Import FlatCAM Tools DB" msgstr "Import FlatCAM Tools DB" -#: FlatCAMCommon.py:1152 -msgid "FlatCAM Tools DB import cancelled." -msgstr "FlatCAM Tools DB import cancelled." - -#: FlatCAMCommon.py:1195 +#: FlatCAMCommon.py:1196 FlatCAMCommon.py:2626 msgid "Saved Tools DB." msgstr "Saved Tools DB." -#: FlatCAMCommon.py:1342 +#: FlatCAMCommon.py:1343 FlatCAMCommon.py:2807 msgid "No Tool/row selected in the Tools Database table" msgstr "No Tool/row selected in the Tools Database table" -#: FlatCAMCommon.py:1360 +#: FlatCAMCommon.py:1361 FlatCAMCommon.py:2824 msgid "Cancelled adding tool from DB." msgstr "Cancelled adding tool from DB." -#: FlatCAMObj.py:257 +#: FlatCAMCommon.py:1462 +#| msgid "GCode Parameters" +msgid "Basic Geo Parameters" +msgstr "Basic Geo Parameters" + +#: FlatCAMCommon.py:1474 +#| msgid "Advanced Param." +msgid "Advanced Geo Parameters" +msgstr "Advanced Geo Parameters" + +#: FlatCAMCommon.py:1486 +#| msgid "Parameters" +msgid "NCC Parameters" +msgstr "NCC Parameters" + +#: FlatCAMCommon.py:1498 +#| msgid "Slot Parameters" +msgid "Paint Parameters" +msgstr "Paint Parameters" + +#: FlatCAMCommon.py:1629 flatcamGUI/ObjectUI.py:966 flatcamGUI/ObjectUI.py:1767 +#: flatcamGUI/PreferencesUI.py:4378 flatcamGUI/PreferencesUI.py:7059 +#: flatcamTools/ToolSolderPaste.py:254 +msgid "Feedrate X-Y" +msgstr "Feedrate X-Y" + +#: FlatCAMCommon.py:1631 +#| msgid "" +#| "FR. Feedrate\n" +#| "The speed on XY plane used while cutting into material." +msgid "" +"Feedrate X-Y. Feedrate\n" +"The speed on XY plane used while cutting into material." +msgstr "" +"Feedrate X-Y. Feedrate\n" +"The speed on XY plane used while cutting into material." + +#: FlatCAMCommon.py:1643 flatcamGUI/ObjectUI.py:981 flatcamGUI/ObjectUI.py:1781 +#: flatcamGUI/PreferencesUI.py:3425 flatcamGUI/PreferencesUI.py:4393 +#: flatcamGUI/PreferencesUI.py:7072 flatcamTools/ToolSolderPaste.py:266 +msgid "Feedrate Z" +msgstr "Feedrate Z" + +#: FlatCAMCommon.py:1645 +#| msgid "" +#| "FR Z. Feedrate Z\n" +#| "The speed on Z plane." +msgid "" +"Feedrate Z\n" +"The speed on Z plane." +msgstr "" +"Feedrate Z\n" +"The speed on Z plane." + +#: FlatCAMCommon.py:1843 flatcamGUI/ObjectUI.py:844 +#: flatcamGUI/PreferencesUI.py:3264 flatcamTools/ToolNCC.py:341 +msgid "Operation" +msgstr "Operation" + +#: FlatCAMCommon.py:1845 flatcamTools/ToolNCC.py:343 +msgid "" +"The 'Operation' can be:\n" +"- Isolation -> will ensure that the non-copper clearing is always complete.\n" +"If it's not successful then the non-copper clearing will fail, too.\n" +"- Clear -> the regular non-copper clearing." +msgstr "" +"The 'Operation' can be:\n" +"- Isolation -> will ensure that the non-copper clearing is always complete.\n" +"If it's not successful then the non-copper clearing will fail, too.\n" +"- Clear -> the regular non-copper clearing." + +#: FlatCAMCommon.py:1852 flatcamEditors/FlatCAMGrbEditor.py:2739 +#: flatcamGUI/GUIElements.py:2577 flatcamTools/ToolNCC.py:350 +msgid "Clear" +msgstr "Clear" + +#: FlatCAMCommon.py:1853 flatcamTools/ToolNCC.py:351 +#: flatcamTools/ToolNCC.py:1627 +#| msgid "Isolation Type" +msgid "Isolation" +msgstr "Isolation" + +#: FlatCAMCommon.py:1861 flatcamGUI/ObjectUI.py:408 flatcamGUI/ObjectUI.py:866 +#: flatcamGUI/PreferencesUI.py:2257 flatcamGUI/PreferencesUI.py:3280 +#: flatcamGUI/PreferencesUI.py:4665 flatcamGUI/PreferencesUI.py:5416 +#: flatcamTools/ToolNCC.py:359 +msgid "Milling Type" +msgstr "Milling Type" + +#: FlatCAMCommon.py:1863 FlatCAMCommon.py:1871 flatcamGUI/PreferencesUI.py:5418 +#: flatcamGUI/PreferencesUI.py:5426 flatcamTools/ToolNCC.py:361 +#: flatcamTools/ToolNCC.py:369 +msgid "" +"Milling type when the selected tool is of type: 'iso_op':\n" +"- climb / best for precision milling and to reduce tool usage\n" +"- conventional / useful when there is no backlash compensation" +msgstr "" +"Milling type when the selected tool is of type: 'iso_op':\n" +"- climb / best for precision milling and to reduce tool usage\n" +"- conventional / useful when there is no backlash compensation" + +#: FlatCAMCommon.py:1868 flatcamGUI/ObjectUI.py:414 +#: flatcamGUI/PreferencesUI.py:2264 flatcamGUI/PreferencesUI.py:4671 +#: flatcamGUI/PreferencesUI.py:5423 flatcamTools/ToolNCC.py:366 +msgid "Climb" +msgstr "Climb" + +#: FlatCAMCommon.py:1869 flatcamGUI/ObjectUI.py:415 +#: flatcamGUI/PreferencesUI.py:2265 flatcamGUI/PreferencesUI.py:4672 +#: flatcamGUI/PreferencesUI.py:5424 flatcamTools/ToolNCC.py:367 +msgid "Conventional" +msgstr "Conventional" + +#: FlatCAMCommon.py:1881 FlatCAMCommon.py:1990 +#: flatcamEditors/FlatCAMGeoEditor.py:452 flatcamGUI/PreferencesUI.py:5461 +#: flatcamGUI/PreferencesUI.py:6002 flatcamTools/ToolNCC.py:382 +#: flatcamTools/ToolPaint.py:329 +#| msgid "Overlap Rate" +msgid "Overlap" +msgstr "Overlap" + +#: FlatCAMCommon.py:1883 flatcamGUI/PreferencesUI.py:5463 +#: flatcamTools/ToolNCC.py:384 +#| msgid "" +#| "How much (fraction) of the tool width to overlap each tool pass.\n" +#| "Adjust the value starting with lower values\n" +#| "and increasing it if areas that should be cleared are still \n" +#| "not cleared.\n" +#| "Lower values = faster processing, faster execution on CNC.\n" +#| "Higher values = slow processing and slow execution on CNC\n" +#| "due of too many paths." +msgid "" +"How much (percentage) of the tool width to overlap each tool pass.\n" +"Adjust the value starting with lower values\n" +"and increasing it if areas that should be cleared are still \n" +"not cleared.\n" +"Lower values = faster processing, faster execution on CNC.\n" +"Higher values = slow processing and slow execution on CNC\n" +"due of too many paths." +msgstr "" +"How much (percentage) of the tool width to overlap each tool pass.\n" +"Adjust the value starting with lower values\n" +"and increasing it if areas that should be cleared are still \n" +"not cleared.\n" +"Lower values = faster processing, faster execution on CNC.\n" +"Higher values = slow processing and slow execution on CNC\n" +"due of too many paths." + +#: FlatCAMCommon.py:1902 FlatCAMCommon.py:2011 +#: flatcamEditors/FlatCAMGeoEditor.py:472 flatcamGUI/PreferencesUI.py:5481 +#: flatcamGUI/PreferencesUI.py:5723 flatcamGUI/PreferencesUI.py:6022 +#: flatcamGUI/PreferencesUI.py:7681 flatcamGUI/PreferencesUI.py:7838 +#: flatcamGUI/PreferencesUI.py:7923 flatcamGUI/PreferencesUI.py:8570 +#: flatcamGUI/PreferencesUI.py:8578 flatcamTools/ToolCopperThieving.py:112 +#: flatcamTools/ToolCopperThieving.py:363 flatcamTools/ToolCutOut.py:191 +#: flatcamTools/ToolFiducials.py:172 flatcamTools/ToolInvertGerber.py:88 +#: flatcamTools/ToolInvertGerber.py:96 flatcamTools/ToolNCC.py:403 +#: flatcamTools/ToolPaint.py:350 +msgid "Margin" +msgstr "Margin" + +#: FlatCAMCommon.py:1904 flatcamGUI/PreferencesUI.py:5483 +#: flatcamGUI/PreferencesUI.py:7683 flatcamGUI/PreferencesUI.py:7925 +#: flatcamGUI/PreferencesUI.py:7989 flatcamTools/ToolCopperThieving.py:114 +#: flatcamTools/ToolFiducials.py:174 flatcamTools/ToolFiducials.py:237 +#: flatcamTools/ToolNCC.py:405 +msgid "Bounding box margin." +msgstr "Bounding box margin." + +#: FlatCAMCommon.py:1915 FlatCAMCommon.py:2026 +#: flatcamEditors/FlatCAMGeoEditor.py:486 flatcamGUI/PreferencesUI.py:5494 +#: flatcamGUI/PreferencesUI.py:6037 flatcamGUI/PreferencesUI.py:8204 +#: flatcamGUI/PreferencesUI.py:8417 flatcamTools/ToolExtractDrills.py:128 +#: flatcamTools/ToolNCC.py:416 flatcamTools/ToolPaint.py:365 +#: flatcamTools/ToolPunchGerber.py:139 +msgid "Method" +msgstr "Method" + +#: FlatCAMCommon.py:1917 flatcamGUI/PreferencesUI.py:5496 +#: flatcamTools/ToolNCC.py:418 +#| msgid "" +#| "Algorithm for painting:\n" +#| "- Standard: Fixed step inwards.\n" +#| "- Seed-based: Outwards from seed.\n" +#| "- Line-based: Parallel lines." +msgid "" +"Algorithm for copper clearing:\n" +"- Standard: Fixed step inwards.\n" +"- Seed-based: Outwards from seed.\n" +"- Line-based: Parallel lines." +msgstr "" +"Algorithm for copper clearing:\n" +"- Standard: Fixed step inwards.\n" +"- Seed-based: Outwards from seed.\n" +"- Line-based: Parallel lines." + +#: FlatCAMCommon.py:1925 FlatCAMCommon.py:2040 +#: flatcamEditors/FlatCAMGeoEditor.py:500 flatcamGUI/PreferencesUI.py:5509 +#: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 +#: flatcamTools/ToolNCC.py:2395 flatcamTools/ToolNCC.py:2424 +#: flatcamTools/ToolNCC.py:2693 flatcamTools/ToolNCC.py:2725 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:1818 +#: flatcamTools/ToolPaint.py:2717 flatcamTools/ToolPaint.py:3198 +#: flatcamTools/ToolPaint.py:3538 +msgid "Standard" +msgstr "Standard" + +#: FlatCAMCommon.py:1925 FlatCAMCommon.py:2040 +#: flatcamEditors/FlatCAMGeoEditor.py:500 +#: flatcamEditors/FlatCAMGeoEditor.py:5156 flatcamGUI/PreferencesUI.py:5509 +#: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:696 +#: flatcamTools/ToolPaint.py:1846 flatcamTools/ToolPaint.py:2729 +#: flatcamTools/ToolPaint.py:3188 flatcamTools/ToolPaint.py:3550 +#| msgid "Line" +msgid "Lines" +msgstr "Lines" + +#: FlatCAMCommon.py:1933 FlatCAMCommon.py:2051 flatcamGUI/PreferencesUI.py:5516 +#: flatcamGUI/PreferencesUI.py:6063 flatcamTools/ToolNCC.py:439 +#: flatcamTools/ToolPaint.py:401 +msgid "Connect" +msgstr "Connect" + +#: FlatCAMCommon.py:1937 FlatCAMCommon.py:2054 +#: flatcamEditors/FlatCAMGeoEditor.py:509 flatcamGUI/PreferencesUI.py:5518 +#: flatcamGUI/PreferencesUI.py:6065 flatcamTools/ToolNCC.py:443 +#: flatcamTools/ToolPaint.py:404 +msgid "" +"Draw lines between resulting\n" +"segments to minimize tool lifts." +msgstr "" +"Draw lines between resulting\n" +"segments to minimize tool lifts." + +#: FlatCAMCommon.py:1943 FlatCAMCommon.py:2058 flatcamGUI/PreferencesUI.py:5525 +#: flatcamGUI/PreferencesUI.py:6071 flatcamTools/ToolNCC.py:449 +#: flatcamTools/ToolPaint.py:408 +msgid "Contour" +msgstr "Contour" + +#: FlatCAMCommon.py:1947 FlatCAMCommon.py:2061 +#: flatcamEditors/FlatCAMGeoEditor.py:519 flatcamGUI/PreferencesUI.py:5527 +#: flatcamGUI/PreferencesUI.py:6073 flatcamTools/ToolNCC.py:453 +#: flatcamTools/ToolPaint.py:411 +msgid "" +"Cut around the perimeter of the polygon\n" +"to trim rough edges." +msgstr "" +"Cut around the perimeter of the polygon\n" +"to trim rough edges." + +#: FlatCAMCommon.py:1953 flatcamEditors/FlatCAMGeoEditor.py:613 +#: flatcamEditors/FlatCAMGrbEditor.py:5145 flatcamGUI/ObjectUI.py:142 +#: flatcamGUI/ObjectUI.py:1495 flatcamGUI/ObjectUI.py:2244 +#: flatcamGUI/PreferencesUI.py:5534 flatcamGUI/PreferencesUI.py:6822 +#: flatcamTools/ToolNCC.py:459 flatcamTools/ToolTransform.py:29 +msgid "Offset" +msgstr "Offset" + +#: FlatCAMCommon.py:1957 flatcamGUI/PreferencesUI.py:5536 +#: flatcamTools/ToolNCC.py:463 +msgid "" +"If used, it will add an offset to the copper features.\n" +"The copper clearing will finish to a distance\n" +"from the copper features.\n" +"The value can be between 0 and 10 FlatCAM units." +msgstr "" +"If used, it will add an offset to the copper features.\n" +"The copper clearing will finish to a distance\n" +"from the copper features.\n" +"The value can be between 0 and 10 FlatCAM units." + +#: FlatCAMCommon.py:1992 flatcamEditors/FlatCAMGeoEditor.py:454 +#: flatcamGUI/PreferencesUI.py:6004 flatcamTools/ToolPaint.py:331 +#| msgid "" +#| "How much (fraction) of the tool width to overlap each tool pass.\n" +#| "Adjust the value starting with lower values\n" +#| "and increasing it if areas that should be painted are still \n" +#| "not painted.\n" +#| "Lower values = faster processing, faster execution on CNC.\n" +#| "Higher values = slow processing and slow execution on CNC\n" +#| "due of too many paths." +msgid "" +"How much (percentage) of the tool width to overlap each tool pass.\n" +"Adjust the value starting with lower values\n" +"and increasing it if areas that should be painted are still \n" +"not painted.\n" +"Lower values = faster processing, faster execution on CNC.\n" +"Higher values = slow processing and slow execution on CNC\n" +"due of too many paths." +msgstr "" +"How much (percentage) of the tool width to overlap each tool pass.\n" +"Adjust the value starting with lower values\n" +"and increasing it if areas that should be painted are still \n" +"not painted.\n" +"Lower values = faster processing, faster execution on CNC.\n" +"Higher values = slow processing and slow execution on CNC\n" +"due of too many paths." + +#: FlatCAMCommon.py:2013 flatcamEditors/FlatCAMGeoEditor.py:474 +#: flatcamGUI/PreferencesUI.py:6024 flatcamTools/ToolPaint.py:352 +msgid "" +"Distance by which to avoid\n" +"the edges of the polygon to\n" +"be painted." +msgstr "" +"Distance by which to avoid\n" +"the edges of the polygon to\n" +"be painted." + +#: FlatCAMCommon.py:2028 flatcamGUI/PreferencesUI.py:6039 +#: flatcamTools/ToolPaint.py:367 +msgid "" +"Algorithm for painting:\n" +"- Standard: Fixed step inwards.\n" +"- Seed-based: Outwards from seed.\n" +"- Line-based: Parallel lines.\n" +"- Laser-lines: Active only for Gerber objects.\n" +"Will create lines that follow the traces.\n" +"- Combo: In case of failure a new method will be picked from the above\n" +"in the order specified." +msgstr "" +"Algorithm for painting:\n" +"- Standard: Fixed step inwards.\n" +"- Seed-based: Outwards from seed.\n" +"- Line-based: Parallel lines.\n" +"- Laser-lines: Active only for Gerber objects.\n" +"Will create lines that follow the traces.\n" +"- Combo: In case of failure a new method will be picked from the above\n" +"in the order specified." + +#: FlatCAMCommon.py:2040 FlatCAMCommon.py:2042 flatcamGUI/PreferencesUI.py:6056 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:392 +#: flatcamTools/ToolPaint.py:690 flatcamTools/ToolPaint.py:695 +#: flatcamTools/ToolPaint.py:1860 flatcamTools/ToolPaint.py:2735 +#: flatcamTools/ToolPaint.py:3207 flatcamTools/ToolPaint.py:3556 +#| msgid "lines" +msgid "Laser_lines" +msgstr "Laser_lines" + +#: FlatCAMCommon.py:2040 flatcamGUI/PreferencesUI.py:6056 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:2011 +#: flatcamTools/ToolPaint.py:2861 flatcamTools/ToolPaint.py:3333 +#: flatcamTools/ToolPaint.py:3682 +#| msgid "Combine" +msgid "Combo" +msgstr "Combo" + +#: FlatCAMCommon.py:2085 +#| msgid "Add Geometry Tool in DB" +msgid "Add Tool in DB" +msgstr "Add Tool in DB" + +#: FlatCAMObj.py:264 msgid "Name changed from" msgstr "Name changed from" -#: FlatCAMObj.py:257 +#: FlatCAMObj.py:264 msgid "to" msgstr "to" -#: FlatCAMObj.py:268 +#: FlatCAMObj.py:275 msgid "Offsetting..." msgstr "Offsetting..." -#: FlatCAMObj.py:282 FlatCAMObj.py:287 +#: FlatCAMObj.py:289 FlatCAMObj.py:294 msgid "Scaling could not be executed." msgstr "Scaling could not be executed." -#: FlatCAMObj.py:291 FlatCAMObj.py:299 +#: FlatCAMObj.py:298 FlatCAMObj.py:306 msgid "Scale done." msgstr "Scale done." -#: FlatCAMObj.py:297 +#: FlatCAMObj.py:304 msgid "Scaling..." msgstr "Scaling..." -#: FlatCAMObj.py:315 +#: FlatCAMObj.py:322 msgid "Skewing..." msgstr "Skewing..." -#: FlatCAMObj.py:736 FlatCAMObj.py:2746 FlatCAMObj.py:3968 -#: flatcamGUI/PreferencesUI.py:1470 flatcamGUI/PreferencesUI.py:2859 +#: FlatCAMObj.py:743 FlatCAMObj.py:831 flatcamGUI/ObjectUI.py:449 +#: flatcamGUI/PreferencesUI.py:6527 flatcamTools/ToolAlignObjects.py:73 +#: flatcamTools/ToolAlignObjects.py:109 flatcamTools/ToolCalibration.py:196 +#: flatcamTools/ToolCalibration.py:631 flatcamTools/ToolCalibration.py:648 +#: flatcamTools/ToolCalibration.py:807 flatcamTools/ToolCalibration.py:815 +#: flatcamTools/ToolCopperThieving.py:145 +#: flatcamTools/ToolCopperThieving.py:159 +#: flatcamTools/ToolCopperThieving.py:605 flatcamTools/ToolCutOut.py:92 +#: flatcamTools/ToolDblSided.py:225 flatcamTools/ToolFilm.py:69 +#: flatcamTools/ToolFilm.py:102 flatcamTools/ToolFilm.py:549 +#: flatcamTools/ToolFilm.py:557 flatcamTools/ToolImage.py:49 +#: flatcamTools/ToolImage.py:252 flatcamTools/ToolImage.py:273 +#: flatcamTools/ToolNCC.py:96 flatcamTools/ToolNCC.py:558 +#: flatcamTools/ToolNCC.py:1293 flatcamTools/ToolPaint.py:502 +#: flatcamTools/ToolPaint.py:703 flatcamTools/ToolPanelize.py:118 +#: flatcamTools/ToolPanelize.py:204 flatcamTools/ToolPanelize.py:374 +#: flatcamTools/ToolPanelize.py:391 +msgid "Gerber" +msgstr "Gerber" + +#: FlatCAMObj.py:743 FlatCAMObj.py:831 flatcamGUI/FlatCAMGUI.py:2154 +#: flatcamGUI/ObjectUI.py:449 flatcamTools/ToolCalibration.py:631 +#: flatcamTools/ToolCalibration.py:648 flatcamTools/ToolCalibration.py:815 +#: flatcamTools/ToolCopperThieving.py:145 +#: flatcamTools/ToolCopperThieving.py:159 +#: flatcamTools/ToolCopperThieving.py:605 flatcamTools/ToolCutOut.py:93 +#: flatcamTools/ToolDblSided.py:227 flatcamTools/ToolFilm.py:69 +#: flatcamTools/ToolFilm.py:102 flatcamTools/ToolFilm.py:549 +#: flatcamTools/ToolFilm.py:557 flatcamTools/ToolImage.py:49 +#: flatcamTools/ToolImage.py:271 flatcamTools/ToolNCC.py:95 +#: flatcamTools/ToolNCC.py:558 flatcamTools/ToolNCC.py:1293 +#: flatcamTools/ToolPaint.py:502 flatcamTools/ToolPaint.py:703 +#: flatcamTools/ToolPanelize.py:118 flatcamTools/ToolPanelize.py:374 +#: flatcamTools/ToolPanelize.py:391 +msgid "Geometry" +msgstr "Geometry" + +#: FlatCAMObj.py:755 FlatCAMObj.py:2957 FlatCAMObj.py:4421 +#: flatcamGUI/PreferencesUI.py:1646 flatcamGUI/PreferencesUI.py:3041 msgid "Basic" msgstr "Basic" -#: FlatCAMObj.py:763 FlatCAMObj.py:2758 FlatCAMObj.py:3989 -#: flatcamGUI/PreferencesUI.py:1471 +#: FlatCAMObj.py:782 FlatCAMObj.py:2970 FlatCAMObj.py:4442 +#: flatcamGUI/PreferencesUI.py:1647 msgid "Advanced" msgstr "Advanced" -#: FlatCAMObj.py:980 +#: FlatCAMObj.py:998 msgid "Buffering solid geometry" msgstr "Buffering solid geometry" -#: FlatCAMObj.py:983 camlib.py:965 flatcamGUI/PreferencesUI.py:2296 -#: flatcamTools/ToolCopperThieving.py:1011 -#: flatcamTools/ToolCopperThieving.py:1200 -#: flatcamTools/ToolCopperThieving.py:1212 -#: flatcamTools/ToolNonCopperClear.py:1624 -#: flatcamTools/ToolNonCopperClear.py:1721 -#: flatcamTools/ToolNonCopperClear.py:1732 -#: flatcamTools/ToolNonCopperClear.py:2015 -#: flatcamTools/ToolNonCopperClear.py:2111 -#: flatcamTools/ToolNonCopperClear.py:2123 +#: FlatCAMObj.py:1001 camlib.py:979 flatcamGUI/PreferencesUI.py:2476 +#: flatcamTools/ToolCopperThieving.py:1017 +#: flatcamTools/ToolCopperThieving.py:1206 +#: flatcamTools/ToolCopperThieving.py:1218 flatcamTools/ToolNCC.py:2050 +#: flatcamTools/ToolNCC.py:2158 flatcamTools/ToolNCC.py:2172 +#: flatcamTools/ToolNCC.py:3103 flatcamTools/ToolNCC.py:3208 +#: flatcamTools/ToolNCC.py:3223 flatcamTools/ToolNCC.py:3489 +#: flatcamTools/ToolNCC.py:3590 flatcamTools/ToolNCC.py:3605 msgid "Buffering" msgstr "Buffering" -#: FlatCAMObj.py:989 +#: FlatCAMObj.py:1007 msgid "Done" msgstr "Done" -#: FlatCAMObj.py:1040 +#: FlatCAMObj.py:1032 FlatCAMObj.py:1058 +#| msgid "Scaling could not be executed." +msgid "Operation could not be done." +msgstr "Operation could not be done." + +#: FlatCAMObj.py:1075 msgid "Isolating..." msgstr "Isolating..." -#: FlatCAMObj.py:1099 +#: FlatCAMObj.py:1134 msgid "Click on a polygon to isolate it." msgstr "Click on a polygon to isolate it." -#: FlatCAMObj.py:1138 FlatCAMObj.py:1243 flatcamTools/ToolPaint.py:1120 +#: FlatCAMObj.py:1173 FlatCAMObj.py:1277 flatcamTools/ToolPaint.py:1504 msgid "Added polygon" msgstr "Added polygon" -#: FlatCAMObj.py:1140 FlatCAMObj.py:1245 +#: FlatCAMObj.py:1174 FlatCAMObj.py:1279 msgid "Click to add next polygon or right click to start isolation." msgstr "Click to add next polygon or right click to start isolation." -#: FlatCAMObj.py:1152 flatcamTools/ToolPaint.py:1134 +#: FlatCAMObj.py:1186 flatcamTools/ToolPaint.py:1518 msgid "Removed polygon" msgstr "Removed polygon" -#: FlatCAMObj.py:1153 +#: FlatCAMObj.py:1187 msgid "Click to add/remove next polygon or right click to start isolation." msgstr "Click to add/remove next polygon or right click to start isolation." -#: FlatCAMObj.py:1158 flatcamTools/ToolPaint.py:1140 +#: FlatCAMObj.py:1192 flatcamTools/ToolPaint.py:1524 msgid "No polygon detected under click position." msgstr "No polygon detected under click position." -#: FlatCAMObj.py:1179 flatcamTools/ToolPaint.py:1169 +#: FlatCAMObj.py:1213 flatcamTools/ToolPaint.py:1553 msgid "List of single polygons is empty. Aborting." msgstr "List of single polygons is empty. Aborting." -#: FlatCAMObj.py:1248 +#: FlatCAMObj.py:1282 msgid "No polygon in selection." msgstr "No polygon in selection." -#: FlatCAMObj.py:1324 FlatCAMObj.py:1457 -#: flatcamTools/ToolNonCopperClear.py:1653 -#: flatcamTools/ToolNonCopperClear.py:2039 -msgid "Isolation geometry could not be generated." -msgstr "Isolation geometry could not be generated." - -#: FlatCAMObj.py:1374 FlatCAMObj.py:3637 FlatCAMObj.py:3922 FlatCAMObj.py:4221 +#: FlatCAMObj.py:1394 FlatCAMObj.py:1542 FlatCAMObj.py:4055 FlatCAMObj.py:4375 +#: FlatCAMObj.py:4762 msgid "Rough" msgstr "Rough" -#: FlatCAMObj.py:1400 FlatCAMObj.py:1480 +#: FlatCAMObj.py:1410 FlatCAMObj.py:1489 flatcamTools/ToolNCC.py:2086 +#: flatcamTools/ToolNCC.py:3137 flatcamTools/ToolNCC.py:3516 +msgid "Isolation geometry could not be generated." +msgstr "Isolation geometry could not be generated." + +#: FlatCAMObj.py:1435 FlatCAMObj.py:1567 msgid "Isolation geometry created" msgstr "Isolation geometry created" -#: FlatCAMObj.py:1409 FlatCAMObj.py:1487 +#: FlatCAMObj.py:1444 FlatCAMObj.py:1574 msgid "Subtracting Geo" msgstr "Subtracting Geo" -#: FlatCAMObj.py:1807 +#: FlatCAMObj.py:1899 msgid "Plotting Apertures" msgstr "Plotting Apertures" -#: FlatCAMObj.py:2573 flatcamEditors/FlatCAMExcEditor.py:2427 +#: FlatCAMObj.py:2753 flatcamEditors/FlatCAMExcEditor.py:2453 msgid "Total Drills" msgstr "Total Drills" -#: FlatCAMObj.py:2605 flatcamEditors/FlatCAMExcEditor.py:2459 +#: FlatCAMObj.py:2784 flatcamEditors/FlatCAMExcEditor.py:2485 msgid "Total Slots" msgstr "Total Slots" -#: FlatCAMObj.py:3060 FlatCAMObj.py:3155 FlatCAMObj.py:3276 -msgid "Please select one or more tools from the list and try again." -msgstr "Please select one or more tools from the list and try again." - -#: FlatCAMObj.py:3067 -msgid "Milling tool for DRILLS is larger than hole size. Cancelled." -msgstr "Milling tool for DRILLS is larger than hole size. Cancelled." - -#: FlatCAMObj.py:3068 FlatCAMObj.py:4533 flatcamEditors/FlatCAMGeoEditor.py:408 -#: flatcamGUI/FlatCAMGUI.py:457 flatcamGUI/FlatCAMGUI.py:1072 -#: flatcamGUI/ObjectUI.py:1353 -msgid "Tool" -msgstr "Tool" - -#: FlatCAMObj.py:3084 FlatCAMObj.py:3177 FlatCAMObj.py:3295 -msgid "Tool_nr" -msgstr "Tool_nr" - -#: FlatCAMObj.py:3084 FlatCAMObj.py:3177 FlatCAMObj.py:3295 -#: flatcamEditors/FlatCAMExcEditor.py:1582 -#: flatcamEditors/FlatCAMExcEditor.py:3048 flatcamGUI/ObjectUI.py:777 -#: flatcamTools/ToolNonCopperClear.py:120 flatcamTools/ToolPaint.py:123 -#: flatcamTools/ToolPcbWizard.py:76 flatcamTools/ToolProperties.py:396 -#: flatcamTools/ToolProperties.py:449 flatcamTools/ToolSolderPaste.py:84 -msgid "Diameter" -msgstr "Diameter" - -#: FlatCAMObj.py:3084 FlatCAMObj.py:3177 FlatCAMObj.py:3295 -msgid "Drills_Nr" -msgstr "Drills_Nr" - -#: FlatCAMObj.py:3084 FlatCAMObj.py:3177 FlatCAMObj.py:3295 -msgid "Slots_Nr" -msgstr "Slots_Nr" - -#: FlatCAMObj.py:3164 -msgid "Milling tool for SLOTS is larger than hole size. Cancelled." -msgstr "Milling tool for SLOTS is larger than hole size. Cancelled." - -#: FlatCAMObj.py:3336 -msgid "" -"Wrong value format for self.defaults[\"z_pdepth\"] or self.options[\"z_pdepth" -"\"]" -msgstr "" -"Wrong value format for self.defaults[\"z_pdepth\"] or self.options[\"z_pdepth" -"\"]" - -#: FlatCAMObj.py:3347 -msgid "" -"Wrong value format for self.defaults[\"feedrate_probe\"] or self." -"options[\"feedrate_probe\"]" -msgstr "" -"Wrong value format for self.defaults[\"feedrate_probe\"] or self." -"options[\"feedrate_probe\"]" - -#: FlatCAMObj.py:3377 FlatCAMObj.py:5354 FlatCAMObj.py:5358 FlatCAMObj.py:5493 -msgid "Generating CNC Code" -msgstr "Generating CNC Code" - -#: FlatCAMObj.py:3637 FlatCAMObj.py:4632 FlatCAMObj.py:4633 FlatCAMObj.py:4642 -msgid "Iso" -msgstr "Iso" - -#: FlatCAMObj.py:3637 -msgid "Finish" -msgstr "Finish" - -#: FlatCAMObj.py:3957 -msgid "Add from Tool DB" -msgstr "Add from Tool DB" - -#: FlatCAMObj.py:3960 flatcamGUI/FlatCAMGUI.py:678 flatcamGUI/FlatCAMGUI.py:794 -#: flatcamGUI/FlatCAMGUI.py:989 flatcamGUI/FlatCAMGUI.py:2015 -#: flatcamGUI/FlatCAMGUI.py:2159 flatcamGUI/FlatCAMGUI.py:2378 -#: flatcamGUI/FlatCAMGUI.py:2557 flatcamGUI/ObjectUI.py:1324 -#: flatcamTools/ToolPanelize.py:534 flatcamTools/ToolPanelize.py:561 -#: flatcamTools/ToolPanelize.py:660 flatcamTools/ToolPanelize.py:694 -#: flatcamTools/ToolPanelize.py:759 -msgid "Copy" -msgstr "Copy" - -#: FlatCAMObj.py:4054 FlatCAMObj.py:4397 FlatCAMObj.py:5107 FlatCAMObj.py:5744 -#: flatcamEditors/FlatCAMExcEditor.py:2534 -#: flatcamEditors/FlatCAMGeoEditor.py:1078 -#: flatcamEditors/FlatCAMGeoEditor.py:1112 -#: flatcamEditors/FlatCAMGeoEditor.py:1133 -#: flatcamEditors/FlatCAMGeoEditor.py:1154 -#: flatcamEditors/FlatCAMGeoEditor.py:1191 -#: flatcamEditors/FlatCAMGeoEditor.py:1219 -#: flatcamEditors/FlatCAMGeoEditor.py:1240 -#: flatcamTools/ToolNonCopperClear.py:1052 -#: flatcamTools/ToolNonCopperClear.py:1461 flatcamTools/ToolPaint.py:835 -#: flatcamTools/ToolPaint.py:1019 flatcamTools/ToolPaint.py:2198 -#: flatcamTools/ToolSolderPaste.py:882 flatcamTools/ToolSolderPaste.py:957 -msgid "Wrong value format entered, use a number." -msgstr "Wrong value format entered, use a number." - -#: FlatCAMObj.py:4240 -msgid "Tool added in Tool Table." -msgstr "Tool added in Tool Table." - -#: FlatCAMObj.py:4347 FlatCAMObj.py:4356 -msgid "Failed. Select a tool to copy." -msgstr "Failed. Select a tool to copy." - -#: FlatCAMObj.py:4383 -msgid "Tool was copied in Tool Table." -msgstr "Tool was copied in Tool Table." - -#: FlatCAMObj.py:4411 -msgid "Tool was edited in Tool Table." -msgstr "Tool was edited in Tool Table." - -#: FlatCAMObj.py:4440 FlatCAMObj.py:4449 -msgid "Failed. Select a tool to delete." -msgstr "Failed. Select a tool to delete." - -#: FlatCAMObj.py:4472 -msgid "Tool was deleted in Tool Table." -msgstr "Tool was deleted in Tool Table." - -#: FlatCAMObj.py:4533 flatcamGUI/ObjectUI.py:1353 +#: FlatCAMObj.py:2857 FlatCAMObj.py:3069 FlatCAMObj.py:3085 FlatCAMObj.py:3089 +#: FlatCAMObj.py:4242 FlatCAMObj.py:4667 FlatCAMObj.py:4703 +#: flatcamGUI/ObjectUI.py:817 flatcamGUI/ObjectUI.py:1660 +#: flatcamTools/ToolNCC.py:331 flatcamTools/ToolNCC.py:794 +#: flatcamTools/ToolNCC.py:808 flatcamTools/ToolNCC.py:1189 +#: flatcamTools/ToolPaint.py:314 flatcamTools/ToolPaint.py:764 +#: flatcamTools/ToolPaint.py:776 flatcamTools/ToolPaint.py:1159 msgid "Parameters for" msgstr "Parameters for" -#: FlatCAMObj.py:4967 +#: FlatCAMObj.py:2857 FlatCAMObj.py:3089 FlatCAMObj.py:4242 FlatCAMObj.py:4703 +#: flatcamTools/ToolNCC.py:808 flatcamTools/ToolNCC.py:1189 +#: flatcamTools/ToolPaint.py:776 flatcamTools/ToolPaint.py:1159 +#| msgid "Rules Tool" +msgid "Multiple Tools" +msgstr "Multiple Tools" + +#: FlatCAMObj.py:3069 +#| msgid "Tool Selection" +msgid "No Tool Selected" +msgstr "No Tool Selected" + +#: FlatCAMObj.py:3085 FlatCAMObj.py:3427 FlatCAMObj.py:4667 +#: flatcamEditors/FlatCAMGeoEditor.py:406 flatcamGUI/FlatCAMGUI.py:496 +#: flatcamGUI/FlatCAMGUI.py:1143 flatcamGUI/ObjectUI.py:817 +#: flatcamGUI/ObjectUI.py:1660 flatcamTools/ToolNCC.py:331 +#: flatcamTools/ToolNCC.py:794 flatcamTools/ToolPaint.py:314 +#: flatcamTools/ToolPaint.py:764 +msgid "Tool" +msgstr "Tool" + +#: FlatCAMObj.py:3419 FlatCAMObj.py:3512 FlatCAMObj.py:3700 +msgid "Please select one or more tools from the list and try again." +msgstr "Please select one or more tools from the list and try again." + +#: FlatCAMObj.py:3426 +msgid "Milling tool for DRILLS is larger than hole size. Cancelled." +msgstr "Milling tool for DRILLS is larger than hole size. Cancelled." + +#: FlatCAMObj.py:3442 FlatCAMObj.py:3533 FlatCAMObj.py:3719 +#: tclCommands/TclCommandDrillcncjob.py:194 +msgid "Tool_nr" +msgstr "Tool_nr" + +#: FlatCAMObj.py:3442 FlatCAMObj.py:3533 FlatCAMObj.py:3719 +#: flatcamEditors/FlatCAMExcEditor.py:1585 +#: flatcamEditors/FlatCAMExcEditor.py:3069 flatcamGUI/ObjectUI.py:780 +#: flatcamTools/ToolNCC.py:132 flatcamTools/ToolPaint.py:128 +#: flatcamTools/ToolPcbWizard.py:76 flatcamTools/ToolProperties.py:416 +#: flatcamTools/ToolProperties.py:476 flatcamTools/ToolSolderPaste.py:86 +#: tclCommands/TclCommandDrillcncjob.py:194 +msgid "Diameter" +msgstr "Diameter" + +#: FlatCAMObj.py:3442 FlatCAMObj.py:3533 FlatCAMObj.py:3719 +#: tclCommands/TclCommandDrillcncjob.py:194 +msgid "Drills_Nr" +msgstr "Drills_Nr" + +#: FlatCAMObj.py:3442 FlatCAMObj.py:3533 FlatCAMObj.py:3719 +#: tclCommands/TclCommandDrillcncjob.py:194 +msgid "Slots_Nr" +msgstr "Slots_Nr" + +#: FlatCAMObj.py:3521 +msgid "Milling tool for SLOTS is larger than hole size. Cancelled." +msgstr "Milling tool for SLOTS is larger than hole size. Cancelled." + +#: FlatCAMObj.py:3626 FlatCAMObj.py:5451 +msgid "Focus Z" +msgstr "Focus Z" + +#: FlatCAMObj.py:3645 FlatCAMObj.py:5470 +msgid "Laser Power" +msgstr "Laser Power" + +#: FlatCAMObj.py:3677 FlatCAMObj.py:5502 flatcamGUI/ObjectUI.py:1048 +#: flatcamGUI/ObjectUI.py:1839 flatcamGUI/PreferencesUI.py:4409 +msgid "Spindle speed" +msgstr "Spindle speed" + +#: FlatCAMObj.py:3776 FlatCAMObj.py:5911 FlatCAMObj.py:5915 FlatCAMObj.py:6060 +msgid "Generating CNC Code" +msgstr "Generating CNC Code" + +#: FlatCAMObj.py:3966 flatcamTools/ToolNCC.py:916 flatcamTools/ToolPaint.py:841 +#| msgid "Apply parameters to all tools" +msgid "Current Tool parameters were applied to all tools." +msgstr "Current Tool parameters were applied to all tools." + +#: FlatCAMObj.py:4055 FlatCAMObj.py:5115 FlatCAMObj.py:5116 FlatCAMObj.py:5125 +msgid "Iso" +msgstr "Iso" + +#: FlatCAMObj.py:4055 +msgid "Finish" +msgstr "Finish" + +#: FlatCAMObj.py:4410 +msgid "Add from Tool DB" +msgstr "Add from Tool DB" + +#: FlatCAMObj.py:4413 flatcamGUI/FlatCAMGUI.py:734 flatcamGUI/FlatCAMGUI.py:848 +#: flatcamGUI/FlatCAMGUI.py:1057 flatcamGUI/FlatCAMGUI.py:2123 +#: flatcamGUI/FlatCAMGUI.py:2267 flatcamGUI/FlatCAMGUI.py:2532 +#: flatcamGUI/FlatCAMGUI.py:2731 flatcamGUI/ObjectUI.py:1615 +#: flatcamTools/ToolPanelize.py:543 flatcamTools/ToolPanelize.py:570 +#: flatcamTools/ToolPanelize.py:669 flatcamTools/ToolPanelize.py:703 +#: flatcamTools/ToolPanelize.py:768 +msgid "Copy" +msgstr "Copy" + +#: FlatCAMObj.py:4507 FlatCAMObj.py:4941 FlatCAMObj.py:5661 FlatCAMObj.py:6307 +#: flatcamEditors/FlatCAMExcEditor.py:2560 +#: flatcamEditors/FlatCAMGeoEditor.py:1077 +#: flatcamEditors/FlatCAMGeoEditor.py:1118 +#: flatcamEditors/FlatCAMGeoEditor.py:1146 +#: flatcamEditors/FlatCAMGeoEditor.py:1174 +#: flatcamEditors/FlatCAMGeoEditor.py:1218 +#: flatcamEditors/FlatCAMGeoEditor.py:1253 +#: flatcamEditors/FlatCAMGeoEditor.py:1281 flatcamTools/ToolNCC.py:1502 +#: flatcamTools/ToolPaint.py:1237 flatcamTools/ToolPaint.py:1408 +#: flatcamTools/ToolSolderPaste.py:883 flatcamTools/ToolSolderPaste.py:956 +msgid "Wrong value format entered, use a number." +msgstr "Wrong value format entered, use a number." + +#: FlatCAMObj.py:4781 +msgid "Tool added in Tool Table." +msgstr "Tool added in Tool Table." + +#: FlatCAMObj.py:4890 FlatCAMObj.py:4899 +msgid "Failed. Select a tool to copy." +msgstr "Failed. Select a tool to copy." + +#: FlatCAMObj.py:4928 +msgid "Tool was copied in Tool Table." +msgstr "Tool was copied in Tool Table." + +#: FlatCAMObj.py:4955 +msgid "Tool was edited in Tool Table." +msgstr "Tool was edited in Tool Table." + +#: FlatCAMObj.py:4984 FlatCAMObj.py:4993 +msgid "Failed. Select a tool to delete." +msgstr "Failed. Select a tool to delete." + +#: FlatCAMObj.py:5017 +msgid "Tool was deleted in Tool Table." +msgstr "Tool was deleted in Tool Table." + +#: FlatCAMObj.py:5523 msgid "This Geometry can't be processed because it is" msgstr "This Geometry can't be processed because it is" -#: FlatCAMObj.py:4969 +#: FlatCAMObj.py:5523 msgid "geometry" msgstr "geometry" -#: FlatCAMObj.py:5012 +#: FlatCAMObj.py:5564 msgid "Failed. No tool selected in the tool table ..." msgstr "Failed. No tool selected in the tool table ..." -#: FlatCAMObj.py:5112 FlatCAMObj.py:5264 +#: FlatCAMObj.py:5667 FlatCAMObj.py:5820 msgid "" "Tool Offset is selected in Tool Table but no value is provided.\n" "Add a Tool Offset or change the Offset Type." @@ -2553,44 +2993,44 @@ msgstr "" "Tool Offset is selected in Tool Table but no value is provided.\n" "Add a Tool Offset or change the Offset Type." -#: FlatCAMObj.py:5177 FlatCAMObj.py:5325 +#: FlatCAMObj.py:5733 FlatCAMObj.py:5882 msgid "G-Code parsing in progress..." msgstr "G-Code parsing in progress..." -#: FlatCAMObj.py:5179 FlatCAMObj.py:5327 +#: FlatCAMObj.py:5735 FlatCAMObj.py:5884 msgid "G-Code parsing finished..." msgstr "G-Code parsing finished..." -#: FlatCAMObj.py:5187 +#: FlatCAMObj.py:5743 msgid "Finished G-Code processing" msgstr "Finished G-Code processing" -#: FlatCAMObj.py:5189 FlatCAMObj.py:5339 +#: FlatCAMObj.py:5745 FlatCAMObj.py:5896 msgid "G-Code processing failed with error" msgstr "G-Code processing failed with error" -#: FlatCAMObj.py:5234 flatcamTools/ToolSolderPaste.py:1303 +#: FlatCAMObj.py:5790 flatcamTools/ToolSolderPaste.py:1300 msgid "Cancelled. Empty file, it has no geometry" msgstr "Cancelled. Empty file, it has no geometry" -#: FlatCAMObj.py:5337 FlatCAMObj.py:5486 +#: FlatCAMObj.py:5894 FlatCAMObj.py:6055 msgid "Finished G-Code processing..." msgstr "Finished G-Code processing..." -#: FlatCAMObj.py:5356 FlatCAMObj.py:5360 FlatCAMObj.py:5496 +#: FlatCAMObj.py:5913 FlatCAMObj.py:5917 FlatCAMObj.py:6062 msgid "CNCjob created" msgstr "CNCjob created" -#: FlatCAMObj.py:5527 FlatCAMObj.py:5536 flatcamParsers/ParseGerber.py:1794 -#: flatcamParsers/ParseGerber.py:1804 +#: FlatCAMObj.py:6092 FlatCAMObj.py:6101 flatcamParsers/ParseGerber.py:1866 +#: flatcamParsers/ParseGerber.py:1876 msgid "Scale factor has to be a number: integer or float." msgstr "Scale factor has to be a number: integer or float." -#: FlatCAMObj.py:5600 +#: FlatCAMObj.py:6164 msgid "Geometry Scale done." msgstr "Geometry Scale done." -#: FlatCAMObj.py:5617 flatcamParsers/ParseGerber.py:1920 +#: FlatCAMObj.py:6181 flatcamParsers/ParseGerber.py:1992 msgid "" "An (x,y) pair of values are needed. Probable you entered only one value in " "the Offset field." @@ -2598,11 +3038,11 @@ msgstr "" "An (x,y) pair of values are needed. Probable you entered only one value in " "the Offset field." -#: FlatCAMObj.py:5674 +#: FlatCAMObj.py:6237 msgid "Geometry Offset done." msgstr "Geometry Offset done." -#: FlatCAMObj.py:5703 +#: FlatCAMObj.py:6266 msgid "" "The Toolchange X,Y field in Edit -> Preferences has to be in the format (x, " "y)\n" @@ -2612,43 +3052,43 @@ msgstr "" "y)\n" "but now there is only one value, not two." -#: FlatCAMObj.py:6388 FlatCAMObj.py:7175 FlatCAMObj.py:7371 +#: FlatCAMObj.py:6956 FlatCAMObj.py:7802 FlatCAMObj.py:7999 msgid "Basic" msgstr "Basic" -#: FlatCAMObj.py:6394 FlatCAMObj.py:7179 FlatCAMObj.py:7375 +#: FlatCAMObj.py:6962 FlatCAMObj.py:7806 FlatCAMObj.py:8003 msgid "Advanced" msgstr "Advanced" -#: FlatCAMObj.py:6437 +#: FlatCAMObj.py:7005 msgid "Plotting..." msgstr "Plotting..." -#: FlatCAMObj.py:6460 FlatCAMObj.py:6465 flatcamTools/ToolSolderPaste.py:1509 +#: FlatCAMObj.py:7034 FlatCAMObj.py:7039 flatcamTools/ToolSolderPaste.py:1498 msgid "Export Machine Code ..." msgstr "Export Machine Code ..." -#: FlatCAMObj.py:6470 flatcamTools/ToolSolderPaste.py:1513 +#: FlatCAMObj.py:7044 flatcamTools/ToolSolderPaste.py:1502 msgid "Export Machine Code cancelled ..." msgstr "Export Machine Code cancelled ..." -#: FlatCAMObj.py:6492 +#: FlatCAMObj.py:7065 msgid "Machine Code file saved to" msgstr "Machine Code file saved to" -#: FlatCAMObj.py:6546 flatcamTools/ToolCalibration.py:1083 +#: FlatCAMObj.py:7126 flatcamTools/ToolCalibration.py:1097 msgid "Loaded Machine Code into Code Editor" msgstr "Loaded Machine Code into Code Editor" -#: FlatCAMObj.py:6684 +#: FlatCAMObj.py:7265 msgid "This CNCJob object can't be processed because it is a" msgstr "This CNCJob object can't be processed because it is a" -#: FlatCAMObj.py:6686 +#: FlatCAMObj.py:7267 msgid "CNCJob object" msgstr "CNCJob object" -#: FlatCAMObj.py:6866 +#: FlatCAMObj.py:7447 msgid "" "G-code does not have a G94 code and we will not include the code in the " "'Prepend to GCode' text box" @@ -2656,38 +3096,38 @@ msgstr "" "G-code does not have a G94 code and we will not include the code in the " "'Prepend to GCode' text box" -#: FlatCAMObj.py:6877 +#: FlatCAMObj.py:7458 msgid "Cancelled. The Toolchange Custom code is enabled but it's empty." msgstr "Cancelled. The Toolchange Custom code is enabled but it's empty." -#: FlatCAMObj.py:6882 +#: FlatCAMObj.py:7463 msgid "Toolchange G-code was replaced by a custom code." msgstr "Toolchange G-code was replaced by a custom code." -#: FlatCAMObj.py:6899 flatcamEditors/FlatCAMTextEditor.py:270 -#: flatcamTools/ToolSolderPaste.py:1540 +#: FlatCAMObj.py:7480 flatcamEditors/FlatCAMTextEditor.py:272 +#: flatcamTools/ToolSolderPaste.py:1529 msgid "No such file or directory" msgstr "No such file or directory" -#: FlatCAMObj.py:6913 flatcamEditors/FlatCAMTextEditor.py:282 +#: FlatCAMObj.py:7494 flatcamEditors/FlatCAMTextEditor.py:284 msgid "Saved to" msgstr "Saved to" -#: FlatCAMObj.py:6923 FlatCAMObj.py:6933 +#: FlatCAMObj.py:7511 FlatCAMObj.py:7521 msgid "" "The used preprocessor file has to have in it's name: 'toolchange_custom'" msgstr "" "The used preprocessor file has to have in it's name: 'toolchange_custom'" -#: FlatCAMObj.py:6937 +#: FlatCAMObj.py:7524 msgid "There is no preprocessor file." msgstr "There is no preprocessor file." -#: FlatCAMObj.py:7194 +#: FlatCAMObj.py:7821 msgid "Script Editor" msgstr "Script Editor" -#: FlatCAMObj.py:7475 +#: FlatCAMObj.py:8103 msgid "Document Editor" msgstr "Document Editor" @@ -2695,6 +3135,16 @@ msgstr "Document Editor" msgid "processes running." msgstr "processes running." +#: FlatCAMTool.py:245 FlatCAMTool.py:252 flatcamGUI/ObjectUI.py:156 +#: flatcamGUI/ObjectUI.py:163 +msgid "Edited value is out of range" +msgstr "Edited value is out of range" + +#: FlatCAMTool.py:247 FlatCAMTool.py:254 flatcamGUI/ObjectUI.py:158 +#: flatcamGUI/ObjectUI.py:165 +msgid "Edited value is within limits." +msgstr "Edited value is within limits." + #: FlatCAMTranslation.py:103 msgid "The application will restart." msgstr "The application will restart." @@ -2707,68 +3157,68 @@ msgstr "Are you sure do you want to change the current language to" msgid "Apply Language ..." msgstr "Apply Language ..." -#: ObjectCollection.py:459 +#: ObjectCollection.py:506 #, python-brace-format msgid "Object renamed from {old} to {new}" msgstr "Object renamed from {old} to {new}" -#: ObjectCollection.py:858 +#: ObjectCollection.py:972 msgid "Cause of error" msgstr "Cause of error" -#: camlib.py:590 +#: camlib.py:593 msgid "self.solid_geometry is neither BaseGeometry or list." msgstr "self.solid_geometry is neither BaseGeometry or list." -#: camlib.py:953 +#: camlib.py:968 msgid "Pass" msgstr "Pass" -#: camlib.py:974 +#: camlib.py:988 msgid "Get Exteriors" msgstr "Get Exteriors" -#: camlib.py:977 +#: camlib.py:991 msgid "Get Interiors" msgstr "Get Interiors" -#: camlib.py:1964 +#: camlib.py:2172 msgid "Object was mirrored" msgstr "Object was mirrored" -#: camlib.py:1967 +#: camlib.py:2175 msgid "Failed to mirror. No object selected" msgstr "Failed to mirror. No object selected" -#: camlib.py:2036 +#: camlib.py:2244 msgid "Object was rotated" msgstr "Object was rotated" -#: camlib.py:2039 +#: camlib.py:2247 msgid "Failed to rotate. No object selected" msgstr "Failed to rotate. No object selected" -#: camlib.py:2107 +#: camlib.py:2314 msgid "Object was skewed" msgstr "Object was skewed" -#: camlib.py:2110 +#: camlib.py:2317 msgid "Failed to skew. No object selected" msgstr "Failed to skew. No object selected" -#: camlib.py:2179 +#: camlib.py:2392 msgid "Object was buffered" msgstr "Object was buffered" -#: camlib.py:2181 +#: camlib.py:2394 msgid "Failed to buffer. No object selected" msgstr "Failed to buffer. No object selected" -#: camlib.py:2378 +#: camlib.py:2599 msgid "There is no such parameter" msgstr "There is no such parameter" -#: camlib.py:2454 +#: camlib.py:2659 camlib.py:2892 camlib.py:3121 camlib.py:3343 msgid "" "The Cut Z parameter has positive value. It is the depth value to drill into " "material.\n" @@ -2782,11 +3232,12 @@ msgstr "" "therefore the app will convert the value to negative. Check the resulting " "CNC code (Gcode etc)." -#: camlib.py:2462 camlib.py:3181 camlib.py:3539 +#: camlib.py:2667 camlib.py:2902 camlib.py:3131 camlib.py:3353 camlib.py:3639 +#: camlib.py:4008 msgid "The Cut Z parameter is zero. There will be no cut, skipping file" msgstr "The Cut Z parameter is zero. There will be no cut, skipping file" -#: camlib.py:2475 camlib.py:3512 +#: camlib.py:2678 camlib.py:3976 msgid "" "The Toolchange X,Y field in Edit -> Preferences has to be in the format (x, " "y) \n" @@ -2796,31 +3247,43 @@ msgstr "" "y) \n" "but now there is only one value, not two. " -#: camlib.py:2550 +#: camlib.py:2687 camlib.py:3590 camlib.py:3958 +#| msgid "" +#| "The Toolchange X,Y field in Edit -> Preferences has to be in the format " +#| "(x, y) \n" +#| "but now there is only one value, not two." +msgid "" +"The End Move X,Y field in Edit -> Preferences has to be in the format (x, y) " +"but now there is only one value, not two." +msgstr "" +"The End Move X,Y field in Edit -> Preferences has to be in the format (x, y) " +"but now there is only one value, not two." + +#: camlib.py:2775 msgid "Creating a list of points to drill..." msgstr "Creating a list of points to drill..." -#: camlib.py:2632 +#: camlib.py:2865 camlib.py:3737 camlib.py:4112 msgid "Starting G-Code" msgstr "Starting G-Code" -#: camlib.py:2727 camlib.py:2870 camlib.py:2972 camlib.py:3292 camlib.py:3653 +#: camlib.py:3006 camlib.py:3225 camlib.py:3389 camlib.py:3750 camlib.py:4123 msgid "Starting G-Code for tool with diameter" msgstr "Starting G-Code for tool with diameter" -#: camlib.py:2783 camlib.py:2926 camlib.py:3029 +#: camlib.py:3089 camlib.py:3307 camlib.py:3475 msgid "G91 coordinates not implemented" msgstr "G91 coordinates not implemented" -#: camlib.py:2789 camlib.py:2933 camlib.py:3035 +#: camlib.py:3095 camlib.py:3314 camlib.py:3481 msgid "The loaded Excellon file has no drills" msgstr "The loaded Excellon file has no drills" -#: camlib.py:3058 +#: camlib.py:3504 msgid "Finished G-Code generation..." msgstr "Finished G-Code generation..." -#: camlib.py:3153 +#: camlib.py:3608 msgid "" "The Toolchange X,Y field in Edit -> Preferences has to be in the format (x, " "y) \n" @@ -2830,7 +3293,7 @@ msgstr "" "y) \n" "but now there is only one value, not two." -#: camlib.py:3166 camlib.py:3525 +#: camlib.py:3622 camlib.py:3991 msgid "" "Cut_Z parameter is None or zero. Most likely a bad combinations of other " "parameters." @@ -2838,7 +3301,7 @@ msgstr "" "Cut_Z parameter is None or zero. Most likely a bad combinations of other " "parameters." -#: camlib.py:3173 camlib.py:3531 +#: camlib.py:3631 camlib.py:4000 msgid "" "The Cut Z parameter has positive value. It is the depth value to cut into " "material.\n" @@ -2852,11 +3315,11 @@ msgstr "" "therefore the app will convert the value to negative.Check the resulting CNC " "code (Gcode etc)." -#: camlib.py:3186 camlib.py:3545 +#: camlib.py:3644 camlib.py:4014 msgid "Travel Z parameter is None or zero." msgstr "Travel Z parameter is None or zero." -#: camlib.py:3191 camlib.py:3550 +#: camlib.py:3649 camlib.py:4019 msgid "" "The Travel Z parameter has negative value. It is the height value to travel " "between cuts.\n" @@ -2870,37 +3333,33 @@ msgstr "" "therefore the app will convert the value to positive.Check the resulting CNC " "code (Gcode etc)." -#: camlib.py:3199 camlib.py:3558 +#: camlib.py:3657 camlib.py:4027 msgid "The Z Travel parameter is zero. This is dangerous, skipping file" msgstr "The Z Travel parameter is zero. This is dangerous, skipping file" -#: camlib.py:3218 camlib.py:3580 +#: camlib.py:3676 camlib.py:4050 msgid "Indexing geometry before generating G-Code..." msgstr "Indexing geometry before generating G-Code..." -#: camlib.py:3279 camlib.py:3642 -msgid "Starting G-Code..." -msgstr "Starting G-Code..." - -#: camlib.py:3362 camlib.py:3724 +#: camlib.py:3820 camlib.py:4192 msgid "Finished G-Code generation" msgstr "Finished G-Code generation" -#: camlib.py:3364 +#: camlib.py:3820 msgid "paths traced" msgstr "paths traced" -#: camlib.py:3399 +#: camlib.py:3853 msgid "Expected a Geometry, got" msgstr "Expected a Geometry, got" -#: camlib.py:3406 +#: camlib.py:3860 msgid "" "Trying to generate a CNC Job from a Geometry object without solid_geometry." msgstr "" "Trying to generate a CNC Job from a Geometry object without solid_geometry." -#: camlib.py:3446 +#: camlib.py:3901 msgid "" "The Tool Offset value is too negative to use for the current_geometry.\n" "Raise the value (in module) and try again." @@ -2908,35 +3367,35 @@ msgstr "" "The Tool Offset value is too negative to use for the current_geometry.\n" "Raise the value (in module) and try again." -#: camlib.py:3724 +#: camlib.py:4192 msgid " paths traced." msgstr " paths traced." -#: camlib.py:3752 +#: camlib.py:4220 msgid "There is no tool data in the SolderPaste geometry." msgstr "There is no tool data in the SolderPaste geometry." -#: camlib.py:3839 +#: camlib.py:4306 msgid "Finished SolderPste G-Code generation" msgstr "Finished SolderPste G-Code generation" -#: camlib.py:3841 +#: camlib.py:4306 msgid "paths traced." msgstr "paths traced." -#: camlib.py:4097 +#: camlib.py:4566 msgid "Parsing GCode file. Number of lines" msgstr "Parsing GCode file. Number of lines" -#: camlib.py:4204 +#: camlib.py:4673 msgid "Creating Geometry from the parsed GCode file. " msgstr "Creating Geometry from the parsed GCode file. " -#: camlib.py:4345 camlib.py:4629 camlib.py:4732 camlib.py:4801 +#: camlib.py:4816 camlib.py:5101 camlib.py:5204 camlib.py:5360 msgid "G91 coordinates not implemented ..." msgstr "G91 coordinates not implemented ..." -#: camlib.py:4476 +#: camlib.py:4948 msgid "Unifying Geometry from parsed Geometry segments" msgstr "Unifying Geometry from parsed Geometry segments" @@ -2964,11 +3423,11 @@ msgstr "To add an Drill Array first select a tool in Tool Table" #: flatcamEditors/FlatCAMExcEditor.py:193 #: flatcamEditors/FlatCAMExcEditor.py:416 #: flatcamEditors/FlatCAMExcEditor.py:637 -#: flatcamEditors/FlatCAMExcEditor.py:1155 -#: flatcamEditors/FlatCAMExcEditor.py:1182 +#: flatcamEditors/FlatCAMExcEditor.py:1152 +#: flatcamEditors/FlatCAMExcEditor.py:1179 #: flatcamEditors/FlatCAMGrbEditor.py:471 -#: flatcamEditors/FlatCAMGrbEditor.py:1936 -#: flatcamEditors/FlatCAMGrbEditor.py:1966 +#: flatcamEditors/FlatCAMGrbEditor.py:1935 +#: flatcamEditors/FlatCAMGrbEditor.py:1965 msgid "Click on target location ..." msgstr "Click on target location ..." @@ -3000,8 +3459,8 @@ msgstr "To add a slot first select a tool" #: flatcamEditors/FlatCAMExcEditor.py:455 #: flatcamEditors/FlatCAMExcEditor.py:462 -#: flatcamEditors/FlatCAMExcEditor.py:744 -#: flatcamEditors/FlatCAMExcEditor.py:751 +#: flatcamEditors/FlatCAMExcEditor.py:743 +#: flatcamEditors/FlatCAMExcEditor.py:750 msgid "Value is missing or wrong format. Add it and retry." msgstr "Value is missing or wrong format. Add it and retry." @@ -3017,70 +3476,64 @@ msgstr "To add an Slot Array first select a tool in Tool Table" msgid "Click on the Slot Circular Array Start position" msgstr "Click on the Slot Circular Array Start position" -#: flatcamEditors/FlatCAMExcEditor.py:682 -#: flatcamEditors/FlatCAMGrbEditor.py:520 +#: flatcamEditors/FlatCAMExcEditor.py:681 +#: flatcamEditors/FlatCAMGrbEditor.py:519 msgid "The value is mistyped. Check the value." msgstr "The value is mistyped. Check the value." -#: flatcamEditors/FlatCAMExcEditor.py:861 +#: flatcamEditors/FlatCAMExcEditor.py:860 msgid "Too many Slots for the selected spacing angle." msgstr "Too many Slots for the selected spacing angle." -#: flatcamEditors/FlatCAMExcEditor.py:884 +#: flatcamEditors/FlatCAMExcEditor.py:883 msgid "Done. Slot Array added." msgstr "Done. Slot Array added." -#: flatcamEditors/FlatCAMExcEditor.py:906 +#: flatcamEditors/FlatCAMExcEditor.py:905 msgid "Click on the Drill(s) to resize ..." msgstr "Click on the Drill(s) to resize ..." -#: flatcamEditors/FlatCAMExcEditor.py:936 +#: flatcamEditors/FlatCAMExcEditor.py:935 msgid "Resize drill(s) failed. Please enter a diameter for resize." msgstr "Resize drill(s) failed. Please enter a diameter for resize." -#: flatcamEditors/FlatCAMExcEditor.py:1026 -#: flatcamEditors/FlatCAMExcEditor.py:1095 flatcamGUI/FlatCAMGUI.py:3165 -#: flatcamGUI/FlatCAMGUI.py:3377 flatcamGUI/FlatCAMGUI.py:3591 -msgid "Cancelled." -msgstr "Cancelled." - -#: flatcamEditors/FlatCAMExcEditor.py:1116 +#: flatcamEditors/FlatCAMExcEditor.py:1113 msgid "Done. Drill/Slot Resize completed." msgstr "Done. Drill/Slot Resize completed." -#: flatcamEditors/FlatCAMExcEditor.py:1119 +#: flatcamEditors/FlatCAMExcEditor.py:1116 msgid "Cancelled. No drills/slots selected for resize ..." msgstr "Cancelled. No drills/slots selected for resize ..." -#: flatcamEditors/FlatCAMExcEditor.py:1157 -#: flatcamEditors/FlatCAMGrbEditor.py:1938 +#: flatcamEditors/FlatCAMExcEditor.py:1154 +#: flatcamEditors/FlatCAMGrbEditor.py:1937 msgid "Click on reference location ..." msgstr "Click on reference location ..." -#: flatcamEditors/FlatCAMExcEditor.py:1214 +#: flatcamEditors/FlatCAMExcEditor.py:1211 msgid "Done. Drill(s) Move completed." msgstr "Done. Drill(s) Move completed." -#: flatcamEditors/FlatCAMExcEditor.py:1322 +#: flatcamEditors/FlatCAMExcEditor.py:1319 msgid "Done. Drill(s) copied." msgstr "Done. Drill(s) copied." -#: flatcamEditors/FlatCAMExcEditor.py:1555 flatcamGUI/PreferencesUI.py:3551 +#: flatcamEditors/FlatCAMExcEditor.py:1558 flatcamGUI/PreferencesUI.py:3829 msgid "Excellon Editor" msgstr "Excellon Editor" -#: flatcamEditors/FlatCAMExcEditor.py:1562 -#: flatcamEditors/FlatCAMGrbEditor.py:2454 +#: flatcamEditors/FlatCAMExcEditor.py:1565 +#: flatcamEditors/FlatCAMGrbEditor.py:2460 msgid "Name:" msgstr "Name:" -#: flatcamEditors/FlatCAMExcEditor.py:1568 flatcamGUI/ObjectUI.py:757 -#: flatcamGUI/ObjectUI.py:1184 flatcamTools/ToolNonCopperClear.py:109 -#: flatcamTools/ToolPaint.py:112 flatcamTools/ToolSolderPaste.py:73 +#: flatcamEditors/FlatCAMExcEditor.py:1571 flatcamGUI/ObjectUI.py:760 +#: flatcamGUI/ObjectUI.py:1463 flatcamTools/ToolNCC.py:120 +#: flatcamTools/ToolPaint.py:115 flatcamTools/ToolSolderPaste.py:75 msgid "Tools Table" msgstr "Tools Table" -#: flatcamEditors/FlatCAMExcEditor.py:1570 flatcamGUI/ObjectUI.py:759 +#: flatcamEditors/FlatCAMExcEditor.py:1573 flatcamGUI/ObjectUI.py:762 msgid "" "Tools in this Excellon object\n" "when are used for drilling." @@ -3088,11 +3541,11 @@ msgstr "" "Tools in this Excellon object\n" "when are used for drilling." -#: flatcamEditors/FlatCAMExcEditor.py:1590 +#: flatcamEditors/FlatCAMExcEditor.py:1593 msgid "Add/Delete Tool" msgstr "Add/Delete Tool" -#: flatcamEditors/FlatCAMExcEditor.py:1592 +#: flatcamEditors/FlatCAMExcEditor.py:1595 msgid "" "Add/Delete a tool to the tool list\n" "for this Excellon object." @@ -3100,16 +3553,16 @@ msgstr "" "Add/Delete a tool to the tool list\n" "for this Excellon object." -#: flatcamEditors/FlatCAMExcEditor.py:1604 flatcamGUI/ObjectUI.py:1297 -#: flatcamGUI/PreferencesUI.py:3582 +#: flatcamEditors/FlatCAMExcEditor.py:1607 flatcamGUI/ObjectUI.py:1583 +#: flatcamGUI/PreferencesUI.py:3860 msgid "Diameter for the new tool" msgstr "Diameter for the new tool" -#: flatcamEditors/FlatCAMExcEditor.py:1614 +#: flatcamEditors/FlatCAMExcEditor.py:1617 msgid "Add Tool" msgstr "Add Tool" -#: flatcamEditors/FlatCAMExcEditor.py:1616 +#: flatcamEditors/FlatCAMExcEditor.py:1619 msgid "" "Add a new tool to the tool list\n" "with the diameter specified above." @@ -3117,11 +3570,11 @@ msgstr "" "Add a new tool to the tool list\n" "with the diameter specified above." -#: flatcamEditors/FlatCAMExcEditor.py:1628 +#: flatcamEditors/FlatCAMExcEditor.py:1631 msgid "Delete Tool" msgstr "Delete Tool" -#: flatcamEditors/FlatCAMExcEditor.py:1630 +#: flatcamEditors/FlatCAMExcEditor.py:1633 msgid "" "Delete a tool in the tool list\n" "by selecting a row in the tool table." @@ -3129,40 +3582,40 @@ msgstr "" "Delete a tool in the tool list\n" "by selecting a row in the tool table." -#: flatcamEditors/FlatCAMExcEditor.py:1648 flatcamGUI/FlatCAMGUI.py:1896 +#: flatcamEditors/FlatCAMExcEditor.py:1651 flatcamGUI/FlatCAMGUI.py:2004 msgid "Resize Drill(s)" msgstr "Resize Drill(s)" -#: flatcamEditors/FlatCAMExcEditor.py:1650 +#: flatcamEditors/FlatCAMExcEditor.py:1653 msgid "Resize a drill or a selection of drills." msgstr "Resize a drill or a selection of drills." -#: flatcamEditors/FlatCAMExcEditor.py:1657 +#: flatcamEditors/FlatCAMExcEditor.py:1660 msgid "Resize Dia" msgstr "Resize Dia" -#: flatcamEditors/FlatCAMExcEditor.py:1659 +#: flatcamEditors/FlatCAMExcEditor.py:1662 msgid "Diameter to resize to." msgstr "Diameter to resize to." -#: flatcamEditors/FlatCAMExcEditor.py:1670 +#: flatcamEditors/FlatCAMExcEditor.py:1673 msgid "Resize" msgstr "Resize" -#: flatcamEditors/FlatCAMExcEditor.py:1672 +#: flatcamEditors/FlatCAMExcEditor.py:1675 msgid "Resize drill(s)" msgstr "Resize drill(s)" -#: flatcamEditors/FlatCAMExcEditor.py:1697 flatcamGUI/FlatCAMGUI.py:1895 -#: flatcamGUI/FlatCAMGUI.py:2147 +#: flatcamEditors/FlatCAMExcEditor.py:1700 flatcamGUI/FlatCAMGUI.py:2003 +#: flatcamGUI/FlatCAMGUI.py:2255 msgid "Add Drill Array" msgstr "Add Drill Array" -#: flatcamEditors/FlatCAMExcEditor.py:1699 +#: flatcamEditors/FlatCAMExcEditor.py:1702 msgid "Add an array of drills (linear or circular array)" msgstr "Add an array of drills (linear or circular array)" -#: flatcamEditors/FlatCAMExcEditor.py:1705 +#: flatcamEditors/FlatCAMExcEditor.py:1708 msgid "" "Select the type of drills array to create.\n" "It can be Linear X(Y) or Circular" @@ -3170,43 +3623,48 @@ msgstr "" "Select the type of drills array to create.\n" "It can be Linear X(Y) or Circular" -#: flatcamEditors/FlatCAMExcEditor.py:1708 -#: flatcamEditors/FlatCAMExcEditor.py:1922 -#: flatcamEditors/FlatCAMGrbEditor.py:2766 +#: flatcamEditors/FlatCAMExcEditor.py:1711 +#: flatcamEditors/FlatCAMExcEditor.py:1925 +#: flatcamEditors/FlatCAMGrbEditor.py:2772 msgid "Linear" msgstr "Linear" -#: flatcamEditors/FlatCAMExcEditor.py:1709 -#: flatcamEditors/FlatCAMExcEditor.py:1923 -#: flatcamEditors/FlatCAMGrbEditor.py:2767 flatcamGUI/ObjectUI.py:311 -#: flatcamGUI/PreferencesUI.py:5044 flatcamGUI/PreferencesUI.py:7465 -#: flatcamTools/ToolFiducials.py:220 flatcamTools/ToolNonCopperClear.py:221 +#: flatcamEditors/FlatCAMExcEditor.py:1712 +#: flatcamEditors/FlatCAMExcEditor.py:1926 +#: flatcamEditors/FlatCAMGrbEditor.py:2773 flatcamGUI/ObjectUI.py:315 +#: flatcamGUI/PreferencesUI.py:5340 flatcamGUI/PreferencesUI.py:5909 +#: flatcamGUI/PreferencesUI.py:7971 flatcamGUI/PreferencesUI.py:8151 +#: flatcamGUI/PreferencesUI.py:8248 flatcamGUI/PreferencesUI.py:8363 +#: flatcamGUI/PreferencesUI.py:8462 flatcamTools/ToolExtractDrills.py:78 +#: flatcamTools/ToolExtractDrills.py:201 flatcamTools/ToolFiducials.py:220 +#: flatcamTools/ToolNCC.py:221 flatcamTools/ToolPaint.py:204 +#: flatcamTools/ToolPunchGerber.py:89 flatcamTools/ToolPunchGerber.py:229 msgid "Circular" msgstr "Circular" -#: flatcamEditors/FlatCAMExcEditor.py:1717 flatcamGUI/PreferencesUI.py:3593 +#: flatcamEditors/FlatCAMExcEditor.py:1720 flatcamGUI/PreferencesUI.py:3871 msgid "Nr of drills" msgstr "Nr of drills" -#: flatcamEditors/FlatCAMExcEditor.py:1718 flatcamGUI/PreferencesUI.py:3595 +#: flatcamEditors/FlatCAMExcEditor.py:1721 flatcamGUI/PreferencesUI.py:3873 msgid "Specify how many drills to be in the array." msgstr "Specify how many drills to be in the array." -#: flatcamEditors/FlatCAMExcEditor.py:1736 -#: flatcamEditors/FlatCAMExcEditor.py:1786 -#: flatcamEditors/FlatCAMExcEditor.py:1858 -#: flatcamEditors/FlatCAMExcEditor.py:1951 -#: flatcamEditors/FlatCAMExcEditor.py:2002 -#: flatcamEditors/FlatCAMGrbEditor.py:1572 -#: flatcamEditors/FlatCAMGrbEditor.py:2795 -#: flatcamEditors/FlatCAMGrbEditor.py:2844 flatcamGUI/PreferencesUI.py:3703 +#: flatcamEditors/FlatCAMExcEditor.py:1739 +#: flatcamEditors/FlatCAMExcEditor.py:1789 +#: flatcamEditors/FlatCAMExcEditor.py:1861 +#: flatcamEditors/FlatCAMExcEditor.py:1954 +#: flatcamEditors/FlatCAMExcEditor.py:2005 +#: flatcamEditors/FlatCAMGrbEditor.py:1571 +#: flatcamEditors/FlatCAMGrbEditor.py:2801 +#: flatcamEditors/FlatCAMGrbEditor.py:2850 flatcamGUI/PreferencesUI.py:3981 msgid "Direction" msgstr "Direction" -#: flatcamEditors/FlatCAMExcEditor.py:1738 -#: flatcamEditors/FlatCAMExcEditor.py:1953 -#: flatcamEditors/FlatCAMGrbEditor.py:2797 flatcamGUI/PreferencesUI.py:2536 -#: flatcamGUI/PreferencesUI.py:3611 flatcamGUI/PreferencesUI.py:3759 +#: flatcamEditors/FlatCAMExcEditor.py:1741 +#: flatcamEditors/FlatCAMExcEditor.py:1956 +#: flatcamEditors/FlatCAMGrbEditor.py:2803 flatcamGUI/PreferencesUI.py:2718 +#: flatcamGUI/PreferencesUI.py:3889 flatcamGUI/PreferencesUI.py:4037 msgid "" "Direction on which the linear array is oriented:\n" "- 'X' - horizontal axis \n" @@ -3218,62 +3676,62 @@ msgstr "" "- 'Y' - vertical axis or \n" "- 'Angle' - a custom angle for the array inclination" -#: flatcamEditors/FlatCAMExcEditor.py:1745 -#: flatcamEditors/FlatCAMExcEditor.py:1867 -#: flatcamEditors/FlatCAMExcEditor.py:1960 -#: flatcamEditors/FlatCAMGrbEditor.py:2804 flatcamGUI/PreferencesUI.py:2542 -#: flatcamGUI/PreferencesUI.py:3617 flatcamGUI/PreferencesUI.py:3712 -#: flatcamGUI/PreferencesUI.py:3765 flatcamGUI/PreferencesUI.py:5853 +#: flatcamEditors/FlatCAMExcEditor.py:1748 +#: flatcamEditors/FlatCAMExcEditor.py:1870 +#: flatcamEditors/FlatCAMExcEditor.py:1963 +#: flatcamEditors/FlatCAMGrbEditor.py:2810 flatcamGUI/PreferencesUI.py:2724 +#: flatcamGUI/PreferencesUI.py:3895 flatcamGUI/PreferencesUI.py:3990 +#: flatcamGUI/PreferencesUI.py:4043 flatcamGUI/PreferencesUI.py:6341 #: flatcamTools/ToolFilm.py:256 msgid "X" msgstr "X" -#: flatcamEditors/FlatCAMExcEditor.py:1746 -#: flatcamEditors/FlatCAMExcEditor.py:1868 -#: flatcamEditors/FlatCAMExcEditor.py:1961 -#: flatcamEditors/FlatCAMGrbEditor.py:2805 flatcamGUI/PreferencesUI.py:2543 -#: flatcamGUI/PreferencesUI.py:3618 flatcamGUI/PreferencesUI.py:3713 -#: flatcamGUI/PreferencesUI.py:3766 flatcamGUI/PreferencesUI.py:5854 +#: flatcamEditors/FlatCAMExcEditor.py:1749 +#: flatcamEditors/FlatCAMExcEditor.py:1871 +#: flatcamEditors/FlatCAMExcEditor.py:1964 +#: flatcamEditors/FlatCAMGrbEditor.py:2811 flatcamGUI/PreferencesUI.py:2725 +#: flatcamGUI/PreferencesUI.py:3896 flatcamGUI/PreferencesUI.py:3991 +#: flatcamGUI/PreferencesUI.py:4044 flatcamGUI/PreferencesUI.py:6342 #: flatcamTools/ToolFilm.py:257 msgid "Y" msgstr "Y" -#: flatcamEditors/FlatCAMExcEditor.py:1747 -#: flatcamEditors/FlatCAMExcEditor.py:1764 -#: flatcamEditors/FlatCAMExcEditor.py:1798 -#: flatcamEditors/FlatCAMExcEditor.py:1869 -#: flatcamEditors/FlatCAMExcEditor.py:1873 -#: flatcamEditors/FlatCAMExcEditor.py:1962 -#: flatcamEditors/FlatCAMExcEditor.py:1980 -#: flatcamEditors/FlatCAMExcEditor.py:2014 -#: flatcamEditors/FlatCAMGrbEditor.py:2806 -#: flatcamEditors/FlatCAMGrbEditor.py:2823 -#: flatcamEditors/FlatCAMGrbEditor.py:2859 flatcamGUI/PreferencesUI.py:2544 -#: flatcamGUI/PreferencesUI.py:2562 flatcamGUI/PreferencesUI.py:3619 -#: flatcamGUI/PreferencesUI.py:3638 flatcamGUI/PreferencesUI.py:3714 -#: flatcamGUI/PreferencesUI.py:3719 flatcamGUI/PreferencesUI.py:3767 -#: flatcamGUI/PreferencesUI.py:3788 flatcamGUI/PreferencesUI.py:6246 -#: flatcamTools/ToolDistance.py:66 flatcamTools/ToolDistanceMin.py:68 -#: flatcamTools/ToolTransform.py:63 +#: flatcamEditors/FlatCAMExcEditor.py:1750 +#: flatcamEditors/FlatCAMExcEditor.py:1767 +#: flatcamEditors/FlatCAMExcEditor.py:1801 +#: flatcamEditors/FlatCAMExcEditor.py:1872 +#: flatcamEditors/FlatCAMExcEditor.py:1876 +#: flatcamEditors/FlatCAMExcEditor.py:1965 +#: flatcamEditors/FlatCAMExcEditor.py:1983 +#: flatcamEditors/FlatCAMExcEditor.py:2017 +#: flatcamEditors/FlatCAMGrbEditor.py:2812 +#: flatcamEditors/FlatCAMGrbEditor.py:2829 +#: flatcamEditors/FlatCAMGrbEditor.py:2865 flatcamGUI/PreferencesUI.py:2726 +#: flatcamGUI/PreferencesUI.py:2744 flatcamGUI/PreferencesUI.py:3897 +#: flatcamGUI/PreferencesUI.py:3916 flatcamGUI/PreferencesUI.py:3992 +#: flatcamGUI/PreferencesUI.py:3997 flatcamGUI/PreferencesUI.py:4045 +#: flatcamGUI/PreferencesUI.py:4066 flatcamGUI/PreferencesUI.py:6733 +#: flatcamTools/ToolDistance.py:120 flatcamTools/ToolDistanceMin.py:69 +#: flatcamTools/ToolTransform.py:61 msgid "Angle" msgstr "Angle" -#: flatcamEditors/FlatCAMExcEditor.py:1751 -#: flatcamEditors/FlatCAMExcEditor.py:1966 -#: flatcamEditors/FlatCAMGrbEditor.py:2810 flatcamGUI/PreferencesUI.py:2550 -#: flatcamGUI/PreferencesUI.py:3625 flatcamGUI/PreferencesUI.py:3773 +#: flatcamEditors/FlatCAMExcEditor.py:1754 +#: flatcamEditors/FlatCAMExcEditor.py:1969 +#: flatcamEditors/FlatCAMGrbEditor.py:2816 flatcamGUI/PreferencesUI.py:2732 +#: flatcamGUI/PreferencesUI.py:3903 flatcamGUI/PreferencesUI.py:4051 msgid "Pitch" msgstr "Pitch" -#: flatcamEditors/FlatCAMExcEditor.py:1753 -#: flatcamEditors/FlatCAMExcEditor.py:1968 -#: flatcamEditors/FlatCAMGrbEditor.py:2812 flatcamGUI/PreferencesUI.py:2552 -#: flatcamGUI/PreferencesUI.py:3627 flatcamGUI/PreferencesUI.py:3775 +#: flatcamEditors/FlatCAMExcEditor.py:1756 +#: flatcamEditors/FlatCAMExcEditor.py:1971 +#: flatcamEditors/FlatCAMGrbEditor.py:2818 flatcamGUI/PreferencesUI.py:2734 +#: flatcamGUI/PreferencesUI.py:3905 flatcamGUI/PreferencesUI.py:4053 msgid "Pitch = Distance between elements of the array." msgstr "Pitch = Distance between elements of the array." -#: flatcamEditors/FlatCAMExcEditor.py:1766 -#: flatcamEditors/FlatCAMExcEditor.py:1982 +#: flatcamEditors/FlatCAMExcEditor.py:1769 +#: flatcamEditors/FlatCAMExcEditor.py:1985 msgid "" "Angle at which the linear array is placed.\n" "The precision is of max 2 decimals.\n" @@ -3285,9 +3743,9 @@ msgstr "" "Min value is: -360 degrees.\n" "Max value is: 360.00 degrees." -#: flatcamEditors/FlatCAMExcEditor.py:1787 -#: flatcamEditors/FlatCAMExcEditor.py:2003 -#: flatcamEditors/FlatCAMGrbEditor.py:2846 +#: flatcamEditors/FlatCAMExcEditor.py:1790 +#: flatcamEditors/FlatCAMExcEditor.py:2006 +#: flatcamEditors/FlatCAMGrbEditor.py:2852 msgid "" "Direction for circular array.Can be CW = clockwise or CCW = counter " "clockwise." @@ -3295,36 +3753,36 @@ msgstr "" "Direction for circular array.Can be CW = clockwise or CCW = counter " "clockwise." -#: flatcamEditors/FlatCAMExcEditor.py:1794 -#: flatcamEditors/FlatCAMExcEditor.py:2010 -#: flatcamEditors/FlatCAMGrbEditor.py:2854 flatcamGUI/PreferencesUI.py:2584 -#: flatcamGUI/PreferencesUI.py:3368 flatcamGUI/PreferencesUI.py:3661 -#: flatcamGUI/PreferencesUI.py:3811 flatcamGUI/PreferencesUI.py:4288 +#: flatcamEditors/FlatCAMExcEditor.py:1797 +#: flatcamEditors/FlatCAMExcEditor.py:2013 +#: flatcamEditors/FlatCAMGrbEditor.py:2860 flatcamGUI/PreferencesUI.py:2766 +#: flatcamGUI/PreferencesUI.py:3646 flatcamGUI/PreferencesUI.py:3939 +#: flatcamGUI/PreferencesUI.py:4089 flatcamGUI/PreferencesUI.py:4581 msgid "CW" msgstr "CW" -#: flatcamEditors/FlatCAMExcEditor.py:1795 -#: flatcamEditors/FlatCAMExcEditor.py:2011 -#: flatcamEditors/FlatCAMGrbEditor.py:2855 flatcamGUI/PreferencesUI.py:2585 -#: flatcamGUI/PreferencesUI.py:3369 flatcamGUI/PreferencesUI.py:3662 -#: flatcamGUI/PreferencesUI.py:3812 flatcamGUI/PreferencesUI.py:4289 +#: flatcamEditors/FlatCAMExcEditor.py:1798 +#: flatcamEditors/FlatCAMExcEditor.py:2014 +#: flatcamEditors/FlatCAMGrbEditor.py:2861 flatcamGUI/PreferencesUI.py:2767 +#: flatcamGUI/PreferencesUI.py:3647 flatcamGUI/PreferencesUI.py:3940 +#: flatcamGUI/PreferencesUI.py:4090 flatcamGUI/PreferencesUI.py:4582 msgid "CCW" msgstr "CCW" -#: flatcamEditors/FlatCAMExcEditor.py:1799 -#: flatcamEditors/FlatCAMExcEditor.py:2015 -#: flatcamEditors/FlatCAMGrbEditor.py:2861 flatcamGUI/PreferencesUI.py:2564 -#: flatcamGUI/PreferencesUI.py:2593 flatcamGUI/PreferencesUI.py:3640 -#: flatcamGUI/PreferencesUI.py:3670 flatcamGUI/PreferencesUI.py:3790 -#: flatcamGUI/PreferencesUI.py:3820 +#: flatcamEditors/FlatCAMExcEditor.py:1802 +#: flatcamEditors/FlatCAMExcEditor.py:2018 +#: flatcamEditors/FlatCAMGrbEditor.py:2867 flatcamGUI/PreferencesUI.py:2746 +#: flatcamGUI/PreferencesUI.py:2775 flatcamGUI/PreferencesUI.py:3918 +#: flatcamGUI/PreferencesUI.py:3948 flatcamGUI/PreferencesUI.py:4068 +#: flatcamGUI/PreferencesUI.py:4098 msgid "Angle at which each element in circular array is placed." msgstr "Angle at which each element in circular array is placed." -#: flatcamEditors/FlatCAMExcEditor.py:1833 +#: flatcamEditors/FlatCAMExcEditor.py:1836 msgid "Slot Parameters" msgstr "Slot Parameters" -#: flatcamEditors/FlatCAMExcEditor.py:1835 +#: flatcamEditors/FlatCAMExcEditor.py:1838 msgid "" "Parameters for adding a slot (hole with oval shape)\n" "either single or as an part of an array." @@ -3332,16 +3790,16 @@ msgstr "" "Parameters for adding a slot (hole with oval shape)\n" "either single or as an part of an array." -#: flatcamEditors/FlatCAMExcEditor.py:1844 flatcamGUI/PreferencesUI.py:3687 -#: flatcamTools/ToolProperties.py:555 +#: flatcamEditors/FlatCAMExcEditor.py:1847 flatcamGUI/PreferencesUI.py:3965 +#: flatcamTools/ToolProperties.py:559 msgid "Length" msgstr "Length" -#: flatcamEditors/FlatCAMExcEditor.py:1846 flatcamGUI/PreferencesUI.py:3689 +#: flatcamEditors/FlatCAMExcEditor.py:1849 flatcamGUI/PreferencesUI.py:3967 msgid "Length = The length of the slot." msgstr "Length = The length of the slot." -#: flatcamEditors/FlatCAMExcEditor.py:1860 flatcamGUI/PreferencesUI.py:3705 +#: flatcamEditors/FlatCAMExcEditor.py:1863 flatcamGUI/PreferencesUI.py:3983 msgid "" "Direction on which the slot is oriented:\n" "- 'X' - horizontal axis \n" @@ -3353,7 +3811,7 @@ msgstr "" "- 'Y' - vertical axis or \n" "- 'Angle' - a custom angle for the slot inclination" -#: flatcamEditors/FlatCAMExcEditor.py:1875 +#: flatcamEditors/FlatCAMExcEditor.py:1878 msgid "" "Angle at which the slot is placed.\n" "The precision is of max 2 decimals.\n" @@ -3365,15 +3823,15 @@ msgstr "" "Min value is: -360 degrees.\n" "Max value is: 360.00 degrees." -#: flatcamEditors/FlatCAMExcEditor.py:1908 +#: flatcamEditors/FlatCAMExcEditor.py:1911 msgid "Slot Array Parameters" msgstr "Slot Array Parameters" -#: flatcamEditors/FlatCAMExcEditor.py:1910 +#: flatcamEditors/FlatCAMExcEditor.py:1913 msgid "Parameters for the array of slots (linear or circular array)" msgstr "Parameters for the array of slots (linear or circular array)" -#: flatcamEditors/FlatCAMExcEditor.py:1919 +#: flatcamEditors/FlatCAMExcEditor.py:1922 msgid "" "Select the type of slot array to create.\n" "It can be Linear X(Y) or Circular" @@ -3381,15 +3839,15 @@ msgstr "" "Select the type of slot array to create.\n" "It can be Linear X(Y) or Circular" -#: flatcamEditors/FlatCAMExcEditor.py:1931 flatcamGUI/PreferencesUI.py:3744 +#: flatcamEditors/FlatCAMExcEditor.py:1934 flatcamGUI/PreferencesUI.py:4022 msgid "Nr of slots" msgstr "Nr of slots" -#: flatcamEditors/FlatCAMExcEditor.py:1932 flatcamGUI/PreferencesUI.py:3746 +#: flatcamEditors/FlatCAMExcEditor.py:1935 flatcamGUI/PreferencesUI.py:4024 msgid "Specify how many slots to be in the array." msgstr "Specify how many slots to be in the array." -#: flatcamEditors/FlatCAMExcEditor.py:2546 +#: flatcamEditors/FlatCAMExcEditor.py:2571 msgid "" "Tool already in the original or actual tool list.\n" "Save and reedit Excellon if you need to add this tool. " @@ -3397,50 +3855,50 @@ msgstr "" "Tool already in the original or actual tool list.\n" "Save and reedit Excellon if you need to add this tool. " -#: flatcamEditors/FlatCAMExcEditor.py:2555 flatcamGUI/FlatCAMGUI.py:3792 +#: flatcamEditors/FlatCAMExcEditor.py:2580 flatcamGUI/FlatCAMGUI.py:4009 msgid "Added new tool with dia" msgstr "Added new tool with dia" -#: flatcamEditors/FlatCAMExcEditor.py:2589 +#: flatcamEditors/FlatCAMExcEditor.py:2613 msgid "Select a tool in Tool Table" msgstr "Select a tool in Tool Table" -#: flatcamEditors/FlatCAMExcEditor.py:2622 +#: flatcamEditors/FlatCAMExcEditor.py:2643 msgid "Deleted tool with diameter" msgstr "Deleted tool with diameter" -#: flatcamEditors/FlatCAMExcEditor.py:2772 +#: flatcamEditors/FlatCAMExcEditor.py:2793 msgid "Done. Tool edit completed." msgstr "Done. Tool edit completed." -#: flatcamEditors/FlatCAMExcEditor.py:3324 +#: flatcamEditors/FlatCAMExcEditor.py:3350 msgid "There are no Tools definitions in the file. Aborting Excellon creation." msgstr "" "There are no Tools definitions in the file. Aborting Excellon creation." -#: flatcamEditors/FlatCAMExcEditor.py:3328 +#: flatcamEditors/FlatCAMExcEditor.py:3354 msgid "An internal error has ocurred. See Shell.\n" msgstr "An internal error has ocurred. See Shell.\n" -#: flatcamEditors/FlatCAMExcEditor.py:3333 +#: flatcamEditors/FlatCAMExcEditor.py:3359 msgid "Creating Excellon." msgstr "Creating Excellon." -#: flatcamEditors/FlatCAMExcEditor.py:3347 +#: flatcamEditors/FlatCAMExcEditor.py:3371 msgid "Excellon editing finished." msgstr "Excellon editing finished." -#: flatcamEditors/FlatCAMExcEditor.py:3365 +#: flatcamEditors/FlatCAMExcEditor.py:3388 msgid "Cancelled. There is no Tool/Drill selected" msgstr "Cancelled. There is no Tool/Drill selected" -#: flatcamEditors/FlatCAMExcEditor.py:3978 +#: flatcamEditors/FlatCAMExcEditor.py:4001 msgid "Done. Drill(s) deleted." msgstr "Done. Drill(s) deleted." -#: flatcamEditors/FlatCAMExcEditor.py:4051 -#: flatcamEditors/FlatCAMExcEditor.py:4061 -#: flatcamEditors/FlatCAMGrbEditor.py:4853 +#: flatcamEditors/FlatCAMExcEditor.py:4074 +#: flatcamEditors/FlatCAMExcEditor.py:4084 +#: flatcamEditors/FlatCAMGrbEditor.py:4897 msgid "Click on the circular array Center position" msgstr "Click on the circular array Center position" @@ -3467,18 +3925,24 @@ msgstr "" "meeting in the corner" #: flatcamEditors/FlatCAMGeoEditor.py:95 -#: flatcamEditors/FlatCAMGrbEditor.py:2622 +#: flatcamEditors/FlatCAMGrbEditor.py:2628 msgid "Round" msgstr "Round" #: flatcamEditors/FlatCAMGeoEditor.py:96 -#: flatcamEditors/FlatCAMGrbEditor.py:2623 flatcamGUI/PreferencesUI.py:7058 +#: flatcamEditors/FlatCAMGrbEditor.py:2629 flatcamGUI/PreferencesUI.py:5606 +#: flatcamGUI/PreferencesUI.py:6130 flatcamGUI/PreferencesUI.py:7564 +#: flatcamGUI/PreferencesUI.py:8167 flatcamGUI/PreferencesUI.py:8274 +#: flatcamGUI/PreferencesUI.py:8379 flatcamGUI/PreferencesUI.py:8488 +#: flatcamTools/ToolExtractDrills.py:94 flatcamTools/ToolExtractDrills.py:227 +#: flatcamTools/ToolNCC.py:583 flatcamTools/ToolPaint.py:527 +#: flatcamTools/ToolPunchGerber.py:105 flatcamTools/ToolPunchGerber.py:255 #: flatcamTools/ToolQRCode.py:198 msgid "Square" msgstr "Square" #: flatcamEditors/FlatCAMGeoEditor.py:97 -#: flatcamEditors/FlatCAMGrbEditor.py:2624 +#: flatcamEditors/FlatCAMGrbEditor.py:2630 msgid "Beveled" msgstr "Beveled" @@ -3495,18 +3959,18 @@ msgid "Full Buffer" msgstr "Full Buffer" #: flatcamEditors/FlatCAMGeoEditor.py:133 -#: flatcamEditors/FlatCAMGeoEditor.py:2885 flatcamGUI/FlatCAMGUI.py:1805 -#: flatcamGUI/PreferencesUI.py:2604 +#: flatcamEditors/FlatCAMGeoEditor.py:3018 flatcamGUI/FlatCAMGUI.py:1913 +#: flatcamGUI/PreferencesUI.py:2786 msgid "Buffer Tool" msgstr "Buffer Tool" #: flatcamEditors/FlatCAMGeoEditor.py:145 #: flatcamEditors/FlatCAMGeoEditor.py:162 #: flatcamEditors/FlatCAMGeoEditor.py:179 -#: flatcamEditors/FlatCAMGeoEditor.py:2904 -#: flatcamEditors/FlatCAMGeoEditor.py:2934 -#: flatcamEditors/FlatCAMGeoEditor.py:2964 -#: flatcamEditors/FlatCAMGrbEditor.py:4906 +#: flatcamEditors/FlatCAMGeoEditor.py:3037 +#: flatcamEditors/FlatCAMGeoEditor.py:3065 +#: flatcamEditors/FlatCAMGeoEditor.py:3093 +#: flatcamEditors/FlatCAMGrbEditor.py:4950 msgid "Buffer distance value is missing or wrong format. Add it and retry." msgstr "Buffer distance value is missing or wrong format. Add it and retry." @@ -3514,7 +3978,7 @@ msgstr "Buffer distance value is missing or wrong format. Add it and retry." msgid "Font" msgstr "Font" -#: flatcamEditors/FlatCAMGeoEditor.py:324 flatcamGUI/FlatCAMGUI.py:2085 +#: flatcamEditors/FlatCAMGeoEditor.py:324 flatcamGUI/FlatCAMGUI.py:2193 msgid "Text" msgstr "Text" @@ -3522,207 +3986,121 @@ msgstr "Text" msgid "Text Tool" msgstr "Text Tool" -#: flatcamEditors/FlatCAMGeoEditor.py:442 flatcamGUI/ObjectUI.py:359 -#: flatcamGUI/PreferencesUI.py:2025 flatcamGUI/PreferencesUI.py:3875 -#: flatcamGUI/PreferencesUI.py:5535 +#: flatcamEditors/FlatCAMGeoEditor.py:440 flatcamGUI/ObjectUI.py:363 +#: flatcamGUI/PreferencesUI.py:2205 msgid "Tool dia" msgstr "Tool dia" -#: flatcamEditors/FlatCAMGeoEditor.py:444 flatcamGUI/PreferencesUI.py:5537 +#: flatcamEditors/FlatCAMGeoEditor.py:442 +#| msgid "" +#| "Diameter of the tool to\n" +#| "be used in the operation." +msgid "Diameter of the tool to be used in the operation." +msgstr "Diameter of the tool to be used in the operation." + +#: flatcamEditors/FlatCAMGeoEditor.py:488 +#| msgid "" +#| "Algorithm for painting:\n" +#| "- Standard: Fixed step inwards.\n" +#| "- Seed-based: Outwards from seed.\n" +#| "- Line-based: Parallel lines." msgid "" -"Diameter of the tool to\n" -"be used in the operation." +"Algorithm to paint the polygons:\n" +"- Standard: Fixed step inwards.\n" +"- Seed-based: Outwards from seed.\n" +"- Line-based: Parallel lines." msgstr "" -"Diameter of the tool to\n" -"be used in the operation." +"Algorithm to paint the polygons:\n" +"- Standard: Fixed step inwards.\n" +"- Seed-based: Outwards from seed.\n" +"- Line-based: Parallel lines." -#: flatcamEditors/FlatCAMGeoEditor.py:455 flatcamGUI/PreferencesUI.py:5152 -#: flatcamGUI/PreferencesUI.py:5567 flatcamTools/ToolNonCopperClear.py:319 -#: flatcamTools/ToolPaint.py:219 -msgid "Overlap Rate" -msgstr "Overlap Rate" - -#: flatcamEditors/FlatCAMGeoEditor.py:457 flatcamGUI/PreferencesUI.py:5569 -#: flatcamTools/ToolPaint.py:221 -msgid "" -"How much (fraction) of the tool width to overlap each tool pass.\n" -"Adjust the value starting with lower values\n" -"and increasing it if areas that should be painted are still \n" -"not painted.\n" -"Lower values = faster processing, faster execution on CNC.\n" -"Higher values = slow processing and slow execution on CNC\n" -"due of too many paths." -msgstr "" -"How much (fraction) of the tool width to overlap each tool pass.\n" -"Adjust the value starting with lower values\n" -"and increasing it if areas that should be painted are still \n" -"not painted.\n" -"Lower values = faster processing, faster execution on CNC.\n" -"Higher values = slow processing and slow execution on CNC\n" -"due of too many paths." - -#: flatcamEditors/FlatCAMGeoEditor.py:475 flatcamGUI/PreferencesUI.py:5171 -#: flatcamGUI/PreferencesUI.py:5384 flatcamGUI/PreferencesUI.py:5587 -#: flatcamGUI/PreferencesUI.py:7175 flatcamGUI/PreferencesUI.py:7332 -#: flatcamGUI/PreferencesUI.py:7417 flatcamTools/ToolCopperThieving.py:111 -#: flatcamTools/ToolCopperThieving.py:361 flatcamTools/ToolCutOut.py:184 -#: flatcamTools/ToolFiducials.py:172 flatcamTools/ToolNonCopperClear.py:337 -#: flatcamTools/ToolPaint.py:238 -msgid "Margin" -msgstr "Margin" - -#: flatcamEditors/FlatCAMGeoEditor.py:477 flatcamGUI/PreferencesUI.py:5589 -#: flatcamTools/ToolPaint.py:240 -msgid "" -"Distance by which to avoid\n" -"the edges of the polygon to\n" -"be painted." -msgstr "" -"Distance by which to avoid\n" -"the edges of the polygon to\n" -"be painted." - -#: flatcamEditors/FlatCAMGeoEditor.py:489 flatcamGUI/PreferencesUI.py:5184 -#: flatcamGUI/PreferencesUI.py:5602 flatcamTools/ToolNonCopperClear.py:348 -#: flatcamTools/ToolPaint.py:251 -msgid "Method" -msgstr "Method" - -#: flatcamEditors/FlatCAMGeoEditor.py:491 -msgid "" -"Algorithm to paint the polygon:
Standard: Fixed step inwards." -"
Seed-based: Outwards from seed." -msgstr "" -"Algorithm to paint the polygon:
Standard: Fixed step inwards." -"
Seed-based: Outwards from seed." - -#: flatcamEditors/FlatCAMGeoEditor.py:496 flatcamGUI/PreferencesUI.py:5193 -#: flatcamGUI/PreferencesUI.py:5611 flatcamTools/ToolNonCopperClear.py:357 -#: flatcamTools/ToolPaint.py:260 -msgid "Standard" -msgstr "Standard" - -#: flatcamEditors/FlatCAMGeoEditor.py:497 flatcamGUI/PreferencesUI.py:5194 -#: flatcamGUI/PreferencesUI.py:5612 flatcamTools/ToolNonCopperClear.py:358 -#: flatcamTools/ToolPaint.py:261 -msgid "Seed-based" -msgstr "Seed-based" - -#: flatcamEditors/FlatCAMGeoEditor.py:498 flatcamGUI/PreferencesUI.py:5195 -#: flatcamGUI/PreferencesUI.py:5613 flatcamTools/ToolNonCopperClear.py:359 -#: flatcamTools/ToolPaint.py:262 -msgid "Straight lines" -msgstr "Straight lines" - -#: flatcamEditors/FlatCAMGeoEditor.py:505 +#: flatcamEditors/FlatCAMGeoEditor.py:507 msgid "Connect:" msgstr "Connect:" -#: flatcamEditors/FlatCAMGeoEditor.py:507 flatcamGUI/PreferencesUI.py:5204 -#: flatcamGUI/PreferencesUI.py:5620 flatcamTools/ToolNonCopperClear.py:366 -#: flatcamTools/ToolPaint.py:269 -msgid "" -"Draw lines between resulting\n" -"segments to minimize tool lifts." -msgstr "" -"Draw lines between resulting\n" -"segments to minimize tool lifts." - -#: flatcamEditors/FlatCAMGeoEditor.py:515 +#: flatcamEditors/FlatCAMGeoEditor.py:517 msgid "Contour:" msgstr "Contour:" -#: flatcamEditors/FlatCAMGeoEditor.py:517 flatcamGUI/PreferencesUI.py:5213 -#: flatcamGUI/PreferencesUI.py:5628 flatcamTools/ToolNonCopperClear.py:373 -#: flatcamTools/ToolPaint.py:276 -msgid "" -"Cut around the perimeter of the polygon\n" -"to trim rough edges." -msgstr "" -"Cut around the perimeter of the polygon\n" -"to trim rough edges." - -#: flatcamEditors/FlatCAMGeoEditor.py:529 flatcamGUI/FlatCAMGUI.py:2089 +#: flatcamEditors/FlatCAMGeoEditor.py:530 flatcamGUI/FlatCAMGUI.py:2197 msgid "Paint" msgstr "Paint" -#: flatcamEditors/FlatCAMGeoEditor.py:547 flatcamGUI/FlatCAMGUI.py:845 -#: flatcamGUI/FlatCAMGUI.py:2423 flatcamGUI/ObjectUI.py:1731 -#: flatcamTools/ToolPaint.py:41 flatcamTools/ToolPaint.py:533 +#: flatcamEditors/FlatCAMGeoEditor.py:548 flatcamGUI/FlatCAMGUI.py:909 +#: flatcamGUI/FlatCAMGUI.py:2588 flatcamGUI/ObjectUI.py:2057 +#: flatcamTools/ToolPaint.py:43 flatcamTools/ToolPaint.py:735 msgid "Paint Tool" msgstr "Paint Tool" #: flatcamEditors/FlatCAMGeoEditor.py:584 -msgid "Paint cancelled. No shape selected." -msgstr "Paint cancelled. No shape selected." +#: flatcamEditors/FlatCAMGeoEditor.py:1056 +#: flatcamEditors/FlatCAMGeoEditor.py:3025 +#: flatcamEditors/FlatCAMGeoEditor.py:3053 +#: flatcamEditors/FlatCAMGeoEditor.py:3081 +#: flatcamEditors/FlatCAMGeoEditor.py:4502 +#: flatcamEditors/FlatCAMGrbEditor.py:5601 +#| msgid "Copy cancelled. No shape selected." +msgid "Cancelled. No shape selected." +msgstr "Cancelled. No shape selected." #: flatcamEditors/FlatCAMGeoEditor.py:597 -#: flatcamEditors/FlatCAMGeoEditor.py:2910 -#: flatcamEditors/FlatCAMGeoEditor.py:2940 -#: flatcamEditors/FlatCAMGeoEditor.py:2970 flatcamGUI/PreferencesUI.py:3871 -#: flatcamTools/ToolProperties.py:120 flatcamTools/ToolProperties.py:158 +#: flatcamEditors/FlatCAMGeoEditor.py:3043 +#: flatcamEditors/FlatCAMGeoEditor.py:3071 +#: flatcamEditors/FlatCAMGeoEditor.py:3099 flatcamGUI/PreferencesUI.py:4149 +#: flatcamTools/ToolProperties.py:117 flatcamTools/ToolProperties.py:162 msgid "Tools" msgstr "Tools" #: flatcamEditors/FlatCAMGeoEditor.py:608 #: flatcamEditors/FlatCAMGeoEditor.py:992 -#: flatcamEditors/FlatCAMGrbEditor.py:5096 -#: flatcamEditors/FlatCAMGrbEditor.py:5493 flatcamGUI/FlatCAMGUI.py:866 -#: flatcamGUI/FlatCAMGUI.py:2441 flatcamTools/ToolTransform.py:422 +#: flatcamEditors/FlatCAMGrbEditor.py:5140 +#: flatcamEditors/FlatCAMGrbEditor.py:5537 flatcamGUI/FlatCAMGUI.py:930 +#: flatcamGUI/FlatCAMGUI.py:2609 flatcamTools/ToolTransform.py:461 msgid "Transform Tool" msgstr "Transform Tool" #: flatcamEditors/FlatCAMGeoEditor.py:609 #: flatcamEditors/FlatCAMGeoEditor.py:674 -#: flatcamEditors/FlatCAMGrbEditor.py:5097 -#: flatcamEditors/FlatCAMGrbEditor.py:5162 flatcamGUI/PreferencesUI.py:6238 -#: flatcamTools/ToolTransform.py:25 flatcamTools/ToolTransform.py:80 +#: flatcamEditors/FlatCAMGrbEditor.py:5141 +#: flatcamEditors/FlatCAMGrbEditor.py:5206 flatcamGUI/PreferencesUI.py:6725 +#: flatcamTools/ToolTransform.py:25 flatcamTools/ToolTransform.py:467 msgid "Rotate" msgstr "Rotate" #: flatcamEditors/FlatCAMGeoEditor.py:610 -#: flatcamEditors/FlatCAMGrbEditor.py:5098 flatcamTools/ToolTransform.py:26 +#: flatcamEditors/FlatCAMGrbEditor.py:5142 flatcamTools/ToolTransform.py:26 msgid "Skew/Shear" msgstr "Skew/Shear" #: flatcamEditors/FlatCAMGeoEditor.py:611 -#: flatcamEditors/FlatCAMGrbEditor.py:2671 -#: flatcamEditors/FlatCAMGrbEditor.py:5099 flatcamGUI/FlatCAMGUI.py:980 -#: flatcamGUI/FlatCAMGUI.py:2017 flatcamGUI/FlatCAMGUI.py:2132 -#: flatcamGUI/FlatCAMGUI.py:2549 flatcamGUI/ObjectUI.py:103 -#: flatcamGUI/ObjectUI.py:121 flatcamGUI/PreferencesUI.py:6288 -#: flatcamTools/ToolTransform.py:27 +#: flatcamEditors/FlatCAMGrbEditor.py:2677 +#: flatcamEditors/FlatCAMGrbEditor.py:5143 flatcamGUI/FlatCAMGUI.py:1048 +#: flatcamGUI/FlatCAMGUI.py:2125 flatcamGUI/FlatCAMGUI.py:2240 +#: flatcamGUI/FlatCAMGUI.py:2723 flatcamGUI/ObjectUI.py:124 +#: flatcamGUI/PreferencesUI.py:6775 flatcamTools/ToolTransform.py:27 msgid "Scale" msgstr "Scale" #: flatcamEditors/FlatCAMGeoEditor.py:612 -#: flatcamEditors/FlatCAMGrbEditor.py:5100 flatcamTools/ToolTransform.py:28 +#: flatcamEditors/FlatCAMGrbEditor.py:5144 flatcamTools/ToolTransform.py:28 msgid "Mirror (Flip)" msgstr "Mirror (Flip)" -#: flatcamEditors/FlatCAMGeoEditor.py:613 -#: flatcamEditors/FlatCAMGrbEditor.py:5101 flatcamGUI/ObjectUI.py:132 -#: flatcamGUI/ObjectUI.py:148 flatcamGUI/ObjectUI.py:1217 -#: flatcamGUI/ObjectUI.py:1916 flatcamGUI/PreferencesUI.py:5234 -#: flatcamGUI/PreferencesUI.py:6335 flatcamTools/ToolNonCopperClear.py:393 -#: flatcamTools/ToolTransform.py:29 -msgid "Offset" -msgstr "Offset" - #: flatcamEditors/FlatCAMGeoEditor.py:626 -#: flatcamEditors/FlatCAMGrbEditor.py:5114 flatcamGUI/FlatCAMGUI.py:787 -#: flatcamGUI/FlatCAMGUI.py:2370 +#: flatcamEditors/FlatCAMGrbEditor.py:5158 flatcamGUI/FlatCAMGUI.py:841 +#: flatcamGUI/FlatCAMGUI.py:2524 msgid "Editor" msgstr "Editor" #: flatcamEditors/FlatCAMGeoEditor.py:658 -#: flatcamEditors/FlatCAMGrbEditor.py:5146 +#: flatcamEditors/FlatCAMGrbEditor.py:5190 msgid "Angle:" msgstr "Angle:" #: flatcamEditors/FlatCAMGeoEditor.py:660 -#: flatcamEditors/FlatCAMGrbEditor.py:5148 flatcamGUI/PreferencesUI.py:6248 -#: flatcamTools/ToolTransform.py:65 +#: flatcamEditors/FlatCAMGrbEditor.py:5192 flatcamGUI/PreferencesUI.py:6735 +#: flatcamTools/ToolTransform.py:63 msgid "" "Angle for Rotation action, in degrees.\n" "Float number between -360 and 359.\n" @@ -3735,7 +4113,7 @@ msgstr "" "Negative numbers for CCW motion." #: flatcamEditors/FlatCAMGeoEditor.py:676 -#: flatcamEditors/FlatCAMGrbEditor.py:5164 +#: flatcamEditors/FlatCAMGrbEditor.py:5208 msgid "" "Rotate the selected shape(s).\n" "The point of reference is the middle of\n" @@ -3746,16 +4124,16 @@ msgstr "" "the bounding box for all selected shapes." #: flatcamEditors/FlatCAMGeoEditor.py:699 -#: flatcamEditors/FlatCAMGrbEditor.py:5187 +#: flatcamEditors/FlatCAMGrbEditor.py:5231 msgid "Angle X:" msgstr "Angle X:" #: flatcamEditors/FlatCAMGeoEditor.py:701 #: flatcamEditors/FlatCAMGeoEditor.py:721 -#: flatcamEditors/FlatCAMGrbEditor.py:5189 -#: flatcamEditors/FlatCAMGrbEditor.py:5209 flatcamGUI/PreferencesUI.py:6267 -#: flatcamGUI/PreferencesUI.py:6281 flatcamTools/ToolCalibration.py:508 -#: flatcamTools/ToolCalibration.py:521 +#: flatcamEditors/FlatCAMGrbEditor.py:5233 +#: flatcamEditors/FlatCAMGrbEditor.py:5253 flatcamGUI/PreferencesUI.py:6754 +#: flatcamGUI/PreferencesUI.py:6768 flatcamTools/ToolCalibration.py:505 +#: flatcamTools/ToolCalibration.py:518 msgid "" "Angle for Skew action, in degrees.\n" "Float number between -360 and 359." @@ -3764,14 +4142,14 @@ msgstr "" "Float number between -360 and 359." #: flatcamEditors/FlatCAMGeoEditor.py:712 -#: flatcamEditors/FlatCAMGrbEditor.py:5200 flatcamTools/ToolTransform.py:109 +#: flatcamEditors/FlatCAMGrbEditor.py:5244 flatcamTools/ToolTransform.py:468 msgid "Skew X" msgstr "Skew X" #: flatcamEditors/FlatCAMGeoEditor.py:714 #: flatcamEditors/FlatCAMGeoEditor.py:734 -#: flatcamEditors/FlatCAMGrbEditor.py:5202 -#: flatcamEditors/FlatCAMGrbEditor.py:5222 +#: flatcamEditors/FlatCAMGrbEditor.py:5246 +#: flatcamEditors/FlatCAMGrbEditor.py:5266 msgid "" "Skew/shear the selected shape(s).\n" "The point of reference is the middle of\n" @@ -3782,34 +4160,34 @@ msgstr "" "the bounding box for all selected shapes." #: flatcamEditors/FlatCAMGeoEditor.py:719 -#: flatcamEditors/FlatCAMGrbEditor.py:5207 +#: flatcamEditors/FlatCAMGrbEditor.py:5251 msgid "Angle Y:" msgstr "Angle Y:" #: flatcamEditors/FlatCAMGeoEditor.py:732 -#: flatcamEditors/FlatCAMGrbEditor.py:5220 flatcamTools/ToolTransform.py:131 +#: flatcamEditors/FlatCAMGrbEditor.py:5264 flatcamTools/ToolTransform.py:469 msgid "Skew Y" msgstr "Skew Y" #: flatcamEditors/FlatCAMGeoEditor.py:760 -#: flatcamEditors/FlatCAMGrbEditor.py:5248 +#: flatcamEditors/FlatCAMGrbEditor.py:5292 msgid "Factor X:" msgstr "Factor X:" #: flatcamEditors/FlatCAMGeoEditor.py:762 -#: flatcamEditors/FlatCAMGrbEditor.py:5250 flatcamTools/ToolCalibration.py:472 +#: flatcamEditors/FlatCAMGrbEditor.py:5294 flatcamTools/ToolCalibration.py:469 msgid "Factor for Scale action over X axis." msgstr "Factor for Scale action over X axis." #: flatcamEditors/FlatCAMGeoEditor.py:772 -#: flatcamEditors/FlatCAMGrbEditor.py:5260 flatcamTools/ToolTransform.py:158 +#: flatcamEditors/FlatCAMGrbEditor.py:5304 flatcamTools/ToolTransform.py:470 msgid "Scale X" msgstr "Scale X" #: flatcamEditors/FlatCAMGeoEditor.py:774 #: flatcamEditors/FlatCAMGeoEditor.py:793 -#: flatcamEditors/FlatCAMGrbEditor.py:5262 -#: flatcamEditors/FlatCAMGrbEditor.py:5281 +#: flatcamEditors/FlatCAMGrbEditor.py:5306 +#: flatcamEditors/FlatCAMGrbEditor.py:5325 msgid "" "Scale the selected shape(s).\n" "The point of reference depends on \n" @@ -3820,28 +4198,28 @@ msgstr "" "the Scale reference checkbox state." #: flatcamEditors/FlatCAMGeoEditor.py:779 -#: flatcamEditors/FlatCAMGrbEditor.py:5267 +#: flatcamEditors/FlatCAMGrbEditor.py:5311 msgid "Factor Y:" msgstr "Factor Y:" #: flatcamEditors/FlatCAMGeoEditor.py:781 -#: flatcamEditors/FlatCAMGrbEditor.py:5269 flatcamTools/ToolCalibration.py:484 +#: flatcamEditors/FlatCAMGrbEditor.py:5313 flatcamTools/ToolCalibration.py:481 msgid "Factor for Scale action over Y axis." msgstr "Factor for Scale action over Y axis." #: flatcamEditors/FlatCAMGeoEditor.py:791 -#: flatcamEditors/FlatCAMGrbEditor.py:5279 flatcamTools/ToolTransform.py:179 +#: flatcamEditors/FlatCAMGrbEditor.py:5323 flatcamTools/ToolTransform.py:471 msgid "Scale Y" msgstr "Scale Y" #: flatcamEditors/FlatCAMGeoEditor.py:800 -#: flatcamEditors/FlatCAMGrbEditor.py:5288 flatcamGUI/PreferencesUI.py:6317 -#: flatcamTools/ToolTransform.py:192 +#: flatcamEditors/FlatCAMGrbEditor.py:5332 flatcamGUI/PreferencesUI.py:6804 +#: flatcamTools/ToolTransform.py:190 msgid "Link" msgstr "Link" #: flatcamEditors/FlatCAMGeoEditor.py:802 -#: flatcamEditors/FlatCAMGrbEditor.py:5290 +#: flatcamEditors/FlatCAMGrbEditor.py:5334 msgid "" "Scale the selected shape(s)\n" "using the Scale Factor X for both axis." @@ -3850,13 +4228,13 @@ msgstr "" "using the Scale Factor X for both axis." #: flatcamEditors/FlatCAMGeoEditor.py:808 -#: flatcamEditors/FlatCAMGrbEditor.py:5296 flatcamGUI/PreferencesUI.py:6325 -#: flatcamTools/ToolTransform.py:200 +#: flatcamEditors/FlatCAMGrbEditor.py:5340 flatcamGUI/PreferencesUI.py:6812 +#: flatcamTools/ToolTransform.py:197 msgid "Scale Reference" msgstr "Scale Reference" #: flatcamEditors/FlatCAMGeoEditor.py:810 -#: flatcamEditors/FlatCAMGrbEditor.py:5298 +#: flatcamEditors/FlatCAMGrbEditor.py:5342 msgid "" "Scale the selected shape(s)\n" "using the origin reference when checked,\n" @@ -3869,24 +4247,24 @@ msgstr "" "of the selected shapes when unchecked." #: flatcamEditors/FlatCAMGeoEditor.py:838 -#: flatcamEditors/FlatCAMGrbEditor.py:5327 +#: flatcamEditors/FlatCAMGrbEditor.py:5371 msgid "Value X:" msgstr "Value X:" #: flatcamEditors/FlatCAMGeoEditor.py:840 -#: flatcamEditors/FlatCAMGrbEditor.py:5329 +#: flatcamEditors/FlatCAMGrbEditor.py:5373 msgid "Value for Offset action on X axis." msgstr "Value for Offset action on X axis." #: flatcamEditors/FlatCAMGeoEditor.py:850 -#: flatcamEditors/FlatCAMGrbEditor.py:5339 flatcamTools/ToolTransform.py:227 +#: flatcamEditors/FlatCAMGrbEditor.py:5383 flatcamTools/ToolTransform.py:474 msgid "Offset X" msgstr "Offset X" #: flatcamEditors/FlatCAMGeoEditor.py:852 #: flatcamEditors/FlatCAMGeoEditor.py:872 -#: flatcamEditors/FlatCAMGrbEditor.py:5341 -#: flatcamEditors/FlatCAMGrbEditor.py:5361 +#: flatcamEditors/FlatCAMGrbEditor.py:5385 +#: flatcamEditors/FlatCAMGrbEditor.py:5405 msgid "" "Offset the selected shape(s).\n" "The point of reference is the middle of\n" @@ -3897,29 +4275,29 @@ msgstr "" "the bounding box for all selected shapes.\n" #: flatcamEditors/FlatCAMGeoEditor.py:858 -#: flatcamEditors/FlatCAMGrbEditor.py:5347 +#: flatcamEditors/FlatCAMGrbEditor.py:5391 msgid "Value Y:" msgstr "Value Y:" #: flatcamEditors/FlatCAMGeoEditor.py:860 -#: flatcamEditors/FlatCAMGrbEditor.py:5349 +#: flatcamEditors/FlatCAMGrbEditor.py:5393 msgid "Value for Offset action on Y axis." msgstr "Value for Offset action on Y axis." #: flatcamEditors/FlatCAMGeoEditor.py:870 -#: flatcamEditors/FlatCAMGrbEditor.py:5359 flatcamTools/ToolTransform.py:248 +#: flatcamEditors/FlatCAMGrbEditor.py:5403 flatcamTools/ToolTransform.py:475 msgid "Offset Y" msgstr "Offset Y" #: flatcamEditors/FlatCAMGeoEditor.py:901 -#: flatcamEditors/FlatCAMGrbEditor.py:5390 flatcamTools/ToolTransform.py:266 +#: flatcamEditors/FlatCAMGrbEditor.py:5434 flatcamTools/ToolTransform.py:476 msgid "Flip on X" msgstr "Flip on X" #: flatcamEditors/FlatCAMGeoEditor.py:903 #: flatcamEditors/FlatCAMGeoEditor.py:910 -#: flatcamEditors/FlatCAMGrbEditor.py:5392 -#: flatcamEditors/FlatCAMGrbEditor.py:5399 +#: flatcamEditors/FlatCAMGrbEditor.py:5436 +#: flatcamEditors/FlatCAMGrbEditor.py:5443 msgid "" "Flip the selected shape(s) over the X axis.\n" "Does not create a new shape." @@ -3928,17 +4306,17 @@ msgstr "" "Does not create a new shape." #: flatcamEditors/FlatCAMGeoEditor.py:908 -#: flatcamEditors/FlatCAMGrbEditor.py:5397 flatcamTools/ToolTransform.py:272 +#: flatcamEditors/FlatCAMGrbEditor.py:5441 flatcamTools/ToolTransform.py:477 msgid "Flip on Y" msgstr "Flip on Y" #: flatcamEditors/FlatCAMGeoEditor.py:916 -#: flatcamEditors/FlatCAMGrbEditor.py:5405 +#: flatcamEditors/FlatCAMGrbEditor.py:5449 msgid "Ref Pt" msgstr "Ref Pt" #: flatcamEditors/FlatCAMGeoEditor.py:918 -#: flatcamEditors/FlatCAMGrbEditor.py:5407 +#: flatcamEditors/FlatCAMGrbEditor.py:5451 msgid "" "Flip the selected shape(s)\n" "around the point in Point Entry Field.\n" @@ -3961,12 +4339,12 @@ msgstr "" "Point Entry field and click Flip on X(Y)" #: flatcamEditors/FlatCAMGeoEditor.py:930 -#: flatcamEditors/FlatCAMGrbEditor.py:5419 +#: flatcamEditors/FlatCAMGrbEditor.py:5463 msgid "Point:" msgstr "Point:" #: flatcamEditors/FlatCAMGeoEditor.py:932 -#: flatcamEditors/FlatCAMGrbEditor.py:5421 flatcamTools/ToolTransform.py:301 +#: flatcamEditors/FlatCAMGrbEditor.py:5465 flatcamTools/ToolTransform.py:300 msgid "" "Coordinates in format (x, y) used as reference for mirroring.\n" "The 'x' in (x, y) will be used when using Flip on X and\n" @@ -3977,7 +4355,7 @@ msgstr "" "the 'y' in (x, y) will be used when using Flip on Y." #: flatcamEditors/FlatCAMGeoEditor.py:942 -#: flatcamEditors/FlatCAMGrbEditor.py:5433 flatcamTools/ToolTransform.py:312 +#: flatcamEditors/FlatCAMGrbEditor.py:5477 flatcamTools/ToolTransform.py:310 msgid "" "The point coordinates can be captured by\n" "left click on canvas together with pressing\n" @@ -3987,347 +4365,347 @@ msgstr "" "left click on canvas together with pressing\n" "SHIFT key. Then click Add button to insert." -#: flatcamEditors/FlatCAMGeoEditor.py:1057 -#: flatcamEditors/FlatCAMGrbEditor.py:5558 -msgid "Transformation cancelled. No shape selected." -msgstr "Transformation cancelled. No shape selected." - -#: flatcamEditors/FlatCAMGeoEditor.py:1258 -#: flatcamEditors/FlatCAMGrbEditor.py:5742 +#: flatcamEditors/FlatCAMGeoEditor.py:1305 +#: flatcamEditors/FlatCAMGrbEditor.py:5785 msgid "No shape selected. Please Select a shape to rotate!" msgstr "No shape selected. Please Select a shape to rotate!" -#: flatcamEditors/FlatCAMGeoEditor.py:1261 -#: flatcamEditors/FlatCAMGrbEditor.py:5745 flatcamTools/ToolTransform.py:611 +#: flatcamEditors/FlatCAMGeoEditor.py:1308 +#: flatcamEditors/FlatCAMGrbEditor.py:5788 flatcamTools/ToolTransform.py:680 msgid "Appying Rotate" msgstr "Appying Rotate" -#: flatcamEditors/FlatCAMGeoEditor.py:1290 -#: flatcamEditors/FlatCAMGrbEditor.py:5779 +#: flatcamEditors/FlatCAMGeoEditor.py:1334 +#: flatcamEditors/FlatCAMGrbEditor.py:5820 msgid "Done. Rotate completed." msgstr "Done. Rotate completed." -#: flatcamEditors/FlatCAMGeoEditor.py:1295 +#: flatcamEditors/FlatCAMGeoEditor.py:1336 msgid "Rotation action was not executed" msgstr "Rotation action was not executed" -#: flatcamEditors/FlatCAMGeoEditor.py:1307 -#: flatcamEditors/FlatCAMGrbEditor.py:5800 +#: flatcamEditors/FlatCAMGeoEditor.py:1355 +#: flatcamEditors/FlatCAMGrbEditor.py:5839 msgid "No shape selected. Please Select a shape to flip!" msgstr "No shape selected. Please Select a shape to flip!" -#: flatcamEditors/FlatCAMGeoEditor.py:1310 -#: flatcamEditors/FlatCAMGrbEditor.py:5803 flatcamTools/ToolTransform.py:664 +#: flatcamEditors/FlatCAMGeoEditor.py:1358 +#: flatcamEditors/FlatCAMGrbEditor.py:5842 flatcamTools/ToolTransform.py:729 msgid "Applying Flip" msgstr "Applying Flip" -#: flatcamEditors/FlatCAMGeoEditor.py:1341 -#: flatcamEditors/FlatCAMGrbEditor.py:5843 flatcamTools/ToolTransform.py:707 +#: flatcamEditors/FlatCAMGeoEditor.py:1387 +#: flatcamEditors/FlatCAMGrbEditor.py:5880 flatcamTools/ToolTransform.py:770 msgid "Flip on the Y axis done" msgstr "Flip on the Y axis done" -#: flatcamEditors/FlatCAMGeoEditor.py:1345 -#: flatcamEditors/FlatCAMGrbEditor.py:5852 flatcamTools/ToolTransform.py:717 +#: flatcamEditors/FlatCAMGeoEditor.py:1391 +#: flatcamEditors/FlatCAMGrbEditor.py:5889 flatcamTools/ToolTransform.py:779 msgid "Flip on the X axis done" msgstr "Flip on the X axis done" -#: flatcamEditors/FlatCAMGeoEditor.py:1355 +#: flatcamEditors/FlatCAMGeoEditor.py:1399 msgid "Flip action was not executed" msgstr "Flip action was not executed" -#: flatcamEditors/FlatCAMGeoEditor.py:1365 -#: flatcamEditors/FlatCAMGrbEditor.py:5874 +#: flatcamEditors/FlatCAMGeoEditor.py:1417 +#: flatcamEditors/FlatCAMGrbEditor.py:5909 msgid "No shape selected. Please Select a shape to shear/skew!" msgstr "No shape selected. Please Select a shape to shear/skew!" -#: flatcamEditors/FlatCAMGeoEditor.py:1368 -#: flatcamEditors/FlatCAMGrbEditor.py:5877 flatcamTools/ToolTransform.py:742 +#: flatcamEditors/FlatCAMGeoEditor.py:1420 +#: flatcamEditors/FlatCAMGrbEditor.py:5912 flatcamTools/ToolTransform.py:802 msgid "Applying Skew" msgstr "Applying Skew" -#: flatcamEditors/FlatCAMGeoEditor.py:1394 -#: flatcamEditors/FlatCAMGrbEditor.py:5913 +#: flatcamEditors/FlatCAMGeoEditor.py:1443 +#: flatcamEditors/FlatCAMGrbEditor.py:5946 msgid "Skew on the X axis done" msgstr "Skew on the X axis done" -#: flatcamEditors/FlatCAMGeoEditor.py:1397 -#: flatcamEditors/FlatCAMGrbEditor.py:5915 +#: flatcamEditors/FlatCAMGeoEditor.py:1445 +#: flatcamEditors/FlatCAMGrbEditor.py:5948 msgid "Skew on the Y axis done" msgstr "Skew on the Y axis done" -#: flatcamEditors/FlatCAMGeoEditor.py:1401 +#: flatcamEditors/FlatCAMGeoEditor.py:1448 msgid "Skew action was not executed" msgstr "Skew action was not executed" -#: flatcamEditors/FlatCAMGeoEditor.py:1413 -#: flatcamEditors/FlatCAMGrbEditor.py:5939 +#: flatcamEditors/FlatCAMGeoEditor.py:1470 +#: flatcamEditors/FlatCAMGrbEditor.py:5970 msgid "No shape selected. Please Select a shape to scale!" msgstr "No shape selected. Please Select a shape to scale!" -#: flatcamEditors/FlatCAMGeoEditor.py:1416 -#: flatcamEditors/FlatCAMGrbEditor.py:5942 flatcamTools/ToolTransform.py:794 +#: flatcamEditors/FlatCAMGeoEditor.py:1473 +#: flatcamEditors/FlatCAMGrbEditor.py:5973 flatcamTools/ToolTransform.py:849 msgid "Applying Scale" msgstr "Applying Scale" -#: flatcamEditors/FlatCAMGeoEditor.py:1451 -#: flatcamEditors/FlatCAMGrbEditor.py:5981 +#: flatcamEditors/FlatCAMGeoEditor.py:1505 +#: flatcamEditors/FlatCAMGrbEditor.py:6010 msgid "Scale on the X axis done" msgstr "Scale on the X axis done" -#: flatcamEditors/FlatCAMGeoEditor.py:1454 -#: flatcamEditors/FlatCAMGrbEditor.py:5983 +#: flatcamEditors/FlatCAMGeoEditor.py:1507 +#: flatcamEditors/FlatCAMGrbEditor.py:6012 msgid "Scale on the Y axis done" msgstr "Scale on the Y axis done" -#: flatcamEditors/FlatCAMGeoEditor.py:1457 +#: flatcamEditors/FlatCAMGeoEditor.py:1509 msgid "Scale action was not executed" msgstr "Scale action was not executed" -#: flatcamEditors/FlatCAMGeoEditor.py:1467 -#: flatcamEditors/FlatCAMGrbEditor.py:6000 +#: flatcamEditors/FlatCAMGeoEditor.py:1524 +#: flatcamEditors/FlatCAMGrbEditor.py:6029 msgid "No shape selected. Please Select a shape to offset!" msgstr "No shape selected. Please Select a shape to offset!" -#: flatcamEditors/FlatCAMGeoEditor.py:1470 -#: flatcamEditors/FlatCAMGrbEditor.py:6003 flatcamTools/ToolTransform.py:849 +#: flatcamEditors/FlatCAMGeoEditor.py:1527 +#: flatcamEditors/FlatCAMGrbEditor.py:6032 flatcamTools/ToolTransform.py:901 msgid "Applying Offset" msgstr "Applying Offset" -#: flatcamEditors/FlatCAMGeoEditor.py:1483 -#: flatcamEditors/FlatCAMGrbEditor.py:6024 +#: flatcamEditors/FlatCAMGeoEditor.py:1537 +#: flatcamEditors/FlatCAMGrbEditor.py:6053 msgid "Offset on the X axis done" msgstr "Offset on the X axis done" -#: flatcamEditors/FlatCAMGeoEditor.py:1486 -#: flatcamEditors/FlatCAMGrbEditor.py:6026 +#: flatcamEditors/FlatCAMGeoEditor.py:1539 +#: flatcamEditors/FlatCAMGrbEditor.py:6055 msgid "Offset on the Y axis done" msgstr "Offset on the Y axis done" -#: flatcamEditors/FlatCAMGeoEditor.py:1490 +#: flatcamEditors/FlatCAMGeoEditor.py:1542 msgid "Offset action was not executed" msgstr "Offset action was not executed" -#: flatcamEditors/FlatCAMGeoEditor.py:1494 -#: flatcamEditors/FlatCAMGrbEditor.py:6033 +#: flatcamEditors/FlatCAMGeoEditor.py:1546 +#: flatcamEditors/FlatCAMGrbEditor.py:6062 msgid "Rotate ..." msgstr "Rotate ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1495 -#: flatcamEditors/FlatCAMGeoEditor.py:1550 -#: flatcamEditors/FlatCAMGeoEditor.py:1567 -#: flatcamEditors/FlatCAMGrbEditor.py:6034 -#: flatcamEditors/FlatCAMGrbEditor.py:6083 -#: flatcamEditors/FlatCAMGrbEditor.py:6098 +#: flatcamEditors/FlatCAMGeoEditor.py:1547 +#: flatcamEditors/FlatCAMGeoEditor.py:1602 +#: flatcamEditors/FlatCAMGeoEditor.py:1619 +#: flatcamEditors/FlatCAMGrbEditor.py:6063 +#: flatcamEditors/FlatCAMGrbEditor.py:6112 +#: flatcamEditors/FlatCAMGrbEditor.py:6127 msgid "Enter an Angle Value (degrees)" msgstr "Enter an Angle Value (degrees)" -#: flatcamEditors/FlatCAMGeoEditor.py:1504 -#: flatcamEditors/FlatCAMGrbEditor.py:6042 +#: flatcamEditors/FlatCAMGeoEditor.py:1556 +#: flatcamEditors/FlatCAMGrbEditor.py:6071 msgid "Geometry shape rotate done" msgstr "Geometry shape rotate done" -#: flatcamEditors/FlatCAMGeoEditor.py:1508 -#: flatcamEditors/FlatCAMGrbEditor.py:6045 +#: flatcamEditors/FlatCAMGeoEditor.py:1560 +#: flatcamEditors/FlatCAMGrbEditor.py:6074 msgid "Geometry shape rotate cancelled" msgstr "Geometry shape rotate cancelled" -#: flatcamEditors/FlatCAMGeoEditor.py:1513 -#: flatcamEditors/FlatCAMGrbEditor.py:6050 +#: flatcamEditors/FlatCAMGeoEditor.py:1565 +#: flatcamEditors/FlatCAMGrbEditor.py:6079 msgid "Offset on X axis ..." msgstr "Offset on X axis ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1514 -#: flatcamEditors/FlatCAMGeoEditor.py:1533 -#: flatcamEditors/FlatCAMGrbEditor.py:6051 -#: flatcamEditors/FlatCAMGrbEditor.py:6068 +#: flatcamEditors/FlatCAMGeoEditor.py:1566 +#: flatcamEditors/FlatCAMGeoEditor.py:1585 +#: flatcamEditors/FlatCAMGrbEditor.py:6080 +#: flatcamEditors/FlatCAMGrbEditor.py:6097 msgid "Enter a distance Value" msgstr "Enter a distance Value" -#: flatcamEditors/FlatCAMGeoEditor.py:1523 -#: flatcamEditors/FlatCAMGrbEditor.py:6059 +#: flatcamEditors/FlatCAMGeoEditor.py:1575 +#: flatcamEditors/FlatCAMGrbEditor.py:6088 msgid "Geometry shape offset on X axis done" msgstr "Geometry shape offset on X axis done" -#: flatcamEditors/FlatCAMGeoEditor.py:1527 -#: flatcamEditors/FlatCAMGrbEditor.py:6062 +#: flatcamEditors/FlatCAMGeoEditor.py:1579 +#: flatcamEditors/FlatCAMGrbEditor.py:6091 msgid "Geometry shape offset X cancelled" msgstr "Geometry shape offset X cancelled" -#: flatcamEditors/FlatCAMGeoEditor.py:1532 -#: flatcamEditors/FlatCAMGrbEditor.py:6067 +#: flatcamEditors/FlatCAMGeoEditor.py:1584 +#: flatcamEditors/FlatCAMGrbEditor.py:6096 msgid "Offset on Y axis ..." msgstr "Offset on Y axis ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1542 -#: flatcamEditors/FlatCAMGrbEditor.py:6076 +#: flatcamEditors/FlatCAMGeoEditor.py:1594 +#: flatcamEditors/FlatCAMGrbEditor.py:6105 msgid "Geometry shape offset on Y axis done" msgstr "Geometry shape offset on Y axis done" -#: flatcamEditors/FlatCAMGeoEditor.py:1546 +#: flatcamEditors/FlatCAMGeoEditor.py:1598 msgid "Geometry shape offset on Y axis canceled" msgstr "Geometry shape offset on Y axis canceled" -#: flatcamEditors/FlatCAMGeoEditor.py:1549 -#: flatcamEditors/FlatCAMGrbEditor.py:6082 +#: flatcamEditors/FlatCAMGeoEditor.py:1601 +#: flatcamEditors/FlatCAMGrbEditor.py:6111 msgid "Skew on X axis ..." msgstr "Skew on X axis ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1559 -#: flatcamEditors/FlatCAMGrbEditor.py:6091 +#: flatcamEditors/FlatCAMGeoEditor.py:1611 +#: flatcamEditors/FlatCAMGrbEditor.py:6120 msgid "Geometry shape skew on X axis done" msgstr "Geometry shape skew on X axis done" -#: flatcamEditors/FlatCAMGeoEditor.py:1563 +#: flatcamEditors/FlatCAMGeoEditor.py:1615 msgid "Geometry shape skew on X axis canceled" msgstr "Geometry shape skew on X axis canceled" -#: flatcamEditors/FlatCAMGeoEditor.py:1566 -#: flatcamEditors/FlatCAMGrbEditor.py:6097 +#: flatcamEditors/FlatCAMGeoEditor.py:1618 +#: flatcamEditors/FlatCAMGrbEditor.py:6126 msgid "Skew on Y axis ..." msgstr "Skew on Y axis ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1576 -#: flatcamEditors/FlatCAMGrbEditor.py:6106 +#: flatcamEditors/FlatCAMGeoEditor.py:1628 +#: flatcamEditors/FlatCAMGrbEditor.py:6135 msgid "Geometry shape skew on Y axis done" msgstr "Geometry shape skew on Y axis done" -#: flatcamEditors/FlatCAMGeoEditor.py:1580 +#: flatcamEditors/FlatCAMGeoEditor.py:1632 msgid "Geometry shape skew on Y axis canceled" msgstr "Geometry shape skew on Y axis canceled" -#: flatcamEditors/FlatCAMGeoEditor.py:1951 -#: flatcamEditors/FlatCAMGeoEditor.py:2016 -#: flatcamEditors/FlatCAMGrbEditor.py:1436 -#: flatcamEditors/FlatCAMGrbEditor.py:1514 +#: flatcamEditors/FlatCAMGeoEditor.py:2009 +#: flatcamEditors/FlatCAMGeoEditor.py:2080 +#: flatcamEditors/FlatCAMGrbEditor.py:1435 +#: flatcamEditors/FlatCAMGrbEditor.py:1513 msgid "Click on Center point ..." msgstr "Click on Center point ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1958 -#: flatcamEditors/FlatCAMGrbEditor.py:1446 +#: flatcamEditors/FlatCAMGeoEditor.py:2022 +#: flatcamEditors/FlatCAMGrbEditor.py:1445 msgid "Click on Perimeter point to complete ..." msgstr "Click on Perimeter point to complete ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1990 +#: flatcamEditors/FlatCAMGeoEditor.py:2054 msgid "Done. Adding Circle completed." msgstr "Done. Adding Circle completed." -#: flatcamEditors/FlatCAMGeoEditor.py:2038 -#: flatcamEditors/FlatCAMGrbEditor.py:1547 +#: flatcamEditors/FlatCAMGeoEditor.py:2108 +#: flatcamEditors/FlatCAMGrbEditor.py:1546 msgid "Click on Start point ..." msgstr "Click on Start point ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2040 -#: flatcamEditors/FlatCAMGrbEditor.py:1549 +#: flatcamEditors/FlatCAMGeoEditor.py:2110 +#: flatcamEditors/FlatCAMGrbEditor.py:1548 msgid "Click on Point3 ..." msgstr "Click on Point3 ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2042 -#: flatcamEditors/FlatCAMGrbEditor.py:1551 +#: flatcamEditors/FlatCAMGeoEditor.py:2112 +#: flatcamEditors/FlatCAMGrbEditor.py:1550 msgid "Click on Stop point ..." msgstr "Click on Stop point ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2047 -#: flatcamEditors/FlatCAMGrbEditor.py:1556 +#: flatcamEditors/FlatCAMGeoEditor.py:2117 +#: flatcamEditors/FlatCAMGrbEditor.py:1555 msgid "Click on Stop point to complete ..." msgstr "Click on Stop point to complete ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2049 -#: flatcamEditors/FlatCAMGrbEditor.py:1558 +#: flatcamEditors/FlatCAMGeoEditor.py:2119 +#: flatcamEditors/FlatCAMGrbEditor.py:1557 msgid "Click on Point2 to complete ..." msgstr "Click on Point2 to complete ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2051 -#: flatcamEditors/FlatCAMGrbEditor.py:1560 +#: flatcamEditors/FlatCAMGeoEditor.py:2121 +#: flatcamEditors/FlatCAMGrbEditor.py:1559 msgid "Click on Center point to complete ..." msgstr "Click on Center point to complete ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2063 +#: flatcamEditors/FlatCAMGeoEditor.py:2133 #, python-format msgid "Direction: %s" msgstr "Direction: %s" -#: flatcamEditors/FlatCAMGeoEditor.py:2077 -#: flatcamEditors/FlatCAMGrbEditor.py:1586 +#: flatcamEditors/FlatCAMGeoEditor.py:2147 +#: flatcamEditors/FlatCAMGrbEditor.py:1585 msgid "Mode: Start -> Stop -> Center. Click on Start point ..." msgstr "Mode: Start -> Stop -> Center. Click on Start point ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2080 -#: flatcamEditors/FlatCAMGrbEditor.py:1589 +#: flatcamEditors/FlatCAMGeoEditor.py:2150 +#: flatcamEditors/FlatCAMGrbEditor.py:1588 msgid "Mode: Point1 -> Point3 -> Point2. Click on Point1 ..." msgstr "Mode: Point1 -> Point3 -> Point2. Click on Point1 ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2083 -#: flatcamEditors/FlatCAMGrbEditor.py:1592 +#: flatcamEditors/FlatCAMGeoEditor.py:2153 +#: flatcamEditors/FlatCAMGrbEditor.py:1591 msgid "Mode: Center -> Start -> Stop. Click on Center point ..." msgstr "Mode: Center -> Start -> Stop. Click on Center point ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2224 +#: flatcamEditors/FlatCAMGeoEditor.py:2294 msgid "Done. Arc completed." msgstr "Done. Arc completed." -#: flatcamEditors/FlatCAMGeoEditor.py:2255 -#: flatcamEditors/FlatCAMGeoEditor.py:2322 +#: flatcamEditors/FlatCAMGeoEditor.py:2325 +#: flatcamEditors/FlatCAMGeoEditor.py:2398 msgid "Click on 1st corner ..." msgstr "Click on 1st corner ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2261 +#: flatcamEditors/FlatCAMGeoEditor.py:2337 msgid "Click on opposite corner to complete ..." msgstr "Click on opposite corner to complete ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2291 +#: flatcamEditors/FlatCAMGeoEditor.py:2367 msgid "Done. Rectangle completed." msgstr "Done. Rectangle completed." -#: flatcamEditors/FlatCAMGeoEditor.py:2329 +#: flatcamEditors/FlatCAMGeoEditor.py:2411 flatcamTools/ToolNCC.py:1737 +#: flatcamTools/ToolPaint.py:1616 msgid "Click on next Point or click right mouse button to complete ..." msgstr "Click on next Point or click right mouse button to complete ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2360 +#: flatcamEditors/FlatCAMGeoEditor.py:2442 msgid "Done. Polygon completed." msgstr "Done. Polygon completed." -#: flatcamEditors/FlatCAMGeoEditor.py:2374 -#: flatcamEditors/FlatCAMGeoEditor.py:2439 -#: flatcamEditors/FlatCAMGrbEditor.py:1112 -#: flatcamEditors/FlatCAMGrbEditor.py:1323 +#: flatcamEditors/FlatCAMGeoEditor.py:2456 +#: flatcamEditors/FlatCAMGeoEditor.py:2521 +#: flatcamEditors/FlatCAMGrbEditor.py:1111 +#: flatcamEditors/FlatCAMGrbEditor.py:1322 msgid "Backtracked one point ..." msgstr "Backtracked one point ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2417 +#: flatcamEditors/FlatCAMGeoEditor.py:2499 msgid "Done. Path completed." msgstr "Done. Path completed." -#: flatcamEditors/FlatCAMGeoEditor.py:2580 +#: flatcamEditors/FlatCAMGeoEditor.py:2658 +msgid "No shape selected. Select a shape to explode" +msgstr "No shape selected. Select a shape to explode" + +#: flatcamEditors/FlatCAMGeoEditor.py:2691 msgid "Done. Polygons exploded into lines." msgstr "Done. Polygons exploded into lines." -#: flatcamEditors/FlatCAMGeoEditor.py:2612 +#: flatcamEditors/FlatCAMGeoEditor.py:2723 msgid "MOVE: No shape selected. Select a shape to move" msgstr "MOVE: No shape selected. Select a shape to move" -#: flatcamEditors/FlatCAMGeoEditor.py:2615 -#: flatcamEditors/FlatCAMGeoEditor.py:2628 +#: flatcamEditors/FlatCAMGeoEditor.py:2726 +#: flatcamEditors/FlatCAMGeoEditor.py:2746 msgid " MOVE: Click on reference point ..." msgstr " MOVE: Click on reference point ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2619 +#: flatcamEditors/FlatCAMGeoEditor.py:2731 msgid " Click on destination point ..." msgstr " Click on destination point ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2653 +#: flatcamEditors/FlatCAMGeoEditor.py:2771 msgid "Done. Geometry(s) Move completed." msgstr "Done. Geometry(s) Move completed." -#: flatcamEditors/FlatCAMGeoEditor.py:2783 +#: flatcamEditors/FlatCAMGeoEditor.py:2904 msgid "Done. Geometry(s) Copy completed." msgstr "Done. Geometry(s) Copy completed." -#: flatcamEditors/FlatCAMGeoEditor.py:2811 -#: flatcamEditors/FlatCAMGrbEditor.py:898 +#: flatcamEditors/FlatCAMGeoEditor.py:2935 +#: flatcamEditors/FlatCAMGrbEditor.py:897 msgid "Click on 1st point ..." msgstr "Click on 1st point ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2829 +#: flatcamEditors/FlatCAMGeoEditor.py:2959 msgid "" "Font not supported. Only Regular, Bold, Italic and BoldItalic are supported. " "Error" @@ -4335,94 +4713,133 @@ msgstr "" "Font not supported. Only Regular, Bold, Italic and BoldItalic are supported. " "Error" -#: flatcamEditors/FlatCAMGeoEditor.py:2837 +#: flatcamEditors/FlatCAMGeoEditor.py:2967 msgid "No text to add." msgstr "No text to add." -#: flatcamEditors/FlatCAMGeoEditor.py:2844 +#: flatcamEditors/FlatCAMGeoEditor.py:2977 msgid " Done. Adding Text completed." msgstr " Done. Adding Text completed." -#: flatcamEditors/FlatCAMGeoEditor.py:2881 +#: flatcamEditors/FlatCAMGeoEditor.py:3014 msgid "Create buffer geometry ..." msgstr "Create buffer geometry ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2892 -#: flatcamEditors/FlatCAMGeoEditor.py:2922 -#: flatcamEditors/FlatCAMGeoEditor.py:2952 -msgid "Buffer cancelled. No shape selected." -msgstr "Buffer cancelled. No shape selected." - -#: flatcamEditors/FlatCAMGeoEditor.py:2917 -#: flatcamEditors/FlatCAMGrbEditor.py:4950 +#: flatcamEditors/FlatCAMGeoEditor.py:3049 +#: flatcamEditors/FlatCAMGrbEditor.py:4994 msgid "Done. Buffer Tool completed." msgstr "Done. Buffer Tool completed." -#: flatcamEditors/FlatCAMGeoEditor.py:2947 +#: flatcamEditors/FlatCAMGeoEditor.py:3077 msgid "Done. Buffer Int Tool completed." msgstr "Done. Buffer Int Tool completed." -#: flatcamEditors/FlatCAMGeoEditor.py:2977 +#: flatcamEditors/FlatCAMGeoEditor.py:3105 msgid "Done. Buffer Ext Tool completed." msgstr "Done. Buffer Ext Tool completed." -#: flatcamEditors/FlatCAMGeoEditor.py:3023 -#: flatcamEditors/FlatCAMGrbEditor.py:2152 +#: flatcamEditors/FlatCAMGeoEditor.py:3154 +#: flatcamEditors/FlatCAMGrbEditor.py:2151 msgid "Select a shape to act as deletion area ..." msgstr "Select a shape to act as deletion area ..." -#: flatcamEditors/FlatCAMGeoEditor.py:3025 -#: flatcamEditors/FlatCAMGeoEditor.py:3045 -#: flatcamEditors/FlatCAMGeoEditor.py:3051 -#: flatcamEditors/FlatCAMGrbEditor.py:2154 +#: flatcamEditors/FlatCAMGeoEditor.py:3156 +#: flatcamEditors/FlatCAMGeoEditor.py:3182 +#: flatcamEditors/FlatCAMGeoEditor.py:3188 +#: flatcamEditors/FlatCAMGrbEditor.py:2153 msgid "Click to pick-up the erase shape..." msgstr "Click to pick-up the erase shape..." -#: flatcamEditors/FlatCAMGeoEditor.py:3055 -#: flatcamEditors/FlatCAMGrbEditor.py:2213 +#: flatcamEditors/FlatCAMGeoEditor.py:3192 +#: flatcamEditors/FlatCAMGrbEditor.py:2212 msgid "Click to erase ..." msgstr "Click to erase ..." -#: flatcamEditors/FlatCAMGeoEditor.py:3084 -#: flatcamEditors/FlatCAMGrbEditor.py:2246 +#: flatcamEditors/FlatCAMGeoEditor.py:3221 +#: flatcamEditors/FlatCAMGrbEditor.py:2245 msgid "Done. Eraser tool action completed." msgstr "Done. Eraser tool action completed." -#: flatcamEditors/FlatCAMGeoEditor.py:3131 +#: flatcamEditors/FlatCAMGeoEditor.py:3271 msgid "Create Paint geometry ..." msgstr "Create Paint geometry ..." -#: flatcamEditors/FlatCAMGeoEditor.py:3144 -#: flatcamEditors/FlatCAMGrbEditor.py:2402 +#: flatcamEditors/FlatCAMGeoEditor.py:3284 +#: flatcamEditors/FlatCAMGrbEditor.py:2408 msgid "Shape transformations ..." msgstr "Shape transformations ..." -#: flatcamEditors/FlatCAMGeoEditor.py:3763 +#: flatcamEditors/FlatCAMGeoEditor.py:3340 flatcamGUI/PreferencesUI.py:4636 +msgid "Geometry Editor" +msgstr "Geometry Editor" + +#: flatcamEditors/FlatCAMGeoEditor.py:3346 +#: flatcamEditors/FlatCAMGrbEditor.py:2486 +#: flatcamEditors/FlatCAMGrbEditor.py:3846 flatcamGUI/ObjectUI.py:262 +#: flatcamGUI/ObjectUI.py:1495 flatcamGUI/ObjectUI.py:2244 +#: flatcamTools/ToolCutOut.py:96 +msgid "Type" +msgstr "Type" + +#: flatcamEditors/FlatCAMGeoEditor.py:3346 flatcamGUI/ObjectUI.py:217 +#: flatcamGUI/ObjectUI.py:741 flatcamGUI/ObjectUI.py:1431 +#: flatcamGUI/ObjectUI.py:2153 flatcamGUI/ObjectUI.py:2457 +#: flatcamGUI/ObjectUI.py:2524 flatcamTools/ToolCalibration.py:234 +#: flatcamTools/ToolFiducials.py:73 +msgid "Name" +msgstr "Name" + +#: flatcamEditors/FlatCAMGeoEditor.py:3588 +msgid "Ring" +msgstr "Ring" + +#: flatcamEditors/FlatCAMGeoEditor.py:3590 +msgid "Line" +msgstr "Line" + +#: flatcamEditors/FlatCAMGeoEditor.py:3592 flatcamGUI/FlatCAMGUI.py:2187 +#: flatcamGUI/PreferencesUI.py:5607 flatcamGUI/PreferencesUI.py:6131 +#: flatcamTools/ToolNCC.py:584 flatcamTools/ToolPaint.py:528 +msgid "Polygon" +msgstr "Polygon" + +#: flatcamEditors/FlatCAMGeoEditor.py:3594 +#| msgid "Multi-Geo" +msgid "Multi-Line" +msgstr "Multi-Line" + +#: flatcamEditors/FlatCAMGeoEditor.py:3596 +#| msgid "Multi-Color" +msgid "Multi-Polygon" +msgstr "Multi-Polygon" + +#: flatcamEditors/FlatCAMGeoEditor.py:3603 +#| msgid "Geo Type" +msgid "Geo Elem" +msgstr "Geo Elem" + +#: flatcamEditors/FlatCAMGeoEditor.py:4076 msgid "Editing MultiGeo Geometry, tool" msgstr "Editing MultiGeo Geometry, tool" -#: flatcamEditors/FlatCAMGeoEditor.py:3765 +#: flatcamEditors/FlatCAMGeoEditor.py:4078 msgid "with diameter" msgstr "with diameter" -#: flatcamEditors/FlatCAMGeoEditor.py:4169 -msgid "Copy cancelled. No shape selected." -msgstr "Copy cancelled. No shape selected." - -#: flatcamEditors/FlatCAMGeoEditor.py:4176 flatcamGUI/FlatCAMGUI.py:3472 -#: flatcamGUI/FlatCAMGUI.py:3519 flatcamGUI/FlatCAMGUI.py:3538 -#: flatcamGUI/FlatCAMGUI.py:3679 flatcamGUI/FlatCAMGUI.py:3719 -#: flatcamGUI/FlatCAMGUI.py:3732 flatcamGUI/FlatCAMGUI.py:3749 +#: flatcamEditors/FlatCAMGeoEditor.py:4509 flatcamGUI/FlatCAMGUI.py:3695 +#: flatcamGUI/FlatCAMGUI.py:3741 flatcamGUI/FlatCAMGUI.py:3759 +#: flatcamGUI/FlatCAMGUI.py:3899 flatcamGUI/FlatCAMGUI.py:3938 +#: flatcamGUI/FlatCAMGUI.py:3950 flatcamGUI/FlatCAMGUI.py:3967 msgid "Click on target point." msgstr "Click on target point." -#: flatcamEditors/FlatCAMGeoEditor.py:4479 -#: flatcamEditors/FlatCAMGeoEditor.py:4514 +#: flatcamEditors/FlatCAMGeoEditor.py:4823 +#: flatcamEditors/FlatCAMGeoEditor.py:4858 msgid "A selection of at least 2 geo items is required to do Intersection." msgstr "A selection of at least 2 geo items is required to do Intersection." -#: flatcamEditors/FlatCAMGeoEditor.py:4600 -#: flatcamEditors/FlatCAMGeoEditor.py:4704 +#: flatcamEditors/FlatCAMGeoEditor.py:4944 +#: flatcamEditors/FlatCAMGeoEditor.py:5048 msgid "" "Negative buffer value is not accepted. Use Buffer interior to generate an " "'inside' shape" @@ -4430,57 +4847,58 @@ msgstr "" "Negative buffer value is not accepted. Use Buffer interior to generate an " "'inside' shape" -#: flatcamEditors/FlatCAMGeoEditor.py:4610 -#: flatcamEditors/FlatCAMGeoEditor.py:4663 -#: flatcamEditors/FlatCAMGeoEditor.py:4713 +#: flatcamEditors/FlatCAMGeoEditor.py:4954 +#: flatcamEditors/FlatCAMGeoEditor.py:5007 +#: flatcamEditors/FlatCAMGeoEditor.py:5057 msgid "Nothing selected for buffering." msgstr "Nothing selected for buffering." -#: flatcamEditors/FlatCAMGeoEditor.py:4615 -#: flatcamEditors/FlatCAMGeoEditor.py:4667 -#: flatcamEditors/FlatCAMGeoEditor.py:4718 +#: flatcamEditors/FlatCAMGeoEditor.py:4959 +#: flatcamEditors/FlatCAMGeoEditor.py:5011 +#: flatcamEditors/FlatCAMGeoEditor.py:5062 msgid "Invalid distance for buffering." msgstr "Invalid distance for buffering." -#: flatcamEditors/FlatCAMGeoEditor.py:4639 -#: flatcamEditors/FlatCAMGeoEditor.py:4738 +#: flatcamEditors/FlatCAMGeoEditor.py:4983 +#: flatcamEditors/FlatCAMGeoEditor.py:5082 msgid "Failed, the result is empty. Choose a different buffer value." msgstr "Failed, the result is empty. Choose a different buffer value." -#: flatcamEditors/FlatCAMGeoEditor.py:4650 +#: flatcamEditors/FlatCAMGeoEditor.py:4994 msgid "Full buffer geometry created." msgstr "Full buffer geometry created." -#: flatcamEditors/FlatCAMGeoEditor.py:4656 +#: flatcamEditors/FlatCAMGeoEditor.py:5000 msgid "Negative buffer value is not accepted." msgstr "Negative buffer value is not accepted." -#: flatcamEditors/FlatCAMGeoEditor.py:4687 +#: flatcamEditors/FlatCAMGeoEditor.py:5031 msgid "Failed, the result is empty. Choose a smaller buffer value." msgstr "Failed, the result is empty. Choose a smaller buffer value." -#: flatcamEditors/FlatCAMGeoEditor.py:4697 +#: flatcamEditors/FlatCAMGeoEditor.py:5041 msgid "Interior buffer geometry created." msgstr "Interior buffer geometry created." -#: flatcamEditors/FlatCAMGeoEditor.py:4748 +#: flatcamEditors/FlatCAMGeoEditor.py:5092 msgid "Exterior buffer geometry created." msgstr "Exterior buffer geometry created." -#: flatcamEditors/FlatCAMGeoEditor.py:4754 +#: flatcamEditors/FlatCAMGeoEditor.py:5098 #, python-format -msgid "Could not do Paint. Overlap value has to be less than 1.00 (100%%)." -msgstr "Could not do Paint. Overlap value has to be less than 1.00 (100%%)." +#| msgid "Could not do Paint. Overlap value has to be less than 1.00 (100%%)." +msgid "Could not do Paint. Overlap value has to be less than 100%%." +msgstr "Could not do Paint. Overlap value has to be less than 100%%." -#: flatcamEditors/FlatCAMGeoEditor.py:4761 +#: flatcamEditors/FlatCAMGeoEditor.py:5105 msgid "Nothing selected for painting." msgstr "Nothing selected for painting." -#: flatcamEditors/FlatCAMGeoEditor.py:4767 +#: flatcamEditors/FlatCAMGeoEditor.py:5111 msgid "Invalid value for" msgstr "Invalid value for" -#: flatcamEditors/FlatCAMGeoEditor.py:4826 +#: flatcamEditors/FlatCAMGeoEditor.py:5170 msgid "" "Could not do Paint. Try a different combination of parameters. Or a " "different method of Paint" @@ -4488,7 +4906,7 @@ msgstr "" "Could not do Paint. Try a different combination of parameters. Or a " "different method of Paint" -#: flatcamEditors/FlatCAMGeoEditor.py:4840 +#: flatcamEditors/FlatCAMGeoEditor.py:5181 msgid "Paint done." msgstr "Paint done." @@ -4502,7 +4920,7 @@ msgid "Aperture size is zero. It needs to be greater than zero." msgstr "Aperture size is zero. It needs to be greater than zero." #: flatcamEditors/FlatCAMGrbEditor.py:371 -#: flatcamEditors/FlatCAMGrbEditor.py:685 +#: flatcamEditors/FlatCAMGrbEditor.py:684 msgid "" "Incompatible aperture type. Select an aperture with type 'C', 'R' or 'O'." msgstr "" @@ -4520,170 +4938,164 @@ msgstr "To add an Pad Array first select a aperture in Aperture Table" msgid "Click on the Pad Circular Array Start position" msgstr "Click on the Pad Circular Array Start position" -#: flatcamEditors/FlatCAMGrbEditor.py:711 +#: flatcamEditors/FlatCAMGrbEditor.py:710 msgid "Too many Pads for the selected spacing angle." msgstr "Too many Pads for the selected spacing angle." -#: flatcamEditors/FlatCAMGrbEditor.py:734 +#: flatcamEditors/FlatCAMGrbEditor.py:733 msgid "Done. Pad Array added." msgstr "Done. Pad Array added." -#: flatcamEditors/FlatCAMGrbEditor.py:759 +#: flatcamEditors/FlatCAMGrbEditor.py:758 msgid "Select shape(s) and then click ..." msgstr "Select shape(s) and then click ..." -#: flatcamEditors/FlatCAMGrbEditor.py:771 +#: flatcamEditors/FlatCAMGrbEditor.py:770 msgid "Failed. Nothing selected." msgstr "Failed. Nothing selected." -#: flatcamEditors/FlatCAMGrbEditor.py:787 +#: flatcamEditors/FlatCAMGrbEditor.py:786 msgid "" "Failed. Poligonize works only on geometries belonging to the same aperture." msgstr "" "Failed. Poligonize works only on geometries belonging to the same aperture." -#: flatcamEditors/FlatCAMGrbEditor.py:841 +#: flatcamEditors/FlatCAMGrbEditor.py:840 msgid "Done. Poligonize completed." msgstr "Done. Poligonize completed." -#: flatcamEditors/FlatCAMGrbEditor.py:896 -#: flatcamEditors/FlatCAMGrbEditor.py:1129 -#: flatcamEditors/FlatCAMGrbEditor.py:1153 +#: flatcamEditors/FlatCAMGrbEditor.py:895 +#: flatcamEditors/FlatCAMGrbEditor.py:1128 +#: flatcamEditors/FlatCAMGrbEditor.py:1152 msgid "Corner Mode 1: 45 degrees ..." msgstr "Corner Mode 1: 45 degrees ..." -#: flatcamEditors/FlatCAMGrbEditor.py:908 -#: flatcamEditors/FlatCAMGrbEditor.py:1238 +#: flatcamEditors/FlatCAMGrbEditor.py:907 +#: flatcamEditors/FlatCAMGrbEditor.py:1237 msgid "Click on next Point or click Right mouse button to complete ..." msgstr "Click on next Point or click Right mouse button to complete ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1117 -#: flatcamEditors/FlatCAMGrbEditor.py:1150 +#: flatcamEditors/FlatCAMGrbEditor.py:1116 +#: flatcamEditors/FlatCAMGrbEditor.py:1149 msgid "Corner Mode 2: Reverse 45 degrees ..." msgstr "Corner Mode 2: Reverse 45 degrees ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1120 -#: flatcamEditors/FlatCAMGrbEditor.py:1147 +#: flatcamEditors/FlatCAMGrbEditor.py:1119 +#: flatcamEditors/FlatCAMGrbEditor.py:1146 msgid "Corner Mode 3: 90 degrees ..." msgstr "Corner Mode 3: 90 degrees ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1123 -#: flatcamEditors/FlatCAMGrbEditor.py:1144 +#: flatcamEditors/FlatCAMGrbEditor.py:1122 +#: flatcamEditors/FlatCAMGrbEditor.py:1143 msgid "Corner Mode 4: Reverse 90 degrees ..." msgstr "Corner Mode 4: Reverse 90 degrees ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1126 -#: flatcamEditors/FlatCAMGrbEditor.py:1141 +#: flatcamEditors/FlatCAMGrbEditor.py:1125 +#: flatcamEditors/FlatCAMGrbEditor.py:1140 msgid "Corner Mode 5: Free angle ..." msgstr "Corner Mode 5: Free angle ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1183 -#: flatcamEditors/FlatCAMGrbEditor.py:1359 -#: flatcamEditors/FlatCAMGrbEditor.py:1398 +#: flatcamEditors/FlatCAMGrbEditor.py:1182 +#: flatcamEditors/FlatCAMGrbEditor.py:1358 +#: flatcamEditors/FlatCAMGrbEditor.py:1397 msgid "Track Mode 1: 45 degrees ..." msgstr "Track Mode 1: 45 degrees ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1339 -#: flatcamEditors/FlatCAMGrbEditor.py:1393 +#: flatcamEditors/FlatCAMGrbEditor.py:1338 +#: flatcamEditors/FlatCAMGrbEditor.py:1392 msgid "Track Mode 2: Reverse 45 degrees ..." msgstr "Track Mode 2: Reverse 45 degrees ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1344 -#: flatcamEditors/FlatCAMGrbEditor.py:1388 +#: flatcamEditors/FlatCAMGrbEditor.py:1343 +#: flatcamEditors/FlatCAMGrbEditor.py:1387 msgid "Track Mode 3: 90 degrees ..." msgstr "Track Mode 3: 90 degrees ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1349 -#: flatcamEditors/FlatCAMGrbEditor.py:1383 +#: flatcamEditors/FlatCAMGrbEditor.py:1348 +#: flatcamEditors/FlatCAMGrbEditor.py:1382 msgid "Track Mode 4: Reverse 90 degrees ..." msgstr "Track Mode 4: Reverse 90 degrees ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1354 -#: flatcamEditors/FlatCAMGrbEditor.py:1378 +#: flatcamEditors/FlatCAMGrbEditor.py:1353 +#: flatcamEditors/FlatCAMGrbEditor.py:1377 msgid "Track Mode 5: Free angle ..." msgstr "Track Mode 5: Free angle ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1779 +#: flatcamEditors/FlatCAMGrbEditor.py:1778 msgid "Scale the selected Gerber apertures ..." msgstr "Scale the selected Gerber apertures ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1821 +#: flatcamEditors/FlatCAMGrbEditor.py:1820 msgid "Buffer the selected apertures ..." msgstr "Buffer the selected apertures ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1863 +#: flatcamEditors/FlatCAMGrbEditor.py:1862 msgid "Mark polygon areas in the edited Gerber ..." msgstr "Mark polygon areas in the edited Gerber ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1929 +#: flatcamEditors/FlatCAMGrbEditor.py:1928 msgid "Nothing selected to move" msgstr "Nothing selected to move" -#: flatcamEditors/FlatCAMGrbEditor.py:2054 +#: flatcamEditors/FlatCAMGrbEditor.py:2053 msgid "Done. Apertures Move completed." msgstr "Done. Apertures Move completed." -#: flatcamEditors/FlatCAMGrbEditor.py:2136 +#: flatcamEditors/FlatCAMGrbEditor.py:2135 msgid "Done. Apertures copied." msgstr "Done. Apertures copied." -#: flatcamEditors/FlatCAMGrbEditor.py:2447 flatcamGUI/FlatCAMGUI.py:2110 -#: flatcamGUI/PreferencesUI.py:2443 +#: flatcamEditors/FlatCAMGrbEditor.py:2453 flatcamGUI/FlatCAMGUI.py:2218 +#: flatcamGUI/PreferencesUI.py:2623 msgid "Gerber Editor" msgstr "Gerber Editor" -#: flatcamEditors/FlatCAMGrbEditor.py:2467 flatcamGUI/ObjectUI.py:223 -#: flatcamTools/ToolProperties.py:156 +#: flatcamEditors/FlatCAMGrbEditor.py:2473 flatcamGUI/ObjectUI.py:227 +#: flatcamTools/ToolProperties.py:159 msgid "Apertures" msgstr "Apertures" -#: flatcamEditors/FlatCAMGrbEditor.py:2469 flatcamGUI/ObjectUI.py:225 +#: flatcamEditors/FlatCAMGrbEditor.py:2475 flatcamGUI/ObjectUI.py:229 msgid "Apertures Table for the Gerber Object." msgstr "Apertures Table for the Gerber Object." -#: flatcamEditors/FlatCAMGrbEditor.py:2480 -#: flatcamEditors/FlatCAMGrbEditor.py:3832 flatcamGUI/ObjectUI.py:258 +#: flatcamEditors/FlatCAMGrbEditor.py:2486 +#: flatcamEditors/FlatCAMGrbEditor.py:3846 flatcamGUI/ObjectUI.py:262 msgid "Code" msgstr "Code" -#: flatcamEditors/FlatCAMGrbEditor.py:2480 -#: flatcamEditors/FlatCAMGrbEditor.py:3832 flatcamGUI/ObjectUI.py:258 -#: flatcamGUI/ObjectUI.py:1217 flatcamGUI/ObjectUI.py:1916 -msgid "Type" -msgstr "Type" - -#: flatcamEditors/FlatCAMGrbEditor.py:2480 -#: flatcamEditors/FlatCAMGrbEditor.py:3832 flatcamGUI/ObjectUI.py:258 -#: flatcamGUI/PreferencesUI.py:1009 flatcamGUI/PreferencesUI.py:7270 -#: flatcamGUI/PreferencesUI.py:7299 flatcamGUI/PreferencesUI.py:7401 -#: flatcamTools/ToolCopperThieving.py:260 -#: flatcamTools/ToolCopperThieving.py:300 flatcamTools/ToolFiducials.py:156 +#: flatcamEditors/FlatCAMGrbEditor.py:2486 +#: flatcamEditors/FlatCAMGrbEditor.py:3846 flatcamGUI/ObjectUI.py:262 +#: flatcamGUI/PreferencesUI.py:1184 flatcamGUI/PreferencesUI.py:7776 +#: flatcamGUI/PreferencesUI.py:7805 flatcamGUI/PreferencesUI.py:7907 +#: flatcamTools/ToolCopperThieving.py:262 +#: flatcamTools/ToolCopperThieving.py:302 flatcamTools/ToolFiducials.py:156 msgid "Size" msgstr "Size" -#: flatcamEditors/FlatCAMGrbEditor.py:2480 -#: flatcamEditors/FlatCAMGrbEditor.py:3832 flatcamGUI/ObjectUI.py:258 +#: flatcamEditors/FlatCAMGrbEditor.py:2486 +#: flatcamEditors/FlatCAMGrbEditor.py:3846 flatcamGUI/ObjectUI.py:262 msgid "Dim" msgstr "Dim" -#: flatcamEditors/FlatCAMGrbEditor.py:2484 flatcamGUI/ObjectUI.py:262 +#: flatcamEditors/FlatCAMGrbEditor.py:2490 flatcamGUI/ObjectUI.py:266 msgid "Index" msgstr "Index" -#: flatcamEditors/FlatCAMGrbEditor.py:2486 -#: flatcamEditors/FlatCAMGrbEditor.py:2515 flatcamGUI/ObjectUI.py:264 +#: flatcamEditors/FlatCAMGrbEditor.py:2492 +#: flatcamEditors/FlatCAMGrbEditor.py:2521 flatcamGUI/ObjectUI.py:268 msgid "Aperture Code" msgstr "Aperture Code" -#: flatcamEditors/FlatCAMGrbEditor.py:2488 flatcamGUI/ObjectUI.py:266 +#: flatcamEditors/FlatCAMGrbEditor.py:2494 flatcamGUI/ObjectUI.py:270 msgid "Type of aperture: circular, rectangle, macros etc" msgstr "Type of aperture: circular, rectangle, macros etc" -#: flatcamEditors/FlatCAMGrbEditor.py:2490 flatcamGUI/ObjectUI.py:268 +#: flatcamEditors/FlatCAMGrbEditor.py:2496 flatcamGUI/ObjectUI.py:272 msgid "Aperture Size:" msgstr "Aperture Size:" -#: flatcamEditors/FlatCAMGrbEditor.py:2492 flatcamGUI/ObjectUI.py:270 +#: flatcamEditors/FlatCAMGrbEditor.py:2498 flatcamGUI/ObjectUI.py:274 msgid "" "Aperture Dimensions:\n" " - (width, height) for R, O type.\n" @@ -4693,15 +5105,15 @@ msgstr "" " - (width, height) for R, O type.\n" " - (dia, nVertices) for P type" -#: flatcamEditors/FlatCAMGrbEditor.py:2516 flatcamGUI/PreferencesUI.py:2474 +#: flatcamEditors/FlatCAMGrbEditor.py:2522 flatcamGUI/PreferencesUI.py:2654 msgid "Code for the new aperture" msgstr "Code for the new aperture" -#: flatcamEditors/FlatCAMGrbEditor.py:2525 +#: flatcamEditors/FlatCAMGrbEditor.py:2531 msgid "Aperture Size" msgstr "Aperture Size" -#: flatcamEditors/FlatCAMGrbEditor.py:2527 +#: flatcamEditors/FlatCAMGrbEditor.py:2533 msgid "" "Size for the new aperture.\n" "If aperture type is 'R' or 'O' then\n" @@ -4715,11 +5127,11 @@ msgstr "" "calculated as:\n" "sqrt(width**2 + height**2)" -#: flatcamEditors/FlatCAMGrbEditor.py:2541 +#: flatcamEditors/FlatCAMGrbEditor.py:2547 msgid "Aperture Type" msgstr "Aperture Type" -#: flatcamEditors/FlatCAMGrbEditor.py:2543 +#: flatcamEditors/FlatCAMGrbEditor.py:2549 msgid "" "Select the type of new aperture. Can be:\n" "C = circular\n" @@ -4731,11 +5143,11 @@ msgstr "" "R = rectangular\n" "O = oblong" -#: flatcamEditors/FlatCAMGrbEditor.py:2554 +#: flatcamEditors/FlatCAMGrbEditor.py:2560 msgid "Aperture Dim" msgstr "Aperture Dim" -#: flatcamEditors/FlatCAMGrbEditor.py:2556 +#: flatcamEditors/FlatCAMGrbEditor.py:2562 msgid "" "Dimensions for the new aperture.\n" "Active only for rectangular apertures (type R).\n" @@ -4745,39 +5157,39 @@ msgstr "" "Active only for rectangular apertures (type R).\n" "The format is (width, height)" -#: flatcamEditors/FlatCAMGrbEditor.py:2565 +#: flatcamEditors/FlatCAMGrbEditor.py:2571 msgid "Add/Delete Aperture" msgstr "Add/Delete Aperture" -#: flatcamEditors/FlatCAMGrbEditor.py:2567 +#: flatcamEditors/FlatCAMGrbEditor.py:2573 msgid "Add/Delete an aperture in the aperture table" msgstr "Add/Delete an aperture in the aperture table" -#: flatcamEditors/FlatCAMGrbEditor.py:2576 +#: flatcamEditors/FlatCAMGrbEditor.py:2582 msgid "Add a new aperture to the aperture list." msgstr "Add a new aperture to the aperture list." -#: flatcamEditors/FlatCAMGrbEditor.py:2581 +#: flatcamEditors/FlatCAMGrbEditor.py:2587 msgid "Delete a aperture in the aperture list" msgstr "Delete a aperture in the aperture list" -#: flatcamEditors/FlatCAMGrbEditor.py:2598 +#: flatcamEditors/FlatCAMGrbEditor.py:2604 msgid "Buffer Aperture" msgstr "Buffer Aperture" -#: flatcamEditors/FlatCAMGrbEditor.py:2600 +#: flatcamEditors/FlatCAMGrbEditor.py:2606 msgid "Buffer a aperture in the aperture list" msgstr "Buffer a aperture in the aperture list" -#: flatcamEditors/FlatCAMGrbEditor.py:2613 flatcamGUI/PreferencesUI.py:2608 +#: flatcamEditors/FlatCAMGrbEditor.py:2619 flatcamGUI/PreferencesUI.py:2790 msgid "Buffer distance" msgstr "Buffer distance" -#: flatcamEditors/FlatCAMGrbEditor.py:2614 +#: flatcamEditors/FlatCAMGrbEditor.py:2620 msgid "Buffer corner" msgstr "Buffer corner" -#: flatcamEditors/FlatCAMGrbEditor.py:2616 +#: flatcamEditors/FlatCAMGrbEditor.py:2622 msgid "" "There are 3 types of corners:\n" " - 'Round': the corner is rounded.\n" @@ -4791,27 +5203,26 @@ msgstr "" " - 'Beveled:' the corner is a line that directly connects the features " "meeting in the corner" -#: flatcamEditors/FlatCAMGrbEditor.py:2631 flatcamGUI/FlatCAMGUI.py:978 -#: flatcamGUI/FlatCAMGUI.py:2015 flatcamGUI/FlatCAMGUI.py:2087 -#: flatcamGUI/FlatCAMGUI.py:2130 flatcamGUI/FlatCAMGUI.py:2547 -#: flatcamGUI/PreferencesUI.py:6393 flatcamTools/ToolTransform.py:30 -#: flatcamTools/ToolTransform.py:349 +#: flatcamEditors/FlatCAMGrbEditor.py:2637 flatcamGUI/FlatCAMGUI.py:1046 +#: flatcamGUI/FlatCAMGUI.py:2123 flatcamGUI/FlatCAMGUI.py:2195 +#: flatcamGUI/FlatCAMGUI.py:2238 flatcamGUI/FlatCAMGUI.py:2721 +#: flatcamGUI/PreferencesUI.py:6880 flatcamTools/ToolTransform.py:30 msgid "Buffer" msgstr "Buffer" -#: flatcamEditors/FlatCAMGrbEditor.py:2646 +#: flatcamEditors/FlatCAMGrbEditor.py:2652 msgid "Scale Aperture" msgstr "Scale Aperture" -#: flatcamEditors/FlatCAMGrbEditor.py:2648 +#: flatcamEditors/FlatCAMGrbEditor.py:2654 msgid "Scale a aperture in the aperture list" msgstr "Scale a aperture in the aperture list" -#: flatcamEditors/FlatCAMGrbEditor.py:2656 flatcamGUI/PreferencesUI.py:2623 +#: flatcamEditors/FlatCAMGrbEditor.py:2662 flatcamGUI/PreferencesUI.py:2805 msgid "Scale factor" msgstr "Scale factor" -#: flatcamEditors/FlatCAMGrbEditor.py:2658 +#: flatcamEditors/FlatCAMGrbEditor.py:2664 msgid "" "The factor by which to scale the selected aperture.\n" "Values can be between 0.0000 and 999.9999" @@ -4819,19 +5230,19 @@ msgstr "" "The factor by which to scale the selected aperture.\n" "Values can be between 0.0000 and 999.9999" -#: flatcamEditors/FlatCAMGrbEditor.py:2686 +#: flatcamEditors/FlatCAMGrbEditor.py:2692 msgid "Mark polygons" msgstr "Mark polygons" -#: flatcamEditors/FlatCAMGrbEditor.py:2688 +#: flatcamEditors/FlatCAMGrbEditor.py:2694 msgid "Mark the polygon areas." msgstr "Mark the polygon areas." -#: flatcamEditors/FlatCAMGrbEditor.py:2696 +#: flatcamEditors/FlatCAMGrbEditor.py:2702 msgid "Area UPPER threshold" msgstr "Area UPPER threshold" -#: flatcamEditors/FlatCAMGrbEditor.py:2698 +#: flatcamEditors/FlatCAMGrbEditor.py:2704 msgid "" "The threshold value, all areas less than this are marked.\n" "Can have a value between 0.0000 and 9999.9999" @@ -4839,11 +5250,11 @@ msgstr "" "The threshold value, all areas less than this are marked.\n" "Can have a value between 0.0000 and 9999.9999" -#: flatcamEditors/FlatCAMGrbEditor.py:2705 +#: flatcamEditors/FlatCAMGrbEditor.py:2711 msgid "Area LOWER threshold" msgstr "Area LOWER threshold" -#: flatcamEditors/FlatCAMGrbEditor.py:2707 +#: flatcamEditors/FlatCAMGrbEditor.py:2713 msgid "" "The threshold value, all areas more than this are marked.\n" "Can have a value between 0.0000 and 9999.9999" @@ -4851,36 +5262,32 @@ msgstr "" "The threshold value, all areas more than this are marked.\n" "Can have a value between 0.0000 and 9999.9999" -#: flatcamEditors/FlatCAMGrbEditor.py:2721 +#: flatcamEditors/FlatCAMGrbEditor.py:2727 msgid "Mark" msgstr "Mark" -#: flatcamEditors/FlatCAMGrbEditor.py:2723 +#: flatcamEditors/FlatCAMGrbEditor.py:2729 msgid "Mark the polygons that fit within limits." msgstr "Mark the polygons that fit within limits." -#: flatcamEditors/FlatCAMGrbEditor.py:2729 +#: flatcamEditors/FlatCAMGrbEditor.py:2735 msgid "Delete all the marked polygons." msgstr "Delete all the marked polygons." -#: flatcamEditors/FlatCAMGrbEditor.py:2733 -msgid "Clear" -msgstr "Clear" - -#: flatcamEditors/FlatCAMGrbEditor.py:2735 +#: flatcamEditors/FlatCAMGrbEditor.py:2741 msgid "Clear all the markings." msgstr "Clear all the markings." -#: flatcamEditors/FlatCAMGrbEditor.py:2755 flatcamGUI/FlatCAMGUI.py:963 -#: flatcamGUI/FlatCAMGUI.py:2015 flatcamGUI/FlatCAMGUI.py:2532 +#: flatcamEditors/FlatCAMGrbEditor.py:2761 flatcamGUI/FlatCAMGUI.py:1031 +#: flatcamGUI/FlatCAMGUI.py:2123 flatcamGUI/FlatCAMGUI.py:2706 msgid "Add Pad Array" msgstr "Add Pad Array" -#: flatcamEditors/FlatCAMGrbEditor.py:2757 +#: flatcamEditors/FlatCAMGrbEditor.py:2763 msgid "Add an array of pads (linear or circular array)" msgstr "Add an array of pads (linear or circular array)" -#: flatcamEditors/FlatCAMGrbEditor.py:2763 +#: flatcamEditors/FlatCAMGrbEditor.py:2769 msgid "" "Select the type of pads array to create.\n" "It can be Linear X(Y) or Circular" @@ -4888,15 +5295,15 @@ msgstr "" "Select the type of pads array to create.\n" "It can be Linear X(Y) or Circular" -#: flatcamEditors/FlatCAMGrbEditor.py:2774 flatcamGUI/PreferencesUI.py:2511 +#: flatcamEditors/FlatCAMGrbEditor.py:2780 flatcamGUI/PreferencesUI.py:2691 msgid "Nr of pads" msgstr "Nr of pads" -#: flatcamEditors/FlatCAMGrbEditor.py:2776 flatcamGUI/PreferencesUI.py:2513 +#: flatcamEditors/FlatCAMGrbEditor.py:2782 flatcamGUI/PreferencesUI.py:2693 msgid "Specify how many pads to be in the array." msgstr "Specify how many pads to be in the array." -#: flatcamEditors/FlatCAMGrbEditor.py:2825 +#: flatcamEditors/FlatCAMGrbEditor.py:2831 msgid "" "Angle at which the linear array is placed.\n" "The precision is of max 2 decimals.\n" @@ -4908,12 +5315,12 @@ msgstr "" "Min value is: -359.99 degrees.\n" "Max value is: 360.00 degrees." -#: flatcamEditors/FlatCAMGrbEditor.py:3307 -#: flatcamEditors/FlatCAMGrbEditor.py:3311 +#: flatcamEditors/FlatCAMGrbEditor.py:3321 +#: flatcamEditors/FlatCAMGrbEditor.py:3325 msgid "Aperture code value is missing or wrong format. Add it and retry." msgstr "Aperture code value is missing or wrong format. Add it and retry." -#: flatcamEditors/FlatCAMGrbEditor.py:3347 +#: flatcamEditors/FlatCAMGrbEditor.py:3361 msgid "" "Aperture dimensions value is missing or wrong format. Add it in format " "(width, height) and retry." @@ -4921,178 +5328,178 @@ msgstr "" "Aperture dimensions value is missing or wrong format. Add it in format " "(width, height) and retry." -#: flatcamEditors/FlatCAMGrbEditor.py:3360 +#: flatcamEditors/FlatCAMGrbEditor.py:3374 msgid "Aperture size value is missing or wrong format. Add it and retry." msgstr "Aperture size value is missing or wrong format. Add it and retry." -#: flatcamEditors/FlatCAMGrbEditor.py:3371 +#: flatcamEditors/FlatCAMGrbEditor.py:3385 msgid "Aperture already in the aperture table." msgstr "Aperture already in the aperture table." -#: flatcamEditors/FlatCAMGrbEditor.py:3379 +#: flatcamEditors/FlatCAMGrbEditor.py:3393 msgid "Added new aperture with code" msgstr "Added new aperture with code" -#: flatcamEditors/FlatCAMGrbEditor.py:3408 +#: flatcamEditors/FlatCAMGrbEditor.py:3422 msgid " Select an aperture in Aperture Table" msgstr " Select an aperture in Aperture Table" -#: flatcamEditors/FlatCAMGrbEditor.py:3416 +#: flatcamEditors/FlatCAMGrbEditor.py:3430 msgid "Select an aperture in Aperture Table -->" msgstr "Select an aperture in Aperture Table -->" -#: flatcamEditors/FlatCAMGrbEditor.py:3439 +#: flatcamEditors/FlatCAMGrbEditor.py:3453 msgid "Deleted aperture with code" msgstr "Deleted aperture with code" -#: flatcamEditors/FlatCAMGrbEditor.py:3924 +#: flatcamEditors/FlatCAMGrbEditor.py:3950 msgid "Loading Gerber into Editor" msgstr "Loading Gerber into Editor" -#: flatcamEditors/FlatCAMGrbEditor.py:4034 +#: flatcamEditors/FlatCAMGrbEditor.py:4078 msgid "Setting up the UI" msgstr "Setting up the UI" -#: flatcamEditors/FlatCAMGrbEditor.py:4035 +#: flatcamEditors/FlatCAMGrbEditor.py:4079 msgid "Adding geometry finished. Preparing the GUI" msgstr "Adding geometry finished. Preparing the GUI" -#: flatcamEditors/FlatCAMGrbEditor.py:4044 +#: flatcamEditors/FlatCAMGrbEditor.py:4088 msgid "Finished loading the Gerber object into the editor." msgstr "Finished loading the Gerber object into the editor." -#: flatcamEditors/FlatCAMGrbEditor.py:4184 +#: flatcamEditors/FlatCAMGrbEditor.py:4228 msgid "" "There are no Aperture definitions in the file. Aborting Gerber creation." msgstr "" "There are no Aperture definitions in the file. Aborting Gerber creation." -#: flatcamEditors/FlatCAMGrbEditor.py:4194 +#: flatcamEditors/FlatCAMGrbEditor.py:4238 msgid "Creating Gerber." msgstr "Creating Gerber." -#: flatcamEditors/FlatCAMGrbEditor.py:4203 +#: flatcamEditors/FlatCAMGrbEditor.py:4247 msgid "Done. Gerber editing finished." msgstr "Done. Gerber editing finished." -#: flatcamEditors/FlatCAMGrbEditor.py:4222 +#: flatcamEditors/FlatCAMGrbEditor.py:4265 msgid "Cancelled. No aperture is selected" msgstr "Cancelled. No aperture is selected" -#: flatcamEditors/FlatCAMGrbEditor.py:4782 +#: flatcamEditors/FlatCAMGrbEditor.py:4826 msgid "Failed. No aperture geometry is selected." msgstr "Failed. No aperture geometry is selected." -#: flatcamEditors/FlatCAMGrbEditor.py:4791 -#: flatcamEditors/FlatCAMGrbEditor.py:5062 +#: flatcamEditors/FlatCAMGrbEditor.py:4835 +#: flatcamEditors/FlatCAMGrbEditor.py:5106 msgid "Done. Apertures geometry deleted." msgstr "Done. Apertures geometry deleted." -#: flatcamEditors/FlatCAMGrbEditor.py:4934 +#: flatcamEditors/FlatCAMGrbEditor.py:4978 msgid "No aperture to buffer. Select at least one aperture and try again." msgstr "No aperture to buffer. Select at least one aperture and try again." -#: flatcamEditors/FlatCAMGrbEditor.py:4946 +#: flatcamEditors/FlatCAMGrbEditor.py:4990 msgid "Failed." msgstr "Failed." -#: flatcamEditors/FlatCAMGrbEditor.py:4965 +#: flatcamEditors/FlatCAMGrbEditor.py:5009 msgid "Scale factor value is missing or wrong format. Add it and retry." msgstr "Scale factor value is missing or wrong format. Add it and retry." -#: flatcamEditors/FlatCAMGrbEditor.py:4997 +#: flatcamEditors/FlatCAMGrbEditor.py:5041 msgid "No aperture to scale. Select at least one aperture and try again." msgstr "No aperture to scale. Select at least one aperture and try again." -#: flatcamEditors/FlatCAMGrbEditor.py:5013 +#: flatcamEditors/FlatCAMGrbEditor.py:5057 msgid "Done. Scale Tool completed." msgstr "Done. Scale Tool completed." -#: flatcamEditors/FlatCAMGrbEditor.py:5051 +#: flatcamEditors/FlatCAMGrbEditor.py:5095 msgid "Polygons marked." msgstr "Polygons marked." -#: flatcamEditors/FlatCAMGrbEditor.py:5054 +#: flatcamEditors/FlatCAMGrbEditor.py:5098 msgid "No polygons were marked. None fit within the limits." msgstr "No polygons were marked. None fit within the limits." -#: flatcamEditors/FlatCAMGrbEditor.py:5783 +#: flatcamEditors/FlatCAMGrbEditor.py:5822 msgid "Rotation action was not executed." msgstr "Rotation action was not executed." -#: flatcamEditors/FlatCAMGrbEditor.py:5919 +#: flatcamEditors/FlatCAMGrbEditor.py:5950 msgid "Skew action was not executed." msgstr "Skew action was not executed." -#: flatcamEditors/FlatCAMGrbEditor.py:5986 +#: flatcamEditors/FlatCAMGrbEditor.py:6015 msgid "Scale action was not executed." msgstr "Scale action was not executed." -#: flatcamEditors/FlatCAMGrbEditor.py:6029 +#: flatcamEditors/FlatCAMGrbEditor.py:6058 msgid "Offset action was not executed." msgstr "Offset action was not executed." -#: flatcamEditors/FlatCAMGrbEditor.py:6079 +#: flatcamEditors/FlatCAMGrbEditor.py:6108 msgid "Geometry shape offset Y cancelled" msgstr "Geometry shape offset Y cancelled" -#: flatcamEditors/FlatCAMGrbEditor.py:6094 +#: flatcamEditors/FlatCAMGrbEditor.py:6123 msgid "Geometry shape skew X cancelled" msgstr "Geometry shape skew X cancelled" -#: flatcamEditors/FlatCAMGrbEditor.py:6109 +#: flatcamEditors/FlatCAMGrbEditor.py:6138 msgid "Geometry shape skew Y cancelled" msgstr "Geometry shape skew Y cancelled" -#: flatcamEditors/FlatCAMTextEditor.py:72 +#: flatcamEditors/FlatCAMTextEditor.py:74 msgid "Print Preview" msgstr "Print Preview" -#: flatcamEditors/FlatCAMTextEditor.py:73 +#: flatcamEditors/FlatCAMTextEditor.py:75 msgid "Open a OS standard Preview Print window." msgstr "Open a OS standard Preview Print window." -#: flatcamEditors/FlatCAMTextEditor.py:76 +#: flatcamEditors/FlatCAMTextEditor.py:78 msgid "Print Code" msgstr "Print Code" -#: flatcamEditors/FlatCAMTextEditor.py:77 +#: flatcamEditors/FlatCAMTextEditor.py:79 msgid "Open a OS standard Print window." msgstr "Open a OS standard Print window." -#: flatcamEditors/FlatCAMTextEditor.py:79 +#: flatcamEditors/FlatCAMTextEditor.py:81 msgid "Find in Code" msgstr "Find in Code" -#: flatcamEditors/FlatCAMTextEditor.py:80 +#: flatcamEditors/FlatCAMTextEditor.py:82 msgid "Will search and highlight in yellow the string in the Find box." msgstr "Will search and highlight in yellow the string in the Find box." -#: flatcamEditors/FlatCAMTextEditor.py:84 +#: flatcamEditors/FlatCAMTextEditor.py:86 msgid "Find box. Enter here the strings to be searched in the text." msgstr "Find box. Enter here the strings to be searched in the text." -#: flatcamEditors/FlatCAMTextEditor.py:86 +#: flatcamEditors/FlatCAMTextEditor.py:88 msgid "Replace With" msgstr "Replace With" -#: flatcamEditors/FlatCAMTextEditor.py:87 +#: flatcamEditors/FlatCAMTextEditor.py:89 msgid "" "Will replace the string from the Find box with the one in the Replace box." msgstr "" "Will replace the string from the Find box with the one in the Replace box." -#: flatcamEditors/FlatCAMTextEditor.py:91 +#: flatcamEditors/FlatCAMTextEditor.py:93 msgid "String to replace the one in the Find box throughout the text." msgstr "String to replace the one in the Find box throughout the text." -#: flatcamEditors/FlatCAMTextEditor.py:93 flatcamGUI/ObjectUI.py:482 -#: flatcamGUI/ObjectUI.py:1809 flatcamGUI/PreferencesUI.py:2070 -#: flatcamGUI/PreferencesUI.py:4419 flatcamGUI/PreferencesUI.py:5647 +#: flatcamEditors/FlatCAMTextEditor.py:95 flatcamGUI/ObjectUI.py:485 +#: flatcamGUI/ObjectUI.py:2137 flatcamGUI/PreferencesUI.py:2250 +#: flatcamGUI/PreferencesUI.py:4712 msgid "All" msgstr "All" -#: flatcamEditors/FlatCAMTextEditor.py:94 +#: flatcamEditors/FlatCAMTextEditor.py:96 msgid "" "When checked it will replace all instances in the 'Find' box\n" "with the text in the 'Replace' box.." @@ -5100,307 +5507,301 @@ msgstr "" "When checked it will replace all instances in the 'Find' box\n" "with the text in the 'Replace' box.." -#: flatcamEditors/FlatCAMTextEditor.py:97 +#: flatcamEditors/FlatCAMTextEditor.py:99 msgid "Copy All" msgstr "Copy All" -#: flatcamEditors/FlatCAMTextEditor.py:98 +#: flatcamEditors/FlatCAMTextEditor.py:100 msgid "Will copy all the text in the Code Editor to the clipboard." msgstr "Will copy all the text in the Code Editor to the clipboard." -#: flatcamEditors/FlatCAMTextEditor.py:101 +#: flatcamEditors/FlatCAMTextEditor.py:103 msgid "Open Code" msgstr "Open Code" -#: flatcamEditors/FlatCAMTextEditor.py:102 +#: flatcamEditors/FlatCAMTextEditor.py:104 msgid "Will open a text file in the editor." msgstr "Will open a text file in the editor." -#: flatcamEditors/FlatCAMTextEditor.py:104 +#: flatcamEditors/FlatCAMTextEditor.py:106 msgid "Save Code" msgstr "Save Code" -#: flatcamEditors/FlatCAMTextEditor.py:105 +#: flatcamEditors/FlatCAMTextEditor.py:107 msgid "Will save the text in the editor into a file." msgstr "Will save the text in the editor into a file." -#: flatcamEditors/FlatCAMTextEditor.py:107 +#: flatcamEditors/FlatCAMTextEditor.py:109 msgid "Run Code" msgstr "Run Code" -#: flatcamEditors/FlatCAMTextEditor.py:108 +#: flatcamEditors/FlatCAMTextEditor.py:110 msgid "Will run the TCL commands found in the text file, one by one." msgstr "Will run the TCL commands found in the text file, one by one." -#: flatcamEditors/FlatCAMTextEditor.py:182 +#: flatcamEditors/FlatCAMTextEditor.py:184 msgid "Open file" msgstr "Open file" -#: flatcamEditors/FlatCAMTextEditor.py:213 -#: flatcamEditors/FlatCAMTextEditor.py:218 +#: flatcamEditors/FlatCAMTextEditor.py:215 +#: flatcamEditors/FlatCAMTextEditor.py:220 msgid "Export Code ..." msgstr "Export Code ..." -#: flatcamEditors/FlatCAMTextEditor.py:221 -msgid "Export Code cancelled." -msgstr "Export Code cancelled." - -#: flatcamEditors/FlatCAMTextEditor.py:332 +#: flatcamEditors/FlatCAMTextEditor.py:334 msgid "Code Editor content copied to clipboard ..." msgstr "Code Editor content copied to clipboard ..." -#: flatcamGUI/FlatCAMGUI.py:52 flatcamGUI/FlatCAMGUI.py:54 -#: flatcamGUI/FlatCAMGUI.py:2040 +#: flatcamGUI/FlatCAMGUI.py:66 flatcamGUI/FlatCAMGUI.py:68 +#: flatcamGUI/FlatCAMGUI.py:2148 msgid "Toggle Panel" msgstr "Toggle Panel" -#: flatcamGUI/FlatCAMGUI.py:64 +#: flatcamGUI/FlatCAMGUI.py:78 msgid "File" msgstr "File" -#: flatcamGUI/FlatCAMGUI.py:69 +#: flatcamGUI/FlatCAMGUI.py:83 msgid "&New Project ...\tCtrl+N" msgstr "&New Project ...\tCtrl+N" -#: flatcamGUI/FlatCAMGUI.py:71 +#: flatcamGUI/FlatCAMGUI.py:85 msgid "Will create a new, blank project" msgstr "Will create a new, blank project" -#: flatcamGUI/FlatCAMGUI.py:76 +#: flatcamGUI/FlatCAMGUI.py:90 msgid "&New" msgstr "&New" -#: flatcamGUI/FlatCAMGUI.py:80 +#: flatcamGUI/FlatCAMGUI.py:94 msgid "Geometry\tN" msgstr "Geometry\tN" -#: flatcamGUI/FlatCAMGUI.py:82 +#: flatcamGUI/FlatCAMGUI.py:96 msgid "Will create a new, empty Geometry Object." msgstr "Will create a new, empty Geometry Object." -#: flatcamGUI/FlatCAMGUI.py:84 +#: flatcamGUI/FlatCAMGUI.py:99 msgid "Gerber\tB" msgstr "Gerber\tB" -#: flatcamGUI/FlatCAMGUI.py:86 +#: flatcamGUI/FlatCAMGUI.py:101 msgid "Will create a new, empty Gerber Object." msgstr "Will create a new, empty Gerber Object." -#: flatcamGUI/FlatCAMGUI.py:88 +#: flatcamGUI/FlatCAMGUI.py:104 msgid "Excellon\tL" msgstr "Excellon\tL" -#: flatcamGUI/FlatCAMGUI.py:90 +#: flatcamGUI/FlatCAMGUI.py:106 msgid "Will create a new, empty Excellon Object." msgstr "Will create a new, empty Excellon Object." -#: flatcamGUI/FlatCAMGUI.py:94 +#: flatcamGUI/FlatCAMGUI.py:111 msgid "Document\tD" msgstr "Document\tD" -#: flatcamGUI/FlatCAMGUI.py:96 +#: flatcamGUI/FlatCAMGUI.py:113 msgid "Will create a new, empty Document Object." msgstr "Will create a new, empty Document Object." -#: flatcamGUI/FlatCAMGUI.py:99 flatcamGUI/FlatCAMGUI.py:4111 +#: flatcamGUI/FlatCAMGUI.py:117 flatcamGUI/FlatCAMGUI.py:4327 #: flatcamTools/ToolPcbWizard.py:62 flatcamTools/ToolPcbWizard.py:69 msgid "Open" msgstr "Open" -#: flatcamGUI/FlatCAMGUI.py:103 +#: flatcamGUI/FlatCAMGUI.py:122 msgid "Open &Project ..." msgstr "Open &Project ..." -#: flatcamGUI/FlatCAMGUI.py:109 flatcamGUI/FlatCAMGUI.py:4121 +#: flatcamGUI/FlatCAMGUI.py:128 flatcamGUI/FlatCAMGUI.py:4337 msgid "Open &Gerber ...\tCtrl+G" msgstr "Open &Gerber ...\tCtrl+G" -#: flatcamGUI/FlatCAMGUI.py:114 flatcamGUI/FlatCAMGUI.py:4126 +#: flatcamGUI/FlatCAMGUI.py:133 flatcamGUI/FlatCAMGUI.py:4342 msgid "Open &Excellon ...\tCtrl+E" msgstr "Open &Excellon ...\tCtrl+E" -#: flatcamGUI/FlatCAMGUI.py:118 flatcamGUI/FlatCAMGUI.py:4131 +#: flatcamGUI/FlatCAMGUI.py:138 flatcamGUI/FlatCAMGUI.py:4347 msgid "Open G-&Code ..." msgstr "Open G-&Code ..." -#: flatcamGUI/FlatCAMGUI.py:124 +#: flatcamGUI/FlatCAMGUI.py:145 msgid "Open Config ..." msgstr "Open Config ..." -#: flatcamGUI/FlatCAMGUI.py:128 +#: flatcamGUI/FlatCAMGUI.py:150 msgid "Recent projects" msgstr "Recent projects" -#: flatcamGUI/FlatCAMGUI.py:129 +#: flatcamGUI/FlatCAMGUI.py:152 msgid "Recent files" msgstr "Recent files" -#: flatcamGUI/FlatCAMGUI.py:135 -msgid "Scripting" -msgstr "Scripting" - -#: flatcamGUI/FlatCAMGUI.py:138 flatcamGUI/FlatCAMGUI.py:829 -#: flatcamGUI/FlatCAMGUI.py:2409 -msgid "New Script ..." -msgstr "New Script ..." - -#: flatcamGUI/FlatCAMGUI.py:139 flatcamGUI/FlatCAMGUI.py:831 -#: flatcamGUI/FlatCAMGUI.py:2411 -msgid "Open Script ..." -msgstr "Open Script ..." - -#: flatcamGUI/FlatCAMGUI.py:141 flatcamGUI/FlatCAMGUI.py:833 -#: flatcamGUI/FlatCAMGUI.py:2413 flatcamGUI/FlatCAMGUI.py:4100 -msgid "Run Script ..." -msgstr "Run Script ..." - -#: flatcamGUI/FlatCAMGUI.py:143 flatcamGUI/FlatCAMGUI.py:4102 -msgid "" -"Will run the opened Tcl Script thus\n" -"enabling the automation of certain\n" -"functions of FlatCAM." -msgstr "" -"Will run the opened Tcl Script thus\n" -"enabling the automation of certain\n" -"functions of FlatCAM." - -#: flatcamGUI/FlatCAMGUI.py:156 -msgid "Import" -msgstr "Import" - -#: flatcamGUI/FlatCAMGUI.py:158 -msgid "&SVG as Geometry Object ..." -msgstr "&SVG as Geometry Object ..." - -#: flatcamGUI/FlatCAMGUI.py:161 -msgid "&SVG as Gerber Object ..." -msgstr "&SVG as Gerber Object ..." - -#: flatcamGUI/FlatCAMGUI.py:166 -msgid "&DXF as Geometry Object ..." -msgstr "&DXF as Geometry Object ..." - -#: flatcamGUI/FlatCAMGUI.py:169 -msgid "&DXF as Gerber Object ..." -msgstr "&DXF as Gerber Object ..." - -#: flatcamGUI/FlatCAMGUI.py:173 -msgid "HPGL2 as Geometry Object ..." -msgstr "HPGL2 as Geometry Object ..." - -#: flatcamGUI/FlatCAMGUI.py:178 -msgid "Export" -msgstr "Export" - -#: flatcamGUI/FlatCAMGUI.py:181 -msgid "Export &SVG ..." -msgstr "Export &SVG ..." - -#: flatcamGUI/FlatCAMGUI.py:184 -msgid "Export DXF ..." -msgstr "Export DXF ..." - -#: flatcamGUI/FlatCAMGUI.py:189 -msgid "Export &PNG ..." -msgstr "Export &PNG ..." - -#: flatcamGUI/FlatCAMGUI.py:191 -msgid "" -"Will export an image in PNG format,\n" -"the saved image will contain the visual \n" -"information currently in FlatCAM Plot Area." -msgstr "" -"Will export an image in PNG format,\n" -"the saved image will contain the visual \n" -"information currently in FlatCAM Plot Area." - -#: flatcamGUI/FlatCAMGUI.py:200 -msgid "Export &Excellon ..." -msgstr "Export &Excellon ..." - -#: flatcamGUI/FlatCAMGUI.py:202 -msgid "" -"Will export an Excellon Object as Excellon file,\n" -"the coordinates format, the file units and zeros\n" -"are set in Preferences -> Excellon Export." -msgstr "" -"Will export an Excellon Object as Excellon file,\n" -"the coordinates format, the file units and zeros\n" -"are set in Preferences -> Excellon Export." - -#: flatcamGUI/FlatCAMGUI.py:209 -msgid "Export &Gerber ..." -msgstr "Export &Gerber ..." - -#: flatcamGUI/FlatCAMGUI.py:211 -msgid "" -"Will export an Gerber Object as Gerber file,\n" -"the coordinates format, the file units and zeros\n" -"are set in Preferences -> Gerber Export." -msgstr "" -"Will export an Gerber Object as Gerber file,\n" -"the coordinates format, the file units and zeros\n" -"are set in Preferences -> Gerber Export." - -#: flatcamGUI/FlatCAMGUI.py:229 -msgid "Backup" -msgstr "Backup" - -#: flatcamGUI/FlatCAMGUI.py:233 -msgid "Import Preferences from file ..." -msgstr "Import Preferences from file ..." - -#: flatcamGUI/FlatCAMGUI.py:238 -msgid "Export Preferences to file ..." -msgstr "Export Preferences to file ..." - -#: flatcamGUI/FlatCAMGUI.py:244 flatcamGUI/FlatCAMGUI.py:1614 -msgid "Print (PDF)" -msgstr "Print (PDF)" - -#: flatcamGUI/FlatCAMGUI.py:247 flatcamGUI/FlatCAMGUI.py:682 -#: flatcamGUI/FlatCAMGUI.py:1252 +#: flatcamGUI/FlatCAMGUI.py:155 flatcamGUI/FlatCAMGUI.py:738 +#: flatcamGUI/FlatCAMGUI.py:1324 msgid "Save" msgstr "Save" +#: flatcamGUI/FlatCAMGUI.py:159 +#| msgid "Save Project &As ...\tCtrl+S" +msgid "&Save Project ...\tCtrl+S" +msgstr "&Save Project ...\tCtrl+S" + +#: flatcamGUI/FlatCAMGUI.py:164 +#| msgid "Save Project &As ...\tCtrl+S" +msgid "Save Project &As ...\tCtrl+Shift+S" +msgstr "Save Project &As ...\tCtrl+Shift+S" + +#: flatcamGUI/FlatCAMGUI.py:179 +msgid "Scripting" +msgstr "Scripting" + +#: flatcamGUI/FlatCAMGUI.py:183 flatcamGUI/FlatCAMGUI.py:888 +#: flatcamGUI/FlatCAMGUI.py:2567 +msgid "New Script ..." +msgstr "New Script ..." + +#: flatcamGUI/FlatCAMGUI.py:185 flatcamGUI/FlatCAMGUI.py:890 +#: flatcamGUI/FlatCAMGUI.py:2569 +msgid "Open Script ..." +msgstr "Open Script ..." + +#: flatcamGUI/FlatCAMGUI.py:187 flatcamGUI/FlatCAMGUI.py:892 +#: flatcamGUI/FlatCAMGUI.py:2571 flatcamGUI/FlatCAMGUI.py:4316 +msgid "Run Script ..." +msgstr "Run Script ..." + +#: flatcamGUI/FlatCAMGUI.py:189 flatcamGUI/FlatCAMGUI.py:4318 +msgid "" +"Will run the opened Tcl Script thus\n" +"enabling the automation of certain\n" +"functions of FlatCAM." +msgstr "" +"Will run the opened Tcl Script thus\n" +"enabling the automation of certain\n" +"functions of FlatCAM." + +#: flatcamGUI/FlatCAMGUI.py:203 +msgid "Import" +msgstr "Import" + +#: flatcamGUI/FlatCAMGUI.py:205 +msgid "&SVG as Geometry Object ..." +msgstr "&SVG as Geometry Object ..." + +#: flatcamGUI/FlatCAMGUI.py:208 +msgid "&SVG as Gerber Object ..." +msgstr "&SVG as Gerber Object ..." + +#: flatcamGUI/FlatCAMGUI.py:213 +msgid "&DXF as Geometry Object ..." +msgstr "&DXF as Geometry Object ..." + +#: flatcamGUI/FlatCAMGUI.py:216 +msgid "&DXF as Gerber Object ..." +msgstr "&DXF as Gerber Object ..." + +#: flatcamGUI/FlatCAMGUI.py:220 +msgid "HPGL2 as Geometry Object ..." +msgstr "HPGL2 as Geometry Object ..." + +#: flatcamGUI/FlatCAMGUI.py:226 +msgid "Export" +msgstr "Export" + +#: flatcamGUI/FlatCAMGUI.py:230 +msgid "Export &SVG ..." +msgstr "Export &SVG ..." + +#: flatcamGUI/FlatCAMGUI.py:234 +msgid "Export DXF ..." +msgstr "Export DXF ..." + +#: flatcamGUI/FlatCAMGUI.py:240 +msgid "Export &PNG ..." +msgstr "Export &PNG ..." + +#: flatcamGUI/FlatCAMGUI.py:242 +msgid "" +"Will export an image in PNG format,\n" +"the saved image will contain the visual \n" +"information currently in FlatCAM Plot Area." +msgstr "" +"Will export an image in PNG format,\n" +"the saved image will contain the visual \n" +"information currently in FlatCAM Plot Area." + #: flatcamGUI/FlatCAMGUI.py:251 -msgid "&Save Project ..." -msgstr "&Save Project ..." +msgid "Export &Excellon ..." +msgstr "Export &Excellon ..." -#: flatcamGUI/FlatCAMGUI.py:256 -msgid "Save Project &As ...\tCtrl+S" -msgstr "Save Project &As ...\tCtrl+S" +#: flatcamGUI/FlatCAMGUI.py:253 +msgid "" +"Will export an Excellon Object as Excellon file,\n" +"the coordinates format, the file units and zeros\n" +"are set in Preferences -> Excellon Export." +msgstr "" +"Will export an Excellon Object as Excellon file,\n" +"the coordinates format, the file units and zeros\n" +"are set in Preferences -> Excellon Export." -#: flatcamGUI/FlatCAMGUI.py:261 -msgid "Save Project C&opy ..." -msgstr "Save Project C&opy ..." +#: flatcamGUI/FlatCAMGUI.py:260 +msgid "Export &Gerber ..." +msgstr "Export &Gerber ..." -#: flatcamGUI/FlatCAMGUI.py:271 +#: flatcamGUI/FlatCAMGUI.py:262 +msgid "" +"Will export an Gerber Object as Gerber file,\n" +"the coordinates format, the file units and zeros\n" +"are set in Preferences -> Gerber Export." +msgstr "" +"Will export an Gerber Object as Gerber file,\n" +"the coordinates format, the file units and zeros\n" +"are set in Preferences -> Gerber Export." + +#: flatcamGUI/FlatCAMGUI.py:272 +msgid "Backup" +msgstr "Backup" + +#: flatcamGUI/FlatCAMGUI.py:277 +msgid "Import Preferences from file ..." +msgstr "Import Preferences from file ..." + +#: flatcamGUI/FlatCAMGUI.py:283 +msgid "Export Preferences to file ..." +msgstr "Export Preferences to file ..." + +#: flatcamGUI/FlatCAMGUI.py:297 flatcamGUI/FlatCAMGUI.py:1715 +msgid "Print (PDF)" +msgstr "Print (PDF)" + +#: flatcamGUI/FlatCAMGUI.py:305 msgid "E&xit" msgstr "E&xit" -#: flatcamGUI/FlatCAMGUI.py:279 flatcamGUI/FlatCAMGUI.py:676 -#: flatcamGUI/FlatCAMGUI.py:2163 +#: flatcamGUI/FlatCAMGUI.py:313 flatcamGUI/FlatCAMGUI.py:732 +#: flatcamGUI/FlatCAMGUI.py:2271 msgid "Edit" msgstr "Edit" -#: flatcamGUI/FlatCAMGUI.py:283 +#: flatcamGUI/FlatCAMGUI.py:317 msgid "Edit Object\tE" msgstr "Edit Object\tE" -#: flatcamGUI/FlatCAMGUI.py:285 +#: flatcamGUI/FlatCAMGUI.py:319 msgid "Close Editor\tCtrl+S" msgstr "Close Editor\tCtrl+S" -#: flatcamGUI/FlatCAMGUI.py:294 +#: flatcamGUI/FlatCAMGUI.py:328 msgid "Conversion" msgstr "Conversion" -#: flatcamGUI/FlatCAMGUI.py:296 +#: flatcamGUI/FlatCAMGUI.py:330 msgid "&Join Geo/Gerber/Exc -> Geo" msgstr "&Join Geo/Gerber/Exc -> Geo" -#: flatcamGUI/FlatCAMGUI.py:298 +#: flatcamGUI/FlatCAMGUI.py:332 msgid "" "Merge a selection of objects, which can be of type:\n" "- Gerber\n" @@ -5414,28 +5815,28 @@ msgstr "" "- Geometry\n" "into a new combo Geometry object." -#: flatcamGUI/FlatCAMGUI.py:305 +#: flatcamGUI/FlatCAMGUI.py:339 msgid "Join Excellon(s) -> Excellon" msgstr "Join Excellon(s) -> Excellon" -#: flatcamGUI/FlatCAMGUI.py:307 +#: flatcamGUI/FlatCAMGUI.py:341 msgid "Merge a selection of Excellon objects into a new combo Excellon object." msgstr "" "Merge a selection of Excellon objects into a new combo Excellon object." -#: flatcamGUI/FlatCAMGUI.py:310 +#: flatcamGUI/FlatCAMGUI.py:344 msgid "Join Gerber(s) -> Gerber" msgstr "Join Gerber(s) -> Gerber" -#: flatcamGUI/FlatCAMGUI.py:312 +#: flatcamGUI/FlatCAMGUI.py:346 msgid "Merge a selection of Gerber objects into a new combo Gerber object." msgstr "Merge a selection of Gerber objects into a new combo Gerber object." -#: flatcamGUI/FlatCAMGUI.py:317 +#: flatcamGUI/FlatCAMGUI.py:351 msgid "Convert Single to MultiGeo" msgstr "Convert Single to MultiGeo" -#: flatcamGUI/FlatCAMGUI.py:319 +#: flatcamGUI/FlatCAMGUI.py:353 msgid "" "Will convert a Geometry object from single_geometry type\n" "to a multi_geometry type." @@ -5443,11 +5844,11 @@ msgstr "" "Will convert a Geometry object from single_geometry type\n" "to a multi_geometry type." -#: flatcamGUI/FlatCAMGUI.py:323 +#: flatcamGUI/FlatCAMGUI.py:357 msgid "Convert Multi to SingleGeo" msgstr "Convert Multi to SingleGeo" -#: flatcamGUI/FlatCAMGUI.py:325 +#: flatcamGUI/FlatCAMGUI.py:359 msgid "" "Will convert a Geometry object from multi_geometry type\n" "to a single_geometry type." @@ -5455,734 +5856,751 @@ msgstr "" "Will convert a Geometry object from multi_geometry type\n" "to a single_geometry type." -#: flatcamGUI/FlatCAMGUI.py:332 +#: flatcamGUI/FlatCAMGUI.py:366 msgid "Convert Any to Geo" msgstr "Convert Any to Geo" -#: flatcamGUI/FlatCAMGUI.py:335 +#: flatcamGUI/FlatCAMGUI.py:369 msgid "Convert Any to Gerber" msgstr "Convert Any to Gerber" -#: flatcamGUI/FlatCAMGUI.py:341 +#: flatcamGUI/FlatCAMGUI.py:375 msgid "&Copy\tCtrl+C" msgstr "&Copy\tCtrl+C" -#: flatcamGUI/FlatCAMGUI.py:346 +#: flatcamGUI/FlatCAMGUI.py:380 msgid "&Delete\tDEL" msgstr "&Delete\tDEL" -#: flatcamGUI/FlatCAMGUI.py:351 +#: flatcamGUI/FlatCAMGUI.py:385 msgid "Se&t Origin\tO" msgstr "Se&t Origin\tO" -#: flatcamGUI/FlatCAMGUI.py:353 +#: flatcamGUI/FlatCAMGUI.py:387 +#| msgid "Se&t Origin\tO" +msgid "Move to Origin\tShift+O" +msgstr "Move to Origin\tShift+O" + +#: flatcamGUI/FlatCAMGUI.py:390 msgid "Jump to Location\tJ" msgstr "Jump to Location\tJ" -#: flatcamGUI/FlatCAMGUI.py:358 +#: flatcamGUI/FlatCAMGUI.py:392 +msgid "Locate in Object\tShift+J" +msgstr "Locate in Object\tShift+J" + +#: flatcamGUI/FlatCAMGUI.py:397 msgid "Toggle Units\tQ" msgstr "Toggle Units\tQ" -#: flatcamGUI/FlatCAMGUI.py:360 +#: flatcamGUI/FlatCAMGUI.py:399 msgid "&Select All\tCtrl+A" msgstr "&Select All\tCtrl+A" -#: flatcamGUI/FlatCAMGUI.py:365 +#: flatcamGUI/FlatCAMGUI.py:404 msgid "&Preferences\tShift+P" msgstr "&Preferences\tShift+P" -#: flatcamGUI/FlatCAMGUI.py:371 flatcamTools/ToolProperties.py:153 +#: flatcamGUI/FlatCAMGUI.py:410 flatcamTools/ToolProperties.py:155 msgid "Options" msgstr "Options" -#: flatcamGUI/FlatCAMGUI.py:373 +#: flatcamGUI/FlatCAMGUI.py:412 msgid "&Rotate Selection\tShift+(R)" msgstr "&Rotate Selection\tShift+(R)" -#: flatcamGUI/FlatCAMGUI.py:378 +#: flatcamGUI/FlatCAMGUI.py:417 msgid "&Skew on X axis\tShift+X" msgstr "&Skew on X axis\tShift+X" -#: flatcamGUI/FlatCAMGUI.py:380 +#: flatcamGUI/FlatCAMGUI.py:419 msgid "S&kew on Y axis\tShift+Y" msgstr "S&kew on Y axis\tShift+Y" -#: flatcamGUI/FlatCAMGUI.py:385 +#: flatcamGUI/FlatCAMGUI.py:424 msgid "Flip on &X axis\tX" msgstr "Flip on &X axis\tX" -#: flatcamGUI/FlatCAMGUI.py:387 +#: flatcamGUI/FlatCAMGUI.py:426 msgid "Flip on &Y axis\tY" msgstr "Flip on &Y axis\tY" -#: flatcamGUI/FlatCAMGUI.py:392 +#: flatcamGUI/FlatCAMGUI.py:431 msgid "View source\tAlt+S" msgstr "View source\tAlt+S" -#: flatcamGUI/FlatCAMGUI.py:394 +#: flatcamGUI/FlatCAMGUI.py:433 msgid "Tools DataBase\tCtrl+D" msgstr "Tools DataBase\tCtrl+D" -#: flatcamGUI/FlatCAMGUI.py:401 flatcamGUI/FlatCAMGUI.py:2060 +#: flatcamGUI/FlatCAMGUI.py:440 flatcamGUI/FlatCAMGUI.py:2168 msgid "View" msgstr "View" -#: flatcamGUI/FlatCAMGUI.py:403 +#: flatcamGUI/FlatCAMGUI.py:442 msgid "Enable all plots\tAlt+1" msgstr "Enable all plots\tAlt+1" -#: flatcamGUI/FlatCAMGUI.py:405 +#: flatcamGUI/FlatCAMGUI.py:444 msgid "Disable all plots\tAlt+2" msgstr "Disable all plots\tAlt+2" -#: flatcamGUI/FlatCAMGUI.py:407 +#: flatcamGUI/FlatCAMGUI.py:446 msgid "Disable non-selected\tAlt+3" msgstr "Disable non-selected\tAlt+3" -#: flatcamGUI/FlatCAMGUI.py:411 +#: flatcamGUI/FlatCAMGUI.py:450 msgid "&Zoom Fit\tV" msgstr "&Zoom Fit\tV" -#: flatcamGUI/FlatCAMGUI.py:413 +#: flatcamGUI/FlatCAMGUI.py:452 msgid "&Zoom In\t=" msgstr "&Zoom In\t=" -#: flatcamGUI/FlatCAMGUI.py:415 +#: flatcamGUI/FlatCAMGUI.py:454 msgid "&Zoom Out\t-" msgstr "&Zoom Out\t-" -#: flatcamGUI/FlatCAMGUI.py:420 +#: flatcamGUI/FlatCAMGUI.py:459 msgid "Redraw All\tF5" msgstr "Redraw All\tF5" -#: flatcamGUI/FlatCAMGUI.py:424 +#: flatcamGUI/FlatCAMGUI.py:463 msgid "Toggle Code Editor\tShift+E" msgstr "Toggle Code Editor\tShift+E" -#: flatcamGUI/FlatCAMGUI.py:427 +#: flatcamGUI/FlatCAMGUI.py:466 msgid "&Toggle FullScreen\tAlt+F10" msgstr "&Toggle FullScreen\tAlt+F10" -#: flatcamGUI/FlatCAMGUI.py:429 +#: flatcamGUI/FlatCAMGUI.py:468 msgid "&Toggle Plot Area\tCtrl+F10" msgstr "&Toggle Plot Area\tCtrl+F10" -#: flatcamGUI/FlatCAMGUI.py:431 +#: flatcamGUI/FlatCAMGUI.py:470 msgid "&Toggle Project/Sel/Tool\t`" msgstr "&Toggle Project/Sel/Tool\t`" -#: flatcamGUI/FlatCAMGUI.py:435 +#: flatcamGUI/FlatCAMGUI.py:474 msgid "&Toggle Grid Snap\tG" msgstr "&Toggle Grid Snap\tG" -#: flatcamGUI/FlatCAMGUI.py:437 +#: flatcamGUI/FlatCAMGUI.py:476 msgid "&Toggle Grid Lines\tAlt+G" msgstr "&Toggle Grid Lines\tAlt+G" -#: flatcamGUI/FlatCAMGUI.py:439 +#: flatcamGUI/FlatCAMGUI.py:478 msgid "&Toggle Axis\tShift+G" msgstr "&Toggle Axis\tShift+G" -#: flatcamGUI/FlatCAMGUI.py:441 +#: flatcamGUI/FlatCAMGUI.py:480 msgid "Toggle Workspace\tShift+W" msgstr "Toggle Workspace\tShift+W" -#: flatcamGUI/FlatCAMGUI.py:446 +#: flatcamGUI/FlatCAMGUI.py:485 msgid "Objects" msgstr "Objects" -#: flatcamGUI/FlatCAMGUI.py:460 +#: flatcamGUI/FlatCAMGUI.py:499 msgid "&Command Line\tS" msgstr "&Command Line\tS" -#: flatcamGUI/FlatCAMGUI.py:465 +#: flatcamGUI/FlatCAMGUI.py:504 msgid "Help" msgstr "Help" -#: flatcamGUI/FlatCAMGUI.py:467 +#: flatcamGUI/FlatCAMGUI.py:506 msgid "Online Help\tF1" msgstr "Online Help\tF1" -#: flatcamGUI/FlatCAMGUI.py:477 +#: flatcamGUI/FlatCAMGUI.py:516 msgid "Report a bug" msgstr "Report a bug" -#: flatcamGUI/FlatCAMGUI.py:480 +#: flatcamGUI/FlatCAMGUI.py:519 msgid "Excellon Specification" msgstr "Excellon Specification" -#: flatcamGUI/FlatCAMGUI.py:482 +#: flatcamGUI/FlatCAMGUI.py:521 msgid "Gerber Specification" msgstr "Gerber Specification" -#: flatcamGUI/FlatCAMGUI.py:487 +#: flatcamGUI/FlatCAMGUI.py:526 msgid "Shortcuts List\tF3" msgstr "Shortcuts List\tF3" -#: flatcamGUI/FlatCAMGUI.py:489 +#: flatcamGUI/FlatCAMGUI.py:528 msgid "YouTube Channel\tF4" msgstr "YouTube Channel\tF4" -#: flatcamGUI/FlatCAMGUI.py:500 +#: flatcamGUI/FlatCAMGUI.py:539 msgid "Add Circle\tO" msgstr "Add Circle\tO" -#: flatcamGUI/FlatCAMGUI.py:503 +#: flatcamGUI/FlatCAMGUI.py:542 msgid "Add Arc\tA" msgstr "Add Arc\tA" -#: flatcamGUI/FlatCAMGUI.py:506 +#: flatcamGUI/FlatCAMGUI.py:545 msgid "Add Rectangle\tR" msgstr "Add Rectangle\tR" -#: flatcamGUI/FlatCAMGUI.py:509 +#: flatcamGUI/FlatCAMGUI.py:548 msgid "Add Polygon\tN" msgstr "Add Polygon\tN" -#: flatcamGUI/FlatCAMGUI.py:512 +#: flatcamGUI/FlatCAMGUI.py:551 msgid "Add Path\tP" msgstr "Add Path\tP" -#: flatcamGUI/FlatCAMGUI.py:515 +#: flatcamGUI/FlatCAMGUI.py:554 msgid "Add Text\tT" msgstr "Add Text\tT" -#: flatcamGUI/FlatCAMGUI.py:518 +#: flatcamGUI/FlatCAMGUI.py:557 msgid "Polygon Union\tU" msgstr "Polygon Union\tU" -#: flatcamGUI/FlatCAMGUI.py:520 +#: flatcamGUI/FlatCAMGUI.py:559 msgid "Polygon Intersection\tE" msgstr "Polygon Intersection\tE" -#: flatcamGUI/FlatCAMGUI.py:522 +#: flatcamGUI/FlatCAMGUI.py:561 msgid "Polygon Subtraction\tS" msgstr "Polygon Subtraction\tS" -#: flatcamGUI/FlatCAMGUI.py:526 +#: flatcamGUI/FlatCAMGUI.py:565 msgid "Cut Path\tX" msgstr "Cut Path\tX" -#: flatcamGUI/FlatCAMGUI.py:529 +#: flatcamGUI/FlatCAMGUI.py:569 msgid "Copy Geom\tC" msgstr "Copy Geom\tC" -#: flatcamGUI/FlatCAMGUI.py:531 +#: flatcamGUI/FlatCAMGUI.py:571 msgid "Delete Shape\tDEL" msgstr "Delete Shape\tDEL" -#: flatcamGUI/FlatCAMGUI.py:535 flatcamGUI/FlatCAMGUI.py:622 +#: flatcamGUI/FlatCAMGUI.py:575 flatcamGUI/FlatCAMGUI.py:662 msgid "Move\tM" msgstr "Move\tM" -#: flatcamGUI/FlatCAMGUI.py:537 +#: flatcamGUI/FlatCAMGUI.py:577 msgid "Buffer Tool\tB" msgstr "Buffer Tool\tB" -#: flatcamGUI/FlatCAMGUI.py:540 +#: flatcamGUI/FlatCAMGUI.py:580 msgid "Paint Tool\tI" msgstr "Paint Tool\tI" -#: flatcamGUI/FlatCAMGUI.py:543 +#: flatcamGUI/FlatCAMGUI.py:583 msgid "Transform Tool\tAlt+R" msgstr "Transform Tool\tAlt+R" -#: flatcamGUI/FlatCAMGUI.py:547 +#: flatcamGUI/FlatCAMGUI.py:587 msgid "Toggle Corner Snap\tK" msgstr "Toggle Corner Snap\tK" -#: flatcamGUI/FlatCAMGUI.py:553 +#: flatcamGUI/FlatCAMGUI.py:593 msgid ">Excellon Editor<" msgstr ">Excellon Editor<" -#: flatcamGUI/FlatCAMGUI.py:557 +#: flatcamGUI/FlatCAMGUI.py:597 msgid "Add Drill Array\tA" msgstr "Add Drill Array\tA" -#: flatcamGUI/FlatCAMGUI.py:559 +#: flatcamGUI/FlatCAMGUI.py:599 msgid "Add Drill\tD" msgstr "Add Drill\tD" -#: flatcamGUI/FlatCAMGUI.py:563 +#: flatcamGUI/FlatCAMGUI.py:603 msgid "Add Slot Array\tQ" msgstr "Add Slot Array\tQ" -#: flatcamGUI/FlatCAMGUI.py:565 +#: flatcamGUI/FlatCAMGUI.py:605 msgid "Add Slot\tW" msgstr "Add Slot\tW" -#: flatcamGUI/FlatCAMGUI.py:569 +#: flatcamGUI/FlatCAMGUI.py:609 msgid "Resize Drill(S)\tR" msgstr "Resize Drill(S)\tR" -#: flatcamGUI/FlatCAMGUI.py:572 flatcamGUI/FlatCAMGUI.py:616 +#: flatcamGUI/FlatCAMGUI.py:612 flatcamGUI/FlatCAMGUI.py:656 msgid "Copy\tC" msgstr "Copy\tC" -#: flatcamGUI/FlatCAMGUI.py:574 flatcamGUI/FlatCAMGUI.py:618 +#: flatcamGUI/FlatCAMGUI.py:614 flatcamGUI/FlatCAMGUI.py:658 msgid "Delete\tDEL" msgstr "Delete\tDEL" -#: flatcamGUI/FlatCAMGUI.py:579 +#: flatcamGUI/FlatCAMGUI.py:619 msgid "Move Drill(s)\tM" msgstr "Move Drill(s)\tM" -#: flatcamGUI/FlatCAMGUI.py:584 +#: flatcamGUI/FlatCAMGUI.py:624 msgid ">Gerber Editor<" msgstr ">Gerber Editor<" -#: flatcamGUI/FlatCAMGUI.py:588 +#: flatcamGUI/FlatCAMGUI.py:628 msgid "Add Pad\tP" msgstr "Add Pad\tP" -#: flatcamGUI/FlatCAMGUI.py:590 +#: flatcamGUI/FlatCAMGUI.py:630 msgid "Add Pad Array\tA" msgstr "Add Pad Array\tA" -#: flatcamGUI/FlatCAMGUI.py:592 +#: flatcamGUI/FlatCAMGUI.py:632 msgid "Add Track\tT" msgstr "Add Track\tT" -#: flatcamGUI/FlatCAMGUI.py:594 +#: flatcamGUI/FlatCAMGUI.py:634 msgid "Add Region\tN" msgstr "Add Region\tN" -#: flatcamGUI/FlatCAMGUI.py:598 +#: flatcamGUI/FlatCAMGUI.py:638 msgid "Poligonize\tAlt+N" msgstr "Poligonize\tAlt+N" -#: flatcamGUI/FlatCAMGUI.py:600 +#: flatcamGUI/FlatCAMGUI.py:640 msgid "Add SemiDisc\tE" msgstr "Add SemiDisc\tE" -#: flatcamGUI/FlatCAMGUI.py:602 +#: flatcamGUI/FlatCAMGUI.py:642 msgid "Add Disc\tD" msgstr "Add Disc\tD" -#: flatcamGUI/FlatCAMGUI.py:604 +#: flatcamGUI/FlatCAMGUI.py:644 msgid "Buffer\tB" msgstr "Buffer\tB" -#: flatcamGUI/FlatCAMGUI.py:606 +#: flatcamGUI/FlatCAMGUI.py:646 msgid "Scale\tS" msgstr "Scale\tS" -#: flatcamGUI/FlatCAMGUI.py:608 +#: flatcamGUI/FlatCAMGUI.py:648 msgid "Mark Area\tAlt+A" msgstr "Mark Area\tAlt+A" -#: flatcamGUI/FlatCAMGUI.py:610 +#: flatcamGUI/FlatCAMGUI.py:650 msgid "Eraser\tCtrl+E" msgstr "Eraser\tCtrl+E" -#: flatcamGUI/FlatCAMGUI.py:612 +#: flatcamGUI/FlatCAMGUI.py:652 msgid "Transform\tAlt+R" msgstr "Transform\tAlt+R" -#: flatcamGUI/FlatCAMGUI.py:639 +#: flatcamGUI/FlatCAMGUI.py:679 msgid "Enable Plot" msgstr "Enable Plot" -#: flatcamGUI/FlatCAMGUI.py:641 +#: flatcamGUI/FlatCAMGUI.py:681 msgid "Disable Plot" msgstr "Disable Plot" -#: flatcamGUI/FlatCAMGUI.py:645 +#: flatcamGUI/FlatCAMGUI.py:685 msgid "Set Color" msgstr "Set Color" -#: flatcamGUI/FlatCAMGUI.py:648 -msgid "Red" -msgstr "Red" - -#: flatcamGUI/FlatCAMGUI.py:651 -msgid "Blue" -msgstr "Blue" - -#: flatcamGUI/FlatCAMGUI.py:654 -msgid "Yellow" -msgstr "Yellow" - -#: flatcamGUI/FlatCAMGUI.py:657 -msgid "Green" -msgstr "Green" - -#: flatcamGUI/FlatCAMGUI.py:660 -msgid "Purple" -msgstr "Purple" - -#: flatcamGUI/FlatCAMGUI.py:663 -msgid "Brown" -msgstr "Brown" - -#: flatcamGUI/FlatCAMGUI.py:666 -msgid "Custom" -msgstr "Custom" - -#: flatcamGUI/FlatCAMGUI.py:671 +#: flatcamGUI/FlatCAMGUI.py:727 msgid "Generate CNC" msgstr "Generate CNC" -#: flatcamGUI/FlatCAMGUI.py:673 +#: flatcamGUI/FlatCAMGUI.py:729 msgid "View Source" msgstr "View Source" -#: flatcamGUI/FlatCAMGUI.py:686 flatcamGUI/FlatCAMGUI.py:2172 -#: flatcamTools/ToolProperties.py:30 +#: flatcamGUI/FlatCAMGUI.py:742 flatcamGUI/FlatCAMGUI.py:2280 +#: flatcamTools/ToolProperties.py:31 msgid "Properties" msgstr "Properties" -#: flatcamGUI/FlatCAMGUI.py:715 +#: flatcamGUI/FlatCAMGUI.py:771 msgid "File Toolbar" msgstr "File Toolbar" -#: flatcamGUI/FlatCAMGUI.py:719 +#: flatcamGUI/FlatCAMGUI.py:775 msgid "Edit Toolbar" msgstr "Edit Toolbar" -#: flatcamGUI/FlatCAMGUI.py:723 +#: flatcamGUI/FlatCAMGUI.py:779 msgid "View Toolbar" msgstr "View Toolbar" -#: flatcamGUI/FlatCAMGUI.py:727 +#: flatcamGUI/FlatCAMGUI.py:783 msgid "Shell Toolbar" msgstr "Shell Toolbar" -#: flatcamGUI/FlatCAMGUI.py:731 +#: flatcamGUI/FlatCAMGUI.py:787 msgid "Tools Toolbar" msgstr "Tools Toolbar" -#: flatcamGUI/FlatCAMGUI.py:735 +#: flatcamGUI/FlatCAMGUI.py:791 msgid "Excellon Editor Toolbar" msgstr "Excellon Editor Toolbar" -#: flatcamGUI/FlatCAMGUI.py:741 +#: flatcamGUI/FlatCAMGUI.py:797 msgid "Geometry Editor Toolbar" msgstr "Geometry Editor Toolbar" -#: flatcamGUI/FlatCAMGUI.py:745 +#: flatcamGUI/FlatCAMGUI.py:801 msgid "Gerber Editor Toolbar" msgstr "Gerber Editor Toolbar" -#: flatcamGUI/FlatCAMGUI.py:749 +#: flatcamGUI/FlatCAMGUI.py:805 msgid "Grid Toolbar" msgstr "Grid Toolbar" -#: flatcamGUI/FlatCAMGUI.py:772 flatcamGUI/FlatCAMGUI.py:2357 +#: flatcamGUI/FlatCAMGUI.py:826 flatcamGUI/FlatCAMGUI.py:2509 msgid "Open project" msgstr "Open project" -#: flatcamGUI/FlatCAMGUI.py:774 flatcamGUI/FlatCAMGUI.py:2359 +#: flatcamGUI/FlatCAMGUI.py:828 flatcamGUI/FlatCAMGUI.py:2511 msgid "Save project" msgstr "Save project" -#: flatcamGUI/FlatCAMGUI.py:780 flatcamGUI/FlatCAMGUI.py:2363 +#: flatcamGUI/FlatCAMGUI.py:834 flatcamGUI/FlatCAMGUI.py:2517 msgid "New Blank Geometry" msgstr "New Blank Geometry" -#: flatcamGUI/FlatCAMGUI.py:782 flatcamGUI/FlatCAMGUI.py:2365 +#: flatcamGUI/FlatCAMGUI.py:836 flatcamGUI/FlatCAMGUI.py:2519 msgid "New Blank Gerber" msgstr "New Blank Gerber" -#: flatcamGUI/FlatCAMGUI.py:784 flatcamGUI/FlatCAMGUI.py:2367 +#: flatcamGUI/FlatCAMGUI.py:838 flatcamGUI/FlatCAMGUI.py:2521 msgid "New Blank Excellon" msgstr "New Blank Excellon" -#: flatcamGUI/FlatCAMGUI.py:789 flatcamGUI/FlatCAMGUI.py:2373 +#: flatcamGUI/FlatCAMGUI.py:843 flatcamGUI/FlatCAMGUI.py:2527 msgid "Save Object and close the Editor" msgstr "Save Object and close the Editor" -#: flatcamGUI/FlatCAMGUI.py:796 flatcamGUI/FlatCAMGUI.py:2380 +#: flatcamGUI/FlatCAMGUI.py:850 flatcamGUI/FlatCAMGUI.py:2534 msgid "&Delete" msgstr "&Delete" -#: flatcamGUI/FlatCAMGUI.py:799 flatcamGUI/FlatCAMGUI.py:1613 -#: flatcamGUI/FlatCAMGUI.py:1812 flatcamGUI/FlatCAMGUI.py:2383 -#: flatcamTools/ToolDistance.py:30 flatcamTools/ToolDistance.py:160 +#: flatcamGUI/FlatCAMGUI.py:853 flatcamGUI/FlatCAMGUI.py:1714 +#: flatcamGUI/FlatCAMGUI.py:1920 flatcamGUI/FlatCAMGUI.py:2537 +#: flatcamTools/ToolDistance.py:35 flatcamTools/ToolDistance.py:195 msgid "Distance Tool" msgstr "Distance Tool" -#: flatcamGUI/FlatCAMGUI.py:801 flatcamGUI/FlatCAMGUI.py:2385 +#: flatcamGUI/FlatCAMGUI.py:855 flatcamGUI/FlatCAMGUI.py:2539 msgid "Distance Min Tool" msgstr "Distance Min Tool" -#: flatcamGUI/FlatCAMGUI.py:803 flatcamGUI/FlatCAMGUI.py:1606 -#: flatcamGUI/FlatCAMGUI.py:2387 +#: flatcamGUI/FlatCAMGUI.py:857 flatcamGUI/FlatCAMGUI.py:1707 +#: flatcamGUI/FlatCAMGUI.py:2541 msgid "Set Origin" msgstr "Set Origin" -#: flatcamGUI/FlatCAMGUI.py:805 flatcamGUI/FlatCAMGUI.py:2389 +#: flatcamGUI/FlatCAMGUI.py:859 +#| msgid "Set Origin" +msgid "Move to Origin" +msgstr "Move to Origin" + +#: flatcamGUI/FlatCAMGUI.py:862 flatcamGUI/FlatCAMGUI.py:2543 msgid "Jump to Location" msgstr "Jump to Location" -#: flatcamGUI/FlatCAMGUI.py:811 flatcamGUI/FlatCAMGUI.py:2393 +#: flatcamGUI/FlatCAMGUI.py:864 flatcamGUI/FlatCAMGUI.py:1719 +#: flatcamGUI/FlatCAMGUI.py:2545 +#| msgid "Document Object" +msgid "Locate in Object" +msgstr "Locate in Object" + +#: flatcamGUI/FlatCAMGUI.py:870 flatcamGUI/FlatCAMGUI.py:2551 msgid "&Replot" msgstr "&Replot" -#: flatcamGUI/FlatCAMGUI.py:813 flatcamGUI/FlatCAMGUI.py:2395 +#: flatcamGUI/FlatCAMGUI.py:872 flatcamGUI/FlatCAMGUI.py:2553 msgid "&Clear plot" msgstr "&Clear plot" -#: flatcamGUI/FlatCAMGUI.py:815 flatcamGUI/FlatCAMGUI.py:1609 -#: flatcamGUI/FlatCAMGUI.py:2397 +#: flatcamGUI/FlatCAMGUI.py:874 flatcamGUI/FlatCAMGUI.py:1710 +#: flatcamGUI/FlatCAMGUI.py:2555 msgid "Zoom In" msgstr "Zoom In" -#: flatcamGUI/FlatCAMGUI.py:817 flatcamGUI/FlatCAMGUI.py:1609 -#: flatcamGUI/FlatCAMGUI.py:2399 +#: flatcamGUI/FlatCAMGUI.py:876 flatcamGUI/FlatCAMGUI.py:1710 +#: flatcamGUI/FlatCAMGUI.py:2557 msgid "Zoom Out" msgstr "Zoom Out" -#: flatcamGUI/FlatCAMGUI.py:819 flatcamGUI/FlatCAMGUI.py:1608 -#: flatcamGUI/FlatCAMGUI.py:2062 flatcamGUI/FlatCAMGUI.py:2401 +#: flatcamGUI/FlatCAMGUI.py:878 flatcamGUI/FlatCAMGUI.py:1709 +#: flatcamGUI/FlatCAMGUI.py:2170 flatcamGUI/FlatCAMGUI.py:2559 msgid "Zoom Fit" msgstr "Zoom Fit" -#: flatcamGUI/FlatCAMGUI.py:827 flatcamGUI/FlatCAMGUI.py:2407 +#: flatcamGUI/FlatCAMGUI.py:886 flatcamGUI/FlatCAMGUI.py:2565 msgid "&Command Line" msgstr "&Command Line" -#: flatcamGUI/FlatCAMGUI.py:839 flatcamGUI/FlatCAMGUI.py:2417 +#: flatcamGUI/FlatCAMGUI.py:898 flatcamGUI/FlatCAMGUI.py:2577 msgid "2Sided Tool" msgstr "2Sided Tool" -#: flatcamGUI/FlatCAMGUI.py:841 flatcamGUI/ObjectUI.py:588 -#: flatcamTools/ToolCutOut.py:436 +#: flatcamGUI/FlatCAMGUI.py:900 flatcamGUI/FlatCAMGUI.py:1725 +#: flatcamGUI/FlatCAMGUI.py:2579 +#| msgid "Excellon Object Color" +msgid "Align Objects Tool" +msgstr "Align Objects Tool" + +#: flatcamGUI/FlatCAMGUI.py:902 flatcamGUI/FlatCAMGUI.py:1726 +#: flatcamGUI/FlatCAMGUI.py:2581 flatcamTools/ToolExtractDrills.py:393 +#| msgid "Create Drills GCode" +msgid "Extract Drills Tool" +msgstr "Extract Drills Tool" + +#: flatcamGUI/FlatCAMGUI.py:905 flatcamGUI/ObjectUI.py:595 +#: flatcamTools/ToolCutOut.py:447 msgid "Cutout Tool" msgstr "Cutout Tool" -#: flatcamGUI/FlatCAMGUI.py:843 flatcamGUI/FlatCAMGUI.py:2421 -#: flatcamGUI/ObjectUI.py:566 flatcamGUI/ObjectUI.py:1749 -#: flatcamTools/ToolNonCopperClear.py:632 +#: flatcamGUI/FlatCAMGUI.py:907 flatcamGUI/FlatCAMGUI.py:2586 +#: flatcamGUI/ObjectUI.py:573 flatcamGUI/ObjectUI.py:2075 +#: flatcamTools/ToolNCC.py:972 msgid "NCC Tool" msgstr "NCC Tool" -#: flatcamGUI/FlatCAMGUI.py:849 flatcamGUI/FlatCAMGUI.py:2427 +#: flatcamGUI/FlatCAMGUI.py:913 flatcamGUI/FlatCAMGUI.py:2592 msgid "Panel Tool" msgstr "Panel Tool" -#: flatcamGUI/FlatCAMGUI.py:851 flatcamGUI/FlatCAMGUI.py:2429 -#: flatcamTools/ToolFilm.py:578 +#: flatcamGUI/FlatCAMGUI.py:915 flatcamGUI/FlatCAMGUI.py:2594 +#: flatcamTools/ToolFilm.py:586 msgid "Film Tool" msgstr "Film Tool" -#: flatcamGUI/FlatCAMGUI.py:853 flatcamGUI/FlatCAMGUI.py:2432 -#: flatcamTools/ToolSolderPaste.py:547 +#: flatcamGUI/FlatCAMGUI.py:917 flatcamGUI/FlatCAMGUI.py:2596 +#: flatcamTools/ToolSolderPaste.py:553 msgid "SolderPaste Tool" msgstr "SolderPaste Tool" -#: flatcamGUI/FlatCAMGUI.py:855 flatcamGUI/FlatCAMGUI.py:2434 +#: flatcamGUI/FlatCAMGUI.py:919 flatcamGUI/FlatCAMGUI.py:2598 #: flatcamTools/ToolSub.py:35 msgid "Subtract Tool" msgstr "Subtract Tool" -#: flatcamGUI/FlatCAMGUI.py:857 flatcamTools/ToolRulesCheck.py:607 +#: flatcamGUI/FlatCAMGUI.py:921 flatcamGUI/FlatCAMGUI.py:2600 +#: flatcamTools/ToolRulesCheck.py:616 msgid "Rules Tool" msgstr "Rules Tool" -#: flatcamGUI/FlatCAMGUI.py:859 flatcamGUI/FlatCAMGUI.py:1624 -#: flatcamTools/ToolOptimal.py:34 flatcamTools/ToolOptimal.py:310 +#: flatcamGUI/FlatCAMGUI.py:923 flatcamGUI/FlatCAMGUI.py:1728 +#: flatcamGUI/FlatCAMGUI.py:2602 flatcamTools/ToolOptimal.py:34 +#: flatcamTools/ToolOptimal.py:308 msgid "Optimal Tool" msgstr "Optimal Tool" -#: flatcamGUI/FlatCAMGUI.py:864 flatcamGUI/FlatCAMGUI.py:1622 -#: flatcamGUI/FlatCAMGUI.py:2439 +#: flatcamGUI/FlatCAMGUI.py:928 flatcamGUI/FlatCAMGUI.py:1725 +#: flatcamGUI/FlatCAMGUI.py:2607 msgid "Calculators Tool" msgstr "Calculators Tool" -#: flatcamGUI/FlatCAMGUI.py:868 flatcamGUI/FlatCAMGUI.py:1625 -#: flatcamGUI/FlatCAMGUI.py:2443 flatcamTools/ToolQRCode.py:43 +#: flatcamGUI/FlatCAMGUI.py:932 flatcamGUI/FlatCAMGUI.py:1729 +#: flatcamGUI/FlatCAMGUI.py:2611 flatcamTools/ToolQRCode.py:43 #: flatcamTools/ToolQRCode.py:382 msgid "QRCode Tool" msgstr "QRCode Tool" -#: flatcamGUI/FlatCAMGUI.py:870 flatcamGUI/FlatCAMGUI.py:2445 -#: flatcamTools/ToolCopperThieving.py:40 flatcamTools/ToolCopperThieving.py:566 +#: flatcamGUI/FlatCAMGUI.py:934 flatcamGUI/FlatCAMGUI.py:2613 +#: flatcamTools/ToolCopperThieving.py:40 flatcamTools/ToolCopperThieving.py:569 msgid "Copper Thieving Tool" msgstr "Copper Thieving Tool" -#: flatcamGUI/FlatCAMGUI.py:873 flatcamGUI/FlatCAMGUI.py:1622 -#: flatcamGUI/FlatCAMGUI.py:2448 flatcamTools/ToolFiducials.py:33 -#: flatcamTools/ToolFiducials.py:393 +#: flatcamGUI/FlatCAMGUI.py:937 flatcamGUI/FlatCAMGUI.py:1726 +#: flatcamGUI/FlatCAMGUI.py:2616 flatcamTools/ToolFiducials.py:33 +#: flatcamTools/ToolFiducials.py:395 msgid "Fiducials Tool" msgstr "Fiducials Tool" -#: flatcamGUI/FlatCAMGUI.py:875 flatcamGUI/FlatCAMGUI.py:2450 -#: flatcamTools/ToolCalibration.py:37 flatcamTools/ToolCalibration.py:762 +#: flatcamGUI/FlatCAMGUI.py:939 flatcamGUI/FlatCAMGUI.py:2618 +#: flatcamTools/ToolCalibration.py:37 flatcamTools/ToolCalibration.py:759 msgid "Calibration Tool" msgstr "Calibration Tool" -#: flatcamGUI/FlatCAMGUI.py:881 flatcamGUI/FlatCAMGUI.py:907 -#: flatcamGUI/FlatCAMGUI.py:959 flatcamGUI/FlatCAMGUI.py:2454 -#: flatcamGUI/FlatCAMGUI.py:2528 +#: flatcamGUI/FlatCAMGUI.py:941 flatcamGUI/FlatCAMGUI.py:1726 +#| msgid "Paint Area Tool" +msgid "Punch Gerber Tool" +msgstr "Punch Gerber Tool" + +#: flatcamGUI/FlatCAMGUI.py:943 flatcamTools/ToolInvertGerber.py:31 +#| msgid "Convert Any to Gerber" +msgid "Invert Gerber Tool" +msgstr "Invert Gerber Tool" + +#: flatcamGUI/FlatCAMGUI.py:949 flatcamGUI/FlatCAMGUI.py:975 +#: flatcamGUI/FlatCAMGUI.py:1027 flatcamGUI/FlatCAMGUI.py:2624 +#: flatcamGUI/FlatCAMGUI.py:2702 msgid "Select" msgstr "Select" -#: flatcamGUI/FlatCAMGUI.py:883 flatcamGUI/FlatCAMGUI.py:2456 +#: flatcamGUI/FlatCAMGUI.py:951 flatcamGUI/FlatCAMGUI.py:2626 msgid "Add Drill Hole" msgstr "Add Drill Hole" -#: flatcamGUI/FlatCAMGUI.py:885 flatcamGUI/FlatCAMGUI.py:2458 +#: flatcamGUI/FlatCAMGUI.py:953 flatcamGUI/FlatCAMGUI.py:2628 msgid "Add Drill Hole Array" msgstr "Add Drill Hole Array" -#: flatcamGUI/FlatCAMGUI.py:887 flatcamGUI/FlatCAMGUI.py:1897 -#: flatcamGUI/FlatCAMGUI.py:2150 flatcamGUI/FlatCAMGUI.py:2462 +#: flatcamGUI/FlatCAMGUI.py:955 flatcamGUI/FlatCAMGUI.py:2005 +#: flatcamGUI/FlatCAMGUI.py:2258 flatcamGUI/FlatCAMGUI.py:2632 msgid "Add Slot" msgstr "Add Slot" -#: flatcamGUI/FlatCAMGUI.py:889 flatcamGUI/FlatCAMGUI.py:1896 -#: flatcamGUI/FlatCAMGUI.py:2152 flatcamGUI/FlatCAMGUI.py:2464 +#: flatcamGUI/FlatCAMGUI.py:957 flatcamGUI/FlatCAMGUI.py:2004 +#: flatcamGUI/FlatCAMGUI.py:2260 flatcamGUI/FlatCAMGUI.py:2634 msgid "Add Slot Array" msgstr "Add Slot Array" -#: flatcamGUI/FlatCAMGUI.py:891 flatcamGUI/FlatCAMGUI.py:2155 -#: flatcamGUI/FlatCAMGUI.py:2460 +#: flatcamGUI/FlatCAMGUI.py:959 flatcamGUI/FlatCAMGUI.py:2263 +#: flatcamGUI/FlatCAMGUI.py:2630 msgid "Resize Drill" msgstr "Resize Drill" -#: flatcamGUI/FlatCAMGUI.py:895 flatcamGUI/FlatCAMGUI.py:2468 +#: flatcamGUI/FlatCAMGUI.py:963 flatcamGUI/FlatCAMGUI.py:2638 msgid "Copy Drill" msgstr "Copy Drill" -#: flatcamGUI/FlatCAMGUI.py:897 flatcamGUI/FlatCAMGUI.py:2470 +#: flatcamGUI/FlatCAMGUI.py:965 flatcamGUI/FlatCAMGUI.py:2640 msgid "Delete Drill" msgstr "Delete Drill" -#: flatcamGUI/FlatCAMGUI.py:901 flatcamGUI/FlatCAMGUI.py:2474 +#: flatcamGUI/FlatCAMGUI.py:969 flatcamGUI/FlatCAMGUI.py:2644 msgid "Move Drill" msgstr "Move Drill" -#: flatcamGUI/FlatCAMGUI.py:909 flatcamGUI/FlatCAMGUI.py:2480 +#: flatcamGUI/FlatCAMGUI.py:977 flatcamGUI/FlatCAMGUI.py:2652 msgid "Add Circle" msgstr "Add Circle" -#: flatcamGUI/FlatCAMGUI.py:911 flatcamGUI/FlatCAMGUI.py:2482 +#: flatcamGUI/FlatCAMGUI.py:979 flatcamGUI/FlatCAMGUI.py:2654 msgid "Add Arc" msgstr "Add Arc" -#: flatcamGUI/FlatCAMGUI.py:913 flatcamGUI/FlatCAMGUI.py:2484 +#: flatcamGUI/FlatCAMGUI.py:981 flatcamGUI/FlatCAMGUI.py:2656 msgid "Add Rectangle" msgstr "Add Rectangle" -#: flatcamGUI/FlatCAMGUI.py:917 flatcamGUI/FlatCAMGUI.py:2488 +#: flatcamGUI/FlatCAMGUI.py:985 flatcamGUI/FlatCAMGUI.py:2660 msgid "Add Path" msgstr "Add Path" -#: flatcamGUI/FlatCAMGUI.py:919 flatcamGUI/FlatCAMGUI.py:2490 +#: flatcamGUI/FlatCAMGUI.py:987 flatcamGUI/FlatCAMGUI.py:2662 msgid "Add Polygon" msgstr "Add Polygon" -#: flatcamGUI/FlatCAMGUI.py:922 flatcamGUI/FlatCAMGUI.py:2493 +#: flatcamGUI/FlatCAMGUI.py:990 flatcamGUI/FlatCAMGUI.py:2665 msgid "Add Text" msgstr "Add Text" -#: flatcamGUI/FlatCAMGUI.py:924 flatcamGUI/FlatCAMGUI.py:2495 +#: flatcamGUI/FlatCAMGUI.py:992 flatcamGUI/FlatCAMGUI.py:2667 msgid "Add Buffer" msgstr "Add Buffer" -#: flatcamGUI/FlatCAMGUI.py:926 flatcamGUI/FlatCAMGUI.py:2497 +#: flatcamGUI/FlatCAMGUI.py:994 flatcamGUI/FlatCAMGUI.py:2669 msgid "Paint Shape" msgstr "Paint Shape" -#: flatcamGUI/FlatCAMGUI.py:928 flatcamGUI/FlatCAMGUI.py:985 -#: flatcamGUI/FlatCAMGUI.py:2091 flatcamGUI/FlatCAMGUI.py:2136 -#: flatcamGUI/FlatCAMGUI.py:2499 flatcamGUI/FlatCAMGUI.py:2553 +#: flatcamGUI/FlatCAMGUI.py:996 flatcamGUI/FlatCAMGUI.py:1053 +#: flatcamGUI/FlatCAMGUI.py:2199 flatcamGUI/FlatCAMGUI.py:2244 +#: flatcamGUI/FlatCAMGUI.py:2671 flatcamGUI/FlatCAMGUI.py:2727 msgid "Eraser" msgstr "Eraser" -#: flatcamGUI/FlatCAMGUI.py:932 flatcamGUI/FlatCAMGUI.py:2503 +#: flatcamGUI/FlatCAMGUI.py:1000 flatcamGUI/FlatCAMGUI.py:2675 msgid "Polygon Union" msgstr "Polygon Union" -#: flatcamGUI/FlatCAMGUI.py:934 flatcamGUI/FlatCAMGUI.py:2505 +#: flatcamGUI/FlatCAMGUI.py:1002 flatcamGUI/FlatCAMGUI.py:2677 msgid "Polygon Explode" msgstr "Polygon Explode" -#: flatcamGUI/FlatCAMGUI.py:937 flatcamGUI/FlatCAMGUI.py:2508 +#: flatcamGUI/FlatCAMGUI.py:1005 flatcamGUI/FlatCAMGUI.py:2680 msgid "Polygon Intersection" msgstr "Polygon Intersection" -#: flatcamGUI/FlatCAMGUI.py:939 flatcamGUI/FlatCAMGUI.py:2510 +#: flatcamGUI/FlatCAMGUI.py:1007 flatcamGUI/FlatCAMGUI.py:2682 msgid "Polygon Subtraction" msgstr "Polygon Subtraction" -#: flatcamGUI/FlatCAMGUI.py:943 flatcamGUI/FlatCAMGUI.py:2514 +#: flatcamGUI/FlatCAMGUI.py:1011 flatcamGUI/FlatCAMGUI.py:2686 msgid "Cut Path" msgstr "Cut Path" -#: flatcamGUI/FlatCAMGUI.py:945 +#: flatcamGUI/FlatCAMGUI.py:1013 msgid "Copy Shape(s)" msgstr "Copy Shape(s)" -#: flatcamGUI/FlatCAMGUI.py:948 +#: flatcamGUI/FlatCAMGUI.py:1016 msgid "Delete Shape '-'" msgstr "Delete Shape '-'" -#: flatcamGUI/FlatCAMGUI.py:950 flatcamGUI/FlatCAMGUI.py:993 -#: flatcamGUI/FlatCAMGUI.py:2103 flatcamGUI/FlatCAMGUI.py:2140 -#: flatcamGUI/FlatCAMGUI.py:2520 flatcamGUI/FlatCAMGUI.py:2561 +#: flatcamGUI/FlatCAMGUI.py:1018 flatcamGUI/FlatCAMGUI.py:1061 +#: flatcamGUI/FlatCAMGUI.py:2211 flatcamGUI/FlatCAMGUI.py:2248 +#: flatcamGUI/FlatCAMGUI.py:2692 flatcamGUI/FlatCAMGUI.py:2735 +#: flatcamGUI/ObjectUI.py:108 msgid "Transformations" msgstr "Transformations" -#: flatcamGUI/FlatCAMGUI.py:953 +#: flatcamGUI/FlatCAMGUI.py:1021 msgid "Move Objects " msgstr "Move Objects " -#: flatcamGUI/FlatCAMGUI.py:961 flatcamGUI/FlatCAMGUI.py:2016 -#: flatcamGUI/FlatCAMGUI.py:2530 +#: flatcamGUI/FlatCAMGUI.py:1029 flatcamGUI/FlatCAMGUI.py:2124 +#: flatcamGUI/FlatCAMGUI.py:2704 msgid "Add Pad" msgstr "Add Pad" -#: flatcamGUI/FlatCAMGUI.py:965 flatcamGUI/FlatCAMGUI.py:2017 -#: flatcamGUI/FlatCAMGUI.py:2534 +#: flatcamGUI/FlatCAMGUI.py:1033 flatcamGUI/FlatCAMGUI.py:2125 +#: flatcamGUI/FlatCAMGUI.py:2708 msgid "Add Track" msgstr "Add Track" -#: flatcamGUI/FlatCAMGUI.py:967 flatcamGUI/FlatCAMGUI.py:2016 -#: flatcamGUI/FlatCAMGUI.py:2536 +#: flatcamGUI/FlatCAMGUI.py:1035 flatcamGUI/FlatCAMGUI.py:2124 +#: flatcamGUI/FlatCAMGUI.py:2710 msgid "Add Region" msgstr "Add Region" -#: flatcamGUI/FlatCAMGUI.py:969 flatcamGUI/FlatCAMGUI.py:2122 -#: flatcamGUI/FlatCAMGUI.py:2538 +#: flatcamGUI/FlatCAMGUI.py:1037 flatcamGUI/FlatCAMGUI.py:2230 +#: flatcamGUI/FlatCAMGUI.py:2712 msgid "Poligonize" msgstr "Poligonize" -#: flatcamGUI/FlatCAMGUI.py:972 flatcamGUI/FlatCAMGUI.py:2124 -#: flatcamGUI/FlatCAMGUI.py:2541 +#: flatcamGUI/FlatCAMGUI.py:1040 flatcamGUI/FlatCAMGUI.py:2232 +#: flatcamGUI/FlatCAMGUI.py:2715 msgid "SemiDisc" msgstr "SemiDisc" -#: flatcamGUI/FlatCAMGUI.py:974 flatcamGUI/FlatCAMGUI.py:2126 -#: flatcamGUI/FlatCAMGUI.py:2543 +#: flatcamGUI/FlatCAMGUI.py:1042 flatcamGUI/FlatCAMGUI.py:2234 +#: flatcamGUI/FlatCAMGUI.py:2717 msgid "Disc" msgstr "Disc" -#: flatcamGUI/FlatCAMGUI.py:982 flatcamGUI/FlatCAMGUI.py:2134 -#: flatcamGUI/FlatCAMGUI.py:2551 +#: flatcamGUI/FlatCAMGUI.py:1050 flatcamGUI/FlatCAMGUI.py:2242 +#: flatcamGUI/FlatCAMGUI.py:2725 msgid "Mark Area" msgstr "Mark Area" -#: flatcamGUI/FlatCAMGUI.py:996 flatcamGUI/FlatCAMGUI.py:2016 -#: flatcamGUI/FlatCAMGUI.py:2107 flatcamGUI/FlatCAMGUI.py:2170 -#: flatcamGUI/FlatCAMGUI.py:2564 flatcamTools/ToolMove.py:28 +#: flatcamGUI/FlatCAMGUI.py:1064 flatcamGUI/FlatCAMGUI.py:2124 +#: flatcamGUI/FlatCAMGUI.py:2215 flatcamGUI/FlatCAMGUI.py:2278 +#: flatcamGUI/FlatCAMGUI.py:2738 flatcamTools/ToolMove.py:28 msgid "Move" msgstr "Move" -#: flatcamGUI/FlatCAMGUI.py:1004 flatcamGUI/FlatCAMGUI.py:2571 +#: flatcamGUI/FlatCAMGUI.py:1072 flatcamGUI/FlatCAMGUI.py:2747 msgid "Snap to grid" msgstr "Snap to grid" -#: flatcamGUI/FlatCAMGUI.py:1007 flatcamGUI/FlatCAMGUI.py:2574 +#: flatcamGUI/FlatCAMGUI.py:1075 flatcamGUI/FlatCAMGUI.py:2750 msgid "Grid X snapping distance" msgstr "Grid X snapping distance" -#: flatcamGUI/FlatCAMGUI.py:1012 flatcamGUI/FlatCAMGUI.py:2579 +#: flatcamGUI/FlatCAMGUI.py:1080 flatcamGUI/FlatCAMGUI.py:2755 msgid "Grid Y snapping distance" msgstr "Grid Y snapping distance" -#: flatcamGUI/FlatCAMGUI.py:1018 flatcamGUI/FlatCAMGUI.py:2585 +#: flatcamGUI/FlatCAMGUI.py:1086 flatcamGUI/FlatCAMGUI.py:2761 msgid "" "When active, value on Grid_X\n" "is copied to the Grid_Y value." @@ -6190,63 +6608,64 @@ msgstr "" "When active, value on Grid_X\n" "is copied to the Grid_Y value." -#: flatcamGUI/FlatCAMGUI.py:1025 flatcamGUI/FlatCAMGUI.py:2592 +#: flatcamGUI/FlatCAMGUI.py:1093 flatcamGUI/FlatCAMGUI.py:2768 msgid "Snap to corner" msgstr "Snap to corner" -#: flatcamGUI/FlatCAMGUI.py:1029 flatcamGUI/FlatCAMGUI.py:2596 -#: flatcamGUI/PreferencesUI.py:984 +#: flatcamGUI/FlatCAMGUI.py:1097 flatcamGUI/FlatCAMGUI.py:2772 +#: flatcamGUI/PreferencesUI.py:1159 msgid "Max. magnet distance" msgstr "Max. magnet distance" -#: flatcamGUI/FlatCAMGUI.py:1063 +#: flatcamGUI/FlatCAMGUI.py:1134 msgid "Selected" msgstr "Selected" -#: flatcamGUI/FlatCAMGUI.py:1090 flatcamGUI/FlatCAMGUI.py:1098 +#: flatcamGUI/FlatCAMGUI.py:1162 flatcamGUI/FlatCAMGUI.py:1170 msgid "Plot Area" msgstr "Plot Area" -#: flatcamGUI/FlatCAMGUI.py:1125 +#: flatcamGUI/FlatCAMGUI.py:1197 msgid "General" msgstr "General" -#: flatcamGUI/FlatCAMGUI.py:1140 flatcamTools/ToolCopperThieving.py:74 -#: flatcamTools/ToolDblSided.py:59 flatcamTools/ToolOptimal.py:71 -#: flatcamTools/ToolQRCode.py:77 +#: flatcamGUI/FlatCAMGUI.py:1212 flatcamTools/ToolCopperThieving.py:75 +#: flatcamTools/ToolDblSided.py:65 flatcamTools/ToolExtractDrills.py:61 +#: flatcamTools/ToolInvertGerber.py:72 flatcamTools/ToolOptimal.py:72 +#: flatcamTools/ToolPunchGerber.py:64 msgid "GERBER" msgstr "GERBER" -#: flatcamGUI/FlatCAMGUI.py:1150 flatcamTools/ToolDblSided.py:87 +#: flatcamGUI/FlatCAMGUI.py:1222 flatcamTools/ToolDblSided.py:93 msgid "EXCELLON" msgstr "EXCELLON" -#: flatcamGUI/FlatCAMGUI.py:1160 flatcamTools/ToolDblSided.py:115 +#: flatcamGUI/FlatCAMGUI.py:1232 flatcamTools/ToolDblSided.py:121 msgid "GEOMETRY" msgstr "GEOMETRY" -#: flatcamGUI/FlatCAMGUI.py:1170 +#: flatcamGUI/FlatCAMGUI.py:1242 msgid "CNC-JOB" msgstr "CNC-JOB" -#: flatcamGUI/FlatCAMGUI.py:1179 flatcamGUI/ObjectUI.py:555 -#: flatcamGUI/ObjectUI.py:1724 +#: flatcamGUI/FlatCAMGUI.py:1251 flatcamGUI/ObjectUI.py:562 +#: flatcamGUI/ObjectUI.py:2050 msgid "TOOLS" msgstr "TOOLS" -#: flatcamGUI/FlatCAMGUI.py:1188 +#: flatcamGUI/FlatCAMGUI.py:1260 msgid "TOOLS 2" msgstr "TOOLS 2" -#: flatcamGUI/FlatCAMGUI.py:1198 +#: flatcamGUI/FlatCAMGUI.py:1270 msgid "UTILITIES" msgstr "UTILITIES" -#: flatcamGUI/FlatCAMGUI.py:1215 flatcamGUI/PreferencesUI.py:2833 +#: flatcamGUI/FlatCAMGUI.py:1287 flatcamGUI/PreferencesUI.py:3015 msgid "Restore Defaults" msgstr "Restore Defaults" -#: flatcamGUI/FlatCAMGUI.py:1218 +#: flatcamGUI/FlatCAMGUI.py:1290 msgid "" "Restore the entire set of default values\n" "to the initial values loaded after first launch." @@ -6254,15 +6673,19 @@ msgstr "" "Restore the entire set of default values\n" "to the initial values loaded after first launch." -#: flatcamGUI/FlatCAMGUI.py:1223 +#: flatcamGUI/FlatCAMGUI.py:1295 msgid "Open Pref Folder" msgstr "Open Pref Folder" -#: flatcamGUI/FlatCAMGUI.py:1226 +#: flatcamGUI/FlatCAMGUI.py:1298 msgid "Open the folder where FlatCAM save the preferences files." msgstr "Open the folder where FlatCAM save the preferences files." -#: flatcamGUI/FlatCAMGUI.py:1234 +#: flatcamGUI/FlatCAMGUI.py:1302 flatcamGUI/FlatCAMGUI.py:2477 +msgid "Clear GUI Settings" +msgstr "Clear GUI Settings" + +#: flatcamGUI/FlatCAMGUI.py:1306 msgid "" "Clear the GUI settings for FlatCAM,\n" "such as: layout, gui state, style, hdpi support etc." @@ -6270,15 +6693,15 @@ msgstr "" "Clear the GUI settings for FlatCAM,\n" "such as: layout, gui state, style, hdpi support etc." -#: flatcamGUI/FlatCAMGUI.py:1245 +#: flatcamGUI/FlatCAMGUI.py:1317 msgid "Apply" msgstr "Apply" -#: flatcamGUI/FlatCAMGUI.py:1248 +#: flatcamGUI/FlatCAMGUI.py:1320 msgid "Apply the current preferences without saving to a file." msgstr "Apply the current preferences without saving to a file." -#: flatcamGUI/FlatCAMGUI.py:1255 +#: flatcamGUI/FlatCAMGUI.py:1327 msgid "" "Save the current settings in the 'current_defaults' file\n" "which is the file storing the working default preferences." @@ -6286,527 +6709,541 @@ msgstr "" "Save the current settings in the 'current_defaults' file\n" "which is the file storing the working default preferences." -#: flatcamGUI/FlatCAMGUI.py:1263 +#: flatcamGUI/FlatCAMGUI.py:1335 msgid "Will not save the changes and will close the preferences window." msgstr "Will not save the changes and will close the preferences window." -#: flatcamGUI/FlatCAMGUI.py:1603 +#: flatcamGUI/FlatCAMGUI.py:1704 msgid "SHOW SHORTCUT LIST" msgstr "SHOW SHORTCUT LIST" -#: flatcamGUI/FlatCAMGUI.py:1603 +#: flatcamGUI/FlatCAMGUI.py:1704 msgid "Switch to Project Tab" msgstr "Switch to Project Tab" -#: flatcamGUI/FlatCAMGUI.py:1603 +#: flatcamGUI/FlatCAMGUI.py:1704 msgid "Switch to Selected Tab" msgstr "Switch to Selected Tab" -#: flatcamGUI/FlatCAMGUI.py:1604 +#: flatcamGUI/FlatCAMGUI.py:1705 msgid "Switch to Tool Tab" msgstr "Switch to Tool Tab" -#: flatcamGUI/FlatCAMGUI.py:1605 +#: flatcamGUI/FlatCAMGUI.py:1706 msgid "New Gerber" msgstr "New Gerber" -#: flatcamGUI/FlatCAMGUI.py:1605 +#: flatcamGUI/FlatCAMGUI.py:1706 msgid "Edit Object (if selected)" msgstr "Edit Object (if selected)" -#: flatcamGUI/FlatCAMGUI.py:1605 +#: flatcamGUI/FlatCAMGUI.py:1706 msgid "Jump to Coordinates" msgstr "Jump to Coordinates" -#: flatcamGUI/FlatCAMGUI.py:1606 +#: flatcamGUI/FlatCAMGUI.py:1707 msgid "New Excellon" msgstr "New Excellon" -#: flatcamGUI/FlatCAMGUI.py:1606 +#: flatcamGUI/FlatCAMGUI.py:1707 msgid "Move Obj" msgstr "Move Obj" -#: flatcamGUI/FlatCAMGUI.py:1606 +#: flatcamGUI/FlatCAMGUI.py:1707 msgid "New Geometry" msgstr "New Geometry" -#: flatcamGUI/FlatCAMGUI.py:1606 +#: flatcamGUI/FlatCAMGUI.py:1707 msgid "Change Units" msgstr "Change Units" -#: flatcamGUI/FlatCAMGUI.py:1607 +#: flatcamGUI/FlatCAMGUI.py:1708 msgid "Open Properties Tool" msgstr "Open Properties Tool" -#: flatcamGUI/FlatCAMGUI.py:1607 +#: flatcamGUI/FlatCAMGUI.py:1708 msgid "Rotate by 90 degree CW" msgstr "Rotate by 90 degree CW" -#: flatcamGUI/FlatCAMGUI.py:1607 +#: flatcamGUI/FlatCAMGUI.py:1708 msgid "Shell Toggle" msgstr "Shell Toggle" -#: flatcamGUI/FlatCAMGUI.py:1608 +#: flatcamGUI/FlatCAMGUI.py:1709 msgid "" "Add a Tool (when in Geometry Selected Tab or in Tools NCC or Tools Paint)" msgstr "" "Add a Tool (when in Geometry Selected Tab or in Tools NCC or Tools Paint)" -#: flatcamGUI/FlatCAMGUI.py:1609 +#: flatcamGUI/FlatCAMGUI.py:1710 msgid "Flip on X_axis" msgstr "Flip on X_axis" -#: flatcamGUI/FlatCAMGUI.py:1609 +#: flatcamGUI/FlatCAMGUI.py:1710 msgid "Flip on Y_axis" msgstr "Flip on Y_axis" -#: flatcamGUI/FlatCAMGUI.py:1612 +#: flatcamGUI/FlatCAMGUI.py:1713 msgid "Copy Obj" msgstr "Copy Obj" -#: flatcamGUI/FlatCAMGUI.py:1612 +#: flatcamGUI/FlatCAMGUI.py:1713 msgid "Open Tools Database" msgstr "Open Tools Database" -#: flatcamGUI/FlatCAMGUI.py:1613 +#: flatcamGUI/FlatCAMGUI.py:1714 msgid "Open Excellon File" msgstr "Open Excellon File" -#: flatcamGUI/FlatCAMGUI.py:1613 +#: flatcamGUI/FlatCAMGUI.py:1714 msgid "Open Gerber File" msgstr "Open Gerber File" -#: flatcamGUI/FlatCAMGUI.py:1613 +#: flatcamGUI/FlatCAMGUI.py:1714 msgid "New Project" msgstr "New Project" -#: flatcamGUI/FlatCAMGUI.py:1614 flatcamTools/ToolPDF.py:42 +#: flatcamGUI/FlatCAMGUI.py:1715 flatcamTools/ToolPDF.py:42 msgid "PDF Import Tool" msgstr "PDF Import Tool" -#: flatcamGUI/FlatCAMGUI.py:1614 -msgid "Save Project As" -msgstr "Save Project As" +#: flatcamGUI/FlatCAMGUI.py:1715 +#| msgid "Save project" +msgid "Save Project" +msgstr "Save Project" -#: flatcamGUI/FlatCAMGUI.py:1614 +#: flatcamGUI/FlatCAMGUI.py:1715 msgid "Toggle Plot Area" msgstr "Toggle Plot Area" -#: flatcamGUI/FlatCAMGUI.py:1617 +#: flatcamGUI/FlatCAMGUI.py:1718 msgid "Copy Obj_Name" msgstr "Copy Obj_Name" -#: flatcamGUI/FlatCAMGUI.py:1618 +#: flatcamGUI/FlatCAMGUI.py:1719 msgid "Toggle Code Editor" msgstr "Toggle Code Editor" -#: flatcamGUI/FlatCAMGUI.py:1618 +#: flatcamGUI/FlatCAMGUI.py:1719 msgid "Toggle the axis" msgstr "Toggle the axis" -#: flatcamGUI/FlatCAMGUI.py:1618 flatcamGUI/FlatCAMGUI.py:1810 -#: flatcamGUI/FlatCAMGUI.py:1897 flatcamGUI/FlatCAMGUI.py:2019 +#: flatcamGUI/FlatCAMGUI.py:1719 flatcamGUI/FlatCAMGUI.py:1918 +#: flatcamGUI/FlatCAMGUI.py:2005 flatcamGUI/FlatCAMGUI.py:2127 msgid "Distance Minimum Tool" msgstr "Distance Minimum Tool" -#: flatcamGUI/FlatCAMGUI.py:1618 +#: flatcamGUI/FlatCAMGUI.py:1720 msgid "Open Preferences Window" msgstr "Open Preferences Window" -#: flatcamGUI/FlatCAMGUI.py:1619 +#: flatcamGUI/FlatCAMGUI.py:1721 msgid "Rotate by 90 degree CCW" msgstr "Rotate by 90 degree CCW" -#: flatcamGUI/FlatCAMGUI.py:1619 +#: flatcamGUI/FlatCAMGUI.py:1721 msgid "Run a Script" msgstr "Run a Script" -#: flatcamGUI/FlatCAMGUI.py:1619 +#: flatcamGUI/FlatCAMGUI.py:1721 msgid "Toggle the workspace" msgstr "Toggle the workspace" -#: flatcamGUI/FlatCAMGUI.py:1619 +#: flatcamGUI/FlatCAMGUI.py:1721 msgid "Skew on X axis" msgstr "Skew on X axis" -#: flatcamGUI/FlatCAMGUI.py:1620 +#: flatcamGUI/FlatCAMGUI.py:1722 msgid "Skew on Y axis" msgstr "Skew on Y axis" -#: flatcamGUI/FlatCAMGUI.py:1622 +#: flatcamGUI/FlatCAMGUI.py:1725 msgid "2-Sided PCB Tool" msgstr "2-Sided PCB Tool" -#: flatcamGUI/FlatCAMGUI.py:1622 +#: flatcamGUI/FlatCAMGUI.py:1725 msgid "Transformations Tool" msgstr "Transformations Tool" -#: flatcamGUI/FlatCAMGUI.py:1623 +#: flatcamGUI/FlatCAMGUI.py:1727 msgid "Solder Paste Dispensing Tool" msgstr "Solder Paste Dispensing Tool" -#: flatcamGUI/FlatCAMGUI.py:1624 +#: flatcamGUI/FlatCAMGUI.py:1728 msgid "Film PCB Tool" msgstr "Film PCB Tool" -#: flatcamGUI/FlatCAMGUI.py:1624 +#: flatcamGUI/FlatCAMGUI.py:1728 msgid "Non-Copper Clearing Tool" msgstr "Non-Copper Clearing Tool" -#: flatcamGUI/FlatCAMGUI.py:1625 +#: flatcamGUI/FlatCAMGUI.py:1729 msgid "Paint Area Tool" msgstr "Paint Area Tool" -#: flatcamGUI/FlatCAMGUI.py:1625 +#: flatcamGUI/FlatCAMGUI.py:1729 msgid "Rules Check Tool" msgstr "Rules Check Tool" -#: flatcamGUI/FlatCAMGUI.py:1626 +#: flatcamGUI/FlatCAMGUI.py:1730 msgid "View File Source" msgstr "View File Source" -#: flatcamGUI/FlatCAMGUI.py:1627 +#: flatcamGUI/FlatCAMGUI.py:1731 msgid "Cutout PCB Tool" msgstr "Cutout PCB Tool" -#: flatcamGUI/FlatCAMGUI.py:1627 +#: flatcamGUI/FlatCAMGUI.py:1731 msgid "Enable all Plots" msgstr "Enable all Plots" -#: flatcamGUI/FlatCAMGUI.py:1627 +#: flatcamGUI/FlatCAMGUI.py:1731 msgid "Disable all Plots" msgstr "Disable all Plots" -#: flatcamGUI/FlatCAMGUI.py:1627 +#: flatcamGUI/FlatCAMGUI.py:1731 msgid "Disable Non-selected Plots" msgstr "Disable Non-selected Plots" -#: flatcamGUI/FlatCAMGUI.py:1628 +#: flatcamGUI/FlatCAMGUI.py:1732 msgid "Toggle Full Screen" msgstr "Toggle Full Screen" -#: flatcamGUI/FlatCAMGUI.py:1631 +#: flatcamGUI/FlatCAMGUI.py:1735 msgid "Abort current task (gracefully)" msgstr "Abort current task (gracefully)" -#: flatcamGUI/FlatCAMGUI.py:1634 +#: flatcamGUI/FlatCAMGUI.py:1738 +msgid "Save Project As" +msgstr "Save Project As" + +#: flatcamGUI/FlatCAMGUI.py:1739 +msgid "" +"Paste Special. Will convert a Windows path style to the one required in Tcl " +"Shell" +msgstr "" +"Paste Special. Will convert a Windows path style to the one required in Tcl " +"Shell" + +#: flatcamGUI/FlatCAMGUI.py:1742 msgid "Open Online Manual" msgstr "Open Online Manual" -#: flatcamGUI/FlatCAMGUI.py:1635 +#: flatcamGUI/FlatCAMGUI.py:1743 msgid "Open Online Tutorials" msgstr "Open Online Tutorials" -#: flatcamGUI/FlatCAMGUI.py:1635 +#: flatcamGUI/FlatCAMGUI.py:1743 msgid "Refresh Plots" msgstr "Refresh Plots" -#: flatcamGUI/FlatCAMGUI.py:1635 flatcamTools/ToolSolderPaste.py:503 +#: flatcamGUI/FlatCAMGUI.py:1743 flatcamTools/ToolSolderPaste.py:509 msgid "Delete Object" msgstr "Delete Object" -#: flatcamGUI/FlatCAMGUI.py:1635 +#: flatcamGUI/FlatCAMGUI.py:1743 msgid "Alternate: Delete Tool" msgstr "Alternate: Delete Tool" -#: flatcamGUI/FlatCAMGUI.py:1636 +#: flatcamGUI/FlatCAMGUI.py:1744 msgid "(left to Key_1)Toogle Notebook Area (Left Side)" msgstr "(left to Key_1)Toogle Notebook Area (Left Side)" -#: flatcamGUI/FlatCAMGUI.py:1636 +#: flatcamGUI/FlatCAMGUI.py:1744 msgid "En(Dis)able Obj Plot" msgstr "En(Dis)able Obj Plot" -#: flatcamGUI/FlatCAMGUI.py:1637 +#: flatcamGUI/FlatCAMGUI.py:1745 msgid "Deselects all objects" msgstr "Deselects all objects" -#: flatcamGUI/FlatCAMGUI.py:1651 +#: flatcamGUI/FlatCAMGUI.py:1759 msgid "Editor Shortcut list" msgstr "Editor Shortcut list" -#: flatcamGUI/FlatCAMGUI.py:1805 +#: flatcamGUI/FlatCAMGUI.py:1913 msgid "GEOMETRY EDITOR" msgstr "GEOMETRY EDITOR" -#: flatcamGUI/FlatCAMGUI.py:1805 +#: flatcamGUI/FlatCAMGUI.py:1913 msgid "Draw an Arc" msgstr "Draw an Arc" -#: flatcamGUI/FlatCAMGUI.py:1805 +#: flatcamGUI/FlatCAMGUI.py:1913 msgid "Copy Geo Item" msgstr "Copy Geo Item" -#: flatcamGUI/FlatCAMGUI.py:1806 +#: flatcamGUI/FlatCAMGUI.py:1914 msgid "Within Add Arc will toogle the ARC direction: CW or CCW" msgstr "Within Add Arc will toogle the ARC direction: CW or CCW" -#: flatcamGUI/FlatCAMGUI.py:1806 +#: flatcamGUI/FlatCAMGUI.py:1914 msgid "Polygon Intersection Tool" msgstr "Polygon Intersection Tool" -#: flatcamGUI/FlatCAMGUI.py:1807 +#: flatcamGUI/FlatCAMGUI.py:1915 msgid "Geo Paint Tool" msgstr "Geo Paint Tool" -#: flatcamGUI/FlatCAMGUI.py:1807 flatcamGUI/FlatCAMGUI.py:1896 -#: flatcamGUI/FlatCAMGUI.py:2016 +#: flatcamGUI/FlatCAMGUI.py:1915 flatcamGUI/FlatCAMGUI.py:2004 +#: flatcamGUI/FlatCAMGUI.py:2124 msgid "Jump to Location (x, y)" msgstr "Jump to Location (x, y)" -#: flatcamGUI/FlatCAMGUI.py:1807 +#: flatcamGUI/FlatCAMGUI.py:1915 msgid "Toggle Corner Snap" msgstr "Toggle Corner Snap" -#: flatcamGUI/FlatCAMGUI.py:1807 +#: flatcamGUI/FlatCAMGUI.py:1915 msgid "Move Geo Item" msgstr "Move Geo Item" -#: flatcamGUI/FlatCAMGUI.py:1808 +#: flatcamGUI/FlatCAMGUI.py:1916 msgid "Within Add Arc will cycle through the ARC modes" msgstr "Within Add Arc will cycle through the ARC modes" -#: flatcamGUI/FlatCAMGUI.py:1808 +#: flatcamGUI/FlatCAMGUI.py:1916 msgid "Draw a Polygon" msgstr "Draw a Polygon" -#: flatcamGUI/FlatCAMGUI.py:1808 +#: flatcamGUI/FlatCAMGUI.py:1916 msgid "Draw a Circle" msgstr "Draw a Circle" -#: flatcamGUI/FlatCAMGUI.py:1809 +#: flatcamGUI/FlatCAMGUI.py:1917 msgid "Draw a Path" msgstr "Draw a Path" -#: flatcamGUI/FlatCAMGUI.py:1809 +#: flatcamGUI/FlatCAMGUI.py:1917 msgid "Draw Rectangle" msgstr "Draw Rectangle" -#: flatcamGUI/FlatCAMGUI.py:1809 +#: flatcamGUI/FlatCAMGUI.py:1917 msgid "Polygon Subtraction Tool" msgstr "Polygon Subtraction Tool" -#: flatcamGUI/FlatCAMGUI.py:1809 +#: flatcamGUI/FlatCAMGUI.py:1917 msgid "Add Text Tool" msgstr "Add Text Tool" -#: flatcamGUI/FlatCAMGUI.py:1810 +#: flatcamGUI/FlatCAMGUI.py:1918 msgid "Polygon Union Tool" msgstr "Polygon Union Tool" -#: flatcamGUI/FlatCAMGUI.py:1810 +#: flatcamGUI/FlatCAMGUI.py:1918 msgid "Flip shape on X axis" msgstr "Flip shape on X axis" -#: flatcamGUI/FlatCAMGUI.py:1810 +#: flatcamGUI/FlatCAMGUI.py:1918 msgid "Flip shape on Y axis" msgstr "Flip shape on Y axis" -#: flatcamGUI/FlatCAMGUI.py:1811 +#: flatcamGUI/FlatCAMGUI.py:1919 msgid "Skew shape on X axis" msgstr "Skew shape on X axis" -#: flatcamGUI/FlatCAMGUI.py:1811 +#: flatcamGUI/FlatCAMGUI.py:1919 msgid "Skew shape on Y axis" msgstr "Skew shape on Y axis" -#: flatcamGUI/FlatCAMGUI.py:1811 +#: flatcamGUI/FlatCAMGUI.py:1919 msgid "Editor Transformation Tool" msgstr "Editor Transformation Tool" -#: flatcamGUI/FlatCAMGUI.py:1812 +#: flatcamGUI/FlatCAMGUI.py:1920 msgid "Offset shape on X axis" msgstr "Offset shape on X axis" -#: flatcamGUI/FlatCAMGUI.py:1812 +#: flatcamGUI/FlatCAMGUI.py:1920 msgid "Offset shape on Y axis" msgstr "Offset shape on Y axis" -#: flatcamGUI/FlatCAMGUI.py:1813 flatcamGUI/FlatCAMGUI.py:1899 -#: flatcamGUI/FlatCAMGUI.py:2021 +#: flatcamGUI/FlatCAMGUI.py:1921 flatcamGUI/FlatCAMGUI.py:2007 +#: flatcamGUI/FlatCAMGUI.py:2129 msgid "Save Object and Exit Editor" msgstr "Save Object and Exit Editor" -#: flatcamGUI/FlatCAMGUI.py:1813 +#: flatcamGUI/FlatCAMGUI.py:1921 msgid "Polygon Cut Tool" msgstr "Polygon Cut Tool" -#: flatcamGUI/FlatCAMGUI.py:1814 +#: flatcamGUI/FlatCAMGUI.py:1922 msgid "Rotate Geometry" msgstr "Rotate Geometry" -#: flatcamGUI/FlatCAMGUI.py:1814 +#: flatcamGUI/FlatCAMGUI.py:1922 msgid "Finish drawing for certain tools" msgstr "Finish drawing for certain tools" -#: flatcamGUI/FlatCAMGUI.py:1814 flatcamGUI/FlatCAMGUI.py:1899 -#: flatcamGUI/FlatCAMGUI.py:2019 +#: flatcamGUI/FlatCAMGUI.py:1922 flatcamGUI/FlatCAMGUI.py:2007 +#: flatcamGUI/FlatCAMGUI.py:2127 msgid "Abort and return to Select" msgstr "Abort and return to Select" -#: flatcamGUI/FlatCAMGUI.py:1815 flatcamGUI/FlatCAMGUI.py:2518 +#: flatcamGUI/FlatCAMGUI.py:1923 flatcamGUI/FlatCAMGUI.py:2690 msgid "Delete Shape" msgstr "Delete Shape" -#: flatcamGUI/FlatCAMGUI.py:1895 +#: flatcamGUI/FlatCAMGUI.py:2003 msgid "EXCELLON EDITOR" msgstr "EXCELLON EDITOR" -#: flatcamGUI/FlatCAMGUI.py:1895 +#: flatcamGUI/FlatCAMGUI.py:2003 msgid "Copy Drill(s)" msgstr "Copy Drill(s)" -#: flatcamGUI/FlatCAMGUI.py:1895 flatcamGUI/FlatCAMGUI.py:2145 +#: flatcamGUI/FlatCAMGUI.py:2003 flatcamGUI/FlatCAMGUI.py:2253 msgid "Add Drill" msgstr "Add Drill" -#: flatcamGUI/FlatCAMGUI.py:1896 +#: flatcamGUI/FlatCAMGUI.py:2004 msgid "Move Drill(s)" msgstr "Move Drill(s)" -#: flatcamGUI/FlatCAMGUI.py:1897 +#: flatcamGUI/FlatCAMGUI.py:2005 msgid "Add a new Tool" msgstr "Add a new Tool" -#: flatcamGUI/FlatCAMGUI.py:1898 +#: flatcamGUI/FlatCAMGUI.py:2006 msgid "Delete Drill(s)" msgstr "Delete Drill(s)" -#: flatcamGUI/FlatCAMGUI.py:1898 +#: flatcamGUI/FlatCAMGUI.py:2006 msgid "Alternate: Delete Tool(s)" msgstr "Alternate: Delete Tool(s)" -#: flatcamGUI/FlatCAMGUI.py:2015 +#: flatcamGUI/FlatCAMGUI.py:2123 msgid "GERBER EDITOR" msgstr "GERBER EDITOR" -#: flatcamGUI/FlatCAMGUI.py:2015 +#: flatcamGUI/FlatCAMGUI.py:2123 msgid "Add Disc" msgstr "Add Disc" -#: flatcamGUI/FlatCAMGUI.py:2015 +#: flatcamGUI/FlatCAMGUI.py:2123 msgid "Add SemiDisc" msgstr "Add SemiDisc" -#: flatcamGUI/FlatCAMGUI.py:2017 +#: flatcamGUI/FlatCAMGUI.py:2125 msgid "Within Track & Region Tools will cycle in REVERSE the bend modes" msgstr "Within Track & Region Tools will cycle in REVERSE the bend modes" -#: flatcamGUI/FlatCAMGUI.py:2018 +#: flatcamGUI/FlatCAMGUI.py:2126 msgid "Within Track & Region Tools will cycle FORWARD the bend modes" msgstr "Within Track & Region Tools will cycle FORWARD the bend modes" -#: flatcamGUI/FlatCAMGUI.py:2019 +#: flatcamGUI/FlatCAMGUI.py:2127 msgid "Alternate: Delete Apertures" msgstr "Alternate: Delete Apertures" -#: flatcamGUI/FlatCAMGUI.py:2020 +#: flatcamGUI/FlatCAMGUI.py:2128 msgid "Eraser Tool" msgstr "Eraser Tool" -#: flatcamGUI/FlatCAMGUI.py:2021 flatcamGUI/PreferencesUI.py:2634 +#: flatcamGUI/FlatCAMGUI.py:2129 flatcamGUI/PreferencesUI.py:2816 msgid "Mark Area Tool" msgstr "Mark Area Tool" -#: flatcamGUI/FlatCAMGUI.py:2021 +#: flatcamGUI/FlatCAMGUI.py:2129 msgid "Poligonize Tool" msgstr "Poligonize Tool" -#: flatcamGUI/FlatCAMGUI.py:2021 +#: flatcamGUI/FlatCAMGUI.py:2129 msgid "Transformation Tool" msgstr "Transformation Tool" -#: flatcamGUI/FlatCAMGUI.py:2038 +#: flatcamGUI/FlatCAMGUI.py:2146 msgid "Toggle Visibility" msgstr "Toggle Visibility" -#: flatcamGUI/FlatCAMGUI.py:2044 +#: flatcamGUI/FlatCAMGUI.py:2152 msgid "New" msgstr "New" -#: flatcamGUI/FlatCAMGUI.py:2046 flatcamTools/ToolCalibration.py:634 -msgid "Geometry" -msgstr "Geometry" - -#: flatcamGUI/FlatCAMGUI.py:2050 flatcamTools/ToolCalibration.py:197 -#: flatcamTools/ToolCalibration.py:634 flatcamTools/ToolFilm.py:359 +#: flatcamGUI/FlatCAMGUI.py:2158 flatcamGUI/PreferencesUI.py:8410 +#: flatcamTools/ToolAlignObjects.py:74 flatcamTools/ToolAlignObjects.py:110 +#: flatcamTools/ToolCalibration.py:197 flatcamTools/ToolCalibration.py:631 +#: flatcamTools/ToolCalibration.py:648 flatcamTools/ToolCalibration.py:807 +#: flatcamTools/ToolCalibration.py:815 flatcamTools/ToolCopperThieving.py:145 +#: flatcamTools/ToolCopperThieving.py:159 +#: flatcamTools/ToolCopperThieving.py:605 flatcamTools/ToolDblSided.py:226 +#: flatcamTools/ToolFilm.py:359 flatcamTools/ToolNCC.py:558 +#: flatcamTools/ToolNCC.py:1293 flatcamTools/ToolPaint.py:502 +#: flatcamTools/ToolPaint.py:703 flatcamTools/ToolPanelize.py:374 +#: flatcamTools/ToolPunchGerber.py:149 flatcamTools/ToolPunchGerber.py:164 msgid "Excellon" msgstr "Excellon" -#: flatcamGUI/FlatCAMGUI.py:2057 +#: flatcamGUI/FlatCAMGUI.py:2165 msgid "Grids" msgstr "Grids" -#: flatcamGUI/FlatCAMGUI.py:2064 +#: flatcamGUI/FlatCAMGUI.py:2172 msgid "Clear Plot" msgstr "Clear Plot" -#: flatcamGUI/FlatCAMGUI.py:2066 +#: flatcamGUI/FlatCAMGUI.py:2174 msgid "Replot" msgstr "Replot" -#: flatcamGUI/FlatCAMGUI.py:2070 +#: flatcamGUI/FlatCAMGUI.py:2178 msgid "Geo Editor" msgstr "Geo Editor" -#: flatcamGUI/FlatCAMGUI.py:2072 +#: flatcamGUI/FlatCAMGUI.py:2180 msgid "Path" msgstr "Path" -#: flatcamGUI/FlatCAMGUI.py:2074 +#: flatcamGUI/FlatCAMGUI.py:2182 msgid "Rectangle" msgstr "Rectangle" -#: flatcamGUI/FlatCAMGUI.py:2077 +#: flatcamGUI/FlatCAMGUI.py:2185 msgid "Circle" msgstr "Circle" -#: flatcamGUI/FlatCAMGUI.py:2079 -msgid "Polygon" -msgstr "Polygon" - -#: flatcamGUI/FlatCAMGUI.py:2081 +#: flatcamGUI/FlatCAMGUI.py:2189 msgid "Arc" msgstr "Arc" -#: flatcamGUI/FlatCAMGUI.py:2095 +#: flatcamGUI/FlatCAMGUI.py:2203 msgid "Union" msgstr "Union" -#: flatcamGUI/FlatCAMGUI.py:2097 +#: flatcamGUI/FlatCAMGUI.py:2205 msgid "Intersection" msgstr "Intersection" -#: flatcamGUI/FlatCAMGUI.py:2099 +#: flatcamGUI/FlatCAMGUI.py:2207 msgid "Subtraction" msgstr "Subtraction" -#: flatcamGUI/FlatCAMGUI.py:2101 flatcamGUI/ObjectUI.py:1811 -#: flatcamGUI/PreferencesUI.py:4421 +#: flatcamGUI/FlatCAMGUI.py:2209 flatcamGUI/ObjectUI.py:2139 +#: flatcamGUI/PreferencesUI.py:4714 msgid "Cut" msgstr "Cut" -#: flatcamGUI/FlatCAMGUI.py:2112 +#: flatcamGUI/FlatCAMGUI.py:2220 msgid "Pad" msgstr "Pad" -#: flatcamGUI/FlatCAMGUI.py:2114 +#: flatcamGUI/FlatCAMGUI.py:2222 msgid "Pad Array" msgstr "Pad Array" -#: flatcamGUI/FlatCAMGUI.py:2118 +#: flatcamGUI/FlatCAMGUI.py:2226 msgid "Track" msgstr "Track" -#: flatcamGUI/FlatCAMGUI.py:2120 +#: flatcamGUI/FlatCAMGUI.py:2228 msgid "Region" msgstr "Region" -#: flatcamGUI/FlatCAMGUI.py:2143 +#: flatcamGUI/FlatCAMGUI.py:2251 msgid "Exc Editor" msgstr "Exc Editor" -#: flatcamGUI/FlatCAMGUI.py:2188 +#: flatcamGUI/FlatCAMGUI.py:2296 msgid "" "Relative neasurement.\n" "Reference is last click position" @@ -6814,7 +7251,7 @@ msgstr "" "Relative neasurement.\n" "Reference is last click position" -#: flatcamGUI/FlatCAMGUI.py:2194 +#: flatcamGUI/FlatCAMGUI.py:2302 msgid "" "Absolute neasurement.\n" "Reference is (X=0, Y= 0) position" @@ -6822,27 +7259,35 @@ msgstr "" "Absolute neasurement.\n" "Reference is (X=0, Y= 0) position" -#: flatcamGUI/FlatCAMGUI.py:2301 +#: flatcamGUI/FlatCAMGUI.py:2406 msgid "Lock Toolbars" msgstr "Lock Toolbars" -#: flatcamGUI/FlatCAMGUI.py:2419 +#: flatcamGUI/FlatCAMGUI.py:2465 +msgid "FlatCAM Preferences Folder opened." +msgstr "FlatCAM Preferences Folder opened." + +#: flatcamGUI/FlatCAMGUI.py:2476 +msgid "Are you sure you want to delete the GUI Settings? \n" +msgstr "Are you sure you want to delete the GUI Settings? \n" + +#: flatcamGUI/FlatCAMGUI.py:2584 msgid "&Cutout Tool" msgstr "&Cutout Tool" -#: flatcamGUI/FlatCAMGUI.py:2478 +#: flatcamGUI/FlatCAMGUI.py:2650 msgid "Select 'Esc'" msgstr "Select 'Esc'" -#: flatcamGUI/FlatCAMGUI.py:2516 +#: flatcamGUI/FlatCAMGUI.py:2688 msgid "Copy Objects" msgstr "Copy Objects" -#: flatcamGUI/FlatCAMGUI.py:2524 +#: flatcamGUI/FlatCAMGUI.py:2696 msgid "Move Objects" msgstr "Move Objects" -#: flatcamGUI/FlatCAMGUI.py:3087 +#: flatcamGUI/FlatCAMGUI.py:3312 msgid "" "Please first select a geometry item to be cutted\n" "then select the geometry item that will be cutted\n" @@ -6854,12 +7299,12 @@ msgstr "" "out of the first item. In the end press ~X~ key or\n" "the toolbar button." -#: flatcamGUI/FlatCAMGUI.py:3094 flatcamGUI/FlatCAMGUI.py:3254 -#: flatcamGUI/FlatCAMGUI.py:3299 flatcamGUI/FlatCAMGUI.py:3319 +#: flatcamGUI/FlatCAMGUI.py:3319 flatcamGUI/FlatCAMGUI.py:3478 +#: flatcamGUI/FlatCAMGUI.py:3523 flatcamGUI/FlatCAMGUI.py:3543 msgid "Warning" msgstr "Warning" -#: flatcamGUI/FlatCAMGUI.py:3249 +#: flatcamGUI/FlatCAMGUI.py:3473 msgid "" "Please select geometry items \n" "on which to perform Intersection Tool." @@ -6867,7 +7312,7 @@ msgstr "" "Please select geometry items \n" "on which to perform Intersection Tool." -#: flatcamGUI/FlatCAMGUI.py:3294 +#: flatcamGUI/FlatCAMGUI.py:3518 msgid "" "Please select geometry items \n" "on which to perform Substraction Tool." @@ -6875,7 +7320,7 @@ msgstr "" "Please select geometry items \n" "on which to perform Substraction Tool." -#: flatcamGUI/FlatCAMGUI.py:3314 +#: flatcamGUI/FlatCAMGUI.py:3538 msgid "" "Please select geometry items \n" "on which to perform union." @@ -6883,61 +7328,62 @@ msgstr "" "Please select geometry items \n" "on which to perform union." -#: flatcamGUI/FlatCAMGUI.py:3394 flatcamGUI/FlatCAMGUI.py:3608 +#: flatcamGUI/FlatCAMGUI.py:3617 flatcamGUI/FlatCAMGUI.py:3828 msgid "Cancelled. Nothing selected to delete." msgstr "Cancelled. Nothing selected to delete." -#: flatcamGUI/FlatCAMGUI.py:3479 flatcamGUI/FlatCAMGUI.py:3726 +#: flatcamGUI/FlatCAMGUI.py:3701 flatcamGUI/FlatCAMGUI.py:3944 msgid "Cancelled. Nothing selected to copy." msgstr "Cancelled. Nothing selected to copy." -#: flatcamGUI/FlatCAMGUI.py:3526 flatcamGUI/FlatCAMGUI.py:3756 +#: flatcamGUI/FlatCAMGUI.py:3747 flatcamGUI/FlatCAMGUI.py:3973 msgid "Cancelled. Nothing selected to move." msgstr "Cancelled. Nothing selected to move." -#: flatcamGUI/FlatCAMGUI.py:3782 +#: flatcamGUI/FlatCAMGUI.py:3999 msgid "New Tool ..." msgstr "New Tool ..." -#: flatcamGUI/FlatCAMGUI.py:3783 flatcamTools/ToolNonCopperClear.py:583 -#: flatcamTools/ToolPaint.py:494 flatcamTools/ToolSolderPaste.py:554 +#: flatcamGUI/FlatCAMGUI.py:4000 flatcamTools/ToolNCC.py:922 +#: flatcamTools/ToolPaint.py:847 flatcamTools/ToolSolderPaste.py:560 msgid "Enter a Tool Diameter" msgstr "Enter a Tool Diameter" -#: flatcamGUI/FlatCAMGUI.py:3795 +#: flatcamGUI/FlatCAMGUI.py:4012 msgid "Adding Tool cancelled ..." msgstr "Adding Tool cancelled ..." -#: flatcamGUI/FlatCAMGUI.py:3808 +#: flatcamGUI/FlatCAMGUI.py:4025 msgid "Distance Tool exit..." msgstr "Distance Tool exit..." -#: flatcamGUI/FlatCAMGUI.py:4018 flatcamGUI/FlatCAMGUI.py:4025 +#: flatcamGUI/FlatCAMGUI.py:4234 flatcamGUI/FlatCAMGUI.py:4241 msgid "Idle." msgstr "Idle." -#: flatcamGUI/FlatCAMGUI.py:4056 +#: flatcamGUI/FlatCAMGUI.py:4272 msgid "Application started ..." msgstr "Application started ..." -#: flatcamGUI/FlatCAMGUI.py:4057 +#: flatcamGUI/FlatCAMGUI.py:4273 msgid "Hello!" msgstr "Hello!" -#: flatcamGUI/FlatCAMGUI.py:4115 +#: flatcamGUI/FlatCAMGUI.py:4331 msgid "Open Project ..." msgstr "Open Project ..." -#: flatcamGUI/FlatCAMGUI.py:4141 +#: flatcamGUI/FlatCAMGUI.py:4357 msgid "Exit" msgstr "Exit" -#: flatcamGUI/GUIElements.py:2261 flatcamGUI/PreferencesUI.py:5265 -#: flatcamGUI/PreferencesUI.py:5825 flatcamTools/ToolFilm.py:219 +#: flatcamGUI/GUIElements.py:2513 flatcamGUI/PreferencesUI.py:6313 +#: flatcamTools/ToolDblSided.py:174 flatcamTools/ToolDblSided.py:389 +#: flatcamTools/ToolFilm.py:219 msgid "Reference" msgstr "Reference" -#: flatcamGUI/GUIElements.py:2263 +#: flatcamGUI/GUIElements.py:2515 msgid "" "The reference can be:\n" "- Absolute -> the reference point is point (0,0)\n" @@ -6947,19 +7393,19 @@ msgstr "" "- Absolute -> the reference point is point (0,0)\n" "- Relative -> the reference point is the mouse position before Jump" -#: flatcamGUI/GUIElements.py:2268 +#: flatcamGUI/GUIElements.py:2520 msgid "Abs" msgstr "Abs" -#: flatcamGUI/GUIElements.py:2269 +#: flatcamGUI/GUIElements.py:2521 msgid "Relative" msgstr "Relative" -#: flatcamGUI/GUIElements.py:2279 +#: flatcamGUI/GUIElements.py:2531 msgid "Location" msgstr "Location" -#: flatcamGUI/GUIElements.py:2281 +#: flatcamGUI/GUIElements.py:2533 msgid "" "The Location value is a tuple (x,y).\n" "If the reference is Absolute then the Jump will be at the position (x,y).\n" @@ -6971,6 +7417,11 @@ msgstr "" "If the reference is Relative then the Jump will be at the (x,y) distance\n" "from the current mouse location point." +#: flatcamGUI/GUIElements.py:2573 +#| msgid "Saved to" +msgid "Save Log" +msgstr "Save Log" + #: flatcamGUI/ObjectUI.py:38 msgid "FlatCAM Object" msgstr "FlatCAM Object" @@ -6993,15 +7444,11 @@ msgstr "" "Edit -> Preferences -> General and check:\n" "'APP. LEVEL' radio button." -#: flatcamGUI/ObjectUI.py:105 -msgid "Change the size of the object." -msgstr "Change the size of the object." +#: flatcamGUI/ObjectUI.py:110 +msgid "Geometrical transformations of the current object." +msgstr "Geometrical transformations of the current object." -#: flatcamGUI/ObjectUI.py:111 -msgid "Factor" -msgstr "Factor" - -#: flatcamGUI/ObjectUI.py:113 +#: flatcamGUI/ObjectUI.py:119 msgid "" "Factor by which to multiply\n" "geometric features of this object.\n" @@ -7011,19 +7458,11 @@ msgstr "" "geometric features of this object.\n" "Expressions are allowed. E.g: 1/25.4" -#: flatcamGUI/ObjectUI.py:123 +#: flatcamGUI/ObjectUI.py:126 msgid "Perform scaling operation." msgstr "Perform scaling operation." -#: flatcamGUI/ObjectUI.py:134 -msgid "Change the position of this object." -msgstr "Change the position of this object." - -#: flatcamGUI/ObjectUI.py:139 -msgid "Vector" -msgstr "Vector" - -#: flatcamGUI/ObjectUI.py:141 +#: flatcamGUI/ObjectUI.py:137 msgid "" "Amount by which to move the object\n" "in the x and y axes in (x, y) format.\n" @@ -7033,60 +7472,53 @@ msgstr "" "in the x and y axes in (x, y) format.\n" "Expressions are allowed. E.g: (1/3.2, 0.5*3)" -#: flatcamGUI/ObjectUI.py:150 +#: flatcamGUI/ObjectUI.py:144 msgid "Perform the offset operation." msgstr "Perform the offset operation." -#: flatcamGUI/ObjectUI.py:167 +#: flatcamGUI/ObjectUI.py:177 msgid "Gerber Object" msgstr "Gerber Object" -#: flatcamGUI/ObjectUI.py:182 flatcamGUI/ObjectUI.py:767 -#: flatcamGUI/ObjectUI.py:1205 flatcamGUI/ObjectUI.py:1905 -#: flatcamGUI/PreferencesUI.py:1783 flatcamGUI/PreferencesUI.py:3849 -#: flatcamGUI/PreferencesUI.py:4406 -msgid "Plot (show) this object." -msgstr "Plot (show) this object." - -#: flatcamGUI/ObjectUI.py:184 flatcamGUI/ObjectUI.py:765 -#: flatcamGUI/PreferencesUI.py:1781 flatcamGUI/PreferencesUI.py:2680 -#: flatcamGUI/PreferencesUI.py:3847 -msgid "Plot" -msgstr "Plot" - -#: flatcamGUI/ObjectUI.py:189 flatcamGUI/ObjectUI.py:726 -#: flatcamGUI/ObjectUI.py:1159 flatcamGUI/ObjectUI.py:1795 -#: flatcamGUI/PreferencesUI.py:1760 flatcamGUI/PreferencesUI.py:2674 -#: flatcamGUI/PreferencesUI.py:3843 flatcamGUI/PreferencesUI.py:4395 +#: flatcamGUI/ObjectUI.py:186 flatcamGUI/ObjectUI.py:729 +#: flatcamGUI/ObjectUI.py:1424 flatcamGUI/ObjectUI.py:2123 +#: flatcamGUI/PreferencesUI.py:1940 flatcamGUI/PreferencesUI.py:2856 +#: flatcamGUI/PreferencesUI.py:4121 flatcamGUI/PreferencesUI.py:4688 msgid "Plot Options" msgstr "Plot Options" -#: flatcamGUI/ObjectUI.py:195 flatcamGUI/ObjectUI.py:727 -#: flatcamGUI/PreferencesUI.py:1767 flatcamGUI/PreferencesUI.py:2686 -#: flatcamGUI/PreferencesUI.py:7222 flatcamTools/ToolCopperThieving.py:190 +#: flatcamGUI/ObjectUI.py:192 flatcamGUI/ObjectUI.py:730 +#: flatcamGUI/PreferencesUI.py:1947 flatcamGUI/PreferencesUI.py:2868 +#: flatcamGUI/PreferencesUI.py:7728 flatcamTools/ToolCopperThieving.py:192 msgid "Solid" msgstr "Solid" -#: flatcamGUI/ObjectUI.py:197 flatcamGUI/PreferencesUI.py:1769 +#: flatcamGUI/ObjectUI.py:194 flatcamGUI/PreferencesUI.py:1949 msgid "Solid color polygons." msgstr "Solid color polygons." -#: flatcamGUI/ObjectUI.py:203 +#: flatcamGUI/ObjectUI.py:200 msgid "Multi-Color" msgstr "Multi-Color" -#: flatcamGUI/ObjectUI.py:205 flatcamGUI/PreferencesUI.py:1776 +#: flatcamGUI/ObjectUI.py:202 flatcamGUI/PreferencesUI.py:1956 msgid "Draw polygons in different colors." msgstr "Draw polygons in different colors." -#: flatcamGUI/ObjectUI.py:213 flatcamGUI/ObjectUI.py:738 -#: flatcamGUI/ObjectUI.py:1165 flatcamGUI/ObjectUI.py:1825 -#: flatcamGUI/ObjectUI.py:2128 flatcamGUI/ObjectUI.py:2194 -#: flatcamTools/ToolCalibration.py:235 flatcamTools/ToolFiducials.py:73 -msgid "Name" -msgstr "Name" +#: flatcamGUI/ObjectUI.py:208 flatcamGUI/ObjectUI.py:768 +#: flatcamGUI/PreferencesUI.py:1961 flatcamGUI/PreferencesUI.py:2862 +#: flatcamGUI/PreferencesUI.py:4125 +msgid "Plot" +msgstr "Plot" -#: flatcamGUI/ObjectUI.py:234 +#: flatcamGUI/ObjectUI.py:210 flatcamGUI/ObjectUI.py:770 +#: flatcamGUI/ObjectUI.py:1484 flatcamGUI/ObjectUI.py:2233 +#: flatcamGUI/PreferencesUI.py:1963 flatcamGUI/PreferencesUI.py:4127 +#: flatcamGUI/PreferencesUI.py:4699 +msgid "Plot (show) this object." +msgstr "Plot (show) this object." + +#: flatcamGUI/ObjectUI.py:238 msgid "" "Toggle the display of the Gerber Apertures Table.\n" "When unchecked, it will delete all mark shapes\n" @@ -7096,11 +7528,11 @@ msgstr "" "When unchecked, it will delete all mark shapes\n" "that are drawn on canvas." -#: flatcamGUI/ObjectUI.py:244 +#: flatcamGUI/ObjectUI.py:248 msgid "Mark All" msgstr "Mark All" -#: flatcamGUI/ObjectUI.py:246 +#: flatcamGUI/ObjectUI.py:250 msgid "" "When checked it will display all the apertures.\n" "When unchecked, it will delete all mark shapes\n" @@ -7110,15 +7542,15 @@ msgstr "" "When unchecked, it will delete all mark shapes\n" "that are drawn on canvas." -#: flatcamGUI/ObjectUI.py:274 +#: flatcamGUI/ObjectUI.py:278 msgid "Mark the aperture instances on canvas." msgstr "Mark the aperture instances on canvas." -#: flatcamGUI/ObjectUI.py:286 flatcamGUI/PreferencesUI.py:2014 +#: flatcamGUI/ObjectUI.py:290 flatcamGUI/PreferencesUI.py:2194 msgid "Isolation Routing" msgstr "Isolation Routing" -#: flatcamGUI/ObjectUI.py:288 flatcamGUI/PreferencesUI.py:2016 +#: flatcamGUI/ObjectUI.py:292 flatcamGUI/PreferencesUI.py:2196 msgid "" "Create a Geometry object with\n" "toolpaths to cut outside polygons." @@ -7126,7 +7558,7 @@ msgstr "" "Create a Geometry object with\n" "toolpaths to cut outside polygons." -#: flatcamGUI/ObjectUI.py:306 flatcamGUI/PreferencesUI.py:2219 +#: flatcamGUI/ObjectUI.py:310 flatcamGUI/PreferencesUI.py:2399 msgid "" "Choose what tool to use for Gerber isolation:\n" "'Circular' or 'V-shape'.\n" @@ -7138,31 +7570,37 @@ msgstr "" "When the 'V-shape' is selected then the tool\n" "diameter will depend on the chosen cut depth." -#: flatcamGUI/ObjectUI.py:312 +#: flatcamGUI/ObjectUI.py:316 msgid "V-Shape" msgstr "V-Shape" -#: flatcamGUI/ObjectUI.py:318 flatcamGUI/ObjectUI.py:1374 -#: flatcamGUI/PreferencesUI.py:2231 flatcamGUI/PreferencesUI.py:5055 -#: flatcamTools/ToolNonCopperClear.py:231 +#: flatcamGUI/ObjectUI.py:322 flatcamGUI/ObjectUI.py:1670 +#: flatcamGUI/PreferencesUI.py:2411 flatcamGUI/PreferencesUI.py:5351 +#: flatcamGUI/PreferencesUI.py:5917 flatcamGUI/PreferencesUI.py:5924 +#: flatcamTools/ToolNCC.py:233 flatcamTools/ToolNCC.py:240 +#: flatcamTools/ToolPaint.py:216 msgid "V-Tip Dia" msgstr "V-Tip Dia" -#: flatcamGUI/ObjectUI.py:320 flatcamGUI/ObjectUI.py:1377 -#: flatcamGUI/PreferencesUI.py:2233 flatcamGUI/PreferencesUI.py:5057 -#: flatcamTools/ToolNonCopperClear.py:233 +#: flatcamGUI/ObjectUI.py:324 flatcamGUI/ObjectUI.py:1673 +#: flatcamGUI/PreferencesUI.py:2413 flatcamGUI/PreferencesUI.py:5353 +#: flatcamGUI/PreferencesUI.py:5919 flatcamTools/ToolNCC.py:235 +#: flatcamTools/ToolPaint.py:218 msgid "The tip diameter for V-Shape Tool" msgstr "The tip diameter for V-Shape Tool" -#: flatcamGUI/ObjectUI.py:331 flatcamGUI/ObjectUI.py:1389 -#: flatcamGUI/PreferencesUI.py:2244 flatcamGUI/PreferencesUI.py:5067 -#: flatcamTools/ToolNonCopperClear.py:242 +#: flatcamGUI/ObjectUI.py:335 flatcamGUI/ObjectUI.py:1685 +#: flatcamGUI/PreferencesUI.py:2424 flatcamGUI/PreferencesUI.py:5363 +#: flatcamGUI/PreferencesUI.py:5930 flatcamGUI/PreferencesUI.py:5938 +#: flatcamTools/ToolNCC.py:246 flatcamTools/ToolNCC.py:254 +#: flatcamTools/ToolPaint.py:229 msgid "V-Tip Angle" msgstr "V-Tip Angle" -#: flatcamGUI/ObjectUI.py:333 flatcamGUI/ObjectUI.py:1392 -#: flatcamGUI/PreferencesUI.py:2246 flatcamGUI/PreferencesUI.py:5069 -#: flatcamTools/ToolNonCopperClear.py:244 +#: flatcamGUI/ObjectUI.py:337 flatcamGUI/ObjectUI.py:1688 +#: flatcamGUI/PreferencesUI.py:2426 flatcamGUI/PreferencesUI.py:5365 +#: flatcamGUI/PreferencesUI.py:5932 flatcamTools/ToolNCC.py:248 +#: flatcamTools/ToolPaint.py:231 msgid "" "The tip angle for V-Shape Tool.\n" "In degree." @@ -7170,9 +7608,9 @@ msgstr "" "The tip angle for V-Shape Tool.\n" "In degree." -#: flatcamGUI/ObjectUI.py:347 flatcamGUI/ObjectUI.py:1408 -#: flatcamGUI/PreferencesUI.py:2259 flatcamGUI/PreferencesUI.py:3963 -#: flatcamGUI/PreferencesUI.py:5330 flatcamTools/ToolCutOut.py:135 +#: flatcamGUI/ObjectUI.py:351 flatcamGUI/ObjectUI.py:1704 +#: flatcamGUI/PreferencesUI.py:2439 flatcamGUI/PreferencesUI.py:4243 +#: flatcamGUI/PreferencesUI.py:5669 flatcamTools/ToolCutOut.py:142 msgid "" "Cutting depth (negative)\n" "below the copper surface." @@ -7180,7 +7618,7 @@ msgstr "" "Cutting depth (negative)\n" "below the copper surface." -#: flatcamGUI/ObjectUI.py:361 +#: flatcamGUI/ObjectUI.py:365 msgid "" "Diameter of the cutting tool.\n" "If you want to have an isolation path\n" @@ -7194,11 +7632,11 @@ msgstr "" "feature, use a negative value for\n" "this parameter." -#: flatcamGUI/ObjectUI.py:377 flatcamGUI/PreferencesUI.py:2038 +#: flatcamGUI/ObjectUI.py:381 flatcamGUI/PreferencesUI.py:2218 msgid "# Passes" msgstr "# Passes" -#: flatcamGUI/ObjectUI.py:379 flatcamGUI/PreferencesUI.py:2040 +#: flatcamGUI/ObjectUI.py:383 flatcamGUI/PreferencesUI.py:2220 msgid "" "Width of the isolation gap in\n" "number (integer) of tool widths." @@ -7206,22 +7644,17 @@ msgstr "" "Width of the isolation gap in\n" "number (integer) of tool widths." -#: flatcamGUI/ObjectUI.py:389 flatcamGUI/PreferencesUI.py:2050 +#: flatcamGUI/ObjectUI.py:394 flatcamGUI/PreferencesUI.py:2230 msgid "Pass overlap" msgstr "Pass overlap" -#: flatcamGUI/ObjectUI.py:391 flatcamGUI/PreferencesUI.py:2052 -msgid "How much (fraction) of the tool width to overlap each tool pass." -msgstr "How much (fraction) of the tool width to overlap each tool pass." +#: flatcamGUI/ObjectUI.py:396 flatcamGUI/PreferencesUI.py:2232 +#| msgid "How much (fraction) of the tool width to overlap each tool pass." +msgid "How much (percentage) of the tool width to overlap each tool pass." +msgstr "How much (percentage) of the tool width to overlap each tool pass." -#: flatcamGUI/ObjectUI.py:403 flatcamGUI/PreferencesUI.py:2077 -#: flatcamGUI/PreferencesUI.py:4372 flatcamGUI/PreferencesUI.py:5112 -#: flatcamTools/ToolNonCopperClear.py:162 -msgid "Milling Type" -msgstr "Milling Type" - -#: flatcamGUI/ObjectUI.py:405 flatcamGUI/PreferencesUI.py:2079 -#: flatcamGUI/PreferencesUI.py:4374 +#: flatcamGUI/ObjectUI.py:410 flatcamGUI/PreferencesUI.py:2259 +#: flatcamGUI/PreferencesUI.py:4667 msgid "" "Milling type:\n" "- climb / best for precision milling and to reduce tool usage\n" @@ -7231,29 +7664,19 @@ msgstr "" "- climb / best for precision milling and to reduce tool usage\n" "- conventional / useful when there is no backlash compensation" -#: flatcamGUI/ObjectUI.py:409 flatcamGUI/PreferencesUI.py:2084 -#: flatcamGUI/PreferencesUI.py:4378 flatcamGUI/PreferencesUI.py:5119 -#: flatcamTools/ToolNonCopperClear.py:169 -msgid "Climb" -msgstr "Climb" - -#: flatcamGUI/ObjectUI.py:410 -msgid "Conventional" -msgstr "Conventional" - -#: flatcamGUI/ObjectUI.py:415 +#: flatcamGUI/ObjectUI.py:420 msgid "Combine" msgstr "Combine" -#: flatcamGUI/ObjectUI.py:417 flatcamGUI/PreferencesUI.py:2091 +#: flatcamGUI/ObjectUI.py:422 flatcamGUI/PreferencesUI.py:2271 msgid "Combine all passes into one object" msgstr "Combine all passes into one object" -#: flatcamGUI/ObjectUI.py:421 flatcamGUI/PreferencesUI.py:2193 +#: flatcamGUI/ObjectUI.py:426 flatcamGUI/PreferencesUI.py:2373 msgid "\"Follow\"" msgstr "\"Follow\"" -#: flatcamGUI/ObjectUI.py:422 flatcamGUI/PreferencesUI.py:2195 +#: flatcamGUI/ObjectUI.py:427 flatcamGUI/PreferencesUI.py:2375 msgid "" "Generate a 'Follow' geometry.\n" "This means that it will cut through\n" @@ -7263,11 +7686,11 @@ msgstr "" "This means that it will cut through\n" "the middle of the trace." -#: flatcamGUI/ObjectUI.py:428 +#: flatcamGUI/ObjectUI.py:433 msgid "Except" msgstr "Except" -#: flatcamGUI/ObjectUI.py:431 +#: flatcamGUI/ObjectUI.py:436 msgid "" "When the isolation geometry is generated,\n" "by checking this, the area of the object bellow\n" @@ -7277,12 +7700,12 @@ msgstr "" "by checking this, the area of the object bellow\n" "will be subtracted from the isolation geometry." -#: flatcamGUI/ObjectUI.py:453 flatcamTools/ToolNonCopperClear.py:82 -#: flatcamTools/ToolPaint.py:85 +#: flatcamGUI/ObjectUI.py:456 flatcamTools/ToolNCC.py:86 +#: flatcamTools/ToolPaint.py:80 msgid "Obj Type" msgstr "Obj Type" -#: flatcamGUI/ObjectUI.py:455 +#: flatcamGUI/ObjectUI.py:458 msgid "" "Specify the type of object to be excepted from isolation.\n" "It can be of type: Gerber or Geometry.\n" @@ -7294,22 +7717,22 @@ msgstr "" "What is selected here will dictate the kind\n" "of objects that will populate the 'Object' combobox." -#: flatcamGUI/ObjectUI.py:468 flatcamGUI/PreferencesUI.py:7522 -#: flatcamTools/ToolCalibration.py:186 flatcamTools/ToolNonCopperClear.py:100 -#: flatcamTools/ToolPaint.py:103 flatcamTools/ToolPanelize.py:81 -#: flatcamTools/ToolPanelize.py:94 +#: flatcamGUI/ObjectUI.py:471 flatcamGUI/PreferencesUI.py:8028 +#: flatcamTools/ToolCalibration.py:186 flatcamTools/ToolNCC.py:109 +#: flatcamTools/ToolPaint.py:103 flatcamTools/ToolPanelize.py:100 +#: flatcamTools/ToolQRCode.py:78 msgid "Object" msgstr "Object" -#: flatcamGUI/ObjectUI.py:469 +#: flatcamGUI/ObjectUI.py:472 msgid "Object whose area will be removed from isolation geometry." msgstr "Object whose area will be removed from isolation geometry." -#: flatcamGUI/ObjectUI.py:476 flatcamGUI/PreferencesUI.py:2064 +#: flatcamGUI/ObjectUI.py:479 flatcamGUI/PreferencesUI.py:2244 msgid "Scope" msgstr "Scope" -#: flatcamGUI/ObjectUI.py:478 flatcamGUI/PreferencesUI.py:2066 +#: flatcamGUI/ObjectUI.py:481 flatcamGUI/PreferencesUI.py:2246 msgid "" "Isolation scope. Choose what to isolate:\n" "- 'All' -> Isolate all the polygons in the object\n" @@ -7319,17 +7742,18 @@ msgstr "" "- 'All' -> Isolate all the polygons in the object\n" "- 'Selection' -> Isolate a selection of polygons." -#: flatcamGUI/ObjectUI.py:483 flatcamGUI/PreferencesUI.py:602 -#: flatcamGUI/PreferencesUI.py:2071 flatcamGUI/PreferencesUI.py:5634 -#: flatcamTools/ToolPaint.py:294 +#: flatcamGUI/ObjectUI.py:486 flatcamGUI/PreferencesUI.py:624 +#: flatcamGUI/PreferencesUI.py:2251 flatcamGUI/PreferencesUI.py:5590 +#: flatcamGUI/PreferencesUI.py:6097 flatcamTools/ToolNCC.py:539 +#: flatcamTools/ToolPaint.py:456 msgid "Selection" msgstr "Selection" -#: flatcamGUI/ObjectUI.py:491 flatcamGUI/PreferencesUI.py:2272 +#: flatcamGUI/ObjectUI.py:494 flatcamGUI/PreferencesUI.py:2452 msgid "Isolation Type" msgstr "Isolation Type" -#: flatcamGUI/ObjectUI.py:493 flatcamGUI/PreferencesUI.py:2274 +#: flatcamGUI/ObjectUI.py:496 flatcamGUI/PreferencesUI.py:2454 msgid "" "Choose how the isolation will be executed:\n" "- 'Full' -> complete isolation of polygons\n" @@ -7349,24 +7773,24 @@ msgstr "" "isolation can be done only when there is an opening\n" "inside of the polygon (e.g polygon is a 'doughnut' shape)." -#: flatcamGUI/ObjectUI.py:502 flatcamGUI/PreferencesUI.py:2283 -#: flatcamGUI/PreferencesUI.py:2304 +#: flatcamGUI/ObjectUI.py:505 flatcamGUI/PreferencesUI.py:2463 +#: flatcamGUI/PreferencesUI.py:2484 msgid "Full" msgstr "Full" -#: flatcamGUI/ObjectUI.py:503 +#: flatcamGUI/ObjectUI.py:506 msgid "Ext" msgstr "Ext" -#: flatcamGUI/ObjectUI.py:504 +#: flatcamGUI/ObjectUI.py:507 msgid "Int" msgstr "Int" -#: flatcamGUI/ObjectUI.py:509 +#: flatcamGUI/ObjectUI.py:512 msgid "Generate Isolation Geometry" msgstr "Generate Isolation Geometry" -#: flatcamGUI/ObjectUI.py:517 +#: flatcamGUI/ObjectUI.py:520 msgid "" "Create a Geometry object with toolpaths to cut \n" "isolation outside, inside or on both sides of the\n" @@ -7388,11 +7812,11 @@ msgstr "" "inside the actual Gerber feature, use a negative tool\n" "diameter above." -#: flatcamGUI/ObjectUI.py:529 +#: flatcamGUI/ObjectUI.py:532 msgid "Buffer Solid Geometry" msgstr "Buffer Solid Geometry" -#: flatcamGUI/ObjectUI.py:531 +#: flatcamGUI/ObjectUI.py:534 msgid "" "This button is shown only when the Gerber file\n" "is loaded without buffering.\n" @@ -7404,11 +7828,11 @@ msgstr "" "Clicking this will create the buffered geometry\n" "required for isolation." -#: flatcamGUI/ObjectUI.py:559 +#: flatcamGUI/ObjectUI.py:566 msgid "Clear N-copper" msgstr "Clear N-copper" -#: flatcamGUI/ObjectUI.py:561 flatcamGUI/PreferencesUI.py:5019 +#: flatcamGUI/ObjectUI.py:568 flatcamGUI/PreferencesUI.py:5312 msgid "" "Create a Geometry object with\n" "toolpaths to cut all non-copper regions." @@ -7416,8 +7840,8 @@ msgstr "" "Create a Geometry object with\n" "toolpaths to cut all non-copper regions." -#: flatcamGUI/ObjectUI.py:568 flatcamGUI/ObjectUI.py:1751 -#: flatcamTools/ToolNonCopperClear.py:473 +#: flatcamGUI/ObjectUI.py:575 flatcamGUI/ObjectUI.py:2077 +#: flatcamTools/ToolNCC.py:599 msgid "" "Create the Geometry Object\n" "for non-copper routing." @@ -7425,11 +7849,11 @@ msgstr "" "Create the Geometry Object\n" "for non-copper routing." -#: flatcamGUI/ObjectUI.py:581 +#: flatcamGUI/ObjectUI.py:588 msgid "Board cutout" msgstr "Board cutout" -#: flatcamGUI/ObjectUI.py:583 flatcamGUI/PreferencesUI.py:5303 +#: flatcamGUI/ObjectUI.py:590 flatcamGUI/PreferencesUI.py:5642 msgid "" "Create toolpaths to cut around\n" "the PCB and separate it from\n" @@ -7439,7 +7863,7 @@ msgstr "" "the PCB and separate it from\n" "the original board." -#: flatcamGUI/ObjectUI.py:590 +#: flatcamGUI/ObjectUI.py:597 msgid "" "Generate the geometry for\n" "the board cutout." @@ -7447,11 +7871,11 @@ msgstr "" "Generate the geometry for\n" "the board cutout." -#: flatcamGUI/ObjectUI.py:608 flatcamGUI/PreferencesUI.py:2101 +#: flatcamGUI/ObjectUI.py:615 flatcamGUI/PreferencesUI.py:2281 msgid "Non-copper regions" msgstr "Non-copper regions" -#: flatcamGUI/ObjectUI.py:610 flatcamGUI/PreferencesUI.py:2103 +#: flatcamGUI/ObjectUI.py:617 flatcamGUI/PreferencesUI.py:2283 msgid "" "Create polygons covering the\n" "areas without copper on the PCB.\n" @@ -7465,12 +7889,12 @@ msgstr "" "object. Can be used to remove all\n" "copper from a specified region." -#: flatcamGUI/ObjectUI.py:620 flatcamGUI/ObjectUI.py:661 -#: flatcamGUI/PreferencesUI.py:2115 flatcamGUI/PreferencesUI.py:2148 +#: flatcamGUI/ObjectUI.py:627 flatcamGUI/ObjectUI.py:668 +#: flatcamGUI/PreferencesUI.py:2295 flatcamGUI/PreferencesUI.py:2328 msgid "Boundary Margin" msgstr "Boundary Margin" -#: flatcamGUI/ObjectUI.py:622 flatcamGUI/PreferencesUI.py:2117 +#: flatcamGUI/ObjectUI.py:629 flatcamGUI/PreferencesUI.py:2297 msgid "" "Specify the edge of the PCB\n" "by drawing a box around all\n" @@ -7482,27 +7906,27 @@ msgstr "" "objects with this minimum\n" "distance." -#: flatcamGUI/ObjectUI.py:637 flatcamGUI/ObjectUI.py:675 -#: flatcamGUI/PreferencesUI.py:2130 flatcamGUI/PreferencesUI.py:2161 +#: flatcamGUI/ObjectUI.py:644 flatcamGUI/ObjectUI.py:682 +#: flatcamGUI/PreferencesUI.py:2310 flatcamGUI/PreferencesUI.py:2341 msgid "Rounded Geo" msgstr "Rounded Geo" -#: flatcamGUI/ObjectUI.py:639 flatcamGUI/PreferencesUI.py:2132 +#: flatcamGUI/ObjectUI.py:646 flatcamGUI/PreferencesUI.py:2312 msgid "Resulting geometry will have rounded corners." msgstr "Resulting geometry will have rounded corners." -#: flatcamGUI/ObjectUI.py:643 flatcamGUI/ObjectUI.py:684 -#: flatcamTools/ToolSolderPaste.py:133 +#: flatcamGUI/ObjectUI.py:650 flatcamGUI/ObjectUI.py:691 +#: flatcamTools/ToolSolderPaste.py:135 msgid "Generate Geo" msgstr "Generate Geo" -#: flatcamGUI/ObjectUI.py:653 flatcamGUI/PreferencesUI.py:2142 -#: flatcamGUI/PreferencesUI.py:7052 flatcamTools/ToolPanelize.py:95 +#: flatcamGUI/ObjectUI.py:660 flatcamGUI/PreferencesUI.py:2322 +#: flatcamGUI/PreferencesUI.py:7558 flatcamTools/ToolPanelize.py:101 #: flatcamTools/ToolQRCode.py:192 msgid "Bounding Box" msgstr "Bounding Box" -#: flatcamGUI/ObjectUI.py:655 +#: flatcamGUI/ObjectUI.py:662 msgid "" "Create a geometry surrounding the Gerber object.\n" "Square shape." @@ -7510,7 +7934,7 @@ msgstr "" "Create a geometry surrounding the Gerber object.\n" "Square shape." -#: flatcamGUI/ObjectUI.py:663 flatcamGUI/PreferencesUI.py:2150 +#: flatcamGUI/ObjectUI.py:670 flatcamGUI/PreferencesUI.py:2330 msgid "" "Distance of the edges of the box\n" "to the nearest polygon." @@ -7518,7 +7942,7 @@ msgstr "" "Distance of the edges of the box\n" "to the nearest polygon." -#: flatcamGUI/ObjectUI.py:677 flatcamGUI/PreferencesUI.py:2163 +#: flatcamGUI/ObjectUI.py:684 flatcamGUI/PreferencesUI.py:2343 msgid "" "If the bounding box is \n" "to have rounded corners\n" @@ -7530,33 +7954,31 @@ msgstr "" "their radius is equal to\n" "the margin." -#: flatcamGUI/ObjectUI.py:686 +#: flatcamGUI/ObjectUI.py:693 msgid "Generate the Geometry object." msgstr "Generate the Geometry object." -#: flatcamGUI/ObjectUI.py:715 +#: flatcamGUI/ObjectUI.py:720 msgid "Excellon Object" msgstr "Excellon Object" -#: flatcamGUI/ObjectUI.py:729 +#: flatcamGUI/ObjectUI.py:732 msgid "Solid circles." msgstr "Solid circles." -#: flatcamGUI/ObjectUI.py:777 flatcamGUI/ObjectUI.py:1926 -#: flatcamTools/ToolProperties.py:161 +#: flatcamGUI/ObjectUI.py:780 flatcamGUI/ObjectUI.py:875 +#: flatcamGUI/ObjectUI.py:2254 flatcamGUI/PreferencesUI.py:3289 +#: flatcamTools/ToolProperties.py:166 msgid "Drills" msgstr "Drills" -#: flatcamGUI/ObjectUI.py:777 flatcamGUI/ObjectUI.py:1926 -#: flatcamGUI/PreferencesUI.py:3683 flatcamTools/ToolProperties.py:162 +#: flatcamGUI/ObjectUI.py:780 flatcamGUI/ObjectUI.py:876 +#: flatcamGUI/ObjectUI.py:2254 flatcamGUI/PreferencesUI.py:3290 +#: flatcamGUI/PreferencesUI.py:3961 flatcamTools/ToolProperties.py:168 msgid "Slots" msgstr "Slots" -#: flatcamGUI/ObjectUI.py:778 flatcamGUI/PreferencesUI.py:3289 -msgid "Offset Z" -msgstr "Offset Z" - -#: flatcamGUI/ObjectUI.py:782 +#: flatcamGUI/ObjectUI.py:785 msgid "" "This is the Tool Number.\n" "When ToolChange is checked, on toolchange event this value\n" @@ -7570,8 +7992,8 @@ msgstr "" "\n" "Here the tools are selected for G-code generation." -#: flatcamGUI/ObjectUI.py:787 flatcamGUI/ObjectUI.py:1230 -#: flatcamTools/ToolPaint.py:137 +#: flatcamGUI/ObjectUI.py:790 flatcamGUI/ObjectUI.py:1508 +#: flatcamTools/ToolPaint.py:142 msgid "" "Tool Diameter. It's value (in current FlatCAM units) \n" "is the cut width into the material." @@ -7579,33 +8001,23 @@ msgstr "" "Tool Diameter. It's value (in current FlatCAM units) \n" "is the cut width into the material." -#: flatcamGUI/ObjectUI.py:790 -msgid "" -"The number of Drill holes. Holes that are drilled with\n" -"a drill bit." -msgstr "" -"The number of Drill holes. Holes that are drilled with\n" -"a drill bit." - #: flatcamGUI/ObjectUI.py:793 msgid "" -"The number of Slot holes. Holes that are created by\n" -"milling them with an endmill bit." +"The number of Drill holes. Holes that are drilled with\n" +"a drill bit." msgstr "" -"The number of Slot holes. Holes that are created by\n" -"milling them with an endmill bit." +"The number of Drill holes. Holes that are drilled with\n" +"a drill bit." -#: flatcamGUI/ObjectUI.py:796 flatcamGUI/PreferencesUI.py:3291 +#: flatcamGUI/ObjectUI.py:796 msgid "" -"Some drill bits (the larger ones) need to drill deeper\n" -"to create the desired exit hole diameter due of the tip shape.\n" -"The value here can compensate the Cut Z parameter." +"The number of Slot holes. Holes that are created by\n" +"milling them with an endmill bit." msgstr "" -"Some drill bits (the larger ones) need to drill deeper\n" -"to create the desired exit hole diameter due of the tip shape.\n" -"The value here can compensate the Cut Z parameter." +"The number of Slot holes. Holes that are created by\n" +"milling them with an endmill bit." -#: flatcamGUI/ObjectUI.py:800 +#: flatcamGUI/ObjectUI.py:799 msgid "" "Toggle display of the drills for the current tool.\n" "This does not select the tools for G-code generation." @@ -7613,453 +8025,8 @@ msgstr "" "Toggle display of the drills for the current tool.\n" "This does not select the tools for G-code generation." -#: flatcamGUI/ObjectUI.py:807 flatcamGUI/PreferencesUI.py:3069 -#: flatcamGUI/PreferencesUI.py:3947 -msgid "Create CNC Job" -msgstr "Create CNC Job" - -#: flatcamGUI/ObjectUI.py:809 -msgid "" -"Create a CNC Job object\n" -"for this drill object." -msgstr "" -"Create a CNC Job object\n" -"for this drill object." - -#: flatcamGUI/ObjectUI.py:822 flatcamGUI/PreferencesUI.py:3084 -msgid "" -"Drill depth (negative)\n" -"below the copper surface." -msgstr "" -"Drill depth (negative)\n" -"below the copper surface." - -#: flatcamGUI/ObjectUI.py:841 flatcamGUI/PreferencesUI.py:3102 -msgid "" -"Tool height when travelling\n" -"across the XY plane." -msgstr "" -"Tool height when travelling\n" -"across the XY plane." - -#: flatcamGUI/ObjectUI.py:858 flatcamGUI/ObjectUI.py:1478 -#: flatcamGUI/PreferencesUI.py:3117 flatcamGUI/PreferencesUI.py:4034 -msgid "Tool change" -msgstr "Tool change" - -#: flatcamGUI/ObjectUI.py:860 flatcamGUI/PreferencesUI.py:3119 -msgid "" -"Include tool-change sequence\n" -"in G-Code (Pause for tool change)." -msgstr "" -"Include tool-change sequence\n" -"in G-Code (Pause for tool change)." - -#: flatcamGUI/ObjectUI.py:866 flatcamGUI/ObjectUI.py:1471 -msgid "Tool change Z" -msgstr "Tool change Z" - -#: flatcamGUI/ObjectUI.py:868 flatcamGUI/ObjectUI.py:1474 -#: flatcamGUI/PreferencesUI.py:3126 flatcamGUI/PreferencesUI.py:4047 -msgid "" -"Z-axis position (height) for\n" -"tool change." -msgstr "" -"Z-axis position (height) for\n" -"tool change." - -#: flatcamGUI/ObjectUI.py:888 flatcamGUI/PreferencesUI.py:3311 -msgid "" -"Height of the tool just after start.\n" -"Delete the value if you don't need this feature." -msgstr "" -"Height of the tool just after start.\n" -"Delete the value if you don't need this feature." - -#: flatcamGUI/ObjectUI.py:896 flatcamGUI/ObjectUI.py:1512 -#: flatcamGUI/PreferencesUI.py:3141 flatcamGUI/PreferencesUI.py:4066 -msgid "End move Z" -msgstr "End move Z" - -#: flatcamGUI/ObjectUI.py:898 flatcamGUI/ObjectUI.py:1514 -#: flatcamGUI/PreferencesUI.py:3143 flatcamGUI/PreferencesUI.py:4068 -msgid "" -"Height of the tool after\n" -"the last move at the end of the job." -msgstr "" -"Height of the tool after\n" -"the last move at the end of the job." - -#: flatcamGUI/ObjectUI.py:915 flatcamGUI/ObjectUI.py:1545 -#: flatcamGUI/PreferencesUI.py:3158 flatcamGUI/PreferencesUI.py:4101 -#: flatcamGUI/PreferencesUI.py:6566 flatcamTools/ToolSolderPaste.py:264 -msgid "Feedrate Z" -msgstr "Feedrate Z" - -#: flatcamGUI/ObjectUI.py:917 flatcamGUI/PreferencesUI.py:3160 -msgid "" -"Tool speed while drilling\n" -"(in units per minute).\n" -"So called 'Plunge' feedrate.\n" -"This is for linear move G01." -msgstr "" -"Tool speed while drilling\n" -"(in units per minute).\n" -"So called 'Plunge' feedrate.\n" -"This is for linear move G01." - -#: flatcamGUI/ObjectUI.py:931 flatcamGUI/ObjectUI.py:1560 -#: flatcamGUI/PreferencesUI.py:3319 flatcamGUI/PreferencesUI.py:4210 -msgid "Feedrate Rapids" -msgstr "Feedrate Rapids" - -#: flatcamGUI/ObjectUI.py:933 flatcamGUI/PreferencesUI.py:3321 -msgid "" -"Tool speed while drilling\n" -"(in units per minute).\n" -"This is for the rapid move G00.\n" -"It is useful only for Marlin,\n" -"ignore for any other cases." -msgstr "" -"Tool speed while drilling\n" -"(in units per minute).\n" -"This is for the rapid move G00.\n" -"It is useful only for Marlin,\n" -"ignore for any other cases." - -#: flatcamGUI/ObjectUI.py:951 flatcamGUI/ObjectUI.py:1603 -#: flatcamGUI/PreferencesUI.py:4117 -msgid "Spindle speed" -msgstr "Spindle speed" - -#: flatcamGUI/ObjectUI.py:953 flatcamGUI/PreferencesUI.py:3175 -msgid "" -"Speed of the spindle\n" -"in RPM (optional)" -msgstr "" -"Speed of the spindle\n" -"in RPM (optional)" - -#: flatcamGUI/ObjectUI.py:965 flatcamGUI/ObjectUI.py:1622 -#: flatcamGUI/PreferencesUI.py:3187 flatcamGUI/PreferencesUI.py:4135 -msgid "" -"Pause to allow the spindle to reach its\n" -"speed before cutting." -msgstr "" -"Pause to allow the spindle to reach its\n" -"speed before cutting." - -#: flatcamGUI/ObjectUI.py:974 flatcamGUI/ObjectUI.py:1632 -#: flatcamGUI/PreferencesUI.py:3193 flatcamGUI/PreferencesUI.py:4140 -msgid "Number of time units for spindle to dwell." -msgstr "Number of time units for spindle to dwell." - -#: flatcamGUI/ObjectUI.py:984 flatcamGUI/PreferencesUI.py:3206 -msgid "" -"The preprocessor JSON file that dictates\n" -"Gcode output." -msgstr "" -"The preprocessor JSON file that dictates\n" -"Gcode output." - -#: flatcamGUI/ObjectUI.py:993 flatcamGUI/ObjectUI.py:1652 -#: flatcamGUI/PreferencesUI.py:3335 flatcamGUI/PreferencesUI.py:4251 -msgid "Probe Z depth" -msgstr "Probe Z depth" - -#: flatcamGUI/ObjectUI.py:995 flatcamGUI/ObjectUI.py:1654 -#: flatcamGUI/PreferencesUI.py:3337 flatcamGUI/PreferencesUI.py:4253 -msgid "" -"The maximum depth that the probe is allowed\n" -"to probe. Negative value, in current units." -msgstr "" -"The maximum depth that the probe is allowed\n" -"to probe. Negative value, in current units." - -#: flatcamGUI/ObjectUI.py:1009 flatcamGUI/ObjectUI.py:1669 -#: flatcamGUI/PreferencesUI.py:3348 flatcamGUI/PreferencesUI.py:4266 -msgid "Feedrate Probe" -msgstr "Feedrate Probe" - -#: flatcamGUI/ObjectUI.py:1011 flatcamGUI/ObjectUI.py:1671 -#: flatcamGUI/PreferencesUI.py:3350 flatcamGUI/PreferencesUI.py:4268 -msgid "The feedrate used while the probe is probing." -msgstr "The feedrate used while the probe is probing." - -#: flatcamGUI/ObjectUI.py:1037 flatcamGUI/PreferencesUI.py:3215 -msgid "Gcode" -msgstr "Gcode" - -#: flatcamGUI/ObjectUI.py:1039 -msgid "" -"Choose what to use for GCode generation:\n" -"'Drills', 'Slots' or 'Both'.\n" -"When choosing 'Slots' or 'Both', slots will be\n" -"converted to a series of drills." -msgstr "" -"Choose what to use for GCode generation:\n" -"'Drills', 'Slots' or 'Both'.\n" -"When choosing 'Slots' or 'Both', slots will be\n" -"converted to a series of drills." - -#: flatcamGUI/ObjectUI.py:1053 -msgid "Create Drills GCode" -msgstr "Create Drills GCode" - -#: flatcamGUI/ObjectUI.py:1055 -msgid "Generate the CNC Job." -msgstr "Generate the CNC Job." - -#: flatcamGUI/ObjectUI.py:1066 flatcamGUI/PreferencesUI.py:3233 -msgid "Mill Holes" -msgstr "Mill Holes" - -#: flatcamGUI/ObjectUI.py:1068 -msgid "" -"Create Geometry for milling holes.\n" -"Select from the Tools Table above the hole dias to be\n" -"milled. Use the # column to make the selection." -msgstr "" -"Create Geometry for milling holes.\n" -"Select from the Tools Table above the hole dias to be\n" -"milled. Use the # column to make the selection." - -#: flatcamGUI/ObjectUI.py:1074 flatcamGUI/PreferencesUI.py:3239 -msgid "Drill Tool dia" -msgstr "Drill Tool dia" - -#: flatcamGUI/ObjectUI.py:1076 flatcamGUI/PreferencesUI.py:2027 -#: flatcamGUI/PreferencesUI.py:3241 -msgid "Diameter of the cutting tool." -msgstr "Diameter of the cutting tool." - -#: flatcamGUI/ObjectUI.py:1083 -msgid "Mill Drills Geo" -msgstr "Mill Drills Geo" - -#: flatcamGUI/ObjectUI.py:1085 -msgid "" -"Create the Geometry Object\n" -"for milling DRILLS toolpaths." -msgstr "" -"Create the Geometry Object\n" -"for milling DRILLS toolpaths." - -#: flatcamGUI/ObjectUI.py:1099 flatcamGUI/PreferencesUI.py:3250 -msgid "Slot Tool dia" -msgstr "Slot Tool dia" - -#: flatcamGUI/ObjectUI.py:1101 flatcamGUI/PreferencesUI.py:3252 -msgid "" -"Diameter of the cutting tool\n" -"when milling slots." -msgstr "" -"Diameter of the cutting tool\n" -"when milling slots." - -#: flatcamGUI/ObjectUI.py:1110 -msgid "Mill Slots Geo" -msgstr "Mill Slots Geo" - -#: flatcamGUI/ObjectUI.py:1112 -msgid "" -"Create the Geometry Object\n" -"for milling SLOTS toolpaths." -msgstr "" -"Create the Geometry Object\n" -"for milling SLOTS toolpaths." - -#: flatcamGUI/ObjectUI.py:1152 flatcamTools/ToolCutOut.py:317 -msgid "Geometry Object" -msgstr "Geometry Object" - -#: flatcamGUI/ObjectUI.py:1186 -msgid "" -"Tools in this Geometry object used for cutting.\n" -"The 'Offset' entry will set an offset for the cut.\n" -"'Offset' can be inside, outside, on path (none) and custom.\n" -"'Type' entry is only informative and it allow to know the \n" -"intent of using the current tool. \n" -"It can be Rough(ing), Finish(ing) or Iso(lation).\n" -"The 'Tool type'(TT) can be circular with 1 to 4 teeths(C1..C4),\n" -"ball(B), or V-Shaped(V). \n" -"When V-shaped is selected the 'Type' entry is automatically \n" -"set to Isolation, the CutZ parameter in the UI form is\n" -"grayed out and Cut Z is automatically calculated from the newly \n" -"showed UI form entries named V-Tip Dia and V-Tip Angle." -msgstr "" -"Tools in this Geometry object used for cutting.\n" -"The 'Offset' entry will set an offset for the cut.\n" -"'Offset' can be inside, outside, on path (none) and custom.\n" -"'Type' entry is only informative and it allow to know the \n" -"intent of using the current tool. \n" -"It can be Rough(ing), Finish(ing) or Iso(lation).\n" -"The 'Tool type'(TT) can be circular with 1 to 4 teeths(C1..C4),\n" -"ball(B), or V-Shaped(V). \n" -"When V-shaped is selected the 'Type' entry is automatically \n" -"set to Isolation, the CutZ parameter in the UI form is\n" -"grayed out and Cut Z is automatically calculated from the newly \n" -"showed UI form entries named V-Tip Dia and V-Tip Angle." - -#: flatcamGUI/ObjectUI.py:1203 flatcamGUI/ObjectUI.py:1903 -#: flatcamGUI/PreferencesUI.py:4405 -msgid "Plot Object" -msgstr "Plot Object" - -#: flatcamGUI/ObjectUI.py:1217 flatcamGUI/ObjectUI.py:1916 -#: flatcamGUI/ObjectUI.py:1926 flatcamGUI/PreferencesUI.py:7241 -#: flatcamTools/ToolCopperThieving.py:220 -msgid "Dia" -msgstr "Dia" - -#: flatcamGUI/ObjectUI.py:1217 flatcamGUI/ObjectUI.py:1916 -#: flatcamTools/ToolNonCopperClear.py:120 flatcamTools/ToolPaint.py:123 -msgid "TT" -msgstr "TT" - -#: flatcamGUI/ObjectUI.py:1224 -msgid "" -"This is the Tool Number.\n" -"When ToolChange is checked, on toolchange event this value\n" -"will be showed as a T1, T2 ... Tn" -msgstr "" -"This is the Tool Number.\n" -"When ToolChange is checked, on toolchange event this value\n" -"will be showed as a T1, T2 ... Tn" - -#: flatcamGUI/ObjectUI.py:1235 -msgid "" -"The value for the Offset can be:\n" -"- Path -> There is no offset, the tool cut will be done through the geometry " -"line.\n" -"- In(side) -> The tool cut will follow the geometry inside. It will create a " -"'pocket'.\n" -"- Out(side) -> The tool cut will follow the geometry line on the outside." -msgstr "" -"The value for the Offset can be:\n" -"- Path -> There is no offset, the tool cut will be done through the geometry " -"line.\n" -"- In(side) -> The tool cut will follow the geometry inside. It will create a " -"'pocket'.\n" -"- Out(side) -> The tool cut will follow the geometry line on the outside." - -#: flatcamGUI/ObjectUI.py:1242 -msgid "" -"The (Operation) Type has only informative value. Usually the UI form " -"values \n" -"are choose based on the operation type and this will serve as a reminder.\n" -"Can be 'Roughing', 'Finishing' or 'Isolation'.\n" -"For Roughing we may choose a lower Feedrate and multiDepth cut.\n" -"For Finishing we may choose a higher Feedrate, without multiDepth.\n" -"For Isolation we need a lower Feedrate as it use a milling bit with a fine " -"tip." -msgstr "" -"The (Operation) Type has only informative value. Usually the UI form " -"values \n" -"are choose based on the operation type and this will serve as a reminder.\n" -"Can be 'Roughing', 'Finishing' or 'Isolation'.\n" -"For Roughing we may choose a lower Feedrate and multiDepth cut.\n" -"For Finishing we may choose a higher Feedrate, without multiDepth.\n" -"For Isolation we need a lower Feedrate as it use a milling bit with a fine " -"tip." - -#: flatcamGUI/ObjectUI.py:1251 -msgid "" -"The Tool Type (TT) can be:\n" -"- Circular with 1 ... 4 teeth -> it is informative only. Being circular the " -"cut width in material\n" -"is exactly the tool diameter.\n" -"- Ball -> informative only and make reference to the Ball type endmill.\n" -"- V-Shape -> it will disable de Z-Cut parameter in the UI form and enable " -"two additional UI form\n" -"fields: V-Tip Dia and V-Tip Angle. Adjusting those two values will adjust " -"the Z-Cut parameter such\n" -"as the cut width into material will be equal with the value in the Tool " -"Diameter column of this table.\n" -"Choosing the V-Shape Tool Type automatically will select the Operation Type " -"as Isolation." -msgstr "" -"The Tool Type (TT) can be:\n" -"- Circular with 1 ... 4 teeth -> it is informative only. Being circular the " -"cut width in material\n" -"is exactly the tool diameter.\n" -"- Ball -> informative only and make reference to the Ball type endmill.\n" -"- V-Shape -> it will disable de Z-Cut parameter in the UI form and enable " -"two additional UI form\n" -"fields: V-Tip Dia and V-Tip Angle. Adjusting those two values will adjust " -"the Z-Cut parameter such\n" -"as the cut width into material will be equal with the value in the Tool " -"Diameter column of this table.\n" -"Choosing the V-Shape Tool Type automatically will select the Operation Type " -"as Isolation." - -#: flatcamGUI/ObjectUI.py:1263 -msgid "" -"Plot column. It is visible only for MultiGeo geometries, meaning geometries " -"that holds the geometry\n" -"data into the tools. For those geometries, deleting the tool will delete the " -"geometry data also,\n" -"so be WARNED. From the checkboxes on each row it can be enabled/disabled the " -"plot on canvas\n" -"for the corresponding tool." -msgstr "" -"Plot column. It is visible only for MultiGeo geometries, meaning geometries " -"that holds the geometry\n" -"data into the tools. For those geometries, deleting the tool will delete the " -"geometry data also,\n" -"so be WARNED. From the checkboxes on each row it can be enabled/disabled the " -"plot on canvas\n" -"for the corresponding tool." - -#: flatcamGUI/ObjectUI.py:1281 -msgid "" -"The value to offset the cut when \n" -"the Offset type selected is 'Offset'.\n" -"The value can be positive for 'outside'\n" -"cut and negative for 'inside' cut." -msgstr "" -"The value to offset the cut when \n" -"the Offset type selected is 'Offset'.\n" -"The value can be positive for 'outside'\n" -"cut and negative for 'inside' cut." - -#: flatcamGUI/ObjectUI.py:1306 -msgid "" -"Add a new tool to the Tool Table\n" -"with the specified diameter." -msgstr "" -"Add a new tool to the Tool Table\n" -"with the specified diameter." - -#: flatcamGUI/ObjectUI.py:1314 -msgid "Add Tool from DataBase" -msgstr "Add Tool from DataBase" - -#: flatcamGUI/ObjectUI.py:1316 -msgid "" -"Add a new tool to the Tool Table\n" -"from the Tool DataBase." -msgstr "" -"Add a new tool to the Tool Table\n" -"from the Tool DataBase." - -#: flatcamGUI/ObjectUI.py:1326 -msgid "" -"Copy a selection of tools in the Tool Table\n" -"by first selecting a row in the Tool Table." -msgstr "" -"Copy a selection of tools in the Tool Table\n" -"by first selecting a row in the Tool Table." - -#: flatcamGUI/ObjectUI.py:1332 -msgid "" -"Delete a selection of tools in the Tool Table\n" -"by first selecting a row in the Tool Table." -msgstr "" -"Delete a selection of tools in the Tool Table\n" -"by first selecting a row in the Tool Table." - -#: flatcamGUI/ObjectUI.py:1356 +#: flatcamGUI/ObjectUI.py:820 flatcamGUI/ObjectUI.py:1663 +#: flatcamTools/ToolNCC.py:334 flatcamTools/ToolPaint.py:317 msgid "" "The data used for creating GCode.\n" "Each tool store it's own set of such data." @@ -8067,13 +8034,72 @@ msgstr "" "The data used for creating GCode.\n" "Each tool store it's own set of such data." -#: flatcamGUI/ObjectUI.py:1426 flatcamGUI/PreferencesUI.py:3981 -#: flatcamGUI/PreferencesUI.py:5348 flatcamTools/ToolCutOut.py:153 +#: flatcamGUI/ObjectUI.py:846 flatcamGUI/PreferencesUI.py:3266 +msgid "" +"Operation type:\n" +"- Drilling -> will drill the drills/slots associated with this tool\n" +"- Milling -> will mill the drills/slots" +msgstr "" +"Operation type:\n" +"- Drilling -> will drill the drills/slots associated with this tool\n" +"- Milling -> will mill the drills/slots" + +#: flatcamGUI/ObjectUI.py:852 flatcamGUI/PreferencesUI.py:3272 +#| msgid "Drills" +msgid "Drilling" +msgstr "Drilling" + +#: flatcamGUI/ObjectUI.py:853 flatcamGUI/PreferencesUI.py:3273 +#| msgid "Milling Type" +msgid "Milling" +msgstr "Milling" + +#: flatcamGUI/ObjectUI.py:868 flatcamGUI/PreferencesUI.py:3282 +msgid "" +"Milling type:\n" +"- Drills -> will mill the drills associated with this tool\n" +"- Slots -> will mill the slots associated with this tool\n" +"- Both -> will mill both drills and mills or whatever is available" +msgstr "" +"Milling type:\n" +"- Drills -> will mill the drills associated with this tool\n" +"- Slots -> will mill the slots associated with this tool\n" +"- Both -> will mill both drills and mills or whatever is available" + +#: flatcamGUI/ObjectUI.py:877 flatcamGUI/PreferencesUI.py:3291 +#: flatcamGUI/PreferencesUI.py:6343 flatcamTools/ToolFilm.py:258 +msgid "Both" +msgstr "Both" + +#: flatcamGUI/ObjectUI.py:885 flatcamGUI/PreferencesUI.py:3298 +#| msgid "Tip Diameter" +msgid "Milling Diameter" +msgstr "Milling Diameter" + +#: flatcamGUI/ObjectUI.py:887 flatcamGUI/PreferencesUI.py:3300 +#| msgid "" +#| "Diameter of the cutting tool\n" +#| "when milling slots." +msgid "The diameter of the tool who will do the milling" +msgstr "The diameter of the tool who will do the milling" + +#: flatcamGUI/ObjectUI.py:901 flatcamGUI/PreferencesUI.py:3313 +msgid "" +"Drill depth (negative)\n" +"below the copper surface." +msgstr "" +"Drill depth (negative)\n" +"below the copper surface." + +#: flatcamGUI/ObjectUI.py:920 flatcamGUI/ObjectUI.py:1722 +#: flatcamGUI/PreferencesUI.py:3331 flatcamGUI/PreferencesUI.py:4261 +#: flatcamGUI/PreferencesUI.py:5687 flatcamTools/ToolCutOut.py:160 msgid "Multi-Depth" msgstr "Multi-Depth" -#: flatcamGUI/ObjectUI.py:1429 flatcamGUI/PreferencesUI.py:3984 -#: flatcamGUI/PreferencesUI.py:5351 flatcamTools/ToolCutOut.py:156 +#: flatcamGUI/ObjectUI.py:923 flatcamGUI/ObjectUI.py:1725 +#: flatcamGUI/PreferencesUI.py:3334 flatcamGUI/PreferencesUI.py:4264 +#: flatcamGUI/PreferencesUI.py:5690 flatcamTools/ToolCutOut.py:163 msgid "" "Use multiple passes to limit\n" "the cut depth in each pass. Will\n" @@ -8085,33 +8111,22 @@ msgstr "" "cut multiple times until Cut Z is\n" "reached." -#: flatcamGUI/ObjectUI.py:1443 flatcamGUI/PreferencesUI.py:5363 -#: flatcamTools/ToolCutOut.py:170 +#: flatcamGUI/ObjectUI.py:936 flatcamGUI/ObjectUI.py:1739 +#: flatcamGUI/PreferencesUI.py:3346 flatcamGUI/PreferencesUI.py:5702 +#: flatcamTools/ToolCutOut.py:177 msgid "Depth of each pass (positive)." msgstr "Depth of each pass (positive)." -#: flatcamGUI/ObjectUI.py:1454 flatcamGUI/PreferencesUI.py:4016 +#: flatcamGUI/ObjectUI.py:947 flatcamGUI/PreferencesUI.py:3354 msgid "" -"Height of the tool when\n" -"moving without cutting." +"Tool height when travelling\n" +"across the XY plane." msgstr "" -"Height of the tool when\n" -"moving without cutting." +"Tool height when travelling\n" +"across the XY plane." -#: flatcamGUI/ObjectUI.py:1481 flatcamGUI/PreferencesUI.py:4037 -msgid "" -"Include tool-change sequence\n" -"in the Machine Code (Pause for tool change)." -msgstr "" -"Include tool-change sequence\n" -"in the Machine Code (Pause for tool change)." - -#: flatcamGUI/ObjectUI.py:1531 flatcamGUI/PreferencesUI.py:4086 -#: flatcamGUI/PreferencesUI.py:6553 flatcamTools/ToolSolderPaste.py:252 -msgid "Feedrate X-Y" -msgstr "Feedrate X-Y" - -#: flatcamGUI/ObjectUI.py:1533 flatcamGUI/PreferencesUI.py:4088 +#: flatcamGUI/ObjectUI.py:968 flatcamGUI/ObjectUI.py:1769 +#: flatcamGUI/PreferencesUI.py:4380 msgid "" "Cutting speed in the XY\n" "plane in units per minute" @@ -8119,36 +8134,45 @@ msgstr "" "Cutting speed in the XY\n" "plane in units per minute" -#: flatcamGUI/ObjectUI.py:1547 flatcamGUI/PreferencesUI.py:4103 +#: flatcamGUI/ObjectUI.py:983 flatcamGUI/PreferencesUI.py:3427 msgid "" -"Cutting speed in the XY\n" -"plane in units per minute.\n" -"It is called also Plunge." +"Tool speed while drilling\n" +"(in units per minute).\n" +"So called 'Plunge' feedrate.\n" +"This is for linear move G01." msgstr "" -"Cutting speed in the XY\n" -"plane in units per minute.\n" -"It is called also Plunge." +"Tool speed while drilling\n" +"(in units per minute).\n" +"So called 'Plunge' feedrate.\n" +"This is for linear move G01." -#: flatcamGUI/ObjectUI.py:1562 flatcamGUI/PreferencesUI.py:4212 +#: flatcamGUI/ObjectUI.py:998 flatcamGUI/ObjectUI.py:1796 +#: flatcamGUI/PreferencesUI.py:3597 flatcamGUI/PreferencesUI.py:4503 +msgid "Feedrate Rapids" +msgstr "Feedrate Rapids" + +#: flatcamGUI/ObjectUI.py:1000 flatcamGUI/PreferencesUI.py:3599 msgid "" -"Cutting speed in the XY plane\n" +"Tool speed while drilling\n" "(in units per minute).\n" "This is for the rapid move G00.\n" "It is useful only for Marlin,\n" "ignore for any other cases." msgstr "" -"Cutting speed in the XY plane\n" +"Tool speed while drilling\n" "(in units per minute).\n" "This is for the rapid move G00.\n" "It is useful only for Marlin,\n" "ignore for any other cases." -#: flatcamGUI/ObjectUI.py:1580 flatcamGUI/PreferencesUI.py:4228 +#: flatcamGUI/ObjectUI.py:1020 flatcamGUI/ObjectUI.py:1816 +#: flatcamGUI/PreferencesUI.py:4521 msgid "Re-cut" msgstr "Re-cut" -#: flatcamGUI/ObjectUI.py:1582 flatcamGUI/ObjectUI.py:1594 -#: flatcamGUI/PreferencesUI.py:4230 flatcamGUI/PreferencesUI.py:4242 +#: flatcamGUI/ObjectUI.py:1022 flatcamGUI/ObjectUI.py:1035 +#: flatcamGUI/ObjectUI.py:1818 flatcamGUI/ObjectUI.py:1830 +#: flatcamGUI/PreferencesUI.py:4523 flatcamGUI/PreferencesUI.py:4535 msgid "" "In order to remove possible\n" "copper leftovers where first cut\n" @@ -8160,29 +8184,49 @@ msgstr "" "meet with last cut, we generate an\n" "extended cut over the first cut section." -#: flatcamGUI/ObjectUI.py:1606 flatcamGUI/PreferencesUI.py:4120 +#: flatcamGUI/ObjectUI.py:1050 flatcamGUI/PreferencesUI.py:3442 msgid "" -"Speed of the spindle in RPM (optional).\n" -"If LASER preprocessor is used,\n" -"this value is the power of laser." +"Speed of the spindle\n" +"in RPM (optional)" msgstr "" -"Speed of the spindle in RPM (optional).\n" -"If LASER preprocessor is used,\n" -"this value is the power of laser." +"Speed of the spindle\n" +"in RPM (optional)" -#: flatcamGUI/ObjectUI.py:1642 flatcamGUI/PreferencesUI.py:4157 +#: flatcamGUI/ObjectUI.py:1065 flatcamGUI/ObjectUI.py:1858 +#: flatcamGUI/PreferencesUI.py:3456 flatcamGUI/PreferencesUI.py:4427 msgid "" -"The Preprocessor file that dictates\n" -"the Machine Code (like GCode, RML, HPGL) output." +"Pause to allow the spindle to reach its\n" +"speed before cutting." msgstr "" -"The Preprocessor file that dictates\n" -"the Machine Code (like GCode, RML, HPGL) output." +"Pause to allow the spindle to reach its\n" +"speed before cutting." -#: flatcamGUI/ObjectUI.py:1689 +#: flatcamGUI/ObjectUI.py:1076 flatcamGUI/ObjectUI.py:1868 +#: flatcamGUI/PreferencesUI.py:3464 flatcamGUI/PreferencesUI.py:4432 +msgid "Number of time units for spindle to dwell." +msgstr "Number of time units for spindle to dwell." + +#: flatcamGUI/ObjectUI.py:1086 flatcamGUI/PreferencesUI.py:3563 +msgid "Offset Z" +msgstr "Offset Z" + +#: flatcamGUI/ObjectUI.py:1088 flatcamGUI/PreferencesUI.py:3565 +msgid "" +"Some drill bits (the larger ones) need to drill deeper\n" +"to create the desired exit hole diameter due of the tip shape.\n" +"The value here can compensate the Cut Z parameter." +msgstr "" +"Some drill bits (the larger ones) need to drill deeper\n" +"to create the desired exit hole diameter due of the tip shape.\n" +"The value here can compensate the Cut Z parameter." + +#: flatcamGUI/ObjectUI.py:1148 flatcamGUI/ObjectUI.py:1922 +#: flatcamTools/ToolNCC.py:492 flatcamTools/ToolPaint.py:423 msgid "Apply parameters to all tools" msgstr "Apply parameters to all tools" -#: flatcamGUI/ObjectUI.py:1691 +#: flatcamGUI/ObjectUI.py:1150 flatcamGUI/ObjectUI.py:1924 +#: flatcamTools/ToolNCC.py:494 flatcamTools/ToolPaint.py:425 msgid "" "The parameters in the current form will be applied\n" "on all the tools from the Tool Table." @@ -8190,29 +8234,477 @@ msgstr "" "The parameters in the current form will be applied\n" "on all the tools from the Tool Table." -#: flatcamGUI/ObjectUI.py:1700 +#: flatcamGUI/ObjectUI.py:1161 flatcamGUI/ObjectUI.py:1935 +#: flatcamTools/ToolNCC.py:505 flatcamTools/ToolPaint.py:436 +#| msgid "GCode Parameters" +msgid "Common Parameters" +msgstr "Common Parameters" + +#: flatcamGUI/ObjectUI.py:1163 flatcamGUI/ObjectUI.py:1937 +#: flatcamTools/ToolNCC.py:507 flatcamTools/ToolPaint.py:438 +#| msgid "Parameters used for this tool." +msgid "Parameters that are common for all tools." +msgstr "Parameters that are common for all tools." + +#: flatcamGUI/ObjectUI.py:1168 flatcamGUI/ObjectUI.py:1942 +msgid "Tool change Z" +msgstr "Tool change Z" + +#: flatcamGUI/ObjectUI.py:1170 flatcamGUI/PreferencesUI.py:3372 msgid "" -"Add at least one tool in the tool-table.\n" -"Click the header to select all, or Ctrl + LMB\n" +"Include tool-change sequence\n" +"in G-Code (Pause for tool change)." +msgstr "" +"Include tool-change sequence\n" +"in G-Code (Pause for tool change)." + +#: flatcamGUI/ObjectUI.py:1177 flatcamGUI/ObjectUI.py:1953 +#: flatcamGUI/PreferencesUI.py:3380 flatcamGUI/PreferencesUI.py:4327 +msgid "" +"Z-axis position (height) for\n" +"tool change." +msgstr "" +"Z-axis position (height) for\n" +"tool change." + +#: flatcamGUI/ObjectUI.py:1194 flatcamGUI/PreferencesUI.py:3588 +msgid "" +"Height of the tool just after start.\n" +"Delete the value if you don't need this feature." +msgstr "" +"Height of the tool just after start.\n" +"Delete the value if you don't need this feature." + +#: flatcamGUI/ObjectUI.py:1203 flatcamGUI/ObjectUI.py:1981 +#: flatcamGUI/PreferencesUI.py:3396 flatcamGUI/PreferencesUI.py:4346 +msgid "End move Z" +msgstr "End move Z" + +#: flatcamGUI/ObjectUI.py:1205 flatcamGUI/ObjectUI.py:1983 +#: flatcamGUI/PreferencesUI.py:3398 flatcamGUI/PreferencesUI.py:4348 +msgid "" +"Height of the tool after\n" +"the last move at the end of the job." +msgstr "" +"Height of the tool after\n" +"the last move at the end of the job." + +#: flatcamGUI/ObjectUI.py:1222 flatcamGUI/ObjectUI.py:2000 +#: flatcamGUI/PreferencesUI.py:3413 flatcamGUI/PreferencesUI.py:4366 +#| msgid "End move Z" +msgid "End move X,Y" +msgstr "End move X,Y" + +#: flatcamGUI/ObjectUI.py:1224 flatcamGUI/ObjectUI.py:2002 +#: flatcamGUI/PreferencesUI.py:3415 flatcamGUI/PreferencesUI.py:4368 +msgid "" +"End move X,Y position. In format (x,y).\n" +"If no value is entered then there is no move\n" +"on X,Y plane at the end of the job." +msgstr "" +"End move X,Y position. In format (x,y).\n" +"If no value is entered then there is no move\n" +"on X,Y plane at the end of the job." + +#: flatcamGUI/ObjectUI.py:1234 flatcamGUI/ObjectUI.py:1876 +#: flatcamGUI/PreferencesUI.py:3613 flatcamGUI/PreferencesUI.py:4544 +msgid "Probe Z depth" +msgstr "Probe Z depth" + +#: flatcamGUI/ObjectUI.py:1236 flatcamGUI/ObjectUI.py:1878 +#: flatcamGUI/PreferencesUI.py:3615 flatcamGUI/PreferencesUI.py:4546 +msgid "" +"The maximum depth that the probe is allowed\n" +"to probe. Negative value, in current units." +msgstr "" +"The maximum depth that the probe is allowed\n" +"to probe. Negative value, in current units." + +#: flatcamGUI/ObjectUI.py:1252 flatcamGUI/ObjectUI.py:1893 +#: flatcamGUI/PreferencesUI.py:3626 flatcamGUI/PreferencesUI.py:4559 +msgid "Feedrate Probe" +msgstr "Feedrate Probe" + +#: flatcamGUI/ObjectUI.py:1254 flatcamGUI/ObjectUI.py:1895 +#: flatcamGUI/PreferencesUI.py:3628 flatcamGUI/PreferencesUI.py:4561 +msgid "The feedrate used while the probe is probing." +msgstr "The feedrate used while the probe is probing." + +#: flatcamGUI/ObjectUI.py:1261 +msgid "e_fr_probe" +msgstr "e_fr_probe" + +#: flatcamGUI/ObjectUI.py:1270 +#| msgid "Preprocessor" +msgid "Preprocessor E" +msgstr "Preprocessor E" + +#: flatcamGUI/ObjectUI.py:1272 +#| msgid "" +#| "The preprocessor JSON file that dictates\n" +#| "Gcode output." +msgid "" +"The preprocessor JSON file that dictates\n" +"Gcode output for Excellon Objects." +msgstr "" +"The preprocessor JSON file that dictates\n" +"Gcode output for Excellon Objects." + +#: flatcamGUI/ObjectUI.py:1282 +#| msgid "Preprocessor" +msgid "Preprocessor G" +msgstr "Preprocessor G" + +#: flatcamGUI/ObjectUI.py:1284 +#| msgid "" +#| "The preprocessor JSON file that dictates\n" +#| "Gcode output." +msgid "" +"The preprocessor JSON file that dictates\n" +"Gcode output for Geometry (Milling) Objects." +msgstr "" +"The preprocessor JSON file that dictates\n" +"Gcode output for Geometry (Milling) Objects." + +#: flatcamGUI/ObjectUI.py:1308 flatcamGUI/ObjectUI.py:2026 +#| msgid "" +#| "Add at least one tool in the tool-table.\n" +#| "Click the header to select all, or Ctrl + LMB\n" +#| "for custom selection of tools." +msgid "" +"Add / Select at least one tool in the tool-table.\n" +"Click the # header to select all, or Ctrl + LMB\n" "for custom selection of tools." msgstr "" -"Add at least one tool in the tool-table.\n" -"Click the header to select all, or Ctrl + LMB\n" +"Add / Select at least one tool in the tool-table.\n" +"Click the # header to select all, or Ctrl + LMB\n" "for custom selection of tools." -#: flatcamGUI/ObjectUI.py:1707 +#: flatcamGUI/ObjectUI.py:1316 flatcamGUI/ObjectUI.py:2033 msgid "Generate CNCJob object" msgstr "Generate CNCJob object" -#: flatcamGUI/ObjectUI.py:1709 +#: flatcamGUI/ObjectUI.py:1318 +msgid "" +"Generate the CNC Job.\n" +"If milling then an additional Geometry object will be created" +msgstr "" +"Generate the CNC Job.\n" +"If milling then an additional Geometry object will be created" + +#: flatcamGUI/ObjectUI.py:1335 +#| msgid "Solid Geometry" +msgid "Milling Geometry" +msgstr "Milling Geometry" + +#: flatcamGUI/ObjectUI.py:1337 +msgid "" +"Create Geometry for milling holes.\n" +"Select from the Tools Table above the hole dias to be\n" +"milled. Use the # column to make the selection." +msgstr "" +"Create Geometry for milling holes.\n" +"Select from the Tools Table above the hole dias to be\n" +"milled. Use the # column to make the selection." + +#: flatcamGUI/ObjectUI.py:1345 flatcamGUI/PreferencesUI.py:2207 +#: flatcamGUI/PreferencesUI.py:3514 +msgid "Diameter of the cutting tool." +msgstr "Diameter of the cutting tool." + +#: flatcamGUI/ObjectUI.py:1355 +#| msgid "Mill Drills Geo" +msgid "Mill Drills" +msgstr "Mill Drills" + +#: flatcamGUI/ObjectUI.py:1357 +msgid "" +"Create the Geometry Object\n" +"for milling DRILLS toolpaths." +msgstr "" +"Create the Geometry Object\n" +"for milling DRILLS toolpaths." + +#: flatcamGUI/ObjectUI.py:1375 +#| msgid "Mill Slots Geo" +msgid "Mill Slots" +msgstr "Mill Slots" + +#: flatcamGUI/ObjectUI.py:1377 +msgid "" +"Create the Geometry Object\n" +"for milling SLOTS toolpaths." +msgstr "" +"Create the Geometry Object\n" +"for milling SLOTS toolpaths." + +#: flatcamGUI/ObjectUI.py:1419 flatcamTools/ToolCutOut.py:327 +msgid "Geometry Object" +msgstr "Geometry Object" + +#: flatcamGUI/ObjectUI.py:1465 +msgid "" +"Tools in this Geometry object used for cutting.\n" +"The 'Offset' entry will set an offset for the cut.\n" +"'Offset' can be inside, outside, on path (none) and custom.\n" +"'Type' entry is only informative and it allow to know the \n" +"intent of using the current tool. \n" +"It can be Rough(ing), Finish(ing) or Iso(lation).\n" +"The 'Tool type'(TT) can be circular with 1 to 4 teeths(C1..C4),\n" +"ball(B), or V-Shaped(V). \n" +"When V-shaped is selected the 'Type' entry is automatically \n" +"set to Isolation, the CutZ parameter in the UI form is\n" +"grayed out and Cut Z is automatically calculated from the newly \n" +"showed UI form entries named V-Tip Dia and V-Tip Angle." +msgstr "" +"Tools in this Geometry object used for cutting.\n" +"The 'Offset' entry will set an offset for the cut.\n" +"'Offset' can be inside, outside, on path (none) and custom.\n" +"'Type' entry is only informative and it allow to know the \n" +"intent of using the current tool. \n" +"It can be Rough(ing), Finish(ing) or Iso(lation).\n" +"The 'Tool type'(TT) can be circular with 1 to 4 teeths(C1..C4),\n" +"ball(B), or V-Shaped(V). \n" +"When V-shaped is selected the 'Type' entry is automatically \n" +"set to Isolation, the CutZ parameter in the UI form is\n" +"grayed out and Cut Z is automatically calculated from the newly \n" +"showed UI form entries named V-Tip Dia and V-Tip Angle." + +#: flatcamGUI/ObjectUI.py:1482 flatcamGUI/ObjectUI.py:2231 +#: flatcamGUI/PreferencesUI.py:4698 +msgid "Plot Object" +msgstr "Plot Object" + +#: flatcamGUI/ObjectUI.py:1495 flatcamGUI/ObjectUI.py:2244 +#: flatcamGUI/ObjectUI.py:2254 flatcamGUI/PreferencesUI.py:7747 +#: flatcamTools/ToolCopperThieving.py:222 +msgid "Dia" +msgstr "Dia" + +#: flatcamGUI/ObjectUI.py:1495 flatcamGUI/ObjectUI.py:2244 +#: flatcamTools/ToolNCC.py:132 flatcamTools/ToolPaint.py:128 +msgid "TT" +msgstr "TT" + +#: flatcamGUI/ObjectUI.py:1502 +msgid "" +"This is the Tool Number.\n" +"When ToolChange is checked, on toolchange event this value\n" +"will be showed as a T1, T2 ... Tn" +msgstr "" +"This is the Tool Number.\n" +"When ToolChange is checked, on toolchange event this value\n" +"will be showed as a T1, T2 ... Tn" + +#: flatcamGUI/ObjectUI.py:1513 +msgid "" +"The value for the Offset can be:\n" +"- Path -> There is no offset, the tool cut will be done through the geometry " +"line.\n" +"- In(side) -> The tool cut will follow the geometry inside. It will create a " +"'pocket'.\n" +"- Out(side) -> The tool cut will follow the geometry line on the outside." +msgstr "" +"The value for the Offset can be:\n" +"- Path -> There is no offset, the tool cut will be done through the geometry " +"line.\n" +"- In(side) -> The tool cut will follow the geometry inside. It will create a " +"'pocket'.\n" +"- Out(side) -> The tool cut will follow the geometry line on the outside." + +#: flatcamGUI/ObjectUI.py:1520 +msgid "" +"The (Operation) Type has only informative value. Usually the UI form " +"values \n" +"are choose based on the operation type and this will serve as a reminder.\n" +"Can be 'Roughing', 'Finishing' or 'Isolation'.\n" +"For Roughing we may choose a lower Feedrate and multiDepth cut.\n" +"For Finishing we may choose a higher Feedrate, without multiDepth.\n" +"For Isolation we need a lower Feedrate as it use a milling bit with a fine " +"tip." +msgstr "" +"The (Operation) Type has only informative value. Usually the UI form " +"values \n" +"are choose based on the operation type and this will serve as a reminder.\n" +"Can be 'Roughing', 'Finishing' or 'Isolation'.\n" +"For Roughing we may choose a lower Feedrate and multiDepth cut.\n" +"For Finishing we may choose a higher Feedrate, without multiDepth.\n" +"For Isolation we need a lower Feedrate as it use a milling bit with a fine " +"tip." + +#: flatcamGUI/ObjectUI.py:1529 +msgid "" +"The Tool Type (TT) can be:\n" +"- Circular with 1 ... 4 teeth -> it is informative only. Being circular the " +"cut width in material\n" +"is exactly the tool diameter.\n" +"- Ball -> informative only and make reference to the Ball type endmill.\n" +"- V-Shape -> it will disable de Z-Cut parameter in the UI form and enable " +"two additional UI form\n" +"fields: V-Tip Dia and V-Tip Angle. Adjusting those two values will adjust " +"the Z-Cut parameter such\n" +"as the cut width into material will be equal with the value in the Tool " +"Diameter column of this table.\n" +"Choosing the V-Shape Tool Type automatically will select the Operation Type " +"as Isolation." +msgstr "" +"The Tool Type (TT) can be:\n" +"- Circular with 1 ... 4 teeth -> it is informative only. Being circular the " +"cut width in material\n" +"is exactly the tool diameter.\n" +"- Ball -> informative only and make reference to the Ball type endmill.\n" +"- V-Shape -> it will disable de Z-Cut parameter in the UI form and enable " +"two additional UI form\n" +"fields: V-Tip Dia and V-Tip Angle. Adjusting those two values will adjust " +"the Z-Cut parameter such\n" +"as the cut width into material will be equal with the value in the Tool " +"Diameter column of this table.\n" +"Choosing the V-Shape Tool Type automatically will select the Operation Type " +"as Isolation." + +#: flatcamGUI/ObjectUI.py:1541 +msgid "" +"Plot column. It is visible only for MultiGeo geometries, meaning geometries " +"that holds the geometry\n" +"data into the tools. For those geometries, deleting the tool will delete the " +"geometry data also,\n" +"so be WARNED. From the checkboxes on each row it can be enabled/disabled the " +"plot on canvas\n" +"for the corresponding tool." +msgstr "" +"Plot column. It is visible only for MultiGeo geometries, meaning geometries " +"that holds the geometry\n" +"data into the tools. For those geometries, deleting the tool will delete the " +"geometry data also,\n" +"so be WARNED. From the checkboxes on each row it can be enabled/disabled the " +"plot on canvas\n" +"for the corresponding tool." + +#: flatcamGUI/ObjectUI.py:1559 +msgid "" +"The value to offset the cut when \n" +"the Offset type selected is 'Offset'.\n" +"The value can be positive for 'outside'\n" +"cut and negative for 'inside' cut." +msgstr "" +"The value to offset the cut when \n" +"the Offset type selected is 'Offset'.\n" +"The value can be positive for 'outside'\n" +"cut and negative for 'inside' cut." + +#: flatcamGUI/ObjectUI.py:1578 flatcamTools/ToolNCC.py:209 +#: flatcamTools/ToolNCC.py:921 flatcamTools/ToolPaint.py:192 +#: flatcamTools/ToolPaint.py:846 flatcamTools/ToolSolderPaste.py:559 +msgid "New Tool" +msgstr "New Tool" + +#: flatcamGUI/ObjectUI.py:1595 +msgid "" +"Add a new tool to the Tool Table\n" +"with the specified diameter." +msgstr "" +"Add a new tool to the Tool Table\n" +"with the specified diameter." + +#: flatcamGUI/ObjectUI.py:1600 flatcamTools/ToolNCC.py:300 +#: flatcamTools/ToolNCC.py:634 flatcamTools/ToolPaint.py:283 +#: flatcamTools/ToolPaint.py:676 +#| msgid "Add from Tool DB" +msgid "Add from DB" +msgstr "Add from DB" + +#: flatcamGUI/ObjectUI.py:1602 flatcamTools/ToolNCC.py:302 +#: flatcamTools/ToolPaint.py:285 +msgid "" +"Add a new tool to the Tool Table\n" +"from the Tool DataBase." +msgstr "" +"Add a new tool to the Tool Table\n" +"from the Tool DataBase." + +#: flatcamGUI/ObjectUI.py:1617 +msgid "" +"Copy a selection of tools in the Tool Table\n" +"by first selecting a row in the Tool Table." +msgstr "" +"Copy a selection of tools in the Tool Table\n" +"by first selecting a row in the Tool Table." + +#: flatcamGUI/ObjectUI.py:1623 +msgid "" +"Delete a selection of tools in the Tool Table\n" +"by first selecting a row in the Tool Table." +msgstr "" +"Delete a selection of tools in the Tool Table\n" +"by first selecting a row in the Tool Table." + +#: flatcamGUI/ObjectUI.py:1750 flatcamGUI/PreferencesUI.py:4296 +msgid "" +"Height of the tool when\n" +"moving without cutting." +msgstr "" +"Height of the tool when\n" +"moving without cutting." + +#: flatcamGUI/ObjectUI.py:1783 flatcamGUI/PreferencesUI.py:4395 +msgid "" +"Cutting speed in the XY\n" +"plane in units per minute.\n" +"It is called also Plunge." +msgstr "" +"Cutting speed in the XY\n" +"plane in units per minute.\n" +"It is called also Plunge." + +#: flatcamGUI/ObjectUI.py:1798 flatcamGUI/PreferencesUI.py:4505 +msgid "" +"Cutting speed in the XY plane\n" +"(in units per minute).\n" +"This is for the rapid move G00.\n" +"It is useful only for Marlin,\n" +"ignore for any other cases." +msgstr "" +"Cutting speed in the XY plane\n" +"(in units per minute).\n" +"This is for the rapid move G00.\n" +"It is useful only for Marlin,\n" +"ignore for any other cases." + +#: flatcamGUI/ObjectUI.py:1842 flatcamGUI/PreferencesUI.py:4412 +msgid "" +"Speed of the spindle in RPM (optional).\n" +"If LASER preprocessor is used,\n" +"this value is the power of laser." +msgstr "" +"Speed of the spindle in RPM (optional).\n" +"If LASER preprocessor is used,\n" +"this value is the power of laser." + +#: flatcamGUI/ObjectUI.py:1945 flatcamGUI/PreferencesUI.py:4317 +msgid "" +"Include tool-change sequence\n" +"in the Machine Code (Pause for tool change)." +msgstr "" +"Include tool-change sequence\n" +"in the Machine Code (Pause for tool change)." + +#: flatcamGUI/ObjectUI.py:2014 flatcamGUI/PreferencesUI.py:4449 +msgid "" +"The Preprocessor file that dictates\n" +"the Machine Code (like GCode, RML, HPGL) output." +msgstr "" +"The Preprocessor file that dictates\n" +"the Machine Code (like GCode, RML, HPGL) output." + +#: flatcamGUI/ObjectUI.py:2035 msgid "Generate the CNC Job object." msgstr "Generate the CNC Job object." -#: flatcamGUI/ObjectUI.py:1726 +#: flatcamGUI/ObjectUI.py:2052 msgid "Launch Paint Tool in Tools Tab." msgstr "Launch Paint Tool in Tools Tab." -#: flatcamGUI/ObjectUI.py:1734 flatcamGUI/PreferencesUI.py:5524 +#: flatcamGUI/ObjectUI.py:2060 flatcamGUI/PreferencesUI.py:5874 msgid "" "Creates tool paths to cover the\n" "whole area of a polygon (remove\n" @@ -8224,15 +8716,15 @@ msgstr "" "all copper). You will be asked\n" "to click on the desired polygon." -#: flatcamGUI/ObjectUI.py:1786 +#: flatcamGUI/ObjectUI.py:2115 msgid "CNC Job Object" msgstr "CNC Job Object" -#: flatcamGUI/ObjectUI.py:1798 flatcamGUI/PreferencesUI.py:4410 +#: flatcamGUI/ObjectUI.py:2126 flatcamGUI/PreferencesUI.py:4703 msgid "Plot kind" msgstr "Plot kind" -#: flatcamGUI/ObjectUI.py:1801 flatcamGUI/PreferencesUI.py:4412 +#: flatcamGUI/ObjectUI.py:2129 flatcamGUI/PreferencesUI.py:4705 msgid "" "This selects the kind of geometries on the canvas to plot.\n" "Those can be either of type 'Travel' which means the moves\n" @@ -8244,15 +8736,15 @@ msgstr "" "above the work piece or it can be of type 'Cut',\n" "which means the moves that cut into the material." -#: flatcamGUI/ObjectUI.py:1810 flatcamGUI/PreferencesUI.py:4420 +#: flatcamGUI/ObjectUI.py:2138 flatcamGUI/PreferencesUI.py:4713 msgid "Travel" msgstr "Travel" -#: flatcamGUI/ObjectUI.py:1814 flatcamGUI/PreferencesUI.py:4429 +#: flatcamGUI/ObjectUI.py:2142 flatcamGUI/PreferencesUI.py:4722 msgid "Display Annotation" msgstr "Display Annotation" -#: flatcamGUI/ObjectUI.py:1816 flatcamGUI/PreferencesUI.py:4431 +#: flatcamGUI/ObjectUI.py:2144 flatcamGUI/PreferencesUI.py:4724 msgid "" "This selects if to display text annotation on the plot.\n" "When checked it will display numbers in order for each end\n" @@ -8262,11 +8754,11 @@ msgstr "" "When checked it will display numbers in order for each end\n" "of a travel line." -#: flatcamGUI/ObjectUI.py:1831 +#: flatcamGUI/ObjectUI.py:2159 msgid "Travelled dist." msgstr "Travelled dist." -#: flatcamGUI/ObjectUI.py:1833 flatcamGUI/ObjectUI.py:1838 +#: flatcamGUI/ObjectUI.py:2161 flatcamGUI/ObjectUI.py:2166 msgid "" "This is the total travelled distance on X-Y plane.\n" "In current units." @@ -8274,11 +8766,11 @@ msgstr "" "This is the total travelled distance on X-Y plane.\n" "In current units." -#: flatcamGUI/ObjectUI.py:1843 +#: flatcamGUI/ObjectUI.py:2171 msgid "Estimated time" msgstr "Estimated time" -#: flatcamGUI/ObjectUI.py:1845 flatcamGUI/ObjectUI.py:1850 +#: flatcamGUI/ObjectUI.py:2173 flatcamGUI/ObjectUI.py:2178 msgid "" "This is the estimated time to do the routing/drilling,\n" "without the time spent in ToolChange events." @@ -8286,11 +8778,11 @@ msgstr "" "This is the estimated time to do the routing/drilling,\n" "without the time spent in ToolChange events." -#: flatcamGUI/ObjectUI.py:1885 +#: flatcamGUI/ObjectUI.py:2213 msgid "CNC Tools Table" msgstr "CNC Tools Table" -#: flatcamGUI/ObjectUI.py:1888 +#: flatcamGUI/ObjectUI.py:2216 msgid "" "Tools in this CNCJob object used for cutting.\n" "The tool diameter is used for plotting on canvas.\n" @@ -8312,24 +8804,24 @@ msgstr "" "The 'Tool type'(TT) can be circular with 1 to 4 teeths(C1..C4),\n" "ball(B), or V-Shaped(V)." -#: flatcamGUI/ObjectUI.py:1916 flatcamGUI/ObjectUI.py:1927 +#: flatcamGUI/ObjectUI.py:2244 flatcamGUI/ObjectUI.py:2255 msgid "P" msgstr "P" -#: flatcamGUI/ObjectUI.py:1937 +#: flatcamGUI/ObjectUI.py:2265 msgid "Update Plot" msgstr "Update Plot" -#: flatcamGUI/ObjectUI.py:1939 +#: flatcamGUI/ObjectUI.py:2267 msgid "Update the plot." msgstr "Update the plot." -#: flatcamGUI/ObjectUI.py:1946 flatcamGUI/PreferencesUI.py:4827 +#: flatcamGUI/ObjectUI.py:2274 flatcamGUI/PreferencesUI.py:5120 msgid "Export CNC Code" msgstr "Export CNC Code" -#: flatcamGUI/ObjectUI.py:1948 flatcamGUI/PreferencesUI.py:4768 -#: flatcamGUI/PreferencesUI.py:4829 +#: flatcamGUI/ObjectUI.py:2276 flatcamGUI/PreferencesUI.py:5061 +#: flatcamGUI/PreferencesUI.py:5122 msgid "" "Export and save G-Code to\n" "make this object to a file." @@ -8337,12 +8829,12 @@ msgstr "" "Export and save G-Code to\n" "make this object to a file." -#: flatcamGUI/ObjectUI.py:1954 +#: flatcamGUI/ObjectUI.py:2282 msgid "Prepend to CNC Code" msgstr "Prepend to CNC Code" -#: flatcamGUI/ObjectUI.py:1956 flatcamGUI/ObjectUI.py:1963 -#: flatcamGUI/PreferencesUI.py:4784 +#: flatcamGUI/ObjectUI.py:2284 flatcamGUI/ObjectUI.py:2291 +#: flatcamGUI/PreferencesUI.py:5077 msgid "" "Type here any G-Code commands you would\n" "like to add at the beginning of the G-Code file." @@ -8350,12 +8842,12 @@ msgstr "" "Type here any G-Code commands you would\n" "like to add at the beginning of the G-Code file." -#: flatcamGUI/ObjectUI.py:1969 +#: flatcamGUI/ObjectUI.py:2297 msgid "Append to CNC Code" msgstr "Append to CNC Code" -#: flatcamGUI/ObjectUI.py:1971 flatcamGUI/ObjectUI.py:1979 -#: flatcamGUI/PreferencesUI.py:4800 +#: flatcamGUI/ObjectUI.py:2299 flatcamGUI/ObjectUI.py:2307 +#: flatcamGUI/PreferencesUI.py:5093 msgid "" "Type here any G-Code commands you would\n" "like to append to the generated file.\n" @@ -8365,11 +8857,11 @@ msgstr "" "like to append to the generated file.\n" "I.e.: M2 (End of program)" -#: flatcamGUI/ObjectUI.py:1993 flatcamGUI/PreferencesUI.py:4835 +#: flatcamGUI/ObjectUI.py:2321 flatcamGUI/PreferencesUI.py:5128 msgid "Toolchange G-Code" msgstr "Toolchange G-Code" -#: flatcamGUI/ObjectUI.py:1996 flatcamGUI/PreferencesUI.py:4838 +#: flatcamGUI/ObjectUI.py:2324 flatcamGUI/PreferencesUI.py:5131 msgid "" "Type here any G-Code commands you would\n" "like to be executed when Toolchange event is encountered.\n" @@ -8391,7 +8883,7 @@ msgstr "" "that has 'toolchange_custom' in it's name and this is built\n" "having as template the 'Toolchange Custom' posprocessor file." -#: flatcamGUI/ObjectUI.py:2011 +#: flatcamGUI/ObjectUI.py:2339 msgid "" "Type here any G-Code commands you would\n" "like to be executed when Toolchange event is encountered.\n" @@ -8409,11 +8901,11 @@ msgstr "" "WARNING: it can be used only with a preprocessor file\n" "that has 'toolchange_custom' in it's name." -#: flatcamGUI/ObjectUI.py:2026 flatcamGUI/PreferencesUI.py:4877 +#: flatcamGUI/ObjectUI.py:2354 flatcamGUI/PreferencesUI.py:5170 msgid "Use Toolchange Macro" msgstr "Use Toolchange Macro" -#: flatcamGUI/ObjectUI.py:2028 flatcamGUI/PreferencesUI.py:4879 +#: flatcamGUI/ObjectUI.py:2356 flatcamGUI/PreferencesUI.py:5172 msgid "" "Check this box if you want to use\n" "a Custom Toolchange GCode (macro)." @@ -8421,7 +8913,7 @@ msgstr "" "Check this box if you want to use\n" "a Custom Toolchange GCode (macro)." -#: flatcamGUI/ObjectUI.py:2036 flatcamGUI/PreferencesUI.py:4891 +#: flatcamGUI/ObjectUI.py:2364 flatcamGUI/PreferencesUI.py:5184 msgid "" "A list of the FlatCAM variables that can be used\n" "in the Toolchange event.\n" @@ -8431,73 +8923,75 @@ msgstr "" "in the Toolchange event.\n" "They have to be surrounded by the '%' symbol" -#: flatcamGUI/ObjectUI.py:2043 flatcamGUI/PreferencesUI.py:2447 -#: flatcamGUI/PreferencesUI.py:3555 flatcamGUI/PreferencesUI.py:4347 -#: flatcamGUI/PreferencesUI.py:4898 flatcamGUI/PreferencesUI.py:5017 -#: flatcamGUI/PreferencesUI.py:5301 flatcamGUI/PreferencesUI.py:5458 -#: flatcamGUI/PreferencesUI.py:5676 flatcamGUI/PreferencesUI.py:5973 -#: flatcamGUI/PreferencesUI.py:6224 flatcamGUI/PreferencesUI.py:6438 -#: flatcamGUI/PreferencesUI.py:6663 flatcamGUI/PreferencesUI.py:6685 -#: flatcamGUI/PreferencesUI.py:6909 flatcamGUI/PreferencesUI.py:6946 -#: flatcamGUI/PreferencesUI.py:7140 flatcamGUI/PreferencesUI.py:7394 -#: flatcamGUI/PreferencesUI.py:7510 flatcamTools/ToolCopperThieving.py:89 -#: flatcamTools/ToolFiducials.py:149 flatcamTools/ToolNonCopperClear.py:315 +#: flatcamGUI/ObjectUI.py:2371 flatcamGUI/PreferencesUI.py:2627 +#: flatcamGUI/PreferencesUI.py:3833 flatcamGUI/PreferencesUI.py:4640 +#: flatcamGUI/PreferencesUI.py:5191 flatcamGUI/PreferencesUI.py:5310 +#: flatcamGUI/PreferencesUI.py:5640 flatcamGUI/PreferencesUI.py:5797 +#: flatcamGUI/PreferencesUI.py:6164 flatcamGUI/PreferencesUI.py:6461 +#: flatcamGUI/PreferencesUI.py:6711 flatcamGUI/PreferencesUI.py:6942 +#: flatcamGUI/PreferencesUI.py:7169 flatcamGUI/PreferencesUI.py:7191 +#: flatcamGUI/PreferencesUI.py:7415 flatcamGUI/PreferencesUI.py:7452 +#: flatcamGUI/PreferencesUI.py:7646 flatcamGUI/PreferencesUI.py:7900 +#: flatcamGUI/PreferencesUI.py:8016 flatcamGUI/PreferencesUI.py:8135 +#: flatcamGUI/PreferencesUI.py:8347 flatcamGUI/PreferencesUI.py:8556 +#: flatcamTools/ToolCopperThieving.py:90 flatcamTools/ToolFiducials.py:149 +#: flatcamTools/ToolInvertGerber.py:82 msgid "Parameters" msgstr "Parameters" -#: flatcamGUI/ObjectUI.py:2046 flatcamGUI/PreferencesUI.py:4903 +#: flatcamGUI/ObjectUI.py:2374 flatcamGUI/PreferencesUI.py:5196 msgid "FlatCAM CNC parameters" msgstr "FlatCAM CNC parameters" -#: flatcamGUI/ObjectUI.py:2047 flatcamGUI/PreferencesUI.py:4908 +#: flatcamGUI/ObjectUI.py:2375 flatcamGUI/PreferencesUI.py:5201 msgid "tool number" msgstr "tool number" -#: flatcamGUI/ObjectUI.py:2048 flatcamGUI/PreferencesUI.py:4909 +#: flatcamGUI/ObjectUI.py:2376 flatcamGUI/PreferencesUI.py:5202 msgid "tool diameter" msgstr "tool diameter" -#: flatcamGUI/ObjectUI.py:2049 flatcamGUI/PreferencesUI.py:4910 +#: flatcamGUI/ObjectUI.py:2377 flatcamGUI/PreferencesUI.py:5203 msgid "for Excellon, total number of drills" msgstr "for Excellon, total number of drills" -#: flatcamGUI/ObjectUI.py:2051 flatcamGUI/PreferencesUI.py:4912 +#: flatcamGUI/ObjectUI.py:2379 flatcamGUI/PreferencesUI.py:5205 msgid "X coord for Toolchange" msgstr "X coord for Toolchange" -#: flatcamGUI/ObjectUI.py:2052 flatcamGUI/PreferencesUI.py:4913 +#: flatcamGUI/ObjectUI.py:2380 flatcamGUI/PreferencesUI.py:5206 msgid "Y coord for Toolchange" msgstr "Y coord for Toolchange" -#: flatcamGUI/ObjectUI.py:2053 flatcamGUI/PreferencesUI.py:4915 +#: flatcamGUI/ObjectUI.py:2381 flatcamGUI/PreferencesUI.py:5208 msgid "Z coord for Toolchange" msgstr "Z coord for Toolchange" -#: flatcamGUI/ObjectUI.py:2054 +#: flatcamGUI/ObjectUI.py:2382 msgid "depth where to cut" msgstr "depth where to cut" -#: flatcamGUI/ObjectUI.py:2055 +#: flatcamGUI/ObjectUI.py:2383 msgid "height where to travel" msgstr "height where to travel" -#: flatcamGUI/ObjectUI.py:2056 flatcamGUI/PreferencesUI.py:4918 +#: flatcamGUI/ObjectUI.py:2384 flatcamGUI/PreferencesUI.py:5211 msgid "the step value for multidepth cut" msgstr "the step value for multidepth cut" -#: flatcamGUI/ObjectUI.py:2058 flatcamGUI/PreferencesUI.py:4920 +#: flatcamGUI/ObjectUI.py:2386 flatcamGUI/PreferencesUI.py:5213 msgid "the value for the spindle speed" msgstr "the value for the spindle speed" -#: flatcamGUI/ObjectUI.py:2060 +#: flatcamGUI/ObjectUI.py:2388 msgid "time to dwell to allow the spindle to reach it's set RPM" msgstr "time to dwell to allow the spindle to reach it's set RPM" -#: flatcamGUI/ObjectUI.py:2076 +#: flatcamGUI/ObjectUI.py:2404 msgid "View CNC Code" msgstr "View CNC Code" -#: flatcamGUI/ObjectUI.py:2078 +#: flatcamGUI/ObjectUI.py:2406 msgid "" "Opens TAB to view/modify/print G-Code\n" "file." @@ -8505,11 +8999,11 @@ msgstr "" "Opens TAB to view/modify/print G-Code\n" "file." -#: flatcamGUI/ObjectUI.py:2083 +#: flatcamGUI/ObjectUI.py:2411 msgid "Save CNC Code" msgstr "Save CNC Code" -#: flatcamGUI/ObjectUI.py:2085 +#: flatcamGUI/ObjectUI.py:2413 msgid "" "Opens dialog to save G-Code\n" "file." @@ -8517,79 +9011,75 @@ msgstr "" "Opens dialog to save G-Code\n" "file." -#: flatcamGUI/ObjectUI.py:2116 +#: flatcamGUI/ObjectUI.py:2447 msgid "Script Object" msgstr "Script Object" -#: flatcamGUI/ObjectUI.py:2138 flatcamGUI/ObjectUI.py:2211 +#: flatcamGUI/ObjectUI.py:2467 flatcamGUI/ObjectUI.py:2541 msgid "Auto Completer" msgstr "Auto Completer" -#: flatcamGUI/ObjectUI.py:2140 +#: flatcamGUI/ObjectUI.py:2469 msgid "This selects if the auto completer is enabled in the Script Editor." msgstr "This selects if the auto completer is enabled in the Script Editor." -#: flatcamGUI/ObjectUI.py:2182 +#: flatcamGUI/ObjectUI.py:2514 msgid "Document Object" msgstr "Document Object" -#: flatcamGUI/ObjectUI.py:2213 +#: flatcamGUI/ObjectUI.py:2543 msgid "This selects if the auto completer is enabled in the Document Editor." msgstr "This selects if the auto completer is enabled in the Document Editor." -#: flatcamGUI/ObjectUI.py:2231 +#: flatcamGUI/ObjectUI.py:2561 msgid "Font Type" msgstr "Font Type" -#: flatcamGUI/ObjectUI.py:2248 flatcamGUI/PreferencesUI.py:1103 +#: flatcamGUI/ObjectUI.py:2578 flatcamGUI/PreferencesUI.py:1278 msgid "Font Size" msgstr "Font Size" -#: flatcamGUI/ObjectUI.py:2284 +#: flatcamGUI/ObjectUI.py:2614 msgid "Alignment" msgstr "Alignment" -#: flatcamGUI/ObjectUI.py:2289 +#: flatcamGUI/ObjectUI.py:2619 msgid "Align Left" msgstr "Align Left" -#: flatcamGUI/ObjectUI.py:2294 -msgid "Center" -msgstr "Center" - -#: flatcamGUI/ObjectUI.py:2299 +#: flatcamGUI/ObjectUI.py:2629 msgid "Align Right" msgstr "Align Right" -#: flatcamGUI/ObjectUI.py:2304 +#: flatcamGUI/ObjectUI.py:2634 msgid "Justify" msgstr "Justify" -#: flatcamGUI/ObjectUI.py:2311 +#: flatcamGUI/ObjectUI.py:2641 msgid "Font Color" msgstr "Font Color" -#: flatcamGUI/ObjectUI.py:2313 +#: flatcamGUI/ObjectUI.py:2643 msgid "Set the font color for the selected text" msgstr "Set the font color for the selected text" -#: flatcamGUI/ObjectUI.py:2327 +#: flatcamGUI/ObjectUI.py:2657 msgid "Selection Color" msgstr "Selection Color" -#: flatcamGUI/ObjectUI.py:2329 +#: flatcamGUI/ObjectUI.py:2659 msgid "Set the selection color when doing text selection." msgstr "Set the selection color when doing text selection." -#: flatcamGUI/ObjectUI.py:2343 +#: flatcamGUI/ObjectUI.py:2673 msgid "Tab Size" msgstr "Tab Size" -#: flatcamGUI/ObjectUI.py:2345 +#: flatcamGUI/ObjectUI.py:2675 msgid "Set the tab size. In pixels. Default value is 80 pixels." msgstr "Set the tab size. In pixels. Default value is 80 pixels." -#: flatcamGUI/PlotCanvasLegacy.py:1254 +#: flatcamGUI/PlotCanvasLegacy.py:1301 msgid "" "Could not annotate due of a difference between the number of text elements " "and the number of text positions." @@ -8597,31 +9087,38 @@ msgstr "" "Could not annotate due of a difference between the number of text elements " "and the number of text positions." -#: flatcamGUI/PreferencesUI.py:324 +#: flatcamGUI/PreferencesUI.py:343 msgid "GUI Preferences" msgstr "GUI Preferences" -#: flatcamGUI/PreferencesUI.py:334 +#: flatcamGUI/PreferencesUI.py:353 msgid "Theme" msgstr "Theme" -#: flatcamGUI/PreferencesUI.py:336 -msgid "Select a theme for FlatCAM." -msgstr "Select a theme for FlatCAM." +#: flatcamGUI/PreferencesUI.py:355 +#| msgid "" +#| "Select an style for FlatCAM.\n" +#| "It will be applied at the next app start." +msgid "" +"Select a theme for FlatCAM.\n" +"It will theme the plot area." +msgstr "" +"Select a theme for FlatCAM.\n" +"It will theme the plot area." -#: flatcamGUI/PreferencesUI.py:340 +#: flatcamGUI/PreferencesUI.py:360 msgid "Light" msgstr "Light" -#: flatcamGUI/PreferencesUI.py:341 +#: flatcamGUI/PreferencesUI.py:361 msgid "Dark" msgstr "Dark" -#: flatcamGUI/PreferencesUI.py:348 +#: flatcamGUI/PreferencesUI.py:368 msgid "Use Gray Icons" msgstr "Use Gray Icons" -#: flatcamGUI/PreferencesUI.py:350 +#: flatcamGUI/PreferencesUI.py:370 msgid "" "Check this box to use a set of icons with\n" "a lighter (gray) color. To be used when a\n" @@ -8631,23 +9128,28 @@ msgstr "" "a lighter (gray) color. To be used when a\n" "full dark theme is applied." -#: flatcamGUI/PreferencesUI.py:356 +#: flatcamGUI/PreferencesUI.py:376 msgid "Apply Theme" msgstr "Apply Theme" -#: flatcamGUI/PreferencesUI.py:358 +#: flatcamGUI/PreferencesUI.py:378 +#| msgid "" +#| "Select a theme for FlatCAM.\n" +#| "The application will restart after change." msgid "" "Select a theme for FlatCAM.\n" +"It will theme the plot area.\n" "The application will restart after change." msgstr "" "Select a theme for FlatCAM.\n" +"It will theme the plot area.\n" "The application will restart after change." -#: flatcamGUI/PreferencesUI.py:369 +#: flatcamGUI/PreferencesUI.py:390 msgid "Layout" msgstr "Layout" -#: flatcamGUI/PreferencesUI.py:371 +#: flatcamGUI/PreferencesUI.py:392 msgid "" "Select an layout for FlatCAM.\n" "It is applied immediately." @@ -8655,11 +9157,11 @@ msgstr "" "Select an layout for FlatCAM.\n" "It is applied immediately." -#: flatcamGUI/PreferencesUI.py:390 +#: flatcamGUI/PreferencesUI.py:412 msgid "Style" msgstr "Style" -#: flatcamGUI/PreferencesUI.py:392 +#: flatcamGUI/PreferencesUI.py:414 msgid "" "Select an style for FlatCAM.\n" "It will be applied at the next app start." @@ -8667,11 +9169,11 @@ msgstr "" "Select an style for FlatCAM.\n" "It will be applied at the next app start." -#: flatcamGUI/PreferencesUI.py:406 +#: flatcamGUI/PreferencesUI.py:428 msgid "Activate HDPI Support" msgstr "Activate HDPI Support" -#: flatcamGUI/PreferencesUI.py:408 +#: flatcamGUI/PreferencesUI.py:430 msgid "" "Enable High DPI support for FlatCAM.\n" "It will be applied at the next app start." @@ -8679,11 +9181,11 @@ msgstr "" "Enable High DPI support for FlatCAM.\n" "It will be applied at the next app start." -#: flatcamGUI/PreferencesUI.py:422 +#: flatcamGUI/PreferencesUI.py:444 msgid "Display Hover Shape" msgstr "Display Hover Shape" -#: flatcamGUI/PreferencesUI.py:424 +#: flatcamGUI/PreferencesUI.py:446 msgid "" "Enable display of a hover shape for FlatCAM objects.\n" "It is displayed whenever the mouse cursor is hovering\n" @@ -8693,11 +9195,11 @@ msgstr "" "It is displayed whenever the mouse cursor is hovering\n" "over any kind of not-selected object." -#: flatcamGUI/PreferencesUI.py:431 +#: flatcamGUI/PreferencesUI.py:453 msgid "Display Selection Shape" msgstr "Display Selection Shape" -#: flatcamGUI/PreferencesUI.py:433 +#: flatcamGUI/PreferencesUI.py:455 msgid "" "Enable the display of a selection shape for FlatCAM objects.\n" "It is displayed whenever the mouse selects an object\n" @@ -8709,28 +9211,28 @@ msgstr "" "either by clicking or dragging mouse from left to right or\n" "right to left." -#: flatcamGUI/PreferencesUI.py:446 +#: flatcamGUI/PreferencesUI.py:468 msgid "Left-Right Selection Color" msgstr "Left-Right Selection Color" -#: flatcamGUI/PreferencesUI.py:449 flatcamGUI/PreferencesUI.py:515 -#: flatcamGUI/PreferencesUI.py:1882 flatcamGUI/PreferencesUI.py:2903 -#: flatcamGUI/PreferencesUI.py:3894 flatcamGUI/PreferencesUI.py:4534 -#: flatcamGUI/PreferencesUI.py:4600 flatcamTools/ToolRulesCheck.py:179 +#: flatcamGUI/PreferencesUI.py:471 flatcamGUI/PreferencesUI.py:537 +#: flatcamGUI/PreferencesUI.py:2062 flatcamGUI/PreferencesUI.py:3085 +#: flatcamGUI/PreferencesUI.py:4174 flatcamGUI/PreferencesUI.py:4827 +#: flatcamGUI/PreferencesUI.py:4893 flatcamTools/ToolRulesCheck.py:186 msgid "Outline" msgstr "Outline" -#: flatcamGUI/PreferencesUI.py:451 +#: flatcamGUI/PreferencesUI.py:473 msgid "Set the line color for the 'left to right' selection box." msgstr "Set the line color for the 'left to right' selection box." -#: flatcamGUI/PreferencesUI.py:465 flatcamGUI/PreferencesUI.py:532 -#: flatcamGUI/PreferencesUI.py:1899 flatcamGUI/PreferencesUI.py:2920 -#: flatcamGUI/PreferencesUI.py:4551 flatcamGUI/PreferencesUI.py:4617 +#: flatcamGUI/PreferencesUI.py:487 flatcamGUI/PreferencesUI.py:554 +#: flatcamGUI/PreferencesUI.py:2079 flatcamGUI/PreferencesUI.py:3102 +#: flatcamGUI/PreferencesUI.py:4844 flatcamGUI/PreferencesUI.py:4910 msgid "Fill" msgstr "Fill" -#: flatcamGUI/PreferencesUI.py:467 +#: flatcamGUI/PreferencesUI.py:489 msgid "" "Set the fill color for the selection box\n" "in case that the selection is done from left to right.\n" @@ -8742,25 +9244,25 @@ msgstr "" "First 6 digits are the color and the last 2\n" "digits are for alpha (transparency) level." -#: flatcamGUI/PreferencesUI.py:485 flatcamGUI/PreferencesUI.py:552 -#: flatcamGUI/PreferencesUI.py:1918 flatcamGUI/PreferencesUI.py:2939 -#: flatcamGUI/PreferencesUI.py:4570 +#: flatcamGUI/PreferencesUI.py:507 flatcamGUI/PreferencesUI.py:574 +#: flatcamGUI/PreferencesUI.py:2098 flatcamGUI/PreferencesUI.py:3121 +#: flatcamGUI/PreferencesUI.py:4863 msgid "Alpha" msgstr "Alpha" -#: flatcamGUI/PreferencesUI.py:487 +#: flatcamGUI/PreferencesUI.py:509 msgid "Set the fill transparency for the 'left to right' selection box." msgstr "Set the fill transparency for the 'left to right' selection box." -#: flatcamGUI/PreferencesUI.py:511 +#: flatcamGUI/PreferencesUI.py:533 msgid "Right-Left Selection Color" msgstr "Right-Left Selection Color" -#: flatcamGUI/PreferencesUI.py:517 +#: flatcamGUI/PreferencesUI.py:539 msgid "Set the line color for the 'right to left' selection box." msgstr "Set the line color for the 'right to left' selection box." -#: flatcamGUI/PreferencesUI.py:534 +#: flatcamGUI/PreferencesUI.py:556 msgid "" "Set the fill color for the selection box\n" "in case that the selection is done from right to left.\n" @@ -8772,43 +9274,43 @@ msgstr "" "First 6 digits are the color and the last 2\n" "digits are for alpha (transparency) level." -#: flatcamGUI/PreferencesUI.py:554 +#: flatcamGUI/PreferencesUI.py:576 msgid "Set the fill transparency for selection 'right to left' box." msgstr "Set the fill transparency for selection 'right to left' box." -#: flatcamGUI/PreferencesUI.py:581 +#: flatcamGUI/PreferencesUI.py:603 msgid "Editor Color" msgstr "Editor Color" -#: flatcamGUI/PreferencesUI.py:585 +#: flatcamGUI/PreferencesUI.py:607 msgid "Drawing" msgstr "Drawing" -#: flatcamGUI/PreferencesUI.py:587 +#: flatcamGUI/PreferencesUI.py:609 msgid "Set the color for the shape." msgstr "Set the color for the shape." -#: flatcamGUI/PreferencesUI.py:604 +#: flatcamGUI/PreferencesUI.py:626 msgid "Set the color of the shape when selected." msgstr "Set the color of the shape when selected." -#: flatcamGUI/PreferencesUI.py:627 +#: flatcamGUI/PreferencesUI.py:649 msgid "Project Items Color" msgstr "Project Items Color" -#: flatcamGUI/PreferencesUI.py:631 +#: flatcamGUI/PreferencesUI.py:653 msgid "Enabled" msgstr "Enabled" -#: flatcamGUI/PreferencesUI.py:633 +#: flatcamGUI/PreferencesUI.py:655 msgid "Set the color of the items in Project Tab Tree." msgstr "Set the color of the items in Project Tab Tree." -#: flatcamGUI/PreferencesUI.py:647 +#: flatcamGUI/PreferencesUI.py:669 msgid "Disabled" msgstr "Disabled" -#: flatcamGUI/PreferencesUI.py:649 +#: flatcamGUI/PreferencesUI.py:671 msgid "" "Set the color of the items in Project Tab Tree,\n" "for the case when the items are disabled." @@ -8816,7 +9318,11 @@ msgstr "" "Set the color of the items in Project Tab Tree,\n" "for the case when the items are disabled." -#: flatcamGUI/PreferencesUI.py:667 +#: flatcamGUI/PreferencesUI.py:687 +msgid "Project AutoHide" +msgstr "Project AutoHide" + +#: flatcamGUI/PreferencesUI.py:689 msgid "" "Check this box if you want the project/selected/tool tab area to\n" "hide automatically when there are no objects loaded and\n" @@ -8826,43 +9332,43 @@ msgstr "" "hide automatically when there are no objects loaded and\n" "to show whenever a new object is created." -#: flatcamGUI/PreferencesUI.py:934 +#: flatcamGUI/PreferencesUI.py:1109 msgid "App Settings" msgstr "App Settings" -#: flatcamGUI/PreferencesUI.py:955 +#: flatcamGUI/PreferencesUI.py:1130 msgid "Grid Settings" msgstr "Grid Settings" -#: flatcamGUI/PreferencesUI.py:959 +#: flatcamGUI/PreferencesUI.py:1134 msgid "X value" msgstr "X value" -#: flatcamGUI/PreferencesUI.py:961 +#: flatcamGUI/PreferencesUI.py:1136 msgid "This is the Grid snap value on X axis." msgstr "This is the Grid snap value on X axis." -#: flatcamGUI/PreferencesUI.py:971 +#: flatcamGUI/PreferencesUI.py:1146 msgid "Y value" msgstr "Y value" -#: flatcamGUI/PreferencesUI.py:973 +#: flatcamGUI/PreferencesUI.py:1148 msgid "This is the Grid snap value on Y axis." msgstr "This is the Grid snap value on Y axis." -#: flatcamGUI/PreferencesUI.py:983 +#: flatcamGUI/PreferencesUI.py:1158 msgid "Snap Max" msgstr "Snap Max" -#: flatcamGUI/PreferencesUI.py:998 +#: flatcamGUI/PreferencesUI.py:1173 msgid "Workspace Settings" msgstr "Workspace Settings" -#: flatcamGUI/PreferencesUI.py:1001 +#: flatcamGUI/PreferencesUI.py:1176 msgid "Active" msgstr "Active" -#: flatcamGUI/PreferencesUI.py:1003 +#: flatcamGUI/PreferencesUI.py:1178 msgid "" "Draw a delimiting rectangle on canvas.\n" "The purpose is to illustrate the limits for our work." @@ -8870,7 +9376,7 @@ msgstr "" "Draw a delimiting rectangle on canvas.\n" "The purpose is to illustrate the limits for our work." -#: flatcamGUI/PreferencesUI.py:1011 +#: flatcamGUI/PreferencesUI.py:1186 msgid "" "Select the type of rectangle to be used on canvas,\n" "as valid workspace." @@ -8878,12 +9384,12 @@ msgstr "" "Select the type of rectangle to be used on canvas,\n" "as valid workspace." -#: flatcamGUI/PreferencesUI.py:1077 +#: flatcamGUI/PreferencesUI.py:1252 msgid "Orientation" msgstr "Orientation" -#: flatcamGUI/PreferencesUI.py:1078 flatcamGUI/PreferencesUI.py:5884 -#: flatcamTools/ToolFilm.py:420 +#: flatcamGUI/PreferencesUI.py:1253 flatcamGUI/PreferencesUI.py:6372 +#: flatcamTools/ToolFilm.py:422 msgid "" "Can be:\n" "- Portrait\n" @@ -8893,21 +9399,21 @@ msgstr "" "- Portrait\n" "- Landscape" -#: flatcamGUI/PreferencesUI.py:1082 flatcamGUI/PreferencesUI.py:5888 -#: flatcamTools/ToolFilm.py:424 +#: flatcamGUI/PreferencesUI.py:1257 flatcamGUI/PreferencesUI.py:6376 +#: flatcamTools/ToolFilm.py:426 msgid "Portrait" msgstr "Portrait" -#: flatcamGUI/PreferencesUI.py:1083 flatcamGUI/PreferencesUI.py:5889 -#: flatcamTools/ToolFilm.py:425 +#: flatcamGUI/PreferencesUI.py:1258 flatcamGUI/PreferencesUI.py:6377 +#: flatcamTools/ToolFilm.py:427 msgid "Landscape" msgstr "Landscape" -#: flatcamGUI/PreferencesUI.py:1107 +#: flatcamGUI/PreferencesUI.py:1282 msgid "Notebook" msgstr "Notebook" -#: flatcamGUI/PreferencesUI.py:1109 +#: flatcamGUI/PreferencesUI.py:1284 msgid "" "This sets the font size for the elements found in the Notebook.\n" "The notebook is the collapsible area in the left side of the GUI,\n" @@ -8917,19 +9423,19 @@ msgstr "" "The notebook is the collapsible area in the left side of the GUI,\n" "and include the Project, Selected and Tool tabs." -#: flatcamGUI/PreferencesUI.py:1128 +#: flatcamGUI/PreferencesUI.py:1303 msgid "Axis" msgstr "Axis" -#: flatcamGUI/PreferencesUI.py:1130 +#: flatcamGUI/PreferencesUI.py:1305 msgid "This sets the font size for canvas axis." msgstr "This sets the font size for canvas axis." -#: flatcamGUI/PreferencesUI.py:1147 +#: flatcamGUI/PreferencesUI.py:1322 msgid "Textbox" msgstr "Textbox" -#: flatcamGUI/PreferencesUI.py:1149 +#: flatcamGUI/PreferencesUI.py:1324 msgid "" "This sets the font size for the Textbox GUI\n" "elements that are used in FlatCAM." @@ -8937,15 +9443,15 @@ msgstr "" "This sets the font size for the Textbox GUI\n" "elements that are used in FlatCAM." -#: flatcamGUI/PreferencesUI.py:1175 +#: flatcamGUI/PreferencesUI.py:1350 msgid "Mouse Settings" msgstr "Mouse Settings" -#: flatcamGUI/PreferencesUI.py:1179 +#: flatcamGUI/PreferencesUI.py:1354 msgid "Cursor Shape" msgstr "Cursor Shape" -#: flatcamGUI/PreferencesUI.py:1181 +#: flatcamGUI/PreferencesUI.py:1356 msgid "" "Choose a mouse cursor shape.\n" "- Small -> with a customizable size.\n" @@ -8955,47 +9461,47 @@ msgstr "" "- Small -> with a customizable size.\n" "- Big -> Infinite lines" -#: flatcamGUI/PreferencesUI.py:1187 +#: flatcamGUI/PreferencesUI.py:1362 msgid "Small" msgstr "Small" -#: flatcamGUI/PreferencesUI.py:1188 +#: flatcamGUI/PreferencesUI.py:1363 msgid "Big" msgstr "Big" -#: flatcamGUI/PreferencesUI.py:1195 +#: flatcamGUI/PreferencesUI.py:1370 msgid "Cursor Size" msgstr "Cursor Size" -#: flatcamGUI/PreferencesUI.py:1197 +#: flatcamGUI/PreferencesUI.py:1372 msgid "Set the size of the mouse cursor, in pixels." msgstr "Set the size of the mouse cursor, in pixels." -#: flatcamGUI/PreferencesUI.py:1208 +#: flatcamGUI/PreferencesUI.py:1383 msgid "Cursor Width" msgstr "Cursor Width" -#: flatcamGUI/PreferencesUI.py:1210 +#: flatcamGUI/PreferencesUI.py:1385 msgid "Set the line width of the mouse cursor, in pixels." msgstr "Set the line width of the mouse cursor, in pixels." -#: flatcamGUI/PreferencesUI.py:1221 flatcamGUI/PreferencesUI.py:1228 +#: flatcamGUI/PreferencesUI.py:1396 flatcamGUI/PreferencesUI.py:1403 msgid "Cursor Color" msgstr "Cursor Color" -#: flatcamGUI/PreferencesUI.py:1223 +#: flatcamGUI/PreferencesUI.py:1398 msgid "Check this box to color mouse cursor." msgstr "Check this box to color mouse cursor." -#: flatcamGUI/PreferencesUI.py:1230 +#: flatcamGUI/PreferencesUI.py:1405 msgid "Set the color of the mouse cursor." msgstr "Set the color of the mouse cursor." -#: flatcamGUI/PreferencesUI.py:1253 +#: flatcamGUI/PreferencesUI.py:1428 msgid "Pan Button" msgstr "Pan Button" -#: flatcamGUI/PreferencesUI.py:1255 +#: flatcamGUI/PreferencesUI.py:1430 msgid "" "Select the mouse button to use for panning:\n" "- MMB --> Middle Mouse Button\n" @@ -9005,35 +9511,35 @@ msgstr "" "- MMB --> Middle Mouse Button\n" "- RMB --> Right Mouse Button" -#: flatcamGUI/PreferencesUI.py:1259 +#: flatcamGUI/PreferencesUI.py:1434 msgid "MMB" msgstr "MMB" -#: flatcamGUI/PreferencesUI.py:1260 +#: flatcamGUI/PreferencesUI.py:1435 msgid "RMB" msgstr "RMB" -#: flatcamGUI/PreferencesUI.py:1266 +#: flatcamGUI/PreferencesUI.py:1441 msgid "Multiple Selection" msgstr "Multiple Selection" -#: flatcamGUI/PreferencesUI.py:1268 +#: flatcamGUI/PreferencesUI.py:1443 msgid "Select the key used for multiple selection." msgstr "Select the key used for multiple selection." -#: flatcamGUI/PreferencesUI.py:1270 +#: flatcamGUI/PreferencesUI.py:1445 msgid "CTRL" msgstr "CTRL" -#: flatcamGUI/PreferencesUI.py:1271 +#: flatcamGUI/PreferencesUI.py:1446 msgid "SHIFT" msgstr "SHIFT" -#: flatcamGUI/PreferencesUI.py:1282 +#: flatcamGUI/PreferencesUI.py:1457 msgid "Delete object confirmation" msgstr "Delete object confirmation" -#: flatcamGUI/PreferencesUI.py:1284 +#: flatcamGUI/PreferencesUI.py:1459 msgid "" "When checked the application will ask for user confirmation\n" "whenever the Delete object(s) event is triggered, either by\n" @@ -9043,11 +9549,11 @@ msgstr "" "whenever the Delete object(s) event is triggered, either by\n" "menu shortcut or key shortcut." -#: flatcamGUI/PreferencesUI.py:1291 +#: flatcamGUI/PreferencesUI.py:1466 msgid "\"Open\" behavior" msgstr "\"Open\" behavior" -#: flatcamGUI/PreferencesUI.py:1293 +#: flatcamGUI/PreferencesUI.py:1468 msgid "" "When checked the path for the last saved file is used when saving files,\n" "and the path for the last opened file is used when opening files.\n" @@ -9061,7 +9567,11 @@ msgstr "" "When unchecked the path for opening files is the one used last: either the\n" "path for saving files or the path for opening files." -#: flatcamGUI/PreferencesUI.py:1304 +#: flatcamGUI/PreferencesUI.py:1477 +msgid "Enable ToolTips" +msgstr "Enable ToolTips" + +#: flatcamGUI/PreferencesUI.py:1479 msgid "" "Check this box if you want to have toolTips displayed\n" "when hovering with mouse over items throughout the App." @@ -9069,11 +9579,11 @@ msgstr "" "Check this box if you want to have toolTips displayed\n" "when hovering with mouse over items throughout the App." -#: flatcamGUI/PreferencesUI.py:1311 +#: flatcamGUI/PreferencesUI.py:1486 msgid "Allow Machinist Unsafe Settings" msgstr "Allow Machinist Unsafe Settings" -#: flatcamGUI/PreferencesUI.py:1313 +#: flatcamGUI/PreferencesUI.py:1488 msgid "" "If checked, some of the application settings will be allowed\n" "to have values that are usually unsafe to use.\n" @@ -9087,11 +9597,11 @@ msgstr "" "It will applied at the next application start.\n" "<>: Don't change this unless you know what you are doing !!!" -#: flatcamGUI/PreferencesUI.py:1324 +#: flatcamGUI/PreferencesUI.py:1500 msgid "Bookmarks limit" msgstr "Bookmarks limit" -#: flatcamGUI/PreferencesUI.py:1326 +#: flatcamGUI/PreferencesUI.py:1502 msgid "" "The maximum number of bookmarks that may be installed in the menu.\n" "The number of bookmarks in the bookmark manager may be greater\n" @@ -9101,27 +9611,27 @@ msgstr "" "The number of bookmarks in the bookmark manager may be greater\n" "but the menu will hold only so much." -#: flatcamGUI/PreferencesUI.py:1335 +#: flatcamGUI/PreferencesUI.py:1511 msgid "Activity Icon" msgstr "Activity Icon" -#: flatcamGUI/PreferencesUI.py:1337 +#: flatcamGUI/PreferencesUI.py:1513 msgid "Select the GIF that show activity when FlatCAM is active." msgstr "Select the GIF that show activity when FlatCAM is active." -#: flatcamGUI/PreferencesUI.py:1395 +#: flatcamGUI/PreferencesUI.py:1571 msgid "App Preferences" msgstr "App Preferences" -#: flatcamGUI/PreferencesUI.py:1405 flatcamGUI/PreferencesUI.py:1811 -#: flatcamGUI/PreferencesUI.py:2359 flatcamGUI/PreferencesUI.py:2804 -#: flatcamGUI/PreferencesUI.py:3417 flatcamTools/ToolDistance.py:49 -#: flatcamTools/ToolDistanceMin.py:49 flatcamTools/ToolPcbWizard.py:127 -#: flatcamTools/ToolProperties.py:152 +#: flatcamGUI/PreferencesUI.py:1581 flatcamGUI/PreferencesUI.py:1991 +#: flatcamGUI/PreferencesUI.py:2539 flatcamGUI/PreferencesUI.py:2986 +#: flatcamGUI/PreferencesUI.py:3695 flatcamTools/ToolDistance.py:56 +#: flatcamTools/ToolDistanceMin.py:50 flatcamTools/ToolPcbWizard.py:127 +#: flatcamTools/ToolProperties.py:154 msgid "Units" msgstr "Units" -#: flatcamGUI/PreferencesUI.py:1406 +#: flatcamGUI/PreferencesUI.py:1582 msgid "" "The default value for FlatCAM units.\n" "Whatever is selected here is set every time\n" @@ -9131,22 +9641,22 @@ msgstr "" "Whatever is selected here is set every time\n" "FLatCAM is started." -#: flatcamGUI/PreferencesUI.py:1409 flatcamGUI/PreferencesUI.py:1817 -#: flatcamGUI/PreferencesUI.py:2365 flatcamGUI/PreferencesUI.py:2815 -#: flatcamGUI/PreferencesUI.py:3423 flatcamTools/ToolCalculators.py:62 +#: flatcamGUI/PreferencesUI.py:1585 flatcamGUI/PreferencesUI.py:1997 +#: flatcamGUI/PreferencesUI.py:2545 flatcamGUI/PreferencesUI.py:2997 +#: flatcamGUI/PreferencesUI.py:3701 flatcamTools/ToolCalculators.py:62 #: flatcamTools/ToolPcbWizard.py:126 msgid "MM" msgstr "MM" -#: flatcamGUI/PreferencesUI.py:1410 +#: flatcamGUI/PreferencesUI.py:1586 msgid "IN" msgstr "IN" -#: flatcamGUI/PreferencesUI.py:1416 +#: flatcamGUI/PreferencesUI.py:1592 msgid "Precision MM" msgstr "Precision MM" -#: flatcamGUI/PreferencesUI.py:1418 +#: flatcamGUI/PreferencesUI.py:1594 msgid "" "The number of decimals used throughout the application\n" "when the set units are in METRIC system.\n" @@ -9156,11 +9666,11 @@ msgstr "" "when the set units are in METRIC system.\n" "Any change here require an application restart." -#: flatcamGUI/PreferencesUI.py:1430 +#: flatcamGUI/PreferencesUI.py:1606 msgid "Precision INCH" msgstr "Precision INCH" -#: flatcamGUI/PreferencesUI.py:1432 +#: flatcamGUI/PreferencesUI.py:1608 msgid "" "The number of decimals used throughout the application\n" "when the set units are in INCH system.\n" @@ -9170,11 +9680,11 @@ msgstr "" "when the set units are in INCH system.\n" "Any change here require an application restart." -#: flatcamGUI/PreferencesUI.py:1444 +#: flatcamGUI/PreferencesUI.py:1620 msgid "Graphic Engine" msgstr "Graphic Engine" -#: flatcamGUI/PreferencesUI.py:1445 +#: flatcamGUI/PreferencesUI.py:1621 msgid "" "Choose what graphic engine to use in FlatCAM.\n" "Legacy(2D) -> reduced functionality, slow performance but enhanced " @@ -9192,19 +9702,19 @@ msgstr "" "Intel HD3000 or older. In this case the plot area will be black therefore\n" "use the Legacy(2D) mode." -#: flatcamGUI/PreferencesUI.py:1451 +#: flatcamGUI/PreferencesUI.py:1627 msgid "Legacy(2D)" msgstr "Legacy(2D)" -#: flatcamGUI/PreferencesUI.py:1452 +#: flatcamGUI/PreferencesUI.py:1628 msgid "OpenGL(3D)" msgstr "OpenGL(3D)" -#: flatcamGUI/PreferencesUI.py:1464 +#: flatcamGUI/PreferencesUI.py:1640 msgid "APP. LEVEL" msgstr "APP. LEVEL" -#: flatcamGUI/PreferencesUI.py:1465 +#: flatcamGUI/PreferencesUI.py:1641 msgid "" "Choose the default level of usage for FlatCAM.\n" "BASIC level -> reduced functionality, best for beginner's.\n" @@ -9220,11 +9730,11 @@ msgstr "" "The choice here will influence the parameters in\n" "the Selected Tab for all kinds of FlatCAM objects." -#: flatcamGUI/PreferencesUI.py:1477 +#: flatcamGUI/PreferencesUI.py:1653 msgid "Portable app" msgstr "Portable app" -#: flatcamGUI/PreferencesUI.py:1478 +#: flatcamGUI/PreferencesUI.py:1654 msgid "" "Choose if the application should run as portable.\n" "\n" @@ -9238,19 +9748,19 @@ msgstr "" "which means that the preferences files will be saved\n" "in the application folder, in the lib\\config subfolder." -#: flatcamGUI/PreferencesUI.py:1491 +#: flatcamGUI/PreferencesUI.py:1667 msgid "Languages" msgstr "Languages" -#: flatcamGUI/PreferencesUI.py:1492 +#: flatcamGUI/PreferencesUI.py:1668 msgid "Set the language used throughout FlatCAM." msgstr "Set the language used throughout FlatCAM." -#: flatcamGUI/PreferencesUI.py:1498 +#: flatcamGUI/PreferencesUI.py:1674 msgid "Apply Language" msgstr "Apply Language" -#: flatcamGUI/PreferencesUI.py:1499 +#: flatcamGUI/PreferencesUI.py:1675 msgid "" "Set the language used throughout FlatCAM.\n" "The app will restart after click." @@ -9258,31 +9768,31 @@ msgstr "" "Set the language used throughout FlatCAM.\n" "The app will restart after click." -#: flatcamGUI/PreferencesUI.py:1513 +#: flatcamGUI/PreferencesUI.py:1689 msgid "Startup Settings" msgstr "Startup Settings" -#: flatcamGUI/PreferencesUI.py:1517 +#: flatcamGUI/PreferencesUI.py:1693 msgid "Splash Screen" msgstr "Splash Screen" -#: flatcamGUI/PreferencesUI.py:1519 +#: flatcamGUI/PreferencesUI.py:1695 msgid "Enable display of the splash screen at application startup." msgstr "Enable display of the splash screen at application startup." -#: flatcamGUI/PreferencesUI.py:1531 +#: flatcamGUI/PreferencesUI.py:1707 msgid "Sys Tray Icon" msgstr "Sys Tray Icon" -#: flatcamGUI/PreferencesUI.py:1533 +#: flatcamGUI/PreferencesUI.py:1709 msgid "Enable display of FlatCAM icon in Sys Tray." msgstr "Enable display of FlatCAM icon in Sys Tray." -#: flatcamGUI/PreferencesUI.py:1538 +#: flatcamGUI/PreferencesUI.py:1714 msgid "Show Shell" msgstr "Show Shell" -#: flatcamGUI/PreferencesUI.py:1540 +#: flatcamGUI/PreferencesUI.py:1716 msgid "" "Check this box if you want the shell to\n" "start automatically at startup." @@ -9290,11 +9800,11 @@ msgstr "" "Check this box if you want the shell to\n" "start automatically at startup." -#: flatcamGUI/PreferencesUI.py:1547 +#: flatcamGUI/PreferencesUI.py:1723 msgid "Show Project" msgstr "Show Project" -#: flatcamGUI/PreferencesUI.py:1549 +#: flatcamGUI/PreferencesUI.py:1725 msgid "" "Check this box if you want the project/selected/tool tab area to\n" "to be shown automatically at startup." @@ -9302,11 +9812,11 @@ msgstr "" "Check this box if you want the project/selected/tool tab area to\n" "to be shown automatically at startup." -#: flatcamGUI/PreferencesUI.py:1555 +#: flatcamGUI/PreferencesUI.py:1731 msgid "Version Check" msgstr "Version Check" -#: flatcamGUI/PreferencesUI.py:1557 +#: flatcamGUI/PreferencesUI.py:1733 msgid "" "Check this box if you want to check\n" "for a new version automatically at startup." @@ -9314,11 +9824,11 @@ msgstr "" "Check this box if you want to check\n" "for a new version automatically at startup." -#: flatcamGUI/PreferencesUI.py:1564 +#: flatcamGUI/PreferencesUI.py:1740 msgid "Send Statistics" msgstr "Send Statistics" -#: flatcamGUI/PreferencesUI.py:1566 +#: flatcamGUI/PreferencesUI.py:1742 msgid "" "Check this box if you agree to send anonymous\n" "stats automatically at startup, to help improve FlatCAM." @@ -9326,11 +9836,11 @@ msgstr "" "Check this box if you agree to send anonymous\n" "stats automatically at startup, to help improve FlatCAM." -#: flatcamGUI/PreferencesUI.py:1580 +#: flatcamGUI/PreferencesUI.py:1756 msgid "Workers number" msgstr "Workers number" -#: flatcamGUI/PreferencesUI.py:1582 flatcamGUI/PreferencesUI.py:1591 +#: flatcamGUI/PreferencesUI.py:1758 msgid "" "The number of Qthreads made available to the App.\n" "A bigger number may finish the jobs more quickly but\n" @@ -9346,35 +9856,42 @@ msgstr "" "Default value is 2.\n" "After change, it will be applied at next App start." -#: flatcamGUI/PreferencesUI.py:1604 +#: flatcamGUI/PreferencesUI.py:1772 msgid "Geo Tolerance" msgstr "Geo Tolerance" -#: flatcamGUI/PreferencesUI.py:1606 flatcamGUI/PreferencesUI.py:1615 +#: flatcamGUI/PreferencesUI.py:1774 +#| msgid "" +#| "This value can counter the effect of the Circle Steps\n" +#| "parameter. Default value is 0.01.\n" +#| "A lower value will increase the detail both in image\n" +#| "and in Gcode for the circles, with a higher cost in\n" +#| "performance. Higher value will provide more\n" +#| "performance at the expense of level of detail." msgid "" "This value can counter the effect of the Circle Steps\n" -"parameter. Default value is 0.01.\n" +"parameter. Default value is 0.005.\n" "A lower value will increase the detail both in image\n" "and in Gcode for the circles, with a higher cost in\n" "performance. Higher value will provide more\n" "performance at the expense of level of detail." msgstr "" "This value can counter the effect of the Circle Steps\n" -"parameter. Default value is 0.01.\n" +"parameter. Default value is 0.005.\n" "A lower value will increase the detail both in image\n" "and in Gcode for the circles, with a higher cost in\n" "performance. Higher value will provide more\n" "performance at the expense of level of detail." -#: flatcamGUI/PreferencesUI.py:1634 +#: flatcamGUI/PreferencesUI.py:1794 msgid "Save Settings" msgstr "Save Settings" -#: flatcamGUI/PreferencesUI.py:1638 +#: flatcamGUI/PreferencesUI.py:1798 msgid "Save Compressed Project" msgstr "Save Compressed Project" -#: flatcamGUI/PreferencesUI.py:1640 +#: flatcamGUI/PreferencesUI.py:1800 msgid "" "Whether to save a compressed or uncompressed project.\n" "When checked it will save a compressed FlatCAM project." @@ -9382,11 +9899,11 @@ msgstr "" "Whether to save a compressed or uncompressed project.\n" "When checked it will save a compressed FlatCAM project." -#: flatcamGUI/PreferencesUI.py:1649 +#: flatcamGUI/PreferencesUI.py:1809 msgid "Compression" msgstr "Compression" -#: flatcamGUI/PreferencesUI.py:1651 +#: flatcamGUI/PreferencesUI.py:1811 msgid "" "The level of compression used when saving\n" "a FlatCAM project. Higher value means better compression\n" @@ -9396,60 +9913,91 @@ msgstr "" "a FlatCAM project. Higher value means better compression\n" "but require more RAM usage and more processing time." -#: flatcamGUI/PreferencesUI.py:1671 +#: flatcamGUI/PreferencesUI.py:1822 +msgid "Enable Auto Save" +msgstr "Enable Auto Save" + +#: flatcamGUI/PreferencesUI.py:1824 +msgid "" +"Check to enable the autosave feature.\n" +"When enabled, the application will try to save a project\n" +"at the set interval." +msgstr "" +"Check to enable the autosave feature.\n" +"When enabled, the application will try to save a project\n" +"at the set interval." + +#: flatcamGUI/PreferencesUI.py:1834 +#| msgid "Interior" +msgid "Interval" +msgstr "Interval" + +#: flatcamGUI/PreferencesUI.py:1836 +msgid "" +"Time interval for autosaving. In milliseconds.\n" +"The application will try to save periodically but only\n" +"if the project was saved manually at least once.\n" +"While active, some operations may block this feature." +msgstr "" +"Time interval for autosaving. In milliseconds.\n" +"The application will try to save periodically but only\n" +"if the project was saved manually at least once.\n" +"While active, some operations may block this feature." + +#: flatcamGUI/PreferencesUI.py:1852 msgid "Text to PDF parameters" msgstr "Text to PDF parameters" -#: flatcamGUI/PreferencesUI.py:1673 +#: flatcamGUI/PreferencesUI.py:1854 msgid "Used when saving text in Code Editor or in FlatCAM Document objects." msgstr "Used when saving text in Code Editor or in FlatCAM Document objects." -#: flatcamGUI/PreferencesUI.py:1682 +#: flatcamGUI/PreferencesUI.py:1863 msgid "Top Margin" msgstr "Top Margin" -#: flatcamGUI/PreferencesUI.py:1684 +#: flatcamGUI/PreferencesUI.py:1865 msgid "Distance between text body and the top of the PDF file." msgstr "Distance between text body and the top of the PDF file." -#: flatcamGUI/PreferencesUI.py:1695 +#: flatcamGUI/PreferencesUI.py:1876 msgid "Bottom Margin" msgstr "Bottom Margin" -#: flatcamGUI/PreferencesUI.py:1697 +#: flatcamGUI/PreferencesUI.py:1878 msgid "Distance between text body and the bottom of the PDF file." msgstr "Distance between text body and the bottom of the PDF file." -#: flatcamGUI/PreferencesUI.py:1708 +#: flatcamGUI/PreferencesUI.py:1889 msgid "Left Margin" msgstr "Left Margin" -#: flatcamGUI/PreferencesUI.py:1710 +#: flatcamGUI/PreferencesUI.py:1891 msgid "Distance between text body and the left of the PDF file." msgstr "Distance between text body and the left of the PDF file." -#: flatcamGUI/PreferencesUI.py:1721 +#: flatcamGUI/PreferencesUI.py:1902 msgid "Right Margin" msgstr "Right Margin" -#: flatcamGUI/PreferencesUI.py:1723 +#: flatcamGUI/PreferencesUI.py:1904 msgid "Distance between text body and the right of the PDF file." msgstr "Distance between text body and the right of the PDF file." -#: flatcamGUI/PreferencesUI.py:1756 +#: flatcamGUI/PreferencesUI.py:1936 msgid "Gerber General" msgstr "Gerber General" -#: flatcamGUI/PreferencesUI.py:1774 +#: flatcamGUI/PreferencesUI.py:1954 msgid "M-Color" msgstr "M-Color" -#: flatcamGUI/PreferencesUI.py:1788 flatcamGUI/PreferencesUI.py:3859 -#: flatcamGUI/PreferencesUI.py:4442 flatcamGUI/PreferencesUI.py:7148 +#: flatcamGUI/PreferencesUI.py:1968 flatcamGUI/PreferencesUI.py:4137 +#: flatcamGUI/PreferencesUI.py:4735 flatcamGUI/PreferencesUI.py:7654 msgid "Circle Steps" msgstr "Circle Steps" -#: flatcamGUI/PreferencesUI.py:1790 +#: flatcamGUI/PreferencesUI.py:1970 msgid "" "The number of circle steps for Gerber \n" "circular aperture linear approximation." @@ -9457,11 +10005,11 @@ msgstr "" "The number of circle steps for Gerber \n" "circular aperture linear approximation." -#: flatcamGUI/PreferencesUI.py:1802 +#: flatcamGUI/PreferencesUI.py:1982 msgid "Default Values" msgstr "Default Values" -#: flatcamGUI/PreferencesUI.py:1804 +#: flatcamGUI/PreferencesUI.py:1984 msgid "" "Those values will be used as fallback values\n" "in case that they are not found in the Gerber file." @@ -9469,25 +10017,25 @@ msgstr "" "Those values will be used as fallback values\n" "in case that they are not found in the Gerber file." -#: flatcamGUI/PreferencesUI.py:1813 flatcamGUI/PreferencesUI.py:1819 -#: flatcamGUI/PreferencesUI.py:2361 flatcamGUI/PreferencesUI.py:2367 +#: flatcamGUI/PreferencesUI.py:1993 flatcamGUI/PreferencesUI.py:1999 +#: flatcamGUI/PreferencesUI.py:2541 flatcamGUI/PreferencesUI.py:2547 msgid "The units used in the Gerber file." msgstr "The units used in the Gerber file." -#: flatcamGUI/PreferencesUI.py:1816 flatcamGUI/PreferencesUI.py:2364 -#: flatcamGUI/PreferencesUI.py:2728 flatcamGUI/PreferencesUI.py:2814 -#: flatcamGUI/PreferencesUI.py:3422 flatcamTools/ToolCalculators.py:61 +#: flatcamGUI/PreferencesUI.py:1996 flatcamGUI/PreferencesUI.py:2544 +#: flatcamGUI/PreferencesUI.py:2910 flatcamGUI/PreferencesUI.py:2996 +#: flatcamGUI/PreferencesUI.py:3700 flatcamTools/ToolCalculators.py:61 #: flatcamTools/ToolPcbWizard.py:125 msgid "INCH" msgstr "INCH" -#: flatcamGUI/PreferencesUI.py:1826 flatcamGUI/PreferencesUI.py:2413 -#: flatcamGUI/PreferencesUI.py:2786 flatcamGUI/PreferencesUI.py:3490 +#: flatcamGUI/PreferencesUI.py:2006 flatcamGUI/PreferencesUI.py:2593 +#: flatcamGUI/PreferencesUI.py:2968 flatcamGUI/PreferencesUI.py:3768 msgid "Zeros" msgstr "Zeros" -#: flatcamGUI/PreferencesUI.py:1829 flatcamGUI/PreferencesUI.py:1839 -#: flatcamGUI/PreferencesUI.py:2416 flatcamGUI/PreferencesUI.py:2426 +#: flatcamGUI/PreferencesUI.py:2009 flatcamGUI/PreferencesUI.py:2019 +#: flatcamGUI/PreferencesUI.py:2596 flatcamGUI/PreferencesUI.py:2606 msgid "" "This sets the type of Gerber zeros.\n" "If LZ then Leading Zeros are removed and\n" @@ -9501,23 +10049,23 @@ msgstr "" "If TZ is checked then Trailing Zeros are removed\n" "and Leading Zeros are kept." -#: flatcamGUI/PreferencesUI.py:1836 flatcamGUI/PreferencesUI.py:2423 -#: flatcamGUI/PreferencesUI.py:2799 flatcamGUI/PreferencesUI.py:3500 +#: flatcamGUI/PreferencesUI.py:2016 flatcamGUI/PreferencesUI.py:2603 +#: flatcamGUI/PreferencesUI.py:2981 flatcamGUI/PreferencesUI.py:3778 #: flatcamTools/ToolPcbWizard.py:111 msgid "LZ" msgstr "LZ" -#: flatcamGUI/PreferencesUI.py:1837 flatcamGUI/PreferencesUI.py:2424 -#: flatcamGUI/PreferencesUI.py:2800 flatcamGUI/PreferencesUI.py:3501 +#: flatcamGUI/PreferencesUI.py:2017 flatcamGUI/PreferencesUI.py:2604 +#: flatcamGUI/PreferencesUI.py:2982 flatcamGUI/PreferencesUI.py:3779 #: flatcamTools/ToolPcbWizard.py:112 msgid "TZ" msgstr "TZ" -#: flatcamGUI/PreferencesUI.py:1855 +#: flatcamGUI/PreferencesUI.py:2035 msgid "Clean Apertures" msgstr "Clean Apertures" -#: flatcamGUI/PreferencesUI.py:1857 +#: flatcamGUI/PreferencesUI.py:2037 msgid "" "Will remove apertures that do not have geometry\n" "thus lowering the number of apertures in the Gerber object." @@ -9525,11 +10073,11 @@ msgstr "" "Will remove apertures that do not have geometry\n" "thus lowering the number of apertures in the Gerber object." -#: flatcamGUI/PreferencesUI.py:1863 +#: flatcamGUI/PreferencesUI.py:2043 msgid "Polarity change buffer" msgstr "Polarity change buffer" -#: flatcamGUI/PreferencesUI.py:1865 +#: flatcamGUI/PreferencesUI.py:2045 msgid "" "Will apply extra buffering for the\n" "solid geometry when we have polarity changes.\n" @@ -9541,17 +10089,17 @@ msgstr "" "May help loading Gerber files that otherwise\n" "do not load correctly." -#: flatcamGUI/PreferencesUI.py:1878 +#: flatcamGUI/PreferencesUI.py:2058 msgid "Gerber Object Color" msgstr "Gerber Object Color" -#: flatcamGUI/PreferencesUI.py:1884 flatcamGUI/PreferencesUI.py:2905 -#: flatcamGUI/PreferencesUI.py:3896 +#: flatcamGUI/PreferencesUI.py:2064 flatcamGUI/PreferencesUI.py:3087 +#: flatcamGUI/PreferencesUI.py:4176 msgid "Set the line color for plotted objects." msgstr "Set the line color for plotted objects." -#: flatcamGUI/PreferencesUI.py:1901 flatcamGUI/PreferencesUI.py:2922 -#: flatcamGUI/PreferencesUI.py:4553 flatcamGUI/PreferencesUI.py:4619 +#: flatcamGUI/PreferencesUI.py:2081 flatcamGUI/PreferencesUI.py:3104 +#: flatcamGUI/PreferencesUI.py:4846 flatcamGUI/PreferencesUI.py:4912 msgid "" "Set the fill color for plotted objects.\n" "First 6 digits are the color and the last 2\n" @@ -9561,34 +10109,29 @@ msgstr "" "First 6 digits are the color and the last 2\n" "digits are for alpha (transparency) level." -#: flatcamGUI/PreferencesUI.py:1920 flatcamGUI/PreferencesUI.py:2941 -#: flatcamGUI/PreferencesUI.py:4572 +#: flatcamGUI/PreferencesUI.py:2100 flatcamGUI/PreferencesUI.py:3123 +#: flatcamGUI/PreferencesUI.py:4865 msgid "Set the fill transparency for plotted objects." msgstr "Set the fill transparency for plotted objects." -#: flatcamGUI/PreferencesUI.py:2011 +#: flatcamGUI/PreferencesUI.py:2191 msgid "Gerber Options" msgstr "Gerber Options" -#: flatcamGUI/PreferencesUI.py:2085 flatcamGUI/PreferencesUI.py:4379 -#: flatcamGUI/PreferencesUI.py:5120 flatcamTools/ToolNonCopperClear.py:170 -msgid "Conv." -msgstr "Conv." - -#: flatcamGUI/PreferencesUI.py:2089 +#: flatcamGUI/PreferencesUI.py:2269 msgid "Combine Passes" msgstr "Combine Passes" -#: flatcamGUI/PreferencesUI.py:2177 +#: flatcamGUI/PreferencesUI.py:2357 msgid "Gerber Adv. Options" msgstr "Gerber Adv. Options" -#: flatcamGUI/PreferencesUI.py:2181 flatcamGUI/PreferencesUI.py:3278 -#: flatcamGUI/PreferencesUI.py:4179 +#: flatcamGUI/PreferencesUI.py:2361 flatcamGUI/PreferencesUI.py:3551 +#: flatcamGUI/PreferencesUI.py:4472 msgid "Advanced Options" msgstr "Advanced Options" -#: flatcamGUI/PreferencesUI.py:2183 +#: flatcamGUI/PreferencesUI.py:2363 msgid "" "A list of Gerber advanced parameters.\n" "Those parameters are available only for\n" @@ -9598,11 +10141,11 @@ msgstr "" "Those parameters are available only for\n" "Advanced App. Level." -#: flatcamGUI/PreferencesUI.py:2202 +#: flatcamGUI/PreferencesUI.py:2382 msgid "Table Show/Hide" msgstr "Table Show/Hide" -#: flatcamGUI/PreferencesUI.py:2204 +#: flatcamGUI/PreferencesUI.py:2384 msgid "" "Toggle the display of the Gerber Apertures Table.\n" "Also, on hide, it will delete all mark shapes\n" @@ -9612,15 +10155,15 @@ msgstr "" "Also, on hide, it will delete all mark shapes\n" "that are drawn on canvas." -#: flatcamGUI/PreferencesUI.py:2284 +#: flatcamGUI/PreferencesUI.py:2464 msgid "Exterior" msgstr "Exterior" -#: flatcamGUI/PreferencesUI.py:2285 +#: flatcamGUI/PreferencesUI.py:2465 msgid "Interior" msgstr "Interior" -#: flatcamGUI/PreferencesUI.py:2298 +#: flatcamGUI/PreferencesUI.py:2478 msgid "" "Buffering type:\n" "- None --> best performance, fast file loading but no so good display\n" @@ -9632,19 +10175,19 @@ msgstr "" "- Full --> slow file loading but good visuals. This is the default.\n" "<>: Don't change this unless you know what you are doing !!!" -#: flatcamGUI/PreferencesUI.py:2303 flatcamGUI/PreferencesUI.py:5852 -#: flatcamGUI/PreferencesUI.py:7446 flatcamTools/ToolFiducials.py:201 -#: flatcamTools/ToolFilm.py:255 flatcamTools/ToolProperties.py:411 -#: flatcamTools/ToolProperties.py:426 flatcamTools/ToolProperties.py:429 -#: flatcamTools/ToolProperties.py:432 flatcamTools/ToolProperties.py:456 +#: flatcamGUI/PreferencesUI.py:2483 flatcamGUI/PreferencesUI.py:6340 +#: flatcamGUI/PreferencesUI.py:7952 flatcamTools/ToolFiducials.py:201 +#: flatcamTools/ToolFilm.py:255 flatcamTools/ToolProperties.py:452 +#: flatcamTools/ToolProperties.py:455 flatcamTools/ToolProperties.py:458 +#: flatcamTools/ToolProperties.py:483 msgid "None" msgstr "None" -#: flatcamGUI/PreferencesUI.py:2309 +#: flatcamGUI/PreferencesUI.py:2489 msgid "Simplify" msgstr "Simplify" -#: flatcamGUI/PreferencesUI.py:2311 +#: flatcamGUI/PreferencesUI.py:2491 msgid "" "When checked all the Gerber polygons will be\n" "loaded with simplification having a set tolerance.\n" @@ -9654,23 +10197,23 @@ msgstr "" "loaded with simplification having a set tolerance.\n" "<>: Don't change this unless you know what you are doing !!!" -#: flatcamGUI/PreferencesUI.py:2318 +#: flatcamGUI/PreferencesUI.py:2498 msgid "Tolerance" msgstr "Tolerance" -#: flatcamGUI/PreferencesUI.py:2319 +#: flatcamGUI/PreferencesUI.py:2499 msgid "Tolerance for polygon simplification." msgstr "Tolerance for polygon simplification." -#: flatcamGUI/PreferencesUI.py:2344 +#: flatcamGUI/PreferencesUI.py:2524 msgid "Gerber Export" msgstr "Gerber Export" -#: flatcamGUI/PreferencesUI.py:2348 flatcamGUI/PreferencesUI.py:3406 +#: flatcamGUI/PreferencesUI.py:2528 flatcamGUI/PreferencesUI.py:3684 msgid "Export Options" msgstr "Export Options" -#: flatcamGUI/PreferencesUI.py:2350 +#: flatcamGUI/PreferencesUI.py:2530 msgid "" "The parameters set here are used in the file exported\n" "when using the File -> Export -> Export Gerber menu entry." @@ -9678,11 +10221,11 @@ msgstr "" "The parameters set here are used in the file exported\n" "when using the File -> Export -> Export Gerber menu entry." -#: flatcamGUI/PreferencesUI.py:2373 flatcamGUI/PreferencesUI.py:3431 +#: flatcamGUI/PreferencesUI.py:2553 flatcamGUI/PreferencesUI.py:3709 msgid "Int/Decimals" msgstr "Int/Decimals" -#: flatcamGUI/PreferencesUI.py:2375 +#: flatcamGUI/PreferencesUI.py:2555 msgid "" "The number of digits in the whole part of the number\n" "and in the fractional part of the number." @@ -9690,7 +10233,7 @@ msgstr "" "The number of digits in the whole part of the number\n" "and in the fractional part of the number." -#: flatcamGUI/PreferencesUI.py:2388 +#: flatcamGUI/PreferencesUI.py:2568 msgid "" "This numbers signify the number of digits in\n" "the whole part of Gerber coordinates." @@ -9698,7 +10241,7 @@ msgstr "" "This numbers signify the number of digits in\n" "the whole part of Gerber coordinates." -#: flatcamGUI/PreferencesUI.py:2404 +#: flatcamGUI/PreferencesUI.py:2584 msgid "" "This numbers signify the number of digits in\n" "the decimal part of Gerber coordinates." @@ -9706,16 +10249,16 @@ msgstr "" "This numbers signify the number of digits in\n" "the decimal part of Gerber coordinates." -#: flatcamGUI/PreferencesUI.py:2449 +#: flatcamGUI/PreferencesUI.py:2629 msgid "A list of Gerber Editor parameters." msgstr "A list of Gerber Editor parameters." -#: flatcamGUI/PreferencesUI.py:2457 flatcamGUI/PreferencesUI.py:3565 -#: flatcamGUI/PreferencesUI.py:4357 flatcamGUI/PreferencesUI.py:7109 +#: flatcamGUI/PreferencesUI.py:2637 flatcamGUI/PreferencesUI.py:3843 +#: flatcamGUI/PreferencesUI.py:4650 flatcamGUI/PreferencesUI.py:7615 msgid "Selection limit" msgstr "Selection limit" -#: flatcamGUI/PreferencesUI.py:2459 +#: flatcamGUI/PreferencesUI.py:2639 msgid "" "Set the number of selected Gerber geometry\n" "items above which the utility geometry\n" @@ -9729,23 +10272,23 @@ msgstr "" "Increases the performance when moving a\n" "large number of geometric elements." -#: flatcamGUI/PreferencesUI.py:2472 +#: flatcamGUI/PreferencesUI.py:2652 msgid "New Aperture code" msgstr "New Aperture code" -#: flatcamGUI/PreferencesUI.py:2485 +#: flatcamGUI/PreferencesUI.py:2665 msgid "New Aperture size" msgstr "New Aperture size" -#: flatcamGUI/PreferencesUI.py:2487 +#: flatcamGUI/PreferencesUI.py:2667 msgid "Size for the new aperture" msgstr "Size for the new aperture" -#: flatcamGUI/PreferencesUI.py:2498 +#: flatcamGUI/PreferencesUI.py:2678 msgid "New Aperture type" msgstr "New Aperture type" -#: flatcamGUI/PreferencesUI.py:2500 +#: flatcamGUI/PreferencesUI.py:2680 msgid "" "Type for the new aperture.\n" "Can be 'C', 'R' or 'O'." @@ -9753,35 +10296,42 @@ msgstr "" "Type for the new aperture.\n" "Can be 'C', 'R' or 'O'." -#: flatcamGUI/PreferencesUI.py:2522 +#: flatcamGUI/PreferencesUI.py:2702 msgid "Aperture Dimensions" msgstr "Aperture Dimensions" -#: flatcamGUI/PreferencesUI.py:2524 flatcamGUI/PreferencesUI.py:3877 -#: flatcamGUI/PreferencesUI.py:5029 -msgid "Diameters of the cutting tools, separated by ','" -msgstr "Diameters of the cutting tools, separated by ','" +#: flatcamGUI/PreferencesUI.py:2704 flatcamGUI/PreferencesUI.py:4155 +#: flatcamGUI/PreferencesUI.py:5322 flatcamGUI/PreferencesUI.py:5889 +#: flatcamGUI/PreferencesUI.py:6955 +msgid "" +"Diameters of the tools, separated by comma.\n" +"The value of the diameter has to use the dot decimals separator.\n" +"Valid values: 0.3, 1.0" +msgstr "" +"Diameters of the tools, separated by comma.\n" +"The value of the diameter has to use the dot decimals separator.\n" +"Valid values: 0.3, 1.0" -#: flatcamGUI/PreferencesUI.py:2530 +#: flatcamGUI/PreferencesUI.py:2712 msgid "Linear Pad Array" msgstr "Linear Pad Array" -#: flatcamGUI/PreferencesUI.py:2534 flatcamGUI/PreferencesUI.py:3609 -#: flatcamGUI/PreferencesUI.py:3757 +#: flatcamGUI/PreferencesUI.py:2716 flatcamGUI/PreferencesUI.py:3887 +#: flatcamGUI/PreferencesUI.py:4035 msgid "Linear Direction" msgstr "Linear Direction" -#: flatcamGUI/PreferencesUI.py:2574 +#: flatcamGUI/PreferencesUI.py:2756 msgid "Circular Pad Array" msgstr "Circular Pad Array" -#: flatcamGUI/PreferencesUI.py:2578 flatcamGUI/PreferencesUI.py:3655 -#: flatcamGUI/PreferencesUI.py:3805 +#: flatcamGUI/PreferencesUI.py:2760 flatcamGUI/PreferencesUI.py:3933 +#: flatcamGUI/PreferencesUI.py:4083 msgid "Circular Direction" msgstr "Circular Direction" -#: flatcamGUI/PreferencesUI.py:2580 flatcamGUI/PreferencesUI.py:3657 -#: flatcamGUI/PreferencesUI.py:3807 +#: flatcamGUI/PreferencesUI.py:2762 flatcamGUI/PreferencesUI.py:3935 +#: flatcamGUI/PreferencesUI.py:4085 msgid "" "Direction for circular array.\n" "Can be CW = clockwise or CCW = counter clockwise." @@ -9789,48 +10339,48 @@ msgstr "" "Direction for circular array.\n" "Can be CW = clockwise or CCW = counter clockwise." -#: flatcamGUI/PreferencesUI.py:2591 flatcamGUI/PreferencesUI.py:3668 -#: flatcamGUI/PreferencesUI.py:3818 +#: flatcamGUI/PreferencesUI.py:2773 flatcamGUI/PreferencesUI.py:3946 +#: flatcamGUI/PreferencesUI.py:4096 msgid "Circular Angle" msgstr "Circular Angle" -#: flatcamGUI/PreferencesUI.py:2610 +#: flatcamGUI/PreferencesUI.py:2792 msgid "Distance at which to buffer the Gerber element." msgstr "Distance at which to buffer the Gerber element." -#: flatcamGUI/PreferencesUI.py:2619 +#: flatcamGUI/PreferencesUI.py:2801 msgid "Scale Tool" msgstr "Scale Tool" -#: flatcamGUI/PreferencesUI.py:2625 +#: flatcamGUI/PreferencesUI.py:2807 msgid "Factor to scale the Gerber element." msgstr "Factor to scale the Gerber element." -#: flatcamGUI/PreferencesUI.py:2638 +#: flatcamGUI/PreferencesUI.py:2820 msgid "Threshold low" msgstr "Threshold low" -#: flatcamGUI/PreferencesUI.py:2640 +#: flatcamGUI/PreferencesUI.py:2822 msgid "Threshold value under which the apertures are not marked." msgstr "Threshold value under which the apertures are not marked." -#: flatcamGUI/PreferencesUI.py:2650 +#: flatcamGUI/PreferencesUI.py:2832 msgid "Threshold high" msgstr "Threshold high" -#: flatcamGUI/PreferencesUI.py:2652 +#: flatcamGUI/PreferencesUI.py:2834 msgid "Threshold value over which the apertures are not marked." msgstr "Threshold value over which the apertures are not marked." -#: flatcamGUI/PreferencesUI.py:2670 +#: flatcamGUI/PreferencesUI.py:2852 msgid "Excellon General" msgstr "Excellon General" -#: flatcamGUI/PreferencesUI.py:2703 +#: flatcamGUI/PreferencesUI.py:2885 msgid "Excellon Format" msgstr "Excellon Format" -#: flatcamGUI/PreferencesUI.py:2705 +#: flatcamGUI/PreferencesUI.py:2887 msgid "" "The NC drill files, usually named Excellon files\n" "are files that can be found in different formats.\n" @@ -9872,12 +10422,12 @@ msgstr "" "Sprint Layout 2:4 INCH LZ\n" "KiCAD 3:5 INCH TZ" -#: flatcamGUI/PreferencesUI.py:2729 +#: flatcamGUI/PreferencesUI.py:2911 msgid "Default values for INCH are 2:4" msgstr "Default values for INCH are 2:4" -#: flatcamGUI/PreferencesUI.py:2736 flatcamGUI/PreferencesUI.py:2765 -#: flatcamGUI/PreferencesUI.py:3445 +#: flatcamGUI/PreferencesUI.py:2918 flatcamGUI/PreferencesUI.py:2947 +#: flatcamGUI/PreferencesUI.py:3723 msgid "" "This numbers signify the number of digits in\n" "the whole part of Excellon coordinates." @@ -9885,8 +10435,8 @@ msgstr "" "This numbers signify the number of digits in\n" "the whole part of Excellon coordinates." -#: flatcamGUI/PreferencesUI.py:2749 flatcamGUI/PreferencesUI.py:2778 -#: flatcamGUI/PreferencesUI.py:3458 +#: flatcamGUI/PreferencesUI.py:2931 flatcamGUI/PreferencesUI.py:2960 +#: flatcamGUI/PreferencesUI.py:3736 msgid "" "This numbers signify the number of digits in\n" "the decimal part of Excellon coordinates." @@ -9894,21 +10444,15 @@ msgstr "" "This numbers signify the number of digits in\n" "the decimal part of Excellon coordinates." -#: flatcamGUI/PreferencesUI.py:2757 +#: flatcamGUI/PreferencesUI.py:2939 msgid "METRIC" msgstr "METRIC" -#: flatcamGUI/PreferencesUI.py:2758 +#: flatcamGUI/PreferencesUI.py:2940 msgid "Default values for METRIC are 3:3" msgstr "Default values for METRIC are 3:3" -#: flatcamGUI/PreferencesUI.py:2789 -#| msgid "" -#| "This sets the type of Excellon zeros.\n" -#| "If LZ then Leading Zeros are kept and\n" -#| "Trailing Zeros are removed.\n" -#| "If TZ is checked then Trailing Zeros are kept\n" -#| "and Leading Zeros are removed." +#: flatcamGUI/PreferencesUI.py:2971 msgid "" "This sets the type of Excellon zeros.\n" "If LZ then Leading Zeros are kept and\n" @@ -9928,7 +10472,7 @@ msgstr "" "This is used when there is no information\n" "stored in the Excellon file." -#: flatcamGUI/PreferencesUI.py:2807 +#: flatcamGUI/PreferencesUI.py:2989 msgid "" "This sets the default units of Excellon files.\n" "If it is not detected in the parsed file the value here\n" @@ -9940,7 +10484,7 @@ msgstr "" "will be used.Some Excellon files don't have an header\n" "therefore this parameter will be used." -#: flatcamGUI/PreferencesUI.py:2817 +#: flatcamGUI/PreferencesUI.py:2999 msgid "" "This sets the units of Excellon files.\n" "Some Excellon files don't have an header\n" @@ -9950,19 +10494,19 @@ msgstr "" "Some Excellon files don't have an header\n" "therefore this parameter will be used." -#: flatcamGUI/PreferencesUI.py:2825 +#: flatcamGUI/PreferencesUI.py:3007 msgid "Update Export settings" msgstr "Update Export settings" -#: flatcamGUI/PreferencesUI.py:2842 +#: flatcamGUI/PreferencesUI.py:3024 msgid "Excellon Optimization" msgstr "Excellon Optimization" -#: flatcamGUI/PreferencesUI.py:2845 +#: flatcamGUI/PreferencesUI.py:3027 msgid "Algorithm:" msgstr "Algorithm:" -#: flatcamGUI/PreferencesUI.py:2847 flatcamGUI/PreferencesUI.py:2863 +#: flatcamGUI/PreferencesUI.py:3029 flatcamGUI/PreferencesUI.py:3045 msgid "" "This sets the optimization type for the Excellon drill path.\n" "If <> is checked then Google OR-Tools algorithm with\n" @@ -9984,20 +10528,20 @@ msgstr "" "If this control is disabled, then FlatCAM works in 32bit mode and it uses\n" "Travelling Salesman algorithm for path optimization." -#: flatcamGUI/PreferencesUI.py:2858 +#: flatcamGUI/PreferencesUI.py:3040 msgid "MetaHeuristic" msgstr "MetaHeuristic" -#: flatcamGUI/PreferencesUI.py:2860 +#: flatcamGUI/PreferencesUI.py:3042 msgid "TSA" msgstr "TSA" -#: flatcamGUI/PreferencesUI.py:2877 flatcamGUI/PreferencesUI.py:3192 -#: flatcamGUI/PreferencesUI.py:4138 +#: flatcamGUI/PreferencesUI.py:3059 flatcamGUI/PreferencesUI.py:3463 +#: flatcamGUI/PreferencesUI.py:4430 msgid "Duration" msgstr "Duration" -#: flatcamGUI/PreferencesUI.py:2880 +#: flatcamGUI/PreferencesUI.py:3062 msgid "" "When OR-Tools Metaheuristic (MH) is enabled there is a\n" "maximum threshold for how much time is spent doing the\n" @@ -10009,15 +10553,19 @@ msgstr "" "path optimization. This max duration is set here.\n" "In seconds." -#: flatcamGUI/PreferencesUI.py:2899 +#: flatcamGUI/PreferencesUI.py:3081 msgid "Excellon Object Color" msgstr "Excellon Object Color" -#: flatcamGUI/PreferencesUI.py:3065 +#: flatcamGUI/PreferencesUI.py:3247 msgid "Excellon Options" msgstr "Excellon Options" -#: flatcamGUI/PreferencesUI.py:3071 +#: flatcamGUI/PreferencesUI.py:3251 flatcamGUI/PreferencesUI.py:4227 +msgid "Create CNC Job" +msgstr "Create CNC Job" + +#: flatcamGUI/PreferencesUI.py:3253 msgid "" "Parameters used to create a CNC Job object\n" "for this drill object." @@ -10025,12 +10573,27 @@ msgstr "" "Parameters used to create a CNC Job object\n" "for this drill object." -#: flatcamGUI/PreferencesUI.py:3185 flatcamGUI/PreferencesUI.py:4133 -#| msgid "Enable Plot" +#: flatcamGUI/PreferencesUI.py:3370 flatcamGUI/PreferencesUI.py:4314 +msgid "Tool change" +msgstr "Tool change" + +#: flatcamGUI/PreferencesUI.py:3454 flatcamGUI/PreferencesUI.py:4425 msgid "Enable Dwell" msgstr "Enable Dwell" -#: flatcamGUI/PreferencesUI.py:3217 +#: flatcamGUI/PreferencesUI.py:3477 +msgid "" +"The preprocessor JSON file that dictates\n" +"Gcode output." +msgstr "" +"The preprocessor JSON file that dictates\n" +"Gcode output." + +#: flatcamGUI/PreferencesUI.py:3488 +msgid "Gcode" +msgstr "Gcode" + +#: flatcamGUI/PreferencesUI.py:3490 msgid "" "Choose what to use for GCode generation:\n" "'Drills', 'Slots' or 'Both'.\n" @@ -10042,15 +10605,35 @@ msgstr "" "When choosing 'Slots' or 'Both', slots will be\n" "converted to drills." -#: flatcamGUI/PreferencesUI.py:3235 +#: flatcamGUI/PreferencesUI.py:3506 +msgid "Mill Holes" +msgstr "Mill Holes" + +#: flatcamGUI/PreferencesUI.py:3508 msgid "Create Geometry for milling holes." msgstr "Create Geometry for milling holes." -#: flatcamGUI/PreferencesUI.py:3271 +#: flatcamGUI/PreferencesUI.py:3512 +msgid "Drill Tool dia" +msgstr "Drill Tool dia" + +#: flatcamGUI/PreferencesUI.py:3523 +msgid "Slot Tool dia" +msgstr "Slot Tool dia" + +#: flatcamGUI/PreferencesUI.py:3525 +msgid "" +"Diameter of the cutting tool\n" +"when milling slots." +msgstr "" +"Diameter of the cutting tool\n" +"when milling slots." + +#: flatcamGUI/PreferencesUI.py:3544 msgid "Excellon Adv. Options" msgstr "Excellon Adv. Options" -#: flatcamGUI/PreferencesUI.py:3280 +#: flatcamGUI/PreferencesUI.py:3553 msgid "" "A list of Excellon advanced parameters.\n" "Those parameters are available only for\n" @@ -10060,19 +10643,19 @@ msgstr "" "Those parameters are available only for\n" "Advanced App. Level." -#: flatcamGUI/PreferencesUI.py:3301 +#: flatcamGUI/PreferencesUI.py:3576 msgid "Toolchange X,Y" msgstr "Toolchange X,Y" -#: flatcamGUI/PreferencesUI.py:3303 flatcamGUI/PreferencesUI.py:4193 +#: flatcamGUI/PreferencesUI.py:3578 flatcamGUI/PreferencesUI.py:4486 msgid "Toolchange X,Y position." msgstr "Toolchange X,Y position." -#: flatcamGUI/PreferencesUI.py:3360 flatcamGUI/PreferencesUI.py:4280 +#: flatcamGUI/PreferencesUI.py:3638 flatcamGUI/PreferencesUI.py:4573 msgid "Spindle direction" msgstr "Spindle direction" -#: flatcamGUI/PreferencesUI.py:3362 flatcamGUI/PreferencesUI.py:4282 +#: flatcamGUI/PreferencesUI.py:3640 flatcamGUI/PreferencesUI.py:4575 msgid "" "This sets the direction that the spindle is rotating.\n" "It can be either:\n" @@ -10084,11 +10667,11 @@ msgstr "" "- CW = clockwise or\n" "- CCW = counter clockwise" -#: flatcamGUI/PreferencesUI.py:3373 flatcamGUI/PreferencesUI.py:4294 +#: flatcamGUI/PreferencesUI.py:3651 flatcamGUI/PreferencesUI.py:4587 msgid "Fast Plunge" msgstr "Fast Plunge" -#: flatcamGUI/PreferencesUI.py:3375 flatcamGUI/PreferencesUI.py:4296 +#: flatcamGUI/PreferencesUI.py:3653 flatcamGUI/PreferencesUI.py:4589 msgid "" "By checking this, the vertical move from\n" "Z_Toolchange to Z_move is done with G0,\n" @@ -10100,11 +10683,11 @@ msgstr "" "meaning the fastest speed available.\n" "WARNING: the move is done at Toolchange X,Y coords." -#: flatcamGUI/PreferencesUI.py:3382 +#: flatcamGUI/PreferencesUI.py:3660 msgid "Fast Retract" msgstr "Fast Retract" -#: flatcamGUI/PreferencesUI.py:3384 +#: flatcamGUI/PreferencesUI.py:3662 msgid "" "Exit hole strategy.\n" " - When uncheked, while exiting the drilled hole the drill bit\n" @@ -10120,11 +10703,11 @@ msgstr "" " - When checked the travel from Z cut (cut depth) to Z_move\n" "(travel height) is done as fast as possible (G0) in one move." -#: flatcamGUI/PreferencesUI.py:3402 +#: flatcamGUI/PreferencesUI.py:3680 msgid "Excellon Export" msgstr "Excellon Export" -#: flatcamGUI/PreferencesUI.py:3408 +#: flatcamGUI/PreferencesUI.py:3686 msgid "" "The parameters set here are used in the file exported\n" "when using the File -> Export -> Export Excellon menu entry." @@ -10132,11 +10715,11 @@ msgstr "" "The parameters set here are used in the file exported\n" "when using the File -> Export -> Export Excellon menu entry." -#: flatcamGUI/PreferencesUI.py:3419 flatcamGUI/PreferencesUI.py:3425 +#: flatcamGUI/PreferencesUI.py:3697 flatcamGUI/PreferencesUI.py:3703 msgid "The units used in the Excellon file." msgstr "The units used in the Excellon file." -#: flatcamGUI/PreferencesUI.py:3433 +#: flatcamGUI/PreferencesUI.py:3711 msgid "" "The NC drill files, usually named Excellon files\n" "are files that can be found in different formats.\n" @@ -10148,11 +10731,11 @@ msgstr "" "Here we set the format used when the provided\n" "coordinates are not using period." -#: flatcamGUI/PreferencesUI.py:3467 +#: flatcamGUI/PreferencesUI.py:3745 msgid "Format" msgstr "Format" -#: flatcamGUI/PreferencesUI.py:3469 flatcamGUI/PreferencesUI.py:3479 +#: flatcamGUI/PreferencesUI.py:3747 flatcamGUI/PreferencesUI.py:3757 msgid "" "Select the kind of coordinates format used.\n" "Coordinates can be saved with decimal point or without.\n" @@ -10168,15 +10751,15 @@ msgstr "" "Also it will have to be specified if LZ = leading zeros are kept\n" "or TZ = trailing zeros are kept." -#: flatcamGUI/PreferencesUI.py:3476 +#: flatcamGUI/PreferencesUI.py:3754 msgid "Decimal" msgstr "Decimal" -#: flatcamGUI/PreferencesUI.py:3477 +#: flatcamGUI/PreferencesUI.py:3755 msgid "No-Decimal" msgstr "No-Decimal" -#: flatcamGUI/PreferencesUI.py:3493 +#: flatcamGUI/PreferencesUI.py:3771 msgid "" "This sets the type of Excellon zeros.\n" "If LZ then Leading Zeros are kept and\n" @@ -10190,7 +10773,7 @@ msgstr "" "If TZ is checked then Trailing Zeros are kept\n" "and Leading Zeros are removed." -#: flatcamGUI/PreferencesUI.py:3503 +#: flatcamGUI/PreferencesUI.py:3781 msgid "" "This sets the default type of Excellon zeros.\n" "If LZ then Leading Zeros are kept and\n" @@ -10204,11 +10787,11 @@ msgstr "" "If TZ is checked then Trailing Zeros are kept\n" "and Leading Zeros are removed." -#: flatcamGUI/PreferencesUI.py:3513 +#: flatcamGUI/PreferencesUI.py:3791 msgid "Slot type" msgstr "Slot type" -#: flatcamGUI/PreferencesUI.py:3516 flatcamGUI/PreferencesUI.py:3526 +#: flatcamGUI/PreferencesUI.py:3794 flatcamGUI/PreferencesUI.py:3804 msgid "" "This sets how the slots will be exported.\n" "If ROUTED then the slots will be routed\n" @@ -10222,19 +10805,19 @@ msgstr "" "If DRILLED(G85) the slots will be exported\n" "using the Drilled slot command (G85)." -#: flatcamGUI/PreferencesUI.py:3523 +#: flatcamGUI/PreferencesUI.py:3801 msgid "Routed" msgstr "Routed" -#: flatcamGUI/PreferencesUI.py:3524 +#: flatcamGUI/PreferencesUI.py:3802 msgid "Drilled(G85)" msgstr "Drilled(G85)" -#: flatcamGUI/PreferencesUI.py:3557 +#: flatcamGUI/PreferencesUI.py:3835 msgid "A list of Excellon Editor parameters." msgstr "A list of Excellon Editor parameters." -#: flatcamGUI/PreferencesUI.py:3567 +#: flatcamGUI/PreferencesUI.py:3845 msgid "" "Set the number of selected Excellon geometry\n" "items above which the utility geometry\n" @@ -10248,19 +10831,21 @@ msgstr "" "Increases the performance when moving a\n" "large number of geometric elements." -#: flatcamGUI/PreferencesUI.py:3580 flatcamGUI/PreferencesUI.py:5100 -msgid "New Tool Dia" -msgstr "New Tool Dia" +#: flatcamGUI/PreferencesUI.py:3858 flatcamGUI/PreferencesUI.py:5396 +#: flatcamGUI/PreferencesUI.py:5962 +#| msgid "New Tool Dia" +msgid "New Dia" +msgstr "New Dia" -#: flatcamGUI/PreferencesUI.py:3605 +#: flatcamGUI/PreferencesUI.py:3883 msgid "Linear Drill Array" msgstr "Linear Drill Array" -#: flatcamGUI/PreferencesUI.py:3651 +#: flatcamGUI/PreferencesUI.py:3929 msgid "Circular Drill Array" msgstr "Circular Drill Array" -#: flatcamGUI/PreferencesUI.py:3721 +#: flatcamGUI/PreferencesUI.py:3999 msgid "" "Angle at which the slot is placed.\n" "The precision is of max 2 decimals.\n" @@ -10272,19 +10857,19 @@ msgstr "" "Min value is: -359.99 degrees.\n" "Max value is: 360.00 degrees." -#: flatcamGUI/PreferencesUI.py:3740 +#: flatcamGUI/PreferencesUI.py:4018 msgid "Linear Slot Array" msgstr "Linear Slot Array" -#: flatcamGUI/PreferencesUI.py:3801 +#: flatcamGUI/PreferencesUI.py:4079 msgid "Circular Slot Array" msgstr "Circular Slot Array" -#: flatcamGUI/PreferencesUI.py:3839 +#: flatcamGUI/PreferencesUI.py:4117 msgid "Geometry General" msgstr "Geometry General" -#: flatcamGUI/PreferencesUI.py:3861 +#: flatcamGUI/PreferencesUI.py:4139 msgid "" "The number of circle steps for Geometry \n" "circle and arc shapes linear approximation." @@ -10292,15 +10877,21 @@ msgstr "" "The number of circle steps for Geometry \n" "circle and arc shapes linear approximation." -#: flatcamGUI/PreferencesUI.py:3890 +#: flatcamGUI/PreferencesUI.py:4153 flatcamGUI/PreferencesUI.py:5320 +#: flatcamGUI/PreferencesUI.py:5887 flatcamGUI/PreferencesUI.py:6953 +#| msgid "Tool Dia" +msgid "Tools Dia" +msgstr "Tools Dia" + +#: flatcamGUI/PreferencesUI.py:4170 msgid "Geometry Object Color" msgstr "Geometry Object Color" -#: flatcamGUI/PreferencesUI.py:3941 +#: flatcamGUI/PreferencesUI.py:4221 msgid "Geometry Options" msgstr "Geometry Options" -#: flatcamGUI/PreferencesUI.py:3949 +#: flatcamGUI/PreferencesUI.py:4229 msgid "" "Create a CNC Job object\n" "tracing the contours of this\n" @@ -10310,11 +10901,11 @@ msgstr "" "tracing the contours of this\n" "Geometry object." -#: flatcamGUI/PreferencesUI.py:3993 +#: flatcamGUI/PreferencesUI.py:4273 msgid "Depth/Pass" msgstr "Depth/Pass" -#: flatcamGUI/PreferencesUI.py:3995 +#: flatcamGUI/PreferencesUI.py:4275 msgid "" "The depth to cut on each pass,\n" "when multidepth is enabled.\n" @@ -10328,11 +10919,11 @@ msgstr "" "it is a fraction from the depth\n" "which has negative value." -#: flatcamGUI/PreferencesUI.py:4173 +#: flatcamGUI/PreferencesUI.py:4466 msgid "Geometry Adv. Options" msgstr "Geometry Adv. Options" -#: flatcamGUI/PreferencesUI.py:4181 +#: flatcamGUI/PreferencesUI.py:4474 msgid "" "A list of Geometry advanced parameters.\n" "Those parameters are available only for\n" @@ -10342,13 +10933,13 @@ msgstr "" "Those parameters are available only for\n" "Advanced App. Level." -#: flatcamGUI/PreferencesUI.py:4191 flatcamGUI/PreferencesUI.py:6539 -#: flatcamGUI/PreferencesUI.py:7586 flatcamTools/ToolCalibration.py:125 -#: flatcamTools/ToolSolderPaste.py:239 +#: flatcamGUI/PreferencesUI.py:4484 flatcamGUI/PreferencesUI.py:7045 +#: flatcamGUI/PreferencesUI.py:8092 flatcamTools/ToolCalibration.py:125 +#: flatcamTools/ToolSolderPaste.py:241 msgid "Toolchange X-Y" msgstr "Toolchange X-Y" -#: flatcamGUI/PreferencesUI.py:4202 +#: flatcamGUI/PreferencesUI.py:4495 msgid "" "Height of the tool just after starting the work.\n" "Delete the value if you don't need this feature." @@ -10356,11 +10947,11 @@ msgstr "" "Height of the tool just after starting the work.\n" "Delete the value if you don't need this feature." -#: flatcamGUI/PreferencesUI.py:4304 +#: flatcamGUI/PreferencesUI.py:4597 msgid "Segment X size" msgstr "Segment X size" -#: flatcamGUI/PreferencesUI.py:4306 +#: flatcamGUI/PreferencesUI.py:4599 msgid "" "The size of the trace segment on the X axis.\n" "Useful for auto-leveling.\n" @@ -10370,11 +10961,11 @@ msgstr "" "Useful for auto-leveling.\n" "A value of 0 means no segmentation on the X axis." -#: flatcamGUI/PreferencesUI.py:4320 +#: flatcamGUI/PreferencesUI.py:4613 msgid "Segment Y size" msgstr "Segment Y size" -#: flatcamGUI/PreferencesUI.py:4322 +#: flatcamGUI/PreferencesUI.py:4615 msgid "" "The size of the trace segment on the Y axis.\n" "Useful for auto-leveling.\n" @@ -10384,15 +10975,11 @@ msgstr "" "Useful for auto-leveling.\n" "A value of 0 means no segmentation on the Y axis." -#: flatcamGUI/PreferencesUI.py:4343 -msgid "Geometry Editor" -msgstr "Geometry Editor" - -#: flatcamGUI/PreferencesUI.py:4349 +#: flatcamGUI/PreferencesUI.py:4642 msgid "A list of Geometry Editor parameters." msgstr "A list of Geometry Editor parameters." -#: flatcamGUI/PreferencesUI.py:4359 flatcamGUI/PreferencesUI.py:7111 +#: flatcamGUI/PreferencesUI.py:4652 flatcamGUI/PreferencesUI.py:7617 msgid "" "Set the number of selected geometry\n" "items above which the utility geometry\n" @@ -10406,11 +10993,11 @@ msgstr "" "Increases the performance when moving a\n" "large number of geometric elements." -#: flatcamGUI/PreferencesUI.py:4391 +#: flatcamGUI/PreferencesUI.py:4684 msgid "CNC Job General" msgstr "CNC Job General" -#: flatcamGUI/PreferencesUI.py:4444 +#: flatcamGUI/PreferencesUI.py:4737 msgid "" "The number of circle steps for GCode \n" "circle and arc shapes linear approximation." @@ -10418,11 +11005,11 @@ msgstr "" "The number of circle steps for GCode \n" "circle and arc shapes linear approximation." -#: flatcamGUI/PreferencesUI.py:4453 +#: flatcamGUI/PreferencesUI.py:4746 msgid "Travel dia" msgstr "Travel dia" -#: flatcamGUI/PreferencesUI.py:4455 +#: flatcamGUI/PreferencesUI.py:4748 msgid "" "The width of the travel lines to be\n" "rendered in the plot." @@ -10430,16 +11017,15 @@ msgstr "" "The width of the travel lines to be\n" "rendered in the plot." -#: flatcamGUI/PreferencesUI.py:4468 -#| msgid "No-Decimal" +#: flatcamGUI/PreferencesUI.py:4761 msgid "G-code Decimals" msgstr "G-code Decimals" -#: flatcamGUI/PreferencesUI.py:4471 flatcamTools/ToolFiducials.py:74 +#: flatcamGUI/PreferencesUI.py:4764 flatcamTools/ToolFiducials.py:74 msgid "Coordinates" msgstr "Coordinates" -#: flatcamGUI/PreferencesUI.py:4473 +#: flatcamGUI/PreferencesUI.py:4766 msgid "" "The number of decimals to be used for \n" "the X, Y, Z coordinates in CNC code (GCODE, etc.)" @@ -10447,11 +11033,11 @@ msgstr "" "The number of decimals to be used for \n" "the X, Y, Z coordinates in CNC code (GCODE, etc.)" -#: flatcamGUI/PreferencesUI.py:4484 flatcamTools/ToolProperties.py:492 +#: flatcamGUI/PreferencesUI.py:4777 flatcamTools/ToolProperties.py:519 msgid "Feedrate" msgstr "Feedrate" -#: flatcamGUI/PreferencesUI.py:4486 +#: flatcamGUI/PreferencesUI.py:4779 msgid "" "The number of decimals to be used for \n" "the Feedrate parameter in CNC code (GCODE, etc.)" @@ -10459,11 +11045,11 @@ msgstr "" "The number of decimals to be used for \n" "the Feedrate parameter in CNC code (GCODE, etc.)" -#: flatcamGUI/PreferencesUI.py:4497 +#: flatcamGUI/PreferencesUI.py:4790 msgid "Coordinates type" msgstr "Coordinates type" -#: flatcamGUI/PreferencesUI.py:4499 +#: flatcamGUI/PreferencesUI.py:4792 msgid "" "The type of coordinates to be used in Gcode.\n" "Can be:\n" @@ -10475,19 +11061,19 @@ msgstr "" "- Absolute G90 -> the reference is the origin x=0, y=0\n" "- Incremental G91 -> the reference is the previous position" -#: flatcamGUI/PreferencesUI.py:4505 +#: flatcamGUI/PreferencesUI.py:4798 msgid "Absolute G90" msgstr "Absolute G90" -#: flatcamGUI/PreferencesUI.py:4506 +#: flatcamGUI/PreferencesUI.py:4799 msgid "Incremental G91" msgstr "Incremental G91" -#: flatcamGUI/PreferencesUI.py:4516 +#: flatcamGUI/PreferencesUI.py:4809 msgid "Force Windows style line-ending" msgstr "Force Windows style line-ending" -#: flatcamGUI/PreferencesUI.py:4518 +#: flatcamGUI/PreferencesUI.py:4811 msgid "" "When checked will force a Windows style line-ending\n" "(\\r\\n) on non-Windows OS's." @@ -10495,35 +11081,35 @@ msgstr "" "When checked will force a Windows style line-ending\n" "(\\r\\n) on non-Windows OS's." -#: flatcamGUI/PreferencesUI.py:4530 +#: flatcamGUI/PreferencesUI.py:4823 msgid "Travel Line Color" msgstr "Travel Line Color" -#: flatcamGUI/PreferencesUI.py:4536 +#: flatcamGUI/PreferencesUI.py:4829 msgid "Set the travel line color for plotted objects." msgstr "Set the travel line color for plotted objects." -#: flatcamGUI/PreferencesUI.py:4596 +#: flatcamGUI/PreferencesUI.py:4889 msgid "CNCJob Object Color" msgstr "CNCJob Object Color" -#: flatcamGUI/PreferencesUI.py:4602 +#: flatcamGUI/PreferencesUI.py:4895 msgid "Set the color for plotted objects." msgstr "Set the color for plotted objects." -#: flatcamGUI/PreferencesUI.py:4762 +#: flatcamGUI/PreferencesUI.py:5055 msgid "CNC Job Options" msgstr "CNC Job Options" -#: flatcamGUI/PreferencesUI.py:4766 +#: flatcamGUI/PreferencesUI.py:5059 msgid "Export G-Code" msgstr "Export G-Code" -#: flatcamGUI/PreferencesUI.py:4782 +#: flatcamGUI/PreferencesUI.py:5075 msgid "Prepend to G-Code" msgstr "Prepend to G-Code" -#: flatcamGUI/PreferencesUI.py:4791 +#: flatcamGUI/PreferencesUI.py:5084 msgid "" "Type here any G-Code commands you would like to add at the beginning of the " "G-Code file." @@ -10531,15 +11117,11 @@ msgstr "" "Type here any G-Code commands you would like to add at the beginning of the " "G-Code file." -#: flatcamGUI/PreferencesUI.py:4798 +#: flatcamGUI/PreferencesUI.py:5091 msgid "Append to G-Code" msgstr "Append to G-Code" -#: flatcamGUI/PreferencesUI.py:4808 -#| msgid "" -#| "Type here any G-Code commands you would\n" -#| "like to append to the generated file.\n" -#| "I.e.: M2 (End of program)" +#: flatcamGUI/PreferencesUI.py:5101 msgid "" "Type here any G-Code commands you would like to append to the generated " "file.\n" @@ -10549,19 +11131,11 @@ msgstr "" "file.\n" "I.e.: M2 (End of program)" -#: flatcamGUI/PreferencesUI.py:4824 +#: flatcamGUI/PreferencesUI.py:5117 msgid "CNC Job Adv. Options" msgstr "CNC Job Adv. Options" -#: flatcamGUI/PreferencesUI.py:4861 -#| msgid "" -#| "Type here any G-Code commands you would\n" -#| "like to be executed when Toolchange event is encountered.\n" -#| "This will constitute a Custom Toolchange GCode,\n" -#| "or a Toolchange Macro.\n" -#| "The FlatCAM variables are surrounded by '%' symbol.\n" -#| "WARNING: it can be used only with a preprocessor file\n" -#| "that has 'toolchange_custom' in it's name." +#: flatcamGUI/PreferencesUI.py:5154 msgid "" "Type here any G-Code commands you would like to be executed when Toolchange " "event is encountered.\n" @@ -10577,45 +11151,46 @@ msgstr "" "WARNING: it can be used only with a preprocessor file that has " "'toolchange_custom' in it's name." -#: flatcamGUI/PreferencesUI.py:4916 +#: flatcamGUI/PreferencesUI.py:5209 msgid "Z depth for the cut" msgstr "Z depth for the cut" -#: flatcamGUI/PreferencesUI.py:4917 +#: flatcamGUI/PreferencesUI.py:5210 msgid "Z height for travel" msgstr "Z height for travel" -#: flatcamGUI/PreferencesUI.py:4923 +#: flatcamGUI/PreferencesUI.py:5216 msgid "dwelltime = time to dwell to allow the spindle to reach it's set RPM" msgstr "dwelltime = time to dwell to allow the spindle to reach it's set RPM" -#: flatcamGUI/PreferencesUI.py:4942 +#: flatcamGUI/PreferencesUI.py:5235 msgid "Annotation Size" msgstr "Annotation Size" -#: flatcamGUI/PreferencesUI.py:4944 +#: flatcamGUI/PreferencesUI.py:5237 msgid "The font size of the annotation text. In pixels." msgstr "The font size of the annotation text. In pixels." -#: flatcamGUI/PreferencesUI.py:4954 +#: flatcamGUI/PreferencesUI.py:5247 msgid "Annotation Color" msgstr "Annotation Color" -#: flatcamGUI/PreferencesUI.py:4956 +#: flatcamGUI/PreferencesUI.py:5249 msgid "Set the font color for the annotation texts." msgstr "Set the font color for the annotation texts." -#: flatcamGUI/PreferencesUI.py:5013 +#: flatcamGUI/PreferencesUI.py:5306 msgid "NCC Tool Options" msgstr "NCC Tool Options" -#: flatcamGUI/PreferencesUI.py:5027 flatcamGUI/PreferencesUI.py:6449 -msgid "Tools dia" -msgstr "Tools dia" +#: flatcamGUI/PreferencesUI.py:5328 flatcamGUI/PreferencesUI.py:5896 +msgid "Comma separated values" +msgstr "Comma separated values" -#: flatcamGUI/PreferencesUI.py:5038 flatcamGUI/PreferencesUI.py:5046 -#: flatcamTools/ToolNonCopperClear.py:215 -#: flatcamTools/ToolNonCopperClear.py:223 +#: flatcamGUI/PreferencesUI.py:5334 flatcamGUI/PreferencesUI.py:5342 +#: flatcamGUI/PreferencesUI.py:5903 flatcamTools/ToolNCC.py:215 +#: flatcamTools/ToolNCC.py:223 flatcamTools/ToolPaint.py:198 +#: flatcamTools/ToolPaint.py:206 msgid "" "Default tool type:\n" "- 'V-shape'\n" @@ -10625,13 +11200,15 @@ msgstr "" "- 'V-shape'\n" "- Circular" -#: flatcamGUI/PreferencesUI.py:5043 flatcamTools/ToolNonCopperClear.py:220 +#: flatcamGUI/PreferencesUI.py:5339 flatcamGUI/PreferencesUI.py:5908 +#: flatcamTools/ToolNCC.py:220 flatcamTools/ToolPaint.py:203 msgid "V-shape" msgstr "V-shape" -#: flatcamGUI/PreferencesUI.py:5083 flatcamGUI/PreferencesUI.py:5092 -#: flatcamTools/ToolNonCopperClear.py:256 -#: flatcamTools/ToolNonCopperClear.py:264 +#: flatcamGUI/PreferencesUI.py:5379 flatcamGUI/PreferencesUI.py:5388 +#: flatcamGUI/PreferencesUI.py:5946 flatcamGUI/PreferencesUI.py:5955 +#: flatcamTools/ToolNCC.py:262 flatcamTools/ToolNCC.py:271 +#: flatcamTools/ToolPaint.py:245 flatcamTools/ToolPaint.py:254 msgid "" "Depth of cut into material. Negative value.\n" "In FlatCAM units." @@ -10639,32 +11216,26 @@ msgstr "" "Depth of cut into material. Negative value.\n" "In FlatCAM units." -#: flatcamGUI/PreferencesUI.py:5102 -msgid "The new tool diameter (cut width) to add in the tool table." -msgstr "The new tool diameter (cut width) to add in the tool table." - -#: flatcamGUI/PreferencesUI.py:5114 flatcamGUI/PreferencesUI.py:5122 -#: flatcamTools/ToolNonCopperClear.py:164 -#: flatcamTools/ToolNonCopperClear.py:172 +#: flatcamGUI/PreferencesUI.py:5398 flatcamGUI/PreferencesUI.py:5964 +#: flatcamTools/ToolNCC.py:280 flatcamTools/ToolPaint.py:263 msgid "" -"Milling type when the selected tool is of type: 'iso_op':\n" -"- climb / best for precision milling and to reduce tool usage\n" -"- conventional / useful when there is no backlash compensation" +"Diameter for the new tool to add in the Tool Table.\n" +"If the tool is V-shape type then this value is automatically\n" +"calculated from the other parameters." msgstr "" -"Milling type when the selected tool is of type: 'iso_op':\n" -"- climb / best for precision milling and to reduce tool usage\n" -"- conventional / useful when there is no backlash compensation" +"Diameter for the new tool to add in the Tool Table.\n" +"If the tool is V-shape type then this value is automatically\n" +"calculated from the other parameters." -#: flatcamGUI/PreferencesUI.py:5131 flatcamGUI/PreferencesUI.py:5546 -#: flatcamTools/ToolNonCopperClear.py:181 flatcamTools/ToolPaint.py:153 +#: flatcamGUI/PreferencesUI.py:5435 flatcamGUI/PreferencesUI.py:5981 +#: flatcamTools/ToolNCC.py:174 flatcamTools/ToolPaint.py:158 msgid "Tool order" msgstr "Tool order" -#: flatcamGUI/PreferencesUI.py:5132 flatcamGUI/PreferencesUI.py:5142 -#: flatcamGUI/PreferencesUI.py:5547 flatcamGUI/PreferencesUI.py:5557 -#: flatcamTools/ToolNonCopperClear.py:182 -#: flatcamTools/ToolNonCopperClear.py:192 flatcamTools/ToolPaint.py:154 -#: flatcamTools/ToolPaint.py:164 +#: flatcamGUI/PreferencesUI.py:5436 flatcamGUI/PreferencesUI.py:5446 +#: flatcamGUI/PreferencesUI.py:5982 flatcamTools/ToolNCC.py:175 +#: flatcamTools/ToolNCC.py:185 flatcamTools/ToolPaint.py:159 +#: flatcamTools/ToolPaint.py:169 msgid "" "This set the way that the tools in the tools table are used.\n" "'No' --> means that the used order is the one in the tool table\n" @@ -10682,103 +11253,21 @@ msgstr "" "WARNING: using rest machining will automatically set the order\n" "in reverse and disable this control." -#: flatcamGUI/PreferencesUI.py:5140 flatcamGUI/PreferencesUI.py:5555 -#: flatcamTools/ToolNonCopperClear.py:190 flatcamTools/ToolPaint.py:162 +#: flatcamGUI/PreferencesUI.py:5444 flatcamGUI/PreferencesUI.py:5990 +#: flatcamTools/ToolNCC.py:183 flatcamTools/ToolPaint.py:167 msgid "Forward" msgstr "Forward" -#: flatcamGUI/PreferencesUI.py:5141 flatcamGUI/PreferencesUI.py:5556 -#: flatcamTools/ToolNonCopperClear.py:191 flatcamTools/ToolPaint.py:163 +#: flatcamGUI/PreferencesUI.py:5445 flatcamGUI/PreferencesUI.py:5991 +#: flatcamTools/ToolNCC.py:184 flatcamTools/ToolPaint.py:168 msgid "Reverse" msgstr "Reverse" -#: flatcamGUI/PreferencesUI.py:5154 flatcamTools/ToolNonCopperClear.py:321 -msgid "" -"How much (fraction) of the tool width to overlap each tool pass.\n" -"Adjust the value starting with lower values\n" -"and increasing it if areas that should be cleared are still \n" -"not cleared.\n" -"Lower values = faster processing, faster execution on CNC.\n" -"Higher values = slow processing and slow execution on CNC\n" -"due of too many paths." -msgstr "" -"How much (fraction) of the tool width to overlap each tool pass.\n" -"Adjust the value starting with lower values\n" -"and increasing it if areas that should be cleared are still \n" -"not cleared.\n" -"Lower values = faster processing, faster execution on CNC.\n" -"Higher values = slow processing and slow execution on CNC\n" -"due of too many paths." - -#: flatcamGUI/PreferencesUI.py:5173 flatcamGUI/PreferencesUI.py:7177 -#: flatcamGUI/PreferencesUI.py:7419 flatcamGUI/PreferencesUI.py:7483 -#: flatcamTools/ToolCopperThieving.py:113 flatcamTools/ToolFiducials.py:174 -#: flatcamTools/ToolFiducials.py:237 flatcamTools/ToolNonCopperClear.py:339 -msgid "Bounding box margin." -msgstr "Bounding box margin." - -#: flatcamGUI/PreferencesUI.py:5186 flatcamGUI/PreferencesUI.py:5604 -#: flatcamTools/ToolNonCopperClear.py:350 -msgid "" -"Algorithm for non-copper clearing:
Standard: Fixed step inwards." -"
Seed-based: Outwards from seed.
Line-based: Parallel " -"lines." -msgstr "" -"Algorithm for non-copper clearing:
Standard: Fixed step inwards." -"
Seed-based: Outwards from seed.
Line-based: Parallel " -"lines." - -#: flatcamGUI/PreferencesUI.py:5202 flatcamGUI/PreferencesUI.py:5618 -#: flatcamTools/ToolNonCopperClear.py:364 flatcamTools/ToolPaint.py:267 -msgid "Connect" -msgstr "Connect" - -#: flatcamGUI/PreferencesUI.py:5211 flatcamGUI/PreferencesUI.py:5626 -#: flatcamTools/ToolNonCopperClear.py:371 flatcamTools/ToolPaint.py:274 -msgid "Contour" -msgstr "Contour" - -#: flatcamGUI/PreferencesUI.py:5220 flatcamTools/ToolNonCopperClear.py:379 -#: flatcamTools/ToolPaint.py:281 -msgid "Rest Machining" -msgstr "Rest Machining" - -#: flatcamGUI/PreferencesUI.py:5222 flatcamTools/ToolNonCopperClear.py:381 -msgid "" -"If checked, use 'rest machining'.\n" -"Basically it will clear copper outside PCB features,\n" -"using the biggest tool and continue with the next tools,\n" -"from bigger to smaller, to clear areas of copper that\n" -"could not be cleared by previous tool, until there is\n" -"no more copper to clear or there are no more tools.\n" -"If not checked, use the standard algorithm." -msgstr "" -"If checked, use 'rest machining'.\n" -"Basically it will clear copper outside PCB features,\n" -"using the biggest tool and continue with the next tools,\n" -"from bigger to smaller, to clear areas of copper that\n" -"could not be cleared by previous tool, until there is\n" -"no more copper to clear or there are no more tools.\n" -"If not checked, use the standard algorithm." - -#: flatcamGUI/PreferencesUI.py:5236 flatcamTools/ToolNonCopperClear.py:395 -#: flatcamTools/ToolNonCopperClear.py:405 -msgid "" -"If used, it will add an offset to the copper features.\n" -"The copper clearing will finish to a distance\n" -"from the copper features.\n" -"The value can be between 0 and 10 FlatCAM units." -msgstr "" -"If used, it will add an offset to the copper features.\n" -"The copper clearing will finish to a distance\n" -"from the copper features.\n" -"The value can be between 0 and 10 FlatCAM units." - -#: flatcamGUI/PreferencesUI.py:5245 flatcamTools/ToolNonCopperClear.py:403 +#: flatcamGUI/PreferencesUI.py:5545 msgid "Offset value" msgstr "Offset value" -#: flatcamGUI/PreferencesUI.py:5247 +#: flatcamGUI/PreferencesUI.py:5547 msgid "" "If used, it will add an offset to the copper features.\n" "The copper clearing will finish to a distance\n" @@ -10790,53 +11279,98 @@ msgstr "" "from the copper features.\n" "The value can be between 0.0 and 9999.9 FlatCAM units." -#: flatcamGUI/PreferencesUI.py:5262 flatcamGUI/PreferencesUI.py:7189 -#: flatcamTools/ToolCopperThieving.py:125 -#: flatcamTools/ToolNonCopperClear.py:429 -msgid "Itself" -msgstr "Itself" +#: flatcamGUI/PreferencesUI.py:5567 flatcamGUI/PreferencesUI.py:6083 +#: flatcamGUI/PreferencesUI.py:6084 flatcamTools/ToolNCC.py:512 +#: flatcamTools/ToolPaint.py:442 +msgid "Rest Machining" +msgstr "Rest Machining" -#: flatcamGUI/PreferencesUI.py:5263 flatcamGUI/PreferencesUI.py:5646 -msgid "Area" -msgstr "Area" - -#: flatcamGUI/PreferencesUI.py:5264 flatcamGUI/PreferencesUI.py:5648 -msgid "Ref" -msgstr "Ref" - -#: flatcamGUI/PreferencesUI.py:5267 +#: flatcamGUI/PreferencesUI.py:5569 flatcamTools/ToolNCC.py:516 msgid "" -"- 'Itself' - the non copper clearing extent\n" -"is based on the object that is copper cleared.\n" -" - 'Area Selection' - left mouse click to start selection of the area to be " -"painted.\n" -"Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple " -"areas.\n" -"- 'Reference Object' - will do non copper clearing within the area\n" -"specified by another object." +"If checked, use 'rest machining'.\n" +"Basically it will clear copper outside PCB features,\n" +"using the biggest tool and continue with the next tools,\n" +"from bigger to smaller, to clear areas of copper that\n" +"could not be cleared by previous tool, until there is\n" +"no more copper to clear or there are no more tools.\n" +"If not checked, use the standard algorithm." msgstr "" -"- 'Itself' - the non copper clearing extent\n" -"is based on the object that is copper cleared.\n" -" - 'Area Selection' - left mouse click to start selection of the area to be " -"painted.\n" -"Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple " -"areas.\n" -"- 'Reference Object' - will do non copper clearing within the area\n" -"specified by another object." +"If checked, use 'rest machining'.\n" +"Basically it will clear copper outside PCB features,\n" +"using the biggest tool and continue with the next tools,\n" +"from bigger to smaller, to clear areas of copper that\n" +"could not be cleared by previous tool, until there is\n" +"no more copper to clear or there are no more tools.\n" +"If not checked, use the standard algorithm." -#: flatcamGUI/PreferencesUI.py:5279 flatcamGUI/PreferencesUI.py:5654 +#: flatcamGUI/PreferencesUI.py:5588 flatcamGUI/PreferencesUI.py:6119 +#: flatcamGUI/PreferencesUI.py:7696 flatcamTools/ToolCopperThieving.py:127 +#: flatcamTools/ToolNCC.py:535 flatcamTools/ToolNCC.py:1309 +#: flatcamTools/ToolNCC.py:1651 flatcamTools/ToolNCC.py:1935 +#: flatcamTools/ToolNCC.py:1990 flatcamTools/ToolPaint.py:486 +#: flatcamTools/ToolPaint.py:939 flatcamTools/ToolPaint.py:1440 +msgid "Area Selection" +msgstr "Area Selection" + +#: flatcamGUI/PreferencesUI.py:5588 flatcamGUI/PreferencesUI.py:6119 +#: flatcamGUI/PreferencesUI.py:7697 flatcamTools/ToolCopperThieving.py:128 +#: flatcamTools/ToolDblSided.py:217 flatcamTools/ToolNCC.py:535 +#: flatcamTools/ToolNCC.py:1667 flatcamTools/ToolNCC.py:1941 +#: flatcamTools/ToolNCC.py:1998 flatcamTools/ToolNCC.py:2306 +#: flatcamTools/ToolNCC.py:2586 flatcamTools/ToolNCC.py:3012 +#: flatcamTools/ToolPaint.py:486 flatcamTools/ToolPaint.py:924 +#: flatcamTools/ToolPaint.py:1456 +msgid "Reference Object" +msgstr "Reference Object" + +#: flatcamGUI/PreferencesUI.py:5592 flatcamTools/ToolNCC.py:541 +#| msgid "" +#| "- 'Itself' - the non copper clearing extent is based on the object that " +#| "is copper cleared.\n" +#| " - 'Area Selection' - left mouse click to start selection of the area to " +#| "be painted.\n" +#| "- 'Reference Object' - will do non copper clearing within the area " +#| "specified by another object." +msgid "" +"Selection of area to be processed.\n" +"- 'Itself' - the processing extent is based on the object that is " +"processed.\n" +" - 'Area Selection' - left mouse click to start selection of the area to be " +"processed.\n" +"- 'Reference Object' - will process the area specified by another object." +msgstr "" +"Selection of area to be processed.\n" +"- 'Itself' - the processing extent is based on the object that is " +"processed.\n" +" - 'Area Selection' - left mouse click to start selection of the area to be " +"processed.\n" +"- 'Reference Object' - will process the area specified by another object." + +#: flatcamGUI/PreferencesUI.py:5601 flatcamGUI/PreferencesUI.py:6125 +#: flatcamTools/ToolNCC.py:578 flatcamTools/ToolPaint.py:522 +#| msgid "V-Shape" +msgid "Shape" +msgstr "Shape" + +#: flatcamGUI/PreferencesUI.py:5603 flatcamGUI/PreferencesUI.py:6127 +#: flatcamTools/ToolNCC.py:580 flatcamTools/ToolPaint.py:524 +#| msgid "Select the key used for multiple selection." +msgid "The kind of selection shape used for area selection." +msgstr "The kind of selection shape used for area selection." + +#: flatcamGUI/PreferencesUI.py:5618 flatcamGUI/PreferencesUI.py:6142 msgid "Normal" msgstr "Normal" -#: flatcamGUI/PreferencesUI.py:5280 flatcamGUI/PreferencesUI.py:5655 +#: flatcamGUI/PreferencesUI.py:5619 flatcamGUI/PreferencesUI.py:6143 msgid "Progressive" msgstr "Progressive" -#: flatcamGUI/PreferencesUI.py:5281 +#: flatcamGUI/PreferencesUI.py:5620 msgid "NCC Plotting" msgstr "NCC Plotting" -#: flatcamGUI/PreferencesUI.py:5283 +#: flatcamGUI/PreferencesUI.py:5622 msgid "" "- 'Normal' - normal plotting, done at the end of the NCC job\n" "- 'Progressive' - after each shape is generated it will be plotted." @@ -10844,16 +11378,16 @@ msgstr "" "- 'Normal' - normal plotting, done at the end of the NCC job\n" "- 'Progressive' - after each shape is generated it will be plotted." -#: flatcamGUI/PreferencesUI.py:5297 +#: flatcamGUI/PreferencesUI.py:5636 msgid "Cutout Tool Options" msgstr "Cutout Tool Options" -#: flatcamGUI/PreferencesUI.py:5312 flatcamTools/ToolCalculators.py:123 -#: flatcamTools/ToolCutOut.py:123 +#: flatcamGUI/PreferencesUI.py:5651 flatcamTools/ToolCalculators.py:123 +#: flatcamTools/ToolCutOut.py:130 msgid "Tool Diameter" msgstr "Tool Diameter" -#: flatcamGUI/PreferencesUI.py:5314 flatcamTools/ToolCutOut.py:125 +#: flatcamGUI/PreferencesUI.py:5653 flatcamTools/ToolCutOut.py:132 msgid "" "Diameter of the tool used to cutout\n" "the PCB shape out of the surrounding material." @@ -10861,11 +11395,11 @@ msgstr "" "Diameter of the tool used to cutout\n" "the PCB shape out of the surrounding material." -#: flatcamGUI/PreferencesUI.py:5369 flatcamTools/ToolCutOut.py:104 +#: flatcamGUI/PreferencesUI.py:5708 msgid "Object kind" msgstr "Object kind" -#: flatcamGUI/PreferencesUI.py:5371 flatcamTools/ToolCutOut.py:106 +#: flatcamGUI/PreferencesUI.py:5710 flatcamTools/ToolCutOut.py:78 msgid "" "Choice of what kind the object we want to cutout is.
- Single: " "contain a single PCB Gerber outline object.
- Panel: a panel PCB " @@ -10877,15 +11411,15 @@ msgstr "" "Gerber object, which is made\n" "out of many individual PCB outlines." -#: flatcamGUI/PreferencesUI.py:5378 flatcamTools/ToolCutOut.py:112 +#: flatcamGUI/PreferencesUI.py:5717 flatcamTools/ToolCutOut.py:84 msgid "Single" msgstr "Single" -#: flatcamGUI/PreferencesUI.py:5379 flatcamTools/ToolCutOut.py:113 +#: flatcamGUI/PreferencesUI.py:5718 flatcamTools/ToolCutOut.py:85 msgid "Panel" msgstr "Panel" -#: flatcamGUI/PreferencesUI.py:5386 flatcamTools/ToolCutOut.py:186 +#: flatcamGUI/PreferencesUI.py:5725 flatcamTools/ToolCutOut.py:193 msgid "" "Margin over bounds. A positive value here\n" "will make the cutout of the PCB further from\n" @@ -10895,11 +11429,11 @@ msgstr "" "will make the cutout of the PCB further from\n" "the actual PCB border" -#: flatcamGUI/PreferencesUI.py:5399 flatcamTools/ToolCutOut.py:197 +#: flatcamGUI/PreferencesUI.py:5738 flatcamTools/ToolCutOut.py:204 msgid "Gap size" msgstr "Gap size" -#: flatcamGUI/PreferencesUI.py:5401 flatcamTools/ToolCutOut.py:199 +#: flatcamGUI/PreferencesUI.py:5740 flatcamTools/ToolCutOut.py:206 msgid "" "The size of the bridge gaps in the cutout\n" "used to keep the board connected to\n" @@ -10911,11 +11445,11 @@ msgstr "" "the surrounding material (the one \n" "from which the PCB is cutout)." -#: flatcamGUI/PreferencesUI.py:5415 flatcamTools/ToolCutOut.py:241 +#: flatcamGUI/PreferencesUI.py:5754 flatcamTools/ToolCutOut.py:250 msgid "Gaps" msgstr "Gaps" -#: flatcamGUI/PreferencesUI.py:5417 +#: flatcamGUI/PreferencesUI.py:5756 msgid "" "Number of gaps used for the cutout.\n" "There can be maximum 8 bridges/gaps.\n" @@ -10939,11 +11473,11 @@ msgstr "" "- 2tb - 2*top + 2*bottom\n" "- 8 - 2*left + 2*right +2*top + 2*bottom" -#: flatcamGUI/PreferencesUI.py:5439 flatcamTools/ToolCutOut.py:216 +#: flatcamGUI/PreferencesUI.py:5778 flatcamTools/ToolCutOut.py:223 msgid "Convex Shape" msgstr "Convex Shape" -#: flatcamGUI/PreferencesUI.py:5441 flatcamTools/ToolCutOut.py:219 +#: flatcamGUI/PreferencesUI.py:5780 flatcamTools/ToolCutOut.py:226 msgid "" "Create a convex shape surrounding the entire PCB.\n" "Used only if the source object type is Gerber." @@ -10951,11 +11485,11 @@ msgstr "" "Create a convex shape surrounding the entire PCB.\n" "Used only if the source object type is Gerber." -#: flatcamGUI/PreferencesUI.py:5454 +#: flatcamGUI/PreferencesUI.py:5793 msgid "2Sided Tool Options" msgstr "2Sided Tool Options" -#: flatcamGUI/PreferencesUI.py:5460 +#: flatcamGUI/PreferencesUI.py:5799 msgid "" "A tool to help in creating a double sided\n" "PCB using alignment holes." @@ -10963,36 +11497,42 @@ msgstr "" "A tool to help in creating a double sided\n" "PCB using alignment holes." -#: flatcamGUI/PreferencesUI.py:5474 +#: flatcamGUI/PreferencesUI.py:5813 msgid "Drill dia" msgstr "Drill dia" -#: flatcamGUI/PreferencesUI.py:5476 flatcamTools/ToolDblSided.py:274 -#: flatcamTools/ToolDblSided.py:285 +#: flatcamGUI/PreferencesUI.py:5815 flatcamTools/ToolDblSided.py:364 +#: flatcamTools/ToolDblSided.py:369 msgid "Diameter of the drill for the alignment holes." msgstr "Diameter of the drill for the alignment holes." -#: flatcamGUI/PreferencesUI.py:5485 flatcamTools/ToolDblSided.py:146 -msgid "Mirror Axis:" -msgstr "Mirror Axis:" +#: flatcamGUI/PreferencesUI.py:5822 flatcamTools/ToolDblSided.py:378 +#| msgid "Align Right" +msgid "Align Axis" +msgstr "Align Axis" -#: flatcamGUI/PreferencesUI.py:5487 flatcamTools/ToolDblSided.py:147 +#: flatcamGUI/PreferencesUI.py:5824 flatcamGUI/PreferencesUI.py:5837 +#: flatcamTools/ToolDblSided.py:166 flatcamTools/ToolDblSided.py:380 msgid "Mirror vertically (X) or horizontally (Y)." msgstr "Mirror vertically (X) or horizontally (Y)." -#: flatcamGUI/PreferencesUI.py:5496 flatcamTools/ToolDblSided.py:156 +#: flatcamGUI/PreferencesUI.py:5835 +msgid "Mirror Axis:" +msgstr "Mirror Axis:" + +#: flatcamGUI/PreferencesUI.py:5846 flatcamTools/ToolDblSided.py:182 msgid "Point" msgstr "Point" -#: flatcamGUI/PreferencesUI.py:5497 flatcamTools/ToolDblSided.py:157 +#: flatcamGUI/PreferencesUI.py:5847 flatcamTools/ToolDblSided.py:183 msgid "Box" msgstr "Box" -#: flatcamGUI/PreferencesUI.py:5498 flatcamTools/ToolDblSided.py:158 +#: flatcamGUI/PreferencesUI.py:5848 msgid "Axis Ref" msgstr "Axis Ref" -#: flatcamGUI/PreferencesUI.py:5500 flatcamTools/ToolDblSided.py:160 +#: flatcamGUI/PreferencesUI.py:5850 msgid "" "The axis should pass through a point or cut\n" " a specified box (in a FlatCAM object) through \n" @@ -11002,48 +11542,77 @@ msgstr "" " a specified box (in a FlatCAM object) through \n" "the center." -#: flatcamGUI/PreferencesUI.py:5516 +#: flatcamGUI/PreferencesUI.py:5866 msgid "Paint Tool Options" msgstr "Paint Tool Options" -#: flatcamGUI/PreferencesUI.py:5522 +#: flatcamGUI/PreferencesUI.py:5872 msgid "Parameters:" msgstr "Parameters:" -#: flatcamGUI/PreferencesUI.py:5636 flatcamTools/ToolPaint.py:296 -#: flatcamTools/ToolPaint.py:313 +#: flatcamGUI/PreferencesUI.py:6086 flatcamTools/ToolPaint.py:445 msgid "" -"How to select Polygons to be painted.\n" -"- 'Polygon Selection' - left mouse click to add/remove polygons to be " -"painted.\n" -"- 'Area Selection' - left mouse click to start selection of the area to be " -"painted.\n" -"Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple " -"areas.\n" -"- 'All Polygons' - the Paint will start after click.\n" -"- 'Reference Object' - will do non copper clearing within the area\n" -"specified by another object." +"If checked, use 'rest machining'.\n" +"Basically it will clear copper outside PCB features,\n" +"using the biggest tool and continue with the next tools,\n" +"from bigger to smaller, to clear areas of copper that\n" +"could not be cleared by previous tool, until there is\n" +"no more copper to clear or there are no more tools.\n" +"\n" +"If not checked, use the standard algorithm." msgstr "" -"How to select Polygons to be painted.\n" +"If checked, use 'rest machining'.\n" +"Basically it will clear copper outside PCB features,\n" +"using the biggest tool and continue with the next tools,\n" +"from bigger to smaller, to clear areas of copper that\n" +"could not be cleared by previous tool, until there is\n" +"no more copper to clear or there are no more tools.\n" +"\n" +"If not checked, use the standard algorithm." + +#: flatcamGUI/PreferencesUI.py:6099 flatcamTools/ToolPaint.py:458 +#| msgid "" +#| "How to select Polygons to be painted.\n" +#| "- 'Polygon Selection' - left mouse click to add/remove polygons to be " +#| "painted.\n" +#| "- 'Area Selection' - left mouse click to start selection of the area to " +#| "be painted.\n" +#| "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple " +#| "areas.\n" +#| "- 'All Polygons' - the Paint will start after click.\n" +#| "- 'Reference Object' - will do non copper clearing within the area\n" +#| "specified by another object." +msgid "" +"Selection of area to be processed.\n" "- 'Polygon Selection' - left mouse click to add/remove polygons to be " -"painted.\n" +"processed.\n" "- 'Area Selection' - left mouse click to start selection of the area to be " -"painted.\n" +"processed.\n" "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple " "areas.\n" -"- 'All Polygons' - the Paint will start after click.\n" -"- 'Reference Object' - will do non copper clearing within the area\n" -"specified by another object." +"- 'All Polygons' - the process will start after click.\n" +"- 'Reference Object' - will process the area specified by another object." +msgstr "" +"Selection of area to be processed.\n" +"- 'Polygon Selection' - left mouse click to add/remove polygons to be " +"processed.\n" +"- 'Area Selection' - left mouse click to start selection of the area to be " +"processed.\n" +"Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple " +"areas.\n" +"- 'All Polygons' - the process will start after click.\n" +"- 'Reference Object' - will process the area specified by another object." -#: flatcamGUI/PreferencesUI.py:5645 -msgid "Sel" -msgstr "Sel" +#: flatcamGUI/PreferencesUI.py:6119 flatcamTools/ToolPaint.py:486 +#: flatcamTools/ToolPaint.py:935 flatcamTools/ToolPaint.py:1420 +msgid "Polygon Selection" +msgstr "Polygon Selection" -#: flatcamGUI/PreferencesUI.py:5656 +#: flatcamGUI/PreferencesUI.py:6144 msgid "Paint Plotting" msgstr "Paint Plotting" -#: flatcamGUI/PreferencesUI.py:5658 +#: flatcamGUI/PreferencesUI.py:6146 msgid "" "- 'Normal' - normal plotting, done at the end of the Paint job\n" "- 'Progressive' - after each shape is generated it will be plotted." @@ -11051,11 +11620,11 @@ msgstr "" "- 'Normal' - normal plotting, done at the end of the Paint job\n" "- 'Progressive' - after each shape is generated it will be plotted." -#: flatcamGUI/PreferencesUI.py:5672 +#: flatcamGUI/PreferencesUI.py:6160 msgid "Film Tool Options" msgstr "Film Tool Options" -#: flatcamGUI/PreferencesUI.py:5678 +#: flatcamGUI/PreferencesUI.py:6166 msgid "" "Create a PCB film from a Gerber or Geometry\n" "FlatCAM object.\n" @@ -11065,11 +11634,11 @@ msgstr "" "FlatCAM object.\n" "The file is saved in SVG format." -#: flatcamGUI/PreferencesUI.py:5689 +#: flatcamGUI/PreferencesUI.py:6177 msgid "Film Type" msgstr "Film Type" -#: flatcamGUI/PreferencesUI.py:5691 flatcamTools/ToolFilm.py:300 +#: flatcamGUI/PreferencesUI.py:6179 flatcamTools/ToolFilm.py:300 msgid "" "Generate a Positive black film or a Negative film.\n" "Positive means that it will print the features\n" @@ -11085,19 +11654,19 @@ msgstr "" "with white on a black canvas.\n" "The Film format is SVG." -#: flatcamGUI/PreferencesUI.py:5702 +#: flatcamGUI/PreferencesUI.py:6190 msgid "Film Color" msgstr "Film Color" -#: flatcamGUI/PreferencesUI.py:5704 +#: flatcamGUI/PreferencesUI.py:6192 msgid "Set the film color when positive film is selected." msgstr "Set the film color when positive film is selected." -#: flatcamGUI/PreferencesUI.py:5727 flatcamTools/ToolFilm.py:316 +#: flatcamGUI/PreferencesUI.py:6215 flatcamTools/ToolFilm.py:316 msgid "Border" msgstr "Border" -#: flatcamGUI/PreferencesUI.py:5729 flatcamTools/ToolFilm.py:318 +#: flatcamGUI/PreferencesUI.py:6217 flatcamTools/ToolFilm.py:318 msgid "" "Specify a border around the object.\n" "Only for negative film.\n" @@ -11117,11 +11686,11 @@ msgstr "" "white color like the rest and which may confound with the\n" "surroundings if not for this border." -#: flatcamGUI/PreferencesUI.py:5746 flatcamTools/ToolFilm.py:283 +#: flatcamGUI/PreferencesUI.py:6234 flatcamTools/ToolFilm.py:283 msgid "Scale Stroke" msgstr "Scale Stroke" -#: flatcamGUI/PreferencesUI.py:5748 flatcamTools/ToolFilm.py:285 +#: flatcamGUI/PreferencesUI.py:6236 flatcamTools/ToolFilm.py:285 msgid "" "Scale the line stroke thickness of each feature in the SVG file.\n" "It means that the line that envelope each SVG feature will be thicker or " @@ -11133,11 +11702,11 @@ msgstr "" "thinner,\n" "therefore the fine features may be more affected by this parameter." -#: flatcamGUI/PreferencesUI.py:5755 flatcamTools/ToolFilm.py:141 +#: flatcamGUI/PreferencesUI.py:6243 flatcamTools/ToolFilm.py:141 msgid "Film Adjustments" msgstr "Film Adjustments" -#: flatcamGUI/PreferencesUI.py:5757 flatcamTools/ToolFilm.py:143 +#: flatcamGUI/PreferencesUI.py:6245 flatcamTools/ToolFilm.py:143 msgid "" "Sometime the printers will distort the print shape, especially the Laser " "types.\n" @@ -11147,11 +11716,11 @@ msgstr "" "types.\n" "This section provide the tools to compensate for the print distortions." -#: flatcamGUI/PreferencesUI.py:5764 flatcamTools/ToolFilm.py:150 +#: flatcamGUI/PreferencesUI.py:6252 flatcamTools/ToolFilm.py:150 msgid "Scale Film geometry" msgstr "Scale Film geometry" -#: flatcamGUI/PreferencesUI.py:5766 flatcamTools/ToolFilm.py:152 +#: flatcamGUI/PreferencesUI.py:6254 flatcamTools/ToolFilm.py:152 msgid "" "A value greater than 1 will stretch the film\n" "while a value less than 1 will jolt it." @@ -11159,21 +11728,21 @@ msgstr "" "A value greater than 1 will stretch the film\n" "while a value less than 1 will jolt it." -#: flatcamGUI/PreferencesUI.py:5776 flatcamGUI/PreferencesUI.py:6296 -#: flatcamTools/ToolFilm.py:162 flatcamTools/ToolTransform.py:148 +#: flatcamGUI/PreferencesUI.py:6264 flatcamGUI/PreferencesUI.py:6783 +#: flatcamTools/ToolFilm.py:162 flatcamTools/ToolTransform.py:149 msgid "X factor" msgstr "X factor" -#: flatcamGUI/PreferencesUI.py:5785 flatcamGUI/PreferencesUI.py:6309 +#: flatcamGUI/PreferencesUI.py:6273 flatcamGUI/PreferencesUI.py:6796 #: flatcamTools/ToolFilm.py:171 flatcamTools/ToolTransform.py:169 msgid "Y factor" msgstr "Y factor" -#: flatcamGUI/PreferencesUI.py:5795 flatcamTools/ToolFilm.py:189 +#: flatcamGUI/PreferencesUI.py:6283 flatcamTools/ToolFilm.py:189 msgid "Skew Film geometry" msgstr "Skew Film geometry" -#: flatcamGUI/PreferencesUI.py:5797 flatcamTools/ToolFilm.py:191 +#: flatcamGUI/PreferencesUI.py:6285 flatcamTools/ToolFilm.py:191 msgid "" "Positive values will skew to the right\n" "while negative values will skew to the left." @@ -11181,17 +11750,17 @@ msgstr "" "Positive values will skew to the right\n" "while negative values will skew to the left." -#: flatcamGUI/PreferencesUI.py:5807 flatcamGUI/PreferencesUI.py:6265 +#: flatcamGUI/PreferencesUI.py:6295 flatcamGUI/PreferencesUI.py:6752 #: flatcamTools/ToolFilm.py:201 flatcamTools/ToolTransform.py:98 msgid "X angle" msgstr "X angle" -#: flatcamGUI/PreferencesUI.py:5816 flatcamGUI/PreferencesUI.py:6279 -#: flatcamTools/ToolFilm.py:210 flatcamTools/ToolTransform.py:120 +#: flatcamGUI/PreferencesUI.py:6304 flatcamGUI/PreferencesUI.py:6766 +#: flatcamTools/ToolFilm.py:210 flatcamTools/ToolTransform.py:119 msgid "Y angle" msgstr "Y angle" -#: flatcamGUI/PreferencesUI.py:5827 flatcamTools/ToolFilm.py:221 +#: flatcamGUI/PreferencesUI.py:6315 flatcamTools/ToolFilm.py:221 msgid "" "The reference point to be used as origin for the skew.\n" "It can be one of the four points of the geometry bounding box." @@ -11199,57 +11768,53 @@ msgstr "" "The reference point to be used as origin for the skew.\n" "It can be one of the four points of the geometry bounding box." -#: flatcamGUI/PreferencesUI.py:5830 flatcamTools/ToolFiducials.py:87 +#: flatcamGUI/PreferencesUI.py:6318 flatcamTools/ToolFiducials.py:87 #: flatcamTools/ToolFilm.py:224 msgid "Bottom Left" msgstr "Bottom Left" -#: flatcamGUI/PreferencesUI.py:5831 flatcamTools/ToolFilm.py:225 +#: flatcamGUI/PreferencesUI.py:6319 flatcamTools/ToolFilm.py:225 msgid "Top Left" msgstr "Top Left" -#: flatcamGUI/PreferencesUI.py:5832 flatcamTools/ToolFilm.py:226 +#: flatcamGUI/PreferencesUI.py:6320 flatcamTools/ToolFilm.py:226 msgid "Bottom Right" msgstr "Bottom Right" -#: flatcamGUI/PreferencesUI.py:5833 flatcamTools/ToolFilm.py:227 +#: flatcamGUI/PreferencesUI.py:6321 flatcamTools/ToolFilm.py:227 msgid "Top right" msgstr "Top right" -#: flatcamGUI/PreferencesUI.py:5841 flatcamTools/ToolFilm.py:244 +#: flatcamGUI/PreferencesUI.py:6329 flatcamTools/ToolFilm.py:244 msgid "Mirror Film geometry" msgstr "Mirror Film geometry" -#: flatcamGUI/PreferencesUI.py:5843 flatcamTools/ToolFilm.py:246 +#: flatcamGUI/PreferencesUI.py:6331 flatcamTools/ToolFilm.py:246 msgid "Mirror the film geometry on the selected axis or on both." msgstr "Mirror the film geometry on the selected axis or on both." -#: flatcamGUI/PreferencesUI.py:5855 flatcamTools/ToolFilm.py:258 -msgid "Both" -msgstr "Both" - -#: flatcamGUI/PreferencesUI.py:5857 flatcamTools/ToolFilm.py:260 +#: flatcamGUI/PreferencesUI.py:6345 flatcamTools/ToolFilm.py:260 msgid "Mirror axis" msgstr "Mirror axis" -#: flatcamGUI/PreferencesUI.py:5867 flatcamTools/ToolFilm.py:403 +#: flatcamGUI/PreferencesUI.py:6355 flatcamTools/ToolFilm.py:405 msgid "SVG" msgstr "SVG" -#: flatcamGUI/PreferencesUI.py:5868 flatcamTools/ToolFilm.py:404 +#: flatcamGUI/PreferencesUI.py:6356 flatcamTools/ToolFilm.py:406 msgid "PNG" msgstr "PNG" -#: flatcamGUI/PreferencesUI.py:5869 flatcamTools/ToolFilm.py:405 +#: flatcamGUI/PreferencesUI.py:6357 flatcamTools/ToolFilm.py:407 msgid "PDF" msgstr "PDF" -#: flatcamGUI/PreferencesUI.py:5872 flatcamTools/ToolFilm.py:298 -#: flatcamTools/ToolFilm.py:408 +#: flatcamGUI/PreferencesUI.py:6360 flatcamTools/ToolFilm.py:298 +#: flatcamTools/ToolFilm.py:410 msgid "Film Type:" msgstr "Film Type:" -#: flatcamGUI/PreferencesUI.py:5874 flatcamTools/ToolFilm.py:410 +#: flatcamGUI/PreferencesUI.py:6362 flatcamTools/ToolFilm.py:412 msgid "" "The file type of the saved film. Can be:\n" "- 'SVG' -> open-source vectorial format\n" @@ -11261,23 +11826,23 @@ msgstr "" "- 'PNG' -> raster image\n" "- 'PDF' -> portable document format" -#: flatcamGUI/PreferencesUI.py:5883 flatcamTools/ToolFilm.py:419 +#: flatcamGUI/PreferencesUI.py:6371 flatcamTools/ToolFilm.py:421 msgid "Page Orientation" msgstr "Page Orientation" -#: flatcamGUI/PreferencesUI.py:5896 flatcamTools/ToolFilm.py:432 +#: flatcamGUI/PreferencesUI.py:6384 flatcamTools/ToolFilm.py:434 msgid "Page Size" msgstr "Page Size" -#: flatcamGUI/PreferencesUI.py:5897 flatcamTools/ToolFilm.py:433 +#: flatcamGUI/PreferencesUI.py:6385 flatcamTools/ToolFilm.py:435 msgid "A selection of standard ISO 216 page sizes." msgstr "A selection of standard ISO 216 page sizes." -#: flatcamGUI/PreferencesUI.py:5969 +#: flatcamGUI/PreferencesUI.py:6457 msgid "Panelize Tool Options" msgstr "Panelize Tool Options" -#: flatcamGUI/PreferencesUI.py:5975 +#: flatcamGUI/PreferencesUI.py:6463 msgid "" "Create an object that contains an array of (x, y) elements,\n" "each element is a copy of the source object spaced\n" @@ -11287,11 +11852,11 @@ msgstr "" "each element is a copy of the source object spaced\n" "at a X distance, Y distance of each other." -#: flatcamGUI/PreferencesUI.py:5992 flatcamTools/ToolPanelize.py:160 +#: flatcamGUI/PreferencesUI.py:6480 flatcamTools/ToolPanelize.py:163 msgid "Spacing cols" msgstr "Spacing cols" -#: flatcamGUI/PreferencesUI.py:5994 flatcamTools/ToolPanelize.py:162 +#: flatcamGUI/PreferencesUI.py:6482 flatcamTools/ToolPanelize.py:165 msgid "" "Spacing between columns of the desired panel.\n" "In current units." @@ -11299,11 +11864,11 @@ msgstr "" "Spacing between columns of the desired panel.\n" "In current units." -#: flatcamGUI/PreferencesUI.py:6006 flatcamTools/ToolPanelize.py:172 +#: flatcamGUI/PreferencesUI.py:6494 flatcamTools/ToolPanelize.py:175 msgid "Spacing rows" msgstr "Spacing rows" -#: flatcamGUI/PreferencesUI.py:6008 flatcamTools/ToolPanelize.py:174 +#: flatcamGUI/PreferencesUI.py:6496 flatcamTools/ToolPanelize.py:177 msgid "" "Spacing between rows of the desired panel.\n" "In current units." @@ -11311,36 +11876,31 @@ msgstr "" "Spacing between rows of the desired panel.\n" "In current units." -#: flatcamGUI/PreferencesUI.py:6019 flatcamTools/ToolPanelize.py:183 +#: flatcamGUI/PreferencesUI.py:6507 flatcamTools/ToolPanelize.py:186 msgid "Columns" msgstr "Columns" -#: flatcamGUI/PreferencesUI.py:6021 flatcamTools/ToolPanelize.py:185 +#: flatcamGUI/PreferencesUI.py:6509 flatcamTools/ToolPanelize.py:188 msgid "Number of columns of the desired panel" msgstr "Number of columns of the desired panel" -#: flatcamGUI/PreferencesUI.py:6031 flatcamTools/ToolPanelize.py:193 +#: flatcamGUI/PreferencesUI.py:6519 flatcamTools/ToolPanelize.py:196 msgid "Rows" msgstr "Rows" -#: flatcamGUI/PreferencesUI.py:6033 flatcamTools/ToolPanelize.py:195 +#: flatcamGUI/PreferencesUI.py:6521 flatcamTools/ToolPanelize.py:198 msgid "Number of rows of the desired panel" msgstr "Number of rows of the desired panel" -#: flatcamGUI/PreferencesUI.py:6039 flatcamTools/ToolCalibration.py:196 -#: flatcamTools/ToolCalibration.py:634 flatcamTools/ToolPanelize.py:201 -msgid "Gerber" -msgstr "Gerber" - -#: flatcamGUI/PreferencesUI.py:6040 flatcamTools/ToolPanelize.py:202 +#: flatcamGUI/PreferencesUI.py:6528 flatcamTools/ToolPanelize.py:205 msgid "Geo" msgstr "Geo" -#: flatcamGUI/PreferencesUI.py:6041 flatcamTools/ToolPanelize.py:203 +#: flatcamGUI/PreferencesUI.py:6529 flatcamTools/ToolPanelize.py:206 msgid "Panel Type" msgstr "Panel Type" -#: flatcamGUI/PreferencesUI.py:6043 +#: flatcamGUI/PreferencesUI.py:6531 msgid "" "Choose the type of object for the panel object:\n" "- Gerber\n" @@ -11350,11 +11910,11 @@ msgstr "" "- Gerber\n" "- Geometry" -#: flatcamGUI/PreferencesUI.py:6052 +#: flatcamGUI/PreferencesUI.py:6540 msgid "Constrain within" msgstr "Constrain within" -#: flatcamGUI/PreferencesUI.py:6054 flatcamTools/ToolPanelize.py:215 +#: flatcamGUI/PreferencesUI.py:6542 flatcamTools/ToolPanelize.py:218 msgid "" "Area define by DX and DY within to constrain the panel.\n" "DX and DY values are in current units.\n" @@ -11368,11 +11928,11 @@ msgstr "" "the final panel will have as many columns and rows as\n" "they fit completely within selected area." -#: flatcamGUI/PreferencesUI.py:6067 flatcamTools/ToolPanelize.py:227 +#: flatcamGUI/PreferencesUI.py:6555 flatcamTools/ToolPanelize.py:230 msgid "Width (DX)" msgstr "Width (DX)" -#: flatcamGUI/PreferencesUI.py:6069 flatcamTools/ToolPanelize.py:229 +#: flatcamGUI/PreferencesUI.py:6557 flatcamTools/ToolPanelize.py:232 msgid "" "The width (DX) within which the panel must fit.\n" "In current units." @@ -11380,11 +11940,11 @@ msgstr "" "The width (DX) within which the panel must fit.\n" "In current units." -#: flatcamGUI/PreferencesUI.py:6080 flatcamTools/ToolPanelize.py:238 +#: flatcamGUI/PreferencesUI.py:6568 flatcamTools/ToolPanelize.py:241 msgid "Height (DY)" msgstr "Height (DY)" -#: flatcamGUI/PreferencesUI.py:6082 flatcamTools/ToolPanelize.py:240 +#: flatcamGUI/PreferencesUI.py:6570 flatcamTools/ToolPanelize.py:243 msgid "" "The height (DY)within which the panel must fit.\n" "In current units." @@ -11392,15 +11952,15 @@ msgstr "" "The height (DY)within which the panel must fit.\n" "In current units." -#: flatcamGUI/PreferencesUI.py:6096 +#: flatcamGUI/PreferencesUI.py:6584 msgid "Calculators Tool Options" msgstr "Calculators Tool Options" -#: flatcamGUI/PreferencesUI.py:6100 flatcamTools/ToolCalculators.py:25 +#: flatcamGUI/PreferencesUI.py:6588 flatcamTools/ToolCalculators.py:25 msgid "V-Shape Tool Calculator" msgstr "V-Shape Tool Calculator" -#: flatcamGUI/PreferencesUI.py:6102 +#: flatcamGUI/PreferencesUI.py:6590 msgid "" "Calculate the tool diameter for a given V-shape tool,\n" "having the tip diameter, tip angle and\n" @@ -11410,11 +11970,11 @@ msgstr "" "having the tip diameter, tip angle and\n" "depth-of-cut as parameters." -#: flatcamGUI/PreferencesUI.py:6117 flatcamTools/ToolCalculators.py:94 +#: flatcamGUI/PreferencesUI.py:6607 flatcamTools/ToolCalculators.py:94 msgid "Tip Diameter" msgstr "Tip Diameter" -#: flatcamGUI/PreferencesUI.py:6119 flatcamTools/ToolCalculators.py:102 +#: flatcamGUI/PreferencesUI.py:6609 flatcamTools/ToolCalculators.py:102 msgid "" "This is the tool tip diameter.\n" "It is specified by manufacturer." @@ -11422,11 +11982,11 @@ msgstr "" "This is the tool tip diameter.\n" "It is specified by manufacturer." -#: flatcamGUI/PreferencesUI.py:6131 flatcamTools/ToolCalculators.py:105 +#: flatcamGUI/PreferencesUI.py:6621 flatcamTools/ToolCalculators.py:105 msgid "Tip Angle" msgstr "Tip Angle" -#: flatcamGUI/PreferencesUI.py:6133 +#: flatcamGUI/PreferencesUI.py:6623 msgid "" "This is the angle on the tip of the tool.\n" "It is specified by manufacturer." @@ -11434,7 +11994,7 @@ msgstr "" "This is the angle on the tip of the tool.\n" "It is specified by manufacturer." -#: flatcamGUI/PreferencesUI.py:6147 +#: flatcamGUI/PreferencesUI.py:6637 msgid "" "This is depth to cut into material.\n" "In the CNCJob object it is the CutZ parameter." @@ -11442,11 +12002,11 @@ msgstr "" "This is depth to cut into material.\n" "In the CNCJob object it is the CutZ parameter." -#: flatcamGUI/PreferencesUI.py:6154 flatcamTools/ToolCalculators.py:27 +#: flatcamGUI/PreferencesUI.py:6644 flatcamTools/ToolCalculators.py:27 msgid "ElectroPlating Calculator" msgstr "ElectroPlating Calculator" -#: flatcamGUI/PreferencesUI.py:6156 flatcamTools/ToolCalculators.py:158 +#: flatcamGUI/PreferencesUI.py:6646 flatcamTools/ToolCalculators.py:158 msgid "" "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 " @@ -11456,27 +12016,27 @@ msgstr "" "using a method like grahite ink or calcium hypophosphite ink or palladium " "chloride." -#: flatcamGUI/PreferencesUI.py:6170 flatcamTools/ToolCalculators.py:167 +#: flatcamGUI/PreferencesUI.py:6657 flatcamTools/ToolCalculators.py:167 msgid "Board Length" msgstr "Board Length" -#: flatcamGUI/PreferencesUI.py:6172 flatcamTools/ToolCalculators.py:173 +#: flatcamGUI/PreferencesUI.py:6659 flatcamTools/ToolCalculators.py:173 msgid "This is the board length. In centimeters." msgstr "This is the board length. In centimeters." -#: flatcamGUI/PreferencesUI.py:6182 flatcamTools/ToolCalculators.py:175 +#: flatcamGUI/PreferencesUI.py:6669 flatcamTools/ToolCalculators.py:175 msgid "Board Width" msgstr "Board Width" -#: flatcamGUI/PreferencesUI.py:6184 flatcamTools/ToolCalculators.py:181 +#: flatcamGUI/PreferencesUI.py:6671 flatcamTools/ToolCalculators.py:181 msgid "This is the board width.In centimeters." msgstr "This is the board width.In centimeters." -#: flatcamGUI/PreferencesUI.py:6189 flatcamTools/ToolCalculators.py:183 +#: flatcamGUI/PreferencesUI.py:6676 flatcamTools/ToolCalculators.py:183 msgid "Current Density" msgstr "Current Density" -#: flatcamGUI/PreferencesUI.py:6195 flatcamTools/ToolCalculators.py:190 +#: flatcamGUI/PreferencesUI.py:6682 flatcamTools/ToolCalculators.py:190 msgid "" "Current density to pass through the board. \n" "In Amps per Square Feet ASF." @@ -11484,11 +12044,11 @@ msgstr "" "Current density to pass through the board. \n" "In Amps per Square Feet ASF." -#: flatcamGUI/PreferencesUI.py:6201 flatcamTools/ToolCalculators.py:193 +#: flatcamGUI/PreferencesUI.py:6688 flatcamTools/ToolCalculators.py:193 msgid "Copper Growth" msgstr "Copper Growth" -#: flatcamGUI/PreferencesUI.py:6207 flatcamTools/ToolCalculators.py:200 +#: flatcamGUI/PreferencesUI.py:6694 flatcamTools/ToolCalculators.py:200 msgid "" "How thick the copper growth is intended to be.\n" "In microns." @@ -11496,11 +12056,11 @@ msgstr "" "How thick the copper growth is intended to be.\n" "In microns." -#: flatcamGUI/PreferencesUI.py:6220 +#: flatcamGUI/PreferencesUI.py:6707 msgid "Transform Tool Options" msgstr "Transform Tool Options" -#: flatcamGUI/PreferencesUI.py:6226 +#: flatcamGUI/PreferencesUI.py:6713 msgid "" "Various transformations that can be applied\n" "on a FlatCAM object." @@ -11508,19 +12068,19 @@ msgstr "" "Various transformations that can be applied\n" "on a FlatCAM object." -#: flatcamGUI/PreferencesUI.py:6257 +#: flatcamGUI/PreferencesUI.py:6744 msgid "Skew" msgstr "Skew" -#: flatcamGUI/PreferencesUI.py:6298 flatcamTools/ToolTransform.py:150 +#: flatcamGUI/PreferencesUI.py:6785 flatcamTools/ToolTransform.py:151 msgid "Factor for scaling on X axis." msgstr "Factor for scaling on X axis." -#: flatcamGUI/PreferencesUI.py:6311 flatcamTools/ToolTransform.py:171 +#: flatcamGUI/PreferencesUI.py:6798 flatcamTools/ToolTransform.py:171 msgid "Factor for scaling on Y axis." msgstr "Factor for scaling on Y axis." -#: flatcamGUI/PreferencesUI.py:6319 flatcamTools/ToolTransform.py:194 +#: flatcamGUI/PreferencesUI.py:6806 flatcamTools/ToolTransform.py:192 msgid "" "Scale the selected object(s)\n" "using the Scale_X factor for both axis." @@ -11528,7 +12088,7 @@ msgstr "" "Scale the selected object(s)\n" "using the Scale_X factor for both axis." -#: flatcamGUI/PreferencesUI.py:6327 flatcamTools/ToolTransform.py:202 +#: flatcamGUI/PreferencesUI.py:6814 flatcamTools/ToolTransform.py:199 msgid "" "Scale the selected object(s)\n" "using the origin reference when checked,\n" @@ -11540,32 +12100,32 @@ msgstr "" "and the center of the biggest bounding box\n" "of the selected objects when unchecked." -#: flatcamGUI/PreferencesUI.py:6343 flatcamTools/ToolTransform.py:217 +#: flatcamGUI/PreferencesUI.py:6830 flatcamTools/ToolTransform.py:218 msgid "X val" msgstr "X val" -#: flatcamGUI/PreferencesUI.py:6345 flatcamTools/ToolTransform.py:219 +#: flatcamGUI/PreferencesUI.py:6832 flatcamTools/ToolTransform.py:220 msgid "Distance to offset on X axis. In current units." msgstr "Distance to offset on X axis. In current units." -#: flatcamGUI/PreferencesUI.py:6356 flatcamTools/ToolTransform.py:238 +#: flatcamGUI/PreferencesUI.py:6843 flatcamTools/ToolTransform.py:238 msgid "Y val" msgstr "Y val" -#: flatcamGUI/PreferencesUI.py:6358 flatcamTools/ToolTransform.py:240 +#: flatcamGUI/PreferencesUI.py:6845 flatcamTools/ToolTransform.py:240 msgid "Distance to offset on Y axis. In current units." msgstr "Distance to offset on Y axis. In current units." -#: flatcamGUI/PreferencesUI.py:6364 flatcamTools/ToolDblSided.py:62 -#: flatcamTools/ToolDblSided.py:90 flatcamTools/ToolDblSided.py:120 +#: flatcamGUI/PreferencesUI.py:6851 flatcamTools/ToolDblSided.py:68 +#: flatcamTools/ToolDblSided.py:96 flatcamTools/ToolDblSided.py:126 msgid "Mirror" msgstr "Mirror" -#: flatcamGUI/PreferencesUI.py:6368 flatcamTools/ToolTransform.py:285 +#: flatcamGUI/PreferencesUI.py:6855 flatcamTools/ToolTransform.py:284 msgid "Mirror Reference" msgstr "Mirror Reference" -#: flatcamGUI/PreferencesUI.py:6370 flatcamTools/ToolTransform.py:287 +#: flatcamGUI/PreferencesUI.py:6857 flatcamTools/ToolTransform.py:286 msgid "" "Flip the selected object(s)\n" "around the point in Point Entry Field.\n" @@ -11587,11 +12147,11 @@ msgstr "" "Or enter the coords in format (x, y) in the\n" "Point Entry field and click Flip on X(Y)" -#: flatcamGUI/PreferencesUI.py:6381 +#: flatcamGUI/PreferencesUI.py:6868 msgid "Mirror Reference point" msgstr "Mirror Reference point" -#: flatcamGUI/PreferencesUI.py:6383 +#: flatcamGUI/PreferencesUI.py:6870 msgid "" "Coordinates in format (x, y) used as reference for mirroring.\n" "The 'x' in (x, y) will be used when using Flip on X and\n" @@ -11601,12 +12161,12 @@ msgstr "" "The 'x' in (x, y) will be used when using Flip on X and\n" "the 'y' in (x, y) will be used when using Flip on Y and" -#: flatcamGUI/PreferencesUI.py:6396 flatcamTools/ToolDistance.py:355 -#: flatcamTools/ToolDistanceMin.py:284 flatcamTools/ToolTransform.py:332 +#: flatcamGUI/PreferencesUI.py:6883 flatcamTools/ToolDistance.py:496 +#: flatcamTools/ToolDistanceMin.py:287 flatcamTools/ToolTransform.py:333 msgid "Distance" msgstr "Distance" -#: flatcamGUI/PreferencesUI.py:6398 flatcamTools/ToolTransform.py:334 +#: flatcamGUI/PreferencesUI.py:6885 flatcamTools/ToolTransform.py:335 msgid "" "A positive value will create the effect of dilation,\n" "while a negative value will create the effect of erosion.\n" @@ -11618,12 +12178,31 @@ msgstr "" "Each geometry element of the object will be increased\n" "or decreased with the 'distance'." -#: flatcamGUI/PreferencesUI.py:6414 flatcamGUI/PreferencesUI.py:7057 -#: flatcamTools/ToolQRCode.py:197 flatcamTools/ToolTransform.py:361 +#: flatcamGUI/PreferencesUI.py:6902 flatcamTools/ToolTransform.py:360 +#| msgid "" +#| "A positive value will create the effect of dilation,\n" +#| "while a negative value will create the effect of erosion.\n" +#| "Each geometry element of the object will be increased\n" +#| "or decreased with the 'distance'." +msgid "" +"A positive value will create the effect of dilation,\n" +"while a negative value will create the effect of erosion.\n" +"Each geometry element of the object will be increased\n" +"or decreased to fit the 'Value'. Value is a percentage\n" +"of the initial dimension." +msgstr "" +"A positive value will create the effect of dilation,\n" +"while a negative value will create the effect of erosion.\n" +"Each geometry element of the object will be increased\n" +"or decreased to fit the 'Value'. Value is a percentage\n" +"of the initial dimension." + +#: flatcamGUI/PreferencesUI.py:6919 flatcamGUI/PreferencesUI.py:7563 +#: flatcamTools/ToolQRCode.py:197 flatcamTools/ToolTransform.py:384 msgid "Rounded" msgstr "Rounded" -#: flatcamGUI/PreferencesUI.py:6416 flatcamTools/ToolTransform.py:363 +#: flatcamGUI/PreferencesUI.py:6921 flatcamTools/ToolTransform.py:386 msgid "" "If checked then the buffer will surround the buffered shape,\n" "every corner will be rounded.\n" @@ -11635,11 +12214,11 @@ msgstr "" "If not checked then the buffer will follow the exact geometry\n" "of the buffered shape." -#: flatcamGUI/PreferencesUI.py:6434 +#: flatcamGUI/PreferencesUI.py:6938 msgid "SolderPaste Tool Options" msgstr "SolderPaste Tool Options" -#: flatcamGUI/PreferencesUI.py:6440 +#: flatcamGUI/PreferencesUI.py:6944 msgid "" "A tool to create GCode for dispensing\n" "solder paste onto a PCB." @@ -11647,47 +12226,43 @@ msgstr "" "A tool to create GCode for dispensing\n" "solder paste onto a PCB." -#: flatcamGUI/PreferencesUI.py:6451 -msgid "Diameters of nozzle tools, separated by ','" -msgstr "Diameters of nozzle tools, separated by ','" - -#: flatcamGUI/PreferencesUI.py:6459 +#: flatcamGUI/PreferencesUI.py:6965 msgid "New Nozzle Dia" msgstr "New Nozzle Dia" -#: flatcamGUI/PreferencesUI.py:6461 flatcamTools/ToolSolderPaste.py:106 +#: flatcamGUI/PreferencesUI.py:6967 flatcamTools/ToolSolderPaste.py:108 msgid "Diameter for the new Nozzle tool to add in the Tool Table" msgstr "Diameter for the new Nozzle tool to add in the Tool Table" -#: flatcamGUI/PreferencesUI.py:6477 flatcamTools/ToolSolderPaste.py:182 +#: flatcamGUI/PreferencesUI.py:6983 flatcamTools/ToolSolderPaste.py:184 msgid "Z Dispense Start" msgstr "Z Dispense Start" -#: flatcamGUI/PreferencesUI.py:6479 flatcamTools/ToolSolderPaste.py:184 +#: flatcamGUI/PreferencesUI.py:6985 flatcamTools/ToolSolderPaste.py:186 msgid "The height (Z) when solder paste dispensing starts." msgstr "The height (Z) when solder paste dispensing starts." -#: flatcamGUI/PreferencesUI.py:6490 flatcamTools/ToolSolderPaste.py:194 +#: flatcamGUI/PreferencesUI.py:6996 flatcamTools/ToolSolderPaste.py:196 msgid "Z Dispense" msgstr "Z Dispense" -#: flatcamGUI/PreferencesUI.py:6492 flatcamTools/ToolSolderPaste.py:196 +#: flatcamGUI/PreferencesUI.py:6998 flatcamTools/ToolSolderPaste.py:198 msgid "The height (Z) when doing solder paste dispensing." msgstr "The height (Z) when doing solder paste dispensing." -#: flatcamGUI/PreferencesUI.py:6503 flatcamTools/ToolSolderPaste.py:206 +#: flatcamGUI/PreferencesUI.py:7009 flatcamTools/ToolSolderPaste.py:208 msgid "Z Dispense Stop" msgstr "Z Dispense Stop" -#: flatcamGUI/PreferencesUI.py:6505 flatcamTools/ToolSolderPaste.py:208 +#: flatcamGUI/PreferencesUI.py:7011 flatcamTools/ToolSolderPaste.py:210 msgid "The height (Z) when solder paste dispensing stops." msgstr "The height (Z) when solder paste dispensing stops." -#: flatcamGUI/PreferencesUI.py:6516 flatcamTools/ToolSolderPaste.py:218 +#: flatcamGUI/PreferencesUI.py:7022 flatcamTools/ToolSolderPaste.py:220 msgid "Z Travel" msgstr "Z Travel" -#: flatcamGUI/PreferencesUI.py:6518 flatcamTools/ToolSolderPaste.py:220 +#: flatcamGUI/PreferencesUI.py:7024 flatcamTools/ToolSolderPaste.py:222 msgid "" "The height (Z) for travel between pads\n" "(without dispensing solder paste)." @@ -11695,15 +12270,15 @@ msgstr "" "The height (Z) for travel between pads\n" "(without dispensing solder paste)." -#: flatcamGUI/PreferencesUI.py:6530 flatcamTools/ToolSolderPaste.py:231 +#: flatcamGUI/PreferencesUI.py:7036 flatcamTools/ToolSolderPaste.py:233 msgid "Z Toolchange" msgstr "Z Toolchange" -#: flatcamGUI/PreferencesUI.py:6532 flatcamTools/ToolSolderPaste.py:233 +#: flatcamGUI/PreferencesUI.py:7038 flatcamTools/ToolSolderPaste.py:235 msgid "The height (Z) for tool (nozzle) change." msgstr "The height (Z) for tool (nozzle) change." -#: flatcamGUI/PreferencesUI.py:6541 flatcamTools/ToolSolderPaste.py:241 +#: flatcamGUI/PreferencesUI.py:7047 flatcamTools/ToolSolderPaste.py:243 msgid "" "The X,Y location for tool (nozzle) change.\n" "The format is (x, y) where x and y are real numbers." @@ -11711,11 +12286,11 @@ msgstr "" "The X,Y location for tool (nozzle) change.\n" "The format is (x, y) where x and y are real numbers." -#: flatcamGUI/PreferencesUI.py:6555 flatcamTools/ToolSolderPaste.py:254 +#: flatcamGUI/PreferencesUI.py:7061 flatcamTools/ToolSolderPaste.py:256 msgid "Feedrate (speed) while moving on the X-Y plane." msgstr "Feedrate (speed) while moving on the X-Y plane." -#: flatcamGUI/PreferencesUI.py:6568 flatcamTools/ToolSolderPaste.py:266 +#: flatcamGUI/PreferencesUI.py:7074 flatcamTools/ToolSolderPaste.py:268 msgid "" "Feedrate (speed) while moving vertically\n" "(on Z plane)." @@ -11723,11 +12298,11 @@ msgstr "" "Feedrate (speed) while moving vertically\n" "(on Z plane)." -#: flatcamGUI/PreferencesUI.py:6580 flatcamTools/ToolSolderPaste.py:277 +#: flatcamGUI/PreferencesUI.py:7086 flatcamTools/ToolSolderPaste.py:279 msgid "Feedrate Z Dispense" msgstr "Feedrate Z Dispense" -#: flatcamGUI/PreferencesUI.py:6582 +#: flatcamGUI/PreferencesUI.py:7088 msgid "" "Feedrate (speed) while moving up vertically\n" "to Dispense position (on Z plane)." @@ -11735,11 +12310,11 @@ msgstr "" "Feedrate (speed) while moving up vertically\n" "to Dispense position (on Z plane)." -#: flatcamGUI/PreferencesUI.py:6593 flatcamTools/ToolSolderPaste.py:289 +#: flatcamGUI/PreferencesUI.py:7099 flatcamTools/ToolSolderPaste.py:291 msgid "Spindle Speed FWD" msgstr "Spindle Speed FWD" -#: flatcamGUI/PreferencesUI.py:6595 flatcamTools/ToolSolderPaste.py:291 +#: flatcamGUI/PreferencesUI.py:7101 flatcamTools/ToolSolderPaste.py:293 msgid "" "The dispenser speed while pushing solder paste\n" "through the dispenser nozzle." @@ -11747,19 +12322,19 @@ msgstr "" "The dispenser speed while pushing solder paste\n" "through the dispenser nozzle." -#: flatcamGUI/PreferencesUI.py:6607 flatcamTools/ToolSolderPaste.py:302 +#: flatcamGUI/PreferencesUI.py:7113 flatcamTools/ToolSolderPaste.py:304 msgid "Dwell FWD" msgstr "Dwell FWD" -#: flatcamGUI/PreferencesUI.py:6609 flatcamTools/ToolSolderPaste.py:304 +#: flatcamGUI/PreferencesUI.py:7115 flatcamTools/ToolSolderPaste.py:306 msgid "Pause after solder dispensing." msgstr "Pause after solder dispensing." -#: flatcamGUI/PreferencesUI.py:6619 flatcamTools/ToolSolderPaste.py:313 +#: flatcamGUI/PreferencesUI.py:7125 flatcamTools/ToolSolderPaste.py:315 msgid "Spindle Speed REV" msgstr "Spindle Speed REV" -#: flatcamGUI/PreferencesUI.py:6621 flatcamTools/ToolSolderPaste.py:315 +#: flatcamGUI/PreferencesUI.py:7127 flatcamTools/ToolSolderPaste.py:317 msgid "" "The dispenser speed while retracting solder paste\n" "through the dispenser nozzle." @@ -11767,11 +12342,11 @@ msgstr "" "The dispenser speed while retracting solder paste\n" "through the dispenser nozzle." -#: flatcamGUI/PreferencesUI.py:6633 flatcamTools/ToolSolderPaste.py:326 +#: flatcamGUI/PreferencesUI.py:7139 flatcamTools/ToolSolderPaste.py:328 msgid "Dwell REV" msgstr "Dwell REV" -#: flatcamGUI/PreferencesUI.py:6635 flatcamTools/ToolSolderPaste.py:328 +#: flatcamGUI/PreferencesUI.py:7141 flatcamTools/ToolSolderPaste.py:330 msgid "" "Pause after solder paste dispenser retracted,\n" "to allow pressure equilibrium." @@ -11779,15 +12354,15 @@ msgstr "" "Pause after solder paste dispenser retracted,\n" "to allow pressure equilibrium." -#: flatcamGUI/PreferencesUI.py:6644 flatcamTools/ToolSolderPaste.py:336 +#: flatcamGUI/PreferencesUI.py:7150 flatcamTools/ToolSolderPaste.py:338 msgid "Files that control the GCode generation." msgstr "Files that control the GCode generation." -#: flatcamGUI/PreferencesUI.py:6659 +#: flatcamGUI/PreferencesUI.py:7165 msgid "Substractor Tool Options" msgstr "Substractor Tool Options" -#: flatcamGUI/PreferencesUI.py:6665 +#: flatcamGUI/PreferencesUI.py:7171 msgid "" "A tool to substract one Gerber or Geometry object\n" "from another of the same type." @@ -11795,21 +12370,21 @@ msgstr "" "A tool to substract one Gerber or Geometry object\n" "from another of the same type." -#: flatcamGUI/PreferencesUI.py:6670 flatcamTools/ToolSub.py:149 +#: flatcamGUI/PreferencesUI.py:7176 flatcamTools/ToolSub.py:155 msgid "Close paths" msgstr "Close paths" -#: flatcamGUI/PreferencesUI.py:6671 +#: flatcamGUI/PreferencesUI.py:7177 msgid "" "Checking this will close the paths cut by the Geometry substractor object." msgstr "" "Checking this will close the paths cut by the Geometry substractor object." -#: flatcamGUI/PreferencesUI.py:6682 +#: flatcamGUI/PreferencesUI.py:7188 msgid "Check Rules Tool Options" msgstr "Check Rules Tool Options" -#: flatcamGUI/PreferencesUI.py:6687 +#: flatcamGUI/PreferencesUI.py:7193 msgid "" "A tool to check if Gerber files are within a set\n" "of Manufacturing Rules." @@ -11817,38 +12392,38 @@ msgstr "" "A tool to check if Gerber files are within a set\n" "of Manufacturing Rules." -#: flatcamGUI/PreferencesUI.py:6697 flatcamTools/ToolRulesCheck.py:256 -#: flatcamTools/ToolRulesCheck.py:920 +#: flatcamGUI/PreferencesUI.py:7203 flatcamTools/ToolRulesCheck.py:265 +#: flatcamTools/ToolRulesCheck.py:929 msgid "Trace Size" msgstr "Trace Size" -#: flatcamGUI/PreferencesUI.py:6699 flatcamTools/ToolRulesCheck.py:258 +#: flatcamGUI/PreferencesUI.py:7205 flatcamTools/ToolRulesCheck.py:267 msgid "This checks if the minimum size for traces is met." msgstr "This checks if the minimum size for traces is met." -#: flatcamGUI/PreferencesUI.py:6709 flatcamGUI/PreferencesUI.py:6729 -#: flatcamGUI/PreferencesUI.py:6749 flatcamGUI/PreferencesUI.py:6769 -#: flatcamGUI/PreferencesUI.py:6789 flatcamGUI/PreferencesUI.py:6809 -#: flatcamGUI/PreferencesUI.py:6829 flatcamGUI/PreferencesUI.py:6849 -#: flatcamGUI/PreferencesUI.py:6871 flatcamGUI/PreferencesUI.py:6891 -#: flatcamTools/ToolRulesCheck.py:268 flatcamTools/ToolRulesCheck.py:290 -#: flatcamTools/ToolRulesCheck.py:313 flatcamTools/ToolRulesCheck.py:336 -#: flatcamTools/ToolRulesCheck.py:359 flatcamTools/ToolRulesCheck.py:382 -#: flatcamTools/ToolRulesCheck.py:405 flatcamTools/ToolRulesCheck.py:428 -#: flatcamTools/ToolRulesCheck.py:453 flatcamTools/ToolRulesCheck.py:476 +#: flatcamGUI/PreferencesUI.py:7215 flatcamGUI/PreferencesUI.py:7235 +#: flatcamGUI/PreferencesUI.py:7255 flatcamGUI/PreferencesUI.py:7275 +#: flatcamGUI/PreferencesUI.py:7295 flatcamGUI/PreferencesUI.py:7315 +#: flatcamGUI/PreferencesUI.py:7335 flatcamGUI/PreferencesUI.py:7355 +#: flatcamGUI/PreferencesUI.py:7377 flatcamGUI/PreferencesUI.py:7397 +#: flatcamTools/ToolRulesCheck.py:277 flatcamTools/ToolRulesCheck.py:299 +#: flatcamTools/ToolRulesCheck.py:322 flatcamTools/ToolRulesCheck.py:345 +#: flatcamTools/ToolRulesCheck.py:368 flatcamTools/ToolRulesCheck.py:391 +#: flatcamTools/ToolRulesCheck.py:414 flatcamTools/ToolRulesCheck.py:437 +#: flatcamTools/ToolRulesCheck.py:462 flatcamTools/ToolRulesCheck.py:485 msgid "Min value" msgstr "Min value" -#: flatcamGUI/PreferencesUI.py:6711 flatcamTools/ToolRulesCheck.py:270 +#: flatcamGUI/PreferencesUI.py:7217 flatcamTools/ToolRulesCheck.py:279 msgid "Minimum acceptable trace size." msgstr "Minimum acceptable trace size." -#: flatcamGUI/PreferencesUI.py:6716 flatcamTools/ToolRulesCheck.py:277 -#: flatcamTools/ToolRulesCheck.py:1148 flatcamTools/ToolRulesCheck.py:1178 +#: flatcamGUI/PreferencesUI.py:7222 flatcamTools/ToolRulesCheck.py:286 +#: flatcamTools/ToolRulesCheck.py:1157 flatcamTools/ToolRulesCheck.py:1187 msgid "Copper to Copper clearance" msgstr "Copper to Copper clearance" -#: flatcamGUI/PreferencesUI.py:6718 flatcamTools/ToolRulesCheck.py:279 +#: flatcamGUI/PreferencesUI.py:7224 flatcamTools/ToolRulesCheck.py:288 msgid "" "This checks if the minimum clearance between copper\n" "features is met." @@ -11856,23 +12431,23 @@ msgstr "" "This checks if the minimum clearance between copper\n" "features is met." -#: flatcamGUI/PreferencesUI.py:6731 flatcamGUI/PreferencesUI.py:6751 -#: flatcamGUI/PreferencesUI.py:6771 flatcamGUI/PreferencesUI.py:6791 -#: flatcamGUI/PreferencesUI.py:6811 flatcamGUI/PreferencesUI.py:6831 -#: flatcamGUI/PreferencesUI.py:6893 flatcamTools/ToolRulesCheck.py:292 -#: flatcamTools/ToolRulesCheck.py:315 flatcamTools/ToolRulesCheck.py:338 -#: flatcamTools/ToolRulesCheck.py:361 flatcamTools/ToolRulesCheck.py:384 -#: flatcamTools/ToolRulesCheck.py:407 flatcamTools/ToolRulesCheck.py:455 +#: flatcamGUI/PreferencesUI.py:7237 flatcamGUI/PreferencesUI.py:7257 +#: flatcamGUI/PreferencesUI.py:7277 flatcamGUI/PreferencesUI.py:7297 +#: flatcamGUI/PreferencesUI.py:7317 flatcamGUI/PreferencesUI.py:7337 +#: flatcamGUI/PreferencesUI.py:7399 flatcamTools/ToolRulesCheck.py:301 +#: flatcamTools/ToolRulesCheck.py:324 flatcamTools/ToolRulesCheck.py:347 +#: flatcamTools/ToolRulesCheck.py:370 flatcamTools/ToolRulesCheck.py:393 +#: flatcamTools/ToolRulesCheck.py:416 flatcamTools/ToolRulesCheck.py:464 msgid "Minimum acceptable clearance value." msgstr "Minimum acceptable clearance value." -#: flatcamGUI/PreferencesUI.py:6736 flatcamTools/ToolRulesCheck.py:300 -#: flatcamTools/ToolRulesCheck.py:1208 flatcamTools/ToolRulesCheck.py:1214 -#: flatcamTools/ToolRulesCheck.py:1227 flatcamTools/ToolRulesCheck.py:1234 +#: flatcamGUI/PreferencesUI.py:7242 flatcamTools/ToolRulesCheck.py:309 +#: flatcamTools/ToolRulesCheck.py:1217 flatcamTools/ToolRulesCheck.py:1223 +#: flatcamTools/ToolRulesCheck.py:1236 flatcamTools/ToolRulesCheck.py:1243 msgid "Copper to Outline clearance" msgstr "Copper to Outline clearance" -#: flatcamGUI/PreferencesUI.py:6738 flatcamTools/ToolRulesCheck.py:302 +#: flatcamGUI/PreferencesUI.py:7244 flatcamTools/ToolRulesCheck.py:311 msgid "" "This checks if the minimum clearance between copper\n" "features and the outline is met." @@ -11880,11 +12455,11 @@ msgstr "" "This checks if the minimum clearance between copper\n" "features and the outline is met." -#: flatcamGUI/PreferencesUI.py:6756 flatcamTools/ToolRulesCheck.py:323 +#: flatcamGUI/PreferencesUI.py:7262 flatcamTools/ToolRulesCheck.py:332 msgid "Silk to Silk Clearance" msgstr "Silk to Silk Clearance" -#: flatcamGUI/PreferencesUI.py:6758 flatcamTools/ToolRulesCheck.py:325 +#: flatcamGUI/PreferencesUI.py:7264 flatcamTools/ToolRulesCheck.py:334 msgid "" "This checks if the minimum clearance between silkscreen\n" "features and silkscreen features is met." @@ -11892,13 +12467,13 @@ msgstr "" "This checks if the minimum clearance between silkscreen\n" "features and silkscreen features is met." -#: flatcamGUI/PreferencesUI.py:6776 flatcamTools/ToolRulesCheck.py:346 -#: flatcamTools/ToolRulesCheck.py:1317 flatcamTools/ToolRulesCheck.py:1323 -#: flatcamTools/ToolRulesCheck.py:1341 +#: flatcamGUI/PreferencesUI.py:7282 flatcamTools/ToolRulesCheck.py:355 +#: flatcamTools/ToolRulesCheck.py:1326 flatcamTools/ToolRulesCheck.py:1332 +#: flatcamTools/ToolRulesCheck.py:1350 msgid "Silk to Solder Mask Clearance" msgstr "Silk to Solder Mask Clearance" -#: flatcamGUI/PreferencesUI.py:6778 flatcamTools/ToolRulesCheck.py:348 +#: flatcamGUI/PreferencesUI.py:7284 flatcamTools/ToolRulesCheck.py:357 msgid "" "This checks if the minimum clearance between silkscreen\n" "features and soldermask features is met." @@ -11906,13 +12481,13 @@ msgstr "" "This checks if the minimum clearance between silkscreen\n" "features and soldermask features is met." -#: flatcamGUI/PreferencesUI.py:6796 flatcamTools/ToolRulesCheck.py:369 -#: flatcamTools/ToolRulesCheck.py:1371 flatcamTools/ToolRulesCheck.py:1377 -#: flatcamTools/ToolRulesCheck.py:1391 flatcamTools/ToolRulesCheck.py:1398 +#: flatcamGUI/PreferencesUI.py:7302 flatcamTools/ToolRulesCheck.py:378 +#: flatcamTools/ToolRulesCheck.py:1380 flatcamTools/ToolRulesCheck.py:1386 +#: flatcamTools/ToolRulesCheck.py:1400 flatcamTools/ToolRulesCheck.py:1407 msgid "Silk to Outline Clearance" msgstr "Silk to Outline Clearance" -#: flatcamGUI/PreferencesUI.py:6798 flatcamTools/ToolRulesCheck.py:371 +#: flatcamGUI/PreferencesUI.py:7304 flatcamTools/ToolRulesCheck.py:380 msgid "" "This checks if the minimum clearance between silk\n" "features and the outline is met." @@ -11920,12 +12495,12 @@ msgstr "" "This checks if the minimum clearance between silk\n" "features and the outline is met." -#: flatcamGUI/PreferencesUI.py:6816 flatcamTools/ToolRulesCheck.py:392 -#: flatcamTools/ToolRulesCheck.py:1409 flatcamTools/ToolRulesCheck.py:1436 +#: flatcamGUI/PreferencesUI.py:7322 flatcamTools/ToolRulesCheck.py:401 +#: flatcamTools/ToolRulesCheck.py:1418 flatcamTools/ToolRulesCheck.py:1445 msgid "Minimum Solder Mask Sliver" msgstr "Minimum Solder Mask Sliver" -#: flatcamGUI/PreferencesUI.py:6818 flatcamTools/ToolRulesCheck.py:394 +#: flatcamGUI/PreferencesUI.py:7324 flatcamTools/ToolRulesCheck.py:403 msgid "" "This checks if the minimum clearance between soldermask\n" "features and soldermask features is met." @@ -11933,13 +12508,13 @@ msgstr "" "This checks if the minimum clearance between soldermask\n" "features and soldermask features is met." -#: flatcamGUI/PreferencesUI.py:6836 flatcamTools/ToolRulesCheck.py:415 -#: flatcamTools/ToolRulesCheck.py:1474 flatcamTools/ToolRulesCheck.py:1480 -#: flatcamTools/ToolRulesCheck.py:1496 flatcamTools/ToolRulesCheck.py:1503 +#: flatcamGUI/PreferencesUI.py:7342 flatcamTools/ToolRulesCheck.py:424 +#: flatcamTools/ToolRulesCheck.py:1483 flatcamTools/ToolRulesCheck.py:1489 +#: flatcamTools/ToolRulesCheck.py:1505 flatcamTools/ToolRulesCheck.py:1512 msgid "Minimum Annular Ring" msgstr "Minimum Annular Ring" -#: flatcamGUI/PreferencesUI.py:6838 flatcamTools/ToolRulesCheck.py:417 +#: flatcamGUI/PreferencesUI.py:7344 flatcamTools/ToolRulesCheck.py:426 msgid "" "This checks if the minimum copper ring left by drilling\n" "a hole into a pad is met." @@ -11947,16 +12522,16 @@ msgstr "" "This checks if the minimum copper ring left by drilling\n" "a hole into a pad is met." -#: flatcamGUI/PreferencesUI.py:6851 flatcamTools/ToolRulesCheck.py:430 +#: flatcamGUI/PreferencesUI.py:7357 flatcamTools/ToolRulesCheck.py:439 msgid "Minimum acceptable ring value." msgstr "Minimum acceptable ring value." -#: flatcamGUI/PreferencesUI.py:6858 flatcamTools/ToolRulesCheck.py:440 -#: flatcamTools/ToolRulesCheck.py:864 +#: flatcamGUI/PreferencesUI.py:7364 flatcamTools/ToolRulesCheck.py:449 +#: flatcamTools/ToolRulesCheck.py:873 msgid "Hole to Hole Clearance" msgstr "Hole to Hole Clearance" -#: flatcamGUI/PreferencesUI.py:6860 flatcamTools/ToolRulesCheck.py:442 +#: flatcamGUI/PreferencesUI.py:7366 flatcamTools/ToolRulesCheck.py:451 msgid "" "This checks if the minimum clearance between a drill hole\n" "and another drill hole is met." @@ -11964,16 +12539,16 @@ msgstr "" "This checks if the minimum clearance between a drill hole\n" "and another drill hole is met." -#: flatcamGUI/PreferencesUI.py:6873 flatcamTools/ToolRulesCheck.py:478 +#: flatcamGUI/PreferencesUI.py:7379 flatcamTools/ToolRulesCheck.py:487 msgid "Minimum acceptable drill size." msgstr "Minimum acceptable drill size." -#: flatcamGUI/PreferencesUI.py:6878 flatcamTools/ToolRulesCheck.py:463 -#: flatcamTools/ToolRulesCheck.py:838 +#: flatcamGUI/PreferencesUI.py:7384 flatcamTools/ToolRulesCheck.py:472 +#: flatcamTools/ToolRulesCheck.py:847 msgid "Hole Size" msgstr "Hole Size" -#: flatcamGUI/PreferencesUI.py:6880 flatcamTools/ToolRulesCheck.py:465 +#: flatcamGUI/PreferencesUI.py:7386 flatcamTools/ToolRulesCheck.py:474 msgid "" "This checks if the drill holes\n" "sizes are above the threshold." @@ -11981,11 +12556,11 @@ msgstr "" "This checks if the drill holes\n" "sizes are above the threshold." -#: flatcamGUI/PreferencesUI.py:6905 +#: flatcamGUI/PreferencesUI.py:7411 msgid "Optimal Tool Options" msgstr "Optimal Tool Options" -#: flatcamGUI/PreferencesUI.py:6911 +#: flatcamGUI/PreferencesUI.py:7417 msgid "" "A tool to find the minimum distance between\n" "every two Gerber geometric elements" @@ -11993,19 +12568,19 @@ msgstr "" "A tool to find the minimum distance between\n" "every two Gerber geometric elements" -#: flatcamGUI/PreferencesUI.py:6926 flatcamTools/ToolOptimal.py:78 +#: flatcamGUI/PreferencesUI.py:7432 flatcamTools/ToolOptimal.py:79 msgid "Precision" msgstr "Precision" -#: flatcamGUI/PreferencesUI.py:6928 +#: flatcamGUI/PreferencesUI.py:7434 msgid "Number of decimals for the distances and coordinates in this tool." msgstr "Number of decimals for the distances and coordinates in this tool." -#: flatcamGUI/PreferencesUI.py:6942 +#: flatcamGUI/PreferencesUI.py:7448 msgid "QRCode Tool Options" msgstr "QRCode Tool Options" -#: flatcamGUI/PreferencesUI.py:6948 +#: flatcamGUI/PreferencesUI.py:7454 msgid "" "A tool to create a QRCode that can be inserted\n" "into a selected Gerber file, or it can be exported as a file." @@ -12013,11 +12588,11 @@ msgstr "" "A tool to create a QRCode that can be inserted\n" "into a selected Gerber file, or it can be exported as a file." -#: flatcamGUI/PreferencesUI.py:6960 flatcamTools/ToolQRCode.py:99 +#: flatcamGUI/PreferencesUI.py:7466 flatcamTools/ToolQRCode.py:100 msgid "Version" msgstr "Version" -#: flatcamGUI/PreferencesUI.py:6962 flatcamTools/ToolQRCode.py:101 +#: flatcamGUI/PreferencesUI.py:7468 flatcamTools/ToolQRCode.py:102 msgid "" "QRCode version can have values from 1 (21x21 boxes)\n" "to 40 (177x177 boxes)." @@ -12025,12 +12600,12 @@ msgstr "" "QRCode version can have values from 1 (21x21 boxes)\n" "to 40 (177x177 boxes)." -#: flatcamGUI/PreferencesUI.py:6973 flatcamTools/ToolQRCode.py:112 +#: flatcamGUI/PreferencesUI.py:7479 flatcamTools/ToolQRCode.py:113 msgid "Error correction" msgstr "Error correction" -#: flatcamGUI/PreferencesUI.py:6975 flatcamGUI/PreferencesUI.py:6986 -#: flatcamTools/ToolQRCode.py:114 flatcamTools/ToolQRCode.py:125 +#: flatcamGUI/PreferencesUI.py:7481 flatcamGUI/PreferencesUI.py:7492 +#: flatcamTools/ToolQRCode.py:115 flatcamTools/ToolQRCode.py:126 #, python-format msgid "" "Parameter that controls the error correction used for the QR Code.\n" @@ -12045,11 +12620,11 @@ msgstr "" "Q = maximum 25%% errors can be corrected\n" "H = maximum 30%% errors can be corrected." -#: flatcamGUI/PreferencesUI.py:6996 flatcamTools/ToolQRCode.py:135 +#: flatcamGUI/PreferencesUI.py:7502 flatcamTools/ToolQRCode.py:136 msgid "Box Size" msgstr "Box Size" -#: flatcamGUI/PreferencesUI.py:6998 flatcamTools/ToolQRCode.py:137 +#: flatcamGUI/PreferencesUI.py:7504 flatcamTools/ToolQRCode.py:138 msgid "" "Box size control the overall size of the QRcode\n" "by adjusting the size of each box in the code." @@ -12057,11 +12632,11 @@ msgstr "" "Box size control the overall size of the QRcode\n" "by adjusting the size of each box in the code." -#: flatcamGUI/PreferencesUI.py:7009 flatcamTools/ToolQRCode.py:148 +#: flatcamGUI/PreferencesUI.py:7515 flatcamTools/ToolQRCode.py:149 msgid "Border Size" msgstr "Border Size" -#: flatcamGUI/PreferencesUI.py:7011 flatcamTools/ToolQRCode.py:150 +#: flatcamGUI/PreferencesUI.py:7517 flatcamTools/ToolQRCode.py:151 msgid "" "Size of the QRCode border. How many boxes thick is the border.\n" "Default value is 4. The width of the clearance around the QRCode." @@ -12069,23 +12644,23 @@ msgstr "" "Size of the QRCode border. How many boxes thick is the border.\n" "Default value is 4. The width of the clearance around the QRCode." -#: flatcamGUI/PreferencesUI.py:7022 flatcamTools/ToolQRCode.py:162 +#: flatcamGUI/PreferencesUI.py:7528 flatcamTools/ToolQRCode.py:162 msgid "QRCode Data" msgstr "QRCode Data" -#: flatcamGUI/PreferencesUI.py:7024 flatcamTools/ToolQRCode.py:164 +#: flatcamGUI/PreferencesUI.py:7530 flatcamTools/ToolQRCode.py:164 msgid "QRCode Data. Alphanumeric text to be encoded in the QRCode." msgstr "QRCode Data. Alphanumeric text to be encoded in the QRCode." -#: flatcamGUI/PreferencesUI.py:7028 flatcamTools/ToolQRCode.py:168 +#: flatcamGUI/PreferencesUI.py:7534 flatcamTools/ToolQRCode.py:168 msgid "Add here the text to be included in the QRCode..." msgstr "Add here the text to be included in the QRCode..." -#: flatcamGUI/PreferencesUI.py:7034 flatcamTools/ToolQRCode.py:174 +#: flatcamGUI/PreferencesUI.py:7540 flatcamTools/ToolQRCode.py:174 msgid "Polarity" msgstr "Polarity" -#: flatcamGUI/PreferencesUI.py:7036 flatcamTools/ToolQRCode.py:176 +#: flatcamGUI/PreferencesUI.py:7542 flatcamTools/ToolQRCode.py:176 msgid "" "Choose the polarity of the QRCode.\n" "It can be drawn in a negative way (squares are clear)\n" @@ -12095,17 +12670,17 @@ msgstr "" "It can be drawn in a negative way (squares are clear)\n" "or in a positive way (squares are opaque)." -#: flatcamGUI/PreferencesUI.py:7040 flatcamTools/ToolFilm.py:296 +#: flatcamGUI/PreferencesUI.py:7546 flatcamTools/ToolFilm.py:296 #: flatcamTools/ToolQRCode.py:180 msgid "Negative" msgstr "Negative" -#: flatcamGUI/PreferencesUI.py:7041 flatcamTools/ToolFilm.py:295 +#: flatcamGUI/PreferencesUI.py:7547 flatcamTools/ToolFilm.py:295 #: flatcamTools/ToolQRCode.py:181 msgid "Positive" msgstr "Positive" -#: flatcamGUI/PreferencesUI.py:7043 flatcamTools/ToolQRCode.py:183 +#: flatcamGUI/PreferencesUI.py:7549 flatcamTools/ToolQRCode.py:183 msgid "" "Choose the type of QRCode to be created.\n" "If added on a Silkscreen Gerber file the QRCode may\n" @@ -12117,7 +12692,7 @@ msgstr "" "be added as positive. If it is added to a Copper Gerber\n" "file then perhaps the QRCode can be added as negative." -#: flatcamGUI/PreferencesUI.py:7054 flatcamGUI/PreferencesUI.py:7060 +#: flatcamGUI/PreferencesUI.py:7560 flatcamGUI/PreferencesUI.py:7566 #: flatcamTools/ToolQRCode.py:194 flatcamTools/ToolQRCode.py:200 msgid "" "The bounding box, meaning the empty space that surrounds\n" @@ -12126,27 +12701,27 @@ msgstr "" "The bounding box, meaning the empty space that surrounds\n" "the QRCode geometry, can have a rounded or a square shape." -#: flatcamGUI/PreferencesUI.py:7067 flatcamTools/ToolQRCode.py:228 +#: flatcamGUI/PreferencesUI.py:7573 flatcamTools/ToolQRCode.py:228 msgid "Fill Color" msgstr "Fill Color" -#: flatcamGUI/PreferencesUI.py:7069 flatcamTools/ToolQRCode.py:230 +#: flatcamGUI/PreferencesUI.py:7575 flatcamTools/ToolQRCode.py:230 msgid "Set the QRCode fill color (squares color)." msgstr "Set the QRCode fill color (squares color)." -#: flatcamGUI/PreferencesUI.py:7088 flatcamTools/ToolQRCode.py:252 +#: flatcamGUI/PreferencesUI.py:7594 flatcamTools/ToolQRCode.py:252 msgid "Back Color" msgstr "Back Color" -#: flatcamGUI/PreferencesUI.py:7090 flatcamTools/ToolQRCode.py:254 +#: flatcamGUI/PreferencesUI.py:7596 flatcamTools/ToolQRCode.py:254 msgid "Set the QRCode background color." msgstr "Set the QRCode background color." -#: flatcamGUI/PreferencesUI.py:7130 +#: flatcamGUI/PreferencesUI.py:7636 msgid "Copper Thieving Tool Options" msgstr "Copper Thieving Tool Options" -#: flatcamGUI/PreferencesUI.py:7142 +#: flatcamGUI/PreferencesUI.py:7648 msgid "" "A tool to generate a Copper Thieving that can be added\n" "to a selected Gerber file." @@ -12154,16 +12729,16 @@ msgstr "" "A tool to generate a Copper Thieving that can be added\n" "to a selected Gerber file." -#: flatcamGUI/PreferencesUI.py:7150 +#: flatcamGUI/PreferencesUI.py:7656 msgid "Number of steps (lines) used to interpolate circles." msgstr "Number of steps (lines) used to interpolate circles." -#: flatcamGUI/PreferencesUI.py:7160 flatcamGUI/PreferencesUI.py:7364 -#: flatcamTools/ToolCopperThieving.py:96 flatcamTools/ToolCopperThieving.py:429 +#: flatcamGUI/PreferencesUI.py:7666 flatcamGUI/PreferencesUI.py:7870 +#: flatcamTools/ToolCopperThieving.py:97 flatcamTools/ToolCopperThieving.py:432 msgid "Clearance" msgstr "Clearance" -#: flatcamGUI/PreferencesUI.py:7162 +#: flatcamGUI/PreferencesUI.py:7668 msgid "" "This set the distance between the copper Thieving components\n" "(the polygon fill may be split in multiple polygons)\n" @@ -12173,22 +12748,11 @@ msgstr "" "(the polygon fill may be split in multiple polygons)\n" "and the copper traces in the Gerber file." -#: flatcamGUI/PreferencesUI.py:7190 flatcamTools/ToolCopperThieving.py:126 -#: flatcamTools/ToolNonCopperClear.py:430 flatcamTools/ToolPaint.py:308 -msgid "Area Selection" -msgstr "Area Selection" - -#: flatcamGUI/PreferencesUI.py:7191 flatcamTools/ToolCopperThieving.py:127 -#: flatcamTools/ToolNonCopperClear.py:431 flatcamTools/ToolPaint.py:310 -msgid "Reference Object" -msgstr "Reference Object" - -#: flatcamGUI/PreferencesUI.py:7193 flatcamTools/ToolCopperThieving.py:129 -#: flatcamTools/ToolNonCopperClear.py:433 +#: flatcamGUI/PreferencesUI.py:7699 flatcamTools/ToolCopperThieving.py:130 msgid "Reference:" msgstr "Reference:" -#: flatcamGUI/PreferencesUI.py:7195 +#: flatcamGUI/PreferencesUI.py:7701 msgid "" "- 'Itself' - the copper Thieving extent is based on the object extent.\n" "- 'Area Selection' - left mouse click to start selection of the area to be " @@ -12202,20 +12766,24 @@ msgstr "" "- 'Reference Object' - will do copper thieving within the area specified by " "another object." -#: flatcamGUI/PreferencesUI.py:7204 flatcamTools/ToolCopperThieving.py:170 +#: flatcamGUI/PreferencesUI.py:7710 flatcamGUI/PreferencesUI.py:8175 +#: flatcamGUI/PreferencesUI.py:8287 flatcamGUI/PreferencesUI.py:8387 +#: flatcamGUI/PreferencesUI.py:8501 flatcamTools/ToolCopperThieving.py:172 +#: flatcamTools/ToolExtractDrills.py:102 flatcamTools/ToolExtractDrills.py:240 +#: flatcamTools/ToolPunchGerber.py:113 flatcamTools/ToolPunchGerber.py:268 msgid "Rectangular" msgstr "Rectangular" -#: flatcamGUI/PreferencesUI.py:7205 flatcamTools/ToolCopperThieving.py:171 +#: flatcamGUI/PreferencesUI.py:7711 flatcamTools/ToolCopperThieving.py:173 msgid "Minimal" msgstr "Minimal" -#: flatcamGUI/PreferencesUI.py:7207 flatcamTools/ToolCopperThieving.py:173 +#: flatcamGUI/PreferencesUI.py:7713 flatcamTools/ToolCopperThieving.py:175 #: flatcamTools/ToolFilm.py:113 msgid "Box Type:" msgstr "Box Type:" -#: flatcamGUI/PreferencesUI.py:7209 flatcamTools/ToolCopperThieving.py:175 +#: flatcamGUI/PreferencesUI.py:7715 flatcamTools/ToolCopperThieving.py:177 msgid "" "- 'Rectangular' - the bounding box will be of rectangular shape.\n" "- 'Minimal' - the bounding box will be the convex hull shape." @@ -12223,23 +12791,23 @@ msgstr "" "- 'Rectangular' - the bounding box will be of rectangular shape.\n" "- 'Minimal' - the bounding box will be the convex hull shape." -#: flatcamGUI/PreferencesUI.py:7223 flatcamTools/ToolCopperThieving.py:191 +#: flatcamGUI/PreferencesUI.py:7729 flatcamTools/ToolCopperThieving.py:193 msgid "Dots Grid" msgstr "Dots Grid" -#: flatcamGUI/PreferencesUI.py:7224 flatcamTools/ToolCopperThieving.py:192 +#: flatcamGUI/PreferencesUI.py:7730 flatcamTools/ToolCopperThieving.py:194 msgid "Squares Grid" msgstr "Squares Grid" -#: flatcamGUI/PreferencesUI.py:7225 flatcamTools/ToolCopperThieving.py:193 +#: flatcamGUI/PreferencesUI.py:7731 flatcamTools/ToolCopperThieving.py:195 msgid "Lines Grid" msgstr "Lines Grid" -#: flatcamGUI/PreferencesUI.py:7227 flatcamTools/ToolCopperThieving.py:195 +#: flatcamGUI/PreferencesUI.py:7733 flatcamTools/ToolCopperThieving.py:197 msgid "Fill Type:" msgstr "Fill Type:" -#: flatcamGUI/PreferencesUI.py:7229 flatcamTools/ToolCopperThieving.py:197 +#: flatcamGUI/PreferencesUI.py:7735 flatcamTools/ToolCopperThieving.py:199 msgid "" "- 'Solid' - copper thieving will be a solid polygon.\n" "- 'Dots Grid' - the empty area will be filled with a pattern of dots.\n" @@ -12251,54 +12819,54 @@ msgstr "" "- 'Squares Grid' - the empty area will be filled with a pattern of squares.\n" "- 'Lines Grid' - the empty area will be filled with a pattern of lines." -#: flatcamGUI/PreferencesUI.py:7237 flatcamTools/ToolCopperThieving.py:216 +#: flatcamGUI/PreferencesUI.py:7743 flatcamTools/ToolCopperThieving.py:218 msgid "Dots Grid Parameters" msgstr "Dots Grid Parameters" -#: flatcamGUI/PreferencesUI.py:7243 flatcamTools/ToolCopperThieving.py:222 +#: flatcamGUI/PreferencesUI.py:7749 flatcamTools/ToolCopperThieving.py:224 msgid "Dot diameter in Dots Grid." msgstr "Dot diameter in Dots Grid." -#: flatcamGUI/PreferencesUI.py:7254 flatcamGUI/PreferencesUI.py:7283 -#: flatcamGUI/PreferencesUI.py:7312 flatcamTools/ToolCopperThieving.py:233 -#: flatcamTools/ToolCopperThieving.py:273 -#: flatcamTools/ToolCopperThieving.py:313 +#: flatcamGUI/PreferencesUI.py:7760 flatcamGUI/PreferencesUI.py:7789 +#: flatcamGUI/PreferencesUI.py:7818 flatcamTools/ToolCopperThieving.py:235 +#: flatcamTools/ToolCopperThieving.py:275 +#: flatcamTools/ToolCopperThieving.py:315 msgid "Spacing" msgstr "Spacing" -#: flatcamGUI/PreferencesUI.py:7256 flatcamTools/ToolCopperThieving.py:235 +#: flatcamGUI/PreferencesUI.py:7762 flatcamTools/ToolCopperThieving.py:237 msgid "Distance between each two dots in Dots Grid." msgstr "Distance between each two dots in Dots Grid." -#: flatcamGUI/PreferencesUI.py:7266 flatcamTools/ToolCopperThieving.py:256 +#: flatcamGUI/PreferencesUI.py:7772 flatcamTools/ToolCopperThieving.py:258 msgid "Squares Grid Parameters" msgstr "Squares Grid Parameters" -#: flatcamGUI/PreferencesUI.py:7272 flatcamTools/ToolCopperThieving.py:262 +#: flatcamGUI/PreferencesUI.py:7778 flatcamTools/ToolCopperThieving.py:264 msgid "Square side size in Squares Grid." msgstr "Square side size in Squares Grid." -#: flatcamGUI/PreferencesUI.py:7285 flatcamTools/ToolCopperThieving.py:275 +#: flatcamGUI/PreferencesUI.py:7791 flatcamTools/ToolCopperThieving.py:277 msgid "Distance between each two squares in Squares Grid." msgstr "Distance between each two squares in Squares Grid." -#: flatcamGUI/PreferencesUI.py:7295 flatcamTools/ToolCopperThieving.py:296 +#: flatcamGUI/PreferencesUI.py:7801 flatcamTools/ToolCopperThieving.py:298 msgid "Lines Grid Parameters" msgstr "Lines Grid Parameters" -#: flatcamGUI/PreferencesUI.py:7301 flatcamTools/ToolCopperThieving.py:302 +#: flatcamGUI/PreferencesUI.py:7807 flatcamTools/ToolCopperThieving.py:304 msgid "Line thickness size in Lines Grid." msgstr "Line thickness size in Lines Grid." -#: flatcamGUI/PreferencesUI.py:7314 flatcamTools/ToolCopperThieving.py:315 +#: flatcamGUI/PreferencesUI.py:7820 flatcamTools/ToolCopperThieving.py:317 msgid "Distance between each two lines in Lines Grid." msgstr "Distance between each two lines in Lines Grid." -#: flatcamGUI/PreferencesUI.py:7324 flatcamTools/ToolCopperThieving.py:353 +#: flatcamGUI/PreferencesUI.py:7830 flatcamTools/ToolCopperThieving.py:355 msgid "Robber Bar Parameters" msgstr "Robber Bar Parameters" -#: flatcamGUI/PreferencesUI.py:7326 flatcamTools/ToolCopperThieving.py:355 +#: flatcamGUI/PreferencesUI.py:7832 flatcamTools/ToolCopperThieving.py:357 msgid "" "Parameters used for the robber bar.\n" "Robber bar = copper border to help in pattern hole plating." @@ -12306,27 +12874,27 @@ msgstr "" "Parameters used for the robber bar.\n" "Robber bar = copper border to help in pattern hole plating." -#: flatcamGUI/PreferencesUI.py:7334 flatcamTools/ToolCopperThieving.py:363 +#: flatcamGUI/PreferencesUI.py:7840 flatcamTools/ToolCopperThieving.py:365 msgid "Bounding box margin for robber bar." msgstr "Bounding box margin for robber bar." -#: flatcamGUI/PreferencesUI.py:7345 flatcamTools/ToolCopperThieving.py:374 +#: flatcamGUI/PreferencesUI.py:7851 flatcamTools/ToolCopperThieving.py:376 msgid "Thickness" msgstr "Thickness" -#: flatcamGUI/PreferencesUI.py:7347 flatcamTools/ToolCopperThieving.py:376 +#: flatcamGUI/PreferencesUI.py:7853 flatcamTools/ToolCopperThieving.py:378 msgid "The robber bar thickness." msgstr "The robber bar thickness." -#: flatcamGUI/PreferencesUI.py:7357 flatcamTools/ToolCopperThieving.py:407 +#: flatcamGUI/PreferencesUI.py:7863 flatcamTools/ToolCopperThieving.py:409 msgid "Pattern Plating Mask" msgstr "Pattern Plating Mask" -#: flatcamGUI/PreferencesUI.py:7359 flatcamTools/ToolCopperThieving.py:409 +#: flatcamGUI/PreferencesUI.py:7865 flatcamTools/ToolCopperThieving.py:411 msgid "Generate a mask for pattern plating." msgstr "Generate a mask for pattern plating." -#: flatcamGUI/PreferencesUI.py:7366 flatcamTools/ToolCopperThieving.py:431 +#: flatcamGUI/PreferencesUI.py:7872 flatcamTools/ToolCopperThieving.py:434 msgid "" "The distance between the possible copper thieving elements\n" "and/or robber bar and the actual openings in the mask." @@ -12334,16 +12902,17 @@ msgstr "" "The distance between the possible copper thieving elements\n" "and/or robber bar and the actual openings in the mask." -#: flatcamGUI/PreferencesUI.py:7385 +#: flatcamGUI/PreferencesUI.py:7891 msgid "Fiducials Tool Options" msgstr "Fiducials Tool Options" -#: flatcamGUI/PreferencesUI.py:7396 flatcamGUI/PreferencesUI.py:7512 -#: flatcamTools/ToolCopperThieving.py:91 flatcamTools/ToolFiducials.py:151 +#: flatcamGUI/PreferencesUI.py:7902 flatcamGUI/PreferencesUI.py:8018 +#: flatcamGUI/PreferencesUI.py:8137 flatcamGUI/PreferencesUI.py:8349 +#: flatcamTools/ToolCopperThieving.py:92 flatcamTools/ToolFiducials.py:151 msgid "Parameters used for this tool." msgstr "Parameters used for this tool." -#: flatcamGUI/PreferencesUI.py:7403 flatcamTools/ToolFiducials.py:158 +#: flatcamGUI/PreferencesUI.py:7909 flatcamTools/ToolFiducials.py:158 msgid "" "This set the fiducial diameter if fiducial type is circular,\n" "otherwise is the size of the fiducial.\n" @@ -12353,19 +12922,19 @@ msgstr "" "otherwise is the size of the fiducial.\n" "The soldermask opening is double than that." -#: flatcamGUI/PreferencesUI.py:7431 flatcamTools/ToolFiducials.py:186 +#: flatcamGUI/PreferencesUI.py:7937 flatcamTools/ToolFiducials.py:186 msgid "Auto" msgstr "Auto" -#: flatcamGUI/PreferencesUI.py:7432 flatcamTools/ToolFiducials.py:187 +#: flatcamGUI/PreferencesUI.py:7938 flatcamTools/ToolFiducials.py:187 msgid "Manual" msgstr "Manual" -#: flatcamGUI/PreferencesUI.py:7434 flatcamTools/ToolFiducials.py:189 +#: flatcamGUI/PreferencesUI.py:7940 flatcamTools/ToolFiducials.py:189 msgid "Mode:" msgstr "Mode:" -#: flatcamGUI/PreferencesUI.py:7436 +#: flatcamGUI/PreferencesUI.py:7942 msgid "" "- 'Auto' - automatic placement of fiducials in the corners of the bounding " "box.\n" @@ -12375,19 +12944,19 @@ msgstr "" "box.\n" "- 'Manual' - manual placement of fiducials." -#: flatcamGUI/PreferencesUI.py:7444 flatcamTools/ToolFiducials.py:199 +#: flatcamGUI/PreferencesUI.py:7950 flatcamTools/ToolFiducials.py:199 msgid "Up" msgstr "Up" -#: flatcamGUI/PreferencesUI.py:7445 flatcamTools/ToolFiducials.py:200 +#: flatcamGUI/PreferencesUI.py:7951 flatcamTools/ToolFiducials.py:200 msgid "Down" msgstr "Down" -#: flatcamGUI/PreferencesUI.py:7448 flatcamTools/ToolFiducials.py:203 +#: flatcamGUI/PreferencesUI.py:7954 flatcamTools/ToolFiducials.py:203 msgid "Second fiducial" msgstr "Second fiducial" -#: flatcamGUI/PreferencesUI.py:7450 flatcamTools/ToolFiducials.py:205 +#: flatcamGUI/PreferencesUI.py:7956 flatcamTools/ToolFiducials.py:205 msgid "" "The position for the second fiducial.\n" "- 'Up' - the order is: bottom-left, top-left, top-right.\n" @@ -12399,19 +12968,19 @@ msgstr "" "- 'Down' - the order is: bottom-left, bottom-right, top-right.\n" "- 'None' - there is no second fiducial. The order is: bottom-left, top-right." -#: flatcamGUI/PreferencesUI.py:7466 flatcamTools/ToolFiducials.py:221 +#: flatcamGUI/PreferencesUI.py:7972 flatcamTools/ToolFiducials.py:221 msgid "Cross" msgstr "Cross" -#: flatcamGUI/PreferencesUI.py:7467 flatcamTools/ToolFiducials.py:222 +#: flatcamGUI/PreferencesUI.py:7973 flatcamTools/ToolFiducials.py:222 msgid "Chess" msgstr "Chess" -#: flatcamGUI/PreferencesUI.py:7470 flatcamTools/ToolFiducials.py:224 +#: flatcamGUI/PreferencesUI.py:7976 flatcamTools/ToolFiducials.py:224 msgid "Fiducial Type" msgstr "Fiducial Type" -#: flatcamGUI/PreferencesUI.py:7472 flatcamTools/ToolFiducials.py:226 +#: flatcamGUI/PreferencesUI.py:7978 flatcamTools/ToolFiducials.py:226 msgid "" "The type of fiducial.\n" "- 'Circular' - this is the regular fiducial.\n" @@ -12423,19 +12992,19 @@ msgstr "" "- 'Cross' - cross lines fiducial.\n" "- 'Chess' - chess pattern fiducial." -#: flatcamGUI/PreferencesUI.py:7481 flatcamTools/ToolFiducials.py:235 +#: flatcamGUI/PreferencesUI.py:7987 flatcamTools/ToolFiducials.py:235 msgid "Line thickness" msgstr "Line thickness" -#: flatcamGUI/PreferencesUI.py:7501 +#: flatcamGUI/PreferencesUI.py:8007 msgid "Calibration Tool Options" msgstr "Calibration Tool Options" -#: flatcamGUI/PreferencesUI.py:7517 flatcamTools/ToolCalibration.py:181 +#: flatcamGUI/PreferencesUI.py:8023 flatcamTools/ToolCalibration.py:181 msgid "Source Type" msgstr "Source Type" -#: flatcamGUI/PreferencesUI.py:7518 flatcamTools/ToolCalibration.py:182 +#: flatcamGUI/PreferencesUI.py:8024 flatcamTools/ToolCalibration.py:182 msgid "" "The source of calibration points.\n" "It can be:\n" @@ -12447,27 +13016,27 @@ msgstr "" "- Object -> click a hole geo for Excellon or a pad for Gerber\n" "- Free -> click freely on canvas to acquire the calibration points" -#: flatcamGUI/PreferencesUI.py:7523 flatcamTools/ToolCalibration.py:187 +#: flatcamGUI/PreferencesUI.py:8029 flatcamTools/ToolCalibration.py:187 msgid "Free" msgstr "Free" -#: flatcamGUI/PreferencesUI.py:7537 flatcamTools/ToolCalibration.py:76 +#: flatcamGUI/PreferencesUI.py:8043 flatcamTools/ToolCalibration.py:76 msgid "Height (Z) for travelling between the points." msgstr "Height (Z) for travelling between the points." -#: flatcamGUI/PreferencesUI.py:7549 flatcamTools/ToolCalibration.py:88 +#: flatcamGUI/PreferencesUI.py:8055 flatcamTools/ToolCalibration.py:88 msgid "Verification Z" msgstr "Verification Z" -#: flatcamGUI/PreferencesUI.py:7551 flatcamTools/ToolCalibration.py:90 +#: flatcamGUI/PreferencesUI.py:8057 flatcamTools/ToolCalibration.py:90 msgid "Height (Z) for checking the point." msgstr "Height (Z) for checking the point." -#: flatcamGUI/PreferencesUI.py:7563 flatcamTools/ToolCalibration.py:102 +#: flatcamGUI/PreferencesUI.py:8069 flatcamTools/ToolCalibration.py:102 msgid "Zero Z tool" msgstr "Zero Z tool" -#: flatcamGUI/PreferencesUI.py:7565 flatcamTools/ToolCalibration.py:104 +#: flatcamGUI/PreferencesUI.py:8071 flatcamTools/ToolCalibration.py:104 msgid "" "Include a sequence to zero the height (Z)\n" "of the verification tool." @@ -12475,11 +13044,11 @@ msgstr "" "Include a sequence to zero the height (Z)\n" "of the verification tool." -#: flatcamGUI/PreferencesUI.py:7574 flatcamTools/ToolCalibration.py:113 +#: flatcamGUI/PreferencesUI.py:8080 flatcamTools/ToolCalibration.py:113 msgid "Height (Z) for mounting the verification probe." msgstr "Height (Z) for mounting the verification probe." -#: flatcamGUI/PreferencesUI.py:7588 flatcamTools/ToolCalibration.py:127 +#: flatcamGUI/PreferencesUI.py:8094 flatcamTools/ToolCalibration.py:127 msgid "" "Toolchange X,Y position.\n" "If no value is entered then the current\n" @@ -12489,11 +13058,11 @@ msgstr "" "If no value is entered then the current\n" "(x, y) point will be used," -#: flatcamGUI/PreferencesUI.py:7599 flatcamTools/ToolCalibration.py:153 +#: flatcamGUI/PreferencesUI.py:8105 flatcamTools/ToolCalibration.py:153 msgid "Second point" msgstr "Second point" -#: flatcamGUI/PreferencesUI.py:7601 flatcamTools/ToolCalibration.py:155 +#: flatcamGUI/PreferencesUI.py:8107 flatcamTools/ToolCalibration.py:155 msgid "" "Second point in the Gcode verification can be:\n" "- top-left -> the user will align the PCB vertically\n" @@ -12503,45 +13072,263 @@ msgstr "" "- top-left -> the user will align the PCB vertically\n" "- bottom-right -> the user will align the PCB horizontally" -#: flatcamGUI/PreferencesUI.py:7605 flatcamTools/ToolCalibration.py:159 -msgid "Top-Left" -msgstr "Top-Left" +#: flatcamGUI/PreferencesUI.py:8126 +#| msgid "Excellon Options" +msgid "Extract Drills Options" +msgstr "Extract Drills Options" -#: flatcamGUI/PreferencesUI.py:7606 flatcamTools/ToolCalibration.py:160 -msgid "Bottom-Right" -msgstr "Bottom-Right" +#: flatcamGUI/PreferencesUI.py:8141 flatcamGUI/PreferencesUI.py:8353 +#: flatcamTools/ToolExtractDrills.py:68 flatcamTools/ToolPunchGerber.py:75 +msgid "Processed Pads Type" +msgstr "Processed Pads Type" -#: flatcamGUI/PreferencesUI.py:7620 +#: flatcamGUI/PreferencesUI.py:8143 flatcamGUI/PreferencesUI.py:8355 +#: flatcamTools/ToolExtractDrills.py:70 flatcamTools/ToolPunchGerber.py:77 +msgid "" +"The type of pads shape to be processed.\n" +"If the PCB has many SMD pads with rectangular pads,\n" +"disable the Rectangular aperture." +msgstr "" +"The type of pads shape to be processed.\n" +"If the PCB has many SMD pads with rectangular pads,\n" +"disable the Rectangular aperture." + +#: flatcamGUI/PreferencesUI.py:8153 flatcamGUI/PreferencesUI.py:8365 +#: flatcamTools/ToolExtractDrills.py:80 flatcamTools/ToolPunchGerber.py:91 +#| msgid "Circular Pad Array" +msgid "Process Circular Pads." +msgstr "Process Circular Pads." + +#: flatcamGUI/PreferencesUI.py:8159 flatcamGUI/PreferencesUI.py:8261 +#: flatcamGUI/PreferencesUI.py:8371 flatcamGUI/PreferencesUI.py:8475 +#: flatcamTools/ToolExtractDrills.py:86 flatcamTools/ToolExtractDrills.py:214 +#: flatcamTools/ToolPunchGerber.py:97 flatcamTools/ToolPunchGerber.py:242 +msgid "Oblong" +msgstr "Oblong" + +#: flatcamGUI/PreferencesUI.py:8161 flatcamGUI/PreferencesUI.py:8373 +#: flatcamTools/ToolExtractDrills.py:88 flatcamTools/ToolPunchGerber.py:99 +msgid "Process Oblong Pads." +msgstr "Process Oblong Pads." + +#: flatcamGUI/PreferencesUI.py:8169 flatcamGUI/PreferencesUI.py:8381 +#: flatcamTools/ToolExtractDrills.py:96 flatcamTools/ToolPunchGerber.py:107 +msgid "Process Square Pads." +msgstr "Process Square Pads." + +#: flatcamGUI/PreferencesUI.py:8177 flatcamGUI/PreferencesUI.py:8389 +#: flatcamTools/ToolExtractDrills.py:104 flatcamTools/ToolPunchGerber.py:115 +#| msgid "Rectangular" +msgid "Process Rectangular Pads." +msgstr "Process Rectangular Pads." + +#: flatcamGUI/PreferencesUI.py:8183 flatcamGUI/PreferencesUI.py:8300 +#: flatcamGUI/PreferencesUI.py:8395 flatcamGUI/PreferencesUI.py:8514 +#: flatcamTools/ToolExtractDrills.py:110 flatcamTools/ToolExtractDrills.py:253 +#: flatcamTools/ToolProperties.py:172 flatcamTools/ToolPunchGerber.py:121 +#: flatcamTools/ToolPunchGerber.py:281 +msgid "Others" +msgstr "Others" + +#: flatcamGUI/PreferencesUI.py:8185 flatcamGUI/PreferencesUI.py:8397 +#: flatcamTools/ToolExtractDrills.py:112 flatcamTools/ToolPunchGerber.py:123 +msgid "Process pads not in the categories above." +msgstr "Process pads not in the categories above." + +#: flatcamGUI/PreferencesUI.py:8198 flatcamGUI/PreferencesUI.py:8222 +#: flatcamGUI/PreferencesUI.py:8411 flatcamGUI/PreferencesUI.py:8436 +#: flatcamTools/ToolExtractDrills.py:139 flatcamTools/ToolExtractDrills.py:156 +#: flatcamTools/ToolPunchGerber.py:150 flatcamTools/ToolPunchGerber.py:184 +#| msgid "Tip Diameter" +msgid "Fixed Diameter" +msgstr "Fixed Diameter" + +#: flatcamGUI/PreferencesUI.py:8199 flatcamGUI/PreferencesUI.py:8239 +#: flatcamGUI/PreferencesUI.py:8412 flatcamGUI/PreferencesUI.py:8453 +#: flatcamTools/ToolExtractDrills.py:140 flatcamTools/ToolExtractDrills.py:192 +#: flatcamTools/ToolPunchGerber.py:151 flatcamTools/ToolPunchGerber.py:214 +#| msgid "Minimum Annular Ring" +msgid "Fixed Annular Ring" +msgstr "Fixed Annular Ring" + +#: flatcamGUI/PreferencesUI.py:8200 flatcamGUI/PreferencesUI.py:8413 +#: flatcamTools/ToolExtractDrills.py:141 flatcamTools/ToolPunchGerber.py:152 +#| msgid "Properties Tool" +msgid "Proportional" +msgstr "Proportional" + +#: flatcamGUI/PreferencesUI.py:8206 flatcamTools/ToolExtractDrills.py:130 +msgid "" +"The method for processing pads. Can be:\n" +"- Fixed Diameter -> all holes will have a set size\n" +"- Fixed Annular Ring -> all holes will have a set annular ring\n" +"- Proportional -> each hole size will be a fraction of the pad size" +msgstr "" +"The method for processing pads. Can be:\n" +"- Fixed Diameter -> all holes will have a set size\n" +"- Fixed Annular Ring -> all holes will have a set annular ring\n" +"- Proportional -> each hole size will be a fraction of the pad size" + +#: flatcamGUI/PreferencesUI.py:8232 flatcamGUI/PreferencesUI.py:8446 +#: flatcamTools/ToolExtractDrills.py:166 flatcamTools/ToolPunchGerber.py:194 +#| msgid "with diameter" +msgid "Fixed hole diameter." +msgstr "Fixed hole diameter." + +#: flatcamGUI/PreferencesUI.py:8241 flatcamGUI/PreferencesUI.py:8455 +#: flatcamTools/ToolExtractDrills.py:194 flatcamTools/ToolPunchGerber.py:216 +msgid "" +"The size of annular ring.\n" +"The copper sliver between the hole exterior\n" +"and the margin of the copper pad." +msgstr "" +"The size of annular ring.\n" +"The copper sliver between the hole exterior\n" +"and the margin of the copper pad." + +#: flatcamGUI/PreferencesUI.py:8250 flatcamGUI/PreferencesUI.py:8464 +#: flatcamTools/ToolExtractDrills.py:203 flatcamTools/ToolPunchGerber.py:231 +msgid "The size of annular ring for circular pads." +msgstr "The size of annular ring for circular pads." + +#: flatcamGUI/PreferencesUI.py:8263 flatcamGUI/PreferencesUI.py:8477 +#: flatcamTools/ToolExtractDrills.py:216 flatcamTools/ToolPunchGerber.py:244 +msgid "The size of annular ring for oblong pads." +msgstr "The size of annular ring for oblong pads." + +#: flatcamGUI/PreferencesUI.py:8276 flatcamGUI/PreferencesUI.py:8490 +#: flatcamTools/ToolExtractDrills.py:229 flatcamTools/ToolPunchGerber.py:257 +msgid "The size of annular ring for square pads." +msgstr "The size of annular ring for square pads." + +#: flatcamGUI/PreferencesUI.py:8289 flatcamGUI/PreferencesUI.py:8503 +#: flatcamTools/ToolExtractDrills.py:242 flatcamTools/ToolPunchGerber.py:270 +msgid "The size of annular ring for rectangular pads." +msgstr "The size of annular ring for rectangular pads." + +#: flatcamGUI/PreferencesUI.py:8302 flatcamGUI/PreferencesUI.py:8516 +#: flatcamTools/ToolExtractDrills.py:255 flatcamTools/ToolPunchGerber.py:283 +msgid "The size of annular ring for other pads." +msgstr "The size of annular ring for other pads." + +#: flatcamGUI/PreferencesUI.py:8312 flatcamGUI/PreferencesUI.py:8526 +#: flatcamTools/ToolExtractDrills.py:276 flatcamTools/ToolPunchGerber.py:299 +#| msgid "Tool Diameter" +msgid "Proportional Diameter" +msgstr "Proportional Diameter" + +#: flatcamGUI/PreferencesUI.py:8321 flatcamGUI/PreferencesUI.py:8535 +msgid "Factor" +msgstr "Factor" + +#: flatcamGUI/PreferencesUI.py:8323 flatcamGUI/PreferencesUI.py:8537 +#: flatcamTools/ToolExtractDrills.py:287 flatcamTools/ToolPunchGerber.py:310 +msgid "" +"Proportional Diameter.\n" +"The hole diameter will be a fraction of the pad size." +msgstr "" +"Proportional Diameter.\n" +"The hole diameter will be a fraction of the pad size." + +#: flatcamGUI/PreferencesUI.py:8338 +#| msgid "Gerber Options" +msgid "Punch Gerber Options" +msgstr "Punch Gerber Options" + +#: flatcamGUI/PreferencesUI.py:8419 flatcamTools/ToolPunchGerber.py:141 +msgid "" +"The punch hole source can be:\n" +"- Excellon Object-> the Excellon object drills center will serve as " +"reference.\n" +"- Fixed Diameter -> will try to use the pads center as reference adding " +"fixed diameter holes.\n" +"- Fixed Annular Ring -> will try to keep a set annular ring.\n" +"- Proportional -> will make a Gerber punch hole having the diameter a " +"percentage of the pad diameter.\n" +msgstr "" +"The punch hole source can be:\n" +"- Excellon Object-> the Excellon object drills center will serve as " +"reference.\n" +"- Fixed Diameter -> will try to use the pads center as reference adding " +"fixed diameter holes.\n" +"- Fixed Annular Ring -> will try to keep a set annular ring.\n" +"- Proportional -> will make a Gerber punch hole having the diameter a " +"percentage of the pad diameter.\n" + +#: flatcamGUI/PreferencesUI.py:8552 +#| msgid "Gerber Options" +msgid "Invert Gerber Tool Options" +msgstr "Invert Gerber Tool Options" + +#: flatcamGUI/PreferencesUI.py:8558 +msgid "" +"A tool to invert Gerber geometry from positive to negative\n" +"and in revers." +msgstr "" +"A tool to invert Gerber geometry from positive to negative\n" +"and in revers." + +#: flatcamGUI/PreferencesUI.py:8572 flatcamTools/ToolInvertGerber.py:90 +#| msgid "" +#| "Distance by which to avoid\n" +#| "the edges of the polygon to\n" +#| "be painted." +msgid "" +"Distance by which to avoid\n" +"the edges of the Gerber object." +msgstr "" +"Distance by which to avoid\n" +"the edges of the Gerber object." + +#: flatcamGUI/PreferencesUI.py:8583 flatcamTools/ToolInvertGerber.py:101 +msgid "Lines Join Style" +msgstr "Lines Join Style" + +#: flatcamGUI/PreferencesUI.py:8585 flatcamTools/ToolInvertGerber.py:103 +msgid "" +"The way that the lines in the object outline will be joined.\n" +"Can be:\n" +"- rounded -> an arc is added between two joining lines\n" +"- square -> the lines meet in 90 degrees angle\n" +"- bevel -> the lines are joined by a third line" +msgstr "" +"The way that the lines in the object outline will be joined.\n" +"Can be:\n" +"- rounded -> an arc is added between two joining lines\n" +"- square -> the lines meet in 90 degrees angle\n" +"- bevel -> the lines are joined by a third line" + +#: flatcamGUI/PreferencesUI.py:8608 msgid "Excellon File associations" msgstr "Excellon File associations" -#: flatcamGUI/PreferencesUI.py:7633 flatcamGUI/PreferencesUI.py:7706 -#: flatcamGUI/PreferencesUI.py:7776 flatcamGUI/PreferencesUI.py:7846 +#: flatcamGUI/PreferencesUI.py:8621 flatcamGUI/PreferencesUI.py:8694 +#: flatcamGUI/PreferencesUI.py:8764 flatcamGUI/PreferencesUI.py:8834 msgid "Restore" msgstr "Restore" -#: flatcamGUI/PreferencesUI.py:7634 flatcamGUI/PreferencesUI.py:7707 -#: flatcamGUI/PreferencesUI.py:7777 +#: flatcamGUI/PreferencesUI.py:8622 flatcamGUI/PreferencesUI.py:8695 +#: flatcamGUI/PreferencesUI.py:8765 msgid "Restore the extension list to the default state." msgstr "Restore the extension list to the default state." -#: flatcamGUI/PreferencesUI.py:7635 flatcamGUI/PreferencesUI.py:7708 -#: flatcamGUI/PreferencesUI.py:7778 flatcamGUI/PreferencesUI.py:7848 +#: flatcamGUI/PreferencesUI.py:8623 flatcamGUI/PreferencesUI.py:8696 +#: flatcamGUI/PreferencesUI.py:8766 flatcamGUI/PreferencesUI.py:8836 msgid "Delete All" msgstr "Delete All" -#: flatcamGUI/PreferencesUI.py:7636 flatcamGUI/PreferencesUI.py:7709 -#: flatcamGUI/PreferencesUI.py:7779 +#: flatcamGUI/PreferencesUI.py:8624 flatcamGUI/PreferencesUI.py:8697 +#: flatcamGUI/PreferencesUI.py:8767 msgid "Delete all extensions from the list." msgstr "Delete all extensions from the list." -#: flatcamGUI/PreferencesUI.py:7644 flatcamGUI/PreferencesUI.py:7717 -#: flatcamGUI/PreferencesUI.py:7787 +#: flatcamGUI/PreferencesUI.py:8632 flatcamGUI/PreferencesUI.py:8705 +#: flatcamGUI/PreferencesUI.py:8775 msgid "Extensions list" msgstr "Extensions list" -#: flatcamGUI/PreferencesUI.py:7646 flatcamGUI/PreferencesUI.py:7719 -#: flatcamGUI/PreferencesUI.py:7789 +#: flatcamGUI/PreferencesUI.py:8634 flatcamGUI/PreferencesUI.py:8707 +#: flatcamGUI/PreferencesUI.py:8777 msgid "" "List of file extensions to be\n" "associated with FlatCAM." @@ -12549,43 +13336,43 @@ msgstr "" "List of file extensions to be\n" "associated with FlatCAM." -#: flatcamGUI/PreferencesUI.py:7666 flatcamGUI/PreferencesUI.py:7739 -#: flatcamGUI/PreferencesUI.py:7808 flatcamGUI/PreferencesUI.py:7880 +#: flatcamGUI/PreferencesUI.py:8654 flatcamGUI/PreferencesUI.py:8727 +#: flatcamGUI/PreferencesUI.py:8796 flatcamGUI/PreferencesUI.py:8868 msgid "Extension" msgstr "Extension" -#: flatcamGUI/PreferencesUI.py:7667 flatcamGUI/PreferencesUI.py:7740 -#: flatcamGUI/PreferencesUI.py:7809 +#: flatcamGUI/PreferencesUI.py:8655 flatcamGUI/PreferencesUI.py:8728 +#: flatcamGUI/PreferencesUI.py:8797 msgid "A file extension to be added or deleted to the list." msgstr "A file extension to be added or deleted to the list." -#: flatcamGUI/PreferencesUI.py:7675 flatcamGUI/PreferencesUI.py:7748 -#: flatcamGUI/PreferencesUI.py:7817 +#: flatcamGUI/PreferencesUI.py:8663 flatcamGUI/PreferencesUI.py:8736 +#: flatcamGUI/PreferencesUI.py:8805 msgid "Add Extension" msgstr "Add Extension" -#: flatcamGUI/PreferencesUI.py:7676 flatcamGUI/PreferencesUI.py:7749 -#: flatcamGUI/PreferencesUI.py:7818 +#: flatcamGUI/PreferencesUI.py:8664 flatcamGUI/PreferencesUI.py:8737 +#: flatcamGUI/PreferencesUI.py:8806 msgid "Add a file extension to the list" msgstr "Add a file extension to the list" -#: flatcamGUI/PreferencesUI.py:7677 flatcamGUI/PreferencesUI.py:7750 -#: flatcamGUI/PreferencesUI.py:7819 +#: flatcamGUI/PreferencesUI.py:8665 flatcamGUI/PreferencesUI.py:8738 +#: flatcamGUI/PreferencesUI.py:8807 msgid "Delete Extension" msgstr "Delete Extension" -#: flatcamGUI/PreferencesUI.py:7678 flatcamGUI/PreferencesUI.py:7751 -#: flatcamGUI/PreferencesUI.py:7820 +#: flatcamGUI/PreferencesUI.py:8666 flatcamGUI/PreferencesUI.py:8739 +#: flatcamGUI/PreferencesUI.py:8808 msgid "Delete a file extension from the list" msgstr "Delete a file extension from the list" -#: flatcamGUI/PreferencesUI.py:7685 flatcamGUI/PreferencesUI.py:7758 -#: flatcamGUI/PreferencesUI.py:7827 +#: flatcamGUI/PreferencesUI.py:8673 flatcamGUI/PreferencesUI.py:8746 +#: flatcamGUI/PreferencesUI.py:8815 msgid "Apply Association" msgstr "Apply Association" -#: flatcamGUI/PreferencesUI.py:7686 flatcamGUI/PreferencesUI.py:7759 -#: flatcamGUI/PreferencesUI.py:7828 +#: flatcamGUI/PreferencesUI.py:8674 flatcamGUI/PreferencesUI.py:8747 +#: flatcamGUI/PreferencesUI.py:8816 msgid "" "Apply the file associations between\n" "FlatCAM and the files with above extensions.\n" @@ -12597,31 +13384,31 @@ msgstr "" "They will be active after next logon.\n" "This work only in Windows." -#: flatcamGUI/PreferencesUI.py:7703 +#: flatcamGUI/PreferencesUI.py:8691 msgid "GCode File associations" msgstr "GCode File associations" -#: flatcamGUI/PreferencesUI.py:7773 +#: flatcamGUI/PreferencesUI.py:8761 msgid "Gerber File associations" msgstr "Gerber File associations" -#: flatcamGUI/PreferencesUI.py:7843 +#: flatcamGUI/PreferencesUI.py:8831 msgid "Autocompleter Keywords" msgstr "Autocompleter Keywords" -#: flatcamGUI/PreferencesUI.py:7847 +#: flatcamGUI/PreferencesUI.py:8835 msgid "Restore the autocompleter keywords list to the default state." msgstr "Restore the autocompleter keywords list to the default state." -#: flatcamGUI/PreferencesUI.py:7849 +#: flatcamGUI/PreferencesUI.py:8837 msgid "Delete all autocompleter keywords from the list." msgstr "Delete all autocompleter keywords from the list." -#: flatcamGUI/PreferencesUI.py:7857 +#: flatcamGUI/PreferencesUI.py:8845 msgid "Keywords list" msgstr "Keywords list" -#: flatcamGUI/PreferencesUI.py:7859 +#: flatcamGUI/PreferencesUI.py:8847 msgid "" "List of keywords used by\n" "the autocompleter in FlatCAM.\n" @@ -12633,31 +13420,31 @@ msgstr "" "The autocompleter is installed\n" "in the Code Editor and for the Tcl Shell." -#: flatcamGUI/PreferencesUI.py:7881 +#: flatcamGUI/PreferencesUI.py:8869 msgid "A keyword to be added or deleted to the list." msgstr "A keyword to be added or deleted to the list." -#: flatcamGUI/PreferencesUI.py:7889 +#: flatcamGUI/PreferencesUI.py:8877 msgid "Add keyword" msgstr "Add keyword" -#: flatcamGUI/PreferencesUI.py:7890 +#: flatcamGUI/PreferencesUI.py:8878 msgid "Add a keyword to the list" msgstr "Add a keyword to the list" -#: flatcamGUI/PreferencesUI.py:7891 +#: flatcamGUI/PreferencesUI.py:8879 msgid "Delete keyword" msgstr "Delete keyword" -#: flatcamGUI/PreferencesUI.py:7892 +#: flatcamGUI/PreferencesUI.py:8880 msgid "Delete a keyword from the list" msgstr "Delete a keyword from the list" -#: flatcamParsers/ParseExcellon.py:314 +#: flatcamParsers/ParseExcellon.py:315 msgid "This is GCODE mark" msgstr "This is GCODE mark" -#: flatcamParsers/ParseExcellon.py:431 +#: flatcamParsers/ParseExcellon.py:432 msgid "" "No tool diameter info's. See shell.\n" "A tool change event: T" @@ -12665,7 +13452,7 @@ msgstr "" "No tool diameter info's. See shell.\n" "A tool change event: T" -#: flatcamParsers/ParseExcellon.py:434 +#: flatcamParsers/ParseExcellon.py:435 msgid "" "was found but the Excellon file have no informations regarding the tool " "diameters therefore the application will try to load it by using some 'fake' " @@ -12679,11 +13466,11 @@ msgstr "" "The user needs to edit the resulting Excellon object and change the " "diameters to reflect the real diameters." -#: flatcamParsers/ParseExcellon.py:886 flatcamTools/ToolSolderPaste.py:1330 +#: flatcamParsers/ParseExcellon.py:897 flatcamTools/ToolSolderPaste.py:1327 msgid "An internal error has ocurred. See shell.\n" msgstr "An internal error has ocurred. See shell.\n" -#: flatcamParsers/ParseExcellon.py:889 +#: flatcamParsers/ParseExcellon.py:900 msgid "" "Excellon Parser error.\n" "Parsing Failed. Line" @@ -12691,7 +13478,7 @@ msgstr "" "Excellon Parser error.\n" "Parsing Failed. Line" -#: flatcamParsers/ParseExcellon.py:973 +#: flatcamParsers/ParseExcellon.py:982 msgid "" "Excellon.create_geometry() -> a drill location was skipped due of not having " "a tool associated.\n" @@ -12709,22 +13496,22 @@ msgstr "Font not supported, try another one." msgid "Gerber processing. Parsing" msgstr "Gerber processing. Parsing" -#: flatcamParsers/ParseGerber.py:426 flatcamParsers/ParseHPGL2.py:176 +#: flatcamParsers/ParseGerber.py:426 flatcamParsers/ParseHPGL2.py:178 msgid "lines" msgstr "lines" -#: flatcamParsers/ParseGerber.py:970 flatcamParsers/ParseGerber.py:1065 -#: flatcamParsers/ParseHPGL2.py:269 flatcamParsers/ParseHPGL2.py:283 -#: flatcamParsers/ParseHPGL2.py:302 flatcamParsers/ParseHPGL2.py:326 -#: flatcamParsers/ParseHPGL2.py:361 +#: flatcamParsers/ParseGerber.py:1002 flatcamParsers/ParseGerber.py:1102 +#: flatcamParsers/ParseHPGL2.py:271 flatcamParsers/ParseHPGL2.py:285 +#: flatcamParsers/ParseHPGL2.py:304 flatcamParsers/ParseHPGL2.py:328 +#: flatcamParsers/ParseHPGL2.py:363 msgid "Coordinates missing, line ignored" msgstr "Coordinates missing, line ignored" -#: flatcamParsers/ParseGerber.py:972 flatcamParsers/ParseGerber.py:1067 +#: flatcamParsers/ParseGerber.py:1004 flatcamParsers/ParseGerber.py:1104 msgid "GERBER file might be CORRUPT. Check the file !!!" msgstr "GERBER file might be CORRUPT. Check the file !!!" -#: flatcamParsers/ParseGerber.py:1021 +#: flatcamParsers/ParseGerber.py:1058 msgid "" "Region does not have enough points. File will be processed but there are " "parser errors. Line number" @@ -12732,66 +13519,238 @@ msgstr "" "Region does not have enough points. File will be processed but there are " "parser errors. Line number" -#: flatcamParsers/ParseGerber.py:1421 flatcamParsers/ParseHPGL2.py:396 +#: flatcamParsers/ParseGerber.py:1488 flatcamParsers/ParseHPGL2.py:398 msgid "Gerber processing. Joining polygons" msgstr "Gerber processing. Joining polygons" -#: flatcamParsers/ParseGerber.py:1438 +#: flatcamParsers/ParseGerber.py:1505 msgid "Gerber processing. Applying Gerber polarity." msgstr "Gerber processing. Applying Gerber polarity." -#: flatcamParsers/ParseGerber.py:1498 +#: flatcamParsers/ParseGerber.py:1565 msgid "Gerber Line" msgstr "Gerber Line" -#: flatcamParsers/ParseGerber.py:1498 +#: flatcamParsers/ParseGerber.py:1565 msgid "Gerber Line Content" msgstr "Gerber Line Content" -#: flatcamParsers/ParseGerber.py:1500 +#: flatcamParsers/ParseGerber.py:1567 msgid "Gerber Parser ERROR" msgstr "Gerber Parser ERROR" -#: flatcamParsers/ParseGerber.py:1884 +#: flatcamParsers/ParseGerber.py:1956 msgid "Gerber Scale done." msgstr "Gerber Scale done." -#: flatcamParsers/ParseGerber.py:1977 +#: flatcamParsers/ParseGerber.py:2049 msgid "Gerber Offset done." msgstr "Gerber Offset done." -#: flatcamParsers/ParseGerber.py:2054 +#: flatcamParsers/ParseGerber.py:2126 msgid "Gerber Mirror done." msgstr "Gerber Mirror done." -#: flatcamParsers/ParseGerber.py:2128 +#: flatcamParsers/ParseGerber.py:2200 msgid "Gerber Skew done." msgstr "Gerber Skew done." -#: flatcamParsers/ParseGerber.py:2192 +#: flatcamParsers/ParseGerber.py:2263 msgid "Gerber Rotate done." msgstr "Gerber Rotate done." -#: flatcamParsers/ParseGerber.py:2273 +#: flatcamParsers/ParseGerber.py:2419 msgid "Gerber Buffer done." msgstr "Gerber Buffer done." -#: flatcamParsers/ParseHPGL2.py:176 +#: flatcamParsers/ParseHPGL2.py:178 msgid "HPGL2 processing. Parsing" msgstr "HPGL2 processing. Parsing" -#: flatcamParsers/ParseHPGL2.py:408 +#: flatcamParsers/ParseHPGL2.py:410 msgid "HPGL2 Line" msgstr "HPGL2 Line" -#: flatcamParsers/ParseHPGL2.py:408 +#: flatcamParsers/ParseHPGL2.py:410 msgid "HPGL2 Line Content" msgstr "HPGL2 Line Content" -#: flatcamParsers/ParseHPGL2.py:409 +#: flatcamParsers/ParseHPGL2.py:411 msgid "HPGL2 Parser ERROR" msgstr "HPGL2 Parser ERROR" +#: flatcamTools/ToolAlignObjects.py:32 +#| msgid "Objects" +msgid "Align Objects" +msgstr "Align Objects" + +#: flatcamTools/ToolAlignObjects.py:61 +#| msgid "Object" +msgid "MOVING object" +msgstr "MOVING object" + +#: flatcamTools/ToolAlignObjects.py:65 +#| msgid "" +#| "Specify the type of object to be panelized\n" +#| "It can be of type: Gerber, Excellon or Geometry.\n" +#| "The selection here decide the type of objects that will be\n" +#| "in the Object combobox." +msgid "" +"Specify the type of object to be aligned.\n" +"It can be of type: Gerber or Excellon.\n" +"The selection here decide the type of objects that will be\n" +"in the Object combobox." +msgstr "" +"Specify the type of object to be aligned.\n" +"It can be of type: Gerber or Excellon.\n" +"The selection here decide the type of objects that will be\n" +"in the Object combobox." + +#: flatcamTools/ToolAlignObjects.py:86 +#| msgid "Object to be painted." +msgid "Object to be aligned." +msgstr "Object to be aligned." + +#: flatcamTools/ToolAlignObjects.py:98 +msgid "TARGET object" +msgstr "TARGET object" + +#: flatcamTools/ToolAlignObjects.py:100 +#| msgid "" +#| "Specify the type of object to be panelized\n" +#| "It can be of type: Gerber, Excellon or Geometry.\n" +#| "The selection here decide the type of objects that will be\n" +#| "in the Object combobox." +msgid "" +"Specify the type of object to be aligned to.\n" +"It can be of type: Gerber or Excellon.\n" +"The selection here decide the type of objects that will be\n" +"in the Object combobox." +msgstr "" +"Specify the type of object to be aligned to.\n" +"It can be of type: Gerber or Excellon.\n" +"The selection here decide the type of objects that will be\n" +"in the Object combobox." + +#: flatcamTools/ToolAlignObjects.py:122 +#| msgid "Object to be painted." +msgid "Object to be aligned to. Aligner." +msgstr "Object to be aligned to. Aligner." + +#: flatcamTools/ToolAlignObjects.py:135 +#| msgid "Alignment" +msgid "Alignment Type" +msgstr "Alignment Type" + +#: flatcamTools/ToolAlignObjects.py:137 +msgid "" +"The type of alignment can be:\n" +"- Single Point -> it require a single point of sync, the action will be a " +"translation\n" +"- Dual Point -> it require two points of sync, the action will be " +"translation followed by rotation" +msgstr "" +"The type of alignment can be:\n" +"- Single Point -> it require a single point of sync, the action will be a " +"translation\n" +"- Dual Point -> it require two points of sync, the action will be " +"translation followed by rotation" + +#: flatcamTools/ToolAlignObjects.py:143 +#| msgid "Single Polygon" +msgid "Single Point" +msgstr "Single Point" + +#: flatcamTools/ToolAlignObjects.py:144 +#| msgid "Half Point" +msgid "Dual Point" +msgstr "Dual Point" + +#: flatcamTools/ToolAlignObjects.py:159 +#| msgid "Align Left" +msgid "Align Object" +msgstr "Align Object" + +#: flatcamTools/ToolAlignObjects.py:161 +msgid "" +"Align the specified object to the aligner object.\n" +"If only one point is used then it assumes translation.\n" +"If tho points are used it assume translation and rotation." +msgstr "" +"Align the specified object to the aligner object.\n" +"If only one point is used then it assumes translation.\n" +"If tho points are used it assume translation and rotation." + +#: flatcamTools/ToolAlignObjects.py:176 flatcamTools/ToolCalculators.py:246 +#: flatcamTools/ToolCalibration.py:683 flatcamTools/ToolCopperThieving.py:485 +#: flatcamTools/ToolCutOut.py:372 flatcamTools/ToolDblSided.py:472 +#: flatcamTools/ToolExtractDrills.py:310 flatcamTools/ToolFiducials.py:318 +#: flatcamTools/ToolFilm.py:520 flatcamTools/ToolInvertGerber.py:140 +#: flatcamTools/ToolNCC.py:612 flatcamTools/ToolOptimal.py:238 +#: flatcamTools/ToolPaint.py:556 flatcamTools/ToolPanelize.py:269 +#: flatcamTools/ToolPunchGerber.py:339 flatcamTools/ToolQRCode.py:314 +#: flatcamTools/ToolRulesCheck.py:516 flatcamTools/ToolSolderPaste.py:474 +#: flatcamTools/ToolSub.py:176 flatcamTools/ToolTransform.py:399 +msgid "Reset Tool" +msgstr "Reset Tool" + +#: flatcamTools/ToolAlignObjects.py:178 flatcamTools/ToolCalculators.py:248 +#: flatcamTools/ToolCalibration.py:685 flatcamTools/ToolCopperThieving.py:487 +#: flatcamTools/ToolCutOut.py:374 flatcamTools/ToolDblSided.py:474 +#: flatcamTools/ToolExtractDrills.py:312 flatcamTools/ToolFiducials.py:320 +#: flatcamTools/ToolFilm.py:522 flatcamTools/ToolInvertGerber.py:142 +#: flatcamTools/ToolNCC.py:614 flatcamTools/ToolOptimal.py:240 +#: flatcamTools/ToolPaint.py:558 flatcamTools/ToolPanelize.py:271 +#: flatcamTools/ToolPunchGerber.py:341 flatcamTools/ToolQRCode.py:316 +#: flatcamTools/ToolRulesCheck.py:518 flatcamTools/ToolSolderPaste.py:476 +#: flatcamTools/ToolSub.py:178 flatcamTools/ToolTransform.py:401 +msgid "Will reset the tool parameters." +msgstr "Will reset the tool parameters." + +#: flatcamTools/ToolAlignObjects.py:244 +#| msgid "Poligonize Tool" +msgid "Align Tool" +msgstr "Align Tool" + +#: flatcamTools/ToolAlignObjects.py:289 +#| msgid "There is no FlatCAM object selected..." +msgid "There is no aligned FlatCAM object selected..." +msgstr "There is no aligned FlatCAM object selected..." + +#: flatcamTools/ToolAlignObjects.py:299 +#| msgid "There is no FlatCAM object selected..." +msgid "There is no aligner FlatCAM object selected..." +msgstr "There is no aligner FlatCAM object selected..." + +#: flatcamTools/ToolAlignObjects.py:325 flatcamTools/ToolAlignObjects.py:385 +#| msgid "First object point" +msgid "First Point" +msgstr "First Point" + +#: flatcamTools/ToolAlignObjects.py:325 flatcamTools/ToolAlignObjects.py:400 +#| msgid "Click on target point." +msgid "Click on the START point." +msgstr "Click on the START point." + +#: flatcamTools/ToolAlignObjects.py:380 flatcamTools/ToolCalibration.py:920 +msgid "Cancelled by user request." +msgstr "Cancelled by user request." + +#: flatcamTools/ToolAlignObjects.py:385 flatcamTools/ToolAlignObjects.py:407 +#| msgid "Click on target point." +msgid "Click on the DESTINATION point." +msgstr "Click on the DESTINATION point." + +#: flatcamTools/ToolAlignObjects.py:385 flatcamTools/ToolAlignObjects.py:400 +#: flatcamTools/ToolAlignObjects.py:407 +msgid " Or right click to cancel." +msgstr " Or right click to cancel." + +#: flatcamTools/ToolAlignObjects.py:400 flatcamTools/ToolAlignObjects.py:407 +#: flatcamTools/ToolFiducials.py:111 +msgid "Second Point" +msgstr "Second Point" + #: flatcamTools/ToolCalculators.py:24 msgid "Calculators" msgstr "Calculators" @@ -12878,7 +13837,7 @@ msgstr "" "Calculate the current intensity value and the procedure time,\n" "depending on the parameters above" -#: flatcamTools/ToolCalculators.py:285 +#: flatcamTools/ToolCalculators.py:299 msgid "Calc. Tool" msgstr "Calc. Tool" @@ -12904,25 +13863,25 @@ msgstr "" "Those four points should be in the four\n" "(as much as possible) corners of the object." -#: flatcamTools/ToolCalibration.py:193 flatcamTools/ToolCutOut.py:80 -#: flatcamTools/ToolFilm.py:78 flatcamTools/ToolImage.py:55 -#: flatcamTools/ToolPanelize.py:66 flatcamTools/ToolProperties.py:169 +#: flatcamTools/ToolCalibration.py:193 flatcamTools/ToolFilm.py:76 +#: flatcamTools/ToolImage.py:54 flatcamTools/ToolPanelize.py:78 +#: flatcamTools/ToolProperties.py:177 msgid "Object Type" msgstr "Object Type" -#: flatcamTools/ToolCalibration.py:211 +#: flatcamTools/ToolCalibration.py:210 msgid "Source object selection" msgstr "Source object selection" -#: flatcamTools/ToolCalibration.py:213 +#: flatcamTools/ToolCalibration.py:212 msgid "FlatCAM Object to be used as a source for reference points." msgstr "FlatCAM Object to be used as a source for reference points." -#: flatcamTools/ToolCalibration.py:219 +#: flatcamTools/ToolCalibration.py:218 msgid "Calibration Points" msgstr "Calibration Points" -#: flatcamTools/ToolCalibration.py:221 +#: flatcamTools/ToolCalibration.py:220 msgid "" "Contain the expected calibration points and the\n" "ones measured." @@ -12930,56 +13889,52 @@ msgstr "" "Contain the expected calibration points and the\n" "ones measured." -#: flatcamTools/ToolCalibration.py:236 flatcamTools/ToolSub.py:74 -#: flatcamTools/ToolSub.py:126 +#: flatcamTools/ToolCalibration.py:235 flatcamTools/ToolSub.py:76 +#: flatcamTools/ToolSub.py:131 msgid "Target" msgstr "Target" -#: flatcamTools/ToolCalibration.py:237 +#: flatcamTools/ToolCalibration.py:236 msgid "Found Delta" msgstr "Found Delta" -#: flatcamTools/ToolCalibration.py:249 +#: flatcamTools/ToolCalibration.py:248 msgid "Bot Left X" msgstr "Bot Left X" -#: flatcamTools/ToolCalibration.py:258 +#: flatcamTools/ToolCalibration.py:257 msgid "Bot Left Y" msgstr "Bot Left Y" -#: flatcamTools/ToolCalibration.py:266 flatcamTools/ToolCalibration.py:267 -msgid "Origin" -msgstr "Origin" - -#: flatcamTools/ToolCalibration.py:278 +#: flatcamTools/ToolCalibration.py:275 msgid "Bot Right X" msgstr "Bot Right X" -#: flatcamTools/ToolCalibration.py:288 +#: flatcamTools/ToolCalibration.py:285 msgid "Bot Right Y" msgstr "Bot Right Y" -#: flatcamTools/ToolCalibration.py:303 +#: flatcamTools/ToolCalibration.py:300 msgid "Top Left X" msgstr "Top Left X" -#: flatcamTools/ToolCalibration.py:312 +#: flatcamTools/ToolCalibration.py:309 msgid "Top Left Y" msgstr "Top Left Y" -#: flatcamTools/ToolCalibration.py:327 +#: flatcamTools/ToolCalibration.py:324 msgid "Top Right X" msgstr "Top Right X" -#: flatcamTools/ToolCalibration.py:337 +#: flatcamTools/ToolCalibration.py:334 msgid "Top Right Y" msgstr "Top Right Y" -#: flatcamTools/ToolCalibration.py:370 +#: flatcamTools/ToolCalibration.py:367 msgid "Get Points" msgstr "Get Points" -#: flatcamTools/ToolCalibration.py:372 +#: flatcamTools/ToolCalibration.py:369 msgid "" "Pick four points by clicking on canvas if the source choice\n" "is 'free' or inside the object geometry if the source is 'object'.\n" @@ -12991,11 +13946,11 @@ msgstr "" "Those four points should be in the four squares of\n" "the object." -#: flatcamTools/ToolCalibration.py:393 +#: flatcamTools/ToolCalibration.py:390 msgid "STEP 2: Verification GCode" msgstr "STEP 2: Verification GCode" -#: flatcamTools/ToolCalibration.py:395 flatcamTools/ToolCalibration.py:408 +#: flatcamTools/ToolCalibration.py:392 flatcamTools/ToolCalibration.py:405 msgid "" "Generate GCode file to locate and align the PCB by using\n" "the four points acquired above.\n" @@ -13013,15 +13968,15 @@ msgstr "" "- third point -> check point. Can be: top-left or bottom-right.\n" "- forth point -> final verification point. Just for evaluation." -#: flatcamTools/ToolCalibration.py:406 flatcamTools/ToolSolderPaste.py:347 +#: flatcamTools/ToolCalibration.py:403 flatcamTools/ToolSolderPaste.py:349 msgid "Generate GCode" msgstr "Generate GCode" -#: flatcamTools/ToolCalibration.py:432 +#: flatcamTools/ToolCalibration.py:429 msgid "STEP 3: Adjustments" msgstr "STEP 3: Adjustments" -#: flatcamTools/ToolCalibration.py:434 flatcamTools/ToolCalibration.py:443 +#: flatcamTools/ToolCalibration.py:431 flatcamTools/ToolCalibration.py:440 msgid "" "Calculate Scale and Skew factors based on the differences (delta)\n" "found when checking the PCB pattern. The differences must be filled\n" @@ -13031,15 +13986,15 @@ msgstr "" "found when checking the PCB pattern. The differences must be filled\n" "in the fields Found (Delta)." -#: flatcamTools/ToolCalibration.py:441 +#: flatcamTools/ToolCalibration.py:438 msgid "Calculate Factors" msgstr "Calculate Factors" -#: flatcamTools/ToolCalibration.py:463 +#: flatcamTools/ToolCalibration.py:460 msgid "STEP 4: Adjusted GCode" msgstr "STEP 4: Adjusted GCode" -#: flatcamTools/ToolCalibration.py:465 +#: flatcamTools/ToolCalibration.py:462 msgid "" "Generate verification GCode file adjusted with\n" "the factors above." @@ -13047,43 +14002,43 @@ msgstr "" "Generate verification GCode file adjusted with\n" "the factors above." -#: flatcamTools/ToolCalibration.py:470 +#: flatcamTools/ToolCalibration.py:467 msgid "Scale Factor X:" msgstr "Scale Factor X:" -#: flatcamTools/ToolCalibration.py:482 +#: flatcamTools/ToolCalibration.py:479 msgid "Scale Factor Y:" msgstr "Scale Factor Y:" -#: flatcamTools/ToolCalibration.py:494 +#: flatcamTools/ToolCalibration.py:491 msgid "Apply Scale Factors" msgstr "Apply Scale Factors" -#: flatcamTools/ToolCalibration.py:496 +#: flatcamTools/ToolCalibration.py:493 msgid "Apply Scale factors on the calibration points." msgstr "Apply Scale factors on the calibration points." -#: flatcamTools/ToolCalibration.py:506 +#: flatcamTools/ToolCalibration.py:503 msgid "Skew Angle X:" msgstr "Skew Angle X:" -#: flatcamTools/ToolCalibration.py:519 +#: flatcamTools/ToolCalibration.py:516 msgid "Skew Angle Y:" msgstr "Skew Angle Y:" -#: flatcamTools/ToolCalibration.py:532 +#: flatcamTools/ToolCalibration.py:529 msgid "Apply Skew Factors" msgstr "Apply Skew Factors" -#: flatcamTools/ToolCalibration.py:534 +#: flatcamTools/ToolCalibration.py:531 msgid "Apply Skew factors on the calibration points." msgstr "Apply Skew factors on the calibration points." -#: flatcamTools/ToolCalibration.py:603 +#: flatcamTools/ToolCalibration.py:600 msgid "Generate Adjusted GCode" msgstr "Generate Adjusted GCode" -#: flatcamTools/ToolCalibration.py:605 +#: flatcamTools/ToolCalibration.py:602 msgid "" "Generate verification GCode file adjusted with\n" "the factors set above.\n" @@ -13095,11 +14050,11 @@ msgstr "" "The GCode parameters can be readjusted\n" "before clicking this button." -#: flatcamTools/ToolCalibration.py:626 +#: flatcamTools/ToolCalibration.py:623 msgid "STEP 5: Calibrate FlatCAM Objects" msgstr "STEP 5: Calibrate FlatCAM Objects" -#: flatcamTools/ToolCalibration.py:628 +#: flatcamTools/ToolCalibration.py:625 msgid "" "Adjust the FlatCAM objects\n" "with the factors determined and verified above." @@ -13107,27 +14062,27 @@ msgstr "" "Adjust the FlatCAM objects\n" "with the factors determined and verified above." -#: flatcamTools/ToolCalibration.py:641 +#: flatcamTools/ToolCalibration.py:637 msgid "Adjusted object type" msgstr "Adjusted object type" -#: flatcamTools/ToolCalibration.py:643 +#: flatcamTools/ToolCalibration.py:638 msgid "Type of the FlatCAM Object to be adjusted." msgstr "Type of the FlatCAM Object to be adjusted." -#: flatcamTools/ToolCalibration.py:654 +#: flatcamTools/ToolCalibration.py:651 msgid "Adjusted object selection" msgstr "Adjusted object selection" -#: flatcamTools/ToolCalibration.py:656 +#: flatcamTools/ToolCalibration.py:653 msgid "The FlatCAM Object to be adjusted." msgstr "The FlatCAM Object to be adjusted." -#: flatcamTools/ToolCalibration.py:663 +#: flatcamTools/ToolCalibration.py:660 msgid "Calibrate" msgstr "Calibrate" -#: flatcamTools/ToolCalibration.py:665 +#: flatcamTools/ToolCalibration.py:662 msgid "" "Adjust (scale and/or skew) the objects\n" "with the factors determined above." @@ -13135,79 +14090,59 @@ msgstr "" "Adjust (scale and/or skew) the objects\n" "with the factors determined above." -#: flatcamTools/ToolCalibration.py:686 flatcamTools/ToolCopperThieving.py:482 -#: flatcamTools/ToolCutOut.py:362 flatcamTools/ToolDblSided.py:405 -#: flatcamTools/ToolFiducials.py:316 flatcamTools/ToolFilm.py:518 -#: flatcamTools/ToolNonCopperClear.py:486 flatcamTools/ToolOptimal.py:237 -#: flatcamTools/ToolPaint.py:372 flatcamTools/ToolPanelize.py:266 -#: flatcamTools/ToolQRCode.py:314 flatcamTools/ToolRulesCheck.py:507 -#: flatcamTools/ToolSolderPaste.py:470 flatcamTools/ToolSub.py:170 -msgid "Reset Tool" -msgstr "Reset Tool" +#: flatcamTools/ToolCalibration.py:770 flatcamTools/ToolCalibration.py:771 +msgid "Origin" +msgstr "Origin" -#: flatcamTools/ToolCalibration.py:688 flatcamTools/ToolCopperThieving.py:484 -#: flatcamTools/ToolCutOut.py:364 flatcamTools/ToolDblSided.py:407 -#: flatcamTools/ToolFiducials.py:318 flatcamTools/ToolFilm.py:520 -#: flatcamTools/ToolNonCopperClear.py:488 flatcamTools/ToolOptimal.py:239 -#: flatcamTools/ToolPaint.py:374 flatcamTools/ToolPanelize.py:268 -#: flatcamTools/ToolQRCode.py:316 flatcamTools/ToolRulesCheck.py:509 -#: flatcamTools/ToolSolderPaste.py:472 flatcamTools/ToolSub.py:172 -msgid "Will reset the tool parameters." -msgstr "Will reset the tool parameters." - -#: flatcamTools/ToolCalibration.py:792 +#: flatcamTools/ToolCalibration.py:800 msgid "Tool initialized" msgstr "Tool initialized" -#: flatcamTools/ToolCalibration.py:824 +#: flatcamTools/ToolCalibration.py:838 msgid "There is no source FlatCAM object selected..." msgstr "There is no source FlatCAM object selected..." -#: flatcamTools/ToolCalibration.py:845 +#: flatcamTools/ToolCalibration.py:859 msgid "Get First calibration point. Bottom Left..." msgstr "Get First calibration point. Bottom Left..." -#: flatcamTools/ToolCalibration.py:906 -msgid "Cancelled by user request." -msgstr "Cancelled by user request." - -#: flatcamTools/ToolCalibration.py:912 +#: flatcamTools/ToolCalibration.py:926 msgid "Get Second calibration point. Bottom Right (Top Left)..." msgstr "Get Second calibration point. Bottom Right (Top Left)..." -#: flatcamTools/ToolCalibration.py:916 +#: flatcamTools/ToolCalibration.py:930 msgid "Get Third calibration point. Top Left (Bottom Right)..." msgstr "Get Third calibration point. Top Left (Bottom Right)..." -#: flatcamTools/ToolCalibration.py:920 +#: flatcamTools/ToolCalibration.py:934 msgid "Get Forth calibration point. Top Right..." msgstr "Get Forth calibration point. Top Right..." -#: flatcamTools/ToolCalibration.py:924 +#: flatcamTools/ToolCalibration.py:938 msgid "Done. All four points have been acquired." msgstr "Done. All four points have been acquired." -#: flatcamTools/ToolCalibration.py:955 +#: flatcamTools/ToolCalibration.py:969 msgid "Verification GCode for FlatCAM Calibration Tool" msgstr "Verification GCode for FlatCAM Calibration Tool" -#: flatcamTools/ToolCalibration.py:967 flatcamTools/ToolCalibration.py:1053 +#: flatcamTools/ToolCalibration.py:981 flatcamTools/ToolCalibration.py:1067 msgid "Gcode Viewer" msgstr "Gcode Viewer" -#: flatcamTools/ToolCalibration.py:983 +#: flatcamTools/ToolCalibration.py:997 msgid "Cancelled. Four points are needed for GCode generation." msgstr "Cancelled. Four points are needed for GCode generation." -#: flatcamTools/ToolCalibration.py:1239 flatcamTools/ToolCalibration.py:1335 +#: flatcamTools/ToolCalibration.py:1253 flatcamTools/ToolCalibration.py:1349 msgid "There is no FlatCAM object selected..." msgstr "There is no FlatCAM object selected..." -#: flatcamTools/ToolCopperThieving.py:76 flatcamTools/ToolFiducials.py:260 +#: flatcamTools/ToolCopperThieving.py:77 flatcamTools/ToolFiducials.py:261 msgid "Gerber Object to which will be added a copper thieving." msgstr "Gerber Object to which will be added a copper thieving." -#: flatcamTools/ToolCopperThieving.py:98 +#: flatcamTools/ToolCopperThieving.py:99 msgid "" "This set the distance between the copper thieving components\n" "(the polygon fill may be split in multiple polygons)\n" @@ -13217,7 +14152,7 @@ msgstr "" "(the polygon fill may be split in multiple polygons)\n" "and the copper traces in the Gerber file." -#: flatcamTools/ToolCopperThieving.py:131 +#: flatcamTools/ToolCopperThieving.py:132 msgid "" "- 'Itself' - the copper thieving extent is based on the object extent.\n" "- 'Area Selection' - left mouse click to start selection of the area to be " @@ -13231,12 +14166,12 @@ msgstr "" "- 'Reference Object' - will do copper thieving within the area specified by " "another object." -#: flatcamTools/ToolCopperThieving.py:138 -#: flatcamTools/ToolNonCopperClear.py:445 flatcamTools/ToolPaint.py:326 +#: flatcamTools/ToolCopperThieving.py:139 flatcamTools/ToolNCC.py:552 +#: flatcamTools/ToolPaint.py:496 msgid "Ref. Type" msgstr "Ref. Type" -#: flatcamTools/ToolCopperThieving.py:140 +#: flatcamTools/ToolCopperThieving.py:141 msgid "" "The type of FlatCAM object to be used as copper thieving reference.\n" "It can be Gerber, Excellon or Geometry." @@ -13244,36 +14179,21 @@ msgstr "" "The type of FlatCAM object to be used as copper thieving reference.\n" "It can be Gerber, Excellon or Geometry." -#: flatcamTools/ToolCopperThieving.py:144 flatcamTools/ToolDblSided.py:215 -#: flatcamTools/ToolNonCopperClear.py:451 flatcamTools/ToolPaint.py:332 -msgid "Reference Gerber" -msgstr "Reference Gerber" - -#: flatcamTools/ToolCopperThieving.py:145 flatcamTools/ToolDblSided.py:216 -#: flatcamTools/ToolNonCopperClear.py:452 flatcamTools/ToolPaint.py:333 -msgid "Reference Excellon" -msgstr "Reference Excellon" - -#: flatcamTools/ToolCopperThieving.py:146 flatcamTools/ToolDblSided.py:217 -#: flatcamTools/ToolNonCopperClear.py:453 flatcamTools/ToolPaint.py:334 -msgid "Reference Geometry" -msgstr "Reference Geometry" - -#: flatcamTools/ToolCopperThieving.py:151 -#: flatcamTools/ToolNonCopperClear.py:456 flatcamTools/ToolPaint.py:337 +#: flatcamTools/ToolCopperThieving.py:150 flatcamTools/ToolNCC.py:562 +#: flatcamTools/ToolPaint.py:506 msgid "Ref. Object" msgstr "Ref. Object" -#: flatcamTools/ToolCopperThieving.py:153 -#: flatcamTools/ToolNonCopperClear.py:458 flatcamTools/ToolPaint.py:339 +#: flatcamTools/ToolCopperThieving.py:152 flatcamTools/ToolNCC.py:564 +#: flatcamTools/ToolPaint.py:508 msgid "The FlatCAM object to be used as non copper clearing reference." msgstr "The FlatCAM object to be used as non copper clearing reference." -#: flatcamTools/ToolCopperThieving.py:326 +#: flatcamTools/ToolCopperThieving.py:328 msgid "Insert Copper thieving" msgstr "Insert Copper thieving" -#: flatcamTools/ToolCopperThieving.py:328 +#: flatcamTools/ToolCopperThieving.py:330 msgid "" "Will add a polygon (may be split in multiple parts)\n" "that will surround the actual Gerber traces at a certain distance." @@ -13281,11 +14201,11 @@ msgstr "" "Will add a polygon (may be split in multiple parts)\n" "that will surround the actual Gerber traces at a certain distance." -#: flatcamTools/ToolCopperThieving.py:387 +#: flatcamTools/ToolCopperThieving.py:389 msgid "Insert Robber Bar" msgstr "Insert Robber Bar" -#: flatcamTools/ToolCopperThieving.py:389 +#: flatcamTools/ToolCopperThieving.py:391 msgid "" "Will add a polygon with a defined thickness\n" "that will surround the actual Gerber object\n" @@ -13297,11 +14217,11 @@ msgstr "" "at a certain distance.\n" "Required when doing holes pattern plating." -#: flatcamTools/ToolCopperThieving.py:413 +#: flatcamTools/ToolCopperThieving.py:415 msgid "Select Soldermask object" msgstr "Select Soldermask object" -#: flatcamTools/ToolCopperThieving.py:415 +#: flatcamTools/ToolCopperThieving.py:417 msgid "" "Gerber Object with the soldermask.\n" "It will be used as a base for\n" @@ -13311,11 +14231,11 @@ msgstr "" "It will be used as a base for\n" "the pattern plating mask." -#: flatcamTools/ToolCopperThieving.py:443 +#: flatcamTools/ToolCopperThieving.py:446 msgid "Plated area" msgstr "Plated area" -#: flatcamTools/ToolCopperThieving.py:445 +#: flatcamTools/ToolCopperThieving.py:448 msgid "" "The area to be plated by pattern plating.\n" "Basically is made from the openings in the plating mask.\n" @@ -13333,19 +14253,19 @@ msgstr "" "a bit larger than the copper pads, and this area is\n" "calculated from the soldermask openings." -#: flatcamTools/ToolCopperThieving.py:456 +#: flatcamTools/ToolCopperThieving.py:459 msgid "mm" msgstr "mm" -#: flatcamTools/ToolCopperThieving.py:458 +#: flatcamTools/ToolCopperThieving.py:461 msgid "in" msgstr "in" -#: flatcamTools/ToolCopperThieving.py:465 +#: flatcamTools/ToolCopperThieving.py:468 msgid "Generate pattern plating mask" msgstr "Generate pattern plating mask" -#: flatcamTools/ToolCopperThieving.py:467 +#: flatcamTools/ToolCopperThieving.py:470 msgid "" "Will add to the soldermask gerber geometry\n" "the geometries of the copper thieving and/or\n" @@ -13355,133 +14275,134 @@ msgstr "" "the geometries of the copper thieving and/or\n" "the robber bar if those were generated." -#: flatcamTools/ToolCopperThieving.py:620 -#: flatcamTools/ToolCopperThieving.py:645 +#: flatcamTools/ToolCopperThieving.py:626 +#: flatcamTools/ToolCopperThieving.py:651 msgid "Lines Grid works only for 'itself' reference ..." msgstr "Lines Grid works only for 'itself' reference ..." -#: flatcamTools/ToolCopperThieving.py:631 +#: flatcamTools/ToolCopperThieving.py:637 msgid "Solid fill selected." msgstr "Solid fill selected." -#: flatcamTools/ToolCopperThieving.py:636 +#: flatcamTools/ToolCopperThieving.py:642 msgid "Dots grid fill selected." msgstr "Dots grid fill selected." -#: flatcamTools/ToolCopperThieving.py:641 +#: flatcamTools/ToolCopperThieving.py:647 msgid "Squares grid fill selected." msgstr "Squares grid fill selected." -#: flatcamTools/ToolCopperThieving.py:662 -#: flatcamTools/ToolCopperThieving.py:744 -#: flatcamTools/ToolCopperThieving.py:1340 flatcamTools/ToolDblSided.py:564 -#: flatcamTools/ToolFiducials.py:464 flatcamTools/ToolFiducials.py:741 -#: flatcamTools/ToolOptimal.py:342 flatcamTools/ToolQRCode.py:424 +#: flatcamTools/ToolCopperThieving.py:668 +#: flatcamTools/ToolCopperThieving.py:750 +#: flatcamTools/ToolCopperThieving.py:1346 flatcamTools/ToolDblSided.py:658 +#: flatcamTools/ToolExtractDrills.py:436 flatcamTools/ToolFiducials.py:466 +#: flatcamTools/ToolFiducials.py:743 flatcamTools/ToolOptimal.py:343 +#: flatcamTools/ToolPunchGerber.py:512 flatcamTools/ToolQRCode.py:426 msgid "There is no Gerber object loaded ..." msgstr "There is no Gerber object loaded ..." -#: flatcamTools/ToolCopperThieving.py:675 -#: flatcamTools/ToolCopperThieving.py:1268 +#: flatcamTools/ToolCopperThieving.py:681 +#: flatcamTools/ToolCopperThieving.py:1274 msgid "Append geometry" msgstr "Append geometry" -#: flatcamTools/ToolCopperThieving.py:719 -#: flatcamTools/ToolCopperThieving.py:1301 -#: flatcamTools/ToolCopperThieving.py:1454 +#: flatcamTools/ToolCopperThieving.py:725 +#: flatcamTools/ToolCopperThieving.py:1307 +#: flatcamTools/ToolCopperThieving.py:1460 msgid "Append source file" msgstr "Append source file" -#: flatcamTools/ToolCopperThieving.py:727 -#: flatcamTools/ToolCopperThieving.py:1309 +#: flatcamTools/ToolCopperThieving.py:733 +#: flatcamTools/ToolCopperThieving.py:1315 msgid "Copper Thieving Tool done." msgstr "Copper Thieving Tool done." -#: flatcamTools/ToolCopperThieving.py:754 -#: flatcamTools/ToolCopperThieving.py:787 flatcamTools/ToolCutOut.py:468 -#: flatcamTools/ToolCutOut.py:642 flatcamTools/ToolNonCopperClear.py:1151 -#: flatcamTools/ToolNonCopperClear.py:1192 -#: flatcamTools/ToolNonCopperClear.py:1224 flatcamTools/ToolPaint.py:1074 -#: flatcamTools/ToolPanelize.py:401 flatcamTools/ToolPanelize.py:416 -#: flatcamTools/ToolSub.py:288 flatcamTools/ToolSub.py:301 -#: flatcamTools/ToolSub.py:492 flatcamTools/ToolSub.py:507 -#: tclCommands/TclCommandCopperClear.py:97 -#: tclCommands/TclCommandCopperClear.py:146 tclCommands/TclCommandPaint.py:97 +#: flatcamTools/ToolCopperThieving.py:760 +#: flatcamTools/ToolCopperThieving.py:793 flatcamTools/ToolCutOut.py:480 +#: flatcamTools/ToolCutOut.py:667 flatcamTools/ToolInvertGerber.py:208 +#: flatcamTools/ToolNCC.py:1603 flatcamTools/ToolNCC.py:1644 +#: flatcamTools/ToolNCC.py:1673 flatcamTools/ToolPaint.py:1462 +#: flatcamTools/ToolPanelize.py:413 flatcamTools/ToolPanelize.py:428 +#: flatcamTools/ToolSub.py:294 flatcamTools/ToolSub.py:307 +#: flatcamTools/ToolSub.py:498 flatcamTools/ToolSub.py:513 +#: tclCommands/TclCommandCopperClear.py:97 tclCommands/TclCommandPaint.py:99 msgid "Could not retrieve object" msgstr "Could not retrieve object" -#: flatcamTools/ToolCopperThieving.py:764 -#: flatcamTools/ToolNonCopperClear.py:1205 +#: flatcamTools/ToolCopperThieving.py:770 flatcamTools/ToolNCC.py:1652 msgid "Click the start point of the area." msgstr "Click the start point of the area." -#: flatcamTools/ToolCopperThieving.py:815 +#: flatcamTools/ToolCopperThieving.py:821 msgid "Click the end point of the filling area." msgstr "Click the end point of the filling area." -#: flatcamTools/ToolCopperThieving.py:821 -#: flatcamTools/ToolNonCopperClear.py:1261 flatcamTools/ToolPaint.py:1201 +#: flatcamTools/ToolCopperThieving.py:827 flatcamTools/ToolNCC.py:1714 +#: flatcamTools/ToolNCC.py:1766 flatcamTools/ToolPaint.py:1594 +#: flatcamTools/ToolPaint.py:1645 msgid "Zone added. Click to start adding next zone or right click to finish." msgstr "Zone added. Click to start adding next zone or right click to finish." -#: flatcamTools/ToolCopperThieving.py:937 -#: flatcamTools/ToolCopperThieving.py:941 -#: flatcamTools/ToolCopperThieving.py:1002 +#: flatcamTools/ToolCopperThieving.py:943 +#: flatcamTools/ToolCopperThieving.py:947 +#: flatcamTools/ToolCopperThieving.py:1008 msgid "Thieving" msgstr "Thieving" -#: flatcamTools/ToolCopperThieving.py:948 +#: flatcamTools/ToolCopperThieving.py:954 msgid "Copper Thieving Tool started. Reading parameters." msgstr "Copper Thieving Tool started. Reading parameters." -#: flatcamTools/ToolCopperThieving.py:973 +#: flatcamTools/ToolCopperThieving.py:979 msgid "Copper Thieving Tool. Preparing isolation polygons." msgstr "Copper Thieving Tool. Preparing isolation polygons." -#: flatcamTools/ToolCopperThieving.py:1018 +#: flatcamTools/ToolCopperThieving.py:1024 msgid "Copper Thieving Tool. Preparing areas to fill with copper." msgstr "Copper Thieving Tool. Preparing areas to fill with copper." -#: flatcamTools/ToolCopperThieving.py:1029 flatcamTools/ToolOptimal.py:349 -#: flatcamTools/ToolPanelize.py:793 flatcamTools/ToolRulesCheck.py:1118 +#: flatcamTools/ToolCopperThieving.py:1035 flatcamTools/ToolOptimal.py:350 +#: flatcamTools/ToolPanelize.py:802 flatcamTools/ToolRulesCheck.py:1127 msgid "Working..." msgstr "Working..." -#: flatcamTools/ToolCopperThieving.py:1056 +#: flatcamTools/ToolCopperThieving.py:1062 msgid "Geometry not supported for bounding box" msgstr "Geometry not supported for bounding box" -#: flatcamTools/ToolCopperThieving.py:1062 -#: flatcamTools/ToolNonCopperClear.py:1513 flatcamTools/ToolPaint.py:2673 +#: flatcamTools/ToolCopperThieving.py:1068 flatcamTools/ToolNCC.py:1933 +#: flatcamTools/ToolNCC.py:1988 flatcamTools/ToolNCC.py:2992 +#: flatcamTools/ToolPaint.py:3854 msgid "No object available." msgstr "No object available." -#: flatcamTools/ToolCopperThieving.py:1099 -#: flatcamTools/ToolNonCopperClear.py:1555 +#: flatcamTools/ToolCopperThieving.py:1105 flatcamTools/ToolNCC.py:1958 +#: flatcamTools/ToolNCC.py:2011 flatcamTools/ToolNCC.py:3034 msgid "The reference object type is not supported." msgstr "The reference object type is not supported." -#: flatcamTools/ToolCopperThieving.py:1104 +#: flatcamTools/ToolCopperThieving.py:1110 msgid "Copper Thieving Tool. Appending new geometry and buffering." msgstr "Copper Thieving Tool. Appending new geometry and buffering." -#: flatcamTools/ToolCopperThieving.py:1120 +#: flatcamTools/ToolCopperThieving.py:1126 msgid "Create geometry" msgstr "Create geometry" -#: flatcamTools/ToolCopperThieving.py:1320 -#: flatcamTools/ToolCopperThieving.py:1324 +#: flatcamTools/ToolCopperThieving.py:1326 +#: flatcamTools/ToolCopperThieving.py:1330 msgid "P-Plating Mask" msgstr "P-Plating Mask" -#: flatcamTools/ToolCopperThieving.py:1346 +#: flatcamTools/ToolCopperThieving.py:1352 msgid "Append PP-M geometry" msgstr "Append PP-M geometry" -#: flatcamTools/ToolCopperThieving.py:1472 +#: flatcamTools/ToolCopperThieving.py:1478 msgid "Generating Pattern Plating Mask done." msgstr "Generating Pattern Plating Mask done." -#: flatcamTools/ToolCopperThieving.py:1544 +#: flatcamTools/ToolCopperThieving.py:1550 msgid "Copper Thieving Tool exit." msgstr "Copper Thieving Tool exit." @@ -13489,31 +14410,45 @@ msgstr "Copper Thieving Tool exit." msgid "Cutout PCB" msgstr "Cutout PCB" -#: flatcamTools/ToolCutOut.py:82 -msgid "" -"Specify the type of object to be cutout.\n" -"It can be of type: Gerber or Geometry.\n" -"What is selected here will dictate the kind\n" -"of objects that will populate the 'Object' combobox." -msgstr "" -"Specify the type of object to be cutout.\n" -"It can be of type: Gerber or Geometry.\n" -"What is selected here will dictate the kind\n" -"of objects that will populate the 'Object' combobox." +#: flatcamTools/ToolCutOut.py:70 flatcamTools/ToolPanelize.py:54 +#| msgid "Move Objects" +msgid "Source Object" +msgstr "Source Object" -#: flatcamTools/ToolCutOut.py:91 flatcamTools/ToolCutOut.py:92 +#: flatcamTools/ToolCutOut.py:71 msgid "Object to be cutout" msgstr "Object to be cutout" -#: flatcamTools/ToolCutOut.py:230 +#: flatcamTools/ToolCutOut.py:76 +msgid "Kind" +msgstr "Kind" + +#: flatcamTools/ToolCutOut.py:98 +msgid "" +"Specify the type of object to be cutout.\n" +"It can be of type: Gerber or Geometry.\n" +"What is selected here will dictate the kind\n" +"of objects that will populate the 'Object' combobox." +msgstr "" +"Specify the type of object to be cutout.\n" +"It can be of type: Gerber or Geometry.\n" +"What is selected here will dictate the kind\n" +"of objects that will populate the 'Object' combobox." + +#: flatcamTools/ToolCutOut.py:122 +#| msgid "Slot Parameters" +msgid "Tool Parameters" +msgstr "Tool Parameters" + +#: flatcamTools/ToolCutOut.py:239 msgid "A. Automatic Bridge Gaps" msgstr "A. Automatic Bridge Gaps" -#: flatcamTools/ToolCutOut.py:232 +#: flatcamTools/ToolCutOut.py:241 msgid "This section handle creation of automatic bridge gaps." msgstr "This section handle creation of automatic bridge gaps." -#: flatcamTools/ToolCutOut.py:243 +#: flatcamTools/ToolCutOut.py:252 msgid "" "Number of gaps used for the Automatic cutout.\n" "There can be maximum 8 bridges/gaps.\n" @@ -13537,11 +14472,11 @@ msgstr "" "- 2tb - 2*top + 2*bottom\n" "- 8 - 2*left + 2*right +2*top + 2*bottom" -#: flatcamTools/ToolCutOut.py:264 +#: flatcamTools/ToolCutOut.py:273 msgid "Generate Freeform Geometry" msgstr "Generate Freeform Geometry" -#: flatcamTools/ToolCutOut.py:266 +#: flatcamTools/ToolCutOut.py:275 msgid "" "Cutout the selected object.\n" "The cutout shape can be of any shape.\n" @@ -13551,11 +14486,11 @@ msgstr "" "The cutout shape can be of any shape.\n" "Useful when the PCB has a non-rectangular shape." -#: flatcamTools/ToolCutOut.py:278 +#: flatcamTools/ToolCutOut.py:287 msgid "Generate Rectangular Geometry" msgstr "Generate Rectangular Geometry" -#: flatcamTools/ToolCutOut.py:280 +#: flatcamTools/ToolCutOut.py:289 msgid "" "Cutout the selected object.\n" "The resulting cutout shape is\n" @@ -13567,11 +14502,11 @@ msgstr "" "always a rectangle shape and it will be\n" "the bounding box of the Object." -#: flatcamTools/ToolCutOut.py:299 +#: flatcamTools/ToolCutOut.py:308 msgid "B. Manual Bridge Gaps" msgstr "B. Manual Bridge Gaps" -#: flatcamTools/ToolCutOut.py:301 +#: flatcamTools/ToolCutOut.py:310 msgid "" "This section handle creation of manual bridge gaps.\n" "This is done by mouse clicking on the perimeter of the\n" @@ -13581,15 +14516,15 @@ msgstr "" "This is done by mouse clicking on the perimeter of the\n" "Geometry object that is used as a cutout object. " -#: flatcamTools/ToolCutOut.py:319 +#: flatcamTools/ToolCutOut.py:329 msgid "Geometry object used to create the manual cutout." msgstr "Geometry object used to create the manual cutout." -#: flatcamTools/ToolCutOut.py:328 +#: flatcamTools/ToolCutOut.py:338 msgid "Generate Manual Geometry" msgstr "Generate Manual Geometry" -#: flatcamTools/ToolCutOut.py:330 +#: flatcamTools/ToolCutOut.py:340 msgid "" "If the object to be cutout is a Gerber\n" "first create a Geometry that surrounds it,\n" @@ -13601,11 +14536,11 @@ msgstr "" "to be used as the cutout, if one doesn't exist yet.\n" "Select the source Gerber file in the top object combobox." -#: flatcamTools/ToolCutOut.py:343 +#: flatcamTools/ToolCutOut.py:353 msgid "Manual Add Bridge Gaps" msgstr "Manual Add Bridge Gaps" -#: flatcamTools/ToolCutOut.py:345 +#: flatcamTools/ToolCutOut.py:355 msgid "" "Use the left mouse button (LMB) click\n" "to create a bridge gap to separate the PCB from\n" @@ -13619,7 +14554,7 @@ msgstr "" "The LMB click has to be done on the perimeter of\n" "the Geometry object used as a cutout geometry." -#: flatcamTools/ToolCutOut.py:473 +#: flatcamTools/ToolCutOut.py:485 msgid "" "There is no object selected for Cutout.\n" "Select one and try again." @@ -13627,16 +14562,17 @@ msgstr "" "There is no object selected for Cutout.\n" "Select one and try again." -#: flatcamTools/ToolCutOut.py:479 flatcamTools/ToolCutOut.py:651 -#: flatcamTools/ToolCutOut.py:795 flatcamTools/ToolCutOut.py:877 +#: flatcamTools/ToolCutOut.py:491 flatcamTools/ToolCutOut.py:676 +#: flatcamTools/ToolCutOut.py:839 flatcamTools/ToolCutOut.py:921 +#: tclCommands/TclCommandGeoCutout.py:185 msgid "Tool Diameter is zero value. Change it to a positive real number." msgstr "Tool Diameter is zero value. Change it to a positive real number." -#: flatcamTools/ToolCutOut.py:493 flatcamTools/ToolCutOut.py:666 +#: flatcamTools/ToolCutOut.py:505 flatcamTools/ToolCutOut.py:691 msgid "Number of gaps value is missing. Add it and retry." msgstr "Number of gaps value is missing. Add it and retry." -#: flatcamTools/ToolCutOut.py:498 flatcamTools/ToolCutOut.py:670 +#: flatcamTools/ToolCutOut.py:510 flatcamTools/ToolCutOut.py:695 msgid "" "Gaps value can be only one of: 'None', 'lr', 'tb', '2lr', '2tb', 4 or 8. " "Fill in a correct value and retry. " @@ -13644,7 +14580,7 @@ msgstr "" "Gaps value can be only one of: 'None', 'lr', 'tb', '2lr', '2tb', 4 or 8. " "Fill in a correct value and retry. " -#: flatcamTools/ToolCutOut.py:503 flatcamTools/ToolCutOut.py:676 +#: flatcamTools/ToolCutOut.py:515 flatcamTools/ToolCutOut.py:701 msgid "" "Cutout operation cannot be done on a multi-geo Geometry.\n" "Optionally, this Multi-geo Geometry can be converted to Single-geo " @@ -13656,39 +14592,44 @@ msgstr "" "Geometry,\n" "and after that perform Cutout." -#: flatcamTools/ToolCutOut.py:625 flatcamTools/ToolCutOut.py:784 +#: flatcamTools/ToolCutOut.py:650 flatcamTools/ToolCutOut.py:828 msgid "Any form CutOut operation finished." msgstr "Any form CutOut operation finished." -#: flatcamTools/ToolCutOut.py:646 flatcamTools/ToolNonCopperClear.py:1155 -#: flatcamTools/ToolPaint.py:994 flatcamTools/ToolPanelize.py:406 -#: tclCommands/TclCommandBbox.py:70 tclCommands/TclCommandNregions.py:70 +#: flatcamTools/ToolCutOut.py:671 flatcamTools/ToolInvertGerber.py:214 +#: flatcamTools/ToolNCC.py:1607 flatcamTools/ToolPaint.py:1385 +#: flatcamTools/ToolPanelize.py:418 tclCommands/TclCommandBbox.py:72 +#: tclCommands/TclCommandNregions.py:72 msgid "Object not found" msgstr "Object not found" -#: flatcamTools/ToolCutOut.py:789 +#: flatcamTools/ToolCutOut.py:814 +msgid "Rectangular cutout with negative margin is not possible." +msgstr "Rectangular cutout with negative margin is not possible." + +#: flatcamTools/ToolCutOut.py:833 msgid "" "Click on the selected geometry object perimeter to create a bridge gap ..." msgstr "" "Click on the selected geometry object perimeter to create a bridge gap ..." -#: flatcamTools/ToolCutOut.py:806 flatcamTools/ToolCutOut.py:832 +#: flatcamTools/ToolCutOut.py:850 flatcamTools/ToolCutOut.py:876 msgid "Could not retrieve Geometry object" msgstr "Could not retrieve Geometry object" -#: flatcamTools/ToolCutOut.py:837 +#: flatcamTools/ToolCutOut.py:881 msgid "Geometry object for manual cutout not found" msgstr "Geometry object for manual cutout not found" -#: flatcamTools/ToolCutOut.py:847 +#: flatcamTools/ToolCutOut.py:891 msgid "Added manual Bridge Gap." msgstr "Added manual Bridge Gap." -#: flatcamTools/ToolCutOut.py:859 +#: flatcamTools/ToolCutOut.py:903 msgid "Could not retrieve Gerber object" msgstr "Could not retrieve Gerber object" -#: flatcamTools/ToolCutOut.py:864 +#: flatcamTools/ToolCutOut.py:908 msgid "" "There is no Gerber object selected for Cutout.\n" "Select one and try again." @@ -13696,7 +14637,7 @@ msgstr "" "There is no Gerber object selected for Cutout.\n" "Select one and try again." -#: flatcamTools/ToolCutOut.py:870 +#: flatcamTools/ToolCutOut.py:914 msgid "" "The selected object has to be of Gerber type.\n" "Select a Gerber file and try again." @@ -13704,11 +14645,11 @@ msgstr "" "The selected object has to be of Gerber type.\n" "Select a Gerber file and try again." -#: flatcamTools/ToolCutOut.py:905 +#: flatcamTools/ToolCutOut.py:949 msgid "Geometry not supported for cutout" msgstr "Geometry not supported for cutout" -#: flatcamTools/ToolCutOut.py:960 +#: flatcamTools/ToolCutOut.py:1007 msgid "Making manual bridge gap..." msgstr "Making manual bridge gap..." @@ -13716,12 +14657,22 @@ msgstr "Making manual bridge gap..." msgid "2-Sided PCB" msgstr "2-Sided PCB" -#: flatcamTools/ToolDblSided.py:60 +#: flatcamTools/ToolDblSided.py:53 +#| msgid "Operation" +msgid "Mirror Operation" +msgstr "Mirror Operation" + +#: flatcamTools/ToolDblSided.py:54 +#| msgid "Excellon Object to be mirrored." +msgid "Objects to be mirrored" +msgstr "Objects to be mirrored" + +#: flatcamTools/ToolDblSided.py:66 msgid "Gerber to be mirrored" msgstr "Gerber to be mirrored" -#: flatcamTools/ToolDblSided.py:64 flatcamTools/ToolDblSided.py:92 -#: flatcamTools/ToolDblSided.py:122 +#: flatcamTools/ToolDblSided.py:70 flatcamTools/ToolDblSided.py:98 +#: flatcamTools/ToolDblSided.py:128 msgid "" "Mirrors (flips) the specified object around \n" "the specified axis. Does not create a new \n" @@ -13731,139 +14682,129 @@ msgstr "" "the specified axis. Does not create a new \n" "object, but modifies it." -#: flatcamTools/ToolDblSided.py:88 +#: flatcamTools/ToolDblSided.py:94 msgid "Excellon Object to be mirrored." msgstr "Excellon Object to be mirrored." -#: flatcamTools/ToolDblSided.py:117 +#: flatcamTools/ToolDblSided.py:123 msgid "Geometry Obj to be mirrored." msgstr "Geometry Obj to be mirrored." -#: flatcamTools/ToolDblSided.py:179 -msgid "Point/Box Reference" -msgstr "Point/Box Reference" +#: flatcamTools/ToolDblSided.py:159 +#| msgid "Slot Parameters" +msgid "Mirror Parameters" +msgstr "Mirror Parameters" -#: flatcamTools/ToolDblSided.py:181 +#: flatcamTools/ToolDblSided.py:160 +#| msgid "Perform the offset operation." +msgid "Parameters for the mirror operation" +msgstr "Parameters for the mirror operation" + +#: flatcamTools/ToolDblSided.py:165 +#| msgid "Mirror Axis:" +msgid "Mirror Axis" +msgstr "Mirror Axis" + +#: flatcamTools/ToolDblSided.py:176 msgid "" -"If 'Point' is selected above it store the coordinates (x, y) through which\n" -"the mirroring axis passes.\n" -"If 'Box' is selected above, select here a FlatCAM object (Gerber, Exc or " -"Geo).\n" -"Through the center of this object pass the mirroring axis selected above." +"The coordinates used as reference for the mirror operation.\n" +"Can be:\n" +"- Point -> a set of coordinates (x,y) around which the object is mirrored\n" +"- Box -> a set of coordinates (x, y) obtained from the center of the\n" +"bounding box of another object selected below" msgstr "" -"If 'Point' is selected above it store the coordinates (x, y) through which\n" -"the mirroring axis passes.\n" -"If 'Box' is selected above, select here a FlatCAM object (Gerber, Exc or " -"Geo).\n" -"Through the center of this object pass the mirroring axis selected above." +"The coordinates used as reference for the mirror operation.\n" +"Can be:\n" +"- Point -> a set of coordinates (x,y) around which the object is mirrored\n" +"- Box -> a set of coordinates (x, y) obtained from the center of the\n" +"bounding box of another object selected below" -#: flatcamTools/ToolDblSided.py:189 +#: flatcamTools/ToolDblSided.py:190 +#| msgid "Points coordinates" +msgid "Point coordinates" +msgstr "Point coordinates" + +#: flatcamTools/ToolDblSided.py:195 +#| msgid "" +#| "Add the coordinates in format (x, y) through which the mirroring " +#| "axis \n" +#| " selected in 'MIRROR AXIS' pass.\n" +#| "The (x, y) coordinates are captured by pressing SHIFT key\n" +#| "and left mouse button click on canvas or you can enter the coords " +#| "manually." msgid "" "Add the coordinates in format (x, y) through which the mirroring " "axis \n" " selected in 'MIRROR AXIS' pass.\n" "The (x, y) coordinates are captured by pressing SHIFT key\n" -"and left mouse button click on canvas or you can enter the coords manually." +"and left mouse button click on canvas or you can enter the coordinates " +"manually." msgstr "" "Add the coordinates in format (x, y) through which the mirroring " "axis \n" " selected in 'MIRROR AXIS' pass.\n" "The (x, y) coordinates are captured by pressing SHIFT key\n" -"and left mouse button click on canvas or you can enter the coords manually." +"and left mouse button click on canvas or you can enter the coordinates " +"manually." -#: flatcamTools/ToolDblSided.py:230 -msgid "Alignment Drill Coordinates" -msgstr "Alignment Drill Coordinates" - -#: flatcamTools/ToolDblSided.py:232 +#: flatcamTools/ToolDblSided.py:219 msgid "" -"Alignment holes (x1, y1), (x2, y2), ... on one side of the mirror axis. For " -"each set of (x, y) coordinates\n" -"entered here, a pair of drills will be created:\n" -"\n" -"- one drill at the coordinates from the field\n" -"- one drill in mirror position over the axis selected above in the 'Mirror " -"Axis'." +"It can be of type: Gerber or Excellon or Geometry.\n" +"The coordinates of the center of the bounding box are used\n" +"as reference for mirror operation." msgstr "" -"Alignment holes (x1, y1), (x2, y2), ... on one side of the mirror axis. For " -"each set of (x, y) coordinates\n" -"entered here, a pair of drills will be created:\n" -"\n" -"- one drill at the coordinates from the field\n" -"- one drill in mirror position over the axis selected above in the 'Mirror " -"Axis'." +"It can be of type: Gerber or Excellon or Geometry.\n" +"The coordinates of the center of the bounding box are used\n" +"as reference for mirror operation." -#: flatcamTools/ToolDblSided.py:247 +#: flatcamTools/ToolDblSided.py:253 +#| msgid "Calculate Bounds Values" +msgid "Bounds Values" +msgstr "Bounds Values" + +#: flatcamTools/ToolDblSided.py:255 +#| msgid "Excellon objects for which to check rules." msgid "" -"Add alignment drill holes coords in the format: (x1, y1), (x2, y2), ... \n" -"on one side of the mirror axis.\n" -"\n" -"The coordinates set can be obtained:\n" -"- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" -"- press SHIFT key and left mouse clicking on canvas. Then Ctrl+V in the " -"field.\n" -"- press SHIFT key and left mouse clicking on canvas. Then RMB click in the " -"field and click Paste.\n" -"- by entering the coords manually in the format: (x1, y1), (x2, y2), ..." +"Select on canvas the object(s)\n" +"for which to calculate bounds values." msgstr "" -"Add alignment drill holes coords in the format: (x1, y1), (x2, y2), ... \n" -"on one side of the mirror axis.\n" -"\n" -"The coordinates set can be obtained:\n" -"- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" -"- press SHIFT key and left mouse clicking on canvas. Then Ctrl+V in the " -"field.\n" -"- press SHIFT key and left mouse clicking on canvas. Then RMB click in the " -"field and click Paste.\n" -"- by entering the coords manually in the format: (x1, y1), (x2, y2), ..." +"Select on canvas the object(s)\n" +"for which to calculate bounds values." -#: flatcamTools/ToolDblSided.py:272 -msgid "Alignment Drill Diameter" -msgstr "Alignment Drill Diameter" - -#: flatcamTools/ToolDblSided.py:292 -msgid "Create Excellon Object" -msgstr "Create Excellon Object" - -#: flatcamTools/ToolDblSided.py:294 -msgid "" -"Creates an Excellon Object containing the\n" -"specified alignment holes and their mirror\n" -"images." -msgstr "" -"Creates an Excellon Object containing the\n" -"specified alignment holes and their mirror\n" -"images." - -#: flatcamTools/ToolDblSided.py:323 +#: flatcamTools/ToolDblSided.py:265 msgid "X min" msgstr "X min" -#: flatcamTools/ToolDblSided.py:325 flatcamTools/ToolDblSided.py:339 +#: flatcamTools/ToolDblSided.py:267 flatcamTools/ToolDblSided.py:281 msgid "Minimum location." msgstr "Minimum location." -#: flatcamTools/ToolDblSided.py:337 +#: flatcamTools/ToolDblSided.py:279 msgid "Y min" msgstr "Y min" -#: flatcamTools/ToolDblSided.py:351 +#: flatcamTools/ToolDblSided.py:293 msgid "X max" msgstr "X max" -#: flatcamTools/ToolDblSided.py:353 flatcamTools/ToolDblSided.py:367 +#: flatcamTools/ToolDblSided.py:295 flatcamTools/ToolDblSided.py:309 msgid "Maximum location." msgstr "Maximum location." -#: flatcamTools/ToolDblSided.py:365 +#: flatcamTools/ToolDblSided.py:307 msgid "Y max" msgstr "Y max" -#: flatcamTools/ToolDblSided.py:377 +#: flatcamTools/ToolDblSided.py:318 +#| msgid "Points coordinates" +msgid "Center point coordinates" +msgstr "Center point coordinates" + +#: flatcamTools/ToolDblSided.py:320 msgid "Centroid" msgstr "Centroid" -#: flatcamTools/ToolDblSided.py:379 +#: flatcamTools/ToolDblSided.py:322 msgid "" "The center point location for the rectangular\n" "bounding shape. Centroid. Format is (x, y)." @@ -13871,11 +14812,11 @@ msgstr "" "The center point location for the rectangular\n" "bounding shape. Centroid. Format is (x, y)." -#: flatcamTools/ToolDblSided.py:388 +#: flatcamTools/ToolDblSided.py:331 msgid "Calculate Bounds Values" msgstr "Calculate Bounds Values" -#: flatcamTools/ToolDblSided.py:390 +#: flatcamTools/ToolDblSided.py:333 msgid "" "Calculate the enveloping rectangular shape coordinates,\n" "for the selection of objects.\n" @@ -13885,11 +14826,127 @@ msgstr "" "for the selection of objects.\n" "The envelope shape is parallel with the X, Y axis." -#: flatcamTools/ToolDblSided.py:462 +#: flatcamTools/ToolDblSided.py:353 +#| msgid "Alignment" +msgid "PCB Alignment" +msgstr "PCB Alignment" + +#: flatcamTools/ToolDblSided.py:355 flatcamTools/ToolDblSided.py:457 +msgid "" +"Creates an Excellon Object containing the\n" +"specified alignment holes and their mirror\n" +"images." +msgstr "" +"Creates an Excellon Object containing the\n" +"specified alignment holes and their mirror\n" +"images." + +#: flatcamTools/ToolDblSided.py:362 +#| msgid "Tip Diameter" +msgid "Drill Diameter" +msgstr "Drill Diameter" + +#: flatcamTools/ToolDblSided.py:391 flatcamTools/ToolDblSided.py:398 +msgid "" +"The reference point used to create the second alignment drill\n" +"from the first alignment drill, by doing mirror.\n" +"It can be modified in the Mirror Parameters -> Reference section" +msgstr "" +"The reference point used to create the second alignment drill\n" +"from the first alignment drill, by doing mirror.\n" +"It can be modified in the Mirror Parameters -> Reference section" + +#: flatcamTools/ToolDblSided.py:411 +msgid "Alignment Drill Coordinates" +msgstr "Alignment Drill Coordinates" + +#: flatcamTools/ToolDblSided.py:413 +#| msgid "" +#| "Alignment holes (x1, y1), (x2, y2), ... on one side of the mirror axis. " +#| "For each set of (x, y) coordinates\n" +#| "entered here, a pair of drills will be created:\n" +#| "\n" +#| "- one drill at the coordinates from the field\n" +#| "- one drill in mirror position over the axis selected above in the " +#| "'Mirror Axis'." +msgid "" +"Alignment holes (x1, y1), (x2, y2), ... on one side of the mirror axis. For " +"each set of (x, y) coordinates\n" +"entered here, a pair of drills will be created:\n" +"\n" +"- one drill at the coordinates from the field\n" +"- one drill in mirror position over the axis selected above in the 'Align " +"Axis'." +msgstr "" +"Alignment holes (x1, y1), (x2, y2), ... on one side of the mirror axis. For " +"each set of (x, y) coordinates\n" +"entered here, a pair of drills will be created:\n" +"\n" +"- one drill at the coordinates from the field\n" +"- one drill in mirror position over the axis selected above in the 'Align " +"Axis'." + +#: flatcamTools/ToolDblSided.py:421 +#| msgid "Points coordinates" +msgid "Drill coordinates" +msgstr "Drill coordinates" + +#: flatcamTools/ToolDblSided.py:428 +#| msgid "" +#| "Add alignment drill holes coords in the format: (x1, y1), (x2, y2), ... \n" +#| "on one side of the mirror axis.\n" +#| "\n" +#| "The coordinates set can be obtained:\n" +#| "- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" +#| "- press SHIFT key and left mouse clicking on canvas. Then Ctrl+V in the " +#| "field.\n" +#| "- press SHIFT key and left mouse clicking on canvas. Then RMB click in " +#| "the field and click Paste.\n" +#| "- by entering the coords manually in the format: (x1, y1), (x2, y2), ..." +msgid "" +"Add alignment drill holes coordinates in the format: (x1, y1), (x2, " +"y2), ... \n" +"on one side of the alignment axis.\n" +"\n" +"The coordinates set can be obtained:\n" +"- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" +"- press SHIFT key and left mouse clicking on canvas. Then Ctrl+V in the " +"field.\n" +"- press SHIFT key and left mouse clicking on canvas. Then RMB click in the " +"field and click Paste.\n" +"- by entering the coords manually in the format: (x1, y1), (x2, y2), ..." +msgstr "" +"Add alignment drill holes coordinates in the format: (x1, y1), (x2, " +"y2), ... \n" +"on one side of the alignment axis.\n" +"\n" +"The coordinates set can be obtained:\n" +"- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" +"- press SHIFT key and left mouse clicking on canvas. Then Ctrl+V in the " +"field.\n" +"- press SHIFT key and left mouse clicking on canvas. Then RMB click in the " +"field and click Paste.\n" +"- by entering the coords manually in the format: (x1, y1), (x2, y2), ..." + +#: flatcamTools/ToolDblSided.py:443 +#| msgid "Delete" +msgid "Delete Last" +msgstr "Delete Last" + +#: flatcamTools/ToolDblSided.py:445 +#| msgid "Delete a aperture in the aperture list" +msgid "Delete the last coordinates tuple in the list." +msgstr "Delete the last coordinates tuple in the list." + +#: flatcamTools/ToolDblSided.py:455 +msgid "Create Excellon Object" +msgstr "Create Excellon Object" + +#: flatcamTools/ToolDblSided.py:542 msgid "2-Sided Tool" msgstr "2-Sided Tool" -#: flatcamTools/ToolDblSided.py:493 +#: flatcamTools/ToolDblSided.py:582 msgid "" "'Point' reference is selected and 'Point' coordinates are missing. Add them " "and retry." @@ -13897,147 +14954,169 @@ msgstr "" "'Point' reference is selected and 'Point' coordinates are missing. Add them " "and retry." -#: flatcamTools/ToolDblSided.py:512 +#: flatcamTools/ToolDblSided.py:601 msgid "There is no Box reference object loaded. Load one and retry." msgstr "There is no Box reference object loaded. Load one and retry." -#: flatcamTools/ToolDblSided.py:524 +#: flatcamTools/ToolDblSided.py:613 msgid "No value or wrong format in Drill Dia entry. Add it and retry." msgstr "No value or wrong format in Drill Dia entry. Add it and retry." -#: flatcamTools/ToolDblSided.py:532 +#: flatcamTools/ToolDblSided.py:624 msgid "There are no Alignment Drill Coordinates to use. Add them and retry." msgstr "There are no Alignment Drill Coordinates to use. Add them and retry." -#: flatcamTools/ToolDblSided.py:555 +#: flatcamTools/ToolDblSided.py:649 msgid "Excellon object with alignment drills created..." msgstr "Excellon object with alignment drills created..." -#: flatcamTools/ToolDblSided.py:568 flatcamTools/ToolDblSided.py:611 -#: flatcamTools/ToolDblSided.py:655 +#: flatcamTools/ToolDblSided.py:662 flatcamTools/ToolDblSided.py:705 +#: flatcamTools/ToolDblSided.py:749 msgid "Only Gerber, Excellon and Geometry objects can be mirrored." msgstr "Only Gerber, Excellon and Geometry objects can be mirrored." -#: flatcamTools/ToolDblSided.py:578 +#: flatcamTools/ToolDblSided.py:672 flatcamTools/ToolDblSided.py:716 msgid "" -"'Point' coordinates missing. Using Origin (0, 0) as mirroring reference." +"There are no Point coordinates in the Point field. Add coords and try " +"again ..." msgstr "" -"'Point' coordinates missing. Using Origin (0, 0) as mirroring reference." +"There are no Point coordinates in the Point field. Add coords and try " +"again ..." -#: flatcamTools/ToolDblSided.py:588 flatcamTools/ToolDblSided.py:632 -#: flatcamTools/ToolDblSided.py:669 +#: flatcamTools/ToolDblSided.py:682 flatcamTools/ToolDblSided.py:726 +#: flatcamTools/ToolDblSided.py:763 msgid "There is no Box object loaded ..." msgstr "There is no Box object loaded ..." -#: flatcamTools/ToolDblSided.py:598 flatcamTools/ToolDblSided.py:642 -#: flatcamTools/ToolDblSided.py:679 +#: flatcamTools/ToolDblSided.py:692 flatcamTools/ToolDblSided.py:736 +#: flatcamTools/ToolDblSided.py:773 msgid "was mirrored" msgstr "was mirrored" -#: flatcamTools/ToolDblSided.py:607 +#: flatcamTools/ToolDblSided.py:701 flatcamTools/ToolPunchGerber.py:533 msgid "There is no Excellon object loaded ..." msgstr "There is no Excellon object loaded ..." -#: flatcamTools/ToolDblSided.py:622 -msgid "" -"There are no Point coordinates in the Point field. Add coords and try " -"again ..." -msgstr "" -"There are no Point coordinates in the Point field. Add coords and try " -"again ..." - -#: flatcamTools/ToolDblSided.py:651 +#: flatcamTools/ToolDblSided.py:745 msgid "There is no Geometry object loaded ..." msgstr "There is no Geometry object loaded ..." -#: flatcamTools/ToolDistance.py:50 flatcamTools/ToolDistanceMin.py:50 +#: flatcamTools/ToolDistance.py:57 flatcamTools/ToolDistanceMin.py:51 msgid "Those are the units in which the distance is measured." msgstr "Those are the units in which the distance is measured." -#: flatcamTools/ToolDistance.py:51 flatcamTools/ToolDistanceMin.py:51 +#: flatcamTools/ToolDistance.py:58 flatcamTools/ToolDistanceMin.py:52 msgid "METRIC (mm)" msgstr "METRIC (mm)" -#: flatcamTools/ToolDistance.py:51 flatcamTools/ToolDistanceMin.py:51 +#: flatcamTools/ToolDistance.py:58 flatcamTools/ToolDistanceMin.py:52 msgid "INCH (in)" msgstr "INCH (in)" -#: flatcamTools/ToolDistance.py:54 +#: flatcamTools/ToolDistance.py:64 +#| msgid "Snap to corner" +msgid "Snap to center" +msgstr "Snap to center" + +#: flatcamTools/ToolDistance.py:66 +msgid "" +"Mouse cursor will snap to the center of the pad/drill\n" +"when it is hovering over the geometry of the pad/drill." +msgstr "" +"Mouse cursor will snap to the center of the pad/drill\n" +"when it is hovering over the geometry of the pad/drill." + +#: flatcamTools/ToolDistance.py:76 msgid "Start Coords" msgstr "Start Coords" -#: flatcamTools/ToolDistance.py:55 flatcamTools/ToolDistance.py:75 +#: flatcamTools/ToolDistance.py:77 flatcamTools/ToolDistance.py:82 msgid "This is measuring Start point coordinates." msgstr "This is measuring Start point coordinates." -#: flatcamTools/ToolDistance.py:57 +#: flatcamTools/ToolDistance.py:87 msgid "Stop Coords" msgstr "Stop Coords" -#: flatcamTools/ToolDistance.py:58 flatcamTools/ToolDistance.py:80 +#: flatcamTools/ToolDistance.py:88 flatcamTools/ToolDistance.py:93 msgid "This is the measuring Stop point coordinates." msgstr "This is the measuring Stop point coordinates." -#: flatcamTools/ToolDistance.py:60 flatcamTools/ToolDistanceMin.py:62 +#: flatcamTools/ToolDistance.py:98 flatcamTools/ToolDistanceMin.py:63 msgid "Dx" msgstr "Dx" -#: flatcamTools/ToolDistance.py:61 flatcamTools/ToolDistance.py:85 -#: flatcamTools/ToolDistanceMin.py:63 flatcamTools/ToolDistanceMin.py:92 +#: flatcamTools/ToolDistance.py:99 flatcamTools/ToolDistance.py:104 +#: flatcamTools/ToolDistanceMin.py:64 flatcamTools/ToolDistanceMin.py:93 msgid "This is the distance measured over the X axis." msgstr "This is the distance measured over the X axis." -#: flatcamTools/ToolDistance.py:63 flatcamTools/ToolDistanceMin.py:65 +#: flatcamTools/ToolDistance.py:109 flatcamTools/ToolDistanceMin.py:66 msgid "Dy" msgstr "Dy" -#: flatcamTools/ToolDistance.py:64 flatcamTools/ToolDistance.py:90 -#: flatcamTools/ToolDistanceMin.py:66 flatcamTools/ToolDistanceMin.py:97 +#: flatcamTools/ToolDistance.py:110 flatcamTools/ToolDistance.py:115 +#: flatcamTools/ToolDistanceMin.py:67 flatcamTools/ToolDistanceMin.py:98 msgid "This is the distance measured over the Y axis." msgstr "This is the distance measured over the Y axis." -#: flatcamTools/ToolDistance.py:67 flatcamTools/ToolDistance.py:95 -#: flatcamTools/ToolDistanceMin.py:69 flatcamTools/ToolDistanceMin.py:102 +#: flatcamTools/ToolDistance.py:121 flatcamTools/ToolDistance.py:126 +#: flatcamTools/ToolDistanceMin.py:70 flatcamTools/ToolDistanceMin.py:103 msgid "This is orientation angle of the measuring line." msgstr "This is orientation angle of the measuring line." -#: flatcamTools/ToolDistance.py:69 flatcamTools/ToolDistanceMin.py:71 +#: flatcamTools/ToolDistance.py:131 flatcamTools/ToolDistanceMin.py:72 msgid "DISTANCE" msgstr "DISTANCE" -#: flatcamTools/ToolDistance.py:70 flatcamTools/ToolDistance.py:100 +#: flatcamTools/ToolDistance.py:132 flatcamTools/ToolDistance.py:137 msgid "This is the point to point Euclidian distance." msgstr "This is the point to point Euclidian distance." -#: flatcamTools/ToolDistance.py:102 flatcamTools/ToolDistanceMin.py:114 +#: flatcamTools/ToolDistance.py:142 flatcamTools/ToolDistance.py:337 +#: flatcamTools/ToolDistanceMin.py:115 msgid "Measure" msgstr "Measure" -#: flatcamTools/ToolDistance.py:212 +#: flatcamTools/ToolDistance.py:272 +#| msgid "Working..." +msgid "Working" +msgstr "Working" + +#: flatcamTools/ToolDistance.py:277 msgid "MEASURING: Click on the Start point ..." msgstr "MEASURING: Click on the Start point ..." -#: flatcamTools/ToolDistance.py:345 +#: flatcamTools/ToolDistance.py:387 +#| msgid "Distance Tool exit..." +msgid "Distance Tool finished." +msgstr "Distance Tool finished." + +#: flatcamTools/ToolDistance.py:455 +msgid "Pads overlapped. Aborting." +msgstr "Pads overlapped. Aborting." + +#: flatcamTools/ToolDistance.py:485 msgid "MEASURING: Click on the Destination point ..." msgstr "MEASURING: Click on the Destination point ..." -#: flatcamTools/ToolDistance.py:353 flatcamTools/ToolDistanceMin.py:282 +#: flatcamTools/ToolDistance.py:494 flatcamTools/ToolDistanceMin.py:285 msgid "MEASURING" msgstr "MEASURING" -#: flatcamTools/ToolDistance.py:354 flatcamTools/ToolDistanceMin.py:283 +#: flatcamTools/ToolDistance.py:495 flatcamTools/ToolDistanceMin.py:286 msgid "Result" msgstr "Result" -#: flatcamTools/ToolDistanceMin.py:31 flatcamTools/ToolDistanceMin.py:152 +#: flatcamTools/ToolDistanceMin.py:32 flatcamTools/ToolDistanceMin.py:144 msgid "Minimum Distance Tool" msgstr "Minimum Distance Tool" -#: flatcamTools/ToolDistanceMin.py:54 +#: flatcamTools/ToolDistanceMin.py:55 msgid "First object point" msgstr "First object point" -#: flatcamTools/ToolDistanceMin.py:55 flatcamTools/ToolDistanceMin.py:80 +#: flatcamTools/ToolDistanceMin.py:56 flatcamTools/ToolDistanceMin.py:81 msgid "" "This is first object point coordinates.\n" "This is the start point for measuring distance." @@ -14045,11 +15124,11 @@ msgstr "" "This is first object point coordinates.\n" "This is the start point for measuring distance." -#: flatcamTools/ToolDistanceMin.py:58 +#: flatcamTools/ToolDistanceMin.py:59 msgid "Second object point" msgstr "Second object point" -#: flatcamTools/ToolDistanceMin.py:59 flatcamTools/ToolDistanceMin.py:86 +#: flatcamTools/ToolDistanceMin.py:60 flatcamTools/ToolDistanceMin.py:87 msgid "" "This is second object point coordinates.\n" "This is the end point for measuring distance." @@ -14057,41 +15136,61 @@ msgstr "" "This is second object point coordinates.\n" "This is the end point for measuring distance." -#: flatcamTools/ToolDistanceMin.py:72 flatcamTools/ToolDistanceMin.py:107 +#: flatcamTools/ToolDistanceMin.py:73 flatcamTools/ToolDistanceMin.py:108 msgid "This is the point to point Euclidean distance." msgstr "This is the point to point Euclidean distance." -#: flatcamTools/ToolDistanceMin.py:74 +#: flatcamTools/ToolDistanceMin.py:75 msgid "Half Point" msgstr "Half Point" -#: flatcamTools/ToolDistanceMin.py:75 flatcamTools/ToolDistanceMin.py:112 +#: flatcamTools/ToolDistanceMin.py:76 flatcamTools/ToolDistanceMin.py:113 msgid "This is the middle point of the point to point Euclidean distance." msgstr "This is the middle point of the point to point Euclidean distance." -#: flatcamTools/ToolDistanceMin.py:117 +#: flatcamTools/ToolDistanceMin.py:118 msgid "Jump to Half Point" msgstr "Jump to Half Point" -#: flatcamTools/ToolDistanceMin.py:163 +#: flatcamTools/ToolDistanceMin.py:155 msgid "" "Select two objects and no more, to measure the distance between them ..." msgstr "" "Select two objects and no more, to measure the distance between them ..." -#: flatcamTools/ToolDistanceMin.py:204 flatcamTools/ToolDistanceMin.py:214 -#: flatcamTools/ToolDistanceMin.py:223 flatcamTools/ToolDistanceMin.py:244 +#: flatcamTools/ToolDistanceMin.py:196 flatcamTools/ToolDistanceMin.py:217 +#: flatcamTools/ToolDistanceMin.py:226 flatcamTools/ToolDistanceMin.py:247 msgid "Select two objects and no more. Currently the selection has objects: " msgstr "Select two objects and no more. Currently the selection has objects: " -#: flatcamTools/ToolDistanceMin.py:291 +#: flatcamTools/ToolDistanceMin.py:294 msgid "Objects intersects or touch at" msgstr "Objects intersects or touch at" -#: flatcamTools/ToolDistanceMin.py:297 +#: flatcamTools/ToolDistanceMin.py:300 msgid "Jumped to the half point between the two selected objects" msgstr "Jumped to the half point between the two selected objects" +#: flatcamTools/ToolExtractDrills.py:29 flatcamTools/ToolExtractDrills.py:295 +#| msgid "Total Drills" +msgid "Extract Drills" +msgstr "Extract Drills" + +#: flatcamTools/ToolExtractDrills.py:62 +#| msgid "Gerber objects for which to check rules." +msgid "Gerber from which to extract drill holes" +msgstr "Gerber from which to extract drill holes" + +#: flatcamTools/ToolExtractDrills.py:297 +msgid "Extract drills from a given Gerber file." +msgstr "Extract drills from a given Gerber file." + +#: flatcamTools/ToolExtractDrills.py:478 flatcamTools/ToolExtractDrills.py:563 +#: flatcamTools/ToolExtractDrills.py:648 +#| msgid "NCC Tool started. Reading parameters." +msgid "No drills extracted. Try different parameters." +msgstr "No drills extracted. Try different parameters." + #: flatcamTools/ToolFiducials.py:56 msgid "Fiducials Coordinates" msgstr "Fiducials Coordinates" @@ -14108,10 +15207,6 @@ msgstr "" msgid "Top Right" msgstr "Top Right" -#: flatcamTools/ToolFiducials.py:111 -msgid "Second Point" -msgstr "Second Point" - #: flatcamTools/ToolFiducials.py:191 msgid "" "- 'Auto' - automatic placement of fiducials in the corners of the bounding " @@ -14122,31 +15217,31 @@ msgstr "" "box.\n" " - 'Manual' - manual placement of fiducials." -#: flatcamTools/ToolFiducials.py:258 +#: flatcamTools/ToolFiducials.py:259 msgid "Copper Gerber" msgstr "Copper Gerber" -#: flatcamTools/ToolFiducials.py:267 +#: flatcamTools/ToolFiducials.py:268 msgid "Add Fiducial" msgstr "Add Fiducial" -#: flatcamTools/ToolFiducials.py:269 +#: flatcamTools/ToolFiducials.py:270 msgid "Will add a polygon on the copper layer to serve as fiducial." msgstr "Will add a polygon on the copper layer to serve as fiducial." -#: flatcamTools/ToolFiducials.py:285 +#: flatcamTools/ToolFiducials.py:286 msgid "Soldermask Gerber" msgstr "Soldermask Gerber" -#: flatcamTools/ToolFiducials.py:287 +#: flatcamTools/ToolFiducials.py:288 msgid "The Soldermask Gerber object." msgstr "The Soldermask Gerber object." -#: flatcamTools/ToolFiducials.py:298 +#: flatcamTools/ToolFiducials.py:300 msgid "Add Soldermask Opening" msgstr "Add Soldermask Opening" -#: flatcamTools/ToolFiducials.py:300 +#: flatcamTools/ToolFiducials.py:302 msgid "" "Will add a polygon on the soldermask layer\n" "to serve as fiducial opening.\n" @@ -14158,23 +15253,23 @@ msgstr "" "The diameter is always double of the diameter\n" "for the copper fiducial." -#: flatcamTools/ToolFiducials.py:514 +#: flatcamTools/ToolFiducials.py:516 msgid "Click to add first Fiducial. Bottom Left..." msgstr "Click to add first Fiducial. Bottom Left..." -#: flatcamTools/ToolFiducials.py:778 +#: flatcamTools/ToolFiducials.py:780 msgid "Click to add the last fiducial. Top Right..." msgstr "Click to add the last fiducial. Top Right..." -#: flatcamTools/ToolFiducials.py:783 +#: flatcamTools/ToolFiducials.py:785 msgid "Click to add the second fiducial. Top Left or Bottom Right..." msgstr "Click to add the second fiducial. Top Left or Bottom Right..." -#: flatcamTools/ToolFiducials.py:786 flatcamTools/ToolFiducials.py:795 +#: flatcamTools/ToolFiducials.py:788 flatcamTools/ToolFiducials.py:797 msgid "Done. All fiducials have been added." msgstr "Done. All fiducials have been added." -#: flatcamTools/ToolFiducials.py:872 +#: flatcamTools/ToolFiducials.py:874 msgid "Fiducials Tool exit." msgstr "Fiducials Tool exit." @@ -14182,7 +15277,7 @@ msgstr "Fiducials Tool exit." msgid "Film PCB" msgstr "Film PCB" -#: flatcamTools/ToolFilm.py:80 +#: flatcamTools/ToolFilm.py:78 msgid "" "Specify the type of object for which to create the film.\n" "The object can be of type: Gerber or Geometry.\n" @@ -14194,11 +15289,11 @@ msgstr "" "The selection here decide the type of objects that will be\n" "in the Film Object combobox." -#: flatcamTools/ToolFilm.py:94 +#: flatcamTools/ToolFilm.py:92 msgid "Film Object" msgstr "Film Object" -#: flatcamTools/ToolFilm.py:96 +#: flatcamTools/ToolFilm.py:94 msgid "Object for which to create the film." msgstr "Object for which to create the film." @@ -14214,7 +15309,7 @@ msgstr "" "the type of objects that will be\n" "in the Box Object combobox." -#: flatcamTools/ToolFilm.py:129 flatcamTools/ToolPanelize.py:136 +#: flatcamTools/ToolFilm.py:129 msgid "Box Object" msgstr "Box Object" @@ -14276,19 +15371,19 @@ msgid "" msgstr "" "Remove the geometry of Excellon from the Film to create the holes in pads." -#: flatcamTools/ToolFilm.py:379 +#: flatcamTools/ToolFilm.py:381 msgid "Punch Size" msgstr "Punch Size" -#: flatcamTools/ToolFilm.py:380 +#: flatcamTools/ToolFilm.py:382 msgid "The value here will control how big is the punch hole in the pads." msgstr "The value here will control how big is the punch hole in the pads." -#: flatcamTools/ToolFilm.py:500 +#: flatcamTools/ToolFilm.py:502 msgid "Save Film" msgstr "Save Film" -#: flatcamTools/ToolFilm.py:502 +#: flatcamTools/ToolFilm.py:504 msgid "" "Create a Film for the selected object, within\n" "the specified box. Does not create a new \n" @@ -14300,7 +15395,7 @@ msgstr "" " FlatCAM object, but directly save it in the\n" "selected format." -#: flatcamTools/ToolFilm.py:652 +#: flatcamTools/ToolFilm.py:664 msgid "" "Using the Pad center does not work on Geometry objects. Only a Gerber object " "has pads." @@ -14308,53 +15403,49 @@ msgstr "" "Using the Pad center does not work on Geometry objects. Only a Gerber object " "has pads." -#: flatcamTools/ToolFilm.py:662 +#: flatcamTools/ToolFilm.py:674 msgid "No FlatCAM object selected. Load an object for Film and retry." msgstr "No FlatCAM object selected. Load an object for Film and retry." -#: flatcamTools/ToolFilm.py:669 +#: flatcamTools/ToolFilm.py:681 msgid "No FlatCAM object selected. Load an object for Box and retry." msgstr "No FlatCAM object selected. Load an object for Box and retry." -#: flatcamTools/ToolFilm.py:673 +#: flatcamTools/ToolFilm.py:685 msgid "No FlatCAM object selected." msgstr "No FlatCAM object selected." -#: flatcamTools/ToolFilm.py:684 +#: flatcamTools/ToolFilm.py:696 msgid "Generating Film ..." msgstr "Generating Film ..." -#: flatcamTools/ToolFilm.py:733 flatcamTools/ToolFilm.py:737 +#: flatcamTools/ToolFilm.py:745 flatcamTools/ToolFilm.py:749 msgid "Export positive film" msgstr "Export positive film" -#: flatcamTools/ToolFilm.py:742 -msgid "Export positive film cancelled." -msgstr "Export positive film cancelled." - -#: flatcamTools/ToolFilm.py:770 +#: flatcamTools/ToolFilm.py:782 msgid "" "No Excellon object selected. Load an object for punching reference and retry." msgstr "" "No Excellon object selected. Load an object for punching reference and retry." -#: flatcamTools/ToolFilm.py:794 -msgid "" -" Could not generate punched hole film because the punch hole sizeis bigger " -"than some of the apertures in the Gerber object." -msgstr "" -" Could not generate punched hole film because the punch hole sizeis bigger " -"than some of the apertures in the Gerber object." - #: flatcamTools/ToolFilm.py:806 msgid "" +" Could not generate punched hole film because the punch hole sizeis bigger " +"than some of the apertures in the Gerber object." +msgstr "" +" Could not generate punched hole film because the punch hole sizeis bigger " +"than some of the apertures in the Gerber object." + +#: flatcamTools/ToolFilm.py:818 +msgid "" "Could not generate punched hole film because the punch hole sizeis bigger " "than some of the apertures in the Gerber object." msgstr "" "Could not generate punched hole film because the punch hole sizeis bigger " "than some of the apertures in the Gerber object." -#: flatcamTools/ToolFilm.py:824 +#: flatcamTools/ToolFilm.py:836 msgid "" "Could not generate punched hole film because the newly created object " "geometry is the same as the one in the source object geometry..." @@ -14362,24 +15453,20 @@ msgstr "" "Could not generate punched hole film because the newly created object " "geometry is the same as the one in the source object geometry..." -#: flatcamTools/ToolFilm.py:879 flatcamTools/ToolFilm.py:883 +#: flatcamTools/ToolFilm.py:891 flatcamTools/ToolFilm.py:895 msgid "Export negative film" msgstr "Export negative film" -#: flatcamTools/ToolFilm.py:888 -msgid "Export negative film cancelled." -msgstr "Export negative film cancelled." - -#: flatcamTools/ToolFilm.py:944 flatcamTools/ToolFilm.py:1122 -#: flatcamTools/ToolPanelize.py:421 +#: flatcamTools/ToolFilm.py:956 flatcamTools/ToolFilm.py:1139 +#: flatcamTools/ToolPanelize.py:433 msgid "No object Box. Using instead" msgstr "No object Box. Using instead" -#: flatcamTools/ToolFilm.py:1060 flatcamTools/ToolFilm.py:1235 +#: flatcamTools/ToolFilm.py:1072 flatcamTools/ToolFilm.py:1252 msgid "Film file exported to" msgstr "Film file exported to" -#: flatcamTools/ToolFilm.py:1063 flatcamTools/ToolFilm.py:1238 +#: flatcamTools/ToolFilm.py:1075 flatcamTools/ToolFilm.py:1255 msgid "Generating Film ... Please wait." msgstr "Generating Film ... Please wait." @@ -14391,7 +15478,7 @@ msgstr "Image as Object" msgid "Image to PCB" msgstr "Image to PCB" -#: flatcamTools/ToolImage.py:57 +#: flatcamTools/ToolImage.py:56 msgid "" "Specify the type of object to create from the image.\n" "It can be of type: Gerber or Geometry." @@ -14399,23 +15486,23 @@ msgstr "" "Specify the type of object to create from the image.\n" "It can be of type: Gerber or Geometry." -#: flatcamTools/ToolImage.py:66 +#: flatcamTools/ToolImage.py:65 msgid "DPI value" msgstr "DPI value" -#: flatcamTools/ToolImage.py:67 +#: flatcamTools/ToolImage.py:66 msgid "Specify a DPI value for the image." msgstr "Specify a DPI value for the image." -#: flatcamTools/ToolImage.py:73 +#: flatcamTools/ToolImage.py:72 msgid "Level of detail" msgstr "Level of detail" -#: flatcamTools/ToolImage.py:82 +#: flatcamTools/ToolImage.py:81 msgid "Image type" msgstr "Image type" -#: flatcamTools/ToolImage.py:84 +#: flatcamTools/ToolImage.py:83 msgid "" "Choose a method for the image interpretation.\n" "B/W means a black & white image. Color means a colored image." @@ -14423,12 +15510,12 @@ msgstr "" "Choose a method for the image interpretation.\n" "B/W means a black & white image. Color means a colored image." -#: flatcamTools/ToolImage.py:93 flatcamTools/ToolImage.py:108 -#: flatcamTools/ToolImage.py:121 flatcamTools/ToolImage.py:134 +#: flatcamTools/ToolImage.py:92 flatcamTools/ToolImage.py:107 +#: flatcamTools/ToolImage.py:120 flatcamTools/ToolImage.py:133 msgid "Mask value" msgstr "Mask value" -#: flatcamTools/ToolImage.py:95 +#: flatcamTools/ToolImage.py:94 msgid "" "Mask for monochrome image.\n" "Takes values between [0 ... 255].\n" @@ -14444,7 +15531,7 @@ msgstr "" "0 means no detail and 255 means everything \n" "(which is totally black)." -#: flatcamTools/ToolImage.py:110 +#: flatcamTools/ToolImage.py:109 msgid "" "Mask for RED color.\n" "Takes values between [0 ... 255].\n" @@ -14456,7 +15543,7 @@ msgstr "" "Decides the level of details to include\n" "in the resulting geometry." -#: flatcamTools/ToolImage.py:123 +#: flatcamTools/ToolImage.py:122 msgid "" "Mask for GREEN color.\n" "Takes values between [0 ... 255].\n" @@ -14468,7 +15555,7 @@ msgstr "" "Decides the level of details to include\n" "in the resulting geometry." -#: flatcamTools/ToolImage.py:136 +#: flatcamTools/ToolImage.py:135 msgid "" "Mask for BLUE color.\n" "Takes values between [0 ... 255].\n" @@ -14480,33 +15567,64 @@ msgstr "" "Decides the level of details to include\n" "in the resulting geometry." -#: flatcamTools/ToolImage.py:144 +#: flatcamTools/ToolImage.py:143 msgid "Import image" msgstr "Import image" -#: flatcamTools/ToolImage.py:146 +#: flatcamTools/ToolImage.py:145 msgid "Open a image of raster type and then import it in FlatCAM." msgstr "Open a image of raster type and then import it in FlatCAM." -#: flatcamTools/ToolImage.py:183 +#: flatcamTools/ToolImage.py:182 msgid "Image Tool" msgstr "Image Tool" -#: flatcamTools/ToolImage.py:235 flatcamTools/ToolImage.py:238 +#: flatcamTools/ToolImage.py:234 flatcamTools/ToolImage.py:237 msgid "Import IMAGE" msgstr "Import IMAGE" -#: flatcamTools/ToolImage.py:286 +#: flatcamTools/ToolImage.py:285 msgid "Importing Image" msgstr "Importing Image" +#: flatcamTools/ToolInvertGerber.py:74 +#| msgid "Gerber Object to which the QRCode will be added." +msgid "Gerber object that will be inverted." +msgstr "Gerber object that will be inverted." + +#: flatcamTools/ToolInvertGerber.py:83 +#| msgid "Parameters used for this tool." +msgid "Parameters for this tool" +msgstr "Parameters for this tool" + +#: flatcamTools/ToolInvertGerber.py:123 +#| msgid "Convert Any to Gerber" +msgid "Invert Gerber" +msgstr "Invert Gerber" + +#: flatcamTools/ToolInvertGerber.py:125 +msgid "" +"Will invert the Gerber object: areas that have copper\n" +"will be empty of copper and previous empty area will be\n" +"filled with copper." +msgstr "" +"Will invert the Gerber object: areas that have copper\n" +"will be empty of copper and previous empty area will be\n" +"filled with copper." + +#: flatcamTools/ToolInvertGerber.py:184 +#| msgid "Text Tool" +msgid "Invert Tool" +msgstr "Invert Tool" + #: flatcamTools/ToolMove.py:103 msgid "MOVE: Click on the Start point ..." msgstr "MOVE: Click on the Start point ..." #: flatcamTools/ToolMove.py:114 -msgid "MOVE action cancelled. No object(s) to move." -msgstr "MOVE action cancelled. No object(s) to move." +#| msgid "MOVE action cancelled. No object(s) to move." +msgid "Cancelled. No object(s) to move." +msgstr "Cancelled. No object(s) to move." #: flatcamTools/ToolMove.py:141 msgid "MOVE: Click on the Destination point ..." @@ -14520,19 +15638,15 @@ msgstr "Moving..." msgid "No object(s) selected." msgstr "No object(s) selected." -#: flatcamTools/ToolMove.py:212 +#: flatcamTools/ToolMove.py:222 msgid "Error when mouse left click." msgstr "Error when mouse left click." -#: flatcamTools/ToolMove.py:260 -msgid "Move action cancelled." -msgstr "Move action cancelled." - -#: flatcamTools/ToolNonCopperClear.py:38 +#: flatcamTools/ToolNCC.py:42 msgid "Non-Copper Clearing" msgstr "Non-Copper Clearing" -#: flatcamTools/ToolNonCopperClear.py:84 +#: flatcamTools/ToolNCC.py:88 msgid "" "Specify the type of object to be cleared of excess copper.\n" "It can be of type: Gerber or Geometry.\n" @@ -14544,11 +15658,11 @@ msgstr "" "What is selected here will dictate the kind\n" "of objects that will populate the 'Object' combobox." -#: flatcamTools/ToolNonCopperClear.py:101 +#: flatcamTools/ToolNCC.py:110 msgid "Object to be cleared of excess copper." msgstr "Object to be cleared of excess copper." -#: flatcamTools/ToolNonCopperClear.py:111 +#: flatcamTools/ToolNCC.py:122 msgid "" "Tools pool from which the algorithm\n" "will pick the ones used for copper clearing." @@ -14556,11 +15670,7 @@ msgstr "" "Tools pool from which the algorithm\n" "will pick the ones used for copper clearing." -#: flatcamTools/ToolNonCopperClear.py:120 -msgid "Operation" -msgstr "Operation" - -#: flatcamTools/ToolNonCopperClear.py:126 +#: flatcamTools/ToolNCC.py:138 msgid "" "This is the Tool Number.\n" "Non copper clearing will start with the tool with the biggest \n" @@ -14576,7 +15686,7 @@ msgstr "" "in the resulting geometry. This is because with some tools\n" "this function will not be able to create painting geometry." -#: flatcamTools/ToolNonCopperClear.py:134 +#: flatcamTools/ToolNCC.py:146 msgid "" "Tool Diameter. It's value (in current FlatCAM units)\n" "is the cut width into the material." @@ -14584,7 +15694,7 @@ msgstr "" "Tool Diameter. It's value (in current FlatCAM units)\n" "is the cut width into the material." -#: flatcamTools/ToolNonCopperClear.py:138 +#: flatcamTools/ToolNCC.py:150 msgid "" "The Tool Type (TT) can be:\n" "- Circular with 1 ... 4 teeth -> it is informative only. Being circular,\n" @@ -14620,33 +15730,7 @@ msgstr "" "Type\n" "in the resulting geometry as Isolation." -#: flatcamTools/ToolNonCopperClear.py:151 -msgid "" -"The 'Operation' can be:\n" -"- Isolation -> will ensure that the non-copper clearing is always complete.\n" -"If it's not successful then the non-copper clearing will fail, too.\n" -"- Clear -> the regular non-copper clearing." -msgstr "" -"The 'Operation' can be:\n" -"- Isolation -> will ensure that the non-copper clearing is always complete.\n" -"If it's not successful then the non-copper clearing will fail, too.\n" -"- Clear -> the regular non-copper clearing." - -#: flatcamTools/ToolNonCopperClear.py:209 -msgid "Tool Selection" -msgstr "Tool Selection" - -#: flatcamTools/ToolNonCopperClear.py:273 -msgid "" -"Diameter for the new tool to add in the Tool Table.\n" -"If the tool is V-shape type then this value is automatically\n" -"calculated from the other parameters." -msgstr "" -"Diameter for the new tool to add in the Tool Table.\n" -"If the tool is V-shape type then this value is automatically\n" -"calculated from the other parameters." - -#: flatcamTools/ToolNonCopperClear.py:288 flatcamTools/ToolPaint.py:190 +#: flatcamTools/ToolNCC.py:296 flatcamTools/ToolPaint.py:279 msgid "" "Add a new tool to the Tool Table\n" "with the diameter specified above." @@ -14654,8 +15738,8 @@ msgstr "" "Add a new tool to the Tool Table\n" "with the diameter specified above." -#: flatcamTools/ToolNonCopperClear.py:300 flatcamTools/ToolPaint.py:202 -#: flatcamTools/ToolSolderPaste.py:129 +#: flatcamTools/ToolNCC.py:318 flatcamTools/ToolPaint.py:301 +#: flatcamTools/ToolSolderPaste.py:131 msgid "" "Delete a selection of tools in the Tool Table\n" "by first selecting a row(s) in the Tool Table." @@ -14663,23 +15747,7 @@ msgstr "" "Delete a selection of tools in the Tool Table\n" "by first selecting a row(s) in the Tool Table." -#: flatcamTools/ToolNonCopperClear.py:435 -msgid "" -"- 'Itself' - the non copper clearing extent is based on the object that is " -"copper cleared.\n" -" - 'Area Selection' - left mouse click to start selection of the area to be " -"painted.\n" -"- 'Reference Object' - will do non copper clearing within the area specified " -"by another object." -msgstr "" -"- 'Itself' - the non copper clearing extent is based on the object that is " -"copper cleared.\n" -" - 'Area Selection' - left mouse click to start selection of the area to be " -"painted.\n" -"- 'Reference Object' - will do non copper clearing within the area specified " -"by another object." - -#: flatcamTools/ToolNonCopperClear.py:447 +#: flatcamTools/ToolNCC.py:554 msgid "" "The type of FlatCAM object to be used as non copper clearing reference.\n" "It can be Gerber, Excellon or Geometry." @@ -14687,114 +15755,123 @@ msgstr "" "The type of FlatCAM object to be used as non copper clearing reference.\n" "It can be Gerber, Excellon or Geometry." -#: flatcamTools/ToolNonCopperClear.py:471 +#: flatcamTools/ToolNCC.py:597 flatcamTools/ToolPaint.py:537 msgid "Generate Geometry" msgstr "Generate Geometry" -#: flatcamTools/ToolNonCopperClear.py:582 flatcamTools/ToolPaint.py:493 -#: flatcamTools/ToolSolderPaste.py:553 -msgid "New Tool" -msgstr "New Tool" - -#: flatcamTools/ToolNonCopperClear.py:981 flatcamTools/ToolPaint.py:766 -#: flatcamTools/ToolSolderPaste.py:887 +#: flatcamTools/ToolNCC.py:1429 flatcamTools/ToolPaint.py:1172 +#: flatcamTools/ToolSolderPaste.py:888 msgid "Please enter a tool diameter to add, in Float format." msgstr "Please enter a tool diameter to add, in Float format." -#: flatcamTools/ToolNonCopperClear.py:1012 flatcamTools/ToolPaint.py:791 -msgid "Adding tool cancelled. Tool already in Tool Table." -msgstr "Adding tool cancelled. Tool already in Tool Table." +#: flatcamTools/ToolNCC.py:1460 flatcamTools/ToolNCC.py:4013 +#: flatcamTools/ToolPaint.py:1196 flatcamTools/ToolPaint.py:4077 +#: flatcamTools/ToolSolderPaste.py:917 +#| msgid "Adding tool cancelled. Tool already in Tool Table." +msgid "Cancelled. Tool already in Tool Table." +msgstr "Cancelled. Tool already in Tool Table." -#: flatcamTools/ToolNonCopperClear.py:1017 flatcamTools/ToolPaint.py:797 +#: flatcamTools/ToolNCC.py:1467 flatcamTools/ToolNCC.py:4030 +#: flatcamTools/ToolPaint.py:1201 flatcamTools/ToolPaint.py:4094 msgid "New tool added to Tool Table." msgstr "New tool added to Tool Table." -#: flatcamTools/ToolNonCopperClear.py:1061 flatcamTools/ToolPaint.py:843 +#: flatcamTools/ToolNCC.py:1511 flatcamTools/ToolPaint.py:1245 msgid "Tool from Tool Table was edited." msgstr "Tool from Tool Table was edited." -#: flatcamTools/ToolNonCopperClear.py:1072 flatcamTools/ToolPaint.py:855 -#: flatcamTools/ToolSolderPaste.py:978 -msgid "Edit cancelled. New diameter value is already in the Tool Table." -msgstr "Edit cancelled. New diameter value is already in the Tool Table." +#: flatcamTools/ToolNCC.py:1523 flatcamTools/ToolPaint.py:1257 +#: flatcamTools/ToolSolderPaste.py:977 +#| msgid "Edit cancelled. New diameter value is already in the Tool Table." +msgid "Cancelled. New diameter value is already in the Tool Table." +msgstr "Cancelled. New diameter value is already in the Tool Table." -#: flatcamTools/ToolNonCopperClear.py:1119 flatcamTools/ToolPaint.py:953 +#: flatcamTools/ToolNCC.py:1575 flatcamTools/ToolPaint.py:1355 msgid "Delete failed. Select a tool to delete." msgstr "Delete failed. Select a tool to delete." -#: flatcamTools/ToolNonCopperClear.py:1124 flatcamTools/ToolPaint.py:959 +#: flatcamTools/ToolNCC.py:1581 flatcamTools/ToolPaint.py:1361 msgid "Tool(s) deleted from Tool Table." msgstr "Tool(s) deleted from Tool Table." -#: flatcamTools/ToolNonCopperClear.py:1171 +#: flatcamTools/ToolNCC.py:1623 msgid "Wrong Tool Dia value format entered, use a number." msgstr "Wrong Tool Dia value format entered, use a number." -#: flatcamTools/ToolNonCopperClear.py:1180 flatcamTools/ToolPaint.py:1023 +#: flatcamTools/ToolNCC.py:1632 flatcamTools/ToolPaint.py:1412 msgid "No selected tools in Tool Table." msgstr "No selected tools in Tool Table." -#: flatcamTools/ToolNonCopperClear.py:1255 flatcamTools/ToolPaint.py:1195 +#: flatcamTools/ToolNCC.py:1708 flatcamTools/ToolPaint.py:1588 msgid "Click the end point of the paint area." msgstr "Click the end point of the paint area." -#: flatcamTools/ToolNonCopperClear.py:1410 -#: flatcamTools/ToolNonCopperClear.py:1412 -msgid "Non-Copper clearing ..." -msgstr "Non-Copper clearing ..." - -#: flatcamTools/ToolNonCopperClear.py:1422 -msgid "NCC Tool started. Reading parameters." -msgstr "NCC Tool started. Reading parameters." - -#: flatcamTools/ToolNonCopperClear.py:1485 +#: flatcamTools/ToolNCC.py:1976 flatcamTools/ToolNCC.py:2964 msgid "NCC Tool. Preparing non-copper polygons." msgstr "NCC Tool. Preparing non-copper polygons." -#: flatcamTools/ToolNonCopperClear.py:1581 -msgid "" -"NCC Tool. Finished non-copper polygons. Normal copper clearing task started." -msgstr "" -"NCC Tool. Finished non-copper polygons. Normal copper clearing task started." - -#: flatcamTools/ToolNonCopperClear.py:1613 +#: flatcamTools/ToolNCC.py:2035 flatcamTools/ToolNCC.py:3092 msgid "NCC Tool. Calculate 'empty' area." msgstr "NCC Tool. Calculate 'empty' area." -#: flatcamTools/ToolNonCopperClear.py:1626 -#: flatcamTools/ToolNonCopperClear.py:1723 -#: flatcamTools/ToolNonCopperClear.py:1735 -#: flatcamTools/ToolNonCopperClear.py:2018 -#: flatcamTools/ToolNonCopperClear.py:2114 -#: flatcamTools/ToolNonCopperClear.py:2126 +#: flatcamTools/ToolNCC.py:2054 flatcamTools/ToolNCC.py:2160 +#: flatcamTools/ToolNCC.py:2174 flatcamTools/ToolNCC.py:3105 +#: flatcamTools/ToolNCC.py:3210 flatcamTools/ToolNCC.py:3225 +#: flatcamTools/ToolNCC.py:3491 flatcamTools/ToolNCC.py:3592 +#: flatcamTools/ToolNCC.py:3607 msgid "Buffering finished" msgstr "Buffering finished" -#: flatcamTools/ToolNonCopperClear.py:1742 -#: flatcamTools/ToolNonCopperClear.py:2132 -msgid "The selected object is not suitable for copper clearing." -msgstr "The selected object is not suitable for copper clearing." - -#: flatcamTools/ToolNonCopperClear.py:1747 -#: flatcamTools/ToolNonCopperClear.py:2137 +#: flatcamTools/ToolNCC.py:2062 flatcamTools/ToolNCC.py:2181 +#: flatcamTools/ToolNCC.py:3113 flatcamTools/ToolNCC.py:3232 +#: flatcamTools/ToolNCC.py:3498 flatcamTools/ToolNCC.py:3614 msgid "Could not get the extent of the area to be non copper cleared." msgstr "Could not get the extent of the area to be non copper cleared." -#: flatcamTools/ToolNonCopperClear.py:1754 +#: flatcamTools/ToolNCC.py:2089 flatcamTools/ToolNCC.py:2167 +#: flatcamTools/ToolNCC.py:3140 flatcamTools/ToolNCC.py:3217 +#: flatcamTools/ToolNCC.py:3518 flatcamTools/ToolNCC.py:3599 +msgid "" +"Isolation geometry is broken. Margin is less than isolation tool diameter." +msgstr "" +"Isolation geometry is broken. Margin is less than isolation tool diameter." + +#: flatcamTools/ToolNCC.py:2184 flatcamTools/ToolNCC.py:3236 +#: flatcamTools/ToolNCC.py:3617 +msgid "The selected object is not suitable for copper clearing." +msgstr "The selected object is not suitable for copper clearing." + +#: flatcamTools/ToolNCC.py:2191 flatcamTools/ToolNCC.py:3243 msgid "NCC Tool. Finished calculation of 'empty' area." msgstr "NCC Tool. Finished calculation of 'empty' area." -#: flatcamTools/ToolNonCopperClear.py:1768 -#: flatcamTools/ToolNonCopperClear.py:2162 -msgid "NCC Tool clearing with tool diameter = " -msgstr "NCC Tool clearing with tool diameter = " +#: flatcamTools/ToolNCC.py:2222 flatcamTools/ToolNCC.py:2224 +#: flatcamTools/ToolNCC.py:2916 flatcamTools/ToolNCC.py:2918 +msgid "Non-Copper clearing ..." +msgstr "Non-Copper clearing ..." -#: flatcamTools/ToolNonCopperClear.py:1771 -#: flatcamTools/ToolNonCopperClear.py:2165 +#: flatcamTools/ToolNCC.py:2278 flatcamTools/ToolNCC.py:3060 +msgid "" +"NCC Tool. Finished non-copper polygons. Normal copper clearing task started." +msgstr "" +"NCC Tool. Finished non-copper polygons. Normal copper clearing task started." + +#: flatcamTools/ToolNCC.py:2312 flatcamTools/ToolNCC.py:2592 +msgid "NCC Tool failed creating bounding box." +msgstr "NCC Tool failed creating bounding box." + +#: flatcamTools/ToolNCC.py:2326 flatcamTools/ToolNCC.py:2609 +#: flatcamTools/ToolNCC.py:3256 flatcamTools/ToolNCC.py:3642 +#| msgid "NCC Tool clearing with tool diameter = " +msgid "NCC Tool clearing with tool diameter" +msgstr "NCC Tool clearing with tool diameter" + +#: flatcamTools/ToolNCC.py:2326 flatcamTools/ToolNCC.py:2609 +#: flatcamTools/ToolNCC.py:3256 flatcamTools/ToolNCC.py:3642 msgid "started." msgstr "started." -#: flatcamTools/ToolNonCopperClear.py:1947 +#: flatcamTools/ToolNCC.py:2518 flatcamTools/ToolNCC.py:3417 msgid "" "There is no NCC Geometry in the file.\n" "Usually it means that the tool diameter is too big for the painted " @@ -14806,25 +15883,25 @@ msgstr "" "geometry.\n" "Change the painting parameters and try again." -#: flatcamTools/ToolNonCopperClear.py:1967 +#: flatcamTools/ToolNCC.py:2527 flatcamTools/ToolNCC.py:3426 msgid "NCC Tool clear all done." msgstr "NCC Tool clear all done." -#: flatcamTools/ToolNonCopperClear.py:1969 +#: flatcamTools/ToolNCC.py:2530 flatcamTools/ToolNCC.py:3429 msgid "NCC Tool clear all done but the copper features isolation is broken for" msgstr "" "NCC Tool clear all done but the copper features isolation is broken for" -#: flatcamTools/ToolNonCopperClear.py:1972 -#: flatcamTools/ToolNonCopperClear.py:2341 +#: flatcamTools/ToolNCC.py:2532 flatcamTools/ToolNCC.py:2817 +#: flatcamTools/ToolNCC.py:3431 flatcamTools/ToolNCC.py:3814 msgid "tools" msgstr "tools" -#: flatcamTools/ToolNonCopperClear.py:2337 +#: flatcamTools/ToolNCC.py:2813 flatcamTools/ToolNCC.py:3810 msgid "NCC Tool Rest Machining clear all done." msgstr "NCC Tool Rest Machining clear all done." -#: flatcamTools/ToolNonCopperClear.py:2340 +#: flatcamTools/ToolNCC.py:2816 flatcamTools/ToolNCC.py:3813 msgid "" "NCC Tool Rest Machining clear all done but the copper features isolation is " "broken for" @@ -14832,7 +15909,11 @@ msgstr "" "NCC Tool Rest Machining clear all done but the copper features isolation is " "broken for" -#: flatcamTools/ToolNonCopperClear.py:2787 +#: flatcamTools/ToolNCC.py:2928 +msgid "NCC Tool started. Reading parameters." +msgstr "NCC Tool started. Reading parameters." + +#: flatcamTools/ToolNCC.py:3906 msgid "" "Try to use the Buffering Type = Full in Preferences -> Gerber General. " "Reload the Gerber file after this change." @@ -14840,43 +15921,43 @@ msgstr "" "Try to use the Buffering Type = Full in Preferences -> Gerber General. " "Reload the Gerber file after this change." -#: flatcamTools/ToolOptimal.py:79 +#: flatcamTools/ToolOptimal.py:80 msgid "Number of decimals kept for found distances." msgstr "Number of decimals kept for found distances." -#: flatcamTools/ToolOptimal.py:87 +#: flatcamTools/ToolOptimal.py:88 msgid "Minimum distance" msgstr "Minimum distance" -#: flatcamTools/ToolOptimal.py:88 +#: flatcamTools/ToolOptimal.py:89 msgid "Display minimum distance between copper features." msgstr "Display minimum distance between copper features." -#: flatcamTools/ToolOptimal.py:92 +#: flatcamTools/ToolOptimal.py:93 msgid "Determined" msgstr "Determined" -#: flatcamTools/ToolOptimal.py:106 +#: flatcamTools/ToolOptimal.py:107 msgid "Occurring" msgstr "Occurring" -#: flatcamTools/ToolOptimal.py:107 +#: flatcamTools/ToolOptimal.py:108 msgid "How many times this minimum is found." msgstr "How many times this minimum is found." -#: flatcamTools/ToolOptimal.py:113 +#: flatcamTools/ToolOptimal.py:114 msgid "Minimum points coordinates" msgstr "Minimum points coordinates" -#: flatcamTools/ToolOptimal.py:114 flatcamTools/ToolOptimal.py:120 +#: flatcamTools/ToolOptimal.py:115 flatcamTools/ToolOptimal.py:121 msgid "Coordinates for points where minimum distance was found." msgstr "Coordinates for points where minimum distance was found." -#: flatcamTools/ToolOptimal.py:133 flatcamTools/ToolOptimal.py:209 +#: flatcamTools/ToolOptimal.py:134 flatcamTools/ToolOptimal.py:210 msgid "Jump to selected position" msgstr "Jump to selected position" -#: flatcamTools/ToolOptimal.py:135 flatcamTools/ToolOptimal.py:211 +#: flatcamTools/ToolOptimal.py:136 flatcamTools/ToolOptimal.py:212 msgid "" "Select a position in the Locations text box and then\n" "click this button." @@ -14884,11 +15965,11 @@ msgstr "" "Select a position in the Locations text box and then\n" "click this button." -#: flatcamTools/ToolOptimal.py:143 +#: flatcamTools/ToolOptimal.py:144 msgid "Other distances" msgstr "Other distances" -#: flatcamTools/ToolOptimal.py:144 +#: flatcamTools/ToolOptimal.py:145 msgid "" "Will display other distances in the Gerber file ordered from\n" "the minimum to the maximum, not including the absolute minimum." @@ -14896,13 +15977,13 @@ msgstr "" "Will display other distances in the Gerber file ordered from\n" "the minimum to the maximum, not including the absolute minimum." -#: flatcamTools/ToolOptimal.py:149 +#: flatcamTools/ToolOptimal.py:150 msgid "Other distances points coordinates" msgstr "Other distances points coordinates" -#: flatcamTools/ToolOptimal.py:150 flatcamTools/ToolOptimal.py:164 -#: flatcamTools/ToolOptimal.py:171 flatcamTools/ToolOptimal.py:188 -#: flatcamTools/ToolOptimal.py:195 +#: flatcamTools/ToolOptimal.py:151 flatcamTools/ToolOptimal.py:165 +#: flatcamTools/ToolOptimal.py:172 flatcamTools/ToolOptimal.py:189 +#: flatcamTools/ToolOptimal.py:196 msgid "" "Other distances and the coordinates for points\n" "where the distance was found." @@ -14910,19 +15991,19 @@ msgstr "" "Other distances and the coordinates for points\n" "where the distance was found." -#: flatcamTools/ToolOptimal.py:163 +#: flatcamTools/ToolOptimal.py:164 msgid "Gerber distances" msgstr "Gerber distances" -#: flatcamTools/ToolOptimal.py:187 +#: flatcamTools/ToolOptimal.py:188 msgid "Points coordinates" msgstr "Points coordinates" -#: flatcamTools/ToolOptimal.py:219 +#: flatcamTools/ToolOptimal.py:220 msgid "Find Minimum" msgstr "Find Minimum" -#: flatcamTools/ToolOptimal.py:221 +#: flatcamTools/ToolOptimal.py:222 msgid "" "Calculate the minimum distance between copper features,\n" "this will allow the determination of the right tool to\n" @@ -14932,11 +16013,11 @@ msgstr "" "this will allow the determination of the right tool to\n" "use for isolation or copper clearing." -#: flatcamTools/ToolOptimal.py:346 +#: flatcamTools/ToolOptimal.py:347 msgid "Only Gerber objects can be evaluated." msgstr "Only Gerber objects can be evaluated." -#: flatcamTools/ToolOptimal.py:352 +#: flatcamTools/ToolOptimal.py:353 msgid "" "Optimal Tool. Started to search for the minimum distance between copper " "features." @@ -14944,15 +16025,15 @@ msgstr "" "Optimal Tool. Started to search for the minimum distance between copper " "features." -#: flatcamTools/ToolOptimal.py:362 +#: flatcamTools/ToolOptimal.py:363 msgid "Optimal Tool. Parsing geometry for aperture" msgstr "Optimal Tool. Parsing geometry for aperture" -#: flatcamTools/ToolOptimal.py:373 +#: flatcamTools/ToolOptimal.py:374 msgid "Optimal Tool. Creating a buffer for the object geometry." msgstr "Optimal Tool. Creating a buffer for the object geometry." -#: flatcamTools/ToolOptimal.py:383 +#: flatcamTools/ToolOptimal.py:384 msgid "" "The Gerber object has one Polygon as geometry.\n" "There are no distances between geometry elements to be found." @@ -14960,17 +16041,17 @@ msgstr "" "The Gerber object has one Polygon as geometry.\n" "There are no distances between geometry elements to be found." -#: flatcamTools/ToolOptimal.py:388 +#: flatcamTools/ToolOptimal.py:389 msgid "" "Optimal Tool. Finding the distances between each two elements. Iterations" msgstr "" "Optimal Tool. Finding the distances between each two elements. Iterations" -#: flatcamTools/ToolOptimal.py:423 +#: flatcamTools/ToolOptimal.py:424 msgid "Optimal Tool. Finding the minimum distance." msgstr "Optimal Tool. Finding the minimum distance." -#: flatcamTools/ToolOptimal.py:439 +#: flatcamTools/ToolOptimal.py:440 msgid "Optimal Tool. Finished successfully." msgstr "Optimal Tool. Finished successfully." @@ -14999,7 +16080,7 @@ msgstr "Open PDF file failed." msgid "Rendered" msgstr "Rendered" -#: flatcamTools/ToolPaint.py:87 +#: flatcamTools/ToolPaint.py:82 msgid "" "Specify the type of object to be painted.\n" "It can be of type: Gerber or Geometry.\n" @@ -15015,7 +16096,7 @@ msgstr "" msgid "Object to be painted." msgstr "Object to be painted." -#: flatcamTools/ToolPaint.py:114 +#: flatcamTools/ToolPaint.py:117 msgid "" "Tools pool from which the algorithm\n" "will pick the ones used for painting." @@ -15023,7 +16104,7 @@ msgstr "" "Tools pool from which the algorithm\n" "will pick the ones used for painting." -#: flatcamTools/ToolPaint.py:129 +#: flatcamTools/ToolPaint.py:134 msgid "" "This is the Tool Number.\n" "Painting will start with the tool with the biggest diameter,\n" @@ -15039,7 +16120,7 @@ msgstr "" "in the resulting geometry. This is because with some tools\n" "this function will not be able to create painting geometry." -#: flatcamTools/ToolPaint.py:141 +#: flatcamTools/ToolPaint.py:146 msgid "" "The Tool Type (TT) can be:
- Circular with 1 ... 4 teeth -> it is " "informative only. Being circular,
the cut width in material is exactly " @@ -15063,51 +16144,7 @@ msgstr "" "table.
Choosing the V-Shape Tool Type automatically will select " "the Operation Type in the resulting geometry as Isolation." -#: flatcamTools/ToolPaint.py:178 -msgid "Diameter for the new tool." -msgstr "Diameter for the new tool." - -#: flatcamTools/ToolPaint.py:253 -msgid "" -"Algorithm for painting:\n" -"- Standard: Fixed step inwards.\n" -"- Seed-based: Outwards from seed.\n" -"- Line-based: Parallel lines." -msgstr "" -"Algorithm for painting:\n" -"- Standard: Fixed step inwards.\n" -"- Seed-based: Outwards from seed.\n" -"- Line-based: Parallel lines." - -#: flatcamTools/ToolPaint.py:283 -msgid "" -"If checked, use 'rest machining'.\n" -"Basically it will clear copper outside PCB features,\n" -"using the biggest tool and continue with the next tools,\n" -"from bigger to smaller, to clear areas of copper that\n" -"could not be cleared by previous tool, until there is\n" -"no more copper to clear or there are no more tools.\n" -"\n" -"If not checked, use the standard algorithm." -msgstr "" -"If checked, use 'rest machining'.\n" -"Basically it will clear copper outside PCB features,\n" -"using the biggest tool and continue with the next tools,\n" -"from bigger to smaller, to clear areas of copper that\n" -"could not be cleared by previous tool, until there is\n" -"no more copper to clear or there are no more tools.\n" -"\n" -"If not checked, use the standard algorithm." - -#: flatcamTools/ToolPaint.py:307 -msgid "Polygon Selection" -msgstr "Polygon Selection" - -#: flatcamTools/ToolPaint.py:309 -msgid "All Polygons" -msgstr "All Polygons" - -#: flatcamTools/ToolPaint.py:328 +#: flatcamTools/ToolPaint.py:498 msgid "" "The type of FlatCAM object to be used as paint reference.\n" "It can be Gerber, Excellon or Geometry." @@ -15115,11 +16152,7 @@ msgstr "" "The type of FlatCAM object to be used as paint reference.\n" "It can be Gerber, Excellon or Geometry." -#: flatcamTools/ToolPaint.py:353 -msgid "Create Paint Geometry" -msgstr "Create Paint Geometry" - -#: flatcamTools/ToolPaint.py:355 +#: flatcamTools/ToolPaint.py:539 msgid "" "- 'Area Selection' - left mouse click to start selection of the area to be " "painted.\n" @@ -15137,128 +16170,169 @@ msgstr "" "- 'Reference Object' - will do non copper clearing within the area\n" "specified by another object." -#: flatcamTools/ToolPaint.py:973 -msgid "Paint Tool. Reading parameters." -msgstr "Paint Tool. Reading parameters." - -#: flatcamTools/ToolPaint.py:988 +#: flatcamTools/ToolPaint.py:1381 #, python-format msgid "Could not retrieve object: %s" msgstr "Could not retrieve object: %s" -#: flatcamTools/ToolPaint.py:1002 +#: flatcamTools/ToolPaint.py:1391 msgid "Can't do Paint on MultiGeo geometries" msgstr "Can't do Paint on MultiGeo geometries" -#: flatcamTools/ToolPaint.py:1035 +#: flatcamTools/ToolPaint.py:1421 msgid "Click on a polygon to paint it." msgstr "Click on a polygon to paint it." -#: flatcamTools/ToolPaint.py:1054 +#: flatcamTools/ToolPaint.py:1441 msgid "Click the start point of the paint area." msgstr "Click the start point of the paint area." -#: flatcamTools/ToolPaint.py:1122 +#: flatcamTools/ToolPaint.py:1506 msgid "Click to add next polygon or right click to start painting." msgstr "Click to add next polygon or right click to start painting." -#: flatcamTools/ToolPaint.py:1135 +#: flatcamTools/ToolPaint.py:1519 msgid "Click to add/remove next polygon or right click to start painting." msgstr "Click to add/remove next polygon or right click to start painting." -#: flatcamTools/ToolPaint.py:1344 flatcamTools/ToolPaint.py:1347 -#: flatcamTools/ToolPaint.py:1349 flatcamTools/ToolPaint.py:1987 -#: flatcamTools/ToolPaint.py:1991 flatcamTools/ToolPaint.py:1994 -#: flatcamTools/ToolPaint.py:2276 flatcamTools/ToolPaint.py:2281 -#: flatcamTools/ToolPaint.py:2284 flatcamTools/ToolPaint.py:2458 -#: flatcamTools/ToolPaint.py:2465 -msgid "Paint Tool." -msgstr "Paint Tool." +#: flatcamTools/ToolPaint.py:2013 +#| msgid "Painting polygon at location" +msgid "Painting polygon with method: lines." +msgstr "Painting polygon with method: lines." -#: flatcamTools/ToolPaint.py:1344 flatcamTools/ToolPaint.py:1347 -#: flatcamTools/ToolPaint.py:1349 -msgid "Normal painting polygon task started." -msgstr "Normal painting polygon task started." +#: flatcamTools/ToolPaint.py:2025 +#| msgid "Normal painting polygon task started." +msgid "Failed. Painting polygon with method: seed." +msgstr "Failed. Painting polygon with method: seed." -#: flatcamTools/ToolPaint.py:1345 flatcamTools/ToolPaint.py:1706 -#: flatcamTools/ToolPaint.py:1988 flatcamTools/ToolPaint.py:2278 -#: flatcamTools/ToolPaint.py:2460 -msgid "Buffering geometry..." -msgstr "Buffering geometry..." +#: flatcamTools/ToolPaint.py:2036 +#| msgid "Normal painting polygon task started." +msgid "Failed. Painting polygon with method: standard." +msgstr "Failed. Painting polygon with method: standard." -#: flatcamTools/ToolPaint.py:1367 -msgid "No polygon found." -msgstr "No polygon found." - -#: flatcamTools/ToolPaint.py:1401 -msgid "Painting polygon..." -msgstr "Painting polygon..." - -#: flatcamTools/ToolPaint.py:1448 +#: flatcamTools/ToolPaint.py:2052 msgid "Geometry could not be painted completely" msgstr "Geometry could not be painted completely" -#: flatcamTools/ToolPaint.py:1481 -msgid "" -"Could not do Paint. Try a different combination of parameters. Or a " -"different strategy of paint" -msgstr "" -"Could not do Paint. Try a different combination of parameters. Or a " -"different strategy of paint" +#: flatcamTools/ToolPaint.py:2081 flatcamTools/ToolPaint.py:2084 +#: flatcamTools/ToolPaint.py:2092 flatcamTools/ToolPaint.py:2634 +#: flatcamTools/ToolPaint.py:2638 flatcamTools/ToolPaint.py:2641 +#: flatcamTools/ToolPaint.py:3448 flatcamTools/ToolPaint.py:3452 +#: flatcamTools/ToolPaint.py:3455 +msgid "Paint Tool." +msgstr "Paint Tool." -#: flatcamTools/ToolPaint.py:1533 flatcamTools/ToolPaint.py:1967 -#: flatcamTools/ToolPaint.py:2117 flatcamTools/ToolPaint.py:2438 -#: flatcamTools/ToolPaint.py:2592 -msgid "" -"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." -msgstr "" -"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." +#: flatcamTools/ToolPaint.py:2081 flatcamTools/ToolPaint.py:2084 +#: flatcamTools/ToolPaint.py:2092 +msgid "Normal painting polygon task started." +msgstr "Normal painting polygon task started." -#: flatcamTools/ToolPaint.py:1539 -msgid "Paint Single Done." -msgstr "Paint Single Done." +#: flatcamTools/ToolPaint.py:2082 flatcamTools/ToolPaint.py:2423 +#: flatcamTools/ToolPaint.py:2635 flatcamTools/ToolPaint.py:3085 +#: flatcamTools/ToolPaint.py:3449 +msgid "Buffering geometry..." +msgstr "Buffering geometry..." -#: flatcamTools/ToolPaint.py:1571 flatcamTools/ToolPaint.py:2145 -#: flatcamTools/ToolPaint.py:2620 -msgid "Polygon Paint started ..." -msgstr "Polygon Paint started ..." +#: flatcamTools/ToolPaint.py:2105 +msgid "No polygon found." +msgstr "No polygon found." -#: flatcamTools/ToolPaint.py:1623 flatcamTools/ToolPaint.py:2207 -msgid "Painting polygons..." -msgstr "Painting polygons..." +#: flatcamTools/ToolPaint.py:2135 +msgid "Painting polygon..." +msgstr "Painting polygon..." -#: flatcamTools/ToolPaint.py:1705 flatcamTools/ToolPaint.py:1708 -#: flatcamTools/ToolPaint.py:1710 -msgid "Paint Tool. Normal painting all task started." -msgstr "Paint Tool. Normal painting all task started." - -#: flatcamTools/ToolPaint.py:1744 flatcamTools/ToolPaint.py:2023 -#: flatcamTools/ToolPaint.py:2325 flatcamTools/ToolPaint.py:2501 +#: flatcamTools/ToolPaint.py:2144 flatcamTools/ToolPaint.py:2466 +#: flatcamTools/ToolPaint.py:2674 flatcamTools/ToolPaint.py:3132 +#: flatcamTools/ToolPaint.py:3492 msgid "Painting with tool diameter = " msgstr "Painting with tool diameter = " -#: flatcamTools/ToolPaint.py:1747 flatcamTools/ToolPaint.py:2026 -#: flatcamTools/ToolPaint.py:2328 flatcamTools/ToolPaint.py:2504 +#: flatcamTools/ToolPaint.py:2145 flatcamTools/ToolPaint.py:2469 +#: flatcamTools/ToolPaint.py:2677 flatcamTools/ToolPaint.py:3135 +#: flatcamTools/ToolPaint.py:3495 msgid "started" msgstr "started" -#: flatcamTools/ToolPaint.py:1976 +#: flatcamTools/ToolPaint.py:2170 flatcamTools/ToolPaint.py:2494 +#: flatcamTools/ToolPaint.py:2703 flatcamTools/ToolPaint.py:3161 +#: flatcamTools/ToolPaint.py:3524 +msgid "Margin parameter too big. Tool is not used" +msgstr "Margin parameter too big. Tool is not used" + +#: flatcamTools/ToolPaint.py:2210 flatcamTools/ToolPaint.py:2564 +#: flatcamTools/ToolPaint.py:3377 +msgid "" +"Could not do Paint. Try a different combination of parameters. Or a " +"different strategy of paint" +msgstr "" +"Could not do Paint. Try a different combination of parameters. Or a " +"different strategy of paint" + +#: flatcamTools/ToolPaint.py:2268 flatcamTools/ToolPaint.py:2614 +#: flatcamTools/ToolPaint.py:2955 flatcamTools/ToolPaint.py:3428 +#: flatcamTools/ToolPaint.py:3771 +msgid "" +"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." +msgstr "" +"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." + +#: flatcamTools/ToolPaint.py:2300 +#| msgid "Paint Single Done." +msgid "Paint Single failed." +msgstr "Paint Single failed." + +#: flatcamTools/ToolPaint.py:2306 +msgid "Paint Single Done." +msgstr "Paint Single Done." + +#: flatcamTools/ToolPaint.py:2308 flatcamTools/ToolPaint.py:2983 +#: flatcamTools/ToolPaint.py:3799 +msgid "Polygon Paint started ..." +msgstr "Polygon Paint started ..." + +#: flatcamTools/ToolPaint.py:2347 flatcamTools/ToolPaint.py:3023 +msgid "Painting polygons..." +msgstr "Painting polygons..." + +#: flatcamTools/ToolPaint.py:2422 flatcamTools/ToolPaint.py:2425 +#: flatcamTools/ToolPaint.py:2427 +msgid "Paint Tool. Normal painting all task started." +msgstr "Paint Tool. Normal painting all task started." + +#: flatcamTools/ToolPaint.py:2623 msgid "Paint All Done." msgstr "Paint All Done." -#: flatcamTools/ToolPaint.py:1987 flatcamTools/ToolPaint.py:1991 -#: flatcamTools/ToolPaint.py:1994 +#: flatcamTools/ToolPaint.py:2634 flatcamTools/ToolPaint.py:2638 +#: flatcamTools/ToolPaint.py:2641 msgid "Rest machining painting all task started." msgstr "Rest machining painting all task started." -#: flatcamTools/ToolPaint.py:2072 flatcamTools/ToolPaint.py:2388 -#: flatcamTools/ToolPaint.py:2548 +#: flatcamTools/ToolPaint.py:2862 flatcamTools/ToolPaint.py:3334 +#: flatcamTools/ToolPaint.py:3683 +#| msgid "Painting polygon at location" +msgid "Painting polygons with method: lines." +msgstr "Painting polygons with method: lines." + +#: flatcamTools/ToolPaint.py:2875 flatcamTools/ToolPaint.py:3347 +#: flatcamTools/ToolPaint.py:3695 +#| msgid "Normal painting polygon task started." +msgid "Failed. Painting polygons with method: seed." +msgstr "Failed. Painting polygons with method: seed." + +#: flatcamTools/ToolPaint.py:2887 flatcamTools/ToolPaint.py:3359 +#: flatcamTools/ToolPaint.py:3707 +#| msgid "Normal painting polygon task started." +msgid "Failed. Painting polygons with method: standard." +msgstr "Failed. Painting polygons with method: standard." + +#: flatcamTools/ToolPaint.py:2904 flatcamTools/ToolPaint.py:3723 msgid "" "Could not do Paint All. Try a different combination of parameters. Or a " "different Method of paint" @@ -15266,32 +16340,30 @@ msgstr "" "Could not do Paint All. Try a different combination of parameters. Or a " "different Method of paint" -#: flatcamTools/ToolPaint.py:2126 flatcamTools/ToolPaint.py:2601 +#: flatcamTools/ToolPaint.py:2964 flatcamTools/ToolPaint.py:3780 msgid "Paint All with Rest-Machining done." msgstr "Paint All with Rest-Machining done." -#: flatcamTools/ToolPaint.py:2277 flatcamTools/ToolPaint.py:2281 -#: flatcamTools/ToolPaint.py:2284 -msgid "Normal painting area task started." -msgstr "Normal painting area task started." +#: flatcamTools/ToolPaint.py:3084 flatcamTools/ToolPaint.py:3087 +#: flatcamTools/ToolPaint.py:3089 +#| msgid "Paint Tool. Normal painting all task started." +msgid "Paint Tool. Normal painting area task started." +msgstr "Paint Tool. Normal painting area task started." -#: flatcamTools/ToolPaint.py:2447 +#: flatcamTools/ToolPaint.py:3437 msgid "Paint Area Done." msgstr "Paint Area Done." -#: flatcamTools/ToolPaint.py:2459 flatcamTools/ToolPaint.py:2465 +#: flatcamTools/ToolPaint.py:3448 flatcamTools/ToolPaint.py:3452 +#: flatcamTools/ToolPaint.py:3455 msgid "Rest machining painting area task started." msgstr "Rest machining painting area task started." -#: flatcamTools/ToolPaint.py:2462 -msgid "Paint Tool. Rest machining painting area task started." -msgstr "Paint Tool. Rest machining painting area task started." - #: flatcamTools/ToolPanelize.py:34 msgid "Panelize PCB" msgstr "Panelize PCB" -#: flatcamTools/ToolPanelize.py:68 +#: flatcamTools/ToolPanelize.py:56 msgid "" "Specify the type of object to be panelized\n" "It can be of type: Gerber, Excellon or Geometry.\n" @@ -15303,7 +16375,7 @@ msgstr "" "The selection here decide the type of objects that will be\n" "in the Object combobox." -#: flatcamTools/ToolPanelize.py:83 +#: flatcamTools/ToolPanelize.py:89 msgid "" "Object to be panelized. This means that it will\n" "be duplicated in an array of rows and columns." @@ -15311,11 +16383,11 @@ msgstr "" "Object to be panelized. This means that it will\n" "be duplicated in an array of rows and columns." -#: flatcamTools/ToolPanelize.py:96 +#: flatcamTools/ToolPanelize.py:102 msgid "Penelization Reference" msgstr "Penelization Reference" -#: flatcamTools/ToolPanelize.py:98 +#: flatcamTools/ToolPanelize.py:104 msgid "" "Choose the reference for panelization:\n" "- Object = the bounding box of a different object\n" @@ -15335,11 +16407,11 @@ msgstr "" "to this reference object therefore maintaining the panelized\n" "objects in sync." -#: flatcamTools/ToolPanelize.py:121 +#: flatcamTools/ToolPanelize.py:125 msgid "Box Type" msgstr "Box Type" -#: flatcamTools/ToolPanelize.py:123 +#: flatcamTools/ToolPanelize.py:127 msgid "" "Specify the type of object to be used as an container for\n" "panelization. It can be: Gerber or Geometry type.\n" @@ -15351,7 +16423,7 @@ msgstr "" "The selection here decide the type of objects that will be\n" "in the Box Object combobox." -#: flatcamTools/ToolPanelize.py:138 +#: flatcamTools/ToolPanelize.py:141 msgid "" "The actual object that is used a container for the\n" " selected object that is to be panelized." @@ -15359,11 +16431,11 @@ msgstr "" "The actual object that is used a container for the\n" " selected object that is to be panelized." -#: flatcamTools/ToolPanelize.py:144 +#: flatcamTools/ToolPanelize.py:147 msgid "Panel Data" msgstr "Panel Data" -#: flatcamTools/ToolPanelize.py:146 +#: flatcamTools/ToolPanelize.py:149 msgid "" "This informations will shape the resulting panel.\n" "The number of rows and columns will set how many\n" @@ -15379,7 +16451,7 @@ msgstr "" "The spacings will set the distance between any two\n" "elements of the panel array." -#: flatcamTools/ToolPanelize.py:205 +#: flatcamTools/ToolPanelize.py:208 msgid "" "Choose the type of object for the panel object:\n" "- Geometry\n" @@ -15389,15 +16461,15 @@ msgstr "" "- Geometry\n" "- Gerber" -#: flatcamTools/ToolPanelize.py:213 +#: flatcamTools/ToolPanelize.py:216 msgid "Constrain panel within" msgstr "Constrain panel within" -#: flatcamTools/ToolPanelize.py:249 +#: flatcamTools/ToolPanelize.py:252 msgid "Panelize Object" msgstr "Panelize Object" -#: flatcamTools/ToolPanelize.py:251 flatcamTools/ToolRulesCheck.py:492 +#: flatcamTools/ToolPanelize.py:254 flatcamTools/ToolRulesCheck.py:501 msgid "" "Panelize the specified object around the specified box.\n" "In other words it creates multiple copies of the source object,\n" @@ -15407,31 +16479,31 @@ msgstr "" "In other words it creates multiple copies of the source object,\n" "arranged in a 2D array of rows and columns." -#: flatcamTools/ToolPanelize.py:319 +#: flatcamTools/ToolPanelize.py:322 msgid "Panel. Tool" msgstr "Panel. Tool" -#: flatcamTools/ToolPanelize.py:448 +#: flatcamTools/ToolPanelize.py:460 msgid "Columns or Rows are zero value. Change them to a positive integer." msgstr "Columns or Rows are zero value. Change them to a positive integer." -#: flatcamTools/ToolPanelize.py:485 +#: flatcamTools/ToolPanelize.py:497 msgid "Generating panel ... " msgstr "Generating panel ... " -#: flatcamTools/ToolPanelize.py:768 +#: flatcamTools/ToolPanelize.py:777 msgid "Generating panel ... Adding the Gerber code." msgstr "Generating panel ... Adding the Gerber code." -#: flatcamTools/ToolPanelize.py:779 +#: flatcamTools/ToolPanelize.py:788 msgid "Generating panel... Spawning copies" msgstr "Generating panel... Spawning copies" -#: flatcamTools/ToolPanelize.py:786 +#: flatcamTools/ToolPanelize.py:795 msgid "Panel done..." msgstr "Panel done..." -#: flatcamTools/ToolPanelize.py:789 +#: flatcamTools/ToolPanelize.py:798 #, python-brace-format msgid "" "{text} Too big for the constrain area. Final panel has {col} columns and " @@ -15440,7 +16512,7 @@ msgstr "" "{text} Too big for the constrain area. Final panel has {col} columns and " "{row} rows" -#: flatcamTools/ToolPanelize.py:798 +#: flatcamTools/ToolPanelize.py:807 msgid "Panel created successfully." msgstr "Panel created successfully." @@ -15580,163 +16652,226 @@ msgstr "PcbWizard .INF file loaded." msgid "Main PcbWizard Excellon file loaded." msgstr "Main PcbWizard Excellon file loaded." -#: flatcamTools/ToolPcbWizard.py:431 +#: flatcamTools/ToolPcbWizard.py:428 msgid "Cannot parse file" msgstr "Cannot parse file" -#: flatcamTools/ToolPcbWizard.py:456 +#: flatcamTools/ToolPcbWizard.py:452 msgid "Importing Excellon." msgstr "Importing Excellon." -#: flatcamTools/ToolPcbWizard.py:463 +#: flatcamTools/ToolPcbWizard.py:459 msgid "Import Excellon file failed." msgstr "Import Excellon file failed." -#: flatcamTools/ToolPcbWizard.py:471 +#: flatcamTools/ToolPcbWizard.py:467 msgid "Imported" msgstr "Imported" -#: flatcamTools/ToolPcbWizard.py:475 +#: flatcamTools/ToolPcbWizard.py:471 msgid "Excellon merging is in progress. Please wait..." msgstr "Excellon merging is in progress. Please wait..." -#: flatcamTools/ToolPcbWizard.py:478 +#: flatcamTools/ToolPcbWizard.py:474 msgid "The imported Excellon file is None." msgstr "The imported Excellon file is None." -#: flatcamTools/ToolProperties.py:119 -msgid "Properties Tool was not displayed. No object selected." -msgstr "Properties Tool was not displayed. No object selected." - -#: flatcamTools/ToolProperties.py:134 +#: flatcamTools/ToolProperties.py:131 msgid "Object Properties are displayed." msgstr "Object Properties are displayed." -#: flatcamTools/ToolProperties.py:135 +#: flatcamTools/ToolProperties.py:136 msgid "Properties Tool" msgstr "Properties Tool" -#: flatcamTools/ToolProperties.py:149 +#: flatcamTools/ToolProperties.py:150 msgid "TYPE" msgstr "TYPE" -#: flatcamTools/ToolProperties.py:150 +#: flatcamTools/ToolProperties.py:151 msgid "NAME" msgstr "NAME" -#: flatcamTools/ToolProperties.py:151 +#: flatcamTools/ToolProperties.py:153 msgid "Dimensions" msgstr "Dimensions" -#: flatcamTools/ToolProperties.py:165 -msgid "Others" -msgstr "Others" - -#: flatcamTools/ToolProperties.py:172 +#: flatcamTools/ToolProperties.py:181 msgid "Geo Type" msgstr "Geo Type" -#: flatcamTools/ToolProperties.py:173 +#: flatcamTools/ToolProperties.py:184 msgid "Single-Geo" msgstr "Single-Geo" -#: flatcamTools/ToolProperties.py:173 +#: flatcamTools/ToolProperties.py:185 msgid "Multi-Geo" msgstr "Multi-Geo" -#: flatcamTools/ToolProperties.py:181 +#: flatcamTools/ToolProperties.py:196 msgid "Calculating dimensions ... Please wait." msgstr "Calculating dimensions ... Please wait." -#: flatcamTools/ToolProperties.py:321 flatcamTools/ToolProperties.py:325 -#: flatcamTools/ToolProperties.py:327 +#: flatcamTools/ToolProperties.py:339 flatcamTools/ToolProperties.py:343 +#: flatcamTools/ToolProperties.py:345 msgid "Inch" msgstr "Inch" -#: flatcamTools/ToolProperties.py:321 flatcamTools/ToolProperties.py:326 -#: flatcamTools/ToolProperties.py:328 +#: flatcamTools/ToolProperties.py:339 flatcamTools/ToolProperties.py:344 +#: flatcamTools/ToolProperties.py:346 msgid "Metric" msgstr "Metric" -#: flatcamTools/ToolProperties.py:401 flatcamTools/ToolProperties.py:459 +#: flatcamTools/ToolProperties.py:421 flatcamTools/ToolProperties.py:486 msgid "Drills number" msgstr "Drills number" -#: flatcamTools/ToolProperties.py:402 flatcamTools/ToolProperties.py:461 +#: flatcamTools/ToolProperties.py:422 flatcamTools/ToolProperties.py:488 msgid "Slots number" msgstr "Slots number" -#: flatcamTools/ToolProperties.py:404 +#: flatcamTools/ToolProperties.py:424 msgid "Drills total number:" msgstr "Drills total number:" -#: flatcamTools/ToolProperties.py:405 +#: flatcamTools/ToolProperties.py:425 msgid "Slots total number:" msgstr "Slots total number:" -#: flatcamTools/ToolProperties.py:411 flatcamTools/ToolProperties.py:426 -#: flatcamTools/ToolProperties.py:429 flatcamTools/ToolProperties.py:432 -#: flatcamTools/ToolProperties.py:456 +#: flatcamTools/ToolProperties.py:452 flatcamTools/ToolProperties.py:455 +#: flatcamTools/ToolProperties.py:458 flatcamTools/ToolProperties.py:483 msgid "Present" msgstr "Present" -#: flatcamTools/ToolProperties.py:427 flatcamTools/ToolProperties.py:457 +#: flatcamTools/ToolProperties.py:453 flatcamTools/ToolProperties.py:484 msgid "Solid Geometry" msgstr "Solid Geometry" -#: flatcamTools/ToolProperties.py:430 +#: flatcamTools/ToolProperties.py:456 msgid "GCode Text" msgstr "GCode Text" -#: flatcamTools/ToolProperties.py:433 +#: flatcamTools/ToolProperties.py:459 msgid "GCode Geometry" msgstr "GCode Geometry" -#: flatcamTools/ToolProperties.py:435 +#: flatcamTools/ToolProperties.py:462 msgid "Data" msgstr "Data" -#: flatcamTools/ToolProperties.py:468 +#: flatcamTools/ToolProperties.py:495 msgid "Depth of Cut" msgstr "Depth of Cut" -#: flatcamTools/ToolProperties.py:480 +#: flatcamTools/ToolProperties.py:507 msgid "Clearance Height" msgstr "Clearance Height" -#: flatcamTools/ToolProperties.py:512 +#: flatcamTools/ToolProperties.py:539 msgid "Routing time" msgstr "Routing time" -#: flatcamTools/ToolProperties.py:519 +#: flatcamTools/ToolProperties.py:546 msgid "Travelled distance" msgstr "Travelled distance" -#: flatcamTools/ToolProperties.py:560 +#: flatcamTools/ToolProperties.py:564 msgid "Width" msgstr "Width" -#: flatcamTools/ToolProperties.py:566 flatcamTools/ToolProperties.py:574 +#: flatcamTools/ToolProperties.py:570 flatcamTools/ToolProperties.py:578 msgid "Box Area" msgstr "Box Area" -#: flatcamTools/ToolProperties.py:569 flatcamTools/ToolProperties.py:577 +#: flatcamTools/ToolProperties.py:573 flatcamTools/ToolProperties.py:581 msgid "Convex_Hull Area" msgstr "Convex_Hull Area" -#: flatcamTools/ToolProperties.py:583 flatcamTools/ToolProperties.py:585 +#: flatcamTools/ToolProperties.py:588 flatcamTools/ToolProperties.py:591 msgid "Copper Area" msgstr "Copper Area" -#: flatcamTools/ToolQRCode.py:79 +#: flatcamTools/ToolPunchGerber.py:30 flatcamTools/ToolPunchGerber.py:323 +#| msgid "Open Gerber" +msgid "Punch Gerber" +msgstr "Punch Gerber" + +#: flatcamTools/ToolPunchGerber.py:65 +#| msgid "Gerber objects for which to check rules." +msgid "Gerber into which to punch holes" +msgstr "Gerber into which to punch holes" + +#: flatcamTools/ToolPunchGerber.py:85 +msgid "ALL" +msgstr "ALL" + +#: flatcamTools/ToolPunchGerber.py:166 +#| msgid "" +#| "Remove the geometry of Excellon from the Film to create the holes in pads." +msgid "" +"Remove the geometry of Excellon from the Gerber to create the holes in pads." +msgstr "" +"Remove the geometry of Excellon from the Gerber to create the holes in pads." + +#: flatcamTools/ToolPunchGerber.py:325 +msgid "" +"Create a Gerber object from the selected object, within\n" +"the specified box." +msgstr "" +"Create a Gerber object from the selected object, within\n" +"the specified box." + +#: flatcamTools/ToolPunchGerber.py:425 +#| msgid "Paint Tool" +msgid "Punch Tool" +msgstr "Punch Tool" + +#: flatcamTools/ToolPunchGerber.py:599 +msgid "The value of the fixed diameter is 0.0. Aborting." +msgstr "The value of the fixed diameter is 0.0. Aborting." + +#: flatcamTools/ToolPunchGerber.py:607 +#| msgid "" +#| " Could not generate punched hole film because the punch hole sizeis " +#| "bigger than some of the apertures in the Gerber object." +msgid "" +" Could not generate punched hole Gerber because the punch hole sizeis bigger " +"than some of the apertures in the Gerber object." +msgstr "" +" Could not generate punched hole Gerber because the punch hole sizeis bigger " +"than some of the apertures in the Gerber object." + +#: flatcamTools/ToolPunchGerber.py:619 +#| msgid "" +#| "Could not generate punched hole film because the punch hole sizeis bigger " +#| "than some of the apertures in the Gerber object." +msgid "" +"Could not generate punched hole Gerber because the punch hole sizeis bigger " +"than some of the apertures in the Gerber object." +msgstr "" +"Could not generate punched hole Gerber because the punch hole sizeis bigger " +"than some of the apertures in the Gerber object." + +#: flatcamTools/ToolPunchGerber.py:656 +#| msgid "" +#| "Could not generate punched hole film because the newly created object " +#| "geometry is the same as the one in the source object geometry..." +msgid "" +"Could not generate punched hole Gerber because the newly created object " +"geometry is the same as the one in the source object geometry..." +msgstr "" +"Could not generate punched hole Gerber because the newly created object " +"geometry is the same as the one in the source object geometry..." + +#: flatcamTools/ToolQRCode.py:80 msgid "Gerber Object to which the QRCode will be added." msgstr "Gerber Object to which the QRCode will be added." -#: flatcamTools/ToolQRCode.py:92 +#: flatcamTools/ToolQRCode.py:93 msgid "QRCode Parameters" msgstr "QRCode Parameters" -#: flatcamTools/ToolQRCode.py:94 +#: flatcamTools/ToolQRCode.py:95 msgid "The parameters used to shape the QRCode." msgstr "The parameters used to shape the QRCode." @@ -15780,31 +16915,27 @@ msgstr "Insert QRCode" msgid "Create the QRCode object." msgstr "Create the QRCode object." -#: flatcamTools/ToolQRCode.py:413 flatcamTools/ToolQRCode.py:748 -#: flatcamTools/ToolQRCode.py:797 +#: flatcamTools/ToolQRCode.py:415 flatcamTools/ToolQRCode.py:750 +#: flatcamTools/ToolQRCode.py:799 msgid "Cancelled. There is no QRCode Data in the text box." msgstr "Cancelled. There is no QRCode Data in the text box." -#: flatcamTools/ToolQRCode.py:432 +#: flatcamTools/ToolQRCode.py:434 msgid "Generating QRCode geometry" msgstr "Generating QRCode geometry" -#: flatcamTools/ToolQRCode.py:472 +#: flatcamTools/ToolQRCode.py:474 msgid "Click on the Destination point ..." msgstr "Click on the Destination point ..." -#: flatcamTools/ToolQRCode.py:587 +#: flatcamTools/ToolQRCode.py:589 msgid "QRCode Tool done." msgstr "QRCode Tool done." -#: flatcamTools/ToolQRCode.py:780 flatcamTools/ToolQRCode.py:784 +#: flatcamTools/ToolQRCode.py:782 flatcamTools/ToolQRCode.py:786 msgid "Export PNG" msgstr "Export PNG" -#: flatcamTools/ToolQRCode.py:789 -msgid " Export PNG cancelled." -msgstr " Export PNG cancelled." - #: flatcamTools/ToolRulesCheck.py:33 msgid "Check Rules" msgstr "Check Rules" @@ -15817,71 +16948,71 @@ msgstr "Gerber Files" msgid "Gerber objects for which to check rules." msgstr "Gerber objects for which to check rules." -#: flatcamTools/ToolRulesCheck.py:77 +#: flatcamTools/ToolRulesCheck.py:78 msgid "Top" msgstr "Top" -#: flatcamTools/ToolRulesCheck.py:79 +#: flatcamTools/ToolRulesCheck.py:80 msgid "The Top Gerber Copper object for which rules are checked." msgstr "The Top Gerber Copper object for which rules are checked." -#: flatcamTools/ToolRulesCheck.py:94 +#: flatcamTools/ToolRulesCheck.py:96 msgid "Bottom" msgstr "Bottom" -#: flatcamTools/ToolRulesCheck.py:96 +#: flatcamTools/ToolRulesCheck.py:98 msgid "The Bottom Gerber Copper object for which rules are checked." msgstr "The Bottom Gerber Copper object for which rules are checked." -#: flatcamTools/ToolRulesCheck.py:111 +#: flatcamTools/ToolRulesCheck.py:114 msgid "SM Top" msgstr "SM Top" -#: flatcamTools/ToolRulesCheck.py:113 +#: flatcamTools/ToolRulesCheck.py:116 msgid "The Top Gerber Solder Mask object for which rules are checked." msgstr "The Top Gerber Solder Mask object for which rules are checked." -#: flatcamTools/ToolRulesCheck.py:128 +#: flatcamTools/ToolRulesCheck.py:132 msgid "SM Bottom" msgstr "SM Bottom" -#: flatcamTools/ToolRulesCheck.py:130 +#: flatcamTools/ToolRulesCheck.py:134 msgid "The Bottom Gerber Solder Mask object for which rules are checked." msgstr "The Bottom Gerber Solder Mask object for which rules are checked." -#: flatcamTools/ToolRulesCheck.py:145 +#: flatcamTools/ToolRulesCheck.py:150 msgid "Silk Top" msgstr "Silk Top" -#: flatcamTools/ToolRulesCheck.py:147 +#: flatcamTools/ToolRulesCheck.py:152 msgid "The Top Gerber Silkscreen object for which rules are checked." msgstr "The Top Gerber Silkscreen object for which rules are checked." -#: flatcamTools/ToolRulesCheck.py:162 +#: flatcamTools/ToolRulesCheck.py:168 msgid "Silk Bottom" msgstr "Silk Bottom" -#: flatcamTools/ToolRulesCheck.py:164 +#: flatcamTools/ToolRulesCheck.py:170 msgid "The Bottom Gerber Silkscreen object for which rules are checked." msgstr "The Bottom Gerber Silkscreen object for which rules are checked." -#: flatcamTools/ToolRulesCheck.py:181 +#: flatcamTools/ToolRulesCheck.py:188 msgid "The Gerber Outline (Cutout) object for which rules are checked." msgstr "The Gerber Outline (Cutout) object for which rules are checked." -#: flatcamTools/ToolRulesCheck.py:192 +#: flatcamTools/ToolRulesCheck.py:199 msgid "Excellon Objects" msgstr "Excellon Objects" -#: flatcamTools/ToolRulesCheck.py:194 +#: flatcamTools/ToolRulesCheck.py:201 msgid "Excellon objects for which to check rules." msgstr "Excellon objects for which to check rules." -#: flatcamTools/ToolRulesCheck.py:205 +#: flatcamTools/ToolRulesCheck.py:213 msgid "Excellon 1" msgstr "Excellon 1" -#: flatcamTools/ToolRulesCheck.py:207 +#: flatcamTools/ToolRulesCheck.py:215 msgid "" "Excellon object for which to check rules.\n" "Holds the plated holes or a general Excellon file content." @@ -15889,11 +17020,11 @@ msgstr "" "Excellon object for which to check rules.\n" "Holds the plated holes or a general Excellon file content." -#: flatcamTools/ToolRulesCheck.py:223 +#: flatcamTools/ToolRulesCheck.py:232 msgid "Excellon 2" msgstr "Excellon 2" -#: flatcamTools/ToolRulesCheck.py:225 +#: flatcamTools/ToolRulesCheck.py:234 msgid "" "Excellon object for which to check rules.\n" "Holds the non-plated holes." @@ -15901,35 +17032,35 @@ msgstr "" "Excellon object for which to check rules.\n" "Holds the non-plated holes." -#: flatcamTools/ToolRulesCheck.py:238 +#: flatcamTools/ToolRulesCheck.py:247 msgid "All Rules" msgstr "All Rules" -#: flatcamTools/ToolRulesCheck.py:240 +#: flatcamTools/ToolRulesCheck.py:249 msgid "This check/uncheck all the rules below." msgstr "This check/uncheck all the rules below." -#: flatcamTools/ToolRulesCheck.py:490 +#: flatcamTools/ToolRulesCheck.py:499 msgid "Run Rules Check" msgstr "Run Rules Check" -#: flatcamTools/ToolRulesCheck.py:1149 flatcamTools/ToolRulesCheck.py:1209 -#: flatcamTools/ToolRulesCheck.py:1246 flatcamTools/ToolRulesCheck.py:1318 -#: flatcamTools/ToolRulesCheck.py:1372 flatcamTools/ToolRulesCheck.py:1410 -#: flatcamTools/ToolRulesCheck.py:1475 +#: flatcamTools/ToolRulesCheck.py:1158 flatcamTools/ToolRulesCheck.py:1218 +#: flatcamTools/ToolRulesCheck.py:1255 flatcamTools/ToolRulesCheck.py:1327 +#: flatcamTools/ToolRulesCheck.py:1381 flatcamTools/ToolRulesCheck.py:1419 +#: flatcamTools/ToolRulesCheck.py:1484 msgid "Value is not valid." msgstr "Value is not valid." -#: flatcamTools/ToolRulesCheck.py:1163 +#: flatcamTools/ToolRulesCheck.py:1172 msgid "TOP -> Copper to Copper clearance" msgstr "TOP -> Copper to Copper clearance" -#: flatcamTools/ToolRulesCheck.py:1174 +#: flatcamTools/ToolRulesCheck.py:1183 msgid "BOTTOM -> Copper to Copper clearance" msgstr "BOTTOM -> Copper to Copper clearance" -#: flatcamTools/ToolRulesCheck.py:1179 flatcamTools/ToolRulesCheck.py:1273 -#: flatcamTools/ToolRulesCheck.py:1437 +#: flatcamTools/ToolRulesCheck.py:1188 flatcamTools/ToolRulesCheck.py:1282 +#: flatcamTools/ToolRulesCheck.py:1446 msgid "" "At least one Gerber object has to be selected for this rule but none is " "selected." @@ -15937,13 +17068,13 @@ msgstr "" "At least one Gerber object has to be selected for this rule but none is " "selected." -#: flatcamTools/ToolRulesCheck.py:1215 +#: flatcamTools/ToolRulesCheck.py:1224 msgid "" "One of the copper Gerber objects or the Outline Gerber object is not valid." msgstr "" "One of the copper Gerber objects or the Outline Gerber object is not valid." -#: flatcamTools/ToolRulesCheck.py:1228 flatcamTools/ToolRulesCheck.py:1392 +#: flatcamTools/ToolRulesCheck.py:1237 flatcamTools/ToolRulesCheck.py:1401 msgid "" "Outline Gerber object presence is mandatory for this rule but it is not " "selected." @@ -15951,31 +17082,31 @@ msgstr "" "Outline Gerber object presence is mandatory for this rule but it is not " "selected." -#: flatcamTools/ToolRulesCheck.py:1245 flatcamTools/ToolRulesCheck.py:1272 +#: flatcamTools/ToolRulesCheck.py:1254 flatcamTools/ToolRulesCheck.py:1281 msgid "Silk to Silk clearance" msgstr "Silk to Silk clearance" -#: flatcamTools/ToolRulesCheck.py:1258 +#: flatcamTools/ToolRulesCheck.py:1267 msgid "TOP -> Silk to Silk clearance" msgstr "TOP -> Silk to Silk clearance" -#: flatcamTools/ToolRulesCheck.py:1268 +#: flatcamTools/ToolRulesCheck.py:1277 msgid "BOTTOM -> Silk to Silk clearance" msgstr "BOTTOM -> Silk to Silk clearance" -#: flatcamTools/ToolRulesCheck.py:1324 +#: flatcamTools/ToolRulesCheck.py:1333 msgid "One or more of the Gerber objects is not valid." msgstr "One or more of the Gerber objects is not valid." -#: flatcamTools/ToolRulesCheck.py:1332 +#: flatcamTools/ToolRulesCheck.py:1341 msgid "TOP -> Silk to Solder Mask Clearance" msgstr "TOP -> Silk to Solder Mask Clearance" -#: flatcamTools/ToolRulesCheck.py:1338 +#: flatcamTools/ToolRulesCheck.py:1347 msgid "BOTTOM -> Silk to Solder Mask Clearance" msgstr "BOTTOM -> Silk to Solder Mask Clearance" -#: flatcamTools/ToolRulesCheck.py:1342 +#: flatcamTools/ToolRulesCheck.py:1351 msgid "" "Both Silk and Solder Mask Gerber objects has to be either both Top or both " "Bottom." @@ -15983,60 +17114,61 @@ msgstr "" "Both Silk and Solder Mask Gerber objects has to be either both Top or both " "Bottom." -#: flatcamTools/ToolRulesCheck.py:1378 +#: flatcamTools/ToolRulesCheck.py:1387 msgid "" "One of the Silk Gerber objects or the Outline Gerber object is not valid." msgstr "" "One of the Silk Gerber objects or the Outline Gerber object is not valid." -#: flatcamTools/ToolRulesCheck.py:1422 +#: flatcamTools/ToolRulesCheck.py:1431 msgid "TOP -> Minimum Solder Mask Sliver" msgstr "TOP -> Minimum Solder Mask Sliver" -#: flatcamTools/ToolRulesCheck.py:1432 +#: flatcamTools/ToolRulesCheck.py:1441 msgid "BOTTOM -> Minimum Solder Mask Sliver" msgstr "BOTTOM -> Minimum Solder Mask Sliver" -#: flatcamTools/ToolRulesCheck.py:1481 +#: flatcamTools/ToolRulesCheck.py:1490 msgid "One of the Copper Gerber objects or the Excellon objects is not valid." msgstr "One of the Copper Gerber objects or the Excellon objects is not valid." -#: flatcamTools/ToolRulesCheck.py:1497 +#: flatcamTools/ToolRulesCheck.py:1506 msgid "" "Excellon object presence is mandatory for this rule but none is selected." msgstr "" "Excellon object presence is mandatory for this rule but none is selected." -#: flatcamTools/ToolRulesCheck.py:1570 flatcamTools/ToolRulesCheck.py:1583 -#: flatcamTools/ToolRulesCheck.py:1594 flatcamTools/ToolRulesCheck.py:1607 +#: flatcamTools/ToolRulesCheck.py:1579 flatcamTools/ToolRulesCheck.py:1592 +#: flatcamTools/ToolRulesCheck.py:1603 flatcamTools/ToolRulesCheck.py:1616 msgid "STATUS" msgstr "STATUS" -#: flatcamTools/ToolRulesCheck.py:1573 flatcamTools/ToolRulesCheck.py:1597 +#: flatcamTools/ToolRulesCheck.py:1582 flatcamTools/ToolRulesCheck.py:1606 msgid "FAILED" msgstr "FAILED" -#: flatcamTools/ToolRulesCheck.py:1586 flatcamTools/ToolRulesCheck.py:1610 +#: flatcamTools/ToolRulesCheck.py:1595 flatcamTools/ToolRulesCheck.py:1619 msgid "PASSED" msgstr "PASSED" -#: flatcamTools/ToolRulesCheck.py:1587 flatcamTools/ToolRulesCheck.py:1611 +#: flatcamTools/ToolRulesCheck.py:1596 flatcamTools/ToolRulesCheck.py:1620 msgid "Violations: There are no violations for the current rule." msgstr "Violations: There are no violations for the current rule." -#: flatcamTools/ToolShell.py:70 flatcamTools/ToolShell.py:72 -msgid "...proccessing..." -msgstr "...proccessing..." +#: flatcamTools/ToolShell.py:72 flatcamTools/ToolShell.py:74 +#| msgid "...proccessing..." +msgid "...processing..." +msgstr "...processing..." -#: flatcamTools/ToolSolderPaste.py:37 +#: flatcamTools/ToolSolderPaste.py:38 msgid "Solder Paste Tool" msgstr "Solder Paste Tool" -#: flatcamTools/ToolSolderPaste.py:68 +#: flatcamTools/ToolSolderPaste.py:70 msgid "Gerber Solder paste object. " msgstr "Gerber Solder paste object. " -#: flatcamTools/ToolSolderPaste.py:75 +#: flatcamTools/ToolSolderPaste.py:77 msgid "" "Tools pool from which the algorithm\n" "will pick the ones used for dispensing solder paste." @@ -16044,7 +17176,7 @@ msgstr "" "Tools pool from which the algorithm\n" "will pick the ones used for dispensing solder paste." -#: flatcamTools/ToolSolderPaste.py:90 +#: flatcamTools/ToolSolderPaste.py:92 msgid "" "This is the Tool Number.\n" "The solder dispensing will start with the tool with the biggest \n" @@ -16058,7 +17190,7 @@ msgstr "" "If there are no longer tools but there are still pads not covered\n" " with solder paste, the app will issue a warning message box." -#: flatcamTools/ToolSolderPaste.py:97 +#: flatcamTools/ToolSolderPaste.py:99 msgid "" "Nozzle tool Diameter. It's value (in current FlatCAM units)\n" "is the width of the solder paste dispensed." @@ -16066,11 +17198,11 @@ msgstr "" "Nozzle tool Diameter. It's value (in current FlatCAM units)\n" "is the width of the solder paste dispensed." -#: flatcamTools/ToolSolderPaste.py:104 +#: flatcamTools/ToolSolderPaste.py:106 msgid "New Nozzle Tool" msgstr "New Nozzle Tool" -#: flatcamTools/ToolSolderPaste.py:123 +#: flatcamTools/ToolSolderPaste.py:125 msgid "" "Add a new nozzle tool to the Tool Table\n" "with the diameter specified above." @@ -16078,15 +17210,15 @@ msgstr "" "Add a new nozzle tool to the Tool Table\n" "with the diameter specified above." -#: flatcamTools/ToolSolderPaste.py:135 +#: flatcamTools/ToolSolderPaste.py:137 msgid "Generate solder paste dispensing geometry." msgstr "Generate solder paste dispensing geometry." -#: flatcamTools/ToolSolderPaste.py:154 +#: flatcamTools/ToolSolderPaste.py:156 msgid "STEP 1" msgstr "STEP 1" -#: flatcamTools/ToolSolderPaste.py:156 +#: flatcamTools/ToolSolderPaste.py:158 msgid "" "First step is to select a number of nozzle tools for usage\n" "and then optionally modify the GCode parameters bellow." @@ -16094,7 +17226,7 @@ msgstr "" "First step is to select a number of nozzle tools for usage\n" "and then optionally modify the GCode parameters bellow." -#: flatcamTools/ToolSolderPaste.py:159 +#: flatcamTools/ToolSolderPaste.py:161 msgid "" "Select tools.\n" "Modify parameters." @@ -16102,7 +17234,7 @@ msgstr "" "Select tools.\n" "Modify parameters." -#: flatcamTools/ToolSolderPaste.py:279 +#: flatcamTools/ToolSolderPaste.py:281 msgid "" "Feedrate (speed) while moving up vertically\n" " to Dispense position (on Z plane)." @@ -16110,7 +17242,7 @@ msgstr "" "Feedrate (speed) while moving up vertically\n" " to Dispense position (on Z plane)." -#: flatcamTools/ToolSolderPaste.py:349 +#: flatcamTools/ToolSolderPaste.py:351 msgid "" "Generate GCode for Solder Paste dispensing\n" "on PCB pads." @@ -16118,11 +17250,11 @@ msgstr "" "Generate GCode for Solder Paste dispensing\n" "on PCB pads." -#: flatcamTools/ToolSolderPaste.py:370 +#: flatcamTools/ToolSolderPaste.py:372 msgid "STEP 2" msgstr "STEP 2" -#: flatcamTools/ToolSolderPaste.py:372 +#: flatcamTools/ToolSolderPaste.py:374 msgid "" "Second step is to create a solder paste dispensing\n" "geometry out of an Solder Paste Mask Gerber file." @@ -16130,11 +17262,11 @@ msgstr "" "Second step is to create a solder paste dispensing\n" "geometry out of an Solder Paste Mask Gerber file." -#: flatcamTools/ToolSolderPaste.py:388 +#: flatcamTools/ToolSolderPaste.py:391 msgid "Geo Result" msgstr "Geo Result" -#: flatcamTools/ToolSolderPaste.py:390 +#: flatcamTools/ToolSolderPaste.py:393 msgid "" "Geometry Solder Paste object.\n" "The name of the object has to end in:\n" @@ -16144,11 +17276,11 @@ msgstr "" "The name of the object has to end in:\n" "'_solderpaste' as a protection." -#: flatcamTools/ToolSolderPaste.py:399 +#: flatcamTools/ToolSolderPaste.py:402 msgid "STEP 3" msgstr "STEP 3" -#: flatcamTools/ToolSolderPaste.py:401 +#: flatcamTools/ToolSolderPaste.py:404 msgid "" "Third step is to select a solder paste dispensing geometry,\n" "and then generate a CNCJob object.\n" @@ -16164,11 +17296,11 @@ msgstr "" "first you need to generate a geometry with those new params,\n" "and only after that you can generate an updated CNCJob." -#: flatcamTools/ToolSolderPaste.py:421 +#: flatcamTools/ToolSolderPaste.py:425 msgid "CNC Result" msgstr "CNC Result" -#: flatcamTools/ToolSolderPaste.py:423 +#: flatcamTools/ToolSolderPaste.py:427 msgid "" "CNCJob Solder paste object.\n" "In order to enable the GCode save section,\n" @@ -16180,11 +17312,11 @@ msgstr "" "the name of the object has to end in:\n" "'_solderpaste' as a protection." -#: flatcamTools/ToolSolderPaste.py:433 +#: flatcamTools/ToolSolderPaste.py:437 msgid "View GCode" msgstr "View GCode" -#: flatcamTools/ToolSolderPaste.py:435 +#: flatcamTools/ToolSolderPaste.py:439 msgid "" "View the generated GCode for Solder Paste dispensing\n" "on PCB pads." @@ -16192,11 +17324,11 @@ msgstr "" "View the generated GCode for Solder Paste dispensing\n" "on PCB pads." -#: flatcamTools/ToolSolderPaste.py:445 +#: flatcamTools/ToolSolderPaste.py:449 msgid "Save GCode" msgstr "Save GCode" -#: flatcamTools/ToolSolderPaste.py:447 +#: flatcamTools/ToolSolderPaste.py:451 msgid "" "Save the generated GCode for Solder Paste dispensing\n" "on PCB pads, to a file." @@ -16204,11 +17336,11 @@ msgstr "" "Save the generated GCode for Solder Paste dispensing\n" "on PCB pads, to a file." -#: flatcamTools/ToolSolderPaste.py:457 +#: flatcamTools/ToolSolderPaste.py:461 msgid "STEP 4" msgstr "STEP 4" -#: flatcamTools/ToolSolderPaste.py:459 +#: flatcamTools/ToolSolderPaste.py:463 msgid "" "Fourth step (and last) is to select a CNCJob made from \n" "a solder paste dispensing geometry, and then view/save it's GCode." @@ -16216,86 +17348,82 @@ msgstr "" "Fourth step (and last) is to select a CNCJob made from \n" "a solder paste dispensing geometry, and then view/save it's GCode." -#: flatcamTools/ToolSolderPaste.py:917 -msgid "Adding Nozzle tool cancelled. Tool already in Tool Table." -msgstr "Adding Nozzle tool cancelled. Tool already in Tool Table." - -#: flatcamTools/ToolSolderPaste.py:923 +#: flatcamTools/ToolSolderPaste.py:922 msgid "New Nozzle tool added to Tool Table." msgstr "New Nozzle tool added to Tool Table." -#: flatcamTools/ToolSolderPaste.py:966 +#: flatcamTools/ToolSolderPaste.py:965 msgid "Nozzle tool from Tool Table was edited." msgstr "Nozzle tool from Tool Table was edited." -#: flatcamTools/ToolSolderPaste.py:1024 +#: flatcamTools/ToolSolderPaste.py:1023 msgid "Delete failed. Select a Nozzle tool to delete." msgstr "Delete failed. Select a Nozzle tool to delete." -#: flatcamTools/ToolSolderPaste.py:1030 +#: flatcamTools/ToolSolderPaste.py:1029 msgid "Nozzle tool(s) deleted from Tool Table." msgstr "Nozzle tool(s) deleted from Tool Table." -#: flatcamTools/ToolSolderPaste.py:1086 +#: flatcamTools/ToolSolderPaste.py:1085 msgid "No SolderPaste mask Gerber object loaded." msgstr "No SolderPaste mask Gerber object loaded." -#: flatcamTools/ToolSolderPaste.py:1104 +#: flatcamTools/ToolSolderPaste.py:1103 msgid "Creating Solder Paste dispensing geometry." msgstr "Creating Solder Paste dispensing geometry." -#: flatcamTools/ToolSolderPaste.py:1117 +#: flatcamTools/ToolSolderPaste.py:1116 msgid "No Nozzle tools in the tool table." msgstr "No Nozzle tools in the tool table." -#: flatcamTools/ToolSolderPaste.py:1244 +#: flatcamTools/ToolSolderPaste.py:1242 msgid "Cancelled. Empty file, it has no geometry..." msgstr "Cancelled. Empty file, it has no geometry..." -#: flatcamTools/ToolSolderPaste.py:1248 +#: flatcamTools/ToolSolderPaste.py:1245 msgid "Solder Paste geometry generated successfully" msgstr "Solder Paste geometry generated successfully" -#: flatcamTools/ToolSolderPaste.py:1255 +#: flatcamTools/ToolSolderPaste.py:1252 msgid "Some or all pads have no solder due of inadequate nozzle diameters..." msgstr "Some or all pads have no solder due of inadequate nozzle diameters..." -#: flatcamTools/ToolSolderPaste.py:1269 +#: flatcamTools/ToolSolderPaste.py:1266 msgid "Generating Solder Paste dispensing geometry..." msgstr "Generating Solder Paste dispensing geometry..." -#: flatcamTools/ToolSolderPaste.py:1289 +#: flatcamTools/ToolSolderPaste.py:1286 msgid "There is no Geometry object available." msgstr "There is no Geometry object available." -#: flatcamTools/ToolSolderPaste.py:1294 +#: flatcamTools/ToolSolderPaste.py:1291 msgid "This Geometry can't be processed. NOT a solder_paste_tool geometry." msgstr "This Geometry can't be processed. NOT a solder_paste_tool geometry." -#: flatcamTools/ToolSolderPaste.py:1401 +#: flatcamTools/ToolSolderPaste.py:1392 msgid "ToolSolderPaste CNCjob created" msgstr "ToolSolderPaste CNCjob created" -#: flatcamTools/ToolSolderPaste.py:1422 +#: flatcamTools/ToolSolderPaste.py:1411 msgid "SP GCode Editor" msgstr "SP GCode Editor" -#: flatcamTools/ToolSolderPaste.py:1434 flatcamTools/ToolSolderPaste.py:1439 -#: flatcamTools/ToolSolderPaste.py:1494 +#: flatcamTools/ToolSolderPaste.py:1423 flatcamTools/ToolSolderPaste.py:1428 +#: flatcamTools/ToolSolderPaste.py:1483 msgid "" "This CNCJob object can't be processed. NOT a solder_paste_tool CNCJob object." msgstr "" "This CNCJob object can't be processed. NOT a solder_paste_tool CNCJob object." -#: flatcamTools/ToolSolderPaste.py:1464 +#: flatcamTools/ToolSolderPaste.py:1453 msgid "No Gcode in the object" msgstr "No Gcode in the object" -#: flatcamTools/ToolSolderPaste.py:1504 +#: flatcamTools/ToolSolderPaste.py:1493 msgid "Export GCode ..." msgstr "Export GCode ..." -#: flatcamTools/ToolSolderPaste.py:1552 +#: flatcamTools/ToolSolderPaste.py:1541 msgid "Solder paste dispenser GCode file saved to" msgstr "Solder paste dispenser GCode file saved to" @@ -16303,7 +17431,7 @@ msgstr "Solder paste dispenser GCode file saved to" msgid "Gerber Objects" msgstr "Gerber Objects" -#: flatcamTools/ToolSub.py:76 +#: flatcamTools/ToolSub.py:78 msgid "" "Gerber object from which to subtract\n" "the subtractor Gerber object." @@ -16311,11 +17439,11 @@ msgstr "" "Gerber object from which to subtract\n" "the subtractor Gerber object." -#: flatcamTools/ToolSub.py:88 flatcamTools/ToolSub.py:140 +#: flatcamTools/ToolSub.py:91 flatcamTools/ToolSub.py:146 msgid "Subtractor" msgstr "Subtractor" -#: flatcamTools/ToolSub.py:90 +#: flatcamTools/ToolSub.py:93 msgid "" "Gerber object that will be subtracted\n" "from the target Gerber object." @@ -16323,11 +17451,11 @@ msgstr "" "Gerber object that will be subtracted\n" "from the target Gerber object." -#: flatcamTools/ToolSub.py:97 +#: flatcamTools/ToolSub.py:100 msgid "Substract Gerber" msgstr "Substract Gerber" -#: flatcamTools/ToolSub.py:99 +#: flatcamTools/ToolSub.py:102 msgid "" "Will remove the area occupied by the subtractor\n" "Gerber from the Target Gerber.\n" @@ -16339,11 +17467,11 @@ msgstr "" "Can be used to remove the overlapping silkscreen\n" "over the soldermask." -#: flatcamTools/ToolSub.py:117 +#: flatcamTools/ToolSub.py:120 msgid "Geometry Objects" msgstr "Geometry Objects" -#: flatcamTools/ToolSub.py:128 +#: flatcamTools/ToolSub.py:133 msgid "" "Geometry object from which to subtract\n" "the subtractor Geometry object." @@ -16351,7 +17479,7 @@ msgstr "" "Geometry object from which to subtract\n" "the subtractor Geometry object." -#: flatcamTools/ToolSub.py:142 +#: flatcamTools/ToolSub.py:148 msgid "" "Geometry object that will be subtracted\n" "from the target Geometry object." @@ -16359,17 +17487,17 @@ msgstr "" "Geometry object that will be subtracted\n" "from the target Geometry object." -#: flatcamTools/ToolSub.py:150 +#: flatcamTools/ToolSub.py:156 msgid "" "Checking this will close the paths cut by the Geometry subtractor object." msgstr "" "Checking this will close the paths cut by the Geometry subtractor object." -#: flatcamTools/ToolSub.py:153 +#: flatcamTools/ToolSub.py:159 msgid "Subtract Geometry" msgstr "Subtract Geometry" -#: flatcamTools/ToolSub.py:155 +#: flatcamTools/ToolSub.py:161 msgid "" "Will remove the area occupied by the subtractor\n" "Geometry from the Target Geometry." @@ -16377,56 +17505,56 @@ msgstr "" "Will remove the area occupied by the subtractor\n" "Geometry from the Target Geometry." -#: flatcamTools/ToolSub.py:262 +#: flatcamTools/ToolSub.py:263 msgid "Sub Tool" msgstr "Sub Tool" -#: flatcamTools/ToolSub.py:278 flatcamTools/ToolSub.py:483 +#: flatcamTools/ToolSub.py:284 flatcamTools/ToolSub.py:489 msgid "No Target object loaded." msgstr "No Target object loaded." -#: flatcamTools/ToolSub.py:281 +#: flatcamTools/ToolSub.py:287 msgid "Loading geometry from Gerber objects." msgstr "Loading geometry from Gerber objects." -#: flatcamTools/ToolSub.py:293 flatcamTools/ToolSub.py:498 +#: flatcamTools/ToolSub.py:299 flatcamTools/ToolSub.py:504 msgid "No Subtractor object loaded." msgstr "No Subtractor object loaded." -#: flatcamTools/ToolSub.py:325 +#: flatcamTools/ToolSub.py:331 msgid "Processing geometry from Subtractor Gerber object." msgstr "Processing geometry from Subtractor Gerber object." -#: flatcamTools/ToolSub.py:346 +#: flatcamTools/ToolSub.py:352 msgid "Parsing geometry for aperture" msgstr "Parsing geometry for aperture" -#: flatcamTools/ToolSub.py:407 +#: flatcamTools/ToolSub.py:413 msgid "Finished parsing geometry for aperture" msgstr "Finished parsing geometry for aperture" -#: flatcamTools/ToolSub.py:452 flatcamTools/ToolSub.py:655 +#: flatcamTools/ToolSub.py:458 flatcamTools/ToolSub.py:661 msgid "Generating new object ..." msgstr "Generating new object ..." -#: flatcamTools/ToolSub.py:456 flatcamTools/ToolSub.py:659 -#: flatcamTools/ToolSub.py:740 +#: flatcamTools/ToolSub.py:462 flatcamTools/ToolSub.py:665 +#: flatcamTools/ToolSub.py:746 msgid "Generating new object failed." msgstr "Generating new object failed." -#: flatcamTools/ToolSub.py:461 flatcamTools/ToolSub.py:665 +#: flatcamTools/ToolSub.py:467 flatcamTools/ToolSub.py:671 msgid "Created" msgstr "Created" -#: flatcamTools/ToolSub.py:512 +#: flatcamTools/ToolSub.py:518 msgid "Currently, the Subtractor geometry cannot be of type Multigeo." msgstr "Currently, the Subtractor geometry cannot be of type Multigeo." -#: flatcamTools/ToolSub.py:557 +#: flatcamTools/ToolSub.py:563 msgid "Parsing solid_geometry ..." msgstr "Parsing solid_geometry ..." -#: flatcamTools/ToolSub.py:559 +#: flatcamTools/ToolSub.py:565 msgid "Parsing solid_geometry for tool" msgstr "Parsing solid_geometry for tool" @@ -16434,7 +17562,7 @@ msgstr "Parsing solid_geometry for tool" msgid "Object Transform" msgstr "Object Transform" -#: flatcamTools/ToolTransform.py:82 +#: flatcamTools/ToolTransform.py:79 msgid "" "Rotate the selected object(s).\n" "The point of reference is the middle of\n" @@ -16444,7 +17572,7 @@ msgstr "" "The point of reference is the middle of\n" "the bounding box for all selected objects." -#: flatcamTools/ToolTransform.py:100 flatcamTools/ToolTransform.py:122 +#: flatcamTools/ToolTransform.py:100 flatcamTools/ToolTransform.py:121 msgid "" "Angle for Skew action, in degrees.\n" "Float number between -360 and 360." @@ -16452,7 +17580,7 @@ msgstr "" "Angle for Skew action, in degrees.\n" "Float number between -360 and 360." -#: flatcamTools/ToolTransform.py:111 flatcamTools/ToolTransform.py:133 +#: flatcamTools/ToolTransform.py:110 flatcamTools/ToolTransform.py:131 msgid "" "Skew/shear the selected object(s).\n" "The point of reference is the middle of\n" @@ -16462,7 +17590,7 @@ msgstr "" "The point of reference is the middle of\n" "the bounding box for all selected objects." -#: flatcamTools/ToolTransform.py:160 flatcamTools/ToolTransform.py:181 +#: flatcamTools/ToolTransform.py:160 flatcamTools/ToolTransform.py:180 msgid "" "Scale the selected object(s).\n" "The point of reference depends on \n" @@ -16472,7 +17600,7 @@ msgstr "" "The point of reference depends on \n" "the Scale reference checkbox state." -#: flatcamTools/ToolTransform.py:229 flatcamTools/ToolTransform.py:250 +#: flatcamTools/ToolTransform.py:229 flatcamTools/ToolTransform.py:249 msgid "" "Offset the selected object(s).\n" "The point of reference is the middle of\n" @@ -16482,188 +17610,591 @@ msgstr "" "The point of reference is the middle of\n" "the bounding box for all selected objects.\n" -#: flatcamTools/ToolTransform.py:268 flatcamTools/ToolTransform.py:274 +#: flatcamTools/ToolTransform.py:269 flatcamTools/ToolTransform.py:274 msgid "Flip the selected object(s) over the X axis." msgstr "Flip the selected object(s) over the X axis." -#: flatcamTools/ToolTransform.py:299 +#: flatcamTools/ToolTransform.py:298 msgid "Ref. Point" msgstr "Ref. Point" -#: flatcamTools/ToolTransform.py:351 +#: flatcamTools/ToolTransform.py:349 +#| msgid "" +#| "Create the buffer effect on each geometry,\n" +#| "element from the selected object." msgid "" "Create the buffer effect on each geometry,\n" -"element from the selected object." +"element from the selected object, using the distance." msgstr "" "Create the buffer effect on each geometry,\n" -"element from the selected object." +"element from the selected object, using the distance." -#: flatcamTools/ToolTransform.py:498 +#: flatcamTools/ToolTransform.py:375 +#| msgid "" +#| "Create the buffer effect on each geometry,\n" +#| "element from the selected object." +msgid "" +"Create the buffer effect on each geometry,\n" +"element from the selected object, using the factor." +msgstr "" +"Create the buffer effect on each geometry,\n" +"element from the selected object, using the factor." + +#: flatcamTools/ToolTransform.py:480 +#| msgid "Buffer" +msgid "Buffer D" +msgstr "Buffer D" + +#: flatcamTools/ToolTransform.py:481 +#| msgid "Buffer" +msgid "Buffer F" +msgstr "Buffer F" + +#: flatcamTools/ToolTransform.py:558 msgid "Rotate transformation can not be done for a value of 0." msgstr "Rotate transformation can not be done for a value of 0." -#: flatcamTools/ToolTransform.py:537 flatcamTools/ToolTransform.py:560 +#: flatcamTools/ToolTransform.py:597 flatcamTools/ToolTransform.py:620 msgid "Scale transformation can not be done for a factor of 0 or 1." msgstr "Scale transformation can not be done for a factor of 0 or 1." -#: flatcamTools/ToolTransform.py:575 flatcamTools/ToolTransform.py:585 +#: flatcamTools/ToolTransform.py:635 flatcamTools/ToolTransform.py:645 msgid "Offset transformation can not be done for a value of 0." msgstr "Offset transformation can not be done for a value of 0." -#: flatcamTools/ToolTransform.py:608 +#: flatcamTools/ToolTransform.py:677 msgid "No object selected. Please Select an object to rotate!" msgstr "No object selected. Please Select an object to rotate!" -#: flatcamTools/ToolTransform.py:636 +#: flatcamTools/ToolTransform.py:703 msgid "CNCJob objects can't be rotated." msgstr "CNCJob objects can't be rotated." -#: flatcamTools/ToolTransform.py:644 +#: flatcamTools/ToolTransform.py:711 msgid "Rotate done" msgstr "Rotate done" -#: flatcamTools/ToolTransform.py:649 flatcamTools/ToolTransform.py:724 -#: flatcamTools/ToolTransform.py:779 flatcamTools/ToolTransform.py:838 -#: flatcamTools/ToolTransform.py:874 flatcamTools/ToolTransform.py:910 +#: flatcamTools/ToolTransform.py:714 flatcamTools/ToolTransform.py:784 +#: flatcamTools/ToolTransform.py:834 flatcamTools/ToolTransform.py:890 +#: flatcamTools/ToolTransform.py:922 flatcamTools/ToolTransform.py:958 msgid "Due of" msgstr "Due of" -#: flatcamTools/ToolTransform.py:649 flatcamTools/ToolTransform.py:724 -#: flatcamTools/ToolTransform.py:779 flatcamTools/ToolTransform.py:838 -#: flatcamTools/ToolTransform.py:874 flatcamTools/ToolTransform.py:910 +#: flatcamTools/ToolTransform.py:714 flatcamTools/ToolTransform.py:784 +#: flatcamTools/ToolTransform.py:834 flatcamTools/ToolTransform.py:890 +#: flatcamTools/ToolTransform.py:922 flatcamTools/ToolTransform.py:958 msgid "action was not executed." msgstr "action was not executed." -#: flatcamTools/ToolTransform.py:661 +#: flatcamTools/ToolTransform.py:726 msgid "No object selected. Please Select an object to flip" msgstr "No object selected. Please Select an object to flip" -#: flatcamTools/ToolTransform.py:696 +#: flatcamTools/ToolTransform.py:759 msgid "CNCJob objects can't be mirrored/flipped." msgstr "CNCJob objects can't be mirrored/flipped." -#: flatcamTools/ToolTransform.py:734 +#: flatcamTools/ToolTransform.py:794 msgid "Skew transformation can not be done for 0, 90 and 180 degrees." msgstr "Skew transformation can not be done for 0, 90 and 180 degrees." -#: flatcamTools/ToolTransform.py:739 +#: flatcamTools/ToolTransform.py:799 msgid "No object selected. Please Select an object to shear/skew!" msgstr "No object selected. Please Select an object to shear/skew!" -#: flatcamTools/ToolTransform.py:761 +#: flatcamTools/ToolTransform.py:819 msgid "CNCJob objects can't be skewed." msgstr "CNCJob objects can't be skewed." -#: flatcamTools/ToolTransform.py:774 +#: flatcamTools/ToolTransform.py:831 msgid "Skew on the" msgstr "Skew on the" -#: flatcamTools/ToolTransform.py:774 flatcamTools/ToolTransform.py:834 -#: flatcamTools/ToolTransform.py:869 +#: flatcamTools/ToolTransform.py:831 flatcamTools/ToolTransform.py:887 +#: flatcamTools/ToolTransform.py:919 msgid "axis done" msgstr "axis done" -#: flatcamTools/ToolTransform.py:791 +#: flatcamTools/ToolTransform.py:846 msgid "No object selected. Please Select an object to scale!" msgstr "No object selected. Please Select an object to scale!" -#: flatcamTools/ToolTransform.py:824 +#: flatcamTools/ToolTransform.py:877 msgid "CNCJob objects can't be scaled." msgstr "CNCJob objects can't be scaled." -#: flatcamTools/ToolTransform.py:834 +#: flatcamTools/ToolTransform.py:887 msgid "Scale on the" msgstr "Scale on the" -#: flatcamTools/ToolTransform.py:846 +#: flatcamTools/ToolTransform.py:898 msgid "No object selected. Please Select an object to offset!" msgstr "No object selected. Please Select an object to offset!" -#: flatcamTools/ToolTransform.py:855 +#: flatcamTools/ToolTransform.py:905 msgid "CNCJob objects can't be offset." msgstr "CNCJob objects can't be offset." -#: flatcamTools/ToolTransform.py:869 +#: flatcamTools/ToolTransform.py:919 msgid "Offset on the" msgstr "Offset on the" -#: flatcamTools/ToolTransform.py:881 +#: flatcamTools/ToolTransform.py:929 msgid "No object selected. Please Select an object to buffer!" msgstr "No object selected. Please Select an object to buffer!" -#: flatcamTools/ToolTransform.py:884 +#: flatcamTools/ToolTransform.py:932 msgid "Applying Buffer" msgstr "Applying Buffer" -#: flatcamTools/ToolTransform.py:888 +#: flatcamTools/ToolTransform.py:936 msgid "CNCJob objects can't be buffered." msgstr "CNCJob objects can't be buffered." -#: flatcamTools/ToolTransform.py:905 +#: flatcamTools/ToolTransform.py:953 msgid "Buffer done" msgstr "Buffer done" -#: tclCommands/TclCommandBbox.py:74 tclCommands/TclCommandNregions.py:73 +#: tclCommands/TclCommandBbox.py:76 tclCommands/TclCommandNregions.py:75 msgid "Expected FlatCAMGerber or FlatCAMGeometry, got" msgstr "Expected FlatCAMGerber or FlatCAMGeometry, got" -#: tclCommands/TclCommandBounds.py:64 tclCommands/TclCommandBounds.py:68 +#: tclCommands/TclCommandBounds.py:67 tclCommands/TclCommandBounds.py:71 msgid "Expected a list of objects names separated by comma. Got" msgstr "Expected a list of objects names separated by comma. Got" -#: tclCommands/TclCommandBounds.py:79 +#: tclCommands/TclCommandBounds.py:82 msgid "TclCommand Bounds done." msgstr "TclCommand Bounds done." -#: tclCommands/TclCommandCopperClear.py:242 tclCommands/TclCommandPaint.py:240 -msgid "Expected -box ." -msgstr "Expected -box ." - -#: tclCommands/TclCommandCopperClear.py:251 tclCommands/TclCommandPaint.py:249 -#: tclCommands/TclCommandScale.py:75 +#: tclCommands/TclCommandCopperClear.py:256 tclCommands/TclCommandPaint.py:261 +#: tclCommands/TclCommandScale.py:81 msgid "Could not retrieve box object" msgstr "Could not retrieve box object" -#: tclCommands/TclCommandCopperClear.py:273 -msgid "" -"None of the following args: 'ref', 'all' were found or none was set to 1.\n" -"Copper clearing failed." -msgstr "" -"None of the following args: 'ref', 'all' were found or none was set to 1.\n" -"Copper clearing failed." +#: tclCommands/TclCommandCopperClear.py:279 +#| msgid "Expected -box ." +msgid "Expected either -box or -all." +msgstr "Expected either -box or -all." -#: tclCommands/TclCommandPaint.py:217 +#: tclCommands/TclCommandGeoCutout.py:148 +#| msgid "Number of gaps value is missing. Add it and retry." +msgid "" +"The name of the object for which cutout is done is missing. Add it and retry." +msgstr "" +"The name of the object for which cutout is done is missing. Add it and retry." + +#: tclCommands/TclCommandGeoCutout.py:190 +#| msgid "" +#| "Gaps value can be only one of: 'None', 'lr', 'tb', '2lr', '2tb', 4 or 8. " +#| "Fill in a correct value and retry. " +msgid "Gaps value can be only one of: 'lr', 'tb', '2lr', '2tb', 4 or 8." +msgstr "Gaps value can be only one of: 'lr', 'tb', '2lr', '2tb', 4 or 8." + +#: tclCommands/TclCommandGeoCutout.py:302 +#: tclCommands/TclCommandGeoCutout.py:360 +#| msgid "Any form CutOut operation finished." +msgid "Any-form Cutout operation finished." +msgstr "Any-form Cutout operation finished." + +#: tclCommands/TclCommandGeoCutout.py:366 +#| msgid "The reference object type is not supported." +msgid "Cancelled. Object type is not supported." +msgstr "Cancelled. Object type is not supported." + +#: tclCommands/TclCommandHelp.py:74 +#| msgid "Available commands:\n" +msgid "Available commands:" +msgstr "Available commands:" + +#: tclCommands/TclCommandHelp.py:112 +#| msgid "" +#| "\n" +#| "\n" +#| "Type help for usage.\n" +#| " Example: help open_gerber" +msgid "Type help for usage." +msgstr "Type help for usage." + +#: tclCommands/TclCommandHelp.py:112 +msgid "Example: help open_gerber" +msgstr "Example: help open_gerber" + +#: tclCommands/TclCommandPaint.py:229 msgid "Expected -x and -y ." msgstr "Expected -x and -y ." -#: tclCommands/TclCommandPaint.py:268 +#: tclCommands/TclCommandPaint.py:254 +msgid "Expected -box ." +msgstr "Expected -box ." + +#: tclCommands/TclCommandPaint.py:279 +#| msgid "" +#| "There was none of the following args: 'ref', 'single', 'all'.\n" +#| "Paint failed." msgid "" -"There was none of the following args: 'ref', 'single', 'all'.\n" +"None of the following args: 'box', 'single', 'all' were used.\n" "Paint failed." msgstr "" -"There was none of the following args: 'ref', 'single', 'all'.\n" +"None of the following args: 'box', 'single', 'all' were used.\n" "Paint failed." -#: tclCommands/TclCommandScale.py:95 -msgid "Expected -origin or -origin or -origin
." -msgstr "Expected -origin or -origin or -origin
." +#: tclCommands/TclCommandScale.py:106 +#| msgid "" +#| "Expected -origin or -origin or -origin
." +msgid "" +"Expected -origin or -origin or -origin
or - " +"origin 3.0,4.2." +msgstr "" +"Expected -origin or -origin or -origin
or - " +"origin 3.0,4.2." -#: tclCommands/TclCommandScale.py:104 +#: tclCommands/TclCommandScale.py:119 msgid "Expected -x -y ." msgstr "Expected -x -y ." -#: tclCommands/TclCommandSetOrigin.py:91 +#: tclCommands/TclCommandSetOrigin.py:95 msgid "Expected a pair of (x, y) coordinates. Got" msgstr "Expected a pair of (x, y) coordinates. Got" -#: tclCommands/TclCommandSetOrigin.py:98 +#: tclCommands/TclCommandSetOrigin.py:102 msgid "Origin set by offsetting all loaded objects with " msgstr "Origin set by offsetting all loaded objects with " -#: tclCommands/TclCommandSubtractRectangle.py:58 +#: tclCommands/TclCommandSubtractRectangle.py:62 msgid "No Geometry name in args. Provide a name and try again." msgstr "No Geometry name in args. Provide a name and try again." +#~ msgid "Executing Tcl Script ..." +#~ msgstr "Executing Tcl Script ..." + +#~ msgid "Open cancelled." +#~ msgstr "Open cancelled." + +#~ msgid "Preferences default restore was cancelled." +#~ msgstr "Preferences default restore was cancelled." + +#~ msgid "FlatCAM preferences import cancelled." +#~ msgstr "FlatCAM preferences import cancelled." + +#~ msgid "FlatCAM preferences export cancelled." +#~ msgstr "FlatCAM preferences export cancelled." + +#~ msgid "Multigeo. Geometry merging finished" +#~ msgstr "Multigeo. Geometry merging finished" + +#~ msgid "Units conversion cancelled." +#~ msgstr "Units conversion cancelled." + +#~ msgid "Open Gerber cancelled." +#~ msgstr "Open Gerber cancelled." + +#~ msgid " Open Excellon cancelled." +#~ msgstr " Open Excellon cancelled." + +#~ msgid "Open G-Code cancelled." +#~ msgstr "Open G-Code cancelled." + +#~ msgid "Open Project cancelled." +#~ msgstr "Open Project cancelled." + +#~ msgid "Open HPGL2 file cancelled." +#~ msgstr "Open HPGL2 file cancelled." + +#~ msgid "Open Config cancelled." +#~ msgstr "Open Config cancelled." + +#~ msgid " Export SVG cancelled." +#~ msgstr " Export SVG cancelled." + +#~ msgid "Export PNG cancelled." +#~ msgstr "Export PNG cancelled." + +#~ msgid "No object selected. Please select an Gerber object to export." +#~ msgstr "No object selected. Please select an Gerber object to export." + +#~ msgid "Save Gerber source file cancelled." +#~ msgstr "Save Gerber source file cancelled." + +#~ msgid "No object selected. Please select an Script object to export." +#~ msgstr "No object selected. Please select an Script object to export." + +#~ msgid "Save Script source file cancelled." +#~ msgstr "Save Script source file cancelled." + +#~ msgid "No object selected. Please select an Document object to export." +#~ msgstr "No object selected. Please select an Document object to export." + +#~ msgid "Save Document source file cancelled." +#~ msgstr "Save Document source file cancelled." + +#~ msgid "No object selected. Please select an Excellon object to export." +#~ msgstr "No object selected. Please select an Excellon object to export." + +#~ msgid "Saving Excellon source file cancelled." +#~ msgstr "Saving Excellon source file cancelled." + +#~ msgid "No object selected. Please Select an Excellon object to export." +#~ msgstr "No object selected. Please Select an Excellon object to export." + +#~ msgid "Export Excellon cancelled." +#~ msgstr "Export Excellon cancelled." + +#~ msgid "No object selected. Please Select an Gerber object to export." +#~ msgstr "No object selected. Please Select an Gerber object to export." + +#~ msgid "Export Gerber cancelled." +#~ msgstr "Export Gerber cancelled." + +#~ msgid "Export DXF cancelled." +#~ msgstr "Export DXF cancelled." + +#~ msgid "Open SVG cancelled." +#~ msgstr "Open SVG cancelled." + +#~ msgid "Open DXF cancelled." +#~ msgstr "Open DXF cancelled." + +#~ msgid "Open TCL script cancelled." +#~ msgstr "Open TCL script cancelled." + +#~ msgid "Run TCL script cancelled." +#~ msgstr "Run TCL script cancelled." + +#~ msgid "Save Project cancelled." +#~ msgstr "Save Project cancelled." + +#~ msgid "Save Object PDF cancelled." +#~ msgstr "Save Object PDF cancelled." + +#~ msgid "Shows list of commands." +#~ msgstr "Shows list of commands." + +#~ msgid "FlatCAM bookmarks export cancelled." +#~ msgstr "FlatCAM bookmarks export cancelled." + +#~ msgid "FlatCAM bookmarks import cancelled." +#~ msgstr "FlatCAM bookmarks import cancelled." + +#~ msgid "FlatCAM Tools DB export cancelled." +#~ msgstr "FlatCAM Tools DB export cancelled." + +#~ msgid "FlatCAM Tools DB import cancelled." +#~ msgstr "FlatCAM Tools DB import cancelled." + +#~ msgid "" +#~ "Wrong value format for self.defaults[\"z_pdepth\"] or self." +#~ "options[\"z_pdepth\"]" +#~ msgstr "" +#~ "Wrong value format for self.defaults[\"z_pdepth\"] or self." +#~ "options[\"z_pdepth\"]" + +#~ msgid "" +#~ "Wrong value format for self.defaults[\"feedrate_probe\"] or self." +#~ "options[\"feedrate_probe\"]" +#~ msgstr "" +#~ "Wrong value format for self.defaults[\"feedrate_probe\"] or self." +#~ "options[\"feedrate_probe\"]" + +#~ msgid "Starting G-Code..." +#~ msgstr "Starting G-Code..." + +#~ msgid "" +#~ "Algorithm to paint the polygon:
Standard: Fixed step inwards." +#~ "
Seed-based: Outwards from seed." +#~ msgstr "" +#~ "Algorithm to paint the polygon:
Standard: Fixed step inwards." +#~ "
Seed-based: Outwards from seed." + +#~ msgid "Seed-based" +#~ msgstr "Seed-based" + +#~ msgid "Straight lines" +#~ msgstr "Straight lines" + +#~ msgid "Paint cancelled. No shape selected." +#~ msgstr "Paint cancelled. No shape selected." + +#~ msgid "Transformation cancelled. No shape selected." +#~ msgstr "Transformation cancelled. No shape selected." + +#~ msgid "Buffer cancelled. No shape selected." +#~ msgstr "Buffer cancelled. No shape selected." + +#~ msgid "Export Code cancelled." +#~ msgstr "Export Code cancelled." + +#~ msgid "&Save Project ..." +#~ msgstr "&Save Project ..." + +#~ msgid "Save Project C&opy ..." +#~ msgstr "Save Project C&opy ..." + +#~ msgid "Change the size of the object." +#~ msgstr "Change the size of the object." + +#~ msgid "Change the position of this object." +#~ msgstr "Change the position of this object." + +#~ msgid "Vector" +#~ msgstr "Vector" + +#~ msgid "" +#~ "Create a CNC Job object\n" +#~ "for this drill object." +#~ msgstr "" +#~ "Create a CNC Job object\n" +#~ "for this drill object." + +#~ msgid "" +#~ "Choose what to use for GCode generation:\n" +#~ "'Drills', 'Slots' or 'Both'.\n" +#~ "When choosing 'Slots' or 'Both', slots will be\n" +#~ "converted to a series of drills." +#~ msgstr "" +#~ "Choose what to use for GCode generation:\n" +#~ "'Drills', 'Slots' or 'Both'.\n" +#~ "When choosing 'Slots' or 'Both', slots will be\n" +#~ "converted to a series of drills." + +#~ msgid "Generate the CNC Job." +#~ msgstr "Generate the CNC Job." + +#~ msgid "Add Tool from DataBase" +#~ msgstr "Add Tool from DataBase" + +#~ msgid "Select a theme for FlatCAM." +#~ msgstr "Select a theme for FlatCAM." + +#~ msgid "Conv." +#~ msgstr "Conv." + +#~ msgid "Diameters of the cutting tools, separated by ','" +#~ msgstr "Diameters of the cutting tools, separated by ','" + +#~ msgid "Tools dia" +#~ msgstr "Tools dia" + +#~ msgid "The new tool diameter (cut width) to add in the tool table." +#~ msgstr "The new tool diameter (cut width) to add in the tool table." + +#~ msgid "" +#~ "Algorithm for non-copper clearing:
Standard: Fixed step inwards." +#~ "
Seed-based: Outwards from seed.
Line-based: Parallel " +#~ "lines." +#~ msgstr "" +#~ "Algorithm for non-copper clearing:
Standard: Fixed step inwards." +#~ "
Seed-based: Outwards from seed.
Line-based: Parallel " +#~ "lines." + +#~ msgid "Area" +#~ msgstr "Area" + +#~ msgid "Ref" +#~ msgstr "Ref" + +#~ msgid "" +#~ "- 'Itself' - the non copper clearing extent\n" +#~ "is based on the object that is copper cleared.\n" +#~ " - 'Area Selection' - left mouse click to start selection of the area to " +#~ "be painted.\n" +#~ "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple " +#~ "areas.\n" +#~ "- 'Reference Object' - will do non copper clearing within the area\n" +#~ "specified by another object." +#~ msgstr "" +#~ "- 'Itself' - the non copper clearing extent\n" +#~ "is based on the object that is copper cleared.\n" +#~ " - 'Area Selection' - left mouse click to start selection of the area to " +#~ "be painted.\n" +#~ "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple " +#~ "areas.\n" +#~ "- 'Reference Object' - will do non copper clearing within the area\n" +#~ "specified by another object." + +#~ msgid "Sel" +#~ msgstr "Sel" + +#~ msgid "Diameters of nozzle tools, separated by ','" +#~ msgstr "Diameters of nozzle tools, separated by ','" + +#~ msgid "Reference Gerber" +#~ msgstr "Reference Gerber" + +#~ msgid "Reference Excellon" +#~ msgstr "Reference Excellon" + +#~ msgid "Reference Geometry" +#~ msgstr "Reference Geometry" + +#~ msgid "Point/Box Reference" +#~ msgstr "Point/Box Reference" + +#~ msgid "" +#~ "If 'Point' is selected above it store the coordinates (x, y) through " +#~ "which\n" +#~ "the mirroring axis passes.\n" +#~ "If 'Box' is selected above, select here a FlatCAM object (Gerber, Exc or " +#~ "Geo).\n" +#~ "Through the center of this object pass the mirroring axis selected above." +#~ msgstr "" +#~ "If 'Point' is selected above it store the coordinates (x, y) through " +#~ "which\n" +#~ "the mirroring axis passes.\n" +#~ "If 'Box' is selected above, select here a FlatCAM object (Gerber, Exc or " +#~ "Geo).\n" +#~ "Through the center of this object pass the mirroring axis selected above." + +#~ msgid "Alignment Drill Diameter" +#~ msgstr "Alignment Drill Diameter" + +#~ msgid "" +#~ "'Point' coordinates missing. Using Origin (0, 0) as mirroring reference." +#~ msgstr "" +#~ "'Point' coordinates missing. Using Origin (0, 0) as mirroring reference." + +#~ msgid "Export positive film cancelled." +#~ msgstr "Export positive film cancelled." + +#~ msgid "Export negative film cancelled." +#~ msgstr "Export negative film cancelled." + +#~ msgid "Move action cancelled." +#~ msgstr "Move action cancelled." + +#~ msgid "Diameter for the new tool." +#~ msgstr "Diameter for the new tool." + +#~ msgid "Create Paint Geometry" +#~ msgstr "Create Paint Geometry" + +#~ msgid "Paint Tool. Reading parameters." +#~ msgstr "Paint Tool. Reading parameters." + +#~ msgid "Normal painting area task started." +#~ msgstr "Normal painting area task started." + +#~ msgid "Paint Tool. Rest machining painting area task started." +#~ msgstr "Paint Tool. Rest machining painting area task started." + +#~ msgid "Properties Tool was not displayed. No object selected." +#~ msgstr "Properties Tool was not displayed. No object selected." + +#~ msgid " Export PNG cancelled." +#~ msgstr " Export PNG cancelled." + +#~ msgid "Adding Nozzle tool cancelled. Tool already in Tool Table." +#~ msgstr "Adding Nozzle tool cancelled. Tool already in Tool Table." + +#~ msgid "" +#~ "None of the following args: 'ref', 'all' were found or none was set to " +#~ "1.\n" +#~ "Copper clearing failed." +#~ msgstr "" +#~ "None of the following args: 'ref', 'all' were found or none was set to " +#~ "1.\n" +#~ "Copper clearing failed." + #~ msgid "PostProcessor" #~ msgstr "PostProcessor" @@ -16691,9 +18222,6 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ msgid "Optimization Time" #~ msgstr "Optimization Time" -#~ msgid "Defaults" -#~ msgstr "Defaults" - #~ msgid "Coordinates decimals" #~ msgstr "Coordinates decimals" @@ -16762,9 +18290,6 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ msgid "Wk. size" #~ msgstr "Wk. size" -#~ msgid "Plot Line" -#~ msgstr "Plot Line" - #~ msgid "Sel. Fill" #~ msgstr "Sel. Fill" @@ -16801,12 +18326,6 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ msgid "Project at StartUp" #~ msgstr "Project at StartUp" -#~ msgid "Project AutoHide" -#~ msgstr "Project AutoHide" - -#~ msgid "Enable ToolTips" -#~ msgstr "Enable ToolTips" - #~ msgid "Mouse Cursor" #~ msgstr "Mouse Cursor" @@ -16830,9 +18349,6 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ msgid "G-code does not have a units code: either G20 or G21" #~ msgstr "G-code does not have a units code: either G20 or G21" -#~ msgid "No shape selected. Select a shape to explode" -#~ msgstr "No shape selected. Select a shape to explode" - #, python-brace-format #~ msgid "" #~ "[selected] {kind} created/selected: {name}" @@ -17160,12 +18676,6 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ msgid "Geometry Reference Box Object" #~ msgstr "Geometry Reference Box Object" -#~ msgid "Single Polygon" -#~ msgstr "Single Polygon" - -#~ msgid "Painting polygon at location" -#~ msgstr "Painting polygon at location" - #~ msgid "{l_save}/FlatCAM_Bookmarks_{date}" #~ msgstr "{l_save}/FlatCAM_Bookmarks_{date}" @@ -17199,9 +18709,6 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ msgid "spindlesspeed = the value for the spindle speed" #~ msgstr "spindlesspeed = the value for the spindle speed" -#~ msgid "White" -#~ msgstr "White" - #~ msgid "Rotate Angle" #~ msgstr "Rotate Angle" @@ -17390,9 +18897,6 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ msgid "FILE ASSOCIATIONS" #~ msgstr "FILE ASSOCIATIONS" -#~ msgid "Advanced Param." -#~ msgstr "Advanced Param." - #~ msgid "MH" #~ msgstr "MH" @@ -19878,9 +21382,6 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ msgid "Save &Defaults" #~ msgstr "Save &Defaults" -#~ msgid "Line" -#~ msgstr "Line" - #~ msgid "Tool dia: " #~ msgstr "Tool dia: " diff --git a/locale/ro/LC_MESSAGES/strings.mo b/locale/ro/LC_MESSAGES/strings.mo index ed72fc105dff1f2d5d0c45c43c01657e47a96021..d076dab8957c6b24cfa114d3a987951dd738e635 100644 GIT binary patch delta 88301 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 O1f}l;Jat=?3I7XKZ>(Sd delta 75765 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 *YXr&ZvP5LIvkI)c!I9wIuUU`^HL)ul(O* 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 gI{#@f;help< to get started\n" -"\n" -msgstr "" -"Tastați >help< pentru a începe\n" -"\n" +#: FlatCAMApp.py:2565 flatcamGUI/GUIElements.py:2592 +msgid "Type >help< to get started" +msgstr "Tastați >help< pentru a începe" -#: FlatCAMApp.py:2627 FlatCAMApp.py:9020 +#: FlatCAMApp.py:2817 FlatCAMApp.py:9393 msgid "New Project - Not saved" msgstr "Proiect nou - Nu a fost salvat" -#: FlatCAMApp.py:2702 FlatCAMApp.py:9088 FlatCAMApp.py:9125 FlatCAMApp.py:9166 -#: FlatCAMApp.py:9237 FlatCAMApp.py:9991 FlatCAMApp.py:11174 -#: FlatCAMApp.py:11233 -msgid "" -"Canvas initialization started.\n" -"Canvas initialization finished in" -msgstr "" -"FlatCAM se inițializează ...\n" -"Initializarea spațiului de afisare s-a terminat in" - -#: FlatCAMApp.py:2704 -msgid "Executing Tcl Script ..." -msgstr "Rulează Tcl Script..." - -#: FlatCAMApp.py:2719 +#: FlatCAMApp.py:2913 msgid "" "Found old default preferences files. Please reboot the application to update." msgstr "" "Au fost găsite fișiere de preferințe implicite vechi. Vă rugăm să reporniți " "aplicația pentru a le actualiza." -#: FlatCAMApp.py:2763 ObjectCollection.py:90 flatcamTools/ToolImage.py:248 +#: FlatCAMApp.py:2964 FlatCAMApp.py:3884 FlatCAMApp.py:3933 FlatCAMApp.py:3988 +#: FlatCAMApp.py:4063 FlatCAMApp.py:6111 FlatCAMApp.py:9477 FlatCAMApp.py:9514 +#: FlatCAMApp.py:9556 FlatCAMApp.py:9585 FlatCAMApp.py:9625 FlatCAMApp.py:9650 +#: FlatCAMApp.py:9702 FlatCAMApp.py:9738 FlatCAMApp.py:9784 FlatCAMApp.py:9825 +#: FlatCAMApp.py:9866 FlatCAMApp.py:9907 FlatCAMApp.py:9948 FlatCAMApp.py:9992 +#: FlatCAMApp.py:10048 FlatCAMApp.py:10080 FlatCAMApp.py:10112 +#: FlatCAMApp.py:10349 FlatCAMApp.py:10393 FlatCAMApp.py:10470 +#: FlatCAMApp.py:10525 FlatCAMCommon.py:371 FlatCAMCommon.py:413 +#: FlatCAMCommon.py:1107 FlatCAMCommon.py:1153 FlatCAMCommon.py:2537 +#: FlatCAMCommon.py:2583 ObjectCollection.py:122 +#: flatcamEditors/FlatCAMExcEditor.py:1024 +#: flatcamEditors/FlatCAMExcEditor.py:1092 +#: flatcamEditors/FlatCAMTextEditor.py:223 flatcamGUI/FlatCAMGUI.py:3389 +#: flatcamGUI/FlatCAMGUI.py:3601 flatcamGUI/FlatCAMGUI.py:3812 +#: flatcamTools/ToolFilm.py:754 flatcamTools/ToolFilm.py:900 +#: flatcamTools/ToolImage.py:247 flatcamTools/ToolMove.py:270 #: flatcamTools/ToolPcbWizard.py:301 flatcamTools/ToolPcbWizard.py:324 -msgid "Open cancelled." -msgstr "Deschidere anulată." +#: flatcamTools/ToolQRCode.py:791 flatcamTools/ToolQRCode.py:838 +msgid "Cancelled." +msgstr "Anulat." -#: FlatCAMApp.py:2779 +#: FlatCAMApp.py:2980 msgid "Open Config file failed." msgstr "Deschiderea fişierului de configurare a eşuat." -#: FlatCAMApp.py:2794 +#: FlatCAMApp.py:2995 msgid "Open Script file failed." msgstr "Deschiderea fişierului Script eşuat." -#: FlatCAMApp.py:2820 +#: FlatCAMApp.py:3021 msgid "Open Excellon file failed." msgstr "Deschiderea fişierului Excellon a eşuat." -#: FlatCAMApp.py:2833 +#: FlatCAMApp.py:3034 msgid "Open GCode file failed." msgstr "Deschiderea fişierului GCode a eşuat." -#: FlatCAMApp.py:2846 +#: FlatCAMApp.py:3047 msgid "Open Gerber file failed." msgstr "Deschiderea fişierului Gerber a eşuat." -#: FlatCAMApp.py:3201 +#: FlatCAMApp.py:3424 msgid "Select a Geometry, Gerber or Excellon Object to edit." msgstr "Selectează un obiect tip Geometrie Gerber sau Excellon pentru editare." -#: FlatCAMApp.py:3216 +#: FlatCAMApp.py:3439 msgid "" "Simultaneous editing of tools geometry in a MultiGeo Geometry is not " "possible.\n" @@ -121,100 +146,98 @@ msgstr "" "MultiGeo nu este posibilă.\n" "Se poate edita numai o singură geometrie de fiecare dată." -#: FlatCAMApp.py:3271 +#: FlatCAMApp.py:3497 msgid "Editor is activated ..." msgstr "Editorul este activ ..." -#: FlatCAMApp.py:3292 +#: FlatCAMApp.py:3518 msgid "Do you want to save the edited object?" msgstr "Vrei sa salvezi obiectul editat?" -#: FlatCAMApp.py:3293 flatcamGUI/FlatCAMGUI.py:2165 +#: FlatCAMApp.py:3519 flatcamGUI/FlatCAMGUI.py:2273 msgid "Close Editor" msgstr "Inchide Editorul" -#: FlatCAMApp.py:3296 FlatCAMApp.py:4014 FlatCAMApp.py:5067 FlatCAMApp.py:7724 -#: FlatCAMApp.py:7750 FlatCAMApp.py:8927 FlatCAMTranslation.py:108 -#: FlatCAMTranslation.py:193 +#: FlatCAMApp.py:3522 FlatCAMApp.py:5163 FlatCAMApp.py:8023 FlatCAMApp.py:8049 +#: FlatCAMApp.py:9298 FlatCAMTranslation.py:108 FlatCAMTranslation.py:199 +#: flatcamGUI/FlatCAMGUI.py:2479 msgid "Yes" msgstr "Da" -#: FlatCAMApp.py:3297 FlatCAMApp.py:4015 FlatCAMApp.py:5068 FlatCAMApp.py:7725 -#: FlatCAMApp.py:7751 FlatCAMApp.py:8928 FlatCAMTranslation.py:109 -#: FlatCAMTranslation.py:194 flatcamGUI/PreferencesUI.py:5139 -#: flatcamGUI/PreferencesUI.py:5554 flatcamTools/ToolNonCopperClear.py:189 -#: flatcamTools/ToolPaint.py:161 +#: FlatCAMApp.py:3523 FlatCAMApp.py:5164 FlatCAMApp.py:8024 FlatCAMApp.py:8050 +#: FlatCAMApp.py:9299 FlatCAMTranslation.py:109 FlatCAMTranslation.py:200 +#: flatcamGUI/FlatCAMGUI.py:2480 flatcamGUI/PreferencesUI.py:5443 +#: flatcamGUI/PreferencesUI.py:5989 flatcamTools/ToolNCC.py:182 +#: flatcamTools/ToolPaint.py:166 msgid "No" msgstr "Nu" -#: FlatCAMApp.py:3298 FlatCAMApp.py:5069 FlatCAMApp.py:5925 FlatCAMApp.py:7006 -#: FlatCAMApp.py:8929 FlatCAMCommon.py:571 flatcamGUI/FlatCAMGUI.py:1260 +#: FlatCAMApp.py:3524 FlatCAMApp.py:5165 FlatCAMApp.py:6049 FlatCAMApp.py:7000 +#: FlatCAMApp.py:9300 FlatCAMCommon.py:572 FlatCAMCommon.py:2127 +#: flatcamGUI/FlatCAMGUI.py:1332 msgid "Cancel" msgstr "Anuleaza" -#: FlatCAMApp.py:3326 +#: FlatCAMApp.py:3556 msgid "Object empty after edit." msgstr "Obiectul nu are date dupa editare." -#: FlatCAMApp.py:3375 FlatCAMApp.py:3395 FlatCAMApp.py:3410 +#: FlatCAMApp.py:3560 FlatCAMApp.py:3581 FlatCAMApp.py:3603 +msgid "Editor exited. Editor content saved." +msgstr "Ieşire din Editor. Continuțul editorului este salvat." + +#: FlatCAMApp.py:3607 FlatCAMApp.py:3630 FlatCAMApp.py:3648 msgid "Select a Gerber, Geometry or Excellon Object to update." msgstr "" "Selectează un obiect tip Gerber, Geometrie sau Excellon pentru actualizare." -#: FlatCAMApp.py:3379 +#: FlatCAMApp.py:3610 msgid "is updated, returning to App..." msgstr "este actualizat, întoarcere la aplicaţie..." -#: FlatCAMApp.py:3774 FlatCAMApp.py:3888 FlatCAMApp.py:4929 +#: FlatCAMApp.py:3617 +msgid "Editor exited. Editor content was not saved." +msgstr "Ieşire din Editor. Continuțul editorului nu a fost salvat." + +#: FlatCAMApp.py:3810 FlatCAMApp.py:3941 FlatCAMApp.py:5012 msgid "Could not load defaults file." msgstr "Nu am putut incărca fişierul cu valori default." -#: FlatCAMApp.py:3786 FlatCAMApp.py:3896 FlatCAMApp.py:4938 +#: FlatCAMApp.py:3822 FlatCAMApp.py:3949 FlatCAMApp.py:5021 msgid "Failed to parse defaults file." msgstr "Parsarea fişierului cu valori default a eșuat." -#: FlatCAMApp.py:3831 -msgid "Preferences default restore was cancelled." -msgstr "Restaurarea preferințelor implicite a fost anulată." - -#: FlatCAMApp.py:3839 FlatCAMApp.py:5017 +#: FlatCAMApp.py:3892 FlatCAMApp.py:5113 msgid "Could not load factory defaults file." msgstr "" "Fişierul cu valori default de fabrică nu a fost posibil să fie deschis." -#: FlatCAMApp.py:3847 FlatCAMApp.py:5027 +#: FlatCAMApp.py:3900 FlatCAMApp.py:5123 msgid "Failed to parse factory defaults file." msgstr "Parsarea fişierului cu valori default de fabrică a eșuat." -#: FlatCAMApp.py:3855 +#: FlatCAMApp.py:3908 msgid "Preferences default values are restored." msgstr "Valorile implicite pt preferințe sunt restabilite." -#: FlatCAMApp.py:3870 FlatCAMApp.py:3874 +#: FlatCAMApp.py:3923 FlatCAMApp.py:3927 msgid "Import FlatCAM Preferences" msgstr "Importă Preferințele FlatCAM" -#: FlatCAMApp.py:3880 -msgid "FlatCAM preferences import cancelled." -msgstr "Importul preferințelor FlatCAM a eșuat." - -#: FlatCAMApp.py:3904 +#: FlatCAMApp.py:3957 msgid "Imported Defaults from" msgstr "Valorile default au fost importate din" -#: FlatCAMApp.py:3924 FlatCAMApp.py:3929 +#: FlatCAMApp.py:3977 FlatCAMApp.py:3982 msgid "Export FlatCAM Preferences" msgstr "Exportă Preferințele FlatCAM" -#: FlatCAMApp.py:3936 -msgid "FlatCAM preferences export cancelled." -msgstr "Exportul preferințelor FlatCAM este anulat." - -#: FlatCAMApp.py:3945 FlatCAMApp.py:10389 FlatCAMApp.py:10437 -#: FlatCAMApp.py:10560 FlatCAMApp.py:10699 FlatCAMCommon.py:378 -#: FlatCAMCommon.py:1114 FlatCAMObj.py:6903 -#: flatcamEditors/FlatCAMTextEditor.py:274 flatcamTools/ToolFilm.py:1019 -#: flatcamTools/ToolFilm.py:1195 flatcamTools/ToolSolderPaste.py:1544 +#: FlatCAMApp.py:3997 FlatCAMApp.py:4071 FlatCAMApp.py:10769 +#: FlatCAMApp.py:10817 FlatCAMApp.py:10943 FlatCAMApp.py:11080 +#: FlatCAMCommon.py:379 FlatCAMCommon.py:1115 FlatCAMCommon.py:2545 +#: FlatCAMObj.py:7484 flatcamEditors/FlatCAMTextEditor.py:276 +#: flatcamTools/ToolFilm.py:1031 flatcamTools/ToolFilm.py:1212 +#: flatcamTools/ToolSolderPaste.py:1533 msgid "" "Permission denied, saving not possible.\n" "Most likely another app is holding the file open and not accessible." @@ -222,48 +245,48 @@ msgstr "" "Permisiune refuzată, salvarea nu este posibilă.\n" "Cel mai probabil o altă aplicație ține fișierul deschis și inaccesibil." -#: FlatCAMApp.py:3957 +#: FlatCAMApp.py:4009 msgid "Could not load preferences file." msgstr "Nu am putut incărca fişierul cu valori default." -#: FlatCAMApp.py:3976 FlatCAMApp.py:4985 +#: FlatCAMApp.py:4028 FlatCAMApp.py:4095 FlatCAMApp.py:5040 msgid "Failed to write defaults to file." msgstr "Salvarea valorilor default intr-un fişier a eșuat." -#: FlatCAMApp.py:3981 +#: FlatCAMApp.py:4033 msgid "Exported preferences to" msgstr "Exportă Preferințele in" -#: FlatCAMApp.py:3998 -msgid "FlatCAM Preferences Folder opened." -msgstr "Folderul de preferințe FlatCAM a fost deschis." +#: FlatCAMApp.py:4053 FlatCAMApp.py:4058 +msgid "Save to file" +msgstr "Salvat in" -#: FlatCAMApp.py:4009 -msgid "Are you sure you want to delete the GUI Settings? \n" -msgstr "Esti sigur că dorești să ștergi setările GUI?\n" +#: FlatCAMApp.py:4082 +msgid "Could not load the file." +msgstr "Nu am putut incărca fişierul." -#: FlatCAMApp.py:4012 flatcamGUI/FlatCAMGUI.py:1230 -msgid "Clear GUI Settings" -msgstr "Șterge Setările GUI" +#: FlatCAMApp.py:4098 +msgid "Exported file to" +msgstr "S-a exportat fişierul in" -#: FlatCAMApp.py:4109 +#: FlatCAMApp.py:4181 msgid "Failed to open recent files file for writing." msgstr "" "Deschiderea fişierului cu >fişiere recente< pentru a fi salvat a eșuat." -#: FlatCAMApp.py:4120 +#: FlatCAMApp.py:4192 msgid "Failed to open recent projects file for writing." msgstr "" "Deschiderea fişierului cu >proiecte recente< pentru a fi salvat a eșuat." -#: FlatCAMApp.py:4205 FlatCAMApp.py:10900 FlatCAMApp.py:10961 -#: FlatCAMApp.py:11090 FlatCAMObj.py:5050 -#: flatcamEditors/FlatCAMGrbEditor.py:4187 flatcamTools/ToolPcbWizard.py:437 +#: FlatCAMApp.py:4277 FlatCAMApp.py:11276 FlatCAMApp.py:11335 +#: FlatCAMApp.py:11463 FlatCAMApp.py:12189 FlatCAMObj.py:5605 +#: flatcamEditors/FlatCAMGrbEditor.py:4231 flatcamTools/ToolPcbWizard.py:433 msgid "An internal error has occurred. See shell.\n" msgstr "" "A apărut o eroare internă. Verifică in TCL Shell pt mai multe detalii.\n" -#: FlatCAMApp.py:4206 +#: FlatCAMApp.py:4278 #, python-brace-format msgid "" "Object ({kind}) failed because: {error} \n" @@ -272,63 +295,63 @@ msgstr "" "Obiectul ({kind}) a eșuat din cauza: {error} \n" "\n" -#: FlatCAMApp.py:4221 +#: FlatCAMApp.py:4293 msgid "Converting units to " msgstr "Se convertesc unitătile la " -#: FlatCAMApp.py:4324 +#: FlatCAMApp.py:4406 msgid "CREATE A NEW FLATCAM TCL SCRIPT" msgstr "CREAȚI UN SCRIPT FLATCAM TCL NOU" -#: FlatCAMApp.py:4325 +#: FlatCAMApp.py:4407 msgid "TCL Tutorial is here" msgstr "Tutorialul TCL este aici" -#: FlatCAMApp.py:4327 +#: FlatCAMApp.py:4409 msgid "FlatCAM commands list" msgstr "Lista de comenzi FlatCAM" -#: FlatCAMApp.py:4378 FlatCAMApp.py:4384 FlatCAMApp.py:4390 FlatCAMApp.py:4396 -#: FlatCAMApp.py:4402 FlatCAMApp.py:4408 +#: FlatCAMApp.py:4460 FlatCAMApp.py:4466 FlatCAMApp.py:4472 FlatCAMApp.py:4478 +#: FlatCAMApp.py:4484 FlatCAMApp.py:4490 msgid "created/selected" msgstr "creat / selectat" -#: FlatCAMApp.py:4423 FlatCAMApp.py:7086 FlatCAMObj.py:271 FlatCAMObj.py:302 -#: FlatCAMObj.py:318 FlatCAMObj.py:398 flatcamTools/ToolCopperThieving.py:1476 -#: flatcamTools/ToolFiducials.py:807 flatcamTools/ToolMove.py:220 -#: flatcamTools/ToolQRCode.py:726 +#: FlatCAMApp.py:4505 FlatCAMApp.py:7086 FlatCAMObj.py:278 FlatCAMObj.py:309 +#: FlatCAMObj.py:325 FlatCAMObj.py:405 flatcamTools/ToolCopperThieving.py:1482 +#: flatcamTools/ToolFiducials.py:809 flatcamTools/ToolMove.py:230 +#: flatcamTools/ToolQRCode.py:728 msgid "Plotting" msgstr "Se afișeaz" -#: FlatCAMApp.py:4486 flatcamGUI/FlatCAMGUI.py:491 +#: FlatCAMApp.py:4568 flatcamGUI/FlatCAMGUI.py:530 msgid "About FlatCAM" msgstr "Despre FlatCAM" -#: FlatCAMApp.py:4512 +#: FlatCAMApp.py:4594 msgid "2D Computer-Aided Printed Circuit Board Manufacturing" msgstr "Productie Cablaje Imprimate asistate 2D de PC" -#: FlatCAMApp.py:4513 +#: FlatCAMApp.py:4595 msgid "Development" msgstr "Dezvoltare" -#: FlatCAMApp.py:4514 +#: FlatCAMApp.py:4596 msgid "DOWNLOAD" msgstr "DOWNLOAD" -#: FlatCAMApp.py:4515 +#: FlatCAMApp.py:4597 msgid "Issue tracker" msgstr "Raportare probleme" -#: FlatCAMApp.py:4519 FlatCAMApp.py:4860 +#: FlatCAMApp.py:4601 FlatCAMApp.py:4942 flatcamGUI/GUIElements.py:2583 msgid "Close" msgstr "Închide" -#: FlatCAMApp.py:4534 +#: FlatCAMApp.py:4616 msgid "Licensed under the MIT license" msgstr "Licențiat sub licența MIT" -#: FlatCAMApp.py:4543 +#: FlatCAMApp.py:4625 msgid "" "Permission is hereby granted, free of charge, to any person obtaining a " "copy\n" @@ -381,7 +404,7 @@ msgstr "" "UTILIZAREA SA,\n" "SAU ORICE TRATĂRI ÎN ACEST SOFTWARE." -#: FlatCAMApp.py:4565 +#: FlatCAMApp.py:4647 msgid "" "Some of the icons used are from the following sources:
Icons by FreepikIcons8Pictograme create de oNline Web Fonts" -#: FlatCAMApp.py:4597 +#: FlatCAMApp.py:4679 msgid "Splash" msgstr "Splash" -#: FlatCAMApp.py:4603 +#: FlatCAMApp.py:4685 msgid "Programmers" msgstr "Programatori" -#: FlatCAMApp.py:4609 +#: FlatCAMApp.py:4691 msgid "Translators" msgstr "Traducatori" -#: FlatCAMApp.py:4615 +#: FlatCAMApp.py:4697 msgid "License" msgstr "Licență" -#: FlatCAMApp.py:4621 +#: FlatCAMApp.py:4703 msgid "Attributions" msgstr "Atribuiri" -#: FlatCAMApp.py:4644 +#: FlatCAMApp.py:4726 msgid "Programmer" msgstr "Programator" -#: FlatCAMApp.py:4645 +#: FlatCAMApp.py:4727 msgid "Status" msgstr "Statut" -#: FlatCAMApp.py:4646 FlatCAMApp.py:4724 +#: FlatCAMApp.py:4728 FlatCAMApp.py:4806 msgid "E-mail" msgstr "E-mail" -#: FlatCAMApp.py:4654 +#: FlatCAMApp.py:4736 msgid "BETA Maintainer >= 2019" msgstr "Programator Beta >= 2019" -#: FlatCAMApp.py:4721 +#: FlatCAMApp.py:4803 msgid "Language" msgstr "Limba" -#: FlatCAMApp.py:4722 +#: FlatCAMApp.py:4804 msgid "Translator" msgstr "Traducător" -#: FlatCAMApp.py:4723 +#: FlatCAMApp.py:4805 msgid "Corrections" msgstr "Corecţii" -#: FlatCAMApp.py:4832 FlatCAMApp.py:4840 FlatCAMApp.py:7769 -#: flatcamGUI/FlatCAMGUI.py:473 +#: FlatCAMApp.py:4914 FlatCAMApp.py:4922 FlatCAMApp.py:8068 +#: flatcamGUI/FlatCAMGUI.py:512 msgid "Bookmarks Manager" msgstr "Bookmarks Manager" -#: FlatCAMApp.py:4851 +#: FlatCAMApp.py:4933 msgid "" "This entry will resolve to another website if:\n" "\n" @@ -471,28 +494,28 @@ msgstr "" "Dacă nu puteți obține informații despre FlatCAM beta\n" "utilizați linkul canalului YouTube din meniul Ajutor." -#: FlatCAMApp.py:4858 +#: FlatCAMApp.py:4940 msgid "Alternative website" msgstr "Site alternativ" -#: FlatCAMApp.py:4989 FlatCAMApp.py:7733 +#: FlatCAMApp.py:5044 FlatCAMApp.py:8032 msgid "Preferences saved." msgstr "Preferințele au fost salvate." -#: FlatCAMApp.py:5043 +#: FlatCAMApp.py:5139 msgid "Failed to write factory defaults to file." msgstr "" "Salvarea fişierului cu valori default de fabrică intr-un fişier a eșuat." -#: FlatCAMApp.py:5047 +#: FlatCAMApp.py:5143 msgid "Factory defaults saved." msgstr "Valori default de fabrică au fost salvate." -#: FlatCAMApp.py:5057 flatcamGUI/FlatCAMGUI.py:3962 +#: FlatCAMApp.py:5153 flatcamGUI/FlatCAMGUI.py:4178 msgid "Application is saving the project. Please wait ..." msgstr "Aplicația salvează proiectul. Vă rugăm aşteptați ..." -#: FlatCAMApp.py:5062 FlatCAMTranslation.py:188 +#: FlatCAMApp.py:5158 FlatCAMTranslation.py:194 msgid "" "There are files/objects modified in FlatCAM. \n" "Do you want to Save the project?" @@ -500,29 +523,29 @@ msgstr "" "FlatCAM are fişiere/obiecte care au fost modificate. \n" "Dorești să Salvezi proiectul?" -#: FlatCAMApp.py:5065 FlatCAMApp.py:8925 FlatCAMTranslation.py:191 +#: FlatCAMApp.py:5161 FlatCAMApp.py:9296 FlatCAMTranslation.py:197 msgid "Save changes" msgstr "Salvează modificarile" -#: FlatCAMApp.py:5306 +#: FlatCAMApp.py:5417 msgid "Selected Excellon file extensions registered with FlatCAM." msgstr "Extensiile de fișiere Excellon selectate înregistrate cu FlatCAM." -#: FlatCAMApp.py:5328 +#: FlatCAMApp.py:5439 msgid "Selected GCode file extensions registered with FlatCAM." msgstr "Extensii de fișiere GCode selectate înregistrate cu FlatCAM." -#: FlatCAMApp.py:5350 +#: FlatCAMApp.py:5461 msgid "Selected Gerber file extensions registered with FlatCAM." msgstr "Extensii de fișiere Gerber selectate înregistrate cu FlatCAM." -#: FlatCAMApp.py:5538 FlatCAMApp.py:5595 FlatCAMApp.py:5623 +#: FlatCAMApp.py:5649 FlatCAMApp.py:5708 FlatCAMApp.py:5736 msgid "At least two objects are required for join. Objects currently selected" msgstr "" "Cel puțin două obiecte sunt necesare pentru a fi unite. Obiectele selectate " "în prezent" -#: FlatCAMApp.py:5547 +#: FlatCAMApp.py:5658 msgid "" "Failed join. The Geometry objects are of different types.\n" "At least one is MultiGeo type and the other is SingleGeo type. A possibility " @@ -539,52 +562,48 @@ msgstr "" "informatii și rezultatul ar putea să nu fie cel dorit. \n" "Verifică codul G-Code generat." -#: FlatCAMApp.py:5559 -msgid "Multigeo. Geometry merging finished" -msgstr "Multigeo. Fuziunea geometriei s-a terminat" - -#: FlatCAMApp.py:5568 +#: FlatCAMApp.py:5670 FlatCAMApp.py:5680 msgid "Geometry merging finished" msgstr "Fuziunea geometriei s-a terminat" -#: FlatCAMApp.py:5590 +#: FlatCAMApp.py:5703 msgid "Failed. Excellon joining works only on Excellon objects." msgstr "" "Eșuat. Fuzionarea Excellon functionează doar cu obiecte de tip Excellon." -#: FlatCAMApp.py:5600 +#: FlatCAMApp.py:5713 msgid "Excellon merging finished" msgstr "Fuziunea Excellon a fost terminată" -#: FlatCAMApp.py:5618 +#: FlatCAMApp.py:5731 msgid "Failed. Gerber joining works only on Gerber objects." msgstr "Eșuat. Fuzionarea Gerber functionează doar cu obiecte de tip Gerber ." -#: FlatCAMApp.py:5628 +#: FlatCAMApp.py:5741 msgid "Gerber merging finished" msgstr "Fuziunea Gerber a fost terminată" -#: FlatCAMApp.py:5648 FlatCAMApp.py:5683 +#: FlatCAMApp.py:5761 FlatCAMApp.py:5796 msgid "Failed. Select a Geometry Object and try again." msgstr "Eșuat. Selectează un obiect Geometrie și încearcă din nou." -#: FlatCAMApp.py:5652 FlatCAMApp.py:5688 +#: FlatCAMApp.py:5765 FlatCAMApp.py:5801 msgid "Expected a FlatCAMGeometry, got" msgstr "Se astepta o Geometrie FlatCAM, s-a primit" -#: FlatCAMApp.py:5665 +#: FlatCAMApp.py:5778 msgid "A Geometry object was converted to MultiGeo type." msgstr "Un obiect Geometrie a fost convertit la tipul MultiGeo." -#: FlatCAMApp.py:5703 +#: FlatCAMApp.py:5816 msgid "A Geometry object was converted to SingleGeo type." msgstr "Un obiect Geometrie a fost convertit la tipul SingleGeo ." -#: FlatCAMApp.py:5919 +#: FlatCAMApp.py:6043 msgid "Toggle Units" msgstr "Comută Unitati" -#: FlatCAMApp.py:5921 +#: FlatCAMApp.py:6045 msgid "" "Changing the units of the project\n" "will scale all objects.\n" @@ -596,49 +615,45 @@ msgstr "" "\n" "Doriți să continuați?" -#: FlatCAMApp.py:5924 FlatCAMApp.py:6929 FlatCAMApp.py:7005 FlatCAMApp.py:9290 -#: FlatCAMApp.py:9304 FlatCAMApp.py:9658 FlatCAMApp.py:9669 +#: FlatCAMApp.py:6048 FlatCAMApp.py:6922 FlatCAMApp.py:6999 FlatCAMApp.py:9669 +#: FlatCAMApp.py:9683 FlatCAMApp.py:10018 FlatCAMApp.py:10028 msgid "Ok" msgstr "Ok" -#: FlatCAMApp.py:5973 +#: FlatCAMApp.py:6097 msgid "Converted units to" msgstr "Unitătile au fost convertite in" -#: FlatCAMApp.py:5987 -msgid "Units conversion cancelled." -msgstr "Conversia unitătilor este anulată." - -#: FlatCAMApp.py:6613 +#: FlatCAMApp.py:6737 msgid "Detachable Tabs" msgstr "Taburi detașabile" -#: FlatCAMApp.py:6828 FlatCAMApp.py:6889 FlatCAMApp.py:7560 FlatCAMApp.py:7622 -#: FlatCAMApp.py:7688 +#: FlatCAMApp.py:6811 FlatCAMApp.py:6855 FlatCAMApp.py:6883 FlatCAMApp.py:7815 +#: FlatCAMApp.py:7883 FlatCAMApp.py:7987 msgid "Preferences" msgstr "Preferințe" -#: FlatCAMApp.py:6831 +#: FlatCAMApp.py:6817 msgid "Preferences applied." msgstr "Preferințele au fost aplicate." -#: FlatCAMApp.py:6894 +#: FlatCAMApp.py:6888 msgid "Preferences closed without saving." msgstr "Tab-ul Preferințe a fost închis fără a salva." -#: FlatCAMApp.py:6917 flatcamTools/ToolNonCopperClear.py:591 -#: flatcamTools/ToolNonCopperClear.py:987 flatcamTools/ToolPaint.py:502 -#: flatcamTools/ToolSolderPaste.py:562 flatcamTools/ToolSolderPaste.py:892 +#: FlatCAMApp.py:6911 flatcamTools/ToolNCC.py:930 flatcamTools/ToolNCC.py:1435 +#: flatcamTools/ToolPaint.py:855 flatcamTools/ToolSolderPaste.py:568 +#: flatcamTools/ToolSolderPaste.py:893 msgid "Please enter a tool diameter with non-zero value, in Float format." msgstr "" "Introduceti un diametru al uneltei valid: valoare ne-nula in format Real." -#: FlatCAMApp.py:6922 flatcamTools/ToolNonCopperClear.py:595 -#: flatcamTools/ToolPaint.py:506 flatcamTools/ToolSolderPaste.py:566 +#: FlatCAMApp.py:6915 flatcamTools/ToolNCC.py:934 flatcamTools/ToolPaint.py:859 +#: flatcamTools/ToolSolderPaste.py:572 msgid "Adding Tool cancelled" msgstr "Adăugarea unei unelte anulată" -#: FlatCAMApp.py:6925 +#: FlatCAMApp.py:6918 msgid "" "Adding Tool works only when Advanced is checked.\n" "Go to Preferences -> General - Show Advanced Options." @@ -646,11 +661,11 @@ msgstr "" "Adăugarea de unelte noi functionează doar in modul Avansat.\n" "Pentru aceasta mergi in Preferințe -> General - Activează Modul Avansat." -#: FlatCAMApp.py:7000 +#: FlatCAMApp.py:6994 msgid "Delete objects" msgstr "Șterge obiectele" -#: FlatCAMApp.py:7003 +#: FlatCAMApp.py:6997 msgid "" "Are you sure you want to permanently delete\n" "the selected objects?" @@ -658,15 +673,15 @@ msgstr "" "Sigur doriți să ștergeți definitiv\n" "obiectele selectate?" -#: FlatCAMApp.py:7034 +#: FlatCAMApp.py:7035 msgid "Object(s) deleted" msgstr "Obiect(ele) șters(e)" -#: FlatCAMApp.py:7038 flatcamTools/ToolDblSided.py:713 +#: FlatCAMApp.py:7039 FlatCAMApp.py:7194 flatcamTools/ToolDblSided.py:819 msgid "Failed. No object(s) selected..." msgstr "Eșuat. Nici-un obiect nu este selectat." -#: FlatCAMApp.py:7040 +#: FlatCAMApp.py:7041 msgid "Save the work in Editor and try again ..." msgstr "Salvează continutul din Editor și încearcă din nou." @@ -682,78 +697,120 @@ msgstr "Click pentru a seta originea..." msgid "Setting Origin..." msgstr "Setează Originea..." -#: FlatCAMApp.py:7131 +#: FlatCAMApp.py:7132 FlatCAMApp.py:7234 msgid "Origin set" msgstr "Originea a fost setată" -#: FlatCAMApp.py:7138 +#: FlatCAMApp.py:7149 msgid "Origin coordinates specified but incomplete." msgstr "Coordonate pentru origine specificate, dar incomplete." -#: FlatCAMApp.py:7197 +#: FlatCAMApp.py:7190 +msgid "Moving to Origin..." +msgstr "Deplasare către Origine..." + +#: FlatCAMApp.py:7271 msgid "Jump to ..." msgstr "Sari la ..." -#: FlatCAMApp.py:7198 +#: FlatCAMApp.py:7272 msgid "Enter the coordinates in format X,Y:" msgstr "Introduceți coordonatele in format X,Y:" -#: FlatCAMApp.py:7208 +#: FlatCAMApp.py:7282 msgid "Wrong coordinates. Enter coordinates in format: X,Y" msgstr "Coordonate gresite. Introduceți coordonatele in format X,Y" -#: FlatCAMApp.py:7288 flatcamEditors/FlatCAMExcEditor.py:3599 -#: flatcamEditors/FlatCAMExcEditor.py:3607 -#: flatcamEditors/FlatCAMGeoEditor.py:4036 -#: flatcamEditors/FlatCAMGeoEditor.py:4051 -#: flatcamEditors/FlatCAMGrbEditor.py:1086 -#: flatcamEditors/FlatCAMGrbEditor.py:1203 -#: flatcamEditors/FlatCAMGrbEditor.py:1489 -#: flatcamEditors/FlatCAMGrbEditor.py:1758 -#: flatcamEditors/FlatCAMGrbEditor.py:4445 -#: flatcamEditors/FlatCAMGrbEditor.py:4460 flatcamGUI/FlatCAMGUI.py:3145 -#: flatcamGUI/FlatCAMGUI.py:3157 +#: FlatCAMApp.py:7360 FlatCAMApp.py:7509 +#: flatcamEditors/FlatCAMExcEditor.py:3622 +#: flatcamEditors/FlatCAMExcEditor.py:3630 +#: flatcamEditors/FlatCAMGeoEditor.py:4349 +#: flatcamEditors/FlatCAMGeoEditor.py:4363 +#: flatcamEditors/FlatCAMGrbEditor.py:1085 +#: flatcamEditors/FlatCAMGrbEditor.py:1202 +#: flatcamEditors/FlatCAMGrbEditor.py:1488 +#: flatcamEditors/FlatCAMGrbEditor.py:1757 +#: flatcamEditors/FlatCAMGrbEditor.py:4489 +#: flatcamEditors/FlatCAMGrbEditor.py:4504 flatcamGUI/FlatCAMGUI.py:3370 +#: flatcamGUI/FlatCAMGUI.py:3382 flatcamTools/ToolAlignObjects.py:393 +#: flatcamTools/ToolAlignObjects.py:415 msgid "Done." msgstr "Executat." -#: FlatCAMApp.py:7440 FlatCAMApp.py:7511 +#: FlatCAMApp.py:7375 FlatCAMApp.py:9665 FlatCAMApp.py:9761 FlatCAMApp.py:9803 +#: FlatCAMApp.py:9844 FlatCAMApp.py:9885 FlatCAMApp.py:9926 FlatCAMApp.py:9970 +#: FlatCAMApp.py:10014 FlatCAMApp.py:10503 FlatCAMApp.py:10507 +#: flatcamTools/ToolProperties.py:116 +msgid "No object selected." +msgstr "Nici-un obiect nu este selectat." + +#: FlatCAMApp.py:7394 +msgid "Bottom-Left" +msgstr "Stânga jos" + +#: FlatCAMApp.py:7395 flatcamGUI/PreferencesUI.py:8111 +#: flatcamTools/ToolCalibration.py:159 +msgid "Top-Left" +msgstr "Stânga-sus" + +#: FlatCAMApp.py:7396 flatcamGUI/PreferencesUI.py:8112 +#: flatcamTools/ToolCalibration.py:160 +msgid "Bottom-Right" +msgstr "Dreapta-jos" + +#: FlatCAMApp.py:7397 +msgid "Top-Right" +msgstr "Dreapta-sus" + +#: FlatCAMApp.py:7398 flatcamGUI/ObjectUI.py:2624 +msgid "Center" +msgstr "Centru" + +#: FlatCAMApp.py:7418 +msgid "Locate ..." +msgstr "Localizează ..." + +#: FlatCAMApp.py:7679 FlatCAMApp.py:7756 msgid "No object is selected. Select an object and try again." msgstr "" "Nici-un obiect nu este selectat. Selectează un obiect și incearcă din nou." -#: FlatCAMApp.py:7531 +#: FlatCAMApp.py:7782 msgid "" "Aborting. The current task will be gracefully closed as soon as possible..." msgstr "Intrerup. Taskul curent va fi închis cât mai curând posibil ..." -#: FlatCAMApp.py:7537 +#: FlatCAMApp.py:7787 msgid "The current task was gracefully closed on user request..." msgstr "Taskul curent a fost închis la cererea utilizatorului ..." -#: FlatCAMApp.py:7619 +#: FlatCAMApp.py:7880 msgid "Preferences edited but not saved." msgstr "Preferințele au fost editate dar nu au fost salvate." -#: FlatCAMApp.py:7633 FlatCAMApp.py:7645 FlatCAMApp.py:7662 FlatCAMApp.py:7679 -#: FlatCAMApp.py:7739 FlatCAMCommon.py:1181 FlatCAMCommon.py:1356 -#: FlatCAMObj.py:4256 +#: FlatCAMApp.py:7897 FlatCAMApp.py:7925 FlatCAMApp.py:7952 FlatCAMApp.py:7971 +#: FlatCAMApp.py:8038 FlatCAMCommon.py:1182 FlatCAMCommon.py:1357 +#: FlatCAMCommon.py:2612 FlatCAMCommon.py:2820 FlatCAMObj.py:4798 +#: flatcamTools/ToolNCC.py:3963 flatcamTools/ToolNCC.py:4047 +#: flatcamTools/ToolPaint.py:4027 flatcamTools/ToolPaint.py:4112 msgid "Tools Database" msgstr "Baza de Date Unelte" -#: FlatCAMApp.py:7659 +#: FlatCAMApp.py:7949 msgid "Tools in Tools Database edited but not saved." msgstr "Uneltele din Baza de date au fost editate dar nu au fost salvate." -#: FlatCAMApp.py:7683 +#: FlatCAMApp.py:7975 flatcamTools/ToolNCC.py:3970 +#: flatcamTools/ToolPaint.py:4034 msgid "Tool from DB added in Tool Table." msgstr "Unealtă din Baza de date adăugată in Tabela de Unelte." -#: FlatCAMApp.py:7685 +#: FlatCAMApp.py:7977 msgid "Adding tool from DB is not allowed for this object." msgstr "" "Adaugarea unei unelte din Baza de date nu este permisa pt acest obiect." -#: FlatCAMApp.py:7719 +#: FlatCAMApp.py:8018 msgid "" "One or more values are changed.\n" "Do you want to save the Preferences?" @@ -761,11 +818,11 @@ msgstr "" "Una sau mai multe valori au fost schimbate.\n" "Dorești să salvezi Preferințele?" -#: FlatCAMApp.py:7721 flatcamGUI/FlatCAMGUI.py:222 +#: FlatCAMApp.py:8020 flatcamGUI/FlatCAMGUI.py:291 msgid "Save Preferences" msgstr "Salvează Pref" -#: FlatCAMApp.py:7745 +#: FlatCAMApp.py:8044 msgid "" "One or more Tools are edited.\n" "Do you want to update the Tools Database?" @@ -773,172 +830,174 @@ msgstr "" "Unul sau mai multe Unelte sunt editate.\n" "Doriți să actualizați baza de date a Uneltelor?" -#: FlatCAMApp.py:7747 +#: FlatCAMApp.py:8046 msgid "Save Tools Database" msgstr "Salvează baza de date Unelte" -#: FlatCAMApp.py:7766 FlatCAMApp.py:9897 FlatCAMObj.py:6509 +#: FlatCAMApp.py:8065 FlatCAMApp.py:10252 FlatCAMObj.py:7089 msgid "Code Editor" msgstr "Editor Cod" -#: FlatCAMApp.py:7784 +#: FlatCAMApp.py:8087 msgid "No object selected to Flip on Y axis." msgstr "Nu sete nici-un obiect selectat pentru oglindire pe axa Y." -#: FlatCAMApp.py:7810 +#: FlatCAMApp.py:8113 msgid "Flip on Y axis done." msgstr "Oglindire pe axa Y executată." -#: FlatCAMApp.py:7812 FlatCAMApp.py:7854 -#: flatcamEditors/FlatCAMGrbEditor.py:5858 +#: FlatCAMApp.py:8115 FlatCAMApp.py:8163 +#: flatcamEditors/FlatCAMGrbEditor.py:5893 msgid "Flip action was not executed." msgstr "Acțiunea de Oglindire nu a fost executată." -#: FlatCAMApp.py:7826 +#: FlatCAMApp.py:8135 msgid "No object selected to Flip on X axis." msgstr "Nu este nici-un obiect selectat pentru oglindire pe axa X." -#: FlatCAMApp.py:7852 +#: FlatCAMApp.py:8161 msgid "Flip on X axis done." msgstr "Oglindirea pe axa X executată." -#: FlatCAMApp.py:7868 +#: FlatCAMApp.py:8183 msgid "No object selected to Rotate." msgstr "Nici-un obiect selectat pentru Rotaţie." -#: FlatCAMApp.py:7871 FlatCAMApp.py:7918 FlatCAMApp.py:7951 +#: FlatCAMApp.py:8186 FlatCAMApp.py:8239 FlatCAMApp.py:8278 msgid "Transform" msgstr "Transformare" -#: FlatCAMApp.py:7871 FlatCAMApp.py:7918 FlatCAMApp.py:7951 +#: FlatCAMApp.py:8186 FlatCAMApp.py:8239 FlatCAMApp.py:8278 msgid "Enter the Angle value:" msgstr "Introduceți valoaea Unghiului:" -#: FlatCAMApp.py:7902 +#: FlatCAMApp.py:8217 msgid "Rotation done." msgstr "Rotaţie executată." -#: FlatCAMApp.py:7904 +#: FlatCAMApp.py:8219 msgid "Rotation movement was not executed." msgstr "Mișcarea de rotație nu a fost executată." -#: FlatCAMApp.py:7916 +#: FlatCAMApp.py:8237 msgid "No object selected to Skew/Shear on X axis." msgstr "Nici-un obiect nu este selectat pentru Deformare pe axa X." -#: FlatCAMApp.py:7938 +#: FlatCAMApp.py:8259 msgid "Skew on X axis done." msgstr "Deformare pe axa X terminată." -#: FlatCAMApp.py:7949 +#: FlatCAMApp.py:8276 msgid "No object selected to Skew/Shear on Y axis." msgstr "Nici-un obiect nu este selectat pentru Deformare pe axa Y." -#: FlatCAMApp.py:7971 +#: FlatCAMApp.py:8298 msgid "Skew on Y axis done." msgstr "Deformare pe axa Y terminată." -#: FlatCAMApp.py:8119 FlatCAMApp.py:8166 flatcamGUI/FlatCAMGUI.py:449 -#: flatcamGUI/FlatCAMGUI.py:1612 +#: FlatCAMApp.py:8451 FlatCAMApp.py:8498 flatcamGUI/FlatCAMGUI.py:488 +#: flatcamGUI/FlatCAMGUI.py:1713 msgid "Select All" msgstr "Selectează toate" -#: FlatCAMApp.py:8123 FlatCAMApp.py:8170 flatcamGUI/FlatCAMGUI.py:451 +#: FlatCAMApp.py:8455 FlatCAMApp.py:8502 flatcamGUI/FlatCAMGUI.py:490 msgid "Deselect All" msgstr "Deselectează toate" -#: FlatCAMApp.py:8186 +#: FlatCAMApp.py:8518 msgid "All objects are selected." msgstr "Totate obiectele sunt selectate." -#: FlatCAMApp.py:8196 +#: FlatCAMApp.py:8528 msgid "Objects selection is cleared." msgstr "Nici-un obiect nu este selectat." -#: FlatCAMApp.py:8216 flatcamGUI/FlatCAMGUI.py:1605 +#: FlatCAMApp.py:8548 flatcamGUI/FlatCAMGUI.py:1706 msgid "Grid On/Off" msgstr "Grid On/Off" -#: FlatCAMApp.py:8228 flatcamEditors/FlatCAMGeoEditor.py:940 -#: flatcamEditors/FlatCAMGrbEditor.py:2574 -#: flatcamEditors/FlatCAMGrbEditor.py:5431 flatcamGUI/ObjectUI.py:1304 -#: flatcamTools/ToolDblSided.py:187 flatcamTools/ToolDblSided.py:245 -#: flatcamTools/ToolNonCopperClear.py:286 flatcamTools/ToolPaint.py:188 -#: flatcamTools/ToolSolderPaste.py:121 flatcamTools/ToolSolderPaste.py:591 -#: flatcamTools/ToolTransform.py:310 +#: FlatCAMApp.py:8560 flatcamEditors/FlatCAMGeoEditor.py:940 +#: flatcamEditors/FlatCAMGrbEditor.py:2580 +#: flatcamEditors/FlatCAMGrbEditor.py:5475 flatcamGUI/ObjectUI.py:1593 +#: flatcamTools/ToolDblSided.py:193 flatcamTools/ToolDblSided.py:426 +#: flatcamTools/ToolNCC.py:294 flatcamTools/ToolNCC.py:631 +#: flatcamTools/ToolPaint.py:277 flatcamTools/ToolPaint.py:673 +#: flatcamTools/ToolSolderPaste.py:123 flatcamTools/ToolSolderPaste.py:597 +#: flatcamTools/ToolTransform.py:479 msgid "Add" msgstr "Adaugă" -#: FlatCAMApp.py:8230 FlatCAMObj.py:3963 -#: flatcamEditors/FlatCAMGrbEditor.py:2579 -#: flatcamEditors/FlatCAMGrbEditor.py:2727 flatcamGUI/FlatCAMGUI.py:680 -#: flatcamGUI/FlatCAMGUI.py:991 flatcamGUI/FlatCAMGUI.py:2018 -#: flatcamGUI/FlatCAMGUI.py:2161 flatcamGUI/FlatCAMGUI.py:2559 -#: flatcamGUI/ObjectUI.py:1330 flatcamTools/ToolNonCopperClear.py:298 -#: flatcamTools/ToolPaint.py:200 flatcamTools/ToolSolderPaste.py:127 -#: flatcamTools/ToolSolderPaste.py:594 +#: FlatCAMApp.py:8562 FlatCAMObj.py:4416 +#: flatcamEditors/FlatCAMGrbEditor.py:2585 +#: flatcamEditors/FlatCAMGrbEditor.py:2733 flatcamGUI/FlatCAMGUI.py:736 +#: flatcamGUI/FlatCAMGUI.py:1059 flatcamGUI/FlatCAMGUI.py:2126 +#: flatcamGUI/FlatCAMGUI.py:2269 flatcamGUI/FlatCAMGUI.py:2733 +#: flatcamGUI/ObjectUI.py:1621 flatcamTools/ToolNCC.py:316 +#: flatcamTools/ToolNCC.py:637 flatcamTools/ToolPaint.py:299 +#: flatcamTools/ToolPaint.py:679 flatcamTools/ToolSolderPaste.py:129 +#: flatcamTools/ToolSolderPaste.py:600 msgid "Delete" msgstr "Șterge" -#: FlatCAMApp.py:8243 +#: FlatCAMApp.py:8575 msgid "New Grid ..." msgstr "Grid nou ..." -#: FlatCAMApp.py:8244 +#: FlatCAMApp.py:8576 msgid "Enter a Grid Value:" msgstr "Introduceti of valoare pt Grid:" -#: FlatCAMApp.py:8252 FlatCAMApp.py:8279 +#: FlatCAMApp.py:8584 FlatCAMApp.py:8611 msgid "Please enter a grid value with non-zero value, in Float format." msgstr "Introduceți o valoare pentru Grila ne-nula și in format Real." -#: FlatCAMApp.py:8258 +#: FlatCAMApp.py:8590 msgid "New Grid added" msgstr "Grid nou" -#: FlatCAMApp.py:8261 +#: FlatCAMApp.py:8593 msgid "Grid already exists" msgstr "Grila există deja" -#: FlatCAMApp.py:8264 +#: FlatCAMApp.py:8596 msgid "Adding New Grid cancelled" msgstr "Adăugarea unei valori de Grilă a fost anulată" -#: FlatCAMApp.py:8286 +#: FlatCAMApp.py:8618 msgid " Grid Value does not exist" msgstr " Valoarea Grilei nu există" -#: FlatCAMApp.py:8289 +#: FlatCAMApp.py:8621 msgid "Grid Value deleted" msgstr "Valoarea Grila a fost stearsă" -#: FlatCAMApp.py:8292 +#: FlatCAMApp.py:8624 msgid "Delete Grid value cancelled" msgstr "Ștergerea unei valori de Grilă a fost anulată" -#: FlatCAMApp.py:8298 +#: FlatCAMApp.py:8630 msgid "Key Shortcut List" msgstr "Lista de shortcut-uri" -#: FlatCAMApp.py:8332 +#: FlatCAMApp.py:8664 msgid " No object selected to copy it's name" msgstr " Nici-un obiect nu este selectat pentru i se copia valoarea" -#: FlatCAMApp.py:8336 +#: FlatCAMApp.py:8668 msgid "Name copied on clipboard ..." msgstr "Numele a fost copiat pe Clipboard ..." -#: FlatCAMApp.py:8534 flatcamEditors/FlatCAMGrbEditor.py:4377 +#: FlatCAMApp.py:8881 flatcamEditors/FlatCAMGrbEditor.py:4421 msgid "Coordinates copied to clipboard." msgstr "Coordonatele au fost copiate in clipboard." -#: FlatCAMApp.py:8762 FlatCAMApp.py:8768 FlatCAMApp.py:8774 FlatCAMApp.py:8780 -#: ObjectCollection.py:797 ObjectCollection.py:803 ObjectCollection.py:809 -#: ObjectCollection.py:815 ObjectCollection.py:821 ObjectCollection.py:827 +#: FlatCAMApp.py:9120 FlatCAMApp.py:9126 FlatCAMApp.py:9132 FlatCAMApp.py:9138 +#: ObjectCollection.py:911 ObjectCollection.py:917 ObjectCollection.py:923 +#: ObjectCollection.py:929 ObjectCollection.py:935 ObjectCollection.py:941 msgid "selected" msgstr "selectat" -#: FlatCAMApp.py:8922 +#: FlatCAMApp.py:9293 msgid "" "There are files/objects opened in FlatCAM.\n" "Creating a New project will delete them.\n" @@ -948,368 +1007,272 @@ msgstr "" "Crearea unui nou Proiect le va șterge..\n" "Doriti să Salvati proiectul curentt?" -#: FlatCAMApp.py:8944 +#: FlatCAMApp.py:9314 msgid "New Project created" msgstr "Un nou Proiect a fost creat" -#: FlatCAMApp.py:9079 FlatCAMApp.py:9083 flatcamGUI/FlatCAMGUI.py:767 -#: flatcamGUI/FlatCAMGUI.py:2352 +#: FlatCAMApp.py:9461 FlatCAMApp.py:9465 flatcamGUI/FlatCAMGUI.py:821 +#: flatcamGUI/FlatCAMGUI.py:2504 msgid "Open Gerber" msgstr "Încarcă Gerber" -#: FlatCAMApp.py:9090 +#: FlatCAMApp.py:9470 FlatCAMApp.py:9507 FlatCAMApp.py:9549 FlatCAMApp.py:9618 +#: FlatCAMApp.py:10371 FlatCAMApp.py:11546 FlatCAMApp.py:11607 +msgid "" +"Canvas initialization started.\n" +"Canvas initialization finished in" +msgstr "" +"FlatCAM se inițializează ...\n" +"Initializarea spațiului de afisare s-a terminat in" + +#: FlatCAMApp.py:9472 msgid "Opening Gerber file." msgstr "Se incarcă un fişier Gerber." -#: FlatCAMApp.py:9096 -msgid "Open Gerber cancelled." -msgstr "Incărcarea unui fişier Gerber este anulată." - -#: FlatCAMApp.py:9117 FlatCAMApp.py:9121 flatcamGUI/FlatCAMGUI.py:769 -#: flatcamGUI/FlatCAMGUI.py:2354 +#: FlatCAMApp.py:9499 FlatCAMApp.py:9503 flatcamGUI/FlatCAMGUI.py:823 +#: flatcamGUI/FlatCAMGUI.py:2506 msgid "Open Excellon" msgstr "Încarcă Excellon" -#: FlatCAMApp.py:9127 +#: FlatCAMApp.py:9509 msgid "Opening Excellon file." msgstr "Se incarcă un fişier Excellon." -#: FlatCAMApp.py:9133 -msgid " Open Excellon cancelled." -msgstr " Incărcarea unui fişier Excellon este anulată." - -#: FlatCAMApp.py:9157 FlatCAMApp.py:9161 +#: FlatCAMApp.py:9540 FlatCAMApp.py:9544 msgid "Open G-Code" msgstr "Încarcă G-Code" -#: FlatCAMApp.py:9168 +#: FlatCAMApp.py:9551 msgid "Opening G-Code file." msgstr "Se incarcă un fişier G-Code." -#: FlatCAMApp.py:9174 -msgid "Open G-Code cancelled." -msgstr "Incărcarea unui fişier G-Code este anulată." - -#: FlatCAMApp.py:9192 FlatCAMApp.py:9195 flatcamGUI/FlatCAMGUI.py:1614 +#: FlatCAMApp.py:9574 FlatCAMApp.py:9577 flatcamGUI/FlatCAMGUI.py:1715 msgid "Open Project" msgstr "Încarcă Project" -#: FlatCAMApp.py:9204 -msgid "Open Project cancelled." -msgstr "Incărcarea unui fişier Proiect FlatCAM este anulată." - -#: FlatCAMApp.py:9228 FlatCAMApp.py:9232 +#: FlatCAMApp.py:9609 FlatCAMApp.py:9613 msgid "Open HPGL2" msgstr "Încarcă HPGL2" -#: FlatCAMApp.py:9239 +#: FlatCAMApp.py:9620 msgid "Opening HPGL2 file." msgstr "Se incarcă un fişier HPGL2." -#: FlatCAMApp.py:9244 -msgid "Open HPGL2 file cancelled." -msgstr "Incărcarea fișierului HPGL2 a fost anulată." - -#: FlatCAMApp.py:9262 FlatCAMApp.py:9265 +#: FlatCAMApp.py:9643 FlatCAMApp.py:9646 msgid "Open Configuration File" msgstr "Încarcă un fişier de Configurare" -#: FlatCAMApp.py:9270 -msgid "Open Config cancelled." -msgstr "Incărcarea unui fişier configurare FlatCAM este anulată." - -#: FlatCAMApp.py:9286 FlatCAMApp.py:9654 FlatCAMApp.py:10124 -#: FlatCAMApp.py:10128 -msgid "No object selected." -msgstr "Nici-un obiect nu este selectat." - -#: FlatCAMApp.py:9287 FlatCAMApp.py:9655 +#: FlatCAMApp.py:9666 FlatCAMApp.py:10015 msgid "Please Select a Geometry object to export" msgstr "Selectează un obiect Geometrie pentru export" -#: FlatCAMApp.py:9301 +#: FlatCAMApp.py:9680 msgid "Only Geometry, Gerber and CNCJob objects can be used." msgstr "Doar obiectele Geometrie, Gerber și CNCJob pot fi folosite." -#: FlatCAMApp.py:9314 FlatCAMApp.py:9318 flatcamTools/ToolQRCode.py:827 -#: flatcamTools/ToolQRCode.py:831 +#: FlatCAMApp.py:9693 FlatCAMApp.py:9697 flatcamTools/ToolQRCode.py:829 +#: flatcamTools/ToolQRCode.py:833 msgid "Export SVG" msgstr "Exporta SVG" -#: FlatCAMApp.py:9324 flatcamTools/ToolQRCode.py:836 -msgid " Export SVG cancelled." -msgstr " Exportul fisierului SVG a fost anulat." - -#: FlatCAMApp.py:9345 +#: FlatCAMApp.py:9723 msgid "Data must be a 3D array with last dimension 3 or 4" msgstr "" "Datele trebuie să fie organizate intr-o arie 3D cu ultima dimensiune cu " "valoarea 3 sau 4" -#: FlatCAMApp.py:9351 FlatCAMApp.py:9355 +#: FlatCAMApp.py:9729 FlatCAMApp.py:9733 msgid "Export PNG Image" msgstr "Exporta imagine PNG" -#: FlatCAMApp.py:9360 -msgid "Export PNG cancelled." -msgstr "Exportul imagine PNG este anulat." - -#: FlatCAMApp.py:9384 -msgid "No object selected. Please select an Gerber object to export." -msgstr "Nici-un obiect selectat. Selectează un obiect Gerber pentru export." - -#: FlatCAMApp.py:9390 FlatCAMApp.py:9613 +#: FlatCAMApp.py:9767 FlatCAMApp.py:9975 msgid "Failed. Only Gerber objects can be saved as Gerber files..." msgstr "Eșuat. Doar obiectele tip Gerber pot fi salvate ca fişiere Gerber..." -#: FlatCAMApp.py:9402 +#: FlatCAMApp.py:9779 msgid "Save Gerber source file" msgstr "Salvează codul sursa Gerber ca fişier" -#: FlatCAMApp.py:9408 -msgid "Save Gerber source file cancelled." -msgstr "Salvarea codului sursa Gerber este anulată." - -#: FlatCAMApp.py:9428 -msgid "No object selected. Please select an Script object to export." -msgstr "Nici-un obiect selectat. Selectează un obiect Script pentru export." - -#: FlatCAMApp.py:9434 +#: FlatCAMApp.py:9808 msgid "Failed. Only Script objects can be saved as TCL Script files..." msgstr "" "Eșuat. Doar obiectele tip Script pot fi salvate ca fişiere TCL Script..." -#: FlatCAMApp.py:9446 +#: FlatCAMApp.py:9820 msgid "Save Script source file" msgstr "Salvează codul sursa Script ca fişier" -#: FlatCAMApp.py:9452 -msgid "Save Script source file cancelled." -msgstr "Salvarea codului sursa Script este anulată." - -#: FlatCAMApp.py:9472 -msgid "No object selected. Please select an Document object to export." -msgstr "Nici-un obiect selectat. Selectează un obiect Document pentru export." - -#: FlatCAMApp.py:9478 +#: FlatCAMApp.py:9849 msgid "Failed. Only Document objects can be saved as Document files..." msgstr "" "Eșuat. Doar obiectele tip Document pot fi salvate ca fişiere Document ..." -#: FlatCAMApp.py:9490 +#: FlatCAMApp.py:9861 msgid "Save Document source file" msgstr "Salvează codul sursa Document ca fişier" -#: FlatCAMApp.py:9496 -msgid "Save Document source file cancelled." -msgstr "Salvarea codului sursa Document este anulată." - -#: FlatCAMApp.py:9516 -msgid "No object selected. Please select an Excellon object to export." -msgstr "Nici-un obiect selectat. Selectează un obiect Excellon pentru export." - -#: FlatCAMApp.py:9522 FlatCAMApp.py:9566 FlatCAMApp.py:10473 +#: FlatCAMApp.py:9890 FlatCAMApp.py:9931 FlatCAMApp.py:10856 msgid "Failed. Only Excellon objects can be saved as Excellon files..." msgstr "" "Eșuat. Doar obiectele tip Excellon pot fi salvate ca fişiere Excellon ..." -#: FlatCAMApp.py:9530 FlatCAMApp.py:9534 +#: FlatCAMApp.py:9898 FlatCAMApp.py:9902 msgid "Save Excellon source file" msgstr "Salvează codul sursa Excellon ca fişier" -#: FlatCAMApp.py:9540 -msgid "Saving Excellon source file cancelled." -msgstr "Salvarea codului sursa Excellon este anulată." - -#: FlatCAMApp.py:9560 -msgid "No object selected. Please Select an Excellon object to export." -msgstr "Nici-un obiect selectat. Selectează un obiect Excellon pentru export." - -#: FlatCAMApp.py:9574 FlatCAMApp.py:9578 +#: FlatCAMApp.py:9939 FlatCAMApp.py:9943 msgid "Export Excellon" msgstr "Exportă Excellon" -#: FlatCAMApp.py:9584 -msgid "Export Excellon cancelled." -msgstr "Exportul fișierului Excellon a fost anulat." - -#: FlatCAMApp.py:9607 -msgid "No object selected. Please Select an Gerber object to export." -msgstr "Nici-un obiect selectat. Selectează un obiect Gerber pentru export." - -#: FlatCAMApp.py:9621 FlatCAMApp.py:9625 +#: FlatCAMApp.py:9983 FlatCAMApp.py:9987 msgid "Export Gerber" msgstr "Exportă Gerber" -#: FlatCAMApp.py:9631 -msgid "Export Gerber cancelled." -msgstr "Exportul fișierului Gerber a fost anulat." - -#: FlatCAMApp.py:9666 +#: FlatCAMApp.py:10025 msgid "Only Geometry objects can be used." msgstr "Doar obiecte tip Geometrie pot fi folosite." -#: FlatCAMApp.py:9680 FlatCAMApp.py:9684 +#: FlatCAMApp.py:10039 FlatCAMApp.py:10043 msgid "Export DXF" msgstr "Exportă DXF" -#: FlatCAMApp.py:9691 -msgid "Export DXF cancelled." -msgstr "Exportul fișierului DXF a fost anulat." - -#: FlatCAMApp.py:9711 FlatCAMApp.py:9714 +#: FlatCAMApp.py:10068 FlatCAMApp.py:10071 msgid "Import SVG" msgstr "Importă SVG" -#: FlatCAMApp.py:9724 -msgid "Open SVG cancelled." -msgstr "Incărcarea fișierului SVG a fost anulată." - -#: FlatCAMApp.py:9743 FlatCAMApp.py:9747 +#: FlatCAMApp.py:10099 FlatCAMApp.py:10103 msgid "Import DXF" msgstr "Importa DXF" -#: FlatCAMApp.py:9757 -msgid "Open DXF cancelled." -msgstr "Incărcarea fișierului DXF a fost anulată." - -#: FlatCAMApp.py:9799 +#: FlatCAMApp.py:10154 msgid "Viewing the source code of the selected object." msgstr "Vizualizarea codului sursă a obiectului selectat." -#: FlatCAMApp.py:9800 FlatCAMObj.py:6495 FlatCAMObj.py:7225 +#: FlatCAMApp.py:10155 FlatCAMObj.py:7075 FlatCAMObj.py:7852 msgid "Loading..." msgstr "Se incarcă..." -#: FlatCAMApp.py:9806 FlatCAMApp.py:9810 +#: FlatCAMApp.py:10161 FlatCAMApp.py:10165 msgid "Select an Gerber or Excellon file to view it's source file." msgstr "Selectati un obiect Gerber sau Excellon pentru a-i vedea codul sursa." -#: FlatCAMApp.py:9824 +#: FlatCAMApp.py:10179 msgid "Source Editor" msgstr "Editor Cod Sursă" -#: FlatCAMApp.py:9864 FlatCAMApp.py:9871 +#: FlatCAMApp.py:10219 FlatCAMApp.py:10226 msgid "There is no selected object for which to see it's source file code." msgstr "Nici-un obiect selectat pentru a-i vedea codul sursa." -#: FlatCAMApp.py:9883 +#: FlatCAMApp.py:10238 msgid "Failed to load the source code for the selected object" msgstr "Codul sursă pentru obiectul selectat nu a putut fi încărcat" -#: FlatCAMApp.py:9925 +#: FlatCAMApp.py:10274 +msgid "Go to Line ..." +msgstr "Mergi la Linia ..." + +#: FlatCAMApp.py:10275 +msgid "Line:" +msgstr "Linia:" + +#: FlatCAMApp.py:10304 msgid "New TCL script file created in Code Editor." msgstr "Un nou script TCL a fost creat in Editorul de cod." -#: FlatCAMApp.py:9963 FlatCAMApp.py:9965 +#: FlatCAMApp.py:10343 FlatCAMApp.py:10345 msgid "Open TCL script" msgstr "Încarcă TCL script" -#: FlatCAMApp.py:9969 -msgid "Open TCL script cancelled." -msgstr "Incărcarea fisierului TCL script anulată." - -#: FlatCAMApp.py:9993 +#: FlatCAMApp.py:10373 msgid "Executing FlatCAMScript file." msgstr "Se executa un fisier script FlatCAM." -#: FlatCAMApp.py:10000 FlatCAMApp.py:10003 +#: FlatCAMApp.py:10381 FlatCAMApp.py:10384 msgid "Run TCL script" msgstr "Ruleaza TCL script" -#: FlatCAMApp.py:10013 -msgid "Run TCL script cancelled." -msgstr "Executarea fisierului Script a fost anulată." - -#: FlatCAMApp.py:10029 +#: FlatCAMApp.py:10408 msgid "TCL script file opened in Code Editor and executed." msgstr "Un fisier script TCL a fost deschis in Editorul de cod si executat." -#: FlatCAMApp.py:10080 FlatCAMApp.py:10086 +#: FlatCAMApp.py:10459 FlatCAMApp.py:10465 msgid "Save Project As ..." msgstr "Salvează Proiectul ca ..." -#: FlatCAMApp.py:10082 flatcamGUI/FlatCAMGUI.py:1051 -#: flatcamGUI/FlatCAMGUI.py:2053 +#: FlatCAMApp.py:10461 flatcamGUI/FlatCAMGUI.py:1119 +#: flatcamGUI/FlatCAMGUI.py:2161 msgid "Project" msgstr "Proiect" -#: FlatCAMApp.py:10091 -msgid "Save Project cancelled." -msgstr "Salvarea Proiect anulată." - -#: FlatCAMApp.py:10121 +#: FlatCAMApp.py:10500 msgid "FlatCAM objects print" msgstr "Tipărirea obiectelor FlatCAM" -#: FlatCAMApp.py:10134 FlatCAMApp.py:10141 +#: FlatCAMApp.py:10513 FlatCAMApp.py:10520 msgid "Save Object as PDF ..." msgstr "Salvați obiectul în format PDF ..." -#: FlatCAMApp.py:10146 -msgid "Save Object PDF cancelled." -msgstr "Salvarea obiectului PDF anulată." - -#: FlatCAMApp.py:10150 +#: FlatCAMApp.py:10529 msgid "Printing PDF ... Please wait." msgstr "Se tipărește PDF ... Vă rugăm să așteptați." -#: FlatCAMApp.py:10329 +#: FlatCAMApp.py:10708 msgid "PDF file saved to" msgstr "Fișierul PDF salvat în" -#: FlatCAMApp.py:10353 +#: FlatCAMApp.py:10733 msgid "Exporting SVG" msgstr "SVG in curs de export" -#: FlatCAMApp.py:10397 +#: FlatCAMApp.py:10776 msgid "SVG file exported to" msgstr "Fişier SVG exportat in" -#: FlatCAMApp.py:10422 +#: FlatCAMApp.py:10802 msgid "" "Save cancelled because source file is empty. Try to export the Gerber file." msgstr "" "Salvare anulată deoarece fișierul sursă este gol. Încercați să exportați " "fișierul Gerber." -#: FlatCAMApp.py:10568 +#: FlatCAMApp.py:10950 msgid "Excellon file exported to" msgstr "Fişierul Excellon exportat in" -#: FlatCAMApp.py:10577 +#: FlatCAMApp.py:10959 msgid "Exporting Excellon" msgstr "Excellon in curs de export" -#: FlatCAMApp.py:10583 FlatCAMApp.py:10591 +#: FlatCAMApp.py:10964 FlatCAMApp.py:10971 msgid "Could not export Excellon file." msgstr "Fişierul Excellon nu a fost posibil să fie exportat." -#: FlatCAMApp.py:10707 +#: FlatCAMApp.py:11087 msgid "Gerber file exported to" msgstr "Fişier Gerber exportat in" -#: FlatCAMApp.py:10715 +#: FlatCAMApp.py:11095 msgid "Exporting Gerber" msgstr "Gerber in curs de export" -#: FlatCAMApp.py:10721 FlatCAMApp.py:10729 +#: FlatCAMApp.py:11100 FlatCAMApp.py:11107 msgid "Could not export Gerber file." msgstr "Fişierul Gerber nu a fost posibil să fie exportat." -#: FlatCAMApp.py:10763 +#: FlatCAMApp.py:11142 msgid "DXF file exported to" msgstr "Fişierul DXF exportat in" -#: FlatCAMApp.py:10769 +#: FlatCAMApp.py:11148 msgid "Exporting DXF" msgstr "DXF in curs de export" -#: FlatCAMApp.py:10774 FlatCAMApp.py:10781 +#: FlatCAMApp.py:11153 FlatCAMApp.py:11160 msgid "Could not export DXF file." msgstr "Fişierul DXF nu a fost posibil să fie exportat." -#: FlatCAMApp.py:10804 FlatCAMApp.py:10847 flatcamTools/ToolImage.py:278 +#: FlatCAMApp.py:11183 FlatCAMApp.py:11225 flatcamTools/ToolImage.py:277 msgid "" "Not supported type is picked as parameter. Only Geometry and Gerber are " "supported" @@ -1317,80 +1280,80 @@ msgstr "" "Tipul parametrului nu este compatibil. Doar obiectele tip Geometrie si " "Gerber sunt acceptate" -#: FlatCAMApp.py:10814 +#: FlatCAMApp.py:11193 msgid "Importing SVG" msgstr "SVG in curs de ia fi importat" -#: FlatCAMApp.py:10825 FlatCAMApp.py:10867 FlatCAMApp.py:10926 -#: FlatCAMApp.py:10993 FlatCAMApp.py:11056 FlatCAMApp.py:11123 -#: FlatCAMApp.py:11161 flatcamTools/ToolImage.py:298 +#: FlatCAMApp.py:11204 FlatCAMApp.py:11244 FlatCAMApp.py:11302 +#: FlatCAMApp.py:11367 FlatCAMApp.py:11431 FlatCAMApp.py:11496 +#: FlatCAMApp.py:11533 flatcamTools/ToolImage.py:297 #: flatcamTools/ToolPDF.py:225 msgid "Opened" msgstr "Încarcat" -#: FlatCAMApp.py:10856 +#: FlatCAMApp.py:11234 msgid "Importing DXF" msgstr "DXF in curs de a fi importat" -#: FlatCAMApp.py:10892 FlatCAMApp.py:11082 +#: FlatCAMApp.py:11268 FlatCAMApp.py:11455 msgid "Failed to open file" msgstr "Eşec in incărcarea fişierului" -#: FlatCAMApp.py:10895 FlatCAMApp.py:11085 +#: FlatCAMApp.py:11271 FlatCAMApp.py:11458 msgid "Failed to parse file" msgstr "Parsarea fişierului a eșuat" -#: FlatCAMApp.py:10907 +#: FlatCAMApp.py:11283 msgid "Object is not Gerber file or empty. Aborting object creation." msgstr "" "Obiectul nu estetip Gerber sau este gol. Se anulează crearea obiectului." -#: FlatCAMApp.py:10912 +#: FlatCAMApp.py:11288 msgid "Opening Gerber" msgstr "Gerber in curs de incărcare" -#: FlatCAMApp.py:10919 +#: FlatCAMApp.py:11295 msgid " Open Gerber failed. Probable not a Gerber file." msgstr " Incărcarea Gerber a eșuat. Probabil nu este de tip Gerber." -#: FlatCAMApp.py:10951 flatcamTools/ToolPcbWizard.py:427 +#: FlatCAMApp.py:11326 flatcamTools/ToolPcbWizard.py:425 msgid "This is not Excellon file." msgstr "Acesta nu este un fişier Excellon." -#: FlatCAMApp.py:10955 +#: FlatCAMApp.py:11330 msgid "Cannot open file" msgstr "Nu se poate incărca fişierul" -#: FlatCAMApp.py:10975 flatcamTools/ToolPDF.py:275 -#: flatcamTools/ToolPcbWizard.py:451 +#: FlatCAMApp.py:11349 flatcamTools/ToolPDF.py:275 +#: flatcamTools/ToolPcbWizard.py:447 msgid "No geometry found in file" msgstr "Nici-o informaţie de tip geometrie nu s-a gasit in fişierul" -#: FlatCAMApp.py:10978 +#: FlatCAMApp.py:11352 msgid "Opening Excellon." msgstr "Excellon in curs de incărcare." -#: FlatCAMApp.py:10985 +#: FlatCAMApp.py:11359 msgid "Open Excellon file failed. Probable not an Excellon file." msgstr "Incărcarea Excellon a eșuat. Probabil nu este de tip Excellon." -#: FlatCAMApp.py:11016 +#: FlatCAMApp.py:11391 msgid "Reading GCode file" msgstr "Se citeşte un fişier G-Code" -#: FlatCAMApp.py:11023 +#: FlatCAMApp.py:11398 msgid "Failed to open" msgstr "A eșuat incărcarea fişierului" -#: FlatCAMApp.py:11031 +#: FlatCAMApp.py:11406 msgid "This is not GCODE" msgstr "Acest obiect nu este de tip GCode" -#: FlatCAMApp.py:11036 +#: FlatCAMApp.py:11411 msgid "Opening G-Code." msgstr "G-Code in curs de incărcare." -#: FlatCAMApp.py:11045 +#: FlatCAMApp.py:11420 msgid "" "Failed to create CNCJob Object. Probable not a GCode file. Try to load it " "from File menu.\n" @@ -1401,124 +1364,104 @@ msgstr "" "Încercați să-l încărcați din meniul Fișier. \n" "Incercarea de a crea un obiect CNCJob din G-Code a eșuat in timpul procesarii" -#: FlatCAMApp.py:11104 +#: FlatCAMApp.py:11477 msgid "Object is not HPGL2 file or empty. Aborting object creation." msgstr "" "Obiectul nu este fișier HPGL2 sau este gol. Se renunta la crearea obiectului." -#: FlatCAMApp.py:11109 +#: FlatCAMApp.py:11482 msgid "Opening HPGL2" msgstr "HPGL2 in curs de incărcare" -#: FlatCAMApp.py:11116 +#: FlatCAMApp.py:11489 msgid " Open HPGL2 failed. Probable not a HPGL2 file." msgstr " Incărcarea HPGL2 a eșuat. Probabil nu este de tip HPGL2 ." -#: FlatCAMApp.py:11137 +#: FlatCAMApp.py:11509 msgid "Opening TCL Script..." msgstr "Încarcă TCL script..." -#: FlatCAMApp.py:11145 +#: FlatCAMApp.py:11517 msgid "TCL script file opened in Code Editor." msgstr "S-a încărcat un script TCL în Editorul Cod." -#: FlatCAMApp.py:11148 +#: FlatCAMApp.py:11520 msgid "Failed to open TCL Script." msgstr "Eşec in incărcarea fişierului TCL." -#: FlatCAMApp.py:11176 +#: FlatCAMApp.py:11548 msgid "Opening FlatCAM Config file." msgstr "Se incarca un fişier FlatCAM de configurare." -#: FlatCAMApp.py:11204 +#: FlatCAMApp.py:11576 msgid "Failed to open config file" msgstr "Eşec in incărcarea fişierului de configurare" -#: FlatCAMApp.py:11230 +#: FlatCAMApp.py:11604 msgid "Loading Project ... Please Wait ..." msgstr "Se încarcă proiectul ... Vă rugăm să așteptați ..." -#: FlatCAMApp.py:11235 +#: FlatCAMApp.py:11609 msgid "Opening FlatCAM Project file." msgstr "Se incarca un fisier proiect FlatCAM." -#: FlatCAMApp.py:11245 FlatCAMApp.py:11263 +#: FlatCAMApp.py:11619 FlatCAMApp.py:11637 msgid "Failed to open project file" msgstr "Eşec in incărcarea fişierului proiect" -#: FlatCAMApp.py:11300 +#: FlatCAMApp.py:11674 msgid "Loading Project ... restoring" msgstr "Se încarcă proiectul ... se restabileste" -#: FlatCAMApp.py:11310 +#: FlatCAMApp.py:11684 msgid "Project loaded from" msgstr "Proiectul a fost incărcat din" -#: FlatCAMApp.py:11373 +#: FlatCAMApp.py:11753 msgid "Redrawing all objects" msgstr "Toate obiectele sunt reafisate" -#: FlatCAMApp.py:11405 -msgid "Available commands:\n" -msgstr "Comenzi disponibile:\n" - -#: FlatCAMApp.py:11407 -msgid "" -"\n" -"\n" -"Type help for usage.\n" -" Example: help open_gerber" -msgstr "" -"\n" -"\n" -"Introduceți help pentru utilizare.\n" -"Exemplu: help open_gerber" - -#: FlatCAMApp.py:11557 -msgid "Shows list of commands." -msgstr "Arata o lista de comenzi." - -#: FlatCAMApp.py:11619 +#: FlatCAMApp.py:11842 msgid "Failed to load recent item list." msgstr "Eşec in incărcarea listei cu fişiere recente." -#: FlatCAMApp.py:11627 +#: FlatCAMApp.py:11849 msgid "Failed to parse recent item list." msgstr "Eşec in parsarea listei cu fişiere recente." -#: FlatCAMApp.py:11638 +#: FlatCAMApp.py:11859 msgid "Failed to load recent projects item list." msgstr "Eşec in incărcarea listei cu proiecte recente." -#: FlatCAMApp.py:11646 +#: FlatCAMApp.py:11866 msgid "Failed to parse recent project item list." msgstr "Eşec in parsarea listei cu proiecte recente." -#: FlatCAMApp.py:11706 +#: FlatCAMApp.py:11927 msgid "Clear Recent projects" msgstr "Sterge Proiectele recente" -#: FlatCAMApp.py:11730 +#: FlatCAMApp.py:11951 msgid "Clear Recent files" msgstr "Sterge fişierele recente" -#: FlatCAMApp.py:11747 flatcamGUI/FlatCAMGUI.py:1276 +#: FlatCAMApp.py:11973 flatcamGUI/FlatCAMGUI.py:1348 msgid "Shortcut Key List" msgstr "Lista cu taste Shortcut" -#: FlatCAMApp.py:11821 +#: FlatCAMApp.py:12047 msgid "Selected Tab - Choose an Item from Project Tab" msgstr "Tab-ul Selectat - Alege un obiect din Tab-ul Proiect" -#: FlatCAMApp.py:11822 +#: FlatCAMApp.py:12048 msgid "Details" msgstr "Detalii" -#: FlatCAMApp.py:11824 +#: FlatCAMApp.py:12050 msgid "The normal flow when working in FlatCAM is the following:" msgstr "Fluxul normal cand se lucreaza in FlatCAM este urmatorul:" -#: FlatCAMApp.py:11825 +#: FlatCAMApp.py:12051 msgid "" "Load/Import a Gerber, Excellon, Gcode, DXF, Raster Image or SVG file into " "FlatCAM using either the toolbars, key shortcuts or even dragging and " @@ -1528,7 +1471,7 @@ msgstr "" "sau SVG în FlatCAM utilizând fie barele de instrumente, combinatii de taste " "sau chiar tragând fișierele în GUI." -#: FlatCAMApp.py:11828 +#: FlatCAMApp.py:12054 msgid "" "You can also load a FlatCAM project by double clicking on the project file, " "drag and drop of the file into the FLATCAM GUI or through the menu (or " @@ -1538,7 +1481,7 @@ msgstr "" "proiectului, tragând fișierul în fereastra FLATCAM sau prin icon-urile din " "meniu (sau din bara de instrumente) oferite în aplicație." -#: FlatCAMApp.py:11831 +#: FlatCAMApp.py:12057 msgid "" "Once an object is available in the Project Tab, by selecting it and then " "focusing on SELECTED TAB (more simpler is to double click the object name in " @@ -1551,7 +1494,7 @@ msgstr "" "proprietățile obiectului în funcție de tipul său: Gerber, Excellon, " "Geometrie sau obiect CNCJob." -#: FlatCAMApp.py:11835 +#: FlatCAMApp.py:12061 msgid "" "If the selection of the object is done on the canvas by single click " "instead, and the SELECTED TAB is in focus, again the object properties will " @@ -1565,14 +1508,14 @@ msgstr "" "de pe ecran va aduce fila SELECTAT și o va popula chiar dacă nu a fost in " "focus." -#: FlatCAMApp.py:11839 +#: FlatCAMApp.py:12065 msgid "" "You can change the parameters in this screen and the flow direction is like " "this:" msgstr "" "Se pot schimba parametrii in acest ecran si directia de executive este asa:" -#: FlatCAMApp.py:11840 +#: FlatCAMApp.py:12066 msgid "" "Gerber/Excellon Object --> Change Parameter --> Generate Geometry --> " "Geometry Object --> Add tools (change param in Selected Tab) --> Generate " @@ -1585,7 +1528,7 @@ msgstr "" "CNC) și / sau adăugați in fata / la final codul G-code (din nou, efectuat în " "fila SELECȚIONATĂ) -> Salvați codul G-code." -#: FlatCAMApp.py:11844 +#: FlatCAMApp.py:12070 msgid "" "A list of key shortcuts is available through an menu entry in Help --> " "Shortcuts List or through its own key shortcut: F3." @@ -1594,105 +1537,169 @@ msgstr "" "meniul Ajutor -> Lista de combinatii taste sau prin propria tasta asociata: " "F3." -#: FlatCAMApp.py:11906 +#: FlatCAMApp.py:12134 msgid "Failed checking for latest version. Could not connect." msgstr "" "Verificarea pentru ultima versiune a eșuat. Nu a fost posibilă conectarea la " "server." -#: FlatCAMApp.py:11914 +#: FlatCAMApp.py:12141 msgid "Could not parse information about latest version." msgstr "Informatia cu privire la ultima versiune nu s-a putut interpreta." -#: FlatCAMApp.py:11925 +#: FlatCAMApp.py:12151 msgid "FlatCAM is up to date!" msgstr "FlatCAM este la ultima versiune!" -#: FlatCAMApp.py:11930 +#: FlatCAMApp.py:12156 msgid "Newer Version Available" msgstr "O nouă versiune este disponibila" -#: FlatCAMApp.py:11931 -msgid "" -"There is a newer version of FlatCAM available for download:\n" -"\n" -msgstr "" -"O nouă versiune de FlatCAM este disponibilă pentru download::\n" -"\n" +#: FlatCAMApp.py:12158 +msgid "There is a newer version of FlatCAM available for download:" +msgstr "O nouă versiune de FlatCAM este disponibilă pentru download:" -#: FlatCAMApp.py:11933 +#: FlatCAMApp.py:12162 msgid "info" msgstr "informaţie" -#: FlatCAMApp.py:12012 +#: FlatCAMApp.py:12190 +msgid "" +"OpenGL canvas initialization failed. HW or HW configuration not supported." +"Change the graphic engine to Legacy(2D) in Edit -> Preferences -> General " +"tab.\n" +"\n" +msgstr "" +"Iniţializarea motorului grafic OpenGL a eşuat. HW sau configurarea HW nu " +"este acceptat(ă). Schimbă motorul grafic in Legacy(2D) in Editare -> " +"Preferinţe -> General\n" +"\n" + +#: FlatCAMApp.py:12269 msgid "All plots disabled." msgstr "Toate afişările sunt dezactivate." -#: FlatCAMApp.py:12019 +#: FlatCAMApp.py:12276 msgid "All non selected plots disabled." msgstr "Toate afişările care nu sunt selectate sunt dezactivate." -#: FlatCAMApp.py:12026 +#: FlatCAMApp.py:12283 msgid "All plots enabled." msgstr "Toate afişările sunt activate." -#: FlatCAMApp.py:12033 +#: FlatCAMApp.py:12289 msgid "Selected plots enabled..." msgstr "Toate afişările selectate sunt activate..." -#: FlatCAMApp.py:12042 +#: FlatCAMApp.py:12297 msgid "Selected plots disabled..." msgstr "Toate afişările selectate sunt dezactivate..." -#: FlatCAMApp.py:12061 +#: FlatCAMApp.py:12330 msgid "Enabling plots ..." msgstr "Activează Afișare ..." -#: FlatCAMApp.py:12101 +#: FlatCAMApp.py:12382 msgid "Disabling plots ..." msgstr "Dezactivează Afișare ..." -#: FlatCAMApp.py:12123 +#: FlatCAMApp.py:12405 msgid "Working ..." msgstr "Se lucrează..." -#: FlatCAMApp.py:12224 +#: FlatCAMApp.py:12460 flatcamGUI/FlatCAMGUI.py:688 +msgid "Red" +msgstr "Roșu" + +#: FlatCAMApp.py:12462 flatcamGUI/FlatCAMGUI.py:691 +msgid "Blue" +msgstr "Albastru" + +#: FlatCAMApp.py:12465 flatcamGUI/FlatCAMGUI.py:694 +msgid "Yellow" +msgstr "Galben" + +#: FlatCAMApp.py:12467 flatcamGUI/FlatCAMGUI.py:697 +msgid "Green" +msgstr "Verde" + +#: FlatCAMApp.py:12469 flatcamGUI/FlatCAMGUI.py:700 +msgid "Purple" +msgstr "Violet" + +#: FlatCAMApp.py:12471 flatcamGUI/FlatCAMGUI.py:703 +msgid "Brown" +msgstr "Maro" + +#: FlatCAMApp.py:12473 FlatCAMApp.py:12529 flatcamGUI/FlatCAMGUI.py:706 +msgid "White" +msgstr "Alb" + +#: FlatCAMApp.py:12475 flatcamGUI/FlatCAMGUI.py:709 +msgid "Black" +msgstr "Negru" + +#: FlatCAMApp.py:12478 flatcamGUI/FlatCAMGUI.py:714 +msgid "Custom" +msgstr "Personalizat" + +#: FlatCAMApp.py:12488 flatcamGUI/FlatCAMGUI.py:722 +msgid "Default" +msgstr "Implicit" + +#: FlatCAMApp.py:12512 flatcamGUI/FlatCAMGUI.py:719 +msgid "Opacity" +msgstr "Opacitate" + +#: FlatCAMApp.py:12514 +msgid "Set alpha level ..." +msgstr "Setează transparenta ..." + +#: FlatCAMApp.py:12514 flatcamGUI/PreferencesUI.py:6900 +#: flatcamGUI/PreferencesUI.py:8230 flatcamGUI/PreferencesUI.py:8444 +#: flatcamTools/ToolExtractDrills.py:164 flatcamTools/ToolExtractDrills.py:285 +#: flatcamTools/ToolPunchGerber.py:192 flatcamTools/ToolPunchGerber.py:308 +#: flatcamTools/ToolTransform.py:358 +msgid "Value" +msgstr "Valoare" + +#: FlatCAMApp.py:12590 msgid "Saving FlatCAM Project" msgstr "Proiectul FlatCAM este in curs de salvare" -#: FlatCAMApp.py:12243 FlatCAMApp.py:12280 +#: FlatCAMApp.py:12611 FlatCAMApp.py:12647 msgid "Project saved to" msgstr "Proiectul s-a salvat in" -#: FlatCAMApp.py:12250 +#: FlatCAMApp.py:12618 msgid "The object is used by another application." msgstr "Obiectul este folosit de o altă aplicație." -#: FlatCAMApp.py:12264 +#: FlatCAMApp.py:12632 msgid "Failed to verify project file" msgstr "Eşec in incărcarea fişierului proiect" -#: FlatCAMApp.py:12264 FlatCAMApp.py:12272 FlatCAMApp.py:12283 +#: FlatCAMApp.py:12632 FlatCAMApp.py:12640 FlatCAMApp.py:12650 msgid "Retry to save it." msgstr "Încercați din nou pentru a-l salva." -#: FlatCAMApp.py:12272 FlatCAMApp.py:12283 +#: FlatCAMApp.py:12640 FlatCAMApp.py:12650 msgid "Failed to parse saved project file" msgstr "Esec in analizarea fişierului Proiect" -#: FlatCAMApp.py:12398 +#: FlatCAMApp.py:13132 msgid "The user requested a graceful exit of the current task." msgstr "Utilizatorul a solicitat o inchidere grațioasă a taskului curent." -#: FlatCAMCommon.py:136 FlatCAMCommon.py:163 +#: FlatCAMCommon.py:137 FlatCAMCommon.py:164 msgid "Title" msgstr "Titlu" -#: FlatCAMCommon.py:137 FlatCAMCommon.py:167 +#: FlatCAMCommon.py:138 FlatCAMCommon.py:168 msgid "Web Link" msgstr "Website" -#: FlatCAMCommon.py:141 +#: FlatCAMCommon.py:142 msgid "" "Index.\n" "The rows in gray color will populate the Bookmarks menu.\n" @@ -1702,7 +1709,7 @@ msgstr "" "Rândurile în culoare gri vor fi adăugate in meniul de Bookmarks.\n" "Numărul de rânduri colorate gri este setat în Preferințe." -#: FlatCAMCommon.py:145 +#: FlatCAMCommon.py:146 msgid "" "Description of the link that is set as an menu action.\n" "Try to keep it short because it is installed as a menu item." @@ -1710,95 +1717,87 @@ msgstr "" "Descrierea Website care este setată ca acțiune de meniu.\n" "Încercați să o mențineți scurtă, deoarece este instalată ca element de meniu." -#: FlatCAMCommon.py:148 +#: FlatCAMCommon.py:149 msgid "Web Link. E.g: https://your_website.org " msgstr "Website. De ex: https://your_website.org " -#: FlatCAMCommon.py:157 +#: FlatCAMCommon.py:158 msgid "New Bookmark" msgstr "Bookmark Nou" -#: FlatCAMCommon.py:176 +#: FlatCAMCommon.py:177 msgid "Add Entry" msgstr "Adaugă Intrare" -#: FlatCAMCommon.py:177 +#: FlatCAMCommon.py:178 msgid "Remove Entry" msgstr "Elimina Intrare" -#: FlatCAMCommon.py:178 +#: FlatCAMCommon.py:179 msgid "Export List" msgstr "Exportă lista" -#: FlatCAMCommon.py:179 +#: FlatCAMCommon.py:180 msgid "Import List" msgstr "Importă lista" -#: FlatCAMCommon.py:260 +#: FlatCAMCommon.py:261 msgid "Title entry is empty." msgstr "Caseta de introducere Titlu este goală." -#: FlatCAMCommon.py:269 +#: FlatCAMCommon.py:270 msgid "Web link entry is empty." msgstr "Caseta de introducere a link-ului web este goală." -#: FlatCAMCommon.py:277 +#: FlatCAMCommon.py:278 msgid "Either the Title or the Weblink already in the table." msgstr "Fie Titlul, fie Weblink-ul deja sunt in tabel." -#: FlatCAMCommon.py:297 +#: FlatCAMCommon.py:298 msgid "Bookmark added." msgstr "Bookmark adăugat." -#: FlatCAMCommon.py:314 +#: FlatCAMCommon.py:315 msgid "This bookmark can not be removed" msgstr "Acest bookmark nu poate fi eliminat" -#: FlatCAMCommon.py:345 +#: FlatCAMCommon.py:346 msgid "Bookmark removed." msgstr "Bookmark-ul a fost eliminat." -#: FlatCAMCommon.py:360 +#: FlatCAMCommon.py:361 msgid "Export FlatCAM Bookmarks" msgstr "Exportați bookmark-urile FlatCAM" -#: FlatCAMCommon.py:363 flatcamGUI/FlatCAMGUI.py:470 +#: FlatCAMCommon.py:364 flatcamGUI/FlatCAMGUI.py:509 msgid "Bookmarks" msgstr "Bookmarks" -#: FlatCAMCommon.py:370 -msgid "FlatCAM bookmarks export cancelled." -msgstr "Exportul de bookmark-uri FlatCAM este anulat." - -#: FlatCAMCommon.py:389 FlatCAMCommon.py:419 +#: FlatCAMCommon.py:390 FlatCAMCommon.py:420 msgid "Could not load bookmarks file." msgstr "Nu am putut incărca fişierul cu bookmark-uri." -#: FlatCAMCommon.py:399 +#: FlatCAMCommon.py:400 msgid "Failed to write bookmarks to file." msgstr "Salvarea bookmark-urilor intr-un fişier a eșuat." -#: FlatCAMCommon.py:401 +#: FlatCAMCommon.py:402 msgid "Exported bookmarks to" msgstr "Exportă Bookmark-uri in" -#: FlatCAMCommon.py:407 +#: FlatCAMCommon.py:408 msgid "Import FlatCAM Bookmarks" msgstr "Importă Bookmark-uri FlatCAM" -#: FlatCAMCommon.py:412 -msgid "FlatCAM bookmarks import cancelled." -msgstr "Importul de Bookmark-uri FlatCAM a eșuat." - -#: FlatCAMCommon.py:426 +#: FlatCAMCommon.py:427 msgid "Imported Bookmarks from" msgstr "Bookmark-uri au fost importate din" -#: FlatCAMCommon.py:529 +#: FlatCAMCommon.py:530 msgid "Add Geometry Tool in DB" msgstr "Adăugați Unealta de Geometrie în DB" -#: FlatCAMCommon.py:531 +#: FlatCAMCommon.py:532 FlatCAMCommon.py:2087 msgid "" "Add a new tool in the Tools Database.\n" "It will be used in the Geometry UI.\n" @@ -1808,35 +1807,35 @@ msgstr "" "Acesta va fi utilizată în UI de Geometrie.\n" "O puteți edita după ce este adăugată." -#: FlatCAMCommon.py:545 +#: FlatCAMCommon.py:546 FlatCAMCommon.py:2101 msgid "Delete Tool from DB" msgstr "Ștergeți unealta din DB" -#: FlatCAMCommon.py:547 +#: FlatCAMCommon.py:548 FlatCAMCommon.py:2103 msgid "Remove a selection of tools in the Tools Database." msgstr "Stergeți o selecție de Unelte din baza de date Unelte." -#: FlatCAMCommon.py:551 +#: FlatCAMCommon.py:552 FlatCAMCommon.py:2107 msgid "Export DB" msgstr "Exportă DB" -#: FlatCAMCommon.py:553 +#: FlatCAMCommon.py:554 FlatCAMCommon.py:2109 msgid "Save the Tools Database to a custom text file." msgstr "Salvați baza de date Unelte într-un fișier text." -#: FlatCAMCommon.py:557 +#: FlatCAMCommon.py:558 FlatCAMCommon.py:2113 msgid "Import DB" msgstr "Importă DB" -#: FlatCAMCommon.py:559 +#: FlatCAMCommon.py:560 FlatCAMCommon.py:2115 msgid "Load the Tools Database information's from a custom text file." msgstr "Încărcați informațiile din baza de date Unelte dintr-un fișier text." -#: FlatCAMCommon.py:563 +#: FlatCAMCommon.py:564 FlatCAMCommon.py:2119 msgid "Add Tool from Tools DB" msgstr "Adăugați Unealta din DB Unelte" -#: FlatCAMCommon.py:565 +#: FlatCAMCommon.py:566 FlatCAMCommon.py:2121 msgid "" "Add a new tool in the Tools Table of the\n" "active Geometry object after selecting a tool\n" @@ -1846,135 +1845,144 @@ msgstr "" "obiectul Geometrie activ după selectarea unei Unelte\n" "în baza de date Unelte." -#: FlatCAMCommon.py:601 FlatCAMCommon.py:1276 +#: FlatCAMCommon.py:602 FlatCAMCommon.py:1277 FlatCAMCommon.py:1531 msgid "Tool Name" msgstr "Nume unealtă" -#: FlatCAMCommon.py:602 FlatCAMCommon.py:1278 -#: flatcamEditors/FlatCAMExcEditor.py:1602 flatcamGUI/ObjectUI.py:1295 -#: flatcamTools/ToolNonCopperClear.py:271 flatcamTools/ToolPaint.py:176 +#: FlatCAMCommon.py:603 FlatCAMCommon.py:1279 FlatCAMCommon.py:1544 +#: flatcamEditors/FlatCAMExcEditor.py:1605 flatcamGUI/ObjectUI.py:1343 +#: flatcamGUI/ObjectUI.py:1581 flatcamGUI/PreferencesUI.py:5971 +#: flatcamTools/ToolNCC.py:278 flatcamTools/ToolNCC.py:287 +#: flatcamTools/ToolPaint.py:261 msgid "Tool Dia" msgstr "Dia Unealtă" -#: FlatCAMCommon.py:603 FlatCAMCommon.py:1280 flatcamGUI/ObjectUI.py:1278 +#: FlatCAMCommon.py:604 FlatCAMCommon.py:1281 FlatCAMCommon.py:1725 +#: flatcamGUI/ObjectUI.py:1556 msgid "Tool Offset" msgstr "Ofset unealtă" -#: FlatCAMCommon.py:604 FlatCAMCommon.py:1282 +#: FlatCAMCommon.py:605 FlatCAMCommon.py:1283 FlatCAMCommon.py:1742 msgid "Custom Offset" -msgstr "Ofset personal." +msgstr "Ofset Personalizat" -#: FlatCAMCommon.py:605 FlatCAMCommon.py:1284 flatcamGUI/ObjectUI.py:304 -#: flatcamGUI/PreferencesUI.py:2217 flatcamGUI/PreferencesUI.py:5036 -#: flatcamTools/ToolNonCopperClear.py:213 +#: FlatCAMCommon.py:606 FlatCAMCommon.py:1285 FlatCAMCommon.py:1709 +#: flatcamGUI/ObjectUI.py:308 flatcamGUI/PreferencesUI.py:2397 +#: flatcamGUI/PreferencesUI.py:5332 flatcamGUI/PreferencesUI.py:5901 +#: flatcamGUI/PreferencesUI.py:5911 flatcamTools/ToolNCC.py:213 +#: flatcamTools/ToolNCC.py:227 flatcamTools/ToolPaint.py:196 msgid "Tool Type" msgstr "Tip Unealtă" -#: FlatCAMCommon.py:606 FlatCAMCommon.py:1286 +#: FlatCAMCommon.py:607 FlatCAMCommon.py:1287 FlatCAMCommon.py:1557 msgid "Tool Shape" msgstr "Formă unealtă" -#: FlatCAMCommon.py:607 FlatCAMCommon.py:1289 flatcamGUI/ObjectUI.py:345 -#: flatcamGUI/ObjectUI.py:820 flatcamGUI/ObjectUI.py:1405 -#: flatcamGUI/ObjectUI.py:1926 flatcamGUI/PreferencesUI.py:2257 -#: flatcamGUI/PreferencesUI.py:3082 flatcamGUI/PreferencesUI.py:3961 -#: flatcamGUI/PreferencesUI.py:5081 flatcamGUI/PreferencesUI.py:5327 -#: flatcamGUI/PreferencesUI.py:6145 flatcamTools/ToolCalculators.py:114 -#: flatcamTools/ToolCutOut.py:132 flatcamTools/ToolNonCopperClear.py:254 +#: FlatCAMCommon.py:608 FlatCAMCommon.py:1290 FlatCAMCommon.py:1573 +#: flatcamGUI/ObjectUI.py:349 flatcamGUI/ObjectUI.py:899 +#: flatcamGUI/ObjectUI.py:1701 flatcamGUI/ObjectUI.py:2254 +#: flatcamGUI/PreferencesUI.py:2437 flatcamGUI/PreferencesUI.py:3311 +#: flatcamGUI/PreferencesUI.py:4241 flatcamGUI/PreferencesUI.py:5377 +#: flatcamGUI/PreferencesUI.py:5666 flatcamGUI/PreferencesUI.py:5944 +#: flatcamGUI/PreferencesUI.py:5952 flatcamGUI/PreferencesUI.py:6635 +#: flatcamTools/ToolCalculators.py:114 flatcamTools/ToolCutOut.py:139 +#: flatcamTools/ToolNCC.py:260 flatcamTools/ToolNCC.py:268 +#: flatcamTools/ToolPaint.py:243 msgid "Cut Z" msgstr "Z tăiere" -#: FlatCAMCommon.py:608 FlatCAMCommon.py:1291 +#: FlatCAMCommon.py:609 FlatCAMCommon.py:1292 FlatCAMCommon.py:1587 msgid "MultiDepth" msgstr "Multi-Pas" -#: FlatCAMCommon.py:609 FlatCAMCommon.py:1293 +#: FlatCAMCommon.py:610 FlatCAMCommon.py:1294 FlatCAMCommon.py:1600 msgid "DPP" msgstr "DPP" -#: FlatCAMCommon.py:610 FlatCAMCommon.py:1295 +#: FlatCAMCommon.py:611 FlatCAMCommon.py:1296 FlatCAMCommon.py:1756 msgid "V-Dia" msgstr "V-Dia" -#: FlatCAMCommon.py:611 FlatCAMCommon.py:1297 +#: FlatCAMCommon.py:612 FlatCAMCommon.py:1298 FlatCAMCommon.py:1770 msgid "V-Angle" msgstr "V-Unghi" -#: FlatCAMCommon.py:612 FlatCAMCommon.py:1299 flatcamGUI/ObjectUI.py:839 -#: flatcamGUI/ObjectUI.py:1452 flatcamGUI/PreferencesUI.py:3100 -#: flatcamGUI/PreferencesUI.py:4014 flatcamGUI/PreferencesUI.py:7535 +#: FlatCAMCommon.py:613 FlatCAMCommon.py:1300 FlatCAMCommon.py:1614 +#: FlatCAMObj.py:3661 FlatCAMObj.py:5486 flatcamGUI/ObjectUI.py:945 +#: flatcamGUI/ObjectUI.py:1748 flatcamGUI/PreferencesUI.py:3352 +#: flatcamGUI/PreferencesUI.py:4294 flatcamGUI/PreferencesUI.py:8041 #: flatcamTools/ToolCalibration.py:74 msgid "Travel Z" msgstr "Z Deplasare" -#: FlatCAMCommon.py:613 FlatCAMCommon.py:1301 +#: FlatCAMCommon.py:614 FlatCAMCommon.py:1302 msgid "FR" msgstr "Feedrate" -#: FlatCAMCommon.py:614 FlatCAMCommon.py:1303 +#: FlatCAMCommon.py:615 FlatCAMCommon.py:1304 msgid "FR Z" msgstr "Z feedrate" -#: FlatCAMCommon.py:615 FlatCAMCommon.py:1305 +#: FlatCAMCommon.py:616 FlatCAMCommon.py:1306 FlatCAMCommon.py:1784 msgid "FR Rapids" msgstr "Feedrate rapizi" -#: FlatCAMCommon.py:616 FlatCAMCommon.py:1307 flatcamGUI/PreferencesUI.py:3173 +#: FlatCAMCommon.py:617 FlatCAMCommon.py:1308 FlatCAMCommon.py:1657 +#: flatcamGUI/PreferencesUI.py:3440 msgid "Spindle Speed" msgstr "Viteza Motor" -#: FlatCAMCommon.py:617 FlatCAMCommon.py:1309 flatcamGUI/ObjectUI.py:963 -#: flatcamGUI/ObjectUI.py:1619 +#: FlatCAMCommon.py:618 FlatCAMCommon.py:1310 FlatCAMCommon.py:1672 +#: flatcamGUI/ObjectUI.py:1063 flatcamGUI/ObjectUI.py:1855 msgid "Dwell" msgstr "Pauza" -#: FlatCAMCommon.py:618 FlatCAMCommon.py:1311 +#: FlatCAMCommon.py:619 FlatCAMCommon.py:1312 FlatCAMCommon.py:1685 msgid "Dwelltime" msgstr "Durata pauza" -#: FlatCAMCommon.py:619 FlatCAMCommon.py:1313 flatcamGUI/ObjectUI.py:982 -#: flatcamGUI/ObjectUI.py:1640 flatcamGUI/PreferencesUI.py:3204 -#: flatcamGUI/PreferencesUI.py:4155 flatcamGUI/PreferencesUI.py:6642 -#: flatcamTools/ToolSolderPaste.py:334 +#: FlatCAMCommon.py:620 FlatCAMCommon.py:1314 flatcamGUI/ObjectUI.py:2012 +#: flatcamGUI/PreferencesUI.py:3475 flatcamGUI/PreferencesUI.py:4447 +#: flatcamGUI/PreferencesUI.py:7148 flatcamTools/ToolSolderPaste.py:336 msgid "Preprocessor" msgstr "Postprocesor" -#: FlatCAMCommon.py:620 FlatCAMCommon.py:1315 +#: FlatCAMCommon.py:621 FlatCAMCommon.py:1316 FlatCAMCommon.py:1800 msgid "ExtraCut" msgstr "Extra taiere" -#: FlatCAMCommon.py:621 FlatCAMCommon.py:1317 +#: FlatCAMCommon.py:622 FlatCAMCommon.py:1318 FlatCAMCommon.py:1815 msgid "E-Cut Length" msgstr "Lungime E-taiere" -#: FlatCAMCommon.py:622 FlatCAMCommon.py:1319 +#: FlatCAMCommon.py:623 FlatCAMCommon.py:1320 msgid "Toolchange" msgstr "Schimb unealtă" -#: FlatCAMCommon.py:623 FlatCAMCommon.py:1321 +#: FlatCAMCommon.py:624 FlatCAMCommon.py:1322 msgid "Toolchange XY" msgstr "X,Y schimb unealtă" -#: FlatCAMCommon.py:624 FlatCAMCommon.py:1323 flatcamGUI/PreferencesUI.py:3124 -#: flatcamGUI/PreferencesUI.py:4044 flatcamGUI/PreferencesUI.py:7572 +#: FlatCAMCommon.py:625 FlatCAMCommon.py:1324 flatcamGUI/PreferencesUI.py:3378 +#: flatcamGUI/PreferencesUI.py:4324 flatcamGUI/PreferencesUI.py:8078 #: flatcamTools/ToolCalibration.py:111 msgid "Toolchange Z" msgstr "Z schimb. unealtă" -#: FlatCAMCommon.py:625 FlatCAMCommon.py:1325 flatcamGUI/ObjectUI.py:886 -#: flatcamGUI/PreferencesUI.py:3309 flatcamGUI/PreferencesUI.py:4200 +#: FlatCAMCommon.py:626 FlatCAMCommon.py:1326 flatcamGUI/ObjectUI.py:1192 +#: flatcamGUI/PreferencesUI.py:3586 flatcamGUI/PreferencesUI.py:4493 msgid "Start Z" msgstr "Z Start" -#: FlatCAMCommon.py:626 FlatCAMCommon.py:1328 +#: FlatCAMCommon.py:627 FlatCAMCommon.py:1329 msgid "End Z" msgstr "Z Oprire" -#: FlatCAMCommon.py:630 +#: FlatCAMCommon.py:631 msgid "Tool Index." msgstr "Index unealta." -#: FlatCAMCommon.py:632 +#: FlatCAMCommon.py:633 FlatCAMCommon.py:1533 msgid "" "Tool name.\n" "This is not used in the app, it's function\n" @@ -1984,11 +1992,11 @@ msgstr "" "Aceasta nu este folosită în aplicație, funcția sa\n" "este să servească drept notă pentru utilizator." -#: FlatCAMCommon.py:636 +#: FlatCAMCommon.py:637 FlatCAMCommon.py:1546 msgid "Tool Diameter." msgstr "Diametru unealtă." -#: FlatCAMCommon.py:638 +#: FlatCAMCommon.py:639 FlatCAMCommon.py:1727 msgid "" "Tool Offset.\n" "Can be of a few types:\n" @@ -2004,7 +2012,7 @@ msgstr "" "Exterior = compensat în exterior cu jumătate din diametrul sculei\n" "Custom = compensare personalizată folosind valoarea Offset personalizat" -#: FlatCAMCommon.py:645 +#: FlatCAMCommon.py:646 FlatCAMCommon.py:1744 msgid "" "Custom Offset.\n" "A value to be used as offset from the current path." @@ -2012,7 +2020,7 @@ msgstr "" "Ofset personalizat.\n" "O valoare care trebuie utilizată ca compensare din Calea curentă." -#: FlatCAMCommon.py:648 +#: FlatCAMCommon.py:649 FlatCAMCommon.py:1711 msgid "" "Tool Type.\n" "Can be:\n" @@ -2026,7 +2034,7 @@ msgstr "" "Aspră = tăietură aspră, viteză scăzută, treceri multiple\n" "Finisare = tăiere de finisare, avans mare" -#: FlatCAMCommon.py:654 +#: FlatCAMCommon.py:655 FlatCAMCommon.py:1559 msgid "" "Tool Shape. \n" "Can be:\n" @@ -2040,7 +2048,7 @@ msgstr "" "B = instrument de frezare cu vârf formal bila\n" "V = instrument de frezare în formă V" -#: FlatCAMCommon.py:660 +#: FlatCAMCommon.py:661 FlatCAMCommon.py:1575 msgid "" "Cutting Depth.\n" "The depth at which to cut into material." @@ -2048,7 +2056,7 @@ msgstr "" "Adâncimea de tăiere.\n" "Adâncimea la care se taie în material." -#: FlatCAMCommon.py:663 +#: FlatCAMCommon.py:664 FlatCAMCommon.py:1589 msgid "" "Multi Depth.\n" "Selecting this will allow cutting in multiple passes,\n" @@ -2058,7 +2066,7 @@ msgstr "" "Selectarea acestui lucru va permite tăierea în mai multe treceri,\n" "fiecare trecere adăugând o adâncime a parametrului DPP." -#: FlatCAMCommon.py:667 +#: FlatCAMCommon.py:668 FlatCAMCommon.py:1602 msgid "" "DPP. Depth per Pass.\n" "The value used to cut into material on each pass." @@ -2066,7 +2074,7 @@ msgstr "" "DPP. Adâncimea pe trecere.\n" "Valoarea folosită pentru a tăia în material la fiecare trecere." -#: FlatCAMCommon.py:670 +#: FlatCAMCommon.py:671 FlatCAMCommon.py:1758 msgid "" "V-Dia.\n" "Diameter of the tip for V-Shape Tools." @@ -2074,7 +2082,7 @@ msgstr "" "V-Dia.\n" "Diametrul vârfului pentru uneltele în formă de V." -#: FlatCAMCommon.py:673 +#: FlatCAMCommon.py:674 FlatCAMCommon.py:1772 msgid "" "V-Agle.\n" "Angle at the tip for the V-Shape Tools." @@ -2082,7 +2090,7 @@ msgstr "" "V-Unghi.\n" "Unghiul în vârf pentru instrumentele în formă de V." -#: FlatCAMCommon.py:676 +#: FlatCAMCommon.py:677 FlatCAMCommon.py:1616 msgid "" "Clearance Height.\n" "Height at which the milling bit will travel between cuts,\n" @@ -2092,7 +2100,7 @@ msgstr "" "Înălțimea la care bitul de frezare va călători între tăieturi,\n" "deasupra suprafeței materialului, evitând toate accesoriile." -#: FlatCAMCommon.py:680 +#: FlatCAMCommon.py:681 msgid "" "FR. Feedrate\n" "The speed on XY plane used while cutting into material." @@ -2100,7 +2108,7 @@ msgstr "" "FR. Avans.\n" "Viteza pe planul XY utilizat la tăierea în material." -#: FlatCAMCommon.py:683 +#: FlatCAMCommon.py:684 msgid "" "FR Z. Feedrate Z\n" "The speed on Z plane." @@ -2108,7 +2116,7 @@ msgstr "" "FR Z. Feedrate Z. Avans Z.\n" "Viteza de deplasare in planul Z." -#: FlatCAMCommon.py:686 +#: FlatCAMCommon.py:687 FlatCAMCommon.py:1786 msgid "" "FR Rapids. Feedrate Rapids\n" "Speed used while moving as fast as possible.\n" @@ -2120,7 +2128,7 @@ msgstr "" "Acesta este folosit doar de unele dispozitive in care nu poate fi utilizata\n" "comanda G-cod G0. În mare parte este vorda de imprimante 3D." -#: FlatCAMCommon.py:691 +#: FlatCAMCommon.py:692 FlatCAMCommon.py:1659 msgid "" "Spindle Speed.\n" "If it's left empty it will not be used.\n" @@ -2130,7 +2138,7 @@ msgstr "" "Dacă este lăsat gol, nu va fi folosit.\n" "Viteza rotorului în RPM." -#: FlatCAMCommon.py:695 +#: FlatCAMCommon.py:696 FlatCAMCommon.py:1674 msgid "" "Dwell.\n" "Check this if a delay is needed to allow\n" @@ -2140,7 +2148,7 @@ msgstr "" "Verificați dacă este necesară o întârziere pentru a permite\n" "motorului sa ajungă la viteza setată." -#: FlatCAMCommon.py:699 +#: FlatCAMCommon.py:700 FlatCAMCommon.py:1687 msgid "" "Dwell Time.\n" "A delay used to allow the motor spindle reach it's set speed." @@ -2148,7 +2156,7 @@ msgstr "" "Durata pauzei.\n" "O întârziere pentru a permite motorului sa ajungă la viteza setată." -#: FlatCAMCommon.py:702 +#: FlatCAMCommon.py:703 msgid "" "Preprocessor.\n" "A selection of files that will alter the generated G-code\n" @@ -2158,7 +2166,7 @@ msgstr "" "O selecție de fișiere care vor modifica codul G generat\n" "pentru a se potrivi pentru o serie de cazuri de utilizare." -#: FlatCAMCommon.py:706 +#: FlatCAMCommon.py:707 FlatCAMCommon.py:1802 msgid "" "Extra Cut.\n" "If checked, after a isolation is finished an extra cut\n" @@ -2172,7 +2180,7 @@ msgstr "" "astfel că acest punct este acoperit de aceste tăieri suplimentare si\n" "asigură o izolare completă." -#: FlatCAMCommon.py:712 +#: FlatCAMCommon.py:713 FlatCAMCommon.py:1817 msgid "" "Extra Cut length.\n" "If checked, after a isolation is finished an extra cut\n" @@ -2187,7 +2195,7 @@ msgstr "" "astfel că acest punct este acoperit de aceste tăieri suplimentare si\n" "asigură o izolare completă." -#: FlatCAMCommon.py:719 +#: FlatCAMCommon.py:720 msgid "" "Toolchange.\n" "It will create a toolchange event.\n" @@ -2199,7 +2207,7 @@ msgstr "" "Tipul schimbului de unelte este determinat de\n" "fișierul preprocesor." -#: FlatCAMCommon.py:724 +#: FlatCAMCommon.py:725 msgid "" "Toolchange XY.\n" "A set of coordinates in the format (x, y).\n" @@ -2211,7 +2219,7 @@ msgstr "" "Va determina poziția carteziană a punctului\n" "unde are loc evenimentul schimbării instrumentelor." -#: FlatCAMCommon.py:729 +#: FlatCAMCommon.py:730 msgid "" "Toolchange Z.\n" "The position on Z plane where the tool change event take place." @@ -2219,7 +2227,7 @@ msgstr "" "Schimb de unelte - locatia Z.\n" "Poziția in planul Z unde are loc evenimentul de schimbare a sculei." -#: FlatCAMCommon.py:732 +#: FlatCAMCommon.py:733 msgid "" "Start Z.\n" "If it's left empty it will not be used.\n" @@ -2229,7 +2237,7 @@ msgstr "" "Dacă este lăsat gol, nu va fi folosit.\n" "O poziție pe planul Z pentru a se deplasa imediat după începerea lucrului." -#: FlatCAMCommon.py:736 +#: FlatCAMCommon.py:737 msgid "" "End Z.\n" "A position on Z plane to move immediately after job stop." @@ -2237,349 +2245,730 @@ msgstr "" "Z Sfârșit.\n" "O poziție pe planul Z pentru a se deplasa imediat după oprirea executiei." -#: FlatCAMCommon.py:748 FlatCAMCommon.py:1125 FlatCAMCommon.py:1159 +#: FlatCAMCommon.py:749 FlatCAMCommon.py:1126 FlatCAMCommon.py:1160 +#: FlatCAMCommon.py:2335 FlatCAMCommon.py:2556 FlatCAMCommon.py:2590 msgid "Could not load Tools DB file." msgstr "Nu s-a putut încărca fișierul DB Unelte." -#: FlatCAMCommon.py:756 FlatCAMCommon.py:1167 +#: FlatCAMCommon.py:757 FlatCAMCommon.py:1168 FlatCAMCommon.py:2343 +#: FlatCAMCommon.py:2598 msgid "Failed to parse Tools DB file." msgstr "Eroare la analizarea fișierului DB Unelte." -#: FlatCAMCommon.py:759 FlatCAMCommon.py:1170 +#: FlatCAMCommon.py:760 FlatCAMCommon.py:1171 FlatCAMCommon.py:2346 +#: FlatCAMCommon.py:2601 msgid "Loaded FlatCAM Tools DB from" msgstr "S-a incărcat DB Unelte din" -#: FlatCAMCommon.py:765 +#: FlatCAMCommon.py:766 FlatCAMCommon.py:2260 msgid "Add to DB" msgstr "Adăugați la DB Unelte" -#: FlatCAMCommon.py:767 +#: FlatCAMCommon.py:768 FlatCAMCommon.py:2263 msgid "Copy from DB" msgstr "Copiați din DB Unelte" -#: FlatCAMCommon.py:769 +#: FlatCAMCommon.py:770 FlatCAMCommon.py:2266 msgid "Delete from DB" msgstr "Ștergeți din DB Unelte" -#: FlatCAMCommon.py:1046 +#: FlatCAMCommon.py:1047 FlatCAMCommon.py:2473 msgid "Tool added to DB." -msgstr "Unealtă adăugată in DB Unelte" +msgstr "Unealtă adăugată in DB." -#: FlatCAMCommon.py:1067 +#: FlatCAMCommon.py:1068 FlatCAMCommon.py:2497 msgid "Tool copied from Tools DB." -msgstr "Unealta a fost copiata din DB Unelte." +msgstr "Unealta a fost copiată din DB Unelte." -#: FlatCAMCommon.py:1085 +#: FlatCAMCommon.py:1086 FlatCAMCommon.py:2516 msgid "Tool removed from Tools DB." -msgstr "Unealta a fost stearsa din DB Unelte." +msgstr "Unealta a fost ștearsă din DB Unelte." -#: FlatCAMCommon.py:1096 +#: FlatCAMCommon.py:1097 FlatCAMCommon.py:2527 msgid "Export Tools Database" msgstr "Export DB Unelte" -#: FlatCAMCommon.py:1099 +#: FlatCAMCommon.py:1100 FlatCAMCommon.py:2530 msgid "Tools_Database" msgstr "DB Unelte" -#: FlatCAMCommon.py:1106 -msgid "FlatCAM Tools DB export cancelled." -msgstr "Exportul DB Unelte a fost anulat." - -#: FlatCAMCommon.py:1136 FlatCAMCommon.py:1139 FlatCAMCommon.py:1191 +#: FlatCAMCommon.py:1137 FlatCAMCommon.py:1140 FlatCAMCommon.py:1192 +#: FlatCAMCommon.py:2567 FlatCAMCommon.py:2570 FlatCAMCommon.py:2622 msgid "Failed to write Tools DB to file." msgstr "Eroare la scrierea DB Unelte în fișier." -#: FlatCAMCommon.py:1142 +#: FlatCAMCommon.py:1143 FlatCAMCommon.py:2573 msgid "Exported Tools DB to" msgstr "S-a exportat DB Unelte in" -#: FlatCAMCommon.py:1149 +#: FlatCAMCommon.py:1150 FlatCAMCommon.py:2580 msgid "Import FlatCAM Tools DB" msgstr "Importă DB Unelte" -#: FlatCAMCommon.py:1152 -msgid "FlatCAM Tools DB import cancelled." -msgstr "Importul DB Unelte a fost anulat." - -#: FlatCAMCommon.py:1195 +#: FlatCAMCommon.py:1196 FlatCAMCommon.py:2626 msgid "Saved Tools DB." -msgstr "DB unelte salvata." +msgstr "DB unelte salvată." -#: FlatCAMCommon.py:1342 +#: FlatCAMCommon.py:1343 FlatCAMCommon.py:2807 msgid "No Tool/row selected in the Tools Database table" msgstr "Nu a fost selectat nici-o Unealta / rând în tabela DB Unelte" -#: FlatCAMCommon.py:1360 +#: FlatCAMCommon.py:1361 FlatCAMCommon.py:2824 msgid "Cancelled adding tool from DB." msgstr "S-a anulat adăugarea de Unealtă din DB Unelte." -#: FlatCAMObj.py:257 +#: FlatCAMCommon.py:1462 +msgid "Basic Geo Parameters" +msgstr "Parametrii bază Geometrie" + +#: FlatCAMCommon.py:1474 +msgid "Advanced Geo Parameters" +msgstr "Param. Avansați Geometrie" + +#: FlatCAMCommon.py:1486 +msgid "NCC Parameters" +msgstr "Parametrii NCC" + +#: FlatCAMCommon.py:1498 +msgid "Paint Parameters" +msgstr "Parametrii Paint" + +#: FlatCAMCommon.py:1629 flatcamGUI/ObjectUI.py:966 flatcamGUI/ObjectUI.py:1767 +#: flatcamGUI/PreferencesUI.py:4378 flatcamGUI/PreferencesUI.py:7059 +#: flatcamTools/ToolSolderPaste.py:254 +msgid "Feedrate X-Y" +msgstr "Feedrate X-Y" + +#: FlatCAMCommon.py:1631 +msgid "" +"Feedrate X-Y. Feedrate\n" +"The speed on XY plane used while cutting into material." +msgstr "" +"Avans X-Y. Avans.\n" +"Viteza pe planul XY utilizat la tăierea în material." + +#: FlatCAMCommon.py:1643 flatcamGUI/ObjectUI.py:981 flatcamGUI/ObjectUI.py:1781 +#: flatcamGUI/PreferencesUI.py:3425 flatcamGUI/PreferencesUI.py:4393 +#: flatcamGUI/PreferencesUI.py:7072 flatcamTools/ToolSolderPaste.py:266 +msgid "Feedrate Z" +msgstr "Feedrate Z" + +#: FlatCAMCommon.py:1645 +msgid "" +"Feedrate Z\n" +"The speed on Z plane." +msgstr "" +"Feedrate Z. Avans Z.\n" +"Viteza de deplasare in planul Z." + +#: FlatCAMCommon.py:1843 flatcamGUI/ObjectUI.py:844 +#: flatcamGUI/PreferencesUI.py:3264 flatcamTools/ToolNCC.py:341 +msgid "Operation" +msgstr "Operațiuni" + +#: FlatCAMCommon.py:1845 flatcamTools/ToolNCC.py:343 +msgid "" +"The 'Operation' can be:\n" +"- Isolation -> will ensure that the non-copper clearing is always complete.\n" +"If it's not successful then the non-copper clearing will fail, too.\n" +"- Clear -> the regular non-copper clearing." +msgstr "" +"„Operațiunea” poate fi:\n" +"- Izolare -> se va asigura că curățarea non-cupru este întotdeauna " +"completă.\n" +"Dacă nu are succes, atunci curățarea din cupru nu va reuși.\n" +"- Curățare -> curățarea obișnuită de cupru." + +#: FlatCAMCommon.py:1852 flatcamEditors/FlatCAMGrbEditor.py:2739 +#: flatcamGUI/GUIElements.py:2577 flatcamTools/ToolNCC.py:350 +msgid "Clear" +msgstr "Șterge" + +#: FlatCAMCommon.py:1853 flatcamTools/ToolNCC.py:351 +#: flatcamTools/ToolNCC.py:1627 +msgid "Isolation" +msgstr "Tip de izolare" + +#: FlatCAMCommon.py:1861 flatcamGUI/ObjectUI.py:408 flatcamGUI/ObjectUI.py:866 +#: flatcamGUI/PreferencesUI.py:2257 flatcamGUI/PreferencesUI.py:3280 +#: flatcamGUI/PreferencesUI.py:4665 flatcamGUI/PreferencesUI.py:5416 +#: flatcamTools/ToolNCC.py:359 +msgid "Milling Type" +msgstr "Tip Frezare" + +#: FlatCAMCommon.py:1863 FlatCAMCommon.py:1871 flatcamGUI/PreferencesUI.py:5418 +#: flatcamGUI/PreferencesUI.py:5426 flatcamTools/ToolNCC.py:361 +#: flatcamTools/ToolNCC.py:369 +msgid "" +"Milling type when the selected tool is of type: 'iso_op':\n" +"- climb / best for precision milling and to reduce tool usage\n" +"- conventional / useful when there is no backlash compensation" +msgstr "" +"Tipul de frezare cand unealta selectată este de tipul: 'iso_op':\n" +"- urcare -> potrivit pentru frezare de precizie și pt a reduce uzura " +"uneltei\n" +"- conventional -> pentru cazul când nu exista o compensare a 'backlash-ului'" + +#: FlatCAMCommon.py:1868 flatcamGUI/ObjectUI.py:414 +#: flatcamGUI/PreferencesUI.py:2264 flatcamGUI/PreferencesUI.py:4671 +#: flatcamGUI/PreferencesUI.py:5423 flatcamTools/ToolNCC.py:366 +msgid "Climb" +msgstr "Urcare" + +#: FlatCAMCommon.py:1869 flatcamGUI/ObjectUI.py:415 +#: flatcamGUI/PreferencesUI.py:2265 flatcamGUI/PreferencesUI.py:4672 +#: flatcamGUI/PreferencesUI.py:5424 flatcamTools/ToolNCC.py:367 +msgid "Conventional" +msgstr "Convenţional" + +#: FlatCAMCommon.py:1881 FlatCAMCommon.py:1990 +#: flatcamEditors/FlatCAMGeoEditor.py:452 flatcamGUI/PreferencesUI.py:5461 +#: flatcamGUI/PreferencesUI.py:6002 flatcamTools/ToolNCC.py:382 +#: flatcamTools/ToolPaint.py:329 +msgid "Overlap" +msgstr "Rată suprapunere" + +#: FlatCAMCommon.py:1883 flatcamGUI/PreferencesUI.py:5463 +#: flatcamTools/ToolNCC.py:384 +msgid "" +"How much (percentage) of the tool width to overlap each tool pass.\n" +"Adjust the value starting with lower values\n" +"and increasing it if areas that should be cleared are still \n" +"not cleared.\n" +"Lower values = faster processing, faster execution on CNC.\n" +"Higher values = slow processing and slow execution on CNC\n" +"due of too many paths." +msgstr "" +"Cât de mult (fracţie) din diametrul uneltei să se suprapună la fiecare " +"trecere a uneltei.\n" +"Ajustează valoarea incepând de la valori mici\n" +"și pe urmă crește dacă ariile care ar trebui >curățate< incă\n" +"nu sunt procesate.\n" +"Valori scăzute = procesare rapidă, execuţie rapidă a PCB-ului.\n" +"Valori mari= procesare lentă cât și o execuţie la fel de lentă a PCB-ului,\n" +"datorită numărului mai mare de treceri-tăiere." + +#: FlatCAMCommon.py:1902 FlatCAMCommon.py:2011 +#: flatcamEditors/FlatCAMGeoEditor.py:472 flatcamGUI/PreferencesUI.py:5481 +#: flatcamGUI/PreferencesUI.py:5723 flatcamGUI/PreferencesUI.py:6022 +#: flatcamGUI/PreferencesUI.py:7681 flatcamGUI/PreferencesUI.py:7838 +#: flatcamGUI/PreferencesUI.py:7923 flatcamGUI/PreferencesUI.py:8570 +#: flatcamGUI/PreferencesUI.py:8578 flatcamTools/ToolCopperThieving.py:112 +#: flatcamTools/ToolCopperThieving.py:363 flatcamTools/ToolCutOut.py:191 +#: flatcamTools/ToolFiducials.py:172 flatcamTools/ToolInvertGerber.py:88 +#: flatcamTools/ToolInvertGerber.py:96 flatcamTools/ToolNCC.py:403 +#: flatcamTools/ToolPaint.py:350 +msgid "Margin" +msgstr "Margine" + +#: FlatCAMCommon.py:1904 flatcamGUI/PreferencesUI.py:5483 +#: flatcamGUI/PreferencesUI.py:7683 flatcamGUI/PreferencesUI.py:7925 +#: flatcamGUI/PreferencesUI.py:7989 flatcamTools/ToolCopperThieving.py:114 +#: flatcamTools/ToolFiducials.py:174 flatcamTools/ToolFiducials.py:237 +#: flatcamTools/ToolNCC.py:405 +msgid "Bounding box margin." +msgstr "Marginea pentru forma înconjurătoare." + +#: FlatCAMCommon.py:1915 FlatCAMCommon.py:2026 +#: flatcamEditors/FlatCAMGeoEditor.py:486 flatcamGUI/PreferencesUI.py:5494 +#: flatcamGUI/PreferencesUI.py:6037 flatcamGUI/PreferencesUI.py:8204 +#: flatcamGUI/PreferencesUI.py:8417 flatcamTools/ToolExtractDrills.py:128 +#: flatcamTools/ToolNCC.py:416 flatcamTools/ToolPaint.py:365 +#: flatcamTools/ToolPunchGerber.py:139 +msgid "Method" +msgstr "Metodă" + +#: FlatCAMCommon.py:1917 flatcamGUI/PreferencesUI.py:5496 +#: flatcamTools/ToolNCC.py:418 +msgid "" +"Algorithm for copper clearing:\n" +"- Standard: Fixed step inwards.\n" +"- Seed-based: Outwards from seed.\n" +"- Line-based: Parallel lines." +msgstr "" +"Algoritm pentru curătare cupru:\n" +"- Standard: pas fix spre interior.\n" +"- Punct-origine: înspre exterior porning de la punctul sămanță.\n" +"- Linii: linii paralele." + +#: FlatCAMCommon.py:1925 FlatCAMCommon.py:2040 +#: flatcamEditors/FlatCAMGeoEditor.py:500 flatcamGUI/PreferencesUI.py:5509 +#: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 +#: flatcamTools/ToolNCC.py:2395 flatcamTools/ToolNCC.py:2424 +#: flatcamTools/ToolNCC.py:2693 flatcamTools/ToolNCC.py:2725 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:1818 +#: flatcamTools/ToolPaint.py:2717 flatcamTools/ToolPaint.py:3198 +#: flatcamTools/ToolPaint.py:3538 +msgid "Standard" +msgstr "Standard" + +#: FlatCAMCommon.py:1925 FlatCAMCommon.py:2040 +#: flatcamEditors/FlatCAMGeoEditor.py:500 +#: flatcamEditors/FlatCAMGeoEditor.py:5156 flatcamGUI/PreferencesUI.py:5509 +#: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:696 +#: flatcamTools/ToolPaint.py:1846 flatcamTools/ToolPaint.py:2729 +#: flatcamTools/ToolPaint.py:3188 flatcamTools/ToolPaint.py:3550 +msgid "Lines" +msgstr "Linii" + +#: FlatCAMCommon.py:1933 FlatCAMCommon.py:2051 flatcamGUI/PreferencesUI.py:5516 +#: flatcamGUI/PreferencesUI.py:6063 flatcamTools/ToolNCC.py:439 +#: flatcamTools/ToolPaint.py:401 +msgid "Connect" +msgstr "Conectează" + +#: FlatCAMCommon.py:1937 FlatCAMCommon.py:2054 +#: flatcamEditors/FlatCAMGeoEditor.py:509 flatcamGUI/PreferencesUI.py:5518 +#: flatcamGUI/PreferencesUI.py:6065 flatcamTools/ToolNCC.py:443 +#: flatcamTools/ToolPaint.py:404 +msgid "" +"Draw lines between resulting\n" +"segments to minimize tool lifts." +msgstr "" +"Desenează linii între segmentele\n" +"rezultate pentru a minimiza miscarile\n" +"de ridicare a uneltei." + +#: FlatCAMCommon.py:1943 FlatCAMCommon.py:2058 flatcamGUI/PreferencesUI.py:5525 +#: flatcamGUI/PreferencesUI.py:6071 flatcamTools/ToolNCC.py:449 +#: flatcamTools/ToolPaint.py:408 +msgid "Contour" +msgstr "Contur" + +#: FlatCAMCommon.py:1947 FlatCAMCommon.py:2061 +#: flatcamEditors/FlatCAMGeoEditor.py:519 flatcamGUI/PreferencesUI.py:5527 +#: flatcamGUI/PreferencesUI.py:6073 flatcamTools/ToolNCC.py:453 +#: flatcamTools/ToolPaint.py:411 +msgid "" +"Cut around the perimeter of the polygon\n" +"to trim rough edges." +msgstr "" +"Taie de-a lungul perimetrului poligonului\n" +"pentru a elimina bavurile." + +#: FlatCAMCommon.py:1953 flatcamEditors/FlatCAMGeoEditor.py:613 +#: flatcamEditors/FlatCAMGrbEditor.py:5145 flatcamGUI/ObjectUI.py:142 +#: flatcamGUI/ObjectUI.py:1495 flatcamGUI/ObjectUI.py:2244 +#: flatcamGUI/PreferencesUI.py:5534 flatcamGUI/PreferencesUI.py:6822 +#: flatcamTools/ToolNCC.py:459 flatcamTools/ToolTransform.py:29 +msgid "Offset" +msgstr "Ofset" + +#: FlatCAMCommon.py:1957 flatcamGUI/PreferencesUI.py:5536 +#: flatcamTools/ToolNCC.py:463 +msgid "" +"If used, it will add an offset to the copper features.\n" +"The copper clearing will finish to a distance\n" +"from the copper features.\n" +"The value can be between 0 and 10 FlatCAM units." +msgstr "" +"Dacă este folosit, va adăuga un offset la traseele de cupru.\n" +"Curătarea de cupru se va termina la o anume distanță\n" +"de traseele de cupru.\n" +"Valoarea poate fi cuprinsă între 0 și 10 unități FlatCAM." + +#: FlatCAMCommon.py:1992 flatcamEditors/FlatCAMGeoEditor.py:454 +#: flatcamGUI/PreferencesUI.py:6004 flatcamTools/ToolPaint.py:331 +msgid "" +"How much (percentage) of the tool width to overlap each tool pass.\n" +"Adjust the value starting with lower values\n" +"and increasing it if areas that should be painted are still \n" +"not painted.\n" +"Lower values = faster processing, faster execution on CNC.\n" +"Higher values = slow processing and slow execution on CNC\n" +"due of too many paths." +msgstr "" +"Cat de mult (fracţie) din diametrul uneltei să se suprapună la fiecare " +"trecere a uneltei.\n" +"Ajustează valoarea incepand de la valori mici și pe urma creste dacă ariile " +"care ar trebui\n" +" >pictate< incă nu sunt procesate.\n" +"Valori scăzute = procesare rapidă, execuţie rapidă a PCB-ului.\n" +"Valori mari= procesare lentă cat și o execuţie la fel de lentă a PCB-ului,\n" +"datorită numărului mai mare de treceri-tăiere." + +#: FlatCAMCommon.py:2013 flatcamEditors/FlatCAMGeoEditor.py:474 +#: flatcamGUI/PreferencesUI.py:6024 flatcamTools/ToolPaint.py:352 +msgid "" +"Distance by which to avoid\n" +"the edges of the polygon to\n" +"be painted." +msgstr "" +"Distanta fata de marginile\n" +"poligonului care trebuie\n" +"să fie >pictat<." + +#: FlatCAMCommon.py:2028 flatcamGUI/PreferencesUI.py:6039 +#: flatcamTools/ToolPaint.py:367 +msgid "" +"Algorithm for painting:\n" +"- Standard: Fixed step inwards.\n" +"- Seed-based: Outwards from seed.\n" +"- Line-based: Parallel lines.\n" +"- Laser-lines: Active only for Gerber objects.\n" +"Will create lines that follow the traces.\n" +"- Combo: In case of failure a new method will be picked from the above\n" +"in the order specified." +msgstr "" +"Algoritm pentru 'pictare':\n" +"- Standard: pasi fixi spre interior\n" +"- Punct_origine: spre exterior plecand de la punctul samantă\n" +"- Linii: linii paralele\n" +"- Linii-laser: Activ numai pentru fisierele Gerber.\n" +"Va crea treceri-unelte care vor urmari traseele.\n" +"- Combinat: In caz de esec, o noua metodă va fi aleasă dintre cele enumerate " +"mai sus\n" +"intr-o ordine specificată." + +#: FlatCAMCommon.py:2040 FlatCAMCommon.py:2042 flatcamGUI/PreferencesUI.py:6056 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:392 +#: flatcamTools/ToolPaint.py:690 flatcamTools/ToolPaint.py:695 +#: flatcamTools/ToolPaint.py:1860 flatcamTools/ToolPaint.py:2735 +#: flatcamTools/ToolPaint.py:3207 flatcamTools/ToolPaint.py:3556 +msgid "Laser_lines" +msgstr "Linii-laser" + +#: FlatCAMCommon.py:2040 flatcamGUI/PreferencesUI.py:6056 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:2011 +#: flatcamTools/ToolPaint.py:2861 flatcamTools/ToolPaint.py:3333 +#: flatcamTools/ToolPaint.py:3682 +msgid "Combo" +msgstr "Combinat" + +#: FlatCAMCommon.py:2085 +msgid "Add Tool in DB" +msgstr "Adăugați Unealta în DB" + +#: FlatCAMObj.py:264 msgid "Name changed from" msgstr "Nume schimbat din" -#: FlatCAMObj.py:257 +#: FlatCAMObj.py:264 msgid "to" msgstr "la" -#: FlatCAMObj.py:268 +#: FlatCAMObj.py:275 msgid "Offsetting..." msgstr "Ofsetare..." -#: FlatCAMObj.py:282 FlatCAMObj.py:287 +#: FlatCAMObj.py:289 FlatCAMObj.py:294 msgid "Scaling could not be executed." msgstr "Scalarea nu a putut fi executată." -#: FlatCAMObj.py:291 FlatCAMObj.py:299 +#: FlatCAMObj.py:298 FlatCAMObj.py:306 msgid "Scale done." msgstr "Scalare efectuată." -#: FlatCAMObj.py:297 +#: FlatCAMObj.py:304 msgid "Scaling..." msgstr "Scalare..." -#: FlatCAMObj.py:315 +#: FlatCAMObj.py:322 msgid "Skewing..." msgstr "Deformare..." -#: FlatCAMObj.py:736 FlatCAMObj.py:2746 FlatCAMObj.py:3968 -#: flatcamGUI/PreferencesUI.py:1470 flatcamGUI/PreferencesUI.py:2859 +#: FlatCAMObj.py:743 FlatCAMObj.py:831 flatcamGUI/ObjectUI.py:449 +#: flatcamGUI/PreferencesUI.py:6527 flatcamTools/ToolAlignObjects.py:73 +#: flatcamTools/ToolAlignObjects.py:109 flatcamTools/ToolCalibration.py:196 +#: flatcamTools/ToolCalibration.py:631 flatcamTools/ToolCalibration.py:648 +#: flatcamTools/ToolCalibration.py:807 flatcamTools/ToolCalibration.py:815 +#: flatcamTools/ToolCopperThieving.py:145 +#: flatcamTools/ToolCopperThieving.py:159 +#: flatcamTools/ToolCopperThieving.py:605 flatcamTools/ToolCutOut.py:92 +#: flatcamTools/ToolDblSided.py:225 flatcamTools/ToolFilm.py:69 +#: flatcamTools/ToolFilm.py:102 flatcamTools/ToolFilm.py:549 +#: flatcamTools/ToolFilm.py:557 flatcamTools/ToolImage.py:49 +#: flatcamTools/ToolImage.py:252 flatcamTools/ToolImage.py:273 +#: flatcamTools/ToolNCC.py:96 flatcamTools/ToolNCC.py:558 +#: flatcamTools/ToolNCC.py:1293 flatcamTools/ToolPaint.py:502 +#: flatcamTools/ToolPaint.py:703 flatcamTools/ToolPanelize.py:118 +#: flatcamTools/ToolPanelize.py:204 flatcamTools/ToolPanelize.py:374 +#: flatcamTools/ToolPanelize.py:391 +msgid "Gerber" +msgstr "Gerber" + +#: FlatCAMObj.py:743 FlatCAMObj.py:831 flatcamGUI/FlatCAMGUI.py:2154 +#: flatcamGUI/ObjectUI.py:449 flatcamTools/ToolCalibration.py:631 +#: flatcamTools/ToolCalibration.py:648 flatcamTools/ToolCalibration.py:815 +#: flatcamTools/ToolCopperThieving.py:145 +#: flatcamTools/ToolCopperThieving.py:159 +#: flatcamTools/ToolCopperThieving.py:605 flatcamTools/ToolCutOut.py:93 +#: flatcamTools/ToolDblSided.py:227 flatcamTools/ToolFilm.py:69 +#: flatcamTools/ToolFilm.py:102 flatcamTools/ToolFilm.py:549 +#: flatcamTools/ToolFilm.py:557 flatcamTools/ToolImage.py:49 +#: flatcamTools/ToolImage.py:271 flatcamTools/ToolNCC.py:95 +#: flatcamTools/ToolNCC.py:558 flatcamTools/ToolNCC.py:1293 +#: flatcamTools/ToolPaint.py:502 flatcamTools/ToolPaint.py:703 +#: flatcamTools/ToolPanelize.py:118 flatcamTools/ToolPanelize.py:374 +#: flatcamTools/ToolPanelize.py:391 +msgid "Geometry" +msgstr "Geometrie" + +#: FlatCAMObj.py:755 FlatCAMObj.py:2957 FlatCAMObj.py:4421 +#: flatcamGUI/PreferencesUI.py:1646 flatcamGUI/PreferencesUI.py:3041 msgid "Basic" msgstr "Baza" -#: FlatCAMObj.py:763 FlatCAMObj.py:2758 FlatCAMObj.py:3989 -#: flatcamGUI/PreferencesUI.py:1471 +#: FlatCAMObj.py:782 FlatCAMObj.py:2970 FlatCAMObj.py:4442 +#: flatcamGUI/PreferencesUI.py:1647 msgid "Advanced" msgstr "Avansat" -#: FlatCAMObj.py:980 +#: FlatCAMObj.py:998 msgid "Buffering solid geometry" msgstr "Buferarea geometriei solide" -#: FlatCAMObj.py:983 camlib.py:965 flatcamGUI/PreferencesUI.py:2296 -#: flatcamTools/ToolCopperThieving.py:1011 -#: flatcamTools/ToolCopperThieving.py:1200 -#: flatcamTools/ToolCopperThieving.py:1212 -#: flatcamTools/ToolNonCopperClear.py:1624 -#: flatcamTools/ToolNonCopperClear.py:1721 -#: flatcamTools/ToolNonCopperClear.py:1732 -#: flatcamTools/ToolNonCopperClear.py:2015 -#: flatcamTools/ToolNonCopperClear.py:2111 -#: flatcamTools/ToolNonCopperClear.py:2123 +#: FlatCAMObj.py:1001 camlib.py:979 flatcamGUI/PreferencesUI.py:2476 +#: flatcamTools/ToolCopperThieving.py:1017 +#: flatcamTools/ToolCopperThieving.py:1206 +#: flatcamTools/ToolCopperThieving.py:1218 flatcamTools/ToolNCC.py:2050 +#: flatcamTools/ToolNCC.py:2158 flatcamTools/ToolNCC.py:2172 +#: flatcamTools/ToolNCC.py:3103 flatcamTools/ToolNCC.py:3208 +#: flatcamTools/ToolNCC.py:3223 flatcamTools/ToolNCC.py:3489 +#: flatcamTools/ToolNCC.py:3590 flatcamTools/ToolNCC.py:3605 msgid "Buffering" msgstr "Buferare" -#: FlatCAMObj.py:989 +#: FlatCAMObj.py:1007 msgid "Done" msgstr "Executat" -#: FlatCAMObj.py:1040 +#: FlatCAMObj.py:1032 FlatCAMObj.py:1058 +msgid "Operation could not be done." +msgstr "Operatia nu a putut fi executată." + +#: FlatCAMObj.py:1075 msgid "Isolating..." msgstr "Se izoleaza..." -#: FlatCAMObj.py:1099 +#: FlatCAMObj.py:1134 msgid "Click on a polygon to isolate it." msgstr "Faceți clic pe un poligon pentru a-l izola." -#: FlatCAMObj.py:1138 FlatCAMObj.py:1243 flatcamTools/ToolPaint.py:1120 +#: FlatCAMObj.py:1173 FlatCAMObj.py:1277 flatcamTools/ToolPaint.py:1504 msgid "Added polygon" msgstr "S-a adăugat poligon" -#: FlatCAMObj.py:1140 FlatCAMObj.py:1245 +#: FlatCAMObj.py:1174 FlatCAMObj.py:1279 msgid "Click to add next polygon or right click to start isolation." msgstr "" "Faceți clic pentru a adăuga următorul poligon sau faceți clic dreapta pentru " "a începe izolarea." -#: FlatCAMObj.py:1152 flatcamTools/ToolPaint.py:1134 +#: FlatCAMObj.py:1186 flatcamTools/ToolPaint.py:1518 msgid "Removed polygon" msgstr "Poligon eliminat" -#: FlatCAMObj.py:1153 +#: FlatCAMObj.py:1187 msgid "Click to add/remove next polygon or right click to start isolation." msgstr "" "Faceți clic pentru a adăuga / elimina următorul poligon sau faceți clic " "dreapta pentru a începe izolarea." -#: FlatCAMObj.py:1158 flatcamTools/ToolPaint.py:1140 +#: FlatCAMObj.py:1192 flatcamTools/ToolPaint.py:1524 msgid "No polygon detected under click position." msgstr "Nu a fost detectat niciun poligon sub poziția clicului." -#: FlatCAMObj.py:1179 flatcamTools/ToolPaint.py:1169 +#: FlatCAMObj.py:1213 flatcamTools/ToolPaint.py:1553 msgid "List of single polygons is empty. Aborting." msgstr "Lista Poligoanelor este goală. Intrerup." -#: FlatCAMObj.py:1248 +#: FlatCAMObj.py:1282 msgid "No polygon in selection." msgstr "Niciun poligon în selecție." -#: FlatCAMObj.py:1324 FlatCAMObj.py:1457 -#: flatcamTools/ToolNonCopperClear.py:1653 -#: flatcamTools/ToolNonCopperClear.py:2039 -msgid "Isolation geometry could not be generated." -msgstr "Geometria de izolare nu a fost posibil să fie generată." - -#: FlatCAMObj.py:1374 FlatCAMObj.py:3637 FlatCAMObj.py:3922 FlatCAMObj.py:4221 +#: FlatCAMObj.py:1394 FlatCAMObj.py:1542 FlatCAMObj.py:4055 FlatCAMObj.py:4375 +#: FlatCAMObj.py:4762 msgid "Rough" msgstr "Grosier" -#: FlatCAMObj.py:1400 FlatCAMObj.py:1480 +#: FlatCAMObj.py:1410 FlatCAMObj.py:1489 flatcamTools/ToolNCC.py:2086 +#: flatcamTools/ToolNCC.py:3137 flatcamTools/ToolNCC.py:3516 +msgid "Isolation geometry could not be generated." +msgstr "Geometria de izolare nu a fost posibil să fie generată." + +#: FlatCAMObj.py:1435 FlatCAMObj.py:1567 msgid "Isolation geometry created" msgstr "Geometria de izolare creată" -#: FlatCAMObj.py:1409 FlatCAMObj.py:1487 +#: FlatCAMObj.py:1444 FlatCAMObj.py:1574 msgid "Subtracting Geo" msgstr "Scădere Geo" -#: FlatCAMObj.py:1807 +#: FlatCAMObj.py:1899 msgid "Plotting Apertures" msgstr "Aperturile sunt in curs de afișare" -#: FlatCAMObj.py:2573 flatcamEditors/FlatCAMExcEditor.py:2427 +#: FlatCAMObj.py:2753 flatcamEditors/FlatCAMExcEditor.py:2453 msgid "Total Drills" msgstr "Nr. Tot. Op. Găurire" -#: FlatCAMObj.py:2605 flatcamEditors/FlatCAMExcEditor.py:2459 +#: FlatCAMObj.py:2784 flatcamEditors/FlatCAMExcEditor.py:2485 msgid "Total Slots" msgstr "Nr. Tot. Sloturi" -#: FlatCAMObj.py:3060 FlatCAMObj.py:3155 FlatCAMObj.py:3276 +#: FlatCAMObj.py:2857 FlatCAMObj.py:3069 FlatCAMObj.py:3085 FlatCAMObj.py:3089 +#: FlatCAMObj.py:4242 FlatCAMObj.py:4667 FlatCAMObj.py:4703 +#: flatcamGUI/ObjectUI.py:817 flatcamGUI/ObjectUI.py:1660 +#: flatcamTools/ToolNCC.py:331 flatcamTools/ToolNCC.py:794 +#: flatcamTools/ToolNCC.py:808 flatcamTools/ToolNCC.py:1189 +#: flatcamTools/ToolPaint.py:314 flatcamTools/ToolPaint.py:764 +#: flatcamTools/ToolPaint.py:776 flatcamTools/ToolPaint.py:1159 +msgid "Parameters for" +msgstr "Parametri pt" + +#: FlatCAMObj.py:2857 FlatCAMObj.py:3089 FlatCAMObj.py:4242 FlatCAMObj.py:4703 +#: flatcamTools/ToolNCC.py:808 flatcamTools/ToolNCC.py:1189 +#: flatcamTools/ToolPaint.py:776 flatcamTools/ToolPaint.py:1159 +msgid "Multiple Tools" +msgstr "Unelte multiple" + +#: FlatCAMObj.py:3069 +msgid "No Tool Selected" +msgstr "Nici-o Unealtă selectată" + +#: FlatCAMObj.py:3085 FlatCAMObj.py:3427 FlatCAMObj.py:4667 +#: flatcamEditors/FlatCAMGeoEditor.py:406 flatcamGUI/FlatCAMGUI.py:496 +#: flatcamGUI/FlatCAMGUI.py:1143 flatcamGUI/ObjectUI.py:817 +#: flatcamGUI/ObjectUI.py:1660 flatcamTools/ToolNCC.py:331 +#: flatcamTools/ToolNCC.py:794 flatcamTools/ToolPaint.py:314 +#: flatcamTools/ToolPaint.py:764 +msgid "Tool" +msgstr "Unealta" + +#: FlatCAMObj.py:3419 FlatCAMObj.py:3512 FlatCAMObj.py:3700 msgid "Please select one or more tools from the list and try again." msgstr "Selectează una sau mai multe unelte din lista și încearcă din nou." -#: FlatCAMObj.py:3067 +#: FlatCAMObj.py:3426 msgid "Milling tool for DRILLS is larger than hole size. Cancelled." msgstr "" "Anulat. Freza pt frezarea găurilor este mai mare decat diametrul găurii." -#: FlatCAMObj.py:3068 FlatCAMObj.py:4533 flatcamEditors/FlatCAMGeoEditor.py:408 -#: flatcamGUI/FlatCAMGUI.py:457 flatcamGUI/FlatCAMGUI.py:1072 -#: flatcamGUI/ObjectUI.py:1353 -msgid "Tool" -msgstr "Unealta" - -#: FlatCAMObj.py:3084 FlatCAMObj.py:3177 FlatCAMObj.py:3295 +#: FlatCAMObj.py:3442 FlatCAMObj.py:3533 FlatCAMObj.py:3719 +#: tclCommands/TclCommandDrillcncjob.py:194 msgid "Tool_nr" msgstr "Nr. Unealtă" -#: FlatCAMObj.py:3084 FlatCAMObj.py:3177 FlatCAMObj.py:3295 -#: flatcamEditors/FlatCAMExcEditor.py:1582 -#: flatcamEditors/FlatCAMExcEditor.py:3048 flatcamGUI/ObjectUI.py:777 -#: flatcamTools/ToolNonCopperClear.py:120 flatcamTools/ToolPaint.py:123 -#: flatcamTools/ToolPcbWizard.py:76 flatcamTools/ToolProperties.py:396 -#: flatcamTools/ToolProperties.py:449 flatcamTools/ToolSolderPaste.py:84 +#: FlatCAMObj.py:3442 FlatCAMObj.py:3533 FlatCAMObj.py:3719 +#: flatcamEditors/FlatCAMExcEditor.py:1585 +#: flatcamEditors/FlatCAMExcEditor.py:3069 flatcamGUI/ObjectUI.py:780 +#: flatcamTools/ToolNCC.py:132 flatcamTools/ToolPaint.py:128 +#: flatcamTools/ToolPcbWizard.py:76 flatcamTools/ToolProperties.py:416 +#: flatcamTools/ToolProperties.py:476 flatcamTools/ToolSolderPaste.py:86 +#: tclCommands/TclCommandDrillcncjob.py:194 msgid "Diameter" msgstr "Diametru" -#: FlatCAMObj.py:3084 FlatCAMObj.py:3177 FlatCAMObj.py:3295 +#: FlatCAMObj.py:3442 FlatCAMObj.py:3533 FlatCAMObj.py:3719 +#: tclCommands/TclCommandDrillcncjob.py:194 msgid "Drills_Nr" msgstr "Nr. gaura" -#: FlatCAMObj.py:3084 FlatCAMObj.py:3177 FlatCAMObj.py:3295 +#: FlatCAMObj.py:3442 FlatCAMObj.py:3533 FlatCAMObj.py:3719 +#: tclCommands/TclCommandDrillcncjob.py:194 msgid "Slots_Nr" msgstr "Nr. slot" -#: FlatCAMObj.py:3164 +#: FlatCAMObj.py:3521 msgid "Milling tool for SLOTS is larger than hole size. Cancelled." msgstr "Anulat. Freza este mai mare decat diametrul slotului de frezat." -#: FlatCAMObj.py:3336 -msgid "" -"Wrong value format for self.defaults[\"z_pdepth\"] or self.options[\"z_pdepth" -"\"]" -msgstr "" -"Valoare gresita pt self.defaults[\"z_pdepth\"] sau self.options[\"z_pdepth\"]" +#: FlatCAMObj.py:3626 FlatCAMObj.py:5451 +msgid "Focus Z" +msgstr "Focalizare Z" -#: FlatCAMObj.py:3347 -msgid "" -"Wrong value format for self.defaults[\"feedrate_probe\"] or self." -"options[\"feedrate_probe\"]" -msgstr "" -"Valoare gresita pt self.defaults[\"feedrate_probe\"] sau self." -"options[\"feedrate_probe\"]" +#: FlatCAMObj.py:3645 FlatCAMObj.py:5470 +msgid "Laser Power" +msgstr "Putere Laser" -#: FlatCAMObj.py:3377 FlatCAMObj.py:5354 FlatCAMObj.py:5358 FlatCAMObj.py:5493 +#: FlatCAMObj.py:3677 FlatCAMObj.py:5502 flatcamGUI/ObjectUI.py:1048 +#: flatcamGUI/ObjectUI.py:1839 flatcamGUI/PreferencesUI.py:4409 +msgid "Spindle speed" +msgstr "Viteza motor" + +#: FlatCAMObj.py:3776 FlatCAMObj.py:5911 FlatCAMObj.py:5915 FlatCAMObj.py:6060 msgid "Generating CNC Code" msgstr "CNC Code in curs de generare" -#: FlatCAMObj.py:3637 FlatCAMObj.py:4632 FlatCAMObj.py:4633 FlatCAMObj.py:4642 +#: FlatCAMObj.py:3966 flatcamTools/ToolNCC.py:916 flatcamTools/ToolPaint.py:841 +msgid "Current Tool parameters were applied to all tools." +msgstr "Parametrii Uneltei curente sunt aplicați la toate Uneltele." + +#: FlatCAMObj.py:4055 FlatCAMObj.py:5115 FlatCAMObj.py:5116 FlatCAMObj.py:5125 msgid "Iso" msgstr "Izo" -#: FlatCAMObj.py:3637 +#: FlatCAMObj.py:4055 msgid "Finish" msgstr "Finisare" -#: FlatCAMObj.py:3957 +#: FlatCAMObj.py:4410 msgid "Add from Tool DB" msgstr "Adaugă Unealta din DB Unelte" -#: FlatCAMObj.py:3960 flatcamGUI/FlatCAMGUI.py:678 flatcamGUI/FlatCAMGUI.py:794 -#: flatcamGUI/FlatCAMGUI.py:989 flatcamGUI/FlatCAMGUI.py:2015 -#: flatcamGUI/FlatCAMGUI.py:2159 flatcamGUI/FlatCAMGUI.py:2378 -#: flatcamGUI/FlatCAMGUI.py:2557 flatcamGUI/ObjectUI.py:1324 -#: flatcamTools/ToolPanelize.py:534 flatcamTools/ToolPanelize.py:561 -#: flatcamTools/ToolPanelize.py:660 flatcamTools/ToolPanelize.py:694 -#: flatcamTools/ToolPanelize.py:759 +#: FlatCAMObj.py:4413 flatcamGUI/FlatCAMGUI.py:734 flatcamGUI/FlatCAMGUI.py:848 +#: flatcamGUI/FlatCAMGUI.py:1057 flatcamGUI/FlatCAMGUI.py:2123 +#: flatcamGUI/FlatCAMGUI.py:2267 flatcamGUI/FlatCAMGUI.py:2532 +#: flatcamGUI/FlatCAMGUI.py:2731 flatcamGUI/ObjectUI.py:1615 +#: flatcamTools/ToolPanelize.py:543 flatcamTools/ToolPanelize.py:570 +#: flatcamTools/ToolPanelize.py:669 flatcamTools/ToolPanelize.py:703 +#: flatcamTools/ToolPanelize.py:768 msgid "Copy" msgstr "Copiază" -#: FlatCAMObj.py:4054 FlatCAMObj.py:4397 FlatCAMObj.py:5107 FlatCAMObj.py:5744 -#: flatcamEditors/FlatCAMExcEditor.py:2534 -#: flatcamEditors/FlatCAMGeoEditor.py:1078 -#: flatcamEditors/FlatCAMGeoEditor.py:1112 -#: flatcamEditors/FlatCAMGeoEditor.py:1133 -#: flatcamEditors/FlatCAMGeoEditor.py:1154 -#: flatcamEditors/FlatCAMGeoEditor.py:1191 -#: flatcamEditors/FlatCAMGeoEditor.py:1219 -#: flatcamEditors/FlatCAMGeoEditor.py:1240 -#: flatcamTools/ToolNonCopperClear.py:1052 -#: flatcamTools/ToolNonCopperClear.py:1461 flatcamTools/ToolPaint.py:835 -#: flatcamTools/ToolPaint.py:1019 flatcamTools/ToolPaint.py:2198 -#: flatcamTools/ToolSolderPaste.py:882 flatcamTools/ToolSolderPaste.py:957 +#: FlatCAMObj.py:4507 FlatCAMObj.py:4941 FlatCAMObj.py:5661 FlatCAMObj.py:6307 +#: flatcamEditors/FlatCAMExcEditor.py:2560 +#: flatcamEditors/FlatCAMGeoEditor.py:1077 +#: flatcamEditors/FlatCAMGeoEditor.py:1118 +#: flatcamEditors/FlatCAMGeoEditor.py:1146 +#: flatcamEditors/FlatCAMGeoEditor.py:1174 +#: flatcamEditors/FlatCAMGeoEditor.py:1218 +#: flatcamEditors/FlatCAMGeoEditor.py:1253 +#: flatcamEditors/FlatCAMGeoEditor.py:1281 flatcamTools/ToolNCC.py:1502 +#: flatcamTools/ToolPaint.py:1237 flatcamTools/ToolPaint.py:1408 +#: flatcamTools/ToolSolderPaste.py:883 flatcamTools/ToolSolderPaste.py:956 msgid "Wrong value format entered, use a number." msgstr "Valoare in format incorect, foloseşte un număr." -#: FlatCAMObj.py:4240 +#: FlatCAMObj.py:4781 msgid "Tool added in Tool Table." msgstr "Unealtă adăugată in Tabela de Unelte." -#: FlatCAMObj.py:4347 FlatCAMObj.py:4356 +#: FlatCAMObj.py:4890 FlatCAMObj.py:4899 msgid "Failed. Select a tool to copy." msgstr "Eșuat. Selectează o unealtă pt copiere." -#: FlatCAMObj.py:4383 +#: FlatCAMObj.py:4928 msgid "Tool was copied in Tool Table." msgstr "Unealta a fost copiata in Tabela de Unelte." -#: FlatCAMObj.py:4411 +#: FlatCAMObj.py:4955 msgid "Tool was edited in Tool Table." msgstr "Unealta a fost editata in Tabela de Unelte." -#: FlatCAMObj.py:4440 FlatCAMObj.py:4449 +#: FlatCAMObj.py:4984 FlatCAMObj.py:4993 msgid "Failed. Select a tool to delete." msgstr "Eșuat. Selectează o unealtă pentru ștergere." -#: FlatCAMObj.py:4472 +#: FlatCAMObj.py:5017 msgid "Tool was deleted in Tool Table." msgstr "Unealta a fost stearsa din Tabela de Unelte." -#: FlatCAMObj.py:4533 flatcamGUI/ObjectUI.py:1353 -msgid "Parameters for" -msgstr "Parametri pt" - -#: FlatCAMObj.py:4967 +#: FlatCAMObj.py:5523 msgid "This Geometry can't be processed because it is" msgstr "Acest obiect Geometrie nu poate fi procesat deoarece" -#: FlatCAMObj.py:4969 +#: FlatCAMObj.py:5523 msgid "geometry" msgstr "geometria" -#: FlatCAMObj.py:5012 +#: FlatCAMObj.py:5564 msgid "Failed. No tool selected in the tool table ..." msgstr "Eșuat. Nici-o unealtă nu este selectată in Tabela de Unelte ..." -#: FlatCAMObj.py:5112 FlatCAMObj.py:5264 +#: FlatCAMObj.py:5667 FlatCAMObj.py:5820 msgid "" "Tool Offset is selected in Tool Table but no value is provided.\n" "Add a Tool Offset or change the Offset Type." @@ -2588,44 +2977,44 @@ msgstr "" "este oferita.\n" "Adaugă un ofset pt unealtă sau schimbă Tipul Ofset." -#: FlatCAMObj.py:5177 FlatCAMObj.py:5325 +#: FlatCAMObj.py:5733 FlatCAMObj.py:5882 msgid "G-Code parsing in progress..." msgstr "Analiza codului G în curs ..." -#: FlatCAMObj.py:5179 FlatCAMObj.py:5327 +#: FlatCAMObj.py:5735 FlatCAMObj.py:5884 msgid "G-Code parsing finished..." msgstr "Analizarea codului G s-a terminat ..." -#: FlatCAMObj.py:5187 +#: FlatCAMObj.py:5743 msgid "Finished G-Code processing" msgstr "Prelucrarea G-Code terminată" -#: FlatCAMObj.py:5189 FlatCAMObj.py:5339 +#: FlatCAMObj.py:5745 FlatCAMObj.py:5896 msgid "G-Code processing failed with error" msgstr "Procesarea G-Code a eșuat cu eroarea" -#: FlatCAMObj.py:5234 flatcamTools/ToolSolderPaste.py:1303 +#: FlatCAMObj.py:5790 flatcamTools/ToolSolderPaste.py:1300 msgid "Cancelled. Empty file, it has no geometry" msgstr "Anulat. Fişier gol, nu are geometrie" -#: FlatCAMObj.py:5337 FlatCAMObj.py:5486 +#: FlatCAMObj.py:5894 FlatCAMObj.py:6055 msgid "Finished G-Code processing..." msgstr "Prelucrarea G-Code terminată ..." -#: FlatCAMObj.py:5356 FlatCAMObj.py:5360 FlatCAMObj.py:5496 +#: FlatCAMObj.py:5913 FlatCAMObj.py:5917 FlatCAMObj.py:6062 msgid "CNCjob created" msgstr "CNCjob creat" -#: FlatCAMObj.py:5527 FlatCAMObj.py:5536 flatcamParsers/ParseGerber.py:1794 -#: flatcamParsers/ParseGerber.py:1804 +#: FlatCAMObj.py:6092 FlatCAMObj.py:6101 flatcamParsers/ParseGerber.py:1866 +#: flatcamParsers/ParseGerber.py:1876 msgid "Scale factor has to be a number: integer or float." msgstr "Factorul de scalare trebuie să fie un număr: natural sau real." -#: FlatCAMObj.py:5600 +#: FlatCAMObj.py:6164 msgid "Geometry Scale done." msgstr "Scalare Geometrie executată." -#: FlatCAMObj.py:5617 flatcamParsers/ParseGerber.py:1920 +#: FlatCAMObj.py:6181 flatcamParsers/ParseGerber.py:1992 msgid "" "An (x,y) pair of values are needed. Probable you entered only one value in " "the Offset field." @@ -2633,11 +3022,11 @@ msgstr "" "O pereche de valori (x,y) este necesară. Probabil că ai introdus numai o " "singură valoare in câmpul Offset." -#: FlatCAMObj.py:5674 +#: FlatCAMObj.py:6237 msgid "Geometry Offset done." msgstr "Ofset Geometrie executat." -#: FlatCAMObj.py:5703 +#: FlatCAMObj.py:6266 msgid "" "The Toolchange X,Y field in Edit -> Preferences has to be in the format (x, " "y)\n" @@ -2647,84 +3036,84 @@ msgstr "" "in formatul (x, y) \n" "dar are o singură valoare in loc de două." -#: FlatCAMObj.py:6388 FlatCAMObj.py:7175 FlatCAMObj.py:7371 +#: FlatCAMObj.py:6956 FlatCAMObj.py:7802 FlatCAMObj.py:7999 msgid "Basic" msgstr "Baza" -#: FlatCAMObj.py:6394 FlatCAMObj.py:7179 FlatCAMObj.py:7375 +#: FlatCAMObj.py:6962 FlatCAMObj.py:7806 FlatCAMObj.py:8003 msgid "Advanced" msgstr "Avansat" -#: FlatCAMObj.py:6437 +#: FlatCAMObj.py:7005 msgid "Plotting..." msgstr "Se afișează..." -#: FlatCAMObj.py:6460 FlatCAMObj.py:6465 flatcamTools/ToolSolderPaste.py:1509 +#: FlatCAMObj.py:7034 FlatCAMObj.py:7039 flatcamTools/ToolSolderPaste.py:1498 msgid "Export Machine Code ..." msgstr "Exportă CNC Cod Masina ..." -#: FlatCAMObj.py:6470 flatcamTools/ToolSolderPaste.py:1513 +#: FlatCAMObj.py:7044 flatcamTools/ToolSolderPaste.py:1502 msgid "Export Machine Code cancelled ..." msgstr "Exportul Codului Mașina a fost anulat ..." -#: FlatCAMObj.py:6492 +#: FlatCAMObj.py:7065 msgid "Machine Code file saved to" msgstr "Fişierul cu cod CNC este salvat in" -#: FlatCAMObj.py:6546 flatcamTools/ToolCalibration.py:1083 +#: FlatCAMObj.py:7126 flatcamTools/ToolCalibration.py:1097 msgid "Loaded Machine Code into Code Editor" msgstr "S-a încărcat Codul Maşină în Editorul Cod" -#: FlatCAMObj.py:6684 +#: FlatCAMObj.py:7265 msgid "This CNCJob object can't be processed because it is a" msgstr "Acest obiect CNCJob nu poate fi procesat deoarece este un" -#: FlatCAMObj.py:6686 +#: FlatCAMObj.py:7267 msgid "CNCJob object" msgstr "Obiect CNCJob" -#: FlatCAMObj.py:6866 +#: FlatCAMObj.py:7447 msgid "" "G-code does not have a G94 code and we will not include the code in the " "'Prepend to GCode' text box" msgstr "" "Codul G nu are un cod G94 și nu vom include codul din caseta de text „Adaugă " -"la GCode”." +"la GCode”" -#: FlatCAMObj.py:6877 +#: FlatCAMObj.py:7458 msgid "Cancelled. The Toolchange Custom code is enabled but it's empty." msgstr "" "Anulat. Codul G-Code din Macro-ul Schimbare unealtă este activat dar nu " "contine nimic." -#: FlatCAMObj.py:6882 +#: FlatCAMObj.py:7463 msgid "Toolchange G-code was replaced by a custom code." msgstr "G-Code-ul pt schimbare unealtă a fost inlocuit cu un cod pesonalizat." -#: FlatCAMObj.py:6899 flatcamEditors/FlatCAMTextEditor.py:270 -#: flatcamTools/ToolSolderPaste.py:1540 +#: FlatCAMObj.py:7480 flatcamEditors/FlatCAMTextEditor.py:272 +#: flatcamTools/ToolSolderPaste.py:1529 msgid "No such file or directory" msgstr "Nu exista un aşa fişier sau director" -#: FlatCAMObj.py:6913 flatcamEditors/FlatCAMTextEditor.py:282 +#: FlatCAMObj.py:7494 flatcamEditors/FlatCAMTextEditor.py:284 msgid "Saved to" msgstr "Salvat in" -#: FlatCAMObj.py:6923 FlatCAMObj.py:6933 +#: FlatCAMObj.py:7511 FlatCAMObj.py:7521 msgid "" "The used preprocessor file has to have in it's name: 'toolchange_custom'" msgstr "" "Postprocesorul folosit trebuie să aibă in numele sau: 'toolchange_custom'" -#: FlatCAMObj.py:6937 +#: FlatCAMObj.py:7524 msgid "There is no preprocessor file." msgstr "Nu exista nici-un fişier postprocesor." -#: FlatCAMObj.py:7194 +#: FlatCAMObj.py:7821 msgid "Script Editor" msgstr "Editor Script" -#: FlatCAMObj.py:7475 +#: FlatCAMObj.py:8103 msgid "Document Editor" msgstr "Editor Documente" @@ -2732,6 +3121,16 @@ msgstr "Editor Documente" msgid "processes running." msgstr "procesele care rulează." +#: FlatCAMTool.py:245 FlatCAMTool.py:252 flatcamGUI/ObjectUI.py:156 +#: flatcamGUI/ObjectUI.py:163 +msgid "Edited value is out of range" +msgstr "Valoarea editată este in afara limitelor" + +#: FlatCAMTool.py:247 FlatCAMTool.py:254 flatcamGUI/ObjectUI.py:158 +#: flatcamGUI/ObjectUI.py:165 +msgid "Edited value is within limits." +msgstr "Valoarea editată este in limite." + #: FlatCAMTranslation.py:103 msgid "The application will restart." msgstr "Aplicaţia va reporni ..." @@ -2744,68 +3143,68 @@ msgstr "Esti sigur că dorești să schimbi din limba curentă in" msgid "Apply Language ..." msgstr "Aplică Traducere ..." -#: ObjectCollection.py:459 +#: ObjectCollection.py:506 #, python-brace-format msgid "Object renamed from {old} to {new}" msgstr "Obiectul este redenumit din {old} in {new}" -#: ObjectCollection.py:858 +#: ObjectCollection.py:972 msgid "Cause of error" msgstr "Motivul erorii" -#: camlib.py:590 +#: camlib.py:593 msgid "self.solid_geometry is neither BaseGeometry or list." msgstr "self.solid_geometry nu este tip BaseGeometry sau tip listă." -#: camlib.py:953 +#: camlib.py:968 msgid "Pass" msgstr "Treceri" -#: camlib.py:974 +#: camlib.py:988 msgid "Get Exteriors" msgstr "Obtine Exterior" -#: camlib.py:977 +#: camlib.py:991 msgid "Get Interiors" msgstr "Obtine Interioare" -#: camlib.py:1964 +#: camlib.py:2172 msgid "Object was mirrored" msgstr "Obiectul a fost oglindit" -#: camlib.py:1967 +#: camlib.py:2175 msgid "Failed to mirror. No object selected" msgstr "Oglindire eșuată. Nici-un obiect nu este selectat" -#: camlib.py:2036 +#: camlib.py:2244 msgid "Object was rotated" msgstr "Obiectul a fost rotit" -#: camlib.py:2039 +#: camlib.py:2247 msgid "Failed to rotate. No object selected" msgstr "Rotaţie eșuată. Nici-un obiect nu este selectat" -#: camlib.py:2107 +#: camlib.py:2314 msgid "Object was skewed" msgstr "Obiectul a fost deformat" -#: camlib.py:2110 +#: camlib.py:2317 msgid "Failed to skew. No object selected" msgstr "Deformare eșuată. Nici-un obiect nu este selectat" -#: camlib.py:2179 +#: camlib.py:2392 msgid "Object was buffered" msgstr "Obiectul a fost tamponat" -#: camlib.py:2181 +#: camlib.py:2394 msgid "Failed to buffer. No object selected" msgstr "Eroare in a face buffer. Nu a fost selectat niciun obiect" -#: camlib.py:2378 +#: camlib.py:2599 msgid "There is no such parameter" msgstr "Nu exista un asemenea parametru" -#: camlib.py:2454 +#: camlib.py:2659 camlib.py:2892 camlib.py:3121 camlib.py:3343 msgid "" "The Cut Z parameter has positive value. It is the depth value to drill into " "material.\n" @@ -2818,13 +3217,14 @@ msgstr "" "Se presupune că este o eroare de tastare astfel ca aplicaţia va converti " "intr-o valoare negativă. Verifică codul masina (G-Code etc) rezultat." -#: camlib.py:2462 camlib.py:3181 camlib.py:3539 +#: camlib.py:2667 camlib.py:2902 camlib.py:3131 camlib.py:3353 camlib.py:3639 +#: camlib.py:4008 msgid "The Cut Z parameter is zero. There will be no cut, skipping file" msgstr "" "Parametrul >Z tăiere< este nul. Nu va fi nici-o tăiere prin urmare nu " "procesam fişierul" -#: camlib.py:2475 camlib.py:3512 +#: camlib.py:2678 camlib.py:3976 msgid "" "The Toolchange X,Y field in Edit -> Preferences has to be in the format (x, " "y) \n" @@ -2834,31 +3234,39 @@ msgstr "" "in formatul (x, y) \n" "dar are o singură valoare in loc de doua. " -#: camlib.py:2550 +#: camlib.py:2687 camlib.py:3590 camlib.py:3958 +msgid "" +"The End Move X,Y field in Edit -> Preferences has to be in the format (x, y) " +"but now there is only one value, not two." +msgstr "" +"Parametrul >Schimbare Unealtă X, Y< in Editare -> Peferințe trebuie să fie " +"in formatul (x, y) dar are o singură valoare in loc de două." + +#: camlib.py:2775 msgid "Creating a list of points to drill..." msgstr "Crearea unei liste de puncte pentru găurire ..." -#: camlib.py:2632 +#: camlib.py:2865 camlib.py:3737 camlib.py:4112 msgid "Starting G-Code" msgstr "Începând G-Code" -#: camlib.py:2727 camlib.py:2870 camlib.py:2972 camlib.py:3292 camlib.py:3653 +#: camlib.py:3006 camlib.py:3225 camlib.py:3389 camlib.py:3750 camlib.py:4123 msgid "Starting G-Code for tool with diameter" msgstr "Pornirea codului G pentru scula cu diametrul" -#: camlib.py:2783 camlib.py:2926 camlib.py:3029 +#: camlib.py:3089 camlib.py:3307 camlib.py:3475 msgid "G91 coordinates not implemented" msgstr "Coordonatele G91 nu au fost implementate" -#: camlib.py:2789 camlib.py:2933 camlib.py:3035 +#: camlib.py:3095 camlib.py:3314 camlib.py:3481 msgid "The loaded Excellon file has no drills" msgstr "Fişierul Excellon incărcat nu are găuri" -#: camlib.py:3058 +#: camlib.py:3504 msgid "Finished G-Code generation..." msgstr "Generarea G-Code finalizata ..." -#: camlib.py:3153 +#: camlib.py:3608 msgid "" "The Toolchange X,Y field in Edit -> Preferences has to be in the format (x, " "y) \n" @@ -2868,7 +3276,7 @@ msgstr "" "in formatul (x, y) \n" "dar are o singură valoare in loc de doua." -#: camlib.py:3166 camlib.py:3525 +#: camlib.py:3622 camlib.py:3991 msgid "" "Cut_Z parameter is None or zero. Most likely a bad combinations of other " "parameters." @@ -2876,7 +3284,7 @@ msgstr "" "Parametrul >Z tăiere< este None sau zero. Cel mai probabil o combinaţie " "nefericita de parametri." -#: camlib.py:3173 camlib.py:3531 +#: camlib.py:3631 camlib.py:4000 msgid "" "The Cut Z parameter has positive value. It is the depth value to cut into " "material.\n" @@ -2889,11 +3297,11 @@ msgstr "" "Se presupune că este o eroare de tastare astfel ca aplicaţia va converti " "intr-o valoare negativă. Verifică codul masina (G-Code etc) rezultat." -#: camlib.py:3186 camlib.py:3545 +#: camlib.py:3644 camlib.py:4014 msgid "Travel Z parameter is None or zero." msgstr "Parametrul >Z deplasare< este None sau zero." -#: camlib.py:3191 camlib.py:3550 +#: camlib.py:3649 camlib.py:4019 msgid "" "The Travel Z parameter has negative value. It is the height value to travel " "between cuts.\n" @@ -2906,40 +3314,36 @@ msgstr "" "Se presupune că este o eroare de tastare astfel ca aplicaţia va converti " "intr-o valoare pozitivă. Verifică codul masina (G-Code etc) rezultat." -#: camlib.py:3199 camlib.py:3558 +#: camlib.py:3657 camlib.py:4027 msgid "The Z Travel parameter is zero. This is dangerous, skipping file" msgstr "" "Parametrul >Z deplasare< este zero. Aceasta este periculos, prin urmare nu " "se procesează fişierul" -#: camlib.py:3218 camlib.py:3580 +#: camlib.py:3676 camlib.py:4050 msgid "Indexing geometry before generating G-Code..." msgstr "Geometria se indexeaza înainte de a genera G-Code..." -#: camlib.py:3279 camlib.py:3642 -msgid "Starting G-Code..." -msgstr "Pornirea G-Code ..." - -#: camlib.py:3362 camlib.py:3724 +#: camlib.py:3820 camlib.py:4192 msgid "Finished G-Code generation" msgstr "Generarea G-Code terminată" -#: camlib.py:3364 +#: camlib.py:3820 msgid "paths traced" msgstr "căi trasate" -#: camlib.py:3399 +#: camlib.py:3853 msgid "Expected a Geometry, got" msgstr "Se astepta o Geometrie, am primit in schimb" -#: camlib.py:3406 +#: camlib.py:3860 msgid "" "Trying to generate a CNC Job from a Geometry object without solid_geometry." msgstr "" "Se încearcă generarea unui CNC Job dintr-un obiect Geometrie fără atributul " "solid_geometry." -#: camlib.py:3446 +#: camlib.py:3901 msgid "" "The Tool Offset value is too negative to use for the current_geometry.\n" "Raise the value (in module) and try again." @@ -2948,35 +3352,35 @@ msgstr "" "current_geometry \n" "Mareste valoarea absoluta și încearcă din nou." -#: camlib.py:3724 +#: camlib.py:4192 msgid " paths traced." msgstr " căi trasate." -#: camlib.py:3752 +#: camlib.py:4220 msgid "There is no tool data in the SolderPaste geometry." msgstr "Nu există date cu privire la unealtă in Geometria SolderPaste." -#: camlib.py:3839 +#: camlib.py:4306 msgid "Finished SolderPste G-Code generation" msgstr "Generarea G-Code SolderPaste s-a terminat" -#: camlib.py:3841 +#: camlib.py:4306 msgid "paths traced." msgstr "căi trasate." -#: camlib.py:4097 +#: camlib.py:4566 msgid "Parsing GCode file. Number of lines" msgstr "Analizând fișierul GCode. Numărul de linii" -#: camlib.py:4204 +#: camlib.py:4673 msgid "Creating Geometry from the parsed GCode file. " msgstr "Crează un obiect tip Geometrie din fisierul GCode analizat. " -#: camlib.py:4345 camlib.py:4629 camlib.py:4732 camlib.py:4801 +#: camlib.py:4816 camlib.py:5101 camlib.py:5204 camlib.py:5360 msgid "G91 coordinates not implemented ..." msgstr "Coordonatele G91 nu au fost implementate ..." -#: camlib.py:4476 +#: camlib.py:4948 msgid "Unifying Geometry from parsed Geometry segments" msgstr "Se unifica Geometria din segmentele de Geometrie parsate" @@ -3008,11 +3412,11 @@ msgstr "" #: flatcamEditors/FlatCAMExcEditor.py:193 #: flatcamEditors/FlatCAMExcEditor.py:416 #: flatcamEditors/FlatCAMExcEditor.py:637 -#: flatcamEditors/FlatCAMExcEditor.py:1155 -#: flatcamEditors/FlatCAMExcEditor.py:1182 +#: flatcamEditors/FlatCAMExcEditor.py:1152 +#: flatcamEditors/FlatCAMExcEditor.py:1179 #: flatcamEditors/FlatCAMGrbEditor.py:471 -#: flatcamEditors/FlatCAMGrbEditor.py:1936 -#: flatcamEditors/FlatCAMGrbEditor.py:1966 +#: flatcamEditors/FlatCAMGrbEditor.py:1935 +#: flatcamEditors/FlatCAMGrbEditor.py:1965 msgid "Click on target location ..." msgstr "Click pe locatia tintă ..." @@ -3046,8 +3450,8 @@ msgstr "Pentru a adăuga un slot mai întâi, selectați o unealtă" #: flatcamEditors/FlatCAMExcEditor.py:455 #: flatcamEditors/FlatCAMExcEditor.py:462 -#: flatcamEditors/FlatCAMExcEditor.py:744 -#: flatcamEditors/FlatCAMExcEditor.py:751 +#: flatcamEditors/FlatCAMExcEditor.py:743 +#: flatcamEditors/FlatCAMExcEditor.py:750 msgid "Value is missing or wrong format. Add it and retry." msgstr "" "Valoarea lipsește sau formatul greșit. Adăugați-l și încercați din nou." @@ -3066,73 +3470,67 @@ msgstr "" msgid "Click on the Slot Circular Array Start position" msgstr "Faceți clic pe poziția de pornire a ariei circulare de slotuluri" -#: flatcamEditors/FlatCAMExcEditor.py:682 -#: flatcamEditors/FlatCAMGrbEditor.py:520 +#: flatcamEditors/FlatCAMExcEditor.py:681 +#: flatcamEditors/FlatCAMGrbEditor.py:519 msgid "The value is mistyped. Check the value." msgstr "Valoarea este gresită. Verifică ce ai introdus." -#: flatcamEditors/FlatCAMExcEditor.py:861 +#: flatcamEditors/FlatCAMExcEditor.py:860 msgid "Too many Slots for the selected spacing angle." msgstr "Prea multe sloturi pentru unghiul de distanțare selectat." -#: flatcamEditors/FlatCAMExcEditor.py:884 +#: flatcamEditors/FlatCAMExcEditor.py:883 msgid "Done. Slot Array added." msgstr "Terminat. S-a adăugat aria de sloturi." -#: flatcamEditors/FlatCAMExcEditor.py:906 +#: flatcamEditors/FlatCAMExcEditor.py:905 msgid "Click on the Drill(s) to resize ..." msgstr "" "Click pe operațiunile de găurire care se dorește să fie redimensionate ..." -#: flatcamEditors/FlatCAMExcEditor.py:936 +#: flatcamEditors/FlatCAMExcEditor.py:935 msgid "Resize drill(s) failed. Please enter a diameter for resize." msgstr "" "Redimensionarea operațiunilor de găurire a eșuat. Adaugă o valoare pentru " "dimetrul la care se face redimensionarea." -#: flatcamEditors/FlatCAMExcEditor.py:1026 -#: flatcamEditors/FlatCAMExcEditor.py:1095 flatcamGUI/FlatCAMGUI.py:3165 -#: flatcamGUI/FlatCAMGUI.py:3377 flatcamGUI/FlatCAMGUI.py:3591 -msgid "Cancelled." -msgstr "Anulat." - -#: flatcamEditors/FlatCAMExcEditor.py:1116 +#: flatcamEditors/FlatCAMExcEditor.py:1113 msgid "Done. Drill/Slot Resize completed." msgstr "Executat. Redimensionarea Perforării / slotului finalizată." -#: flatcamEditors/FlatCAMExcEditor.py:1119 +#: flatcamEditors/FlatCAMExcEditor.py:1116 msgid "Cancelled. No drills/slots selected for resize ..." msgstr "Anulat. Nu au fost selectate găuri / sloturi pentru redimensionare ..." -#: flatcamEditors/FlatCAMExcEditor.py:1157 -#: flatcamEditors/FlatCAMGrbEditor.py:1938 +#: flatcamEditors/FlatCAMExcEditor.py:1154 +#: flatcamEditors/FlatCAMGrbEditor.py:1937 msgid "Click on reference location ..." msgstr "Click pe locatia de referinţă ..." -#: flatcamEditors/FlatCAMExcEditor.py:1214 +#: flatcamEditors/FlatCAMExcEditor.py:1211 msgid "Done. Drill(s) Move completed." msgstr "Executat. Operatiile de găurire au fost mutate." -#: flatcamEditors/FlatCAMExcEditor.py:1322 +#: flatcamEditors/FlatCAMExcEditor.py:1319 msgid "Done. Drill(s) copied." msgstr "Executat. Operatiile de găurire au fost copiate." -#: flatcamEditors/FlatCAMExcEditor.py:1555 flatcamGUI/PreferencesUI.py:3551 +#: flatcamEditors/FlatCAMExcEditor.py:1558 flatcamGUI/PreferencesUI.py:3829 msgid "Excellon Editor" msgstr "Editor Excellon" -#: flatcamEditors/FlatCAMExcEditor.py:1562 -#: flatcamEditors/FlatCAMGrbEditor.py:2454 +#: flatcamEditors/FlatCAMExcEditor.py:1565 +#: flatcamEditors/FlatCAMGrbEditor.py:2460 msgid "Name:" msgstr "Nume:" -#: flatcamEditors/FlatCAMExcEditor.py:1568 flatcamGUI/ObjectUI.py:757 -#: flatcamGUI/ObjectUI.py:1184 flatcamTools/ToolNonCopperClear.py:109 -#: flatcamTools/ToolPaint.py:112 flatcamTools/ToolSolderPaste.py:73 +#: flatcamEditors/FlatCAMExcEditor.py:1571 flatcamGUI/ObjectUI.py:760 +#: flatcamGUI/ObjectUI.py:1463 flatcamTools/ToolNCC.py:120 +#: flatcamTools/ToolPaint.py:115 flatcamTools/ToolSolderPaste.py:75 msgid "Tools Table" msgstr "Tabela Unelte" -#: flatcamEditors/FlatCAMExcEditor.py:1570 flatcamGUI/ObjectUI.py:759 +#: flatcamEditors/FlatCAMExcEditor.py:1573 flatcamGUI/ObjectUI.py:762 msgid "" "Tools in this Excellon object\n" "when are used for drilling." @@ -3140,11 +3538,11 @@ msgstr "" "Burghie (unelte) in acest obiect Excellon\n" "când se face găurire." -#: flatcamEditors/FlatCAMExcEditor.py:1590 +#: flatcamEditors/FlatCAMExcEditor.py:1593 msgid "Add/Delete Tool" msgstr "Adaugă/Șterge Unealta" -#: flatcamEditors/FlatCAMExcEditor.py:1592 +#: flatcamEditors/FlatCAMExcEditor.py:1595 msgid "" "Add/Delete a tool to the tool list\n" "for this Excellon object." @@ -3152,16 +3550,16 @@ msgstr "" "Adaugă/Șterge o unealtă la lista de unelte\n" "pentru acest obiect Excellon." -#: flatcamEditors/FlatCAMExcEditor.py:1604 flatcamGUI/ObjectUI.py:1297 -#: flatcamGUI/PreferencesUI.py:3582 +#: flatcamEditors/FlatCAMExcEditor.py:1607 flatcamGUI/ObjectUI.py:1583 +#: flatcamGUI/PreferencesUI.py:3860 msgid "Diameter for the new tool" msgstr "Diametru pentru noua unealtă (burghiu, freza)" -#: flatcamEditors/FlatCAMExcEditor.py:1614 +#: flatcamEditors/FlatCAMExcEditor.py:1617 msgid "Add Tool" msgstr "Adaugă Unealta" -#: flatcamEditors/FlatCAMExcEditor.py:1616 +#: flatcamEditors/FlatCAMExcEditor.py:1619 msgid "" "Add a new tool to the tool list\n" "with the diameter specified above." @@ -3169,11 +3567,11 @@ msgstr "" "Adaugă o unealtă noua la lista de unelte\n" "cu diametrul specificat deasupra." -#: flatcamEditors/FlatCAMExcEditor.py:1628 +#: flatcamEditors/FlatCAMExcEditor.py:1631 msgid "Delete Tool" msgstr "Șterge Unealta" -#: flatcamEditors/FlatCAMExcEditor.py:1630 +#: flatcamEditors/FlatCAMExcEditor.py:1633 msgid "" "Delete a tool in the tool list\n" "by selecting a row in the tool table." @@ -3181,42 +3579,42 @@ msgstr "" "Șterge o unealtă in lista de unelte\n" "prin selectarea unei linii in tabela de unelte." -#: flatcamEditors/FlatCAMExcEditor.py:1648 flatcamGUI/FlatCAMGUI.py:1896 +#: flatcamEditors/FlatCAMExcEditor.py:1651 flatcamGUI/FlatCAMGUI.py:2004 msgid "Resize Drill(s)" msgstr "Redimensionare operațiuni de găurire" -#: flatcamEditors/FlatCAMExcEditor.py:1650 +#: flatcamEditors/FlatCAMExcEditor.py:1653 msgid "Resize a drill or a selection of drills." msgstr "" "Redimensionează o operaţie de găurire sau o selecţie de operațiuni de " "găurire." -#: flatcamEditors/FlatCAMExcEditor.py:1657 +#: flatcamEditors/FlatCAMExcEditor.py:1660 msgid "Resize Dia" msgstr "Redimens. Dia" -#: flatcamEditors/FlatCAMExcEditor.py:1659 +#: flatcamEditors/FlatCAMExcEditor.py:1662 msgid "Diameter to resize to." msgstr "Diametrul la care se face redimensionarea." -#: flatcamEditors/FlatCAMExcEditor.py:1670 +#: flatcamEditors/FlatCAMExcEditor.py:1673 msgid "Resize" msgstr "Redimensionează" -#: flatcamEditors/FlatCAMExcEditor.py:1672 +#: flatcamEditors/FlatCAMExcEditor.py:1675 msgid "Resize drill(s)" msgstr "Redimensionează op. de găurire." -#: flatcamEditors/FlatCAMExcEditor.py:1697 flatcamGUI/FlatCAMGUI.py:1895 -#: flatcamGUI/FlatCAMGUI.py:2147 +#: flatcamEditors/FlatCAMExcEditor.py:1700 flatcamGUI/FlatCAMGUI.py:2003 +#: flatcamGUI/FlatCAMGUI.py:2255 msgid "Add Drill Array" msgstr "Adaugă o arie de op. găurire" -#: flatcamEditors/FlatCAMExcEditor.py:1699 +#: flatcamEditors/FlatCAMExcEditor.py:1702 msgid "Add an array of drills (linear or circular array)" msgstr "Adaugă o arie de operațiuni de găurire (arie lineara sau circulara)." -#: flatcamEditors/FlatCAMExcEditor.py:1705 +#: flatcamEditors/FlatCAMExcEditor.py:1708 msgid "" "Select the type of drills array to create.\n" "It can be Linear X(Y) or Circular" @@ -3224,43 +3622,48 @@ msgstr "" "Selectează tipul de arii de operațiuni de găurire.\n" "Poate fi Liniar X(Y) sau Circular" -#: flatcamEditors/FlatCAMExcEditor.py:1708 -#: flatcamEditors/FlatCAMExcEditor.py:1922 -#: flatcamEditors/FlatCAMGrbEditor.py:2766 +#: flatcamEditors/FlatCAMExcEditor.py:1711 +#: flatcamEditors/FlatCAMExcEditor.py:1925 +#: flatcamEditors/FlatCAMGrbEditor.py:2772 msgid "Linear" msgstr "Liniar" -#: flatcamEditors/FlatCAMExcEditor.py:1709 -#: flatcamEditors/FlatCAMExcEditor.py:1923 -#: flatcamEditors/FlatCAMGrbEditor.py:2767 flatcamGUI/ObjectUI.py:311 -#: flatcamGUI/PreferencesUI.py:5044 flatcamGUI/PreferencesUI.py:7465 -#: flatcamTools/ToolFiducials.py:220 flatcamTools/ToolNonCopperClear.py:221 +#: flatcamEditors/FlatCAMExcEditor.py:1712 +#: flatcamEditors/FlatCAMExcEditor.py:1926 +#: flatcamEditors/FlatCAMGrbEditor.py:2773 flatcamGUI/ObjectUI.py:315 +#: flatcamGUI/PreferencesUI.py:5340 flatcamGUI/PreferencesUI.py:5909 +#: flatcamGUI/PreferencesUI.py:7971 flatcamGUI/PreferencesUI.py:8151 +#: flatcamGUI/PreferencesUI.py:8248 flatcamGUI/PreferencesUI.py:8363 +#: flatcamGUI/PreferencesUI.py:8462 flatcamTools/ToolExtractDrills.py:78 +#: flatcamTools/ToolExtractDrills.py:201 flatcamTools/ToolFiducials.py:220 +#: flatcamTools/ToolNCC.py:221 flatcamTools/ToolPaint.py:204 +#: flatcamTools/ToolPunchGerber.py:89 flatcamTools/ToolPunchGerber.py:229 msgid "Circular" msgstr "Circular" -#: flatcamEditors/FlatCAMExcEditor.py:1717 flatcamGUI/PreferencesUI.py:3593 +#: flatcamEditors/FlatCAMExcEditor.py:1720 flatcamGUI/PreferencesUI.py:3871 msgid "Nr of drills" msgstr "Nr. op. găurire" -#: flatcamEditors/FlatCAMExcEditor.py:1718 flatcamGUI/PreferencesUI.py:3595 +#: flatcamEditors/FlatCAMExcEditor.py:1721 flatcamGUI/PreferencesUI.py:3873 msgid "Specify how many drills to be in the array." msgstr "Specifica cate operațiuni de găurire să fie incluse in arie." -#: flatcamEditors/FlatCAMExcEditor.py:1736 -#: flatcamEditors/FlatCAMExcEditor.py:1786 -#: flatcamEditors/FlatCAMExcEditor.py:1858 -#: flatcamEditors/FlatCAMExcEditor.py:1951 -#: flatcamEditors/FlatCAMExcEditor.py:2002 -#: flatcamEditors/FlatCAMGrbEditor.py:1572 -#: flatcamEditors/FlatCAMGrbEditor.py:2795 -#: flatcamEditors/FlatCAMGrbEditor.py:2844 flatcamGUI/PreferencesUI.py:3703 +#: flatcamEditors/FlatCAMExcEditor.py:1739 +#: flatcamEditors/FlatCAMExcEditor.py:1789 +#: flatcamEditors/FlatCAMExcEditor.py:1861 +#: flatcamEditors/FlatCAMExcEditor.py:1954 +#: flatcamEditors/FlatCAMExcEditor.py:2005 +#: flatcamEditors/FlatCAMGrbEditor.py:1571 +#: flatcamEditors/FlatCAMGrbEditor.py:2801 +#: flatcamEditors/FlatCAMGrbEditor.py:2850 flatcamGUI/PreferencesUI.py:3981 msgid "Direction" msgstr "Direcţie" -#: flatcamEditors/FlatCAMExcEditor.py:1738 -#: flatcamEditors/FlatCAMExcEditor.py:1953 -#: flatcamEditors/FlatCAMGrbEditor.py:2797 flatcamGUI/PreferencesUI.py:2536 -#: flatcamGUI/PreferencesUI.py:3611 flatcamGUI/PreferencesUI.py:3759 +#: flatcamEditors/FlatCAMExcEditor.py:1741 +#: flatcamEditors/FlatCAMExcEditor.py:1956 +#: flatcamEditors/FlatCAMGrbEditor.py:2803 flatcamGUI/PreferencesUI.py:2718 +#: flatcamGUI/PreferencesUI.py:3889 flatcamGUI/PreferencesUI.py:4037 msgid "" "Direction on which the linear array is oriented:\n" "- 'X' - horizontal axis \n" @@ -3272,62 +3675,62 @@ msgstr "" "- 'Y' - pe axa verticala sau \n" "- 'Unghi' - un unghi particular pentru inclinatia ariei" -#: flatcamEditors/FlatCAMExcEditor.py:1745 -#: flatcamEditors/FlatCAMExcEditor.py:1867 -#: flatcamEditors/FlatCAMExcEditor.py:1960 -#: flatcamEditors/FlatCAMGrbEditor.py:2804 flatcamGUI/PreferencesUI.py:2542 -#: flatcamGUI/PreferencesUI.py:3617 flatcamGUI/PreferencesUI.py:3712 -#: flatcamGUI/PreferencesUI.py:3765 flatcamGUI/PreferencesUI.py:5853 +#: flatcamEditors/FlatCAMExcEditor.py:1748 +#: flatcamEditors/FlatCAMExcEditor.py:1870 +#: flatcamEditors/FlatCAMExcEditor.py:1963 +#: flatcamEditors/FlatCAMGrbEditor.py:2810 flatcamGUI/PreferencesUI.py:2724 +#: flatcamGUI/PreferencesUI.py:3895 flatcamGUI/PreferencesUI.py:3990 +#: flatcamGUI/PreferencesUI.py:4043 flatcamGUI/PreferencesUI.py:6341 #: flatcamTools/ToolFilm.py:256 msgid "X" msgstr "X" -#: flatcamEditors/FlatCAMExcEditor.py:1746 -#: flatcamEditors/FlatCAMExcEditor.py:1868 -#: flatcamEditors/FlatCAMExcEditor.py:1961 -#: flatcamEditors/FlatCAMGrbEditor.py:2805 flatcamGUI/PreferencesUI.py:2543 -#: flatcamGUI/PreferencesUI.py:3618 flatcamGUI/PreferencesUI.py:3713 -#: flatcamGUI/PreferencesUI.py:3766 flatcamGUI/PreferencesUI.py:5854 +#: flatcamEditors/FlatCAMExcEditor.py:1749 +#: flatcamEditors/FlatCAMExcEditor.py:1871 +#: flatcamEditors/FlatCAMExcEditor.py:1964 +#: flatcamEditors/FlatCAMGrbEditor.py:2811 flatcamGUI/PreferencesUI.py:2725 +#: flatcamGUI/PreferencesUI.py:3896 flatcamGUI/PreferencesUI.py:3991 +#: flatcamGUI/PreferencesUI.py:4044 flatcamGUI/PreferencesUI.py:6342 #: flatcamTools/ToolFilm.py:257 msgid "Y" msgstr "Y" -#: flatcamEditors/FlatCAMExcEditor.py:1747 -#: flatcamEditors/FlatCAMExcEditor.py:1764 -#: flatcamEditors/FlatCAMExcEditor.py:1798 -#: flatcamEditors/FlatCAMExcEditor.py:1869 -#: flatcamEditors/FlatCAMExcEditor.py:1873 -#: flatcamEditors/FlatCAMExcEditor.py:1962 -#: flatcamEditors/FlatCAMExcEditor.py:1980 -#: flatcamEditors/FlatCAMExcEditor.py:2014 -#: flatcamEditors/FlatCAMGrbEditor.py:2806 -#: flatcamEditors/FlatCAMGrbEditor.py:2823 -#: flatcamEditors/FlatCAMGrbEditor.py:2859 flatcamGUI/PreferencesUI.py:2544 -#: flatcamGUI/PreferencesUI.py:2562 flatcamGUI/PreferencesUI.py:3619 -#: flatcamGUI/PreferencesUI.py:3638 flatcamGUI/PreferencesUI.py:3714 -#: flatcamGUI/PreferencesUI.py:3719 flatcamGUI/PreferencesUI.py:3767 -#: flatcamGUI/PreferencesUI.py:3788 flatcamGUI/PreferencesUI.py:6246 -#: flatcamTools/ToolDistance.py:66 flatcamTools/ToolDistanceMin.py:68 -#: flatcamTools/ToolTransform.py:63 +#: flatcamEditors/FlatCAMExcEditor.py:1750 +#: flatcamEditors/FlatCAMExcEditor.py:1767 +#: flatcamEditors/FlatCAMExcEditor.py:1801 +#: flatcamEditors/FlatCAMExcEditor.py:1872 +#: flatcamEditors/FlatCAMExcEditor.py:1876 +#: flatcamEditors/FlatCAMExcEditor.py:1965 +#: flatcamEditors/FlatCAMExcEditor.py:1983 +#: flatcamEditors/FlatCAMExcEditor.py:2017 +#: flatcamEditors/FlatCAMGrbEditor.py:2812 +#: flatcamEditors/FlatCAMGrbEditor.py:2829 +#: flatcamEditors/FlatCAMGrbEditor.py:2865 flatcamGUI/PreferencesUI.py:2726 +#: flatcamGUI/PreferencesUI.py:2744 flatcamGUI/PreferencesUI.py:3897 +#: flatcamGUI/PreferencesUI.py:3916 flatcamGUI/PreferencesUI.py:3992 +#: flatcamGUI/PreferencesUI.py:3997 flatcamGUI/PreferencesUI.py:4045 +#: flatcamGUI/PreferencesUI.py:4066 flatcamGUI/PreferencesUI.py:6733 +#: flatcamTools/ToolDistance.py:120 flatcamTools/ToolDistanceMin.py:69 +#: flatcamTools/ToolTransform.py:61 msgid "Angle" msgstr "Unghi" -#: flatcamEditors/FlatCAMExcEditor.py:1751 -#: flatcamEditors/FlatCAMExcEditor.py:1966 -#: flatcamEditors/FlatCAMGrbEditor.py:2810 flatcamGUI/PreferencesUI.py:2550 -#: flatcamGUI/PreferencesUI.py:3625 flatcamGUI/PreferencesUI.py:3773 +#: flatcamEditors/FlatCAMExcEditor.py:1754 +#: flatcamEditors/FlatCAMExcEditor.py:1969 +#: flatcamEditors/FlatCAMGrbEditor.py:2816 flatcamGUI/PreferencesUI.py:2732 +#: flatcamGUI/PreferencesUI.py:3903 flatcamGUI/PreferencesUI.py:4051 msgid "Pitch" msgstr "Pas" -#: flatcamEditors/FlatCAMExcEditor.py:1753 -#: flatcamEditors/FlatCAMExcEditor.py:1968 -#: flatcamEditors/FlatCAMGrbEditor.py:2812 flatcamGUI/PreferencesUI.py:2552 -#: flatcamGUI/PreferencesUI.py:3627 flatcamGUI/PreferencesUI.py:3775 +#: flatcamEditors/FlatCAMExcEditor.py:1756 +#: flatcamEditors/FlatCAMExcEditor.py:1971 +#: flatcamEditors/FlatCAMGrbEditor.py:2818 flatcamGUI/PreferencesUI.py:2734 +#: flatcamGUI/PreferencesUI.py:3905 flatcamGUI/PreferencesUI.py:4053 msgid "Pitch = Distance between elements of the array." msgstr "Pas = Distanta între elementele ariei." -#: flatcamEditors/FlatCAMExcEditor.py:1766 -#: flatcamEditors/FlatCAMExcEditor.py:1982 +#: flatcamEditors/FlatCAMExcEditor.py:1769 +#: flatcamEditors/FlatCAMExcEditor.py:1985 msgid "" "Angle at which the linear array is placed.\n" "The precision is of max 2 decimals.\n" @@ -3339,9 +3742,9 @@ msgstr "" "Val minima este: -360grade.\n" "Val maxima este: 360.00 grade." -#: flatcamEditors/FlatCAMExcEditor.py:1787 -#: flatcamEditors/FlatCAMExcEditor.py:2003 -#: flatcamEditors/FlatCAMGrbEditor.py:2846 +#: flatcamEditors/FlatCAMExcEditor.py:1790 +#: flatcamEditors/FlatCAMExcEditor.py:2006 +#: flatcamEditors/FlatCAMGrbEditor.py:2852 msgid "" "Direction for circular array.Can be CW = clockwise or CCW = counter " "clockwise." @@ -3349,38 +3752,38 @@ msgstr "" "Directia pentru aria circulară. Poate fi CW = in sensul acelor de ceasornic " "sau CCW = invers acelor de ceasornic." -#: flatcamEditors/FlatCAMExcEditor.py:1794 -#: flatcamEditors/FlatCAMExcEditor.py:2010 -#: flatcamEditors/FlatCAMGrbEditor.py:2854 flatcamGUI/PreferencesUI.py:2584 -#: flatcamGUI/PreferencesUI.py:3368 flatcamGUI/PreferencesUI.py:3661 -#: flatcamGUI/PreferencesUI.py:3811 flatcamGUI/PreferencesUI.py:4288 +#: flatcamEditors/FlatCAMExcEditor.py:1797 +#: flatcamEditors/FlatCAMExcEditor.py:2013 +#: flatcamEditors/FlatCAMGrbEditor.py:2860 flatcamGUI/PreferencesUI.py:2766 +#: flatcamGUI/PreferencesUI.py:3646 flatcamGUI/PreferencesUI.py:3939 +#: flatcamGUI/PreferencesUI.py:4089 flatcamGUI/PreferencesUI.py:4581 msgid "CW" msgstr "Orar" -#: flatcamEditors/FlatCAMExcEditor.py:1795 -#: flatcamEditors/FlatCAMExcEditor.py:2011 -#: flatcamEditors/FlatCAMGrbEditor.py:2855 flatcamGUI/PreferencesUI.py:2585 -#: flatcamGUI/PreferencesUI.py:3369 flatcamGUI/PreferencesUI.py:3662 -#: flatcamGUI/PreferencesUI.py:3812 flatcamGUI/PreferencesUI.py:4289 +#: flatcamEditors/FlatCAMExcEditor.py:1798 +#: flatcamEditors/FlatCAMExcEditor.py:2014 +#: flatcamEditors/FlatCAMGrbEditor.py:2861 flatcamGUI/PreferencesUI.py:2767 +#: flatcamGUI/PreferencesUI.py:3647 flatcamGUI/PreferencesUI.py:3940 +#: flatcamGUI/PreferencesUI.py:4090 flatcamGUI/PreferencesUI.py:4582 msgid "CCW" msgstr "Antiorar" -#: flatcamEditors/FlatCAMExcEditor.py:1799 -#: flatcamEditors/FlatCAMExcEditor.py:2015 -#: flatcamEditors/FlatCAMGrbEditor.py:2861 flatcamGUI/PreferencesUI.py:2564 -#: flatcamGUI/PreferencesUI.py:2593 flatcamGUI/PreferencesUI.py:3640 -#: flatcamGUI/PreferencesUI.py:3670 flatcamGUI/PreferencesUI.py:3790 -#: flatcamGUI/PreferencesUI.py:3820 +#: flatcamEditors/FlatCAMExcEditor.py:1802 +#: flatcamEditors/FlatCAMExcEditor.py:2018 +#: flatcamEditors/FlatCAMGrbEditor.py:2867 flatcamGUI/PreferencesUI.py:2746 +#: flatcamGUI/PreferencesUI.py:2775 flatcamGUI/PreferencesUI.py:3918 +#: flatcamGUI/PreferencesUI.py:3948 flatcamGUI/PreferencesUI.py:4068 +#: flatcamGUI/PreferencesUI.py:4098 msgid "Angle at which each element in circular array is placed." msgstr "" "Unghiul la care fiecare element al ariei circulare este plasat fata de " "originea ariei." -#: flatcamEditors/FlatCAMExcEditor.py:1833 +#: flatcamEditors/FlatCAMExcEditor.py:1836 msgid "Slot Parameters" msgstr "Parametrii pt slot" -#: flatcamEditors/FlatCAMExcEditor.py:1835 +#: flatcamEditors/FlatCAMExcEditor.py:1838 msgid "" "Parameters for adding a slot (hole with oval shape)\n" "either single or as an part of an array." @@ -3388,16 +3791,16 @@ msgstr "" "Parametri pentru adăugarea unui slot (gaură cu formă ovală)\n" "fie single sau ca parte a unei arii." -#: flatcamEditors/FlatCAMExcEditor.py:1844 flatcamGUI/PreferencesUI.py:3687 -#: flatcamTools/ToolProperties.py:555 +#: flatcamEditors/FlatCAMExcEditor.py:1847 flatcamGUI/PreferencesUI.py:3965 +#: flatcamTools/ToolProperties.py:559 msgid "Length" msgstr "Lungime" -#: flatcamEditors/FlatCAMExcEditor.py:1846 flatcamGUI/PreferencesUI.py:3689 +#: flatcamEditors/FlatCAMExcEditor.py:1849 flatcamGUI/PreferencesUI.py:3967 msgid "Length = The length of the slot." msgstr "Lungime = Lungimea slotului." -#: flatcamEditors/FlatCAMExcEditor.py:1860 flatcamGUI/PreferencesUI.py:3705 +#: flatcamEditors/FlatCAMExcEditor.py:1863 flatcamGUI/PreferencesUI.py:3983 msgid "" "Direction on which the slot is oriented:\n" "- 'X' - horizontal axis \n" @@ -3409,7 +3812,7 @@ msgstr "" "- „Y” - axa verticală sau\n" "- „Unghi” - un unghi personalizat pentru înclinarea slotului" -#: flatcamEditors/FlatCAMExcEditor.py:1875 +#: flatcamEditors/FlatCAMExcEditor.py:1878 msgid "" "Angle at which the slot is placed.\n" "The precision is of max 2 decimals.\n" @@ -3421,15 +3824,15 @@ msgstr "" "Valoarea minimă este: -360 grade.\n" "Valoarea maximă este: 360.00 grade." -#: flatcamEditors/FlatCAMExcEditor.py:1908 +#: flatcamEditors/FlatCAMExcEditor.py:1911 msgid "Slot Array Parameters" msgstr "Parametri Arie sloturi" -#: flatcamEditors/FlatCAMExcEditor.py:1910 +#: flatcamEditors/FlatCAMExcEditor.py:1913 msgid "Parameters for the array of slots (linear or circular array)" msgstr "Parametri pentru Aria de sloturi (arie circulară sau liniară)" -#: flatcamEditors/FlatCAMExcEditor.py:1919 +#: flatcamEditors/FlatCAMExcEditor.py:1922 msgid "" "Select the type of slot array to create.\n" "It can be Linear X(Y) or Circular" @@ -3437,15 +3840,15 @@ msgstr "" "Selectați tipul de slot pentru creare.\n" "Poate fi liniar X (Y) sau circular" -#: flatcamEditors/FlatCAMExcEditor.py:1931 flatcamGUI/PreferencesUI.py:3744 +#: flatcamEditors/FlatCAMExcEditor.py:1934 flatcamGUI/PreferencesUI.py:4022 msgid "Nr of slots" msgstr "Nr de sloturi" -#: flatcamEditors/FlatCAMExcEditor.py:1932 flatcamGUI/PreferencesUI.py:3746 +#: flatcamEditors/FlatCAMExcEditor.py:1935 flatcamGUI/PreferencesUI.py:4024 msgid "Specify how many slots to be in the array." msgstr "Specificați câte sloturi trebuie să fie în arie." -#: flatcamEditors/FlatCAMExcEditor.py:2546 +#: flatcamEditors/FlatCAMExcEditor.py:2571 msgid "" "Tool already in the original or actual tool list.\n" "Save and reedit Excellon if you need to add this tool. " @@ -3454,52 +3857,52 @@ msgstr "" "Salvează și reeditează obiectul Excellon dacă ai nevoie să adaugi această " "unealtă. " -#: flatcamEditors/FlatCAMExcEditor.py:2555 flatcamGUI/FlatCAMGUI.py:3792 +#: flatcamEditors/FlatCAMExcEditor.py:2580 flatcamGUI/FlatCAMGUI.py:4009 msgid "Added new tool with dia" msgstr "O nouă unealtă este adăugată cu diametrul" -#: flatcamEditors/FlatCAMExcEditor.py:2589 +#: flatcamEditors/FlatCAMExcEditor.py:2613 msgid "Select a tool in Tool Table" msgstr "Selectează o unealtă in Tabela de Unelte" -#: flatcamEditors/FlatCAMExcEditor.py:2622 +#: flatcamEditors/FlatCAMExcEditor.py:2643 msgid "Deleted tool with diameter" msgstr "Unealtă ștearsă cu diametrul" -#: flatcamEditors/FlatCAMExcEditor.py:2772 +#: flatcamEditors/FlatCAMExcEditor.py:2793 msgid "Done. Tool edit completed." msgstr "Terminat. Editarea uneltei a fost finalizată." -#: flatcamEditors/FlatCAMExcEditor.py:3324 +#: flatcamEditors/FlatCAMExcEditor.py:3350 msgid "There are no Tools definitions in the file. Aborting Excellon creation." msgstr "" "Nu exista definitii de unelte in fişier. Se anulează crearea de obiect " "Excellon." -#: flatcamEditors/FlatCAMExcEditor.py:3328 +#: flatcamEditors/FlatCAMExcEditor.py:3354 msgid "An internal error has ocurred. See Shell.\n" msgstr "" "A apărut o eroare internă. Verifică in TCL Shell pt mai multe detalii.\n" -#: flatcamEditors/FlatCAMExcEditor.py:3333 +#: flatcamEditors/FlatCAMExcEditor.py:3359 msgid "Creating Excellon." msgstr "In curs de creere Excellon." -#: flatcamEditors/FlatCAMExcEditor.py:3347 +#: flatcamEditors/FlatCAMExcEditor.py:3371 msgid "Excellon editing finished." msgstr "Editarea Excellon a fost terminată." -#: flatcamEditors/FlatCAMExcEditor.py:3365 +#: flatcamEditors/FlatCAMExcEditor.py:3388 msgid "Cancelled. There is no Tool/Drill selected" msgstr "Anulat. Nu este selectată nici-o unealtă sau op. de găurire" -#: flatcamEditors/FlatCAMExcEditor.py:3978 +#: flatcamEditors/FlatCAMExcEditor.py:4001 msgid "Done. Drill(s) deleted." msgstr "Executat. Operatiile de găurire șterse." -#: flatcamEditors/FlatCAMExcEditor.py:4051 -#: flatcamEditors/FlatCAMExcEditor.py:4061 -#: flatcamEditors/FlatCAMGrbEditor.py:4853 +#: flatcamEditors/FlatCAMExcEditor.py:4074 +#: flatcamEditors/FlatCAMExcEditor.py:4084 +#: flatcamEditors/FlatCAMGrbEditor.py:4897 msgid "Click on the circular array Center position" msgstr "Click pe punctul de Centru al ariei circulare" @@ -3526,18 +3929,24 @@ msgstr "" "care formează coltul" #: flatcamEditors/FlatCAMGeoEditor.py:95 -#: flatcamEditors/FlatCAMGrbEditor.py:2622 +#: flatcamEditors/FlatCAMGrbEditor.py:2628 msgid "Round" msgstr "Rotund" #: flatcamEditors/FlatCAMGeoEditor.py:96 -#: flatcamEditors/FlatCAMGrbEditor.py:2623 flatcamGUI/PreferencesUI.py:7058 +#: flatcamEditors/FlatCAMGrbEditor.py:2629 flatcamGUI/PreferencesUI.py:5606 +#: flatcamGUI/PreferencesUI.py:6130 flatcamGUI/PreferencesUI.py:7564 +#: flatcamGUI/PreferencesUI.py:8167 flatcamGUI/PreferencesUI.py:8274 +#: flatcamGUI/PreferencesUI.py:8379 flatcamGUI/PreferencesUI.py:8488 +#: flatcamTools/ToolExtractDrills.py:94 flatcamTools/ToolExtractDrills.py:227 +#: flatcamTools/ToolNCC.py:583 flatcamTools/ToolPaint.py:527 +#: flatcamTools/ToolPunchGerber.py:105 flatcamTools/ToolPunchGerber.py:255 #: flatcamTools/ToolQRCode.py:198 msgid "Square" msgstr "Patrat" #: flatcamEditors/FlatCAMGeoEditor.py:97 -#: flatcamEditors/FlatCAMGrbEditor.py:2624 +#: flatcamEditors/FlatCAMGrbEditor.py:2630 msgid "Beveled" msgstr "Beveled" @@ -3554,18 +3963,18 @@ msgid "Full Buffer" msgstr "Bufer complet" #: flatcamEditors/FlatCAMGeoEditor.py:133 -#: flatcamEditors/FlatCAMGeoEditor.py:2885 flatcamGUI/FlatCAMGUI.py:1805 -#: flatcamGUI/PreferencesUI.py:2604 +#: flatcamEditors/FlatCAMGeoEditor.py:3018 flatcamGUI/FlatCAMGUI.py:1913 +#: flatcamGUI/PreferencesUI.py:2786 msgid "Buffer Tool" msgstr "Unealta Bufer" #: flatcamEditors/FlatCAMGeoEditor.py:145 #: flatcamEditors/FlatCAMGeoEditor.py:162 #: flatcamEditors/FlatCAMGeoEditor.py:179 -#: flatcamEditors/FlatCAMGeoEditor.py:2904 -#: flatcamEditors/FlatCAMGeoEditor.py:2934 -#: flatcamEditors/FlatCAMGeoEditor.py:2964 -#: flatcamEditors/FlatCAMGrbEditor.py:4906 +#: flatcamEditors/FlatCAMGeoEditor.py:3037 +#: flatcamEditors/FlatCAMGeoEditor.py:3065 +#: flatcamEditors/FlatCAMGeoEditor.py:3093 +#: flatcamEditors/FlatCAMGrbEditor.py:4950 msgid "Buffer distance value is missing or wrong format. Add it and retry." msgstr "" "Valoarea distantei bufer lipseste sau este intr-un format gresit. Adaugă din " @@ -3575,7 +3984,7 @@ msgstr "" msgid "Font" msgstr "Font" -#: flatcamEditors/FlatCAMGeoEditor.py:324 flatcamGUI/FlatCAMGUI.py:2085 +#: flatcamEditors/FlatCAMGeoEditor.py:324 flatcamGUI/FlatCAMGUI.py:2193 msgid "Text" msgstr "Text" @@ -3583,209 +3992,112 @@ msgstr "Text" msgid "Text Tool" msgstr "Unealta Text" -#: flatcamEditors/FlatCAMGeoEditor.py:442 flatcamGUI/ObjectUI.py:359 -#: flatcamGUI/PreferencesUI.py:2025 flatcamGUI/PreferencesUI.py:3875 -#: flatcamGUI/PreferencesUI.py:5535 +#: flatcamEditors/FlatCAMGeoEditor.py:440 flatcamGUI/ObjectUI.py:363 +#: flatcamGUI/PreferencesUI.py:2205 msgid "Tool dia" msgstr "Dia unealtă" -#: flatcamEditors/FlatCAMGeoEditor.py:444 flatcamGUI/PreferencesUI.py:5537 +#: flatcamEditors/FlatCAMGeoEditor.py:442 +msgid "Diameter of the tool to be used in the operation." +msgstr "Diametrul uneltei care este utilizata in operaţie." + +#: flatcamEditors/FlatCAMGeoEditor.py:488 msgid "" -"Diameter of the tool to\n" -"be used in the operation." +"Algorithm to paint the polygons:\n" +"- Standard: Fixed step inwards.\n" +"- Seed-based: Outwards from seed.\n" +"- Line-based: Parallel lines." msgstr "" -"Diametrul uneltei care este utilizata in operaţie. \n" -"Este și lăţimea de tăiere pentru uneltele cilindrice." +"Algoritm pentru picture poligoane:\n" +"- Standard: pas fix spre interior.\n" +"- Semințe: înspre exterior porning de la punctul sămanță.\n" +"- Linii: linii paralele." -#: flatcamEditors/FlatCAMGeoEditor.py:455 flatcamGUI/PreferencesUI.py:5152 -#: flatcamGUI/PreferencesUI.py:5567 flatcamTools/ToolNonCopperClear.py:319 -#: flatcamTools/ToolPaint.py:219 -msgid "Overlap Rate" -msgstr "Rată suprapunere" - -#: flatcamEditors/FlatCAMGeoEditor.py:457 flatcamGUI/PreferencesUI.py:5569 -#: flatcamTools/ToolPaint.py:221 -msgid "" -"How much (fraction) of the tool width to overlap each tool pass.\n" -"Adjust the value starting with lower values\n" -"and increasing it if areas that should be painted are still \n" -"not painted.\n" -"Lower values = faster processing, faster execution on CNC.\n" -"Higher values = slow processing and slow execution on CNC\n" -"due of too many paths." -msgstr "" -"Cat de mult (fracţie) din diametrul uneltei să se suprapună la fiecare " -"trecere a uneltei.\n" -"Ajustează valoarea incepand de la valori mici și pe urma creste daca ariile " -"care ar trebui\n" -" >pictate< inca nu sunt procesate.\n" -"Valori scazute = procesare rapida,execuţie rapida a PCB-ului.\n" -"Valori mari= procesare lenta cat și o execuţie la fel de lenta a PCB-ului,\n" -"datorita numărului mai mare de treceri-tăiere." - -#: flatcamEditors/FlatCAMGeoEditor.py:475 flatcamGUI/PreferencesUI.py:5171 -#: flatcamGUI/PreferencesUI.py:5384 flatcamGUI/PreferencesUI.py:5587 -#: flatcamGUI/PreferencesUI.py:7175 flatcamGUI/PreferencesUI.py:7332 -#: flatcamGUI/PreferencesUI.py:7417 flatcamTools/ToolCopperThieving.py:111 -#: flatcamTools/ToolCopperThieving.py:361 flatcamTools/ToolCutOut.py:184 -#: flatcamTools/ToolFiducials.py:172 flatcamTools/ToolNonCopperClear.py:337 -#: flatcamTools/ToolPaint.py:238 -msgid "Margin" -msgstr "Margine" - -#: flatcamEditors/FlatCAMGeoEditor.py:477 flatcamGUI/PreferencesUI.py:5589 -#: flatcamTools/ToolPaint.py:240 -msgid "" -"Distance by which to avoid\n" -"the edges of the polygon to\n" -"be painted." -msgstr "" -"Distanta fata de marginile\n" -"poligonului care trebuie\n" -"să fie >pictat<." - -#: flatcamEditors/FlatCAMGeoEditor.py:489 flatcamGUI/PreferencesUI.py:5184 -#: flatcamGUI/PreferencesUI.py:5602 flatcamTools/ToolNonCopperClear.py:348 -#: flatcamTools/ToolPaint.py:251 -msgid "Method" -msgstr "Metodă" - -#: flatcamEditors/FlatCAMGeoEditor.py:491 -msgid "" -"Algorithm to paint the polygon:
Standard: Fixed step inwards." -"
Seed-based: Outwards from seed." -msgstr "" -"Algoritm pentru a picta poligonul
Standard: Pas fix spre interior." -"
Samanta: Spre exterior pornind de la un punct-samanta." - -#: flatcamEditors/FlatCAMGeoEditor.py:496 flatcamGUI/PreferencesUI.py:5193 -#: flatcamGUI/PreferencesUI.py:5611 flatcamTools/ToolNonCopperClear.py:357 -#: flatcamTools/ToolPaint.py:260 -msgid "Standard" -msgstr "Standard" - -#: flatcamEditors/FlatCAMGeoEditor.py:497 flatcamGUI/PreferencesUI.py:5194 -#: flatcamGUI/PreferencesUI.py:5612 flatcamTools/ToolNonCopperClear.py:358 -#: flatcamTools/ToolPaint.py:261 -msgid "Seed-based" -msgstr "Punct-samanta" - -#: flatcamEditors/FlatCAMGeoEditor.py:498 flatcamGUI/PreferencesUI.py:5195 -#: flatcamGUI/PreferencesUI.py:5613 flatcamTools/ToolNonCopperClear.py:359 -#: flatcamTools/ToolPaint.py:262 -msgid "Straight lines" -msgstr "Linii drepte" - -#: flatcamEditors/FlatCAMGeoEditor.py:505 +#: flatcamEditors/FlatCAMGeoEditor.py:507 msgid "Connect:" msgstr "Conectează:" -#: flatcamEditors/FlatCAMGeoEditor.py:507 flatcamGUI/PreferencesUI.py:5204 -#: flatcamGUI/PreferencesUI.py:5620 flatcamTools/ToolNonCopperClear.py:366 -#: flatcamTools/ToolPaint.py:269 -msgid "" -"Draw lines between resulting\n" -"segments to minimize tool lifts." -msgstr "" -"Desenează linii între segmentele\n" -"rezultate pentru a minimiza miscarile\n" -"de ridicare a uneltei." - -#: flatcamEditors/FlatCAMGeoEditor.py:515 +#: flatcamEditors/FlatCAMGeoEditor.py:517 msgid "Contour:" msgstr "Contur:" -#: flatcamEditors/FlatCAMGeoEditor.py:517 flatcamGUI/PreferencesUI.py:5213 -#: flatcamGUI/PreferencesUI.py:5628 flatcamTools/ToolNonCopperClear.py:373 -#: flatcamTools/ToolPaint.py:276 -msgid "" -"Cut around the perimeter of the polygon\n" -"to trim rough edges." -msgstr "" -"Taie de-a lungul perimetrului poligonului\n" -"pentru a elimina bavurile." - -#: flatcamEditors/FlatCAMGeoEditor.py:529 flatcamGUI/FlatCAMGUI.py:2089 +#: flatcamEditors/FlatCAMGeoEditor.py:530 flatcamGUI/FlatCAMGUI.py:2197 msgid "Paint" msgstr "Pictează" -#: flatcamEditors/FlatCAMGeoEditor.py:547 flatcamGUI/FlatCAMGUI.py:845 -#: flatcamGUI/FlatCAMGUI.py:2423 flatcamGUI/ObjectUI.py:1731 -#: flatcamTools/ToolPaint.py:41 flatcamTools/ToolPaint.py:533 +#: flatcamEditors/FlatCAMGeoEditor.py:548 flatcamGUI/FlatCAMGUI.py:909 +#: flatcamGUI/FlatCAMGUI.py:2588 flatcamGUI/ObjectUI.py:2057 +#: flatcamTools/ToolPaint.py:43 flatcamTools/ToolPaint.py:735 msgid "Paint Tool" msgstr "Unealta Paint" #: flatcamEditors/FlatCAMGeoEditor.py:584 -msgid "Paint cancelled. No shape selected." -msgstr "Operaţie Paint anulată. Nici-o forma selectată." +#: flatcamEditors/FlatCAMGeoEditor.py:1056 +#: flatcamEditors/FlatCAMGeoEditor.py:3025 +#: flatcamEditors/FlatCAMGeoEditor.py:3053 +#: flatcamEditors/FlatCAMGeoEditor.py:3081 +#: flatcamEditors/FlatCAMGeoEditor.py:4502 +#: flatcamEditors/FlatCAMGrbEditor.py:5601 +msgid "Cancelled. No shape selected." +msgstr "Anulat. Nici-o forma geometrică nu este selectată." #: flatcamEditors/FlatCAMGeoEditor.py:597 -#: flatcamEditors/FlatCAMGeoEditor.py:2910 -#: flatcamEditors/FlatCAMGeoEditor.py:2940 -#: flatcamEditors/FlatCAMGeoEditor.py:2970 flatcamGUI/PreferencesUI.py:3871 -#: flatcamTools/ToolProperties.py:120 flatcamTools/ToolProperties.py:158 +#: flatcamEditors/FlatCAMGeoEditor.py:3043 +#: flatcamEditors/FlatCAMGeoEditor.py:3071 +#: flatcamEditors/FlatCAMGeoEditor.py:3099 flatcamGUI/PreferencesUI.py:4149 +#: flatcamTools/ToolProperties.py:117 flatcamTools/ToolProperties.py:162 msgid "Tools" msgstr "Unelte" #: flatcamEditors/FlatCAMGeoEditor.py:608 #: flatcamEditors/FlatCAMGeoEditor.py:992 -#: flatcamEditors/FlatCAMGrbEditor.py:5096 -#: flatcamEditors/FlatCAMGrbEditor.py:5493 flatcamGUI/FlatCAMGUI.py:866 -#: flatcamGUI/FlatCAMGUI.py:2441 flatcamTools/ToolTransform.py:422 +#: flatcamEditors/FlatCAMGrbEditor.py:5140 +#: flatcamEditors/FlatCAMGrbEditor.py:5537 flatcamGUI/FlatCAMGUI.py:930 +#: flatcamGUI/FlatCAMGUI.py:2609 flatcamTools/ToolTransform.py:461 msgid "Transform Tool" msgstr "Unealta Transformare" #: flatcamEditors/FlatCAMGeoEditor.py:609 #: flatcamEditors/FlatCAMGeoEditor.py:674 -#: flatcamEditors/FlatCAMGrbEditor.py:5097 -#: flatcamEditors/FlatCAMGrbEditor.py:5162 flatcamGUI/PreferencesUI.py:6238 -#: flatcamTools/ToolTransform.py:25 flatcamTools/ToolTransform.py:80 +#: flatcamEditors/FlatCAMGrbEditor.py:5141 +#: flatcamEditors/FlatCAMGrbEditor.py:5206 flatcamGUI/PreferencesUI.py:6725 +#: flatcamTools/ToolTransform.py:25 flatcamTools/ToolTransform.py:467 msgid "Rotate" msgstr "Rotaţie" #: flatcamEditors/FlatCAMGeoEditor.py:610 -#: flatcamEditors/FlatCAMGrbEditor.py:5098 flatcamTools/ToolTransform.py:26 +#: flatcamEditors/FlatCAMGrbEditor.py:5142 flatcamTools/ToolTransform.py:26 msgid "Skew/Shear" msgstr "Deformare" #: flatcamEditors/FlatCAMGeoEditor.py:611 -#: flatcamEditors/FlatCAMGrbEditor.py:2671 -#: flatcamEditors/FlatCAMGrbEditor.py:5099 flatcamGUI/FlatCAMGUI.py:980 -#: flatcamGUI/FlatCAMGUI.py:2017 flatcamGUI/FlatCAMGUI.py:2132 -#: flatcamGUI/FlatCAMGUI.py:2549 flatcamGUI/ObjectUI.py:103 -#: flatcamGUI/ObjectUI.py:121 flatcamGUI/PreferencesUI.py:6288 -#: flatcamTools/ToolTransform.py:27 +#: flatcamEditors/FlatCAMGrbEditor.py:2677 +#: flatcamEditors/FlatCAMGrbEditor.py:5143 flatcamGUI/FlatCAMGUI.py:1048 +#: flatcamGUI/FlatCAMGUI.py:2125 flatcamGUI/FlatCAMGUI.py:2240 +#: flatcamGUI/FlatCAMGUI.py:2723 flatcamGUI/ObjectUI.py:124 +#: flatcamGUI/PreferencesUI.py:6775 flatcamTools/ToolTransform.py:27 msgid "Scale" msgstr "Scalare" #: flatcamEditors/FlatCAMGeoEditor.py:612 -#: flatcamEditors/FlatCAMGrbEditor.py:5100 flatcamTools/ToolTransform.py:28 +#: flatcamEditors/FlatCAMGrbEditor.py:5144 flatcamTools/ToolTransform.py:28 msgid "Mirror (Flip)" msgstr "Oglindire" -#: flatcamEditors/FlatCAMGeoEditor.py:613 -#: flatcamEditors/FlatCAMGrbEditor.py:5101 flatcamGUI/ObjectUI.py:132 -#: flatcamGUI/ObjectUI.py:148 flatcamGUI/ObjectUI.py:1217 -#: flatcamGUI/ObjectUI.py:1916 flatcamGUI/PreferencesUI.py:5234 -#: flatcamGUI/PreferencesUI.py:6335 flatcamTools/ToolNonCopperClear.py:393 -#: flatcamTools/ToolTransform.py:29 -msgid "Offset" -msgstr "Ofset" - #: flatcamEditors/FlatCAMGeoEditor.py:626 -#: flatcamEditors/FlatCAMGrbEditor.py:5114 flatcamGUI/FlatCAMGUI.py:787 -#: flatcamGUI/FlatCAMGUI.py:2370 +#: flatcamEditors/FlatCAMGrbEditor.py:5158 flatcamGUI/FlatCAMGUI.py:841 +#: flatcamGUI/FlatCAMGUI.py:2524 msgid "Editor" msgstr "Editor" #: flatcamEditors/FlatCAMGeoEditor.py:658 -#: flatcamEditors/FlatCAMGrbEditor.py:5146 +#: flatcamEditors/FlatCAMGrbEditor.py:5190 msgid "Angle:" msgstr "Unghi:" #: flatcamEditors/FlatCAMGeoEditor.py:660 -#: flatcamEditors/FlatCAMGrbEditor.py:5148 flatcamGUI/PreferencesUI.py:6248 -#: flatcamTools/ToolTransform.py:65 +#: flatcamEditors/FlatCAMGrbEditor.py:5192 flatcamGUI/PreferencesUI.py:6735 +#: flatcamTools/ToolTransform.py:63 msgid "" "Angle for Rotation action, in degrees.\n" "Float number between -360 and 359.\n" @@ -3797,7 +4109,7 @@ msgstr "" "Numerele negative inseamna o mișcare in sens invers ace ceasornic." #: flatcamEditors/FlatCAMGeoEditor.py:676 -#: flatcamEditors/FlatCAMGrbEditor.py:5164 +#: flatcamEditors/FlatCAMGrbEditor.py:5208 msgid "" "Rotate the selected shape(s).\n" "The point of reference is the middle of\n" @@ -3809,16 +4121,16 @@ msgstr "" "toate formele selectate." #: flatcamEditors/FlatCAMGeoEditor.py:699 -#: flatcamEditors/FlatCAMGrbEditor.py:5187 +#: flatcamEditors/FlatCAMGrbEditor.py:5231 msgid "Angle X:" msgstr "Unghi X:" #: flatcamEditors/FlatCAMGeoEditor.py:701 #: flatcamEditors/FlatCAMGeoEditor.py:721 -#: flatcamEditors/FlatCAMGrbEditor.py:5189 -#: flatcamEditors/FlatCAMGrbEditor.py:5209 flatcamGUI/PreferencesUI.py:6267 -#: flatcamGUI/PreferencesUI.py:6281 flatcamTools/ToolCalibration.py:508 -#: flatcamTools/ToolCalibration.py:521 +#: flatcamEditors/FlatCAMGrbEditor.py:5233 +#: flatcamEditors/FlatCAMGrbEditor.py:5253 flatcamGUI/PreferencesUI.py:6754 +#: flatcamGUI/PreferencesUI.py:6768 flatcamTools/ToolCalibration.py:505 +#: flatcamTools/ToolCalibration.py:518 msgid "" "Angle for Skew action, in degrees.\n" "Float number between -360 and 359." @@ -3827,14 +4139,14 @@ msgstr "" "Ia valori Reale între -360 and 359 grade." #: flatcamEditors/FlatCAMGeoEditor.py:712 -#: flatcamEditors/FlatCAMGrbEditor.py:5200 flatcamTools/ToolTransform.py:109 +#: flatcamEditors/FlatCAMGrbEditor.py:5244 flatcamTools/ToolTransform.py:468 msgid "Skew X" msgstr "Deformare X" #: flatcamEditors/FlatCAMGeoEditor.py:714 #: flatcamEditors/FlatCAMGeoEditor.py:734 -#: flatcamEditors/FlatCAMGrbEditor.py:5202 -#: flatcamEditors/FlatCAMGrbEditor.py:5222 +#: flatcamEditors/FlatCAMGrbEditor.py:5246 +#: flatcamEditors/FlatCAMGrbEditor.py:5266 msgid "" "Skew/shear the selected shape(s).\n" "The point of reference is the middle of\n" @@ -3846,34 +4158,34 @@ msgstr "" "toate formele selectate." #: flatcamEditors/FlatCAMGeoEditor.py:719 -#: flatcamEditors/FlatCAMGrbEditor.py:5207 +#: flatcamEditors/FlatCAMGrbEditor.py:5251 msgid "Angle Y:" msgstr "Unghi Y:" #: flatcamEditors/FlatCAMGeoEditor.py:732 -#: flatcamEditors/FlatCAMGrbEditor.py:5220 flatcamTools/ToolTransform.py:131 +#: flatcamEditors/FlatCAMGrbEditor.py:5264 flatcamTools/ToolTransform.py:469 msgid "Skew Y" msgstr "Deformare Y" #: flatcamEditors/FlatCAMGeoEditor.py:760 -#: flatcamEditors/FlatCAMGrbEditor.py:5248 +#: flatcamEditors/FlatCAMGrbEditor.py:5292 msgid "Factor X:" msgstr "Factor X:" #: flatcamEditors/FlatCAMGeoEditor.py:762 -#: flatcamEditors/FlatCAMGrbEditor.py:5250 flatcamTools/ToolCalibration.py:472 +#: flatcamEditors/FlatCAMGrbEditor.py:5294 flatcamTools/ToolCalibration.py:469 msgid "Factor for Scale action over X axis." msgstr "Factor pentru scalarea pe axa X." #: flatcamEditors/FlatCAMGeoEditor.py:772 -#: flatcamEditors/FlatCAMGrbEditor.py:5260 flatcamTools/ToolTransform.py:158 +#: flatcamEditors/FlatCAMGrbEditor.py:5304 flatcamTools/ToolTransform.py:470 msgid "Scale X" msgstr "Scalează X" #: flatcamEditors/FlatCAMGeoEditor.py:774 #: flatcamEditors/FlatCAMGeoEditor.py:793 -#: flatcamEditors/FlatCAMGrbEditor.py:5262 -#: flatcamEditors/FlatCAMGrbEditor.py:5281 +#: flatcamEditors/FlatCAMGrbEditor.py:5306 +#: flatcamEditors/FlatCAMGrbEditor.py:5325 msgid "" "Scale the selected shape(s).\n" "The point of reference depends on \n" @@ -3884,28 +4196,28 @@ msgstr "" "starea checkbox-ului >Referința scalare<." #: flatcamEditors/FlatCAMGeoEditor.py:779 -#: flatcamEditors/FlatCAMGrbEditor.py:5267 +#: flatcamEditors/FlatCAMGrbEditor.py:5311 msgid "Factor Y:" msgstr "Factor Y:" #: flatcamEditors/FlatCAMGeoEditor.py:781 -#: flatcamEditors/FlatCAMGrbEditor.py:5269 flatcamTools/ToolCalibration.py:484 +#: flatcamEditors/FlatCAMGrbEditor.py:5313 flatcamTools/ToolCalibration.py:481 msgid "Factor for Scale action over Y axis." msgstr "Factor pentru scalarea pe axa Y." #: flatcamEditors/FlatCAMGeoEditor.py:791 -#: flatcamEditors/FlatCAMGrbEditor.py:5279 flatcamTools/ToolTransform.py:179 +#: flatcamEditors/FlatCAMGrbEditor.py:5323 flatcamTools/ToolTransform.py:471 msgid "Scale Y" msgstr "Scalează Y" #: flatcamEditors/FlatCAMGeoEditor.py:800 -#: flatcamEditors/FlatCAMGrbEditor.py:5288 flatcamGUI/PreferencesUI.py:6317 -#: flatcamTools/ToolTransform.py:192 +#: flatcamEditors/FlatCAMGrbEditor.py:5332 flatcamGUI/PreferencesUI.py:6804 +#: flatcamTools/ToolTransform.py:190 msgid "Link" msgstr "Legatura" #: flatcamEditors/FlatCAMGeoEditor.py:802 -#: flatcamEditors/FlatCAMGrbEditor.py:5290 +#: flatcamEditors/FlatCAMGrbEditor.py:5334 msgid "" "Scale the selected shape(s)\n" "using the Scale Factor X for both axis." @@ -3914,13 +4226,13 @@ msgstr "" "folsoind factorul: Factor X pentru ambele axe." #: flatcamEditors/FlatCAMGeoEditor.py:808 -#: flatcamEditors/FlatCAMGrbEditor.py:5296 flatcamGUI/PreferencesUI.py:6325 -#: flatcamTools/ToolTransform.py:200 +#: flatcamEditors/FlatCAMGrbEditor.py:5340 flatcamGUI/PreferencesUI.py:6812 +#: flatcamTools/ToolTransform.py:197 msgid "Scale Reference" msgstr "Referința scalare" #: flatcamEditors/FlatCAMGeoEditor.py:810 -#: flatcamEditors/FlatCAMGrbEditor.py:5298 +#: flatcamEditors/FlatCAMGrbEditor.py:5342 msgid "" "Scale the selected shape(s)\n" "using the origin reference when checked,\n" @@ -3934,24 +4246,24 @@ msgstr "" "bifat și este originea când este bifat." #: flatcamEditors/FlatCAMGeoEditor.py:838 -#: flatcamEditors/FlatCAMGrbEditor.py:5327 +#: flatcamEditors/FlatCAMGrbEditor.py:5371 msgid "Value X:" msgstr "Valoare X:" #: flatcamEditors/FlatCAMGeoEditor.py:840 -#: flatcamEditors/FlatCAMGrbEditor.py:5329 +#: flatcamEditors/FlatCAMGrbEditor.py:5373 msgid "Value for Offset action on X axis." msgstr "Valoare pentru deplasarea pe axa X." #: flatcamEditors/FlatCAMGeoEditor.py:850 -#: flatcamEditors/FlatCAMGrbEditor.py:5339 flatcamTools/ToolTransform.py:227 +#: flatcamEditors/FlatCAMGrbEditor.py:5383 flatcamTools/ToolTransform.py:474 msgid "Offset X" msgstr "Ofset pe X" #: flatcamEditors/FlatCAMGeoEditor.py:852 #: flatcamEditors/FlatCAMGeoEditor.py:872 -#: flatcamEditors/FlatCAMGrbEditor.py:5341 -#: flatcamEditors/FlatCAMGrbEditor.py:5361 +#: flatcamEditors/FlatCAMGrbEditor.py:5385 +#: flatcamEditors/FlatCAMGrbEditor.py:5405 msgid "" "Offset the selected shape(s).\n" "The point of reference is the middle of\n" @@ -3963,29 +4275,29 @@ msgstr "" "toate formele selectate.\n" #: flatcamEditors/FlatCAMGeoEditor.py:858 -#: flatcamEditors/FlatCAMGrbEditor.py:5347 +#: flatcamEditors/FlatCAMGrbEditor.py:5391 msgid "Value Y:" msgstr "Valoare Y:" #: flatcamEditors/FlatCAMGeoEditor.py:860 -#: flatcamEditors/FlatCAMGrbEditor.py:5349 +#: flatcamEditors/FlatCAMGrbEditor.py:5393 msgid "Value for Offset action on Y axis." msgstr "Valoare pentru deplasarea pe axa Y." #: flatcamEditors/FlatCAMGeoEditor.py:870 -#: flatcamEditors/FlatCAMGrbEditor.py:5359 flatcamTools/ToolTransform.py:248 +#: flatcamEditors/FlatCAMGrbEditor.py:5403 flatcamTools/ToolTransform.py:475 msgid "Offset Y" msgstr "Ofset pe Y" #: flatcamEditors/FlatCAMGeoEditor.py:901 -#: flatcamEditors/FlatCAMGrbEditor.py:5390 flatcamTools/ToolTransform.py:266 +#: flatcamEditors/FlatCAMGrbEditor.py:5434 flatcamTools/ToolTransform.py:476 msgid "Flip on X" msgstr "Oglindește pe X" #: flatcamEditors/FlatCAMGeoEditor.py:903 #: flatcamEditors/FlatCAMGeoEditor.py:910 -#: flatcamEditors/FlatCAMGrbEditor.py:5392 -#: flatcamEditors/FlatCAMGrbEditor.py:5399 +#: flatcamEditors/FlatCAMGrbEditor.py:5436 +#: flatcamEditors/FlatCAMGrbEditor.py:5443 msgid "" "Flip the selected shape(s) over the X axis.\n" "Does not create a new shape." @@ -3994,17 +4306,17 @@ msgstr "" "Nu crează noi forme." #: flatcamEditors/FlatCAMGeoEditor.py:908 -#: flatcamEditors/FlatCAMGrbEditor.py:5397 flatcamTools/ToolTransform.py:272 +#: flatcamEditors/FlatCAMGrbEditor.py:5441 flatcamTools/ToolTransform.py:477 msgid "Flip on Y" msgstr "Oglindește pe Y" #: flatcamEditors/FlatCAMGeoEditor.py:916 -#: flatcamEditors/FlatCAMGrbEditor.py:5405 +#: flatcamEditors/FlatCAMGrbEditor.py:5449 msgid "Ref Pt" msgstr "Pt ref" #: flatcamEditors/FlatCAMGeoEditor.py:918 -#: flatcamEditors/FlatCAMGrbEditor.py:5407 +#: flatcamEditors/FlatCAMGrbEditor.py:5451 msgid "" "Flip the selected shape(s)\n" "around the point in Point Entry Field.\n" @@ -4028,12 +4340,12 @@ msgstr "" "La final click pe >Oglindește pe X(Y)<." #: flatcamEditors/FlatCAMGeoEditor.py:930 -#: flatcamEditors/FlatCAMGrbEditor.py:5419 +#: flatcamEditors/FlatCAMGrbEditor.py:5463 msgid "Point:" msgstr "Punct:" #: flatcamEditors/FlatCAMGeoEditor.py:932 -#: flatcamEditors/FlatCAMGrbEditor.py:5421 flatcamTools/ToolTransform.py:301 +#: flatcamEditors/FlatCAMGrbEditor.py:5465 flatcamTools/ToolTransform.py:300 msgid "" "Coordinates in format (x, y) used as reference for mirroring.\n" "The 'x' in (x, y) will be used when using Flip on X and\n" @@ -4044,7 +4356,7 @@ msgstr "" "și valoarea 'y' in (x, y) va fi folosita când se face oglindire pe Y." #: flatcamEditors/FlatCAMGeoEditor.py:942 -#: flatcamEditors/FlatCAMGrbEditor.py:5433 flatcamTools/ToolTransform.py:312 +#: flatcamEditors/FlatCAMGrbEditor.py:5477 flatcamTools/ToolTransform.py:310 msgid "" "The point coordinates can be captured by\n" "left click on canvas together with pressing\n" @@ -4055,360 +4367,360 @@ msgstr "" "tasta SHIFT.\n" "La final, apasa butonul >Adaugă< pt a le insera." -#: flatcamEditors/FlatCAMGeoEditor.py:1057 -#: flatcamEditors/FlatCAMGrbEditor.py:5558 -msgid "Transformation cancelled. No shape selected." -msgstr "Transformare anulată. Nici-o formă nu este selectată." - -#: flatcamEditors/FlatCAMGeoEditor.py:1258 -#: flatcamEditors/FlatCAMGrbEditor.py:5742 +#: flatcamEditors/FlatCAMGeoEditor.py:1305 +#: flatcamEditors/FlatCAMGrbEditor.py:5785 msgid "No shape selected. Please Select a shape to rotate!" msgstr "" "Nici-o forma nu este selectată. Selectează o forma pentru a putea face " "Rotaţie!" -#: flatcamEditors/FlatCAMGeoEditor.py:1261 -#: flatcamEditors/FlatCAMGrbEditor.py:5745 flatcamTools/ToolTransform.py:611 +#: flatcamEditors/FlatCAMGeoEditor.py:1308 +#: flatcamEditors/FlatCAMGrbEditor.py:5788 flatcamTools/ToolTransform.py:680 msgid "Appying Rotate" msgstr "Execuţie Rotaţie" -#: flatcamEditors/FlatCAMGeoEditor.py:1290 -#: flatcamEditors/FlatCAMGrbEditor.py:5779 +#: flatcamEditors/FlatCAMGeoEditor.py:1334 +#: flatcamEditors/FlatCAMGrbEditor.py:5820 msgid "Done. Rotate completed." msgstr "Executat. Rotaţie finalizată." -#: flatcamEditors/FlatCAMGeoEditor.py:1295 +#: flatcamEditors/FlatCAMGeoEditor.py:1336 msgid "Rotation action was not executed" msgstr "Actiunea de rotatie nu a fost efectuată" -#: flatcamEditors/FlatCAMGeoEditor.py:1307 -#: flatcamEditors/FlatCAMGrbEditor.py:5800 +#: flatcamEditors/FlatCAMGeoEditor.py:1355 +#: flatcamEditors/FlatCAMGrbEditor.py:5839 msgid "No shape selected. Please Select a shape to flip!" msgstr "" "Nici-o formă nu este selectată. Selectează o formă pentru a putea face " "Oglindire!" -#: flatcamEditors/FlatCAMGeoEditor.py:1310 -#: flatcamEditors/FlatCAMGrbEditor.py:5803 flatcamTools/ToolTransform.py:664 +#: flatcamEditors/FlatCAMGeoEditor.py:1358 +#: flatcamEditors/FlatCAMGrbEditor.py:5842 flatcamTools/ToolTransform.py:729 msgid "Applying Flip" msgstr "Execuţie Oglindire" -#: flatcamEditors/FlatCAMGeoEditor.py:1341 -#: flatcamEditors/FlatCAMGrbEditor.py:5843 flatcamTools/ToolTransform.py:707 +#: flatcamEditors/FlatCAMGeoEditor.py:1387 +#: flatcamEditors/FlatCAMGrbEditor.py:5880 flatcamTools/ToolTransform.py:770 msgid "Flip on the Y axis done" msgstr "Oglindire pe axa Y executată" -#: flatcamEditors/FlatCAMGeoEditor.py:1345 -#: flatcamEditors/FlatCAMGrbEditor.py:5852 flatcamTools/ToolTransform.py:717 +#: flatcamEditors/FlatCAMGeoEditor.py:1391 +#: flatcamEditors/FlatCAMGrbEditor.py:5889 flatcamTools/ToolTransform.py:779 msgid "Flip on the X axis done" msgstr "Oglindire pe axa X executată" -#: flatcamEditors/FlatCAMGeoEditor.py:1355 +#: flatcamEditors/FlatCAMGeoEditor.py:1399 msgid "Flip action was not executed" msgstr "Actiunea de oglindire nu a fost efectuată" -#: flatcamEditors/FlatCAMGeoEditor.py:1365 -#: flatcamEditors/FlatCAMGrbEditor.py:5874 +#: flatcamEditors/FlatCAMGeoEditor.py:1417 +#: flatcamEditors/FlatCAMGrbEditor.py:5909 msgid "No shape selected. Please Select a shape to shear/skew!" msgstr "" "Nici-o formă nu este selectată. Selectează o formă pentru a putea face " "Deformare!" -#: flatcamEditors/FlatCAMGeoEditor.py:1368 -#: flatcamEditors/FlatCAMGrbEditor.py:5877 flatcamTools/ToolTransform.py:742 +#: flatcamEditors/FlatCAMGeoEditor.py:1420 +#: flatcamEditors/FlatCAMGrbEditor.py:5912 flatcamTools/ToolTransform.py:802 msgid "Applying Skew" msgstr "Execuţie Deformare" -#: flatcamEditors/FlatCAMGeoEditor.py:1394 -#: flatcamEditors/FlatCAMGrbEditor.py:5913 +#: flatcamEditors/FlatCAMGeoEditor.py:1443 +#: flatcamEditors/FlatCAMGrbEditor.py:5946 msgid "Skew on the X axis done" msgstr "Oglindire pe axa X executată" -#: flatcamEditors/FlatCAMGeoEditor.py:1397 -#: flatcamEditors/FlatCAMGrbEditor.py:5915 +#: flatcamEditors/FlatCAMGeoEditor.py:1445 +#: flatcamEditors/FlatCAMGrbEditor.py:5948 msgid "Skew on the Y axis done" msgstr "Oglindire pe axa Y executată" -#: flatcamEditors/FlatCAMGeoEditor.py:1401 +#: flatcamEditors/FlatCAMGeoEditor.py:1448 msgid "Skew action was not executed" msgstr "Actiunea de deformare nu a fost efectuată" -#: flatcamEditors/FlatCAMGeoEditor.py:1413 -#: flatcamEditors/FlatCAMGrbEditor.py:5939 +#: flatcamEditors/FlatCAMGeoEditor.py:1470 +#: flatcamEditors/FlatCAMGrbEditor.py:5970 msgid "No shape selected. Please Select a shape to scale!" msgstr "" "Nici-o formă nu este selectată. Selectează o formă pentru a putea face " "Scalare!" -#: flatcamEditors/FlatCAMGeoEditor.py:1416 -#: flatcamEditors/FlatCAMGrbEditor.py:5942 flatcamTools/ToolTransform.py:794 +#: flatcamEditors/FlatCAMGeoEditor.py:1473 +#: flatcamEditors/FlatCAMGrbEditor.py:5973 flatcamTools/ToolTransform.py:849 msgid "Applying Scale" msgstr "Execuţie Scalare" -#: flatcamEditors/FlatCAMGeoEditor.py:1451 -#: flatcamEditors/FlatCAMGrbEditor.py:5981 +#: flatcamEditors/FlatCAMGeoEditor.py:1505 +#: flatcamEditors/FlatCAMGrbEditor.py:6010 msgid "Scale on the X axis done" msgstr "Scalarea pe axa X executată" -#: flatcamEditors/FlatCAMGeoEditor.py:1454 -#: flatcamEditors/FlatCAMGrbEditor.py:5983 +#: flatcamEditors/FlatCAMGeoEditor.py:1507 +#: flatcamEditors/FlatCAMGrbEditor.py:6012 msgid "Scale on the Y axis done" msgstr "Scalarea pe axa Y executată" -#: flatcamEditors/FlatCAMGeoEditor.py:1457 +#: flatcamEditors/FlatCAMGeoEditor.py:1509 msgid "Scale action was not executed" msgstr "Scalarea nu a fost efectuată" -#: flatcamEditors/FlatCAMGeoEditor.py:1467 -#: flatcamEditors/FlatCAMGrbEditor.py:6000 +#: flatcamEditors/FlatCAMGeoEditor.py:1524 +#: flatcamEditors/FlatCAMGrbEditor.py:6029 msgid "No shape selected. Please Select a shape to offset!" msgstr "" "Nici-o formă nu este selectată. Selectează o formă pentru a putea face Ofset!" -#: flatcamEditors/FlatCAMGeoEditor.py:1470 -#: flatcamEditors/FlatCAMGrbEditor.py:6003 flatcamTools/ToolTransform.py:849 +#: flatcamEditors/FlatCAMGeoEditor.py:1527 +#: flatcamEditors/FlatCAMGrbEditor.py:6032 flatcamTools/ToolTransform.py:901 msgid "Applying Offset" msgstr "Execuţie Ofset" -#: flatcamEditors/FlatCAMGeoEditor.py:1483 -#: flatcamEditors/FlatCAMGrbEditor.py:6024 +#: flatcamEditors/FlatCAMGeoEditor.py:1537 +#: flatcamEditors/FlatCAMGrbEditor.py:6053 msgid "Offset on the X axis done" msgstr "Ofset pe axa X efectuat" -#: flatcamEditors/FlatCAMGeoEditor.py:1486 -#: flatcamEditors/FlatCAMGrbEditor.py:6026 +#: flatcamEditors/FlatCAMGeoEditor.py:1539 +#: flatcamEditors/FlatCAMGrbEditor.py:6055 msgid "Offset on the Y axis done" msgstr "Ofset pe axa Y efectuat" -#: flatcamEditors/FlatCAMGeoEditor.py:1490 +#: flatcamEditors/FlatCAMGeoEditor.py:1542 msgid "Offset action was not executed" msgstr "Actiuena de Ofset nu a fost efectuată" -#: flatcamEditors/FlatCAMGeoEditor.py:1494 -#: flatcamEditors/FlatCAMGrbEditor.py:6033 +#: flatcamEditors/FlatCAMGeoEditor.py:1546 +#: flatcamEditors/FlatCAMGrbEditor.py:6062 msgid "Rotate ..." msgstr "Rotaţie ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1495 -#: flatcamEditors/FlatCAMGeoEditor.py:1550 -#: flatcamEditors/FlatCAMGeoEditor.py:1567 -#: flatcamEditors/FlatCAMGrbEditor.py:6034 -#: flatcamEditors/FlatCAMGrbEditor.py:6083 -#: flatcamEditors/FlatCAMGrbEditor.py:6098 +#: flatcamEditors/FlatCAMGeoEditor.py:1547 +#: flatcamEditors/FlatCAMGeoEditor.py:1602 +#: flatcamEditors/FlatCAMGeoEditor.py:1619 +#: flatcamEditors/FlatCAMGrbEditor.py:6063 +#: flatcamEditors/FlatCAMGrbEditor.py:6112 +#: flatcamEditors/FlatCAMGrbEditor.py:6127 msgid "Enter an Angle Value (degrees)" msgstr "Introdu o valoare in grade pt Unghi" -#: flatcamEditors/FlatCAMGeoEditor.py:1504 -#: flatcamEditors/FlatCAMGrbEditor.py:6042 +#: flatcamEditors/FlatCAMGeoEditor.py:1556 +#: flatcamEditors/FlatCAMGrbEditor.py:6071 msgid "Geometry shape rotate done" msgstr "Rotatia formei geometrice executată" -#: flatcamEditors/FlatCAMGeoEditor.py:1508 -#: flatcamEditors/FlatCAMGrbEditor.py:6045 +#: flatcamEditors/FlatCAMGeoEditor.py:1560 +#: flatcamEditors/FlatCAMGrbEditor.py:6074 msgid "Geometry shape rotate cancelled" msgstr "Rotatia formei geometrice anulată" -#: flatcamEditors/FlatCAMGeoEditor.py:1513 -#: flatcamEditors/FlatCAMGrbEditor.py:6050 +#: flatcamEditors/FlatCAMGeoEditor.py:1565 +#: flatcamEditors/FlatCAMGrbEditor.py:6079 msgid "Offset on X axis ..." msgstr "Ofset pe axa X ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1514 -#: flatcamEditors/FlatCAMGeoEditor.py:1533 -#: flatcamEditors/FlatCAMGrbEditor.py:6051 -#: flatcamEditors/FlatCAMGrbEditor.py:6068 +#: flatcamEditors/FlatCAMGeoEditor.py:1566 +#: flatcamEditors/FlatCAMGeoEditor.py:1585 +#: flatcamEditors/FlatCAMGrbEditor.py:6080 +#: flatcamEditors/FlatCAMGrbEditor.py:6097 msgid "Enter a distance Value" msgstr "Introdu of valoare pt Distantă" -#: flatcamEditors/FlatCAMGeoEditor.py:1523 -#: flatcamEditors/FlatCAMGrbEditor.py:6059 +#: flatcamEditors/FlatCAMGeoEditor.py:1575 +#: flatcamEditors/FlatCAMGrbEditor.py:6088 msgid "Geometry shape offset on X axis done" msgstr "Ofset pe axa X executat" -#: flatcamEditors/FlatCAMGeoEditor.py:1527 -#: flatcamEditors/FlatCAMGrbEditor.py:6062 +#: flatcamEditors/FlatCAMGeoEditor.py:1579 +#: flatcamEditors/FlatCAMGrbEditor.py:6091 msgid "Geometry shape offset X cancelled" msgstr "Ofset pe axa X anulat" -#: flatcamEditors/FlatCAMGeoEditor.py:1532 -#: flatcamEditors/FlatCAMGrbEditor.py:6067 +#: flatcamEditors/FlatCAMGeoEditor.py:1584 +#: flatcamEditors/FlatCAMGrbEditor.py:6096 msgid "Offset on Y axis ..." msgstr "Ofset pe axa Y ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1542 -#: flatcamEditors/FlatCAMGrbEditor.py:6076 +#: flatcamEditors/FlatCAMGeoEditor.py:1594 +#: flatcamEditors/FlatCAMGrbEditor.py:6105 msgid "Geometry shape offset on Y axis done" msgstr "Ofset pe axa Y executat" -#: flatcamEditors/FlatCAMGeoEditor.py:1546 +#: flatcamEditors/FlatCAMGeoEditor.py:1598 msgid "Geometry shape offset on Y axis canceled" msgstr "Ofset pe axa Y anulat" -#: flatcamEditors/FlatCAMGeoEditor.py:1549 -#: flatcamEditors/FlatCAMGrbEditor.py:6082 +#: flatcamEditors/FlatCAMGeoEditor.py:1601 +#: flatcamEditors/FlatCAMGrbEditor.py:6111 msgid "Skew on X axis ..." msgstr "Deformare pe axa X ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1559 -#: flatcamEditors/FlatCAMGrbEditor.py:6091 +#: flatcamEditors/FlatCAMGeoEditor.py:1611 +#: flatcamEditors/FlatCAMGrbEditor.py:6120 msgid "Geometry shape skew on X axis done" msgstr "Deformarea pe axa X executată" -#: flatcamEditors/FlatCAMGeoEditor.py:1563 +#: flatcamEditors/FlatCAMGeoEditor.py:1615 msgid "Geometry shape skew on X axis canceled" msgstr "Deformarea pe axa X anulată" -#: flatcamEditors/FlatCAMGeoEditor.py:1566 -#: flatcamEditors/FlatCAMGrbEditor.py:6097 +#: flatcamEditors/FlatCAMGeoEditor.py:1618 +#: flatcamEditors/FlatCAMGrbEditor.py:6126 msgid "Skew on Y axis ..." msgstr "Deformare pe axa Y ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1576 -#: flatcamEditors/FlatCAMGrbEditor.py:6106 +#: flatcamEditors/FlatCAMGeoEditor.py:1628 +#: flatcamEditors/FlatCAMGrbEditor.py:6135 msgid "Geometry shape skew on Y axis done" msgstr "Deformarea pe axa Y executată" -#: flatcamEditors/FlatCAMGeoEditor.py:1580 +#: flatcamEditors/FlatCAMGeoEditor.py:1632 msgid "Geometry shape skew on Y axis canceled" msgstr "Deformarea pe axa Y anulată" -#: flatcamEditors/FlatCAMGeoEditor.py:1951 -#: flatcamEditors/FlatCAMGeoEditor.py:2016 -#: flatcamEditors/FlatCAMGrbEditor.py:1436 -#: flatcamEditors/FlatCAMGrbEditor.py:1514 +#: flatcamEditors/FlatCAMGeoEditor.py:2009 +#: flatcamEditors/FlatCAMGeoEditor.py:2080 +#: flatcamEditors/FlatCAMGrbEditor.py:1435 +#: flatcamEditors/FlatCAMGrbEditor.py:1513 msgid "Click on Center point ..." msgstr "Click pe punctul de Centru ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1958 -#: flatcamEditors/FlatCAMGrbEditor.py:1446 +#: flatcamEditors/FlatCAMGeoEditor.py:2022 +#: flatcamEditors/FlatCAMGrbEditor.py:1445 msgid "Click on Perimeter point to complete ..." msgstr "Click pe un punct aflat pe Circumferintă pentru terminare ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1990 +#: flatcamEditors/FlatCAMGeoEditor.py:2054 msgid "Done. Adding Circle completed." msgstr "Executat. Adăugarea unei forme Cerc terminată." -#: flatcamEditors/FlatCAMGeoEditor.py:2038 -#: flatcamEditors/FlatCAMGrbEditor.py:1547 +#: flatcamEditors/FlatCAMGeoEditor.py:2108 +#: flatcamEditors/FlatCAMGrbEditor.py:1546 msgid "Click on Start point ..." msgstr "Click pe punctul de Start ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2040 -#: flatcamEditors/FlatCAMGrbEditor.py:1549 +#: flatcamEditors/FlatCAMGeoEditor.py:2110 +#: flatcamEditors/FlatCAMGrbEditor.py:1548 msgid "Click on Point3 ..." msgstr "Click pe Punctul3 ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2042 -#: flatcamEditors/FlatCAMGrbEditor.py:1551 +#: flatcamEditors/FlatCAMGeoEditor.py:2112 +#: flatcamEditors/FlatCAMGrbEditor.py:1550 msgid "Click on Stop point ..." msgstr "Click pe punctulde Stop ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2047 -#: flatcamEditors/FlatCAMGrbEditor.py:1556 +#: flatcamEditors/FlatCAMGeoEditor.py:2117 +#: flatcamEditors/FlatCAMGrbEditor.py:1555 msgid "Click on Stop point to complete ..." msgstr "Click pe punctul de Stop pentru terminare ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2049 -#: flatcamEditors/FlatCAMGrbEditor.py:1558 +#: flatcamEditors/FlatCAMGeoEditor.py:2119 +#: flatcamEditors/FlatCAMGrbEditor.py:1557 msgid "Click on Point2 to complete ..." msgstr "Click pe Punctul2 pentru terminare ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2051 -#: flatcamEditors/FlatCAMGrbEditor.py:1560 +#: flatcamEditors/FlatCAMGeoEditor.py:2121 +#: flatcamEditors/FlatCAMGrbEditor.py:1559 msgid "Click on Center point to complete ..." msgstr "Click pe punctul de Centru pentru terminare ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2063 +#: flatcamEditors/FlatCAMGeoEditor.py:2133 #, python-format msgid "Direction: %s" msgstr "Direcţie: %s" -#: flatcamEditors/FlatCAMGeoEditor.py:2077 -#: flatcamEditors/FlatCAMGrbEditor.py:1586 +#: flatcamEditors/FlatCAMGeoEditor.py:2147 +#: flatcamEditors/FlatCAMGrbEditor.py:1585 msgid "Mode: Start -> Stop -> Center. Click on Start point ..." msgstr "Mod: Start -> Stop -> Centru. Click pe punctul de Start ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2080 -#: flatcamEditors/FlatCAMGrbEditor.py:1589 +#: flatcamEditors/FlatCAMGeoEditor.py:2150 +#: flatcamEditors/FlatCAMGrbEditor.py:1588 msgid "Mode: Point1 -> Point3 -> Point2. Click on Point1 ..." msgstr "Mod: Point1 -> Point3 -> Point2. Click pe Punctul1 ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2083 -#: flatcamEditors/FlatCAMGrbEditor.py:1592 +#: flatcamEditors/FlatCAMGeoEditor.py:2153 +#: flatcamEditors/FlatCAMGrbEditor.py:1591 msgid "Mode: Center -> Start -> Stop. Click on Center point ..." msgstr "Mod: Center -> Start -> Stop. Click pe punctul de Centru ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2224 +#: flatcamEditors/FlatCAMGeoEditor.py:2294 msgid "Done. Arc completed." msgstr "Executat. Adăugarea unei forme Arc terminată." -#: flatcamEditors/FlatCAMGeoEditor.py:2255 -#: flatcamEditors/FlatCAMGeoEditor.py:2322 +#: flatcamEditors/FlatCAMGeoEditor.py:2325 +#: flatcamEditors/FlatCAMGeoEditor.py:2398 msgid "Click on 1st corner ..." msgstr "Click pe primul colt ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2261 +#: flatcamEditors/FlatCAMGeoEditor.py:2337 msgid "Click on opposite corner to complete ..." msgstr "Click pe punctul opus pentru terminare ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2291 +#: flatcamEditors/FlatCAMGeoEditor.py:2367 msgid "Done. Rectangle completed." msgstr "Executat. Adăugare Pătrat terminată." -#: flatcamEditors/FlatCAMGeoEditor.py:2329 +#: flatcamEditors/FlatCAMGeoEditor.py:2411 flatcamTools/ToolNCC.py:1737 +#: flatcamTools/ToolPaint.py:1616 msgid "Click on next Point or click right mouse button to complete ..." msgstr "" "Click pe punctul următor sau click buton dreapta al mousului pentru " "terminare ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2360 +#: flatcamEditors/FlatCAMGeoEditor.py:2442 msgid "Done. Polygon completed." msgstr "Executat. Adăugarea unei forme Poligon terminată." -#: flatcamEditors/FlatCAMGeoEditor.py:2374 -#: flatcamEditors/FlatCAMGeoEditor.py:2439 -#: flatcamEditors/FlatCAMGrbEditor.py:1112 -#: flatcamEditors/FlatCAMGrbEditor.py:1323 +#: flatcamEditors/FlatCAMGeoEditor.py:2456 +#: flatcamEditors/FlatCAMGeoEditor.py:2521 +#: flatcamEditors/FlatCAMGrbEditor.py:1111 +#: flatcamEditors/FlatCAMGrbEditor.py:1322 msgid "Backtracked one point ..." msgstr "Revenit la penultimul Punct ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2417 +#: flatcamEditors/FlatCAMGeoEditor.py:2499 msgid "Done. Path completed." msgstr "Executat. Traseu finalizat." -#: flatcamEditors/FlatCAMGeoEditor.py:2580 +#: flatcamEditors/FlatCAMGeoEditor.py:2658 +msgid "No shape selected. Select a shape to explode" +msgstr "Nicio formă selectată. Selectați o formă pentru a o exploda" + +#: flatcamEditors/FlatCAMGeoEditor.py:2691 msgid "Done. Polygons exploded into lines." msgstr "Terminat. Poligoanele au fost descompuse în linii." -#: flatcamEditors/FlatCAMGeoEditor.py:2612 +#: flatcamEditors/FlatCAMGeoEditor.py:2723 msgid "MOVE: No shape selected. Select a shape to move" msgstr "" "MUTARE: Nici-o formă nu este selectată. Selectează o formă pentru a putea " "face deplasare" -#: flatcamEditors/FlatCAMGeoEditor.py:2615 -#: flatcamEditors/FlatCAMGeoEditor.py:2628 +#: flatcamEditors/FlatCAMGeoEditor.py:2726 +#: flatcamEditors/FlatCAMGeoEditor.py:2746 msgid " MOVE: Click on reference point ..." msgstr " MUTARE: Click pe punctul de referinţă ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2619 +#: flatcamEditors/FlatCAMGeoEditor.py:2731 msgid " Click on destination point ..." msgstr " Click pe punctul de Destinaţie ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2653 +#: flatcamEditors/FlatCAMGeoEditor.py:2771 msgid "Done. Geometry(s) Move completed." msgstr "Executat. Mutarea Geometriilor terminată." -#: flatcamEditors/FlatCAMGeoEditor.py:2783 +#: flatcamEditors/FlatCAMGeoEditor.py:2904 msgid "Done. Geometry(s) Copy completed." msgstr "Executat. Copierea Geometriilor terminată." -#: flatcamEditors/FlatCAMGeoEditor.py:2811 -#: flatcamEditors/FlatCAMGrbEditor.py:898 +#: flatcamEditors/FlatCAMGeoEditor.py:2935 +#: flatcamEditors/FlatCAMGrbEditor.py:897 msgid "Click on 1st point ..." msgstr "Click pe primul punct ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2829 +#: flatcamEditors/FlatCAMGeoEditor.py:2959 msgid "" "Font not supported. Only Regular, Bold, Italic and BoldItalic are supported. " "Error" @@ -4416,98 +4728,132 @@ msgstr "" "Fontul nu este compatibil. Doar cele tip: Regular, Bold, Italic și " "BoldItalic sunt acceptate. Eroarea" -#: flatcamEditors/FlatCAMGeoEditor.py:2837 +#: flatcamEditors/FlatCAMGeoEditor.py:2967 msgid "No text to add." msgstr "Niciun text de adăugat." -#: flatcamEditors/FlatCAMGeoEditor.py:2844 +#: flatcamEditors/FlatCAMGeoEditor.py:2977 msgid " Done. Adding Text completed." msgstr " Executat. Adăugarea de Text terminată." -#: flatcamEditors/FlatCAMGeoEditor.py:2881 +#: flatcamEditors/FlatCAMGeoEditor.py:3014 msgid "Create buffer geometry ..." msgstr "Crează o geometrie de tipe Bufer ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2892 -#: flatcamEditors/FlatCAMGeoEditor.py:2922 -#: flatcamEditors/FlatCAMGeoEditor.py:2952 -msgid "Buffer cancelled. No shape selected." -msgstr "" -"Crearea de geometrie Bufer anulată. Nici-o forma geometrică nu este " -"selectată." - -#: flatcamEditors/FlatCAMGeoEditor.py:2917 -#: flatcamEditors/FlatCAMGrbEditor.py:4950 +#: flatcamEditors/FlatCAMGeoEditor.py:3049 +#: flatcamEditors/FlatCAMGrbEditor.py:4994 msgid "Done. Buffer Tool completed." msgstr "Executat. Unealta Bufer terminată." -#: flatcamEditors/FlatCAMGeoEditor.py:2947 +#: flatcamEditors/FlatCAMGeoEditor.py:3077 msgid "Done. Buffer Int Tool completed." msgstr "Executat. Unealta Bufer Intern terminată." -#: flatcamEditors/FlatCAMGeoEditor.py:2977 +#: flatcamEditors/FlatCAMGeoEditor.py:3105 msgid "Done. Buffer Ext Tool completed." msgstr "Executat. Unealta Bufer Extern terminată." -#: flatcamEditors/FlatCAMGeoEditor.py:3023 -#: flatcamEditors/FlatCAMGrbEditor.py:2152 +#: flatcamEditors/FlatCAMGeoEditor.py:3154 +#: flatcamEditors/FlatCAMGrbEditor.py:2151 msgid "Select a shape to act as deletion area ..." msgstr "Selectează o formă geometrică ca formă de stergere ..." -#: flatcamEditors/FlatCAMGeoEditor.py:3025 -#: flatcamEditors/FlatCAMGeoEditor.py:3045 -#: flatcamEditors/FlatCAMGeoEditor.py:3051 -#: flatcamEditors/FlatCAMGrbEditor.py:2154 +#: flatcamEditors/FlatCAMGeoEditor.py:3156 +#: flatcamEditors/FlatCAMGeoEditor.py:3182 +#: flatcamEditors/FlatCAMGeoEditor.py:3188 +#: flatcamEditors/FlatCAMGrbEditor.py:2153 msgid "Click to pick-up the erase shape..." msgstr "Click pentru a activa forma de stergere..." -#: flatcamEditors/FlatCAMGeoEditor.py:3055 -#: flatcamEditors/FlatCAMGrbEditor.py:2213 +#: flatcamEditors/FlatCAMGeoEditor.py:3192 +#: flatcamEditors/FlatCAMGrbEditor.py:2212 msgid "Click to erase ..." msgstr "Click pt a sterge ..." -#: flatcamEditors/FlatCAMGeoEditor.py:3084 -#: flatcamEditors/FlatCAMGrbEditor.py:2246 +#: flatcamEditors/FlatCAMGeoEditor.py:3221 +#: flatcamEditors/FlatCAMGrbEditor.py:2245 msgid "Done. Eraser tool action completed." msgstr "Executat. Unealta Stergere s-a terminat." -#: flatcamEditors/FlatCAMGeoEditor.py:3131 +#: flatcamEditors/FlatCAMGeoEditor.py:3271 msgid "Create Paint geometry ..." msgstr "Crează o geometrie Paint ..." -#: flatcamEditors/FlatCAMGeoEditor.py:3144 -#: flatcamEditors/FlatCAMGrbEditor.py:2402 +#: flatcamEditors/FlatCAMGeoEditor.py:3284 +#: flatcamEditors/FlatCAMGrbEditor.py:2408 msgid "Shape transformations ..." msgstr "Transformări de forme geometrice ..." -#: flatcamEditors/FlatCAMGeoEditor.py:3763 +#: flatcamEditors/FlatCAMGeoEditor.py:3340 flatcamGUI/PreferencesUI.py:4636 +msgid "Geometry Editor" +msgstr "Editor Geometrii" + +#: flatcamEditors/FlatCAMGeoEditor.py:3346 +#: flatcamEditors/FlatCAMGrbEditor.py:2486 +#: flatcamEditors/FlatCAMGrbEditor.py:3846 flatcamGUI/ObjectUI.py:262 +#: flatcamGUI/ObjectUI.py:1495 flatcamGUI/ObjectUI.py:2244 +#: flatcamTools/ToolCutOut.py:96 +msgid "Type" +msgstr "Tip" + +#: flatcamEditors/FlatCAMGeoEditor.py:3346 flatcamGUI/ObjectUI.py:217 +#: flatcamGUI/ObjectUI.py:741 flatcamGUI/ObjectUI.py:1431 +#: flatcamGUI/ObjectUI.py:2153 flatcamGUI/ObjectUI.py:2457 +#: flatcamGUI/ObjectUI.py:2524 flatcamTools/ToolCalibration.py:234 +#: flatcamTools/ToolFiducials.py:73 +msgid "Name" +msgstr "Nume" + +#: flatcamEditors/FlatCAMGeoEditor.py:3588 +msgid "Ring" +msgstr "Inel" + +#: flatcamEditors/FlatCAMGeoEditor.py:3590 +msgid "Line" +msgstr "Linie" + +#: flatcamEditors/FlatCAMGeoEditor.py:3592 flatcamGUI/FlatCAMGUI.py:2187 +#: flatcamGUI/PreferencesUI.py:5607 flatcamGUI/PreferencesUI.py:6131 +#: flatcamTools/ToolNCC.py:584 flatcamTools/ToolPaint.py:528 +msgid "Polygon" +msgstr "Poligon" + +#: flatcamEditors/FlatCAMGeoEditor.py:3594 +msgid "Multi-Line" +msgstr "Multi-Linie" + +#: flatcamEditors/FlatCAMGeoEditor.py:3596 +msgid "Multi-Polygon" +msgstr "Multi-Poligon" + +#: flatcamEditors/FlatCAMGeoEditor.py:3603 +msgid "Geo Elem" +msgstr "Element Geo" + +#: flatcamEditors/FlatCAMGeoEditor.py:4076 msgid "Editing MultiGeo Geometry, tool" msgstr "Se editează Geometrie tip MultiGeo. unealta" -#: flatcamEditors/FlatCAMGeoEditor.py:3765 +#: flatcamEditors/FlatCAMGeoEditor.py:4078 msgid "with diameter" msgstr "cu diametrul" -#: flatcamEditors/FlatCAMGeoEditor.py:4169 -msgid "Copy cancelled. No shape selected." -msgstr "Copiere anulată. Nici-o forma geometrică nu este selectată." - -#: flatcamEditors/FlatCAMGeoEditor.py:4176 flatcamGUI/FlatCAMGUI.py:3472 -#: flatcamGUI/FlatCAMGUI.py:3519 flatcamGUI/FlatCAMGUI.py:3538 -#: flatcamGUI/FlatCAMGUI.py:3679 flatcamGUI/FlatCAMGUI.py:3719 -#: flatcamGUI/FlatCAMGUI.py:3732 flatcamGUI/FlatCAMGUI.py:3749 +#: flatcamEditors/FlatCAMGeoEditor.py:4509 flatcamGUI/FlatCAMGUI.py:3695 +#: flatcamGUI/FlatCAMGUI.py:3741 flatcamGUI/FlatCAMGUI.py:3759 +#: flatcamGUI/FlatCAMGUI.py:3899 flatcamGUI/FlatCAMGUI.py:3938 +#: flatcamGUI/FlatCAMGUI.py:3950 flatcamGUI/FlatCAMGUI.py:3967 msgid "Click on target point." msgstr "Click pe punctul tinta." -#: flatcamEditors/FlatCAMGeoEditor.py:4479 -#: flatcamEditors/FlatCAMGeoEditor.py:4514 +#: flatcamEditors/FlatCAMGeoEditor.py:4823 +#: flatcamEditors/FlatCAMGeoEditor.py:4858 msgid "A selection of at least 2 geo items is required to do Intersection." msgstr "" "Cel puțin o selecţie de doua forme geometrice este necesară pentru a face o " "Intersecţie." -#: flatcamEditors/FlatCAMGeoEditor.py:4600 -#: flatcamEditors/FlatCAMGeoEditor.py:4704 +#: flatcamEditors/FlatCAMGeoEditor.py:4944 +#: flatcamEditors/FlatCAMGeoEditor.py:5048 msgid "" "Negative buffer value is not accepted. Use Buffer interior to generate an " "'inside' shape" @@ -4515,59 +4861,59 @@ msgstr "" "O valoare de bufer negativă nu se acceptă. Foloseste Bufer Interior pentru a " "genera o formă geo. interioară" -#: flatcamEditors/FlatCAMGeoEditor.py:4610 -#: flatcamEditors/FlatCAMGeoEditor.py:4663 -#: flatcamEditors/FlatCAMGeoEditor.py:4713 +#: flatcamEditors/FlatCAMGeoEditor.py:4954 +#: flatcamEditors/FlatCAMGeoEditor.py:5007 +#: flatcamEditors/FlatCAMGeoEditor.py:5057 msgid "Nothing selected for buffering." msgstr "Nici-o forma geometrică nu este selectată pentru a face Bufer." -#: flatcamEditors/FlatCAMGeoEditor.py:4615 -#: flatcamEditors/FlatCAMGeoEditor.py:4667 -#: flatcamEditors/FlatCAMGeoEditor.py:4718 +#: flatcamEditors/FlatCAMGeoEditor.py:4959 +#: flatcamEditors/FlatCAMGeoEditor.py:5011 +#: flatcamEditors/FlatCAMGeoEditor.py:5062 msgid "Invalid distance for buffering." msgstr "Distanta invalida pentru a face Bufer." -#: flatcamEditors/FlatCAMGeoEditor.py:4639 -#: flatcamEditors/FlatCAMGeoEditor.py:4738 +#: flatcamEditors/FlatCAMGeoEditor.py:4983 +#: flatcamEditors/FlatCAMGeoEditor.py:5082 msgid "Failed, the result is empty. Choose a different buffer value." msgstr "Eșuat, rezultatul este gol. Foloseşte o valoare diferita pentru Bufer." -#: flatcamEditors/FlatCAMGeoEditor.py:4650 +#: flatcamEditors/FlatCAMGeoEditor.py:4994 msgid "Full buffer geometry created." msgstr "Geometrie tip Bufer Complet creată." -#: flatcamEditors/FlatCAMGeoEditor.py:4656 +#: flatcamEditors/FlatCAMGeoEditor.py:5000 msgid "Negative buffer value is not accepted." msgstr "Valoarea bufer negativă nu este acceptată." -#: flatcamEditors/FlatCAMGeoEditor.py:4687 +#: flatcamEditors/FlatCAMGeoEditor.py:5031 msgid "Failed, the result is empty. Choose a smaller buffer value." msgstr "Eșuat, rezultatul este gol. Foloseşte of valoare mai mica pt. Bufer." -#: flatcamEditors/FlatCAMGeoEditor.py:4697 +#: flatcamEditors/FlatCAMGeoEditor.py:5041 msgid "Interior buffer geometry created." msgstr "Geometrie Bufer interior creată." -#: flatcamEditors/FlatCAMGeoEditor.py:4748 +#: flatcamEditors/FlatCAMGeoEditor.py:5092 msgid "Exterior buffer geometry created." msgstr "Geometrie Bufer Exterior creată." -#: flatcamEditors/FlatCAMGeoEditor.py:4754 +#: flatcamEditors/FlatCAMGeoEditor.py:5098 #, python-format -msgid "Could not do Paint. Overlap value has to be less than 1.00 (100%%)." +msgid "Could not do Paint. Overlap value has to be less than 100%%." msgstr "" "Nu se poate face Paint. Valoarea de suprapunere trebuie să fie mai puțin de " -"1.00 (100%%)." +"100%%." -#: flatcamEditors/FlatCAMGeoEditor.py:4761 +#: flatcamEditors/FlatCAMGeoEditor.py:5105 msgid "Nothing selected for painting." msgstr "Nici-o forma geometrică nu este selectată pentru Paint." -#: flatcamEditors/FlatCAMGeoEditor.py:4767 +#: flatcamEditors/FlatCAMGeoEditor.py:5111 msgid "Invalid value for" msgstr "Valoare invalida pentru" -#: flatcamEditors/FlatCAMGeoEditor.py:4826 +#: flatcamEditors/FlatCAMGeoEditor.py:5170 msgid "" "Could not do Paint. Try a different combination of parameters. Or a " "different method of Paint" @@ -4575,7 +4921,7 @@ msgstr "" "Nu se poate face Paint. Incearcă o combinaţie diferita de parametri. Or o " "metoda diferita de Paint" -#: flatcamEditors/FlatCAMGeoEditor.py:4840 +#: flatcamEditors/FlatCAMGeoEditor.py:5181 msgid "Paint done." msgstr "Pictare executata." @@ -4591,7 +4937,7 @@ msgid "Aperture size is zero. It needs to be greater than zero." msgstr "Dimens. aperturii este zero. Trebuie sa fie mai mare ca zero." #: flatcamEditors/FlatCAMGrbEditor.py:371 -#: flatcamEditors/FlatCAMGrbEditor.py:685 +#: flatcamEditors/FlatCAMGrbEditor.py:684 msgid "" "Incompatible aperture type. Select an aperture with type 'C', 'R' or 'O'." msgstr "" @@ -4612,165 +4958,159 @@ msgstr "" msgid "Click on the Pad Circular Array Start position" msgstr "Click pe punctul de Start al ariei de paduri" -#: flatcamEditors/FlatCAMGrbEditor.py:711 +#: flatcamEditors/FlatCAMGrbEditor.py:710 msgid "Too many Pads for the selected spacing angle." msgstr "Prea multe paduri pentru unghiul selectat." -#: flatcamEditors/FlatCAMGrbEditor.py:734 +#: flatcamEditors/FlatCAMGrbEditor.py:733 msgid "Done. Pad Array added." msgstr "Executat. Aria de paduri a fost adăugată." -#: flatcamEditors/FlatCAMGrbEditor.py:759 +#: flatcamEditors/FlatCAMGrbEditor.py:758 msgid "Select shape(s) and then click ..." msgstr "Selectează formele si apoi click ..." -#: flatcamEditors/FlatCAMGrbEditor.py:771 +#: flatcamEditors/FlatCAMGrbEditor.py:770 msgid "Failed. Nothing selected." msgstr "Eșuat. Nu este nimic selectat." -#: flatcamEditors/FlatCAMGrbEditor.py:787 +#: flatcamEditors/FlatCAMGrbEditor.py:786 msgid "" "Failed. Poligonize works only on geometries belonging to the same aperture." msgstr "" "Esuat. Poligonizarea lucrează doar asupra geometriilor care apartin aceleasi " "aperturi." -#: flatcamEditors/FlatCAMGrbEditor.py:841 +#: flatcamEditors/FlatCAMGrbEditor.py:840 msgid "Done. Poligonize completed." msgstr "Executat. Poligonizare completă." -#: flatcamEditors/FlatCAMGrbEditor.py:896 -#: flatcamEditors/FlatCAMGrbEditor.py:1129 -#: flatcamEditors/FlatCAMGrbEditor.py:1153 +#: flatcamEditors/FlatCAMGrbEditor.py:895 +#: flatcamEditors/FlatCAMGrbEditor.py:1128 +#: flatcamEditors/FlatCAMGrbEditor.py:1152 msgid "Corner Mode 1: 45 degrees ..." msgstr "Mod Colt 1: 45 grade ..." -#: flatcamEditors/FlatCAMGrbEditor.py:908 -#: flatcamEditors/FlatCAMGrbEditor.py:1238 +#: flatcamEditors/FlatCAMGrbEditor.py:907 +#: flatcamEditors/FlatCAMGrbEditor.py:1237 msgid "Click on next Point or click Right mouse button to complete ..." msgstr "" "Click pe punctul următor sau click buton dreapta al mousului pentru " "terminare ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1117 -#: flatcamEditors/FlatCAMGrbEditor.py:1150 +#: flatcamEditors/FlatCAMGrbEditor.py:1116 +#: flatcamEditors/FlatCAMGrbEditor.py:1149 msgid "Corner Mode 2: Reverse 45 degrees ..." msgstr "Mod Colt 2: Invers 45 grade ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1120 -#: flatcamEditors/FlatCAMGrbEditor.py:1147 +#: flatcamEditors/FlatCAMGrbEditor.py:1119 +#: flatcamEditors/FlatCAMGrbEditor.py:1146 msgid "Corner Mode 3: 90 degrees ..." msgstr "Mod Colt 3: 90 grade ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1123 -#: flatcamEditors/FlatCAMGrbEditor.py:1144 +#: flatcamEditors/FlatCAMGrbEditor.py:1122 +#: flatcamEditors/FlatCAMGrbEditor.py:1143 msgid "Corner Mode 4: Reverse 90 degrees ..." msgstr "Mod Colt 4: Invers 90 grade ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1126 -#: flatcamEditors/FlatCAMGrbEditor.py:1141 +#: flatcamEditors/FlatCAMGrbEditor.py:1125 +#: flatcamEditors/FlatCAMGrbEditor.py:1140 msgid "Corner Mode 5: Free angle ..." msgstr "Mod Colt 5: Unghi liber ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1183 -#: flatcamEditors/FlatCAMGrbEditor.py:1359 -#: flatcamEditors/FlatCAMGrbEditor.py:1398 +#: flatcamEditors/FlatCAMGrbEditor.py:1182 +#: flatcamEditors/FlatCAMGrbEditor.py:1358 +#: flatcamEditors/FlatCAMGrbEditor.py:1397 msgid "Track Mode 1: 45 degrees ..." msgstr "Mod Traseu 1: 45 grade ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1339 -#: flatcamEditors/FlatCAMGrbEditor.py:1393 +#: flatcamEditors/FlatCAMGrbEditor.py:1338 +#: flatcamEditors/FlatCAMGrbEditor.py:1392 msgid "Track Mode 2: Reverse 45 degrees ..." msgstr "Mod Traseu 2: Invers 45 grade ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1344 -#: flatcamEditors/FlatCAMGrbEditor.py:1388 +#: flatcamEditors/FlatCAMGrbEditor.py:1343 +#: flatcamEditors/FlatCAMGrbEditor.py:1387 msgid "Track Mode 3: 90 degrees ..." msgstr "Mod Traseu 3: 90 grade ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1349 -#: flatcamEditors/FlatCAMGrbEditor.py:1383 +#: flatcamEditors/FlatCAMGrbEditor.py:1348 +#: flatcamEditors/FlatCAMGrbEditor.py:1382 msgid "Track Mode 4: Reverse 90 degrees ..." msgstr "Mod Traseu 4: Invers 90 grade ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1354 -#: flatcamEditors/FlatCAMGrbEditor.py:1378 +#: flatcamEditors/FlatCAMGrbEditor.py:1353 +#: flatcamEditors/FlatCAMGrbEditor.py:1377 msgid "Track Mode 5: Free angle ..." msgstr "Mod Traseu 5: Unghi liber ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1779 +#: flatcamEditors/FlatCAMGrbEditor.py:1778 msgid "Scale the selected Gerber apertures ..." msgstr "Șterge aperturile Gerber selectate ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1821 +#: flatcamEditors/FlatCAMGrbEditor.py:1820 msgid "Buffer the selected apertures ..." msgstr "Bufereaza aperturile selectate." -#: flatcamEditors/FlatCAMGrbEditor.py:1863 +#: flatcamEditors/FlatCAMGrbEditor.py:1862 msgid "Mark polygon areas in the edited Gerber ..." msgstr "Marchează ariile poligonale in obiectul Gerber editat ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1929 +#: flatcamEditors/FlatCAMGrbEditor.py:1928 msgid "Nothing selected to move" msgstr "Nimic nu este selectat pentru mutare" -#: flatcamEditors/FlatCAMGrbEditor.py:2054 +#: flatcamEditors/FlatCAMGrbEditor.py:2053 msgid "Done. Apertures Move completed." msgstr "Executat. Mutarea Aperturilor terminată." -#: flatcamEditors/FlatCAMGrbEditor.py:2136 +#: flatcamEditors/FlatCAMGrbEditor.py:2135 msgid "Done. Apertures copied." msgstr "Executat. Aperturile au fost copiate." -#: flatcamEditors/FlatCAMGrbEditor.py:2447 flatcamGUI/FlatCAMGUI.py:2110 -#: flatcamGUI/PreferencesUI.py:2443 +#: flatcamEditors/FlatCAMGrbEditor.py:2453 flatcamGUI/FlatCAMGUI.py:2218 +#: flatcamGUI/PreferencesUI.py:2623 msgid "Gerber Editor" msgstr "Editor Gerber" -#: flatcamEditors/FlatCAMGrbEditor.py:2467 flatcamGUI/ObjectUI.py:223 -#: flatcamTools/ToolProperties.py:156 +#: flatcamEditors/FlatCAMGrbEditor.py:2473 flatcamGUI/ObjectUI.py:227 +#: flatcamTools/ToolProperties.py:159 msgid "Apertures" msgstr "Aperturi" -#: flatcamEditors/FlatCAMGrbEditor.py:2469 flatcamGUI/ObjectUI.py:225 +#: flatcamEditors/FlatCAMGrbEditor.py:2475 flatcamGUI/ObjectUI.py:229 msgid "Apertures Table for the Gerber Object." msgstr "Tabela de aperturi pt obiectul Gerber." -#: flatcamEditors/FlatCAMGrbEditor.py:2480 -#: flatcamEditors/FlatCAMGrbEditor.py:3832 flatcamGUI/ObjectUI.py:258 +#: flatcamEditors/FlatCAMGrbEditor.py:2486 +#: flatcamEditors/FlatCAMGrbEditor.py:3846 flatcamGUI/ObjectUI.py:262 msgid "Code" msgstr "Cod" -#: flatcamEditors/FlatCAMGrbEditor.py:2480 -#: flatcamEditors/FlatCAMGrbEditor.py:3832 flatcamGUI/ObjectUI.py:258 -#: flatcamGUI/ObjectUI.py:1217 flatcamGUI/ObjectUI.py:1916 -msgid "Type" -msgstr "Tip" - -#: flatcamEditors/FlatCAMGrbEditor.py:2480 -#: flatcamEditors/FlatCAMGrbEditor.py:3832 flatcamGUI/ObjectUI.py:258 -#: flatcamGUI/PreferencesUI.py:1009 flatcamGUI/PreferencesUI.py:7270 -#: flatcamGUI/PreferencesUI.py:7299 flatcamGUI/PreferencesUI.py:7401 -#: flatcamTools/ToolCopperThieving.py:260 -#: flatcamTools/ToolCopperThieving.py:300 flatcamTools/ToolFiducials.py:156 +#: flatcamEditors/FlatCAMGrbEditor.py:2486 +#: flatcamEditors/FlatCAMGrbEditor.py:3846 flatcamGUI/ObjectUI.py:262 +#: flatcamGUI/PreferencesUI.py:1184 flatcamGUI/PreferencesUI.py:7776 +#: flatcamGUI/PreferencesUI.py:7805 flatcamGUI/PreferencesUI.py:7907 +#: flatcamTools/ToolCopperThieving.py:262 +#: flatcamTools/ToolCopperThieving.py:302 flatcamTools/ToolFiducials.py:156 msgid "Size" msgstr "Dimensiune" -#: flatcamEditors/FlatCAMGrbEditor.py:2480 -#: flatcamEditors/FlatCAMGrbEditor.py:3832 flatcamGUI/ObjectUI.py:258 +#: flatcamEditors/FlatCAMGrbEditor.py:2486 +#: flatcamEditors/FlatCAMGrbEditor.py:3846 flatcamGUI/ObjectUI.py:262 msgid "Dim" msgstr "Dim" -#: flatcamEditors/FlatCAMGrbEditor.py:2484 flatcamGUI/ObjectUI.py:262 +#: flatcamEditors/FlatCAMGrbEditor.py:2490 flatcamGUI/ObjectUI.py:266 msgid "Index" msgstr "Index" -#: flatcamEditors/FlatCAMGrbEditor.py:2486 -#: flatcamEditors/FlatCAMGrbEditor.py:2515 flatcamGUI/ObjectUI.py:264 +#: flatcamEditors/FlatCAMGrbEditor.py:2492 +#: flatcamEditors/FlatCAMGrbEditor.py:2521 flatcamGUI/ObjectUI.py:268 msgid "Aperture Code" msgstr "Cod" -#: flatcamEditors/FlatCAMGrbEditor.py:2488 flatcamGUI/ObjectUI.py:266 +#: flatcamEditors/FlatCAMGrbEditor.py:2494 flatcamGUI/ObjectUI.py:270 msgid "Type of aperture: circular, rectangle, macros etc" msgstr "" "Tipul aperturilor:\n" @@ -4779,11 +5119,11 @@ msgstr "" "- macro-uri\n" "etc" -#: flatcamEditors/FlatCAMGrbEditor.py:2490 flatcamGUI/ObjectUI.py:268 +#: flatcamEditors/FlatCAMGrbEditor.py:2496 flatcamGUI/ObjectUI.py:272 msgid "Aperture Size:" msgstr "Dim. aper.:" -#: flatcamEditors/FlatCAMGrbEditor.py:2492 flatcamGUI/ObjectUI.py:270 +#: flatcamEditors/FlatCAMGrbEditor.py:2498 flatcamGUI/ObjectUI.py:274 msgid "" "Aperture Dimensions:\n" " - (width, height) for R, O type.\n" @@ -4793,15 +5133,15 @@ msgstr "" "- (latime, inaltime) pt tipurile R, O.\n" "- (diametru, nVertices) pt tipul P" -#: flatcamEditors/FlatCAMGrbEditor.py:2516 flatcamGUI/PreferencesUI.py:2474 +#: flatcamEditors/FlatCAMGrbEditor.py:2522 flatcamGUI/PreferencesUI.py:2654 msgid "Code for the new aperture" msgstr "Diametru pentru noua apertură" -#: flatcamEditors/FlatCAMGrbEditor.py:2525 +#: flatcamEditors/FlatCAMGrbEditor.py:2531 msgid "Aperture Size" msgstr "Dim. aper" -#: flatcamEditors/FlatCAMGrbEditor.py:2527 +#: flatcamEditors/FlatCAMGrbEditor.py:2533 msgid "" "Size for the new aperture.\n" "If aperture type is 'R' or 'O' then\n" @@ -4814,11 +5154,11 @@ msgstr "" "valoarea este calculată automat prin:\n" "sqrt(lătime**2 + inăltime**2)" -#: flatcamEditors/FlatCAMGrbEditor.py:2541 +#: flatcamEditors/FlatCAMGrbEditor.py:2547 msgid "Aperture Type" msgstr "Tip aper" -#: flatcamEditors/FlatCAMGrbEditor.py:2543 +#: flatcamEditors/FlatCAMGrbEditor.py:2549 msgid "" "Select the type of new aperture. Can be:\n" "C = circular\n" @@ -4830,11 +5170,11 @@ msgstr "" "R = rectangular\n" "O = oval" -#: flatcamEditors/FlatCAMGrbEditor.py:2554 +#: flatcamEditors/FlatCAMGrbEditor.py:2560 msgid "Aperture Dim" msgstr "Dim. aper" -#: flatcamEditors/FlatCAMGrbEditor.py:2556 +#: flatcamEditors/FlatCAMGrbEditor.py:2562 msgid "" "Dimensions for the new aperture.\n" "Active only for rectangular apertures (type R).\n" @@ -4844,39 +5184,39 @@ msgstr "" "Activă doar pentru aperturile rectangulare (tip 'R').\n" "Formatul este (lătime, inăltime)" -#: flatcamEditors/FlatCAMGrbEditor.py:2565 +#: flatcamEditors/FlatCAMGrbEditor.py:2571 msgid "Add/Delete Aperture" msgstr "Adaugă/Șterge apertură" -#: flatcamEditors/FlatCAMGrbEditor.py:2567 +#: flatcamEditors/FlatCAMGrbEditor.py:2573 msgid "Add/Delete an aperture in the aperture table" msgstr "Adaugă/Șterge o apertură din lista de aperturi" -#: flatcamEditors/FlatCAMGrbEditor.py:2576 +#: flatcamEditors/FlatCAMGrbEditor.py:2582 msgid "Add a new aperture to the aperture list." msgstr "Adaugă o nouă apertură in lista de aperturi." -#: flatcamEditors/FlatCAMGrbEditor.py:2581 +#: flatcamEditors/FlatCAMGrbEditor.py:2587 msgid "Delete a aperture in the aperture list" msgstr "Șterge o apertură din lista de aperturi" -#: flatcamEditors/FlatCAMGrbEditor.py:2598 +#: flatcamEditors/FlatCAMGrbEditor.py:2604 msgid "Buffer Aperture" msgstr "Bufer pt apertură" -#: flatcamEditors/FlatCAMGrbEditor.py:2600 +#: flatcamEditors/FlatCAMGrbEditor.py:2606 msgid "Buffer a aperture in the aperture list" msgstr "Fă bufer pt o apertură din lista de aperturi" -#: flatcamEditors/FlatCAMGrbEditor.py:2613 flatcamGUI/PreferencesUI.py:2608 +#: flatcamEditors/FlatCAMGrbEditor.py:2619 flatcamGUI/PreferencesUI.py:2790 msgid "Buffer distance" msgstr "Distanta pt bufer" -#: flatcamEditors/FlatCAMGrbEditor.py:2614 +#: flatcamEditors/FlatCAMGrbEditor.py:2620 msgid "Buffer corner" msgstr "Coltul pt bufer" -#: flatcamEditors/FlatCAMGrbEditor.py:2616 +#: flatcamEditors/FlatCAMGrbEditor.py:2622 msgid "" "There are 3 types of corners:\n" " - 'Round': the corner is rounded.\n" @@ -4890,27 +5230,26 @@ msgstr "" " - 'Beveled:' coltul este inlocuit cu o linie care uneste capetele liniilor " "care formează coltul" -#: flatcamEditors/FlatCAMGrbEditor.py:2631 flatcamGUI/FlatCAMGUI.py:978 -#: flatcamGUI/FlatCAMGUI.py:2015 flatcamGUI/FlatCAMGUI.py:2087 -#: flatcamGUI/FlatCAMGUI.py:2130 flatcamGUI/FlatCAMGUI.py:2547 -#: flatcamGUI/PreferencesUI.py:6393 flatcamTools/ToolTransform.py:30 -#: flatcamTools/ToolTransform.py:349 +#: flatcamEditors/FlatCAMGrbEditor.py:2637 flatcamGUI/FlatCAMGUI.py:1046 +#: flatcamGUI/FlatCAMGUI.py:2123 flatcamGUI/FlatCAMGUI.py:2195 +#: flatcamGUI/FlatCAMGUI.py:2238 flatcamGUI/FlatCAMGUI.py:2721 +#: flatcamGUI/PreferencesUI.py:6880 flatcamTools/ToolTransform.py:30 msgid "Buffer" msgstr "Bufer" -#: flatcamEditors/FlatCAMGrbEditor.py:2646 +#: flatcamEditors/FlatCAMGrbEditor.py:2652 msgid "Scale Aperture" msgstr "Scalează aper" -#: flatcamEditors/FlatCAMGrbEditor.py:2648 +#: flatcamEditors/FlatCAMGrbEditor.py:2654 msgid "Scale a aperture in the aperture list" msgstr "Scalează o apertură in lista de aperturi" -#: flatcamEditors/FlatCAMGrbEditor.py:2656 flatcamGUI/PreferencesUI.py:2623 +#: flatcamEditors/FlatCAMGrbEditor.py:2662 flatcamGUI/PreferencesUI.py:2805 msgid "Scale factor" msgstr "Factor Scalare" -#: flatcamEditors/FlatCAMGrbEditor.py:2658 +#: flatcamEditors/FlatCAMGrbEditor.py:2664 msgid "" "The factor by which to scale the selected aperture.\n" "Values can be between 0.0000 and 999.9999" @@ -4918,19 +5257,19 @@ msgstr "" "Factorul cu care se va face scalarea aperturii selectate.\n" "Poate lua valori intre: 0.000 si 999.9999" -#: flatcamEditors/FlatCAMGrbEditor.py:2686 +#: flatcamEditors/FlatCAMGrbEditor.py:2692 msgid "Mark polygons" msgstr "Marchează poligoanele" -#: flatcamEditors/FlatCAMGrbEditor.py:2688 +#: flatcamEditors/FlatCAMGrbEditor.py:2694 msgid "Mark the polygon areas." msgstr "Marchează ariile poligonale." -#: flatcamEditors/FlatCAMGrbEditor.py:2696 +#: flatcamEditors/FlatCAMGrbEditor.py:2702 msgid "Area UPPER threshold" msgstr "Pragul de sus pt. arie" -#: flatcamEditors/FlatCAMGrbEditor.py:2698 +#: flatcamEditors/FlatCAMGrbEditor.py:2704 msgid "" "The threshold value, all areas less than this are marked.\n" "Can have a value between 0.0000 and 9999.9999" @@ -4938,11 +5277,11 @@ msgstr "" "Valoare de prag, toate poligoanele cu arii mai mici vor fi marcate.\n" "Poate lua valori intre: 0.000 si 999.9999" -#: flatcamEditors/FlatCAMGrbEditor.py:2705 +#: flatcamEditors/FlatCAMGrbEditor.py:2711 msgid "Area LOWER threshold" msgstr "Pragul de jos pt. arie" -#: flatcamEditors/FlatCAMGrbEditor.py:2707 +#: flatcamEditors/FlatCAMGrbEditor.py:2713 msgid "" "The threshold value, all areas more than this are marked.\n" "Can have a value between 0.0000 and 9999.9999" @@ -4950,36 +5289,32 @@ msgstr "" "Valoare de prag, toate poligoanele cu arii mai mari vor fi marcate.\n" "Poate lua valori intre: 0.000 si 999.9999" -#: flatcamEditors/FlatCAMGrbEditor.py:2721 +#: flatcamEditors/FlatCAMGrbEditor.py:2727 msgid "Mark" msgstr "Marchează" -#: flatcamEditors/FlatCAMGrbEditor.py:2723 +#: flatcamEditors/FlatCAMGrbEditor.py:2729 msgid "Mark the polygons that fit within limits." msgstr "Marcați poligoanele care se încadrează în limite." -#: flatcamEditors/FlatCAMGrbEditor.py:2729 +#: flatcamEditors/FlatCAMGrbEditor.py:2735 msgid "Delete all the marked polygons." msgstr "Ștergeți toate poligoanele marcate." -#: flatcamEditors/FlatCAMGrbEditor.py:2733 -msgid "Clear" -msgstr "Șterge" - -#: flatcamEditors/FlatCAMGrbEditor.py:2735 +#: flatcamEditors/FlatCAMGrbEditor.py:2741 msgid "Clear all the markings." msgstr "Ștergeți toate marcajele." -#: flatcamEditors/FlatCAMGrbEditor.py:2755 flatcamGUI/FlatCAMGUI.py:963 -#: flatcamGUI/FlatCAMGUI.py:2015 flatcamGUI/FlatCAMGUI.py:2532 +#: flatcamEditors/FlatCAMGrbEditor.py:2761 flatcamGUI/FlatCAMGUI.py:1031 +#: flatcamGUI/FlatCAMGUI.py:2123 flatcamGUI/FlatCAMGUI.py:2706 msgid "Add Pad Array" msgstr "Adaugă o arie de paduri" -#: flatcamEditors/FlatCAMGrbEditor.py:2757 +#: flatcamEditors/FlatCAMGrbEditor.py:2763 msgid "Add an array of pads (linear or circular array)" msgstr "Adaugă o arie de paduri (arie lineara sau circulara)." -#: flatcamEditors/FlatCAMGrbEditor.py:2763 +#: flatcamEditors/FlatCAMGrbEditor.py:2769 msgid "" "Select the type of pads array to create.\n" "It can be Linear X(Y) or Circular" @@ -4987,15 +5322,15 @@ msgstr "" "Selectează tipul de arii de paduri.\n" "Poate fi Liniar X(Y) sau Circular" -#: flatcamEditors/FlatCAMGrbEditor.py:2774 flatcamGUI/PreferencesUI.py:2511 +#: flatcamEditors/FlatCAMGrbEditor.py:2780 flatcamGUI/PreferencesUI.py:2691 msgid "Nr of pads" msgstr "Nr. paduri" -#: flatcamEditors/FlatCAMGrbEditor.py:2776 flatcamGUI/PreferencesUI.py:2513 +#: flatcamEditors/FlatCAMGrbEditor.py:2782 flatcamGUI/PreferencesUI.py:2693 msgid "Specify how many pads to be in the array." msgstr "Specifica cate paduri să fie incluse in arie." -#: flatcamEditors/FlatCAMGrbEditor.py:2825 +#: flatcamEditors/FlatCAMGrbEditor.py:2831 msgid "" "Angle at which the linear array is placed.\n" "The precision is of max 2 decimals.\n" @@ -5007,14 +5342,14 @@ msgstr "" "Val minima este: -359.99 grade.\n" "Val maxima este: 360.00 grade." -#: flatcamEditors/FlatCAMGrbEditor.py:3307 -#: flatcamEditors/FlatCAMGrbEditor.py:3311 +#: flatcamEditors/FlatCAMGrbEditor.py:3321 +#: flatcamEditors/FlatCAMGrbEditor.py:3325 msgid "Aperture code value is missing or wrong format. Add it and retry." msgstr "" "Valoarea codului aperturii lipseste sau este in format greșit. Adaugă din " "nou și reîncearcă." -#: flatcamEditors/FlatCAMGrbEditor.py:3347 +#: flatcamEditors/FlatCAMGrbEditor.py:3361 msgid "" "Aperture dimensions value is missing or wrong format. Add it in format " "(width, height) and retry." @@ -5022,190 +5357,190 @@ msgstr "" "Dimensiunile aperturii lipsesc sau sunt intr-un format greșit. Adaugă din " "nou și reîncearcă." -#: flatcamEditors/FlatCAMGrbEditor.py:3360 +#: flatcamEditors/FlatCAMGrbEditor.py:3374 msgid "Aperture size value is missing or wrong format. Add it and retry." msgstr "" "Valoarea mărimii aperturii lipseste sau este in format greșit. Adaugă din " "nou și reîncearcă." -#: flatcamEditors/FlatCAMGrbEditor.py:3371 +#: flatcamEditors/FlatCAMGrbEditor.py:3385 msgid "Aperture already in the aperture table." msgstr "Apertura este deja in lista de aperturi." -#: flatcamEditors/FlatCAMGrbEditor.py:3379 +#: flatcamEditors/FlatCAMGrbEditor.py:3393 msgid "Added new aperture with code" msgstr "O nouă apertură este adăugată cu codul" -#: flatcamEditors/FlatCAMGrbEditor.py:3408 +#: flatcamEditors/FlatCAMGrbEditor.py:3422 msgid " Select an aperture in Aperture Table" msgstr " Selectează o unealtă in Tabela de Aperturi" -#: flatcamEditors/FlatCAMGrbEditor.py:3416 +#: flatcamEditors/FlatCAMGrbEditor.py:3430 msgid "Select an aperture in Aperture Table -->" msgstr "Selectează o unealtă in Tabela de Aperturi -->" -#: flatcamEditors/FlatCAMGrbEditor.py:3439 +#: flatcamEditors/FlatCAMGrbEditor.py:3453 msgid "Deleted aperture with code" msgstr "A fost stearsă unealta cu codul" -#: flatcamEditors/FlatCAMGrbEditor.py:3924 +#: flatcamEditors/FlatCAMGrbEditor.py:3950 msgid "Loading Gerber into Editor" msgstr "Se încarcă Gerber în editor" -#: flatcamEditors/FlatCAMGrbEditor.py:4034 +#: flatcamEditors/FlatCAMGrbEditor.py:4078 msgid "Setting up the UI" msgstr "Configurarea UI" -#: flatcamEditors/FlatCAMGrbEditor.py:4035 +#: flatcamEditors/FlatCAMGrbEditor.py:4079 msgid "Adding geometry finished. Preparing the GUI" msgstr "Adăugarea geometriei terminate. Pregătirea GUI" -#: flatcamEditors/FlatCAMGrbEditor.py:4044 +#: flatcamEditors/FlatCAMGrbEditor.py:4088 msgid "Finished loading the Gerber object into the editor." msgstr "S-a terminat încărcarea obiectului Gerber în editor." -#: flatcamEditors/FlatCAMGrbEditor.py:4184 +#: flatcamEditors/FlatCAMGrbEditor.py:4228 msgid "" "There are no Aperture definitions in the file. Aborting Gerber creation." msgstr "" "Nu există definitii de aperturi in fişier. Se anulează crearea de obiect " "Gerber." -#: flatcamEditors/FlatCAMGrbEditor.py:4194 +#: flatcamEditors/FlatCAMGrbEditor.py:4238 msgid "Creating Gerber." msgstr "Gerber in curs de creare." -#: flatcamEditors/FlatCAMGrbEditor.py:4203 +#: flatcamEditors/FlatCAMGrbEditor.py:4247 msgid "Done. Gerber editing finished." msgstr "Editarea Gerber a fost terminată." -#: flatcamEditors/FlatCAMGrbEditor.py:4222 +#: flatcamEditors/FlatCAMGrbEditor.py:4265 msgid "Cancelled. No aperture is selected" msgstr "Anulat. Nici-o apertură nu este selectată" -#: flatcamEditors/FlatCAMGrbEditor.py:4782 +#: flatcamEditors/FlatCAMGrbEditor.py:4826 msgid "Failed. No aperture geometry is selected." msgstr "Anulat. Nici-o geometrie de apertură nu este selectată." -#: flatcamEditors/FlatCAMGrbEditor.py:4791 -#: flatcamEditors/FlatCAMGrbEditor.py:5062 +#: flatcamEditors/FlatCAMGrbEditor.py:4835 +#: flatcamEditors/FlatCAMGrbEditor.py:5106 msgid "Done. Apertures geometry deleted." msgstr "Executat. Geometriile aperturilor au fost șterse." -#: flatcamEditors/FlatCAMGrbEditor.py:4934 +#: flatcamEditors/FlatCAMGrbEditor.py:4978 msgid "No aperture to buffer. Select at least one aperture and try again." msgstr "" "Nici-o apertură sel. pt a face bufer. Selectează cel puțin o apertură și " "încearcă din nou." -#: flatcamEditors/FlatCAMGrbEditor.py:4946 +#: flatcamEditors/FlatCAMGrbEditor.py:4990 msgid "Failed." msgstr "Esuat." -#: flatcamEditors/FlatCAMGrbEditor.py:4965 +#: flatcamEditors/FlatCAMGrbEditor.py:5009 msgid "Scale factor value is missing or wrong format. Add it and retry." msgstr "" "Valoarea factorului de scalare lipseste sau este in format gresit. Adaugă " "din nou și reîncearcă." -#: flatcamEditors/FlatCAMGrbEditor.py:4997 +#: flatcamEditors/FlatCAMGrbEditor.py:5041 msgid "No aperture to scale. Select at least one aperture and try again." msgstr "" "Nici-o apertură sel. pt scalare. Selectează cel puțin o apertură și încearcă " "din nou." -#: flatcamEditors/FlatCAMGrbEditor.py:5013 +#: flatcamEditors/FlatCAMGrbEditor.py:5057 msgid "Done. Scale Tool completed." msgstr "Executat. Unealta Scalare a terminat." -#: flatcamEditors/FlatCAMGrbEditor.py:5051 +#: flatcamEditors/FlatCAMGrbEditor.py:5095 msgid "Polygons marked." msgstr "Poligoanele sunt marcate." -#: flatcamEditors/FlatCAMGrbEditor.py:5054 +#: flatcamEditors/FlatCAMGrbEditor.py:5098 msgid "No polygons were marked. None fit within the limits." msgstr "Nu au fost marcate poligoane. Niciunul nu se încadrează în limite." -#: flatcamEditors/FlatCAMGrbEditor.py:5783 +#: flatcamEditors/FlatCAMGrbEditor.py:5822 msgid "Rotation action was not executed." msgstr "Actiuena de rotatie nu a fost efectuatăt." -#: flatcamEditors/FlatCAMGrbEditor.py:5919 +#: flatcamEditors/FlatCAMGrbEditor.py:5950 msgid "Skew action was not executed." msgstr "Actiunea de deformare nu a fost efectuată." -#: flatcamEditors/FlatCAMGrbEditor.py:5986 +#: flatcamEditors/FlatCAMGrbEditor.py:6015 msgid "Scale action was not executed." msgstr "Actiuena de scalare nu a fost efectuată." -#: flatcamEditors/FlatCAMGrbEditor.py:6029 +#: flatcamEditors/FlatCAMGrbEditor.py:6058 msgid "Offset action was not executed." msgstr "Actiuena de offset nu a fost efectuată." -#: flatcamEditors/FlatCAMGrbEditor.py:6079 +#: flatcamEditors/FlatCAMGrbEditor.py:6108 msgid "Geometry shape offset Y cancelled" msgstr "Deplasarea formei geometrice pe axa Y anulată" -#: flatcamEditors/FlatCAMGrbEditor.py:6094 +#: flatcamEditors/FlatCAMGrbEditor.py:6123 msgid "Geometry shape skew X cancelled" msgstr "Deformarea formei geometrice pe axa X anulată" -#: flatcamEditors/FlatCAMGrbEditor.py:6109 +#: flatcamEditors/FlatCAMGrbEditor.py:6138 msgid "Geometry shape skew Y cancelled" msgstr "Deformarea formei geometrice pe axa Y executată" -#: flatcamEditors/FlatCAMTextEditor.py:72 +#: flatcamEditors/FlatCAMTextEditor.py:74 msgid "Print Preview" msgstr "Preview tiparire" -#: flatcamEditors/FlatCAMTextEditor.py:73 +#: flatcamEditors/FlatCAMTextEditor.py:75 msgid "Open a OS standard Preview Print window." msgstr "Deschide o fereastra standard a OS cu Previzualizare Tiparire." -#: flatcamEditors/FlatCAMTextEditor.py:76 +#: flatcamEditors/FlatCAMTextEditor.py:78 msgid "Print Code" msgstr "Tipareste Cod" -#: flatcamEditors/FlatCAMTextEditor.py:77 +#: flatcamEditors/FlatCAMTextEditor.py:79 msgid "Open a OS standard Print window." msgstr "Deschide o fereastra standard a OS pt Tiparire." -#: flatcamEditors/FlatCAMTextEditor.py:79 +#: flatcamEditors/FlatCAMTextEditor.py:81 msgid "Find in Code" msgstr "Cauta in Cod" -#: flatcamEditors/FlatCAMTextEditor.py:80 +#: flatcamEditors/FlatCAMTextEditor.py:82 msgid "Will search and highlight in yellow the string in the Find box." msgstr "Va cauta si va sublinia in galben acele stringuri din campul Cautare." -#: flatcamEditors/FlatCAMTextEditor.py:84 +#: flatcamEditors/FlatCAMTextEditor.py:86 msgid "Find box. Enter here the strings to be searched in the text." msgstr "" "Campul Cautare. Introduceti aici acele stringuri care sa fie cautate in text." -#: flatcamEditors/FlatCAMTextEditor.py:86 +#: flatcamEditors/FlatCAMTextEditor.py:88 msgid "Replace With" msgstr "Inlocuieste cu" -#: flatcamEditors/FlatCAMTextEditor.py:87 +#: flatcamEditors/FlatCAMTextEditor.py:89 msgid "" "Will replace the string from the Find box with the one in the Replace box." msgstr "" "Va inlocui toate cuvintele gasite conform cu ce este in 'Căutare'\n" "cu textul din casuta 'Inlocuieste'." -#: flatcamEditors/FlatCAMTextEditor.py:91 +#: flatcamEditors/FlatCAMTextEditor.py:93 msgid "String to replace the one in the Find box throughout the text." msgstr "" "String care sa inlocuiasca pe acele din campul 'Cautare' in cadrul textului." -#: flatcamEditors/FlatCAMTextEditor.py:93 flatcamGUI/ObjectUI.py:482 -#: flatcamGUI/ObjectUI.py:1809 flatcamGUI/PreferencesUI.py:2070 -#: flatcamGUI/PreferencesUI.py:4419 flatcamGUI/PreferencesUI.py:5647 +#: flatcamEditors/FlatCAMTextEditor.py:95 flatcamGUI/ObjectUI.py:485 +#: flatcamGUI/ObjectUI.py:2137 flatcamGUI/PreferencesUI.py:2250 +#: flatcamGUI/PreferencesUI.py:4712 msgid "All" msgstr "Toate" -#: flatcamEditors/FlatCAMTextEditor.py:94 +#: flatcamEditors/FlatCAMTextEditor.py:96 msgid "" "When checked it will replace all instances in the 'Find' box\n" "with the text in the 'Replace' box.." @@ -5214,163 +5549,172 @@ msgstr "" "'Caută'\n" "cu textul din casuta 'Inlocuieste'..." -#: flatcamEditors/FlatCAMTextEditor.py:97 +#: flatcamEditors/FlatCAMTextEditor.py:99 msgid "Copy All" msgstr "Copiază tot" -#: flatcamEditors/FlatCAMTextEditor.py:98 +#: flatcamEditors/FlatCAMTextEditor.py:100 msgid "Will copy all the text in the Code Editor to the clipboard." msgstr "Va copia textul din editorul de cod în clipboard." -#: flatcamEditors/FlatCAMTextEditor.py:101 +#: flatcamEditors/FlatCAMTextEditor.py:103 msgid "Open Code" msgstr "Deschide Cod" -#: flatcamEditors/FlatCAMTextEditor.py:102 +#: flatcamEditors/FlatCAMTextEditor.py:104 msgid "Will open a text file in the editor." msgstr "Va deschide un fisier text in Editor." -#: flatcamEditors/FlatCAMTextEditor.py:104 +#: flatcamEditors/FlatCAMTextEditor.py:106 msgid "Save Code" msgstr "Salvează Cod" -#: flatcamEditors/FlatCAMTextEditor.py:105 +#: flatcamEditors/FlatCAMTextEditor.py:107 msgid "Will save the text in the editor into a file." msgstr "Va salva textul din Editor intr-un fisier." -#: flatcamEditors/FlatCAMTextEditor.py:107 +#: flatcamEditors/FlatCAMTextEditor.py:109 msgid "Run Code" msgstr "Rulează Cod" -#: flatcamEditors/FlatCAMTextEditor.py:108 +#: flatcamEditors/FlatCAMTextEditor.py:110 msgid "Will run the TCL commands found in the text file, one by one." msgstr "" "Va rula instructiunile/comenzile TCL care se găsesc in textul din Editor, " "una cate una." -#: flatcamEditors/FlatCAMTextEditor.py:182 +#: flatcamEditors/FlatCAMTextEditor.py:184 msgid "Open file" msgstr "Deschide fişierul" -#: flatcamEditors/FlatCAMTextEditor.py:213 -#: flatcamEditors/FlatCAMTextEditor.py:218 +#: flatcamEditors/FlatCAMTextEditor.py:215 +#: flatcamEditors/FlatCAMTextEditor.py:220 msgid "Export Code ..." msgstr "Exportă GCode ..." -#: flatcamEditors/FlatCAMTextEditor.py:221 -msgid "Export Code cancelled." -msgstr "Exportul Codului este anulat." - -#: flatcamEditors/FlatCAMTextEditor.py:332 +#: flatcamEditors/FlatCAMTextEditor.py:334 msgid "Code Editor content copied to clipboard ..." msgstr "Conținut Editor de cod copiat în clipboard ..." -#: flatcamGUI/FlatCAMGUI.py:52 flatcamGUI/FlatCAMGUI.py:54 -#: flatcamGUI/FlatCAMGUI.py:2040 +#: flatcamGUI/FlatCAMGUI.py:66 flatcamGUI/FlatCAMGUI.py:68 +#: flatcamGUI/FlatCAMGUI.py:2148 msgid "Toggle Panel" msgstr "Comută Panel" -#: flatcamGUI/FlatCAMGUI.py:64 +#: flatcamGUI/FlatCAMGUI.py:78 msgid "File" msgstr "Fişiere" -#: flatcamGUI/FlatCAMGUI.py:69 +#: flatcamGUI/FlatCAMGUI.py:83 msgid "&New Project ...\tCtrl+N" msgstr "&Proiect Nou...\tCtrl+N" -#: flatcamGUI/FlatCAMGUI.py:71 +#: flatcamGUI/FlatCAMGUI.py:85 msgid "Will create a new, blank project" msgstr "Se va crea un proiect nou, fără continut" -#: flatcamGUI/FlatCAMGUI.py:76 +#: flatcamGUI/FlatCAMGUI.py:90 msgid "&New" msgstr "&Nou" -#: flatcamGUI/FlatCAMGUI.py:80 +#: flatcamGUI/FlatCAMGUI.py:94 msgid "Geometry\tN" msgstr "Geometrie\tN" -#: flatcamGUI/FlatCAMGUI.py:82 +#: flatcamGUI/FlatCAMGUI.py:96 msgid "Will create a new, empty Geometry Object." msgstr "Va crea un obiect nou de tip Geometrie, fără continut." -#: flatcamGUI/FlatCAMGUI.py:84 +#: flatcamGUI/FlatCAMGUI.py:99 msgid "Gerber\tB" msgstr "Gerber\tB" -#: flatcamGUI/FlatCAMGUI.py:86 +#: flatcamGUI/FlatCAMGUI.py:101 msgid "Will create a new, empty Gerber Object." msgstr "Va crea un obiect nou de tip Gerber, fără continut." -#: flatcamGUI/FlatCAMGUI.py:88 +#: flatcamGUI/FlatCAMGUI.py:104 msgid "Excellon\tL" msgstr "Excellon\tL" -#: flatcamGUI/FlatCAMGUI.py:90 +#: flatcamGUI/FlatCAMGUI.py:106 msgid "Will create a new, empty Excellon Object." msgstr "Va crea un obiect nou de tip Excellon, fără continut." -#: flatcamGUI/FlatCAMGUI.py:94 +#: flatcamGUI/FlatCAMGUI.py:111 msgid "Document\tD" msgstr "Document\tD" -#: flatcamGUI/FlatCAMGUI.py:96 +#: flatcamGUI/FlatCAMGUI.py:113 msgid "Will create a new, empty Document Object." msgstr "Va crea un obiect nou de tip Document, fără continut." -#: flatcamGUI/FlatCAMGUI.py:99 flatcamGUI/FlatCAMGUI.py:4111 +#: flatcamGUI/FlatCAMGUI.py:117 flatcamGUI/FlatCAMGUI.py:4327 #: flatcamTools/ToolPcbWizard.py:62 flatcamTools/ToolPcbWizard.py:69 msgid "Open" msgstr "Încarcă" -#: flatcamGUI/FlatCAMGUI.py:103 +#: flatcamGUI/FlatCAMGUI.py:122 msgid "Open &Project ..." msgstr "Încarcă &Project ..." -#: flatcamGUI/FlatCAMGUI.py:109 flatcamGUI/FlatCAMGUI.py:4121 +#: flatcamGUI/FlatCAMGUI.py:128 flatcamGUI/FlatCAMGUI.py:4337 msgid "Open &Gerber ...\tCtrl+G" msgstr "Încarcă &Gerber ...\tCtrl+G" -#: flatcamGUI/FlatCAMGUI.py:114 flatcamGUI/FlatCAMGUI.py:4126 +#: flatcamGUI/FlatCAMGUI.py:133 flatcamGUI/FlatCAMGUI.py:4342 msgid "Open &Excellon ...\tCtrl+E" msgstr "Încarcă &Excellon ...\tCtrl+E" -#: flatcamGUI/FlatCAMGUI.py:118 flatcamGUI/FlatCAMGUI.py:4131 +#: flatcamGUI/FlatCAMGUI.py:138 flatcamGUI/FlatCAMGUI.py:4347 msgid "Open G-&Code ..." msgstr "Încarcă G-&Code ..." -#: flatcamGUI/FlatCAMGUI.py:124 +#: flatcamGUI/FlatCAMGUI.py:145 msgid "Open Config ..." msgstr "Încarcă Config ..." -#: flatcamGUI/FlatCAMGUI.py:128 +#: flatcamGUI/FlatCAMGUI.py:150 msgid "Recent projects" msgstr "Proiectele recente" -#: flatcamGUI/FlatCAMGUI.py:129 +#: flatcamGUI/FlatCAMGUI.py:152 msgid "Recent files" msgstr "Fişierele Recente" -#: flatcamGUI/FlatCAMGUI.py:135 +#: flatcamGUI/FlatCAMGUI.py:155 flatcamGUI/FlatCAMGUI.py:738 +#: flatcamGUI/FlatCAMGUI.py:1324 +msgid "Save" +msgstr "Salvează" + +#: flatcamGUI/FlatCAMGUI.py:159 +msgid "&Save Project ...\tCtrl+S" +msgstr "Salvează Proiect ...\tCtrl+S" + +#: flatcamGUI/FlatCAMGUI.py:164 +msgid "Save Project &As ...\tCtrl+Shift+S" +msgstr "Salvează Proiect ca ...\tCtrl+Shift+S" + +#: flatcamGUI/FlatCAMGUI.py:179 msgid "Scripting" msgstr "Scripting" -#: flatcamGUI/FlatCAMGUI.py:138 flatcamGUI/FlatCAMGUI.py:829 -#: flatcamGUI/FlatCAMGUI.py:2409 +#: flatcamGUI/FlatCAMGUI.py:183 flatcamGUI/FlatCAMGUI.py:888 +#: flatcamGUI/FlatCAMGUI.py:2567 msgid "New Script ..." msgstr "Script nou ..." -#: flatcamGUI/FlatCAMGUI.py:139 flatcamGUI/FlatCAMGUI.py:831 -#: flatcamGUI/FlatCAMGUI.py:2411 +#: flatcamGUI/FlatCAMGUI.py:185 flatcamGUI/FlatCAMGUI.py:890 +#: flatcamGUI/FlatCAMGUI.py:2569 msgid "Open Script ..." msgstr "Încarcă &Script..." -#: flatcamGUI/FlatCAMGUI.py:141 flatcamGUI/FlatCAMGUI.py:833 -#: flatcamGUI/FlatCAMGUI.py:2413 flatcamGUI/FlatCAMGUI.py:4100 +#: flatcamGUI/FlatCAMGUI.py:187 flatcamGUI/FlatCAMGUI.py:892 +#: flatcamGUI/FlatCAMGUI.py:2571 flatcamGUI/FlatCAMGUI.py:4316 msgid "Run Script ..." msgstr "Rulează Script..." -#: flatcamGUI/FlatCAMGUI.py:143 flatcamGUI/FlatCAMGUI.py:4102 +#: flatcamGUI/FlatCAMGUI.py:189 flatcamGUI/FlatCAMGUI.py:4318 msgid "" "Will run the opened Tcl Script thus\n" "enabling the automation of certain\n" @@ -5380,47 +5724,47 @@ msgstr "" "o automatizare a anumitor functii\n" "din FlatCAM." -#: flatcamGUI/FlatCAMGUI.py:156 +#: flatcamGUI/FlatCAMGUI.py:203 msgid "Import" msgstr "Import" -#: flatcamGUI/FlatCAMGUI.py:158 +#: flatcamGUI/FlatCAMGUI.py:205 msgid "&SVG as Geometry Object ..." msgstr "&SVG ca și obiect Geometrie ..." -#: flatcamGUI/FlatCAMGUI.py:161 +#: flatcamGUI/FlatCAMGUI.py:208 msgid "&SVG as Gerber Object ..." msgstr "&SVG ca și obiect Gerber ..." -#: flatcamGUI/FlatCAMGUI.py:166 +#: flatcamGUI/FlatCAMGUI.py:213 msgid "&DXF as Geometry Object ..." msgstr "&DXF ca și obiect Geometrie ..." -#: flatcamGUI/FlatCAMGUI.py:169 +#: flatcamGUI/FlatCAMGUI.py:216 msgid "&DXF as Gerber Object ..." msgstr "&DXF ca și obiect Gerber ..." -#: flatcamGUI/FlatCAMGUI.py:173 +#: flatcamGUI/FlatCAMGUI.py:220 msgid "HPGL2 as Geometry Object ..." msgstr "HPGL2 ca obiect de geometrie ..." -#: flatcamGUI/FlatCAMGUI.py:178 +#: flatcamGUI/FlatCAMGUI.py:226 msgid "Export" msgstr "Export" -#: flatcamGUI/FlatCAMGUI.py:181 +#: flatcamGUI/FlatCAMGUI.py:230 msgid "Export &SVG ..." msgstr "Exporta &SVG ..." -#: flatcamGUI/FlatCAMGUI.py:184 +#: flatcamGUI/FlatCAMGUI.py:234 msgid "Export DXF ..." msgstr "Exporta DXF ..." -#: flatcamGUI/FlatCAMGUI.py:189 +#: flatcamGUI/FlatCAMGUI.py:240 msgid "Export &PNG ..." msgstr "Exporta &PNG ..." -#: flatcamGUI/FlatCAMGUI.py:191 +#: flatcamGUI/FlatCAMGUI.py:242 msgid "" "Will export an image in PNG format,\n" "the saved image will contain the visual \n" @@ -5430,11 +5774,11 @@ msgstr "" "imagina salvata va contine elementele vizuale\n" "afisate in zona de afișare." -#: flatcamGUI/FlatCAMGUI.py:200 +#: flatcamGUI/FlatCAMGUI.py:251 msgid "Export &Excellon ..." msgstr "Exporta Excellon ..." -#: flatcamGUI/FlatCAMGUI.py:202 +#: flatcamGUI/FlatCAMGUI.py:253 msgid "" "Will export an Excellon Object as Excellon file,\n" "the coordinates format, the file units and zeros\n" @@ -5444,11 +5788,11 @@ msgstr "" "Formatul coordonatelor, unitatile de masura și tipul\n" "de zerouri se vor seta in Preferințe -> Export Excellon." -#: flatcamGUI/FlatCAMGUI.py:209 +#: flatcamGUI/FlatCAMGUI.py:260 msgid "Export &Gerber ..." msgstr "Exporta &Gerber ..." -#: flatcamGUI/FlatCAMGUI.py:211 +#: flatcamGUI/FlatCAMGUI.py:262 msgid "" "Will export an Gerber Object as Gerber file,\n" "the coordinates format, the file units and zeros\n" @@ -5458,65 +5802,48 @@ msgstr "" "Formatul coordonatelor, unitatile de măsură și tipul\n" "de zerouri se vor seta in Preferințe -> Export Gerber." -#: flatcamGUI/FlatCAMGUI.py:229 +#: flatcamGUI/FlatCAMGUI.py:272 msgid "Backup" msgstr "Backup" -#: flatcamGUI/FlatCAMGUI.py:233 +#: flatcamGUI/FlatCAMGUI.py:277 msgid "Import Preferences from file ..." msgstr "Importați Preferințele din fișier ..." -#: flatcamGUI/FlatCAMGUI.py:238 +#: flatcamGUI/FlatCAMGUI.py:283 msgid "Export Preferences to file ..." msgstr "Exportați Preferințele într-un fișier ..." -#: flatcamGUI/FlatCAMGUI.py:244 flatcamGUI/FlatCAMGUI.py:1614 +#: flatcamGUI/FlatCAMGUI.py:297 flatcamGUI/FlatCAMGUI.py:1715 msgid "Print (PDF)" msgstr "Tipărire (PDF)" -#: flatcamGUI/FlatCAMGUI.py:247 flatcamGUI/FlatCAMGUI.py:682 -#: flatcamGUI/FlatCAMGUI.py:1252 -msgid "Save" -msgstr "Salvează" - -#: flatcamGUI/FlatCAMGUI.py:251 -msgid "&Save Project ..." -msgstr "&Salvează Proiect ..." - -#: flatcamGUI/FlatCAMGUI.py:256 -msgid "Save Project &As ...\tCtrl+S" -msgstr "Salvează Proiect &ca ...\tCtrl+S" - -#: flatcamGUI/FlatCAMGUI.py:261 -msgid "Save Project C&opy ..." -msgstr "Salvează o C&opie Proiect..." - -#: flatcamGUI/FlatCAMGUI.py:271 +#: flatcamGUI/FlatCAMGUI.py:305 msgid "E&xit" msgstr "Iesire" -#: flatcamGUI/FlatCAMGUI.py:279 flatcamGUI/FlatCAMGUI.py:676 -#: flatcamGUI/FlatCAMGUI.py:2163 +#: flatcamGUI/FlatCAMGUI.py:313 flatcamGUI/FlatCAMGUI.py:732 +#: flatcamGUI/FlatCAMGUI.py:2271 msgid "Edit" msgstr "Editează" -#: flatcamGUI/FlatCAMGUI.py:283 +#: flatcamGUI/FlatCAMGUI.py:317 msgid "Edit Object\tE" msgstr "Editare Obiect\tE" -#: flatcamGUI/FlatCAMGUI.py:285 +#: flatcamGUI/FlatCAMGUI.py:319 msgid "Close Editor\tCtrl+S" msgstr "Salvează Editor\tCtrl+S" -#: flatcamGUI/FlatCAMGUI.py:294 +#: flatcamGUI/FlatCAMGUI.py:328 msgid "Conversion" msgstr "Conversii" -#: flatcamGUI/FlatCAMGUI.py:296 +#: flatcamGUI/FlatCAMGUI.py:330 msgid "&Join Geo/Gerber/Exc -> Geo" msgstr "&Fuzionează Geo/Gerber/Exc -> Geo" -#: flatcamGUI/FlatCAMGUI.py:298 +#: flatcamGUI/FlatCAMGUI.py:332 msgid "" "Merge a selection of objects, which can be of type:\n" "- Gerber\n" @@ -5530,30 +5857,30 @@ msgstr "" "- Geometrie\n" "intr-un nou obiect tip Geometrie >combo<." -#: flatcamGUI/FlatCAMGUI.py:305 +#: flatcamGUI/FlatCAMGUI.py:339 msgid "Join Excellon(s) -> Excellon" msgstr "Fuzionează Excellon(s) -> Excellon" -#: flatcamGUI/FlatCAMGUI.py:307 +#: flatcamGUI/FlatCAMGUI.py:341 msgid "Merge a selection of Excellon objects into a new combo Excellon object." msgstr "" "Fuzionează o selecţie de obiecte Excellon intr-un nou obiect Excellon " ">combo<." -#: flatcamGUI/FlatCAMGUI.py:310 +#: flatcamGUI/FlatCAMGUI.py:344 msgid "Join Gerber(s) -> Gerber" msgstr "Fuzionează Gerber(s) -> Gerber" -#: flatcamGUI/FlatCAMGUI.py:312 +#: flatcamGUI/FlatCAMGUI.py:346 msgid "Merge a selection of Gerber objects into a new combo Gerber object." msgstr "" "Fuzionează o selecţie de obiecte Gerber intr-un nou obiect Gerber >combo<." -#: flatcamGUI/FlatCAMGUI.py:317 +#: flatcamGUI/FlatCAMGUI.py:351 msgid "Convert Single to MultiGeo" msgstr "Converteste SingleGeo in MultiGeo" -#: flatcamGUI/FlatCAMGUI.py:319 +#: flatcamGUI/FlatCAMGUI.py:353 msgid "" "Will convert a Geometry object from single_geometry type\n" "to a multi_geometry type." @@ -5561,11 +5888,11 @@ msgstr "" "Va converti un obiect Geometrie din tipul simpla geometrie (SingleGeo)\n" "la tipul geometrie complexa (MultiGeo)." -#: flatcamGUI/FlatCAMGUI.py:323 +#: flatcamGUI/FlatCAMGUI.py:357 msgid "Convert Multi to SingleGeo" msgstr "Converteste MultiGeo in SingleGeo" -#: flatcamGUI/FlatCAMGUI.py:325 +#: flatcamGUI/FlatCAMGUI.py:359 msgid "" "Will convert a Geometry object from multi_geometry type\n" "to a single_geometry type." @@ -5573,734 +5900,744 @@ msgstr "" "Va converti un obiect Geometrie din tipul geometrie complexa (MultiGeo)\n" "la tipul geometrie simpla (SingleGeo)." -#: flatcamGUI/FlatCAMGUI.py:332 +#: flatcamGUI/FlatCAMGUI.py:366 msgid "Convert Any to Geo" msgstr "Converteste Oricare to Geo" -#: flatcamGUI/FlatCAMGUI.py:335 +#: flatcamGUI/FlatCAMGUI.py:369 msgid "Convert Any to Gerber" msgstr "Converteste Oricare in Gerber" -#: flatcamGUI/FlatCAMGUI.py:341 +#: flatcamGUI/FlatCAMGUI.py:375 msgid "&Copy\tCtrl+C" msgstr "&Copiază\tCtrl+C" -#: flatcamGUI/FlatCAMGUI.py:346 +#: flatcamGUI/FlatCAMGUI.py:380 msgid "&Delete\tDEL" msgstr "&Șterge\tDEL" -#: flatcamGUI/FlatCAMGUI.py:351 +#: flatcamGUI/FlatCAMGUI.py:385 msgid "Se&t Origin\tO" msgstr "Se&tează Originea\tO" -#: flatcamGUI/FlatCAMGUI.py:353 +#: flatcamGUI/FlatCAMGUI.py:387 +msgid "Move to Origin\tShift+O" +msgstr "Deplasează la Origine\tShift+O" + +#: flatcamGUI/FlatCAMGUI.py:390 msgid "Jump to Location\tJ" msgstr "Sari la Locaţie\tJ" -#: flatcamGUI/FlatCAMGUI.py:358 +#: flatcamGUI/FlatCAMGUI.py:392 +msgid "Locate in Object\tShift+J" +msgstr "Localizează in Obiect\tShift+J" + +#: flatcamGUI/FlatCAMGUI.py:397 msgid "Toggle Units\tQ" msgstr "Comută Unitati\tQ" -#: flatcamGUI/FlatCAMGUI.py:360 +#: flatcamGUI/FlatCAMGUI.py:399 msgid "&Select All\tCtrl+A" msgstr "&Selectează Tot\tCtrl+A" -#: flatcamGUI/FlatCAMGUI.py:365 +#: flatcamGUI/FlatCAMGUI.py:404 msgid "&Preferences\tShift+P" msgstr "&Preferințe\tShift+P" -#: flatcamGUI/FlatCAMGUI.py:371 flatcamTools/ToolProperties.py:153 +#: flatcamGUI/FlatCAMGUI.py:410 flatcamTools/ToolProperties.py:155 msgid "Options" msgstr "Opțiuni" -#: flatcamGUI/FlatCAMGUI.py:373 +#: flatcamGUI/FlatCAMGUI.py:412 msgid "&Rotate Selection\tShift+(R)" msgstr "&Roteste Selectia\tShift+(R)" -#: flatcamGUI/FlatCAMGUI.py:378 +#: flatcamGUI/FlatCAMGUI.py:417 msgid "&Skew on X axis\tShift+X" msgstr "&Deformează pe axa X\tShift+X" -#: flatcamGUI/FlatCAMGUI.py:380 +#: flatcamGUI/FlatCAMGUI.py:419 msgid "S&kew on Y axis\tShift+Y" msgstr "Deformează pe axa Y\tShift+Y" -#: flatcamGUI/FlatCAMGUI.py:385 +#: flatcamGUI/FlatCAMGUI.py:424 msgid "Flip on &X axis\tX" msgstr "Oglindește pe axa &X\tX" -#: flatcamGUI/FlatCAMGUI.py:387 +#: flatcamGUI/FlatCAMGUI.py:426 msgid "Flip on &Y axis\tY" msgstr "Oglindește pe axa &Y\tY" -#: flatcamGUI/FlatCAMGUI.py:392 +#: flatcamGUI/FlatCAMGUI.py:431 msgid "View source\tAlt+S" msgstr "Vezi sursa\tAlt+S" -#: flatcamGUI/FlatCAMGUI.py:394 +#: flatcamGUI/FlatCAMGUI.py:433 msgid "Tools DataBase\tCtrl+D" msgstr "Baza de data Unelte\tCtrl+D" -#: flatcamGUI/FlatCAMGUI.py:401 flatcamGUI/FlatCAMGUI.py:2060 +#: flatcamGUI/FlatCAMGUI.py:440 flatcamGUI/FlatCAMGUI.py:2168 msgid "View" msgstr "Vizualizare" -#: flatcamGUI/FlatCAMGUI.py:403 +#: flatcamGUI/FlatCAMGUI.py:442 msgid "Enable all plots\tAlt+1" msgstr "Activează toate afişările\tAlt+1" -#: flatcamGUI/FlatCAMGUI.py:405 +#: flatcamGUI/FlatCAMGUI.py:444 msgid "Disable all plots\tAlt+2" msgstr "Dezactivează toate afişările\tAlt+2" -#: flatcamGUI/FlatCAMGUI.py:407 +#: flatcamGUI/FlatCAMGUI.py:446 msgid "Disable non-selected\tAlt+3" msgstr "Dezactivează non-selectate\tAlt+3" -#: flatcamGUI/FlatCAMGUI.py:411 +#: flatcamGUI/FlatCAMGUI.py:450 msgid "&Zoom Fit\tV" msgstr "&Mărește și potrivește\tV" -#: flatcamGUI/FlatCAMGUI.py:413 +#: flatcamGUI/FlatCAMGUI.py:452 msgid "&Zoom In\t=" msgstr "&Măreste\t=" -#: flatcamGUI/FlatCAMGUI.py:415 +#: flatcamGUI/FlatCAMGUI.py:454 msgid "&Zoom Out\t-" msgstr "&Micșorează\t-" -#: flatcamGUI/FlatCAMGUI.py:420 +#: flatcamGUI/FlatCAMGUI.py:459 msgid "Redraw All\tF5" msgstr "Reafisare Toate\tF5" -#: flatcamGUI/FlatCAMGUI.py:424 +#: flatcamGUI/FlatCAMGUI.py:463 msgid "Toggle Code Editor\tShift+E" msgstr "Comută Editorul de cod\tShift+E" -#: flatcamGUI/FlatCAMGUI.py:427 +#: flatcamGUI/FlatCAMGUI.py:466 msgid "&Toggle FullScreen\tAlt+F10" msgstr "Comută FullScreen\tAlt+F10" -#: flatcamGUI/FlatCAMGUI.py:429 +#: flatcamGUI/FlatCAMGUI.py:468 msgid "&Toggle Plot Area\tCtrl+F10" msgstr "Comută Aria de Afișare\tCtrl+F10" -#: flatcamGUI/FlatCAMGUI.py:431 +#: flatcamGUI/FlatCAMGUI.py:470 msgid "&Toggle Project/Sel/Tool\t`" msgstr "Comută Proiect/Sel/Unealta\t`" -#: flatcamGUI/FlatCAMGUI.py:435 +#: flatcamGUI/FlatCAMGUI.py:474 msgid "&Toggle Grid Snap\tG" msgstr "Comută Grid\tG" -#: flatcamGUI/FlatCAMGUI.py:437 +#: flatcamGUI/FlatCAMGUI.py:476 msgid "&Toggle Grid Lines\tAlt+G" msgstr "Comută Linii Grid\tAlt+G" -#: flatcamGUI/FlatCAMGUI.py:439 +#: flatcamGUI/FlatCAMGUI.py:478 msgid "&Toggle Axis\tShift+G" msgstr "Comută Axe\tShift+G" -#: flatcamGUI/FlatCAMGUI.py:441 +#: flatcamGUI/FlatCAMGUI.py:480 msgid "Toggle Workspace\tShift+W" msgstr "Comută Suprafata de lucru\tShift+W" -#: flatcamGUI/FlatCAMGUI.py:446 +#: flatcamGUI/FlatCAMGUI.py:485 msgid "Objects" msgstr "Obiecte" -#: flatcamGUI/FlatCAMGUI.py:460 +#: flatcamGUI/FlatCAMGUI.py:499 msgid "&Command Line\tS" msgstr "&Linie de comanda\tS" -#: flatcamGUI/FlatCAMGUI.py:465 +#: flatcamGUI/FlatCAMGUI.py:504 msgid "Help" msgstr "Ajutor" -#: flatcamGUI/FlatCAMGUI.py:467 +#: flatcamGUI/FlatCAMGUI.py:506 msgid "Online Help\tF1" msgstr "Resurse online\tF1" -#: flatcamGUI/FlatCAMGUI.py:477 +#: flatcamGUI/FlatCAMGUI.py:516 msgid "Report a bug" msgstr "Raportati o eroare program" -#: flatcamGUI/FlatCAMGUI.py:480 +#: flatcamGUI/FlatCAMGUI.py:519 msgid "Excellon Specification" msgstr "Specificatii Excellon" -#: flatcamGUI/FlatCAMGUI.py:482 +#: flatcamGUI/FlatCAMGUI.py:521 msgid "Gerber Specification" msgstr "Specificatii Gerber" -#: flatcamGUI/FlatCAMGUI.py:487 +#: flatcamGUI/FlatCAMGUI.py:526 msgid "Shortcuts List\tF3" msgstr "Lista shortcut-uri\tF3" -#: flatcamGUI/FlatCAMGUI.py:489 +#: flatcamGUI/FlatCAMGUI.py:528 msgid "YouTube Channel\tF4" msgstr "YouTube \tF4" -#: flatcamGUI/FlatCAMGUI.py:500 +#: flatcamGUI/FlatCAMGUI.py:539 msgid "Add Circle\tO" msgstr "Adaugă Cerc\tO" -#: flatcamGUI/FlatCAMGUI.py:503 +#: flatcamGUI/FlatCAMGUI.py:542 msgid "Add Arc\tA" msgstr "Adaugă Arc\tA" -#: flatcamGUI/FlatCAMGUI.py:506 +#: flatcamGUI/FlatCAMGUI.py:545 msgid "Add Rectangle\tR" msgstr "Adaugă Patrulater\tR" -#: flatcamGUI/FlatCAMGUI.py:509 +#: flatcamGUI/FlatCAMGUI.py:548 msgid "Add Polygon\tN" msgstr "Adaugă Poligon\tN" -#: flatcamGUI/FlatCAMGUI.py:512 +#: flatcamGUI/FlatCAMGUI.py:551 msgid "Add Path\tP" msgstr "Adaugă Cale\tP" -#: flatcamGUI/FlatCAMGUI.py:515 +#: flatcamGUI/FlatCAMGUI.py:554 msgid "Add Text\tT" msgstr "Adaugă Text\tT" -#: flatcamGUI/FlatCAMGUI.py:518 +#: flatcamGUI/FlatCAMGUI.py:557 msgid "Polygon Union\tU" msgstr "Uniune Poligoane\tU" -#: flatcamGUI/FlatCAMGUI.py:520 +#: flatcamGUI/FlatCAMGUI.py:559 msgid "Polygon Intersection\tE" msgstr "Intersecţie Poligoane\tE" -#: flatcamGUI/FlatCAMGUI.py:522 +#: flatcamGUI/FlatCAMGUI.py:561 msgid "Polygon Subtraction\tS" msgstr "Substracţie Poligoane\tS" -#: flatcamGUI/FlatCAMGUI.py:526 +#: flatcamGUI/FlatCAMGUI.py:565 msgid "Cut Path\tX" msgstr "Tăiere Cale\tX" -#: flatcamGUI/FlatCAMGUI.py:529 +#: flatcamGUI/FlatCAMGUI.py:569 msgid "Copy Geom\tC" msgstr "Copiază Geo\tC" -#: flatcamGUI/FlatCAMGUI.py:531 +#: flatcamGUI/FlatCAMGUI.py:571 msgid "Delete Shape\tDEL" msgstr "Șterge forma Geo.\tDEL" -#: flatcamGUI/FlatCAMGUI.py:535 flatcamGUI/FlatCAMGUI.py:622 +#: flatcamGUI/FlatCAMGUI.py:575 flatcamGUI/FlatCAMGUI.py:662 msgid "Move\tM" msgstr "Muta\tM" -#: flatcamGUI/FlatCAMGUI.py:537 +#: flatcamGUI/FlatCAMGUI.py:577 msgid "Buffer Tool\tB" msgstr "Unealta Bufer\tB" -#: flatcamGUI/FlatCAMGUI.py:540 +#: flatcamGUI/FlatCAMGUI.py:580 msgid "Paint Tool\tI" msgstr "Unealta Paint\tI" -#: flatcamGUI/FlatCAMGUI.py:543 +#: flatcamGUI/FlatCAMGUI.py:583 msgid "Transform Tool\tAlt+R" msgstr "Unealta Transformare\tAlt+R" -#: flatcamGUI/FlatCAMGUI.py:547 +#: flatcamGUI/FlatCAMGUI.py:587 msgid "Toggle Corner Snap\tK" msgstr "Comută lipire colt\tK" -#: flatcamGUI/FlatCAMGUI.py:553 +#: flatcamGUI/FlatCAMGUI.py:593 msgid ">Excellon Editor<" msgstr ">Editor Excellon<" -#: flatcamGUI/FlatCAMGUI.py:557 +#: flatcamGUI/FlatCAMGUI.py:597 msgid "Add Drill Array\tA" msgstr "Adaugă Arie Găuriri\tA" -#: flatcamGUI/FlatCAMGUI.py:559 +#: flatcamGUI/FlatCAMGUI.py:599 msgid "Add Drill\tD" msgstr "Adaugă Găurire\tD" -#: flatcamGUI/FlatCAMGUI.py:563 +#: flatcamGUI/FlatCAMGUI.py:603 msgid "Add Slot Array\tQ" msgstr "Adăugați Arie de Sloturi\tQ" -#: flatcamGUI/FlatCAMGUI.py:565 +#: flatcamGUI/FlatCAMGUI.py:605 msgid "Add Slot\tW" msgstr "Adăugați Slot\tW" -#: flatcamGUI/FlatCAMGUI.py:569 +#: flatcamGUI/FlatCAMGUI.py:609 msgid "Resize Drill(S)\tR" msgstr "Redimens. Găuriri\tR" -#: flatcamGUI/FlatCAMGUI.py:572 flatcamGUI/FlatCAMGUI.py:616 +#: flatcamGUI/FlatCAMGUI.py:612 flatcamGUI/FlatCAMGUI.py:656 msgid "Copy\tC" msgstr "Copiază\tC" -#: flatcamGUI/FlatCAMGUI.py:574 flatcamGUI/FlatCAMGUI.py:618 +#: flatcamGUI/FlatCAMGUI.py:614 flatcamGUI/FlatCAMGUI.py:658 msgid "Delete\tDEL" msgstr "Șterge\tDEL" -#: flatcamGUI/FlatCAMGUI.py:579 +#: flatcamGUI/FlatCAMGUI.py:619 msgid "Move Drill(s)\tM" msgstr "Muta Găuriri\tM" -#: flatcamGUI/FlatCAMGUI.py:584 +#: flatcamGUI/FlatCAMGUI.py:624 msgid ">Gerber Editor<" msgstr ">Editor Gerber<" -#: flatcamGUI/FlatCAMGUI.py:588 +#: flatcamGUI/FlatCAMGUI.py:628 msgid "Add Pad\tP" msgstr "Adaugă Pad\tP" -#: flatcamGUI/FlatCAMGUI.py:590 +#: flatcamGUI/FlatCAMGUI.py:630 msgid "Add Pad Array\tA" msgstr "Adaugă Arie paduri\tA" -#: flatcamGUI/FlatCAMGUI.py:592 +#: flatcamGUI/FlatCAMGUI.py:632 msgid "Add Track\tT" msgstr "Adaugă Traseu\tA" -#: flatcamGUI/FlatCAMGUI.py:594 +#: flatcamGUI/FlatCAMGUI.py:634 msgid "Add Region\tN" msgstr "Adaugă Regiune\tN" -#: flatcamGUI/FlatCAMGUI.py:598 +#: flatcamGUI/FlatCAMGUI.py:638 msgid "Poligonize\tAlt+N" msgstr "Poligonizare\tAlt+N" -#: flatcamGUI/FlatCAMGUI.py:600 +#: flatcamGUI/FlatCAMGUI.py:640 msgid "Add SemiDisc\tE" msgstr "Adaugă SemiDisc\tE" -#: flatcamGUI/FlatCAMGUI.py:602 +#: flatcamGUI/FlatCAMGUI.py:642 msgid "Add Disc\tD" msgstr "Adaugă Disc\tD" -#: flatcamGUI/FlatCAMGUI.py:604 +#: flatcamGUI/FlatCAMGUI.py:644 msgid "Buffer\tB" msgstr "Bufer\tB" -#: flatcamGUI/FlatCAMGUI.py:606 +#: flatcamGUI/FlatCAMGUI.py:646 msgid "Scale\tS" msgstr "Scalare\tS" -#: flatcamGUI/FlatCAMGUI.py:608 +#: flatcamGUI/FlatCAMGUI.py:648 msgid "Mark Area\tAlt+A" msgstr "Marchează aria\tAlt+A" -#: flatcamGUI/FlatCAMGUI.py:610 +#: flatcamGUI/FlatCAMGUI.py:650 msgid "Eraser\tCtrl+E" msgstr "Radieră\tCtrl+E" -#: flatcamGUI/FlatCAMGUI.py:612 +#: flatcamGUI/FlatCAMGUI.py:652 msgid "Transform\tAlt+R" msgstr "Unealta Transformare\tAlt+R" -#: flatcamGUI/FlatCAMGUI.py:639 +#: flatcamGUI/FlatCAMGUI.py:679 msgid "Enable Plot" msgstr "Activează Afișare" -#: flatcamGUI/FlatCAMGUI.py:641 +#: flatcamGUI/FlatCAMGUI.py:681 msgid "Disable Plot" msgstr "Dezactivează Afișare" -#: flatcamGUI/FlatCAMGUI.py:645 +#: flatcamGUI/FlatCAMGUI.py:685 msgid "Set Color" msgstr "Setați culoarea" -#: flatcamGUI/FlatCAMGUI.py:648 -msgid "Red" -msgstr "Roșu" - -#: flatcamGUI/FlatCAMGUI.py:651 -msgid "Blue" -msgstr "Albastru" - -#: flatcamGUI/FlatCAMGUI.py:654 -msgid "Yellow" -msgstr "Galben" - -#: flatcamGUI/FlatCAMGUI.py:657 -msgid "Green" -msgstr "Verde" - -#: flatcamGUI/FlatCAMGUI.py:660 -msgid "Purple" -msgstr "Violet" - -#: flatcamGUI/FlatCAMGUI.py:663 -msgid "Brown" -msgstr "Maro" - -#: flatcamGUI/FlatCAMGUI.py:666 -msgid "Custom" -msgstr "Personalizat" - -#: flatcamGUI/FlatCAMGUI.py:671 +#: flatcamGUI/FlatCAMGUI.py:727 msgid "Generate CNC" msgstr "Generează CNC" -#: flatcamGUI/FlatCAMGUI.py:673 +#: flatcamGUI/FlatCAMGUI.py:729 msgid "View Source" msgstr "Vizualiz. Sursa" -#: flatcamGUI/FlatCAMGUI.py:686 flatcamGUI/FlatCAMGUI.py:2172 -#: flatcamTools/ToolProperties.py:30 +#: flatcamGUI/FlatCAMGUI.py:742 flatcamGUI/FlatCAMGUI.py:2280 +#: flatcamTools/ToolProperties.py:31 msgid "Properties" msgstr "Proprietati" -#: flatcamGUI/FlatCAMGUI.py:715 +#: flatcamGUI/FlatCAMGUI.py:771 msgid "File Toolbar" msgstr "Toolbar Fişiere" -#: flatcamGUI/FlatCAMGUI.py:719 +#: flatcamGUI/FlatCAMGUI.py:775 msgid "Edit Toolbar" msgstr "Toolbar Editare" -#: flatcamGUI/FlatCAMGUI.py:723 +#: flatcamGUI/FlatCAMGUI.py:779 msgid "View Toolbar" msgstr "Toolbar Vizualizare" -#: flatcamGUI/FlatCAMGUI.py:727 +#: flatcamGUI/FlatCAMGUI.py:783 msgid "Shell Toolbar" msgstr "Toolbar Linie de comanda" -#: flatcamGUI/FlatCAMGUI.py:731 +#: flatcamGUI/FlatCAMGUI.py:787 msgid "Tools Toolbar" msgstr "Toolbar Unelte" -#: flatcamGUI/FlatCAMGUI.py:735 +#: flatcamGUI/FlatCAMGUI.py:791 msgid "Excellon Editor Toolbar" msgstr "Toolbar Editor Excellon" -#: flatcamGUI/FlatCAMGUI.py:741 +#: flatcamGUI/FlatCAMGUI.py:797 msgid "Geometry Editor Toolbar" msgstr "Toolbar Editor Geometrii" -#: flatcamGUI/FlatCAMGUI.py:745 +#: flatcamGUI/FlatCAMGUI.py:801 msgid "Gerber Editor Toolbar" msgstr "Toolbar Editor Gerber" -#: flatcamGUI/FlatCAMGUI.py:749 +#: flatcamGUI/FlatCAMGUI.py:805 msgid "Grid Toolbar" msgstr "Toolbar Grid-uri" -#: flatcamGUI/FlatCAMGUI.py:772 flatcamGUI/FlatCAMGUI.py:2357 +#: flatcamGUI/FlatCAMGUI.py:826 flatcamGUI/FlatCAMGUI.py:2509 msgid "Open project" msgstr "Încarcă Proiect" -#: flatcamGUI/FlatCAMGUI.py:774 flatcamGUI/FlatCAMGUI.py:2359 +#: flatcamGUI/FlatCAMGUI.py:828 flatcamGUI/FlatCAMGUI.py:2511 msgid "Save project" msgstr "Salvează Proiect" -#: flatcamGUI/FlatCAMGUI.py:780 flatcamGUI/FlatCAMGUI.py:2363 +#: flatcamGUI/FlatCAMGUI.py:834 flatcamGUI/FlatCAMGUI.py:2517 msgid "New Blank Geometry" msgstr "Geometrie Noua (goală)" -#: flatcamGUI/FlatCAMGUI.py:782 flatcamGUI/FlatCAMGUI.py:2365 +#: flatcamGUI/FlatCAMGUI.py:836 flatcamGUI/FlatCAMGUI.py:2519 msgid "New Blank Gerber" msgstr "Gerber Nou (gol)" -#: flatcamGUI/FlatCAMGUI.py:784 flatcamGUI/FlatCAMGUI.py:2367 +#: flatcamGUI/FlatCAMGUI.py:838 flatcamGUI/FlatCAMGUI.py:2521 msgid "New Blank Excellon" msgstr "Excellon nou (gol)" -#: flatcamGUI/FlatCAMGUI.py:789 flatcamGUI/FlatCAMGUI.py:2373 +#: flatcamGUI/FlatCAMGUI.py:843 flatcamGUI/FlatCAMGUI.py:2527 msgid "Save Object and close the Editor" msgstr "Salvează Obiectul și inchide Editorul" -#: flatcamGUI/FlatCAMGUI.py:796 flatcamGUI/FlatCAMGUI.py:2380 +#: flatcamGUI/FlatCAMGUI.py:850 flatcamGUI/FlatCAMGUI.py:2534 msgid "&Delete" msgstr "&Șterge" -#: flatcamGUI/FlatCAMGUI.py:799 flatcamGUI/FlatCAMGUI.py:1613 -#: flatcamGUI/FlatCAMGUI.py:1812 flatcamGUI/FlatCAMGUI.py:2383 -#: flatcamTools/ToolDistance.py:30 flatcamTools/ToolDistance.py:160 +#: flatcamGUI/FlatCAMGUI.py:853 flatcamGUI/FlatCAMGUI.py:1714 +#: flatcamGUI/FlatCAMGUI.py:1920 flatcamGUI/FlatCAMGUI.py:2537 +#: flatcamTools/ToolDistance.py:35 flatcamTools/ToolDistance.py:195 msgid "Distance Tool" msgstr "Unealta Distanță" -#: flatcamGUI/FlatCAMGUI.py:801 flatcamGUI/FlatCAMGUI.py:2385 +#: flatcamGUI/FlatCAMGUI.py:855 flatcamGUI/FlatCAMGUI.py:2539 msgid "Distance Min Tool" msgstr "Unealta Distanță min" -#: flatcamGUI/FlatCAMGUI.py:803 flatcamGUI/FlatCAMGUI.py:1606 -#: flatcamGUI/FlatCAMGUI.py:2387 +#: flatcamGUI/FlatCAMGUI.py:857 flatcamGUI/FlatCAMGUI.py:1707 +#: flatcamGUI/FlatCAMGUI.py:2541 msgid "Set Origin" msgstr "Setează Originea" -#: flatcamGUI/FlatCAMGUI.py:805 flatcamGUI/FlatCAMGUI.py:2389 +#: flatcamGUI/FlatCAMGUI.py:859 +msgid "Move to Origin" +msgstr "Deplasează-te la Origine" + +#: flatcamGUI/FlatCAMGUI.py:862 flatcamGUI/FlatCAMGUI.py:2543 msgid "Jump to Location" msgstr "Sari la Locaţie" -#: flatcamGUI/FlatCAMGUI.py:811 flatcamGUI/FlatCAMGUI.py:2393 +#: flatcamGUI/FlatCAMGUI.py:864 flatcamGUI/FlatCAMGUI.py:1719 +#: flatcamGUI/FlatCAMGUI.py:2545 +msgid "Locate in Object" +msgstr "Localizează in Obiect" + +#: flatcamGUI/FlatCAMGUI.py:870 flatcamGUI/FlatCAMGUI.py:2551 msgid "&Replot" msgstr "&Reafișare" -#: flatcamGUI/FlatCAMGUI.py:813 flatcamGUI/FlatCAMGUI.py:2395 +#: flatcamGUI/FlatCAMGUI.py:872 flatcamGUI/FlatCAMGUI.py:2553 msgid "&Clear plot" msgstr "&Șterge Afișare" -#: flatcamGUI/FlatCAMGUI.py:815 flatcamGUI/FlatCAMGUI.py:1609 -#: flatcamGUI/FlatCAMGUI.py:2397 +#: flatcamGUI/FlatCAMGUI.py:874 flatcamGUI/FlatCAMGUI.py:1710 +#: flatcamGUI/FlatCAMGUI.py:2555 msgid "Zoom In" msgstr "Marire" -#: flatcamGUI/FlatCAMGUI.py:817 flatcamGUI/FlatCAMGUI.py:1609 -#: flatcamGUI/FlatCAMGUI.py:2399 +#: flatcamGUI/FlatCAMGUI.py:876 flatcamGUI/FlatCAMGUI.py:1710 +#: flatcamGUI/FlatCAMGUI.py:2557 msgid "Zoom Out" msgstr "Micsorare" -#: flatcamGUI/FlatCAMGUI.py:819 flatcamGUI/FlatCAMGUI.py:1608 -#: flatcamGUI/FlatCAMGUI.py:2062 flatcamGUI/FlatCAMGUI.py:2401 +#: flatcamGUI/FlatCAMGUI.py:878 flatcamGUI/FlatCAMGUI.py:1709 +#: flatcamGUI/FlatCAMGUI.py:2170 flatcamGUI/FlatCAMGUI.py:2559 msgid "Zoom Fit" msgstr "Marire și ajustare" -#: flatcamGUI/FlatCAMGUI.py:827 flatcamGUI/FlatCAMGUI.py:2407 +#: flatcamGUI/FlatCAMGUI.py:886 flatcamGUI/FlatCAMGUI.py:2565 msgid "&Command Line" msgstr "&Linie de comanda" -#: flatcamGUI/FlatCAMGUI.py:839 flatcamGUI/FlatCAMGUI.py:2417 +#: flatcamGUI/FlatCAMGUI.py:898 flatcamGUI/FlatCAMGUI.py:2577 msgid "2Sided Tool" msgstr "Unealta 2-fețe" -#: flatcamGUI/FlatCAMGUI.py:841 flatcamGUI/ObjectUI.py:588 -#: flatcamTools/ToolCutOut.py:436 +#: flatcamGUI/FlatCAMGUI.py:900 flatcamGUI/FlatCAMGUI.py:1725 +#: flatcamGUI/FlatCAMGUI.py:2579 +msgid "Align Objects Tool" +msgstr "Unealta de Aliniere" + +#: flatcamGUI/FlatCAMGUI.py:902 flatcamGUI/FlatCAMGUI.py:1726 +#: flatcamGUI/FlatCAMGUI.py:2581 flatcamTools/ToolExtractDrills.py:393 +msgid "Extract Drills Tool" +msgstr "Unealta de Extragere Găuri" + +#: flatcamGUI/FlatCAMGUI.py:905 flatcamGUI/ObjectUI.py:595 +#: flatcamTools/ToolCutOut.py:447 msgid "Cutout Tool" msgstr "Unealta Decupare" -#: flatcamGUI/FlatCAMGUI.py:843 flatcamGUI/FlatCAMGUI.py:2421 -#: flatcamGUI/ObjectUI.py:566 flatcamGUI/ObjectUI.py:1749 -#: flatcamTools/ToolNonCopperClear.py:632 +#: flatcamGUI/FlatCAMGUI.py:907 flatcamGUI/FlatCAMGUI.py:2586 +#: flatcamGUI/ObjectUI.py:573 flatcamGUI/ObjectUI.py:2075 +#: flatcamTools/ToolNCC.py:972 msgid "NCC Tool" msgstr "Unealta NCC" -#: flatcamGUI/FlatCAMGUI.py:849 flatcamGUI/FlatCAMGUI.py:2427 +#: flatcamGUI/FlatCAMGUI.py:913 flatcamGUI/FlatCAMGUI.py:2592 msgid "Panel Tool" msgstr "Unealta Panel" -#: flatcamGUI/FlatCAMGUI.py:851 flatcamGUI/FlatCAMGUI.py:2429 -#: flatcamTools/ToolFilm.py:578 +#: flatcamGUI/FlatCAMGUI.py:915 flatcamGUI/FlatCAMGUI.py:2594 +#: flatcamTools/ToolFilm.py:586 msgid "Film Tool" msgstr "Unealta Film" -#: flatcamGUI/FlatCAMGUI.py:853 flatcamGUI/FlatCAMGUI.py:2432 -#: flatcamTools/ToolSolderPaste.py:547 +#: flatcamGUI/FlatCAMGUI.py:917 flatcamGUI/FlatCAMGUI.py:2596 +#: flatcamTools/ToolSolderPaste.py:553 msgid "SolderPaste Tool" msgstr "Unealta Dispenser SP" -#: flatcamGUI/FlatCAMGUI.py:855 flatcamGUI/FlatCAMGUI.py:2434 +#: flatcamGUI/FlatCAMGUI.py:919 flatcamGUI/FlatCAMGUI.py:2598 #: flatcamTools/ToolSub.py:35 msgid "Subtract Tool" msgstr "Unealta Scădere" -#: flatcamGUI/FlatCAMGUI.py:857 flatcamTools/ToolRulesCheck.py:607 +#: flatcamGUI/FlatCAMGUI.py:921 flatcamGUI/FlatCAMGUI.py:2600 +#: flatcamTools/ToolRulesCheck.py:616 msgid "Rules Tool" msgstr "Unalta Verif. Reguli" -#: flatcamGUI/FlatCAMGUI.py:859 flatcamGUI/FlatCAMGUI.py:1624 -#: flatcamTools/ToolOptimal.py:34 flatcamTools/ToolOptimal.py:310 +#: flatcamGUI/FlatCAMGUI.py:923 flatcamGUI/FlatCAMGUI.py:1728 +#: flatcamGUI/FlatCAMGUI.py:2602 flatcamTools/ToolOptimal.py:34 +#: flatcamTools/ToolOptimal.py:308 msgid "Optimal Tool" msgstr "Unealta Optim" -#: flatcamGUI/FlatCAMGUI.py:864 flatcamGUI/FlatCAMGUI.py:1622 -#: flatcamGUI/FlatCAMGUI.py:2439 +#: flatcamGUI/FlatCAMGUI.py:928 flatcamGUI/FlatCAMGUI.py:1725 +#: flatcamGUI/FlatCAMGUI.py:2607 msgid "Calculators Tool" msgstr "Unealta Calculatoare" -#: flatcamGUI/FlatCAMGUI.py:868 flatcamGUI/FlatCAMGUI.py:1625 -#: flatcamGUI/FlatCAMGUI.py:2443 flatcamTools/ToolQRCode.py:43 +#: flatcamGUI/FlatCAMGUI.py:932 flatcamGUI/FlatCAMGUI.py:1729 +#: flatcamGUI/FlatCAMGUI.py:2611 flatcamTools/ToolQRCode.py:43 #: flatcamTools/ToolQRCode.py:382 msgid "QRCode Tool" msgstr "Unealta QRCode" -#: flatcamGUI/FlatCAMGUI.py:870 flatcamGUI/FlatCAMGUI.py:2445 -#: flatcamTools/ToolCopperThieving.py:40 flatcamTools/ToolCopperThieving.py:566 +#: flatcamGUI/FlatCAMGUI.py:934 flatcamGUI/FlatCAMGUI.py:2613 +#: flatcamTools/ToolCopperThieving.py:40 flatcamTools/ToolCopperThieving.py:569 msgid "Copper Thieving Tool" msgstr "Unealta Copper Thieving" -#: flatcamGUI/FlatCAMGUI.py:873 flatcamGUI/FlatCAMGUI.py:1622 -#: flatcamGUI/FlatCAMGUI.py:2448 flatcamTools/ToolFiducials.py:33 -#: flatcamTools/ToolFiducials.py:393 +#: flatcamGUI/FlatCAMGUI.py:937 flatcamGUI/FlatCAMGUI.py:1726 +#: flatcamGUI/FlatCAMGUI.py:2616 flatcamTools/ToolFiducials.py:33 +#: flatcamTools/ToolFiducials.py:395 msgid "Fiducials Tool" msgstr "Unealta Fiducials" -#: flatcamGUI/FlatCAMGUI.py:875 flatcamGUI/FlatCAMGUI.py:2450 -#: flatcamTools/ToolCalibration.py:37 flatcamTools/ToolCalibration.py:762 +#: flatcamGUI/FlatCAMGUI.py:939 flatcamGUI/FlatCAMGUI.py:2618 +#: flatcamTools/ToolCalibration.py:37 flatcamTools/ToolCalibration.py:759 msgid "Calibration Tool" msgstr "Unealta Calibrare" -#: flatcamGUI/FlatCAMGUI.py:881 flatcamGUI/FlatCAMGUI.py:907 -#: flatcamGUI/FlatCAMGUI.py:959 flatcamGUI/FlatCAMGUI.py:2454 -#: flatcamGUI/FlatCAMGUI.py:2528 +#: flatcamGUI/FlatCAMGUI.py:941 flatcamGUI/FlatCAMGUI.py:1726 +msgid "Punch Gerber Tool" +msgstr "Unealta Punctare Gerber" + +#: flatcamGUI/FlatCAMGUI.py:943 flatcamTools/ToolInvertGerber.py:31 +msgid "Invert Gerber Tool" +msgstr "Unealta Inversare Gerber" + +#: flatcamGUI/FlatCAMGUI.py:949 flatcamGUI/FlatCAMGUI.py:975 +#: flatcamGUI/FlatCAMGUI.py:1027 flatcamGUI/FlatCAMGUI.py:2624 +#: flatcamGUI/FlatCAMGUI.py:2702 msgid "Select" msgstr "Selectează" -#: flatcamGUI/FlatCAMGUI.py:883 flatcamGUI/FlatCAMGUI.py:2456 +#: flatcamGUI/FlatCAMGUI.py:951 flatcamGUI/FlatCAMGUI.py:2626 msgid "Add Drill Hole" msgstr "Adaugă o Găurire" -#: flatcamGUI/FlatCAMGUI.py:885 flatcamGUI/FlatCAMGUI.py:2458 +#: flatcamGUI/FlatCAMGUI.py:953 flatcamGUI/FlatCAMGUI.py:2628 msgid "Add Drill Hole Array" msgstr "Adaugă o arie de Găuriri" -#: flatcamGUI/FlatCAMGUI.py:887 flatcamGUI/FlatCAMGUI.py:1897 -#: flatcamGUI/FlatCAMGUI.py:2150 flatcamGUI/FlatCAMGUI.py:2462 +#: flatcamGUI/FlatCAMGUI.py:955 flatcamGUI/FlatCAMGUI.py:2005 +#: flatcamGUI/FlatCAMGUI.py:2258 flatcamGUI/FlatCAMGUI.py:2632 msgid "Add Slot" msgstr "Adaugă Slot" -#: flatcamGUI/FlatCAMGUI.py:889 flatcamGUI/FlatCAMGUI.py:1896 -#: flatcamGUI/FlatCAMGUI.py:2152 flatcamGUI/FlatCAMGUI.py:2464 +#: flatcamGUI/FlatCAMGUI.py:957 flatcamGUI/FlatCAMGUI.py:2004 +#: flatcamGUI/FlatCAMGUI.py:2260 flatcamGUI/FlatCAMGUI.py:2634 msgid "Add Slot Array" msgstr "Adaugă o Arie sloturi" -#: flatcamGUI/FlatCAMGUI.py:891 flatcamGUI/FlatCAMGUI.py:2155 -#: flatcamGUI/FlatCAMGUI.py:2460 +#: flatcamGUI/FlatCAMGUI.py:959 flatcamGUI/FlatCAMGUI.py:2263 +#: flatcamGUI/FlatCAMGUI.py:2630 msgid "Resize Drill" msgstr "Redimens. Găurire" -#: flatcamGUI/FlatCAMGUI.py:895 flatcamGUI/FlatCAMGUI.py:2468 +#: flatcamGUI/FlatCAMGUI.py:963 flatcamGUI/FlatCAMGUI.py:2638 msgid "Copy Drill" msgstr "Copiază Găurire" -#: flatcamGUI/FlatCAMGUI.py:897 flatcamGUI/FlatCAMGUI.py:2470 +#: flatcamGUI/FlatCAMGUI.py:965 flatcamGUI/FlatCAMGUI.py:2640 msgid "Delete Drill" msgstr "Șterge Găurire" -#: flatcamGUI/FlatCAMGUI.py:901 flatcamGUI/FlatCAMGUI.py:2474 +#: flatcamGUI/FlatCAMGUI.py:969 flatcamGUI/FlatCAMGUI.py:2644 msgid "Move Drill" msgstr "Muta Găurire" -#: flatcamGUI/FlatCAMGUI.py:909 flatcamGUI/FlatCAMGUI.py:2480 +#: flatcamGUI/FlatCAMGUI.py:977 flatcamGUI/FlatCAMGUI.py:2652 msgid "Add Circle" msgstr "Adaugă Cerc" -#: flatcamGUI/FlatCAMGUI.py:911 flatcamGUI/FlatCAMGUI.py:2482 +#: flatcamGUI/FlatCAMGUI.py:979 flatcamGUI/FlatCAMGUI.py:2654 msgid "Add Arc" msgstr "Adaugă Arc" -#: flatcamGUI/FlatCAMGUI.py:913 flatcamGUI/FlatCAMGUI.py:2484 +#: flatcamGUI/FlatCAMGUI.py:981 flatcamGUI/FlatCAMGUI.py:2656 msgid "Add Rectangle" msgstr "Adaugă Patrulater" -#: flatcamGUI/FlatCAMGUI.py:917 flatcamGUI/FlatCAMGUI.py:2488 +#: flatcamGUI/FlatCAMGUI.py:985 flatcamGUI/FlatCAMGUI.py:2660 msgid "Add Path" msgstr "Adaugă Cale" -#: flatcamGUI/FlatCAMGUI.py:919 flatcamGUI/FlatCAMGUI.py:2490 +#: flatcamGUI/FlatCAMGUI.py:987 flatcamGUI/FlatCAMGUI.py:2662 msgid "Add Polygon" msgstr "Adaugă Poligon" -#: flatcamGUI/FlatCAMGUI.py:922 flatcamGUI/FlatCAMGUI.py:2493 +#: flatcamGUI/FlatCAMGUI.py:990 flatcamGUI/FlatCAMGUI.py:2665 msgid "Add Text" msgstr "Adaugă Text" -#: flatcamGUI/FlatCAMGUI.py:924 flatcamGUI/FlatCAMGUI.py:2495 +#: flatcamGUI/FlatCAMGUI.py:992 flatcamGUI/FlatCAMGUI.py:2667 msgid "Add Buffer" msgstr "Adaugă Bufer" -#: flatcamGUI/FlatCAMGUI.py:926 flatcamGUI/FlatCAMGUI.py:2497 +#: flatcamGUI/FlatCAMGUI.py:994 flatcamGUI/FlatCAMGUI.py:2669 msgid "Paint Shape" msgstr "Paint o forma" -#: flatcamGUI/FlatCAMGUI.py:928 flatcamGUI/FlatCAMGUI.py:985 -#: flatcamGUI/FlatCAMGUI.py:2091 flatcamGUI/FlatCAMGUI.py:2136 -#: flatcamGUI/FlatCAMGUI.py:2499 flatcamGUI/FlatCAMGUI.py:2553 +#: flatcamGUI/FlatCAMGUI.py:996 flatcamGUI/FlatCAMGUI.py:1053 +#: flatcamGUI/FlatCAMGUI.py:2199 flatcamGUI/FlatCAMGUI.py:2244 +#: flatcamGUI/FlatCAMGUI.py:2671 flatcamGUI/FlatCAMGUI.py:2727 msgid "Eraser" msgstr "Stergere Selectivă" -#: flatcamGUI/FlatCAMGUI.py:932 flatcamGUI/FlatCAMGUI.py:2503 +#: flatcamGUI/FlatCAMGUI.py:1000 flatcamGUI/FlatCAMGUI.py:2675 msgid "Polygon Union" msgstr "Uniune Poligoane" -#: flatcamGUI/FlatCAMGUI.py:934 flatcamGUI/FlatCAMGUI.py:2505 +#: flatcamGUI/FlatCAMGUI.py:1002 flatcamGUI/FlatCAMGUI.py:2677 msgid "Polygon Explode" msgstr "Explodare Poligoane" -#: flatcamGUI/FlatCAMGUI.py:937 flatcamGUI/FlatCAMGUI.py:2508 +#: flatcamGUI/FlatCAMGUI.py:1005 flatcamGUI/FlatCAMGUI.py:2680 msgid "Polygon Intersection" msgstr "Intersecţie Poligoane" -#: flatcamGUI/FlatCAMGUI.py:939 flatcamGUI/FlatCAMGUI.py:2510 +#: flatcamGUI/FlatCAMGUI.py:1007 flatcamGUI/FlatCAMGUI.py:2682 msgid "Polygon Subtraction" msgstr "Substracţie Poligoane" -#: flatcamGUI/FlatCAMGUI.py:943 flatcamGUI/FlatCAMGUI.py:2514 +#: flatcamGUI/FlatCAMGUI.py:1011 flatcamGUI/FlatCAMGUI.py:2686 msgid "Cut Path" msgstr "Taie Cale" -#: flatcamGUI/FlatCAMGUI.py:945 +#: flatcamGUI/FlatCAMGUI.py:1013 msgid "Copy Shape(s)" msgstr "Copiază forme geo." -#: flatcamGUI/FlatCAMGUI.py:948 +#: flatcamGUI/FlatCAMGUI.py:1016 msgid "Delete Shape '-'" msgstr "Șterge forme geo" -#: flatcamGUI/FlatCAMGUI.py:950 flatcamGUI/FlatCAMGUI.py:993 -#: flatcamGUI/FlatCAMGUI.py:2103 flatcamGUI/FlatCAMGUI.py:2140 -#: flatcamGUI/FlatCAMGUI.py:2520 flatcamGUI/FlatCAMGUI.py:2561 +#: flatcamGUI/FlatCAMGUI.py:1018 flatcamGUI/FlatCAMGUI.py:1061 +#: flatcamGUI/FlatCAMGUI.py:2211 flatcamGUI/FlatCAMGUI.py:2248 +#: flatcamGUI/FlatCAMGUI.py:2692 flatcamGUI/FlatCAMGUI.py:2735 +#: flatcamGUI/ObjectUI.py:108 msgid "Transformations" msgstr "Transformări" -#: flatcamGUI/FlatCAMGUI.py:953 +#: flatcamGUI/FlatCAMGUI.py:1021 msgid "Move Objects " msgstr "Mută Obiecte " -#: flatcamGUI/FlatCAMGUI.py:961 flatcamGUI/FlatCAMGUI.py:2016 -#: flatcamGUI/FlatCAMGUI.py:2530 +#: flatcamGUI/FlatCAMGUI.py:1029 flatcamGUI/FlatCAMGUI.py:2124 +#: flatcamGUI/FlatCAMGUI.py:2704 msgid "Add Pad" msgstr "Adaugă Pad" -#: flatcamGUI/FlatCAMGUI.py:965 flatcamGUI/FlatCAMGUI.py:2017 -#: flatcamGUI/FlatCAMGUI.py:2534 +#: flatcamGUI/FlatCAMGUI.py:1033 flatcamGUI/FlatCAMGUI.py:2125 +#: flatcamGUI/FlatCAMGUI.py:2708 msgid "Add Track" msgstr "Adaugă Traseu" -#: flatcamGUI/FlatCAMGUI.py:967 flatcamGUI/FlatCAMGUI.py:2016 -#: flatcamGUI/FlatCAMGUI.py:2536 +#: flatcamGUI/FlatCAMGUI.py:1035 flatcamGUI/FlatCAMGUI.py:2124 +#: flatcamGUI/FlatCAMGUI.py:2710 msgid "Add Region" msgstr "Adaugă Regiune" -#: flatcamGUI/FlatCAMGUI.py:969 flatcamGUI/FlatCAMGUI.py:2122 -#: flatcamGUI/FlatCAMGUI.py:2538 +#: flatcamGUI/FlatCAMGUI.py:1037 flatcamGUI/FlatCAMGUI.py:2230 +#: flatcamGUI/FlatCAMGUI.py:2712 msgid "Poligonize" msgstr "Poligonizare" -#: flatcamGUI/FlatCAMGUI.py:972 flatcamGUI/FlatCAMGUI.py:2124 -#: flatcamGUI/FlatCAMGUI.py:2541 +#: flatcamGUI/FlatCAMGUI.py:1040 flatcamGUI/FlatCAMGUI.py:2232 +#: flatcamGUI/FlatCAMGUI.py:2715 msgid "SemiDisc" msgstr "SemiDisc" -#: flatcamGUI/FlatCAMGUI.py:974 flatcamGUI/FlatCAMGUI.py:2126 -#: flatcamGUI/FlatCAMGUI.py:2543 +#: flatcamGUI/FlatCAMGUI.py:1042 flatcamGUI/FlatCAMGUI.py:2234 +#: flatcamGUI/FlatCAMGUI.py:2717 msgid "Disc" msgstr "Disc" -#: flatcamGUI/FlatCAMGUI.py:982 flatcamGUI/FlatCAMGUI.py:2134 -#: flatcamGUI/FlatCAMGUI.py:2551 +#: flatcamGUI/FlatCAMGUI.py:1050 flatcamGUI/FlatCAMGUI.py:2242 +#: flatcamGUI/FlatCAMGUI.py:2725 msgid "Mark Area" msgstr "Marc. aria" -#: flatcamGUI/FlatCAMGUI.py:996 flatcamGUI/FlatCAMGUI.py:2016 -#: flatcamGUI/FlatCAMGUI.py:2107 flatcamGUI/FlatCAMGUI.py:2170 -#: flatcamGUI/FlatCAMGUI.py:2564 flatcamTools/ToolMove.py:28 +#: flatcamGUI/FlatCAMGUI.py:1064 flatcamGUI/FlatCAMGUI.py:2124 +#: flatcamGUI/FlatCAMGUI.py:2215 flatcamGUI/FlatCAMGUI.py:2278 +#: flatcamGUI/FlatCAMGUI.py:2738 flatcamTools/ToolMove.py:28 msgid "Move" msgstr "Mutare" -#: flatcamGUI/FlatCAMGUI.py:1004 flatcamGUI/FlatCAMGUI.py:2571 +#: flatcamGUI/FlatCAMGUI.py:1072 flatcamGUI/FlatCAMGUI.py:2747 msgid "Snap to grid" msgstr "Lipire la grid" -#: flatcamGUI/FlatCAMGUI.py:1007 flatcamGUI/FlatCAMGUI.py:2574 +#: flatcamGUI/FlatCAMGUI.py:1075 flatcamGUI/FlatCAMGUI.py:2750 msgid "Grid X snapping distance" msgstr "Distanta de lipire la grid pe axa X" -#: flatcamGUI/FlatCAMGUI.py:1012 flatcamGUI/FlatCAMGUI.py:2579 +#: flatcamGUI/FlatCAMGUI.py:1080 flatcamGUI/FlatCAMGUI.py:2755 msgid "Grid Y snapping distance" msgstr "Distanta de lipire la grid pe axa Y" -#: flatcamGUI/FlatCAMGUI.py:1018 flatcamGUI/FlatCAMGUI.py:2585 +#: flatcamGUI/FlatCAMGUI.py:1086 flatcamGUI/FlatCAMGUI.py:2761 msgid "" "When active, value on Grid_X\n" "is copied to the Grid_Y value." @@ -6308,63 +6645,64 @@ msgstr "" "Când este activ, valoarea de pe Grid_X\n" "este copiata și in Grid_Y." -#: flatcamGUI/FlatCAMGUI.py:1025 flatcamGUI/FlatCAMGUI.py:2592 +#: flatcamGUI/FlatCAMGUI.py:1093 flatcamGUI/FlatCAMGUI.py:2768 msgid "Snap to corner" msgstr "Lipire la colt" -#: flatcamGUI/FlatCAMGUI.py:1029 flatcamGUI/FlatCAMGUI.py:2596 -#: flatcamGUI/PreferencesUI.py:984 +#: flatcamGUI/FlatCAMGUI.py:1097 flatcamGUI/FlatCAMGUI.py:2772 +#: flatcamGUI/PreferencesUI.py:1159 msgid "Max. magnet distance" msgstr "Distanta magnetica maxima" -#: flatcamGUI/FlatCAMGUI.py:1063 +#: flatcamGUI/FlatCAMGUI.py:1134 msgid "Selected" msgstr "Selectat" -#: flatcamGUI/FlatCAMGUI.py:1090 flatcamGUI/FlatCAMGUI.py:1098 +#: flatcamGUI/FlatCAMGUI.py:1162 flatcamGUI/FlatCAMGUI.py:1170 msgid "Plot Area" msgstr "Arie Afișare" -#: flatcamGUI/FlatCAMGUI.py:1125 +#: flatcamGUI/FlatCAMGUI.py:1197 msgid "General" msgstr "General" -#: flatcamGUI/FlatCAMGUI.py:1140 flatcamTools/ToolCopperThieving.py:74 -#: flatcamTools/ToolDblSided.py:59 flatcamTools/ToolOptimal.py:71 -#: flatcamTools/ToolQRCode.py:77 +#: flatcamGUI/FlatCAMGUI.py:1212 flatcamTools/ToolCopperThieving.py:75 +#: flatcamTools/ToolDblSided.py:65 flatcamTools/ToolExtractDrills.py:61 +#: flatcamTools/ToolInvertGerber.py:72 flatcamTools/ToolOptimal.py:72 +#: flatcamTools/ToolPunchGerber.py:64 msgid "GERBER" msgstr "GERBER" -#: flatcamGUI/FlatCAMGUI.py:1150 flatcamTools/ToolDblSided.py:87 +#: flatcamGUI/FlatCAMGUI.py:1222 flatcamTools/ToolDblSided.py:93 msgid "EXCELLON" msgstr "EXCELLON" -#: flatcamGUI/FlatCAMGUI.py:1160 flatcamTools/ToolDblSided.py:115 +#: flatcamGUI/FlatCAMGUI.py:1232 flatcamTools/ToolDblSided.py:121 msgid "GEOMETRY" msgstr "GEOMETRIE" -#: flatcamGUI/FlatCAMGUI.py:1170 +#: flatcamGUI/FlatCAMGUI.py:1242 msgid "CNC-JOB" msgstr "CNCJob" -#: flatcamGUI/FlatCAMGUI.py:1179 flatcamGUI/ObjectUI.py:555 -#: flatcamGUI/ObjectUI.py:1724 +#: flatcamGUI/FlatCAMGUI.py:1251 flatcamGUI/ObjectUI.py:562 +#: flatcamGUI/ObjectUI.py:2050 msgid "TOOLS" msgstr "Unelte" -#: flatcamGUI/FlatCAMGUI.py:1188 +#: flatcamGUI/FlatCAMGUI.py:1260 msgid "TOOLS 2" msgstr "UNELTE 2" -#: flatcamGUI/FlatCAMGUI.py:1198 +#: flatcamGUI/FlatCAMGUI.py:1270 msgid "UTILITIES" msgstr "UTILITARE" -#: flatcamGUI/FlatCAMGUI.py:1215 flatcamGUI/PreferencesUI.py:2833 +#: flatcamGUI/FlatCAMGUI.py:1287 flatcamGUI/PreferencesUI.py:3015 msgid "Restore Defaults" msgstr "Restabiliți setările de bază" -#: flatcamGUI/FlatCAMGUI.py:1218 +#: flatcamGUI/FlatCAMGUI.py:1290 msgid "" "Restore the entire set of default values\n" "to the initial values loaded after first launch." @@ -6372,15 +6710,19 @@ msgstr "" "Restaurați întregul set de valori implicite\n" "la valorile inițiale încărcate după prima lansare." -#: flatcamGUI/FlatCAMGUI.py:1223 +#: flatcamGUI/FlatCAMGUI.py:1295 msgid "Open Pref Folder" msgstr "Deschide Pref Dir" -#: flatcamGUI/FlatCAMGUI.py:1226 +#: flatcamGUI/FlatCAMGUI.py:1298 msgid "Open the folder where FlatCAM save the preferences files." msgstr "Deschide directorul unde FlatCAM salvează fişierele cu setări." -#: flatcamGUI/FlatCAMGUI.py:1234 +#: flatcamGUI/FlatCAMGUI.py:1302 flatcamGUI/FlatCAMGUI.py:2477 +msgid "Clear GUI Settings" +msgstr "Șterge Setările GUI" + +#: flatcamGUI/FlatCAMGUI.py:1306 msgid "" "Clear the GUI settings for FlatCAM,\n" "such as: layout, gui state, style, hdpi support etc." @@ -6388,15 +6730,15 @@ msgstr "" "Șterge setările GUI pentru FlatCAM,\n" "cum ar fi: amplasare, stare UI, suport HDPI sau traducerea." -#: flatcamGUI/FlatCAMGUI.py:1245 +#: flatcamGUI/FlatCAMGUI.py:1317 msgid "Apply" msgstr "Aplicați" -#: flatcamGUI/FlatCAMGUI.py:1248 +#: flatcamGUI/FlatCAMGUI.py:1320 msgid "Apply the current preferences without saving to a file." msgstr "Aplicați preferințele actuale fără a salva într-un fișier." -#: flatcamGUI/FlatCAMGUI.py:1255 +#: flatcamGUI/FlatCAMGUI.py:1327 msgid "" "Save the current settings in the 'current_defaults' file\n" "which is the file storing the working default preferences." @@ -6404,532 +6746,545 @@ msgstr "" "Salvează setările curente in fişierul numit: 'current_defaults'\n" "fişier care este cel unde se salvează preferințele cu care se va lucra." -#: flatcamGUI/FlatCAMGUI.py:1263 +#: flatcamGUI/FlatCAMGUI.py:1335 msgid "Will not save the changes and will close the preferences window." msgstr "Nu va salva modificările și va închide fereastra de preferințe." -#: flatcamGUI/FlatCAMGUI.py:1603 +#: flatcamGUI/FlatCAMGUI.py:1704 msgid "SHOW SHORTCUT LIST" msgstr "ARATA LISTA DE TASTE SHORTCUT" -#: flatcamGUI/FlatCAMGUI.py:1603 +#: flatcamGUI/FlatCAMGUI.py:1704 msgid "Switch to Project Tab" msgstr "Treci la Tab-ul Proiect" -#: flatcamGUI/FlatCAMGUI.py:1603 +#: flatcamGUI/FlatCAMGUI.py:1704 msgid "Switch to Selected Tab" msgstr "Treci la Tab-ul Selectat" -#: flatcamGUI/FlatCAMGUI.py:1604 +#: flatcamGUI/FlatCAMGUI.py:1705 msgid "Switch to Tool Tab" msgstr "Treci la Tab-ul 'Unealta'" -#: flatcamGUI/FlatCAMGUI.py:1605 +#: flatcamGUI/FlatCAMGUI.py:1706 msgid "New Gerber" msgstr "Gerber Nou" -#: flatcamGUI/FlatCAMGUI.py:1605 +#: flatcamGUI/FlatCAMGUI.py:1706 msgid "Edit Object (if selected)" msgstr "Editeaza obiectul (daca este selectat)" -#: flatcamGUI/FlatCAMGUI.py:1605 +#: flatcamGUI/FlatCAMGUI.py:1706 msgid "Jump to Coordinates" msgstr "Sari la Coordonatele" -#: flatcamGUI/FlatCAMGUI.py:1606 +#: flatcamGUI/FlatCAMGUI.py:1707 msgid "New Excellon" msgstr "Excellon nou" -#: flatcamGUI/FlatCAMGUI.py:1606 +#: flatcamGUI/FlatCAMGUI.py:1707 msgid "Move Obj" msgstr "Mută Obiecte" -#: flatcamGUI/FlatCAMGUI.py:1606 +#: flatcamGUI/FlatCAMGUI.py:1707 msgid "New Geometry" msgstr "Geometrie Noua" -#: flatcamGUI/FlatCAMGUI.py:1606 +#: flatcamGUI/FlatCAMGUI.py:1707 msgid "Change Units" msgstr "Comută Unitati" -#: flatcamGUI/FlatCAMGUI.py:1607 +#: flatcamGUI/FlatCAMGUI.py:1708 msgid "Open Properties Tool" msgstr "Deschide Unealta Proprietati" -#: flatcamGUI/FlatCAMGUI.py:1607 +#: flatcamGUI/FlatCAMGUI.py:1708 msgid "Rotate by 90 degree CW" msgstr "Roteste cu 90 grade CW" -#: flatcamGUI/FlatCAMGUI.py:1607 +#: flatcamGUI/FlatCAMGUI.py:1708 msgid "Shell Toggle" msgstr "Comuta Linie de comanda" -#: flatcamGUI/FlatCAMGUI.py:1608 +#: flatcamGUI/FlatCAMGUI.py:1709 msgid "" "Add a Tool (when in Geometry Selected Tab or in Tools NCC or Tools Paint)" msgstr "" "Adaugă o Unealtă (cand ne aflam in tab-ul Selected al Geometriei sau in " "Unealta NCC sau in unealta Paint)" -#: flatcamGUI/FlatCAMGUI.py:1609 +#: flatcamGUI/FlatCAMGUI.py:1710 msgid "Flip on X_axis" msgstr "Oglindește pe axa X" -#: flatcamGUI/FlatCAMGUI.py:1609 +#: flatcamGUI/FlatCAMGUI.py:1710 msgid "Flip on Y_axis" msgstr "Oglindește pe axa Y" -#: flatcamGUI/FlatCAMGUI.py:1612 +#: flatcamGUI/FlatCAMGUI.py:1713 msgid "Copy Obj" msgstr "Copiază Obiecte" -#: flatcamGUI/FlatCAMGUI.py:1612 +#: flatcamGUI/FlatCAMGUI.py:1713 msgid "Open Tools Database" msgstr "Deschide baza de date Unelte" -#: flatcamGUI/FlatCAMGUI.py:1613 +#: flatcamGUI/FlatCAMGUI.py:1714 msgid "Open Excellon File" msgstr "Încarcă un fisier Excellon" -#: flatcamGUI/FlatCAMGUI.py:1613 +#: flatcamGUI/FlatCAMGUI.py:1714 msgid "Open Gerber File" msgstr "Încarcă un fisier Gerber" -#: flatcamGUI/FlatCAMGUI.py:1613 +#: flatcamGUI/FlatCAMGUI.py:1714 msgid "New Project" msgstr "Un Nou Project" -#: flatcamGUI/FlatCAMGUI.py:1614 flatcamTools/ToolPDF.py:42 +#: flatcamGUI/FlatCAMGUI.py:1715 flatcamTools/ToolPDF.py:42 msgid "PDF Import Tool" msgstr "Unealta import PDF" -#: flatcamGUI/FlatCAMGUI.py:1614 -msgid "Save Project As" -msgstr "Salvează Proiectul ca" +#: flatcamGUI/FlatCAMGUI.py:1715 +msgid "Save Project" +msgstr "Salvează Proiectul" -#: flatcamGUI/FlatCAMGUI.py:1614 +#: flatcamGUI/FlatCAMGUI.py:1715 msgid "Toggle Plot Area" msgstr "Comută Aria de Afișare" -#: flatcamGUI/FlatCAMGUI.py:1617 +#: flatcamGUI/FlatCAMGUI.py:1718 msgid "Copy Obj_Name" msgstr "Copiază Nume Obiect" -#: flatcamGUI/FlatCAMGUI.py:1618 +#: flatcamGUI/FlatCAMGUI.py:1719 msgid "Toggle Code Editor" msgstr "Comută Editorul de cod" -#: flatcamGUI/FlatCAMGUI.py:1618 +#: flatcamGUI/FlatCAMGUI.py:1719 msgid "Toggle the axis" msgstr "Comută Reprezentare Axe" -#: flatcamGUI/FlatCAMGUI.py:1618 flatcamGUI/FlatCAMGUI.py:1810 -#: flatcamGUI/FlatCAMGUI.py:1897 flatcamGUI/FlatCAMGUI.py:2019 +#: flatcamGUI/FlatCAMGUI.py:1719 flatcamGUI/FlatCAMGUI.py:1918 +#: flatcamGUI/FlatCAMGUI.py:2005 flatcamGUI/FlatCAMGUI.py:2127 msgid "Distance Minimum Tool" msgstr "Unealta Distanță minimă" -#: flatcamGUI/FlatCAMGUI.py:1618 +#: flatcamGUI/FlatCAMGUI.py:1720 msgid "Open Preferences Window" msgstr "Deschide Preferințe" -#: flatcamGUI/FlatCAMGUI.py:1619 +#: flatcamGUI/FlatCAMGUI.py:1721 msgid "Rotate by 90 degree CCW" msgstr "Roteste cu 90 grade CCW" -#: flatcamGUI/FlatCAMGUI.py:1619 +#: flatcamGUI/FlatCAMGUI.py:1721 msgid "Run a Script" msgstr "Rulează TCL script" -#: flatcamGUI/FlatCAMGUI.py:1619 +#: flatcamGUI/FlatCAMGUI.py:1721 msgid "Toggle the workspace" msgstr "Comută Suprafata de lucru" -#: flatcamGUI/FlatCAMGUI.py:1619 +#: flatcamGUI/FlatCAMGUI.py:1721 msgid "Skew on X axis" msgstr "Deformare pe axa X" -#: flatcamGUI/FlatCAMGUI.py:1620 +#: flatcamGUI/FlatCAMGUI.py:1722 msgid "Skew on Y axis" msgstr "Deformare pe axa Y" -#: flatcamGUI/FlatCAMGUI.py:1622 +#: flatcamGUI/FlatCAMGUI.py:1725 msgid "2-Sided PCB Tool" msgstr "Unealta 2-fețe" -#: flatcamGUI/FlatCAMGUI.py:1622 +#: flatcamGUI/FlatCAMGUI.py:1725 msgid "Transformations Tool" msgstr "Unealta Transformări" -#: flatcamGUI/FlatCAMGUI.py:1623 +#: flatcamGUI/FlatCAMGUI.py:1727 msgid "Solder Paste Dispensing Tool" msgstr "Unealta DispensorPF" -#: flatcamGUI/FlatCAMGUI.py:1624 +#: flatcamGUI/FlatCAMGUI.py:1728 msgid "Film PCB Tool" msgstr "Unealta Film" -#: flatcamGUI/FlatCAMGUI.py:1624 +#: flatcamGUI/FlatCAMGUI.py:1728 msgid "Non-Copper Clearing Tool" msgstr "Curățăre Non-Cupru" -#: flatcamGUI/FlatCAMGUI.py:1625 +#: flatcamGUI/FlatCAMGUI.py:1729 msgid "Paint Area Tool" msgstr "Unealta Paint" -#: flatcamGUI/FlatCAMGUI.py:1625 +#: flatcamGUI/FlatCAMGUI.py:1729 msgid "Rules Check Tool" msgstr "Unealta Verificari Reguli" -#: flatcamGUI/FlatCAMGUI.py:1626 +#: flatcamGUI/FlatCAMGUI.py:1730 msgid "View File Source" msgstr "Vizualiz. Cod Sursă" -#: flatcamGUI/FlatCAMGUI.py:1627 +#: flatcamGUI/FlatCAMGUI.py:1731 msgid "Cutout PCB Tool" msgstr "Unealta Decupare" -#: flatcamGUI/FlatCAMGUI.py:1627 +#: flatcamGUI/FlatCAMGUI.py:1731 msgid "Enable all Plots" msgstr "Activează Afișare pt Tot" -#: flatcamGUI/FlatCAMGUI.py:1627 +#: flatcamGUI/FlatCAMGUI.py:1731 msgid "Disable all Plots" msgstr "Dezactivează Afișare pt Tot" -#: flatcamGUI/FlatCAMGUI.py:1627 +#: flatcamGUI/FlatCAMGUI.py:1731 msgid "Disable Non-selected Plots" msgstr "Dezactivează ne-selectate" -#: flatcamGUI/FlatCAMGUI.py:1628 +#: flatcamGUI/FlatCAMGUI.py:1732 msgid "Toggle Full Screen" msgstr "Comută FullScreen" -#: flatcamGUI/FlatCAMGUI.py:1631 +#: flatcamGUI/FlatCAMGUI.py:1735 msgid "Abort current task (gracefully)" msgstr "Renutna la task" -#: flatcamGUI/FlatCAMGUI.py:1634 +#: flatcamGUI/FlatCAMGUI.py:1738 +msgid "Save Project As" +msgstr "Salvează Proiectul ca" + +#: flatcamGUI/FlatCAMGUI.py:1739 +msgid "" +"Paste Special. Will convert a Windows path style to the one required in Tcl " +"Shell" +msgstr "" +"Lipire specială. Va converti stilul de adresa cale Windows in cel necesar in " +"Tcl Shell" + +#: flatcamGUI/FlatCAMGUI.py:1742 msgid "Open Online Manual" msgstr "Deschide Manualul Online" -#: flatcamGUI/FlatCAMGUI.py:1635 +#: flatcamGUI/FlatCAMGUI.py:1743 msgid "Open Online Tutorials" msgstr "Deschide Tutoriale Online" -#: flatcamGUI/FlatCAMGUI.py:1635 +#: flatcamGUI/FlatCAMGUI.py:1743 msgid "Refresh Plots" msgstr "Improspatare Afișare" -#: flatcamGUI/FlatCAMGUI.py:1635 flatcamTools/ToolSolderPaste.py:503 +#: flatcamGUI/FlatCAMGUI.py:1743 flatcamTools/ToolSolderPaste.py:509 msgid "Delete Object" msgstr "Șterge Obiectul" -#: flatcamGUI/FlatCAMGUI.py:1635 +#: flatcamGUI/FlatCAMGUI.py:1743 msgid "Alternate: Delete Tool" msgstr "Alternativ: Șterge Unealta" -#: flatcamGUI/FlatCAMGUI.py:1636 +#: flatcamGUI/FlatCAMGUI.py:1744 msgid "(left to Key_1)Toogle Notebook Area (Left Side)" msgstr "(in stanga tasta 1) Comuta aria Notebook (partea stanga)" -#: flatcamGUI/FlatCAMGUI.py:1636 +#: flatcamGUI/FlatCAMGUI.py:1744 msgid "En(Dis)able Obj Plot" msgstr "(Dez)activează Afișare" -#: flatcamGUI/FlatCAMGUI.py:1637 +#: flatcamGUI/FlatCAMGUI.py:1745 msgid "Deselects all objects" msgstr "Deselectează toate obiectele" -#: flatcamGUI/FlatCAMGUI.py:1651 +#: flatcamGUI/FlatCAMGUI.py:1759 msgid "Editor Shortcut list" msgstr "Lista de shortcut-uri" -#: flatcamGUI/FlatCAMGUI.py:1805 +#: flatcamGUI/FlatCAMGUI.py:1913 msgid "GEOMETRY EDITOR" msgstr "EDITOR GEOMETRIE" -#: flatcamGUI/FlatCAMGUI.py:1805 +#: flatcamGUI/FlatCAMGUI.py:1913 msgid "Draw an Arc" msgstr "Deseneaza un Arc" -#: flatcamGUI/FlatCAMGUI.py:1805 +#: flatcamGUI/FlatCAMGUI.py:1913 msgid "Copy Geo Item" msgstr "Copiază Geo" -#: flatcamGUI/FlatCAMGUI.py:1806 +#: flatcamGUI/FlatCAMGUI.py:1914 msgid "Within Add Arc will toogle the ARC direction: CW or CCW" msgstr "In cadrul 'Aadauga Arc' va comuta intre directiile arcului: CW sau CCW" -#: flatcamGUI/FlatCAMGUI.py:1806 +#: flatcamGUI/FlatCAMGUI.py:1914 msgid "Polygon Intersection Tool" msgstr "Unealta Intersecţie Poligoane" -#: flatcamGUI/FlatCAMGUI.py:1807 +#: flatcamGUI/FlatCAMGUI.py:1915 msgid "Geo Paint Tool" msgstr "Unealta Paint Geo" -#: flatcamGUI/FlatCAMGUI.py:1807 flatcamGUI/FlatCAMGUI.py:1896 -#: flatcamGUI/FlatCAMGUI.py:2016 +#: flatcamGUI/FlatCAMGUI.py:1915 flatcamGUI/FlatCAMGUI.py:2004 +#: flatcamGUI/FlatCAMGUI.py:2124 msgid "Jump to Location (x, y)" msgstr "Sari la Locaţia (x, y)" -#: flatcamGUI/FlatCAMGUI.py:1807 +#: flatcamGUI/FlatCAMGUI.py:1915 msgid "Toggle Corner Snap" msgstr "Comută lipire colt" -#: flatcamGUI/FlatCAMGUI.py:1807 +#: flatcamGUI/FlatCAMGUI.py:1915 msgid "Move Geo Item" msgstr "Muta El. Geo" -#: flatcamGUI/FlatCAMGUI.py:1808 +#: flatcamGUI/FlatCAMGUI.py:1916 msgid "Within Add Arc will cycle through the ARC modes" msgstr "In cadrul 'Adauga Arc' va trece circular prin tipurile de Arc" -#: flatcamGUI/FlatCAMGUI.py:1808 +#: flatcamGUI/FlatCAMGUI.py:1916 msgid "Draw a Polygon" msgstr "Deseneaza un Poligon" -#: flatcamGUI/FlatCAMGUI.py:1808 +#: flatcamGUI/FlatCAMGUI.py:1916 msgid "Draw a Circle" msgstr "Deseneaza un Cerc" -#: flatcamGUI/FlatCAMGUI.py:1809 +#: flatcamGUI/FlatCAMGUI.py:1917 msgid "Draw a Path" msgstr "Deseneaza un Traseu" -#: flatcamGUI/FlatCAMGUI.py:1809 +#: flatcamGUI/FlatCAMGUI.py:1917 msgid "Draw Rectangle" msgstr "Deseneaza un Patrulater" -#: flatcamGUI/FlatCAMGUI.py:1809 +#: flatcamGUI/FlatCAMGUI.py:1917 msgid "Polygon Subtraction Tool" msgstr "Unealta Substracţie Poligoane" -#: flatcamGUI/FlatCAMGUI.py:1809 +#: flatcamGUI/FlatCAMGUI.py:1917 msgid "Add Text Tool" msgstr "Unealta Adaugare Text" -#: flatcamGUI/FlatCAMGUI.py:1810 +#: flatcamGUI/FlatCAMGUI.py:1918 msgid "Polygon Union Tool" msgstr "Unealta Uniune Poligoane" -#: flatcamGUI/FlatCAMGUI.py:1810 +#: flatcamGUI/FlatCAMGUI.py:1918 msgid "Flip shape on X axis" msgstr "Oglindește pe axa X" -#: flatcamGUI/FlatCAMGUI.py:1810 +#: flatcamGUI/FlatCAMGUI.py:1918 msgid "Flip shape on Y axis" msgstr "Oglindește pe axa Y" -#: flatcamGUI/FlatCAMGUI.py:1811 +#: flatcamGUI/FlatCAMGUI.py:1919 msgid "Skew shape on X axis" msgstr "Deformare pe axa X" -#: flatcamGUI/FlatCAMGUI.py:1811 +#: flatcamGUI/FlatCAMGUI.py:1919 msgid "Skew shape on Y axis" msgstr "Deformare pe axa Y" -#: flatcamGUI/FlatCAMGUI.py:1811 +#: flatcamGUI/FlatCAMGUI.py:1919 msgid "Editor Transformation Tool" msgstr "Unealta Transformare in Editor" -#: flatcamGUI/FlatCAMGUI.py:1812 +#: flatcamGUI/FlatCAMGUI.py:1920 msgid "Offset shape on X axis" msgstr "Ofset pe axa X" -#: flatcamGUI/FlatCAMGUI.py:1812 +#: flatcamGUI/FlatCAMGUI.py:1920 msgid "Offset shape on Y axis" msgstr "Ofset pe axa Y" -#: flatcamGUI/FlatCAMGUI.py:1813 flatcamGUI/FlatCAMGUI.py:1899 -#: flatcamGUI/FlatCAMGUI.py:2021 +#: flatcamGUI/FlatCAMGUI.py:1921 flatcamGUI/FlatCAMGUI.py:2007 +#: flatcamGUI/FlatCAMGUI.py:2129 msgid "Save Object and Exit Editor" msgstr "Salvează Obiectul și inchide Editorul" -#: flatcamGUI/FlatCAMGUI.py:1813 +#: flatcamGUI/FlatCAMGUI.py:1921 msgid "Polygon Cut Tool" msgstr "Unealta Taiere Poligoane" -#: flatcamGUI/FlatCAMGUI.py:1814 +#: flatcamGUI/FlatCAMGUI.py:1922 msgid "Rotate Geometry" msgstr "Roteste Geometrie" -#: flatcamGUI/FlatCAMGUI.py:1814 +#: flatcamGUI/FlatCAMGUI.py:1922 msgid "Finish drawing for certain tools" msgstr "Termina de desenat (pt anumite unelte)" -#: flatcamGUI/FlatCAMGUI.py:1814 flatcamGUI/FlatCAMGUI.py:1899 -#: flatcamGUI/FlatCAMGUI.py:2019 +#: flatcamGUI/FlatCAMGUI.py:1922 flatcamGUI/FlatCAMGUI.py:2007 +#: flatcamGUI/FlatCAMGUI.py:2127 msgid "Abort and return to Select" msgstr "Renutna si intoarce-te la Selectie" -#: flatcamGUI/FlatCAMGUI.py:1815 flatcamGUI/FlatCAMGUI.py:2518 +#: flatcamGUI/FlatCAMGUI.py:1923 flatcamGUI/FlatCAMGUI.py:2690 msgid "Delete Shape" msgstr "Șterge forme geo" -#: flatcamGUI/FlatCAMGUI.py:1895 +#: flatcamGUI/FlatCAMGUI.py:2003 msgid "EXCELLON EDITOR" msgstr "EDITOR EXCELLON" -#: flatcamGUI/FlatCAMGUI.py:1895 +#: flatcamGUI/FlatCAMGUI.py:2003 msgid "Copy Drill(s)" msgstr "Copiaza Găurire" -#: flatcamGUI/FlatCAMGUI.py:1895 flatcamGUI/FlatCAMGUI.py:2145 +#: flatcamGUI/FlatCAMGUI.py:2003 flatcamGUI/FlatCAMGUI.py:2253 msgid "Add Drill" msgstr "Adaugă găurire" -#: flatcamGUI/FlatCAMGUI.py:1896 +#: flatcamGUI/FlatCAMGUI.py:2004 msgid "Move Drill(s)" msgstr "Muta Găuri" -#: flatcamGUI/FlatCAMGUI.py:1897 +#: flatcamGUI/FlatCAMGUI.py:2005 msgid "Add a new Tool" msgstr "Adaugă Unealta Noua" -#: flatcamGUI/FlatCAMGUI.py:1898 +#: flatcamGUI/FlatCAMGUI.py:2006 msgid "Delete Drill(s)" msgstr "Șterge Găuri" -#: flatcamGUI/FlatCAMGUI.py:1898 +#: flatcamGUI/FlatCAMGUI.py:2006 msgid "Alternate: Delete Tool(s)" msgstr "Alternativ: Șterge Unealta" -#: flatcamGUI/FlatCAMGUI.py:2015 +#: flatcamGUI/FlatCAMGUI.py:2123 msgid "GERBER EDITOR" msgstr "EDITOR GERBER" -#: flatcamGUI/FlatCAMGUI.py:2015 +#: flatcamGUI/FlatCAMGUI.py:2123 msgid "Add Disc" msgstr "Adaugă Disc" -#: flatcamGUI/FlatCAMGUI.py:2015 +#: flatcamGUI/FlatCAMGUI.py:2123 msgid "Add SemiDisc" msgstr "Adaugă SemiDisc" -#: flatcamGUI/FlatCAMGUI.py:2017 +#: flatcamGUI/FlatCAMGUI.py:2125 msgid "Within Track & Region Tools will cycle in REVERSE the bend modes" msgstr "" "In cadrul uneltelor Traseu si Regiune va trece circular in Revers prin " "modurile de indoire" -#: flatcamGUI/FlatCAMGUI.py:2018 +#: flatcamGUI/FlatCAMGUI.py:2126 msgid "Within Track & Region Tools will cycle FORWARD the bend modes" msgstr "" "In cadrul uneltelor Traseu si Regiune va trece circular in Avans prin " "modurile de indoire" -#: flatcamGUI/FlatCAMGUI.py:2019 +#: flatcamGUI/FlatCAMGUI.py:2127 msgid "Alternate: Delete Apertures" msgstr "Alternativ: Șterge Apertură" -#: flatcamGUI/FlatCAMGUI.py:2020 +#: flatcamGUI/FlatCAMGUI.py:2128 msgid "Eraser Tool" msgstr "Unealta Stergere" -#: flatcamGUI/FlatCAMGUI.py:2021 flatcamGUI/PreferencesUI.py:2634 +#: flatcamGUI/FlatCAMGUI.py:2129 flatcamGUI/PreferencesUI.py:2816 msgid "Mark Area Tool" msgstr "Unealta de Marc. Arie" -#: flatcamGUI/FlatCAMGUI.py:2021 +#: flatcamGUI/FlatCAMGUI.py:2129 msgid "Poligonize Tool" msgstr "Unealta Poligonizare" -#: flatcamGUI/FlatCAMGUI.py:2021 +#: flatcamGUI/FlatCAMGUI.py:2129 msgid "Transformation Tool" msgstr "Unealta Transformare" -#: flatcamGUI/FlatCAMGUI.py:2038 +#: flatcamGUI/FlatCAMGUI.py:2146 msgid "Toggle Visibility" msgstr "Comută Vizibilitate" -#: flatcamGUI/FlatCAMGUI.py:2044 +#: flatcamGUI/FlatCAMGUI.py:2152 msgid "New" msgstr "Nou" -#: flatcamGUI/FlatCAMGUI.py:2046 flatcamTools/ToolCalibration.py:634 -msgid "Geometry" -msgstr "Geometrie" - -#: flatcamGUI/FlatCAMGUI.py:2050 flatcamTools/ToolCalibration.py:197 -#: flatcamTools/ToolCalibration.py:634 flatcamTools/ToolFilm.py:359 +#: flatcamGUI/FlatCAMGUI.py:2158 flatcamGUI/PreferencesUI.py:8410 +#: flatcamTools/ToolAlignObjects.py:74 flatcamTools/ToolAlignObjects.py:110 +#: flatcamTools/ToolCalibration.py:197 flatcamTools/ToolCalibration.py:631 +#: flatcamTools/ToolCalibration.py:648 flatcamTools/ToolCalibration.py:807 +#: flatcamTools/ToolCalibration.py:815 flatcamTools/ToolCopperThieving.py:145 +#: flatcamTools/ToolCopperThieving.py:159 +#: flatcamTools/ToolCopperThieving.py:605 flatcamTools/ToolDblSided.py:226 +#: flatcamTools/ToolFilm.py:359 flatcamTools/ToolNCC.py:558 +#: flatcamTools/ToolNCC.py:1293 flatcamTools/ToolPaint.py:502 +#: flatcamTools/ToolPaint.py:703 flatcamTools/ToolPanelize.py:374 +#: flatcamTools/ToolPunchGerber.py:149 flatcamTools/ToolPunchGerber.py:164 msgid "Excellon" msgstr "Excellon" -#: flatcamGUI/FlatCAMGUI.py:2057 +#: flatcamGUI/FlatCAMGUI.py:2165 msgid "Grids" msgstr "Grid-uri" -#: flatcamGUI/FlatCAMGUI.py:2064 +#: flatcamGUI/FlatCAMGUI.py:2172 msgid "Clear Plot" msgstr "Șterge Afișare" -#: flatcamGUI/FlatCAMGUI.py:2066 +#: flatcamGUI/FlatCAMGUI.py:2174 msgid "Replot" msgstr "Reafișare" -#: flatcamGUI/FlatCAMGUI.py:2070 +#: flatcamGUI/FlatCAMGUI.py:2178 msgid "Geo Editor" msgstr "Editor Geometrii" -#: flatcamGUI/FlatCAMGUI.py:2072 +#: flatcamGUI/FlatCAMGUI.py:2180 msgid "Path" msgstr "Pe cale" -#: flatcamGUI/FlatCAMGUI.py:2074 +#: flatcamGUI/FlatCAMGUI.py:2182 msgid "Rectangle" msgstr "Patrulater" -#: flatcamGUI/FlatCAMGUI.py:2077 +#: flatcamGUI/FlatCAMGUI.py:2185 msgid "Circle" msgstr "Cerc" -#: flatcamGUI/FlatCAMGUI.py:2079 -msgid "Polygon" -msgstr "Poligon" - -#: flatcamGUI/FlatCAMGUI.py:2081 +#: flatcamGUI/FlatCAMGUI.py:2189 msgid "Arc" msgstr "Arc" -#: flatcamGUI/FlatCAMGUI.py:2095 +#: flatcamGUI/FlatCAMGUI.py:2203 msgid "Union" msgstr "Uniune" -#: flatcamGUI/FlatCAMGUI.py:2097 +#: flatcamGUI/FlatCAMGUI.py:2205 msgid "Intersection" msgstr "Intersecţie" -#: flatcamGUI/FlatCAMGUI.py:2099 +#: flatcamGUI/FlatCAMGUI.py:2207 msgid "Subtraction" msgstr "Scădere" -#: flatcamGUI/FlatCAMGUI.py:2101 flatcamGUI/ObjectUI.py:1811 -#: flatcamGUI/PreferencesUI.py:4421 +#: flatcamGUI/FlatCAMGUI.py:2209 flatcamGUI/ObjectUI.py:2139 +#: flatcamGUI/PreferencesUI.py:4714 msgid "Cut" msgstr "Tăiere" -#: flatcamGUI/FlatCAMGUI.py:2112 +#: flatcamGUI/FlatCAMGUI.py:2220 msgid "Pad" msgstr "Pad" -#: flatcamGUI/FlatCAMGUI.py:2114 +#: flatcamGUI/FlatCAMGUI.py:2222 msgid "Pad Array" msgstr "Arie de paduri" -#: flatcamGUI/FlatCAMGUI.py:2118 +#: flatcamGUI/FlatCAMGUI.py:2226 msgid "Track" msgstr "Traseu" -#: flatcamGUI/FlatCAMGUI.py:2120 +#: flatcamGUI/FlatCAMGUI.py:2228 msgid "Region" msgstr "Regiune" -#: flatcamGUI/FlatCAMGUI.py:2143 +#: flatcamGUI/FlatCAMGUI.py:2251 msgid "Exc Editor" msgstr "Editor EXC" -#: flatcamGUI/FlatCAMGUI.py:2188 +#: flatcamGUI/FlatCAMGUI.py:2296 msgid "" "Relative neasurement.\n" "Reference is last click position" @@ -6937,7 +7292,7 @@ msgstr "" "Măsurătoare relativă.\n" "Referința este poziţia ultimului click pe canvas" -#: flatcamGUI/FlatCAMGUI.py:2194 +#: flatcamGUI/FlatCAMGUI.py:2302 msgid "" "Absolute neasurement.\n" "Reference is (X=0, Y= 0) position" @@ -6945,27 +7300,35 @@ msgstr "" "Măsurătoare absolută.\n" "Referința este originea (0, 0)" -#: flatcamGUI/FlatCAMGUI.py:2301 +#: flatcamGUI/FlatCAMGUI.py:2406 msgid "Lock Toolbars" msgstr "Blochează Toolbar-uri" -#: flatcamGUI/FlatCAMGUI.py:2419 +#: flatcamGUI/FlatCAMGUI.py:2465 +msgid "FlatCAM Preferences Folder opened." +msgstr "Folderul de preferințe FlatCAM a fost deschis." + +#: flatcamGUI/FlatCAMGUI.py:2476 +msgid "Are you sure you want to delete the GUI Settings? \n" +msgstr "Esti sigur că dorești să ștergi setările GUI?\n" + +#: flatcamGUI/FlatCAMGUI.py:2584 msgid "&Cutout Tool" msgstr "Unealta Decupare" -#: flatcamGUI/FlatCAMGUI.py:2478 +#: flatcamGUI/FlatCAMGUI.py:2650 msgid "Select 'Esc'" msgstr "Select" -#: flatcamGUI/FlatCAMGUI.py:2516 +#: flatcamGUI/FlatCAMGUI.py:2688 msgid "Copy Objects" msgstr "Copiază Obiecte" -#: flatcamGUI/FlatCAMGUI.py:2524 +#: flatcamGUI/FlatCAMGUI.py:2696 msgid "Move Objects" msgstr "Mută Obiecte" -#: flatcamGUI/FlatCAMGUI.py:3087 +#: flatcamGUI/FlatCAMGUI.py:3312 msgid "" "Please first select a geometry item to be cutted\n" "then select the geometry item that will be cutted\n" @@ -6976,12 +7339,12 @@ msgstr "" "apoi selectează forma geo. tăietoare. La final apasă tasta ~X~ sau\n" "butonul corespunzator din Toolbar." -#: flatcamGUI/FlatCAMGUI.py:3094 flatcamGUI/FlatCAMGUI.py:3254 -#: flatcamGUI/FlatCAMGUI.py:3299 flatcamGUI/FlatCAMGUI.py:3319 +#: flatcamGUI/FlatCAMGUI.py:3319 flatcamGUI/FlatCAMGUI.py:3478 +#: flatcamGUI/FlatCAMGUI.py:3523 flatcamGUI/FlatCAMGUI.py:3543 msgid "Warning" msgstr "Atenţie" -#: flatcamGUI/FlatCAMGUI.py:3249 +#: flatcamGUI/FlatCAMGUI.py:3473 msgid "" "Please select geometry items \n" "on which to perform Intersection Tool." @@ -6989,7 +7352,7 @@ msgstr "" "Selectează forma geometrică asupra căreia să se\n" "aplice Unealta Intersecţie." -#: flatcamGUI/FlatCAMGUI.py:3294 +#: flatcamGUI/FlatCAMGUI.py:3518 msgid "" "Please select geometry items \n" "on which to perform Substraction Tool." @@ -6997,7 +7360,7 @@ msgstr "" "Selectează forma geometrică asupra căreia să se\n" "aplice Unealta Substracţie." -#: flatcamGUI/FlatCAMGUI.py:3314 +#: flatcamGUI/FlatCAMGUI.py:3538 msgid "" "Please select geometry items \n" "on which to perform union." @@ -7005,61 +7368,62 @@ msgstr "" "Selectează forma geometrică asupra căreia să se\n" "aplice Unealta Uniune." -#: flatcamGUI/FlatCAMGUI.py:3394 flatcamGUI/FlatCAMGUI.py:3608 +#: flatcamGUI/FlatCAMGUI.py:3617 flatcamGUI/FlatCAMGUI.py:3828 msgid "Cancelled. Nothing selected to delete." msgstr "Anulat. Nimic nu este selectat pentru ștergere." -#: flatcamGUI/FlatCAMGUI.py:3479 flatcamGUI/FlatCAMGUI.py:3726 +#: flatcamGUI/FlatCAMGUI.py:3701 flatcamGUI/FlatCAMGUI.py:3944 msgid "Cancelled. Nothing selected to copy." msgstr "Anulat. Nimic nu este selectat pentru copiere." -#: flatcamGUI/FlatCAMGUI.py:3526 flatcamGUI/FlatCAMGUI.py:3756 +#: flatcamGUI/FlatCAMGUI.py:3747 flatcamGUI/FlatCAMGUI.py:3973 msgid "Cancelled. Nothing selected to move." msgstr "Anulat. Nimic nu este selectat pentru mutare." -#: flatcamGUI/FlatCAMGUI.py:3782 +#: flatcamGUI/FlatCAMGUI.py:3999 msgid "New Tool ..." msgstr "O noua Unealtă ..." -#: flatcamGUI/FlatCAMGUI.py:3783 flatcamTools/ToolNonCopperClear.py:583 -#: flatcamTools/ToolPaint.py:494 flatcamTools/ToolSolderPaste.py:554 +#: flatcamGUI/FlatCAMGUI.py:4000 flatcamTools/ToolNCC.py:922 +#: flatcamTools/ToolPaint.py:847 flatcamTools/ToolSolderPaste.py:560 msgid "Enter a Tool Diameter" msgstr "Introduceti un Diametru de Unealtă" -#: flatcamGUI/FlatCAMGUI.py:3795 +#: flatcamGUI/FlatCAMGUI.py:4012 msgid "Adding Tool cancelled ..." msgstr "Adăugarea unei unelte anulată..." -#: flatcamGUI/FlatCAMGUI.py:3808 +#: flatcamGUI/FlatCAMGUI.py:4025 msgid "Distance Tool exit..." msgstr "Măsurătoarea s-a terminat ..." -#: flatcamGUI/FlatCAMGUI.py:4018 flatcamGUI/FlatCAMGUI.py:4025 +#: flatcamGUI/FlatCAMGUI.py:4234 flatcamGUI/FlatCAMGUI.py:4241 msgid "Idle." msgstr "Inactiv." -#: flatcamGUI/FlatCAMGUI.py:4056 +#: flatcamGUI/FlatCAMGUI.py:4272 msgid "Application started ..." msgstr "Aplicaţia a pornit ..." -#: flatcamGUI/FlatCAMGUI.py:4057 +#: flatcamGUI/FlatCAMGUI.py:4273 msgid "Hello!" msgstr "Bună!" -#: flatcamGUI/FlatCAMGUI.py:4115 +#: flatcamGUI/FlatCAMGUI.py:4331 msgid "Open Project ..." msgstr "Încarcă Project ..." -#: flatcamGUI/FlatCAMGUI.py:4141 +#: flatcamGUI/FlatCAMGUI.py:4357 msgid "Exit" msgstr "Iesiere" -#: flatcamGUI/GUIElements.py:2261 flatcamGUI/PreferencesUI.py:5265 -#: flatcamGUI/PreferencesUI.py:5825 flatcamTools/ToolFilm.py:219 +#: flatcamGUI/GUIElements.py:2513 flatcamGUI/PreferencesUI.py:6313 +#: flatcamTools/ToolDblSided.py:174 flatcamTools/ToolDblSided.py:389 +#: flatcamTools/ToolFilm.py:219 msgid "Reference" msgstr "Referinţă" -#: flatcamGUI/GUIElements.py:2263 +#: flatcamGUI/GUIElements.py:2515 msgid "" "The reference can be:\n" "- Absolute -> the reference point is point (0,0)\n" @@ -7069,19 +7433,19 @@ msgstr "" "- Absolut -> punctul de referință este punctul (0,0)\n" "- Relativ -> punctul de referință este poziția mouse-ului înainte de Salt" -#: flatcamGUI/GUIElements.py:2268 +#: flatcamGUI/GUIElements.py:2520 msgid "Abs" msgstr "Abs" -#: flatcamGUI/GUIElements.py:2269 +#: flatcamGUI/GUIElements.py:2521 msgid "Relative" msgstr "Relativ" -#: flatcamGUI/GUIElements.py:2279 +#: flatcamGUI/GUIElements.py:2531 msgid "Location" msgstr "Locaţie" -#: flatcamGUI/GUIElements.py:2281 +#: flatcamGUI/GUIElements.py:2533 msgid "" "The Location value is a tuple (x,y).\n" "If the reference is Absolute then the Jump will be at the position (x,y).\n" @@ -7093,6 +7457,10 @@ msgstr "" "Dacă referința este Relativă, Saltul se va face la distanța (x, y)\n" "din punctul de locație al mouse-ului curent." +#: flatcamGUI/GUIElements.py:2573 +msgid "Save Log" +msgstr "Salvează Log" + #: flatcamGUI/ObjectUI.py:38 msgid "FlatCAM Object" msgstr "Obiect FlatCAM" @@ -7115,15 +7483,11 @@ msgstr "" "Edit -> Preferințe -> General și bifează:\n" "butonul radio: >Nivel App<." -#: flatcamGUI/ObjectUI.py:105 -msgid "Change the size of the object." -msgstr "Schimbă dimensiunea obiectului." +#: flatcamGUI/ObjectUI.py:110 +msgid "Geometrical transformations of the current object." +msgstr "Transformări geometrice ale obictului curent." -#: flatcamGUI/ObjectUI.py:111 -msgid "Factor" -msgstr "Factor" - -#: flatcamGUI/ObjectUI.py:113 +#: flatcamGUI/ObjectUI.py:119 msgid "" "Factor by which to multiply\n" "geometric features of this object.\n" @@ -7134,19 +7498,11 @@ msgstr "" "acestui obiect.\n" "Expresiile sunt permise. De ex: 1 / 25.4" -#: flatcamGUI/ObjectUI.py:123 +#: flatcamGUI/ObjectUI.py:126 msgid "Perform scaling operation." msgstr "Efectuează operatia de scalare." -#: flatcamGUI/ObjectUI.py:134 -msgid "Change the position of this object." -msgstr "Schimbă poziţia acestui obiect." - -#: flatcamGUI/ObjectUI.py:139 -msgid "Vector" -msgstr "Vector" - -#: flatcamGUI/ObjectUI.py:141 +#: flatcamGUI/ObjectUI.py:137 msgid "" "Amount by which to move the object\n" "in the x and y axes in (x, y) format.\n" @@ -7156,62 +7512,55 @@ msgstr "" "pe axele X și /sau Y in formatul (x,y).\n" "Expresiile sunt permise. De ex: (1/3.2, 0.5*3)" -#: flatcamGUI/ObjectUI.py:150 +#: flatcamGUI/ObjectUI.py:144 msgid "Perform the offset operation." msgstr "Efectuează operația de Ofset." -#: flatcamGUI/ObjectUI.py:167 +#: flatcamGUI/ObjectUI.py:177 msgid "Gerber Object" msgstr "Obiect Gerber" -#: flatcamGUI/ObjectUI.py:182 flatcamGUI/ObjectUI.py:767 -#: flatcamGUI/ObjectUI.py:1205 flatcamGUI/ObjectUI.py:1905 -#: flatcamGUI/PreferencesUI.py:1783 flatcamGUI/PreferencesUI.py:3849 -#: flatcamGUI/PreferencesUI.py:4406 -msgid "Plot (show) this object." -msgstr "Afisează (arata) acest obiect." - -#: flatcamGUI/ObjectUI.py:184 flatcamGUI/ObjectUI.py:765 -#: flatcamGUI/PreferencesUI.py:1781 flatcamGUI/PreferencesUI.py:2680 -#: flatcamGUI/PreferencesUI.py:3847 -msgid "Plot" -msgstr "Afisează" - -#: flatcamGUI/ObjectUI.py:189 flatcamGUI/ObjectUI.py:726 -#: flatcamGUI/ObjectUI.py:1159 flatcamGUI/ObjectUI.py:1795 -#: flatcamGUI/PreferencesUI.py:1760 flatcamGUI/PreferencesUI.py:2674 -#: flatcamGUI/PreferencesUI.py:3843 flatcamGUI/PreferencesUI.py:4395 +#: flatcamGUI/ObjectUI.py:186 flatcamGUI/ObjectUI.py:729 +#: flatcamGUI/ObjectUI.py:1424 flatcamGUI/ObjectUI.py:2123 +#: flatcamGUI/PreferencesUI.py:1940 flatcamGUI/PreferencesUI.py:2856 +#: flatcamGUI/PreferencesUI.py:4121 flatcamGUI/PreferencesUI.py:4688 msgid "Plot Options" msgstr "Opțiuni afișare" -#: flatcamGUI/ObjectUI.py:195 flatcamGUI/ObjectUI.py:727 -#: flatcamGUI/PreferencesUI.py:1767 flatcamGUI/PreferencesUI.py:2686 -#: flatcamGUI/PreferencesUI.py:7222 flatcamTools/ToolCopperThieving.py:190 +#: flatcamGUI/ObjectUI.py:192 flatcamGUI/ObjectUI.py:730 +#: flatcamGUI/PreferencesUI.py:1947 flatcamGUI/PreferencesUI.py:2868 +#: flatcamGUI/PreferencesUI.py:7728 flatcamTools/ToolCopperThieving.py:192 msgid "Solid" msgstr "Solid" -#: flatcamGUI/ObjectUI.py:197 flatcamGUI/PreferencesUI.py:1769 +#: flatcamGUI/ObjectUI.py:194 flatcamGUI/PreferencesUI.py:1949 msgid "Solid color polygons." msgstr "Poligoane color solide." -#: flatcamGUI/ObjectUI.py:203 +#: flatcamGUI/ObjectUI.py:200 msgid "Multi-Color" msgstr "Multicolor" -#: flatcamGUI/ObjectUI.py:205 flatcamGUI/PreferencesUI.py:1776 +#: flatcamGUI/ObjectUI.py:202 flatcamGUI/PreferencesUI.py:1956 msgid "Draw polygons in different colors." msgstr "" "Desenează poligoanele Gerber din multiple culori\n" "alese in mod aleator." -#: flatcamGUI/ObjectUI.py:213 flatcamGUI/ObjectUI.py:738 -#: flatcamGUI/ObjectUI.py:1165 flatcamGUI/ObjectUI.py:1825 -#: flatcamGUI/ObjectUI.py:2128 flatcamGUI/ObjectUI.py:2194 -#: flatcamTools/ToolCalibration.py:235 flatcamTools/ToolFiducials.py:73 -msgid "Name" -msgstr "Nume" +#: flatcamGUI/ObjectUI.py:208 flatcamGUI/ObjectUI.py:768 +#: flatcamGUI/PreferencesUI.py:1961 flatcamGUI/PreferencesUI.py:2862 +#: flatcamGUI/PreferencesUI.py:4125 +msgid "Plot" +msgstr "Afisează" -#: flatcamGUI/ObjectUI.py:234 +#: flatcamGUI/ObjectUI.py:210 flatcamGUI/ObjectUI.py:770 +#: flatcamGUI/ObjectUI.py:1484 flatcamGUI/ObjectUI.py:2233 +#: flatcamGUI/PreferencesUI.py:1963 flatcamGUI/PreferencesUI.py:4127 +#: flatcamGUI/PreferencesUI.py:4699 +msgid "Plot (show) this object." +msgstr "Afisează (arata) acest obiect." + +#: flatcamGUI/ObjectUI.py:238 msgid "" "Toggle the display of the Gerber Apertures Table.\n" "When unchecked, it will delete all mark shapes\n" @@ -7221,11 +7570,11 @@ msgstr "" "Când se debifează, toate marcajele aperturilor\n" "care sutn curent afisate, vor fi șterse." -#: flatcamGUI/ObjectUI.py:244 +#: flatcamGUI/ObjectUI.py:248 msgid "Mark All" msgstr "Marc. Toate" -#: flatcamGUI/ObjectUI.py:246 +#: flatcamGUI/ObjectUI.py:250 msgid "" "When checked it will display all the apertures.\n" "When unchecked, it will delete all mark shapes\n" @@ -7234,15 +7583,15 @@ msgstr "" "Când este bifat se vor afisa toate aperturile.\n" "Când este debifat se vor șterge toate marcajele de aperturi." -#: flatcamGUI/ObjectUI.py:274 +#: flatcamGUI/ObjectUI.py:278 msgid "Mark the aperture instances on canvas." msgstr "Marchează aperturile pe canvas." -#: flatcamGUI/ObjectUI.py:286 flatcamGUI/PreferencesUI.py:2014 +#: flatcamGUI/ObjectUI.py:290 flatcamGUI/PreferencesUI.py:2194 msgid "Isolation Routing" msgstr "Izolare" -#: flatcamGUI/ObjectUI.py:288 flatcamGUI/PreferencesUI.py:2016 +#: flatcamGUI/ObjectUI.py:292 flatcamGUI/PreferencesUI.py:2196 msgid "" "Create a Geometry object with\n" "toolpaths to cut outside polygons." @@ -7251,7 +7600,7 @@ msgstr "" "care să fie taiate in afara poligoanelor,\n" "urmărindu-le conturul." -#: flatcamGUI/ObjectUI.py:306 flatcamGUI/PreferencesUI.py:2219 +#: flatcamGUI/ObjectUI.py:310 flatcamGUI/PreferencesUI.py:2399 msgid "" "Choose what tool to use for Gerber isolation:\n" "'Circular' or 'V-shape'.\n" @@ -7263,33 +7612,39 @@ msgstr "" "Când este selectată „forma V”, atunci\n" "diametrul uneltei va depinde de adâncimea de tăiere aleasă." -#: flatcamGUI/ObjectUI.py:312 +#: flatcamGUI/ObjectUI.py:316 msgid "V-Shape" msgstr "Forma-V" -#: flatcamGUI/ObjectUI.py:318 flatcamGUI/ObjectUI.py:1374 -#: flatcamGUI/PreferencesUI.py:2231 flatcamGUI/PreferencesUI.py:5055 -#: flatcamTools/ToolNonCopperClear.py:231 +#: flatcamGUI/ObjectUI.py:322 flatcamGUI/ObjectUI.py:1670 +#: flatcamGUI/PreferencesUI.py:2411 flatcamGUI/PreferencesUI.py:5351 +#: flatcamGUI/PreferencesUI.py:5917 flatcamGUI/PreferencesUI.py:5924 +#: flatcamTools/ToolNCC.py:233 flatcamTools/ToolNCC.py:240 +#: flatcamTools/ToolPaint.py:216 msgid "V-Tip Dia" msgstr "V-dia" -#: flatcamGUI/ObjectUI.py:320 flatcamGUI/ObjectUI.py:1377 -#: flatcamGUI/PreferencesUI.py:2233 flatcamGUI/PreferencesUI.py:5057 -#: flatcamTools/ToolNonCopperClear.py:233 +#: flatcamGUI/ObjectUI.py:324 flatcamGUI/ObjectUI.py:1673 +#: flatcamGUI/PreferencesUI.py:2413 flatcamGUI/PreferencesUI.py:5353 +#: flatcamGUI/PreferencesUI.py:5919 flatcamTools/ToolNCC.py:235 +#: flatcamTools/ToolPaint.py:218 msgid "The tip diameter for V-Shape Tool" msgstr "" "Diametrul la vârf al uneltei tip V-Shape.\n" "Forma in V" -#: flatcamGUI/ObjectUI.py:331 flatcamGUI/ObjectUI.py:1389 -#: flatcamGUI/PreferencesUI.py:2244 flatcamGUI/PreferencesUI.py:5067 -#: flatcamTools/ToolNonCopperClear.py:242 +#: flatcamGUI/ObjectUI.py:335 flatcamGUI/ObjectUI.py:1685 +#: flatcamGUI/PreferencesUI.py:2424 flatcamGUI/PreferencesUI.py:5363 +#: flatcamGUI/PreferencesUI.py:5930 flatcamGUI/PreferencesUI.py:5938 +#: flatcamTools/ToolNCC.py:246 flatcamTools/ToolNCC.py:254 +#: flatcamTools/ToolPaint.py:229 msgid "V-Tip Angle" msgstr "V-unghi" -#: flatcamGUI/ObjectUI.py:333 flatcamGUI/ObjectUI.py:1392 -#: flatcamGUI/PreferencesUI.py:2246 flatcamGUI/PreferencesUI.py:5069 -#: flatcamTools/ToolNonCopperClear.py:244 +#: flatcamGUI/ObjectUI.py:337 flatcamGUI/ObjectUI.py:1688 +#: flatcamGUI/PreferencesUI.py:2426 flatcamGUI/PreferencesUI.py:5365 +#: flatcamGUI/PreferencesUI.py:5932 flatcamTools/ToolNCC.py:248 +#: flatcamTools/ToolPaint.py:231 msgid "" "The tip angle for V-Shape Tool.\n" "In degree." @@ -7297,9 +7652,9 @@ msgstr "" "Unghiul la vârf pentru unealta tip V-Shape. \n" "In grade." -#: flatcamGUI/ObjectUI.py:347 flatcamGUI/ObjectUI.py:1408 -#: flatcamGUI/PreferencesUI.py:2259 flatcamGUI/PreferencesUI.py:3963 -#: flatcamGUI/PreferencesUI.py:5330 flatcamTools/ToolCutOut.py:135 +#: flatcamGUI/ObjectUI.py:351 flatcamGUI/ObjectUI.py:1704 +#: flatcamGUI/PreferencesUI.py:2439 flatcamGUI/PreferencesUI.py:4243 +#: flatcamGUI/PreferencesUI.py:5669 flatcamTools/ToolCutOut.py:142 msgid "" "Cutting depth (negative)\n" "below the copper surface." @@ -7307,7 +7662,7 @@ msgstr "" "Adâncimea la care se taie sub suprafata de cupru.\n" "Valoare negativă." -#: flatcamGUI/ObjectUI.py:361 +#: flatcamGUI/ObjectUI.py:365 msgid "" "Diameter of the cutting tool.\n" "If you want to have an isolation path\n" @@ -7320,11 +7675,11 @@ msgstr "" "in interiorul poligonului Gerber (traseu), foloseşte\n" "o valoare negativă pt acest parametru." -#: flatcamGUI/ObjectUI.py:377 flatcamGUI/PreferencesUI.py:2038 +#: flatcamGUI/ObjectUI.py:381 flatcamGUI/PreferencesUI.py:2218 msgid "# Passes" msgstr "# Treceri" -#: flatcamGUI/ObjectUI.py:379 flatcamGUI/PreferencesUI.py:2040 +#: flatcamGUI/ObjectUI.py:383 flatcamGUI/PreferencesUI.py:2220 msgid "" "Width of the isolation gap in\n" "number (integer) of tool widths." @@ -7332,24 +7687,18 @@ msgstr "" "Lăţimea spatiului de izolare\n" "in număr intreg de grosimi ale uneltei." -#: flatcamGUI/ObjectUI.py:389 flatcamGUI/PreferencesUI.py:2050 +#: flatcamGUI/ObjectUI.py:394 flatcamGUI/PreferencesUI.py:2230 msgid "Pass overlap" msgstr "Suprapunere" -#: flatcamGUI/ObjectUI.py:391 flatcamGUI/PreferencesUI.py:2052 -msgid "How much (fraction) of the tool width to overlap each tool pass." +#: flatcamGUI/ObjectUI.py:396 flatcamGUI/PreferencesUI.py:2232 +msgid "How much (percentage) of the tool width to overlap each tool pass." msgstr "" -"Cat de mult (o fracţie din diametrul uneltei) din diametrul uneltei,\n" -"(lăţimea de tăiere) să se suprapună peste trecerea anterioară." +"Cat de mult (procent) din diametrul uneltei, (lăţimea de tăiere), să se " +"suprapună peste trecerea anterioară." -#: flatcamGUI/ObjectUI.py:403 flatcamGUI/PreferencesUI.py:2077 -#: flatcamGUI/PreferencesUI.py:4372 flatcamGUI/PreferencesUI.py:5112 -#: flatcamTools/ToolNonCopperClear.py:162 -msgid "Milling Type" -msgstr "Tip Frezare" - -#: flatcamGUI/ObjectUI.py:405 flatcamGUI/PreferencesUI.py:2079 -#: flatcamGUI/PreferencesUI.py:4374 +#: flatcamGUI/ObjectUI.py:410 flatcamGUI/PreferencesUI.py:2259 +#: flatcamGUI/PreferencesUI.py:4667 msgid "" "Milling type:\n" "- climb / best for precision milling and to reduce tool usage\n" @@ -7360,29 +7709,19 @@ msgstr "" "uneltei\n" "- conventional -> pentru cazul când nu exista o compensare a 'backlash-ului'" -#: flatcamGUI/ObjectUI.py:409 flatcamGUI/PreferencesUI.py:2084 -#: flatcamGUI/PreferencesUI.py:4378 flatcamGUI/PreferencesUI.py:5119 -#: flatcamTools/ToolNonCopperClear.py:169 -msgid "Climb" -msgstr "Urcare" - -#: flatcamGUI/ObjectUI.py:410 -msgid "Conventional" -msgstr "Convenţional" - -#: flatcamGUI/ObjectUI.py:415 +#: flatcamGUI/ObjectUI.py:420 msgid "Combine" msgstr "Combina" -#: flatcamGUI/ObjectUI.py:417 flatcamGUI/PreferencesUI.py:2091 +#: flatcamGUI/ObjectUI.py:422 flatcamGUI/PreferencesUI.py:2271 msgid "Combine all passes into one object" msgstr "Combina toate trecerile intr-un singur obiect" -#: flatcamGUI/ObjectUI.py:421 flatcamGUI/PreferencesUI.py:2193 +#: flatcamGUI/ObjectUI.py:426 flatcamGUI/PreferencesUI.py:2373 msgid "\"Follow\"" msgstr "\"Urmareste\"" -#: flatcamGUI/ObjectUI.py:422 flatcamGUI/PreferencesUI.py:2195 +#: flatcamGUI/ObjectUI.py:427 flatcamGUI/PreferencesUI.py:2375 msgid "" "Generate a 'Follow' geometry.\n" "This means that it will cut through\n" @@ -7392,11 +7731,11 @@ msgstr "" "Mai exact, in loc să se genereze un poligon se va genera o 'linie'.\n" "In acest fel se taie prin mijlocul unui traseu și nu in jurul lui." -#: flatcamGUI/ObjectUI.py:428 +#: flatcamGUI/ObjectUI.py:433 msgid "Except" msgstr "Exceptie" -#: flatcamGUI/ObjectUI.py:431 +#: flatcamGUI/ObjectUI.py:436 msgid "" "When the isolation geometry is generated,\n" "by checking this, the area of the object bellow\n" @@ -7406,12 +7745,12 @@ msgstr "" "prin bifarea aici, aria obiectului de mai jos va fi\n" "scăzută din geometrie de tip Izolare." -#: flatcamGUI/ObjectUI.py:453 flatcamTools/ToolNonCopperClear.py:82 -#: flatcamTools/ToolPaint.py:85 +#: flatcamGUI/ObjectUI.py:456 flatcamTools/ToolNCC.py:86 +#: flatcamTools/ToolPaint.py:80 msgid "Obj Type" msgstr "Tip obiect" -#: flatcamGUI/ObjectUI.py:455 +#: flatcamGUI/ObjectUI.py:458 msgid "" "Specify the type of object to be excepted from isolation.\n" "It can be of type: Gerber or Geometry.\n" @@ -7424,23 +7763,23 @@ msgstr "" "obiecte care vor aparea in combobox-ul\n" "numit >Obiect<." -#: flatcamGUI/ObjectUI.py:468 flatcamGUI/PreferencesUI.py:7522 -#: flatcamTools/ToolCalibration.py:186 flatcamTools/ToolNonCopperClear.py:100 -#: flatcamTools/ToolPaint.py:103 flatcamTools/ToolPanelize.py:81 -#: flatcamTools/ToolPanelize.py:94 +#: flatcamGUI/ObjectUI.py:471 flatcamGUI/PreferencesUI.py:8028 +#: flatcamTools/ToolCalibration.py:186 flatcamTools/ToolNCC.py:109 +#: flatcamTools/ToolPaint.py:103 flatcamTools/ToolPanelize.py:100 +#: flatcamTools/ToolQRCode.py:78 msgid "Object" msgstr "Obiect" -#: flatcamGUI/ObjectUI.py:469 +#: flatcamGUI/ObjectUI.py:472 msgid "Object whose area will be removed from isolation geometry." msgstr "" "Obiectul a cărui suprafată va fi indepărtată din geometria tip Izolare." -#: flatcamGUI/ObjectUI.py:476 flatcamGUI/PreferencesUI.py:2064 +#: flatcamGUI/ObjectUI.py:479 flatcamGUI/PreferencesUI.py:2244 msgid "Scope" msgstr "Domeniu" -#: flatcamGUI/ObjectUI.py:478 flatcamGUI/PreferencesUI.py:2066 +#: flatcamGUI/ObjectUI.py:481 flatcamGUI/PreferencesUI.py:2246 msgid "" "Isolation scope. Choose what to isolate:\n" "- 'All' -> Isolate all the polygons in the object\n" @@ -7450,17 +7789,18 @@ msgstr "" "- 'Toate' -> Izolați toate poligoanele din obiect\n" "- 'Selecție' -> Izolați o selecție de poligoane." -#: flatcamGUI/ObjectUI.py:483 flatcamGUI/PreferencesUI.py:602 -#: flatcamGUI/PreferencesUI.py:2071 flatcamGUI/PreferencesUI.py:5634 -#: flatcamTools/ToolPaint.py:294 +#: flatcamGUI/ObjectUI.py:486 flatcamGUI/PreferencesUI.py:624 +#: flatcamGUI/PreferencesUI.py:2251 flatcamGUI/PreferencesUI.py:5590 +#: flatcamGUI/PreferencesUI.py:6097 flatcamTools/ToolNCC.py:539 +#: flatcamTools/ToolPaint.py:456 msgid "Selection" msgstr "Selecţie" -#: flatcamGUI/ObjectUI.py:491 flatcamGUI/PreferencesUI.py:2272 +#: flatcamGUI/ObjectUI.py:494 flatcamGUI/PreferencesUI.py:2452 msgid "Isolation Type" msgstr "Tip de izolare" -#: flatcamGUI/ObjectUI.py:493 flatcamGUI/PreferencesUI.py:2274 +#: flatcamGUI/ObjectUI.py:496 flatcamGUI/PreferencesUI.py:2454 msgid "" "Choose how the isolation will be executed:\n" "- 'Full' -> complete isolation of polygons\n" @@ -7480,24 +7820,24 @@ msgstr "" "„Interior”se poate face numai atunci când există o deschidere\n" "în interiorul poligonului (de exemplu, poligonul are o formă de „gogoașă”)." -#: flatcamGUI/ObjectUI.py:502 flatcamGUI/PreferencesUI.py:2283 -#: flatcamGUI/PreferencesUI.py:2304 +#: flatcamGUI/ObjectUI.py:505 flatcamGUI/PreferencesUI.py:2463 +#: flatcamGUI/PreferencesUI.py:2484 msgid "Full" msgstr "Complet" -#: flatcamGUI/ObjectUI.py:503 +#: flatcamGUI/ObjectUI.py:506 msgid "Ext" msgstr "Ext" -#: flatcamGUI/ObjectUI.py:504 +#: flatcamGUI/ObjectUI.py:507 msgid "Int" msgstr "Int" -#: flatcamGUI/ObjectUI.py:509 +#: flatcamGUI/ObjectUI.py:512 msgid "Generate Isolation Geometry" msgstr "Creează Geometrie de Izolare" -#: flatcamGUI/ObjectUI.py:517 +#: flatcamGUI/ObjectUI.py:520 msgid "" "Create a Geometry object with toolpaths to cut \n" "isolation outside, inside or on both sides of the\n" @@ -7516,11 +7856,11 @@ msgstr "" "(traseu, zona etc) iar >in interior< inseamna efectiv in interiorul\n" "acelui elem. Gerber (daca poate fi posibil)." -#: flatcamGUI/ObjectUI.py:529 +#: flatcamGUI/ObjectUI.py:532 msgid "Buffer Solid Geometry" msgstr "Creează Bufer Geometrie Solidă" -#: flatcamGUI/ObjectUI.py:531 +#: flatcamGUI/ObjectUI.py:534 msgid "" "This button is shown only when the Gerber file\n" "is loaded without buffering.\n" @@ -7532,11 +7872,11 @@ msgstr "" "Bifarea aici va crea această buferare care este necesară\n" "pentru a crea geometrie de tip Izolare." -#: flatcamGUI/ObjectUI.py:559 +#: flatcamGUI/ObjectUI.py:566 msgid "Clear N-copper" msgstr "Curăță Non-Cu" -#: flatcamGUI/ObjectUI.py:561 flatcamGUI/PreferencesUI.py:5019 +#: flatcamGUI/ObjectUI.py:568 flatcamGUI/PreferencesUI.py:5312 msgid "" "Create a Geometry object with\n" "toolpaths to cut all non-copper regions." @@ -7545,8 +7885,8 @@ msgstr "" "care să curete de cupru toate zonele unde se dorește să nu \n" "fie cupru." -#: flatcamGUI/ObjectUI.py:568 flatcamGUI/ObjectUI.py:1751 -#: flatcamTools/ToolNonCopperClear.py:473 +#: flatcamGUI/ObjectUI.py:575 flatcamGUI/ObjectUI.py:2077 +#: flatcamTools/ToolNCC.py:599 msgid "" "Create the Geometry Object\n" "for non-copper routing." @@ -7555,11 +7895,11 @@ msgstr "" "pt rutare non-cupru (adica pt\n" "curățare zone de cupru)." -#: flatcamGUI/ObjectUI.py:581 +#: flatcamGUI/ObjectUI.py:588 msgid "Board cutout" msgstr "Decupare PCB" -#: flatcamGUI/ObjectUI.py:583 flatcamGUI/PreferencesUI.py:5303 +#: flatcamGUI/ObjectUI.py:590 flatcamGUI/PreferencesUI.py:5642 msgid "" "Create toolpaths to cut around\n" "the PCB and separate it from\n" @@ -7569,7 +7909,7 @@ msgstr "" "lasand punţi pentru a separa PCB-ul de \n" "placa din care a fost taiat." -#: flatcamGUI/ObjectUI.py:590 +#: flatcamGUI/ObjectUI.py:597 msgid "" "Generate the geometry for\n" "the board cutout." @@ -7577,11 +7917,11 @@ msgstr "" "Generează un obiect Geometrie\n" "pt decuparea PCB." -#: flatcamGUI/ObjectUI.py:608 flatcamGUI/PreferencesUI.py:2101 +#: flatcamGUI/ObjectUI.py:615 flatcamGUI/PreferencesUI.py:2281 msgid "Non-copper regions" msgstr "Regiuni fără Cu" -#: flatcamGUI/ObjectUI.py:610 flatcamGUI/PreferencesUI.py:2103 +#: flatcamGUI/ObjectUI.py:617 flatcamGUI/PreferencesUI.py:2283 msgid "" "Create polygons covering the\n" "areas without copper on the PCB.\n" @@ -7594,12 +7934,12 @@ msgstr "" "obiectului sursa. Poate fi folosit pt a indeparta\n" "cuprul din zona specificata." -#: flatcamGUI/ObjectUI.py:620 flatcamGUI/ObjectUI.py:661 -#: flatcamGUI/PreferencesUI.py:2115 flatcamGUI/PreferencesUI.py:2148 +#: flatcamGUI/ObjectUI.py:627 flatcamGUI/ObjectUI.py:668 +#: flatcamGUI/PreferencesUI.py:2295 flatcamGUI/PreferencesUI.py:2328 msgid "Boundary Margin" msgstr "Margine" -#: flatcamGUI/ObjectUI.py:622 flatcamGUI/PreferencesUI.py:2117 +#: flatcamGUI/ObjectUI.py:629 flatcamGUI/PreferencesUI.py:2297 msgid "" "Specify the edge of the PCB\n" "by drawing a box around all\n" @@ -7610,29 +7950,29 @@ msgstr "" "unei forme patratice de jur imprejurul la toate obiectele\n" "la o distanţa minima cu valoarea din acest câmp." -#: flatcamGUI/ObjectUI.py:637 flatcamGUI/ObjectUI.py:675 -#: flatcamGUI/PreferencesUI.py:2130 flatcamGUI/PreferencesUI.py:2161 +#: flatcamGUI/ObjectUI.py:644 flatcamGUI/ObjectUI.py:682 +#: flatcamGUI/PreferencesUI.py:2310 flatcamGUI/PreferencesUI.py:2341 msgid "Rounded Geo" msgstr "Geo rotunjita" -#: flatcamGUI/ObjectUI.py:639 flatcamGUI/PreferencesUI.py:2132 +#: flatcamGUI/ObjectUI.py:646 flatcamGUI/PreferencesUI.py:2312 msgid "Resulting geometry will have rounded corners." msgstr "" "Obiectul Geometrie rezultat \n" "va avea colțurile rotunjite." -#: flatcamGUI/ObjectUI.py:643 flatcamGUI/ObjectUI.py:684 -#: flatcamTools/ToolSolderPaste.py:133 +#: flatcamGUI/ObjectUI.py:650 flatcamGUI/ObjectUI.py:691 +#: flatcamTools/ToolSolderPaste.py:135 msgid "Generate Geo" msgstr "Crează Geo" -#: flatcamGUI/ObjectUI.py:653 flatcamGUI/PreferencesUI.py:2142 -#: flatcamGUI/PreferencesUI.py:7052 flatcamTools/ToolPanelize.py:95 +#: flatcamGUI/ObjectUI.py:660 flatcamGUI/PreferencesUI.py:2322 +#: flatcamGUI/PreferencesUI.py:7558 flatcamTools/ToolPanelize.py:101 #: flatcamTools/ToolQRCode.py:192 msgid "Bounding Box" msgstr "Forma înconjurătoare" -#: flatcamGUI/ObjectUI.py:655 +#: flatcamGUI/ObjectUI.py:662 msgid "" "Create a geometry surrounding the Gerber object.\n" "Square shape." @@ -7640,7 +7980,7 @@ msgstr "" "Generează un obiect tip Geometrie care va inconjura\n" "obiectul Gerber. Forma patratica (rectangulara)." -#: flatcamGUI/ObjectUI.py:663 flatcamGUI/PreferencesUI.py:2150 +#: flatcamGUI/ObjectUI.py:670 flatcamGUI/PreferencesUI.py:2330 msgid "" "Distance of the edges of the box\n" "to the nearest polygon." @@ -7648,7 +7988,7 @@ msgstr "" "Distanta de la marginile formei înconjurătoare\n" "pana la cel mai apropiat poligon." -#: flatcamGUI/ObjectUI.py:677 flatcamGUI/PreferencesUI.py:2163 +#: flatcamGUI/ObjectUI.py:684 flatcamGUI/PreferencesUI.py:2343 msgid "" "If the bounding box is \n" "to have rounded corners\n" @@ -7658,33 +7998,31 @@ msgstr "" "Daca forma înconjurătoare să aibă colțuri rotunjite.\n" "Raza acesor colțuri va fi egală cu parametrul Margine." -#: flatcamGUI/ObjectUI.py:686 +#: flatcamGUI/ObjectUI.py:693 msgid "Generate the Geometry object." msgstr "Generează obiectul Geometrie." -#: flatcamGUI/ObjectUI.py:715 +#: flatcamGUI/ObjectUI.py:720 msgid "Excellon Object" msgstr "Obiect Excellon" -#: flatcamGUI/ObjectUI.py:729 +#: flatcamGUI/ObjectUI.py:732 msgid "Solid circles." msgstr "Cercuri solide." -#: flatcamGUI/ObjectUI.py:777 flatcamGUI/ObjectUI.py:1926 -#: flatcamTools/ToolProperties.py:161 +#: flatcamGUI/ObjectUI.py:780 flatcamGUI/ObjectUI.py:875 +#: flatcamGUI/ObjectUI.py:2254 flatcamGUI/PreferencesUI.py:3289 +#: flatcamTools/ToolProperties.py:166 msgid "Drills" msgstr "Găuri" -#: flatcamGUI/ObjectUI.py:777 flatcamGUI/ObjectUI.py:1926 -#: flatcamGUI/PreferencesUI.py:3683 flatcamTools/ToolProperties.py:162 +#: flatcamGUI/ObjectUI.py:780 flatcamGUI/ObjectUI.py:876 +#: flatcamGUI/ObjectUI.py:2254 flatcamGUI/PreferencesUI.py:3290 +#: flatcamGUI/PreferencesUI.py:3961 flatcamTools/ToolProperties.py:168 msgid "Slots" msgstr "Sloturi" -#: flatcamGUI/ObjectUI.py:778 flatcamGUI/PreferencesUI.py:3289 -msgid "Offset Z" -msgstr "Ofset Z" - -#: flatcamGUI/ObjectUI.py:782 +#: flatcamGUI/ObjectUI.py:785 msgid "" "This is the Tool Number.\n" "When ToolChange is checked, on toolchange event this value\n" @@ -7698,8 +8036,8 @@ msgstr "" "in codul masina CNC.\n" "Aici se selectează uneltele pt generarea de G-Code." -#: flatcamGUI/ObjectUI.py:787 flatcamGUI/ObjectUI.py:1230 -#: flatcamTools/ToolPaint.py:137 +#: flatcamGUI/ObjectUI.py:790 flatcamGUI/ObjectUI.py:1508 +#: flatcamTools/ToolPaint.py:142 msgid "" "Tool Diameter. It's value (in current FlatCAM units) \n" "is the cut width into the material." @@ -7707,7 +8045,7 @@ msgstr "" "Diametrul uneltei. Valoarea să (in unitati curente)\n" "reprezinta lăţimea taieturii in material." -#: flatcamGUI/ObjectUI.py:790 +#: flatcamGUI/ObjectUI.py:793 msgid "" "The number of Drill holes. Holes that are drilled with\n" "a drill bit." @@ -7715,7 +8053,7 @@ msgstr "" "Numărul de găuri. Sunt găuri efectuate prin\n" "operațiuni de găurire efectuate cu un burghiu." -#: flatcamGUI/ObjectUI.py:793 +#: flatcamGUI/ObjectUI.py:796 msgid "" "The number of Slot holes. Holes that are created by\n" "milling them with an endmill bit." @@ -7723,20 +8061,7 @@ msgstr "" "Numărul de sloturi. Sunt găuri efectuate\n" "prin op. de frezare cu o freza." -#: flatcamGUI/ObjectUI.py:796 flatcamGUI/PreferencesUI.py:3291 -msgid "" -"Some drill bits (the larger ones) need to drill deeper\n" -"to create the desired exit hole diameter due of the tip shape.\n" -"The value here can compensate the Cut Z parameter." -msgstr "" -"Unele burghie (in special cele cu diametru mai mare)\n" -"au nevoie să găurească mai adanc pentru a depăși conul\n" -"din vârful burghiului astfel încât diametrul găurii de ieșire\n" -"să fie cel dorit.\n" -"Valoarea de aici efectuează o compensare asupra\n" -"parametrului >Z tăiere<." - -#: flatcamGUI/ObjectUI.py:800 +#: flatcamGUI/ObjectUI.py:799 msgid "" "Toggle display of the drills for the current tool.\n" "This does not select the tools for G-code generation." @@ -7744,20 +8069,60 @@ msgstr "" "Comută afișarea găurilor pt unealta curentă.\n" "Aceata nu selectează uneltele pt generarea G-Code." -#: flatcamGUI/ObjectUI.py:807 flatcamGUI/PreferencesUI.py:3069 -#: flatcamGUI/PreferencesUI.py:3947 -msgid "Create CNC Job" -msgstr "Crează CNCJob" - -#: flatcamGUI/ObjectUI.py:809 +#: flatcamGUI/ObjectUI.py:820 flatcamGUI/ObjectUI.py:1663 +#: flatcamTools/ToolNCC.py:334 flatcamTools/ToolPaint.py:317 msgid "" -"Create a CNC Job object\n" -"for this drill object." +"The data used for creating GCode.\n" +"Each tool store it's own set of such data." msgstr "" -"Crează un obiect CNCJob din\n" -"acest obiect." +"Datele folosite pentru crearea codului GCode.\n" +"Fiecare unealtă stochează un subset de asemenea date." -#: flatcamGUI/ObjectUI.py:822 flatcamGUI/PreferencesUI.py:3084 +#: flatcamGUI/ObjectUI.py:846 flatcamGUI/PreferencesUI.py:3266 +msgid "" +"Operation type:\n" +"- Drilling -> will drill the drills/slots associated with this tool\n" +"- Milling -> will mill the drills/slots" +msgstr "" +"Tip operatie:\n" +"- Găurire -> va găuri găurile/sloturile associate acestei unelte\n" +"- Frezare -> va freza găurile/sloturile" + +#: flatcamGUI/ObjectUI.py:852 flatcamGUI/PreferencesUI.py:3272 +msgid "Drilling" +msgstr "Găurire" + +#: flatcamGUI/ObjectUI.py:853 flatcamGUI/PreferencesUI.py:3273 +msgid "Milling" +msgstr "Frezare" + +#: flatcamGUI/ObjectUI.py:868 flatcamGUI/PreferencesUI.py:3282 +msgid "" +"Milling type:\n" +"- Drills -> will mill the drills associated with this tool\n" +"- Slots -> will mill the slots associated with this tool\n" +"- Both -> will mill both drills and mills or whatever is available" +msgstr "" +"Tip frezare:\n" +"- Găuri -> va freza găurile asociate acestei unelte\n" +"- Sloturi -> va freza sloturile asociate acestei unelte\n" +"- Ambele -> va freza atat găurile cat si sloturile sau doar acelea care sunt " +"disponibile" + +#: flatcamGUI/ObjectUI.py:877 flatcamGUI/PreferencesUI.py:3291 +#: flatcamGUI/PreferencesUI.py:6343 flatcamTools/ToolFilm.py:258 +msgid "Both" +msgstr "Ambele" + +#: flatcamGUI/ObjectUI.py:885 flatcamGUI/PreferencesUI.py:3298 +msgid "Milling Diameter" +msgstr "Dia frezare" + +#: flatcamGUI/ObjectUI.py:887 flatcamGUI/PreferencesUI.py:3300 +msgid "The diameter of the tool who will do the milling" +msgstr "Diametrul frezei când se frezează sloturile" + +#: flatcamGUI/ObjectUI.py:901 flatcamGUI/PreferencesUI.py:3313 msgid "" "Drill depth (negative)\n" "below the copper surface." @@ -7766,7 +8131,35 @@ msgstr "" "Daca se foloseşte o val. pozitivă, aplicaţia\n" "va incerca in mod automat să schimbe semnul." -#: flatcamGUI/ObjectUI.py:841 flatcamGUI/PreferencesUI.py:3102 +#: flatcamGUI/ObjectUI.py:920 flatcamGUI/ObjectUI.py:1722 +#: flatcamGUI/PreferencesUI.py:3331 flatcamGUI/PreferencesUI.py:4261 +#: flatcamGUI/PreferencesUI.py:5687 flatcamTools/ToolCutOut.py:160 +msgid "Multi-Depth" +msgstr "Multi-Pas" + +#: flatcamGUI/ObjectUI.py:923 flatcamGUI/ObjectUI.py:1725 +#: flatcamGUI/PreferencesUI.py:3334 flatcamGUI/PreferencesUI.py:4264 +#: flatcamGUI/PreferencesUI.py:5690 flatcamTools/ToolCutOut.py:163 +msgid "" +"Use multiple passes to limit\n" +"the cut depth in each pass. Will\n" +"cut multiple times until Cut Z is\n" +"reached." +msgstr "" +"Folosiți mai multe pase pentru a limita\n" +"adâncimea tăiată în fiecare trecere. Se\n" +"va tăia de mai multe ori până când este\n" +"atins Z de tăiere, Z Cut." + +#: flatcamGUI/ObjectUI.py:936 flatcamGUI/ObjectUI.py:1739 +#: flatcamGUI/PreferencesUI.py:3346 flatcamGUI/PreferencesUI.py:5702 +#: flatcamTools/ToolCutOut.py:177 +msgid "Depth of each pass (positive)." +msgstr "" +"Adâncimea pentru fiecare trecere.\n" +"Valoare pozitivă, in unitatile curente." + +#: flatcamGUI/ObjectUI.py:947 flatcamGUI/PreferencesUI.py:3354 msgid "" "Tool height when travelling\n" "across the XY plane." @@ -7775,58 +8168,16 @@ msgstr "" "in planul X-Y, fără a efectua taieri, adica\n" "in afara materialului." -#: flatcamGUI/ObjectUI.py:858 flatcamGUI/ObjectUI.py:1478 -#: flatcamGUI/PreferencesUI.py:3117 flatcamGUI/PreferencesUI.py:4034 -msgid "Tool change" -msgstr "Schimb unealtă" - -#: flatcamGUI/ObjectUI.py:860 flatcamGUI/PreferencesUI.py:3119 +#: flatcamGUI/ObjectUI.py:968 flatcamGUI/ObjectUI.py:1769 +#: flatcamGUI/PreferencesUI.py:4380 msgid "" -"Include tool-change sequence\n" -"in G-Code (Pause for tool change)." +"Cutting speed in the XY\n" +"plane in units per minute" msgstr "" -"Include o secventa de schimbare unealtă\n" -"in codul G-Code (pauza pentru schimbare unealtă).\n" -"De obicei este folosita comanda G-Code M6." +"Viteza de tăiere in planul X-Y\n" +"in unitati pe minut" -#: flatcamGUI/ObjectUI.py:866 flatcamGUI/ObjectUI.py:1471 -msgid "Tool change Z" -msgstr "Z schimb unealtă" - -#: flatcamGUI/ObjectUI.py:868 flatcamGUI/ObjectUI.py:1474 -#: flatcamGUI/PreferencesUI.py:3126 flatcamGUI/PreferencesUI.py:4047 -msgid "" -"Z-axis position (height) for\n" -"tool change." -msgstr "Înălţimea, pe axa Z, pentru schimbul uneltei." - -#: flatcamGUI/ObjectUI.py:888 flatcamGUI/PreferencesUI.py:3311 -msgid "" -"Height of the tool just after start.\n" -"Delete the value if you don't need this feature." -msgstr "" -"Înălţimea uneltei imediat dupa ce se porneste operatia CNC.\n" -"Lasa casuta goala daca nu se foloseşte." - -#: flatcamGUI/ObjectUI.py:896 flatcamGUI/ObjectUI.py:1512 -#: flatcamGUI/PreferencesUI.py:3141 flatcamGUI/PreferencesUI.py:4066 -msgid "End move Z" -msgstr "Z oprire" - -#: flatcamGUI/ObjectUI.py:898 flatcamGUI/ObjectUI.py:1514 -#: flatcamGUI/PreferencesUI.py:3143 flatcamGUI/PreferencesUI.py:4068 -msgid "" -"Height of the tool after\n" -"the last move at the end of the job." -msgstr "Înălţimea la care se parchează freza dupa ce se termina lucrul." - -#: flatcamGUI/ObjectUI.py:915 flatcamGUI/ObjectUI.py:1545 -#: flatcamGUI/PreferencesUI.py:3158 flatcamGUI/PreferencesUI.py:4101 -#: flatcamGUI/PreferencesUI.py:6566 flatcamTools/ToolSolderPaste.py:264 -msgid "Feedrate Z" -msgstr "Feedrate Z" - -#: flatcamGUI/ObjectUI.py:917 flatcamGUI/PreferencesUI.py:3160 +#: flatcamGUI/ObjectUI.py:983 flatcamGUI/PreferencesUI.py:3427 msgid "" "Tool speed while drilling\n" "(in units per minute).\n" @@ -7838,12 +8189,12 @@ msgstr "" "Asa numita viteza unealta tip \"plunge\".\n" "Aceasta este mișcarea lineara G01." -#: flatcamGUI/ObjectUI.py:931 flatcamGUI/ObjectUI.py:1560 -#: flatcamGUI/PreferencesUI.py:3319 flatcamGUI/PreferencesUI.py:4210 +#: flatcamGUI/ObjectUI.py:998 flatcamGUI/ObjectUI.py:1796 +#: flatcamGUI/PreferencesUI.py:3597 flatcamGUI/PreferencesUI.py:4503 msgid "Feedrate Rapids" msgstr "Feedrate rapizi" -#: flatcamGUI/ObjectUI.py:933 flatcamGUI/PreferencesUI.py:3321 +#: flatcamGUI/ObjectUI.py:1000 flatcamGUI/PreferencesUI.py:3599 msgid "" "Tool speed while drilling\n" "(in units per minute).\n" @@ -7856,12 +8207,26 @@ msgstr "" "printerul 3D Marlin, implicit când se foloseşte fişierul\n" "postprocesor: Marlin. Ignora aceasta parametru in rest." -#: flatcamGUI/ObjectUI.py:951 flatcamGUI/ObjectUI.py:1603 -#: flatcamGUI/PreferencesUI.py:4117 -msgid "Spindle speed" -msgstr "Viteza motor" +#: flatcamGUI/ObjectUI.py:1020 flatcamGUI/ObjectUI.py:1816 +#: flatcamGUI/PreferencesUI.py:4521 +msgid "Re-cut" +msgstr "Re-tăiere" -#: flatcamGUI/ObjectUI.py:953 flatcamGUI/PreferencesUI.py:3175 +#: flatcamGUI/ObjectUI.py:1022 flatcamGUI/ObjectUI.py:1035 +#: flatcamGUI/ObjectUI.py:1818 flatcamGUI/ObjectUI.py:1830 +#: flatcamGUI/PreferencesUI.py:4523 flatcamGUI/PreferencesUI.py:4535 +msgid "" +"In order to remove possible\n" +"copper leftovers where first cut\n" +"meet with last cut, we generate an\n" +"extended cut over the first cut section." +msgstr "" +"Bifează daca se dorește o siguranţă ca resturile de cupru\n" +"care pot ramane acolo unde se intalneste inceputul taierii\n" +"cu sfârşitul acesteia (este vorba de un contur), sunt eliminate\n" +"prin taierea peste acest punct." + +#: flatcamGUI/ObjectUI.py:1050 flatcamGUI/PreferencesUI.py:3442 msgid "" "Speed of the spindle\n" "in RPM (optional)" @@ -7871,8 +8236,8 @@ msgstr "" "Acest parametru este optional și se poate lasa gol\n" "daca nu se foloseşte." -#: flatcamGUI/ObjectUI.py:965 flatcamGUI/ObjectUI.py:1622 -#: flatcamGUI/PreferencesUI.py:3187 flatcamGUI/PreferencesUI.py:4135 +#: flatcamGUI/ObjectUI.py:1065 flatcamGUI/ObjectUI.py:1858 +#: flatcamGUI/PreferencesUI.py:3456 flatcamGUI/PreferencesUI.py:4427 msgid "" "Pause to allow the spindle to reach its\n" "speed before cutting." @@ -7880,26 +8245,115 @@ msgstr "" "O pauza care permite motorului să ajunga la turatia specificata,\n" "inainte de a incepe mișcarea spre poziţia de tăiere (găurire)." -#: flatcamGUI/ObjectUI.py:974 flatcamGUI/ObjectUI.py:1632 -#: flatcamGUI/PreferencesUI.py:3193 flatcamGUI/PreferencesUI.py:4140 +#: flatcamGUI/ObjectUI.py:1076 flatcamGUI/ObjectUI.py:1868 +#: flatcamGUI/PreferencesUI.py:3464 flatcamGUI/PreferencesUI.py:4432 msgid "Number of time units for spindle to dwell." msgstr "Timpul (ori secunde ori milisec) cat se stă in pauză." -#: flatcamGUI/ObjectUI.py:984 flatcamGUI/PreferencesUI.py:3206 -msgid "" -"The preprocessor JSON file that dictates\n" -"Gcode output." -msgstr "" -"Fișierul JSON postprocesor care dictează\n" -"codul Gcode." +#: flatcamGUI/ObjectUI.py:1086 flatcamGUI/PreferencesUI.py:3563 +msgid "Offset Z" +msgstr "Ofset Z" -#: flatcamGUI/ObjectUI.py:993 flatcamGUI/ObjectUI.py:1652 -#: flatcamGUI/PreferencesUI.py:3335 flatcamGUI/PreferencesUI.py:4251 +#: flatcamGUI/ObjectUI.py:1088 flatcamGUI/PreferencesUI.py:3565 +msgid "" +"Some drill bits (the larger ones) need to drill deeper\n" +"to create the desired exit hole diameter due of the tip shape.\n" +"The value here can compensate the Cut Z parameter." +msgstr "" +"Unele burghie (in special cele cu diametru mai mare)\n" +"au nevoie să găurească mai adanc pentru a depăși conul\n" +"din vârful burghiului astfel încât diametrul găurii de ieșire\n" +"să fie cel dorit.\n" +"Valoarea de aici efectuează o compensare asupra\n" +"parametrului >Z tăiere<." + +#: flatcamGUI/ObjectUI.py:1148 flatcamGUI/ObjectUI.py:1922 +#: flatcamTools/ToolNCC.py:492 flatcamTools/ToolPaint.py:423 +msgid "Apply parameters to all tools" +msgstr "Aplicați parametrii la toate Uneltele" + +#: flatcamGUI/ObjectUI.py:1150 flatcamGUI/ObjectUI.py:1924 +#: flatcamTools/ToolNCC.py:494 flatcamTools/ToolPaint.py:425 +msgid "" +"The parameters in the current form will be applied\n" +"on all the tools from the Tool Table." +msgstr "" +"Parametrii din formularul curent vor fi aplicați\n" +"la toate Uneltele din Tabelul Unelte." + +#: flatcamGUI/ObjectUI.py:1161 flatcamGUI/ObjectUI.py:1935 +#: flatcamTools/ToolNCC.py:505 flatcamTools/ToolPaint.py:436 +msgid "Common Parameters" +msgstr "Parametrii Comuni" + +#: flatcamGUI/ObjectUI.py:1163 flatcamGUI/ObjectUI.py:1937 +#: flatcamTools/ToolNCC.py:507 flatcamTools/ToolPaint.py:438 +msgid "Parameters that are common for all tools." +msgstr "Parametrii care sunt comuni pentru toate uneltele." + +#: flatcamGUI/ObjectUI.py:1168 flatcamGUI/ObjectUI.py:1942 +msgid "Tool change Z" +msgstr "Z schimb unealtă" + +#: flatcamGUI/ObjectUI.py:1170 flatcamGUI/PreferencesUI.py:3372 +msgid "" +"Include tool-change sequence\n" +"in G-Code (Pause for tool change)." +msgstr "" +"Include o secventa de schimbare unealtă\n" +"in codul G-Code (pauza pentru schimbare unealtă).\n" +"De obicei este folosita comanda G-Code M6." + +#: flatcamGUI/ObjectUI.py:1177 flatcamGUI/ObjectUI.py:1953 +#: flatcamGUI/PreferencesUI.py:3380 flatcamGUI/PreferencesUI.py:4327 +msgid "" +"Z-axis position (height) for\n" +"tool change." +msgstr "Înălţimea, pe axa Z, pentru schimbul uneltei." + +#: flatcamGUI/ObjectUI.py:1194 flatcamGUI/PreferencesUI.py:3588 +msgid "" +"Height of the tool just after start.\n" +"Delete the value if you don't need this feature." +msgstr "" +"Înălţimea uneltei imediat dupa ce se porneste operatia CNC.\n" +"Lasa casuta goala daca nu se foloseşte." + +#: flatcamGUI/ObjectUI.py:1203 flatcamGUI/ObjectUI.py:1981 +#: flatcamGUI/PreferencesUI.py:3396 flatcamGUI/PreferencesUI.py:4346 +msgid "End move Z" +msgstr "Z oprire" + +#: flatcamGUI/ObjectUI.py:1205 flatcamGUI/ObjectUI.py:1983 +#: flatcamGUI/PreferencesUI.py:3398 flatcamGUI/PreferencesUI.py:4348 +msgid "" +"Height of the tool after\n" +"the last move at the end of the job." +msgstr "Înălţimea la care se parchează freza dupa ce se termina lucrul." + +#: flatcamGUI/ObjectUI.py:1222 flatcamGUI/ObjectUI.py:2000 +#: flatcamGUI/PreferencesUI.py:3413 flatcamGUI/PreferencesUI.py:4366 +msgid "End move X,Y" +msgstr "X-Y Ultima miscare" + +#: flatcamGUI/ObjectUI.py:1224 flatcamGUI/ObjectUI.py:2002 +#: flatcamGUI/PreferencesUI.py:3415 flatcamGUI/PreferencesUI.py:4368 +msgid "" +"End move X,Y position. In format (x,y).\n" +"If no value is entered then there is no move\n" +"on X,Y plane at the end of the job." +msgstr "" +"Pozitia X-Y pt ultima miscare. In format (x,y).\n" +"Dacă nici-o valoare nu este introdusă atunci nici-o miscare nu va fi\n" +"efectuată la final." + +#: flatcamGUI/ObjectUI.py:1234 flatcamGUI/ObjectUI.py:1876 +#: flatcamGUI/PreferencesUI.py:3613 flatcamGUI/PreferencesUI.py:4544 msgid "Probe Z depth" msgstr "Z sonda" -#: flatcamGUI/ObjectUI.py:995 flatcamGUI/ObjectUI.py:1654 -#: flatcamGUI/PreferencesUI.py:3337 flatcamGUI/PreferencesUI.py:4253 +#: flatcamGUI/ObjectUI.py:1236 flatcamGUI/ObjectUI.py:1878 +#: flatcamGUI/PreferencesUI.py:3615 flatcamGUI/PreferencesUI.py:4546 msgid "" "The maximum depth that the probe is allowed\n" "to probe. Negative value, in current units." @@ -7907,47 +8361,71 @@ msgstr "" "Adâncimea maxima la care este permis sondei să coboare.\n" "Are o valoare negativă, in unitatile curente." -#: flatcamGUI/ObjectUI.py:1009 flatcamGUI/ObjectUI.py:1669 -#: flatcamGUI/PreferencesUI.py:3348 flatcamGUI/PreferencesUI.py:4266 +#: flatcamGUI/ObjectUI.py:1252 flatcamGUI/ObjectUI.py:1893 +#: flatcamGUI/PreferencesUI.py:3626 flatcamGUI/PreferencesUI.py:4559 msgid "Feedrate Probe" msgstr "Feedrate sonda" -#: flatcamGUI/ObjectUI.py:1011 flatcamGUI/ObjectUI.py:1671 -#: flatcamGUI/PreferencesUI.py:3350 flatcamGUI/PreferencesUI.py:4268 +#: flatcamGUI/ObjectUI.py:1254 flatcamGUI/ObjectUI.py:1895 +#: flatcamGUI/PreferencesUI.py:3628 flatcamGUI/PreferencesUI.py:4561 msgid "The feedrate used while the probe is probing." msgstr "Viteza sondei când aceasta coboara." -#: flatcamGUI/ObjectUI.py:1037 flatcamGUI/PreferencesUI.py:3215 -msgid "Gcode" -msgstr "Gcode" +#: flatcamGUI/ObjectUI.py:1261 +msgid "e_fr_probe" +msgstr "e_fr_probe" -#: flatcamGUI/ObjectUI.py:1039 +#: flatcamGUI/ObjectUI.py:1270 +msgid "Preprocessor E" +msgstr "Postprocesor E" + +#: flatcamGUI/ObjectUI.py:1272 msgid "" -"Choose what to use for GCode generation:\n" -"'Drills', 'Slots' or 'Both'.\n" -"When choosing 'Slots' or 'Both', slots will be\n" -"converted to a series of drills." +"The preprocessor JSON file that dictates\n" +"Gcode output for Excellon Objects." msgstr "" -"Alege ce să folosești pentru generarea de G-Code:\n" -"- Găuri\n" -"- Sloturi\n" -"- Ambele\n" -"Când se alege >Sloturi< sau >Ambele<, sloturile\n" -"vor fi convertite intr-o serie de găuriri." +"Fișierul JSON postprocesor care dictează\n" +"codul Gcode pentru obiectele Excellon." -#: flatcamGUI/ObjectUI.py:1053 -msgid "Create Drills GCode" -msgstr "Crează GCode Găuri" +#: flatcamGUI/ObjectUI.py:1282 +msgid "Preprocessor G" +msgstr "Postprocesor G" -#: flatcamGUI/ObjectUI.py:1055 -msgid "Generate the CNC Job." -msgstr "Generează un obiect CNCJob." +#: flatcamGUI/ObjectUI.py:1284 +msgid "" +"The preprocessor JSON file that dictates\n" +"Gcode output for Geometry (Milling) Objects." +msgstr "" +"Fișierul JSON postprocesor care dictează\n" +"codul Gcode pentru obiectele Geometrie (cand se frezează)." -#: flatcamGUI/ObjectUI.py:1066 flatcamGUI/PreferencesUI.py:3233 -msgid "Mill Holes" -msgstr "Frezare găuri" +#: flatcamGUI/ObjectUI.py:1308 flatcamGUI/ObjectUI.py:2026 +msgid "" +"Add / Select at least one tool in the tool-table.\n" +"Click the # header to select all, or Ctrl + LMB\n" +"for custom selection of tools." +msgstr "" +"Adaugă/selectează cel puțin o unealtă in Tabela de Unelte.\n" +"Click pe header coloana # pentru selectarea a toate sau CTRL + LMB click\n" +"pentru o selecţie personalizată de unelte." -#: flatcamGUI/ObjectUI.py:1068 +#: flatcamGUI/ObjectUI.py:1316 flatcamGUI/ObjectUI.py:2033 +msgid "Generate CNCJob object" +msgstr "Generează un obiect CNCJob" + +#: flatcamGUI/ObjectUI.py:1318 +msgid "" +"Generate the CNC Job.\n" +"If milling then an additional Geometry object will be created" +msgstr "" +"Generează obiectul CNCJob.\n" +"Dacă se frezează atunci va fi creat un obiect Geometrie additional" + +#: flatcamGUI/ObjectUI.py:1335 +msgid "Milling Geometry" +msgstr "Geometrie Frezare" + +#: flatcamGUI/ObjectUI.py:1337 msgid "" "Create Geometry for milling holes.\n" "Select from the Tools Table above the hole dias to be\n" @@ -7957,20 +8435,16 @@ msgstr "" "Selectați din tabelul Unelte de deasupra găurile\n" "care trebuie frezate. Utilizați coloana # pentru a face selecția." -#: flatcamGUI/ObjectUI.py:1074 flatcamGUI/PreferencesUI.py:3239 -msgid "Drill Tool dia" -msgstr "Dia. Burghiu Găurire" - -#: flatcamGUI/ObjectUI.py:1076 flatcamGUI/PreferencesUI.py:2027 -#: flatcamGUI/PreferencesUI.py:3241 +#: flatcamGUI/ObjectUI.py:1345 flatcamGUI/PreferencesUI.py:2207 +#: flatcamGUI/PreferencesUI.py:3514 msgid "Diameter of the cutting tool." msgstr "Diametrul uneltei taietoare." -#: flatcamGUI/ObjectUI.py:1083 -msgid "Mill Drills Geo" -msgstr "Geo pt frezare găuri" +#: flatcamGUI/ObjectUI.py:1355 +msgid "Mill Drills" +msgstr "Frezare Găuri" -#: flatcamGUI/ObjectUI.py:1085 +#: flatcamGUI/ObjectUI.py:1357 msgid "" "Create the Geometry Object\n" "for milling DRILLS toolpaths." @@ -7978,21 +8452,11 @@ msgstr "" "Crează un obiect tip Geometrie pt.\n" "frezarea rutelor create din Găuri." -#: flatcamGUI/ObjectUI.py:1099 flatcamGUI/PreferencesUI.py:3250 -msgid "Slot Tool dia" -msgstr "Dia. Freza Slot" +#: flatcamGUI/ObjectUI.py:1375 +msgid "Mill Slots" +msgstr "Frezare Sloturi" -#: flatcamGUI/ObjectUI.py:1101 flatcamGUI/PreferencesUI.py:3252 -msgid "" -"Diameter of the cutting tool\n" -"when milling slots." -msgstr "Diametrul frezei când se frezează sloturile." - -#: flatcamGUI/ObjectUI.py:1110 -msgid "Mill Slots Geo" -msgstr "Geo pt. frezare sloturi" - -#: flatcamGUI/ObjectUI.py:1112 +#: flatcamGUI/ObjectUI.py:1377 msgid "" "Create the Geometry Object\n" "for milling SLOTS toolpaths." @@ -8000,11 +8464,11 @@ msgstr "" "Crează un obiect tip Geometrie pt.\n" "frezarea rutelor create din Sloturi." -#: flatcamGUI/ObjectUI.py:1152 flatcamTools/ToolCutOut.py:317 +#: flatcamGUI/ObjectUI.py:1419 flatcamTools/ToolCutOut.py:327 msgid "Geometry Object" msgstr "Obiect Geometrie" -#: flatcamGUI/ObjectUI.py:1186 +#: flatcamGUI/ObjectUI.py:1465 msgid "" "Tools in this Geometry object used for cutting.\n" "The 'Offset' entry will set an offset for the cut.\n" @@ -8034,23 +8498,23 @@ msgstr "" "- V-Dia \n" "- V-unghi." -#: flatcamGUI/ObjectUI.py:1203 flatcamGUI/ObjectUI.py:1903 -#: flatcamGUI/PreferencesUI.py:4405 +#: flatcamGUI/ObjectUI.py:1482 flatcamGUI/ObjectUI.py:2231 +#: flatcamGUI/PreferencesUI.py:4698 msgid "Plot Object" msgstr "Afisează" -#: flatcamGUI/ObjectUI.py:1217 flatcamGUI/ObjectUI.py:1916 -#: flatcamGUI/ObjectUI.py:1926 flatcamGUI/PreferencesUI.py:7241 -#: flatcamTools/ToolCopperThieving.py:220 +#: flatcamGUI/ObjectUI.py:1495 flatcamGUI/ObjectUI.py:2244 +#: flatcamGUI/ObjectUI.py:2254 flatcamGUI/PreferencesUI.py:7747 +#: flatcamTools/ToolCopperThieving.py:222 msgid "Dia" msgstr "Dia" -#: flatcamGUI/ObjectUI.py:1217 flatcamGUI/ObjectUI.py:1916 -#: flatcamTools/ToolNonCopperClear.py:120 flatcamTools/ToolPaint.py:123 +#: flatcamGUI/ObjectUI.py:1495 flatcamGUI/ObjectUI.py:2244 +#: flatcamTools/ToolNCC.py:132 flatcamTools/ToolPaint.py:128 msgid "TT" msgstr "TU" -#: flatcamGUI/ObjectUI.py:1224 +#: flatcamGUI/ObjectUI.py:1502 msgid "" "This is the Tool Number.\n" "When ToolChange is checked, on toolchange event this value\n" @@ -8061,7 +8525,7 @@ msgstr "" "la evenim. de schimb unealtă, va aparea sub forma T1, T2, etc\n" "in codul masina CNC" -#: flatcamGUI/ObjectUI.py:1235 +#: flatcamGUI/ObjectUI.py:1513 msgid "" "The value for the Offset can be:\n" "- Path -> There is no offset, the tool cut will be done through the geometry " @@ -8077,7 +8541,7 @@ msgstr "" "'buzunar'\n" "- Afară-> Tăietura va urma geometria pe exterior." -#: flatcamGUI/ObjectUI.py:1242 +#: flatcamGUI/ObjectUI.py:1520 msgid "" "The (Operation) Type has only informative value. Usually the UI form " "values \n" @@ -8100,7 +8564,7 @@ msgstr "" "un\n" "vârf fin, ascuțit." -#: flatcamGUI/ObjectUI.py:1251 +#: flatcamGUI/ObjectUI.py:1529 msgid "" "The Tool Type (TT) can be:\n" "- Circular with 1 ... 4 teeth -> it is informative only. Being circular the " @@ -8130,7 +8594,7 @@ msgstr "" "Alegerea tipului V-Shape (forma in V) va selecta automat Tipul de Operaţie " "ca Izolare." -#: flatcamGUI/ObjectUI.py:1263 +#: flatcamGUI/ObjectUI.py:1541 msgid "" "Plot column. It is visible only for MultiGeo geometries, meaning geometries " "that holds the geometry\n" @@ -8150,7 +8614,7 @@ msgstr "" "se poate activa/dezactiva\n" "afișarea in canvas." -#: flatcamGUI/ObjectUI.py:1281 +#: flatcamGUI/ObjectUI.py:1559 msgid "" "The value to offset the cut when \n" "the Offset type selected is 'Offset'.\n" @@ -8161,7 +8625,13 @@ msgstr "" "este >Ofset<. Aceasta valoare poate fi pozitivă pentru un ofset\n" "in exterior sau poate fi negativă pentru un ofset in interior." -#: flatcamGUI/ObjectUI.py:1306 +#: flatcamGUI/ObjectUI.py:1578 flatcamTools/ToolNCC.py:209 +#: flatcamTools/ToolNCC.py:921 flatcamTools/ToolPaint.py:192 +#: flatcamTools/ToolPaint.py:846 flatcamTools/ToolSolderPaste.py:559 +msgid "New Tool" +msgstr "O Noua Unealtă" + +#: flatcamGUI/ObjectUI.py:1595 msgid "" "Add a new tool to the Tool Table\n" "with the specified diameter." @@ -8169,11 +8639,14 @@ msgstr "" "Adăugați o Unealta noua in Tabelul de Unelte\n" "cu diametrul specificat." -#: flatcamGUI/ObjectUI.py:1314 -msgid "Add Tool from DataBase" -msgstr "Adăugați Unealta din DB Unelte" +#: flatcamGUI/ObjectUI.py:1600 flatcamTools/ToolNCC.py:300 +#: flatcamTools/ToolNCC.py:634 flatcamTools/ToolPaint.py:283 +#: flatcamTools/ToolPaint.py:676 +msgid "Add from DB" +msgstr "Adaugă Unealtă din DB" -#: flatcamGUI/ObjectUI.py:1316 +#: flatcamGUI/ObjectUI.py:1602 flatcamTools/ToolNCC.py:302 +#: flatcamTools/ToolPaint.py:285 msgid "" "Add a new tool to the Tool Table\n" "from the Tool DataBase." @@ -8181,7 +8654,7 @@ msgstr "" "Adaugă o noua unealta in Tabela de Unelte,\n" "din DB Unelte." -#: flatcamGUI/ObjectUI.py:1326 +#: flatcamGUI/ObjectUI.py:1617 msgid "" "Copy a selection of tools in the Tool Table\n" "by first selecting a row in the Tool Table." @@ -8189,7 +8662,7 @@ msgstr "" "Copiază o selecţie de unelte in Tabela de Unelte prin\n" "selectarea unei linii (sau mai multe) in Tabela de Unelte." -#: flatcamGUI/ObjectUI.py:1332 +#: flatcamGUI/ObjectUI.py:1623 msgid "" "Delete a selection of tools in the Tool Table\n" "by first selecting a row in the Tool Table." @@ -8197,40 +8670,7 @@ msgstr "" "Șterge o selecţie de unelte in Tabela de Unelte prin\n" "selectarea unei linii (sau mai multe) in Tabela de Unelte." -#: flatcamGUI/ObjectUI.py:1356 -msgid "" -"The data used for creating GCode.\n" -"Each tool store it's own set of such data." -msgstr "" -"Datele folosite pentru crearea codului GCode.\n" -"Fiecare unealtă stochează un subset de asemenea date." - -#: flatcamGUI/ObjectUI.py:1426 flatcamGUI/PreferencesUI.py:3981 -#: flatcamGUI/PreferencesUI.py:5348 flatcamTools/ToolCutOut.py:153 -msgid "Multi-Depth" -msgstr "Multi-Pas" - -#: flatcamGUI/ObjectUI.py:1429 flatcamGUI/PreferencesUI.py:3984 -#: flatcamGUI/PreferencesUI.py:5351 flatcamTools/ToolCutOut.py:156 -msgid "" -"Use multiple passes to limit\n" -"the cut depth in each pass. Will\n" -"cut multiple times until Cut Z is\n" -"reached." -msgstr "" -"Folosiți mai multe pase pentru a limita\n" -"adâncimea tăiată în fiecare trecere. Se\n" -"va tăia de mai multe ori până când este\n" -"atins Z de tăiere, Z Cut." - -#: flatcamGUI/ObjectUI.py:1443 flatcamGUI/PreferencesUI.py:5363 -#: flatcamTools/ToolCutOut.py:170 -msgid "Depth of each pass (positive)." -msgstr "" -"Adâncimea pentru fiecare trecere.\n" -"Valoare pozitivă, in unitatile curente." - -#: flatcamGUI/ObjectUI.py:1454 flatcamGUI/PreferencesUI.py:4016 +#: flatcamGUI/ObjectUI.py:1750 flatcamGUI/PreferencesUI.py:4296 msgid "" "Height of the tool when\n" "moving without cutting." @@ -8238,29 +8678,7 @@ msgstr "" "Înălţimea la care se misca unealta când nu taie,\n" "deasupra materialului." -#: flatcamGUI/ObjectUI.py:1481 flatcamGUI/PreferencesUI.py:4037 -msgid "" -"Include tool-change sequence\n" -"in the Machine Code (Pause for tool change)." -msgstr "" -"Include o secventa de schimb unealtă in \n" -"codul masina CNC. O pauza pentru schimbul\n" -"uneltei (M6)." - -#: flatcamGUI/ObjectUI.py:1531 flatcamGUI/PreferencesUI.py:4086 -#: flatcamGUI/PreferencesUI.py:6553 flatcamTools/ToolSolderPaste.py:252 -msgid "Feedrate X-Y" -msgstr "Feedrate X-Y" - -#: flatcamGUI/ObjectUI.py:1533 flatcamGUI/PreferencesUI.py:4088 -msgid "" -"Cutting speed in the XY\n" -"plane in units per minute" -msgstr "" -"Viteza de tăiere in planul X-Y\n" -"in unitati pe minut" - -#: flatcamGUI/ObjectUI.py:1547 flatcamGUI/PreferencesUI.py:4103 +#: flatcamGUI/ObjectUI.py:1783 flatcamGUI/PreferencesUI.py:4395 msgid "" "Cutting speed in the XY\n" "plane in units per minute.\n" @@ -8270,7 +8688,7 @@ msgstr "" "in unitati pe minut.\n" "Mai este numita și viteza de plonjare." -#: flatcamGUI/ObjectUI.py:1562 flatcamGUI/PreferencesUI.py:4212 +#: flatcamGUI/ObjectUI.py:1798 flatcamGUI/PreferencesUI.py:4505 msgid "" "Cutting speed in the XY plane\n" "(in units per minute).\n" @@ -8283,24 +8701,7 @@ msgstr "" "Este utila doar când se foloseşte cu un printer 3D Marlin,\n" "pentru toate celelalte cazuri ignora acest parametru." -#: flatcamGUI/ObjectUI.py:1580 flatcamGUI/PreferencesUI.py:4228 -msgid "Re-cut" -msgstr "Re-tăiere" - -#: flatcamGUI/ObjectUI.py:1582 flatcamGUI/ObjectUI.py:1594 -#: flatcamGUI/PreferencesUI.py:4230 flatcamGUI/PreferencesUI.py:4242 -msgid "" -"In order to remove possible\n" -"copper leftovers where first cut\n" -"meet with last cut, we generate an\n" -"extended cut over the first cut section." -msgstr "" -"Bifează daca se dorește o siguranţă ca resturile de cupru\n" -"care pot ramane acolo unde se intalneste inceputul taierii\n" -"cu sfârşitul acesteia (este vorba de un contur), sunt eliminate\n" -"prin taierea peste acest punct." - -#: flatcamGUI/ObjectUI.py:1606 flatcamGUI/PreferencesUI.py:4120 +#: flatcamGUI/ObjectUI.py:1842 flatcamGUI/PreferencesUI.py:4412 msgid "" "Speed of the spindle in RPM (optional).\n" "If LASER preprocessor is used,\n" @@ -8310,7 +8711,16 @@ msgstr "" "Daca postprocesorul Laser este folosit,\n" "valoarea să este puterea laserului." -#: flatcamGUI/ObjectUI.py:1642 flatcamGUI/PreferencesUI.py:4157 +#: flatcamGUI/ObjectUI.py:1945 flatcamGUI/PreferencesUI.py:4317 +msgid "" +"Include tool-change sequence\n" +"in the Machine Code (Pause for tool change)." +msgstr "" +"Include o secventa de schimb unealtă in \n" +"codul masina CNC. O pauza pentru schimbul\n" +"uneltei (M6)." + +#: flatcamGUI/ObjectUI.py:2014 flatcamGUI/PreferencesUI.py:4449 msgid "" "The Preprocessor file that dictates\n" "the Machine Code (like GCode, RML, HPGL) output." @@ -8319,43 +8729,17 @@ msgstr "" "codului masina CNC (GCode, RML, HPGL) care \n" "mai apoi este salvat." -#: flatcamGUI/ObjectUI.py:1689 -msgid "Apply parameters to all tools" -msgstr "Aplicați parametrii la toate Uneltele" - -#: flatcamGUI/ObjectUI.py:1691 -msgid "" -"The parameters in the current form will be applied\n" -"on all the tools from the Tool Table." -msgstr "" -"Parametrii din formularul curent vor fi aplicați\n" -"la toate Uneltele din Tabelul Unelte." - -#: flatcamGUI/ObjectUI.py:1700 -msgid "" -"Add at least one tool in the tool-table.\n" -"Click the header to select all, or Ctrl + LMB\n" -"for custom selection of tools." -msgstr "" -"Adaugă cel puțin o unealtă in Tabela de Unelte.\n" -"Click pe header pentru selectarea tuturora asu CTRL + LMB click\n" -"pentru o selecţie personalizata de unelte." - -#: flatcamGUI/ObjectUI.py:1707 -msgid "Generate CNCJob object" -msgstr "Generează un obiect CNCJob" - -#: flatcamGUI/ObjectUI.py:1709 +#: flatcamGUI/ObjectUI.py:2035 msgid "Generate the CNC Job object." msgstr "Generează un obiect CNCJob." -#: flatcamGUI/ObjectUI.py:1726 +#: flatcamGUI/ObjectUI.py:2052 msgid "Launch Paint Tool in Tools Tab." msgstr "" "Lansează unealta FlatCAM numita Paint și\n" "o instalează in Tab-ul Unealta." -#: flatcamGUI/ObjectUI.py:1734 flatcamGUI/PreferencesUI.py:5524 +#: flatcamGUI/ObjectUI.py:2060 flatcamGUI/PreferencesUI.py:5874 msgid "" "Creates tool paths to cover the\n" "whole area of a polygon (remove\n" @@ -8368,15 +8752,15 @@ msgstr "" "singur poligon se va cere să faceti click pe poligonul\n" "dorit." -#: flatcamGUI/ObjectUI.py:1786 +#: flatcamGUI/ObjectUI.py:2115 msgid "CNC Job Object" msgstr "Obiect CNCJob" -#: flatcamGUI/ObjectUI.py:1798 flatcamGUI/PreferencesUI.py:4410 +#: flatcamGUI/ObjectUI.py:2126 flatcamGUI/PreferencesUI.py:4703 msgid "Plot kind" msgstr "Tip afișare" -#: flatcamGUI/ObjectUI.py:1801 flatcamGUI/PreferencesUI.py:4412 +#: flatcamGUI/ObjectUI.py:2129 flatcamGUI/PreferencesUI.py:4705 msgid "" "This selects the kind of geometries on the canvas to plot.\n" "Those can be either of type 'Travel' which means the moves\n" @@ -8388,15 +8772,15 @@ msgstr "" "- Voiaj -> miscarile deasupra materialului\n" "- Tăiere -> miscarile in material, tăiere." -#: flatcamGUI/ObjectUI.py:1810 flatcamGUI/PreferencesUI.py:4420 +#: flatcamGUI/ObjectUI.py:2138 flatcamGUI/PreferencesUI.py:4713 msgid "Travel" msgstr "Voiaj" -#: flatcamGUI/ObjectUI.py:1814 flatcamGUI/PreferencesUI.py:4429 +#: flatcamGUI/ObjectUI.py:2142 flatcamGUI/PreferencesUI.py:4722 msgid "Display Annotation" msgstr "Afişează notații" -#: flatcamGUI/ObjectUI.py:1816 flatcamGUI/PreferencesUI.py:4431 +#: flatcamGUI/ObjectUI.py:2144 flatcamGUI/PreferencesUI.py:4724 msgid "" "This selects if to display text annotation on the plot.\n" "When checked it will display numbers in order for each end\n" @@ -8406,11 +8790,11 @@ msgstr "" "Cand este selectat va afisa numerele in ordine pt fiecare\n" "capat al liniilor de traversare." -#: flatcamGUI/ObjectUI.py:1831 +#: flatcamGUI/ObjectUI.py:2159 msgid "Travelled dist." msgstr "Dist. parcursă" -#: flatcamGUI/ObjectUI.py:1833 flatcamGUI/ObjectUI.py:1838 +#: flatcamGUI/ObjectUI.py:2161 flatcamGUI/ObjectUI.py:2166 msgid "" "This is the total travelled distance on X-Y plane.\n" "In current units." @@ -8418,11 +8802,11 @@ msgstr "" "Aceasta este distanţa totala parcursa in planul X-Y.\n" "In unitatile curente." -#: flatcamGUI/ObjectUI.py:1843 +#: flatcamGUI/ObjectUI.py:2171 msgid "Estimated time" msgstr "Durată estimată" -#: flatcamGUI/ObjectUI.py:1845 flatcamGUI/ObjectUI.py:1850 +#: flatcamGUI/ObjectUI.py:2173 flatcamGUI/ObjectUI.py:2178 msgid "" "This is the estimated time to do the routing/drilling,\n" "without the time spent in ToolChange events." @@ -8430,11 +8814,11 @@ msgstr "" "Acesta este timpul estimat pentru efectuarea traseului / găuririi,\n" "fără timpul petrecut în evenimentele ToolChange." -#: flatcamGUI/ObjectUI.py:1885 +#: flatcamGUI/ObjectUI.py:2213 msgid "CNC Tools Table" msgstr "Tabela Unelte CNC" -#: flatcamGUI/ObjectUI.py:1888 +#: flatcamGUI/ObjectUI.py:2216 msgid "" "Tools in this CNCJob object used for cutting.\n" "The tool diameter is used for plotting on canvas.\n" @@ -8455,24 +8839,24 @@ msgstr "" "Shape\n" "(cu forma in V)." -#: flatcamGUI/ObjectUI.py:1916 flatcamGUI/ObjectUI.py:1927 +#: flatcamGUI/ObjectUI.py:2244 flatcamGUI/ObjectUI.py:2255 msgid "P" msgstr "P" -#: flatcamGUI/ObjectUI.py:1937 +#: flatcamGUI/ObjectUI.py:2265 msgid "Update Plot" msgstr "Actualiz. afișare" -#: flatcamGUI/ObjectUI.py:1939 +#: flatcamGUI/ObjectUI.py:2267 msgid "Update the plot." msgstr "Actualizează afișarea obiectelor." -#: flatcamGUI/ObjectUI.py:1946 flatcamGUI/PreferencesUI.py:4827 +#: flatcamGUI/ObjectUI.py:2274 flatcamGUI/PreferencesUI.py:5120 msgid "Export CNC Code" msgstr "Exporta codul masina CNC" -#: flatcamGUI/ObjectUI.py:1948 flatcamGUI/PreferencesUI.py:4768 -#: flatcamGUI/PreferencesUI.py:4829 +#: flatcamGUI/ObjectUI.py:2276 flatcamGUI/PreferencesUI.py:5061 +#: flatcamGUI/PreferencesUI.py:5122 msgid "" "Export and save G-Code to\n" "make this object to a file." @@ -8480,12 +8864,12 @@ msgstr "" "Exportă și salvează codul G-Code intr-un fişier\n" "care este salvat pe HDD." -#: flatcamGUI/ObjectUI.py:1954 +#: flatcamGUI/ObjectUI.py:2282 msgid "Prepend to CNC Code" msgstr "Adaugă la inceput in codul G-Code" -#: flatcamGUI/ObjectUI.py:1956 flatcamGUI/ObjectUI.py:1963 -#: flatcamGUI/PreferencesUI.py:4784 +#: flatcamGUI/ObjectUI.py:2284 flatcamGUI/ObjectUI.py:2291 +#: flatcamGUI/PreferencesUI.py:5077 msgid "" "Type here any G-Code commands you would\n" "like to add at the beginning of the G-Code file." @@ -8493,12 +8877,12 @@ msgstr "" "Adaugă aici orice comenzi G-Code care se dorește să fie\n" "inserate la inceputul codului G-Code." -#: flatcamGUI/ObjectUI.py:1969 +#: flatcamGUI/ObjectUI.py:2297 msgid "Append to CNC Code" msgstr "Adaugă la sfârşit in codul G-Code" -#: flatcamGUI/ObjectUI.py:1971 flatcamGUI/ObjectUI.py:1979 -#: flatcamGUI/PreferencesUI.py:4800 +#: flatcamGUI/ObjectUI.py:2299 flatcamGUI/ObjectUI.py:2307 +#: flatcamGUI/PreferencesUI.py:5093 msgid "" "Type here any G-Code commands you would\n" "like to append to the generated file.\n" @@ -8507,11 +8891,11 @@ msgstr "" "Adaugă aici orice comenzi G-Code care se dorește să fie\n" "inserate la sfârşitul codului G-Code." -#: flatcamGUI/ObjectUI.py:1993 flatcamGUI/PreferencesUI.py:4835 +#: flatcamGUI/ObjectUI.py:2321 flatcamGUI/PreferencesUI.py:5128 msgid "Toolchange G-Code" msgstr "G-Code pt schimb unealtă" -#: flatcamGUI/ObjectUI.py:1996 flatcamGUI/PreferencesUI.py:4838 +#: flatcamGUI/ObjectUI.py:2324 flatcamGUI/PreferencesUI.py:5131 msgid "" "Type here any G-Code commands you would\n" "like to be executed when Toolchange event is encountered.\n" @@ -8533,7 +8917,7 @@ msgstr "" "'toolchange_custom'\n" "in numele sau." -#: flatcamGUI/ObjectUI.py:2011 +#: flatcamGUI/ObjectUI.py:2339 msgid "" "Type here any G-Code commands you would\n" "like to be executed when Toolchange event is encountered.\n" @@ -8552,11 +8936,11 @@ msgstr "" "'toolchange_custom'\n" "in numele sau." -#: flatcamGUI/ObjectUI.py:2026 flatcamGUI/PreferencesUI.py:4877 +#: flatcamGUI/ObjectUI.py:2354 flatcamGUI/PreferencesUI.py:5170 msgid "Use Toolchange Macro" msgstr "Fol. Macro schimb unealtă" -#: flatcamGUI/ObjectUI.py:2028 flatcamGUI/PreferencesUI.py:4879 +#: flatcamGUI/ObjectUI.py:2356 flatcamGUI/PreferencesUI.py:5172 msgid "" "Check this box if you want to use\n" "a Custom Toolchange GCode (macro)." @@ -8564,7 +8948,7 @@ msgstr "" "Bifează aici daca dorești să folosești Macro pentru\n" "schimb unelte." -#: flatcamGUI/ObjectUI.py:2036 flatcamGUI/PreferencesUI.py:4891 +#: flatcamGUI/ObjectUI.py:2364 flatcamGUI/PreferencesUI.py:5184 msgid "" "A list of the FlatCAM variables that can be used\n" "in the Toolchange event.\n" @@ -8574,73 +8958,75 @@ msgstr "" "de schimb al uneltei (când se intalneste comanda M6).\n" "Este necesar să fie inconjurate de simbolul '%'" -#: flatcamGUI/ObjectUI.py:2043 flatcamGUI/PreferencesUI.py:2447 -#: flatcamGUI/PreferencesUI.py:3555 flatcamGUI/PreferencesUI.py:4347 -#: flatcamGUI/PreferencesUI.py:4898 flatcamGUI/PreferencesUI.py:5017 -#: flatcamGUI/PreferencesUI.py:5301 flatcamGUI/PreferencesUI.py:5458 -#: flatcamGUI/PreferencesUI.py:5676 flatcamGUI/PreferencesUI.py:5973 -#: flatcamGUI/PreferencesUI.py:6224 flatcamGUI/PreferencesUI.py:6438 -#: flatcamGUI/PreferencesUI.py:6663 flatcamGUI/PreferencesUI.py:6685 -#: flatcamGUI/PreferencesUI.py:6909 flatcamGUI/PreferencesUI.py:6946 -#: flatcamGUI/PreferencesUI.py:7140 flatcamGUI/PreferencesUI.py:7394 -#: flatcamGUI/PreferencesUI.py:7510 flatcamTools/ToolCopperThieving.py:89 -#: flatcamTools/ToolFiducials.py:149 flatcamTools/ToolNonCopperClear.py:315 +#: flatcamGUI/ObjectUI.py:2371 flatcamGUI/PreferencesUI.py:2627 +#: flatcamGUI/PreferencesUI.py:3833 flatcamGUI/PreferencesUI.py:4640 +#: flatcamGUI/PreferencesUI.py:5191 flatcamGUI/PreferencesUI.py:5310 +#: flatcamGUI/PreferencesUI.py:5640 flatcamGUI/PreferencesUI.py:5797 +#: flatcamGUI/PreferencesUI.py:6164 flatcamGUI/PreferencesUI.py:6461 +#: flatcamGUI/PreferencesUI.py:6711 flatcamGUI/PreferencesUI.py:6942 +#: flatcamGUI/PreferencesUI.py:7169 flatcamGUI/PreferencesUI.py:7191 +#: flatcamGUI/PreferencesUI.py:7415 flatcamGUI/PreferencesUI.py:7452 +#: flatcamGUI/PreferencesUI.py:7646 flatcamGUI/PreferencesUI.py:7900 +#: flatcamGUI/PreferencesUI.py:8016 flatcamGUI/PreferencesUI.py:8135 +#: flatcamGUI/PreferencesUI.py:8347 flatcamGUI/PreferencesUI.py:8556 +#: flatcamTools/ToolCopperThieving.py:90 flatcamTools/ToolFiducials.py:149 +#: flatcamTools/ToolInvertGerber.py:82 msgid "Parameters" msgstr "Parametri" -#: flatcamGUI/ObjectUI.py:2046 flatcamGUI/PreferencesUI.py:4903 +#: flatcamGUI/ObjectUI.py:2374 flatcamGUI/PreferencesUI.py:5196 msgid "FlatCAM CNC parameters" msgstr "Parametri FlatCAM CNC" -#: flatcamGUI/ObjectUI.py:2047 flatcamGUI/PreferencesUI.py:4908 +#: flatcamGUI/ObjectUI.py:2375 flatcamGUI/PreferencesUI.py:5201 msgid "tool number" msgstr "numărul uneltei" -#: flatcamGUI/ObjectUI.py:2048 flatcamGUI/PreferencesUI.py:4909 +#: flatcamGUI/ObjectUI.py:2376 flatcamGUI/PreferencesUI.py:5202 msgid "tool diameter" msgstr "diametrul sculei" -#: flatcamGUI/ObjectUI.py:2049 flatcamGUI/PreferencesUI.py:4910 +#: flatcamGUI/ObjectUI.py:2377 flatcamGUI/PreferencesUI.py:5203 msgid "for Excellon, total number of drills" msgstr "pentru Excellon, numărul total de operațiuni găurire" -#: flatcamGUI/ObjectUI.py:2051 flatcamGUI/PreferencesUI.py:4912 +#: flatcamGUI/ObjectUI.py:2379 flatcamGUI/PreferencesUI.py:5205 msgid "X coord for Toolchange" msgstr "Coordonata X pentru schimbarea uneltei" -#: flatcamGUI/ObjectUI.py:2052 flatcamGUI/PreferencesUI.py:4913 +#: flatcamGUI/ObjectUI.py:2380 flatcamGUI/PreferencesUI.py:5206 msgid "Y coord for Toolchange" msgstr "Coordonata Y pentru schimbarea uneltei" -#: flatcamGUI/ObjectUI.py:2053 flatcamGUI/PreferencesUI.py:4915 +#: flatcamGUI/ObjectUI.py:2381 flatcamGUI/PreferencesUI.py:5208 msgid "Z coord for Toolchange" msgstr "Coordonata Z pentru schimbarea uneltei" -#: flatcamGUI/ObjectUI.py:2054 +#: flatcamGUI/ObjectUI.py:2382 msgid "depth where to cut" msgstr "adâncimea de tăiere" -#: flatcamGUI/ObjectUI.py:2055 +#: flatcamGUI/ObjectUI.py:2383 msgid "height where to travel" msgstr "inălţimea deplasare" -#: flatcamGUI/ObjectUI.py:2056 flatcamGUI/PreferencesUI.py:4918 +#: flatcamGUI/ObjectUI.py:2384 flatcamGUI/PreferencesUI.py:5211 msgid "the step value for multidepth cut" msgstr "pasul pentru taierea progresiva" -#: flatcamGUI/ObjectUI.py:2058 flatcamGUI/PreferencesUI.py:4920 +#: flatcamGUI/ObjectUI.py:2386 flatcamGUI/PreferencesUI.py:5213 msgid "the value for the spindle speed" msgstr "valoarea viteza motor" -#: flatcamGUI/ObjectUI.py:2060 +#: flatcamGUI/ObjectUI.py:2388 msgid "time to dwell to allow the spindle to reach it's set RPM" msgstr "durata de asteptare ca motorul să ajunga la turatia setată" -#: flatcamGUI/ObjectUI.py:2076 +#: flatcamGUI/ObjectUI.py:2404 msgid "View CNC Code" msgstr "Vizualiz. codul CNC" -#: flatcamGUI/ObjectUI.py:2078 +#: flatcamGUI/ObjectUI.py:2406 msgid "" "Opens TAB to view/modify/print G-Code\n" "file." @@ -8648,11 +9034,11 @@ msgstr "" "Deschide un nou tab pentru a vizualiza, modifica\n" "sau tipari codul G-Code." -#: flatcamGUI/ObjectUI.py:2083 +#: flatcamGUI/ObjectUI.py:2411 msgid "Save CNC Code" msgstr "Salvează codul CNC" -#: flatcamGUI/ObjectUI.py:2085 +#: flatcamGUI/ObjectUI.py:2413 msgid "" "Opens dialog to save G-Code\n" "file." @@ -8660,83 +9046,79 @@ msgstr "" "Deshide o fereastra dialog pentru salvarea codului\n" "G-Code intr-un fişier." -#: flatcamGUI/ObjectUI.py:2116 +#: flatcamGUI/ObjectUI.py:2447 msgid "Script Object" msgstr "Editare Script" -#: flatcamGUI/ObjectUI.py:2138 flatcamGUI/ObjectUI.py:2211 +#: flatcamGUI/ObjectUI.py:2467 flatcamGUI/ObjectUI.py:2541 msgid "Auto Completer" msgstr "Autocompletare" -#: flatcamGUI/ObjectUI.py:2140 +#: flatcamGUI/ObjectUI.py:2469 msgid "This selects if the auto completer is enabled in the Script Editor." msgstr "" "Aceasta selectează dacă completatorul automat este activat în Script Editor." -#: flatcamGUI/ObjectUI.py:2182 +#: flatcamGUI/ObjectUI.py:2514 msgid "Document Object" msgstr "Obiect document" -#: flatcamGUI/ObjectUI.py:2213 +#: flatcamGUI/ObjectUI.py:2543 msgid "This selects if the auto completer is enabled in the Document Editor." msgstr "" "Aceasta selectează dacă completatorul automat este activat în Editorul de " "documente." -#: flatcamGUI/ObjectUI.py:2231 +#: flatcamGUI/ObjectUI.py:2561 msgid "Font Type" msgstr "Tipul Font" -#: flatcamGUI/ObjectUI.py:2248 flatcamGUI/PreferencesUI.py:1103 +#: flatcamGUI/ObjectUI.py:2578 flatcamGUI/PreferencesUI.py:1278 msgid "Font Size" msgstr "Dim. Font" -#: flatcamGUI/ObjectUI.py:2284 +#: flatcamGUI/ObjectUI.py:2614 msgid "Alignment" msgstr "Aliniere" -#: flatcamGUI/ObjectUI.py:2289 +#: flatcamGUI/ObjectUI.py:2619 msgid "Align Left" msgstr "Aliniați la stânga" -#: flatcamGUI/ObjectUI.py:2294 -msgid "Center" -msgstr "Centru" - -#: flatcamGUI/ObjectUI.py:2299 +#: flatcamGUI/ObjectUI.py:2629 msgid "Align Right" msgstr "Aliniați la dreapta" -#: flatcamGUI/ObjectUI.py:2304 +#: flatcamGUI/ObjectUI.py:2634 msgid "Justify" msgstr "Aliniere duala" -#: flatcamGUI/ObjectUI.py:2311 +#: flatcamGUI/ObjectUI.py:2641 msgid "Font Color" msgstr "Culoare FOnt" -#: flatcamGUI/ObjectUI.py:2313 +#: flatcamGUI/ObjectUI.py:2643 msgid "Set the font color for the selected text" msgstr "Setați culoarea fontului pentru textul selectat" -#: flatcamGUI/ObjectUI.py:2327 +#: flatcamGUI/ObjectUI.py:2657 msgid "Selection Color" msgstr "Culoare de selecție" -#: flatcamGUI/ObjectUI.py:2329 +#: flatcamGUI/ObjectUI.py:2659 msgid "Set the selection color when doing text selection." msgstr "Setați culoarea de selecție atunci când faceți selecția textului." -#: flatcamGUI/ObjectUI.py:2343 +#: flatcamGUI/ObjectUI.py:2673 msgid "Tab Size" msgstr "Dimens. filei" -#: flatcamGUI/ObjectUI.py:2345 +#: flatcamGUI/ObjectUI.py:2675 msgid "Set the tab size. In pixels. Default value is 80 pixels." msgstr "" "Setați dimensiunea filei. În pixeli. Valoarea implicită este de 80 pixeli." -#: flatcamGUI/PlotCanvasLegacy.py:1254 +#: flatcamGUI/PlotCanvasLegacy.py:1301 msgid "" "Could not annotate due of a difference between the number of text elements " "and the number of text positions." @@ -8744,31 +9126,35 @@ msgstr "" "Nu s-a putut adnota datorită unei diferențe între numărul de elemente de " "text și numărul de locații de text." -#: flatcamGUI/PreferencesUI.py:324 +#: flatcamGUI/PreferencesUI.py:343 msgid "GUI Preferences" msgstr "Preferințe GUI" -#: flatcamGUI/PreferencesUI.py:334 +#: flatcamGUI/PreferencesUI.py:353 msgid "Theme" msgstr "Temă" -#: flatcamGUI/PreferencesUI.py:336 -msgid "Select a theme for FlatCAM." -msgstr "Selectați o temă pentru FlatCAM." +#: flatcamGUI/PreferencesUI.py:355 +msgid "" +"Select a theme for FlatCAM.\n" +"It will theme the plot area." +msgstr "" +"Selectează o Temă pentru FlatCAM.\n" +"Va afecta zona de afisare." -#: flatcamGUI/PreferencesUI.py:340 +#: flatcamGUI/PreferencesUI.py:360 msgid "Light" msgstr "Luminos" -#: flatcamGUI/PreferencesUI.py:341 +#: flatcamGUI/PreferencesUI.py:361 msgid "Dark" msgstr "Întunecat" -#: flatcamGUI/PreferencesUI.py:348 +#: flatcamGUI/PreferencesUI.py:368 msgid "Use Gray Icons" msgstr "Utilizați pictogramele gri" -#: flatcamGUI/PreferencesUI.py:350 +#: flatcamGUI/PreferencesUI.py:370 msgid "" "Check this box to use a set of icons with\n" "a lighter (gray) color. To be used when a\n" @@ -8778,23 +9164,25 @@ msgstr "" "o culoare mai deschisă (gri). Pentru a fi utilizat atunci când\n" "se aplică o temă complet întunecată." -#: flatcamGUI/PreferencesUI.py:356 +#: flatcamGUI/PreferencesUI.py:376 msgid "Apply Theme" msgstr "Aplicați Tema" -#: flatcamGUI/PreferencesUI.py:358 +#: flatcamGUI/PreferencesUI.py:378 msgid "" "Select a theme for FlatCAM.\n" +"It will theme the plot area.\n" "The application will restart after change." msgstr "" -"Selectați o temă pentru FlatCAM.\n" +"Selectați o Temă pentru FlatCAM.\n" +"Va afecta zona de afisare.\n" "Aplicația va reporni după modificare." -#: flatcamGUI/PreferencesUI.py:369 +#: flatcamGUI/PreferencesUI.py:390 msgid "Layout" msgstr "Amplasare" -#: flatcamGUI/PreferencesUI.py:371 +#: flatcamGUI/PreferencesUI.py:392 msgid "" "Select an layout for FlatCAM.\n" "It is applied immediately." @@ -8802,11 +9190,11 @@ msgstr "" "Selectează un stil de amplasare a elementelor GUI in FlatCAM.\n" "Se aplică imediat." -#: flatcamGUI/PreferencesUI.py:390 +#: flatcamGUI/PreferencesUI.py:412 msgid "Style" msgstr "Stil" -#: flatcamGUI/PreferencesUI.py:392 +#: flatcamGUI/PreferencesUI.py:414 msgid "" "Select an style for FlatCAM.\n" "It will be applied at the next app start." @@ -8814,11 +9202,11 @@ msgstr "" "Selectează un stil pentru FlatCAM.\n" "Se va aplic la următoarea pornire a aplicaţiei." -#: flatcamGUI/PreferencesUI.py:406 +#: flatcamGUI/PreferencesUI.py:428 msgid "Activate HDPI Support" msgstr "Activați HDPI" -#: flatcamGUI/PreferencesUI.py:408 +#: flatcamGUI/PreferencesUI.py:430 msgid "" "Enable High DPI support for FlatCAM.\n" "It will be applied at the next app start." @@ -8827,11 +9215,11 @@ msgstr "" "Util pentru monitoarele 4k.\n" "Va fi aplicată la următoarea pornire a aplicaţiei." -#: flatcamGUI/PreferencesUI.py:422 +#: flatcamGUI/PreferencesUI.py:444 msgid "Display Hover Shape" msgstr "Afișează forma Hover" -#: flatcamGUI/PreferencesUI.py:424 +#: flatcamGUI/PreferencesUI.py:446 msgid "" "Enable display of a hover shape for FlatCAM objects.\n" "It is displayed whenever the mouse cursor is hovering\n" @@ -8841,11 +9229,11 @@ msgstr "" "in canvas-ul FlatCAM. Forma este afișată doar dacă obiectul \n" "nu este selectat." -#: flatcamGUI/PreferencesUI.py:431 +#: flatcamGUI/PreferencesUI.py:453 msgid "Display Selection Shape" msgstr "Afișați forma de selecție" -#: flatcamGUI/PreferencesUI.py:433 +#: flatcamGUI/PreferencesUI.py:455 msgid "" "Enable the display of a selection shape for FlatCAM objects.\n" "It is displayed whenever the mouse selects an object\n" @@ -8857,30 +9245,30 @@ msgstr "" "pe canvas-ul FlatCAM fie făcând click pe obiect fie prin\n" "crearea unei ferestre de selectie." -#: flatcamGUI/PreferencesUI.py:446 +#: flatcamGUI/PreferencesUI.py:468 msgid "Left-Right Selection Color" msgstr "Culoare de selecție stânga-dreapta" -#: flatcamGUI/PreferencesUI.py:449 flatcamGUI/PreferencesUI.py:515 -#: flatcamGUI/PreferencesUI.py:1882 flatcamGUI/PreferencesUI.py:2903 -#: flatcamGUI/PreferencesUI.py:3894 flatcamGUI/PreferencesUI.py:4534 -#: flatcamGUI/PreferencesUI.py:4600 flatcamTools/ToolRulesCheck.py:179 +#: flatcamGUI/PreferencesUI.py:471 flatcamGUI/PreferencesUI.py:537 +#: flatcamGUI/PreferencesUI.py:2062 flatcamGUI/PreferencesUI.py:3085 +#: flatcamGUI/PreferencesUI.py:4174 flatcamGUI/PreferencesUI.py:4827 +#: flatcamGUI/PreferencesUI.py:4893 flatcamTools/ToolRulesCheck.py:186 msgid "Outline" msgstr "Contur" -#: flatcamGUI/PreferencesUI.py:451 +#: flatcamGUI/PreferencesUI.py:473 msgid "Set the line color for the 'left to right' selection box." msgstr "" "Setează transparenţa conturului formei de selecţie\n" "când selectia se face de la stânga la dreapta." -#: flatcamGUI/PreferencesUI.py:465 flatcamGUI/PreferencesUI.py:532 -#: flatcamGUI/PreferencesUI.py:1899 flatcamGUI/PreferencesUI.py:2920 -#: flatcamGUI/PreferencesUI.py:4551 flatcamGUI/PreferencesUI.py:4617 +#: flatcamGUI/PreferencesUI.py:487 flatcamGUI/PreferencesUI.py:554 +#: flatcamGUI/PreferencesUI.py:2079 flatcamGUI/PreferencesUI.py:3102 +#: flatcamGUI/PreferencesUI.py:4844 flatcamGUI/PreferencesUI.py:4910 msgid "Fill" msgstr "Continut" -#: flatcamGUI/PreferencesUI.py:467 +#: flatcamGUI/PreferencesUI.py:489 msgid "" "Set the fill color for the selection box\n" "in case that the selection is done from left to right.\n" @@ -8892,29 +9280,29 @@ msgstr "" "Primii 6 digiti sunt culoarea efectivă și ultimii\n" "doi sunt pentru nivelul de transparenţă (alfa)." -#: flatcamGUI/PreferencesUI.py:485 flatcamGUI/PreferencesUI.py:552 -#: flatcamGUI/PreferencesUI.py:1918 flatcamGUI/PreferencesUI.py:2939 -#: flatcamGUI/PreferencesUI.py:4570 +#: flatcamGUI/PreferencesUI.py:507 flatcamGUI/PreferencesUI.py:574 +#: flatcamGUI/PreferencesUI.py:2098 flatcamGUI/PreferencesUI.py:3121 +#: flatcamGUI/PreferencesUI.py:4863 msgid "Alpha" msgstr "Alfa" -#: flatcamGUI/PreferencesUI.py:487 +#: flatcamGUI/PreferencesUI.py:509 msgid "Set the fill transparency for the 'left to right' selection box." msgstr "" "Setează transparenţa formei de selecţie când selectia\n" "se face de la stânga la dreapta." -#: flatcamGUI/PreferencesUI.py:511 +#: flatcamGUI/PreferencesUI.py:533 msgid "Right-Left Selection Color" msgstr "Culoare de selecție dreapta-stânga" -#: flatcamGUI/PreferencesUI.py:517 +#: flatcamGUI/PreferencesUI.py:539 msgid "Set the line color for the 'right to left' selection box." msgstr "" "Setează transparenţa conturului formei de selecţie\n" "când selectia se face de la dreapta la stânga." -#: flatcamGUI/PreferencesUI.py:534 +#: flatcamGUI/PreferencesUI.py:556 msgid "" "Set the fill color for the selection box\n" "in case that the selection is done from right to left.\n" @@ -8926,47 +9314,47 @@ msgstr "" "Primii 6 digiti sunt culoarea efectiva și ultimii\n" "doi sunt pentru nivelul de transparenţă (alfa)." -#: flatcamGUI/PreferencesUI.py:554 +#: flatcamGUI/PreferencesUI.py:576 msgid "Set the fill transparency for selection 'right to left' box." msgstr "" "Setează transparenţa formei de selecţie când selectia\n" "se face de la dreapta la stânga." -#: flatcamGUI/PreferencesUI.py:581 +#: flatcamGUI/PreferencesUI.py:603 msgid "Editor Color" msgstr "Culoare editor" -#: flatcamGUI/PreferencesUI.py:585 +#: flatcamGUI/PreferencesUI.py:607 msgid "Drawing" msgstr "Desen" -#: flatcamGUI/PreferencesUI.py:587 +#: flatcamGUI/PreferencesUI.py:609 msgid "Set the color for the shape." msgstr "Setează culoarea pentru forma geometrică din Editor." -#: flatcamGUI/PreferencesUI.py:604 +#: flatcamGUI/PreferencesUI.py:626 msgid "Set the color of the shape when selected." msgstr "" "Setează culoarea formei geometrice in Editor\n" "când se face o selecţie." -#: flatcamGUI/PreferencesUI.py:627 +#: flatcamGUI/PreferencesUI.py:649 msgid "Project Items Color" msgstr "Culoarea articolelor din Proiect" -#: flatcamGUI/PreferencesUI.py:631 +#: flatcamGUI/PreferencesUI.py:653 msgid "Enabled" msgstr "Activat" -#: flatcamGUI/PreferencesUI.py:633 +#: flatcamGUI/PreferencesUI.py:655 msgid "Set the color of the items in Project Tab Tree." msgstr "Setează culoarea elementelor din tab-ul Proiect." -#: flatcamGUI/PreferencesUI.py:647 +#: flatcamGUI/PreferencesUI.py:669 msgid "Disabled" msgstr "Dezactivat" -#: flatcamGUI/PreferencesUI.py:649 +#: flatcamGUI/PreferencesUI.py:671 msgid "" "Set the color of the items in Project Tab Tree,\n" "for the case when the items are disabled." @@ -8974,7 +9362,11 @@ msgstr "" "Setează culoarea elementelor din tab-ul Proiect\n" "in cazul in care elementele sunt dezactivate." -#: flatcamGUI/PreferencesUI.py:667 +#: flatcamGUI/PreferencesUI.py:687 +msgid "Project AutoHide" +msgstr "Ascundere Proiect" + +#: flatcamGUI/PreferencesUI.py:689 msgid "" "Check this box if you want the project/selected/tool tab area to\n" "hide automatically when there are no objects loaded and\n" @@ -8984,43 +9376,43 @@ msgstr "" "când nu sunt obiecte incărcate și să fie afișată automat\n" "când un obiect nou este creat/incărcat." -#: flatcamGUI/PreferencesUI.py:934 +#: flatcamGUI/PreferencesUI.py:1109 msgid "App Settings" msgstr "Setări Aplicație" -#: flatcamGUI/PreferencesUI.py:955 +#: flatcamGUI/PreferencesUI.py:1130 msgid "Grid Settings" msgstr "Setări Grilă" -#: flatcamGUI/PreferencesUI.py:959 +#: flatcamGUI/PreferencesUI.py:1134 msgid "X value" msgstr "Val X" -#: flatcamGUI/PreferencesUI.py:961 +#: flatcamGUI/PreferencesUI.py:1136 msgid "This is the Grid snap value on X axis." msgstr "Aceasta este valoare pentru lipire pe Grid pe axa X." -#: flatcamGUI/PreferencesUI.py:971 +#: flatcamGUI/PreferencesUI.py:1146 msgid "Y value" msgstr "Val Y" -#: flatcamGUI/PreferencesUI.py:973 +#: flatcamGUI/PreferencesUI.py:1148 msgid "This is the Grid snap value on Y axis." msgstr "Aceasta este valoare pentru lipire pe Grid pe axa Y." -#: flatcamGUI/PreferencesUI.py:983 +#: flatcamGUI/PreferencesUI.py:1158 msgid "Snap Max" msgstr "Lipire Max" -#: flatcamGUI/PreferencesUI.py:998 +#: flatcamGUI/PreferencesUI.py:1173 msgid "Workspace Settings" msgstr "Setări ale Spațiului de Lucru" -#: flatcamGUI/PreferencesUI.py:1001 +#: flatcamGUI/PreferencesUI.py:1176 msgid "Active" msgstr "Activ" -#: flatcamGUI/PreferencesUI.py:1003 +#: flatcamGUI/PreferencesUI.py:1178 msgid "" "Draw a delimiting rectangle on canvas.\n" "The purpose is to illustrate the limits for our work." @@ -9028,7 +9420,7 @@ msgstr "" "Desenează un patrulater care delimitează o suprafată de lucru.\n" "Scopul este de a ilustra limitele suprafetei noastre de lucru." -#: flatcamGUI/PreferencesUI.py:1011 +#: flatcamGUI/PreferencesUI.py:1186 msgid "" "Select the type of rectangle to be used on canvas,\n" "as valid workspace." @@ -9036,12 +9428,12 @@ msgstr "" "Selectează tipul de patrulater care va fi desenat pe canvas,\n" "pentru a delimita suprafata de lucru disponibilă (SL)." -#: flatcamGUI/PreferencesUI.py:1077 +#: flatcamGUI/PreferencesUI.py:1252 msgid "Orientation" msgstr "Orientare" -#: flatcamGUI/PreferencesUI.py:1078 flatcamGUI/PreferencesUI.py:5884 -#: flatcamTools/ToolFilm.py:420 +#: flatcamGUI/PreferencesUI.py:1253 flatcamGUI/PreferencesUI.py:6372 +#: flatcamTools/ToolFilm.py:422 msgid "" "Can be:\n" "- Portrait\n" @@ -9051,21 +9443,21 @@ msgstr "" "- Portret\n" "- Peisaj" -#: flatcamGUI/PreferencesUI.py:1082 flatcamGUI/PreferencesUI.py:5888 -#: flatcamTools/ToolFilm.py:424 +#: flatcamGUI/PreferencesUI.py:1257 flatcamGUI/PreferencesUI.py:6376 +#: flatcamTools/ToolFilm.py:426 msgid "Portrait" msgstr "Portret" -#: flatcamGUI/PreferencesUI.py:1083 flatcamGUI/PreferencesUI.py:5889 -#: flatcamTools/ToolFilm.py:425 +#: flatcamGUI/PreferencesUI.py:1258 flatcamGUI/PreferencesUI.py:6377 +#: flatcamTools/ToolFilm.py:427 msgid "Landscape" msgstr "Peisaj" -#: flatcamGUI/PreferencesUI.py:1107 +#: flatcamGUI/PreferencesUI.py:1282 msgid "Notebook" msgstr "Agendă" -#: flatcamGUI/PreferencesUI.py:1109 +#: flatcamGUI/PreferencesUI.py:1284 msgid "" "This sets the font size for the elements found in the Notebook.\n" "The notebook is the collapsible area in the left side of the GUI,\n" @@ -9076,19 +9468,19 @@ msgstr "" "Notebook-ul este zona pliabilă din partea stângă a GUI,\n" "și include filele Proiect, Selectat și Unelte." -#: flatcamGUI/PreferencesUI.py:1128 +#: flatcamGUI/PreferencesUI.py:1303 msgid "Axis" msgstr "Axă" -#: flatcamGUI/PreferencesUI.py:1130 +#: flatcamGUI/PreferencesUI.py:1305 msgid "This sets the font size for canvas axis." msgstr "Aceasta setează dimensiunea fontului pentru axele zonei de afisare." -#: flatcamGUI/PreferencesUI.py:1147 +#: flatcamGUI/PreferencesUI.py:1322 msgid "Textbox" msgstr "Casetă de text" -#: flatcamGUI/PreferencesUI.py:1149 +#: flatcamGUI/PreferencesUI.py:1324 msgid "" "This sets the font size for the Textbox GUI\n" "elements that are used in FlatCAM." @@ -9096,15 +9488,15 @@ msgstr "" "Aceasta setează dimensiunea fontului pentru elementele \n" "interfața GUI care sunt utilizate în FlatCAM." -#: flatcamGUI/PreferencesUI.py:1175 +#: flatcamGUI/PreferencesUI.py:1350 msgid "Mouse Settings" msgstr "Setări mouse" -#: flatcamGUI/PreferencesUI.py:1179 +#: flatcamGUI/PreferencesUI.py:1354 msgid "Cursor Shape" msgstr "Forma cursorului" -#: flatcamGUI/PreferencesUI.py:1181 +#: flatcamGUI/PreferencesUI.py:1356 msgid "" "Choose a mouse cursor shape.\n" "- Small -> with a customizable size.\n" @@ -9114,47 +9506,47 @@ msgstr "" "- Mic -> cu o dimensiune personalizabilă.\n" "- Mare -> Linii infinite" -#: flatcamGUI/PreferencesUI.py:1187 +#: flatcamGUI/PreferencesUI.py:1362 msgid "Small" msgstr "Mic" -#: flatcamGUI/PreferencesUI.py:1188 +#: flatcamGUI/PreferencesUI.py:1363 msgid "Big" msgstr "Mare" -#: flatcamGUI/PreferencesUI.py:1195 +#: flatcamGUI/PreferencesUI.py:1370 msgid "Cursor Size" msgstr "Dimensiunea cursorului" -#: flatcamGUI/PreferencesUI.py:1197 +#: flatcamGUI/PreferencesUI.py:1372 msgid "Set the size of the mouse cursor, in pixels." msgstr "Setați dimensiunea cursorului mouse-ului, în pixeli." -#: flatcamGUI/PreferencesUI.py:1208 +#: flatcamGUI/PreferencesUI.py:1383 msgid "Cursor Width" msgstr "Lățimea cursorului" -#: flatcamGUI/PreferencesUI.py:1210 +#: flatcamGUI/PreferencesUI.py:1385 msgid "Set the line width of the mouse cursor, in pixels." msgstr "Setați lățimea liniei cursorului mouse-ului, în pixeli." -#: flatcamGUI/PreferencesUI.py:1221 flatcamGUI/PreferencesUI.py:1228 +#: flatcamGUI/PreferencesUI.py:1396 flatcamGUI/PreferencesUI.py:1403 msgid "Cursor Color" msgstr "Culoarea cursorului" -#: flatcamGUI/PreferencesUI.py:1223 +#: flatcamGUI/PreferencesUI.py:1398 msgid "Check this box to color mouse cursor." msgstr "Bifează această casetă pentru a colora cursorul mouse-ului." -#: flatcamGUI/PreferencesUI.py:1230 +#: flatcamGUI/PreferencesUI.py:1405 msgid "Set the color of the mouse cursor." msgstr "Setați culoarea cursorului mouse-ului." -#: flatcamGUI/PreferencesUI.py:1253 +#: flatcamGUI/PreferencesUI.py:1428 msgid "Pan Button" msgstr "Buton Pan (mișcare)" -#: flatcamGUI/PreferencesUI.py:1255 +#: flatcamGUI/PreferencesUI.py:1430 msgid "" "Select the mouse button to use for panning:\n" "- MMB --> Middle Mouse Button\n" @@ -9164,35 +9556,35 @@ msgstr "" "- MMB - butonul din mijloc al mouse-ului\n" "- RMB - butonul in dreapta al mouse-ului" -#: flatcamGUI/PreferencesUI.py:1259 +#: flatcamGUI/PreferencesUI.py:1434 msgid "MMB" msgstr "MMB" -#: flatcamGUI/PreferencesUI.py:1260 +#: flatcamGUI/PreferencesUI.py:1435 msgid "RMB" msgstr "RMB" -#: flatcamGUI/PreferencesUI.py:1266 +#: flatcamGUI/PreferencesUI.py:1441 msgid "Multiple Selection" msgstr "Selecție Multiplă" -#: flatcamGUI/PreferencesUI.py:1268 +#: flatcamGUI/PreferencesUI.py:1443 msgid "Select the key used for multiple selection." msgstr "Selectează tasta folosita pentru selectia multipla." -#: flatcamGUI/PreferencesUI.py:1270 +#: flatcamGUI/PreferencesUI.py:1445 msgid "CTRL" msgstr "CTRL" -#: flatcamGUI/PreferencesUI.py:1271 +#: flatcamGUI/PreferencesUI.py:1446 msgid "SHIFT" msgstr "SHIFT" -#: flatcamGUI/PreferencesUI.py:1282 +#: flatcamGUI/PreferencesUI.py:1457 msgid "Delete object confirmation" msgstr "Confirmare de ștergere a obiectului" -#: flatcamGUI/PreferencesUI.py:1284 +#: flatcamGUI/PreferencesUI.py:1459 msgid "" "When checked the application will ask for user confirmation\n" "whenever the Delete object(s) event is triggered, either by\n" @@ -9202,11 +9594,11 @@ msgstr "" "ori de câte ori este declanșat evenimentul de Ștergere a \n" "unor obiecte, fie de cu ajutorul meniurilor sau cu combinatii de taste." -#: flatcamGUI/PreferencesUI.py:1291 +#: flatcamGUI/PreferencesUI.py:1466 msgid "\"Open\" behavior" msgstr "Stil \"Încarcare\"" -#: flatcamGUI/PreferencesUI.py:1293 +#: flatcamGUI/PreferencesUI.py:1468 msgid "" "When checked the path for the last saved file is used when saving files,\n" "and the path for the last opened file is used when opening files.\n" @@ -9224,7 +9616,11 @@ msgstr "" "ambele \n" "cazuri: fie că se deschide un fisier, fie că se salvează un fisier." -#: flatcamGUI/PreferencesUI.py:1304 +#: flatcamGUI/PreferencesUI.py:1477 +msgid "Enable ToolTips" +msgstr "Activează ToolTip-uri" + +#: flatcamGUI/PreferencesUI.py:1479 msgid "" "Check this box if you want to have toolTips displayed\n" "when hovering with mouse over items throughout the App." @@ -9232,11 +9628,11 @@ msgstr "" "Bifează daca dorești ca să fie afisate texte explicative când se\n" "tine mouse-ul deasupra diverselor texte din FlatCAM." -#: flatcamGUI/PreferencesUI.py:1311 +#: flatcamGUI/PreferencesUI.py:1486 msgid "Allow Machinist Unsafe Settings" msgstr "Permiteți setări nesigure pt Mașiniști" -#: flatcamGUI/PreferencesUI.py:1313 +#: flatcamGUI/PreferencesUI.py:1488 msgid "" "If checked, some of the application settings will be allowed\n" "to have values that are usually unsafe to use.\n" @@ -9250,11 +9646,11 @@ msgstr "" "Se va aplica la următoarea pornire a aplicatiei.\n" "<>: Nu schimbați acest lucru decât dacă știți ce faceți !!!" -#: flatcamGUI/PreferencesUI.py:1324 +#: flatcamGUI/PreferencesUI.py:1500 msgid "Bookmarks limit" msgstr "Limită nr. bookmark-uri" -#: flatcamGUI/PreferencesUI.py:1326 +#: flatcamGUI/PreferencesUI.py:1502 msgid "" "The maximum number of bookmarks that may be installed in the menu.\n" "The number of bookmarks in the bookmark manager may be greater\n" @@ -9264,27 +9660,27 @@ msgstr "" "Numărul de bookmark-uri în managerul de bookmark-uri poate fi mai mare\n" "dar meniul va conține doar atât de mult." -#: flatcamGUI/PreferencesUI.py:1335 +#: flatcamGUI/PreferencesUI.py:1511 msgid "Activity Icon" msgstr "Icon activitare" -#: flatcamGUI/PreferencesUI.py:1337 +#: flatcamGUI/PreferencesUI.py:1513 msgid "Select the GIF that show activity when FlatCAM is active." msgstr "Selectați GIF-ul care arată activitatea când FlatCAM este activ." -#: flatcamGUI/PreferencesUI.py:1395 +#: flatcamGUI/PreferencesUI.py:1571 msgid "App Preferences" msgstr "Preferințele Aplicaţie" -#: flatcamGUI/PreferencesUI.py:1405 flatcamGUI/PreferencesUI.py:1811 -#: flatcamGUI/PreferencesUI.py:2359 flatcamGUI/PreferencesUI.py:2804 -#: flatcamGUI/PreferencesUI.py:3417 flatcamTools/ToolDistance.py:49 -#: flatcamTools/ToolDistanceMin.py:49 flatcamTools/ToolPcbWizard.py:127 -#: flatcamTools/ToolProperties.py:152 +#: flatcamGUI/PreferencesUI.py:1581 flatcamGUI/PreferencesUI.py:1991 +#: flatcamGUI/PreferencesUI.py:2539 flatcamGUI/PreferencesUI.py:2986 +#: flatcamGUI/PreferencesUI.py:3695 flatcamTools/ToolDistance.py:56 +#: flatcamTools/ToolDistanceMin.py:50 flatcamTools/ToolPcbWizard.py:127 +#: flatcamTools/ToolProperties.py:154 msgid "Units" msgstr "Unităti" -#: flatcamGUI/PreferencesUI.py:1406 +#: flatcamGUI/PreferencesUI.py:1582 msgid "" "The default value for FlatCAM units.\n" "Whatever is selected here is set every time\n" @@ -9293,22 +9689,22 @@ msgstr "" "Unitatea de masura pt FlatCAM.\n" "Este setată la fiecare pornire a programului." -#: flatcamGUI/PreferencesUI.py:1409 flatcamGUI/PreferencesUI.py:1817 -#: flatcamGUI/PreferencesUI.py:2365 flatcamGUI/PreferencesUI.py:2815 -#: flatcamGUI/PreferencesUI.py:3423 flatcamTools/ToolCalculators.py:62 +#: flatcamGUI/PreferencesUI.py:1585 flatcamGUI/PreferencesUI.py:1997 +#: flatcamGUI/PreferencesUI.py:2545 flatcamGUI/PreferencesUI.py:2997 +#: flatcamGUI/PreferencesUI.py:3701 flatcamTools/ToolCalculators.py:62 #: flatcamTools/ToolPcbWizard.py:126 msgid "MM" msgstr "MM" -#: flatcamGUI/PreferencesUI.py:1410 +#: flatcamGUI/PreferencesUI.py:1586 msgid "IN" msgstr "Inch" -#: flatcamGUI/PreferencesUI.py:1416 +#: flatcamGUI/PreferencesUI.py:1592 msgid "Precision MM" msgstr "Precizie MM" -#: flatcamGUI/PreferencesUI.py:1418 +#: flatcamGUI/PreferencesUI.py:1594 msgid "" "The number of decimals used throughout the application\n" "when the set units are in METRIC system.\n" @@ -9318,11 +9714,11 @@ msgstr "" "când unitățile setate sunt în sistem METRIC.\n" "Orice modificare necesită repornirea aplicației." -#: flatcamGUI/PreferencesUI.py:1430 +#: flatcamGUI/PreferencesUI.py:1606 msgid "Precision INCH" msgstr "Precizie INCH" -#: flatcamGUI/PreferencesUI.py:1432 +#: flatcamGUI/PreferencesUI.py:1608 msgid "" "The number of decimals used throughout the application\n" "when the set units are in INCH system.\n" @@ -9332,11 +9728,11 @@ msgstr "" "când unitățile setate sunt în sistem INCH.\n" "Orice modificare necesită repornirea aplicației." -#: flatcamGUI/PreferencesUI.py:1444 +#: flatcamGUI/PreferencesUI.py:1620 msgid "Graphic Engine" msgstr "Motor grafic" -#: flatcamGUI/PreferencesUI.py:1445 +#: flatcamGUI/PreferencesUI.py:1621 msgid "" "Choose what graphic engine to use in FlatCAM.\n" "Legacy(2D) -> reduced functionality, slow performance but enhanced " @@ -9355,19 +9751,19 @@ msgstr "" "Intel HD3000 sau mai vechi. În acest caz, suprafața de afisare va fi neagră\n" "prin urmare folosiți modul Legacy (2D)." -#: flatcamGUI/PreferencesUI.py:1451 +#: flatcamGUI/PreferencesUI.py:1627 msgid "Legacy(2D)" msgstr "Legacy(2D)" -#: flatcamGUI/PreferencesUI.py:1452 +#: flatcamGUI/PreferencesUI.py:1628 msgid "OpenGL(3D)" msgstr "OpenGL(3D)" -#: flatcamGUI/PreferencesUI.py:1464 +#: flatcamGUI/PreferencesUI.py:1640 msgid "APP. LEVEL" msgstr "Nivel aplicatie" -#: flatcamGUI/PreferencesUI.py:1465 +#: flatcamGUI/PreferencesUI.py:1641 msgid "" "Choose the default level of usage for FlatCAM.\n" "BASIC level -> reduced functionality, best for beginner's.\n" @@ -9383,11 +9779,11 @@ msgstr "" "Alegerea efectuata aici va influenta ce aparamtri sunt disponibili\n" "in Tab-ul SELECTAT dar și in alte parti ale FlatCAM." -#: flatcamGUI/PreferencesUI.py:1477 +#: flatcamGUI/PreferencesUI.py:1653 msgid "Portable app" msgstr "Aplicație portabilă" -#: flatcamGUI/PreferencesUI.py:1478 +#: flatcamGUI/PreferencesUI.py:1654 msgid "" "Choose if the application should run as portable.\n" "\n" @@ -9401,19 +9797,19 @@ msgstr "" "ceea ce înseamnă că fișierele de preferințe vor fi salvate\n" "în folderul aplicației, în subfolderul lib \\ config." -#: flatcamGUI/PreferencesUI.py:1491 +#: flatcamGUI/PreferencesUI.py:1667 msgid "Languages" msgstr "Traduceri" -#: flatcamGUI/PreferencesUI.py:1492 +#: flatcamGUI/PreferencesUI.py:1668 msgid "Set the language used throughout FlatCAM." msgstr "Setează limba folosita pentru textele din FlatCAM." -#: flatcamGUI/PreferencesUI.py:1498 +#: flatcamGUI/PreferencesUI.py:1674 msgid "Apply Language" msgstr "Aplica Traducere" -#: flatcamGUI/PreferencesUI.py:1499 +#: flatcamGUI/PreferencesUI.py:1675 msgid "" "Set the language used throughout FlatCAM.\n" "The app will restart after click." @@ -9421,31 +9817,31 @@ msgstr "" "Setați limba folosită în FlatCAM.\n" "Aplicația va reporni după clic." -#: flatcamGUI/PreferencesUI.py:1513 +#: flatcamGUI/PreferencesUI.py:1689 msgid "Startup Settings" msgstr "Setări de Pornire" -#: flatcamGUI/PreferencesUI.py:1517 +#: flatcamGUI/PreferencesUI.py:1693 msgid "Splash Screen" msgstr "Ecran Pornire" -#: flatcamGUI/PreferencesUI.py:1519 +#: flatcamGUI/PreferencesUI.py:1695 msgid "Enable display of the splash screen at application startup." msgstr "Activeaza afisarea unui ecran de pornire la pornirea aplicatiei." -#: flatcamGUI/PreferencesUI.py:1531 +#: flatcamGUI/PreferencesUI.py:1707 msgid "Sys Tray Icon" msgstr "Icon in Sys Tray" -#: flatcamGUI/PreferencesUI.py:1533 +#: flatcamGUI/PreferencesUI.py:1709 msgid "Enable display of FlatCAM icon in Sys Tray." msgstr "Activare pentru afișarea pictogramei FlatCAM în Sys Tray." -#: flatcamGUI/PreferencesUI.py:1538 +#: flatcamGUI/PreferencesUI.py:1714 msgid "Show Shell" msgstr "Arată Shell" -#: flatcamGUI/PreferencesUI.py:1540 +#: flatcamGUI/PreferencesUI.py:1716 msgid "" "Check this box if you want the shell to\n" "start automatically at startup." @@ -9454,11 +9850,11 @@ msgstr "" "automata a ferestrei Shell (linia de comanda)\n" "la initializarea aplicaţiei." -#: flatcamGUI/PreferencesUI.py:1547 +#: flatcamGUI/PreferencesUI.py:1723 msgid "Show Project" msgstr "Afișați Proiectul" -#: flatcamGUI/PreferencesUI.py:1549 +#: flatcamGUI/PreferencesUI.py:1725 msgid "" "Check this box if you want the project/selected/tool tab area to\n" "to be shown automatically at startup." @@ -9466,11 +9862,11 @@ msgstr "" "Bifează aici daca dorești ca zona Notebook să fie\n" "afișată automat la pornire." -#: flatcamGUI/PreferencesUI.py:1555 +#: flatcamGUI/PreferencesUI.py:1731 msgid "Version Check" msgstr "Verificare versiune" -#: flatcamGUI/PreferencesUI.py:1557 +#: flatcamGUI/PreferencesUI.py:1733 msgid "" "Check this box if you want to check\n" "for a new version automatically at startup." @@ -9479,11 +9875,11 @@ msgstr "" "daca exista o versiune mai noua,\n" "la pornirea aplicaţiei." -#: flatcamGUI/PreferencesUI.py:1564 +#: flatcamGUI/PreferencesUI.py:1740 msgid "Send Statistics" msgstr "Trimiteți statistici" -#: flatcamGUI/PreferencesUI.py:1566 +#: flatcamGUI/PreferencesUI.py:1742 msgid "" "Check this box if you agree to send anonymous\n" "stats automatically at startup, to help improve FlatCAM." @@ -9493,11 +9889,11 @@ msgstr "" "aplicaţia. In acest fel dezvoltatorii vor sti unde să se focalizeze\n" "in crearea de inbunatatiri." -#: flatcamGUI/PreferencesUI.py:1580 +#: flatcamGUI/PreferencesUI.py:1756 msgid "Workers number" msgstr "Număr de worker's" -#: flatcamGUI/PreferencesUI.py:1582 flatcamGUI/PreferencesUI.py:1591 +#: flatcamGUI/PreferencesUI.py:1758 msgid "" "The number of Qthreads made available to the App.\n" "A bigger number may finish the jobs more quickly but\n" @@ -9513,35 +9909,35 @@ msgstr "" "Valoarea standard este 2.\n" "Dupa schimbarea valoarii, se va aplica la următoarea pornire a aplicatiei." -#: flatcamGUI/PreferencesUI.py:1604 +#: flatcamGUI/PreferencesUI.py:1772 msgid "Geo Tolerance" msgstr "Toleranta geometrică" -#: flatcamGUI/PreferencesUI.py:1606 flatcamGUI/PreferencesUI.py:1615 +#: flatcamGUI/PreferencesUI.py:1774 msgid "" "This value can counter the effect of the Circle Steps\n" -"parameter. Default value is 0.01.\n" +"parameter. Default value is 0.005.\n" "A lower value will increase the detail both in image\n" "and in Gcode for the circles, with a higher cost in\n" "performance. Higher value will provide more\n" "performance at the expense of level of detail." msgstr "" "Această valoare afectează efectul prametrului Pasi Cerc.\n" -"Valoarea default este 0.01.\n" +"Valoarea default este 0.005.\n" "O valoare mai mică va creste detaliile atat in imagine cat si\n" "in GCode pentru cercuri dar cu pretul unei scăderi in performantă.\n" -"O valoare mai mare va oferi mai multă performantă dar in\n" +"O valoare mai mare va oferi o performantă crescută dar in\n" "defavoarea nievelului de detalii." -#: flatcamGUI/PreferencesUI.py:1634 +#: flatcamGUI/PreferencesUI.py:1794 msgid "Save Settings" msgstr "Setări pentru Salvare" -#: flatcamGUI/PreferencesUI.py:1638 +#: flatcamGUI/PreferencesUI.py:1798 msgid "Save Compressed Project" msgstr "Salvează Proiectul comprimat" -#: flatcamGUI/PreferencesUI.py:1640 +#: flatcamGUI/PreferencesUI.py:1800 msgid "" "Whether to save a compressed or uncompressed project.\n" "When checked it will save a compressed FlatCAM project." @@ -9550,11 +9946,11 @@ msgstr "" "Când este bifat aici, se va salva o arhiva a proiectului\n" "lucru care poate reduce dimensiunea semnificativ." -#: flatcamGUI/PreferencesUI.py:1649 +#: flatcamGUI/PreferencesUI.py:1809 msgid "Compression" msgstr "Compresie" -#: flatcamGUI/PreferencesUI.py:1651 +#: flatcamGUI/PreferencesUI.py:1811 msgid "" "The level of compression used when saving\n" "a FlatCAM project. Higher value means better compression\n" @@ -9565,62 +9961,93 @@ msgstr "" "dar cu consum redus de resurse in timp ce valoarea 9 cere multa memorie RAM\n" "și in plus, durează semnificativ mai mult." -#: flatcamGUI/PreferencesUI.py:1671 +#: flatcamGUI/PreferencesUI.py:1822 +msgid "Enable Auto Save" +msgstr "Activează Salvarea Automată" + +#: flatcamGUI/PreferencesUI.py:1824 +msgid "" +"Check to enable the autosave feature.\n" +"When enabled, the application will try to save a project\n" +"at the set interval." +msgstr "" +"Bifează pentru activarea optiunii de auto-salvare.\n" +"Cand este activate, aplicatia va incereca sa salveze\n" +"proiectul intr-un mod periodic." + +#: flatcamGUI/PreferencesUI.py:1834 +#| msgid "Interior" +msgid "Interval" +msgstr "Interval" + +#: flatcamGUI/PreferencesUI.py:1836 +msgid "" +"Time interval for autosaving. In milliseconds.\n" +"The application will try to save periodically but only\n" +"if the project was saved manually at least once.\n" +"While active, some operations may block this feature." +msgstr "" +"Interval periodic pentru autosalvare. In milisecunde.\n" +"Aplicatia va incerca sa salveze periodic doar dacă\n" +"proiectul a fost salvat manual cel putin odată.\n" +"Cand unele operatii sunt active, această capabilitate poate fi sistată." + +#: flatcamGUI/PreferencesUI.py:1852 msgid "Text to PDF parameters" msgstr "Parametri text la PDF" -#: flatcamGUI/PreferencesUI.py:1673 +#: flatcamGUI/PreferencesUI.py:1854 msgid "Used when saving text in Code Editor or in FlatCAM Document objects." msgstr "" "Utilizat la salvarea textului în Codul Editor sau în obiectele FlatCAM " "Document." -#: flatcamGUI/PreferencesUI.py:1682 +#: flatcamGUI/PreferencesUI.py:1863 msgid "Top Margin" msgstr "Margine Sus" -#: flatcamGUI/PreferencesUI.py:1684 +#: flatcamGUI/PreferencesUI.py:1865 msgid "Distance between text body and the top of the PDF file." msgstr "Distanța dintre corpul textului și partea superioară a fișierului PDF." -#: flatcamGUI/PreferencesUI.py:1695 +#: flatcamGUI/PreferencesUI.py:1876 msgid "Bottom Margin" msgstr "Margine Jos" -#: flatcamGUI/PreferencesUI.py:1697 +#: flatcamGUI/PreferencesUI.py:1878 msgid "Distance between text body and the bottom of the PDF file." msgstr "Distanța dintre corpul textului și partea de jos a fișierului PDF." -#: flatcamGUI/PreferencesUI.py:1708 +#: flatcamGUI/PreferencesUI.py:1889 msgid "Left Margin" msgstr "Margine Stânga" -#: flatcamGUI/PreferencesUI.py:1710 +#: flatcamGUI/PreferencesUI.py:1891 msgid "Distance between text body and the left of the PDF file." msgstr "Distanța dintre corpul textului și stânga fișierului PDF." -#: flatcamGUI/PreferencesUI.py:1721 +#: flatcamGUI/PreferencesUI.py:1902 msgid "Right Margin" msgstr "Margine Dreapta" -#: flatcamGUI/PreferencesUI.py:1723 +#: flatcamGUI/PreferencesUI.py:1904 msgid "Distance between text body and the right of the PDF file." msgstr "Distanța dintre corpul textului și dreapta fișierului PDF." -#: flatcamGUI/PreferencesUI.py:1756 +#: flatcamGUI/PreferencesUI.py:1936 msgid "Gerber General" msgstr "Gerber General" -#: flatcamGUI/PreferencesUI.py:1774 +#: flatcamGUI/PreferencesUI.py:1954 msgid "M-Color" msgstr "M-Color" -#: flatcamGUI/PreferencesUI.py:1788 flatcamGUI/PreferencesUI.py:3859 -#: flatcamGUI/PreferencesUI.py:4442 flatcamGUI/PreferencesUI.py:7148 +#: flatcamGUI/PreferencesUI.py:1968 flatcamGUI/PreferencesUI.py:4137 +#: flatcamGUI/PreferencesUI.py:4735 flatcamGUI/PreferencesUI.py:7654 msgid "Circle Steps" msgstr "Pași pt. cerc" -#: flatcamGUI/PreferencesUI.py:1790 +#: flatcamGUI/PreferencesUI.py:1970 msgid "" "The number of circle steps for Gerber \n" "circular aperture linear approximation." @@ -9628,11 +10055,11 @@ msgstr "" "Numărul de segmente utilizate pentru\n" "aproximarea lineara a aperturilor Gerber circulare." -#: flatcamGUI/PreferencesUI.py:1802 +#: flatcamGUI/PreferencesUI.py:1982 msgid "Default Values" msgstr "Val. Implicite" -#: flatcamGUI/PreferencesUI.py:1804 +#: flatcamGUI/PreferencesUI.py:1984 msgid "" "Those values will be used as fallback values\n" "in case that they are not found in the Gerber file." @@ -9640,25 +10067,25 @@ msgstr "" "Aceste valori vor fi utilizate ca valori de baza\n" "în cazul în care acestea nu sunt găsite în fișierul Gerber." -#: flatcamGUI/PreferencesUI.py:1813 flatcamGUI/PreferencesUI.py:1819 -#: flatcamGUI/PreferencesUI.py:2361 flatcamGUI/PreferencesUI.py:2367 +#: flatcamGUI/PreferencesUI.py:1993 flatcamGUI/PreferencesUI.py:1999 +#: flatcamGUI/PreferencesUI.py:2541 flatcamGUI/PreferencesUI.py:2547 msgid "The units used in the Gerber file." msgstr "Unitătile de măsură folosite in fişierul Gerber." -#: flatcamGUI/PreferencesUI.py:1816 flatcamGUI/PreferencesUI.py:2364 -#: flatcamGUI/PreferencesUI.py:2728 flatcamGUI/PreferencesUI.py:2814 -#: flatcamGUI/PreferencesUI.py:3422 flatcamTools/ToolCalculators.py:61 +#: flatcamGUI/PreferencesUI.py:1996 flatcamGUI/PreferencesUI.py:2544 +#: flatcamGUI/PreferencesUI.py:2910 flatcamGUI/PreferencesUI.py:2996 +#: flatcamGUI/PreferencesUI.py:3700 flatcamTools/ToolCalculators.py:61 #: flatcamTools/ToolPcbWizard.py:125 msgid "INCH" msgstr "Inch" -#: flatcamGUI/PreferencesUI.py:1826 flatcamGUI/PreferencesUI.py:2413 -#: flatcamGUI/PreferencesUI.py:2786 flatcamGUI/PreferencesUI.py:3490 +#: flatcamGUI/PreferencesUI.py:2006 flatcamGUI/PreferencesUI.py:2593 +#: flatcamGUI/PreferencesUI.py:2968 flatcamGUI/PreferencesUI.py:3768 msgid "Zeros" msgstr "Zero-uri" -#: flatcamGUI/PreferencesUI.py:1829 flatcamGUI/PreferencesUI.py:1839 -#: flatcamGUI/PreferencesUI.py:2416 flatcamGUI/PreferencesUI.py:2426 +#: flatcamGUI/PreferencesUI.py:2009 flatcamGUI/PreferencesUI.py:2019 +#: flatcamGUI/PreferencesUI.py:2596 flatcamGUI/PreferencesUI.py:2606 msgid "" "This sets the type of Gerber zeros.\n" "If LZ then Leading Zeros are removed and\n" @@ -9674,23 +10101,23 @@ msgstr "" "cele de la final sunt păstrate.\n" "(Invers fată de fişierele Excellon)." -#: flatcamGUI/PreferencesUI.py:1836 flatcamGUI/PreferencesUI.py:2423 -#: flatcamGUI/PreferencesUI.py:2799 flatcamGUI/PreferencesUI.py:3500 +#: flatcamGUI/PreferencesUI.py:2016 flatcamGUI/PreferencesUI.py:2603 +#: flatcamGUI/PreferencesUI.py:2981 flatcamGUI/PreferencesUI.py:3778 #: flatcamTools/ToolPcbWizard.py:111 msgid "LZ" msgstr "LZ" -#: flatcamGUI/PreferencesUI.py:1837 flatcamGUI/PreferencesUI.py:2424 -#: flatcamGUI/PreferencesUI.py:2800 flatcamGUI/PreferencesUI.py:3501 +#: flatcamGUI/PreferencesUI.py:2017 flatcamGUI/PreferencesUI.py:2604 +#: flatcamGUI/PreferencesUI.py:2982 flatcamGUI/PreferencesUI.py:3779 #: flatcamTools/ToolPcbWizard.py:112 msgid "TZ" msgstr "TZ" -#: flatcamGUI/PreferencesUI.py:1855 +#: flatcamGUI/PreferencesUI.py:2035 msgid "Clean Apertures" msgstr "Curățați Aperturile" -#: flatcamGUI/PreferencesUI.py:1857 +#: flatcamGUI/PreferencesUI.py:2037 msgid "" "Will remove apertures that do not have geometry\n" "thus lowering the number of apertures in the Gerber object." @@ -9698,11 +10125,11 @@ msgstr "" "Va elimina Aperturile care nu au geometrie\n" "scăzând astfel numărul de aperturi în obiectul Gerber." -#: flatcamGUI/PreferencesUI.py:1863 +#: flatcamGUI/PreferencesUI.py:2043 msgid "Polarity change buffer" msgstr "Tampon la Schimbarea polarității" -#: flatcamGUI/PreferencesUI.py:1865 +#: flatcamGUI/PreferencesUI.py:2045 msgid "" "Will apply extra buffering for the\n" "solid geometry when we have polarity changes.\n" @@ -9714,17 +10141,17 @@ msgstr "" "Poate ajuta la încărcarea fișierelor Gerber care altfel\n" "nu se încarcă corect." -#: flatcamGUI/PreferencesUI.py:1878 +#: flatcamGUI/PreferencesUI.py:2058 msgid "Gerber Object Color" msgstr "Culoare obiect Gerber" -#: flatcamGUI/PreferencesUI.py:1884 flatcamGUI/PreferencesUI.py:2905 -#: flatcamGUI/PreferencesUI.py:3896 +#: flatcamGUI/PreferencesUI.py:2064 flatcamGUI/PreferencesUI.py:3087 +#: flatcamGUI/PreferencesUI.py:4176 msgid "Set the line color for plotted objects." msgstr "Setează culoarea conturului." -#: flatcamGUI/PreferencesUI.py:1901 flatcamGUI/PreferencesUI.py:2922 -#: flatcamGUI/PreferencesUI.py:4553 flatcamGUI/PreferencesUI.py:4619 +#: flatcamGUI/PreferencesUI.py:2081 flatcamGUI/PreferencesUI.py:3104 +#: flatcamGUI/PreferencesUI.py:4846 flatcamGUI/PreferencesUI.py:4912 msgid "" "Set the fill color for plotted objects.\n" "First 6 digits are the color and the last 2\n" @@ -9734,34 +10161,29 @@ msgstr "" "Primii 6 digiti sunt culoarea efectivă și ultimii\n" "doi sunt pentru nivelul de transparenţă (alfa)." -#: flatcamGUI/PreferencesUI.py:1920 flatcamGUI/PreferencesUI.py:2941 -#: flatcamGUI/PreferencesUI.py:4572 +#: flatcamGUI/PreferencesUI.py:2100 flatcamGUI/PreferencesUI.py:3123 +#: flatcamGUI/PreferencesUI.py:4865 msgid "Set the fill transparency for plotted objects." msgstr "Setează nivelul de transparenţă pentru obiectele afisate." -#: flatcamGUI/PreferencesUI.py:2011 +#: flatcamGUI/PreferencesUI.py:2191 msgid "Gerber Options" msgstr "Opțiuni Gerber" -#: flatcamGUI/PreferencesUI.py:2085 flatcamGUI/PreferencesUI.py:4379 -#: flatcamGUI/PreferencesUI.py:5120 flatcamTools/ToolNonCopperClear.py:170 -msgid "Conv." -msgstr "Conv." - -#: flatcamGUI/PreferencesUI.py:2089 +#: flatcamGUI/PreferencesUI.py:2269 msgid "Combine Passes" msgstr "Combina" -#: flatcamGUI/PreferencesUI.py:2177 +#: flatcamGUI/PreferencesUI.py:2357 msgid "Gerber Adv. Options" msgstr "Opțiuni Av. Gerber" -#: flatcamGUI/PreferencesUI.py:2181 flatcamGUI/PreferencesUI.py:3278 -#: flatcamGUI/PreferencesUI.py:4179 +#: flatcamGUI/PreferencesUI.py:2361 flatcamGUI/PreferencesUI.py:3551 +#: flatcamGUI/PreferencesUI.py:4472 msgid "Advanced Options" msgstr "Opțiuni avansate" -#: flatcamGUI/PreferencesUI.py:2183 +#: flatcamGUI/PreferencesUI.py:2363 msgid "" "A list of Gerber advanced parameters.\n" "Those parameters are available only for\n" @@ -9772,11 +10194,11 @@ msgstr "" "când este selectat Nivelul Avansat pentru\n" "aplicaţie in Preferințe - > General." -#: flatcamGUI/PreferencesUI.py:2202 +#: flatcamGUI/PreferencesUI.py:2382 msgid "Table Show/Hide" msgstr "Arata/Ascunde Tabela" -#: flatcamGUI/PreferencesUI.py:2204 +#: flatcamGUI/PreferencesUI.py:2384 msgid "" "Toggle the display of the Gerber Apertures Table.\n" "Also, on hide, it will delete all mark shapes\n" @@ -9786,15 +10208,15 @@ msgstr "" "când se ascunde aceasta, se vor șterge și toate\n" "posibil afisatele marcaje ale aperturilor." -#: flatcamGUI/PreferencesUI.py:2284 +#: flatcamGUI/PreferencesUI.py:2464 msgid "Exterior" msgstr "Exterior" -#: flatcamGUI/PreferencesUI.py:2285 +#: flatcamGUI/PreferencesUI.py:2465 msgid "Interior" msgstr "Interior" -#: flatcamGUI/PreferencesUI.py:2298 +#: flatcamGUI/PreferencesUI.py:2478 msgid "" "Buffering type:\n" "- None --> best performance, fast file loading but no so good display\n" @@ -9808,19 +10230,19 @@ msgstr "" "valoarea de bază.\n" "<>: Nu schimba această valoare decat dacă stii ce faci !!!" -#: flatcamGUI/PreferencesUI.py:2303 flatcamGUI/PreferencesUI.py:5852 -#: flatcamGUI/PreferencesUI.py:7446 flatcamTools/ToolFiducials.py:201 -#: flatcamTools/ToolFilm.py:255 flatcamTools/ToolProperties.py:411 -#: flatcamTools/ToolProperties.py:426 flatcamTools/ToolProperties.py:429 -#: flatcamTools/ToolProperties.py:432 flatcamTools/ToolProperties.py:456 +#: flatcamGUI/PreferencesUI.py:2483 flatcamGUI/PreferencesUI.py:6340 +#: flatcamGUI/PreferencesUI.py:7952 flatcamTools/ToolFiducials.py:201 +#: flatcamTools/ToolFilm.py:255 flatcamTools/ToolProperties.py:452 +#: flatcamTools/ToolProperties.py:455 flatcamTools/ToolProperties.py:458 +#: flatcamTools/ToolProperties.py:483 msgid "None" msgstr "Nimic" -#: flatcamGUI/PreferencesUI.py:2309 +#: flatcamGUI/PreferencesUI.py:2489 msgid "Simplify" msgstr "Simplifica" -#: flatcamGUI/PreferencesUI.py:2311 +#: flatcamGUI/PreferencesUI.py:2491 msgid "" "When checked all the Gerber polygons will be\n" "loaded with simplification having a set tolerance.\n" @@ -9830,23 +10252,23 @@ msgstr "" "încărcate simplificat cu o toleranță stabilită.\n" "<>: Nu schimbați acest lucru decât dacă știți ce faceți !!!" -#: flatcamGUI/PreferencesUI.py:2318 +#: flatcamGUI/PreferencesUI.py:2498 msgid "Tolerance" msgstr "Toleranta" -#: flatcamGUI/PreferencesUI.py:2319 +#: flatcamGUI/PreferencesUI.py:2499 msgid "Tolerance for polygon simplification." msgstr "Toleranță pentru simplificarea poligoanelor." -#: flatcamGUI/PreferencesUI.py:2344 +#: flatcamGUI/PreferencesUI.py:2524 msgid "Gerber Export" msgstr "Export Gerber" -#: flatcamGUI/PreferencesUI.py:2348 flatcamGUI/PreferencesUI.py:3406 +#: flatcamGUI/PreferencesUI.py:2528 flatcamGUI/PreferencesUI.py:3684 msgid "Export Options" msgstr "Opțiuni de Export" -#: flatcamGUI/PreferencesUI.py:2350 +#: flatcamGUI/PreferencesUI.py:2530 msgid "" "The parameters set here are used in the file exported\n" "when using the File -> Export -> Export Gerber menu entry." @@ -9855,11 +10277,11 @@ msgstr "" "se exporta un fişier Gerber folosind:\n" "File -> Exportă -> Exportă Gerber." -#: flatcamGUI/PreferencesUI.py:2373 flatcamGUI/PreferencesUI.py:3431 +#: flatcamGUI/PreferencesUI.py:2553 flatcamGUI/PreferencesUI.py:3709 msgid "Int/Decimals" msgstr "Înt/Zecimale" -#: flatcamGUI/PreferencesUI.py:2375 +#: flatcamGUI/PreferencesUI.py:2555 msgid "" "The number of digits in the whole part of the number\n" "and in the fractional part of the number." @@ -9867,7 +10289,7 @@ msgstr "" "Acest număr reprezinta numărul de digiti din partea\n" "intreagă si in partea fractională a numărului." -#: flatcamGUI/PreferencesUI.py:2388 +#: flatcamGUI/PreferencesUI.py:2568 msgid "" "This numbers signify the number of digits in\n" "the whole part of Gerber coordinates." @@ -9875,7 +10297,7 @@ msgstr "" "Acest număr reprezinta numărul de digiti din partea\n" "intreagă a coordonatelor Gerber." -#: flatcamGUI/PreferencesUI.py:2404 +#: flatcamGUI/PreferencesUI.py:2584 msgid "" "This numbers signify the number of digits in\n" "the decimal part of Gerber coordinates." @@ -9883,16 +10305,16 @@ msgstr "" "Acest număr reprezinta numărul de digiti din partea\n" "zecimală a coordonatelor Gerber." -#: flatcamGUI/PreferencesUI.py:2449 +#: flatcamGUI/PreferencesUI.py:2629 msgid "A list of Gerber Editor parameters." msgstr "O listă de parametri ai Editorului Gerber." -#: flatcamGUI/PreferencesUI.py:2457 flatcamGUI/PreferencesUI.py:3565 -#: flatcamGUI/PreferencesUI.py:4357 flatcamGUI/PreferencesUI.py:7109 +#: flatcamGUI/PreferencesUI.py:2637 flatcamGUI/PreferencesUI.py:3843 +#: flatcamGUI/PreferencesUI.py:4650 flatcamGUI/PreferencesUI.py:7615 msgid "Selection limit" msgstr "Limita selecţie" -#: flatcamGUI/PreferencesUI.py:2459 +#: flatcamGUI/PreferencesUI.py:2639 msgid "" "Set the number of selected Gerber geometry\n" "items above which the utility geometry\n" @@ -9905,23 +10327,23 @@ msgstr "" "Creste performanta cand se mută un număr mai mare\n" "de elemente geometrice." -#: flatcamGUI/PreferencesUI.py:2472 +#: flatcamGUI/PreferencesUI.py:2652 msgid "New Aperture code" msgstr "Cod pt aperture noua" -#: flatcamGUI/PreferencesUI.py:2485 +#: flatcamGUI/PreferencesUI.py:2665 msgid "New Aperture size" msgstr "Dim. pt aperture noua" -#: flatcamGUI/PreferencesUI.py:2487 +#: flatcamGUI/PreferencesUI.py:2667 msgid "Size for the new aperture" msgstr "Dim. pentru noua apertură" -#: flatcamGUI/PreferencesUI.py:2498 +#: flatcamGUI/PreferencesUI.py:2678 msgid "New Aperture type" msgstr "Tip pt noua apaertura" -#: flatcamGUI/PreferencesUI.py:2500 +#: flatcamGUI/PreferencesUI.py:2680 msgid "" "Type for the new aperture.\n" "Can be 'C', 'R' or 'O'." @@ -9929,35 +10351,42 @@ msgstr "" "Tipul noii aperture.\n" "Poate fi „C”, „R” sau „O”." -#: flatcamGUI/PreferencesUI.py:2522 +#: flatcamGUI/PreferencesUI.py:2702 msgid "Aperture Dimensions" msgstr "Dim. aper" -#: flatcamGUI/PreferencesUI.py:2524 flatcamGUI/PreferencesUI.py:3877 -#: flatcamGUI/PreferencesUI.py:5029 -msgid "Diameters of the cutting tools, separated by ','" -msgstr "Diametrele pentru unelte tăietoare, separate cu virgula" +#: flatcamGUI/PreferencesUI.py:2704 flatcamGUI/PreferencesUI.py:4155 +#: flatcamGUI/PreferencesUI.py:5322 flatcamGUI/PreferencesUI.py:5889 +#: flatcamGUI/PreferencesUI.py:6955 +msgid "" +"Diameters of the tools, separated by comma.\n" +"The value of the diameter has to use the dot decimals separator.\n" +"Valid values: 0.3, 1.0" +msgstr "" +"Diametrele uneltelor separate cu virgulă.\n" +"Valoarea diametrului trebuie sa folosească punctul ca si separator zecimal.\n" +"Valori valide: 0.3, 1.0" -#: flatcamGUI/PreferencesUI.py:2530 +#: flatcamGUI/PreferencesUI.py:2712 msgid "Linear Pad Array" msgstr "Arie Lineară de Sloturi" -#: flatcamGUI/PreferencesUI.py:2534 flatcamGUI/PreferencesUI.py:3609 -#: flatcamGUI/PreferencesUI.py:3757 +#: flatcamGUI/PreferencesUI.py:2716 flatcamGUI/PreferencesUI.py:3887 +#: flatcamGUI/PreferencesUI.py:4035 msgid "Linear Direction" msgstr "Direcție liniară" -#: flatcamGUI/PreferencesUI.py:2574 +#: flatcamGUI/PreferencesUI.py:2756 msgid "Circular Pad Array" msgstr "Arie de Sloturi circ" -#: flatcamGUI/PreferencesUI.py:2578 flatcamGUI/PreferencesUI.py:3655 -#: flatcamGUI/PreferencesUI.py:3805 +#: flatcamGUI/PreferencesUI.py:2760 flatcamGUI/PreferencesUI.py:3933 +#: flatcamGUI/PreferencesUI.py:4083 msgid "Circular Direction" msgstr "Direcția circulară" -#: flatcamGUI/PreferencesUI.py:2580 flatcamGUI/PreferencesUI.py:3657 -#: flatcamGUI/PreferencesUI.py:3807 +#: flatcamGUI/PreferencesUI.py:2762 flatcamGUI/PreferencesUI.py:3935 +#: flatcamGUI/PreferencesUI.py:4085 msgid "" "Direction for circular array.\n" "Can be CW = clockwise or CCW = counter clockwise." @@ -9966,48 +10395,48 @@ msgstr "" "Poate fi CW = in sensul acelor de ceasornic sau CCW = invers acelor de " "ceasornic." -#: flatcamGUI/PreferencesUI.py:2591 flatcamGUI/PreferencesUI.py:3668 -#: flatcamGUI/PreferencesUI.py:3818 +#: flatcamGUI/PreferencesUI.py:2773 flatcamGUI/PreferencesUI.py:3946 +#: flatcamGUI/PreferencesUI.py:4096 msgid "Circular Angle" msgstr "Unghi circular" -#: flatcamGUI/PreferencesUI.py:2610 +#: flatcamGUI/PreferencesUI.py:2792 msgid "Distance at which to buffer the Gerber element." msgstr "Distanța la care se bufferează elementul Gerber." -#: flatcamGUI/PreferencesUI.py:2619 +#: flatcamGUI/PreferencesUI.py:2801 msgid "Scale Tool" msgstr "Unalta de Scalare" -#: flatcamGUI/PreferencesUI.py:2625 +#: flatcamGUI/PreferencesUI.py:2807 msgid "Factor to scale the Gerber element." msgstr "Factor pentru scalarea elementului Gerber." -#: flatcamGUI/PreferencesUI.py:2638 +#: flatcamGUI/PreferencesUI.py:2820 msgid "Threshold low" msgstr "Prag minim" -#: flatcamGUI/PreferencesUI.py:2640 +#: flatcamGUI/PreferencesUI.py:2822 msgid "Threshold value under which the apertures are not marked." msgstr "Valoarea pragului sub care aperturile nu sunt marcate." -#: flatcamGUI/PreferencesUI.py:2650 +#: flatcamGUI/PreferencesUI.py:2832 msgid "Threshold high" msgstr "Prag mare" -#: flatcamGUI/PreferencesUI.py:2652 +#: flatcamGUI/PreferencesUI.py:2834 msgid "Threshold value over which the apertures are not marked." msgstr "Valoarea pragului peste care nu sunt marcate aperturile." -#: flatcamGUI/PreferencesUI.py:2670 +#: flatcamGUI/PreferencesUI.py:2852 msgid "Excellon General" msgstr "Excellon General" -#: flatcamGUI/PreferencesUI.py:2703 +#: flatcamGUI/PreferencesUI.py:2885 msgid "Excellon Format" msgstr "Format Excellon" -#: flatcamGUI/PreferencesUI.py:2705 +#: flatcamGUI/PreferencesUI.py:2887 msgid "" "The NC drill files, usually named Excellon files\n" "are files that can be found in different formats.\n" @@ -10053,14 +10482,14 @@ msgstr "" "Sprint Layout 2:4 INCH LZ\n" "KiCAD 3:5 INCH TZ" -#: flatcamGUI/PreferencesUI.py:2729 +#: flatcamGUI/PreferencesUI.py:2911 msgid "Default values for INCH are 2:4" msgstr "" "Valorile default pentru Inch sunt 2:4\n" "adica 2 parti intregi și 4 zecimale" -#: flatcamGUI/PreferencesUI.py:2736 flatcamGUI/PreferencesUI.py:2765 -#: flatcamGUI/PreferencesUI.py:3445 +#: flatcamGUI/PreferencesUI.py:2918 flatcamGUI/PreferencesUI.py:2947 +#: flatcamGUI/PreferencesUI.py:3723 msgid "" "This numbers signify the number of digits in\n" "the whole part of Excellon coordinates." @@ -10068,8 +10497,8 @@ msgstr "" "Acest număr reprezinta numărul de digiti din partea\n" "intreaga a coordonatelor Excellon." -#: flatcamGUI/PreferencesUI.py:2749 flatcamGUI/PreferencesUI.py:2778 -#: flatcamGUI/PreferencesUI.py:3458 +#: flatcamGUI/PreferencesUI.py:2931 flatcamGUI/PreferencesUI.py:2960 +#: flatcamGUI/PreferencesUI.py:3736 msgid "" "This numbers signify the number of digits in\n" "the decimal part of Excellon coordinates." @@ -10077,17 +10506,17 @@ msgstr "" "Acest număr reprezinta numărul de digiti din partea\n" "zecimala a coordonatelor Excellon." -#: flatcamGUI/PreferencesUI.py:2757 +#: flatcamGUI/PreferencesUI.py:2939 msgid "METRIC" msgstr "Metric" -#: flatcamGUI/PreferencesUI.py:2758 +#: flatcamGUI/PreferencesUI.py:2940 msgid "Default values for METRIC are 3:3" msgstr "" "Valorile default pentru Metric sunt 3:3\n" "adica 3 parti intregi și 3 zecimale" -#: flatcamGUI/PreferencesUI.py:2789 +#: flatcamGUI/PreferencesUI.py:2971 msgid "" "This sets the type of Excellon zeros.\n" "If LZ then Leading Zeros are kept and\n" @@ -10108,7 +10537,7 @@ msgstr "" "Se foloseşte atunci când nu există informații\n" "stocate în fișierul Excellon." -#: flatcamGUI/PreferencesUI.py:2807 +#: flatcamGUI/PreferencesUI.py:2989 msgid "" "This sets the default units of Excellon files.\n" "If it is not detected in the parsed file the value here\n" @@ -10122,7 +10551,7 @@ msgstr "" "(unde se gasesc unitatile) și atunci se va folosi\n" "aceasta valoare." -#: flatcamGUI/PreferencesUI.py:2817 +#: flatcamGUI/PreferencesUI.py:2999 msgid "" "This sets the units of Excellon files.\n" "Some Excellon files don't have an header\n" @@ -10135,19 +10564,19 @@ msgstr "" "(unde se gasesc unitatile) și atunci se va folosi\n" "aceasta valoare." -#: flatcamGUI/PreferencesUI.py:2825 +#: flatcamGUI/PreferencesUI.py:3007 msgid "Update Export settings" msgstr "Actualizeaza setarile de Export" -#: flatcamGUI/PreferencesUI.py:2842 +#: flatcamGUI/PreferencesUI.py:3024 msgid "Excellon Optimization" msgstr "Optimizare Excellon" -#: flatcamGUI/PreferencesUI.py:2845 +#: flatcamGUI/PreferencesUI.py:3027 msgid "Algorithm:" msgstr "Algoritm:" -#: flatcamGUI/PreferencesUI.py:2847 flatcamGUI/PreferencesUI.py:2863 +#: flatcamGUI/PreferencesUI.py:3029 flatcamGUI/PreferencesUI.py:3045 msgid "" "This sets the optimization type for the Excellon drill path.\n" "If <> is checked then Google OR-Tools algorithm with\n" @@ -10173,20 +10602,20 @@ msgstr "" "folosește\n" "Algoritmul Traveling Salesman pentru optimizarea căii." -#: flatcamGUI/PreferencesUI.py:2858 +#: flatcamGUI/PreferencesUI.py:3040 msgid "MetaHeuristic" msgstr "MetaHeuristic" -#: flatcamGUI/PreferencesUI.py:2860 +#: flatcamGUI/PreferencesUI.py:3042 msgid "TSA" msgstr "TSA" -#: flatcamGUI/PreferencesUI.py:2877 flatcamGUI/PreferencesUI.py:3192 -#: flatcamGUI/PreferencesUI.py:4138 +#: flatcamGUI/PreferencesUI.py:3059 flatcamGUI/PreferencesUI.py:3463 +#: flatcamGUI/PreferencesUI.py:4430 msgid "Duration" msgstr "Durată" -#: flatcamGUI/PreferencesUI.py:2880 +#: flatcamGUI/PreferencesUI.py:3062 msgid "" "When OR-Tools Metaheuristic (MH) is enabled there is a\n" "maximum threshold for how much time is spent doing the\n" @@ -10197,15 +10626,19 @@ msgstr "" "reprezinta cat timp se sta pentru fiecare element in\n" "incercarea de a afla calea optima." -#: flatcamGUI/PreferencesUI.py:2899 +#: flatcamGUI/PreferencesUI.py:3081 msgid "Excellon Object Color" msgstr "Culoare obiect Excellon" -#: flatcamGUI/PreferencesUI.py:3065 +#: flatcamGUI/PreferencesUI.py:3247 msgid "Excellon Options" msgstr "Opțiuni Excellon" -#: flatcamGUI/PreferencesUI.py:3071 +#: flatcamGUI/PreferencesUI.py:3251 flatcamGUI/PreferencesUI.py:4227 +msgid "Create CNC Job" +msgstr "Crează CNCJob" + +#: flatcamGUI/PreferencesUI.py:3253 msgid "" "Parameters used to create a CNC Job object\n" "for this drill object." @@ -10213,11 +10646,27 @@ msgstr "" "Parametrii folositi pentru a crea un obiect FlatCAM tip CNCJob\n" "din acest obiect Excellon." -#: flatcamGUI/PreferencesUI.py:3185 flatcamGUI/PreferencesUI.py:4133 +#: flatcamGUI/PreferencesUI.py:3370 flatcamGUI/PreferencesUI.py:4314 +msgid "Tool change" +msgstr "Schimb unealtă" + +#: flatcamGUI/PreferencesUI.py:3454 flatcamGUI/PreferencesUI.py:4425 msgid "Enable Dwell" msgstr "Activați Pauză" -#: flatcamGUI/PreferencesUI.py:3217 +#: flatcamGUI/PreferencesUI.py:3477 +msgid "" +"The preprocessor JSON file that dictates\n" +"Gcode output." +msgstr "" +"Fișierul JSON postprocesor care dictează\n" +"codul Gcode." + +#: flatcamGUI/PreferencesUI.py:3488 +msgid "Gcode" +msgstr "Gcode" + +#: flatcamGUI/PreferencesUI.py:3490 msgid "" "Choose what to use for GCode generation:\n" "'Drills', 'Slots' or 'Both'.\n" @@ -10231,15 +10680,33 @@ msgstr "" "Când se alege Sloturi sau Ambele, sloturile vor fi convertite in serii de " "găuri." -#: flatcamGUI/PreferencesUI.py:3235 +#: flatcamGUI/PreferencesUI.py:3506 +msgid "Mill Holes" +msgstr "Frezare găuri" + +#: flatcamGUI/PreferencesUI.py:3508 msgid "Create Geometry for milling holes." msgstr "Crează un obiect tip Geometrie pentru frezarea găurilor." -#: flatcamGUI/PreferencesUI.py:3271 +#: flatcamGUI/PreferencesUI.py:3512 +msgid "Drill Tool dia" +msgstr "Dia. Burghiu Găurire" + +#: flatcamGUI/PreferencesUI.py:3523 +msgid "Slot Tool dia" +msgstr "Dia. Freza Slot" + +#: flatcamGUI/PreferencesUI.py:3525 +msgid "" +"Diameter of the cutting tool\n" +"when milling slots." +msgstr "Diametrul frezei când se frezează sloturile." + +#: flatcamGUI/PreferencesUI.py:3544 msgid "Excellon Adv. Options" msgstr "Opțiuni Avans. Excellon" -#: flatcamGUI/PreferencesUI.py:3280 +#: flatcamGUI/PreferencesUI.py:3553 msgid "" "A list of Excellon advanced parameters.\n" "Those parameters are available only for\n" @@ -10250,19 +10717,19 @@ msgstr "" "când este selectat Nivelul Avansat pentru\n" "aplicaţie in Preferințe - > General." -#: flatcamGUI/PreferencesUI.py:3301 +#: flatcamGUI/PreferencesUI.py:3576 msgid "Toolchange X,Y" msgstr "X,Y schimb. unealtă" -#: flatcamGUI/PreferencesUI.py:3303 flatcamGUI/PreferencesUI.py:4193 +#: flatcamGUI/PreferencesUI.py:3578 flatcamGUI/PreferencesUI.py:4486 msgid "Toolchange X,Y position." msgstr "Poziţia X,Y in format (x,y) unde se face schimbarea uneltei." -#: flatcamGUI/PreferencesUI.py:3360 flatcamGUI/PreferencesUI.py:4280 +#: flatcamGUI/PreferencesUI.py:3638 flatcamGUI/PreferencesUI.py:4573 msgid "Spindle direction" msgstr "Directie rotatie Motor" -#: flatcamGUI/PreferencesUI.py:3362 flatcamGUI/PreferencesUI.py:4282 +#: flatcamGUI/PreferencesUI.py:3640 flatcamGUI/PreferencesUI.py:4575 msgid "" "This sets the direction that the spindle is rotating.\n" "It can be either:\n" @@ -10274,11 +10741,11 @@ msgstr "" "- CW = in sensul acelor de ceasornic\n" "- CCW = in sensul invers acelor de ceasornic" -#: flatcamGUI/PreferencesUI.py:3373 flatcamGUI/PreferencesUI.py:4294 +#: flatcamGUI/PreferencesUI.py:3651 flatcamGUI/PreferencesUI.py:4587 msgid "Fast Plunge" msgstr "Plonjare rapidă" -#: flatcamGUI/PreferencesUI.py:3375 flatcamGUI/PreferencesUI.py:4296 +#: flatcamGUI/PreferencesUI.py:3653 flatcamGUI/PreferencesUI.py:4589 msgid "" "By checking this, the vertical move from\n" "Z_Toolchange to Z_move is done with G0,\n" @@ -10295,11 +10762,11 @@ msgstr "" "schimba\n" "unealta. Daca aveti ceva plasat sub unealtă ceva se va strica." -#: flatcamGUI/PreferencesUI.py:3382 +#: flatcamGUI/PreferencesUI.py:3660 msgid "Fast Retract" msgstr "Retragere rapida" -#: flatcamGUI/PreferencesUI.py:3384 +#: flatcamGUI/PreferencesUI.py:3662 msgid "" "Exit hole strategy.\n" " - When uncheked, while exiting the drilled hole the drill bit\n" @@ -10318,11 +10785,11 @@ msgstr "" "adâncimea\n" "de deplasare cu viteza maxima G0, intr-o singură mișcare." -#: flatcamGUI/PreferencesUI.py:3402 +#: flatcamGUI/PreferencesUI.py:3680 msgid "Excellon Export" msgstr "Export Excellon" -#: flatcamGUI/PreferencesUI.py:3408 +#: flatcamGUI/PreferencesUI.py:3686 msgid "" "The parameters set here are used in the file exported\n" "when using the File -> Export -> Export Excellon menu entry." @@ -10331,11 +10798,11 @@ msgstr "" "se exporta un fişier Excellon folosind:\n" "File -> Exporta -> Exporta Excellon." -#: flatcamGUI/PreferencesUI.py:3419 flatcamGUI/PreferencesUI.py:3425 +#: flatcamGUI/PreferencesUI.py:3697 flatcamGUI/PreferencesUI.py:3703 msgid "The units used in the Excellon file." msgstr "Unitatile de masura folosite in fişierul Excellon." -#: flatcamGUI/PreferencesUI.py:3433 +#: flatcamGUI/PreferencesUI.py:3711 msgid "" "The NC drill files, usually named Excellon files\n" "are files that can be found in different formats.\n" @@ -10347,11 +10814,11 @@ msgstr "" "Aici se setează formatul Excellon când nu se utilizează\n" "coordonate cu zecimale." -#: flatcamGUI/PreferencesUI.py:3467 +#: flatcamGUI/PreferencesUI.py:3745 msgid "Format" msgstr "Format" -#: flatcamGUI/PreferencesUI.py:3469 flatcamGUI/PreferencesUI.py:3479 +#: flatcamGUI/PreferencesUI.py:3747 flatcamGUI/PreferencesUI.py:3757 msgid "" "Select the kind of coordinates format used.\n" "Coordinates can be saved with decimal point or without.\n" @@ -10370,15 +10837,15 @@ msgstr "" "- LZ = zerourile prefix sunt pastrate și cele sufix eliminate\n" "- TZ = zerourile prefix sunt eliminate și cele sufix pastrate." -#: flatcamGUI/PreferencesUI.py:3476 +#: flatcamGUI/PreferencesUI.py:3754 msgid "Decimal" msgstr "Zecimale" -#: flatcamGUI/PreferencesUI.py:3477 +#: flatcamGUI/PreferencesUI.py:3755 msgid "No-Decimal" msgstr "Fără zecimale" -#: flatcamGUI/PreferencesUI.py:3493 +#: flatcamGUI/PreferencesUI.py:3771 msgid "" "This sets the type of Excellon zeros.\n" "If LZ then Leading Zeros are kept and\n" @@ -10394,7 +10861,7 @@ msgstr "" "cele de la final sunt pastrate.\n" "(Invers fata de fişierele Gerber)." -#: flatcamGUI/PreferencesUI.py:3503 +#: flatcamGUI/PreferencesUI.py:3781 msgid "" "This sets the default type of Excellon zeros.\n" "If LZ then Leading Zeros are kept and\n" @@ -10406,11 +10873,11 @@ msgstr "" "- LZ = zerourile prefix sunt pastrate și cele sufix eliminate\n" "- TZ = zerourile prefix sunt eliminate și cele sufix pastrate." -#: flatcamGUI/PreferencesUI.py:3513 +#: flatcamGUI/PreferencesUI.py:3791 msgid "Slot type" msgstr "Tip slot" -#: flatcamGUI/PreferencesUI.py:3516 flatcamGUI/PreferencesUI.py:3526 +#: flatcamGUI/PreferencesUI.py:3794 flatcamGUI/PreferencesUI.py:3804 msgid "" "This sets how the slots will be exported.\n" "If ROUTED then the slots will be routed\n" @@ -10424,19 +10891,19 @@ msgstr "" "Dacă sunt Găurite (G85) sloturile vor fi exportate\n" "folosind comanda slotului găurit (G85)." -#: flatcamGUI/PreferencesUI.py:3523 +#: flatcamGUI/PreferencesUI.py:3801 msgid "Routed" msgstr "Decupate" -#: flatcamGUI/PreferencesUI.py:3524 +#: flatcamGUI/PreferencesUI.py:3802 msgid "Drilled(G85)" msgstr "Găurite(G85)" -#: flatcamGUI/PreferencesUI.py:3557 +#: flatcamGUI/PreferencesUI.py:3835 msgid "A list of Excellon Editor parameters." msgstr "O listă de parametri ai Editorului Excellon." -#: flatcamGUI/PreferencesUI.py:3567 +#: flatcamGUI/PreferencesUI.py:3845 msgid "" "Set the number of selected Excellon geometry\n" "items above which the utility geometry\n" @@ -10450,19 +10917,20 @@ msgstr "" "Creste performanta cand se muta un număr mai mare de \n" "elemente geometrice." -#: flatcamGUI/PreferencesUI.py:3580 flatcamGUI/PreferencesUI.py:5100 -msgid "New Tool Dia" -msgstr "Dia. nou unealtă" +#: flatcamGUI/PreferencesUI.py:3858 flatcamGUI/PreferencesUI.py:5396 +#: flatcamGUI/PreferencesUI.py:5962 +msgid "New Dia" +msgstr "Dia. nou" -#: flatcamGUI/PreferencesUI.py:3605 +#: flatcamGUI/PreferencesUI.py:3883 msgid "Linear Drill Array" msgstr "Arie lineară de găuri" -#: flatcamGUI/PreferencesUI.py:3651 +#: flatcamGUI/PreferencesUI.py:3929 msgid "Circular Drill Array" msgstr "Arie circ. de găuri" -#: flatcamGUI/PreferencesUI.py:3721 +#: flatcamGUI/PreferencesUI.py:3999 msgid "" "Angle at which the slot is placed.\n" "The precision is of max 2 decimals.\n" @@ -10474,19 +10942,19 @@ msgstr "" "Valoarea minimă este: -359,99 grade.\n" "Valoarea maximă este: 360,00 grade." -#: flatcamGUI/PreferencesUI.py:3740 +#: flatcamGUI/PreferencesUI.py:4018 msgid "Linear Slot Array" msgstr "Arie lineară de Sloturi" -#: flatcamGUI/PreferencesUI.py:3801 +#: flatcamGUI/PreferencesUI.py:4079 msgid "Circular Slot Array" msgstr "Arie circ. de Sloturi" -#: flatcamGUI/PreferencesUI.py:3839 +#: flatcamGUI/PreferencesUI.py:4117 msgid "Geometry General" msgstr "Geometrie General" -#: flatcamGUI/PreferencesUI.py:3861 +#: flatcamGUI/PreferencesUI.py:4139 msgid "" "The number of circle steps for Geometry \n" "circle and arc shapes linear approximation." @@ -10494,15 +10962,20 @@ msgstr "" "Numărul de segmente utilizate pentru\n" "aproximarea lineara a Geometriilor circulare." -#: flatcamGUI/PreferencesUI.py:3890 +#: flatcamGUI/PreferencesUI.py:4153 flatcamGUI/PreferencesUI.py:5320 +#: flatcamGUI/PreferencesUI.py:5887 flatcamGUI/PreferencesUI.py:6953 +msgid "Tools Dia" +msgstr "Dia Unealtă" + +#: flatcamGUI/PreferencesUI.py:4170 msgid "Geometry Object Color" msgstr "Culoare obiect Geometrie" -#: flatcamGUI/PreferencesUI.py:3941 +#: flatcamGUI/PreferencesUI.py:4221 msgid "Geometry Options" msgstr "Opțiuni Geometrie" -#: flatcamGUI/PreferencesUI.py:3949 +#: flatcamGUI/PreferencesUI.py:4229 msgid "" "Create a CNC Job object\n" "tracing the contours of this\n" @@ -10511,11 +10984,11 @@ msgstr "" "Crează un obiect CNCJob care urmăreste conturul\n" "acestui obiect tip Geometrie." -#: flatcamGUI/PreferencesUI.py:3993 +#: flatcamGUI/PreferencesUI.py:4273 msgid "Depth/Pass" msgstr "Adânc./Trecere" -#: flatcamGUI/PreferencesUI.py:3995 +#: flatcamGUI/PreferencesUI.py:4275 msgid "" "The depth to cut on each pass,\n" "when multidepth is enabled.\n" @@ -10528,11 +11001,11 @@ msgstr "" "Valoarea este pozitivă desi reprezinta o fracţie\n" "a adancimii de tăiere care este o valoare negativă." -#: flatcamGUI/PreferencesUI.py:4173 +#: flatcamGUI/PreferencesUI.py:4466 msgid "Geometry Adv. Options" msgstr "Opțiuni Avans. Geometrie" -#: flatcamGUI/PreferencesUI.py:4181 +#: flatcamGUI/PreferencesUI.py:4474 msgid "" "A list of Geometry advanced parameters.\n" "Those parameters are available only for\n" @@ -10543,13 +11016,13 @@ msgstr "" "când este selectat Nivelul Avansat pentru\n" "aplicaţie in Preferințe - > General." -#: flatcamGUI/PreferencesUI.py:4191 flatcamGUI/PreferencesUI.py:6539 -#: flatcamGUI/PreferencesUI.py:7586 flatcamTools/ToolCalibration.py:125 -#: flatcamTools/ToolSolderPaste.py:239 +#: flatcamGUI/PreferencesUI.py:4484 flatcamGUI/PreferencesUI.py:7045 +#: flatcamGUI/PreferencesUI.py:8092 flatcamTools/ToolCalibration.py:125 +#: flatcamTools/ToolSolderPaste.py:241 msgid "Toolchange X-Y" msgstr "X,Y schimb. unealtă" -#: flatcamGUI/PreferencesUI.py:4202 +#: flatcamGUI/PreferencesUI.py:4495 msgid "" "Height of the tool just after starting the work.\n" "Delete the value if you don't need this feature." @@ -10557,11 +11030,11 @@ msgstr "" "Înălţimea uneltei la care se gaseste la inceputul lucrului.\n" "Lasa câmpul gol daca nu folosești aceasta." -#: flatcamGUI/PreferencesUI.py:4304 +#: flatcamGUI/PreferencesUI.py:4597 msgid "Segment X size" msgstr "Dim. seg X" -#: flatcamGUI/PreferencesUI.py:4306 +#: flatcamGUI/PreferencesUI.py:4599 msgid "" "The size of the trace segment on the X axis.\n" "Useful for auto-leveling.\n" @@ -10572,11 +11045,11 @@ msgstr "" "O valoare de 0 inseamnaca nu se face segmentare\n" "pe axa X." -#: flatcamGUI/PreferencesUI.py:4320 +#: flatcamGUI/PreferencesUI.py:4613 msgid "Segment Y size" msgstr "Dim. seg Y" -#: flatcamGUI/PreferencesUI.py:4322 +#: flatcamGUI/PreferencesUI.py:4615 msgid "" "The size of the trace segment on the Y axis.\n" "Useful for auto-leveling.\n" @@ -10587,15 +11060,11 @@ msgstr "" "O valoare de 0 inseamnaca nu se face segmentare\n" "pe axa Y." -#: flatcamGUI/PreferencesUI.py:4343 -msgid "Geometry Editor" -msgstr "Editor Geometrii" - -#: flatcamGUI/PreferencesUI.py:4349 +#: flatcamGUI/PreferencesUI.py:4642 msgid "A list of Geometry Editor parameters." msgstr "O lista de parametri ai Editorului de Geometrii." -#: flatcamGUI/PreferencesUI.py:4359 flatcamGUI/PreferencesUI.py:7111 +#: flatcamGUI/PreferencesUI.py:4652 flatcamGUI/PreferencesUI.py:7617 msgid "" "Set the number of selected geometry\n" "items above which the utility geometry\n" @@ -10609,11 +11078,11 @@ msgstr "" "Creste performanta cand se muta un număr mai mare de \n" "elemente geometrice." -#: flatcamGUI/PreferencesUI.py:4391 +#: flatcamGUI/PreferencesUI.py:4684 msgid "CNC Job General" msgstr "CNCJob General" -#: flatcamGUI/PreferencesUI.py:4444 +#: flatcamGUI/PreferencesUI.py:4737 msgid "" "The number of circle steps for GCode \n" "circle and arc shapes linear approximation." @@ -10621,25 +11090,25 @@ msgstr "" "Numărul de segmente utilizate pentru\n" "aproximarea lineara a reprezentarilor GCodului circular." -#: flatcamGUI/PreferencesUI.py:4453 +#: flatcamGUI/PreferencesUI.py:4746 msgid "Travel dia" msgstr "Dia Deplasare" -#: flatcamGUI/PreferencesUI.py:4455 +#: flatcamGUI/PreferencesUI.py:4748 msgid "" "The width of the travel lines to be\n" "rendered in the plot." msgstr "Diametrul liniilor de deplasare care să fie redate prin afișare." -#: flatcamGUI/PreferencesUI.py:4468 +#: flatcamGUI/PreferencesUI.py:4761 msgid "G-code Decimals" msgstr "Zecimale G-Code" -#: flatcamGUI/PreferencesUI.py:4471 flatcamTools/ToolFiducials.py:74 +#: flatcamGUI/PreferencesUI.py:4764 flatcamTools/ToolFiducials.py:74 msgid "Coordinates" msgstr "Coordinate" -#: flatcamGUI/PreferencesUI.py:4473 +#: flatcamGUI/PreferencesUI.py:4766 msgid "" "The number of decimals to be used for \n" "the X, Y, Z coordinates in CNC code (GCODE, etc.)" @@ -10647,11 +11116,11 @@ msgstr "" "Numărul de zecimale care să fie folosit in \n" "coordonatele X,Y,Z in codul CNC (GCode etc)." -#: flatcamGUI/PreferencesUI.py:4484 flatcamTools/ToolProperties.py:492 +#: flatcamGUI/PreferencesUI.py:4777 flatcamTools/ToolProperties.py:519 msgid "Feedrate" msgstr "Feedrate" -#: flatcamGUI/PreferencesUI.py:4486 +#: flatcamGUI/PreferencesUI.py:4779 msgid "" "The number of decimals to be used for \n" "the Feedrate parameter in CNC code (GCODE, etc.)" @@ -10659,11 +11128,11 @@ msgstr "" "Numărul de zecimale care să fie folosit in \n" "parametrul >Feedrate< in codul CNC (GCode etc)." -#: flatcamGUI/PreferencesUI.py:4497 +#: flatcamGUI/PreferencesUI.py:4790 msgid "Coordinates type" msgstr "Tip coordinate" -#: flatcamGUI/PreferencesUI.py:4499 +#: flatcamGUI/PreferencesUI.py:4792 msgid "" "The type of coordinates to be used in Gcode.\n" "Can be:\n" @@ -10675,19 +11144,19 @@ msgstr "" "- Absolut G90 -> referinta este originea x=0, y=0\n" "- Incrementator G91 -> referinta este pozitia anterioară" -#: flatcamGUI/PreferencesUI.py:4505 +#: flatcamGUI/PreferencesUI.py:4798 msgid "Absolute G90" msgstr "Absolut G90" -#: flatcamGUI/PreferencesUI.py:4506 +#: flatcamGUI/PreferencesUI.py:4799 msgid "Incremental G91" msgstr "Incrementator G91" -#: flatcamGUI/PreferencesUI.py:4516 +#: flatcamGUI/PreferencesUI.py:4809 msgid "Force Windows style line-ending" msgstr "Forțați finalizarea liniei în stil Windows" -#: flatcamGUI/PreferencesUI.py:4518 +#: flatcamGUI/PreferencesUI.py:4811 msgid "" "When checked will force a Windows style line-ending\n" "(\\r\\n) on non-Windows OS's." @@ -10695,35 +11164,35 @@ msgstr "" "Când este bifat, va forța o linie de finalizare a stilului Windows\n" "(\\r \\n) pe sistemele de operare non-Windows." -#: flatcamGUI/PreferencesUI.py:4530 +#: flatcamGUI/PreferencesUI.py:4823 msgid "Travel Line Color" msgstr "Culoare Linie Trecere" -#: flatcamGUI/PreferencesUI.py:4536 +#: flatcamGUI/PreferencesUI.py:4829 msgid "Set the travel line color for plotted objects." msgstr "Setați culoarea liniei de trecere pentru obiectele trasate." -#: flatcamGUI/PreferencesUI.py:4596 +#: flatcamGUI/PreferencesUI.py:4889 msgid "CNCJob Object Color" msgstr "Culoare obiect CNCJob" -#: flatcamGUI/PreferencesUI.py:4602 +#: flatcamGUI/PreferencesUI.py:4895 msgid "Set the color for plotted objects." msgstr "Setați culoarea pentru obiectele trasate." -#: flatcamGUI/PreferencesUI.py:4762 +#: flatcamGUI/PreferencesUI.py:5055 msgid "CNC Job Options" msgstr "Opțiuni CNCJob" -#: flatcamGUI/PreferencesUI.py:4766 +#: flatcamGUI/PreferencesUI.py:5059 msgid "Export G-Code" msgstr "Exportă G-Code" -#: flatcamGUI/PreferencesUI.py:4782 +#: flatcamGUI/PreferencesUI.py:5075 msgid "Prepend to G-Code" msgstr "Adaugă la inceputul G-Code" -#: flatcamGUI/PreferencesUI.py:4791 +#: flatcamGUI/PreferencesUI.py:5084 msgid "" "Type here any G-Code commands you would like to add at the beginning of the " "G-Code file." @@ -10731,11 +11200,11 @@ msgstr "" "Introduceți aici orice comandă G-Code pe care doriți să o adăugați la " "începutul fișierului G-Code." -#: flatcamGUI/PreferencesUI.py:4798 +#: flatcamGUI/PreferencesUI.py:5091 msgid "Append to G-Code" msgstr "Adaugă la sfârşitul G-Code" -#: flatcamGUI/PreferencesUI.py:4808 +#: flatcamGUI/PreferencesUI.py:5101 msgid "" "Type here any G-Code commands you would like to append to the generated " "file.\n" @@ -10745,11 +11214,11 @@ msgstr "" "inserate la sfârşitul codului G-Code.\n" "De exemplu: M2 (Sfârșitul programului)" -#: flatcamGUI/PreferencesUI.py:4824 +#: flatcamGUI/PreferencesUI.py:5117 msgid "CNC Job Adv. Options" msgstr "Opțiuni Avans. CNCJob" -#: flatcamGUI/PreferencesUI.py:4861 +#: flatcamGUI/PreferencesUI.py:5154 msgid "" "Type here any G-Code commands you would like to be executed when Toolchange " "event is encountered.\n" @@ -10767,45 +11236,46 @@ msgstr "" "poate fi folosit doar cu un fişier postprocesor care contine " "'toolchange_custom' în nume." -#: flatcamGUI/PreferencesUI.py:4916 +#: flatcamGUI/PreferencesUI.py:5209 msgid "Z depth for the cut" msgstr "Z adâncimea de tăiere" -#: flatcamGUI/PreferencesUI.py:4917 +#: flatcamGUI/PreferencesUI.py:5210 msgid "Z height for travel" msgstr "Z Înălţimea deplasare" -#: flatcamGUI/PreferencesUI.py:4923 +#: flatcamGUI/PreferencesUI.py:5216 msgid "dwelltime = time to dwell to allow the spindle to reach it's set RPM" msgstr "dwelltime = durata de asteptare ca motorul să ajunga la turatia setată" -#: flatcamGUI/PreferencesUI.py:4942 +#: flatcamGUI/PreferencesUI.py:5235 msgid "Annotation Size" msgstr "Dim. anotate" -#: flatcamGUI/PreferencesUI.py:4944 +#: flatcamGUI/PreferencesUI.py:5237 msgid "The font size of the annotation text. In pixels." msgstr "Dimensiunea fontului pt. textul cu notatii. In pixeli." -#: flatcamGUI/PreferencesUI.py:4954 +#: flatcamGUI/PreferencesUI.py:5247 msgid "Annotation Color" msgstr "Culoarea anotatii" -#: flatcamGUI/PreferencesUI.py:4956 +#: flatcamGUI/PreferencesUI.py:5249 msgid "Set the font color for the annotation texts." msgstr "Setează culoarea pentru textul cu anotatii." -#: flatcamGUI/PreferencesUI.py:5013 +#: flatcamGUI/PreferencesUI.py:5306 msgid "NCC Tool Options" msgstr "Opțiuni Unealta NCC" -#: flatcamGUI/PreferencesUI.py:5027 flatcamGUI/PreferencesUI.py:6449 -msgid "Tools dia" -msgstr "Dia unealtă" +#: flatcamGUI/PreferencesUI.py:5328 flatcamGUI/PreferencesUI.py:5896 +msgid "Comma separated values" +msgstr "Valori separate cu virgulă" -#: flatcamGUI/PreferencesUI.py:5038 flatcamGUI/PreferencesUI.py:5046 -#: flatcamTools/ToolNonCopperClear.py:215 -#: flatcamTools/ToolNonCopperClear.py:223 +#: flatcamGUI/PreferencesUI.py:5334 flatcamGUI/PreferencesUI.py:5342 +#: flatcamGUI/PreferencesUI.py:5903 flatcamTools/ToolNCC.py:215 +#: flatcamTools/ToolNCC.py:223 flatcamTools/ToolPaint.py:198 +#: flatcamTools/ToolPaint.py:206 msgid "" "Default tool type:\n" "- 'V-shape'\n" @@ -10815,13 +11285,15 @@ msgstr "" "- 'Forma-V'\n" "- Circular" -#: flatcamGUI/PreferencesUI.py:5043 flatcamTools/ToolNonCopperClear.py:220 +#: flatcamGUI/PreferencesUI.py:5339 flatcamGUI/PreferencesUI.py:5908 +#: flatcamTools/ToolNCC.py:220 flatcamTools/ToolPaint.py:203 msgid "V-shape" msgstr "Forma-V" -#: flatcamGUI/PreferencesUI.py:5083 flatcamGUI/PreferencesUI.py:5092 -#: flatcamTools/ToolNonCopperClear.py:256 -#: flatcamTools/ToolNonCopperClear.py:264 +#: flatcamGUI/PreferencesUI.py:5379 flatcamGUI/PreferencesUI.py:5388 +#: flatcamGUI/PreferencesUI.py:5946 flatcamGUI/PreferencesUI.py:5955 +#: flatcamTools/ToolNCC.py:262 flatcamTools/ToolNCC.py:271 +#: flatcamTools/ToolPaint.py:245 flatcamTools/ToolPaint.py:254 msgid "" "Depth of cut into material. Negative value.\n" "In FlatCAM units." @@ -10829,34 +11301,26 @@ msgstr "" "Adancimea de tăiere in material. Valoare negative.\n" "In unitătile FlatCAM." -#: flatcamGUI/PreferencesUI.py:5102 -msgid "The new tool diameter (cut width) to add in the tool table." -msgstr "" -"Noul diametru al sculei (lățimea tăiată) pt adăugare în tabelul Unelte." - -#: flatcamGUI/PreferencesUI.py:5114 flatcamGUI/PreferencesUI.py:5122 -#: flatcamTools/ToolNonCopperClear.py:164 -#: flatcamTools/ToolNonCopperClear.py:172 +#: flatcamGUI/PreferencesUI.py:5398 flatcamGUI/PreferencesUI.py:5964 +#: flatcamTools/ToolNCC.py:280 flatcamTools/ToolPaint.py:263 msgid "" -"Milling type when the selected tool is of type: 'iso_op':\n" -"- climb / best for precision milling and to reduce tool usage\n" -"- conventional / useful when there is no backlash compensation" +"Diameter for the new tool to add in the Tool Table.\n" +"If the tool is V-shape type then this value is automatically\n" +"calculated from the other parameters." msgstr "" -"Tipul de frezare cand unealta selectată este de tipul: 'iso_op':\n" -"- urcare -> potrivit pentru frezare de precizie și pt a reduce uzura " -"uneltei\n" -"- conventional -> pentru cazul când nu exista o compensare a 'backlash-ului'" +"Diametru pentru Unealta nouă de adăugat în Tabelul Uneltelor.\n" +"Dacă instrumentul este în formă de V, atunci această valoare este automat\n" +"calculată din ceilalți parametri." -#: flatcamGUI/PreferencesUI.py:5131 flatcamGUI/PreferencesUI.py:5546 -#: flatcamTools/ToolNonCopperClear.py:181 flatcamTools/ToolPaint.py:153 +#: flatcamGUI/PreferencesUI.py:5435 flatcamGUI/PreferencesUI.py:5981 +#: flatcamTools/ToolNCC.py:174 flatcamTools/ToolPaint.py:158 msgid "Tool order" msgstr "Ordine unelte" -#: flatcamGUI/PreferencesUI.py:5132 flatcamGUI/PreferencesUI.py:5142 -#: flatcamGUI/PreferencesUI.py:5547 flatcamGUI/PreferencesUI.py:5557 -#: flatcamTools/ToolNonCopperClear.py:182 -#: flatcamTools/ToolNonCopperClear.py:192 flatcamTools/ToolPaint.py:154 -#: flatcamTools/ToolPaint.py:164 +#: flatcamGUI/PreferencesUI.py:5436 flatcamGUI/PreferencesUI.py:5446 +#: flatcamGUI/PreferencesUI.py:5982 flatcamTools/ToolNCC.py:175 +#: flatcamTools/ToolNCC.py:185 flatcamTools/ToolPaint.py:159 +#: flatcamTools/ToolPaint.py:169 msgid "" "This set the way that the tools in the tools table are used.\n" "'No' --> means that the used order is the one in the tool table\n" @@ -10875,69 +11339,39 @@ msgstr "" "AVERTIZARE: folosirea prelucrării 'resturi' va seta automat ordonarea\n" "în sens invers și va dezactiva acest control." -#: flatcamGUI/PreferencesUI.py:5140 flatcamGUI/PreferencesUI.py:5555 -#: flatcamTools/ToolNonCopperClear.py:190 flatcamTools/ToolPaint.py:162 +#: flatcamGUI/PreferencesUI.py:5444 flatcamGUI/PreferencesUI.py:5990 +#: flatcamTools/ToolNCC.py:183 flatcamTools/ToolPaint.py:167 msgid "Forward" msgstr "Înainte" -#: flatcamGUI/PreferencesUI.py:5141 flatcamGUI/PreferencesUI.py:5556 -#: flatcamTools/ToolNonCopperClear.py:191 flatcamTools/ToolPaint.py:163 +#: flatcamGUI/PreferencesUI.py:5445 flatcamGUI/PreferencesUI.py:5991 +#: flatcamTools/ToolNCC.py:184 flatcamTools/ToolPaint.py:168 msgid "Reverse" msgstr "Înapoi" -#: flatcamGUI/PreferencesUI.py:5154 flatcamTools/ToolNonCopperClear.py:321 +#: flatcamGUI/PreferencesUI.py:5545 +msgid "Offset value" +msgstr "Valoare Ofset" + +#: flatcamGUI/PreferencesUI.py:5547 msgid "" -"How much (fraction) of the tool width to overlap each tool pass.\n" -"Adjust the value starting with lower values\n" -"and increasing it if areas that should be cleared are still \n" -"not cleared.\n" -"Lower values = faster processing, faster execution on CNC.\n" -"Higher values = slow processing and slow execution on CNC\n" -"due of too many paths." +"If used, it will add an offset to the copper features.\n" +"The copper clearing will finish to a distance\n" +"from the copper features.\n" +"The value can be between 0.0 and 9999.9 FlatCAM units." msgstr "" -"Cat de mult (fracţie) din diametrul uneltei să se suprapună la fiecare " -"trecere a uneltei.\n" -"Ajustează valoarea incepand de la valori mici\n" -"și pe urma creste daca ariile care ar trebui >curățate< inca\n" -"nu sunt procesate.\n" -"Valori scazute = procesare rapida,execuţie rapida a PCB-ului.\n" -"Valori mari= procesare lenta cat și o execuţie la fel de lenta a PCB-ului,\n" -"datorita numărului mai mare de treceri-tăiere." +"Dacă este folosit, va adăuga un offset la traseele de cupru.\n" +"Curătarea de cupru se va termina la o anume distanță\n" +"de traseele de cupru.\n" +"Valoarea poate fi cuprinsă între 0 și 9999.9 unități FlatCAM." -#: flatcamGUI/PreferencesUI.py:5173 flatcamGUI/PreferencesUI.py:7177 -#: flatcamGUI/PreferencesUI.py:7419 flatcamGUI/PreferencesUI.py:7483 -#: flatcamTools/ToolCopperThieving.py:113 flatcamTools/ToolFiducials.py:174 -#: flatcamTools/ToolFiducials.py:237 flatcamTools/ToolNonCopperClear.py:339 -msgid "Bounding box margin." -msgstr "Marginea pentru forma înconjurătoare." - -#: flatcamGUI/PreferencesUI.py:5186 flatcamGUI/PreferencesUI.py:5604 -#: flatcamTools/ToolNonCopperClear.py:350 -msgid "" -"Algorithm for non-copper clearing:
Standard: Fixed step inwards." -"
Seed-based: Outwards from seed.
Line-based: Parallel " -"lines." -msgstr "" -"Algoritm pt curățare de cupru:
Standard: Pas fix spre interior." -"
Punct-samanta: De la punctul samanta, spre expterior.
Linii " -"drepte: Linii paralele." - -#: flatcamGUI/PreferencesUI.py:5202 flatcamGUI/PreferencesUI.py:5618 -#: flatcamTools/ToolNonCopperClear.py:364 flatcamTools/ToolPaint.py:267 -msgid "Connect" -msgstr "Conectează" - -#: flatcamGUI/PreferencesUI.py:5211 flatcamGUI/PreferencesUI.py:5626 -#: flatcamTools/ToolNonCopperClear.py:371 flatcamTools/ToolPaint.py:274 -msgid "Contour" -msgstr "Contur" - -#: flatcamGUI/PreferencesUI.py:5220 flatcamTools/ToolNonCopperClear.py:379 -#: flatcamTools/ToolPaint.py:281 +#: flatcamGUI/PreferencesUI.py:5567 flatcamGUI/PreferencesUI.py:6083 +#: flatcamGUI/PreferencesUI.py:6084 flatcamTools/ToolNCC.py:512 +#: flatcamTools/ToolPaint.py:442 msgid "Rest Machining" msgstr "Prelucrare prin Resturi" -#: flatcamGUI/PreferencesUI.py:5222 flatcamTools/ToolNonCopperClear.py:381 +#: flatcamGUI/PreferencesUI.py:5569 flatcamTools/ToolNCC.py:516 msgid "" "If checked, use 'rest machining'.\n" "Basically it will clear copper outside PCB features,\n" @@ -10955,82 +11389,65 @@ msgstr "" "final. Aceasta deaorece unele unelte nu vor putea genera geometrie.\n" "Daca nu este bifat, foloseşte algoritmul standard." -#: flatcamGUI/PreferencesUI.py:5236 flatcamTools/ToolNonCopperClear.py:395 -#: flatcamTools/ToolNonCopperClear.py:405 +#: flatcamGUI/PreferencesUI.py:5588 flatcamGUI/PreferencesUI.py:6119 +#: flatcamGUI/PreferencesUI.py:7696 flatcamTools/ToolCopperThieving.py:127 +#: flatcamTools/ToolNCC.py:535 flatcamTools/ToolNCC.py:1309 +#: flatcamTools/ToolNCC.py:1651 flatcamTools/ToolNCC.py:1935 +#: flatcamTools/ToolNCC.py:1990 flatcamTools/ToolPaint.py:486 +#: flatcamTools/ToolPaint.py:939 flatcamTools/ToolPaint.py:1440 +msgid "Area Selection" +msgstr "Selecţie zonă" + +#: flatcamGUI/PreferencesUI.py:5588 flatcamGUI/PreferencesUI.py:6119 +#: flatcamGUI/PreferencesUI.py:7697 flatcamTools/ToolCopperThieving.py:128 +#: flatcamTools/ToolDblSided.py:217 flatcamTools/ToolNCC.py:535 +#: flatcamTools/ToolNCC.py:1667 flatcamTools/ToolNCC.py:1941 +#: flatcamTools/ToolNCC.py:1998 flatcamTools/ToolNCC.py:2306 +#: flatcamTools/ToolNCC.py:2586 flatcamTools/ToolNCC.py:3012 +#: flatcamTools/ToolPaint.py:486 flatcamTools/ToolPaint.py:924 +#: flatcamTools/ToolPaint.py:1456 +msgid "Reference Object" +msgstr "Obiect Ref" + +#: flatcamGUI/PreferencesUI.py:5592 flatcamTools/ToolNCC.py:541 msgid "" -"If used, it will add an offset to the copper features.\n" -"The copper clearing will finish to a distance\n" -"from the copper features.\n" -"The value can be between 0 and 10 FlatCAM units." -msgstr "" -"Dacă este folosit, va adăuga un offset la traseele de cupru.\n" -"Curătarea de cupru se va termina la o anume distanță\n" -"de traseele de cupru.\n" -"Valoarea poate fi cuprinsă între 0 și 10 unități FlatCAM." - -#: flatcamGUI/PreferencesUI.py:5245 flatcamTools/ToolNonCopperClear.py:403 -msgid "Offset value" -msgstr "Valoare Ofset" - -#: flatcamGUI/PreferencesUI.py:5247 -msgid "" -"If used, it will add an offset to the copper features.\n" -"The copper clearing will finish to a distance\n" -"from the copper features.\n" -"The value can be between 0.0 and 9999.9 FlatCAM units." -msgstr "" -"Dacă este folosit, va adăuga un offset la traseele de cupru.\n" -"Curătarea de cupru se va termina la o anume distanță\n" -"de traseele de cupru.\n" -"Valoarea poate fi cuprinsă între 0 și 9999.9 unități FlatCAM." - -#: flatcamGUI/PreferencesUI.py:5262 flatcamGUI/PreferencesUI.py:7189 -#: flatcamTools/ToolCopperThieving.py:125 -#: flatcamTools/ToolNonCopperClear.py:429 -msgid "Itself" -msgstr "Însuşi" - -#: flatcamGUI/PreferencesUI.py:5263 flatcamGUI/PreferencesUI.py:5646 -msgid "Area" -msgstr "Aria" - -#: flatcamGUI/PreferencesUI.py:5264 flatcamGUI/PreferencesUI.py:5648 -msgid "Ref" -msgstr "Ref" - -#: flatcamGUI/PreferencesUI.py:5267 -msgid "" -"- 'Itself' - the non copper clearing extent\n" -"is based on the object that is copper cleared.\n" +"Selection of area to be processed.\n" +"- 'Itself' - the processing extent is based on the object that is " +"processed.\n" " - 'Area Selection' - left mouse click to start selection of the area to be " -"painted.\n" -"Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple " -"areas.\n" -"- 'Reference Object' - will do non copper clearing within the area\n" -"specified by another object." +"processed.\n" +"- 'Reference Object' - will process the area specified by another object." msgstr "" -"- „Însuși” - suprafața de curățare a cuprului\n" -"se bazează pe obiectul care este curățat de cupru.\n" -"  - „Selecție zonă” - faceți clic stânga cu mouse-ul pentru a începe " -"selecția zonei care va fi pictată.\n" -"Menținerea unei taste de modificare apăsată (CTRL sau SHIFT) va permite " -"adăugarea mai multor zone.\n" -"- „Obiect de referință” - va face o curățare fără cupru în zona\n" -"specificată de un alt obiect." +"Selectia suprafetei pt procesare.\n" +"- „Însuși” - suprafața de procesare se bazează pe obiectul care este " +"procesat.\n" +"- „Selecție zonă” - faceți clic stânga cu mouse-ul pentru a începe selecția " +"zonei care va fi procesată.\n" +"- „Obiect de referință” - va procesa în zona specificată de un alt obiect." -#: flatcamGUI/PreferencesUI.py:5279 flatcamGUI/PreferencesUI.py:5654 +#: flatcamGUI/PreferencesUI.py:5601 flatcamGUI/PreferencesUI.py:6125 +#: flatcamTools/ToolNCC.py:578 flatcamTools/ToolPaint.py:522 +msgid "Shape" +msgstr "Formă" + +#: flatcamGUI/PreferencesUI.py:5603 flatcamGUI/PreferencesUI.py:6127 +#: flatcamTools/ToolNCC.py:580 flatcamTools/ToolPaint.py:524 +msgid "The kind of selection shape used for area selection." +msgstr "Selectează forma de selectie folosita pentru selectia zonală." + +#: flatcamGUI/PreferencesUI.py:5618 flatcamGUI/PreferencesUI.py:6142 msgid "Normal" msgstr "Normal" -#: flatcamGUI/PreferencesUI.py:5280 flatcamGUI/PreferencesUI.py:5655 +#: flatcamGUI/PreferencesUI.py:5619 flatcamGUI/PreferencesUI.py:6143 msgid "Progressive" msgstr "Progresiv" -#: flatcamGUI/PreferencesUI.py:5281 +#: flatcamGUI/PreferencesUI.py:5620 msgid "NCC Plotting" msgstr "Afisare NCC" -#: flatcamGUI/PreferencesUI.py:5283 +#: flatcamGUI/PreferencesUI.py:5622 msgid "" "- 'Normal' - normal plotting, done at the end of the NCC job\n" "- 'Progressive' - after each shape is generated it will be plotted." @@ -11038,16 +11455,16 @@ msgstr "" "- 'Normal' - afisare normală, efectuată la sfarsitul activitătii NCC\n" "- 'Progresiv' - forma se afisează imediat ce a fost generată." -#: flatcamGUI/PreferencesUI.py:5297 +#: flatcamGUI/PreferencesUI.py:5636 msgid "Cutout Tool Options" msgstr "Opțiuni Unealta Decupare" -#: flatcamGUI/PreferencesUI.py:5312 flatcamTools/ToolCalculators.py:123 -#: flatcamTools/ToolCutOut.py:123 +#: flatcamGUI/PreferencesUI.py:5651 flatcamTools/ToolCalculators.py:123 +#: flatcamTools/ToolCutOut.py:130 msgid "Tool Diameter" msgstr "Dia unealtă" -#: flatcamGUI/PreferencesUI.py:5314 flatcamTools/ToolCutOut.py:125 +#: flatcamGUI/PreferencesUI.py:5653 flatcamTools/ToolCutOut.py:132 msgid "" "Diameter of the tool used to cutout\n" "the PCB shape out of the surrounding material." @@ -11055,11 +11472,11 @@ msgstr "" "Diametrul uneltei folosita pt decuparea\n" "PCB-ului din materialului inconjurator." -#: flatcamGUI/PreferencesUI.py:5369 flatcamTools/ToolCutOut.py:104 +#: flatcamGUI/PreferencesUI.py:5708 msgid "Object kind" msgstr "Tipul de obiect" -#: flatcamGUI/PreferencesUI.py:5371 flatcamTools/ToolCutOut.py:106 +#: flatcamGUI/PreferencesUI.py:5710 flatcamTools/ToolCutOut.py:78 msgid "" "Choice of what kind the object we want to cutout is.
- Single: " "contain a single PCB Gerber outline object.
- Panel: a panel PCB " @@ -11071,15 +11488,15 @@ msgstr "" "tip panel, care este făcut\n" "din mai multe contururi PCB." -#: flatcamGUI/PreferencesUI.py:5378 flatcamTools/ToolCutOut.py:112 +#: flatcamGUI/PreferencesUI.py:5717 flatcamTools/ToolCutOut.py:84 msgid "Single" msgstr "Unic" -#: flatcamGUI/PreferencesUI.py:5379 flatcamTools/ToolCutOut.py:113 +#: flatcamGUI/PreferencesUI.py:5718 flatcamTools/ToolCutOut.py:85 msgid "Panel" msgstr "Panel" -#: flatcamGUI/PreferencesUI.py:5386 flatcamTools/ToolCutOut.py:186 +#: flatcamGUI/PreferencesUI.py:5725 flatcamTools/ToolCutOut.py:193 msgid "" "Margin over bounds. A positive value here\n" "will make the cutout of the PCB further from\n" @@ -11089,11 +11506,11 @@ msgstr "" "va face decuparea distanțat cu aceasta valoare \n" "fata de PCB-ul efectiv" -#: flatcamGUI/PreferencesUI.py:5399 flatcamTools/ToolCutOut.py:197 +#: flatcamGUI/PreferencesUI.py:5738 flatcamTools/ToolCutOut.py:204 msgid "Gap size" msgstr "Dim. punte" -#: flatcamGUI/PreferencesUI.py:5401 flatcamTools/ToolCutOut.py:199 +#: flatcamGUI/PreferencesUI.py:5740 flatcamTools/ToolCutOut.py:206 msgid "" "The size of the bridge gaps in the cutout\n" "used to keep the board connected to\n" @@ -11104,11 +11521,11 @@ msgstr "" "in a mentine ataşat PCB-ul la materialul de unde \n" "este decupat." -#: flatcamGUI/PreferencesUI.py:5415 flatcamTools/ToolCutOut.py:241 +#: flatcamGUI/PreferencesUI.py:5754 flatcamTools/ToolCutOut.py:250 msgid "Gaps" msgstr "Punţi" -#: flatcamGUI/PreferencesUI.py:5417 +#: flatcamGUI/PreferencesUI.py:5756 msgid "" "Number of gaps used for the cutout.\n" "There can be maximum 8 bridges/gaps.\n" @@ -11132,11 +11549,11 @@ msgstr "" "- 2tb = 2* sus - 2* jos\n" "- 8 = 2* stânga - 2* dreapta - 2* sus - 2* jos" -#: flatcamGUI/PreferencesUI.py:5439 flatcamTools/ToolCutOut.py:216 +#: flatcamGUI/PreferencesUI.py:5778 flatcamTools/ToolCutOut.py:223 msgid "Convex Shape" msgstr "Forma convexă" -#: flatcamGUI/PreferencesUI.py:5441 flatcamTools/ToolCutOut.py:219 +#: flatcamGUI/PreferencesUI.py:5780 flatcamTools/ToolCutOut.py:226 msgid "" "Create a convex shape surrounding the entire PCB.\n" "Used only if the source object type is Gerber." @@ -11145,11 +11562,11 @@ msgstr "" "tot PCB-ul. Forma sa este convexa.\n" "Se foloseste doar daca obiectul sursă este de tip Gerber." -#: flatcamGUI/PreferencesUI.py:5454 +#: flatcamGUI/PreferencesUI.py:5793 msgid "2Sided Tool Options" msgstr "Opțiuni Unealta 2Fețe" -#: flatcamGUI/PreferencesUI.py:5460 +#: flatcamGUI/PreferencesUI.py:5799 msgid "" "A tool to help in creating a double sided\n" "PCB using alignment holes." @@ -11157,36 +11574,41 @@ msgstr "" "O unealtă care ajuta in crearea de PCB-uri cu 2 fețe\n" "folosind găuri de aliniere." -#: flatcamGUI/PreferencesUI.py:5474 +#: flatcamGUI/PreferencesUI.py:5813 msgid "Drill dia" msgstr "Dia gaură" -#: flatcamGUI/PreferencesUI.py:5476 flatcamTools/ToolDblSided.py:274 -#: flatcamTools/ToolDblSided.py:285 +#: flatcamGUI/PreferencesUI.py:5815 flatcamTools/ToolDblSided.py:364 +#: flatcamTools/ToolDblSided.py:369 msgid "Diameter of the drill for the alignment holes." msgstr "Diametrul găurii pentru găurile de aliniere." -#: flatcamGUI/PreferencesUI.py:5485 flatcamTools/ToolDblSided.py:146 -msgid "Mirror Axis:" -msgstr "Axe oglindire:" +#: flatcamGUI/PreferencesUI.py:5822 flatcamTools/ToolDblSided.py:378 +msgid "Align Axis" +msgstr "Aliniați Axa" -#: flatcamGUI/PreferencesUI.py:5487 flatcamTools/ToolDblSided.py:147 +#: flatcamGUI/PreferencesUI.py:5824 flatcamGUI/PreferencesUI.py:5837 +#: flatcamTools/ToolDblSided.py:166 flatcamTools/ToolDblSided.py:380 msgid "Mirror vertically (X) or horizontally (Y)." msgstr "Oglindește vertical (X) sau orizontal (Y)." -#: flatcamGUI/PreferencesUI.py:5496 flatcamTools/ToolDblSided.py:156 +#: flatcamGUI/PreferencesUI.py:5835 +msgid "Mirror Axis:" +msgstr "Axe oglindire:" + +#: flatcamGUI/PreferencesUI.py:5846 flatcamTools/ToolDblSided.py:182 msgid "Point" msgstr "Punct" -#: flatcamGUI/PreferencesUI.py:5497 flatcamTools/ToolDblSided.py:157 +#: flatcamGUI/PreferencesUI.py:5847 flatcamTools/ToolDblSided.py:183 msgid "Box" msgstr "Forma" -#: flatcamGUI/PreferencesUI.py:5498 flatcamTools/ToolDblSided.py:158 +#: flatcamGUI/PreferencesUI.py:5848 msgid "Axis Ref" msgstr "Axa de Ref" -#: flatcamGUI/PreferencesUI.py:5500 flatcamTools/ToolDblSided.py:160 +#: flatcamGUI/PreferencesUI.py:5850 msgid "" "The axis should pass through a point or cut\n" " a specified box (in a FlatCAM object) through \n" @@ -11195,48 +11617,66 @@ msgstr "" "Axa de referinţă ar trebui să treacă printr-un punct ori să strabata\n" " o forma (obiect FlatCAM) prin mijloc." -#: flatcamGUI/PreferencesUI.py:5516 +#: flatcamGUI/PreferencesUI.py:5866 msgid "Paint Tool Options" msgstr "Opțiuni Unealta Paint" -#: flatcamGUI/PreferencesUI.py:5522 +#: flatcamGUI/PreferencesUI.py:5872 msgid "Parameters:" msgstr "Parametri:" -#: flatcamGUI/PreferencesUI.py:5636 flatcamTools/ToolPaint.py:296 -#: flatcamTools/ToolPaint.py:313 +#: flatcamGUI/PreferencesUI.py:6086 flatcamTools/ToolPaint.py:445 msgid "" -"How to select Polygons to be painted.\n" +"If checked, use 'rest machining'.\n" +"Basically it will clear copper outside PCB features,\n" +"using the biggest tool and continue with the next tools,\n" +"from bigger to smaller, to clear areas of copper that\n" +"could not be cleared by previous tool, until there is\n" +"no more copper to clear or there are no more tools.\n" +"\n" +"If not checked, use the standard algorithm." +msgstr "" +"Daca este bifat, foloste 'rest machining'.\n" +"Mai exact, se va curăța cuprul din afara traseelor,\n" +"folosind mai intai unealta cu diametrul cel mai mare\n" +"apoi folosindu-se progresiv unelte cu diametrul tot\n" +"mai mic, din cele disponibile in tabela de unelte, pt a\n" +"curăța zonele care nu s-au putut curăța cu unealta\n" +"precedenta.\n" +"Daca nu este bifat, foloseşte algoritmul standard." + +#: flatcamGUI/PreferencesUI.py:6099 flatcamTools/ToolPaint.py:458 +msgid "" +"Selection of area to be processed.\n" "- 'Polygon Selection' - left mouse click to add/remove polygons to be " -"painted.\n" +"processed.\n" "- 'Area Selection' - left mouse click to start selection of the area to be " -"painted.\n" +"processed.\n" "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple " "areas.\n" -"- 'All Polygons' - the Paint will start after click.\n" -"- 'Reference Object' - will do non copper clearing within the area\n" -"specified by another object." +"- 'All Polygons' - the process will start after click.\n" +"- 'Reference Object' - will process the area specified by another object." msgstr "" -"Cum se selectează Poligoanele care vor fi pictate.\n" +"Selectia suprafetei care va fi procesată.\n" "- „Selecție poligon” - faceți clic stânga pentru a adăuga / elimina " -"poligoane care urmează să fie pictate.\n" +"poligoane care urmează să fie procesate.\n" "- „Selecție zonă” - faceți clic stânga cu mouse-ul pentru a începe selecția " -"zonei care va fi pictată.\n" +"zonei care va fi procesată.\n" "Menținerea unei taste modificatoare apăsată (CTRL sau SHIFT) va permite " "adăugarea mai multor zone.\n" -"- „Toate Poligoanele” - Unealta Paint va începe după clic.\n" -"- „Obiect de referință” - va face o curățare fără cupru în zona specificată " -"de un alt obiect." +"- „Toate Poligoanele” - procesarea va începe după clic.\n" +"- „Obiect de referință” - se va procesa zona specificată de un alt obiect." -#: flatcamGUI/PreferencesUI.py:5645 -msgid "Sel" -msgstr "Selectează" +#: flatcamGUI/PreferencesUI.py:6119 flatcamTools/ToolPaint.py:486 +#: flatcamTools/ToolPaint.py:935 flatcamTools/ToolPaint.py:1420 +msgid "Polygon Selection" +msgstr "Selecție Poligon" -#: flatcamGUI/PreferencesUI.py:5656 +#: flatcamGUI/PreferencesUI.py:6144 msgid "Paint Plotting" msgstr "Afisare Paint" -#: flatcamGUI/PreferencesUI.py:5658 +#: flatcamGUI/PreferencesUI.py:6146 msgid "" "- 'Normal' - normal plotting, done at the end of the Paint job\n" "- 'Progressive' - after each shape is generated it will be plotted." @@ -11244,11 +11684,11 @@ msgstr "" "- 'Normal' - afisare normală, efectuată la sfarsitul activitătii Paint\n" "- 'Progresiv' - forma se afisează imediat ce a fost generată." -#: flatcamGUI/PreferencesUI.py:5672 +#: flatcamGUI/PreferencesUI.py:6160 msgid "Film Tool Options" msgstr "Opțiuni Unealta Film" -#: flatcamGUI/PreferencesUI.py:5678 +#: flatcamGUI/PreferencesUI.py:6166 msgid "" "Create a PCB film from a Gerber or Geometry\n" "FlatCAM object.\n" @@ -11257,11 +11697,11 @@ msgstr "" "Crează un film PCB dintr-un obiect Gerber sau tip Geometrie.\n" "Fişierul este salvat in format SVG." -#: flatcamGUI/PreferencesUI.py:5689 +#: flatcamGUI/PreferencesUI.py:6177 msgid "Film Type" msgstr "Tip film" -#: flatcamGUI/PreferencesUI.py:5691 flatcamTools/ToolFilm.py:300 +#: flatcamGUI/PreferencesUI.py:6179 flatcamTools/ToolFilm.py:300 msgid "" "Generate a Positive black film or a Negative film.\n" "Positive means that it will print the features\n" @@ -11275,19 +11715,19 @@ msgstr "" "Negativ = traseele vor fi albe pe un fundal negru.\n" "Formatul fişierului pt filmul salvat este SVG." -#: flatcamGUI/PreferencesUI.py:5702 +#: flatcamGUI/PreferencesUI.py:6190 msgid "Film Color" msgstr "Film Color" -#: flatcamGUI/PreferencesUI.py:5704 +#: flatcamGUI/PreferencesUI.py:6192 msgid "Set the film color when positive film is selected." msgstr "Setați culoarea filmului atunci când este selectat filmul pozitiv." -#: flatcamGUI/PreferencesUI.py:5727 flatcamTools/ToolFilm.py:316 +#: flatcamGUI/PreferencesUI.py:6215 flatcamTools/ToolFilm.py:316 msgid "Border" msgstr "Bordură" -#: flatcamGUI/PreferencesUI.py:5729 flatcamTools/ToolFilm.py:318 +#: flatcamGUI/PreferencesUI.py:6217 flatcamTools/ToolFilm.py:318 msgid "" "Specify a border around the object.\n" "Only for negative film.\n" @@ -11304,11 +11744,11 @@ msgstr "" "Va crea o bara solidă neagră in jurul printului efectiv permitand o\n" "delimitare exactă." -#: flatcamGUI/PreferencesUI.py:5746 flatcamTools/ToolFilm.py:283 +#: flatcamGUI/PreferencesUI.py:6234 flatcamTools/ToolFilm.py:283 msgid "Scale Stroke" msgstr "Scalează" -#: flatcamGUI/PreferencesUI.py:5748 flatcamTools/ToolFilm.py:285 +#: flatcamGUI/PreferencesUI.py:6236 flatcamTools/ToolFilm.py:285 msgid "" "Scale the line stroke thickness of each feature in the SVG file.\n" "It means that the line that envelope each SVG feature will be thicker or " @@ -11318,11 +11758,11 @@ msgstr "" "Scalează grosimea conturului fiecarui element din fişierul SVG.\n" "Elementele mai mici vor fi afectate mai mult." -#: flatcamGUI/PreferencesUI.py:5755 flatcamTools/ToolFilm.py:141 +#: flatcamGUI/PreferencesUI.py:6243 flatcamTools/ToolFilm.py:141 msgid "Film Adjustments" msgstr "Reglarea filmelor" -#: flatcamGUI/PreferencesUI.py:5757 flatcamTools/ToolFilm.py:143 +#: flatcamGUI/PreferencesUI.py:6245 flatcamTools/ToolFilm.py:143 msgid "" "Sometime the printers will distort the print shape, especially the Laser " "types.\n" @@ -11333,11 +11773,11 @@ msgstr "" "Această secțiune oferă instrumentele pentru a compensa distorsiunile de " "tipărire." -#: flatcamGUI/PreferencesUI.py:5764 flatcamTools/ToolFilm.py:150 +#: flatcamGUI/PreferencesUI.py:6252 flatcamTools/ToolFilm.py:150 msgid "Scale Film geometry" msgstr "Scalați geo film" -#: flatcamGUI/PreferencesUI.py:5766 flatcamTools/ToolFilm.py:152 +#: flatcamGUI/PreferencesUI.py:6254 flatcamTools/ToolFilm.py:152 msgid "" "A value greater than 1 will stretch the film\n" "while a value less than 1 will jolt it." @@ -11345,21 +11785,21 @@ msgstr "" "O valoare mai mare de 1 va întinde filmul\n" "în timp ce o valoare mai mică de 1 il va compacta." -#: flatcamGUI/PreferencesUI.py:5776 flatcamGUI/PreferencesUI.py:6296 -#: flatcamTools/ToolFilm.py:162 flatcamTools/ToolTransform.py:148 +#: flatcamGUI/PreferencesUI.py:6264 flatcamGUI/PreferencesUI.py:6783 +#: flatcamTools/ToolFilm.py:162 flatcamTools/ToolTransform.py:149 msgid "X factor" msgstr "Factor X" -#: flatcamGUI/PreferencesUI.py:5785 flatcamGUI/PreferencesUI.py:6309 +#: flatcamGUI/PreferencesUI.py:6273 flatcamGUI/PreferencesUI.py:6796 #: flatcamTools/ToolFilm.py:171 flatcamTools/ToolTransform.py:169 msgid "Y factor" msgstr "Factor Y" -#: flatcamGUI/PreferencesUI.py:5795 flatcamTools/ToolFilm.py:189 +#: flatcamGUI/PreferencesUI.py:6283 flatcamTools/ToolFilm.py:189 msgid "Skew Film geometry" msgstr "Deformeaza Geo Film" -#: flatcamGUI/PreferencesUI.py:5797 flatcamTools/ToolFilm.py:191 +#: flatcamGUI/PreferencesUI.py:6285 flatcamTools/ToolFilm.py:191 msgid "" "Positive values will skew to the right\n" "while negative values will skew to the left." @@ -11367,17 +11807,17 @@ msgstr "" "Valorile pozitive vor înclina spre dreapta\n" "în timp ce valorile negative vor înclina spre stânga." -#: flatcamGUI/PreferencesUI.py:5807 flatcamGUI/PreferencesUI.py:6265 +#: flatcamGUI/PreferencesUI.py:6295 flatcamGUI/PreferencesUI.py:6752 #: flatcamTools/ToolFilm.py:201 flatcamTools/ToolTransform.py:98 msgid "X angle" msgstr "Unghi X" -#: flatcamGUI/PreferencesUI.py:5816 flatcamGUI/PreferencesUI.py:6279 -#: flatcamTools/ToolFilm.py:210 flatcamTools/ToolTransform.py:120 +#: flatcamGUI/PreferencesUI.py:6304 flatcamGUI/PreferencesUI.py:6766 +#: flatcamTools/ToolFilm.py:210 flatcamTools/ToolTransform.py:119 msgid "Y angle" msgstr "Unghi Y" -#: flatcamGUI/PreferencesUI.py:5827 flatcamTools/ToolFilm.py:221 +#: flatcamGUI/PreferencesUI.py:6315 flatcamTools/ToolFilm.py:221 msgid "" "The reference point to be used as origin for the skew.\n" "It can be one of the four points of the geometry bounding box." @@ -11386,57 +11826,53 @@ msgstr "" "Poate fi unul dintre cele patru puncte ale căsuței de delimitare a " "geometriei." -#: flatcamGUI/PreferencesUI.py:5830 flatcamTools/ToolFiducials.py:87 +#: flatcamGUI/PreferencesUI.py:6318 flatcamTools/ToolFiducials.py:87 #: flatcamTools/ToolFilm.py:224 msgid "Bottom Left" msgstr "Stânga jos" -#: flatcamGUI/PreferencesUI.py:5831 flatcamTools/ToolFilm.py:225 +#: flatcamGUI/PreferencesUI.py:6319 flatcamTools/ToolFilm.py:225 msgid "Top Left" msgstr "Stânga sus" -#: flatcamGUI/PreferencesUI.py:5832 flatcamTools/ToolFilm.py:226 +#: flatcamGUI/PreferencesUI.py:6320 flatcamTools/ToolFilm.py:226 msgid "Bottom Right" msgstr "Dreapta-jos" -#: flatcamGUI/PreferencesUI.py:5833 flatcamTools/ToolFilm.py:227 +#: flatcamGUI/PreferencesUI.py:6321 flatcamTools/ToolFilm.py:227 msgid "Top right" msgstr "Dreapta-sus" -#: flatcamGUI/PreferencesUI.py:5841 flatcamTools/ToolFilm.py:244 +#: flatcamGUI/PreferencesUI.py:6329 flatcamTools/ToolFilm.py:244 msgid "Mirror Film geometry" msgstr "Oglindeste Geo Film" -#: flatcamGUI/PreferencesUI.py:5843 flatcamTools/ToolFilm.py:246 +#: flatcamGUI/PreferencesUI.py:6331 flatcamTools/ToolFilm.py:246 msgid "Mirror the film geometry on the selected axis or on both." msgstr "Oglindeste geometria filmului pe axa selectată sau pe ambele." -#: flatcamGUI/PreferencesUI.py:5855 flatcamTools/ToolFilm.py:258 -msgid "Both" -msgstr "Ambele" - -#: flatcamGUI/PreferencesUI.py:5857 flatcamTools/ToolFilm.py:260 +#: flatcamGUI/PreferencesUI.py:6345 flatcamTools/ToolFilm.py:260 msgid "Mirror axis" msgstr "Axe oglindire" -#: flatcamGUI/PreferencesUI.py:5867 flatcamTools/ToolFilm.py:403 +#: flatcamGUI/PreferencesUI.py:6355 flatcamTools/ToolFilm.py:405 msgid "SVG" msgstr "SVG" -#: flatcamGUI/PreferencesUI.py:5868 flatcamTools/ToolFilm.py:404 +#: flatcamGUI/PreferencesUI.py:6356 flatcamTools/ToolFilm.py:406 msgid "PNG" msgstr "PNG" -#: flatcamGUI/PreferencesUI.py:5869 flatcamTools/ToolFilm.py:405 +#: flatcamGUI/PreferencesUI.py:6357 flatcamTools/ToolFilm.py:407 msgid "PDF" msgstr "PDF" -#: flatcamGUI/PreferencesUI.py:5872 flatcamTools/ToolFilm.py:298 -#: flatcamTools/ToolFilm.py:408 +#: flatcamGUI/PreferencesUI.py:6360 flatcamTools/ToolFilm.py:298 +#: flatcamTools/ToolFilm.py:410 msgid "Film Type:" msgstr "Tip film:" -#: flatcamGUI/PreferencesUI.py:5874 flatcamTools/ToolFilm.py:410 +#: flatcamGUI/PreferencesUI.py:6362 flatcamTools/ToolFilm.py:412 msgid "" "The file type of the saved film. Can be:\n" "- 'SVG' -> open-source vectorial format\n" @@ -11448,23 +11884,23 @@ msgstr "" "- „PNG” -> imagine raster\n" "- „PDF” -> format document portabil" -#: flatcamGUI/PreferencesUI.py:5883 flatcamTools/ToolFilm.py:419 +#: flatcamGUI/PreferencesUI.py:6371 flatcamTools/ToolFilm.py:421 msgid "Page Orientation" msgstr "Orientarea paginii" -#: flatcamGUI/PreferencesUI.py:5896 flatcamTools/ToolFilm.py:432 +#: flatcamGUI/PreferencesUI.py:6384 flatcamTools/ToolFilm.py:434 msgid "Page Size" msgstr "Mărimea paginii" -#: flatcamGUI/PreferencesUI.py:5897 flatcamTools/ToolFilm.py:433 +#: flatcamGUI/PreferencesUI.py:6385 flatcamTools/ToolFilm.py:435 msgid "A selection of standard ISO 216 page sizes." msgstr "O selecție de dimensiuni standard de pagină conform ISO 216." -#: flatcamGUI/PreferencesUI.py:5969 +#: flatcamGUI/PreferencesUI.py:6457 msgid "Panelize Tool Options" msgstr "Opțiuni Unealta Panelizare" -#: flatcamGUI/PreferencesUI.py:5975 +#: flatcamGUI/PreferencesUI.py:6463 msgid "" "Create an object that contains an array of (x, y) elements,\n" "each element is a copy of the source object spaced\n" @@ -11474,11 +11910,11 @@ msgstr "" "unde fiecare element este o copie a obiectului sursa, separat la o\n" "distanţă X, Y unul de celalalt." -#: flatcamGUI/PreferencesUI.py:5992 flatcamTools/ToolPanelize.py:160 +#: flatcamGUI/PreferencesUI.py:6480 flatcamTools/ToolPanelize.py:163 msgid "Spacing cols" msgstr "Sep. coloane" -#: flatcamGUI/PreferencesUI.py:5994 flatcamTools/ToolPanelize.py:162 +#: flatcamGUI/PreferencesUI.py:6482 flatcamTools/ToolPanelize.py:165 msgid "" "Spacing between columns of the desired panel.\n" "In current units." @@ -11486,11 +11922,11 @@ msgstr "" "Spatiul de separare între coloane.\n" "In unitatile curente." -#: flatcamGUI/PreferencesUI.py:6006 flatcamTools/ToolPanelize.py:172 +#: flatcamGUI/PreferencesUI.py:6494 flatcamTools/ToolPanelize.py:175 msgid "Spacing rows" msgstr "Sep. linii" -#: flatcamGUI/PreferencesUI.py:6008 flatcamTools/ToolPanelize.py:174 +#: flatcamGUI/PreferencesUI.py:6496 flatcamTools/ToolPanelize.py:177 msgid "" "Spacing between rows of the desired panel.\n" "In current units." @@ -11498,36 +11934,31 @@ msgstr "" "Spatiul de separare între linii.\n" "In unitatile curente." -#: flatcamGUI/PreferencesUI.py:6019 flatcamTools/ToolPanelize.py:183 +#: flatcamGUI/PreferencesUI.py:6507 flatcamTools/ToolPanelize.py:186 msgid "Columns" msgstr "Coloane" -#: flatcamGUI/PreferencesUI.py:6021 flatcamTools/ToolPanelize.py:185 +#: flatcamGUI/PreferencesUI.py:6509 flatcamTools/ToolPanelize.py:188 msgid "Number of columns of the desired panel" msgstr "Numărul de coloane ale panel-ului dorit" -#: flatcamGUI/PreferencesUI.py:6031 flatcamTools/ToolPanelize.py:193 +#: flatcamGUI/PreferencesUI.py:6519 flatcamTools/ToolPanelize.py:196 msgid "Rows" msgstr "Linii" -#: flatcamGUI/PreferencesUI.py:6033 flatcamTools/ToolPanelize.py:195 +#: flatcamGUI/PreferencesUI.py:6521 flatcamTools/ToolPanelize.py:198 msgid "Number of rows of the desired panel" msgstr "Numărul de linii ale panel-ului dorit" -#: flatcamGUI/PreferencesUI.py:6039 flatcamTools/ToolCalibration.py:196 -#: flatcamTools/ToolCalibration.py:634 flatcamTools/ToolPanelize.py:201 -msgid "Gerber" -msgstr "Gerber" - -#: flatcamGUI/PreferencesUI.py:6040 flatcamTools/ToolPanelize.py:202 +#: flatcamGUI/PreferencesUI.py:6528 flatcamTools/ToolPanelize.py:205 msgid "Geo" msgstr "Geo" -#: flatcamGUI/PreferencesUI.py:6041 flatcamTools/ToolPanelize.py:203 +#: flatcamGUI/PreferencesUI.py:6529 flatcamTools/ToolPanelize.py:206 msgid "Panel Type" msgstr "Tip panel" -#: flatcamGUI/PreferencesUI.py:6043 +#: flatcamGUI/PreferencesUI.py:6531 msgid "" "Choose the type of object for the panel object:\n" "- Gerber\n" @@ -11537,11 +11968,11 @@ msgstr "" "- Gerber\n" "- Geometrie" -#: flatcamGUI/PreferencesUI.py:6052 +#: flatcamGUI/PreferencesUI.py:6540 msgid "Constrain within" msgstr "Constrange" -#: flatcamGUI/PreferencesUI.py:6054 flatcamTools/ToolPanelize.py:215 +#: flatcamGUI/PreferencesUI.py:6542 flatcamTools/ToolPanelize.py:218 msgid "" "Area define by DX and DY within to constrain the panel.\n" "DX and DY values are in current units.\n" @@ -11555,11 +11986,11 @@ msgstr "" "panelul final va contine numai acel număr de linii/coloane care se inscrie\n" "complet in aria desemnata." -#: flatcamGUI/PreferencesUI.py:6067 flatcamTools/ToolPanelize.py:227 +#: flatcamGUI/PreferencesUI.py:6555 flatcamTools/ToolPanelize.py:230 msgid "Width (DX)" msgstr "Lătime (Dx)" -#: flatcamGUI/PreferencesUI.py:6069 flatcamTools/ToolPanelize.py:229 +#: flatcamGUI/PreferencesUI.py:6557 flatcamTools/ToolPanelize.py:232 msgid "" "The width (DX) within which the panel must fit.\n" "In current units." @@ -11567,11 +11998,11 @@ msgstr "" "Lăţimea (Dx) in care panelul trebuie să se inscrie.\n" "In unitati curente." -#: flatcamGUI/PreferencesUI.py:6080 flatcamTools/ToolPanelize.py:238 +#: flatcamGUI/PreferencesUI.py:6568 flatcamTools/ToolPanelize.py:241 msgid "Height (DY)" msgstr "Inăltime (Dy)" -#: flatcamGUI/PreferencesUI.py:6082 flatcamTools/ToolPanelize.py:240 +#: flatcamGUI/PreferencesUI.py:6570 flatcamTools/ToolPanelize.py:243 msgid "" "The height (DY)within which the panel must fit.\n" "In current units." @@ -11579,15 +12010,15 @@ msgstr "" "Înălţimea (Dy) in care panelul trebuie să se inscrie.\n" "In unitati curente." -#: flatcamGUI/PreferencesUI.py:6096 +#: flatcamGUI/PreferencesUI.py:6584 msgid "Calculators Tool Options" msgstr "Opțiuni Unealta Calculatoare" -#: flatcamGUI/PreferencesUI.py:6100 flatcamTools/ToolCalculators.py:25 +#: flatcamGUI/PreferencesUI.py:6588 flatcamTools/ToolCalculators.py:25 msgid "V-Shape Tool Calculator" msgstr "Calculator Unealta V-Shape" -#: flatcamGUI/PreferencesUI.py:6102 +#: flatcamGUI/PreferencesUI.py:6590 msgid "" "Calculate the tool diameter for a given V-shape tool,\n" "having the tip diameter, tip angle and\n" @@ -11597,11 +12028,11 @@ msgstr "" "avand diametrul vârfului și unghiul la vârf cat și\n" "adâncimea de tăiere, ca parametri." -#: flatcamGUI/PreferencesUI.py:6117 flatcamTools/ToolCalculators.py:94 +#: flatcamGUI/PreferencesUI.py:6607 flatcamTools/ToolCalculators.py:94 msgid "Tip Diameter" msgstr "Dia vârf" -#: flatcamGUI/PreferencesUI.py:6119 flatcamTools/ToolCalculators.py:102 +#: flatcamGUI/PreferencesUI.py:6609 flatcamTools/ToolCalculators.py:102 msgid "" "This is the tool tip diameter.\n" "It is specified by manufacturer." @@ -11609,11 +12040,11 @@ msgstr "" "Acesta este diametrul la vârf al uneltei.\n" "Este specificat de producator." -#: flatcamGUI/PreferencesUI.py:6131 flatcamTools/ToolCalculators.py:105 +#: flatcamGUI/PreferencesUI.py:6621 flatcamTools/ToolCalculators.py:105 msgid "Tip Angle" msgstr "V-Unghi" -#: flatcamGUI/PreferencesUI.py:6133 +#: flatcamGUI/PreferencesUI.py:6623 msgid "" "This is the angle on the tip of the tool.\n" "It is specified by manufacturer." @@ -11621,7 +12052,7 @@ msgstr "" "Acesta este unghiul la vârf al uneltei.\n" "Este specificat de producator." -#: flatcamGUI/PreferencesUI.py:6147 +#: flatcamGUI/PreferencesUI.py:6637 msgid "" "This is depth to cut into material.\n" "In the CNCJob object it is the CutZ parameter." @@ -11629,11 +12060,11 @@ msgstr "" "Aceasta este adâncimea la care se taie in material.\n" "In obiectul CNCJob este parametrul >Z tăiere<." -#: flatcamGUI/PreferencesUI.py:6154 flatcamTools/ToolCalculators.py:27 +#: flatcamGUI/PreferencesUI.py:6644 flatcamTools/ToolCalculators.py:27 msgid "ElectroPlating Calculator" msgstr "Calculator ElectroPlacare" -#: flatcamGUI/PreferencesUI.py:6156 flatcamTools/ToolCalculators.py:158 +#: flatcamGUI/PreferencesUI.py:6646 flatcamTools/ToolCalculators.py:158 msgid "" "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 " @@ -11645,31 +12076,31 @@ msgstr "" "- clorura paladiu\n" "- hipofosfit de calciu." -#: flatcamGUI/PreferencesUI.py:6170 flatcamTools/ToolCalculators.py:167 +#: flatcamGUI/PreferencesUI.py:6657 flatcamTools/ToolCalculators.py:167 msgid "Board Length" msgstr "Lung. plăcii" -#: flatcamGUI/PreferencesUI.py:6172 flatcamTools/ToolCalculators.py:173 +#: flatcamGUI/PreferencesUI.py:6659 flatcamTools/ToolCalculators.py:173 msgid "This is the board length. In centimeters." msgstr "" "Aceasta este lungimea PCB-ului.\n" "In centimetri." -#: flatcamGUI/PreferencesUI.py:6182 flatcamTools/ToolCalculators.py:175 +#: flatcamGUI/PreferencesUI.py:6669 flatcamTools/ToolCalculators.py:175 msgid "Board Width" msgstr "Lăt. plăcii" -#: flatcamGUI/PreferencesUI.py:6184 flatcamTools/ToolCalculators.py:181 +#: flatcamGUI/PreferencesUI.py:6671 flatcamTools/ToolCalculators.py:181 msgid "This is the board width.In centimeters." msgstr "" "Aceasta este lăţimea PCB-ului.\n" "In centimetri." -#: flatcamGUI/PreferencesUI.py:6189 flatcamTools/ToolCalculators.py:183 +#: flatcamGUI/PreferencesUI.py:6676 flatcamTools/ToolCalculators.py:183 msgid "Current Density" msgstr "Densitate I" -#: flatcamGUI/PreferencesUI.py:6195 flatcamTools/ToolCalculators.py:190 +#: flatcamGUI/PreferencesUI.py:6682 flatcamTools/ToolCalculators.py:190 msgid "" "Current density to pass through the board. \n" "In Amps per Square Feet ASF." @@ -11677,11 +12108,11 @@ msgstr "" "Densitatea de curent care să treaca prin placa.\n" "In ASF (amperi pe picior la patrat)." -#: flatcamGUI/PreferencesUI.py:6201 flatcamTools/ToolCalculators.py:193 +#: flatcamGUI/PreferencesUI.py:6688 flatcamTools/ToolCalculators.py:193 msgid "Copper Growth" msgstr "Grosime Cu" -#: flatcamGUI/PreferencesUI.py:6207 flatcamTools/ToolCalculators.py:200 +#: flatcamGUI/PreferencesUI.py:6694 flatcamTools/ToolCalculators.py:200 msgid "" "How thick the copper growth is intended to be.\n" "In microns." @@ -11689,11 +12120,11 @@ msgstr "" "Cat de gros se dorește să fie stratul de cupru depus.\n" "In microni." -#: flatcamGUI/PreferencesUI.py:6220 +#: flatcamGUI/PreferencesUI.py:6707 msgid "Transform Tool Options" msgstr "Opțiuni Unealta Transformare" -#: flatcamGUI/PreferencesUI.py:6226 +#: flatcamGUI/PreferencesUI.py:6713 msgid "" "Various transformations that can be applied\n" "on a FlatCAM object." @@ -11701,19 +12132,19 @@ msgstr "" "Diverse transformări care pot fi aplicate\n" "asupra unui obiect FlatCAM." -#: flatcamGUI/PreferencesUI.py:6257 +#: flatcamGUI/PreferencesUI.py:6744 msgid "Skew" msgstr "Deformare" -#: flatcamGUI/PreferencesUI.py:6298 flatcamTools/ToolTransform.py:150 +#: flatcamGUI/PreferencesUI.py:6785 flatcamTools/ToolTransform.py:151 msgid "Factor for scaling on X axis." msgstr "Factor de scalare pe axa X." -#: flatcamGUI/PreferencesUI.py:6311 flatcamTools/ToolTransform.py:171 +#: flatcamGUI/PreferencesUI.py:6798 flatcamTools/ToolTransform.py:171 msgid "Factor for scaling on Y axis." msgstr "Factor de scalare pe axa Y." -#: flatcamGUI/PreferencesUI.py:6319 flatcamTools/ToolTransform.py:194 +#: flatcamGUI/PreferencesUI.py:6806 flatcamTools/ToolTransform.py:192 msgid "" "Scale the selected object(s)\n" "using the Scale_X factor for both axis." @@ -11721,7 +12152,7 @@ msgstr "" "Scalează obiectele selectate folosind\n" "Factor Scal_X pentru ambele axe." -#: flatcamGUI/PreferencesUI.py:6327 flatcamTools/ToolTransform.py:202 +#: flatcamGUI/PreferencesUI.py:6814 flatcamTools/ToolTransform.py:199 msgid "" "Scale the selected object(s)\n" "using the origin reference when checked,\n" @@ -11734,32 +12165,32 @@ msgstr "" "centrul formei inconjuatoare care cuprinde\n" "toate obiectele selectate." -#: flatcamGUI/PreferencesUI.py:6343 flatcamTools/ToolTransform.py:217 +#: flatcamGUI/PreferencesUI.py:6830 flatcamTools/ToolTransform.py:218 msgid "X val" msgstr "Val X" -#: flatcamGUI/PreferencesUI.py:6345 flatcamTools/ToolTransform.py:219 +#: flatcamGUI/PreferencesUI.py:6832 flatcamTools/ToolTransform.py:220 msgid "Distance to offset on X axis. In current units." msgstr "Distanta la care se face ofset pe axa X. In unitatile curente." -#: flatcamGUI/PreferencesUI.py:6356 flatcamTools/ToolTransform.py:238 +#: flatcamGUI/PreferencesUI.py:6843 flatcamTools/ToolTransform.py:238 msgid "Y val" msgstr "Val Y" -#: flatcamGUI/PreferencesUI.py:6358 flatcamTools/ToolTransform.py:240 +#: flatcamGUI/PreferencesUI.py:6845 flatcamTools/ToolTransform.py:240 msgid "Distance to offset on Y axis. In current units." msgstr "Distanta la care se face ofset pe axa Y. In unitatile curente." -#: flatcamGUI/PreferencesUI.py:6364 flatcamTools/ToolDblSided.py:62 -#: flatcamTools/ToolDblSided.py:90 flatcamTools/ToolDblSided.py:120 +#: flatcamGUI/PreferencesUI.py:6851 flatcamTools/ToolDblSided.py:68 +#: flatcamTools/ToolDblSided.py:96 flatcamTools/ToolDblSided.py:126 msgid "Mirror" msgstr "Oglindește" -#: flatcamGUI/PreferencesUI.py:6368 flatcamTools/ToolTransform.py:285 +#: flatcamGUI/PreferencesUI.py:6855 flatcamTools/ToolTransform.py:284 msgid "Mirror Reference" msgstr "Referinţă Oglindire" -#: flatcamGUI/PreferencesUI.py:6370 flatcamTools/ToolTransform.py:287 +#: flatcamGUI/PreferencesUI.py:6857 flatcamTools/ToolTransform.py:286 msgid "" "Flip the selected object(s)\n" "around the point in Point Entry Field.\n" @@ -11782,11 +12213,11 @@ msgstr "" "in forma (x, y).\n" "La final apasă butonul de oglindire pe axa dorită" -#: flatcamGUI/PreferencesUI.py:6381 +#: flatcamGUI/PreferencesUI.py:6868 msgid "Mirror Reference point" msgstr "Punct referinţă Oglindire" -#: flatcamGUI/PreferencesUI.py:6383 +#: flatcamGUI/PreferencesUI.py:6870 msgid "" "Coordinates in format (x, y) used as reference for mirroring.\n" "The 'x' in (x, y) will be used when using Flip on X and\n" @@ -11797,12 +12228,12 @@ msgstr "" "X din (x,y) se va folosi când se face oglindirea pe axa X\n" "Y din (x,y) se va folosi când se face oglindirea pe axa Y si" -#: flatcamGUI/PreferencesUI.py:6396 flatcamTools/ToolDistance.py:355 -#: flatcamTools/ToolDistanceMin.py:284 flatcamTools/ToolTransform.py:332 +#: flatcamGUI/PreferencesUI.py:6883 flatcamTools/ToolDistance.py:496 +#: flatcamTools/ToolDistanceMin.py:287 flatcamTools/ToolTransform.py:333 msgid "Distance" msgstr "Distanță" -#: flatcamGUI/PreferencesUI.py:6398 flatcamTools/ToolTransform.py:334 +#: flatcamGUI/PreferencesUI.py:6885 flatcamTools/ToolTransform.py:335 msgid "" "A positive value will create the effect of dilation,\n" "while a negative value will create the effect of erosion.\n" @@ -11814,12 +12245,26 @@ msgstr "" "Fiecare element de geometrie al obiectului va fi mărit\n" "sau scăzut proportional cu „distanța”." -#: flatcamGUI/PreferencesUI.py:6414 flatcamGUI/PreferencesUI.py:7057 -#: flatcamTools/ToolQRCode.py:197 flatcamTools/ToolTransform.py:361 +#: flatcamGUI/PreferencesUI.py:6902 flatcamTools/ToolTransform.py:360 +msgid "" +"A positive value will create the effect of dilation,\n" +"while a negative value will create the effect of erosion.\n" +"Each geometry element of the object will be increased\n" +"or decreased to fit the 'Value'. Value is a percentage\n" +"of the initial dimension." +msgstr "" +"O valoare pozitivă va crea efectul dilatării,\n" +"în timp ce o valoare negativă va crea efectul eroziunii.\n" +"Fiecare element de geometrie al obiectului va fi mărit\n" +"sau scăzut proportional cu „distanța”. Valoarea este\n" +"un procent din dimensiunea initială." + +#: flatcamGUI/PreferencesUI.py:6919 flatcamGUI/PreferencesUI.py:7563 +#: flatcamTools/ToolQRCode.py:197 flatcamTools/ToolTransform.py:384 msgid "Rounded" msgstr "Rotunjit" -#: flatcamGUI/PreferencesUI.py:6416 flatcamTools/ToolTransform.py:363 +#: flatcamGUI/PreferencesUI.py:6921 flatcamTools/ToolTransform.py:386 msgid "" "If checked then the buffer will surround the buffered shape,\n" "every corner will be rounded.\n" @@ -11831,11 +12276,11 @@ msgstr "" "Dacă nu este bifat, bufferul va urma geometria exactă\n" "de forma tamponată." -#: flatcamGUI/PreferencesUI.py:6434 +#: flatcamGUI/PreferencesUI.py:6938 msgid "SolderPaste Tool Options" msgstr "Opțiuni Unealta Pasta Fludor" -#: flatcamGUI/PreferencesUI.py:6440 +#: flatcamGUI/PreferencesUI.py:6944 msgid "" "A tool to create GCode for dispensing\n" "solder paste onto a PCB." @@ -11843,49 +12288,45 @@ msgstr "" "O unealtă care crează cod G-Code pentru dispensarea de pastă de fludor\n" "pe padurile unui PCB." -#: flatcamGUI/PreferencesUI.py:6451 -msgid "Diameters of nozzle tools, separated by ','" -msgstr "Diametrele uneltelor (nozzle), separate prin virgula." - -#: flatcamGUI/PreferencesUI.py:6459 +#: flatcamGUI/PreferencesUI.py:6965 msgid "New Nozzle Dia" msgstr "Dia nou" -#: flatcamGUI/PreferencesUI.py:6461 flatcamTools/ToolSolderPaste.py:106 +#: flatcamGUI/PreferencesUI.py:6967 flatcamTools/ToolSolderPaste.py:108 msgid "Diameter for the new Nozzle tool to add in the Tool Table" msgstr "" "Valoarea pentru diametrul unei noi unelte (nozzle) pentru adaugare in Tabela " "de Unelte" -#: flatcamGUI/PreferencesUI.py:6477 flatcamTools/ToolSolderPaste.py:182 +#: flatcamGUI/PreferencesUI.py:6983 flatcamTools/ToolSolderPaste.py:184 msgid "Z Dispense Start" msgstr "Z start dispensare" -#: flatcamGUI/PreferencesUI.py:6479 flatcamTools/ToolSolderPaste.py:184 +#: flatcamGUI/PreferencesUI.py:6985 flatcamTools/ToolSolderPaste.py:186 msgid "The height (Z) when solder paste dispensing starts." msgstr "Înălţimea (Z) când incepe dispensarea de pastă de fludor." -#: flatcamGUI/PreferencesUI.py:6490 flatcamTools/ToolSolderPaste.py:194 +#: flatcamGUI/PreferencesUI.py:6996 flatcamTools/ToolSolderPaste.py:196 msgid "Z Dispense" msgstr "Z dispensare" -#: flatcamGUI/PreferencesUI.py:6492 flatcamTools/ToolSolderPaste.py:196 +#: flatcamGUI/PreferencesUI.py:6998 flatcamTools/ToolSolderPaste.py:198 msgid "The height (Z) when doing solder paste dispensing." msgstr "Înălţimea (Z) in timp ce se face dispensarea de pastă de fludor." -#: flatcamGUI/PreferencesUI.py:6503 flatcamTools/ToolSolderPaste.py:206 +#: flatcamGUI/PreferencesUI.py:7009 flatcamTools/ToolSolderPaste.py:208 msgid "Z Dispense Stop" msgstr "Z stop dispensare" -#: flatcamGUI/PreferencesUI.py:6505 flatcamTools/ToolSolderPaste.py:208 +#: flatcamGUI/PreferencesUI.py:7011 flatcamTools/ToolSolderPaste.py:210 msgid "The height (Z) when solder paste dispensing stops." msgstr "Înălţimea (Z) când se opreste dispensarea de pastă de fludor." -#: flatcamGUI/PreferencesUI.py:6516 flatcamTools/ToolSolderPaste.py:218 +#: flatcamGUI/PreferencesUI.py:7022 flatcamTools/ToolSolderPaste.py:220 msgid "Z Travel" msgstr "Z deplasare" -#: flatcamGUI/PreferencesUI.py:6518 flatcamTools/ToolSolderPaste.py:220 +#: flatcamGUI/PreferencesUI.py:7024 flatcamTools/ToolSolderPaste.py:222 msgid "" "The height (Z) for travel between pads\n" "(without dispensing solder paste)." @@ -11893,15 +12334,15 @@ msgstr "" "Înălţimea (Z) când se face deplasare între pad-uri.\n" "(fără dispensare de pastă de fludor)." -#: flatcamGUI/PreferencesUI.py:6530 flatcamTools/ToolSolderPaste.py:231 +#: flatcamGUI/PreferencesUI.py:7036 flatcamTools/ToolSolderPaste.py:233 msgid "Z Toolchange" msgstr "Z schimb. unealtă" -#: flatcamGUI/PreferencesUI.py:6532 flatcamTools/ToolSolderPaste.py:233 +#: flatcamGUI/PreferencesUI.py:7038 flatcamTools/ToolSolderPaste.py:235 msgid "The height (Z) for tool (nozzle) change." msgstr "Înălţimea (Z) când se schimbă unealta (nozzle-ul)." -#: flatcamGUI/PreferencesUI.py:6541 flatcamTools/ToolSolderPaste.py:241 +#: flatcamGUI/PreferencesUI.py:7047 flatcamTools/ToolSolderPaste.py:243 msgid "" "The X,Y location for tool (nozzle) change.\n" "The format is (x, y) where x and y are real numbers." @@ -11909,22 +12350,22 @@ msgstr "" "Coordonatele X, Y pentru schimbarea uneltei (nozzle).\n" "Formatul este (x,y) unde x și y sunt numere Reale." -#: flatcamGUI/PreferencesUI.py:6555 flatcamTools/ToolSolderPaste.py:254 +#: flatcamGUI/PreferencesUI.py:7061 flatcamTools/ToolSolderPaste.py:256 msgid "Feedrate (speed) while moving on the X-Y plane." msgstr "Viteza de deplasare a uneltei când se deplasează in planul X-Y." -#: flatcamGUI/PreferencesUI.py:6568 flatcamTools/ToolSolderPaste.py:266 +#: flatcamGUI/PreferencesUI.py:7074 flatcamTools/ToolSolderPaste.py:268 msgid "" "Feedrate (speed) while moving vertically\n" "(on Z plane)." msgstr "" "Viteza de deplasare a uneltei când se misca in plan vertical (planul Z)." -#: flatcamGUI/PreferencesUI.py:6580 flatcamTools/ToolSolderPaste.py:277 +#: flatcamGUI/PreferencesUI.py:7086 flatcamTools/ToolSolderPaste.py:279 msgid "Feedrate Z Dispense" msgstr "Feedrate Z dispensare" -#: flatcamGUI/PreferencesUI.py:6582 +#: flatcamGUI/PreferencesUI.py:7088 msgid "" "Feedrate (speed) while moving up vertically\n" "to Dispense position (on Z plane)." @@ -11932,11 +12373,11 @@ msgstr "" "Viteza de deplasare la mișcarea pe verticala spre\n" "poziţia de dispensare (in planul Z)." -#: flatcamGUI/PreferencesUI.py:6593 flatcamTools/ToolSolderPaste.py:289 +#: flatcamGUI/PreferencesUI.py:7099 flatcamTools/ToolSolderPaste.py:291 msgid "Spindle Speed FWD" msgstr "Viteza motor inainte" -#: flatcamGUI/PreferencesUI.py:6595 flatcamTools/ToolSolderPaste.py:291 +#: flatcamGUI/PreferencesUI.py:7101 flatcamTools/ToolSolderPaste.py:293 msgid "" "The dispenser speed while pushing solder paste\n" "through the dispenser nozzle." @@ -11944,19 +12385,19 @@ msgstr "" "Viteza motorului de dispensare in timp ce impinge pastă de fludor\n" "prin orificiul uneltei de dispensare." -#: flatcamGUI/PreferencesUI.py:6607 flatcamTools/ToolSolderPaste.py:302 +#: flatcamGUI/PreferencesUI.py:7113 flatcamTools/ToolSolderPaste.py:304 msgid "Dwell FWD" msgstr "Pauza FWD" -#: flatcamGUI/PreferencesUI.py:6609 flatcamTools/ToolSolderPaste.py:304 +#: flatcamGUI/PreferencesUI.py:7115 flatcamTools/ToolSolderPaste.py:306 msgid "Pause after solder dispensing." msgstr "Pauza dupa dispensarea de pastă de fludor." -#: flatcamGUI/PreferencesUI.py:6619 flatcamTools/ToolSolderPaste.py:313 +#: flatcamGUI/PreferencesUI.py:7125 flatcamTools/ToolSolderPaste.py:315 msgid "Spindle Speed REV" msgstr "Viteza motor inapoi" -#: flatcamGUI/PreferencesUI.py:6621 flatcamTools/ToolSolderPaste.py:315 +#: flatcamGUI/PreferencesUI.py:7127 flatcamTools/ToolSolderPaste.py:317 msgid "" "The dispenser speed while retracting solder paste\n" "through the dispenser nozzle." @@ -11964,11 +12405,11 @@ msgstr "" "Viteza motorului de dispensare in timp ce retrage pasta de fludor\n" "prin orificiul uneltei de dispensare." -#: flatcamGUI/PreferencesUI.py:6633 flatcamTools/ToolSolderPaste.py:326 +#: flatcamGUI/PreferencesUI.py:7139 flatcamTools/ToolSolderPaste.py:328 msgid "Dwell REV" msgstr "Pauza REV" -#: flatcamGUI/PreferencesUI.py:6635 flatcamTools/ToolSolderPaste.py:328 +#: flatcamGUI/PreferencesUI.py:7141 flatcamTools/ToolSolderPaste.py:330 msgid "" "Pause after solder paste dispenser retracted,\n" "to allow pressure equilibrium." @@ -11976,15 +12417,15 @@ msgstr "" "Pauza dupa ce pasta de fludor a fost retrasă,\n" "necesară pt a ajunge la un echilibru al presiunilor." -#: flatcamGUI/PreferencesUI.py:6644 flatcamTools/ToolSolderPaste.py:336 +#: flatcamGUI/PreferencesUI.py:7150 flatcamTools/ToolSolderPaste.py:338 msgid "Files that control the GCode generation." msgstr "Fişiere care controlează generarea codului G-Code." -#: flatcamGUI/PreferencesUI.py:6659 +#: flatcamGUI/PreferencesUI.py:7165 msgid "Substractor Tool Options" msgstr "Opțiuni Unealta Substracţie" -#: flatcamGUI/PreferencesUI.py:6665 +#: flatcamGUI/PreferencesUI.py:7171 msgid "" "A tool to substract one Gerber or Geometry object\n" "from another of the same type." @@ -11992,22 +12433,22 @@ msgstr "" "O unealtă pentru scăderea unui obiect Gerber sau Geometry\n" "din altul de același tip." -#: flatcamGUI/PreferencesUI.py:6670 flatcamTools/ToolSub.py:149 +#: flatcamGUI/PreferencesUI.py:7176 flatcamTools/ToolSub.py:155 msgid "Close paths" msgstr "Închide căile" -#: flatcamGUI/PreferencesUI.py:6671 +#: flatcamGUI/PreferencesUI.py:7177 msgid "" "Checking this will close the paths cut by the Geometry substractor object." msgstr "" "Verificând aceasta, se vor închide căile tăiate de obiectul tăietor de tip " "Geometrie." -#: flatcamGUI/PreferencesUI.py:6682 +#: flatcamGUI/PreferencesUI.py:7188 msgid "Check Rules Tool Options" msgstr "Opțiuni Unealta Verificare Reguli" -#: flatcamGUI/PreferencesUI.py:6687 +#: flatcamGUI/PreferencesUI.py:7193 msgid "" "A tool to check if Gerber files are within a set\n" "of Manufacturing Rules." @@ -12015,38 +12456,38 @@ msgstr "" "Un instrument pentru a verifica dacă fișierele Gerber se află într-un set\n" "de Norme de fabricație." -#: flatcamGUI/PreferencesUI.py:6697 flatcamTools/ToolRulesCheck.py:256 -#: flatcamTools/ToolRulesCheck.py:920 +#: flatcamGUI/PreferencesUI.py:7203 flatcamTools/ToolRulesCheck.py:265 +#: flatcamTools/ToolRulesCheck.py:929 msgid "Trace Size" msgstr "Dim. traseu" -#: flatcamGUI/PreferencesUI.py:6699 flatcamTools/ToolRulesCheck.py:258 +#: flatcamGUI/PreferencesUI.py:7205 flatcamTools/ToolRulesCheck.py:267 msgid "This checks if the minimum size for traces is met." msgstr "Aceasta verifică dacă dimensiunea minimă a traseelor este respectată." -#: flatcamGUI/PreferencesUI.py:6709 flatcamGUI/PreferencesUI.py:6729 -#: flatcamGUI/PreferencesUI.py:6749 flatcamGUI/PreferencesUI.py:6769 -#: flatcamGUI/PreferencesUI.py:6789 flatcamGUI/PreferencesUI.py:6809 -#: flatcamGUI/PreferencesUI.py:6829 flatcamGUI/PreferencesUI.py:6849 -#: flatcamGUI/PreferencesUI.py:6871 flatcamGUI/PreferencesUI.py:6891 -#: flatcamTools/ToolRulesCheck.py:268 flatcamTools/ToolRulesCheck.py:290 -#: flatcamTools/ToolRulesCheck.py:313 flatcamTools/ToolRulesCheck.py:336 -#: flatcamTools/ToolRulesCheck.py:359 flatcamTools/ToolRulesCheck.py:382 -#: flatcamTools/ToolRulesCheck.py:405 flatcamTools/ToolRulesCheck.py:428 -#: flatcamTools/ToolRulesCheck.py:453 flatcamTools/ToolRulesCheck.py:476 +#: flatcamGUI/PreferencesUI.py:7215 flatcamGUI/PreferencesUI.py:7235 +#: flatcamGUI/PreferencesUI.py:7255 flatcamGUI/PreferencesUI.py:7275 +#: flatcamGUI/PreferencesUI.py:7295 flatcamGUI/PreferencesUI.py:7315 +#: flatcamGUI/PreferencesUI.py:7335 flatcamGUI/PreferencesUI.py:7355 +#: flatcamGUI/PreferencesUI.py:7377 flatcamGUI/PreferencesUI.py:7397 +#: flatcamTools/ToolRulesCheck.py:277 flatcamTools/ToolRulesCheck.py:299 +#: flatcamTools/ToolRulesCheck.py:322 flatcamTools/ToolRulesCheck.py:345 +#: flatcamTools/ToolRulesCheck.py:368 flatcamTools/ToolRulesCheck.py:391 +#: flatcamTools/ToolRulesCheck.py:414 flatcamTools/ToolRulesCheck.py:437 +#: flatcamTools/ToolRulesCheck.py:462 flatcamTools/ToolRulesCheck.py:485 msgid "Min value" msgstr "Val. min" -#: flatcamGUI/PreferencesUI.py:6711 flatcamTools/ToolRulesCheck.py:270 +#: flatcamGUI/PreferencesUI.py:7217 flatcamTools/ToolRulesCheck.py:279 msgid "Minimum acceptable trace size." msgstr "Dimensiunea minimă acceptabilă a traseelor." -#: flatcamGUI/PreferencesUI.py:6716 flatcamTools/ToolRulesCheck.py:277 -#: flatcamTools/ToolRulesCheck.py:1148 flatcamTools/ToolRulesCheck.py:1178 +#: flatcamGUI/PreferencesUI.py:7222 flatcamTools/ToolRulesCheck.py:286 +#: flatcamTools/ToolRulesCheck.py:1157 flatcamTools/ToolRulesCheck.py:1187 msgid "Copper to Copper clearance" msgstr "Distanta de la cupru până la cupru" -#: flatcamGUI/PreferencesUI.py:6718 flatcamTools/ToolRulesCheck.py:279 +#: flatcamGUI/PreferencesUI.py:7224 flatcamTools/ToolRulesCheck.py:288 msgid "" "This checks if the minimum clearance between copper\n" "features is met." @@ -12054,23 +12495,23 @@ msgstr "" "Aceasta verifică dacă distanța minimă dintre traseele cupru\n" "este îndeplinita." -#: flatcamGUI/PreferencesUI.py:6731 flatcamGUI/PreferencesUI.py:6751 -#: flatcamGUI/PreferencesUI.py:6771 flatcamGUI/PreferencesUI.py:6791 -#: flatcamGUI/PreferencesUI.py:6811 flatcamGUI/PreferencesUI.py:6831 -#: flatcamGUI/PreferencesUI.py:6893 flatcamTools/ToolRulesCheck.py:292 -#: flatcamTools/ToolRulesCheck.py:315 flatcamTools/ToolRulesCheck.py:338 -#: flatcamTools/ToolRulesCheck.py:361 flatcamTools/ToolRulesCheck.py:384 -#: flatcamTools/ToolRulesCheck.py:407 flatcamTools/ToolRulesCheck.py:455 +#: flatcamGUI/PreferencesUI.py:7237 flatcamGUI/PreferencesUI.py:7257 +#: flatcamGUI/PreferencesUI.py:7277 flatcamGUI/PreferencesUI.py:7297 +#: flatcamGUI/PreferencesUI.py:7317 flatcamGUI/PreferencesUI.py:7337 +#: flatcamGUI/PreferencesUI.py:7399 flatcamTools/ToolRulesCheck.py:301 +#: flatcamTools/ToolRulesCheck.py:324 flatcamTools/ToolRulesCheck.py:347 +#: flatcamTools/ToolRulesCheck.py:370 flatcamTools/ToolRulesCheck.py:393 +#: flatcamTools/ToolRulesCheck.py:416 flatcamTools/ToolRulesCheck.py:464 msgid "Minimum acceptable clearance value." msgstr "Valoarea minimă acceptabilă a distantei." -#: flatcamGUI/PreferencesUI.py:6736 flatcamTools/ToolRulesCheck.py:300 -#: flatcamTools/ToolRulesCheck.py:1208 flatcamTools/ToolRulesCheck.py:1214 -#: flatcamTools/ToolRulesCheck.py:1227 flatcamTools/ToolRulesCheck.py:1234 +#: flatcamGUI/PreferencesUI.py:7242 flatcamTools/ToolRulesCheck.py:309 +#: flatcamTools/ToolRulesCheck.py:1217 flatcamTools/ToolRulesCheck.py:1223 +#: flatcamTools/ToolRulesCheck.py:1236 flatcamTools/ToolRulesCheck.py:1243 msgid "Copper to Outline clearance" msgstr "Distanta de la Cupru până la contur" -#: flatcamGUI/PreferencesUI.py:6738 flatcamTools/ToolRulesCheck.py:302 +#: flatcamGUI/PreferencesUI.py:7244 flatcamTools/ToolRulesCheck.py:311 msgid "" "This checks if the minimum clearance between copper\n" "features and the outline is met." @@ -12078,11 +12519,11 @@ msgstr "" "Aceasta verifică dacă distanța minimă dintre\n" "traseele de cupru și conturul este îndeplinit." -#: flatcamGUI/PreferencesUI.py:6756 flatcamTools/ToolRulesCheck.py:323 +#: flatcamGUI/PreferencesUI.py:7262 flatcamTools/ToolRulesCheck.py:332 msgid "Silk to Silk Clearance" msgstr "Distanta Silk până la Silk Clearance" -#: flatcamGUI/PreferencesUI.py:6758 flatcamTools/ToolRulesCheck.py:325 +#: flatcamGUI/PreferencesUI.py:7264 flatcamTools/ToolRulesCheck.py:334 msgid "" "This checks if the minimum clearance between silkscreen\n" "features and silkscreen features is met." @@ -12090,13 +12531,13 @@ msgstr "" "Acest lucru verifică dacă distanța minimă între silk (anotari)\n" "sunt îndeplinite." -#: flatcamGUI/PreferencesUI.py:6776 flatcamTools/ToolRulesCheck.py:346 -#: flatcamTools/ToolRulesCheck.py:1317 flatcamTools/ToolRulesCheck.py:1323 -#: flatcamTools/ToolRulesCheck.py:1341 +#: flatcamGUI/PreferencesUI.py:7282 flatcamTools/ToolRulesCheck.py:355 +#: flatcamTools/ToolRulesCheck.py:1326 flatcamTools/ToolRulesCheck.py:1332 +#: flatcamTools/ToolRulesCheck.py:1350 msgid "Silk to Solder Mask Clearance" msgstr "Distanta intre Silk (anotari) si Solder mask (masca fludor)" -#: flatcamGUI/PreferencesUI.py:6778 flatcamTools/ToolRulesCheck.py:348 +#: flatcamGUI/PreferencesUI.py:7284 flatcamTools/ToolRulesCheck.py:357 msgid "" "This checks if the minimum clearance between silkscreen\n" "features and soldermask features is met." @@ -12104,13 +12545,13 @@ msgstr "" "Acest lucru verifică dacă distanța minimă între Silk (anotari)\n" "și Solder Mask (masca de fludor) este îndeplinită." -#: flatcamGUI/PreferencesUI.py:6796 flatcamTools/ToolRulesCheck.py:369 -#: flatcamTools/ToolRulesCheck.py:1371 flatcamTools/ToolRulesCheck.py:1377 -#: flatcamTools/ToolRulesCheck.py:1391 flatcamTools/ToolRulesCheck.py:1398 +#: flatcamGUI/PreferencesUI.py:7302 flatcamTools/ToolRulesCheck.py:378 +#: flatcamTools/ToolRulesCheck.py:1380 flatcamTools/ToolRulesCheck.py:1386 +#: flatcamTools/ToolRulesCheck.py:1400 flatcamTools/ToolRulesCheck.py:1407 msgid "Silk to Outline Clearance" msgstr "Distanta Silk (anotari) si Contur" -#: flatcamGUI/PreferencesUI.py:6798 flatcamTools/ToolRulesCheck.py:371 +#: flatcamGUI/PreferencesUI.py:7304 flatcamTools/ToolRulesCheck.py:380 msgid "" "This checks if the minimum clearance between silk\n" "features and the outline is met." @@ -12118,14 +12559,14 @@ msgstr "" "Acest lucru verifică dacă distanța minimă dintre Silk (anotari)\n" "și Contur este îndeplinită." -#: flatcamGUI/PreferencesUI.py:6816 flatcamTools/ToolRulesCheck.py:392 -#: flatcamTools/ToolRulesCheck.py:1409 flatcamTools/ToolRulesCheck.py:1436 +#: flatcamGUI/PreferencesUI.py:7322 flatcamTools/ToolRulesCheck.py:401 +#: flatcamTools/ToolRulesCheck.py:1418 flatcamTools/ToolRulesCheck.py:1445 msgid "Minimum Solder Mask Sliver" msgstr "" "Dim. minima a separatorului din Solder Mask\n" "(masca de fludor)" -#: flatcamGUI/PreferencesUI.py:6818 flatcamTools/ToolRulesCheck.py:394 +#: flatcamGUI/PreferencesUI.py:7324 flatcamTools/ToolRulesCheck.py:403 msgid "" "This checks if the minimum clearance between soldermask\n" "features and soldermask features is met." @@ -12133,13 +12574,13 @@ msgstr "" "Acest lucru verifică dacă distanta minimă între\n" "elementele soldermask (masca de fludor) este îndeplinită." -#: flatcamGUI/PreferencesUI.py:6836 flatcamTools/ToolRulesCheck.py:415 -#: flatcamTools/ToolRulesCheck.py:1474 flatcamTools/ToolRulesCheck.py:1480 -#: flatcamTools/ToolRulesCheck.py:1496 flatcamTools/ToolRulesCheck.py:1503 +#: flatcamGUI/PreferencesUI.py:7342 flatcamTools/ToolRulesCheck.py:424 +#: flatcamTools/ToolRulesCheck.py:1483 flatcamTools/ToolRulesCheck.py:1489 +#: flatcamTools/ToolRulesCheck.py:1505 flatcamTools/ToolRulesCheck.py:1512 msgid "Minimum Annular Ring" msgstr "Inel anular minim" -#: flatcamGUI/PreferencesUI.py:6838 flatcamTools/ToolRulesCheck.py:417 +#: flatcamGUI/PreferencesUI.py:7344 flatcamTools/ToolRulesCheck.py:426 msgid "" "This checks if the minimum copper ring left by drilling\n" "a hole into a pad is met." @@ -12147,16 +12588,16 @@ msgstr "" "Acest lucru verifică dacă inelul de cupru minim rămas prin găurire\n" "unde se întâlnește o gaură cu pad-ul depășește valoarea minimă." -#: flatcamGUI/PreferencesUI.py:6851 flatcamTools/ToolRulesCheck.py:430 +#: flatcamGUI/PreferencesUI.py:7357 flatcamTools/ToolRulesCheck.py:439 msgid "Minimum acceptable ring value." msgstr "Valoarea minimă acceptabilă a inelului." -#: flatcamGUI/PreferencesUI.py:6858 flatcamTools/ToolRulesCheck.py:440 -#: flatcamTools/ToolRulesCheck.py:864 +#: flatcamGUI/PreferencesUI.py:7364 flatcamTools/ToolRulesCheck.py:449 +#: flatcamTools/ToolRulesCheck.py:873 msgid "Hole to Hole Clearance" msgstr "Distanta de la Gaură la Gaură" -#: flatcamGUI/PreferencesUI.py:6860 flatcamTools/ToolRulesCheck.py:442 +#: flatcamGUI/PreferencesUI.py:7366 flatcamTools/ToolRulesCheck.py:451 msgid "" "This checks if the minimum clearance between a drill hole\n" "and another drill hole is met." @@ -12164,16 +12605,16 @@ msgstr "" "Acest lucru verifică dacă distanța minimă dintre o gaură\n" "și o altă gaură este îndeplinită." -#: flatcamGUI/PreferencesUI.py:6873 flatcamTools/ToolRulesCheck.py:478 +#: flatcamGUI/PreferencesUI.py:7379 flatcamTools/ToolRulesCheck.py:487 msgid "Minimum acceptable drill size." msgstr "Dimensiunea minimă acceptabilă a gaurii." -#: flatcamGUI/PreferencesUI.py:6878 flatcamTools/ToolRulesCheck.py:463 -#: flatcamTools/ToolRulesCheck.py:838 +#: flatcamGUI/PreferencesUI.py:7384 flatcamTools/ToolRulesCheck.py:472 +#: flatcamTools/ToolRulesCheck.py:847 msgid "Hole Size" msgstr "Dimens. gaura" -#: flatcamGUI/PreferencesUI.py:6880 flatcamTools/ToolRulesCheck.py:465 +#: flatcamGUI/PreferencesUI.py:7386 flatcamTools/ToolRulesCheck.py:474 msgid "" "This checks if the drill holes\n" "sizes are above the threshold." @@ -12181,11 +12622,11 @@ msgstr "" "Acest lucru verifică dacă\n" "dimensiunile găurilor sunt peste prag." -#: flatcamGUI/PreferencesUI.py:6905 +#: flatcamGUI/PreferencesUI.py:7411 msgid "Optimal Tool Options" msgstr "Opțiuni Unealta Optim" -#: flatcamGUI/PreferencesUI.py:6911 +#: flatcamGUI/PreferencesUI.py:7417 msgid "" "A tool to find the minimum distance between\n" "every two Gerber geometric elements" @@ -12193,20 +12634,20 @@ msgstr "" "Un instrument pentru a găsi distanța minimă între\n" "la fiecare două elemente geometrice Gerber" -#: flatcamGUI/PreferencesUI.py:6926 flatcamTools/ToolOptimal.py:78 +#: flatcamGUI/PreferencesUI.py:7432 flatcamTools/ToolOptimal.py:79 msgid "Precision" msgstr "Precizie" -#: flatcamGUI/PreferencesUI.py:6928 +#: flatcamGUI/PreferencesUI.py:7434 msgid "Number of decimals for the distances and coordinates in this tool." msgstr "" "Numărul de zecimale pentru distanțele și coordonatele din acest instrument." -#: flatcamGUI/PreferencesUI.py:6942 +#: flatcamGUI/PreferencesUI.py:7448 msgid "QRCode Tool Options" msgstr "Opțiuni Unealta QRCode" -#: flatcamGUI/PreferencesUI.py:6948 +#: flatcamGUI/PreferencesUI.py:7454 msgid "" "A tool to create a QRCode that can be inserted\n" "into a selected Gerber file, or it can be exported as a file." @@ -12214,11 +12655,11 @@ msgstr "" "O unealta pentru a crea un cod QRC care poate fi inserat\n" "într-un fișier Gerber selectat sau care poate fi exportat ca fișier." -#: flatcamGUI/PreferencesUI.py:6960 flatcamTools/ToolQRCode.py:99 +#: flatcamGUI/PreferencesUI.py:7466 flatcamTools/ToolQRCode.py:100 msgid "Version" msgstr "Versiune" -#: flatcamGUI/PreferencesUI.py:6962 flatcamTools/ToolQRCode.py:101 +#: flatcamGUI/PreferencesUI.py:7468 flatcamTools/ToolQRCode.py:102 msgid "" "QRCode version can have values from 1 (21x21 boxes)\n" "to 40 (177x177 boxes)." @@ -12226,12 +12667,12 @@ msgstr "" "Versiunea QRCode poate avea valori de la 1 (21x21 elemente)\n" "la 40 (177x177 elemente)." -#: flatcamGUI/PreferencesUI.py:6973 flatcamTools/ToolQRCode.py:112 +#: flatcamGUI/PreferencesUI.py:7479 flatcamTools/ToolQRCode.py:113 msgid "Error correction" msgstr "Corectarea erorii" -#: flatcamGUI/PreferencesUI.py:6975 flatcamGUI/PreferencesUI.py:6986 -#: flatcamTools/ToolQRCode.py:114 flatcamTools/ToolQRCode.py:125 +#: flatcamGUI/PreferencesUI.py:7481 flatcamGUI/PreferencesUI.py:7492 +#: flatcamTools/ToolQRCode.py:115 flatcamTools/ToolQRCode.py:126 #, python-format msgid "" "Parameter that controls the error correction used for the QR Code.\n" @@ -12246,11 +12687,11 @@ msgstr "" "Q = erorile maxime de 25%% pot fi corectate\n" "H = maxim 30%% erorile pot fi corectate." -#: flatcamGUI/PreferencesUI.py:6996 flatcamTools/ToolQRCode.py:135 +#: flatcamGUI/PreferencesUI.py:7502 flatcamTools/ToolQRCode.py:136 msgid "Box Size" msgstr "Dim. Element" -#: flatcamGUI/PreferencesUI.py:6998 flatcamTools/ToolQRCode.py:137 +#: flatcamGUI/PreferencesUI.py:7504 flatcamTools/ToolQRCode.py:138 msgid "" "Box size control the overall size of the QRcode\n" "by adjusting the size of each box in the code." @@ -12258,11 +12699,11 @@ msgstr "" "Dimensiunea Element controlează dimensiunea generală a codului QR\n" "prin ajustarea dimensiunii fiecărui element din cod." -#: flatcamGUI/PreferencesUI.py:7009 flatcamTools/ToolQRCode.py:148 +#: flatcamGUI/PreferencesUI.py:7515 flatcamTools/ToolQRCode.py:149 msgid "Border Size" msgstr "Dim Bordură" -#: flatcamGUI/PreferencesUI.py:7011 flatcamTools/ToolQRCode.py:150 +#: flatcamGUI/PreferencesUI.py:7517 flatcamTools/ToolQRCode.py:151 msgid "" "Size of the QRCode border. How many boxes thick is the border.\n" "Default value is 4. The width of the clearance around the QRCode." @@ -12270,23 +12711,23 @@ msgstr "" "Dimensiunea chenarului QRCode. Câte elemente va contine bordura.\n" "Valoarea implicită este 4. Lățimea spatiului liber în jurul codului QRC." -#: flatcamGUI/PreferencesUI.py:7022 flatcamTools/ToolQRCode.py:162 +#: flatcamGUI/PreferencesUI.py:7528 flatcamTools/ToolQRCode.py:162 msgid "QRCode Data" msgstr "Date QRCode" -#: flatcamGUI/PreferencesUI.py:7024 flatcamTools/ToolQRCode.py:164 +#: flatcamGUI/PreferencesUI.py:7530 flatcamTools/ToolQRCode.py:164 msgid "QRCode Data. Alphanumeric text to be encoded in the QRCode." msgstr "Date QRCode. Text alfanumeric care va fi codat în codul QRC." -#: flatcamGUI/PreferencesUI.py:7028 flatcamTools/ToolQRCode.py:168 +#: flatcamGUI/PreferencesUI.py:7534 flatcamTools/ToolQRCode.py:168 msgid "Add here the text to be included in the QRCode..." msgstr "Adăugați aici textul care va fi inclus în codul QR ..." -#: flatcamGUI/PreferencesUI.py:7034 flatcamTools/ToolQRCode.py:174 +#: flatcamGUI/PreferencesUI.py:7540 flatcamTools/ToolQRCode.py:174 msgid "Polarity" msgstr "Polaritate" -#: flatcamGUI/PreferencesUI.py:7036 flatcamTools/ToolQRCode.py:176 +#: flatcamGUI/PreferencesUI.py:7542 flatcamTools/ToolQRCode.py:176 msgid "" "Choose the polarity of the QRCode.\n" "It can be drawn in a negative way (squares are clear)\n" @@ -12296,17 +12737,17 @@ msgstr "" "Poate fi desenat într-un mod negativ (pătratele sunt clare)\n" "sau într-un mod pozitiv (pătratele sunt opace)." -#: flatcamGUI/PreferencesUI.py:7040 flatcamTools/ToolFilm.py:296 +#: flatcamGUI/PreferencesUI.py:7546 flatcamTools/ToolFilm.py:296 #: flatcamTools/ToolQRCode.py:180 msgid "Negative" msgstr "Negativ" -#: flatcamGUI/PreferencesUI.py:7041 flatcamTools/ToolFilm.py:295 +#: flatcamGUI/PreferencesUI.py:7547 flatcamTools/ToolFilm.py:295 #: flatcamTools/ToolQRCode.py:181 msgid "Positive" msgstr "Pozitiv" -#: flatcamGUI/PreferencesUI.py:7043 flatcamTools/ToolQRCode.py:183 +#: flatcamGUI/PreferencesUI.py:7549 flatcamTools/ToolQRCode.py:183 msgid "" "Choose the type of QRCode to be created.\n" "If added on a Silkscreen Gerber file the QRCode may\n" @@ -12318,7 +12759,7 @@ msgstr "" "să fie adăugat ca fiind pozitiv. Dacă este adăugat la un Gerber de cupru\n" "atunci codul QR poate fi adăugat ca negativ." -#: flatcamGUI/PreferencesUI.py:7054 flatcamGUI/PreferencesUI.py:7060 +#: flatcamGUI/PreferencesUI.py:7560 flatcamGUI/PreferencesUI.py:7566 #: flatcamTools/ToolQRCode.py:194 flatcamTools/ToolQRCode.py:200 msgid "" "The bounding box, meaning the empty space that surrounds\n" @@ -12327,27 +12768,27 @@ msgstr "" "Caseta de încadrare, adică spațiul gol care înconjoară\n" "geometria QRCode, poate avea o formă rotunjită sau pătrată." -#: flatcamGUI/PreferencesUI.py:7067 flatcamTools/ToolQRCode.py:228 +#: flatcamGUI/PreferencesUI.py:7573 flatcamTools/ToolQRCode.py:228 msgid "Fill Color" msgstr "Culoare Continut" -#: flatcamGUI/PreferencesUI.py:7069 flatcamTools/ToolQRCode.py:230 +#: flatcamGUI/PreferencesUI.py:7575 flatcamTools/ToolQRCode.py:230 msgid "Set the QRCode fill color (squares color)." msgstr "Setați culoarea QRCode de umplere (culoarea elementelor)." -#: flatcamGUI/PreferencesUI.py:7088 flatcamTools/ToolQRCode.py:252 +#: flatcamGUI/PreferencesUI.py:7594 flatcamTools/ToolQRCode.py:252 msgid "Back Color" msgstr "Culoare de fundal" -#: flatcamGUI/PreferencesUI.py:7090 flatcamTools/ToolQRCode.py:254 +#: flatcamGUI/PreferencesUI.py:7596 flatcamTools/ToolQRCode.py:254 msgid "Set the QRCode background color." msgstr "Setați culoarea de fundal QRCode." -#: flatcamGUI/PreferencesUI.py:7130 +#: flatcamGUI/PreferencesUI.py:7636 msgid "Copper Thieving Tool Options" msgstr "Opțiunile Uneltei Copper Thieving" -#: flatcamGUI/PreferencesUI.py:7142 +#: flatcamGUI/PreferencesUI.py:7648 msgid "" "A tool to generate a Copper Thieving that can be added\n" "to a selected Gerber file." @@ -12355,16 +12796,16 @@ msgstr "" "Un instrument pentru a genera o Copper Thieving care poate fi adăugat\n" "la un fișier Gerber selectat." -#: flatcamGUI/PreferencesUI.py:7150 +#: flatcamGUI/PreferencesUI.py:7656 msgid "Number of steps (lines) used to interpolate circles." msgstr "Numărul de pași (linii) utilizate pentru interpolarea cercurilor." -#: flatcamGUI/PreferencesUI.py:7160 flatcamGUI/PreferencesUI.py:7364 -#: flatcamTools/ToolCopperThieving.py:96 flatcamTools/ToolCopperThieving.py:429 +#: flatcamGUI/PreferencesUI.py:7666 flatcamGUI/PreferencesUI.py:7870 +#: flatcamTools/ToolCopperThieving.py:97 flatcamTools/ToolCopperThieving.py:432 msgid "Clearance" msgstr "Degajare" -#: flatcamGUI/PreferencesUI.py:7162 +#: flatcamGUI/PreferencesUI.py:7668 msgid "" "This set the distance between the copper Thieving components\n" "(the polygon fill may be split in multiple polygons)\n" @@ -12374,22 +12815,11 @@ msgstr "" "(umplutura poligonului poate fi împărțită în mai multe poligoane)\n" "si traseele de cupru din fisierul Gerber." -#: flatcamGUI/PreferencesUI.py:7190 flatcamTools/ToolCopperThieving.py:126 -#: flatcamTools/ToolNonCopperClear.py:430 flatcamTools/ToolPaint.py:308 -msgid "Area Selection" -msgstr "Selecţie zonă" - -#: flatcamGUI/PreferencesUI.py:7191 flatcamTools/ToolCopperThieving.py:127 -#: flatcamTools/ToolNonCopperClear.py:431 flatcamTools/ToolPaint.py:310 -msgid "Reference Object" -msgstr "Obiect Ref" - -#: flatcamGUI/PreferencesUI.py:7193 flatcamTools/ToolCopperThieving.py:129 -#: flatcamTools/ToolNonCopperClear.py:433 +#: flatcamGUI/PreferencesUI.py:7699 flatcamTools/ToolCopperThieving.py:130 msgid "Reference:" msgstr "Referinţă:" -#: flatcamGUI/PreferencesUI.py:7195 +#: flatcamGUI/PreferencesUI.py:7701 msgid "" "- 'Itself' - the copper Thieving extent is based on the object extent.\n" "- 'Area Selection' - left mouse click to start selection of the area to be " @@ -12404,20 +12834,24 @@ msgstr "" "- „Obiect de referință” - va face Copper Thieving în zona specificată de un " "alt obiect." -#: flatcamGUI/PreferencesUI.py:7204 flatcamTools/ToolCopperThieving.py:170 +#: flatcamGUI/PreferencesUI.py:7710 flatcamGUI/PreferencesUI.py:8175 +#: flatcamGUI/PreferencesUI.py:8287 flatcamGUI/PreferencesUI.py:8387 +#: flatcamGUI/PreferencesUI.py:8501 flatcamTools/ToolCopperThieving.py:172 +#: flatcamTools/ToolExtractDrills.py:102 flatcamTools/ToolExtractDrills.py:240 +#: flatcamTools/ToolPunchGerber.py:113 flatcamTools/ToolPunchGerber.py:268 msgid "Rectangular" msgstr "Patrulater" -#: flatcamGUI/PreferencesUI.py:7205 flatcamTools/ToolCopperThieving.py:171 +#: flatcamGUI/PreferencesUI.py:7711 flatcamTools/ToolCopperThieving.py:173 msgid "Minimal" msgstr "Minimal" -#: flatcamGUI/PreferencesUI.py:7207 flatcamTools/ToolCopperThieving.py:173 +#: flatcamGUI/PreferencesUI.py:7713 flatcamTools/ToolCopperThieving.py:175 #: flatcamTools/ToolFilm.py:113 msgid "Box Type:" msgstr "Tip container:" -#: flatcamGUI/PreferencesUI.py:7209 flatcamTools/ToolCopperThieving.py:175 +#: flatcamGUI/PreferencesUI.py:7715 flatcamTools/ToolCopperThieving.py:177 msgid "" "- 'Rectangular' - the bounding box will be of rectangular shape.\n" "- 'Minimal' - the bounding box will be the convex hull shape." @@ -12425,23 +12859,23 @@ msgstr "" "- „Dreptunghiular” - caseta de delimitare va avea o formă dreptunghiulară.\n" "- „Minimal” - caseta de delimitare va fi forma arie convexă." -#: flatcamGUI/PreferencesUI.py:7223 flatcamTools/ToolCopperThieving.py:191 +#: flatcamGUI/PreferencesUI.py:7729 flatcamTools/ToolCopperThieving.py:193 msgid "Dots Grid" msgstr "Grilă de puncte" -#: flatcamGUI/PreferencesUI.py:7224 flatcamTools/ToolCopperThieving.py:192 +#: flatcamGUI/PreferencesUI.py:7730 flatcamTools/ToolCopperThieving.py:194 msgid "Squares Grid" msgstr "Grilă de pătrate" -#: flatcamGUI/PreferencesUI.py:7225 flatcamTools/ToolCopperThieving.py:193 +#: flatcamGUI/PreferencesUI.py:7731 flatcamTools/ToolCopperThieving.py:195 msgid "Lines Grid" msgstr "Grilă de linii" -#: flatcamGUI/PreferencesUI.py:7227 flatcamTools/ToolCopperThieving.py:195 +#: flatcamGUI/PreferencesUI.py:7733 flatcamTools/ToolCopperThieving.py:197 msgid "Fill Type:" msgstr "Tip de umplere:" -#: flatcamGUI/PreferencesUI.py:7229 flatcamTools/ToolCopperThieving.py:197 +#: flatcamGUI/PreferencesUI.py:7735 flatcamTools/ToolCopperThieving.py:199 msgid "" "- 'Solid' - copper thieving will be a solid polygon.\n" "- 'Dots Grid' - the empty area will be filled with a pattern of dots.\n" @@ -12453,54 +12887,54 @@ msgstr "" "- „Grilă de pătrate” - zona goală va fi umplută cu un model de pătrate.\n" "- „Grilă de linii” - zona goală va fi umplută cu un model de linii." -#: flatcamGUI/PreferencesUI.py:7237 flatcamTools/ToolCopperThieving.py:216 +#: flatcamGUI/PreferencesUI.py:7743 flatcamTools/ToolCopperThieving.py:218 msgid "Dots Grid Parameters" msgstr "Parametri grilă puncte" -#: flatcamGUI/PreferencesUI.py:7243 flatcamTools/ToolCopperThieving.py:222 +#: flatcamGUI/PreferencesUI.py:7749 flatcamTools/ToolCopperThieving.py:224 msgid "Dot diameter in Dots Grid." msgstr "Diametrul punctului în Grila de Puncte." -#: flatcamGUI/PreferencesUI.py:7254 flatcamGUI/PreferencesUI.py:7283 -#: flatcamGUI/PreferencesUI.py:7312 flatcamTools/ToolCopperThieving.py:233 -#: flatcamTools/ToolCopperThieving.py:273 -#: flatcamTools/ToolCopperThieving.py:313 +#: flatcamGUI/PreferencesUI.py:7760 flatcamGUI/PreferencesUI.py:7789 +#: flatcamGUI/PreferencesUI.py:7818 flatcamTools/ToolCopperThieving.py:235 +#: flatcamTools/ToolCopperThieving.py:275 +#: flatcamTools/ToolCopperThieving.py:315 msgid "Spacing" msgstr "Spaţiere" -#: flatcamGUI/PreferencesUI.py:7256 flatcamTools/ToolCopperThieving.py:235 +#: flatcamGUI/PreferencesUI.py:7762 flatcamTools/ToolCopperThieving.py:237 msgid "Distance between each two dots in Dots Grid." msgstr "Distanța dintre fiecare două puncte din Grila de Puncte." -#: flatcamGUI/PreferencesUI.py:7266 flatcamTools/ToolCopperThieving.py:256 +#: flatcamGUI/PreferencesUI.py:7772 flatcamTools/ToolCopperThieving.py:258 msgid "Squares Grid Parameters" msgstr "Parametri grilă de patrate" -#: flatcamGUI/PreferencesUI.py:7272 flatcamTools/ToolCopperThieving.py:262 +#: flatcamGUI/PreferencesUI.py:7778 flatcamTools/ToolCopperThieving.py:264 msgid "Square side size in Squares Grid." -msgstr "Dimensiunea pătratului în grila de pătrate" +msgstr "Dimensiunea pătratului în Grila de Pătrate." -#: flatcamGUI/PreferencesUI.py:7285 flatcamTools/ToolCopperThieving.py:275 +#: flatcamGUI/PreferencesUI.py:7791 flatcamTools/ToolCopperThieving.py:277 msgid "Distance between each two squares in Squares Grid." msgstr "Distanța dintre fiecare două pătrate din Grila Pătrate." -#: flatcamGUI/PreferencesUI.py:7295 flatcamTools/ToolCopperThieving.py:296 +#: flatcamGUI/PreferencesUI.py:7801 flatcamTools/ToolCopperThieving.py:298 msgid "Lines Grid Parameters" msgstr "Parametri grilă de linii" -#: flatcamGUI/PreferencesUI.py:7301 flatcamTools/ToolCopperThieving.py:302 +#: flatcamGUI/PreferencesUI.py:7807 flatcamTools/ToolCopperThieving.py:304 msgid "Line thickness size in Lines Grid." msgstr "Mărimea grosimii liniei în Grila de linii." -#: flatcamGUI/PreferencesUI.py:7314 flatcamTools/ToolCopperThieving.py:315 +#: flatcamGUI/PreferencesUI.py:7820 flatcamTools/ToolCopperThieving.py:317 msgid "Distance between each two lines in Lines Grid." msgstr "Distanța dintre fiecare două linii în Grial de linii." -#: flatcamGUI/PreferencesUI.py:7324 flatcamTools/ToolCopperThieving.py:353 +#: flatcamGUI/PreferencesUI.py:7830 flatcamTools/ToolCopperThieving.py:355 msgid "Robber Bar Parameters" msgstr "Parametri pentru Robber Bar" -#: flatcamGUI/PreferencesUI.py:7326 flatcamTools/ToolCopperThieving.py:355 +#: flatcamGUI/PreferencesUI.py:7832 flatcamTools/ToolCopperThieving.py:357 msgid "" "Parameters used for the robber bar.\n" "Robber bar = copper border to help in pattern hole plating." @@ -12508,29 +12942,29 @@ msgstr "" "Parametrii folosiți pentru Robber Bar.\n" "Robber Bar = bordura de cupru pentru a ajuta la placarea de găuri, cu model." -#: flatcamGUI/PreferencesUI.py:7334 flatcamTools/ToolCopperThieving.py:363 +#: flatcamGUI/PreferencesUI.py:7840 flatcamTools/ToolCopperThieving.py:365 msgid "Bounding box margin for robber bar." msgstr "" "Marginea pentru forma înconjurătoare\n" "a Robber Bar." -#: flatcamGUI/PreferencesUI.py:7345 flatcamTools/ToolCopperThieving.py:374 +#: flatcamGUI/PreferencesUI.py:7851 flatcamTools/ToolCopperThieving.py:376 msgid "Thickness" msgstr "Grosime" -#: flatcamGUI/PreferencesUI.py:7347 flatcamTools/ToolCopperThieving.py:376 +#: flatcamGUI/PreferencesUI.py:7853 flatcamTools/ToolCopperThieving.py:378 msgid "The robber bar thickness." msgstr "Grosimea Robber Bar." -#: flatcamGUI/PreferencesUI.py:7357 flatcamTools/ToolCopperThieving.py:407 +#: flatcamGUI/PreferencesUI.py:7863 flatcamTools/ToolCopperThieving.py:409 msgid "Pattern Plating Mask" msgstr "Masca de placare cu model" -#: flatcamGUI/PreferencesUI.py:7359 flatcamTools/ToolCopperThieving.py:409 +#: flatcamGUI/PreferencesUI.py:7865 flatcamTools/ToolCopperThieving.py:411 msgid "Generate a mask for pattern plating." msgstr "Generați o mască pentru placarea cu model." -#: flatcamGUI/PreferencesUI.py:7366 flatcamTools/ToolCopperThieving.py:431 +#: flatcamGUI/PreferencesUI.py:7872 flatcamTools/ToolCopperThieving.py:434 msgid "" "The distance between the possible copper thieving elements\n" "and/or robber bar and the actual openings in the mask." @@ -12538,16 +12972,17 @@ msgstr "" "Distanța dintre posibilele elemente Copper Thieving\n" "și / sau Robber Bar și deschiderile efective ale măștii." -#: flatcamGUI/PreferencesUI.py:7385 +#: flatcamGUI/PreferencesUI.py:7891 msgid "Fiducials Tool Options" msgstr "Opțiuni Unealta Fiducials" -#: flatcamGUI/PreferencesUI.py:7396 flatcamGUI/PreferencesUI.py:7512 -#: flatcamTools/ToolCopperThieving.py:91 flatcamTools/ToolFiducials.py:151 +#: flatcamGUI/PreferencesUI.py:7902 flatcamGUI/PreferencesUI.py:8018 +#: flatcamGUI/PreferencesUI.py:8137 flatcamGUI/PreferencesUI.py:8349 +#: flatcamTools/ToolCopperThieving.py:92 flatcamTools/ToolFiducials.py:151 msgid "Parameters used for this tool." msgstr "Parametrii folosiți pentru aceasta unealta." -#: flatcamGUI/PreferencesUI.py:7403 flatcamTools/ToolFiducials.py:158 +#: flatcamGUI/PreferencesUI.py:7909 flatcamTools/ToolFiducials.py:158 msgid "" "This set the fiducial diameter if fiducial type is circular,\n" "otherwise is the size of the fiducial.\n" @@ -12557,19 +12992,19 @@ msgstr "" "altfel este dimensiunea fiducial-ului.\n" "Deschiderea soldermask este dublă." -#: flatcamGUI/PreferencesUI.py:7431 flatcamTools/ToolFiducials.py:186 +#: flatcamGUI/PreferencesUI.py:7937 flatcamTools/ToolFiducials.py:186 msgid "Auto" msgstr "Auto" -#: flatcamGUI/PreferencesUI.py:7432 flatcamTools/ToolFiducials.py:187 +#: flatcamGUI/PreferencesUI.py:7938 flatcamTools/ToolFiducials.py:187 msgid "Manual" msgstr "Manual" -#: flatcamGUI/PreferencesUI.py:7434 flatcamTools/ToolFiducials.py:189 +#: flatcamGUI/PreferencesUI.py:7940 flatcamTools/ToolFiducials.py:189 msgid "Mode:" msgstr "Mod:" -#: flatcamGUI/PreferencesUI.py:7436 +#: flatcamGUI/PreferencesUI.py:7942 msgid "" "- 'Auto' - automatic placement of fiducials in the corners of the bounding " "box.\n" @@ -12578,19 +13013,19 @@ msgstr "" "- „Auto” - plasarea automată a fiducial în colțurile casetei de delimitare.\n" "- „Manual” - plasarea manuală a fiducial." -#: flatcamGUI/PreferencesUI.py:7444 flatcamTools/ToolFiducials.py:199 +#: flatcamGUI/PreferencesUI.py:7950 flatcamTools/ToolFiducials.py:199 msgid "Up" msgstr "Sus" -#: flatcamGUI/PreferencesUI.py:7445 flatcamTools/ToolFiducials.py:200 +#: flatcamGUI/PreferencesUI.py:7951 flatcamTools/ToolFiducials.py:200 msgid "Down" msgstr "Jos" -#: flatcamGUI/PreferencesUI.py:7448 flatcamTools/ToolFiducials.py:203 +#: flatcamGUI/PreferencesUI.py:7954 flatcamTools/ToolFiducials.py:203 msgid "Second fiducial" msgstr "Al 2-lea Fiducial" -#: flatcamGUI/PreferencesUI.py:7450 flatcamTools/ToolFiducials.py:205 +#: flatcamGUI/PreferencesUI.py:7956 flatcamTools/ToolFiducials.py:205 msgid "" "The position for the second fiducial.\n" "- 'Up' - the order is: bottom-left, top-left, top-right.\n" @@ -12603,19 +13038,19 @@ msgstr "" "- „Niciuna” - nu există un al doilea fiduțial. Ordinea este: jos-stânga, sus-" "dreapta." -#: flatcamGUI/PreferencesUI.py:7466 flatcamTools/ToolFiducials.py:221 +#: flatcamGUI/PreferencesUI.py:7972 flatcamTools/ToolFiducials.py:221 msgid "Cross" msgstr "Cruce" -#: flatcamGUI/PreferencesUI.py:7467 flatcamTools/ToolFiducials.py:222 +#: flatcamGUI/PreferencesUI.py:7973 flatcamTools/ToolFiducials.py:222 msgid "Chess" msgstr "Şah" -#: flatcamGUI/PreferencesUI.py:7470 flatcamTools/ToolFiducials.py:224 +#: flatcamGUI/PreferencesUI.py:7976 flatcamTools/ToolFiducials.py:224 msgid "Fiducial Type" msgstr "Tip Fiducial" -#: flatcamGUI/PreferencesUI.py:7472 flatcamTools/ToolFiducials.py:226 +#: flatcamGUI/PreferencesUI.py:7978 flatcamTools/ToolFiducials.py:226 msgid "" "The type of fiducial.\n" "- 'Circular' - this is the regular fiducial.\n" @@ -12627,19 +13062,19 @@ msgstr "" "- „Cross” - linii încrucișate fiduciare.\n" "- „Șah” - model de șah fiduciar." -#: flatcamGUI/PreferencesUI.py:7481 flatcamTools/ToolFiducials.py:235 +#: flatcamGUI/PreferencesUI.py:7987 flatcamTools/ToolFiducials.py:235 msgid "Line thickness" msgstr "Grosimea liniei" -#: flatcamGUI/PreferencesUI.py:7501 +#: flatcamGUI/PreferencesUI.py:8007 msgid "Calibration Tool Options" msgstr "Opțiuni Unealta Calibrare" -#: flatcamGUI/PreferencesUI.py:7517 flatcamTools/ToolCalibration.py:181 +#: flatcamGUI/PreferencesUI.py:8023 flatcamTools/ToolCalibration.py:181 msgid "Source Type" msgstr "Tipul sursei" -#: flatcamGUI/PreferencesUI.py:7518 flatcamTools/ToolCalibration.py:182 +#: flatcamGUI/PreferencesUI.py:8024 flatcamTools/ToolCalibration.py:182 msgid "" "The source of calibration points.\n" "It can be:\n" @@ -12652,27 +13087,27 @@ msgstr "" "pentru Gerber\n" "- Liber -> faceți clic liber pe ecran pentru a obține punctele de calibrare" -#: flatcamGUI/PreferencesUI.py:7523 flatcamTools/ToolCalibration.py:187 +#: flatcamGUI/PreferencesUI.py:8029 flatcamTools/ToolCalibration.py:187 msgid "Free" msgstr "Liber" -#: flatcamGUI/PreferencesUI.py:7537 flatcamTools/ToolCalibration.py:76 +#: flatcamGUI/PreferencesUI.py:8043 flatcamTools/ToolCalibration.py:76 msgid "Height (Z) for travelling between the points." msgstr "Înălțime (Z) pentru deplasarea între puncte." -#: flatcamGUI/PreferencesUI.py:7549 flatcamTools/ToolCalibration.py:88 +#: flatcamGUI/PreferencesUI.py:8055 flatcamTools/ToolCalibration.py:88 msgid "Verification Z" msgstr "Z Verificare" -#: flatcamGUI/PreferencesUI.py:7551 flatcamTools/ToolCalibration.py:90 +#: flatcamGUI/PreferencesUI.py:8057 flatcamTools/ToolCalibration.py:90 msgid "Height (Z) for checking the point." msgstr "Înălțimea (Z) pentru verificarea punctului." -#: flatcamGUI/PreferencesUI.py:7563 flatcamTools/ToolCalibration.py:102 +#: flatcamGUI/PreferencesUI.py:8069 flatcamTools/ToolCalibration.py:102 msgid "Zero Z tool" msgstr "Realizare Zero Z" -#: flatcamGUI/PreferencesUI.py:7565 flatcamTools/ToolCalibration.py:104 +#: flatcamGUI/PreferencesUI.py:8071 flatcamTools/ToolCalibration.py:104 msgid "" "Include a sequence to zero the height (Z)\n" "of the verification tool." @@ -12680,11 +13115,11 @@ msgstr "" "Includeți o secvență pentru aliniere la zero a înălțimii (Z)\n" "uneltei de verificare." -#: flatcamGUI/PreferencesUI.py:7574 flatcamTools/ToolCalibration.py:113 +#: flatcamGUI/PreferencesUI.py:8080 flatcamTools/ToolCalibration.py:113 msgid "Height (Z) for mounting the verification probe." msgstr "Înălțime (Z) pentru montarea sondei de verificare." -#: flatcamGUI/PreferencesUI.py:7588 flatcamTools/ToolCalibration.py:127 +#: flatcamGUI/PreferencesUI.py:8094 flatcamTools/ToolCalibration.py:127 msgid "" "Toolchange X,Y position.\n" "If no value is entered then the current\n" @@ -12694,11 +13129,11 @@ msgstr "" "Dacă nu este introdusă nicio valoare, atunci poziția\n" "(x, y) curentă se va folosi," -#: flatcamGUI/PreferencesUI.py:7599 flatcamTools/ToolCalibration.py:153 +#: flatcamGUI/PreferencesUI.py:8105 flatcamTools/ToolCalibration.py:153 msgid "Second point" msgstr "Al doilea punct" -#: flatcamGUI/PreferencesUI.py:7601 flatcamTools/ToolCalibration.py:155 +#: flatcamGUI/PreferencesUI.py:8107 flatcamTools/ToolCalibration.py:155 msgid "" "Second point in the Gcode verification can be:\n" "- top-left -> the user will align the PCB vertically\n" @@ -12708,45 +13143,255 @@ msgstr "" "- în stânga sus -> utilizatorul va alinia PCB-ul pe verticală\n" "- în jos-dreapta -> utilizatorul va alinia PCB-ul pe orizontală" -#: flatcamGUI/PreferencesUI.py:7605 flatcamTools/ToolCalibration.py:159 -msgid "Top-Left" -msgstr "Stânga-sus" +#: flatcamGUI/PreferencesUI.py:8126 +msgid "Extract Drills Options" +msgstr "Opțiuni Extractie Găuri" -#: flatcamGUI/PreferencesUI.py:7606 flatcamTools/ToolCalibration.py:160 -msgid "Bottom-Right" -msgstr "Dreapta-jos" +#: flatcamGUI/PreferencesUI.py:8141 flatcamGUI/PreferencesUI.py:8353 +#: flatcamTools/ToolExtractDrills.py:68 flatcamTools/ToolPunchGerber.py:75 +msgid "Processed Pads Type" +msgstr "Tipul de pad-uri procesate" -#: flatcamGUI/PreferencesUI.py:7620 +#: flatcamGUI/PreferencesUI.py:8143 flatcamGUI/PreferencesUI.py:8355 +#: flatcamTools/ToolExtractDrills.py:70 flatcamTools/ToolPunchGerber.py:77 +msgid "" +"The type of pads shape to be processed.\n" +"If the PCB has many SMD pads with rectangular pads,\n" +"disable the Rectangular aperture." +msgstr "" +"Tipul de forme ale pad-urilor care vor fi procesate.\n" +"Daca PCB-ul are multe paduri SMD cu formă rectangulară,\n" +"dezactivează apertura Rectangular." + +#: flatcamGUI/PreferencesUI.py:8153 flatcamGUI/PreferencesUI.py:8365 +#: flatcamTools/ToolExtractDrills.py:80 flatcamTools/ToolPunchGerber.py:91 +msgid "Process Circular Pads." +msgstr "Procesează paduri Circulare." + +#: flatcamGUI/PreferencesUI.py:8159 flatcamGUI/PreferencesUI.py:8261 +#: flatcamGUI/PreferencesUI.py:8371 flatcamGUI/PreferencesUI.py:8475 +#: flatcamTools/ToolExtractDrills.py:86 flatcamTools/ToolExtractDrills.py:214 +#: flatcamTools/ToolPunchGerber.py:97 flatcamTools/ToolPunchGerber.py:242 +msgid "Oblong" +msgstr "Oval" + +#: flatcamGUI/PreferencesUI.py:8161 flatcamGUI/PreferencesUI.py:8373 +#: flatcamTools/ToolExtractDrills.py:88 flatcamTools/ToolPunchGerber.py:99 +msgid "Process Oblong Pads." +msgstr "Procesează paduri Ovale." + +#: flatcamGUI/PreferencesUI.py:8169 flatcamGUI/PreferencesUI.py:8381 +#: flatcamTools/ToolExtractDrills.py:96 flatcamTools/ToolPunchGerber.py:107 +msgid "Process Square Pads." +msgstr "Procesează paduri Pătratice." + +#: flatcamGUI/PreferencesUI.py:8177 flatcamGUI/PreferencesUI.py:8389 +#: flatcamTools/ToolExtractDrills.py:104 flatcamTools/ToolPunchGerber.py:115 +msgid "Process Rectangular Pads." +msgstr "Procesează paduri Rectangulare." + +#: flatcamGUI/PreferencesUI.py:8183 flatcamGUI/PreferencesUI.py:8300 +#: flatcamGUI/PreferencesUI.py:8395 flatcamGUI/PreferencesUI.py:8514 +#: flatcamTools/ToolExtractDrills.py:110 flatcamTools/ToolExtractDrills.py:253 +#: flatcamTools/ToolProperties.py:172 flatcamTools/ToolPunchGerber.py:121 +#: flatcamTools/ToolPunchGerber.py:281 +msgid "Others" +msgstr "Altele" + +#: flatcamGUI/PreferencesUI.py:8185 flatcamGUI/PreferencesUI.py:8397 +#: flatcamTools/ToolExtractDrills.py:112 flatcamTools/ToolPunchGerber.py:123 +msgid "Process pads not in the categories above." +msgstr "Procesează paduri care nu se regăsesc in alte categorii." + +#: flatcamGUI/PreferencesUI.py:8198 flatcamGUI/PreferencesUI.py:8222 +#: flatcamGUI/PreferencesUI.py:8411 flatcamGUI/PreferencesUI.py:8436 +#: flatcamTools/ToolExtractDrills.py:139 flatcamTools/ToolExtractDrills.py:156 +#: flatcamTools/ToolPunchGerber.py:150 flatcamTools/ToolPunchGerber.py:184 +msgid "Fixed Diameter" +msgstr "Dia fix" + +#: flatcamGUI/PreferencesUI.py:8199 flatcamGUI/PreferencesUI.py:8239 +#: flatcamGUI/PreferencesUI.py:8412 flatcamGUI/PreferencesUI.py:8453 +#: flatcamTools/ToolExtractDrills.py:140 flatcamTools/ToolExtractDrills.py:192 +#: flatcamTools/ToolPunchGerber.py:151 flatcamTools/ToolPunchGerber.py:214 +msgid "Fixed Annular Ring" +msgstr "Inel anular Fix" + +#: flatcamGUI/PreferencesUI.py:8200 flatcamGUI/PreferencesUI.py:8413 +#: flatcamTools/ToolExtractDrills.py:141 flatcamTools/ToolPunchGerber.py:152 +msgid "Proportional" +msgstr "Proportional" + +#: flatcamGUI/PreferencesUI.py:8206 flatcamTools/ToolExtractDrills.py:130 +msgid "" +"The method for processing pads. Can be:\n" +"- Fixed Diameter -> all holes will have a set size\n" +"- Fixed Annular Ring -> all holes will have a set annular ring\n" +"- Proportional -> each hole size will be a fraction of the pad size" +msgstr "" +"Metoda de procesare a padurilor. Poate fi:\n" +"- Diametru fix -> toate găurile vor avea o dimensiune prestabilită\n" +"- Inel anular fix -> toate găurile vor avea un inel anular cu dimensiune " +"prestabilită\n" +"- Proportional -> fiecare gaură va avea un diametru cu dimensiunea fractie a " +"dimensiunii padului" + +#: flatcamGUI/PreferencesUI.py:8232 flatcamGUI/PreferencesUI.py:8446 +#: flatcamTools/ToolExtractDrills.py:166 flatcamTools/ToolPunchGerber.py:194 +msgid "Fixed hole diameter." +msgstr "Dia gaură fix." + +#: flatcamGUI/PreferencesUI.py:8241 flatcamGUI/PreferencesUI.py:8455 +#: flatcamTools/ToolExtractDrills.py:194 flatcamTools/ToolPunchGerber.py:216 +msgid "" +"The size of annular ring.\n" +"The copper sliver between the hole exterior\n" +"and the margin of the copper pad." +msgstr "" +"Dimensiunea Inelului Anular.\n" +"Inelul de cupru dintre exteriorul găurii si\n" +"marginea exterioară a padului de cupru." + +#: flatcamGUI/PreferencesUI.py:8250 flatcamGUI/PreferencesUI.py:8464 +#: flatcamTools/ToolExtractDrills.py:203 flatcamTools/ToolPunchGerber.py:231 +msgid "The size of annular ring for circular pads." +msgstr "Dimensiunea inelului anular pentru paduri Circulare." + +#: flatcamGUI/PreferencesUI.py:8263 flatcamGUI/PreferencesUI.py:8477 +#: flatcamTools/ToolExtractDrills.py:216 flatcamTools/ToolPunchGerber.py:244 +msgid "The size of annular ring for oblong pads." +msgstr "Dimensiunea inelului anular pentru paduri Ovale." + +#: flatcamGUI/PreferencesUI.py:8276 flatcamGUI/PreferencesUI.py:8490 +#: flatcamTools/ToolExtractDrills.py:229 flatcamTools/ToolPunchGerber.py:257 +msgid "The size of annular ring for square pads." +msgstr "Dimensiunea inelului anular pentru paduri Pătratice." + +#: flatcamGUI/PreferencesUI.py:8289 flatcamGUI/PreferencesUI.py:8503 +#: flatcamTools/ToolExtractDrills.py:242 flatcamTools/ToolPunchGerber.py:270 +msgid "The size of annular ring for rectangular pads." +msgstr "Dimnensiunea inelului anular pentru paduri Rectangulare." + +#: flatcamGUI/PreferencesUI.py:8302 flatcamGUI/PreferencesUI.py:8516 +#: flatcamTools/ToolExtractDrills.py:255 flatcamTools/ToolPunchGerber.py:283 +msgid "The size of annular ring for other pads." +msgstr "" +"Dimensiunea inelului anular pentru alte tipuri de paduri decat cele de mai " +"sus." + +#: flatcamGUI/PreferencesUI.py:8312 flatcamGUI/PreferencesUI.py:8526 +#: flatcamTools/ToolExtractDrills.py:276 flatcamTools/ToolPunchGerber.py:299 +msgid "Proportional Diameter" +msgstr "Diametru Proportional" + +#: flatcamGUI/PreferencesUI.py:8321 flatcamGUI/PreferencesUI.py:8535 +msgid "Factor" +msgstr "Factor" + +#: flatcamGUI/PreferencesUI.py:8323 flatcamGUI/PreferencesUI.py:8537 +#: flatcamTools/ToolExtractDrills.py:287 flatcamTools/ToolPunchGerber.py:310 +msgid "" +"Proportional Diameter.\n" +"The hole diameter will be a fraction of the pad size." +msgstr "" +"Diametru Proportional.\n" +"Diametrul găurii va fi un procent din dimensiunea padului." + +#: flatcamGUI/PreferencesUI.py:8338 +msgid "Punch Gerber Options" +msgstr "Opțiuni Punctare Gerber" + +#: flatcamGUI/PreferencesUI.py:8419 flatcamTools/ToolPunchGerber.py:141 +msgid "" +"The punch hole source can be:\n" +"- Excellon Object-> the Excellon object drills center will serve as " +"reference.\n" +"- Fixed Diameter -> will try to use the pads center as reference adding " +"fixed diameter holes.\n" +"- Fixed Annular Ring -> will try to keep a set annular ring.\n" +"- Proportional -> will make a Gerber punch hole having the diameter a " +"percentage of the pad diameter.\n" +msgstr "" +"Sursa de punctare pt găuri poate fi:\n" +"- Obiect Excellon -> centrul găurilor din obiectul Excellon va servi ca " +"referintă.\n" +"- Diametru Fix -> se va incerca să se folosească centrul padurilor ca " +"referintă adăungand diametrul fix al găurilor.\n" +"- Inel anular Fix -> va incerca să mentină un inele anular cu dimensiune " +"prestabilită.\n" +"- Proportional -> găurile de punctare vor avea diametrul un procent " +"prestabilit din diametrul padului.\n" + +#: flatcamGUI/PreferencesUI.py:8552 +msgid "Invert Gerber Tool Options" +msgstr "Opțiuni Unalta de Inversare Gerber" + +#: flatcamGUI/PreferencesUI.py:8558 +msgid "" +"A tool to invert Gerber geometry from positive to negative\n" +"and in revers." +msgstr "" +"O unealtă de inversare a geometriei unui obiect Gerber \n" +"din pozitiv in negative si invers." + +#: flatcamGUI/PreferencesUI.py:8572 flatcamTools/ToolInvertGerber.py:90 +msgid "" +"Distance by which to avoid\n" +"the edges of the Gerber object." +msgstr "" +"Distanta cu care trebuie evitate\n" +"marginile obiectului Gerber." + +#: flatcamGUI/PreferencesUI.py:8583 flatcamTools/ToolInvertGerber.py:101 +msgid "Lines Join Style" +msgstr "Stil Unire Linii" + +#: flatcamGUI/PreferencesUI.py:8585 flatcamTools/ToolInvertGerber.py:103 +msgid "" +"The way that the lines in the object outline will be joined.\n" +"Can be:\n" +"- rounded -> an arc is added between two joining lines\n" +"- square -> the lines meet in 90 degrees angle\n" +"- bevel -> the lines are joined by a third line" +msgstr "" +"Modul in care liniile dintr-un perimetru al unui obiect vor fi unite.\n" +"Poate fi:\n" +"- rotunjit -> un arc este adăugat intre oricare doua linii care se " +"intalnesc\n" +"- pătrat -> liniile se vor intalni intr-un unghi de 90 grade\n" +"- Teşit -> liniile sunt unite de o a 3-a linie" + +#: flatcamGUI/PreferencesUI.py:8608 msgid "Excellon File associations" msgstr "Asocieri fisiere Excellon" -#: flatcamGUI/PreferencesUI.py:7633 flatcamGUI/PreferencesUI.py:7706 -#: flatcamGUI/PreferencesUI.py:7776 flatcamGUI/PreferencesUI.py:7846 +#: flatcamGUI/PreferencesUI.py:8621 flatcamGUI/PreferencesUI.py:8694 +#: flatcamGUI/PreferencesUI.py:8764 flatcamGUI/PreferencesUI.py:8834 msgid "Restore" msgstr "Restabilire" -#: flatcamGUI/PreferencesUI.py:7634 flatcamGUI/PreferencesUI.py:7707 -#: flatcamGUI/PreferencesUI.py:7777 +#: flatcamGUI/PreferencesUI.py:8622 flatcamGUI/PreferencesUI.py:8695 +#: flatcamGUI/PreferencesUI.py:8765 msgid "Restore the extension list to the default state." msgstr "Restabiliți lista de extensii la starea implicită." -#: flatcamGUI/PreferencesUI.py:7635 flatcamGUI/PreferencesUI.py:7708 -#: flatcamGUI/PreferencesUI.py:7778 flatcamGUI/PreferencesUI.py:7848 +#: flatcamGUI/PreferencesUI.py:8623 flatcamGUI/PreferencesUI.py:8696 +#: flatcamGUI/PreferencesUI.py:8766 flatcamGUI/PreferencesUI.py:8836 msgid "Delete All" msgstr "Sterge tot" -#: flatcamGUI/PreferencesUI.py:7636 flatcamGUI/PreferencesUI.py:7709 -#: flatcamGUI/PreferencesUI.py:7779 +#: flatcamGUI/PreferencesUI.py:8624 flatcamGUI/PreferencesUI.py:8697 +#: flatcamGUI/PreferencesUI.py:8767 msgid "Delete all extensions from the list." msgstr "Ștergeți toate extensiile din listă." -#: flatcamGUI/PreferencesUI.py:7644 flatcamGUI/PreferencesUI.py:7717 -#: flatcamGUI/PreferencesUI.py:7787 +#: flatcamGUI/PreferencesUI.py:8632 flatcamGUI/PreferencesUI.py:8705 +#: flatcamGUI/PreferencesUI.py:8775 msgid "Extensions list" msgstr "Lista de extensii" -#: flatcamGUI/PreferencesUI.py:7646 flatcamGUI/PreferencesUI.py:7719 -#: flatcamGUI/PreferencesUI.py:7789 +#: flatcamGUI/PreferencesUI.py:8634 flatcamGUI/PreferencesUI.py:8707 +#: flatcamGUI/PreferencesUI.py:8777 msgid "" "List of file extensions to be\n" "associated with FlatCAM." @@ -12754,43 +13399,43 @@ msgstr "" "Listă de extensii fisiere care să fie\n" "associate cu FlatCAM." -#: flatcamGUI/PreferencesUI.py:7666 flatcamGUI/PreferencesUI.py:7739 -#: flatcamGUI/PreferencesUI.py:7808 flatcamGUI/PreferencesUI.py:7880 +#: flatcamGUI/PreferencesUI.py:8654 flatcamGUI/PreferencesUI.py:8727 +#: flatcamGUI/PreferencesUI.py:8796 flatcamGUI/PreferencesUI.py:8868 msgid "Extension" msgstr "Extensie fișier" -#: flatcamGUI/PreferencesUI.py:7667 flatcamGUI/PreferencesUI.py:7740 -#: flatcamGUI/PreferencesUI.py:7809 +#: flatcamGUI/PreferencesUI.py:8655 flatcamGUI/PreferencesUI.py:8728 +#: flatcamGUI/PreferencesUI.py:8797 msgid "A file extension to be added or deleted to the list." msgstr "O extensie de fișier care trebuie adăugată sau ștersă din listă." -#: flatcamGUI/PreferencesUI.py:7675 flatcamGUI/PreferencesUI.py:7748 -#: flatcamGUI/PreferencesUI.py:7817 +#: flatcamGUI/PreferencesUI.py:8663 flatcamGUI/PreferencesUI.py:8736 +#: flatcamGUI/PreferencesUI.py:8805 msgid "Add Extension" msgstr "Adaugă Extensie" -#: flatcamGUI/PreferencesUI.py:7676 flatcamGUI/PreferencesUI.py:7749 -#: flatcamGUI/PreferencesUI.py:7818 +#: flatcamGUI/PreferencesUI.py:8664 flatcamGUI/PreferencesUI.py:8737 +#: flatcamGUI/PreferencesUI.py:8806 msgid "Add a file extension to the list" msgstr "Adăugați o extensie de fișier la listă" -#: flatcamGUI/PreferencesUI.py:7677 flatcamGUI/PreferencesUI.py:7750 -#: flatcamGUI/PreferencesUI.py:7819 +#: flatcamGUI/PreferencesUI.py:8665 flatcamGUI/PreferencesUI.py:8738 +#: flatcamGUI/PreferencesUI.py:8807 msgid "Delete Extension" msgstr "Ștergeți Extensia" -#: flatcamGUI/PreferencesUI.py:7678 flatcamGUI/PreferencesUI.py:7751 -#: flatcamGUI/PreferencesUI.py:7820 +#: flatcamGUI/PreferencesUI.py:8666 flatcamGUI/PreferencesUI.py:8739 +#: flatcamGUI/PreferencesUI.py:8808 msgid "Delete a file extension from the list" msgstr "Ștergeți o extensie de fișier din listă" -#: flatcamGUI/PreferencesUI.py:7685 flatcamGUI/PreferencesUI.py:7758 -#: flatcamGUI/PreferencesUI.py:7827 +#: flatcamGUI/PreferencesUI.py:8673 flatcamGUI/PreferencesUI.py:8746 +#: flatcamGUI/PreferencesUI.py:8815 msgid "Apply Association" msgstr "Aplicați Asociere" -#: flatcamGUI/PreferencesUI.py:7686 flatcamGUI/PreferencesUI.py:7759 -#: flatcamGUI/PreferencesUI.py:7828 +#: flatcamGUI/PreferencesUI.py:8674 flatcamGUI/PreferencesUI.py:8747 +#: flatcamGUI/PreferencesUI.py:8816 msgid "" "Apply the file associations between\n" "FlatCAM and the files with above extensions.\n" @@ -12802,32 +13447,32 @@ msgstr "" "Vor fi active după următorul login.\n" "Functionează numai pt Windows." -#: flatcamGUI/PreferencesUI.py:7703 +#: flatcamGUI/PreferencesUI.py:8691 msgid "GCode File associations" msgstr "Asocierile de fisiere G-Code" -#: flatcamGUI/PreferencesUI.py:7773 +#: flatcamGUI/PreferencesUI.py:8761 msgid "Gerber File associations" msgstr "Asocierile de fisiere Gerber" -#: flatcamGUI/PreferencesUI.py:7843 +#: flatcamGUI/PreferencesUI.py:8831 msgid "Autocompleter Keywords" msgstr "Cuvinte cheie pt autocomplete" -#: flatcamGUI/PreferencesUI.py:7847 +#: flatcamGUI/PreferencesUI.py:8835 msgid "Restore the autocompleter keywords list to the default state." msgstr "" "Restaurați lista cuvinte cheie pentru autocompletere la starea implicită." -#: flatcamGUI/PreferencesUI.py:7849 +#: flatcamGUI/PreferencesUI.py:8837 msgid "Delete all autocompleter keywords from the list." msgstr "Ștergeți din listă toate cuvintele cheie pentru autocompletare." -#: flatcamGUI/PreferencesUI.py:7857 +#: flatcamGUI/PreferencesUI.py:8845 msgid "Keywords list" msgstr "Lista de cuvinte cheie" -#: flatcamGUI/PreferencesUI.py:7859 +#: flatcamGUI/PreferencesUI.py:8847 msgid "" "List of keywords used by\n" "the autocompleter in FlatCAM.\n" @@ -12839,31 +13484,31 @@ msgstr "" "Autocompleterul este instalat\n" "în Editorul de coduri și pentru Shell Tcl." -#: flatcamGUI/PreferencesUI.py:7881 +#: flatcamGUI/PreferencesUI.py:8869 msgid "A keyword to be added or deleted to the list." msgstr "Un cuvânt cheie care trebuie adăugat sau șters la listă." -#: flatcamGUI/PreferencesUI.py:7889 +#: flatcamGUI/PreferencesUI.py:8877 msgid "Add keyword" msgstr "Adăugați cuvant cheie" -#: flatcamGUI/PreferencesUI.py:7890 +#: flatcamGUI/PreferencesUI.py:8878 msgid "Add a keyword to the list" msgstr "Adăugați un cuvânt cheie la listă" -#: flatcamGUI/PreferencesUI.py:7891 +#: flatcamGUI/PreferencesUI.py:8879 msgid "Delete keyword" msgstr "Ștergeți cuvântul cheie" -#: flatcamGUI/PreferencesUI.py:7892 +#: flatcamGUI/PreferencesUI.py:8880 msgid "Delete a keyword from the list" msgstr "Ștergeți un cuvânt cheie din listă" -#: flatcamParsers/ParseExcellon.py:314 +#: flatcamParsers/ParseExcellon.py:315 msgid "This is GCODE mark" msgstr "Acesta este un marcaj Gerber" -#: flatcamParsers/ParseExcellon.py:431 +#: flatcamParsers/ParseExcellon.py:432 msgid "" "No tool diameter info's. See shell.\n" "A tool change event: T" @@ -12871,7 +13516,7 @@ msgstr "" "Nu există informații despre diametrul uneltei. Vezi Shell.\n" "Un eveniment de schimbare a uneltei: T" -#: flatcamParsers/ParseExcellon.py:434 +#: flatcamParsers/ParseExcellon.py:435 msgid "" "was found but the Excellon file have no informations regarding the tool " "diameters therefore the application will try to load it by using some 'fake' " @@ -12884,12 +13529,12 @@ msgstr "" "Userul trebuie să editeze obictul Excellon rezultat si sa ajusteze " "diametrele a.i sa reflecte diametrele reale." -#: flatcamParsers/ParseExcellon.py:886 flatcamTools/ToolSolderPaste.py:1330 +#: flatcamParsers/ParseExcellon.py:897 flatcamTools/ToolSolderPaste.py:1327 msgid "An internal error has ocurred. See shell.\n" msgstr "" "A apărut o eroare internă. Verifică in TCL Shell pt mai multe detalii.\n" -#: flatcamParsers/ParseExcellon.py:889 +#: flatcamParsers/ParseExcellon.py:900 msgid "" "Excellon Parser error.\n" "Parsing Failed. Line" @@ -12897,7 +13542,7 @@ msgstr "" "Eroare de analiza Excellon.\n" "Analizarea a esuat. Linia" -#: flatcamParsers/ParseExcellon.py:973 +#: flatcamParsers/ParseExcellon.py:982 msgid "" "Excellon.create_geometry() -> a drill location was skipped due of not having " "a tool associated.\n" @@ -12915,22 +13560,22 @@ msgstr "Fontul nu este acceptat, incearcă altul." msgid "Gerber processing. Parsing" msgstr "Prelucrare Gerber. Analizare" -#: flatcamParsers/ParseGerber.py:426 flatcamParsers/ParseHPGL2.py:176 +#: flatcamParsers/ParseGerber.py:426 flatcamParsers/ParseHPGL2.py:178 msgid "lines" msgstr "linii" -#: flatcamParsers/ParseGerber.py:970 flatcamParsers/ParseGerber.py:1065 -#: flatcamParsers/ParseHPGL2.py:269 flatcamParsers/ParseHPGL2.py:283 -#: flatcamParsers/ParseHPGL2.py:302 flatcamParsers/ParseHPGL2.py:326 -#: flatcamParsers/ParseHPGL2.py:361 +#: flatcamParsers/ParseGerber.py:1002 flatcamParsers/ParseGerber.py:1102 +#: flatcamParsers/ParseHPGL2.py:271 flatcamParsers/ParseHPGL2.py:285 +#: flatcamParsers/ParseHPGL2.py:304 flatcamParsers/ParseHPGL2.py:328 +#: flatcamParsers/ParseHPGL2.py:363 msgid "Coordinates missing, line ignored" msgstr "Coordonatele lipsesc, linia este ignorată" -#: flatcamParsers/ParseGerber.py:972 flatcamParsers/ParseGerber.py:1067 +#: flatcamParsers/ParseGerber.py:1004 flatcamParsers/ParseGerber.py:1104 msgid "GERBER file might be CORRUPT. Check the file !!!" msgstr "Fişierul Gerber poate fi corrupt. Verificati fişierul!!!" -#: flatcamParsers/ParseGerber.py:1021 +#: flatcamParsers/ParseGerber.py:1058 msgid "" "Region does not have enough points. File will be processed but there are " "parser errors. Line number" @@ -12938,66 +13583,217 @@ msgstr "" "Regiunea Gerber nu are suficiente puncte. Fişierul va fi procesat dar sunt " "erori de parsare. Numărul liniei" -#: flatcamParsers/ParseGerber.py:1421 flatcamParsers/ParseHPGL2.py:396 +#: flatcamParsers/ParseGerber.py:1488 flatcamParsers/ParseHPGL2.py:398 msgid "Gerber processing. Joining polygons" msgstr "Prelucrare Gerber. Se combină poligoanele" -#: flatcamParsers/ParseGerber.py:1438 +#: flatcamParsers/ParseGerber.py:1505 msgid "Gerber processing. Applying Gerber polarity." msgstr "Prelucrare Gerber. Se aplica polaritatea Gerber." -#: flatcamParsers/ParseGerber.py:1498 +#: flatcamParsers/ParseGerber.py:1565 msgid "Gerber Line" msgstr "Linia Gerber" -#: flatcamParsers/ParseGerber.py:1498 +#: flatcamParsers/ParseGerber.py:1565 msgid "Gerber Line Content" msgstr "Continut linie Gerber" -#: flatcamParsers/ParseGerber.py:1500 +#: flatcamParsers/ParseGerber.py:1567 msgid "Gerber Parser ERROR" msgstr "Eroare in parserul Gerber" -#: flatcamParsers/ParseGerber.py:1884 +#: flatcamParsers/ParseGerber.py:1956 msgid "Gerber Scale done." msgstr "Scalarea Gerber efectuată." -#: flatcamParsers/ParseGerber.py:1977 +#: flatcamParsers/ParseGerber.py:2049 msgid "Gerber Offset done." msgstr "Offsetare Gerber efectuată." -#: flatcamParsers/ParseGerber.py:2054 +#: flatcamParsers/ParseGerber.py:2126 msgid "Gerber Mirror done." msgstr "Oglindirea Gerber efectuată." -#: flatcamParsers/ParseGerber.py:2128 +#: flatcamParsers/ParseGerber.py:2200 msgid "Gerber Skew done." msgstr "Deformarea Gerber efectuată." -#: flatcamParsers/ParseGerber.py:2192 +#: flatcamParsers/ParseGerber.py:2263 msgid "Gerber Rotate done." msgstr "Rotatia Gerber efectuată." -#: flatcamParsers/ParseGerber.py:2273 +#: flatcamParsers/ParseGerber.py:2419 msgid "Gerber Buffer done." msgstr "Buffer Gerber efectuat." -#: flatcamParsers/ParseHPGL2.py:176 +#: flatcamParsers/ParseHPGL2.py:178 msgid "HPGL2 processing. Parsing" msgstr "Prelucrare HPGL2. Analizare" -#: flatcamParsers/ParseHPGL2.py:408 +#: flatcamParsers/ParseHPGL2.py:410 msgid "HPGL2 Line" msgstr "Linie HPGL2" -#: flatcamParsers/ParseHPGL2.py:408 +#: flatcamParsers/ParseHPGL2.py:410 msgid "HPGL2 Line Content" msgstr "Continut linie HPGL2" -#: flatcamParsers/ParseHPGL2.py:409 +#: flatcamParsers/ParseHPGL2.py:411 msgid "HPGL2 Parser ERROR" msgstr "Eroare in parserul HPGL2" +#: flatcamTools/ToolAlignObjects.py:32 +msgid "Align Objects" +msgstr "Aliniere Obiecte" + +#: flatcamTools/ToolAlignObjects.py:61 +msgid "MOVING object" +msgstr "MISCARE obiect" + +#: flatcamTools/ToolAlignObjects.py:65 +msgid "" +"Specify the type of object to be aligned.\n" +"It can be of type: Gerber or Excellon.\n" +"The selection here decide the type of objects that will be\n" +"in the Object combobox." +msgstr "" +"Specifică tipul de obiect care va fi aliniat.\n" +"Poate fi de tipul: Gerber sau Excellon.\n" +"Selectia făcută aici va dicta tipul de obiecte care se vor\n" +"regăsi in combobox-ul >Obiect<." + +#: flatcamTools/ToolAlignObjects.py:86 +msgid "Object to be aligned." +msgstr "Obiect care trebuie aliniat." + +#: flatcamTools/ToolAlignObjects.py:98 +msgid "TARGET object" +msgstr "Obiectul TINTA" + +#: flatcamTools/ToolAlignObjects.py:100 +msgid "" +"Specify the type of object to be aligned to.\n" +"It can be of type: Gerber or Excellon.\n" +"The selection here decide the type of objects that will be\n" +"in the Object combobox." +msgstr "" +"Specifică tipul de obiect la care se va alinia un alt obiect.\n" +"Poate fi de tipul: Gerbe sau Excellon.\n" +"Selectia făcută aici va dicta tipul de obiecte care se vor\n" +"regăsi in combobox-ul >Obiect<." + +#: flatcamTools/ToolAlignObjects.py:122 +msgid "Object to be aligned to. Aligner." +msgstr "Obiectul către care se face alinierea. Aliniator." + +#: flatcamTools/ToolAlignObjects.py:135 +msgid "Alignment Type" +msgstr "Tip Aliniere" + +#: flatcamTools/ToolAlignObjects.py:137 +msgid "" +"The type of alignment can be:\n" +"- Single Point -> it require a single point of sync, the action will be a " +"translation\n" +"- Dual Point -> it require two points of sync, the action will be " +"translation followed by rotation" +msgstr "" +"Tipul de aliniere poate fi:\n" +"- Punct Singular -> necesită un singur punct de sincronizare, actiunea va fi " +"o translatie\n" +"- Punct Dublu -> necesita două puncta de sincronizare, actiunea va di o " +"translatie urmată de o posibilă rotatie" + +#: flatcamTools/ToolAlignObjects.py:143 +msgid "Single Point" +msgstr "Punct Singular" + +#: flatcamTools/ToolAlignObjects.py:144 +msgid "Dual Point" +msgstr "Punct Dublu" + +#: flatcamTools/ToolAlignObjects.py:159 +msgid "Align Object" +msgstr "Aliniază Obiectul" + +#: flatcamTools/ToolAlignObjects.py:161 +msgid "" +"Align the specified object to the aligner object.\n" +"If only one point is used then it assumes translation.\n" +"If tho points are used it assume translation and rotation." +msgstr "" +"Aliniază obiectul specificat la obiectul aliniator.\n" +"Dacă doar un singul punct de aliniere este folosit atunci se presupune o " +"simplă translatie.\n" +"Daca se folosesc două puncte atunci va fi o translatie urmată de o posibilă " +"rotatie." + +#: flatcamTools/ToolAlignObjects.py:176 flatcamTools/ToolCalculators.py:246 +#: flatcamTools/ToolCalibration.py:683 flatcamTools/ToolCopperThieving.py:485 +#: flatcamTools/ToolCutOut.py:372 flatcamTools/ToolDblSided.py:472 +#: flatcamTools/ToolExtractDrills.py:310 flatcamTools/ToolFiducials.py:318 +#: flatcamTools/ToolFilm.py:520 flatcamTools/ToolInvertGerber.py:140 +#: flatcamTools/ToolNCC.py:612 flatcamTools/ToolOptimal.py:238 +#: flatcamTools/ToolPaint.py:556 flatcamTools/ToolPanelize.py:269 +#: flatcamTools/ToolPunchGerber.py:339 flatcamTools/ToolQRCode.py:314 +#: flatcamTools/ToolRulesCheck.py:516 flatcamTools/ToolSolderPaste.py:474 +#: flatcamTools/ToolSub.py:176 flatcamTools/ToolTransform.py:399 +msgid "Reset Tool" +msgstr "Resetați Unealta" + +#: flatcamTools/ToolAlignObjects.py:178 flatcamTools/ToolCalculators.py:248 +#: flatcamTools/ToolCalibration.py:685 flatcamTools/ToolCopperThieving.py:487 +#: flatcamTools/ToolCutOut.py:374 flatcamTools/ToolDblSided.py:474 +#: flatcamTools/ToolExtractDrills.py:312 flatcamTools/ToolFiducials.py:320 +#: flatcamTools/ToolFilm.py:522 flatcamTools/ToolInvertGerber.py:142 +#: flatcamTools/ToolNCC.py:614 flatcamTools/ToolOptimal.py:240 +#: flatcamTools/ToolPaint.py:558 flatcamTools/ToolPanelize.py:271 +#: flatcamTools/ToolPunchGerber.py:341 flatcamTools/ToolQRCode.py:316 +#: flatcamTools/ToolRulesCheck.py:518 flatcamTools/ToolSolderPaste.py:476 +#: flatcamTools/ToolSub.py:178 flatcamTools/ToolTransform.py:401 +msgid "Will reset the tool parameters." +msgstr "Va reseta parametrii uneltei." + +#: flatcamTools/ToolAlignObjects.py:244 +msgid "Align Tool" +msgstr "Unealta Aliniere" + +#: flatcamTools/ToolAlignObjects.py:289 +msgid "There is no aligned FlatCAM object selected..." +msgstr "Nu a fost selectat niciun obiect FlatCAM pentru a fi aliniat..." + +#: flatcamTools/ToolAlignObjects.py:299 +msgid "There is no aligner FlatCAM object selected..." +msgstr "" +"Nu a fost selectat niciun obiect FlatCAM către care să se facă alinierea..." + +#: flatcamTools/ToolAlignObjects.py:325 flatcamTools/ToolAlignObjects.py:385 +msgid "First Point" +msgstr "Primul punct" + +#: flatcamTools/ToolAlignObjects.py:325 flatcamTools/ToolAlignObjects.py:400 +msgid "Click on the START point." +msgstr "Click pe punctul START." + +#: flatcamTools/ToolAlignObjects.py:380 flatcamTools/ToolCalibration.py:920 +msgid "Cancelled by user request." +msgstr "Anulat prin solicitarea utilizatorului." + +#: flatcamTools/ToolAlignObjects.py:385 flatcamTools/ToolAlignObjects.py:407 +msgid "Click on the DESTINATION point." +msgstr "Click pe punctul DESTINATIE." + +#: flatcamTools/ToolAlignObjects.py:385 flatcamTools/ToolAlignObjects.py:400 +#: flatcamTools/ToolAlignObjects.py:407 +msgid " Or right click to cancel." +msgstr " Sau fă click dreapta pentru anulare." + +#: flatcamTools/ToolAlignObjects.py:400 flatcamTools/ToolAlignObjects.py:407 +#: flatcamTools/ToolFiducials.py:111 +msgid "Second Point" +msgstr "Al doilea punct" + #: flatcamTools/ToolCalculators.py:24 msgid "Calculators" msgstr "Calculatoare" @@ -13085,7 +13881,7 @@ msgstr "" "Calculează intensitatea curentului cat și durata procedurii\n" "in funcţie de parametrii de mai sus" -#: flatcamTools/ToolCalculators.py:285 +#: flatcamTools/ToolCalculators.py:299 msgid "Calc. Tool" msgstr "Unealta Calc" @@ -13111,26 +13907,26 @@ msgstr "" "Aceste patru puncte ar trebui să fie în cele patru\n" "(pe cât posibil) colțurile obiectului." -#: flatcamTools/ToolCalibration.py:193 flatcamTools/ToolCutOut.py:80 -#: flatcamTools/ToolFilm.py:78 flatcamTools/ToolImage.py:55 -#: flatcamTools/ToolPanelize.py:66 flatcamTools/ToolProperties.py:169 +#: flatcamTools/ToolCalibration.py:193 flatcamTools/ToolFilm.py:76 +#: flatcamTools/ToolImage.py:54 flatcamTools/ToolPanelize.py:78 +#: flatcamTools/ToolProperties.py:177 msgid "Object Type" msgstr "Tip Obiect" -#: flatcamTools/ToolCalibration.py:211 +#: flatcamTools/ToolCalibration.py:210 msgid "Source object selection" msgstr "Selectarea obiectului sursă" -#: flatcamTools/ToolCalibration.py:213 +#: flatcamTools/ToolCalibration.py:212 msgid "FlatCAM Object to be used as a source for reference points." msgstr "" "Obiect FlatCAM care trebuie utilizat ca sursă pentru punctele de referință." -#: flatcamTools/ToolCalibration.py:219 +#: flatcamTools/ToolCalibration.py:218 msgid "Calibration Points" msgstr "Puncte de calibrare" -#: flatcamTools/ToolCalibration.py:221 +#: flatcamTools/ToolCalibration.py:220 msgid "" "Contain the expected calibration points and the\n" "ones measured." @@ -13138,56 +13934,52 @@ msgstr "" "Conține punctele de calibrare așteptate și\n" "cele măsurate." -#: flatcamTools/ToolCalibration.py:236 flatcamTools/ToolSub.py:74 -#: flatcamTools/ToolSub.py:126 +#: flatcamTools/ToolCalibration.py:235 flatcamTools/ToolSub.py:76 +#: flatcamTools/ToolSub.py:131 msgid "Target" msgstr "Tintă" -#: flatcamTools/ToolCalibration.py:237 +#: flatcamTools/ToolCalibration.py:236 msgid "Found Delta" msgstr "Delta găsit" -#: flatcamTools/ToolCalibration.py:249 +#: flatcamTools/ToolCalibration.py:248 msgid "Bot Left X" msgstr "Stânga jos X" -#: flatcamTools/ToolCalibration.py:258 +#: flatcamTools/ToolCalibration.py:257 msgid "Bot Left Y" msgstr "Stânga jos Y" -#: flatcamTools/ToolCalibration.py:266 flatcamTools/ToolCalibration.py:267 -msgid "Origin" -msgstr "Originea" - -#: flatcamTools/ToolCalibration.py:278 +#: flatcamTools/ToolCalibration.py:275 msgid "Bot Right X" msgstr "Dreapta-jos X" -#: flatcamTools/ToolCalibration.py:288 +#: flatcamTools/ToolCalibration.py:285 msgid "Bot Right Y" msgstr "Dreapta-jos Y" -#: flatcamTools/ToolCalibration.py:303 +#: flatcamTools/ToolCalibration.py:300 msgid "Top Left X" msgstr "Stânga sus X" -#: flatcamTools/ToolCalibration.py:312 +#: flatcamTools/ToolCalibration.py:309 msgid "Top Left Y" msgstr "Stânga sus Y" -#: flatcamTools/ToolCalibration.py:327 +#: flatcamTools/ToolCalibration.py:324 msgid "Top Right X" msgstr "Dreapta-sus X" -#: flatcamTools/ToolCalibration.py:337 +#: flatcamTools/ToolCalibration.py:334 msgid "Top Right Y" msgstr "Dreapta-sus Y" -#: flatcamTools/ToolCalibration.py:370 +#: flatcamTools/ToolCalibration.py:367 msgid "Get Points" msgstr "Obține puncte" -#: flatcamTools/ToolCalibration.py:372 +#: flatcamTools/ToolCalibration.py:369 msgid "" "Pick four points by clicking on canvas if the source choice\n" "is 'free' or inside the object geometry if the source is 'object'.\n" @@ -13199,11 +13991,11 @@ msgstr "" "Aceste patru puncte ar trebui să se afle în cele patru colțuri ale\n" "obiectului." -#: flatcamTools/ToolCalibration.py:393 +#: flatcamTools/ToolCalibration.py:390 msgid "STEP 2: Verification GCode" msgstr "PASUL 2: GCode de verificare" -#: flatcamTools/ToolCalibration.py:395 flatcamTools/ToolCalibration.py:408 +#: flatcamTools/ToolCalibration.py:392 flatcamTools/ToolCalibration.py:405 msgid "" "Generate GCode file to locate and align the PCB by using\n" "the four points acquired above.\n" @@ -13223,15 +14015,15 @@ msgstr "" "dreapta.\n" "- punctul înainte -> punctul de verificare final. Doar pentru evaluare." -#: flatcamTools/ToolCalibration.py:406 flatcamTools/ToolSolderPaste.py:347 +#: flatcamTools/ToolCalibration.py:403 flatcamTools/ToolSolderPaste.py:349 msgid "Generate GCode" msgstr "Generează GCode" -#: flatcamTools/ToolCalibration.py:432 +#: flatcamTools/ToolCalibration.py:429 msgid "STEP 3: Adjustments" msgstr "PASUL 3: Reglaje" -#: flatcamTools/ToolCalibration.py:434 flatcamTools/ToolCalibration.py:443 +#: flatcamTools/ToolCalibration.py:431 flatcamTools/ToolCalibration.py:440 msgid "" "Calculate Scale and Skew factors based on the differences (delta)\n" "found when checking the PCB pattern. The differences must be filled\n" @@ -13241,15 +14033,15 @@ msgstr "" "găsite la verificarea modelului PCB. Diferențele trebuie completate\n" "în câmpurile găsite (Delta)." -#: flatcamTools/ToolCalibration.py:441 +#: flatcamTools/ToolCalibration.py:438 msgid "Calculate Factors" msgstr "Calculați factorii" -#: flatcamTools/ToolCalibration.py:463 +#: flatcamTools/ToolCalibration.py:460 msgid "STEP 4: Adjusted GCode" msgstr "PASUL 4: GCode ajustat" -#: flatcamTools/ToolCalibration.py:465 +#: flatcamTools/ToolCalibration.py:462 msgid "" "Generate verification GCode file adjusted with\n" "the factors above." @@ -13257,43 +14049,43 @@ msgstr "" "Generați fișierul GCode de verificare ajustat cu\n" "factorii de mai sus." -#: flatcamTools/ToolCalibration.py:470 +#: flatcamTools/ToolCalibration.py:467 msgid "Scale Factor X:" msgstr "Factor scalare X:" -#: flatcamTools/ToolCalibration.py:482 +#: flatcamTools/ToolCalibration.py:479 msgid "Scale Factor Y:" msgstr "Factor scalare Y:" -#: flatcamTools/ToolCalibration.py:494 +#: flatcamTools/ToolCalibration.py:491 msgid "Apply Scale Factors" msgstr "Aplicați factorii de scalare" -#: flatcamTools/ToolCalibration.py:496 +#: flatcamTools/ToolCalibration.py:493 msgid "Apply Scale factors on the calibration points." msgstr "Aplicați factorii de Scalare asupra punctelor de calibrare." -#: flatcamTools/ToolCalibration.py:506 +#: flatcamTools/ToolCalibration.py:503 msgid "Skew Angle X:" msgstr "Unghi X Deformare:" -#: flatcamTools/ToolCalibration.py:519 +#: flatcamTools/ToolCalibration.py:516 msgid "Skew Angle Y:" msgstr "Unghi Y Deformare:" -#: flatcamTools/ToolCalibration.py:532 +#: flatcamTools/ToolCalibration.py:529 msgid "Apply Skew Factors" msgstr "Aplicați factorii de deformare" -#: flatcamTools/ToolCalibration.py:534 +#: flatcamTools/ToolCalibration.py:531 msgid "Apply Skew factors on the calibration points." msgstr "Aplicați factorii de Deformare asupra punctelor de calibrare." -#: flatcamTools/ToolCalibration.py:603 +#: flatcamTools/ToolCalibration.py:600 msgid "Generate Adjusted GCode" msgstr "Generați GCode ajustat" -#: flatcamTools/ToolCalibration.py:605 +#: flatcamTools/ToolCalibration.py:602 msgid "" "Generate verification GCode file adjusted with\n" "the factors set above.\n" @@ -13305,11 +14097,11 @@ msgstr "" "Parametrii GCode pot fi reglați\n" "înainte de a face clic pe acest buton." -#: flatcamTools/ToolCalibration.py:626 +#: flatcamTools/ToolCalibration.py:623 msgid "STEP 5: Calibrate FlatCAM Objects" msgstr "PASUL 5: Calibrați obiectele FlatCAM" -#: flatcamTools/ToolCalibration.py:628 +#: flatcamTools/ToolCalibration.py:625 msgid "" "Adjust the FlatCAM objects\n" "with the factors determined and verified above." @@ -13317,27 +14109,27 @@ msgstr "" "Reglați obiectele FlatCAM\n" "cu factorii determinați și verificați mai sus." -#: flatcamTools/ToolCalibration.py:641 +#: flatcamTools/ToolCalibration.py:637 msgid "Adjusted object type" msgstr "Tipul obiectului ajustat" -#: flatcamTools/ToolCalibration.py:643 +#: flatcamTools/ToolCalibration.py:638 msgid "Type of the FlatCAM Object to be adjusted." msgstr "Tipul obiectului FlatCAM care trebuie ajustat." -#: flatcamTools/ToolCalibration.py:654 +#: flatcamTools/ToolCalibration.py:651 msgid "Adjusted object selection" msgstr "Selectarea obiectului ajustat" -#: flatcamTools/ToolCalibration.py:656 +#: flatcamTools/ToolCalibration.py:653 msgid "The FlatCAM Object to be adjusted." msgstr "Obiectul FlatCAM care trebuie ajustat." -#: flatcamTools/ToolCalibration.py:663 +#: flatcamTools/ToolCalibration.py:660 msgid "Calibrate" msgstr "Calibreaza" -#: flatcamTools/ToolCalibration.py:665 +#: flatcamTools/ToolCalibration.py:662 msgid "" "Adjust (scale and/or skew) the objects\n" "with the factors determined above." @@ -13345,81 +14137,61 @@ msgstr "" "Reglați (Scalați și / sau Deformați) obiectele\n" "cu factorii determinați mai sus." -#: flatcamTools/ToolCalibration.py:686 flatcamTools/ToolCopperThieving.py:482 -#: flatcamTools/ToolCutOut.py:362 flatcamTools/ToolDblSided.py:405 -#: flatcamTools/ToolFiducials.py:316 flatcamTools/ToolFilm.py:518 -#: flatcamTools/ToolNonCopperClear.py:486 flatcamTools/ToolOptimal.py:237 -#: flatcamTools/ToolPaint.py:372 flatcamTools/ToolPanelize.py:266 -#: flatcamTools/ToolQRCode.py:314 flatcamTools/ToolRulesCheck.py:507 -#: flatcamTools/ToolSolderPaste.py:470 flatcamTools/ToolSub.py:170 -msgid "Reset Tool" -msgstr "Resetați Unealta" +#: flatcamTools/ToolCalibration.py:770 flatcamTools/ToolCalibration.py:771 +msgid "Origin" +msgstr "Originea" -#: flatcamTools/ToolCalibration.py:688 flatcamTools/ToolCopperThieving.py:484 -#: flatcamTools/ToolCutOut.py:364 flatcamTools/ToolDblSided.py:407 -#: flatcamTools/ToolFiducials.py:318 flatcamTools/ToolFilm.py:520 -#: flatcamTools/ToolNonCopperClear.py:488 flatcamTools/ToolOptimal.py:239 -#: flatcamTools/ToolPaint.py:374 flatcamTools/ToolPanelize.py:268 -#: flatcamTools/ToolQRCode.py:316 flatcamTools/ToolRulesCheck.py:509 -#: flatcamTools/ToolSolderPaste.py:472 flatcamTools/ToolSub.py:172 -msgid "Will reset the tool parameters." -msgstr "Va reseta parametrii uneltei." - -#: flatcamTools/ToolCalibration.py:792 +#: flatcamTools/ToolCalibration.py:800 msgid "Tool initialized" msgstr "Unealtă initializată" -#: flatcamTools/ToolCalibration.py:824 +#: flatcamTools/ToolCalibration.py:838 msgid "There is no source FlatCAM object selected..." msgstr "Nu a fost selectat niciun obiect FlatCAM sursă ..." -#: flatcamTools/ToolCalibration.py:845 +#: flatcamTools/ToolCalibration.py:859 msgid "Get First calibration point. Bottom Left..." msgstr "Obțineți primul punct de calibrare. Stânga jos..." -#: flatcamTools/ToolCalibration.py:906 -msgid "Cancelled by user request." -msgstr "Anulat prin solicitarea utilizatorului." - -#: flatcamTools/ToolCalibration.py:912 +#: flatcamTools/ToolCalibration.py:926 msgid "Get Second calibration point. Bottom Right (Top Left)..." msgstr "" "Obțineți al doilea punct de calibrare. Dreapta jos (sau în stânga sus) ..." -#: flatcamTools/ToolCalibration.py:916 +#: flatcamTools/ToolCalibration.py:930 msgid "Get Third calibration point. Top Left (Bottom Right)..." msgstr "" "Obțineți al treilea punct de calibrare. Sus stanga (sau în jos dreapta)..." -#: flatcamTools/ToolCalibration.py:920 +#: flatcamTools/ToolCalibration.py:934 msgid "Get Forth calibration point. Top Right..." msgstr "Obțineți punctul de calibrare Forth. Sus în dreapta..." -#: flatcamTools/ToolCalibration.py:924 +#: flatcamTools/ToolCalibration.py:938 msgid "Done. All four points have been acquired." msgstr "Terminat. Toate cele patru puncte au fost obținute." -#: flatcamTools/ToolCalibration.py:955 +#: flatcamTools/ToolCalibration.py:969 msgid "Verification GCode for FlatCAM Calibration Tool" msgstr "GCode de verificare pentru Unealta FlatCAM de Calibrare" -#: flatcamTools/ToolCalibration.py:967 flatcamTools/ToolCalibration.py:1053 +#: flatcamTools/ToolCalibration.py:981 flatcamTools/ToolCalibration.py:1067 msgid "Gcode Viewer" msgstr "Gcode Viewer" -#: flatcamTools/ToolCalibration.py:983 +#: flatcamTools/ToolCalibration.py:997 msgid "Cancelled. Four points are needed for GCode generation." msgstr "Anulat. Patru puncte sunt necesare pentru generarea GCode." -#: flatcamTools/ToolCalibration.py:1239 flatcamTools/ToolCalibration.py:1335 +#: flatcamTools/ToolCalibration.py:1253 flatcamTools/ToolCalibration.py:1349 msgid "There is no FlatCAM object selected..." msgstr "Nu a fost selectat niciun obiect FlatCAM ..." -#: flatcamTools/ToolCopperThieving.py:76 flatcamTools/ToolFiducials.py:260 +#: flatcamTools/ToolCopperThieving.py:77 flatcamTools/ToolFiducials.py:261 msgid "Gerber Object to which will be added a copper thieving." msgstr "Obiect Gerber căruia i se va adăuga Copper Thieving." -#: flatcamTools/ToolCopperThieving.py:98 +#: flatcamTools/ToolCopperThieving.py:99 msgid "" "This set the distance between the copper thieving components\n" "(the polygon fill may be split in multiple polygons)\n" @@ -13429,7 +14201,7 @@ msgstr "" "(umplutura poligonului poate fi împărțită în mai multe poligoane)\n" "si traseele de cupru din fisierul Gerber." -#: flatcamTools/ToolCopperThieving.py:131 +#: flatcamTools/ToolCopperThieving.py:132 msgid "" "- 'Itself' - the copper thieving extent is based on the object extent.\n" "- 'Area Selection' - left mouse click to start selection of the area to be " @@ -13443,12 +14215,12 @@ msgstr "" "- „Obiect de referință” - va face Copper Thieving în zona specificată de un " "alt obiect." -#: flatcamTools/ToolCopperThieving.py:138 -#: flatcamTools/ToolNonCopperClear.py:445 flatcamTools/ToolPaint.py:326 +#: flatcamTools/ToolCopperThieving.py:139 flatcamTools/ToolNCC.py:552 +#: flatcamTools/ToolPaint.py:496 msgid "Ref. Type" msgstr "Tip Ref" -#: flatcamTools/ToolCopperThieving.py:140 +#: flatcamTools/ToolCopperThieving.py:141 msgid "" "The type of FlatCAM object to be used as copper thieving reference.\n" "It can be Gerber, Excellon or Geometry." @@ -13457,37 +14229,22 @@ msgstr "" "Thieving.\n" "Poate fi Gerber, Excellon sau Geometrie." -#: flatcamTools/ToolCopperThieving.py:144 flatcamTools/ToolDblSided.py:215 -#: flatcamTools/ToolNonCopperClear.py:451 flatcamTools/ToolPaint.py:332 -msgid "Reference Gerber" -msgstr "Referință Gerber" - -#: flatcamTools/ToolCopperThieving.py:145 flatcamTools/ToolDblSided.py:216 -#: flatcamTools/ToolNonCopperClear.py:452 flatcamTools/ToolPaint.py:333 -msgid "Reference Excellon" -msgstr "Referință Excellon" - -#: flatcamTools/ToolCopperThieving.py:146 flatcamTools/ToolDblSided.py:217 -#: flatcamTools/ToolNonCopperClear.py:453 flatcamTools/ToolPaint.py:334 -msgid "Reference Geometry" -msgstr "Referință Geometrie" - -#: flatcamTools/ToolCopperThieving.py:151 -#: flatcamTools/ToolNonCopperClear.py:456 flatcamTools/ToolPaint.py:337 +#: flatcamTools/ToolCopperThieving.py:150 flatcamTools/ToolNCC.py:562 +#: flatcamTools/ToolPaint.py:506 msgid "Ref. Object" msgstr "Obiect Ref" -#: flatcamTools/ToolCopperThieving.py:153 -#: flatcamTools/ToolNonCopperClear.py:458 flatcamTools/ToolPaint.py:339 +#: flatcamTools/ToolCopperThieving.py:152 flatcamTools/ToolNCC.py:564 +#: flatcamTools/ToolPaint.py:508 msgid "The FlatCAM object to be used as non copper clearing reference." msgstr "" "Obiectul FlatCAM pentru a fi utilizat ca referință pt. curățarea de cupru." -#: flatcamTools/ToolCopperThieving.py:326 +#: flatcamTools/ToolCopperThieving.py:328 msgid "Insert Copper thieving" msgstr "Inserați Copper Thieving" -#: flatcamTools/ToolCopperThieving.py:328 +#: flatcamTools/ToolCopperThieving.py:330 msgid "" "Will add a polygon (may be split in multiple parts)\n" "that will surround the actual Gerber traces at a certain distance." @@ -13495,11 +14252,11 @@ msgstr "" "Se va adăuga un poligon (poate fi împărțit în mai multe părți)\n" "care va înconjura traseele Gerber la o anumită distanță." -#: flatcamTools/ToolCopperThieving.py:387 +#: flatcamTools/ToolCopperThieving.py:389 msgid "Insert Robber Bar" msgstr "Inserați Rober Bar" -#: flatcamTools/ToolCopperThieving.py:389 +#: flatcamTools/ToolCopperThieving.py:391 msgid "" "Will add a polygon with a defined thickness\n" "that will surround the actual Gerber object\n" @@ -13511,11 +14268,11 @@ msgstr "" "la o anumită distanță.\n" "Necesar atunci când faceți placare găuri cu model." -#: flatcamTools/ToolCopperThieving.py:413 +#: flatcamTools/ToolCopperThieving.py:415 msgid "Select Soldermask object" msgstr "Selectați obiectul Soldermask" -#: flatcamTools/ToolCopperThieving.py:415 +#: flatcamTools/ToolCopperThieving.py:417 msgid "" "Gerber Object with the soldermask.\n" "It will be used as a base for\n" @@ -13525,11 +14282,11 @@ msgstr "" "Acesta va fi folosit ca bază pentru\n" "generarea de masca pentru placare cu model." -#: flatcamTools/ToolCopperThieving.py:443 +#: flatcamTools/ToolCopperThieving.py:446 msgid "Plated area" msgstr "Zona placată" -#: flatcamTools/ToolCopperThieving.py:445 +#: flatcamTools/ToolCopperThieving.py:448 msgid "" "The area to be plated by pattern plating.\n" "Basically is made from the openings in the plating mask.\n" @@ -13547,19 +14304,19 @@ msgstr "" "un pic mai mari decât padurile de cupru, iar această zonă este\n" "calculată din deschiderile soldermask." -#: flatcamTools/ToolCopperThieving.py:456 +#: flatcamTools/ToolCopperThieving.py:459 msgid "mm" msgstr "mm" -#: flatcamTools/ToolCopperThieving.py:458 +#: flatcamTools/ToolCopperThieving.py:461 msgid "in" msgstr "in" -#: flatcamTools/ToolCopperThieving.py:465 +#: flatcamTools/ToolCopperThieving.py:468 msgid "Generate pattern plating mask" msgstr "Generați mască de placare cu model" -#: flatcamTools/ToolCopperThieving.py:467 +#: flatcamTools/ToolCopperThieving.py:470 msgid "" "Will add to the soldermask gerber geometry\n" "the geometries of the copper thieving and/or\n" @@ -13569,136 +14326,137 @@ msgstr "" "geometriile Copper Thieving și / sau\n" "Robber Bar dacă acestea au fost generate." -#: flatcamTools/ToolCopperThieving.py:620 -#: flatcamTools/ToolCopperThieving.py:645 +#: flatcamTools/ToolCopperThieving.py:626 +#: flatcamTools/ToolCopperThieving.py:651 msgid "Lines Grid works only for 'itself' reference ..." msgstr "Gridul de Linii funcționează numai pentru referința „în sine” ..." -#: flatcamTools/ToolCopperThieving.py:631 +#: flatcamTools/ToolCopperThieving.py:637 msgid "Solid fill selected." msgstr "Umplere solidă selectată." -#: flatcamTools/ToolCopperThieving.py:636 +#: flatcamTools/ToolCopperThieving.py:642 msgid "Dots grid fill selected." msgstr "Umplere Grila de Puncte selectată." -#: flatcamTools/ToolCopperThieving.py:641 +#: flatcamTools/ToolCopperThieving.py:647 msgid "Squares grid fill selected." msgstr "Umplere Grila de Pătrate selectată." -#: flatcamTools/ToolCopperThieving.py:662 -#: flatcamTools/ToolCopperThieving.py:744 -#: flatcamTools/ToolCopperThieving.py:1340 flatcamTools/ToolDblSided.py:564 -#: flatcamTools/ToolFiducials.py:464 flatcamTools/ToolFiducials.py:741 -#: flatcamTools/ToolOptimal.py:342 flatcamTools/ToolQRCode.py:424 +#: flatcamTools/ToolCopperThieving.py:668 +#: flatcamTools/ToolCopperThieving.py:750 +#: flatcamTools/ToolCopperThieving.py:1346 flatcamTools/ToolDblSided.py:658 +#: flatcamTools/ToolExtractDrills.py:436 flatcamTools/ToolFiducials.py:466 +#: flatcamTools/ToolFiducials.py:743 flatcamTools/ToolOptimal.py:343 +#: flatcamTools/ToolPunchGerber.py:512 flatcamTools/ToolQRCode.py:426 msgid "There is no Gerber object loaded ..." msgstr "Nu este nici-un obiect Gerber incărcat ..." -#: flatcamTools/ToolCopperThieving.py:675 -#: flatcamTools/ToolCopperThieving.py:1268 +#: flatcamTools/ToolCopperThieving.py:681 +#: flatcamTools/ToolCopperThieving.py:1274 msgid "Append geometry" msgstr "Adăugați geometria" -#: flatcamTools/ToolCopperThieving.py:719 -#: flatcamTools/ToolCopperThieving.py:1301 -#: flatcamTools/ToolCopperThieving.py:1454 +#: flatcamTools/ToolCopperThieving.py:725 +#: flatcamTools/ToolCopperThieving.py:1307 +#: flatcamTools/ToolCopperThieving.py:1460 msgid "Append source file" msgstr "Adăugați fișierul sursă" -#: flatcamTools/ToolCopperThieving.py:727 -#: flatcamTools/ToolCopperThieving.py:1309 +#: flatcamTools/ToolCopperThieving.py:733 +#: flatcamTools/ToolCopperThieving.py:1315 msgid "Copper Thieving Tool done." msgstr "Unealta Copper Thieving efectuata." -#: flatcamTools/ToolCopperThieving.py:754 -#: flatcamTools/ToolCopperThieving.py:787 flatcamTools/ToolCutOut.py:468 -#: flatcamTools/ToolCutOut.py:642 flatcamTools/ToolNonCopperClear.py:1151 -#: flatcamTools/ToolNonCopperClear.py:1192 -#: flatcamTools/ToolNonCopperClear.py:1224 flatcamTools/ToolPaint.py:1074 -#: flatcamTools/ToolPanelize.py:401 flatcamTools/ToolPanelize.py:416 -#: flatcamTools/ToolSub.py:288 flatcamTools/ToolSub.py:301 -#: flatcamTools/ToolSub.py:492 flatcamTools/ToolSub.py:507 -#: tclCommands/TclCommandCopperClear.py:97 -#: tclCommands/TclCommandCopperClear.py:146 tclCommands/TclCommandPaint.py:97 +#: flatcamTools/ToolCopperThieving.py:760 +#: flatcamTools/ToolCopperThieving.py:793 flatcamTools/ToolCutOut.py:480 +#: flatcamTools/ToolCutOut.py:667 flatcamTools/ToolInvertGerber.py:208 +#: flatcamTools/ToolNCC.py:1603 flatcamTools/ToolNCC.py:1644 +#: flatcamTools/ToolNCC.py:1673 flatcamTools/ToolPaint.py:1462 +#: flatcamTools/ToolPanelize.py:413 flatcamTools/ToolPanelize.py:428 +#: flatcamTools/ToolSub.py:294 flatcamTools/ToolSub.py:307 +#: flatcamTools/ToolSub.py:498 flatcamTools/ToolSub.py:513 +#: tclCommands/TclCommandCopperClear.py:97 tclCommands/TclCommandPaint.py:99 msgid "Could not retrieve object" msgstr "Nu s-a putut incărca obiectul" -#: flatcamTools/ToolCopperThieving.py:764 -#: flatcamTools/ToolNonCopperClear.py:1205 +#: flatcamTools/ToolCopperThieving.py:770 flatcamTools/ToolNCC.py:1652 msgid "Click the start point of the area." msgstr "Faceți clic pe punctul de pornire al zonei." -#: flatcamTools/ToolCopperThieving.py:815 +#: flatcamTools/ToolCopperThieving.py:821 msgid "Click the end point of the filling area." msgstr "Faceți clic pe punctul final al zonei de umplere." -#: flatcamTools/ToolCopperThieving.py:821 -#: flatcamTools/ToolNonCopperClear.py:1261 flatcamTools/ToolPaint.py:1201 +#: flatcamTools/ToolCopperThieving.py:827 flatcamTools/ToolNCC.py:1714 +#: flatcamTools/ToolNCC.py:1766 flatcamTools/ToolPaint.py:1594 +#: flatcamTools/ToolPaint.py:1645 msgid "Zone added. Click to start adding next zone or right click to finish." msgstr "" "Zona adăugată. Faceți clic stanga pt a continua adăugarea de zone sau click " "dreapta pentru a termina." -#: flatcamTools/ToolCopperThieving.py:937 -#: flatcamTools/ToolCopperThieving.py:941 -#: flatcamTools/ToolCopperThieving.py:1002 +#: flatcamTools/ToolCopperThieving.py:943 +#: flatcamTools/ToolCopperThieving.py:947 +#: flatcamTools/ToolCopperThieving.py:1008 msgid "Thieving" msgstr "Thieving" -#: flatcamTools/ToolCopperThieving.py:948 +#: flatcamTools/ToolCopperThieving.py:954 msgid "Copper Thieving Tool started. Reading parameters." msgstr "Unealta Thieving Tool a pornit. Se citesc parametrii." -#: flatcamTools/ToolCopperThieving.py:973 +#: flatcamTools/ToolCopperThieving.py:979 msgid "Copper Thieving Tool. Preparing isolation polygons." msgstr "Unealta Thieving Tool. Se pregătesc poligoanele de isolare." -#: flatcamTools/ToolCopperThieving.py:1018 +#: flatcamTools/ToolCopperThieving.py:1024 msgid "Copper Thieving Tool. Preparing areas to fill with copper." msgstr "Unealta Thieving Tool. Se pregătesc zonele de umplut cu cupru." -#: flatcamTools/ToolCopperThieving.py:1029 flatcamTools/ToolOptimal.py:349 -#: flatcamTools/ToolPanelize.py:793 flatcamTools/ToolRulesCheck.py:1118 +#: flatcamTools/ToolCopperThieving.py:1035 flatcamTools/ToolOptimal.py:350 +#: flatcamTools/ToolPanelize.py:802 flatcamTools/ToolRulesCheck.py:1127 msgid "Working..." msgstr "Se lucrează..." -#: flatcamTools/ToolCopperThieving.py:1056 +#: flatcamTools/ToolCopperThieving.py:1062 msgid "Geometry not supported for bounding box" msgstr "Geometria nu este acceptată pentru caseta de delimitare" -#: flatcamTools/ToolCopperThieving.py:1062 -#: flatcamTools/ToolNonCopperClear.py:1513 flatcamTools/ToolPaint.py:2673 +#: flatcamTools/ToolCopperThieving.py:1068 flatcamTools/ToolNCC.py:1933 +#: flatcamTools/ToolNCC.py:1988 flatcamTools/ToolNCC.py:2992 +#: flatcamTools/ToolPaint.py:3854 msgid "No object available." msgstr "Nici-un obiect disponibil." -#: flatcamTools/ToolCopperThieving.py:1099 -#: flatcamTools/ToolNonCopperClear.py:1555 +#: flatcamTools/ToolCopperThieving.py:1105 flatcamTools/ToolNCC.py:1958 +#: flatcamTools/ToolNCC.py:2011 flatcamTools/ToolNCC.py:3034 msgid "The reference object type is not supported." msgstr "Tipul de obiect de referintă nu este acceptat." -#: flatcamTools/ToolCopperThieving.py:1104 +#: flatcamTools/ToolCopperThieving.py:1110 msgid "Copper Thieving Tool. Appending new geometry and buffering." msgstr "" "Unealta Copper Thieving. Se adauga o noua geometrie si se fuzioneaza acestea." -#: flatcamTools/ToolCopperThieving.py:1120 +#: flatcamTools/ToolCopperThieving.py:1126 msgid "Create geometry" msgstr "Creați geometrie" -#: flatcamTools/ToolCopperThieving.py:1320 -#: flatcamTools/ToolCopperThieving.py:1324 +#: flatcamTools/ToolCopperThieving.py:1326 +#: flatcamTools/ToolCopperThieving.py:1330 msgid "P-Plating Mask" msgstr "Mască M-Placare" -#: flatcamTools/ToolCopperThieving.py:1346 +#: flatcamTools/ToolCopperThieving.py:1352 msgid "Append PP-M geometry" msgstr "Adaugă geometrie mască PM" -#: flatcamTools/ToolCopperThieving.py:1472 +#: flatcamTools/ToolCopperThieving.py:1478 msgid "Generating Pattern Plating Mask done." msgstr "Generarea măștii de placare cu model efectuată." -#: flatcamTools/ToolCopperThieving.py:1544 +#: flatcamTools/ToolCopperThieving.py:1550 msgid "Copper Thieving Tool exit." msgstr "Unealta Copper Thieving terminata." @@ -13706,7 +14464,19 @@ msgstr "Unealta Copper Thieving terminata." msgid "Cutout PCB" msgstr "Decupare PCB" -#: flatcamTools/ToolCutOut.py:82 +#: flatcamTools/ToolCutOut.py:70 flatcamTools/ToolPanelize.py:54 +msgid "Source Object" +msgstr "Obiect Sursă" + +#: flatcamTools/ToolCutOut.py:71 +msgid "Object to be cutout" +msgstr "Obiect care trebuie decupat" + +#: flatcamTools/ToolCutOut.py:76 +msgid "Kind" +msgstr "Fel" + +#: flatcamTools/ToolCutOut.py:98 msgid "" "Specify the type of object to be cutout.\n" "It can be of type: Gerber or Geometry.\n" @@ -13719,21 +14489,21 @@ msgstr "" "obiecte care vor aparea in combobox-ul\n" "numit >Obiect<." -#: flatcamTools/ToolCutOut.py:91 flatcamTools/ToolCutOut.py:92 -msgid "Object to be cutout" -msgstr "Obiect care trebuie decupat" +#: flatcamTools/ToolCutOut.py:122 +msgid "Tool Parameters" +msgstr "Parametrii Unealtă" -#: flatcamTools/ToolCutOut.py:230 +#: flatcamTools/ToolCutOut.py:239 msgid "A. Automatic Bridge Gaps" msgstr "A. Punţi realiz. automat" -#: flatcamTools/ToolCutOut.py:232 +#: flatcamTools/ToolCutOut.py:241 msgid "This section handle creation of automatic bridge gaps." msgstr "" "Aceasta sectiune va permite crearea in mod automat\n" "a pana la 8 punţi." -#: flatcamTools/ToolCutOut.py:243 +#: flatcamTools/ToolCutOut.py:252 msgid "" "Number of gaps used for the Automatic cutout.\n" "There can be maximum 8 bridges/gaps.\n" @@ -13757,11 +14527,11 @@ msgstr "" "- 2tb = 2* sus - 2* jos\n" "- 8 = 2* stânga - 2* dreapta - 2* sus - 2* jos" -#: flatcamTools/ToolCutOut.py:264 +#: flatcamTools/ToolCutOut.py:273 msgid "Generate Freeform Geometry" msgstr "Generați geometrie cu formă liberă" -#: flatcamTools/ToolCutOut.py:266 +#: flatcamTools/ToolCutOut.py:275 msgid "" "Cutout the selected object.\n" "The cutout shape can be of any shape.\n" @@ -13771,11 +14541,11 @@ msgstr "" "Forma decupajului poate avea orice forma.\n" "Folositor când PCB-ul are o forma neregulata." -#: flatcamTools/ToolCutOut.py:278 +#: flatcamTools/ToolCutOut.py:287 msgid "Generate Rectangular Geometry" msgstr "Generați geometrie dreptunghiulară" -#: flatcamTools/ToolCutOut.py:280 +#: flatcamTools/ToolCutOut.py:289 msgid "" "Cutout the selected object.\n" "The resulting cutout shape is\n" @@ -13785,11 +14555,11 @@ msgstr "" "Decupează obiectul selectat.\n" "Forma decupajului este tot timpul dreptunghiulara.." -#: flatcamTools/ToolCutOut.py:299 +#: flatcamTools/ToolCutOut.py:308 msgid "B. Manual Bridge Gaps" msgstr "B. Punţi realiz. manual" -#: flatcamTools/ToolCutOut.py:301 +#: flatcamTools/ToolCutOut.py:310 msgid "" "This section handle creation of manual bridge gaps.\n" "This is done by mouse clicking on the perimeter of the\n" @@ -13801,15 +14571,15 @@ msgstr "" "apasarea tastei CTRL, operatia se va repeta automat pana când\n" "se va apasa tasta 'Escape'. " -#: flatcamTools/ToolCutOut.py:319 +#: flatcamTools/ToolCutOut.py:329 msgid "Geometry object used to create the manual cutout." msgstr "Obiect tip Geometrie folosit pentru crearea decupajului manual." -#: flatcamTools/ToolCutOut.py:328 +#: flatcamTools/ToolCutOut.py:338 msgid "Generate Manual Geometry" msgstr "Generați geometrie manuală" -#: flatcamTools/ToolCutOut.py:330 +#: flatcamTools/ToolCutOut.py:340 msgid "" "If the object to be cutout is a Gerber\n" "first create a Geometry that surrounds it,\n" @@ -13822,11 +14592,11 @@ msgstr "" "Selectează obiectul sursa Gerber in combobox-ul de mai sus,\n" "numit >Obiect<." -#: flatcamTools/ToolCutOut.py:343 +#: flatcamTools/ToolCutOut.py:353 msgid "Manual Add Bridge Gaps" msgstr "Adaugă punţi manual" -#: flatcamTools/ToolCutOut.py:345 +#: flatcamTools/ToolCutOut.py:355 msgid "" "Use the left mouse button (LMB) click\n" "to create a bridge gap to separate the PCB from\n" @@ -13840,7 +14610,7 @@ msgstr "" "apasarea tastei CTRL, operatia se va repeta automat pana când\n" "se va apasa tasta 'Escape'." -#: flatcamTools/ToolCutOut.py:473 +#: flatcamTools/ToolCutOut.py:485 msgid "" "There is no object selected for Cutout.\n" "Select one and try again." @@ -13848,18 +14618,19 @@ msgstr "" "Nu este nici-un obiect selectat pentru decupaj.\n" "Selectează unul și încearcă din nou." -#: flatcamTools/ToolCutOut.py:479 flatcamTools/ToolCutOut.py:651 -#: flatcamTools/ToolCutOut.py:795 flatcamTools/ToolCutOut.py:877 +#: flatcamTools/ToolCutOut.py:491 flatcamTools/ToolCutOut.py:676 +#: flatcamTools/ToolCutOut.py:839 flatcamTools/ToolCutOut.py:921 +#: tclCommands/TclCommandGeoCutout.py:185 msgid "Tool Diameter is zero value. Change it to a positive real number." msgstr "Diametrul uneltei este zero. Schimbă intr-o valoare pozitivă Reală." -#: flatcamTools/ToolCutOut.py:493 flatcamTools/ToolCutOut.py:666 +#: flatcamTools/ToolCutOut.py:505 flatcamTools/ToolCutOut.py:691 msgid "Number of gaps value is missing. Add it and retry." msgstr "" "Numărul de punţi lipseste sau este in format gresit. Adaugă din nou și " "reîncearcă." -#: flatcamTools/ToolCutOut.py:498 flatcamTools/ToolCutOut.py:670 +#: flatcamTools/ToolCutOut.py:510 flatcamTools/ToolCutOut.py:695 msgid "" "Gaps value can be only one of: 'None', 'lr', 'tb', '2lr', '2tb', 4 or 8. " "Fill in a correct value and retry. " @@ -13867,7 +14638,7 @@ msgstr "" "Valoarea spatiilor poate fi doar una dintre: „Niciuna”, „lr”, „tb”, „2lr”, " "„2tb”, 4 sau 8. Completați o valoare corectă și încercați din nou. " -#: flatcamTools/ToolCutOut.py:503 flatcamTools/ToolCutOut.py:676 +#: flatcamTools/ToolCutOut.py:515 flatcamTools/ToolCutOut.py:701 msgid "" "Cutout operation cannot be done on a multi-geo Geometry.\n" "Optionally, this Multi-geo Geometry can be converted to Single-geo " @@ -13879,40 +14650,45 @@ msgstr "" "Se poate insa converti MultiGeo in tip SingleGeo și apoi se poate efectua " "decupajul." -#: flatcamTools/ToolCutOut.py:625 flatcamTools/ToolCutOut.py:784 +#: flatcamTools/ToolCutOut.py:650 flatcamTools/ToolCutOut.py:828 msgid "Any form CutOut operation finished." msgstr "Operatia de decupaj cu formă liberă s-a terminat." -#: flatcamTools/ToolCutOut.py:646 flatcamTools/ToolNonCopperClear.py:1155 -#: flatcamTools/ToolPaint.py:994 flatcamTools/ToolPanelize.py:406 -#: tclCommands/TclCommandBbox.py:70 tclCommands/TclCommandNregions.py:70 +#: flatcamTools/ToolCutOut.py:671 flatcamTools/ToolInvertGerber.py:214 +#: flatcamTools/ToolNCC.py:1607 flatcamTools/ToolPaint.py:1385 +#: flatcamTools/ToolPanelize.py:418 tclCommands/TclCommandBbox.py:72 +#: tclCommands/TclCommandNregions.py:72 msgid "Object not found" msgstr "Obiectul nu a fost gasit" -#: flatcamTools/ToolCutOut.py:789 +#: flatcamTools/ToolCutOut.py:814 +msgid "Rectangular cutout with negative margin is not possible." +msgstr "Tăierea rectangulară cu marginea negativă nu este posibilă." + +#: flatcamTools/ToolCutOut.py:833 msgid "" "Click on the selected geometry object perimeter to create a bridge gap ..." msgstr "" "Click pe perimetrul obiectului tip Geometrie selectat\n" "pentru a crea o punte separatoare." -#: flatcamTools/ToolCutOut.py:806 flatcamTools/ToolCutOut.py:832 +#: flatcamTools/ToolCutOut.py:850 flatcamTools/ToolCutOut.py:876 msgid "Could not retrieve Geometry object" msgstr "Nu s-a putut incărca obiectul Geometrie" -#: flatcamTools/ToolCutOut.py:837 +#: flatcamTools/ToolCutOut.py:881 msgid "Geometry object for manual cutout not found" msgstr "Obiectul Geometrie pentru decupaj manual nu este găsit" -#: flatcamTools/ToolCutOut.py:847 +#: flatcamTools/ToolCutOut.py:891 msgid "Added manual Bridge Gap." msgstr "O punte a fost adăugată in mod manual." -#: flatcamTools/ToolCutOut.py:859 +#: flatcamTools/ToolCutOut.py:903 msgid "Could not retrieve Gerber object" msgstr "Nu s-a putut incărca obiectul Gerber" -#: flatcamTools/ToolCutOut.py:864 +#: flatcamTools/ToolCutOut.py:908 msgid "" "There is no Gerber object selected for Cutout.\n" "Select one and try again." @@ -13920,7 +14696,7 @@ msgstr "" "Nu există obiect selectat pt operatia de decupare.\n" "Selectează un obiect si incearcă din nou." -#: flatcamTools/ToolCutOut.py:870 +#: flatcamTools/ToolCutOut.py:914 msgid "" "The selected object has to be of Gerber type.\n" "Select a Gerber file and try again." @@ -13928,11 +14704,11 @@ msgstr "" "Obiectul selectat trebuie să fie de tip Gerber.\n" "Selectează un obiect Gerber si incearcă din nou." -#: flatcamTools/ToolCutOut.py:905 +#: flatcamTools/ToolCutOut.py:949 msgid "Geometry not supported for cutout" msgstr "Geometria nu este acceptată pentru decupaj" -#: flatcamTools/ToolCutOut.py:960 +#: flatcamTools/ToolCutOut.py:1007 msgid "Making manual bridge gap..." msgstr "Se generează o punte separatoare in mod manual..." @@ -13940,12 +14716,20 @@ msgstr "Se generează o punte separatoare in mod manual..." msgid "2-Sided PCB" msgstr "2-fețe PCB" -#: flatcamTools/ToolDblSided.py:60 +#: flatcamTools/ToolDblSided.py:53 +msgid "Mirror Operation" +msgstr "Operațiune Oglindire" + +#: flatcamTools/ToolDblSided.py:54 +msgid "Objects to be mirrored" +msgstr "Obiecte care vor fi Oglindite" + +#: flatcamTools/ToolDblSided.py:66 msgid "Gerber to be mirrored" msgstr "Gerber pentru oglindit" -#: flatcamTools/ToolDblSided.py:64 flatcamTools/ToolDblSided.py:92 -#: flatcamTools/ToolDblSided.py:122 +#: flatcamTools/ToolDblSided.py:70 flatcamTools/ToolDblSided.py:98 +#: flatcamTools/ToolDblSided.py:128 msgid "" "Mirrors (flips) the specified object around \n" "the specified axis. Does not create a new \n" @@ -13954,73 +14738,193 @@ msgstr "" "Oglindește obiectul specificat pe axa specificata.\n" "Nu crează un obiect nou ci il modifica." -#: flatcamTools/ToolDblSided.py:88 +#: flatcamTools/ToolDblSided.py:94 msgid "Excellon Object to be mirrored." msgstr "Obiectul Excellon care va fi oglindit." -#: flatcamTools/ToolDblSided.py:117 +#: flatcamTools/ToolDblSided.py:123 msgid "Geometry Obj to be mirrored." msgstr "Obiectul Geometrie care va fi oglindit." -#: flatcamTools/ToolDblSided.py:179 -msgid "Point/Box Reference" -msgstr "Referință Punct/Container" +#: flatcamTools/ToolDblSided.py:159 +msgid "Mirror Parameters" +msgstr "Parametrii Oglindire" -#: flatcamTools/ToolDblSided.py:181 +#: flatcamTools/ToolDblSided.py:160 +msgid "Parameters for the mirror operation" +msgstr "Parametri pt operația de Oglindire" + +#: flatcamTools/ToolDblSided.py:165 +msgid "Mirror Axis" +msgstr "Axa Oglindire" + +#: flatcamTools/ToolDblSided.py:176 msgid "" -"If 'Point' is selected above it store the coordinates (x, y) through which\n" -"the mirroring axis passes.\n" -"If 'Box' is selected above, select here a FlatCAM object (Gerber, Exc or " -"Geo).\n" -"Through the center of this object pass the mirroring axis selected above." +"The coordinates used as reference for the mirror operation.\n" +"Can be:\n" +"- Point -> a set of coordinates (x,y) around which the object is mirrored\n" +"- Box -> a set of coordinates (x, y) obtained from the center of the\n" +"bounding box of another object selected below" msgstr "" -"Daca 'Punct' este selectat mai sus, atunci va stoca coordonatele (x,y) prin " -"care\n" -"axa de oglindire trece.\n" -"Daca 'Container' este selectat mai sus atunci va fi disponibila aici o lista " -"de obiecte\n" -"FlatCAM: Gerber, Excellon sau Geometrie. Prin mijocul geometric al acestor " -"obiecte\n" -"va trece axa de oglindire selectată mai sus." +"Coordinatele folosite ca referintă pentru operatia de Oglindire.\n" +"Pot fi:\n" +"- Punct -> un set de coordinate (x,y) in jurul cărora se va face oglindirea\n" +"- Cuie -> un set de coordinate (x,y) obtinute din centrul formei " +"inconjurătoare\n" +"al unui alt obiect, selectat mai jos" -#: flatcamTools/ToolDblSided.py:189 +#: flatcamTools/ToolDblSided.py:190 +msgid "Point coordinates" +msgstr "Coordonatele Punct" + +#: flatcamTools/ToolDblSided.py:195 msgid "" "Add the coordinates in format (x, y) through which the mirroring " "axis \n" " selected in 'MIRROR AXIS' pass.\n" "The (x, y) coordinates are captured by pressing SHIFT key\n" -"and left mouse button click on canvas or you can enter the coords manually." +"and left mouse button click on canvas or you can enter the coordinates " +"manually." msgstr "" -"Adaugă coordonatele in formatul (x, y) ale punctului prin care trece\n" -"axa de oglindire selectată mai sus.\n" +"Adaugă coordonatele in formatul (x, y) prin care trece\n" +"axa de oglindire selectată mai sus, in pasul 'AXA OGLINDIRE'.\n" "Coordonatele (x,y) pot fi obtinute prin combinatia tasta SHIFT + click mouse " "pe\n" -"canvas sau le puteti introduce manual." +"suprafata de afisare sau le puteti introduce manual." -#: flatcamTools/ToolDblSided.py:230 +#: flatcamTools/ToolDblSided.py:219 +msgid "" +"It can be of type: Gerber or Excellon or Geometry.\n" +"The coordinates of the center of the bounding box are used\n" +"as reference for mirror operation." +msgstr "" +"Poate fi de tipul: Gerber, Excellon sau Geometrie.\n" +"Coordonatele centrului formei inconjurătoare sunt folosite\n" +"ca si referintă pentru operatiunea de Oglindire." + +#: flatcamTools/ToolDblSided.py:253 +msgid "Bounds Values" +msgstr "Valorile Limitelor" + +#: flatcamTools/ToolDblSided.py:255 +msgid "" +"Select on canvas the object(s)\n" +"for which to calculate bounds values." +msgstr "" +"Selectati pe suprafata de afisare obiectul(e)\n" +"pentru care se calculează valorile limitelor." + +#: flatcamTools/ToolDblSided.py:265 +msgid "X min" +msgstr "X min" + +#: flatcamTools/ToolDblSided.py:267 flatcamTools/ToolDblSided.py:281 +msgid "Minimum location." +msgstr "Locație minimă." + +#: flatcamTools/ToolDblSided.py:279 +msgid "Y min" +msgstr "Y min" + +#: flatcamTools/ToolDblSided.py:293 +msgid "X max" +msgstr "X max" + +#: flatcamTools/ToolDblSided.py:295 flatcamTools/ToolDblSided.py:309 +msgid "Maximum location." +msgstr "Locație maximă." + +#: flatcamTools/ToolDblSided.py:307 +msgid "Y max" +msgstr "Y max" + +#: flatcamTools/ToolDblSided.py:318 +msgid "Center point coordinates" +msgstr "Coordonatele punctului central" + +#: flatcamTools/ToolDblSided.py:320 +msgid "Centroid" +msgstr "Centroid" + +#: flatcamTools/ToolDblSided.py:322 +msgid "" +"The center point location for the rectangular\n" +"bounding shape. Centroid. Format is (x, y)." +msgstr "" +"Locația punctului central pentru dreptunghiul\n" +"formă de delimitare. Centroid. Formatul este (x, y)." + +#: flatcamTools/ToolDblSided.py:331 +msgid "Calculate Bounds Values" +msgstr "Calculați valorile limitelor" + +#: flatcamTools/ToolDblSided.py:333 +msgid "" +"Calculate the enveloping rectangular shape coordinates,\n" +"for the selection of objects.\n" +"The envelope shape is parallel with the X, Y axis." +msgstr "" +"Calculați coordonatele pt forma dreptunghiulară învelitoare,\n" +"pentru selectarea obiectelor.\n" +"Forma este paralelă cu axele X, Y." + +#: flatcamTools/ToolDblSided.py:353 +msgid "PCB Alignment" +msgstr "Aliniere PCB" + +#: flatcamTools/ToolDblSided.py:355 flatcamTools/ToolDblSided.py:457 +msgid "" +"Creates an Excellon Object containing the\n" +"specified alignment holes and their mirror\n" +"images." +msgstr "" +"Crează un obiect Excellon care contine găurile\n" +"de aliniere specificate cat și cele in oglinda." + +#: flatcamTools/ToolDblSided.py:362 +msgid "Drill Diameter" +msgstr "Dia Găurire" + +#: flatcamTools/ToolDblSided.py:391 flatcamTools/ToolDblSided.py:398 +msgid "" +"The reference point used to create the second alignment drill\n" +"from the first alignment drill, by doing mirror.\n" +"It can be modified in the Mirror Parameters -> Reference section" +msgstr "" +"Punctul de referintă folosit pentru crearea găurii de aliniere secundară,\n" +"din prima gaură de aliniere prin oglindire.\n" +"Poate fi modificat in Parametri Oglindire -> Sectiunea Referintă" + +#: flatcamTools/ToolDblSided.py:411 msgid "Alignment Drill Coordinates" msgstr "Dia. găuri de aliniere" -#: flatcamTools/ToolDblSided.py:232 +#: flatcamTools/ToolDblSided.py:413 msgid "" "Alignment holes (x1, y1), (x2, y2), ... on one side of the mirror axis. For " "each set of (x, y) coordinates\n" "entered here, a pair of drills will be created:\n" "\n" "- one drill at the coordinates from the field\n" -"- one drill in mirror position over the axis selected above in the 'Mirror " +"- one drill in mirror position over the axis selected above in the 'Align " "Axis'." msgstr "" "Găuri de aliniere in formatul unei liste: (x1, y1), (x2, y2) samd.\n" "Pentru fiecare punct din lista de mai sus (cu coord. (x,y) )\n" -"un alt punct va fi creat in oglinda.\n" -"- un punct cu coord. specificate\n" -"- un punct cu coord. in poziţia oglindita pe axa selectată mai sus." +"vor fi create o pereche de găuri:\n" +"- o gaură cu coord. specificate in campul de editare\n" +"- o gaură cu coord. in poziţia oglindită pe axa selectată mai sus in 'Axa " +"Aliniere'." -#: flatcamTools/ToolDblSided.py:247 +#: flatcamTools/ToolDblSided.py:421 +msgid "Drill coordinates" +msgstr "Coordonatele găuri" + +#: flatcamTools/ToolDblSided.py:428 msgid "" -"Add alignment drill holes coords in the format: (x1, y1), (x2, y2), ... \n" -"on one side of the mirror axis.\n" +"Add alignment drill holes coordinates in the format: (x1, y1), (x2, " +"y2), ... \n" +"on one side of the alignment axis.\n" "\n" "The coordinates set can be obtained:\n" "- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" @@ -14033,86 +14937,31 @@ msgstr "" "Adăugă coordonatele pt găurile de aliniere in formatul: (x1,y1), (x2,y2) " "samd\n" "\n" -"Coordonatele pot fi obtinute prin urmatoarele metoda:\n" -"- apasare tasta SHIFT + click mouse pe canvas. Apoi apasa butonul 'Adaugă'.\n" -"- apasare tasta SHIFT + click mouse pe canvas. Apoi CTRL + V combo in câmpul " +"Coordonatele pot fi obtinute prin urmatoarele metodă:\n" +"- apăsare tasta SHIFT + click mouse pe canvas. Apoi apasa butonul 'Adaugă'.\n" +"- apăsare tasta SHIFT + click mouse pe canvas. Apoi CTRL + V combo in câmpul " "de editare\n" -"- apasare tasta SHIFT + click mouse pe canvas. Apoi click dreapta și Paste " +"- apăsare tasta SHIFT + click mouse pe canvas. Apoi click dreapta și Paste " "in câmpul de edit.\n" -"- se intorduc manual in formatul (x1,y1), (x2,y2) ..." +"- se introduc manual in formatul (x1,y1), (x2,y2) ..." -#: flatcamTools/ToolDblSided.py:272 -msgid "Alignment Drill Diameter" -msgstr "Dia. găuri de aliniere" +#: flatcamTools/ToolDblSided.py:443 +msgid "Delete Last" +msgstr "Șterge Ultima" -#: flatcamTools/ToolDblSided.py:292 +#: flatcamTools/ToolDblSided.py:445 +msgid "Delete the last coordinates tuple in the list." +msgstr "Șterge ultimul set de coordinate din listă." + +#: flatcamTools/ToolDblSided.py:455 msgid "Create Excellon Object" msgstr "Crează un obiect Excellon" -#: flatcamTools/ToolDblSided.py:294 -msgid "" -"Creates an Excellon Object containing the\n" -"specified alignment holes and their mirror\n" -"images." -msgstr "" -"Crează un obiect Excellon care contine găurile\n" -"de aliniere specificate cat și cele in oglinda." - -#: flatcamTools/ToolDblSided.py:323 -msgid "X min" -msgstr "X min" - -#: flatcamTools/ToolDblSided.py:325 flatcamTools/ToolDblSided.py:339 -msgid "Minimum location." -msgstr "Locație minimă." - -#: flatcamTools/ToolDblSided.py:337 -msgid "Y min" -msgstr "Y min" - -#: flatcamTools/ToolDblSided.py:351 -msgid "X max" -msgstr "X max" - -#: flatcamTools/ToolDblSided.py:353 flatcamTools/ToolDblSided.py:367 -msgid "Maximum location." -msgstr "Locație maximă." - -#: flatcamTools/ToolDblSided.py:365 -msgid "Y max" -msgstr "Y max" - -#: flatcamTools/ToolDblSided.py:377 -msgid "Centroid" -msgstr "Centroid" - -#: flatcamTools/ToolDblSided.py:379 -msgid "" -"The center point location for the rectangular\n" -"bounding shape. Centroid. Format is (x, y)." -msgstr "" -"Locația punctului central pentru dreptunghiul\n" -"formă de delimitare. Centroid. Formatul este (x, y)." - -#: flatcamTools/ToolDblSided.py:388 -msgid "Calculate Bounds Values" -msgstr "Calculați valorile limitelor" - -#: flatcamTools/ToolDblSided.py:390 -msgid "" -"Calculate the enveloping rectangular shape coordinates,\n" -"for the selection of objects.\n" -"The envelope shape is parallel with the X, Y axis." -msgstr "" -"Calculați coordonatele pt forma dreptunghiulară învelitoare,\n" -"pentru selectarea obiectelor.\n" -"Forma este paralelă cu axa X, Y" - -#: flatcamTools/ToolDblSided.py:462 +#: flatcamTools/ToolDblSided.py:542 msgid "2-Sided Tool" msgstr "Unealta 2-fețe" -#: flatcamTools/ToolDblSided.py:493 +#: flatcamTools/ToolDblSided.py:582 msgid "" "'Point' reference is selected and 'Point' coordinates are missing. Add them " "and retry." @@ -14120,151 +14969,170 @@ msgstr "" "Referința 'Punct' este selectată dar coordonatele sale lipsesc. Adăugă-le si " "încearcă din nou." -#: flatcamTools/ToolDblSided.py:512 +#: flatcamTools/ToolDblSided.py:601 msgid "There is no Box reference object loaded. Load one and retry." msgstr "" "Nici-un obiect container nu este incărcat. Încarcă unul și încearcă din nou." -#: flatcamTools/ToolDblSided.py:524 +#: flatcamTools/ToolDblSided.py:613 msgid "No value or wrong format in Drill Dia entry. Add it and retry." msgstr "" "Val. pt dia burghiu lipseste sau este in format gresit. Adaugă una și " "încearcă din nou." -#: flatcamTools/ToolDblSided.py:532 +#: flatcamTools/ToolDblSided.py:624 msgid "There are no Alignment Drill Coordinates to use. Add them and retry." msgstr "" "Nu exista coord. pentru găurile de aliniere. Adaugă-le și încearcă din nou." -#: flatcamTools/ToolDblSided.py:555 +#: flatcamTools/ToolDblSided.py:649 msgid "Excellon object with alignment drills created..." msgstr "Obiectul Excellon conținând găurile de aliniere a fost creat ..." -#: flatcamTools/ToolDblSided.py:568 flatcamTools/ToolDblSided.py:611 -#: flatcamTools/ToolDblSided.py:655 +#: flatcamTools/ToolDblSided.py:662 flatcamTools/ToolDblSided.py:705 +#: flatcamTools/ToolDblSided.py:749 msgid "Only Gerber, Excellon and Geometry objects can be mirrored." msgstr "Doar obiectele de tip Geometrie, Excellon și Gerber pot fi oglindite." -#: flatcamTools/ToolDblSided.py:578 -msgid "" -"'Point' coordinates missing. Using Origin (0, 0) as mirroring reference." -msgstr "" -"Coord. 'Punct'-ului lipsesc. Se folosesc coord. punctului Origine (0,0) ca " -"ref. pt oglindire." - -#: flatcamTools/ToolDblSided.py:588 flatcamTools/ToolDblSided.py:632 -#: flatcamTools/ToolDblSided.py:669 -msgid "There is no Box object loaded ..." -msgstr "Nu este incărcat nici-un obiect container ..." - -#: flatcamTools/ToolDblSided.py:598 flatcamTools/ToolDblSided.py:642 -#: flatcamTools/ToolDblSided.py:679 -msgid "was mirrored" -msgstr "a fost oglindit" - -#: flatcamTools/ToolDblSided.py:607 -msgid "There is no Excellon object loaded ..." -msgstr "Nici-un obiect tip Excellon nu este incărcat ..." - -#: flatcamTools/ToolDblSided.py:622 +#: flatcamTools/ToolDblSided.py:672 flatcamTools/ToolDblSided.py:716 msgid "" "There are no Point coordinates in the Point field. Add coords and try " "again ..." msgstr "" "Nu există coord. in câmpul 'Punct'. Adaugă coord. și încearcă din nou..." -#: flatcamTools/ToolDblSided.py:651 +#: flatcamTools/ToolDblSided.py:682 flatcamTools/ToolDblSided.py:726 +#: flatcamTools/ToolDblSided.py:763 +msgid "There is no Box object loaded ..." +msgstr "Nu este incărcat nici-un obiect container ..." + +#: flatcamTools/ToolDblSided.py:692 flatcamTools/ToolDblSided.py:736 +#: flatcamTools/ToolDblSided.py:773 +msgid "was mirrored" +msgstr "a fost oglindit" + +#: flatcamTools/ToolDblSided.py:701 flatcamTools/ToolPunchGerber.py:533 +msgid "There is no Excellon object loaded ..." +msgstr "Nici-un obiect tip Excellon nu este incărcat ..." + +#: flatcamTools/ToolDblSided.py:745 msgid "There is no Geometry object loaded ..." msgstr "Nici-un obiect tip Geometrie nu este incărcat ..." -#: flatcamTools/ToolDistance.py:50 flatcamTools/ToolDistanceMin.py:50 +#: flatcamTools/ToolDistance.py:57 flatcamTools/ToolDistanceMin.py:51 msgid "Those are the units in which the distance is measured." msgstr "Unitatile de masura in care se masoara distanța." -#: flatcamTools/ToolDistance.py:51 flatcamTools/ToolDistanceMin.py:51 +#: flatcamTools/ToolDistance.py:58 flatcamTools/ToolDistanceMin.py:52 msgid "METRIC (mm)" msgstr "Metric (mm)" -#: flatcamTools/ToolDistance.py:51 flatcamTools/ToolDistanceMin.py:51 +#: flatcamTools/ToolDistance.py:58 flatcamTools/ToolDistanceMin.py:52 msgid "INCH (in)" msgstr "INCH (in)" -#: flatcamTools/ToolDistance.py:54 +#: flatcamTools/ToolDistance.py:64 +msgid "Snap to center" +msgstr "Sari in Centru" + +#: flatcamTools/ToolDistance.py:66 +msgid "" +"Mouse cursor will snap to the center of the pad/drill\n" +"when it is hovering over the geometry of the pad/drill." +msgstr "" +"Cursorul mouse-ului va sari (automat) pozitionandu-se in centrul padului/" +"găurii\n" +"atunci cand se găseste deasupra geometriei acelui pad/gaură." + +#: flatcamTools/ToolDistance.py:76 msgid "Start Coords" msgstr "Coordonate Start" -#: flatcamTools/ToolDistance.py:55 flatcamTools/ToolDistance.py:75 +#: flatcamTools/ToolDistance.py:77 flatcamTools/ToolDistance.py:82 msgid "This is measuring Start point coordinates." msgstr "Coordonatele punctului de Start." -#: flatcamTools/ToolDistance.py:57 +#: flatcamTools/ToolDistance.py:87 msgid "Stop Coords" msgstr "Coordonate Stop" -#: flatcamTools/ToolDistance.py:58 flatcamTools/ToolDistance.py:80 +#: flatcamTools/ToolDistance.py:88 flatcamTools/ToolDistance.py:93 msgid "This is the measuring Stop point coordinates." msgstr "Coordonatele punctului de Stop." -#: flatcamTools/ToolDistance.py:60 flatcamTools/ToolDistanceMin.py:62 +#: flatcamTools/ToolDistance.py:98 flatcamTools/ToolDistanceMin.py:63 msgid "Dx" msgstr "Dx" -#: flatcamTools/ToolDistance.py:61 flatcamTools/ToolDistance.py:85 -#: flatcamTools/ToolDistanceMin.py:63 flatcamTools/ToolDistanceMin.py:92 +#: flatcamTools/ToolDistance.py:99 flatcamTools/ToolDistance.py:104 +#: flatcamTools/ToolDistanceMin.py:64 flatcamTools/ToolDistanceMin.py:93 msgid "This is the distance measured over the X axis." msgstr "Distanta masurata pe axa X." -#: flatcamTools/ToolDistance.py:63 flatcamTools/ToolDistanceMin.py:65 +#: flatcamTools/ToolDistance.py:109 flatcamTools/ToolDistanceMin.py:66 msgid "Dy" msgstr "Dy" -#: flatcamTools/ToolDistance.py:64 flatcamTools/ToolDistance.py:90 -#: flatcamTools/ToolDistanceMin.py:66 flatcamTools/ToolDistanceMin.py:97 +#: flatcamTools/ToolDistance.py:110 flatcamTools/ToolDistance.py:115 +#: flatcamTools/ToolDistanceMin.py:67 flatcamTools/ToolDistanceMin.py:98 msgid "This is the distance measured over the Y axis." msgstr "Distanta masurata pe axa Y." -#: flatcamTools/ToolDistance.py:67 flatcamTools/ToolDistance.py:95 -#: flatcamTools/ToolDistanceMin.py:69 flatcamTools/ToolDistanceMin.py:102 +#: flatcamTools/ToolDistance.py:121 flatcamTools/ToolDistance.py:126 +#: flatcamTools/ToolDistanceMin.py:70 flatcamTools/ToolDistanceMin.py:103 msgid "This is orientation angle of the measuring line." msgstr "Acesta este unghiul de orientare al liniei de măsurare." -#: flatcamTools/ToolDistance.py:69 flatcamTools/ToolDistanceMin.py:71 +#: flatcamTools/ToolDistance.py:131 flatcamTools/ToolDistanceMin.py:72 msgid "DISTANCE" msgstr "DISTANTA" -#: flatcamTools/ToolDistance.py:70 flatcamTools/ToolDistance.py:100 +#: flatcamTools/ToolDistance.py:132 flatcamTools/ToolDistance.py:137 msgid "This is the point to point Euclidian distance." msgstr "Distanta euclidiana de la punct la punct." -#: flatcamTools/ToolDistance.py:102 flatcamTools/ToolDistanceMin.py:114 +#: flatcamTools/ToolDistance.py:142 flatcamTools/ToolDistance.py:337 +#: flatcamTools/ToolDistanceMin.py:115 msgid "Measure" msgstr "Măsoară" -#: flatcamTools/ToolDistance.py:212 +#: flatcamTools/ToolDistance.py:272 +msgid "Working" +msgstr "Se lucrează" + +#: flatcamTools/ToolDistance.py:277 msgid "MEASURING: Click on the Start point ..." msgstr "Masoara: Click pe punctul de Start ..." -#: flatcamTools/ToolDistance.py:345 +#: flatcamTools/ToolDistance.py:387 +msgid "Distance Tool finished." +msgstr "Măsurătoarea s-a terminat." + +#: flatcamTools/ToolDistance.py:455 +msgid "Pads overlapped. Aborting." +msgstr "Pad-urile sunt suprapuse. Operatie anulată." + +#: flatcamTools/ToolDistance.py:485 msgid "MEASURING: Click on the Destination point ..." msgstr "Masoara: Click pe punctul Destinaţie..." -#: flatcamTools/ToolDistance.py:353 flatcamTools/ToolDistanceMin.py:282 +#: flatcamTools/ToolDistance.py:494 flatcamTools/ToolDistanceMin.py:285 msgid "MEASURING" msgstr "MĂSURARE" -#: flatcamTools/ToolDistance.py:354 flatcamTools/ToolDistanceMin.py:283 +#: flatcamTools/ToolDistance.py:495 flatcamTools/ToolDistanceMin.py:286 msgid "Result" msgstr "Rezultat" -#: flatcamTools/ToolDistanceMin.py:31 flatcamTools/ToolDistanceMin.py:152 +#: flatcamTools/ToolDistanceMin.py:32 flatcamTools/ToolDistanceMin.py:144 msgid "Minimum Distance Tool" msgstr "Unealta de distanță minimă" -#: flatcamTools/ToolDistanceMin.py:54 +#: flatcamTools/ToolDistanceMin.py:55 msgid "First object point" msgstr "Primul punct" -#: flatcamTools/ToolDistanceMin.py:55 flatcamTools/ToolDistanceMin.py:80 +#: flatcamTools/ToolDistanceMin.py:56 flatcamTools/ToolDistanceMin.py:81 msgid "" "This is first object point coordinates.\n" "This is the start point for measuring distance." @@ -14272,11 +15140,11 @@ msgstr "" "Aceasta este prima coordonată a punctelor obiectului.\n" "Acesta este punctul de pornire pentru măsurarea distanței." -#: flatcamTools/ToolDistanceMin.py:58 +#: flatcamTools/ToolDistanceMin.py:59 msgid "Second object point" msgstr "Al doilea punct" -#: flatcamTools/ToolDistanceMin.py:59 flatcamTools/ToolDistanceMin.py:86 +#: flatcamTools/ToolDistanceMin.py:60 flatcamTools/ToolDistanceMin.py:87 msgid "" "This is second object point coordinates.\n" "This is the end point for measuring distance." @@ -14284,43 +15152,60 @@ msgstr "" "Aceasta este a doua coordonata a punctelor obiectului.\n" "Acesta este punctul final pentru măsurarea distanței." -#: flatcamTools/ToolDistanceMin.py:72 flatcamTools/ToolDistanceMin.py:107 +#: flatcamTools/ToolDistanceMin.py:73 flatcamTools/ToolDistanceMin.py:108 msgid "This is the point to point Euclidean distance." msgstr "Distanta euclidiana de la punct la punct." -#: flatcamTools/ToolDistanceMin.py:74 +#: flatcamTools/ToolDistanceMin.py:75 msgid "Half Point" msgstr "Punctul de mijloc" -#: flatcamTools/ToolDistanceMin.py:75 flatcamTools/ToolDistanceMin.py:112 +#: flatcamTools/ToolDistanceMin.py:76 flatcamTools/ToolDistanceMin.py:113 msgid "This is the middle point of the point to point Euclidean distance." msgstr "Acesta este punctul de mijloc al distanței euclidiană." -#: flatcamTools/ToolDistanceMin.py:117 +#: flatcamTools/ToolDistanceMin.py:118 msgid "Jump to Half Point" msgstr "Sari la Punctul de Mijloc" -#: flatcamTools/ToolDistanceMin.py:163 +#: flatcamTools/ToolDistanceMin.py:155 msgid "" "Select two objects and no more, to measure the distance between them ..." msgstr "" "Selectați două obiecte și nu mai mult, pentru a măsura distanța dintre " "ele ..." -#: flatcamTools/ToolDistanceMin.py:204 flatcamTools/ToolDistanceMin.py:214 -#: flatcamTools/ToolDistanceMin.py:223 flatcamTools/ToolDistanceMin.py:244 +#: flatcamTools/ToolDistanceMin.py:196 flatcamTools/ToolDistanceMin.py:217 +#: flatcamTools/ToolDistanceMin.py:226 flatcamTools/ToolDistanceMin.py:247 msgid "Select two objects and no more. Currently the selection has objects: " msgstr "" "Selectați două obiecte și nu mai mult. În prezent, selecția are nr obiecte: " -#: flatcamTools/ToolDistanceMin.py:291 +#: flatcamTools/ToolDistanceMin.py:294 msgid "Objects intersects or touch at" msgstr "Obiectele se intersectează sau ating la" -#: flatcamTools/ToolDistanceMin.py:297 +#: flatcamTools/ToolDistanceMin.py:300 msgid "Jumped to the half point between the two selected objects" msgstr "A sărit la jumătatea punctului dintre cele două obiecte selectate" +#: flatcamTools/ToolExtractDrills.py:29 flatcamTools/ToolExtractDrills.py:295 +msgid "Extract Drills" +msgstr "Extrage Găuri" + +#: flatcamTools/ToolExtractDrills.py:62 +msgid "Gerber from which to extract drill holes" +msgstr "Obiect Gerber din care se vor extrage găurile" + +#: flatcamTools/ToolExtractDrills.py:297 +msgid "Extract drills from a given Gerber file." +msgstr "Extrage găuri dintr-un fisier Gerber." + +#: flatcamTools/ToolExtractDrills.py:478 flatcamTools/ToolExtractDrills.py:563 +#: flatcamTools/ToolExtractDrills.py:648 +msgid "No drills extracted. Try different parameters." +msgstr "Nu s-au extras găuri. Incearcă alti parametri." + #: flatcamTools/ToolFiducials.py:56 msgid "Fiducials Coordinates" msgstr "Coordonatele Fiducials" @@ -14337,10 +15222,6 @@ msgstr "" msgid "Top Right" msgstr "Dreapta-sus" -#: flatcamTools/ToolFiducials.py:111 -msgid "Second Point" -msgstr "Al doilea punct" - #: flatcamTools/ToolFiducials.py:191 msgid "" "- 'Auto' - automatic placement of fiducials in the corners of the bounding " @@ -14351,32 +15232,32 @@ msgstr "" "delimitare.\n" "  - „Manual” - plasarea manuală a fiduciarelor." -#: flatcamTools/ToolFiducials.py:258 +#: flatcamTools/ToolFiducials.py:259 msgid "Copper Gerber" msgstr "Gerber Cupru" -#: flatcamTools/ToolFiducials.py:267 +#: flatcamTools/ToolFiducials.py:268 msgid "Add Fiducial" msgstr "Adaugă Fiducial" -#: flatcamTools/ToolFiducials.py:269 +#: flatcamTools/ToolFiducials.py:270 msgid "Will add a polygon on the copper layer to serve as fiducial." msgstr "" "Va adăuga un poligon pe stratul de cupru pentru a servi drept fiduciar." -#: flatcamTools/ToolFiducials.py:285 +#: flatcamTools/ToolFiducials.py:286 msgid "Soldermask Gerber" msgstr "Gerber Soldermask" -#: flatcamTools/ToolFiducials.py:287 +#: flatcamTools/ToolFiducials.py:288 msgid "The Soldermask Gerber object." msgstr "Obiectul Soldermask Gerber." -#: flatcamTools/ToolFiducials.py:298 -msgid "Add Soldermask Opening" -msgstr "Adăugați deschidere Soldermask." - #: flatcamTools/ToolFiducials.py:300 +msgid "Add Soldermask Opening" +msgstr "Adăugați deschidere Soldermask" + +#: flatcamTools/ToolFiducials.py:302 msgid "" "Will add a polygon on the soldermask layer\n" "to serve as fiducial opening.\n" @@ -14388,25 +15269,25 @@ msgstr "" "Diametrul este întotdeauna dublu față de diametrul\n" "pentru fiduciarul de cupru." -#: flatcamTools/ToolFiducials.py:514 +#: flatcamTools/ToolFiducials.py:516 msgid "Click to add first Fiducial. Bottom Left..." msgstr "Faceți clic pentru a adăuga primul Fiducial. Stânga jos..." -#: flatcamTools/ToolFiducials.py:778 +#: flatcamTools/ToolFiducials.py:780 msgid "Click to add the last fiducial. Top Right..." msgstr "Faceți clic pentru a adăuga ultimul Fiducial. Dreapta Sus..." -#: flatcamTools/ToolFiducials.py:783 +#: flatcamTools/ToolFiducials.py:785 msgid "Click to add the second fiducial. Top Left or Bottom Right..." msgstr "" "Faceți clic pentru a adăuga cel de-al doilea Fiducial. Stânga sus sau " "dreapta jos ..." -#: flatcamTools/ToolFiducials.py:786 flatcamTools/ToolFiducials.py:795 +#: flatcamTools/ToolFiducials.py:788 flatcamTools/ToolFiducials.py:797 msgid "Done. All fiducials have been added." msgstr "Terminat. Au fost adăugate toate Fiducials." -#: flatcamTools/ToolFiducials.py:872 +#: flatcamTools/ToolFiducials.py:874 msgid "Fiducials Tool exit." msgstr "Unealta Fiducials terminate." @@ -14414,7 +15295,7 @@ msgstr "Unealta Fiducials terminate." msgid "Film PCB" msgstr "Film PCB" -#: flatcamTools/ToolFilm.py:80 +#: flatcamTools/ToolFilm.py:78 msgid "" "Specify the type of object for which to create the film.\n" "The object can be of type: Gerber or Geometry.\n" @@ -14426,11 +15307,11 @@ msgstr "" "Selectia facuta aici controlează ce obiecte vor fi \n" "gasite in combobox-ul >Obiect Film<." -#: flatcamTools/ToolFilm.py:94 +#: flatcamTools/ToolFilm.py:92 msgid "Film Object" msgstr "Obiect Film" -#: flatcamTools/ToolFilm.py:96 +#: flatcamTools/ToolFilm.py:94 msgid "Object for which to create the film." msgstr "Obiectul pt care se crează filmul." @@ -14446,7 +15327,7 @@ msgstr "" "Selectia facuta aici controlează ce obiecte vor fi \n" "gasite in combobox-ul >Container<." -#: flatcamTools/ToolFilm.py:129 flatcamTools/ToolPanelize.py:136 +#: flatcamTools/ToolFilm.py:129 msgid "Box Object" msgstr "Container" @@ -14508,20 +15389,20 @@ msgid "" msgstr "" "Îndepărtați geometria Excellon din film pentru a crea găurile din pad-uri." -#: flatcamTools/ToolFilm.py:379 +#: flatcamTools/ToolFilm.py:381 msgid "Punch Size" msgstr "Mărimea Perforatii" -#: flatcamTools/ToolFilm.py:380 +#: flatcamTools/ToolFilm.py:382 msgid "The value here will control how big is the punch hole in the pads." msgstr "" "Valoarea de aici va controla cât de mare este gaura de perforare în pad-uri." -#: flatcamTools/ToolFilm.py:500 +#: flatcamTools/ToolFilm.py:502 msgid "Save Film" msgstr "Salveaa filmul" -#: flatcamTools/ToolFilm.py:502 +#: flatcamTools/ToolFilm.py:504 msgid "" "Create a Film for the selected object, within\n" "the specified box. Does not create a new \n" @@ -14532,7 +15413,7 @@ msgstr "" "container selectat. Nu crează un obiect nou FlatCAM ci\n" "salvează pe HDD un fişier in formatul selectat." -#: flatcamTools/ToolFilm.py:652 +#: flatcamTools/ToolFilm.py:664 msgid "" "Using the Pad center does not work on Geometry objects. Only a Gerber object " "has pads." @@ -14540,42 +15421,38 @@ msgstr "" "Utilizarea centrului Pad nu funcționează pe obiecte de Geometrie. Doar un " "obiect Gerber are pad-uri." -#: flatcamTools/ToolFilm.py:662 +#: flatcamTools/ToolFilm.py:674 msgid "No FlatCAM object selected. Load an object for Film and retry." msgstr "" "Nici-un obiect FlaCAM nu este selectat. Incarcă un obiect pt Film și " "încearcă din nou." -#: flatcamTools/ToolFilm.py:669 +#: flatcamTools/ToolFilm.py:681 msgid "No FlatCAM object selected. Load an object for Box and retry." msgstr "" "Nici-un obiect FlatCAM nu este selectat. Încarcă un obiect container și " "încearcă din nou." -#: flatcamTools/ToolFilm.py:673 +#: flatcamTools/ToolFilm.py:685 msgid "No FlatCAM object selected." msgstr "Nici-un obiect nu este selectat." -#: flatcamTools/ToolFilm.py:684 +#: flatcamTools/ToolFilm.py:696 msgid "Generating Film ..." msgstr "Se generează Film-ul ..." -#: flatcamTools/ToolFilm.py:733 flatcamTools/ToolFilm.py:737 +#: flatcamTools/ToolFilm.py:745 flatcamTools/ToolFilm.py:749 msgid "Export positive film" msgstr "Export film pozitiv" -#: flatcamTools/ToolFilm.py:742 -msgid "Export positive film cancelled." -msgstr "Exportul filmului pozitiv a fost anulat." - -#: flatcamTools/ToolFilm.py:770 +#: flatcamTools/ToolFilm.py:782 msgid "" "No Excellon object selected. Load an object for punching reference and retry." msgstr "" "Nici-un obiect Excellon nu este selectat. Incarcă un obiect ca referinta " "pentru perforare și încearcă din nou." -#: flatcamTools/ToolFilm.py:794 +#: flatcamTools/ToolFilm.py:806 msgid "" " Could not generate punched hole film because the punch hole sizeis bigger " "than some of the apertures in the Gerber object." @@ -14583,7 +15460,7 @@ msgstr "" " Nu a putut genera un film cu găuri perforate, deoarece dimensiunea găurii " "de perforare este mai mare decât unele dintre aperturile din obiectul Gerber." -#: flatcamTools/ToolFilm.py:806 +#: flatcamTools/ToolFilm.py:818 msgid "" "Could not generate punched hole film because the punch hole sizeis bigger " "than some of the apertures in the Gerber object." @@ -14591,7 +15468,7 @@ msgstr "" "Nu s-a putut genera un film cu găuri perforate, deoarece dimensiunea găurii " "de perforare este mai mare decât unele dintre aperturile din obiectul Gerber." -#: flatcamTools/ToolFilm.py:824 +#: flatcamTools/ToolFilm.py:836 msgid "" "Could not generate punched hole film because the newly created object " "geometry is the same as the one in the source object geometry..." @@ -14599,24 +15476,20 @@ msgstr "" "Nu s-a putut genera Film cu găuri perforate, deoarece geometria obiectului " "nou creat este aceeași cu cea din geometria obiectului sursă ..." -#: flatcamTools/ToolFilm.py:879 flatcamTools/ToolFilm.py:883 +#: flatcamTools/ToolFilm.py:891 flatcamTools/ToolFilm.py:895 msgid "Export negative film" msgstr "Export film negativ" -#: flatcamTools/ToolFilm.py:888 -msgid "Export negative film cancelled." -msgstr "Exportul filmului negativ a fost anulat." - -#: flatcamTools/ToolFilm.py:944 flatcamTools/ToolFilm.py:1122 -#: flatcamTools/ToolPanelize.py:421 +#: flatcamTools/ToolFilm.py:956 flatcamTools/ToolFilm.py:1139 +#: flatcamTools/ToolPanelize.py:433 msgid "No object Box. Using instead" msgstr "Nu exista container. Se foloseşte in schimb" -#: flatcamTools/ToolFilm.py:1060 flatcamTools/ToolFilm.py:1235 +#: flatcamTools/ToolFilm.py:1072 flatcamTools/ToolFilm.py:1252 msgid "Film file exported to" msgstr "Fișierul Film exportat în" -#: flatcamTools/ToolFilm.py:1063 flatcamTools/ToolFilm.py:1238 +#: flatcamTools/ToolFilm.py:1075 flatcamTools/ToolFilm.py:1255 msgid "Generating Film ... Please wait." msgstr "Filmul se generează ... Aşteaptă." @@ -14628,7 +15501,7 @@ msgstr "Imagine ca Obiect" msgid "Image to PCB" msgstr "Imagine -> PCB" -#: flatcamTools/ToolImage.py:57 +#: flatcamTools/ToolImage.py:56 msgid "" "Specify the type of object to create from the image.\n" "It can be of type: Gerber or Geometry." @@ -14636,23 +15509,23 @@ msgstr "" "Specifica tipul de obiect care se vrea a fi creat din imagine.\n" "Tipul sau poate să fie ori Gerber ori Geometrie." -#: flatcamTools/ToolImage.py:66 +#: flatcamTools/ToolImage.py:65 msgid "DPI value" msgstr "Val. DPI" -#: flatcamTools/ToolImage.py:67 +#: flatcamTools/ToolImage.py:66 msgid "Specify a DPI value for the image." msgstr "Specifica o valoare DPI pt imagine." -#: flatcamTools/ToolImage.py:73 +#: flatcamTools/ToolImage.py:72 msgid "Level of detail" msgstr "Nivel Detaliu" -#: flatcamTools/ToolImage.py:82 +#: flatcamTools/ToolImage.py:81 msgid "Image type" msgstr "Tip imagine" -#: flatcamTools/ToolImage.py:84 +#: flatcamTools/ToolImage.py:83 msgid "" "Choose a method for the image interpretation.\n" "B/W means a black & white image. Color means a colored image." @@ -14661,12 +15534,12 @@ msgstr "" "B/W = imagine alb-negru\n" "Color = imagine in culori." -#: flatcamTools/ToolImage.py:93 flatcamTools/ToolImage.py:108 -#: flatcamTools/ToolImage.py:121 flatcamTools/ToolImage.py:134 +#: flatcamTools/ToolImage.py:92 flatcamTools/ToolImage.py:107 +#: flatcamTools/ToolImage.py:120 flatcamTools/ToolImage.py:133 msgid "Mask value" msgstr "Val. masca" -#: flatcamTools/ToolImage.py:95 +#: flatcamTools/ToolImage.py:94 msgid "" "Mask for monochrome image.\n" "Takes values between [0 ... 255].\n" @@ -14683,7 +15556,7 @@ msgstr "" "255 = include totul (ceeace ce inseamna\n" "negru complet)." -#: flatcamTools/ToolImage.py:110 +#: flatcamTools/ToolImage.py:109 msgid "" "Mask for RED color.\n" "Takes values between [0 ... 255].\n" @@ -14695,7 +15568,7 @@ msgstr "" "Decide nivelul de detalii care să fie\n" "incluse in obiectul rezultat." -#: flatcamTools/ToolImage.py:123 +#: flatcamTools/ToolImage.py:122 msgid "" "Mask for GREEN color.\n" "Takes values between [0 ... 255].\n" @@ -14707,7 +15580,7 @@ msgstr "" "Decide nivelul de detalii care să fie\n" "incluse in obiectul rezultat." -#: flatcamTools/ToolImage.py:136 +#: flatcamTools/ToolImage.py:135 msgid "" "Mask for BLUE color.\n" "Takes values between [0 ... 255].\n" @@ -14719,34 +15592,60 @@ msgstr "" "Decide nivelul de detalii care să fie\n" "incluse in obiectul rezultat." -#: flatcamTools/ToolImage.py:144 +#: flatcamTools/ToolImage.py:143 msgid "Import image" msgstr "Importa imagine" -#: flatcamTools/ToolImage.py:146 +#: flatcamTools/ToolImage.py:145 msgid "Open a image of raster type and then import it in FlatCAM." msgstr "Deschide o imagine tip raster și importa aceasta in FlatCAM." -#: flatcamTools/ToolImage.py:183 +#: flatcamTools/ToolImage.py:182 msgid "Image Tool" msgstr "Unealta Imagine" -#: flatcamTools/ToolImage.py:235 flatcamTools/ToolImage.py:238 +#: flatcamTools/ToolImage.py:234 flatcamTools/ToolImage.py:237 msgid "Import IMAGE" msgstr "Importa Imagine" -#: flatcamTools/ToolImage.py:286 +#: flatcamTools/ToolImage.py:285 msgid "Importing Image" msgstr "Imaginea in curs de a fi importata" +#: flatcamTools/ToolInvertGerber.py:74 +msgid "Gerber object that will be inverted." +msgstr "" +"Obiect Gerber care va fi inversat\n" +"(din pozitiv in negativ)." + +#: flatcamTools/ToolInvertGerber.py:83 +msgid "Parameters for this tool" +msgstr "Parametrii pt această unealtă" + +#: flatcamTools/ToolInvertGerber.py:123 +msgid "Invert Gerber" +msgstr "Inversează Gerber" + +#: flatcamTools/ToolInvertGerber.py:125 +msgid "" +"Will invert the Gerber object: areas that have copper\n" +"will be empty of copper and previous empty area will be\n" +"filled with copper." +msgstr "" +"Va inversa obiectul Gerber: ariile care contin cupru vor devein goale,\n" +"iar ariile care nu aveau cupru vor fi pline." + +#: flatcamTools/ToolInvertGerber.py:184 +msgid "Invert Tool" +msgstr "Unealta Inversie" + #: flatcamTools/ToolMove.py:103 msgid "MOVE: Click on the Start point ..." msgstr "MUTARE: Click pe punctul de Start ..." #: flatcamTools/ToolMove.py:114 -msgid "MOVE action cancelled. No object(s) to move." -msgstr "" -"Actiunea de Mutare a fost anulată. Nu sunt obiecte care să fie mutate ..." +msgid "Cancelled. No object(s) to move." +msgstr "Anulat. Nu sunt obiecte care să fie mutate." #: flatcamTools/ToolMove.py:141 msgid "MOVE: Click on the Destination point ..." @@ -14760,19 +15659,15 @@ msgstr "In mișcare ..." msgid "No object(s) selected." msgstr "Nici-un obiect nu este selectat." -#: flatcamTools/ToolMove.py:212 +#: flatcamTools/ToolMove.py:222 msgid "Error when mouse left click." msgstr "Eroare atunci când faceți clic pe butonul stânga al mouse-ului." -#: flatcamTools/ToolMove.py:260 -msgid "Move action cancelled." -msgstr "Actiunea de mutare a fost anulată." - -#: flatcamTools/ToolNonCopperClear.py:38 +#: flatcamTools/ToolNCC.py:42 msgid "Non-Copper Clearing" msgstr "Curățăre Non-Cu" -#: flatcamTools/ToolNonCopperClear.py:84 +#: flatcamTools/ToolNCC.py:88 msgid "" "Specify the type of object to be cleared of excess copper.\n" "It can be of type: Gerber or Geometry.\n" @@ -14784,11 +15679,11 @@ msgstr "" "Ceea ce este selectat aici va dicta genul\n" "de obiecte care vor popula combobox-ul „Obiect”." -#: flatcamTools/ToolNonCopperClear.py:101 +#: flatcamTools/ToolNCC.py:110 msgid "Object to be cleared of excess copper." msgstr "Obiect care trebuie curatat de excesul de cupru." -#: flatcamTools/ToolNonCopperClear.py:111 +#: flatcamTools/ToolNCC.py:122 msgid "" "Tools pool from which the algorithm\n" "will pick the ones used for copper clearing." @@ -14796,11 +15691,7 @@ msgstr "" "Un număr de unelte din care algoritmul va alege\n" "pe acelea care vor fi folosite pentru curățarea de Cu." -#: flatcamTools/ToolNonCopperClear.py:120 -msgid "Operation" -msgstr "Operațiuni" - -#: flatcamTools/ToolNonCopperClear.py:126 +#: flatcamTools/ToolNCC.py:138 msgid "" "This is the Tool Number.\n" "Non copper clearing will start with the tool with the biggest \n" @@ -14816,7 +15707,7 @@ msgstr "" "Doar uneltele care efectiv au creat geometrie vor fi prezente in obiectul\n" "final. Aceasta deaorece unele unelte nu vor putea genera geometrie." -#: flatcamTools/ToolNonCopperClear.py:134 +#: flatcamTools/ToolNCC.py:146 msgid "" "Tool Diameter. It's value (in current FlatCAM units)\n" "is the cut width into the material." @@ -14824,7 +15715,7 @@ msgstr "" "Diametrul uneltei. Valoarea să (in unitati curente FlatCAM)\n" "reprezintă lăţimea tăieturii in material." -#: flatcamTools/ToolNonCopperClear.py:138 +#: flatcamTools/ToolNCC.py:150 msgid "" "The Tool Type (TT) can be:\n" "- Circular with 1 ... 4 teeth -> it is informative only. Being circular,\n" @@ -14857,34 +15748,7 @@ msgstr "" "operare\n" "în geometria rezultată ca fiind Izolare." -#: flatcamTools/ToolNonCopperClear.py:151 -msgid "" -"The 'Operation' can be:\n" -"- Isolation -> will ensure that the non-copper clearing is always complete.\n" -"If it's not successful then the non-copper clearing will fail, too.\n" -"- Clear -> the regular non-copper clearing." -msgstr "" -"„Operațiunea” poate fi:\n" -"- Izolare -> se va asigura că curățarea non-cupru este întotdeauna " -"completă.\n" -"Dacă nu are succes, atunci curățarea din cupru nu va reuși.\n" -"- Curățare -> curățarea obișnuită de cupru." - -#: flatcamTools/ToolNonCopperClear.py:209 -msgid "Tool Selection" -msgstr "Selecţie Unealtă" - -#: flatcamTools/ToolNonCopperClear.py:273 -msgid "" -"Diameter for the new tool to add in the Tool Table.\n" -"If the tool is V-shape type then this value is automatically\n" -"calculated from the other parameters." -msgstr "" -"Diametru pentru Unealta nouă de adăugat în Tabelul Uneltelor.\n" -"Dacă instrumentul este în formă de V, atunci această valoare este automat\n" -"calculată din ceilalți parametri." - -#: flatcamTools/ToolNonCopperClear.py:288 flatcamTools/ToolPaint.py:190 +#: flatcamTools/ToolNCC.py:296 flatcamTools/ToolPaint.py:279 msgid "" "Add a new tool to the Tool Table\n" "with the diameter specified above." @@ -14892,8 +15756,8 @@ msgstr "" "Adaugă o noua unelata in Tabela de Unelte,\n" "cu diametrul specificat mai sus." -#: flatcamTools/ToolNonCopperClear.py:300 flatcamTools/ToolPaint.py:202 -#: flatcamTools/ToolSolderPaste.py:129 +#: flatcamTools/ToolNCC.py:318 flatcamTools/ToolPaint.py:301 +#: flatcamTools/ToolSolderPaste.py:131 msgid "" "Delete a selection of tools in the Tool Table\n" "by first selecting a row(s) in the Tool Table." @@ -14901,23 +15765,7 @@ msgstr "" "Șterge o selecţie de unelte in Tabela de Unelte,\n" "efectuata prin selectia liniilot din Tabela de Unelte." -#: flatcamTools/ToolNonCopperClear.py:435 -msgid "" -"- 'Itself' - the non copper clearing extent is based on the object that is " -"copper cleared.\n" -" - 'Area Selection' - left mouse click to start selection of the area to be " -"painted.\n" -"- 'Reference Object' - will do non copper clearing within the area specified " -"by another object." -msgstr "" -"- „Însuși” - suprafața de curățare a cuprului se bazează pe obiectul care " -"este curățat de cupru.\n" -"- „Selecție zonă” - faceți clic stânga cu mouse-ul pentru a începe selecția " -"zonei care va fi pictată.\n" -"- „Obiect de referință” - va face o curățare fără cupru în zona specificată " -"de un alt obiect." - -#: flatcamTools/ToolNonCopperClear.py:447 +#: flatcamTools/ToolNCC.py:554 msgid "" "The type of FlatCAM object to be used as non copper clearing reference.\n" "It can be Gerber, Excellon or Geometry." @@ -14926,120 +15774,124 @@ msgstr "" "non-cupru.\n" "Poate fi Gerber, Excellon sau Geometry." -#: flatcamTools/ToolNonCopperClear.py:471 +#: flatcamTools/ToolNCC.py:597 flatcamTools/ToolPaint.py:537 msgid "Generate Geometry" msgstr "Genereza Geometrie" -#: flatcamTools/ToolNonCopperClear.py:582 flatcamTools/ToolPaint.py:493 -#: flatcamTools/ToolSolderPaste.py:553 -msgid "New Tool" -msgstr "O Noua Unealtă" - -#: flatcamTools/ToolNonCopperClear.py:981 flatcamTools/ToolPaint.py:766 -#: flatcamTools/ToolSolderPaste.py:887 +#: flatcamTools/ToolNCC.py:1429 flatcamTools/ToolPaint.py:1172 +#: flatcamTools/ToolSolderPaste.py:888 msgid "Please enter a tool diameter to add, in Float format." msgstr "Introduce diametrul unei unelte pt a fi adăugată, in format Real." -#: flatcamTools/ToolNonCopperClear.py:1012 flatcamTools/ToolPaint.py:791 -msgid "Adding tool cancelled. Tool already in Tool Table." -msgstr "" -"Adăugarea unei unelte noi este anulată. Unealta există deja in Tabela de " -"Unelte." +#: flatcamTools/ToolNCC.py:1460 flatcamTools/ToolNCC.py:4013 +#: flatcamTools/ToolPaint.py:1196 flatcamTools/ToolPaint.py:4077 +#: flatcamTools/ToolSolderPaste.py:917 +msgid "Cancelled. Tool already in Tool Table." +msgstr "Anulat. Unealta există deja in Tabela de Unelte." -#: flatcamTools/ToolNonCopperClear.py:1017 flatcamTools/ToolPaint.py:797 +#: flatcamTools/ToolNCC.py:1467 flatcamTools/ToolNCC.py:4030 +#: flatcamTools/ToolPaint.py:1201 flatcamTools/ToolPaint.py:4094 msgid "New tool added to Tool Table." msgstr "O noua unealtă a fost adăugată in Tabela de Unelte." -#: flatcamTools/ToolNonCopperClear.py:1061 flatcamTools/ToolPaint.py:843 +#: flatcamTools/ToolNCC.py:1511 flatcamTools/ToolPaint.py:1245 msgid "Tool from Tool Table was edited." msgstr "O unealtă din Tabela de Unelte a fost editata." -#: flatcamTools/ToolNonCopperClear.py:1072 flatcamTools/ToolPaint.py:855 -#: flatcamTools/ToolSolderPaste.py:978 -msgid "Edit cancelled. New diameter value is already in the Tool Table." +#: flatcamTools/ToolNCC.py:1523 flatcamTools/ToolPaint.py:1257 +#: flatcamTools/ToolSolderPaste.py:977 +msgid "Cancelled. New diameter value is already in the Tool Table." msgstr "" -"Editare eșuată. Noua valoare pt diametrul uneltei este deja in Tabela de " -"Unelte." +"Anulat. Noua valoare pt diametrul uneltei este deja in Tabela de Unelte." -#: flatcamTools/ToolNonCopperClear.py:1119 flatcamTools/ToolPaint.py:953 +#: flatcamTools/ToolNCC.py:1575 flatcamTools/ToolPaint.py:1355 msgid "Delete failed. Select a tool to delete." msgstr "Ștergere eșuată. Selectează o unealtă pt ștergere." -#: flatcamTools/ToolNonCopperClear.py:1124 flatcamTools/ToolPaint.py:959 +#: flatcamTools/ToolNCC.py:1581 flatcamTools/ToolPaint.py:1361 msgid "Tool(s) deleted from Tool Table." msgstr "Au fost șterse unelte din Tabela de Unelte." -#: flatcamTools/ToolNonCopperClear.py:1171 +#: flatcamTools/ToolNCC.py:1623 msgid "Wrong Tool Dia value format entered, use a number." msgstr "Diametrul uneltei este in format gresit, foloseşte un număr Real." -#: flatcamTools/ToolNonCopperClear.py:1180 flatcamTools/ToolPaint.py:1023 +#: flatcamTools/ToolNCC.py:1632 flatcamTools/ToolPaint.py:1412 msgid "No selected tools in Tool Table." msgstr "Nu sunt unelte selectate in Tabela de Unelte." -#: flatcamTools/ToolNonCopperClear.py:1255 flatcamTools/ToolPaint.py:1195 +#: flatcamTools/ToolNCC.py:1708 flatcamTools/ToolPaint.py:1588 msgid "Click the end point of the paint area." msgstr "Faceți clic pe punctul final al zonei de pictat." -#: flatcamTools/ToolNonCopperClear.py:1410 -#: flatcamTools/ToolNonCopperClear.py:1412 -msgid "Non-Copper clearing ..." -msgstr "Curățare Non-Cupru ..." - -#: flatcamTools/ToolNonCopperClear.py:1422 -msgid "NCC Tool started. Reading parameters." -msgstr "Unealta NCC a pornit. Se citesc parametrii." - -#: flatcamTools/ToolNonCopperClear.py:1485 +#: flatcamTools/ToolNCC.py:1976 flatcamTools/ToolNCC.py:2964 msgid "NCC Tool. Preparing non-copper polygons." msgstr "Unealta NCC. Se pregătesc poligoanele non-cupru." -#: flatcamTools/ToolNonCopperClear.py:1581 +#: flatcamTools/ToolNCC.py:2035 flatcamTools/ToolNCC.py:3092 +msgid "NCC Tool. Calculate 'empty' area." +msgstr "Unealta NCC. Calculează aria 'goală'." + +#: flatcamTools/ToolNCC.py:2054 flatcamTools/ToolNCC.py:2160 +#: flatcamTools/ToolNCC.py:2174 flatcamTools/ToolNCC.py:3105 +#: flatcamTools/ToolNCC.py:3210 flatcamTools/ToolNCC.py:3225 +#: flatcamTools/ToolNCC.py:3491 flatcamTools/ToolNCC.py:3592 +#: flatcamTools/ToolNCC.py:3607 +msgid "Buffering finished" +msgstr "Buferarea terminată" + +#: flatcamTools/ToolNCC.py:2062 flatcamTools/ToolNCC.py:2181 +#: flatcamTools/ToolNCC.py:3113 flatcamTools/ToolNCC.py:3232 +#: flatcamTools/ToolNCC.py:3498 flatcamTools/ToolNCC.py:3614 +msgid "Could not get the extent of the area to be non copper cleared." +msgstr "" +"Nu s-a putut obtine intinderea suprafaței care să fie curățată de cupru." + +#: flatcamTools/ToolNCC.py:2089 flatcamTools/ToolNCC.py:2167 +#: flatcamTools/ToolNCC.py:3140 flatcamTools/ToolNCC.py:3217 +#: flatcamTools/ToolNCC.py:3518 flatcamTools/ToolNCC.py:3599 +msgid "" +"Isolation geometry is broken. Margin is less than isolation tool diameter." +msgstr "" +"Geometria de Izolare este discontinuă.\n" +"Marginea este mai mic decat diametrul uneltei de izolare." + +#: flatcamTools/ToolNCC.py:2184 flatcamTools/ToolNCC.py:3236 +#: flatcamTools/ToolNCC.py:3617 +msgid "The selected object is not suitable for copper clearing." +msgstr "Obiectul selectat nu este potrivit pentru curățarea cuprului." + +#: flatcamTools/ToolNCC.py:2191 flatcamTools/ToolNCC.py:3243 +msgid "NCC Tool. Finished calculation of 'empty' area." +msgstr "Unealta NCC. S-a terminat calculul suprafetei 'goale'." + +#: flatcamTools/ToolNCC.py:2222 flatcamTools/ToolNCC.py:2224 +#: flatcamTools/ToolNCC.py:2916 flatcamTools/ToolNCC.py:2918 +msgid "Non-Copper clearing ..." +msgstr "Curățare Non-Cupru ..." + +#: flatcamTools/ToolNCC.py:2278 flatcamTools/ToolNCC.py:3060 msgid "" "NCC Tool. Finished non-copper polygons. Normal copper clearing task started." msgstr "" "Unelata NCC. S-a terminat pregătirea poligoanelor non-cupru. Taskul de " "curatare normal de cupru a inceput." -#: flatcamTools/ToolNonCopperClear.py:1613 -msgid "NCC Tool. Calculate 'empty' area." -msgstr "Unealta NCC. Calculează aria 'goală'." +#: flatcamTools/ToolNCC.py:2312 flatcamTools/ToolNCC.py:2592 +msgid "NCC Tool failed creating bounding box." +msgstr "Unealta NCC a esuat in a crea forma inconjurătoare." -#: flatcamTools/ToolNonCopperClear.py:1626 -#: flatcamTools/ToolNonCopperClear.py:1723 -#: flatcamTools/ToolNonCopperClear.py:1735 -#: flatcamTools/ToolNonCopperClear.py:2018 -#: flatcamTools/ToolNonCopperClear.py:2114 -#: flatcamTools/ToolNonCopperClear.py:2126 -msgid "Buffering finished" -msgstr "Buferarea terminată" +#: flatcamTools/ToolNCC.py:2326 flatcamTools/ToolNCC.py:2609 +#: flatcamTools/ToolNCC.py:3256 flatcamTools/ToolNCC.py:3642 +msgid "NCC Tool clearing with tool diameter" +msgstr "Unealta NCC cu diametrul uneltei" -#: flatcamTools/ToolNonCopperClear.py:1742 -#: flatcamTools/ToolNonCopperClear.py:2132 -msgid "The selected object is not suitable for copper clearing." -msgstr "Obiectul selectat nu este potrivit pentru curățarea cuprului." - -#: flatcamTools/ToolNonCopperClear.py:1747 -#: flatcamTools/ToolNonCopperClear.py:2137 -msgid "Could not get the extent of the area to be non copper cleared." -msgstr "" -"Nu s-a putut obtine intinderea suprafaței care să fie curățată de cupru." - -#: flatcamTools/ToolNonCopperClear.py:1754 -msgid "NCC Tool. Finished calculation of 'empty' area." -msgstr "Unealta NCC. S-a terminat calculul suprafetei 'goale'." - -#: flatcamTools/ToolNonCopperClear.py:1768 -#: flatcamTools/ToolNonCopperClear.py:2162 -msgid "NCC Tool clearing with tool diameter = " -msgstr "Unealta NCC cu diametrul uneltei = " - -#: flatcamTools/ToolNonCopperClear.py:1771 -#: flatcamTools/ToolNonCopperClear.py:2165 +#: flatcamTools/ToolNCC.py:2326 flatcamTools/ToolNCC.py:2609 +#: flatcamTools/ToolNCC.py:3256 flatcamTools/ToolNCC.py:3642 msgid "started." msgstr "a inceput." -#: flatcamTools/ToolNonCopperClear.py:1947 +#: flatcamTools/ToolNCC.py:2518 flatcamTools/ToolNCC.py:3417 msgid "" "There is no NCC Geometry in the file.\n" "Usually it means that the tool diameter is too big for the painted " @@ -15051,25 +15903,25 @@ msgstr "" "pictată.\n" "Schimbați parametrii Paint și încercați din nou." -#: flatcamTools/ToolNonCopperClear.py:1967 +#: flatcamTools/ToolNCC.py:2527 flatcamTools/ToolNCC.py:3426 msgid "NCC Tool clear all done." msgstr "Unealta NCC curătare toate efectuată." -#: flatcamTools/ToolNonCopperClear.py:1969 +#: flatcamTools/ToolNCC.py:2530 flatcamTools/ToolNCC.py:3429 msgid "NCC Tool clear all done but the copper features isolation is broken for" msgstr "" "Unealta NCC curătare toate efectuată dar izolatia este intreruptă pentru" -#: flatcamTools/ToolNonCopperClear.py:1972 -#: flatcamTools/ToolNonCopperClear.py:2341 +#: flatcamTools/ToolNCC.py:2532 flatcamTools/ToolNCC.py:2817 +#: flatcamTools/ToolNCC.py:3431 flatcamTools/ToolNCC.py:3814 msgid "tools" msgstr "unelte" -#: flatcamTools/ToolNonCopperClear.py:2337 +#: flatcamTools/ToolNCC.py:2813 flatcamTools/ToolNCC.py:3810 msgid "NCC Tool Rest Machining clear all done." msgstr "Unealta NCC curătare cu prelucrare tip 'rest' efectuată." -#: flatcamTools/ToolNonCopperClear.py:2340 +#: flatcamTools/ToolNCC.py:2816 flatcamTools/ToolNCC.py:3813 msgid "" "NCC Tool Rest Machining clear all done but the copper features isolation is " "broken for" @@ -15077,7 +15929,11 @@ msgstr "" "Unealta NCC curătare toate cu prelucrare tip 'rest' efectuată dar izolatia " "este intreruptă pentru" -#: flatcamTools/ToolNonCopperClear.py:2787 +#: flatcamTools/ToolNCC.py:2928 +msgid "NCC Tool started. Reading parameters." +msgstr "Unealta NCC a pornit. Se citesc parametrii." + +#: flatcamTools/ToolNCC.py:3906 msgid "" "Try to use the Buffering Type = Full in Preferences -> Gerber General. " "Reload the Gerber file after this change." @@ -15085,43 +15941,43 @@ msgstr "" "Incearcă să folosesti optiunea Tipul de buffering = Complet in Preferinte -> " "Gerber General. Reincarcă fisierul Gerber după această schimbare." -#: flatcamTools/ToolOptimal.py:79 +#: flatcamTools/ToolOptimal.py:80 msgid "Number of decimals kept for found distances." msgstr "Numărul de zecimale păstrate pentru distanțele găsite." -#: flatcamTools/ToolOptimal.py:87 +#: flatcamTools/ToolOptimal.py:88 msgid "Minimum distance" msgstr "Distanta minima" -#: flatcamTools/ToolOptimal.py:88 +#: flatcamTools/ToolOptimal.py:89 msgid "Display minimum distance between copper features." msgstr "Afișează distanța minimă între caracteristicile de cupru." -#: flatcamTools/ToolOptimal.py:92 +#: flatcamTools/ToolOptimal.py:93 msgid "Determined" msgstr "Determinat" -#: flatcamTools/ToolOptimal.py:106 +#: flatcamTools/ToolOptimal.py:107 msgid "Occurring" msgstr "Aparute" -#: flatcamTools/ToolOptimal.py:107 +#: flatcamTools/ToolOptimal.py:108 msgid "How many times this minimum is found." msgstr "De câte ori este găsit acest minim." -#: flatcamTools/ToolOptimal.py:113 +#: flatcamTools/ToolOptimal.py:114 msgid "Minimum points coordinates" msgstr "Coordonatele punctelor minime" -#: flatcamTools/ToolOptimal.py:114 flatcamTools/ToolOptimal.py:120 +#: flatcamTools/ToolOptimal.py:115 flatcamTools/ToolOptimal.py:121 msgid "Coordinates for points where minimum distance was found." msgstr "Coordonate pentru puncte în care a fost găsită distanța minimă." -#: flatcamTools/ToolOptimal.py:133 flatcamTools/ToolOptimal.py:209 +#: flatcamTools/ToolOptimal.py:134 flatcamTools/ToolOptimal.py:210 msgid "Jump to selected position" msgstr "Salt la poziția selectată" -#: flatcamTools/ToolOptimal.py:135 flatcamTools/ToolOptimal.py:211 +#: flatcamTools/ToolOptimal.py:136 flatcamTools/ToolOptimal.py:212 msgid "" "Select a position in the Locations text box and then\n" "click this button." @@ -15129,11 +15985,11 @@ msgstr "" "Selectați o poziție în caseta de text Locații, apoi\n" "faceți clic pe acest buton." -#: flatcamTools/ToolOptimal.py:143 +#: flatcamTools/ToolOptimal.py:144 msgid "Other distances" msgstr "Alte distanțe" -#: flatcamTools/ToolOptimal.py:144 +#: flatcamTools/ToolOptimal.py:145 msgid "" "Will display other distances in the Gerber file ordered from\n" "the minimum to the maximum, not including the absolute minimum." @@ -15141,13 +15997,13 @@ msgstr "" "Va afișa alte distanțe din fișierul Gerber ordonate de la\n" "minim până la maxim, neincluzând minimul absolut." -#: flatcamTools/ToolOptimal.py:149 +#: flatcamTools/ToolOptimal.py:150 msgid "Other distances points coordinates" msgstr "Coordonatele altor puncte distanțe" -#: flatcamTools/ToolOptimal.py:150 flatcamTools/ToolOptimal.py:164 -#: flatcamTools/ToolOptimal.py:171 flatcamTools/ToolOptimal.py:188 -#: flatcamTools/ToolOptimal.py:195 +#: flatcamTools/ToolOptimal.py:151 flatcamTools/ToolOptimal.py:165 +#: flatcamTools/ToolOptimal.py:172 flatcamTools/ToolOptimal.py:189 +#: flatcamTools/ToolOptimal.py:196 msgid "" "Other distances and the coordinates for points\n" "where the distance was found." @@ -15155,19 +16011,19 @@ msgstr "" "Alte distanțe și coordonatele pentru puncte\n" "unde a fost găsită distanța." -#: flatcamTools/ToolOptimal.py:163 +#: flatcamTools/ToolOptimal.py:164 msgid "Gerber distances" msgstr "Distanțele Gerber" -#: flatcamTools/ToolOptimal.py:187 +#: flatcamTools/ToolOptimal.py:188 msgid "Points coordinates" msgstr "Coordonatele punctelor" -#: flatcamTools/ToolOptimal.py:219 +#: flatcamTools/ToolOptimal.py:220 msgid "Find Minimum" msgstr "Găsiți Minim" -#: flatcamTools/ToolOptimal.py:221 +#: flatcamTools/ToolOptimal.py:222 msgid "" "Calculate the minimum distance between copper features,\n" "this will allow the determination of the right tool to\n" @@ -15177,11 +16033,11 @@ msgstr "" "acest lucru va permite determinarea uneltei potrivite\n" "pentru izolare sau curatare de cupru." -#: flatcamTools/ToolOptimal.py:346 +#: flatcamTools/ToolOptimal.py:347 msgid "Only Gerber objects can be evaluated." msgstr "Doar obiecte tip Gerber pot fi folosite." -#: flatcamTools/ToolOptimal.py:352 +#: flatcamTools/ToolOptimal.py:353 msgid "" "Optimal Tool. Started to search for the minimum distance between copper " "features." @@ -15189,16 +16045,16 @@ msgstr "" "Unealta Optim. A început să caute distanța minimă între caracteristicile de " "cupru." -#: flatcamTools/ToolOptimal.py:362 +#: flatcamTools/ToolOptimal.py:363 msgid "Optimal Tool. Parsing geometry for aperture" msgstr "Unealta Optim. Analiza geometriei pentru apertura" -#: flatcamTools/ToolOptimal.py:373 +#: flatcamTools/ToolOptimal.py:374 msgid "Optimal Tool. Creating a buffer for the object geometry." msgstr "" "Unealta Optim. Se creeaza o Geometrie la o distanta de geometria obiectului." -#: flatcamTools/ToolOptimal.py:383 +#: flatcamTools/ToolOptimal.py:384 msgid "" "The Gerber object has one Polygon as geometry.\n" "There are no distances between geometry elements to be found." @@ -15206,17 +16062,17 @@ msgstr "" "Obiectul Gerber are un poligon ca geometrie.\n" "Nu există distanțe între elementele de geometrie care sa poata fi gasite." -#: flatcamTools/ToolOptimal.py:388 +#: flatcamTools/ToolOptimal.py:389 msgid "" "Optimal Tool. Finding the distances between each two elements. Iterations" msgstr "" "Unealta Optim. Se caută distanțele dintre fiecare două elemente. Iterații" -#: flatcamTools/ToolOptimal.py:423 +#: flatcamTools/ToolOptimal.py:424 msgid "Optimal Tool. Finding the minimum distance." msgstr "Unealta Optim. Se caută distanța minimă." -#: flatcamTools/ToolOptimal.py:439 +#: flatcamTools/ToolOptimal.py:440 msgid "Optimal Tool. Finished successfully." msgstr "Unealta Optim. Procesul s-a terminat cu succes." @@ -15245,7 +16101,7 @@ msgstr "Deschiderea fişierului PDF a eşuat." msgid "Rendered" msgstr "Randat" -#: flatcamTools/ToolPaint.py:87 +#: flatcamTools/ToolPaint.py:82 msgid "" "Specify the type of object to be painted.\n" "It can be of type: Gerber or Geometry.\n" @@ -15261,7 +16117,7 @@ msgstr "" msgid "Object to be painted." msgstr "Obiect care trebuie pictat." -#: flatcamTools/ToolPaint.py:114 +#: flatcamTools/ToolPaint.py:117 msgid "" "Tools pool from which the algorithm\n" "will pick the ones used for painting." @@ -15269,7 +16125,7 @@ msgstr "" "O suma de unelte din care algoritmul va alege pe acelea\n" "care vor fi folosite pentru 'pictare'." -#: flatcamTools/ToolPaint.py:129 +#: flatcamTools/ToolPaint.py:134 msgid "" "This is the Tool Number.\n" "Painting will start with the tool with the biggest diameter,\n" @@ -15285,7 +16141,7 @@ msgstr "" "Doar uneltele care efectiv au creat geometrie vor fi prezente in obiectul\n" "final. Aceasta deaorece unele unelte nu vor putea genera geometrie." -#: flatcamTools/ToolPaint.py:141 +#: flatcamTools/ToolPaint.py:146 msgid "" "The Tool Type (TT) can be:
- Circular with 1 ... 4 teeth -> it is " "informative only. Being circular,
the cut width in material is exactly " @@ -15308,51 +16164,7 @@ msgstr "" "unealtă< din coloana tabelei de Unelte.
Alegerea tipului V-Shape " "va selecta automat Tipul Operaţiei ca fiind Izolare." -#: flatcamTools/ToolPaint.py:178 -msgid "Diameter for the new tool." -msgstr "Diametrul pt noua unealtă." - -#: flatcamTools/ToolPaint.py:253 -msgid "" -"Algorithm for painting:\n" -"- Standard: Fixed step inwards.\n" -"- Seed-based: Outwards from seed.\n" -"- Line-based: Parallel lines." -msgstr "" -"Algoritm pentru pictură:\n" -"- Standard: pas fix spre interior.\n" -"- Semințe: înspre exterior porning de la punctul sămanță.\n" -"- Linii: linii paralele." - -#: flatcamTools/ToolPaint.py:283 -msgid "" -"If checked, use 'rest machining'.\n" -"Basically it will clear copper outside PCB features,\n" -"using the biggest tool and continue with the next tools,\n" -"from bigger to smaller, to clear areas of copper that\n" -"could not be cleared by previous tool, until there is\n" -"no more copper to clear or there are no more tools.\n" -"\n" -"If not checked, use the standard algorithm." -msgstr "" -"Daca este bifat, foloste 'rest machining'.\n" -"Mai exact, se va curăța cuprul din afara traseelor,\n" -"folosind mai intai unealta cu diametrul cel mai mare\n" -"apoi folosindu-se progresiv unelte cu diametrul tot\n" -"mai mic, din cele disponibile in tabela de unelte, pt a\n" -"curăța zonele care nu s-au putut curăța cu unealta\n" -"precedenta.\n" -"Daca nu este bifat, foloseşte algoritmul standard." - -#: flatcamTools/ToolPaint.py:307 -msgid "Polygon Selection" -msgstr "Selecție Poligon" - -#: flatcamTools/ToolPaint.py:309 -msgid "All Polygons" -msgstr "Toate Poligoanele" - -#: flatcamTools/ToolPaint.py:328 +#: flatcamTools/ToolPaint.py:498 msgid "" "The type of FlatCAM object to be used as paint reference.\n" "It can be Gerber, Excellon or Geometry." @@ -15360,11 +16172,7 @@ msgstr "" "Tipul de obiect FlatCAM care trebuie utilizat ca referință pt. pictare.\n" "Poate fi Gerber, Excellon sau Geometry." -#: flatcamTools/ToolPaint.py:353 -msgid "Create Paint Geometry" -msgstr "Crează un obiect Geometrie tip 'Paint'" - -#: flatcamTools/ToolPaint.py:355 +#: flatcamTools/ToolPaint.py:539 msgid "" "- 'Area Selection' - left mouse click to start selection of the area to be " "painted.\n" @@ -15382,72 +16190,98 @@ msgstr "" "- „Obiect de referință” - va face o curățare fără cupru în zona specificată " "de un alt obiect." -#: flatcamTools/ToolPaint.py:973 -msgid "Paint Tool. Reading parameters." -msgstr "Unealta Paint. Se citesc parametrii." - -#: flatcamTools/ToolPaint.py:988 +#: flatcamTools/ToolPaint.py:1381 #, python-format msgid "Could not retrieve object: %s" msgstr "Nu s-a putut incărca obiectul: %s" -#: flatcamTools/ToolPaint.py:1002 +#: flatcamTools/ToolPaint.py:1391 msgid "Can't do Paint on MultiGeo geometries" msgstr "Nu se poate face 'pictare' pe geometrii MultiGeo" -#: flatcamTools/ToolPaint.py:1035 +#: flatcamTools/ToolPaint.py:1421 msgid "Click on a polygon to paint it." msgstr "Faceți clic pe un poligon pentru a-l picta." -#: flatcamTools/ToolPaint.py:1054 +#: flatcamTools/ToolPaint.py:1441 msgid "Click the start point of the paint area." msgstr "Faceți clic pe punctul de pornire al zonei de pictat." -#: flatcamTools/ToolPaint.py:1122 +#: flatcamTools/ToolPaint.py:1506 msgid "Click to add next polygon or right click to start painting." msgstr "" "Faceți clic pentru a adăuga următorul poligon sau faceți clic dreapta pentru " "a începe Paint." -#: flatcamTools/ToolPaint.py:1135 +#: flatcamTools/ToolPaint.py:1519 msgid "Click to add/remove next polygon or right click to start painting." msgstr "" "Faceți clic pentru a adăuga / elimina următorul poligon sau faceți clic " "dreapta pentru a începe Paint." -#: flatcamTools/ToolPaint.py:1344 flatcamTools/ToolPaint.py:1347 -#: flatcamTools/ToolPaint.py:1349 flatcamTools/ToolPaint.py:1987 -#: flatcamTools/ToolPaint.py:1991 flatcamTools/ToolPaint.py:1994 -#: flatcamTools/ToolPaint.py:2276 flatcamTools/ToolPaint.py:2281 -#: flatcamTools/ToolPaint.py:2284 flatcamTools/ToolPaint.py:2458 -#: flatcamTools/ToolPaint.py:2465 -msgid "Paint Tool." -msgstr "Unealta Paint." +#: flatcamTools/ToolPaint.py:2013 +msgid "Painting polygon with method: lines." +msgstr "Se pictează poligonul cu metoda: linii." -#: flatcamTools/ToolPaint.py:1344 flatcamTools/ToolPaint.py:1347 -#: flatcamTools/ToolPaint.py:1349 -msgid "Normal painting polygon task started." -msgstr "Taskul de pictare normal a unui polygon a inceput." +#: flatcamTools/ToolPaint.py:2025 +msgid "Failed. Painting polygon with method: seed." +msgstr "Esuat. Se pictează poligonul cu metoda: sămantă." -#: flatcamTools/ToolPaint.py:1345 flatcamTools/ToolPaint.py:1706 -#: flatcamTools/ToolPaint.py:1988 flatcamTools/ToolPaint.py:2278 -#: flatcamTools/ToolPaint.py:2460 -msgid "Buffering geometry..." -msgstr "Crează o geometrie de tipul Bufer..." +#: flatcamTools/ToolPaint.py:2036 +msgid "Failed. Painting polygon with method: standard." +msgstr "Esuat. Se picteaza poligonul cu metoda: standard." -#: flatcamTools/ToolPaint.py:1367 -msgid "No polygon found." -msgstr "Nu s-a gasit nici-un poligon." - -#: flatcamTools/ToolPaint.py:1401 -msgid "Painting polygon..." -msgstr "Se 'pictează' un poligon..." - -#: flatcamTools/ToolPaint.py:1448 +#: flatcamTools/ToolPaint.py:2052 msgid "Geometry could not be painted completely" msgstr "Geometria nu a fost posibil să fie 'pictată' complet" -#: flatcamTools/ToolPaint.py:1481 +#: flatcamTools/ToolPaint.py:2081 flatcamTools/ToolPaint.py:2084 +#: flatcamTools/ToolPaint.py:2092 flatcamTools/ToolPaint.py:2634 +#: flatcamTools/ToolPaint.py:2638 flatcamTools/ToolPaint.py:2641 +#: flatcamTools/ToolPaint.py:3448 flatcamTools/ToolPaint.py:3452 +#: flatcamTools/ToolPaint.py:3455 +msgid "Paint Tool." +msgstr "Unealta Paint." + +#: flatcamTools/ToolPaint.py:2081 flatcamTools/ToolPaint.py:2084 +#: flatcamTools/ToolPaint.py:2092 +msgid "Normal painting polygon task started." +msgstr "Taskul de pictare normal a unui polygon a inceput." + +#: flatcamTools/ToolPaint.py:2082 flatcamTools/ToolPaint.py:2423 +#: flatcamTools/ToolPaint.py:2635 flatcamTools/ToolPaint.py:3085 +#: flatcamTools/ToolPaint.py:3449 +msgid "Buffering geometry..." +msgstr "Crează o geometrie de tipul Bufer..." + +#: flatcamTools/ToolPaint.py:2105 +msgid "No polygon found." +msgstr "Nu s-a gasit nici-un poligon." + +#: flatcamTools/ToolPaint.py:2135 +msgid "Painting polygon..." +msgstr "Se 'pictează' un poligon..." + +#: flatcamTools/ToolPaint.py:2144 flatcamTools/ToolPaint.py:2466 +#: flatcamTools/ToolPaint.py:2674 flatcamTools/ToolPaint.py:3132 +#: flatcamTools/ToolPaint.py:3492 +msgid "Painting with tool diameter = " +msgstr "Pictand cu o unealtă cu diametrul = " + +#: flatcamTools/ToolPaint.py:2145 flatcamTools/ToolPaint.py:2469 +#: flatcamTools/ToolPaint.py:2677 flatcamTools/ToolPaint.py:3135 +#: flatcamTools/ToolPaint.py:3495 +msgid "started" +msgstr "a inceput" + +#: flatcamTools/ToolPaint.py:2170 flatcamTools/ToolPaint.py:2494 +#: flatcamTools/ToolPaint.py:2703 flatcamTools/ToolPaint.py:3161 +#: flatcamTools/ToolPaint.py:3524 +msgid "Margin parameter too big. Tool is not used" +msgstr "Parametrul Margine este prea mare. Unealta nu este folosită" + +#: flatcamTools/ToolPaint.py:2210 flatcamTools/ToolPaint.py:2564 +#: flatcamTools/ToolPaint.py:3377 msgid "" "Could not do Paint. Try a different combination of parameters. Or a " "different strategy of paint" @@ -15455,9 +16289,9 @@ msgstr "" "Nu s-a putut face operatia de 'pictare'. Incearcă o combinaţie diferita de " "parametri. Sau o strategie diferita de 'pictare'" -#: flatcamTools/ToolPaint.py:1533 flatcamTools/ToolPaint.py:1967 -#: flatcamTools/ToolPaint.py:2117 flatcamTools/ToolPaint.py:2438 -#: flatcamTools/ToolPaint.py:2592 +#: flatcamTools/ToolPaint.py:2268 flatcamTools/ToolPaint.py:2614 +#: flatcamTools/ToolPaint.py:2955 flatcamTools/ToolPaint.py:3428 +#: flatcamTools/ToolPaint.py:3771 msgid "" "There is no Painting Geometry in the file.\n" "Usually it means that the tool diameter is too big for the painted " @@ -15469,46 +16303,54 @@ msgstr "" "geometrice.\n" "Schimbă parametrii de 'pictare' și încearcă din nou." -#: flatcamTools/ToolPaint.py:1539 +#: flatcamTools/ToolPaint.py:2300 +msgid "Paint Single failed." +msgstr "Pictarea unui polygon a esuat." + +#: flatcamTools/ToolPaint.py:2306 msgid "Paint Single Done." msgstr "Pictarea unui polygon efectuată." -#: flatcamTools/ToolPaint.py:1571 flatcamTools/ToolPaint.py:2145 -#: flatcamTools/ToolPaint.py:2620 +#: flatcamTools/ToolPaint.py:2308 flatcamTools/ToolPaint.py:2983 +#: flatcamTools/ToolPaint.py:3799 msgid "Polygon Paint started ..." msgstr "Paint pt poligon a inceput ..." -#: flatcamTools/ToolPaint.py:1623 flatcamTools/ToolPaint.py:2207 +#: flatcamTools/ToolPaint.py:2347 flatcamTools/ToolPaint.py:3023 msgid "Painting polygons..." msgstr "Se 'pictează' poligoane..." -#: flatcamTools/ToolPaint.py:1705 flatcamTools/ToolPaint.py:1708 -#: flatcamTools/ToolPaint.py:1710 +#: flatcamTools/ToolPaint.py:2422 flatcamTools/ToolPaint.py:2425 +#: flatcamTools/ToolPaint.py:2427 msgid "Paint Tool. Normal painting all task started." msgstr "Unealta Paint. Taskul de pictare a tuturor poligoanelor a inceput." -#: flatcamTools/ToolPaint.py:1744 flatcamTools/ToolPaint.py:2023 -#: flatcamTools/ToolPaint.py:2325 flatcamTools/ToolPaint.py:2501 -msgid "Painting with tool diameter = " -msgstr "Pictand cu o unealtă cu diametrul = " - -#: flatcamTools/ToolPaint.py:1747 flatcamTools/ToolPaint.py:2026 -#: flatcamTools/ToolPaint.py:2328 flatcamTools/ToolPaint.py:2504 -msgid "started" -msgstr "a inceput" - -#: flatcamTools/ToolPaint.py:1976 +#: flatcamTools/ToolPaint.py:2623 msgid "Paint All Done." msgstr "Pictarea Tuturor poligoanelor efectuată." -#: flatcamTools/ToolPaint.py:1987 flatcamTools/ToolPaint.py:1991 -#: flatcamTools/ToolPaint.py:1994 +#: flatcamTools/ToolPaint.py:2634 flatcamTools/ToolPaint.py:2638 +#: flatcamTools/ToolPaint.py:2641 msgid "Rest machining painting all task started." msgstr "" "Taskul de pictare prin prelucrare 'rest' a tuturor poligoanelor a inceput." -#: flatcamTools/ToolPaint.py:2072 flatcamTools/ToolPaint.py:2388 -#: flatcamTools/ToolPaint.py:2548 +#: flatcamTools/ToolPaint.py:2862 flatcamTools/ToolPaint.py:3334 +#: flatcamTools/ToolPaint.py:3683 +msgid "Painting polygons with method: lines." +msgstr "Se pictează poligoane aflat icu metoda: linii." + +#: flatcamTools/ToolPaint.py:2875 flatcamTools/ToolPaint.py:3347 +#: flatcamTools/ToolPaint.py:3695 +msgid "Failed. Painting polygons with method: seed." +msgstr "Esuat. Se pictează poligoanele cu metoda: sămantă." + +#: flatcamTools/ToolPaint.py:2887 flatcamTools/ToolPaint.py:3359 +#: flatcamTools/ToolPaint.py:3707 +msgid "Failed. Painting polygons with method: standard." +msgstr "Esuat. Se pictează poligoanele cu metoda: standard." + +#: flatcamTools/ToolPaint.py:2904 flatcamTools/ToolPaint.py:3723 msgid "" "Could not do Paint All. Try a different combination of parameters. Or a " "different Method of paint" @@ -15516,35 +16358,30 @@ msgstr "" "Nu s-a efectuat op. 'Paint' pt toate poligoanele. Incearcă o combinaţie " "diferită de parametri. Sau încearcă o alta metoda de 'pictat'" -#: flatcamTools/ToolPaint.py:2126 flatcamTools/ToolPaint.py:2601 +#: flatcamTools/ToolPaint.py:2964 flatcamTools/ToolPaint.py:3780 msgid "Paint All with Rest-Machining done." msgstr "'Paint' pentru toate poligoanele cu strategia Rest a fost efectuată." -#: flatcamTools/ToolPaint.py:2277 flatcamTools/ToolPaint.py:2281 -#: flatcamTools/ToolPaint.py:2284 -msgid "Normal painting area task started." -msgstr "Taskul de pictare normal a unei arii a inceput." +#: flatcamTools/ToolPaint.py:3084 flatcamTools/ToolPaint.py:3087 +#: flatcamTools/ToolPaint.py:3089 +msgid "Paint Tool. Normal painting area task started." +msgstr "Unealta Paint. Taskul de pictare a unei arii a inceput." -#: flatcamTools/ToolPaint.py:2447 +#: flatcamTools/ToolPaint.py:3437 msgid "Paint Area Done." msgstr "Paint pt o zona efectuata." -#: flatcamTools/ToolPaint.py:2459 flatcamTools/ToolPaint.py:2465 +#: flatcamTools/ToolPaint.py:3448 flatcamTools/ToolPaint.py:3452 +#: flatcamTools/ToolPaint.py:3455 msgid "Rest machining painting area task started." msgstr "" "Taskul de pictare a unei arii cu strategia de masinare 'rest' a inceput." -#: flatcamTools/ToolPaint.py:2462 -msgid "Paint Tool. Rest machining painting area task started." -msgstr "" -"Unealta Paint. Taskul de pictare a unei arii cu strategia de masinare 'rest' " -"a inceput." - #: flatcamTools/ToolPanelize.py:34 msgid "Panelize PCB" msgstr "Panelizează PCB" -#: flatcamTools/ToolPanelize.py:68 +#: flatcamTools/ToolPanelize.py:56 msgid "" "Specify the type of object to be panelized\n" "It can be of type: Gerber, Excellon or Geometry.\n" @@ -15556,7 +16393,7 @@ msgstr "" "Selectia facuta aici va dicta tipul de obiecte care se vor\n" "regasi in combobox-ul >Obiect<." -#: flatcamTools/ToolPanelize.py:83 +#: flatcamTools/ToolPanelize.py:89 msgid "" "Object to be panelized. This means that it will\n" "be duplicated in an array of rows and columns." @@ -15565,11 +16402,11 @@ msgstr "" "Acesta va fi multiplicat intr-o arie\n" "de linii și coloane." -#: flatcamTools/ToolPanelize.py:96 +#: flatcamTools/ToolPanelize.py:102 msgid "Penelization Reference" msgstr "Referintă panelizare" -#: flatcamTools/ToolPanelize.py:98 +#: flatcamTools/ToolPanelize.py:104 msgid "" "Choose the reference for panelization:\n" "- Object = the bounding box of a different object\n" @@ -15591,11 +16428,11 @@ msgstr "" "referintă,\n" "prin urmare mentinand obiectele paenlizate in sincronizare unul cu altul." -#: flatcamTools/ToolPanelize.py:121 +#: flatcamTools/ToolPanelize.py:125 msgid "Box Type" msgstr "Tip container" -#: flatcamTools/ToolPanelize.py:123 +#: flatcamTools/ToolPanelize.py:127 msgid "" "Specify the type of object to be used as an container for\n" "panelization. It can be: Gerber or Geometry type.\n" @@ -15607,7 +16444,7 @@ msgstr "" "Selectia facuta aici va dicta tipul de obiecte care se vor\n" "regasi in combobox-ul >Container<." -#: flatcamTools/ToolPanelize.py:138 +#: flatcamTools/ToolPanelize.py:141 msgid "" "The actual object that is used a container for the\n" " selected object that is to be panelized." @@ -15615,11 +16452,11 @@ msgstr "" "Obiectul care este folosit ca și container \n" "pt obiectul care va fi panelizat." -#: flatcamTools/ToolPanelize.py:144 +#: flatcamTools/ToolPanelize.py:147 msgid "Panel Data" msgstr "Date panel" -#: flatcamTools/ToolPanelize.py:146 +#: flatcamTools/ToolPanelize.py:149 msgid "" "This informations will shape the resulting panel.\n" "The number of rows and columns will set how many\n" @@ -15635,7 +16472,7 @@ msgstr "" "Spatierile sunt de fapt distante intre oricare două elemente ale \n" "ariei panelului." -#: flatcamTools/ToolPanelize.py:205 +#: flatcamTools/ToolPanelize.py:208 msgid "" "Choose the type of object for the panel object:\n" "- Geometry\n" @@ -15645,15 +16482,15 @@ msgstr "" "- Geometrie\n" "-Gerber" -#: flatcamTools/ToolPanelize.py:213 +#: flatcamTools/ToolPanelize.py:216 msgid "Constrain panel within" msgstr "Mentine panelul in" -#: flatcamTools/ToolPanelize.py:249 +#: flatcamTools/ToolPanelize.py:252 msgid "Panelize Object" msgstr "Panelizează obiectul" -#: flatcamTools/ToolPanelize.py:251 flatcamTools/ToolRulesCheck.py:492 +#: flatcamTools/ToolPanelize.py:254 flatcamTools/ToolRulesCheck.py:501 msgid "" "Panelize the specified object around the specified box.\n" "In other words it creates multiple copies of the source object,\n" @@ -15663,33 +16500,33 @@ msgstr "" "Cu alte cuvinte se crează copii multiple ale obiectului sursa,\n" "aranjate intr-o arie 2D de linii și coloane." -#: flatcamTools/ToolPanelize.py:319 +#: flatcamTools/ToolPanelize.py:322 msgid "Panel. Tool" msgstr "Unealta Panel" -#: flatcamTools/ToolPanelize.py:448 +#: flatcamTools/ToolPanelize.py:460 msgid "Columns or Rows are zero value. Change them to a positive integer." msgstr "" "Val. coloane sau linii este zero. Schimbă aceasta val. intr-un număr pozitiv " "intreg." -#: flatcamTools/ToolPanelize.py:485 +#: flatcamTools/ToolPanelize.py:497 msgid "Generating panel ... " msgstr "Se generează Panel-ul… " -#: flatcamTools/ToolPanelize.py:768 +#: flatcamTools/ToolPanelize.py:777 msgid "Generating panel ... Adding the Gerber code." msgstr "Generarea panelului ... Adăugarea codului Gerber." -#: flatcamTools/ToolPanelize.py:779 +#: flatcamTools/ToolPanelize.py:788 msgid "Generating panel... Spawning copies" msgstr "Generarea panelului ... Se fac copii" -#: flatcamTools/ToolPanelize.py:786 +#: flatcamTools/ToolPanelize.py:795 msgid "Panel done..." msgstr "Panel executat ..." -#: flatcamTools/ToolPanelize.py:789 +#: flatcamTools/ToolPanelize.py:798 #, python-brace-format msgid "" "{text} Too big for the constrain area. Final panel has {col} columns and " @@ -15698,7 +16535,7 @@ msgstr "" "{text} Prea mare pt aria desemnată. Panelul final are {col} coloane si {row} " "linii" -#: flatcamTools/ToolPanelize.py:798 +#: flatcamTools/ToolPanelize.py:807 msgid "Panel created successfully." msgstr "Panel creat cu succes." @@ -15772,7 +16609,7 @@ msgstr "Fără supresie" #: flatcamTools/ToolPcbWizard.py:114 msgid "Zeros supp." -msgstr "Supresie Zerouri" +msgstr "Supresie Zero" #: flatcamTools/ToolPcbWizard.py:116 msgid "" @@ -15843,164 +16680,215 @@ msgstr "Fisierul .INF tip PCBWizard a fost incărcat." msgid "Main PcbWizard Excellon file loaded." msgstr "Fişierul Excellon tip PCBWizard a fost incărcat." -#: flatcamTools/ToolPcbWizard.py:431 +#: flatcamTools/ToolPcbWizard.py:428 msgid "Cannot parse file" msgstr "Nu se poate parsa fişierul" -#: flatcamTools/ToolPcbWizard.py:456 +#: flatcamTools/ToolPcbWizard.py:452 msgid "Importing Excellon." msgstr "Excellon in curs de import." -#: flatcamTools/ToolPcbWizard.py:463 +#: flatcamTools/ToolPcbWizard.py:459 msgid "Import Excellon file failed." msgstr "Fişierul Excellon nu a fost posibil să fie importat." -#: flatcamTools/ToolPcbWizard.py:471 +#: flatcamTools/ToolPcbWizard.py:467 msgid "Imported" msgstr "Importat" -#: flatcamTools/ToolPcbWizard.py:475 +#: flatcamTools/ToolPcbWizard.py:471 msgid "Excellon merging is in progress. Please wait..." msgstr "Fuziunea fisiere Excellon este in curs. Vă rugăm aşteptați ..." -#: flatcamTools/ToolPcbWizard.py:478 +#: flatcamTools/ToolPcbWizard.py:474 msgid "The imported Excellon file is None." msgstr "Fişierul Excellon importat este gol." -#: flatcamTools/ToolProperties.py:119 -msgid "Properties Tool was not displayed. No object selected." -msgstr "" -"Unealta Proprietati nu a fost afișată. Nici-un obiect nu este selectat." - -#: flatcamTools/ToolProperties.py:134 +#: flatcamTools/ToolProperties.py:131 msgid "Object Properties are displayed." msgstr "Proprietatile obiectului sunt afisate in Tab-ul Unealta." -#: flatcamTools/ToolProperties.py:135 +#: flatcamTools/ToolProperties.py:136 msgid "Properties Tool" msgstr "Unealta Proprietati" -#: flatcamTools/ToolProperties.py:149 +#: flatcamTools/ToolProperties.py:150 msgid "TYPE" msgstr "TIP" -#: flatcamTools/ToolProperties.py:150 +#: flatcamTools/ToolProperties.py:151 msgid "NAME" msgstr "NUME" -#: flatcamTools/ToolProperties.py:151 +#: flatcamTools/ToolProperties.py:153 msgid "Dimensions" msgstr "Dimensiuni" -#: flatcamTools/ToolProperties.py:165 -msgid "Others" -msgstr "Alții" - -#: flatcamTools/ToolProperties.py:172 +#: flatcamTools/ToolProperties.py:181 msgid "Geo Type" msgstr "Tip Geo" -#: flatcamTools/ToolProperties.py:173 +#: flatcamTools/ToolProperties.py:184 msgid "Single-Geo" msgstr "Geo-Unică" -#: flatcamTools/ToolProperties.py:173 +#: flatcamTools/ToolProperties.py:185 msgid "Multi-Geo" msgstr "Geo-Multi" -#: flatcamTools/ToolProperties.py:181 +#: flatcamTools/ToolProperties.py:196 msgid "Calculating dimensions ... Please wait." msgstr "Se calculează dimensiunile ... Aşteaptă." -#: flatcamTools/ToolProperties.py:321 flatcamTools/ToolProperties.py:325 -#: flatcamTools/ToolProperties.py:327 +#: flatcamTools/ToolProperties.py:339 flatcamTools/ToolProperties.py:343 +#: flatcamTools/ToolProperties.py:345 msgid "Inch" msgstr "Inch" -#: flatcamTools/ToolProperties.py:321 flatcamTools/ToolProperties.py:326 -#: flatcamTools/ToolProperties.py:328 +#: flatcamTools/ToolProperties.py:339 flatcamTools/ToolProperties.py:344 +#: flatcamTools/ToolProperties.py:346 msgid "Metric" msgstr "Metric" -#: flatcamTools/ToolProperties.py:401 flatcamTools/ToolProperties.py:459 +#: flatcamTools/ToolProperties.py:421 flatcamTools/ToolProperties.py:486 msgid "Drills number" msgstr "Numărul de găuri" -#: flatcamTools/ToolProperties.py:402 flatcamTools/ToolProperties.py:461 +#: flatcamTools/ToolProperties.py:422 flatcamTools/ToolProperties.py:488 msgid "Slots number" msgstr "Numărul de sloturi" -#: flatcamTools/ToolProperties.py:404 +#: flatcamTools/ToolProperties.py:424 msgid "Drills total number:" msgstr "Număr total de gauri:" -#: flatcamTools/ToolProperties.py:405 +#: flatcamTools/ToolProperties.py:425 msgid "Slots total number:" msgstr "Număr total de sloturi:" -#: flatcamTools/ToolProperties.py:411 flatcamTools/ToolProperties.py:426 -#: flatcamTools/ToolProperties.py:429 flatcamTools/ToolProperties.py:432 -#: flatcamTools/ToolProperties.py:456 +#: flatcamTools/ToolProperties.py:452 flatcamTools/ToolProperties.py:455 +#: flatcamTools/ToolProperties.py:458 flatcamTools/ToolProperties.py:483 msgid "Present" msgstr "Prezent" -#: flatcamTools/ToolProperties.py:427 flatcamTools/ToolProperties.py:457 +#: flatcamTools/ToolProperties.py:453 flatcamTools/ToolProperties.py:484 msgid "Solid Geometry" msgstr "Geometrie Solidă" -#: flatcamTools/ToolProperties.py:430 +#: flatcamTools/ToolProperties.py:456 msgid "GCode Text" msgstr "Text GCode" -#: flatcamTools/ToolProperties.py:433 +#: flatcamTools/ToolProperties.py:459 msgid "GCode Geometry" msgstr "Geometrie GCode" -#: flatcamTools/ToolProperties.py:435 +#: flatcamTools/ToolProperties.py:462 msgid "Data" msgstr "Date" -#: flatcamTools/ToolProperties.py:468 +#: flatcamTools/ToolProperties.py:495 msgid "Depth of Cut" msgstr "Adâncimea de Tăiere" -#: flatcamTools/ToolProperties.py:480 +#: flatcamTools/ToolProperties.py:507 msgid "Clearance Height" msgstr "Înălțime Sigură" -#: flatcamTools/ToolProperties.py:512 +#: flatcamTools/ToolProperties.py:539 msgid "Routing time" msgstr "Timpul de rutare" -#: flatcamTools/ToolProperties.py:519 +#: flatcamTools/ToolProperties.py:546 msgid "Travelled distance" msgstr "Distanța parcursă" -#: flatcamTools/ToolProperties.py:560 +#: flatcamTools/ToolProperties.py:564 msgid "Width" msgstr "Lătime" -#: flatcamTools/ToolProperties.py:566 flatcamTools/ToolProperties.py:574 +#: flatcamTools/ToolProperties.py:570 flatcamTools/ToolProperties.py:578 msgid "Box Area" msgstr "Arie pătratică" -#: flatcamTools/ToolProperties.py:569 flatcamTools/ToolProperties.py:577 +#: flatcamTools/ToolProperties.py:573 flatcamTools/ToolProperties.py:581 msgid "Convex_Hull Area" msgstr "Arie convexă" -#: flatcamTools/ToolProperties.py:583 flatcamTools/ToolProperties.py:585 +#: flatcamTools/ToolProperties.py:588 flatcamTools/ToolProperties.py:591 msgid "Copper Area" msgstr "Aria de Cupru" -#: flatcamTools/ToolQRCode.py:79 +#: flatcamTools/ToolPunchGerber.py:30 flatcamTools/ToolPunchGerber.py:323 +msgid "Punch Gerber" +msgstr "Punctează Gerber" + +#: flatcamTools/ToolPunchGerber.py:65 +msgid "Gerber into which to punch holes" +msgstr "Obiect Gerber pentru Punctare găuri" + +#: flatcamTools/ToolPunchGerber.py:85 +msgid "ALL" +msgstr "TOATE" + +#: flatcamTools/ToolPunchGerber.py:166 +msgid "" +"Remove the geometry of Excellon from the Gerber to create the holes in pads." +msgstr "" +"Îndepărtați geometria Excellon din obiectul Gerber pentru a crea găurile din " +"pad-uri." + +#: flatcamTools/ToolPunchGerber.py:325 +msgid "" +"Create a Gerber object from the selected object, within\n" +"the specified box." +msgstr "" +"Creează un obiect Gerber din obiectul selectat, in cadrul\n" +"formei 'cutie' specificate." + +#: flatcamTools/ToolPunchGerber.py:425 +msgid "Punch Tool" +msgstr "Unealta Punctare" + +#: flatcamTools/ToolPunchGerber.py:599 +msgid "The value of the fixed diameter is 0.0. Aborting." +msgstr "Valoarea pentru diametrul fix ste 0.0. Renuntăm." + +#: flatcamTools/ToolPunchGerber.py:607 +msgid "" +" Could not generate punched hole Gerber because the punch hole sizeis bigger " +"than some of the apertures in the Gerber object." +msgstr "" +" Nu a putut genera un obiect Gerber cu găuri punctate, deoarece dimensiunea " +"găurii de perforare este mai mare decât unele dintre aperturile din obiectul " +"Gerber." + +#: flatcamTools/ToolPunchGerber.py:619 +msgid "" +"Could not generate punched hole Gerber because the punch hole sizeis bigger " +"than some of the apertures in the Gerber object." +msgstr "" +"Nu s-a putut genera un obiect Gerber cu găuri punctate, deoarece dimensiunea " +"găurii de perforare este mai mare decât unele dintre aperturile din obiectul " +"Gerber." + +#: flatcamTools/ToolPunchGerber.py:656 +msgid "" +"Could not generate punched hole Gerber because the newly created object " +"geometry is the same as the one in the source object geometry..." +msgstr "" +"Nu s-a putut genera un obiect cu găuri puctate, deoarece geometria " +"obiectului nou creat este aceeași cu cea din geometria obiectului sursă ..." + +#: flatcamTools/ToolQRCode.py:80 msgid "Gerber Object to which the QRCode will be added." msgstr "Obiect Gerber la care se va adăuga codul QR." -#: flatcamTools/ToolQRCode.py:92 +#: flatcamTools/ToolQRCode.py:93 msgid "QRCode Parameters" msgstr "Parametrii QRCode" -#: flatcamTools/ToolQRCode.py:94 +#: flatcamTools/ToolQRCode.py:95 msgid "The parameters used to shape the QRCode." msgstr "Parametrii utilizați pentru modelarea codului QR." @@ -16044,31 +16932,27 @@ msgstr "Inserați codul QR" msgid "Create the QRCode object." msgstr "Creați obiectul QRCode." -#: flatcamTools/ToolQRCode.py:413 flatcamTools/ToolQRCode.py:748 -#: flatcamTools/ToolQRCode.py:797 +#: flatcamTools/ToolQRCode.py:415 flatcamTools/ToolQRCode.py:750 +#: flatcamTools/ToolQRCode.py:799 msgid "Cancelled. There is no QRCode Data in the text box." msgstr "Anulat. Nu există date QRCode în caseta de text." -#: flatcamTools/ToolQRCode.py:432 +#: flatcamTools/ToolQRCode.py:434 msgid "Generating QRCode geometry" msgstr "Generarea geometriei QRCode" -#: flatcamTools/ToolQRCode.py:472 +#: flatcamTools/ToolQRCode.py:474 msgid "Click on the Destination point ..." msgstr "Click pe punctul de Destinaţie ..." -#: flatcamTools/ToolQRCode.py:587 +#: flatcamTools/ToolQRCode.py:589 msgid "QRCode Tool done." msgstr "Unealta QRCode efectuata." -#: flatcamTools/ToolQRCode.py:780 flatcamTools/ToolQRCode.py:784 +#: flatcamTools/ToolQRCode.py:782 flatcamTools/ToolQRCode.py:786 msgid "Export PNG" msgstr "Exporta PNG" -#: flatcamTools/ToolQRCode.py:789 -msgid " Export PNG cancelled." -msgstr " Exportul PNG a fost anulat." - #: flatcamTools/ToolRulesCheck.py:33 msgid "Check Rules" msgstr "Verificați regulile" @@ -16081,77 +16965,77 @@ msgstr "Fișiere Gerber" msgid "Gerber objects for which to check rules." msgstr "Obiecte Gerber pentru care trebuie verificate regulile." -#: flatcamTools/ToolRulesCheck.py:77 +#: flatcamTools/ToolRulesCheck.py:78 msgid "Top" msgstr "Top" -#: flatcamTools/ToolRulesCheck.py:79 +#: flatcamTools/ToolRulesCheck.py:80 msgid "The Top Gerber Copper object for which rules are checked." msgstr "Obiectul Top Gerber cupru pentru care sunt verificate regulile." -#: flatcamTools/ToolRulesCheck.py:94 +#: flatcamTools/ToolRulesCheck.py:96 msgid "Bottom" msgstr "Bottom" -#: flatcamTools/ToolRulesCheck.py:96 +#: flatcamTools/ToolRulesCheck.py:98 msgid "The Bottom Gerber Copper object for which rules are checked." msgstr "Obiectul Bottom Gerber cupru pentru care sunt verificate regulile." -#: flatcamTools/ToolRulesCheck.py:111 +#: flatcamTools/ToolRulesCheck.py:114 msgid "SM Top" msgstr "SM Top" -#: flatcamTools/ToolRulesCheck.py:113 +#: flatcamTools/ToolRulesCheck.py:116 msgid "The Top Gerber Solder Mask object for which rules are checked." msgstr "" "Obiectul Top (superior) Gerber Solder Mask pentru care sunt verificate " "regulile." -#: flatcamTools/ToolRulesCheck.py:128 +#: flatcamTools/ToolRulesCheck.py:132 msgid "SM Bottom" msgstr "SM Bottom" -#: flatcamTools/ToolRulesCheck.py:130 +#: flatcamTools/ToolRulesCheck.py:134 msgid "The Bottom Gerber Solder Mask object for which rules are checked." msgstr "" "Obiectul Bottom (inferior) Gerber Solder Mask pentru care sunt verificate " "regulile." -#: flatcamTools/ToolRulesCheck.py:145 +#: flatcamTools/ToolRulesCheck.py:150 msgid "Silk Top" msgstr "Silk Top" -#: flatcamTools/ToolRulesCheck.py:147 +#: flatcamTools/ToolRulesCheck.py:152 msgid "The Top Gerber Silkscreen object for which rules are checked." msgstr "Obiectul Top Gerber Silkscreen pentru care sunt verificate regulile." -#: flatcamTools/ToolRulesCheck.py:162 +#: flatcamTools/ToolRulesCheck.py:168 msgid "Silk Bottom" msgstr "Silk Bottom" -#: flatcamTools/ToolRulesCheck.py:164 +#: flatcamTools/ToolRulesCheck.py:170 msgid "The Bottom Gerber Silkscreen object for which rules are checked." msgstr "" "Obiectul Bottom Gerber Silkscreen pentru care sunt verificate regulile." -#: flatcamTools/ToolRulesCheck.py:181 +#: flatcamTools/ToolRulesCheck.py:188 msgid "The Gerber Outline (Cutout) object for which rules are checked." msgstr "" "Obiectul Gerber Outline (decupaj) pentru care sunt verificate regulile." -#: flatcamTools/ToolRulesCheck.py:192 +#: flatcamTools/ToolRulesCheck.py:199 msgid "Excellon Objects" msgstr "Obiecte Excellon" -#: flatcamTools/ToolRulesCheck.py:194 +#: flatcamTools/ToolRulesCheck.py:201 msgid "Excellon objects for which to check rules." msgstr "Obiecte Excellon pentru care trebuie verificate regulile." -#: flatcamTools/ToolRulesCheck.py:205 +#: flatcamTools/ToolRulesCheck.py:213 msgid "Excellon 1" msgstr "Excellon 1" -#: flatcamTools/ToolRulesCheck.py:207 +#: flatcamTools/ToolRulesCheck.py:215 msgid "" "Excellon object for which to check rules.\n" "Holds the plated holes or a general Excellon file content." @@ -16159,11 +17043,11 @@ msgstr "" "Obiect Excellon pentru care trebuie verificate regulile.\n" "Contine găurile placate sau un conținut general Excellon." -#: flatcamTools/ToolRulesCheck.py:223 +#: flatcamTools/ToolRulesCheck.py:232 msgid "Excellon 2" msgstr "Excellon 2" -#: flatcamTools/ToolRulesCheck.py:225 +#: flatcamTools/ToolRulesCheck.py:234 msgid "" "Excellon object for which to check rules.\n" "Holds the non-plated holes." @@ -16171,35 +17055,35 @@ msgstr "" "Obiect Excellon pentru care trebuie verificate regulile.\n" "Contine găurile ne-placate." -#: flatcamTools/ToolRulesCheck.py:238 +#: flatcamTools/ToolRulesCheck.py:247 msgid "All Rules" msgstr "Totate Regulile" -#: flatcamTools/ToolRulesCheck.py:240 +#: flatcamTools/ToolRulesCheck.py:249 msgid "This check/uncheck all the rules below." msgstr "Aceasta bifează/debifează toate regulile de mai jos." -#: flatcamTools/ToolRulesCheck.py:490 +#: flatcamTools/ToolRulesCheck.py:499 msgid "Run Rules Check" msgstr "Executați Verificarea regulilor" -#: flatcamTools/ToolRulesCheck.py:1149 flatcamTools/ToolRulesCheck.py:1209 -#: flatcamTools/ToolRulesCheck.py:1246 flatcamTools/ToolRulesCheck.py:1318 -#: flatcamTools/ToolRulesCheck.py:1372 flatcamTools/ToolRulesCheck.py:1410 -#: flatcamTools/ToolRulesCheck.py:1475 +#: flatcamTools/ToolRulesCheck.py:1158 flatcamTools/ToolRulesCheck.py:1218 +#: flatcamTools/ToolRulesCheck.py:1255 flatcamTools/ToolRulesCheck.py:1327 +#: flatcamTools/ToolRulesCheck.py:1381 flatcamTools/ToolRulesCheck.py:1419 +#: flatcamTools/ToolRulesCheck.py:1484 msgid "Value is not valid." msgstr "Valoarea nu este valabilă." -#: flatcamTools/ToolRulesCheck.py:1163 +#: flatcamTools/ToolRulesCheck.py:1172 msgid "TOP -> Copper to Copper clearance" msgstr "TOP -> Distanta de la Cupru la Cupru" -#: flatcamTools/ToolRulesCheck.py:1174 +#: flatcamTools/ToolRulesCheck.py:1183 msgid "BOTTOM -> Copper to Copper clearance" msgstr "BOTTOM -> Distanta de la Cupru la Cupru" -#: flatcamTools/ToolRulesCheck.py:1179 flatcamTools/ToolRulesCheck.py:1273 -#: flatcamTools/ToolRulesCheck.py:1437 +#: flatcamTools/ToolRulesCheck.py:1188 flatcamTools/ToolRulesCheck.py:1282 +#: flatcamTools/ToolRulesCheck.py:1446 msgid "" "At least one Gerber object has to be selected for this rule but none is " "selected." @@ -16207,14 +17091,14 @@ msgstr "" "Pentru această regulă trebuie selectat cel puțin un obiect Gerber, dar " "niciunul nu este selectat." -#: flatcamTools/ToolRulesCheck.py:1215 +#: flatcamTools/ToolRulesCheck.py:1224 msgid "" "One of the copper Gerber objects or the Outline Gerber object is not valid." msgstr "" "Unul dintre obiectele Gerber din cupru sau obiectul Gerber contur nu este " "valid." -#: flatcamTools/ToolRulesCheck.py:1228 flatcamTools/ToolRulesCheck.py:1392 +#: flatcamTools/ToolRulesCheck.py:1237 flatcamTools/ToolRulesCheck.py:1401 msgid "" "Outline Gerber object presence is mandatory for this rule but it is not " "selected." @@ -16222,31 +17106,31 @@ msgstr "" "Prezenta obiectului Gerber contur este obligatorie pentru această regulă, " "dar nu este selectată." -#: flatcamTools/ToolRulesCheck.py:1245 flatcamTools/ToolRulesCheck.py:1272 +#: flatcamTools/ToolRulesCheck.py:1254 flatcamTools/ToolRulesCheck.py:1281 msgid "Silk to Silk clearance" msgstr "Distanta Silk la Silk" -#: flatcamTools/ToolRulesCheck.py:1258 +#: flatcamTools/ToolRulesCheck.py:1267 msgid "TOP -> Silk to Silk clearance" msgstr "TOP -> Distanta Silk la Silk" -#: flatcamTools/ToolRulesCheck.py:1268 +#: flatcamTools/ToolRulesCheck.py:1277 msgid "BOTTOM -> Silk to Silk clearance" msgstr "BOTTOM -> Distanta Silk la Silk" -#: flatcamTools/ToolRulesCheck.py:1324 +#: flatcamTools/ToolRulesCheck.py:1333 msgid "One or more of the Gerber objects is not valid." msgstr "Unul sau mai multe dintre obiectele Gerber nu sunt valabile." -#: flatcamTools/ToolRulesCheck.py:1332 +#: flatcamTools/ToolRulesCheck.py:1341 msgid "TOP -> Silk to Solder Mask Clearance" msgstr "TOP -> Distanta Silk la Solder mask" -#: flatcamTools/ToolRulesCheck.py:1338 +#: flatcamTools/ToolRulesCheck.py:1347 msgid "BOTTOM -> Silk to Solder Mask Clearance" msgstr "BOTTOM -> Distanta Silk la Solder mask" -#: flatcamTools/ToolRulesCheck.py:1342 +#: flatcamTools/ToolRulesCheck.py:1351 msgid "" "Both Silk and Solder Mask Gerber objects has to be either both Top or both " "Bottom." @@ -16254,62 +17138,62 @@ msgstr "" "Atât obiectele Silk cat si cele Solder Mask trebuie ori ambele TOP ori " "ambele BOTTOM." -#: flatcamTools/ToolRulesCheck.py:1378 +#: flatcamTools/ToolRulesCheck.py:1387 msgid "" "One of the Silk Gerber objects or the Outline Gerber object is not valid." msgstr "" "Unul dintre obiectele Silk Gerber sau obiectul Contur Gerber nu este valid." -#: flatcamTools/ToolRulesCheck.py:1422 +#: flatcamTools/ToolRulesCheck.py:1431 msgid "TOP -> Minimum Solder Mask Sliver" msgstr "TOP -> Distanta minima intre elementele Solder Mask" -#: flatcamTools/ToolRulesCheck.py:1432 +#: flatcamTools/ToolRulesCheck.py:1441 msgid "BOTTOM -> Minimum Solder Mask Sliver" msgstr "BOTTOM -> Distanta minima intre elementele Solder Mask" -#: flatcamTools/ToolRulesCheck.py:1481 +#: flatcamTools/ToolRulesCheck.py:1490 msgid "One of the Copper Gerber objects or the Excellon objects is not valid." msgstr "" "Unul dintre obiectele Gerber Cupru sau obiectele Excellon nu este valabil." -#: flatcamTools/ToolRulesCheck.py:1497 +#: flatcamTools/ToolRulesCheck.py:1506 msgid "" "Excellon object presence is mandatory for this rule but none is selected." msgstr "" "Prezența obiectului Excellon este obligatorie pentru această regulă, dar " "niciunul nu este selectat." -#: flatcamTools/ToolRulesCheck.py:1570 flatcamTools/ToolRulesCheck.py:1583 -#: flatcamTools/ToolRulesCheck.py:1594 flatcamTools/ToolRulesCheck.py:1607 +#: flatcamTools/ToolRulesCheck.py:1579 flatcamTools/ToolRulesCheck.py:1592 +#: flatcamTools/ToolRulesCheck.py:1603 flatcamTools/ToolRulesCheck.py:1616 msgid "STATUS" msgstr "STARE" -#: flatcamTools/ToolRulesCheck.py:1573 flatcamTools/ToolRulesCheck.py:1597 +#: flatcamTools/ToolRulesCheck.py:1582 flatcamTools/ToolRulesCheck.py:1606 msgid "FAILED" msgstr "A EȘUAT" -#: flatcamTools/ToolRulesCheck.py:1586 flatcamTools/ToolRulesCheck.py:1610 +#: flatcamTools/ToolRulesCheck.py:1595 flatcamTools/ToolRulesCheck.py:1619 msgid "PASSED" msgstr "A TRECUT" -#: flatcamTools/ToolRulesCheck.py:1587 flatcamTools/ToolRulesCheck.py:1611 +#: flatcamTools/ToolRulesCheck.py:1596 flatcamTools/ToolRulesCheck.py:1620 msgid "Violations: There are no violations for the current rule." msgstr "Încălcări: nu există încălcări pentru regula actuală." -#: flatcamTools/ToolShell.py:70 flatcamTools/ToolShell.py:72 -msgid "...proccessing..." +#: flatcamTools/ToolShell.py:72 flatcamTools/ToolShell.py:74 +msgid "...processing..." msgstr "...in procesare..." -#: flatcamTools/ToolSolderPaste.py:37 +#: flatcamTools/ToolSolderPaste.py:38 msgid "Solder Paste Tool" msgstr "Unealta DispensorPF" -#: flatcamTools/ToolSolderPaste.py:68 +#: flatcamTools/ToolSolderPaste.py:70 msgid "Gerber Solder paste object. " msgstr "Obiect Gerber cu masca pt dispensarea de pastă de fludor. " -#: flatcamTools/ToolSolderPaste.py:75 +#: flatcamTools/ToolSolderPaste.py:77 msgid "" "Tools pool from which the algorithm\n" "will pick the ones used for dispensing solder paste." @@ -16317,7 +17201,7 @@ msgstr "" "Un număr de unelte (nozzle) din care algoritmul va alege pe acelea\n" "care vor fi folosite pentru dispensarea pastei de fludor." -#: flatcamTools/ToolSolderPaste.py:90 +#: flatcamTools/ToolSolderPaste.py:92 msgid "" "This is the Tool Number.\n" "The solder dispensing will start with the tool with the biggest \n" @@ -16332,7 +17216,7 @@ msgstr "" "Daca numai sunt unelte dar mai sunt inca paduri neacoperite de pastă de \n" "fludor, aplicaţia va afisa un mesaj de avertizare in Status Bar." -#: flatcamTools/ToolSolderPaste.py:97 +#: flatcamTools/ToolSolderPaste.py:99 msgid "" "Nozzle tool Diameter. It's value (in current FlatCAM units)\n" "is the width of the solder paste dispensed." @@ -16340,11 +17224,11 @@ msgstr "" "Diametrul uneltei Nozzle. Valoarea sa (in unitati de maura curente)\n" "este lăţimea cantiatii de pastă de fludor dispensata." -#: flatcamTools/ToolSolderPaste.py:104 +#: flatcamTools/ToolSolderPaste.py:106 msgid "New Nozzle Tool" msgstr "Unealtă noua" -#: flatcamTools/ToolSolderPaste.py:123 +#: flatcamTools/ToolSolderPaste.py:125 msgid "" "Add a new nozzle tool to the Tool Table\n" "with the diameter specified above." @@ -16352,15 +17236,15 @@ msgstr "" "Adaugă o unealtă nouă tip Nozzle in Tabela de Unelte\n" "cu diametrul specificat mai sus." -#: flatcamTools/ToolSolderPaste.py:135 +#: flatcamTools/ToolSolderPaste.py:137 msgid "Generate solder paste dispensing geometry." msgstr "Generează un obiect Geometrie pt dispensarea de pastă de fludor." -#: flatcamTools/ToolSolderPaste.py:154 +#: flatcamTools/ToolSolderPaste.py:156 msgid "STEP 1" msgstr "PAS 1" -#: flatcamTools/ToolSolderPaste.py:156 +#: flatcamTools/ToolSolderPaste.py:158 msgid "" "First step is to select a number of nozzle tools for usage\n" "and then optionally modify the GCode parameters bellow." @@ -16369,7 +17253,7 @@ msgstr "" "utilizare și apoi in mod optional, să se modifice parametrii\n" "GCode de mai jos." -#: flatcamTools/ToolSolderPaste.py:159 +#: flatcamTools/ToolSolderPaste.py:161 msgid "" "Select tools.\n" "Modify parameters." @@ -16377,7 +17261,7 @@ msgstr "" "Selectează unelte.\n" "Modifica parametri." -#: flatcamTools/ToolSolderPaste.py:279 +#: flatcamTools/ToolSolderPaste.py:281 msgid "" "Feedrate (speed) while moving up vertically\n" " to Dispense position (on Z plane)." @@ -16385,7 +17269,7 @@ msgstr "" "Viteza de deplasare la mișcarea pe verticala spre\n" "poziţia de dispensare (in planul Z)." -#: flatcamTools/ToolSolderPaste.py:349 +#: flatcamTools/ToolSolderPaste.py:351 msgid "" "Generate GCode for Solder Paste dispensing\n" "on PCB pads." @@ -16393,11 +17277,11 @@ msgstr "" "Generează GCode pt dispensarea\n" "de pastă de fludor pe padurile PCB." -#: flatcamTools/ToolSolderPaste.py:370 +#: flatcamTools/ToolSolderPaste.py:372 msgid "STEP 2" msgstr "PAS 2" -#: flatcamTools/ToolSolderPaste.py:372 +#: flatcamTools/ToolSolderPaste.py:374 msgid "" "Second step is to create a solder paste dispensing\n" "geometry out of an Solder Paste Mask Gerber file." @@ -16406,11 +17290,11 @@ msgstr "" "de pastă de fludor, dintr-un fişier Gerber cu datele mastii de plasare\n" "a pastei de fludor." -#: flatcamTools/ToolSolderPaste.py:388 +#: flatcamTools/ToolSolderPaste.py:391 msgid "Geo Result" msgstr "Rezultat Geo" -#: flatcamTools/ToolSolderPaste.py:390 +#: flatcamTools/ToolSolderPaste.py:393 msgid "" "Geometry Solder Paste object.\n" "The name of the object has to end in:\n" @@ -16420,11 +17304,11 @@ msgstr "" "Numele obiectului trebuie să se termine obligatoriu\n" "in: '_solderpaste'." -#: flatcamTools/ToolSolderPaste.py:399 +#: flatcamTools/ToolSolderPaste.py:402 msgid "STEP 3" msgstr "PAS 3" -#: flatcamTools/ToolSolderPaste.py:401 +#: flatcamTools/ToolSolderPaste.py:404 msgid "" "Third step is to select a solder paste dispensing geometry,\n" "and then generate a CNCJob object.\n" @@ -16440,11 +17324,11 @@ msgstr "" "mai intai trebuie generat obiectul Geometrie cu acei parametri noi și abia\n" "apoi se poate genera un obiect CNCJob actualizat." -#: flatcamTools/ToolSolderPaste.py:421 +#: flatcamTools/ToolSolderPaste.py:425 msgid "CNC Result" msgstr "Rezultat CNC" -#: flatcamTools/ToolSolderPaste.py:423 +#: flatcamTools/ToolSolderPaste.py:427 msgid "" "CNCJob Solder paste object.\n" "In order to enable the GCode save section,\n" @@ -16456,11 +17340,11 @@ msgstr "" "numele obiectului trebuie să se termine obligatoriu in:\n" "'_solderpaste'." -#: flatcamTools/ToolSolderPaste.py:433 +#: flatcamTools/ToolSolderPaste.py:437 msgid "View GCode" msgstr "Vizualiz. GCode" -#: flatcamTools/ToolSolderPaste.py:435 +#: flatcamTools/ToolSolderPaste.py:439 msgid "" "View the generated GCode for Solder Paste dispensing\n" "on PCB pads." @@ -16468,11 +17352,11 @@ msgstr "" "Vizualizează codul GCode generat pt dispensarea de \n" "pastă de fludor pe padurile PCB-ului." -#: flatcamTools/ToolSolderPaste.py:445 +#: flatcamTools/ToolSolderPaste.py:449 msgid "Save GCode" msgstr "Salvează GCode" -#: flatcamTools/ToolSolderPaste.py:447 +#: flatcamTools/ToolSolderPaste.py:451 msgid "" "Save the generated GCode for Solder Paste dispensing\n" "on PCB pads, to a file." @@ -16480,11 +17364,11 @@ msgstr "" "Salvează codul GCode generat pt dispensare pastă de fludor\n" "pe padurile unui PCB, intr-un fişier pe HDD." -#: flatcamTools/ToolSolderPaste.py:457 +#: flatcamTools/ToolSolderPaste.py:461 msgid "STEP 4" msgstr "PAS 4" -#: flatcamTools/ToolSolderPaste.py:459 +#: flatcamTools/ToolSolderPaste.py:463 msgid "" "Fourth step (and last) is to select a CNCJob made from \n" "a solder paste dispensing geometry, and then view/save it's GCode." @@ -16494,95 +17378,89 @@ msgstr "" "avand posibilitatea de a vizualiza continutul acestuia sau de a-l salva\n" "intr-un fişier GCode pe HDD." -#: flatcamTools/ToolSolderPaste.py:917 -msgid "Adding Nozzle tool cancelled. Tool already in Tool Table." -msgstr "" -"Adăugarea unei unelte Nozzle a fost anulată. Unealta există deja in Tabela " -"de Unelte." - -#: flatcamTools/ToolSolderPaste.py:923 +#: flatcamTools/ToolSolderPaste.py:922 msgid "New Nozzle tool added to Tool Table." msgstr "A fost adăugată o noua unealtă Nozzle in Tabela de Unelte." -#: flatcamTools/ToolSolderPaste.py:966 +#: flatcamTools/ToolSolderPaste.py:965 msgid "Nozzle tool from Tool Table was edited." msgstr "Unealta Nozzle din Tabela de Unelte a fost editată." -#: flatcamTools/ToolSolderPaste.py:1024 +#: flatcamTools/ToolSolderPaste.py:1023 msgid "Delete failed. Select a Nozzle tool to delete." msgstr "Ștergerea a eșuat. Selectează o unealtă Nozzle pt a o șterge." -#: flatcamTools/ToolSolderPaste.py:1030 +#: flatcamTools/ToolSolderPaste.py:1029 msgid "Nozzle tool(s) deleted from Tool Table." msgstr "Uneltele (nozzle) au fost șterse din Tabela de Unelte." -#: flatcamTools/ToolSolderPaste.py:1086 +#: flatcamTools/ToolSolderPaste.py:1085 msgid "No SolderPaste mask Gerber object loaded." msgstr "" "Nu este incărcat ni-un obiect Gerber cu informatia măstii pt pasta de fludor." -#: flatcamTools/ToolSolderPaste.py:1104 +#: flatcamTools/ToolSolderPaste.py:1103 msgid "Creating Solder Paste dispensing geometry." msgstr "Se creează Geometrie pt dispensare pastă de fludor." -#: flatcamTools/ToolSolderPaste.py:1117 +#: flatcamTools/ToolSolderPaste.py:1116 msgid "No Nozzle tools in the tool table." msgstr "Nu sunt unelte Nozzle in Tabela de Unelte." -#: flatcamTools/ToolSolderPaste.py:1244 +#: flatcamTools/ToolSolderPaste.py:1242 msgid "Cancelled. Empty file, it has no geometry..." msgstr "Anulat. Fişier gol, nu are geometrie ..." -#: flatcamTools/ToolSolderPaste.py:1248 +#: flatcamTools/ToolSolderPaste.py:1245 msgid "Solder Paste geometry generated successfully" msgstr "" "Obiectul Geometrie pt dispens. de pastă de fludor a fost generat cu succes" -#: flatcamTools/ToolSolderPaste.py:1255 +#: flatcamTools/ToolSolderPaste.py:1252 msgid "Some or all pads have no solder due of inadequate nozzle diameters..." msgstr "" "Cel puțin unele pad-uri nu au pastă de fludor datorita diametrelor uneltelor " "(nozzle) ne adecvate." -#: flatcamTools/ToolSolderPaste.py:1269 +#: flatcamTools/ToolSolderPaste.py:1266 msgid "Generating Solder Paste dispensing geometry..." msgstr "Se generează Geometria de dispensare a pastei de fludor ..." -#: flatcamTools/ToolSolderPaste.py:1289 +#: flatcamTools/ToolSolderPaste.py:1286 msgid "There is no Geometry object available." msgstr "Nu există obiect Geometrie disponibil." -#: flatcamTools/ToolSolderPaste.py:1294 +#: flatcamTools/ToolSolderPaste.py:1291 msgid "This Geometry can't be processed. NOT a solder_paste_tool geometry." msgstr "" "Acest obiect Geometrie nu poate fi procesat Nu este o Geometrie tip " "solder_paste_tool." -#: flatcamTools/ToolSolderPaste.py:1401 +#: flatcamTools/ToolSolderPaste.py:1392 msgid "ToolSolderPaste CNCjob created" msgstr "ToolSolderPaste CNCjob a fost creat" -#: flatcamTools/ToolSolderPaste.py:1422 +#: flatcamTools/ToolSolderPaste.py:1411 msgid "SP GCode Editor" msgstr "Editor GCode SP" -#: flatcamTools/ToolSolderPaste.py:1434 flatcamTools/ToolSolderPaste.py:1439 -#: flatcamTools/ToolSolderPaste.py:1494 +#: flatcamTools/ToolSolderPaste.py:1423 flatcamTools/ToolSolderPaste.py:1428 +#: flatcamTools/ToolSolderPaste.py:1483 msgid "" "This CNCJob object can't be processed. NOT a solder_paste_tool CNCJob object." msgstr "" "Acest obiect CNCJob nu poate fi procesat. Nu este un obiect CNCJob tip " "'solder_paste_tool'." -#: flatcamTools/ToolSolderPaste.py:1464 +#: flatcamTools/ToolSolderPaste.py:1453 msgid "No Gcode in the object" msgstr "Nu există cod GCode in acest obiect" -#: flatcamTools/ToolSolderPaste.py:1504 +#: flatcamTools/ToolSolderPaste.py:1493 msgid "Export GCode ..." msgstr "Exporta GCode ..." -#: flatcamTools/ToolSolderPaste.py:1552 +#: flatcamTools/ToolSolderPaste.py:1541 msgid "Solder paste dispenser GCode file saved to" msgstr "Fişierul GCode pt dispensare pastă de fludor este salvat in" @@ -16590,7 +17468,7 @@ msgstr "Fişierul GCode pt dispensare pastă de fludor este salvat in" msgid "Gerber Objects" msgstr "Obiecte Gerber" -#: flatcamTools/ToolSub.py:76 +#: flatcamTools/ToolSub.py:78 msgid "" "Gerber object from which to subtract\n" "the subtractor Gerber object." @@ -16598,11 +17476,11 @@ msgstr "" "Obiectul Gerber din care se scade \n" "obiectul Gerber substractor." -#: flatcamTools/ToolSub.py:88 flatcamTools/ToolSub.py:140 +#: flatcamTools/ToolSub.py:91 flatcamTools/ToolSub.py:146 msgid "Subtractor" msgstr "Substractor" -#: flatcamTools/ToolSub.py:90 +#: flatcamTools/ToolSub.py:93 msgid "" "Gerber object that will be subtracted\n" "from the target Gerber object." @@ -16610,11 +17488,11 @@ msgstr "" "Obiectul Gerber care se scade din \n" "obiectul Gerber tintă." -#: flatcamTools/ToolSub.py:97 +#: flatcamTools/ToolSub.py:100 msgid "Substract Gerber" msgstr "Execută" -#: flatcamTools/ToolSub.py:99 +#: flatcamTools/ToolSub.py:102 msgid "" "Will remove the area occupied by the subtractor\n" "Gerber from the Target Gerber.\n" @@ -16626,11 +17504,11 @@ msgstr "" "Poate fi utilizat pt. a indepărta silkscreen-ul\n" "care se suprapune peste soldermask." -#: flatcamTools/ToolSub.py:117 +#: flatcamTools/ToolSub.py:120 msgid "Geometry Objects" msgstr "Obiecte Geometrie" -#: flatcamTools/ToolSub.py:128 +#: flatcamTools/ToolSub.py:133 msgid "" "Geometry object from which to subtract\n" "the subtractor Geometry object." @@ -16638,7 +17516,7 @@ msgstr "" "Obiectul Geometrie din care se scade \n" "obiectul Geometrie substractor." -#: flatcamTools/ToolSub.py:142 +#: flatcamTools/ToolSub.py:148 msgid "" "Geometry object that will be subtracted\n" "from the target Geometry object." @@ -16646,18 +17524,18 @@ msgstr "" "Obiectul Geometrie care se va scădea \n" "din obiectul Geometrie tintă." -#: flatcamTools/ToolSub.py:150 +#: flatcamTools/ToolSub.py:156 msgid "" "Checking this will close the paths cut by the Geometry subtractor object." msgstr "" "Verificând aceasta, se vor închide căile tăiate de obiectul tăietor de tip " "Geometrie." -#: flatcamTools/ToolSub.py:153 +#: flatcamTools/ToolSub.py:159 msgid "Subtract Geometry" msgstr "Scadeti Geometria" -#: flatcamTools/ToolSub.py:155 +#: flatcamTools/ToolSub.py:161 msgid "" "Will remove the area occupied by the subtractor\n" "Geometry from the Target Geometry." @@ -16665,56 +17543,56 @@ msgstr "" "Va indepărta aria ocupată de obiectul Geometrie \n" "substractor din obiectul Geometrie tintă." -#: flatcamTools/ToolSub.py:262 +#: flatcamTools/ToolSub.py:263 msgid "Sub Tool" msgstr "Unealta Scădere" -#: flatcamTools/ToolSub.py:278 flatcamTools/ToolSub.py:483 +#: flatcamTools/ToolSub.py:284 flatcamTools/ToolSub.py:489 msgid "No Target object loaded." msgstr "Nu este incărcat un obiect Tintă." -#: flatcamTools/ToolSub.py:281 +#: flatcamTools/ToolSub.py:287 msgid "Loading geometry from Gerber objects." msgstr "Se Încarcă geometria din obiectele Gerber." -#: flatcamTools/ToolSub.py:293 flatcamTools/ToolSub.py:498 +#: flatcamTools/ToolSub.py:299 flatcamTools/ToolSub.py:504 msgid "No Subtractor object loaded." msgstr "Nu este incărcat obiect Substractor (scăzător)." -#: flatcamTools/ToolSub.py:325 +#: flatcamTools/ToolSub.py:331 msgid "Processing geometry from Subtractor Gerber object." msgstr "Procesarea geometriei din obiectul Gerber Scăzător." -#: flatcamTools/ToolSub.py:346 +#: flatcamTools/ToolSub.py:352 msgid "Parsing geometry for aperture" msgstr "Se analizează Geometria pt apertura" -#: flatcamTools/ToolSub.py:407 +#: flatcamTools/ToolSub.py:413 msgid "Finished parsing geometry for aperture" msgstr "S-a terminat analiza geometriei pt apertura" -#: flatcamTools/ToolSub.py:452 flatcamTools/ToolSub.py:655 +#: flatcamTools/ToolSub.py:458 flatcamTools/ToolSub.py:661 msgid "Generating new object ..." msgstr "Se generează un obiect nou ..." -#: flatcamTools/ToolSub.py:456 flatcamTools/ToolSub.py:659 -#: flatcamTools/ToolSub.py:740 +#: flatcamTools/ToolSub.py:462 flatcamTools/ToolSub.py:665 +#: flatcamTools/ToolSub.py:746 msgid "Generating new object failed." msgstr "Generarea unui obiect nou a esuat." -#: flatcamTools/ToolSub.py:461 flatcamTools/ToolSub.py:665 +#: flatcamTools/ToolSub.py:467 flatcamTools/ToolSub.py:671 msgid "Created" msgstr "Creat" -#: flatcamTools/ToolSub.py:512 +#: flatcamTools/ToolSub.py:518 msgid "Currently, the Subtractor geometry cannot be of type Multigeo." msgstr "Momentan, obiectul substractor Geometrie nu poate fi de tip Multigeo." -#: flatcamTools/ToolSub.py:557 +#: flatcamTools/ToolSub.py:563 msgid "Parsing solid_geometry ..." msgstr "Analizează geometria solidă..." -#: flatcamTools/ToolSub.py:559 +#: flatcamTools/ToolSub.py:565 msgid "Parsing solid_geometry for tool" msgstr "Se analizează Geometria pt unealta" @@ -16722,7 +17600,7 @@ msgstr "Se analizează Geometria pt unealta" msgid "Object Transform" msgstr "Transformare Obiect" -#: flatcamTools/ToolTransform.py:82 +#: flatcamTools/ToolTransform.py:79 msgid "" "Rotate the selected object(s).\n" "The point of reference is the middle of\n" @@ -16732,7 +17610,7 @@ msgstr "" "Punctul de referinţă este mijlocul \n" "formei înconjurătoare pt toate obiectele." -#: flatcamTools/ToolTransform.py:100 flatcamTools/ToolTransform.py:122 +#: flatcamTools/ToolTransform.py:100 flatcamTools/ToolTransform.py:121 msgid "" "Angle for Skew action, in degrees.\n" "Float number between -360 and 360." @@ -16740,7 +17618,7 @@ msgstr "" "Valoarea unghiului de Deformare, in grade.\n" "Ia valori Reale între -360 si 360 grade." -#: flatcamTools/ToolTransform.py:111 flatcamTools/ToolTransform.py:133 +#: flatcamTools/ToolTransform.py:110 flatcamTools/ToolTransform.py:131 msgid "" "Skew/shear the selected object(s).\n" "The point of reference is the middle of\n" @@ -16750,7 +17628,7 @@ msgstr "" "Punctul de referinţă este mijlocul \n" "formei înconjurătoare pt toate obiectele." -#: flatcamTools/ToolTransform.py:160 flatcamTools/ToolTransform.py:181 +#: flatcamTools/ToolTransform.py:160 flatcamTools/ToolTransform.py:180 msgid "" "Scale the selected object(s).\n" "The point of reference depends on \n" @@ -16760,7 +17638,7 @@ msgstr "" "Punctul de referinţă depinde de\n" "starea checkbox-ului >Referința Scalare<." -#: flatcamTools/ToolTransform.py:229 flatcamTools/ToolTransform.py:250 +#: flatcamTools/ToolTransform.py:229 flatcamTools/ToolTransform.py:249 msgid "" "Offset the selected object(s).\n" "The point of reference is the middle of\n" @@ -16770,200 +17648,594 @@ msgstr "" "Punctul de referinţă este mijlocul formei înconjurătoare\n" "pentru toate obiectele selectate.\n" -#: flatcamTools/ToolTransform.py:268 flatcamTools/ToolTransform.py:274 +#: flatcamTools/ToolTransform.py:269 flatcamTools/ToolTransform.py:274 msgid "Flip the selected object(s) over the X axis." msgstr "Oglindește obiectele selectate pe axa X." -#: flatcamTools/ToolTransform.py:299 +#: flatcamTools/ToolTransform.py:298 msgid "Ref. Point" msgstr "Pt. Ref" -#: flatcamTools/ToolTransform.py:351 +#: flatcamTools/ToolTransform.py:349 msgid "" "Create the buffer effect on each geometry,\n" -"element from the selected object." +"element from the selected object, using the distance." msgstr "" "Creați efectul buffer pe fiecare geometrie,\n" -"element din obiectul selectat." +"element din obiectul selectat, folosind distanta." -#: flatcamTools/ToolTransform.py:498 +#: flatcamTools/ToolTransform.py:375 +msgid "" +"Create the buffer effect on each geometry,\n" +"element from the selected object, using the factor." +msgstr "" +"Creați efectul buffer pe fiecare geometrie,\n" +"element din obiectul selectat, folosing un factor." + +#: flatcamTools/ToolTransform.py:480 +msgid "Buffer D" +msgstr "Bufer D" + +#: flatcamTools/ToolTransform.py:481 +msgid "Buffer F" +msgstr "Bufer F" + +#: flatcamTools/ToolTransform.py:558 msgid "Rotate transformation can not be done for a value of 0." msgstr "Transformarea Rotire nu se poate face pentru o valoare de 0." -#: flatcamTools/ToolTransform.py:537 flatcamTools/ToolTransform.py:560 +#: flatcamTools/ToolTransform.py:597 flatcamTools/ToolTransform.py:620 msgid "Scale transformation can not be done for a factor of 0 or 1." msgstr "Transformarea Scalare nu se poate face pentru un factor de 0 sau 1." -#: flatcamTools/ToolTransform.py:575 flatcamTools/ToolTransform.py:585 +#: flatcamTools/ToolTransform.py:635 flatcamTools/ToolTransform.py:645 msgid "Offset transformation can not be done for a value of 0." msgstr "Transformarea Deplasare nu se poate face pentru o valoare de 0." -#: flatcamTools/ToolTransform.py:608 +#: flatcamTools/ToolTransform.py:677 msgid "No object selected. Please Select an object to rotate!" msgstr "" "Nici-un obiect nu este selectat. Selectează un obiect pentru a fi Rotit!" -#: flatcamTools/ToolTransform.py:636 +#: flatcamTools/ToolTransform.py:703 msgid "CNCJob objects can't be rotated." msgstr "Obiectele tip CNCJob nu pot fi Rotite." -#: flatcamTools/ToolTransform.py:644 +#: flatcamTools/ToolTransform.py:711 msgid "Rotate done" msgstr "Rotaţie efectuată" -#: flatcamTools/ToolTransform.py:649 flatcamTools/ToolTransform.py:724 -#: flatcamTools/ToolTransform.py:779 flatcamTools/ToolTransform.py:838 -#: flatcamTools/ToolTransform.py:874 flatcamTools/ToolTransform.py:910 +#: flatcamTools/ToolTransform.py:714 flatcamTools/ToolTransform.py:784 +#: flatcamTools/ToolTransform.py:834 flatcamTools/ToolTransform.py:890 +#: flatcamTools/ToolTransform.py:922 flatcamTools/ToolTransform.py:958 msgid "Due of" msgstr "Datorită" -#: flatcamTools/ToolTransform.py:649 flatcamTools/ToolTransform.py:724 -#: flatcamTools/ToolTransform.py:779 flatcamTools/ToolTransform.py:838 -#: flatcamTools/ToolTransform.py:874 flatcamTools/ToolTransform.py:910 +#: flatcamTools/ToolTransform.py:714 flatcamTools/ToolTransform.py:784 +#: flatcamTools/ToolTransform.py:834 flatcamTools/ToolTransform.py:890 +#: flatcamTools/ToolTransform.py:922 flatcamTools/ToolTransform.py:958 msgid "action was not executed." msgstr "actiunea nu a fost efectuată." -#: flatcamTools/ToolTransform.py:661 +#: flatcamTools/ToolTransform.py:726 msgid "No object selected. Please Select an object to flip" msgstr "" "Nici-un obiect nu este selectat. Selectează un obiect pentru a fi Oglindit" -#: flatcamTools/ToolTransform.py:696 +#: flatcamTools/ToolTransform.py:759 msgid "CNCJob objects can't be mirrored/flipped." msgstr "Obiectele tip CNCJob nu pot fi Oglindite." -#: flatcamTools/ToolTransform.py:734 +#: flatcamTools/ToolTransform.py:794 msgid "Skew transformation can not be done for 0, 90 and 180 degrees." msgstr "Transformarea Inclinare nu se poate face la 0, 90 și 180 de grade." -#: flatcamTools/ToolTransform.py:739 +#: flatcamTools/ToolTransform.py:799 msgid "No object selected. Please Select an object to shear/skew!" msgstr "" "Nici-un obiect nu este selectat. Selectează un obiect pentru a fi Deformat!" -#: flatcamTools/ToolTransform.py:761 +#: flatcamTools/ToolTransform.py:819 msgid "CNCJob objects can't be skewed." msgstr "Obiectele tip CNCJob nu pot fi deformate." -#: flatcamTools/ToolTransform.py:774 +#: flatcamTools/ToolTransform.py:831 msgid "Skew on the" msgstr "Deformează pe" -#: flatcamTools/ToolTransform.py:774 flatcamTools/ToolTransform.py:834 -#: flatcamTools/ToolTransform.py:869 +#: flatcamTools/ToolTransform.py:831 flatcamTools/ToolTransform.py:887 +#: flatcamTools/ToolTransform.py:919 msgid "axis done" msgstr "axa efectuată" -#: flatcamTools/ToolTransform.py:791 +#: flatcamTools/ToolTransform.py:846 msgid "No object selected. Please Select an object to scale!" msgstr "" "Nici-un obiect nu este selectat. Selectează un obiect pentru a fi Scalat!" -#: flatcamTools/ToolTransform.py:824 +#: flatcamTools/ToolTransform.py:877 msgid "CNCJob objects can't be scaled." msgstr "Obiectele tip CNCJob nu pot fi scalate." -#: flatcamTools/ToolTransform.py:834 +#: flatcamTools/ToolTransform.py:887 msgid "Scale on the" msgstr "Scalează pe" -#: flatcamTools/ToolTransform.py:846 +#: flatcamTools/ToolTransform.py:898 msgid "No object selected. Please Select an object to offset!" msgstr "" "Nici-un obiect nu este selectat. Selectează un obiect pentru a fi Ofsetat!" -#: flatcamTools/ToolTransform.py:855 +#: flatcamTools/ToolTransform.py:905 msgid "CNCJob objects can't be offset." msgstr "Obiectele tip CNCJob nu pot fi deplasate." -#: flatcamTools/ToolTransform.py:869 +#: flatcamTools/ToolTransform.py:919 msgid "Offset on the" msgstr "Ofset pe" -#: flatcamTools/ToolTransform.py:881 +#: flatcamTools/ToolTransform.py:929 msgid "No object selected. Please Select an object to buffer!" msgstr "" "Nu a fost selectat niciun obiect. Vă rugăm să selectați un obiect de " "tamponat (buffer)" -#: flatcamTools/ToolTransform.py:884 +#: flatcamTools/ToolTransform.py:932 msgid "Applying Buffer" msgstr "Aplicarea tampon (Buffer)" -#: flatcamTools/ToolTransform.py:888 +#: flatcamTools/ToolTransform.py:936 msgid "CNCJob objects can't be buffered." msgstr "CNCJob objects can't be buffered (buffer)." -#: flatcamTools/ToolTransform.py:905 +#: flatcamTools/ToolTransform.py:953 msgid "Buffer done" msgstr "Buffer finalizat" -#: tclCommands/TclCommandBbox.py:74 tclCommands/TclCommandNregions.py:73 +#: tclCommands/TclCommandBbox.py:76 tclCommands/TclCommandNregions.py:75 msgid "Expected FlatCAMGerber or FlatCAMGeometry, got" msgstr "Se astepta un obiect FlatCAMGerber sau FlatCAMGeometry, s-a primit" -#: tclCommands/TclCommandBounds.py:64 tclCommands/TclCommandBounds.py:68 +#: tclCommands/TclCommandBounds.py:67 tclCommands/TclCommandBounds.py:71 msgid "Expected a list of objects names separated by comma. Got" msgstr "" "Se aștepta o listă de nume de obiecte separate prin virgulă. S-au primit" -#: tclCommands/TclCommandBounds.py:79 +#: tclCommands/TclCommandBounds.py:82 msgid "TclCommand Bounds done." msgstr "TclCommand Bounds executata." -#: tclCommands/TclCommandCopperClear.py:242 tclCommands/TclCommandPaint.py:240 -msgid "Expected -box ." -msgstr "Asteptăm -box ." - -#: tclCommands/TclCommandCopperClear.py:251 tclCommands/TclCommandPaint.py:249 -#: tclCommands/TclCommandScale.py:75 +#: tclCommands/TclCommandCopperClear.py:256 tclCommands/TclCommandPaint.py:261 +#: tclCommands/TclCommandScale.py:81 msgid "Could not retrieve box object" msgstr "Nu s-a putut incărca obiectul" -#: tclCommands/TclCommandCopperClear.py:273 -msgid "" -"None of the following args: 'ref', 'all' were found or none was set to 1.\n" -"Copper clearing failed." -msgstr "" -"Niciunul din următoarele argumente: „ref”, „toate” nu au fost găsite sau " -"nici unul nu a fost setat la 1.\n" -"Curatarea de cupru a eșuat." +#: tclCommands/TclCommandCopperClear.py:279 +msgid "Expected either -box or -all." +msgstr "Asteptăm -box sau -all." -#: tclCommands/TclCommandPaint.py:217 +#: tclCommands/TclCommandGeoCutout.py:148 +msgid "" +"The name of the object for which cutout is done is missing. Add it and retry." +msgstr "" +"Numele obiectului pentru care se efectuează tăierea lipseste. Adaugă din nou " +"și reîncearcă." + +#: tclCommands/TclCommandGeoCutout.py:190 +msgid "Gaps value can be only one of: 'lr', 'tb', '2lr', '2tb', 4 or 8." +msgstr "" +"Valoarea spatiilor poate fi doar una dintre: „Niciuna”, „lr”, „tb”, „2lr”, " +"„2tb”, 4 sau 8." + +#: tclCommands/TclCommandGeoCutout.py:302 +#: tclCommands/TclCommandGeoCutout.py:360 +msgid "Any-form Cutout operation finished." +msgstr "Operatia de tăiere cu formă liberă s-a terminat." + +#: tclCommands/TclCommandGeoCutout.py:366 +msgid "Cancelled. Object type is not supported." +msgstr "Anulat. Tipul de obiect nu este acceptat." + +#: tclCommands/TclCommandHelp.py:74 +msgid "Available commands:" +msgstr "Comenzi disponibile:" + +#: tclCommands/TclCommandHelp.py:112 +msgid "Type help for usage." +msgstr "Introduceți help pentru utilizare." + +#: tclCommands/TclCommandHelp.py:112 +msgid "Example: help open_gerber" +msgstr "Exemplu: help open_gerber" + +#: tclCommands/TclCommandPaint.py:229 msgid "Expected -x and -y ." msgstr "Asteptam -x si -y ." -#: tclCommands/TclCommandPaint.py:268 +#: tclCommands/TclCommandPaint.py:254 +msgid "Expected -box ." +msgstr "Asteptăm -box ." + +#: tclCommands/TclCommandPaint.py:279 msgid "" -"There was none of the following args: 'ref', 'single', 'all'.\n" +"None of the following args: 'box', 'single', 'all' were used.\n" "Paint failed." msgstr "" -"Nu a existat niciunul din următoarele argumente: „ref”, „single”, „all”.\n" +"Nu s-a folosit niciunul din următoarele argumente: „box”, „single”, „all”.\n" "Pictura nu a reușit." -#: tclCommands/TclCommandScale.py:95 -msgid "Expected -origin or -origin or -origin
." +#: tclCommands/TclCommandScale.py:106 +msgid "" +"Expected -origin or -origin or -origin
or - " +"origin 3.0,4.2." msgstr "" -"Asteptam -origin sau -origin sau -origin
." +"Asteptam -origin sau -origin sau -origin
or -" +"origin 3.0,4.2." -#: tclCommands/TclCommandScale.py:104 +#: tclCommands/TclCommandScale.py:119 msgid "Expected -x -y ." msgstr "Asteptam -x -y ." -#: tclCommands/TclCommandSetOrigin.py:91 +#: tclCommands/TclCommandSetOrigin.py:95 msgid "Expected a pair of (x, y) coordinates. Got" msgstr "Se așteaptă o pereche de coordonate (x, y). S-au primit" -#: tclCommands/TclCommandSetOrigin.py:98 +#: tclCommands/TclCommandSetOrigin.py:102 msgid "Origin set by offsetting all loaded objects with " msgstr "Originea setată prin ofsetarea tuturor obiectelor încărcate cu " -#: tclCommands/TclCommandSubtractRectangle.py:58 +#: tclCommands/TclCommandSubtractRectangle.py:62 msgid "No Geometry name in args. Provide a name and try again." msgstr "" "Nici-un nume de Geometrie in argumente. Furnizați un nume și încercați din " "nou." +#~ msgid "Executing Tcl Script ..." +#~ msgstr "Rulează Tcl Script..." + +#~ msgid "Open cancelled." +#~ msgstr "Deschidere anulată." + +#~ msgid "Preferences default restore was cancelled." +#~ msgstr "Restaurarea preferințelor implicite a fost anulată." + +#~ msgid "FlatCAM preferences import cancelled." +#~ msgstr "Importul preferințelor FlatCAM a eșuat." + +#~ msgid "FlatCAM preferences export cancelled." +#~ msgstr "Exportul preferințelor FlatCAM este anulat." + +#~ msgid "Multigeo. Geometry merging finished" +#~ msgstr "Multigeo. Fuziunea geometriei s-a terminat" + +#~ msgid "Units conversion cancelled." +#~ msgstr "Conversia unitătilor este anulată." + +#~ msgid "Open Gerber cancelled." +#~ msgstr "Incărcarea unui fişier Gerber este anulată." + +#~ msgid " Open Excellon cancelled." +#~ msgstr " Incărcarea unui fişier Excellon este anulată." + +#~ msgid "Open G-Code cancelled." +#~ msgstr "Incărcarea unui fişier G-Code este anulată." + +#~ msgid "Open Project cancelled." +#~ msgstr "Incărcarea unui fişier Proiect FlatCAM este anulată." + +#~ msgid "Open HPGL2 file cancelled." +#~ msgstr "Incărcarea fișierului HPGL2 a fost anulată." + +#~ msgid "Open Config cancelled." +#~ msgstr "Incărcarea unui fişier configurare FlatCAM este anulată." + +#~ msgid " Export SVG cancelled." +#~ msgstr " Exportul fisierului SVG a fost anulat." + +#~ msgid "Export PNG cancelled." +#~ msgstr "Exportul imagine PNG este anulat." + +#~ msgid "No object selected. Please select an Gerber object to export." +#~ msgstr "Nici-un obiect selectat. Selectează un obiect Gerber pentru export." + +#~ msgid "Save Gerber source file cancelled." +#~ msgstr "Salvarea codului sursa Gerber este anulată." + +#~ msgid "No object selected. Please select an Script object to export." +#~ msgstr "Nici-un obiect selectat. Selectează un obiect Script pentru export." + +#~ msgid "Save Script source file cancelled." +#~ msgstr "Salvarea codului sursa Script este anulată." + +#~ msgid "No object selected. Please select an Document object to export." +#~ msgstr "" +#~ "Nici-un obiect selectat. Selectează un obiect Document pentru export." + +#~ msgid "Save Document source file cancelled." +#~ msgstr "Salvarea codului sursa Document este anulată." + +#~ msgid "No object selected. Please select an Excellon object to export." +#~ msgstr "" +#~ "Nici-un obiect selectat. Selectează un obiect Excellon pentru export." + +#~ msgid "Saving Excellon source file cancelled." +#~ msgstr "Salvarea codului sursa Excellon este anulată." + +#~ msgid "No object selected. Please Select an Excellon object to export." +#~ msgstr "" +#~ "Nici-un obiect selectat. Selectează un obiect Excellon pentru export." + +#~ msgid "Export Excellon cancelled." +#~ msgstr "Exportul fișierului Excellon a fost anulat." + +#~ msgid "No object selected. Please Select an Gerber object to export." +#~ msgstr "Nici-un obiect selectat. Selectează un obiect Gerber pentru export." + +#~ msgid "Export Gerber cancelled." +#~ msgstr "Exportul fișierului Gerber a fost anulat." + +#~ msgid "Export DXF cancelled." +#~ msgstr "Exportul fișierului DXF a fost anulat." + +#~ msgid "Open SVG cancelled." +#~ msgstr "Incărcarea fișierului SVG a fost anulată." + +#~ msgid "Open DXF cancelled." +#~ msgstr "Incărcarea fișierului DXF a fost anulată." + +#~ msgid "Open TCL script cancelled." +#~ msgstr "Incărcarea fisierului TCL script anulată." + +#~ msgid "Run TCL script cancelled." +#~ msgstr "Executarea fisierului Script a fost anulată." + +#~ msgid "Save Project cancelled." +#~ msgstr "Salvarea Proiect anulată." + +#~ msgid "Save Object PDF cancelled." +#~ msgstr "Salvarea obiectului PDF anulată." + +#~ msgid "Shows list of commands." +#~ msgstr "Arata o lista de comenzi." + +#~ msgid "FlatCAM bookmarks export cancelled." +#~ msgstr "Exportul de bookmark-uri FlatCAM este anulat." + +#~ msgid "FlatCAM bookmarks import cancelled." +#~ msgstr "Importul de Bookmark-uri FlatCAM a eșuat." + +#~ msgid "FlatCAM Tools DB export cancelled." +#~ msgstr "Exportul DB Unelte a fost anulat." + +#~ msgid "FlatCAM Tools DB import cancelled." +#~ msgstr "Importul DB Unelte a fost anulat." + +#~ msgid "" +#~ "Wrong value format for self.defaults[\"z_pdepth\"] or self." +#~ "options[\"z_pdepth\"]" +#~ msgstr "" +#~ "Valoare gresita pt self.defaults[\"z_pdepth\"] sau self.options[\"z_pdepth" +#~ "\"]" + +#~ msgid "" +#~ "Wrong value format for self.defaults[\"feedrate_probe\"] or self." +#~ "options[\"feedrate_probe\"]" +#~ msgstr "" +#~ "Valoare gresita pt self.defaults[\"feedrate_probe\"] sau self." +#~ "options[\"feedrate_probe\"]" + +#~ msgid "Starting G-Code..." +#~ msgstr "Pornirea G-Code ..." + +#~ msgid "" +#~ "Algorithm to paint the polygon:
Standard: Fixed step inwards." +#~ "
Seed-based: Outwards from seed." +#~ msgstr "" +#~ "Algoritm pentru a picta poligonul
Standard: Pas fix spre " +#~ "interior.
Samanta: Spre exterior pornind de la un punct-samanta." + +#~ msgid "Seed-based" +#~ msgstr "Punct-samanta" + +#~ msgid "Straight lines" +#~ msgstr "Linii drepte" + +#~ msgid "Paint cancelled. No shape selected." +#~ msgstr "Operaţie Paint anulată. Nici-o forma selectată." + +#~ msgid "Transformation cancelled. No shape selected." +#~ msgstr "Transformare anulată. Nici-o formă nu este selectată." + +#~ msgid "Buffer cancelled. No shape selected." +#~ msgstr "" +#~ "Crearea de geometrie Bufer anulată. Nici-o forma geometrică nu este " +#~ "selectată." + +#~ msgid "Export Code cancelled." +#~ msgstr "Exportul Codului este anulat." + +#~ msgid "&Save Project ..." +#~ msgstr "&Salvează Proiect ..." + +#~ msgid "Save Project C&opy ..." +#~ msgstr "Salvează o C&opie Proiect..." + +#~ msgid "Change the size of the object." +#~ msgstr "Schimbă dimensiunea obiectului." + +#~ msgid "Change the position of this object." +#~ msgstr "Schimbă poziţia acestui obiect." + +#~ msgid "Vector" +#~ msgstr "Vector" + +#~ msgid "" +#~ "Create a CNC Job object\n" +#~ "for this drill object." +#~ msgstr "" +#~ "Crează un obiect CNCJob din\n" +#~ "acest obiect." + +#~ msgid "" +#~ "Choose what to use for GCode generation:\n" +#~ "'Drills', 'Slots' or 'Both'.\n" +#~ "When choosing 'Slots' or 'Both', slots will be\n" +#~ "converted to a series of drills." +#~ msgstr "" +#~ "Alege ce să folosești pentru generarea de G-Code:\n" +#~ "- Găuri\n" +#~ "- Sloturi\n" +#~ "- Ambele\n" +#~ "Când se alege >Sloturi< sau >Ambele<, sloturile\n" +#~ "vor fi convertite intr-o serie de găuriri." + +#~ msgid "Generate the CNC Job." +#~ msgstr "Generează un obiect CNCJob." + +#~ msgid "Add Tool from DataBase" +#~ msgstr "Adăugați Unealta din DB Unelte" + +#~ msgid "Select a theme for FlatCAM." +#~ msgstr "Selectați o temă pentru FlatCAM." + +#~ msgid "Conv." +#~ msgstr "Conv." + +#~ msgid "Diameters of the cutting tools, separated by ','" +#~ msgstr "Diametrele pentru unelte tăietoare, separate cu virgula" + +#~ msgid "Tools dia" +#~ msgstr "Dia unealtă" + +#~ msgid "The new tool diameter (cut width) to add in the tool table." +#~ msgstr "" +#~ "Noul diametru al sculei (lățimea tăiată) pt adăugare în tabelul Unelte." + +#~ msgid "" +#~ "Algorithm for non-copper clearing:
Standard: Fixed step inwards." +#~ "
Seed-based: Outwards from seed.
Line-based: Parallel " +#~ "lines." +#~ msgstr "" +#~ "Algoritm pt curățare de cupru:
Standard: Pas fix spre interior." +#~ "
Punct-samanta: De la punctul samanta, spre expterior." +#~ "
Linii drepte: Linii paralele." + +#~ msgid "Area" +#~ msgstr "Aria" + +#~ msgid "Ref" +#~ msgstr "Ref" + +#~ msgid "" +#~ "- 'Itself' - the non copper clearing extent\n" +#~ "is based on the object that is copper cleared.\n" +#~ " - 'Area Selection' - left mouse click to start selection of the area to " +#~ "be painted.\n" +#~ "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple " +#~ "areas.\n" +#~ "- 'Reference Object' - will do non copper clearing within the area\n" +#~ "specified by another object." +#~ msgstr "" +#~ "- „Însuși” - suprafața de curățare a cuprului\n" +#~ "se bazează pe obiectul care este curățat de cupru.\n" +#~ "  - „Selecție zonă” - faceți clic stânga cu mouse-ul pentru a începe " +#~ "selecția zonei care va fi pictată.\n" +#~ "Menținerea unei taste de modificare apăsată (CTRL sau SHIFT) va permite " +#~ "adăugarea mai multor zone.\n" +#~ "- „Obiect de referință” - va face o curățare fără cupru în zona\n" +#~ "specificată de un alt obiect." + +#~ msgid "Sel" +#~ msgstr "Selectează" + +#~ msgid "Diameters of nozzle tools, separated by ','" +#~ msgstr "Diametrele uneltelor (nozzle), separate prin virgula." + +#~ msgid "Reference Gerber" +#~ msgstr "Referință Gerber" + +#~ msgid "Reference Excellon" +#~ msgstr "Referință Excellon" + +#~ msgid "Reference Geometry" +#~ msgstr "Referință Geometrie" + +#~ msgid "Point/Box Reference" +#~ msgstr "Referință Punct/Container" + +#~ msgid "" +#~ "If 'Point' is selected above it store the coordinates (x, y) through " +#~ "which\n" +#~ "the mirroring axis passes.\n" +#~ "If 'Box' is selected above, select here a FlatCAM object (Gerber, Exc or " +#~ "Geo).\n" +#~ "Through the center of this object pass the mirroring axis selected above." +#~ msgstr "" +#~ "Daca 'Punct' este selectat mai sus, atunci va stoca coordonatele (x,y) " +#~ "prin care\n" +#~ "axa de oglindire trece.\n" +#~ "Daca 'Container' este selectat mai sus atunci va fi disponibila aici o " +#~ "lista de obiecte\n" +#~ "FlatCAM: Gerber, Excellon sau Geometrie. Prin mijocul geometric al " +#~ "acestor obiecte\n" +#~ "va trece axa de oglindire selectată mai sus." + +#~ msgid "Alignment Drill Diameter" +#~ msgstr "Dia. găuri de aliniere" + +#~ msgid "" +#~ "'Point' coordinates missing. Using Origin (0, 0) as mirroring reference." +#~ msgstr "" +#~ "Coord. 'Punct'-ului lipsesc. Se folosesc coord. punctului Origine (0,0) " +#~ "ca ref. pt oglindire." + +#~ msgid "Export positive film cancelled." +#~ msgstr "Exportul filmului pozitiv a fost anulat." + +#~ msgid "Export negative film cancelled." +#~ msgstr "Exportul filmului negativ a fost anulat." + +#~ msgid "Move action cancelled." +#~ msgstr "Actiunea de mutare a fost anulată." + +#~ msgid "Diameter for the new tool." +#~ msgstr "Diametrul pt noua unealtă." + +#~ msgid "Create Paint Geometry" +#~ msgstr "Crează un obiect Geometrie tip 'Paint'" + +#~ msgid "Paint Tool. Reading parameters." +#~ msgstr "Unealta Paint. Se citesc parametrii." + +#~ msgid "Normal painting area task started." +#~ msgstr "Taskul de pictare normal a unei arii a inceput." + +#~ msgid "Paint Tool. Rest machining painting area task started." +#~ msgstr "" +#~ "Unealta Paint. Taskul de pictare a unei arii cu strategia de masinare " +#~ "'rest' a inceput." + +#~ msgid "Properties Tool was not displayed. No object selected." +#~ msgstr "" +#~ "Unealta Proprietati nu a fost afișată. Nici-un obiect nu este selectat." + +#~ msgid " Export PNG cancelled." +#~ msgstr " Exportul PNG a fost anulat." + +#~ msgid "Adding Nozzle tool cancelled. Tool already in Tool Table." +#~ msgstr "" +#~ "Adăugarea unei unelte Nozzle a fost anulată. Unealta există deja in " +#~ "Tabela de Unelte." + +#~ msgid "" +#~ "None of the following args: 'ref', 'all' were found or none was set to " +#~ "1.\n" +#~ "Copper clearing failed." +#~ msgstr "" +#~ "Niciunul din următoarele argumente: „ref”, „toate” nu au fost găsite sau " +#~ "nici unul nu a fost setat la 1.\n" +#~ "Curatarea de cupru a eșuat." + #~ msgid "PostProcessor" #~ msgstr "Postprocesor" @@ -16994,9 +18266,6 @@ msgstr "" #~ msgid "Optimization Time" #~ msgstr "Durata optimizare" -#~ msgid "Defaults" -#~ msgstr "Val. Implicite" - #~ msgid "Coordinates decimals" #~ msgstr "Coord. zecimale" @@ -17065,9 +18334,6 @@ msgstr "" #~ msgid "Wk. size" #~ msgstr "Dim. Sp. Lucru" -#~ msgid "Plot Line" -#~ msgstr "Culoare contur" - #~ msgid "Sel. Fill" #~ msgstr "Culoare Selecţie" @@ -17104,12 +18370,6 @@ msgstr "" #~ msgid "Project at StartUp" #~ msgstr "Proiect la pornire" -#~ msgid "Project AutoHide" -#~ msgstr "Ascundere Proiect" - -#~ msgid "Enable ToolTips" -#~ msgstr "Activează ToolTip-uri" - #~ msgid "Mouse Cursor" #~ msgstr "Cursor de mouse" @@ -17131,9 +18391,6 @@ msgstr "" #~ msgid "G-code does not have a units code: either G20 or G21" #~ msgstr "G-code nu contine codul pt unitati: G20 sau G21" -#~ msgid "No shape selected. Select a shape to explode" -#~ msgstr "Nicio formă selectată. Selectați o formă pentru a o exploda" - #~ msgid "" #~ "- 'Rectangular' - the bounding box will be of rectangular shape.\n" #~ " - 'Minimal' - the bounding box will be the convex hull shape." @@ -17425,9 +18682,6 @@ msgstr "" #~ "Valoarea de suprapunere trebuie sa ia valori intre 0 (inclusiv) si 1 " #~ "(exclusiv), " -#~ msgid "Single Polygon" -#~ msgstr "Poligon unic" - #~ msgid "Overlap value must be between 0 (inclusive) and 1 (exclusive)" #~ msgstr "" #~ "Valoarea de suprapunere trrebuie sa ia valori intre 0 (inclusiv) si 1 " @@ -17436,9 +18690,6 @@ msgstr "" #~ msgid "Click inside the desired polygon." #~ msgstr "Click in interiorul poligonului care se dorește să fie 'pictat'." -#~ msgid "Painting polygon at location" -#~ msgstr "Se pictează poligonul aflat in pozitia" - #~ msgid "Program Author" #~ msgstr "Autorul Programului" @@ -17706,9 +18957,6 @@ msgstr "" #~ msgid "FILE ASSOCIATIONS" #~ msgstr "ASOCIERI FISIERE" -#~ msgid "Advanced Param." -#~ msgstr "Param. Avansați" - #~ msgid "MH" #~ msgstr "MH" @@ -19929,9 +21177,6 @@ msgstr "" #~ msgid "Save &Defaults" #~ msgstr "Salvează valori &Default" -#~ msgid "Line" -#~ msgstr "Linie" - #~ msgid "Tool dia: " #~ msgstr "Dia Unealtă:" diff --git a/locale_template/strings.pot b/locale_template/strings.pot index 1b9bc7d7..e76c382f 100644 --- a/locale_template/strings.pot +++ b/locale_template/strings.pot @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2019-12-28 23:09+0400\n" +"POT-Creation-Date: 2020-04-24 09:22+0300\n" "PO-Revision-Date: 2019-03-25 15:08+0200\n" "Last-Translator: \n" "Language-Team: \n" @@ -15,7 +15,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: pygettext.py 1.5\n" -"X-Generator: Poedit 2.2.3\n" +"X-Generator: Poedit 2.2.4\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-Basepath: ..\n" "X-Poedit-SearchPath-0: .\n" @@ -23,283 +23,306 @@ msgstr "" "X-Poedit-SearchPathExcluded-1: doc\n" "X-Poedit-SearchPathExcluded-2: tests\n" -#: FlatCAMApp.py:1040 +#: FlatCAMApp.py:784 FlatCAMApp.py:816 FlatCAMCommon.py:1925 FlatCAMCommon.py:2040 +#: flatcamEditors/FlatCAMGeoEditor.py:500 flatcamEditors/FlatCAMGeoEditor.py:570 +#: flatcamEditors/FlatCAMGeoEditor.py:5152 flatcamGUI/PreferencesUI.py:5509 +#: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 flatcamTools/ToolNCC.py:2401 +#: flatcamTools/ToolNCC.py:2429 flatcamTools/ToolNCC.py:2699 flatcamTools/ToolNCC.py:2731 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:1832 +#: flatcamTools/ToolPaint.py:2723 flatcamTools/ToolPaint.py:3178 +#: flatcamTools/ToolPaint.py:3544 +msgid "Seed" +msgstr "" + +#: FlatCAMApp.py:790 flatcamGUI/PreferencesUI.py:5588 flatcamGUI/PreferencesUI.py:7695 +#: flatcamTools/ToolCopperThieving.py:126 flatcamTools/ToolNCC.py:535 +#: flatcamTools/ToolNCC.py:1299 flatcamTools/ToolNCC.py:1638 flatcamTools/ToolNCC.py:1919 +#: flatcamTools/ToolNCC.py:1983 flatcamTools/ToolNCC.py:2967 flatcamTools/ToolNCC.py:2976 +msgid "Itself" +msgstr "" + +#: FlatCAMApp.py:817 flatcamGUI/PreferencesUI.py:6119 flatcamTools/ToolPaint.py:486 +#: flatcamTools/ToolPaint.py:1415 +msgid "All Polygons" +msgstr "" + +#: FlatCAMApp.py:1124 msgid "FlatCAM is initializing ..." msgstr "" -#: FlatCAMApp.py:1669 +#: FlatCAMApp.py:1809 msgid "Could not find the Language files. The App strings are missing." msgstr "" -#: FlatCAMApp.py:1763 +#: FlatCAMApp.py:1903 msgid "" "FlatCAM is initializing ...\n" "Canvas initialization started." msgstr "" -#: FlatCAMApp.py:1781 +#: FlatCAMApp.py:1923 msgid "" "FlatCAM is initializing ...\n" "Canvas initialization started.\n" "Canvas initialization finished in" msgstr "" -#: FlatCAMApp.py:2401 -msgid "" -"Type >help< to get started\n" -"\n" +#: FlatCAMApp.py:2565 flatcamGUI/GUIElements.py:2592 +msgid "Type >help< to get started" msgstr "" -#: FlatCAMApp.py:2627 FlatCAMApp.py:9020 +#: FlatCAMApp.py:2817 FlatCAMApp.py:9393 msgid "New Project - Not saved" msgstr "" -#: FlatCAMApp.py:2702 FlatCAMApp.py:9088 FlatCAMApp.py:9125 FlatCAMApp.py:9166 -#: FlatCAMApp.py:9237 FlatCAMApp.py:9991 FlatCAMApp.py:11174 FlatCAMApp.py:11233 -msgid "" -"Canvas initialization started.\n" -"Canvas initialization finished in" -msgstr "" - -#: FlatCAMApp.py:2704 -msgid "Executing Tcl Script ..." -msgstr "" - -#: FlatCAMApp.py:2719 +#: FlatCAMApp.py:2913 msgid "Found old default preferences files. Please reboot the application to update." msgstr "" -#: FlatCAMApp.py:2763 ObjectCollection.py:90 flatcamTools/ToolImage.py:248 -#: flatcamTools/ToolPcbWizard.py:301 flatcamTools/ToolPcbWizard.py:324 -msgid "Open cancelled." +#: FlatCAMApp.py:2964 FlatCAMApp.py:3884 FlatCAMApp.py:3933 FlatCAMApp.py:3988 +#: FlatCAMApp.py:4063 FlatCAMApp.py:6111 FlatCAMApp.py:9477 FlatCAMApp.py:9514 +#: FlatCAMApp.py:9556 FlatCAMApp.py:9585 FlatCAMApp.py:9625 FlatCAMApp.py:9650 +#: FlatCAMApp.py:9702 FlatCAMApp.py:9738 FlatCAMApp.py:9784 FlatCAMApp.py:9825 +#: FlatCAMApp.py:9866 FlatCAMApp.py:9907 FlatCAMApp.py:9948 FlatCAMApp.py:9992 +#: FlatCAMApp.py:10048 FlatCAMApp.py:10080 FlatCAMApp.py:10112 FlatCAMApp.py:10349 +#: FlatCAMApp.py:10393 FlatCAMApp.py:10470 FlatCAMApp.py:10525 FlatCAMCommon.py:371 +#: FlatCAMCommon.py:413 FlatCAMCommon.py:1107 FlatCAMCommon.py:1153 FlatCAMCommon.py:2537 +#: FlatCAMCommon.py:2583 ObjectCollection.py:122 flatcamEditors/FlatCAMExcEditor.py:1024 +#: flatcamEditors/FlatCAMExcEditor.py:1092 flatcamEditors/FlatCAMTextEditor.py:223 +#: flatcamGUI/FlatCAMGUI.py:3389 flatcamGUI/FlatCAMGUI.py:3601 flatcamGUI/FlatCAMGUI.py:3812 +#: flatcamTools/ToolFilm.py:754 flatcamTools/ToolFilm.py:900 flatcamTools/ToolImage.py:247 +#: flatcamTools/ToolMove.py:270 flatcamTools/ToolPcbWizard.py:301 +#: flatcamTools/ToolPcbWizard.py:324 flatcamTools/ToolQRCode.py:791 +#: flatcamTools/ToolQRCode.py:838 +msgid "Cancelled." msgstr "" -#: FlatCAMApp.py:2779 +#: FlatCAMApp.py:2980 msgid "Open Config file failed." msgstr "" -#: FlatCAMApp.py:2794 +#: FlatCAMApp.py:2995 msgid "Open Script file failed." msgstr "" -#: FlatCAMApp.py:2820 +#: FlatCAMApp.py:3021 msgid "Open Excellon file failed." msgstr "" -#: FlatCAMApp.py:2833 +#: FlatCAMApp.py:3034 msgid "Open GCode file failed." msgstr "" -#: FlatCAMApp.py:2846 +#: FlatCAMApp.py:3047 msgid "Open Gerber file failed." msgstr "" -#: FlatCAMApp.py:3201 +#: FlatCAMApp.py:3424 msgid "Select a Geometry, Gerber or Excellon Object to edit." msgstr "" -#: FlatCAMApp.py:3216 +#: FlatCAMApp.py:3439 msgid "" "Simultaneous editing of tools geometry in a MultiGeo Geometry is not possible.\n" "Edit only one geometry at a time." msgstr "" -#: FlatCAMApp.py:3271 +#: FlatCAMApp.py:3497 msgid "Editor is activated ..." msgstr "" -#: FlatCAMApp.py:3292 +#: FlatCAMApp.py:3518 msgid "Do you want to save the edited object?" msgstr "" -#: FlatCAMApp.py:3293 flatcamGUI/FlatCAMGUI.py:2165 +#: FlatCAMApp.py:3519 flatcamGUI/FlatCAMGUI.py:2273 msgid "Close Editor" msgstr "" -#: FlatCAMApp.py:3296 FlatCAMApp.py:4014 FlatCAMApp.py:5067 FlatCAMApp.py:7724 -#: FlatCAMApp.py:7750 FlatCAMApp.py:8927 FlatCAMTranslation.py:108 FlatCAMTranslation.py:193 +#: FlatCAMApp.py:3522 FlatCAMApp.py:5163 FlatCAMApp.py:8023 FlatCAMApp.py:8049 +#: FlatCAMApp.py:9298 FlatCAMTranslation.py:108 FlatCAMTranslation.py:199 +#: flatcamGUI/FlatCAMGUI.py:2479 msgid "Yes" msgstr "" -#: FlatCAMApp.py:3297 FlatCAMApp.py:4015 FlatCAMApp.py:5068 FlatCAMApp.py:7725 -#: FlatCAMApp.py:7751 FlatCAMApp.py:8928 FlatCAMTranslation.py:109 FlatCAMTranslation.py:194 -#: flatcamGUI/PreferencesUI.py:5139 flatcamGUI/PreferencesUI.py:5554 -#: flatcamTools/ToolNonCopperClear.py:189 flatcamTools/ToolPaint.py:161 +#: FlatCAMApp.py:3523 FlatCAMApp.py:5164 FlatCAMApp.py:8024 FlatCAMApp.py:8050 +#: FlatCAMApp.py:9299 FlatCAMTranslation.py:109 FlatCAMTranslation.py:200 +#: flatcamGUI/FlatCAMGUI.py:2480 flatcamGUI/PreferencesUI.py:5443 +#: flatcamGUI/PreferencesUI.py:5989 flatcamTools/ToolNCC.py:182 +#: flatcamTools/ToolPaint.py:166 msgid "No" msgstr "" -#: FlatCAMApp.py:3298 FlatCAMApp.py:5069 FlatCAMApp.py:5925 FlatCAMApp.py:7006 -#: FlatCAMApp.py:8929 FlatCAMCommon.py:571 flatcamGUI/FlatCAMGUI.py:1260 +#: FlatCAMApp.py:3524 FlatCAMApp.py:5165 FlatCAMApp.py:6049 FlatCAMApp.py:7000 +#: FlatCAMApp.py:9300 FlatCAMCommon.py:572 FlatCAMCommon.py:2127 +#: flatcamGUI/FlatCAMGUI.py:1332 msgid "Cancel" msgstr "" -#: FlatCAMApp.py:3326 +#: FlatCAMApp.py:3556 msgid "Object empty after edit." msgstr "" -#: FlatCAMApp.py:3375 FlatCAMApp.py:3395 FlatCAMApp.py:3410 +#: FlatCAMApp.py:3560 FlatCAMApp.py:3581 FlatCAMApp.py:3603 +msgid "Editor exited. Editor content saved." +msgstr "" + +#: FlatCAMApp.py:3607 FlatCAMApp.py:3630 FlatCAMApp.py:3648 msgid "Select a Gerber, Geometry or Excellon Object to update." msgstr "" -#: FlatCAMApp.py:3379 +#: FlatCAMApp.py:3610 msgid "is updated, returning to App..." msgstr "" -#: FlatCAMApp.py:3774 FlatCAMApp.py:3888 FlatCAMApp.py:4929 +#: FlatCAMApp.py:3617 +msgid "Editor exited. Editor content was not saved." +msgstr "" + +#: FlatCAMApp.py:3810 FlatCAMApp.py:3941 FlatCAMApp.py:5012 msgid "Could not load defaults file." msgstr "" -#: FlatCAMApp.py:3786 FlatCAMApp.py:3896 FlatCAMApp.py:4938 +#: FlatCAMApp.py:3822 FlatCAMApp.py:3949 FlatCAMApp.py:5021 msgid "Failed to parse defaults file." msgstr "" -#: FlatCAMApp.py:3831 -msgid "Preferences default restore was cancelled." -msgstr "" - -#: FlatCAMApp.py:3839 FlatCAMApp.py:5017 +#: FlatCAMApp.py:3892 FlatCAMApp.py:5113 msgid "Could not load factory defaults file." msgstr "" -#: FlatCAMApp.py:3847 FlatCAMApp.py:5027 +#: FlatCAMApp.py:3900 FlatCAMApp.py:5123 msgid "Failed to parse factory defaults file." msgstr "" -#: FlatCAMApp.py:3855 +#: FlatCAMApp.py:3908 msgid "Preferences default values are restored." msgstr "" -#: FlatCAMApp.py:3870 FlatCAMApp.py:3874 +#: FlatCAMApp.py:3923 FlatCAMApp.py:3927 msgid "Import FlatCAM Preferences" msgstr "" -#: FlatCAMApp.py:3880 -msgid "FlatCAM preferences import cancelled." -msgstr "" - -#: FlatCAMApp.py:3904 +#: FlatCAMApp.py:3957 msgid "Imported Defaults from" msgstr "" -#: FlatCAMApp.py:3924 FlatCAMApp.py:3929 +#: FlatCAMApp.py:3977 FlatCAMApp.py:3982 msgid "Export FlatCAM Preferences" msgstr "" -#: FlatCAMApp.py:3936 -msgid "FlatCAM preferences export cancelled." -msgstr "" - -#: FlatCAMApp.py:3945 FlatCAMApp.py:10389 FlatCAMApp.py:10437 FlatCAMApp.py:10560 -#: FlatCAMApp.py:10699 FlatCAMCommon.py:378 FlatCAMCommon.py:1114 FlatCAMObj.py:6903 -#: flatcamEditors/FlatCAMTextEditor.py:274 flatcamTools/ToolFilm.py:1019 -#: flatcamTools/ToolFilm.py:1195 flatcamTools/ToolSolderPaste.py:1544 +#: FlatCAMApp.py:3997 FlatCAMApp.py:4071 FlatCAMApp.py:10769 FlatCAMApp.py:10817 +#: FlatCAMApp.py:10943 FlatCAMApp.py:11080 FlatCAMCommon.py:379 FlatCAMCommon.py:1115 +#: FlatCAMCommon.py:2545 FlatCAMObj.py:7484 flatcamEditors/FlatCAMTextEditor.py:276 +#: flatcamTools/ToolFilm.py:1031 flatcamTools/ToolFilm.py:1212 +#: flatcamTools/ToolSolderPaste.py:1533 msgid "" "Permission denied, saving not possible.\n" "Most likely another app is holding the file open and not accessible." msgstr "" -#: FlatCAMApp.py:3957 +#: FlatCAMApp.py:4009 msgid "Could not load preferences file." msgstr "" -#: FlatCAMApp.py:3976 FlatCAMApp.py:4985 +#: FlatCAMApp.py:4028 FlatCAMApp.py:4095 FlatCAMApp.py:5040 msgid "Failed to write defaults to file." msgstr "" -#: FlatCAMApp.py:3981 +#: FlatCAMApp.py:4033 msgid "Exported preferences to" msgstr "" -#: FlatCAMApp.py:3998 -msgid "FlatCAM Preferences Folder opened." +#: FlatCAMApp.py:4053 FlatCAMApp.py:4058 +msgid "Save to file" msgstr "" -#: FlatCAMApp.py:4009 -msgid "Are you sure you want to delete the GUI Settings? \n" +#: FlatCAMApp.py:4082 +msgid "Could not load the file." msgstr "" -#: FlatCAMApp.py:4012 flatcamGUI/FlatCAMGUI.py:1230 -msgid "Clear GUI Settings" +#: FlatCAMApp.py:4098 +msgid "Exported file to" msgstr "" -#: FlatCAMApp.py:4109 +#: FlatCAMApp.py:4181 msgid "Failed to open recent files file for writing." msgstr "" -#: FlatCAMApp.py:4120 +#: FlatCAMApp.py:4192 msgid "Failed to open recent projects file for writing." msgstr "" -#: FlatCAMApp.py:4205 FlatCAMApp.py:10900 FlatCAMApp.py:10961 FlatCAMApp.py:11090 -#: FlatCAMObj.py:5050 flatcamEditors/FlatCAMGrbEditor.py:4187 -#: flatcamTools/ToolPcbWizard.py:437 +#: FlatCAMApp.py:4277 FlatCAMApp.py:11276 FlatCAMApp.py:11335 FlatCAMApp.py:11463 +#: FlatCAMApp.py:12189 FlatCAMObj.py:5605 flatcamEditors/FlatCAMGrbEditor.py:4231 +#: flatcamTools/ToolPcbWizard.py:433 msgid "An internal error has occurred. See shell.\n" msgstr "" -#: FlatCAMApp.py:4206 +#: FlatCAMApp.py:4278 #, python-brace-format msgid "" "Object ({kind}) failed because: {error} \n" "\n" msgstr "" -#: FlatCAMApp.py:4221 +#: FlatCAMApp.py:4293 msgid "Converting units to " msgstr "" -#: FlatCAMApp.py:4324 +#: FlatCAMApp.py:4406 msgid "CREATE A NEW FLATCAM TCL SCRIPT" msgstr "" -#: FlatCAMApp.py:4325 +#: FlatCAMApp.py:4407 msgid "TCL Tutorial is here" msgstr "" -#: FlatCAMApp.py:4327 +#: FlatCAMApp.py:4409 msgid "FlatCAM commands list" msgstr "" -#: FlatCAMApp.py:4378 FlatCAMApp.py:4384 FlatCAMApp.py:4390 FlatCAMApp.py:4396 -#: FlatCAMApp.py:4402 FlatCAMApp.py:4408 +#: FlatCAMApp.py:4460 FlatCAMApp.py:4466 FlatCAMApp.py:4472 FlatCAMApp.py:4478 +#: FlatCAMApp.py:4484 FlatCAMApp.py:4490 msgid "created/selected" msgstr "" -#: FlatCAMApp.py:4423 FlatCAMApp.py:7086 FlatCAMObj.py:271 FlatCAMObj.py:302 -#: FlatCAMObj.py:318 FlatCAMObj.py:398 flatcamTools/ToolCopperThieving.py:1476 -#: flatcamTools/ToolFiducials.py:807 flatcamTools/ToolMove.py:220 -#: flatcamTools/ToolQRCode.py:726 +#: FlatCAMApp.py:4505 FlatCAMApp.py:7086 FlatCAMObj.py:278 FlatCAMObj.py:309 +#: FlatCAMObj.py:325 FlatCAMObj.py:405 flatcamTools/ToolCopperThieving.py:1482 +#: flatcamTools/ToolFiducials.py:809 flatcamTools/ToolMove.py:230 +#: flatcamTools/ToolQRCode.py:728 msgid "Plotting" msgstr "" -#: FlatCAMApp.py:4486 flatcamGUI/FlatCAMGUI.py:491 +#: FlatCAMApp.py:4568 flatcamGUI/FlatCAMGUI.py:530 msgid "About FlatCAM" msgstr "" -#: FlatCAMApp.py:4512 +#: FlatCAMApp.py:4594 msgid "2D Computer-Aided Printed Circuit Board Manufacturing" msgstr "" -#: FlatCAMApp.py:4513 +#: FlatCAMApp.py:4595 msgid "Development" msgstr "" -#: FlatCAMApp.py:4514 +#: FlatCAMApp.py:4596 msgid "DOWNLOAD" msgstr "" -#: FlatCAMApp.py:4515 +#: FlatCAMApp.py:4597 msgid "Issue tracker" msgstr "" -#: FlatCAMApp.py:4519 FlatCAMApp.py:4860 +#: FlatCAMApp.py:4601 FlatCAMApp.py:4942 flatcamGUI/GUIElements.py:2583 msgid "Close" msgstr "" -#: FlatCAMApp.py:4534 +#: FlatCAMApp.py:4616 msgid "Licensed under the MIT license" msgstr "" -#: FlatCAMApp.py:4543 +#: FlatCAMApp.py:4625 msgid "" "Permission is hereby granted, free of charge, to any person obtaining a copy\n" "of this software and associated documentation files (the \"Software\"), to deal\n" @@ -320,7 +343,7 @@ msgid "" "THE SOFTWARE." msgstr "" -#: FlatCAMApp.py:4565 +#: FlatCAMApp.py:4647 msgid "" "Some of the icons used are from the following sources:
Icons by Freepik from oNline Web Fonts" msgstr "" -#: FlatCAMApp.py:4597 +#: FlatCAMApp.py:4679 msgid "Splash" msgstr "" -#: FlatCAMApp.py:4603 +#: FlatCAMApp.py:4685 msgid "Programmers" msgstr "" -#: FlatCAMApp.py:4609 +#: FlatCAMApp.py:4691 msgid "Translators" msgstr "" -#: FlatCAMApp.py:4615 +#: FlatCAMApp.py:4697 msgid "License" msgstr "" -#: FlatCAMApp.py:4621 +#: FlatCAMApp.py:4703 msgid "Attributions" msgstr "" -#: FlatCAMApp.py:4644 +#: FlatCAMApp.py:4726 msgid "Programmer" msgstr "" -#: FlatCAMApp.py:4645 +#: FlatCAMApp.py:4727 msgid "Status" msgstr "" -#: FlatCAMApp.py:4646 FlatCAMApp.py:4724 +#: FlatCAMApp.py:4728 FlatCAMApp.py:4806 msgid "E-mail" msgstr "" -#: FlatCAMApp.py:4654 +#: FlatCAMApp.py:4736 msgid "BETA Maintainer >= 2019" msgstr "" -#: FlatCAMApp.py:4721 +#: FlatCAMApp.py:4803 msgid "Language" msgstr "" -#: FlatCAMApp.py:4722 +#: FlatCAMApp.py:4804 msgid "Translator" msgstr "" -#: FlatCAMApp.py:4723 +#: FlatCAMApp.py:4805 msgid "Corrections" msgstr "" -#: FlatCAMApp.py:4832 FlatCAMApp.py:4840 FlatCAMApp.py:7769 flatcamGUI/FlatCAMGUI.py:473 +#: FlatCAMApp.py:4914 FlatCAMApp.py:4922 FlatCAMApp.py:8068 flatcamGUI/FlatCAMGUI.py:512 msgid "Bookmarks Manager" msgstr "" -#: FlatCAMApp.py:4851 +#: FlatCAMApp.py:4933 msgid "" "This entry will resolve to another website if:\n" "\n" @@ -393,53 +416,53 @@ msgid "" "use the YouTube channel link from the Help menu." msgstr "" -#: FlatCAMApp.py:4858 +#: FlatCAMApp.py:4940 msgid "Alternative website" msgstr "" -#: FlatCAMApp.py:4989 FlatCAMApp.py:7733 +#: FlatCAMApp.py:5044 FlatCAMApp.py:8032 msgid "Preferences saved." msgstr "" -#: FlatCAMApp.py:5043 +#: FlatCAMApp.py:5139 msgid "Failed to write factory defaults to file." msgstr "" -#: FlatCAMApp.py:5047 +#: FlatCAMApp.py:5143 msgid "Factory defaults saved." msgstr "" -#: FlatCAMApp.py:5057 flatcamGUI/FlatCAMGUI.py:3962 +#: FlatCAMApp.py:5153 flatcamGUI/FlatCAMGUI.py:4178 msgid "Application is saving the project. Please wait ..." msgstr "" -#: FlatCAMApp.py:5062 FlatCAMTranslation.py:188 +#: FlatCAMApp.py:5158 FlatCAMTranslation.py:194 msgid "" "There are files/objects modified in FlatCAM. \n" "Do you want to Save the project?" msgstr "" -#: FlatCAMApp.py:5065 FlatCAMApp.py:8925 FlatCAMTranslation.py:191 +#: FlatCAMApp.py:5161 FlatCAMApp.py:9296 FlatCAMTranslation.py:197 msgid "Save changes" msgstr "" -#: FlatCAMApp.py:5306 +#: FlatCAMApp.py:5417 msgid "Selected Excellon file extensions registered with FlatCAM." msgstr "" -#: FlatCAMApp.py:5328 +#: FlatCAMApp.py:5439 msgid "Selected GCode file extensions registered with FlatCAM." msgstr "" -#: FlatCAMApp.py:5350 +#: FlatCAMApp.py:5461 msgid "Selected Gerber file extensions registered with FlatCAM." msgstr "" -#: FlatCAMApp.py:5538 FlatCAMApp.py:5595 FlatCAMApp.py:5623 +#: FlatCAMApp.py:5649 FlatCAMApp.py:5708 FlatCAMApp.py:5736 msgid "At least two objects are required for join. Objects currently selected" msgstr "" -#: FlatCAMApp.py:5547 +#: FlatCAMApp.py:5658 msgid "" "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 " @@ -449,51 +472,47 @@ msgid "" "Check the generated GCODE." msgstr "" -#: FlatCAMApp.py:5559 -msgid "Multigeo. Geometry merging finished" -msgstr "" - -#: FlatCAMApp.py:5568 +#: FlatCAMApp.py:5670 FlatCAMApp.py:5680 msgid "Geometry merging finished" msgstr "" -#: FlatCAMApp.py:5590 +#: FlatCAMApp.py:5703 msgid "Failed. Excellon joining works only on Excellon objects." msgstr "" -#: FlatCAMApp.py:5600 +#: FlatCAMApp.py:5713 msgid "Excellon merging finished" msgstr "" -#: FlatCAMApp.py:5618 +#: FlatCAMApp.py:5731 msgid "Failed. Gerber joining works only on Gerber objects." msgstr "" -#: FlatCAMApp.py:5628 +#: FlatCAMApp.py:5741 msgid "Gerber merging finished" msgstr "" -#: FlatCAMApp.py:5648 FlatCAMApp.py:5683 +#: FlatCAMApp.py:5761 FlatCAMApp.py:5796 msgid "Failed. Select a Geometry Object and try again." msgstr "" -#: FlatCAMApp.py:5652 FlatCAMApp.py:5688 +#: FlatCAMApp.py:5765 FlatCAMApp.py:5801 msgid "Expected a FlatCAMGeometry, got" msgstr "" -#: FlatCAMApp.py:5665 +#: FlatCAMApp.py:5778 msgid "A Geometry object was converted to MultiGeo type." msgstr "" -#: FlatCAMApp.py:5703 +#: FlatCAMApp.py:5816 msgid "A Geometry object was converted to SingleGeo type." msgstr "" -#: FlatCAMApp.py:5919 +#: FlatCAMApp.py:6043 msgid "Toggle Units" msgstr "" -#: FlatCAMApp.py:5921 +#: FlatCAMApp.py:6045 msgid "" "Changing the units of the project\n" "will scale all objects.\n" @@ -501,72 +520,68 @@ msgid "" "Do you want to continue?" msgstr "" -#: FlatCAMApp.py:5924 FlatCAMApp.py:6929 FlatCAMApp.py:7005 FlatCAMApp.py:9290 -#: FlatCAMApp.py:9304 FlatCAMApp.py:9658 FlatCAMApp.py:9669 +#: FlatCAMApp.py:6048 FlatCAMApp.py:6922 FlatCAMApp.py:6999 FlatCAMApp.py:9669 +#: FlatCAMApp.py:9683 FlatCAMApp.py:10018 FlatCAMApp.py:10028 msgid "Ok" msgstr "" -#: FlatCAMApp.py:5973 +#: FlatCAMApp.py:6097 msgid "Converted units to" msgstr "" -#: FlatCAMApp.py:5987 -msgid "Units conversion cancelled." -msgstr "" - -#: FlatCAMApp.py:6613 +#: FlatCAMApp.py:6737 msgid "Detachable Tabs" msgstr "" -#: FlatCAMApp.py:6828 FlatCAMApp.py:6889 FlatCAMApp.py:7560 FlatCAMApp.py:7622 -#: FlatCAMApp.py:7688 +#: FlatCAMApp.py:6811 FlatCAMApp.py:6855 FlatCAMApp.py:6883 FlatCAMApp.py:7815 +#: FlatCAMApp.py:7883 FlatCAMApp.py:7987 msgid "Preferences" msgstr "" -#: FlatCAMApp.py:6831 +#: FlatCAMApp.py:6817 msgid "Preferences applied." msgstr "" -#: FlatCAMApp.py:6894 +#: FlatCAMApp.py:6888 msgid "Preferences closed without saving." msgstr "" -#: FlatCAMApp.py:6917 flatcamTools/ToolNonCopperClear.py:591 -#: flatcamTools/ToolNonCopperClear.py:987 flatcamTools/ToolPaint.py:502 -#: flatcamTools/ToolSolderPaste.py:562 flatcamTools/ToolSolderPaste.py:892 +#: FlatCAMApp.py:6911 flatcamTools/ToolNCC.py:930 flatcamTools/ToolNCC.py:1435 +#: flatcamTools/ToolPaint.py:855 flatcamTools/ToolSolderPaste.py:568 +#: flatcamTools/ToolSolderPaste.py:893 msgid "Please enter a tool diameter with non-zero value, in Float format." msgstr "" -#: FlatCAMApp.py:6922 flatcamTools/ToolNonCopperClear.py:595 flatcamTools/ToolPaint.py:506 -#: flatcamTools/ToolSolderPaste.py:566 +#: FlatCAMApp.py:6915 flatcamTools/ToolNCC.py:934 flatcamTools/ToolPaint.py:859 +#: flatcamTools/ToolSolderPaste.py:572 msgid "Adding Tool cancelled" msgstr "" -#: FlatCAMApp.py:6925 +#: FlatCAMApp.py:6918 msgid "" "Adding Tool works only when Advanced is checked.\n" "Go to Preferences -> General - Show Advanced Options." msgstr "" -#: FlatCAMApp.py:7000 +#: FlatCAMApp.py:6994 msgid "Delete objects" msgstr "" -#: FlatCAMApp.py:7003 +#: FlatCAMApp.py:6997 msgid "" "Are you sure you want to permanently delete\n" "the selected objects?" msgstr "" -#: FlatCAMApp.py:7034 +#: FlatCAMApp.py:7035 msgid "Object(s) deleted" msgstr "" -#: FlatCAMApp.py:7038 flatcamTools/ToolDblSided.py:713 +#: FlatCAMApp.py:7039 FlatCAMApp.py:7194 flatcamTools/ToolDblSided.py:819 msgid "Failed. No object(s) selected..." msgstr "" -#: FlatCAMApp.py:7040 +#: FlatCAMApp.py:7041 msgid "Save the work in Editor and try again ..." msgstr "" @@ -582,811 +597,738 @@ msgstr "" msgid "Setting Origin..." msgstr "" -#: FlatCAMApp.py:7131 +#: FlatCAMApp.py:7132 FlatCAMApp.py:7234 msgid "Origin set" msgstr "" -#: FlatCAMApp.py:7138 +#: FlatCAMApp.py:7149 msgid "Origin coordinates specified but incomplete." msgstr "" -#: FlatCAMApp.py:7197 +#: FlatCAMApp.py:7190 +msgid "Moving to Origin..." +msgstr "" + +#: FlatCAMApp.py:7271 msgid "Jump to ..." msgstr "" -#: FlatCAMApp.py:7198 +#: FlatCAMApp.py:7272 msgid "Enter the coordinates in format X,Y:" msgstr "" -#: FlatCAMApp.py:7208 +#: FlatCAMApp.py:7282 msgid "Wrong coordinates. Enter coordinates in format: X,Y" msgstr "" -#: FlatCAMApp.py:7288 flatcamEditors/FlatCAMExcEditor.py:3599 -#: flatcamEditors/FlatCAMExcEditor.py:3607 flatcamEditors/FlatCAMGeoEditor.py:4036 -#: flatcamEditors/FlatCAMGeoEditor.py:4051 flatcamEditors/FlatCAMGrbEditor.py:1086 -#: flatcamEditors/FlatCAMGrbEditor.py:1203 flatcamEditors/FlatCAMGrbEditor.py:1489 -#: flatcamEditors/FlatCAMGrbEditor.py:1758 flatcamEditors/FlatCAMGrbEditor.py:4445 -#: flatcamEditors/FlatCAMGrbEditor.py:4460 flatcamGUI/FlatCAMGUI.py:3145 -#: flatcamGUI/FlatCAMGUI.py:3157 +#: FlatCAMApp.py:7360 FlatCAMApp.py:7509 flatcamEditors/FlatCAMExcEditor.py:3622 +#: flatcamEditors/FlatCAMExcEditor.py:3630 flatcamEditors/FlatCAMGeoEditor.py:4349 +#: flatcamEditors/FlatCAMGeoEditor.py:4363 flatcamEditors/FlatCAMGrbEditor.py:1085 +#: flatcamEditors/FlatCAMGrbEditor.py:1202 flatcamEditors/FlatCAMGrbEditor.py:1488 +#: flatcamEditors/FlatCAMGrbEditor.py:1757 flatcamEditors/FlatCAMGrbEditor.py:4489 +#: flatcamEditors/FlatCAMGrbEditor.py:4504 flatcamGUI/FlatCAMGUI.py:3370 +#: flatcamGUI/FlatCAMGUI.py:3382 flatcamTools/ToolAlignObjects.py:393 +#: flatcamTools/ToolAlignObjects.py:415 msgid "Done." msgstr "" -#: FlatCAMApp.py:7440 FlatCAMApp.py:7511 +#: FlatCAMApp.py:7375 FlatCAMApp.py:9665 FlatCAMApp.py:9761 FlatCAMApp.py:9803 +#: FlatCAMApp.py:9844 FlatCAMApp.py:9885 FlatCAMApp.py:9926 FlatCAMApp.py:9970 +#: FlatCAMApp.py:10014 FlatCAMApp.py:10503 FlatCAMApp.py:10507 +#: flatcamTools/ToolProperties.py:116 +msgid "No object selected." +msgstr "" + +#: FlatCAMApp.py:7394 +msgid "Bottom-Left" +msgstr "" + +#: FlatCAMApp.py:7395 flatcamGUI/PreferencesUI.py:8111 flatcamTools/ToolCalibration.py:159 +msgid "Top-Left" +msgstr "" + +#: FlatCAMApp.py:7396 flatcamGUI/PreferencesUI.py:8112 flatcamTools/ToolCalibration.py:160 +msgid "Bottom-Right" +msgstr "" + +#: FlatCAMApp.py:7397 +msgid "Top-Right" +msgstr "" + +#: FlatCAMApp.py:7398 flatcamGUI/ObjectUI.py:2624 +msgid "Center" +msgstr "" + +#: FlatCAMApp.py:7418 +msgid "Locate ..." +msgstr "" + +#: FlatCAMApp.py:7679 FlatCAMApp.py:7756 msgid "No object is selected. Select an object and try again." msgstr "" -#: FlatCAMApp.py:7531 +#: FlatCAMApp.py:7782 msgid "Aborting. The current task will be gracefully closed as soon as possible..." msgstr "" -#: FlatCAMApp.py:7537 +#: FlatCAMApp.py:7787 msgid "The current task was gracefully closed on user request..." msgstr "" -#: FlatCAMApp.py:7619 +#: FlatCAMApp.py:7880 msgid "Preferences edited but not saved." msgstr "" -#: FlatCAMApp.py:7633 FlatCAMApp.py:7645 FlatCAMApp.py:7662 FlatCAMApp.py:7679 -#: FlatCAMApp.py:7739 FlatCAMCommon.py:1181 FlatCAMCommon.py:1356 FlatCAMObj.py:4256 +#: FlatCAMApp.py:7897 FlatCAMApp.py:7925 FlatCAMApp.py:7952 FlatCAMApp.py:7971 +#: FlatCAMApp.py:8038 FlatCAMCommon.py:1182 FlatCAMCommon.py:1357 FlatCAMCommon.py:2612 +#: FlatCAMCommon.py:2820 FlatCAMObj.py:4798 flatcamTools/ToolNCC.py:3963 +#: flatcamTools/ToolNCC.py:4047 flatcamTools/ToolPaint.py:4027 +#: flatcamTools/ToolPaint.py:4112 msgid "Tools Database" msgstr "" -#: FlatCAMApp.py:7659 +#: FlatCAMApp.py:7949 msgid "Tools in Tools Database edited but not saved." msgstr "" -#: FlatCAMApp.py:7683 +#: FlatCAMApp.py:7975 flatcamTools/ToolNCC.py:3970 flatcamTools/ToolPaint.py:4034 msgid "Tool from DB added in Tool Table." msgstr "" -#: FlatCAMApp.py:7685 +#: FlatCAMApp.py:7977 msgid "Adding tool from DB is not allowed for this object." msgstr "" -#: FlatCAMApp.py:7719 +#: FlatCAMApp.py:8018 msgid "" "One or more values are changed.\n" "Do you want to save the Preferences?" msgstr "" -#: FlatCAMApp.py:7721 flatcamGUI/FlatCAMGUI.py:222 +#: FlatCAMApp.py:8020 flatcamGUI/FlatCAMGUI.py:291 msgid "Save Preferences" msgstr "" -#: FlatCAMApp.py:7745 +#: FlatCAMApp.py:8044 msgid "" "One or more Tools are edited.\n" "Do you want to update the Tools Database?" msgstr "" -#: FlatCAMApp.py:7747 +#: FlatCAMApp.py:8046 msgid "Save Tools Database" msgstr "" -#: FlatCAMApp.py:7766 FlatCAMApp.py:9897 FlatCAMObj.py:6509 +#: FlatCAMApp.py:8065 FlatCAMApp.py:10252 FlatCAMObj.py:7089 msgid "Code Editor" msgstr "" -#: FlatCAMApp.py:7784 +#: FlatCAMApp.py:8087 msgid "No object selected to Flip on Y axis." msgstr "" -#: FlatCAMApp.py:7810 +#: FlatCAMApp.py:8113 msgid "Flip on Y axis done." msgstr "" -#: FlatCAMApp.py:7812 FlatCAMApp.py:7854 flatcamEditors/FlatCAMGrbEditor.py:5858 +#: FlatCAMApp.py:8115 FlatCAMApp.py:8163 flatcamEditors/FlatCAMGrbEditor.py:5893 msgid "Flip action was not executed." msgstr "" -#: FlatCAMApp.py:7826 +#: FlatCAMApp.py:8135 msgid "No object selected to Flip on X axis." msgstr "" -#: FlatCAMApp.py:7852 +#: FlatCAMApp.py:8161 msgid "Flip on X axis done." msgstr "" -#: FlatCAMApp.py:7868 +#: FlatCAMApp.py:8183 msgid "No object selected to Rotate." msgstr "" -#: FlatCAMApp.py:7871 FlatCAMApp.py:7918 FlatCAMApp.py:7951 +#: FlatCAMApp.py:8186 FlatCAMApp.py:8239 FlatCAMApp.py:8278 msgid "Transform" msgstr "" -#: FlatCAMApp.py:7871 FlatCAMApp.py:7918 FlatCAMApp.py:7951 +#: FlatCAMApp.py:8186 FlatCAMApp.py:8239 FlatCAMApp.py:8278 msgid "Enter the Angle value:" msgstr "" -#: FlatCAMApp.py:7902 +#: FlatCAMApp.py:8217 msgid "Rotation done." msgstr "" -#: FlatCAMApp.py:7904 +#: FlatCAMApp.py:8219 msgid "Rotation movement was not executed." msgstr "" -#: FlatCAMApp.py:7916 +#: FlatCAMApp.py:8237 msgid "No object selected to Skew/Shear on X axis." msgstr "" -#: FlatCAMApp.py:7938 +#: FlatCAMApp.py:8259 msgid "Skew on X axis done." msgstr "" -#: FlatCAMApp.py:7949 +#: FlatCAMApp.py:8276 msgid "No object selected to Skew/Shear on Y axis." msgstr "" -#: FlatCAMApp.py:7971 +#: FlatCAMApp.py:8298 msgid "Skew on Y axis done." msgstr "" -#: FlatCAMApp.py:8119 FlatCAMApp.py:8166 flatcamGUI/FlatCAMGUI.py:449 -#: flatcamGUI/FlatCAMGUI.py:1612 +#: FlatCAMApp.py:8451 FlatCAMApp.py:8498 flatcamGUI/FlatCAMGUI.py:488 +#: flatcamGUI/FlatCAMGUI.py:1713 msgid "Select All" msgstr "" -#: FlatCAMApp.py:8123 FlatCAMApp.py:8170 flatcamGUI/FlatCAMGUI.py:451 +#: FlatCAMApp.py:8455 FlatCAMApp.py:8502 flatcamGUI/FlatCAMGUI.py:490 msgid "Deselect All" msgstr "" -#: FlatCAMApp.py:8186 +#: FlatCAMApp.py:8518 msgid "All objects are selected." msgstr "" -#: FlatCAMApp.py:8196 +#: FlatCAMApp.py:8528 msgid "Objects selection is cleared." msgstr "" -#: FlatCAMApp.py:8216 flatcamGUI/FlatCAMGUI.py:1605 +#: FlatCAMApp.py:8548 flatcamGUI/FlatCAMGUI.py:1706 msgid "Grid On/Off" msgstr "" -#: FlatCAMApp.py:8228 flatcamEditors/FlatCAMGeoEditor.py:940 -#: flatcamEditors/FlatCAMGrbEditor.py:2574 flatcamEditors/FlatCAMGrbEditor.py:5431 -#: flatcamGUI/ObjectUI.py:1304 flatcamTools/ToolDblSided.py:187 -#: flatcamTools/ToolDblSided.py:245 flatcamTools/ToolNonCopperClear.py:286 -#: flatcamTools/ToolPaint.py:188 flatcamTools/ToolSolderPaste.py:121 -#: flatcamTools/ToolSolderPaste.py:591 flatcamTools/ToolTransform.py:310 +#: FlatCAMApp.py:8560 flatcamEditors/FlatCAMGeoEditor.py:940 +#: flatcamEditors/FlatCAMGrbEditor.py:2580 flatcamEditors/FlatCAMGrbEditor.py:5475 +#: flatcamGUI/ObjectUI.py:1593 flatcamTools/ToolDblSided.py:193 +#: flatcamTools/ToolDblSided.py:426 flatcamTools/ToolNCC.py:294 flatcamTools/ToolNCC.py:631 +#: flatcamTools/ToolPaint.py:277 flatcamTools/ToolPaint.py:673 +#: flatcamTools/ToolSolderPaste.py:123 flatcamTools/ToolSolderPaste.py:597 +#: flatcamTools/ToolTransform.py:479 msgid "Add" msgstr "" -#: FlatCAMApp.py:8230 FlatCAMObj.py:3963 flatcamEditors/FlatCAMGrbEditor.py:2579 -#: flatcamEditors/FlatCAMGrbEditor.py:2727 flatcamGUI/FlatCAMGUI.py:680 -#: flatcamGUI/FlatCAMGUI.py:991 flatcamGUI/FlatCAMGUI.py:2018 flatcamGUI/FlatCAMGUI.py:2161 -#: flatcamGUI/FlatCAMGUI.py:2559 flatcamGUI/ObjectUI.py:1330 -#: flatcamTools/ToolNonCopperClear.py:298 flatcamTools/ToolPaint.py:200 -#: flatcamTools/ToolSolderPaste.py:127 flatcamTools/ToolSolderPaste.py:594 +#: FlatCAMApp.py:8562 FlatCAMObj.py:4416 flatcamEditors/FlatCAMGrbEditor.py:2585 +#: flatcamEditors/FlatCAMGrbEditor.py:2733 flatcamGUI/FlatCAMGUI.py:736 +#: flatcamGUI/FlatCAMGUI.py:1059 flatcamGUI/FlatCAMGUI.py:2126 flatcamGUI/FlatCAMGUI.py:2269 +#: flatcamGUI/FlatCAMGUI.py:2733 flatcamGUI/ObjectUI.py:1621 flatcamTools/ToolNCC.py:316 +#: flatcamTools/ToolNCC.py:637 flatcamTools/ToolPaint.py:299 flatcamTools/ToolPaint.py:679 +#: flatcamTools/ToolSolderPaste.py:129 flatcamTools/ToolSolderPaste.py:600 msgid "Delete" msgstr "" -#: FlatCAMApp.py:8243 +#: FlatCAMApp.py:8575 msgid "New Grid ..." msgstr "" -#: FlatCAMApp.py:8244 +#: FlatCAMApp.py:8576 msgid "Enter a Grid Value:" msgstr "" -#: FlatCAMApp.py:8252 FlatCAMApp.py:8279 +#: FlatCAMApp.py:8584 FlatCAMApp.py:8611 msgid "Please enter a grid value with non-zero value, in Float format." msgstr "" -#: FlatCAMApp.py:8258 +#: FlatCAMApp.py:8590 msgid "New Grid added" msgstr "" -#: FlatCAMApp.py:8261 +#: FlatCAMApp.py:8593 msgid "Grid already exists" msgstr "" -#: FlatCAMApp.py:8264 +#: FlatCAMApp.py:8596 msgid "Adding New Grid cancelled" msgstr "" -#: FlatCAMApp.py:8286 +#: FlatCAMApp.py:8618 msgid " Grid Value does not exist" msgstr "" -#: FlatCAMApp.py:8289 +#: FlatCAMApp.py:8621 msgid "Grid Value deleted" msgstr "" -#: FlatCAMApp.py:8292 +#: FlatCAMApp.py:8624 msgid "Delete Grid value cancelled" msgstr "" -#: FlatCAMApp.py:8298 +#: FlatCAMApp.py:8630 msgid "Key Shortcut List" msgstr "" -#: FlatCAMApp.py:8332 +#: FlatCAMApp.py:8664 msgid " No object selected to copy it's name" msgstr "" -#: FlatCAMApp.py:8336 +#: FlatCAMApp.py:8668 msgid "Name copied on clipboard ..." msgstr "" -#: FlatCAMApp.py:8534 flatcamEditors/FlatCAMGrbEditor.py:4377 +#: FlatCAMApp.py:8881 flatcamEditors/FlatCAMGrbEditor.py:4421 msgid "Coordinates copied to clipboard." msgstr "" -#: FlatCAMApp.py:8762 FlatCAMApp.py:8768 FlatCAMApp.py:8774 FlatCAMApp.py:8780 -#: ObjectCollection.py:797 ObjectCollection.py:803 ObjectCollection.py:809 -#: ObjectCollection.py:815 ObjectCollection.py:821 ObjectCollection.py:827 +#: FlatCAMApp.py:9120 FlatCAMApp.py:9126 FlatCAMApp.py:9132 FlatCAMApp.py:9138 +#: ObjectCollection.py:911 ObjectCollection.py:917 ObjectCollection.py:923 +#: ObjectCollection.py:929 ObjectCollection.py:935 ObjectCollection.py:941 msgid "selected" msgstr "" -#: FlatCAMApp.py:8922 +#: FlatCAMApp.py:9293 msgid "" "There are files/objects opened in FlatCAM.\n" "Creating a New project will delete them.\n" "Do you want to Save the project?" msgstr "" -#: FlatCAMApp.py:8944 +#: FlatCAMApp.py:9314 msgid "New Project created" msgstr "" -#: FlatCAMApp.py:9079 FlatCAMApp.py:9083 flatcamGUI/FlatCAMGUI.py:767 -#: flatcamGUI/FlatCAMGUI.py:2352 +#: FlatCAMApp.py:9461 FlatCAMApp.py:9465 flatcamGUI/FlatCAMGUI.py:821 +#: flatcamGUI/FlatCAMGUI.py:2504 msgid "Open Gerber" msgstr "" -#: FlatCAMApp.py:9090 -msgid "Opening Gerber file." -msgstr "" - -#: FlatCAMApp.py:9096 -msgid "Open Gerber cancelled." -msgstr "" - -#: FlatCAMApp.py:9117 FlatCAMApp.py:9121 flatcamGUI/FlatCAMGUI.py:769 -#: flatcamGUI/FlatCAMGUI.py:2354 -msgid "Open Excellon" -msgstr "" - -#: FlatCAMApp.py:9127 -msgid "Opening Excellon file." -msgstr "" - -#: FlatCAMApp.py:9133 -msgid " Open Excellon cancelled." -msgstr "" - -#: FlatCAMApp.py:9157 FlatCAMApp.py:9161 -msgid "Open G-Code" -msgstr "" - -#: FlatCAMApp.py:9168 -msgid "Opening G-Code file." -msgstr "" - -#: FlatCAMApp.py:9174 -msgid "Open G-Code cancelled." -msgstr "" - -#: FlatCAMApp.py:9192 FlatCAMApp.py:9195 flatcamGUI/FlatCAMGUI.py:1614 -msgid "Open Project" -msgstr "" - -#: FlatCAMApp.py:9204 -msgid "Open Project cancelled." -msgstr "" - -#: FlatCAMApp.py:9228 FlatCAMApp.py:9232 -msgid "Open HPGL2" -msgstr "" - -#: FlatCAMApp.py:9239 -msgid "Opening HPGL2 file." -msgstr "" - -#: FlatCAMApp.py:9244 -msgid "Open HPGL2 file cancelled." -msgstr "" - -#: FlatCAMApp.py:9262 FlatCAMApp.py:9265 -msgid "Open Configuration File" -msgstr "" - -#: FlatCAMApp.py:9270 -msgid "Open Config cancelled." -msgstr "" - -#: FlatCAMApp.py:9286 FlatCAMApp.py:9654 FlatCAMApp.py:10124 FlatCAMApp.py:10128 -msgid "No object selected." -msgstr "" - -#: FlatCAMApp.py:9287 FlatCAMApp.py:9655 -msgid "Please Select a Geometry object to export" -msgstr "" - -#: FlatCAMApp.py:9301 -msgid "Only Geometry, Gerber and CNCJob objects can be used." -msgstr "" - -#: FlatCAMApp.py:9314 FlatCAMApp.py:9318 flatcamTools/ToolQRCode.py:827 -#: flatcamTools/ToolQRCode.py:831 -msgid "Export SVG" -msgstr "" - -#: FlatCAMApp.py:9324 flatcamTools/ToolQRCode.py:836 -msgid " Export SVG cancelled." -msgstr "" - -#: FlatCAMApp.py:9345 -msgid "Data must be a 3D array with last dimension 3 or 4" -msgstr "" - -#: FlatCAMApp.py:9351 FlatCAMApp.py:9355 -msgid "Export PNG Image" -msgstr "" - -#: FlatCAMApp.py:9360 -msgid "Export PNG cancelled." -msgstr "" - -#: FlatCAMApp.py:9384 -msgid "No object selected. Please select an Gerber object to export." -msgstr "" - -#: FlatCAMApp.py:9390 FlatCAMApp.py:9613 -msgid "Failed. Only Gerber objects can be saved as Gerber files..." -msgstr "" - -#: FlatCAMApp.py:9402 -msgid "Save Gerber source file" -msgstr "" - -#: FlatCAMApp.py:9408 -msgid "Save Gerber source file cancelled." -msgstr "" - -#: FlatCAMApp.py:9428 -msgid "No object selected. Please select an Script object to export." -msgstr "" - -#: FlatCAMApp.py:9434 -msgid "Failed. Only Script objects can be saved as TCL Script files..." -msgstr "" - -#: FlatCAMApp.py:9446 -msgid "Save Script source file" -msgstr "" - -#: FlatCAMApp.py:9452 -msgid "Save Script source file cancelled." +#: FlatCAMApp.py:9470 FlatCAMApp.py:9507 FlatCAMApp.py:9549 FlatCAMApp.py:9618 +#: FlatCAMApp.py:10371 FlatCAMApp.py:11546 FlatCAMApp.py:11607 +msgid "" +"Canvas initialization started.\n" +"Canvas initialization finished in" msgstr "" #: FlatCAMApp.py:9472 -msgid "No object selected. Please select an Document object to export." +msgid "Opening Gerber file." msgstr "" -#: FlatCAMApp.py:9478 +#: FlatCAMApp.py:9499 FlatCAMApp.py:9503 flatcamGUI/FlatCAMGUI.py:823 +#: flatcamGUI/FlatCAMGUI.py:2506 +msgid "Open Excellon" +msgstr "" + +#: FlatCAMApp.py:9509 +msgid "Opening Excellon file." +msgstr "" + +#: FlatCAMApp.py:9540 FlatCAMApp.py:9544 +msgid "Open G-Code" +msgstr "" + +#: FlatCAMApp.py:9551 +msgid "Opening G-Code file." +msgstr "" + +#: FlatCAMApp.py:9574 FlatCAMApp.py:9577 flatcamGUI/FlatCAMGUI.py:1715 +msgid "Open Project" +msgstr "" + +#: FlatCAMApp.py:9609 FlatCAMApp.py:9613 +msgid "Open HPGL2" +msgstr "" + +#: FlatCAMApp.py:9620 +msgid "Opening HPGL2 file." +msgstr "" + +#: FlatCAMApp.py:9643 FlatCAMApp.py:9646 +msgid "Open Configuration File" +msgstr "" + +#: FlatCAMApp.py:9666 FlatCAMApp.py:10015 +msgid "Please Select a Geometry object to export" +msgstr "" + +#: FlatCAMApp.py:9680 +msgid "Only Geometry, Gerber and CNCJob objects can be used." +msgstr "" + +#: FlatCAMApp.py:9693 FlatCAMApp.py:9697 flatcamTools/ToolQRCode.py:829 +#: flatcamTools/ToolQRCode.py:833 +msgid "Export SVG" +msgstr "" + +#: FlatCAMApp.py:9723 +msgid "Data must be a 3D array with last dimension 3 or 4" +msgstr "" + +#: FlatCAMApp.py:9729 FlatCAMApp.py:9733 +msgid "Export PNG Image" +msgstr "" + +#: FlatCAMApp.py:9767 FlatCAMApp.py:9975 +msgid "Failed. Only Gerber objects can be saved as Gerber files..." +msgstr "" + +#: FlatCAMApp.py:9779 +msgid "Save Gerber source file" +msgstr "" + +#: FlatCAMApp.py:9808 +msgid "Failed. Only Script objects can be saved as TCL Script files..." +msgstr "" + +#: FlatCAMApp.py:9820 +msgid "Save Script source file" +msgstr "" + +#: FlatCAMApp.py:9849 msgid "Failed. Only Document objects can be saved as Document files..." msgstr "" -#: FlatCAMApp.py:9490 +#: FlatCAMApp.py:9861 msgid "Save Document source file" msgstr "" -#: FlatCAMApp.py:9496 -msgid "Save Document source file cancelled." -msgstr "" - -#: FlatCAMApp.py:9516 -msgid "No object selected. Please select an Excellon object to export." -msgstr "" - -#: FlatCAMApp.py:9522 FlatCAMApp.py:9566 FlatCAMApp.py:10473 +#: FlatCAMApp.py:9890 FlatCAMApp.py:9931 FlatCAMApp.py:10856 msgid "Failed. Only Excellon objects can be saved as Excellon files..." msgstr "" -#: FlatCAMApp.py:9530 FlatCAMApp.py:9534 +#: FlatCAMApp.py:9898 FlatCAMApp.py:9902 msgid "Save Excellon source file" msgstr "" -#: FlatCAMApp.py:9540 -msgid "Saving Excellon source file cancelled." -msgstr "" - -#: FlatCAMApp.py:9560 -msgid "No object selected. Please Select an Excellon object to export." -msgstr "" - -#: FlatCAMApp.py:9574 FlatCAMApp.py:9578 +#: FlatCAMApp.py:9939 FlatCAMApp.py:9943 msgid "Export Excellon" msgstr "" -#: FlatCAMApp.py:9584 -msgid "Export Excellon cancelled." -msgstr "" - -#: FlatCAMApp.py:9607 -msgid "No object selected. Please Select an Gerber object to export." -msgstr "" - -#: FlatCAMApp.py:9621 FlatCAMApp.py:9625 +#: FlatCAMApp.py:9983 FlatCAMApp.py:9987 msgid "Export Gerber" msgstr "" -#: FlatCAMApp.py:9631 -msgid "Export Gerber cancelled." -msgstr "" - -#: FlatCAMApp.py:9666 +#: FlatCAMApp.py:10025 msgid "Only Geometry objects can be used." msgstr "" -#: FlatCAMApp.py:9680 FlatCAMApp.py:9684 +#: FlatCAMApp.py:10039 FlatCAMApp.py:10043 msgid "Export DXF" msgstr "" -#: FlatCAMApp.py:9691 -msgid "Export DXF cancelled." -msgstr "" - -#: FlatCAMApp.py:9711 FlatCAMApp.py:9714 +#: FlatCAMApp.py:10068 FlatCAMApp.py:10071 msgid "Import SVG" msgstr "" -#: FlatCAMApp.py:9724 -msgid "Open SVG cancelled." -msgstr "" - -#: FlatCAMApp.py:9743 FlatCAMApp.py:9747 +#: FlatCAMApp.py:10099 FlatCAMApp.py:10103 msgid "Import DXF" msgstr "" -#: FlatCAMApp.py:9757 -msgid "Open DXF cancelled." -msgstr "" - -#: FlatCAMApp.py:9799 +#: FlatCAMApp.py:10154 msgid "Viewing the source code of the selected object." msgstr "" -#: FlatCAMApp.py:9800 FlatCAMObj.py:6495 FlatCAMObj.py:7225 +#: FlatCAMApp.py:10155 FlatCAMObj.py:7075 FlatCAMObj.py:7852 msgid "Loading..." msgstr "" -#: FlatCAMApp.py:9806 FlatCAMApp.py:9810 +#: FlatCAMApp.py:10161 FlatCAMApp.py:10165 msgid "Select an Gerber or Excellon file to view it's source file." msgstr "" -#: FlatCAMApp.py:9824 +#: FlatCAMApp.py:10179 msgid "Source Editor" msgstr "" -#: FlatCAMApp.py:9864 FlatCAMApp.py:9871 +#: FlatCAMApp.py:10219 FlatCAMApp.py:10226 msgid "There is no selected object for which to see it's source file code." msgstr "" -#: FlatCAMApp.py:9883 +#: FlatCAMApp.py:10238 msgid "Failed to load the source code for the selected object" msgstr "" -#: FlatCAMApp.py:9925 +#: FlatCAMApp.py:10274 +msgid "Go to Line ..." +msgstr "" + +#: FlatCAMApp.py:10275 +msgid "Line:" +msgstr "" + +#: FlatCAMApp.py:10304 msgid "New TCL script file created in Code Editor." msgstr "" -#: FlatCAMApp.py:9963 FlatCAMApp.py:9965 +#: FlatCAMApp.py:10343 FlatCAMApp.py:10345 msgid "Open TCL script" msgstr "" -#: FlatCAMApp.py:9969 -msgid "Open TCL script cancelled." -msgstr "" - -#: FlatCAMApp.py:9993 +#: FlatCAMApp.py:10373 msgid "Executing FlatCAMScript file." msgstr "" -#: FlatCAMApp.py:10000 FlatCAMApp.py:10003 +#: FlatCAMApp.py:10381 FlatCAMApp.py:10384 msgid "Run TCL script" msgstr "" -#: FlatCAMApp.py:10013 -msgid "Run TCL script cancelled." -msgstr "" - -#: FlatCAMApp.py:10029 +#: FlatCAMApp.py:10408 msgid "TCL script file opened in Code Editor and executed." msgstr "" -#: FlatCAMApp.py:10080 FlatCAMApp.py:10086 +#: FlatCAMApp.py:10459 FlatCAMApp.py:10465 msgid "Save Project As ..." msgstr "" -#: FlatCAMApp.py:10082 flatcamGUI/FlatCAMGUI.py:1051 flatcamGUI/FlatCAMGUI.py:2053 +#: FlatCAMApp.py:10461 flatcamGUI/FlatCAMGUI.py:1119 flatcamGUI/FlatCAMGUI.py:2161 msgid "Project" msgstr "" -#: FlatCAMApp.py:10091 -msgid "Save Project cancelled." -msgstr "" - -#: FlatCAMApp.py:10121 +#: FlatCAMApp.py:10500 msgid "FlatCAM objects print" msgstr "" -#: FlatCAMApp.py:10134 FlatCAMApp.py:10141 +#: FlatCAMApp.py:10513 FlatCAMApp.py:10520 msgid "Save Object as PDF ..." msgstr "" -#: FlatCAMApp.py:10146 -msgid "Save Object PDF cancelled." -msgstr "" - -#: FlatCAMApp.py:10150 +#: FlatCAMApp.py:10529 msgid "Printing PDF ... Please wait." msgstr "" -#: FlatCAMApp.py:10329 +#: FlatCAMApp.py:10708 msgid "PDF file saved to" msgstr "" -#: FlatCAMApp.py:10353 +#: FlatCAMApp.py:10733 msgid "Exporting SVG" msgstr "" -#: FlatCAMApp.py:10397 +#: FlatCAMApp.py:10776 msgid "SVG file exported to" msgstr "" -#: FlatCAMApp.py:10422 +#: FlatCAMApp.py:10802 msgid "Save cancelled because source file is empty. Try to export the Gerber file." msgstr "" -#: FlatCAMApp.py:10568 +#: FlatCAMApp.py:10950 msgid "Excellon file exported to" msgstr "" -#: FlatCAMApp.py:10577 +#: FlatCAMApp.py:10959 msgid "Exporting Excellon" msgstr "" -#: FlatCAMApp.py:10583 FlatCAMApp.py:10591 +#: FlatCAMApp.py:10964 FlatCAMApp.py:10971 msgid "Could not export Excellon file." msgstr "" -#: FlatCAMApp.py:10707 +#: FlatCAMApp.py:11087 msgid "Gerber file exported to" msgstr "" -#: FlatCAMApp.py:10715 +#: FlatCAMApp.py:11095 msgid "Exporting Gerber" msgstr "" -#: FlatCAMApp.py:10721 FlatCAMApp.py:10729 +#: FlatCAMApp.py:11100 FlatCAMApp.py:11107 msgid "Could not export Gerber file." msgstr "" -#: FlatCAMApp.py:10763 +#: FlatCAMApp.py:11142 msgid "DXF file exported to" msgstr "" -#: FlatCAMApp.py:10769 +#: FlatCAMApp.py:11148 msgid "Exporting DXF" msgstr "" -#: FlatCAMApp.py:10774 FlatCAMApp.py:10781 +#: FlatCAMApp.py:11153 FlatCAMApp.py:11160 msgid "Could not export DXF file." msgstr "" -#: FlatCAMApp.py:10804 FlatCAMApp.py:10847 flatcamTools/ToolImage.py:278 +#: FlatCAMApp.py:11183 FlatCAMApp.py:11225 flatcamTools/ToolImage.py:277 msgid "Not supported type is picked as parameter. Only Geometry and Gerber are supported" msgstr "" -#: FlatCAMApp.py:10814 +#: FlatCAMApp.py:11193 msgid "Importing SVG" msgstr "" -#: FlatCAMApp.py:10825 FlatCAMApp.py:10867 FlatCAMApp.py:10926 FlatCAMApp.py:10993 -#: FlatCAMApp.py:11056 FlatCAMApp.py:11123 FlatCAMApp.py:11161 flatcamTools/ToolImage.py:298 +#: FlatCAMApp.py:11204 FlatCAMApp.py:11244 FlatCAMApp.py:11302 FlatCAMApp.py:11367 +#: FlatCAMApp.py:11431 FlatCAMApp.py:11496 FlatCAMApp.py:11533 flatcamTools/ToolImage.py:297 #: flatcamTools/ToolPDF.py:225 msgid "Opened" msgstr "" -#: FlatCAMApp.py:10856 +#: FlatCAMApp.py:11234 msgid "Importing DXF" msgstr "" -#: FlatCAMApp.py:10892 FlatCAMApp.py:11082 +#: FlatCAMApp.py:11268 FlatCAMApp.py:11455 msgid "Failed to open file" msgstr "" -#: FlatCAMApp.py:10895 FlatCAMApp.py:11085 +#: FlatCAMApp.py:11271 FlatCAMApp.py:11458 msgid "Failed to parse file" msgstr "" -#: FlatCAMApp.py:10907 +#: FlatCAMApp.py:11283 msgid "Object is not Gerber file or empty. Aborting object creation." msgstr "" -#: FlatCAMApp.py:10912 +#: FlatCAMApp.py:11288 msgid "Opening Gerber" msgstr "" -#: FlatCAMApp.py:10919 +#: FlatCAMApp.py:11295 msgid " Open Gerber failed. Probable not a Gerber file." msgstr "" -#: FlatCAMApp.py:10951 flatcamTools/ToolPcbWizard.py:427 +#: FlatCAMApp.py:11326 flatcamTools/ToolPcbWizard.py:425 msgid "This is not Excellon file." msgstr "" -#: FlatCAMApp.py:10955 +#: FlatCAMApp.py:11330 msgid "Cannot open file" msgstr "" -#: FlatCAMApp.py:10975 flatcamTools/ToolPDF.py:275 flatcamTools/ToolPcbWizard.py:451 +#: FlatCAMApp.py:11349 flatcamTools/ToolPDF.py:275 flatcamTools/ToolPcbWizard.py:447 msgid "No geometry found in file" msgstr "" -#: FlatCAMApp.py:10978 +#: FlatCAMApp.py:11352 msgid "Opening Excellon." msgstr "" -#: FlatCAMApp.py:10985 +#: FlatCAMApp.py:11359 msgid "Open Excellon file failed. Probable not an Excellon file." msgstr "" -#: FlatCAMApp.py:11016 +#: FlatCAMApp.py:11391 msgid "Reading GCode file" msgstr "" -#: FlatCAMApp.py:11023 +#: FlatCAMApp.py:11398 msgid "Failed to open" msgstr "" -#: FlatCAMApp.py:11031 +#: FlatCAMApp.py:11406 msgid "This is not GCODE" msgstr "" -#: FlatCAMApp.py:11036 +#: FlatCAMApp.py:11411 msgid "Opening G-Code." msgstr "" -#: FlatCAMApp.py:11045 +#: FlatCAMApp.py:11420 msgid "" "Failed to create CNCJob Object. Probable not a GCode file. Try to load it from File " "menu.\n" " Attempting to create a FlatCAM CNCJob Object from G-Code file failed during processing" msgstr "" -#: FlatCAMApp.py:11104 +#: FlatCAMApp.py:11477 msgid "Object is not HPGL2 file or empty. Aborting object creation." msgstr "" -#: FlatCAMApp.py:11109 +#: FlatCAMApp.py:11482 msgid "Opening HPGL2" msgstr "" -#: FlatCAMApp.py:11116 +#: FlatCAMApp.py:11489 msgid " Open HPGL2 failed. Probable not a HPGL2 file." msgstr "" -#: FlatCAMApp.py:11137 +#: FlatCAMApp.py:11509 msgid "Opening TCL Script..." msgstr "" -#: FlatCAMApp.py:11145 +#: FlatCAMApp.py:11517 msgid "TCL script file opened in Code Editor." msgstr "" -#: FlatCAMApp.py:11148 +#: FlatCAMApp.py:11520 msgid "Failed to open TCL Script." msgstr "" -#: FlatCAMApp.py:11176 +#: FlatCAMApp.py:11548 msgid "Opening FlatCAM Config file." msgstr "" -#: FlatCAMApp.py:11204 +#: FlatCAMApp.py:11576 msgid "Failed to open config file" msgstr "" -#: FlatCAMApp.py:11230 +#: FlatCAMApp.py:11604 msgid "Loading Project ... Please Wait ..." msgstr "" -#: FlatCAMApp.py:11235 +#: FlatCAMApp.py:11609 msgid "Opening FlatCAM Project file." msgstr "" -#: FlatCAMApp.py:11245 FlatCAMApp.py:11263 +#: FlatCAMApp.py:11619 FlatCAMApp.py:11637 msgid "Failed to open project file" msgstr "" -#: FlatCAMApp.py:11300 +#: FlatCAMApp.py:11674 msgid "Loading Project ... restoring" msgstr "" -#: FlatCAMApp.py:11310 +#: FlatCAMApp.py:11684 msgid "Project loaded from" msgstr "" -#: FlatCAMApp.py:11373 +#: FlatCAMApp.py:11753 msgid "Redrawing all objects" msgstr "" -#: FlatCAMApp.py:11405 -msgid "Available commands:\n" -msgstr "" - -#: FlatCAMApp.py:11407 -msgid "" -"\n" -"\n" -"Type help for usage.\n" -" Example: help open_gerber" -msgstr "" - -#: FlatCAMApp.py:11557 -msgid "Shows list of commands." -msgstr "" - -#: FlatCAMApp.py:11619 +#: FlatCAMApp.py:11842 msgid "Failed to load recent item list." msgstr "" -#: FlatCAMApp.py:11627 +#: FlatCAMApp.py:11849 msgid "Failed to parse recent item list." msgstr "" -#: FlatCAMApp.py:11638 +#: FlatCAMApp.py:11859 msgid "Failed to load recent projects item list." msgstr "" -#: FlatCAMApp.py:11646 +#: FlatCAMApp.py:11866 msgid "Failed to parse recent project item list." msgstr "" -#: FlatCAMApp.py:11706 +#: FlatCAMApp.py:11927 msgid "Clear Recent projects" msgstr "" -#: FlatCAMApp.py:11730 +#: FlatCAMApp.py:11951 msgid "Clear Recent files" msgstr "" -#: FlatCAMApp.py:11747 flatcamGUI/FlatCAMGUI.py:1276 +#: FlatCAMApp.py:11973 flatcamGUI/FlatCAMGUI.py:1348 msgid "Shortcut Key List" msgstr "" -#: FlatCAMApp.py:11821 +#: FlatCAMApp.py:12047 msgid "Selected Tab - Choose an Item from Project Tab" msgstr "" -#: FlatCAMApp.py:11822 +#: FlatCAMApp.py:12048 msgid "Details" msgstr "" -#: FlatCAMApp.py:11824 +#: FlatCAMApp.py:12050 msgid "The normal flow when working in FlatCAM is the following:" msgstr "" -#: FlatCAMApp.py:11825 +#: FlatCAMApp.py:12051 msgid "" "Load/Import a Gerber, Excellon, Gcode, DXF, Raster Image or SVG file into FlatCAM using " "either the toolbars, key shortcuts or even dragging and dropping the files on the GUI." msgstr "" -#: FlatCAMApp.py:11828 +#: FlatCAMApp.py:12054 msgid "" "You can also load a FlatCAM project by double clicking on the project file, drag and drop " "of the file into the FLATCAM GUI or through the menu (or toolbar) actions offered within " "the app." msgstr "" -#: FlatCAMApp.py:11831 +#: FlatCAMApp.py:12057 msgid "" "Once an object is available in the Project Tab, by selecting it and then focusing on " "SELECTED TAB (more simpler is to double click the object name in the Project Tab, " @@ -1394,7 +1336,7 @@ msgid "" "Excellon, Geometry or CNCJob object." msgstr "" -#: FlatCAMApp.py:11835 +#: FlatCAMApp.py:12061 msgid "" "If the selection of the object is done on the canvas by single click instead, and the " "SELECTED TAB is in focus, again the object properties will be displayed into the Selected " @@ -1402,11 +1344,11 @@ msgid "" "TAB and populate it even if it was out of focus." msgstr "" -#: FlatCAMApp.py:11839 +#: FlatCAMApp.py:12065 msgid "You can change the parameters in this screen and the flow direction is like this:" msgstr "" -#: FlatCAMApp.py:11840 +#: FlatCAMApp.py:12066 msgid "" "Gerber/Excellon Object --> Change Parameter --> Generate Geometry --> Geometry Object --> " "Add tools (change param in Selected Tab) --> Generate CNCJob --> CNCJob Object --> Verify " @@ -1414,389 +1356,447 @@ msgid "" "TAB) --> Save GCode." msgstr "" -#: FlatCAMApp.py:11844 +#: FlatCAMApp.py:12070 msgid "" "A list of key shortcuts is available through an menu entry in Help --> Shortcuts List or " "through its own key shortcut: F3." msgstr "" -#: FlatCAMApp.py:11906 +#: FlatCAMApp.py:12134 msgid "Failed checking for latest version. Could not connect." msgstr "" -#: FlatCAMApp.py:11914 +#: FlatCAMApp.py:12141 msgid "Could not parse information about latest version." msgstr "" -#: FlatCAMApp.py:11925 +#: FlatCAMApp.py:12151 msgid "FlatCAM is up to date!" msgstr "" -#: FlatCAMApp.py:11930 +#: FlatCAMApp.py:12156 msgid "Newer Version Available" msgstr "" -#: FlatCAMApp.py:11931 -msgid "" -"There is a newer version of FlatCAM available for download:\n" -"\n" +#: FlatCAMApp.py:12158 +msgid "There is a newer version of FlatCAM available for download:" msgstr "" -#: FlatCAMApp.py:11933 +#: FlatCAMApp.py:12162 msgid "info" msgstr "" -#: FlatCAMApp.py:12012 +#: FlatCAMApp.py:12190 +msgid "" +"OpenGL canvas initialization failed. HW or HW configuration not supported.Change the " +"graphic engine to Legacy(2D) in Edit -> Preferences -> General tab.\n" +"\n" +msgstr "" + +#: FlatCAMApp.py:12269 msgid "All plots disabled." msgstr "" -#: FlatCAMApp.py:12019 +#: FlatCAMApp.py:12276 msgid "All non selected plots disabled." msgstr "" -#: FlatCAMApp.py:12026 +#: FlatCAMApp.py:12283 msgid "All plots enabled." msgstr "" -#: FlatCAMApp.py:12033 +#: FlatCAMApp.py:12289 msgid "Selected plots enabled..." msgstr "" -#: FlatCAMApp.py:12042 +#: FlatCAMApp.py:12297 msgid "Selected plots disabled..." msgstr "" -#: FlatCAMApp.py:12061 +#: FlatCAMApp.py:12330 msgid "Enabling plots ..." msgstr "" -#: FlatCAMApp.py:12101 +#: FlatCAMApp.py:12382 msgid "Disabling plots ..." msgstr "" -#: FlatCAMApp.py:12123 +#: FlatCAMApp.py:12405 msgid "Working ..." msgstr "" -#: FlatCAMApp.py:12224 +#: FlatCAMApp.py:12460 flatcamGUI/FlatCAMGUI.py:688 +msgid "Red" +msgstr "" + +#: FlatCAMApp.py:12462 flatcamGUI/FlatCAMGUI.py:691 +msgid "Blue" +msgstr "" + +#: FlatCAMApp.py:12465 flatcamGUI/FlatCAMGUI.py:694 +msgid "Yellow" +msgstr "" + +#: FlatCAMApp.py:12467 flatcamGUI/FlatCAMGUI.py:697 +msgid "Green" +msgstr "" + +#: FlatCAMApp.py:12469 flatcamGUI/FlatCAMGUI.py:700 +msgid "Purple" +msgstr "" + +#: FlatCAMApp.py:12471 flatcamGUI/FlatCAMGUI.py:703 +msgid "Brown" +msgstr "" + +#: FlatCAMApp.py:12473 FlatCAMApp.py:12529 flatcamGUI/FlatCAMGUI.py:706 +msgid "White" +msgstr "" + +#: FlatCAMApp.py:12475 flatcamGUI/FlatCAMGUI.py:709 +msgid "Black" +msgstr "" + +#: FlatCAMApp.py:12478 flatcamGUI/FlatCAMGUI.py:714 +msgid "Custom" +msgstr "" + +#: FlatCAMApp.py:12488 flatcamGUI/FlatCAMGUI.py:722 +msgid "Default" +msgstr "" + +#: FlatCAMApp.py:12512 flatcamGUI/FlatCAMGUI.py:719 +msgid "Opacity" +msgstr "" + +#: FlatCAMApp.py:12514 +msgid "Set alpha level ..." +msgstr "" + +#: FlatCAMApp.py:12514 flatcamGUI/PreferencesUI.py:6900 flatcamGUI/PreferencesUI.py:8230 +#: flatcamGUI/PreferencesUI.py:8444 flatcamTools/ToolExtractDrills.py:164 +#: flatcamTools/ToolExtractDrills.py:285 flatcamTools/ToolPunchGerber.py:192 +#: flatcamTools/ToolPunchGerber.py:308 flatcamTools/ToolTransform.py:358 +msgid "Value" +msgstr "" + +#: FlatCAMApp.py:12590 msgid "Saving FlatCAM Project" msgstr "" -#: FlatCAMApp.py:12243 FlatCAMApp.py:12280 +#: FlatCAMApp.py:12611 FlatCAMApp.py:12647 msgid "Project saved to" msgstr "" -#: FlatCAMApp.py:12250 +#: FlatCAMApp.py:12618 msgid "The object is used by another application." msgstr "" -#: FlatCAMApp.py:12264 +#: FlatCAMApp.py:12632 msgid "Failed to verify project file" msgstr "" -#: FlatCAMApp.py:12264 FlatCAMApp.py:12272 FlatCAMApp.py:12283 +#: FlatCAMApp.py:12632 FlatCAMApp.py:12640 FlatCAMApp.py:12650 msgid "Retry to save it." msgstr "" -#: FlatCAMApp.py:12272 FlatCAMApp.py:12283 +#: FlatCAMApp.py:12640 FlatCAMApp.py:12650 msgid "Failed to parse saved project file" msgstr "" -#: FlatCAMApp.py:12398 +#: FlatCAMApp.py:13132 msgid "The user requested a graceful exit of the current task." msgstr "" -#: FlatCAMCommon.py:136 FlatCAMCommon.py:163 +#: FlatCAMCommon.py:137 FlatCAMCommon.py:164 msgid "Title" msgstr "" -#: FlatCAMCommon.py:137 FlatCAMCommon.py:167 +#: FlatCAMCommon.py:138 FlatCAMCommon.py:168 msgid "Web Link" msgstr "" -#: FlatCAMCommon.py:141 +#: FlatCAMCommon.py:142 msgid "" "Index.\n" "The rows in gray color will populate the Bookmarks menu.\n" "The number of gray colored rows is set in Preferences." msgstr "" -#: FlatCAMCommon.py:145 +#: FlatCAMCommon.py:146 msgid "" "Description of the link that is set as an menu action.\n" "Try to keep it short because it is installed as a menu item." msgstr "" -#: FlatCAMCommon.py:148 +#: FlatCAMCommon.py:149 msgid "Web Link. E.g: https://your_website.org " msgstr "" -#: FlatCAMCommon.py:157 +#: FlatCAMCommon.py:158 msgid "New Bookmark" msgstr "" -#: FlatCAMCommon.py:176 +#: FlatCAMCommon.py:177 msgid "Add Entry" msgstr "" -#: FlatCAMCommon.py:177 +#: FlatCAMCommon.py:178 msgid "Remove Entry" msgstr "" -#: FlatCAMCommon.py:178 +#: FlatCAMCommon.py:179 msgid "Export List" msgstr "" -#: FlatCAMCommon.py:179 +#: FlatCAMCommon.py:180 msgid "Import List" msgstr "" -#: FlatCAMCommon.py:260 +#: FlatCAMCommon.py:261 msgid "Title entry is empty." msgstr "" -#: FlatCAMCommon.py:269 +#: FlatCAMCommon.py:270 msgid "Web link entry is empty." msgstr "" -#: FlatCAMCommon.py:277 +#: FlatCAMCommon.py:278 msgid "Either the Title or the Weblink already in the table." msgstr "" -#: FlatCAMCommon.py:297 +#: FlatCAMCommon.py:298 msgid "Bookmark added." msgstr "" -#: FlatCAMCommon.py:314 +#: FlatCAMCommon.py:315 msgid "This bookmark can not be removed" msgstr "" -#: FlatCAMCommon.py:345 +#: FlatCAMCommon.py:346 msgid "Bookmark removed." msgstr "" -#: FlatCAMCommon.py:360 +#: FlatCAMCommon.py:361 msgid "Export FlatCAM Bookmarks" msgstr "" -#: FlatCAMCommon.py:363 flatcamGUI/FlatCAMGUI.py:470 +#: FlatCAMCommon.py:364 flatcamGUI/FlatCAMGUI.py:509 msgid "Bookmarks" msgstr "" -#: FlatCAMCommon.py:370 -msgid "FlatCAM bookmarks export cancelled." -msgstr "" - -#: FlatCAMCommon.py:389 FlatCAMCommon.py:419 +#: FlatCAMCommon.py:390 FlatCAMCommon.py:420 msgid "Could not load bookmarks file." msgstr "" -#: FlatCAMCommon.py:399 +#: FlatCAMCommon.py:400 msgid "Failed to write bookmarks to file." msgstr "" -#: FlatCAMCommon.py:401 +#: FlatCAMCommon.py:402 msgid "Exported bookmarks to" msgstr "" -#: FlatCAMCommon.py:407 +#: FlatCAMCommon.py:408 msgid "Import FlatCAM Bookmarks" msgstr "" -#: FlatCAMCommon.py:412 -msgid "FlatCAM bookmarks import cancelled." -msgstr "" - -#: FlatCAMCommon.py:426 +#: FlatCAMCommon.py:427 msgid "Imported Bookmarks from" msgstr "" -#: FlatCAMCommon.py:529 +#: FlatCAMCommon.py:530 msgid "Add Geometry Tool in DB" msgstr "" -#: FlatCAMCommon.py:531 +#: FlatCAMCommon.py:532 FlatCAMCommon.py:2087 msgid "" "Add a new tool in the Tools Database.\n" "It will be used in the Geometry UI.\n" "You can edit it after it is added." msgstr "" -#: FlatCAMCommon.py:545 +#: FlatCAMCommon.py:546 FlatCAMCommon.py:2101 msgid "Delete Tool from DB" msgstr "" -#: FlatCAMCommon.py:547 +#: FlatCAMCommon.py:548 FlatCAMCommon.py:2103 msgid "Remove a selection of tools in the Tools Database." msgstr "" -#: FlatCAMCommon.py:551 +#: FlatCAMCommon.py:552 FlatCAMCommon.py:2107 msgid "Export DB" msgstr "" -#: FlatCAMCommon.py:553 +#: FlatCAMCommon.py:554 FlatCAMCommon.py:2109 msgid "Save the Tools Database to a custom text file." msgstr "" -#: FlatCAMCommon.py:557 +#: FlatCAMCommon.py:558 FlatCAMCommon.py:2113 msgid "Import DB" msgstr "" -#: FlatCAMCommon.py:559 +#: FlatCAMCommon.py:560 FlatCAMCommon.py:2115 msgid "Load the Tools Database information's from a custom text file." msgstr "" -#: FlatCAMCommon.py:563 +#: FlatCAMCommon.py:564 FlatCAMCommon.py:2119 msgid "Add Tool from Tools DB" msgstr "" -#: FlatCAMCommon.py:565 +#: FlatCAMCommon.py:566 FlatCAMCommon.py:2121 msgid "" "Add a new tool in the Tools Table of the\n" "active Geometry object after selecting a tool\n" "in the Tools Database." msgstr "" -#: FlatCAMCommon.py:601 FlatCAMCommon.py:1276 +#: FlatCAMCommon.py:602 FlatCAMCommon.py:1277 FlatCAMCommon.py:1531 msgid "Tool Name" msgstr "" -#: FlatCAMCommon.py:602 FlatCAMCommon.py:1278 flatcamEditors/FlatCAMExcEditor.py:1602 -#: flatcamGUI/ObjectUI.py:1295 flatcamTools/ToolNonCopperClear.py:271 -#: flatcamTools/ToolPaint.py:176 +#: FlatCAMCommon.py:603 FlatCAMCommon.py:1279 FlatCAMCommon.py:1544 +#: flatcamEditors/FlatCAMExcEditor.py:1605 flatcamGUI/ObjectUI.py:1343 +#: flatcamGUI/ObjectUI.py:1581 flatcamGUI/PreferencesUI.py:5971 flatcamTools/ToolNCC.py:278 +#: flatcamTools/ToolNCC.py:287 flatcamTools/ToolPaint.py:261 msgid "Tool Dia" msgstr "" -#: FlatCAMCommon.py:603 FlatCAMCommon.py:1280 flatcamGUI/ObjectUI.py:1278 +#: FlatCAMCommon.py:604 FlatCAMCommon.py:1281 FlatCAMCommon.py:1725 +#: flatcamGUI/ObjectUI.py:1556 msgid "Tool Offset" msgstr "" -#: FlatCAMCommon.py:604 FlatCAMCommon.py:1282 +#: FlatCAMCommon.py:605 FlatCAMCommon.py:1283 FlatCAMCommon.py:1742 msgid "Custom Offset" msgstr "" -#: FlatCAMCommon.py:605 FlatCAMCommon.py:1284 flatcamGUI/ObjectUI.py:304 -#: flatcamGUI/PreferencesUI.py:2217 flatcamGUI/PreferencesUI.py:5036 -#: flatcamTools/ToolNonCopperClear.py:213 +#: FlatCAMCommon.py:606 FlatCAMCommon.py:1285 FlatCAMCommon.py:1709 +#: flatcamGUI/ObjectUI.py:308 flatcamGUI/PreferencesUI.py:2397 +#: flatcamGUI/PreferencesUI.py:5332 flatcamGUI/PreferencesUI.py:5901 +#: flatcamGUI/PreferencesUI.py:5911 flatcamTools/ToolNCC.py:213 flatcamTools/ToolNCC.py:227 +#: flatcamTools/ToolPaint.py:196 msgid "Tool Type" msgstr "" -#: FlatCAMCommon.py:606 FlatCAMCommon.py:1286 +#: FlatCAMCommon.py:607 FlatCAMCommon.py:1287 FlatCAMCommon.py:1557 msgid "Tool Shape" msgstr "" -#: FlatCAMCommon.py:607 FlatCAMCommon.py:1289 flatcamGUI/ObjectUI.py:345 -#: flatcamGUI/ObjectUI.py:820 flatcamGUI/ObjectUI.py:1405 flatcamGUI/ObjectUI.py:1926 -#: flatcamGUI/PreferencesUI.py:2257 flatcamGUI/PreferencesUI.py:3082 -#: flatcamGUI/PreferencesUI.py:3961 flatcamGUI/PreferencesUI.py:5081 -#: flatcamGUI/PreferencesUI.py:5327 flatcamGUI/PreferencesUI.py:6145 -#: flatcamTools/ToolCalculators.py:114 flatcamTools/ToolCutOut.py:132 -#: flatcamTools/ToolNonCopperClear.py:254 +#: FlatCAMCommon.py:608 FlatCAMCommon.py:1290 FlatCAMCommon.py:1573 +#: flatcamGUI/ObjectUI.py:349 flatcamGUI/ObjectUI.py:899 flatcamGUI/ObjectUI.py:1701 +#: flatcamGUI/ObjectUI.py:2254 flatcamGUI/PreferencesUI.py:2437 +#: flatcamGUI/PreferencesUI.py:3311 flatcamGUI/PreferencesUI.py:4241 +#: flatcamGUI/PreferencesUI.py:5377 flatcamGUI/PreferencesUI.py:5666 +#: flatcamGUI/PreferencesUI.py:5944 flatcamGUI/PreferencesUI.py:5952 +#: flatcamGUI/PreferencesUI.py:6635 flatcamTools/ToolCalculators.py:114 +#: flatcamTools/ToolCutOut.py:139 flatcamTools/ToolNCC.py:260 flatcamTools/ToolNCC.py:268 +#: flatcamTools/ToolPaint.py:243 msgid "Cut Z" msgstr "" -#: FlatCAMCommon.py:608 FlatCAMCommon.py:1291 +#: FlatCAMCommon.py:609 FlatCAMCommon.py:1292 FlatCAMCommon.py:1587 msgid "MultiDepth" msgstr "" -#: FlatCAMCommon.py:609 FlatCAMCommon.py:1293 +#: FlatCAMCommon.py:610 FlatCAMCommon.py:1294 FlatCAMCommon.py:1600 msgid "DPP" msgstr "" -#: FlatCAMCommon.py:610 FlatCAMCommon.py:1295 +#: FlatCAMCommon.py:611 FlatCAMCommon.py:1296 FlatCAMCommon.py:1756 msgid "V-Dia" msgstr "" -#: FlatCAMCommon.py:611 FlatCAMCommon.py:1297 +#: FlatCAMCommon.py:612 FlatCAMCommon.py:1298 FlatCAMCommon.py:1770 msgid "V-Angle" msgstr "" -#: FlatCAMCommon.py:612 FlatCAMCommon.py:1299 flatcamGUI/ObjectUI.py:839 -#: flatcamGUI/ObjectUI.py:1452 flatcamGUI/PreferencesUI.py:3100 -#: flatcamGUI/PreferencesUI.py:4014 flatcamGUI/PreferencesUI.py:7535 -#: flatcamTools/ToolCalibration.py:74 +#: FlatCAMCommon.py:613 FlatCAMCommon.py:1300 FlatCAMCommon.py:1614 FlatCAMObj.py:3661 +#: FlatCAMObj.py:5486 flatcamGUI/ObjectUI.py:945 flatcamGUI/ObjectUI.py:1748 +#: flatcamGUI/PreferencesUI.py:3352 flatcamGUI/PreferencesUI.py:4294 +#: flatcamGUI/PreferencesUI.py:8041 flatcamTools/ToolCalibration.py:74 msgid "Travel Z" msgstr "" -#: FlatCAMCommon.py:613 FlatCAMCommon.py:1301 +#: FlatCAMCommon.py:614 FlatCAMCommon.py:1302 msgid "FR" msgstr "" -#: FlatCAMCommon.py:614 FlatCAMCommon.py:1303 +#: FlatCAMCommon.py:615 FlatCAMCommon.py:1304 msgid "FR Z" msgstr "" -#: FlatCAMCommon.py:615 FlatCAMCommon.py:1305 +#: FlatCAMCommon.py:616 FlatCAMCommon.py:1306 FlatCAMCommon.py:1784 msgid "FR Rapids" msgstr "" -#: FlatCAMCommon.py:616 FlatCAMCommon.py:1307 flatcamGUI/PreferencesUI.py:3173 +#: FlatCAMCommon.py:617 FlatCAMCommon.py:1308 FlatCAMCommon.py:1657 +#: flatcamGUI/PreferencesUI.py:3440 msgid "Spindle Speed" msgstr "" -#: FlatCAMCommon.py:617 FlatCAMCommon.py:1309 flatcamGUI/ObjectUI.py:963 -#: flatcamGUI/ObjectUI.py:1619 +#: FlatCAMCommon.py:618 FlatCAMCommon.py:1310 FlatCAMCommon.py:1672 +#: flatcamGUI/ObjectUI.py:1063 flatcamGUI/ObjectUI.py:1855 msgid "Dwell" msgstr "" -#: FlatCAMCommon.py:618 FlatCAMCommon.py:1311 +#: FlatCAMCommon.py:619 FlatCAMCommon.py:1312 FlatCAMCommon.py:1685 msgid "Dwelltime" msgstr "" -#: FlatCAMCommon.py:619 FlatCAMCommon.py:1313 flatcamGUI/ObjectUI.py:982 -#: flatcamGUI/ObjectUI.py:1640 flatcamGUI/PreferencesUI.py:3204 -#: flatcamGUI/PreferencesUI.py:4155 flatcamGUI/PreferencesUI.py:6642 -#: flatcamTools/ToolSolderPaste.py:334 +#: FlatCAMCommon.py:620 FlatCAMCommon.py:1314 flatcamGUI/ObjectUI.py:2012 +#: flatcamGUI/PreferencesUI.py:3475 flatcamGUI/PreferencesUI.py:4447 +#: flatcamGUI/PreferencesUI.py:7148 flatcamTools/ToolSolderPaste.py:336 msgid "Preprocessor" msgstr "" -#: FlatCAMCommon.py:620 FlatCAMCommon.py:1315 +#: FlatCAMCommon.py:621 FlatCAMCommon.py:1316 FlatCAMCommon.py:1800 msgid "ExtraCut" msgstr "" -#: FlatCAMCommon.py:621 FlatCAMCommon.py:1317 +#: FlatCAMCommon.py:622 FlatCAMCommon.py:1318 FlatCAMCommon.py:1815 msgid "E-Cut Length" msgstr "" -#: FlatCAMCommon.py:622 FlatCAMCommon.py:1319 +#: FlatCAMCommon.py:623 FlatCAMCommon.py:1320 msgid "Toolchange" msgstr "" -#: FlatCAMCommon.py:623 FlatCAMCommon.py:1321 +#: FlatCAMCommon.py:624 FlatCAMCommon.py:1322 msgid "Toolchange XY" msgstr "" -#: FlatCAMCommon.py:624 FlatCAMCommon.py:1323 flatcamGUI/PreferencesUI.py:3124 -#: flatcamGUI/PreferencesUI.py:4044 flatcamGUI/PreferencesUI.py:7572 +#: FlatCAMCommon.py:625 FlatCAMCommon.py:1324 flatcamGUI/PreferencesUI.py:3378 +#: flatcamGUI/PreferencesUI.py:4324 flatcamGUI/PreferencesUI.py:8078 #: flatcamTools/ToolCalibration.py:111 msgid "Toolchange Z" msgstr "" -#: FlatCAMCommon.py:625 FlatCAMCommon.py:1325 flatcamGUI/ObjectUI.py:886 -#: flatcamGUI/PreferencesUI.py:3309 flatcamGUI/PreferencesUI.py:4200 +#: FlatCAMCommon.py:626 FlatCAMCommon.py:1326 flatcamGUI/ObjectUI.py:1192 +#: flatcamGUI/PreferencesUI.py:3586 flatcamGUI/PreferencesUI.py:4493 msgid "Start Z" msgstr "" -#: FlatCAMCommon.py:626 FlatCAMCommon.py:1328 +#: FlatCAMCommon.py:627 FlatCAMCommon.py:1329 msgid "End Z" msgstr "" -#: FlatCAMCommon.py:630 +#: FlatCAMCommon.py:631 msgid "Tool Index." msgstr "" -#: FlatCAMCommon.py:632 +#: FlatCAMCommon.py:633 FlatCAMCommon.py:1533 msgid "" "Tool name.\n" "This is not used in the app, it's function\n" "is to serve as a note for the user." msgstr "" -#: FlatCAMCommon.py:636 +#: FlatCAMCommon.py:637 FlatCAMCommon.py:1546 msgid "Tool Diameter." msgstr "" -#: FlatCAMCommon.py:638 +#: FlatCAMCommon.py:639 FlatCAMCommon.py:1727 msgid "" "Tool Offset.\n" "Can be of a few types:\n" @@ -1806,13 +1806,13 @@ msgid "" "Custom = custom offset using the Custom Offset value" msgstr "" -#: FlatCAMCommon.py:645 +#: FlatCAMCommon.py:646 FlatCAMCommon.py:1744 msgid "" "Custom Offset.\n" "A value to be used as offset from the current path." msgstr "" -#: FlatCAMCommon.py:648 +#: FlatCAMCommon.py:649 FlatCAMCommon.py:1711 msgid "" "Tool Type.\n" "Can be:\n" @@ -1821,7 +1821,7 @@ msgid "" "Finish = finishing cut, high feedrate" msgstr "" -#: FlatCAMCommon.py:654 +#: FlatCAMCommon.py:655 FlatCAMCommon.py:1559 msgid "" "Tool Shape. \n" "Can be:\n" @@ -1830,57 +1830,57 @@ msgid "" "V = v-shape milling tool" msgstr "" -#: FlatCAMCommon.py:660 +#: FlatCAMCommon.py:661 FlatCAMCommon.py:1575 msgid "" "Cutting Depth.\n" "The depth at which to cut into material." msgstr "" -#: FlatCAMCommon.py:663 +#: FlatCAMCommon.py:664 FlatCAMCommon.py:1589 msgid "" "Multi Depth.\n" "Selecting this will allow cutting in multiple passes,\n" "each pass adding a DPP parameter depth." msgstr "" -#: FlatCAMCommon.py:667 +#: FlatCAMCommon.py:668 FlatCAMCommon.py:1602 msgid "" "DPP. Depth per Pass.\n" "The value used to cut into material on each pass." msgstr "" -#: FlatCAMCommon.py:670 +#: FlatCAMCommon.py:671 FlatCAMCommon.py:1758 msgid "" "V-Dia.\n" "Diameter of the tip for V-Shape Tools." msgstr "" -#: FlatCAMCommon.py:673 +#: FlatCAMCommon.py:674 FlatCAMCommon.py:1772 msgid "" "V-Agle.\n" "Angle at the tip for the V-Shape Tools." msgstr "" -#: FlatCAMCommon.py:676 +#: FlatCAMCommon.py:677 FlatCAMCommon.py:1616 msgid "" "Clearance Height.\n" "Height at which the milling bit will travel between cuts,\n" "above the surface of the material, avoiding all fixtures." msgstr "" -#: FlatCAMCommon.py:680 +#: FlatCAMCommon.py:681 msgid "" "FR. Feedrate\n" "The speed on XY plane used while cutting into material." msgstr "" -#: FlatCAMCommon.py:683 +#: FlatCAMCommon.py:684 msgid "" "FR Z. Feedrate Z\n" "The speed on Z plane." msgstr "" -#: FlatCAMCommon.py:686 +#: FlatCAMCommon.py:687 FlatCAMCommon.py:1786 msgid "" "FR Rapids. Feedrate Rapids\n" "Speed used while moving as fast as possible.\n" @@ -1888,34 +1888,34 @@ msgid "" "the G0 g-code command. Mostly 3D printers." msgstr "" -#: FlatCAMCommon.py:691 +#: FlatCAMCommon.py:692 FlatCAMCommon.py:1659 msgid "" "Spindle Speed.\n" "If it's left empty it will not be used.\n" "The speed of the spindle in RPM." msgstr "" -#: FlatCAMCommon.py:695 +#: FlatCAMCommon.py:696 FlatCAMCommon.py:1674 msgid "" "Dwell.\n" "Check this if a delay is needed to allow\n" "the spindle motor to reach it's set speed." msgstr "" -#: FlatCAMCommon.py:699 +#: FlatCAMCommon.py:700 FlatCAMCommon.py:1687 msgid "" "Dwell Time.\n" "A delay used to allow the motor spindle reach it's set speed." msgstr "" -#: FlatCAMCommon.py:702 +#: FlatCAMCommon.py:703 msgid "" "Preprocessor.\n" "A selection of files that will alter the generated G-code\n" "to fit for a number of use cases." msgstr "" -#: FlatCAMCommon.py:706 +#: FlatCAMCommon.py:707 FlatCAMCommon.py:1802 msgid "" "Extra Cut.\n" "If checked, after a isolation is finished an extra cut\n" @@ -1924,7 +1924,7 @@ msgid "" "ensure a complete isolation." msgstr "" -#: FlatCAMCommon.py:712 +#: FlatCAMCommon.py:713 FlatCAMCommon.py:1817 msgid "" "Extra Cut length.\n" "If checked, after a isolation is finished an extra cut\n" @@ -1934,7 +1934,7 @@ msgid "" "the extra cut." msgstr "" -#: FlatCAMCommon.py:719 +#: FlatCAMCommon.py:720 msgid "" "Toolchange.\n" "It will create a toolchange event.\n" @@ -1942,7 +1942,7 @@ msgid "" "the preprocessor file." msgstr "" -#: FlatCAMCommon.py:724 +#: FlatCAMCommon.py:725 msgid "" "Toolchange XY.\n" "A set of coordinates in the format (x, y).\n" @@ -1950,476 +1950,786 @@ msgid "" "where the tool change event take place." msgstr "" -#: FlatCAMCommon.py:729 +#: FlatCAMCommon.py:730 msgid "" "Toolchange Z.\n" "The position on Z plane where the tool change event take place." msgstr "" -#: FlatCAMCommon.py:732 +#: FlatCAMCommon.py:733 msgid "" "Start Z.\n" "If it's left empty it will not be used.\n" "A position on Z plane to move immediately after job start." msgstr "" -#: FlatCAMCommon.py:736 +#: FlatCAMCommon.py:737 msgid "" "End Z.\n" "A position on Z plane to move immediately after job stop." msgstr "" -#: FlatCAMCommon.py:748 FlatCAMCommon.py:1125 FlatCAMCommon.py:1159 +#: FlatCAMCommon.py:749 FlatCAMCommon.py:1126 FlatCAMCommon.py:1160 FlatCAMCommon.py:2335 +#: FlatCAMCommon.py:2556 FlatCAMCommon.py:2590 msgid "Could not load Tools DB file." msgstr "" -#: FlatCAMCommon.py:756 FlatCAMCommon.py:1167 +#: FlatCAMCommon.py:757 FlatCAMCommon.py:1168 FlatCAMCommon.py:2343 FlatCAMCommon.py:2598 msgid "Failed to parse Tools DB file." msgstr "" -#: FlatCAMCommon.py:759 FlatCAMCommon.py:1170 +#: FlatCAMCommon.py:760 FlatCAMCommon.py:1171 FlatCAMCommon.py:2346 FlatCAMCommon.py:2601 msgid "Loaded FlatCAM Tools DB from" msgstr "" -#: FlatCAMCommon.py:765 +#: FlatCAMCommon.py:766 FlatCAMCommon.py:2260 msgid "Add to DB" msgstr "" -#: FlatCAMCommon.py:767 +#: FlatCAMCommon.py:768 FlatCAMCommon.py:2263 msgid "Copy from DB" msgstr "" -#: FlatCAMCommon.py:769 +#: FlatCAMCommon.py:770 FlatCAMCommon.py:2266 msgid "Delete from DB" msgstr "" -#: FlatCAMCommon.py:1046 +#: FlatCAMCommon.py:1047 FlatCAMCommon.py:2473 msgid "Tool added to DB." msgstr "" -#: FlatCAMCommon.py:1067 +#: FlatCAMCommon.py:1068 FlatCAMCommon.py:2497 msgid "Tool copied from Tools DB." msgstr "" -#: FlatCAMCommon.py:1085 +#: FlatCAMCommon.py:1086 FlatCAMCommon.py:2516 msgid "Tool removed from Tools DB." msgstr "" -#: FlatCAMCommon.py:1096 +#: FlatCAMCommon.py:1097 FlatCAMCommon.py:2527 msgid "Export Tools Database" msgstr "" -#: FlatCAMCommon.py:1099 +#: FlatCAMCommon.py:1100 FlatCAMCommon.py:2530 msgid "Tools_Database" msgstr "" -#: FlatCAMCommon.py:1106 -msgid "FlatCAM Tools DB export cancelled." -msgstr "" - -#: FlatCAMCommon.py:1136 FlatCAMCommon.py:1139 FlatCAMCommon.py:1191 +#: FlatCAMCommon.py:1137 FlatCAMCommon.py:1140 FlatCAMCommon.py:1192 FlatCAMCommon.py:2567 +#: FlatCAMCommon.py:2570 FlatCAMCommon.py:2622 msgid "Failed to write Tools DB to file." msgstr "" -#: FlatCAMCommon.py:1142 +#: FlatCAMCommon.py:1143 FlatCAMCommon.py:2573 msgid "Exported Tools DB to" msgstr "" -#: FlatCAMCommon.py:1149 +#: FlatCAMCommon.py:1150 FlatCAMCommon.py:2580 msgid "Import FlatCAM Tools DB" msgstr "" -#: FlatCAMCommon.py:1152 -msgid "FlatCAM Tools DB import cancelled." -msgstr "" - -#: FlatCAMCommon.py:1195 +#: FlatCAMCommon.py:1196 FlatCAMCommon.py:2626 msgid "Saved Tools DB." msgstr "" -#: FlatCAMCommon.py:1342 +#: FlatCAMCommon.py:1343 FlatCAMCommon.py:2807 msgid "No Tool/row selected in the Tools Database table" msgstr "" -#: FlatCAMCommon.py:1360 +#: FlatCAMCommon.py:1361 FlatCAMCommon.py:2824 msgid "Cancelled adding tool from DB." msgstr "" -#: FlatCAMObj.py:257 +#: FlatCAMCommon.py:1462 +msgid "Basic Geo Parameters" +msgstr "" + +#: FlatCAMCommon.py:1474 +msgid "Advanced Geo Parameters" +msgstr "" + +#: FlatCAMCommon.py:1486 +msgid "NCC Parameters" +msgstr "" + +#: FlatCAMCommon.py:1498 +msgid "Paint Parameters" +msgstr "" + +#: FlatCAMCommon.py:1629 flatcamGUI/ObjectUI.py:966 flatcamGUI/ObjectUI.py:1767 +#: flatcamGUI/PreferencesUI.py:4378 flatcamGUI/PreferencesUI.py:7059 +#: flatcamTools/ToolSolderPaste.py:254 +msgid "Feedrate X-Y" +msgstr "" + +#: FlatCAMCommon.py:1631 +msgid "" +"Feedrate X-Y. Feedrate\n" +"The speed on XY plane used while cutting into material." +msgstr "" + +#: FlatCAMCommon.py:1643 flatcamGUI/ObjectUI.py:981 flatcamGUI/ObjectUI.py:1781 +#: flatcamGUI/PreferencesUI.py:3425 flatcamGUI/PreferencesUI.py:4393 +#: flatcamGUI/PreferencesUI.py:7072 flatcamTools/ToolSolderPaste.py:266 +msgid "Feedrate Z" +msgstr "" + +#: FlatCAMCommon.py:1645 +msgid "" +"Feedrate Z\n" +"The speed on Z plane." +msgstr "" + +#: FlatCAMCommon.py:1843 flatcamGUI/ObjectUI.py:844 flatcamGUI/PreferencesUI.py:3264 +#: flatcamTools/ToolNCC.py:341 +msgid "Operation" +msgstr "" + +#: FlatCAMCommon.py:1845 flatcamTools/ToolNCC.py:343 +msgid "" +"The 'Operation' can be:\n" +"- Isolation -> will ensure that the non-copper clearing is always complete.\n" +"If it's not successful then the non-copper clearing will fail, too.\n" +"- Clear -> the regular non-copper clearing." +msgstr "" + +#: FlatCAMCommon.py:1852 flatcamEditors/FlatCAMGrbEditor.py:2739 +#: flatcamGUI/GUIElements.py:2577 flatcamTools/ToolNCC.py:350 +msgid "Clear" +msgstr "" + +#: FlatCAMCommon.py:1853 flatcamTools/ToolNCC.py:351 flatcamTools/ToolNCC.py:1627 +msgid "Isolation" +msgstr "" + +#: FlatCAMCommon.py:1861 flatcamGUI/ObjectUI.py:408 flatcamGUI/ObjectUI.py:866 +#: flatcamGUI/PreferencesUI.py:2257 flatcamGUI/PreferencesUI.py:3280 +#: flatcamGUI/PreferencesUI.py:4665 flatcamGUI/PreferencesUI.py:5416 +#: flatcamTools/ToolNCC.py:359 +msgid "Milling Type" +msgstr "" + +#: FlatCAMCommon.py:1863 FlatCAMCommon.py:1871 flatcamGUI/PreferencesUI.py:5418 +#: flatcamGUI/PreferencesUI.py:5426 flatcamTools/ToolNCC.py:361 flatcamTools/ToolNCC.py:369 +msgid "" +"Milling type when the selected tool is of type: 'iso_op':\n" +"- climb / best for precision milling and to reduce tool usage\n" +"- conventional / useful when there is no backlash compensation" +msgstr "" + +#: FlatCAMCommon.py:1868 flatcamGUI/ObjectUI.py:414 flatcamGUI/PreferencesUI.py:2264 +#: flatcamGUI/PreferencesUI.py:4671 flatcamGUI/PreferencesUI.py:5423 +#: flatcamTools/ToolNCC.py:366 +msgid "Climb" +msgstr "" + +#: FlatCAMCommon.py:1869 flatcamGUI/ObjectUI.py:415 flatcamGUI/PreferencesUI.py:2265 +#: flatcamGUI/PreferencesUI.py:4672 flatcamGUI/PreferencesUI.py:5424 +#: flatcamTools/ToolNCC.py:367 +msgid "Conventional" +msgstr "" + +#: FlatCAMCommon.py:1881 FlatCAMCommon.py:1990 flatcamEditors/FlatCAMGeoEditor.py:452 +#: flatcamGUI/PreferencesUI.py:5461 flatcamGUI/PreferencesUI.py:6002 +#: flatcamTools/ToolNCC.py:382 flatcamTools/ToolPaint.py:329 +msgid "Overlap" +msgstr "" + +#: FlatCAMCommon.py:1883 flatcamGUI/PreferencesUI.py:5463 flatcamTools/ToolNCC.py:384 +msgid "" +"How much (percentage) of the tool width to overlap each tool pass.\n" +"Adjust the value starting with lower values\n" +"and increasing it if areas that should be cleared are still \n" +"not cleared.\n" +"Lower values = faster processing, faster execution on CNC.\n" +"Higher values = slow processing and slow execution on CNC\n" +"due of too many paths." +msgstr "" + +#: FlatCAMCommon.py:1902 FlatCAMCommon.py:2011 flatcamEditors/FlatCAMGeoEditor.py:472 +#: flatcamGUI/PreferencesUI.py:5481 flatcamGUI/PreferencesUI.py:5723 +#: flatcamGUI/PreferencesUI.py:6022 flatcamGUI/PreferencesUI.py:7681 +#: flatcamGUI/PreferencesUI.py:7838 flatcamGUI/PreferencesUI.py:7923 +#: flatcamGUI/PreferencesUI.py:8570 flatcamGUI/PreferencesUI.py:8578 +#: flatcamTools/ToolCopperThieving.py:112 flatcamTools/ToolCopperThieving.py:363 +#: flatcamTools/ToolCutOut.py:191 flatcamTools/ToolFiducials.py:172 +#: flatcamTools/ToolInvertGerber.py:88 flatcamTools/ToolInvertGerber.py:96 +#: flatcamTools/ToolNCC.py:403 flatcamTools/ToolPaint.py:350 +msgid "Margin" +msgstr "" + +#: FlatCAMCommon.py:1904 flatcamGUI/PreferencesUI.py:5483 flatcamGUI/PreferencesUI.py:7683 +#: flatcamGUI/PreferencesUI.py:7925 flatcamGUI/PreferencesUI.py:7989 +#: flatcamTools/ToolCopperThieving.py:114 flatcamTools/ToolFiducials.py:174 +#: flatcamTools/ToolFiducials.py:237 flatcamTools/ToolNCC.py:405 +msgid "Bounding box margin." +msgstr "" + +#: FlatCAMCommon.py:1915 FlatCAMCommon.py:2026 flatcamEditors/FlatCAMGeoEditor.py:486 +#: flatcamGUI/PreferencesUI.py:5494 flatcamGUI/PreferencesUI.py:6037 +#: flatcamGUI/PreferencesUI.py:8204 flatcamGUI/PreferencesUI.py:8417 +#: flatcamTools/ToolExtractDrills.py:128 flatcamTools/ToolNCC.py:416 +#: flatcamTools/ToolPaint.py:365 flatcamTools/ToolPunchGerber.py:139 +msgid "Method" +msgstr "" + +#: FlatCAMCommon.py:1917 flatcamGUI/PreferencesUI.py:5496 flatcamTools/ToolNCC.py:418 +msgid "" +"Algorithm for copper clearing:\n" +"- Standard: Fixed step inwards.\n" +"- Seed-based: Outwards from seed.\n" +"- Line-based: Parallel lines." +msgstr "" + +#: FlatCAMCommon.py:1925 FlatCAMCommon.py:2040 flatcamEditors/FlatCAMGeoEditor.py:500 +#: flatcamGUI/PreferencesUI.py:5509 flatcamGUI/PreferencesUI.py:6056 +#: flatcamTools/ToolNCC.py:431 flatcamTools/ToolNCC.py:2395 flatcamTools/ToolNCC.py:2424 +#: flatcamTools/ToolNCC.py:2693 flatcamTools/ToolNCC.py:2725 flatcamTools/ToolPaint.py:390 +#: flatcamTools/ToolPaint.py:1818 flatcamTools/ToolPaint.py:2717 +#: flatcamTools/ToolPaint.py:3198 flatcamTools/ToolPaint.py:3538 +msgid "Standard" +msgstr "" + +#: FlatCAMCommon.py:1925 FlatCAMCommon.py:2040 flatcamEditors/FlatCAMGeoEditor.py:500 +#: flatcamEditors/FlatCAMGeoEditor.py:5156 flatcamGUI/PreferencesUI.py:5509 +#: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:696 +#: flatcamTools/ToolPaint.py:1846 flatcamTools/ToolPaint.py:2729 +#: flatcamTools/ToolPaint.py:3188 flatcamTools/ToolPaint.py:3550 +msgid "Lines" +msgstr "" + +#: FlatCAMCommon.py:1933 FlatCAMCommon.py:2051 flatcamGUI/PreferencesUI.py:5516 +#: flatcamGUI/PreferencesUI.py:6063 flatcamTools/ToolNCC.py:439 +#: flatcamTools/ToolPaint.py:401 +msgid "Connect" +msgstr "" + +#: FlatCAMCommon.py:1937 FlatCAMCommon.py:2054 flatcamEditors/FlatCAMGeoEditor.py:509 +#: flatcamGUI/PreferencesUI.py:5518 flatcamGUI/PreferencesUI.py:6065 +#: flatcamTools/ToolNCC.py:443 flatcamTools/ToolPaint.py:404 +msgid "" +"Draw lines between resulting\n" +"segments to minimize tool lifts." +msgstr "" + +#: FlatCAMCommon.py:1943 FlatCAMCommon.py:2058 flatcamGUI/PreferencesUI.py:5525 +#: flatcamGUI/PreferencesUI.py:6071 flatcamTools/ToolNCC.py:449 +#: flatcamTools/ToolPaint.py:408 +msgid "Contour" +msgstr "" + +#: FlatCAMCommon.py:1947 FlatCAMCommon.py:2061 flatcamEditors/FlatCAMGeoEditor.py:519 +#: flatcamGUI/PreferencesUI.py:5527 flatcamGUI/PreferencesUI.py:6073 +#: flatcamTools/ToolNCC.py:453 flatcamTools/ToolPaint.py:411 +msgid "" +"Cut around the perimeter of the polygon\n" +"to trim rough edges." +msgstr "" + +#: FlatCAMCommon.py:1953 flatcamEditors/FlatCAMGeoEditor.py:613 +#: flatcamEditors/FlatCAMGrbEditor.py:5145 flatcamGUI/ObjectUI.py:142 +#: flatcamGUI/ObjectUI.py:1495 flatcamGUI/ObjectUI.py:2244 flatcamGUI/PreferencesUI.py:5534 +#: flatcamGUI/PreferencesUI.py:6822 flatcamTools/ToolNCC.py:459 +#: flatcamTools/ToolTransform.py:29 +msgid "Offset" +msgstr "" + +#: FlatCAMCommon.py:1957 flatcamGUI/PreferencesUI.py:5536 flatcamTools/ToolNCC.py:463 +msgid "" +"If used, it will add an offset to the copper features.\n" +"The copper clearing will finish to a distance\n" +"from the copper features.\n" +"The value can be between 0 and 10 FlatCAM units." +msgstr "" + +#: FlatCAMCommon.py:1992 flatcamEditors/FlatCAMGeoEditor.py:454 +#: flatcamGUI/PreferencesUI.py:6004 flatcamTools/ToolPaint.py:331 +msgid "" +"How much (percentage) of the tool width to overlap each tool pass.\n" +"Adjust the value starting with lower values\n" +"and increasing it if areas that should be painted are still \n" +"not painted.\n" +"Lower values = faster processing, faster execution on CNC.\n" +"Higher values = slow processing and slow execution on CNC\n" +"due of too many paths." +msgstr "" + +#: FlatCAMCommon.py:2013 flatcamEditors/FlatCAMGeoEditor.py:474 +#: flatcamGUI/PreferencesUI.py:6024 flatcamTools/ToolPaint.py:352 +msgid "" +"Distance by which to avoid\n" +"the edges of the polygon to\n" +"be painted." +msgstr "" + +#: FlatCAMCommon.py:2028 flatcamGUI/PreferencesUI.py:6039 flatcamTools/ToolPaint.py:367 +msgid "" +"Algorithm for painting:\n" +"- Standard: Fixed step inwards.\n" +"- Seed-based: Outwards from seed.\n" +"- Line-based: Parallel lines.\n" +"- Laser-lines: Active only for Gerber objects.\n" +"Will create lines that follow the traces.\n" +"- Combo: In case of failure a new method will be picked from the above\n" +"in the order specified." +msgstr "" + +#: FlatCAMCommon.py:2040 FlatCAMCommon.py:2042 flatcamGUI/PreferencesUI.py:6056 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:392 flatcamTools/ToolPaint.py:690 +#: flatcamTools/ToolPaint.py:695 flatcamTools/ToolPaint.py:1860 +#: flatcamTools/ToolPaint.py:2735 flatcamTools/ToolPaint.py:3207 +#: flatcamTools/ToolPaint.py:3556 +msgid "Laser_lines" +msgstr "" + +#: FlatCAMCommon.py:2040 flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolPaint.py:390 +#: flatcamTools/ToolPaint.py:2011 flatcamTools/ToolPaint.py:2861 +#: flatcamTools/ToolPaint.py:3333 flatcamTools/ToolPaint.py:3682 +msgid "Combo" +msgstr "" + +#: FlatCAMCommon.py:2085 +msgid "Add Tool in DB" +msgstr "" + +#: FlatCAMObj.py:264 msgid "Name changed from" msgstr "" -#: FlatCAMObj.py:257 +#: FlatCAMObj.py:264 msgid "to" msgstr "" -#: FlatCAMObj.py:268 +#: FlatCAMObj.py:275 msgid "Offsetting..." msgstr "" -#: FlatCAMObj.py:282 FlatCAMObj.py:287 +#: FlatCAMObj.py:289 FlatCAMObj.py:294 msgid "Scaling could not be executed." msgstr "" -#: FlatCAMObj.py:291 FlatCAMObj.py:299 +#: FlatCAMObj.py:298 FlatCAMObj.py:306 msgid "Scale done." msgstr "" -#: FlatCAMObj.py:297 +#: FlatCAMObj.py:304 msgid "Scaling..." msgstr "" -#: FlatCAMObj.py:315 +#: FlatCAMObj.py:322 msgid "Skewing..." msgstr "" -#: FlatCAMObj.py:736 FlatCAMObj.py:2746 FlatCAMObj.py:3968 flatcamGUI/PreferencesUI.py:1470 -#: flatcamGUI/PreferencesUI.py:2859 +#: FlatCAMObj.py:743 FlatCAMObj.py:831 flatcamGUI/ObjectUI.py:449 +#: flatcamGUI/PreferencesUI.py:6527 flatcamTools/ToolAlignObjects.py:73 +#: flatcamTools/ToolAlignObjects.py:109 flatcamTools/ToolCalibration.py:196 +#: flatcamTools/ToolCalibration.py:631 flatcamTools/ToolCalibration.py:648 +#: flatcamTools/ToolCalibration.py:807 flatcamTools/ToolCalibration.py:815 +#: flatcamTools/ToolCopperThieving.py:145 flatcamTools/ToolCopperThieving.py:159 +#: flatcamTools/ToolCopperThieving.py:605 flatcamTools/ToolCutOut.py:92 +#: flatcamTools/ToolDblSided.py:225 flatcamTools/ToolFilm.py:69 flatcamTools/ToolFilm.py:102 +#: flatcamTools/ToolFilm.py:549 flatcamTools/ToolFilm.py:557 flatcamTools/ToolImage.py:49 +#: flatcamTools/ToolImage.py:252 flatcamTools/ToolImage.py:273 flatcamTools/ToolNCC.py:96 +#: flatcamTools/ToolNCC.py:558 flatcamTools/ToolNCC.py:1293 flatcamTools/ToolPaint.py:502 +#: flatcamTools/ToolPaint.py:703 flatcamTools/ToolPanelize.py:118 +#: flatcamTools/ToolPanelize.py:204 flatcamTools/ToolPanelize.py:374 +#: flatcamTools/ToolPanelize.py:391 +msgid "Gerber" +msgstr "" + +#: FlatCAMObj.py:743 FlatCAMObj.py:831 flatcamGUI/FlatCAMGUI.py:2154 +#: flatcamGUI/ObjectUI.py:449 flatcamTools/ToolCalibration.py:631 +#: flatcamTools/ToolCalibration.py:648 flatcamTools/ToolCalibration.py:815 +#: flatcamTools/ToolCopperThieving.py:145 flatcamTools/ToolCopperThieving.py:159 +#: flatcamTools/ToolCopperThieving.py:605 flatcamTools/ToolCutOut.py:93 +#: flatcamTools/ToolDblSided.py:227 flatcamTools/ToolFilm.py:69 flatcamTools/ToolFilm.py:102 +#: flatcamTools/ToolFilm.py:549 flatcamTools/ToolFilm.py:557 flatcamTools/ToolImage.py:49 +#: flatcamTools/ToolImage.py:271 flatcamTools/ToolNCC.py:95 flatcamTools/ToolNCC.py:558 +#: flatcamTools/ToolNCC.py:1293 flatcamTools/ToolPaint.py:502 flatcamTools/ToolPaint.py:703 +#: flatcamTools/ToolPanelize.py:118 flatcamTools/ToolPanelize.py:374 +#: flatcamTools/ToolPanelize.py:391 +msgid "Geometry" +msgstr "" + +#: FlatCAMObj.py:755 FlatCAMObj.py:2957 FlatCAMObj.py:4421 flatcamGUI/PreferencesUI.py:1646 +#: flatcamGUI/PreferencesUI.py:3041 msgid "Basic" msgstr "" -#: FlatCAMObj.py:763 FlatCAMObj.py:2758 FlatCAMObj.py:3989 flatcamGUI/PreferencesUI.py:1471 +#: FlatCAMObj.py:782 FlatCAMObj.py:2970 FlatCAMObj.py:4442 flatcamGUI/PreferencesUI.py:1647 msgid "Advanced" msgstr "" -#: FlatCAMObj.py:980 +#: FlatCAMObj.py:998 msgid "Buffering solid geometry" msgstr "" -#: FlatCAMObj.py:983 camlib.py:965 flatcamGUI/PreferencesUI.py:2296 -#: flatcamTools/ToolCopperThieving.py:1011 flatcamTools/ToolCopperThieving.py:1200 -#: flatcamTools/ToolCopperThieving.py:1212 flatcamTools/ToolNonCopperClear.py:1624 -#: flatcamTools/ToolNonCopperClear.py:1721 flatcamTools/ToolNonCopperClear.py:1732 -#: flatcamTools/ToolNonCopperClear.py:2015 flatcamTools/ToolNonCopperClear.py:2111 -#: flatcamTools/ToolNonCopperClear.py:2123 +#: FlatCAMObj.py:1001 camlib.py:979 flatcamGUI/PreferencesUI.py:2476 +#: flatcamTools/ToolCopperThieving.py:1017 flatcamTools/ToolCopperThieving.py:1206 +#: flatcamTools/ToolCopperThieving.py:1218 flatcamTools/ToolNCC.py:2050 +#: flatcamTools/ToolNCC.py:2158 flatcamTools/ToolNCC.py:2172 flatcamTools/ToolNCC.py:3103 +#: flatcamTools/ToolNCC.py:3208 flatcamTools/ToolNCC.py:3223 flatcamTools/ToolNCC.py:3489 +#: flatcamTools/ToolNCC.py:3590 flatcamTools/ToolNCC.py:3605 msgid "Buffering" msgstr "" -#: FlatCAMObj.py:989 +#: FlatCAMObj.py:1007 msgid "Done" msgstr "" -#: FlatCAMObj.py:1040 +#: FlatCAMObj.py:1032 FlatCAMObj.py:1058 +msgid "Operation could not be done." +msgstr "" + +#: FlatCAMObj.py:1075 msgid "Isolating..." msgstr "" -#: FlatCAMObj.py:1099 +#: FlatCAMObj.py:1134 msgid "Click on a polygon to isolate it." msgstr "" -#: FlatCAMObj.py:1138 FlatCAMObj.py:1243 flatcamTools/ToolPaint.py:1120 +#: FlatCAMObj.py:1173 FlatCAMObj.py:1277 flatcamTools/ToolPaint.py:1504 msgid "Added polygon" msgstr "" -#: FlatCAMObj.py:1140 FlatCAMObj.py:1245 +#: FlatCAMObj.py:1174 FlatCAMObj.py:1279 msgid "Click to add next polygon or right click to start isolation." msgstr "" -#: FlatCAMObj.py:1152 flatcamTools/ToolPaint.py:1134 +#: FlatCAMObj.py:1186 flatcamTools/ToolPaint.py:1518 msgid "Removed polygon" msgstr "" -#: FlatCAMObj.py:1153 +#: FlatCAMObj.py:1187 msgid "Click to add/remove next polygon or right click to start isolation." msgstr "" -#: FlatCAMObj.py:1158 flatcamTools/ToolPaint.py:1140 +#: FlatCAMObj.py:1192 flatcamTools/ToolPaint.py:1524 msgid "No polygon detected under click position." msgstr "" -#: FlatCAMObj.py:1179 flatcamTools/ToolPaint.py:1169 +#: FlatCAMObj.py:1213 flatcamTools/ToolPaint.py:1553 msgid "List of single polygons is empty. Aborting." msgstr "" -#: FlatCAMObj.py:1248 +#: FlatCAMObj.py:1282 msgid "No polygon in selection." msgstr "" -#: FlatCAMObj.py:1324 FlatCAMObj.py:1457 flatcamTools/ToolNonCopperClear.py:1653 -#: flatcamTools/ToolNonCopperClear.py:2039 -msgid "Isolation geometry could not be generated." -msgstr "" - -#: FlatCAMObj.py:1374 FlatCAMObj.py:3637 FlatCAMObj.py:3922 FlatCAMObj.py:4221 +#: FlatCAMObj.py:1394 FlatCAMObj.py:1542 FlatCAMObj.py:4055 FlatCAMObj.py:4375 +#: FlatCAMObj.py:4762 msgid "Rough" msgstr "" -#: FlatCAMObj.py:1400 FlatCAMObj.py:1480 +#: FlatCAMObj.py:1410 FlatCAMObj.py:1489 flatcamTools/ToolNCC.py:2086 +#: flatcamTools/ToolNCC.py:3137 flatcamTools/ToolNCC.py:3516 +msgid "Isolation geometry could not be generated." +msgstr "" + +#: FlatCAMObj.py:1435 FlatCAMObj.py:1567 msgid "Isolation geometry created" msgstr "" -#: FlatCAMObj.py:1409 FlatCAMObj.py:1487 +#: FlatCAMObj.py:1444 FlatCAMObj.py:1574 msgid "Subtracting Geo" msgstr "" -#: FlatCAMObj.py:1807 +#: FlatCAMObj.py:1899 msgid "Plotting Apertures" msgstr "" -#: FlatCAMObj.py:2573 flatcamEditors/FlatCAMExcEditor.py:2427 +#: FlatCAMObj.py:2753 flatcamEditors/FlatCAMExcEditor.py:2453 msgid "Total Drills" msgstr "" -#: FlatCAMObj.py:2605 flatcamEditors/FlatCAMExcEditor.py:2459 +#: FlatCAMObj.py:2784 flatcamEditors/FlatCAMExcEditor.py:2485 msgid "Total Slots" msgstr "" -#: FlatCAMObj.py:3060 FlatCAMObj.py:3155 FlatCAMObj.py:3276 -msgid "Please select one or more tools from the list and try again." -msgstr "" - -#: FlatCAMObj.py:3067 -msgid "Milling tool for DRILLS is larger than hole size. Cancelled." -msgstr "" - -#: FlatCAMObj.py:3068 FlatCAMObj.py:4533 flatcamEditors/FlatCAMGeoEditor.py:408 -#: flatcamGUI/FlatCAMGUI.py:457 flatcamGUI/FlatCAMGUI.py:1072 flatcamGUI/ObjectUI.py:1353 -msgid "Tool" -msgstr "" - -#: FlatCAMObj.py:3084 FlatCAMObj.py:3177 FlatCAMObj.py:3295 -msgid "Tool_nr" -msgstr "" - -#: FlatCAMObj.py:3084 FlatCAMObj.py:3177 FlatCAMObj.py:3295 -#: flatcamEditors/FlatCAMExcEditor.py:1582 flatcamEditors/FlatCAMExcEditor.py:3048 -#: flatcamGUI/ObjectUI.py:777 flatcamTools/ToolNonCopperClear.py:120 -#: flatcamTools/ToolPaint.py:123 flatcamTools/ToolPcbWizard.py:76 -#: flatcamTools/ToolProperties.py:396 flatcamTools/ToolProperties.py:449 -#: flatcamTools/ToolSolderPaste.py:84 -msgid "Diameter" -msgstr "" - -#: FlatCAMObj.py:3084 FlatCAMObj.py:3177 FlatCAMObj.py:3295 -msgid "Drills_Nr" -msgstr "" - -#: FlatCAMObj.py:3084 FlatCAMObj.py:3177 FlatCAMObj.py:3295 -msgid "Slots_Nr" -msgstr "" - -#: FlatCAMObj.py:3164 -msgid "Milling tool for SLOTS is larger than hole size. Cancelled." -msgstr "" - -#: FlatCAMObj.py:3336 -msgid "Wrong value format for self.defaults[\"z_pdepth\"] or self.options[\"z_pdepth\"]" -msgstr "" - -#: FlatCAMObj.py:3347 -msgid "" -"Wrong value format for self.defaults[\"feedrate_probe\"] or self.options[\"feedrate_probe" -"\"]" -msgstr "" - -#: FlatCAMObj.py:3377 FlatCAMObj.py:5354 FlatCAMObj.py:5358 FlatCAMObj.py:5493 -msgid "Generating CNC Code" -msgstr "" - -#: FlatCAMObj.py:3637 FlatCAMObj.py:4632 FlatCAMObj.py:4633 FlatCAMObj.py:4642 -msgid "Iso" -msgstr "" - -#: FlatCAMObj.py:3637 -msgid "Finish" -msgstr "" - -#: FlatCAMObj.py:3957 -msgid "Add from Tool DB" -msgstr "" - -#: FlatCAMObj.py:3960 flatcamGUI/FlatCAMGUI.py:678 flatcamGUI/FlatCAMGUI.py:794 -#: flatcamGUI/FlatCAMGUI.py:989 flatcamGUI/FlatCAMGUI.py:2015 flatcamGUI/FlatCAMGUI.py:2159 -#: flatcamGUI/FlatCAMGUI.py:2378 flatcamGUI/FlatCAMGUI.py:2557 flatcamGUI/ObjectUI.py:1324 -#: flatcamTools/ToolPanelize.py:534 flatcamTools/ToolPanelize.py:561 -#: flatcamTools/ToolPanelize.py:660 flatcamTools/ToolPanelize.py:694 -#: flatcamTools/ToolPanelize.py:759 -msgid "Copy" -msgstr "" - -#: FlatCAMObj.py:4054 FlatCAMObj.py:4397 FlatCAMObj.py:5107 FlatCAMObj.py:5744 -#: flatcamEditors/FlatCAMExcEditor.py:2534 flatcamEditors/FlatCAMGeoEditor.py:1078 -#: flatcamEditors/FlatCAMGeoEditor.py:1112 flatcamEditors/FlatCAMGeoEditor.py:1133 -#: flatcamEditors/FlatCAMGeoEditor.py:1154 flatcamEditors/FlatCAMGeoEditor.py:1191 -#: flatcamEditors/FlatCAMGeoEditor.py:1219 flatcamEditors/FlatCAMGeoEditor.py:1240 -#: flatcamTools/ToolNonCopperClear.py:1052 flatcamTools/ToolNonCopperClear.py:1461 -#: flatcamTools/ToolPaint.py:835 flatcamTools/ToolPaint.py:1019 -#: flatcamTools/ToolPaint.py:2198 flatcamTools/ToolSolderPaste.py:882 -#: flatcamTools/ToolSolderPaste.py:957 -msgid "Wrong value format entered, use a number." -msgstr "" - -#: FlatCAMObj.py:4240 -msgid "Tool added in Tool Table." -msgstr "" - -#: FlatCAMObj.py:4347 FlatCAMObj.py:4356 -msgid "Failed. Select a tool to copy." -msgstr "" - -#: FlatCAMObj.py:4383 -msgid "Tool was copied in Tool Table." -msgstr "" - -#: FlatCAMObj.py:4411 -msgid "Tool was edited in Tool Table." -msgstr "" - -#: FlatCAMObj.py:4440 FlatCAMObj.py:4449 -msgid "Failed. Select a tool to delete." -msgstr "" - -#: FlatCAMObj.py:4472 -msgid "Tool was deleted in Tool Table." -msgstr "" - -#: FlatCAMObj.py:4533 flatcamGUI/ObjectUI.py:1353 +#: FlatCAMObj.py:2857 FlatCAMObj.py:3069 FlatCAMObj.py:3085 FlatCAMObj.py:3089 +#: FlatCAMObj.py:4242 FlatCAMObj.py:4667 FlatCAMObj.py:4703 flatcamGUI/ObjectUI.py:817 +#: flatcamGUI/ObjectUI.py:1660 flatcamTools/ToolNCC.py:331 flatcamTools/ToolNCC.py:794 +#: flatcamTools/ToolNCC.py:808 flatcamTools/ToolNCC.py:1189 flatcamTools/ToolPaint.py:314 +#: flatcamTools/ToolPaint.py:764 flatcamTools/ToolPaint.py:776 +#: flatcamTools/ToolPaint.py:1159 msgid "Parameters for" msgstr "" -#: FlatCAMObj.py:4967 +#: FlatCAMObj.py:2857 FlatCAMObj.py:3089 FlatCAMObj.py:4242 FlatCAMObj.py:4703 +#: flatcamTools/ToolNCC.py:808 flatcamTools/ToolNCC.py:1189 flatcamTools/ToolPaint.py:776 +#: flatcamTools/ToolPaint.py:1159 +msgid "Multiple Tools" +msgstr "" + +#: FlatCAMObj.py:3069 +msgid "No Tool Selected" +msgstr "" + +#: FlatCAMObj.py:3085 FlatCAMObj.py:3427 FlatCAMObj.py:4667 +#: flatcamEditors/FlatCAMGeoEditor.py:406 flatcamGUI/FlatCAMGUI.py:496 +#: flatcamGUI/FlatCAMGUI.py:1143 flatcamGUI/ObjectUI.py:817 flatcamGUI/ObjectUI.py:1660 +#: flatcamTools/ToolNCC.py:331 flatcamTools/ToolNCC.py:794 flatcamTools/ToolPaint.py:314 +#: flatcamTools/ToolPaint.py:764 +msgid "Tool" +msgstr "" + +#: FlatCAMObj.py:3419 FlatCAMObj.py:3512 FlatCAMObj.py:3700 +msgid "Please select one or more tools from the list and try again." +msgstr "" + +#: FlatCAMObj.py:3426 +msgid "Milling tool for DRILLS is larger than hole size. Cancelled." +msgstr "" + +#: FlatCAMObj.py:3442 FlatCAMObj.py:3533 FlatCAMObj.py:3719 +#: tclCommands/TclCommandDrillcncjob.py:194 +msgid "Tool_nr" +msgstr "" + +#: FlatCAMObj.py:3442 FlatCAMObj.py:3533 FlatCAMObj.py:3719 +#: flatcamEditors/FlatCAMExcEditor.py:1585 flatcamEditors/FlatCAMExcEditor.py:3069 +#: flatcamGUI/ObjectUI.py:780 flatcamTools/ToolNCC.py:132 flatcamTools/ToolPaint.py:128 +#: flatcamTools/ToolPcbWizard.py:76 flatcamTools/ToolProperties.py:416 +#: flatcamTools/ToolProperties.py:476 flatcamTools/ToolSolderPaste.py:86 +#: tclCommands/TclCommandDrillcncjob.py:194 +msgid "Diameter" +msgstr "" + +#: FlatCAMObj.py:3442 FlatCAMObj.py:3533 FlatCAMObj.py:3719 +#: tclCommands/TclCommandDrillcncjob.py:194 +msgid "Drills_Nr" +msgstr "" + +#: FlatCAMObj.py:3442 FlatCAMObj.py:3533 FlatCAMObj.py:3719 +#: tclCommands/TclCommandDrillcncjob.py:194 +msgid "Slots_Nr" +msgstr "" + +#: FlatCAMObj.py:3521 +msgid "Milling tool for SLOTS is larger than hole size. Cancelled." +msgstr "" + +#: FlatCAMObj.py:3626 FlatCAMObj.py:5451 +msgid "Focus Z" +msgstr "" + +#: FlatCAMObj.py:3645 FlatCAMObj.py:5470 +msgid "Laser Power" +msgstr "" + +#: FlatCAMObj.py:3677 FlatCAMObj.py:5502 flatcamGUI/ObjectUI.py:1048 +#: flatcamGUI/ObjectUI.py:1839 flatcamGUI/PreferencesUI.py:4409 +msgid "Spindle speed" +msgstr "" + +#: FlatCAMObj.py:3776 FlatCAMObj.py:5911 FlatCAMObj.py:5915 FlatCAMObj.py:6060 +msgid "Generating CNC Code" +msgstr "" + +#: FlatCAMObj.py:3966 flatcamTools/ToolNCC.py:916 flatcamTools/ToolPaint.py:841 +msgid "Current Tool parameters were applied to all tools." +msgstr "" + +#: FlatCAMObj.py:4055 FlatCAMObj.py:5115 FlatCAMObj.py:5116 FlatCAMObj.py:5125 +msgid "Iso" +msgstr "" + +#: FlatCAMObj.py:4055 +msgid "Finish" +msgstr "" + +#: FlatCAMObj.py:4410 +msgid "Add from Tool DB" +msgstr "" + +#: FlatCAMObj.py:4413 flatcamGUI/FlatCAMGUI.py:734 flatcamGUI/FlatCAMGUI.py:848 +#: flatcamGUI/FlatCAMGUI.py:1057 flatcamGUI/FlatCAMGUI.py:2123 flatcamGUI/FlatCAMGUI.py:2267 +#: flatcamGUI/FlatCAMGUI.py:2532 flatcamGUI/FlatCAMGUI.py:2731 flatcamGUI/ObjectUI.py:1615 +#: flatcamTools/ToolPanelize.py:543 flatcamTools/ToolPanelize.py:570 +#: flatcamTools/ToolPanelize.py:669 flatcamTools/ToolPanelize.py:703 +#: flatcamTools/ToolPanelize.py:768 +msgid "Copy" +msgstr "" + +#: FlatCAMObj.py:4507 FlatCAMObj.py:4941 FlatCAMObj.py:5661 FlatCAMObj.py:6307 +#: flatcamEditors/FlatCAMExcEditor.py:2560 flatcamEditors/FlatCAMGeoEditor.py:1077 +#: flatcamEditors/FlatCAMGeoEditor.py:1118 flatcamEditors/FlatCAMGeoEditor.py:1146 +#: flatcamEditors/FlatCAMGeoEditor.py:1174 flatcamEditors/FlatCAMGeoEditor.py:1218 +#: flatcamEditors/FlatCAMGeoEditor.py:1253 flatcamEditors/FlatCAMGeoEditor.py:1281 +#: flatcamTools/ToolNCC.py:1502 flatcamTools/ToolPaint.py:1237 +#: flatcamTools/ToolPaint.py:1408 flatcamTools/ToolSolderPaste.py:883 +#: flatcamTools/ToolSolderPaste.py:956 +msgid "Wrong value format entered, use a number." +msgstr "" + +#: FlatCAMObj.py:4781 +msgid "Tool added in Tool Table." +msgstr "" + +#: FlatCAMObj.py:4890 FlatCAMObj.py:4899 +msgid "Failed. Select a tool to copy." +msgstr "" + +#: FlatCAMObj.py:4928 +msgid "Tool was copied in Tool Table." +msgstr "" + +#: FlatCAMObj.py:4955 +msgid "Tool was edited in Tool Table." +msgstr "" + +#: FlatCAMObj.py:4984 FlatCAMObj.py:4993 +msgid "Failed. Select a tool to delete." +msgstr "" + +#: FlatCAMObj.py:5017 +msgid "Tool was deleted in Tool Table." +msgstr "" + +#: FlatCAMObj.py:5523 msgid "This Geometry can't be processed because it is" msgstr "" -#: FlatCAMObj.py:4969 +#: FlatCAMObj.py:5523 msgid "geometry" msgstr "" -#: FlatCAMObj.py:5012 +#: FlatCAMObj.py:5564 msgid "Failed. No tool selected in the tool table ..." msgstr "" -#: FlatCAMObj.py:5112 FlatCAMObj.py:5264 +#: FlatCAMObj.py:5667 FlatCAMObj.py:5820 msgid "" "Tool Offset is selected in Tool Table but no value is provided.\n" "Add a Tool Offset or change the Offset Type." msgstr "" -#: FlatCAMObj.py:5177 FlatCAMObj.py:5325 +#: FlatCAMObj.py:5733 FlatCAMObj.py:5882 msgid "G-Code parsing in progress..." msgstr "" -#: FlatCAMObj.py:5179 FlatCAMObj.py:5327 +#: FlatCAMObj.py:5735 FlatCAMObj.py:5884 msgid "G-Code parsing finished..." msgstr "" -#: FlatCAMObj.py:5187 +#: FlatCAMObj.py:5743 msgid "Finished G-Code processing" msgstr "" -#: FlatCAMObj.py:5189 FlatCAMObj.py:5339 +#: FlatCAMObj.py:5745 FlatCAMObj.py:5896 msgid "G-Code processing failed with error" msgstr "" -#: FlatCAMObj.py:5234 flatcamTools/ToolSolderPaste.py:1303 +#: FlatCAMObj.py:5790 flatcamTools/ToolSolderPaste.py:1300 msgid "Cancelled. Empty file, it has no geometry" msgstr "" -#: FlatCAMObj.py:5337 FlatCAMObj.py:5486 +#: FlatCAMObj.py:5894 FlatCAMObj.py:6055 msgid "Finished G-Code processing..." msgstr "" -#: FlatCAMObj.py:5356 FlatCAMObj.py:5360 FlatCAMObj.py:5496 +#: FlatCAMObj.py:5913 FlatCAMObj.py:5917 FlatCAMObj.py:6062 msgid "CNCjob created" msgstr "" -#: FlatCAMObj.py:5527 FlatCAMObj.py:5536 flatcamParsers/ParseGerber.py:1794 -#: flatcamParsers/ParseGerber.py:1804 +#: FlatCAMObj.py:6092 FlatCAMObj.py:6101 flatcamParsers/ParseGerber.py:1866 +#: flatcamParsers/ParseGerber.py:1876 msgid "Scale factor has to be a number: integer or float." msgstr "" -#: FlatCAMObj.py:5600 +#: FlatCAMObj.py:6164 msgid "Geometry Scale done." msgstr "" -#: FlatCAMObj.py:5617 flatcamParsers/ParseGerber.py:1920 +#: FlatCAMObj.py:6181 flatcamParsers/ParseGerber.py:1992 msgid "" "An (x,y) pair of values are needed. Probable you entered only one value in the Offset " "field." msgstr "" -#: FlatCAMObj.py:5674 +#: FlatCAMObj.py:6237 msgid "Geometry Offset done." msgstr "" -#: FlatCAMObj.py:5703 +#: FlatCAMObj.py:6266 msgid "" "The Toolchange X,Y field in Edit -> Preferences has to be in the format (x, y)\n" "but now there is only one value, not two." msgstr "" -#: FlatCAMObj.py:6388 FlatCAMObj.py:7175 FlatCAMObj.py:7371 +#: FlatCAMObj.py:6956 FlatCAMObj.py:7802 FlatCAMObj.py:7999 msgid "Basic" msgstr "" -#: FlatCAMObj.py:6394 FlatCAMObj.py:7179 FlatCAMObj.py:7375 +#: FlatCAMObj.py:6962 FlatCAMObj.py:7806 FlatCAMObj.py:8003 msgid "Advanced" msgstr "" -#: FlatCAMObj.py:6437 +#: FlatCAMObj.py:7005 msgid "Plotting..." msgstr "" -#: FlatCAMObj.py:6460 FlatCAMObj.py:6465 flatcamTools/ToolSolderPaste.py:1509 +#: FlatCAMObj.py:7034 FlatCAMObj.py:7039 flatcamTools/ToolSolderPaste.py:1498 msgid "Export Machine Code ..." msgstr "" -#: FlatCAMObj.py:6470 flatcamTools/ToolSolderPaste.py:1513 +#: FlatCAMObj.py:7044 flatcamTools/ToolSolderPaste.py:1502 msgid "Export Machine Code cancelled ..." msgstr "" -#: FlatCAMObj.py:6492 +#: FlatCAMObj.py:7065 msgid "Machine Code file saved to" msgstr "" -#: FlatCAMObj.py:6546 flatcamTools/ToolCalibration.py:1083 +#: FlatCAMObj.py:7126 flatcamTools/ToolCalibration.py:1097 msgid "Loaded Machine Code into Code Editor" msgstr "" -#: FlatCAMObj.py:6684 +#: FlatCAMObj.py:7265 msgid "This CNCJob object can't be processed because it is a" msgstr "" -#: FlatCAMObj.py:6686 +#: FlatCAMObj.py:7267 msgid "CNCJob object" msgstr "" -#: FlatCAMObj.py:6866 +#: FlatCAMObj.py:7447 msgid "" "G-code does not have a G94 code and we will not include the code in the 'Prepend to " "GCode' text box" msgstr "" -#: FlatCAMObj.py:6877 +#: FlatCAMObj.py:7458 msgid "Cancelled. The Toolchange Custom code is enabled but it's empty." msgstr "" -#: FlatCAMObj.py:6882 +#: FlatCAMObj.py:7463 msgid "Toolchange G-code was replaced by a custom code." msgstr "" -#: FlatCAMObj.py:6899 flatcamEditors/FlatCAMTextEditor.py:270 -#: flatcamTools/ToolSolderPaste.py:1540 +#: FlatCAMObj.py:7480 flatcamEditors/FlatCAMTextEditor.py:272 +#: flatcamTools/ToolSolderPaste.py:1529 msgid "No such file or directory" msgstr "" -#: FlatCAMObj.py:6913 flatcamEditors/FlatCAMTextEditor.py:282 +#: FlatCAMObj.py:7494 flatcamEditors/FlatCAMTextEditor.py:284 msgid "Saved to" msgstr "" -#: FlatCAMObj.py:6923 FlatCAMObj.py:6933 +#: FlatCAMObj.py:7511 FlatCAMObj.py:7521 msgid "The used preprocessor file has to have in it's name: 'toolchange_custom'" msgstr "" -#: FlatCAMObj.py:6937 +#: FlatCAMObj.py:7524 msgid "There is no preprocessor file." msgstr "" -#: FlatCAMObj.py:7194 +#: FlatCAMObj.py:7821 msgid "Script Editor" msgstr "" -#: FlatCAMObj.py:7475 +#: FlatCAMObj.py:8103 msgid "Document Editor" msgstr "" @@ -2427,6 +2737,16 @@ msgstr "" msgid "processes running." msgstr "" +#: FlatCAMTool.py:245 FlatCAMTool.py:252 flatcamGUI/ObjectUI.py:156 +#: flatcamGUI/ObjectUI.py:163 +msgid "Edited value is out of range" +msgstr "" + +#: FlatCAMTool.py:247 FlatCAMTool.py:254 flatcamGUI/ObjectUI.py:158 +#: flatcamGUI/ObjectUI.py:165 +msgid "Edited value is within limits." +msgstr "" + #: FlatCAMTranslation.py:103 msgid "The application will restart." msgstr "" @@ -2439,130 +2759,136 @@ msgstr "" msgid "Apply Language ..." msgstr "" -#: ObjectCollection.py:459 +#: ObjectCollection.py:506 #, python-brace-format msgid "Object renamed from {old} to {new}" msgstr "" -#: ObjectCollection.py:858 +#: ObjectCollection.py:972 msgid "Cause of error" msgstr "" -#: camlib.py:590 +#: camlib.py:593 msgid "self.solid_geometry is neither BaseGeometry or list." msgstr "" -#: camlib.py:953 +#: camlib.py:968 msgid "Pass" msgstr "" -#: camlib.py:974 +#: camlib.py:988 msgid "Get Exteriors" msgstr "" -#: camlib.py:977 +#: camlib.py:991 msgid "Get Interiors" msgstr "" -#: camlib.py:1964 +#: camlib.py:2172 msgid "Object was mirrored" msgstr "" -#: camlib.py:1967 +#: camlib.py:2175 msgid "Failed to mirror. No object selected" msgstr "" -#: camlib.py:2036 +#: camlib.py:2244 msgid "Object was rotated" msgstr "" -#: camlib.py:2039 +#: camlib.py:2247 msgid "Failed to rotate. No object selected" msgstr "" -#: camlib.py:2107 +#: camlib.py:2314 msgid "Object was skewed" msgstr "" -#: camlib.py:2110 +#: camlib.py:2317 msgid "Failed to skew. No object selected" msgstr "" -#: camlib.py:2179 +#: camlib.py:2392 msgid "Object was buffered" msgstr "" -#: camlib.py:2181 +#: camlib.py:2394 msgid "Failed to buffer. No object selected" msgstr "" -#: camlib.py:2378 +#: camlib.py:2599 msgid "There is no such parameter" msgstr "" -#: camlib.py:2454 +#: camlib.py:2659 camlib.py:2892 camlib.py:3121 camlib.py:3343 msgid "" "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)." msgstr "" -#: camlib.py:2462 camlib.py:3181 camlib.py:3539 +#: camlib.py:2667 camlib.py:2902 camlib.py:3131 camlib.py:3353 camlib.py:3639 camlib.py:4008 msgid "The Cut Z parameter is zero. There will be no cut, skipping file" msgstr "" -#: camlib.py:2475 camlib.py:3512 +#: camlib.py:2678 camlib.py:3976 msgid "" "The Toolchange X,Y field in Edit -> Preferences has to be in the format (x, y) \n" "but now there is only one value, not two. " msgstr "" -#: camlib.py:2550 +#: camlib.py:2687 camlib.py:3590 camlib.py:3958 +msgid "" +"The End Move X,Y field in Edit -> Preferences has to be in the format (x, y) but now " +"there is only one value, not two." +msgstr "" + +#: camlib.py:2775 msgid "Creating a list of points to drill..." msgstr "" -#: camlib.py:2632 +#: camlib.py:2865 camlib.py:3737 camlib.py:4112 msgid "Starting G-Code" msgstr "" -#: camlib.py:2727 camlib.py:2870 camlib.py:2972 camlib.py:3292 camlib.py:3653 +#: camlib.py:3006 camlib.py:3225 camlib.py:3389 camlib.py:3750 camlib.py:4123 msgid "Starting G-Code for tool with diameter" msgstr "" -#: camlib.py:2783 camlib.py:2926 camlib.py:3029 +#: camlib.py:3089 camlib.py:3307 camlib.py:3475 msgid "G91 coordinates not implemented" msgstr "" -#: camlib.py:2789 camlib.py:2933 camlib.py:3035 +#: camlib.py:3095 camlib.py:3314 camlib.py:3481 msgid "The loaded Excellon file has no drills" msgstr "" -#: camlib.py:3058 +#: camlib.py:3504 msgid "Finished G-Code generation..." msgstr "" -#: camlib.py:3153 +#: camlib.py:3608 msgid "" "The Toolchange X,Y field in Edit -> Preferences has to be in the format (x, y) \n" "but now there is only one value, not two." msgstr "" -#: camlib.py:3166 camlib.py:3525 +#: camlib.py:3622 camlib.py:3991 msgid "Cut_Z parameter is None or zero. Most likely a bad combinations of other parameters." msgstr "" -#: camlib.py:3173 camlib.py:3531 +#: camlib.py:3631 camlib.py:4000 msgid "" "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)." msgstr "" -#: camlib.py:3186 camlib.py:3545 +#: camlib.py:3644 camlib.py:4014 msgid "Travel Z parameter is None or zero." msgstr "" -#: camlib.py:3191 camlib.py:3550 +#: camlib.py:3649 camlib.py:4019 msgid "" "The Travel Z parameter has negative value. It is the height value to travel between " "cuts.\n" @@ -2570,69 +2896,65 @@ msgid "" "the app will convert the value to positive.Check the resulting CNC code (Gcode etc)." msgstr "" -#: camlib.py:3199 camlib.py:3558 +#: camlib.py:3657 camlib.py:4027 msgid "The Z Travel parameter is zero. This is dangerous, skipping file" msgstr "" -#: camlib.py:3218 camlib.py:3580 +#: camlib.py:3676 camlib.py:4050 msgid "Indexing geometry before generating G-Code..." msgstr "" -#: camlib.py:3279 camlib.py:3642 -msgid "Starting G-Code..." -msgstr "" - -#: camlib.py:3362 camlib.py:3724 +#: camlib.py:3820 camlib.py:4192 msgid "Finished G-Code generation" msgstr "" -#: camlib.py:3364 +#: camlib.py:3820 msgid "paths traced" msgstr "" -#: camlib.py:3399 +#: camlib.py:3853 msgid "Expected a Geometry, got" msgstr "" -#: camlib.py:3406 +#: camlib.py:3860 msgid "Trying to generate a CNC Job from a Geometry object without solid_geometry." msgstr "" -#: camlib.py:3446 +#: camlib.py:3901 msgid "" "The Tool Offset value is too negative to use for the current_geometry.\n" "Raise the value (in module) and try again." msgstr "" -#: camlib.py:3724 +#: camlib.py:4192 msgid " paths traced." msgstr "" -#: camlib.py:3752 +#: camlib.py:4220 msgid "There is no tool data in the SolderPaste geometry." msgstr "" -#: camlib.py:3839 +#: camlib.py:4306 msgid "Finished SolderPste G-Code generation" msgstr "" -#: camlib.py:3841 +#: camlib.py:4306 msgid "paths traced." msgstr "" -#: camlib.py:4097 +#: camlib.py:4566 msgid "Parsing GCode file. Number of lines" msgstr "" -#: camlib.py:4204 +#: camlib.py:4673 msgid "Creating Geometry from the parsed GCode file. " msgstr "" -#: camlib.py:4345 camlib.py:4629 camlib.py:4732 camlib.py:4801 +#: camlib.py:4816 camlib.py:5101 camlib.py:5204 camlib.py:5360 msgid "G91 coordinates not implemented ..." msgstr "" -#: camlib.py:4476 +#: camlib.py:4948 msgid "Unifying Geometry from parsed Geometry segments" msgstr "" @@ -2656,9 +2978,9 @@ msgid "To add an Drill Array first select a tool in Tool Table" msgstr "" #: flatcamEditors/FlatCAMExcEditor.py:193 flatcamEditors/FlatCAMExcEditor.py:416 -#: flatcamEditors/FlatCAMExcEditor.py:637 flatcamEditors/FlatCAMExcEditor.py:1155 -#: flatcamEditors/FlatCAMExcEditor.py:1182 flatcamEditors/FlatCAMGrbEditor.py:471 -#: flatcamEditors/FlatCAMGrbEditor.py:1936 flatcamEditors/FlatCAMGrbEditor.py:1966 +#: flatcamEditors/FlatCAMExcEditor.py:637 flatcamEditors/FlatCAMExcEditor.py:1152 +#: flatcamEditors/FlatCAMExcEditor.py:1179 flatcamEditors/FlatCAMGrbEditor.py:471 +#: flatcamEditors/FlatCAMGrbEditor.py:1935 flatcamEditors/FlatCAMGrbEditor.py:1965 msgid "Click on target location ..." msgstr "" @@ -2688,7 +3010,7 @@ msgid "To add a slot first select a tool" msgstr "" #: flatcamEditors/FlatCAMExcEditor.py:455 flatcamEditors/FlatCAMExcEditor.py:462 -#: flatcamEditors/FlatCAMExcEditor.py:744 flatcamEditors/FlatCAMExcEditor.py:751 +#: flatcamEditors/FlatCAMExcEditor.py:743 flatcamEditors/FlatCAMExcEditor.py:750 msgid "Value is missing or wrong format. Add it and retry." msgstr "" @@ -2704,176 +3026,176 @@ msgstr "" msgid "Click on the Slot Circular Array Start position" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:682 flatcamEditors/FlatCAMGrbEditor.py:520 +#: flatcamEditors/FlatCAMExcEditor.py:681 flatcamEditors/FlatCAMGrbEditor.py:519 msgid "The value is mistyped. Check the value." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:861 +#: flatcamEditors/FlatCAMExcEditor.py:860 msgid "Too many Slots for the selected spacing angle." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:884 +#: flatcamEditors/FlatCAMExcEditor.py:883 msgid "Done. Slot Array added." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:906 +#: flatcamEditors/FlatCAMExcEditor.py:905 msgid "Click on the Drill(s) to resize ..." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:936 +#: flatcamEditors/FlatCAMExcEditor.py:935 msgid "Resize drill(s) failed. Please enter a diameter for resize." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1026 flatcamEditors/FlatCAMExcEditor.py:1095 -#: flatcamGUI/FlatCAMGUI.py:3165 flatcamGUI/FlatCAMGUI.py:3377 flatcamGUI/FlatCAMGUI.py:3591 -msgid "Cancelled." -msgstr "" - -#: flatcamEditors/FlatCAMExcEditor.py:1116 +#: flatcamEditors/FlatCAMExcEditor.py:1113 msgid "Done. Drill/Slot Resize completed." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1119 +#: flatcamEditors/FlatCAMExcEditor.py:1116 msgid "Cancelled. No drills/slots selected for resize ..." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1157 flatcamEditors/FlatCAMGrbEditor.py:1938 +#: flatcamEditors/FlatCAMExcEditor.py:1154 flatcamEditors/FlatCAMGrbEditor.py:1937 msgid "Click on reference location ..." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1214 +#: flatcamEditors/FlatCAMExcEditor.py:1211 msgid "Done. Drill(s) Move completed." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1322 +#: flatcamEditors/FlatCAMExcEditor.py:1319 msgid "Done. Drill(s) copied." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1555 flatcamGUI/PreferencesUI.py:3551 +#: flatcamEditors/FlatCAMExcEditor.py:1558 flatcamGUI/PreferencesUI.py:3829 msgid "Excellon Editor" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1562 flatcamEditors/FlatCAMGrbEditor.py:2454 +#: flatcamEditors/FlatCAMExcEditor.py:1565 flatcamEditors/FlatCAMGrbEditor.py:2460 msgid "Name:" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1568 flatcamGUI/ObjectUI.py:757 -#: flatcamGUI/ObjectUI.py:1184 flatcamTools/ToolNonCopperClear.py:109 -#: flatcamTools/ToolPaint.py:112 flatcamTools/ToolSolderPaste.py:73 +#: flatcamEditors/FlatCAMExcEditor.py:1571 flatcamGUI/ObjectUI.py:760 +#: flatcamGUI/ObjectUI.py:1463 flatcamTools/ToolNCC.py:120 flatcamTools/ToolPaint.py:115 +#: flatcamTools/ToolSolderPaste.py:75 msgid "Tools Table" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1570 flatcamGUI/ObjectUI.py:759 +#: flatcamEditors/FlatCAMExcEditor.py:1573 flatcamGUI/ObjectUI.py:762 msgid "" "Tools in this Excellon object\n" "when are used for drilling." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1590 +#: flatcamEditors/FlatCAMExcEditor.py:1593 msgid "Add/Delete Tool" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1592 +#: flatcamEditors/FlatCAMExcEditor.py:1595 msgid "" "Add/Delete a tool to the tool list\n" "for this Excellon object." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1604 flatcamGUI/ObjectUI.py:1297 -#: flatcamGUI/PreferencesUI.py:3582 +#: flatcamEditors/FlatCAMExcEditor.py:1607 flatcamGUI/ObjectUI.py:1583 +#: flatcamGUI/PreferencesUI.py:3860 msgid "Diameter for the new tool" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1614 +#: flatcamEditors/FlatCAMExcEditor.py:1617 msgid "Add Tool" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1616 +#: flatcamEditors/FlatCAMExcEditor.py:1619 msgid "" "Add a new tool to the tool list\n" "with the diameter specified above." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1628 +#: flatcamEditors/FlatCAMExcEditor.py:1631 msgid "Delete Tool" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1630 +#: flatcamEditors/FlatCAMExcEditor.py:1633 msgid "" "Delete a tool in the tool list\n" "by selecting a row in the tool table." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1648 flatcamGUI/FlatCAMGUI.py:1896 +#: flatcamEditors/FlatCAMExcEditor.py:1651 flatcamGUI/FlatCAMGUI.py:2004 msgid "Resize Drill(s)" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1650 +#: flatcamEditors/FlatCAMExcEditor.py:1653 msgid "Resize a drill or a selection of drills." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1657 +#: flatcamEditors/FlatCAMExcEditor.py:1660 msgid "Resize Dia" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1659 +#: flatcamEditors/FlatCAMExcEditor.py:1662 msgid "Diameter to resize to." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1670 +#: flatcamEditors/FlatCAMExcEditor.py:1673 msgid "Resize" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1672 +#: flatcamEditors/FlatCAMExcEditor.py:1675 msgid "Resize drill(s)" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1697 flatcamGUI/FlatCAMGUI.py:1895 -#: flatcamGUI/FlatCAMGUI.py:2147 +#: flatcamEditors/FlatCAMExcEditor.py:1700 flatcamGUI/FlatCAMGUI.py:2003 +#: flatcamGUI/FlatCAMGUI.py:2255 msgid "Add Drill Array" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1699 +#: flatcamEditors/FlatCAMExcEditor.py:1702 msgid "Add an array of drills (linear or circular array)" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1705 +#: flatcamEditors/FlatCAMExcEditor.py:1708 msgid "" "Select the type of drills array to create.\n" "It can be Linear X(Y) or Circular" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1708 flatcamEditors/FlatCAMExcEditor.py:1922 -#: flatcamEditors/FlatCAMGrbEditor.py:2766 +#: flatcamEditors/FlatCAMExcEditor.py:1711 flatcamEditors/FlatCAMExcEditor.py:1925 +#: flatcamEditors/FlatCAMGrbEditor.py:2772 msgid "Linear" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1709 flatcamEditors/FlatCAMExcEditor.py:1923 -#: flatcamEditors/FlatCAMGrbEditor.py:2767 flatcamGUI/ObjectUI.py:311 -#: flatcamGUI/PreferencesUI.py:5044 flatcamGUI/PreferencesUI.py:7465 -#: flatcamTools/ToolFiducials.py:220 flatcamTools/ToolNonCopperClear.py:221 +#: flatcamEditors/FlatCAMExcEditor.py:1712 flatcamEditors/FlatCAMExcEditor.py:1926 +#: flatcamEditors/FlatCAMGrbEditor.py:2773 flatcamGUI/ObjectUI.py:315 +#: flatcamGUI/PreferencesUI.py:5340 flatcamGUI/PreferencesUI.py:5909 +#: flatcamGUI/PreferencesUI.py:7971 flatcamGUI/PreferencesUI.py:8151 +#: flatcamGUI/PreferencesUI.py:8248 flatcamGUI/PreferencesUI.py:8363 +#: flatcamGUI/PreferencesUI.py:8462 flatcamTools/ToolExtractDrills.py:78 +#: flatcamTools/ToolExtractDrills.py:201 flatcamTools/ToolFiducials.py:220 +#: flatcamTools/ToolNCC.py:221 flatcamTools/ToolPaint.py:204 +#: flatcamTools/ToolPunchGerber.py:89 flatcamTools/ToolPunchGerber.py:229 msgid "Circular" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1717 flatcamGUI/PreferencesUI.py:3593 +#: flatcamEditors/FlatCAMExcEditor.py:1720 flatcamGUI/PreferencesUI.py:3871 msgid "Nr of drills" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1718 flatcamGUI/PreferencesUI.py:3595 +#: flatcamEditors/FlatCAMExcEditor.py:1721 flatcamGUI/PreferencesUI.py:3873 msgid "Specify how many drills to be in the array." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1736 flatcamEditors/FlatCAMExcEditor.py:1786 -#: flatcamEditors/FlatCAMExcEditor.py:1858 flatcamEditors/FlatCAMExcEditor.py:1951 -#: flatcamEditors/FlatCAMExcEditor.py:2002 flatcamEditors/FlatCAMGrbEditor.py:1572 -#: flatcamEditors/FlatCAMGrbEditor.py:2795 flatcamEditors/FlatCAMGrbEditor.py:2844 -#: flatcamGUI/PreferencesUI.py:3703 +#: flatcamEditors/FlatCAMExcEditor.py:1739 flatcamEditors/FlatCAMExcEditor.py:1789 +#: flatcamEditors/FlatCAMExcEditor.py:1861 flatcamEditors/FlatCAMExcEditor.py:1954 +#: flatcamEditors/FlatCAMExcEditor.py:2005 flatcamEditors/FlatCAMGrbEditor.py:1571 +#: flatcamEditors/FlatCAMGrbEditor.py:2801 flatcamEditors/FlatCAMGrbEditor.py:2850 +#: flatcamGUI/PreferencesUI.py:3981 msgid "Direction" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1738 flatcamEditors/FlatCAMExcEditor.py:1953 -#: flatcamEditors/FlatCAMGrbEditor.py:2797 flatcamGUI/PreferencesUI.py:2536 -#: flatcamGUI/PreferencesUI.py:3611 flatcamGUI/PreferencesUI.py:3759 +#: flatcamEditors/FlatCAMExcEditor.py:1741 flatcamEditors/FlatCAMExcEditor.py:1956 +#: flatcamEditors/FlatCAMGrbEditor.py:2803 flatcamGUI/PreferencesUI.py:2718 +#: flatcamGUI/PreferencesUI.py:3889 flatcamGUI/PreferencesUI.py:4037 msgid "" "Direction on which the linear array is oriented:\n" "- 'X' - horizontal axis \n" @@ -2881,50 +3203,50 @@ msgid "" "- 'Angle' - a custom angle for the array inclination" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1745 flatcamEditors/FlatCAMExcEditor.py:1867 -#: flatcamEditors/FlatCAMExcEditor.py:1960 flatcamEditors/FlatCAMGrbEditor.py:2804 -#: flatcamGUI/PreferencesUI.py:2542 flatcamGUI/PreferencesUI.py:3617 -#: flatcamGUI/PreferencesUI.py:3712 flatcamGUI/PreferencesUI.py:3765 -#: flatcamGUI/PreferencesUI.py:5853 flatcamTools/ToolFilm.py:256 +#: flatcamEditors/FlatCAMExcEditor.py:1748 flatcamEditors/FlatCAMExcEditor.py:1870 +#: flatcamEditors/FlatCAMExcEditor.py:1963 flatcamEditors/FlatCAMGrbEditor.py:2810 +#: flatcamGUI/PreferencesUI.py:2724 flatcamGUI/PreferencesUI.py:3895 +#: flatcamGUI/PreferencesUI.py:3990 flatcamGUI/PreferencesUI.py:4043 +#: flatcamGUI/PreferencesUI.py:6341 flatcamTools/ToolFilm.py:256 msgid "X" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1746 flatcamEditors/FlatCAMExcEditor.py:1868 -#: flatcamEditors/FlatCAMExcEditor.py:1961 flatcamEditors/FlatCAMGrbEditor.py:2805 -#: flatcamGUI/PreferencesUI.py:2543 flatcamGUI/PreferencesUI.py:3618 -#: flatcamGUI/PreferencesUI.py:3713 flatcamGUI/PreferencesUI.py:3766 -#: flatcamGUI/PreferencesUI.py:5854 flatcamTools/ToolFilm.py:257 +#: flatcamEditors/FlatCAMExcEditor.py:1749 flatcamEditors/FlatCAMExcEditor.py:1871 +#: flatcamEditors/FlatCAMExcEditor.py:1964 flatcamEditors/FlatCAMGrbEditor.py:2811 +#: flatcamGUI/PreferencesUI.py:2725 flatcamGUI/PreferencesUI.py:3896 +#: flatcamGUI/PreferencesUI.py:3991 flatcamGUI/PreferencesUI.py:4044 +#: flatcamGUI/PreferencesUI.py:6342 flatcamTools/ToolFilm.py:257 msgid "Y" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1747 flatcamEditors/FlatCAMExcEditor.py:1764 -#: flatcamEditors/FlatCAMExcEditor.py:1798 flatcamEditors/FlatCAMExcEditor.py:1869 -#: flatcamEditors/FlatCAMExcEditor.py:1873 flatcamEditors/FlatCAMExcEditor.py:1962 -#: flatcamEditors/FlatCAMExcEditor.py:1980 flatcamEditors/FlatCAMExcEditor.py:2014 -#: flatcamEditors/FlatCAMGrbEditor.py:2806 flatcamEditors/FlatCAMGrbEditor.py:2823 -#: flatcamEditors/FlatCAMGrbEditor.py:2859 flatcamGUI/PreferencesUI.py:2544 -#: flatcamGUI/PreferencesUI.py:2562 flatcamGUI/PreferencesUI.py:3619 -#: flatcamGUI/PreferencesUI.py:3638 flatcamGUI/PreferencesUI.py:3714 -#: flatcamGUI/PreferencesUI.py:3719 flatcamGUI/PreferencesUI.py:3767 -#: flatcamGUI/PreferencesUI.py:3788 flatcamGUI/PreferencesUI.py:6246 -#: flatcamTools/ToolDistance.py:66 flatcamTools/ToolDistanceMin.py:68 -#: flatcamTools/ToolTransform.py:63 +#: flatcamEditors/FlatCAMExcEditor.py:1750 flatcamEditors/FlatCAMExcEditor.py:1767 +#: flatcamEditors/FlatCAMExcEditor.py:1801 flatcamEditors/FlatCAMExcEditor.py:1872 +#: flatcamEditors/FlatCAMExcEditor.py:1876 flatcamEditors/FlatCAMExcEditor.py:1965 +#: flatcamEditors/FlatCAMExcEditor.py:1983 flatcamEditors/FlatCAMExcEditor.py:2017 +#: flatcamEditors/FlatCAMGrbEditor.py:2812 flatcamEditors/FlatCAMGrbEditor.py:2829 +#: flatcamEditors/FlatCAMGrbEditor.py:2865 flatcamGUI/PreferencesUI.py:2726 +#: flatcamGUI/PreferencesUI.py:2744 flatcamGUI/PreferencesUI.py:3897 +#: flatcamGUI/PreferencesUI.py:3916 flatcamGUI/PreferencesUI.py:3992 +#: flatcamGUI/PreferencesUI.py:3997 flatcamGUI/PreferencesUI.py:4045 +#: flatcamGUI/PreferencesUI.py:4066 flatcamGUI/PreferencesUI.py:6733 +#: flatcamTools/ToolDistance.py:120 flatcamTools/ToolDistanceMin.py:69 +#: flatcamTools/ToolTransform.py:61 msgid "Angle" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1751 flatcamEditors/FlatCAMExcEditor.py:1966 -#: flatcamEditors/FlatCAMGrbEditor.py:2810 flatcamGUI/PreferencesUI.py:2550 -#: flatcamGUI/PreferencesUI.py:3625 flatcamGUI/PreferencesUI.py:3773 +#: flatcamEditors/FlatCAMExcEditor.py:1754 flatcamEditors/FlatCAMExcEditor.py:1969 +#: flatcamEditors/FlatCAMGrbEditor.py:2816 flatcamGUI/PreferencesUI.py:2732 +#: flatcamGUI/PreferencesUI.py:3903 flatcamGUI/PreferencesUI.py:4051 msgid "Pitch" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1753 flatcamEditors/FlatCAMExcEditor.py:1968 -#: flatcamEditors/FlatCAMGrbEditor.py:2812 flatcamGUI/PreferencesUI.py:2552 -#: flatcamGUI/PreferencesUI.py:3627 flatcamGUI/PreferencesUI.py:3775 +#: flatcamEditors/FlatCAMExcEditor.py:1756 flatcamEditors/FlatCAMExcEditor.py:1971 +#: flatcamEditors/FlatCAMGrbEditor.py:2818 flatcamGUI/PreferencesUI.py:2734 +#: flatcamGUI/PreferencesUI.py:3905 flatcamGUI/PreferencesUI.py:4053 msgid "Pitch = Distance between elements of the array." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1766 flatcamEditors/FlatCAMExcEditor.py:1982 +#: flatcamEditors/FlatCAMExcEditor.py:1769 flatcamEditors/FlatCAMExcEditor.py:1985 msgid "" "Angle at which the linear array is placed.\n" "The precision is of max 2 decimals.\n" @@ -2932,53 +3254,53 @@ msgid "" "Max value is: 360.00 degrees." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1787 flatcamEditors/FlatCAMExcEditor.py:2003 -#: flatcamEditors/FlatCAMGrbEditor.py:2846 +#: flatcamEditors/FlatCAMExcEditor.py:1790 flatcamEditors/FlatCAMExcEditor.py:2006 +#: flatcamEditors/FlatCAMGrbEditor.py:2852 msgid "Direction for circular array.Can be CW = clockwise or CCW = counter clockwise." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1794 flatcamEditors/FlatCAMExcEditor.py:2010 -#: flatcamEditors/FlatCAMGrbEditor.py:2854 flatcamGUI/PreferencesUI.py:2584 -#: flatcamGUI/PreferencesUI.py:3368 flatcamGUI/PreferencesUI.py:3661 -#: flatcamGUI/PreferencesUI.py:3811 flatcamGUI/PreferencesUI.py:4288 +#: flatcamEditors/FlatCAMExcEditor.py:1797 flatcamEditors/FlatCAMExcEditor.py:2013 +#: flatcamEditors/FlatCAMGrbEditor.py:2860 flatcamGUI/PreferencesUI.py:2766 +#: flatcamGUI/PreferencesUI.py:3646 flatcamGUI/PreferencesUI.py:3939 +#: flatcamGUI/PreferencesUI.py:4089 flatcamGUI/PreferencesUI.py:4581 msgid "CW" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1795 flatcamEditors/FlatCAMExcEditor.py:2011 -#: flatcamEditors/FlatCAMGrbEditor.py:2855 flatcamGUI/PreferencesUI.py:2585 -#: flatcamGUI/PreferencesUI.py:3369 flatcamGUI/PreferencesUI.py:3662 -#: flatcamGUI/PreferencesUI.py:3812 flatcamGUI/PreferencesUI.py:4289 +#: flatcamEditors/FlatCAMExcEditor.py:1798 flatcamEditors/FlatCAMExcEditor.py:2014 +#: flatcamEditors/FlatCAMGrbEditor.py:2861 flatcamGUI/PreferencesUI.py:2767 +#: flatcamGUI/PreferencesUI.py:3647 flatcamGUI/PreferencesUI.py:3940 +#: flatcamGUI/PreferencesUI.py:4090 flatcamGUI/PreferencesUI.py:4582 msgid "CCW" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1799 flatcamEditors/FlatCAMExcEditor.py:2015 -#: flatcamEditors/FlatCAMGrbEditor.py:2861 flatcamGUI/PreferencesUI.py:2564 -#: flatcamGUI/PreferencesUI.py:2593 flatcamGUI/PreferencesUI.py:3640 -#: flatcamGUI/PreferencesUI.py:3670 flatcamGUI/PreferencesUI.py:3790 -#: flatcamGUI/PreferencesUI.py:3820 +#: flatcamEditors/FlatCAMExcEditor.py:1802 flatcamEditors/FlatCAMExcEditor.py:2018 +#: flatcamEditors/FlatCAMGrbEditor.py:2867 flatcamGUI/PreferencesUI.py:2746 +#: flatcamGUI/PreferencesUI.py:2775 flatcamGUI/PreferencesUI.py:3918 +#: flatcamGUI/PreferencesUI.py:3948 flatcamGUI/PreferencesUI.py:4068 +#: flatcamGUI/PreferencesUI.py:4098 msgid "Angle at which each element in circular array is placed." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1833 +#: flatcamEditors/FlatCAMExcEditor.py:1836 msgid "Slot Parameters" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1835 +#: flatcamEditors/FlatCAMExcEditor.py:1838 msgid "" "Parameters for adding a slot (hole with oval shape)\n" "either single or as an part of an array." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1844 flatcamGUI/PreferencesUI.py:3687 -#: flatcamTools/ToolProperties.py:555 +#: flatcamEditors/FlatCAMExcEditor.py:1847 flatcamGUI/PreferencesUI.py:3965 +#: flatcamTools/ToolProperties.py:559 msgid "Length" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1846 flatcamGUI/PreferencesUI.py:3689 +#: flatcamEditors/FlatCAMExcEditor.py:1849 flatcamGUI/PreferencesUI.py:3967 msgid "Length = The length of the slot." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1860 flatcamGUI/PreferencesUI.py:3705 +#: flatcamEditors/FlatCAMExcEditor.py:1863 flatcamGUI/PreferencesUI.py:3983 msgid "" "Direction on which the slot is oriented:\n" "- 'X' - horizontal axis \n" @@ -2986,7 +3308,7 @@ msgid "" "- 'Angle' - a custom angle for the slot inclination" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1875 +#: flatcamEditors/FlatCAMExcEditor.py:1878 msgid "" "Angle at which the slot is placed.\n" "The precision is of max 2 decimals.\n" @@ -2994,76 +3316,76 @@ msgid "" "Max value is: 360.00 degrees." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1908 +#: flatcamEditors/FlatCAMExcEditor.py:1911 msgid "Slot Array Parameters" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1910 +#: flatcamEditors/FlatCAMExcEditor.py:1913 msgid "Parameters for the array of slots (linear or circular array)" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1919 +#: flatcamEditors/FlatCAMExcEditor.py:1922 msgid "" "Select the type of slot array to create.\n" "It can be Linear X(Y) or Circular" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1931 flatcamGUI/PreferencesUI.py:3744 +#: flatcamEditors/FlatCAMExcEditor.py:1934 flatcamGUI/PreferencesUI.py:4022 msgid "Nr of slots" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:1932 flatcamGUI/PreferencesUI.py:3746 +#: flatcamEditors/FlatCAMExcEditor.py:1935 flatcamGUI/PreferencesUI.py:4024 msgid "Specify how many slots to be in the array." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:2546 +#: flatcamEditors/FlatCAMExcEditor.py:2571 msgid "" "Tool already in the original or actual tool list.\n" "Save and reedit Excellon if you need to add this tool. " msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:2555 flatcamGUI/FlatCAMGUI.py:3792 +#: flatcamEditors/FlatCAMExcEditor.py:2580 flatcamGUI/FlatCAMGUI.py:4009 msgid "Added new tool with dia" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:2589 +#: flatcamEditors/FlatCAMExcEditor.py:2613 msgid "Select a tool in Tool Table" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:2622 +#: flatcamEditors/FlatCAMExcEditor.py:2643 msgid "Deleted tool with diameter" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:2772 +#: flatcamEditors/FlatCAMExcEditor.py:2793 msgid "Done. Tool edit completed." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:3324 +#: flatcamEditors/FlatCAMExcEditor.py:3350 msgid "There are no Tools definitions in the file. Aborting Excellon creation." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:3328 +#: flatcamEditors/FlatCAMExcEditor.py:3354 msgid "An internal error has ocurred. See Shell.\n" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:3333 +#: flatcamEditors/FlatCAMExcEditor.py:3359 msgid "Creating Excellon." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:3347 +#: flatcamEditors/FlatCAMExcEditor.py:3371 msgid "Excellon editing finished." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:3365 +#: flatcamEditors/FlatCAMExcEditor.py:3388 msgid "Cancelled. There is no Tool/Drill selected" msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:3978 +#: flatcamEditors/FlatCAMExcEditor.py:4001 msgid "Done. Drill(s) deleted." msgstr "" -#: flatcamEditors/FlatCAMExcEditor.py:4051 flatcamEditors/FlatCAMExcEditor.py:4061 -#: flatcamEditors/FlatCAMGrbEditor.py:4853 +#: flatcamEditors/FlatCAMExcEditor.py:4074 flatcamEditors/FlatCAMExcEditor.py:4084 +#: flatcamEditors/FlatCAMGrbEditor.py:4897 msgid "Click on the circular array Center position" msgstr "" @@ -3084,16 +3406,22 @@ msgid "" "corner" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:95 flatcamEditors/FlatCAMGrbEditor.py:2622 +#: flatcamEditors/FlatCAMGeoEditor.py:95 flatcamEditors/FlatCAMGrbEditor.py:2628 msgid "Round" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:96 flatcamEditors/FlatCAMGrbEditor.py:2623 -#: flatcamGUI/PreferencesUI.py:7058 flatcamTools/ToolQRCode.py:198 +#: flatcamEditors/FlatCAMGeoEditor.py:96 flatcamEditors/FlatCAMGrbEditor.py:2629 +#: flatcamGUI/PreferencesUI.py:5606 flatcamGUI/PreferencesUI.py:6130 +#: flatcamGUI/PreferencesUI.py:7564 flatcamGUI/PreferencesUI.py:8167 +#: flatcamGUI/PreferencesUI.py:8274 flatcamGUI/PreferencesUI.py:8379 +#: flatcamGUI/PreferencesUI.py:8488 flatcamTools/ToolExtractDrills.py:94 +#: flatcamTools/ToolExtractDrills.py:227 flatcamTools/ToolNCC.py:583 +#: flatcamTools/ToolPaint.py:527 flatcamTools/ToolPunchGerber.py:105 +#: flatcamTools/ToolPunchGerber.py:255 flatcamTools/ToolQRCode.py:198 msgid "Square" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:97 flatcamEditors/FlatCAMGrbEditor.py:2624 +#: flatcamEditors/FlatCAMGeoEditor.py:97 flatcamEditors/FlatCAMGrbEditor.py:2630 msgid "Beveled" msgstr "" @@ -3109,15 +3437,15 @@ msgstr "" msgid "Full Buffer" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:133 flatcamEditors/FlatCAMGeoEditor.py:2885 -#: flatcamGUI/FlatCAMGUI.py:1805 flatcamGUI/PreferencesUI.py:2604 +#: flatcamEditors/FlatCAMGeoEditor.py:133 flatcamEditors/FlatCAMGeoEditor.py:3018 +#: flatcamGUI/FlatCAMGUI.py:1913 flatcamGUI/PreferencesUI.py:2786 msgid "Buffer Tool" msgstr "" #: flatcamEditors/FlatCAMGeoEditor.py:145 flatcamEditors/FlatCAMGeoEditor.py:162 -#: flatcamEditors/FlatCAMGeoEditor.py:179 flatcamEditors/FlatCAMGeoEditor.py:2904 -#: flatcamEditors/FlatCAMGeoEditor.py:2934 flatcamEditors/FlatCAMGeoEditor.py:2964 -#: flatcamEditors/FlatCAMGrbEditor.py:4906 +#: flatcamEditors/FlatCAMGeoEditor.py:179 flatcamEditors/FlatCAMGeoEditor.py:3037 +#: flatcamEditors/FlatCAMGeoEditor.py:3065 flatcamEditors/FlatCAMGeoEditor.py:3093 +#: flatcamEditors/FlatCAMGrbEditor.py:4950 msgid "Buffer distance value is missing or wrong format. Add it and retry." msgstr "" @@ -3125,7 +3453,7 @@ msgstr "" msgid "Font" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:324 flatcamGUI/FlatCAMGUI.py:2085 +#: flatcamEditors/FlatCAMGeoEditor.py:324 flatcamGUI/FlatCAMGUI.py:2193 msgid "Text" msgstr "" @@ -3133,180 +3461,98 @@ msgstr "" msgid "Text Tool" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:442 flatcamGUI/ObjectUI.py:359 -#: flatcamGUI/PreferencesUI.py:2025 flatcamGUI/PreferencesUI.py:3875 -#: flatcamGUI/PreferencesUI.py:5535 +#: flatcamEditors/FlatCAMGeoEditor.py:440 flatcamGUI/ObjectUI.py:363 +#: flatcamGUI/PreferencesUI.py:2205 msgid "Tool dia" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:444 flatcamGUI/PreferencesUI.py:5537 +#: flatcamEditors/FlatCAMGeoEditor.py:442 +msgid "Diameter of the tool to be used in the operation." +msgstr "" + +#: flatcamEditors/FlatCAMGeoEditor.py:488 msgid "" -"Diameter of the tool to\n" -"be used in the operation." +"Algorithm to paint the polygons:\n" +"- Standard: Fixed step inwards.\n" +"- Seed-based: Outwards from seed.\n" +"- Line-based: Parallel lines." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:455 flatcamGUI/PreferencesUI.py:5152 -#: flatcamGUI/PreferencesUI.py:5567 flatcamTools/ToolNonCopperClear.py:319 -#: flatcamTools/ToolPaint.py:219 -msgid "Overlap Rate" -msgstr "" - -#: flatcamEditors/FlatCAMGeoEditor.py:457 flatcamGUI/PreferencesUI.py:5569 -#: flatcamTools/ToolPaint.py:221 -msgid "" -"How much (fraction) of the tool width to overlap each tool pass.\n" -"Adjust the value starting with lower values\n" -"and increasing it if areas that should be painted are still \n" -"not painted.\n" -"Lower values = faster processing, faster execution on CNC.\n" -"Higher values = slow processing and slow execution on CNC\n" -"due of too many paths." -msgstr "" - -#: flatcamEditors/FlatCAMGeoEditor.py:475 flatcamGUI/PreferencesUI.py:5171 -#: flatcamGUI/PreferencesUI.py:5384 flatcamGUI/PreferencesUI.py:5587 -#: flatcamGUI/PreferencesUI.py:7175 flatcamGUI/PreferencesUI.py:7332 -#: flatcamGUI/PreferencesUI.py:7417 flatcamTools/ToolCopperThieving.py:111 -#: flatcamTools/ToolCopperThieving.py:361 flatcamTools/ToolCutOut.py:184 -#: flatcamTools/ToolFiducials.py:172 flatcamTools/ToolNonCopperClear.py:337 -#: flatcamTools/ToolPaint.py:238 -msgid "Margin" -msgstr "" - -#: flatcamEditors/FlatCAMGeoEditor.py:477 flatcamGUI/PreferencesUI.py:5589 -#: flatcamTools/ToolPaint.py:240 -msgid "" -"Distance by which to avoid\n" -"the edges of the polygon to\n" -"be painted." -msgstr "" - -#: flatcamEditors/FlatCAMGeoEditor.py:489 flatcamGUI/PreferencesUI.py:5184 -#: flatcamGUI/PreferencesUI.py:5602 flatcamTools/ToolNonCopperClear.py:348 -#: flatcamTools/ToolPaint.py:251 -msgid "Method" -msgstr "" - -#: flatcamEditors/FlatCAMGeoEditor.py:491 -msgid "" -"Algorithm to paint the polygon:
Standard: Fixed step inwards.
Seed-based: Outwards from seed." -msgstr "" - -#: flatcamEditors/FlatCAMGeoEditor.py:496 flatcamGUI/PreferencesUI.py:5193 -#: flatcamGUI/PreferencesUI.py:5611 flatcamTools/ToolNonCopperClear.py:357 -#: flatcamTools/ToolPaint.py:260 -msgid "Standard" -msgstr "" - -#: flatcamEditors/FlatCAMGeoEditor.py:497 flatcamGUI/PreferencesUI.py:5194 -#: flatcamGUI/PreferencesUI.py:5612 flatcamTools/ToolNonCopperClear.py:358 -#: flatcamTools/ToolPaint.py:261 -msgid "Seed-based" -msgstr "" - -#: flatcamEditors/FlatCAMGeoEditor.py:498 flatcamGUI/PreferencesUI.py:5195 -#: flatcamGUI/PreferencesUI.py:5613 flatcamTools/ToolNonCopperClear.py:359 -#: flatcamTools/ToolPaint.py:262 -msgid "Straight lines" -msgstr "" - -#: flatcamEditors/FlatCAMGeoEditor.py:505 +#: flatcamEditors/FlatCAMGeoEditor.py:507 msgid "Connect:" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:507 flatcamGUI/PreferencesUI.py:5204 -#: flatcamGUI/PreferencesUI.py:5620 flatcamTools/ToolNonCopperClear.py:366 -#: flatcamTools/ToolPaint.py:269 -msgid "" -"Draw lines between resulting\n" -"segments to minimize tool lifts." -msgstr "" - -#: flatcamEditors/FlatCAMGeoEditor.py:515 +#: flatcamEditors/FlatCAMGeoEditor.py:517 msgid "Contour:" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:517 flatcamGUI/PreferencesUI.py:5213 -#: flatcamGUI/PreferencesUI.py:5628 flatcamTools/ToolNonCopperClear.py:373 -#: flatcamTools/ToolPaint.py:276 -msgid "" -"Cut around the perimeter of the polygon\n" -"to trim rough edges." -msgstr "" - -#: flatcamEditors/FlatCAMGeoEditor.py:529 flatcamGUI/FlatCAMGUI.py:2089 +#: flatcamEditors/FlatCAMGeoEditor.py:530 flatcamGUI/FlatCAMGUI.py:2197 msgid "Paint" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:547 flatcamGUI/FlatCAMGUI.py:845 -#: flatcamGUI/FlatCAMGUI.py:2423 flatcamGUI/ObjectUI.py:1731 flatcamTools/ToolPaint.py:41 -#: flatcamTools/ToolPaint.py:533 +#: flatcamEditors/FlatCAMGeoEditor.py:548 flatcamGUI/FlatCAMGUI.py:909 +#: flatcamGUI/FlatCAMGUI.py:2588 flatcamGUI/ObjectUI.py:2057 flatcamTools/ToolPaint.py:43 +#: flatcamTools/ToolPaint.py:735 msgid "Paint Tool" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:584 -msgid "Paint cancelled. No shape selected." +#: flatcamEditors/FlatCAMGeoEditor.py:584 flatcamEditors/FlatCAMGeoEditor.py:1056 +#: flatcamEditors/FlatCAMGeoEditor.py:3025 flatcamEditors/FlatCAMGeoEditor.py:3053 +#: flatcamEditors/FlatCAMGeoEditor.py:3081 flatcamEditors/FlatCAMGeoEditor.py:4502 +#: flatcamEditors/FlatCAMGrbEditor.py:5601 +msgid "Cancelled. No shape selected." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:597 flatcamEditors/FlatCAMGeoEditor.py:2910 -#: flatcamEditors/FlatCAMGeoEditor.py:2940 flatcamEditors/FlatCAMGeoEditor.py:2970 -#: flatcamGUI/PreferencesUI.py:3871 flatcamTools/ToolProperties.py:120 -#: flatcamTools/ToolProperties.py:158 +#: flatcamEditors/FlatCAMGeoEditor.py:597 flatcamEditors/FlatCAMGeoEditor.py:3043 +#: flatcamEditors/FlatCAMGeoEditor.py:3071 flatcamEditors/FlatCAMGeoEditor.py:3099 +#: flatcamGUI/PreferencesUI.py:4149 flatcamTools/ToolProperties.py:117 +#: flatcamTools/ToolProperties.py:162 msgid "Tools" msgstr "" #: flatcamEditors/FlatCAMGeoEditor.py:608 flatcamEditors/FlatCAMGeoEditor.py:992 -#: flatcamEditors/FlatCAMGrbEditor.py:5096 flatcamEditors/FlatCAMGrbEditor.py:5493 -#: flatcamGUI/FlatCAMGUI.py:866 flatcamGUI/FlatCAMGUI.py:2441 -#: flatcamTools/ToolTransform.py:422 +#: flatcamEditors/FlatCAMGrbEditor.py:5140 flatcamEditors/FlatCAMGrbEditor.py:5537 +#: flatcamGUI/FlatCAMGUI.py:930 flatcamGUI/FlatCAMGUI.py:2609 +#: flatcamTools/ToolTransform.py:461 msgid "Transform Tool" msgstr "" #: flatcamEditors/FlatCAMGeoEditor.py:609 flatcamEditors/FlatCAMGeoEditor.py:674 -#: flatcamEditors/FlatCAMGrbEditor.py:5097 flatcamEditors/FlatCAMGrbEditor.py:5162 -#: flatcamGUI/PreferencesUI.py:6238 flatcamTools/ToolTransform.py:25 -#: flatcamTools/ToolTransform.py:80 +#: flatcamEditors/FlatCAMGrbEditor.py:5141 flatcamEditors/FlatCAMGrbEditor.py:5206 +#: flatcamGUI/PreferencesUI.py:6725 flatcamTools/ToolTransform.py:25 +#: flatcamTools/ToolTransform.py:467 msgid "Rotate" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:610 flatcamEditors/FlatCAMGrbEditor.py:5098 +#: flatcamEditors/FlatCAMGeoEditor.py:610 flatcamEditors/FlatCAMGrbEditor.py:5142 #: flatcamTools/ToolTransform.py:26 msgid "Skew/Shear" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:611 flatcamEditors/FlatCAMGrbEditor.py:2671 -#: flatcamEditors/FlatCAMGrbEditor.py:5099 flatcamGUI/FlatCAMGUI.py:980 -#: flatcamGUI/FlatCAMGUI.py:2017 flatcamGUI/FlatCAMGUI.py:2132 flatcamGUI/FlatCAMGUI.py:2549 -#: flatcamGUI/ObjectUI.py:103 flatcamGUI/ObjectUI.py:121 flatcamGUI/PreferencesUI.py:6288 +#: flatcamEditors/FlatCAMGeoEditor.py:611 flatcamEditors/FlatCAMGrbEditor.py:2677 +#: flatcamEditors/FlatCAMGrbEditor.py:5143 flatcamGUI/FlatCAMGUI.py:1048 +#: flatcamGUI/FlatCAMGUI.py:2125 flatcamGUI/FlatCAMGUI.py:2240 flatcamGUI/FlatCAMGUI.py:2723 +#: flatcamGUI/ObjectUI.py:124 flatcamGUI/PreferencesUI.py:6775 #: flatcamTools/ToolTransform.py:27 msgid "Scale" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:612 flatcamEditors/FlatCAMGrbEditor.py:5100 +#: flatcamEditors/FlatCAMGeoEditor.py:612 flatcamEditors/FlatCAMGrbEditor.py:5144 #: flatcamTools/ToolTransform.py:28 msgid "Mirror (Flip)" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:613 flatcamEditors/FlatCAMGrbEditor.py:5101 -#: flatcamGUI/ObjectUI.py:132 flatcamGUI/ObjectUI.py:148 flatcamGUI/ObjectUI.py:1217 -#: flatcamGUI/ObjectUI.py:1916 flatcamGUI/PreferencesUI.py:5234 -#: flatcamGUI/PreferencesUI.py:6335 flatcamTools/ToolNonCopperClear.py:393 -#: flatcamTools/ToolTransform.py:29 -msgid "Offset" -msgstr "" - -#: flatcamEditors/FlatCAMGeoEditor.py:626 flatcamEditors/FlatCAMGrbEditor.py:5114 -#: flatcamGUI/FlatCAMGUI.py:787 flatcamGUI/FlatCAMGUI.py:2370 +#: flatcamEditors/FlatCAMGeoEditor.py:626 flatcamEditors/FlatCAMGrbEditor.py:5158 +#: flatcamGUI/FlatCAMGUI.py:841 flatcamGUI/FlatCAMGUI.py:2524 msgid "Editor" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:658 flatcamEditors/FlatCAMGrbEditor.py:5146 +#: flatcamEditors/FlatCAMGeoEditor.py:658 flatcamEditors/FlatCAMGrbEditor.py:5190 msgid "Angle:" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:660 flatcamEditors/FlatCAMGrbEditor.py:5148 -#: flatcamGUI/PreferencesUI.py:6248 flatcamTools/ToolTransform.py:65 +#: flatcamEditors/FlatCAMGeoEditor.py:660 flatcamEditors/FlatCAMGrbEditor.py:5192 +#: flatcamGUI/PreferencesUI.py:6735 flatcamTools/ToolTransform.py:63 msgid "" "Angle for Rotation action, in degrees.\n" "Float number between -360 and 359.\n" @@ -3314,101 +3560,101 @@ msgid "" "Negative numbers for CCW motion." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:676 flatcamEditors/FlatCAMGrbEditor.py:5164 +#: flatcamEditors/FlatCAMGeoEditor.py:676 flatcamEditors/FlatCAMGrbEditor.py:5208 msgid "" "Rotate the selected shape(s).\n" "The point of reference is the middle of\n" "the bounding box for all selected shapes." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:699 flatcamEditors/FlatCAMGrbEditor.py:5187 +#: flatcamEditors/FlatCAMGeoEditor.py:699 flatcamEditors/FlatCAMGrbEditor.py:5231 msgid "Angle X:" msgstr "" #: flatcamEditors/FlatCAMGeoEditor.py:701 flatcamEditors/FlatCAMGeoEditor.py:721 -#: flatcamEditors/FlatCAMGrbEditor.py:5189 flatcamEditors/FlatCAMGrbEditor.py:5209 -#: flatcamGUI/PreferencesUI.py:6267 flatcamGUI/PreferencesUI.py:6281 -#: flatcamTools/ToolCalibration.py:508 flatcamTools/ToolCalibration.py:521 +#: flatcamEditors/FlatCAMGrbEditor.py:5233 flatcamEditors/FlatCAMGrbEditor.py:5253 +#: flatcamGUI/PreferencesUI.py:6754 flatcamGUI/PreferencesUI.py:6768 +#: flatcamTools/ToolCalibration.py:505 flatcamTools/ToolCalibration.py:518 msgid "" "Angle for Skew action, in degrees.\n" "Float number between -360 and 359." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:712 flatcamEditors/FlatCAMGrbEditor.py:5200 -#: flatcamTools/ToolTransform.py:109 +#: flatcamEditors/FlatCAMGeoEditor.py:712 flatcamEditors/FlatCAMGrbEditor.py:5244 +#: flatcamTools/ToolTransform.py:468 msgid "Skew X" msgstr "" #: flatcamEditors/FlatCAMGeoEditor.py:714 flatcamEditors/FlatCAMGeoEditor.py:734 -#: flatcamEditors/FlatCAMGrbEditor.py:5202 flatcamEditors/FlatCAMGrbEditor.py:5222 +#: flatcamEditors/FlatCAMGrbEditor.py:5246 flatcamEditors/FlatCAMGrbEditor.py:5266 msgid "" "Skew/shear the selected shape(s).\n" "The point of reference is the middle of\n" "the bounding box for all selected shapes." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:719 flatcamEditors/FlatCAMGrbEditor.py:5207 +#: flatcamEditors/FlatCAMGeoEditor.py:719 flatcamEditors/FlatCAMGrbEditor.py:5251 msgid "Angle Y:" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:732 flatcamEditors/FlatCAMGrbEditor.py:5220 -#: flatcamTools/ToolTransform.py:131 +#: flatcamEditors/FlatCAMGeoEditor.py:732 flatcamEditors/FlatCAMGrbEditor.py:5264 +#: flatcamTools/ToolTransform.py:469 msgid "Skew Y" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:760 flatcamEditors/FlatCAMGrbEditor.py:5248 +#: flatcamEditors/FlatCAMGeoEditor.py:760 flatcamEditors/FlatCAMGrbEditor.py:5292 msgid "Factor X:" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:762 flatcamEditors/FlatCAMGrbEditor.py:5250 -#: flatcamTools/ToolCalibration.py:472 +#: flatcamEditors/FlatCAMGeoEditor.py:762 flatcamEditors/FlatCAMGrbEditor.py:5294 +#: flatcamTools/ToolCalibration.py:469 msgid "Factor for Scale action over X axis." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:772 flatcamEditors/FlatCAMGrbEditor.py:5260 -#: flatcamTools/ToolTransform.py:158 +#: flatcamEditors/FlatCAMGeoEditor.py:772 flatcamEditors/FlatCAMGrbEditor.py:5304 +#: flatcamTools/ToolTransform.py:470 msgid "Scale X" msgstr "" #: flatcamEditors/FlatCAMGeoEditor.py:774 flatcamEditors/FlatCAMGeoEditor.py:793 -#: flatcamEditors/FlatCAMGrbEditor.py:5262 flatcamEditors/FlatCAMGrbEditor.py:5281 +#: flatcamEditors/FlatCAMGrbEditor.py:5306 flatcamEditors/FlatCAMGrbEditor.py:5325 msgid "" "Scale the selected shape(s).\n" "The point of reference depends on \n" "the Scale reference checkbox state." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:779 flatcamEditors/FlatCAMGrbEditor.py:5267 +#: flatcamEditors/FlatCAMGeoEditor.py:779 flatcamEditors/FlatCAMGrbEditor.py:5311 msgid "Factor Y:" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:781 flatcamEditors/FlatCAMGrbEditor.py:5269 -#: flatcamTools/ToolCalibration.py:484 +#: flatcamEditors/FlatCAMGeoEditor.py:781 flatcamEditors/FlatCAMGrbEditor.py:5313 +#: flatcamTools/ToolCalibration.py:481 msgid "Factor for Scale action over Y axis." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:791 flatcamEditors/FlatCAMGrbEditor.py:5279 -#: flatcamTools/ToolTransform.py:179 +#: flatcamEditors/FlatCAMGeoEditor.py:791 flatcamEditors/FlatCAMGrbEditor.py:5323 +#: flatcamTools/ToolTransform.py:471 msgid "Scale Y" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:800 flatcamEditors/FlatCAMGrbEditor.py:5288 -#: flatcamGUI/PreferencesUI.py:6317 flatcamTools/ToolTransform.py:192 +#: flatcamEditors/FlatCAMGeoEditor.py:800 flatcamEditors/FlatCAMGrbEditor.py:5332 +#: flatcamGUI/PreferencesUI.py:6804 flatcamTools/ToolTransform.py:190 msgid "Link" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:802 flatcamEditors/FlatCAMGrbEditor.py:5290 +#: flatcamEditors/FlatCAMGeoEditor.py:802 flatcamEditors/FlatCAMGrbEditor.py:5334 msgid "" "Scale the selected shape(s)\n" "using the Scale Factor X for both axis." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:808 flatcamEditors/FlatCAMGrbEditor.py:5296 -#: flatcamGUI/PreferencesUI.py:6325 flatcamTools/ToolTransform.py:200 +#: flatcamEditors/FlatCAMGeoEditor.py:808 flatcamEditors/FlatCAMGrbEditor.py:5340 +#: flatcamGUI/PreferencesUI.py:6812 flatcamTools/ToolTransform.py:197 msgid "Scale Reference" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:810 flatcamEditors/FlatCAMGrbEditor.py:5298 +#: flatcamEditors/FlatCAMGeoEditor.py:810 flatcamEditors/FlatCAMGrbEditor.py:5342 msgid "" "Scale the selected shape(s)\n" "using the origin reference when checked,\n" @@ -3416,62 +3662,62 @@ msgid "" "of the selected shapes when unchecked." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:838 flatcamEditors/FlatCAMGrbEditor.py:5327 +#: flatcamEditors/FlatCAMGeoEditor.py:838 flatcamEditors/FlatCAMGrbEditor.py:5371 msgid "Value X:" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:840 flatcamEditors/FlatCAMGrbEditor.py:5329 +#: flatcamEditors/FlatCAMGeoEditor.py:840 flatcamEditors/FlatCAMGrbEditor.py:5373 msgid "Value for Offset action on X axis." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:850 flatcamEditors/FlatCAMGrbEditor.py:5339 -#: flatcamTools/ToolTransform.py:227 +#: flatcamEditors/FlatCAMGeoEditor.py:850 flatcamEditors/FlatCAMGrbEditor.py:5383 +#: flatcamTools/ToolTransform.py:474 msgid "Offset X" msgstr "" #: flatcamEditors/FlatCAMGeoEditor.py:852 flatcamEditors/FlatCAMGeoEditor.py:872 -#: flatcamEditors/FlatCAMGrbEditor.py:5341 flatcamEditors/FlatCAMGrbEditor.py:5361 +#: flatcamEditors/FlatCAMGrbEditor.py:5385 flatcamEditors/FlatCAMGrbEditor.py:5405 msgid "" "Offset the selected shape(s).\n" "The point of reference is the middle of\n" "the bounding box for all selected shapes.\n" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:858 flatcamEditors/FlatCAMGrbEditor.py:5347 +#: flatcamEditors/FlatCAMGeoEditor.py:858 flatcamEditors/FlatCAMGrbEditor.py:5391 msgid "Value Y:" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:860 flatcamEditors/FlatCAMGrbEditor.py:5349 +#: flatcamEditors/FlatCAMGeoEditor.py:860 flatcamEditors/FlatCAMGrbEditor.py:5393 msgid "Value for Offset action on Y axis." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:870 flatcamEditors/FlatCAMGrbEditor.py:5359 -#: flatcamTools/ToolTransform.py:248 +#: flatcamEditors/FlatCAMGeoEditor.py:870 flatcamEditors/FlatCAMGrbEditor.py:5403 +#: flatcamTools/ToolTransform.py:475 msgid "Offset Y" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:901 flatcamEditors/FlatCAMGrbEditor.py:5390 -#: flatcamTools/ToolTransform.py:266 +#: flatcamEditors/FlatCAMGeoEditor.py:901 flatcamEditors/FlatCAMGrbEditor.py:5434 +#: flatcamTools/ToolTransform.py:476 msgid "Flip on X" msgstr "" #: flatcamEditors/FlatCAMGeoEditor.py:903 flatcamEditors/FlatCAMGeoEditor.py:910 -#: flatcamEditors/FlatCAMGrbEditor.py:5392 flatcamEditors/FlatCAMGrbEditor.py:5399 +#: flatcamEditors/FlatCAMGrbEditor.py:5436 flatcamEditors/FlatCAMGrbEditor.py:5443 msgid "" "Flip the selected shape(s) over the X axis.\n" "Does not create a new shape." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:908 flatcamEditors/FlatCAMGrbEditor.py:5397 -#: flatcamTools/ToolTransform.py:272 +#: flatcamEditors/FlatCAMGeoEditor.py:908 flatcamEditors/FlatCAMGrbEditor.py:5441 +#: flatcamTools/ToolTransform.py:477 msgid "Flip on Y" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:916 flatcamEditors/FlatCAMGrbEditor.py:5405 +#: flatcamEditors/FlatCAMGeoEditor.py:916 flatcamEditors/FlatCAMGrbEditor.py:5449 msgid "Ref Pt" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:918 flatcamEditors/FlatCAMGrbEditor.py:5407 +#: flatcamEditors/FlatCAMGeoEditor.py:918 flatcamEditors/FlatCAMGrbEditor.py:5451 msgid "" "Flip the selected shape(s)\n" "around the point in Point Entry Field.\n" @@ -3484,458 +3730,493 @@ msgid "" "Point Entry field and click Flip on X(Y)" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:930 flatcamEditors/FlatCAMGrbEditor.py:5419 +#: flatcamEditors/FlatCAMGeoEditor.py:930 flatcamEditors/FlatCAMGrbEditor.py:5463 msgid "Point:" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:932 flatcamEditors/FlatCAMGrbEditor.py:5421 -#: flatcamTools/ToolTransform.py:301 +#: flatcamEditors/FlatCAMGeoEditor.py:932 flatcamEditors/FlatCAMGrbEditor.py:5465 +#: flatcamTools/ToolTransform.py:300 msgid "" "Coordinates in format (x, y) used as reference for mirroring.\n" "The 'x' in (x, y) will be used when using Flip on X and\n" "the 'y' in (x, y) will be used when using Flip on Y." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:942 flatcamEditors/FlatCAMGrbEditor.py:5433 -#: flatcamTools/ToolTransform.py:312 +#: flatcamEditors/FlatCAMGeoEditor.py:942 flatcamEditors/FlatCAMGrbEditor.py:5477 +#: flatcamTools/ToolTransform.py:310 msgid "" "The point coordinates can be captured by\n" "left click on canvas together with pressing\n" "SHIFT key. Then click Add button to insert." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1057 flatcamEditors/FlatCAMGrbEditor.py:5558 -msgid "Transformation cancelled. No shape selected." -msgstr "" - -#: flatcamEditors/FlatCAMGeoEditor.py:1258 flatcamEditors/FlatCAMGrbEditor.py:5742 +#: flatcamEditors/FlatCAMGeoEditor.py:1305 flatcamEditors/FlatCAMGrbEditor.py:5785 msgid "No shape selected. Please Select a shape to rotate!" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1261 flatcamEditors/FlatCAMGrbEditor.py:5745 -#: flatcamTools/ToolTransform.py:611 +#: flatcamEditors/FlatCAMGeoEditor.py:1308 flatcamEditors/FlatCAMGrbEditor.py:5788 +#: flatcamTools/ToolTransform.py:680 msgid "Appying Rotate" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1290 flatcamEditors/FlatCAMGrbEditor.py:5779 +#: flatcamEditors/FlatCAMGeoEditor.py:1334 flatcamEditors/FlatCAMGrbEditor.py:5820 msgid "Done. Rotate completed." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1295 +#: flatcamEditors/FlatCAMGeoEditor.py:1336 msgid "Rotation action was not executed" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1307 flatcamEditors/FlatCAMGrbEditor.py:5800 +#: flatcamEditors/FlatCAMGeoEditor.py:1355 flatcamEditors/FlatCAMGrbEditor.py:5839 msgid "No shape selected. Please Select a shape to flip!" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1310 flatcamEditors/FlatCAMGrbEditor.py:5803 -#: flatcamTools/ToolTransform.py:664 +#: flatcamEditors/FlatCAMGeoEditor.py:1358 flatcamEditors/FlatCAMGrbEditor.py:5842 +#: flatcamTools/ToolTransform.py:729 msgid "Applying Flip" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1341 flatcamEditors/FlatCAMGrbEditor.py:5843 -#: flatcamTools/ToolTransform.py:707 +#: flatcamEditors/FlatCAMGeoEditor.py:1387 flatcamEditors/FlatCAMGrbEditor.py:5880 +#: flatcamTools/ToolTransform.py:770 msgid "Flip on the Y axis done" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1345 flatcamEditors/FlatCAMGrbEditor.py:5852 -#: flatcamTools/ToolTransform.py:717 +#: flatcamEditors/FlatCAMGeoEditor.py:1391 flatcamEditors/FlatCAMGrbEditor.py:5889 +#: flatcamTools/ToolTransform.py:779 msgid "Flip on the X axis done" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1355 +#: flatcamEditors/FlatCAMGeoEditor.py:1399 msgid "Flip action was not executed" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1365 flatcamEditors/FlatCAMGrbEditor.py:5874 +#: flatcamEditors/FlatCAMGeoEditor.py:1417 flatcamEditors/FlatCAMGrbEditor.py:5909 msgid "No shape selected. Please Select a shape to shear/skew!" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1368 flatcamEditors/FlatCAMGrbEditor.py:5877 -#: flatcamTools/ToolTransform.py:742 +#: flatcamEditors/FlatCAMGeoEditor.py:1420 flatcamEditors/FlatCAMGrbEditor.py:5912 +#: flatcamTools/ToolTransform.py:802 msgid "Applying Skew" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1394 flatcamEditors/FlatCAMGrbEditor.py:5913 +#: flatcamEditors/FlatCAMGeoEditor.py:1443 flatcamEditors/FlatCAMGrbEditor.py:5946 msgid "Skew on the X axis done" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1397 flatcamEditors/FlatCAMGrbEditor.py:5915 +#: flatcamEditors/FlatCAMGeoEditor.py:1445 flatcamEditors/FlatCAMGrbEditor.py:5948 msgid "Skew on the Y axis done" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1401 +#: flatcamEditors/FlatCAMGeoEditor.py:1448 msgid "Skew action was not executed" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1413 flatcamEditors/FlatCAMGrbEditor.py:5939 +#: flatcamEditors/FlatCAMGeoEditor.py:1470 flatcamEditors/FlatCAMGrbEditor.py:5970 msgid "No shape selected. Please Select a shape to scale!" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1416 flatcamEditors/FlatCAMGrbEditor.py:5942 -#: flatcamTools/ToolTransform.py:794 +#: flatcamEditors/FlatCAMGeoEditor.py:1473 flatcamEditors/FlatCAMGrbEditor.py:5973 +#: flatcamTools/ToolTransform.py:849 msgid "Applying Scale" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1451 flatcamEditors/FlatCAMGrbEditor.py:5981 +#: flatcamEditors/FlatCAMGeoEditor.py:1505 flatcamEditors/FlatCAMGrbEditor.py:6010 msgid "Scale on the X axis done" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1454 flatcamEditors/FlatCAMGrbEditor.py:5983 +#: flatcamEditors/FlatCAMGeoEditor.py:1507 flatcamEditors/FlatCAMGrbEditor.py:6012 msgid "Scale on the Y axis done" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1457 +#: flatcamEditors/FlatCAMGeoEditor.py:1509 msgid "Scale action was not executed" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1467 flatcamEditors/FlatCAMGrbEditor.py:6000 +#: flatcamEditors/FlatCAMGeoEditor.py:1524 flatcamEditors/FlatCAMGrbEditor.py:6029 msgid "No shape selected. Please Select a shape to offset!" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1470 flatcamEditors/FlatCAMGrbEditor.py:6003 -#: flatcamTools/ToolTransform.py:849 +#: flatcamEditors/FlatCAMGeoEditor.py:1527 flatcamEditors/FlatCAMGrbEditor.py:6032 +#: flatcamTools/ToolTransform.py:901 msgid "Applying Offset" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1483 flatcamEditors/FlatCAMGrbEditor.py:6024 +#: flatcamEditors/FlatCAMGeoEditor.py:1537 flatcamEditors/FlatCAMGrbEditor.py:6053 msgid "Offset on the X axis done" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1486 flatcamEditors/FlatCAMGrbEditor.py:6026 +#: flatcamEditors/FlatCAMGeoEditor.py:1539 flatcamEditors/FlatCAMGrbEditor.py:6055 msgid "Offset on the Y axis done" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1490 +#: flatcamEditors/FlatCAMGeoEditor.py:1542 msgid "Offset action was not executed" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1494 flatcamEditors/FlatCAMGrbEditor.py:6033 +#: flatcamEditors/FlatCAMGeoEditor.py:1546 flatcamEditors/FlatCAMGrbEditor.py:6062 msgid "Rotate ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1495 flatcamEditors/FlatCAMGeoEditor.py:1550 -#: flatcamEditors/FlatCAMGeoEditor.py:1567 flatcamEditors/FlatCAMGrbEditor.py:6034 -#: flatcamEditors/FlatCAMGrbEditor.py:6083 flatcamEditors/FlatCAMGrbEditor.py:6098 +#: flatcamEditors/FlatCAMGeoEditor.py:1547 flatcamEditors/FlatCAMGeoEditor.py:1602 +#: flatcamEditors/FlatCAMGeoEditor.py:1619 flatcamEditors/FlatCAMGrbEditor.py:6063 +#: flatcamEditors/FlatCAMGrbEditor.py:6112 flatcamEditors/FlatCAMGrbEditor.py:6127 msgid "Enter an Angle Value (degrees)" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1504 flatcamEditors/FlatCAMGrbEditor.py:6042 +#: flatcamEditors/FlatCAMGeoEditor.py:1556 flatcamEditors/FlatCAMGrbEditor.py:6071 msgid "Geometry shape rotate done" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1508 flatcamEditors/FlatCAMGrbEditor.py:6045 +#: flatcamEditors/FlatCAMGeoEditor.py:1560 flatcamEditors/FlatCAMGrbEditor.py:6074 msgid "Geometry shape rotate cancelled" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1513 flatcamEditors/FlatCAMGrbEditor.py:6050 +#: flatcamEditors/FlatCAMGeoEditor.py:1565 flatcamEditors/FlatCAMGrbEditor.py:6079 msgid "Offset on X axis ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1514 flatcamEditors/FlatCAMGeoEditor.py:1533 -#: flatcamEditors/FlatCAMGrbEditor.py:6051 flatcamEditors/FlatCAMGrbEditor.py:6068 +#: flatcamEditors/FlatCAMGeoEditor.py:1566 flatcamEditors/FlatCAMGeoEditor.py:1585 +#: flatcamEditors/FlatCAMGrbEditor.py:6080 flatcamEditors/FlatCAMGrbEditor.py:6097 msgid "Enter a distance Value" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1523 flatcamEditors/FlatCAMGrbEditor.py:6059 +#: flatcamEditors/FlatCAMGeoEditor.py:1575 flatcamEditors/FlatCAMGrbEditor.py:6088 msgid "Geometry shape offset on X axis done" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1527 flatcamEditors/FlatCAMGrbEditor.py:6062 +#: flatcamEditors/FlatCAMGeoEditor.py:1579 flatcamEditors/FlatCAMGrbEditor.py:6091 msgid "Geometry shape offset X cancelled" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1532 flatcamEditors/FlatCAMGrbEditor.py:6067 +#: flatcamEditors/FlatCAMGeoEditor.py:1584 flatcamEditors/FlatCAMGrbEditor.py:6096 msgid "Offset on Y axis ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1542 flatcamEditors/FlatCAMGrbEditor.py:6076 +#: flatcamEditors/FlatCAMGeoEditor.py:1594 flatcamEditors/FlatCAMGrbEditor.py:6105 msgid "Geometry shape offset on Y axis done" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1546 +#: flatcamEditors/FlatCAMGeoEditor.py:1598 msgid "Geometry shape offset on Y axis canceled" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1549 flatcamEditors/FlatCAMGrbEditor.py:6082 +#: flatcamEditors/FlatCAMGeoEditor.py:1601 flatcamEditors/FlatCAMGrbEditor.py:6111 msgid "Skew on X axis ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1559 flatcamEditors/FlatCAMGrbEditor.py:6091 +#: flatcamEditors/FlatCAMGeoEditor.py:1611 flatcamEditors/FlatCAMGrbEditor.py:6120 msgid "Geometry shape skew on X axis done" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1563 +#: flatcamEditors/FlatCAMGeoEditor.py:1615 msgid "Geometry shape skew on X axis canceled" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1566 flatcamEditors/FlatCAMGrbEditor.py:6097 +#: flatcamEditors/FlatCAMGeoEditor.py:1618 flatcamEditors/FlatCAMGrbEditor.py:6126 msgid "Skew on Y axis ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1576 flatcamEditors/FlatCAMGrbEditor.py:6106 +#: flatcamEditors/FlatCAMGeoEditor.py:1628 flatcamEditors/FlatCAMGrbEditor.py:6135 msgid "Geometry shape skew on Y axis done" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1580 +#: flatcamEditors/FlatCAMGeoEditor.py:1632 msgid "Geometry shape skew on Y axis canceled" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1951 flatcamEditors/FlatCAMGeoEditor.py:2016 -#: flatcamEditors/FlatCAMGrbEditor.py:1436 flatcamEditors/FlatCAMGrbEditor.py:1514 +#: flatcamEditors/FlatCAMGeoEditor.py:2009 flatcamEditors/FlatCAMGeoEditor.py:2080 +#: flatcamEditors/FlatCAMGrbEditor.py:1435 flatcamEditors/FlatCAMGrbEditor.py:1513 msgid "Click on Center point ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1958 flatcamEditors/FlatCAMGrbEditor.py:1446 +#: flatcamEditors/FlatCAMGeoEditor.py:2022 flatcamEditors/FlatCAMGrbEditor.py:1445 msgid "Click on Perimeter point to complete ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:1990 +#: flatcamEditors/FlatCAMGeoEditor.py:2054 msgid "Done. Adding Circle completed." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2038 flatcamEditors/FlatCAMGrbEditor.py:1547 +#: flatcamEditors/FlatCAMGeoEditor.py:2108 flatcamEditors/FlatCAMGrbEditor.py:1546 msgid "Click on Start point ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2040 flatcamEditors/FlatCAMGrbEditor.py:1549 +#: flatcamEditors/FlatCAMGeoEditor.py:2110 flatcamEditors/FlatCAMGrbEditor.py:1548 msgid "Click on Point3 ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2042 flatcamEditors/FlatCAMGrbEditor.py:1551 +#: flatcamEditors/FlatCAMGeoEditor.py:2112 flatcamEditors/FlatCAMGrbEditor.py:1550 msgid "Click on Stop point ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2047 flatcamEditors/FlatCAMGrbEditor.py:1556 +#: flatcamEditors/FlatCAMGeoEditor.py:2117 flatcamEditors/FlatCAMGrbEditor.py:1555 msgid "Click on Stop point to complete ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2049 flatcamEditors/FlatCAMGrbEditor.py:1558 +#: flatcamEditors/FlatCAMGeoEditor.py:2119 flatcamEditors/FlatCAMGrbEditor.py:1557 msgid "Click on Point2 to complete ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2051 flatcamEditors/FlatCAMGrbEditor.py:1560 +#: flatcamEditors/FlatCAMGeoEditor.py:2121 flatcamEditors/FlatCAMGrbEditor.py:1559 msgid "Click on Center point to complete ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2063 +#: flatcamEditors/FlatCAMGeoEditor.py:2133 #, python-format msgid "Direction: %s" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2077 flatcamEditors/FlatCAMGrbEditor.py:1586 +#: flatcamEditors/FlatCAMGeoEditor.py:2147 flatcamEditors/FlatCAMGrbEditor.py:1585 msgid "Mode: Start -> Stop -> Center. Click on Start point ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2080 flatcamEditors/FlatCAMGrbEditor.py:1589 +#: flatcamEditors/FlatCAMGeoEditor.py:2150 flatcamEditors/FlatCAMGrbEditor.py:1588 msgid "Mode: Point1 -> Point3 -> Point2. Click on Point1 ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2083 flatcamEditors/FlatCAMGrbEditor.py:1592 +#: flatcamEditors/FlatCAMGeoEditor.py:2153 flatcamEditors/FlatCAMGrbEditor.py:1591 msgid "Mode: Center -> Start -> Stop. Click on Center point ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2224 +#: flatcamEditors/FlatCAMGeoEditor.py:2294 msgid "Done. Arc completed." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2255 flatcamEditors/FlatCAMGeoEditor.py:2322 +#: flatcamEditors/FlatCAMGeoEditor.py:2325 flatcamEditors/FlatCAMGeoEditor.py:2398 msgid "Click on 1st corner ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2261 +#: flatcamEditors/FlatCAMGeoEditor.py:2337 msgid "Click on opposite corner to complete ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2291 +#: flatcamEditors/FlatCAMGeoEditor.py:2367 msgid "Done. Rectangle completed." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2329 +#: flatcamEditors/FlatCAMGeoEditor.py:2411 flatcamTools/ToolNCC.py:1737 +#: flatcamTools/ToolPaint.py:1616 msgid "Click on next Point or click right mouse button to complete ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2360 +#: flatcamEditors/FlatCAMGeoEditor.py:2442 msgid "Done. Polygon completed." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2374 flatcamEditors/FlatCAMGeoEditor.py:2439 -#: flatcamEditors/FlatCAMGrbEditor.py:1112 flatcamEditors/FlatCAMGrbEditor.py:1323 +#: flatcamEditors/FlatCAMGeoEditor.py:2456 flatcamEditors/FlatCAMGeoEditor.py:2521 +#: flatcamEditors/FlatCAMGrbEditor.py:1111 flatcamEditors/FlatCAMGrbEditor.py:1322 msgid "Backtracked one point ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2417 +#: flatcamEditors/FlatCAMGeoEditor.py:2499 msgid "Done. Path completed." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2580 +#: flatcamEditors/FlatCAMGeoEditor.py:2658 +msgid "No shape selected. Select a shape to explode" +msgstr "" + +#: flatcamEditors/FlatCAMGeoEditor.py:2691 msgid "Done. Polygons exploded into lines." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2612 +#: flatcamEditors/FlatCAMGeoEditor.py:2723 msgid "MOVE: No shape selected. Select a shape to move" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2615 flatcamEditors/FlatCAMGeoEditor.py:2628 +#: flatcamEditors/FlatCAMGeoEditor.py:2726 flatcamEditors/FlatCAMGeoEditor.py:2746 msgid " MOVE: Click on reference point ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2619 +#: flatcamEditors/FlatCAMGeoEditor.py:2731 msgid " Click on destination point ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2653 +#: flatcamEditors/FlatCAMGeoEditor.py:2771 msgid "Done. Geometry(s) Move completed." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2783 +#: flatcamEditors/FlatCAMGeoEditor.py:2904 msgid "Done. Geometry(s) Copy completed." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2811 flatcamEditors/FlatCAMGrbEditor.py:898 +#: flatcamEditors/FlatCAMGeoEditor.py:2935 flatcamEditors/FlatCAMGrbEditor.py:897 msgid "Click on 1st point ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2829 +#: flatcamEditors/FlatCAMGeoEditor.py:2959 msgid "Font not supported. Only Regular, Bold, Italic and BoldItalic are supported. Error" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2837 +#: flatcamEditors/FlatCAMGeoEditor.py:2967 msgid "No text to add." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2844 +#: flatcamEditors/FlatCAMGeoEditor.py:2977 msgid " Done. Adding Text completed." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2881 +#: flatcamEditors/FlatCAMGeoEditor.py:3014 msgid "Create buffer geometry ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2892 flatcamEditors/FlatCAMGeoEditor.py:2922 -#: flatcamEditors/FlatCAMGeoEditor.py:2952 -msgid "Buffer cancelled. No shape selected." -msgstr "" - -#: flatcamEditors/FlatCAMGeoEditor.py:2917 flatcamEditors/FlatCAMGrbEditor.py:4950 +#: flatcamEditors/FlatCAMGeoEditor.py:3049 flatcamEditors/FlatCAMGrbEditor.py:4994 msgid "Done. Buffer Tool completed." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2947 +#: flatcamEditors/FlatCAMGeoEditor.py:3077 msgid "Done. Buffer Int Tool completed." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:2977 +#: flatcamEditors/FlatCAMGeoEditor.py:3105 msgid "Done. Buffer Ext Tool completed." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:3023 flatcamEditors/FlatCAMGrbEditor.py:2152 +#: flatcamEditors/FlatCAMGeoEditor.py:3154 flatcamEditors/FlatCAMGrbEditor.py:2151 msgid "Select a shape to act as deletion area ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:3025 flatcamEditors/FlatCAMGeoEditor.py:3045 -#: flatcamEditors/FlatCAMGeoEditor.py:3051 flatcamEditors/FlatCAMGrbEditor.py:2154 +#: flatcamEditors/FlatCAMGeoEditor.py:3156 flatcamEditors/FlatCAMGeoEditor.py:3182 +#: flatcamEditors/FlatCAMGeoEditor.py:3188 flatcamEditors/FlatCAMGrbEditor.py:2153 msgid "Click to pick-up the erase shape..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:3055 flatcamEditors/FlatCAMGrbEditor.py:2213 +#: flatcamEditors/FlatCAMGeoEditor.py:3192 flatcamEditors/FlatCAMGrbEditor.py:2212 msgid "Click to erase ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:3084 flatcamEditors/FlatCAMGrbEditor.py:2246 +#: flatcamEditors/FlatCAMGeoEditor.py:3221 flatcamEditors/FlatCAMGrbEditor.py:2245 msgid "Done. Eraser tool action completed." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:3131 +#: flatcamEditors/FlatCAMGeoEditor.py:3271 msgid "Create Paint geometry ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:3144 flatcamEditors/FlatCAMGrbEditor.py:2402 +#: flatcamEditors/FlatCAMGeoEditor.py:3284 flatcamEditors/FlatCAMGrbEditor.py:2408 msgid "Shape transformations ..." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:3763 +#: flatcamEditors/FlatCAMGeoEditor.py:3340 flatcamGUI/PreferencesUI.py:4636 +msgid "Geometry Editor" +msgstr "" + +#: flatcamEditors/FlatCAMGeoEditor.py:3346 flatcamEditors/FlatCAMGrbEditor.py:2486 +#: flatcamEditors/FlatCAMGrbEditor.py:3846 flatcamGUI/ObjectUI.py:262 +#: flatcamGUI/ObjectUI.py:1495 flatcamGUI/ObjectUI.py:2244 flatcamTools/ToolCutOut.py:96 +msgid "Type" +msgstr "" + +#: flatcamEditors/FlatCAMGeoEditor.py:3346 flatcamGUI/ObjectUI.py:217 +#: flatcamGUI/ObjectUI.py:741 flatcamGUI/ObjectUI.py:1431 flatcamGUI/ObjectUI.py:2153 +#: flatcamGUI/ObjectUI.py:2457 flatcamGUI/ObjectUI.py:2524 +#: flatcamTools/ToolCalibration.py:234 flatcamTools/ToolFiducials.py:73 +msgid "Name" +msgstr "" + +#: flatcamEditors/FlatCAMGeoEditor.py:3588 +msgid "Ring" +msgstr "" + +#: flatcamEditors/FlatCAMGeoEditor.py:3590 +msgid "Line" +msgstr "" + +#: flatcamEditors/FlatCAMGeoEditor.py:3592 flatcamGUI/FlatCAMGUI.py:2187 +#: flatcamGUI/PreferencesUI.py:5607 flatcamGUI/PreferencesUI.py:6131 +#: flatcamTools/ToolNCC.py:584 flatcamTools/ToolPaint.py:528 +msgid "Polygon" +msgstr "" + +#: flatcamEditors/FlatCAMGeoEditor.py:3594 +msgid "Multi-Line" +msgstr "" + +#: flatcamEditors/FlatCAMGeoEditor.py:3596 +msgid "Multi-Polygon" +msgstr "" + +#: flatcamEditors/FlatCAMGeoEditor.py:3603 +msgid "Geo Elem" +msgstr "" + +#: flatcamEditors/FlatCAMGeoEditor.py:4076 msgid "Editing MultiGeo Geometry, tool" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:3765 +#: flatcamEditors/FlatCAMGeoEditor.py:4078 msgid "with diameter" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:4169 -msgid "Copy cancelled. No shape selected." -msgstr "" - -#: flatcamEditors/FlatCAMGeoEditor.py:4176 flatcamGUI/FlatCAMGUI.py:3472 -#: flatcamGUI/FlatCAMGUI.py:3519 flatcamGUI/FlatCAMGUI.py:3538 flatcamGUI/FlatCAMGUI.py:3679 -#: flatcamGUI/FlatCAMGUI.py:3719 flatcamGUI/FlatCAMGUI.py:3732 flatcamGUI/FlatCAMGUI.py:3749 +#: flatcamEditors/FlatCAMGeoEditor.py:4509 flatcamGUI/FlatCAMGUI.py:3695 +#: flatcamGUI/FlatCAMGUI.py:3741 flatcamGUI/FlatCAMGUI.py:3759 flatcamGUI/FlatCAMGUI.py:3899 +#: flatcamGUI/FlatCAMGUI.py:3938 flatcamGUI/FlatCAMGUI.py:3950 flatcamGUI/FlatCAMGUI.py:3967 msgid "Click on target point." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:4479 flatcamEditors/FlatCAMGeoEditor.py:4514 +#: flatcamEditors/FlatCAMGeoEditor.py:4823 flatcamEditors/FlatCAMGeoEditor.py:4858 msgid "A selection of at least 2 geo items is required to do Intersection." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:4600 flatcamEditors/FlatCAMGeoEditor.py:4704 +#: flatcamEditors/FlatCAMGeoEditor.py:4944 flatcamEditors/FlatCAMGeoEditor.py:5048 msgid "" "Negative buffer value is not accepted. Use Buffer interior to generate an 'inside' shape" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:4610 flatcamEditors/FlatCAMGeoEditor.py:4663 -#: flatcamEditors/FlatCAMGeoEditor.py:4713 +#: flatcamEditors/FlatCAMGeoEditor.py:4954 flatcamEditors/FlatCAMGeoEditor.py:5007 +#: flatcamEditors/FlatCAMGeoEditor.py:5057 msgid "Nothing selected for buffering." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:4615 flatcamEditors/FlatCAMGeoEditor.py:4667 -#: flatcamEditors/FlatCAMGeoEditor.py:4718 +#: flatcamEditors/FlatCAMGeoEditor.py:4959 flatcamEditors/FlatCAMGeoEditor.py:5011 +#: flatcamEditors/FlatCAMGeoEditor.py:5062 msgid "Invalid distance for buffering." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:4639 flatcamEditors/FlatCAMGeoEditor.py:4738 +#: flatcamEditors/FlatCAMGeoEditor.py:4983 flatcamEditors/FlatCAMGeoEditor.py:5082 msgid "Failed, the result is empty. Choose a different buffer value." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:4650 +#: flatcamEditors/FlatCAMGeoEditor.py:4994 msgid "Full buffer geometry created." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:4656 +#: flatcamEditors/FlatCAMGeoEditor.py:5000 msgid "Negative buffer value is not accepted." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:4687 +#: flatcamEditors/FlatCAMGeoEditor.py:5031 msgid "Failed, the result is empty. Choose a smaller buffer value." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:4697 +#: flatcamEditors/FlatCAMGeoEditor.py:5041 msgid "Interior buffer geometry created." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:4748 +#: flatcamEditors/FlatCAMGeoEditor.py:5092 msgid "Exterior buffer geometry created." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:4754 +#: flatcamEditors/FlatCAMGeoEditor.py:5098 #, python-format -msgid "Could not do Paint. Overlap value has to be less than 1.00 (100%%)." +msgid "Could not do Paint. Overlap value has to be less than 100%%." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:4761 +#: flatcamEditors/FlatCAMGeoEditor.py:5105 msgid "Nothing selected for painting." msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:4767 +#: flatcamEditors/FlatCAMGeoEditor.py:5111 msgid "Invalid value for" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:4826 +#: flatcamEditors/FlatCAMGeoEditor.py:5170 msgid "" "Could not do Paint. Try a different combination of parameters. Or a different method of " "Paint" msgstr "" -#: flatcamEditors/FlatCAMGeoEditor.py:4840 +#: flatcamEditors/FlatCAMGeoEditor.py:5181 msgid "Paint done." msgstr "" @@ -3947,7 +4228,7 @@ msgstr "" msgid "Aperture size is zero. It needs to be greater than zero." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:371 flatcamEditors/FlatCAMGrbEditor.py:685 +#: flatcamEditors/FlatCAMGrbEditor.py:371 flatcamEditors/FlatCAMGrbEditor.py:684 msgid "Incompatible aperture type. Select an aperture with type 'C', 'R' or 'O'." msgstr "" @@ -3963,170 +4244,165 @@ msgstr "" msgid "Click on the Pad Circular Array Start position" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:711 +#: flatcamEditors/FlatCAMGrbEditor.py:710 msgid "Too many Pads for the selected spacing angle." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:734 +#: flatcamEditors/FlatCAMGrbEditor.py:733 msgid "Done. Pad Array added." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:759 +#: flatcamEditors/FlatCAMGrbEditor.py:758 msgid "Select shape(s) and then click ..." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:771 +#: flatcamEditors/FlatCAMGrbEditor.py:770 msgid "Failed. Nothing selected." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:787 +#: flatcamEditors/FlatCAMGrbEditor.py:786 msgid "Failed. Poligonize works only on geometries belonging to the same aperture." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:841 +#: flatcamEditors/FlatCAMGrbEditor.py:840 msgid "Done. Poligonize completed." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:896 flatcamEditors/FlatCAMGrbEditor.py:1129 -#: flatcamEditors/FlatCAMGrbEditor.py:1153 +#: flatcamEditors/FlatCAMGrbEditor.py:895 flatcamEditors/FlatCAMGrbEditor.py:1128 +#: flatcamEditors/FlatCAMGrbEditor.py:1152 msgid "Corner Mode 1: 45 degrees ..." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:908 flatcamEditors/FlatCAMGrbEditor.py:1238 +#: flatcamEditors/FlatCAMGrbEditor.py:907 flatcamEditors/FlatCAMGrbEditor.py:1237 msgid "Click on next Point or click Right mouse button to complete ..." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:1117 flatcamEditors/FlatCAMGrbEditor.py:1150 +#: flatcamEditors/FlatCAMGrbEditor.py:1116 flatcamEditors/FlatCAMGrbEditor.py:1149 msgid "Corner Mode 2: Reverse 45 degrees ..." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:1120 flatcamEditors/FlatCAMGrbEditor.py:1147 +#: flatcamEditors/FlatCAMGrbEditor.py:1119 flatcamEditors/FlatCAMGrbEditor.py:1146 msgid "Corner Mode 3: 90 degrees ..." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:1123 flatcamEditors/FlatCAMGrbEditor.py:1144 +#: flatcamEditors/FlatCAMGrbEditor.py:1122 flatcamEditors/FlatCAMGrbEditor.py:1143 msgid "Corner Mode 4: Reverse 90 degrees ..." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:1126 flatcamEditors/FlatCAMGrbEditor.py:1141 +#: flatcamEditors/FlatCAMGrbEditor.py:1125 flatcamEditors/FlatCAMGrbEditor.py:1140 msgid "Corner Mode 5: Free angle ..." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:1183 flatcamEditors/FlatCAMGrbEditor.py:1359 -#: flatcamEditors/FlatCAMGrbEditor.py:1398 +#: flatcamEditors/FlatCAMGrbEditor.py:1182 flatcamEditors/FlatCAMGrbEditor.py:1358 +#: flatcamEditors/FlatCAMGrbEditor.py:1397 msgid "Track Mode 1: 45 degrees ..." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:1339 flatcamEditors/FlatCAMGrbEditor.py:1393 +#: flatcamEditors/FlatCAMGrbEditor.py:1338 flatcamEditors/FlatCAMGrbEditor.py:1392 msgid "Track Mode 2: Reverse 45 degrees ..." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:1344 flatcamEditors/FlatCAMGrbEditor.py:1388 +#: flatcamEditors/FlatCAMGrbEditor.py:1343 flatcamEditors/FlatCAMGrbEditor.py:1387 msgid "Track Mode 3: 90 degrees ..." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:1349 flatcamEditors/FlatCAMGrbEditor.py:1383 +#: flatcamEditors/FlatCAMGrbEditor.py:1348 flatcamEditors/FlatCAMGrbEditor.py:1382 msgid "Track Mode 4: Reverse 90 degrees ..." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:1354 flatcamEditors/FlatCAMGrbEditor.py:1378 +#: flatcamEditors/FlatCAMGrbEditor.py:1353 flatcamEditors/FlatCAMGrbEditor.py:1377 msgid "Track Mode 5: Free angle ..." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:1779 +#: flatcamEditors/FlatCAMGrbEditor.py:1778 msgid "Scale the selected Gerber apertures ..." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:1821 +#: flatcamEditors/FlatCAMGrbEditor.py:1820 msgid "Buffer the selected apertures ..." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:1863 +#: flatcamEditors/FlatCAMGrbEditor.py:1862 msgid "Mark polygon areas in the edited Gerber ..." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:1929 +#: flatcamEditors/FlatCAMGrbEditor.py:1928 msgid "Nothing selected to move" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2054 +#: flatcamEditors/FlatCAMGrbEditor.py:2053 msgid "Done. Apertures Move completed." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2136 +#: flatcamEditors/FlatCAMGrbEditor.py:2135 msgid "Done. Apertures copied." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2447 flatcamGUI/FlatCAMGUI.py:2110 -#: flatcamGUI/PreferencesUI.py:2443 +#: flatcamEditors/FlatCAMGrbEditor.py:2453 flatcamGUI/FlatCAMGUI.py:2218 +#: flatcamGUI/PreferencesUI.py:2623 msgid "Gerber Editor" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2467 flatcamGUI/ObjectUI.py:223 -#: flatcamTools/ToolProperties.py:156 +#: flatcamEditors/FlatCAMGrbEditor.py:2473 flatcamGUI/ObjectUI.py:227 +#: flatcamTools/ToolProperties.py:159 msgid "Apertures" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2469 flatcamGUI/ObjectUI.py:225 +#: flatcamEditors/FlatCAMGrbEditor.py:2475 flatcamGUI/ObjectUI.py:229 msgid "Apertures Table for the Gerber Object." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2480 flatcamEditors/FlatCAMGrbEditor.py:3832 -#: flatcamGUI/ObjectUI.py:258 +#: flatcamEditors/FlatCAMGrbEditor.py:2486 flatcamEditors/FlatCAMGrbEditor.py:3846 +#: flatcamGUI/ObjectUI.py:262 msgid "Code" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2480 flatcamEditors/FlatCAMGrbEditor.py:3832 -#: flatcamGUI/ObjectUI.py:258 flatcamGUI/ObjectUI.py:1217 flatcamGUI/ObjectUI.py:1916 -msgid "Type" -msgstr "" - -#: flatcamEditors/FlatCAMGrbEditor.py:2480 flatcamEditors/FlatCAMGrbEditor.py:3832 -#: flatcamGUI/ObjectUI.py:258 flatcamGUI/PreferencesUI.py:1009 -#: flatcamGUI/PreferencesUI.py:7270 flatcamGUI/PreferencesUI.py:7299 -#: flatcamGUI/PreferencesUI.py:7401 flatcamTools/ToolCopperThieving.py:260 -#: flatcamTools/ToolCopperThieving.py:300 flatcamTools/ToolFiducials.py:156 +#: flatcamEditors/FlatCAMGrbEditor.py:2486 flatcamEditors/FlatCAMGrbEditor.py:3846 +#: flatcamGUI/ObjectUI.py:262 flatcamGUI/PreferencesUI.py:1184 +#: flatcamGUI/PreferencesUI.py:7776 flatcamGUI/PreferencesUI.py:7805 +#: flatcamGUI/PreferencesUI.py:7907 flatcamTools/ToolCopperThieving.py:262 +#: flatcamTools/ToolCopperThieving.py:302 flatcamTools/ToolFiducials.py:156 msgid "Size" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2480 flatcamEditors/FlatCAMGrbEditor.py:3832 -#: flatcamGUI/ObjectUI.py:258 +#: flatcamEditors/FlatCAMGrbEditor.py:2486 flatcamEditors/FlatCAMGrbEditor.py:3846 +#: flatcamGUI/ObjectUI.py:262 msgid "Dim" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2484 flatcamGUI/ObjectUI.py:262 +#: flatcamEditors/FlatCAMGrbEditor.py:2490 flatcamGUI/ObjectUI.py:266 msgid "Index" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2486 flatcamEditors/FlatCAMGrbEditor.py:2515 -#: flatcamGUI/ObjectUI.py:264 +#: flatcamEditors/FlatCAMGrbEditor.py:2492 flatcamEditors/FlatCAMGrbEditor.py:2521 +#: flatcamGUI/ObjectUI.py:268 msgid "Aperture Code" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2488 flatcamGUI/ObjectUI.py:266 +#: flatcamEditors/FlatCAMGrbEditor.py:2494 flatcamGUI/ObjectUI.py:270 msgid "Type of aperture: circular, rectangle, macros etc" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2490 flatcamGUI/ObjectUI.py:268 +#: flatcamEditors/FlatCAMGrbEditor.py:2496 flatcamGUI/ObjectUI.py:272 msgid "Aperture Size:" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2492 flatcamGUI/ObjectUI.py:270 +#: flatcamEditors/FlatCAMGrbEditor.py:2498 flatcamGUI/ObjectUI.py:274 msgid "" "Aperture Dimensions:\n" " - (width, height) for R, O type.\n" " - (dia, nVertices) for P type" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2516 flatcamGUI/PreferencesUI.py:2474 +#: flatcamEditors/FlatCAMGrbEditor.py:2522 flatcamGUI/PreferencesUI.py:2654 msgid "Code for the new aperture" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2525 +#: flatcamEditors/FlatCAMGrbEditor.py:2531 msgid "Aperture Size" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2527 +#: flatcamEditors/FlatCAMGrbEditor.py:2533 msgid "" "Size for the new aperture.\n" "If aperture type is 'R' or 'O' then\n" @@ -4135,11 +4411,11 @@ msgid "" "sqrt(width**2 + height**2)" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2541 +#: flatcamEditors/FlatCAMGrbEditor.py:2547 msgid "Aperture Type" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2543 +#: flatcamEditors/FlatCAMGrbEditor.py:2549 msgid "" "Select the type of new aperture. Can be:\n" "C = circular\n" @@ -4147,50 +4423,50 @@ msgid "" "O = oblong" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2554 +#: flatcamEditors/FlatCAMGrbEditor.py:2560 msgid "Aperture Dim" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2556 +#: flatcamEditors/FlatCAMGrbEditor.py:2562 msgid "" "Dimensions for the new aperture.\n" "Active only for rectangular apertures (type R).\n" "The format is (width, height)" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2565 +#: flatcamEditors/FlatCAMGrbEditor.py:2571 msgid "Add/Delete Aperture" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2567 +#: flatcamEditors/FlatCAMGrbEditor.py:2573 msgid "Add/Delete an aperture in the aperture table" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2576 +#: flatcamEditors/FlatCAMGrbEditor.py:2582 msgid "Add a new aperture to the aperture list." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2581 +#: flatcamEditors/FlatCAMGrbEditor.py:2587 msgid "Delete a aperture in the aperture list" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2598 +#: flatcamEditors/FlatCAMGrbEditor.py:2604 msgid "Buffer Aperture" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2600 +#: flatcamEditors/FlatCAMGrbEditor.py:2606 msgid "Buffer a aperture in the aperture list" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2613 flatcamGUI/PreferencesUI.py:2608 +#: flatcamEditors/FlatCAMGrbEditor.py:2619 flatcamGUI/PreferencesUI.py:2790 msgid "Buffer distance" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2614 +#: flatcamEditors/FlatCAMGrbEditor.py:2620 msgid "Buffer corner" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2616 +#: flatcamEditors/FlatCAMGrbEditor.py:2622 msgid "" "There are 3 types of corners:\n" " - 'Round': the corner is rounded.\n" @@ -4199,103 +4475,99 @@ msgid "" "corner" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2631 flatcamGUI/FlatCAMGUI.py:978 -#: flatcamGUI/FlatCAMGUI.py:2015 flatcamGUI/FlatCAMGUI.py:2087 flatcamGUI/FlatCAMGUI.py:2130 -#: flatcamGUI/FlatCAMGUI.py:2547 flatcamGUI/PreferencesUI.py:6393 -#: flatcamTools/ToolTransform.py:30 flatcamTools/ToolTransform.py:349 +#: flatcamEditors/FlatCAMGrbEditor.py:2637 flatcamGUI/FlatCAMGUI.py:1046 +#: flatcamGUI/FlatCAMGUI.py:2123 flatcamGUI/FlatCAMGUI.py:2195 flatcamGUI/FlatCAMGUI.py:2238 +#: flatcamGUI/FlatCAMGUI.py:2721 flatcamGUI/PreferencesUI.py:6880 +#: flatcamTools/ToolTransform.py:30 msgid "Buffer" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2646 +#: flatcamEditors/FlatCAMGrbEditor.py:2652 msgid "Scale Aperture" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2648 +#: flatcamEditors/FlatCAMGrbEditor.py:2654 msgid "Scale a aperture in the aperture list" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2656 flatcamGUI/PreferencesUI.py:2623 +#: flatcamEditors/FlatCAMGrbEditor.py:2662 flatcamGUI/PreferencesUI.py:2805 msgid "Scale factor" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2658 +#: flatcamEditors/FlatCAMGrbEditor.py:2664 msgid "" "The factor by which to scale the selected aperture.\n" "Values can be between 0.0000 and 999.9999" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2686 +#: flatcamEditors/FlatCAMGrbEditor.py:2692 msgid "Mark polygons" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2688 +#: flatcamEditors/FlatCAMGrbEditor.py:2694 msgid "Mark the polygon areas." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2696 +#: flatcamEditors/FlatCAMGrbEditor.py:2702 msgid "Area UPPER threshold" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2698 +#: flatcamEditors/FlatCAMGrbEditor.py:2704 msgid "" "The threshold value, all areas less than this are marked.\n" "Can have a value between 0.0000 and 9999.9999" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2705 +#: flatcamEditors/FlatCAMGrbEditor.py:2711 msgid "Area LOWER threshold" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2707 +#: flatcamEditors/FlatCAMGrbEditor.py:2713 msgid "" "The threshold value, all areas more than this are marked.\n" "Can have a value between 0.0000 and 9999.9999" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2721 +#: flatcamEditors/FlatCAMGrbEditor.py:2727 msgid "Mark" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2723 +#: flatcamEditors/FlatCAMGrbEditor.py:2729 msgid "Mark the polygons that fit within limits." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2729 +#: flatcamEditors/FlatCAMGrbEditor.py:2735 msgid "Delete all the marked polygons." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2733 -msgid "Clear" -msgstr "" - -#: flatcamEditors/FlatCAMGrbEditor.py:2735 +#: flatcamEditors/FlatCAMGrbEditor.py:2741 msgid "Clear all the markings." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2755 flatcamGUI/FlatCAMGUI.py:963 -#: flatcamGUI/FlatCAMGUI.py:2015 flatcamGUI/FlatCAMGUI.py:2532 +#: flatcamEditors/FlatCAMGrbEditor.py:2761 flatcamGUI/FlatCAMGUI.py:1031 +#: flatcamGUI/FlatCAMGUI.py:2123 flatcamGUI/FlatCAMGUI.py:2706 msgid "Add Pad Array" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2757 +#: flatcamEditors/FlatCAMGrbEditor.py:2763 msgid "Add an array of pads (linear or circular array)" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2763 +#: flatcamEditors/FlatCAMGrbEditor.py:2769 msgid "" "Select the type of pads array to create.\n" "It can be Linear X(Y) or Circular" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2774 flatcamGUI/PreferencesUI.py:2511 +#: flatcamEditors/FlatCAMGrbEditor.py:2780 flatcamGUI/PreferencesUI.py:2691 msgid "Nr of pads" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2776 flatcamGUI/PreferencesUI.py:2513 +#: flatcamEditors/FlatCAMGrbEditor.py:2782 flatcamGUI/PreferencesUI.py:2693 msgid "Specify how many pads to be in the array." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:2825 +#: flatcamEditors/FlatCAMGrbEditor.py:2831 msgid "" "Angle at which the linear array is placed.\n" "The precision is of max 2 decimals.\n" @@ -4303,471 +4575,463 @@ msgid "" "Max value is: 360.00 degrees." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:3307 flatcamEditors/FlatCAMGrbEditor.py:3311 +#: flatcamEditors/FlatCAMGrbEditor.py:3321 flatcamEditors/FlatCAMGrbEditor.py:3325 msgid "Aperture code value is missing or wrong format. Add it and retry." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:3347 +#: flatcamEditors/FlatCAMGrbEditor.py:3361 msgid "" "Aperture dimensions value is missing or wrong format. Add it in format (width, height) " "and retry." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:3360 +#: flatcamEditors/FlatCAMGrbEditor.py:3374 msgid "Aperture size value is missing or wrong format. Add it and retry." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:3371 +#: flatcamEditors/FlatCAMGrbEditor.py:3385 msgid "Aperture already in the aperture table." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:3379 +#: flatcamEditors/FlatCAMGrbEditor.py:3393 msgid "Added new aperture with code" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:3408 +#: flatcamEditors/FlatCAMGrbEditor.py:3422 msgid " Select an aperture in Aperture Table" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:3416 +#: flatcamEditors/FlatCAMGrbEditor.py:3430 msgid "Select an aperture in Aperture Table -->" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:3439 +#: flatcamEditors/FlatCAMGrbEditor.py:3453 msgid "Deleted aperture with code" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:3924 +#: flatcamEditors/FlatCAMGrbEditor.py:3950 msgid "Loading Gerber into Editor" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:4034 +#: flatcamEditors/FlatCAMGrbEditor.py:4078 msgid "Setting up the UI" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:4035 +#: flatcamEditors/FlatCAMGrbEditor.py:4079 msgid "Adding geometry finished. Preparing the GUI" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:4044 +#: flatcamEditors/FlatCAMGrbEditor.py:4088 msgid "Finished loading the Gerber object into the editor." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:4184 +#: flatcamEditors/FlatCAMGrbEditor.py:4228 msgid "There are no Aperture definitions in the file. Aborting Gerber creation." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:4194 +#: flatcamEditors/FlatCAMGrbEditor.py:4238 msgid "Creating Gerber." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:4203 +#: flatcamEditors/FlatCAMGrbEditor.py:4247 msgid "Done. Gerber editing finished." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:4222 +#: flatcamEditors/FlatCAMGrbEditor.py:4265 msgid "Cancelled. No aperture is selected" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:4782 +#: flatcamEditors/FlatCAMGrbEditor.py:4826 msgid "Failed. No aperture geometry is selected." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:4791 flatcamEditors/FlatCAMGrbEditor.py:5062 +#: flatcamEditors/FlatCAMGrbEditor.py:4835 flatcamEditors/FlatCAMGrbEditor.py:5106 msgid "Done. Apertures geometry deleted." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:4934 +#: flatcamEditors/FlatCAMGrbEditor.py:4978 msgid "No aperture to buffer. Select at least one aperture and try again." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:4946 +#: flatcamEditors/FlatCAMGrbEditor.py:4990 msgid "Failed." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:4965 +#: flatcamEditors/FlatCAMGrbEditor.py:5009 msgid "Scale factor value is missing or wrong format. Add it and retry." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:4997 +#: flatcamEditors/FlatCAMGrbEditor.py:5041 msgid "No aperture to scale. Select at least one aperture and try again." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:5013 +#: flatcamEditors/FlatCAMGrbEditor.py:5057 msgid "Done. Scale Tool completed." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:5051 +#: flatcamEditors/FlatCAMGrbEditor.py:5095 msgid "Polygons marked." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:5054 +#: flatcamEditors/FlatCAMGrbEditor.py:5098 msgid "No polygons were marked. None fit within the limits." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:5783 +#: flatcamEditors/FlatCAMGrbEditor.py:5822 msgid "Rotation action was not executed." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:5919 +#: flatcamEditors/FlatCAMGrbEditor.py:5950 msgid "Skew action was not executed." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:5986 +#: flatcamEditors/FlatCAMGrbEditor.py:6015 msgid "Scale action was not executed." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:6029 +#: flatcamEditors/FlatCAMGrbEditor.py:6058 msgid "Offset action was not executed." msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:6079 +#: flatcamEditors/FlatCAMGrbEditor.py:6108 msgid "Geometry shape offset Y cancelled" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:6094 +#: flatcamEditors/FlatCAMGrbEditor.py:6123 msgid "Geometry shape skew X cancelled" msgstr "" -#: flatcamEditors/FlatCAMGrbEditor.py:6109 +#: flatcamEditors/FlatCAMGrbEditor.py:6138 msgid "Geometry shape skew Y cancelled" msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:72 +#: flatcamEditors/FlatCAMTextEditor.py:74 msgid "Print Preview" msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:73 +#: flatcamEditors/FlatCAMTextEditor.py:75 msgid "Open a OS standard Preview Print window." msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:76 +#: flatcamEditors/FlatCAMTextEditor.py:78 msgid "Print Code" msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:77 +#: flatcamEditors/FlatCAMTextEditor.py:79 msgid "Open a OS standard Print window." msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:79 +#: flatcamEditors/FlatCAMTextEditor.py:81 msgid "Find in Code" msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:80 +#: flatcamEditors/FlatCAMTextEditor.py:82 msgid "Will search and highlight in yellow the string in the Find box." msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:84 +#: flatcamEditors/FlatCAMTextEditor.py:86 msgid "Find box. Enter here the strings to be searched in the text." msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:86 +#: flatcamEditors/FlatCAMTextEditor.py:88 msgid "Replace With" msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:87 +#: flatcamEditors/FlatCAMTextEditor.py:89 msgid "Will replace the string from the Find box with the one in the Replace box." msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:91 +#: flatcamEditors/FlatCAMTextEditor.py:93 msgid "String to replace the one in the Find box throughout the text." msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:93 flatcamGUI/ObjectUI.py:482 -#: flatcamGUI/ObjectUI.py:1809 flatcamGUI/PreferencesUI.py:2070 -#: flatcamGUI/PreferencesUI.py:4419 flatcamGUI/PreferencesUI.py:5647 +#: flatcamEditors/FlatCAMTextEditor.py:95 flatcamGUI/ObjectUI.py:485 +#: flatcamGUI/ObjectUI.py:2137 flatcamGUI/PreferencesUI.py:2250 +#: flatcamGUI/PreferencesUI.py:4712 msgid "All" msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:94 +#: flatcamEditors/FlatCAMTextEditor.py:96 msgid "" "When checked it will replace all instances in the 'Find' box\n" "with the text in the 'Replace' box.." msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:97 +#: flatcamEditors/FlatCAMTextEditor.py:99 msgid "Copy All" msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:98 +#: flatcamEditors/FlatCAMTextEditor.py:100 msgid "Will copy all the text in the Code Editor to the clipboard." msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:101 +#: flatcamEditors/FlatCAMTextEditor.py:103 msgid "Open Code" msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:102 +#: flatcamEditors/FlatCAMTextEditor.py:104 msgid "Will open a text file in the editor." msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:104 +#: flatcamEditors/FlatCAMTextEditor.py:106 msgid "Save Code" msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:105 +#: flatcamEditors/FlatCAMTextEditor.py:107 msgid "Will save the text in the editor into a file." msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:107 +#: flatcamEditors/FlatCAMTextEditor.py:109 msgid "Run Code" msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:108 +#: flatcamEditors/FlatCAMTextEditor.py:110 msgid "Will run the TCL commands found in the text file, one by one." msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:182 +#: flatcamEditors/FlatCAMTextEditor.py:184 msgid "Open file" msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:213 flatcamEditors/FlatCAMTextEditor.py:218 +#: flatcamEditors/FlatCAMTextEditor.py:215 flatcamEditors/FlatCAMTextEditor.py:220 msgid "Export Code ..." msgstr "" -#: flatcamEditors/FlatCAMTextEditor.py:221 -msgid "Export Code cancelled." -msgstr "" - -#: flatcamEditors/FlatCAMTextEditor.py:332 +#: flatcamEditors/FlatCAMTextEditor.py:334 msgid "Code Editor content copied to clipboard ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:52 flatcamGUI/FlatCAMGUI.py:54 flatcamGUI/FlatCAMGUI.py:2040 +#: flatcamGUI/FlatCAMGUI.py:66 flatcamGUI/FlatCAMGUI.py:68 flatcamGUI/FlatCAMGUI.py:2148 msgid "Toggle Panel" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:64 +#: flatcamGUI/FlatCAMGUI.py:78 msgid "File" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:69 +#: flatcamGUI/FlatCAMGUI.py:83 msgid "&New Project ...\tCtrl+N" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:71 +#: flatcamGUI/FlatCAMGUI.py:85 msgid "Will create a new, blank project" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:76 +#: flatcamGUI/FlatCAMGUI.py:90 msgid "&New" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:80 +#: flatcamGUI/FlatCAMGUI.py:94 msgid "Geometry\tN" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:82 +#: flatcamGUI/FlatCAMGUI.py:96 msgid "Will create a new, empty Geometry Object." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:84 +#: flatcamGUI/FlatCAMGUI.py:99 msgid "Gerber\tB" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:86 +#: flatcamGUI/FlatCAMGUI.py:101 msgid "Will create a new, empty Gerber Object." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:88 +#: flatcamGUI/FlatCAMGUI.py:104 msgid "Excellon\tL" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:90 +#: flatcamGUI/FlatCAMGUI.py:106 msgid "Will create a new, empty Excellon Object." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:94 +#: flatcamGUI/FlatCAMGUI.py:111 msgid "Document\tD" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:96 +#: flatcamGUI/FlatCAMGUI.py:113 msgid "Will create a new, empty Document Object." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:99 flatcamGUI/FlatCAMGUI.py:4111 +#: flatcamGUI/FlatCAMGUI.py:117 flatcamGUI/FlatCAMGUI.py:4327 #: flatcamTools/ToolPcbWizard.py:62 flatcamTools/ToolPcbWizard.py:69 msgid "Open" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:103 +#: flatcamGUI/FlatCAMGUI.py:122 msgid "Open &Project ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:109 flatcamGUI/FlatCAMGUI.py:4121 +#: flatcamGUI/FlatCAMGUI.py:128 flatcamGUI/FlatCAMGUI.py:4337 msgid "Open &Gerber ...\tCtrl+G" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:114 flatcamGUI/FlatCAMGUI.py:4126 +#: flatcamGUI/FlatCAMGUI.py:133 flatcamGUI/FlatCAMGUI.py:4342 msgid "Open &Excellon ...\tCtrl+E" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:118 flatcamGUI/FlatCAMGUI.py:4131 +#: flatcamGUI/FlatCAMGUI.py:138 flatcamGUI/FlatCAMGUI.py:4347 msgid "Open G-&Code ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:124 +#: flatcamGUI/FlatCAMGUI.py:145 msgid "Open Config ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:128 +#: flatcamGUI/FlatCAMGUI.py:150 msgid "Recent projects" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:129 +#: flatcamGUI/FlatCAMGUI.py:152 msgid "Recent files" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:135 +#: flatcamGUI/FlatCAMGUI.py:155 flatcamGUI/FlatCAMGUI.py:738 flatcamGUI/FlatCAMGUI.py:1324 +msgid "Save" +msgstr "" + +#: flatcamGUI/FlatCAMGUI.py:159 +msgid "&Save Project ...\tCtrl+S" +msgstr "" + +#: flatcamGUI/FlatCAMGUI.py:164 +msgid "Save Project &As ...\tCtrl+Shift+S" +msgstr "" + +#: flatcamGUI/FlatCAMGUI.py:179 msgid "Scripting" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:138 flatcamGUI/FlatCAMGUI.py:829 flatcamGUI/FlatCAMGUI.py:2409 +#: flatcamGUI/FlatCAMGUI.py:183 flatcamGUI/FlatCAMGUI.py:888 flatcamGUI/FlatCAMGUI.py:2567 msgid "New Script ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:139 flatcamGUI/FlatCAMGUI.py:831 flatcamGUI/FlatCAMGUI.py:2411 +#: flatcamGUI/FlatCAMGUI.py:185 flatcamGUI/FlatCAMGUI.py:890 flatcamGUI/FlatCAMGUI.py:2569 msgid "Open Script ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:141 flatcamGUI/FlatCAMGUI.py:833 flatcamGUI/FlatCAMGUI.py:2413 -#: flatcamGUI/FlatCAMGUI.py:4100 +#: flatcamGUI/FlatCAMGUI.py:187 flatcamGUI/FlatCAMGUI.py:892 flatcamGUI/FlatCAMGUI.py:2571 +#: flatcamGUI/FlatCAMGUI.py:4316 msgid "Run Script ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:143 flatcamGUI/FlatCAMGUI.py:4102 +#: flatcamGUI/FlatCAMGUI.py:189 flatcamGUI/FlatCAMGUI.py:4318 msgid "" "Will run the opened Tcl Script thus\n" "enabling the automation of certain\n" "functions of FlatCAM." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:156 +#: flatcamGUI/FlatCAMGUI.py:203 msgid "Import" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:158 +#: flatcamGUI/FlatCAMGUI.py:205 msgid "&SVG as Geometry Object ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:161 +#: flatcamGUI/FlatCAMGUI.py:208 msgid "&SVG as Gerber Object ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:166 +#: flatcamGUI/FlatCAMGUI.py:213 msgid "&DXF as Geometry Object ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:169 +#: flatcamGUI/FlatCAMGUI.py:216 msgid "&DXF as Gerber Object ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:173 +#: flatcamGUI/FlatCAMGUI.py:220 msgid "HPGL2 as Geometry Object ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:178 +#: flatcamGUI/FlatCAMGUI.py:226 msgid "Export" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:181 +#: flatcamGUI/FlatCAMGUI.py:230 msgid "Export &SVG ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:184 +#: flatcamGUI/FlatCAMGUI.py:234 msgid "Export DXF ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:189 +#: flatcamGUI/FlatCAMGUI.py:240 msgid "Export &PNG ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:191 +#: flatcamGUI/FlatCAMGUI.py:242 msgid "" "Will export an image in PNG format,\n" "the saved image will contain the visual \n" "information currently in FlatCAM Plot Area." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:200 +#: flatcamGUI/FlatCAMGUI.py:251 msgid "Export &Excellon ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:202 +#: flatcamGUI/FlatCAMGUI.py:253 msgid "" "Will export an Excellon Object as Excellon file,\n" "the coordinates format, the file units and zeros\n" "are set in Preferences -> Excellon Export." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:209 +#: flatcamGUI/FlatCAMGUI.py:260 msgid "Export &Gerber ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:211 +#: flatcamGUI/FlatCAMGUI.py:262 msgid "" "Will export an Gerber Object as Gerber file,\n" "the coordinates format, the file units and zeros\n" "are set in Preferences -> Gerber Export." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:229 +#: flatcamGUI/FlatCAMGUI.py:272 msgid "Backup" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:233 +#: flatcamGUI/FlatCAMGUI.py:277 msgid "Import Preferences from file ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:238 +#: flatcamGUI/FlatCAMGUI.py:283 msgid "Export Preferences to file ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:244 flatcamGUI/FlatCAMGUI.py:1614 +#: flatcamGUI/FlatCAMGUI.py:297 flatcamGUI/FlatCAMGUI.py:1715 msgid "Print (PDF)" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:247 flatcamGUI/FlatCAMGUI.py:682 flatcamGUI/FlatCAMGUI.py:1252 -msgid "Save" -msgstr "" - -#: flatcamGUI/FlatCAMGUI.py:251 -msgid "&Save Project ..." -msgstr "" - -#: flatcamGUI/FlatCAMGUI.py:256 -msgid "Save Project &As ...\tCtrl+S" -msgstr "" - -#: flatcamGUI/FlatCAMGUI.py:261 -msgid "Save Project C&opy ..." -msgstr "" - -#: flatcamGUI/FlatCAMGUI.py:271 +#: flatcamGUI/FlatCAMGUI.py:305 msgid "E&xit" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:279 flatcamGUI/FlatCAMGUI.py:676 flatcamGUI/FlatCAMGUI.py:2163 +#: flatcamGUI/FlatCAMGUI.py:313 flatcamGUI/FlatCAMGUI.py:732 flatcamGUI/FlatCAMGUI.py:2271 msgid "Edit" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:283 +#: flatcamGUI/FlatCAMGUI.py:317 msgid "Edit Object\tE" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:285 +#: flatcamGUI/FlatCAMGUI.py:319 msgid "Close Editor\tCtrl+S" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:294 +#: flatcamGUI/FlatCAMGUI.py:328 msgid "Conversion" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:296 +#: flatcamGUI/FlatCAMGUI.py:330 msgid "&Join Geo/Gerber/Exc -> Geo" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:298 +#: flatcamGUI/FlatCAMGUI.py:332 msgid "" "Merge a selection of objects, which can be of type:\n" "- Gerber\n" @@ -4776,1390 +5040,1418 @@ msgid "" "into a new combo Geometry object." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:305 +#: flatcamGUI/FlatCAMGUI.py:339 msgid "Join Excellon(s) -> Excellon" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:307 +#: flatcamGUI/FlatCAMGUI.py:341 msgid "Merge a selection of Excellon objects into a new combo Excellon object." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:310 +#: flatcamGUI/FlatCAMGUI.py:344 msgid "Join Gerber(s) -> Gerber" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:312 +#: flatcamGUI/FlatCAMGUI.py:346 msgid "Merge a selection of Gerber objects into a new combo Gerber object." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:317 +#: flatcamGUI/FlatCAMGUI.py:351 msgid "Convert Single to MultiGeo" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:319 +#: flatcamGUI/FlatCAMGUI.py:353 msgid "" "Will convert a Geometry object from single_geometry type\n" "to a multi_geometry type." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:323 +#: flatcamGUI/FlatCAMGUI.py:357 msgid "Convert Multi to SingleGeo" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:325 +#: flatcamGUI/FlatCAMGUI.py:359 msgid "" "Will convert a Geometry object from multi_geometry type\n" "to a single_geometry type." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:332 +#: flatcamGUI/FlatCAMGUI.py:366 msgid "Convert Any to Geo" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:335 +#: flatcamGUI/FlatCAMGUI.py:369 msgid "Convert Any to Gerber" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:341 +#: flatcamGUI/FlatCAMGUI.py:375 msgid "&Copy\tCtrl+C" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:346 +#: flatcamGUI/FlatCAMGUI.py:380 msgid "&Delete\tDEL" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:351 +#: flatcamGUI/FlatCAMGUI.py:385 msgid "Se&t Origin\tO" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:353 +#: flatcamGUI/FlatCAMGUI.py:387 +msgid "Move to Origin\tShift+O" +msgstr "" + +#: flatcamGUI/FlatCAMGUI.py:390 msgid "Jump to Location\tJ" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:358 +#: flatcamGUI/FlatCAMGUI.py:392 +msgid "Locate in Object\tShift+J" +msgstr "" + +#: flatcamGUI/FlatCAMGUI.py:397 msgid "Toggle Units\tQ" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:360 +#: flatcamGUI/FlatCAMGUI.py:399 msgid "&Select All\tCtrl+A" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:365 +#: flatcamGUI/FlatCAMGUI.py:404 msgid "&Preferences\tShift+P" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:371 flatcamTools/ToolProperties.py:153 +#: flatcamGUI/FlatCAMGUI.py:410 flatcamTools/ToolProperties.py:155 msgid "Options" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:373 +#: flatcamGUI/FlatCAMGUI.py:412 msgid "&Rotate Selection\tShift+(R)" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:378 +#: flatcamGUI/FlatCAMGUI.py:417 msgid "&Skew on X axis\tShift+X" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:380 +#: flatcamGUI/FlatCAMGUI.py:419 msgid "S&kew on Y axis\tShift+Y" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:385 +#: flatcamGUI/FlatCAMGUI.py:424 msgid "Flip on &X axis\tX" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:387 +#: flatcamGUI/FlatCAMGUI.py:426 msgid "Flip on &Y axis\tY" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:392 +#: flatcamGUI/FlatCAMGUI.py:431 msgid "View source\tAlt+S" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:394 +#: flatcamGUI/FlatCAMGUI.py:433 msgid "Tools DataBase\tCtrl+D" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:401 flatcamGUI/FlatCAMGUI.py:2060 +#: flatcamGUI/FlatCAMGUI.py:440 flatcamGUI/FlatCAMGUI.py:2168 msgid "View" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:403 +#: flatcamGUI/FlatCAMGUI.py:442 msgid "Enable all plots\tAlt+1" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:405 +#: flatcamGUI/FlatCAMGUI.py:444 msgid "Disable all plots\tAlt+2" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:407 +#: flatcamGUI/FlatCAMGUI.py:446 msgid "Disable non-selected\tAlt+3" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:411 +#: flatcamGUI/FlatCAMGUI.py:450 msgid "&Zoom Fit\tV" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:413 +#: flatcamGUI/FlatCAMGUI.py:452 msgid "&Zoom In\t=" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:415 +#: flatcamGUI/FlatCAMGUI.py:454 msgid "&Zoom Out\t-" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:420 +#: flatcamGUI/FlatCAMGUI.py:459 msgid "Redraw All\tF5" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:424 +#: flatcamGUI/FlatCAMGUI.py:463 msgid "Toggle Code Editor\tShift+E" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:427 +#: flatcamGUI/FlatCAMGUI.py:466 msgid "&Toggle FullScreen\tAlt+F10" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:429 +#: flatcamGUI/FlatCAMGUI.py:468 msgid "&Toggle Plot Area\tCtrl+F10" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:431 +#: flatcamGUI/FlatCAMGUI.py:470 msgid "&Toggle Project/Sel/Tool\t`" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:435 +#: flatcamGUI/FlatCAMGUI.py:474 msgid "&Toggle Grid Snap\tG" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:437 +#: flatcamGUI/FlatCAMGUI.py:476 msgid "&Toggle Grid Lines\tAlt+G" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:439 +#: flatcamGUI/FlatCAMGUI.py:478 msgid "&Toggle Axis\tShift+G" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:441 +#: flatcamGUI/FlatCAMGUI.py:480 msgid "Toggle Workspace\tShift+W" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:446 +#: flatcamGUI/FlatCAMGUI.py:485 msgid "Objects" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:460 +#: flatcamGUI/FlatCAMGUI.py:499 msgid "&Command Line\tS" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:465 +#: flatcamGUI/FlatCAMGUI.py:504 msgid "Help" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:467 +#: flatcamGUI/FlatCAMGUI.py:506 msgid "Online Help\tF1" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:477 +#: flatcamGUI/FlatCAMGUI.py:516 msgid "Report a bug" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:480 +#: flatcamGUI/FlatCAMGUI.py:519 msgid "Excellon Specification" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:482 +#: flatcamGUI/FlatCAMGUI.py:521 msgid "Gerber Specification" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:487 +#: flatcamGUI/FlatCAMGUI.py:526 msgid "Shortcuts List\tF3" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:489 +#: flatcamGUI/FlatCAMGUI.py:528 msgid "YouTube Channel\tF4" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:500 +#: flatcamGUI/FlatCAMGUI.py:539 msgid "Add Circle\tO" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:503 +#: flatcamGUI/FlatCAMGUI.py:542 msgid "Add Arc\tA" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:506 +#: flatcamGUI/FlatCAMGUI.py:545 msgid "Add Rectangle\tR" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:509 +#: flatcamGUI/FlatCAMGUI.py:548 msgid "Add Polygon\tN" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:512 +#: flatcamGUI/FlatCAMGUI.py:551 msgid "Add Path\tP" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:515 +#: flatcamGUI/FlatCAMGUI.py:554 msgid "Add Text\tT" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:518 +#: flatcamGUI/FlatCAMGUI.py:557 msgid "Polygon Union\tU" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:520 +#: flatcamGUI/FlatCAMGUI.py:559 msgid "Polygon Intersection\tE" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:522 +#: flatcamGUI/FlatCAMGUI.py:561 msgid "Polygon Subtraction\tS" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:526 +#: flatcamGUI/FlatCAMGUI.py:565 msgid "Cut Path\tX" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:529 +#: flatcamGUI/FlatCAMGUI.py:569 msgid "Copy Geom\tC" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:531 +#: flatcamGUI/FlatCAMGUI.py:571 msgid "Delete Shape\tDEL" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:535 flatcamGUI/FlatCAMGUI.py:622 +#: flatcamGUI/FlatCAMGUI.py:575 flatcamGUI/FlatCAMGUI.py:662 msgid "Move\tM" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:537 +#: flatcamGUI/FlatCAMGUI.py:577 msgid "Buffer Tool\tB" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:540 +#: flatcamGUI/FlatCAMGUI.py:580 msgid "Paint Tool\tI" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:543 +#: flatcamGUI/FlatCAMGUI.py:583 msgid "Transform Tool\tAlt+R" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:547 +#: flatcamGUI/FlatCAMGUI.py:587 msgid "Toggle Corner Snap\tK" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:553 +#: flatcamGUI/FlatCAMGUI.py:593 msgid ">Excellon Editor<" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:557 +#: flatcamGUI/FlatCAMGUI.py:597 msgid "Add Drill Array\tA" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:559 +#: flatcamGUI/FlatCAMGUI.py:599 msgid "Add Drill\tD" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:563 +#: flatcamGUI/FlatCAMGUI.py:603 msgid "Add Slot Array\tQ" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:565 +#: flatcamGUI/FlatCAMGUI.py:605 msgid "Add Slot\tW" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:569 +#: flatcamGUI/FlatCAMGUI.py:609 msgid "Resize Drill(S)\tR" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:572 flatcamGUI/FlatCAMGUI.py:616 +#: flatcamGUI/FlatCAMGUI.py:612 flatcamGUI/FlatCAMGUI.py:656 msgid "Copy\tC" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:574 flatcamGUI/FlatCAMGUI.py:618 +#: flatcamGUI/FlatCAMGUI.py:614 flatcamGUI/FlatCAMGUI.py:658 msgid "Delete\tDEL" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:579 +#: flatcamGUI/FlatCAMGUI.py:619 msgid "Move Drill(s)\tM" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:584 +#: flatcamGUI/FlatCAMGUI.py:624 msgid ">Gerber Editor<" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:588 +#: flatcamGUI/FlatCAMGUI.py:628 msgid "Add Pad\tP" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:590 +#: flatcamGUI/FlatCAMGUI.py:630 msgid "Add Pad Array\tA" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:592 +#: flatcamGUI/FlatCAMGUI.py:632 msgid "Add Track\tT" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:594 +#: flatcamGUI/FlatCAMGUI.py:634 msgid "Add Region\tN" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:598 +#: flatcamGUI/FlatCAMGUI.py:638 msgid "Poligonize\tAlt+N" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:600 +#: flatcamGUI/FlatCAMGUI.py:640 msgid "Add SemiDisc\tE" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:602 +#: flatcamGUI/FlatCAMGUI.py:642 msgid "Add Disc\tD" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:604 +#: flatcamGUI/FlatCAMGUI.py:644 msgid "Buffer\tB" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:606 +#: flatcamGUI/FlatCAMGUI.py:646 msgid "Scale\tS" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:608 +#: flatcamGUI/FlatCAMGUI.py:648 msgid "Mark Area\tAlt+A" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:610 +#: flatcamGUI/FlatCAMGUI.py:650 msgid "Eraser\tCtrl+E" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:612 +#: flatcamGUI/FlatCAMGUI.py:652 msgid "Transform\tAlt+R" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:639 +#: flatcamGUI/FlatCAMGUI.py:679 msgid "Enable Plot" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:641 +#: flatcamGUI/FlatCAMGUI.py:681 msgid "Disable Plot" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:645 +#: flatcamGUI/FlatCAMGUI.py:685 msgid "Set Color" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:648 -msgid "Red" -msgstr "" - -#: flatcamGUI/FlatCAMGUI.py:651 -msgid "Blue" -msgstr "" - -#: flatcamGUI/FlatCAMGUI.py:654 -msgid "Yellow" -msgstr "" - -#: flatcamGUI/FlatCAMGUI.py:657 -msgid "Green" -msgstr "" - -#: flatcamGUI/FlatCAMGUI.py:660 -msgid "Purple" -msgstr "" - -#: flatcamGUI/FlatCAMGUI.py:663 -msgid "Brown" -msgstr "" - -#: flatcamGUI/FlatCAMGUI.py:666 -msgid "Custom" -msgstr "" - -#: flatcamGUI/FlatCAMGUI.py:671 +#: flatcamGUI/FlatCAMGUI.py:727 msgid "Generate CNC" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:673 +#: flatcamGUI/FlatCAMGUI.py:729 msgid "View Source" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:686 flatcamGUI/FlatCAMGUI.py:2172 -#: flatcamTools/ToolProperties.py:30 +#: flatcamGUI/FlatCAMGUI.py:742 flatcamGUI/FlatCAMGUI.py:2280 +#: flatcamTools/ToolProperties.py:31 msgid "Properties" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:715 +#: flatcamGUI/FlatCAMGUI.py:771 msgid "File Toolbar" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:719 +#: flatcamGUI/FlatCAMGUI.py:775 msgid "Edit Toolbar" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:723 +#: flatcamGUI/FlatCAMGUI.py:779 msgid "View Toolbar" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:727 +#: flatcamGUI/FlatCAMGUI.py:783 msgid "Shell Toolbar" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:731 +#: flatcamGUI/FlatCAMGUI.py:787 msgid "Tools Toolbar" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:735 +#: flatcamGUI/FlatCAMGUI.py:791 msgid "Excellon Editor Toolbar" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:741 +#: flatcamGUI/FlatCAMGUI.py:797 msgid "Geometry Editor Toolbar" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:745 +#: flatcamGUI/FlatCAMGUI.py:801 msgid "Gerber Editor Toolbar" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:749 +#: flatcamGUI/FlatCAMGUI.py:805 msgid "Grid Toolbar" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:772 flatcamGUI/FlatCAMGUI.py:2357 +#: flatcamGUI/FlatCAMGUI.py:826 flatcamGUI/FlatCAMGUI.py:2509 msgid "Open project" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:774 flatcamGUI/FlatCAMGUI.py:2359 +#: flatcamGUI/FlatCAMGUI.py:828 flatcamGUI/FlatCAMGUI.py:2511 msgid "Save project" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:780 flatcamGUI/FlatCAMGUI.py:2363 +#: flatcamGUI/FlatCAMGUI.py:834 flatcamGUI/FlatCAMGUI.py:2517 msgid "New Blank Geometry" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:782 flatcamGUI/FlatCAMGUI.py:2365 +#: flatcamGUI/FlatCAMGUI.py:836 flatcamGUI/FlatCAMGUI.py:2519 msgid "New Blank Gerber" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:784 flatcamGUI/FlatCAMGUI.py:2367 +#: flatcamGUI/FlatCAMGUI.py:838 flatcamGUI/FlatCAMGUI.py:2521 msgid "New Blank Excellon" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:789 flatcamGUI/FlatCAMGUI.py:2373 +#: flatcamGUI/FlatCAMGUI.py:843 flatcamGUI/FlatCAMGUI.py:2527 msgid "Save Object and close the Editor" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:796 flatcamGUI/FlatCAMGUI.py:2380 +#: flatcamGUI/FlatCAMGUI.py:850 flatcamGUI/FlatCAMGUI.py:2534 msgid "&Delete" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:799 flatcamGUI/FlatCAMGUI.py:1613 flatcamGUI/FlatCAMGUI.py:1812 -#: flatcamGUI/FlatCAMGUI.py:2383 flatcamTools/ToolDistance.py:30 -#: flatcamTools/ToolDistance.py:160 +#: flatcamGUI/FlatCAMGUI.py:853 flatcamGUI/FlatCAMGUI.py:1714 flatcamGUI/FlatCAMGUI.py:1920 +#: flatcamGUI/FlatCAMGUI.py:2537 flatcamTools/ToolDistance.py:35 +#: flatcamTools/ToolDistance.py:195 msgid "Distance Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:801 flatcamGUI/FlatCAMGUI.py:2385 +#: flatcamGUI/FlatCAMGUI.py:855 flatcamGUI/FlatCAMGUI.py:2539 msgid "Distance Min Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:803 flatcamGUI/FlatCAMGUI.py:1606 flatcamGUI/FlatCAMGUI.py:2387 +#: flatcamGUI/FlatCAMGUI.py:857 flatcamGUI/FlatCAMGUI.py:1707 flatcamGUI/FlatCAMGUI.py:2541 msgid "Set Origin" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:805 flatcamGUI/FlatCAMGUI.py:2389 +#: flatcamGUI/FlatCAMGUI.py:859 +msgid "Move to Origin" +msgstr "" + +#: flatcamGUI/FlatCAMGUI.py:862 flatcamGUI/FlatCAMGUI.py:2543 msgid "Jump to Location" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:811 flatcamGUI/FlatCAMGUI.py:2393 +#: flatcamGUI/FlatCAMGUI.py:864 flatcamGUI/FlatCAMGUI.py:1719 flatcamGUI/FlatCAMGUI.py:2545 +msgid "Locate in Object" +msgstr "" + +#: flatcamGUI/FlatCAMGUI.py:870 flatcamGUI/FlatCAMGUI.py:2551 msgid "&Replot" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:813 flatcamGUI/FlatCAMGUI.py:2395 +#: flatcamGUI/FlatCAMGUI.py:872 flatcamGUI/FlatCAMGUI.py:2553 msgid "&Clear plot" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:815 flatcamGUI/FlatCAMGUI.py:1609 flatcamGUI/FlatCAMGUI.py:2397 +#: flatcamGUI/FlatCAMGUI.py:874 flatcamGUI/FlatCAMGUI.py:1710 flatcamGUI/FlatCAMGUI.py:2555 msgid "Zoom In" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:817 flatcamGUI/FlatCAMGUI.py:1609 flatcamGUI/FlatCAMGUI.py:2399 +#: flatcamGUI/FlatCAMGUI.py:876 flatcamGUI/FlatCAMGUI.py:1710 flatcamGUI/FlatCAMGUI.py:2557 msgid "Zoom Out" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:819 flatcamGUI/FlatCAMGUI.py:1608 flatcamGUI/FlatCAMGUI.py:2062 -#: flatcamGUI/FlatCAMGUI.py:2401 +#: flatcamGUI/FlatCAMGUI.py:878 flatcamGUI/FlatCAMGUI.py:1709 flatcamGUI/FlatCAMGUI.py:2170 +#: flatcamGUI/FlatCAMGUI.py:2559 msgid "Zoom Fit" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:827 flatcamGUI/FlatCAMGUI.py:2407 +#: flatcamGUI/FlatCAMGUI.py:886 flatcamGUI/FlatCAMGUI.py:2565 msgid "&Command Line" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:839 flatcamGUI/FlatCAMGUI.py:2417 +#: flatcamGUI/FlatCAMGUI.py:898 flatcamGUI/FlatCAMGUI.py:2577 msgid "2Sided Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:841 flatcamGUI/ObjectUI.py:588 flatcamTools/ToolCutOut.py:436 +#: flatcamGUI/FlatCAMGUI.py:900 flatcamGUI/FlatCAMGUI.py:1725 flatcamGUI/FlatCAMGUI.py:2579 +msgid "Align Objects Tool" +msgstr "" + +#: flatcamGUI/FlatCAMGUI.py:902 flatcamGUI/FlatCAMGUI.py:1726 flatcamGUI/FlatCAMGUI.py:2581 +#: flatcamTools/ToolExtractDrills.py:393 +msgid "Extract Drills Tool" +msgstr "" + +#: flatcamGUI/FlatCAMGUI.py:905 flatcamGUI/ObjectUI.py:595 flatcamTools/ToolCutOut.py:447 msgid "Cutout Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:843 flatcamGUI/FlatCAMGUI.py:2421 flatcamGUI/ObjectUI.py:566 -#: flatcamGUI/ObjectUI.py:1749 flatcamTools/ToolNonCopperClear.py:632 +#: flatcamGUI/FlatCAMGUI.py:907 flatcamGUI/FlatCAMGUI.py:2586 flatcamGUI/ObjectUI.py:573 +#: flatcamGUI/ObjectUI.py:2075 flatcamTools/ToolNCC.py:972 msgid "NCC Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:849 flatcamGUI/FlatCAMGUI.py:2427 +#: flatcamGUI/FlatCAMGUI.py:913 flatcamGUI/FlatCAMGUI.py:2592 msgid "Panel Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:851 flatcamGUI/FlatCAMGUI.py:2429 flatcamTools/ToolFilm.py:578 +#: flatcamGUI/FlatCAMGUI.py:915 flatcamGUI/FlatCAMGUI.py:2594 flatcamTools/ToolFilm.py:586 msgid "Film Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:853 flatcamGUI/FlatCAMGUI.py:2432 -#: flatcamTools/ToolSolderPaste.py:547 +#: flatcamGUI/FlatCAMGUI.py:917 flatcamGUI/FlatCAMGUI.py:2596 +#: flatcamTools/ToolSolderPaste.py:553 msgid "SolderPaste Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:855 flatcamGUI/FlatCAMGUI.py:2434 flatcamTools/ToolSub.py:35 +#: flatcamGUI/FlatCAMGUI.py:919 flatcamGUI/FlatCAMGUI.py:2598 flatcamTools/ToolSub.py:35 msgid "Subtract Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:857 flatcamTools/ToolRulesCheck.py:607 +#: flatcamGUI/FlatCAMGUI.py:921 flatcamGUI/FlatCAMGUI.py:2600 +#: flatcamTools/ToolRulesCheck.py:616 msgid "Rules Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:859 flatcamGUI/FlatCAMGUI.py:1624 flatcamTools/ToolOptimal.py:34 -#: flatcamTools/ToolOptimal.py:310 +#: flatcamGUI/FlatCAMGUI.py:923 flatcamGUI/FlatCAMGUI.py:1728 flatcamGUI/FlatCAMGUI.py:2602 +#: flatcamTools/ToolOptimal.py:34 flatcamTools/ToolOptimal.py:308 msgid "Optimal Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:864 flatcamGUI/FlatCAMGUI.py:1622 flatcamGUI/FlatCAMGUI.py:2439 +#: flatcamGUI/FlatCAMGUI.py:928 flatcamGUI/FlatCAMGUI.py:1725 flatcamGUI/FlatCAMGUI.py:2607 msgid "Calculators Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:868 flatcamGUI/FlatCAMGUI.py:1625 flatcamGUI/FlatCAMGUI.py:2443 +#: flatcamGUI/FlatCAMGUI.py:932 flatcamGUI/FlatCAMGUI.py:1729 flatcamGUI/FlatCAMGUI.py:2611 #: flatcamTools/ToolQRCode.py:43 flatcamTools/ToolQRCode.py:382 msgid "QRCode Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:870 flatcamGUI/FlatCAMGUI.py:2445 -#: flatcamTools/ToolCopperThieving.py:40 flatcamTools/ToolCopperThieving.py:566 +#: flatcamGUI/FlatCAMGUI.py:934 flatcamGUI/FlatCAMGUI.py:2613 +#: flatcamTools/ToolCopperThieving.py:40 flatcamTools/ToolCopperThieving.py:569 msgid "Copper Thieving Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:873 flatcamGUI/FlatCAMGUI.py:1622 flatcamGUI/FlatCAMGUI.py:2448 -#: flatcamTools/ToolFiducials.py:33 flatcamTools/ToolFiducials.py:393 +#: flatcamGUI/FlatCAMGUI.py:937 flatcamGUI/FlatCAMGUI.py:1726 flatcamGUI/FlatCAMGUI.py:2616 +#: flatcamTools/ToolFiducials.py:33 flatcamTools/ToolFiducials.py:395 msgid "Fiducials Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:875 flatcamGUI/FlatCAMGUI.py:2450 -#: flatcamTools/ToolCalibration.py:37 flatcamTools/ToolCalibration.py:762 +#: flatcamGUI/FlatCAMGUI.py:939 flatcamGUI/FlatCAMGUI.py:2618 +#: flatcamTools/ToolCalibration.py:37 flatcamTools/ToolCalibration.py:759 msgid "Calibration Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:881 flatcamGUI/FlatCAMGUI.py:907 flatcamGUI/FlatCAMGUI.py:959 -#: flatcamGUI/FlatCAMGUI.py:2454 flatcamGUI/FlatCAMGUI.py:2528 +#: flatcamGUI/FlatCAMGUI.py:941 flatcamGUI/FlatCAMGUI.py:1726 +msgid "Punch Gerber Tool" +msgstr "" + +#: flatcamGUI/FlatCAMGUI.py:943 flatcamTools/ToolInvertGerber.py:31 +msgid "Invert Gerber Tool" +msgstr "" + +#: flatcamGUI/FlatCAMGUI.py:949 flatcamGUI/FlatCAMGUI.py:975 flatcamGUI/FlatCAMGUI.py:1027 +#: flatcamGUI/FlatCAMGUI.py:2624 flatcamGUI/FlatCAMGUI.py:2702 msgid "Select" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:883 flatcamGUI/FlatCAMGUI.py:2456 +#: flatcamGUI/FlatCAMGUI.py:951 flatcamGUI/FlatCAMGUI.py:2626 msgid "Add Drill Hole" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:885 flatcamGUI/FlatCAMGUI.py:2458 +#: flatcamGUI/FlatCAMGUI.py:953 flatcamGUI/FlatCAMGUI.py:2628 msgid "Add Drill Hole Array" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:887 flatcamGUI/FlatCAMGUI.py:1897 flatcamGUI/FlatCAMGUI.py:2150 -#: flatcamGUI/FlatCAMGUI.py:2462 +#: flatcamGUI/FlatCAMGUI.py:955 flatcamGUI/FlatCAMGUI.py:2005 flatcamGUI/FlatCAMGUI.py:2258 +#: flatcamGUI/FlatCAMGUI.py:2632 msgid "Add Slot" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:889 flatcamGUI/FlatCAMGUI.py:1896 flatcamGUI/FlatCAMGUI.py:2152 -#: flatcamGUI/FlatCAMGUI.py:2464 +#: flatcamGUI/FlatCAMGUI.py:957 flatcamGUI/FlatCAMGUI.py:2004 flatcamGUI/FlatCAMGUI.py:2260 +#: flatcamGUI/FlatCAMGUI.py:2634 msgid "Add Slot Array" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:891 flatcamGUI/FlatCAMGUI.py:2155 flatcamGUI/FlatCAMGUI.py:2460 +#: flatcamGUI/FlatCAMGUI.py:959 flatcamGUI/FlatCAMGUI.py:2263 flatcamGUI/FlatCAMGUI.py:2630 msgid "Resize Drill" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:895 flatcamGUI/FlatCAMGUI.py:2468 +#: flatcamGUI/FlatCAMGUI.py:963 flatcamGUI/FlatCAMGUI.py:2638 msgid "Copy Drill" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:897 flatcamGUI/FlatCAMGUI.py:2470 +#: flatcamGUI/FlatCAMGUI.py:965 flatcamGUI/FlatCAMGUI.py:2640 msgid "Delete Drill" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:901 flatcamGUI/FlatCAMGUI.py:2474 +#: flatcamGUI/FlatCAMGUI.py:969 flatcamGUI/FlatCAMGUI.py:2644 msgid "Move Drill" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:909 flatcamGUI/FlatCAMGUI.py:2480 +#: flatcamGUI/FlatCAMGUI.py:977 flatcamGUI/FlatCAMGUI.py:2652 msgid "Add Circle" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:911 flatcamGUI/FlatCAMGUI.py:2482 +#: flatcamGUI/FlatCAMGUI.py:979 flatcamGUI/FlatCAMGUI.py:2654 msgid "Add Arc" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:913 flatcamGUI/FlatCAMGUI.py:2484 +#: flatcamGUI/FlatCAMGUI.py:981 flatcamGUI/FlatCAMGUI.py:2656 msgid "Add Rectangle" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:917 flatcamGUI/FlatCAMGUI.py:2488 +#: flatcamGUI/FlatCAMGUI.py:985 flatcamGUI/FlatCAMGUI.py:2660 msgid "Add Path" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:919 flatcamGUI/FlatCAMGUI.py:2490 +#: flatcamGUI/FlatCAMGUI.py:987 flatcamGUI/FlatCAMGUI.py:2662 msgid "Add Polygon" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:922 flatcamGUI/FlatCAMGUI.py:2493 +#: flatcamGUI/FlatCAMGUI.py:990 flatcamGUI/FlatCAMGUI.py:2665 msgid "Add Text" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:924 flatcamGUI/FlatCAMGUI.py:2495 +#: flatcamGUI/FlatCAMGUI.py:992 flatcamGUI/FlatCAMGUI.py:2667 msgid "Add Buffer" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:926 flatcamGUI/FlatCAMGUI.py:2497 +#: flatcamGUI/FlatCAMGUI.py:994 flatcamGUI/FlatCAMGUI.py:2669 msgid "Paint Shape" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:928 flatcamGUI/FlatCAMGUI.py:985 flatcamGUI/FlatCAMGUI.py:2091 -#: flatcamGUI/FlatCAMGUI.py:2136 flatcamGUI/FlatCAMGUI.py:2499 flatcamGUI/FlatCAMGUI.py:2553 +#: flatcamGUI/FlatCAMGUI.py:996 flatcamGUI/FlatCAMGUI.py:1053 flatcamGUI/FlatCAMGUI.py:2199 +#: flatcamGUI/FlatCAMGUI.py:2244 flatcamGUI/FlatCAMGUI.py:2671 flatcamGUI/FlatCAMGUI.py:2727 msgid "Eraser" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:932 flatcamGUI/FlatCAMGUI.py:2503 +#: flatcamGUI/FlatCAMGUI.py:1000 flatcamGUI/FlatCAMGUI.py:2675 msgid "Polygon Union" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:934 flatcamGUI/FlatCAMGUI.py:2505 +#: flatcamGUI/FlatCAMGUI.py:1002 flatcamGUI/FlatCAMGUI.py:2677 msgid "Polygon Explode" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:937 flatcamGUI/FlatCAMGUI.py:2508 +#: flatcamGUI/FlatCAMGUI.py:1005 flatcamGUI/FlatCAMGUI.py:2680 msgid "Polygon Intersection" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:939 flatcamGUI/FlatCAMGUI.py:2510 +#: flatcamGUI/FlatCAMGUI.py:1007 flatcamGUI/FlatCAMGUI.py:2682 msgid "Polygon Subtraction" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:943 flatcamGUI/FlatCAMGUI.py:2514 +#: flatcamGUI/FlatCAMGUI.py:1011 flatcamGUI/FlatCAMGUI.py:2686 msgid "Cut Path" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:945 +#: flatcamGUI/FlatCAMGUI.py:1013 msgid "Copy Shape(s)" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:948 +#: flatcamGUI/FlatCAMGUI.py:1016 msgid "Delete Shape '-'" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:950 flatcamGUI/FlatCAMGUI.py:993 flatcamGUI/FlatCAMGUI.py:2103 -#: flatcamGUI/FlatCAMGUI.py:2140 flatcamGUI/FlatCAMGUI.py:2520 flatcamGUI/FlatCAMGUI.py:2561 +#: flatcamGUI/FlatCAMGUI.py:1018 flatcamGUI/FlatCAMGUI.py:1061 flatcamGUI/FlatCAMGUI.py:2211 +#: flatcamGUI/FlatCAMGUI.py:2248 flatcamGUI/FlatCAMGUI.py:2692 flatcamGUI/FlatCAMGUI.py:2735 +#: flatcamGUI/ObjectUI.py:108 msgid "Transformations" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:953 +#: flatcamGUI/FlatCAMGUI.py:1021 msgid "Move Objects " msgstr "" -#: flatcamGUI/FlatCAMGUI.py:961 flatcamGUI/FlatCAMGUI.py:2016 flatcamGUI/FlatCAMGUI.py:2530 +#: flatcamGUI/FlatCAMGUI.py:1029 flatcamGUI/FlatCAMGUI.py:2124 flatcamGUI/FlatCAMGUI.py:2704 msgid "Add Pad" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:965 flatcamGUI/FlatCAMGUI.py:2017 flatcamGUI/FlatCAMGUI.py:2534 +#: flatcamGUI/FlatCAMGUI.py:1033 flatcamGUI/FlatCAMGUI.py:2125 flatcamGUI/FlatCAMGUI.py:2708 msgid "Add Track" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:967 flatcamGUI/FlatCAMGUI.py:2016 flatcamGUI/FlatCAMGUI.py:2536 +#: flatcamGUI/FlatCAMGUI.py:1035 flatcamGUI/FlatCAMGUI.py:2124 flatcamGUI/FlatCAMGUI.py:2710 msgid "Add Region" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:969 flatcamGUI/FlatCAMGUI.py:2122 flatcamGUI/FlatCAMGUI.py:2538 +#: flatcamGUI/FlatCAMGUI.py:1037 flatcamGUI/FlatCAMGUI.py:2230 flatcamGUI/FlatCAMGUI.py:2712 msgid "Poligonize" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:972 flatcamGUI/FlatCAMGUI.py:2124 flatcamGUI/FlatCAMGUI.py:2541 +#: flatcamGUI/FlatCAMGUI.py:1040 flatcamGUI/FlatCAMGUI.py:2232 flatcamGUI/FlatCAMGUI.py:2715 msgid "SemiDisc" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:974 flatcamGUI/FlatCAMGUI.py:2126 flatcamGUI/FlatCAMGUI.py:2543 +#: flatcamGUI/FlatCAMGUI.py:1042 flatcamGUI/FlatCAMGUI.py:2234 flatcamGUI/FlatCAMGUI.py:2717 msgid "Disc" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:982 flatcamGUI/FlatCAMGUI.py:2134 flatcamGUI/FlatCAMGUI.py:2551 +#: flatcamGUI/FlatCAMGUI.py:1050 flatcamGUI/FlatCAMGUI.py:2242 flatcamGUI/FlatCAMGUI.py:2725 msgid "Mark Area" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:996 flatcamGUI/FlatCAMGUI.py:2016 flatcamGUI/FlatCAMGUI.py:2107 -#: flatcamGUI/FlatCAMGUI.py:2170 flatcamGUI/FlatCAMGUI.py:2564 flatcamTools/ToolMove.py:28 +#: flatcamGUI/FlatCAMGUI.py:1064 flatcamGUI/FlatCAMGUI.py:2124 flatcamGUI/FlatCAMGUI.py:2215 +#: flatcamGUI/FlatCAMGUI.py:2278 flatcamGUI/FlatCAMGUI.py:2738 flatcamTools/ToolMove.py:28 msgid "Move" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1004 flatcamGUI/FlatCAMGUI.py:2571 +#: flatcamGUI/FlatCAMGUI.py:1072 flatcamGUI/FlatCAMGUI.py:2747 msgid "Snap to grid" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1007 flatcamGUI/FlatCAMGUI.py:2574 +#: flatcamGUI/FlatCAMGUI.py:1075 flatcamGUI/FlatCAMGUI.py:2750 msgid "Grid X snapping distance" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1012 flatcamGUI/FlatCAMGUI.py:2579 +#: flatcamGUI/FlatCAMGUI.py:1080 flatcamGUI/FlatCAMGUI.py:2755 msgid "Grid Y snapping distance" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1018 flatcamGUI/FlatCAMGUI.py:2585 +#: flatcamGUI/FlatCAMGUI.py:1086 flatcamGUI/FlatCAMGUI.py:2761 msgid "" "When active, value on Grid_X\n" "is copied to the Grid_Y value." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1025 flatcamGUI/FlatCAMGUI.py:2592 +#: flatcamGUI/FlatCAMGUI.py:1093 flatcamGUI/FlatCAMGUI.py:2768 msgid "Snap to corner" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1029 flatcamGUI/FlatCAMGUI.py:2596 -#: flatcamGUI/PreferencesUI.py:984 +#: flatcamGUI/FlatCAMGUI.py:1097 flatcamGUI/FlatCAMGUI.py:2772 +#: flatcamGUI/PreferencesUI.py:1159 msgid "Max. magnet distance" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1063 +#: flatcamGUI/FlatCAMGUI.py:1134 msgid "Selected" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1090 flatcamGUI/FlatCAMGUI.py:1098 +#: flatcamGUI/FlatCAMGUI.py:1162 flatcamGUI/FlatCAMGUI.py:1170 msgid "Plot Area" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1125 +#: flatcamGUI/FlatCAMGUI.py:1197 msgid "General" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1140 flatcamTools/ToolCopperThieving.py:74 -#: flatcamTools/ToolDblSided.py:59 flatcamTools/ToolOptimal.py:71 -#: flatcamTools/ToolQRCode.py:77 +#: flatcamGUI/FlatCAMGUI.py:1212 flatcamTools/ToolCopperThieving.py:75 +#: flatcamTools/ToolDblSided.py:65 flatcamTools/ToolExtractDrills.py:61 +#: flatcamTools/ToolInvertGerber.py:72 flatcamTools/ToolOptimal.py:72 +#: flatcamTools/ToolPunchGerber.py:64 msgid "GERBER" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1150 flatcamTools/ToolDblSided.py:87 +#: flatcamGUI/FlatCAMGUI.py:1222 flatcamTools/ToolDblSided.py:93 msgid "EXCELLON" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1160 flatcamTools/ToolDblSided.py:115 +#: flatcamGUI/FlatCAMGUI.py:1232 flatcamTools/ToolDblSided.py:121 msgid "GEOMETRY" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1170 +#: flatcamGUI/FlatCAMGUI.py:1242 msgid "CNC-JOB" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1179 flatcamGUI/ObjectUI.py:555 flatcamGUI/ObjectUI.py:1724 +#: flatcamGUI/FlatCAMGUI.py:1251 flatcamGUI/ObjectUI.py:562 flatcamGUI/ObjectUI.py:2050 msgid "TOOLS" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1188 +#: flatcamGUI/FlatCAMGUI.py:1260 msgid "TOOLS 2" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1198 +#: flatcamGUI/FlatCAMGUI.py:1270 msgid "UTILITIES" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1215 flatcamGUI/PreferencesUI.py:2833 +#: flatcamGUI/FlatCAMGUI.py:1287 flatcamGUI/PreferencesUI.py:3015 msgid "Restore Defaults" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1218 +#: flatcamGUI/FlatCAMGUI.py:1290 msgid "" "Restore the entire set of default values\n" "to the initial values loaded after first launch." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1223 +#: flatcamGUI/FlatCAMGUI.py:1295 msgid "Open Pref Folder" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1226 +#: flatcamGUI/FlatCAMGUI.py:1298 msgid "Open the folder where FlatCAM save the preferences files." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1234 +#: flatcamGUI/FlatCAMGUI.py:1302 flatcamGUI/FlatCAMGUI.py:2477 +msgid "Clear GUI Settings" +msgstr "" + +#: flatcamGUI/FlatCAMGUI.py:1306 msgid "" "Clear the GUI settings for FlatCAM,\n" "such as: layout, gui state, style, hdpi support etc." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1245 +#: flatcamGUI/FlatCAMGUI.py:1317 msgid "Apply" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1248 +#: flatcamGUI/FlatCAMGUI.py:1320 msgid "Apply the current preferences without saving to a file." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1255 +#: flatcamGUI/FlatCAMGUI.py:1327 msgid "" "Save the current settings in the 'current_defaults' file\n" "which is the file storing the working default preferences." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1263 +#: flatcamGUI/FlatCAMGUI.py:1335 msgid "Will not save the changes and will close the preferences window." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1603 +#: flatcamGUI/FlatCAMGUI.py:1704 msgid "SHOW SHORTCUT LIST" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1603 +#: flatcamGUI/FlatCAMGUI.py:1704 msgid "Switch to Project Tab" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1603 +#: flatcamGUI/FlatCAMGUI.py:1704 msgid "Switch to Selected Tab" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1604 +#: flatcamGUI/FlatCAMGUI.py:1705 msgid "Switch to Tool Tab" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1605 +#: flatcamGUI/FlatCAMGUI.py:1706 msgid "New Gerber" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1605 +#: flatcamGUI/FlatCAMGUI.py:1706 msgid "Edit Object (if selected)" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1605 +#: flatcamGUI/FlatCAMGUI.py:1706 msgid "Jump to Coordinates" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1606 +#: flatcamGUI/FlatCAMGUI.py:1707 msgid "New Excellon" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1606 +#: flatcamGUI/FlatCAMGUI.py:1707 msgid "Move Obj" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1606 +#: flatcamGUI/FlatCAMGUI.py:1707 msgid "New Geometry" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1606 +#: flatcamGUI/FlatCAMGUI.py:1707 msgid "Change Units" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1607 +#: flatcamGUI/FlatCAMGUI.py:1708 msgid "Open Properties Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1607 +#: flatcamGUI/FlatCAMGUI.py:1708 msgid "Rotate by 90 degree CW" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1607 +#: flatcamGUI/FlatCAMGUI.py:1708 msgid "Shell Toggle" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1608 +#: flatcamGUI/FlatCAMGUI.py:1709 msgid "Add a Tool (when in Geometry Selected Tab or in Tools NCC or Tools Paint)" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1609 +#: flatcamGUI/FlatCAMGUI.py:1710 msgid "Flip on X_axis" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1609 +#: flatcamGUI/FlatCAMGUI.py:1710 msgid "Flip on Y_axis" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1612 +#: flatcamGUI/FlatCAMGUI.py:1713 msgid "Copy Obj" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1612 +#: flatcamGUI/FlatCAMGUI.py:1713 msgid "Open Tools Database" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1613 +#: flatcamGUI/FlatCAMGUI.py:1714 msgid "Open Excellon File" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1613 +#: flatcamGUI/FlatCAMGUI.py:1714 msgid "Open Gerber File" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1613 +#: flatcamGUI/FlatCAMGUI.py:1714 msgid "New Project" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1614 flatcamTools/ToolPDF.py:42 +#: flatcamGUI/FlatCAMGUI.py:1715 flatcamTools/ToolPDF.py:42 msgid "PDF Import Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1614 -msgid "Save Project As" +#: flatcamGUI/FlatCAMGUI.py:1715 +msgid "Save Project" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1614 +#: flatcamGUI/FlatCAMGUI.py:1715 msgid "Toggle Plot Area" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1617 +#: flatcamGUI/FlatCAMGUI.py:1718 msgid "Copy Obj_Name" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1618 +#: flatcamGUI/FlatCAMGUI.py:1719 msgid "Toggle Code Editor" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1618 +#: flatcamGUI/FlatCAMGUI.py:1719 msgid "Toggle the axis" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1618 flatcamGUI/FlatCAMGUI.py:1810 flatcamGUI/FlatCAMGUI.py:1897 -#: flatcamGUI/FlatCAMGUI.py:2019 +#: flatcamGUI/FlatCAMGUI.py:1719 flatcamGUI/FlatCAMGUI.py:1918 flatcamGUI/FlatCAMGUI.py:2005 +#: flatcamGUI/FlatCAMGUI.py:2127 msgid "Distance Minimum Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1618 +#: flatcamGUI/FlatCAMGUI.py:1720 msgid "Open Preferences Window" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1619 +#: flatcamGUI/FlatCAMGUI.py:1721 msgid "Rotate by 90 degree CCW" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1619 +#: flatcamGUI/FlatCAMGUI.py:1721 msgid "Run a Script" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1619 +#: flatcamGUI/FlatCAMGUI.py:1721 msgid "Toggle the workspace" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1619 +#: flatcamGUI/FlatCAMGUI.py:1721 msgid "Skew on X axis" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1620 +#: flatcamGUI/FlatCAMGUI.py:1722 msgid "Skew on Y axis" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1622 +#: flatcamGUI/FlatCAMGUI.py:1725 msgid "2-Sided PCB Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1622 +#: flatcamGUI/FlatCAMGUI.py:1725 msgid "Transformations Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1623 +#: flatcamGUI/FlatCAMGUI.py:1727 msgid "Solder Paste Dispensing Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1624 +#: flatcamGUI/FlatCAMGUI.py:1728 msgid "Film PCB Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1624 +#: flatcamGUI/FlatCAMGUI.py:1728 msgid "Non-Copper Clearing Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1625 +#: flatcamGUI/FlatCAMGUI.py:1729 msgid "Paint Area Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1625 +#: flatcamGUI/FlatCAMGUI.py:1729 msgid "Rules Check Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1626 +#: flatcamGUI/FlatCAMGUI.py:1730 msgid "View File Source" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1627 +#: flatcamGUI/FlatCAMGUI.py:1731 msgid "Cutout PCB Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1627 +#: flatcamGUI/FlatCAMGUI.py:1731 msgid "Enable all Plots" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1627 +#: flatcamGUI/FlatCAMGUI.py:1731 msgid "Disable all Plots" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1627 +#: flatcamGUI/FlatCAMGUI.py:1731 msgid "Disable Non-selected Plots" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1628 +#: flatcamGUI/FlatCAMGUI.py:1732 msgid "Toggle Full Screen" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1631 +#: flatcamGUI/FlatCAMGUI.py:1735 msgid "Abort current task (gracefully)" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1634 +#: flatcamGUI/FlatCAMGUI.py:1738 +msgid "Save Project As" +msgstr "" + +#: flatcamGUI/FlatCAMGUI.py:1739 +msgid "Paste Special. Will convert a Windows path style to the one required in Tcl Shell" +msgstr "" + +#: flatcamGUI/FlatCAMGUI.py:1742 msgid "Open Online Manual" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1635 +#: flatcamGUI/FlatCAMGUI.py:1743 msgid "Open Online Tutorials" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1635 +#: flatcamGUI/FlatCAMGUI.py:1743 msgid "Refresh Plots" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1635 flatcamTools/ToolSolderPaste.py:503 +#: flatcamGUI/FlatCAMGUI.py:1743 flatcamTools/ToolSolderPaste.py:509 msgid "Delete Object" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1635 +#: flatcamGUI/FlatCAMGUI.py:1743 msgid "Alternate: Delete Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1636 +#: flatcamGUI/FlatCAMGUI.py:1744 msgid "(left to Key_1)Toogle Notebook Area (Left Side)" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1636 +#: flatcamGUI/FlatCAMGUI.py:1744 msgid "En(Dis)able Obj Plot" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1637 +#: flatcamGUI/FlatCAMGUI.py:1745 msgid "Deselects all objects" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1651 +#: flatcamGUI/FlatCAMGUI.py:1759 msgid "Editor Shortcut list" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1805 +#: flatcamGUI/FlatCAMGUI.py:1913 msgid "GEOMETRY EDITOR" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1805 +#: flatcamGUI/FlatCAMGUI.py:1913 msgid "Draw an Arc" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1805 +#: flatcamGUI/FlatCAMGUI.py:1913 msgid "Copy Geo Item" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1806 +#: flatcamGUI/FlatCAMGUI.py:1914 msgid "Within Add Arc will toogle the ARC direction: CW or CCW" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1806 +#: flatcamGUI/FlatCAMGUI.py:1914 msgid "Polygon Intersection Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1807 +#: flatcamGUI/FlatCAMGUI.py:1915 msgid "Geo Paint Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1807 flatcamGUI/FlatCAMGUI.py:1896 flatcamGUI/FlatCAMGUI.py:2016 +#: flatcamGUI/FlatCAMGUI.py:1915 flatcamGUI/FlatCAMGUI.py:2004 flatcamGUI/FlatCAMGUI.py:2124 msgid "Jump to Location (x, y)" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1807 +#: flatcamGUI/FlatCAMGUI.py:1915 msgid "Toggle Corner Snap" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1807 +#: flatcamGUI/FlatCAMGUI.py:1915 msgid "Move Geo Item" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1808 +#: flatcamGUI/FlatCAMGUI.py:1916 msgid "Within Add Arc will cycle through the ARC modes" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1808 +#: flatcamGUI/FlatCAMGUI.py:1916 msgid "Draw a Polygon" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1808 +#: flatcamGUI/FlatCAMGUI.py:1916 msgid "Draw a Circle" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1809 +#: flatcamGUI/FlatCAMGUI.py:1917 msgid "Draw a Path" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1809 +#: flatcamGUI/FlatCAMGUI.py:1917 msgid "Draw Rectangle" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1809 +#: flatcamGUI/FlatCAMGUI.py:1917 msgid "Polygon Subtraction Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1809 +#: flatcamGUI/FlatCAMGUI.py:1917 msgid "Add Text Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1810 +#: flatcamGUI/FlatCAMGUI.py:1918 msgid "Polygon Union Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1810 +#: flatcamGUI/FlatCAMGUI.py:1918 msgid "Flip shape on X axis" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1810 +#: flatcamGUI/FlatCAMGUI.py:1918 msgid "Flip shape on Y axis" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1811 +#: flatcamGUI/FlatCAMGUI.py:1919 msgid "Skew shape on X axis" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1811 +#: flatcamGUI/FlatCAMGUI.py:1919 msgid "Skew shape on Y axis" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1811 +#: flatcamGUI/FlatCAMGUI.py:1919 msgid "Editor Transformation Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1812 +#: flatcamGUI/FlatCAMGUI.py:1920 msgid "Offset shape on X axis" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1812 +#: flatcamGUI/FlatCAMGUI.py:1920 msgid "Offset shape on Y axis" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1813 flatcamGUI/FlatCAMGUI.py:1899 flatcamGUI/FlatCAMGUI.py:2021 +#: flatcamGUI/FlatCAMGUI.py:1921 flatcamGUI/FlatCAMGUI.py:2007 flatcamGUI/FlatCAMGUI.py:2129 msgid "Save Object and Exit Editor" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1813 +#: flatcamGUI/FlatCAMGUI.py:1921 msgid "Polygon Cut Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1814 +#: flatcamGUI/FlatCAMGUI.py:1922 msgid "Rotate Geometry" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1814 +#: flatcamGUI/FlatCAMGUI.py:1922 msgid "Finish drawing for certain tools" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1814 flatcamGUI/FlatCAMGUI.py:1899 flatcamGUI/FlatCAMGUI.py:2019 +#: flatcamGUI/FlatCAMGUI.py:1922 flatcamGUI/FlatCAMGUI.py:2007 flatcamGUI/FlatCAMGUI.py:2127 msgid "Abort and return to Select" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1815 flatcamGUI/FlatCAMGUI.py:2518 +#: flatcamGUI/FlatCAMGUI.py:1923 flatcamGUI/FlatCAMGUI.py:2690 msgid "Delete Shape" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1895 +#: flatcamGUI/FlatCAMGUI.py:2003 msgid "EXCELLON EDITOR" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1895 +#: flatcamGUI/FlatCAMGUI.py:2003 msgid "Copy Drill(s)" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1895 flatcamGUI/FlatCAMGUI.py:2145 +#: flatcamGUI/FlatCAMGUI.py:2003 flatcamGUI/FlatCAMGUI.py:2253 msgid "Add Drill" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1896 +#: flatcamGUI/FlatCAMGUI.py:2004 msgid "Move Drill(s)" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1897 +#: flatcamGUI/FlatCAMGUI.py:2005 msgid "Add a new Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1898 +#: flatcamGUI/FlatCAMGUI.py:2006 msgid "Delete Drill(s)" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:1898 +#: flatcamGUI/FlatCAMGUI.py:2006 msgid "Alternate: Delete Tool(s)" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2015 +#: flatcamGUI/FlatCAMGUI.py:2123 msgid "GERBER EDITOR" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2015 +#: flatcamGUI/FlatCAMGUI.py:2123 msgid "Add Disc" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2015 +#: flatcamGUI/FlatCAMGUI.py:2123 msgid "Add SemiDisc" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2017 +#: flatcamGUI/FlatCAMGUI.py:2125 msgid "Within Track & Region Tools will cycle in REVERSE the bend modes" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2018 +#: flatcamGUI/FlatCAMGUI.py:2126 msgid "Within Track & Region Tools will cycle FORWARD the bend modes" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2019 +#: flatcamGUI/FlatCAMGUI.py:2127 msgid "Alternate: Delete Apertures" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2020 +#: flatcamGUI/FlatCAMGUI.py:2128 msgid "Eraser Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2021 flatcamGUI/PreferencesUI.py:2634 +#: flatcamGUI/FlatCAMGUI.py:2129 flatcamGUI/PreferencesUI.py:2816 msgid "Mark Area Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2021 +#: flatcamGUI/FlatCAMGUI.py:2129 msgid "Poligonize Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2021 +#: flatcamGUI/FlatCAMGUI.py:2129 msgid "Transformation Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2038 +#: flatcamGUI/FlatCAMGUI.py:2146 msgid "Toggle Visibility" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2044 +#: flatcamGUI/FlatCAMGUI.py:2152 msgid "New" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2046 flatcamTools/ToolCalibration.py:634 -msgid "Geometry" -msgstr "" - -#: flatcamGUI/FlatCAMGUI.py:2050 flatcamTools/ToolCalibration.py:197 -#: flatcamTools/ToolCalibration.py:634 flatcamTools/ToolFilm.py:359 +#: flatcamGUI/FlatCAMGUI.py:2158 flatcamGUI/PreferencesUI.py:8410 +#: flatcamTools/ToolAlignObjects.py:74 flatcamTools/ToolAlignObjects.py:110 +#: flatcamTools/ToolCalibration.py:197 flatcamTools/ToolCalibration.py:631 +#: flatcamTools/ToolCalibration.py:648 flatcamTools/ToolCalibration.py:807 +#: flatcamTools/ToolCalibration.py:815 flatcamTools/ToolCopperThieving.py:145 +#: flatcamTools/ToolCopperThieving.py:159 flatcamTools/ToolCopperThieving.py:605 +#: flatcamTools/ToolDblSided.py:226 flatcamTools/ToolFilm.py:359 flatcamTools/ToolNCC.py:558 +#: flatcamTools/ToolNCC.py:1293 flatcamTools/ToolPaint.py:502 flatcamTools/ToolPaint.py:703 +#: flatcamTools/ToolPanelize.py:374 flatcamTools/ToolPunchGerber.py:149 +#: flatcamTools/ToolPunchGerber.py:164 msgid "Excellon" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2057 +#: flatcamGUI/FlatCAMGUI.py:2165 msgid "Grids" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2064 +#: flatcamGUI/FlatCAMGUI.py:2172 msgid "Clear Plot" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2066 +#: flatcamGUI/FlatCAMGUI.py:2174 msgid "Replot" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2070 +#: flatcamGUI/FlatCAMGUI.py:2178 msgid "Geo Editor" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2072 +#: flatcamGUI/FlatCAMGUI.py:2180 msgid "Path" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2074 +#: flatcamGUI/FlatCAMGUI.py:2182 msgid "Rectangle" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2077 +#: flatcamGUI/FlatCAMGUI.py:2185 msgid "Circle" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2079 -msgid "Polygon" -msgstr "" - -#: flatcamGUI/FlatCAMGUI.py:2081 +#: flatcamGUI/FlatCAMGUI.py:2189 msgid "Arc" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2095 +#: flatcamGUI/FlatCAMGUI.py:2203 msgid "Union" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2097 +#: flatcamGUI/FlatCAMGUI.py:2205 msgid "Intersection" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2099 +#: flatcamGUI/FlatCAMGUI.py:2207 msgid "Subtraction" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2101 flatcamGUI/ObjectUI.py:1811 -#: flatcamGUI/PreferencesUI.py:4421 +#: flatcamGUI/FlatCAMGUI.py:2209 flatcamGUI/ObjectUI.py:2139 +#: flatcamGUI/PreferencesUI.py:4714 msgid "Cut" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2112 +#: flatcamGUI/FlatCAMGUI.py:2220 msgid "Pad" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2114 +#: flatcamGUI/FlatCAMGUI.py:2222 msgid "Pad Array" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2118 +#: flatcamGUI/FlatCAMGUI.py:2226 msgid "Track" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2120 +#: flatcamGUI/FlatCAMGUI.py:2228 msgid "Region" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2143 +#: flatcamGUI/FlatCAMGUI.py:2251 msgid "Exc Editor" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2188 +#: flatcamGUI/FlatCAMGUI.py:2296 msgid "" "Relative neasurement.\n" "Reference is last click position" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2194 +#: flatcamGUI/FlatCAMGUI.py:2302 msgid "" "Absolute neasurement.\n" "Reference is (X=0, Y= 0) position" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2301 +#: flatcamGUI/FlatCAMGUI.py:2406 msgid "Lock Toolbars" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2419 +#: flatcamGUI/FlatCAMGUI.py:2465 +msgid "FlatCAM Preferences Folder opened." +msgstr "" + +#: flatcamGUI/FlatCAMGUI.py:2476 +msgid "Are you sure you want to delete the GUI Settings? \n" +msgstr "" + +#: flatcamGUI/FlatCAMGUI.py:2584 msgid "&Cutout Tool" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2478 +#: flatcamGUI/FlatCAMGUI.py:2650 msgid "Select 'Esc'" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2516 +#: flatcamGUI/FlatCAMGUI.py:2688 msgid "Copy Objects" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:2524 +#: flatcamGUI/FlatCAMGUI.py:2696 msgid "Move Objects" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:3087 +#: flatcamGUI/FlatCAMGUI.py:3312 msgid "" "Please first select a geometry item to be cutted\n" "then select the geometry item that will be cutted\n" @@ -6167,103 +6459,104 @@ msgid "" "the toolbar button." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:3094 flatcamGUI/FlatCAMGUI.py:3254 flatcamGUI/FlatCAMGUI.py:3299 -#: flatcamGUI/FlatCAMGUI.py:3319 +#: flatcamGUI/FlatCAMGUI.py:3319 flatcamGUI/FlatCAMGUI.py:3478 flatcamGUI/FlatCAMGUI.py:3523 +#: flatcamGUI/FlatCAMGUI.py:3543 msgid "Warning" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:3249 +#: flatcamGUI/FlatCAMGUI.py:3473 msgid "" "Please select geometry items \n" "on which to perform Intersection Tool." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:3294 +#: flatcamGUI/FlatCAMGUI.py:3518 msgid "" "Please select geometry items \n" "on which to perform Substraction Tool." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:3314 +#: flatcamGUI/FlatCAMGUI.py:3538 msgid "" "Please select geometry items \n" "on which to perform union." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:3394 flatcamGUI/FlatCAMGUI.py:3608 +#: flatcamGUI/FlatCAMGUI.py:3617 flatcamGUI/FlatCAMGUI.py:3828 msgid "Cancelled. Nothing selected to delete." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:3479 flatcamGUI/FlatCAMGUI.py:3726 +#: flatcamGUI/FlatCAMGUI.py:3701 flatcamGUI/FlatCAMGUI.py:3944 msgid "Cancelled. Nothing selected to copy." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:3526 flatcamGUI/FlatCAMGUI.py:3756 +#: flatcamGUI/FlatCAMGUI.py:3747 flatcamGUI/FlatCAMGUI.py:3973 msgid "Cancelled. Nothing selected to move." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:3782 +#: flatcamGUI/FlatCAMGUI.py:3999 msgid "New Tool ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:3783 flatcamTools/ToolNonCopperClear.py:583 -#: flatcamTools/ToolPaint.py:494 flatcamTools/ToolSolderPaste.py:554 +#: flatcamGUI/FlatCAMGUI.py:4000 flatcamTools/ToolNCC.py:922 flatcamTools/ToolPaint.py:847 +#: flatcamTools/ToolSolderPaste.py:560 msgid "Enter a Tool Diameter" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:3795 +#: flatcamGUI/FlatCAMGUI.py:4012 msgid "Adding Tool cancelled ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:3808 +#: flatcamGUI/FlatCAMGUI.py:4025 msgid "Distance Tool exit..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:4018 flatcamGUI/FlatCAMGUI.py:4025 +#: flatcamGUI/FlatCAMGUI.py:4234 flatcamGUI/FlatCAMGUI.py:4241 msgid "Idle." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:4056 +#: flatcamGUI/FlatCAMGUI.py:4272 msgid "Application started ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:4057 +#: flatcamGUI/FlatCAMGUI.py:4273 msgid "Hello!" msgstr "" -#: flatcamGUI/FlatCAMGUI.py:4115 +#: flatcamGUI/FlatCAMGUI.py:4331 msgid "Open Project ..." msgstr "" -#: flatcamGUI/FlatCAMGUI.py:4141 +#: flatcamGUI/FlatCAMGUI.py:4357 msgid "Exit" msgstr "" -#: flatcamGUI/GUIElements.py:2261 flatcamGUI/PreferencesUI.py:5265 -#: flatcamGUI/PreferencesUI.py:5825 flatcamTools/ToolFilm.py:219 +#: flatcamGUI/GUIElements.py:2513 flatcamGUI/PreferencesUI.py:6313 +#: flatcamTools/ToolDblSided.py:174 flatcamTools/ToolDblSided.py:389 +#: flatcamTools/ToolFilm.py:219 msgid "Reference" msgstr "" -#: flatcamGUI/GUIElements.py:2263 +#: flatcamGUI/GUIElements.py:2515 msgid "" "The reference can be:\n" "- Absolute -> the reference point is point (0,0)\n" "- Relative -> the reference point is the mouse position before Jump" msgstr "" -#: flatcamGUI/GUIElements.py:2268 +#: flatcamGUI/GUIElements.py:2520 msgid "Abs" msgstr "" -#: flatcamGUI/GUIElements.py:2269 +#: flatcamGUI/GUIElements.py:2521 msgid "Relative" msgstr "" -#: flatcamGUI/GUIElements.py:2279 +#: flatcamGUI/GUIElements.py:2531 msgid "Location" msgstr "" -#: flatcamGUI/GUIElements.py:2281 +#: flatcamGUI/GUIElements.py:2533 msgid "" "The Location value is a tuple (x,y).\n" "If the reference is Absolute then the Jump will be at the position (x,y).\n" @@ -6271,6 +6564,10 @@ msgid "" "from the current mouse location point." msgstr "" +#: flatcamGUI/GUIElements.py:2573 +msgid "Save Log" +msgstr "" + #: flatcamGUI/ObjectUI.py:38 msgid "FlatCAM Object" msgstr "" @@ -6286,123 +6583,105 @@ msgid "" "'APP. LEVEL' radio button." msgstr "" -#: flatcamGUI/ObjectUI.py:105 -msgid "Change the size of the object." +#: flatcamGUI/ObjectUI.py:110 +msgid "Geometrical transformations of the current object." msgstr "" -#: flatcamGUI/ObjectUI.py:111 -msgid "Factor" -msgstr "" - -#: flatcamGUI/ObjectUI.py:113 +#: flatcamGUI/ObjectUI.py:119 msgid "" "Factor by which to multiply\n" "geometric features of this object.\n" "Expressions are allowed. E.g: 1/25.4" msgstr "" -#: flatcamGUI/ObjectUI.py:123 +#: flatcamGUI/ObjectUI.py:126 msgid "Perform scaling operation." msgstr "" -#: flatcamGUI/ObjectUI.py:134 -msgid "Change the position of this object." -msgstr "" - -#: flatcamGUI/ObjectUI.py:139 -msgid "Vector" -msgstr "" - -#: flatcamGUI/ObjectUI.py:141 +#: flatcamGUI/ObjectUI.py:137 msgid "" "Amount by which to move the object\n" "in the x and y axes in (x, y) format.\n" "Expressions are allowed. E.g: (1/3.2, 0.5*3)" msgstr "" -#: flatcamGUI/ObjectUI.py:150 +#: flatcamGUI/ObjectUI.py:144 msgid "Perform the offset operation." msgstr "" -#: flatcamGUI/ObjectUI.py:167 +#: flatcamGUI/ObjectUI.py:177 msgid "Gerber Object" msgstr "" -#: flatcamGUI/ObjectUI.py:182 flatcamGUI/ObjectUI.py:767 flatcamGUI/ObjectUI.py:1205 -#: flatcamGUI/ObjectUI.py:1905 flatcamGUI/PreferencesUI.py:1783 -#: flatcamGUI/PreferencesUI.py:3849 flatcamGUI/PreferencesUI.py:4406 -msgid "Plot (show) this object." -msgstr "" - -#: flatcamGUI/ObjectUI.py:184 flatcamGUI/ObjectUI.py:765 flatcamGUI/PreferencesUI.py:1781 -#: flatcamGUI/PreferencesUI.py:2680 flatcamGUI/PreferencesUI.py:3847 -msgid "Plot" -msgstr "" - -#: flatcamGUI/ObjectUI.py:189 flatcamGUI/ObjectUI.py:726 flatcamGUI/ObjectUI.py:1159 -#: flatcamGUI/ObjectUI.py:1795 flatcamGUI/PreferencesUI.py:1760 -#: flatcamGUI/PreferencesUI.py:2674 flatcamGUI/PreferencesUI.py:3843 -#: flatcamGUI/PreferencesUI.py:4395 +#: flatcamGUI/ObjectUI.py:186 flatcamGUI/ObjectUI.py:729 flatcamGUI/ObjectUI.py:1424 +#: flatcamGUI/ObjectUI.py:2123 flatcamGUI/PreferencesUI.py:1940 +#: flatcamGUI/PreferencesUI.py:2856 flatcamGUI/PreferencesUI.py:4121 +#: flatcamGUI/PreferencesUI.py:4688 msgid "Plot Options" msgstr "" -#: flatcamGUI/ObjectUI.py:195 flatcamGUI/ObjectUI.py:727 flatcamGUI/PreferencesUI.py:1767 -#: flatcamGUI/PreferencesUI.py:2686 flatcamGUI/PreferencesUI.py:7222 -#: flatcamTools/ToolCopperThieving.py:190 +#: flatcamGUI/ObjectUI.py:192 flatcamGUI/ObjectUI.py:730 flatcamGUI/PreferencesUI.py:1947 +#: flatcamGUI/PreferencesUI.py:2868 flatcamGUI/PreferencesUI.py:7728 +#: flatcamTools/ToolCopperThieving.py:192 msgid "Solid" msgstr "" -#: flatcamGUI/ObjectUI.py:197 flatcamGUI/PreferencesUI.py:1769 +#: flatcamGUI/ObjectUI.py:194 flatcamGUI/PreferencesUI.py:1949 msgid "Solid color polygons." msgstr "" -#: flatcamGUI/ObjectUI.py:203 +#: flatcamGUI/ObjectUI.py:200 msgid "Multi-Color" msgstr "" -#: flatcamGUI/ObjectUI.py:205 flatcamGUI/PreferencesUI.py:1776 +#: flatcamGUI/ObjectUI.py:202 flatcamGUI/PreferencesUI.py:1956 msgid "Draw polygons in different colors." msgstr "" -#: flatcamGUI/ObjectUI.py:213 flatcamGUI/ObjectUI.py:738 flatcamGUI/ObjectUI.py:1165 -#: flatcamGUI/ObjectUI.py:1825 flatcamGUI/ObjectUI.py:2128 flatcamGUI/ObjectUI.py:2194 -#: flatcamTools/ToolCalibration.py:235 flatcamTools/ToolFiducials.py:73 -msgid "Name" +#: flatcamGUI/ObjectUI.py:208 flatcamGUI/ObjectUI.py:768 flatcamGUI/PreferencesUI.py:1961 +#: flatcamGUI/PreferencesUI.py:2862 flatcamGUI/PreferencesUI.py:4125 +msgid "Plot" msgstr "" -#: flatcamGUI/ObjectUI.py:234 +#: flatcamGUI/ObjectUI.py:210 flatcamGUI/ObjectUI.py:770 flatcamGUI/ObjectUI.py:1484 +#: flatcamGUI/ObjectUI.py:2233 flatcamGUI/PreferencesUI.py:1963 +#: flatcamGUI/PreferencesUI.py:4127 flatcamGUI/PreferencesUI.py:4699 +msgid "Plot (show) this object." +msgstr "" + +#: flatcamGUI/ObjectUI.py:238 msgid "" "Toggle the display of the Gerber Apertures Table.\n" "When unchecked, it will delete all mark shapes\n" "that are drawn on canvas." msgstr "" -#: flatcamGUI/ObjectUI.py:244 +#: flatcamGUI/ObjectUI.py:248 msgid "Mark All" msgstr "" -#: flatcamGUI/ObjectUI.py:246 +#: flatcamGUI/ObjectUI.py:250 msgid "" "When checked it will display all the apertures.\n" "When unchecked, it will delete all mark shapes\n" "that are drawn on canvas." msgstr "" -#: flatcamGUI/ObjectUI.py:274 +#: flatcamGUI/ObjectUI.py:278 msgid "Mark the aperture instances on canvas." msgstr "" -#: flatcamGUI/ObjectUI.py:286 flatcamGUI/PreferencesUI.py:2014 +#: flatcamGUI/ObjectUI.py:290 flatcamGUI/PreferencesUI.py:2194 msgid "Isolation Routing" msgstr "" -#: flatcamGUI/ObjectUI.py:288 flatcamGUI/PreferencesUI.py:2016 +#: flatcamGUI/ObjectUI.py:292 flatcamGUI/PreferencesUI.py:2196 msgid "" "Create a Geometry object with\n" "toolpaths to cut outside polygons." msgstr "" -#: flatcamGUI/ObjectUI.py:306 flatcamGUI/PreferencesUI.py:2219 +#: flatcamGUI/ObjectUI.py:310 flatcamGUI/PreferencesUI.py:2399 msgid "" "Choose what tool to use for Gerber isolation:\n" "'Circular' or 'V-shape'.\n" @@ -6410,41 +6689,47 @@ msgid "" "diameter will depend on the chosen cut depth." msgstr "" -#: flatcamGUI/ObjectUI.py:312 +#: flatcamGUI/ObjectUI.py:316 msgid "V-Shape" msgstr "" -#: flatcamGUI/ObjectUI.py:318 flatcamGUI/ObjectUI.py:1374 flatcamGUI/PreferencesUI.py:2231 -#: flatcamGUI/PreferencesUI.py:5055 flatcamTools/ToolNonCopperClear.py:231 +#: flatcamGUI/ObjectUI.py:322 flatcamGUI/ObjectUI.py:1670 flatcamGUI/PreferencesUI.py:2411 +#: flatcamGUI/PreferencesUI.py:5351 flatcamGUI/PreferencesUI.py:5917 +#: flatcamGUI/PreferencesUI.py:5924 flatcamTools/ToolNCC.py:233 flatcamTools/ToolNCC.py:240 +#: flatcamTools/ToolPaint.py:216 msgid "V-Tip Dia" msgstr "" -#: flatcamGUI/ObjectUI.py:320 flatcamGUI/ObjectUI.py:1377 flatcamGUI/PreferencesUI.py:2233 -#: flatcamGUI/PreferencesUI.py:5057 flatcamTools/ToolNonCopperClear.py:233 +#: flatcamGUI/ObjectUI.py:324 flatcamGUI/ObjectUI.py:1673 flatcamGUI/PreferencesUI.py:2413 +#: flatcamGUI/PreferencesUI.py:5353 flatcamGUI/PreferencesUI.py:5919 +#: flatcamTools/ToolNCC.py:235 flatcamTools/ToolPaint.py:218 msgid "The tip diameter for V-Shape Tool" msgstr "" -#: flatcamGUI/ObjectUI.py:331 flatcamGUI/ObjectUI.py:1389 flatcamGUI/PreferencesUI.py:2244 -#: flatcamGUI/PreferencesUI.py:5067 flatcamTools/ToolNonCopperClear.py:242 +#: flatcamGUI/ObjectUI.py:335 flatcamGUI/ObjectUI.py:1685 flatcamGUI/PreferencesUI.py:2424 +#: flatcamGUI/PreferencesUI.py:5363 flatcamGUI/PreferencesUI.py:5930 +#: flatcamGUI/PreferencesUI.py:5938 flatcamTools/ToolNCC.py:246 flatcamTools/ToolNCC.py:254 +#: flatcamTools/ToolPaint.py:229 msgid "V-Tip Angle" msgstr "" -#: flatcamGUI/ObjectUI.py:333 flatcamGUI/ObjectUI.py:1392 flatcamGUI/PreferencesUI.py:2246 -#: flatcamGUI/PreferencesUI.py:5069 flatcamTools/ToolNonCopperClear.py:244 +#: flatcamGUI/ObjectUI.py:337 flatcamGUI/ObjectUI.py:1688 flatcamGUI/PreferencesUI.py:2426 +#: flatcamGUI/PreferencesUI.py:5365 flatcamGUI/PreferencesUI.py:5932 +#: flatcamTools/ToolNCC.py:248 flatcamTools/ToolPaint.py:231 msgid "" "The tip angle for V-Shape Tool.\n" "In degree." msgstr "" -#: flatcamGUI/ObjectUI.py:347 flatcamGUI/ObjectUI.py:1408 flatcamGUI/PreferencesUI.py:2259 -#: flatcamGUI/PreferencesUI.py:3963 flatcamGUI/PreferencesUI.py:5330 -#: flatcamTools/ToolCutOut.py:135 +#: flatcamGUI/ObjectUI.py:351 flatcamGUI/ObjectUI.py:1704 flatcamGUI/PreferencesUI.py:2439 +#: flatcamGUI/PreferencesUI.py:4243 flatcamGUI/PreferencesUI.py:5669 +#: flatcamTools/ToolCutOut.py:142 msgid "" "Cutting depth (negative)\n" "below the copper surface." msgstr "" -#: flatcamGUI/ObjectUI.py:361 +#: flatcamGUI/ObjectUI.py:365 msgid "" "Diameter of the cutting tool.\n" "If you want to have an isolation path\n" @@ -6453,84 +6738,67 @@ msgid "" "this parameter." msgstr "" -#: flatcamGUI/ObjectUI.py:377 flatcamGUI/PreferencesUI.py:2038 +#: flatcamGUI/ObjectUI.py:381 flatcamGUI/PreferencesUI.py:2218 msgid "# Passes" msgstr "" -#: flatcamGUI/ObjectUI.py:379 flatcamGUI/PreferencesUI.py:2040 +#: flatcamGUI/ObjectUI.py:383 flatcamGUI/PreferencesUI.py:2220 msgid "" "Width of the isolation gap in\n" "number (integer) of tool widths." msgstr "" -#: flatcamGUI/ObjectUI.py:389 flatcamGUI/PreferencesUI.py:2050 +#: flatcamGUI/ObjectUI.py:394 flatcamGUI/PreferencesUI.py:2230 msgid "Pass overlap" msgstr "" -#: flatcamGUI/ObjectUI.py:391 flatcamGUI/PreferencesUI.py:2052 -msgid "How much (fraction) of the tool width to overlap each tool pass." +#: flatcamGUI/ObjectUI.py:396 flatcamGUI/PreferencesUI.py:2232 +msgid "How much (percentage) of the tool width to overlap each tool pass." msgstr "" -#: flatcamGUI/ObjectUI.py:403 flatcamGUI/PreferencesUI.py:2077 -#: flatcamGUI/PreferencesUI.py:4372 flatcamGUI/PreferencesUI.py:5112 -#: flatcamTools/ToolNonCopperClear.py:162 -msgid "Milling Type" -msgstr "" - -#: flatcamGUI/ObjectUI.py:405 flatcamGUI/PreferencesUI.py:2079 -#: flatcamGUI/PreferencesUI.py:4374 +#: flatcamGUI/ObjectUI.py:410 flatcamGUI/PreferencesUI.py:2259 +#: flatcamGUI/PreferencesUI.py:4667 msgid "" "Milling type:\n" "- climb / best for precision milling and to reduce tool usage\n" "- conventional / useful when there is no backlash compensation" msgstr "" -#: flatcamGUI/ObjectUI.py:409 flatcamGUI/PreferencesUI.py:2084 -#: flatcamGUI/PreferencesUI.py:4378 flatcamGUI/PreferencesUI.py:5119 -#: flatcamTools/ToolNonCopperClear.py:169 -msgid "Climb" -msgstr "" - -#: flatcamGUI/ObjectUI.py:410 -msgid "Conventional" -msgstr "" - -#: flatcamGUI/ObjectUI.py:415 +#: flatcamGUI/ObjectUI.py:420 msgid "Combine" msgstr "" -#: flatcamGUI/ObjectUI.py:417 flatcamGUI/PreferencesUI.py:2091 +#: flatcamGUI/ObjectUI.py:422 flatcamGUI/PreferencesUI.py:2271 msgid "Combine all passes into one object" msgstr "" -#: flatcamGUI/ObjectUI.py:421 flatcamGUI/PreferencesUI.py:2193 +#: flatcamGUI/ObjectUI.py:426 flatcamGUI/PreferencesUI.py:2373 msgid "\"Follow\"" msgstr "" -#: flatcamGUI/ObjectUI.py:422 flatcamGUI/PreferencesUI.py:2195 +#: flatcamGUI/ObjectUI.py:427 flatcamGUI/PreferencesUI.py:2375 msgid "" "Generate a 'Follow' geometry.\n" "This means that it will cut through\n" "the middle of the trace." msgstr "" -#: flatcamGUI/ObjectUI.py:428 +#: flatcamGUI/ObjectUI.py:433 msgid "Except" msgstr "" -#: flatcamGUI/ObjectUI.py:431 +#: flatcamGUI/ObjectUI.py:436 msgid "" "When the isolation geometry is generated,\n" "by checking this, the area of the object bellow\n" "will be subtracted from the isolation geometry." msgstr "" -#: flatcamGUI/ObjectUI.py:453 flatcamTools/ToolNonCopperClear.py:82 -#: flatcamTools/ToolPaint.py:85 +#: flatcamGUI/ObjectUI.py:456 flatcamTools/ToolNCC.py:86 flatcamTools/ToolPaint.py:80 msgid "Obj Type" msgstr "" -#: flatcamGUI/ObjectUI.py:455 +#: flatcamGUI/ObjectUI.py:458 msgid "" "Specify the type of object to be excepted from isolation.\n" "It can be of type: Gerber or Geometry.\n" @@ -6538,39 +6806,40 @@ msgid "" "of objects that will populate the 'Object' combobox." msgstr "" -#: flatcamGUI/ObjectUI.py:468 flatcamGUI/PreferencesUI.py:7522 -#: flatcamTools/ToolCalibration.py:186 flatcamTools/ToolNonCopperClear.py:100 -#: flatcamTools/ToolPaint.py:103 flatcamTools/ToolPanelize.py:81 -#: flatcamTools/ToolPanelize.py:94 +#: flatcamGUI/ObjectUI.py:471 flatcamGUI/PreferencesUI.py:8028 +#: flatcamTools/ToolCalibration.py:186 flatcamTools/ToolNCC.py:109 +#: flatcamTools/ToolPaint.py:103 flatcamTools/ToolPanelize.py:100 +#: flatcamTools/ToolQRCode.py:78 msgid "Object" msgstr "" -#: flatcamGUI/ObjectUI.py:469 +#: flatcamGUI/ObjectUI.py:472 msgid "Object whose area will be removed from isolation geometry." msgstr "" -#: flatcamGUI/ObjectUI.py:476 flatcamGUI/PreferencesUI.py:2064 +#: flatcamGUI/ObjectUI.py:479 flatcamGUI/PreferencesUI.py:2244 msgid "Scope" msgstr "" -#: flatcamGUI/ObjectUI.py:478 flatcamGUI/PreferencesUI.py:2066 +#: flatcamGUI/ObjectUI.py:481 flatcamGUI/PreferencesUI.py:2246 msgid "" "Isolation scope. Choose what to isolate:\n" "- 'All' -> Isolate all the polygons in the object\n" "- 'Selection' -> Isolate a selection of polygons." msgstr "" -#: flatcamGUI/ObjectUI.py:483 flatcamGUI/PreferencesUI.py:602 -#: flatcamGUI/PreferencesUI.py:2071 flatcamGUI/PreferencesUI.py:5634 -#: flatcamTools/ToolPaint.py:294 +#: flatcamGUI/ObjectUI.py:486 flatcamGUI/PreferencesUI.py:624 +#: flatcamGUI/PreferencesUI.py:2251 flatcamGUI/PreferencesUI.py:5590 +#: flatcamGUI/PreferencesUI.py:6097 flatcamTools/ToolNCC.py:539 +#: flatcamTools/ToolPaint.py:456 msgid "Selection" msgstr "" -#: flatcamGUI/ObjectUI.py:491 flatcamGUI/PreferencesUI.py:2272 +#: flatcamGUI/ObjectUI.py:494 flatcamGUI/PreferencesUI.py:2452 msgid "Isolation Type" msgstr "" -#: flatcamGUI/ObjectUI.py:493 flatcamGUI/PreferencesUI.py:2274 +#: flatcamGUI/ObjectUI.py:496 flatcamGUI/PreferencesUI.py:2454 msgid "" "Choose how the isolation will be executed:\n" "- 'Full' -> complete isolation of polygons\n" @@ -6582,24 +6851,24 @@ msgid "" "inside of the polygon (e.g polygon is a 'doughnut' shape)." msgstr "" -#: flatcamGUI/ObjectUI.py:502 flatcamGUI/PreferencesUI.py:2283 -#: flatcamGUI/PreferencesUI.py:2304 +#: flatcamGUI/ObjectUI.py:505 flatcamGUI/PreferencesUI.py:2463 +#: flatcamGUI/PreferencesUI.py:2484 msgid "Full" msgstr "" -#: flatcamGUI/ObjectUI.py:503 +#: flatcamGUI/ObjectUI.py:506 msgid "Ext" msgstr "" -#: flatcamGUI/ObjectUI.py:504 +#: flatcamGUI/ObjectUI.py:507 msgid "Int" msgstr "" -#: flatcamGUI/ObjectUI.py:509 +#: flatcamGUI/ObjectUI.py:512 msgid "Generate Isolation Geometry" msgstr "" -#: flatcamGUI/ObjectUI.py:517 +#: flatcamGUI/ObjectUI.py:520 msgid "" "Create a Geometry object with toolpaths to cut \n" "isolation outside, inside or on both sides of the\n" @@ -6612,11 +6881,11 @@ msgid "" "diameter above." msgstr "" -#: flatcamGUI/ObjectUI.py:529 +#: flatcamGUI/ObjectUI.py:532 msgid "Buffer Solid Geometry" msgstr "" -#: flatcamGUI/ObjectUI.py:531 +#: flatcamGUI/ObjectUI.py:534 msgid "" "This button is shown only when the Gerber file\n" "is loaded without buffering.\n" @@ -6624,45 +6893,44 @@ msgid "" "required for isolation." msgstr "" -#: flatcamGUI/ObjectUI.py:559 +#: flatcamGUI/ObjectUI.py:566 msgid "Clear N-copper" msgstr "" -#: flatcamGUI/ObjectUI.py:561 flatcamGUI/PreferencesUI.py:5019 +#: flatcamGUI/ObjectUI.py:568 flatcamGUI/PreferencesUI.py:5312 msgid "" "Create a Geometry object with\n" "toolpaths to cut all non-copper regions." msgstr "" -#: flatcamGUI/ObjectUI.py:568 flatcamGUI/ObjectUI.py:1751 -#: flatcamTools/ToolNonCopperClear.py:473 +#: flatcamGUI/ObjectUI.py:575 flatcamGUI/ObjectUI.py:2077 flatcamTools/ToolNCC.py:599 msgid "" "Create the Geometry Object\n" "for non-copper routing." msgstr "" -#: flatcamGUI/ObjectUI.py:581 +#: flatcamGUI/ObjectUI.py:588 msgid "Board cutout" msgstr "" -#: flatcamGUI/ObjectUI.py:583 flatcamGUI/PreferencesUI.py:5303 +#: flatcamGUI/ObjectUI.py:590 flatcamGUI/PreferencesUI.py:5642 msgid "" "Create toolpaths to cut around\n" "the PCB and separate it from\n" "the original board." msgstr "" -#: flatcamGUI/ObjectUI.py:590 +#: flatcamGUI/ObjectUI.py:597 msgid "" "Generate the geometry for\n" "the board cutout." msgstr "" -#: flatcamGUI/ObjectUI.py:608 flatcamGUI/PreferencesUI.py:2101 +#: flatcamGUI/ObjectUI.py:615 flatcamGUI/PreferencesUI.py:2281 msgid "Non-copper regions" msgstr "" -#: flatcamGUI/ObjectUI.py:610 flatcamGUI/PreferencesUI.py:2103 +#: flatcamGUI/ObjectUI.py:617 flatcamGUI/PreferencesUI.py:2283 msgid "" "Create polygons covering the\n" "areas without copper on the PCB.\n" @@ -6671,12 +6939,12 @@ msgid "" "copper from a specified region." msgstr "" -#: flatcamGUI/ObjectUI.py:620 flatcamGUI/ObjectUI.py:661 flatcamGUI/PreferencesUI.py:2115 -#: flatcamGUI/PreferencesUI.py:2148 +#: flatcamGUI/ObjectUI.py:627 flatcamGUI/ObjectUI.py:668 flatcamGUI/PreferencesUI.py:2295 +#: flatcamGUI/PreferencesUI.py:2328 msgid "Boundary Margin" msgstr "" -#: flatcamGUI/ObjectUI.py:622 flatcamGUI/PreferencesUI.py:2117 +#: flatcamGUI/ObjectUI.py:629 flatcamGUI/PreferencesUI.py:2297 msgid "" "Specify the edge of the PCB\n" "by drawing a box around all\n" @@ -6684,38 +6952,38 @@ msgid "" "distance." msgstr "" -#: flatcamGUI/ObjectUI.py:637 flatcamGUI/ObjectUI.py:675 flatcamGUI/PreferencesUI.py:2130 -#: flatcamGUI/PreferencesUI.py:2161 +#: flatcamGUI/ObjectUI.py:644 flatcamGUI/ObjectUI.py:682 flatcamGUI/PreferencesUI.py:2310 +#: flatcamGUI/PreferencesUI.py:2341 msgid "Rounded Geo" msgstr "" -#: flatcamGUI/ObjectUI.py:639 flatcamGUI/PreferencesUI.py:2132 +#: flatcamGUI/ObjectUI.py:646 flatcamGUI/PreferencesUI.py:2312 msgid "Resulting geometry will have rounded corners." msgstr "" -#: flatcamGUI/ObjectUI.py:643 flatcamGUI/ObjectUI.py:684 flatcamTools/ToolSolderPaste.py:133 +#: flatcamGUI/ObjectUI.py:650 flatcamGUI/ObjectUI.py:691 flatcamTools/ToolSolderPaste.py:135 msgid "Generate Geo" msgstr "" -#: flatcamGUI/ObjectUI.py:653 flatcamGUI/PreferencesUI.py:2142 -#: flatcamGUI/PreferencesUI.py:7052 flatcamTools/ToolPanelize.py:95 +#: flatcamGUI/ObjectUI.py:660 flatcamGUI/PreferencesUI.py:2322 +#: flatcamGUI/PreferencesUI.py:7558 flatcamTools/ToolPanelize.py:101 #: flatcamTools/ToolQRCode.py:192 msgid "Bounding Box" msgstr "" -#: flatcamGUI/ObjectUI.py:655 +#: flatcamGUI/ObjectUI.py:662 msgid "" "Create a geometry surrounding the Gerber object.\n" "Square shape." msgstr "" -#: flatcamGUI/ObjectUI.py:663 flatcamGUI/PreferencesUI.py:2150 +#: flatcamGUI/ObjectUI.py:670 flatcamGUI/PreferencesUI.py:2330 msgid "" "Distance of the edges of the box\n" "to the nearest polygon." msgstr "" -#: flatcamGUI/ObjectUI.py:677 flatcamGUI/PreferencesUI.py:2163 +#: flatcamGUI/ObjectUI.py:684 flatcamGUI/PreferencesUI.py:2343 msgid "" "If the bounding box is \n" "to have rounded corners\n" @@ -6723,32 +6991,30 @@ msgid "" "the margin." msgstr "" -#: flatcamGUI/ObjectUI.py:686 +#: flatcamGUI/ObjectUI.py:693 msgid "Generate the Geometry object." msgstr "" -#: flatcamGUI/ObjectUI.py:715 +#: flatcamGUI/ObjectUI.py:720 msgid "Excellon Object" msgstr "" -#: flatcamGUI/ObjectUI.py:729 +#: flatcamGUI/ObjectUI.py:732 msgid "Solid circles." msgstr "" -#: flatcamGUI/ObjectUI.py:777 flatcamGUI/ObjectUI.py:1926 flatcamTools/ToolProperties.py:161 +#: flatcamGUI/ObjectUI.py:780 flatcamGUI/ObjectUI.py:875 flatcamGUI/ObjectUI.py:2254 +#: flatcamGUI/PreferencesUI.py:3289 flatcamTools/ToolProperties.py:166 msgid "Drills" msgstr "" -#: flatcamGUI/ObjectUI.py:777 flatcamGUI/ObjectUI.py:1926 flatcamGUI/PreferencesUI.py:3683 -#: flatcamTools/ToolProperties.py:162 +#: flatcamGUI/ObjectUI.py:780 flatcamGUI/ObjectUI.py:876 flatcamGUI/ObjectUI.py:2254 +#: flatcamGUI/PreferencesUI.py:3290 flatcamGUI/PreferencesUI.py:3961 +#: flatcamTools/ToolProperties.py:168 msgid "Slots" msgstr "" -#: flatcamGUI/ObjectUI.py:778 flatcamGUI/PreferencesUI.py:3289 -msgid "Offset Z" -msgstr "" - -#: flatcamGUI/ObjectUI.py:782 +#: flatcamGUI/ObjectUI.py:785 msgid "" "This is the Tool Number.\n" "When ToolChange is checked, on toolchange event this value\n" @@ -6757,107 +7023,113 @@ msgid "" "Here the tools are selected for G-code generation." msgstr "" -#: flatcamGUI/ObjectUI.py:787 flatcamGUI/ObjectUI.py:1230 flatcamTools/ToolPaint.py:137 +#: flatcamGUI/ObjectUI.py:790 flatcamGUI/ObjectUI.py:1508 flatcamTools/ToolPaint.py:142 msgid "" "Tool Diameter. It's value (in current FlatCAM units) \n" "is the cut width into the material." msgstr "" -#: flatcamGUI/ObjectUI.py:790 +#: flatcamGUI/ObjectUI.py:793 msgid "" "The number of Drill holes. Holes that are drilled with\n" "a drill bit." msgstr "" -#: flatcamGUI/ObjectUI.py:793 +#: flatcamGUI/ObjectUI.py:796 msgid "" "The number of Slot holes. Holes that are created by\n" "milling them with an endmill bit." msgstr "" -#: flatcamGUI/ObjectUI.py:796 flatcamGUI/PreferencesUI.py:3291 -msgid "" -"Some drill bits (the larger ones) need to drill deeper\n" -"to create the desired exit hole diameter due of the tip shape.\n" -"The value here can compensate the Cut Z parameter." -msgstr "" - -#: flatcamGUI/ObjectUI.py:800 +#: flatcamGUI/ObjectUI.py:799 msgid "" "Toggle display of the drills for the current tool.\n" "This does not select the tools for G-code generation." msgstr "" -#: flatcamGUI/ObjectUI.py:807 flatcamGUI/PreferencesUI.py:3069 -#: flatcamGUI/PreferencesUI.py:3947 -msgid "Create CNC Job" -msgstr "" - -#: flatcamGUI/ObjectUI.py:809 +#: flatcamGUI/ObjectUI.py:820 flatcamGUI/ObjectUI.py:1663 flatcamTools/ToolNCC.py:334 +#: flatcamTools/ToolPaint.py:317 msgid "" -"Create a CNC Job object\n" -"for this drill object." +"The data used for creating GCode.\n" +"Each tool store it's own set of such data." msgstr "" -#: flatcamGUI/ObjectUI.py:822 flatcamGUI/PreferencesUI.py:3084 +#: flatcamGUI/ObjectUI.py:846 flatcamGUI/PreferencesUI.py:3266 +msgid "" +"Operation type:\n" +"- Drilling -> will drill the drills/slots associated with this tool\n" +"- Milling -> will mill the drills/slots" +msgstr "" + +#: flatcamGUI/ObjectUI.py:852 flatcamGUI/PreferencesUI.py:3272 +msgid "Drilling" +msgstr "" + +#: flatcamGUI/ObjectUI.py:853 flatcamGUI/PreferencesUI.py:3273 +msgid "Milling" +msgstr "" + +#: flatcamGUI/ObjectUI.py:868 flatcamGUI/PreferencesUI.py:3282 +msgid "" +"Milling type:\n" +"- Drills -> will mill the drills associated with this tool\n" +"- Slots -> will mill the slots associated with this tool\n" +"- Both -> will mill both drills and mills or whatever is available" +msgstr "" + +#: flatcamGUI/ObjectUI.py:877 flatcamGUI/PreferencesUI.py:3291 +#: flatcamGUI/PreferencesUI.py:6343 flatcamTools/ToolFilm.py:258 +msgid "Both" +msgstr "" + +#: flatcamGUI/ObjectUI.py:885 flatcamGUI/PreferencesUI.py:3298 +msgid "Milling Diameter" +msgstr "" + +#: flatcamGUI/ObjectUI.py:887 flatcamGUI/PreferencesUI.py:3300 +msgid "The diameter of the tool who will do the milling" +msgstr "" + +#: flatcamGUI/ObjectUI.py:901 flatcamGUI/PreferencesUI.py:3313 msgid "" "Drill depth (negative)\n" "below the copper surface." msgstr "" -#: flatcamGUI/ObjectUI.py:841 flatcamGUI/PreferencesUI.py:3102 +#: flatcamGUI/ObjectUI.py:920 flatcamGUI/ObjectUI.py:1722 flatcamGUI/PreferencesUI.py:3331 +#: flatcamGUI/PreferencesUI.py:4261 flatcamGUI/PreferencesUI.py:5687 +#: flatcamTools/ToolCutOut.py:160 +msgid "Multi-Depth" +msgstr "" + +#: flatcamGUI/ObjectUI.py:923 flatcamGUI/ObjectUI.py:1725 flatcamGUI/PreferencesUI.py:3334 +#: flatcamGUI/PreferencesUI.py:4264 flatcamGUI/PreferencesUI.py:5690 +#: flatcamTools/ToolCutOut.py:163 +msgid "" +"Use multiple passes to limit\n" +"the cut depth in each pass. Will\n" +"cut multiple times until Cut Z is\n" +"reached." +msgstr "" + +#: flatcamGUI/ObjectUI.py:936 flatcamGUI/ObjectUI.py:1739 flatcamGUI/PreferencesUI.py:3346 +#: flatcamGUI/PreferencesUI.py:5702 flatcamTools/ToolCutOut.py:177 +msgid "Depth of each pass (positive)." +msgstr "" + +#: flatcamGUI/ObjectUI.py:947 flatcamGUI/PreferencesUI.py:3354 msgid "" "Tool height when travelling\n" "across the XY plane." msgstr "" -#: flatcamGUI/ObjectUI.py:858 flatcamGUI/ObjectUI.py:1478 flatcamGUI/PreferencesUI.py:3117 -#: flatcamGUI/PreferencesUI.py:4034 -msgid "Tool change" -msgstr "" - -#: flatcamGUI/ObjectUI.py:860 flatcamGUI/PreferencesUI.py:3119 +#: flatcamGUI/ObjectUI.py:968 flatcamGUI/ObjectUI.py:1769 flatcamGUI/PreferencesUI.py:4380 msgid "" -"Include tool-change sequence\n" -"in G-Code (Pause for tool change)." +"Cutting speed in the XY\n" +"plane in units per minute" msgstr "" -#: flatcamGUI/ObjectUI.py:866 flatcamGUI/ObjectUI.py:1471 -msgid "Tool change Z" -msgstr "" - -#: flatcamGUI/ObjectUI.py:868 flatcamGUI/ObjectUI.py:1474 flatcamGUI/PreferencesUI.py:3126 -#: flatcamGUI/PreferencesUI.py:4047 -msgid "" -"Z-axis position (height) for\n" -"tool change." -msgstr "" - -#: flatcamGUI/ObjectUI.py:888 flatcamGUI/PreferencesUI.py:3311 -msgid "" -"Height of the tool just after start.\n" -"Delete the value if you don't need this feature." -msgstr "" - -#: flatcamGUI/ObjectUI.py:896 flatcamGUI/ObjectUI.py:1512 flatcamGUI/PreferencesUI.py:3141 -#: flatcamGUI/PreferencesUI.py:4066 -msgid "End move Z" -msgstr "" - -#: flatcamGUI/ObjectUI.py:898 flatcamGUI/ObjectUI.py:1514 flatcamGUI/PreferencesUI.py:3143 -#: flatcamGUI/PreferencesUI.py:4068 -msgid "" -"Height of the tool after\n" -"the last move at the end of the job." -msgstr "" - -#: flatcamGUI/ObjectUI.py:915 flatcamGUI/ObjectUI.py:1545 flatcamGUI/PreferencesUI.py:3158 -#: flatcamGUI/PreferencesUI.py:4101 flatcamGUI/PreferencesUI.py:6566 -#: flatcamTools/ToolSolderPaste.py:264 -msgid "Feedrate Z" -msgstr "" - -#: flatcamGUI/ObjectUI.py:917 flatcamGUI/PreferencesUI.py:3160 +#: flatcamGUI/ObjectUI.py:983 flatcamGUI/PreferencesUI.py:3427 msgid "" "Tool speed while drilling\n" "(in units per minute).\n" @@ -6865,12 +7137,12 @@ msgid "" "This is for linear move G01." msgstr "" -#: flatcamGUI/ObjectUI.py:931 flatcamGUI/ObjectUI.py:1560 flatcamGUI/PreferencesUI.py:3319 -#: flatcamGUI/PreferencesUI.py:4210 +#: flatcamGUI/ObjectUI.py:998 flatcamGUI/ObjectUI.py:1796 flatcamGUI/PreferencesUI.py:3597 +#: flatcamGUI/PreferencesUI.py:4503 msgid "Feedrate Rapids" msgstr "" -#: flatcamGUI/ObjectUI.py:933 flatcamGUI/PreferencesUI.py:3321 +#: flatcamGUI/ObjectUI.py:1000 flatcamGUI/PreferencesUI.py:3599 msgid "" "Tool speed while drilling\n" "(in units per minute).\n" @@ -6879,131 +7151,223 @@ msgid "" "ignore for any other cases." msgstr "" -#: flatcamGUI/ObjectUI.py:951 flatcamGUI/ObjectUI.py:1603 flatcamGUI/PreferencesUI.py:4117 -msgid "Spindle speed" +#: flatcamGUI/ObjectUI.py:1020 flatcamGUI/ObjectUI.py:1816 flatcamGUI/PreferencesUI.py:4521 +msgid "Re-cut" msgstr "" -#: flatcamGUI/ObjectUI.py:953 flatcamGUI/PreferencesUI.py:3175 +#: flatcamGUI/ObjectUI.py:1022 flatcamGUI/ObjectUI.py:1035 flatcamGUI/ObjectUI.py:1818 +#: flatcamGUI/ObjectUI.py:1830 flatcamGUI/PreferencesUI.py:4523 +#: flatcamGUI/PreferencesUI.py:4535 +msgid "" +"In order to remove possible\n" +"copper leftovers where first cut\n" +"meet with last cut, we generate an\n" +"extended cut over the first cut section." +msgstr "" + +#: flatcamGUI/ObjectUI.py:1050 flatcamGUI/PreferencesUI.py:3442 msgid "" "Speed of the spindle\n" "in RPM (optional)" msgstr "" -#: flatcamGUI/ObjectUI.py:965 flatcamGUI/ObjectUI.py:1622 flatcamGUI/PreferencesUI.py:3187 -#: flatcamGUI/PreferencesUI.py:4135 +#: flatcamGUI/ObjectUI.py:1065 flatcamGUI/ObjectUI.py:1858 flatcamGUI/PreferencesUI.py:3456 +#: flatcamGUI/PreferencesUI.py:4427 msgid "" "Pause to allow the spindle to reach its\n" "speed before cutting." msgstr "" -#: flatcamGUI/ObjectUI.py:974 flatcamGUI/ObjectUI.py:1632 flatcamGUI/PreferencesUI.py:3193 -#: flatcamGUI/PreferencesUI.py:4140 +#: flatcamGUI/ObjectUI.py:1076 flatcamGUI/ObjectUI.py:1868 flatcamGUI/PreferencesUI.py:3464 +#: flatcamGUI/PreferencesUI.py:4432 msgid "Number of time units for spindle to dwell." msgstr "" -#: flatcamGUI/ObjectUI.py:984 flatcamGUI/PreferencesUI.py:3206 -msgid "" -"The preprocessor JSON file that dictates\n" -"Gcode output." +#: flatcamGUI/ObjectUI.py:1086 flatcamGUI/PreferencesUI.py:3563 +msgid "Offset Z" msgstr "" -#: flatcamGUI/ObjectUI.py:993 flatcamGUI/ObjectUI.py:1652 flatcamGUI/PreferencesUI.py:3335 -#: flatcamGUI/PreferencesUI.py:4251 +#: flatcamGUI/ObjectUI.py:1088 flatcamGUI/PreferencesUI.py:3565 +msgid "" +"Some drill bits (the larger ones) need to drill deeper\n" +"to create the desired exit hole diameter due of the tip shape.\n" +"The value here can compensate the Cut Z parameter." +msgstr "" + +#: flatcamGUI/ObjectUI.py:1148 flatcamGUI/ObjectUI.py:1922 flatcamTools/ToolNCC.py:492 +#: flatcamTools/ToolPaint.py:423 +msgid "Apply parameters to all tools" +msgstr "" + +#: flatcamGUI/ObjectUI.py:1150 flatcamGUI/ObjectUI.py:1924 flatcamTools/ToolNCC.py:494 +#: flatcamTools/ToolPaint.py:425 +msgid "" +"The parameters in the current form will be applied\n" +"on all the tools from the Tool Table." +msgstr "" + +#: flatcamGUI/ObjectUI.py:1161 flatcamGUI/ObjectUI.py:1935 flatcamTools/ToolNCC.py:505 +#: flatcamTools/ToolPaint.py:436 +msgid "Common Parameters" +msgstr "" + +#: flatcamGUI/ObjectUI.py:1163 flatcamGUI/ObjectUI.py:1937 flatcamTools/ToolNCC.py:507 +#: flatcamTools/ToolPaint.py:438 +msgid "Parameters that are common for all tools." +msgstr "" + +#: flatcamGUI/ObjectUI.py:1168 flatcamGUI/ObjectUI.py:1942 +msgid "Tool change Z" +msgstr "" + +#: flatcamGUI/ObjectUI.py:1170 flatcamGUI/PreferencesUI.py:3372 +msgid "" +"Include tool-change sequence\n" +"in G-Code (Pause for tool change)." +msgstr "" + +#: flatcamGUI/ObjectUI.py:1177 flatcamGUI/ObjectUI.py:1953 flatcamGUI/PreferencesUI.py:3380 +#: flatcamGUI/PreferencesUI.py:4327 +msgid "" +"Z-axis position (height) for\n" +"tool change." +msgstr "" + +#: flatcamGUI/ObjectUI.py:1194 flatcamGUI/PreferencesUI.py:3588 +msgid "" +"Height of the tool just after start.\n" +"Delete the value if you don't need this feature." +msgstr "" + +#: flatcamGUI/ObjectUI.py:1203 flatcamGUI/ObjectUI.py:1981 flatcamGUI/PreferencesUI.py:3396 +#: flatcamGUI/PreferencesUI.py:4346 +msgid "End move Z" +msgstr "" + +#: flatcamGUI/ObjectUI.py:1205 flatcamGUI/ObjectUI.py:1983 flatcamGUI/PreferencesUI.py:3398 +#: flatcamGUI/PreferencesUI.py:4348 +msgid "" +"Height of the tool after\n" +"the last move at the end of the job." +msgstr "" + +#: flatcamGUI/ObjectUI.py:1222 flatcamGUI/ObjectUI.py:2000 flatcamGUI/PreferencesUI.py:3413 +#: flatcamGUI/PreferencesUI.py:4366 +msgid "End move X,Y" +msgstr "" + +#: flatcamGUI/ObjectUI.py:1224 flatcamGUI/ObjectUI.py:2002 flatcamGUI/PreferencesUI.py:3415 +#: flatcamGUI/PreferencesUI.py:4368 +msgid "" +"End move X,Y position. In format (x,y).\n" +"If no value is entered then there is no move\n" +"on X,Y plane at the end of the job." +msgstr "" + +#: flatcamGUI/ObjectUI.py:1234 flatcamGUI/ObjectUI.py:1876 flatcamGUI/PreferencesUI.py:3613 +#: flatcamGUI/PreferencesUI.py:4544 msgid "Probe Z depth" msgstr "" -#: flatcamGUI/ObjectUI.py:995 flatcamGUI/ObjectUI.py:1654 flatcamGUI/PreferencesUI.py:3337 -#: flatcamGUI/PreferencesUI.py:4253 +#: flatcamGUI/ObjectUI.py:1236 flatcamGUI/ObjectUI.py:1878 flatcamGUI/PreferencesUI.py:3615 +#: flatcamGUI/PreferencesUI.py:4546 msgid "" "The maximum depth that the probe is allowed\n" "to probe. Negative value, in current units." msgstr "" -#: flatcamGUI/ObjectUI.py:1009 flatcamGUI/ObjectUI.py:1669 flatcamGUI/PreferencesUI.py:3348 -#: flatcamGUI/PreferencesUI.py:4266 +#: flatcamGUI/ObjectUI.py:1252 flatcamGUI/ObjectUI.py:1893 flatcamGUI/PreferencesUI.py:3626 +#: flatcamGUI/PreferencesUI.py:4559 msgid "Feedrate Probe" msgstr "" -#: flatcamGUI/ObjectUI.py:1011 flatcamGUI/ObjectUI.py:1671 flatcamGUI/PreferencesUI.py:3350 -#: flatcamGUI/PreferencesUI.py:4268 +#: flatcamGUI/ObjectUI.py:1254 flatcamGUI/ObjectUI.py:1895 flatcamGUI/PreferencesUI.py:3628 +#: flatcamGUI/PreferencesUI.py:4561 msgid "The feedrate used while the probe is probing." msgstr "" -#: flatcamGUI/ObjectUI.py:1037 flatcamGUI/PreferencesUI.py:3215 -msgid "Gcode" +#: flatcamGUI/ObjectUI.py:1261 +msgid "e_fr_probe" msgstr "" -#: flatcamGUI/ObjectUI.py:1039 +#: flatcamGUI/ObjectUI.py:1270 +msgid "Preprocessor E" +msgstr "" + +#: flatcamGUI/ObjectUI.py:1272 msgid "" -"Choose what to use for GCode generation:\n" -"'Drills', 'Slots' or 'Both'.\n" -"When choosing 'Slots' or 'Both', slots will be\n" -"converted to a series of drills." +"The preprocessor JSON file that dictates\n" +"Gcode output for Excellon Objects." msgstr "" -#: flatcamGUI/ObjectUI.py:1053 -msgid "Create Drills GCode" +#: flatcamGUI/ObjectUI.py:1282 +msgid "Preprocessor G" msgstr "" -#: flatcamGUI/ObjectUI.py:1055 -msgid "Generate the CNC Job." +#: flatcamGUI/ObjectUI.py:1284 +msgid "" +"The preprocessor JSON file that dictates\n" +"Gcode output for Geometry (Milling) Objects." msgstr "" -#: flatcamGUI/ObjectUI.py:1066 flatcamGUI/PreferencesUI.py:3233 -msgid "Mill Holes" +#: flatcamGUI/ObjectUI.py:1308 flatcamGUI/ObjectUI.py:2026 +msgid "" +"Add / Select at least one tool in the tool-table.\n" +"Click the # header to select all, or Ctrl + LMB\n" +"for custom selection of tools." msgstr "" -#: flatcamGUI/ObjectUI.py:1068 +#: flatcamGUI/ObjectUI.py:1316 flatcamGUI/ObjectUI.py:2033 +msgid "Generate CNCJob object" +msgstr "" + +#: flatcamGUI/ObjectUI.py:1318 +msgid "" +"Generate the CNC Job.\n" +"If milling then an additional Geometry object will be created" +msgstr "" + +#: flatcamGUI/ObjectUI.py:1335 +msgid "Milling Geometry" +msgstr "" + +#: flatcamGUI/ObjectUI.py:1337 msgid "" "Create Geometry for milling holes.\n" "Select from the Tools Table above the hole dias to be\n" "milled. Use the # column to make the selection." msgstr "" -#: flatcamGUI/ObjectUI.py:1074 flatcamGUI/PreferencesUI.py:3239 -msgid "Drill Tool dia" -msgstr "" - -#: flatcamGUI/ObjectUI.py:1076 flatcamGUI/PreferencesUI.py:2027 -#: flatcamGUI/PreferencesUI.py:3241 +#: flatcamGUI/ObjectUI.py:1345 flatcamGUI/PreferencesUI.py:2207 +#: flatcamGUI/PreferencesUI.py:3514 msgid "Diameter of the cutting tool." msgstr "" -#: flatcamGUI/ObjectUI.py:1083 -msgid "Mill Drills Geo" +#: flatcamGUI/ObjectUI.py:1355 +msgid "Mill Drills" msgstr "" -#: flatcamGUI/ObjectUI.py:1085 +#: flatcamGUI/ObjectUI.py:1357 msgid "" "Create the Geometry Object\n" "for milling DRILLS toolpaths." msgstr "" -#: flatcamGUI/ObjectUI.py:1099 flatcamGUI/PreferencesUI.py:3250 -msgid "Slot Tool dia" +#: flatcamGUI/ObjectUI.py:1375 +msgid "Mill Slots" msgstr "" -#: flatcamGUI/ObjectUI.py:1101 flatcamGUI/PreferencesUI.py:3252 -msgid "" -"Diameter of the cutting tool\n" -"when milling slots." -msgstr "" - -#: flatcamGUI/ObjectUI.py:1110 -msgid "Mill Slots Geo" -msgstr "" - -#: flatcamGUI/ObjectUI.py:1112 +#: flatcamGUI/ObjectUI.py:1377 msgid "" "Create the Geometry Object\n" "for milling SLOTS toolpaths." msgstr "" -#: flatcamGUI/ObjectUI.py:1152 flatcamTools/ToolCutOut.py:317 +#: flatcamGUI/ObjectUI.py:1419 flatcamTools/ToolCutOut.py:327 msgid "Geometry Object" msgstr "" -#: flatcamGUI/ObjectUI.py:1186 +#: flatcamGUI/ObjectUI.py:1465 msgid "" "Tools in this Geometry object used for cutting.\n" "The 'Offset' entry will set an offset for the cut.\n" @@ -7019,28 +7383,28 @@ msgid "" "showed UI form entries named V-Tip Dia and V-Tip Angle." msgstr "" -#: flatcamGUI/ObjectUI.py:1203 flatcamGUI/ObjectUI.py:1903 flatcamGUI/PreferencesUI.py:4405 +#: flatcamGUI/ObjectUI.py:1482 flatcamGUI/ObjectUI.py:2231 flatcamGUI/PreferencesUI.py:4698 msgid "Plot Object" msgstr "" -#: flatcamGUI/ObjectUI.py:1217 flatcamGUI/ObjectUI.py:1916 flatcamGUI/ObjectUI.py:1926 -#: flatcamGUI/PreferencesUI.py:7241 flatcamTools/ToolCopperThieving.py:220 +#: flatcamGUI/ObjectUI.py:1495 flatcamGUI/ObjectUI.py:2244 flatcamGUI/ObjectUI.py:2254 +#: flatcamGUI/PreferencesUI.py:7747 flatcamTools/ToolCopperThieving.py:222 msgid "Dia" msgstr "" -#: flatcamGUI/ObjectUI.py:1217 flatcamGUI/ObjectUI.py:1916 -#: flatcamTools/ToolNonCopperClear.py:120 flatcamTools/ToolPaint.py:123 +#: flatcamGUI/ObjectUI.py:1495 flatcamGUI/ObjectUI.py:2244 flatcamTools/ToolNCC.py:132 +#: flatcamTools/ToolPaint.py:128 msgid "TT" msgstr "" -#: flatcamGUI/ObjectUI.py:1224 +#: flatcamGUI/ObjectUI.py:1502 msgid "" "This is the Tool Number.\n" "When ToolChange is checked, on toolchange event this value\n" "will be showed as a T1, T2 ... Tn" msgstr "" -#: flatcamGUI/ObjectUI.py:1235 +#: flatcamGUI/ObjectUI.py:1513 msgid "" "The value for the Offset can be:\n" "- Path -> There is no offset, the tool cut will be done through the geometry line.\n" @@ -7048,7 +7412,7 @@ msgid "" "- Out(side) -> The tool cut will follow the geometry line on the outside." msgstr "" -#: flatcamGUI/ObjectUI.py:1242 +#: flatcamGUI/ObjectUI.py:1520 msgid "" "The (Operation) Type has only informative value. Usually the UI form values \n" "are choose based on the operation type and this will serve as a reminder.\n" @@ -7058,7 +7422,7 @@ msgid "" "For Isolation we need a lower Feedrate as it use a milling bit with a fine tip." msgstr "" -#: flatcamGUI/ObjectUI.py:1251 +#: flatcamGUI/ObjectUI.py:1529 msgid "" "The Tool Type (TT) can be:\n" "- Circular with 1 ... 4 teeth -> it is informative only. Being circular the cut width in " @@ -7074,7 +7438,7 @@ msgid "" "Choosing the V-Shape Tool Type automatically will select the Operation Type as Isolation." msgstr "" -#: flatcamGUI/ObjectUI.py:1263 +#: flatcamGUI/ObjectUI.py:1541 msgid "" "Plot column. It is visible only for MultiGeo geometries, meaning geometries that holds " "the geometry\n" @@ -7085,7 +7449,7 @@ msgid "" "for the corresponding tool." msgstr "" -#: flatcamGUI/ObjectUI.py:1281 +#: flatcamGUI/ObjectUI.py:1559 msgid "" "The value to offset the cut when \n" "the Offset type selected is 'Offset'.\n" @@ -7093,90 +7457,55 @@ msgid "" "cut and negative for 'inside' cut." msgstr "" -#: flatcamGUI/ObjectUI.py:1306 +#: flatcamGUI/ObjectUI.py:1578 flatcamTools/ToolNCC.py:209 flatcamTools/ToolNCC.py:921 +#: flatcamTools/ToolPaint.py:192 flatcamTools/ToolPaint.py:846 +#: flatcamTools/ToolSolderPaste.py:559 +msgid "New Tool" +msgstr "" + +#: flatcamGUI/ObjectUI.py:1595 msgid "" "Add a new tool to the Tool Table\n" "with the specified diameter." msgstr "" -#: flatcamGUI/ObjectUI.py:1314 -msgid "Add Tool from DataBase" +#: flatcamGUI/ObjectUI.py:1600 flatcamTools/ToolNCC.py:300 flatcamTools/ToolNCC.py:634 +#: flatcamTools/ToolPaint.py:283 flatcamTools/ToolPaint.py:676 +msgid "Add from DB" msgstr "" -#: flatcamGUI/ObjectUI.py:1316 +#: flatcamGUI/ObjectUI.py:1602 flatcamTools/ToolNCC.py:302 flatcamTools/ToolPaint.py:285 msgid "" "Add a new tool to the Tool Table\n" "from the Tool DataBase." msgstr "" -#: flatcamGUI/ObjectUI.py:1326 +#: flatcamGUI/ObjectUI.py:1617 msgid "" "Copy a selection of tools in the Tool Table\n" "by first selecting a row in the Tool Table." msgstr "" -#: flatcamGUI/ObjectUI.py:1332 +#: flatcamGUI/ObjectUI.py:1623 msgid "" "Delete a selection of tools in the Tool Table\n" "by first selecting a row in the Tool Table." msgstr "" -#: flatcamGUI/ObjectUI.py:1356 -msgid "" -"The data used for creating GCode.\n" -"Each tool store it's own set of such data." -msgstr "" - -#: flatcamGUI/ObjectUI.py:1426 flatcamGUI/PreferencesUI.py:3981 -#: flatcamGUI/PreferencesUI.py:5348 flatcamTools/ToolCutOut.py:153 -msgid "Multi-Depth" -msgstr "" - -#: flatcamGUI/ObjectUI.py:1429 flatcamGUI/PreferencesUI.py:3984 -#: flatcamGUI/PreferencesUI.py:5351 flatcamTools/ToolCutOut.py:156 -msgid "" -"Use multiple passes to limit\n" -"the cut depth in each pass. Will\n" -"cut multiple times until Cut Z is\n" -"reached." -msgstr "" - -#: flatcamGUI/ObjectUI.py:1443 flatcamGUI/PreferencesUI.py:5363 -#: flatcamTools/ToolCutOut.py:170 -msgid "Depth of each pass (positive)." -msgstr "" - -#: flatcamGUI/ObjectUI.py:1454 flatcamGUI/PreferencesUI.py:4016 +#: flatcamGUI/ObjectUI.py:1750 flatcamGUI/PreferencesUI.py:4296 msgid "" "Height of the tool when\n" "moving without cutting." msgstr "" -#: flatcamGUI/ObjectUI.py:1481 flatcamGUI/PreferencesUI.py:4037 -msgid "" -"Include tool-change sequence\n" -"in the Machine Code (Pause for tool change)." -msgstr "" - -#: flatcamGUI/ObjectUI.py:1531 flatcamGUI/PreferencesUI.py:4086 -#: flatcamGUI/PreferencesUI.py:6553 flatcamTools/ToolSolderPaste.py:252 -msgid "Feedrate X-Y" -msgstr "" - -#: flatcamGUI/ObjectUI.py:1533 flatcamGUI/PreferencesUI.py:4088 -msgid "" -"Cutting speed in the XY\n" -"plane in units per minute" -msgstr "" - -#: flatcamGUI/ObjectUI.py:1547 flatcamGUI/PreferencesUI.py:4103 +#: flatcamGUI/ObjectUI.py:1783 flatcamGUI/PreferencesUI.py:4395 msgid "" "Cutting speed in the XY\n" "plane in units per minute.\n" "It is called also Plunge." msgstr "" -#: flatcamGUI/ObjectUI.py:1562 flatcamGUI/PreferencesUI.py:4212 +#: flatcamGUI/ObjectUI.py:1798 flatcamGUI/PreferencesUI.py:4505 msgid "" "Cutting speed in the XY plane\n" "(in units per minute).\n" @@ -7185,62 +7514,34 @@ msgid "" "ignore for any other cases." msgstr "" -#: flatcamGUI/ObjectUI.py:1580 flatcamGUI/PreferencesUI.py:4228 -msgid "Re-cut" -msgstr "" - -#: flatcamGUI/ObjectUI.py:1582 flatcamGUI/ObjectUI.py:1594 flatcamGUI/PreferencesUI.py:4230 -#: flatcamGUI/PreferencesUI.py:4242 -msgid "" -"In order to remove possible\n" -"copper leftovers where first cut\n" -"meet with last cut, we generate an\n" -"extended cut over the first cut section." -msgstr "" - -#: flatcamGUI/ObjectUI.py:1606 flatcamGUI/PreferencesUI.py:4120 +#: flatcamGUI/ObjectUI.py:1842 flatcamGUI/PreferencesUI.py:4412 msgid "" "Speed of the spindle in RPM (optional).\n" "If LASER preprocessor is used,\n" "this value is the power of laser." msgstr "" -#: flatcamGUI/ObjectUI.py:1642 flatcamGUI/PreferencesUI.py:4157 +#: flatcamGUI/ObjectUI.py:1945 flatcamGUI/PreferencesUI.py:4317 +msgid "" +"Include tool-change sequence\n" +"in the Machine Code (Pause for tool change)." +msgstr "" + +#: flatcamGUI/ObjectUI.py:2014 flatcamGUI/PreferencesUI.py:4449 msgid "" "The Preprocessor file that dictates\n" "the Machine Code (like GCode, RML, HPGL) output." msgstr "" -#: flatcamGUI/ObjectUI.py:1689 -msgid "Apply parameters to all tools" -msgstr "" - -#: flatcamGUI/ObjectUI.py:1691 -msgid "" -"The parameters in the current form will be applied\n" -"on all the tools from the Tool Table." -msgstr "" - -#: flatcamGUI/ObjectUI.py:1700 -msgid "" -"Add at least one tool in the tool-table.\n" -"Click the header to select all, or Ctrl + LMB\n" -"for custom selection of tools." -msgstr "" - -#: flatcamGUI/ObjectUI.py:1707 -msgid "Generate CNCJob object" -msgstr "" - -#: flatcamGUI/ObjectUI.py:1709 +#: flatcamGUI/ObjectUI.py:2035 msgid "Generate the CNC Job object." msgstr "" -#: flatcamGUI/ObjectUI.py:1726 +#: flatcamGUI/ObjectUI.py:2052 msgid "Launch Paint Tool in Tools Tab." msgstr "" -#: flatcamGUI/ObjectUI.py:1734 flatcamGUI/PreferencesUI.py:5524 +#: flatcamGUI/ObjectUI.py:2060 flatcamGUI/PreferencesUI.py:5874 msgid "" "Creates tool paths to cover the\n" "whole area of a polygon (remove\n" @@ -7248,15 +7549,15 @@ msgid "" "to click on the desired polygon." msgstr "" -#: flatcamGUI/ObjectUI.py:1786 +#: flatcamGUI/ObjectUI.py:2115 msgid "CNC Job Object" msgstr "" -#: flatcamGUI/ObjectUI.py:1798 flatcamGUI/PreferencesUI.py:4410 +#: flatcamGUI/ObjectUI.py:2126 flatcamGUI/PreferencesUI.py:4703 msgid "Plot kind" msgstr "" -#: flatcamGUI/ObjectUI.py:1801 flatcamGUI/PreferencesUI.py:4412 +#: flatcamGUI/ObjectUI.py:2129 flatcamGUI/PreferencesUI.py:4705 msgid "" "This selects the kind of geometries on the canvas to plot.\n" "Those can be either of type 'Travel' which means the moves\n" @@ -7264,46 +7565,46 @@ msgid "" "which means the moves that cut into the material." msgstr "" -#: flatcamGUI/ObjectUI.py:1810 flatcamGUI/PreferencesUI.py:4420 +#: flatcamGUI/ObjectUI.py:2138 flatcamGUI/PreferencesUI.py:4713 msgid "Travel" msgstr "" -#: flatcamGUI/ObjectUI.py:1814 flatcamGUI/PreferencesUI.py:4429 +#: flatcamGUI/ObjectUI.py:2142 flatcamGUI/PreferencesUI.py:4722 msgid "Display Annotation" msgstr "" -#: flatcamGUI/ObjectUI.py:1816 flatcamGUI/PreferencesUI.py:4431 +#: flatcamGUI/ObjectUI.py:2144 flatcamGUI/PreferencesUI.py:4724 msgid "" "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." msgstr "" -#: flatcamGUI/ObjectUI.py:1831 +#: flatcamGUI/ObjectUI.py:2159 msgid "Travelled dist." msgstr "" -#: flatcamGUI/ObjectUI.py:1833 flatcamGUI/ObjectUI.py:1838 +#: flatcamGUI/ObjectUI.py:2161 flatcamGUI/ObjectUI.py:2166 msgid "" "This is the total travelled distance on X-Y plane.\n" "In current units." msgstr "" -#: flatcamGUI/ObjectUI.py:1843 +#: flatcamGUI/ObjectUI.py:2171 msgid "Estimated time" msgstr "" -#: flatcamGUI/ObjectUI.py:1845 flatcamGUI/ObjectUI.py:1850 +#: flatcamGUI/ObjectUI.py:2173 flatcamGUI/ObjectUI.py:2178 msgid "" "This is the estimated time to do the routing/drilling,\n" "without the time spent in ToolChange events." msgstr "" -#: flatcamGUI/ObjectUI.py:1885 +#: flatcamGUI/ObjectUI.py:2213 msgid "CNC Tools Table" msgstr "" -#: flatcamGUI/ObjectUI.py:1888 +#: flatcamGUI/ObjectUI.py:2216 msgid "" "Tools in this CNCJob object used for cutting.\n" "The tool diameter is used for plotting on canvas.\n" @@ -7316,55 +7617,55 @@ msgid "" "ball(B), or V-Shaped(V)." msgstr "" -#: flatcamGUI/ObjectUI.py:1916 flatcamGUI/ObjectUI.py:1927 +#: flatcamGUI/ObjectUI.py:2244 flatcamGUI/ObjectUI.py:2255 msgid "P" msgstr "" -#: flatcamGUI/ObjectUI.py:1937 +#: flatcamGUI/ObjectUI.py:2265 msgid "Update Plot" msgstr "" -#: flatcamGUI/ObjectUI.py:1939 +#: flatcamGUI/ObjectUI.py:2267 msgid "Update the plot." msgstr "" -#: flatcamGUI/ObjectUI.py:1946 flatcamGUI/PreferencesUI.py:4827 +#: flatcamGUI/ObjectUI.py:2274 flatcamGUI/PreferencesUI.py:5120 msgid "Export CNC Code" msgstr "" -#: flatcamGUI/ObjectUI.py:1948 flatcamGUI/PreferencesUI.py:4768 -#: flatcamGUI/PreferencesUI.py:4829 +#: flatcamGUI/ObjectUI.py:2276 flatcamGUI/PreferencesUI.py:5061 +#: flatcamGUI/PreferencesUI.py:5122 msgid "" "Export and save G-Code to\n" "make this object to a file." msgstr "" -#: flatcamGUI/ObjectUI.py:1954 +#: flatcamGUI/ObjectUI.py:2282 msgid "Prepend to CNC Code" msgstr "" -#: flatcamGUI/ObjectUI.py:1956 flatcamGUI/ObjectUI.py:1963 flatcamGUI/PreferencesUI.py:4784 +#: flatcamGUI/ObjectUI.py:2284 flatcamGUI/ObjectUI.py:2291 flatcamGUI/PreferencesUI.py:5077 msgid "" "Type here any G-Code commands you would\n" "like to add at the beginning of the G-Code file." msgstr "" -#: flatcamGUI/ObjectUI.py:1969 +#: flatcamGUI/ObjectUI.py:2297 msgid "Append to CNC Code" msgstr "" -#: flatcamGUI/ObjectUI.py:1971 flatcamGUI/ObjectUI.py:1979 flatcamGUI/PreferencesUI.py:4800 +#: flatcamGUI/ObjectUI.py:2299 flatcamGUI/ObjectUI.py:2307 flatcamGUI/PreferencesUI.py:5093 msgid "" "Type here any G-Code commands you would\n" "like to append to the generated file.\n" "I.e.: M2 (End of program)" msgstr "" -#: flatcamGUI/ObjectUI.py:1993 flatcamGUI/PreferencesUI.py:4835 +#: flatcamGUI/ObjectUI.py:2321 flatcamGUI/PreferencesUI.py:5128 msgid "Toolchange G-Code" msgstr "" -#: flatcamGUI/ObjectUI.py:1996 flatcamGUI/PreferencesUI.py:4838 +#: flatcamGUI/ObjectUI.py:2324 flatcamGUI/PreferencesUI.py:5131 msgid "" "Type here any G-Code commands you would\n" "like to be executed when Toolchange event is encountered.\n" @@ -7377,7 +7678,7 @@ msgid "" "having as template the 'Toolchange Custom' posprocessor file." msgstr "" -#: flatcamGUI/ObjectUI.py:2011 +#: flatcamGUI/ObjectUI.py:2339 msgid "" "Type here any G-Code commands you would\n" "like to be executed when Toolchange event is encountered.\n" @@ -7388,270 +7689,271 @@ msgid "" "that has 'toolchange_custom' in it's name." msgstr "" -#: flatcamGUI/ObjectUI.py:2026 flatcamGUI/PreferencesUI.py:4877 +#: flatcamGUI/ObjectUI.py:2354 flatcamGUI/PreferencesUI.py:5170 msgid "Use Toolchange Macro" msgstr "" -#: flatcamGUI/ObjectUI.py:2028 flatcamGUI/PreferencesUI.py:4879 +#: flatcamGUI/ObjectUI.py:2356 flatcamGUI/PreferencesUI.py:5172 msgid "" "Check this box if you want to use\n" "a Custom Toolchange GCode (macro)." msgstr "" -#: flatcamGUI/ObjectUI.py:2036 flatcamGUI/PreferencesUI.py:4891 +#: flatcamGUI/ObjectUI.py:2364 flatcamGUI/PreferencesUI.py:5184 msgid "" "A list of the FlatCAM variables that can be used\n" "in the Toolchange event.\n" "They have to be surrounded by the '%' symbol" msgstr "" -#: flatcamGUI/ObjectUI.py:2043 flatcamGUI/PreferencesUI.py:2447 -#: flatcamGUI/PreferencesUI.py:3555 flatcamGUI/PreferencesUI.py:4347 -#: flatcamGUI/PreferencesUI.py:4898 flatcamGUI/PreferencesUI.py:5017 -#: flatcamGUI/PreferencesUI.py:5301 flatcamGUI/PreferencesUI.py:5458 -#: flatcamGUI/PreferencesUI.py:5676 flatcamGUI/PreferencesUI.py:5973 -#: flatcamGUI/PreferencesUI.py:6224 flatcamGUI/PreferencesUI.py:6438 -#: flatcamGUI/PreferencesUI.py:6663 flatcamGUI/PreferencesUI.py:6685 -#: flatcamGUI/PreferencesUI.py:6909 flatcamGUI/PreferencesUI.py:6946 -#: flatcamGUI/PreferencesUI.py:7140 flatcamGUI/PreferencesUI.py:7394 -#: flatcamGUI/PreferencesUI.py:7510 flatcamTools/ToolCopperThieving.py:89 -#: flatcamTools/ToolFiducials.py:149 flatcamTools/ToolNonCopperClear.py:315 +#: flatcamGUI/ObjectUI.py:2371 flatcamGUI/PreferencesUI.py:2627 +#: flatcamGUI/PreferencesUI.py:3833 flatcamGUI/PreferencesUI.py:4640 +#: flatcamGUI/PreferencesUI.py:5191 flatcamGUI/PreferencesUI.py:5310 +#: flatcamGUI/PreferencesUI.py:5640 flatcamGUI/PreferencesUI.py:5797 +#: flatcamGUI/PreferencesUI.py:6164 flatcamGUI/PreferencesUI.py:6461 +#: flatcamGUI/PreferencesUI.py:6711 flatcamGUI/PreferencesUI.py:6942 +#: flatcamGUI/PreferencesUI.py:7169 flatcamGUI/PreferencesUI.py:7191 +#: flatcamGUI/PreferencesUI.py:7415 flatcamGUI/PreferencesUI.py:7452 +#: flatcamGUI/PreferencesUI.py:7646 flatcamGUI/PreferencesUI.py:7900 +#: flatcamGUI/PreferencesUI.py:8016 flatcamGUI/PreferencesUI.py:8135 +#: flatcamGUI/PreferencesUI.py:8347 flatcamGUI/PreferencesUI.py:8556 +#: flatcamTools/ToolCopperThieving.py:90 flatcamTools/ToolFiducials.py:149 +#: flatcamTools/ToolInvertGerber.py:82 msgid "Parameters" msgstr "" -#: flatcamGUI/ObjectUI.py:2046 flatcamGUI/PreferencesUI.py:4903 +#: flatcamGUI/ObjectUI.py:2374 flatcamGUI/PreferencesUI.py:5196 msgid "FlatCAM CNC parameters" msgstr "" -#: flatcamGUI/ObjectUI.py:2047 flatcamGUI/PreferencesUI.py:4908 +#: flatcamGUI/ObjectUI.py:2375 flatcamGUI/PreferencesUI.py:5201 msgid "tool number" msgstr "" -#: flatcamGUI/ObjectUI.py:2048 flatcamGUI/PreferencesUI.py:4909 +#: flatcamGUI/ObjectUI.py:2376 flatcamGUI/PreferencesUI.py:5202 msgid "tool diameter" msgstr "" -#: flatcamGUI/ObjectUI.py:2049 flatcamGUI/PreferencesUI.py:4910 +#: flatcamGUI/ObjectUI.py:2377 flatcamGUI/PreferencesUI.py:5203 msgid "for Excellon, total number of drills" msgstr "" -#: flatcamGUI/ObjectUI.py:2051 flatcamGUI/PreferencesUI.py:4912 +#: flatcamGUI/ObjectUI.py:2379 flatcamGUI/PreferencesUI.py:5205 msgid "X coord for Toolchange" msgstr "" -#: flatcamGUI/ObjectUI.py:2052 flatcamGUI/PreferencesUI.py:4913 +#: flatcamGUI/ObjectUI.py:2380 flatcamGUI/PreferencesUI.py:5206 msgid "Y coord for Toolchange" msgstr "" -#: flatcamGUI/ObjectUI.py:2053 flatcamGUI/PreferencesUI.py:4915 +#: flatcamGUI/ObjectUI.py:2381 flatcamGUI/PreferencesUI.py:5208 msgid "Z coord for Toolchange" msgstr "" -#: flatcamGUI/ObjectUI.py:2054 +#: flatcamGUI/ObjectUI.py:2382 msgid "depth where to cut" msgstr "" -#: flatcamGUI/ObjectUI.py:2055 +#: flatcamGUI/ObjectUI.py:2383 msgid "height where to travel" msgstr "" -#: flatcamGUI/ObjectUI.py:2056 flatcamGUI/PreferencesUI.py:4918 +#: flatcamGUI/ObjectUI.py:2384 flatcamGUI/PreferencesUI.py:5211 msgid "the step value for multidepth cut" msgstr "" -#: flatcamGUI/ObjectUI.py:2058 flatcamGUI/PreferencesUI.py:4920 +#: flatcamGUI/ObjectUI.py:2386 flatcamGUI/PreferencesUI.py:5213 msgid "the value for the spindle speed" msgstr "" -#: flatcamGUI/ObjectUI.py:2060 +#: flatcamGUI/ObjectUI.py:2388 msgid "time to dwell to allow the spindle to reach it's set RPM" msgstr "" -#: flatcamGUI/ObjectUI.py:2076 +#: flatcamGUI/ObjectUI.py:2404 msgid "View CNC Code" msgstr "" -#: flatcamGUI/ObjectUI.py:2078 +#: flatcamGUI/ObjectUI.py:2406 msgid "" "Opens TAB to view/modify/print G-Code\n" "file." msgstr "" -#: flatcamGUI/ObjectUI.py:2083 +#: flatcamGUI/ObjectUI.py:2411 msgid "Save CNC Code" msgstr "" -#: flatcamGUI/ObjectUI.py:2085 +#: flatcamGUI/ObjectUI.py:2413 msgid "" "Opens dialog to save G-Code\n" "file." msgstr "" -#: flatcamGUI/ObjectUI.py:2116 +#: flatcamGUI/ObjectUI.py:2447 msgid "Script Object" msgstr "" -#: flatcamGUI/ObjectUI.py:2138 flatcamGUI/ObjectUI.py:2211 +#: flatcamGUI/ObjectUI.py:2467 flatcamGUI/ObjectUI.py:2541 msgid "Auto Completer" msgstr "" -#: flatcamGUI/ObjectUI.py:2140 +#: flatcamGUI/ObjectUI.py:2469 msgid "This selects if the auto completer is enabled in the Script Editor." msgstr "" -#: flatcamGUI/ObjectUI.py:2182 +#: flatcamGUI/ObjectUI.py:2514 msgid "Document Object" msgstr "" -#: flatcamGUI/ObjectUI.py:2213 +#: flatcamGUI/ObjectUI.py:2543 msgid "This selects if the auto completer is enabled in the Document Editor." msgstr "" -#: flatcamGUI/ObjectUI.py:2231 +#: flatcamGUI/ObjectUI.py:2561 msgid "Font Type" msgstr "" -#: flatcamGUI/ObjectUI.py:2248 flatcamGUI/PreferencesUI.py:1103 +#: flatcamGUI/ObjectUI.py:2578 flatcamGUI/PreferencesUI.py:1278 msgid "Font Size" msgstr "" -#: flatcamGUI/ObjectUI.py:2284 +#: flatcamGUI/ObjectUI.py:2614 msgid "Alignment" msgstr "" -#: flatcamGUI/ObjectUI.py:2289 +#: flatcamGUI/ObjectUI.py:2619 msgid "Align Left" msgstr "" -#: flatcamGUI/ObjectUI.py:2294 -msgid "Center" -msgstr "" - -#: flatcamGUI/ObjectUI.py:2299 +#: flatcamGUI/ObjectUI.py:2629 msgid "Align Right" msgstr "" -#: flatcamGUI/ObjectUI.py:2304 +#: flatcamGUI/ObjectUI.py:2634 msgid "Justify" msgstr "" -#: flatcamGUI/ObjectUI.py:2311 +#: flatcamGUI/ObjectUI.py:2641 msgid "Font Color" msgstr "" -#: flatcamGUI/ObjectUI.py:2313 +#: flatcamGUI/ObjectUI.py:2643 msgid "Set the font color for the selected text" msgstr "" -#: flatcamGUI/ObjectUI.py:2327 +#: flatcamGUI/ObjectUI.py:2657 msgid "Selection Color" msgstr "" -#: flatcamGUI/ObjectUI.py:2329 +#: flatcamGUI/ObjectUI.py:2659 msgid "Set the selection color when doing text selection." msgstr "" -#: flatcamGUI/ObjectUI.py:2343 +#: flatcamGUI/ObjectUI.py:2673 msgid "Tab Size" msgstr "" -#: flatcamGUI/ObjectUI.py:2345 +#: flatcamGUI/ObjectUI.py:2675 msgid "Set the tab size. In pixels. Default value is 80 pixels." msgstr "" -#: flatcamGUI/PlotCanvasLegacy.py:1254 +#: flatcamGUI/PlotCanvasLegacy.py:1301 msgid "" "Could not annotate due of a difference between the number of text elements and the number " "of text positions." msgstr "" -#: flatcamGUI/PreferencesUI.py:324 +#: flatcamGUI/PreferencesUI.py:343 msgid "GUI Preferences" msgstr "" -#: flatcamGUI/PreferencesUI.py:334 +#: flatcamGUI/PreferencesUI.py:353 msgid "Theme" msgstr "" -#: flatcamGUI/PreferencesUI.py:336 -msgid "Select a theme for FlatCAM." +#: flatcamGUI/PreferencesUI.py:355 +msgid "" +"Select a theme for FlatCAM.\n" +"It will theme the plot area." msgstr "" -#: flatcamGUI/PreferencesUI.py:340 +#: flatcamGUI/PreferencesUI.py:360 msgid "Light" msgstr "" -#: flatcamGUI/PreferencesUI.py:341 +#: flatcamGUI/PreferencesUI.py:361 msgid "Dark" msgstr "" -#: flatcamGUI/PreferencesUI.py:348 +#: flatcamGUI/PreferencesUI.py:368 msgid "Use Gray Icons" msgstr "" -#: flatcamGUI/PreferencesUI.py:350 +#: flatcamGUI/PreferencesUI.py:370 msgid "" "Check this box to use a set of icons with\n" "a lighter (gray) color. To be used when a\n" "full dark theme is applied." msgstr "" -#: flatcamGUI/PreferencesUI.py:356 +#: flatcamGUI/PreferencesUI.py:376 msgid "Apply Theme" msgstr "" -#: flatcamGUI/PreferencesUI.py:358 +#: flatcamGUI/PreferencesUI.py:378 msgid "" "Select a theme for FlatCAM.\n" +"It will theme the plot area.\n" "The application will restart after change." msgstr "" -#: flatcamGUI/PreferencesUI.py:369 +#: flatcamGUI/PreferencesUI.py:390 msgid "Layout" msgstr "" -#: flatcamGUI/PreferencesUI.py:371 +#: flatcamGUI/PreferencesUI.py:392 msgid "" "Select an layout for FlatCAM.\n" "It is applied immediately." msgstr "" -#: flatcamGUI/PreferencesUI.py:390 +#: flatcamGUI/PreferencesUI.py:412 msgid "Style" msgstr "" -#: flatcamGUI/PreferencesUI.py:392 +#: flatcamGUI/PreferencesUI.py:414 msgid "" "Select an style for FlatCAM.\n" "It will be applied at the next app start." msgstr "" -#: flatcamGUI/PreferencesUI.py:406 +#: flatcamGUI/PreferencesUI.py:428 msgid "Activate HDPI Support" msgstr "" -#: flatcamGUI/PreferencesUI.py:408 +#: flatcamGUI/PreferencesUI.py:430 msgid "" "Enable High DPI support for FlatCAM.\n" "It will be applied at the next app start." msgstr "" -#: flatcamGUI/PreferencesUI.py:422 +#: flatcamGUI/PreferencesUI.py:444 msgid "Display Hover Shape" msgstr "" -#: flatcamGUI/PreferencesUI.py:424 +#: flatcamGUI/PreferencesUI.py:446 msgid "" "Enable display of a hover shape for FlatCAM objects.\n" "It is displayed whenever the mouse cursor is hovering\n" "over any kind of not-selected object." msgstr "" -#: flatcamGUI/PreferencesUI.py:431 +#: flatcamGUI/PreferencesUI.py:453 msgid "Display Selection Shape" msgstr "" -#: flatcamGUI/PreferencesUI.py:433 +#: flatcamGUI/PreferencesUI.py:455 msgid "" "Enable the display of a selection shape for FlatCAM objects.\n" "It is displayed whenever the mouse selects an object\n" @@ -7659,28 +7961,28 @@ msgid "" "right to left." msgstr "" -#: flatcamGUI/PreferencesUI.py:446 +#: flatcamGUI/PreferencesUI.py:468 msgid "Left-Right Selection Color" msgstr "" -#: flatcamGUI/PreferencesUI.py:449 flatcamGUI/PreferencesUI.py:515 -#: flatcamGUI/PreferencesUI.py:1882 flatcamGUI/PreferencesUI.py:2903 -#: flatcamGUI/PreferencesUI.py:3894 flatcamGUI/PreferencesUI.py:4534 -#: flatcamGUI/PreferencesUI.py:4600 flatcamTools/ToolRulesCheck.py:179 +#: flatcamGUI/PreferencesUI.py:471 flatcamGUI/PreferencesUI.py:537 +#: flatcamGUI/PreferencesUI.py:2062 flatcamGUI/PreferencesUI.py:3085 +#: flatcamGUI/PreferencesUI.py:4174 flatcamGUI/PreferencesUI.py:4827 +#: flatcamGUI/PreferencesUI.py:4893 flatcamTools/ToolRulesCheck.py:186 msgid "Outline" msgstr "" -#: flatcamGUI/PreferencesUI.py:451 +#: flatcamGUI/PreferencesUI.py:473 msgid "Set the line color for the 'left to right' selection box." msgstr "" -#: flatcamGUI/PreferencesUI.py:465 flatcamGUI/PreferencesUI.py:532 -#: flatcamGUI/PreferencesUI.py:1899 flatcamGUI/PreferencesUI.py:2920 -#: flatcamGUI/PreferencesUI.py:4551 flatcamGUI/PreferencesUI.py:4617 +#: flatcamGUI/PreferencesUI.py:487 flatcamGUI/PreferencesUI.py:554 +#: flatcamGUI/PreferencesUI.py:2079 flatcamGUI/PreferencesUI.py:3102 +#: flatcamGUI/PreferencesUI.py:4844 flatcamGUI/PreferencesUI.py:4910 msgid "Fill" msgstr "" -#: flatcamGUI/PreferencesUI.py:467 +#: flatcamGUI/PreferencesUI.py:489 msgid "" "Set the fill color for the selection box\n" "in case that the selection is done from left to right.\n" @@ -7688,25 +7990,25 @@ msgid "" "digits are for alpha (transparency) level." msgstr "" -#: flatcamGUI/PreferencesUI.py:485 flatcamGUI/PreferencesUI.py:552 -#: flatcamGUI/PreferencesUI.py:1918 flatcamGUI/PreferencesUI.py:2939 -#: flatcamGUI/PreferencesUI.py:4570 +#: flatcamGUI/PreferencesUI.py:507 flatcamGUI/PreferencesUI.py:574 +#: flatcamGUI/PreferencesUI.py:2098 flatcamGUI/PreferencesUI.py:3121 +#: flatcamGUI/PreferencesUI.py:4863 msgid "Alpha" msgstr "" -#: flatcamGUI/PreferencesUI.py:487 +#: flatcamGUI/PreferencesUI.py:509 msgid "Set the fill transparency for the 'left to right' selection box." msgstr "" -#: flatcamGUI/PreferencesUI.py:511 +#: flatcamGUI/PreferencesUI.py:533 msgid "Right-Left Selection Color" msgstr "" -#: flatcamGUI/PreferencesUI.py:517 +#: flatcamGUI/PreferencesUI.py:539 msgid "Set the line color for the 'right to left' selection box." msgstr "" -#: flatcamGUI/PreferencesUI.py:534 +#: flatcamGUI/PreferencesUI.py:556 msgid "" "Set the fill color for the selection box\n" "in case that the selection is done from right to left.\n" @@ -7714,260 +8016,260 @@ msgid "" "digits are for alpha (transparency) level." msgstr "" -#: flatcamGUI/PreferencesUI.py:554 +#: flatcamGUI/PreferencesUI.py:576 msgid "Set the fill transparency for selection 'right to left' box." msgstr "" -#: flatcamGUI/PreferencesUI.py:581 +#: flatcamGUI/PreferencesUI.py:603 msgid "Editor Color" msgstr "" -#: flatcamGUI/PreferencesUI.py:585 +#: flatcamGUI/PreferencesUI.py:607 msgid "Drawing" msgstr "" -#: flatcamGUI/PreferencesUI.py:587 +#: flatcamGUI/PreferencesUI.py:609 msgid "Set the color for the shape." msgstr "" -#: flatcamGUI/PreferencesUI.py:604 +#: flatcamGUI/PreferencesUI.py:626 msgid "Set the color of the shape when selected." msgstr "" -#: flatcamGUI/PreferencesUI.py:627 +#: flatcamGUI/PreferencesUI.py:649 msgid "Project Items Color" msgstr "" -#: flatcamGUI/PreferencesUI.py:631 +#: flatcamGUI/PreferencesUI.py:653 msgid "Enabled" msgstr "" -#: flatcamGUI/PreferencesUI.py:633 +#: flatcamGUI/PreferencesUI.py:655 msgid "Set the color of the items in Project Tab Tree." msgstr "" -#: flatcamGUI/PreferencesUI.py:647 +#: flatcamGUI/PreferencesUI.py:669 msgid "Disabled" msgstr "" -#: flatcamGUI/PreferencesUI.py:649 +#: flatcamGUI/PreferencesUI.py:671 msgid "" "Set the color of the items in Project Tab Tree,\n" "for the case when the items are disabled." msgstr "" -#: flatcamGUI/PreferencesUI.py:665 +#: flatcamGUI/PreferencesUI.py:687 msgid "Project AutoHide" msgstr "" -#: flatcamGUI/PreferencesUI.py:667 +#: flatcamGUI/PreferencesUI.py:689 msgid "" "Check this box if you want the project/selected/tool tab area to\n" "hide automatically when there are no objects loaded and\n" "to show whenever a new object is created." msgstr "" -#: flatcamGUI/PreferencesUI.py:934 +#: flatcamGUI/PreferencesUI.py:1109 msgid "App Settings" msgstr "" -#: flatcamGUI/PreferencesUI.py:955 +#: flatcamGUI/PreferencesUI.py:1130 msgid "Grid Settings" msgstr "" -#: flatcamGUI/PreferencesUI.py:959 +#: flatcamGUI/PreferencesUI.py:1134 msgid "X value" msgstr "" -#: flatcamGUI/PreferencesUI.py:961 +#: flatcamGUI/PreferencesUI.py:1136 msgid "This is the Grid snap value on X axis." msgstr "" -#: flatcamGUI/PreferencesUI.py:971 +#: flatcamGUI/PreferencesUI.py:1146 msgid "Y value" msgstr "" -#: flatcamGUI/PreferencesUI.py:973 +#: flatcamGUI/PreferencesUI.py:1148 msgid "This is the Grid snap value on Y axis." msgstr "" -#: flatcamGUI/PreferencesUI.py:983 +#: flatcamGUI/PreferencesUI.py:1158 msgid "Snap Max" msgstr "" -#: flatcamGUI/PreferencesUI.py:998 +#: flatcamGUI/PreferencesUI.py:1173 msgid "Workspace Settings" msgstr "" -#: flatcamGUI/PreferencesUI.py:1001 +#: flatcamGUI/PreferencesUI.py:1176 msgid "Active" msgstr "" -#: flatcamGUI/PreferencesUI.py:1003 +#: flatcamGUI/PreferencesUI.py:1178 msgid "" "Draw a delimiting rectangle on canvas.\n" "The purpose is to illustrate the limits for our work." msgstr "" -#: flatcamGUI/PreferencesUI.py:1011 +#: flatcamGUI/PreferencesUI.py:1186 msgid "" "Select the type of rectangle to be used on canvas,\n" "as valid workspace." msgstr "" -#: flatcamGUI/PreferencesUI.py:1077 +#: flatcamGUI/PreferencesUI.py:1252 msgid "Orientation" msgstr "" -#: flatcamGUI/PreferencesUI.py:1078 flatcamGUI/PreferencesUI.py:5884 -#: flatcamTools/ToolFilm.py:420 +#: flatcamGUI/PreferencesUI.py:1253 flatcamGUI/PreferencesUI.py:6372 +#: flatcamTools/ToolFilm.py:422 msgid "" "Can be:\n" "- Portrait\n" "- Landscape" msgstr "" -#: flatcamGUI/PreferencesUI.py:1082 flatcamGUI/PreferencesUI.py:5888 -#: flatcamTools/ToolFilm.py:424 +#: flatcamGUI/PreferencesUI.py:1257 flatcamGUI/PreferencesUI.py:6376 +#: flatcamTools/ToolFilm.py:426 msgid "Portrait" msgstr "" -#: flatcamGUI/PreferencesUI.py:1083 flatcamGUI/PreferencesUI.py:5889 -#: flatcamTools/ToolFilm.py:425 +#: flatcamGUI/PreferencesUI.py:1258 flatcamGUI/PreferencesUI.py:6377 +#: flatcamTools/ToolFilm.py:427 msgid "Landscape" msgstr "" -#: flatcamGUI/PreferencesUI.py:1107 +#: flatcamGUI/PreferencesUI.py:1282 msgid "Notebook" msgstr "" -#: flatcamGUI/PreferencesUI.py:1109 +#: flatcamGUI/PreferencesUI.py:1284 msgid "" "This sets the font size for the elements found in the Notebook.\n" "The notebook is the collapsible area in the left side of the GUI,\n" "and include the Project, Selected and Tool tabs." msgstr "" -#: flatcamGUI/PreferencesUI.py:1128 +#: flatcamGUI/PreferencesUI.py:1303 msgid "Axis" msgstr "" -#: flatcamGUI/PreferencesUI.py:1130 +#: flatcamGUI/PreferencesUI.py:1305 msgid "This sets the font size for canvas axis." msgstr "" -#: flatcamGUI/PreferencesUI.py:1147 +#: flatcamGUI/PreferencesUI.py:1322 msgid "Textbox" msgstr "" -#: flatcamGUI/PreferencesUI.py:1149 +#: flatcamGUI/PreferencesUI.py:1324 msgid "" "This sets the font size for the Textbox GUI\n" "elements that are used in FlatCAM." msgstr "" -#: flatcamGUI/PreferencesUI.py:1175 +#: flatcamGUI/PreferencesUI.py:1350 msgid "Mouse Settings" msgstr "" -#: flatcamGUI/PreferencesUI.py:1179 +#: flatcamGUI/PreferencesUI.py:1354 msgid "Cursor Shape" msgstr "" -#: flatcamGUI/PreferencesUI.py:1181 +#: flatcamGUI/PreferencesUI.py:1356 msgid "" "Choose a mouse cursor shape.\n" "- Small -> with a customizable size.\n" "- Big -> Infinite lines" msgstr "" -#: flatcamGUI/PreferencesUI.py:1187 +#: flatcamGUI/PreferencesUI.py:1362 msgid "Small" msgstr "" -#: flatcamGUI/PreferencesUI.py:1188 +#: flatcamGUI/PreferencesUI.py:1363 msgid "Big" msgstr "" -#: flatcamGUI/PreferencesUI.py:1195 +#: flatcamGUI/PreferencesUI.py:1370 msgid "Cursor Size" msgstr "" -#: flatcamGUI/PreferencesUI.py:1197 +#: flatcamGUI/PreferencesUI.py:1372 msgid "Set the size of the mouse cursor, in pixels." msgstr "" -#: flatcamGUI/PreferencesUI.py:1208 +#: flatcamGUI/PreferencesUI.py:1383 msgid "Cursor Width" msgstr "" -#: flatcamGUI/PreferencesUI.py:1210 +#: flatcamGUI/PreferencesUI.py:1385 msgid "Set the line width of the mouse cursor, in pixels." msgstr "" -#: flatcamGUI/PreferencesUI.py:1221 flatcamGUI/PreferencesUI.py:1228 +#: flatcamGUI/PreferencesUI.py:1396 flatcamGUI/PreferencesUI.py:1403 msgid "Cursor Color" msgstr "" -#: flatcamGUI/PreferencesUI.py:1223 +#: flatcamGUI/PreferencesUI.py:1398 msgid "Check this box to color mouse cursor." msgstr "" -#: flatcamGUI/PreferencesUI.py:1230 +#: flatcamGUI/PreferencesUI.py:1405 msgid "Set the color of the mouse cursor." msgstr "" -#: flatcamGUI/PreferencesUI.py:1253 +#: flatcamGUI/PreferencesUI.py:1428 msgid "Pan Button" msgstr "" -#: flatcamGUI/PreferencesUI.py:1255 +#: flatcamGUI/PreferencesUI.py:1430 msgid "" "Select the mouse button to use for panning:\n" "- MMB --> Middle Mouse Button\n" "- RMB --> Right Mouse Button" msgstr "" -#: flatcamGUI/PreferencesUI.py:1259 +#: flatcamGUI/PreferencesUI.py:1434 msgid "MMB" msgstr "" -#: flatcamGUI/PreferencesUI.py:1260 +#: flatcamGUI/PreferencesUI.py:1435 msgid "RMB" msgstr "" -#: flatcamGUI/PreferencesUI.py:1266 +#: flatcamGUI/PreferencesUI.py:1441 msgid "Multiple Selection" msgstr "" -#: flatcamGUI/PreferencesUI.py:1268 +#: flatcamGUI/PreferencesUI.py:1443 msgid "Select the key used for multiple selection." msgstr "" -#: flatcamGUI/PreferencesUI.py:1270 +#: flatcamGUI/PreferencesUI.py:1445 msgid "CTRL" msgstr "" -#: flatcamGUI/PreferencesUI.py:1271 +#: flatcamGUI/PreferencesUI.py:1446 msgid "SHIFT" msgstr "" -#: flatcamGUI/PreferencesUI.py:1282 +#: flatcamGUI/PreferencesUI.py:1457 msgid "Delete object confirmation" msgstr "" -#: flatcamGUI/PreferencesUI.py:1284 +#: flatcamGUI/PreferencesUI.py:1459 msgid "" "When checked the application will ask for user confirmation\n" "whenever the Delete object(s) event is triggered, either by\n" "menu shortcut or key shortcut." msgstr "" -#: flatcamGUI/PreferencesUI.py:1291 +#: flatcamGUI/PreferencesUI.py:1466 msgid "\"Open\" behavior" msgstr "" -#: flatcamGUI/PreferencesUI.py:1293 +#: flatcamGUI/PreferencesUI.py:1468 msgid "" "When checked the path for the last saved file is used when saving files,\n" "and the path for the last opened file is used when opening files.\n" @@ -7976,21 +8278,21 @@ msgid "" "path for saving files or the path for opening files." msgstr "" -#: flatcamGUI/PreferencesUI.py:1302 +#: flatcamGUI/PreferencesUI.py:1477 msgid "Enable ToolTips" msgstr "" -#: flatcamGUI/PreferencesUI.py:1304 +#: flatcamGUI/PreferencesUI.py:1479 msgid "" "Check this box if you want to have toolTips displayed\n" "when hovering with mouse over items throughout the App." msgstr "" -#: flatcamGUI/PreferencesUI.py:1311 +#: flatcamGUI/PreferencesUI.py:1486 msgid "Allow Machinist Unsafe Settings" msgstr "" -#: flatcamGUI/PreferencesUI.py:1313 +#: flatcamGUI/PreferencesUI.py:1488 msgid "" "If checked, some of the application settings will be allowed\n" "to have values that are usually unsafe to use.\n" @@ -7999,82 +8301,82 @@ msgid "" "<>: Don't change this unless you know what you are doing !!!" msgstr "" -#: flatcamGUI/PreferencesUI.py:1324 +#: flatcamGUI/PreferencesUI.py:1500 msgid "Bookmarks limit" msgstr "" -#: flatcamGUI/PreferencesUI.py:1326 +#: flatcamGUI/PreferencesUI.py:1502 msgid "" "The maximum number of bookmarks that may be installed in the menu.\n" "The number of bookmarks in the bookmark manager may be greater\n" "but the menu will hold only so much." msgstr "" -#: flatcamGUI/PreferencesUI.py:1335 +#: flatcamGUI/PreferencesUI.py:1511 msgid "Activity Icon" msgstr "" -#: flatcamGUI/PreferencesUI.py:1337 +#: flatcamGUI/PreferencesUI.py:1513 msgid "Select the GIF that show activity when FlatCAM is active." msgstr "" -#: flatcamGUI/PreferencesUI.py:1395 +#: flatcamGUI/PreferencesUI.py:1571 msgid "App Preferences" msgstr "" -#: flatcamGUI/PreferencesUI.py:1405 flatcamGUI/PreferencesUI.py:1811 -#: flatcamGUI/PreferencesUI.py:2359 flatcamGUI/PreferencesUI.py:2804 -#: flatcamGUI/PreferencesUI.py:3417 flatcamTools/ToolDistance.py:49 -#: flatcamTools/ToolDistanceMin.py:49 flatcamTools/ToolPcbWizard.py:127 -#: flatcamTools/ToolProperties.py:152 +#: flatcamGUI/PreferencesUI.py:1581 flatcamGUI/PreferencesUI.py:1991 +#: flatcamGUI/PreferencesUI.py:2539 flatcamGUI/PreferencesUI.py:2986 +#: flatcamGUI/PreferencesUI.py:3695 flatcamTools/ToolDistance.py:56 +#: flatcamTools/ToolDistanceMin.py:50 flatcamTools/ToolPcbWizard.py:127 +#: flatcamTools/ToolProperties.py:154 msgid "Units" msgstr "" -#: flatcamGUI/PreferencesUI.py:1406 +#: flatcamGUI/PreferencesUI.py:1582 msgid "" "The default value for FlatCAM units.\n" "Whatever is selected here is set every time\n" "FLatCAM is started." msgstr "" -#: flatcamGUI/PreferencesUI.py:1409 flatcamGUI/PreferencesUI.py:1817 -#: flatcamGUI/PreferencesUI.py:2365 flatcamGUI/PreferencesUI.py:2815 -#: flatcamGUI/PreferencesUI.py:3423 flatcamTools/ToolCalculators.py:62 +#: flatcamGUI/PreferencesUI.py:1585 flatcamGUI/PreferencesUI.py:1997 +#: flatcamGUI/PreferencesUI.py:2545 flatcamGUI/PreferencesUI.py:2997 +#: flatcamGUI/PreferencesUI.py:3701 flatcamTools/ToolCalculators.py:62 #: flatcamTools/ToolPcbWizard.py:126 msgid "MM" msgstr "" -#: flatcamGUI/PreferencesUI.py:1410 +#: flatcamGUI/PreferencesUI.py:1586 msgid "IN" msgstr "" -#: flatcamGUI/PreferencesUI.py:1416 +#: flatcamGUI/PreferencesUI.py:1592 msgid "Precision MM" msgstr "" -#: flatcamGUI/PreferencesUI.py:1418 +#: flatcamGUI/PreferencesUI.py:1594 msgid "" "The number of decimals used throughout the application\n" "when the set units are in METRIC system.\n" "Any change here require an application restart." msgstr "" -#: flatcamGUI/PreferencesUI.py:1430 +#: flatcamGUI/PreferencesUI.py:1606 msgid "Precision INCH" msgstr "" -#: flatcamGUI/PreferencesUI.py:1432 +#: flatcamGUI/PreferencesUI.py:1608 msgid "" "The number of decimals used throughout the application\n" "when the set units are in INCH system.\n" "Any change here require an application restart." msgstr "" -#: flatcamGUI/PreferencesUI.py:1444 +#: flatcamGUI/PreferencesUI.py:1620 msgid "Graphic Engine" msgstr "" -#: flatcamGUI/PreferencesUI.py:1445 +#: flatcamGUI/PreferencesUI.py:1621 msgid "" "Choose what graphic engine to use in FlatCAM.\n" "Legacy(2D) -> reduced functionality, slow performance but enhanced compatibility.\n" @@ -8084,19 +8386,19 @@ msgid "" "use the Legacy(2D) mode." msgstr "" -#: flatcamGUI/PreferencesUI.py:1451 +#: flatcamGUI/PreferencesUI.py:1627 msgid "Legacy(2D)" msgstr "" -#: flatcamGUI/PreferencesUI.py:1452 +#: flatcamGUI/PreferencesUI.py:1628 msgid "OpenGL(3D)" msgstr "" -#: flatcamGUI/PreferencesUI.py:1464 +#: flatcamGUI/PreferencesUI.py:1640 msgid "APP. LEVEL" msgstr "" -#: flatcamGUI/PreferencesUI.py:1465 +#: flatcamGUI/PreferencesUI.py:1641 msgid "" "Choose the default level of usage for FlatCAM.\n" "BASIC level -> reduced functionality, best for beginner's.\n" @@ -8106,11 +8408,11 @@ msgid "" "the Selected Tab for all kinds of FlatCAM objects." msgstr "" -#: flatcamGUI/PreferencesUI.py:1477 +#: flatcamGUI/PreferencesUI.py:1653 msgid "Portable app" msgstr "" -#: flatcamGUI/PreferencesUI.py:1478 +#: flatcamGUI/PreferencesUI.py:1654 msgid "" "Choose if the application should run as portable.\n" "\n" @@ -8119,89 +8421,89 @@ msgid "" "in the application folder, in the lib\\config subfolder." msgstr "" -#: flatcamGUI/PreferencesUI.py:1491 +#: flatcamGUI/PreferencesUI.py:1667 msgid "Languages" msgstr "" -#: flatcamGUI/PreferencesUI.py:1492 +#: flatcamGUI/PreferencesUI.py:1668 msgid "Set the language used throughout FlatCAM." msgstr "" -#: flatcamGUI/PreferencesUI.py:1498 +#: flatcamGUI/PreferencesUI.py:1674 msgid "Apply Language" msgstr "" -#: flatcamGUI/PreferencesUI.py:1499 +#: flatcamGUI/PreferencesUI.py:1675 msgid "" "Set the language used throughout FlatCAM.\n" "The app will restart after click." msgstr "" -#: flatcamGUI/PreferencesUI.py:1513 +#: flatcamGUI/PreferencesUI.py:1689 msgid "Startup Settings" msgstr "" -#: flatcamGUI/PreferencesUI.py:1517 +#: flatcamGUI/PreferencesUI.py:1693 msgid "Splash Screen" msgstr "" -#: flatcamGUI/PreferencesUI.py:1519 +#: flatcamGUI/PreferencesUI.py:1695 msgid "Enable display of the splash screen at application startup." msgstr "" -#: flatcamGUI/PreferencesUI.py:1531 +#: flatcamGUI/PreferencesUI.py:1707 msgid "Sys Tray Icon" msgstr "" -#: flatcamGUI/PreferencesUI.py:1533 +#: flatcamGUI/PreferencesUI.py:1709 msgid "Enable display of FlatCAM icon in Sys Tray." msgstr "" -#: flatcamGUI/PreferencesUI.py:1538 +#: flatcamGUI/PreferencesUI.py:1714 msgid "Show Shell" msgstr "" -#: flatcamGUI/PreferencesUI.py:1540 +#: flatcamGUI/PreferencesUI.py:1716 msgid "" "Check this box if you want the shell to\n" "start automatically at startup." msgstr "" -#: flatcamGUI/PreferencesUI.py:1547 +#: flatcamGUI/PreferencesUI.py:1723 msgid "Show Project" msgstr "" -#: flatcamGUI/PreferencesUI.py:1549 +#: flatcamGUI/PreferencesUI.py:1725 msgid "" "Check this box if you want the project/selected/tool tab area to\n" "to be shown automatically at startup." msgstr "" -#: flatcamGUI/PreferencesUI.py:1555 +#: flatcamGUI/PreferencesUI.py:1731 msgid "Version Check" msgstr "" -#: flatcamGUI/PreferencesUI.py:1557 +#: flatcamGUI/PreferencesUI.py:1733 msgid "" "Check this box if you want to check\n" "for a new version automatically at startup." msgstr "" -#: flatcamGUI/PreferencesUI.py:1564 +#: flatcamGUI/PreferencesUI.py:1740 msgid "Send Statistics" msgstr "" -#: flatcamGUI/PreferencesUI.py:1566 +#: flatcamGUI/PreferencesUI.py:1742 msgid "" "Check this box if you agree to send anonymous\n" "stats automatically at startup, to help improve FlatCAM." msgstr "" -#: flatcamGUI/PreferencesUI.py:1580 +#: flatcamGUI/PreferencesUI.py:1756 msgid "Workers number" msgstr "" -#: flatcamGUI/PreferencesUI.py:1582 flatcamGUI/PreferencesUI.py:1591 +#: flatcamGUI/PreferencesUI.py:1758 msgid "" "The number of Qthreads made available to the App.\n" "A bigger number may finish the jobs more quickly but\n" @@ -8211,133 +8513,156 @@ msgid "" "After change, it will be applied at next App start." msgstr "" -#: flatcamGUI/PreferencesUI.py:1604 +#: flatcamGUI/PreferencesUI.py:1772 msgid "Geo Tolerance" msgstr "" -#: flatcamGUI/PreferencesUI.py:1606 flatcamGUI/PreferencesUI.py:1615 +#: flatcamGUI/PreferencesUI.py:1774 msgid "" "This value can counter the effect of the Circle Steps\n" -"parameter. Default value is 0.01.\n" +"parameter. Default value is 0.005.\n" "A lower value will increase the detail both in image\n" "and in Gcode for the circles, with a higher cost in\n" "performance. Higher value will provide more\n" "performance at the expense of level of detail." msgstr "" -#: flatcamGUI/PreferencesUI.py:1634 +#: flatcamGUI/PreferencesUI.py:1794 msgid "Save Settings" msgstr "" -#: flatcamGUI/PreferencesUI.py:1638 +#: flatcamGUI/PreferencesUI.py:1798 msgid "Save Compressed Project" msgstr "" -#: flatcamGUI/PreferencesUI.py:1640 +#: flatcamGUI/PreferencesUI.py:1800 msgid "" "Whether to save a compressed or uncompressed project.\n" "When checked it will save a compressed FlatCAM project." msgstr "" -#: flatcamGUI/PreferencesUI.py:1649 +#: flatcamGUI/PreferencesUI.py:1809 msgid "Compression" msgstr "" -#: flatcamGUI/PreferencesUI.py:1651 +#: flatcamGUI/PreferencesUI.py:1811 msgid "" "The level of compression used when saving\n" "a FlatCAM project. Higher value means better compression\n" "but require more RAM usage and more processing time." msgstr "" -#: flatcamGUI/PreferencesUI.py:1671 +#: flatcamGUI/PreferencesUI.py:1822 +msgid "Enable Auto Save" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:1824 +msgid "" +"Check to enable the autosave feature.\n" +"When enabled, the application will try to save a project\n" +"at the set interval." +msgstr "" + +#: flatcamGUI/PreferencesUI.py:1834 +msgid "Interval" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:1836 +msgid "" +"Time interval for autosaving. In milliseconds.\n" +"The application will try to save periodically but only\n" +"if the project was saved manually at least once.\n" +"While active, some operations may block this feature." +msgstr "" + +#: flatcamGUI/PreferencesUI.py:1852 msgid "Text to PDF parameters" msgstr "" -#: flatcamGUI/PreferencesUI.py:1673 +#: flatcamGUI/PreferencesUI.py:1854 msgid "Used when saving text in Code Editor or in FlatCAM Document objects." msgstr "" -#: flatcamGUI/PreferencesUI.py:1682 +#: flatcamGUI/PreferencesUI.py:1863 msgid "Top Margin" msgstr "" -#: flatcamGUI/PreferencesUI.py:1684 +#: flatcamGUI/PreferencesUI.py:1865 msgid "Distance between text body and the top of the PDF file." msgstr "" -#: flatcamGUI/PreferencesUI.py:1695 +#: flatcamGUI/PreferencesUI.py:1876 msgid "Bottom Margin" msgstr "" -#: flatcamGUI/PreferencesUI.py:1697 +#: flatcamGUI/PreferencesUI.py:1878 msgid "Distance between text body and the bottom of the PDF file." msgstr "" -#: flatcamGUI/PreferencesUI.py:1708 +#: flatcamGUI/PreferencesUI.py:1889 msgid "Left Margin" msgstr "" -#: flatcamGUI/PreferencesUI.py:1710 +#: flatcamGUI/PreferencesUI.py:1891 msgid "Distance between text body and the left of the PDF file." msgstr "" -#: flatcamGUI/PreferencesUI.py:1721 +#: flatcamGUI/PreferencesUI.py:1902 msgid "Right Margin" msgstr "" -#: flatcamGUI/PreferencesUI.py:1723 +#: flatcamGUI/PreferencesUI.py:1904 msgid "Distance between text body and the right of the PDF file." msgstr "" -#: flatcamGUI/PreferencesUI.py:1756 +#: flatcamGUI/PreferencesUI.py:1936 msgid "Gerber General" msgstr "" -#: flatcamGUI/PreferencesUI.py:1774 +#: flatcamGUI/PreferencesUI.py:1954 msgid "M-Color" msgstr "" -#: flatcamGUI/PreferencesUI.py:1788 flatcamGUI/PreferencesUI.py:3859 -#: flatcamGUI/PreferencesUI.py:4442 flatcamGUI/PreferencesUI.py:7148 +#: flatcamGUI/PreferencesUI.py:1968 flatcamGUI/PreferencesUI.py:4137 +#: flatcamGUI/PreferencesUI.py:4735 flatcamGUI/PreferencesUI.py:7654 msgid "Circle Steps" msgstr "" -#: flatcamGUI/PreferencesUI.py:1790 +#: flatcamGUI/PreferencesUI.py:1970 msgid "" "The number of circle steps for Gerber \n" "circular aperture linear approximation." msgstr "" -#: flatcamGUI/PreferencesUI.py:1802 +#: flatcamGUI/PreferencesUI.py:1982 msgid "Default Values" msgstr "" -#: flatcamGUI/PreferencesUI.py:1804 +#: flatcamGUI/PreferencesUI.py:1984 msgid "" "Those values will be used as fallback values\n" "in case that they are not found in the Gerber file." msgstr "" -#: flatcamGUI/PreferencesUI.py:1813 flatcamGUI/PreferencesUI.py:1819 -#: flatcamGUI/PreferencesUI.py:2361 flatcamGUI/PreferencesUI.py:2367 +#: flatcamGUI/PreferencesUI.py:1993 flatcamGUI/PreferencesUI.py:1999 +#: flatcamGUI/PreferencesUI.py:2541 flatcamGUI/PreferencesUI.py:2547 msgid "The units used in the Gerber file." msgstr "" -#: flatcamGUI/PreferencesUI.py:1816 flatcamGUI/PreferencesUI.py:2364 -#: flatcamGUI/PreferencesUI.py:2728 flatcamGUI/PreferencesUI.py:2814 -#: flatcamGUI/PreferencesUI.py:3422 flatcamTools/ToolCalculators.py:61 +#: flatcamGUI/PreferencesUI.py:1996 flatcamGUI/PreferencesUI.py:2544 +#: flatcamGUI/PreferencesUI.py:2910 flatcamGUI/PreferencesUI.py:2996 +#: flatcamGUI/PreferencesUI.py:3700 flatcamTools/ToolCalculators.py:61 #: flatcamTools/ToolPcbWizard.py:125 msgid "INCH" msgstr "" -#: flatcamGUI/PreferencesUI.py:1826 flatcamGUI/PreferencesUI.py:2413 -#: flatcamGUI/PreferencesUI.py:2786 flatcamGUI/PreferencesUI.py:3490 +#: flatcamGUI/PreferencesUI.py:2006 flatcamGUI/PreferencesUI.py:2593 +#: flatcamGUI/PreferencesUI.py:2968 flatcamGUI/PreferencesUI.py:3768 msgid "Zeros" msgstr "" -#: flatcamGUI/PreferencesUI.py:1829 flatcamGUI/PreferencesUI.py:1839 -#: flatcamGUI/PreferencesUI.py:2416 flatcamGUI/PreferencesUI.py:2426 +#: flatcamGUI/PreferencesUI.py:2009 flatcamGUI/PreferencesUI.py:2019 +#: flatcamGUI/PreferencesUI.py:2596 flatcamGUI/PreferencesUI.py:2606 msgid "" "This sets the type of Gerber zeros.\n" "If LZ then Leading Zeros are removed and\n" @@ -8346,33 +8671,33 @@ msgid "" "and Leading Zeros are kept." msgstr "" -#: flatcamGUI/PreferencesUI.py:1836 flatcamGUI/PreferencesUI.py:2423 -#: flatcamGUI/PreferencesUI.py:2799 flatcamGUI/PreferencesUI.py:3500 +#: flatcamGUI/PreferencesUI.py:2016 flatcamGUI/PreferencesUI.py:2603 +#: flatcamGUI/PreferencesUI.py:2981 flatcamGUI/PreferencesUI.py:3778 #: flatcamTools/ToolPcbWizard.py:111 msgid "LZ" msgstr "" -#: flatcamGUI/PreferencesUI.py:1837 flatcamGUI/PreferencesUI.py:2424 -#: flatcamGUI/PreferencesUI.py:2800 flatcamGUI/PreferencesUI.py:3501 +#: flatcamGUI/PreferencesUI.py:2017 flatcamGUI/PreferencesUI.py:2604 +#: flatcamGUI/PreferencesUI.py:2982 flatcamGUI/PreferencesUI.py:3779 #: flatcamTools/ToolPcbWizard.py:112 msgid "TZ" msgstr "" -#: flatcamGUI/PreferencesUI.py:1855 +#: flatcamGUI/PreferencesUI.py:2035 msgid "Clean Apertures" msgstr "" -#: flatcamGUI/PreferencesUI.py:1857 +#: flatcamGUI/PreferencesUI.py:2037 msgid "" "Will remove apertures that do not have geometry\n" "thus lowering the number of apertures in the Gerber object." msgstr "" -#: flatcamGUI/PreferencesUI.py:1863 +#: flatcamGUI/PreferencesUI.py:2043 msgid "Polarity change buffer" msgstr "" -#: flatcamGUI/PreferencesUI.py:1865 +#: flatcamGUI/PreferencesUI.py:2045 msgid "" "Will apply extra buffering for the\n" "solid geometry when we have polarity changes.\n" @@ -8380,77 +8705,72 @@ msgid "" "do not load correctly." msgstr "" -#: flatcamGUI/PreferencesUI.py:1878 +#: flatcamGUI/PreferencesUI.py:2058 msgid "Gerber Object Color" msgstr "" -#: flatcamGUI/PreferencesUI.py:1884 flatcamGUI/PreferencesUI.py:2905 -#: flatcamGUI/PreferencesUI.py:3896 +#: flatcamGUI/PreferencesUI.py:2064 flatcamGUI/PreferencesUI.py:3087 +#: flatcamGUI/PreferencesUI.py:4176 msgid "Set the line color for plotted objects." msgstr "" -#: flatcamGUI/PreferencesUI.py:1901 flatcamGUI/PreferencesUI.py:2922 -#: flatcamGUI/PreferencesUI.py:4553 flatcamGUI/PreferencesUI.py:4619 +#: flatcamGUI/PreferencesUI.py:2081 flatcamGUI/PreferencesUI.py:3104 +#: flatcamGUI/PreferencesUI.py:4846 flatcamGUI/PreferencesUI.py:4912 msgid "" "Set the fill color for plotted objects.\n" "First 6 digits are the color and the last 2\n" "digits are for alpha (transparency) level." msgstr "" -#: flatcamGUI/PreferencesUI.py:1920 flatcamGUI/PreferencesUI.py:2941 -#: flatcamGUI/PreferencesUI.py:4572 +#: flatcamGUI/PreferencesUI.py:2100 flatcamGUI/PreferencesUI.py:3123 +#: flatcamGUI/PreferencesUI.py:4865 msgid "Set the fill transparency for plotted objects." msgstr "" -#: flatcamGUI/PreferencesUI.py:2011 +#: flatcamGUI/PreferencesUI.py:2191 msgid "Gerber Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:2085 flatcamGUI/PreferencesUI.py:4379 -#: flatcamGUI/PreferencesUI.py:5120 flatcamTools/ToolNonCopperClear.py:170 -msgid "Conv." -msgstr "" - -#: flatcamGUI/PreferencesUI.py:2089 +#: flatcamGUI/PreferencesUI.py:2269 msgid "Combine Passes" msgstr "" -#: flatcamGUI/PreferencesUI.py:2177 +#: flatcamGUI/PreferencesUI.py:2357 msgid "Gerber Adv. Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:2181 flatcamGUI/PreferencesUI.py:3278 -#: flatcamGUI/PreferencesUI.py:4179 +#: flatcamGUI/PreferencesUI.py:2361 flatcamGUI/PreferencesUI.py:3551 +#: flatcamGUI/PreferencesUI.py:4472 msgid "Advanced Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:2183 +#: flatcamGUI/PreferencesUI.py:2363 msgid "" "A list of Gerber advanced parameters.\n" "Those parameters are available only for\n" "Advanced App. Level." msgstr "" -#: flatcamGUI/PreferencesUI.py:2202 +#: flatcamGUI/PreferencesUI.py:2382 msgid "Table Show/Hide" msgstr "" -#: flatcamGUI/PreferencesUI.py:2204 +#: flatcamGUI/PreferencesUI.py:2384 msgid "" "Toggle the display of the Gerber Apertures Table.\n" "Also, on hide, it will delete all mark shapes\n" "that are drawn on canvas." msgstr "" -#: flatcamGUI/PreferencesUI.py:2284 +#: flatcamGUI/PreferencesUI.py:2464 msgid "Exterior" msgstr "" -#: flatcamGUI/PreferencesUI.py:2285 +#: flatcamGUI/PreferencesUI.py:2465 msgid "Interior" msgstr "" -#: flatcamGUI/PreferencesUI.py:2298 +#: flatcamGUI/PreferencesUI.py:2478 msgid "" "Buffering type:\n" "- None --> best performance, fast file loading but no so good display\n" @@ -8458,79 +8778,79 @@ msgid "" "<>: Don't change this unless you know what you are doing !!!" msgstr "" -#: flatcamGUI/PreferencesUI.py:2303 flatcamGUI/PreferencesUI.py:5852 -#: flatcamGUI/PreferencesUI.py:7446 flatcamTools/ToolFiducials.py:201 -#: flatcamTools/ToolFilm.py:255 flatcamTools/ToolProperties.py:411 -#: flatcamTools/ToolProperties.py:426 flatcamTools/ToolProperties.py:429 -#: flatcamTools/ToolProperties.py:432 flatcamTools/ToolProperties.py:456 +#: flatcamGUI/PreferencesUI.py:2483 flatcamGUI/PreferencesUI.py:6340 +#: flatcamGUI/PreferencesUI.py:7952 flatcamTools/ToolFiducials.py:201 +#: flatcamTools/ToolFilm.py:255 flatcamTools/ToolProperties.py:452 +#: flatcamTools/ToolProperties.py:455 flatcamTools/ToolProperties.py:458 +#: flatcamTools/ToolProperties.py:483 msgid "None" msgstr "" -#: flatcamGUI/PreferencesUI.py:2309 +#: flatcamGUI/PreferencesUI.py:2489 msgid "Simplify" msgstr "" -#: flatcamGUI/PreferencesUI.py:2311 +#: flatcamGUI/PreferencesUI.py:2491 msgid "" "When checked all the Gerber polygons will be\n" "loaded with simplification having a set tolerance.\n" "<>: Don't change this unless you know what you are doing !!!" msgstr "" -#: flatcamGUI/PreferencesUI.py:2318 +#: flatcamGUI/PreferencesUI.py:2498 msgid "Tolerance" msgstr "" -#: flatcamGUI/PreferencesUI.py:2319 +#: flatcamGUI/PreferencesUI.py:2499 msgid "Tolerance for polygon simplification." msgstr "" -#: flatcamGUI/PreferencesUI.py:2344 +#: flatcamGUI/PreferencesUI.py:2524 msgid "Gerber Export" msgstr "" -#: flatcamGUI/PreferencesUI.py:2348 flatcamGUI/PreferencesUI.py:3406 +#: flatcamGUI/PreferencesUI.py:2528 flatcamGUI/PreferencesUI.py:3684 msgid "Export Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:2350 +#: flatcamGUI/PreferencesUI.py:2530 msgid "" "The parameters set here are used in the file exported\n" "when using the File -> Export -> Export Gerber menu entry." msgstr "" -#: flatcamGUI/PreferencesUI.py:2373 flatcamGUI/PreferencesUI.py:3431 +#: flatcamGUI/PreferencesUI.py:2553 flatcamGUI/PreferencesUI.py:3709 msgid "Int/Decimals" msgstr "" -#: flatcamGUI/PreferencesUI.py:2375 +#: flatcamGUI/PreferencesUI.py:2555 msgid "" "The number of digits in the whole part of the number\n" "and in the fractional part of the number." msgstr "" -#: flatcamGUI/PreferencesUI.py:2388 +#: flatcamGUI/PreferencesUI.py:2568 msgid "" "This numbers signify the number of digits in\n" "the whole part of Gerber coordinates." msgstr "" -#: flatcamGUI/PreferencesUI.py:2404 +#: flatcamGUI/PreferencesUI.py:2584 msgid "" "This numbers signify the number of digits in\n" "the decimal part of Gerber coordinates." msgstr "" -#: flatcamGUI/PreferencesUI.py:2449 +#: flatcamGUI/PreferencesUI.py:2629 msgid "A list of Gerber Editor parameters." msgstr "" -#: flatcamGUI/PreferencesUI.py:2457 flatcamGUI/PreferencesUI.py:3565 -#: flatcamGUI/PreferencesUI.py:4357 flatcamGUI/PreferencesUI.py:7109 +#: flatcamGUI/PreferencesUI.py:2637 flatcamGUI/PreferencesUI.py:3843 +#: flatcamGUI/PreferencesUI.py:4650 flatcamGUI/PreferencesUI.py:7615 msgid "Selection limit" msgstr "" -#: flatcamGUI/PreferencesUI.py:2459 +#: flatcamGUI/PreferencesUI.py:2639 msgid "" "Set the number of selected Gerber geometry\n" "items above which the utility geometry\n" @@ -8539,104 +8859,108 @@ msgid "" "large number of geometric elements." msgstr "" -#: flatcamGUI/PreferencesUI.py:2472 +#: flatcamGUI/PreferencesUI.py:2652 msgid "New Aperture code" msgstr "" -#: flatcamGUI/PreferencesUI.py:2485 +#: flatcamGUI/PreferencesUI.py:2665 msgid "New Aperture size" msgstr "" -#: flatcamGUI/PreferencesUI.py:2487 +#: flatcamGUI/PreferencesUI.py:2667 msgid "Size for the new aperture" msgstr "" -#: flatcamGUI/PreferencesUI.py:2498 +#: flatcamGUI/PreferencesUI.py:2678 msgid "New Aperture type" msgstr "" -#: flatcamGUI/PreferencesUI.py:2500 +#: flatcamGUI/PreferencesUI.py:2680 msgid "" "Type for the new aperture.\n" "Can be 'C', 'R' or 'O'." msgstr "" -#: flatcamGUI/PreferencesUI.py:2522 +#: flatcamGUI/PreferencesUI.py:2702 msgid "Aperture Dimensions" msgstr "" -#: flatcamGUI/PreferencesUI.py:2524 flatcamGUI/PreferencesUI.py:3877 -#: flatcamGUI/PreferencesUI.py:5029 -msgid "Diameters of the cutting tools, separated by ','" +#: flatcamGUI/PreferencesUI.py:2704 flatcamGUI/PreferencesUI.py:4155 +#: flatcamGUI/PreferencesUI.py:5322 flatcamGUI/PreferencesUI.py:5889 +#: flatcamGUI/PreferencesUI.py:6955 +msgid "" +"Diameters of the tools, separated by comma.\n" +"The value of the diameter has to use the dot decimals separator.\n" +"Valid values: 0.3, 1.0" msgstr "" -#: flatcamGUI/PreferencesUI.py:2530 +#: flatcamGUI/PreferencesUI.py:2712 msgid "Linear Pad Array" msgstr "" -#: flatcamGUI/PreferencesUI.py:2534 flatcamGUI/PreferencesUI.py:3609 -#: flatcamGUI/PreferencesUI.py:3757 +#: flatcamGUI/PreferencesUI.py:2716 flatcamGUI/PreferencesUI.py:3887 +#: flatcamGUI/PreferencesUI.py:4035 msgid "Linear Direction" msgstr "" -#: flatcamGUI/PreferencesUI.py:2574 +#: flatcamGUI/PreferencesUI.py:2756 msgid "Circular Pad Array" msgstr "" -#: flatcamGUI/PreferencesUI.py:2578 flatcamGUI/PreferencesUI.py:3655 -#: flatcamGUI/PreferencesUI.py:3805 +#: flatcamGUI/PreferencesUI.py:2760 flatcamGUI/PreferencesUI.py:3933 +#: flatcamGUI/PreferencesUI.py:4083 msgid "Circular Direction" msgstr "" -#: flatcamGUI/PreferencesUI.py:2580 flatcamGUI/PreferencesUI.py:3657 -#: flatcamGUI/PreferencesUI.py:3807 +#: flatcamGUI/PreferencesUI.py:2762 flatcamGUI/PreferencesUI.py:3935 +#: flatcamGUI/PreferencesUI.py:4085 msgid "" "Direction for circular array.\n" "Can be CW = clockwise or CCW = counter clockwise." msgstr "" -#: flatcamGUI/PreferencesUI.py:2591 flatcamGUI/PreferencesUI.py:3668 -#: flatcamGUI/PreferencesUI.py:3818 +#: flatcamGUI/PreferencesUI.py:2773 flatcamGUI/PreferencesUI.py:3946 +#: flatcamGUI/PreferencesUI.py:4096 msgid "Circular Angle" msgstr "" -#: flatcamGUI/PreferencesUI.py:2610 +#: flatcamGUI/PreferencesUI.py:2792 msgid "Distance at which to buffer the Gerber element." msgstr "" -#: flatcamGUI/PreferencesUI.py:2619 +#: flatcamGUI/PreferencesUI.py:2801 msgid "Scale Tool" msgstr "" -#: flatcamGUI/PreferencesUI.py:2625 +#: flatcamGUI/PreferencesUI.py:2807 msgid "Factor to scale the Gerber element." msgstr "" -#: flatcamGUI/PreferencesUI.py:2638 +#: flatcamGUI/PreferencesUI.py:2820 msgid "Threshold low" msgstr "" -#: flatcamGUI/PreferencesUI.py:2640 +#: flatcamGUI/PreferencesUI.py:2822 msgid "Threshold value under which the apertures are not marked." msgstr "" -#: flatcamGUI/PreferencesUI.py:2650 +#: flatcamGUI/PreferencesUI.py:2832 msgid "Threshold high" msgstr "" -#: flatcamGUI/PreferencesUI.py:2652 +#: flatcamGUI/PreferencesUI.py:2834 msgid "Threshold value over which the apertures are not marked." msgstr "" -#: flatcamGUI/PreferencesUI.py:2670 +#: flatcamGUI/PreferencesUI.py:2852 msgid "Excellon General" msgstr "" -#: flatcamGUI/PreferencesUI.py:2703 +#: flatcamGUI/PreferencesUI.py:2885 msgid "Excellon Format" msgstr "" -#: flatcamGUI/PreferencesUI.py:2705 +#: flatcamGUI/PreferencesUI.py:2887 msgid "" "The NC drill files, usually named Excellon files\n" "are files that can be found in different formats.\n" @@ -8659,33 +8983,33 @@ msgid "" "KiCAD 3:5 INCH TZ" msgstr "" -#: flatcamGUI/PreferencesUI.py:2729 +#: flatcamGUI/PreferencesUI.py:2911 msgid "Default values for INCH are 2:4" msgstr "" -#: flatcamGUI/PreferencesUI.py:2736 flatcamGUI/PreferencesUI.py:2765 -#: flatcamGUI/PreferencesUI.py:3445 +#: flatcamGUI/PreferencesUI.py:2918 flatcamGUI/PreferencesUI.py:2947 +#: flatcamGUI/PreferencesUI.py:3723 msgid "" "This numbers signify the number of digits in\n" "the whole part of Excellon coordinates." msgstr "" -#: flatcamGUI/PreferencesUI.py:2749 flatcamGUI/PreferencesUI.py:2778 -#: flatcamGUI/PreferencesUI.py:3458 +#: flatcamGUI/PreferencesUI.py:2931 flatcamGUI/PreferencesUI.py:2960 +#: flatcamGUI/PreferencesUI.py:3736 msgid "" "This numbers signify the number of digits in\n" "the decimal part of Excellon coordinates." msgstr "" -#: flatcamGUI/PreferencesUI.py:2757 +#: flatcamGUI/PreferencesUI.py:2939 msgid "METRIC" msgstr "" -#: flatcamGUI/PreferencesUI.py:2758 +#: flatcamGUI/PreferencesUI.py:2940 msgid "Default values for METRIC are 3:3" msgstr "" -#: flatcamGUI/PreferencesUI.py:2789 +#: flatcamGUI/PreferencesUI.py:2971 msgid "" "This sets the type of Excellon zeros.\n" "If LZ then Leading Zeros are kept and\n" @@ -8697,7 +9021,7 @@ msgid "" "stored in the Excellon file." msgstr "" -#: flatcamGUI/PreferencesUI.py:2807 +#: flatcamGUI/PreferencesUI.py:2989 msgid "" "This sets the default units of Excellon files.\n" "If it is not detected in the parsed file the value here\n" @@ -8705,26 +9029,26 @@ msgid "" "therefore this parameter will be used." msgstr "" -#: flatcamGUI/PreferencesUI.py:2817 +#: flatcamGUI/PreferencesUI.py:2999 msgid "" "This sets the units of Excellon files.\n" "Some Excellon files don't have an header\n" "therefore this parameter will be used." msgstr "" -#: flatcamGUI/PreferencesUI.py:2825 +#: flatcamGUI/PreferencesUI.py:3007 msgid "Update Export settings" msgstr "" -#: flatcamGUI/PreferencesUI.py:2842 +#: flatcamGUI/PreferencesUI.py:3024 msgid "Excellon Optimization" msgstr "" -#: flatcamGUI/PreferencesUI.py:2845 +#: flatcamGUI/PreferencesUI.py:3027 msgid "Algorithm:" msgstr "" -#: flatcamGUI/PreferencesUI.py:2847 flatcamGUI/PreferencesUI.py:2863 +#: flatcamGUI/PreferencesUI.py:3029 flatcamGUI/PreferencesUI.py:3045 msgid "" "This sets the optimization type for the Excellon drill path.\n" "If <> is checked then Google OR-Tools algorithm with\n" @@ -8737,20 +9061,20 @@ msgid "" "Travelling Salesman algorithm for path optimization." msgstr "" -#: flatcamGUI/PreferencesUI.py:2858 +#: flatcamGUI/PreferencesUI.py:3040 msgid "MetaHeuristic" msgstr "" -#: flatcamGUI/PreferencesUI.py:2860 +#: flatcamGUI/PreferencesUI.py:3042 msgid "TSA" msgstr "" -#: flatcamGUI/PreferencesUI.py:2877 flatcamGUI/PreferencesUI.py:3192 -#: flatcamGUI/PreferencesUI.py:4138 +#: flatcamGUI/PreferencesUI.py:3059 flatcamGUI/PreferencesUI.py:3463 +#: flatcamGUI/PreferencesUI.py:4430 msgid "Duration" msgstr "" -#: flatcamGUI/PreferencesUI.py:2880 +#: flatcamGUI/PreferencesUI.py:3062 msgid "" "When OR-Tools Metaheuristic (MH) is enabled there is a\n" "maximum threshold for how much time is spent doing the\n" @@ -8758,25 +9082,43 @@ msgid "" "In seconds." msgstr "" -#: flatcamGUI/PreferencesUI.py:2899 +#: flatcamGUI/PreferencesUI.py:3081 msgid "Excellon Object Color" msgstr "" -#: flatcamGUI/PreferencesUI.py:3065 +#: flatcamGUI/PreferencesUI.py:3247 msgid "Excellon Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:3071 +#: flatcamGUI/PreferencesUI.py:3251 flatcamGUI/PreferencesUI.py:4227 +msgid "Create CNC Job" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:3253 msgid "" "Parameters used to create a CNC Job object\n" "for this drill object." msgstr "" -#: flatcamGUI/PreferencesUI.py:3185 flatcamGUI/PreferencesUI.py:4133 +#: flatcamGUI/PreferencesUI.py:3370 flatcamGUI/PreferencesUI.py:4314 +msgid "Tool change" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:3454 flatcamGUI/PreferencesUI.py:4425 msgid "Enable Dwell" msgstr "" -#: flatcamGUI/PreferencesUI.py:3217 +#: flatcamGUI/PreferencesUI.py:3477 +msgid "" +"The preprocessor JSON file that dictates\n" +"Gcode output." +msgstr "" + +#: flatcamGUI/PreferencesUI.py:3488 +msgid "Gcode" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:3490 msgid "" "Choose what to use for GCode generation:\n" "'Drills', 'Slots' or 'Both'.\n" @@ -8784,34 +9126,52 @@ msgid "" "converted to drills." msgstr "" -#: flatcamGUI/PreferencesUI.py:3235 +#: flatcamGUI/PreferencesUI.py:3506 +msgid "Mill Holes" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:3508 msgid "Create Geometry for milling holes." msgstr "" -#: flatcamGUI/PreferencesUI.py:3271 +#: flatcamGUI/PreferencesUI.py:3512 +msgid "Drill Tool dia" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:3523 +msgid "Slot Tool dia" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:3525 +msgid "" +"Diameter of the cutting tool\n" +"when milling slots." +msgstr "" + +#: flatcamGUI/PreferencesUI.py:3544 msgid "Excellon Adv. Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:3280 +#: flatcamGUI/PreferencesUI.py:3553 msgid "" "A list of Excellon advanced parameters.\n" "Those parameters are available only for\n" "Advanced App. Level." msgstr "" -#: flatcamGUI/PreferencesUI.py:3301 +#: flatcamGUI/PreferencesUI.py:3576 msgid "Toolchange X,Y" msgstr "" -#: flatcamGUI/PreferencesUI.py:3303 flatcamGUI/PreferencesUI.py:4193 +#: flatcamGUI/PreferencesUI.py:3578 flatcamGUI/PreferencesUI.py:4486 msgid "Toolchange X,Y position." msgstr "" -#: flatcamGUI/PreferencesUI.py:3360 flatcamGUI/PreferencesUI.py:4280 +#: flatcamGUI/PreferencesUI.py:3638 flatcamGUI/PreferencesUI.py:4573 msgid "Spindle direction" msgstr "" -#: flatcamGUI/PreferencesUI.py:3362 flatcamGUI/PreferencesUI.py:4282 +#: flatcamGUI/PreferencesUI.py:3640 flatcamGUI/PreferencesUI.py:4575 msgid "" "This sets the direction that the spindle is rotating.\n" "It can be either:\n" @@ -8819,11 +9179,11 @@ msgid "" "- CCW = counter clockwise" msgstr "" -#: flatcamGUI/PreferencesUI.py:3373 flatcamGUI/PreferencesUI.py:4294 +#: flatcamGUI/PreferencesUI.py:3651 flatcamGUI/PreferencesUI.py:4587 msgid "Fast Plunge" msgstr "" -#: flatcamGUI/PreferencesUI.py:3375 flatcamGUI/PreferencesUI.py:4296 +#: flatcamGUI/PreferencesUI.py:3653 flatcamGUI/PreferencesUI.py:4589 msgid "" "By checking this, the vertical move from\n" "Z_Toolchange to Z_move is done with G0,\n" @@ -8831,11 +9191,11 @@ msgid "" "WARNING: the move is done at Toolchange X,Y coords." msgstr "" -#: flatcamGUI/PreferencesUI.py:3382 +#: flatcamGUI/PreferencesUI.py:3660 msgid "Fast Retract" msgstr "" -#: flatcamGUI/PreferencesUI.py:3384 +#: flatcamGUI/PreferencesUI.py:3662 msgid "" "Exit hole strategy.\n" " - When uncheked, while exiting the drilled hole the drill bit\n" @@ -8845,21 +9205,21 @@ msgid "" "(travel height) is done as fast as possible (G0) in one move." msgstr "" -#: flatcamGUI/PreferencesUI.py:3402 +#: flatcamGUI/PreferencesUI.py:3680 msgid "Excellon Export" msgstr "" -#: flatcamGUI/PreferencesUI.py:3408 +#: flatcamGUI/PreferencesUI.py:3686 msgid "" "The parameters set here are used in the file exported\n" "when using the File -> Export -> Export Excellon menu entry." msgstr "" -#: flatcamGUI/PreferencesUI.py:3419 flatcamGUI/PreferencesUI.py:3425 +#: flatcamGUI/PreferencesUI.py:3697 flatcamGUI/PreferencesUI.py:3703 msgid "The units used in the Excellon file." msgstr "" -#: flatcamGUI/PreferencesUI.py:3433 +#: flatcamGUI/PreferencesUI.py:3711 msgid "" "The NC drill files, usually named Excellon files\n" "are files that can be found in different formats.\n" @@ -8867,11 +9227,11 @@ msgid "" "coordinates are not using period." msgstr "" -#: flatcamGUI/PreferencesUI.py:3467 +#: flatcamGUI/PreferencesUI.py:3745 msgid "Format" msgstr "" -#: flatcamGUI/PreferencesUI.py:3469 flatcamGUI/PreferencesUI.py:3479 +#: flatcamGUI/PreferencesUI.py:3747 flatcamGUI/PreferencesUI.py:3757 msgid "" "Select the kind of coordinates format used.\n" "Coordinates can be saved with decimal point or without.\n" @@ -8881,15 +9241,15 @@ msgid "" "or TZ = trailing zeros are kept." msgstr "" -#: flatcamGUI/PreferencesUI.py:3476 +#: flatcamGUI/PreferencesUI.py:3754 msgid "Decimal" msgstr "" -#: flatcamGUI/PreferencesUI.py:3477 +#: flatcamGUI/PreferencesUI.py:3755 msgid "No-Decimal" msgstr "" -#: flatcamGUI/PreferencesUI.py:3493 +#: flatcamGUI/PreferencesUI.py:3771 msgid "" "This sets the type of Excellon zeros.\n" "If LZ then Leading Zeros are kept and\n" @@ -8898,7 +9258,7 @@ msgid "" "and Leading Zeros are removed." msgstr "" -#: flatcamGUI/PreferencesUI.py:3503 +#: flatcamGUI/PreferencesUI.py:3781 msgid "" "This sets the default type of Excellon zeros.\n" "If LZ then Leading Zeros are kept and\n" @@ -8907,11 +9267,11 @@ msgid "" "and Leading Zeros are removed." msgstr "" -#: flatcamGUI/PreferencesUI.py:3513 +#: flatcamGUI/PreferencesUI.py:3791 msgid "Slot type" msgstr "" -#: flatcamGUI/PreferencesUI.py:3516 flatcamGUI/PreferencesUI.py:3526 +#: flatcamGUI/PreferencesUI.py:3794 flatcamGUI/PreferencesUI.py:3804 msgid "" "This sets how the slots will be exported.\n" "If ROUTED then the slots will be routed\n" @@ -8920,19 +9280,19 @@ msgid "" "using the Drilled slot command (G85)." msgstr "" -#: flatcamGUI/PreferencesUI.py:3523 +#: flatcamGUI/PreferencesUI.py:3801 msgid "Routed" msgstr "" -#: flatcamGUI/PreferencesUI.py:3524 +#: flatcamGUI/PreferencesUI.py:3802 msgid "Drilled(G85)" msgstr "" -#: flatcamGUI/PreferencesUI.py:3557 +#: flatcamGUI/PreferencesUI.py:3835 msgid "A list of Excellon Editor parameters." msgstr "" -#: flatcamGUI/PreferencesUI.py:3567 +#: flatcamGUI/PreferencesUI.py:3845 msgid "" "Set the number of selected Excellon geometry\n" "items above which the utility geometry\n" @@ -8941,19 +9301,20 @@ msgid "" "large number of geometric elements." msgstr "" -#: flatcamGUI/PreferencesUI.py:3580 flatcamGUI/PreferencesUI.py:5100 -msgid "New Tool Dia" +#: flatcamGUI/PreferencesUI.py:3858 flatcamGUI/PreferencesUI.py:5396 +#: flatcamGUI/PreferencesUI.py:5962 +msgid "New Dia" msgstr "" -#: flatcamGUI/PreferencesUI.py:3605 +#: flatcamGUI/PreferencesUI.py:3883 msgid "Linear Drill Array" msgstr "" -#: flatcamGUI/PreferencesUI.py:3651 +#: flatcamGUI/PreferencesUI.py:3929 msgid "Circular Drill Array" msgstr "" -#: flatcamGUI/PreferencesUI.py:3721 +#: flatcamGUI/PreferencesUI.py:3999 msgid "" "Angle at which the slot is placed.\n" "The precision is of max 2 decimals.\n" @@ -8961,44 +9322,49 @@ msgid "" "Max value is: 360.00 degrees." msgstr "" -#: flatcamGUI/PreferencesUI.py:3740 +#: flatcamGUI/PreferencesUI.py:4018 msgid "Linear Slot Array" msgstr "" -#: flatcamGUI/PreferencesUI.py:3801 +#: flatcamGUI/PreferencesUI.py:4079 msgid "Circular Slot Array" msgstr "" -#: flatcamGUI/PreferencesUI.py:3839 +#: flatcamGUI/PreferencesUI.py:4117 msgid "Geometry General" msgstr "" -#: flatcamGUI/PreferencesUI.py:3861 +#: flatcamGUI/PreferencesUI.py:4139 msgid "" "The number of circle steps for Geometry \n" "circle and arc shapes linear approximation." msgstr "" -#: flatcamGUI/PreferencesUI.py:3890 +#: flatcamGUI/PreferencesUI.py:4153 flatcamGUI/PreferencesUI.py:5320 +#: flatcamGUI/PreferencesUI.py:5887 flatcamGUI/PreferencesUI.py:6953 +msgid "Tools Dia" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:4170 msgid "Geometry Object Color" msgstr "" -#: flatcamGUI/PreferencesUI.py:3941 +#: flatcamGUI/PreferencesUI.py:4221 msgid "Geometry Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:3949 +#: flatcamGUI/PreferencesUI.py:4229 msgid "" "Create a CNC Job object\n" "tracing the contours of this\n" "Geometry object." msgstr "" -#: flatcamGUI/PreferencesUI.py:3993 +#: flatcamGUI/PreferencesUI.py:4273 msgid "Depth/Pass" msgstr "" -#: flatcamGUI/PreferencesUI.py:3995 +#: flatcamGUI/PreferencesUI.py:4275 msgid "" "The depth to cut on each pass,\n" "when multidepth is enabled.\n" @@ -9007,60 +9373,56 @@ msgid "" "which has negative value." msgstr "" -#: flatcamGUI/PreferencesUI.py:4173 +#: flatcamGUI/PreferencesUI.py:4466 msgid "Geometry Adv. Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:4181 +#: flatcamGUI/PreferencesUI.py:4474 msgid "" "A list of Geometry advanced parameters.\n" "Those parameters are available only for\n" "Advanced App. Level." msgstr "" -#: flatcamGUI/PreferencesUI.py:4191 flatcamGUI/PreferencesUI.py:6539 -#: flatcamGUI/PreferencesUI.py:7586 flatcamTools/ToolCalibration.py:125 -#: flatcamTools/ToolSolderPaste.py:239 +#: flatcamGUI/PreferencesUI.py:4484 flatcamGUI/PreferencesUI.py:7045 +#: flatcamGUI/PreferencesUI.py:8092 flatcamTools/ToolCalibration.py:125 +#: flatcamTools/ToolSolderPaste.py:241 msgid "Toolchange X-Y" msgstr "" -#: flatcamGUI/PreferencesUI.py:4202 +#: flatcamGUI/PreferencesUI.py:4495 msgid "" "Height of the tool just after starting the work.\n" "Delete the value if you don't need this feature." msgstr "" -#: flatcamGUI/PreferencesUI.py:4304 +#: flatcamGUI/PreferencesUI.py:4597 msgid "Segment X size" msgstr "" -#: flatcamGUI/PreferencesUI.py:4306 +#: flatcamGUI/PreferencesUI.py:4599 msgid "" "The size of the trace segment on the X axis.\n" "Useful for auto-leveling.\n" "A value of 0 means no segmentation on the X axis." msgstr "" -#: flatcamGUI/PreferencesUI.py:4320 +#: flatcamGUI/PreferencesUI.py:4613 msgid "Segment Y size" msgstr "" -#: flatcamGUI/PreferencesUI.py:4322 +#: flatcamGUI/PreferencesUI.py:4615 msgid "" "The size of the trace segment on the Y axis.\n" "Useful for auto-leveling.\n" "A value of 0 means no segmentation on the Y axis." msgstr "" -#: flatcamGUI/PreferencesUI.py:4343 -msgid "Geometry Editor" -msgstr "" - -#: flatcamGUI/PreferencesUI.py:4349 +#: flatcamGUI/PreferencesUI.py:4642 msgid "A list of Geometry Editor parameters." msgstr "" -#: flatcamGUI/PreferencesUI.py:4359 flatcamGUI/PreferencesUI.py:7111 +#: flatcamGUI/PreferencesUI.py:4652 flatcamGUI/PreferencesUI.py:7617 msgid "" "Set the number of selected geometry\n" "items above which the utility geometry\n" @@ -9069,55 +9431,55 @@ msgid "" "large number of geometric elements." msgstr "" -#: flatcamGUI/PreferencesUI.py:4391 +#: flatcamGUI/PreferencesUI.py:4684 msgid "CNC Job General" msgstr "" -#: flatcamGUI/PreferencesUI.py:4444 +#: flatcamGUI/PreferencesUI.py:4737 msgid "" "The number of circle steps for GCode \n" "circle and arc shapes linear approximation." msgstr "" -#: flatcamGUI/PreferencesUI.py:4453 +#: flatcamGUI/PreferencesUI.py:4746 msgid "Travel dia" msgstr "" -#: flatcamGUI/PreferencesUI.py:4455 +#: flatcamGUI/PreferencesUI.py:4748 msgid "" "The width of the travel lines to be\n" "rendered in the plot." msgstr "" -#: flatcamGUI/PreferencesUI.py:4468 +#: flatcamGUI/PreferencesUI.py:4761 msgid "G-code Decimals" msgstr "" -#: flatcamGUI/PreferencesUI.py:4471 flatcamTools/ToolFiducials.py:74 +#: flatcamGUI/PreferencesUI.py:4764 flatcamTools/ToolFiducials.py:74 msgid "Coordinates" msgstr "" -#: flatcamGUI/PreferencesUI.py:4473 +#: flatcamGUI/PreferencesUI.py:4766 msgid "" "The number of decimals to be used for \n" "the X, Y, Z coordinates in CNC code (GCODE, etc.)" msgstr "" -#: flatcamGUI/PreferencesUI.py:4484 flatcamTools/ToolProperties.py:492 +#: flatcamGUI/PreferencesUI.py:4777 flatcamTools/ToolProperties.py:519 msgid "Feedrate" msgstr "" -#: flatcamGUI/PreferencesUI.py:4486 +#: flatcamGUI/PreferencesUI.py:4779 msgid "" "The number of decimals to be used for \n" "the Feedrate parameter in CNC code (GCODE, etc.)" msgstr "" -#: flatcamGUI/PreferencesUI.py:4497 +#: flatcamGUI/PreferencesUI.py:4790 msgid "Coordinates type" msgstr "" -#: flatcamGUI/PreferencesUI.py:4499 +#: flatcamGUI/PreferencesUI.py:4792 msgid "" "The type of coordinates to be used in Gcode.\n" "Can be:\n" @@ -9125,72 +9487,72 @@ msgid "" "- Incremental G91 -> the reference is the previous position" msgstr "" -#: flatcamGUI/PreferencesUI.py:4505 +#: flatcamGUI/PreferencesUI.py:4798 msgid "Absolute G90" msgstr "" -#: flatcamGUI/PreferencesUI.py:4506 +#: flatcamGUI/PreferencesUI.py:4799 msgid "Incremental G91" msgstr "" -#: flatcamGUI/PreferencesUI.py:4516 +#: flatcamGUI/PreferencesUI.py:4809 msgid "Force Windows style line-ending" msgstr "" -#: flatcamGUI/PreferencesUI.py:4518 +#: flatcamGUI/PreferencesUI.py:4811 msgid "" "When checked will force a Windows style line-ending\n" "(\\r\\n) on non-Windows OS's." msgstr "" -#: flatcamGUI/PreferencesUI.py:4530 +#: flatcamGUI/PreferencesUI.py:4823 msgid "Travel Line Color" msgstr "" -#: flatcamGUI/PreferencesUI.py:4536 +#: flatcamGUI/PreferencesUI.py:4829 msgid "Set the travel line color for plotted objects." msgstr "" -#: flatcamGUI/PreferencesUI.py:4596 +#: flatcamGUI/PreferencesUI.py:4889 msgid "CNCJob Object Color" msgstr "" -#: flatcamGUI/PreferencesUI.py:4602 +#: flatcamGUI/PreferencesUI.py:4895 msgid "Set the color for plotted objects." msgstr "" -#: flatcamGUI/PreferencesUI.py:4762 +#: flatcamGUI/PreferencesUI.py:5055 msgid "CNC Job Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:4766 +#: flatcamGUI/PreferencesUI.py:5059 msgid "Export G-Code" msgstr "" -#: flatcamGUI/PreferencesUI.py:4782 +#: flatcamGUI/PreferencesUI.py:5075 msgid "Prepend to G-Code" msgstr "" -#: flatcamGUI/PreferencesUI.py:4791 +#: flatcamGUI/PreferencesUI.py:5084 msgid "" "Type here any G-Code commands you would like to add at the beginning of the G-Code file." msgstr "" -#: flatcamGUI/PreferencesUI.py:4798 +#: flatcamGUI/PreferencesUI.py:5091 msgid "Append to G-Code" msgstr "" -#: flatcamGUI/PreferencesUI.py:4808 +#: flatcamGUI/PreferencesUI.py:5101 msgid "" "Type here any G-Code commands you would like to append to the generated file.\n" "I.e.: M2 (End of program)" msgstr "" -#: flatcamGUI/PreferencesUI.py:4824 +#: flatcamGUI/PreferencesUI.py:5117 msgid "CNC Job Adv. Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:4861 +#: flatcamGUI/PreferencesUI.py:5154 msgid "" "Type here any G-Code commands you would like to be executed when Toolchange event is " "encountered.\n" @@ -9200,82 +9562,81 @@ msgid "" "it's name." msgstr "" -#: flatcamGUI/PreferencesUI.py:4916 +#: flatcamGUI/PreferencesUI.py:5209 msgid "Z depth for the cut" msgstr "" -#: flatcamGUI/PreferencesUI.py:4917 +#: flatcamGUI/PreferencesUI.py:5210 msgid "Z height for travel" msgstr "" -#: flatcamGUI/PreferencesUI.py:4923 +#: flatcamGUI/PreferencesUI.py:5216 msgid "dwelltime = time to dwell to allow the spindle to reach it's set RPM" msgstr "" -#: flatcamGUI/PreferencesUI.py:4942 +#: flatcamGUI/PreferencesUI.py:5235 msgid "Annotation Size" msgstr "" -#: flatcamGUI/PreferencesUI.py:4944 +#: flatcamGUI/PreferencesUI.py:5237 msgid "The font size of the annotation text. In pixels." msgstr "" -#: flatcamGUI/PreferencesUI.py:4954 +#: flatcamGUI/PreferencesUI.py:5247 msgid "Annotation Color" msgstr "" -#: flatcamGUI/PreferencesUI.py:4956 +#: flatcamGUI/PreferencesUI.py:5249 msgid "Set the font color for the annotation texts." msgstr "" -#: flatcamGUI/PreferencesUI.py:5013 +#: flatcamGUI/PreferencesUI.py:5306 msgid "NCC Tool Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:5027 flatcamGUI/PreferencesUI.py:6449 -msgid "Tools dia" +#: flatcamGUI/PreferencesUI.py:5328 flatcamGUI/PreferencesUI.py:5896 +msgid "Comma separated values" msgstr "" -#: flatcamGUI/PreferencesUI.py:5038 flatcamGUI/PreferencesUI.py:5046 -#: flatcamTools/ToolNonCopperClear.py:215 flatcamTools/ToolNonCopperClear.py:223 +#: flatcamGUI/PreferencesUI.py:5334 flatcamGUI/PreferencesUI.py:5342 +#: flatcamGUI/PreferencesUI.py:5903 flatcamTools/ToolNCC.py:215 flatcamTools/ToolNCC.py:223 +#: flatcamTools/ToolPaint.py:198 flatcamTools/ToolPaint.py:206 msgid "" "Default tool type:\n" "- 'V-shape'\n" "- Circular" msgstr "" -#: flatcamGUI/PreferencesUI.py:5043 flatcamTools/ToolNonCopperClear.py:220 +#: flatcamGUI/PreferencesUI.py:5339 flatcamGUI/PreferencesUI.py:5908 +#: flatcamTools/ToolNCC.py:220 flatcamTools/ToolPaint.py:203 msgid "V-shape" msgstr "" -#: flatcamGUI/PreferencesUI.py:5083 flatcamGUI/PreferencesUI.py:5092 -#: flatcamTools/ToolNonCopperClear.py:256 flatcamTools/ToolNonCopperClear.py:264 +#: flatcamGUI/PreferencesUI.py:5379 flatcamGUI/PreferencesUI.py:5388 +#: flatcamGUI/PreferencesUI.py:5946 flatcamGUI/PreferencesUI.py:5955 +#: flatcamTools/ToolNCC.py:262 flatcamTools/ToolNCC.py:271 flatcamTools/ToolPaint.py:245 +#: flatcamTools/ToolPaint.py:254 msgid "" "Depth of cut into material. Negative value.\n" "In FlatCAM units." msgstr "" -#: flatcamGUI/PreferencesUI.py:5102 -msgid "The new tool diameter (cut width) to add in the tool table." -msgstr "" - -#: flatcamGUI/PreferencesUI.py:5114 flatcamGUI/PreferencesUI.py:5122 -#: flatcamTools/ToolNonCopperClear.py:164 flatcamTools/ToolNonCopperClear.py:172 +#: flatcamGUI/PreferencesUI.py:5398 flatcamGUI/PreferencesUI.py:5964 +#: flatcamTools/ToolNCC.py:280 flatcamTools/ToolPaint.py:263 msgid "" -"Milling type when the selected tool is of type: 'iso_op':\n" -"- climb / best for precision milling and to reduce tool usage\n" -"- conventional / useful when there is no backlash compensation" +"Diameter for the new tool to add in the Tool Table.\n" +"If the tool is V-shape type then this value is automatically\n" +"calculated from the other parameters." msgstr "" -#: flatcamGUI/PreferencesUI.py:5131 flatcamGUI/PreferencesUI.py:5546 -#: flatcamTools/ToolNonCopperClear.py:181 flatcamTools/ToolPaint.py:153 +#: flatcamGUI/PreferencesUI.py:5435 flatcamGUI/PreferencesUI.py:5981 +#: flatcamTools/ToolNCC.py:174 flatcamTools/ToolPaint.py:158 msgid "Tool order" msgstr "" -#: flatcamGUI/PreferencesUI.py:5132 flatcamGUI/PreferencesUI.py:5142 -#: flatcamGUI/PreferencesUI.py:5547 flatcamGUI/PreferencesUI.py:5557 -#: flatcamTools/ToolNonCopperClear.py:182 flatcamTools/ToolNonCopperClear.py:192 -#: flatcamTools/ToolPaint.py:154 flatcamTools/ToolPaint.py:164 +#: flatcamGUI/PreferencesUI.py:5436 flatcamGUI/PreferencesUI.py:5446 +#: flatcamGUI/PreferencesUI.py:5982 flatcamTools/ToolNCC.py:175 flatcamTools/ToolNCC.py:185 +#: flatcamTools/ToolPaint.py:159 flatcamTools/ToolPaint.py:169 msgid "" "This set the way that the tools in the tools table are used.\n" "'No' --> means that the used order is the one in the tool table\n" @@ -9286,57 +9647,35 @@ msgid "" "in reverse and disable this control." msgstr "" -#: flatcamGUI/PreferencesUI.py:5140 flatcamGUI/PreferencesUI.py:5555 -#: flatcamTools/ToolNonCopperClear.py:190 flatcamTools/ToolPaint.py:162 +#: flatcamGUI/PreferencesUI.py:5444 flatcamGUI/PreferencesUI.py:5990 +#: flatcamTools/ToolNCC.py:183 flatcamTools/ToolPaint.py:167 msgid "Forward" msgstr "" -#: flatcamGUI/PreferencesUI.py:5141 flatcamGUI/PreferencesUI.py:5556 -#: flatcamTools/ToolNonCopperClear.py:191 flatcamTools/ToolPaint.py:163 +#: flatcamGUI/PreferencesUI.py:5445 flatcamGUI/PreferencesUI.py:5991 +#: flatcamTools/ToolNCC.py:184 flatcamTools/ToolPaint.py:168 msgid "Reverse" msgstr "" -#: flatcamGUI/PreferencesUI.py:5154 flatcamTools/ToolNonCopperClear.py:321 +#: flatcamGUI/PreferencesUI.py:5545 +msgid "Offset value" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:5547 msgid "" -"How much (fraction) of the tool width to overlap each tool pass.\n" -"Adjust the value starting with lower values\n" -"and increasing it if areas that should be cleared are still \n" -"not cleared.\n" -"Lower values = faster processing, faster execution on CNC.\n" -"Higher values = slow processing and slow execution on CNC\n" -"due of too many paths." +"If used, it will add an offset to the copper features.\n" +"The copper clearing will finish to a distance\n" +"from the copper features.\n" +"The value can be between 0.0 and 9999.9 FlatCAM units." msgstr "" -#: flatcamGUI/PreferencesUI.py:5173 flatcamGUI/PreferencesUI.py:7177 -#: flatcamGUI/PreferencesUI.py:7419 flatcamGUI/PreferencesUI.py:7483 -#: flatcamTools/ToolCopperThieving.py:113 flatcamTools/ToolFiducials.py:174 -#: flatcamTools/ToolFiducials.py:237 flatcamTools/ToolNonCopperClear.py:339 -msgid "Bounding box margin." -msgstr "" - -#: flatcamGUI/PreferencesUI.py:5186 flatcamGUI/PreferencesUI.py:5604 -#: flatcamTools/ToolNonCopperClear.py:350 -msgid "" -"Algorithm for non-copper clearing:
Standard: Fixed step inwards.
Seed-" -"based: Outwards from seed.
Line-based: Parallel lines." -msgstr "" - -#: flatcamGUI/PreferencesUI.py:5202 flatcamGUI/PreferencesUI.py:5618 -#: flatcamTools/ToolNonCopperClear.py:364 flatcamTools/ToolPaint.py:267 -msgid "Connect" -msgstr "" - -#: flatcamGUI/PreferencesUI.py:5211 flatcamGUI/PreferencesUI.py:5626 -#: flatcamTools/ToolNonCopperClear.py:371 flatcamTools/ToolPaint.py:274 -msgid "Contour" -msgstr "" - -#: flatcamGUI/PreferencesUI.py:5220 flatcamTools/ToolNonCopperClear.py:379 -#: flatcamTools/ToolPaint.py:281 +#: flatcamGUI/PreferencesUI.py:5567 flatcamGUI/PreferencesUI.py:6083 +#: flatcamGUI/PreferencesUI.py:6084 flatcamTools/ToolNCC.py:512 +#: flatcamTools/ToolPaint.py:442 msgid "Rest Machining" msgstr "" -#: flatcamGUI/PreferencesUI.py:5222 flatcamTools/ToolNonCopperClear.py:381 +#: flatcamGUI/PreferencesUI.py:5569 flatcamTools/ToolNCC.py:516 msgid "" "If checked, use 'rest machining'.\n" "Basically it will clear copper outside PCB features,\n" @@ -9347,114 +9686,105 @@ msgid "" "If not checked, use the standard algorithm." msgstr "" -#: flatcamGUI/PreferencesUI.py:5236 flatcamTools/ToolNonCopperClear.py:395 -#: flatcamTools/ToolNonCopperClear.py:405 +#: flatcamGUI/PreferencesUI.py:5588 flatcamGUI/PreferencesUI.py:6119 +#: flatcamGUI/PreferencesUI.py:7696 flatcamTools/ToolCopperThieving.py:127 +#: flatcamTools/ToolNCC.py:535 flatcamTools/ToolNCC.py:1309 flatcamTools/ToolNCC.py:1651 +#: flatcamTools/ToolNCC.py:1935 flatcamTools/ToolNCC.py:1990 flatcamTools/ToolPaint.py:486 +#: flatcamTools/ToolPaint.py:939 flatcamTools/ToolPaint.py:1440 +msgid "Area Selection" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:5588 flatcamGUI/PreferencesUI.py:6119 +#: flatcamGUI/PreferencesUI.py:7697 flatcamTools/ToolCopperThieving.py:128 +#: flatcamTools/ToolDblSided.py:217 flatcamTools/ToolNCC.py:535 flatcamTools/ToolNCC.py:1667 +#: flatcamTools/ToolNCC.py:1941 flatcamTools/ToolNCC.py:1998 flatcamTools/ToolNCC.py:2306 +#: flatcamTools/ToolNCC.py:2586 flatcamTools/ToolNCC.py:3012 flatcamTools/ToolPaint.py:486 +#: flatcamTools/ToolPaint.py:924 flatcamTools/ToolPaint.py:1456 +msgid "Reference Object" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:5592 flatcamTools/ToolNCC.py:541 msgid "" -"If used, it will add an offset to the copper features.\n" -"The copper clearing will finish to a distance\n" -"from the copper features.\n" -"The value can be between 0 and 10 FlatCAM units." +"Selection of area to be processed.\n" +"- 'Itself' - the processing extent is based on the object that is processed.\n" +" - 'Area Selection' - left mouse click to start selection of the area to be processed.\n" +"- 'Reference Object' - will process the area specified by another object." msgstr "" -#: flatcamGUI/PreferencesUI.py:5245 flatcamTools/ToolNonCopperClear.py:403 -msgid "Offset value" +#: flatcamGUI/PreferencesUI.py:5601 flatcamGUI/PreferencesUI.py:6125 +#: flatcamTools/ToolNCC.py:578 flatcamTools/ToolPaint.py:522 +msgid "Shape" msgstr "" -#: flatcamGUI/PreferencesUI.py:5247 -msgid "" -"If used, it will add an offset to the copper features.\n" -"The copper clearing will finish to a distance\n" -"from the copper features.\n" -"The value can be between 0.0 and 9999.9 FlatCAM units." +#: flatcamGUI/PreferencesUI.py:5603 flatcamGUI/PreferencesUI.py:6127 +#: flatcamTools/ToolNCC.py:580 flatcamTools/ToolPaint.py:524 +msgid "The kind of selection shape used for area selection." msgstr "" -#: flatcamGUI/PreferencesUI.py:5262 flatcamGUI/PreferencesUI.py:7189 -#: flatcamTools/ToolCopperThieving.py:125 flatcamTools/ToolNonCopperClear.py:429 -msgid "Itself" -msgstr "" - -#: flatcamGUI/PreferencesUI.py:5263 flatcamGUI/PreferencesUI.py:5646 -msgid "Area" -msgstr "" - -#: flatcamGUI/PreferencesUI.py:5264 flatcamGUI/PreferencesUI.py:5648 -msgid "Ref" -msgstr "" - -#: flatcamGUI/PreferencesUI.py:5267 -msgid "" -"- 'Itself' - the non copper clearing extent\n" -"is based on the object that is copper cleared.\n" -" - 'Area Selection' - left mouse click to start selection of the area to be painted.\n" -"Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple areas.\n" -"- 'Reference Object' - will do non copper clearing within the area\n" -"specified by another object." -msgstr "" - -#: flatcamGUI/PreferencesUI.py:5279 flatcamGUI/PreferencesUI.py:5654 +#: flatcamGUI/PreferencesUI.py:5618 flatcamGUI/PreferencesUI.py:6142 msgid "Normal" msgstr "" -#: flatcamGUI/PreferencesUI.py:5280 flatcamGUI/PreferencesUI.py:5655 +#: flatcamGUI/PreferencesUI.py:5619 flatcamGUI/PreferencesUI.py:6143 msgid "Progressive" msgstr "" -#: flatcamGUI/PreferencesUI.py:5281 +#: flatcamGUI/PreferencesUI.py:5620 msgid "NCC Plotting" msgstr "" -#: flatcamGUI/PreferencesUI.py:5283 +#: flatcamGUI/PreferencesUI.py:5622 msgid "" "- 'Normal' - normal plotting, done at the end of the NCC job\n" "- 'Progressive' - after each shape is generated it will be plotted." msgstr "" -#: flatcamGUI/PreferencesUI.py:5297 +#: flatcamGUI/PreferencesUI.py:5636 msgid "Cutout Tool Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:5312 flatcamTools/ToolCalculators.py:123 -#: flatcamTools/ToolCutOut.py:123 +#: flatcamGUI/PreferencesUI.py:5651 flatcamTools/ToolCalculators.py:123 +#: flatcamTools/ToolCutOut.py:130 msgid "Tool Diameter" msgstr "" -#: flatcamGUI/PreferencesUI.py:5314 flatcamTools/ToolCutOut.py:125 +#: flatcamGUI/PreferencesUI.py:5653 flatcamTools/ToolCutOut.py:132 msgid "" "Diameter of the tool used to cutout\n" "the PCB shape out of the surrounding material." msgstr "" -#: flatcamGUI/PreferencesUI.py:5369 flatcamTools/ToolCutOut.py:104 +#: flatcamGUI/PreferencesUI.py:5708 msgid "Object kind" msgstr "" -#: flatcamGUI/PreferencesUI.py:5371 flatcamTools/ToolCutOut.py:106 +#: flatcamGUI/PreferencesUI.py:5710 flatcamTools/ToolCutOut.py:78 msgid "" "Choice of what kind the object we want to cutout is.
- Single: contain a single " "PCB Gerber outline object.
- Panel: a panel PCB Gerber object, which is made\n" "out of many individual PCB outlines." msgstr "" -#: flatcamGUI/PreferencesUI.py:5378 flatcamTools/ToolCutOut.py:112 +#: flatcamGUI/PreferencesUI.py:5717 flatcamTools/ToolCutOut.py:84 msgid "Single" msgstr "" -#: flatcamGUI/PreferencesUI.py:5379 flatcamTools/ToolCutOut.py:113 +#: flatcamGUI/PreferencesUI.py:5718 flatcamTools/ToolCutOut.py:85 msgid "Panel" msgstr "" -#: flatcamGUI/PreferencesUI.py:5386 flatcamTools/ToolCutOut.py:186 +#: flatcamGUI/PreferencesUI.py:5725 flatcamTools/ToolCutOut.py:193 msgid "" "Margin over bounds. A positive value here\n" "will make the cutout of the PCB further from\n" "the actual PCB border" msgstr "" -#: flatcamGUI/PreferencesUI.py:5399 flatcamTools/ToolCutOut.py:197 +#: flatcamGUI/PreferencesUI.py:5738 flatcamTools/ToolCutOut.py:204 msgid "Gap size" msgstr "" -#: flatcamGUI/PreferencesUI.py:5401 flatcamTools/ToolCutOut.py:199 +#: flatcamGUI/PreferencesUI.py:5740 flatcamTools/ToolCutOut.py:206 msgid "" "The size of the bridge gaps in the cutout\n" "used to keep the board connected to\n" @@ -9462,11 +9792,11 @@ msgid "" "from which the PCB is cutout)." msgstr "" -#: flatcamGUI/PreferencesUI.py:5415 flatcamTools/ToolCutOut.py:241 +#: flatcamGUI/PreferencesUI.py:5754 flatcamTools/ToolCutOut.py:250 msgid "Gaps" msgstr "" -#: flatcamGUI/PreferencesUI.py:5417 +#: flatcamGUI/PreferencesUI.py:5756 msgid "" "Number of gaps used for the cutout.\n" "There can be maximum 8 bridges/gaps.\n" @@ -9480,112 +9810,128 @@ msgid "" "- 8 - 2*left + 2*right +2*top + 2*bottom" msgstr "" -#: flatcamGUI/PreferencesUI.py:5439 flatcamTools/ToolCutOut.py:216 +#: flatcamGUI/PreferencesUI.py:5778 flatcamTools/ToolCutOut.py:223 msgid "Convex Shape" msgstr "" -#: flatcamGUI/PreferencesUI.py:5441 flatcamTools/ToolCutOut.py:219 +#: flatcamGUI/PreferencesUI.py:5780 flatcamTools/ToolCutOut.py:226 msgid "" "Create a convex shape surrounding the entire PCB.\n" "Used only if the source object type is Gerber." msgstr "" -#: flatcamGUI/PreferencesUI.py:5454 +#: flatcamGUI/PreferencesUI.py:5793 msgid "2Sided Tool Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:5460 +#: flatcamGUI/PreferencesUI.py:5799 msgid "" "A tool to help in creating a double sided\n" "PCB using alignment holes." msgstr "" -#: flatcamGUI/PreferencesUI.py:5474 +#: flatcamGUI/PreferencesUI.py:5813 msgid "Drill dia" msgstr "" -#: flatcamGUI/PreferencesUI.py:5476 flatcamTools/ToolDblSided.py:274 -#: flatcamTools/ToolDblSided.py:285 +#: flatcamGUI/PreferencesUI.py:5815 flatcamTools/ToolDblSided.py:364 +#: flatcamTools/ToolDblSided.py:369 msgid "Diameter of the drill for the alignment holes." msgstr "" -#: flatcamGUI/PreferencesUI.py:5485 flatcamTools/ToolDblSided.py:146 -msgid "Mirror Axis:" +#: flatcamGUI/PreferencesUI.py:5822 flatcamTools/ToolDblSided.py:378 +msgid "Align Axis" msgstr "" -#: flatcamGUI/PreferencesUI.py:5487 flatcamTools/ToolDblSided.py:147 +#: flatcamGUI/PreferencesUI.py:5824 flatcamGUI/PreferencesUI.py:5837 +#: flatcamTools/ToolDblSided.py:166 flatcamTools/ToolDblSided.py:380 msgid "Mirror vertically (X) or horizontally (Y)." msgstr "" -#: flatcamGUI/PreferencesUI.py:5496 flatcamTools/ToolDblSided.py:156 +#: flatcamGUI/PreferencesUI.py:5835 +msgid "Mirror Axis:" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:5846 flatcamTools/ToolDblSided.py:182 msgid "Point" msgstr "" -#: flatcamGUI/PreferencesUI.py:5497 flatcamTools/ToolDblSided.py:157 +#: flatcamGUI/PreferencesUI.py:5847 flatcamTools/ToolDblSided.py:183 msgid "Box" msgstr "" -#: flatcamGUI/PreferencesUI.py:5498 flatcamTools/ToolDblSided.py:158 +#: flatcamGUI/PreferencesUI.py:5848 msgid "Axis Ref" msgstr "" -#: flatcamGUI/PreferencesUI.py:5500 flatcamTools/ToolDblSided.py:160 +#: flatcamGUI/PreferencesUI.py:5850 msgid "" "The axis should pass through a point or cut\n" " a specified box (in a FlatCAM object) through \n" "the center." msgstr "" -#: flatcamGUI/PreferencesUI.py:5516 +#: flatcamGUI/PreferencesUI.py:5866 msgid "Paint Tool Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:5522 +#: flatcamGUI/PreferencesUI.py:5872 msgid "Parameters:" msgstr "" -#: flatcamGUI/PreferencesUI.py:5636 flatcamTools/ToolPaint.py:296 -#: flatcamTools/ToolPaint.py:313 +#: flatcamGUI/PreferencesUI.py:6086 flatcamTools/ToolPaint.py:445 msgid "" -"How to select Polygons to be painted.\n" -"- 'Polygon Selection' - left mouse click to add/remove polygons to be painted.\n" -"- 'Area Selection' - left mouse click to start selection of the area to be painted.\n" +"If checked, use 'rest machining'.\n" +"Basically it will clear copper outside PCB features,\n" +"using the biggest tool and continue with the next tools,\n" +"from bigger to smaller, to clear areas of copper that\n" +"could not be cleared by previous tool, until there is\n" +"no more copper to clear or there are no more tools.\n" +"\n" +"If not checked, use the standard algorithm." +msgstr "" + +#: flatcamGUI/PreferencesUI.py:6099 flatcamTools/ToolPaint.py:458 +msgid "" +"Selection of area to be processed.\n" +"- 'Polygon Selection' - left mouse click to add/remove polygons to be processed.\n" +"- 'Area Selection' - left mouse click to start selection of the area to be processed.\n" "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple areas.\n" -"- 'All Polygons' - the Paint will start after click.\n" -"- 'Reference Object' - will do non copper clearing within the area\n" -"specified by another object." +"- 'All Polygons' - the process will start after click.\n" +"- 'Reference Object' - will process the area specified by another object." msgstr "" -#: flatcamGUI/PreferencesUI.py:5645 -msgid "Sel" +#: flatcamGUI/PreferencesUI.py:6119 flatcamTools/ToolPaint.py:486 +#: flatcamTools/ToolPaint.py:935 flatcamTools/ToolPaint.py:1420 +msgid "Polygon Selection" msgstr "" -#: flatcamGUI/PreferencesUI.py:5656 +#: flatcamGUI/PreferencesUI.py:6144 msgid "Paint Plotting" msgstr "" -#: flatcamGUI/PreferencesUI.py:5658 +#: flatcamGUI/PreferencesUI.py:6146 msgid "" "- 'Normal' - normal plotting, done at the end of the Paint job\n" "- 'Progressive' - after each shape is generated it will be plotted." msgstr "" -#: flatcamGUI/PreferencesUI.py:5672 +#: flatcamGUI/PreferencesUI.py:6160 msgid "Film Tool Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:5678 +#: flatcamGUI/PreferencesUI.py:6166 msgid "" "Create a PCB film from a Gerber or Geometry\n" "FlatCAM object.\n" "The file is saved in SVG format." msgstr "" -#: flatcamGUI/PreferencesUI.py:5689 +#: flatcamGUI/PreferencesUI.py:6177 msgid "Film Type" msgstr "" -#: flatcamGUI/PreferencesUI.py:5691 flatcamTools/ToolFilm.py:300 +#: flatcamGUI/PreferencesUI.py:6179 flatcamTools/ToolFilm.py:300 msgid "" "Generate a Positive black film or a Negative film.\n" "Positive means that it will print the features\n" @@ -9595,19 +9941,19 @@ msgid "" "The Film format is SVG." msgstr "" -#: flatcamGUI/PreferencesUI.py:5702 +#: flatcamGUI/PreferencesUI.py:6190 msgid "Film Color" msgstr "" -#: flatcamGUI/PreferencesUI.py:5704 +#: flatcamGUI/PreferencesUI.py:6192 msgid "Set the film color when positive film is selected." msgstr "" -#: flatcamGUI/PreferencesUI.py:5727 flatcamTools/ToolFilm.py:316 +#: flatcamGUI/PreferencesUI.py:6215 flatcamTools/ToolFilm.py:316 msgid "Border" msgstr "" -#: flatcamGUI/PreferencesUI.py:5729 flatcamTools/ToolFilm.py:318 +#: flatcamGUI/PreferencesUI.py:6217 flatcamTools/ToolFilm.py:318 msgid "" "Specify a border around the object.\n" "Only for negative film.\n" @@ -9619,124 +9965,120 @@ msgid "" "surroundings if not for this border." msgstr "" -#: flatcamGUI/PreferencesUI.py:5746 flatcamTools/ToolFilm.py:283 +#: flatcamGUI/PreferencesUI.py:6234 flatcamTools/ToolFilm.py:283 msgid "Scale Stroke" msgstr "" -#: flatcamGUI/PreferencesUI.py:5748 flatcamTools/ToolFilm.py:285 +#: flatcamGUI/PreferencesUI.py:6236 flatcamTools/ToolFilm.py:285 msgid "" "Scale the line stroke thickness of each feature in the SVG file.\n" "It means that the line that envelope each SVG feature will be thicker or thinner,\n" "therefore the fine features may be more affected by this parameter." msgstr "" -#: flatcamGUI/PreferencesUI.py:5755 flatcamTools/ToolFilm.py:141 +#: flatcamGUI/PreferencesUI.py:6243 flatcamTools/ToolFilm.py:141 msgid "Film Adjustments" msgstr "" -#: flatcamGUI/PreferencesUI.py:5757 flatcamTools/ToolFilm.py:143 +#: flatcamGUI/PreferencesUI.py:6245 flatcamTools/ToolFilm.py:143 msgid "" "Sometime the printers will distort the print shape, especially the Laser types.\n" "This section provide the tools to compensate for the print distortions." msgstr "" -#: flatcamGUI/PreferencesUI.py:5764 flatcamTools/ToolFilm.py:150 +#: flatcamGUI/PreferencesUI.py:6252 flatcamTools/ToolFilm.py:150 msgid "Scale Film geometry" msgstr "" -#: flatcamGUI/PreferencesUI.py:5766 flatcamTools/ToolFilm.py:152 +#: flatcamGUI/PreferencesUI.py:6254 flatcamTools/ToolFilm.py:152 msgid "" "A value greater than 1 will stretch the film\n" "while a value less than 1 will jolt it." msgstr "" -#: flatcamGUI/PreferencesUI.py:5776 flatcamGUI/PreferencesUI.py:6296 -#: flatcamTools/ToolFilm.py:162 flatcamTools/ToolTransform.py:148 +#: flatcamGUI/PreferencesUI.py:6264 flatcamGUI/PreferencesUI.py:6783 +#: flatcamTools/ToolFilm.py:162 flatcamTools/ToolTransform.py:149 msgid "X factor" msgstr "" -#: flatcamGUI/PreferencesUI.py:5785 flatcamGUI/PreferencesUI.py:6309 +#: flatcamGUI/PreferencesUI.py:6273 flatcamGUI/PreferencesUI.py:6796 #: flatcamTools/ToolFilm.py:171 flatcamTools/ToolTransform.py:169 msgid "Y factor" msgstr "" -#: flatcamGUI/PreferencesUI.py:5795 flatcamTools/ToolFilm.py:189 +#: flatcamGUI/PreferencesUI.py:6283 flatcamTools/ToolFilm.py:189 msgid "Skew Film geometry" msgstr "" -#: flatcamGUI/PreferencesUI.py:5797 flatcamTools/ToolFilm.py:191 +#: flatcamGUI/PreferencesUI.py:6285 flatcamTools/ToolFilm.py:191 msgid "" "Positive values will skew to the right\n" "while negative values will skew to the left." msgstr "" -#: flatcamGUI/PreferencesUI.py:5807 flatcamGUI/PreferencesUI.py:6265 +#: flatcamGUI/PreferencesUI.py:6295 flatcamGUI/PreferencesUI.py:6752 #: flatcamTools/ToolFilm.py:201 flatcamTools/ToolTransform.py:98 msgid "X angle" msgstr "" -#: flatcamGUI/PreferencesUI.py:5816 flatcamGUI/PreferencesUI.py:6279 -#: flatcamTools/ToolFilm.py:210 flatcamTools/ToolTransform.py:120 +#: flatcamGUI/PreferencesUI.py:6304 flatcamGUI/PreferencesUI.py:6766 +#: flatcamTools/ToolFilm.py:210 flatcamTools/ToolTransform.py:119 msgid "Y angle" msgstr "" -#: flatcamGUI/PreferencesUI.py:5827 flatcamTools/ToolFilm.py:221 +#: flatcamGUI/PreferencesUI.py:6315 flatcamTools/ToolFilm.py:221 msgid "" "The reference point to be used as origin for the skew.\n" "It can be one of the four points of the geometry bounding box." msgstr "" -#: flatcamGUI/PreferencesUI.py:5830 flatcamTools/ToolFiducials.py:87 +#: flatcamGUI/PreferencesUI.py:6318 flatcamTools/ToolFiducials.py:87 #: flatcamTools/ToolFilm.py:224 msgid "Bottom Left" msgstr "" -#: flatcamGUI/PreferencesUI.py:5831 flatcamTools/ToolFilm.py:225 +#: flatcamGUI/PreferencesUI.py:6319 flatcamTools/ToolFilm.py:225 msgid "Top Left" msgstr "" -#: flatcamGUI/PreferencesUI.py:5832 flatcamTools/ToolFilm.py:226 +#: flatcamGUI/PreferencesUI.py:6320 flatcamTools/ToolFilm.py:226 msgid "Bottom Right" msgstr "" -#: flatcamGUI/PreferencesUI.py:5833 flatcamTools/ToolFilm.py:227 +#: flatcamGUI/PreferencesUI.py:6321 flatcamTools/ToolFilm.py:227 msgid "Top right" msgstr "" -#: flatcamGUI/PreferencesUI.py:5841 flatcamTools/ToolFilm.py:244 +#: flatcamGUI/PreferencesUI.py:6329 flatcamTools/ToolFilm.py:244 msgid "Mirror Film geometry" msgstr "" -#: flatcamGUI/PreferencesUI.py:5843 flatcamTools/ToolFilm.py:246 +#: flatcamGUI/PreferencesUI.py:6331 flatcamTools/ToolFilm.py:246 msgid "Mirror the film geometry on the selected axis or on both." msgstr "" -#: flatcamGUI/PreferencesUI.py:5855 flatcamTools/ToolFilm.py:258 -msgid "Both" -msgstr "" - -#: flatcamGUI/PreferencesUI.py:5857 flatcamTools/ToolFilm.py:260 +#: flatcamGUI/PreferencesUI.py:6345 flatcamTools/ToolFilm.py:260 msgid "Mirror axis" msgstr "" -#: flatcamGUI/PreferencesUI.py:5867 flatcamTools/ToolFilm.py:403 +#: flatcamGUI/PreferencesUI.py:6355 flatcamTools/ToolFilm.py:405 msgid "SVG" msgstr "" -#: flatcamGUI/PreferencesUI.py:5868 flatcamTools/ToolFilm.py:404 +#: flatcamGUI/PreferencesUI.py:6356 flatcamTools/ToolFilm.py:406 msgid "PNG" msgstr "" -#: flatcamGUI/PreferencesUI.py:5869 flatcamTools/ToolFilm.py:405 +#: flatcamGUI/PreferencesUI.py:6357 flatcamTools/ToolFilm.py:407 msgid "PDF" msgstr "" -#: flatcamGUI/PreferencesUI.py:5872 flatcamTools/ToolFilm.py:298 -#: flatcamTools/ToolFilm.py:408 +#: flatcamGUI/PreferencesUI.py:6360 flatcamTools/ToolFilm.py:298 +#: flatcamTools/ToolFilm.py:410 msgid "Film Type:" msgstr "" -#: flatcamGUI/PreferencesUI.py:5874 flatcamTools/ToolFilm.py:410 +#: flatcamGUI/PreferencesUI.py:6362 flatcamTools/ToolFilm.py:412 msgid "" "The file type of the saved film. Can be:\n" "- 'SVG' -> open-source vectorial format\n" @@ -9744,90 +10086,85 @@ msgid "" "- 'PDF' -> portable document format" msgstr "" -#: flatcamGUI/PreferencesUI.py:5883 flatcamTools/ToolFilm.py:419 +#: flatcamGUI/PreferencesUI.py:6371 flatcamTools/ToolFilm.py:421 msgid "Page Orientation" msgstr "" -#: flatcamGUI/PreferencesUI.py:5896 flatcamTools/ToolFilm.py:432 +#: flatcamGUI/PreferencesUI.py:6384 flatcamTools/ToolFilm.py:434 msgid "Page Size" msgstr "" -#: flatcamGUI/PreferencesUI.py:5897 flatcamTools/ToolFilm.py:433 +#: flatcamGUI/PreferencesUI.py:6385 flatcamTools/ToolFilm.py:435 msgid "A selection of standard ISO 216 page sizes." msgstr "" -#: flatcamGUI/PreferencesUI.py:5969 +#: flatcamGUI/PreferencesUI.py:6457 msgid "Panelize Tool Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:5975 +#: flatcamGUI/PreferencesUI.py:6463 msgid "" "Create an object that contains an array of (x, y) elements,\n" "each element is a copy of the source object spaced\n" "at a X distance, Y distance of each other." msgstr "" -#: flatcamGUI/PreferencesUI.py:5992 flatcamTools/ToolPanelize.py:160 +#: flatcamGUI/PreferencesUI.py:6480 flatcamTools/ToolPanelize.py:163 msgid "Spacing cols" msgstr "" -#: flatcamGUI/PreferencesUI.py:5994 flatcamTools/ToolPanelize.py:162 +#: flatcamGUI/PreferencesUI.py:6482 flatcamTools/ToolPanelize.py:165 msgid "" "Spacing between columns of the desired panel.\n" "In current units." msgstr "" -#: flatcamGUI/PreferencesUI.py:6006 flatcamTools/ToolPanelize.py:172 +#: flatcamGUI/PreferencesUI.py:6494 flatcamTools/ToolPanelize.py:175 msgid "Spacing rows" msgstr "" -#: flatcamGUI/PreferencesUI.py:6008 flatcamTools/ToolPanelize.py:174 +#: flatcamGUI/PreferencesUI.py:6496 flatcamTools/ToolPanelize.py:177 msgid "" "Spacing between rows of the desired panel.\n" "In current units." msgstr "" -#: flatcamGUI/PreferencesUI.py:6019 flatcamTools/ToolPanelize.py:183 +#: flatcamGUI/PreferencesUI.py:6507 flatcamTools/ToolPanelize.py:186 msgid "Columns" msgstr "" -#: flatcamGUI/PreferencesUI.py:6021 flatcamTools/ToolPanelize.py:185 +#: flatcamGUI/PreferencesUI.py:6509 flatcamTools/ToolPanelize.py:188 msgid "Number of columns of the desired panel" msgstr "" -#: flatcamGUI/PreferencesUI.py:6031 flatcamTools/ToolPanelize.py:193 +#: flatcamGUI/PreferencesUI.py:6519 flatcamTools/ToolPanelize.py:196 msgid "Rows" msgstr "" -#: flatcamGUI/PreferencesUI.py:6033 flatcamTools/ToolPanelize.py:195 +#: flatcamGUI/PreferencesUI.py:6521 flatcamTools/ToolPanelize.py:198 msgid "Number of rows of the desired panel" msgstr "" -#: flatcamGUI/PreferencesUI.py:6039 flatcamTools/ToolCalibration.py:196 -#: flatcamTools/ToolCalibration.py:634 flatcamTools/ToolPanelize.py:201 -msgid "Gerber" -msgstr "" - -#: flatcamGUI/PreferencesUI.py:6040 flatcamTools/ToolPanelize.py:202 +#: flatcamGUI/PreferencesUI.py:6528 flatcamTools/ToolPanelize.py:205 msgid "Geo" msgstr "" -#: flatcamGUI/PreferencesUI.py:6041 flatcamTools/ToolPanelize.py:203 +#: flatcamGUI/PreferencesUI.py:6529 flatcamTools/ToolPanelize.py:206 msgid "Panel Type" msgstr "" -#: flatcamGUI/PreferencesUI.py:6043 +#: flatcamGUI/PreferencesUI.py:6531 msgid "" "Choose the type of object for the panel object:\n" "- Gerber\n" "- Geometry" msgstr "" -#: flatcamGUI/PreferencesUI.py:6052 +#: flatcamGUI/PreferencesUI.py:6540 msgid "Constrain within" msgstr "" -#: flatcamGUI/PreferencesUI.py:6054 flatcamTools/ToolPanelize.py:215 +#: flatcamGUI/PreferencesUI.py:6542 flatcamTools/ToolPanelize.py:218 msgid "" "Area define by DX and DY within to constrain the panel.\n" "DX and DY values are in current units.\n" @@ -9836,142 +10173,142 @@ msgid "" "they fit completely within selected area." msgstr "" -#: flatcamGUI/PreferencesUI.py:6067 flatcamTools/ToolPanelize.py:227 +#: flatcamGUI/PreferencesUI.py:6555 flatcamTools/ToolPanelize.py:230 msgid "Width (DX)" msgstr "" -#: flatcamGUI/PreferencesUI.py:6069 flatcamTools/ToolPanelize.py:229 +#: flatcamGUI/PreferencesUI.py:6557 flatcamTools/ToolPanelize.py:232 msgid "" "The width (DX) within which the panel must fit.\n" "In current units." msgstr "" -#: flatcamGUI/PreferencesUI.py:6080 flatcamTools/ToolPanelize.py:238 +#: flatcamGUI/PreferencesUI.py:6568 flatcamTools/ToolPanelize.py:241 msgid "Height (DY)" msgstr "" -#: flatcamGUI/PreferencesUI.py:6082 flatcamTools/ToolPanelize.py:240 +#: flatcamGUI/PreferencesUI.py:6570 flatcamTools/ToolPanelize.py:243 msgid "" "The height (DY)within which the panel must fit.\n" "In current units." msgstr "" -#: flatcamGUI/PreferencesUI.py:6096 +#: flatcamGUI/PreferencesUI.py:6584 msgid "Calculators Tool Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:6100 flatcamTools/ToolCalculators.py:25 +#: flatcamGUI/PreferencesUI.py:6588 flatcamTools/ToolCalculators.py:25 msgid "V-Shape Tool Calculator" msgstr "" -#: flatcamGUI/PreferencesUI.py:6102 +#: flatcamGUI/PreferencesUI.py:6590 msgid "" "Calculate the tool diameter for a given V-shape tool,\n" "having the tip diameter, tip angle and\n" "depth-of-cut as parameters." msgstr "" -#: flatcamGUI/PreferencesUI.py:6117 flatcamTools/ToolCalculators.py:94 +#: flatcamGUI/PreferencesUI.py:6607 flatcamTools/ToolCalculators.py:94 msgid "Tip Diameter" msgstr "" -#: flatcamGUI/PreferencesUI.py:6119 flatcamTools/ToolCalculators.py:102 +#: flatcamGUI/PreferencesUI.py:6609 flatcamTools/ToolCalculators.py:102 msgid "" "This is the tool tip diameter.\n" "It is specified by manufacturer." msgstr "" -#: flatcamGUI/PreferencesUI.py:6131 flatcamTools/ToolCalculators.py:105 +#: flatcamGUI/PreferencesUI.py:6621 flatcamTools/ToolCalculators.py:105 msgid "Tip Angle" msgstr "" -#: flatcamGUI/PreferencesUI.py:6133 +#: flatcamGUI/PreferencesUI.py:6623 msgid "" "This is the angle on the tip of the tool.\n" "It is specified by manufacturer." msgstr "" -#: flatcamGUI/PreferencesUI.py:6147 +#: flatcamGUI/PreferencesUI.py:6637 msgid "" "This is depth to cut into material.\n" "In the CNCJob object it is the CutZ parameter." msgstr "" -#: flatcamGUI/PreferencesUI.py:6154 flatcamTools/ToolCalculators.py:27 +#: flatcamGUI/PreferencesUI.py:6644 flatcamTools/ToolCalculators.py:27 msgid "ElectroPlating Calculator" msgstr "" -#: flatcamGUI/PreferencesUI.py:6156 flatcamTools/ToolCalculators.py:158 +#: flatcamGUI/PreferencesUI.py:6646 flatcamTools/ToolCalculators.py:158 msgid "" "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." msgstr "" -#: flatcamGUI/PreferencesUI.py:6170 flatcamTools/ToolCalculators.py:167 +#: flatcamGUI/PreferencesUI.py:6657 flatcamTools/ToolCalculators.py:167 msgid "Board Length" msgstr "" -#: flatcamGUI/PreferencesUI.py:6172 flatcamTools/ToolCalculators.py:173 +#: flatcamGUI/PreferencesUI.py:6659 flatcamTools/ToolCalculators.py:173 msgid "This is the board length. In centimeters." msgstr "" -#: flatcamGUI/PreferencesUI.py:6182 flatcamTools/ToolCalculators.py:175 +#: flatcamGUI/PreferencesUI.py:6669 flatcamTools/ToolCalculators.py:175 msgid "Board Width" msgstr "" -#: flatcamGUI/PreferencesUI.py:6184 flatcamTools/ToolCalculators.py:181 +#: flatcamGUI/PreferencesUI.py:6671 flatcamTools/ToolCalculators.py:181 msgid "This is the board width.In centimeters." msgstr "" -#: flatcamGUI/PreferencesUI.py:6189 flatcamTools/ToolCalculators.py:183 +#: flatcamGUI/PreferencesUI.py:6676 flatcamTools/ToolCalculators.py:183 msgid "Current Density" msgstr "" -#: flatcamGUI/PreferencesUI.py:6195 flatcamTools/ToolCalculators.py:190 +#: flatcamGUI/PreferencesUI.py:6682 flatcamTools/ToolCalculators.py:190 msgid "" "Current density to pass through the board. \n" "In Amps per Square Feet ASF." msgstr "" -#: flatcamGUI/PreferencesUI.py:6201 flatcamTools/ToolCalculators.py:193 +#: flatcamGUI/PreferencesUI.py:6688 flatcamTools/ToolCalculators.py:193 msgid "Copper Growth" msgstr "" -#: flatcamGUI/PreferencesUI.py:6207 flatcamTools/ToolCalculators.py:200 +#: flatcamGUI/PreferencesUI.py:6694 flatcamTools/ToolCalculators.py:200 msgid "" "How thick the copper growth is intended to be.\n" "In microns." msgstr "" -#: flatcamGUI/PreferencesUI.py:6220 +#: flatcamGUI/PreferencesUI.py:6707 msgid "Transform Tool Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:6226 +#: flatcamGUI/PreferencesUI.py:6713 msgid "" "Various transformations that can be applied\n" "on a FlatCAM object." msgstr "" -#: flatcamGUI/PreferencesUI.py:6257 +#: flatcamGUI/PreferencesUI.py:6744 msgid "Skew" msgstr "" -#: flatcamGUI/PreferencesUI.py:6298 flatcamTools/ToolTransform.py:150 +#: flatcamGUI/PreferencesUI.py:6785 flatcamTools/ToolTransform.py:151 msgid "Factor for scaling on X axis." msgstr "" -#: flatcamGUI/PreferencesUI.py:6311 flatcamTools/ToolTransform.py:171 +#: flatcamGUI/PreferencesUI.py:6798 flatcamTools/ToolTransform.py:171 msgid "Factor for scaling on Y axis." msgstr "" -#: flatcamGUI/PreferencesUI.py:6319 flatcamTools/ToolTransform.py:194 +#: flatcamGUI/PreferencesUI.py:6806 flatcamTools/ToolTransform.py:192 msgid "" "Scale the selected object(s)\n" "using the Scale_X factor for both axis." msgstr "" -#: flatcamGUI/PreferencesUI.py:6327 flatcamTools/ToolTransform.py:202 +#: flatcamGUI/PreferencesUI.py:6814 flatcamTools/ToolTransform.py:199 msgid "" "Scale the selected object(s)\n" "using the origin reference when checked,\n" @@ -9979,32 +10316,32 @@ msgid "" "of the selected objects when unchecked." msgstr "" -#: flatcamGUI/PreferencesUI.py:6343 flatcamTools/ToolTransform.py:217 +#: flatcamGUI/PreferencesUI.py:6830 flatcamTools/ToolTransform.py:218 msgid "X val" msgstr "" -#: flatcamGUI/PreferencesUI.py:6345 flatcamTools/ToolTransform.py:219 +#: flatcamGUI/PreferencesUI.py:6832 flatcamTools/ToolTransform.py:220 msgid "Distance to offset on X axis. In current units." msgstr "" -#: flatcamGUI/PreferencesUI.py:6356 flatcamTools/ToolTransform.py:238 +#: flatcamGUI/PreferencesUI.py:6843 flatcamTools/ToolTransform.py:238 msgid "Y val" msgstr "" -#: flatcamGUI/PreferencesUI.py:6358 flatcamTools/ToolTransform.py:240 +#: flatcamGUI/PreferencesUI.py:6845 flatcamTools/ToolTransform.py:240 msgid "Distance to offset on Y axis. In current units." msgstr "" -#: flatcamGUI/PreferencesUI.py:6364 flatcamTools/ToolDblSided.py:62 -#: flatcamTools/ToolDblSided.py:90 flatcamTools/ToolDblSided.py:120 +#: flatcamGUI/PreferencesUI.py:6851 flatcamTools/ToolDblSided.py:68 +#: flatcamTools/ToolDblSided.py:96 flatcamTools/ToolDblSided.py:126 msgid "Mirror" msgstr "" -#: flatcamGUI/PreferencesUI.py:6368 flatcamTools/ToolTransform.py:285 +#: flatcamGUI/PreferencesUI.py:6855 flatcamTools/ToolTransform.py:284 msgid "Mirror Reference" msgstr "" -#: flatcamGUI/PreferencesUI.py:6370 flatcamTools/ToolTransform.py:287 +#: flatcamGUI/PreferencesUI.py:6857 flatcamTools/ToolTransform.py:286 msgid "" "Flip the selected object(s)\n" "around the point in Point Entry Field.\n" @@ -10017,23 +10354,23 @@ msgid "" "Point Entry field and click Flip on X(Y)" msgstr "" -#: flatcamGUI/PreferencesUI.py:6381 +#: flatcamGUI/PreferencesUI.py:6868 msgid "Mirror Reference point" msgstr "" -#: flatcamGUI/PreferencesUI.py:6383 +#: flatcamGUI/PreferencesUI.py:6870 msgid "" "Coordinates in format (x, y) used as reference for mirroring.\n" "The 'x' in (x, y) will be used when using Flip on X and\n" "the 'y' in (x, y) will be used when using Flip on Y and" msgstr "" -#: flatcamGUI/PreferencesUI.py:6396 flatcamTools/ToolDistance.py:355 -#: flatcamTools/ToolDistanceMin.py:284 flatcamTools/ToolTransform.py:332 +#: flatcamGUI/PreferencesUI.py:6883 flatcamTools/ToolDistance.py:496 +#: flatcamTools/ToolDistanceMin.py:287 flatcamTools/ToolTransform.py:333 msgid "Distance" msgstr "" -#: flatcamGUI/PreferencesUI.py:6398 flatcamTools/ToolTransform.py:334 +#: flatcamGUI/PreferencesUI.py:6885 flatcamTools/ToolTransform.py:335 msgid "" "A positive value will create the effect of dilation,\n" "while a negative value will create the effect of erosion.\n" @@ -10041,12 +10378,21 @@ msgid "" "or decreased with the 'distance'." msgstr "" -#: flatcamGUI/PreferencesUI.py:6414 flatcamGUI/PreferencesUI.py:7057 -#: flatcamTools/ToolQRCode.py:197 flatcamTools/ToolTransform.py:361 +#: flatcamGUI/PreferencesUI.py:6902 flatcamTools/ToolTransform.py:360 +msgid "" +"A positive value will create the effect of dilation,\n" +"while a negative value will create the effect of erosion.\n" +"Each geometry element of the object will be increased\n" +"or decreased to fit the 'Value'. Value is a percentage\n" +"of the initial dimension." +msgstr "" + +#: flatcamGUI/PreferencesUI.py:6919 flatcamGUI/PreferencesUI.py:7563 +#: flatcamTools/ToolQRCode.py:197 flatcamTools/ToolTransform.py:384 msgid "Rounded" msgstr "" -#: flatcamGUI/PreferencesUI.py:6416 flatcamTools/ToolTransform.py:363 +#: flatcamGUI/PreferencesUI.py:6921 flatcamTools/ToolTransform.py:386 msgid "" "If checked then the buffer will surround the buffered shape,\n" "every corner will be rounded.\n" @@ -10054,356 +10400,352 @@ msgid "" "of the buffered shape." msgstr "" -#: flatcamGUI/PreferencesUI.py:6434 +#: flatcamGUI/PreferencesUI.py:6938 msgid "SolderPaste Tool Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:6440 +#: flatcamGUI/PreferencesUI.py:6944 msgid "" "A tool to create GCode for dispensing\n" "solder paste onto a PCB." msgstr "" -#: flatcamGUI/PreferencesUI.py:6451 -msgid "Diameters of nozzle tools, separated by ','" -msgstr "" - -#: flatcamGUI/PreferencesUI.py:6459 +#: flatcamGUI/PreferencesUI.py:6965 msgid "New Nozzle Dia" msgstr "" -#: flatcamGUI/PreferencesUI.py:6461 flatcamTools/ToolSolderPaste.py:106 +#: flatcamGUI/PreferencesUI.py:6967 flatcamTools/ToolSolderPaste.py:108 msgid "Diameter for the new Nozzle tool to add in the Tool Table" msgstr "" -#: flatcamGUI/PreferencesUI.py:6477 flatcamTools/ToolSolderPaste.py:182 +#: flatcamGUI/PreferencesUI.py:6983 flatcamTools/ToolSolderPaste.py:184 msgid "Z Dispense Start" msgstr "" -#: flatcamGUI/PreferencesUI.py:6479 flatcamTools/ToolSolderPaste.py:184 +#: flatcamGUI/PreferencesUI.py:6985 flatcamTools/ToolSolderPaste.py:186 msgid "The height (Z) when solder paste dispensing starts." msgstr "" -#: flatcamGUI/PreferencesUI.py:6490 flatcamTools/ToolSolderPaste.py:194 +#: flatcamGUI/PreferencesUI.py:6996 flatcamTools/ToolSolderPaste.py:196 msgid "Z Dispense" msgstr "" -#: flatcamGUI/PreferencesUI.py:6492 flatcamTools/ToolSolderPaste.py:196 +#: flatcamGUI/PreferencesUI.py:6998 flatcamTools/ToolSolderPaste.py:198 msgid "The height (Z) when doing solder paste dispensing." msgstr "" -#: flatcamGUI/PreferencesUI.py:6503 flatcamTools/ToolSolderPaste.py:206 +#: flatcamGUI/PreferencesUI.py:7009 flatcamTools/ToolSolderPaste.py:208 msgid "Z Dispense Stop" msgstr "" -#: flatcamGUI/PreferencesUI.py:6505 flatcamTools/ToolSolderPaste.py:208 +#: flatcamGUI/PreferencesUI.py:7011 flatcamTools/ToolSolderPaste.py:210 msgid "The height (Z) when solder paste dispensing stops." msgstr "" -#: flatcamGUI/PreferencesUI.py:6516 flatcamTools/ToolSolderPaste.py:218 +#: flatcamGUI/PreferencesUI.py:7022 flatcamTools/ToolSolderPaste.py:220 msgid "Z Travel" msgstr "" -#: flatcamGUI/PreferencesUI.py:6518 flatcamTools/ToolSolderPaste.py:220 +#: flatcamGUI/PreferencesUI.py:7024 flatcamTools/ToolSolderPaste.py:222 msgid "" "The height (Z) for travel between pads\n" "(without dispensing solder paste)." msgstr "" -#: flatcamGUI/PreferencesUI.py:6530 flatcamTools/ToolSolderPaste.py:231 +#: flatcamGUI/PreferencesUI.py:7036 flatcamTools/ToolSolderPaste.py:233 msgid "Z Toolchange" msgstr "" -#: flatcamGUI/PreferencesUI.py:6532 flatcamTools/ToolSolderPaste.py:233 +#: flatcamGUI/PreferencesUI.py:7038 flatcamTools/ToolSolderPaste.py:235 msgid "The height (Z) for tool (nozzle) change." msgstr "" -#: flatcamGUI/PreferencesUI.py:6541 flatcamTools/ToolSolderPaste.py:241 +#: flatcamGUI/PreferencesUI.py:7047 flatcamTools/ToolSolderPaste.py:243 msgid "" "The X,Y location for tool (nozzle) change.\n" "The format is (x, y) where x and y are real numbers." msgstr "" -#: flatcamGUI/PreferencesUI.py:6555 flatcamTools/ToolSolderPaste.py:254 +#: flatcamGUI/PreferencesUI.py:7061 flatcamTools/ToolSolderPaste.py:256 msgid "Feedrate (speed) while moving on the X-Y plane." msgstr "" -#: flatcamGUI/PreferencesUI.py:6568 flatcamTools/ToolSolderPaste.py:266 +#: flatcamGUI/PreferencesUI.py:7074 flatcamTools/ToolSolderPaste.py:268 msgid "" "Feedrate (speed) while moving vertically\n" "(on Z plane)." msgstr "" -#: flatcamGUI/PreferencesUI.py:6580 flatcamTools/ToolSolderPaste.py:277 +#: flatcamGUI/PreferencesUI.py:7086 flatcamTools/ToolSolderPaste.py:279 msgid "Feedrate Z Dispense" msgstr "" -#: flatcamGUI/PreferencesUI.py:6582 +#: flatcamGUI/PreferencesUI.py:7088 msgid "" "Feedrate (speed) while moving up vertically\n" "to Dispense position (on Z plane)." msgstr "" -#: flatcamGUI/PreferencesUI.py:6593 flatcamTools/ToolSolderPaste.py:289 +#: flatcamGUI/PreferencesUI.py:7099 flatcamTools/ToolSolderPaste.py:291 msgid "Spindle Speed FWD" msgstr "" -#: flatcamGUI/PreferencesUI.py:6595 flatcamTools/ToolSolderPaste.py:291 +#: flatcamGUI/PreferencesUI.py:7101 flatcamTools/ToolSolderPaste.py:293 msgid "" "The dispenser speed while pushing solder paste\n" "through the dispenser nozzle." msgstr "" -#: flatcamGUI/PreferencesUI.py:6607 flatcamTools/ToolSolderPaste.py:302 +#: flatcamGUI/PreferencesUI.py:7113 flatcamTools/ToolSolderPaste.py:304 msgid "Dwell FWD" msgstr "" -#: flatcamGUI/PreferencesUI.py:6609 flatcamTools/ToolSolderPaste.py:304 +#: flatcamGUI/PreferencesUI.py:7115 flatcamTools/ToolSolderPaste.py:306 msgid "Pause after solder dispensing." msgstr "" -#: flatcamGUI/PreferencesUI.py:6619 flatcamTools/ToolSolderPaste.py:313 +#: flatcamGUI/PreferencesUI.py:7125 flatcamTools/ToolSolderPaste.py:315 msgid "Spindle Speed REV" msgstr "" -#: flatcamGUI/PreferencesUI.py:6621 flatcamTools/ToolSolderPaste.py:315 +#: flatcamGUI/PreferencesUI.py:7127 flatcamTools/ToolSolderPaste.py:317 msgid "" "The dispenser speed while retracting solder paste\n" "through the dispenser nozzle." msgstr "" -#: flatcamGUI/PreferencesUI.py:6633 flatcamTools/ToolSolderPaste.py:326 +#: flatcamGUI/PreferencesUI.py:7139 flatcamTools/ToolSolderPaste.py:328 msgid "Dwell REV" msgstr "" -#: flatcamGUI/PreferencesUI.py:6635 flatcamTools/ToolSolderPaste.py:328 +#: flatcamGUI/PreferencesUI.py:7141 flatcamTools/ToolSolderPaste.py:330 msgid "" "Pause after solder paste dispenser retracted,\n" "to allow pressure equilibrium." msgstr "" -#: flatcamGUI/PreferencesUI.py:6644 flatcamTools/ToolSolderPaste.py:336 +#: flatcamGUI/PreferencesUI.py:7150 flatcamTools/ToolSolderPaste.py:338 msgid "Files that control the GCode generation." msgstr "" -#: flatcamGUI/PreferencesUI.py:6659 +#: flatcamGUI/PreferencesUI.py:7165 msgid "Substractor Tool Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:6665 +#: flatcamGUI/PreferencesUI.py:7171 msgid "" "A tool to substract one Gerber or Geometry object\n" "from another of the same type." msgstr "" -#: flatcamGUI/PreferencesUI.py:6670 flatcamTools/ToolSub.py:149 +#: flatcamGUI/PreferencesUI.py:7176 flatcamTools/ToolSub.py:155 msgid "Close paths" msgstr "" -#: flatcamGUI/PreferencesUI.py:6671 +#: flatcamGUI/PreferencesUI.py:7177 msgid "Checking this will close the paths cut by the Geometry substractor object." msgstr "" -#: flatcamGUI/PreferencesUI.py:6682 +#: flatcamGUI/PreferencesUI.py:7188 msgid "Check Rules Tool Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:6687 +#: flatcamGUI/PreferencesUI.py:7193 msgid "" "A tool to check if Gerber files are within a set\n" "of Manufacturing Rules." msgstr "" -#: flatcamGUI/PreferencesUI.py:6697 flatcamTools/ToolRulesCheck.py:256 -#: flatcamTools/ToolRulesCheck.py:920 +#: flatcamGUI/PreferencesUI.py:7203 flatcamTools/ToolRulesCheck.py:265 +#: flatcamTools/ToolRulesCheck.py:929 msgid "Trace Size" msgstr "" -#: flatcamGUI/PreferencesUI.py:6699 flatcamTools/ToolRulesCheck.py:258 +#: flatcamGUI/PreferencesUI.py:7205 flatcamTools/ToolRulesCheck.py:267 msgid "This checks if the minimum size for traces is met." msgstr "" -#: flatcamGUI/PreferencesUI.py:6709 flatcamGUI/PreferencesUI.py:6729 -#: flatcamGUI/PreferencesUI.py:6749 flatcamGUI/PreferencesUI.py:6769 -#: flatcamGUI/PreferencesUI.py:6789 flatcamGUI/PreferencesUI.py:6809 -#: flatcamGUI/PreferencesUI.py:6829 flatcamGUI/PreferencesUI.py:6849 -#: flatcamGUI/PreferencesUI.py:6871 flatcamGUI/PreferencesUI.py:6891 -#: flatcamTools/ToolRulesCheck.py:268 flatcamTools/ToolRulesCheck.py:290 -#: flatcamTools/ToolRulesCheck.py:313 flatcamTools/ToolRulesCheck.py:336 -#: flatcamTools/ToolRulesCheck.py:359 flatcamTools/ToolRulesCheck.py:382 -#: flatcamTools/ToolRulesCheck.py:405 flatcamTools/ToolRulesCheck.py:428 -#: flatcamTools/ToolRulesCheck.py:453 flatcamTools/ToolRulesCheck.py:476 +#: flatcamGUI/PreferencesUI.py:7215 flatcamGUI/PreferencesUI.py:7235 +#: flatcamGUI/PreferencesUI.py:7255 flatcamGUI/PreferencesUI.py:7275 +#: flatcamGUI/PreferencesUI.py:7295 flatcamGUI/PreferencesUI.py:7315 +#: flatcamGUI/PreferencesUI.py:7335 flatcamGUI/PreferencesUI.py:7355 +#: flatcamGUI/PreferencesUI.py:7377 flatcamGUI/PreferencesUI.py:7397 +#: flatcamTools/ToolRulesCheck.py:277 flatcamTools/ToolRulesCheck.py:299 +#: flatcamTools/ToolRulesCheck.py:322 flatcamTools/ToolRulesCheck.py:345 +#: flatcamTools/ToolRulesCheck.py:368 flatcamTools/ToolRulesCheck.py:391 +#: flatcamTools/ToolRulesCheck.py:414 flatcamTools/ToolRulesCheck.py:437 +#: flatcamTools/ToolRulesCheck.py:462 flatcamTools/ToolRulesCheck.py:485 msgid "Min value" msgstr "" -#: flatcamGUI/PreferencesUI.py:6711 flatcamTools/ToolRulesCheck.py:270 +#: flatcamGUI/PreferencesUI.py:7217 flatcamTools/ToolRulesCheck.py:279 msgid "Minimum acceptable trace size." msgstr "" -#: flatcamGUI/PreferencesUI.py:6716 flatcamTools/ToolRulesCheck.py:277 -#: flatcamTools/ToolRulesCheck.py:1148 flatcamTools/ToolRulesCheck.py:1178 +#: flatcamGUI/PreferencesUI.py:7222 flatcamTools/ToolRulesCheck.py:286 +#: flatcamTools/ToolRulesCheck.py:1157 flatcamTools/ToolRulesCheck.py:1187 msgid "Copper to Copper clearance" msgstr "" -#: flatcamGUI/PreferencesUI.py:6718 flatcamTools/ToolRulesCheck.py:279 +#: flatcamGUI/PreferencesUI.py:7224 flatcamTools/ToolRulesCheck.py:288 msgid "" "This checks if the minimum clearance between copper\n" "features is met." msgstr "" -#: flatcamGUI/PreferencesUI.py:6731 flatcamGUI/PreferencesUI.py:6751 -#: flatcamGUI/PreferencesUI.py:6771 flatcamGUI/PreferencesUI.py:6791 -#: flatcamGUI/PreferencesUI.py:6811 flatcamGUI/PreferencesUI.py:6831 -#: flatcamGUI/PreferencesUI.py:6893 flatcamTools/ToolRulesCheck.py:292 -#: flatcamTools/ToolRulesCheck.py:315 flatcamTools/ToolRulesCheck.py:338 -#: flatcamTools/ToolRulesCheck.py:361 flatcamTools/ToolRulesCheck.py:384 -#: flatcamTools/ToolRulesCheck.py:407 flatcamTools/ToolRulesCheck.py:455 +#: flatcamGUI/PreferencesUI.py:7237 flatcamGUI/PreferencesUI.py:7257 +#: flatcamGUI/PreferencesUI.py:7277 flatcamGUI/PreferencesUI.py:7297 +#: flatcamGUI/PreferencesUI.py:7317 flatcamGUI/PreferencesUI.py:7337 +#: flatcamGUI/PreferencesUI.py:7399 flatcamTools/ToolRulesCheck.py:301 +#: flatcamTools/ToolRulesCheck.py:324 flatcamTools/ToolRulesCheck.py:347 +#: flatcamTools/ToolRulesCheck.py:370 flatcamTools/ToolRulesCheck.py:393 +#: flatcamTools/ToolRulesCheck.py:416 flatcamTools/ToolRulesCheck.py:464 msgid "Minimum acceptable clearance value." msgstr "" -#: flatcamGUI/PreferencesUI.py:6736 flatcamTools/ToolRulesCheck.py:300 -#: flatcamTools/ToolRulesCheck.py:1208 flatcamTools/ToolRulesCheck.py:1214 -#: flatcamTools/ToolRulesCheck.py:1227 flatcamTools/ToolRulesCheck.py:1234 +#: flatcamGUI/PreferencesUI.py:7242 flatcamTools/ToolRulesCheck.py:309 +#: flatcamTools/ToolRulesCheck.py:1217 flatcamTools/ToolRulesCheck.py:1223 +#: flatcamTools/ToolRulesCheck.py:1236 flatcamTools/ToolRulesCheck.py:1243 msgid "Copper to Outline clearance" msgstr "" -#: flatcamGUI/PreferencesUI.py:6738 flatcamTools/ToolRulesCheck.py:302 +#: flatcamGUI/PreferencesUI.py:7244 flatcamTools/ToolRulesCheck.py:311 msgid "" "This checks if the minimum clearance between copper\n" "features and the outline is met." msgstr "" -#: flatcamGUI/PreferencesUI.py:6756 flatcamTools/ToolRulesCheck.py:323 +#: flatcamGUI/PreferencesUI.py:7262 flatcamTools/ToolRulesCheck.py:332 msgid "Silk to Silk Clearance" msgstr "" -#: flatcamGUI/PreferencesUI.py:6758 flatcamTools/ToolRulesCheck.py:325 +#: flatcamGUI/PreferencesUI.py:7264 flatcamTools/ToolRulesCheck.py:334 msgid "" "This checks if the minimum clearance between silkscreen\n" "features and silkscreen features is met." msgstr "" -#: flatcamGUI/PreferencesUI.py:6776 flatcamTools/ToolRulesCheck.py:346 -#: flatcamTools/ToolRulesCheck.py:1317 flatcamTools/ToolRulesCheck.py:1323 -#: flatcamTools/ToolRulesCheck.py:1341 +#: flatcamGUI/PreferencesUI.py:7282 flatcamTools/ToolRulesCheck.py:355 +#: flatcamTools/ToolRulesCheck.py:1326 flatcamTools/ToolRulesCheck.py:1332 +#: flatcamTools/ToolRulesCheck.py:1350 msgid "Silk to Solder Mask Clearance" msgstr "" -#: flatcamGUI/PreferencesUI.py:6778 flatcamTools/ToolRulesCheck.py:348 +#: flatcamGUI/PreferencesUI.py:7284 flatcamTools/ToolRulesCheck.py:357 msgid "" "This checks if the minimum clearance between silkscreen\n" "features and soldermask features is met." msgstr "" -#: flatcamGUI/PreferencesUI.py:6796 flatcamTools/ToolRulesCheck.py:369 -#: flatcamTools/ToolRulesCheck.py:1371 flatcamTools/ToolRulesCheck.py:1377 -#: flatcamTools/ToolRulesCheck.py:1391 flatcamTools/ToolRulesCheck.py:1398 +#: flatcamGUI/PreferencesUI.py:7302 flatcamTools/ToolRulesCheck.py:378 +#: flatcamTools/ToolRulesCheck.py:1380 flatcamTools/ToolRulesCheck.py:1386 +#: flatcamTools/ToolRulesCheck.py:1400 flatcamTools/ToolRulesCheck.py:1407 msgid "Silk to Outline Clearance" msgstr "" -#: flatcamGUI/PreferencesUI.py:6798 flatcamTools/ToolRulesCheck.py:371 +#: flatcamGUI/PreferencesUI.py:7304 flatcamTools/ToolRulesCheck.py:380 msgid "" "This checks if the minimum clearance between silk\n" "features and the outline is met." msgstr "" -#: flatcamGUI/PreferencesUI.py:6816 flatcamTools/ToolRulesCheck.py:392 -#: flatcamTools/ToolRulesCheck.py:1409 flatcamTools/ToolRulesCheck.py:1436 +#: flatcamGUI/PreferencesUI.py:7322 flatcamTools/ToolRulesCheck.py:401 +#: flatcamTools/ToolRulesCheck.py:1418 flatcamTools/ToolRulesCheck.py:1445 msgid "Minimum Solder Mask Sliver" msgstr "" -#: flatcamGUI/PreferencesUI.py:6818 flatcamTools/ToolRulesCheck.py:394 +#: flatcamGUI/PreferencesUI.py:7324 flatcamTools/ToolRulesCheck.py:403 msgid "" "This checks if the minimum clearance between soldermask\n" "features and soldermask features is met." msgstr "" -#: flatcamGUI/PreferencesUI.py:6836 flatcamTools/ToolRulesCheck.py:415 -#: flatcamTools/ToolRulesCheck.py:1474 flatcamTools/ToolRulesCheck.py:1480 -#: flatcamTools/ToolRulesCheck.py:1496 flatcamTools/ToolRulesCheck.py:1503 +#: flatcamGUI/PreferencesUI.py:7342 flatcamTools/ToolRulesCheck.py:424 +#: flatcamTools/ToolRulesCheck.py:1483 flatcamTools/ToolRulesCheck.py:1489 +#: flatcamTools/ToolRulesCheck.py:1505 flatcamTools/ToolRulesCheck.py:1512 msgid "Minimum Annular Ring" msgstr "" -#: flatcamGUI/PreferencesUI.py:6838 flatcamTools/ToolRulesCheck.py:417 +#: flatcamGUI/PreferencesUI.py:7344 flatcamTools/ToolRulesCheck.py:426 msgid "" "This checks if the minimum copper ring left by drilling\n" "a hole into a pad is met." msgstr "" -#: flatcamGUI/PreferencesUI.py:6851 flatcamTools/ToolRulesCheck.py:430 +#: flatcamGUI/PreferencesUI.py:7357 flatcamTools/ToolRulesCheck.py:439 msgid "Minimum acceptable ring value." msgstr "" -#: flatcamGUI/PreferencesUI.py:6858 flatcamTools/ToolRulesCheck.py:440 -#: flatcamTools/ToolRulesCheck.py:864 +#: flatcamGUI/PreferencesUI.py:7364 flatcamTools/ToolRulesCheck.py:449 +#: flatcamTools/ToolRulesCheck.py:873 msgid "Hole to Hole Clearance" msgstr "" -#: flatcamGUI/PreferencesUI.py:6860 flatcamTools/ToolRulesCheck.py:442 +#: flatcamGUI/PreferencesUI.py:7366 flatcamTools/ToolRulesCheck.py:451 msgid "" "This checks if the minimum clearance between a drill hole\n" "and another drill hole is met." msgstr "" -#: flatcamGUI/PreferencesUI.py:6873 flatcamTools/ToolRulesCheck.py:478 +#: flatcamGUI/PreferencesUI.py:7379 flatcamTools/ToolRulesCheck.py:487 msgid "Minimum acceptable drill size." msgstr "" -#: flatcamGUI/PreferencesUI.py:6878 flatcamTools/ToolRulesCheck.py:463 -#: flatcamTools/ToolRulesCheck.py:838 +#: flatcamGUI/PreferencesUI.py:7384 flatcamTools/ToolRulesCheck.py:472 +#: flatcamTools/ToolRulesCheck.py:847 msgid "Hole Size" msgstr "" -#: flatcamGUI/PreferencesUI.py:6880 flatcamTools/ToolRulesCheck.py:465 +#: flatcamGUI/PreferencesUI.py:7386 flatcamTools/ToolRulesCheck.py:474 msgid "" "This checks if the drill holes\n" "sizes are above the threshold." msgstr "" -#: flatcamGUI/PreferencesUI.py:6905 +#: flatcamGUI/PreferencesUI.py:7411 msgid "Optimal Tool Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:6911 +#: flatcamGUI/PreferencesUI.py:7417 msgid "" "A tool to find the minimum distance between\n" "every two Gerber geometric elements" msgstr "" -#: flatcamGUI/PreferencesUI.py:6926 flatcamTools/ToolOptimal.py:78 +#: flatcamGUI/PreferencesUI.py:7432 flatcamTools/ToolOptimal.py:79 msgid "Precision" msgstr "" -#: flatcamGUI/PreferencesUI.py:6928 +#: flatcamGUI/PreferencesUI.py:7434 msgid "Number of decimals for the distances and coordinates in this tool." msgstr "" -#: flatcamGUI/PreferencesUI.py:6942 +#: flatcamGUI/PreferencesUI.py:7448 msgid "QRCode Tool Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:6948 +#: flatcamGUI/PreferencesUI.py:7454 msgid "" "A tool to create a QRCode that can be inserted\n" "into a selected Gerber file, or it can be exported as a file." msgstr "" -#: flatcamGUI/PreferencesUI.py:6960 flatcamTools/ToolQRCode.py:99 +#: flatcamGUI/PreferencesUI.py:7466 flatcamTools/ToolQRCode.py:100 msgid "Version" msgstr "" -#: flatcamGUI/PreferencesUI.py:6962 flatcamTools/ToolQRCode.py:101 +#: flatcamGUI/PreferencesUI.py:7468 flatcamTools/ToolQRCode.py:102 msgid "" "QRCode version can have values from 1 (21x21 boxes)\n" "to 40 (177x177 boxes)." msgstr "" -#: flatcamGUI/PreferencesUI.py:6973 flatcamTools/ToolQRCode.py:112 +#: flatcamGUI/PreferencesUI.py:7479 flatcamTools/ToolQRCode.py:113 msgid "Error correction" msgstr "" -#: flatcamGUI/PreferencesUI.py:6975 flatcamGUI/PreferencesUI.py:6986 -#: flatcamTools/ToolQRCode.py:114 flatcamTools/ToolQRCode.py:125 +#: flatcamGUI/PreferencesUI.py:7481 flatcamGUI/PreferencesUI.py:7492 +#: flatcamTools/ToolQRCode.py:115 flatcamTools/ToolQRCode.py:126 #, python-format msgid "" "Parameter that controls the error correction used for the QR Code.\n" @@ -10413,60 +10755,60 @@ msgid "" "H = maximum 30%% errors can be corrected." msgstr "" -#: flatcamGUI/PreferencesUI.py:6996 flatcamTools/ToolQRCode.py:135 +#: flatcamGUI/PreferencesUI.py:7502 flatcamTools/ToolQRCode.py:136 msgid "Box Size" msgstr "" -#: flatcamGUI/PreferencesUI.py:6998 flatcamTools/ToolQRCode.py:137 +#: flatcamGUI/PreferencesUI.py:7504 flatcamTools/ToolQRCode.py:138 msgid "" "Box size control the overall size of the QRcode\n" "by adjusting the size of each box in the code." msgstr "" -#: flatcamGUI/PreferencesUI.py:7009 flatcamTools/ToolQRCode.py:148 +#: flatcamGUI/PreferencesUI.py:7515 flatcamTools/ToolQRCode.py:149 msgid "Border Size" msgstr "" -#: flatcamGUI/PreferencesUI.py:7011 flatcamTools/ToolQRCode.py:150 +#: flatcamGUI/PreferencesUI.py:7517 flatcamTools/ToolQRCode.py:151 msgid "" "Size of the QRCode border. How many boxes thick is the border.\n" "Default value is 4. The width of the clearance around the QRCode." msgstr "" -#: flatcamGUI/PreferencesUI.py:7022 flatcamTools/ToolQRCode.py:162 +#: flatcamGUI/PreferencesUI.py:7528 flatcamTools/ToolQRCode.py:162 msgid "QRCode Data" msgstr "" -#: flatcamGUI/PreferencesUI.py:7024 flatcamTools/ToolQRCode.py:164 +#: flatcamGUI/PreferencesUI.py:7530 flatcamTools/ToolQRCode.py:164 msgid "QRCode Data. Alphanumeric text to be encoded in the QRCode." msgstr "" -#: flatcamGUI/PreferencesUI.py:7028 flatcamTools/ToolQRCode.py:168 +#: flatcamGUI/PreferencesUI.py:7534 flatcamTools/ToolQRCode.py:168 msgid "Add here the text to be included in the QRCode..." msgstr "" -#: flatcamGUI/PreferencesUI.py:7034 flatcamTools/ToolQRCode.py:174 +#: flatcamGUI/PreferencesUI.py:7540 flatcamTools/ToolQRCode.py:174 msgid "Polarity" msgstr "" -#: flatcamGUI/PreferencesUI.py:7036 flatcamTools/ToolQRCode.py:176 +#: flatcamGUI/PreferencesUI.py:7542 flatcamTools/ToolQRCode.py:176 msgid "" "Choose the polarity of the QRCode.\n" "It can be drawn in a negative way (squares are clear)\n" "or in a positive way (squares are opaque)." msgstr "" -#: flatcamGUI/PreferencesUI.py:7040 flatcamTools/ToolFilm.py:296 +#: flatcamGUI/PreferencesUI.py:7546 flatcamTools/ToolFilm.py:296 #: flatcamTools/ToolQRCode.py:180 msgid "Negative" msgstr "" -#: flatcamGUI/PreferencesUI.py:7041 flatcamTools/ToolFilm.py:295 +#: flatcamGUI/PreferencesUI.py:7547 flatcamTools/ToolFilm.py:295 #: flatcamTools/ToolQRCode.py:181 msgid "Positive" msgstr "" -#: flatcamGUI/PreferencesUI.py:7043 flatcamTools/ToolQRCode.py:183 +#: flatcamGUI/PreferencesUI.py:7549 flatcamTools/ToolQRCode.py:183 msgid "" "Choose the type of QRCode to be created.\n" "If added on a Silkscreen Gerber file the QRCode may\n" @@ -10474,71 +10816,60 @@ msgid "" "file then perhaps the QRCode can be added as negative." msgstr "" -#: flatcamGUI/PreferencesUI.py:7054 flatcamGUI/PreferencesUI.py:7060 +#: flatcamGUI/PreferencesUI.py:7560 flatcamGUI/PreferencesUI.py:7566 #: flatcamTools/ToolQRCode.py:194 flatcamTools/ToolQRCode.py:200 msgid "" "The bounding box, meaning the empty space that surrounds\n" "the QRCode geometry, can have a rounded or a square shape." msgstr "" -#: flatcamGUI/PreferencesUI.py:7067 flatcamTools/ToolQRCode.py:228 +#: flatcamGUI/PreferencesUI.py:7573 flatcamTools/ToolQRCode.py:228 msgid "Fill Color" msgstr "" -#: flatcamGUI/PreferencesUI.py:7069 flatcamTools/ToolQRCode.py:230 +#: flatcamGUI/PreferencesUI.py:7575 flatcamTools/ToolQRCode.py:230 msgid "Set the QRCode fill color (squares color)." msgstr "" -#: flatcamGUI/PreferencesUI.py:7088 flatcamTools/ToolQRCode.py:252 +#: flatcamGUI/PreferencesUI.py:7594 flatcamTools/ToolQRCode.py:252 msgid "Back Color" msgstr "" -#: flatcamGUI/PreferencesUI.py:7090 flatcamTools/ToolQRCode.py:254 +#: flatcamGUI/PreferencesUI.py:7596 flatcamTools/ToolQRCode.py:254 msgid "Set the QRCode background color." msgstr "" -#: flatcamGUI/PreferencesUI.py:7130 +#: flatcamGUI/PreferencesUI.py:7636 msgid "Copper Thieving Tool Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:7142 +#: flatcamGUI/PreferencesUI.py:7648 msgid "" "A tool to generate a Copper Thieving that can be added\n" "to a selected Gerber file." msgstr "" -#: flatcamGUI/PreferencesUI.py:7150 +#: flatcamGUI/PreferencesUI.py:7656 msgid "Number of steps (lines) used to interpolate circles." msgstr "" -#: flatcamGUI/PreferencesUI.py:7160 flatcamGUI/PreferencesUI.py:7364 -#: flatcamTools/ToolCopperThieving.py:96 flatcamTools/ToolCopperThieving.py:429 +#: flatcamGUI/PreferencesUI.py:7666 flatcamGUI/PreferencesUI.py:7870 +#: flatcamTools/ToolCopperThieving.py:97 flatcamTools/ToolCopperThieving.py:432 msgid "Clearance" msgstr "" -#: flatcamGUI/PreferencesUI.py:7162 +#: flatcamGUI/PreferencesUI.py:7668 msgid "" "This set the distance between the copper Thieving components\n" "(the polygon fill may be split in multiple polygons)\n" "and the copper traces in the Gerber file." msgstr "" -#: flatcamGUI/PreferencesUI.py:7190 flatcamTools/ToolCopperThieving.py:126 -#: flatcamTools/ToolNonCopperClear.py:430 flatcamTools/ToolPaint.py:308 -msgid "Area Selection" -msgstr "" - -#: flatcamGUI/PreferencesUI.py:7191 flatcamTools/ToolCopperThieving.py:127 -#: flatcamTools/ToolNonCopperClear.py:431 flatcamTools/ToolPaint.py:310 -msgid "Reference Object" -msgstr "" - -#: flatcamGUI/PreferencesUI.py:7193 flatcamTools/ToolCopperThieving.py:129 -#: flatcamTools/ToolNonCopperClear.py:433 +#: flatcamGUI/PreferencesUI.py:7699 flatcamTools/ToolCopperThieving.py:130 msgid "Reference:" msgstr "" -#: flatcamGUI/PreferencesUI.py:7195 +#: flatcamGUI/PreferencesUI.py:7701 msgid "" "- 'Itself' - the copper Thieving extent is based on the object extent.\n" "- 'Area Selection' - left mouse click to start selection of the area to be filled.\n" @@ -10546,42 +10877,46 @@ msgid "" "object." msgstr "" -#: flatcamGUI/PreferencesUI.py:7204 flatcamTools/ToolCopperThieving.py:170 +#: flatcamGUI/PreferencesUI.py:7710 flatcamGUI/PreferencesUI.py:8175 +#: flatcamGUI/PreferencesUI.py:8287 flatcamGUI/PreferencesUI.py:8387 +#: flatcamGUI/PreferencesUI.py:8501 flatcamTools/ToolCopperThieving.py:172 +#: flatcamTools/ToolExtractDrills.py:102 flatcamTools/ToolExtractDrills.py:240 +#: flatcamTools/ToolPunchGerber.py:113 flatcamTools/ToolPunchGerber.py:268 msgid "Rectangular" msgstr "" -#: flatcamGUI/PreferencesUI.py:7205 flatcamTools/ToolCopperThieving.py:171 +#: flatcamGUI/PreferencesUI.py:7711 flatcamTools/ToolCopperThieving.py:173 msgid "Minimal" msgstr "" -#: flatcamGUI/PreferencesUI.py:7207 flatcamTools/ToolCopperThieving.py:173 +#: flatcamGUI/PreferencesUI.py:7713 flatcamTools/ToolCopperThieving.py:175 #: flatcamTools/ToolFilm.py:113 msgid "Box Type:" msgstr "" -#: flatcamGUI/PreferencesUI.py:7209 flatcamTools/ToolCopperThieving.py:175 +#: flatcamGUI/PreferencesUI.py:7715 flatcamTools/ToolCopperThieving.py:177 msgid "" "- 'Rectangular' - the bounding box will be of rectangular shape.\n" "- 'Minimal' - the bounding box will be the convex hull shape." msgstr "" -#: flatcamGUI/PreferencesUI.py:7223 flatcamTools/ToolCopperThieving.py:191 +#: flatcamGUI/PreferencesUI.py:7729 flatcamTools/ToolCopperThieving.py:193 msgid "Dots Grid" msgstr "" -#: flatcamGUI/PreferencesUI.py:7224 flatcamTools/ToolCopperThieving.py:192 +#: flatcamGUI/PreferencesUI.py:7730 flatcamTools/ToolCopperThieving.py:194 msgid "Squares Grid" msgstr "" -#: flatcamGUI/PreferencesUI.py:7225 flatcamTools/ToolCopperThieving.py:193 +#: flatcamGUI/PreferencesUI.py:7731 flatcamTools/ToolCopperThieving.py:195 msgid "Lines Grid" msgstr "" -#: flatcamGUI/PreferencesUI.py:7227 flatcamTools/ToolCopperThieving.py:195 +#: flatcamGUI/PreferencesUI.py:7733 flatcamTools/ToolCopperThieving.py:197 msgid "Fill Type:" msgstr "" -#: flatcamGUI/PreferencesUI.py:7229 flatcamTools/ToolCopperThieving.py:197 +#: flatcamGUI/PreferencesUI.py:7735 flatcamTools/ToolCopperThieving.py:199 msgid "" "- 'Solid' - copper thieving will be a solid polygon.\n" "- 'Dots Grid' - the empty area will be filled with a pattern of dots.\n" @@ -10589,131 +10924,132 @@ msgid "" "- 'Lines Grid' - the empty area will be filled with a pattern of lines." msgstr "" -#: flatcamGUI/PreferencesUI.py:7237 flatcamTools/ToolCopperThieving.py:216 +#: flatcamGUI/PreferencesUI.py:7743 flatcamTools/ToolCopperThieving.py:218 msgid "Dots Grid Parameters" msgstr "" -#: flatcamGUI/PreferencesUI.py:7243 flatcamTools/ToolCopperThieving.py:222 +#: flatcamGUI/PreferencesUI.py:7749 flatcamTools/ToolCopperThieving.py:224 msgid "Dot diameter in Dots Grid." msgstr "" -#: flatcamGUI/PreferencesUI.py:7254 flatcamGUI/PreferencesUI.py:7283 -#: flatcamGUI/PreferencesUI.py:7312 flatcamTools/ToolCopperThieving.py:233 -#: flatcamTools/ToolCopperThieving.py:273 flatcamTools/ToolCopperThieving.py:313 +#: flatcamGUI/PreferencesUI.py:7760 flatcamGUI/PreferencesUI.py:7789 +#: flatcamGUI/PreferencesUI.py:7818 flatcamTools/ToolCopperThieving.py:235 +#: flatcamTools/ToolCopperThieving.py:275 flatcamTools/ToolCopperThieving.py:315 msgid "Spacing" msgstr "" -#: flatcamGUI/PreferencesUI.py:7256 flatcamTools/ToolCopperThieving.py:235 +#: flatcamGUI/PreferencesUI.py:7762 flatcamTools/ToolCopperThieving.py:237 msgid "Distance between each two dots in Dots Grid." msgstr "" -#: flatcamGUI/PreferencesUI.py:7266 flatcamTools/ToolCopperThieving.py:256 +#: flatcamGUI/PreferencesUI.py:7772 flatcamTools/ToolCopperThieving.py:258 msgid "Squares Grid Parameters" msgstr "" -#: flatcamGUI/PreferencesUI.py:7272 flatcamTools/ToolCopperThieving.py:262 +#: flatcamGUI/PreferencesUI.py:7778 flatcamTools/ToolCopperThieving.py:264 msgid "Square side size in Squares Grid." msgstr "" -#: flatcamGUI/PreferencesUI.py:7285 flatcamTools/ToolCopperThieving.py:275 +#: flatcamGUI/PreferencesUI.py:7791 flatcamTools/ToolCopperThieving.py:277 msgid "Distance between each two squares in Squares Grid." msgstr "" -#: flatcamGUI/PreferencesUI.py:7295 flatcamTools/ToolCopperThieving.py:296 +#: flatcamGUI/PreferencesUI.py:7801 flatcamTools/ToolCopperThieving.py:298 msgid "Lines Grid Parameters" msgstr "" -#: flatcamGUI/PreferencesUI.py:7301 flatcamTools/ToolCopperThieving.py:302 +#: flatcamGUI/PreferencesUI.py:7807 flatcamTools/ToolCopperThieving.py:304 msgid "Line thickness size in Lines Grid." msgstr "" -#: flatcamGUI/PreferencesUI.py:7314 flatcamTools/ToolCopperThieving.py:315 +#: flatcamGUI/PreferencesUI.py:7820 flatcamTools/ToolCopperThieving.py:317 msgid "Distance between each two lines in Lines Grid." msgstr "" -#: flatcamGUI/PreferencesUI.py:7324 flatcamTools/ToolCopperThieving.py:353 +#: flatcamGUI/PreferencesUI.py:7830 flatcamTools/ToolCopperThieving.py:355 msgid "Robber Bar Parameters" msgstr "" -#: flatcamGUI/PreferencesUI.py:7326 flatcamTools/ToolCopperThieving.py:355 +#: flatcamGUI/PreferencesUI.py:7832 flatcamTools/ToolCopperThieving.py:357 msgid "" "Parameters used for the robber bar.\n" "Robber bar = copper border to help in pattern hole plating." msgstr "" -#: flatcamGUI/PreferencesUI.py:7334 flatcamTools/ToolCopperThieving.py:363 +#: flatcamGUI/PreferencesUI.py:7840 flatcamTools/ToolCopperThieving.py:365 msgid "Bounding box margin for robber bar." msgstr "" -#: flatcamGUI/PreferencesUI.py:7345 flatcamTools/ToolCopperThieving.py:374 +#: flatcamGUI/PreferencesUI.py:7851 flatcamTools/ToolCopperThieving.py:376 msgid "Thickness" msgstr "" -#: flatcamGUI/PreferencesUI.py:7347 flatcamTools/ToolCopperThieving.py:376 +#: flatcamGUI/PreferencesUI.py:7853 flatcamTools/ToolCopperThieving.py:378 msgid "The robber bar thickness." msgstr "" -#: flatcamGUI/PreferencesUI.py:7357 flatcamTools/ToolCopperThieving.py:407 +#: flatcamGUI/PreferencesUI.py:7863 flatcamTools/ToolCopperThieving.py:409 msgid "Pattern Plating Mask" msgstr "" -#: flatcamGUI/PreferencesUI.py:7359 flatcamTools/ToolCopperThieving.py:409 +#: flatcamGUI/PreferencesUI.py:7865 flatcamTools/ToolCopperThieving.py:411 msgid "Generate a mask for pattern plating." msgstr "" -#: flatcamGUI/PreferencesUI.py:7366 flatcamTools/ToolCopperThieving.py:431 +#: flatcamGUI/PreferencesUI.py:7872 flatcamTools/ToolCopperThieving.py:434 msgid "" "The distance between the possible copper thieving elements\n" "and/or robber bar and the actual openings in the mask." msgstr "" -#: flatcamGUI/PreferencesUI.py:7385 +#: flatcamGUI/PreferencesUI.py:7891 msgid "Fiducials Tool Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:7396 flatcamGUI/PreferencesUI.py:7512 -#: flatcamTools/ToolCopperThieving.py:91 flatcamTools/ToolFiducials.py:151 +#: flatcamGUI/PreferencesUI.py:7902 flatcamGUI/PreferencesUI.py:8018 +#: flatcamGUI/PreferencesUI.py:8137 flatcamGUI/PreferencesUI.py:8349 +#: flatcamTools/ToolCopperThieving.py:92 flatcamTools/ToolFiducials.py:151 msgid "Parameters used for this tool." msgstr "" -#: flatcamGUI/PreferencesUI.py:7403 flatcamTools/ToolFiducials.py:158 +#: flatcamGUI/PreferencesUI.py:7909 flatcamTools/ToolFiducials.py:158 msgid "" "This set the fiducial diameter if fiducial type is circular,\n" "otherwise is the size of the fiducial.\n" "The soldermask opening is double than that." msgstr "" -#: flatcamGUI/PreferencesUI.py:7431 flatcamTools/ToolFiducials.py:186 +#: flatcamGUI/PreferencesUI.py:7937 flatcamTools/ToolFiducials.py:186 msgid "Auto" msgstr "" -#: flatcamGUI/PreferencesUI.py:7432 flatcamTools/ToolFiducials.py:187 +#: flatcamGUI/PreferencesUI.py:7938 flatcamTools/ToolFiducials.py:187 msgid "Manual" msgstr "" -#: flatcamGUI/PreferencesUI.py:7434 flatcamTools/ToolFiducials.py:189 +#: flatcamGUI/PreferencesUI.py:7940 flatcamTools/ToolFiducials.py:189 msgid "Mode:" msgstr "" -#: flatcamGUI/PreferencesUI.py:7436 +#: flatcamGUI/PreferencesUI.py:7942 msgid "" "- 'Auto' - automatic placement of fiducials in the corners of the bounding box.\n" "- 'Manual' - manual placement of fiducials." msgstr "" -#: flatcamGUI/PreferencesUI.py:7444 flatcamTools/ToolFiducials.py:199 +#: flatcamGUI/PreferencesUI.py:7950 flatcamTools/ToolFiducials.py:199 msgid "Up" msgstr "" -#: flatcamGUI/PreferencesUI.py:7445 flatcamTools/ToolFiducials.py:200 +#: flatcamGUI/PreferencesUI.py:7951 flatcamTools/ToolFiducials.py:200 msgid "Down" msgstr "" -#: flatcamGUI/PreferencesUI.py:7448 flatcamTools/ToolFiducials.py:203 +#: flatcamGUI/PreferencesUI.py:7954 flatcamTools/ToolFiducials.py:203 msgid "Second fiducial" msgstr "" -#: flatcamGUI/PreferencesUI.py:7450 flatcamTools/ToolFiducials.py:205 +#: flatcamGUI/PreferencesUI.py:7956 flatcamTools/ToolFiducials.py:205 msgid "" "The position for the second fiducial.\n" "- 'Up' - the order is: bottom-left, top-left, top-right.\n" @@ -10721,19 +11057,19 @@ msgid "" "- 'None' - there is no second fiducial. The order is: bottom-left, top-right." msgstr "" -#: flatcamGUI/PreferencesUI.py:7466 flatcamTools/ToolFiducials.py:221 +#: flatcamGUI/PreferencesUI.py:7972 flatcamTools/ToolFiducials.py:221 msgid "Cross" msgstr "" -#: flatcamGUI/PreferencesUI.py:7467 flatcamTools/ToolFiducials.py:222 +#: flatcamGUI/PreferencesUI.py:7973 flatcamTools/ToolFiducials.py:222 msgid "Chess" msgstr "" -#: flatcamGUI/PreferencesUI.py:7470 flatcamTools/ToolFiducials.py:224 +#: flatcamGUI/PreferencesUI.py:7976 flatcamTools/ToolFiducials.py:224 msgid "Fiducial Type" msgstr "" -#: flatcamGUI/PreferencesUI.py:7472 flatcamTools/ToolFiducials.py:226 +#: flatcamGUI/PreferencesUI.py:7978 flatcamTools/ToolFiducials.py:226 msgid "" "The type of fiducial.\n" "- 'Circular' - this is the regular fiducial.\n" @@ -10741,19 +11077,19 @@ msgid "" "- 'Chess' - chess pattern fiducial." msgstr "" -#: flatcamGUI/PreferencesUI.py:7481 flatcamTools/ToolFiducials.py:235 +#: flatcamGUI/PreferencesUI.py:7987 flatcamTools/ToolFiducials.py:235 msgid "Line thickness" msgstr "" -#: flatcamGUI/PreferencesUI.py:7501 +#: flatcamGUI/PreferencesUI.py:8007 msgid "Calibration Tool Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:7517 flatcamTools/ToolCalibration.py:181 +#: flatcamGUI/PreferencesUI.py:8023 flatcamTools/ToolCalibration.py:181 msgid "Source Type" msgstr "" -#: flatcamGUI/PreferencesUI.py:7518 flatcamTools/ToolCalibration.py:182 +#: flatcamGUI/PreferencesUI.py:8024 flatcamTools/ToolCalibration.py:182 msgid "" "The source of calibration points.\n" "It can be:\n" @@ -10761,135 +11097,309 @@ msgid "" "- Free -> click freely on canvas to acquire the calibration points" msgstr "" -#: flatcamGUI/PreferencesUI.py:7523 flatcamTools/ToolCalibration.py:187 +#: flatcamGUI/PreferencesUI.py:8029 flatcamTools/ToolCalibration.py:187 msgid "Free" msgstr "" -#: flatcamGUI/PreferencesUI.py:7537 flatcamTools/ToolCalibration.py:76 +#: flatcamGUI/PreferencesUI.py:8043 flatcamTools/ToolCalibration.py:76 msgid "Height (Z) for travelling between the points." msgstr "" -#: flatcamGUI/PreferencesUI.py:7549 flatcamTools/ToolCalibration.py:88 +#: flatcamGUI/PreferencesUI.py:8055 flatcamTools/ToolCalibration.py:88 msgid "Verification Z" msgstr "" -#: flatcamGUI/PreferencesUI.py:7551 flatcamTools/ToolCalibration.py:90 +#: flatcamGUI/PreferencesUI.py:8057 flatcamTools/ToolCalibration.py:90 msgid "Height (Z) for checking the point." msgstr "" -#: flatcamGUI/PreferencesUI.py:7563 flatcamTools/ToolCalibration.py:102 +#: flatcamGUI/PreferencesUI.py:8069 flatcamTools/ToolCalibration.py:102 msgid "Zero Z tool" msgstr "" -#: flatcamGUI/PreferencesUI.py:7565 flatcamTools/ToolCalibration.py:104 +#: flatcamGUI/PreferencesUI.py:8071 flatcamTools/ToolCalibration.py:104 msgid "" "Include a sequence to zero the height (Z)\n" "of the verification tool." msgstr "" -#: flatcamGUI/PreferencesUI.py:7574 flatcamTools/ToolCalibration.py:113 +#: flatcamGUI/PreferencesUI.py:8080 flatcamTools/ToolCalibration.py:113 msgid "Height (Z) for mounting the verification probe." msgstr "" -#: flatcamGUI/PreferencesUI.py:7588 flatcamTools/ToolCalibration.py:127 +#: flatcamGUI/PreferencesUI.py:8094 flatcamTools/ToolCalibration.py:127 msgid "" "Toolchange X,Y position.\n" "If no value is entered then the current\n" "(x, y) point will be used," msgstr "" -#: flatcamGUI/PreferencesUI.py:7599 flatcamTools/ToolCalibration.py:153 +#: flatcamGUI/PreferencesUI.py:8105 flatcamTools/ToolCalibration.py:153 msgid "Second point" msgstr "" -#: flatcamGUI/PreferencesUI.py:7601 flatcamTools/ToolCalibration.py:155 +#: flatcamGUI/PreferencesUI.py:8107 flatcamTools/ToolCalibration.py:155 msgid "" "Second point in the Gcode verification can be:\n" "- top-left -> the user will align the PCB vertically\n" "- bottom-right -> the user will align the PCB horizontally" msgstr "" -#: flatcamGUI/PreferencesUI.py:7605 flatcamTools/ToolCalibration.py:159 -msgid "Top-Left" +#: flatcamGUI/PreferencesUI.py:8126 +msgid "Extract Drills Options" msgstr "" -#: flatcamGUI/PreferencesUI.py:7606 flatcamTools/ToolCalibration.py:160 -msgid "Bottom-Right" +#: flatcamGUI/PreferencesUI.py:8141 flatcamGUI/PreferencesUI.py:8353 +#: flatcamTools/ToolExtractDrills.py:68 flatcamTools/ToolPunchGerber.py:75 +msgid "Processed Pads Type" msgstr "" -#: flatcamGUI/PreferencesUI.py:7620 +#: flatcamGUI/PreferencesUI.py:8143 flatcamGUI/PreferencesUI.py:8355 +#: flatcamTools/ToolExtractDrills.py:70 flatcamTools/ToolPunchGerber.py:77 +msgid "" +"The type of pads shape to be processed.\n" +"If the PCB has many SMD pads with rectangular pads,\n" +"disable the Rectangular aperture." +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8153 flatcamGUI/PreferencesUI.py:8365 +#: flatcamTools/ToolExtractDrills.py:80 flatcamTools/ToolPunchGerber.py:91 +msgid "Process Circular Pads." +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8159 flatcamGUI/PreferencesUI.py:8261 +#: flatcamGUI/PreferencesUI.py:8371 flatcamGUI/PreferencesUI.py:8475 +#: flatcamTools/ToolExtractDrills.py:86 flatcamTools/ToolExtractDrills.py:214 +#: flatcamTools/ToolPunchGerber.py:97 flatcamTools/ToolPunchGerber.py:242 +msgid "Oblong" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8161 flatcamGUI/PreferencesUI.py:8373 +#: flatcamTools/ToolExtractDrills.py:88 flatcamTools/ToolPunchGerber.py:99 +msgid "Process Oblong Pads." +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8169 flatcamGUI/PreferencesUI.py:8381 +#: flatcamTools/ToolExtractDrills.py:96 flatcamTools/ToolPunchGerber.py:107 +msgid "Process Square Pads." +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8177 flatcamGUI/PreferencesUI.py:8389 +#: flatcamTools/ToolExtractDrills.py:104 flatcamTools/ToolPunchGerber.py:115 +msgid "Process Rectangular Pads." +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8183 flatcamGUI/PreferencesUI.py:8300 +#: flatcamGUI/PreferencesUI.py:8395 flatcamGUI/PreferencesUI.py:8514 +#: flatcamTools/ToolExtractDrills.py:110 flatcamTools/ToolExtractDrills.py:253 +#: flatcamTools/ToolProperties.py:172 flatcamTools/ToolPunchGerber.py:121 +#: flatcamTools/ToolPunchGerber.py:281 +msgid "Others" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8185 flatcamGUI/PreferencesUI.py:8397 +#: flatcamTools/ToolExtractDrills.py:112 flatcamTools/ToolPunchGerber.py:123 +msgid "Process pads not in the categories above." +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8198 flatcamGUI/PreferencesUI.py:8222 +#: flatcamGUI/PreferencesUI.py:8411 flatcamGUI/PreferencesUI.py:8436 +#: flatcamTools/ToolExtractDrills.py:139 flatcamTools/ToolExtractDrills.py:156 +#: flatcamTools/ToolPunchGerber.py:150 flatcamTools/ToolPunchGerber.py:184 +msgid "Fixed Diameter" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8199 flatcamGUI/PreferencesUI.py:8239 +#: flatcamGUI/PreferencesUI.py:8412 flatcamGUI/PreferencesUI.py:8453 +#: flatcamTools/ToolExtractDrills.py:140 flatcamTools/ToolExtractDrills.py:192 +#: flatcamTools/ToolPunchGerber.py:151 flatcamTools/ToolPunchGerber.py:214 +msgid "Fixed Annular Ring" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8200 flatcamGUI/PreferencesUI.py:8413 +#: flatcamTools/ToolExtractDrills.py:141 flatcamTools/ToolPunchGerber.py:152 +msgid "Proportional" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8206 flatcamTools/ToolExtractDrills.py:130 +msgid "" +"The method for processing pads. Can be:\n" +"- Fixed Diameter -> all holes will have a set size\n" +"- Fixed Annular Ring -> all holes will have a set annular ring\n" +"- Proportional -> each hole size will be a fraction of the pad size" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8232 flatcamGUI/PreferencesUI.py:8446 +#: flatcamTools/ToolExtractDrills.py:166 flatcamTools/ToolPunchGerber.py:194 +msgid "Fixed hole diameter." +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8241 flatcamGUI/PreferencesUI.py:8455 +#: flatcamTools/ToolExtractDrills.py:194 flatcamTools/ToolPunchGerber.py:216 +msgid "" +"The size of annular ring.\n" +"The copper sliver between the hole exterior\n" +"and the margin of the copper pad." +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8250 flatcamGUI/PreferencesUI.py:8464 +#: flatcamTools/ToolExtractDrills.py:203 flatcamTools/ToolPunchGerber.py:231 +msgid "The size of annular ring for circular pads." +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8263 flatcamGUI/PreferencesUI.py:8477 +#: flatcamTools/ToolExtractDrills.py:216 flatcamTools/ToolPunchGerber.py:244 +msgid "The size of annular ring for oblong pads." +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8276 flatcamGUI/PreferencesUI.py:8490 +#: flatcamTools/ToolExtractDrills.py:229 flatcamTools/ToolPunchGerber.py:257 +msgid "The size of annular ring for square pads." +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8289 flatcamGUI/PreferencesUI.py:8503 +#: flatcamTools/ToolExtractDrills.py:242 flatcamTools/ToolPunchGerber.py:270 +msgid "The size of annular ring for rectangular pads." +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8302 flatcamGUI/PreferencesUI.py:8516 +#: flatcamTools/ToolExtractDrills.py:255 flatcamTools/ToolPunchGerber.py:283 +msgid "The size of annular ring for other pads." +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8312 flatcamGUI/PreferencesUI.py:8526 +#: flatcamTools/ToolExtractDrills.py:276 flatcamTools/ToolPunchGerber.py:299 +msgid "Proportional Diameter" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8321 flatcamGUI/PreferencesUI.py:8535 +msgid "Factor" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8323 flatcamGUI/PreferencesUI.py:8537 +#: flatcamTools/ToolExtractDrills.py:287 flatcamTools/ToolPunchGerber.py:310 +msgid "" +"Proportional Diameter.\n" +"The hole diameter will be a fraction of the pad size." +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8338 +msgid "Punch Gerber Options" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8419 flatcamTools/ToolPunchGerber.py:141 +msgid "" +"The punch hole source can be:\n" +"- Excellon Object-> the Excellon object drills center will serve as reference.\n" +"- Fixed Diameter -> will try to use the pads center as reference adding fixed diameter " +"holes.\n" +"- Fixed Annular Ring -> will try to keep a set annular ring.\n" +"- Proportional -> will make a Gerber punch hole having the diameter a percentage of the " +"pad diameter.\n" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8552 +msgid "Invert Gerber Tool Options" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8558 +msgid "" +"A tool to invert Gerber geometry from positive to negative\n" +"and in revers." +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8572 flatcamTools/ToolInvertGerber.py:90 +msgid "" +"Distance by which to avoid\n" +"the edges of the Gerber object." +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8583 flatcamTools/ToolInvertGerber.py:101 +msgid "Lines Join Style" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8585 flatcamTools/ToolInvertGerber.py:103 +msgid "" +"The way that the lines in the object outline will be joined.\n" +"Can be:\n" +"- rounded -> an arc is added between two joining lines\n" +"- square -> the lines meet in 90 degrees angle\n" +"- bevel -> the lines are joined by a third line" +msgstr "" + +#: flatcamGUI/PreferencesUI.py:8608 msgid "Excellon File associations" msgstr "" -#: flatcamGUI/PreferencesUI.py:7633 flatcamGUI/PreferencesUI.py:7706 -#: flatcamGUI/PreferencesUI.py:7776 flatcamGUI/PreferencesUI.py:7846 +#: flatcamGUI/PreferencesUI.py:8621 flatcamGUI/PreferencesUI.py:8694 +#: flatcamGUI/PreferencesUI.py:8764 flatcamGUI/PreferencesUI.py:8834 msgid "Restore" msgstr "" -#: flatcamGUI/PreferencesUI.py:7634 flatcamGUI/PreferencesUI.py:7707 -#: flatcamGUI/PreferencesUI.py:7777 +#: flatcamGUI/PreferencesUI.py:8622 flatcamGUI/PreferencesUI.py:8695 +#: flatcamGUI/PreferencesUI.py:8765 msgid "Restore the extension list to the default state." msgstr "" -#: flatcamGUI/PreferencesUI.py:7635 flatcamGUI/PreferencesUI.py:7708 -#: flatcamGUI/PreferencesUI.py:7778 flatcamGUI/PreferencesUI.py:7848 +#: flatcamGUI/PreferencesUI.py:8623 flatcamGUI/PreferencesUI.py:8696 +#: flatcamGUI/PreferencesUI.py:8766 flatcamGUI/PreferencesUI.py:8836 msgid "Delete All" msgstr "" -#: flatcamGUI/PreferencesUI.py:7636 flatcamGUI/PreferencesUI.py:7709 -#: flatcamGUI/PreferencesUI.py:7779 +#: flatcamGUI/PreferencesUI.py:8624 flatcamGUI/PreferencesUI.py:8697 +#: flatcamGUI/PreferencesUI.py:8767 msgid "Delete all extensions from the list." msgstr "" -#: flatcamGUI/PreferencesUI.py:7644 flatcamGUI/PreferencesUI.py:7717 -#: flatcamGUI/PreferencesUI.py:7787 +#: flatcamGUI/PreferencesUI.py:8632 flatcamGUI/PreferencesUI.py:8705 +#: flatcamGUI/PreferencesUI.py:8775 msgid "Extensions list" msgstr "" -#: flatcamGUI/PreferencesUI.py:7646 flatcamGUI/PreferencesUI.py:7719 -#: flatcamGUI/PreferencesUI.py:7789 +#: flatcamGUI/PreferencesUI.py:8634 flatcamGUI/PreferencesUI.py:8707 +#: flatcamGUI/PreferencesUI.py:8777 msgid "" "List of file extensions to be\n" "associated with FlatCAM." msgstr "" -#: flatcamGUI/PreferencesUI.py:7666 flatcamGUI/PreferencesUI.py:7739 -#: flatcamGUI/PreferencesUI.py:7808 flatcamGUI/PreferencesUI.py:7880 +#: flatcamGUI/PreferencesUI.py:8654 flatcamGUI/PreferencesUI.py:8727 +#: flatcamGUI/PreferencesUI.py:8796 flatcamGUI/PreferencesUI.py:8868 msgid "Extension" msgstr "" -#: flatcamGUI/PreferencesUI.py:7667 flatcamGUI/PreferencesUI.py:7740 -#: flatcamGUI/PreferencesUI.py:7809 +#: flatcamGUI/PreferencesUI.py:8655 flatcamGUI/PreferencesUI.py:8728 +#: flatcamGUI/PreferencesUI.py:8797 msgid "A file extension to be added or deleted to the list." msgstr "" -#: flatcamGUI/PreferencesUI.py:7675 flatcamGUI/PreferencesUI.py:7748 -#: flatcamGUI/PreferencesUI.py:7817 +#: flatcamGUI/PreferencesUI.py:8663 flatcamGUI/PreferencesUI.py:8736 +#: flatcamGUI/PreferencesUI.py:8805 msgid "Add Extension" msgstr "" -#: flatcamGUI/PreferencesUI.py:7676 flatcamGUI/PreferencesUI.py:7749 -#: flatcamGUI/PreferencesUI.py:7818 +#: flatcamGUI/PreferencesUI.py:8664 flatcamGUI/PreferencesUI.py:8737 +#: flatcamGUI/PreferencesUI.py:8806 msgid "Add a file extension to the list" msgstr "" -#: flatcamGUI/PreferencesUI.py:7677 flatcamGUI/PreferencesUI.py:7750 -#: flatcamGUI/PreferencesUI.py:7819 +#: flatcamGUI/PreferencesUI.py:8665 flatcamGUI/PreferencesUI.py:8738 +#: flatcamGUI/PreferencesUI.py:8807 msgid "Delete Extension" msgstr "" -#: flatcamGUI/PreferencesUI.py:7678 flatcamGUI/PreferencesUI.py:7751 -#: flatcamGUI/PreferencesUI.py:7820 +#: flatcamGUI/PreferencesUI.py:8666 flatcamGUI/PreferencesUI.py:8739 +#: flatcamGUI/PreferencesUI.py:8808 msgid "Delete a file extension from the list" msgstr "" -#: flatcamGUI/PreferencesUI.py:7685 flatcamGUI/PreferencesUI.py:7758 -#: flatcamGUI/PreferencesUI.py:7827 +#: flatcamGUI/PreferencesUI.py:8673 flatcamGUI/PreferencesUI.py:8746 +#: flatcamGUI/PreferencesUI.py:8815 msgid "Apply Association" msgstr "" -#: flatcamGUI/PreferencesUI.py:7686 flatcamGUI/PreferencesUI.py:7759 -#: flatcamGUI/PreferencesUI.py:7828 +#: flatcamGUI/PreferencesUI.py:8674 flatcamGUI/PreferencesUI.py:8747 +#: flatcamGUI/PreferencesUI.py:8816 msgid "" "Apply the file associations between\n" "FlatCAM and the files with above extensions.\n" @@ -10897,31 +11407,31 @@ msgid "" "This work only in Windows." msgstr "" -#: flatcamGUI/PreferencesUI.py:7703 +#: flatcamGUI/PreferencesUI.py:8691 msgid "GCode File associations" msgstr "" -#: flatcamGUI/PreferencesUI.py:7773 +#: flatcamGUI/PreferencesUI.py:8761 msgid "Gerber File associations" msgstr "" -#: flatcamGUI/PreferencesUI.py:7843 +#: flatcamGUI/PreferencesUI.py:8831 msgid "Autocompleter Keywords" msgstr "" -#: flatcamGUI/PreferencesUI.py:7847 +#: flatcamGUI/PreferencesUI.py:8835 msgid "Restore the autocompleter keywords list to the default state." msgstr "" -#: flatcamGUI/PreferencesUI.py:7849 +#: flatcamGUI/PreferencesUI.py:8837 msgid "Delete all autocompleter keywords from the list." msgstr "" -#: flatcamGUI/PreferencesUI.py:7857 +#: flatcamGUI/PreferencesUI.py:8845 msgid "Keywords list" msgstr "" -#: flatcamGUI/PreferencesUI.py:7859 +#: flatcamGUI/PreferencesUI.py:8847 msgid "" "List of keywords used by\n" "the autocompleter in FlatCAM.\n" @@ -10929,37 +11439,37 @@ msgid "" "in the Code Editor and for the Tcl Shell." msgstr "" -#: flatcamGUI/PreferencesUI.py:7881 +#: flatcamGUI/PreferencesUI.py:8869 msgid "A keyword to be added or deleted to the list." msgstr "" -#: flatcamGUI/PreferencesUI.py:7889 +#: flatcamGUI/PreferencesUI.py:8877 msgid "Add keyword" msgstr "" -#: flatcamGUI/PreferencesUI.py:7890 +#: flatcamGUI/PreferencesUI.py:8878 msgid "Add a keyword to the list" msgstr "" -#: flatcamGUI/PreferencesUI.py:7891 +#: flatcamGUI/PreferencesUI.py:8879 msgid "Delete keyword" msgstr "" -#: flatcamGUI/PreferencesUI.py:7892 +#: flatcamGUI/PreferencesUI.py:8880 msgid "Delete a keyword from the list" msgstr "" -#: flatcamParsers/ParseExcellon.py:314 +#: flatcamParsers/ParseExcellon.py:315 msgid "This is GCODE mark" msgstr "" -#: flatcamParsers/ParseExcellon.py:431 +#: flatcamParsers/ParseExcellon.py:432 msgid "" "No tool diameter info's. See shell.\n" "A tool change event: T" msgstr "" -#: flatcamParsers/ParseExcellon.py:434 +#: flatcamParsers/ParseExcellon.py:435 msgid "" "was found but the Excellon file have no informations regarding the tool diameters " "therefore the application will try to load it by using some 'fake' diameters.\n" @@ -10967,17 +11477,17 @@ msgid "" "the real diameters." msgstr "" -#: flatcamParsers/ParseExcellon.py:886 flatcamTools/ToolSolderPaste.py:1330 +#: flatcamParsers/ParseExcellon.py:897 flatcamTools/ToolSolderPaste.py:1327 msgid "An internal error has ocurred. See shell.\n" msgstr "" -#: flatcamParsers/ParseExcellon.py:889 +#: flatcamParsers/ParseExcellon.py:900 msgid "" "Excellon Parser error.\n" "Parsing Failed. Line" msgstr "" -#: flatcamParsers/ParseExcellon.py:973 +#: flatcamParsers/ParseExcellon.py:982 msgid "" "Excellon.create_geometry() -> a drill location was skipped due of not having a tool " "associated.\n" @@ -10992,87 +11502,218 @@ msgstr "" msgid "Gerber processing. Parsing" msgstr "" -#: flatcamParsers/ParseGerber.py:426 flatcamParsers/ParseHPGL2.py:176 +#: flatcamParsers/ParseGerber.py:426 flatcamParsers/ParseHPGL2.py:178 msgid "lines" msgstr "" -#: flatcamParsers/ParseGerber.py:970 flatcamParsers/ParseGerber.py:1065 -#: flatcamParsers/ParseHPGL2.py:269 flatcamParsers/ParseHPGL2.py:283 -#: flatcamParsers/ParseHPGL2.py:302 flatcamParsers/ParseHPGL2.py:326 -#: flatcamParsers/ParseHPGL2.py:361 +#: flatcamParsers/ParseGerber.py:1002 flatcamParsers/ParseGerber.py:1102 +#: flatcamParsers/ParseHPGL2.py:271 flatcamParsers/ParseHPGL2.py:285 +#: flatcamParsers/ParseHPGL2.py:304 flatcamParsers/ParseHPGL2.py:328 +#: flatcamParsers/ParseHPGL2.py:363 msgid "Coordinates missing, line ignored" msgstr "" -#: flatcamParsers/ParseGerber.py:972 flatcamParsers/ParseGerber.py:1067 +#: flatcamParsers/ParseGerber.py:1004 flatcamParsers/ParseGerber.py:1104 msgid "GERBER file might be CORRUPT. Check the file !!!" msgstr "" -#: flatcamParsers/ParseGerber.py:1021 +#: flatcamParsers/ParseGerber.py:1058 msgid "" "Region does not have enough points. File will be processed but there are parser errors. " "Line number" msgstr "" -#: flatcamParsers/ParseGerber.py:1421 flatcamParsers/ParseHPGL2.py:396 +#: flatcamParsers/ParseGerber.py:1488 flatcamParsers/ParseHPGL2.py:398 msgid "Gerber processing. Joining polygons" msgstr "" -#: flatcamParsers/ParseGerber.py:1438 +#: flatcamParsers/ParseGerber.py:1505 msgid "Gerber processing. Applying Gerber polarity." msgstr "" -#: flatcamParsers/ParseGerber.py:1498 +#: flatcamParsers/ParseGerber.py:1565 msgid "Gerber Line" msgstr "" -#: flatcamParsers/ParseGerber.py:1498 +#: flatcamParsers/ParseGerber.py:1565 msgid "Gerber Line Content" msgstr "" -#: flatcamParsers/ParseGerber.py:1500 +#: flatcamParsers/ParseGerber.py:1567 msgid "Gerber Parser ERROR" msgstr "" -#: flatcamParsers/ParseGerber.py:1884 +#: flatcamParsers/ParseGerber.py:1956 msgid "Gerber Scale done." msgstr "" -#: flatcamParsers/ParseGerber.py:1977 +#: flatcamParsers/ParseGerber.py:2049 msgid "Gerber Offset done." msgstr "" -#: flatcamParsers/ParseGerber.py:2054 +#: flatcamParsers/ParseGerber.py:2126 msgid "Gerber Mirror done." msgstr "" -#: flatcamParsers/ParseGerber.py:2128 +#: flatcamParsers/ParseGerber.py:2200 msgid "Gerber Skew done." msgstr "" -#: flatcamParsers/ParseGerber.py:2192 +#: flatcamParsers/ParseGerber.py:2263 msgid "Gerber Rotate done." msgstr "" -#: flatcamParsers/ParseGerber.py:2273 +#: flatcamParsers/ParseGerber.py:2419 msgid "Gerber Buffer done." msgstr "" -#: flatcamParsers/ParseHPGL2.py:176 +#: flatcamParsers/ParseHPGL2.py:178 msgid "HPGL2 processing. Parsing" msgstr "" -#: flatcamParsers/ParseHPGL2.py:408 +#: flatcamParsers/ParseHPGL2.py:410 msgid "HPGL2 Line" msgstr "" -#: flatcamParsers/ParseHPGL2.py:408 +#: flatcamParsers/ParseHPGL2.py:410 msgid "HPGL2 Line Content" msgstr "" -#: flatcamParsers/ParseHPGL2.py:409 +#: flatcamParsers/ParseHPGL2.py:411 msgid "HPGL2 Parser ERROR" msgstr "" +#: flatcamTools/ToolAlignObjects.py:32 +msgid "Align Objects" +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:61 +msgid "MOVING object" +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:65 +msgid "" +"Specify the type of object to be aligned.\n" +"It can be of type: Gerber or Excellon.\n" +"The selection here decide the type of objects that will be\n" +"in the Object combobox." +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:86 +msgid "Object to be aligned." +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:98 +msgid "TARGET object" +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:100 +msgid "" +"Specify the type of object to be aligned to.\n" +"It can be of type: Gerber or Excellon.\n" +"The selection here decide the type of objects that will be\n" +"in the Object combobox." +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:122 +msgid "Object to be aligned to. Aligner." +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:135 +msgid "Alignment Type" +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:137 +msgid "" +"The type of alignment can be:\n" +"- Single Point -> it require a single point of sync, the action will be a translation\n" +"- Dual Point -> it require two points of sync, the action will be translation followed by " +"rotation" +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:143 +msgid "Single Point" +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:144 +msgid "Dual Point" +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:159 +msgid "Align Object" +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:161 +msgid "" +"Align the specified object to the aligner object.\n" +"If only one point is used then it assumes translation.\n" +"If tho points are used it assume translation and rotation." +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:176 flatcamTools/ToolCalculators.py:246 +#: flatcamTools/ToolCalibration.py:683 flatcamTools/ToolCopperThieving.py:485 +#: flatcamTools/ToolCutOut.py:372 flatcamTools/ToolDblSided.py:472 +#: flatcamTools/ToolExtractDrills.py:310 flatcamTools/ToolFiducials.py:318 +#: flatcamTools/ToolFilm.py:520 flatcamTools/ToolInvertGerber.py:140 +#: flatcamTools/ToolNCC.py:612 flatcamTools/ToolOptimal.py:238 flatcamTools/ToolPaint.py:556 +#: flatcamTools/ToolPanelize.py:269 flatcamTools/ToolPunchGerber.py:339 +#: flatcamTools/ToolQRCode.py:314 flatcamTools/ToolRulesCheck.py:516 +#: flatcamTools/ToolSolderPaste.py:474 flatcamTools/ToolSub.py:176 +#: flatcamTools/ToolTransform.py:399 +msgid "Reset Tool" +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:178 flatcamTools/ToolCalculators.py:248 +#: flatcamTools/ToolCalibration.py:685 flatcamTools/ToolCopperThieving.py:487 +#: flatcamTools/ToolCutOut.py:374 flatcamTools/ToolDblSided.py:474 +#: flatcamTools/ToolExtractDrills.py:312 flatcamTools/ToolFiducials.py:320 +#: flatcamTools/ToolFilm.py:522 flatcamTools/ToolInvertGerber.py:142 +#: flatcamTools/ToolNCC.py:614 flatcamTools/ToolOptimal.py:240 flatcamTools/ToolPaint.py:558 +#: flatcamTools/ToolPanelize.py:271 flatcamTools/ToolPunchGerber.py:341 +#: flatcamTools/ToolQRCode.py:316 flatcamTools/ToolRulesCheck.py:518 +#: flatcamTools/ToolSolderPaste.py:476 flatcamTools/ToolSub.py:178 +#: flatcamTools/ToolTransform.py:401 +msgid "Will reset the tool parameters." +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:244 +msgid "Align Tool" +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:289 +msgid "There is no aligned FlatCAM object selected..." +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:299 +msgid "There is no aligner FlatCAM object selected..." +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:325 flatcamTools/ToolAlignObjects.py:385 +msgid "First Point" +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:325 flatcamTools/ToolAlignObjects.py:400 +msgid "Click on the START point." +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:380 flatcamTools/ToolCalibration.py:920 +msgid "Cancelled by user request." +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:385 flatcamTools/ToolAlignObjects.py:407 +msgid "Click on the DESTINATION point." +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:385 flatcamTools/ToolAlignObjects.py:400 +#: flatcamTools/ToolAlignObjects.py:407 +msgid " Or right click to cancel." +msgstr "" + +#: flatcamTools/ToolAlignObjects.py:400 flatcamTools/ToolAlignObjects.py:407 +#: flatcamTools/ToolFiducials.py:111 +msgid "Second Point" +msgstr "" + #: flatcamTools/ToolCalculators.py:24 msgid "Calculators" msgstr "" @@ -11144,7 +11785,7 @@ msgid "" "depending on the parameters above" msgstr "" -#: flatcamTools/ToolCalculators.py:285 +#: flatcamTools/ToolCalculators.py:299 msgid "Calc. Tool" msgstr "" @@ -11167,80 +11808,76 @@ msgid "" "(as much as possible) corners of the object." msgstr "" -#: flatcamTools/ToolCalibration.py:193 flatcamTools/ToolCutOut.py:80 -#: flatcamTools/ToolFilm.py:78 flatcamTools/ToolImage.py:55 flatcamTools/ToolPanelize.py:66 -#: flatcamTools/ToolProperties.py:169 +#: flatcamTools/ToolCalibration.py:193 flatcamTools/ToolFilm.py:76 +#: flatcamTools/ToolImage.py:54 flatcamTools/ToolPanelize.py:78 +#: flatcamTools/ToolProperties.py:177 msgid "Object Type" msgstr "" -#: flatcamTools/ToolCalibration.py:211 +#: flatcamTools/ToolCalibration.py:210 msgid "Source object selection" msgstr "" -#: flatcamTools/ToolCalibration.py:213 +#: flatcamTools/ToolCalibration.py:212 msgid "FlatCAM Object to be used as a source for reference points." msgstr "" -#: flatcamTools/ToolCalibration.py:219 +#: flatcamTools/ToolCalibration.py:218 msgid "Calibration Points" msgstr "" -#: flatcamTools/ToolCalibration.py:221 +#: flatcamTools/ToolCalibration.py:220 msgid "" "Contain the expected calibration points and the\n" "ones measured." msgstr "" -#: flatcamTools/ToolCalibration.py:236 flatcamTools/ToolSub.py:74 -#: flatcamTools/ToolSub.py:126 +#: flatcamTools/ToolCalibration.py:235 flatcamTools/ToolSub.py:76 +#: flatcamTools/ToolSub.py:131 msgid "Target" msgstr "" -#: flatcamTools/ToolCalibration.py:237 +#: flatcamTools/ToolCalibration.py:236 msgid "Found Delta" msgstr "" -#: flatcamTools/ToolCalibration.py:249 +#: flatcamTools/ToolCalibration.py:248 msgid "Bot Left X" msgstr "" -#: flatcamTools/ToolCalibration.py:258 +#: flatcamTools/ToolCalibration.py:257 msgid "Bot Left Y" msgstr "" -#: flatcamTools/ToolCalibration.py:266 flatcamTools/ToolCalibration.py:267 -msgid "Origin" -msgstr "" - -#: flatcamTools/ToolCalibration.py:278 +#: flatcamTools/ToolCalibration.py:275 msgid "Bot Right X" msgstr "" -#: flatcamTools/ToolCalibration.py:288 +#: flatcamTools/ToolCalibration.py:285 msgid "Bot Right Y" msgstr "" -#: flatcamTools/ToolCalibration.py:303 +#: flatcamTools/ToolCalibration.py:300 msgid "Top Left X" msgstr "" -#: flatcamTools/ToolCalibration.py:312 +#: flatcamTools/ToolCalibration.py:309 msgid "Top Left Y" msgstr "" -#: flatcamTools/ToolCalibration.py:327 +#: flatcamTools/ToolCalibration.py:324 msgid "Top Right X" msgstr "" -#: flatcamTools/ToolCalibration.py:337 +#: flatcamTools/ToolCalibration.py:334 msgid "Top Right Y" msgstr "" -#: flatcamTools/ToolCalibration.py:370 +#: flatcamTools/ToolCalibration.py:367 msgid "Get Points" msgstr "" -#: flatcamTools/ToolCalibration.py:372 +#: flatcamTools/ToolCalibration.py:369 msgid "" "Pick four points by clicking on canvas if the source choice\n" "is 'free' or inside the object geometry if the source is 'object'.\n" @@ -11248,11 +11885,11 @@ msgid "" "the object." msgstr "" -#: flatcamTools/ToolCalibration.py:393 +#: flatcamTools/ToolCalibration.py:390 msgid "STEP 2: Verification GCode" msgstr "" -#: flatcamTools/ToolCalibration.py:395 flatcamTools/ToolCalibration.py:408 +#: flatcamTools/ToolCalibration.py:392 flatcamTools/ToolCalibration.py:405 msgid "" "Generate GCode file to locate and align the PCB by using\n" "the four points acquired above.\n" @@ -11263,72 +11900,72 @@ msgid "" "- forth point -> final verification point. Just for evaluation." msgstr "" -#: flatcamTools/ToolCalibration.py:406 flatcamTools/ToolSolderPaste.py:347 +#: flatcamTools/ToolCalibration.py:403 flatcamTools/ToolSolderPaste.py:349 msgid "Generate GCode" msgstr "" -#: flatcamTools/ToolCalibration.py:432 +#: flatcamTools/ToolCalibration.py:429 msgid "STEP 3: Adjustments" msgstr "" -#: flatcamTools/ToolCalibration.py:434 flatcamTools/ToolCalibration.py:443 +#: flatcamTools/ToolCalibration.py:431 flatcamTools/ToolCalibration.py:440 msgid "" "Calculate Scale and Skew factors based on the differences (delta)\n" "found when checking the PCB pattern. The differences must be filled\n" "in the fields Found (Delta)." msgstr "" -#: flatcamTools/ToolCalibration.py:441 +#: flatcamTools/ToolCalibration.py:438 msgid "Calculate Factors" msgstr "" -#: flatcamTools/ToolCalibration.py:463 +#: flatcamTools/ToolCalibration.py:460 msgid "STEP 4: Adjusted GCode" msgstr "" -#: flatcamTools/ToolCalibration.py:465 +#: flatcamTools/ToolCalibration.py:462 msgid "" "Generate verification GCode file adjusted with\n" "the factors above." msgstr "" -#: flatcamTools/ToolCalibration.py:470 +#: flatcamTools/ToolCalibration.py:467 msgid "Scale Factor X:" msgstr "" -#: flatcamTools/ToolCalibration.py:482 +#: flatcamTools/ToolCalibration.py:479 msgid "Scale Factor Y:" msgstr "" -#: flatcamTools/ToolCalibration.py:494 +#: flatcamTools/ToolCalibration.py:491 msgid "Apply Scale Factors" msgstr "" -#: flatcamTools/ToolCalibration.py:496 +#: flatcamTools/ToolCalibration.py:493 msgid "Apply Scale factors on the calibration points." msgstr "" -#: flatcamTools/ToolCalibration.py:506 +#: flatcamTools/ToolCalibration.py:503 msgid "Skew Angle X:" msgstr "" -#: flatcamTools/ToolCalibration.py:519 +#: flatcamTools/ToolCalibration.py:516 msgid "Skew Angle Y:" msgstr "" -#: flatcamTools/ToolCalibration.py:532 +#: flatcamTools/ToolCalibration.py:529 msgid "Apply Skew Factors" msgstr "" -#: flatcamTools/ToolCalibration.py:534 +#: flatcamTools/ToolCalibration.py:531 msgid "Apply Skew factors on the calibration points." msgstr "" -#: flatcamTools/ToolCalibration.py:603 +#: flatcamTools/ToolCalibration.py:600 msgid "Generate Adjusted GCode" msgstr "" -#: flatcamTools/ToolCalibration.py:605 +#: flatcamTools/ToolCalibration.py:602 msgid "" "Generate verification GCode file adjusted with\n" "the factors set above.\n" @@ -11336,122 +11973,102 @@ msgid "" "before clicking this button." msgstr "" -#: flatcamTools/ToolCalibration.py:626 +#: flatcamTools/ToolCalibration.py:623 msgid "STEP 5: Calibrate FlatCAM Objects" msgstr "" -#: flatcamTools/ToolCalibration.py:628 +#: flatcamTools/ToolCalibration.py:625 msgid "" "Adjust the FlatCAM objects\n" "with the factors determined and verified above." msgstr "" -#: flatcamTools/ToolCalibration.py:641 +#: flatcamTools/ToolCalibration.py:637 msgid "Adjusted object type" msgstr "" -#: flatcamTools/ToolCalibration.py:643 +#: flatcamTools/ToolCalibration.py:638 msgid "Type of the FlatCAM Object to be adjusted." msgstr "" -#: flatcamTools/ToolCalibration.py:654 +#: flatcamTools/ToolCalibration.py:651 msgid "Adjusted object selection" msgstr "" -#: flatcamTools/ToolCalibration.py:656 +#: flatcamTools/ToolCalibration.py:653 msgid "The FlatCAM Object to be adjusted." msgstr "" -#: flatcamTools/ToolCalibration.py:663 +#: flatcamTools/ToolCalibration.py:660 msgid "Calibrate" msgstr "" -#: flatcamTools/ToolCalibration.py:665 +#: flatcamTools/ToolCalibration.py:662 msgid "" "Adjust (scale and/or skew) the objects\n" "with the factors determined above." msgstr "" -#: flatcamTools/ToolCalibration.py:686 flatcamTools/ToolCopperThieving.py:482 -#: flatcamTools/ToolCutOut.py:362 flatcamTools/ToolDblSided.py:405 -#: flatcamTools/ToolFiducials.py:316 flatcamTools/ToolFilm.py:518 -#: flatcamTools/ToolNonCopperClear.py:486 flatcamTools/ToolOptimal.py:237 -#: flatcamTools/ToolPaint.py:372 flatcamTools/ToolPanelize.py:266 -#: flatcamTools/ToolQRCode.py:314 flatcamTools/ToolRulesCheck.py:507 -#: flatcamTools/ToolSolderPaste.py:470 flatcamTools/ToolSub.py:170 -msgid "Reset Tool" +#: flatcamTools/ToolCalibration.py:770 flatcamTools/ToolCalibration.py:771 +msgid "Origin" msgstr "" -#: flatcamTools/ToolCalibration.py:688 flatcamTools/ToolCopperThieving.py:484 -#: flatcamTools/ToolCutOut.py:364 flatcamTools/ToolDblSided.py:407 -#: flatcamTools/ToolFiducials.py:318 flatcamTools/ToolFilm.py:520 -#: flatcamTools/ToolNonCopperClear.py:488 flatcamTools/ToolOptimal.py:239 -#: flatcamTools/ToolPaint.py:374 flatcamTools/ToolPanelize.py:268 -#: flatcamTools/ToolQRCode.py:316 flatcamTools/ToolRulesCheck.py:509 -#: flatcamTools/ToolSolderPaste.py:472 flatcamTools/ToolSub.py:172 -msgid "Will reset the tool parameters." -msgstr "" - -#: flatcamTools/ToolCalibration.py:792 +#: flatcamTools/ToolCalibration.py:800 msgid "Tool initialized" msgstr "" -#: flatcamTools/ToolCalibration.py:824 +#: flatcamTools/ToolCalibration.py:838 msgid "There is no source FlatCAM object selected..." msgstr "" -#: flatcamTools/ToolCalibration.py:845 +#: flatcamTools/ToolCalibration.py:859 msgid "Get First calibration point. Bottom Left..." msgstr "" -#: flatcamTools/ToolCalibration.py:906 -msgid "Cancelled by user request." -msgstr "" - -#: flatcamTools/ToolCalibration.py:912 +#: flatcamTools/ToolCalibration.py:926 msgid "Get Second calibration point. Bottom Right (Top Left)..." msgstr "" -#: flatcamTools/ToolCalibration.py:916 +#: flatcamTools/ToolCalibration.py:930 msgid "Get Third calibration point. Top Left (Bottom Right)..." msgstr "" -#: flatcamTools/ToolCalibration.py:920 +#: flatcamTools/ToolCalibration.py:934 msgid "Get Forth calibration point. Top Right..." msgstr "" -#: flatcamTools/ToolCalibration.py:924 +#: flatcamTools/ToolCalibration.py:938 msgid "Done. All four points have been acquired." msgstr "" -#: flatcamTools/ToolCalibration.py:955 +#: flatcamTools/ToolCalibration.py:969 msgid "Verification GCode for FlatCAM Calibration Tool" msgstr "" -#: flatcamTools/ToolCalibration.py:967 flatcamTools/ToolCalibration.py:1053 +#: flatcamTools/ToolCalibration.py:981 flatcamTools/ToolCalibration.py:1067 msgid "Gcode Viewer" msgstr "" -#: flatcamTools/ToolCalibration.py:983 +#: flatcamTools/ToolCalibration.py:997 msgid "Cancelled. Four points are needed for GCode generation." msgstr "" -#: flatcamTools/ToolCalibration.py:1239 flatcamTools/ToolCalibration.py:1335 +#: flatcamTools/ToolCalibration.py:1253 flatcamTools/ToolCalibration.py:1349 msgid "There is no FlatCAM object selected..." msgstr "" -#: flatcamTools/ToolCopperThieving.py:76 flatcamTools/ToolFiducials.py:260 +#: flatcamTools/ToolCopperThieving.py:77 flatcamTools/ToolFiducials.py:261 msgid "Gerber Object to which will be added a copper thieving." msgstr "" -#: flatcamTools/ToolCopperThieving.py:98 +#: flatcamTools/ToolCopperThieving.py:99 msgid "" "This set the distance between the copper thieving components\n" "(the polygon fill may be split in multiple polygons)\n" "and the copper traces in the Gerber file." msgstr "" -#: flatcamTools/ToolCopperThieving.py:131 +#: flatcamTools/ToolCopperThieving.py:132 msgid "" "- 'Itself' - the copper thieving extent is based on the object extent.\n" "- 'Area Selection' - left mouse click to start selection of the area to be filled.\n" @@ -11459,57 +12076,42 @@ msgid "" "object." msgstr "" -#: flatcamTools/ToolCopperThieving.py:138 flatcamTools/ToolNonCopperClear.py:445 -#: flatcamTools/ToolPaint.py:326 +#: flatcamTools/ToolCopperThieving.py:139 flatcamTools/ToolNCC.py:552 +#: flatcamTools/ToolPaint.py:496 msgid "Ref. Type" msgstr "" -#: flatcamTools/ToolCopperThieving.py:140 +#: flatcamTools/ToolCopperThieving.py:141 msgid "" "The type of FlatCAM object to be used as copper thieving reference.\n" "It can be Gerber, Excellon or Geometry." msgstr "" -#: flatcamTools/ToolCopperThieving.py:144 flatcamTools/ToolDblSided.py:215 -#: flatcamTools/ToolNonCopperClear.py:451 flatcamTools/ToolPaint.py:332 -msgid "Reference Gerber" -msgstr "" - -#: flatcamTools/ToolCopperThieving.py:145 flatcamTools/ToolDblSided.py:216 -#: flatcamTools/ToolNonCopperClear.py:452 flatcamTools/ToolPaint.py:333 -msgid "Reference Excellon" -msgstr "" - -#: flatcamTools/ToolCopperThieving.py:146 flatcamTools/ToolDblSided.py:217 -#: flatcamTools/ToolNonCopperClear.py:453 flatcamTools/ToolPaint.py:334 -msgid "Reference Geometry" -msgstr "" - -#: flatcamTools/ToolCopperThieving.py:151 flatcamTools/ToolNonCopperClear.py:456 -#: flatcamTools/ToolPaint.py:337 +#: flatcamTools/ToolCopperThieving.py:150 flatcamTools/ToolNCC.py:562 +#: flatcamTools/ToolPaint.py:506 msgid "Ref. Object" msgstr "" -#: flatcamTools/ToolCopperThieving.py:153 flatcamTools/ToolNonCopperClear.py:458 -#: flatcamTools/ToolPaint.py:339 +#: flatcamTools/ToolCopperThieving.py:152 flatcamTools/ToolNCC.py:564 +#: flatcamTools/ToolPaint.py:508 msgid "The FlatCAM object to be used as non copper clearing reference." msgstr "" -#: flatcamTools/ToolCopperThieving.py:326 +#: flatcamTools/ToolCopperThieving.py:328 msgid "Insert Copper thieving" msgstr "" -#: flatcamTools/ToolCopperThieving.py:328 +#: flatcamTools/ToolCopperThieving.py:330 msgid "" "Will add a polygon (may be split in multiple parts)\n" "that will surround the actual Gerber traces at a certain distance." msgstr "" -#: flatcamTools/ToolCopperThieving.py:387 +#: flatcamTools/ToolCopperThieving.py:389 msgid "Insert Robber Bar" msgstr "" -#: flatcamTools/ToolCopperThieving.py:389 +#: flatcamTools/ToolCopperThieving.py:391 msgid "" "Will add a polygon with a defined thickness\n" "that will surround the actual Gerber object\n" @@ -11517,22 +12119,22 @@ msgid "" "Required when doing holes pattern plating." msgstr "" -#: flatcamTools/ToolCopperThieving.py:413 +#: flatcamTools/ToolCopperThieving.py:415 msgid "Select Soldermask object" msgstr "" -#: flatcamTools/ToolCopperThieving.py:415 +#: flatcamTools/ToolCopperThieving.py:417 msgid "" "Gerber Object with the soldermask.\n" "It will be used as a base for\n" "the pattern plating mask." msgstr "" -#: flatcamTools/ToolCopperThieving.py:443 +#: flatcamTools/ToolCopperThieving.py:446 msgid "Plated area" msgstr "" -#: flatcamTools/ToolCopperThieving.py:445 +#: flatcamTools/ToolCopperThieving.py:448 msgid "" "The area to be plated by pattern plating.\n" "Basically is made from the openings in the plating mask.\n" @@ -11543,141 +12145,144 @@ msgid "" "calculated from the soldermask openings." msgstr "" -#: flatcamTools/ToolCopperThieving.py:456 +#: flatcamTools/ToolCopperThieving.py:459 msgid "mm" msgstr "" -#: flatcamTools/ToolCopperThieving.py:458 +#: flatcamTools/ToolCopperThieving.py:461 msgid "in" msgstr "" -#: flatcamTools/ToolCopperThieving.py:465 +#: flatcamTools/ToolCopperThieving.py:468 msgid "Generate pattern plating mask" msgstr "" -#: flatcamTools/ToolCopperThieving.py:467 +#: flatcamTools/ToolCopperThieving.py:470 msgid "" "Will add to the soldermask gerber geometry\n" "the geometries of the copper thieving and/or\n" "the robber bar if those were generated." msgstr "" -#: flatcamTools/ToolCopperThieving.py:620 flatcamTools/ToolCopperThieving.py:645 +#: flatcamTools/ToolCopperThieving.py:626 flatcamTools/ToolCopperThieving.py:651 msgid "Lines Grid works only for 'itself' reference ..." msgstr "" -#: flatcamTools/ToolCopperThieving.py:631 +#: flatcamTools/ToolCopperThieving.py:637 msgid "Solid fill selected." msgstr "" -#: flatcamTools/ToolCopperThieving.py:636 +#: flatcamTools/ToolCopperThieving.py:642 msgid "Dots grid fill selected." msgstr "" -#: flatcamTools/ToolCopperThieving.py:641 +#: flatcamTools/ToolCopperThieving.py:647 msgid "Squares grid fill selected." msgstr "" -#: flatcamTools/ToolCopperThieving.py:662 flatcamTools/ToolCopperThieving.py:744 -#: flatcamTools/ToolCopperThieving.py:1340 flatcamTools/ToolDblSided.py:564 -#: flatcamTools/ToolFiducials.py:464 flatcamTools/ToolFiducials.py:741 -#: flatcamTools/ToolOptimal.py:342 flatcamTools/ToolQRCode.py:424 +#: flatcamTools/ToolCopperThieving.py:668 flatcamTools/ToolCopperThieving.py:750 +#: flatcamTools/ToolCopperThieving.py:1346 flatcamTools/ToolDblSided.py:658 +#: flatcamTools/ToolExtractDrills.py:436 flatcamTools/ToolFiducials.py:466 +#: flatcamTools/ToolFiducials.py:743 flatcamTools/ToolOptimal.py:343 +#: flatcamTools/ToolPunchGerber.py:512 flatcamTools/ToolQRCode.py:426 msgid "There is no Gerber object loaded ..." msgstr "" -#: flatcamTools/ToolCopperThieving.py:675 flatcamTools/ToolCopperThieving.py:1268 +#: flatcamTools/ToolCopperThieving.py:681 flatcamTools/ToolCopperThieving.py:1274 msgid "Append geometry" msgstr "" -#: flatcamTools/ToolCopperThieving.py:719 flatcamTools/ToolCopperThieving.py:1301 -#: flatcamTools/ToolCopperThieving.py:1454 +#: flatcamTools/ToolCopperThieving.py:725 flatcamTools/ToolCopperThieving.py:1307 +#: flatcamTools/ToolCopperThieving.py:1460 msgid "Append source file" msgstr "" -#: flatcamTools/ToolCopperThieving.py:727 flatcamTools/ToolCopperThieving.py:1309 +#: flatcamTools/ToolCopperThieving.py:733 flatcamTools/ToolCopperThieving.py:1315 msgid "Copper Thieving Tool done." msgstr "" -#: flatcamTools/ToolCopperThieving.py:754 flatcamTools/ToolCopperThieving.py:787 -#: flatcamTools/ToolCutOut.py:468 flatcamTools/ToolCutOut.py:642 -#: flatcamTools/ToolNonCopperClear.py:1151 flatcamTools/ToolNonCopperClear.py:1192 -#: flatcamTools/ToolNonCopperClear.py:1224 flatcamTools/ToolPaint.py:1074 -#: flatcamTools/ToolPanelize.py:401 flatcamTools/ToolPanelize.py:416 -#: flatcamTools/ToolSub.py:288 flatcamTools/ToolSub.py:301 flatcamTools/ToolSub.py:492 -#: flatcamTools/ToolSub.py:507 tclCommands/TclCommandCopperClear.py:97 -#: tclCommands/TclCommandCopperClear.py:146 tclCommands/TclCommandPaint.py:97 +#: flatcamTools/ToolCopperThieving.py:760 flatcamTools/ToolCopperThieving.py:793 +#: flatcamTools/ToolCutOut.py:480 flatcamTools/ToolCutOut.py:667 +#: flatcamTools/ToolInvertGerber.py:208 flatcamTools/ToolNCC.py:1603 +#: flatcamTools/ToolNCC.py:1644 flatcamTools/ToolNCC.py:1673 flatcamTools/ToolPaint.py:1462 +#: flatcamTools/ToolPanelize.py:413 flatcamTools/ToolPanelize.py:428 +#: flatcamTools/ToolSub.py:294 flatcamTools/ToolSub.py:307 flatcamTools/ToolSub.py:498 +#: flatcamTools/ToolSub.py:513 tclCommands/TclCommandCopperClear.py:97 +#: tclCommands/TclCommandPaint.py:99 msgid "Could not retrieve object" msgstr "" -#: flatcamTools/ToolCopperThieving.py:764 flatcamTools/ToolNonCopperClear.py:1205 +#: flatcamTools/ToolCopperThieving.py:770 flatcamTools/ToolNCC.py:1652 msgid "Click the start point of the area." msgstr "" -#: flatcamTools/ToolCopperThieving.py:815 +#: flatcamTools/ToolCopperThieving.py:821 msgid "Click the end point of the filling area." msgstr "" -#: flatcamTools/ToolCopperThieving.py:821 flatcamTools/ToolNonCopperClear.py:1261 -#: flatcamTools/ToolPaint.py:1201 +#: flatcamTools/ToolCopperThieving.py:827 flatcamTools/ToolNCC.py:1714 +#: flatcamTools/ToolNCC.py:1766 flatcamTools/ToolPaint.py:1594 +#: flatcamTools/ToolPaint.py:1645 msgid "Zone added. Click to start adding next zone or right click to finish." msgstr "" -#: flatcamTools/ToolCopperThieving.py:937 flatcamTools/ToolCopperThieving.py:941 -#: flatcamTools/ToolCopperThieving.py:1002 +#: flatcamTools/ToolCopperThieving.py:943 flatcamTools/ToolCopperThieving.py:947 +#: flatcamTools/ToolCopperThieving.py:1008 msgid "Thieving" msgstr "" -#: flatcamTools/ToolCopperThieving.py:948 +#: flatcamTools/ToolCopperThieving.py:954 msgid "Copper Thieving Tool started. Reading parameters." msgstr "" -#: flatcamTools/ToolCopperThieving.py:973 +#: flatcamTools/ToolCopperThieving.py:979 msgid "Copper Thieving Tool. Preparing isolation polygons." msgstr "" -#: flatcamTools/ToolCopperThieving.py:1018 +#: flatcamTools/ToolCopperThieving.py:1024 msgid "Copper Thieving Tool. Preparing areas to fill with copper." msgstr "" -#: flatcamTools/ToolCopperThieving.py:1029 flatcamTools/ToolOptimal.py:349 -#: flatcamTools/ToolPanelize.py:793 flatcamTools/ToolRulesCheck.py:1118 +#: flatcamTools/ToolCopperThieving.py:1035 flatcamTools/ToolOptimal.py:350 +#: flatcamTools/ToolPanelize.py:802 flatcamTools/ToolRulesCheck.py:1127 msgid "Working..." msgstr "" -#: flatcamTools/ToolCopperThieving.py:1056 +#: flatcamTools/ToolCopperThieving.py:1062 msgid "Geometry not supported for bounding box" msgstr "" -#: flatcamTools/ToolCopperThieving.py:1062 flatcamTools/ToolNonCopperClear.py:1513 -#: flatcamTools/ToolPaint.py:2673 +#: flatcamTools/ToolCopperThieving.py:1068 flatcamTools/ToolNCC.py:1933 +#: flatcamTools/ToolNCC.py:1988 flatcamTools/ToolNCC.py:2992 flatcamTools/ToolPaint.py:3854 msgid "No object available." msgstr "" -#: flatcamTools/ToolCopperThieving.py:1099 flatcamTools/ToolNonCopperClear.py:1555 +#: flatcamTools/ToolCopperThieving.py:1105 flatcamTools/ToolNCC.py:1958 +#: flatcamTools/ToolNCC.py:2011 flatcamTools/ToolNCC.py:3034 msgid "The reference object type is not supported." msgstr "" -#: flatcamTools/ToolCopperThieving.py:1104 +#: flatcamTools/ToolCopperThieving.py:1110 msgid "Copper Thieving Tool. Appending new geometry and buffering." msgstr "" -#: flatcamTools/ToolCopperThieving.py:1120 +#: flatcamTools/ToolCopperThieving.py:1126 msgid "Create geometry" msgstr "" -#: flatcamTools/ToolCopperThieving.py:1320 flatcamTools/ToolCopperThieving.py:1324 +#: flatcamTools/ToolCopperThieving.py:1326 flatcamTools/ToolCopperThieving.py:1330 msgid "P-Plating Mask" msgstr "" -#: flatcamTools/ToolCopperThieving.py:1346 +#: flatcamTools/ToolCopperThieving.py:1352 msgid "Append PP-M geometry" msgstr "" -#: flatcamTools/ToolCopperThieving.py:1472 +#: flatcamTools/ToolCopperThieving.py:1478 msgid "Generating Pattern Plating Mask done." msgstr "" -#: flatcamTools/ToolCopperThieving.py:1544 +#: flatcamTools/ToolCopperThieving.py:1550 msgid "Copper Thieving Tool exit." msgstr "" @@ -11685,7 +12290,19 @@ msgstr "" msgid "Cutout PCB" msgstr "" -#: flatcamTools/ToolCutOut.py:82 +#: flatcamTools/ToolCutOut.py:70 flatcamTools/ToolPanelize.py:54 +msgid "Source Object" +msgstr "" + +#: flatcamTools/ToolCutOut.py:71 +msgid "Object to be cutout" +msgstr "" + +#: flatcamTools/ToolCutOut.py:76 +msgid "Kind" +msgstr "" + +#: flatcamTools/ToolCutOut.py:98 msgid "" "Specify the type of object to be cutout.\n" "It can be of type: Gerber or Geometry.\n" @@ -11693,19 +12310,19 @@ msgid "" "of objects that will populate the 'Object' combobox." msgstr "" -#: flatcamTools/ToolCutOut.py:91 flatcamTools/ToolCutOut.py:92 -msgid "Object to be cutout" +#: flatcamTools/ToolCutOut.py:122 +msgid "Tool Parameters" msgstr "" -#: flatcamTools/ToolCutOut.py:230 +#: flatcamTools/ToolCutOut.py:239 msgid "A. Automatic Bridge Gaps" msgstr "" -#: flatcamTools/ToolCutOut.py:232 +#: flatcamTools/ToolCutOut.py:241 msgid "This section handle creation of automatic bridge gaps." msgstr "" -#: flatcamTools/ToolCutOut.py:243 +#: flatcamTools/ToolCutOut.py:252 msgid "" "Number of gaps used for the Automatic cutout.\n" "There can be maximum 8 bridges/gaps.\n" @@ -11719,22 +12336,22 @@ msgid "" "- 8 - 2*left + 2*right +2*top + 2*bottom" msgstr "" -#: flatcamTools/ToolCutOut.py:264 +#: flatcamTools/ToolCutOut.py:273 msgid "Generate Freeform Geometry" msgstr "" -#: flatcamTools/ToolCutOut.py:266 +#: flatcamTools/ToolCutOut.py:275 msgid "" "Cutout the selected object.\n" "The cutout shape can be of any shape.\n" "Useful when the PCB has a non-rectangular shape." msgstr "" -#: flatcamTools/ToolCutOut.py:278 +#: flatcamTools/ToolCutOut.py:287 msgid "Generate Rectangular Geometry" msgstr "" -#: flatcamTools/ToolCutOut.py:280 +#: flatcamTools/ToolCutOut.py:289 msgid "" "Cutout the selected object.\n" "The resulting cutout shape is\n" @@ -11742,26 +12359,26 @@ msgid "" "the bounding box of the Object." msgstr "" -#: flatcamTools/ToolCutOut.py:299 +#: flatcamTools/ToolCutOut.py:308 msgid "B. Manual Bridge Gaps" msgstr "" -#: flatcamTools/ToolCutOut.py:301 +#: flatcamTools/ToolCutOut.py:310 msgid "" "This section handle creation of manual bridge gaps.\n" "This is done by mouse clicking on the perimeter of the\n" "Geometry object that is used as a cutout object. " msgstr "" -#: flatcamTools/ToolCutOut.py:319 +#: flatcamTools/ToolCutOut.py:329 msgid "Geometry object used to create the manual cutout." msgstr "" -#: flatcamTools/ToolCutOut.py:328 +#: flatcamTools/ToolCutOut.py:338 msgid "Generate Manual Geometry" msgstr "" -#: flatcamTools/ToolCutOut.py:330 +#: flatcamTools/ToolCutOut.py:340 msgid "" "If the object to be cutout is a Gerber\n" "first create a Geometry that surrounds it,\n" @@ -11769,11 +12386,11 @@ msgid "" "Select the source Gerber file in the top object combobox." msgstr "" -#: flatcamTools/ToolCutOut.py:343 +#: flatcamTools/ToolCutOut.py:353 msgid "Manual Add Bridge Gaps" msgstr "" -#: flatcamTools/ToolCutOut.py:345 +#: flatcamTools/ToolCutOut.py:355 msgid "" "Use the left mouse button (LMB) click\n" "to create a bridge gap to separate the PCB from\n" @@ -11782,81 +12399,87 @@ msgid "" "the Geometry object used as a cutout geometry." msgstr "" -#: flatcamTools/ToolCutOut.py:473 +#: flatcamTools/ToolCutOut.py:485 msgid "" "There is no object selected for Cutout.\n" "Select one and try again." msgstr "" -#: flatcamTools/ToolCutOut.py:479 flatcamTools/ToolCutOut.py:651 -#: flatcamTools/ToolCutOut.py:795 flatcamTools/ToolCutOut.py:877 +#: flatcamTools/ToolCutOut.py:491 flatcamTools/ToolCutOut.py:676 +#: flatcamTools/ToolCutOut.py:839 flatcamTools/ToolCutOut.py:921 +#: tclCommands/TclCommandGeoCutout.py:185 msgid "Tool Diameter is zero value. Change it to a positive real number." msgstr "" -#: flatcamTools/ToolCutOut.py:493 flatcamTools/ToolCutOut.py:666 +#: flatcamTools/ToolCutOut.py:505 flatcamTools/ToolCutOut.py:691 msgid "Number of gaps value is missing. Add it and retry." msgstr "" -#: flatcamTools/ToolCutOut.py:498 flatcamTools/ToolCutOut.py:670 +#: flatcamTools/ToolCutOut.py:510 flatcamTools/ToolCutOut.py:695 msgid "" "Gaps value can be only one of: 'None', 'lr', 'tb', '2lr', '2tb', 4 or 8. Fill in a " "correct value and retry. " msgstr "" -#: flatcamTools/ToolCutOut.py:503 flatcamTools/ToolCutOut.py:676 +#: flatcamTools/ToolCutOut.py:515 flatcamTools/ToolCutOut.py:701 msgid "" "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." msgstr "" -#: flatcamTools/ToolCutOut.py:625 flatcamTools/ToolCutOut.py:784 +#: flatcamTools/ToolCutOut.py:650 flatcamTools/ToolCutOut.py:828 msgid "Any form CutOut operation finished." msgstr "" -#: flatcamTools/ToolCutOut.py:646 flatcamTools/ToolNonCopperClear.py:1155 -#: flatcamTools/ToolPaint.py:994 flatcamTools/ToolPanelize.py:406 -#: tclCommands/TclCommandBbox.py:70 tclCommands/TclCommandNregions.py:70 +#: flatcamTools/ToolCutOut.py:671 flatcamTools/ToolInvertGerber.py:214 +#: flatcamTools/ToolNCC.py:1607 flatcamTools/ToolPaint.py:1385 +#: flatcamTools/ToolPanelize.py:418 tclCommands/TclCommandBbox.py:72 +#: tclCommands/TclCommandNregions.py:72 msgid "Object not found" msgstr "" -#: flatcamTools/ToolCutOut.py:789 +#: flatcamTools/ToolCutOut.py:814 +msgid "Rectangular cutout with negative margin is not possible." +msgstr "" + +#: flatcamTools/ToolCutOut.py:833 msgid "Click on the selected geometry object perimeter to create a bridge gap ..." msgstr "" -#: flatcamTools/ToolCutOut.py:806 flatcamTools/ToolCutOut.py:832 +#: flatcamTools/ToolCutOut.py:850 flatcamTools/ToolCutOut.py:876 msgid "Could not retrieve Geometry object" msgstr "" -#: flatcamTools/ToolCutOut.py:837 +#: flatcamTools/ToolCutOut.py:881 msgid "Geometry object for manual cutout not found" msgstr "" -#: flatcamTools/ToolCutOut.py:847 +#: flatcamTools/ToolCutOut.py:891 msgid "Added manual Bridge Gap." msgstr "" -#: flatcamTools/ToolCutOut.py:859 +#: flatcamTools/ToolCutOut.py:903 msgid "Could not retrieve Gerber object" msgstr "" -#: flatcamTools/ToolCutOut.py:864 +#: flatcamTools/ToolCutOut.py:908 msgid "" "There is no Gerber object selected for Cutout.\n" "Select one and try again." msgstr "" -#: flatcamTools/ToolCutOut.py:870 +#: flatcamTools/ToolCutOut.py:914 msgid "" "The selected object has to be of Gerber type.\n" "Select a Gerber file and try again." msgstr "" -#: flatcamTools/ToolCutOut.py:905 +#: flatcamTools/ToolCutOut.py:949 msgid "Geometry not supported for cutout" msgstr "" -#: flatcamTools/ToolCutOut.py:960 +#: flatcamTools/ToolCutOut.py:1007 msgid "Making manual bridge gap..." msgstr "" @@ -11864,64 +12487,177 @@ msgstr "" msgid "2-Sided PCB" msgstr "" -#: flatcamTools/ToolDblSided.py:60 +#: flatcamTools/ToolDblSided.py:53 +msgid "Mirror Operation" +msgstr "" + +#: flatcamTools/ToolDblSided.py:54 +msgid "Objects to be mirrored" +msgstr "" + +#: flatcamTools/ToolDblSided.py:66 msgid "Gerber to be mirrored" msgstr "" -#: flatcamTools/ToolDblSided.py:64 flatcamTools/ToolDblSided.py:92 -#: flatcamTools/ToolDblSided.py:122 +#: flatcamTools/ToolDblSided.py:70 flatcamTools/ToolDblSided.py:98 +#: flatcamTools/ToolDblSided.py:128 msgid "" "Mirrors (flips) the specified object around \n" "the specified axis. Does not create a new \n" "object, but modifies it." msgstr "" -#: flatcamTools/ToolDblSided.py:88 +#: flatcamTools/ToolDblSided.py:94 msgid "Excellon Object to be mirrored." msgstr "" -#: flatcamTools/ToolDblSided.py:117 +#: flatcamTools/ToolDblSided.py:123 msgid "Geometry Obj to be mirrored." msgstr "" -#: flatcamTools/ToolDblSided.py:179 -msgid "Point/Box Reference" +#: flatcamTools/ToolDblSided.py:159 +msgid "Mirror Parameters" msgstr "" -#: flatcamTools/ToolDblSided.py:181 +#: flatcamTools/ToolDblSided.py:160 +msgid "Parameters for the mirror operation" +msgstr "" + +#: flatcamTools/ToolDblSided.py:165 +msgid "Mirror Axis" +msgstr "" + +#: flatcamTools/ToolDblSided.py:176 msgid "" -"If 'Point' is selected above it store the coordinates (x, y) through which\n" -"the mirroring axis passes.\n" -"If 'Box' is selected above, select here a FlatCAM object (Gerber, Exc or Geo).\n" -"Through the center of this object pass the mirroring axis selected above." +"The coordinates used as reference for the mirror operation.\n" +"Can be:\n" +"- Point -> a set of coordinates (x,y) around which the object is mirrored\n" +"- Box -> a set of coordinates (x, y) obtained from the center of the\n" +"bounding box of another object selected below" msgstr "" -#: flatcamTools/ToolDblSided.py:189 +#: flatcamTools/ToolDblSided.py:190 +msgid "Point coordinates" +msgstr "" + +#: flatcamTools/ToolDblSided.py:195 msgid "" "Add the coordinates in format (x, y) through which the mirroring axis \n" " selected in 'MIRROR AXIS' pass.\n" "The (x, y) coordinates are captured by pressing SHIFT key\n" -"and left mouse button click on canvas or you can enter the coords manually." +"and left mouse button click on canvas or you can enter the coordinates manually." msgstr "" -#: flatcamTools/ToolDblSided.py:230 +#: flatcamTools/ToolDblSided.py:219 +msgid "" +"It can be of type: Gerber or Excellon or Geometry.\n" +"The coordinates of the center of the bounding box are used\n" +"as reference for mirror operation." +msgstr "" + +#: flatcamTools/ToolDblSided.py:253 +msgid "Bounds Values" +msgstr "" + +#: flatcamTools/ToolDblSided.py:255 +msgid "" +"Select on canvas the object(s)\n" +"for which to calculate bounds values." +msgstr "" + +#: flatcamTools/ToolDblSided.py:265 +msgid "X min" +msgstr "" + +#: flatcamTools/ToolDblSided.py:267 flatcamTools/ToolDblSided.py:281 +msgid "Minimum location." +msgstr "" + +#: flatcamTools/ToolDblSided.py:279 +msgid "Y min" +msgstr "" + +#: flatcamTools/ToolDblSided.py:293 +msgid "X max" +msgstr "" + +#: flatcamTools/ToolDblSided.py:295 flatcamTools/ToolDblSided.py:309 +msgid "Maximum location." +msgstr "" + +#: flatcamTools/ToolDblSided.py:307 +msgid "Y max" +msgstr "" + +#: flatcamTools/ToolDblSided.py:318 +msgid "Center point coordinates" +msgstr "" + +#: flatcamTools/ToolDblSided.py:320 +msgid "Centroid" +msgstr "" + +#: flatcamTools/ToolDblSided.py:322 +msgid "" +"The center point location for the rectangular\n" +"bounding shape. Centroid. Format is (x, y)." +msgstr "" + +#: flatcamTools/ToolDblSided.py:331 +msgid "Calculate Bounds Values" +msgstr "" + +#: flatcamTools/ToolDblSided.py:333 +msgid "" +"Calculate the enveloping rectangular shape coordinates,\n" +"for the selection of objects.\n" +"The envelope shape is parallel with the X, Y axis." +msgstr "" + +#: flatcamTools/ToolDblSided.py:353 +msgid "PCB Alignment" +msgstr "" + +#: flatcamTools/ToolDblSided.py:355 flatcamTools/ToolDblSided.py:457 +msgid "" +"Creates an Excellon Object containing the\n" +"specified alignment holes and their mirror\n" +"images." +msgstr "" + +#: flatcamTools/ToolDblSided.py:362 +msgid "Drill Diameter" +msgstr "" + +#: flatcamTools/ToolDblSided.py:391 flatcamTools/ToolDblSided.py:398 +msgid "" +"The reference point used to create the second alignment drill\n" +"from the first alignment drill, by doing mirror.\n" +"It can be modified in the Mirror Parameters -> Reference section" +msgstr "" + +#: flatcamTools/ToolDblSided.py:411 msgid "Alignment Drill Coordinates" msgstr "" -#: flatcamTools/ToolDblSided.py:232 +#: flatcamTools/ToolDblSided.py:413 msgid "" "Alignment holes (x1, y1), (x2, y2), ... on one side of the mirror axis. For each set of " "(x, y) coordinates\n" "entered here, a pair of drills will be created:\n" "\n" "- one drill at the coordinates from the field\n" -"- one drill in mirror position over the axis selected above in the 'Mirror Axis'." +"- one drill in mirror position over the axis selected above in the 'Align Axis'." msgstr "" -#: flatcamTools/ToolDblSided.py:247 +#: flatcamTools/ToolDblSided.py:421 +msgid "Drill coordinates" +msgstr "" + +#: flatcamTools/ToolDblSided.py:428 msgid "" -"Add alignment drill holes coords in the format: (x1, y1), (x2, y2), ... \n" -"on one side of the mirror axis.\n" +"Add alignment drill holes coordinates in the format: (x1, y1), (x2, y2), ... \n" +"on one side of the alignment axis.\n" "\n" "The coordinates set can be obtained:\n" "- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" @@ -11931,258 +12667,246 @@ msgid "" "- by entering the coords manually in the format: (x1, y1), (x2, y2), ..." msgstr "" -#: flatcamTools/ToolDblSided.py:272 -msgid "Alignment Drill Diameter" +#: flatcamTools/ToolDblSided.py:443 +msgid "Delete Last" msgstr "" -#: flatcamTools/ToolDblSided.py:292 +#: flatcamTools/ToolDblSided.py:445 +msgid "Delete the last coordinates tuple in the list." +msgstr "" + +#: flatcamTools/ToolDblSided.py:455 msgid "Create Excellon Object" msgstr "" -#: flatcamTools/ToolDblSided.py:294 -msgid "" -"Creates an Excellon Object containing the\n" -"specified alignment holes and their mirror\n" -"images." -msgstr "" - -#: flatcamTools/ToolDblSided.py:323 -msgid "X min" -msgstr "" - -#: flatcamTools/ToolDblSided.py:325 flatcamTools/ToolDblSided.py:339 -msgid "Minimum location." -msgstr "" - -#: flatcamTools/ToolDblSided.py:337 -msgid "Y min" -msgstr "" - -#: flatcamTools/ToolDblSided.py:351 -msgid "X max" -msgstr "" - -#: flatcamTools/ToolDblSided.py:353 flatcamTools/ToolDblSided.py:367 -msgid "Maximum location." -msgstr "" - -#: flatcamTools/ToolDblSided.py:365 -msgid "Y max" -msgstr "" - -#: flatcamTools/ToolDblSided.py:377 -msgid "Centroid" -msgstr "" - -#: flatcamTools/ToolDblSided.py:379 -msgid "" -"The center point location for the rectangular\n" -"bounding shape. Centroid. Format is (x, y)." -msgstr "" - -#: flatcamTools/ToolDblSided.py:388 -msgid "Calculate Bounds Values" -msgstr "" - -#: flatcamTools/ToolDblSided.py:390 -msgid "" -"Calculate the enveloping rectangular shape coordinates,\n" -"for the selection of objects.\n" -"The envelope shape is parallel with the X, Y axis." -msgstr "" - -#: flatcamTools/ToolDblSided.py:462 +#: flatcamTools/ToolDblSided.py:542 msgid "2-Sided Tool" msgstr "" -#: flatcamTools/ToolDblSided.py:493 +#: flatcamTools/ToolDblSided.py:582 msgid "" "'Point' reference is selected and 'Point' coordinates are missing. Add them and retry." msgstr "" -#: flatcamTools/ToolDblSided.py:512 +#: flatcamTools/ToolDblSided.py:601 msgid "There is no Box reference object loaded. Load one and retry." msgstr "" -#: flatcamTools/ToolDblSided.py:524 +#: flatcamTools/ToolDblSided.py:613 msgid "No value or wrong format in Drill Dia entry. Add it and retry." msgstr "" -#: flatcamTools/ToolDblSided.py:532 +#: flatcamTools/ToolDblSided.py:624 msgid "There are no Alignment Drill Coordinates to use. Add them and retry." msgstr "" -#: flatcamTools/ToolDblSided.py:555 +#: flatcamTools/ToolDblSided.py:649 msgid "Excellon object with alignment drills created..." msgstr "" -#: flatcamTools/ToolDblSided.py:568 flatcamTools/ToolDblSided.py:611 -#: flatcamTools/ToolDblSided.py:655 +#: flatcamTools/ToolDblSided.py:662 flatcamTools/ToolDblSided.py:705 +#: flatcamTools/ToolDblSided.py:749 msgid "Only Gerber, Excellon and Geometry objects can be mirrored." msgstr "" -#: flatcamTools/ToolDblSided.py:578 -msgid "'Point' coordinates missing. Using Origin (0, 0) as mirroring reference." -msgstr "" - -#: flatcamTools/ToolDblSided.py:588 flatcamTools/ToolDblSided.py:632 -#: flatcamTools/ToolDblSided.py:669 -msgid "There is no Box object loaded ..." -msgstr "" - -#: flatcamTools/ToolDblSided.py:598 flatcamTools/ToolDblSided.py:642 -#: flatcamTools/ToolDblSided.py:679 -msgid "was mirrored" -msgstr "" - -#: flatcamTools/ToolDblSided.py:607 -msgid "There is no Excellon object loaded ..." -msgstr "" - -#: flatcamTools/ToolDblSided.py:622 +#: flatcamTools/ToolDblSided.py:672 flatcamTools/ToolDblSided.py:716 msgid "There are no Point coordinates in the Point field. Add coords and try again ..." msgstr "" -#: flatcamTools/ToolDblSided.py:651 +#: flatcamTools/ToolDblSided.py:682 flatcamTools/ToolDblSided.py:726 +#: flatcamTools/ToolDblSided.py:763 +msgid "There is no Box object loaded ..." +msgstr "" + +#: flatcamTools/ToolDblSided.py:692 flatcamTools/ToolDblSided.py:736 +#: flatcamTools/ToolDblSided.py:773 +msgid "was mirrored" +msgstr "" + +#: flatcamTools/ToolDblSided.py:701 flatcamTools/ToolPunchGerber.py:533 +msgid "There is no Excellon object loaded ..." +msgstr "" + +#: flatcamTools/ToolDblSided.py:745 msgid "There is no Geometry object loaded ..." msgstr "" -#: flatcamTools/ToolDistance.py:50 flatcamTools/ToolDistanceMin.py:50 +#: flatcamTools/ToolDistance.py:57 flatcamTools/ToolDistanceMin.py:51 msgid "Those are the units in which the distance is measured." msgstr "" -#: flatcamTools/ToolDistance.py:51 flatcamTools/ToolDistanceMin.py:51 +#: flatcamTools/ToolDistance.py:58 flatcamTools/ToolDistanceMin.py:52 msgid "METRIC (mm)" msgstr "" -#: flatcamTools/ToolDistance.py:51 flatcamTools/ToolDistanceMin.py:51 +#: flatcamTools/ToolDistance.py:58 flatcamTools/ToolDistanceMin.py:52 msgid "INCH (in)" msgstr "" -#: flatcamTools/ToolDistance.py:54 +#: flatcamTools/ToolDistance.py:64 +msgid "Snap to center" +msgstr "" + +#: flatcamTools/ToolDistance.py:66 +msgid "" +"Mouse cursor will snap to the center of the pad/drill\n" +"when it is hovering over the geometry of the pad/drill." +msgstr "" + +#: flatcamTools/ToolDistance.py:76 msgid "Start Coords" msgstr "" -#: flatcamTools/ToolDistance.py:55 flatcamTools/ToolDistance.py:75 +#: flatcamTools/ToolDistance.py:77 flatcamTools/ToolDistance.py:82 msgid "This is measuring Start point coordinates." msgstr "" -#: flatcamTools/ToolDistance.py:57 +#: flatcamTools/ToolDistance.py:87 msgid "Stop Coords" msgstr "" -#: flatcamTools/ToolDistance.py:58 flatcamTools/ToolDistance.py:80 +#: flatcamTools/ToolDistance.py:88 flatcamTools/ToolDistance.py:93 msgid "This is the measuring Stop point coordinates." msgstr "" -#: flatcamTools/ToolDistance.py:60 flatcamTools/ToolDistanceMin.py:62 +#: flatcamTools/ToolDistance.py:98 flatcamTools/ToolDistanceMin.py:63 msgid "Dx" msgstr "" -#: flatcamTools/ToolDistance.py:61 flatcamTools/ToolDistance.py:85 -#: flatcamTools/ToolDistanceMin.py:63 flatcamTools/ToolDistanceMin.py:92 +#: flatcamTools/ToolDistance.py:99 flatcamTools/ToolDistance.py:104 +#: flatcamTools/ToolDistanceMin.py:64 flatcamTools/ToolDistanceMin.py:93 msgid "This is the distance measured over the X axis." msgstr "" -#: flatcamTools/ToolDistance.py:63 flatcamTools/ToolDistanceMin.py:65 +#: flatcamTools/ToolDistance.py:109 flatcamTools/ToolDistanceMin.py:66 msgid "Dy" msgstr "" -#: flatcamTools/ToolDistance.py:64 flatcamTools/ToolDistance.py:90 -#: flatcamTools/ToolDistanceMin.py:66 flatcamTools/ToolDistanceMin.py:97 +#: flatcamTools/ToolDistance.py:110 flatcamTools/ToolDistance.py:115 +#: flatcamTools/ToolDistanceMin.py:67 flatcamTools/ToolDistanceMin.py:98 msgid "This is the distance measured over the Y axis." msgstr "" -#: flatcamTools/ToolDistance.py:67 flatcamTools/ToolDistance.py:95 -#: flatcamTools/ToolDistanceMin.py:69 flatcamTools/ToolDistanceMin.py:102 +#: flatcamTools/ToolDistance.py:121 flatcamTools/ToolDistance.py:126 +#: flatcamTools/ToolDistanceMin.py:70 flatcamTools/ToolDistanceMin.py:103 msgid "This is orientation angle of the measuring line." msgstr "" -#: flatcamTools/ToolDistance.py:69 flatcamTools/ToolDistanceMin.py:71 +#: flatcamTools/ToolDistance.py:131 flatcamTools/ToolDistanceMin.py:72 msgid "DISTANCE" msgstr "" -#: flatcamTools/ToolDistance.py:70 flatcamTools/ToolDistance.py:100 +#: flatcamTools/ToolDistance.py:132 flatcamTools/ToolDistance.py:137 msgid "This is the point to point Euclidian distance." msgstr "" -#: flatcamTools/ToolDistance.py:102 flatcamTools/ToolDistanceMin.py:114 +#: flatcamTools/ToolDistance.py:142 flatcamTools/ToolDistance.py:337 +#: flatcamTools/ToolDistanceMin.py:115 msgid "Measure" msgstr "" -#: flatcamTools/ToolDistance.py:212 +#: flatcamTools/ToolDistance.py:272 +msgid "Working" +msgstr "" + +#: flatcamTools/ToolDistance.py:277 msgid "MEASURING: Click on the Start point ..." msgstr "" -#: flatcamTools/ToolDistance.py:345 +#: flatcamTools/ToolDistance.py:387 +msgid "Distance Tool finished." +msgstr "" + +#: flatcamTools/ToolDistance.py:455 +msgid "Pads overlapped. Aborting." +msgstr "" + +#: flatcamTools/ToolDistance.py:485 msgid "MEASURING: Click on the Destination point ..." msgstr "" -#: flatcamTools/ToolDistance.py:353 flatcamTools/ToolDistanceMin.py:282 +#: flatcamTools/ToolDistance.py:494 flatcamTools/ToolDistanceMin.py:285 msgid "MEASURING" msgstr "" -#: flatcamTools/ToolDistance.py:354 flatcamTools/ToolDistanceMin.py:283 +#: flatcamTools/ToolDistance.py:495 flatcamTools/ToolDistanceMin.py:286 msgid "Result" msgstr "" -#: flatcamTools/ToolDistanceMin.py:31 flatcamTools/ToolDistanceMin.py:152 +#: flatcamTools/ToolDistanceMin.py:32 flatcamTools/ToolDistanceMin.py:144 msgid "Minimum Distance Tool" msgstr "" -#: flatcamTools/ToolDistanceMin.py:54 +#: flatcamTools/ToolDistanceMin.py:55 msgid "First object point" msgstr "" -#: flatcamTools/ToolDistanceMin.py:55 flatcamTools/ToolDistanceMin.py:80 +#: flatcamTools/ToolDistanceMin.py:56 flatcamTools/ToolDistanceMin.py:81 msgid "" "This is first object point coordinates.\n" "This is the start point for measuring distance." msgstr "" -#: flatcamTools/ToolDistanceMin.py:58 +#: flatcamTools/ToolDistanceMin.py:59 msgid "Second object point" msgstr "" -#: flatcamTools/ToolDistanceMin.py:59 flatcamTools/ToolDistanceMin.py:86 +#: flatcamTools/ToolDistanceMin.py:60 flatcamTools/ToolDistanceMin.py:87 msgid "" "This is second object point coordinates.\n" "This is the end point for measuring distance." msgstr "" -#: flatcamTools/ToolDistanceMin.py:72 flatcamTools/ToolDistanceMin.py:107 +#: flatcamTools/ToolDistanceMin.py:73 flatcamTools/ToolDistanceMin.py:108 msgid "This is the point to point Euclidean distance." msgstr "" -#: flatcamTools/ToolDistanceMin.py:74 +#: flatcamTools/ToolDistanceMin.py:75 msgid "Half Point" msgstr "" -#: flatcamTools/ToolDistanceMin.py:75 flatcamTools/ToolDistanceMin.py:112 +#: flatcamTools/ToolDistanceMin.py:76 flatcamTools/ToolDistanceMin.py:113 msgid "This is the middle point of the point to point Euclidean distance." msgstr "" -#: flatcamTools/ToolDistanceMin.py:117 +#: flatcamTools/ToolDistanceMin.py:118 msgid "Jump to Half Point" msgstr "" -#: flatcamTools/ToolDistanceMin.py:163 +#: flatcamTools/ToolDistanceMin.py:155 msgid "Select two objects and no more, to measure the distance between them ..." msgstr "" -#: flatcamTools/ToolDistanceMin.py:204 flatcamTools/ToolDistanceMin.py:214 -#: flatcamTools/ToolDistanceMin.py:223 flatcamTools/ToolDistanceMin.py:244 +#: flatcamTools/ToolDistanceMin.py:196 flatcamTools/ToolDistanceMin.py:217 +#: flatcamTools/ToolDistanceMin.py:226 flatcamTools/ToolDistanceMin.py:247 msgid "Select two objects and no more. Currently the selection has objects: " msgstr "" -#: flatcamTools/ToolDistanceMin.py:291 +#: flatcamTools/ToolDistanceMin.py:294 msgid "Objects intersects or touch at" msgstr "" -#: flatcamTools/ToolDistanceMin.py:297 +#: flatcamTools/ToolDistanceMin.py:300 msgid "Jumped to the half point between the two selected objects" msgstr "" +#: flatcamTools/ToolExtractDrills.py:29 flatcamTools/ToolExtractDrills.py:295 +msgid "Extract Drills" +msgstr "" + +#: flatcamTools/ToolExtractDrills.py:62 +msgid "Gerber from which to extract drill holes" +msgstr "" + +#: flatcamTools/ToolExtractDrills.py:297 +msgid "Extract drills from a given Gerber file." +msgstr "" + +#: flatcamTools/ToolExtractDrills.py:478 flatcamTools/ToolExtractDrills.py:563 +#: flatcamTools/ToolExtractDrills.py:648 +msgid "No drills extracted. Try different parameters." +msgstr "" + #: flatcamTools/ToolFiducials.py:56 msgid "Fiducials Coordinates" msgstr "" @@ -12197,41 +12921,37 @@ msgstr "" msgid "Top Right" msgstr "" -#: flatcamTools/ToolFiducials.py:111 -msgid "Second Point" -msgstr "" - #: flatcamTools/ToolFiducials.py:191 msgid "" "- 'Auto' - automatic placement of fiducials in the corners of the bounding box.\n" " - 'Manual' - manual placement of fiducials." msgstr "" -#: flatcamTools/ToolFiducials.py:258 +#: flatcamTools/ToolFiducials.py:259 msgid "Copper Gerber" msgstr "" -#: flatcamTools/ToolFiducials.py:267 +#: flatcamTools/ToolFiducials.py:268 msgid "Add Fiducial" msgstr "" -#: flatcamTools/ToolFiducials.py:269 +#: flatcamTools/ToolFiducials.py:270 msgid "Will add a polygon on the copper layer to serve as fiducial." msgstr "" -#: flatcamTools/ToolFiducials.py:285 +#: flatcamTools/ToolFiducials.py:286 msgid "Soldermask Gerber" msgstr "" -#: flatcamTools/ToolFiducials.py:287 +#: flatcamTools/ToolFiducials.py:288 msgid "The Soldermask Gerber object." msgstr "" -#: flatcamTools/ToolFiducials.py:298 +#: flatcamTools/ToolFiducials.py:300 msgid "Add Soldermask Opening" msgstr "" -#: flatcamTools/ToolFiducials.py:300 +#: flatcamTools/ToolFiducials.py:302 msgid "" "Will add a polygon on the soldermask layer\n" "to serve as fiducial opening.\n" @@ -12239,23 +12959,23 @@ msgid "" "for the copper fiducial." msgstr "" -#: flatcamTools/ToolFiducials.py:514 +#: flatcamTools/ToolFiducials.py:516 msgid "Click to add first Fiducial. Bottom Left..." msgstr "" -#: flatcamTools/ToolFiducials.py:778 +#: flatcamTools/ToolFiducials.py:780 msgid "Click to add the last fiducial. Top Right..." msgstr "" -#: flatcamTools/ToolFiducials.py:783 +#: flatcamTools/ToolFiducials.py:785 msgid "Click to add the second fiducial. Top Left or Bottom Right..." msgstr "" -#: flatcamTools/ToolFiducials.py:786 flatcamTools/ToolFiducials.py:795 +#: flatcamTools/ToolFiducials.py:788 flatcamTools/ToolFiducials.py:797 msgid "Done. All fiducials have been added." msgstr "" -#: flatcamTools/ToolFiducials.py:872 +#: flatcamTools/ToolFiducials.py:874 msgid "Fiducials Tool exit." msgstr "" @@ -12263,7 +12983,7 @@ msgstr "" msgid "Film PCB" msgstr "" -#: flatcamTools/ToolFilm.py:80 +#: flatcamTools/ToolFilm.py:78 msgid "" "Specify the type of object for which to create the film.\n" "The object can be of type: Gerber or Geometry.\n" @@ -12271,11 +12991,11 @@ msgid "" "in the Film Object combobox." msgstr "" -#: flatcamTools/ToolFilm.py:94 +#: flatcamTools/ToolFilm.py:92 msgid "Film Object" msgstr "" -#: flatcamTools/ToolFilm.py:96 +#: flatcamTools/ToolFilm.py:94 msgid "Object for which to create the film." msgstr "" @@ -12287,7 +13007,7 @@ msgid "" "in the Box Object combobox." msgstr "" -#: flatcamTools/ToolFilm.py:129 flatcamTools/ToolPanelize.py:136 +#: flatcamTools/ToolFilm.py:129 msgid "Box Object" msgstr "" @@ -12337,19 +13057,19 @@ msgstr "" msgid "Remove the geometry of Excellon from the Film to create the holes in pads." msgstr "" -#: flatcamTools/ToolFilm.py:379 +#: flatcamTools/ToolFilm.py:381 msgid "Punch Size" msgstr "" -#: flatcamTools/ToolFilm.py:380 +#: flatcamTools/ToolFilm.py:382 msgid "The value here will control how big is the punch hole in the pads." msgstr "" -#: flatcamTools/ToolFilm.py:500 +#: flatcamTools/ToolFilm.py:502 msgid "Save Film" msgstr "" -#: flatcamTools/ToolFilm.py:502 +#: flatcamTools/ToolFilm.py:504 msgid "" "Create a Film for the selected object, within\n" "the specified box. Does not create a new \n" @@ -12357,75 +13077,67 @@ msgid "" "selected format." msgstr "" -#: flatcamTools/ToolFilm.py:652 +#: flatcamTools/ToolFilm.py:664 msgid "" "Using the Pad center does not work on Geometry objects. Only a Gerber object has pads." msgstr "" -#: flatcamTools/ToolFilm.py:662 +#: flatcamTools/ToolFilm.py:674 msgid "No FlatCAM object selected. Load an object for Film and retry." msgstr "" -#: flatcamTools/ToolFilm.py:669 +#: flatcamTools/ToolFilm.py:681 msgid "No FlatCAM object selected. Load an object for Box and retry." msgstr "" -#: flatcamTools/ToolFilm.py:673 +#: flatcamTools/ToolFilm.py:685 msgid "No FlatCAM object selected." msgstr "" -#: flatcamTools/ToolFilm.py:684 +#: flatcamTools/ToolFilm.py:696 msgid "Generating Film ..." msgstr "" -#: flatcamTools/ToolFilm.py:733 flatcamTools/ToolFilm.py:737 +#: flatcamTools/ToolFilm.py:745 flatcamTools/ToolFilm.py:749 msgid "Export positive film" msgstr "" -#: flatcamTools/ToolFilm.py:742 -msgid "Export positive film cancelled." -msgstr "" - -#: flatcamTools/ToolFilm.py:770 +#: flatcamTools/ToolFilm.py:782 msgid "No Excellon object selected. Load an object for punching reference and retry." msgstr "" -#: flatcamTools/ToolFilm.py:794 +#: flatcamTools/ToolFilm.py:806 msgid "" " Could not generate punched hole film because the punch hole sizeis bigger than some of " "the apertures in the Gerber object." msgstr "" -#: flatcamTools/ToolFilm.py:806 +#: flatcamTools/ToolFilm.py:818 msgid "" "Could not generate punched hole film because the punch hole sizeis bigger than some of " "the apertures in the Gerber object." msgstr "" -#: flatcamTools/ToolFilm.py:824 +#: flatcamTools/ToolFilm.py:836 msgid "" "Could not generate punched hole film because the newly created object geometry is the " "same as the one in the source object geometry..." msgstr "" -#: flatcamTools/ToolFilm.py:879 flatcamTools/ToolFilm.py:883 +#: flatcamTools/ToolFilm.py:891 flatcamTools/ToolFilm.py:895 msgid "Export negative film" msgstr "" -#: flatcamTools/ToolFilm.py:888 -msgid "Export negative film cancelled." -msgstr "" - -#: flatcamTools/ToolFilm.py:944 flatcamTools/ToolFilm.py:1122 -#: flatcamTools/ToolPanelize.py:421 +#: flatcamTools/ToolFilm.py:956 flatcamTools/ToolFilm.py:1139 +#: flatcamTools/ToolPanelize.py:433 msgid "No object Box. Using instead" msgstr "" -#: flatcamTools/ToolFilm.py:1060 flatcamTools/ToolFilm.py:1235 +#: flatcamTools/ToolFilm.py:1072 flatcamTools/ToolFilm.py:1252 msgid "Film file exported to" msgstr "" -#: flatcamTools/ToolFilm.py:1063 flatcamTools/ToolFilm.py:1238 +#: flatcamTools/ToolFilm.py:1075 flatcamTools/ToolFilm.py:1255 msgid "Generating Film ... Please wait." msgstr "" @@ -12437,40 +13149,40 @@ msgstr "" msgid "Image to PCB" msgstr "" -#: flatcamTools/ToolImage.py:57 +#: flatcamTools/ToolImage.py:56 msgid "" "Specify the type of object to create from the image.\n" "It can be of type: Gerber or Geometry." msgstr "" -#: flatcamTools/ToolImage.py:66 +#: flatcamTools/ToolImage.py:65 msgid "DPI value" msgstr "" -#: flatcamTools/ToolImage.py:67 +#: flatcamTools/ToolImage.py:66 msgid "Specify a DPI value for the image." msgstr "" -#: flatcamTools/ToolImage.py:73 +#: flatcamTools/ToolImage.py:72 msgid "Level of detail" msgstr "" -#: flatcamTools/ToolImage.py:82 +#: flatcamTools/ToolImage.py:81 msgid "Image type" msgstr "" -#: flatcamTools/ToolImage.py:84 +#: flatcamTools/ToolImage.py:83 msgid "" "Choose a method for the image interpretation.\n" "B/W means a black & white image. Color means a colored image." msgstr "" -#: flatcamTools/ToolImage.py:93 flatcamTools/ToolImage.py:108 flatcamTools/ToolImage.py:121 -#: flatcamTools/ToolImage.py:134 +#: flatcamTools/ToolImage.py:92 flatcamTools/ToolImage.py:107 flatcamTools/ToolImage.py:120 +#: flatcamTools/ToolImage.py:133 msgid "Mask value" msgstr "" -#: flatcamTools/ToolImage.py:95 +#: flatcamTools/ToolImage.py:94 msgid "" "Mask for monochrome image.\n" "Takes values between [0 ... 255].\n" @@ -12480,7 +13192,7 @@ msgid "" "(which is totally black)." msgstr "" -#: flatcamTools/ToolImage.py:110 +#: flatcamTools/ToolImage.py:109 msgid "" "Mask for RED color.\n" "Takes values between [0 ... 255].\n" @@ -12488,7 +13200,7 @@ msgid "" "in the resulting geometry." msgstr "" -#: flatcamTools/ToolImage.py:123 +#: flatcamTools/ToolImage.py:122 msgid "" "Mask for GREEN color.\n" "Takes values between [0 ... 255].\n" @@ -12496,7 +13208,7 @@ msgid "" "in the resulting geometry." msgstr "" -#: flatcamTools/ToolImage.py:136 +#: flatcamTools/ToolImage.py:135 msgid "" "Mask for BLUE color.\n" "Takes values between [0 ... 255].\n" @@ -12504,32 +13216,55 @@ msgid "" "in the resulting geometry." msgstr "" -#: flatcamTools/ToolImage.py:144 +#: flatcamTools/ToolImage.py:143 msgid "Import image" msgstr "" -#: flatcamTools/ToolImage.py:146 +#: flatcamTools/ToolImage.py:145 msgid "Open a image of raster type and then import it in FlatCAM." msgstr "" -#: flatcamTools/ToolImage.py:183 +#: flatcamTools/ToolImage.py:182 msgid "Image Tool" msgstr "" -#: flatcamTools/ToolImage.py:235 flatcamTools/ToolImage.py:238 +#: flatcamTools/ToolImage.py:234 flatcamTools/ToolImage.py:237 msgid "Import IMAGE" msgstr "" -#: flatcamTools/ToolImage.py:286 +#: flatcamTools/ToolImage.py:285 msgid "Importing Image" msgstr "" +#: flatcamTools/ToolInvertGerber.py:74 +msgid "Gerber object that will be inverted." +msgstr "" + +#: flatcamTools/ToolInvertGerber.py:83 +msgid "Parameters for this tool" +msgstr "" + +#: flatcamTools/ToolInvertGerber.py:123 +msgid "Invert Gerber" +msgstr "" + +#: flatcamTools/ToolInvertGerber.py:125 +msgid "" +"Will invert the Gerber object: areas that have copper\n" +"will be empty of copper and previous empty area will be\n" +"filled with copper." +msgstr "" + +#: flatcamTools/ToolInvertGerber.py:184 +msgid "Invert Tool" +msgstr "" + #: flatcamTools/ToolMove.py:103 msgid "MOVE: Click on the Start point ..." msgstr "" #: flatcamTools/ToolMove.py:114 -msgid "MOVE action cancelled. No object(s) to move." +msgid "Cancelled. No object(s) to move." msgstr "" #: flatcamTools/ToolMove.py:141 @@ -12544,19 +13279,15 @@ msgstr "" msgid "No object(s) selected." msgstr "" -#: flatcamTools/ToolMove.py:212 +#: flatcamTools/ToolMove.py:222 msgid "Error when mouse left click." msgstr "" -#: flatcamTools/ToolMove.py:260 -msgid "Move action cancelled." -msgstr "" - -#: flatcamTools/ToolNonCopperClear.py:38 +#: flatcamTools/ToolNCC.py:42 msgid "Non-Copper Clearing" msgstr "" -#: flatcamTools/ToolNonCopperClear.py:84 +#: flatcamTools/ToolNCC.py:88 msgid "" "Specify the type of object to be cleared of excess copper.\n" "It can be of type: Gerber or Geometry.\n" @@ -12564,21 +13295,17 @@ msgid "" "of objects that will populate the 'Object' combobox." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:101 +#: flatcamTools/ToolNCC.py:110 msgid "Object to be cleared of excess copper." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:111 +#: flatcamTools/ToolNCC.py:122 msgid "" "Tools pool from which the algorithm\n" "will pick the ones used for copper clearing." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:120 -msgid "Operation" -msgstr "" - -#: flatcamTools/ToolNonCopperClear.py:126 +#: flatcamTools/ToolNCC.py:138 msgid "" "This is the Tool Number.\n" "Non copper clearing will start with the tool with the biggest \n" @@ -12588,13 +13315,13 @@ msgid "" "this function will not be able to create painting geometry." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:134 +#: flatcamTools/ToolNCC.py:146 msgid "" "Tool Diameter. It's value (in current FlatCAM units)\n" "is the cut width into the material." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:138 +#: flatcamTools/ToolNCC.py:150 msgid "" "The Tool Type (TT) can be:\n" "- Circular with 1 ... 4 teeth -> it is informative only. Being circular,\n" @@ -12609,298 +13336,281 @@ msgid "" "in the resulting geometry as Isolation." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:151 -msgid "" -"The 'Operation' can be:\n" -"- Isolation -> will ensure that the non-copper clearing is always complete.\n" -"If it's not successful then the non-copper clearing will fail, too.\n" -"- Clear -> the regular non-copper clearing." -msgstr "" - -#: flatcamTools/ToolNonCopperClear.py:209 -msgid "Tool Selection" -msgstr "" - -#: flatcamTools/ToolNonCopperClear.py:273 -msgid "" -"Diameter for the new tool to add in the Tool Table.\n" -"If the tool is V-shape type then this value is automatically\n" -"calculated from the other parameters." -msgstr "" - -#: flatcamTools/ToolNonCopperClear.py:288 flatcamTools/ToolPaint.py:190 +#: flatcamTools/ToolNCC.py:296 flatcamTools/ToolPaint.py:279 msgid "" "Add a new tool to the Tool Table\n" "with the diameter specified above." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:300 flatcamTools/ToolPaint.py:202 -#: flatcamTools/ToolSolderPaste.py:129 +#: flatcamTools/ToolNCC.py:318 flatcamTools/ToolPaint.py:301 +#: flatcamTools/ToolSolderPaste.py:131 msgid "" "Delete a selection of tools in the Tool Table\n" "by first selecting a row(s) in the Tool Table." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:435 -msgid "" -"- 'Itself' - the non copper clearing extent is based on the object that is copper " -"cleared.\n" -" - 'Area Selection' - left mouse click to start selection of the area to be painted.\n" -"- 'Reference Object' - will do non copper clearing within the area specified by another " -"object." -msgstr "" - -#: flatcamTools/ToolNonCopperClear.py:447 +#: flatcamTools/ToolNCC.py:554 msgid "" "The type of FlatCAM object to be used as non copper clearing reference.\n" "It can be Gerber, Excellon or Geometry." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:471 +#: flatcamTools/ToolNCC.py:597 flatcamTools/ToolPaint.py:537 msgid "Generate Geometry" msgstr "" -#: flatcamTools/ToolNonCopperClear.py:582 flatcamTools/ToolPaint.py:493 -#: flatcamTools/ToolSolderPaste.py:553 -msgid "New Tool" -msgstr "" - -#: flatcamTools/ToolNonCopperClear.py:981 flatcamTools/ToolPaint.py:766 -#: flatcamTools/ToolSolderPaste.py:887 +#: flatcamTools/ToolNCC.py:1429 flatcamTools/ToolPaint.py:1172 +#: flatcamTools/ToolSolderPaste.py:888 msgid "Please enter a tool diameter to add, in Float format." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:1012 flatcamTools/ToolPaint.py:791 -msgid "Adding tool cancelled. Tool already in Tool Table." +#: flatcamTools/ToolNCC.py:1460 flatcamTools/ToolNCC.py:4013 flatcamTools/ToolPaint.py:1196 +#: flatcamTools/ToolPaint.py:4077 flatcamTools/ToolSolderPaste.py:917 +msgid "Cancelled. Tool already in Tool Table." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:1017 flatcamTools/ToolPaint.py:797 +#: flatcamTools/ToolNCC.py:1467 flatcamTools/ToolNCC.py:4030 flatcamTools/ToolPaint.py:1201 +#: flatcamTools/ToolPaint.py:4094 msgid "New tool added to Tool Table." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:1061 flatcamTools/ToolPaint.py:843 +#: flatcamTools/ToolNCC.py:1511 flatcamTools/ToolPaint.py:1245 msgid "Tool from Tool Table was edited." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:1072 flatcamTools/ToolPaint.py:855 -#: flatcamTools/ToolSolderPaste.py:978 -msgid "Edit cancelled. New diameter value is already in the Tool Table." +#: flatcamTools/ToolNCC.py:1523 flatcamTools/ToolPaint.py:1257 +#: flatcamTools/ToolSolderPaste.py:977 +msgid "Cancelled. New diameter value is already in the Tool Table." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:1119 flatcamTools/ToolPaint.py:953 +#: flatcamTools/ToolNCC.py:1575 flatcamTools/ToolPaint.py:1355 msgid "Delete failed. Select a tool to delete." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:1124 flatcamTools/ToolPaint.py:959 +#: flatcamTools/ToolNCC.py:1581 flatcamTools/ToolPaint.py:1361 msgid "Tool(s) deleted from Tool Table." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:1171 +#: flatcamTools/ToolNCC.py:1623 msgid "Wrong Tool Dia value format entered, use a number." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:1180 flatcamTools/ToolPaint.py:1023 +#: flatcamTools/ToolNCC.py:1632 flatcamTools/ToolPaint.py:1412 msgid "No selected tools in Tool Table." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:1255 flatcamTools/ToolPaint.py:1195 +#: flatcamTools/ToolNCC.py:1708 flatcamTools/ToolPaint.py:1588 msgid "Click the end point of the paint area." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:1410 flatcamTools/ToolNonCopperClear.py:1412 -msgid "Non-Copper clearing ..." -msgstr "" - -#: flatcamTools/ToolNonCopperClear.py:1422 -msgid "NCC Tool started. Reading parameters." -msgstr "" - -#: flatcamTools/ToolNonCopperClear.py:1485 +#: flatcamTools/ToolNCC.py:1976 flatcamTools/ToolNCC.py:2964 msgid "NCC Tool. Preparing non-copper polygons." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:1581 -msgid "NCC Tool. Finished non-copper polygons. Normal copper clearing task started." -msgstr "" - -#: flatcamTools/ToolNonCopperClear.py:1613 +#: flatcamTools/ToolNCC.py:2035 flatcamTools/ToolNCC.py:3092 msgid "NCC Tool. Calculate 'empty' area." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:1626 flatcamTools/ToolNonCopperClear.py:1723 -#: flatcamTools/ToolNonCopperClear.py:1735 flatcamTools/ToolNonCopperClear.py:2018 -#: flatcamTools/ToolNonCopperClear.py:2114 flatcamTools/ToolNonCopperClear.py:2126 +#: flatcamTools/ToolNCC.py:2054 flatcamTools/ToolNCC.py:2160 flatcamTools/ToolNCC.py:2174 +#: flatcamTools/ToolNCC.py:3105 flatcamTools/ToolNCC.py:3210 flatcamTools/ToolNCC.py:3225 +#: flatcamTools/ToolNCC.py:3491 flatcamTools/ToolNCC.py:3592 flatcamTools/ToolNCC.py:3607 msgid "Buffering finished" msgstr "" -#: flatcamTools/ToolNonCopperClear.py:1742 flatcamTools/ToolNonCopperClear.py:2132 -msgid "The selected object is not suitable for copper clearing." -msgstr "" - -#: flatcamTools/ToolNonCopperClear.py:1747 flatcamTools/ToolNonCopperClear.py:2137 +#: flatcamTools/ToolNCC.py:2062 flatcamTools/ToolNCC.py:2181 flatcamTools/ToolNCC.py:3113 +#: flatcamTools/ToolNCC.py:3232 flatcamTools/ToolNCC.py:3498 flatcamTools/ToolNCC.py:3614 msgid "Could not get the extent of the area to be non copper cleared." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:1754 +#: flatcamTools/ToolNCC.py:2089 flatcamTools/ToolNCC.py:2167 flatcamTools/ToolNCC.py:3140 +#: flatcamTools/ToolNCC.py:3217 flatcamTools/ToolNCC.py:3518 flatcamTools/ToolNCC.py:3599 +msgid "Isolation geometry is broken. Margin is less than isolation tool diameter." +msgstr "" + +#: flatcamTools/ToolNCC.py:2184 flatcamTools/ToolNCC.py:3236 flatcamTools/ToolNCC.py:3617 +msgid "The selected object is not suitable for copper clearing." +msgstr "" + +#: flatcamTools/ToolNCC.py:2191 flatcamTools/ToolNCC.py:3243 msgid "NCC Tool. Finished calculation of 'empty' area." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:1768 flatcamTools/ToolNonCopperClear.py:2162 -msgid "NCC Tool clearing with tool diameter = " +#: flatcamTools/ToolNCC.py:2222 flatcamTools/ToolNCC.py:2224 flatcamTools/ToolNCC.py:2916 +#: flatcamTools/ToolNCC.py:2918 +msgid "Non-Copper clearing ..." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:1771 flatcamTools/ToolNonCopperClear.py:2165 +#: flatcamTools/ToolNCC.py:2278 flatcamTools/ToolNCC.py:3060 +msgid "NCC Tool. Finished non-copper polygons. Normal copper clearing task started." +msgstr "" + +#: flatcamTools/ToolNCC.py:2312 flatcamTools/ToolNCC.py:2592 +msgid "NCC Tool failed creating bounding box." +msgstr "" + +#: flatcamTools/ToolNCC.py:2326 flatcamTools/ToolNCC.py:2609 flatcamTools/ToolNCC.py:3256 +#: flatcamTools/ToolNCC.py:3642 +msgid "NCC Tool clearing with tool diameter" +msgstr "" + +#: flatcamTools/ToolNCC.py:2326 flatcamTools/ToolNCC.py:2609 flatcamTools/ToolNCC.py:3256 +#: flatcamTools/ToolNCC.py:3642 msgid "started." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:1947 +#: flatcamTools/ToolNCC.py:2518 flatcamTools/ToolNCC.py:3417 msgid "" "There is no NCC 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." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:1967 +#: flatcamTools/ToolNCC.py:2527 flatcamTools/ToolNCC.py:3426 msgid "NCC Tool clear all done." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:1969 +#: flatcamTools/ToolNCC.py:2530 flatcamTools/ToolNCC.py:3429 msgid "NCC Tool clear all done but the copper features isolation is broken for" msgstr "" -#: flatcamTools/ToolNonCopperClear.py:1972 flatcamTools/ToolNonCopperClear.py:2341 +#: flatcamTools/ToolNCC.py:2532 flatcamTools/ToolNCC.py:2817 flatcamTools/ToolNCC.py:3431 +#: flatcamTools/ToolNCC.py:3814 msgid "tools" msgstr "" -#: flatcamTools/ToolNonCopperClear.py:2337 +#: flatcamTools/ToolNCC.py:2813 flatcamTools/ToolNCC.py:3810 msgid "NCC Tool Rest Machining clear all done." msgstr "" -#: flatcamTools/ToolNonCopperClear.py:2340 +#: flatcamTools/ToolNCC.py:2816 flatcamTools/ToolNCC.py:3813 msgid "" "NCC Tool Rest Machining clear all done but the copper features isolation is broken for" msgstr "" -#: flatcamTools/ToolNonCopperClear.py:2787 +#: flatcamTools/ToolNCC.py:2928 +msgid "NCC Tool started. Reading parameters." +msgstr "" + +#: flatcamTools/ToolNCC.py:3906 msgid "" "Try to use the Buffering Type = Full in Preferences -> Gerber General. Reload the Gerber " "file after this change." msgstr "" -#: flatcamTools/ToolOptimal.py:79 +#: flatcamTools/ToolOptimal.py:80 msgid "Number of decimals kept for found distances." msgstr "" -#: flatcamTools/ToolOptimal.py:87 +#: flatcamTools/ToolOptimal.py:88 msgid "Minimum distance" msgstr "" -#: flatcamTools/ToolOptimal.py:88 +#: flatcamTools/ToolOptimal.py:89 msgid "Display minimum distance between copper features." msgstr "" -#: flatcamTools/ToolOptimal.py:92 +#: flatcamTools/ToolOptimal.py:93 msgid "Determined" msgstr "" -#: flatcamTools/ToolOptimal.py:106 +#: flatcamTools/ToolOptimal.py:107 msgid "Occurring" msgstr "" -#: flatcamTools/ToolOptimal.py:107 +#: flatcamTools/ToolOptimal.py:108 msgid "How many times this minimum is found." msgstr "" -#: flatcamTools/ToolOptimal.py:113 +#: flatcamTools/ToolOptimal.py:114 msgid "Minimum points coordinates" msgstr "" -#: flatcamTools/ToolOptimal.py:114 flatcamTools/ToolOptimal.py:120 +#: flatcamTools/ToolOptimal.py:115 flatcamTools/ToolOptimal.py:121 msgid "Coordinates for points where minimum distance was found." msgstr "" -#: flatcamTools/ToolOptimal.py:133 flatcamTools/ToolOptimal.py:209 +#: flatcamTools/ToolOptimal.py:134 flatcamTools/ToolOptimal.py:210 msgid "Jump to selected position" msgstr "" -#: flatcamTools/ToolOptimal.py:135 flatcamTools/ToolOptimal.py:211 +#: flatcamTools/ToolOptimal.py:136 flatcamTools/ToolOptimal.py:212 msgid "" "Select a position in the Locations text box and then\n" "click this button." msgstr "" -#: flatcamTools/ToolOptimal.py:143 +#: flatcamTools/ToolOptimal.py:144 msgid "Other distances" msgstr "" -#: flatcamTools/ToolOptimal.py:144 +#: flatcamTools/ToolOptimal.py:145 msgid "" "Will display other distances in the Gerber file ordered from\n" "the minimum to the maximum, not including the absolute minimum." msgstr "" -#: flatcamTools/ToolOptimal.py:149 +#: flatcamTools/ToolOptimal.py:150 msgid "Other distances points coordinates" msgstr "" -#: flatcamTools/ToolOptimal.py:150 flatcamTools/ToolOptimal.py:164 -#: flatcamTools/ToolOptimal.py:171 flatcamTools/ToolOptimal.py:188 -#: flatcamTools/ToolOptimal.py:195 +#: flatcamTools/ToolOptimal.py:151 flatcamTools/ToolOptimal.py:165 +#: flatcamTools/ToolOptimal.py:172 flatcamTools/ToolOptimal.py:189 +#: flatcamTools/ToolOptimal.py:196 msgid "" "Other distances and the coordinates for points\n" "where the distance was found." msgstr "" -#: flatcamTools/ToolOptimal.py:163 +#: flatcamTools/ToolOptimal.py:164 msgid "Gerber distances" msgstr "" -#: flatcamTools/ToolOptimal.py:187 +#: flatcamTools/ToolOptimal.py:188 msgid "Points coordinates" msgstr "" -#: flatcamTools/ToolOptimal.py:219 +#: flatcamTools/ToolOptimal.py:220 msgid "Find Minimum" msgstr "" -#: flatcamTools/ToolOptimal.py:221 +#: flatcamTools/ToolOptimal.py:222 msgid "" "Calculate the minimum distance between copper features,\n" "this will allow the determination of the right tool to\n" "use for isolation or copper clearing." msgstr "" -#: flatcamTools/ToolOptimal.py:346 +#: flatcamTools/ToolOptimal.py:347 msgid "Only Gerber objects can be evaluated." msgstr "" -#: flatcamTools/ToolOptimal.py:352 +#: flatcamTools/ToolOptimal.py:353 msgid "Optimal Tool. Started to search for the minimum distance between copper features." msgstr "" -#: flatcamTools/ToolOptimal.py:362 +#: flatcamTools/ToolOptimal.py:363 msgid "Optimal Tool. Parsing geometry for aperture" msgstr "" -#: flatcamTools/ToolOptimal.py:373 +#: flatcamTools/ToolOptimal.py:374 msgid "Optimal Tool. Creating a buffer for the object geometry." msgstr "" -#: flatcamTools/ToolOptimal.py:383 +#: flatcamTools/ToolOptimal.py:384 msgid "" "The Gerber object has one Polygon as geometry.\n" "There are no distances between geometry elements to be found." msgstr "" -#: flatcamTools/ToolOptimal.py:388 +#: flatcamTools/ToolOptimal.py:389 msgid "Optimal Tool. Finding the distances between each two elements. Iterations" msgstr "" -#: flatcamTools/ToolOptimal.py:423 +#: flatcamTools/ToolOptimal.py:424 msgid "Optimal Tool. Finding the minimum distance." msgstr "" -#: flatcamTools/ToolOptimal.py:439 +#: flatcamTools/ToolOptimal.py:440 msgid "Optimal Tool. Finished successfully." msgstr "" @@ -12929,7 +13639,7 @@ msgstr "" msgid "Rendered" msgstr "" -#: flatcamTools/ToolPaint.py:87 +#: flatcamTools/ToolPaint.py:82 msgid "" "Specify the type of object to be painted.\n" "It can be of type: Gerber or Geometry.\n" @@ -12941,13 +13651,13 @@ msgstr "" msgid "Object to be painted." msgstr "" -#: flatcamTools/ToolPaint.py:114 +#: flatcamTools/ToolPaint.py:117 msgid "" "Tools pool from which the algorithm\n" "will pick the ones used for painting." msgstr "" -#: flatcamTools/ToolPaint.py:129 +#: flatcamTools/ToolPaint.py:134 msgid "" "This is the Tool Number.\n" "Painting will start with the tool with the biggest diameter,\n" @@ -12957,7 +13667,7 @@ msgid "" "this function will not be able to create painting geometry." msgstr "" -#: flatcamTools/ToolPaint.py:141 +#: flatcamTools/ToolPaint.py:146 msgid "" "The Tool Type (TT) can be:
- Circular with 1 ... 4 teeth -> it is informative " "only. Being circular,
the cut width in material is exactly the tool diameter.
- " @@ -12970,49 +13680,13 @@ msgid "" "the resulting geometry as Isolation." msgstr "" -#: flatcamTools/ToolPaint.py:178 -msgid "Diameter for the new tool." -msgstr "" - -#: flatcamTools/ToolPaint.py:253 -msgid "" -"Algorithm for painting:\n" -"- Standard: Fixed step inwards.\n" -"- Seed-based: Outwards from seed.\n" -"- Line-based: Parallel lines." -msgstr "" - -#: flatcamTools/ToolPaint.py:283 -msgid "" -"If checked, use 'rest machining'.\n" -"Basically it will clear copper outside PCB features,\n" -"using the biggest tool and continue with the next tools,\n" -"from bigger to smaller, to clear areas of copper that\n" -"could not be cleared by previous tool, until there is\n" -"no more copper to clear or there are no more tools.\n" -"\n" -"If not checked, use the standard algorithm." -msgstr "" - -#: flatcamTools/ToolPaint.py:307 -msgid "Polygon Selection" -msgstr "" - -#: flatcamTools/ToolPaint.py:309 -msgid "All Polygons" -msgstr "" - -#: flatcamTools/ToolPaint.py:328 +#: flatcamTools/ToolPaint.py:498 msgid "" "The type of FlatCAM object to be used as paint reference.\n" "It can be Gerber, Excellon or Geometry." msgstr "" -#: flatcamTools/ToolPaint.py:353 -msgid "Create Paint Geometry" -msgstr "" - -#: flatcamTools/ToolPaint.py:355 +#: flatcamTools/ToolPaint.py:539 msgid "" "- 'Area Selection' - left mouse click to start selection of the area to be painted.\n" "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple areas.\n" @@ -13021,152 +13695,183 @@ msgid "" "specified by another object." msgstr "" -#: flatcamTools/ToolPaint.py:973 -msgid "Paint Tool. Reading parameters." -msgstr "" - -#: flatcamTools/ToolPaint.py:988 +#: flatcamTools/ToolPaint.py:1381 #, python-format msgid "Could not retrieve object: %s" msgstr "" -#: flatcamTools/ToolPaint.py:1002 +#: flatcamTools/ToolPaint.py:1391 msgid "Can't do Paint on MultiGeo geometries" msgstr "" -#: flatcamTools/ToolPaint.py:1035 +#: flatcamTools/ToolPaint.py:1421 msgid "Click on a polygon to paint it." msgstr "" -#: flatcamTools/ToolPaint.py:1054 +#: flatcamTools/ToolPaint.py:1441 msgid "Click the start point of the paint area." msgstr "" -#: flatcamTools/ToolPaint.py:1122 +#: flatcamTools/ToolPaint.py:1506 msgid "Click to add next polygon or right click to start painting." msgstr "" -#: flatcamTools/ToolPaint.py:1135 +#: flatcamTools/ToolPaint.py:1519 msgid "Click to add/remove next polygon or right click to start painting." msgstr "" -#: flatcamTools/ToolPaint.py:1344 flatcamTools/ToolPaint.py:1347 -#: flatcamTools/ToolPaint.py:1349 flatcamTools/ToolPaint.py:1987 -#: flatcamTools/ToolPaint.py:1991 flatcamTools/ToolPaint.py:1994 -#: flatcamTools/ToolPaint.py:2276 flatcamTools/ToolPaint.py:2281 -#: flatcamTools/ToolPaint.py:2284 flatcamTools/ToolPaint.py:2458 -#: flatcamTools/ToolPaint.py:2465 -msgid "Paint Tool." +#: flatcamTools/ToolPaint.py:2013 +msgid "Painting polygon with method: lines." msgstr "" -#: flatcamTools/ToolPaint.py:1344 flatcamTools/ToolPaint.py:1347 -#: flatcamTools/ToolPaint.py:1349 -msgid "Normal painting polygon task started." +#: flatcamTools/ToolPaint.py:2025 +msgid "Failed. Painting polygon with method: seed." msgstr "" -#: flatcamTools/ToolPaint.py:1345 flatcamTools/ToolPaint.py:1706 -#: flatcamTools/ToolPaint.py:1988 flatcamTools/ToolPaint.py:2278 -#: flatcamTools/ToolPaint.py:2460 -msgid "Buffering geometry..." +#: flatcamTools/ToolPaint.py:2036 +msgid "Failed. Painting polygon with method: standard." msgstr "" -#: flatcamTools/ToolPaint.py:1367 -msgid "No polygon found." -msgstr "" - -#: flatcamTools/ToolPaint.py:1401 -msgid "Painting polygon..." -msgstr "" - -#: flatcamTools/ToolPaint.py:1448 +#: flatcamTools/ToolPaint.py:2052 msgid "Geometry could not be painted completely" msgstr "" -#: flatcamTools/ToolPaint.py:1481 +#: flatcamTools/ToolPaint.py:2081 flatcamTools/ToolPaint.py:2084 +#: flatcamTools/ToolPaint.py:2092 flatcamTools/ToolPaint.py:2634 +#: flatcamTools/ToolPaint.py:2638 flatcamTools/ToolPaint.py:2641 +#: flatcamTools/ToolPaint.py:3448 flatcamTools/ToolPaint.py:3452 +#: flatcamTools/ToolPaint.py:3455 +msgid "Paint Tool." +msgstr "" + +#: flatcamTools/ToolPaint.py:2081 flatcamTools/ToolPaint.py:2084 +#: flatcamTools/ToolPaint.py:2092 +msgid "Normal painting polygon task started." +msgstr "" + +#: flatcamTools/ToolPaint.py:2082 flatcamTools/ToolPaint.py:2423 +#: flatcamTools/ToolPaint.py:2635 flatcamTools/ToolPaint.py:3085 +#: flatcamTools/ToolPaint.py:3449 +msgid "Buffering geometry..." +msgstr "" + +#: flatcamTools/ToolPaint.py:2105 +msgid "No polygon found." +msgstr "" + +#: flatcamTools/ToolPaint.py:2135 +msgid "Painting polygon..." +msgstr "" + +#: flatcamTools/ToolPaint.py:2144 flatcamTools/ToolPaint.py:2466 +#: flatcamTools/ToolPaint.py:2674 flatcamTools/ToolPaint.py:3132 +#: flatcamTools/ToolPaint.py:3492 +msgid "Painting with tool diameter = " +msgstr "" + +#: flatcamTools/ToolPaint.py:2145 flatcamTools/ToolPaint.py:2469 +#: flatcamTools/ToolPaint.py:2677 flatcamTools/ToolPaint.py:3135 +#: flatcamTools/ToolPaint.py:3495 +msgid "started" +msgstr "" + +#: flatcamTools/ToolPaint.py:2170 flatcamTools/ToolPaint.py:2494 +#: flatcamTools/ToolPaint.py:2703 flatcamTools/ToolPaint.py:3161 +#: flatcamTools/ToolPaint.py:3524 +msgid "Margin parameter too big. Tool is not used" +msgstr "" + +#: flatcamTools/ToolPaint.py:2210 flatcamTools/ToolPaint.py:2564 +#: flatcamTools/ToolPaint.py:3377 msgid "" "Could not do Paint. Try a different combination of parameters. Or a different strategy of " "paint" msgstr "" -#: flatcamTools/ToolPaint.py:1533 flatcamTools/ToolPaint.py:1967 -#: flatcamTools/ToolPaint.py:2117 flatcamTools/ToolPaint.py:2438 -#: flatcamTools/ToolPaint.py:2592 +#: flatcamTools/ToolPaint.py:2268 flatcamTools/ToolPaint.py:2614 +#: flatcamTools/ToolPaint.py:2955 flatcamTools/ToolPaint.py:3428 +#: flatcamTools/ToolPaint.py:3771 msgid "" "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." msgstr "" -#: flatcamTools/ToolPaint.py:1539 +#: flatcamTools/ToolPaint.py:2300 +msgid "Paint Single failed." +msgstr "" + +#: flatcamTools/ToolPaint.py:2306 msgid "Paint Single Done." msgstr "" -#: flatcamTools/ToolPaint.py:1571 flatcamTools/ToolPaint.py:2145 -#: flatcamTools/ToolPaint.py:2620 +#: flatcamTools/ToolPaint.py:2308 flatcamTools/ToolPaint.py:2983 +#: flatcamTools/ToolPaint.py:3799 msgid "Polygon Paint started ..." msgstr "" -#: flatcamTools/ToolPaint.py:1623 flatcamTools/ToolPaint.py:2207 +#: flatcamTools/ToolPaint.py:2347 flatcamTools/ToolPaint.py:3023 msgid "Painting polygons..." msgstr "" -#: flatcamTools/ToolPaint.py:1705 flatcamTools/ToolPaint.py:1708 -#: flatcamTools/ToolPaint.py:1710 +#: flatcamTools/ToolPaint.py:2422 flatcamTools/ToolPaint.py:2425 +#: flatcamTools/ToolPaint.py:2427 msgid "Paint Tool. Normal painting all task started." msgstr "" -#: flatcamTools/ToolPaint.py:1744 flatcamTools/ToolPaint.py:2023 -#: flatcamTools/ToolPaint.py:2325 flatcamTools/ToolPaint.py:2501 -msgid "Painting with tool diameter = " -msgstr "" - -#: flatcamTools/ToolPaint.py:1747 flatcamTools/ToolPaint.py:2026 -#: flatcamTools/ToolPaint.py:2328 flatcamTools/ToolPaint.py:2504 -msgid "started" -msgstr "" - -#: flatcamTools/ToolPaint.py:1976 +#: flatcamTools/ToolPaint.py:2623 msgid "Paint All Done." msgstr "" -#: flatcamTools/ToolPaint.py:1987 flatcamTools/ToolPaint.py:1991 -#: flatcamTools/ToolPaint.py:1994 +#: flatcamTools/ToolPaint.py:2634 flatcamTools/ToolPaint.py:2638 +#: flatcamTools/ToolPaint.py:2641 msgid "Rest machining painting all task started." msgstr "" -#: flatcamTools/ToolPaint.py:2072 flatcamTools/ToolPaint.py:2388 -#: flatcamTools/ToolPaint.py:2548 +#: flatcamTools/ToolPaint.py:2862 flatcamTools/ToolPaint.py:3334 +#: flatcamTools/ToolPaint.py:3683 +msgid "Painting polygons with method: lines." +msgstr "" + +#: flatcamTools/ToolPaint.py:2875 flatcamTools/ToolPaint.py:3347 +#: flatcamTools/ToolPaint.py:3695 +msgid "Failed. Painting polygons with method: seed." +msgstr "" + +#: flatcamTools/ToolPaint.py:2887 flatcamTools/ToolPaint.py:3359 +#: flatcamTools/ToolPaint.py:3707 +msgid "Failed. Painting polygons with method: standard." +msgstr "" + +#: flatcamTools/ToolPaint.py:2904 flatcamTools/ToolPaint.py:3723 msgid "" "Could not do Paint All. Try a different combination of parameters. Or a different Method " "of paint" msgstr "" -#: flatcamTools/ToolPaint.py:2126 flatcamTools/ToolPaint.py:2601 +#: flatcamTools/ToolPaint.py:2964 flatcamTools/ToolPaint.py:3780 msgid "Paint All with Rest-Machining done." msgstr "" -#: flatcamTools/ToolPaint.py:2277 flatcamTools/ToolPaint.py:2281 -#: flatcamTools/ToolPaint.py:2284 -msgid "Normal painting area task started." +#: flatcamTools/ToolPaint.py:3084 flatcamTools/ToolPaint.py:3087 +#: flatcamTools/ToolPaint.py:3089 +msgid "Paint Tool. Normal painting area task started." msgstr "" -#: flatcamTools/ToolPaint.py:2447 +#: flatcamTools/ToolPaint.py:3437 msgid "Paint Area Done." msgstr "" -#: flatcamTools/ToolPaint.py:2459 flatcamTools/ToolPaint.py:2465 +#: flatcamTools/ToolPaint.py:3448 flatcamTools/ToolPaint.py:3452 +#: flatcamTools/ToolPaint.py:3455 msgid "Rest machining painting area task started." msgstr "" -#: flatcamTools/ToolPaint.py:2462 -msgid "Paint Tool. Rest machining painting area task started." -msgstr "" - #: flatcamTools/ToolPanelize.py:34 msgid "Panelize PCB" msgstr "" -#: flatcamTools/ToolPanelize.py:68 +#: flatcamTools/ToolPanelize.py:56 msgid "" "Specify the type of object to be panelized\n" "It can be of type: Gerber, Excellon or Geometry.\n" @@ -13174,17 +13879,17 @@ msgid "" "in the Object combobox." msgstr "" -#: flatcamTools/ToolPanelize.py:83 +#: flatcamTools/ToolPanelize.py:89 msgid "" "Object to be panelized. This means that it will\n" "be duplicated in an array of rows and columns." msgstr "" -#: flatcamTools/ToolPanelize.py:96 +#: flatcamTools/ToolPanelize.py:102 msgid "Penelization Reference" msgstr "" -#: flatcamTools/ToolPanelize.py:98 +#: flatcamTools/ToolPanelize.py:104 msgid "" "Choose the reference for panelization:\n" "- Object = the bounding box of a different object\n" @@ -13196,11 +13901,11 @@ msgid "" "objects in sync." msgstr "" -#: flatcamTools/ToolPanelize.py:121 +#: flatcamTools/ToolPanelize.py:125 msgid "Box Type" msgstr "" -#: flatcamTools/ToolPanelize.py:123 +#: flatcamTools/ToolPanelize.py:127 msgid "" "Specify the type of object to be used as an container for\n" "panelization. It can be: Gerber or Geometry type.\n" @@ -13208,17 +13913,17 @@ msgid "" "in the Box Object combobox." msgstr "" -#: flatcamTools/ToolPanelize.py:138 +#: flatcamTools/ToolPanelize.py:141 msgid "" "The actual object that is used a container for the\n" " selected object that is to be panelized." msgstr "" -#: flatcamTools/ToolPanelize.py:144 +#: flatcamTools/ToolPanelize.py:147 msgid "Panel Data" msgstr "" -#: flatcamTools/ToolPanelize.py:146 +#: flatcamTools/ToolPanelize.py:149 msgid "" "This informations will shape the resulting panel.\n" "The number of rows and columns will set how many\n" @@ -13228,58 +13933,58 @@ msgid "" "elements of the panel array." msgstr "" -#: flatcamTools/ToolPanelize.py:205 +#: flatcamTools/ToolPanelize.py:208 msgid "" "Choose the type of object for the panel object:\n" "- Geometry\n" "- Gerber" msgstr "" -#: flatcamTools/ToolPanelize.py:213 +#: flatcamTools/ToolPanelize.py:216 msgid "Constrain panel within" msgstr "" -#: flatcamTools/ToolPanelize.py:249 +#: flatcamTools/ToolPanelize.py:252 msgid "Panelize Object" msgstr "" -#: flatcamTools/ToolPanelize.py:251 flatcamTools/ToolRulesCheck.py:492 +#: flatcamTools/ToolPanelize.py:254 flatcamTools/ToolRulesCheck.py:501 msgid "" "Panelize the specified object around the specified box.\n" "In other words it creates multiple copies of the source object,\n" "arranged in a 2D array of rows and columns." msgstr "" -#: flatcamTools/ToolPanelize.py:319 +#: flatcamTools/ToolPanelize.py:322 msgid "Panel. Tool" msgstr "" -#: flatcamTools/ToolPanelize.py:448 +#: flatcamTools/ToolPanelize.py:460 msgid "Columns or Rows are zero value. Change them to a positive integer." msgstr "" -#: flatcamTools/ToolPanelize.py:485 +#: flatcamTools/ToolPanelize.py:497 msgid "Generating panel ... " msgstr "" -#: flatcamTools/ToolPanelize.py:768 +#: flatcamTools/ToolPanelize.py:777 msgid "Generating panel ... Adding the Gerber code." msgstr "" -#: flatcamTools/ToolPanelize.py:779 +#: flatcamTools/ToolPanelize.py:788 msgid "Generating panel... Spawning copies" msgstr "" -#: flatcamTools/ToolPanelize.py:786 +#: flatcamTools/ToolPanelize.py:795 msgid "Panel done..." msgstr "" -#: flatcamTools/ToolPanelize.py:789 +#: flatcamTools/ToolPanelize.py:798 #, python-brace-format msgid "{text} Too big for the constrain area. Final panel has {col} columns and {row} rows" msgstr "" -#: flatcamTools/ToolPanelize.py:798 +#: flatcamTools/ToolPanelize.py:807 msgid "Panel created successfully." msgstr "" @@ -13403,163 +14108,202 @@ msgstr "" msgid "Main PcbWizard Excellon file loaded." msgstr "" -#: flatcamTools/ToolPcbWizard.py:431 +#: flatcamTools/ToolPcbWizard.py:428 msgid "Cannot parse file" msgstr "" -#: flatcamTools/ToolPcbWizard.py:456 +#: flatcamTools/ToolPcbWizard.py:452 msgid "Importing Excellon." msgstr "" -#: flatcamTools/ToolPcbWizard.py:463 +#: flatcamTools/ToolPcbWizard.py:459 msgid "Import Excellon file failed." msgstr "" -#: flatcamTools/ToolPcbWizard.py:471 +#: flatcamTools/ToolPcbWizard.py:467 msgid "Imported" msgstr "" -#: flatcamTools/ToolPcbWizard.py:475 +#: flatcamTools/ToolPcbWizard.py:471 msgid "Excellon merging is in progress. Please wait..." msgstr "" -#: flatcamTools/ToolPcbWizard.py:478 +#: flatcamTools/ToolPcbWizard.py:474 msgid "The imported Excellon file is None." msgstr "" -#: flatcamTools/ToolProperties.py:119 -msgid "Properties Tool was not displayed. No object selected." -msgstr "" - -#: flatcamTools/ToolProperties.py:134 +#: flatcamTools/ToolProperties.py:131 msgid "Object Properties are displayed." msgstr "" -#: flatcamTools/ToolProperties.py:135 +#: flatcamTools/ToolProperties.py:136 msgid "Properties Tool" msgstr "" -#: flatcamTools/ToolProperties.py:149 +#: flatcamTools/ToolProperties.py:150 msgid "TYPE" msgstr "" -#: flatcamTools/ToolProperties.py:150 +#: flatcamTools/ToolProperties.py:151 msgid "NAME" msgstr "" -#: flatcamTools/ToolProperties.py:151 +#: flatcamTools/ToolProperties.py:153 msgid "Dimensions" msgstr "" -#: flatcamTools/ToolProperties.py:165 -msgid "Others" -msgstr "" - -#: flatcamTools/ToolProperties.py:172 +#: flatcamTools/ToolProperties.py:181 msgid "Geo Type" msgstr "" -#: flatcamTools/ToolProperties.py:173 +#: flatcamTools/ToolProperties.py:184 msgid "Single-Geo" msgstr "" -#: flatcamTools/ToolProperties.py:173 +#: flatcamTools/ToolProperties.py:185 msgid "Multi-Geo" msgstr "" -#: flatcamTools/ToolProperties.py:181 +#: flatcamTools/ToolProperties.py:196 msgid "Calculating dimensions ... Please wait." msgstr "" -#: flatcamTools/ToolProperties.py:321 flatcamTools/ToolProperties.py:325 -#: flatcamTools/ToolProperties.py:327 +#: flatcamTools/ToolProperties.py:339 flatcamTools/ToolProperties.py:343 +#: flatcamTools/ToolProperties.py:345 msgid "Inch" msgstr "" -#: flatcamTools/ToolProperties.py:321 flatcamTools/ToolProperties.py:326 -#: flatcamTools/ToolProperties.py:328 +#: flatcamTools/ToolProperties.py:339 flatcamTools/ToolProperties.py:344 +#: flatcamTools/ToolProperties.py:346 msgid "Metric" msgstr "" -#: flatcamTools/ToolProperties.py:401 flatcamTools/ToolProperties.py:459 +#: flatcamTools/ToolProperties.py:421 flatcamTools/ToolProperties.py:486 msgid "Drills number" msgstr "" -#: flatcamTools/ToolProperties.py:402 flatcamTools/ToolProperties.py:461 +#: flatcamTools/ToolProperties.py:422 flatcamTools/ToolProperties.py:488 msgid "Slots number" msgstr "" -#: flatcamTools/ToolProperties.py:404 +#: flatcamTools/ToolProperties.py:424 msgid "Drills total number:" msgstr "" -#: flatcamTools/ToolProperties.py:405 +#: flatcamTools/ToolProperties.py:425 msgid "Slots total number:" msgstr "" -#: flatcamTools/ToolProperties.py:411 flatcamTools/ToolProperties.py:426 -#: flatcamTools/ToolProperties.py:429 flatcamTools/ToolProperties.py:432 -#: flatcamTools/ToolProperties.py:456 +#: flatcamTools/ToolProperties.py:452 flatcamTools/ToolProperties.py:455 +#: flatcamTools/ToolProperties.py:458 flatcamTools/ToolProperties.py:483 msgid "Present" msgstr "" -#: flatcamTools/ToolProperties.py:427 flatcamTools/ToolProperties.py:457 +#: flatcamTools/ToolProperties.py:453 flatcamTools/ToolProperties.py:484 msgid "Solid Geometry" msgstr "" -#: flatcamTools/ToolProperties.py:430 +#: flatcamTools/ToolProperties.py:456 msgid "GCode Text" msgstr "" -#: flatcamTools/ToolProperties.py:433 +#: flatcamTools/ToolProperties.py:459 msgid "GCode Geometry" msgstr "" -#: flatcamTools/ToolProperties.py:435 +#: flatcamTools/ToolProperties.py:462 msgid "Data" msgstr "" -#: flatcamTools/ToolProperties.py:468 +#: flatcamTools/ToolProperties.py:495 msgid "Depth of Cut" msgstr "" -#: flatcamTools/ToolProperties.py:480 +#: flatcamTools/ToolProperties.py:507 msgid "Clearance Height" msgstr "" -#: flatcamTools/ToolProperties.py:512 +#: flatcamTools/ToolProperties.py:539 msgid "Routing time" msgstr "" -#: flatcamTools/ToolProperties.py:519 +#: flatcamTools/ToolProperties.py:546 msgid "Travelled distance" msgstr "" -#: flatcamTools/ToolProperties.py:560 +#: flatcamTools/ToolProperties.py:564 msgid "Width" msgstr "" -#: flatcamTools/ToolProperties.py:566 flatcamTools/ToolProperties.py:574 +#: flatcamTools/ToolProperties.py:570 flatcamTools/ToolProperties.py:578 msgid "Box Area" msgstr "" -#: flatcamTools/ToolProperties.py:569 flatcamTools/ToolProperties.py:577 +#: flatcamTools/ToolProperties.py:573 flatcamTools/ToolProperties.py:581 msgid "Convex_Hull Area" msgstr "" -#: flatcamTools/ToolProperties.py:583 flatcamTools/ToolProperties.py:585 +#: flatcamTools/ToolProperties.py:588 flatcamTools/ToolProperties.py:591 msgid "Copper Area" msgstr "" -#: flatcamTools/ToolQRCode.py:79 +#: flatcamTools/ToolPunchGerber.py:30 flatcamTools/ToolPunchGerber.py:323 +msgid "Punch Gerber" +msgstr "" + +#: flatcamTools/ToolPunchGerber.py:65 +msgid "Gerber into which to punch holes" +msgstr "" + +#: flatcamTools/ToolPunchGerber.py:85 +msgid "ALL" +msgstr "" + +#: flatcamTools/ToolPunchGerber.py:166 +msgid "Remove the geometry of Excellon from the Gerber to create the holes in pads." +msgstr "" + +#: flatcamTools/ToolPunchGerber.py:325 +msgid "" +"Create a Gerber object from the selected object, within\n" +"the specified box." +msgstr "" + +#: flatcamTools/ToolPunchGerber.py:425 +msgid "Punch Tool" +msgstr "" + +#: flatcamTools/ToolPunchGerber.py:599 +msgid "The value of the fixed diameter is 0.0. Aborting." +msgstr "" + +#: flatcamTools/ToolPunchGerber.py:607 +msgid "" +" Could not generate punched hole Gerber because the punch hole sizeis bigger than some of " +"the apertures in the Gerber object." +msgstr "" + +#: flatcamTools/ToolPunchGerber.py:619 +msgid "" +"Could not generate punched hole Gerber because the punch hole sizeis bigger than some of " +"the apertures in the Gerber object." +msgstr "" + +#: flatcamTools/ToolPunchGerber.py:656 +msgid "" +"Could not generate punched hole Gerber because the newly created object geometry is the " +"same as the one in the source object geometry..." +msgstr "" + +#: flatcamTools/ToolQRCode.py:80 msgid "Gerber Object to which the QRCode will be added." msgstr "" -#: flatcamTools/ToolQRCode.py:92 +#: flatcamTools/ToolQRCode.py:93 msgid "QRCode Parameters" msgstr "" -#: flatcamTools/ToolQRCode.py:94 +#: flatcamTools/ToolQRCode.py:95 msgid "The parameters used to shape the QRCode." msgstr "" @@ -13601,31 +14345,27 @@ msgstr "" msgid "Create the QRCode object." msgstr "" -#: flatcamTools/ToolQRCode.py:413 flatcamTools/ToolQRCode.py:748 -#: flatcamTools/ToolQRCode.py:797 +#: flatcamTools/ToolQRCode.py:415 flatcamTools/ToolQRCode.py:750 +#: flatcamTools/ToolQRCode.py:799 msgid "Cancelled. There is no QRCode Data in the text box." msgstr "" -#: flatcamTools/ToolQRCode.py:432 +#: flatcamTools/ToolQRCode.py:434 msgid "Generating QRCode geometry" msgstr "" -#: flatcamTools/ToolQRCode.py:472 +#: flatcamTools/ToolQRCode.py:474 msgid "Click on the Destination point ..." msgstr "" -#: flatcamTools/ToolQRCode.py:587 +#: flatcamTools/ToolQRCode.py:589 msgid "QRCode Tool done." msgstr "" -#: flatcamTools/ToolQRCode.py:780 flatcamTools/ToolQRCode.py:784 +#: flatcamTools/ToolQRCode.py:782 flatcamTools/ToolQRCode.py:786 msgid "Export PNG" msgstr "" -#: flatcamTools/ToolQRCode.py:789 -msgid " Export PNG cancelled." -msgstr "" - #: flatcamTools/ToolRulesCheck.py:33 msgid "Check Rules" msgstr "" @@ -13638,210 +14378,210 @@ msgstr "" msgid "Gerber objects for which to check rules." msgstr "" -#: flatcamTools/ToolRulesCheck.py:77 +#: flatcamTools/ToolRulesCheck.py:78 msgid "Top" msgstr "" -#: flatcamTools/ToolRulesCheck.py:79 +#: flatcamTools/ToolRulesCheck.py:80 msgid "The Top Gerber Copper object for which rules are checked." msgstr "" -#: flatcamTools/ToolRulesCheck.py:94 +#: flatcamTools/ToolRulesCheck.py:96 msgid "Bottom" msgstr "" -#: flatcamTools/ToolRulesCheck.py:96 +#: flatcamTools/ToolRulesCheck.py:98 msgid "The Bottom Gerber Copper object for which rules are checked." msgstr "" -#: flatcamTools/ToolRulesCheck.py:111 +#: flatcamTools/ToolRulesCheck.py:114 msgid "SM Top" msgstr "" -#: flatcamTools/ToolRulesCheck.py:113 +#: flatcamTools/ToolRulesCheck.py:116 msgid "The Top Gerber Solder Mask object for which rules are checked." msgstr "" -#: flatcamTools/ToolRulesCheck.py:128 +#: flatcamTools/ToolRulesCheck.py:132 msgid "SM Bottom" msgstr "" -#: flatcamTools/ToolRulesCheck.py:130 +#: flatcamTools/ToolRulesCheck.py:134 msgid "The Bottom Gerber Solder Mask object for which rules are checked." msgstr "" -#: flatcamTools/ToolRulesCheck.py:145 +#: flatcamTools/ToolRulesCheck.py:150 msgid "Silk Top" msgstr "" -#: flatcamTools/ToolRulesCheck.py:147 +#: flatcamTools/ToolRulesCheck.py:152 msgid "The Top Gerber Silkscreen object for which rules are checked." msgstr "" -#: flatcamTools/ToolRulesCheck.py:162 +#: flatcamTools/ToolRulesCheck.py:168 msgid "Silk Bottom" msgstr "" -#: flatcamTools/ToolRulesCheck.py:164 +#: flatcamTools/ToolRulesCheck.py:170 msgid "The Bottom Gerber Silkscreen object for which rules are checked." msgstr "" -#: flatcamTools/ToolRulesCheck.py:181 +#: flatcamTools/ToolRulesCheck.py:188 msgid "The Gerber Outline (Cutout) object for which rules are checked." msgstr "" -#: flatcamTools/ToolRulesCheck.py:192 +#: flatcamTools/ToolRulesCheck.py:199 msgid "Excellon Objects" msgstr "" -#: flatcamTools/ToolRulesCheck.py:194 +#: flatcamTools/ToolRulesCheck.py:201 msgid "Excellon objects for which to check rules." msgstr "" -#: flatcamTools/ToolRulesCheck.py:205 +#: flatcamTools/ToolRulesCheck.py:213 msgid "Excellon 1" msgstr "" -#: flatcamTools/ToolRulesCheck.py:207 +#: flatcamTools/ToolRulesCheck.py:215 msgid "" "Excellon object for which to check rules.\n" "Holds the plated holes or a general Excellon file content." msgstr "" -#: flatcamTools/ToolRulesCheck.py:223 +#: flatcamTools/ToolRulesCheck.py:232 msgid "Excellon 2" msgstr "" -#: flatcamTools/ToolRulesCheck.py:225 +#: flatcamTools/ToolRulesCheck.py:234 msgid "" "Excellon object for which to check rules.\n" "Holds the non-plated holes." msgstr "" -#: flatcamTools/ToolRulesCheck.py:238 +#: flatcamTools/ToolRulesCheck.py:247 msgid "All Rules" msgstr "" -#: flatcamTools/ToolRulesCheck.py:240 +#: flatcamTools/ToolRulesCheck.py:249 msgid "This check/uncheck all the rules below." msgstr "" -#: flatcamTools/ToolRulesCheck.py:490 +#: flatcamTools/ToolRulesCheck.py:499 msgid "Run Rules Check" msgstr "" -#: flatcamTools/ToolRulesCheck.py:1149 flatcamTools/ToolRulesCheck.py:1209 -#: flatcamTools/ToolRulesCheck.py:1246 flatcamTools/ToolRulesCheck.py:1318 -#: flatcamTools/ToolRulesCheck.py:1372 flatcamTools/ToolRulesCheck.py:1410 -#: flatcamTools/ToolRulesCheck.py:1475 +#: flatcamTools/ToolRulesCheck.py:1158 flatcamTools/ToolRulesCheck.py:1218 +#: flatcamTools/ToolRulesCheck.py:1255 flatcamTools/ToolRulesCheck.py:1327 +#: flatcamTools/ToolRulesCheck.py:1381 flatcamTools/ToolRulesCheck.py:1419 +#: flatcamTools/ToolRulesCheck.py:1484 msgid "Value is not valid." msgstr "" -#: flatcamTools/ToolRulesCheck.py:1163 +#: flatcamTools/ToolRulesCheck.py:1172 msgid "TOP -> Copper to Copper clearance" msgstr "" -#: flatcamTools/ToolRulesCheck.py:1174 +#: flatcamTools/ToolRulesCheck.py:1183 msgid "BOTTOM -> Copper to Copper clearance" msgstr "" -#: flatcamTools/ToolRulesCheck.py:1179 flatcamTools/ToolRulesCheck.py:1273 -#: flatcamTools/ToolRulesCheck.py:1437 +#: flatcamTools/ToolRulesCheck.py:1188 flatcamTools/ToolRulesCheck.py:1282 +#: flatcamTools/ToolRulesCheck.py:1446 msgid "At least one Gerber object has to be selected for this rule but none is selected." msgstr "" -#: flatcamTools/ToolRulesCheck.py:1215 +#: flatcamTools/ToolRulesCheck.py:1224 msgid "One of the copper Gerber objects or the Outline Gerber object is not valid." msgstr "" -#: flatcamTools/ToolRulesCheck.py:1228 flatcamTools/ToolRulesCheck.py:1392 +#: flatcamTools/ToolRulesCheck.py:1237 flatcamTools/ToolRulesCheck.py:1401 msgid "Outline Gerber object presence is mandatory for this rule but it is not selected." msgstr "" -#: flatcamTools/ToolRulesCheck.py:1245 flatcamTools/ToolRulesCheck.py:1272 +#: flatcamTools/ToolRulesCheck.py:1254 flatcamTools/ToolRulesCheck.py:1281 msgid "Silk to Silk clearance" msgstr "" -#: flatcamTools/ToolRulesCheck.py:1258 +#: flatcamTools/ToolRulesCheck.py:1267 msgid "TOP -> Silk to Silk clearance" msgstr "" -#: flatcamTools/ToolRulesCheck.py:1268 +#: flatcamTools/ToolRulesCheck.py:1277 msgid "BOTTOM -> Silk to Silk clearance" msgstr "" -#: flatcamTools/ToolRulesCheck.py:1324 +#: flatcamTools/ToolRulesCheck.py:1333 msgid "One or more of the Gerber objects is not valid." msgstr "" -#: flatcamTools/ToolRulesCheck.py:1332 +#: flatcamTools/ToolRulesCheck.py:1341 msgid "TOP -> Silk to Solder Mask Clearance" msgstr "" -#: flatcamTools/ToolRulesCheck.py:1338 +#: flatcamTools/ToolRulesCheck.py:1347 msgid "BOTTOM -> Silk to Solder Mask Clearance" msgstr "" -#: flatcamTools/ToolRulesCheck.py:1342 +#: flatcamTools/ToolRulesCheck.py:1351 msgid "Both Silk and Solder Mask Gerber objects has to be either both Top or both Bottom." msgstr "" -#: flatcamTools/ToolRulesCheck.py:1378 +#: flatcamTools/ToolRulesCheck.py:1387 msgid "One of the Silk Gerber objects or the Outline Gerber object is not valid." msgstr "" -#: flatcamTools/ToolRulesCheck.py:1422 +#: flatcamTools/ToolRulesCheck.py:1431 msgid "TOP -> Minimum Solder Mask Sliver" msgstr "" -#: flatcamTools/ToolRulesCheck.py:1432 +#: flatcamTools/ToolRulesCheck.py:1441 msgid "BOTTOM -> Minimum Solder Mask Sliver" msgstr "" -#: flatcamTools/ToolRulesCheck.py:1481 +#: flatcamTools/ToolRulesCheck.py:1490 msgid "One of the Copper Gerber objects or the Excellon objects is not valid." msgstr "" -#: flatcamTools/ToolRulesCheck.py:1497 +#: flatcamTools/ToolRulesCheck.py:1506 msgid "Excellon object presence is mandatory for this rule but none is selected." msgstr "" -#: flatcamTools/ToolRulesCheck.py:1570 flatcamTools/ToolRulesCheck.py:1583 -#: flatcamTools/ToolRulesCheck.py:1594 flatcamTools/ToolRulesCheck.py:1607 +#: flatcamTools/ToolRulesCheck.py:1579 flatcamTools/ToolRulesCheck.py:1592 +#: flatcamTools/ToolRulesCheck.py:1603 flatcamTools/ToolRulesCheck.py:1616 msgid "STATUS" msgstr "" -#: flatcamTools/ToolRulesCheck.py:1573 flatcamTools/ToolRulesCheck.py:1597 +#: flatcamTools/ToolRulesCheck.py:1582 flatcamTools/ToolRulesCheck.py:1606 msgid "FAILED" msgstr "" -#: flatcamTools/ToolRulesCheck.py:1586 flatcamTools/ToolRulesCheck.py:1610 +#: flatcamTools/ToolRulesCheck.py:1595 flatcamTools/ToolRulesCheck.py:1619 msgid "PASSED" msgstr "" -#: flatcamTools/ToolRulesCheck.py:1587 flatcamTools/ToolRulesCheck.py:1611 +#: flatcamTools/ToolRulesCheck.py:1596 flatcamTools/ToolRulesCheck.py:1620 msgid "Violations: There are no violations for the current rule." msgstr "" -#: flatcamTools/ToolShell.py:70 flatcamTools/ToolShell.py:72 -msgid "...proccessing..." +#: flatcamTools/ToolShell.py:72 flatcamTools/ToolShell.py:74 +msgid "...processing..." msgstr "" -#: flatcamTools/ToolSolderPaste.py:37 +#: flatcamTools/ToolSolderPaste.py:38 msgid "Solder Paste Tool" msgstr "" -#: flatcamTools/ToolSolderPaste.py:68 +#: flatcamTools/ToolSolderPaste.py:70 msgid "Gerber Solder paste object. " msgstr "" -#: flatcamTools/ToolSolderPaste.py:75 +#: flatcamTools/ToolSolderPaste.py:77 msgid "" "Tools pool from which the algorithm\n" "will pick the ones used for dispensing solder paste." msgstr "" -#: flatcamTools/ToolSolderPaste.py:90 +#: flatcamTools/ToolSolderPaste.py:92 msgid "" "This is the Tool Number.\n" "The solder dispensing will start with the tool with the biggest \n" @@ -13850,80 +14590,80 @@ msgid "" " with solder paste, the app will issue a warning message box." msgstr "" -#: flatcamTools/ToolSolderPaste.py:97 +#: flatcamTools/ToolSolderPaste.py:99 msgid "" "Nozzle tool Diameter. It's value (in current FlatCAM units)\n" "is the width of the solder paste dispensed." msgstr "" -#: flatcamTools/ToolSolderPaste.py:104 +#: flatcamTools/ToolSolderPaste.py:106 msgid "New Nozzle Tool" msgstr "" -#: flatcamTools/ToolSolderPaste.py:123 +#: flatcamTools/ToolSolderPaste.py:125 msgid "" "Add a new nozzle tool to the Tool Table\n" "with the diameter specified above." msgstr "" -#: flatcamTools/ToolSolderPaste.py:135 +#: flatcamTools/ToolSolderPaste.py:137 msgid "Generate solder paste dispensing geometry." msgstr "" -#: flatcamTools/ToolSolderPaste.py:154 +#: flatcamTools/ToolSolderPaste.py:156 msgid "STEP 1" msgstr "" -#: flatcamTools/ToolSolderPaste.py:156 +#: flatcamTools/ToolSolderPaste.py:158 msgid "" "First step is to select a number of nozzle tools for usage\n" "and then optionally modify the GCode parameters bellow." msgstr "" -#: flatcamTools/ToolSolderPaste.py:159 +#: flatcamTools/ToolSolderPaste.py:161 msgid "" "Select tools.\n" "Modify parameters." msgstr "" -#: flatcamTools/ToolSolderPaste.py:279 +#: flatcamTools/ToolSolderPaste.py:281 msgid "" "Feedrate (speed) while moving up vertically\n" " to Dispense position (on Z plane)." msgstr "" -#: flatcamTools/ToolSolderPaste.py:349 +#: flatcamTools/ToolSolderPaste.py:351 msgid "" "Generate GCode for Solder Paste dispensing\n" "on PCB pads." msgstr "" -#: flatcamTools/ToolSolderPaste.py:370 +#: flatcamTools/ToolSolderPaste.py:372 msgid "STEP 2" msgstr "" -#: flatcamTools/ToolSolderPaste.py:372 +#: flatcamTools/ToolSolderPaste.py:374 msgid "" "Second step is to create a solder paste dispensing\n" "geometry out of an Solder Paste Mask Gerber file." msgstr "" -#: flatcamTools/ToolSolderPaste.py:388 +#: flatcamTools/ToolSolderPaste.py:391 msgid "Geo Result" msgstr "" -#: flatcamTools/ToolSolderPaste.py:390 +#: flatcamTools/ToolSolderPaste.py:393 msgid "" "Geometry Solder Paste object.\n" "The name of the object has to end in:\n" "'_solderpaste' as a protection." msgstr "" -#: flatcamTools/ToolSolderPaste.py:399 +#: flatcamTools/ToolSolderPaste.py:402 msgid "STEP 3" msgstr "" -#: flatcamTools/ToolSolderPaste.py:401 +#: flatcamTools/ToolSolderPaste.py:404 msgid "" "Third step is to select a solder paste dispensing geometry,\n" "and then generate a CNCJob object.\n" @@ -13933,11 +14673,11 @@ msgid "" "and only after that you can generate an updated CNCJob." msgstr "" -#: flatcamTools/ToolSolderPaste.py:421 +#: flatcamTools/ToolSolderPaste.py:425 msgid "CNC Result" msgstr "" -#: flatcamTools/ToolSolderPaste.py:423 +#: flatcamTools/ToolSolderPaste.py:427 msgid "" "CNCJob Solder paste object.\n" "In order to enable the GCode save section,\n" @@ -13945,114 +14685,110 @@ msgid "" "'_solderpaste' as a protection." msgstr "" -#: flatcamTools/ToolSolderPaste.py:433 +#: flatcamTools/ToolSolderPaste.py:437 msgid "View GCode" msgstr "" -#: flatcamTools/ToolSolderPaste.py:435 +#: flatcamTools/ToolSolderPaste.py:439 msgid "" "View the generated GCode for Solder Paste dispensing\n" "on PCB pads." msgstr "" -#: flatcamTools/ToolSolderPaste.py:445 +#: flatcamTools/ToolSolderPaste.py:449 msgid "Save GCode" msgstr "" -#: flatcamTools/ToolSolderPaste.py:447 +#: flatcamTools/ToolSolderPaste.py:451 msgid "" "Save the generated GCode for Solder Paste dispensing\n" "on PCB pads, to a file." msgstr "" -#: flatcamTools/ToolSolderPaste.py:457 +#: flatcamTools/ToolSolderPaste.py:461 msgid "STEP 4" msgstr "" -#: flatcamTools/ToolSolderPaste.py:459 +#: flatcamTools/ToolSolderPaste.py:463 msgid "" "Fourth step (and last) is to select a CNCJob made from \n" "a solder paste dispensing geometry, and then view/save it's GCode." msgstr "" -#: flatcamTools/ToolSolderPaste.py:917 -msgid "Adding Nozzle tool cancelled. Tool already in Tool Table." -msgstr "" - -#: flatcamTools/ToolSolderPaste.py:923 +#: flatcamTools/ToolSolderPaste.py:922 msgid "New Nozzle tool added to Tool Table." msgstr "" -#: flatcamTools/ToolSolderPaste.py:966 +#: flatcamTools/ToolSolderPaste.py:965 msgid "Nozzle tool from Tool Table was edited." msgstr "" -#: flatcamTools/ToolSolderPaste.py:1024 +#: flatcamTools/ToolSolderPaste.py:1023 msgid "Delete failed. Select a Nozzle tool to delete." msgstr "" -#: flatcamTools/ToolSolderPaste.py:1030 +#: flatcamTools/ToolSolderPaste.py:1029 msgid "Nozzle tool(s) deleted from Tool Table." msgstr "" -#: flatcamTools/ToolSolderPaste.py:1086 +#: flatcamTools/ToolSolderPaste.py:1085 msgid "No SolderPaste mask Gerber object loaded." msgstr "" -#: flatcamTools/ToolSolderPaste.py:1104 +#: flatcamTools/ToolSolderPaste.py:1103 msgid "Creating Solder Paste dispensing geometry." msgstr "" -#: flatcamTools/ToolSolderPaste.py:1117 +#: flatcamTools/ToolSolderPaste.py:1116 msgid "No Nozzle tools in the tool table." msgstr "" -#: flatcamTools/ToolSolderPaste.py:1244 +#: flatcamTools/ToolSolderPaste.py:1242 msgid "Cancelled. Empty file, it has no geometry..." msgstr "" -#: flatcamTools/ToolSolderPaste.py:1248 +#: flatcamTools/ToolSolderPaste.py:1245 msgid "Solder Paste geometry generated successfully" msgstr "" -#: flatcamTools/ToolSolderPaste.py:1255 +#: flatcamTools/ToolSolderPaste.py:1252 msgid "Some or all pads have no solder due of inadequate nozzle diameters..." msgstr "" -#: flatcamTools/ToolSolderPaste.py:1269 +#: flatcamTools/ToolSolderPaste.py:1266 msgid "Generating Solder Paste dispensing geometry..." msgstr "" -#: flatcamTools/ToolSolderPaste.py:1289 +#: flatcamTools/ToolSolderPaste.py:1286 msgid "There is no Geometry object available." msgstr "" -#: flatcamTools/ToolSolderPaste.py:1294 +#: flatcamTools/ToolSolderPaste.py:1291 msgid "This Geometry can't be processed. NOT a solder_paste_tool geometry." msgstr "" -#: flatcamTools/ToolSolderPaste.py:1401 +#: flatcamTools/ToolSolderPaste.py:1392 msgid "ToolSolderPaste CNCjob created" msgstr "" -#: flatcamTools/ToolSolderPaste.py:1422 +#: flatcamTools/ToolSolderPaste.py:1411 msgid "SP GCode Editor" msgstr "" -#: flatcamTools/ToolSolderPaste.py:1434 flatcamTools/ToolSolderPaste.py:1439 -#: flatcamTools/ToolSolderPaste.py:1494 +#: flatcamTools/ToolSolderPaste.py:1423 flatcamTools/ToolSolderPaste.py:1428 +#: flatcamTools/ToolSolderPaste.py:1483 msgid "This CNCJob object can't be processed. NOT a solder_paste_tool CNCJob object." msgstr "" -#: flatcamTools/ToolSolderPaste.py:1464 +#: flatcamTools/ToolSolderPaste.py:1453 msgid "No Gcode in the object" msgstr "" -#: flatcamTools/ToolSolderPaste.py:1504 +#: flatcamTools/ToolSolderPaste.py:1493 msgid "Export GCode ..." msgstr "" -#: flatcamTools/ToolSolderPaste.py:1552 +#: flatcamTools/ToolSolderPaste.py:1541 msgid "Solder paste dispenser GCode file saved to" msgstr "" @@ -14060,27 +14796,27 @@ msgstr "" msgid "Gerber Objects" msgstr "" -#: flatcamTools/ToolSub.py:76 +#: flatcamTools/ToolSub.py:78 msgid "" "Gerber object from which to subtract\n" "the subtractor Gerber object." msgstr "" -#: flatcamTools/ToolSub.py:88 flatcamTools/ToolSub.py:140 +#: flatcamTools/ToolSub.py:91 flatcamTools/ToolSub.py:146 msgid "Subtractor" msgstr "" -#: flatcamTools/ToolSub.py:90 +#: flatcamTools/ToolSub.py:93 msgid "" "Gerber object that will be subtracted\n" "from the target Gerber object." msgstr "" -#: flatcamTools/ToolSub.py:97 +#: flatcamTools/ToolSub.py:100 msgid "Substract Gerber" msgstr "" -#: flatcamTools/ToolSub.py:99 +#: flatcamTools/ToolSub.py:102 msgid "" "Will remove the area occupied by the subtractor\n" "Gerber from the Target Gerber.\n" @@ -14088,85 +14824,85 @@ msgid "" "over the soldermask." msgstr "" -#: flatcamTools/ToolSub.py:117 +#: flatcamTools/ToolSub.py:120 msgid "Geometry Objects" msgstr "" -#: flatcamTools/ToolSub.py:128 +#: flatcamTools/ToolSub.py:133 msgid "" "Geometry object from which to subtract\n" "the subtractor Geometry object." msgstr "" -#: flatcamTools/ToolSub.py:142 +#: flatcamTools/ToolSub.py:148 msgid "" "Geometry object that will be subtracted\n" "from the target Geometry object." msgstr "" -#: flatcamTools/ToolSub.py:150 +#: flatcamTools/ToolSub.py:156 msgid "Checking this will close the paths cut by the Geometry subtractor object." msgstr "" -#: flatcamTools/ToolSub.py:153 +#: flatcamTools/ToolSub.py:159 msgid "Subtract Geometry" msgstr "" -#: flatcamTools/ToolSub.py:155 +#: flatcamTools/ToolSub.py:161 msgid "" "Will remove the area occupied by the subtractor\n" "Geometry from the Target Geometry." msgstr "" -#: flatcamTools/ToolSub.py:262 +#: flatcamTools/ToolSub.py:263 msgid "Sub Tool" msgstr "" -#: flatcamTools/ToolSub.py:278 flatcamTools/ToolSub.py:483 +#: flatcamTools/ToolSub.py:284 flatcamTools/ToolSub.py:489 msgid "No Target object loaded." msgstr "" -#: flatcamTools/ToolSub.py:281 +#: flatcamTools/ToolSub.py:287 msgid "Loading geometry from Gerber objects." msgstr "" -#: flatcamTools/ToolSub.py:293 flatcamTools/ToolSub.py:498 +#: flatcamTools/ToolSub.py:299 flatcamTools/ToolSub.py:504 msgid "No Subtractor object loaded." msgstr "" -#: flatcamTools/ToolSub.py:325 +#: flatcamTools/ToolSub.py:331 msgid "Processing geometry from Subtractor Gerber object." msgstr "" -#: flatcamTools/ToolSub.py:346 +#: flatcamTools/ToolSub.py:352 msgid "Parsing geometry for aperture" msgstr "" -#: flatcamTools/ToolSub.py:407 +#: flatcamTools/ToolSub.py:413 msgid "Finished parsing geometry for aperture" msgstr "" -#: flatcamTools/ToolSub.py:452 flatcamTools/ToolSub.py:655 +#: flatcamTools/ToolSub.py:458 flatcamTools/ToolSub.py:661 msgid "Generating new object ..." msgstr "" -#: flatcamTools/ToolSub.py:456 flatcamTools/ToolSub.py:659 flatcamTools/ToolSub.py:740 +#: flatcamTools/ToolSub.py:462 flatcamTools/ToolSub.py:665 flatcamTools/ToolSub.py:746 msgid "Generating new object failed." msgstr "" -#: flatcamTools/ToolSub.py:461 flatcamTools/ToolSub.py:665 +#: flatcamTools/ToolSub.py:467 flatcamTools/ToolSub.py:671 msgid "Created" msgstr "" -#: flatcamTools/ToolSub.py:512 +#: flatcamTools/ToolSub.py:518 msgid "Currently, the Subtractor geometry cannot be of type Multigeo." msgstr "" -#: flatcamTools/ToolSub.py:557 +#: flatcamTools/ToolSub.py:563 msgid "Parsing solid_geometry ..." msgstr "" -#: flatcamTools/ToolSub.py:559 +#: flatcamTools/ToolSub.py:565 msgid "Parsing solid_geometry for tool" msgstr "" @@ -14174,213 +14910,254 @@ msgstr "" msgid "Object Transform" msgstr "" -#: flatcamTools/ToolTransform.py:82 +#: flatcamTools/ToolTransform.py:79 msgid "" "Rotate the selected object(s).\n" "The point of reference is the middle of\n" "the bounding box for all selected objects." msgstr "" -#: flatcamTools/ToolTransform.py:100 flatcamTools/ToolTransform.py:122 +#: flatcamTools/ToolTransform.py:100 flatcamTools/ToolTransform.py:121 msgid "" "Angle for Skew action, in degrees.\n" "Float number between -360 and 360." msgstr "" -#: flatcamTools/ToolTransform.py:111 flatcamTools/ToolTransform.py:133 +#: flatcamTools/ToolTransform.py:110 flatcamTools/ToolTransform.py:131 msgid "" "Skew/shear the selected object(s).\n" "The point of reference is the middle of\n" "the bounding box for all selected objects." msgstr "" -#: flatcamTools/ToolTransform.py:160 flatcamTools/ToolTransform.py:181 +#: flatcamTools/ToolTransform.py:160 flatcamTools/ToolTransform.py:180 msgid "" "Scale the selected object(s).\n" "The point of reference depends on \n" "the Scale reference checkbox state." msgstr "" -#: flatcamTools/ToolTransform.py:229 flatcamTools/ToolTransform.py:250 +#: flatcamTools/ToolTransform.py:229 flatcamTools/ToolTransform.py:249 msgid "" "Offset the selected object(s).\n" "The point of reference is the middle of\n" "the bounding box for all selected objects.\n" msgstr "" -#: flatcamTools/ToolTransform.py:268 flatcamTools/ToolTransform.py:274 +#: flatcamTools/ToolTransform.py:269 flatcamTools/ToolTransform.py:274 msgid "Flip the selected object(s) over the X axis." msgstr "" -#: flatcamTools/ToolTransform.py:299 +#: flatcamTools/ToolTransform.py:298 msgid "Ref. Point" msgstr "" -#: flatcamTools/ToolTransform.py:351 +#: flatcamTools/ToolTransform.py:349 msgid "" "Create the buffer effect on each geometry,\n" -"element from the selected object." +"element from the selected object, using the distance." msgstr "" -#: flatcamTools/ToolTransform.py:498 +#: flatcamTools/ToolTransform.py:375 +msgid "" +"Create the buffer effect on each geometry,\n" +"element from the selected object, using the factor." +msgstr "" + +#: flatcamTools/ToolTransform.py:480 +msgid "Buffer D" +msgstr "" + +#: flatcamTools/ToolTransform.py:481 +msgid "Buffer F" +msgstr "" + +#: flatcamTools/ToolTransform.py:558 msgid "Rotate transformation can not be done for a value of 0." msgstr "" -#: flatcamTools/ToolTransform.py:537 flatcamTools/ToolTransform.py:560 +#: flatcamTools/ToolTransform.py:597 flatcamTools/ToolTransform.py:620 msgid "Scale transformation can not be done for a factor of 0 or 1." msgstr "" -#: flatcamTools/ToolTransform.py:575 flatcamTools/ToolTransform.py:585 +#: flatcamTools/ToolTransform.py:635 flatcamTools/ToolTransform.py:645 msgid "Offset transformation can not be done for a value of 0." msgstr "" -#: flatcamTools/ToolTransform.py:608 +#: flatcamTools/ToolTransform.py:677 msgid "No object selected. Please Select an object to rotate!" msgstr "" -#: flatcamTools/ToolTransform.py:636 +#: flatcamTools/ToolTransform.py:703 msgid "CNCJob objects can't be rotated." msgstr "" -#: flatcamTools/ToolTransform.py:644 +#: flatcamTools/ToolTransform.py:711 msgid "Rotate done" msgstr "" -#: flatcamTools/ToolTransform.py:649 flatcamTools/ToolTransform.py:724 -#: flatcamTools/ToolTransform.py:779 flatcamTools/ToolTransform.py:838 -#: flatcamTools/ToolTransform.py:874 flatcamTools/ToolTransform.py:910 +#: flatcamTools/ToolTransform.py:714 flatcamTools/ToolTransform.py:784 +#: flatcamTools/ToolTransform.py:834 flatcamTools/ToolTransform.py:890 +#: flatcamTools/ToolTransform.py:922 flatcamTools/ToolTransform.py:958 msgid "Due of" msgstr "" -#: flatcamTools/ToolTransform.py:649 flatcamTools/ToolTransform.py:724 -#: flatcamTools/ToolTransform.py:779 flatcamTools/ToolTransform.py:838 -#: flatcamTools/ToolTransform.py:874 flatcamTools/ToolTransform.py:910 +#: flatcamTools/ToolTransform.py:714 flatcamTools/ToolTransform.py:784 +#: flatcamTools/ToolTransform.py:834 flatcamTools/ToolTransform.py:890 +#: flatcamTools/ToolTransform.py:922 flatcamTools/ToolTransform.py:958 msgid "action was not executed." msgstr "" -#: flatcamTools/ToolTransform.py:661 +#: flatcamTools/ToolTransform.py:726 msgid "No object selected. Please Select an object to flip" msgstr "" -#: flatcamTools/ToolTransform.py:696 +#: flatcamTools/ToolTransform.py:759 msgid "CNCJob objects can't be mirrored/flipped." msgstr "" -#: flatcamTools/ToolTransform.py:734 +#: flatcamTools/ToolTransform.py:794 msgid "Skew transformation can not be done for 0, 90 and 180 degrees." msgstr "" -#: flatcamTools/ToolTransform.py:739 +#: flatcamTools/ToolTransform.py:799 msgid "No object selected. Please Select an object to shear/skew!" msgstr "" -#: flatcamTools/ToolTransform.py:761 +#: flatcamTools/ToolTransform.py:819 msgid "CNCJob objects can't be skewed." msgstr "" -#: flatcamTools/ToolTransform.py:774 +#: flatcamTools/ToolTransform.py:831 msgid "Skew on the" msgstr "" -#: flatcamTools/ToolTransform.py:774 flatcamTools/ToolTransform.py:834 -#: flatcamTools/ToolTransform.py:869 +#: flatcamTools/ToolTransform.py:831 flatcamTools/ToolTransform.py:887 +#: flatcamTools/ToolTransform.py:919 msgid "axis done" msgstr "" -#: flatcamTools/ToolTransform.py:791 +#: flatcamTools/ToolTransform.py:846 msgid "No object selected. Please Select an object to scale!" msgstr "" -#: flatcamTools/ToolTransform.py:824 +#: flatcamTools/ToolTransform.py:877 msgid "CNCJob objects can't be scaled." msgstr "" -#: flatcamTools/ToolTransform.py:834 +#: flatcamTools/ToolTransform.py:887 msgid "Scale on the" msgstr "" -#: flatcamTools/ToolTransform.py:846 +#: flatcamTools/ToolTransform.py:898 msgid "No object selected. Please Select an object to offset!" msgstr "" -#: flatcamTools/ToolTransform.py:855 +#: flatcamTools/ToolTransform.py:905 msgid "CNCJob objects can't be offset." msgstr "" -#: flatcamTools/ToolTransform.py:869 +#: flatcamTools/ToolTransform.py:919 msgid "Offset on the" msgstr "" -#: flatcamTools/ToolTransform.py:881 +#: flatcamTools/ToolTransform.py:929 msgid "No object selected. Please Select an object to buffer!" msgstr "" -#: flatcamTools/ToolTransform.py:884 +#: flatcamTools/ToolTransform.py:932 msgid "Applying Buffer" msgstr "" -#: flatcamTools/ToolTransform.py:888 +#: flatcamTools/ToolTransform.py:936 msgid "CNCJob objects can't be buffered." msgstr "" -#: flatcamTools/ToolTransform.py:905 +#: flatcamTools/ToolTransform.py:953 msgid "Buffer done" msgstr "" -#: tclCommands/TclCommandBbox.py:74 tclCommands/TclCommandNregions.py:73 +#: tclCommands/TclCommandBbox.py:76 tclCommands/TclCommandNregions.py:75 msgid "Expected FlatCAMGerber or FlatCAMGeometry, got" msgstr "" -#: tclCommands/TclCommandBounds.py:64 tclCommands/TclCommandBounds.py:68 +#: tclCommands/TclCommandBounds.py:67 tclCommands/TclCommandBounds.py:71 msgid "Expected a list of objects names separated by comma. Got" msgstr "" -#: tclCommands/TclCommandBounds.py:79 +#: tclCommands/TclCommandBounds.py:82 msgid "TclCommand Bounds done." msgstr "" -#: tclCommands/TclCommandCopperClear.py:242 tclCommands/TclCommandPaint.py:240 -msgid "Expected -box ." -msgstr "" - -#: tclCommands/TclCommandCopperClear.py:251 tclCommands/TclCommandPaint.py:249 -#: tclCommands/TclCommandScale.py:75 +#: tclCommands/TclCommandCopperClear.py:256 tclCommands/TclCommandPaint.py:261 +#: tclCommands/TclCommandScale.py:81 msgid "Could not retrieve box object" msgstr "" -#: tclCommands/TclCommandCopperClear.py:273 -msgid "" -"None of the following args: 'ref', 'all' were found or none was set to 1.\n" -"Copper clearing failed." +#: tclCommands/TclCommandCopperClear.py:279 +msgid "Expected either -box or -all." msgstr "" -#: tclCommands/TclCommandPaint.py:217 +#: tclCommands/TclCommandGeoCutout.py:148 +msgid "The name of the object for which cutout is done is missing. Add it and retry." +msgstr "" + +#: tclCommands/TclCommandGeoCutout.py:190 +msgid "Gaps value can be only one of: 'lr', 'tb', '2lr', '2tb', 4 or 8." +msgstr "" + +#: tclCommands/TclCommandGeoCutout.py:302 tclCommands/TclCommandGeoCutout.py:360 +msgid "Any-form Cutout operation finished." +msgstr "" + +#: tclCommands/TclCommandGeoCutout.py:366 +msgid "Cancelled. Object type is not supported." +msgstr "" + +#: tclCommands/TclCommandHelp.py:74 +msgid "Available commands:" +msgstr "" + +#: tclCommands/TclCommandHelp.py:112 +msgid "Type help for usage." +msgstr "" + +#: tclCommands/TclCommandHelp.py:112 +msgid "Example: help open_gerber" +msgstr "" + +#: tclCommands/TclCommandPaint.py:229 msgid "Expected -x and -y ." msgstr "" -#: tclCommands/TclCommandPaint.py:268 +#: tclCommands/TclCommandPaint.py:254 +msgid "Expected -box ." +msgstr "" + +#: tclCommands/TclCommandPaint.py:279 msgid "" -"There was none of the following args: 'ref', 'single', 'all'.\n" +"None of the following args: 'box', 'single', 'all' were used.\n" "Paint failed." msgstr "" -#: tclCommands/TclCommandScale.py:95 -msgid "Expected -origin or -origin or -origin
." +#: tclCommands/TclCommandScale.py:106 +msgid "" +"Expected -origin or -origin or -origin
or - origin 3.0,4.2." msgstr "" -#: tclCommands/TclCommandScale.py:104 +#: tclCommands/TclCommandScale.py:119 msgid "Expected -x -y ." msgstr "" -#: tclCommands/TclCommandSetOrigin.py:91 +#: tclCommands/TclCommandSetOrigin.py:95 msgid "Expected a pair of (x, y) coordinates. Got" msgstr "" -#: tclCommands/TclCommandSetOrigin.py:98 +#: tclCommands/TclCommandSetOrigin.py:102 msgid "Origin set by offsetting all loaded objects with " msgstr "" -#: tclCommands/TclCommandSubtractRectangle.py:58 +#: tclCommands/TclCommandSubtractRectangle.py:62 msgid "No Geometry name in args. Provide a name and try again." msgstr "" diff --git a/requirements.txt b/requirements.txt index 0f1f6d04..89cda8e4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,8 @@ # This file contains python only requirements to be installed with pip # Python packages that cannot be installed with pip (e.g. PyQt5, GDAL) are not included. +# For Windows GDAL wheel can be found here: https://www.lfd.uci.edu/~gohlke/pythonlibs/#gdal # Usage: pip3 install -r requirements.txt + pyqt5>=5.12.1 numpy>=1.16 matplotlib>=3.1 @@ -13,7 +15,7 @@ dill rtree pyopengl vispy -ortools +ortools>=7.0 svg.path simplejson shapely>=1.3 @@ -24,4 +26,5 @@ lxml ezdxf qrcode>=6.1 reportlab>=3.5 -svglib \ No newline at end of file +svglib +gdal \ No newline at end of file From c9ba61dea981d5432467ecfc9c5fffff3b8703c4 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 24 Apr 2020 14:21:57 +0300 Subject: [PATCH 204/209] - updated some of the icons in the dark_resources folder (some added, some modified) --- CHANGELOG.md | 1 + FlatCAMApp.py | 2 +- share/dark_resources/about32.png | Bin 0 -> 1996 bytes share/dark_resources/align16.png | Bin 0 -> 475 bytes share/dark_resources/align32.png | Bin 0 -> 558 bytes share/dark_resources/black32.png | Bin 183 -> 194 bytes share/dark_resources/extract_drill16.png | Bin 0 -> 492 bytes share/dark_resources/extract_drill32.png | Bin 0 -> 714 bytes share/dark_resources/file32.png | Bin 502 -> 497 bytes share/dark_resources/film32.png | Bin 0 -> 544 bytes share/dark_resources/flatcam_icon128.png | Bin 1761 -> 1706 bytes share/dark_resources/geometry32.png | Bin 0 -> 732 bytes share/dark_resources/invert16.png | Bin 0 -> 411 bytes share/dark_resources/invert32.png | Bin 0 -> 534 bytes share/dark_resources/link16.png | Bin 0 -> 589 bytes share/dark_resources/locate16.png | Bin 0 -> 591 bytes share/dark_resources/locate32.png | Bin 0 -> 933 bytes share/dark_resources/origin2_16.png | Bin 0 -> 540 bytes share/dark_resources/origin2_32.png | Bin 0 -> 807 bytes share/dark_resources/punch16.png | Bin 0 -> 542 bytes share/dark_resources/punch32.png | Bin 0 -> 767 bytes share/dark_resources/white32.png | Bin 0 -> 203 bytes 22 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 share/dark_resources/about32.png create mode 100644 share/dark_resources/align16.png create mode 100644 share/dark_resources/align32.png create mode 100644 share/dark_resources/extract_drill16.png create mode 100644 share/dark_resources/extract_drill32.png create mode 100644 share/dark_resources/film32.png create mode 100644 share/dark_resources/geometry32.png create mode 100644 share/dark_resources/invert16.png create mode 100644 share/dark_resources/invert32.png create mode 100644 share/dark_resources/link16.png create mode 100644 share/dark_resources/locate16.png create mode 100644 share/dark_resources/locate32.png create mode 100644 share/dark_resources/origin2_16.png create mode 100644 share/dark_resources/origin2_32.png create mode 100644 share/dark_resources/punch16.png create mode 100644 share/dark_resources/punch32.png create mode 100644 share/dark_resources/white32.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bef25d7..6b0b4b10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ CHANGELOG for FlatCAM beta - update the language template strings.pot and updated the Romanian translation - updated the Readme file with the steps for installation for MacOS - updated the requirements.txt file +- updated some of the icons in the dark_resources folder (some added, some modified) 23.04.2020 diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 21af0c26..a90fbd68 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -145,7 +145,7 @@ class App(QtCore.QObject): # ################################### Version and VERSION DATE ################################################## # ############################################################################################################### version = 8.992 - version_date = "2020/03/27" + version_date = "2020/05/01" beta = True engine = '3D' diff --git a/share/dark_resources/about32.png b/share/dark_resources/about32.png new file mode 100644 index 0000000000000000000000000000000000000000..91c2caf1c3c32a52dc722f3900addb264a9c7260 GIT binary patch literal 1996 zcmV;-2Q&DIP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 zVoOIv0RI600RN!9r;`8x2IEOYK~z}7otIl|9aj~GzqR+woSTnN9GW<`vY#wIL%p9L%2tCr4XRJN@|JT3%wf5e^ZT`j|KD-yq11Q-k z=&iY2W(x>~Vr9k{Gh=Yid9B(zQ*S(d1ZV-??W`;R19TnmooqJs-01Kfx#3L%WHTvh zO(<1eT-QS@FkXw5VwL=@5=+a4LZe=KxqSWffw@z^Tm;-tL}2{OzulY7rVsACXDl~5 zvVqwfb>^3wEZ%B$%rn8?zLb!*A!);{l_CpE`9iHY_w3ZMXC{HhT8c<-@ZTNUv2Ezd z`*&^UU-J#7=IS(CrW;tKa{&PnpGZP^EZtnDSeSqH%Io`{0?NJAkY3=s?;C$|WOx&2 zu9R3QyOv4uN+%Kl!_@Jz9OQcw21$%we47`je7aR zKb-{XfUy9w+0=8JM>cTcpDSIF6M_dyh)}9|ym4wJl-mD)oMbq?!$5YrkL1AE~5?;iwe7VyCE-~coEW@kNjMD8y*u{p_S#xtucmvYTRl%N6=O88AQr|B8Q zfRZGM+~{s#5-2JZI|tVFg&ocS60hq(_FBW^hlgj`_u^C+0c|NPOQGAt)>yXxY}p#i z)@Vy1mLlaOu+r&v*vMG3_8UpsYf%GNZ+8 zX-B_YXi{yMFbXA|k*$>i6{w@M|4qCr`sy2u2bq+iRxK^IzqJfzM#OAE;Kt1c^`?nB znIg=o3ObuoYZGWIAxfcCOo2dt;~5eO7t^XQ;BQKvWsH07=1Tcnuj2d9fnFAwOBGE`WO z#e0~MgDfL6U$c)3=u(4UI(CJ}=u`ZW}2n=`J06+~|bN^Ba? z6o*72k7!V!4o+oPQR+4e31$GO1vuwzvP^iAyj{UJNOWv?q)T9yRH($QvPM<&yu z*>se1TVXjC**?w0kmlNSiIc}qpE&pH2loT>z#LE_IHt!Br3Pr_FCTep{rE$7Y1{cU zl7My#)={40tyw9BXcZdKvJ`_kVWi*V?E5!4{qETl=YR9ieqaH(9tU4dpiQEgzx3Lh znZbKLPGtH&k7!4x9B`nRowjz5L!UuCf&hy;v#blKy93Tq}Y~AzYM-uBscU!4}aqXlxCDZ+bq7=1idC|D_ zg=RHBRa?4xHr8ZT0=F0Wf3Ide)JOm+{4;$zcz0qcbOVq&QIn|#@1N{)x`rYaU05UK!IV~_bEipAz zF*rIiH99pkD=;)VFfe?iwD|x403~!qSaf7zbY(hiZ)9m^c>ppnF*z+TIV~|YR53U@ eGc`IjG%GMPIxsK|`3yw>00007&6$m|WnB|O z#Gi*hP=2bb6ZF7Xc+RF+!B^V$8@JTxOJp_m@nuLYlMBmR=5_UG+tzJ@9jm@y@5t?l z`{Idhvd8oTzvhNl{a+epV%*NYPL@N%h%VN ze~5mU)iKt4VRBw@1<=u|C9V-ADTyViR>?)FK#IZ0z{o(?z(m)`B*f6b%EZLV&`8_B zz{nC}Q!>*kacg+JM&~L}gCxj?;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7 V^x5xhq=1STJYD@<);T3K0RRNMpAP^4 literal 0 HcmV?d00001 diff --git a/share/dark_resources/align32.png b/share/dark_resources/align32.png new file mode 100644 index 0000000000000000000000000000000000000000..4249e35aaa3bef62366a3f32f360d9e5827b2c4f GIT binary patch literal 558 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`KgTaOtrqTue#_3jOhPaSZV|es`*^-(d%VR(s`B znL5v9${LTb{t)Cn=Uc>hsc53d$`gze6x0y^)DZua`YFYj$_+56r|aj{?Vru03)a8NCA zjVMV;EJ?LWE=mPb3`Pb<2D%0&x<)1;h6Yw9W>y9!+6D$z1_p+8g&$Bfba4!+n3J4vfT73B z;{b!kf+tNZQzRrJLMO1!VUd^-qaDz2XvKjC0tq3G&#WaA+*Fy3t5Oy-GDvdf#Y?B> Qi-OGeboFyt=akR{06+vZVgLXD delta 167 zcmX@axSer=L_G%^0|P^GRn-?DRp;sA7!u+BcKT_-1_d70$xJ??UjN_zSjoiQu~_2x z`4_qq4=-l8w`tC_m(LGRuf5o3#J|obHF;C7almdKI;Vst02c;B)&Kwi diff --git a/share/dark_resources/extract_drill16.png b/share/dark_resources/extract_drill16.png new file mode 100644 index 0000000000000000000000000000000000000000..ca38b16d3f1b44bf4f3c60b8c5e43d25dd2975a9 GIT binary patch literal 492 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|T2M2s2)r5VjjA$X?><>&pIwMS{y*$e*=N4=8ls)5S4F<9zAFjaf{N5-s-r zevaJIuAc-f6@PIwiG|O&C(fa=jKi+AbXQ3w&+OMZI!CS@3KL{HY1%YvWHRhw;uY>N1uO!pqS6kzIpdpn<6zp`nG* zQ>T20^7)aH9+G=3?R#pp%n#%1p*4LjCYC~lr*2Pet>leYt<@-5-rz0utL4qY_U_`3 z>$_Tbs_Pin{hrsF#g(a23iPUKiEBhjN@7W>RdP`(kYX@0Ff!0JFwr$K2{AOVGBvd_ qw9qy%ure?ZI9q=cMMG|WN@iLmZVibOj;8`OFnGH9xvXcR literal 0 HcmV?d00001 diff --git a/share/dark_resources/extract_drill32.png b/share/dark_resources/extract_drill32.png new file mode 100644 index 0000000000000000000000000000000000000000..16f1dd72baacd60185ec01b0d19f368d95ebeae5 GIT binary patch literal 714 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1DhWRGhUkzwi_tOUgGKN%Kn5!g3DaYBV(620|Vn;PZ!4!kK;$D?9UDk6gh7H zUGkR5&hSMP{Kdp$ZK4kTJ z`NR#GsY`oZ7^iPpu_(Gwy!~s)XDPoMb!ShV@+zJ?>vpSbk;#qDy)SChZXPf1Oz$ab z=3motdj{u2znZ6}?lB)Ps%Oe~@ z1J?c3u?v(FCo^ul^+KHW0mqJx8~*x<$4+_aUq0X3xubOQ>OGydul1e=JhjZesOMuK zsvuF^vX}XR-*0UNr<6=m8q$fk&(86ffW!Lsh6N=$jwj5OsmAL!8?Ec Q37`fBPgg&ebxsLQ0Bm6#00000 literal 0 HcmV?d00001 diff --git a/share/dark_resources/file32.png b/share/dark_resources/file32.png index 2a034650c7c24eade2ae5e93f6d18a9a4d67e36d..a62c673086fcc95c55ace9e3b81c20ec01a6c48a 100644 GIT binary patch delta 321 zcmeyy{E>M=cfABRuem~&oH_#o!#+Z-aO99x@QwqrlbDb40@ArKT;L=;{rO zQ?{&eeBQ-4L&4gH+gsyOpi76pTxYUNbIrPYmw(pmTh5*$vVQ3YT(f zZLiA0XN}y6#XFQ{C>RKG?G)$Q=`E1)E2damT)|bC(oGdeQfpezc z4yJo*EjNxz7`Vy463bxy8elIY@tQinPE6uLKDjGg4ld0k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKpuOE zr>`sf6BY?>K4z`YI|CUQ7&Say978;gznyBBb=X0`^*-D5=HkW%=9fH-Z#kcM)!s4@ z+t*Mk{F0;Wp^Q@R2hJQ}4{?JXB|C5XclA#6;`MrYH*MRG!+RwEtqDFhm-Foo7Cj9Q z<|h|V&pXV}+rLxhhVz<+1&*SwuNUkJW4lutuvSzx;{qpx>4e!@=U3+2GDJ9>(fRe_ z=+YO8fe)8%RGGlm|6VJCsaW{XoK$|rJf9>5F%esq!bfX39tDXD9pafW%WHU8>&c z2Gh;lP0i=bqZ1C#myXW;npE`IH9FVYT&~f5o{z5$6ZgB{4ZrPP2%Jl6`G1dHHIpmf zhCiS>!EdIV-|@P2$@{;@zj=8~K<7@w31Bd)mbgZgq$HN4S|t~y0x1R~10w@n0~1{% zlMq8gD?<}217mFi11kfAn76NhF@&TcH$NpatrE8e-3>t&Kn)C@u6{1-oD!M<5ue5n literal 0 HcmV?d00001 diff --git a/share/dark_resources/flatcam_icon128.png b/share/dark_resources/flatcam_icon128.png index 893bbf379b9d56200f3f5179501ab6bb94eb2df1..2ad0261ea1f7cd5a538a19ce0e27d05e93bf6e40 100644 GIT binary patch delta 1494 zcma)+c{J1s0LOnn<7f;s?vdn7S~+GyS}_cfduVmZ%m|Sq%06^BGP$8Vuv(Ok+#g7wxmxoIRlG}iw=Xj zrc|mA$24qqyLAeRxjD-$0A)nuEsAsKDt-bkaKCd>{3$0a*R07sHU$BvRV?C+1 zapM4HC64vVE?8m)eOg9)IIyJEo(a@6&BdL~6W(H)J%`qQYi9(-Q=_e*x3bxpVDsyy zYuPnLkyWLKkf-uoye<}hF!MS>hLJBWrE1iD)2k2APpT<{4u>A)YqB^AI70(Y!HGDO z>d#7(k(U=glU<&E$9TJ*OV^LP(AfjWF#uZK>Czd!h#PH5^H^WvU22MeIGZq`r>+Dr z8DSmU5HrrYO;IQrWckwjdfQU1P5i5HoO$80M`OqBK^-_o;|oIlnIYsO$NE~J(Ezdn zs82GNNxQXSo3!P(X=IpMH{tySG2RA_TuLlaJc2$jF7VKDk2t7M9$Vj|XMX?@6^4H+ z;#S9MGzrjRS5UK>_3lO0Pjb%t8aM0psYAr%2-e4)_MqhL%>ha1jiy(t7qB@7lK4w& ze%0L9_oO$_zL!x2`HeTFoqTrLPqnuCPy15Hu#s(_NW%AUpK-~lL0erB)n3M!)!r>L zesm)+eZ$n1*`kl2F-Dwq z-nRv#{REf{Gmvzd^sSk6p2Z**Fnq4j`=G_j}7F=eZT z!m$~#a7uBn7|$xFpaP|4Cc$$X9N+AjrR-=^98JFV`R6MmpJ|w5*>W*sFIWvj*mPk4 z(6g4#9r9Kd95DK8PJ+9T;=1hx#@0?n15YeVmG;eI3Y|yyqc?bKHkX@t;(>h|REns^ zhP%1AGh!4l{3j9wtr{=oUSv}miqO*X-MIS;ZPDJqq2_CadE>XGaL6ee&Cdkd<8Uyj zz3ws>1e$u4=CIR*Fqa0P=A}|K`Bg40uaS(e@19f)ZI+V2tL@4LXV99arxhQN2`#)EndKKFYTh_e2;_a+SgyKZ z`}w^KUopYn*@yF|oVd6k>j>jc;wJsxbBj!}$JtYSUdyPm$z9%=U(3oSgarFjRTQlyRL zf5_Pu@JFbuD;iOAcOtt(;S~zGCC6?Wr8{s!6h8<7@+G^&0w_UfdG*t<5dgQXB}S2Q zp`d|n-6CNd>9qR_Dvss~{;&b)R{;(SmKOgXIm46C`0z<|u&>?#4A!aPKEm>zFl|t- z$NoORm5%*86p{DEwaEJ!PQr?^Ck$Nicw@YQG5+Ln9L^Yr>wvmiGN6Ae^=h}lj9Ov* EpZ|KfZ2$lO delta 1572 zcma)#XHe630ET}dESV~ahy(&v6h$B)Gl8%SQ#RCrvJ?>og%HD(f1pJqqF4c=G86-b zl|##xl}Z9$QI;qeWF&~JC;^GYRHa_qPaSuCzdU!(d-uLo$~@(3mmy`OD&~s|YY+gL zTDScU0g2pqMM2SsKvZ`pWQY(UeDe{6mLJ{Q5dn{4%qvZH?(8ljna@WAjyW;GacQ(!*WVOzUrq7RnrWXoow4OjB?@J9F}2e-VR2j2 zmPZGm{%1A@@gYf88;Hz_S!Oxc?FtPAj0SC+yN^TD%~ki*-g~Z`ldtD;*1J1mbn*OG zGz17{jFi!C3?12XUsK*H&yRjEyf7s(;#Q?lmrItV!Nw}KZA_|vhrP22XVj0RQN@$enbl>DiOyDvFGn{`wyZK5LK}k6 z){xYc^Y{)mZ6GVKk$o%G>!CqG+JmGZaVo|5x(k+v=Dpe)1z1rUZO4GdM44;v^ ze&X;fEYO`%bVQ;pHMBg=MAxO+EY+$viG#|g;qa@4B87lmkbv=(0uz4U?vKUCvLC)} zJ`Yd{iyS#HVXDQ4n;!}fDk1M-K}h?TIL9`^60w3>E%L(6z@jP}QQXgLvKnu)(uofL zC0i5a?U*A}E4?VkV(;=FNvSU9Tygy%Qf<}7oivvgD~}6&kOv#;?V z@8^;JYUrs~a|2B&(WzeJ&XMDVi72U~cD8)DSU zk22B4Fffp@`HaIF8`qxIKA|D-DD8vUD5{2@?LIlOD9UcqGb7_v!!U8z>!dvs^;BW8 zy4zMgDkp0Sz3AcmQgpA@owY1=J2PYjy<6IpgLmU4Sn&=Be|3^i5lV@-D4 zA=EtPD0i(UT`-;Nw3X$6D!M&){I+&hSB5DlQ+Dlzz%>gUL%2PcQm+J};6s1f|CCG( zRh_P=xZteC&^7NcWSfSsL}ki+dOd;|=@+x7fKb=_E%jr`NAP zy}j(j`q$C__5Z8TCI9GE11*DoA2ciC=Ikin7;C6C@Z_(!t;189hdJon zbRvutfjv%)_y%B#F~t~S%nVJ;0x%e?i8;i^1@(tm5-rWl_j~Gk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr16wo*Gj6g|ZU+jomw5WRvOi&w;O3LOKG8v&fq`+Ar;B5V$MLt5_j=0&iX5%K zJ~Op*$H&En>x2>=&n)X$q#(%o$bG}sjgv&2{xwb!(+pxs%9IUI@r@F6Ikf7pSdxxN zpn#C+MYobL@yP4h3vbRex3*H=_$7u-@A=*0dvkx^Yj*!*zUIW#vpfbaP063W-&d18 z&2)ru#f*j5Vudyb-8X&`?r&26rs|-2Ew@a7f6%9xEt{os45msO&#b-mG{ASA_cqNV zmh3AyUfX#lOMZ_PJ+{8s`pkosb5_jvE?iO?q~OG^t+BgN+qJ{h;041hrXQ+$3-y`~ z>OV+lxZlsqzFk7+)2b4)^D7tWUWgLsn00U^>)}nyJYP=S&+zAB)J>hq>Pvp8p4g^( zR9L38#5q3b>>8_A8S1=eRzK#HR%?E;SZwW@O0L#=$)!5I2abH@oFP%teW#;xM>@yX z550No&+PTEys_x$fB$(k-V0xC-eatNM=|ZK(NDS8I`?bO$u*zuerdjM`BjgmeJ9uq zp6@r>yJ@{*)nmiIA50H$#T(0)@nqf0Psn(4=HdaSZ@zn$xphsQ)B5$n(TZ237_JwGuZDqiD#@PsvQH#I1qHH35_oB|$a>=ckpFCl;kLl$V$5 gW#(lUCnpx9>g5-u&wghk1ysb~>FVdQ&MBb@0IqBs&Hw-a literal 0 HcmV?d00001 diff --git a/share/dark_resources/invert16.png b/share/dark_resources/invert16.png new file mode 100644 index 0000000000000000000000000000000000000000..52e8acbf3306706c8b735771a64213743a7770ce GIT binary patch literal 411 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{Xiaj ziKnkC`x6!kE(4u|s$ZReLW@0J978nDFP&(}*AyVY%I@rZNYbL+tuJBqG%0lWD;U%U}a)qWn!XjU|?lnu==n6P81Ef`6-!cmAEzBTJRkd Ox(uGKelF{r5}E*kH;U~5 literal 0 HcmV?d00001 diff --git a/share/dark_resources/invert32.png b/share/dark_resources/invert32.png new file mode 100644 index 0000000000000000000000000000000000000000..7840e6832fbfd8e0232b43a72d20c1ecf086f288 GIT binary patch literal 534 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKpuOE zr>`sf6BY?B1H(niGiNg}Fv@wlIEHu}e>>IM@34bF+kRKQ=MpTIPK(?haoI#Q?O-fF zv1?&V7x#n+^tJiUJbmd*l zsgO+CmfF(GdE`_wKhwsLcb*%Se$KVzUhrgzB$LO}!;HCm!>)gg@f8nVEWUMBZu#b@ z?6*msd`}v}m!E2WQ#8A_)2QeH!?ulgT(eu1U)&D*yg%=@hh(3?>j#`)SM}e%nt6}o zKBvW-r-CzBWK8-KCNvyY>VL52?ZNiLHr)#(jk*p#owwe=T5Cy~Rx`uDL!mn6dP};b zXIiNX_pM0Y=_-=f=)LpV451$nX8H#`(+)g7kIOlJ>5&iB@#+6KexJFP#5di1neg@b zdrv+4fByvkqRJftb{~#^0tTLHiEBhjN@7W>RdP`(kYX@0Ff!0JFwr$K2{AOVGO@5S qvD7v&ure?>rKMMiq9HdwB{QuOw}##2(~bf)FnGH9xvXrJ literal 0 HcmV?d00001 diff --git a/share/dark_resources/link16.png b/share/dark_resources/link16.png new file mode 100644 index 0000000000000000000000000000000000000000..d46c2a2e194825ad6f4fced1febf50a1ae281f02 GIT binary patch literal 589 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+uenMVO6iP5s=4O z;1OBOz`%C|gc+x5^GO2**-JcqUD=71B7jxM-tKOHst2l4_d|q|$4|dj~9V#n6cP&cI4&SV$wQ`zKSjw%m1ID8FET2vA zvbl0E#bdruYK_e`$u`lVk{gE)9^Y_KxYOWZ@l_i1gFeqomDbJ;q20j z`5Qv_ZSZ&$u=upH_L7VP9UIQ8$4)!(IN&j}a}WEv1eXnxADVn;37N)d)!XWR+VSP) z!v^znJCAbbE?s71HC0t4*xPs&`}?eilb*84J5S}F_L7zL(UBdCPnlUI1=UYLRzpRu!9zHNU_E#f9z+U@8`NYGMl6L|_PPN1}q9i4;B-JXpC>2OC7#SED z=o*;l8kvL`8d@2eSQ#5>8yHv_7?g-UyNseCH$NpatrE8eR*$%Rpaw~h4Z-BuF?hQAxvXC&$iToT>*?YcqH(@-!hU_{LXo5P z_n$4jQk^Q`>+Q5hN}#jT<&vXH?9;!j|5$Z+J=rHSHoK^(HQPIgchB%q3l`^&;!Il6 zvR*#A|KZ+k=hqi6uP!=o`&~{s$-}7cu&BJD-`rW3=T4nEwTVw!e#fd%b(# zxM%9ImVoV3yL9a?etX4uiD5_J_s4AKy{6B)I>m3T$;Ca14=oH}^hN#j%A40UFc z6{-!PH8q<;Ze?qKdHgt-OLyDi(!3u_rn*fD@;rQtv)^RmySvehAIesKJ}KtPpf0CU zeNV}9m57JoNyXPCmR~+GO}V+mbF%U(n?n9MjQl){GIdw#q?jz=l{~tcH^hJ|qu`*F z`j^6UwZ3?T(9hWPUF1B|Ht3B(=zAHySnw;9AMa~mbgZgq$HN4S|t~y0x1R~ z10w@n0~1{%lMq7#D-#PVBU5by11kfA(@%Z7P&DM`r(~v8;?}Th$5%6;21$?&!TD(= p<%vb94CUqJdYO6I#mR{Use1WE>9gP2NC6cwc)I$ztaD0e0ssxs)CT|n literal 0 HcmV?d00001 diff --git a/share/dark_resources/locate32.png b/share/dark_resources/locate32.png new file mode 100644 index 0000000000000000000000000000000000000000..3ade490ad766cc7221b97d563bfec7fd065f9d89 GIT binary patch literal 933 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`KgTaOs=3Nf`l6VJh}?aSZV|zI3X;hiIV4vHHdS zhrb`&v?1z;eT#;PQ}+V*hl@BS8Lau{`nKrm{Lq~nH5Ns+1UL%jE)mh>>NFD+bWFLW zwz_q~%=JxPE36Y$zigdR`8n;L^w+7+*FCd-Ui1A<@&4lDLZ3I^(Ak$|7VO%iZ}aqM zPheNv=_~0|BBg?gOHxXHCGGttbU*8edgOe2$L$j*&RgNgG4*xV#EEgM6zrRJOq}R8 zg(Km5PtTP}(y;;;r>QaceN=9cWnZ9bZqce2?|MRj})>^AC_kR05bBmt1+2Fwzw}WMd zmv2T?iSY$KN&YUW&~)IP`nkpfU%nVkQ`<22^S97{6@5>?6lyMNkXBjo{r0}O~Hi(GMl)GXyP1HW=e&H>r z6R!Gic^2m^X%IQtGa;*pV}bUT|AA_ZGm;w2w`|alZS)QhcQnYE|M_zJPJvIhOWHZL z6z?8UeA^)q()oYQns58WxlC6?YqzfI33*|9F|%t0!?Fza4gG~P>k_W~bd%iuAnC{}Cs!<(+> zuRIglk{O_}^52BrhdquOtL^?OS5p08)q*~!db@2C7aYlZX1+PHi!0n?9aq&(cWu`@ zOQ*YSE1I@b=cv~71=H9Mm`r}Nu*v<+^WF9ln{Tp2$29fye0w%gY|R28orfp(oqb;K zRhrwm`Sv!QqZU8qPiDT}^6Yo@f9}Qqxvv)NxR?q|k*X!G5hW>!C8<`)MX5lF!N|bK zK-a)T*T^Kq(7?*X+{)Bc+rYrez`#ITUJgY=ZhlH;S|x4`j%CXi0X0a1YzWRzD=AMb mN@XZ7FW1Y=%Pvk%EJ)SMFG`>N&PEETh{4m<&t;ucLK6V{n2MSJ literal 0 HcmV?d00001 diff --git a/share/dark_resources/origin2_16.png b/share/dark_resources/origin2_16.png new file mode 100644 index 0000000000000000000000000000000000000000..ff699506787404f53236917ae397a185ad8f32b5 GIT binary patch literal 540 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+uenMVO6iP5s=4O z;1OBOz`%C|gc+x5^GO2**-JcqUD=EaloalUk-q5q)(k=Fg+ zFKr315@S;{{3CqWY0AMPcTd_o{184C$>b?5eE8If^O*^S6Gg8G+49tecs;oH^x2%r zzwg-|@9^5%*q?kL>_vlh9%r9oaNY}}BSGx@emreG^H6Koa+i%49GDkItjyzDwqUnc zii@U$+e)kdO&gQ8Ylgg7wk)poLj%L^8Ru-BK-N0 z&*7&+Tqc6)Ra)^858CZ#`N<3IT6whZ&x6BTFHJUH8x+fFx!O2Q<*8W4#1H2-WtFxI z%9%cxEqi{A-)4pnl`Qv8oNp~vd}kZJuG;9ES%*H**QzD15hW>!C8<`)MX5lF!N|bK zK-a)T*T^Kq(7?*n*viO4+rYrez+iF=M=gqm-29Zxv`X9>9x-k>2-F}6vLQG>t)x7$ mD3zhSyj(9cFS|H7u^?41zbJk7I~ysWA_h-aKbLh*2~7YeR>K(p literal 0 HcmV?d00001 diff --git a/share/dark_resources/origin2_32.png b/share/dark_resources/origin2_32.png new file mode 100644 index 0000000000000000000000000000000000000000..b1ad7a0c82f660a37e9f007de8c01f7ba89913d1 GIT binary patch literal 807 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`KgTaG5F|dR)7Ufr0U>r;B5V$ML08_h$zOiX6AE zoFcVw^4bYAx{lmX+^py7VO_Q|K-wzuKU4H06~5dc^}?d!6VH@7md1K7T%a)V)~?K8 zub$RvS6th>e`No#dNT8ST+!!y&2u*IslI1<|NFb2^M3E;G@M~6_+C6xhG&6;qD`X4 zlh`)Sq5~%GbH1IOboThxWzNdyL&IGqqx14LR=T_0x;kl-*NRoEWKy@T`R=w#Ly~pE zC2LcY>yhE1Z*9)6UO6l1U{`{0@Rc72dCk`Bj(u)rzjETM7E5&jOHAkAtE=-`^M(A~`DXO;7Gy8+)8=5%UwmYBGUvMwi*~cW^_2<u#y7I}h zPv3dAU6$e843(31uGz1}Zlrg3?qho-7N{$o>96|q$&N);zTdwd^w72vUweupHRRgz zhBft9R$c#@(Xef~=~CIZ8LOf@|H_paZ_T*K5Z8WDh>hWcT9FR>-h2NUFUs)ea2SNd z1Ji_RiEBhjN@7W>RdP`(kYX@0Ff!0JFwr$K2{AOVGBvg`Hr6&Uure@+{TL&Oq9Hdw zB{QuOw+5XxPnH5TNP=t#&QB{TPb^AhC@(M9%goCzPEIUH)ypqRpZ(583aE&|)78&q Iol`;+07Own8vp&K3Q**Zz6$`|qq7-#PETb~~>1%4?zB*F{TLPre&|*g)cfQb8zt%(^G`@iENe zD{~}xEI%|hsjQr6+H>r4bZ^L)m~|)A4=?a-UFqng`QGu)Wyg--!w+~`$g+a*1s}*n!V>~oxq~w=IM)k z&X{r<`X0*FdEl69KFRv*r`tT=*8Z07tGV{7%_{Z+(BG;ht`Q|Ei6yC4$wjF^iowXh z$UxV?MAyh9#L&RX#N5inSlhtB%D`ZLpw=!F4Y~O#nQ4`{HN4}Q#0JzL39=zLKdq!Z nu_%?Hyu4g5GcUV1Ik6yBFTW^#_B$IXpdtoOS3j3^P6k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5n0T@z;^_M8K-LVNdpDhOFVsD*`KgTaOn$%h;Kj3z`%Ic)5S5w40}p?f1ZU6# zMHi;S2NY~81k>^#)>;3Ec>Y%Ue)YQcXU7km>Hk^#?ECEdXYy?d_f4~0ZX4OYjB)(Y=4QNNYZt8D@Y~HTDj<0dd)!wg(Foo9CAkmR z8#Q?D^C-XbEMVVxqv@Ah3?d)@iS7+OK0C{IGAs8&*{vM5>(AA{s+wiu$8x&-s$fQ3 zvj7#doUAi!Lpg)cT^Bx$D=8{8{1s!iA3AVo4`h zIf9m@FRv){jMq8Rq1~dYT-(dJ#8X-<$%d;UY01eOn|Cad7faeDb|HU>JLmCA-`!$K zUJDnkT5x>p{V!4LpQy&BuRnGBpKkWF^~=}Pe}B)$|5tea=2C`)yYHW9?w{dkwm|5M zNpAP?Zo0RWYuMbnwk9^!K^Rcbjgs?)FK#IZ0z{o(?z(m)`B*f6b%Ea8t&|KTVz{cptHiA#Xz`9hpaw~h4Z-BuF?hQAxvXEpngtyU%)+Z0n3yMXb4iFU=x^XMl9%A^ lS;53MBk<&b9=V$t3=FNSa<2#6nF4YygQu&X%Q~loCIHKFIl=${ literal 0 HcmV?d00001 From 935d556c93f957024e71060cc52eb8ae99d5c337 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 24 Apr 2020 21:08:27 +0300 Subject: [PATCH 205/209] - updated Paint Tool for the new Tool DB - updated the Tcl commands CopperClear and Paint --- CHANGELOG.md | 2 + flatcamTools/ToolPaint.py | 1336 ++++++++------------------ tclCommands/TclCommandCopperClear.py | 70 +- tclCommands/TclCommandPaint.py | 49 +- 4 files changed, 498 insertions(+), 959 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b0b4b10..7ba9929d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ CHANGELOG for FlatCAM beta - updated the Readme file with the steps for installation for MacOS - updated the requirements.txt file - updated some of the icons in the dark_resources folder (some added, some modified) +- updated Paint Tool for the new Tool DB +- updated the Tcl commands CopperClear and Paint 23.04.2020 diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 4ad2890f..1bec59b1 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -1556,11 +1556,11 @@ class ToolPaint(FlatCAMTool, Gerber): def on_mouse_release(self, event): if self.app.is_legacy is False: event_pos = event.pos - event_is_dragging = event.is_dragging + # event_is_dragging = event.is_dragging right_button = 2 else: event_pos = (event.xdata, event.ydata) - event_is_dragging = self.app.plotcanvas.is_dragging + # event_is_dragging = self.app.plotcanvas.is_dragging right_button = 3 try: @@ -1682,11 +1682,11 @@ class ToolPaint(FlatCAMTool, Gerber): if self.app.is_legacy is False: event_pos = event.pos event_is_dragging = event.is_dragging - right_button = 2 + # right_button = 2 else: event_pos = (event.xdata, event.ydata) event_is_dragging = self.app.plotcanvas.is_dragging - right_button = 3 + # right_button = 3 try: x = float(event_pos[0]) @@ -1734,8 +1734,8 @@ class ToolPaint(FlatCAMTool, Gerber): self.draw_moving_selection_shape_poly(points=self.points, data=(curr_pos[0], curr_pos[1])) def on_key_press(self, event): - modifiers = QtWidgets.QApplication.keyboardModifiers() - matplotlib_key_flag = False + # modifiers = QtWidgets.QApplication.keyboardModifiers() + # matplotlib_key_flag = False # events out of the self.app.collection view (it's about Project Tab) are of type int if type(event) is int: @@ -1744,7 +1744,7 @@ class ToolPaint(FlatCAMTool, Gerber): elif type(event) == QtGui.QKeyEvent: key = event.key() elif isinstance(event, mpl_key_event): # MatPlotLib key events are trickier to interpret than the rest - matplotlib_key_flag = True + # matplotlib_key_flag = True key = event.key key = QtGui.QKeySequence(key) @@ -1754,13 +1754,17 @@ class ToolPaint(FlatCAMTool, Gerber): if '+' in key_string: mod, __, key_text = key_string.rpartition('+') if mod.lower() == 'ctrl': - modifiers = QtCore.Qt.ControlModifier + # modifiers = QtCore.Qt.ControlModifier + pass elif mod.lower() == 'alt': - modifiers = QtCore.Qt.AltModifier + # modifiers = QtCore.Qt.AltModifier + pass elif mod.lower() == 'shift': - modifiers = QtCore.Qt.ShiftModifier + # modifiers = QtCore.Qt.ShiftModifier + pass else: - modifiers = QtCore.Qt.NoModifier + # modifiers = QtCore.Qt.NoModifier + pass key = QtGui.QKeySequence(key_text) # events from Vispy are of type KeyEvent @@ -2091,7 +2095,6 @@ class ToolPaint(FlatCAMTool, Gerber): else: self.app.inform.emit('%s %s' % (_("Paint Tool."), _("Normal painting polygon task started."))) - polygon_list = None if inside_pt and poly_list is None: polygon_list = [self.find_polygon(point=inside_pt, geoset=obj.solid_geometry)] elif (inside_pt is None and poly_list) or (inside_pt and poly_list): @@ -2137,6 +2140,7 @@ class ToolPaint(FlatCAMTool, Gerber): tool_dia = None current_uid = None final_solid_geometry = [] + old_disp_number = 0 for tool_dia in sorted_tools: log.debug("Starting geometry processing for tool: %s" % str(tool_dia)) @@ -2184,12 +2188,30 @@ class ToolPaint(FlatCAMTool, Gerber): cp = [] try: for pp in poly_buf: + # provide the app with a way to process the GUI events when in a blocking loop + QtWidgets.QApplication.processEvents() + if self.app.abort_flag: + # graceful abort requested by the user + raise FlatCAMApp.GracefulException geo_res = self.paint_polygon_worker(pp, tooldiameter=tool_dia, over=over, conn=conn, cont=cont, paint_method=paint_method, obj=obj, prog_plot=prog_plot) if geo_res: cp.append(geo_res) + pol_nr += 1 + disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100])) + # log.debug("Polygons cleared: %d" % pol_nr) + + if old_disp_number < disp_number <= 100: + self.app.proc_container.update_view_text(' %d%%' % disp_number) + old_disp_number = disp_number except TypeError: + # provide the app with a way to process the GUI events when in a blocking loop + QtWidgets.QApplication.processEvents() + if self.app.abort_flag: + # graceful abort requested by the user + raise FlatCAMApp.GracefulException + geo_res = self.paint_polygon_worker(poly_buf, tooldiameter=tool_dia, over=over, conn=conn, cont=cont, paint_method=paint_method, obj=obj, prog_plot=prog_plot) @@ -2229,12 +2251,11 @@ class ToolPaint(FlatCAMTool, Gerber): if not tools_storage[uid]['solid_geometry']: tools_storage.pop(uid, None) + if not tools_storage: + return 'fail' + def job_init(geo_obj, app_obj): - if not tools_storage: - return 'fail' - geo_obj.options["cnctooldia"] = str(tool_dia) - # this will turn on the FlatCAMCNCJob plot for multiple tools geo_obj.multigeo = True geo_obj.multitool = True @@ -2254,7 +2275,7 @@ class ToolPaint(FlatCAMTool, Gerber): geo_obj.options['xmax'] = c geo_obj.options['ymax'] = d except Exception as ee: - log.debug("ToolPaint.paint_poly.gen_paintarea() bounds error --> %s" % str(ee)) + log.debug("ToolPaint.paint_poly.job_init() bounds error --> %s" % str(ee)) return # test if at least one tool has solid_geometry. If no tool has solid_geometry we raise an Exception @@ -2273,16 +2294,6 @@ class ToolPaint(FlatCAMTool, Gerber): # Experimental... # print("Indexing...", end=' ') # geo_obj.make_index() - # if errors == 0: - # print("[success] Paint single polygon Done") - # 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. " - # "%d area(s) could not be painted.\n" - # "Use different paint parameters or edit the paint geometry and correct" - # "the issue." - # % errors) def job_thread(app_obj): try: @@ -2292,7 +2303,8 @@ class ToolPaint(FlatCAMTool, Gerber): return except Exception as er: proc.done() - app_obj.inform.emit('[ERROR_NOTCL] %s --> %s' % ('PaintTool.paint_poly()', str(er))) + app_obj.inform.emit('[ERROR] %s --> %s' % ('PaintTool.paint_poly()', str(er))) + traceback.print_stack() return proc.done() @@ -2321,46 +2333,17 @@ class ToolPaint(FlatCAMTool, Gerber): """ Paints all polygons in this object. + :param obj: painted object + :param tooldia: a tuple or single element made out of diameters of the tools to be used + :param order: if the tools are ordered and how + :param outname: name of the resulting object + :param method: choice out of _("Seed"), 'normal', 'lines' + :param tools_storage: whether to use the current tools_storage self.paints_tools or a different one. + Usage of the different one is related to when this function is called from a TcL command. :param run_threaded: :param plot: - :param obj: painted object - :param tooldia: a tuple or single element made out of diameters of the tools to be used - :param overlap: value by which the paths will overlap - :param order: if the tools are ordered and how - :param margin: a border around painting area - :param outname: name of the resulting object - :param connect: Connect lines to avoid tool lifts. - :param contour: Paint around the edges. - :param method: choice out of _("Seed"), 'normal', 'lines' - :param tools_storage: whether to use the current tools_storage self.paints_tools or a different one. - Usage of the different one is related to when this function is called from a TcL command. :return: """ - paint_method = method if method is not None else self.paintmethod_combo.get_value() - - # determine if to use the progressive plotting - if self.app.defaults["tools_paint_plotting"] == 'progressive': - prog_plot = True - else: - prog_plot = False - - proc = self.app.proc_container.new(_("Painting polygons...")) - name = outname if outname is not None else self.obj_name + "_paint" - order = order if order is not None else self.order_radio.get_value() - tools_storage = self.paint_tools if tools_storage is None else tools_storage - - sorted_tools = [] - if tooldia is not None: - try: - sorted_tools = [float(eval(dia)) for dia in tooldia.split(",") if dia != ''] - except AttributeError: - if not isinstance(tooldia, list): - sorted_tools = [float(tooldia)] - else: - sorted_tools = tooldia - else: - for row in range(self.tools_table.rowCount()): - sorted_tools.append(float(self.tools_table.item(row, 1).text())) # This is a recursive generator of individual Polygons. # Note: Double check correct implementation. Might exit @@ -2410,23 +2393,57 @@ class ToolPaint(FlatCAMTool, Gerber): return self.flat_geometry + if obj.kind == 'gerber': + # I don't do anything here, like buffering when the Gerber is loaded without buffering????!!!! + if self.app.defaults["gerber_buffering"] == 'no': + self.app.inform.emit('%s %s %s' % (_("Paint Tool."), _("Paint all polygons task started."), + _("Buffering geometry..."))) + else: + self.app.inform.emit('%s %s' % (_("Paint Tool."), _("Paint all polygons task started."))) + + if self.app.defaults["tools_paint_plotting"] == 'progressive': + if isinstance(obj.solid_geometry, list): + obj.solid_geometry = MultiPolygon(obj.solid_geometry).buffer(0) + else: + obj.solid_geometry = obj.solid_geometry.buffer(0) + else: + self.app.inform.emit('%s %s' % (_("Paint Tool."), _("Paint all polygons task started."))) + + painted_area = recurse(obj.solid_geometry) + + # No polygon? + if not painted_area: + self.app.log.warning('No polygon found.') + self.app.inform.emit('[WARNING] %s' % _('No polygon found.')) + return + + paint_method = method if method is not None else self.paintmethod_combo.get_value() + # determine if to use the progressive plotting + prog_plot = True if self.app.defaults["tools_paint_plotting"] == 'progressive' else False + + name = outname if outname is not None else self.obj_name + "_paint" + order = order if order is not None else self.order_radio.get_value() + tools_storage = self.paint_tools if tools_storage is None else tools_storage + + sorted_tools = [] + if tooldia is not None: + try: + sorted_tools = [float(eval(dia)) for dia in tooldia.split(",") if dia != ''] + except AttributeError: + if not isinstance(tooldia, list): + sorted_tools = [float(tooldia)] + else: + sorted_tools = tooldia + else: + for row in range(self.tools_table.rowCount()): + sorted_tools.append(float(self.tools_table.item(row, 1).text())) + + proc = self.app.proc_container.new(_("Painting polygons...")) + # Initializes the new geometry object def gen_paintarea(geo_obj, app_obj): - # assert isinstance(geo_obj, FlatCAMGeometry), \ - # "Initializer expected a FlatCAMGeometry, got %s" % type(geo_obj) - log.debug("Paint Tool. Normal painting all task started.") - if obj.kind == 'gerber': - if app_obj.defaults["gerber_buffering"] == 'no': - app_obj.inform.emit('%s %s' % - (_("Paint Tool. Normal painting all task started."), - _("Buffering geometry..."))) - else: - app_obj.inform.emit(_("Paint Tool. Normal painting all task started.")) - else: - app_obj.inform.emit(_("Paint Tool. Normal painting all task started.")) - tool_dia = None if order == 'fwd': sorted_tools.sort(reverse=False) elif order == 'rev': @@ -2434,38 +2451,16 @@ class ToolPaint(FlatCAMTool, Gerber): else: pass - if obj.kind == 'gerber': - if self.app.defaults["tools_paint_plotting"] == 'progressive': - if isinstance(obj.solid_geometry, list): - obj.solid_geometry = MultiPolygon(obj.solid_geometry).buffer(0) - else: - obj.solid_geometry = obj.solid_geometry.buffer(0) - - try: - a, b, c, d = obj.bounds() - geo_obj.options['xmin'] = a - geo_obj.options['ymin'] = b - geo_obj.options['xmax'] = c - geo_obj.options['ymax'] = d - except Exception as e: - log.debug("ToolPaint.paint_poly.gen_paintarea() bounds error --> %s" % str(e)) - return - - total_geometry = [] + tool_dia = None current_uid = int(1) old_disp_number = 0 - geo_obj.solid_geometry = [] final_solid_geometry = [] - painted_area = recurse(obj.solid_geometry) - for tool_dia in sorted_tools: log.debug("Starting geometry processing for tool: %s" % str(tool_dia)) app_obj.inform.emit( - '[success] %s %s%s %s' % (_('Painting with tool diameter = '), - str(tool_dia), - self.units.lower(), + '[success] %s %s%s %s' % (_('Painting with tool diameter = '), str(tool_dia), self.units.lower(), _('started')) ) app_obj.proc_container.update_view_text(' %d%%' % 0) @@ -2486,6 +2481,7 @@ class ToolPaint(FlatCAMTool, Gerber): paint_margin = float(tools_storage[current_uid]['data']['tools_paintmargin']) poly_buf = [] for pol in painted_area: + pol = Polygon(pol) if not isinstance(pol, Polygon) else pol buffered_pol = pol.buffer(-paint_margin) if buffered_pol and not buffered_pol.is_empty: poly_buf.append(buffered_pol) @@ -2508,10 +2504,8 @@ class ToolPaint(FlatCAMTool, Gerber): try: cp = [] - geo_res = None try: for pp in poly_buf: - # provide the app with a way to process the GUI events when in a blocking loop QtWidgets.QApplication.processEvents() if self.app.abort_flag: @@ -2526,6 +2520,16 @@ class ToolPaint(FlatCAMTool, Gerber): poly_processed.append(True) else: poly_processed.append(False) + + pol_nr += 1 + disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100])) + # log.debug("Polygons cleared: %d" % pol_nr) + + if old_disp_number < disp_number <= 100: + app_obj.proc_container.update_view_text(' %d%%' % disp_number) + old_disp_number = disp_number + # log.debug("Polygons cleared: %d. Percentage done: %d%%" % (pol_nr, disp_number)) + except TypeError: # provide the app with a way to process the GUI events when in a blocking loop QtWidgets.QApplication.processEvents() @@ -2548,15 +2552,6 @@ class ToolPaint(FlatCAMTool, Gerber): total_geometry += list(x.get_objects()) final_solid_geometry += total_geometry - pol_nr += 1 - disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100])) - # log.debug("Polygons cleared: %d" % pol_nr) - - if old_disp_number < disp_number <= 100: - app_obj.proc_container.update_view_text(' %d%%' % disp_number) - old_disp_number = disp_number - # log.debug("Polygons cleared: %d. Percentage done: %d%%" % (pol_nr, disp_number)) - except Exception as err: log.debug("Could not Paint the polygons. %s" % str(err)) self.app.inform.emit( @@ -2604,11 +2599,27 @@ class ToolPaint(FlatCAMTool, Gerber): geo_obj.solid_geometry = cascaded_union(final_solid_geometry) + try: + # a, b, c, d = obj.bounds() + if isinstance(geo_obj.solid_geometry, list): + a, b, c, d = MultiPolygon(geo_obj.solid_geometry).bounds + else: + a, b, c, d = geo_obj.solid_geometry.bounds + + geo_obj.options['xmin'] = a + geo_obj.options['ymin'] = b + geo_obj.options['xmax'] = c + geo_obj.options['ymax'] = d + except Exception as e: + log.debug("ToolPaint.paint_poly.gen_paintarea() bounds error --> %s" % str(e)) + return + # test if at least one tool has solid_geometry. If no tool has solid_geometry we raise an Exception has_solid_geo = 0 for tooluid in geo_obj.tools: if geo_obj.tools[tooluid]['solid_geometry']: has_solid_geo += 1 + if has_solid_geo == 0: self.app.inform.emit('[ERROR] %s' % _("There is no Painting Geometry in the file.\n" @@ -2624,56 +2635,22 @@ class ToolPaint(FlatCAMTool, Gerber): # Initializes the new geometry object def gen_paintarea_rest_machining(geo_obj, app_obj): - # assert isinstance(geo_obj, FlatCAMGeometry), \ - # "Initializer expected a FlatCAMGeometry, got %s" % type(geo_obj) - log.debug("Paint Tool. Rest machining painting all task started.") - if obj.kind == 'gerber': - if app_obj.defaults["gerber_buffering"] == 'no': - app_obj.inform.emit('%s %s %s' % - (_("Paint Tool."), _("Rest machining painting all task started."), - _("Buffering geometry..."))) - else: - app_obj.inform.emit('%s %s' % - (_("Paint Tool."), _("Rest machining painting all task started."))) - else: - app_obj.inform.emit('%s %s' % - (_("Paint Tool."), _("Rest machining painting all task started."))) - tool_dia = None + # when using rest machining use always the reverse order; from bigger tool to smaller one sorted_tools.sort(reverse=True) - if obj.kind == 'gerber': - if self.app.defaults["tools_paint_plotting"] == 'progressive': - if isinstance(obj.solid_geometry, list): - obj.solid_geometry = MultiPolygon(obj.solid_geometry).buffer(0) - else: - obj.solid_geometry = obj.solid_geometry.buffer(0) - - try: - a, b, c, d = obj.bounds() - geo_obj.options['xmin'] = a - geo_obj.options['ymin'] = b - geo_obj.options['xmax'] = c - geo_obj.options['ymax'] = d - except Exception as e: - log.debug("ToolPaint.paint_poly.gen_paintarea() bounds error --> %s" % str(e)) - return - + tool_dia = None cleared_geo = [] current_uid = int(1) - geo_obj.solid_geometry = [] - final_solid_geometry = [] old_disp_number = 0 - painted_area = recurse(obj.solid_geometry) + final_solid_geometry = [] for tool_dia in sorted_tools: log.debug("Starting geometry processing for tool: %s" % str(tool_dia)) app_obj.inform.emit( - '[success] %s %s%s %s' % (_('Painting with tool diameter = '), - str(tool_dia), - self.units.lower(), + '[success] %s %s%s %s' % (_('Painting with tool diameter = '), str(tool_dia), self.units.lower(), _('started')) ) app_obj.proc_container.update_view_text(' %d%%' % 0) @@ -2710,212 +2687,59 @@ class ToolPaint(FlatCAMTool, Gerber): pol_nr = 0 - for geo in poly_buf: + # ----------------------------- + # effective polygon clearing job + # ----------------------------- + try: + cp = [] try: - cp = None + for pp in poly_buf: + # provide the app with a way to process the GUI events when in a blocking loop + QtWidgets.QApplication.processEvents() + if self.app.abort_flag: + # graceful abort requested by the user + raise FlatCAMApp.GracefulException + geo_res = self.paint_polygon_worker(pp, tooldiameter=tool_dia, over=over, conn=conn, + cont=cont, paint_method=paint_method, obj=obj, + prog_plot=prog_plot) + if geo_res: + cp.append(geo_res) + pol_nr += 1 + disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100])) + # log.debug("Polygons cleared: %d" % pol_nr) - if paint_method == _("Standard"): - # Type(cp) == FlatCAMRTreeStorage | None - cp = self.clear_polygon(geo, tooldia=tool_dia, - steps_per_circle=self.app.defaults["geometry_circle_steps"], - overlap=over, contour=cont, connect=conn, - prog_plot=prog_plot) - elif paint_method == _("Seed"): - # Type(cp) == FlatCAMRTreeStorage | None - cp = self.clear_polygon2(geo, tooldia=tool_dia, - steps_per_circle=self.app.defaults["geometry_circle_steps"], - overlap=over, contour=cont, connect=conn, - prog_plot=prog_plot) - elif paint_method == _("Lines"): - # Type(cp) == FlatCAMRTreeStorage | None - cp = self.clear_polygon3(geo, tooldia=tool_dia, - steps_per_circle=self.app.defaults["geometry_circle_steps"], - overlap=over, contour=cont, connect=conn, - prog_plot=prog_plot) - elif paint_method == _("Laser_lines"): - # line = None - # aperture_size = None + if old_disp_number < disp_number <= 100: + self.app.proc_container.update_view_text(' %d%%' % disp_number) + old_disp_number = disp_number + except TypeError: + # provide the app with a way to process the GUI events when in a blocking loop + QtWidgets.QApplication.processEvents() + if self.app.abort_flag: + # graceful abort requested by the user + raise FlatCAMApp.GracefulException - # the key is the aperture type and the val is a list of geo elements - flash_el_dict = {} - # the key is the aperture size, the val is a list of geo elements - traces_el_dict = {} - - # find the flashes and the lines that are in the selected polygon and store - # them separately - for apid, apval in obj.apertures.items(): - for geo_el in apval['geometry']: - if apval["size"] == 0.0: - if apval["size"] in traces_el_dict: - traces_el_dict[apval["size"]].append(geo_el) - else: - traces_el_dict[apval["size"]] = [geo_el] - - if 'follow' in geo_el and geo_el['follow'].within(geo): - if isinstance(geo_el['follow'], Point): - if apval["type"] == 'C': - if 'C' in flash_el_dict: - flash_el_dict['C'].append(geo_el) - else: - flash_el_dict['C'] = [geo_el] - elif apval["type"] == 'O': - if 'O' in flash_el_dict: - flash_el_dict['O'].append(geo_el) - else: - flash_el_dict['O'] = [geo_el] - elif apval["type"] == 'R': - if 'R' in flash_el_dict: - flash_el_dict['R'].append(geo_el) - else: - flash_el_dict['R'] = [geo_el] - else: - aperture_size = apval['size'] - - if aperture_size in traces_el_dict: - traces_el_dict[aperture_size].append(geo_el) - else: - traces_el_dict[aperture_size] = [geo_el] - - cp = FlatCAMRTreeStorage() - pads_lines_list = [] - - # process the flashes found in the selected polygon with the 'lines' method - # for rectangular flashes and with _("Seed") for oblong and circular flashes - # and pads (flahes) need the contour therefore I override the GUI settings - # with always True - for ap_type in flash_el_dict: - for elem in flash_el_dict[ap_type]: - if 'solid' in elem: - if ap_type == 'C': - f_o = self.clear_polygon2(elem['solid'], - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=True, - connect=conn, - prog_plot=prog_plot) - pads_lines_list += [p for p in f_o.get_objects() if p] - - elif ap_type == 'O': - f_o = self.clear_polygon2(elem['solid'], - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=True, - connect=conn, - prog_plot=prog_plot) - pads_lines_list += [p for p in f_o.get_objects() if p] - - elif ap_type == 'R': - f_o = self.clear_polygon3(elem['solid'], - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=True, - connect=conn, - prog_plot=prog_plot) - - pads_lines_list += [p for p in f_o.get_objects() if p] - - # add the lines from pads to the storage - try: - for lin in pads_lines_list: - if lin: - cp.insert(lin) - except TypeError: - cp.insert(pads_lines_list) - - copper_lines_list = [] - # process the traces found in the selected polygon using the 'laser_lines' - # method, method which will follow the 'follow' line therefore use the longer - # path possible for the laser, therefore the acceleration will play - # a smaller factor - for aperture_size in traces_el_dict: - for elem in traces_el_dict[aperture_size]: - line = elem['follow'] - if line: - t_o = self.fill_with_lines(line, aperture_size, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - - copper_lines_list += [p for p in t_o.get_objects() if p] - - # add the lines from copper features to storage but first try to make as few - # lines as possible - # by trying to fuse them - lines_union = linemerge(unary_union(copper_lines_list)) - try: - for lin in lines_union: - if lin: - cp.insert(lin) - except TypeError: - cp.insert(lines_union) - elif paint_method == _("Combo"): - self.app.inform.emit(_("Painting polygons with method: lines.")) - cp = self.clear_polygon3(geo, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - - if cp and cp.objects: - pass - else: - self.app.inform.emit(_("Failed. Painting polygons with method: seed.")) - cp = self.clear_polygon2(geo, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - if cp and cp.objects: - pass - else: - self.app.inform.emit(_("Failed. Painting polygons with method: standard.")) - cp = self.clear_polygon(geo, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, + geo_res = self.paint_polygon_worker(poly_buf, tooldiameter=tool_dia, over=over, conn=conn, + cont=cont, paint_method=paint_method, obj=obj, prog_plot=prog_plot) + if geo_res: + cp.append(geo_res) - if cp is not None: - cleared_geo += list(cp.get_objects()) - except FlatCAMApp.GracefulException: - return "fail" - except Exception as e: - log.debug("Could not Paint the polygons. %s" % str(e)) - self.app.inform.emit('[ERROR] %s\n%s' % - (_("Could not do Paint All. Try a different combination of parameters. " - "Or a different Method of paint"), - str(e))) - return "fail" + if cp: + for x in cp: + cleared_geo += list(x.get_objects()) + final_solid_geometry += cleared_geo + except FlatCAMApp.GracefulException: + return "fail" + except Exception as e: + log.debug("Could not Paint the polygons. %s" % str(e)) + self.app.inform.emit( + '[ERROR] %s\n%s' % + (_("Could not do Paint. Try a different combination of parameters. " + "Or a different strategy of paint"), str(e) + ) + ) + continue - pol_nr += 1 - disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100])) - # log.debug("Polygons cleared: %d" % pol_nr) - - if old_disp_number < disp_number <= 100: - app_obj.proc_container.update_view_text(' %d%%' % disp_number) - old_disp_number = disp_number - # log.debug("Polygons cleared: %d. Percentage done: %d%%" % (pol_nr, disp_number)) - - final_solid_geometry += cleared_geo # add the solid_geometry to the current too in self.paint_tools (or tools_storage) dictionary and # then reset the temporary list that stored that solid_geometry tools_storage[current_uid]['solid_geometry'] = deepcopy(cleared_geo) @@ -2945,6 +2769,21 @@ class ToolPaint(FlatCAMTool, Gerber): geo_obj.solid_geometry = cascaded_union(final_solid_geometry) + try: + # a, b, c, d = obj.bounds() + if isinstance(geo_obj.solid_geometry, list): + a, b, c, d = MultiPolygon(geo_obj.solid_geometry).bounds + else: + a, b, c, d = geo_obj.solid_geometry.bounds + + geo_obj.options['xmin'] = a + geo_obj.options['ymin'] = b + geo_obj.options['xmax'] = c + geo_obj.options['ymax'] = d + except Exception as e: + log.debug("ToolPaint.paint_poly.gen_paintarea_rest_machining() bounds error --> %s" % str(e)) + return + # test if at least one tool has solid_geometry. If no tool has solid_geometry we raise an Exception has_solid_geo = 0 for tooluid in geo_obj.tools: @@ -2966,19 +2805,27 @@ class ToolPaint(FlatCAMTool, Gerber): def job_thread(app_obj): try: if self.rest_cb.isChecked(): - app_obj.new_object("geometry", name, gen_paintarea_rest_machining, plot=plot) + ret = app_obj.new_object("geometry", name, gen_paintarea_rest_machining, plot=plot) else: - app_obj.new_object("geometry", name, gen_paintarea, plot=plot) + ret = app_obj.new_object("geometry", name, gen_paintarea, plot=plot) except FlatCAMApp.GracefulException: proc.done() return - except Exception: + except Exception as err: proc.done() + app_obj.inform.emit('[ERROR] %s --> %s' % ('PaintTool.paint_poly_all()', str(err))) traceback.print_stack() return proc.done() + + if ret == 'fail': + self.app.inform.emit('[ERROR] %s' % _("Paint All failed.")) + return + # focus on Selected Tab - self.app.ui.notebook.setCurrentWidget(self.app.ui.selected_tab) + # self.app.ui.notebook.setCurrentWidget(self.app.ui.selected_tab) + + self.app.inform.emit('[success] %s' % _("Paint Poly All Done.")) self.app.inform.emit(_("Polygon Paint started ...")) @@ -2991,52 +2838,23 @@ class ToolPaint(FlatCAMTool, Gerber): else: job_thread(app_obj=self.app) - def paint_poly_area(self, obj, sel_obj, tooldia=None, order=None, method=None, - outname=None, tools_storage=None, plot=True, run_threaded=True): + def paint_poly_area(self, obj, sel_obj, tooldia=None, order=None, method=None, outname=None, + tools_storage=None, plot=True, run_threaded=True): """ Paints all polygons in this object that are within the sel_obj object - :param run_threaded: - :param plot: :param obj: painted object :param sel_obj: paint only what is inside this object bounds :param tooldia: a tuple or single element made out of diameters of the tools to be used - :param overlap: value by which the paths will overlap :param order: if the tools are ordered and how - :param margin: a border around painting area :param outname: name of the resulting object - :param connect: Connect lines to avoid tool lifts. - :param contour: Paint around the edges. :param method: choice out of _("Seed"), 'normal', 'lines' :param tools_storage: whether to use the current tools_storage self.paints_tools or a different one. Usage of the different one is related to when this function is called from a TcL command. + :param run_threaded: + :param plot: :return: """ - paint_method = method if method is not None else self.paintmethod_combo.get_value() - - # determine if to use the progressive plotting - if self.app.defaults["tools_paint_plotting"] == 'progressive': - prog_plot = True - else: - prog_plot = False - - proc = self.app.proc_container.new(_("Painting polygons...")) - name = outname if outname is not None else self.obj_name + "_paint" - order = order if order is not None else self.order_radio.get_value() - tools_storage = self.paint_tools if tools_storage is None else tools_storage - - sorted_tools = [] - if tooldia is not None: - try: - sorted_tools = [float(eval(dia)) for dia in tooldia.split(",") if dia != ''] - except AttributeError: - if not isinstance(tooldia, list): - sorted_tools = [float(tooldia)] - else: - sorted_tools = tooldia - else: - for row in range(self.tools_table.rowCount()): - sorted_tools.append(float(self.tools_table.item(row, 1).text())) def recurse(geometry, reset=True): """ @@ -3072,23 +2890,58 @@ class ToolPaint(FlatCAMTool, Gerber): return self.flat_geometry + # this is were heavy lifting is done and creating the geometry to be painted + target_geo = MultiPolygon(obj.solid_geometry) + if obj.kind == 'gerber': + # I don't do anything here, like buffering when the Gerber is loaded without buffering????!!!! + if self.app.defaults["gerber_buffering"] == 'no': + self.app.inform.emit('%s %s %s' % (_("Paint Tool."), _("Painting area task started."), + _("Buffering geometry..."))) + else: + self.app.inform.emit('%s %s' % (_("Paint Tool."), _("Painting area task started."))) + + if obj.kind == 'gerber': + if self.app.defaults["tools_paint_plotting"] == 'progressive': + target_geo = target_geo.buffer(0) + else: + self.app.inform.emit('%s %s' % (_("Paint Tool."), _("Painting area task started."))) + + geo_to_paint = target_geo.intersection(sel_obj) + painted_area = recurse(geo_to_paint) + + # No polygon? + if not painted_area: + self.app.log.warning('No polygon found.') + self.app.inform.emit('[WARNING] %s' % _('No polygon found.')) + return + + paint_method = method if method is not None else self.paintmethod_combo.get_value() + # determine if to use the progressive plotting + prog_plot = True if self.app.defaults["tools_paint_plotting"] == 'progressive' else False + + name = outname if outname is not None else self.obj_name + "_paint" + order = order if order is not None else self.order_radio.get_value() + tools_storage = self.paint_tools if tools_storage is None else tools_storage + + sorted_tools = [] + if tooldia is not None: + try: + sorted_tools = [float(eval(dia)) for dia in tooldia.split(",") if dia != ''] + except AttributeError: + if not isinstance(tooldia, list): + sorted_tools = [float(tooldia)] + else: + sorted_tools = tooldia + else: + for row in range(self.tools_table.rowCount()): + sorted_tools.append(float(self.tools_table.item(row, 1).text())) + + proc = self.app.proc_container.new(_("Painting polygons...")) + # Initializes the new geometry object def gen_paintarea(geo_obj, app_obj): - # assert isinstance(geo_obj, FlatCAMGeometry), \ - # "Initializer expected a FlatCAMGeometry, got %s" % type(geo_obj) - log.debug("Paint Tool. Normal painting area task started.") - if obj.kind == 'gerber': - if app_obj.defaults["gerber_buffering"] == 'no': - app_obj.inform.emit('%s %s' % - (_("Paint Tool. Normal painting area task started."), - _("Buffering geometry..."))) - else: - app_obj.inform.emit(_("Paint Tool. Normal painting area task started.")) - else: - app_obj.inform.emit(_("Paint Tool. Normal painting area task started.")) - tool_dia = None if order == 'fwd': sorted_tools.sort(reverse=False) elif order == 'rev': @@ -3096,42 +2949,16 @@ class ToolPaint(FlatCAMTool, Gerber): else: pass - # this is were heavy lifting is done and creating the geometry to be painted - target_geo = MultiPolygon(obj.solid_geometry) - - if obj.kind == 'gerber': - if self.app.defaults["tools_paint_plotting"] == 'progressive': - if isinstance(target_geo, list): - target_geo = MultiPolygon(target_geo).buffer(0) - else: - target_geo = target_geo.buffer(0) - - geo_to_paint = target_geo.intersection(sel_obj) - painted_area = recurse(geo_to_paint) - - try: - a, b, c, d = self.paint_bounds(geo_to_paint) - geo_obj.options['xmin'] = a - geo_obj.options['ymin'] = b - geo_obj.options['xmax'] = c - geo_obj.options['ymax'] = d - except Exception as e: - log.debug("ToolPaint.paint_poly.gen_paintarea() bounds error --> %s" % str(e)) - return - - total_geometry = [] + tool_dia = None current_uid = int(1) - - geo_obj.solid_geometry = [] - final_solid_geometry = [] old_disp_number = 0 + final_solid_geometry = [] + for tool_dia in sorted_tools: log.debug("Starting geometry processing for tool: %s" % str(tool_dia)) app_obj.inform.emit( - '[success] %s %s%s %s' % (_('Painting with tool diameter = '), - str(tool_dia), - self.units.lower(), + '[success] %s %s%s %s' % (_('Painting with tool diameter = '), str(tool_dia), self.units.lower(), _('started')) ) app_obj.proc_container.update_view_text(' %d%%' % 0) @@ -3141,7 +2968,6 @@ class ToolPaint(FlatCAMTool, Gerber): if float('%.*f' % (self.decimals, v['tooldia'])) == float('%.*f' % (self.decimals, tool_dia)): current_uid = int(k) break - if not current_uid: return "fail" @@ -3153,6 +2979,7 @@ class ToolPaint(FlatCAMTool, Gerber): paint_margin = float(tools_storage[current_uid]['data']['tools_paintmargin']) poly_buf = [] for pol in painted_area: + pol = Polygon(pol) if not isinstance(pol, Polygon) else pol buffered_pol = pol.buffer(-paint_margin) if buffered_pol and not buffered_pol.is_empty: poly_buf.append(buffered_pol) @@ -3168,226 +2995,73 @@ class ToolPaint(FlatCAMTool, Gerber): pol_nr = 0 - for geo in poly_buf: + # ----------------------------- + # effective polygon clearing job + # ----------------------------- + poly_processed = [] + total_geometry = [] + + try: try: - # Polygons are the only really paintable geometries, lines in theory have no area to be painted - if not isinstance(geo, Polygon): - continue + for pp in poly_buf: + # provide the app with a way to process the GUI events when in a blocking loop + QtWidgets.QApplication.processEvents() + if self.app.abort_flag: + # graceful abort requested by the user + raise FlatCAMApp.GracefulException - cp = None - if paint_method == _("Seed"): - # Type(cp) == FlatCAMRTreeStorage | None - cp = self.clear_polygon2(geo, - tooldia=tool_dia, - steps_per_circle=self.app.defaults["geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - - elif paint_method == _("Lines"): - # Type(cp) == FlatCAMRTreeStorage | None - cp = self.clear_polygon3(geo, - tooldia=tool_dia, - steps_per_circle=self.app.defaults["geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - - elif paint_method == _("Standard"): - # Type(cp) == FlatCAMRTreeStorage | None - cp = self.clear_polygon(geo, - tooldia=tool_dia, - steps_per_circle=self.app.defaults["geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - elif paint_method == _("Laser_lines"): - # line = None - # aperture_size = None - - # the key is the aperture type and the val is a list of geo elements - flash_el_dict = {} - # the key is the aperture size, the val is a list of geo elements - traces_el_dict = {} - - # find the flashes and the lines that are in the selected polygon and store - # them separately - for apid, apval in obj.apertures.items(): - for geo_el in apval['geometry']: - if apval["size"] == 0.0: - if apval["size"] in traces_el_dict: - traces_el_dict[apval["size"]].append(geo_el) - else: - traces_el_dict[apval["size"]] = [geo_el] - - if 'follow' in geo_el and geo_el['follow'].within(geo): - if isinstance(geo_el['follow'], Point): - if apval["type"] == 'C': - if 'C' in flash_el_dict: - flash_el_dict['C'].append(geo_el) - else: - flash_el_dict['C'] = [geo_el] - elif apval["type"] == 'O': - if 'O' in flash_el_dict: - flash_el_dict['O'].append(geo_el) - else: - flash_el_dict['O'] = [geo_el] - elif apval["type"] == 'R': - if 'R' in flash_el_dict: - flash_el_dict['R'].append(geo_el) - else: - flash_el_dict['R'] = [geo_el] - else: - aperture_size = apval['size'] - - if aperture_size in traces_el_dict: - traces_el_dict[aperture_size].append(geo_el) - else: - traces_el_dict[aperture_size] = [geo_el] - - cp = FlatCAMRTreeStorage() - pads_lines_list = [] - - # process the flashes found in the selected polygon with the 'lines' method - # for rectangular flashes and with _("Seed") for oblong and circular flashes - # and pads (flahes) need the contour therefore I override the GUI settings - # with always True - for ap_type in flash_el_dict: - for elem in flash_el_dict[ap_type]: - if 'solid' in elem: - if ap_type == 'C': - f_o = self.clear_polygon2(elem['solid'], - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=True, - connect=conn, - prog_plot=prog_plot) - pads_lines_list += [p for p in f_o.get_objects() if p] - - elif ap_type == 'O': - f_o = self.clear_polygon2(elem['solid'], - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=True, - connect=conn, - prog_plot=prog_plot) - pads_lines_list += [p for p in f_o.get_objects() if p] - - elif ap_type == 'R': - f_o = self.clear_polygon3(elem['solid'], - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=True, - connect=conn, - prog_plot=prog_plot) - - pads_lines_list += [p for p in f_o.get_objects() if p] - - # add the lines from pads to the storage - try: - for lin in pads_lines_list: - if lin: - cp.insert(lin) - except TypeError: - cp.insert(pads_lines_list) - - copper_lines_list = [] - # process the traces found in the selected polygon using the 'laser_lines' - # method, method which will follow the 'follow' line therefore use the longer - # path possible for the laser, therefore the acceleration will play - # a smaller factor - for aperture_size in traces_el_dict: - for elem in traces_el_dict[aperture_size]: - line = elem['follow'] - if line: - t_o = self.fill_with_lines(line, aperture_size, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - - copper_lines_list += [p for p in t_o.get_objects() if p] - - # add the lines from copper features to storage but first try to make as few - # lines as possible - # by trying to fuse them - lines_union = linemerge(unary_union(copper_lines_list)) - try: - for lin in lines_union: - if lin: - cp.insert(lin) - except TypeError: - cp.insert(lines_union) - elif paint_method == _("Combo"): - self.app.inform.emit(_("Painting polygons with method: lines.")) - cp = self.clear_polygon3(geo, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - - if cp and cp.objects: - pass + geo_res = self.paint_polygon_worker(pp, tooldiameter=tool_dia, over=over, conn=conn, + cont=cont, paint_method=paint_method, obj=obj, + prog_plot=prog_plot) + if geo_res and geo_res.objects: + total_geometry += list(geo_res.get_objects()) + poly_processed.append(True) else: - self.app.inform.emit(_("Failed. Painting polygons with method: seed.")) - cp = self.clear_polygon2(geo, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - if cp and cp.objects: - pass - else: - self.app.inform.emit(_("Failed. Painting polygons with method: standard.")) - cp = self.clear_polygon(geo, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, + poly_processed.append(False) + + pol_nr += 1 + disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100])) + # log.debug("Polygons cleared: %d" % pol_nr) + + if old_disp_number < disp_number <= 100: + app_obj.proc_container.update_view_text(' %d%%' % disp_number) + old_disp_number = disp_number + # log.debug("Polygons cleared: %d. Percentage done: %d%%" % (pol_nr, disp_number)) + + except TypeError: + # provide the app with a way to process the GUI events when in a blocking loop + QtWidgets.QApplication.processEvents() + if self.app.abort_flag: + # graceful abort requested by the user + raise FlatCAMApp.GracefulException + + geo_res = self.paint_polygon_worker(poly_buf, tooldiameter=tool_dia, over=over, conn=conn, + cont=cont, paint_method=paint_method, obj=obj, prog_plot=prog_plot) - if cp and cp.objects: - total_geometry += list(cp.get_objects()) - final_solid_geometry += total_geometry - except FlatCAMApp.GracefulException: - return "fail" - except Exception as err: - log.debug("Could not Paint the polygons. %s" % str(err)) - self.app.inform.emit( - '[ERROR] %s\n%s' % - (_("Could not do Paint. Try a different combination of parameters. " - "Or a different strategy of paint"), str(err) - ) - ) - continue + if geo_res and geo_res.objects: + total_geometry += list(geo_res.get_objects()) + poly_processed.append(True) + else: + poly_processed.append(False) - pol_nr += 1 - disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100])) - # log.debug("Polygons cleared: %d" % pol_nr) + except Exception as err: + log.debug("Could not Paint the polygons. %s" % str(err)) + self.app.inform.emit( + '[ERROR] %s\n%s' % + (_("Could not do Paint. Try a different combination of parameters. " + "Or a different strategy of paint"), str(err) + ) + ) + continue - if old_disp_number < disp_number <= 100: - app_obj.proc_container.update_view_text(' %d%%' % disp_number) - old_disp_number = disp_number - # log.debug("Polygons cleared: %d. Percentage done: %d%%" % (pol_nr, disp_number)) + p_cleared = poly_processed.count(True) + p_not_cleared = poly_processed.count(False) + + if p_not_cleared: + app_obj.poly_not_cleared = True + + if p_cleared == 0: + continue # add the solid_geometry to the current too in self.paint_tools (tools_storage) # dictionary and then reset the temporary list that stored that solid_geometry @@ -3418,6 +3092,16 @@ class ToolPaint(FlatCAMTool, Gerber): geo_obj.solid_geometry = cascaded_union(final_solid_geometry) + try: + a, b, c, d = self.paint_bounds(geo_to_paint) + geo_obj.options['xmin'] = a + geo_obj.options['ymin'] = b + geo_obj.options['xmax'] = c + geo_obj.options['ymax'] = d + except Exception as e: + log.debug("ToolPaint.paint_poly.gen_paintarea() bounds error --> %s" % str(e)) + return + # test if at least one tool has solid_geometry. If no tool has solid_geometry we raise an Exception has_solid_geo = 0 for tooluid in geo_obj.tools: @@ -3428,7 +3112,7 @@ class ToolPaint(FlatCAMTool, Gerber): _("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 + return "fail" # Experimental... # print("Indexing...", end=' ') @@ -3438,60 +3122,22 @@ class ToolPaint(FlatCAMTool, Gerber): # Initializes the new geometry object def gen_paintarea_rest_machining(geo_obj, app_obj): - # assert isinstance(geo_obj, FlatCAMGeometry), \ - # "Initializer expected a FlatCAMGeometry, got %s" % type(geo_obj) - log.debug("Paint Tool. Rest machining painting area task started.") - if obj.kind == 'gerber': - if app_obj.defaults["gerber_buffering"] == 'no': - app_obj.inform.emit('%s %s %s' % - (_("Paint Tool."), _("Rest machining painting area task started."), - _("Buffering geometry..."))) - else: - app_obj.inform.emit('%s %s' % - (_("Paint Tool."), _("Rest machining painting area task started."))) - else: - app_obj.inform.emit('%s %s' % - (_("Paint Tool."), _("Rest machining painting area task started."))) - tool_dia = None sorted_tools.sort(reverse=True) cleared_geo = [] + + tool_dia = None current_uid = int(1) - geo_obj.solid_geometry = [] - final_solid_geometry = [] old_disp_number = 0 - # this is were heavy lifting is done and creating the geometry to be painted - target_geo = obj.solid_geometry - - if obj.kind == 'gerber': - if self.app.defaults["tools_paint_plotting"] == 'progressive': - if isinstance(target_geo, list): - target_geo = MultiPolygon(target_geo).buffer(0) - else: - target_geo = target_geo.buffer(0) - - geo_to_paint = target_geo.intersection(sel_obj) - painted_area = recurse(geo_to_paint) - - try: - a, b, c, d = obj.bounds() - geo_obj.options['xmin'] = a - geo_obj.options['ymin'] = b - geo_obj.options['xmax'] = c - geo_obj.options['ymax'] = d - except Exception as e: - log.debug("ToolPaint.paint_poly.gen_paintarea() bounds error --> %s" % str(e)) - return + final_solid_geometry = [] for tool_dia in sorted_tools: log.debug("Starting geometry processing for tool: %s" % str(tool_dia)) app_obj.inform.emit( - '[success] %s %s%s %s' % (_('Painting with tool diameter = '), - str(tool_dia), - self.units.lower(), + '[success] %s %s%s %s' % (_('Painting with tool diameter = '), str(tool_dia), self.units.lower(), _('started')) ) app_obj.proc_container.update_view_text(' %d%%' % 0) @@ -3501,12 +3147,9 @@ class ToolPaint(FlatCAMTool, Gerber): if float('%.*f' % (self.decimals, v['tooldia'])) == float('%.*f' % (self.decimals, tool_dia)): current_uid = int(k) break - if not current_uid: return "fail" - painted_area = recurse(obj.solid_geometry) - # determine the tool parameters to use over = float(tools_storage[current_uid]['data']['tools_paintoverlap']) / 100.0 conn = tools_storage[current_uid]['data']['tools_pathconnect'] @@ -3531,207 +3174,72 @@ class ToolPaint(FlatCAMTool, Gerber): pol_nr = 0 - for geo in poly_buf: + # ----------------------------- + # effective polygon clearing job + # ----------------------------- + poly_processed = [] + + try: try: - cp = None + for pp in poly_buf: + # provide the app with a way to process the GUI events when in a blocking loop + QtWidgets.QApplication.processEvents() + if self.app.abort_flag: + # graceful abort requested by the user + raise FlatCAMApp.GracefulException - if paint_method == _("Standard"): - # Type(cp) == FlatCAMRTreeStorage | None - cp = self.clear_polygon(geo, tooldia=tool_dia, - steps_per_circle=self.app.defaults["geometry_circle_steps"], - overlap=over, contour=cont, connect=conn, - prog_plot=prog_plot) - elif paint_method == _("Seed"): - # Type(cp) == FlatCAMRTreeStorage | None - cp = self.clear_polygon2(geo, tooldia=tool_dia, - steps_per_circle=self.app.defaults["geometry_circle_steps"], - overlap=over, contour=cont, connect=conn, - prog_plot=prog_plot) - elif paint_method == _("Lines"): - # Type(cp) == FlatCAMRTreeStorage | None - cp = self.clear_polygon3(geo, tooldia=tool_dia, - steps_per_circle=self.app.defaults["geometry_circle_steps"], - overlap=over, contour=cont, connect=conn, - prog_plot=prog_plot) - elif paint_method == _("Laser_lines"): - # line = None - # aperture_size = None - - # the key is the aperture type and the val is a list of geo elements - flash_el_dict = {} - # the key is the aperture size, the val is a list of geo elements - copper_el_dict = {} - - # find the flashes and the lines that are in the selected polygon and store - # them separately - for apid, apval in obj.apertures.items(): - for geo_el in apval['geometry']: - if apval["size"] == 0.0: - if apval["size"] in copper_el_dict: - copper_el_dict[apval["size"]].append(geo_el) - else: - copper_el_dict[apval["size"]] = [geo_el] - - if 'follow' in geo_el and geo_el['follow'].within(geo): - if isinstance(geo_el['follow'], Point): - if apval["type"] == 'C': - if 'C' in flash_el_dict: - flash_el_dict['C'].append(geo_el) - else: - flash_el_dict['C'] = [geo_el] - elif apval["type"] == 'O': - if 'O' in flash_el_dict: - flash_el_dict['O'].append(geo_el) - else: - flash_el_dict['O'] = [geo_el] - elif apval["type"] == 'R': - if 'R' in flash_el_dict: - flash_el_dict['R'].append(geo_el) - else: - flash_el_dict['R'] = [geo_el] - else: - aperture_size = apval['size'] - - if aperture_size in copper_el_dict: - copper_el_dict[aperture_size].append(geo_el) - else: - copper_el_dict[aperture_size] = [geo_el] - - cp = FlatCAMRTreeStorage() - pads_lines_list = [] - - # process the flashes found in the selected polygon with the 'lines' method - # for rectangular flashes and with _("Seed") for oblong and circular flashes - # and pads (flahes) need the contour therefore I override the GUI settings - # with always True - for ap_type in flash_el_dict: - for elem in flash_el_dict[ap_type]: - if 'solid' in elem: - if ap_type == 'C': - f_o = self.clear_polygon2(elem['solid'], - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=True, - connect=conn, - prog_plot=prog_plot) - pads_lines_list += [p for p in f_o.get_objects() if p] - - elif ap_type == 'O': - f_o = self.clear_polygon2(elem['solid'], - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=True, - connect=conn, - prog_plot=prog_plot) - pads_lines_list += [p for p in f_o.get_objects() if p] - - elif ap_type == 'R': - f_o = self.clear_polygon3(elem['solid'], - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=True, - connect=conn, - prog_plot=prog_plot) - - pads_lines_list += [p for p in f_o.get_objects() if p] - - # add the lines from pads to the storage - try: - for lin in pads_lines_list: - if lin: - cp.insert(lin) - except TypeError: - cp.insert(pads_lines_list) - - copper_lines_list = [] - # process the traces found in the selected polygon using the 'laser_lines' - # method, method which will follow the 'follow' line therefore use the longer - # path possible for the laser, therefore the acceleration will play - # a smaller factor - for aperture_size in copper_el_dict: - for elem in copper_el_dict[aperture_size]: - line = elem['follow'] - if line: - t_o = self.fill_with_lines(line, aperture_size, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - - copper_lines_list += [p for p in t_o.get_objects() if p] - - # add the lines from copper features to storage but first try to make as few - # lines as possible - # by trying to fuse them - lines_union = linemerge(unary_union(copper_lines_list)) - try: - for lin in lines_union: - if lin: - cp.insert(lin) - except TypeError: - cp.insert(lines_union) - elif paint_method == _("Combo"): - self.app.inform.emit(_("Painting polygons with method: lines.")) - cp = self.clear_polygon3(geo, - tooldia=tool_dia, - steps_per_circle=self.app.defaults["geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - - if cp and cp.objects: - pass + geo_res = self.paint_polygon_worker(pp, tooldiameter=tool_dia, over=over, conn=conn, + cont=cont, paint_method=paint_method, obj=obj, + prog_plot=prog_plot) + if geo_res and geo_res.objects: + cleared_geo += list(geo_res.get_objects()) + poly_processed.append(True) else: - self.app.inform.emit(_("Failed. Painting polygons with method: seed.")) - cp = self.clear_polygon2(geo, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, - prog_plot=prog_plot) - if cp and cp.objects: - pass - else: - self.app.inform.emit(_("Failed. Painting polygons with method: standard.")) - cp = self.clear_polygon(geo, - tooldia=tool_dia, - steps_per_circle=self.app.defaults[ - "geometry_circle_steps"], - overlap=over, - contour=cont, - connect=conn, + poly_processed.append(False) + + pol_nr += 1 + disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100])) + # log.debug("Polygons cleared: %d" % pol_nr) + + if old_disp_number < disp_number <= 100: + app_obj.proc_container.update_view_text(' %d%%' % disp_number) + old_disp_number = disp_number + # log.debug("Polygons cleared: %d. Percentage done: %d%%" % (pol_nr, disp_number)) + + except TypeError: + # provide the app with a way to process the GUI events when in a blocking loop + QtWidgets.QApplication.processEvents() + if self.app.abort_flag: + # graceful abort requested by the user + raise FlatCAMApp.GracefulException + + geo_res = self.paint_polygon_worker(poly_buf, tooldiameter=tool_dia, over=over, conn=conn, + cont=cont, paint_method=paint_method, obj=obj, prog_plot=prog_plot) - if cp and cp.objects: - cleared_geo += list(cp.get_objects()) - except FlatCAMApp.GracefulException: - return "fail" - except Exception as e: - log.debug("Could not Paint the polygons. %s" % str(e)) - self.app.inform.emit('[ERROR] %s\n%s' % - (_("Could not do Paint All. Try a different combination of parameters. " - "Or a different Method of paint"), str(e))) - return + if geo_res and geo_res.objects: + cleared_geo += list(geo_res.get_objects()) + poly_processed.append(True) + else: + poly_processed.append(False) - pol_nr += 1 - disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100])) - # log.debug("Polygons cleared: %d" % pol_nr) + except Exception as err: + log.debug("Could not Paint the polygons. %s" % str(err)) + self.app.inform.emit( + '[ERROR] %s\n%s' % + (_("Could not do Paint. Try a different combination of parameters. " + "Or a different strategy of paint"), str(err) + ) + ) + continue - if old_disp_number < disp_number <= 100: - app_obj.proc_container.update_view_text(' %d%%' % disp_number) - old_disp_number = disp_number - # log.debug("Polygons cleared: %d. Percentage done: %d%%" % (pol_nr, disp_number)) + p_cleared = poly_processed.count(True) + p_not_cleared = poly_processed.count(False) + + if p_not_cleared: + app_obj.poly_not_cleared = True + + if p_cleared == 0: + continue final_solid_geometry += cleared_geo # add the solid_geometry to the current too in self.paint_tools (or tools_storage) dictionary and @@ -3761,6 +3269,18 @@ class ToolPaint(FlatCAMTool, Gerber): geo_obj.tools.clear() geo_obj.tools = dict(tools_storage) + geo_obj.solid_geometry = cascaded_union(final_solid_geometry) + + try: + a, b, c, d = self.paint_bounds(geo_to_paint) + geo_obj.options['xmin'] = a + geo_obj.options['ymin'] = b + geo_obj.options['xmax'] = c + geo_obj.options['ymax'] = d + except Exception as e: + log.debug("ToolPaint.paint_poly.gen_paintarea_rest_machining() bounds error --> %s" % str(e)) + return + # test if at least one tool has solid_geometry. If no tool has solid_geometry we raise an Exception has_solid_geo = 0 for tooluid in geo_obj.tools: @@ -3782,19 +3302,27 @@ class ToolPaint(FlatCAMTool, Gerber): def job_thread(app_obj): try: if self.rest_cb.isChecked(): - app_obj.new_object("geometry", name, gen_paintarea_rest_machining, plot=plot) + ret = app_obj.new_object("geometry", name, gen_paintarea_rest_machining, plot=plot) else: - app_obj.new_object("geometry", name, gen_paintarea, plot=plot) + ret = app_obj.new_object("geometry", name, gen_paintarea, plot=plot) except FlatCAMApp.GracefulException: proc.done() return - except Exception: + except Exception as err: proc.done() + app_obj.inform.emit('[ERROR] %s --> %s' % ('PaintTool.paint_poly_area()', str(err))) traceback.print_stack() return proc.done() + + if ret == 'fail': + self.app.inform.emit('[ERROR] %s' % _("Paint Area failed.")) + return + # focus on Selected Tab - self.app.ui.notebook.setCurrentWidget(self.app.ui.selected_tab) + # self.app.ui.notebook.setCurrentWidget(self.app.ui.selected_tab) + + self.app.inform.emit('[success] %s' % _("Paint Poly Area Done.")) self.app.inform.emit(_("Polygon Paint started ...")) @@ -3807,35 +3335,21 @@ class ToolPaint(FlatCAMTool, Gerber): else: job_thread(app_obj=self.app) - def paint_poly_ref(self, obj, sel_obj, - tooldia=None, - overlap=None, - order=None, - margin=None, - method=None, - outname=None, - connect=None, - contour=None, - tools_storage=None, - plot=True, - run_threaded=True): + def paint_poly_ref(self, obj, sel_obj, tooldia=None, order=None, method=None, outname=None, + tools_storage=None, plot=True, run_threaded=True): """ Paints all polygons in this object that are within the sel_obj object - :param run_threaded: - :param plot: :param obj: painted object :param sel_obj: paint only what is inside this object bounds :param tooldia: a tuple or single element made out of diameters of the tools to be used - :param overlap: value by which the paths will overlap :param order: if the tools are ordered and how - :param margin: a border around painting area :param outname: name of the resulting object - :param connect: Connect lines to avoid tool lifts. - :param contour: Paint around the edges. :param method: choice out of _("Seed"), 'normal', 'lines' :param tools_storage: whether to use the current tools_storage self.paints_tools or a different one. Usage of the different one is related to when this function is called from a TcL command. + :param run_threaded: + :param plot: :return: """ geo = sel_obj.solid_geometry @@ -3850,20 +3364,16 @@ class ToolPaint(FlatCAMTool, Gerber): 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)) + log.debug("ToolPaint.paint_poly_ref() --> %s" % str(e)) self.app.inform.emit('[ERROR_NOTCL] %s' % _("No object available.")) return self.paint_poly_area(obj=obj, sel_obj=sel_rect, tooldia=tooldia, - overlap=overlap, order=order, - margin=margin, method=method, outname=outname, - connect=connect, - contour=contour, tools_storage=tools_storage, plot=plot, run_threaded=run_threaded) diff --git a/tclCommands/TclCommandCopperClear.py b/tclCommands/TclCommandCopperClear.py index 29c73cd5..b82efdfd 100644 --- a/tclCommands/TclCommandCopperClear.py +++ b/tclCommands/TclCommandCopperClear.py @@ -122,8 +122,21 @@ class TclCommandCopperClear(TclCommand): if 'method' in args: method = args['method'] + if method == "standard": + method_data = _("Standard") + elif method == "seed": + method_data = _("Seed") + else: + method_data = _("Lines") else: method = str(self.app.defaults["tools_nccmethod"]) + method_data = method + if method == _("Standard"): + method = "standard" + elif method == _("Seed"): + method = "seed" + else: + method = "lines" if 'connect' in args: try: @@ -155,11 +168,34 @@ class TclCommandCopperClear(TclCommand): except AttributeError: tools = [float(tooldia)] + if 'rest' in args: + try: + par = args['rest'].capitalize() + except AttributeError: + par = args['rest'] + rest = bool(eval(par)) + else: + rest = bool(eval(str(self.app.defaults["tools_nccrest"]))) + + if 'outname' in args: + outname = args['outname'] + else: + if rest is True: + outname = name + "_ncc" + else: + outname = name + "_ncc_rm" + + # used only to have correct information's in the obj.tools[tool]['data'] dict + if "all" in args: + select = _("Itself") + else: + select = _("Reference Object") + # store here the default data for Geometry Data default_data = {} default_data.update({ - "name": '_paint', - "plot": self.app.defaults["geometry_plot"], + "name": outname, + "plot": False, "cutz": self.app.defaults["geometry_cutz"], "vtipdia": 0.1, "vtipangle": 30, @@ -183,12 +219,12 @@ class TclCommandCopperClear(TclCommand): "startz": self.app.defaults["geometry_startz"], "tooldia": self.app.defaults["tools_painttooldia"], - "paintmargin": self.app.defaults["tools_paintmargin"], - "paintmethod": self.app.defaults["tools_paintmethod"], - "selectmethod": self.app.defaults["tools_selectmethod"], - "pathconnect": self.app.defaults["tools_pathconnect"], - "paintcontour": self.app.defaults["tools_paintcontour"], - "paintoverlap": self.app.defaults["tools_paintoverlap"] + "tools_nccmargin": margin, + "tools_nccmethod": method_data, + "tools_nccref": select, + "tools_nccconnect": connect, + "tools_ncccontour": contour, + "tools_nccoverlap": overlap }) ncc_tools = {} @@ -206,23 +242,7 @@ class TclCommandCopperClear(TclCommand): 'solid_geometry': [] } }) - - if 'rest' in args: - try: - par = args['rest'].capitalize() - except AttributeError: - par = args['rest'] - rest = bool(eval(par)) - else: - rest = bool(eval(str(self.app.defaults["tools_nccrest"]))) - - if 'outname' in args: - outname = args['outname'] - else: - if rest is True: - outname = name + "_ncc" - else: - outname = name + "_ncc_rm" + ncc_tools[int(tooluid)]['data']['tooldia'] = float('%.*f' % (obj.decimals, tool)) # Non-Copper clear all polygons in the non-copper clear object if 'all' in args: diff --git a/tclCommands/TclCommandPaint.py b/tclCommands/TclCommandPaint.py index 7e54e1c6..6b8a85ba 100644 --- a/tclCommands/TclCommandPaint.py +++ b/tclCommands/TclCommandPaint.py @@ -66,7 +66,7 @@ class TclCommandPaint(TclCommand): '"no" -> the order used is the one provided.' '"fwd" -> tools are ordered from smallest to biggest.' '"rev" -> tools are ordered from biggest to smallest.'), - ('method', 'Algorithm for painting. Can be: "standard", "seed" or "lines".'), + ('method', 'Algorithm for painting. Can be: "standard", "seed", "lines", "laser_lines", "combo".'), ('connect', 'Draw lines to minimize tool lifts. True (1) or False (0)'), ('contour', 'Cut around the perimeter of the painting. True (1) or False (0)'), ('all', 'If used, paint all polygons in the object.'), @@ -121,6 +121,16 @@ class TclCommandPaint(TclCommand): if 'method' in args: method = args['method'] + if method == "standard": + method = _("Standard") + elif method == "seed": + method = _("Seed") + elif method == "lines": + method = _("Lines") + elif method == "laser_lines": + method = _("Laser_lines") + else: + method = _("Combo") else: method = str(self.app.defaults["tools_paintmethod"]) @@ -147,6 +157,14 @@ class TclCommandPaint(TclCommand): else: outname = name + "_paint" + # used only to have correct information's in the obj.tools[tool]['data'] dict + if "all" in args: + select = _("All Polygons") + elif "single" in args: + select = _("Polygon Selection") + else: + select = _("Reference Object") + try: tools = [float(eval(dia)) for dia in tooldia.split(",") if dia != ''] except AttributeError: @@ -154,8 +172,8 @@ class TclCommandPaint(TclCommand): # store here the default data for Geometry Data default_data = {} default_data.update({ - "name": '_paint', - "plot": self.app.defaults["geometry_plot"], + "name": outname, + "plot": False, "cutz": self.app.defaults["geometry_cutz"], "vtipdia": 0.1, "vtipangle": 30, @@ -180,12 +198,12 @@ class TclCommandPaint(TclCommand): "startz": self.app.defaults["geometry_startz"], "tooldia": self.app.defaults["tools_painttooldia"], - "paintmargin": self.app.defaults["tools_paintmargin"], - "paintmethod": self.app.defaults["tools_paintmethod"], - "selectmethod": self.app.defaults["tools_selectmethod"], - "pathconnect": self.app.defaults["tools_pathconnect"], - "paintcontour": self.app.defaults["tools_paintcontour"], - "paintoverlap": self.app.defaults["tools_paintoverlap"] + "paintmargin": margin, + "paintmethod": method, + "selectmethod": select, + "pathconnect": connect, + "paintcontour": contour, + "paintoverlap": overlap }) paint_tools = {} @@ -203,6 +221,7 @@ class TclCommandPaint(TclCommand): 'solid_geometry': [] } }) + paint_tools[int(tooluid)]['data']['tooldia'] = float('%.*f' % (obj.decimals, tool)) if obj is None: return "Object not found: %s" % name @@ -211,13 +230,9 @@ class TclCommandPaint(TclCommand): if 'all' in args: self.app.paint_tool.paint_poly_all(obj=obj, tooldia=tooldia, - overlap=overlap, order=order, - margin=margin, method=method, outname=outname, - connect=connect, - contour=contour, tools_storage=paint_tools, plot=False, run_threaded=False) @@ -234,13 +249,9 @@ class TclCommandPaint(TclCommand): self.app.paint_tool.paint_poly(obj=obj, inside_pt=[x, y], tooldia=tooldia, - overlap=overlap, order=order, - margin=margin, method=method, outname=outname, - connect=connect, - contour=contour, tools_storage=paint_tools, plot=False, run_threaded=False) @@ -264,13 +275,9 @@ class TclCommandPaint(TclCommand): self.app.paint_tool.paint_poly_ref(obj=obj, sel_obj=box_obj, tooldia=tooldia, - overlap=overlap, order=order, - margin=margin, method=method, outname=outname, - connect=connect, - contour=contour, tools_storage=paint_tools, plot=False, run_threaded=False) From a76a7d29da094f3b00fe7e5ba3d637a2632c1cac Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 24 Apr 2020 21:14:00 +0300 Subject: [PATCH 206/209] - updated the language template and the Romanian translation to the latest changes --- locale/en/LC_MESSAGES/strings.mo | Bin 352042 -> 351502 bytes locale/en/LC_MESSAGES/strings.po | 537 ++++++++----------------------- locale/ro/LC_MESSAGES/strings.mo | Bin 380697 -> 380061 bytes locale/ro/LC_MESSAGES/strings.po | 233 +++++++------- locale_template/strings.pot | 187 +++++------ 5 files changed, 338 insertions(+), 619 deletions(-) diff --git a/locale/en/LC_MESSAGES/strings.mo b/locale/en/LC_MESSAGES/strings.mo index a6bb163f94d2d616151c1638ec924bd41df10961..f56c057cf1268cb5b424095692d226836f30b290 100644 GIT binary patch delta 66540 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

o3V!dq5l14X0r! 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 B8V~>g delta 66689 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 to get started\n" -#| "\n" msgid "Type >help< to get started" msgstr "Type >help< to get started" @@ -257,17 +255,14 @@ msgid "Exported preferences to" msgstr "Exported preferences to" #: FlatCAMApp.py:4053 FlatCAMApp.py:4058 -#| msgid "Saved to" msgid "Save to file" msgstr "Save to file" #: FlatCAMApp.py:4082 -#| msgid "Could not load defaults file." msgid "Could not load the file." msgstr "Could not load the file." #: FlatCAMApp.py:4098 -#| msgid "Exported Tools DB to" msgid "Exported file to" msgstr "Exported file to" @@ -693,7 +688,6 @@ msgid "Origin coordinates specified but incomplete." msgstr "Origin coordinates specified but incomplete." #: FlatCAMApp.py:7190 -#| msgid "Setting Origin..." msgid "Moving to Origin..." msgstr "Moving to Origin..." @@ -733,7 +727,6 @@ msgid "No object selected." msgstr "No object selected." #: FlatCAMApp.py:7394 -#| msgid "Bottom Left" msgid "Bottom-Left" msgstr "Bottom-Left" @@ -748,7 +741,6 @@ msgid "Bottom-Right" msgstr "Bottom-Right" #: FlatCAMApp.py:7397 -#| msgid "Top Right" msgid "Top-Right" msgstr "Top-Right" @@ -757,7 +749,6 @@ msgid "Center" msgstr "Center" #: FlatCAMApp.py:7418 -#| msgid "Rotate ..." msgid "Locate ..." msgstr "Locate ..." @@ -783,7 +774,7 @@ msgstr "Preferences edited but not saved." #: FlatCAMApp.py:8038 FlatCAMCommon.py:1182 FlatCAMCommon.py:1357 #: FlatCAMCommon.py:2612 FlatCAMCommon.py:2820 FlatCAMObj.py:4798 #: flatcamTools/ToolNCC.py:3963 flatcamTools/ToolNCC.py:4047 -#: flatcamTools/ToolPaint.py:4027 flatcamTools/ToolPaint.py:4112 +#: flatcamTools/ToolPaint.py:3537 flatcamTools/ToolPaint.py:3622 msgid "Tools Database" msgstr "Tools Database" @@ -792,7 +783,7 @@ msgid "Tools in Tools Database edited but not saved." msgstr "Tools in Tools Database edited but not saved." #: FlatCAMApp.py:7975 flatcamTools/ToolNCC.py:3970 -#: flatcamTools/ToolPaint.py:4034 +#: flatcamTools/ToolPaint.py:3544 msgid "Tool from DB added in Tool Table." msgstr "Tool from DB added in Tool Table." @@ -1154,12 +1145,10 @@ msgid "Failed to load the source code for the selected object" msgstr "Failed to load the source code for the selected object" #: FlatCAMApp.py:10274 -#| msgid "Plot Line" msgid "Go to Line ..." msgstr "Go to Line ..." #: FlatCAMApp.py:10275 -#| msgid "Line" msgid "Line:" msgstr "Line:" @@ -1537,9 +1526,6 @@ msgid "Newer Version Available" msgstr "Newer Version Available" #: FlatCAMApp.py:12158 -#| msgid "" -#| "There is a newer version of FlatCAM available for download:\n" -#| "\n" msgid "There is a newer version of FlatCAM available for download:" msgstr "There is a newer version of FlatCAM available for download:" @@ -1628,7 +1614,6 @@ msgid "Custom" msgstr "Custom" #: FlatCAMApp.py:12488 flatcamGUI/FlatCAMGUI.py:722 -#| msgid "Defaults" msgid "Default" msgstr "Default" @@ -1645,7 +1630,6 @@ msgstr "Set alpha level ..." #: flatcamTools/ToolExtractDrills.py:164 flatcamTools/ToolExtractDrills.py:285 #: flatcamTools/ToolPunchGerber.py:192 flatcamTools/ToolPunchGerber.py:308 #: flatcamTools/ToolTransform.py:358 -#| msgid "Value X:" msgid "Value" msgstr "Value" @@ -2305,22 +2289,18 @@ msgid "Cancelled adding tool from DB." msgstr "Cancelled adding tool from DB." #: FlatCAMCommon.py:1462 -#| msgid "GCode Parameters" msgid "Basic Geo Parameters" msgstr "Basic Geo Parameters" #: FlatCAMCommon.py:1474 -#| msgid "Advanced Param." msgid "Advanced Geo Parameters" msgstr "Advanced Geo Parameters" #: FlatCAMCommon.py:1486 -#| msgid "Parameters" msgid "NCC Parameters" msgstr "NCC Parameters" #: FlatCAMCommon.py:1498 -#| msgid "Slot Parameters" msgid "Paint Parameters" msgstr "Paint Parameters" @@ -2331,9 +2311,6 @@ msgid "Feedrate X-Y" msgstr "Feedrate X-Y" #: FlatCAMCommon.py:1631 -#| msgid "" -#| "FR. Feedrate\n" -#| "The speed on XY plane used while cutting into material." msgid "" "Feedrate X-Y. Feedrate\n" "The speed on XY plane used while cutting into material." @@ -2348,9 +2325,6 @@ msgid "Feedrate Z" msgstr "Feedrate Z" #: FlatCAMCommon.py:1645 -#| msgid "" -#| "FR Z. Feedrate Z\n" -#| "The speed on Z plane." msgid "" "Feedrate Z\n" "The speed on Z plane." @@ -2382,7 +2356,6 @@ msgstr "Clear" #: FlatCAMCommon.py:1853 flatcamTools/ToolNCC.py:351 #: flatcamTools/ToolNCC.py:1627 -#| msgid "Isolation Type" msgid "Isolation" msgstr "Isolation" @@ -2421,20 +2394,11 @@ msgstr "Conventional" #: flatcamEditors/FlatCAMGeoEditor.py:452 flatcamGUI/PreferencesUI.py:5461 #: flatcamGUI/PreferencesUI.py:6002 flatcamTools/ToolNCC.py:382 #: flatcamTools/ToolPaint.py:329 -#| msgid "Overlap Rate" msgid "Overlap" msgstr "Overlap" #: FlatCAMCommon.py:1883 flatcamGUI/PreferencesUI.py:5463 #: flatcamTools/ToolNCC.py:384 -#| msgid "" -#| "How much (fraction) of the tool width to overlap each tool pass.\n" -#| "Adjust the value starting with lower values\n" -#| "and increasing it if areas that should be cleared are still \n" -#| "not cleared.\n" -#| "Lower values = faster processing, faster execution on CNC.\n" -#| "Higher values = slow processing and slow execution on CNC\n" -#| "due of too many paths." msgid "" "How much (percentage) of the tool width to overlap each tool pass.\n" "Adjust the value starting with lower values\n" @@ -2484,11 +2448,6 @@ msgstr "Method" #: FlatCAMCommon.py:1917 flatcamGUI/PreferencesUI.py:5496 #: flatcamTools/ToolNCC.py:418 -#| msgid "" -#| "Algorithm for painting:\n" -#| "- Standard: Fixed step inwards.\n" -#| "- Seed-based: Outwards from seed.\n" -#| "- Line-based: Parallel lines." msgid "" "Algorithm for copper clearing:\n" "- Standard: Fixed step inwards.\n" @@ -2505,9 +2464,9 @@ msgstr "" #: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 #: flatcamTools/ToolNCC.py:2395 flatcamTools/ToolNCC.py:2424 #: flatcamTools/ToolNCC.py:2693 flatcamTools/ToolNCC.py:2725 -#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:1818 -#: flatcamTools/ToolPaint.py:2717 flatcamTools/ToolPaint.py:3198 -#: flatcamTools/ToolPaint.py:3538 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:1822 +#: tclCommands/TclCommandCopperClear.py:126 +#: tclCommands/TclCommandCopperClear.py:134 tclCommands/TclCommandPaint.py:125 msgid "Standard" msgstr "Standard" @@ -2516,9 +2475,8 @@ msgstr "Standard" #: flatcamEditors/FlatCAMGeoEditor.py:5156 flatcamGUI/PreferencesUI.py:5509 #: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 #: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:696 -#: flatcamTools/ToolPaint.py:1846 flatcamTools/ToolPaint.py:2729 -#: flatcamTools/ToolPaint.py:3188 flatcamTools/ToolPaint.py:3550 -#| msgid "Line" +#: flatcamTools/ToolPaint.py:1850 tclCommands/TclCommandCopperClear.py:130 +#: tclCommands/TclCommandPaint.py:129 msgid "Lines" msgstr "Lines" @@ -2579,14 +2537,6 @@ msgstr "" #: FlatCAMCommon.py:1992 flatcamEditors/FlatCAMGeoEditor.py:454 #: flatcamGUI/PreferencesUI.py:6004 flatcamTools/ToolPaint.py:331 -#| msgid "" -#| "How much (fraction) of the tool width to overlap each tool pass.\n" -#| "Adjust the value starting with lower values\n" -#| "and increasing it if areas that should be painted are still \n" -#| "not painted.\n" -#| "Lower values = faster processing, faster execution on CNC.\n" -#| "Higher values = slow processing and slow execution on CNC\n" -#| "due of too many paths." msgid "" "How much (percentage) of the tool width to overlap each tool pass.\n" "Adjust the value starting with lower values\n" @@ -2639,22 +2589,17 @@ msgstr "" #: FlatCAMCommon.py:2040 FlatCAMCommon.py:2042 flatcamGUI/PreferencesUI.py:6056 #: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:392 #: flatcamTools/ToolPaint.py:690 flatcamTools/ToolPaint.py:695 -#: flatcamTools/ToolPaint.py:1860 flatcamTools/ToolPaint.py:2735 -#: flatcamTools/ToolPaint.py:3207 flatcamTools/ToolPaint.py:3556 -#| msgid "lines" +#: flatcamTools/ToolPaint.py:1864 tclCommands/TclCommandPaint.py:131 msgid "Laser_lines" msgstr "Laser_lines" #: FlatCAMCommon.py:2040 flatcamGUI/PreferencesUI.py:6056 -#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:2011 -#: flatcamTools/ToolPaint.py:2861 flatcamTools/ToolPaint.py:3333 -#: flatcamTools/ToolPaint.py:3682 -#| msgid "Combine" +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:2015 +#: tclCommands/TclCommandPaint.py:133 msgid "Combo" msgstr "Combo" #: FlatCAMCommon.py:2085 -#| msgid "Add Geometry Tool in DB" msgid "Add Tool in DB" msgstr "Add Tool in DB" @@ -2753,7 +2698,6 @@ msgid "Done" msgstr "Done" #: FlatCAMObj.py:1032 FlatCAMObj.py:1058 -#| msgid "Scaling could not be executed." msgid "Operation could not be done." msgstr "Operation could not be done." @@ -2836,12 +2780,10 @@ msgstr "Parameters for" #: FlatCAMObj.py:2857 FlatCAMObj.py:3089 FlatCAMObj.py:4242 FlatCAMObj.py:4703 #: flatcamTools/ToolNCC.py:808 flatcamTools/ToolNCC.py:1189 #: flatcamTools/ToolPaint.py:776 flatcamTools/ToolPaint.py:1159 -#| msgid "Rules Tool" msgid "Multiple Tools" msgstr "Multiple Tools" #: FlatCAMObj.py:3069 -#| msgid "Tool Selection" msgid "No Tool Selected" msgstr "No Tool Selected" @@ -2909,7 +2851,6 @@ msgid "Generating CNC Code" msgstr "Generating CNC Code" #: FlatCAMObj.py:3966 flatcamTools/ToolNCC.py:916 flatcamTools/ToolPaint.py:841 -#| msgid "Apply parameters to all tools" msgid "Current Tool parameters were applied to all tools." msgstr "Current Tool parameters were applied to all tools." @@ -3248,10 +3189,6 @@ msgstr "" "but now there is only one value, not two. " #: camlib.py:2687 camlib.py:3590 camlib.py:3958 -#| msgid "" -#| "The Toolchange X,Y field in Edit -> Preferences has to be in the format " -#| "(x, y) \n" -#| "but now there is only one value, not two." msgid "" "The End Move X,Y field in Edit -> Preferences has to be in the format (x, y) " "but now there is only one value, not two." @@ -3992,18 +3929,10 @@ msgid "Tool dia" msgstr "Tool dia" #: flatcamEditors/FlatCAMGeoEditor.py:442 -#| msgid "" -#| "Diameter of the tool to\n" -#| "be used in the operation." msgid "Diameter of the tool to be used in the operation." msgstr "Diameter of the tool to be used in the operation." #: flatcamEditors/FlatCAMGeoEditor.py:488 -#| msgid "" -#| "Algorithm for painting:\n" -#| "- Standard: Fixed step inwards.\n" -#| "- Seed-based: Outwards from seed.\n" -#| "- Line-based: Parallel lines." msgid "" "Algorithm to paint the polygons:\n" "- Standard: Fixed step inwards.\n" @@ -4040,7 +3969,6 @@ msgstr "Paint Tool" #: flatcamEditors/FlatCAMGeoEditor.py:3081 #: flatcamEditors/FlatCAMGeoEditor.py:4502 #: flatcamEditors/FlatCAMGrbEditor.py:5601 -#| msgid "Copy cancelled. No shape selected." msgid "Cancelled. No shape selected." msgstr "Cancelled. No shape selected." @@ -4804,17 +4732,14 @@ msgid "Polygon" msgstr "Polygon" #: flatcamEditors/FlatCAMGeoEditor.py:3594 -#| msgid "Multi-Geo" msgid "Multi-Line" msgstr "Multi-Line" #: flatcamEditors/FlatCAMGeoEditor.py:3596 -#| msgid "Multi-Color" msgid "Multi-Polygon" msgstr "Multi-Polygon" #: flatcamEditors/FlatCAMGeoEditor.py:3603 -#| msgid "Geo Type" msgid "Geo Elem" msgstr "Geo Elem" @@ -4886,7 +4811,6 @@ msgstr "Exterior buffer geometry created." #: flatcamEditors/FlatCAMGeoEditor.py:5098 #, python-format -#| msgid "Could not do Paint. Overlap value has to be less than 1.00 (100%%)." msgid "Could not do Paint. Overlap value has to be less than 100%%." msgstr "Could not do Paint. Overlap value has to be less than 100%%." @@ -5644,12 +5568,10 @@ msgid "Save" msgstr "Save" #: flatcamGUI/FlatCAMGUI.py:159 -#| msgid "Save Project &As ...\tCtrl+S" msgid "&Save Project ...\tCtrl+S" msgstr "&Save Project ...\tCtrl+S" #: flatcamGUI/FlatCAMGUI.py:164 -#| msgid "Save Project &As ...\tCtrl+S" msgid "Save Project &As ...\tCtrl+Shift+S" msgstr "Save Project &As ...\tCtrl+Shift+S" @@ -5877,7 +5799,6 @@ msgid "Se&t Origin\tO" msgstr "Se&t Origin\tO" #: flatcamGUI/FlatCAMGUI.py:387 -#| msgid "Se&t Origin\tO" msgid "Move to Origin\tShift+O" msgstr "Move to Origin\tShift+O" @@ -6294,7 +6215,6 @@ msgid "Set Origin" msgstr "Set Origin" #: flatcamGUI/FlatCAMGUI.py:859 -#| msgid "Set Origin" msgid "Move to Origin" msgstr "Move to Origin" @@ -6304,7 +6224,6 @@ msgstr "Jump to Location" #: flatcamGUI/FlatCAMGUI.py:864 flatcamGUI/FlatCAMGUI.py:1719 #: flatcamGUI/FlatCAMGUI.py:2545 -#| msgid "Document Object" msgid "Locate in Object" msgstr "Locate in Object" @@ -6341,13 +6260,11 @@ msgstr "2Sided Tool" #: flatcamGUI/FlatCAMGUI.py:900 flatcamGUI/FlatCAMGUI.py:1725 #: flatcamGUI/FlatCAMGUI.py:2579 -#| msgid "Excellon Object Color" msgid "Align Objects Tool" msgstr "Align Objects Tool" #: flatcamGUI/FlatCAMGUI.py:902 flatcamGUI/FlatCAMGUI.py:1726 #: flatcamGUI/FlatCAMGUI.py:2581 flatcamTools/ToolExtractDrills.py:393 -#| msgid "Create Drills GCode" msgid "Extract Drills Tool" msgstr "Extract Drills Tool" @@ -6420,12 +6337,10 @@ msgid "Calibration Tool" msgstr "Calibration Tool" #: flatcamGUI/FlatCAMGUI.py:941 flatcamGUI/FlatCAMGUI.py:1726 -#| msgid "Paint Area Tool" msgid "Punch Gerber Tool" msgstr "Punch Gerber Tool" #: flatcamGUI/FlatCAMGUI.py:943 flatcamTools/ToolInvertGerber.py:31 -#| msgid "Convert Any to Gerber" msgid "Invert Gerber Tool" msgstr "Invert Gerber Tool" @@ -6808,7 +6723,6 @@ msgid "PDF Import Tool" msgstr "PDF Import Tool" #: flatcamGUI/FlatCAMGUI.py:1715 -#| msgid "Save project" msgid "Save Project" msgstr "Save Project" @@ -7418,7 +7332,6 @@ msgstr "" "from the current mouse location point." #: flatcamGUI/GUIElements.py:2573 -#| msgid "Saved to" msgid "Save Log" msgstr "Save Log" @@ -7649,7 +7562,6 @@ msgid "Pass overlap" msgstr "Pass overlap" #: flatcamGUI/ObjectUI.py:396 flatcamGUI/PreferencesUI.py:2232 -#| msgid "How much (fraction) of the tool width to overlap each tool pass." msgid "How much (percentage) of the tool width to overlap each tool pass." msgstr "How much (percentage) of the tool width to overlap each tool pass." @@ -8045,12 +7957,10 @@ msgstr "" "- Milling -> will mill the drills/slots" #: flatcamGUI/ObjectUI.py:852 flatcamGUI/PreferencesUI.py:3272 -#| msgid "Drills" msgid "Drilling" msgstr "Drilling" #: flatcamGUI/ObjectUI.py:853 flatcamGUI/PreferencesUI.py:3273 -#| msgid "Milling Type" msgid "Milling" msgstr "Milling" @@ -8072,14 +7982,10 @@ msgid "Both" msgstr "Both" #: flatcamGUI/ObjectUI.py:885 flatcamGUI/PreferencesUI.py:3298 -#| msgid "Tip Diameter" msgid "Milling Diameter" msgstr "Milling Diameter" #: flatcamGUI/ObjectUI.py:887 flatcamGUI/PreferencesUI.py:3300 -#| msgid "" -#| "Diameter of the cutting tool\n" -#| "when milling slots." msgid "The diameter of the tool who will do the milling" msgstr "The diameter of the tool who will do the milling" @@ -8236,13 +8142,11 @@ msgstr "" #: flatcamGUI/ObjectUI.py:1161 flatcamGUI/ObjectUI.py:1935 #: flatcamTools/ToolNCC.py:505 flatcamTools/ToolPaint.py:436 -#| msgid "GCode Parameters" msgid "Common Parameters" msgstr "Common Parameters" #: flatcamGUI/ObjectUI.py:1163 flatcamGUI/ObjectUI.py:1937 #: flatcamTools/ToolNCC.py:507 flatcamTools/ToolPaint.py:438 -#| msgid "Parameters used for this tool." msgid "Parameters that are common for all tools." msgstr "Parameters that are common for all tools." @@ -8291,7 +8195,6 @@ msgstr "" #: flatcamGUI/ObjectUI.py:1222 flatcamGUI/ObjectUI.py:2000 #: flatcamGUI/PreferencesUI.py:3413 flatcamGUI/PreferencesUI.py:4366 -#| msgid "End move Z" msgid "End move X,Y" msgstr "End move X,Y" @@ -8335,14 +8238,10 @@ msgid "e_fr_probe" msgstr "e_fr_probe" #: flatcamGUI/ObjectUI.py:1270 -#| msgid "Preprocessor" msgid "Preprocessor E" msgstr "Preprocessor E" #: flatcamGUI/ObjectUI.py:1272 -#| msgid "" -#| "The preprocessor JSON file that dictates\n" -#| "Gcode output." msgid "" "The preprocessor JSON file that dictates\n" "Gcode output for Excellon Objects." @@ -8351,14 +8250,10 @@ msgstr "" "Gcode output for Excellon Objects." #: flatcamGUI/ObjectUI.py:1282 -#| msgid "Preprocessor" msgid "Preprocessor G" msgstr "Preprocessor G" #: flatcamGUI/ObjectUI.py:1284 -#| msgid "" -#| "The preprocessor JSON file that dictates\n" -#| "Gcode output." msgid "" "The preprocessor JSON file that dictates\n" "Gcode output for Geometry (Milling) Objects." @@ -8367,10 +8262,6 @@ msgstr "" "Gcode output for Geometry (Milling) Objects." #: flatcamGUI/ObjectUI.py:1308 flatcamGUI/ObjectUI.py:2026 -#| msgid "" -#| "Add at least one tool in the tool-table.\n" -#| "Click the header to select all, or Ctrl + LMB\n" -#| "for custom selection of tools." msgid "" "Add / Select at least one tool in the tool-table.\n" "Click the # header to select all, or Ctrl + LMB\n" @@ -8393,7 +8284,6 @@ msgstr "" "If milling then an additional Geometry object will be created" #: flatcamGUI/ObjectUI.py:1335 -#| msgid "Solid Geometry" msgid "Milling Geometry" msgstr "Milling Geometry" @@ -8413,7 +8303,6 @@ msgid "Diameter of the cutting tool." msgstr "Diameter of the cutting tool." #: flatcamGUI/ObjectUI.py:1355 -#| msgid "Mill Drills Geo" msgid "Mill Drills" msgstr "Mill Drills" @@ -8426,7 +8315,6 @@ msgstr "" "for milling DRILLS toolpaths." #: flatcamGUI/ObjectUI.py:1375 -#| msgid "Mill Slots Geo" msgid "Mill Slots" msgstr "Mill Slots" @@ -8609,7 +8497,6 @@ msgstr "" #: flatcamGUI/ObjectUI.py:1600 flatcamTools/ToolNCC.py:300 #: flatcamTools/ToolNCC.py:634 flatcamTools/ToolPaint.py:283 #: flatcamTools/ToolPaint.py:676 -#| msgid "Add from Tool DB" msgid "Add from DB" msgstr "Add from DB" @@ -9096,9 +8983,6 @@ msgid "Theme" msgstr "Theme" #: flatcamGUI/PreferencesUI.py:355 -#| msgid "" -#| "Select an style for FlatCAM.\n" -#| "It will be applied at the next app start." msgid "" "Select a theme for FlatCAM.\n" "It will theme the plot area." @@ -9133,9 +9017,6 @@ msgid "Apply Theme" msgstr "Apply Theme" #: flatcamGUI/PreferencesUI.py:378 -#| msgid "" -#| "Select a theme for FlatCAM.\n" -#| "The application will restart after change." msgid "" "Select a theme for FlatCAM.\n" "It will theme the plot area.\n" @@ -9861,13 +9742,6 @@ msgid "Geo Tolerance" msgstr "Geo Tolerance" #: flatcamGUI/PreferencesUI.py:1774 -#| msgid "" -#| "This value can counter the effect of the Circle Steps\n" -#| "parameter. Default value is 0.01.\n" -#| "A lower value will increase the detail both in image\n" -#| "and in Gcode for the circles, with a higher cost in\n" -#| "performance. Higher value will provide more\n" -#| "performance at the expense of level of detail." msgid "" "This value can counter the effect of the Circle Steps\n" "parameter. Default value is 0.005.\n" @@ -9928,7 +9802,6 @@ msgstr "" "at the set interval." #: flatcamGUI/PreferencesUI.py:1834 -#| msgid "Interior" msgid "Interval" msgstr "Interval" @@ -10833,7 +10706,6 @@ msgstr "" #: flatcamGUI/PreferencesUI.py:3858 flatcamGUI/PreferencesUI.py:5396 #: flatcamGUI/PreferencesUI.py:5962 -#| msgid "New Tool Dia" msgid "New Dia" msgstr "New Dia" @@ -10879,7 +10751,6 @@ msgstr "" #: flatcamGUI/PreferencesUI.py:4153 flatcamGUI/PreferencesUI.py:5320 #: flatcamGUI/PreferencesUI.py:5887 flatcamGUI/PreferencesUI.py:6953 -#| msgid "Tool Dia" msgid "Tools Dia" msgstr "Tools Dia" @@ -11319,18 +11190,12 @@ msgstr "Area Selection" #: flatcamTools/ToolNCC.py:1998 flatcamTools/ToolNCC.py:2306 #: flatcamTools/ToolNCC.py:2586 flatcamTools/ToolNCC.py:3012 #: flatcamTools/ToolPaint.py:486 flatcamTools/ToolPaint.py:924 -#: flatcamTools/ToolPaint.py:1456 +#: flatcamTools/ToolPaint.py:1456 tclCommands/TclCommandCopperClear.py:192 +#: tclCommands/TclCommandPaint.py:166 msgid "Reference Object" msgstr "Reference Object" #: flatcamGUI/PreferencesUI.py:5592 flatcamTools/ToolNCC.py:541 -#| msgid "" -#| "- 'Itself' - the non copper clearing extent is based on the object that " -#| "is copper cleared.\n" -#| " - 'Area Selection' - left mouse click to start selection of the area to " -#| "be painted.\n" -#| "- 'Reference Object' - will do non copper clearing within the area " -#| "specified by another object." msgid "" "Selection of area to be processed.\n" "- 'Itself' - the processing extent is based on the object that is " @@ -11348,13 +11213,11 @@ msgstr "" #: flatcamGUI/PreferencesUI.py:5601 flatcamGUI/PreferencesUI.py:6125 #: flatcamTools/ToolNCC.py:578 flatcamTools/ToolPaint.py:522 -#| msgid "V-Shape" msgid "Shape" msgstr "Shape" #: flatcamGUI/PreferencesUI.py:5603 flatcamGUI/PreferencesUI.py:6127 #: flatcamTools/ToolNCC.py:580 flatcamTools/ToolPaint.py:524 -#| msgid "Select the key used for multiple selection." msgid "The kind of selection shape used for area selection." msgstr "The kind of selection shape used for area selection." @@ -11507,7 +11370,6 @@ msgid "Diameter of the drill for the alignment holes." msgstr "Diameter of the drill for the alignment holes." #: flatcamGUI/PreferencesUI.py:5822 flatcamTools/ToolDblSided.py:378 -#| msgid "Align Right" msgid "Align Axis" msgstr "Align Axis" @@ -11571,17 +11433,6 @@ msgstr "" "If not checked, use the standard algorithm." #: flatcamGUI/PreferencesUI.py:6099 flatcamTools/ToolPaint.py:458 -#| msgid "" -#| "How to select Polygons to be painted.\n" -#| "- 'Polygon Selection' - left mouse click to add/remove polygons to be " -#| "painted.\n" -#| "- 'Area Selection' - left mouse click to start selection of the area to " -#| "be painted.\n" -#| "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple " -#| "areas.\n" -#| "- 'All Polygons' - the Paint will start after click.\n" -#| "- 'Reference Object' - will do non copper clearing within the area\n" -#| "specified by another object." msgid "" "Selection of area to be processed.\n" "- 'Polygon Selection' - left mouse click to add/remove polygons to be " @@ -11605,6 +11456,7 @@ msgstr "" #: flatcamGUI/PreferencesUI.py:6119 flatcamTools/ToolPaint.py:486 #: flatcamTools/ToolPaint.py:935 flatcamTools/ToolPaint.py:1420 +#: tclCommands/TclCommandPaint.py:164 msgid "Polygon Selection" msgstr "Polygon Selection" @@ -12179,11 +12031,6 @@ msgstr "" "or decreased with the 'distance'." #: flatcamGUI/PreferencesUI.py:6902 flatcamTools/ToolTransform.py:360 -#| msgid "" -#| "A positive value will create the effect of dilation,\n" -#| "while a negative value will create the effect of erosion.\n" -#| "Each geometry element of the object will be increased\n" -#| "or decreased with the 'distance'." msgid "" "A positive value will create the effect of dilation,\n" "while a negative value will create the effect of erosion.\n" @@ -13073,7 +12920,6 @@ msgstr "" "- bottom-right -> the user will align the PCB horizontally" #: flatcamGUI/PreferencesUI.py:8126 -#| msgid "Excellon Options" msgid "Extract Drills Options" msgstr "Extract Drills Options" @@ -13095,7 +12941,6 @@ msgstr "" #: flatcamGUI/PreferencesUI.py:8153 flatcamGUI/PreferencesUI.py:8365 #: flatcamTools/ToolExtractDrills.py:80 flatcamTools/ToolPunchGerber.py:91 -#| msgid "Circular Pad Array" msgid "Process Circular Pads." msgstr "Process Circular Pads." @@ -13118,7 +12963,6 @@ msgstr "Process Square Pads." #: flatcamGUI/PreferencesUI.py:8177 flatcamGUI/PreferencesUI.py:8389 #: flatcamTools/ToolExtractDrills.py:104 flatcamTools/ToolPunchGerber.py:115 -#| msgid "Rectangular" msgid "Process Rectangular Pads." msgstr "Process Rectangular Pads." @@ -13139,7 +12983,6 @@ msgstr "Process pads not in the categories above." #: flatcamGUI/PreferencesUI.py:8411 flatcamGUI/PreferencesUI.py:8436 #: flatcamTools/ToolExtractDrills.py:139 flatcamTools/ToolExtractDrills.py:156 #: flatcamTools/ToolPunchGerber.py:150 flatcamTools/ToolPunchGerber.py:184 -#| msgid "Tip Diameter" msgid "Fixed Diameter" msgstr "Fixed Diameter" @@ -13147,13 +12990,11 @@ msgstr "Fixed Diameter" #: flatcamGUI/PreferencesUI.py:8412 flatcamGUI/PreferencesUI.py:8453 #: flatcamTools/ToolExtractDrills.py:140 flatcamTools/ToolExtractDrills.py:192 #: flatcamTools/ToolPunchGerber.py:151 flatcamTools/ToolPunchGerber.py:214 -#| msgid "Minimum Annular Ring" msgid "Fixed Annular Ring" msgstr "Fixed Annular Ring" #: flatcamGUI/PreferencesUI.py:8200 flatcamGUI/PreferencesUI.py:8413 #: flatcamTools/ToolExtractDrills.py:141 flatcamTools/ToolPunchGerber.py:152 -#| msgid "Properties Tool" msgid "Proportional" msgstr "Proportional" @@ -13171,7 +13012,6 @@ msgstr "" #: flatcamGUI/PreferencesUI.py:8232 flatcamGUI/PreferencesUI.py:8446 #: flatcamTools/ToolExtractDrills.py:166 flatcamTools/ToolPunchGerber.py:194 -#| msgid "with diameter" msgid "Fixed hole diameter." msgstr "Fixed hole diameter." @@ -13213,7 +13053,6 @@ msgstr "The size of annular ring for other pads." #: flatcamGUI/PreferencesUI.py:8312 flatcamGUI/PreferencesUI.py:8526 #: flatcamTools/ToolExtractDrills.py:276 flatcamTools/ToolPunchGerber.py:299 -#| msgid "Tool Diameter" msgid "Proportional Diameter" msgstr "Proportional Diameter" @@ -13231,7 +13070,6 @@ msgstr "" "The hole diameter will be a fraction of the pad size." #: flatcamGUI/PreferencesUI.py:8338 -#| msgid "Gerber Options" msgid "Punch Gerber Options" msgstr "Punch Gerber Options" @@ -13256,7 +13094,6 @@ msgstr "" "percentage of the pad diameter.\n" #: flatcamGUI/PreferencesUI.py:8552 -#| msgid "Gerber Options" msgid "Invert Gerber Tool Options" msgstr "Invert Gerber Tool Options" @@ -13269,10 +13106,6 @@ msgstr "" "and in revers." #: flatcamGUI/PreferencesUI.py:8572 flatcamTools/ToolInvertGerber.py:90 -#| msgid "" -#| "Distance by which to avoid\n" -#| "the edges of the polygon to\n" -#| "be painted." msgid "" "Distance by which to avoid\n" "the edges of the Gerber object." @@ -13580,21 +13413,14 @@ msgid "HPGL2 Parser ERROR" msgstr "HPGL2 Parser ERROR" #: flatcamTools/ToolAlignObjects.py:32 -#| msgid "Objects" msgid "Align Objects" msgstr "Align Objects" #: flatcamTools/ToolAlignObjects.py:61 -#| msgid "Object" msgid "MOVING object" msgstr "MOVING object" #: flatcamTools/ToolAlignObjects.py:65 -#| msgid "" -#| "Specify the type of object to be panelized\n" -#| "It can be of type: Gerber, Excellon or Geometry.\n" -#| "The selection here decide the type of objects that will be\n" -#| "in the Object combobox." msgid "" "Specify the type of object to be aligned.\n" "It can be of type: Gerber or Excellon.\n" @@ -13607,7 +13433,6 @@ msgstr "" "in the Object combobox." #: flatcamTools/ToolAlignObjects.py:86 -#| msgid "Object to be painted." msgid "Object to be aligned." msgstr "Object to be aligned." @@ -13616,11 +13441,6 @@ msgid "TARGET object" msgstr "TARGET object" #: flatcamTools/ToolAlignObjects.py:100 -#| msgid "" -#| "Specify the type of object to be panelized\n" -#| "It can be of type: Gerber, Excellon or Geometry.\n" -#| "The selection here decide the type of objects that will be\n" -#| "in the Object combobox." msgid "" "Specify the type of object to be aligned to.\n" "It can be of type: Gerber or Excellon.\n" @@ -13633,12 +13453,10 @@ msgstr "" "in the Object combobox." #: flatcamTools/ToolAlignObjects.py:122 -#| msgid "Object to be painted." msgid "Object to be aligned to. Aligner." msgstr "Object to be aligned to. Aligner." #: flatcamTools/ToolAlignObjects.py:135 -#| msgid "Alignment" msgid "Alignment Type" msgstr "Alignment Type" @@ -13657,17 +13475,14 @@ msgstr "" "translation followed by rotation" #: flatcamTools/ToolAlignObjects.py:143 -#| msgid "Single Polygon" msgid "Single Point" msgstr "Single Point" #: flatcamTools/ToolAlignObjects.py:144 -#| msgid "Half Point" msgid "Dual Point" msgstr "Dual Point" #: flatcamTools/ToolAlignObjects.py:159 -#| msgid "Align Left" msgid "Align Object" msgstr "Align Object" @@ -13708,27 +13523,22 @@ msgid "Will reset the tool parameters." msgstr "Will reset the tool parameters." #: flatcamTools/ToolAlignObjects.py:244 -#| msgid "Poligonize Tool" msgid "Align Tool" msgstr "Align Tool" #: flatcamTools/ToolAlignObjects.py:289 -#| msgid "There is no FlatCAM object selected..." msgid "There is no aligned FlatCAM object selected..." msgstr "There is no aligned FlatCAM object selected..." #: flatcamTools/ToolAlignObjects.py:299 -#| msgid "There is no FlatCAM object selected..." msgid "There is no aligner FlatCAM object selected..." msgstr "There is no aligner FlatCAM object selected..." #: flatcamTools/ToolAlignObjects.py:325 flatcamTools/ToolAlignObjects.py:385 -#| msgid "First object point" msgid "First Point" msgstr "First Point" #: flatcamTools/ToolAlignObjects.py:325 flatcamTools/ToolAlignObjects.py:400 -#| msgid "Click on target point." msgid "Click on the START point." msgstr "Click on the START point." @@ -13737,7 +13547,6 @@ msgid "Cancelled by user request." msgstr "Cancelled by user request." #: flatcamTools/ToolAlignObjects.py:385 flatcamTools/ToolAlignObjects.py:407 -#| msgid "Click on target point." msgid "Click on the DESTINATION point." msgstr "Click on the DESTINATION point." @@ -14372,7 +14181,7 @@ msgstr "Geometry not supported for bounding box" #: flatcamTools/ToolCopperThieving.py:1068 flatcamTools/ToolNCC.py:1933 #: flatcamTools/ToolNCC.py:1988 flatcamTools/ToolNCC.py:2992 -#: flatcamTools/ToolPaint.py:3854 +#: flatcamTools/ToolPaint.py:3368 msgid "No object available." msgstr "No object available." @@ -14411,7 +14220,6 @@ msgid "Cutout PCB" msgstr "Cutout PCB" #: flatcamTools/ToolCutOut.py:70 flatcamTools/ToolPanelize.py:54 -#| msgid "Move Objects" msgid "Source Object" msgstr "Source Object" @@ -14436,7 +14244,6 @@ msgstr "" "of objects that will populate the 'Object' combobox." #: flatcamTools/ToolCutOut.py:122 -#| msgid "Slot Parameters" msgid "Tool Parameters" msgstr "Tool Parameters" @@ -14658,12 +14465,10 @@ msgid "2-Sided PCB" msgstr "2-Sided PCB" #: flatcamTools/ToolDblSided.py:53 -#| msgid "Operation" msgid "Mirror Operation" msgstr "Mirror Operation" #: flatcamTools/ToolDblSided.py:54 -#| msgid "Excellon Object to be mirrored." msgid "Objects to be mirrored" msgstr "Objects to be mirrored" @@ -14691,17 +14496,14 @@ msgid "Geometry Obj to be mirrored." msgstr "Geometry Obj to be mirrored." #: flatcamTools/ToolDblSided.py:159 -#| msgid "Slot Parameters" msgid "Mirror Parameters" msgstr "Mirror Parameters" #: flatcamTools/ToolDblSided.py:160 -#| msgid "Perform the offset operation." msgid "Parameters for the mirror operation" msgstr "Parameters for the mirror operation" #: flatcamTools/ToolDblSided.py:165 -#| msgid "Mirror Axis:" msgid "Mirror Axis" msgstr "Mirror Axis" @@ -14720,18 +14522,10 @@ msgstr "" "bounding box of another object selected below" #: flatcamTools/ToolDblSided.py:190 -#| msgid "Points coordinates" msgid "Point coordinates" msgstr "Point coordinates" #: flatcamTools/ToolDblSided.py:195 -#| msgid "" -#| "Add the coordinates in format (x, y) through which the mirroring " -#| "axis \n" -#| " selected in 'MIRROR AXIS' pass.\n" -#| "The (x, y) coordinates are captured by pressing SHIFT key\n" -#| "and left mouse button click on canvas or you can enter the coords " -#| "manually." msgid "" "Add the coordinates in format (x, y) through which the mirroring " "axis \n" @@ -14758,12 +14552,10 @@ msgstr "" "as reference for mirror operation." #: flatcamTools/ToolDblSided.py:253 -#| msgid "Calculate Bounds Values" msgid "Bounds Values" msgstr "Bounds Values" #: flatcamTools/ToolDblSided.py:255 -#| msgid "Excellon objects for which to check rules." msgid "" "Select on canvas the object(s)\n" "for which to calculate bounds values." @@ -14796,7 +14588,6 @@ msgid "Y max" msgstr "Y max" #: flatcamTools/ToolDblSided.py:318 -#| msgid "Points coordinates" msgid "Center point coordinates" msgstr "Center point coordinates" @@ -14827,7 +14618,6 @@ msgstr "" "The envelope shape is parallel with the X, Y axis." #: flatcamTools/ToolDblSided.py:353 -#| msgid "Alignment" msgid "PCB Alignment" msgstr "PCB Alignment" @@ -14842,7 +14632,6 @@ msgstr "" "images." #: flatcamTools/ToolDblSided.py:362 -#| msgid "Tip Diameter" msgid "Drill Diameter" msgstr "Drill Diameter" @@ -14861,14 +14650,6 @@ msgid "Alignment Drill Coordinates" msgstr "Alignment Drill Coordinates" #: flatcamTools/ToolDblSided.py:413 -#| msgid "" -#| "Alignment holes (x1, y1), (x2, y2), ... on one side of the mirror axis. " -#| "For each set of (x, y) coordinates\n" -#| "entered here, a pair of drills will be created:\n" -#| "\n" -#| "- one drill at the coordinates from the field\n" -#| "- one drill in mirror position over the axis selected above in the " -#| "'Mirror Axis'." msgid "" "Alignment holes (x1, y1), (x2, y2), ... on one side of the mirror axis. For " "each set of (x, y) coordinates\n" @@ -14887,22 +14668,10 @@ msgstr "" "Axis'." #: flatcamTools/ToolDblSided.py:421 -#| msgid "Points coordinates" msgid "Drill coordinates" msgstr "Drill coordinates" #: flatcamTools/ToolDblSided.py:428 -#| msgid "" -#| "Add alignment drill holes coords in the format: (x1, y1), (x2, y2), ... \n" -#| "on one side of the mirror axis.\n" -#| "\n" -#| "The coordinates set can be obtained:\n" -#| "- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" -#| "- press SHIFT key and left mouse clicking on canvas. Then Ctrl+V in the " -#| "field.\n" -#| "- press SHIFT key and left mouse clicking on canvas. Then RMB click in " -#| "the field and click Paste.\n" -#| "- by entering the coords manually in the format: (x1, y1), (x2, y2), ..." msgid "" "Add alignment drill holes coordinates in the format: (x1, y1), (x2, " "y2), ... \n" @@ -14929,12 +14698,10 @@ msgstr "" "- by entering the coords manually in the format: (x1, y1), (x2, y2), ..." #: flatcamTools/ToolDblSided.py:443 -#| msgid "Delete" msgid "Delete Last" msgstr "Delete Last" #: flatcamTools/ToolDblSided.py:445 -#| msgid "Delete a aperture in the aperture list" msgid "Delete the last coordinates tuple in the list." msgstr "Delete the last coordinates tuple in the list." @@ -15014,7 +14781,6 @@ msgid "INCH (in)" msgstr "INCH (in)" #: flatcamTools/ToolDistance.py:64 -#| msgid "Snap to corner" msgid "Snap to center" msgstr "Snap to center" @@ -15079,7 +14845,6 @@ msgid "Measure" msgstr "Measure" #: flatcamTools/ToolDistance.py:272 -#| msgid "Working..." msgid "Working" msgstr "Working" @@ -15088,7 +14853,6 @@ msgid "MEASURING: Click on the Start point ..." msgstr "MEASURING: Click on the Start point ..." #: flatcamTools/ToolDistance.py:387 -#| msgid "Distance Tool exit..." msgid "Distance Tool finished." msgstr "Distance Tool finished." @@ -15172,12 +14936,10 @@ msgid "Jumped to the half point between the two selected objects" msgstr "Jumped to the half point between the two selected objects" #: flatcamTools/ToolExtractDrills.py:29 flatcamTools/ToolExtractDrills.py:295 -#| msgid "Total Drills" msgid "Extract Drills" msgstr "Extract Drills" #: flatcamTools/ToolExtractDrills.py:62 -#| msgid "Gerber objects for which to check rules." msgid "Gerber from which to extract drill holes" msgstr "Gerber from which to extract drill holes" @@ -15187,7 +14949,6 @@ msgstr "Extract drills from a given Gerber file." #: flatcamTools/ToolExtractDrills.py:478 flatcamTools/ToolExtractDrills.py:563 #: flatcamTools/ToolExtractDrills.py:648 -#| msgid "NCC Tool started. Reading parameters." msgid "No drills extracted. Try different parameters." msgstr "No drills extracted. Try different parameters." @@ -15588,17 +15349,14 @@ msgid "Importing Image" msgstr "Importing Image" #: flatcamTools/ToolInvertGerber.py:74 -#| msgid "Gerber Object to which the QRCode will be added." msgid "Gerber object that will be inverted." msgstr "Gerber object that will be inverted." #: flatcamTools/ToolInvertGerber.py:83 -#| msgid "Parameters used for this tool." msgid "Parameters for this tool" msgstr "Parameters for this tool" #: flatcamTools/ToolInvertGerber.py:123 -#| msgid "Convert Any to Gerber" msgid "Invert Gerber" msgstr "Invert Gerber" @@ -15613,7 +15371,6 @@ msgstr "" "filled with copper." #: flatcamTools/ToolInvertGerber.py:184 -#| msgid "Text Tool" msgid "Invert Tool" msgstr "Invert Tool" @@ -15622,7 +15379,6 @@ msgid "MOVE: Click on the Start point ..." msgstr "MOVE: Click on the Start point ..." #: flatcamTools/ToolMove.py:114 -#| msgid "MOVE action cancelled. No object(s) to move." msgid "Cancelled. No object(s) to move." msgstr "Cancelled. No object(s) to move." @@ -15765,14 +15521,13 @@ msgid "Please enter a tool diameter to add, in Float format." msgstr "Please enter a tool diameter to add, in Float format." #: flatcamTools/ToolNCC.py:1460 flatcamTools/ToolNCC.py:4013 -#: flatcamTools/ToolPaint.py:1196 flatcamTools/ToolPaint.py:4077 +#: flatcamTools/ToolPaint.py:1196 flatcamTools/ToolPaint.py:3587 #: flatcamTools/ToolSolderPaste.py:917 -#| msgid "Adding tool cancelled. Tool already in Tool Table." msgid "Cancelled. Tool already in Tool Table." msgstr "Cancelled. Tool already in Tool Table." #: flatcamTools/ToolNCC.py:1467 flatcamTools/ToolNCC.py:4030 -#: flatcamTools/ToolPaint.py:1201 flatcamTools/ToolPaint.py:4094 +#: flatcamTools/ToolPaint.py:1201 flatcamTools/ToolPaint.py:3604 msgid "New tool added to Tool Table." msgstr "New tool added to Tool Table." @@ -15782,7 +15537,6 @@ msgstr "Tool from Tool Table was edited." #: flatcamTools/ToolNCC.py:1523 flatcamTools/ToolPaint.py:1257 #: flatcamTools/ToolSolderPaste.py:977 -#| msgid "Edit cancelled. New diameter value is already in the Tool Table." msgid "Cancelled. New diameter value is already in the Tool Table." msgstr "Cancelled. New diameter value is already in the Tool Table." @@ -15862,7 +15616,6 @@ msgstr "NCC Tool failed creating bounding box." #: flatcamTools/ToolNCC.py:2326 flatcamTools/ToolNCC.py:2609 #: flatcamTools/ToolNCC.py:3256 flatcamTools/ToolNCC.py:3642 -#| msgid "NCC Tool clearing with tool diameter = " msgid "NCC Tool clearing with tool diameter" msgstr "NCC Tool clearing with tool diameter" @@ -16195,72 +15948,70 @@ msgstr "Click to add next polygon or right click to start painting." msgid "Click to add/remove next polygon or right click to start painting." msgstr "Click to add/remove next polygon or right click to start painting." -#: flatcamTools/ToolPaint.py:2013 -#| msgid "Painting polygon at location" +#: flatcamTools/ToolPaint.py:2017 msgid "Painting polygon with method: lines." msgstr "Painting polygon with method: lines." -#: flatcamTools/ToolPaint.py:2025 -#| msgid "Normal painting polygon task started." +#: flatcamTools/ToolPaint.py:2029 msgid "Failed. Painting polygon with method: seed." msgstr "Failed. Painting polygon with method: seed." -#: flatcamTools/ToolPaint.py:2036 -#| msgid "Normal painting polygon task started." +#: flatcamTools/ToolPaint.py:2040 msgid "Failed. Painting polygon with method: standard." msgstr "Failed. Painting polygon with method: standard." -#: flatcamTools/ToolPaint.py:2052 +#: flatcamTools/ToolPaint.py:2056 msgid "Geometry could not be painted completely" msgstr "Geometry could not be painted completely" -#: flatcamTools/ToolPaint.py:2081 flatcamTools/ToolPaint.py:2084 -#: flatcamTools/ToolPaint.py:2092 flatcamTools/ToolPaint.py:2634 -#: flatcamTools/ToolPaint.py:2638 flatcamTools/ToolPaint.py:2641 -#: flatcamTools/ToolPaint.py:3448 flatcamTools/ToolPaint.py:3452 -#: flatcamTools/ToolPaint.py:3455 +#: flatcamTools/ToolPaint.py:2085 flatcamTools/ToolPaint.py:2088 +#: flatcamTools/ToolPaint.py:2096 flatcamTools/ToolPaint.py:2399 +#: flatcamTools/ToolPaint.py:2402 flatcamTools/ToolPaint.py:2410 +#: flatcamTools/ToolPaint.py:2898 flatcamTools/ToolPaint.py:2901 +#: flatcamTools/ToolPaint.py:2907 msgid "Paint Tool." msgstr "Paint Tool." -#: flatcamTools/ToolPaint.py:2081 flatcamTools/ToolPaint.py:2084 -#: flatcamTools/ToolPaint.py:2092 +#: flatcamTools/ToolPaint.py:2085 flatcamTools/ToolPaint.py:2088 +#: flatcamTools/ToolPaint.py:2096 msgid "Normal painting polygon task started." msgstr "Normal painting polygon task started." -#: flatcamTools/ToolPaint.py:2082 flatcamTools/ToolPaint.py:2423 -#: flatcamTools/ToolPaint.py:2635 flatcamTools/ToolPaint.py:3085 -#: flatcamTools/ToolPaint.py:3449 +#: flatcamTools/ToolPaint.py:2086 flatcamTools/ToolPaint.py:2400 +#: flatcamTools/ToolPaint.py:2899 msgid "Buffering geometry..." msgstr "Buffering geometry..." -#: flatcamTools/ToolPaint.py:2105 +#: flatcamTools/ToolPaint.py:2108 flatcamTools/ToolPaint.py:2417 +#: flatcamTools/ToolPaint.py:2915 msgid "No polygon found." msgstr "No polygon found." -#: flatcamTools/ToolPaint.py:2135 +#: flatcamTools/ToolPaint.py:2138 msgid "Painting polygon..." msgstr "Painting polygon..." -#: flatcamTools/ToolPaint.py:2144 flatcamTools/ToolPaint.py:2466 -#: flatcamTools/ToolPaint.py:2674 flatcamTools/ToolPaint.py:3132 -#: flatcamTools/ToolPaint.py:3492 +#: flatcamTools/ToolPaint.py:2148 flatcamTools/ToolPaint.py:2463 +#: flatcamTools/ToolPaint.py:2653 flatcamTools/ToolPaint.py:2961 +#: flatcamTools/ToolPaint.py:3140 msgid "Painting with tool diameter = " msgstr "Painting with tool diameter = " -#: flatcamTools/ToolPaint.py:2145 flatcamTools/ToolPaint.py:2469 -#: flatcamTools/ToolPaint.py:2677 flatcamTools/ToolPaint.py:3135 -#: flatcamTools/ToolPaint.py:3495 +#: flatcamTools/ToolPaint.py:2149 flatcamTools/ToolPaint.py:2464 +#: flatcamTools/ToolPaint.py:2654 flatcamTools/ToolPaint.py:2962 +#: flatcamTools/ToolPaint.py:3141 msgid "started" msgstr "started" -#: flatcamTools/ToolPaint.py:2170 flatcamTools/ToolPaint.py:2494 -#: flatcamTools/ToolPaint.py:2703 flatcamTools/ToolPaint.py:3161 -#: flatcamTools/ToolPaint.py:3524 +#: flatcamTools/ToolPaint.py:2174 flatcamTools/ToolPaint.py:2490 +#: flatcamTools/ToolPaint.py:2680 flatcamTools/ToolPaint.py:2988 +#: flatcamTools/ToolPaint.py:3167 msgid "Margin parameter too big. Tool is not used" msgstr "Margin parameter too big. Tool is not used" -#: flatcamTools/ToolPaint.py:2210 flatcamTools/ToolPaint.py:2564 -#: flatcamTools/ToolPaint.py:3377 +#: flatcamTools/ToolPaint.py:2232 flatcamTools/ToolPaint.py:2559 +#: flatcamTools/ToolPaint.py:2737 flatcamTools/ToolPaint.py:3051 +#: flatcamTools/ToolPaint.py:3229 msgid "" "Could not do Paint. Try a different combination of parameters. Or a " "different strategy of paint" @@ -16268,9 +16019,9 @@ msgstr "" "Could not do Paint. Try a different combination of parameters. Or a " "different strategy of paint" -#: flatcamTools/ToolPaint.py:2268 flatcamTools/ToolPaint.py:2614 -#: flatcamTools/ToolPaint.py:2955 flatcamTools/ToolPaint.py:3428 -#: flatcamTools/ToolPaint.py:3771 +#: flatcamTools/ToolPaint.py:2289 flatcamTools/ToolPaint.py:2625 +#: flatcamTools/ToolPaint.py:2794 flatcamTools/ToolPaint.py:3112 +#: flatcamTools/ToolPaint.py:3291 msgid "" "There is no Painting Geometry in the file.\n" "Usually it means that the tool diameter is too big for the painted " @@ -16282,82 +16033,66 @@ msgstr "" "geometry.\n" "Change the painting parameters and try again." -#: flatcamTools/ToolPaint.py:2300 -#| msgid "Paint Single Done." +#: flatcamTools/ToolPaint.py:2312 msgid "Paint Single failed." msgstr "Paint Single failed." -#: flatcamTools/ToolPaint.py:2306 +#: flatcamTools/ToolPaint.py:2318 msgid "Paint Single Done." msgstr "Paint Single Done." -#: flatcamTools/ToolPaint.py:2308 flatcamTools/ToolPaint.py:2983 -#: flatcamTools/ToolPaint.py:3799 +#: flatcamTools/ToolPaint.py:2320 flatcamTools/ToolPaint.py:2830 +#: flatcamTools/ToolPaint.py:3327 msgid "Polygon Paint started ..." msgstr "Polygon Paint started ..." -#: flatcamTools/ToolPaint.py:2347 flatcamTools/ToolPaint.py:3023 +#: flatcamTools/ToolPaint.py:2399 flatcamTools/ToolPaint.py:2402 +#: flatcamTools/ToolPaint.py:2410 +#| msgid "Normal painting polygon task started." +msgid "Paint all polygons task started." +msgstr "Paint all polygons task started." + +#: flatcamTools/ToolPaint.py:2441 flatcamTools/ToolPaint.py:2939 msgid "Painting polygons..." msgstr "Painting polygons..." -#: flatcamTools/ToolPaint.py:2422 flatcamTools/ToolPaint.py:2425 -#: flatcamTools/ToolPaint.py:2427 -msgid "Paint Tool. Normal painting all task started." -msgstr "Paint Tool. Normal painting all task started." - -#: flatcamTools/ToolPaint.py:2623 +#: flatcamTools/ToolPaint.py:2634 msgid "Paint All Done." msgstr "Paint All Done." -#: flatcamTools/ToolPaint.py:2634 flatcamTools/ToolPaint.py:2638 -#: flatcamTools/ToolPaint.py:2641 -msgid "Rest machining painting all task started." -msgstr "Rest machining painting all task started." - -#: flatcamTools/ToolPaint.py:2862 flatcamTools/ToolPaint.py:3334 -#: flatcamTools/ToolPaint.py:3683 -#| msgid "Painting polygon at location" -msgid "Painting polygons with method: lines." -msgstr "Painting polygons with method: lines." - -#: flatcamTools/ToolPaint.py:2875 flatcamTools/ToolPaint.py:3347 -#: flatcamTools/ToolPaint.py:3695 -#| msgid "Normal painting polygon task started." -msgid "Failed. Painting polygons with method: seed." -msgstr "Failed. Painting polygons with method: seed." - -#: flatcamTools/ToolPaint.py:2887 flatcamTools/ToolPaint.py:3359 -#: flatcamTools/ToolPaint.py:3707 -#| msgid "Normal painting polygon task started." -msgid "Failed. Painting polygons with method: standard." -msgstr "Failed. Painting polygons with method: standard." - -#: flatcamTools/ToolPaint.py:2904 flatcamTools/ToolPaint.py:3723 -msgid "" -"Could not do Paint All. Try a different combination of parameters. Or a " -"different Method of paint" -msgstr "" -"Could not do Paint All. Try a different combination of parameters. Or a " -"different Method of paint" - -#: flatcamTools/ToolPaint.py:2964 flatcamTools/ToolPaint.py:3780 +#: flatcamTools/ToolPaint.py:2803 flatcamTools/ToolPaint.py:3300 msgid "Paint All with Rest-Machining done." msgstr "Paint All with Rest-Machining done." -#: flatcamTools/ToolPaint.py:3084 flatcamTools/ToolPaint.py:3087 -#: flatcamTools/ToolPaint.py:3089 -#| msgid "Paint Tool. Normal painting all task started." -msgid "Paint Tool. Normal painting area task started." -msgstr "Paint Tool. Normal painting area task started." +#: flatcamTools/ToolPaint.py:2822 +#| msgid "Paint Single failed." +msgid "Paint All failed." +msgstr "Paint All failed." -#: flatcamTools/ToolPaint.py:3437 +#: flatcamTools/ToolPaint.py:2828 +#| msgid "Paint All Done." +msgid "Paint Poly All Done." +msgstr "Paint Poly All Done." + +#: flatcamTools/ToolPaint.py:2898 flatcamTools/ToolPaint.py:2901 +#: flatcamTools/ToolPaint.py:2907 +#| msgid "Normal painting area task started." +msgid "Painting area task started." +msgstr "Painting area task started." + +#: flatcamTools/ToolPaint.py:3121 msgid "Paint Area Done." msgstr "Paint Area Done." -#: flatcamTools/ToolPaint.py:3448 flatcamTools/ToolPaint.py:3452 -#: flatcamTools/ToolPaint.py:3455 -msgid "Rest machining painting area task started." -msgstr "Rest machining painting area task started." +#: flatcamTools/ToolPaint.py:3319 +#| msgid "Paint Single failed." +msgid "Paint Area failed." +msgstr "Paint Area failed." + +#: flatcamTools/ToolPaint.py:3325 +#| msgid "Paint Area Done." +msgid "Paint Poly Area Done." +msgstr "Paint Poly Area Done." #: flatcamTools/ToolPanelize.py:34 msgid "Panelize PCB" @@ -16792,12 +16527,10 @@ msgid "Copper Area" msgstr "Copper Area" #: flatcamTools/ToolPunchGerber.py:30 flatcamTools/ToolPunchGerber.py:323 -#| msgid "Open Gerber" msgid "Punch Gerber" msgstr "Punch Gerber" #: flatcamTools/ToolPunchGerber.py:65 -#| msgid "Gerber objects for which to check rules." msgid "Gerber into which to punch holes" msgstr "Gerber into which to punch holes" @@ -16806,8 +16539,6 @@ msgid "ALL" msgstr "ALL" #: flatcamTools/ToolPunchGerber.py:166 -#| msgid "" -#| "Remove the geometry of Excellon from the Film to create the holes in pads." msgid "" "Remove the geometry of Excellon from the Gerber to create the holes in pads." msgstr "" @@ -16822,7 +16553,6 @@ msgstr "" "the specified box." #: flatcamTools/ToolPunchGerber.py:425 -#| msgid "Paint Tool" msgid "Punch Tool" msgstr "Punch Tool" @@ -16831,9 +16561,6 @@ msgid "The value of the fixed diameter is 0.0. Aborting." msgstr "The value of the fixed diameter is 0.0. Aborting." #: flatcamTools/ToolPunchGerber.py:607 -#| msgid "" -#| " Could not generate punched hole film because the punch hole sizeis " -#| "bigger than some of the apertures in the Gerber object." msgid "" " Could not generate punched hole Gerber because the punch hole sizeis bigger " "than some of the apertures in the Gerber object." @@ -16842,9 +16569,6 @@ msgstr "" "than some of the apertures in the Gerber object." #: flatcamTools/ToolPunchGerber.py:619 -#| msgid "" -#| "Could not generate punched hole film because the punch hole sizeis bigger " -#| "than some of the apertures in the Gerber object." msgid "" "Could not generate punched hole Gerber because the punch hole sizeis bigger " "than some of the apertures in the Gerber object." @@ -16853,9 +16577,6 @@ msgstr "" "than some of the apertures in the Gerber object." #: flatcamTools/ToolPunchGerber.py:656 -#| msgid "" -#| "Could not generate punched hole film because the newly created object " -#| "geometry is the same as the one in the source object geometry..." msgid "" "Could not generate punched hole Gerber because the newly created object " "geometry is the same as the one in the source object geometry..." @@ -17156,7 +16877,6 @@ msgid "Violations: There are no violations for the current rule." msgstr "Violations: There are no violations for the current rule." #: flatcamTools/ToolShell.py:72 flatcamTools/ToolShell.py:74 -#| msgid "...proccessing..." msgid "...processing..." msgstr "...processing..." @@ -17619,9 +17339,6 @@ msgid "Ref. Point" msgstr "Ref. Point" #: flatcamTools/ToolTransform.py:349 -#| msgid "" -#| "Create the buffer effect on each geometry,\n" -#| "element from the selected object." msgid "" "Create the buffer effect on each geometry,\n" "element from the selected object, using the distance." @@ -17630,9 +17347,6 @@ msgstr "" "element from the selected object, using the distance." #: flatcamTools/ToolTransform.py:375 -#| msgid "" -#| "Create the buffer effect on each geometry,\n" -#| "element from the selected object." msgid "" "Create the buffer effect on each geometry,\n" "element from the selected object, using the factor." @@ -17641,12 +17355,10 @@ msgstr "" "element from the selected object, using the factor." #: flatcamTools/ToolTransform.py:480 -#| msgid "Buffer" msgid "Buffer D" msgstr "Buffer D" #: flatcamTools/ToolTransform.py:481 -#| msgid "Buffer" msgid "Buffer F" msgstr "Buffer F" @@ -17767,52 +17479,39 @@ msgstr "Expected a list of objects names separated by comma. Got" msgid "TclCommand Bounds done." msgstr "TclCommand Bounds done." -#: tclCommands/TclCommandCopperClear.py:256 tclCommands/TclCommandPaint.py:261 +#: tclCommands/TclCommandCopperClear.py:276 tclCommands/TclCommandPaint.py:272 #: tclCommands/TclCommandScale.py:81 msgid "Could not retrieve box object" msgstr "Could not retrieve box object" -#: tclCommands/TclCommandCopperClear.py:279 -#| msgid "Expected -box ." +#: tclCommands/TclCommandCopperClear.py:299 msgid "Expected either -box or -all." msgstr "Expected either -box or -all." #: tclCommands/TclCommandGeoCutout.py:148 -#| msgid "Number of gaps value is missing. Add it and retry." msgid "" "The name of the object for which cutout is done is missing. Add it and retry." msgstr "" "The name of the object for which cutout is done is missing. Add it and retry." #: tclCommands/TclCommandGeoCutout.py:190 -#| msgid "" -#| "Gaps value can be only one of: 'None', 'lr', 'tb', '2lr', '2tb', 4 or 8. " -#| "Fill in a correct value and retry. " msgid "Gaps value can be only one of: 'lr', 'tb', '2lr', '2tb', 4 or 8." msgstr "Gaps value can be only one of: 'lr', 'tb', '2lr', '2tb', 4 or 8." #: tclCommands/TclCommandGeoCutout.py:302 #: tclCommands/TclCommandGeoCutout.py:360 -#| msgid "Any form CutOut operation finished." msgid "Any-form Cutout operation finished." msgstr "Any-form Cutout operation finished." #: tclCommands/TclCommandGeoCutout.py:366 -#| msgid "The reference object type is not supported." msgid "Cancelled. Object type is not supported." msgstr "Cancelled. Object type is not supported." #: tclCommands/TclCommandHelp.py:74 -#| msgid "Available commands:\n" msgid "Available commands:" msgstr "Available commands:" #: tclCommands/TclCommandHelp.py:112 -#| msgid "" -#| "\n" -#| "\n" -#| "Type help for usage.\n" -#| " Example: help open_gerber" msgid "Type help for usage." msgstr "Type help for usage." @@ -17820,18 +17519,15 @@ msgstr "Type help for usage." msgid "Example: help open_gerber" msgstr "Example: help open_gerber" -#: tclCommands/TclCommandPaint.py:229 +#: tclCommands/TclCommandPaint.py:244 msgid "Expected -x and -y ." msgstr "Expected -x and -y ." -#: tclCommands/TclCommandPaint.py:254 +#: tclCommands/TclCommandPaint.py:265 msgid "Expected -box ." msgstr "Expected -box ." -#: tclCommands/TclCommandPaint.py:279 -#| msgid "" -#| "There was none of the following args: 'ref', 'single', 'all'.\n" -#| "Paint failed." +#: tclCommands/TclCommandPaint.py:286 msgid "" "None of the following args: 'box', 'single', 'all' were used.\n" "Paint failed." @@ -17840,8 +17536,6 @@ msgstr "" "Paint failed." #: tclCommands/TclCommandScale.py:106 -#| msgid "" -#| "Expected -origin or -origin or -origin

." msgid "" "Expected -origin or -origin or -origin
or - " "origin 3.0,4.2." @@ -17865,6 +17559,38 @@ msgstr "Origin set by offsetting all loaded objects with " msgid "No Geometry name in args. Provide a name and try again." msgstr "No Geometry name in args. Provide a name and try again." +#~ msgid "Paint Tool. Normal painting all task started." +#~ msgstr "Paint Tool. Normal painting all task started." + +#~ msgid "Rest machining painting all task started." +#~ msgstr "Rest machining painting all task started." + +#~| msgid "Painting polygon at location" +#~ msgid "Painting polygons with method: lines." +#~ msgstr "Painting polygons with method: lines." + +#~| msgid "Normal painting polygon task started." +#~ msgid "Failed. Painting polygons with method: seed." +#~ msgstr "Failed. Painting polygons with method: seed." + +#~| msgid "Normal painting polygon task started." +#~ msgid "Failed. Painting polygons with method: standard." +#~ msgstr "Failed. Painting polygons with method: standard." + +#~ msgid "" +#~ "Could not do Paint All. Try a different combination of parameters. Or a " +#~ "different Method of paint" +#~ msgstr "" +#~ "Could not do Paint All. Try a different combination of parameters. Or a " +#~ "different Method of paint" + +#~| msgid "Paint Tool. Normal painting all task started." +#~ msgid "Paint Tool. Normal painting area task started." +#~ msgstr "Paint Tool. Normal painting area task started." + +#~ msgid "Rest machining painting area task started." +#~ msgstr "Rest machining painting area task started." + #~ msgid "Executing Tcl Script ..." #~ msgstr "Executing Tcl Script ..." @@ -18171,9 +17897,6 @@ msgstr "No Geometry name in args. Provide a name and try again." #~ msgid "Paint Tool. Reading parameters." #~ msgstr "Paint Tool. Reading parameters." -#~ msgid "Normal painting area task started." -#~ msgstr "Normal painting area task started." - #~ msgid "Paint Tool. Rest machining painting area task started." #~ msgstr "Paint Tool. Rest machining painting area task started." diff --git a/locale/ro/LC_MESSAGES/strings.mo b/locale/ro/LC_MESSAGES/strings.mo index d076dab8957c6b24cfa114d3a987951dd738e635..19ee1f95112dd078f71266fe810a6fe20644c61b 100644 GIT binary patch delta 66634 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 delta 66939 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 diff --git a/locale/ro/LC_MESSAGES/strings.po b/locale/ro/LC_MESSAGES/strings.po index 43ebfce8..393d81cd 100644 --- a/locale/ro/LC_MESSAGES/strings.po +++ b/locale/ro/LC_MESSAGES/strings.po @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2020-04-24 09:23+0300\n" -"PO-Revision-Date: 2020-04-24 11:22+0300\n" +"POT-Creation-Date: 2020-04-24 21:10+0300\n" +"PO-Revision-Date: 2020-04-24 21:13+0300\n" "Last-Translator: \n" "Language-Team: \n" "Language: ro\n" @@ -30,9 +30,9 @@ msgstr "" #: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 #: flatcamTools/ToolNCC.py:2401 flatcamTools/ToolNCC.py:2429 #: flatcamTools/ToolNCC.py:2699 flatcamTools/ToolNCC.py:2731 -#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:1832 -#: flatcamTools/ToolPaint.py:2723 flatcamTools/ToolPaint.py:3178 -#: flatcamTools/ToolPaint.py:3544 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:1836 +#: tclCommands/TclCommandCopperClear.py:128 +#: tclCommands/TclCommandCopperClear.py:136 tclCommands/TclCommandPaint.py:127 msgid "Seed" msgstr "Punct_arbitrar" @@ -41,12 +41,13 @@ msgstr "Punct_arbitrar" #: flatcamTools/ToolNCC.py:535 flatcamTools/ToolNCC.py:1299 #: flatcamTools/ToolNCC.py:1638 flatcamTools/ToolNCC.py:1919 #: flatcamTools/ToolNCC.py:1983 flatcamTools/ToolNCC.py:2967 -#: flatcamTools/ToolNCC.py:2976 +#: flatcamTools/ToolNCC.py:2976 tclCommands/TclCommandCopperClear.py:190 msgid "Itself" msgstr "Însuşi" #: FlatCAMApp.py:817 flatcamGUI/PreferencesUI.py:6119 #: flatcamTools/ToolPaint.py:486 flatcamTools/ToolPaint.py:1415 +#: tclCommands/TclCommandPaint.py:162 msgid "All Polygons" msgstr "Toate Poligoanele" @@ -792,7 +793,7 @@ msgstr "Preferințele au fost editate dar nu au fost salvate." #: FlatCAMApp.py:8038 FlatCAMCommon.py:1182 FlatCAMCommon.py:1357 #: FlatCAMCommon.py:2612 FlatCAMCommon.py:2820 FlatCAMObj.py:4798 #: flatcamTools/ToolNCC.py:3963 flatcamTools/ToolNCC.py:4047 -#: flatcamTools/ToolPaint.py:4027 flatcamTools/ToolPaint.py:4112 +#: flatcamTools/ToolPaint.py:3537 flatcamTools/ToolPaint.py:3622 msgid "Tools Database" msgstr "Baza de Date Unelte" @@ -801,7 +802,7 @@ msgid "Tools in Tools Database edited but not saved." msgstr "Uneltele din Baza de date au fost editate dar nu au fost salvate." #: FlatCAMApp.py:7975 flatcamTools/ToolNCC.py:3970 -#: flatcamTools/ToolPaint.py:4034 +#: flatcamTools/ToolPaint.py:3544 msgid "Tool from DB added in Tool Table." msgstr "Unealtă din Baza de date adăugată in Tabela de Unelte." @@ -2496,9 +2497,9 @@ msgstr "" #: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 #: flatcamTools/ToolNCC.py:2395 flatcamTools/ToolNCC.py:2424 #: flatcamTools/ToolNCC.py:2693 flatcamTools/ToolNCC.py:2725 -#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:1818 -#: flatcamTools/ToolPaint.py:2717 flatcamTools/ToolPaint.py:3198 -#: flatcamTools/ToolPaint.py:3538 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:1822 +#: tclCommands/TclCommandCopperClear.py:126 +#: tclCommands/TclCommandCopperClear.py:134 tclCommands/TclCommandPaint.py:125 msgid "Standard" msgstr "Standard" @@ -2507,8 +2508,8 @@ msgstr "Standard" #: flatcamEditors/FlatCAMGeoEditor.py:5156 flatcamGUI/PreferencesUI.py:5509 #: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 #: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:696 -#: flatcamTools/ToolPaint.py:1846 flatcamTools/ToolPaint.py:2729 -#: flatcamTools/ToolPaint.py:3188 flatcamTools/ToolPaint.py:3550 +#: flatcamTools/ToolPaint.py:1850 tclCommands/TclCommandCopperClear.py:130 +#: tclCommands/TclCommandPaint.py:129 msgid "Lines" msgstr "Linii" @@ -2624,15 +2625,13 @@ msgstr "" #: FlatCAMCommon.py:2040 FlatCAMCommon.py:2042 flatcamGUI/PreferencesUI.py:6056 #: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:392 #: flatcamTools/ToolPaint.py:690 flatcamTools/ToolPaint.py:695 -#: flatcamTools/ToolPaint.py:1860 flatcamTools/ToolPaint.py:2735 -#: flatcamTools/ToolPaint.py:3207 flatcamTools/ToolPaint.py:3556 +#: flatcamTools/ToolPaint.py:1864 tclCommands/TclCommandPaint.py:131 msgid "Laser_lines" msgstr "Linii-laser" #: FlatCAMCommon.py:2040 flatcamGUI/PreferencesUI.py:6056 -#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:2011 -#: flatcamTools/ToolPaint.py:2861 flatcamTools/ToolPaint.py:3333 -#: flatcamTools/ToolPaint.py:3682 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:2015 +#: tclCommands/TclCommandPaint.py:133 msgid "Combo" msgstr "Combinat" @@ -9976,7 +9975,6 @@ msgstr "" "proiectul intr-un mod periodic." #: flatcamGUI/PreferencesUI.py:1834 -#| msgid "Interior" msgid "Interval" msgstr "Interval" @@ -11405,7 +11403,8 @@ msgstr "Selecţie zonă" #: flatcamTools/ToolNCC.py:1998 flatcamTools/ToolNCC.py:2306 #: flatcamTools/ToolNCC.py:2586 flatcamTools/ToolNCC.py:3012 #: flatcamTools/ToolPaint.py:486 flatcamTools/ToolPaint.py:924 -#: flatcamTools/ToolPaint.py:1456 +#: flatcamTools/ToolPaint.py:1456 tclCommands/TclCommandCopperClear.py:192 +#: tclCommands/TclCommandPaint.py:166 msgid "Reference Object" msgstr "Obiect Ref" @@ -11669,6 +11668,7 @@ msgstr "" #: flatcamGUI/PreferencesUI.py:6119 flatcamTools/ToolPaint.py:486 #: flatcamTools/ToolPaint.py:935 flatcamTools/ToolPaint.py:1420 +#: tclCommands/TclCommandPaint.py:164 msgid "Polygon Selection" msgstr "Selecție Poligon" @@ -14425,7 +14425,7 @@ msgstr "Geometria nu este acceptată pentru caseta de delimitare" #: flatcamTools/ToolCopperThieving.py:1068 flatcamTools/ToolNCC.py:1933 #: flatcamTools/ToolNCC.py:1988 flatcamTools/ToolNCC.py:2992 -#: flatcamTools/ToolPaint.py:3854 +#: flatcamTools/ToolPaint.py:3368 msgid "No object available." msgstr "Nici-un obiect disponibil." @@ -15784,13 +15784,13 @@ msgid "Please enter a tool diameter to add, in Float format." msgstr "Introduce diametrul unei unelte pt a fi adăugată, in format Real." #: flatcamTools/ToolNCC.py:1460 flatcamTools/ToolNCC.py:4013 -#: flatcamTools/ToolPaint.py:1196 flatcamTools/ToolPaint.py:4077 +#: flatcamTools/ToolPaint.py:1196 flatcamTools/ToolPaint.py:3587 #: flatcamTools/ToolSolderPaste.py:917 msgid "Cancelled. Tool already in Tool Table." msgstr "Anulat. Unealta există deja in Tabela de Unelte." #: flatcamTools/ToolNCC.py:1467 flatcamTools/ToolNCC.py:4030 -#: flatcamTools/ToolPaint.py:1201 flatcamTools/ToolPaint.py:4094 +#: flatcamTools/ToolPaint.py:1201 flatcamTools/ToolPaint.py:3604 msgid "New tool added to Tool Table." msgstr "O noua unealtă a fost adăugată in Tabela de Unelte." @@ -16219,69 +16219,70 @@ msgstr "" "Faceți clic pentru a adăuga / elimina următorul poligon sau faceți clic " "dreapta pentru a începe Paint." -#: flatcamTools/ToolPaint.py:2013 +#: flatcamTools/ToolPaint.py:2017 msgid "Painting polygon with method: lines." msgstr "Se pictează poligonul cu metoda: linii." -#: flatcamTools/ToolPaint.py:2025 +#: flatcamTools/ToolPaint.py:2029 msgid "Failed. Painting polygon with method: seed." msgstr "Esuat. Se pictează poligonul cu metoda: sămantă." -#: flatcamTools/ToolPaint.py:2036 +#: flatcamTools/ToolPaint.py:2040 msgid "Failed. Painting polygon with method: standard." msgstr "Esuat. Se picteaza poligonul cu metoda: standard." -#: flatcamTools/ToolPaint.py:2052 +#: flatcamTools/ToolPaint.py:2056 msgid "Geometry could not be painted completely" msgstr "Geometria nu a fost posibil să fie 'pictată' complet" -#: flatcamTools/ToolPaint.py:2081 flatcamTools/ToolPaint.py:2084 -#: flatcamTools/ToolPaint.py:2092 flatcamTools/ToolPaint.py:2634 -#: flatcamTools/ToolPaint.py:2638 flatcamTools/ToolPaint.py:2641 -#: flatcamTools/ToolPaint.py:3448 flatcamTools/ToolPaint.py:3452 -#: flatcamTools/ToolPaint.py:3455 +#: flatcamTools/ToolPaint.py:2085 flatcamTools/ToolPaint.py:2088 +#: flatcamTools/ToolPaint.py:2096 flatcamTools/ToolPaint.py:2399 +#: flatcamTools/ToolPaint.py:2402 flatcamTools/ToolPaint.py:2410 +#: flatcamTools/ToolPaint.py:2898 flatcamTools/ToolPaint.py:2901 +#: flatcamTools/ToolPaint.py:2907 msgid "Paint Tool." msgstr "Unealta Paint." -#: flatcamTools/ToolPaint.py:2081 flatcamTools/ToolPaint.py:2084 -#: flatcamTools/ToolPaint.py:2092 +#: flatcamTools/ToolPaint.py:2085 flatcamTools/ToolPaint.py:2088 +#: flatcamTools/ToolPaint.py:2096 msgid "Normal painting polygon task started." msgstr "Taskul de pictare normal a unui polygon a inceput." -#: flatcamTools/ToolPaint.py:2082 flatcamTools/ToolPaint.py:2423 -#: flatcamTools/ToolPaint.py:2635 flatcamTools/ToolPaint.py:3085 -#: flatcamTools/ToolPaint.py:3449 +#: flatcamTools/ToolPaint.py:2086 flatcamTools/ToolPaint.py:2400 +#: flatcamTools/ToolPaint.py:2899 msgid "Buffering geometry..." msgstr "Crează o geometrie de tipul Bufer..." -#: flatcamTools/ToolPaint.py:2105 +#: flatcamTools/ToolPaint.py:2108 flatcamTools/ToolPaint.py:2417 +#: flatcamTools/ToolPaint.py:2915 msgid "No polygon found." msgstr "Nu s-a gasit nici-un poligon." -#: flatcamTools/ToolPaint.py:2135 +#: flatcamTools/ToolPaint.py:2138 msgid "Painting polygon..." msgstr "Se 'pictează' un poligon..." -#: flatcamTools/ToolPaint.py:2144 flatcamTools/ToolPaint.py:2466 -#: flatcamTools/ToolPaint.py:2674 flatcamTools/ToolPaint.py:3132 -#: flatcamTools/ToolPaint.py:3492 +#: flatcamTools/ToolPaint.py:2148 flatcamTools/ToolPaint.py:2463 +#: flatcamTools/ToolPaint.py:2653 flatcamTools/ToolPaint.py:2961 +#: flatcamTools/ToolPaint.py:3140 msgid "Painting with tool diameter = " msgstr "Pictand cu o unealtă cu diametrul = " -#: flatcamTools/ToolPaint.py:2145 flatcamTools/ToolPaint.py:2469 -#: flatcamTools/ToolPaint.py:2677 flatcamTools/ToolPaint.py:3135 -#: flatcamTools/ToolPaint.py:3495 +#: flatcamTools/ToolPaint.py:2149 flatcamTools/ToolPaint.py:2464 +#: flatcamTools/ToolPaint.py:2654 flatcamTools/ToolPaint.py:2962 +#: flatcamTools/ToolPaint.py:3141 msgid "started" msgstr "a inceput" -#: flatcamTools/ToolPaint.py:2170 flatcamTools/ToolPaint.py:2494 -#: flatcamTools/ToolPaint.py:2703 flatcamTools/ToolPaint.py:3161 -#: flatcamTools/ToolPaint.py:3524 +#: flatcamTools/ToolPaint.py:2174 flatcamTools/ToolPaint.py:2490 +#: flatcamTools/ToolPaint.py:2680 flatcamTools/ToolPaint.py:2988 +#: flatcamTools/ToolPaint.py:3167 msgid "Margin parameter too big. Tool is not used" msgstr "Parametrul Margine este prea mare. Unealta nu este folosită" -#: flatcamTools/ToolPaint.py:2210 flatcamTools/ToolPaint.py:2564 -#: flatcamTools/ToolPaint.py:3377 +#: flatcamTools/ToolPaint.py:2232 flatcamTools/ToolPaint.py:2559 +#: flatcamTools/ToolPaint.py:2737 flatcamTools/ToolPaint.py:3051 +#: flatcamTools/ToolPaint.py:3229 msgid "" "Could not do Paint. Try a different combination of parameters. Or a " "different strategy of paint" @@ -16289,9 +16290,9 @@ msgstr "" "Nu s-a putut face operatia de 'pictare'. Incearcă o combinaţie diferita de " "parametri. Sau o strategie diferita de 'pictare'" -#: flatcamTools/ToolPaint.py:2268 flatcamTools/ToolPaint.py:2614 -#: flatcamTools/ToolPaint.py:2955 flatcamTools/ToolPaint.py:3428 -#: flatcamTools/ToolPaint.py:3771 +#: flatcamTools/ToolPaint.py:2289 flatcamTools/ToolPaint.py:2625 +#: flatcamTools/ToolPaint.py:2794 flatcamTools/ToolPaint.py:3112 +#: flatcamTools/ToolPaint.py:3291 msgid "" "There is no Painting Geometry in the file.\n" "Usually it means that the tool diameter is too big for the painted " @@ -16303,79 +16304,60 @@ msgstr "" "geometrice.\n" "Schimbă parametrii de 'pictare' și încearcă din nou." -#: flatcamTools/ToolPaint.py:2300 +#: flatcamTools/ToolPaint.py:2312 msgid "Paint Single failed." msgstr "Pictarea unui polygon a esuat." -#: flatcamTools/ToolPaint.py:2306 +#: flatcamTools/ToolPaint.py:2318 msgid "Paint Single Done." msgstr "Pictarea unui polygon efectuată." -#: flatcamTools/ToolPaint.py:2308 flatcamTools/ToolPaint.py:2983 -#: flatcamTools/ToolPaint.py:3799 +#: flatcamTools/ToolPaint.py:2320 flatcamTools/ToolPaint.py:2830 +#: flatcamTools/ToolPaint.py:3327 msgid "Polygon Paint started ..." msgstr "Paint pt poligon a inceput ..." -#: flatcamTools/ToolPaint.py:2347 flatcamTools/ToolPaint.py:3023 +#: flatcamTools/ToolPaint.py:2399 flatcamTools/ToolPaint.py:2402 +#: flatcamTools/ToolPaint.py:2410 +msgid "Paint all polygons task started." +msgstr "Taskul de pictare pt toate poligoanele a inceput." + +#: flatcamTools/ToolPaint.py:2441 flatcamTools/ToolPaint.py:2939 msgid "Painting polygons..." msgstr "Se 'pictează' poligoane..." -#: flatcamTools/ToolPaint.py:2422 flatcamTools/ToolPaint.py:2425 -#: flatcamTools/ToolPaint.py:2427 -msgid "Paint Tool. Normal painting all task started." -msgstr "Unealta Paint. Taskul de pictare a tuturor poligoanelor a inceput." - -#: flatcamTools/ToolPaint.py:2623 +#: flatcamTools/ToolPaint.py:2634 msgid "Paint All Done." msgstr "Pictarea Tuturor poligoanelor efectuată." -#: flatcamTools/ToolPaint.py:2634 flatcamTools/ToolPaint.py:2638 -#: flatcamTools/ToolPaint.py:2641 -msgid "Rest machining painting all task started." -msgstr "" -"Taskul de pictare prin prelucrare 'rest' a tuturor poligoanelor a inceput." - -#: flatcamTools/ToolPaint.py:2862 flatcamTools/ToolPaint.py:3334 -#: flatcamTools/ToolPaint.py:3683 -msgid "Painting polygons with method: lines." -msgstr "Se pictează poligoane aflat icu metoda: linii." - -#: flatcamTools/ToolPaint.py:2875 flatcamTools/ToolPaint.py:3347 -#: flatcamTools/ToolPaint.py:3695 -msgid "Failed. Painting polygons with method: seed." -msgstr "Esuat. Se pictează poligoanele cu metoda: sămantă." - -#: flatcamTools/ToolPaint.py:2887 flatcamTools/ToolPaint.py:3359 -#: flatcamTools/ToolPaint.py:3707 -msgid "Failed. Painting polygons with method: standard." -msgstr "Esuat. Se pictează poligoanele cu metoda: standard." - -#: flatcamTools/ToolPaint.py:2904 flatcamTools/ToolPaint.py:3723 -msgid "" -"Could not do Paint All. Try a different combination of parameters. Or a " -"different Method of paint" -msgstr "" -"Nu s-a efectuat op. 'Paint' pt toate poligoanele. Incearcă o combinaţie " -"diferită de parametri. Sau încearcă o alta metoda de 'pictat'" - -#: flatcamTools/ToolPaint.py:2964 flatcamTools/ToolPaint.py:3780 +#: flatcamTools/ToolPaint.py:2803 flatcamTools/ToolPaint.py:3300 msgid "Paint All with Rest-Machining done." msgstr "'Paint' pentru toate poligoanele cu strategia Rest a fost efectuată." -#: flatcamTools/ToolPaint.py:3084 flatcamTools/ToolPaint.py:3087 -#: flatcamTools/ToolPaint.py:3089 -msgid "Paint Tool. Normal painting area task started." -msgstr "Unealta Paint. Taskul de pictare a unei arii a inceput." +#: flatcamTools/ToolPaint.py:2822 +msgid "Paint All failed." +msgstr "Pictarea pt toate poligoanele a easuat." -#: flatcamTools/ToolPaint.py:3437 +#: flatcamTools/ToolPaint.py:2828 +msgid "Paint Poly All Done." +msgstr "Pictarea pt toate poligoanele efectuată." + +#: flatcamTools/ToolPaint.py:2898 flatcamTools/ToolPaint.py:2901 +#: flatcamTools/ToolPaint.py:2907 +msgid "Painting area task started." +msgstr "Taskul de pictare a unei arii a inceput." + +#: flatcamTools/ToolPaint.py:3121 msgid "Paint Area Done." msgstr "Paint pt o zona efectuata." -#: flatcamTools/ToolPaint.py:3448 flatcamTools/ToolPaint.py:3452 -#: flatcamTools/ToolPaint.py:3455 -msgid "Rest machining painting area task started." -msgstr "" -"Taskul de pictare a unei arii cu strategia de masinare 'rest' a inceput." +#: flatcamTools/ToolPaint.py:3319 +msgid "Paint Area failed." +msgstr "Pictarea unei Zone a esuat." + +#: flatcamTools/ToolPaint.py:3325 +msgid "Paint Poly Area Done." +msgstr "Paint pt o Zonă efectuat." #: flatcamTools/ToolPanelize.py:34 msgid "Panelize PCB" @@ -17805,12 +17787,12 @@ msgstr "" msgid "TclCommand Bounds done." msgstr "TclCommand Bounds executata." -#: tclCommands/TclCommandCopperClear.py:256 tclCommands/TclCommandPaint.py:261 +#: tclCommands/TclCommandCopperClear.py:276 tclCommands/TclCommandPaint.py:272 #: tclCommands/TclCommandScale.py:81 msgid "Could not retrieve box object" msgstr "Nu s-a putut incărca obiectul" -#: tclCommands/TclCommandCopperClear.py:279 +#: tclCommands/TclCommandCopperClear.py:299 msgid "Expected either -box or -all." msgstr "Asteptăm -box sau -all." @@ -17848,15 +17830,15 @@ msgstr "Introduceți help pentru utilizare." msgid "Example: help open_gerber" msgstr "Exemplu: help open_gerber" -#: tclCommands/TclCommandPaint.py:229 +#: tclCommands/TclCommandPaint.py:244 msgid "Expected -x and -y ." msgstr "Asteptam -x si -y ." -#: tclCommands/TclCommandPaint.py:254 +#: tclCommands/TclCommandPaint.py:265 msgid "Expected -box ." msgstr "Asteptăm -box ." -#: tclCommands/TclCommandPaint.py:279 +#: tclCommands/TclCommandPaint.py:286 msgid "" "None of the following args: 'box', 'single', 'all' were used.\n" "Paint failed." @@ -17890,6 +17872,36 @@ msgstr "" "Nici-un nume de Geometrie in argumente. Furnizați un nume și încercați din " "nou." +#~ msgid "Paint Tool. Normal painting all task started." +#~ msgstr "Unealta Paint. Taskul de pictare a tuturor poligoanelor a inceput." + +#~ msgid "Rest machining painting all task started." +#~ msgstr "" +#~ "Taskul de pictare prin prelucrare 'rest' a tuturor poligoanelor a inceput." + +#~ msgid "Painting polygons with method: lines." +#~ msgstr "Se pictează poligoane aflat icu metoda: linii." + +#~ msgid "Failed. Painting polygons with method: seed." +#~ msgstr "Esuat. Se pictează poligoanele cu metoda: sămantă." + +#~ msgid "Failed. Painting polygons with method: standard." +#~ msgstr "Esuat. Se pictează poligoanele cu metoda: standard." + +#~ msgid "" +#~ "Could not do Paint All. Try a different combination of parameters. Or a " +#~ "different Method of paint" +#~ msgstr "" +#~ "Nu s-a efectuat op. 'Paint' pt toate poligoanele. Incearcă o combinaţie " +#~ "diferită de parametri. Sau încearcă o alta metoda de 'pictat'" + +#~ msgid "Paint Tool. Normal painting area task started." +#~ msgstr "Unealta Paint. Taskul de pictare a unei arii a inceput." + +#~ msgid "Rest machining painting area task started." +#~ msgstr "" +#~ "Taskul de pictare a unei arii cu strategia de masinare 'rest' a inceput." + #~ msgid "Executing Tcl Script ..." #~ msgstr "Rulează Tcl Script..." @@ -18207,9 +18219,6 @@ msgstr "" #~ msgid "Paint Tool. Reading parameters." #~ msgstr "Unealta Paint. Se citesc parametrii." -#~ msgid "Normal painting area task started." -#~ msgstr "Taskul de pictare normal a unei arii a inceput." - #~ msgid "Paint Tool. Rest machining painting area task started." #~ msgstr "" #~ "Unealta Paint. Taskul de pictare a unei arii cu strategia de masinare " diff --git a/locale_template/strings.pot b/locale_template/strings.pot index e76c382f..0856f258 100644 --- a/locale_template/strings.pot +++ b/locale_template/strings.pot @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2020-04-24 09:22+0300\n" +"POT-Creation-Date: 2020-04-24 21:10+0300\n" "PO-Revision-Date: 2019-03-25 15:08+0200\n" "Last-Translator: \n" "Language-Team: \n" @@ -28,9 +28,9 @@ msgstr "" #: flatcamEditors/FlatCAMGeoEditor.py:5152 flatcamGUI/PreferencesUI.py:5509 #: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 flatcamTools/ToolNCC.py:2401 #: flatcamTools/ToolNCC.py:2429 flatcamTools/ToolNCC.py:2699 flatcamTools/ToolNCC.py:2731 -#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:1832 -#: flatcamTools/ToolPaint.py:2723 flatcamTools/ToolPaint.py:3178 -#: flatcamTools/ToolPaint.py:3544 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:1836 +#: tclCommands/TclCommandCopperClear.py:128 tclCommands/TclCommandCopperClear.py:136 +#: tclCommands/TclCommandPaint.py:127 msgid "Seed" msgstr "" @@ -38,11 +38,12 @@ msgstr "" #: flatcamTools/ToolCopperThieving.py:126 flatcamTools/ToolNCC.py:535 #: flatcamTools/ToolNCC.py:1299 flatcamTools/ToolNCC.py:1638 flatcamTools/ToolNCC.py:1919 #: flatcamTools/ToolNCC.py:1983 flatcamTools/ToolNCC.py:2967 flatcamTools/ToolNCC.py:2976 +#: tclCommands/TclCommandCopperClear.py:190 msgid "Itself" msgstr "" #: FlatCAMApp.py:817 flatcamGUI/PreferencesUI.py:6119 flatcamTools/ToolPaint.py:486 -#: flatcamTools/ToolPaint.py:1415 +#: flatcamTools/ToolPaint.py:1415 tclCommands/TclCommandPaint.py:162 msgid "All Polygons" msgstr "" @@ -682,8 +683,8 @@ msgstr "" #: FlatCAMApp.py:7897 FlatCAMApp.py:7925 FlatCAMApp.py:7952 FlatCAMApp.py:7971 #: FlatCAMApp.py:8038 FlatCAMCommon.py:1182 FlatCAMCommon.py:1357 FlatCAMCommon.py:2612 #: FlatCAMCommon.py:2820 FlatCAMObj.py:4798 flatcamTools/ToolNCC.py:3963 -#: flatcamTools/ToolNCC.py:4047 flatcamTools/ToolPaint.py:4027 -#: flatcamTools/ToolPaint.py:4112 +#: flatcamTools/ToolNCC.py:4047 flatcamTools/ToolPaint.py:3537 +#: flatcamTools/ToolPaint.py:3622 msgid "Tools Database" msgstr "" @@ -691,7 +692,7 @@ msgstr "" msgid "Tools in Tools Database edited but not saved." msgstr "" -#: FlatCAMApp.py:7975 flatcamTools/ToolNCC.py:3970 flatcamTools/ToolPaint.py:4034 +#: FlatCAMApp.py:7975 flatcamTools/ToolNCC.py:3970 flatcamTools/ToolPaint.py:3544 msgid "Tool from DB added in Tool Table." msgstr "" @@ -2184,8 +2185,8 @@ msgstr "" #: flatcamGUI/PreferencesUI.py:5509 flatcamGUI/PreferencesUI.py:6056 #: flatcamTools/ToolNCC.py:431 flatcamTools/ToolNCC.py:2395 flatcamTools/ToolNCC.py:2424 #: flatcamTools/ToolNCC.py:2693 flatcamTools/ToolNCC.py:2725 flatcamTools/ToolPaint.py:390 -#: flatcamTools/ToolPaint.py:1818 flatcamTools/ToolPaint.py:2717 -#: flatcamTools/ToolPaint.py:3198 flatcamTools/ToolPaint.py:3538 +#: flatcamTools/ToolPaint.py:1822 tclCommands/TclCommandCopperClear.py:126 +#: tclCommands/TclCommandCopperClear.py:134 tclCommands/TclCommandPaint.py:125 msgid "Standard" msgstr "" @@ -2193,8 +2194,8 @@ msgstr "" #: flatcamEditors/FlatCAMGeoEditor.py:5156 flatcamGUI/PreferencesUI.py:5509 #: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 #: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:696 -#: flatcamTools/ToolPaint.py:1846 flatcamTools/ToolPaint.py:2729 -#: flatcamTools/ToolPaint.py:3188 flatcamTools/ToolPaint.py:3550 +#: flatcamTools/ToolPaint.py:1850 tclCommands/TclCommandCopperClear.py:130 +#: tclCommands/TclCommandPaint.py:129 msgid "Lines" msgstr "" @@ -2276,15 +2277,13 @@ msgstr "" #: FlatCAMCommon.py:2040 FlatCAMCommon.py:2042 flatcamGUI/PreferencesUI.py:6056 #: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:392 flatcamTools/ToolPaint.py:690 -#: flatcamTools/ToolPaint.py:695 flatcamTools/ToolPaint.py:1860 -#: flatcamTools/ToolPaint.py:2735 flatcamTools/ToolPaint.py:3207 -#: flatcamTools/ToolPaint.py:3556 +#: flatcamTools/ToolPaint.py:695 flatcamTools/ToolPaint.py:1864 +#: tclCommands/TclCommandPaint.py:131 msgid "Laser_lines" msgstr "" #: FlatCAMCommon.py:2040 flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolPaint.py:390 -#: flatcamTools/ToolPaint.py:2011 flatcamTools/ToolPaint.py:2861 -#: flatcamTools/ToolPaint.py:3333 flatcamTools/ToolPaint.py:3682 +#: flatcamTools/ToolPaint.py:2015 tclCommands/TclCommandPaint.py:133 msgid "Combo" msgstr "" @@ -9700,6 +9699,7 @@ msgstr "" #: flatcamTools/ToolNCC.py:1941 flatcamTools/ToolNCC.py:1998 flatcamTools/ToolNCC.py:2306 #: flatcamTools/ToolNCC.py:2586 flatcamTools/ToolNCC.py:3012 flatcamTools/ToolPaint.py:486 #: flatcamTools/ToolPaint.py:924 flatcamTools/ToolPaint.py:1456 +#: tclCommands/TclCommandCopperClear.py:192 tclCommands/TclCommandPaint.py:166 msgid "Reference Object" msgstr "" @@ -9903,6 +9903,7 @@ msgstr "" #: flatcamGUI/PreferencesUI.py:6119 flatcamTools/ToolPaint.py:486 #: flatcamTools/ToolPaint.py:935 flatcamTools/ToolPaint.py:1420 +#: tclCommands/TclCommandPaint.py:164 msgid "Polygon Selection" msgstr "" @@ -12253,7 +12254,7 @@ msgid "Geometry not supported for bounding box" msgstr "" #: flatcamTools/ToolCopperThieving.py:1068 flatcamTools/ToolNCC.py:1933 -#: flatcamTools/ToolNCC.py:1988 flatcamTools/ToolNCC.py:2992 flatcamTools/ToolPaint.py:3854 +#: flatcamTools/ToolNCC.py:1988 flatcamTools/ToolNCC.py:2992 flatcamTools/ToolPaint.py:3368 msgid "No object available." msgstr "" @@ -13365,12 +13366,12 @@ msgid "Please enter a tool diameter to add, in Float format." msgstr "" #: flatcamTools/ToolNCC.py:1460 flatcamTools/ToolNCC.py:4013 flatcamTools/ToolPaint.py:1196 -#: flatcamTools/ToolPaint.py:4077 flatcamTools/ToolSolderPaste.py:917 +#: flatcamTools/ToolPaint.py:3587 flatcamTools/ToolSolderPaste.py:917 msgid "Cancelled. Tool already in Tool Table." msgstr "" #: flatcamTools/ToolNCC.py:1467 flatcamTools/ToolNCC.py:4030 flatcamTools/ToolPaint.py:1201 -#: flatcamTools/ToolPaint.py:4094 +#: flatcamTools/ToolPaint.py:3604 msgid "New tool added to Tool Table." msgstr "" @@ -13720,151 +13721,137 @@ msgstr "" msgid "Click to add/remove next polygon or right click to start painting." msgstr "" -#: flatcamTools/ToolPaint.py:2013 +#: flatcamTools/ToolPaint.py:2017 msgid "Painting polygon with method: lines." msgstr "" -#: flatcamTools/ToolPaint.py:2025 +#: flatcamTools/ToolPaint.py:2029 msgid "Failed. Painting polygon with method: seed." msgstr "" -#: flatcamTools/ToolPaint.py:2036 +#: flatcamTools/ToolPaint.py:2040 msgid "Failed. Painting polygon with method: standard." msgstr "" -#: flatcamTools/ToolPaint.py:2052 +#: flatcamTools/ToolPaint.py:2056 msgid "Geometry could not be painted completely" msgstr "" -#: flatcamTools/ToolPaint.py:2081 flatcamTools/ToolPaint.py:2084 -#: flatcamTools/ToolPaint.py:2092 flatcamTools/ToolPaint.py:2634 -#: flatcamTools/ToolPaint.py:2638 flatcamTools/ToolPaint.py:2641 -#: flatcamTools/ToolPaint.py:3448 flatcamTools/ToolPaint.py:3452 -#: flatcamTools/ToolPaint.py:3455 +#: flatcamTools/ToolPaint.py:2085 flatcamTools/ToolPaint.py:2088 +#: flatcamTools/ToolPaint.py:2096 flatcamTools/ToolPaint.py:2399 +#: flatcamTools/ToolPaint.py:2402 flatcamTools/ToolPaint.py:2410 +#: flatcamTools/ToolPaint.py:2898 flatcamTools/ToolPaint.py:2901 +#: flatcamTools/ToolPaint.py:2907 msgid "Paint Tool." msgstr "" -#: flatcamTools/ToolPaint.py:2081 flatcamTools/ToolPaint.py:2084 -#: flatcamTools/ToolPaint.py:2092 +#: flatcamTools/ToolPaint.py:2085 flatcamTools/ToolPaint.py:2088 +#: flatcamTools/ToolPaint.py:2096 msgid "Normal painting polygon task started." msgstr "" -#: flatcamTools/ToolPaint.py:2082 flatcamTools/ToolPaint.py:2423 -#: flatcamTools/ToolPaint.py:2635 flatcamTools/ToolPaint.py:3085 -#: flatcamTools/ToolPaint.py:3449 +#: flatcamTools/ToolPaint.py:2086 flatcamTools/ToolPaint.py:2400 +#: flatcamTools/ToolPaint.py:2899 msgid "Buffering geometry..." msgstr "" -#: flatcamTools/ToolPaint.py:2105 +#: flatcamTools/ToolPaint.py:2108 flatcamTools/ToolPaint.py:2417 +#: flatcamTools/ToolPaint.py:2915 msgid "No polygon found." msgstr "" -#: flatcamTools/ToolPaint.py:2135 +#: flatcamTools/ToolPaint.py:2138 msgid "Painting polygon..." msgstr "" -#: flatcamTools/ToolPaint.py:2144 flatcamTools/ToolPaint.py:2466 -#: flatcamTools/ToolPaint.py:2674 flatcamTools/ToolPaint.py:3132 -#: flatcamTools/ToolPaint.py:3492 +#: flatcamTools/ToolPaint.py:2148 flatcamTools/ToolPaint.py:2463 +#: flatcamTools/ToolPaint.py:2653 flatcamTools/ToolPaint.py:2961 +#: flatcamTools/ToolPaint.py:3140 msgid "Painting with tool diameter = " msgstr "" -#: flatcamTools/ToolPaint.py:2145 flatcamTools/ToolPaint.py:2469 -#: flatcamTools/ToolPaint.py:2677 flatcamTools/ToolPaint.py:3135 -#: flatcamTools/ToolPaint.py:3495 +#: flatcamTools/ToolPaint.py:2149 flatcamTools/ToolPaint.py:2464 +#: flatcamTools/ToolPaint.py:2654 flatcamTools/ToolPaint.py:2962 +#: flatcamTools/ToolPaint.py:3141 msgid "started" msgstr "" -#: flatcamTools/ToolPaint.py:2170 flatcamTools/ToolPaint.py:2494 -#: flatcamTools/ToolPaint.py:2703 flatcamTools/ToolPaint.py:3161 -#: flatcamTools/ToolPaint.py:3524 +#: flatcamTools/ToolPaint.py:2174 flatcamTools/ToolPaint.py:2490 +#: flatcamTools/ToolPaint.py:2680 flatcamTools/ToolPaint.py:2988 +#: flatcamTools/ToolPaint.py:3167 msgid "Margin parameter too big. Tool is not used" msgstr "" -#: flatcamTools/ToolPaint.py:2210 flatcamTools/ToolPaint.py:2564 -#: flatcamTools/ToolPaint.py:3377 +#: flatcamTools/ToolPaint.py:2232 flatcamTools/ToolPaint.py:2559 +#: flatcamTools/ToolPaint.py:2737 flatcamTools/ToolPaint.py:3051 +#: flatcamTools/ToolPaint.py:3229 msgid "" "Could not do Paint. Try a different combination of parameters. Or a different strategy of " "paint" msgstr "" -#: flatcamTools/ToolPaint.py:2268 flatcamTools/ToolPaint.py:2614 -#: flatcamTools/ToolPaint.py:2955 flatcamTools/ToolPaint.py:3428 -#: flatcamTools/ToolPaint.py:3771 +#: flatcamTools/ToolPaint.py:2289 flatcamTools/ToolPaint.py:2625 +#: flatcamTools/ToolPaint.py:2794 flatcamTools/ToolPaint.py:3112 +#: flatcamTools/ToolPaint.py:3291 msgid "" "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." msgstr "" -#: flatcamTools/ToolPaint.py:2300 +#: flatcamTools/ToolPaint.py:2312 msgid "Paint Single failed." msgstr "" -#: flatcamTools/ToolPaint.py:2306 +#: flatcamTools/ToolPaint.py:2318 msgid "Paint Single Done." msgstr "" -#: flatcamTools/ToolPaint.py:2308 flatcamTools/ToolPaint.py:2983 -#: flatcamTools/ToolPaint.py:3799 +#: flatcamTools/ToolPaint.py:2320 flatcamTools/ToolPaint.py:2830 +#: flatcamTools/ToolPaint.py:3327 msgid "Polygon Paint started ..." msgstr "" -#: flatcamTools/ToolPaint.py:2347 flatcamTools/ToolPaint.py:3023 +#: flatcamTools/ToolPaint.py:2399 flatcamTools/ToolPaint.py:2402 +#: flatcamTools/ToolPaint.py:2410 +msgid "Paint all polygons task started." +msgstr "" + +#: flatcamTools/ToolPaint.py:2441 flatcamTools/ToolPaint.py:2939 msgid "Painting polygons..." msgstr "" -#: flatcamTools/ToolPaint.py:2422 flatcamTools/ToolPaint.py:2425 -#: flatcamTools/ToolPaint.py:2427 -msgid "Paint Tool. Normal painting all task started." -msgstr "" - -#: flatcamTools/ToolPaint.py:2623 +#: flatcamTools/ToolPaint.py:2634 msgid "Paint All Done." msgstr "" -#: flatcamTools/ToolPaint.py:2634 flatcamTools/ToolPaint.py:2638 -#: flatcamTools/ToolPaint.py:2641 -msgid "Rest machining painting all task started." -msgstr "" - -#: flatcamTools/ToolPaint.py:2862 flatcamTools/ToolPaint.py:3334 -#: flatcamTools/ToolPaint.py:3683 -msgid "Painting polygons with method: lines." -msgstr "" - -#: flatcamTools/ToolPaint.py:2875 flatcamTools/ToolPaint.py:3347 -#: flatcamTools/ToolPaint.py:3695 -msgid "Failed. Painting polygons with method: seed." -msgstr "" - -#: flatcamTools/ToolPaint.py:2887 flatcamTools/ToolPaint.py:3359 -#: flatcamTools/ToolPaint.py:3707 -msgid "Failed. Painting polygons with method: standard." -msgstr "" - -#: flatcamTools/ToolPaint.py:2904 flatcamTools/ToolPaint.py:3723 -msgid "" -"Could not do Paint All. Try a different combination of parameters. Or a different Method " -"of paint" -msgstr "" - -#: flatcamTools/ToolPaint.py:2964 flatcamTools/ToolPaint.py:3780 +#: flatcamTools/ToolPaint.py:2803 flatcamTools/ToolPaint.py:3300 msgid "Paint All with Rest-Machining done." msgstr "" -#: flatcamTools/ToolPaint.py:3084 flatcamTools/ToolPaint.py:3087 -#: flatcamTools/ToolPaint.py:3089 -msgid "Paint Tool. Normal painting area task started." +#: flatcamTools/ToolPaint.py:2822 +msgid "Paint All failed." msgstr "" -#: flatcamTools/ToolPaint.py:3437 +#: flatcamTools/ToolPaint.py:2828 +msgid "Paint Poly All Done." +msgstr "" + +#: flatcamTools/ToolPaint.py:2898 flatcamTools/ToolPaint.py:2901 +#: flatcamTools/ToolPaint.py:2907 +msgid "Painting area task started." +msgstr "" + +#: flatcamTools/ToolPaint.py:3121 msgid "Paint Area Done." msgstr "" -#: flatcamTools/ToolPaint.py:3448 flatcamTools/ToolPaint.py:3452 -#: flatcamTools/ToolPaint.py:3455 -msgid "Rest machining painting area task started." +#: flatcamTools/ToolPaint.py:3319 +msgid "Paint Area failed." +msgstr "" + +#: flatcamTools/ToolPaint.py:3325 +msgid "Paint Poly Area Done." msgstr "" #: flatcamTools/ToolPanelize.py:34 @@ -15089,12 +15076,12 @@ msgstr "" msgid "TclCommand Bounds done." msgstr "" -#: tclCommands/TclCommandCopperClear.py:256 tclCommands/TclCommandPaint.py:261 +#: tclCommands/TclCommandCopperClear.py:276 tclCommands/TclCommandPaint.py:272 #: tclCommands/TclCommandScale.py:81 msgid "Could not retrieve box object" msgstr "" -#: tclCommands/TclCommandCopperClear.py:279 +#: tclCommands/TclCommandCopperClear.py:299 msgid "Expected either -box or -all." msgstr "" @@ -15126,15 +15113,15 @@ msgstr "" msgid "Example: help open_gerber" msgstr "" -#: tclCommands/TclCommandPaint.py:229 +#: tclCommands/TclCommandPaint.py:244 msgid "Expected -x and -y ." msgstr "" -#: tclCommands/TclCommandPaint.py:254 +#: tclCommands/TclCommandPaint.py:265 msgid "Expected -box ." msgstr "" -#: tclCommands/TclCommandPaint.py:279 +#: tclCommands/TclCommandPaint.py:286 msgid "" "None of the following args: 'box', 'single', 'all' were used.\n" "Paint failed." From 02959500000dfa24d7e4584f1a45cb1055a8dc31 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 25 Apr 2020 06:55:41 +0300 Subject: [PATCH 207/209] - ensured that on Graceful Exit (CTRL+ALT+X key combo) if using Progressive Plotting, the eventual residual plotted lines are deleted. This apply for Tool NCC and Tool Paint --- CHANGELOG.md | 4 ++ FlatCAMApp.py | 6 +++ flatcamTools/ToolNCC.py | 83 +++++++++++++++++++-------------------- flatcamTools/ToolPaint.py | 19 +++++++-- 4 files changed, 66 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ba9929d..81240a73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ CHANGELOG for FlatCAM beta ================================================= +25.04.2020 + +- ensured that on Graceful Exit (CTRL+ALT+X key combo) if using Progressive Plotting, the eventual residual plotted lines are deleted. This apply for Tool NCC and Tool Paint + 24.04.2020 - some PEP changes, some method descriptions updated diff --git a/FlatCAMApp.py b/FlatCAMApp.py index a90fbd68..bb03ba24 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -253,6 +253,11 @@ class App(QtCore.QObject): # close app signal close_app_signal = pyqtSignal() + # will perform the cleanup operation after a Graceful Exit + # usefull for the NCC Tool and Paint Tool where some progressive plotting might leave + # graphic residues behind + cleanup = pyqtSignal() + def __init__(self, user_defaults=True): """ Starts the application. @@ -7781,6 +7786,7 @@ class App(QtCore.QObject): if self.abort_flag is False: self.inform.emit(_("Aborting. The current task will be gracefully closed as soon as possible...")) self.abort_flag = True + self.cleanup.emit() def app_is_idle(self): if self.abort_flag: diff --git a/flatcamTools/ToolNCC.py b/flatcamTools/ToolNCC.py index 4b4f4e0f..cfbeecaf 100644 --- a/flatcamTools/ToolNCC.py +++ b/flatcamTools/ToolNCC.py @@ -8,8 +8,8 @@ from PyQt5 import QtWidgets, QtCore, QtGui from FlatCAMTool import FlatCAMTool -from flatcamGUI.GUIElements import FCCheckBox, FCDoubleSpinner, RadioSet, FCTable, FCInputDialog, FCButton, FCComboBox, \ - OptionalInputSection +from flatcamGUI.GUIElements import FCCheckBox, FCDoubleSpinner, RadioSet, FCTable, FCInputDialog, FCButton,\ + FCComboBox, OptionalInputSection from flatcamParsers.ParseGerber import Gerber import FlatCAMApp @@ -743,6 +743,9 @@ class NonCopperClear(FlatCAMTool, Gerber): self.reset_button.clicked.connect(self.set_tool_ui) + # Cleanup on Graceful exit (CTRL+ALT+X combo key) + self.app.cleanup.connect(self.reset_usage) + def on_type_obj_index_changed(self, val): obj_type = 0 if val == 'gerber' else 2 self.object_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) @@ -873,7 +876,6 @@ class NonCopperClear(FlatCAMTool, Gerber): for tooluid_key, tooluid_val in self.ncc_tools.items(): tooluid_val['data'] = deepcopy(temp_tool_data) - # store all the data associated with the row parameter to the self.tools storage # tooldia_item = float(self.tools_table.item(row, 1).text()) # type_item = self.tools_table.cellWidget(row, 2).currentText() @@ -1343,6 +1345,9 @@ class NonCopperClear(FlatCAMTool, Gerber): def on_tooltable_cellwidget_change(self): cw = self.sender() + assert isinstance(cw, QtWidgets.QComboBox),\ + "Expected a QtWidgets.QComboBox, got %s" % isinstance(cw, QtWidgets.QComboBox) + cw_index = self.tools_table.indexAt(cw.pos()) cw_row = cw_index.row() cw_col = cw_index.column() @@ -1359,20 +1364,6 @@ class NonCopperClear(FlatCAMTool, Gerber): 'tool_type': tt, }) - # if cw_col == 4: - # op = cw.currentText() - # - # if op == 'iso_op': - # self.milling_type_label.show() - # self.milling_type_radio.show() - # else: - # self.milling_type_label.hide() - # self.milling_type_radio.hide() - # - # self.ncc_tools[current_uid].update({ - # 'operation': op - # }) - def on_tool_type(self, val): if val == 'V': self.addtool_entry_lbl.setDisabled(True) @@ -1851,8 +1842,8 @@ class NonCopperClear(FlatCAMTool, Gerber): self.draw_moving_selection_shape_poly(points=self.points, data=(curr_pos[0], curr_pos[1])) def on_key_press(self, event): - modifiers = QtWidgets.QApplication.keyboardModifiers() - matplotlib_key_flag = False + # modifiers = QtWidgets.QApplication.keyboardModifiers() + # matplotlib_key_flag = False # events out of the self.app.collection view (it's about Project Tab) are of type int if type(event) is int: @@ -1861,7 +1852,7 @@ class NonCopperClear(FlatCAMTool, Gerber): elif type(event) == QtGui.QKeyEvent: key = event.key() elif isinstance(event, mpl_key_event): # MatPlotLib key events are trickier to interpret than the rest - matplotlib_key_flag = True + # matplotlib_key_flag = True key = event.key key = QtGui.QKeySequence(key) @@ -1871,13 +1862,17 @@ class NonCopperClear(FlatCAMTool, Gerber): if '+' in key_string: mod, __, key_text = key_string.rpartition('+') if mod.lower() == 'ctrl': - modifiers = QtCore.Qt.ControlModifier + # modifiers = QtCore.Qt.ControlModifier + pass elif mod.lower() == 'alt': - modifiers = QtCore.Qt.AltModifier + # modifiers = QtCore.Qt.AltModifier + pass elif mod.lower() == 'shift': - modifiers = QtCore.Qt.ShiftModifier + # modifiers = QtCore.Qt.ShiftModifier + pass else: - modifiers = QtCore.Qt.NoModifier + # modifiers = QtCore.Qt.NoModifier + pass key = QtGui.QKeySequence(key_text) # events from Vispy are of type KeyEvent @@ -3078,7 +3073,7 @@ class NonCopperClear(FlatCAMTool, Gerber): app_obj.poly_not_cleared = False # Generate area for each tool - offset = sum(sorted_tools) + offset_a = sum(sorted_tools) current_uid = int(1) try: tool = eval(self.app.defaults["tools_ncctools"])[0] @@ -3154,8 +3149,8 @@ class NonCopperClear(FlatCAMTool, Gerber): if new_geo and not new_geo.is_empty: new_geometry.append(new_geo) elif isinstance(geo_elem, MultiPolygon): - for poly in geo_elem: - for ring in self.poly2rings(poly): + for a_poly in geo_elem: + for ring in self.poly2rings(a_poly): new_geo = ring.intersection(bounding_box) if new_geo and not new_geo.is_empty: new_geometry.append(new_geo) @@ -3260,10 +3255,10 @@ class NonCopperClear(FlatCAMTool, Gerber): cleared_geo[:] = [] # Get remaining tools offset - offset -= (tool - 1e-12) + offset_a -= (tool - 1e-12) # Area to clear - area = empty.buffer(-offset) + area = empty.buffer(-offset_a) try: area = area.difference(cleared) except Exception: @@ -3369,7 +3364,7 @@ class NonCopperClear(FlatCAMTool, Gerber): # check if there is a geometry at all in the cleared geometry if cleared_geo: # Overall cleared area - cleared = empty.buffer(-offset * (1 + overlap)).buffer(-tool / 1.999999).buffer( + cleared = empty.buffer(-offset_a * (1 + overlap)).buffer(-tool / 1.999999).buffer( tool / 1.999999) # clean-up cleared geo @@ -3533,8 +3528,8 @@ class NonCopperClear(FlatCAMTool, Gerber): if new_geo and not new_geo.is_empty: new_geometry.append(new_geo) elif isinstance(geo_elem, MultiPolygon): - for poly in geo_elem: - for ring in self.poly2rings(poly): + for poly_g in geo_elem: + for ring in self.poly2rings(poly_g): new_geo = ring.intersection(bounding_box) if new_geo and not new_geo.is_empty: new_geometry.append(new_geo) @@ -3647,7 +3642,7 @@ class NonCopperClear(FlatCAMTool, Gerber): cleared_geo[:] = [] # Area to clear - for poly in cleared_by_last_tool: + for poly_r in cleared_by_last_tool: # provide the app with a way to process the GUI events when in a blocking loop QtWidgets.QApplication.processEvents() @@ -3655,7 +3650,7 @@ class NonCopperClear(FlatCAMTool, Gerber): # graceful abort requested by the user raise FlatCAMApp.GracefulException try: - area = area.difference(poly) + area = area.difference(poly_r) except Exception: pass cleared_by_last_tool[:] = [] @@ -3716,27 +3711,27 @@ class NonCopperClear(FlatCAMTool, Gerber): # a smaller tool rest_geo.append(p) elif isinstance(p, MultiPolygon): - for poly in p: - if poly is not None: + for poly_p in p: + if poly_p is not None: # provide the app with a way to process the GUI events when # in a blocking loop QtWidgets.QApplication.processEvents() try: if ncc_method == 'standard': - cp = self.clear_polygon(poly, tool_used, + cp = self.clear_polygon(poly_p, tool_used, self.grb_circle_steps, overlap=overlap, contour=contour, connect=connect, prog_plot=False) elif ncc_method == 'seed': - cp = self.clear_polygon2(poly, tool_used, + cp = self.clear_polygon2(poly_p, tool_used, self.grb_circle_steps, overlap=overlap, contour=contour, connect=connect, prog_plot=False) else: - cp = self.clear_polygon3(poly, tool_used, + cp = self.clear_polygon3(poly_p, tool_used, self.grb_circle_steps, overlap=overlap, contour=contour, connect=connect, @@ -3746,7 +3741,7 @@ class NonCopperClear(FlatCAMTool, Gerber): log.warning("Polygon can't be cleared. %s" % str(eee)) # this polygon should be added to a list and then try clear it with # a smaller tool - rest_geo.append(poly) + rest_geo.append(poly_p) pol_nr += 1 disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100])) @@ -3779,8 +3774,8 @@ class NonCopperClear(FlatCAMTool, Gerber): # graceful abort requested by the user raise FlatCAMApp.GracefulException - poly = p.buffer(buffer_value) - cleared_by_last_tool.append(poly) + r_poly = p.buffer(buffer_value) + cleared_by_last_tool.append(r_poly) # find the tooluid associated with the current tool_dia so we know # where to add the tool solid_geometry @@ -4065,4 +4060,8 @@ class NonCopperClear(FlatCAMTool, Gerber): self.cursor_pos = None self.mouse_is_dragging = False + prog_plot = True if self.app.defaults["tools_ncc_plotting"] == 'progressive' else False + if prog_plot: + self.temp_shapes.clear(update=True) + self.sel_rect = [] diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 1bec59b1..d7b85ca7 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -665,6 +665,9 @@ class ToolPaint(FlatCAMTool, Gerber): self.reset_button.clicked.connect(self.set_tool_ui) + # Cleanup on Graceful exit (CTRL+ALT+X combo key) + self.app.cleanup.connect(self.reset_usage) + # ############################################################################# # ###################### Setup CONTEXT MENU ################################### # ############################################################################# @@ -860,6 +863,10 @@ class ToolPaint(FlatCAMTool, Gerber): def on_tooltable_cellwidget_change(self): cw = self.sender() + + assert isinstance(cw, QtWidgets.QComboBox), \ + "Expected a QtWidgets.QComboBox, got %s" % isinstance(cw, QtWidgets.QComboBox) + cw_index = self.tools_table.indexAt(cw.pos()) cw_row = cw_index.row() cw_col = cw_index.column() @@ -2285,10 +2292,10 @@ class ToolPaint(FlatCAMTool, Gerber): has_solid_geo += 1 if has_solid_geo == 0: - self.app.inform.emit('[ERROR] %s' % - _("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.")) + app_obj.inform.emit('[ERROR] %s' % + _("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 "fail" # Experimental... @@ -3495,6 +3502,10 @@ class ToolPaint(FlatCAMTool, Gerber): self.cursor_pos = None self.mouse_is_dragging = False + prog_plot = True if self.app.defaults["tools_paint_plotting"] == 'progressive' else False + if prog_plot: + self.temp_shapes.clear(update=True) + self.sel_rect = [] @staticmethod From 74582d02df7eb3c43d696de54ee331c4fde757e8 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 25 Apr 2020 07:30:10 +0300 Subject: [PATCH 208/209] - fixed links in Attributions tab in Help -> About FlatCAM to be able to open external links. --- CHANGELOG.md | 1 + FlatCAMApp.py | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81240a73..8403789e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ CHANGELOG for FlatCAM beta 25.04.2020 - ensured that on Graceful Exit (CTRL+ALT+X key combo) if using Progressive Plotting, the eventual residual plotted lines are deleted. This apply for Tool NCC and Tool Paint +- fixed links in Attributions tab in Help -> About FlatCAM to be able to open external links. 24.04.2020 diff --git a/FlatCAMApp.py b/FlatCAMApp.py index bb03ba24..0cd6a882 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -4657,6 +4657,7 @@ class App(QtCore.QObject): 'Icons by oNline Web Fonts' ) ) + attributions_label.setOpenExternalLinks(True) # layouts layout1 = QtWidgets.QVBoxLayout() From 769b5165b448db4e78a7f074aacc31626b29c3c9 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 25 Apr 2020 17:46:06 +0300 Subject: [PATCH 209/209] - updated Google Translations for French and Spanish languages --- CHANGELOG.md | 1 + locale/en/LC_MESSAGES/strings.mo | Bin 351502 -> 351502 bytes locale/en/LC_MESSAGES/strings.po | 1104 ++- locale/es/LC_MESSAGES/strings.mo | Bin 369755 -> 384105 bytes locale/es/LC_MESSAGES/strings.po | 10540 ++++++++++++++++------------- locale/fr/LC_MESSAGES/strings.mo | Bin 372669 -> 387115 bytes locale/fr/LC_MESSAGES/strings.po | 10523 +++++++++++++++------------- locale/ro/LC_MESSAGES/strings.mo | Bin 380061 -> 380061 bytes locale/ro/LC_MESSAGES/strings.po | 1060 +-- 9 files changed, 12851 insertions(+), 10377 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8403789e..c9ac9e74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ CHANGELOG for FlatCAM beta - ensured that on Graceful Exit (CTRL+ALT+X key combo) if using Progressive Plotting, the eventual residual plotted lines are deleted. This apply for Tool NCC and Tool Paint - fixed links in Attributions tab in Help -> About FlatCAM to be able to open external links. +- updated Google Translations for French and Spanish languages 24.04.2020 diff --git a/locale/en/LC_MESSAGES/strings.mo b/locale/en/LC_MESSAGES/strings.mo index f56c057cf1268cb5b424095692d226836f30b290..7d01d57846df6e2305632697510ad1d1374faaa0 100644 GIT binary patch delta 37 rcmeC%CEB-3w4sHug=q_Op+38*f}x3(sbzbGJ~I%rY_HH~ou&%_>n#h9 delta 37 rcmeC%CEB-3w4sHug=q_Op+38bf{~$>p+S3vJ~I%rY_HH~ou&%_>Mjd^ diff --git a/locale/en/LC_MESSAGES/strings.po b/locale/en/LC_MESSAGES/strings.po index 63d41f2d..782a66c3 100644 --- a/locale/en/LC_MESSAGES/strings.po +++ b/locale/en/LC_MESSAGES/strings.po @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2020-04-24 21:10+0300\n" -"PO-Revision-Date: 2020-04-24 21:10+0300\n" +"POT-Creation-Date: 2020-04-25 14:59+0300\n" +"PO-Revision-Date: 2020-04-25 14:59+0300\n" "Last-Translator: \n" "Language-Team: \n" "Language: en\n" @@ -22,43 +22,43 @@ msgstr "" "X-Poedit-SearchPathExcluded-1: doc\n" "X-Poedit-SearchPathExcluded-2: tests\n" -#: FlatCAMApp.py:784 FlatCAMApp.py:816 FlatCAMCommon.py:1925 +#: FlatCAMApp.py:789 FlatCAMApp.py:821 FlatCAMCommon.py:1925 #: FlatCAMCommon.py:2040 flatcamEditors/FlatCAMGeoEditor.py:500 #: flatcamEditors/FlatCAMGeoEditor.py:570 #: flatcamEditors/FlatCAMGeoEditor.py:5152 flatcamGUI/PreferencesUI.py:5509 #: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 -#: flatcamTools/ToolNCC.py:2401 flatcamTools/ToolNCC.py:2429 -#: flatcamTools/ToolNCC.py:2699 flatcamTools/ToolNCC.py:2731 -#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:1836 +#: flatcamTools/ToolNCC.py:2396 flatcamTools/ToolNCC.py:2424 +#: flatcamTools/ToolNCC.py:2694 flatcamTools/ToolNCC.py:2726 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:1843 #: tclCommands/TclCommandCopperClear.py:128 #: tclCommands/TclCommandCopperClear.py:136 tclCommands/TclCommandPaint.py:127 msgid "Seed" msgstr "Seed" -#: FlatCAMApp.py:790 flatcamGUI/PreferencesUI.py:5588 +#: FlatCAMApp.py:795 flatcamGUI/PreferencesUI.py:5588 #: flatcamGUI/PreferencesUI.py:7695 flatcamTools/ToolCopperThieving.py:126 -#: flatcamTools/ToolNCC.py:535 flatcamTools/ToolNCC.py:1299 -#: flatcamTools/ToolNCC.py:1638 flatcamTools/ToolNCC.py:1919 -#: flatcamTools/ToolNCC.py:1983 flatcamTools/ToolNCC.py:2967 -#: flatcamTools/ToolNCC.py:2976 tclCommands/TclCommandCopperClear.py:190 +#: flatcamTools/ToolNCC.py:535 flatcamTools/ToolNCC.py:1301 +#: flatcamTools/ToolNCC.py:1629 flatcamTools/ToolNCC.py:1914 +#: flatcamTools/ToolNCC.py:1978 flatcamTools/ToolNCC.py:2962 +#: flatcamTools/ToolNCC.py:2971 tclCommands/TclCommandCopperClear.py:190 msgid "Itself" msgstr "Itself" -#: FlatCAMApp.py:817 flatcamGUI/PreferencesUI.py:6119 -#: flatcamTools/ToolPaint.py:486 flatcamTools/ToolPaint.py:1415 +#: FlatCAMApp.py:822 flatcamGUI/PreferencesUI.py:6119 +#: flatcamTools/ToolPaint.py:486 flatcamTools/ToolPaint.py:1422 #: tclCommands/TclCommandPaint.py:162 msgid "All Polygons" msgstr "All Polygons" -#: FlatCAMApp.py:1124 +#: FlatCAMApp.py:1129 msgid "FlatCAM is initializing ..." msgstr "FlatCAM is initializing ..." -#: FlatCAMApp.py:1809 +#: FlatCAMApp.py:1814 msgid "Could not find the Language files. The App strings are missing." msgstr "Could not find the Language files. The App strings are missing." -#: FlatCAMApp.py:1903 +#: FlatCAMApp.py:1908 msgid "" "FlatCAM is initializing ...\n" "Canvas initialization started." @@ -66,7 +66,7 @@ msgstr "" "FlatCAM is initializing ...\n" "Canvas initialization started." -#: FlatCAMApp.py:1923 +#: FlatCAMApp.py:1928 msgid "" "FlatCAM is initializing ...\n" "Canvas initialization started.\n" @@ -76,28 +76,28 @@ msgstr "" "Canvas initialization started.\n" "Canvas initialization finished in" -#: FlatCAMApp.py:2565 flatcamGUI/GUIElements.py:2592 +#: FlatCAMApp.py:2570 flatcamGUI/GUIElements.py:2592 msgid "Type >help< to get started" msgstr "Type >help< to get started" -#: FlatCAMApp.py:2817 FlatCAMApp.py:9393 +#: FlatCAMApp.py:2822 FlatCAMApp.py:9400 msgid "New Project - Not saved" msgstr "New Project - Not saved" -#: FlatCAMApp.py:2913 +#: FlatCAMApp.py:2918 msgid "" "Found old default preferences files. Please reboot the application to update." msgstr "" "Found old default preferences files. Please reboot the application to update." -#: FlatCAMApp.py:2964 FlatCAMApp.py:3884 FlatCAMApp.py:3933 FlatCAMApp.py:3988 -#: FlatCAMApp.py:4063 FlatCAMApp.py:6111 FlatCAMApp.py:9477 FlatCAMApp.py:9514 -#: FlatCAMApp.py:9556 FlatCAMApp.py:9585 FlatCAMApp.py:9625 FlatCAMApp.py:9650 -#: FlatCAMApp.py:9702 FlatCAMApp.py:9738 FlatCAMApp.py:9784 FlatCAMApp.py:9825 -#: FlatCAMApp.py:9866 FlatCAMApp.py:9907 FlatCAMApp.py:9948 FlatCAMApp.py:9992 -#: FlatCAMApp.py:10048 FlatCAMApp.py:10080 FlatCAMApp.py:10112 -#: FlatCAMApp.py:10349 FlatCAMApp.py:10393 FlatCAMApp.py:10470 -#: FlatCAMApp.py:10525 FlatCAMCommon.py:371 FlatCAMCommon.py:413 +#: FlatCAMApp.py:2969 FlatCAMApp.py:3889 FlatCAMApp.py:3938 FlatCAMApp.py:3993 +#: FlatCAMApp.py:4068 FlatCAMApp.py:6117 FlatCAMApp.py:9484 FlatCAMApp.py:9521 +#: FlatCAMApp.py:9563 FlatCAMApp.py:9592 FlatCAMApp.py:9632 FlatCAMApp.py:9657 +#: FlatCAMApp.py:9709 FlatCAMApp.py:9745 FlatCAMApp.py:9791 FlatCAMApp.py:9832 +#: FlatCAMApp.py:9873 FlatCAMApp.py:9914 FlatCAMApp.py:9955 FlatCAMApp.py:9999 +#: FlatCAMApp.py:10055 FlatCAMApp.py:10087 FlatCAMApp.py:10119 +#: FlatCAMApp.py:10356 FlatCAMApp.py:10400 FlatCAMApp.py:10477 +#: FlatCAMApp.py:10532 FlatCAMCommon.py:371 FlatCAMCommon.py:413 #: FlatCAMCommon.py:1107 FlatCAMCommon.py:1153 FlatCAMCommon.py:2537 #: FlatCAMCommon.py:2583 ObjectCollection.py:122 #: flatcamEditors/FlatCAMExcEditor.py:1024 @@ -111,31 +111,31 @@ msgstr "" msgid "Cancelled." msgstr "Cancelled." -#: FlatCAMApp.py:2980 +#: FlatCAMApp.py:2985 msgid "Open Config file failed." msgstr "Open Config file failed." -#: FlatCAMApp.py:2995 +#: FlatCAMApp.py:3000 msgid "Open Script file failed." msgstr "Open Script file failed." -#: FlatCAMApp.py:3021 +#: FlatCAMApp.py:3026 msgid "Open Excellon file failed." msgstr "Open Excellon file failed." -#: FlatCAMApp.py:3034 +#: FlatCAMApp.py:3039 msgid "Open GCode file failed." msgstr "Open GCode file failed." -#: FlatCAMApp.py:3047 +#: FlatCAMApp.py:3052 msgid "Open Gerber file failed." msgstr "Open Gerber file failed." -#: FlatCAMApp.py:3424 +#: FlatCAMApp.py:3429 msgid "Select a Geometry, Gerber or Excellon Object to edit." msgstr "Select a Geometry, Gerber or Excellon Object to edit." -#: FlatCAMApp.py:3439 +#: FlatCAMApp.py:3444 msgid "" "Simultaneous editing of tools geometry in a MultiGeo Geometry is not " "possible.\n" @@ -145,92 +145,92 @@ msgstr "" "possible.\n" "Edit only one geometry at a time." -#: FlatCAMApp.py:3497 +#: FlatCAMApp.py:3502 msgid "Editor is activated ..." msgstr "Editor is activated ..." -#: FlatCAMApp.py:3518 +#: FlatCAMApp.py:3523 msgid "Do you want to save the edited object?" msgstr "Do you want to save the edited object?" -#: FlatCAMApp.py:3519 flatcamGUI/FlatCAMGUI.py:2273 +#: FlatCAMApp.py:3524 flatcamGUI/FlatCAMGUI.py:2273 msgid "Close Editor" msgstr "Close Editor" -#: FlatCAMApp.py:3522 FlatCAMApp.py:5163 FlatCAMApp.py:8023 FlatCAMApp.py:8049 -#: FlatCAMApp.py:9298 FlatCAMTranslation.py:108 FlatCAMTranslation.py:199 +#: FlatCAMApp.py:3527 FlatCAMApp.py:5169 FlatCAMApp.py:8030 FlatCAMApp.py:8056 +#: FlatCAMApp.py:9305 FlatCAMTranslation.py:108 FlatCAMTranslation.py:199 #: flatcamGUI/FlatCAMGUI.py:2479 msgid "Yes" msgstr "Yes" -#: FlatCAMApp.py:3523 FlatCAMApp.py:5164 FlatCAMApp.py:8024 FlatCAMApp.py:8050 -#: FlatCAMApp.py:9299 FlatCAMTranslation.py:109 FlatCAMTranslation.py:200 +#: FlatCAMApp.py:3528 FlatCAMApp.py:5170 FlatCAMApp.py:8031 FlatCAMApp.py:8057 +#: FlatCAMApp.py:9306 FlatCAMTranslation.py:109 FlatCAMTranslation.py:200 #: flatcamGUI/FlatCAMGUI.py:2480 flatcamGUI/PreferencesUI.py:5443 #: flatcamGUI/PreferencesUI.py:5989 flatcamTools/ToolNCC.py:182 #: flatcamTools/ToolPaint.py:166 msgid "No" msgstr "No" -#: FlatCAMApp.py:3524 FlatCAMApp.py:5165 FlatCAMApp.py:6049 FlatCAMApp.py:7000 -#: FlatCAMApp.py:9300 FlatCAMCommon.py:572 FlatCAMCommon.py:2127 +#: FlatCAMApp.py:3529 FlatCAMApp.py:5171 FlatCAMApp.py:6055 FlatCAMApp.py:7006 +#: FlatCAMApp.py:9307 FlatCAMCommon.py:572 FlatCAMCommon.py:2127 #: flatcamGUI/FlatCAMGUI.py:1332 msgid "Cancel" msgstr "Cancel" -#: FlatCAMApp.py:3556 +#: FlatCAMApp.py:3561 msgid "Object empty after edit." msgstr "Object empty after edit." -#: FlatCAMApp.py:3560 FlatCAMApp.py:3581 FlatCAMApp.py:3603 +#: FlatCAMApp.py:3565 FlatCAMApp.py:3586 FlatCAMApp.py:3608 msgid "Editor exited. Editor content saved." msgstr "Editor exited. Editor content saved." -#: FlatCAMApp.py:3607 FlatCAMApp.py:3630 FlatCAMApp.py:3648 +#: FlatCAMApp.py:3612 FlatCAMApp.py:3635 FlatCAMApp.py:3653 msgid "Select a Gerber, Geometry or Excellon Object to update." msgstr "Select a Gerber, Geometry or Excellon Object to update." -#: FlatCAMApp.py:3610 +#: FlatCAMApp.py:3615 msgid "is updated, returning to App..." msgstr "is updated, returning to App..." -#: FlatCAMApp.py:3617 +#: FlatCAMApp.py:3622 msgid "Editor exited. Editor content was not saved." msgstr "Editor exited. Editor content was not saved." -#: FlatCAMApp.py:3810 FlatCAMApp.py:3941 FlatCAMApp.py:5012 +#: FlatCAMApp.py:3815 FlatCAMApp.py:3946 FlatCAMApp.py:5018 msgid "Could not load defaults file." msgstr "Could not load defaults file." -#: FlatCAMApp.py:3822 FlatCAMApp.py:3949 FlatCAMApp.py:5021 +#: FlatCAMApp.py:3827 FlatCAMApp.py:3954 FlatCAMApp.py:5027 msgid "Failed to parse defaults file." msgstr "Failed to parse defaults file." -#: FlatCAMApp.py:3892 FlatCAMApp.py:5113 +#: FlatCAMApp.py:3897 FlatCAMApp.py:5119 msgid "Could not load factory defaults file." msgstr "Could not load factory defaults file." -#: FlatCAMApp.py:3900 FlatCAMApp.py:5123 +#: FlatCAMApp.py:3905 FlatCAMApp.py:5129 msgid "Failed to parse factory defaults file." msgstr "Failed to parse factory defaults file." -#: FlatCAMApp.py:3908 +#: FlatCAMApp.py:3913 msgid "Preferences default values are restored." msgstr "Preferences default values are restored." -#: FlatCAMApp.py:3923 FlatCAMApp.py:3927 +#: FlatCAMApp.py:3928 FlatCAMApp.py:3932 msgid "Import FlatCAM Preferences" msgstr "Import FlatCAM Preferences" -#: FlatCAMApp.py:3957 +#: FlatCAMApp.py:3962 msgid "Imported Defaults from" msgstr "Imported Defaults from" -#: FlatCAMApp.py:3977 FlatCAMApp.py:3982 +#: FlatCAMApp.py:3982 FlatCAMApp.py:3987 msgid "Export FlatCAM Preferences" msgstr "Export FlatCAM Preferences" -#: FlatCAMApp.py:3997 FlatCAMApp.py:4071 FlatCAMApp.py:10769 -#: FlatCAMApp.py:10817 FlatCAMApp.py:10943 FlatCAMApp.py:11080 +#: FlatCAMApp.py:4002 FlatCAMApp.py:4076 FlatCAMApp.py:10776 +#: FlatCAMApp.py:10824 FlatCAMApp.py:10950 FlatCAMApp.py:11087 #: FlatCAMCommon.py:379 FlatCAMCommon.py:1115 FlatCAMCommon.py:2545 #: FlatCAMObj.py:7484 flatcamEditors/FlatCAMTextEditor.py:276 #: flatcamTools/ToolFilm.py:1031 flatcamTools/ToolFilm.py:1212 @@ -242,45 +242,45 @@ msgstr "" "Permission denied, saving not possible.\n" "Most likely another app is holding the file open and not accessible." -#: FlatCAMApp.py:4009 +#: FlatCAMApp.py:4014 msgid "Could not load preferences file." msgstr "Could not load preferences file." -#: FlatCAMApp.py:4028 FlatCAMApp.py:4095 FlatCAMApp.py:5040 +#: FlatCAMApp.py:4033 FlatCAMApp.py:4100 FlatCAMApp.py:5046 msgid "Failed to write defaults to file." msgstr "Failed to write defaults to file." -#: FlatCAMApp.py:4033 +#: FlatCAMApp.py:4038 msgid "Exported preferences to" msgstr "Exported preferences to" -#: FlatCAMApp.py:4053 FlatCAMApp.py:4058 +#: FlatCAMApp.py:4058 FlatCAMApp.py:4063 msgid "Save to file" msgstr "Save to file" -#: FlatCAMApp.py:4082 +#: FlatCAMApp.py:4087 msgid "Could not load the file." msgstr "Could not load the file." -#: FlatCAMApp.py:4098 +#: FlatCAMApp.py:4103 msgid "Exported file to" msgstr "Exported file to" -#: FlatCAMApp.py:4181 +#: FlatCAMApp.py:4186 msgid "Failed to open recent files file for writing." msgstr "Failed to open recent files file for writing." -#: FlatCAMApp.py:4192 +#: FlatCAMApp.py:4197 msgid "Failed to open recent projects file for writing." msgstr "Failed to open recent projects file for writing." -#: FlatCAMApp.py:4277 FlatCAMApp.py:11276 FlatCAMApp.py:11335 -#: FlatCAMApp.py:11463 FlatCAMApp.py:12189 FlatCAMObj.py:5605 +#: FlatCAMApp.py:4282 FlatCAMApp.py:11283 FlatCAMApp.py:11342 +#: FlatCAMApp.py:11470 FlatCAMApp.py:12196 FlatCAMObj.py:5605 #: flatcamEditors/FlatCAMGrbEditor.py:4231 flatcamTools/ToolPcbWizard.py:433 msgid "An internal error has occurred. See shell.\n" msgstr "An internal error has occurred. See shell.\n" -#: FlatCAMApp.py:4278 +#: FlatCAMApp.py:4283 #, python-brace-format msgid "" "Object ({kind}) failed because: {error} \n" @@ -289,63 +289,63 @@ msgstr "" "Object ({kind}) failed because: {error} \n" "\n" -#: FlatCAMApp.py:4293 +#: FlatCAMApp.py:4298 msgid "Converting units to " msgstr "Converting units to " -#: FlatCAMApp.py:4406 +#: FlatCAMApp.py:4411 msgid "CREATE A NEW FLATCAM TCL SCRIPT" msgstr "CREATE A NEW FLATCAM TCL SCRIPT" -#: FlatCAMApp.py:4407 +#: FlatCAMApp.py:4412 msgid "TCL Tutorial is here" msgstr "TCL Tutorial is here" -#: FlatCAMApp.py:4409 +#: FlatCAMApp.py:4414 msgid "FlatCAM commands list" msgstr "FlatCAM commands list" -#: FlatCAMApp.py:4460 FlatCAMApp.py:4466 FlatCAMApp.py:4472 FlatCAMApp.py:4478 -#: FlatCAMApp.py:4484 FlatCAMApp.py:4490 +#: FlatCAMApp.py:4465 FlatCAMApp.py:4471 FlatCAMApp.py:4477 FlatCAMApp.py:4483 +#: FlatCAMApp.py:4489 FlatCAMApp.py:4495 msgid "created/selected" msgstr "created/selected" -#: FlatCAMApp.py:4505 FlatCAMApp.py:7086 FlatCAMObj.py:278 FlatCAMObj.py:309 +#: FlatCAMApp.py:4510 FlatCAMApp.py:7092 FlatCAMObj.py:278 FlatCAMObj.py:309 #: FlatCAMObj.py:325 FlatCAMObj.py:405 flatcamTools/ToolCopperThieving.py:1482 #: flatcamTools/ToolFiducials.py:809 flatcamTools/ToolMove.py:230 #: flatcamTools/ToolQRCode.py:728 msgid "Plotting" msgstr "Plotting" -#: FlatCAMApp.py:4568 flatcamGUI/FlatCAMGUI.py:530 +#: FlatCAMApp.py:4573 flatcamGUI/FlatCAMGUI.py:530 msgid "About FlatCAM" msgstr "About FlatCAM" -#: FlatCAMApp.py:4594 +#: FlatCAMApp.py:4599 msgid "2D Computer-Aided Printed Circuit Board Manufacturing" msgstr "2D Computer-Aided Printed Circuit Board Manufacturing" -#: FlatCAMApp.py:4595 +#: FlatCAMApp.py:4600 msgid "Development" msgstr "Development" -#: FlatCAMApp.py:4596 +#: FlatCAMApp.py:4601 msgid "DOWNLOAD" msgstr "DOWNLOAD" -#: FlatCAMApp.py:4597 +#: FlatCAMApp.py:4602 msgid "Issue tracker" msgstr "Issue tracker" -#: FlatCAMApp.py:4601 FlatCAMApp.py:4942 flatcamGUI/GUIElements.py:2583 +#: FlatCAMApp.py:4606 FlatCAMApp.py:4948 flatcamGUI/GUIElements.py:2583 msgid "Close" msgstr "Close" -#: FlatCAMApp.py:4616 +#: FlatCAMApp.py:4621 msgid "Licensed under the MIT license" msgstr "Licensed under the MIT license" -#: FlatCAMApp.py:4625 +#: FlatCAMApp.py:4630 msgid "" "Permission is hereby granted, free of charge, to any person obtaining a " "copy\n" @@ -393,7 +393,7 @@ msgstr "" "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n" "THE SOFTWARE." -#: FlatCAMApp.py:4647 +#: FlatCAMApp.py:4652 msgid "" "Some of the icons used are from the following sources:
Icons by FreepikIcons8
Icons by oNline Web Fonts" -#: FlatCAMApp.py:4679 +#: FlatCAMApp.py:4685 msgid "Splash" msgstr "Splash" -#: FlatCAMApp.py:4685 +#: FlatCAMApp.py:4691 msgid "Programmers" msgstr "Programmers" -#: FlatCAMApp.py:4691 +#: FlatCAMApp.py:4697 msgid "Translators" msgstr "Translators" -#: FlatCAMApp.py:4697 +#: FlatCAMApp.py:4703 msgid "License" msgstr "License" -#: FlatCAMApp.py:4703 +#: FlatCAMApp.py:4709 msgid "Attributions" msgstr "Attributions" -#: FlatCAMApp.py:4726 +#: FlatCAMApp.py:4732 msgid "Programmer" msgstr "Programmer" -#: FlatCAMApp.py:4727 +#: FlatCAMApp.py:4733 msgid "Status" msgstr "Status" -#: FlatCAMApp.py:4728 FlatCAMApp.py:4806 +#: FlatCAMApp.py:4734 FlatCAMApp.py:4812 msgid "E-mail" msgstr "E-mail" -#: FlatCAMApp.py:4736 +#: FlatCAMApp.py:4742 msgid "BETA Maintainer >= 2019" msgstr "BETA Maintainer >= 2019" -#: FlatCAMApp.py:4803 +#: FlatCAMApp.py:4809 msgid "Language" msgstr "Language" -#: FlatCAMApp.py:4804 +#: FlatCAMApp.py:4810 msgid "Translator" msgstr "Translator" -#: FlatCAMApp.py:4805 +#: FlatCAMApp.py:4811 msgid "Corrections" msgstr "Corrections" -#: FlatCAMApp.py:4914 FlatCAMApp.py:4922 FlatCAMApp.py:8068 +#: FlatCAMApp.py:4920 FlatCAMApp.py:4928 FlatCAMApp.py:8075 #: flatcamGUI/FlatCAMGUI.py:512 msgid "Bookmarks Manager" msgstr "Bookmarks Manager" -#: FlatCAMApp.py:4933 +#: FlatCAMApp.py:4939 msgid "" "This entry will resolve to another website if:\n" "\n" @@ -482,27 +482,27 @@ msgstr "" "If you can't get any informations about FlatCAM beta\n" "use the YouTube channel link from the Help menu." -#: FlatCAMApp.py:4940 +#: FlatCAMApp.py:4946 msgid "Alternative website" msgstr "Alternative website" -#: FlatCAMApp.py:5044 FlatCAMApp.py:8032 +#: FlatCAMApp.py:5050 FlatCAMApp.py:8039 msgid "Preferences saved." msgstr "Preferences saved." -#: FlatCAMApp.py:5139 +#: FlatCAMApp.py:5145 msgid "Failed to write factory defaults to file." msgstr "Failed to write factory defaults to file." -#: FlatCAMApp.py:5143 +#: FlatCAMApp.py:5149 msgid "Factory defaults saved." msgstr "Factory defaults saved." -#: FlatCAMApp.py:5153 flatcamGUI/FlatCAMGUI.py:4178 +#: FlatCAMApp.py:5159 flatcamGUI/FlatCAMGUI.py:4178 msgid "Application is saving the project. Please wait ..." msgstr "Application is saving the project. Please wait ..." -#: FlatCAMApp.py:5158 FlatCAMTranslation.py:194 +#: FlatCAMApp.py:5164 FlatCAMTranslation.py:194 msgid "" "There are files/objects modified in FlatCAM. \n" "Do you want to Save the project?" @@ -510,27 +510,27 @@ msgstr "" "There are files/objects modified in FlatCAM. \n" "Do you want to Save the project?" -#: FlatCAMApp.py:5161 FlatCAMApp.py:9296 FlatCAMTranslation.py:197 +#: FlatCAMApp.py:5167 FlatCAMApp.py:9303 FlatCAMTranslation.py:197 msgid "Save changes" msgstr "Save changes" -#: FlatCAMApp.py:5417 +#: FlatCAMApp.py:5423 msgid "Selected Excellon file extensions registered with FlatCAM." msgstr "Selected Excellon file extensions registered with FlatCAM." -#: FlatCAMApp.py:5439 +#: FlatCAMApp.py:5445 msgid "Selected GCode file extensions registered with FlatCAM." msgstr "Selected GCode file extensions registered with FlatCAM." -#: FlatCAMApp.py:5461 +#: FlatCAMApp.py:5467 msgid "Selected Gerber file extensions registered with FlatCAM." msgstr "Selected Gerber file extensions registered with FlatCAM." -#: FlatCAMApp.py:5649 FlatCAMApp.py:5708 FlatCAMApp.py:5736 +#: FlatCAMApp.py:5655 FlatCAMApp.py:5714 FlatCAMApp.py:5742 msgid "At least two objects are required for join. Objects currently selected" msgstr "At least two objects are required for join. Objects currently selected" -#: FlatCAMApp.py:5658 +#: FlatCAMApp.py:5664 msgid "" "Failed join. The Geometry objects are of different types.\n" "At least one is MultiGeo type and the other is SingleGeo type. A possibility " @@ -546,47 +546,47 @@ msgstr "" "be lost and the result may not be what was expected. \n" "Check the generated GCODE." -#: FlatCAMApp.py:5670 FlatCAMApp.py:5680 +#: FlatCAMApp.py:5676 FlatCAMApp.py:5686 msgid "Geometry merging finished" msgstr "Geometry merging finished" -#: FlatCAMApp.py:5703 +#: FlatCAMApp.py:5709 msgid "Failed. Excellon joining works only on Excellon objects." msgstr "Failed. Excellon joining works only on Excellon objects." -#: FlatCAMApp.py:5713 +#: FlatCAMApp.py:5719 msgid "Excellon merging finished" msgstr "Excellon merging finished" -#: FlatCAMApp.py:5731 +#: FlatCAMApp.py:5737 msgid "Failed. Gerber joining works only on Gerber objects." msgstr "Failed. Gerber joining works only on Gerber objects." -#: FlatCAMApp.py:5741 +#: FlatCAMApp.py:5747 msgid "Gerber merging finished" msgstr "Gerber merging finished" -#: FlatCAMApp.py:5761 FlatCAMApp.py:5796 +#: FlatCAMApp.py:5767 FlatCAMApp.py:5802 msgid "Failed. Select a Geometry Object and try again." msgstr "Failed. Select a Geometry Object and try again." -#: FlatCAMApp.py:5765 FlatCAMApp.py:5801 +#: FlatCAMApp.py:5771 FlatCAMApp.py:5807 msgid "Expected a FlatCAMGeometry, got" msgstr "Expected a FlatCAMGeometry, got" -#: FlatCAMApp.py:5778 +#: FlatCAMApp.py:5784 msgid "A Geometry object was converted to MultiGeo type." msgstr "A Geometry object was converted to MultiGeo type." -#: FlatCAMApp.py:5816 +#: FlatCAMApp.py:5822 msgid "A Geometry object was converted to SingleGeo type." msgstr "A Geometry object was converted to SingleGeo type." -#: FlatCAMApp.py:6043 +#: FlatCAMApp.py:6049 msgid "Toggle Units" msgstr "Toggle Units" -#: FlatCAMApp.py:6045 +#: FlatCAMApp.py:6051 msgid "" "Changing the units of the project\n" "will scale all objects.\n" @@ -598,44 +598,44 @@ msgstr "" "\n" "Do you want to continue?" -#: FlatCAMApp.py:6048 FlatCAMApp.py:6922 FlatCAMApp.py:6999 FlatCAMApp.py:9669 -#: FlatCAMApp.py:9683 FlatCAMApp.py:10018 FlatCAMApp.py:10028 +#: FlatCAMApp.py:6054 FlatCAMApp.py:6928 FlatCAMApp.py:7005 FlatCAMApp.py:9676 +#: FlatCAMApp.py:9690 FlatCAMApp.py:10025 FlatCAMApp.py:10035 msgid "Ok" msgstr "Ok" -#: FlatCAMApp.py:6097 +#: FlatCAMApp.py:6103 msgid "Converted units to" msgstr "Converted units to" -#: FlatCAMApp.py:6737 +#: FlatCAMApp.py:6743 msgid "Detachable Tabs" msgstr "Detachable Tabs" -#: FlatCAMApp.py:6811 FlatCAMApp.py:6855 FlatCAMApp.py:6883 FlatCAMApp.py:7815 -#: FlatCAMApp.py:7883 FlatCAMApp.py:7987 +#: FlatCAMApp.py:6817 FlatCAMApp.py:6861 FlatCAMApp.py:6889 FlatCAMApp.py:7822 +#: FlatCAMApp.py:7890 FlatCAMApp.py:7994 msgid "Preferences" msgstr "Preferences" -#: FlatCAMApp.py:6817 +#: FlatCAMApp.py:6823 msgid "Preferences applied." msgstr "Preferences applied." -#: FlatCAMApp.py:6888 +#: FlatCAMApp.py:6894 msgid "Preferences closed without saving." msgstr "Preferences closed without saving." -#: FlatCAMApp.py:6911 flatcamTools/ToolNCC.py:930 flatcamTools/ToolNCC.py:1435 -#: flatcamTools/ToolPaint.py:855 flatcamTools/ToolSolderPaste.py:568 +#: FlatCAMApp.py:6917 flatcamTools/ToolNCC.py:932 flatcamTools/ToolNCC.py:1426 +#: flatcamTools/ToolPaint.py:858 flatcamTools/ToolSolderPaste.py:568 #: flatcamTools/ToolSolderPaste.py:893 msgid "Please enter a tool diameter with non-zero value, in Float format." msgstr "Please enter a tool diameter with non-zero value, in Float format." -#: FlatCAMApp.py:6915 flatcamTools/ToolNCC.py:934 flatcamTools/ToolPaint.py:859 +#: FlatCAMApp.py:6921 flatcamTools/ToolNCC.py:936 flatcamTools/ToolPaint.py:862 #: flatcamTools/ToolSolderPaste.py:572 msgid "Adding Tool cancelled" msgstr "Adding Tool cancelled" -#: FlatCAMApp.py:6918 +#: FlatCAMApp.py:6924 msgid "" "Adding Tool works only when Advanced is checked.\n" "Go to Preferences -> General - Show Advanced Options." @@ -643,11 +643,11 @@ msgstr "" "Adding Tool works only when Advanced is checked.\n" "Go to Preferences -> General - Show Advanced Options." -#: FlatCAMApp.py:6994 +#: FlatCAMApp.py:7000 msgid "Delete objects" msgstr "Delete objects" -#: FlatCAMApp.py:6997 +#: FlatCAMApp.py:7003 msgid "" "Are you sure you want to permanently delete\n" "the selected objects?" @@ -655,55 +655,55 @@ msgstr "" "Are you sure you want to permanently delete\n" "the selected objects?" -#: FlatCAMApp.py:7035 +#: FlatCAMApp.py:7041 msgid "Object(s) deleted" msgstr "Object(s) deleted" -#: FlatCAMApp.py:7039 FlatCAMApp.py:7194 flatcamTools/ToolDblSided.py:819 +#: FlatCAMApp.py:7045 FlatCAMApp.py:7200 flatcamTools/ToolDblSided.py:819 msgid "Failed. No object(s) selected..." msgstr "Failed. No object(s) selected..." -#: FlatCAMApp.py:7041 +#: FlatCAMApp.py:7047 msgid "Save the work in Editor and try again ..." msgstr "Save the work in Editor and try again ..." -#: FlatCAMApp.py:7070 +#: FlatCAMApp.py:7076 msgid "Object deleted" msgstr "Object deleted" -#: FlatCAMApp.py:7097 +#: FlatCAMApp.py:7103 msgid "Click to set the origin ..." msgstr "Click to set the origin ..." -#: FlatCAMApp.py:7119 +#: FlatCAMApp.py:7125 msgid "Setting Origin..." msgstr "Setting Origin..." -#: FlatCAMApp.py:7132 FlatCAMApp.py:7234 +#: FlatCAMApp.py:7138 FlatCAMApp.py:7240 msgid "Origin set" msgstr "Origin set" -#: FlatCAMApp.py:7149 +#: FlatCAMApp.py:7155 msgid "Origin coordinates specified but incomplete." msgstr "Origin coordinates specified but incomplete." -#: FlatCAMApp.py:7190 +#: FlatCAMApp.py:7196 msgid "Moving to Origin..." msgstr "Moving to Origin..." -#: FlatCAMApp.py:7271 +#: FlatCAMApp.py:7277 msgid "Jump to ..." msgstr "Jump to ..." -#: FlatCAMApp.py:7272 +#: FlatCAMApp.py:7278 msgid "Enter the coordinates in format X,Y:" msgstr "Enter the coordinates in format X,Y:" -#: FlatCAMApp.py:7282 +#: FlatCAMApp.py:7288 msgid "Wrong coordinates. Enter coordinates in format: X,Y" msgstr "Wrong coordinates. Enter coordinates in format: X,Y" -#: FlatCAMApp.py:7360 FlatCAMApp.py:7509 +#: FlatCAMApp.py:7366 FlatCAMApp.py:7515 #: flatcamEditors/FlatCAMExcEditor.py:3622 #: flatcamEditors/FlatCAMExcEditor.py:3630 #: flatcamEditors/FlatCAMGeoEditor.py:4349 @@ -719,79 +719,79 @@ msgstr "Wrong coordinates. Enter coordinates in format: X,Y" msgid "Done." msgstr "Done." -#: FlatCAMApp.py:7375 FlatCAMApp.py:9665 FlatCAMApp.py:9761 FlatCAMApp.py:9803 -#: FlatCAMApp.py:9844 FlatCAMApp.py:9885 FlatCAMApp.py:9926 FlatCAMApp.py:9970 -#: FlatCAMApp.py:10014 FlatCAMApp.py:10503 FlatCAMApp.py:10507 +#: FlatCAMApp.py:7381 FlatCAMApp.py:9672 FlatCAMApp.py:9768 FlatCAMApp.py:9810 +#: FlatCAMApp.py:9851 FlatCAMApp.py:9892 FlatCAMApp.py:9933 FlatCAMApp.py:9977 +#: FlatCAMApp.py:10021 FlatCAMApp.py:10510 FlatCAMApp.py:10514 #: flatcamTools/ToolProperties.py:116 msgid "No object selected." msgstr "No object selected." -#: FlatCAMApp.py:7394 +#: FlatCAMApp.py:7400 msgid "Bottom-Left" msgstr "Bottom-Left" -#: FlatCAMApp.py:7395 flatcamGUI/PreferencesUI.py:8111 +#: FlatCAMApp.py:7401 flatcamGUI/PreferencesUI.py:8111 #: flatcamTools/ToolCalibration.py:159 msgid "Top-Left" msgstr "Top-Left" -#: FlatCAMApp.py:7396 flatcamGUI/PreferencesUI.py:8112 +#: FlatCAMApp.py:7402 flatcamGUI/PreferencesUI.py:8112 #: flatcamTools/ToolCalibration.py:160 msgid "Bottom-Right" msgstr "Bottom-Right" -#: FlatCAMApp.py:7397 +#: FlatCAMApp.py:7403 msgid "Top-Right" msgstr "Top-Right" -#: FlatCAMApp.py:7398 flatcamGUI/ObjectUI.py:2624 +#: FlatCAMApp.py:7404 flatcamGUI/ObjectUI.py:2624 msgid "Center" msgstr "Center" -#: FlatCAMApp.py:7418 +#: FlatCAMApp.py:7424 msgid "Locate ..." msgstr "Locate ..." -#: FlatCAMApp.py:7679 FlatCAMApp.py:7756 +#: FlatCAMApp.py:7685 FlatCAMApp.py:7762 msgid "No object is selected. Select an object and try again." msgstr "No object is selected. Select an object and try again." -#: FlatCAMApp.py:7782 +#: FlatCAMApp.py:7788 msgid "" "Aborting. The current task will be gracefully closed as soon as possible..." msgstr "" "Aborting. The current task will be gracefully closed as soon as possible..." -#: FlatCAMApp.py:7787 +#: FlatCAMApp.py:7794 msgid "The current task was gracefully closed on user request..." msgstr "The current task was gracefully closed on user request..." -#: FlatCAMApp.py:7880 +#: FlatCAMApp.py:7887 msgid "Preferences edited but not saved." msgstr "Preferences edited but not saved." -#: FlatCAMApp.py:7897 FlatCAMApp.py:7925 FlatCAMApp.py:7952 FlatCAMApp.py:7971 -#: FlatCAMApp.py:8038 FlatCAMCommon.py:1182 FlatCAMCommon.py:1357 +#: FlatCAMApp.py:7904 FlatCAMApp.py:7932 FlatCAMApp.py:7959 FlatCAMApp.py:7978 +#: FlatCAMApp.py:8045 FlatCAMCommon.py:1182 FlatCAMCommon.py:1357 #: FlatCAMCommon.py:2612 FlatCAMCommon.py:2820 FlatCAMObj.py:4798 -#: flatcamTools/ToolNCC.py:3963 flatcamTools/ToolNCC.py:4047 -#: flatcamTools/ToolPaint.py:3537 flatcamTools/ToolPaint.py:3622 +#: flatcamTools/ToolNCC.py:3958 flatcamTools/ToolNCC.py:4042 +#: flatcamTools/ToolPaint.py:3548 flatcamTools/ToolPaint.py:3633 msgid "Tools Database" msgstr "Tools Database" -#: FlatCAMApp.py:7949 +#: FlatCAMApp.py:7956 msgid "Tools in Tools Database edited but not saved." msgstr "Tools in Tools Database edited but not saved." -#: FlatCAMApp.py:7975 flatcamTools/ToolNCC.py:3970 -#: flatcamTools/ToolPaint.py:3544 +#: FlatCAMApp.py:7982 flatcamTools/ToolNCC.py:3965 +#: flatcamTools/ToolPaint.py:3555 msgid "Tool from DB added in Tool Table." msgstr "Tool from DB added in Tool Table." -#: FlatCAMApp.py:7977 +#: FlatCAMApp.py:7984 msgid "Adding tool from DB is not allowed for this object." msgstr "Adding tool from DB is not allowed for this object." -#: FlatCAMApp.py:8018 +#: FlatCAMApp.py:8025 msgid "" "One or more values are changed.\n" "Do you want to save the Preferences?" @@ -799,11 +799,11 @@ msgstr "" "One or more values are changed.\n" "Do you want to save the Preferences?" -#: FlatCAMApp.py:8020 flatcamGUI/FlatCAMGUI.py:291 +#: FlatCAMApp.py:8027 flatcamGUI/FlatCAMGUI.py:291 msgid "Save Preferences" msgstr "Save Preferences" -#: FlatCAMApp.py:8044 +#: FlatCAMApp.py:8051 msgid "" "One or more Tools are edited.\n" "Do you want to update the Tools Database?" @@ -811,174 +811,174 @@ msgstr "" "One or more Tools are edited.\n" "Do you want to update the Tools Database?" -#: FlatCAMApp.py:8046 +#: FlatCAMApp.py:8053 msgid "Save Tools Database" msgstr "Save Tools Database" -#: FlatCAMApp.py:8065 FlatCAMApp.py:10252 FlatCAMObj.py:7089 +#: FlatCAMApp.py:8072 FlatCAMApp.py:10259 FlatCAMObj.py:7089 msgid "Code Editor" msgstr "Code Editor" -#: FlatCAMApp.py:8087 +#: FlatCAMApp.py:8094 msgid "No object selected to Flip on Y axis." msgstr "No object selected to Flip on Y axis." -#: FlatCAMApp.py:8113 +#: FlatCAMApp.py:8120 msgid "Flip on Y axis done." msgstr "Flip on Y axis done." -#: FlatCAMApp.py:8115 FlatCAMApp.py:8163 +#: FlatCAMApp.py:8122 FlatCAMApp.py:8170 #: flatcamEditors/FlatCAMGrbEditor.py:5893 msgid "Flip action was not executed." msgstr "Flip action was not executed." -#: FlatCAMApp.py:8135 +#: FlatCAMApp.py:8142 msgid "No object selected to Flip on X axis." msgstr "No object selected to Flip on X axis." -#: FlatCAMApp.py:8161 +#: FlatCAMApp.py:8168 msgid "Flip on X axis done." msgstr "Flip on X axis done." -#: FlatCAMApp.py:8183 +#: FlatCAMApp.py:8190 msgid "No object selected to Rotate." msgstr "No object selected to Rotate." -#: FlatCAMApp.py:8186 FlatCAMApp.py:8239 FlatCAMApp.py:8278 +#: FlatCAMApp.py:8193 FlatCAMApp.py:8246 FlatCAMApp.py:8285 msgid "Transform" msgstr "Transform" -#: FlatCAMApp.py:8186 FlatCAMApp.py:8239 FlatCAMApp.py:8278 +#: FlatCAMApp.py:8193 FlatCAMApp.py:8246 FlatCAMApp.py:8285 msgid "Enter the Angle value:" msgstr "Enter the Angle value:" -#: FlatCAMApp.py:8217 +#: FlatCAMApp.py:8224 msgid "Rotation done." msgstr "Rotation done." -#: FlatCAMApp.py:8219 +#: FlatCAMApp.py:8226 msgid "Rotation movement was not executed." msgstr "Rotation movement was not executed." -#: FlatCAMApp.py:8237 +#: FlatCAMApp.py:8244 msgid "No object selected to Skew/Shear on X axis." msgstr "No object selected to Skew/Shear on X axis." -#: FlatCAMApp.py:8259 +#: FlatCAMApp.py:8266 msgid "Skew on X axis done." msgstr "Skew on X axis done." -#: FlatCAMApp.py:8276 +#: FlatCAMApp.py:8283 msgid "No object selected to Skew/Shear on Y axis." msgstr "No object selected to Skew/Shear on Y axis." -#: FlatCAMApp.py:8298 +#: FlatCAMApp.py:8305 msgid "Skew on Y axis done." msgstr "Skew on Y axis done." -#: FlatCAMApp.py:8451 FlatCAMApp.py:8498 flatcamGUI/FlatCAMGUI.py:488 +#: FlatCAMApp.py:8458 FlatCAMApp.py:8505 flatcamGUI/FlatCAMGUI.py:488 #: flatcamGUI/FlatCAMGUI.py:1713 msgid "Select All" msgstr "Select All" -#: FlatCAMApp.py:8455 FlatCAMApp.py:8502 flatcamGUI/FlatCAMGUI.py:490 +#: FlatCAMApp.py:8462 FlatCAMApp.py:8509 flatcamGUI/FlatCAMGUI.py:490 msgid "Deselect All" msgstr "Deselect All" -#: FlatCAMApp.py:8518 +#: FlatCAMApp.py:8525 msgid "All objects are selected." msgstr "All objects are selected." -#: FlatCAMApp.py:8528 +#: FlatCAMApp.py:8535 msgid "Objects selection is cleared." msgstr "Objects selection is cleared." -#: FlatCAMApp.py:8548 flatcamGUI/FlatCAMGUI.py:1706 +#: FlatCAMApp.py:8555 flatcamGUI/FlatCAMGUI.py:1706 msgid "Grid On/Off" msgstr "Grid On/Off" -#: FlatCAMApp.py:8560 flatcamEditors/FlatCAMGeoEditor.py:940 +#: FlatCAMApp.py:8567 flatcamEditors/FlatCAMGeoEditor.py:940 #: flatcamEditors/FlatCAMGrbEditor.py:2580 #: flatcamEditors/FlatCAMGrbEditor.py:5475 flatcamGUI/ObjectUI.py:1593 #: flatcamTools/ToolDblSided.py:193 flatcamTools/ToolDblSided.py:426 #: flatcamTools/ToolNCC.py:294 flatcamTools/ToolNCC.py:631 -#: flatcamTools/ToolPaint.py:277 flatcamTools/ToolPaint.py:673 +#: flatcamTools/ToolPaint.py:277 flatcamTools/ToolPaint.py:676 #: flatcamTools/ToolSolderPaste.py:123 flatcamTools/ToolSolderPaste.py:597 #: flatcamTools/ToolTransform.py:479 msgid "Add" msgstr "Add" -#: FlatCAMApp.py:8562 FlatCAMObj.py:4416 +#: FlatCAMApp.py:8569 FlatCAMObj.py:4416 #: flatcamEditors/FlatCAMGrbEditor.py:2585 #: flatcamEditors/FlatCAMGrbEditor.py:2733 flatcamGUI/FlatCAMGUI.py:736 #: flatcamGUI/FlatCAMGUI.py:1059 flatcamGUI/FlatCAMGUI.py:2126 #: flatcamGUI/FlatCAMGUI.py:2269 flatcamGUI/FlatCAMGUI.py:2733 #: flatcamGUI/ObjectUI.py:1621 flatcamTools/ToolNCC.py:316 #: flatcamTools/ToolNCC.py:637 flatcamTools/ToolPaint.py:299 -#: flatcamTools/ToolPaint.py:679 flatcamTools/ToolSolderPaste.py:129 +#: flatcamTools/ToolPaint.py:682 flatcamTools/ToolSolderPaste.py:129 #: flatcamTools/ToolSolderPaste.py:600 msgid "Delete" msgstr "Delete" -#: FlatCAMApp.py:8575 +#: FlatCAMApp.py:8582 msgid "New Grid ..." msgstr "New Grid ..." -#: FlatCAMApp.py:8576 +#: FlatCAMApp.py:8583 msgid "Enter a Grid Value:" msgstr "Enter a Grid Value:" -#: FlatCAMApp.py:8584 FlatCAMApp.py:8611 +#: FlatCAMApp.py:8591 FlatCAMApp.py:8618 msgid "Please enter a grid value with non-zero value, in Float format." msgstr "Please enter a grid value with non-zero value, in Float format." -#: FlatCAMApp.py:8590 +#: FlatCAMApp.py:8597 msgid "New Grid added" msgstr "New Grid added" -#: FlatCAMApp.py:8593 +#: FlatCAMApp.py:8600 msgid "Grid already exists" msgstr "Grid already exists" -#: FlatCAMApp.py:8596 +#: FlatCAMApp.py:8603 msgid "Adding New Grid cancelled" msgstr "Adding New Grid cancelled" -#: FlatCAMApp.py:8618 +#: FlatCAMApp.py:8625 msgid " Grid Value does not exist" msgstr " Grid Value does not exist" -#: FlatCAMApp.py:8621 +#: FlatCAMApp.py:8628 msgid "Grid Value deleted" msgstr "Grid Value deleted" -#: FlatCAMApp.py:8624 +#: FlatCAMApp.py:8631 msgid "Delete Grid value cancelled" msgstr "Delete Grid value cancelled" -#: FlatCAMApp.py:8630 +#: FlatCAMApp.py:8637 msgid "Key Shortcut List" msgstr "Key Shortcut List" -#: FlatCAMApp.py:8664 +#: FlatCAMApp.py:8671 msgid " No object selected to copy it's name" msgstr " No object selected to copy it's name" -#: FlatCAMApp.py:8668 +#: FlatCAMApp.py:8675 msgid "Name copied on clipboard ..." msgstr "Name copied on clipboard ..." -#: FlatCAMApp.py:8881 flatcamEditors/FlatCAMGrbEditor.py:4421 +#: FlatCAMApp.py:8888 flatcamEditors/FlatCAMGrbEditor.py:4421 msgid "Coordinates copied to clipboard." msgstr "Coordinates copied to clipboard." -#: FlatCAMApp.py:9120 FlatCAMApp.py:9126 FlatCAMApp.py:9132 FlatCAMApp.py:9138 +#: FlatCAMApp.py:9127 FlatCAMApp.py:9133 FlatCAMApp.py:9139 FlatCAMApp.py:9145 #: ObjectCollection.py:911 ObjectCollection.py:917 ObjectCollection.py:923 #: ObjectCollection.py:929 ObjectCollection.py:935 ObjectCollection.py:941 msgid "selected" msgstr "selected" -#: FlatCAMApp.py:9293 +#: FlatCAMApp.py:9300 msgid "" "There are files/objects opened in FlatCAM.\n" "Creating a New project will delete them.\n" @@ -988,17 +988,17 @@ msgstr "" "Creating a New project will delete them.\n" "Do you want to Save the project?" -#: FlatCAMApp.py:9314 +#: FlatCAMApp.py:9321 msgid "New Project created" msgstr "New Project created" -#: FlatCAMApp.py:9461 FlatCAMApp.py:9465 flatcamGUI/FlatCAMGUI.py:821 +#: FlatCAMApp.py:9468 FlatCAMApp.py:9472 flatcamGUI/FlatCAMGUI.py:821 #: flatcamGUI/FlatCAMGUI.py:2504 msgid "Open Gerber" msgstr "Open Gerber" -#: FlatCAMApp.py:9470 FlatCAMApp.py:9507 FlatCAMApp.py:9549 FlatCAMApp.py:9618 -#: FlatCAMApp.py:10371 FlatCAMApp.py:11546 FlatCAMApp.py:11607 +#: FlatCAMApp.py:9477 FlatCAMApp.py:9514 FlatCAMApp.py:9556 FlatCAMApp.py:9625 +#: FlatCAMApp.py:10378 FlatCAMApp.py:11553 FlatCAMApp.py:11614 msgid "" "Canvas initialization started.\n" "Canvas initialization finished in" @@ -1006,248 +1006,248 @@ msgstr "" "Canvas initialization started.\n" "Canvas initialization finished in" -#: FlatCAMApp.py:9472 +#: FlatCAMApp.py:9479 msgid "Opening Gerber file." msgstr "Opening Gerber file." -#: FlatCAMApp.py:9499 FlatCAMApp.py:9503 flatcamGUI/FlatCAMGUI.py:823 +#: FlatCAMApp.py:9506 FlatCAMApp.py:9510 flatcamGUI/FlatCAMGUI.py:823 #: flatcamGUI/FlatCAMGUI.py:2506 msgid "Open Excellon" msgstr "Open Excellon" -#: FlatCAMApp.py:9509 +#: FlatCAMApp.py:9516 msgid "Opening Excellon file." msgstr "Opening Excellon file." -#: FlatCAMApp.py:9540 FlatCAMApp.py:9544 +#: FlatCAMApp.py:9547 FlatCAMApp.py:9551 msgid "Open G-Code" msgstr "Open G-Code" -#: FlatCAMApp.py:9551 +#: FlatCAMApp.py:9558 msgid "Opening G-Code file." msgstr "Opening G-Code file." -#: FlatCAMApp.py:9574 FlatCAMApp.py:9577 flatcamGUI/FlatCAMGUI.py:1715 +#: FlatCAMApp.py:9581 FlatCAMApp.py:9584 flatcamGUI/FlatCAMGUI.py:1715 msgid "Open Project" msgstr "Open Project" -#: FlatCAMApp.py:9609 FlatCAMApp.py:9613 +#: FlatCAMApp.py:9616 FlatCAMApp.py:9620 msgid "Open HPGL2" msgstr "Open HPGL2" -#: FlatCAMApp.py:9620 +#: FlatCAMApp.py:9627 msgid "Opening HPGL2 file." msgstr "Opening HPGL2 file." -#: FlatCAMApp.py:9643 FlatCAMApp.py:9646 +#: FlatCAMApp.py:9650 FlatCAMApp.py:9653 msgid "Open Configuration File" msgstr "Open Configuration File" -#: FlatCAMApp.py:9666 FlatCAMApp.py:10015 +#: FlatCAMApp.py:9673 FlatCAMApp.py:10022 msgid "Please Select a Geometry object to export" msgstr "Please Select a Geometry object to export" -#: FlatCAMApp.py:9680 +#: FlatCAMApp.py:9687 msgid "Only Geometry, Gerber and CNCJob objects can be used." msgstr "Only Geometry, Gerber and CNCJob objects can be used." -#: FlatCAMApp.py:9693 FlatCAMApp.py:9697 flatcamTools/ToolQRCode.py:829 +#: FlatCAMApp.py:9700 FlatCAMApp.py:9704 flatcamTools/ToolQRCode.py:829 #: flatcamTools/ToolQRCode.py:833 msgid "Export SVG" msgstr "Export SVG" -#: FlatCAMApp.py:9723 +#: FlatCAMApp.py:9730 msgid "Data must be a 3D array with last dimension 3 or 4" msgstr "Data must be a 3D array with last dimension 3 or 4" -#: FlatCAMApp.py:9729 FlatCAMApp.py:9733 +#: FlatCAMApp.py:9736 FlatCAMApp.py:9740 msgid "Export PNG Image" msgstr "Export PNG Image" -#: FlatCAMApp.py:9767 FlatCAMApp.py:9975 +#: FlatCAMApp.py:9774 FlatCAMApp.py:9982 msgid "Failed. Only Gerber objects can be saved as Gerber files..." msgstr "Failed. Only Gerber objects can be saved as Gerber files..." -#: FlatCAMApp.py:9779 +#: FlatCAMApp.py:9786 msgid "Save Gerber source file" msgstr "Save Gerber source file" -#: FlatCAMApp.py:9808 +#: FlatCAMApp.py:9815 msgid "Failed. Only Script objects can be saved as TCL Script files..." msgstr "Failed. Only Script objects can be saved as TCL Script files..." -#: FlatCAMApp.py:9820 +#: FlatCAMApp.py:9827 msgid "Save Script source file" msgstr "Save Script source file" -#: FlatCAMApp.py:9849 +#: FlatCAMApp.py:9856 msgid "Failed. Only Document objects can be saved as Document files..." msgstr "Failed. Only Document objects can be saved as Document files..." -#: FlatCAMApp.py:9861 +#: FlatCAMApp.py:9868 msgid "Save Document source file" msgstr "Save Document source file" -#: FlatCAMApp.py:9890 FlatCAMApp.py:9931 FlatCAMApp.py:10856 +#: FlatCAMApp.py:9897 FlatCAMApp.py:9938 FlatCAMApp.py:10863 msgid "Failed. Only Excellon objects can be saved as Excellon files..." msgstr "Failed. Only Excellon objects can be saved as Excellon files..." -#: FlatCAMApp.py:9898 FlatCAMApp.py:9902 +#: FlatCAMApp.py:9905 FlatCAMApp.py:9909 msgid "Save Excellon source file" msgstr "Save Excellon source file" -#: FlatCAMApp.py:9939 FlatCAMApp.py:9943 +#: FlatCAMApp.py:9946 FlatCAMApp.py:9950 msgid "Export Excellon" msgstr "Export Excellon" -#: FlatCAMApp.py:9983 FlatCAMApp.py:9987 +#: FlatCAMApp.py:9990 FlatCAMApp.py:9994 msgid "Export Gerber" msgstr "Export Gerber" -#: FlatCAMApp.py:10025 +#: FlatCAMApp.py:10032 msgid "Only Geometry objects can be used." msgstr "Only Geometry objects can be used." -#: FlatCAMApp.py:10039 FlatCAMApp.py:10043 +#: FlatCAMApp.py:10046 FlatCAMApp.py:10050 msgid "Export DXF" msgstr "Export DXF" -#: FlatCAMApp.py:10068 FlatCAMApp.py:10071 +#: FlatCAMApp.py:10075 FlatCAMApp.py:10078 msgid "Import SVG" msgstr "Import SVG" -#: FlatCAMApp.py:10099 FlatCAMApp.py:10103 +#: FlatCAMApp.py:10106 FlatCAMApp.py:10110 msgid "Import DXF" msgstr "Import DXF" -#: FlatCAMApp.py:10154 +#: FlatCAMApp.py:10161 msgid "Viewing the source code of the selected object." msgstr "Viewing the source code of the selected object." -#: FlatCAMApp.py:10155 FlatCAMObj.py:7075 FlatCAMObj.py:7852 +#: FlatCAMApp.py:10162 FlatCAMObj.py:7075 FlatCAMObj.py:7852 msgid "Loading..." msgstr "Loading..." -#: FlatCAMApp.py:10161 FlatCAMApp.py:10165 +#: FlatCAMApp.py:10168 FlatCAMApp.py:10172 msgid "Select an Gerber or Excellon file to view it's source file." msgstr "Select an Gerber or Excellon file to view it's source file." -#: FlatCAMApp.py:10179 +#: FlatCAMApp.py:10186 msgid "Source Editor" msgstr "Source Editor" -#: FlatCAMApp.py:10219 FlatCAMApp.py:10226 +#: FlatCAMApp.py:10226 FlatCAMApp.py:10233 msgid "There is no selected object for which to see it's source file code." msgstr "There is no selected object for which to see it's source file code." -#: FlatCAMApp.py:10238 +#: FlatCAMApp.py:10245 msgid "Failed to load the source code for the selected object" msgstr "Failed to load the source code for the selected object" -#: FlatCAMApp.py:10274 +#: FlatCAMApp.py:10281 msgid "Go to Line ..." msgstr "Go to Line ..." -#: FlatCAMApp.py:10275 +#: FlatCAMApp.py:10282 msgid "Line:" msgstr "Line:" -#: FlatCAMApp.py:10304 +#: FlatCAMApp.py:10311 msgid "New TCL script file created in Code Editor." msgstr "New TCL script file created in Code Editor." -#: FlatCAMApp.py:10343 FlatCAMApp.py:10345 +#: FlatCAMApp.py:10350 FlatCAMApp.py:10352 msgid "Open TCL script" msgstr "Open TCL script" -#: FlatCAMApp.py:10373 +#: FlatCAMApp.py:10380 msgid "Executing FlatCAMScript file." msgstr "Executing FlatCAMScript file." -#: FlatCAMApp.py:10381 FlatCAMApp.py:10384 +#: FlatCAMApp.py:10388 FlatCAMApp.py:10391 msgid "Run TCL script" msgstr "Run TCL script" -#: FlatCAMApp.py:10408 +#: FlatCAMApp.py:10415 msgid "TCL script file opened in Code Editor and executed." msgstr "TCL script file opened in Code Editor and executed." -#: FlatCAMApp.py:10459 FlatCAMApp.py:10465 +#: FlatCAMApp.py:10466 FlatCAMApp.py:10472 msgid "Save Project As ..." msgstr "Save Project As ..." -#: FlatCAMApp.py:10461 flatcamGUI/FlatCAMGUI.py:1119 +#: FlatCAMApp.py:10468 flatcamGUI/FlatCAMGUI.py:1119 #: flatcamGUI/FlatCAMGUI.py:2161 msgid "Project" msgstr "Project" -#: FlatCAMApp.py:10500 +#: FlatCAMApp.py:10507 msgid "FlatCAM objects print" msgstr "FlatCAM objects print" -#: FlatCAMApp.py:10513 FlatCAMApp.py:10520 +#: FlatCAMApp.py:10520 FlatCAMApp.py:10527 msgid "Save Object as PDF ..." msgstr "Save Object as PDF ..." -#: FlatCAMApp.py:10529 +#: FlatCAMApp.py:10536 msgid "Printing PDF ... Please wait." msgstr "Printing PDF ... Please wait." -#: FlatCAMApp.py:10708 +#: FlatCAMApp.py:10715 msgid "PDF file saved to" msgstr "PDF file saved to" -#: FlatCAMApp.py:10733 +#: FlatCAMApp.py:10740 msgid "Exporting SVG" msgstr "Exporting SVG" -#: FlatCAMApp.py:10776 +#: FlatCAMApp.py:10783 msgid "SVG file exported to" msgstr "SVG file exported to" -#: FlatCAMApp.py:10802 +#: FlatCAMApp.py:10809 msgid "" "Save cancelled because source file is empty. Try to export the Gerber file." msgstr "" "Save cancelled because source file is empty. Try to export the Gerber file." -#: FlatCAMApp.py:10950 +#: FlatCAMApp.py:10957 msgid "Excellon file exported to" msgstr "Excellon file exported to" -#: FlatCAMApp.py:10959 +#: FlatCAMApp.py:10966 msgid "Exporting Excellon" msgstr "Exporting Excellon" -#: FlatCAMApp.py:10964 FlatCAMApp.py:10971 +#: FlatCAMApp.py:10971 FlatCAMApp.py:10978 msgid "Could not export Excellon file." msgstr "Could not export Excellon file." -#: FlatCAMApp.py:11087 +#: FlatCAMApp.py:11094 msgid "Gerber file exported to" msgstr "Gerber file exported to" -#: FlatCAMApp.py:11095 +#: FlatCAMApp.py:11102 msgid "Exporting Gerber" msgstr "Exporting Gerber" -#: FlatCAMApp.py:11100 FlatCAMApp.py:11107 +#: FlatCAMApp.py:11107 FlatCAMApp.py:11114 msgid "Could not export Gerber file." msgstr "Could not export Gerber file." -#: FlatCAMApp.py:11142 +#: FlatCAMApp.py:11149 msgid "DXF file exported to" msgstr "DXF file exported to" -#: FlatCAMApp.py:11148 +#: FlatCAMApp.py:11155 msgid "Exporting DXF" msgstr "Exporting DXF" -#: FlatCAMApp.py:11153 FlatCAMApp.py:11160 +#: FlatCAMApp.py:11160 FlatCAMApp.py:11167 msgid "Could not export DXF file." msgstr "Could not export DXF file." -#: FlatCAMApp.py:11183 FlatCAMApp.py:11225 flatcamTools/ToolImage.py:277 +#: FlatCAMApp.py:11190 FlatCAMApp.py:11232 flatcamTools/ToolImage.py:277 msgid "" "Not supported type is picked as parameter. Only Geometry and Gerber are " "supported" @@ -1255,79 +1255,79 @@ msgstr "" "Not supported type is picked as parameter. Only Geometry and Gerber are " "supported" -#: FlatCAMApp.py:11193 +#: FlatCAMApp.py:11200 msgid "Importing SVG" msgstr "Importing SVG" -#: FlatCAMApp.py:11204 FlatCAMApp.py:11244 FlatCAMApp.py:11302 -#: FlatCAMApp.py:11367 FlatCAMApp.py:11431 FlatCAMApp.py:11496 -#: FlatCAMApp.py:11533 flatcamTools/ToolImage.py:297 +#: FlatCAMApp.py:11211 FlatCAMApp.py:11251 FlatCAMApp.py:11309 +#: FlatCAMApp.py:11374 FlatCAMApp.py:11438 FlatCAMApp.py:11503 +#: FlatCAMApp.py:11540 flatcamTools/ToolImage.py:297 #: flatcamTools/ToolPDF.py:225 msgid "Opened" msgstr "Opened" -#: FlatCAMApp.py:11234 +#: FlatCAMApp.py:11241 msgid "Importing DXF" msgstr "Importing DXF" -#: FlatCAMApp.py:11268 FlatCAMApp.py:11455 +#: FlatCAMApp.py:11275 FlatCAMApp.py:11462 msgid "Failed to open file" msgstr "Failed to open file" -#: FlatCAMApp.py:11271 FlatCAMApp.py:11458 +#: FlatCAMApp.py:11278 FlatCAMApp.py:11465 msgid "Failed to parse file" msgstr "Failed to parse file" -#: FlatCAMApp.py:11283 +#: FlatCAMApp.py:11290 msgid "Object is not Gerber file or empty. Aborting object creation." msgstr "Object is not Gerber file or empty. Aborting object creation." -#: FlatCAMApp.py:11288 +#: FlatCAMApp.py:11295 msgid "Opening Gerber" msgstr "Opening Gerber" -#: FlatCAMApp.py:11295 +#: FlatCAMApp.py:11302 msgid " Open Gerber failed. Probable not a Gerber file." msgstr " Open Gerber failed. Probable not a Gerber file." -#: FlatCAMApp.py:11326 flatcamTools/ToolPcbWizard.py:425 +#: FlatCAMApp.py:11333 flatcamTools/ToolPcbWizard.py:425 msgid "This is not Excellon file." msgstr "This is not Excellon file." -#: FlatCAMApp.py:11330 +#: FlatCAMApp.py:11337 msgid "Cannot open file" msgstr "Cannot open file" -#: FlatCAMApp.py:11349 flatcamTools/ToolPDF.py:275 +#: FlatCAMApp.py:11356 flatcamTools/ToolPDF.py:275 #: flatcamTools/ToolPcbWizard.py:447 msgid "No geometry found in file" msgstr "No geometry found in file" -#: FlatCAMApp.py:11352 +#: FlatCAMApp.py:11359 msgid "Opening Excellon." msgstr "Opening Excellon." -#: FlatCAMApp.py:11359 +#: FlatCAMApp.py:11366 msgid "Open Excellon file failed. Probable not an Excellon file." msgstr "Open Excellon file failed. Probable not an Excellon file." -#: FlatCAMApp.py:11391 +#: FlatCAMApp.py:11398 msgid "Reading GCode file" msgstr "Reading GCode file" -#: FlatCAMApp.py:11398 +#: FlatCAMApp.py:11405 msgid "Failed to open" msgstr "Failed to open" -#: FlatCAMApp.py:11406 +#: FlatCAMApp.py:11413 msgid "This is not GCODE" msgstr "This is not GCODE" -#: FlatCAMApp.py:11411 +#: FlatCAMApp.py:11418 msgid "Opening G-Code." msgstr "Opening G-Code." -#: FlatCAMApp.py:11420 +#: FlatCAMApp.py:11427 msgid "" "Failed to create CNCJob Object. Probable not a GCode file. Try to load it " "from File menu.\n" @@ -1339,103 +1339,103 @@ msgstr "" " Attempting to create a FlatCAM CNCJob Object from G-Code file failed during " "processing" -#: FlatCAMApp.py:11477 +#: FlatCAMApp.py:11484 msgid "Object is not HPGL2 file or empty. Aborting object creation." msgstr "Object is not HPGL2 file or empty. Aborting object creation." -#: FlatCAMApp.py:11482 +#: FlatCAMApp.py:11489 msgid "Opening HPGL2" msgstr "Opening HPGL2" -#: FlatCAMApp.py:11489 +#: FlatCAMApp.py:11496 msgid " Open HPGL2 failed. Probable not a HPGL2 file." msgstr " Open HPGL2 failed. Probable not a HPGL2 file." -#: FlatCAMApp.py:11509 +#: FlatCAMApp.py:11516 msgid "Opening TCL Script..." msgstr "Opening TCL Script..." -#: FlatCAMApp.py:11517 +#: FlatCAMApp.py:11524 msgid "TCL script file opened in Code Editor." msgstr "TCL script file opened in Code Editor." -#: FlatCAMApp.py:11520 +#: FlatCAMApp.py:11527 msgid "Failed to open TCL Script." msgstr "Failed to open TCL Script." -#: FlatCAMApp.py:11548 +#: FlatCAMApp.py:11555 msgid "Opening FlatCAM Config file." msgstr "Opening FlatCAM Config file." -#: FlatCAMApp.py:11576 +#: FlatCAMApp.py:11583 msgid "Failed to open config file" msgstr "Failed to open config file" -#: FlatCAMApp.py:11604 +#: FlatCAMApp.py:11611 msgid "Loading Project ... Please Wait ..." msgstr "Loading Project ... Please Wait ..." -#: FlatCAMApp.py:11609 +#: FlatCAMApp.py:11616 msgid "Opening FlatCAM Project file." msgstr "Opening FlatCAM Project file." -#: FlatCAMApp.py:11619 FlatCAMApp.py:11637 +#: FlatCAMApp.py:11626 FlatCAMApp.py:11644 msgid "Failed to open project file" msgstr "Failed to open project file" -#: FlatCAMApp.py:11674 +#: FlatCAMApp.py:11681 msgid "Loading Project ... restoring" msgstr "Loading Project ... restoring" -#: FlatCAMApp.py:11684 +#: FlatCAMApp.py:11691 msgid "Project loaded from" msgstr "Project loaded from" -#: FlatCAMApp.py:11753 +#: FlatCAMApp.py:11760 msgid "Redrawing all objects" msgstr "Redrawing all objects" -#: FlatCAMApp.py:11842 +#: FlatCAMApp.py:11849 msgid "Failed to load recent item list." msgstr "Failed to load recent item list." -#: FlatCAMApp.py:11849 +#: FlatCAMApp.py:11856 msgid "Failed to parse recent item list." msgstr "Failed to parse recent item list." -#: FlatCAMApp.py:11859 +#: FlatCAMApp.py:11866 msgid "Failed to load recent projects item list." msgstr "Failed to load recent projects item list." -#: FlatCAMApp.py:11866 +#: FlatCAMApp.py:11873 msgid "Failed to parse recent project item list." msgstr "Failed to parse recent project item list." -#: FlatCAMApp.py:11927 +#: FlatCAMApp.py:11934 msgid "Clear Recent projects" msgstr "Clear Recent projects" -#: FlatCAMApp.py:11951 +#: FlatCAMApp.py:11958 msgid "Clear Recent files" msgstr "Clear Recent files" -#: FlatCAMApp.py:11973 flatcamGUI/FlatCAMGUI.py:1348 +#: FlatCAMApp.py:11980 flatcamGUI/FlatCAMGUI.py:1348 msgid "Shortcut Key List" msgstr "Shortcut Key List" -#: FlatCAMApp.py:12047 +#: FlatCAMApp.py:12054 msgid "Selected Tab - Choose an Item from Project Tab" msgstr "Selected Tab - Choose an Item from Project Tab" -#: FlatCAMApp.py:12048 +#: FlatCAMApp.py:12055 msgid "Details" msgstr "Details" -#: FlatCAMApp.py:12050 +#: FlatCAMApp.py:12057 msgid "The normal flow when working in FlatCAM is the following:" msgstr "The normal flow when working in FlatCAM is the following:" -#: FlatCAMApp.py:12051 +#: FlatCAMApp.py:12058 msgid "" "Load/Import a Gerber, Excellon, Gcode, DXF, Raster Image or SVG file into " "FlatCAM using either the toolbars, key shortcuts or even dragging and " @@ -1445,30 +1445,30 @@ msgstr "" "FlatCAM using either the toolbars, key shortcuts or even dragging and " "dropping the files on the GUI." -#: FlatCAMApp.py:12054 -msgid "" -"You can also load a FlatCAM project by double clicking on the project file, " -"drag and drop of the file into the FLATCAM GUI or through the menu (or " -"toolbar) actions offered within the app." -msgstr "" -"You can also load a FlatCAM project by double clicking on the project file, " -"drag and drop of the file into the FLATCAM GUI or through the menu (or " -"toolbar) actions offered within the app." - -#: FlatCAMApp.py:12057 -msgid "" -"Once an object is available in the Project Tab, by selecting it and then " -"focusing on SELECTED TAB (more simpler is to double click the object name in " -"the Project Tab, SELECTED TAB will be updated with the object properties " -"according to its kind: Gerber, Excellon, Geometry or CNCJob object." -msgstr "" -"Once an object is available in the Project Tab, by selecting it and then " -"focusing on SELECTED TAB (more simpler is to double click the object name in " -"the Project Tab, SELECTED TAB will be updated with the object properties " -"according to its kind: Gerber, Excellon, Geometry or CNCJob object." - #: FlatCAMApp.py:12061 msgid "" +"You can also load a FlatCAM project by double clicking on the project file, " +"drag and drop of the file into the FLATCAM GUI or through the menu (or " +"toolbar) actions offered within the app." +msgstr "" +"You can also load a FlatCAM project by double clicking on the project file, " +"drag and drop of the file into the FLATCAM GUI or through the menu (or " +"toolbar) actions offered within the app." + +#: FlatCAMApp.py:12064 +msgid "" +"Once an object is available in the Project Tab, by selecting it and then " +"focusing on SELECTED TAB (more simpler is to double click the object name in " +"the Project Tab, SELECTED TAB will be updated with the object properties " +"according to its kind: Gerber, Excellon, Geometry or CNCJob object." +msgstr "" +"Once an object is available in the Project Tab, by selecting it and then " +"focusing on SELECTED TAB (more simpler is to double click the object name in " +"the Project Tab, SELECTED TAB will be updated with the object properties " +"according to its kind: Gerber, Excellon, Geometry or CNCJob object." + +#: FlatCAMApp.py:12068 +msgid "" "If the selection of the object is done on the canvas by single click " "instead, and the SELECTED TAB is in focus, again the object properties will " "be displayed into the Selected Tab. Alternatively, double clicking on the " @@ -1481,7 +1481,7 @@ msgstr "" "object on the canvas will bring the SELECTED TAB and populate it even if it " "was out of focus." -#: FlatCAMApp.py:12065 +#: FlatCAMApp.py:12072 msgid "" "You can change the parameters in this screen and the flow direction is like " "this:" @@ -1489,7 +1489,7 @@ msgstr "" "You can change the parameters in this screen and the flow direction is like " "this:" -#: FlatCAMApp.py:12066 +#: FlatCAMApp.py:12073 msgid "" "Gerber/Excellon Object --> Change Parameter --> Generate Geometry --> " "Geometry Object --> Add tools (change param in Selected Tab) --> Generate " @@ -1501,7 +1501,7 @@ msgstr "" "CNCJob --> CNCJob Object --> Verify GCode (through Edit CNC Code) and/or " "append/prepend to GCode (again, done in SELECTED TAB) --> Save GCode." -#: FlatCAMApp.py:12070 +#: FlatCAMApp.py:12077 msgid "" "A list of key shortcuts is available through an menu entry in Help --> " "Shortcuts List or through its own key shortcut: F3." @@ -1509,31 +1509,31 @@ msgstr "" "A list of key shortcuts is available through an menu entry in Help --> " "Shortcuts List or through its own key shortcut: F3." -#: FlatCAMApp.py:12134 +#: FlatCAMApp.py:12141 msgid "Failed checking for latest version. Could not connect." msgstr "Failed checking for latest version. Could not connect." -#: FlatCAMApp.py:12141 +#: FlatCAMApp.py:12148 msgid "Could not parse information about latest version." msgstr "Could not parse information about latest version." -#: FlatCAMApp.py:12151 +#: FlatCAMApp.py:12158 msgid "FlatCAM is up to date!" msgstr "FlatCAM is up to date!" -#: FlatCAMApp.py:12156 +#: FlatCAMApp.py:12163 msgid "Newer Version Available" msgstr "Newer Version Available" -#: FlatCAMApp.py:12158 +#: FlatCAMApp.py:12165 msgid "There is a newer version of FlatCAM available for download:" msgstr "There is a newer version of FlatCAM available for download:" -#: FlatCAMApp.py:12162 +#: FlatCAMApp.py:12169 msgid "info" msgstr "info" -#: FlatCAMApp.py:12190 +#: FlatCAMApp.py:12197 msgid "" "OpenGL canvas initialization failed. HW or HW configuration not supported." "Change the graphic engine to Legacy(2D) in Edit -> Preferences -> General " @@ -1545,87 +1545,87 @@ msgstr "" "tab.\n" "\n" -#: FlatCAMApp.py:12269 +#: FlatCAMApp.py:12276 msgid "All plots disabled." msgstr "All plots disabled." -#: FlatCAMApp.py:12276 +#: FlatCAMApp.py:12283 msgid "All non selected plots disabled." msgstr "All non selected plots disabled." -#: FlatCAMApp.py:12283 +#: FlatCAMApp.py:12290 msgid "All plots enabled." msgstr "All plots enabled." -#: FlatCAMApp.py:12289 +#: FlatCAMApp.py:12296 msgid "Selected plots enabled..." msgstr "Selected plots enabled..." -#: FlatCAMApp.py:12297 +#: FlatCAMApp.py:12304 msgid "Selected plots disabled..." msgstr "Selected plots disabled..." -#: FlatCAMApp.py:12330 +#: FlatCAMApp.py:12337 msgid "Enabling plots ..." msgstr "Enabling plots ..." -#: FlatCAMApp.py:12382 +#: FlatCAMApp.py:12389 msgid "Disabling plots ..." msgstr "Disabling plots ..." -#: FlatCAMApp.py:12405 +#: FlatCAMApp.py:12412 msgid "Working ..." msgstr "Working ..." -#: FlatCAMApp.py:12460 flatcamGUI/FlatCAMGUI.py:688 +#: FlatCAMApp.py:12467 flatcamGUI/FlatCAMGUI.py:688 msgid "Red" msgstr "Red" -#: FlatCAMApp.py:12462 flatcamGUI/FlatCAMGUI.py:691 +#: FlatCAMApp.py:12469 flatcamGUI/FlatCAMGUI.py:691 msgid "Blue" msgstr "Blue" -#: FlatCAMApp.py:12465 flatcamGUI/FlatCAMGUI.py:694 +#: FlatCAMApp.py:12472 flatcamGUI/FlatCAMGUI.py:694 msgid "Yellow" msgstr "Yellow" -#: FlatCAMApp.py:12467 flatcamGUI/FlatCAMGUI.py:697 +#: FlatCAMApp.py:12474 flatcamGUI/FlatCAMGUI.py:697 msgid "Green" msgstr "Green" -#: FlatCAMApp.py:12469 flatcamGUI/FlatCAMGUI.py:700 +#: FlatCAMApp.py:12476 flatcamGUI/FlatCAMGUI.py:700 msgid "Purple" msgstr "Purple" -#: FlatCAMApp.py:12471 flatcamGUI/FlatCAMGUI.py:703 +#: FlatCAMApp.py:12478 flatcamGUI/FlatCAMGUI.py:703 msgid "Brown" msgstr "Brown" -#: FlatCAMApp.py:12473 FlatCAMApp.py:12529 flatcamGUI/FlatCAMGUI.py:706 +#: FlatCAMApp.py:12480 FlatCAMApp.py:12536 flatcamGUI/FlatCAMGUI.py:706 msgid "White" msgstr "White" -#: FlatCAMApp.py:12475 flatcamGUI/FlatCAMGUI.py:709 +#: FlatCAMApp.py:12482 flatcamGUI/FlatCAMGUI.py:709 msgid "Black" msgstr "Black" -#: FlatCAMApp.py:12478 flatcamGUI/FlatCAMGUI.py:714 +#: FlatCAMApp.py:12485 flatcamGUI/FlatCAMGUI.py:714 msgid "Custom" msgstr "Custom" -#: FlatCAMApp.py:12488 flatcamGUI/FlatCAMGUI.py:722 +#: FlatCAMApp.py:12495 flatcamGUI/FlatCAMGUI.py:722 msgid "Default" msgstr "Default" -#: FlatCAMApp.py:12512 flatcamGUI/FlatCAMGUI.py:719 +#: FlatCAMApp.py:12519 flatcamGUI/FlatCAMGUI.py:719 msgid "Opacity" msgstr "Opacity" -#: FlatCAMApp.py:12514 +#: FlatCAMApp.py:12521 msgid "Set alpha level ..." msgstr "Set alpha level ..." -#: FlatCAMApp.py:12514 flatcamGUI/PreferencesUI.py:6900 +#: FlatCAMApp.py:12521 flatcamGUI/PreferencesUI.py:6900 #: flatcamGUI/PreferencesUI.py:8230 flatcamGUI/PreferencesUI.py:8444 #: flatcamTools/ToolExtractDrills.py:164 flatcamTools/ToolExtractDrills.py:285 #: flatcamTools/ToolPunchGerber.py:192 flatcamTools/ToolPunchGerber.py:308 @@ -1633,31 +1633,31 @@ msgstr "Set alpha level ..." msgid "Value" msgstr "Value" -#: FlatCAMApp.py:12590 +#: FlatCAMApp.py:12597 msgid "Saving FlatCAM Project" msgstr "Saving FlatCAM Project" -#: FlatCAMApp.py:12611 FlatCAMApp.py:12647 +#: FlatCAMApp.py:12618 FlatCAMApp.py:12654 msgid "Project saved to" msgstr "Project saved to" -#: FlatCAMApp.py:12618 +#: FlatCAMApp.py:12625 msgid "The object is used by another application." msgstr "The object is used by another application." -#: FlatCAMApp.py:12632 +#: FlatCAMApp.py:12639 msgid "Failed to verify project file" msgstr "Failed to verify project file" -#: FlatCAMApp.py:12632 FlatCAMApp.py:12640 FlatCAMApp.py:12650 +#: FlatCAMApp.py:12639 FlatCAMApp.py:12647 FlatCAMApp.py:12657 msgid "Retry to save it." msgstr "Retry to save it." -#: FlatCAMApp.py:12640 FlatCAMApp.py:12650 +#: FlatCAMApp.py:12647 FlatCAMApp.py:12657 msgid "Failed to parse saved project file" msgstr "Failed to parse saved project file" -#: FlatCAMApp.py:13132 +#: FlatCAMApp.py:13139 msgid "The user requested a graceful exit of the current task." msgstr "The user requested a graceful exit of the current task." @@ -2355,7 +2355,7 @@ msgid "Clear" msgstr "Clear" #: FlatCAMCommon.py:1853 flatcamTools/ToolNCC.py:351 -#: flatcamTools/ToolNCC.py:1627 +#: flatcamTools/ToolNCC.py:1618 msgid "Isolation" msgstr "Isolation" @@ -2462,9 +2462,9 @@ msgstr "" #: FlatCAMCommon.py:1925 FlatCAMCommon.py:2040 #: flatcamEditors/FlatCAMGeoEditor.py:500 flatcamGUI/PreferencesUI.py:5509 #: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 -#: flatcamTools/ToolNCC.py:2395 flatcamTools/ToolNCC.py:2424 -#: flatcamTools/ToolNCC.py:2693 flatcamTools/ToolNCC.py:2725 -#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:1822 +#: flatcamTools/ToolNCC.py:2390 flatcamTools/ToolNCC.py:2419 +#: flatcamTools/ToolNCC.py:2688 flatcamTools/ToolNCC.py:2720 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:1829 #: tclCommands/TclCommandCopperClear.py:126 #: tclCommands/TclCommandCopperClear.py:134 tclCommands/TclCommandPaint.py:125 msgid "Standard" @@ -2474,8 +2474,8 @@ msgstr "Standard" #: flatcamEditors/FlatCAMGeoEditor.py:500 #: flatcamEditors/FlatCAMGeoEditor.py:5156 flatcamGUI/PreferencesUI.py:5509 #: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 -#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:696 -#: flatcamTools/ToolPaint.py:1850 tclCommands/TclCommandCopperClear.py:130 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:699 +#: flatcamTools/ToolPaint.py:1857 tclCommands/TclCommandCopperClear.py:130 #: tclCommands/TclCommandPaint.py:129 msgid "Lines" msgstr "Lines" @@ -2588,13 +2588,13 @@ msgstr "" #: FlatCAMCommon.py:2040 FlatCAMCommon.py:2042 flatcamGUI/PreferencesUI.py:6056 #: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:392 -#: flatcamTools/ToolPaint.py:690 flatcamTools/ToolPaint.py:695 -#: flatcamTools/ToolPaint.py:1864 tclCommands/TclCommandPaint.py:131 +#: flatcamTools/ToolPaint.py:693 flatcamTools/ToolPaint.py:698 +#: flatcamTools/ToolPaint.py:1871 tclCommands/TclCommandPaint.py:131 msgid "Laser_lines" msgstr "Laser_lines" #: FlatCAMCommon.py:2040 flatcamGUI/PreferencesUI.py:6056 -#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:2015 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:2022 #: tclCommands/TclCommandPaint.py:133 msgid "Combo" msgstr "Combo" @@ -2644,8 +2644,8 @@ msgstr "Skewing..." #: flatcamTools/ToolFilm.py:557 flatcamTools/ToolImage.py:49 #: flatcamTools/ToolImage.py:252 flatcamTools/ToolImage.py:273 #: flatcamTools/ToolNCC.py:96 flatcamTools/ToolNCC.py:558 -#: flatcamTools/ToolNCC.py:1293 flatcamTools/ToolPaint.py:502 -#: flatcamTools/ToolPaint.py:703 flatcamTools/ToolPanelize.py:118 +#: flatcamTools/ToolNCC.py:1295 flatcamTools/ToolPaint.py:502 +#: flatcamTools/ToolPaint.py:706 flatcamTools/ToolPanelize.py:118 #: flatcamTools/ToolPanelize.py:204 flatcamTools/ToolPanelize.py:374 #: flatcamTools/ToolPanelize.py:391 msgid "Gerber" @@ -2661,8 +2661,8 @@ msgstr "Gerber" #: flatcamTools/ToolFilm.py:102 flatcamTools/ToolFilm.py:549 #: flatcamTools/ToolFilm.py:557 flatcamTools/ToolImage.py:49 #: flatcamTools/ToolImage.py:271 flatcamTools/ToolNCC.py:95 -#: flatcamTools/ToolNCC.py:558 flatcamTools/ToolNCC.py:1293 -#: flatcamTools/ToolPaint.py:502 flatcamTools/ToolPaint.py:703 +#: flatcamTools/ToolNCC.py:558 flatcamTools/ToolNCC.py:1295 +#: flatcamTools/ToolPaint.py:502 flatcamTools/ToolPaint.py:706 #: flatcamTools/ToolPanelize.py:118 flatcamTools/ToolPanelize.py:374 #: flatcamTools/ToolPanelize.py:391 msgid "Geometry" @@ -2685,11 +2685,11 @@ msgstr "Buffering solid geometry" #: FlatCAMObj.py:1001 camlib.py:979 flatcamGUI/PreferencesUI.py:2476 #: flatcamTools/ToolCopperThieving.py:1017 #: flatcamTools/ToolCopperThieving.py:1206 -#: flatcamTools/ToolCopperThieving.py:1218 flatcamTools/ToolNCC.py:2050 -#: flatcamTools/ToolNCC.py:2158 flatcamTools/ToolNCC.py:2172 -#: flatcamTools/ToolNCC.py:3103 flatcamTools/ToolNCC.py:3208 -#: flatcamTools/ToolNCC.py:3223 flatcamTools/ToolNCC.py:3489 -#: flatcamTools/ToolNCC.py:3590 flatcamTools/ToolNCC.py:3605 +#: flatcamTools/ToolCopperThieving.py:1218 flatcamTools/ToolNCC.py:2045 +#: flatcamTools/ToolNCC.py:2153 flatcamTools/ToolNCC.py:2167 +#: flatcamTools/ToolNCC.py:3098 flatcamTools/ToolNCC.py:3203 +#: flatcamTools/ToolNCC.py:3218 flatcamTools/ToolNCC.py:3484 +#: flatcamTools/ToolNCC.py:3585 flatcamTools/ToolNCC.py:3600 msgid "Buffering" msgstr "Buffering" @@ -2709,7 +2709,7 @@ msgstr "Isolating..." msgid "Click on a polygon to isolate it." msgstr "Click on a polygon to isolate it." -#: FlatCAMObj.py:1173 FlatCAMObj.py:1277 flatcamTools/ToolPaint.py:1504 +#: FlatCAMObj.py:1173 FlatCAMObj.py:1277 flatcamTools/ToolPaint.py:1511 msgid "Added polygon" msgstr "Added polygon" @@ -2717,7 +2717,7 @@ msgstr "Added polygon" msgid "Click to add next polygon or right click to start isolation." msgstr "Click to add next polygon or right click to start isolation." -#: FlatCAMObj.py:1186 flatcamTools/ToolPaint.py:1518 +#: FlatCAMObj.py:1186 flatcamTools/ToolPaint.py:1525 msgid "Removed polygon" msgstr "Removed polygon" @@ -2725,11 +2725,11 @@ msgstr "Removed polygon" msgid "Click to add/remove next polygon or right click to start isolation." msgstr "Click to add/remove next polygon or right click to start isolation." -#: FlatCAMObj.py:1192 flatcamTools/ToolPaint.py:1524 +#: FlatCAMObj.py:1192 flatcamTools/ToolPaint.py:1531 msgid "No polygon detected under click position." msgstr "No polygon detected under click position." -#: FlatCAMObj.py:1213 flatcamTools/ToolPaint.py:1553 +#: FlatCAMObj.py:1213 flatcamTools/ToolPaint.py:1560 msgid "List of single polygons is empty. Aborting." msgstr "List of single polygons is empty. Aborting." @@ -2742,8 +2742,8 @@ msgstr "No polygon in selection." msgid "Rough" msgstr "Rough" -#: FlatCAMObj.py:1410 FlatCAMObj.py:1489 flatcamTools/ToolNCC.py:2086 -#: flatcamTools/ToolNCC.py:3137 flatcamTools/ToolNCC.py:3516 +#: FlatCAMObj.py:1410 FlatCAMObj.py:1489 flatcamTools/ToolNCC.py:2081 +#: flatcamTools/ToolNCC.py:3132 flatcamTools/ToolNCC.py:3511 msgid "Isolation geometry could not be generated." msgstr "Isolation geometry could not be generated." @@ -2770,16 +2770,16 @@ msgstr "Total Slots" #: FlatCAMObj.py:2857 FlatCAMObj.py:3069 FlatCAMObj.py:3085 FlatCAMObj.py:3089 #: FlatCAMObj.py:4242 FlatCAMObj.py:4667 FlatCAMObj.py:4703 #: flatcamGUI/ObjectUI.py:817 flatcamGUI/ObjectUI.py:1660 -#: flatcamTools/ToolNCC.py:331 flatcamTools/ToolNCC.py:794 -#: flatcamTools/ToolNCC.py:808 flatcamTools/ToolNCC.py:1189 -#: flatcamTools/ToolPaint.py:314 flatcamTools/ToolPaint.py:764 -#: flatcamTools/ToolPaint.py:776 flatcamTools/ToolPaint.py:1159 +#: flatcamTools/ToolNCC.py:331 flatcamTools/ToolNCC.py:797 +#: flatcamTools/ToolNCC.py:811 flatcamTools/ToolNCC.py:1191 +#: flatcamTools/ToolPaint.py:314 flatcamTools/ToolPaint.py:767 +#: flatcamTools/ToolPaint.py:779 flatcamTools/ToolPaint.py:1166 msgid "Parameters for" msgstr "Parameters for" #: FlatCAMObj.py:2857 FlatCAMObj.py:3089 FlatCAMObj.py:4242 FlatCAMObj.py:4703 -#: flatcamTools/ToolNCC.py:808 flatcamTools/ToolNCC.py:1189 -#: flatcamTools/ToolPaint.py:776 flatcamTools/ToolPaint.py:1159 +#: flatcamTools/ToolNCC.py:811 flatcamTools/ToolNCC.py:1191 +#: flatcamTools/ToolPaint.py:779 flatcamTools/ToolPaint.py:1166 msgid "Multiple Tools" msgstr "Multiple Tools" @@ -2791,8 +2791,8 @@ msgstr "No Tool Selected" #: flatcamEditors/FlatCAMGeoEditor.py:406 flatcamGUI/FlatCAMGUI.py:496 #: flatcamGUI/FlatCAMGUI.py:1143 flatcamGUI/ObjectUI.py:817 #: flatcamGUI/ObjectUI.py:1660 flatcamTools/ToolNCC.py:331 -#: flatcamTools/ToolNCC.py:794 flatcamTools/ToolPaint.py:314 -#: flatcamTools/ToolPaint.py:764 +#: flatcamTools/ToolNCC.py:797 flatcamTools/ToolPaint.py:314 +#: flatcamTools/ToolPaint.py:767 msgid "Tool" msgstr "Tool" @@ -2850,7 +2850,7 @@ msgstr "Spindle speed" msgid "Generating CNC Code" msgstr "Generating CNC Code" -#: FlatCAMObj.py:3966 flatcamTools/ToolNCC.py:916 flatcamTools/ToolPaint.py:841 +#: FlatCAMObj.py:3966 flatcamTools/ToolNCC.py:918 flatcamTools/ToolPaint.py:844 msgid "Current Tool parameters were applied to all tools." msgstr "Current Tool parameters were applied to all tools." @@ -2884,8 +2884,8 @@ msgstr "Copy" #: flatcamEditors/FlatCAMGeoEditor.py:1174 #: flatcamEditors/FlatCAMGeoEditor.py:1218 #: flatcamEditors/FlatCAMGeoEditor.py:1253 -#: flatcamEditors/FlatCAMGeoEditor.py:1281 flatcamTools/ToolNCC.py:1502 -#: flatcamTools/ToolPaint.py:1237 flatcamTools/ToolPaint.py:1408 +#: flatcamEditors/FlatCAMGeoEditor.py:1281 flatcamTools/ToolNCC.py:1493 +#: flatcamTools/ToolPaint.py:1244 flatcamTools/ToolPaint.py:1415 #: flatcamTools/ToolSolderPaste.py:883 flatcamTools/ToolSolderPaste.py:956 msgid "Wrong value format entered, use a number." msgstr "Wrong value format entered, use a number." @@ -3958,7 +3958,7 @@ msgstr "Paint" #: flatcamEditors/FlatCAMGeoEditor.py:548 flatcamGUI/FlatCAMGUI.py:909 #: flatcamGUI/FlatCAMGUI.py:2588 flatcamGUI/ObjectUI.py:2057 -#: flatcamTools/ToolPaint.py:43 flatcamTools/ToolPaint.py:735 +#: flatcamTools/ToolPaint.py:43 flatcamTools/ToolPaint.py:738 msgid "Paint Tool" msgstr "Paint Tool" @@ -4579,8 +4579,8 @@ msgstr "Click on opposite corner to complete ..." msgid "Done. Rectangle completed." msgstr "Done. Rectangle completed." -#: flatcamEditors/FlatCAMGeoEditor.py:2411 flatcamTools/ToolNCC.py:1737 -#: flatcamTools/ToolPaint.py:1616 +#: flatcamEditors/FlatCAMGeoEditor.py:2411 flatcamTools/ToolNCC.py:1728 +#: flatcamTools/ToolPaint.py:1623 msgid "Click on next Point or click right mouse button to complete ..." msgstr "Click on next Point or click right mouse button to complete ..." @@ -6275,7 +6275,7 @@ msgstr "Cutout Tool" #: flatcamGUI/FlatCAMGUI.py:907 flatcamGUI/FlatCAMGUI.py:2586 #: flatcamGUI/ObjectUI.py:573 flatcamGUI/ObjectUI.py:2075 -#: flatcamTools/ToolNCC.py:972 +#: flatcamTools/ToolNCC.py:974 msgid "NCC Tool" msgstr "NCC Tool" @@ -7082,8 +7082,8 @@ msgstr "New" #: flatcamTools/ToolCopperThieving.py:159 #: flatcamTools/ToolCopperThieving.py:605 flatcamTools/ToolDblSided.py:226 #: flatcamTools/ToolFilm.py:359 flatcamTools/ToolNCC.py:558 -#: flatcamTools/ToolNCC.py:1293 flatcamTools/ToolPaint.py:502 -#: flatcamTools/ToolPaint.py:703 flatcamTools/ToolPanelize.py:374 +#: flatcamTools/ToolNCC.py:1295 flatcamTools/ToolPaint.py:502 +#: flatcamTools/ToolPaint.py:706 flatcamTools/ToolPanelize.py:374 #: flatcamTools/ToolPunchGerber.py:149 flatcamTools/ToolPunchGerber.py:164 msgid "Excellon" msgstr "Excellon" @@ -7258,8 +7258,8 @@ msgstr "Cancelled. Nothing selected to move." msgid "New Tool ..." msgstr "New Tool ..." -#: flatcamGUI/FlatCAMGUI.py:4000 flatcamTools/ToolNCC.py:922 -#: flatcamTools/ToolPaint.py:847 flatcamTools/ToolSolderPaste.py:560 +#: flatcamGUI/FlatCAMGUI.py:4000 flatcamTools/ToolNCC.py:924 +#: flatcamTools/ToolPaint.py:850 flatcamTools/ToolSolderPaste.py:560 msgid "Enter a Tool Diameter" msgstr "Enter a Tool Diameter" @@ -8481,8 +8481,8 @@ msgstr "" "cut and negative for 'inside' cut." #: flatcamGUI/ObjectUI.py:1578 flatcamTools/ToolNCC.py:209 -#: flatcamTools/ToolNCC.py:921 flatcamTools/ToolPaint.py:192 -#: flatcamTools/ToolPaint.py:846 flatcamTools/ToolSolderPaste.py:559 +#: flatcamTools/ToolNCC.py:923 flatcamTools/ToolPaint.py:192 +#: flatcamTools/ToolPaint.py:849 flatcamTools/ToolSolderPaste.py:559 msgid "New Tool" msgstr "New Tool" @@ -8496,7 +8496,7 @@ msgstr "" #: flatcamGUI/ObjectUI.py:1600 flatcamTools/ToolNCC.py:300 #: flatcamTools/ToolNCC.py:634 flatcamTools/ToolPaint.py:283 -#: flatcamTools/ToolPaint.py:676 +#: flatcamTools/ToolPaint.py:679 msgid "Add from DB" msgstr "Add from DB" @@ -11176,21 +11176,21 @@ msgstr "" #: flatcamGUI/PreferencesUI.py:5588 flatcamGUI/PreferencesUI.py:6119 #: flatcamGUI/PreferencesUI.py:7696 flatcamTools/ToolCopperThieving.py:127 -#: flatcamTools/ToolNCC.py:535 flatcamTools/ToolNCC.py:1309 -#: flatcamTools/ToolNCC.py:1651 flatcamTools/ToolNCC.py:1935 -#: flatcamTools/ToolNCC.py:1990 flatcamTools/ToolPaint.py:486 -#: flatcamTools/ToolPaint.py:939 flatcamTools/ToolPaint.py:1440 +#: flatcamTools/ToolNCC.py:535 flatcamTools/ToolNCC.py:1311 +#: flatcamTools/ToolNCC.py:1642 flatcamTools/ToolNCC.py:1930 +#: flatcamTools/ToolNCC.py:1985 flatcamTools/ToolPaint.py:486 +#: flatcamTools/ToolPaint.py:946 flatcamTools/ToolPaint.py:1447 msgid "Area Selection" msgstr "Area Selection" #: flatcamGUI/PreferencesUI.py:5588 flatcamGUI/PreferencesUI.py:6119 #: flatcamGUI/PreferencesUI.py:7697 flatcamTools/ToolCopperThieving.py:128 #: flatcamTools/ToolDblSided.py:217 flatcamTools/ToolNCC.py:535 -#: flatcamTools/ToolNCC.py:1667 flatcamTools/ToolNCC.py:1941 -#: flatcamTools/ToolNCC.py:1998 flatcamTools/ToolNCC.py:2306 -#: flatcamTools/ToolNCC.py:2586 flatcamTools/ToolNCC.py:3012 -#: flatcamTools/ToolPaint.py:486 flatcamTools/ToolPaint.py:924 -#: flatcamTools/ToolPaint.py:1456 tclCommands/TclCommandCopperClear.py:192 +#: flatcamTools/ToolNCC.py:1658 flatcamTools/ToolNCC.py:1936 +#: flatcamTools/ToolNCC.py:1993 flatcamTools/ToolNCC.py:2301 +#: flatcamTools/ToolNCC.py:2581 flatcamTools/ToolNCC.py:3007 +#: flatcamTools/ToolPaint.py:486 flatcamTools/ToolPaint.py:931 +#: flatcamTools/ToolPaint.py:1463 tclCommands/TclCommandCopperClear.py:192 #: tclCommands/TclCommandPaint.py:166 msgid "Reference Object" msgstr "Reference Object" @@ -11455,7 +11455,7 @@ msgstr "" "- 'Reference Object' - will process the area specified by another object." #: flatcamGUI/PreferencesUI.py:6119 flatcamTools/ToolPaint.py:486 -#: flatcamTools/ToolPaint.py:935 flatcamTools/ToolPaint.py:1420 +#: flatcamTools/ToolPaint.py:942 flatcamTools/ToolPaint.py:1427 #: tclCommands/TclCommandPaint.py:164 msgid "Polygon Selection" msgstr "Polygon Selection" @@ -14129,8 +14129,8 @@ msgstr "Copper Thieving Tool done." #: flatcamTools/ToolCopperThieving.py:760 #: flatcamTools/ToolCopperThieving.py:793 flatcamTools/ToolCutOut.py:480 #: flatcamTools/ToolCutOut.py:667 flatcamTools/ToolInvertGerber.py:208 -#: flatcamTools/ToolNCC.py:1603 flatcamTools/ToolNCC.py:1644 -#: flatcamTools/ToolNCC.py:1673 flatcamTools/ToolPaint.py:1462 +#: flatcamTools/ToolNCC.py:1594 flatcamTools/ToolNCC.py:1635 +#: flatcamTools/ToolNCC.py:1664 flatcamTools/ToolPaint.py:1469 #: flatcamTools/ToolPanelize.py:413 flatcamTools/ToolPanelize.py:428 #: flatcamTools/ToolSub.py:294 flatcamTools/ToolSub.py:307 #: flatcamTools/ToolSub.py:498 flatcamTools/ToolSub.py:513 @@ -14138,7 +14138,7 @@ msgstr "Copper Thieving Tool done." msgid "Could not retrieve object" msgstr "Could not retrieve object" -#: flatcamTools/ToolCopperThieving.py:770 flatcamTools/ToolNCC.py:1652 +#: flatcamTools/ToolCopperThieving.py:770 flatcamTools/ToolNCC.py:1643 msgid "Click the start point of the area." msgstr "Click the start point of the area." @@ -14146,9 +14146,9 @@ msgstr "Click the start point of the area." msgid "Click the end point of the filling area." msgstr "Click the end point of the filling area." -#: flatcamTools/ToolCopperThieving.py:827 flatcamTools/ToolNCC.py:1714 -#: flatcamTools/ToolNCC.py:1766 flatcamTools/ToolPaint.py:1594 -#: flatcamTools/ToolPaint.py:1645 +#: flatcamTools/ToolCopperThieving.py:827 flatcamTools/ToolNCC.py:1705 +#: flatcamTools/ToolNCC.py:1757 flatcamTools/ToolPaint.py:1601 +#: flatcamTools/ToolPaint.py:1652 msgid "Zone added. Click to start adding next zone or right click to finish." msgstr "Zone added. Click to start adding next zone or right click to finish." @@ -14179,14 +14179,14 @@ msgstr "Working..." msgid "Geometry not supported for bounding box" msgstr "Geometry not supported for bounding box" -#: flatcamTools/ToolCopperThieving.py:1068 flatcamTools/ToolNCC.py:1933 -#: flatcamTools/ToolNCC.py:1988 flatcamTools/ToolNCC.py:2992 -#: flatcamTools/ToolPaint.py:3368 +#: flatcamTools/ToolCopperThieving.py:1068 flatcamTools/ToolNCC.py:1928 +#: flatcamTools/ToolNCC.py:1983 flatcamTools/ToolNCC.py:2987 +#: flatcamTools/ToolPaint.py:3375 msgid "No object available." msgstr "No object available." -#: flatcamTools/ToolCopperThieving.py:1105 flatcamTools/ToolNCC.py:1958 -#: flatcamTools/ToolNCC.py:2011 flatcamTools/ToolNCC.py:3034 +#: flatcamTools/ToolCopperThieving.py:1105 flatcamTools/ToolNCC.py:1953 +#: flatcamTools/ToolNCC.py:2006 flatcamTools/ToolNCC.py:3029 msgid "The reference object type is not supported." msgstr "The reference object type is not supported." @@ -14404,7 +14404,7 @@ msgid "Any form CutOut operation finished." msgstr "Any form CutOut operation finished." #: flatcamTools/ToolCutOut.py:671 flatcamTools/ToolInvertGerber.py:214 -#: flatcamTools/ToolNCC.py:1607 flatcamTools/ToolPaint.py:1385 +#: flatcamTools/ToolNCC.py:1598 flatcamTools/ToolPaint.py:1392 #: flatcamTools/ToolPanelize.py:418 tclCommands/TclCommandBbox.py:72 #: tclCommands/TclCommandNregions.py:72 msgid "Object not found" @@ -15515,116 +15515,116 @@ msgstr "" msgid "Generate Geometry" msgstr "Generate Geometry" -#: flatcamTools/ToolNCC.py:1429 flatcamTools/ToolPaint.py:1172 +#: flatcamTools/ToolNCC.py:1420 flatcamTools/ToolPaint.py:1179 #: flatcamTools/ToolSolderPaste.py:888 msgid "Please enter a tool diameter to add, in Float format." msgstr "Please enter a tool diameter to add, in Float format." -#: flatcamTools/ToolNCC.py:1460 flatcamTools/ToolNCC.py:4013 -#: flatcamTools/ToolPaint.py:1196 flatcamTools/ToolPaint.py:3587 +#: flatcamTools/ToolNCC.py:1451 flatcamTools/ToolNCC.py:4008 +#: flatcamTools/ToolPaint.py:1203 flatcamTools/ToolPaint.py:3598 #: flatcamTools/ToolSolderPaste.py:917 msgid "Cancelled. Tool already in Tool Table." msgstr "Cancelled. Tool already in Tool Table." -#: flatcamTools/ToolNCC.py:1467 flatcamTools/ToolNCC.py:4030 -#: flatcamTools/ToolPaint.py:1201 flatcamTools/ToolPaint.py:3604 +#: flatcamTools/ToolNCC.py:1458 flatcamTools/ToolNCC.py:4025 +#: flatcamTools/ToolPaint.py:1208 flatcamTools/ToolPaint.py:3615 msgid "New tool added to Tool Table." msgstr "New tool added to Tool Table." -#: flatcamTools/ToolNCC.py:1511 flatcamTools/ToolPaint.py:1245 +#: flatcamTools/ToolNCC.py:1502 flatcamTools/ToolPaint.py:1252 msgid "Tool from Tool Table was edited." msgstr "Tool from Tool Table was edited." -#: flatcamTools/ToolNCC.py:1523 flatcamTools/ToolPaint.py:1257 +#: flatcamTools/ToolNCC.py:1514 flatcamTools/ToolPaint.py:1264 #: flatcamTools/ToolSolderPaste.py:977 msgid "Cancelled. New diameter value is already in the Tool Table." msgstr "Cancelled. New diameter value is already in the Tool Table." -#: flatcamTools/ToolNCC.py:1575 flatcamTools/ToolPaint.py:1355 +#: flatcamTools/ToolNCC.py:1566 flatcamTools/ToolPaint.py:1362 msgid "Delete failed. Select a tool to delete." msgstr "Delete failed. Select a tool to delete." -#: flatcamTools/ToolNCC.py:1581 flatcamTools/ToolPaint.py:1361 +#: flatcamTools/ToolNCC.py:1572 flatcamTools/ToolPaint.py:1368 msgid "Tool(s) deleted from Tool Table." msgstr "Tool(s) deleted from Tool Table." -#: flatcamTools/ToolNCC.py:1623 +#: flatcamTools/ToolNCC.py:1614 msgid "Wrong Tool Dia value format entered, use a number." msgstr "Wrong Tool Dia value format entered, use a number." -#: flatcamTools/ToolNCC.py:1632 flatcamTools/ToolPaint.py:1412 +#: flatcamTools/ToolNCC.py:1623 flatcamTools/ToolPaint.py:1419 msgid "No selected tools in Tool Table." msgstr "No selected tools in Tool Table." -#: flatcamTools/ToolNCC.py:1708 flatcamTools/ToolPaint.py:1588 +#: flatcamTools/ToolNCC.py:1699 flatcamTools/ToolPaint.py:1595 msgid "Click the end point of the paint area." msgstr "Click the end point of the paint area." -#: flatcamTools/ToolNCC.py:1976 flatcamTools/ToolNCC.py:2964 +#: flatcamTools/ToolNCC.py:1971 flatcamTools/ToolNCC.py:2959 msgid "NCC Tool. Preparing non-copper polygons." msgstr "NCC Tool. Preparing non-copper polygons." -#: flatcamTools/ToolNCC.py:2035 flatcamTools/ToolNCC.py:3092 +#: flatcamTools/ToolNCC.py:2030 flatcamTools/ToolNCC.py:3087 msgid "NCC Tool. Calculate 'empty' area." msgstr "NCC Tool. Calculate 'empty' area." -#: flatcamTools/ToolNCC.py:2054 flatcamTools/ToolNCC.py:2160 -#: flatcamTools/ToolNCC.py:2174 flatcamTools/ToolNCC.py:3105 -#: flatcamTools/ToolNCC.py:3210 flatcamTools/ToolNCC.py:3225 -#: flatcamTools/ToolNCC.py:3491 flatcamTools/ToolNCC.py:3592 -#: flatcamTools/ToolNCC.py:3607 +#: flatcamTools/ToolNCC.py:2049 flatcamTools/ToolNCC.py:2155 +#: flatcamTools/ToolNCC.py:2169 flatcamTools/ToolNCC.py:3100 +#: flatcamTools/ToolNCC.py:3205 flatcamTools/ToolNCC.py:3220 +#: flatcamTools/ToolNCC.py:3486 flatcamTools/ToolNCC.py:3587 +#: flatcamTools/ToolNCC.py:3602 msgid "Buffering finished" msgstr "Buffering finished" -#: flatcamTools/ToolNCC.py:2062 flatcamTools/ToolNCC.py:2181 -#: flatcamTools/ToolNCC.py:3113 flatcamTools/ToolNCC.py:3232 -#: flatcamTools/ToolNCC.py:3498 flatcamTools/ToolNCC.py:3614 +#: flatcamTools/ToolNCC.py:2057 flatcamTools/ToolNCC.py:2176 +#: flatcamTools/ToolNCC.py:3108 flatcamTools/ToolNCC.py:3227 +#: flatcamTools/ToolNCC.py:3493 flatcamTools/ToolNCC.py:3609 msgid "Could not get the extent of the area to be non copper cleared." msgstr "Could not get the extent of the area to be non copper cleared." -#: flatcamTools/ToolNCC.py:2089 flatcamTools/ToolNCC.py:2167 -#: flatcamTools/ToolNCC.py:3140 flatcamTools/ToolNCC.py:3217 -#: flatcamTools/ToolNCC.py:3518 flatcamTools/ToolNCC.py:3599 +#: flatcamTools/ToolNCC.py:2084 flatcamTools/ToolNCC.py:2162 +#: flatcamTools/ToolNCC.py:3135 flatcamTools/ToolNCC.py:3212 +#: flatcamTools/ToolNCC.py:3513 flatcamTools/ToolNCC.py:3594 msgid "" "Isolation geometry is broken. Margin is less than isolation tool diameter." msgstr "" "Isolation geometry is broken. Margin is less than isolation tool diameter." -#: flatcamTools/ToolNCC.py:2184 flatcamTools/ToolNCC.py:3236 -#: flatcamTools/ToolNCC.py:3617 +#: flatcamTools/ToolNCC.py:2179 flatcamTools/ToolNCC.py:3231 +#: flatcamTools/ToolNCC.py:3612 msgid "The selected object is not suitable for copper clearing." msgstr "The selected object is not suitable for copper clearing." -#: flatcamTools/ToolNCC.py:2191 flatcamTools/ToolNCC.py:3243 +#: flatcamTools/ToolNCC.py:2186 flatcamTools/ToolNCC.py:3238 msgid "NCC Tool. Finished calculation of 'empty' area." msgstr "NCC Tool. Finished calculation of 'empty' area." -#: flatcamTools/ToolNCC.py:2222 flatcamTools/ToolNCC.py:2224 -#: flatcamTools/ToolNCC.py:2916 flatcamTools/ToolNCC.py:2918 +#: flatcamTools/ToolNCC.py:2217 flatcamTools/ToolNCC.py:2219 +#: flatcamTools/ToolNCC.py:2911 flatcamTools/ToolNCC.py:2913 msgid "Non-Copper clearing ..." msgstr "Non-Copper clearing ..." -#: flatcamTools/ToolNCC.py:2278 flatcamTools/ToolNCC.py:3060 +#: flatcamTools/ToolNCC.py:2273 flatcamTools/ToolNCC.py:3055 msgid "" "NCC Tool. Finished non-copper polygons. Normal copper clearing task started." msgstr "" "NCC Tool. Finished non-copper polygons. Normal copper clearing task started." -#: flatcamTools/ToolNCC.py:2312 flatcamTools/ToolNCC.py:2592 +#: flatcamTools/ToolNCC.py:2307 flatcamTools/ToolNCC.py:2587 msgid "NCC Tool failed creating bounding box." msgstr "NCC Tool failed creating bounding box." -#: flatcamTools/ToolNCC.py:2326 flatcamTools/ToolNCC.py:2609 -#: flatcamTools/ToolNCC.py:3256 flatcamTools/ToolNCC.py:3642 +#: flatcamTools/ToolNCC.py:2321 flatcamTools/ToolNCC.py:2604 +#: flatcamTools/ToolNCC.py:3251 flatcamTools/ToolNCC.py:3637 msgid "NCC Tool clearing with tool diameter" msgstr "NCC Tool clearing with tool diameter" -#: flatcamTools/ToolNCC.py:2326 flatcamTools/ToolNCC.py:2609 -#: flatcamTools/ToolNCC.py:3256 flatcamTools/ToolNCC.py:3642 +#: flatcamTools/ToolNCC.py:2321 flatcamTools/ToolNCC.py:2604 +#: flatcamTools/ToolNCC.py:3251 flatcamTools/ToolNCC.py:3637 msgid "started." msgstr "started." -#: flatcamTools/ToolNCC.py:2518 flatcamTools/ToolNCC.py:3417 +#: flatcamTools/ToolNCC.py:2513 flatcamTools/ToolNCC.py:3412 msgid "" "There is no NCC Geometry in the file.\n" "Usually it means that the tool diameter is too big for the painted " @@ -15636,25 +15636,25 @@ msgstr "" "geometry.\n" "Change the painting parameters and try again." -#: flatcamTools/ToolNCC.py:2527 flatcamTools/ToolNCC.py:3426 +#: flatcamTools/ToolNCC.py:2522 flatcamTools/ToolNCC.py:3421 msgid "NCC Tool clear all done." msgstr "NCC Tool clear all done." -#: flatcamTools/ToolNCC.py:2530 flatcamTools/ToolNCC.py:3429 +#: flatcamTools/ToolNCC.py:2525 flatcamTools/ToolNCC.py:3424 msgid "NCC Tool clear all done but the copper features isolation is broken for" msgstr "" "NCC Tool clear all done but the copper features isolation is broken for" -#: flatcamTools/ToolNCC.py:2532 flatcamTools/ToolNCC.py:2817 -#: flatcamTools/ToolNCC.py:3431 flatcamTools/ToolNCC.py:3814 +#: flatcamTools/ToolNCC.py:2527 flatcamTools/ToolNCC.py:2812 +#: flatcamTools/ToolNCC.py:3426 flatcamTools/ToolNCC.py:3809 msgid "tools" msgstr "tools" -#: flatcamTools/ToolNCC.py:2813 flatcamTools/ToolNCC.py:3810 +#: flatcamTools/ToolNCC.py:2808 flatcamTools/ToolNCC.py:3805 msgid "NCC Tool Rest Machining clear all done." msgstr "NCC Tool Rest Machining clear all done." -#: flatcamTools/ToolNCC.py:2816 flatcamTools/ToolNCC.py:3813 +#: flatcamTools/ToolNCC.py:2811 flatcamTools/ToolNCC.py:3808 msgid "" "NCC Tool Rest Machining clear all done but the copper features isolation is " "broken for" @@ -15662,11 +15662,11 @@ msgstr "" "NCC Tool Rest Machining clear all done but the copper features isolation is " "broken for" -#: flatcamTools/ToolNCC.py:2928 +#: flatcamTools/ToolNCC.py:2923 msgid "NCC Tool started. Reading parameters." msgstr "NCC Tool started. Reading parameters." -#: flatcamTools/ToolNCC.py:3906 +#: flatcamTools/ToolNCC.py:3901 msgid "" "Try to use the Buffering Type = Full in Preferences -> Gerber General. " "Reload the Gerber file after this change." @@ -15923,95 +15923,95 @@ msgstr "" "- 'Reference Object' - will do non copper clearing within the area\n" "specified by another object." -#: flatcamTools/ToolPaint.py:1381 +#: flatcamTools/ToolPaint.py:1388 #, python-format msgid "Could not retrieve object: %s" msgstr "Could not retrieve object: %s" -#: flatcamTools/ToolPaint.py:1391 +#: flatcamTools/ToolPaint.py:1398 msgid "Can't do Paint on MultiGeo geometries" msgstr "Can't do Paint on MultiGeo geometries" -#: flatcamTools/ToolPaint.py:1421 +#: flatcamTools/ToolPaint.py:1428 msgid "Click on a polygon to paint it." msgstr "Click on a polygon to paint it." -#: flatcamTools/ToolPaint.py:1441 +#: flatcamTools/ToolPaint.py:1448 msgid "Click the start point of the paint area." msgstr "Click the start point of the paint area." -#: flatcamTools/ToolPaint.py:1506 +#: flatcamTools/ToolPaint.py:1513 msgid "Click to add next polygon or right click to start painting." msgstr "Click to add next polygon or right click to start painting." -#: flatcamTools/ToolPaint.py:1519 +#: flatcamTools/ToolPaint.py:1526 msgid "Click to add/remove next polygon or right click to start painting." msgstr "Click to add/remove next polygon or right click to start painting." -#: flatcamTools/ToolPaint.py:2017 +#: flatcamTools/ToolPaint.py:2024 msgid "Painting polygon with method: lines." msgstr "Painting polygon with method: lines." -#: flatcamTools/ToolPaint.py:2029 +#: flatcamTools/ToolPaint.py:2036 msgid "Failed. Painting polygon with method: seed." msgstr "Failed. Painting polygon with method: seed." -#: flatcamTools/ToolPaint.py:2040 +#: flatcamTools/ToolPaint.py:2047 msgid "Failed. Painting polygon with method: standard." msgstr "Failed. Painting polygon with method: standard." -#: flatcamTools/ToolPaint.py:2056 +#: flatcamTools/ToolPaint.py:2063 msgid "Geometry could not be painted completely" msgstr "Geometry could not be painted completely" -#: flatcamTools/ToolPaint.py:2085 flatcamTools/ToolPaint.py:2088 -#: flatcamTools/ToolPaint.py:2096 flatcamTools/ToolPaint.py:2399 -#: flatcamTools/ToolPaint.py:2402 flatcamTools/ToolPaint.py:2410 -#: flatcamTools/ToolPaint.py:2898 flatcamTools/ToolPaint.py:2901 -#: flatcamTools/ToolPaint.py:2907 +#: flatcamTools/ToolPaint.py:2092 flatcamTools/ToolPaint.py:2095 +#: flatcamTools/ToolPaint.py:2103 flatcamTools/ToolPaint.py:2406 +#: flatcamTools/ToolPaint.py:2409 flatcamTools/ToolPaint.py:2417 +#: flatcamTools/ToolPaint.py:2905 flatcamTools/ToolPaint.py:2908 +#: flatcamTools/ToolPaint.py:2914 msgid "Paint Tool." msgstr "Paint Tool." -#: flatcamTools/ToolPaint.py:2085 flatcamTools/ToolPaint.py:2088 -#: flatcamTools/ToolPaint.py:2096 +#: flatcamTools/ToolPaint.py:2092 flatcamTools/ToolPaint.py:2095 +#: flatcamTools/ToolPaint.py:2103 msgid "Normal painting polygon task started." msgstr "Normal painting polygon task started." -#: flatcamTools/ToolPaint.py:2086 flatcamTools/ToolPaint.py:2400 -#: flatcamTools/ToolPaint.py:2899 +#: flatcamTools/ToolPaint.py:2093 flatcamTools/ToolPaint.py:2407 +#: flatcamTools/ToolPaint.py:2906 msgid "Buffering geometry..." msgstr "Buffering geometry..." -#: flatcamTools/ToolPaint.py:2108 flatcamTools/ToolPaint.py:2417 -#: flatcamTools/ToolPaint.py:2915 +#: flatcamTools/ToolPaint.py:2115 flatcamTools/ToolPaint.py:2424 +#: flatcamTools/ToolPaint.py:2922 msgid "No polygon found." msgstr "No polygon found." -#: flatcamTools/ToolPaint.py:2138 +#: flatcamTools/ToolPaint.py:2145 msgid "Painting polygon..." msgstr "Painting polygon..." -#: flatcamTools/ToolPaint.py:2148 flatcamTools/ToolPaint.py:2463 -#: flatcamTools/ToolPaint.py:2653 flatcamTools/ToolPaint.py:2961 -#: flatcamTools/ToolPaint.py:3140 +#: flatcamTools/ToolPaint.py:2155 flatcamTools/ToolPaint.py:2470 +#: flatcamTools/ToolPaint.py:2660 flatcamTools/ToolPaint.py:2968 +#: flatcamTools/ToolPaint.py:3147 msgid "Painting with tool diameter = " msgstr "Painting with tool diameter = " -#: flatcamTools/ToolPaint.py:2149 flatcamTools/ToolPaint.py:2464 -#: flatcamTools/ToolPaint.py:2654 flatcamTools/ToolPaint.py:2962 -#: flatcamTools/ToolPaint.py:3141 +#: flatcamTools/ToolPaint.py:2156 flatcamTools/ToolPaint.py:2471 +#: flatcamTools/ToolPaint.py:2661 flatcamTools/ToolPaint.py:2969 +#: flatcamTools/ToolPaint.py:3148 msgid "started" msgstr "started" -#: flatcamTools/ToolPaint.py:2174 flatcamTools/ToolPaint.py:2490 -#: flatcamTools/ToolPaint.py:2680 flatcamTools/ToolPaint.py:2988 -#: flatcamTools/ToolPaint.py:3167 +#: flatcamTools/ToolPaint.py:2181 flatcamTools/ToolPaint.py:2497 +#: flatcamTools/ToolPaint.py:2687 flatcamTools/ToolPaint.py:2995 +#: flatcamTools/ToolPaint.py:3174 msgid "Margin parameter too big. Tool is not used" msgstr "Margin parameter too big. Tool is not used" -#: flatcamTools/ToolPaint.py:2232 flatcamTools/ToolPaint.py:2559 -#: flatcamTools/ToolPaint.py:2737 flatcamTools/ToolPaint.py:3051 -#: flatcamTools/ToolPaint.py:3229 +#: flatcamTools/ToolPaint.py:2239 flatcamTools/ToolPaint.py:2566 +#: flatcamTools/ToolPaint.py:2744 flatcamTools/ToolPaint.py:3058 +#: flatcamTools/ToolPaint.py:3236 msgid "" "Could not do Paint. Try a different combination of parameters. Or a " "different strategy of paint" @@ -16019,9 +16019,9 @@ msgstr "" "Could not do Paint. Try a different combination of parameters. Or a " "different strategy of paint" -#: flatcamTools/ToolPaint.py:2289 flatcamTools/ToolPaint.py:2625 -#: flatcamTools/ToolPaint.py:2794 flatcamTools/ToolPaint.py:3112 -#: flatcamTools/ToolPaint.py:3291 +#: flatcamTools/ToolPaint.py:2296 flatcamTools/ToolPaint.py:2632 +#: flatcamTools/ToolPaint.py:2801 flatcamTools/ToolPaint.py:3119 +#: flatcamTools/ToolPaint.py:3298 msgid "" "There is no Painting Geometry in the file.\n" "Usually it means that the tool diameter is too big for the painted " @@ -16033,64 +16033,58 @@ msgstr "" "geometry.\n" "Change the painting parameters and try again." -#: flatcamTools/ToolPaint.py:2312 +#: flatcamTools/ToolPaint.py:2319 msgid "Paint Single failed." msgstr "Paint Single failed." -#: flatcamTools/ToolPaint.py:2318 +#: flatcamTools/ToolPaint.py:2325 msgid "Paint Single Done." msgstr "Paint Single Done." -#: flatcamTools/ToolPaint.py:2320 flatcamTools/ToolPaint.py:2830 -#: flatcamTools/ToolPaint.py:3327 +#: flatcamTools/ToolPaint.py:2327 flatcamTools/ToolPaint.py:2837 +#: flatcamTools/ToolPaint.py:3334 msgid "Polygon Paint started ..." msgstr "Polygon Paint started ..." -#: flatcamTools/ToolPaint.py:2399 flatcamTools/ToolPaint.py:2402 -#: flatcamTools/ToolPaint.py:2410 -#| msgid "Normal painting polygon task started." +#: flatcamTools/ToolPaint.py:2406 flatcamTools/ToolPaint.py:2409 +#: flatcamTools/ToolPaint.py:2417 msgid "Paint all polygons task started." msgstr "Paint all polygons task started." -#: flatcamTools/ToolPaint.py:2441 flatcamTools/ToolPaint.py:2939 +#: flatcamTools/ToolPaint.py:2448 flatcamTools/ToolPaint.py:2946 msgid "Painting polygons..." msgstr "Painting polygons..." -#: flatcamTools/ToolPaint.py:2634 +#: flatcamTools/ToolPaint.py:2641 msgid "Paint All Done." msgstr "Paint All Done." -#: flatcamTools/ToolPaint.py:2803 flatcamTools/ToolPaint.py:3300 +#: flatcamTools/ToolPaint.py:2810 flatcamTools/ToolPaint.py:3307 msgid "Paint All with Rest-Machining done." msgstr "Paint All with Rest-Machining done." -#: flatcamTools/ToolPaint.py:2822 -#| msgid "Paint Single failed." +#: flatcamTools/ToolPaint.py:2829 msgid "Paint All failed." msgstr "Paint All failed." -#: flatcamTools/ToolPaint.py:2828 -#| msgid "Paint All Done." +#: flatcamTools/ToolPaint.py:2835 msgid "Paint Poly All Done." msgstr "Paint Poly All Done." -#: flatcamTools/ToolPaint.py:2898 flatcamTools/ToolPaint.py:2901 -#: flatcamTools/ToolPaint.py:2907 -#| msgid "Normal painting area task started." +#: flatcamTools/ToolPaint.py:2905 flatcamTools/ToolPaint.py:2908 +#: flatcamTools/ToolPaint.py:2914 msgid "Painting area task started." msgstr "Painting area task started." -#: flatcamTools/ToolPaint.py:3121 +#: flatcamTools/ToolPaint.py:3128 msgid "Paint Area Done." msgstr "Paint Area Done." -#: flatcamTools/ToolPaint.py:3319 -#| msgid "Paint Single failed." +#: flatcamTools/ToolPaint.py:3326 msgid "Paint Area failed." msgstr "Paint Area failed." -#: flatcamTools/ToolPaint.py:3325 -#| msgid "Paint Area Done." +#: flatcamTools/ToolPaint.py:3332 msgid "Paint Poly Area Done." msgstr "Paint Poly Area Done." diff --git a/locale/es/LC_MESSAGES/strings.mo b/locale/es/LC_MESSAGES/strings.mo index 5c8ff10154a7b2dab16b4314b873e38e9272f3b4..8750d6f21cc726fe149359fd147c7fe837136b0a 100644 GIT binary patch delta 87494 zcmXWkb%0hy+sE;u+Kba!`mw{*80x{+>??ndd5E(t*t9uSa5X^@bR=li>_ zdH;AnGjnR@nrr5qU6AMcsU&~xPU_!G5H`o-|1y5%d8x2?8_z2e&-0oeQLE>b4up7V zu?&8LZEz^w!qnI-EW}HJgE0fn#!R>y^WaU)g>j?Uc_mTDn_wKz^F5zJbQ-?JxH!+% z*I+E_TQN57cgN2lef6$6A7V=C|6p>A7d6C-hS^cq=S3YaiDB3jlVU4O#Phv@6m-E9 z)QPj5TTwSWi^=c-CcrPK8zhLP8}J}h1WKXKYl;c6uWKLgT#o9{0gQ>KRpkpZ8a3zX;)i(cu@b7jF@A_2Y`8>&lBZCD5U(vZLyhbp4#3h0ZRES~1ocgc zLcDU=FL8($fxA)ldsrE>CJFIMVsGq*Td@|VP8#CX!R}Zde@g0ycvUEbB@6LtV@<4& zOHd>K2Ll*8xy@O8)Lf@Rt%^ce4I817bOq}CZKx3Mz(RNg6XOSrit$p|`AK~Wx*!vd zz-*{wT#qquJ1SZBJ5Qo+d_>I*IO@T_pw9cl`8VqP_o(xtr?TfHG<`3e zf_jz{b;IJQ6Dzp(+Ni8;g-Ng%>b&u&^QNO7xX87yL!GxBb>Gvd0bE6O@D5hNXBe*a zUpTd`^CqYZ`eIfbg;j9_Dv91=cWjp?#4C&!QArmwZHQL_YhqcPg1@o+E}&M$s&uw$ zuAn*)ExipWAx3KbXQZG54e?)Wi|TRn47MCQqCz+Xi{m8BfhRGTq^PYsc1D}J?5K#8 zMQvcUQOVcE)kk1Q>I>12pb(NN#LI^{QK4yr!I7hG@D`Oc@iJTJGof-M7iwxMqBfpJ zn46LRjw7f?&1zFL-Z|5`7?o>lv$Fox(;YNu!#RqI#P9CJJGg@SQ&dD|WV0=L5o)S- zA&KstK&_(N+3m*nQRlzHaQuWCNa_fSXd%?|szvy=j$6_Yg@)m%cfc4_5-mktxC^y2 zUc~-*ADd&d9Bu=`?9}f$J5Vjw3M(ah!zf zuma}KV-7)WAcs()KZ(kXtC#^FIlqdu9LR$TbxG6!s$m0c<&OJ1C@7RiUBe~JLj6xH zgVFPbcx|vMs^=R~?e|e3&XO<0%Z!nzjxdwjo>fTp8p?e#8HdcRK!GeBp#~giBTa=@9McwAuWcQ zvTCT@XyNLe-0{Jv2Tw#@KfM_1Up@Pd2D!!^*zP=tdhi*nix*HgNMGD;kPWqe6hL*X zoNKS`>djFd``Xn9qgKf{)PUC)XZ`C2KhdBOpF@TEBC12zT>ZZD8ERzjuqB3+un4tA zb*v-m`tGO)4{-Hyu0GAxm$>>`pMvIeH!39OQ60L5nemaU$1Q0&k{Wg699RyEqxOLj zsOx87I$VtE=ufCsa~k!WKTz+CS9lBkSfxU|brc?>A~2`4g=PWjL7P#@dC=9*p(1m` z)gPg9<~=HDy)w45B|;5k8LC5DFdJUPwD=Ljwf<9C(bDs;xf4UJS1s43$?8wWIYzt@oLz9NFdSH!&;qK$Q@$H0D5URNXNGv7L_xv(O1aA zs@erfP@!*x8bL=?1iGWLdK_w*O~ZQl9V%ikQ0INZj+nTbO~Ei!J#F<6uM&>KT6iA2 zW11SQ|MC>3)UeQ9M9tYd?2Dah+K0$>tU^6=En9BA@HgrMuq#%t9pW{?-PkjPAI<87 zc;~2(svF|{gSG3~Pe>K&^C`#i)A%#(1sk&dwTwa=nH8}mCrrYLwExvO#9M}an^;5= zH?;_)LPaDSDq?w2xlsnSvDA0Il|DyvVq1HYoy>jPAF zf5OI?sF@{WchnpX#IZO5bzYq2_72I6+UrZ8lClvhH@-nFztyOY`6no7?yjM3@ES8< ztQNLzbE7V(gQc*ya~tZ0FWvDJgiRlzMNu!YMyTt0ppyAp%!Aud_rHU=wEm;EvYr;e z+#INd5$I!8+<g8A#A7BEl z|7>loN5xTd*c$Z>*cUZd)0}fq*}n)Cy0sV!_oFtbQ?7mv)uI2PrXWf?+ac4U9-PJ1 zyI>ri@AaXe5RF7Va3v~)>ru<|FzP|SqPE&w7#$y?&U=B%g=p>Vr`}|!^BSSfYlZ4~ zXH<^$M-6lY`bx4{6tqLFa~^Xi+(KpZE7T35b+88|LUkw;hGQfa#=5u(C*yi7($RA0 z9;$;;JK1$fQSXKfo!s|-Bn^5{DO3{GM|G&Ta|%XMUxS+4|Dis`5_h&8t~ToYF{r6q zf|`kwf$N=pEBr-+M)b~|82H-Sze0^Xg{x=5M$`+q_Nk~Xc_C_< z?RNE>uKvl@(|57^m&R_KR~?nCdwdElD7?j1Sih@{J;WP=*HFLtXwbv1n~i!oZFlvHsE$6zaP$+iUuyjqM1{B(29ptW!b(&Jj-#^q zuB(4WZCojPSrTSPT~`Lx!S<;0pJD}!);q+TgEg=s-o?^d|JnP5cw0g|uPbW3r|f4x zT6M(M)Q_S@l(Bz^w*cFr=K3>gOHDSww&<*=Bs_zKFfh>Gp2bid>4B|r0=C4zu$I<; z&8}f5Pne3o4W!F$$&|VjaqYd8rpdC0Q4&jDt`E zIgH9FZz$?Pu_-9|Qm6qlqp~(1>IOxzELO$XFQrAO zj;=z@^*Yq@et}w+QAU_CN3i}Cs<(== zk0o#lszYZ`5%~-I;yP)atvChbIeD4Vbb>Ic|z>laT>N3$j z7W-jM>c?y}_{+=V&tA!^POO|{ij4vSJBfQ7aG zw^2}t|3)pljNjS`%~9)q9%^U1hPrXWX=XW8Quakfa3N}LS2=f}mfLaE{%{7BBfp^D zlF!jkMIqL7%hIf<iJyMgSMlt{~5J9o}(TRbC#W# z9#t=iI^NLP87u3ks zqL$assQdityo1W2m#Ebf@aI@h@}si1Br4gep?0|Xs17tkh5l<)&xfPtd;;pcS*Yt4 zV(?vnI&Yox2dqN<05-*FbM3g_mO>~E-JCs9H|T@v&>++U#-biD1(jrTP?1`N>fn0R z{;(T$-6d3R-9k;}Csa{0sGL|6eFfry*j2eO&IxebnEh=J3abmd*Q7 zk-31S@i){1lPuCN68M@$P04qt4Q350Y4@QXco7weN3I_2I|i!tpN4`$Tn-h=s;Hhf zM)kNoDwO?E$utucfn}%%?n6z@30J@1yym=*>c|UJB%&_1h$cZ_4Y?>N^d(XCCa4F0 zjT+$)*FGL~qj{*g+=M#soNK@7>i=K_?NPqBkw>ELUl}#PcBldL{+{)(2Tpbki!e9! z9asVHV|$EPV%a+#^H9Hr*)i5q`|2%-ir_ZX%V;+$Ie*7mA$;efrXXUuWq(=J02VK2 z{c8g`KtnFP?GD6SVf#TIEKGY9)B{IhCftO2;IF9Uy@uNHo}&g7y3$PGOz+H#T9#!| zQ&-)mpgC>iPUwi*hz6iSHVuQz3l-|!u6`PoBUezX<1T6k{fN3>>Q(lD9H{FGp^~pM z>VBP28+c*cHuA7W{;4)Olwxb?+1{I;J z?)YPC_q|UP_z>`7uCdU>L4`0GDyy@iMiz-5upXYrnrrQN>UB2a%&0jofLealF)Ox4 zP1QuyMmHTb1+#F4*8gG(N|rL~?R8oa%Tw=;x^O${f<4Zo*pB)+%!rX2%!a7s8|qwu z%B@|fNL%#Ipy z1=QQI3FgH9s3}~5n)}Pn*O-}lf~~B7Wp5D*3UN)$hP_a4v4yAyA8_?Ms1ZilX6I)> zomautJEN|jgnAqPh{f;~YA4OL-BwdU%ul`NcGkZxSV==Tp2uAH9JN8D`N4kbE$keG zy5VkD{|B|vgY~Z@>p+7xo*q~WzsH*R z3^fHMc3SBBp^|en>ISn==PgC8p63{jA5c@0a+hU)Zq({1fttd4sAO&HQ_vI)#xVRA zgEvNH?^4%(8uftl&i|p7**#Z(gBqE)+XnO%YS|@5bvOemiSwb>eF<0hYf;dRo1l8w z9)o*67N^sN$(MAWb-XAl`)gxS?1uV8TZ6hjY`>kC67@EX z#MD~!XhIU`WZu>jV^rl_~rCe+lNLoKt*s1W~wHSiG* z!GecvYPX?s?I8Lp9HpQOPNC-RGHPyLxq9p)wv$DmlBpJI2W*Avz)^SnE-Dhyj#|Xh zqLMThYCxq>tF0>PKJ|{W{?+q#G$>oUpmwZ5?u2!y3-+KodIY=SNi2=|kJ%?#e^k;A zMMYo&sw2}~`&ta<5Ncp&QB(Tx80)_QbMcmjLNruAVK*9s%841Mq*{S`E&qgy&{b@T zZ}A@1IcZZ<@RS{IhS_N!j7qkZSPu`ofP=*7oa3U^4Z5$D2%u*Omy&h^g z^+SzdA?CszsGag2s$>75mT{_|E!py-UP7%ffTK}UF&-6Jeb|$rHJn8)w;QPBdWG5n z8=kWf`k00K0!)X8F#_*mMT~pie$CbpBdISzop;gs8Z%N)e8KKp6f9XXlO0vB;p+WRNjwh~((h4IxW>5;710Z*2;6Y>*O-jwdm$Gs=~AGk zA`5Cc7DU~stg|5oSBa|+Laml5sN_9>O3F8=`_#T<*SA8|`?~rl=UnvJgT3_>lE4!OML|@#1F7M#=30h*GBDpgHg%28Wrg?ms$S` z$$c8qgz)u>8exjxZEmw-HtO|J?ZZ*YHwE=sJ`XkWUr-~Ae#K0RQK)A|MKTBK`ogGv zq9SVG^{%k~wXQqTAbnKG=c8`05%s|Bs0$7_e?evUUDWdPuG)DiP!G(6dO1a6Zmf?v zaSWEg?brZc_!QbusQ5oSaV;vDu3{M8LXGsEGxarlCp1LuXsuEE!a&p%EXMLg@=s@` zKkRMT<%WIzu0q{+E$ZFkZ=#^A-Gv(QA>4u|Fc~)*aFf?4PP-N2HNz)=+Ao(Y-wE-4 z;=ILJnD!QT?Yg=5LcATcSG;c#`GndZqCK$CCq+dxBQj9m%S}NeDTwM(4R=B#)P-$P zq3(m4qG=dhrl_Pmikj2wsL(&caQp}Lpu`XDcsNd@o)b0T1DI6n{{#hf;3g_b-k@?I z@W?ul6xE&uCtv|o2oGX8Jc^|-+F$lVY9;3k)BvudBKsHz;7e34bpD&?YW>fppa*P1 zEyI1Nz4{z#L>Eybyn*WZ-CsS5)MNqwc!^eLZLu z1wCLLY6^CuZg2>-tS(`8yp6iSS5NGZYO>%I>U~fT`hwFj_ESsZ?@?2?3N>{{P!GP2 zitxjytbg_FBMo|K#Cc{tO^ce_yr|_>6^med)cgH=R0mh19=sbhB_}Wxe?|@DJSt*W zUHvwy1CO2Wp0WNFvcPleaR$^0*-;}ch)SY5?s#(yr``@Vw_{KpnvMEF<2%$`??ZLy zFe-v4Q2W7e?)ZDuGXKw~ppi#;VIxn1s%Jxuuqf(=)lnU(i`p?;U>@v?I)5eVfjh7u z?nUL+ON_wYFKsFoqawQ(bwB?S1#O`>P*aikmHjDIR@_Xz6KW2VytchPA1X49QG0n` z)Q87B%!E5oH@@zCfa>5&R1SpxV^fk6nL6LgNI@aYi<+~dm=nvR-uHb_p<0NVnq{at z-h@itt(X;mM1}YU=0@+0OHOD?G)Ze0#axZ4aQ>c(X$7~qwU5GarBXNl4Xaj{onE8E(cN~|X zLfGM7dkyzO<-%B0q~>8IormS{A@;+F5BA`tsEBQL?m$IuKkB}xoWG*48{VX#IeOrH zhuROKf3%+g6Qh3Qs*5}ETRespKG|PVjrrLkG6!|PC8+O*HK=6WkD7u@sGNCki+K3A652z6xMs@TY>Vel#*FQ&H?|rd)0@M^|KwVc9 zwVzb{;@cdLprIEH8&JzF6)9F2(_;Z_hFT>vP;-46yW>^Vva1*p8th;-REX=MI@$u2 zBVAp6C@P00qB_o>nA(X;P&eL$>gj&e7WpeG*&bpSe2E%C^H8%h>UclYgNLIYJkizX zp_cV>)ctp$I(*F4{nHfGldGtn-A9G+88*Z(m<1aKLW4;+9JP*5pqA4uRF;Q@g$CDu z1nT8f2el0QVs%`BTBa{h9Y`J}R8z$KQ_u#J2Nn7nsE*V_-MBe6#?h$t{s(Gq|8%}` zhDEiJCUIs%4Wu|~fHhFb+0@nB24(&Aq@d6Za|gzwLN(jD0yT%*Q6oNrnu3R@b^RJO zRk5Pkb!jnzdM?yJnxZ<;4z*MELS6SQhHCwi(L;lOVW18wC#Iv4 za1CmwyM@|NLStA2bD%n21vN#DQ4#2kd2ke##UHQ?zC}M5g~BmIgRj|6sHqr(fxUnN`sVIaBeKk~0v_$1hFIV4y zTGt0qAwG^;X7^Az6`I^enjE!LhP!%pjIQ^8WU#xxEg%l`JDs**ed)FLmudpl)y)gUb`OYF@eaFQ_Stm(B)|3H6);u3i(h%v+}O z?XA>@hHx4dp^|GqDgy6NHx5Z}Ba4FzsaHmI_%3Q0Jwwg?8&r~hmBDt>G^k`OhU!og zR788Arfj(H4opRbbUCVLTTu}>h7ouT(_z$%*0HRptvW9b#agJ2{)~FiRV<88u?l9+ zWcTTXTE5@8x__90cC4qU#Yzmr}Ycc3pYY z{i>nvU(eN7Avx}CLL%UMTPWy32T>6?ZU?+yQSbXZs0Tejh4!s$kDk?ze}$T=c&HAh zKqX@)RF0H($LpZJFPfq5*9PNj{r9GzuhP+|3)Z+3cB7K+fncTgQz*WhRTI6s2e8CZW~ip)Qu~l zMpW0;8#~)Md!X(&7!}z$s0Xh=MPLj1>e){eG?KHp0`K4h92a2^>Yl?!J_wuBJ|4B_ z-$O+%T~1qG6)+q1me>j>pmx$nSO%lzvW=+<>N-Cc>t7>VL4%gbZq(fUj%o2FYNv{y z+d`NGl}s5>?fp^L4?#U>8Y&q#qh3xQQ4uJT#|GE{wM@IBo--;B>t7FEOhY%^hyMlm zL+8j)?*R2I1ww;=&GtSj)NKpe*4r5s%K4}fuf$S#9t&WcLiU<2kL#$9$MP6i*c^ab zp8I?X3gthj5k(fUP!>dGbuH9`nqV-AusG|dk2}7lsO^w@P|0@$b^dRt4&O$tnun-W z_Alx@ub5ruC#0Z|q(UWCKGZ5GiAs`MsCC@RwRdvugHWNLfVzG$>Rs}q^E~Rok5Ebc z0hMEMirWA)B1!3cB`D}Y)lfZahU!2M)QEl5J79`)4%VaoJt{)4P|NZY>ik$GECR_; z9n6T@n2KOlY>wJV$71mB|F5B-9_~f;_&n-Hf1+;u)cFa&rXH)LMWjC})Zd^YHxaeW zW}|XyxvL*SMd&=LL-$dU`k=bjf1*;BMA=XssfT&76Y9nbQ4d<>+=iNx1E@$HM_u>3 z^KaMwAL{zJr7glKPy@@3nuia-uXY*eh-yQZ&4lljKwfU z8N03ms=X1aW9?k~K&(oABC^Q5%Vk*qy3th{H21eqJ$!}Ai7%)*j$77lm>jiiGNEqJ z5*6~cs1fx--ESPK15;50Sb)0EO6O)&````m#Ou71v)a1}Kb_fZjf zhsxq;6|9~I75dVsWF3aejmfAH&O+^kE3paQ!8};JqIJaYP9Y}^{ZJ2Dj=I5*s2=Y} zZI!1{8`M2isQ*HZu5lhZCYY8jgxUCR7ItqNbz_Dw0((j^6)Gg9ZM! z8|nswP$L+NdhlXYa;`un(N5IJ520>!($%jxZ=yDw`>r0nszop^>bmTxRS~JW)_(;G z3RQJf1lpmpdn{@>PDG99dsLFHKy_prs-yc*8_KWFr|x*PYBuutsPj^xB9I@IlqJv) zr_h9gIxqwkvKgpIEJt-{3u>enQ9Zwny5SpChhkT^_LNwSdT!M9L!A>a7xg*V7ms0e zEL?;2pN+!U8g{`J)Pwe;dU_VsvEMM51E{%wh02i+sPkjgG?Sw`n9bEopgK|ml><#t z*LQGsugUt)L_>cXv}Z3ueMsymhU|51!#Rxl9>`SBI?@)^^O2|sOhJWwrgJGO7dE^4 zZd8X)pd#}tDk67X`#b!edRTqyh`)k@k}G-x3u$a;Dpa;cpl+BK)sa%D5m&_m*bWQf z0<44=F*_!2Xj^r8)K2;hD(P;cHmuLcM&^4(8rg|$u_6Z+VR^iRT1HtK+mBvVF@pLS zEEB>{NZ673t0tCAO`3)V{|T4XSe5p7sQZ;|=3Y7&PW>`g#y40&>%U}kOSUmslmk;y zBRYk8*?281dyAlU!p^AWHX0TB#i&rPaqhx+bnqlD!mBOq{{33pdEcO}n~E{D{^wE9 z94*Ii+=&X|6;uR5+t|-~nNWLpS!p^l$Lt)k~R9Fw;V4gQ*bzOz<48$i_dmRkj| zH0Sj}Us?SFg&g<*nG-Kz2fJZ$)OzlS%I57@1g|+0b+lDc6OYn95)WgAPNCjjjMmwX zA3@#!4JxAPzqSrF`OMnJ`^X&UM$~dY+J*J66K~Vd3;#xCeY39i;I^m-^hB+aA*dVrI0hHs z2u#z>jxRxVbft4U>fLb&b>Cl|*Dw|J+dc*Lmq4rJ_U@AcfMY_5PBNdr{2wnI%# zchr>hMJ4SBR0LMNok5NK3Nn?x_YVanN7P=H_4!aQp_ZtPrYCC7 zC!jj85Ow3F&Ml}9l7py-UBfc(qP7i>f2#1YhpuA@5s z6!n0QsQbhkWl5bBl^f|%>%TB+Io3j5*LIW}X)hX-Ji{>`&ce)i64jAss1f~xio_>p zn$fm=OJhdbTcSSQMq?MtUgT3y$Ty%ux*c`F8Pu}7fa>}GP#t)I zzv6qGPqLjIV@cUzTxf7lUyfxseiuJsrtzWP7fe6Fj;Eg(8vIKr?NCYUU!$Px{_HF< z$$k^^4Nj;1Z@h^^Cx?35vFVghZ!`~%JvB7=ADPbh)*|o#dviQ&8h^6E&(Lz3hF17L<=kj>S7cgGy_}FK5wCo;2j>OUU-rH zGU@|r2W|8nKcaDdf9y|v<6_(4(tmGn&AF)GJib7^#9l7ZcLVD$VyS%!4Z>L*xPf`F z_cHsiSdO)*KSzzQ)bh~af3m#|b5f7HA~g87U`n8_JA-BLBWA@CEA3aX9Z_%Ft*9Kk zt2)p3lCH9!bgE*0>OF8Cu0SPWvDLO-+u~~Kd+`RgSz~{0SZb|}XeySY{Ujz}q_Nh8 z2LF;-n)UW4sQpkI&^fG$**38LwGj-W&=`NgsXDMRH27Dgc42Ail{VRwOu&}ZPoj3T z%$x1HI@pK$dhCU%x7f(P#SzqZ;bSbk)xIY(k{AuB_u9t#FG%484U6zI_Mqnrwuc7) z^{ePV+EzLXHK#w}7A&yCUc>jX4)rgn4~sfG?fgloFQT2ODfkm}VT@hYUKl%3Z@Y{2 zKaIi}8U|t0-R7^jiF)-tcH#$T+r2jOGnkI!Z%{j2(tY+*?PzR6{WboM4fcn6YcR)w z(BR)4yNusZZ*kD3^tw+$bDi%e+dzKC^weKqWlVU;K1Q2kA|f*z%hJB?u;s=R%%by- zSke{4Nb29vz@dK z^+2tLU04aDowD!wTBwLjM!h9Bp_2D+XZ+JvFYIiE8MXe$QP4;?;8OetSK*v9HfP0t zHoIUM+81CNypGED52$5W@~nNHcS9|+@u(eiFGj~>s8w+e3sC>_oK_F(FUfg(Kzq~; zXJI&ALG1_caUo8*V4=?Pi)~c3P^)Gt*2f2^NEN$iAEP6%HT7Se`7c?04k~HiVsQOe z{x#J5Ov6z88wX#uw^aMz>_!7o%k&It*`@#8Mp^^oQ}2x0c!pp@+<*#w=oK>?R$%0{ zu>j7!YPodwf2@BktJ~K?y@S~3y8Wn>plEu{5DqV|`;_sqoiZP{!h!Bm`A^M!T1 z>r2aphf0>-m>ZX(BJm4qJ^zNW@g|nR zC#a6(dT-0J1U8{Q7xhi}0`;6vt{(MYwX^;cQ0T^iGFU8 zY7c*a$+7)M8~Jejn)-Cq13#cT81<7yHW8}hxiJ+M#&mlBH=q!X15xXEJ}ShgQ6sp9 zF){yV``j*tU8pz1Nq7RaBi8xP{?x1&sy-dVaf_?}g3+iyN8Rro2EYG9zu1Elp+Z;z zHHY<49}L}H`)SmOuHtNbfXa!XeDl`83D_NfMF!|gBoEG zXL)BWR0o=(I?z5EfB#v9Uhcp!)D6bD`ZUxC7og5tjk@u6)Cdot=JF_J#6MjBcD;{$A}RK{`?S*T7Fqj z11N$Suq^7jj;QZxF|hZ$`Bzi5m!hkkpSC2)?|=p(3#jb8G$Yqo7becD_Vq|2t&rz3B06 zq_I#VPmemD3l+jrs0h}?&e#qw;8`q>-z5kH--@@92YQ7Q27;@gGe*(+??pk$H^3cO ziAkw%L_P2rs>i>$TniIyc0d@UF9 zDd>WpSQviccn&OW2&I!aaxU3}E~O@&&XxiKHMMU8weG9%t0)b&SD`@|Vkvff5b z$=^=@g)6*8UGNEYgRpE?kBYiM9Mlamp>B}NncrCyb$w}!ij`4YaxL74^{@`c&29r| zgXDtm^`oHd_AxF_M`iU=)B`u6IYGelYfQp?=& zHK>8D$Jn?F6DYfnQ_u~sVt%}h>S>ak)}98_QO|<9aTP3#U!xwp9CgE0sFDAGdhk#9 z6?1u9QooeT&bx*6s6R!Y|MJEwlRFUnQ?T5Tf#9D~HNYjD@C>#0f1B5Kw(Y3w{SB3T zQSw=Y3Zs_cH>mUXpw7F2ie&8kHjr@Cev=I~z_R&S|H}5NG-wBFf|}#5s2=;M5KqDM zxB~TMa{`rQ_fb>x1ofJI=h_n$u$Nd$)VrY|>bz>My&>v;y$i7Zb;H^2zz?Xs|2!tg z2dEBs1?_^Qn2Bmp)aQ0!DU=THOsA9lj0sO8?EP{12SvKHk*ShZLn_-8u3igN+SpW_(pQz8)j--vjJdSKpCHn-(ak*wovhgt>w zQ3KhB8rUUN$NVQ0vQzL%2ZEp55vaLqin`Gx)Ux~z^WjERlKzPrN#Zhr;E&VwFc0;K zI2`w)a->MvfHwlWq3-(>hhge+0dJYs|3V5QX((QvBw@q{@f`J&73`aDPDRW12Uvsl zw3PzEUrcnzn$+*0u8*u7@Y>-Is8A=ZV*049_#xK9@>K)DkJ{OoUhDq_1ud6^)ht<( zV`}QTFe6sSa@ZTS%ywV^kD`+FBo@WXsAP*<-I6mSD#Q_}Y%hfeu@dUKs5RXCKcNaV zq({wVBx>1|MLnY$B(1t_%~O7j=J9$)cq6GwEZLl`pVJ@ z6!f4vsH|>ONIa9cf&P z^{<|OO@kgd8nqmkpgMFAb;Gl$(EfpX@Jq~rQEJ;r^P4=^EMU zsgD}jXw*(P8?{yMMn&KyW+lm^HMYp+@tfGlOQ1&H1RLWZ)P)yOH;UQR%!S&y>Z0bf zziXd>;nX*xMtTkvfmfIhdo{D=x)L>zJJaM5}4#O2 ztECtlpi|4PK<$yKwMO^ zBtq@s*__2tQ&R&K!q%uys(z>&`=}8uLOoy`D&%`n`@zr7JE;5rYx4a!&^nL-dvhQg z>IREYC$2<=ZV##hr(OLISAT*U`4?A@Gbj-JdqU|@Nm>Kd;jX9w`lxrs7!3aXznK*D zpk=5j*oo@-QS6VGQQ2B`u!XEHs)J2X*R^%^fv57ye ze_)6m$c5@@8Ptdypq60=)SRA0_540+IlgxF)I;sM2-J;Bp?1J#k{lX=N2#wGX1VtD zH`ej)=<9)_D5&RiQOULuHTTC*BlsN^ffuN`e2>#H?r`hSQp`_%GivqRMeUR+SY7I9 z1&qL+sP;vuft>JJ|KSua)1bL|gQ55V)q&5bP{$o%FQa6r_5%0=R>EHR5qn^_k@hux z9oJItFe(uIHGQ1X_8o8-HO0?Rk@`5A2WYt^9b*qFh#Fxj)CmnSE%rg3Hxu*XHdM#% zq22{gQ6Wz~)>cJX%tgHh>il6?4!2+pe2qDfKPevJ#cV7f{zdcE(*|NtqA*tQ_b_K~BS#xEnQRNtfD*15w$! z9+jk5P!A4SW~(9tD*MY~73_pc!fnn+7*0Lya$5zZQTxT1<*fhq6!y>%iD_1twNWD& zg#~aEmchH&4KuB@pY3L11?nHLDVAOp@CM={?1KqcTd2ojPU=fhQ+6Je%zv%+ZBLKC z#$H0nP;-?AwYTR$&3zfvl+;CSKuxh2c0=t8Yf-s!5-Z~`uAY3Yy`0jcA{2>wEjL6> zO>>`ul4=m@>vsz3M)Oh2aT#hIZ$NeE6qdppsPj^b zTA-$^t8*ACl2cIwnuq#cSb@R+{%^Z$IEK3LR~&}-P$Ouw#U9uLwKY$1^&edQB5F0f zN1dNyt9>_Q!K&03V;6jcdP&vWX3OyiX4U$CKtVT-yWRHag1C_SB%FbnehB`m#M_16 zQ*ZL4EwlHShkDr^_KxU_IjAo|P1RXc*2mvz11Nv18b#R|Kv;~j7V^*z`aJM6I^XbvL(yo?ubZy@*wnxXpx!9OW& zzMu8qjuTJNpsdb*KzlMjx1%}~{h&=r7F4rzBzrZp0!wLIQukcCxxxqg~L0fC!l>Mkx0qaxuaT#7lEuR6W z%@L>(Pr?As!v?qrlj2L%0Aif6h{Z$QKM868jZw?5HFCc1^`uaghViIuJ%ajVdV#u8 zhM(<|DmyAC3ZOz*-`N4R@eIK1ILWo|Kt<#P>Vdyw0=(~hkHP=_-&kiYRN~{`qmMt~cr10!{-E(BmZqNPyyZx5)UsNPdIuaw4J^(Do5CunByEP_*aze3#Ui!fTiT|3xjk)W29#<-?5Bzd?;`IZngvsF9VuXrFQoP*c$Z^^O>a+WDqoOk9MT zy4C1wZr4+2f2gYJw>N8LsiSj$^zb%D$zuWI_`{EkvS8yr%S8SPtU$s?|3pLVes0Xz~ZD7MO zJ+4G8tCOgA#c!x(`vP^{Thw(i{%5b>Z2x2ZD?2ODph%2Iy)I{9IBr2D*Dt7CxQB{R ztZSC6xv@C)7FZG&Vp;qjDhEN)FB?T=Bpk>CHr_UfLf8~lhR@U=7YhK;Nz zY7S?j*7x_Qj{Sfd;YrkLIfv@#Wz>{?MCDBCoAz!fi&|wpQLDvYOhKVKh06ZBsN_j- z%U&+ooz0w6P#e|()XxpqFdM!`ebJ=;(;i#|b-!k)kxxRcjHZXP{QkK~w}TqdN32Dq>mhDuO=0 z=ck}8wyd*0D#RVJ3l2psw+Gk=-=ZE|^PYu#AZkMzj*7rE)H>gQn(HH|`^UO(_eqV~ zL33hsp6?Zv?p{L_HZQxk|cvYgA~*p+dg{b=@6QWd1@; z!3PY-w2v$aOFv@$Yv=1hgXVrEM&dzK4!l4`B+g%!l-W>oS_a!=BUEVjqe6Zjl{5EI z`$6d6_O{G~Td4QKni&2#;N8ZakA2&T>O8RrHb+Hb2zJ5|s0cm6S?E2rNX$m<11nJ- zJ>`6W8fn-wYtM%IeyD_sY+qC^4MXMF6yFt=VL=*pqC)=^6%p^bbub0$2ANzvm$Qho zJSqaUP!H&cT9yM)5n76hXd&M&A3$9-XQl?`=4Rn!BTp>Eg*i{cnm z*8hZx#C6p9|DvWM=1Z$*L7i6^OJIF$p!GkK!f+ZMVJqzP%3eArQ4#rqld#}x%lgBp zY5`AF29Ek;FPyYrZ9{~eVpk5S7v@ZQ#WTvS9-p{~n`+Q>>_xYmD53Yr2RHTTm{ z`@wS51v@buPoZ|Wzfk8T`qv(i1$BOY%#4*$Q`OTs&bb)1@%)JDz+v=@Q}~lYUQGSL zUP84oxRW_IptATRYJ{&*BZ~FWLY@laP%nt;NCi~Ko4EF_s7MY$J$N)KlFL7`{&ip% z4cb@^VSeWF0qSp|r2K55O!c2VFe_@=6+x}<7O1z`2#krFQ9IopREPHC5&Rj$@Y^pI z!C6?I`oS-(e&3I_VFumg4AH7XY}MhOdUrTI~zZ-dJ2si-+#gOPY1OQ9Fl zt}l(+f_tMz_&ut_cTrR9MGFglXXHZ-$nQfzAzXyI@HA>F-l95`D!O%`1}awuV`bcl zS~Xv=DprgU7R>q?Sc&>#EQj||*JXVFmBlwv4}6VUb|LX>s*<6$+`Ooru?Fh3 z-4(;JFXqyKq}OE`B0x=^1Q)9m?ohmV?)#qIsvuO z>~Boh=r^cjUXF_3DGW{-s)MhS@V|ecx$%_xpghT{R$1vgQ9cp$BHAU$dT`A~1Y3aC|62Nmk(sO8rim5hT>JK{Jbg1&c% zf=;}QS{{GlRD6lr7yNJ=$u(4j{zRSk9F;roP!CR+&gM8RrlVc}^}t5BovG-6Rj4P+ zVCT2R;J^RVgMw}}5;ez*Q6t=inu6a^|LIk}jJAbV&SX2~P%O&vwHS_fu{MTfwq$OA z+H!kgEnI<{@HHwKmt`T+TK~H!=!@h67QlZ|9m<{6_V#M1)iD{>vDK)E9Y-bGHPqC^ z$`;0pj9*BgrXW8m$x5MCM=exDI-(-k4}*XIXEX)fXd3FmL#Sl=8MVP&MLqB(DjB0@ zw{=_ql}wdU$9teUI2tv=<*0pQH)`GgiD~gQ4#I>HtpA)8rbO60HJx5sZ z4+?T%HR^3pbGQlhQhA4wm_Mf_aYxiZrea|{h}xjuVRp=&%R0~$)$t*@d@C%aLD_!- z)uFepo-w!8>!Y%G6lyt5L`7yMYUCSGp*@5e@p)H&iyCoQ9`{;Dg+4zj!sUDl+GuKH zFodWZjYiGc49tORQMvIO_QP0_ZofcXHw_iym8f^dF4P8f!PW1&`bSiU;^wtv_j6Ow z4XU7$tR*UhgHb20N3Du8SOV{%rY3zpOU{a@5RXHxhJ&bg!@n3jFTY)15nHf|TBAC8 zut4xj$@eZ=!An@s4m3c8s53Ukf!Gj#amTY1vg1WD3hh-;>%SH%lFd-7VK6EgzejcC zfNQ^v8gSIYno6IKObVKdjHr=DqC#H{bzxiQIMjpIJ9oPFBd8>NfEszSBDN2d!LHP2 zVt@P(6{&tjZ3EkgQFy-hBZYjp7qwwLL(N^fVwPkDQ2Rqo)P^(&ClSiuaI8XF!ah15 zlne`g{bns?4~RewEFY@lrCob5lvpnzGfd`JdW?HY*Tj@^}t)GDSU!jEgw<26jsGLk`Z-Yo+_+=y*x_L zpqEfB)SL~#aGZlm#+|60>>=v>cc}FnqpIB~H|ltCT!qy!2EIZq(@&`L6IZj26+`7f z)oQ-ou$4Q|8<%om1nMP|u6kJTH>255$v7H2;~!WTE7Y(D&qtlV7B!_?u^8s5X&vZ> z>fl(^)XqUgW}Qz#A>8gf>JD5+_4o#AKM2&a5yi)X)Kj9i*t)12cSf!IL8wShcgJ^O z81-|gkY7UO!Y$N0#(zvfJ&IP_LY)%BsaMAy*d6ELAE*cPs}mOdL#QdJ5J%K?uUpje zYlM10e^iJ^I_IKR)dp8Tf}HPrS19P4?hWe0AXz<2rn;!**a7umA2pJB7>eJaLcRpG zHLr2?&8Ud%M2+|aYGeA<9gkDrBAx_;KmTW;pdQyi%}Eo~2GSNaHRE0Td{h=MLp|`Y z^AswA7f=tni|SaK26kR%)O~WIlCdPF!bX@_$i0=;JT9?yYgsWw6-*+SR81#?orhAA+5bDM$;r~zbm_3Ai;dcEeXe}(3} zJCLY_jVz@z3u?p3hnl+zm=9aJ_L-=WtVHF;Wh{>W;4qAA85aC&xSLV+9Ie8P}fIkYpW-@GY9ItQm7=X zgxWV6qjJOVL7@eO;n)oS!0TAJU0Cp6Fi6ziw$#U{2hZqWH(Y|c(HacL1DF+WqLMdS zN1LjgsJCci=P*=9mLie$y=@e<=O0Cl{0{0tf1#4-9jd3Ho$R~>s40m=b)Xz7luc0k zL=V(;6;3!takgqLkE8_&}ZBaLTjM`A%qBEI&bzT?O zKEOE+6@j^^8*e~G@+j)MGpOtShw8w6REOW7KZru~ZnpJ~#J1G;VR}r{JY!Fed9^*VRG2oPI=g;4$h!uTVJ=rKjai1S)Cs^<@2PZi>^;4Le~Jyo{RL zYt9#_8%6D9%P=`=edk5(Xf-exV$=rH*VVs4CEFC#)GbEk&U(}o?eE3<*A33lp!Izl z%i#yq4NLa6gipL+x!i1hr)!!Fm{dn025zYL8!p z%8diq5wBt=EcK18f;FgB@&l&R$J);nlmkyu$q_c(vNQ>5HKajh^GMX*KLH!zepD7G zB8SwT8nuztK}ATpH4>+yaw_f!dui1}J!dW^)cb!e1+B~dsAX~%HR4yOP?a3X>ImUI zkNU?d9*(k&s`eO*+&nDJd3#Y)^$}xXk+IhC3aC|99kbv-R5C9?U&*wCg0lJ;DulnG zPJD+7aoTbAwc8hU{t48E^Bd;DzfmJjIo?KA7&B9^>gv5w_aBWNa5ieSeHhRB*IXo= zU^k3F^{h0O#)hta9_lT&5tT$gVtTxUy3reVJkCVhIg_CFfpn-Tig4z4mcR(wD^6r? za!}|)gK}UACd8enb$tf)fGf@ysEsJbB%88SIG%bA9EU%mlD61n+hE3`=6V)tOJ9Zc znZm7DiFy=&s)e`)YW*%lCD(h*kF~$GY#)ny@XweFZ(>o5Jb&VT06#GW-8d5}5`|G;G96HJHr6>8mECKwHl9F5D(MUxVFZR#FM*0& zOJ`S9P7OjuU?FPbS%ty%{}Tnx)iu-&@1f@QJt`Mc&a^p?M0KbZX2sSRjuTz`demq8 zK3D$}Q&NA4wJ`Q9`-MddEJ=Ma#?|`&gMx1S1k2)Q+=iuRTaRC%Lirh$d{O3D#4@0! zq9AH{bwE9EIx49*q9S|DwO>Ky!fSUt%3RLV`cF+kNmBr|SNo_??L(EeCj;zMkcpH@)Wf#~KRYPApTVo2E`&OtPPr*{S1QnTE zSQlTQULNHZ+H1NK>W1C19S%V457&?+_x?iV!ei8P-lOjS1$Ey9i&*~w3Kd zp@}R-1Vp7XQWOCZEZ7j1Do7Opk){+u0YMZSSn2=!nK>JxzVG{e=eiERbDnerr%BbNmX{zc|c*AYD5L6ho^)nPi(l8QY7X zM4abkn_mVLy?UVN#ex#pa8PDdO3$1HYk=1k77D&%ugB(~w4^sElPnRG z7EcA`L^KzaYs6wu*6&)y-v)}~PZa->!keH3tgW=|6ai&&x7mKJ> zwn7Oog?bIJJvbMXh(8A%&*@J&z@-UVa8qhLDt0PF_(*V?OO3n(o-14>W+ z4$2&fdfgt%Xz*$3gTMp~p9as%`fvVLgyTgR#oo3Zt^s9TuLoraz68bbRZs#evBBPw zM}gAf_rTvl=R5YD)E#gH^}+AjC!nohALgW}x&yEGPl=1Lc}A3Ty+u0Lt<`toXl! z5?H>?c0jd2S&nTt2koxt4MDo(32*}F2PKg2mEbMK*FttnihwekYk{)f`+_pryr68^ zFR1zk&_(??*buy>_|>-9cU-YS3Nj{w(y}?Aw0J2f0lWrE4{ZR&!Cp|h@;gxG!UItB zi*8jz2TIR00c8j~f{EY&Ro@EA&UXZqAr0Q3AYGVen~jw~xk|MFC4iowOu~3ju8v8d z7+$Av8z_d3g3=Q=z@eaXyS;^v0L4xcC>vEODEiNWO!lB-DFtc428CO}X4LnCvi|Rb z5|F;bc2o?M7B&Q>$J(iSZ&2(E1*Hd*LFu6}ivBDpt7`!$bM19-oUH$MC`g3WciLCI z`k+MU2Rne%z{kOT;9#)wN4BA-Kru8Ibb%%)lWGen0UQJ+@Dre{mTy4`_#r4gntvBV zhJQzS3Np5hz)IjCP`Y{oC|$b)d;&ZN%GkHqZ7vTs}gt@Ho)6vWWqpll!&_Sk~eKoRT+%Kp#|lvUCXlt28XjJbo~q9 zG;k?68!Wfi-YH)Pt5g3Glxs=ReYTxe`_%n^F9_0=;}ix#>B50+4&{{eZnw<^e^o8Yp^oRlT+1cLH6|p9BqXN|1sqzh^*ETmeeNYd|p&0%Z$6 z2+Ha93MfOB`=C9!qCuHd?LnDCeL(4f04Q^5y27=fWe1d1aRn5);NKL)V4hFxF02pA zI*tWh;FF+Cnkk^jy$lWq_kt3j>yT|I2JB6}1Nb~R7aRqa`_w)!%mihw>;`3rJPFd% zLC0?tWO+OUr3cC!wkKO9P{yo6r?MLfU@z70!M(WLD^`GqxQ~KNMS8dj<+4b82Ft&v-gKg@BsA_ z;1qD_F}p{~d>-N0N_`|a6|8*RzV~|#bjkYvk%BnNf5Kh`WkA_DDuWVOV^Ee~EGRwE z7nCtiRQxfjK26~~@MHL|fYZSdCvCgmf-(d@Dtri9@BfROvK>`WSRa(t&>n09J^^+B zSAa717r{pd=V8*< z_P(*}l07L8gEDmAfHIUfL0MJCWqaQ!5B8-V8>A3TVKL|e_klCOt6(p1^cDLgvjuEI z{SvqqEctDO<2!Jt!nIfJA$sAOJsFQFtoNO5XAamJ`7@v#--}ybJyW{&vH@SY7(jHeB^5d#D}5;-e z+dFP$kYyZn)TAI?+tnsGhJv!;OaMh;iK?#y6RGb5W!=~O#nx*BR-qmT%8+F$Tn^Tz zz6X>o{U`8Q@HQydnkm1^oM8RUq97Z{Vo(@sLD`TtfXl&8Kod;5X>U;XKncLOWn(E& zHl%u>==V|>4_2Z+9IOmZ2Bo2^K)Hy02$q)he^@cDD#qW!fL`!7d)C$h%TjNuupcOf z(iBbwW2r9!r6K3Q=fNMqMc}yK?foO)ANCw80m_gx1B24ly(!3Lb`%&1P5|YiGzFBF zy#&hTI0VYpx(5_The4U$=RxU_pFq*m|Fo|aWk9jt9&8Lg4z>dqfFgh5Pu9OEd_v~AYswIgR36e*o|Y$G3vj7AA-Arn$vnAn5jFhUn*#4IIX|katpkQz#9=x>lcjY zI-QOr>LVka*1_W_m_hvyP+I8C<+LW%M1}Lgfza23(twAc$Q8?N%T-etY)wJNv_B|& z_i(TjxDb@(^EMa*ehJD&D0d#GH6%qqnG@B)>0kp;X7wge*bqzsrA5oYPT*nC01M`KI@tOh zMZpNLgsPVXWztpvWpXzJrH6Zf5sNDH|FvTS*b%+D)t&Yu8*mWyE!Fw{sUD6B)o@z>U%zcldu-kZ z&mnLZd=mVkmOaKzYZCzS1Hj49f2w0oK3`p@^;yoZpx7Hy&mO9o(N62u?Jy{-rB;2X zb@hB1Y(%|NOweilPvmhiPU{8aB`^y{p9Z$UeV~kay@pQ5+u#_mC0L=6(>hoT0h>`@ z3&w#LK)IYpH+EWE^5bAv>T5tbSKLta;!T{^510%KQjkeju&Lc89l`z7mx1#8KO>qs zt$V*`o7>CgDkvwKDlG^Qz8@S${Y*={rHxxT9V4hO0A>CE1`Y>%w6<{_xP^K|8>jW( z_k%kr#6rkw>$G;j?cfvC?}K&0;qC06nGMR={|U|qUu^HR_HuA=tlRbClgRk;Ybu1@Q!^)mPwg0;KZ>;5*F zNWFM>r=vYM0hA%w1~v!(0A=fq?qNGh0$WgD4UPl90_TG9J)PF8nr{{QdO7)h5Z3?i z6aomG=q*}9fd$~^fx#jY}D7DbZ>)c)a%4K9Y2E0K-tS@KIXLkk67z|PV0Y8 ze-8Sg2m0Im%V2%#X1r`X+|q%)@bCD8LTj+&0J@&834#NtUmR#prpAM8#Y9lXejzAB z^ED`wGT&gfX7sj#-Kg&!V)sP8q4vhq1FQjorU;UrL& z`z$b4*8hGAa)8J?&uKkaC6n+3bq4f_9rP^3Ci3#2lfX$E?{E; zmw?ipiH*YU^(!bLSvD=>|9_m=uN>YU{CNx&<_>_ zAAm9>1r}R-yW>r;EcLES?4w#D*noN(C=GaZ3F}{$$9V|t!Lp{^Rl`9sI8xzwP|j?# zKnd^!D9h`L!rm|0N2?Gh{Ld9$Qg{p80o_>2#m&mu>y0z#7zF1WSUO!5Hu}P&T-SU=y&}D|S5ojnn!gbfrNt@F_S7ybPLP@7L^8^Hs1k^;@7E z+w-lphpsj#TXjpY8W;!4q#O$xtfswSA6fqg*Et>h6%|K`^-k-19qldqvN;lz4dV9rRps} z7NnyGC^r~!pp3C!)lF633|5AI5zGr}@7T*WKPY+?L0PtK!AfAFqR#-W-~V`xLPZ#x zz&zk-Pz-$y%JR7ZMuNHCwI@vhQ1*iwpj>|IgZaRrpfn%_lpYudz5>nx<#Jy8J$s*- z3d-_+77Vtau!e$Mr!RoAkwm@^155*dX1V+f2EYp&?ZaiCIptN8vSQuObN*8YeXM$(I z@4yjT?Ur@hX0M`^U>E3xw%a{92$UgogL3su0j1~Gf-+e*Y-jz;aybk^B0i@Cu7aZY z6PO$PP2oLI0(I`Nu|6mViXotEDC;GXRv;@&ssrTm5~)-uK^d+mK<_CBZe+m8|Z?bGmLP=>JB z0lRCLg@qqzw3Ah!^bHsMI7krxfsH1k^*THr&%~L+J4Xy)6 zBXA0o%V_&!PRDEDBCreC;&XdXp90EG_CDwVAAm9xNyqK3T?jUzej4lu<~?EGqV)k~ z=-vcn_D7tgr(~Ixqac&81}OLcO~GnlXK)ZW3KTuon~qM--j_#lRVb-+&@_9W=n3;2+>0 z;A7y8)AsUh^MyV89|L7MyA@`Eaj4$8i93zU;i#2K4j5tM5}El@7M?ar|N<0%Y=AhUJ@SRLG= z>R*H6=m$^-AAoXH)6Uv+CK8mMX#@(t6)4NJEhqu>1!b(=pls0-z((M+pfr42kb*?K z7nDhJ6qJjFan8P8*92v(#()xW259XQpcq^OHbUS%Q0C6J=WVAR%GSRtts|8J zUzUhf3a(L%UWAj(4)U6+3x6TyDNKYhG&u#{bn-Vc;G{@$3v@0a^Bv`q(1%g3fc!_$ zPa~TJJp*S|B~p^?1N`8El?p-|l!x_q6M+bFaaz#{=0cR^fN&qona0D9f&MMB{Je{m zSo`ImkhBd;_f=vhB&$6n`5cE8?Xt;^!_Yhgxf6#$)yj|HpMoyuMM(jALmuP3sd{o2 z^@Y&Ssvtth2b-WE=`Vs{tN%yZioksMhEli!t|G{$7@7=jRlT!^*1WDXWfE&RtOVwx zg;kM}>xiVMDJLMCh@HZWe?vKDXb{$uYbYnO^E`#qMmSk1Jp;WPhE`!z{@Bn>>JKpX z0l~#W+eY~%a2a_8`B!u%3LR$)$@S2U!Cp^%j8Z-IIx_3Ab0M$vKgonJ1%s7TZ@h(b zNlT#fr~e!;AY2Cn58?j+{T7BgLvIeP3B23TB4s>DUn=|t-OI?tfFB~?kMcnR8iOB6 zCB>Kc-$t~u$ZNvLhvRBgJ7M&B4E-TIQg6z8;a640h1L++A{hUhENPyS)m6O+vhyiV zz?P&d1RG940+AFvkK=AIxVAV}W8g`Yeuep`it;+V%F1v{%B57#EL1&pO`M_A6(>JZ z{1n;!U?=!Bkq<$iPF+$Nc(R+mh)x0MbNKsn7UQ^zMk@T|lj9lcqm_f2l*cKjH!zqp z^`-tk@*j}LAjc+Xy>=N&xeX4URe`4~ThpP>fmV=uS#*+Q{6EZLu_onIgzh8I3iK$QYc3DD#fmF^;hfr}N0Vv0){(^T`hs|B3uB@Ycc0#O^!Piw6JHgJPAS41u7#^dIP~}Fdv{Si9hx0h$09{xsd5f-9vp9<@LzyLcc6Q zaHVxDQF4CD3!tyS&S`Q4*}7l=WmQk*vI7b_<|=|X7=wW_)HA@@)a5}je}~dBS`3ih zq%406LQ++nzDK}i38DqL20HbTI}G1TaJP`*wC>mhy@&Eq9i5#7wgh=QG5*!)jtCf4 z7>czRl*FHUwNfgAJ2BRj`XY>XNA^4h{{khQg+J0RI%1*SR>9?hUICpr@)>MPk{1(_ zTB*hu*xkkX;~(h^L`mBT8UlC%y4U*u_Yj{$Ny%F;qAJo=GjW`cTpQsf2!~UD zXg&-!K&CT#&tkABj;~O!2T#(gs-;pci{U@vPr}C6*qR0HCuI8~n>!Efmrvlc5Ll+7 zd;y_w>Ox@-E#C}(Gv&>cV{^3TCmd-6!JqiePUX?Btk(T|I6bF=N>jK88^y5KNOYwC z%M;;5TJgH-;{F)@HryTX_YiG+gv+Z|m81Ls+B?)=LGEP&kTe>j{3%dJh8QMQf!_^& zU2LBusJGBLMG#)frzc*hNLwpOn~_|^=agT2%mt~k8*qDW}wtt8PBhR9g6dH zO8--AR7U;{9LfjGA5xaI51TWv)ekzij}G~DuMyN6gy&y#h_^8~4}~{TC_zgG&~;nE z+;rs_%90MlFOOUg3{1vAGPw!?{DfRM$#Huia`Glc(tP-}37R+Xj?(Du!B%zZDKzGe z_4|vqoMQ%~zT?%aR&73Y1)>Et}fcTx^N zp&qB?8=+f*21(+F@*HpBV<7e5UKvWj#K$q4Z%UmQ_v}`R>k{@4%yy+_|nc%kCvRnXl)g-7#je+ zi3+R*DwuPbs598$fF> zBD@H^uY{ggEvtee+ps(_xLJ_^}!7=Di~l}B%jvDJe51bC9<748gl24Zgnfpn*F z9pTMT{D|=WUj~79$SpDSBFs-gNfW`nU`c3vYigyo1TbD1=toN{Dtaw~ISsEP^)GYu z;yh&Ps7BlZud1>bv-&>+$KlizBOej<2~bi!C0rgOanR}#P(hs6Q+$!RhrFcT$ntll z9m`Z*XdQFdZbA=8s)LQ*(qMW1no32|F&y-O7y6kDMIo$j?TOzrb$2W)pjZu)`nM=1=lUjROv4NgZr(bVPrsPW$_!{2K=EK`<%z zAwP!mLrNiCb*~$GM}mD$(MMxw8NB>Bh$g>CkbQ8v58CI*7QjY7%0H-~hz6UgVC0#D zB%eHgc@^g+$^TBXm1ChVz~I*?J2A4JAoxC!9~op~sooQrH)%iuPLF~?r8^$^EfN&@ zS!A9ECCR&m%h(K7BY<$yG4`!8cpT=ZD6fF|GDZ*JdzHR4~JkDWb~4`;H)n!LLki zOZ^QTcg(>TnbFw)635@6yE&5a?}uMq2wHlTRsp_pfL@^oTrukH$eO zOO2}|J#h#_FDXMpejT~TaFkmOp%QiQajavf3Lp()WpsPs%Y?RrTtb#mI>x(W&<*1m zTK^6~SfA41;3x|BP^^xF78t)qxhL{FRG{BdeiB*|^%ck_tDgBA+3MmLy(MHxx3G5( zKU>J9kd+jihk?#GPR6mMDwLljAHtA{prj%gdK$TN7`jTmj*{Jk(~HV@A&hrHZ$5@! zf&LzHi_s|zy&C#0vA0h-! z!x9*XqFw;Q>v7N+nF`2$O&(17clcvfPso>X8`0T;TzzslbwF0nr^bH@LbFgPhQaET z3sb(1k(H_kbQIfRSkitJ`BnAov>4tkc;k_O2VMZ42Rr+*^C}H-lTW~ZR`t~P;3?!> zV96kbsTB6p3+q)+h~*L}4<(4oDq{X~grgU7uY=*V7DrFRe*+tjtJVtdC1j>hZwUPf zY)(-MBM9&g!Hh(&1_8;-2&?_Ym4HAImeErrF6!q7^@qKY@6L zT#L*XwvL+^lr$$t&*0NaTj9Njj3hsfBu!TJUdVT%J{6~b!s`J2V`v|NI|!f%v}fS& z&sB%B8qQ1vCCRh-4+y9~Eli+X9Qpw2l2$LQbfjpo5u6E7zEyEF0jt98jcNJFN>WE~ zEzK#VH2LN}JN-o1(^YeZz#odeu0)VCxzHVljF&J^pgWWNHGX~%-!E4ntja2YTnLBL zE*uv{@hS#eW4r_g-lzNvvYT=I6SPc>rK7VD$Kg~}*^vKp@e2HS75HJwkE=1*4K|hQ zrKG1YEa_VWnjrjcjuu?QSRxLeS4R4%KtIG`HE2z3Rfk5Pf2kg8p`1KL!>+5|(UJWL zS^4RU(@O4RSud>-UZn^(!6+1(tAPH(`5)w;p{>giRJ>|oSLBzF$EyKPC%BR5F30YA z=)5L%T!r=oxeWPxZ0IynQac(D`~kyrVALhwfSH2wkIGn8@D1paIzrzGKZ^Adgnk?& z4KVPM3hDt4!|6J-V${beJ2A*DQUT{va{I8CB;#M7f}~UAt0=?~HLpS)-x8R71=t3B zQ8}rk3|3G2d0BqARH*S8N+ z8dh^0$!DgL`YOezRZz{q2Jj_$P+o(Qq}QNNqrIUcOw#bbUA<_x*XUOG}{l5Z2FX8A*CEOh& z<8j!Y-pHW5o%~*oURsUfacJRG6TJ|$+7Ld*&Rlr+p%tdw2Hc_M$Y{#V$P1wt!TuiP zgG;4C-iU#>aqsmuk<770KBQtzo%RfdVN}U1AGknPvkX} zC6&T%A9yRVTL*{XbQxc(>-Lg69?2gA+miY#{ii{z|4ZX6 zoDN`&Pou0<4tgw#A1b5QsXv7OHvFX+D}mve&>BLER5~S*ElA!8ttB#Tl_tIREy|K=!q3CrunIgzP#2+5bsQxKNqq?mO|S>UPrEod^nB8$-mQ^ z$RAZfeTBV-;qMmeK>Q5m&nVqhE&DU9jnRRO=LAKc5B&@QmLrGLlgRKNiLEaN&nP+J zb%b7&Wy1gSu>OlmF?_s1Uap2OSO~^26gGq{fzPT4!=&Lvx*J1t6#XUS1N6YF^u!b6A0G=SY2Jk-yQ_!yhZ9Yz)BR5rcw#oA{Nu7wOv+~xD^1o9joPVa2UcuN{ zjK2S`AZO!j3pt!JRN)G`KM-(d?2e_Jgzi3q$wYR!d@tppl0{T?Q1~2XEG_wqay|sU z!C5#J#Nn^1-V}p3;CDb?(lU4j>B(g3?_%p$_)mjp;nm0KTh#$-uTFnRzi0j|c$EeytB{4VA31b79x-ju|Gx%;^+@# zB%OmkQ}hUY2J-Tm;&+sN$jyV-nDXDqzJ;B4kn2q#edPSt2&3{Hs~e%F819U6LCTU0 zlrO@sPL4z|lROFKrHcO&@{+njpQu{>22OS>y6`@OC#kqLc)@u74~YtHNC> zicezTW7YjKJY`uvrBJ$q;|1ixMD9dx5BZyyNoTDd(;QSs+m&r%T(^OFVRZw3moyX801g{r*AskD3 zNBP)9eZ`}o?e%{UV{=g$ij$U4eNEcr~D{psvJ%j#m+sbXIlplL||NWpH+o_J>m&0+W;l?`6B_ z=m+hD3g{i^iRcU>$DlU>89(+9Q_n>pn~@y?o`k-H@^m?%SAm&CM7bfHAf$2DnYzY*G(jc(-+E63l+eh$Vi%k{4g3KsgvS$!+vY>WP%ixbm$U45sNpz6p)3l6P&khfNp}$#f$-zBU@Wx1 zsprDjJIF|SUKy71yBOR>Fh>=wAu=0OaM!UhNcF-4nmdC0KJ}6Cd!YBTJfM4UV7Z zP3{Au6#O43Z_i=-7x|!hD}udoG7+H*7%rc~&}-1|qcjj&djcqr^V-O?245kUh5r_M z*O2L`^eR)nP7keD^#{m}g?5m9fIwH1m%={=<_dq%oT#Gu7NVqG2oRSelYd5{coj#V zVMtOD0(l$$Me3*N<^}K`BdAe|e~Nm5A7qwa!g+TQ zfYD66k|J?BmHH&guOqk@M8l;9nT23I=fYI|8T3A4(T0!JhCXRe;W)nRIl9_mEzYv=-hP>Z8z= z)D}CEP7u%y@(@*j4%$#;3KGO!bPDHU{LjHGqgplxMm-n?hF`?VN#*o0j7W+k*jvaS z2cMz4`;qVBxGYB3A=@6g69nu5tCNdj=Py1xq|KAI-4Te9)`3}kpP!6YY(0nKkCvQZdhYBzqnQQ1s(x4ThzM0lnK~B;^ z>LsCT;3b?7hQ3}oe+xS!$+yEFv@b+a(lQi=z}SG&tJDurUrBi|t?P;MFUsLHHAKTz z3tJ+46C3T|XQ=?3lGPB z9RwERd=|o4I2wd<9qI{08%{@{|0b;?=*N+h^sWt#UsaE|2;f-)l=KZa2y95!(K}4Q zr=aC$)dllYIG)3JF&sXD;30A%^cu=Y1%fyNZ3qsYBKwHG1i`j|R+oGh{?DMKwm9Dc zZ&ePvupMurGY@)ODy2b^HUF$qMWX4fX1qnvuM=DeWK4W5rQBNjKevillqKcE`3D3v z8O3l~iSjz=7jXD4^3T8@18orHs>rQVHV#p4LjW68W7^?(K6>v$Ka2c!^up;9<=_=s z_BxES2u+~8fjoioa1_g_7R9Ts+m7=e$gQA1j>C=0>F+ojj?PMW)8Xw$J_S27p%tL~ zBsm7JrQqMl(Wo?eLH__^6ar3+Tt*=;(Z7IjbBuSP{4%s~I!=8w`89GDdT-&(g|4Ip zAZZlBQ0XhFmYOT8KMU-|ahdSLefciYu%0Dso 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 to get started\n" -"\n" -msgstr "" -"Escriba >ayuda< para comenzar\n" -"\n" +#: FlatCAMApp.py:2570 flatcamGUI/GUIElements.py:2592 +msgid "Type >help< to get started" +msgstr "Escriba >help< para comenzar" -#: FlatCAMApp.py:2627 FlatCAMApp.py:9020 +#: FlatCAMApp.py:2822 FlatCAMApp.py:9400 msgid "New Project - Not saved" msgstr "Proyecto nuevo: no guardado" -#: FlatCAMApp.py:2702 FlatCAMApp.py:9088 FlatCAMApp.py:9125 FlatCAMApp.py:9166 -#: FlatCAMApp.py:9237 FlatCAMApp.py:9991 FlatCAMApp.py:11174 -#: FlatCAMApp.py:11233 -msgid "" -"Canvas initialization started.\n" -"Canvas initialization finished in" -msgstr "" -"Se inició la inicialización del lienzo.\n" -"La inicialización del lienzo terminó en" - -#: FlatCAMApp.py:2704 -msgid "Executing Tcl Script ..." -msgstr "Ejecutando Tcl Script ..." - -#: FlatCAMApp.py:2719 +#: FlatCAMApp.py:2918 msgid "" "Found old default preferences files. Please reboot the application to update." msgstr "" "Se encontraron archivos de preferencias predeterminados antiguos. Reinicie " "la aplicación para actualizar." -#: FlatCAMApp.py:2763 ObjectCollection.py:90 flatcamTools/ToolImage.py:248 +#: FlatCAMApp.py:2969 FlatCAMApp.py:3889 FlatCAMApp.py:3938 FlatCAMApp.py:3993 +#: FlatCAMApp.py:4068 FlatCAMApp.py:6117 FlatCAMApp.py:9484 FlatCAMApp.py:9521 +#: FlatCAMApp.py:9563 FlatCAMApp.py:9592 FlatCAMApp.py:9632 FlatCAMApp.py:9657 +#: FlatCAMApp.py:9709 FlatCAMApp.py:9745 FlatCAMApp.py:9791 FlatCAMApp.py:9832 +#: FlatCAMApp.py:9873 FlatCAMApp.py:9914 FlatCAMApp.py:9955 FlatCAMApp.py:9999 +#: FlatCAMApp.py:10055 FlatCAMApp.py:10087 FlatCAMApp.py:10119 +#: FlatCAMApp.py:10356 FlatCAMApp.py:10400 FlatCAMApp.py:10477 +#: FlatCAMApp.py:10532 FlatCAMCommon.py:371 FlatCAMCommon.py:413 +#: FlatCAMCommon.py:1107 FlatCAMCommon.py:1153 FlatCAMCommon.py:2537 +#: FlatCAMCommon.py:2583 ObjectCollection.py:122 +#: flatcamEditors/FlatCAMExcEditor.py:1024 +#: flatcamEditors/FlatCAMExcEditor.py:1092 +#: flatcamEditors/FlatCAMTextEditor.py:223 flatcamGUI/FlatCAMGUI.py:3389 +#: flatcamGUI/FlatCAMGUI.py:3601 flatcamGUI/FlatCAMGUI.py:3812 +#: flatcamTools/ToolFilm.py:754 flatcamTools/ToolFilm.py:900 +#: flatcamTools/ToolImage.py:247 flatcamTools/ToolMove.py:270 #: flatcamTools/ToolPcbWizard.py:301 flatcamTools/ToolPcbWizard.py:324 -msgid "Open cancelled." -msgstr "Abierto cancelado." +#: flatcamTools/ToolQRCode.py:791 flatcamTools/ToolQRCode.py:838 +msgid "Cancelled." +msgstr "Cancelado." -#: FlatCAMApp.py:2779 +#: FlatCAMApp.py:2985 msgid "Open Config file failed." msgstr "El archivo de configuración abierto falló." -#: FlatCAMApp.py:2794 +#: FlatCAMApp.py:3000 msgid "Open Script file failed." msgstr "Error al abrir el archivo de script." -#: FlatCAMApp.py:2820 +#: FlatCAMApp.py:3026 msgid "Open Excellon file failed." msgstr "Abrir archivo Excellon falló." -#: FlatCAMApp.py:2833 +#: FlatCAMApp.py:3039 msgid "Open GCode file failed." msgstr "Error al abrir el archivo GCode." -#: FlatCAMApp.py:2846 +#: FlatCAMApp.py:3052 msgid "Open Gerber file failed." msgstr "Error al abrir el archivo Gerber." -#: FlatCAMApp.py:3201 +#: FlatCAMApp.py:3429 msgid "Select a Geometry, Gerber or Excellon Object to edit." msgstr "Seleccione un objeto Geometry, Gerber o Excellon para editar." -#: FlatCAMApp.py:3216 +#: FlatCAMApp.py:3444 msgid "" "Simultaneous editing of tools geometry in a MultiGeo Geometry is not " "possible.\n" @@ -122,98 +148,96 @@ msgstr "" "MultiGeo no es posible.\n" "Edite solo una geometría a la vez." -#: FlatCAMApp.py:3271 +#: FlatCAMApp.py:3502 msgid "Editor is activated ..." msgstr "Editor está activado ..." -#: FlatCAMApp.py:3292 +#: FlatCAMApp.py:3523 msgid "Do you want to save the edited object?" msgstr "Quieres guardar el objeto editado?" -#: FlatCAMApp.py:3293 flatcamGUI/FlatCAMGUI.py:2165 +#: FlatCAMApp.py:3524 flatcamGUI/FlatCAMGUI.py:2273 msgid "Close Editor" msgstr "Cerrar Editor" -#: FlatCAMApp.py:3296 FlatCAMApp.py:4014 FlatCAMApp.py:5067 FlatCAMApp.py:7724 -#: FlatCAMApp.py:7750 FlatCAMApp.py:8927 FlatCAMTranslation.py:108 -#: FlatCAMTranslation.py:193 +#: FlatCAMApp.py:3527 FlatCAMApp.py:5169 FlatCAMApp.py:8030 FlatCAMApp.py:8056 +#: FlatCAMApp.py:9305 FlatCAMTranslation.py:108 FlatCAMTranslation.py:199 +#: flatcamGUI/FlatCAMGUI.py:2479 msgid "Yes" msgstr "Sí" -#: FlatCAMApp.py:3297 FlatCAMApp.py:4015 FlatCAMApp.py:5068 FlatCAMApp.py:7725 -#: FlatCAMApp.py:7751 FlatCAMApp.py:8928 FlatCAMTranslation.py:109 -#: FlatCAMTranslation.py:194 flatcamGUI/PreferencesUI.py:5139 -#: flatcamGUI/PreferencesUI.py:5554 flatcamTools/ToolNonCopperClear.py:189 -#: flatcamTools/ToolPaint.py:161 +#: FlatCAMApp.py:3528 FlatCAMApp.py:5170 FlatCAMApp.py:8031 FlatCAMApp.py:8057 +#: FlatCAMApp.py:9306 FlatCAMTranslation.py:109 FlatCAMTranslation.py:200 +#: flatcamGUI/FlatCAMGUI.py:2480 flatcamGUI/PreferencesUI.py:5443 +#: flatcamGUI/PreferencesUI.py:5989 flatcamTools/ToolNCC.py:182 +#: flatcamTools/ToolPaint.py:166 msgid "No" msgstr "No" -#: FlatCAMApp.py:3298 FlatCAMApp.py:5069 FlatCAMApp.py:5925 FlatCAMApp.py:7006 -#: FlatCAMApp.py:8929 FlatCAMCommon.py:571 flatcamGUI/FlatCAMGUI.py:1260 +#: FlatCAMApp.py:3529 FlatCAMApp.py:5171 FlatCAMApp.py:6055 FlatCAMApp.py:7006 +#: FlatCAMApp.py:9307 FlatCAMCommon.py:572 FlatCAMCommon.py:2127 +#: flatcamGUI/FlatCAMGUI.py:1332 msgid "Cancel" msgstr "Cancelar" -#: FlatCAMApp.py:3326 +#: FlatCAMApp.py:3561 msgid "Object empty after edit." msgstr "Objeto vacío después de editar." -#: FlatCAMApp.py:3375 FlatCAMApp.py:3395 FlatCAMApp.py:3410 +#: FlatCAMApp.py:3565 FlatCAMApp.py:3586 FlatCAMApp.py:3608 +msgid "Editor exited. Editor content saved." +msgstr "Editor salido. Contenido del editor guardado." + +#: FlatCAMApp.py:3612 FlatCAMApp.py:3635 FlatCAMApp.py:3653 msgid "Select a Gerber, Geometry or Excellon Object to update." msgstr "Seleccione un objeto Gerber, Geometry o Excellon para actualizar." -#: FlatCAMApp.py:3379 +#: FlatCAMApp.py:3615 msgid "is updated, returning to App..." msgstr "se actualiza, volviendo a la aplicación ..." -#: FlatCAMApp.py:3774 FlatCAMApp.py:3888 FlatCAMApp.py:4929 +#: FlatCAMApp.py:3622 +msgid "Editor exited. Editor content was not saved." +msgstr "Editor salido. El contenido del editor no se guardó." + +#: FlatCAMApp.py:3815 FlatCAMApp.py:3946 FlatCAMApp.py:5018 msgid "Could not load defaults file." msgstr "No se pudo cargar el archivo predeterminado." -#: FlatCAMApp.py:3786 FlatCAMApp.py:3896 FlatCAMApp.py:4938 +#: FlatCAMApp.py:3827 FlatCAMApp.py:3954 FlatCAMApp.py:5027 msgid "Failed to parse defaults file." msgstr "Error al analizar el archivo predeterminado." -#: FlatCAMApp.py:3831 -msgid "Preferences default restore was cancelled." -msgstr "La restauración predeterminada de preferencias fue cancelada." - -#: FlatCAMApp.py:3839 FlatCAMApp.py:5017 +#: FlatCAMApp.py:3897 FlatCAMApp.py:5119 msgid "Could not load factory defaults file." msgstr "No se pudo cargar el archivo de valores predeterminados de fábrica." -#: FlatCAMApp.py:3847 FlatCAMApp.py:5027 +#: FlatCAMApp.py:3905 FlatCAMApp.py:5129 msgid "Failed to parse factory defaults file." msgstr "Error al analizar el archivo de valores predeterminados de fábrica." -#: FlatCAMApp.py:3855 +#: FlatCAMApp.py:3913 msgid "Preferences default values are restored." msgstr "Se restauran los valores predeterminados de las preferencias." -#: FlatCAMApp.py:3870 FlatCAMApp.py:3874 +#: FlatCAMApp.py:3928 FlatCAMApp.py:3932 msgid "Import FlatCAM Preferences" msgstr "Importar preferencias de FlatCAM" -#: FlatCAMApp.py:3880 -msgid "FlatCAM preferences import cancelled." -msgstr "Importación de preferencias de FlatCAM cancelada." - -#: FlatCAMApp.py:3904 +#: FlatCAMApp.py:3962 msgid "Imported Defaults from" msgstr "Valores predeterminados importados de" -#: FlatCAMApp.py:3924 FlatCAMApp.py:3929 +#: FlatCAMApp.py:3982 FlatCAMApp.py:3987 msgid "Export FlatCAM Preferences" msgstr "Exportar preferencias de FlatCAM" -#: FlatCAMApp.py:3936 -msgid "FlatCAM preferences export cancelled." -msgstr "Exportación de preferencias de FlatCAM cancelada." - -#: FlatCAMApp.py:3945 FlatCAMApp.py:10389 FlatCAMApp.py:10437 -#: FlatCAMApp.py:10560 FlatCAMApp.py:10699 FlatCAMCommon.py:378 -#: FlatCAMCommon.py:1114 FlatCAMObj.py:6903 -#: flatcamEditors/FlatCAMTextEditor.py:274 flatcamTools/ToolFilm.py:1019 -#: flatcamTools/ToolFilm.py:1195 flatcamTools/ToolSolderPaste.py:1544 +#: FlatCAMApp.py:4002 FlatCAMApp.py:4076 FlatCAMApp.py:10776 +#: FlatCAMApp.py:10824 FlatCAMApp.py:10950 FlatCAMApp.py:11087 +#: FlatCAMCommon.py:379 FlatCAMCommon.py:1115 FlatCAMCommon.py:2545 +#: FlatCAMObj.py:7484 flatcamEditors/FlatCAMTextEditor.py:276 +#: flatcamTools/ToolFilm.py:1031 flatcamTools/ToolFilm.py:1212 +#: flatcamTools/ToolSolderPaste.py:1533 msgid "" "Permission denied, saving not possible.\n" "Most likely another app is holding the file open and not accessible." @@ -222,108 +246,108 @@ msgstr "" "Lo más probable es que otra aplicación mantenga el archivo abierto y no " "accesible." -#: FlatCAMApp.py:3957 +#: FlatCAMApp.py:4014 msgid "Could not load preferences file." msgstr "No se pudo cargar el archivo de preferencias." -#: FlatCAMApp.py:3976 FlatCAMApp.py:4985 +#: FlatCAMApp.py:4033 FlatCAMApp.py:4100 FlatCAMApp.py:5046 msgid "Failed to write defaults to file." msgstr "Error al escribir los valores predeterminados en el archivo." -#: FlatCAMApp.py:3981 +#: FlatCAMApp.py:4038 msgid "Exported preferences to" msgstr "Preferencias exportadas a" -#: FlatCAMApp.py:3998 -msgid "FlatCAM Preferences Folder opened." -msgstr "Carpeta de preferencias de FlatCAM abierta." +#: FlatCAMApp.py:4058 FlatCAMApp.py:4063 +msgid "Save to file" +msgstr "Guardar en archivo" -#: FlatCAMApp.py:4009 -msgid "Are you sure you want to delete the GUI Settings? \n" -msgstr "¿Está seguro de que desea eliminar la configuración de la GUI?\n" +#: FlatCAMApp.py:4087 +msgid "Could not load the file." +msgstr "No se pudo cargar el archivo." -#: FlatCAMApp.py:4012 flatcamGUI/FlatCAMGUI.py:1230 -msgid "Clear GUI Settings" -msgstr "Borrar la configuración de la GUI" +#: FlatCAMApp.py:4103 +msgid "Exported file to" +msgstr "Exported file to" -#: FlatCAMApp.py:4109 +#: FlatCAMApp.py:4186 msgid "Failed to open recent files file for writing." msgstr "Error al abrir archivos recientes para escritura." -#: FlatCAMApp.py:4120 +#: FlatCAMApp.py:4197 msgid "Failed to open recent projects file for writing." msgstr "Error al abrir el archivo de proyectos recientes para escribir." -#: FlatCAMApp.py:4205 FlatCAMApp.py:10900 FlatCAMApp.py:10961 -#: FlatCAMApp.py:11090 FlatCAMObj.py:5050 -#: flatcamEditors/FlatCAMGrbEditor.py:4187 flatcamTools/ToolPcbWizard.py:437 +#: FlatCAMApp.py:4282 FlatCAMApp.py:11283 FlatCAMApp.py:11342 +#: FlatCAMApp.py:11470 FlatCAMApp.py:12196 FlatCAMObj.py:5605 +#: flatcamEditors/FlatCAMGrbEditor.py:4231 flatcamTools/ToolPcbWizard.py:433 msgid "An internal error has occurred. See shell.\n" msgstr "Ha ocurrido un error interno. Ver concha\n" -#: FlatCAMApp.py:4206 +#: FlatCAMApp.py:4283 #, python-brace-format msgid "" "Object ({kind}) failed because: {error} \n" "\n" msgstr "El objeto ({kind}) falló porque: {error}\n" -#: FlatCAMApp.py:4221 +#: FlatCAMApp.py:4298 msgid "Converting units to " msgstr "Convertir unidades a " -#: FlatCAMApp.py:4324 +#: FlatCAMApp.py:4411 msgid "CREATE A NEW FLATCAM TCL SCRIPT" msgstr "CREA UN NUEVO SCRIPT FLATCAM TCL" -#: FlatCAMApp.py:4325 +#: FlatCAMApp.py:4412 msgid "TCL Tutorial is here" msgstr "TCL Tutorial está aquí" -#: FlatCAMApp.py:4327 +#: FlatCAMApp.py:4414 msgid "FlatCAM commands list" msgstr "Lista de comandos de FlatCAM" -#: FlatCAMApp.py:4378 FlatCAMApp.py:4384 FlatCAMApp.py:4390 FlatCAMApp.py:4396 -#: FlatCAMApp.py:4402 FlatCAMApp.py:4408 +#: FlatCAMApp.py:4465 FlatCAMApp.py:4471 FlatCAMApp.py:4477 FlatCAMApp.py:4483 +#: FlatCAMApp.py:4489 FlatCAMApp.py:4495 msgid "created/selected" msgstr "creado / seleccionado" -#: FlatCAMApp.py:4423 FlatCAMApp.py:7086 FlatCAMObj.py:271 FlatCAMObj.py:302 -#: FlatCAMObj.py:318 FlatCAMObj.py:398 flatcamTools/ToolCopperThieving.py:1476 -#: flatcamTools/ToolFiducials.py:807 flatcamTools/ToolMove.py:220 -#: flatcamTools/ToolQRCode.py:726 +#: FlatCAMApp.py:4510 FlatCAMApp.py:7092 FlatCAMObj.py:278 FlatCAMObj.py:309 +#: FlatCAMObj.py:325 FlatCAMObj.py:405 flatcamTools/ToolCopperThieving.py:1482 +#: flatcamTools/ToolFiducials.py:809 flatcamTools/ToolMove.py:230 +#: flatcamTools/ToolQRCode.py:728 msgid "Plotting" msgstr "Trazado" -#: FlatCAMApp.py:4486 flatcamGUI/FlatCAMGUI.py:491 +#: FlatCAMApp.py:4573 flatcamGUI/FlatCAMGUI.py:530 msgid "About FlatCAM" msgstr "Sobre FlatCAM" -#: FlatCAMApp.py:4512 +#: FlatCAMApp.py:4599 msgid "2D Computer-Aided Printed Circuit Board Manufacturing" msgstr "Fabricación de placa de circuito impreso asistida por computadora 2D" -#: FlatCAMApp.py:4513 +#: FlatCAMApp.py:4600 msgid "Development" msgstr "Desarrollo" -#: FlatCAMApp.py:4514 +#: FlatCAMApp.py:4601 msgid "DOWNLOAD" msgstr "DESCARGAR" -#: FlatCAMApp.py:4515 +#: FlatCAMApp.py:4602 msgid "Issue tracker" msgstr "Rastreador de problemas" -#: FlatCAMApp.py:4519 FlatCAMApp.py:4860 +#: FlatCAMApp.py:4606 FlatCAMApp.py:4948 flatcamGUI/GUIElements.py:2583 msgid "Close" msgstr "Cerca" -#: FlatCAMApp.py:4534 +#: FlatCAMApp.py:4621 msgid "Licensed under the MIT license" msgstr "Licenciado bajo la licencia MIT" -#: FlatCAMApp.py:4543 +#: FlatCAMApp.py:4630 msgid "" "Permission is hereby granted, free of charge, to any person obtaining a " "copy\n" @@ -373,7 +397,7 @@ msgstr "" "FUERA DE O EN CONEXIÓN CON EL SOFTWARE O EL USO U OTRAS OFERTAS EN\n" "EL SOFTWARE." -#: FlatCAMApp.py:4565 +#: FlatCAMApp.py:4652 msgid "" "Some of the icons used are from the following sources:
Icons by FreepikIcons8
Iconos de oNline Web Fonts" -#: FlatCAMApp.py:4597 +#: FlatCAMApp.py:4685 msgid "Splash" msgstr "Pantalla de bienvenida" -#: FlatCAMApp.py:4603 +#: FlatCAMApp.py:4691 msgid "Programmers" msgstr "Programadores" -#: FlatCAMApp.py:4609 +#: FlatCAMApp.py:4697 msgid "Translators" msgstr "Traductores" -#: FlatCAMApp.py:4615 +#: FlatCAMApp.py:4703 msgid "License" msgstr "Licencia" -#: FlatCAMApp.py:4621 +#: FlatCAMApp.py:4709 msgid "Attributions" msgstr "Atribuciones" -#: FlatCAMApp.py:4644 +#: FlatCAMApp.py:4732 msgid "Programmer" msgstr "Programador" -#: FlatCAMApp.py:4645 +#: FlatCAMApp.py:4733 msgid "Status" msgstr "Estado" -#: FlatCAMApp.py:4646 FlatCAMApp.py:4724 +#: FlatCAMApp.py:4734 FlatCAMApp.py:4812 msgid "E-mail" msgstr "Email" -#: FlatCAMApp.py:4654 +#: FlatCAMApp.py:4742 msgid "BETA Maintainer >= 2019" msgstr "BETA Mantenedor >= 2019" -#: FlatCAMApp.py:4721 +#: FlatCAMApp.py:4809 msgid "Language" msgstr "Idioma" -#: FlatCAMApp.py:4722 +#: FlatCAMApp.py:4810 msgid "Translator" msgstr "Traductor" -#: FlatCAMApp.py:4723 +#: FlatCAMApp.py:4811 msgid "Corrections" msgstr "Correcciones" -#: FlatCAMApp.py:4832 FlatCAMApp.py:4840 FlatCAMApp.py:7769 -#: flatcamGUI/FlatCAMGUI.py:473 +#: FlatCAMApp.py:4920 FlatCAMApp.py:4928 FlatCAMApp.py:8075 +#: flatcamGUI/FlatCAMGUI.py:512 msgid "Bookmarks Manager" msgstr "Administrador de Marcadores" -#: FlatCAMApp.py:4851 +#: FlatCAMApp.py:4939 msgid "" "This entry will resolve to another website if:\n" "\n" @@ -462,28 +486,28 @@ msgstr "" "Si no puede obtener información sobre FlatCAM beta\n" "use el enlace del canal de YouTube desde el menú Ayuda." -#: FlatCAMApp.py:4858 +#: FlatCAMApp.py:4946 msgid "Alternative website" msgstr "Sitio web alternativo" -#: FlatCAMApp.py:4989 FlatCAMApp.py:7733 +#: FlatCAMApp.py:5050 FlatCAMApp.py:8039 msgid "Preferences saved." msgstr "Preferencias guardadas." -#: FlatCAMApp.py:5043 +#: FlatCAMApp.py:5145 msgid "Failed to write factory defaults to file." msgstr "" "Error al escribir los valores predeterminados de fábrica en el archivo." -#: FlatCAMApp.py:5047 +#: FlatCAMApp.py:5149 msgid "Factory defaults saved." msgstr "Valores predeterminados de fábrica guardados." -#: FlatCAMApp.py:5057 flatcamGUI/FlatCAMGUI.py:3962 +#: FlatCAMApp.py:5159 flatcamGUI/FlatCAMGUI.py:4178 msgid "Application is saving the project. Please wait ..." msgstr "La aplicación es guardar el proyecto. Por favor espera ..." -#: FlatCAMApp.py:5062 FlatCAMTranslation.py:188 +#: FlatCAMApp.py:5164 FlatCAMTranslation.py:194 msgid "" "There are files/objects modified in FlatCAM. \n" "Do you want to Save the project?" @@ -491,29 +515,29 @@ msgstr "" "Hay archivos / objetos modificados en FlatCAM.\n" "¿Quieres guardar el proyecto?" -#: FlatCAMApp.py:5065 FlatCAMApp.py:8925 FlatCAMTranslation.py:191 +#: FlatCAMApp.py:5167 FlatCAMApp.py:9303 FlatCAMTranslation.py:197 msgid "Save changes" msgstr "Guardar cambios" -#: FlatCAMApp.py:5306 +#: FlatCAMApp.py:5423 msgid "Selected Excellon file extensions registered with FlatCAM." msgstr "Extensiones de archivo Excellon seleccionadas registradas con FlatCAM." -#: FlatCAMApp.py:5328 +#: FlatCAMApp.py:5445 msgid "Selected GCode file extensions registered with FlatCAM." msgstr "Extensiones de archivo GCode seleccionadas registradas con FlatCAM." -#: FlatCAMApp.py:5350 +#: FlatCAMApp.py:5467 msgid "Selected Gerber file extensions registered with FlatCAM." msgstr "Extensiones de archivo Gerber seleccionadas registradas con FlatCAM." -#: FlatCAMApp.py:5538 FlatCAMApp.py:5595 FlatCAMApp.py:5623 +#: FlatCAMApp.py:5655 FlatCAMApp.py:5714 FlatCAMApp.py:5742 msgid "At least two objects are required for join. Objects currently selected" msgstr "" "Se requieren al menos dos objetos para unirse. Objetos actualmente " "seleccionados" -#: FlatCAMApp.py:5547 +#: FlatCAMApp.py:5664 msgid "" "Failed join. The Geometry objects are of different types.\n" "At least one is MultiGeo type and the other is SingleGeo type. A possibility " @@ -529,51 +553,47 @@ msgstr "" "pueden perderse y el resultado puede no ser el esperado.\n" "Compruebe el GCODE generado." -#: FlatCAMApp.py:5559 -msgid "Multigeo. Geometry merging finished" -msgstr "Multi Geo. Geometría fusionada terminada" - -#: FlatCAMApp.py:5568 +#: FlatCAMApp.py:5676 FlatCAMApp.py:5686 msgid "Geometry merging finished" msgstr "Geometría fusionada terminada" -#: FlatCAMApp.py:5590 +#: FlatCAMApp.py:5709 msgid "Failed. Excellon joining works only on Excellon objects." msgstr "Ha fallado. La unión de Excellon funciona solo en objetos de Excellon." -#: FlatCAMApp.py:5600 +#: FlatCAMApp.py:5719 msgid "Excellon merging finished" msgstr "Excellon fusión finalizada" -#: FlatCAMApp.py:5618 +#: FlatCAMApp.py:5737 msgid "Failed. Gerber joining works only on Gerber objects." msgstr "Ha fallado. La unión de Gerber funciona solo en objetos de Gerber." -#: FlatCAMApp.py:5628 +#: FlatCAMApp.py:5747 msgid "Gerber merging finished" msgstr "Gerber fusión finalizada" -#: FlatCAMApp.py:5648 FlatCAMApp.py:5683 +#: FlatCAMApp.py:5767 FlatCAMApp.py:5802 msgid "Failed. Select a Geometry Object and try again." msgstr "Ha fallado. Seleccione un objeto de Geometría y vuelva a intentarlo." -#: FlatCAMApp.py:5652 FlatCAMApp.py:5688 +#: FlatCAMApp.py:5771 FlatCAMApp.py:5807 msgid "Expected a FlatCAMGeometry, got" msgstr "Se esperaba un FlatCAMGeometry, se obtuvo" -#: FlatCAMApp.py:5665 +#: FlatCAMApp.py:5784 msgid "A Geometry object was converted to MultiGeo type." msgstr "Un objeto Geometry fue convertido al tipo MultiGeo." -#: FlatCAMApp.py:5703 +#: FlatCAMApp.py:5822 msgid "A Geometry object was converted to SingleGeo type." msgstr "Un objeto Geometry fue convertido al tipo SingleGeo." -#: FlatCAMApp.py:5919 +#: FlatCAMApp.py:6049 msgid "Toggle Units" msgstr "(Escriba ayuda para empezar)" -#: FlatCAMApp.py:5921 +#: FlatCAMApp.py:6051 msgid "" "Changing the units of the project\n" "will scale all objects.\n" @@ -585,29 +605,25 @@ msgstr "" "\n" "¿Quieres continuar?" -#: FlatCAMApp.py:5924 FlatCAMApp.py:6929 FlatCAMApp.py:7005 FlatCAMApp.py:9290 -#: FlatCAMApp.py:9304 FlatCAMApp.py:9658 FlatCAMApp.py:9669 +#: FlatCAMApp.py:6054 FlatCAMApp.py:6928 FlatCAMApp.py:7005 FlatCAMApp.py:9676 +#: FlatCAMApp.py:9690 FlatCAMApp.py:10025 FlatCAMApp.py:10035 msgid "Ok" msgstr "De acuerdo" -#: FlatCAMApp.py:5973 +#: FlatCAMApp.py:6103 msgid "Converted units to" msgstr "Convertir unidades a" -#: FlatCAMApp.py:5987 -msgid "Units conversion cancelled." -msgstr "Conversión de unidades cancelada." - -#: FlatCAMApp.py:6613 +#: FlatCAMApp.py:6743 msgid "Detachable Tabs" msgstr "Tabulacion desmontables" -#: FlatCAMApp.py:6828 FlatCAMApp.py:6889 FlatCAMApp.py:7560 FlatCAMApp.py:7622 -#: FlatCAMApp.py:7688 +#: FlatCAMApp.py:6817 FlatCAMApp.py:6861 FlatCAMApp.py:6889 FlatCAMApp.py:7822 +#: FlatCAMApp.py:7890 FlatCAMApp.py:7994 msgid "Preferences" msgstr "Preferencias" -#: FlatCAMApp.py:6831 +#: FlatCAMApp.py:6823 msgid "Preferences applied." msgstr "Preferencias aplicadas." @@ -615,20 +631,20 @@ msgstr "Preferencias aplicadas." msgid "Preferences closed without saving." msgstr "Preferencias cerradas sin guardar." -#: FlatCAMApp.py:6917 flatcamTools/ToolNonCopperClear.py:591 -#: flatcamTools/ToolNonCopperClear.py:987 flatcamTools/ToolPaint.py:502 -#: flatcamTools/ToolSolderPaste.py:562 flatcamTools/ToolSolderPaste.py:892 +#: FlatCAMApp.py:6917 flatcamTools/ToolNCC.py:932 flatcamTools/ToolNCC.py:1426 +#: flatcamTools/ToolPaint.py:858 flatcamTools/ToolSolderPaste.py:568 +#: flatcamTools/ToolSolderPaste.py:893 msgid "Please enter a tool diameter with non-zero value, in Float format." msgstr "" "Introduzca un diámetro de herramienta con valor distinto de cero, en formato " "Float." -#: FlatCAMApp.py:6922 flatcamTools/ToolNonCopperClear.py:595 -#: flatcamTools/ToolPaint.py:506 flatcamTools/ToolSolderPaste.py:566 +#: FlatCAMApp.py:6921 flatcamTools/ToolNCC.py:936 flatcamTools/ToolPaint.py:862 +#: flatcamTools/ToolSolderPaste.py:572 msgid "Adding Tool cancelled" msgstr "Añadiendo herramienta cancelada" -#: FlatCAMApp.py:6925 +#: FlatCAMApp.py:6924 msgid "" "Adding Tool works only when Advanced is checked.\n" "Go to Preferences -> General - Show Advanced Options." @@ -648,102 +664,144 @@ msgstr "" "¿Estás seguro de que deseas eliminarlo permanentemente?\n" "los objetos seleccionados?" -#: FlatCAMApp.py:7034 +#: FlatCAMApp.py:7041 msgid "Object(s) deleted" msgstr "Objeto (s) eliminado" -#: FlatCAMApp.py:7038 flatcamTools/ToolDblSided.py:713 +#: FlatCAMApp.py:7045 FlatCAMApp.py:7200 flatcamTools/ToolDblSided.py:819 msgid "Failed. No object(s) selected..." msgstr "Ha fallado. Ningún objeto (s) seleccionado ..." -#: FlatCAMApp.py:7040 +#: FlatCAMApp.py:7047 msgid "Save the work in Editor and try again ..." msgstr "Guarda el trabajo en el Editor y vuelve a intentarlo ..." -#: FlatCAMApp.py:7070 +#: FlatCAMApp.py:7076 msgid "Object deleted" msgstr "Objeto eliminado" -#: FlatCAMApp.py:7097 +#: FlatCAMApp.py:7103 msgid "Click to set the origin ..." msgstr "Haga clic para establecer el origen ..." -#: FlatCAMApp.py:7119 +#: FlatCAMApp.py:7125 msgid "Setting Origin..." msgstr "Establecer Origen ..." -#: FlatCAMApp.py:7131 +#: FlatCAMApp.py:7138 FlatCAMApp.py:7240 msgid "Origin set" msgstr "Conjunto de origen" -#: FlatCAMApp.py:7138 +#: FlatCAMApp.py:7155 msgid "Origin coordinates specified but incomplete." msgstr "Origin coordinates specified but incomplete." -#: FlatCAMApp.py:7197 +#: FlatCAMApp.py:7196 +msgid "Moving to Origin..." +msgstr "Mudarse al origen ..." + +#: FlatCAMApp.py:7277 msgid "Jump to ..." msgstr "Salta a ..." -#: FlatCAMApp.py:7198 +#: FlatCAMApp.py:7278 msgid "Enter the coordinates in format X,Y:" msgstr "Introduzca las coordenadas en formato X, Y:" -#: FlatCAMApp.py:7208 +#: FlatCAMApp.py:7288 msgid "Wrong coordinates. Enter coordinates in format: X,Y" msgstr "Coordenadas erróneas. Introduzca las coordenadas en formato: X, Y" -#: FlatCAMApp.py:7288 flatcamEditors/FlatCAMExcEditor.py:3599 -#: flatcamEditors/FlatCAMExcEditor.py:3607 -#: flatcamEditors/FlatCAMGeoEditor.py:4036 -#: flatcamEditors/FlatCAMGeoEditor.py:4051 -#: flatcamEditors/FlatCAMGrbEditor.py:1086 -#: flatcamEditors/FlatCAMGrbEditor.py:1203 -#: flatcamEditors/FlatCAMGrbEditor.py:1489 -#: flatcamEditors/FlatCAMGrbEditor.py:1758 -#: flatcamEditors/FlatCAMGrbEditor.py:4445 -#: flatcamEditors/FlatCAMGrbEditor.py:4460 flatcamGUI/FlatCAMGUI.py:3145 -#: flatcamGUI/FlatCAMGUI.py:3157 +#: FlatCAMApp.py:7366 FlatCAMApp.py:7515 +#: flatcamEditors/FlatCAMExcEditor.py:3622 +#: flatcamEditors/FlatCAMExcEditor.py:3630 +#: flatcamEditors/FlatCAMGeoEditor.py:4349 +#: flatcamEditors/FlatCAMGeoEditor.py:4363 +#: flatcamEditors/FlatCAMGrbEditor.py:1085 +#: flatcamEditors/FlatCAMGrbEditor.py:1202 +#: flatcamEditors/FlatCAMGrbEditor.py:1488 +#: flatcamEditors/FlatCAMGrbEditor.py:1757 +#: flatcamEditors/FlatCAMGrbEditor.py:4489 +#: flatcamEditors/FlatCAMGrbEditor.py:4504 flatcamGUI/FlatCAMGUI.py:3370 +#: flatcamGUI/FlatCAMGUI.py:3382 flatcamTools/ToolAlignObjects.py:393 +#: flatcamTools/ToolAlignObjects.py:415 msgid "Done." msgstr "Hecho." -#: FlatCAMApp.py:7440 FlatCAMApp.py:7511 +#: FlatCAMApp.py:7381 FlatCAMApp.py:9672 FlatCAMApp.py:9768 FlatCAMApp.py:9810 +#: FlatCAMApp.py:9851 FlatCAMApp.py:9892 FlatCAMApp.py:9933 FlatCAMApp.py:9977 +#: FlatCAMApp.py:10021 FlatCAMApp.py:10510 FlatCAMApp.py:10514 +#: flatcamTools/ToolProperties.py:116 +msgid "No object selected." +msgstr "Ningún objeto seleccionado." + +#: FlatCAMApp.py:7400 +msgid "Bottom-Left" +msgstr "Abajo-izquierda" + +#: FlatCAMApp.py:7401 flatcamGUI/PreferencesUI.py:8111 +#: flatcamTools/ToolCalibration.py:159 +msgid "Top-Left" +msgstr "Arriba a la izquierda" + +#: FlatCAMApp.py:7402 flatcamGUI/PreferencesUI.py:8112 +#: flatcamTools/ToolCalibration.py:160 +msgid "Bottom-Right" +msgstr "Abajo a la derecha" + +#: FlatCAMApp.py:7403 +msgid "Top-Right" +msgstr "Top-Derecha" + +#: FlatCAMApp.py:7404 flatcamGUI/ObjectUI.py:2624 +msgid "Center" +msgstr "Centrar" + +#: FlatCAMApp.py:7424 +msgid "Locate ..." +msgstr "Localizar ..." + +#: FlatCAMApp.py:7685 FlatCAMApp.py:7762 msgid "No object is selected. Select an object and try again." msgstr "" "Ningún objeto está seleccionado. Seleccione un objeto y vuelva a intentarlo." -#: FlatCAMApp.py:7531 +#: FlatCAMApp.py:7788 msgid "" "Aborting. The current task will be gracefully closed as soon as possible..." msgstr "Abortar La tarea actual se cerrará con gracia lo antes posible ..." -#: FlatCAMApp.py:7537 +#: FlatCAMApp.py:7794 msgid "The current task was gracefully closed on user request..." msgstr "La tarea actual se cerró correctamente a petición del usuario ..." -#: FlatCAMApp.py:7619 +#: FlatCAMApp.py:7887 msgid "Preferences edited but not saved." msgstr "Preferencias editadas pero no guardadas." -#: FlatCAMApp.py:7633 FlatCAMApp.py:7645 FlatCAMApp.py:7662 FlatCAMApp.py:7679 -#: FlatCAMApp.py:7739 FlatCAMCommon.py:1181 FlatCAMCommon.py:1356 -#: FlatCAMObj.py:4256 +#: FlatCAMApp.py:7904 FlatCAMApp.py:7932 FlatCAMApp.py:7959 FlatCAMApp.py:7978 +#: FlatCAMApp.py:8045 FlatCAMCommon.py:1182 FlatCAMCommon.py:1357 +#: FlatCAMCommon.py:2612 FlatCAMCommon.py:2820 FlatCAMObj.py:4798 +#: flatcamTools/ToolNCC.py:3958 flatcamTools/ToolNCC.py:4042 +#: flatcamTools/ToolPaint.py:3548 flatcamTools/ToolPaint.py:3633 msgid "Tools Database" msgstr "Base de Datos de Herramientas" -#: FlatCAMApp.py:7659 +#: FlatCAMApp.py:7956 msgid "Tools in Tools Database edited but not saved." msgstr "" "Herramientas en la base de datos de herramientas editadas pero no guardadas." -#: FlatCAMApp.py:7683 +#: FlatCAMApp.py:7982 flatcamTools/ToolNCC.py:3965 +#: flatcamTools/ToolPaint.py:3555 msgid "Tool from DB added in Tool Table." msgstr "Herramienta de DB agregada en la Tabla de herramientas." -#: FlatCAMApp.py:7685 +#: FlatCAMApp.py:7984 msgid "Adding tool from DB is not allowed for this object." msgstr "No se permite agregar herramientas desde DB para este objeto." -#: FlatCAMApp.py:7719 +#: FlatCAMApp.py:8025 msgid "" "One or more values are changed.\n" "Do you want to save the Preferences?" @@ -751,11 +809,11 @@ msgstr "" "Uno o más valores son cambiados.\n" "¿Quieres guardar las preferencias?" -#: FlatCAMApp.py:7721 flatcamGUI/FlatCAMGUI.py:222 +#: FlatCAMApp.py:8027 flatcamGUI/FlatCAMGUI.py:291 msgid "Save Preferences" msgstr "Guardar Preferencias" -#: FlatCAMApp.py:7745 +#: FlatCAMApp.py:8051 msgid "" "One or more Tools are edited.\n" "Do you want to update the Tools Database?" @@ -763,174 +821,176 @@ msgstr "" "Se editan una o más herramientas.\n" "¿Desea actualizar la base de datos de herramientas?" -#: FlatCAMApp.py:7747 +#: FlatCAMApp.py:8053 msgid "Save Tools Database" msgstr "Guardar base de datos de herramientas" -#: FlatCAMApp.py:7766 FlatCAMApp.py:9897 FlatCAMObj.py:6509 +#: FlatCAMApp.py:8072 FlatCAMApp.py:10259 FlatCAMObj.py:7089 msgid "Code Editor" msgstr "Editor de código" -#: FlatCAMApp.py:7784 +#: FlatCAMApp.py:8094 msgid "No object selected to Flip on Y axis." msgstr "Ningún objeto seleccionado para Voltear en el eje Y." -#: FlatCAMApp.py:7810 +#: FlatCAMApp.py:8120 msgid "Flip on Y axis done." msgstr "Voltear sobre el eje Y hecho." -#: FlatCAMApp.py:7812 FlatCAMApp.py:7854 -#: flatcamEditors/FlatCAMGrbEditor.py:5858 +#: FlatCAMApp.py:8122 FlatCAMApp.py:8170 +#: flatcamEditors/FlatCAMGrbEditor.py:5893 msgid "Flip action was not executed." msgstr "La acción de voltear no se ejecutó." -#: FlatCAMApp.py:7826 +#: FlatCAMApp.py:8142 msgid "No object selected to Flip on X axis." msgstr "Ningún objeto seleccionado para Voltear en el eje X." -#: FlatCAMApp.py:7852 +#: FlatCAMApp.py:8168 msgid "Flip on X axis done." msgstr "Voltear sobre el eje X hecho." -#: FlatCAMApp.py:7868 +#: FlatCAMApp.py:8190 msgid "No object selected to Rotate." msgstr "Ningún objeto seleccionado para rotar." -#: FlatCAMApp.py:7871 FlatCAMApp.py:7918 FlatCAMApp.py:7951 +#: FlatCAMApp.py:8193 FlatCAMApp.py:8246 FlatCAMApp.py:8285 msgid "Transform" msgstr "Transformar" -#: FlatCAMApp.py:7871 FlatCAMApp.py:7918 FlatCAMApp.py:7951 +#: FlatCAMApp.py:8193 FlatCAMApp.py:8246 FlatCAMApp.py:8285 msgid "Enter the Angle value:" msgstr "Ingrese el valor del ángulo:" -#: FlatCAMApp.py:7902 +#: FlatCAMApp.py:8224 msgid "Rotation done." msgstr "Rotación hecha." -#: FlatCAMApp.py:7904 +#: FlatCAMApp.py:8226 msgid "Rotation movement was not executed." msgstr "El movimiento de rotación no se ejecutó." -#: FlatCAMApp.py:7916 +#: FlatCAMApp.py:8244 msgid "No object selected to Skew/Shear on X axis." msgstr "Ningún objeto seleccionado para sesgar / cortar en el eje X." -#: FlatCAMApp.py:7938 +#: FlatCAMApp.py:8266 msgid "Skew on X axis done." msgstr "Sesgar en el eje X hecho." -#: FlatCAMApp.py:7949 +#: FlatCAMApp.py:8283 msgid "No object selected to Skew/Shear on Y axis." msgstr "Ningún objeto seleccionado para sesgar / cortar en el eje Y." -#: FlatCAMApp.py:7971 +#: FlatCAMApp.py:8305 msgid "Skew on Y axis done." msgstr "Sesgar en el eje Y hecho." -#: FlatCAMApp.py:8119 FlatCAMApp.py:8166 flatcamGUI/FlatCAMGUI.py:449 -#: flatcamGUI/FlatCAMGUI.py:1612 +#: FlatCAMApp.py:8458 FlatCAMApp.py:8505 flatcamGUI/FlatCAMGUI.py:488 +#: flatcamGUI/FlatCAMGUI.py:1713 msgid "Select All" msgstr "Seleccionar todo" -#: FlatCAMApp.py:8123 FlatCAMApp.py:8170 flatcamGUI/FlatCAMGUI.py:451 +#: FlatCAMApp.py:8462 FlatCAMApp.py:8509 flatcamGUI/FlatCAMGUI.py:490 msgid "Deselect All" msgstr "Deseleccionar todo" -#: FlatCAMApp.py:8186 +#: FlatCAMApp.py:8525 msgid "All objects are selected." msgstr "Todos los objetos están seleccionados." -#: FlatCAMApp.py:8196 +#: FlatCAMApp.py:8535 msgid "Objects selection is cleared." msgstr "La selección de objetos se borra." -#: FlatCAMApp.py:8216 flatcamGUI/FlatCAMGUI.py:1605 +#: FlatCAMApp.py:8555 flatcamGUI/FlatCAMGUI.py:1706 msgid "Grid On/Off" msgstr "Grid On/Off" -#: FlatCAMApp.py:8228 flatcamEditors/FlatCAMGeoEditor.py:940 -#: flatcamEditors/FlatCAMGrbEditor.py:2574 -#: flatcamEditors/FlatCAMGrbEditor.py:5431 flatcamGUI/ObjectUI.py:1304 -#: flatcamTools/ToolDblSided.py:187 flatcamTools/ToolDblSided.py:245 -#: flatcamTools/ToolNonCopperClear.py:286 flatcamTools/ToolPaint.py:188 -#: flatcamTools/ToolSolderPaste.py:121 flatcamTools/ToolSolderPaste.py:591 -#: flatcamTools/ToolTransform.py:310 +#: FlatCAMApp.py:8567 flatcamEditors/FlatCAMGeoEditor.py:940 +#: flatcamEditors/FlatCAMGrbEditor.py:2580 +#: flatcamEditors/FlatCAMGrbEditor.py:5475 flatcamGUI/ObjectUI.py:1593 +#: flatcamTools/ToolDblSided.py:193 flatcamTools/ToolDblSided.py:426 +#: flatcamTools/ToolNCC.py:294 flatcamTools/ToolNCC.py:631 +#: flatcamTools/ToolPaint.py:277 flatcamTools/ToolPaint.py:676 +#: flatcamTools/ToolSolderPaste.py:123 flatcamTools/ToolSolderPaste.py:597 +#: flatcamTools/ToolTransform.py:479 msgid "Add" msgstr "Añadir" -#: FlatCAMApp.py:8230 FlatCAMObj.py:3963 -#: flatcamEditors/FlatCAMGrbEditor.py:2579 -#: flatcamEditors/FlatCAMGrbEditor.py:2727 flatcamGUI/FlatCAMGUI.py:680 -#: flatcamGUI/FlatCAMGUI.py:991 flatcamGUI/FlatCAMGUI.py:2018 -#: flatcamGUI/FlatCAMGUI.py:2161 flatcamGUI/FlatCAMGUI.py:2559 -#: flatcamGUI/ObjectUI.py:1330 flatcamTools/ToolNonCopperClear.py:298 -#: flatcamTools/ToolPaint.py:200 flatcamTools/ToolSolderPaste.py:127 -#: flatcamTools/ToolSolderPaste.py:594 +#: FlatCAMApp.py:8569 FlatCAMObj.py:4416 +#: flatcamEditors/FlatCAMGrbEditor.py:2585 +#: flatcamEditors/FlatCAMGrbEditor.py:2733 flatcamGUI/FlatCAMGUI.py:736 +#: flatcamGUI/FlatCAMGUI.py:1059 flatcamGUI/FlatCAMGUI.py:2126 +#: flatcamGUI/FlatCAMGUI.py:2269 flatcamGUI/FlatCAMGUI.py:2733 +#: flatcamGUI/ObjectUI.py:1621 flatcamTools/ToolNCC.py:316 +#: flatcamTools/ToolNCC.py:637 flatcamTools/ToolPaint.py:299 +#: flatcamTools/ToolPaint.py:682 flatcamTools/ToolSolderPaste.py:129 +#: flatcamTools/ToolSolderPaste.py:600 msgid "Delete" msgstr "Borrar" -#: FlatCAMApp.py:8243 +#: FlatCAMApp.py:8582 msgid "New Grid ..." msgstr "Nueva rejilla ..." -#: FlatCAMApp.py:8244 +#: FlatCAMApp.py:8583 msgid "Enter a Grid Value:" msgstr "Introduzca un valor de cuadrícula:" -#: FlatCAMApp.py:8252 FlatCAMApp.py:8279 +#: FlatCAMApp.py:8591 FlatCAMApp.py:8618 msgid "Please enter a grid value with non-zero value, in Float format." msgstr "" "Introduzca un valor de cuadrícula con un valor distinto de cero, en formato " "Float." -#: FlatCAMApp.py:8258 +#: FlatCAMApp.py:8597 msgid "New Grid added" msgstr "Nueva rejilla" -#: FlatCAMApp.py:8261 +#: FlatCAMApp.py:8600 msgid "Grid already exists" msgstr "La rejilla ya existe" -#: FlatCAMApp.py:8264 +#: FlatCAMApp.py:8603 msgid "Adding New Grid cancelled" msgstr "Agregar nueva cuadrícula cancelado" -#: FlatCAMApp.py:8286 +#: FlatCAMApp.py:8625 msgid " Grid Value does not exist" msgstr " El valor de cuadrícula no existe" -#: FlatCAMApp.py:8289 +#: FlatCAMApp.py:8628 msgid "Grid Value deleted" msgstr "Valor de cuadrícula eliminado" -#: FlatCAMApp.py:8292 +#: FlatCAMApp.py:8631 msgid "Delete Grid value cancelled" msgstr "Eliminar el valor de cuadrícula cancelado" -#: FlatCAMApp.py:8298 +#: FlatCAMApp.py:8637 msgid "Key Shortcut List" msgstr "Lista de atajos de teclas" -#: FlatCAMApp.py:8332 +#: FlatCAMApp.py:8671 msgid " No object selected to copy it's name" msgstr " Ningún objeto seleccionado para copiar su nombre" -#: FlatCAMApp.py:8336 +#: FlatCAMApp.py:8675 msgid "Name copied on clipboard ..." msgstr "Nombre copiado en el portapapeles ..." -#: FlatCAMApp.py:8534 flatcamEditors/FlatCAMGrbEditor.py:4377 +#: FlatCAMApp.py:8888 flatcamEditors/FlatCAMGrbEditor.py:4421 msgid "Coordinates copied to clipboard." msgstr "Coordenadas copiadas al portapapeles." -#: FlatCAMApp.py:8762 FlatCAMApp.py:8768 FlatCAMApp.py:8774 FlatCAMApp.py:8780 -#: ObjectCollection.py:797 ObjectCollection.py:803 ObjectCollection.py:809 -#: ObjectCollection.py:815 ObjectCollection.py:821 ObjectCollection.py:827 +#: FlatCAMApp.py:9127 FlatCAMApp.py:9133 FlatCAMApp.py:9139 FlatCAMApp.py:9145 +#: ObjectCollection.py:911 ObjectCollection.py:917 ObjectCollection.py:923 +#: ObjectCollection.py:929 ObjectCollection.py:935 ObjectCollection.py:941 msgid "selected" msgstr "seleccionado" -#: FlatCAMApp.py:8922 +#: FlatCAMApp.py:9300 msgid "" "There are files/objects opened in FlatCAM.\n" "Creating a New project will delete them.\n" @@ -940,377 +1000,275 @@ msgstr "" "Crear un nuevo proyecto los borrará.\n" "¿Quieres guardar el proyecto?" -#: FlatCAMApp.py:8944 +#: FlatCAMApp.py:9321 msgid "New Project created" msgstr "Nuevo proyecto creado" -#: FlatCAMApp.py:9079 FlatCAMApp.py:9083 flatcamGUI/FlatCAMGUI.py:767 -#: flatcamGUI/FlatCAMGUI.py:2352 +#: FlatCAMApp.py:9468 FlatCAMApp.py:9472 flatcamGUI/FlatCAMGUI.py:821 +#: flatcamGUI/FlatCAMGUI.py:2504 msgid "Open Gerber" msgstr "Abrir gerber" -#: FlatCAMApp.py:9090 +#: FlatCAMApp.py:9477 FlatCAMApp.py:9514 FlatCAMApp.py:9556 FlatCAMApp.py:9625 +#: FlatCAMApp.py:10378 FlatCAMApp.py:11553 FlatCAMApp.py:11614 +msgid "" +"Canvas initialization started.\n" +"Canvas initialization finished in" +msgstr "" +"Se inició la inicialización del lienzo.\n" +"La inicialización del lienzo terminó en" + +#: FlatCAMApp.py:9479 msgid "Opening Gerber file." msgstr "Abriendo el archivo Gerber." -#: FlatCAMApp.py:9096 -msgid "Open Gerber cancelled." -msgstr "Abierto Gerber cancelado." - -#: FlatCAMApp.py:9117 FlatCAMApp.py:9121 flatcamGUI/FlatCAMGUI.py:769 -#: flatcamGUI/FlatCAMGUI.py:2354 +#: FlatCAMApp.py:9506 FlatCAMApp.py:9510 flatcamGUI/FlatCAMGUI.py:823 +#: flatcamGUI/FlatCAMGUI.py:2506 msgid "Open Excellon" msgstr "Abierto Excellon" -#: FlatCAMApp.py:9127 +#: FlatCAMApp.py:9516 msgid "Opening Excellon file." msgstr "Abriendo el archivo Excellon." -#: FlatCAMApp.py:9133 -msgid " Open Excellon cancelled." -msgstr " Abierto Excellon cancelado." - -#: FlatCAMApp.py:9157 FlatCAMApp.py:9161 +#: FlatCAMApp.py:9547 FlatCAMApp.py:9551 msgid "Open G-Code" msgstr "Código G abierto" -#: FlatCAMApp.py:9168 +#: FlatCAMApp.py:9558 msgid "Opening G-Code file." msgstr "Abriendo el archivo G-code." -#: FlatCAMApp.py:9174 -msgid "Open G-Code cancelled." -msgstr "Abierto G-Code cancelado." - -#: FlatCAMApp.py:9192 FlatCAMApp.py:9195 flatcamGUI/FlatCAMGUI.py:1614 +#: FlatCAMApp.py:9581 FlatCAMApp.py:9584 flatcamGUI/FlatCAMGUI.py:1715 msgid "Open Project" msgstr "Proyecto abierto" -#: FlatCAMApp.py:9204 -msgid "Open Project cancelled." -msgstr "Proyecto abierto cancelado." - -#: FlatCAMApp.py:9228 FlatCAMApp.py:9232 +#: FlatCAMApp.py:9616 FlatCAMApp.py:9620 msgid "Open HPGL2" msgstr "Abra HPGL2" -#: FlatCAMApp.py:9239 +#: FlatCAMApp.py:9627 msgid "Opening HPGL2 file." msgstr "Abrir el archivo HPGL2." -#: FlatCAMApp.py:9244 -msgid "Open HPGL2 file cancelled." -msgstr "Abrir el archivo HPGL2 cancelado." - -#: FlatCAMApp.py:9262 FlatCAMApp.py:9265 +#: FlatCAMApp.py:9650 FlatCAMApp.py:9653 msgid "Open Configuration File" msgstr "Abrir archivo de configuración" -#: FlatCAMApp.py:9270 -msgid "Open Config cancelled." -msgstr "Configuración abierta cancelada." - -#: FlatCAMApp.py:9286 FlatCAMApp.py:9654 FlatCAMApp.py:10124 -#: FlatCAMApp.py:10128 -msgid "No object selected." -msgstr "Ningún objeto seleccionado." - -#: FlatCAMApp.py:9287 FlatCAMApp.py:9655 +#: FlatCAMApp.py:9673 FlatCAMApp.py:10022 msgid "Please Select a Geometry object to export" msgstr "Seleccione un objeto de geometría para exportar" -#: FlatCAMApp.py:9301 +#: FlatCAMApp.py:9687 msgid "Only Geometry, Gerber and CNCJob objects can be used." msgstr "Solo se pueden utilizar objetos Geometry, Gerber y CNCJob." -#: FlatCAMApp.py:9314 FlatCAMApp.py:9318 flatcamTools/ToolQRCode.py:827 -#: flatcamTools/ToolQRCode.py:831 +#: FlatCAMApp.py:9700 FlatCAMApp.py:9704 flatcamTools/ToolQRCode.py:829 +#: flatcamTools/ToolQRCode.py:833 msgid "Export SVG" msgstr "Exportar SVG" -#: FlatCAMApp.py:9324 flatcamTools/ToolQRCode.py:836 -msgid " Export SVG cancelled." -msgstr " Exportar SVG cancelado." - -#: FlatCAMApp.py:9345 +#: FlatCAMApp.py:9730 msgid "Data must be a 3D array with last dimension 3 or 4" msgstr "Los datos deben ser una matriz 3D con la última dimensión 3 o 4" -#: FlatCAMApp.py:9351 FlatCAMApp.py:9355 +#: FlatCAMApp.py:9736 FlatCAMApp.py:9740 msgid "Export PNG Image" msgstr "Exportar imagen PNG" -#: FlatCAMApp.py:9360 -msgid "Export PNG cancelled." -msgstr "Exportación PNG cancelada." - -#: FlatCAMApp.py:9384 -msgid "No object selected. Please select an Gerber object to export." -msgstr "" -"Ningún objeto seleccionado. Por favor, seleccione un objeto Gerber para " -"exportar." - -#: FlatCAMApp.py:9390 FlatCAMApp.py:9613 +#: FlatCAMApp.py:9774 FlatCAMApp.py:9982 msgid "Failed. Only Gerber objects can be saved as Gerber files..." msgstr "" "Ha fallado. Solo los objetos Gerber se pueden guardar como archivos " "Gerber ..." -#: FlatCAMApp.py:9402 +#: FlatCAMApp.py:9786 msgid "Save Gerber source file" msgstr "Guardar el archivo fuente de Gerber" -#: FlatCAMApp.py:9408 -msgid "Save Gerber source file cancelled." -msgstr "Guardar el archivo fuente de Gerber cancelado." - -#: FlatCAMApp.py:9428 -msgid "No object selected. Please select an Script object to export." -msgstr "Ningún objeto seleccionado. Seleccione un objeto Script para exportar." - -#: FlatCAMApp.py:9434 +#: FlatCAMApp.py:9815 msgid "Failed. Only Script objects can be saved as TCL Script files..." msgstr "" "Ha fallado. Solo los objetos Script se pueden guardar como archivos TCL " "Script ..." -#: FlatCAMApp.py:9446 +#: FlatCAMApp.py:9827 msgid "Save Script source file" msgstr "Guardar archivo fuente de script" -#: FlatCAMApp.py:9452 -msgid "Save Script source file cancelled." -msgstr "Guardar archivo fuente de script cancelado." - -#: FlatCAMApp.py:9472 -msgid "No object selected. Please select an Document object to export." -msgstr "" -"Ningún objeto seleccionado. Seleccione un objeto de documento para exportar." - -#: FlatCAMApp.py:9478 +#: FlatCAMApp.py:9856 msgid "Failed. Only Document objects can be saved as Document files..." msgstr "" "Ha fallado. Solo los objetos de documento se pueden guardar como archivos de " "documento ..." -#: FlatCAMApp.py:9490 +#: FlatCAMApp.py:9868 msgid "Save Document source file" msgstr "Guardar archivo fuente del Documento" -#: FlatCAMApp.py:9496 -msgid "Save Document source file cancelled." -msgstr "Guardar Documento fuente archivo cancelado." - -#: FlatCAMApp.py:9516 -msgid "No object selected. Please select an Excellon object to export." -msgstr "" -"Ningún objeto seleccionado. Por favor, seleccione un objeto Excellon para " -"exportar." - -#: FlatCAMApp.py:9522 FlatCAMApp.py:9566 FlatCAMApp.py:10473 +#: FlatCAMApp.py:9897 FlatCAMApp.py:9938 FlatCAMApp.py:10863 msgid "Failed. Only Excellon objects can be saved as Excellon files..." msgstr "" "Ha fallado. Solo los objetos Excellon se pueden guardar como archivos " "Excellon ..." -#: FlatCAMApp.py:9530 FlatCAMApp.py:9534 +#: FlatCAMApp.py:9905 FlatCAMApp.py:9909 msgid "Save Excellon source file" msgstr "Guardar el archivo fuente de Excellon" -#: FlatCAMApp.py:9540 -msgid "Saving Excellon source file cancelled." -msgstr "Guardando el archivo fuente Excellon cancelado." - -#: FlatCAMApp.py:9560 -msgid "No object selected. Please Select an Excellon object to export." -msgstr "" -"Ningún objeto seleccionado. Seleccione un objeto Excellon para exportar." - -#: FlatCAMApp.py:9574 FlatCAMApp.py:9578 +#: FlatCAMApp.py:9946 FlatCAMApp.py:9950 msgid "Export Excellon" msgstr "Exportar Excellon" -#: FlatCAMApp.py:9584 -msgid "Export Excellon cancelled." -msgstr "Exportación Excellon cancelada." - -#: FlatCAMApp.py:9607 -msgid "No object selected. Please Select an Gerber object to export." -msgstr "Ningún objeto seleccionado. Seleccione un objeto Gerber para exportar." - -#: FlatCAMApp.py:9621 FlatCAMApp.py:9625 +#: FlatCAMApp.py:9990 FlatCAMApp.py:9994 msgid "Export Gerber" msgstr "Gerber Exportación" -#: FlatCAMApp.py:9631 -msgid "Export Gerber cancelled." -msgstr "Exportación Gerber cancelada." - -#: FlatCAMApp.py:9666 +#: FlatCAMApp.py:10032 msgid "Only Geometry objects can be used." msgstr "Solo se pueden utilizar objetos de Geometría." -#: FlatCAMApp.py:9680 FlatCAMApp.py:9684 +#: FlatCAMApp.py:10046 FlatCAMApp.py:10050 msgid "Export DXF" msgstr "Exportar DXF" -#: FlatCAMApp.py:9691 -msgid "Export DXF cancelled." -msgstr "Exportación DXF cancelada." - -#: FlatCAMApp.py:9711 FlatCAMApp.py:9714 +#: FlatCAMApp.py:10075 FlatCAMApp.py:10078 msgid "Import SVG" msgstr "Importar SVG" -#: FlatCAMApp.py:9724 -msgid "Open SVG cancelled." -msgstr "Abrir SVG cancelado." - -#: FlatCAMApp.py:9743 FlatCAMApp.py:9747 +#: FlatCAMApp.py:10106 FlatCAMApp.py:10110 msgid "Import DXF" msgstr "Importar DXF" -#: FlatCAMApp.py:9757 -msgid "Open DXF cancelled." -msgstr "Abrir DXF cancelado." - -#: FlatCAMApp.py:9799 +#: FlatCAMApp.py:10161 msgid "Viewing the source code of the selected object." msgstr "Ver el código fuente del objeto seleccionado." -#: FlatCAMApp.py:9800 FlatCAMObj.py:6495 FlatCAMObj.py:7225 +#: FlatCAMApp.py:10162 FlatCAMObj.py:7075 FlatCAMObj.py:7852 msgid "Loading..." msgstr "Cargando..." -#: FlatCAMApp.py:9806 FlatCAMApp.py:9810 +#: FlatCAMApp.py:10168 FlatCAMApp.py:10172 msgid "Select an Gerber or Excellon file to view it's source file." msgstr "Seleccione un archivo Gerber o Excellon para ver su archivo fuente." -#: FlatCAMApp.py:9824 +#: FlatCAMApp.py:10186 msgid "Source Editor" msgstr "Editor de fuente" -#: FlatCAMApp.py:9864 FlatCAMApp.py:9871 +#: FlatCAMApp.py:10226 FlatCAMApp.py:10233 msgid "There is no selected object for which to see it's source file code." msgstr "No hay ningún objeto seleccionado para el cual ver su código fuente." -#: FlatCAMApp.py:9883 +#: FlatCAMApp.py:10245 msgid "Failed to load the source code for the selected object" msgstr "Error al cargar el código fuente para el objeto seleccionado" -#: FlatCAMApp.py:9925 +#: FlatCAMApp.py:10281 +msgid "Go to Line ..." +msgstr "Ir a la línea ..." + +#: FlatCAMApp.py:10282 +msgid "Line:" +msgstr "Línea:" + +#: FlatCAMApp.py:10311 msgid "New TCL script file created in Code Editor." msgstr "Nuevo archivo de script TCL creado en Code Editor." -#: FlatCAMApp.py:9963 FlatCAMApp.py:9965 +#: FlatCAMApp.py:10350 FlatCAMApp.py:10352 msgid "Open TCL script" msgstr "Abrir script TCL" -#: FlatCAMApp.py:9969 -msgid "Open TCL script cancelled." -msgstr "Abrir el script TCL cancelado." - -#: FlatCAMApp.py:9993 +#: FlatCAMApp.py:10380 msgid "Executing FlatCAMScript file." msgstr "Ejecutando archivo FlatCAMScript." -#: FlatCAMApp.py:10000 FlatCAMApp.py:10003 +#: FlatCAMApp.py:10388 FlatCAMApp.py:10391 msgid "Run TCL script" msgstr "Ejecutar script TCL" -#: FlatCAMApp.py:10013 -msgid "Run TCL script cancelled." -msgstr "Ejecutar script TCL cancelado." - -#: FlatCAMApp.py:10029 +#: FlatCAMApp.py:10415 msgid "TCL script file opened in Code Editor and executed." msgstr "El archivo de script TCL se abrió en el Editor de código y se ejecutó." -#: FlatCAMApp.py:10080 FlatCAMApp.py:10086 +#: FlatCAMApp.py:10466 FlatCAMApp.py:10472 msgid "Save Project As ..." msgstr "Guardar proyecto como ..." -#: FlatCAMApp.py:10082 flatcamGUI/FlatCAMGUI.py:1051 -#: flatcamGUI/FlatCAMGUI.py:2053 +#: FlatCAMApp.py:10468 flatcamGUI/FlatCAMGUI.py:1119 +#: flatcamGUI/FlatCAMGUI.py:2161 msgid "Project" msgstr "Proyecto" -#: FlatCAMApp.py:10091 -msgid "Save Project cancelled." -msgstr "Guardar Proyecto cancelado." - -#: FlatCAMApp.py:10121 +#: FlatCAMApp.py:10507 msgid "FlatCAM objects print" msgstr "Impresión de objetos FlatCAM" -#: FlatCAMApp.py:10134 FlatCAMApp.py:10141 +#: FlatCAMApp.py:10520 FlatCAMApp.py:10527 msgid "Save Object as PDF ..." msgstr "Guardar objeto como PDF ..." -#: FlatCAMApp.py:10146 -msgid "Save Object PDF cancelled." -msgstr "Guardar objeto PDF cancelado." - -#: FlatCAMApp.py:10150 +#: FlatCAMApp.py:10536 msgid "Printing PDF ... Please wait." msgstr "Imprimiendo PDF ... Por favor espere." -#: FlatCAMApp.py:10329 +#: FlatCAMApp.py:10715 msgid "PDF file saved to" msgstr "Archivo PDF guardado en" -#: FlatCAMApp.py:10353 +#: FlatCAMApp.py:10740 msgid "Exporting SVG" msgstr "Exportando SVG" -#: FlatCAMApp.py:10397 +#: FlatCAMApp.py:10783 msgid "SVG file exported to" msgstr "Archivo SVG exportado a" -#: FlatCAMApp.py:10422 +#: FlatCAMApp.py:10809 msgid "" "Save cancelled because source file is empty. Try to export the Gerber file." msgstr "" "Guardar cancelado porque el archivo fuente está vacío. Intenta exportar el " "archivo Gerber." -#: FlatCAMApp.py:10568 +#: FlatCAMApp.py:10957 msgid "Excellon file exported to" msgstr "Archivo Excellon exportado a" -#: FlatCAMApp.py:10577 +#: FlatCAMApp.py:10966 msgid "Exporting Excellon" msgstr "Exportando excellon" -#: FlatCAMApp.py:10583 FlatCAMApp.py:10591 +#: FlatCAMApp.py:10971 FlatCAMApp.py:10978 msgid "Could not export Excellon file." msgstr "No se pudo exportar el archivo Excellon." -#: FlatCAMApp.py:10707 +#: FlatCAMApp.py:11094 msgid "Gerber file exported to" msgstr "Archivo Gerber exportado a" -#: FlatCAMApp.py:10715 +#: FlatCAMApp.py:11102 msgid "Exporting Gerber" msgstr "Gerber exportador" -#: FlatCAMApp.py:10721 FlatCAMApp.py:10729 +#: FlatCAMApp.py:11107 FlatCAMApp.py:11114 msgid "Could not export Gerber file." msgstr "No se pudo exportar el archivo Gerber." -#: FlatCAMApp.py:10763 +#: FlatCAMApp.py:11149 msgid "DXF file exported to" msgstr "Archivo DXF exportado a" -#: FlatCAMApp.py:10769 +#: FlatCAMApp.py:11155 msgid "Exporting DXF" msgstr "Exportando DXF" -#: FlatCAMApp.py:10774 FlatCAMApp.py:10781 +#: FlatCAMApp.py:11160 FlatCAMApp.py:11167 msgid "Could not export DXF file." msgstr "No se pudo exportar el archivo DXF." -#: FlatCAMApp.py:10804 FlatCAMApp.py:10847 flatcamTools/ToolImage.py:278 +#: FlatCAMApp.py:11190 FlatCAMApp.py:11232 flatcamTools/ToolImage.py:277 msgid "" "Not supported type is picked as parameter. Only Geometry and Gerber are " "supported" @@ -1318,83 +1276,83 @@ msgstr "" "El tipo no soportado se elige como parámetro. Solo Geometría y Gerber son " "compatibles" -#: FlatCAMApp.py:10814 +#: FlatCAMApp.py:11200 msgid "Importing SVG" msgstr "Importando SVG" -#: FlatCAMApp.py:10825 FlatCAMApp.py:10867 FlatCAMApp.py:10926 -#: FlatCAMApp.py:10993 FlatCAMApp.py:11056 FlatCAMApp.py:11123 -#: FlatCAMApp.py:11161 flatcamTools/ToolImage.py:298 +#: FlatCAMApp.py:11211 FlatCAMApp.py:11251 FlatCAMApp.py:11309 +#: FlatCAMApp.py:11374 FlatCAMApp.py:11438 FlatCAMApp.py:11503 +#: FlatCAMApp.py:11540 flatcamTools/ToolImage.py:297 #: flatcamTools/ToolPDF.py:225 msgid "Opened" msgstr "Abierto" -#: FlatCAMApp.py:10856 +#: FlatCAMApp.py:11241 msgid "Importing DXF" msgstr "Importando DXF" -#: FlatCAMApp.py:10892 FlatCAMApp.py:11082 +#: FlatCAMApp.py:11275 FlatCAMApp.py:11462 msgid "Failed to open file" msgstr "Fallo al abrir el archivo" -#: FlatCAMApp.py:10895 FlatCAMApp.py:11085 +#: FlatCAMApp.py:11278 FlatCAMApp.py:11465 msgid "Failed to parse file" msgstr "Error al analizar el archivo" -#: FlatCAMApp.py:10907 +#: FlatCAMApp.py:11290 msgid "Object is not Gerber file or empty. Aborting object creation." msgstr "" "El objeto no es un archivo Gerber o está vacío. Anulando la creación de " "objetos." -#: FlatCAMApp.py:10912 +#: FlatCAMApp.py:11295 msgid "Opening Gerber" msgstr "Apertura de gerber" -#: FlatCAMApp.py:10919 +#: FlatCAMApp.py:11302 msgid " Open Gerber failed. Probable not a Gerber file." msgstr " Gerber abierto fracasó. Probablemente no sea un archivo de Gerber." -#: FlatCAMApp.py:10951 flatcamTools/ToolPcbWizard.py:427 +#: FlatCAMApp.py:11333 flatcamTools/ToolPcbWizard.py:425 msgid "This is not Excellon file." msgstr "Este no es un archivo de Excellon." -#: FlatCAMApp.py:10955 +#: FlatCAMApp.py:11337 msgid "Cannot open file" msgstr "No se puede abrir el archivo" -#: FlatCAMApp.py:10975 flatcamTools/ToolPDF.py:275 -#: flatcamTools/ToolPcbWizard.py:451 +#: FlatCAMApp.py:11356 flatcamTools/ToolPDF.py:275 +#: flatcamTools/ToolPcbWizard.py:447 msgid "No geometry found in file" msgstr "No se encontró geometría en el archivo" -#: FlatCAMApp.py:10978 +#: FlatCAMApp.py:11359 msgid "Opening Excellon." msgstr "Apertura Excellon." -#: FlatCAMApp.py:10985 +#: FlatCAMApp.py:11366 msgid "Open Excellon file failed. Probable not an Excellon file." msgstr "" "Error al abrir el archivo Excellon. Probablemente no sea un archivo de " "Excellon." -#: FlatCAMApp.py:11016 +#: FlatCAMApp.py:11398 msgid "Reading GCode file" msgstr "Lectura de archivo GCode" -#: FlatCAMApp.py:11023 +#: FlatCAMApp.py:11405 msgid "Failed to open" msgstr "Falló al abrir" -#: FlatCAMApp.py:11031 +#: FlatCAMApp.py:11413 msgid "This is not GCODE" msgstr "Esto no es GCODE" -#: FlatCAMApp.py:11036 +#: FlatCAMApp.py:11418 msgid "Opening G-Code." msgstr "Apertura del código G." -#: FlatCAMApp.py:11045 +#: FlatCAMApp.py:11427 msgid "" "Failed to create CNCJob Object. Probable not a GCode file. Try to load it " "from File menu.\n" @@ -1406,125 +1364,105 @@ msgstr "" "Intento de crear un objeto FlatCAM CNCJob desde el archivo G-Code falló " "durante el procesamiento" -#: FlatCAMApp.py:11104 +#: FlatCAMApp.py:11484 msgid "Object is not HPGL2 file or empty. Aborting object creation." msgstr "" "El objeto no es un archivo HPGL2 o está vacío. Anulando la creación de " "objetos." -#: FlatCAMApp.py:11109 +#: FlatCAMApp.py:11489 msgid "Opening HPGL2" msgstr "Apertura de HPGL2" -#: FlatCAMApp.py:11116 +#: FlatCAMApp.py:11496 msgid " Open HPGL2 failed. Probable not a HPGL2 file." msgstr " Abrir HPGL2 falló. Probablemente no sea un archivo HPGL2." -#: FlatCAMApp.py:11137 +#: FlatCAMApp.py:11516 msgid "Opening TCL Script..." msgstr "Abriendo TCL Script ..." -#: FlatCAMApp.py:11145 +#: FlatCAMApp.py:11524 msgid "TCL script file opened in Code Editor." msgstr "Archivo de script TCL abierto en Code Editor." -#: FlatCAMApp.py:11148 +#: FlatCAMApp.py:11527 msgid "Failed to open TCL Script." msgstr "Error al abrir la secuencia de comandos TCL." -#: FlatCAMApp.py:11176 +#: FlatCAMApp.py:11555 msgid "Opening FlatCAM Config file." msgstr "Abrir el archivo de configuración de FlatCAM." -#: FlatCAMApp.py:11204 +#: FlatCAMApp.py:11583 msgid "Failed to open config file" msgstr "Error al abrir el archivo de configuración" -#: FlatCAMApp.py:11230 +#: FlatCAMApp.py:11611 msgid "Loading Project ... Please Wait ..." msgstr "Cargando proyecto ... Espere ..." -#: FlatCAMApp.py:11235 +#: FlatCAMApp.py:11616 msgid "Opening FlatCAM Project file." msgstr "Apertura del archivo del proyecto FlatCAM." -#: FlatCAMApp.py:11245 FlatCAMApp.py:11263 +#: FlatCAMApp.py:11626 FlatCAMApp.py:11644 msgid "Failed to open project file" msgstr "Error al abrir el archivo del proyecto" -#: FlatCAMApp.py:11300 +#: FlatCAMApp.py:11681 msgid "Loading Project ... restoring" msgstr "Cargando Proyecto ... restaurando" -#: FlatCAMApp.py:11310 +#: FlatCAMApp.py:11691 msgid "Project loaded from" msgstr "Proyecto cargado desde" -#: FlatCAMApp.py:11373 +#: FlatCAMApp.py:11760 msgid "Redrawing all objects" msgstr "Redibujando todos los objetos" -#: FlatCAMApp.py:11405 -msgid "Available commands:\n" -msgstr "Comandos disponibles:\n" - -#: FlatCAMApp.py:11407 -msgid "" -"\n" -"\n" -"Type help for usage.\n" -" Example: help open_gerber" -msgstr "" -"\n" -"\n" -"Escriba help para su uso.\n" -"Ejemplo: help open_gerber" - -#: FlatCAMApp.py:11557 -msgid "Shows list of commands." -msgstr "Muestra la lista de comandos." - -#: FlatCAMApp.py:11619 +#: FlatCAMApp.py:11849 msgid "Failed to load recent item list." msgstr "Error al cargar la lista de elementos recientes." -#: FlatCAMApp.py:11627 +#: FlatCAMApp.py:11856 msgid "Failed to parse recent item list." msgstr "Error al analizar la lista de elementos recientes." -#: FlatCAMApp.py:11638 +#: FlatCAMApp.py:11866 msgid "Failed to load recent projects item list." msgstr "Error al cargar la lista de elementos de proyectos recientes." -#: FlatCAMApp.py:11646 +#: FlatCAMApp.py:11873 msgid "Failed to parse recent project item list." msgstr "Error al analizar la lista de elementos del proyecto reciente." -#: FlatCAMApp.py:11706 +#: FlatCAMApp.py:11934 msgid "Clear Recent projects" msgstr "Borrar proyectos recientes" -#: FlatCAMApp.py:11730 +#: FlatCAMApp.py:11958 msgid "Clear Recent files" msgstr "Borrar archivos recientes" -#: FlatCAMApp.py:11747 flatcamGUI/FlatCAMGUI.py:1276 +#: FlatCAMApp.py:11980 flatcamGUI/FlatCAMGUI.py:1348 msgid "Shortcut Key List" msgstr " Lista de teclas de acceso directo " -#: FlatCAMApp.py:11821 +#: FlatCAMApp.py:12054 msgid "Selected Tab - Choose an Item from Project Tab" msgstr "Pestaña Seleccionada: elija un elemento de la pestaña Proyecto" -#: FlatCAMApp.py:11822 +#: FlatCAMApp.py:12055 msgid "Details" msgstr "Detalles" -#: FlatCAMApp.py:11824 +#: FlatCAMApp.py:12057 msgid "The normal flow when working in FlatCAM is the following:" msgstr "El flujo normal cuando se trabaja en FlatCAM es el siguiente:" -#: FlatCAMApp.py:11825 +#: FlatCAMApp.py:12058 msgid "" "Load/Import a Gerber, Excellon, Gcode, DXF, Raster Image or SVG file into " "FlatCAM using either the toolbars, key shortcuts or even dragging and " @@ -1534,7 +1472,7 @@ msgstr "" "en FlatCAM usando las barras de herramientas, atajos de teclado o incluso " "arrastrando y soltando los archivos en la GUI." -#: FlatCAMApp.py:11828 +#: FlatCAMApp.py:12061 msgid "" "You can also load a FlatCAM project by double clicking on the project file, " "drag and drop of the file into the FLATCAM GUI or through the menu (or " @@ -1545,7 +1483,7 @@ msgstr "" "mediante las acciones del menú (o barra de herramientas) que se ofrecen " "dentro de la aplicación." -#: FlatCAMApp.py:11831 +#: FlatCAMApp.py:12064 msgid "" "Once an object is available in the Project Tab, by selecting it and then " "focusing on SELECTED TAB (more simpler is to double click the object name in " @@ -1558,7 +1496,7 @@ msgstr "" "SELECCIONADA se actualizará con las propiedades del objeto según su tipo: " "Gerber, Objeto Excellon, Geometry o CNCJob." -#: FlatCAMApp.py:11835 +#: FlatCAMApp.py:12068 msgid "" "If the selection of the object is done on the canvas by single click " "instead, and the SELECTED TAB is in focus, again the object properties will " @@ -1572,7 +1510,7 @@ msgstr "" "el objeto en el lienzo traerá la PESTAÑA SELECCIONADA y la completará " "incluso si estaba fuera de foco." -#: FlatCAMApp.py:11839 +#: FlatCAMApp.py:12072 msgid "" "You can change the parameters in this screen and the flow direction is like " "this:" @@ -1580,7 +1518,7 @@ msgstr "" "Puede cambiar los parámetros en esta pantalla y la dirección del flujo es " "así:" -#: FlatCAMApp.py:11840 +#: FlatCAMApp.py:12073 msgid "" "Gerber/Excellon Object --> Change Parameter --> Generate Geometry --> " "Geometry Object --> Add tools (change param in Selected Tab) --> Generate " @@ -1593,7 +1531,7 @@ msgstr "" "(mediante Edit CNC Código) y / o anexar / anteponer a GCode (nuevamente, " "hecho en la PESTAÑA SELECCIONADA) -> Guardar GCode." -#: FlatCAMApp.py:11844 +#: FlatCAMApp.py:12077 msgid "" "A list of key shortcuts is available through an menu entry in Help --> " "Shortcuts List or through its own key shortcut: F3." @@ -1602,103 +1540,167 @@ msgstr "" "menú en Ayuda -> Lista de atajos o mediante su propio atajo de teclado: " "F3 ." -#: FlatCAMApp.py:11906 +#: FlatCAMApp.py:12141 msgid "Failed checking for latest version. Could not connect." msgstr "Falló la comprobación de la última versión. No pudo conectar." -#: FlatCAMApp.py:11914 +#: FlatCAMApp.py:12148 msgid "Could not parse information about latest version." msgstr "No se pudo analizar la información sobre la última versión." -#: FlatCAMApp.py:11925 +#: FlatCAMApp.py:12158 msgid "FlatCAM is up to date!" msgstr "FlatCAM está al día!" -#: FlatCAMApp.py:11930 +#: FlatCAMApp.py:12163 msgid "Newer Version Available" msgstr "Nueva versión disponible" -#: FlatCAMApp.py:11931 -msgid "" -"There is a newer version of FlatCAM available for download:\n" -"\n" -msgstr "" -"Hay una versión más nueva de FlatCAM disponible para descargar:\n" -"\n" +#: FlatCAMApp.py:12165 +msgid "There is a newer version of FlatCAM available for download:" +msgstr "Hay una versión más nueva de FlatCAM disponible para descargar:" -#: FlatCAMApp.py:11933 +#: FlatCAMApp.py:12169 msgid "info" msgstr "info" -#: FlatCAMApp.py:12012 +#: FlatCAMApp.py:12197 +msgid "" +"OpenGL canvas initialization failed. HW or HW configuration not supported." +"Change the graphic engine to Legacy(2D) in Edit -> Preferences -> General " +"tab.\n" +"\n" +msgstr "" +"La inicialización del lienzo de OpenGL falló. No se admite la configuración " +"HW o HW. Cambie el motor gráfico a Legacy (2D) en Edición -> Preferencias -> " +"pestaña General.\n" +"\n" + +#: FlatCAMApp.py:12276 msgid "All plots disabled." msgstr "Todas las parcelas con discapacidad." -#: FlatCAMApp.py:12019 +#: FlatCAMApp.py:12283 msgid "All non selected plots disabled." msgstr "Todas las parcelas no seleccionadas deshabilitadas." -#: FlatCAMApp.py:12026 +#: FlatCAMApp.py:12290 msgid "All plots enabled." msgstr "Todas las parcelas habilitadas." -#: FlatCAMApp.py:12033 +#: FlatCAMApp.py:12296 msgid "Selected plots enabled..." msgstr "Parcelas seleccionadas habilitadas ..." -#: FlatCAMApp.py:12042 +#: FlatCAMApp.py:12304 msgid "Selected plots disabled..." msgstr "Parcelas seleccionadas deshabilitadas ..." -#: FlatCAMApp.py:12061 +#: FlatCAMApp.py:12337 msgid "Enabling plots ..." msgstr "Habilitación de parcelas ..." -#: FlatCAMApp.py:12101 +#: FlatCAMApp.py:12389 msgid "Disabling plots ..." msgstr "Inhabilitando parcelas ..." -#: FlatCAMApp.py:12123 +#: FlatCAMApp.py:12412 msgid "Working ..." msgstr "Trabajando ..." -#: FlatCAMApp.py:12224 +#: FlatCAMApp.py:12467 flatcamGUI/FlatCAMGUI.py:688 +msgid "Red" +msgstr "Rojo" + +#: FlatCAMApp.py:12469 flatcamGUI/FlatCAMGUI.py:691 +msgid "Blue" +msgstr "Azul" + +#: FlatCAMApp.py:12472 flatcamGUI/FlatCAMGUI.py:694 +msgid "Yellow" +msgstr "Amarillo" + +#: FlatCAMApp.py:12474 flatcamGUI/FlatCAMGUI.py:697 +msgid "Green" +msgstr "Verde" + +#: FlatCAMApp.py:12476 flatcamGUI/FlatCAMGUI.py:700 +msgid "Purple" +msgstr "Púrpura" + +#: FlatCAMApp.py:12478 flatcamGUI/FlatCAMGUI.py:703 +msgid "Brown" +msgstr "Marrón" + +#: FlatCAMApp.py:12480 FlatCAMApp.py:12536 flatcamGUI/FlatCAMGUI.py:706 +msgid "White" +msgstr "Blanca" + +#: FlatCAMApp.py:12482 flatcamGUI/FlatCAMGUI.py:709 +msgid "Black" +msgstr "Negra" + +#: FlatCAMApp.py:12485 flatcamGUI/FlatCAMGUI.py:714 +msgid "Custom" +msgstr "Personalizado" + +#: FlatCAMApp.py:12495 flatcamGUI/FlatCAMGUI.py:722 +msgid "Default" +msgstr "Predeterminado" + +#: FlatCAMApp.py:12519 flatcamGUI/FlatCAMGUI.py:719 +msgid "Opacity" +msgstr "Opacidad" + +#: FlatCAMApp.py:12521 +msgid "Set alpha level ..." +msgstr "Establecer nivel alfa ..." + +#: FlatCAMApp.py:12521 flatcamGUI/PreferencesUI.py:6900 +#: flatcamGUI/PreferencesUI.py:8230 flatcamGUI/PreferencesUI.py:8444 +#: flatcamTools/ToolExtractDrills.py:164 flatcamTools/ToolExtractDrills.py:285 +#: flatcamTools/ToolPunchGerber.py:192 flatcamTools/ToolPunchGerber.py:308 +#: flatcamTools/ToolTransform.py:358 +msgid "Value" +msgstr "Valor" + +#: FlatCAMApp.py:12597 msgid "Saving FlatCAM Project" msgstr "Proyecto FlatCAM de ahorro" -#: FlatCAMApp.py:12243 FlatCAMApp.py:12280 +#: FlatCAMApp.py:12618 FlatCAMApp.py:12654 msgid "Project saved to" msgstr "Proyecto guardado en" -#: FlatCAMApp.py:12250 +#: FlatCAMApp.py:12625 msgid "The object is used by another application." msgstr "El objeto es utilizado por otra aplicación." -#: FlatCAMApp.py:12264 +#: FlatCAMApp.py:12639 msgid "Failed to verify project file" msgstr "Error al abrir el archivo de proyecto" -#: FlatCAMApp.py:12264 FlatCAMApp.py:12272 FlatCAMApp.py:12283 +#: FlatCAMApp.py:12639 FlatCAMApp.py:12647 FlatCAMApp.py:12657 msgid "Retry to save it." msgstr "Vuelva a intentar guardarlo." -#: FlatCAMApp.py:12272 FlatCAMApp.py:12283 +#: FlatCAMApp.py:12647 FlatCAMApp.py:12657 msgid "Failed to parse saved project file" msgstr "Error al analizar el archivo por defecto" -#: FlatCAMApp.py:12398 +#: FlatCAMApp.py:13139 msgid "The user requested a graceful exit of the current task." msgstr "El usuario solicitó una salida elegante de la tarea actual." -#: FlatCAMCommon.py:136 FlatCAMCommon.py:163 +#: FlatCAMCommon.py:137 FlatCAMCommon.py:164 msgid "Title" msgstr "Título" -#: FlatCAMCommon.py:137 FlatCAMCommon.py:167 +#: FlatCAMCommon.py:138 FlatCAMCommon.py:168 msgid "Web Link" msgstr "Enlace Web" -#: FlatCAMCommon.py:141 +#: FlatCAMCommon.py:142 msgid "" "Index.\n" "The rows in gray color will populate the Bookmarks menu.\n" @@ -1708,7 +1710,7 @@ msgstr "" "Las filas en color gris llenarán el menú Marcadores.\n" "El número de filas de color gris se establece en Preferencias." -#: FlatCAMCommon.py:145 +#: FlatCAMCommon.py:146 msgid "" "Description of the link that is set as an menu action.\n" "Try to keep it short because it is installed as a menu item." @@ -1716,95 +1718,87 @@ msgstr "" "Descripción del enlace que se establece como una acción de menú.\n" "Intenta mantenerlo corto porque está instalado como un elemento del menú." -#: FlatCAMCommon.py:148 +#: FlatCAMCommon.py:149 msgid "Web Link. E.g: https://your_website.org " msgstr "Enlace web. P.ej: https://your_website.org " -#: FlatCAMCommon.py:157 +#: FlatCAMCommon.py:158 msgid "New Bookmark" msgstr "Nuevo Marcador" -#: FlatCAMCommon.py:176 +#: FlatCAMCommon.py:177 msgid "Add Entry" msgstr "Añadir entrada" -#: FlatCAMCommon.py:177 +#: FlatCAMCommon.py:178 msgid "Remove Entry" msgstr "Remueva la entrada" -#: FlatCAMCommon.py:178 +#: FlatCAMCommon.py:179 msgid "Export List" msgstr "Exportar la lista" -#: FlatCAMCommon.py:179 +#: FlatCAMCommon.py:180 msgid "Import List" msgstr "Importar la lista" -#: FlatCAMCommon.py:260 +#: FlatCAMCommon.py:261 msgid "Title entry is empty." msgstr "La entrada del título está vacía." -#: FlatCAMCommon.py:269 +#: FlatCAMCommon.py:270 msgid "Web link entry is empty." msgstr "La entrada del enlace web está vacía." -#: FlatCAMCommon.py:277 +#: FlatCAMCommon.py:278 msgid "Either the Title or the Weblink already in the table." msgstr "Ya sea el Título o el Enlace web ya en la tabla." -#: FlatCAMCommon.py:297 +#: FlatCAMCommon.py:298 msgid "Bookmark added." msgstr "Marcador agregado." -#: FlatCAMCommon.py:314 +#: FlatCAMCommon.py:315 msgid "This bookmark can not be removed" msgstr "Este marcador no se puede eliminar" -#: FlatCAMCommon.py:345 +#: FlatCAMCommon.py:346 msgid "Bookmark removed." msgstr "Marcador eliminado." -#: FlatCAMCommon.py:360 +#: FlatCAMCommon.py:361 msgid "Export FlatCAM Bookmarks" msgstr "Exportar marcadores de FlatCAM" -#: FlatCAMCommon.py:363 flatcamGUI/FlatCAMGUI.py:470 +#: FlatCAMCommon.py:364 flatcamGUI/FlatCAMGUI.py:509 msgid "Bookmarks" msgstr "Marcadores" -#: FlatCAMCommon.py:370 -msgid "FlatCAM bookmarks export cancelled." -msgstr "Exportación de marcadores de FlatCAM cancelada." - -#: FlatCAMCommon.py:389 FlatCAMCommon.py:419 +#: FlatCAMCommon.py:390 FlatCAMCommon.py:420 msgid "Could not load bookmarks file." msgstr "No se pudo cargar el archivo de marcadores." -#: FlatCAMCommon.py:399 +#: FlatCAMCommon.py:400 msgid "Failed to write bookmarks to file." msgstr "Error al escribir marcadores en el archivo." -#: FlatCAMCommon.py:401 +#: FlatCAMCommon.py:402 msgid "Exported bookmarks to" msgstr "Marcadores exportados a" -#: FlatCAMCommon.py:407 +#: FlatCAMCommon.py:408 msgid "Import FlatCAM Bookmarks" msgstr "Importar marcadores de FlatCAM" -#: FlatCAMCommon.py:412 -msgid "FlatCAM bookmarks import cancelled." -msgstr "Se canceló la importación de marcadores de FlatCAM." - -#: FlatCAMCommon.py:426 +#: FlatCAMCommon.py:427 msgid "Imported Bookmarks from" msgstr "Marcadores importados de" -#: FlatCAMCommon.py:529 +#: FlatCAMCommon.py:530 msgid "Add Geometry Tool in DB" msgstr "Agregar herramienta de geo. en DB" -#: FlatCAMCommon.py:531 +#: FlatCAMCommon.py:532 FlatCAMCommon.py:2087 msgid "" "Add a new tool in the Tools Database.\n" "It will be used in the Geometry UI.\n" @@ -1814,38 +1808,38 @@ msgstr "" "Se utilizará en la interfaz de usuario de geometría.\n" "Puede editarlo después de agregarlo." -#: FlatCAMCommon.py:545 +#: FlatCAMCommon.py:546 FlatCAMCommon.py:2101 msgid "Delete Tool from DB" msgstr "Eliminar herram. de la BD" -#: FlatCAMCommon.py:547 +#: FlatCAMCommon.py:548 FlatCAMCommon.py:2103 msgid "Remove a selection of tools in the Tools Database." msgstr "Eliminar una selección de herramientas en la DB de herramientas." -#: FlatCAMCommon.py:551 +#: FlatCAMCommon.py:552 FlatCAMCommon.py:2107 msgid "Export DB" msgstr "Exportar DB" -#: FlatCAMCommon.py:553 +#: FlatCAMCommon.py:554 FlatCAMCommon.py:2109 msgid "Save the Tools Database to a custom text file." msgstr "" "Guarde la base de datos de herramientas en un archivo de texto personalizado." -#: FlatCAMCommon.py:557 +#: FlatCAMCommon.py:558 FlatCAMCommon.py:2113 msgid "Import DB" msgstr "Importar DB" -#: FlatCAMCommon.py:559 +#: FlatCAMCommon.py:560 FlatCAMCommon.py:2115 msgid "Load the Tools Database information's from a custom text file." msgstr "" "Cargue la información de la DB de herramientas desde un archivo de texto " "personalizado." -#: FlatCAMCommon.py:563 +#: FlatCAMCommon.py:564 FlatCAMCommon.py:2119 msgid "Add Tool from Tools DB" msgstr "Agregar herramienta desde DB de herramientas" -#: FlatCAMCommon.py:565 +#: FlatCAMCommon.py:566 FlatCAMCommon.py:2121 msgid "" "Add a new tool in the Tools Table of the\n" "active Geometry object after selecting a tool\n" @@ -1855,135 +1849,144 @@ msgstr "" "objeto de geometría activo después de seleccionar una herramienta\n" "en la base de datos de herramientas." -#: FlatCAMCommon.py:601 FlatCAMCommon.py:1276 +#: FlatCAMCommon.py:602 FlatCAMCommon.py:1277 FlatCAMCommon.py:1531 msgid "Tool Name" msgstr "Nombre de Herram" -#: FlatCAMCommon.py:602 FlatCAMCommon.py:1278 -#: flatcamEditors/FlatCAMExcEditor.py:1602 flatcamGUI/ObjectUI.py:1295 -#: flatcamTools/ToolNonCopperClear.py:271 flatcamTools/ToolPaint.py:176 +#: FlatCAMCommon.py:603 FlatCAMCommon.py:1279 FlatCAMCommon.py:1544 +#: flatcamEditors/FlatCAMExcEditor.py:1605 flatcamGUI/ObjectUI.py:1343 +#: flatcamGUI/ObjectUI.py:1581 flatcamGUI/PreferencesUI.py:5971 +#: flatcamTools/ToolNCC.py:278 flatcamTools/ToolNCC.py:287 +#: flatcamTools/ToolPaint.py:261 msgid "Tool Dia" msgstr "Diá. de Herram" -#: FlatCAMCommon.py:603 FlatCAMCommon.py:1280 flatcamGUI/ObjectUI.py:1278 +#: FlatCAMCommon.py:604 FlatCAMCommon.py:1281 FlatCAMCommon.py:1725 +#: flatcamGUI/ObjectUI.py:1556 msgid "Tool Offset" msgstr "Offset de Herram" -#: FlatCAMCommon.py:604 FlatCAMCommon.py:1282 +#: FlatCAMCommon.py:605 FlatCAMCommon.py:1283 FlatCAMCommon.py:1742 msgid "Custom Offset" -msgstr "Desplazamiento person." +msgstr "Desplazamiento personalizado" -#: FlatCAMCommon.py:605 FlatCAMCommon.py:1284 flatcamGUI/ObjectUI.py:304 -#: flatcamGUI/PreferencesUI.py:2217 flatcamGUI/PreferencesUI.py:5036 -#: flatcamTools/ToolNonCopperClear.py:213 +#: FlatCAMCommon.py:606 FlatCAMCommon.py:1285 FlatCAMCommon.py:1709 +#: flatcamGUI/ObjectUI.py:308 flatcamGUI/PreferencesUI.py:2397 +#: flatcamGUI/PreferencesUI.py:5332 flatcamGUI/PreferencesUI.py:5901 +#: flatcamGUI/PreferencesUI.py:5911 flatcamTools/ToolNCC.py:213 +#: flatcamTools/ToolNCC.py:227 flatcamTools/ToolPaint.py:196 msgid "Tool Type" msgstr "Tipo de herram" -#: FlatCAMCommon.py:606 FlatCAMCommon.py:1286 +#: FlatCAMCommon.py:607 FlatCAMCommon.py:1287 FlatCAMCommon.py:1557 msgid "Tool Shape" msgstr "Forma de la herram" -#: FlatCAMCommon.py:607 FlatCAMCommon.py:1289 flatcamGUI/ObjectUI.py:345 -#: flatcamGUI/ObjectUI.py:820 flatcamGUI/ObjectUI.py:1405 -#: flatcamGUI/ObjectUI.py:1926 flatcamGUI/PreferencesUI.py:2257 -#: flatcamGUI/PreferencesUI.py:3082 flatcamGUI/PreferencesUI.py:3961 -#: flatcamGUI/PreferencesUI.py:5081 flatcamGUI/PreferencesUI.py:5327 -#: flatcamGUI/PreferencesUI.py:6145 flatcamTools/ToolCalculators.py:114 -#: flatcamTools/ToolCutOut.py:132 flatcamTools/ToolNonCopperClear.py:254 +#: FlatCAMCommon.py:608 FlatCAMCommon.py:1290 FlatCAMCommon.py:1573 +#: flatcamGUI/ObjectUI.py:349 flatcamGUI/ObjectUI.py:899 +#: flatcamGUI/ObjectUI.py:1701 flatcamGUI/ObjectUI.py:2254 +#: flatcamGUI/PreferencesUI.py:2437 flatcamGUI/PreferencesUI.py:3311 +#: flatcamGUI/PreferencesUI.py:4241 flatcamGUI/PreferencesUI.py:5377 +#: flatcamGUI/PreferencesUI.py:5666 flatcamGUI/PreferencesUI.py:5944 +#: flatcamGUI/PreferencesUI.py:5952 flatcamGUI/PreferencesUI.py:6635 +#: flatcamTools/ToolCalculators.py:114 flatcamTools/ToolCutOut.py:139 +#: flatcamTools/ToolNCC.py:260 flatcamTools/ToolNCC.py:268 +#: flatcamTools/ToolPaint.py:243 msgid "Cut Z" msgstr "Corte Z" -#: FlatCAMCommon.py:608 FlatCAMCommon.py:1291 +#: FlatCAMCommon.py:609 FlatCAMCommon.py:1292 FlatCAMCommon.py:1587 msgid "MultiDepth" msgstr "Profund. Múlti" -#: FlatCAMCommon.py:609 FlatCAMCommon.py:1293 +#: FlatCAMCommon.py:610 FlatCAMCommon.py:1294 FlatCAMCommon.py:1600 msgid "DPP" msgstr "PPP" -#: FlatCAMCommon.py:610 FlatCAMCommon.py:1295 +#: FlatCAMCommon.py:611 FlatCAMCommon.py:1296 FlatCAMCommon.py:1756 msgid "V-Dia" msgstr "V-Dia" -#: FlatCAMCommon.py:611 FlatCAMCommon.py:1297 +#: FlatCAMCommon.py:612 FlatCAMCommon.py:1298 FlatCAMCommon.py:1770 msgid "V-Angle" msgstr "V-Ángulo" -#: FlatCAMCommon.py:612 FlatCAMCommon.py:1299 flatcamGUI/ObjectUI.py:839 -#: flatcamGUI/ObjectUI.py:1452 flatcamGUI/PreferencesUI.py:3100 -#: flatcamGUI/PreferencesUI.py:4014 flatcamGUI/PreferencesUI.py:7535 +#: FlatCAMCommon.py:613 FlatCAMCommon.py:1300 FlatCAMCommon.py:1614 +#: FlatCAMObj.py:3661 FlatCAMObj.py:5486 flatcamGUI/ObjectUI.py:945 +#: flatcamGUI/ObjectUI.py:1748 flatcamGUI/PreferencesUI.py:3352 +#: flatcamGUI/PreferencesUI.py:4294 flatcamGUI/PreferencesUI.py:8041 #: flatcamTools/ToolCalibration.py:74 msgid "Travel Z" msgstr "Viaje Z" -#: FlatCAMCommon.py:613 FlatCAMCommon.py:1301 +#: FlatCAMCommon.py:614 FlatCAMCommon.py:1302 msgid "FR" msgstr "FR" -#: FlatCAMCommon.py:614 FlatCAMCommon.py:1303 +#: FlatCAMCommon.py:615 FlatCAMCommon.py:1304 msgid "FR Z" msgstr "FR Z" -#: FlatCAMCommon.py:615 FlatCAMCommon.py:1305 +#: FlatCAMCommon.py:616 FlatCAMCommon.py:1306 FlatCAMCommon.py:1784 msgid "FR Rapids" msgstr "Avance rápido" -#: FlatCAMCommon.py:616 FlatCAMCommon.py:1307 flatcamGUI/PreferencesUI.py:3173 +#: FlatCAMCommon.py:617 FlatCAMCommon.py:1308 FlatCAMCommon.py:1657 +#: flatcamGUI/PreferencesUI.py:3440 msgid "Spindle Speed" msgstr "Eje de velocidad" -#: FlatCAMCommon.py:617 FlatCAMCommon.py:1309 flatcamGUI/ObjectUI.py:963 -#: flatcamGUI/ObjectUI.py:1619 +#: FlatCAMCommon.py:618 FlatCAMCommon.py:1310 FlatCAMCommon.py:1672 +#: flatcamGUI/ObjectUI.py:1063 flatcamGUI/ObjectUI.py:1855 msgid "Dwell" msgstr "Habitar" -#: FlatCAMCommon.py:618 FlatCAMCommon.py:1311 +#: FlatCAMCommon.py:619 FlatCAMCommon.py:1312 FlatCAMCommon.py:1685 msgid "Dwelltime" -msgstr "Tiempo de perman." +msgstr "Tiempo de permanencia" -#: FlatCAMCommon.py:619 FlatCAMCommon.py:1313 flatcamGUI/ObjectUI.py:982 -#: flatcamGUI/ObjectUI.py:1640 flatcamGUI/PreferencesUI.py:3204 -#: flatcamGUI/PreferencesUI.py:4155 flatcamGUI/PreferencesUI.py:6642 -#: flatcamTools/ToolSolderPaste.py:334 +#: FlatCAMCommon.py:620 FlatCAMCommon.py:1314 flatcamGUI/ObjectUI.py:2012 +#: flatcamGUI/PreferencesUI.py:3475 flatcamGUI/PreferencesUI.py:4447 +#: flatcamGUI/PreferencesUI.py:7148 flatcamTools/ToolSolderPaste.py:336 msgid "Preprocessor" msgstr "Postprocesador" -#: FlatCAMCommon.py:620 FlatCAMCommon.py:1315 +#: FlatCAMCommon.py:621 FlatCAMCommon.py:1316 FlatCAMCommon.py:1800 msgid "ExtraCut" msgstr "Corte extra" -#: FlatCAMCommon.py:621 FlatCAMCommon.py:1317 +#: FlatCAMCommon.py:622 FlatCAMCommon.py:1318 FlatCAMCommon.py:1815 msgid "E-Cut Length" msgstr "Longitud de Corte extra" -#: FlatCAMCommon.py:622 FlatCAMCommon.py:1319 +#: FlatCAMCommon.py:623 FlatCAMCommon.py:1320 msgid "Toolchange" msgstr "Cambio de herram" -#: FlatCAMCommon.py:623 FlatCAMCommon.py:1321 +#: FlatCAMCommon.py:624 FlatCAMCommon.py:1322 msgid "Toolchange XY" msgstr "Cambio de herra X, Y" -#: FlatCAMCommon.py:624 FlatCAMCommon.py:1323 flatcamGUI/PreferencesUI.py:3124 -#: flatcamGUI/PreferencesUI.py:4044 flatcamGUI/PreferencesUI.py:7572 +#: FlatCAMCommon.py:625 FlatCAMCommon.py:1324 flatcamGUI/PreferencesUI.py:3378 +#: flatcamGUI/PreferencesUI.py:4324 flatcamGUI/PreferencesUI.py:8078 #: flatcamTools/ToolCalibration.py:111 msgid "Toolchange Z" msgstr "Cambio de herramienta Z" -#: FlatCAMCommon.py:625 FlatCAMCommon.py:1325 flatcamGUI/ObjectUI.py:886 -#: flatcamGUI/PreferencesUI.py:3309 flatcamGUI/PreferencesUI.py:4200 +#: FlatCAMCommon.py:626 FlatCAMCommon.py:1326 flatcamGUI/ObjectUI.py:1192 +#: flatcamGUI/PreferencesUI.py:3586 flatcamGUI/PreferencesUI.py:4493 msgid "Start Z" msgstr "Comience Z" -#: FlatCAMCommon.py:626 FlatCAMCommon.py:1328 +#: FlatCAMCommon.py:627 FlatCAMCommon.py:1329 msgid "End Z" msgstr "Fin Z" -#: FlatCAMCommon.py:630 +#: FlatCAMCommon.py:631 msgid "Tool Index." msgstr "Índice de herramientas." -#: FlatCAMCommon.py:632 +#: FlatCAMCommon.py:633 FlatCAMCommon.py:1533 msgid "" "Tool name.\n" "This is not used in the app, it's function\n" @@ -1993,11 +1996,11 @@ msgstr "" "Esto no se usa en la aplicación, es función\n" "es servir como una nota para el usuario." -#: FlatCAMCommon.py:636 +#: FlatCAMCommon.py:637 FlatCAMCommon.py:1546 msgid "Tool Diameter." msgstr "Diá. de Herram." -#: FlatCAMCommon.py:638 +#: FlatCAMCommon.py:639 FlatCAMCommon.py:1727 msgid "" "Tool Offset.\n" "Can be of a few types:\n" @@ -2014,7 +2017,7 @@ msgstr "" "Personalizado = desplazamiento personalizado utilizando el valor de " "desplazamiento personalizado" -#: FlatCAMCommon.py:645 +#: FlatCAMCommon.py:646 FlatCAMCommon.py:1744 msgid "" "Custom Offset.\n" "A value to be used as offset from the current path." @@ -2022,7 +2025,7 @@ msgstr "" "Desplazamiento personalizado.\n" "Un valor que se utilizará como desplazamiento de la ruta actual." -#: FlatCAMCommon.py:648 +#: FlatCAMCommon.py:649 FlatCAMCommon.py:1711 msgid "" "Tool Type.\n" "Can be:\n" @@ -2036,7 +2039,7 @@ msgstr "" "Áspero = corte rugoso, baja velocidad de avance, múltiples pasadas\n" "Acabado = corte de acabado, alto avance" -#: FlatCAMCommon.py:654 +#: FlatCAMCommon.py:655 FlatCAMCommon.py:1559 msgid "" "Tool Shape. \n" "Can be:\n" @@ -2050,7 +2053,7 @@ msgstr "" "B = herramienta de fresado de punta esférica\n" "V = herramienta de fresado en forma de V" -#: FlatCAMCommon.py:660 +#: FlatCAMCommon.py:661 FlatCAMCommon.py:1575 msgid "" "Cutting Depth.\n" "The depth at which to cut into material." @@ -2058,7 +2061,7 @@ msgstr "" "Profundidad de corte.\n" "La profundidad a la cual cortar en material." -#: FlatCAMCommon.py:663 +#: FlatCAMCommon.py:664 FlatCAMCommon.py:1589 msgid "" "Multi Depth.\n" "Selecting this will allow cutting in multiple passes,\n" @@ -2068,7 +2071,7 @@ msgstr "" "Seleccionar esto permitirá cortar en múltiples pasadas,\n" "cada pasada agrega una profundidad de parámetro PPP." -#: FlatCAMCommon.py:667 +#: FlatCAMCommon.py:668 FlatCAMCommon.py:1602 msgid "" "DPP. Depth per Pass.\n" "The value used to cut into material on each pass." @@ -2076,7 +2079,7 @@ msgstr "" "PPP. Profundidad por pase.\n" "El valor utilizado para cortar en material en cada pasada." -#: FlatCAMCommon.py:670 +#: FlatCAMCommon.py:671 FlatCAMCommon.py:1758 msgid "" "V-Dia.\n" "Diameter of the tip for V-Shape Tools." @@ -2084,7 +2087,7 @@ msgstr "" "V-Dia.\n" "Diámetro de la punta para herramientas en forma de V." -#: FlatCAMCommon.py:673 +#: FlatCAMCommon.py:674 FlatCAMCommon.py:1772 msgid "" "V-Agle.\n" "Angle at the tip for the V-Shape Tools." @@ -2092,7 +2095,7 @@ msgstr "" "Ángulo en V.\n" "Ángulo en la punta para las herramientas en forma de V." -#: FlatCAMCommon.py:676 +#: FlatCAMCommon.py:677 FlatCAMCommon.py:1616 msgid "" "Clearance Height.\n" "Height at which the milling bit will travel between cuts,\n" @@ -2102,7 +2105,7 @@ msgstr "" "Altura a la que viajará la broca entre cortes,\n" "sobre la superficie del material, evitando todos los accesorios." -#: FlatCAMCommon.py:680 +#: FlatCAMCommon.py:681 msgid "" "FR. Feedrate\n" "The speed on XY plane used while cutting into material." @@ -2110,15 +2113,15 @@ msgstr "" "FR. Avance\n" "La velocidad en el plano XY utilizada al cortar material." -#: FlatCAMCommon.py:683 +#: FlatCAMCommon.py:684 msgid "" "FR Z. Feedrate Z\n" "The speed on Z plane." msgstr "" "FR Z. Avance Z\n" -"La velocidad en el plano Z" +"La velocidad en el plano Z." -#: FlatCAMCommon.py:686 +#: FlatCAMCommon.py:687 FlatCAMCommon.py:1786 msgid "" "FR Rapids. Feedrate Rapids\n" "Speed used while moving as fast as possible.\n" @@ -2130,7 +2133,7 @@ msgstr "" "Esto solo lo usan algunos dispositivos que no pueden usar\n" "el comando G0 g-code. Mayormente impresoras 3D." -#: FlatCAMCommon.py:691 +#: FlatCAMCommon.py:692 FlatCAMCommon.py:1659 msgid "" "Spindle Speed.\n" "If it's left empty it will not be used.\n" @@ -2140,7 +2143,7 @@ msgstr "" "Si se deja vacío, no se usará.\n" "La velocidad del husillo en RPM." -#: FlatCAMCommon.py:695 +#: FlatCAMCommon.py:696 FlatCAMCommon.py:1674 msgid "" "Dwell.\n" "Check this if a delay is needed to allow\n" @@ -2150,7 +2153,7 @@ msgstr "" "Marque esto si se necesita un retraso para permitir\n" "el motor del husillo para alcanzar su velocidad establecida." -#: FlatCAMCommon.py:699 +#: FlatCAMCommon.py:700 FlatCAMCommon.py:1687 msgid "" "Dwell Time.\n" "A delay used to allow the motor spindle reach it's set speed." @@ -2159,7 +2162,7 @@ msgstr "" "Un retraso utilizado para permitir que el eje del motor alcance su velocidad " "establecida." -#: FlatCAMCommon.py:702 +#: FlatCAMCommon.py:703 msgid "" "Preprocessor.\n" "A selection of files that will alter the generated G-code\n" @@ -2169,7 +2172,7 @@ msgstr "" "Una selección de archivos que alterarán el código G generado\n" "para adaptarse a una serie de casos de uso." -#: FlatCAMCommon.py:706 +#: FlatCAMCommon.py:707 FlatCAMCommon.py:1802 msgid "" "Extra Cut.\n" "If checked, after a isolation is finished an extra cut\n" @@ -2183,7 +2186,7 @@ msgstr "" "como que este punto está cubierto por este corte adicional para\n" "Garantizar un aislamiento completo." -#: FlatCAMCommon.py:712 +#: FlatCAMCommon.py:713 FlatCAMCommon.py:1817 msgid "" "Extra Cut length.\n" "If checked, after a isolation is finished an extra cut\n" @@ -2199,7 +2202,7 @@ msgstr "" "Garantizar un aislamiento completo. Esta es la longitud de\n" "El corte extra." -#: FlatCAMCommon.py:719 +#: FlatCAMCommon.py:720 msgid "" "Toolchange.\n" "It will create a toolchange event.\n" @@ -2211,7 +2214,7 @@ msgstr "" "El tipo de cambio de herramienta está determinado por\n" "El archivo del preprocesador." -#: FlatCAMCommon.py:724 +#: FlatCAMCommon.py:725 msgid "" "Toolchange XY.\n" "A set of coordinates in the format (x, y).\n" @@ -2223,7 +2226,7 @@ msgstr "" "Determinará la posición cartesiana del punto.\n" "donde tiene lugar el evento de cambio de herramienta." -#: FlatCAMCommon.py:729 +#: FlatCAMCommon.py:730 msgid "" "Toolchange Z.\n" "The position on Z plane where the tool change event take place." @@ -2232,7 +2235,7 @@ msgstr "" "La posición en el plano Z donde tiene lugar el evento de cambio de " "herramienta." -#: FlatCAMCommon.py:732 +#: FlatCAMCommon.py:733 msgid "" "Start Z.\n" "If it's left empty it will not be used.\n" @@ -2243,7 +2246,7 @@ msgstr "" "Una posición en el plano Z para moverse inmediatamente después del inicio " "del trabajo." -#: FlatCAMCommon.py:736 +#: FlatCAMCommon.py:737 msgid "" "End Z.\n" "A position on Z plane to move immediately after job stop." @@ -2252,357 +2255,734 @@ msgstr "" "Una posición en el plano Z para moverse inmediatamente después de la " "detención del trabajo." -#: FlatCAMCommon.py:748 FlatCAMCommon.py:1125 FlatCAMCommon.py:1159 +#: FlatCAMCommon.py:749 FlatCAMCommon.py:1126 FlatCAMCommon.py:1160 +#: FlatCAMCommon.py:2335 FlatCAMCommon.py:2556 FlatCAMCommon.py:2590 msgid "Could not load Tools DB file." msgstr "No se pudo cargar el archivo de herramientas DB." -#: FlatCAMCommon.py:756 FlatCAMCommon.py:1167 +#: FlatCAMCommon.py:757 FlatCAMCommon.py:1168 FlatCAMCommon.py:2343 +#: FlatCAMCommon.py:2598 msgid "Failed to parse Tools DB file." msgstr "Error al analizar el archivo DB de Herramientas." -#: FlatCAMCommon.py:759 FlatCAMCommon.py:1170 +#: FlatCAMCommon.py:760 FlatCAMCommon.py:1171 FlatCAMCommon.py:2346 +#: FlatCAMCommon.py:2601 msgid "Loaded FlatCAM Tools DB from" msgstr "Base de datos de herramientas FlatCAM cargada de" -#: FlatCAMCommon.py:765 +#: FlatCAMCommon.py:766 FlatCAMCommon.py:2260 msgid "Add to DB" msgstr "Añadir a DB" -#: FlatCAMCommon.py:767 +#: FlatCAMCommon.py:768 FlatCAMCommon.py:2263 msgid "Copy from DB" msgstr "Copiar de DB" -#: FlatCAMCommon.py:769 +#: FlatCAMCommon.py:770 FlatCAMCommon.py:2266 msgid "Delete from DB" msgstr "Eliminar de la DB" -#: FlatCAMCommon.py:1046 +#: FlatCAMCommon.py:1047 FlatCAMCommon.py:2473 msgid "Tool added to DB." msgstr "Herramienta agregada a la base de datos." -#: FlatCAMCommon.py:1067 +#: FlatCAMCommon.py:1068 FlatCAMCommon.py:2497 msgid "Tool copied from Tools DB." msgstr "Herramienta copiada de Herramientas DB." -#: FlatCAMCommon.py:1085 +#: FlatCAMCommon.py:1086 FlatCAMCommon.py:2516 msgid "Tool removed from Tools DB." msgstr "Herramienta eliminada de Herramientas DB." -#: FlatCAMCommon.py:1096 +#: FlatCAMCommon.py:1097 FlatCAMCommon.py:2527 msgid "Export Tools Database" msgstr "Exportar la DB de herramientas" -#: FlatCAMCommon.py:1099 +#: FlatCAMCommon.py:1100 FlatCAMCommon.py:2530 msgid "Tools_Database" msgstr "DB de herramientasram" -#: FlatCAMCommon.py:1106 -msgid "FlatCAM Tools DB export cancelled." -msgstr "Exportación de DB de herramientas FlatCAM cancelada." - -#: FlatCAMCommon.py:1136 FlatCAMCommon.py:1139 FlatCAMCommon.py:1191 +#: FlatCAMCommon.py:1137 FlatCAMCommon.py:1140 FlatCAMCommon.py:1192 +#: FlatCAMCommon.py:2567 FlatCAMCommon.py:2570 FlatCAMCommon.py:2622 msgid "Failed to write Tools DB to file." msgstr "Error al escribir Herramientas DB en el archivo." -#: FlatCAMCommon.py:1142 +#: FlatCAMCommon.py:1143 FlatCAMCommon.py:2573 msgid "Exported Tools DB to" msgstr "Exportó la base de datos de herramientas a" -#: FlatCAMCommon.py:1149 +#: FlatCAMCommon.py:1150 FlatCAMCommon.py:2580 msgid "Import FlatCAM Tools DB" msgstr "Importe la base de datos de herramientas FlatCAM" -#: FlatCAMCommon.py:1152 -msgid "FlatCAM Tools DB import cancelled." -msgstr "Se ha cancelado la importación de DB de herramientas FlatCAM." - -#: FlatCAMCommon.py:1195 +#: FlatCAMCommon.py:1196 FlatCAMCommon.py:2626 msgid "Saved Tools DB." msgstr "Guardado el DB de herramientas." -#: FlatCAMCommon.py:1342 +#: FlatCAMCommon.py:1343 FlatCAMCommon.py:2807 msgid "No Tool/row selected in the Tools Database table" msgstr "" "No se seleccionó ninguna herramienta / fila en la tabla Base de datos de " "herramientas" -#: FlatCAMCommon.py:1360 +#: FlatCAMCommon.py:1361 FlatCAMCommon.py:2824 msgid "Cancelled adding tool from DB." msgstr "Se canceló la herramienta de agregar de la DB." -#: FlatCAMObj.py:257 +#: FlatCAMCommon.py:1462 +msgid "Basic Geo Parameters" +msgstr "Parámetros básicos de Geo" + +#: FlatCAMCommon.py:1474 +msgid "Advanced Geo Parameters" +msgstr "Parámetros avanzados de Geo" + +#: FlatCAMCommon.py:1486 +msgid "NCC Parameters" +msgstr "NCC Parameters" + +#: FlatCAMCommon.py:1498 +msgid "Paint Parameters" +msgstr "Parámetros de Pintura" + +#: FlatCAMCommon.py:1629 flatcamGUI/ObjectUI.py:966 flatcamGUI/ObjectUI.py:1767 +#: flatcamGUI/PreferencesUI.py:4378 flatcamGUI/PreferencesUI.py:7059 +#: flatcamTools/ToolSolderPaste.py:254 +msgid "Feedrate X-Y" +msgstr "Avance X-Y" + +#: FlatCAMCommon.py:1631 +msgid "" +"Feedrate X-Y. Feedrate\n" +"The speed on XY plane used while cutting into material." +msgstr "" +"Avance X-Y. Avance\n" +"La velocidad en el plano XY utilizada mientras se corta en material." + +#: FlatCAMCommon.py:1643 flatcamGUI/ObjectUI.py:981 flatcamGUI/ObjectUI.py:1781 +#: flatcamGUI/PreferencesUI.py:3425 flatcamGUI/PreferencesUI.py:4393 +#: flatcamGUI/PreferencesUI.py:7072 flatcamTools/ToolSolderPaste.py:266 +msgid "Feedrate Z" +msgstr "Avance Z" + +#: FlatCAMCommon.py:1645 +msgid "" +"Feedrate Z\n" +"The speed on Z plane." +msgstr "" +"Avance Z\n" +"La velocidad en el plano Z." + +#: FlatCAMCommon.py:1843 flatcamGUI/ObjectUI.py:844 +#: flatcamGUI/PreferencesUI.py:3264 flatcamTools/ToolNCC.py:341 +msgid "Operation" +msgstr "Operación" + +#: FlatCAMCommon.py:1845 flatcamTools/ToolNCC.py:343 +msgid "" +"The 'Operation' can be:\n" +"- Isolation -> will ensure that the non-copper clearing is always complete.\n" +"If it's not successful then the non-copper clearing will fail, too.\n" +"- Clear -> the regular non-copper clearing." +msgstr "" +"La 'Operación' puede ser:\n" +"- Aislamiento -> asegurará que la limpieza sin cobre esté siempre completa.\n" +"Si no tiene éxito, la limpieza sin cobre también fallará.\n" +"- Borrar -> la limpieza regular sin cobre." + +#: FlatCAMCommon.py:1852 flatcamEditors/FlatCAMGrbEditor.py:2739 +#: flatcamGUI/GUIElements.py:2577 flatcamTools/ToolNCC.py:350 +msgid "Clear" +msgstr "Limpiar" + +#: FlatCAMCommon.py:1853 flatcamTools/ToolNCC.py:351 +#: flatcamTools/ToolNCC.py:1618 +msgid "Isolation" +msgstr "Aislamiento" + +#: FlatCAMCommon.py:1861 flatcamGUI/ObjectUI.py:408 flatcamGUI/ObjectUI.py:866 +#: flatcamGUI/PreferencesUI.py:2257 flatcamGUI/PreferencesUI.py:3280 +#: flatcamGUI/PreferencesUI.py:4665 flatcamGUI/PreferencesUI.py:5416 +#: flatcamTools/ToolNCC.py:359 +msgid "Milling Type" +msgstr "Tipo de fresado" + +#: FlatCAMCommon.py:1863 FlatCAMCommon.py:1871 flatcamGUI/PreferencesUI.py:5418 +#: flatcamGUI/PreferencesUI.py:5426 flatcamTools/ToolNCC.py:361 +#: flatcamTools/ToolNCC.py:369 +msgid "" +"Milling type when the selected tool is of type: 'iso_op':\n" +"- climb / best for precision milling and to reduce tool usage\n" +"- conventional / useful when there is no backlash compensation" +msgstr "" +"Tipo de fresado cuando la herramienta seleccionada es de tipo: 'iso_op':\n" +"- ascenso / mejor para fresado de precisión y para reducir el uso de " +"herramientas\n" +"- convencional / útil cuando no hay compensación de reacción" + +#: FlatCAMCommon.py:1868 flatcamGUI/ObjectUI.py:414 +#: flatcamGUI/PreferencesUI.py:2264 flatcamGUI/PreferencesUI.py:4671 +#: flatcamGUI/PreferencesUI.py:5423 flatcamTools/ToolNCC.py:366 +msgid "Climb" +msgstr "Subida" + +#: FlatCAMCommon.py:1869 flatcamGUI/ObjectUI.py:415 +#: flatcamGUI/PreferencesUI.py:2265 flatcamGUI/PreferencesUI.py:4672 +#: flatcamGUI/PreferencesUI.py:5424 flatcamTools/ToolNCC.py:367 +msgid "Conventional" +msgstr "Convencional" + +#: FlatCAMCommon.py:1881 FlatCAMCommon.py:1990 +#: flatcamEditors/FlatCAMGeoEditor.py:452 flatcamGUI/PreferencesUI.py:5461 +#: flatcamGUI/PreferencesUI.py:6002 flatcamTools/ToolNCC.py:382 +#: flatcamTools/ToolPaint.py:329 +msgid "Overlap" +msgstr "Superposición" + +#: FlatCAMCommon.py:1883 flatcamGUI/PreferencesUI.py:5463 +#: flatcamTools/ToolNCC.py:384 +msgid "" +"How much (percentage) of the tool width to overlap each tool pass.\n" +"Adjust the value starting with lower values\n" +"and increasing it if areas that should be cleared are still \n" +"not cleared.\n" +"Lower values = faster processing, faster execution on CNC.\n" +"Higher values = slow processing and slow execution on CNC\n" +"due of too many paths." +msgstr "" +"Cuánto (porcentaje) del ancho de la herramienta para superponer cada pasada " +"de herramienta.\n" +"Ajuste el valor comenzando con valores más bajos\n" +"y aumentarlo si las áreas que deberían limpiarse aún están\n" +"no borrado.\n" +"Valores más bajos = procesamiento más rápido, ejecución más rápida en CNC.\n" +"Valores más altos = procesamiento lento y ejecución lenta en CNC\n" +"debido a demasiados caminos." + +#: FlatCAMCommon.py:1902 FlatCAMCommon.py:2011 +#: flatcamEditors/FlatCAMGeoEditor.py:472 flatcamGUI/PreferencesUI.py:5481 +#: flatcamGUI/PreferencesUI.py:5723 flatcamGUI/PreferencesUI.py:6022 +#: flatcamGUI/PreferencesUI.py:7681 flatcamGUI/PreferencesUI.py:7838 +#: flatcamGUI/PreferencesUI.py:7923 flatcamGUI/PreferencesUI.py:8570 +#: flatcamGUI/PreferencesUI.py:8578 flatcamTools/ToolCopperThieving.py:112 +#: flatcamTools/ToolCopperThieving.py:363 flatcamTools/ToolCutOut.py:191 +#: flatcamTools/ToolFiducials.py:172 flatcamTools/ToolInvertGerber.py:88 +#: flatcamTools/ToolInvertGerber.py:96 flatcamTools/ToolNCC.py:403 +#: flatcamTools/ToolPaint.py:350 +msgid "Margin" +msgstr "Margen" + +#: FlatCAMCommon.py:1904 flatcamGUI/PreferencesUI.py:5483 +#: flatcamGUI/PreferencesUI.py:7683 flatcamGUI/PreferencesUI.py:7925 +#: flatcamGUI/PreferencesUI.py:7989 flatcamTools/ToolCopperThieving.py:114 +#: flatcamTools/ToolFiducials.py:174 flatcamTools/ToolFiducials.py:237 +#: flatcamTools/ToolNCC.py:405 +msgid "Bounding box margin." +msgstr "Margen de cuadro delimitador." + +#: FlatCAMCommon.py:1915 FlatCAMCommon.py:2026 +#: flatcamEditors/FlatCAMGeoEditor.py:486 flatcamGUI/PreferencesUI.py:5494 +#: flatcamGUI/PreferencesUI.py:6037 flatcamGUI/PreferencesUI.py:8204 +#: flatcamGUI/PreferencesUI.py:8417 flatcamTools/ToolExtractDrills.py:128 +#: flatcamTools/ToolNCC.py:416 flatcamTools/ToolPaint.py:365 +#: flatcamTools/ToolPunchGerber.py:139 +msgid "Method" +msgstr "Método" + +#: FlatCAMCommon.py:1917 flatcamGUI/PreferencesUI.py:5496 +#: flatcamTools/ToolNCC.py:418 +msgid "" +"Algorithm for copper clearing:\n" +"- Standard: Fixed step inwards.\n" +"- Seed-based: Outwards from seed.\n" +"- Line-based: Parallel lines." +msgstr "" +"Algoritmo para la limpieza de cobre:\n" +"- Estándar: paso fijo hacia adentro.\n" +"- Basado en semillas: hacia afuera de la semilla.\n" +"- Basado en líneas: líneas paralelas." + +#: FlatCAMCommon.py:1925 FlatCAMCommon.py:2040 +#: flatcamEditors/FlatCAMGeoEditor.py:500 flatcamGUI/PreferencesUI.py:5509 +#: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 +#: flatcamTools/ToolNCC.py:2390 flatcamTools/ToolNCC.py:2419 +#: flatcamTools/ToolNCC.py:2688 flatcamTools/ToolNCC.py:2720 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:1829 +#: tclCommands/TclCommandCopperClear.py:126 +#: tclCommands/TclCommandCopperClear.py:134 tclCommands/TclCommandPaint.py:125 +msgid "Standard" +msgstr "Estándar" + +#: FlatCAMCommon.py:1925 FlatCAMCommon.py:2040 +#: flatcamEditors/FlatCAMGeoEditor.py:500 +#: flatcamEditors/FlatCAMGeoEditor.py:5156 flatcamGUI/PreferencesUI.py:5509 +#: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:699 +#: flatcamTools/ToolPaint.py:1857 tclCommands/TclCommandCopperClear.py:130 +#: tclCommands/TclCommandPaint.py:129 +msgid "Lines" +msgstr "Líneas" + +#: FlatCAMCommon.py:1933 FlatCAMCommon.py:2051 flatcamGUI/PreferencesUI.py:5516 +#: flatcamGUI/PreferencesUI.py:6063 flatcamTools/ToolNCC.py:439 +#: flatcamTools/ToolPaint.py:401 +msgid "Connect" +msgstr "Conectar" + +#: FlatCAMCommon.py:1937 FlatCAMCommon.py:2054 +#: flatcamEditors/FlatCAMGeoEditor.py:509 flatcamGUI/PreferencesUI.py:5518 +#: flatcamGUI/PreferencesUI.py:6065 flatcamTools/ToolNCC.py:443 +#: flatcamTools/ToolPaint.py:404 +msgid "" +"Draw lines between resulting\n" +"segments to minimize tool lifts." +msgstr "" +"Dibuja líneas entre el resultado\n" +"Segmentos para minimizar elevaciones de herramientas." + +#: FlatCAMCommon.py:1943 FlatCAMCommon.py:2058 flatcamGUI/PreferencesUI.py:5525 +#: flatcamGUI/PreferencesUI.py:6071 flatcamTools/ToolNCC.py:449 +#: flatcamTools/ToolPaint.py:408 +msgid "Contour" +msgstr "Contorno" + +#: FlatCAMCommon.py:1947 FlatCAMCommon.py:2061 +#: flatcamEditors/FlatCAMGeoEditor.py:519 flatcamGUI/PreferencesUI.py:5527 +#: flatcamGUI/PreferencesUI.py:6073 flatcamTools/ToolNCC.py:453 +#: flatcamTools/ToolPaint.py:411 +msgid "" +"Cut around the perimeter of the polygon\n" +"to trim rough edges." +msgstr "" +"Corta todo el perímetro del polígono.\n" +"Para recortar los bordes ásperos." + +#: FlatCAMCommon.py:1953 flatcamEditors/FlatCAMGeoEditor.py:613 +#: flatcamEditors/FlatCAMGrbEditor.py:5145 flatcamGUI/ObjectUI.py:142 +#: flatcamGUI/ObjectUI.py:1495 flatcamGUI/ObjectUI.py:2244 +#: flatcamGUI/PreferencesUI.py:5534 flatcamGUI/PreferencesUI.py:6822 +#: flatcamTools/ToolNCC.py:459 flatcamTools/ToolTransform.py:29 +msgid "Offset" +msgstr "Compensar" + +#: FlatCAMCommon.py:1957 flatcamGUI/PreferencesUI.py:5536 +#: flatcamTools/ToolNCC.py:463 +msgid "" +"If used, it will add an offset to the copper features.\n" +"The copper clearing will finish to a distance\n" +"from the copper features.\n" +"The value can be between 0 and 10 FlatCAM units." +msgstr "" +"Si se usa, agregará un desplazamiento a las características de cobre.\n" +"El claro de cobre terminará a cierta distancia.\n" +"de las características de cobre.\n" +"El valor puede estar entre 0 y 10 unidades FlatCAM." + +#: FlatCAMCommon.py:1992 flatcamEditors/FlatCAMGeoEditor.py:454 +#: flatcamGUI/PreferencesUI.py:6004 flatcamTools/ToolPaint.py:331 +msgid "" +"How much (percentage) of the tool width to overlap each tool pass.\n" +"Adjust the value starting with lower values\n" +"and increasing it if areas that should be painted are still \n" +"not painted.\n" +"Lower values = faster processing, faster execution on CNC.\n" +"Higher values = slow processing and slow execution on CNC\n" +"due of too many paths." +msgstr "" +"Cuánto (porcentaje) del ancho de la herramienta para superponer cada pasada " +"de herramienta.\n" +"Ajuste el valor comenzando con valores más bajos\n" +"y aumentarlo si las áreas que deben pintarse aún están\n" +"No pintado.\n" +"Valores más bajos = procesamiento más rápido, ejecución más rápida en CNC.\n" +"Valores más altos = procesamiento lento y ejecución lenta en CNC\n" +"debido a demasiados caminos." + +#: FlatCAMCommon.py:2013 flatcamEditors/FlatCAMGeoEditor.py:474 +#: flatcamGUI/PreferencesUI.py:6024 flatcamTools/ToolPaint.py:352 +msgid "" +"Distance by which to avoid\n" +"the edges of the polygon to\n" +"be painted." +msgstr "" +"Distancia por la cual evitar\n" +"los bordes del polígono a\n" +"ser pintado." + +#: FlatCAMCommon.py:2028 flatcamGUI/PreferencesUI.py:6039 +#: flatcamTools/ToolPaint.py:367 +msgid "" +"Algorithm for painting:\n" +"- Standard: Fixed step inwards.\n" +"- Seed-based: Outwards from seed.\n" +"- Line-based: Parallel lines.\n" +"- Laser-lines: Active only for Gerber objects.\n" +"Will create lines that follow the traces.\n" +"- Combo: In case of failure a new method will be picked from the above\n" +"in the order specified." +msgstr "" +"Algoritmo para pintar:\n" +"- Estándar: paso fijo hacia adentro.\n" +"- Basado en semillas: hacia afuera de la semilla.\n" +"- Basado en líneas: líneas paralelas.\n" +"- Líneas láser: activas solo para objetos Gerber.\n" +"Creará líneas que siguen los rastros.\n" +"- Combo: en caso de falla, se elegirá un nuevo método de los anteriores\n" +"en el orden especificado." + +#: FlatCAMCommon.py:2040 FlatCAMCommon.py:2042 flatcamGUI/PreferencesUI.py:6056 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:392 +#: flatcamTools/ToolPaint.py:693 flatcamTools/ToolPaint.py:698 +#: flatcamTools/ToolPaint.py:1871 tclCommands/TclCommandPaint.py:131 +msgid "Laser_lines" +msgstr "Lineas laser" + +#: FlatCAMCommon.py:2040 flatcamGUI/PreferencesUI.py:6056 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:2022 +#: tclCommands/TclCommandPaint.py:133 +msgid "Combo" +msgstr "Combo" + +#: FlatCAMCommon.py:2085 +msgid "Add Tool in DB" +msgstr "Agregar herramienta en DB" + +#: FlatCAMObj.py:264 msgid "Name changed from" msgstr "Nombre cambiado de" -#: FlatCAMObj.py:257 +#: FlatCAMObj.py:264 msgid "to" msgstr "a" -#: FlatCAMObj.py:268 +#: FlatCAMObj.py:275 msgid "Offsetting..." msgstr "Compensación ..." -#: FlatCAMObj.py:282 FlatCAMObj.py:287 +#: FlatCAMObj.py:289 FlatCAMObj.py:294 msgid "Scaling could not be executed." msgstr "No se pudo ejecutar el escalado." -#: FlatCAMObj.py:291 FlatCAMObj.py:299 +#: FlatCAMObj.py:298 FlatCAMObj.py:306 msgid "Scale done." msgstr "Escala hecha." -#: FlatCAMObj.py:297 +#: FlatCAMObj.py:304 msgid "Scaling..." msgstr "Escalando..." -#: FlatCAMObj.py:315 +#: FlatCAMObj.py:322 msgid "Skewing..." msgstr "Sesgar..." -#: FlatCAMObj.py:736 FlatCAMObj.py:2746 FlatCAMObj.py:3968 -#: flatcamGUI/PreferencesUI.py:1470 flatcamGUI/PreferencesUI.py:2859 +#: FlatCAMObj.py:743 FlatCAMObj.py:831 flatcamGUI/ObjectUI.py:449 +#: flatcamGUI/PreferencesUI.py:6527 flatcamTools/ToolAlignObjects.py:73 +#: flatcamTools/ToolAlignObjects.py:109 flatcamTools/ToolCalibration.py:196 +#: flatcamTools/ToolCalibration.py:631 flatcamTools/ToolCalibration.py:648 +#: flatcamTools/ToolCalibration.py:807 flatcamTools/ToolCalibration.py:815 +#: flatcamTools/ToolCopperThieving.py:145 +#: flatcamTools/ToolCopperThieving.py:159 +#: flatcamTools/ToolCopperThieving.py:605 flatcamTools/ToolCutOut.py:92 +#: flatcamTools/ToolDblSided.py:225 flatcamTools/ToolFilm.py:69 +#: flatcamTools/ToolFilm.py:102 flatcamTools/ToolFilm.py:549 +#: flatcamTools/ToolFilm.py:557 flatcamTools/ToolImage.py:49 +#: flatcamTools/ToolImage.py:252 flatcamTools/ToolImage.py:273 +#: flatcamTools/ToolNCC.py:96 flatcamTools/ToolNCC.py:558 +#: flatcamTools/ToolNCC.py:1295 flatcamTools/ToolPaint.py:502 +#: flatcamTools/ToolPaint.py:706 flatcamTools/ToolPanelize.py:118 +#: flatcamTools/ToolPanelize.py:204 flatcamTools/ToolPanelize.py:374 +#: flatcamTools/ToolPanelize.py:391 +msgid "Gerber" +msgstr "Gerber" + +#: FlatCAMObj.py:743 FlatCAMObj.py:831 flatcamGUI/FlatCAMGUI.py:2154 +#: flatcamGUI/ObjectUI.py:449 flatcamTools/ToolCalibration.py:631 +#: flatcamTools/ToolCalibration.py:648 flatcamTools/ToolCalibration.py:815 +#: flatcamTools/ToolCopperThieving.py:145 +#: flatcamTools/ToolCopperThieving.py:159 +#: flatcamTools/ToolCopperThieving.py:605 flatcamTools/ToolCutOut.py:93 +#: flatcamTools/ToolDblSided.py:227 flatcamTools/ToolFilm.py:69 +#: flatcamTools/ToolFilm.py:102 flatcamTools/ToolFilm.py:549 +#: flatcamTools/ToolFilm.py:557 flatcamTools/ToolImage.py:49 +#: flatcamTools/ToolImage.py:271 flatcamTools/ToolNCC.py:95 +#: flatcamTools/ToolNCC.py:558 flatcamTools/ToolNCC.py:1295 +#: flatcamTools/ToolPaint.py:502 flatcamTools/ToolPaint.py:706 +#: flatcamTools/ToolPanelize.py:118 flatcamTools/ToolPanelize.py:374 +#: flatcamTools/ToolPanelize.py:391 +msgid "Geometry" +msgstr "Geometría" + +#: FlatCAMObj.py:755 FlatCAMObj.py:2957 FlatCAMObj.py:4421 +#: flatcamGUI/PreferencesUI.py:1646 flatcamGUI/PreferencesUI.py:3041 msgid "Basic" msgstr "BASIC" -#: FlatCAMObj.py:763 FlatCAMObj.py:2758 FlatCAMObj.py:3989 -#: flatcamGUI/PreferencesUI.py:1471 +#: FlatCAMObj.py:782 FlatCAMObj.py:2970 FlatCAMObj.py:4442 +#: flatcamGUI/PreferencesUI.py:1647 msgid "Advanced" msgstr "Avanzado" -#: FlatCAMObj.py:980 +#: FlatCAMObj.py:998 msgid "Buffering solid geometry" msgstr "Amortiguación de geometría sólida" -#: FlatCAMObj.py:983 camlib.py:965 flatcamGUI/PreferencesUI.py:2296 -#: flatcamTools/ToolCopperThieving.py:1011 -#: flatcamTools/ToolCopperThieving.py:1200 -#: flatcamTools/ToolCopperThieving.py:1212 -#: flatcamTools/ToolNonCopperClear.py:1624 -#: flatcamTools/ToolNonCopperClear.py:1721 -#: flatcamTools/ToolNonCopperClear.py:1732 -#: flatcamTools/ToolNonCopperClear.py:2015 -#: flatcamTools/ToolNonCopperClear.py:2111 -#: flatcamTools/ToolNonCopperClear.py:2123 +#: FlatCAMObj.py:1001 camlib.py:979 flatcamGUI/PreferencesUI.py:2476 +#: flatcamTools/ToolCopperThieving.py:1017 +#: flatcamTools/ToolCopperThieving.py:1206 +#: flatcamTools/ToolCopperThieving.py:1218 flatcamTools/ToolNCC.py:2045 +#: flatcamTools/ToolNCC.py:2153 flatcamTools/ToolNCC.py:2167 +#: flatcamTools/ToolNCC.py:3098 flatcamTools/ToolNCC.py:3203 +#: flatcamTools/ToolNCC.py:3218 flatcamTools/ToolNCC.py:3484 +#: flatcamTools/ToolNCC.py:3585 flatcamTools/ToolNCC.py:3600 msgid "Buffering" msgstr "Tamponamiento" -#: FlatCAMObj.py:989 +#: FlatCAMObj.py:1007 msgid "Done" msgstr "Hecho" -#: FlatCAMObj.py:1040 +#: FlatCAMObj.py:1032 FlatCAMObj.py:1058 +msgid "Operation could not be done." +msgstr "La operación no se pudo hacer." + +#: FlatCAMObj.py:1075 msgid "Isolating..." msgstr "Aislando ..." -#: FlatCAMObj.py:1099 +#: FlatCAMObj.py:1134 msgid "Click on a polygon to isolate it." msgstr "Haga clic en un polígono para aislarlo." -#: FlatCAMObj.py:1138 FlatCAMObj.py:1243 flatcamTools/ToolPaint.py:1120 +#: FlatCAMObj.py:1173 FlatCAMObj.py:1277 flatcamTools/ToolPaint.py:1511 msgid "Added polygon" msgstr "Polígono agregado" -#: FlatCAMObj.py:1140 FlatCAMObj.py:1245 +#: FlatCAMObj.py:1174 FlatCAMObj.py:1279 msgid "Click to add next polygon or right click to start isolation." msgstr "" "Haga clic para agregar el siguiente polígono o haga clic con el botón " "derecho para iniciar el aislamiento." -#: FlatCAMObj.py:1152 flatcamTools/ToolPaint.py:1134 +#: FlatCAMObj.py:1186 flatcamTools/ToolPaint.py:1525 msgid "Removed polygon" msgstr "Polígono eliminado" -#: FlatCAMObj.py:1153 +#: FlatCAMObj.py:1187 msgid "Click to add/remove next polygon or right click to start isolation." msgstr "" "Haga clic para agregar / eliminar el siguiente polígono o haga clic con el " "botón derecho para iniciar el aislamiento." -#: FlatCAMObj.py:1158 flatcamTools/ToolPaint.py:1140 +#: FlatCAMObj.py:1192 flatcamTools/ToolPaint.py:1531 msgid "No polygon detected under click position." msgstr "No se detectó ningún polígono bajo la posición de clic." -#: FlatCAMObj.py:1179 flatcamTools/ToolPaint.py:1169 +#: FlatCAMObj.py:1213 flatcamTools/ToolPaint.py:1560 msgid "List of single polygons is empty. Aborting." -msgstr "La lista de polígonos individuales está vacía. Abortar" +msgstr "La lista de polígonos individuales está vacía. Abortar." -#: FlatCAMObj.py:1248 +#: FlatCAMObj.py:1282 msgid "No polygon in selection." msgstr "No hay polígono en la selección." -#: FlatCAMObj.py:1324 FlatCAMObj.py:1457 -#: flatcamTools/ToolNonCopperClear.py:1653 -#: flatcamTools/ToolNonCopperClear.py:2039 -msgid "Isolation geometry could not be generated." -msgstr "La geometría de aislamiento no se pudo generar." - -#: FlatCAMObj.py:1374 FlatCAMObj.py:3637 FlatCAMObj.py:3922 FlatCAMObj.py:4221 +#: FlatCAMObj.py:1394 FlatCAMObj.py:1542 FlatCAMObj.py:4055 FlatCAMObj.py:4375 +#: FlatCAMObj.py:4762 msgid "Rough" msgstr "Áspero" -#: FlatCAMObj.py:1400 FlatCAMObj.py:1480 +#: FlatCAMObj.py:1410 FlatCAMObj.py:1489 flatcamTools/ToolNCC.py:2081 +#: flatcamTools/ToolNCC.py:3132 flatcamTools/ToolNCC.py:3511 +msgid "Isolation geometry could not be generated." +msgstr "La geometría de aislamiento no se pudo generar." + +#: FlatCAMObj.py:1435 FlatCAMObj.py:1567 msgid "Isolation geometry created" msgstr "Geometría de aislamiento creada" -#: FlatCAMObj.py:1409 FlatCAMObj.py:1487 +#: FlatCAMObj.py:1444 FlatCAMObj.py:1574 msgid "Subtracting Geo" msgstr "Restando Geo" -#: FlatCAMObj.py:1807 +#: FlatCAMObj.py:1899 msgid "Plotting Apertures" msgstr "Aperturas de trazado" -#: FlatCAMObj.py:2573 flatcamEditors/FlatCAMExcEditor.py:2427 +#: FlatCAMObj.py:2753 flatcamEditors/FlatCAMExcEditor.py:2453 msgid "Total Drills" msgstr "Taladros totales" -#: FlatCAMObj.py:2605 flatcamEditors/FlatCAMExcEditor.py:2459 +#: FlatCAMObj.py:2784 flatcamEditors/FlatCAMExcEditor.py:2485 msgid "Total Slots" msgstr "Ranuras totales" -#: FlatCAMObj.py:3060 FlatCAMObj.py:3155 FlatCAMObj.py:3276 +#: FlatCAMObj.py:2857 FlatCAMObj.py:3069 FlatCAMObj.py:3085 FlatCAMObj.py:3089 +#: FlatCAMObj.py:4242 FlatCAMObj.py:4667 FlatCAMObj.py:4703 +#: flatcamGUI/ObjectUI.py:817 flatcamGUI/ObjectUI.py:1660 +#: flatcamTools/ToolNCC.py:331 flatcamTools/ToolNCC.py:797 +#: flatcamTools/ToolNCC.py:811 flatcamTools/ToolNCC.py:1191 +#: flatcamTools/ToolPaint.py:314 flatcamTools/ToolPaint.py:767 +#: flatcamTools/ToolPaint.py:779 flatcamTools/ToolPaint.py:1166 +msgid "Parameters for" +msgstr "Parámetros para" + +#: FlatCAMObj.py:2857 FlatCAMObj.py:3089 FlatCAMObj.py:4242 FlatCAMObj.py:4703 +#: flatcamTools/ToolNCC.py:811 flatcamTools/ToolNCC.py:1191 +#: flatcamTools/ToolPaint.py:779 flatcamTools/ToolPaint.py:1166 +msgid "Multiple Tools" +msgstr "Herramientas múltiples" + +#: FlatCAMObj.py:3069 +msgid "No Tool Selected" +msgstr "Ninguna herramienta seleccionada" + +#: FlatCAMObj.py:3085 FlatCAMObj.py:3427 FlatCAMObj.py:4667 +#: flatcamEditors/FlatCAMGeoEditor.py:406 flatcamGUI/FlatCAMGUI.py:496 +#: flatcamGUI/FlatCAMGUI.py:1143 flatcamGUI/ObjectUI.py:817 +#: flatcamGUI/ObjectUI.py:1660 flatcamTools/ToolNCC.py:331 +#: flatcamTools/ToolNCC.py:797 flatcamTools/ToolPaint.py:314 +#: flatcamTools/ToolPaint.py:767 +msgid "Tool" +msgstr "Herramienta" + +#: FlatCAMObj.py:3419 FlatCAMObj.py:3512 FlatCAMObj.py:3700 msgid "Please select one or more tools from the list and try again." msgstr "" "Por favor seleccione una o más herramientas de la lista e intente nuevamente." -#: FlatCAMObj.py:3067 +#: FlatCAMObj.py:3426 msgid "Milling tool for DRILLS is larger than hole size. Cancelled." msgstr "" "La herramienta de fresado para TALADRO es más grande que el tamaño del " "orificio. Cancelado." -#: FlatCAMObj.py:3068 FlatCAMObj.py:4533 flatcamEditors/FlatCAMGeoEditor.py:408 -#: flatcamGUI/FlatCAMGUI.py:457 flatcamGUI/FlatCAMGUI.py:1072 -#: flatcamGUI/ObjectUI.py:1353 -msgid "Tool" -msgstr "Herramienta" - -#: FlatCAMObj.py:3084 FlatCAMObj.py:3177 FlatCAMObj.py:3295 +#: FlatCAMObj.py:3442 FlatCAMObj.py:3533 FlatCAMObj.py:3719 +#: tclCommands/TclCommandDrillcncjob.py:194 msgid "Tool_nr" msgstr "Herramienta_nu" -#: FlatCAMObj.py:3084 FlatCAMObj.py:3177 FlatCAMObj.py:3295 -#: flatcamEditors/FlatCAMExcEditor.py:1582 -#: flatcamEditors/FlatCAMExcEditor.py:3048 flatcamGUI/ObjectUI.py:777 -#: flatcamTools/ToolNonCopperClear.py:120 flatcamTools/ToolPaint.py:123 -#: flatcamTools/ToolPcbWizard.py:76 flatcamTools/ToolProperties.py:396 -#: flatcamTools/ToolProperties.py:449 flatcamTools/ToolSolderPaste.py:84 +#: FlatCAMObj.py:3442 FlatCAMObj.py:3533 FlatCAMObj.py:3719 +#: flatcamEditors/FlatCAMExcEditor.py:1585 +#: flatcamEditors/FlatCAMExcEditor.py:3069 flatcamGUI/ObjectUI.py:780 +#: flatcamTools/ToolNCC.py:132 flatcamTools/ToolPaint.py:128 +#: flatcamTools/ToolPcbWizard.py:76 flatcamTools/ToolProperties.py:416 +#: flatcamTools/ToolProperties.py:476 flatcamTools/ToolSolderPaste.py:86 +#: tclCommands/TclCommandDrillcncjob.py:194 msgid "Diameter" msgstr "Diámetro" -#: FlatCAMObj.py:3084 FlatCAMObj.py:3177 FlatCAMObj.py:3295 +#: FlatCAMObj.py:3442 FlatCAMObj.py:3533 FlatCAMObj.py:3719 +#: tclCommands/TclCommandDrillcncjob.py:194 msgid "Drills_Nr" msgstr "Taladros_nu" -#: FlatCAMObj.py:3084 FlatCAMObj.py:3177 FlatCAMObj.py:3295 +#: FlatCAMObj.py:3442 FlatCAMObj.py:3533 FlatCAMObj.py:3719 +#: tclCommands/TclCommandDrillcncjob.py:194 msgid "Slots_Nr" msgstr "Ranuras_nu" -#: FlatCAMObj.py:3164 +#: FlatCAMObj.py:3521 msgid "Milling tool for SLOTS is larger than hole size. Cancelled." msgstr "" "La herramienta de fresado para SLOTS es más grande que el tamaño del " "orificio. Cancelado." -#: FlatCAMObj.py:3336 -msgid "" -"Wrong value format for self.defaults[\"z_pdepth\"] or self.options[\"z_pdepth" -"\"]" -msgstr "" -"Formato de valor incorrecto para self.defaults [\"z_pdepth\"] o self.options " -"[\"z_pdepth\"]" +#: FlatCAMObj.py:3626 FlatCAMObj.py:5451 +msgid "Focus Z" +msgstr "Enfoque Z" -#: FlatCAMObj.py:3347 -msgid "" -"Wrong value format for self.defaults[\"feedrate_probe\"] or self." -"options[\"feedrate_probe\"]" -msgstr "" -"Formato de valor incorrecto para self.defaults [\"feedrate_probe\"] o self." -"options [\"feedrate_probe\"]" +#: FlatCAMObj.py:3645 FlatCAMObj.py:5470 +msgid "Laser Power" +msgstr "Poder del laser" -#: FlatCAMObj.py:3377 FlatCAMObj.py:5354 FlatCAMObj.py:5358 FlatCAMObj.py:5493 +#: FlatCAMObj.py:3677 FlatCAMObj.py:5502 flatcamGUI/ObjectUI.py:1048 +#: flatcamGUI/ObjectUI.py:1839 flatcamGUI/PreferencesUI.py:4409 +msgid "Spindle speed" +msgstr "Eje de velocidad" + +#: FlatCAMObj.py:3776 FlatCAMObj.py:5911 FlatCAMObj.py:5915 FlatCAMObj.py:6060 msgid "Generating CNC Code" msgstr "Generando Código CNC" -#: FlatCAMObj.py:3637 FlatCAMObj.py:4632 FlatCAMObj.py:4633 FlatCAMObj.py:4642 +#: FlatCAMObj.py:3966 flatcamTools/ToolNCC.py:918 flatcamTools/ToolPaint.py:844 +msgid "Current Tool parameters were applied to all tools." +msgstr "" +"Los parámetros actuales de la herramienta se aplicaron a todas las " +"herramientas." + +#: FlatCAMObj.py:4055 FlatCAMObj.py:5115 FlatCAMObj.py:5116 FlatCAMObj.py:5125 msgid "Iso" msgstr "Aisl" -#: FlatCAMObj.py:3637 +#: FlatCAMObj.py:4055 msgid "Finish" msgstr "Terminar" -#: FlatCAMObj.py:3957 +#: FlatCAMObj.py:4410 msgid "Add from Tool DB" msgstr "Agregar desde la DB de herramientas" -#: FlatCAMObj.py:3960 flatcamGUI/FlatCAMGUI.py:678 flatcamGUI/FlatCAMGUI.py:794 -#: flatcamGUI/FlatCAMGUI.py:989 flatcamGUI/FlatCAMGUI.py:2015 -#: flatcamGUI/FlatCAMGUI.py:2159 flatcamGUI/FlatCAMGUI.py:2378 -#: flatcamGUI/FlatCAMGUI.py:2557 flatcamGUI/ObjectUI.py:1324 -#: flatcamTools/ToolPanelize.py:534 flatcamTools/ToolPanelize.py:561 -#: flatcamTools/ToolPanelize.py:660 flatcamTools/ToolPanelize.py:694 -#: flatcamTools/ToolPanelize.py:759 +#: FlatCAMObj.py:4413 flatcamGUI/FlatCAMGUI.py:734 flatcamGUI/FlatCAMGUI.py:848 +#: flatcamGUI/FlatCAMGUI.py:1057 flatcamGUI/FlatCAMGUI.py:2123 +#: flatcamGUI/FlatCAMGUI.py:2267 flatcamGUI/FlatCAMGUI.py:2532 +#: flatcamGUI/FlatCAMGUI.py:2731 flatcamGUI/ObjectUI.py:1615 +#: flatcamTools/ToolPanelize.py:543 flatcamTools/ToolPanelize.py:570 +#: flatcamTools/ToolPanelize.py:669 flatcamTools/ToolPanelize.py:703 +#: flatcamTools/ToolPanelize.py:768 msgid "Copy" msgstr "Dupdo" -#: FlatCAMObj.py:4054 FlatCAMObj.py:4397 FlatCAMObj.py:5107 FlatCAMObj.py:5744 -#: flatcamEditors/FlatCAMExcEditor.py:2534 -#: flatcamEditors/FlatCAMGeoEditor.py:1078 -#: flatcamEditors/FlatCAMGeoEditor.py:1112 -#: flatcamEditors/FlatCAMGeoEditor.py:1133 -#: flatcamEditors/FlatCAMGeoEditor.py:1154 -#: flatcamEditors/FlatCAMGeoEditor.py:1191 -#: flatcamEditors/FlatCAMGeoEditor.py:1219 -#: flatcamEditors/FlatCAMGeoEditor.py:1240 -#: flatcamTools/ToolNonCopperClear.py:1052 -#: flatcamTools/ToolNonCopperClear.py:1461 flatcamTools/ToolPaint.py:835 -#: flatcamTools/ToolPaint.py:1019 flatcamTools/ToolPaint.py:2198 -#: flatcamTools/ToolSolderPaste.py:882 flatcamTools/ToolSolderPaste.py:957 +#: FlatCAMObj.py:4507 FlatCAMObj.py:4941 FlatCAMObj.py:5661 FlatCAMObj.py:6307 +#: flatcamEditors/FlatCAMExcEditor.py:2560 +#: flatcamEditors/FlatCAMGeoEditor.py:1077 +#: flatcamEditors/FlatCAMGeoEditor.py:1118 +#: flatcamEditors/FlatCAMGeoEditor.py:1146 +#: flatcamEditors/FlatCAMGeoEditor.py:1174 +#: flatcamEditors/FlatCAMGeoEditor.py:1218 +#: flatcamEditors/FlatCAMGeoEditor.py:1253 +#: flatcamEditors/FlatCAMGeoEditor.py:1281 flatcamTools/ToolNCC.py:1493 +#: flatcamTools/ToolPaint.py:1244 flatcamTools/ToolPaint.py:1415 +#: flatcamTools/ToolSolderPaste.py:883 flatcamTools/ToolSolderPaste.py:956 msgid "Wrong value format entered, use a number." msgstr "Formato de valor incorrecto introducido, use un número." -#: FlatCAMObj.py:4240 +#: FlatCAMObj.py:4781 msgid "Tool added in Tool Table." msgstr "Herramienta añadida en la tabla de herramientas." -#: FlatCAMObj.py:4347 FlatCAMObj.py:4356 +#: FlatCAMObj.py:4890 FlatCAMObj.py:4899 msgid "Failed. Select a tool to copy." msgstr "Ha fallado. Seleccione una herramienta para copiar." -#: FlatCAMObj.py:4383 +#: FlatCAMObj.py:4928 msgid "Tool was copied in Tool Table." msgstr "La herramienta se copió en la tabla de herramientas." -#: FlatCAMObj.py:4411 +#: FlatCAMObj.py:4955 msgid "Tool was edited in Tool Table." msgstr "La herramienta fue editada en la tabla de herramientas." -#: FlatCAMObj.py:4440 FlatCAMObj.py:4449 +#: FlatCAMObj.py:4984 FlatCAMObj.py:4993 msgid "Failed. Select a tool to delete." msgstr "Ha fallado. Seleccione una herramienta para eliminar." -#: FlatCAMObj.py:4472 +#: FlatCAMObj.py:5017 msgid "Tool was deleted in Tool Table." msgstr "La herramienta se eliminó en la tabla de herramientas." -#: FlatCAMObj.py:4533 flatcamGUI/ObjectUI.py:1353 -msgid "Parameters for" -msgstr "Parámetros para" - -#: FlatCAMObj.py:4967 +#: FlatCAMObj.py:5523 msgid "This Geometry can't be processed because it is" msgstr "Esta geometría no se puede procesar porque es" -#: FlatCAMObj.py:4969 +#: FlatCAMObj.py:5523 msgid "geometry" msgstr "geometría" -#: FlatCAMObj.py:5012 +#: FlatCAMObj.py:5564 msgid "Failed. No tool selected in the tool table ..." msgstr "" "Ha fallado. Ninguna herramienta seleccionada en la tabla de herramientas ..." -#: FlatCAMObj.py:5112 FlatCAMObj.py:5264 +#: FlatCAMObj.py:5667 FlatCAMObj.py:5820 msgid "" "Tool Offset is selected in Tool Table but no value is provided.\n" "Add a Tool Offset or change the Offset Type." @@ -2611,44 +2991,44 @@ msgstr "" "pero no se proporciona ningún valor.\n" "Agregue una Herramienta de compensación o cambie el Tipo de compensación." -#: FlatCAMObj.py:5177 FlatCAMObj.py:5325 +#: FlatCAMObj.py:5733 FlatCAMObj.py:5882 msgid "G-Code parsing in progress..." msgstr "Análisis de código G en progreso ..." -#: FlatCAMObj.py:5179 FlatCAMObj.py:5327 +#: FlatCAMObj.py:5735 FlatCAMObj.py:5884 msgid "G-Code parsing finished..." msgstr "Análisis de código G terminado ..." -#: FlatCAMObj.py:5187 +#: FlatCAMObj.py:5743 msgid "Finished G-Code processing" msgstr "Procesamiento de código G terminado" -#: FlatCAMObj.py:5189 FlatCAMObj.py:5339 +#: FlatCAMObj.py:5745 FlatCAMObj.py:5896 msgid "G-Code processing failed with error" msgstr "El procesamiento del código G falló con error" -#: FlatCAMObj.py:5234 flatcamTools/ToolSolderPaste.py:1303 +#: FlatCAMObj.py:5790 flatcamTools/ToolSolderPaste.py:1300 msgid "Cancelled. Empty file, it has no geometry" msgstr "Cancelado. Archivo vacío, no tiene geometría" -#: FlatCAMObj.py:5337 FlatCAMObj.py:5486 +#: FlatCAMObj.py:5894 FlatCAMObj.py:6055 msgid "Finished G-Code processing..." msgstr "Procesamiento de código G terminado ..." -#: FlatCAMObj.py:5356 FlatCAMObj.py:5360 FlatCAMObj.py:5496 +#: FlatCAMObj.py:5913 FlatCAMObj.py:5917 FlatCAMObj.py:6062 msgid "CNCjob created" msgstr "CNCjob creado" -#: FlatCAMObj.py:5527 FlatCAMObj.py:5536 flatcamParsers/ParseGerber.py:1794 -#: flatcamParsers/ParseGerber.py:1804 +#: FlatCAMObj.py:6092 FlatCAMObj.py:6101 flatcamParsers/ParseGerber.py:1866 +#: flatcamParsers/ParseGerber.py:1876 msgid "Scale factor has to be a number: integer or float." msgstr "El factor de escala debe ser un número: entero o Real." -#: FlatCAMObj.py:5600 +#: FlatCAMObj.py:6164 msgid "Geometry Scale done." msgstr "Escala de geometría realizada." -#: FlatCAMObj.py:5617 flatcamParsers/ParseGerber.py:1920 +#: FlatCAMObj.py:6181 flatcamParsers/ParseGerber.py:1992 msgid "" "An (x,y) pair of values are needed. Probable you entered only one value in " "the Offset field." @@ -2656,11 +3036,11 @@ msgstr "" "Se necesita un par de valores (x, y). Probablemente haya ingresado un solo " "valor en el campo Desplazamiento." -#: FlatCAMObj.py:5674 +#: FlatCAMObj.py:6237 msgid "Geometry Offset done." msgstr "Desplazamiento de geometría realizado." -#: FlatCAMObj.py:5703 +#: FlatCAMObj.py:6266 msgid "" "The Toolchange X,Y field in Edit -> Preferences has to be in the format (x, " "y)\n" @@ -2670,43 +3050,43 @@ msgstr "" "formato (x, y)\n" "pero ahora solo hay un valor, no dos." -#: FlatCAMObj.py:6388 FlatCAMObj.py:7175 FlatCAMObj.py:7371 +#: FlatCAMObj.py:6956 FlatCAMObj.py:7802 FlatCAMObj.py:7999 msgid "Basic" msgstr "Basic" -#: FlatCAMObj.py:6394 FlatCAMObj.py:7179 FlatCAMObj.py:7375 +#: FlatCAMObj.py:6962 FlatCAMObj.py:7806 FlatCAMObj.py:8003 msgid "Advanced" msgstr "Avanzado" -#: FlatCAMObj.py:6437 +#: FlatCAMObj.py:7005 msgid "Plotting..." msgstr "Trazando ..." -#: FlatCAMObj.py:6460 FlatCAMObj.py:6465 flatcamTools/ToolSolderPaste.py:1509 +#: FlatCAMObj.py:7034 FlatCAMObj.py:7039 flatcamTools/ToolSolderPaste.py:1498 msgid "Export Machine Code ..." msgstr "Exportar código de máquina ..." -#: FlatCAMObj.py:6470 flatcamTools/ToolSolderPaste.py:1513 +#: FlatCAMObj.py:7044 flatcamTools/ToolSolderPaste.py:1502 msgid "Export Machine Code cancelled ..." msgstr "Exportar código de máquina cancelado ..." -#: FlatCAMObj.py:6492 +#: FlatCAMObj.py:7065 msgid "Machine Code file saved to" msgstr "Archivo de código de máquina guardado en" -#: FlatCAMObj.py:6546 flatcamTools/ToolCalibration.py:1083 +#: FlatCAMObj.py:7126 flatcamTools/ToolCalibration.py:1097 msgid "Loaded Machine Code into Code Editor" msgstr "Código de máquina cargado en el editor de código" -#: FlatCAMObj.py:6684 +#: FlatCAMObj.py:7265 msgid "This CNCJob object can't be processed because it is a" msgstr "Este objeto CNCJob no se puede procesar porque es un" -#: FlatCAMObj.py:6686 +#: FlatCAMObj.py:7267 msgid "CNCJob object" msgstr "Objeto CNCJob" -#: FlatCAMObj.py:6866 +#: FlatCAMObj.py:7447 msgid "" "G-code does not have a G94 code and we will not include the code in the " "'Prepend to GCode' text box" @@ -2714,40 +3094,40 @@ msgstr "" "El código G no tiene un código G94 y no incluiremos el código en el cuadro " "de texto 'Anteponer al código GC'" -#: FlatCAMObj.py:6877 +#: FlatCAMObj.py:7458 msgid "Cancelled. The Toolchange Custom code is enabled but it's empty." msgstr "" "Cancelado. El código personalizado de Toolchange está habilitado pero está " "vacío." -#: FlatCAMObj.py:6882 +#: FlatCAMObj.py:7463 msgid "Toolchange G-code was replaced by a custom code." msgstr "El código G de Toolchange fue reemplazado por un código personalizado." -#: FlatCAMObj.py:6899 flatcamEditors/FlatCAMTextEditor.py:270 -#: flatcamTools/ToolSolderPaste.py:1540 +#: FlatCAMObj.py:7480 flatcamEditors/FlatCAMTextEditor.py:272 +#: flatcamTools/ToolSolderPaste.py:1529 msgid "No such file or directory" msgstr "El fichero o directorio no existe" -#: FlatCAMObj.py:6913 flatcamEditors/FlatCAMTextEditor.py:282 +#: FlatCAMObj.py:7494 flatcamEditors/FlatCAMTextEditor.py:284 msgid "Saved to" msgstr "Guardado en" -#: FlatCAMObj.py:6923 FlatCAMObj.py:6933 +#: FlatCAMObj.py:7511 FlatCAMObj.py:7521 msgid "" "The used preprocessor file has to have in it's name: 'toolchange_custom'" msgstr "" "El archivo de postprocesador usado debe tener su nombre: 'toolchange_custom'" -#: FlatCAMObj.py:6937 +#: FlatCAMObj.py:7524 msgid "There is no preprocessor file." msgstr "No hay archivo de postprocesador." -#: FlatCAMObj.py:7194 +#: FlatCAMObj.py:7821 msgid "Script Editor" msgstr "Editor de guiones" -#: FlatCAMObj.py:7475 +#: FlatCAMObj.py:8103 msgid "Document Editor" msgstr "Editor de Documentos" @@ -2755,6 +3135,16 @@ msgstr "Editor de Documentos" msgid "processes running." msgstr "procesos en ejecución." +#: FlatCAMTool.py:245 FlatCAMTool.py:252 flatcamGUI/ObjectUI.py:156 +#: flatcamGUI/ObjectUI.py:163 +msgid "Edited value is out of range" +msgstr "El valor editado está fuera de rango" + +#: FlatCAMTool.py:247 FlatCAMTool.py:254 flatcamGUI/ObjectUI.py:158 +#: flatcamGUI/ObjectUI.py:165 +msgid "Edited value is within limits." +msgstr "El valor editado está dentro de los límites." + #: FlatCAMTranslation.py:103 msgid "The application will restart." msgstr "La aplicación se reiniciará." @@ -2767,68 +3157,68 @@ msgstr "¿Está seguro de que desea cambiar el idioma actual a" msgid "Apply Language ..." msgstr "Aplicar Idioma ..." -#: ObjectCollection.py:459 +#: ObjectCollection.py:506 #, python-brace-format msgid "Object renamed from {old} to {new}" msgstr "Objeto renombrado de {old} a {new}" -#: ObjectCollection.py:858 +#: ObjectCollection.py:972 msgid "Cause of error" msgstr "Causa del error" -#: camlib.py:590 +#: camlib.py:593 msgid "self.solid_geometry is neither BaseGeometry or list." msgstr "self.solid_geometry no es ni BaseGeometry ni lista." -#: camlib.py:953 +#: camlib.py:968 msgid "Pass" msgstr "Pases" -#: camlib.py:974 +#: camlib.py:988 msgid "Get Exteriors" msgstr "Obtener exteriores" -#: camlib.py:977 +#: camlib.py:991 msgid "Get Interiors" msgstr "Obtener interiores" -#: camlib.py:1964 +#: camlib.py:2172 msgid "Object was mirrored" msgstr "El objeto fue reflejado" -#: camlib.py:1967 +#: camlib.py:2175 msgid "Failed to mirror. No object selected" msgstr "No se pudo reflejar. Ningún objeto seleccionado" -#: camlib.py:2036 +#: camlib.py:2244 msgid "Object was rotated" msgstr "El objeto fue girado" -#: camlib.py:2039 +#: camlib.py:2247 msgid "Failed to rotate. No object selected" msgstr "No se pudo rotar. Ningún objeto seleccionado" -#: camlib.py:2107 +#: camlib.py:2314 msgid "Object was skewed" msgstr "El objeto fue sesgado" -#: camlib.py:2110 +#: camlib.py:2317 msgid "Failed to skew. No object selected" msgstr "Error al sesgar. Ningún objeto seleccionado" -#: camlib.py:2179 +#: camlib.py:2392 msgid "Object was buffered" msgstr "El objeto fue almacenado" -#: camlib.py:2181 +#: camlib.py:2394 msgid "Failed to buffer. No object selected" msgstr "Error al almacenar en búfer. Ningún objeto seleccionado" -#: camlib.py:2378 +#: camlib.py:2599 msgid "There is no such parameter" msgstr "No hay tal parámetro" -#: camlib.py:2454 +#: camlib.py:2659 camlib.py:2892 camlib.py:3121 camlib.py:3343 msgid "" "The Cut Z parameter has positive value. It is the depth value to drill into " "material.\n" @@ -2842,11 +3232,12 @@ msgstr "" "tipográfico, por lo tanto, la aplicación convertirá el valor a negativo. " "Compruebe el código CNC resultante (Gcode, etc.)." -#: camlib.py:2462 camlib.py:3181 camlib.py:3539 +#: camlib.py:2667 camlib.py:2902 camlib.py:3131 camlib.py:3353 camlib.py:3639 +#: camlib.py:4008 msgid "The Cut Z parameter is zero. There will be no cut, skipping file" msgstr "El parámetro Cut Z es cero. No habrá corte, saltando archivo" -#: camlib.py:2475 camlib.py:3512 +#: camlib.py:2678 camlib.py:3976 msgid "" "The Toolchange X,Y field in Edit -> Preferences has to be in the format (x, " "y) \n" @@ -2856,31 +3247,39 @@ msgstr "" "formato (x, y)\n" "pero ahora solo hay un valor, no dos. " -#: camlib.py:2550 +#: camlib.py:2687 camlib.py:3590 camlib.py:3958 +msgid "" +"The End Move X,Y field in Edit -> Preferences has to be in the format (x, y) " +"but now there is only one value, not two." +msgstr "" +"El campo de movimiento final X, Y en Editar -> Preferencias debe estar en el " +"formato (x, y) pero ahora solo hay un valor, no dos." + +#: camlib.py:2775 msgid "Creating a list of points to drill..." msgstr "Crear una lista de puntos para explorar ..." -#: camlib.py:2632 +#: camlib.py:2865 camlib.py:3737 camlib.py:4112 msgid "Starting G-Code" msgstr "Iniciando el código G" -#: camlib.py:2727 camlib.py:2870 camlib.py:2972 camlib.py:3292 camlib.py:3653 +#: camlib.py:3006 camlib.py:3225 camlib.py:3389 camlib.py:3750 camlib.py:4123 msgid "Starting G-Code for tool with diameter" msgstr "Código G inicial para herramienta con diámetro" -#: camlib.py:2783 camlib.py:2926 camlib.py:3029 +#: camlib.py:3089 camlib.py:3307 camlib.py:3475 msgid "G91 coordinates not implemented" msgstr "Coordenadas G91 no implementadas" -#: camlib.py:2789 camlib.py:2933 camlib.py:3035 +#: camlib.py:3095 camlib.py:3314 camlib.py:3481 msgid "The loaded Excellon file has no drills" msgstr "El archivo Excellon cargado no tiene perforaciones" -#: camlib.py:3058 +#: camlib.py:3504 msgid "Finished G-Code generation..." msgstr "Generación de código G finalizada ..." -#: camlib.py:3153 +#: camlib.py:3608 msgid "" "The Toolchange X,Y field in Edit -> Preferences has to be in the format (x, " "y) \n" @@ -2890,7 +3289,7 @@ msgstr "" "formato (x, y)\n" "pero ahora solo hay un valor, no dos." -#: camlib.py:3166 camlib.py:3525 +#: camlib.py:3622 camlib.py:3991 msgid "" "Cut_Z parameter is None or zero. Most likely a bad combinations of other " "parameters." @@ -2898,7 +3297,7 @@ msgstr "" "El parámetro Cut_Z es Ninguno o cero. Lo más probable es una mala " "combinación de otros parámetros." -#: camlib.py:3173 camlib.py:3531 +#: camlib.py:3631 camlib.py:4000 msgid "" "The Cut Z parameter has positive value. It is the depth value to cut into " "material.\n" @@ -2912,11 +3311,11 @@ msgstr "" "tipográfico, por lo tanto, la aplicación convertirá el valor a negativo. " "Verifique el código CNC resultante (Gcode, etc.)." -#: camlib.py:3186 camlib.py:3545 +#: camlib.py:3644 camlib.py:4014 msgid "Travel Z parameter is None or zero." msgstr "El parámetro Travel Z des Ninguno o cero." -#: camlib.py:3191 camlib.py:3550 +#: camlib.py:3649 camlib.py:4019 msgid "" "The Travel Z parameter has negative value. It is the height value to travel " "between cuts.\n" @@ -2930,39 +3329,35 @@ msgstr "" "error tipográfico, por lo tanto, la aplicación convertirá el valor a " "positivo. Verifique el código CNC resultante (Gcode, etc.)." -#: camlib.py:3199 camlib.py:3558 +#: camlib.py:3657 camlib.py:4027 msgid "The Z Travel parameter is zero. This is dangerous, skipping file" msgstr "" "El parámetro Z Travel es cero. Esto es peligroso, saltando el archive %s" -#: camlib.py:3218 camlib.py:3580 +#: camlib.py:3676 camlib.py:4050 msgid "Indexing geometry before generating G-Code..." msgstr "Indexación de la geometría antes de generar código G ..." -#: camlib.py:3279 camlib.py:3642 -msgid "Starting G-Code..." -msgstr "Iniciando el código G ..." - -#: camlib.py:3362 camlib.py:3724 +#: camlib.py:3820 camlib.py:4192 msgid "Finished G-Code generation" msgstr "Generación de código G terminada" -#: camlib.py:3364 +#: camlib.py:3820 msgid "paths traced" msgstr "caminos trazados" -#: camlib.py:3399 +#: camlib.py:3853 msgid "Expected a Geometry, got" msgstr "Se esperaba una Geometría, se obtuvo" -#: camlib.py:3406 +#: camlib.py:3860 msgid "" "Trying to generate a CNC Job from a Geometry object without solid_geometry." msgstr "" "Intentando generar un trabajo de CNC desde un objeto de geometría sin " "solid_geometry." -#: camlib.py:3446 +#: camlib.py:3901 msgid "" "The Tool Offset value is too negative to use for the current_geometry.\n" "Raise the value (in module) and try again." @@ -2971,35 +3366,35 @@ msgstr "" "en current_geometry.\n" "Aumente el valor (en el módulo) e intente nuevamente." -#: camlib.py:3724 +#: camlib.py:4192 msgid " paths traced." msgstr " caminos trazados." -#: camlib.py:3752 +#: camlib.py:4220 msgid "There is no tool data in the SolderPaste geometry." msgstr "No hay datos de herramientas en la geometría SolderPaste." -#: camlib.py:3839 +#: camlib.py:4306 msgid "Finished SolderPste G-Code generation" msgstr "Generación de código G de soldadura soldada terminada" -#: camlib.py:3841 +#: camlib.py:4306 msgid "paths traced." msgstr "caminos trazados." -#: camlib.py:4097 +#: camlib.py:4566 msgid "Parsing GCode file. Number of lines" msgstr "Analizando el archivo GCode. Número de líneas" -#: camlib.py:4204 +#: camlib.py:4673 msgid "Creating Geometry from the parsed GCode file. " msgstr "Crear geometría a partir del archivo GCode analizado. " -#: camlib.py:4345 camlib.py:4629 camlib.py:4732 camlib.py:4801 +#: camlib.py:4816 camlib.py:5101 camlib.py:5204 camlib.py:5360 msgid "G91 coordinates not implemented ..." msgstr "Coordenadas G91 no implementadas ..." -#: camlib.py:4476 +#: camlib.py:4948 msgid "Unifying Geometry from parsed Geometry segments" msgstr "Geometría unificadora de segmentos de geometría analizados" @@ -3029,11 +3424,11 @@ msgstr "" #: flatcamEditors/FlatCAMExcEditor.py:193 #: flatcamEditors/FlatCAMExcEditor.py:416 #: flatcamEditors/FlatCAMExcEditor.py:637 -#: flatcamEditors/FlatCAMExcEditor.py:1155 -#: flatcamEditors/FlatCAMExcEditor.py:1182 +#: flatcamEditors/FlatCAMExcEditor.py:1152 +#: flatcamEditors/FlatCAMExcEditor.py:1179 #: flatcamEditors/FlatCAMGrbEditor.py:471 -#: flatcamEditors/FlatCAMGrbEditor.py:1936 -#: flatcamEditors/FlatCAMGrbEditor.py:1966 +#: flatcamEditors/FlatCAMGrbEditor.py:1935 +#: flatcamEditors/FlatCAMGrbEditor.py:1965 msgid "Click on target location ..." msgstr "Haga clic en la ubicación de destino ..." @@ -3067,8 +3462,8 @@ msgstr "Para agregar un espacio primero seleccione una herramienta" #: flatcamEditors/FlatCAMExcEditor.py:455 #: flatcamEditors/FlatCAMExcEditor.py:462 -#: flatcamEditors/FlatCAMExcEditor.py:744 -#: flatcamEditors/FlatCAMExcEditor.py:751 +#: flatcamEditors/FlatCAMExcEditor.py:743 +#: flatcamEditors/FlatCAMExcEditor.py:750 msgid "Value is missing or wrong format. Add it and retry." msgstr "" "Falta el formato del formato o es incorrecto Añádelo y vuelve a intentarlo." @@ -3087,73 +3482,67 @@ msgstr "" msgid "Click on the Slot Circular Array Start position" msgstr "Haga clic en la posición de inicio de la matriz circular de ranura" -#: flatcamEditors/FlatCAMExcEditor.py:682 -#: flatcamEditors/FlatCAMGrbEditor.py:520 +#: flatcamEditors/FlatCAMExcEditor.py:681 +#: flatcamEditors/FlatCAMGrbEditor.py:519 msgid "The value is mistyped. Check the value." msgstr "El valor está mal escrito. Compruebe el valor." -#: flatcamEditors/FlatCAMExcEditor.py:861 +#: flatcamEditors/FlatCAMExcEditor.py:860 msgid "Too many Slots for the selected spacing angle." msgstr "Demasiadas ranuras para el ángulo de separación seleccionado." -#: flatcamEditors/FlatCAMExcEditor.py:884 +#: flatcamEditors/FlatCAMExcEditor.py:883 msgid "Done. Slot Array added." msgstr "Hecho. Matriz de ranuras agregada." -#: flatcamEditors/FlatCAMExcEditor.py:906 +#: flatcamEditors/FlatCAMExcEditor.py:905 msgid "Click on the Drill(s) to resize ..." msgstr "Haga clic en el taladro(s) para cambiar el tamaño ..." -#: flatcamEditors/FlatCAMExcEditor.py:936 +#: flatcamEditors/FlatCAMExcEditor.py:935 msgid "Resize drill(s) failed. Please enter a diameter for resize." msgstr "" "Falló el tamaño de los taladros. Por favor, introduzca un diámetro para " "cambiar el tamaño." -#: flatcamEditors/FlatCAMExcEditor.py:1026 -#: flatcamEditors/FlatCAMExcEditor.py:1095 flatcamGUI/FlatCAMGUI.py:3165 -#: flatcamGUI/FlatCAMGUI.py:3377 flatcamGUI/FlatCAMGUI.py:3591 -msgid "Cancelled." -msgstr "Cancelado." - -#: flatcamEditors/FlatCAMExcEditor.py:1116 +#: flatcamEditors/FlatCAMExcEditor.py:1113 msgid "Done. Drill/Slot Resize completed." msgstr "Hecho. Tamaño de taladro / ranura completado." -#: flatcamEditors/FlatCAMExcEditor.py:1119 +#: flatcamEditors/FlatCAMExcEditor.py:1116 msgid "Cancelled. No drills/slots selected for resize ..." msgstr "" "Cancelado. No hay taladros / ranuras seleccionados para cambiar el tamaño ..." -#: flatcamEditors/FlatCAMExcEditor.py:1157 -#: flatcamEditors/FlatCAMGrbEditor.py:1938 +#: flatcamEditors/FlatCAMExcEditor.py:1154 +#: flatcamEditors/FlatCAMGrbEditor.py:1937 msgid "Click on reference location ..." msgstr "Haga clic en la ubicación de referencia ..." -#: flatcamEditors/FlatCAMExcEditor.py:1214 +#: flatcamEditors/FlatCAMExcEditor.py:1211 msgid "Done. Drill(s) Move completed." msgstr "Hecho. Taladro (s) Movimiento completado." -#: flatcamEditors/FlatCAMExcEditor.py:1322 +#: flatcamEditors/FlatCAMExcEditor.py:1319 msgid "Done. Drill(s) copied." msgstr "Hecho. Taladro (s) copiado." -#: flatcamEditors/FlatCAMExcEditor.py:1555 flatcamGUI/PreferencesUI.py:3551 +#: flatcamEditors/FlatCAMExcEditor.py:1558 flatcamGUI/PreferencesUI.py:3829 msgid "Excellon Editor" msgstr "Excellon Editor" -#: flatcamEditors/FlatCAMExcEditor.py:1562 -#: flatcamEditors/FlatCAMGrbEditor.py:2454 +#: flatcamEditors/FlatCAMExcEditor.py:1565 +#: flatcamEditors/FlatCAMGrbEditor.py:2460 msgid "Name:" msgstr "Nombre:" -#: flatcamEditors/FlatCAMExcEditor.py:1568 flatcamGUI/ObjectUI.py:757 -#: flatcamGUI/ObjectUI.py:1184 flatcamTools/ToolNonCopperClear.py:109 -#: flatcamTools/ToolPaint.py:112 flatcamTools/ToolSolderPaste.py:73 +#: flatcamEditors/FlatCAMExcEditor.py:1571 flatcamGUI/ObjectUI.py:760 +#: flatcamGUI/ObjectUI.py:1463 flatcamTools/ToolNCC.py:120 +#: flatcamTools/ToolPaint.py:115 flatcamTools/ToolSolderPaste.py:75 msgid "Tools Table" msgstr "Tabla de herramientas" -#: flatcamEditors/FlatCAMExcEditor.py:1570 flatcamGUI/ObjectUI.py:759 +#: flatcamEditors/FlatCAMExcEditor.py:1573 flatcamGUI/ObjectUI.py:762 msgid "" "Tools in this Excellon object\n" "when are used for drilling." @@ -3161,11 +3550,11 @@ msgstr "" "Herramientas en este objeto Excellon.\n" "Cuando se utilizan para la perforación." -#: flatcamEditors/FlatCAMExcEditor.py:1590 +#: flatcamEditors/FlatCAMExcEditor.py:1593 msgid "Add/Delete Tool" msgstr "Añadir / Eliminar herramienta" -#: flatcamEditors/FlatCAMExcEditor.py:1592 +#: flatcamEditors/FlatCAMExcEditor.py:1595 msgid "" "Add/Delete a tool to the tool list\n" "for this Excellon object." @@ -3173,16 +3562,16 @@ msgstr "" "Agregar / Eliminar una herramienta a la lista de herramientas\n" "para este objeto Excellon." -#: flatcamEditors/FlatCAMExcEditor.py:1604 flatcamGUI/ObjectUI.py:1297 -#: flatcamGUI/PreferencesUI.py:3582 +#: flatcamEditors/FlatCAMExcEditor.py:1607 flatcamGUI/ObjectUI.py:1583 +#: flatcamGUI/PreferencesUI.py:3860 msgid "Diameter for the new tool" msgstr "Diámetro para la nueva herramienta" -#: flatcamEditors/FlatCAMExcEditor.py:1614 +#: flatcamEditors/FlatCAMExcEditor.py:1617 msgid "Add Tool" msgstr "Añadir herramienta" -#: flatcamEditors/FlatCAMExcEditor.py:1616 +#: flatcamEditors/FlatCAMExcEditor.py:1619 msgid "" "Add a new tool to the tool list\n" "with the diameter specified above." @@ -3190,11 +3579,11 @@ msgstr "" "Agregar una nueva herramienta a la lista de herramientas\n" "con el diámetro especificado anteriormente." -#: flatcamEditors/FlatCAMExcEditor.py:1628 +#: flatcamEditors/FlatCAMExcEditor.py:1631 msgid "Delete Tool" msgstr "Eliminar herramienta" -#: flatcamEditors/FlatCAMExcEditor.py:1630 +#: flatcamEditors/FlatCAMExcEditor.py:1633 msgid "" "Delete a tool in the tool list\n" "by selecting a row in the tool table." @@ -3202,40 +3591,40 @@ msgstr "" "Eliminar una herramienta en la lista de herramientas\n" "seleccionando una fila en la tabla de herramientas." -#: flatcamEditors/FlatCAMExcEditor.py:1648 flatcamGUI/FlatCAMGUI.py:1896 +#: flatcamEditors/FlatCAMExcEditor.py:1651 flatcamGUI/FlatCAMGUI.py:2004 msgid "Resize Drill(s)" msgstr "Cambiar el tamaño de taladro (s)" -#: flatcamEditors/FlatCAMExcEditor.py:1650 +#: flatcamEditors/FlatCAMExcEditor.py:1653 msgid "Resize a drill or a selection of drills." msgstr "Cambiar el tamaño de un ejercicio o una selección de ejercicios." -#: flatcamEditors/FlatCAMExcEditor.py:1657 +#: flatcamEditors/FlatCAMExcEditor.py:1660 msgid "Resize Dia" msgstr "Cambiar el diá" -#: flatcamEditors/FlatCAMExcEditor.py:1659 +#: flatcamEditors/FlatCAMExcEditor.py:1662 msgid "Diameter to resize to." msgstr "Diámetro para redimensionar a." -#: flatcamEditors/FlatCAMExcEditor.py:1670 +#: flatcamEditors/FlatCAMExcEditor.py:1673 msgid "Resize" msgstr "Redimensionar" -#: flatcamEditors/FlatCAMExcEditor.py:1672 +#: flatcamEditors/FlatCAMExcEditor.py:1675 msgid "Resize drill(s)" msgstr "Cambiar el tamaño de taladro" -#: flatcamEditors/FlatCAMExcEditor.py:1697 flatcamGUI/FlatCAMGUI.py:1895 -#: flatcamGUI/FlatCAMGUI.py:2147 +#: flatcamEditors/FlatCAMExcEditor.py:1700 flatcamGUI/FlatCAMGUI.py:2003 +#: flatcamGUI/FlatCAMGUI.py:2255 msgid "Add Drill Array" msgstr "Añadir Drill Array" -#: flatcamEditors/FlatCAMExcEditor.py:1699 +#: flatcamEditors/FlatCAMExcEditor.py:1702 msgid "Add an array of drills (linear or circular array)" msgstr "Agregar una matriz de taladros (lineal o circular)" -#: flatcamEditors/FlatCAMExcEditor.py:1705 +#: flatcamEditors/FlatCAMExcEditor.py:1708 msgid "" "Select the type of drills array to create.\n" "It can be Linear X(Y) or Circular" @@ -3243,43 +3632,48 @@ msgstr "" "Seleccione el tipo de matriz de ejercicios para crear.\n" "Puede ser lineal X (Y) o circular" -#: flatcamEditors/FlatCAMExcEditor.py:1708 -#: flatcamEditors/FlatCAMExcEditor.py:1922 -#: flatcamEditors/FlatCAMGrbEditor.py:2766 +#: flatcamEditors/FlatCAMExcEditor.py:1711 +#: flatcamEditors/FlatCAMExcEditor.py:1925 +#: flatcamEditors/FlatCAMGrbEditor.py:2772 msgid "Linear" msgstr "Lineal" -#: flatcamEditors/FlatCAMExcEditor.py:1709 -#: flatcamEditors/FlatCAMExcEditor.py:1923 -#: flatcamEditors/FlatCAMGrbEditor.py:2767 flatcamGUI/ObjectUI.py:311 -#: flatcamGUI/PreferencesUI.py:5044 flatcamGUI/PreferencesUI.py:7465 -#: flatcamTools/ToolFiducials.py:220 flatcamTools/ToolNonCopperClear.py:221 +#: flatcamEditors/FlatCAMExcEditor.py:1712 +#: flatcamEditors/FlatCAMExcEditor.py:1926 +#: flatcamEditors/FlatCAMGrbEditor.py:2773 flatcamGUI/ObjectUI.py:315 +#: flatcamGUI/PreferencesUI.py:5340 flatcamGUI/PreferencesUI.py:5909 +#: flatcamGUI/PreferencesUI.py:7971 flatcamGUI/PreferencesUI.py:8151 +#: flatcamGUI/PreferencesUI.py:8248 flatcamGUI/PreferencesUI.py:8363 +#: flatcamGUI/PreferencesUI.py:8462 flatcamTools/ToolExtractDrills.py:78 +#: flatcamTools/ToolExtractDrills.py:201 flatcamTools/ToolFiducials.py:220 +#: flatcamTools/ToolNCC.py:221 flatcamTools/ToolPaint.py:204 +#: flatcamTools/ToolPunchGerber.py:89 flatcamTools/ToolPunchGerber.py:229 msgid "Circular" msgstr "Circular" -#: flatcamEditors/FlatCAMExcEditor.py:1717 flatcamGUI/PreferencesUI.py:3593 +#: flatcamEditors/FlatCAMExcEditor.py:1720 flatcamGUI/PreferencesUI.py:3871 msgid "Nr of drills" msgstr "Nu. de ejercicios" -#: flatcamEditors/FlatCAMExcEditor.py:1718 flatcamGUI/PreferencesUI.py:3595 +#: flatcamEditors/FlatCAMExcEditor.py:1721 flatcamGUI/PreferencesUI.py:3873 msgid "Specify how many drills to be in the array." msgstr "Especifique cuántos ejercicios debe estar en la matriz." -#: flatcamEditors/FlatCAMExcEditor.py:1736 -#: flatcamEditors/FlatCAMExcEditor.py:1786 -#: flatcamEditors/FlatCAMExcEditor.py:1858 -#: flatcamEditors/FlatCAMExcEditor.py:1951 -#: flatcamEditors/FlatCAMExcEditor.py:2002 -#: flatcamEditors/FlatCAMGrbEditor.py:1572 -#: flatcamEditors/FlatCAMGrbEditor.py:2795 -#: flatcamEditors/FlatCAMGrbEditor.py:2844 flatcamGUI/PreferencesUI.py:3703 +#: flatcamEditors/FlatCAMExcEditor.py:1739 +#: flatcamEditors/FlatCAMExcEditor.py:1789 +#: flatcamEditors/FlatCAMExcEditor.py:1861 +#: flatcamEditors/FlatCAMExcEditor.py:1954 +#: flatcamEditors/FlatCAMExcEditor.py:2005 +#: flatcamEditors/FlatCAMGrbEditor.py:1571 +#: flatcamEditors/FlatCAMGrbEditor.py:2801 +#: flatcamEditors/FlatCAMGrbEditor.py:2850 flatcamGUI/PreferencesUI.py:3981 msgid "Direction" msgstr "Dirección" -#: flatcamEditors/FlatCAMExcEditor.py:1738 -#: flatcamEditors/FlatCAMExcEditor.py:1953 -#: flatcamEditors/FlatCAMGrbEditor.py:2797 flatcamGUI/PreferencesUI.py:2536 -#: flatcamGUI/PreferencesUI.py:3611 flatcamGUI/PreferencesUI.py:3759 +#: flatcamEditors/FlatCAMExcEditor.py:1741 +#: flatcamEditors/FlatCAMExcEditor.py:1956 +#: flatcamEditors/FlatCAMGrbEditor.py:2803 flatcamGUI/PreferencesUI.py:2718 +#: flatcamGUI/PreferencesUI.py:3889 flatcamGUI/PreferencesUI.py:4037 msgid "" "Direction on which the linear array is oriented:\n" "- 'X' - horizontal axis \n" @@ -3291,62 +3685,62 @@ msgstr "" "- 'Y' - eje vertical o\n" "- 'Ángulo': un ángulo personalizado para la inclinación de la matriz" -#: flatcamEditors/FlatCAMExcEditor.py:1745 -#: flatcamEditors/FlatCAMExcEditor.py:1867 -#: flatcamEditors/FlatCAMExcEditor.py:1960 -#: flatcamEditors/FlatCAMGrbEditor.py:2804 flatcamGUI/PreferencesUI.py:2542 -#: flatcamGUI/PreferencesUI.py:3617 flatcamGUI/PreferencesUI.py:3712 -#: flatcamGUI/PreferencesUI.py:3765 flatcamGUI/PreferencesUI.py:5853 +#: flatcamEditors/FlatCAMExcEditor.py:1748 +#: flatcamEditors/FlatCAMExcEditor.py:1870 +#: flatcamEditors/FlatCAMExcEditor.py:1963 +#: flatcamEditors/FlatCAMGrbEditor.py:2810 flatcamGUI/PreferencesUI.py:2724 +#: flatcamGUI/PreferencesUI.py:3895 flatcamGUI/PreferencesUI.py:3990 +#: flatcamGUI/PreferencesUI.py:4043 flatcamGUI/PreferencesUI.py:6341 #: flatcamTools/ToolFilm.py:256 msgid "X" msgstr "X" -#: flatcamEditors/FlatCAMExcEditor.py:1746 -#: flatcamEditors/FlatCAMExcEditor.py:1868 -#: flatcamEditors/FlatCAMExcEditor.py:1961 -#: flatcamEditors/FlatCAMGrbEditor.py:2805 flatcamGUI/PreferencesUI.py:2543 -#: flatcamGUI/PreferencesUI.py:3618 flatcamGUI/PreferencesUI.py:3713 -#: flatcamGUI/PreferencesUI.py:3766 flatcamGUI/PreferencesUI.py:5854 +#: flatcamEditors/FlatCAMExcEditor.py:1749 +#: flatcamEditors/FlatCAMExcEditor.py:1871 +#: flatcamEditors/FlatCAMExcEditor.py:1964 +#: flatcamEditors/FlatCAMGrbEditor.py:2811 flatcamGUI/PreferencesUI.py:2725 +#: flatcamGUI/PreferencesUI.py:3896 flatcamGUI/PreferencesUI.py:3991 +#: flatcamGUI/PreferencesUI.py:4044 flatcamGUI/PreferencesUI.py:6342 #: flatcamTools/ToolFilm.py:257 msgid "Y" msgstr "Y" -#: flatcamEditors/FlatCAMExcEditor.py:1747 -#: flatcamEditors/FlatCAMExcEditor.py:1764 -#: flatcamEditors/FlatCAMExcEditor.py:1798 -#: flatcamEditors/FlatCAMExcEditor.py:1869 -#: flatcamEditors/FlatCAMExcEditor.py:1873 -#: flatcamEditors/FlatCAMExcEditor.py:1962 -#: flatcamEditors/FlatCAMExcEditor.py:1980 -#: flatcamEditors/FlatCAMExcEditor.py:2014 -#: flatcamEditors/FlatCAMGrbEditor.py:2806 -#: flatcamEditors/FlatCAMGrbEditor.py:2823 -#: flatcamEditors/FlatCAMGrbEditor.py:2859 flatcamGUI/PreferencesUI.py:2544 -#: flatcamGUI/PreferencesUI.py:2562 flatcamGUI/PreferencesUI.py:3619 -#: flatcamGUI/PreferencesUI.py:3638 flatcamGUI/PreferencesUI.py:3714 -#: flatcamGUI/PreferencesUI.py:3719 flatcamGUI/PreferencesUI.py:3767 -#: flatcamGUI/PreferencesUI.py:3788 flatcamGUI/PreferencesUI.py:6246 -#: flatcamTools/ToolDistance.py:66 flatcamTools/ToolDistanceMin.py:68 -#: flatcamTools/ToolTransform.py:63 +#: flatcamEditors/FlatCAMExcEditor.py:1750 +#: flatcamEditors/FlatCAMExcEditor.py:1767 +#: flatcamEditors/FlatCAMExcEditor.py:1801 +#: flatcamEditors/FlatCAMExcEditor.py:1872 +#: flatcamEditors/FlatCAMExcEditor.py:1876 +#: flatcamEditors/FlatCAMExcEditor.py:1965 +#: flatcamEditors/FlatCAMExcEditor.py:1983 +#: flatcamEditors/FlatCAMExcEditor.py:2017 +#: flatcamEditors/FlatCAMGrbEditor.py:2812 +#: flatcamEditors/FlatCAMGrbEditor.py:2829 +#: flatcamEditors/FlatCAMGrbEditor.py:2865 flatcamGUI/PreferencesUI.py:2726 +#: flatcamGUI/PreferencesUI.py:2744 flatcamGUI/PreferencesUI.py:3897 +#: flatcamGUI/PreferencesUI.py:3916 flatcamGUI/PreferencesUI.py:3992 +#: flatcamGUI/PreferencesUI.py:3997 flatcamGUI/PreferencesUI.py:4045 +#: flatcamGUI/PreferencesUI.py:4066 flatcamGUI/PreferencesUI.py:6733 +#: flatcamTools/ToolDistance.py:120 flatcamTools/ToolDistanceMin.py:69 +#: flatcamTools/ToolTransform.py:61 msgid "Angle" msgstr "Ángulo" -#: flatcamEditors/FlatCAMExcEditor.py:1751 -#: flatcamEditors/FlatCAMExcEditor.py:1966 -#: flatcamEditors/FlatCAMGrbEditor.py:2810 flatcamGUI/PreferencesUI.py:2550 -#: flatcamGUI/PreferencesUI.py:3625 flatcamGUI/PreferencesUI.py:3773 +#: flatcamEditors/FlatCAMExcEditor.py:1754 +#: flatcamEditors/FlatCAMExcEditor.py:1969 +#: flatcamEditors/FlatCAMGrbEditor.py:2816 flatcamGUI/PreferencesUI.py:2732 +#: flatcamGUI/PreferencesUI.py:3903 flatcamGUI/PreferencesUI.py:4051 msgid "Pitch" msgstr "Paso" -#: flatcamEditors/FlatCAMExcEditor.py:1753 -#: flatcamEditors/FlatCAMExcEditor.py:1968 -#: flatcamEditors/FlatCAMGrbEditor.py:2812 flatcamGUI/PreferencesUI.py:2552 -#: flatcamGUI/PreferencesUI.py:3627 flatcamGUI/PreferencesUI.py:3775 +#: flatcamEditors/FlatCAMExcEditor.py:1756 +#: flatcamEditors/FlatCAMExcEditor.py:1971 +#: flatcamEditors/FlatCAMGrbEditor.py:2818 flatcamGUI/PreferencesUI.py:2734 +#: flatcamGUI/PreferencesUI.py:3905 flatcamGUI/PreferencesUI.py:4053 msgid "Pitch = Distance between elements of the array." msgstr "Paso = Distancia entre elementos de la matriz." -#: flatcamEditors/FlatCAMExcEditor.py:1766 -#: flatcamEditors/FlatCAMExcEditor.py:1982 +#: flatcamEditors/FlatCAMExcEditor.py:1769 +#: flatcamEditors/FlatCAMExcEditor.py:1985 msgid "" "Angle at which the linear array is placed.\n" "The precision is of max 2 decimals.\n" @@ -3358,9 +3752,9 @@ msgstr "" "El valor mínimo es: -360 grados.\n" "El valor máximo es: 360.00 grados." -#: flatcamEditors/FlatCAMExcEditor.py:1787 -#: flatcamEditors/FlatCAMExcEditor.py:2003 -#: flatcamEditors/FlatCAMGrbEditor.py:2846 +#: flatcamEditors/FlatCAMExcEditor.py:1790 +#: flatcamEditors/FlatCAMExcEditor.py:2006 +#: flatcamEditors/FlatCAMGrbEditor.py:2852 msgid "" "Direction for circular array.Can be CW = clockwise or CCW = counter " "clockwise." @@ -3368,36 +3762,36 @@ msgstr "" "Dirección de la matriz circular. Puede ser CW = en sentido horario o CCW = " "en sentido antihorario." -#: flatcamEditors/FlatCAMExcEditor.py:1794 -#: flatcamEditors/FlatCAMExcEditor.py:2010 -#: flatcamEditors/FlatCAMGrbEditor.py:2854 flatcamGUI/PreferencesUI.py:2584 -#: flatcamGUI/PreferencesUI.py:3368 flatcamGUI/PreferencesUI.py:3661 -#: flatcamGUI/PreferencesUI.py:3811 flatcamGUI/PreferencesUI.py:4288 +#: flatcamEditors/FlatCAMExcEditor.py:1797 +#: flatcamEditors/FlatCAMExcEditor.py:2013 +#: flatcamEditors/FlatCAMGrbEditor.py:2860 flatcamGUI/PreferencesUI.py:2766 +#: flatcamGUI/PreferencesUI.py:3646 flatcamGUI/PreferencesUI.py:3939 +#: flatcamGUI/PreferencesUI.py:4089 flatcamGUI/PreferencesUI.py:4581 msgid "CW" msgstr "CW" -#: flatcamEditors/FlatCAMExcEditor.py:1795 -#: flatcamEditors/FlatCAMExcEditor.py:2011 -#: flatcamEditors/FlatCAMGrbEditor.py:2855 flatcamGUI/PreferencesUI.py:2585 -#: flatcamGUI/PreferencesUI.py:3369 flatcamGUI/PreferencesUI.py:3662 -#: flatcamGUI/PreferencesUI.py:3812 flatcamGUI/PreferencesUI.py:4289 +#: flatcamEditors/FlatCAMExcEditor.py:1798 +#: flatcamEditors/FlatCAMExcEditor.py:2014 +#: flatcamEditors/FlatCAMGrbEditor.py:2861 flatcamGUI/PreferencesUI.py:2767 +#: flatcamGUI/PreferencesUI.py:3647 flatcamGUI/PreferencesUI.py:3940 +#: flatcamGUI/PreferencesUI.py:4090 flatcamGUI/PreferencesUI.py:4582 msgid "CCW" msgstr "CCW" -#: flatcamEditors/FlatCAMExcEditor.py:1799 -#: flatcamEditors/FlatCAMExcEditor.py:2015 -#: flatcamEditors/FlatCAMGrbEditor.py:2861 flatcamGUI/PreferencesUI.py:2564 -#: flatcamGUI/PreferencesUI.py:2593 flatcamGUI/PreferencesUI.py:3640 -#: flatcamGUI/PreferencesUI.py:3670 flatcamGUI/PreferencesUI.py:3790 -#: flatcamGUI/PreferencesUI.py:3820 +#: flatcamEditors/FlatCAMExcEditor.py:1802 +#: flatcamEditors/FlatCAMExcEditor.py:2018 +#: flatcamEditors/FlatCAMGrbEditor.py:2867 flatcamGUI/PreferencesUI.py:2746 +#: flatcamGUI/PreferencesUI.py:2775 flatcamGUI/PreferencesUI.py:3918 +#: flatcamGUI/PreferencesUI.py:3948 flatcamGUI/PreferencesUI.py:4068 +#: flatcamGUI/PreferencesUI.py:4098 msgid "Angle at which each element in circular array is placed." msgstr "Ángulo en el que se coloca cada elemento de la matriz circular." -#: flatcamEditors/FlatCAMExcEditor.py:1833 +#: flatcamEditors/FlatCAMExcEditor.py:1836 msgid "Slot Parameters" msgstr "Parámetros de ranura" -#: flatcamEditors/FlatCAMExcEditor.py:1835 +#: flatcamEditors/FlatCAMExcEditor.py:1838 msgid "" "Parameters for adding a slot (hole with oval shape)\n" "either single or as an part of an array." @@ -3405,16 +3799,16 @@ msgstr "" "Parámetros para agregar una ranura (agujero con forma ovalada)\n" "ya sea solo o como parte de una matriz." -#: flatcamEditors/FlatCAMExcEditor.py:1844 flatcamGUI/PreferencesUI.py:3687 -#: flatcamTools/ToolProperties.py:555 +#: flatcamEditors/FlatCAMExcEditor.py:1847 flatcamGUI/PreferencesUI.py:3965 +#: flatcamTools/ToolProperties.py:559 msgid "Length" msgstr "Longitud" -#: flatcamEditors/FlatCAMExcEditor.py:1846 flatcamGUI/PreferencesUI.py:3689 +#: flatcamEditors/FlatCAMExcEditor.py:1849 flatcamGUI/PreferencesUI.py:3967 msgid "Length = The length of the slot." msgstr "Longitud = La longitud de la ranura." -#: flatcamEditors/FlatCAMExcEditor.py:1860 flatcamGUI/PreferencesUI.py:3705 +#: flatcamEditors/FlatCAMExcEditor.py:1863 flatcamGUI/PreferencesUI.py:3983 msgid "" "Direction on which the slot is oriented:\n" "- 'X' - horizontal axis \n" @@ -3426,7 +3820,7 @@ msgstr "" "- 'Y' - eje vertical o\n" "- 'Ángulo': un ángulo personalizado para la inclinación de la ranura" -#: flatcamEditors/FlatCAMExcEditor.py:1875 +#: flatcamEditors/FlatCAMExcEditor.py:1878 msgid "" "Angle at which the slot is placed.\n" "The precision is of max 2 decimals.\n" @@ -3438,15 +3832,15 @@ msgstr "" "El valor mínimo es: -360 grados.\n" "El valor máximo es: 360.00 grados." -#: flatcamEditors/FlatCAMExcEditor.py:1908 +#: flatcamEditors/FlatCAMExcEditor.py:1911 msgid "Slot Array Parameters" msgstr "Parámetros de matriz de ranuras" -#: flatcamEditors/FlatCAMExcEditor.py:1910 +#: flatcamEditors/FlatCAMExcEditor.py:1913 msgid "Parameters for the array of slots (linear or circular array)" msgstr "Parámetros para la matriz de ranuras (matriz lineal o circular)" -#: flatcamEditors/FlatCAMExcEditor.py:1919 +#: flatcamEditors/FlatCAMExcEditor.py:1922 msgid "" "Select the type of slot array to create.\n" "It can be Linear X(Y) or Circular" @@ -3454,15 +3848,15 @@ msgstr "" "Seleccione el tipo de matriz de ranuras para crear.\n" "Puede ser lineal X (Y) o circular" -#: flatcamEditors/FlatCAMExcEditor.py:1931 flatcamGUI/PreferencesUI.py:3744 +#: flatcamEditors/FlatCAMExcEditor.py:1934 flatcamGUI/PreferencesUI.py:4022 msgid "Nr of slots" msgstr "Nro. De ranuras" -#: flatcamEditors/FlatCAMExcEditor.py:1932 flatcamGUI/PreferencesUI.py:3746 +#: flatcamEditors/FlatCAMExcEditor.py:1935 flatcamGUI/PreferencesUI.py:4024 msgid "Specify how many slots to be in the array." msgstr "Especifique cuántas ranuras debe haber en la matriz." -#: flatcamEditors/FlatCAMExcEditor.py:2546 +#: flatcamEditors/FlatCAMExcEditor.py:2571 msgid "" "Tool already in the original or actual tool list.\n" "Save and reedit Excellon if you need to add this tool. " @@ -3470,51 +3864,51 @@ msgstr "" "Herramienta ya en la lista de herramientas original o real.\n" "Guarde y reedite Excellon si necesita agregar esta herramienta. " -#: flatcamEditors/FlatCAMExcEditor.py:2555 flatcamGUI/FlatCAMGUI.py:3792 +#: flatcamEditors/FlatCAMExcEditor.py:2580 flatcamGUI/FlatCAMGUI.py:4009 msgid "Added new tool with dia" msgstr "Nueva herramienta agregada con dia" -#: flatcamEditors/FlatCAMExcEditor.py:2589 +#: flatcamEditors/FlatCAMExcEditor.py:2613 msgid "Select a tool in Tool Table" msgstr "Seleccione una herramienta en la tabla de herramientas" -#: flatcamEditors/FlatCAMExcEditor.py:2622 +#: flatcamEditors/FlatCAMExcEditor.py:2643 msgid "Deleted tool with diameter" msgstr "Herramienta eliminada con diámetro" -#: flatcamEditors/FlatCAMExcEditor.py:2772 +#: flatcamEditors/FlatCAMExcEditor.py:2793 msgid "Done. Tool edit completed." msgstr "Hecho. Edición de herramienta completada." -#: flatcamEditors/FlatCAMExcEditor.py:3324 +#: flatcamEditors/FlatCAMExcEditor.py:3350 msgid "There are no Tools definitions in the file. Aborting Excellon creation." msgstr "" "No hay definiciones de herramientas en el archivo. Anulando la creación de " "Excellon." -#: flatcamEditors/FlatCAMExcEditor.py:3328 +#: flatcamEditors/FlatCAMExcEditor.py:3354 msgid "An internal error has ocurred. See Shell.\n" msgstr "Ha ocurrido un error interno. Ver concha.\n" -#: flatcamEditors/FlatCAMExcEditor.py:3333 +#: flatcamEditors/FlatCAMExcEditor.py:3359 msgid "Creating Excellon." msgstr "Creación de Excellon." -#: flatcamEditors/FlatCAMExcEditor.py:3347 +#: flatcamEditors/FlatCAMExcEditor.py:3371 msgid "Excellon editing finished." msgstr "Excelente edición terminada." -#: flatcamEditors/FlatCAMExcEditor.py:3365 +#: flatcamEditors/FlatCAMExcEditor.py:3388 msgid "Cancelled. There is no Tool/Drill selected" msgstr "Cancelado. No hay herramienta / taladro seleccionado" -#: flatcamEditors/FlatCAMExcEditor.py:3978 +#: flatcamEditors/FlatCAMExcEditor.py:4001 msgid "Done. Drill(s) deleted." msgstr "Hecho. Taladro (s) eliminado (s)." -#: flatcamEditors/FlatCAMExcEditor.py:4051 -#: flatcamEditors/FlatCAMExcEditor.py:4061 -#: flatcamEditors/FlatCAMGrbEditor.py:4853 +#: flatcamEditors/FlatCAMExcEditor.py:4074 +#: flatcamEditors/FlatCAMExcEditor.py:4084 +#: flatcamEditors/FlatCAMGrbEditor.py:4897 msgid "Click on the circular array Center position" msgstr "Haga clic en la posición del centro matriz circular" @@ -3542,18 +3936,24 @@ msgstr "" "funciones que se encuentran en la esquina" #: flatcamEditors/FlatCAMGeoEditor.py:95 -#: flatcamEditors/FlatCAMGrbEditor.py:2622 +#: flatcamEditors/FlatCAMGrbEditor.py:2628 msgid "Round" msgstr "Redondo" #: flatcamEditors/FlatCAMGeoEditor.py:96 -#: flatcamEditors/FlatCAMGrbEditor.py:2623 flatcamGUI/PreferencesUI.py:7058 +#: flatcamEditors/FlatCAMGrbEditor.py:2629 flatcamGUI/PreferencesUI.py:5606 +#: flatcamGUI/PreferencesUI.py:6130 flatcamGUI/PreferencesUI.py:7564 +#: flatcamGUI/PreferencesUI.py:8167 flatcamGUI/PreferencesUI.py:8274 +#: flatcamGUI/PreferencesUI.py:8379 flatcamGUI/PreferencesUI.py:8488 +#: flatcamTools/ToolExtractDrills.py:94 flatcamTools/ToolExtractDrills.py:227 +#: flatcamTools/ToolNCC.py:583 flatcamTools/ToolPaint.py:527 +#: flatcamTools/ToolPunchGerber.py:105 flatcamTools/ToolPunchGerber.py:255 #: flatcamTools/ToolQRCode.py:198 msgid "Square" msgstr "Cuadrado" #: flatcamEditors/FlatCAMGeoEditor.py:97 -#: flatcamEditors/FlatCAMGrbEditor.py:2624 +#: flatcamEditors/FlatCAMGrbEditor.py:2630 msgid "Beveled" msgstr "Biselado" @@ -3570,18 +3970,18 @@ msgid "Full Buffer" msgstr "Buffer lleno" #: flatcamEditors/FlatCAMGeoEditor.py:133 -#: flatcamEditors/FlatCAMGeoEditor.py:2885 flatcamGUI/FlatCAMGUI.py:1805 -#: flatcamGUI/PreferencesUI.py:2604 +#: flatcamEditors/FlatCAMGeoEditor.py:3018 flatcamGUI/FlatCAMGUI.py:1913 +#: flatcamGUI/PreferencesUI.py:2786 msgid "Buffer Tool" msgstr "Herramienta Buffer" #: flatcamEditors/FlatCAMGeoEditor.py:145 #: flatcamEditors/FlatCAMGeoEditor.py:162 #: flatcamEditors/FlatCAMGeoEditor.py:179 -#: flatcamEditors/FlatCAMGeoEditor.py:2904 -#: flatcamEditors/FlatCAMGeoEditor.py:2934 -#: flatcamEditors/FlatCAMGeoEditor.py:2964 -#: flatcamEditors/FlatCAMGrbEditor.py:4906 +#: flatcamEditors/FlatCAMGeoEditor.py:3037 +#: flatcamEditors/FlatCAMGeoEditor.py:3065 +#: flatcamEditors/FlatCAMGeoEditor.py:3093 +#: flatcamEditors/FlatCAMGrbEditor.py:4950 msgid "Buffer distance value is missing or wrong format. Add it and retry." msgstr "" "Falta el valor de la distancia del búfer o el formato es incorrecto. " @@ -3591,7 +3991,7 @@ msgstr "" msgid "Font" msgstr "Font" -#: flatcamEditors/FlatCAMGeoEditor.py:324 flatcamGUI/FlatCAMGUI.py:2085 +#: flatcamEditors/FlatCAMGeoEditor.py:324 flatcamGUI/FlatCAMGUI.py:2193 msgid "Text" msgstr "Texto" @@ -3599,208 +3999,112 @@ msgstr "Texto" msgid "Text Tool" msgstr "Herramienta de texto" -#: flatcamEditors/FlatCAMGeoEditor.py:442 flatcamGUI/ObjectUI.py:359 -#: flatcamGUI/PreferencesUI.py:2025 flatcamGUI/PreferencesUI.py:3875 -#: flatcamGUI/PreferencesUI.py:5535 +#: flatcamEditors/FlatCAMGeoEditor.py:440 flatcamGUI/ObjectUI.py:363 +#: flatcamGUI/PreferencesUI.py:2205 msgid "Tool dia" msgstr "Diá. de la herramienta" -#: flatcamEditors/FlatCAMGeoEditor.py:444 flatcamGUI/PreferencesUI.py:5537 +#: flatcamEditors/FlatCAMGeoEditor.py:442 +msgid "Diameter of the tool to be used in the operation." +msgstr "Diámetro de la herramienta a utilizar en la operación." + +#: flatcamEditors/FlatCAMGeoEditor.py:488 msgid "" -"Diameter of the tool to\n" -"be used in the operation." +"Algorithm to paint the polygons:\n" +"- Standard: Fixed step inwards.\n" +"- Seed-based: Outwards from seed.\n" +"- Line-based: Parallel lines." msgstr "" -"Diámetro de la herramienta para\n" -"ser utilizado en la operación." +"Algoritmo para pintar los polígonos:\n" +"- Estándar: paso fijo hacia adentro.\n" +"- Basado en semillas: hacia afuera de la semilla.\n" +"- Basado en líneas: líneas paralelas." -#: flatcamEditors/FlatCAMGeoEditor.py:455 flatcamGUI/PreferencesUI.py:5152 -#: flatcamGUI/PreferencesUI.py:5567 flatcamTools/ToolNonCopperClear.py:319 -#: flatcamTools/ToolPaint.py:219 -msgid "Overlap Rate" -msgstr "Tasa de superpos" - -#: flatcamEditors/FlatCAMGeoEditor.py:457 flatcamGUI/PreferencesUI.py:5569 -#: flatcamTools/ToolPaint.py:221 -msgid "" -"How much (fraction) of the tool width to overlap each tool pass.\n" -"Adjust the value starting with lower values\n" -"and increasing it if areas that should be painted are still \n" -"not painted.\n" -"Lower values = faster processing, faster execution on CNC.\n" -"Higher values = slow processing and slow execution on CNC\n" -"due of too many paths." -msgstr "" -"Cuánta (fracción) del ancho de la herramienta se superponen con cada pasada " -"de la herramienta.\n" -"Ajuste el valor comenzando con valores más bajos\n" -"y aumentándola si las áreas que deben ser pintadas son todavía\n" -"no pintado\n" -"Valores más bajos = procesamiento más rápido, ejecución más rápida en PCB.\n" -"Valores más altos = procesamiento lento y ejecución lenta en CNC\n" -"Debido a demasiados caminos." - -#: flatcamEditors/FlatCAMGeoEditor.py:475 flatcamGUI/PreferencesUI.py:5171 -#: flatcamGUI/PreferencesUI.py:5384 flatcamGUI/PreferencesUI.py:5587 -#: flatcamGUI/PreferencesUI.py:7175 flatcamGUI/PreferencesUI.py:7332 -#: flatcamGUI/PreferencesUI.py:7417 flatcamTools/ToolCopperThieving.py:111 -#: flatcamTools/ToolCopperThieving.py:361 flatcamTools/ToolCutOut.py:184 -#: flatcamTools/ToolFiducials.py:172 flatcamTools/ToolNonCopperClear.py:337 -#: flatcamTools/ToolPaint.py:238 -msgid "Margin" -msgstr "Margen" - -#: flatcamEditors/FlatCAMGeoEditor.py:477 flatcamGUI/PreferencesUI.py:5589 -#: flatcamTools/ToolPaint.py:240 -msgid "" -"Distance by which to avoid\n" -"the edges of the polygon to\n" -"be painted." -msgstr "" -"Distancia por la cual evitar\n" -"los bordes del polígono a\n" -"ser pintado." - -#: flatcamEditors/FlatCAMGeoEditor.py:489 flatcamGUI/PreferencesUI.py:5184 -#: flatcamGUI/PreferencesUI.py:5602 flatcamTools/ToolNonCopperClear.py:348 -#: flatcamTools/ToolPaint.py:251 -msgid "Method" -msgstr "Método" - -#: flatcamEditors/FlatCAMGeoEditor.py:491 -msgid "" -"Algorithm to paint the polygon:
Standard: Fixed step inwards." -"
Seed-based: Outwards from seed." -msgstr "" -"Algoritmo para pintar el polígono:
Estándar : Paso fijo hacia " -"adentro.
Basado en semillas : Hacia afuera desde las semillas." - -#: flatcamEditors/FlatCAMGeoEditor.py:496 flatcamGUI/PreferencesUI.py:5193 -#: flatcamGUI/PreferencesUI.py:5611 flatcamTools/ToolNonCopperClear.py:357 -#: flatcamTools/ToolPaint.py:260 -msgid "Standard" -msgstr "Estándar" - -#: flatcamEditors/FlatCAMGeoEditor.py:497 flatcamGUI/PreferencesUI.py:5194 -#: flatcamGUI/PreferencesUI.py:5612 flatcamTools/ToolNonCopperClear.py:358 -#: flatcamTools/ToolPaint.py:261 -msgid "Seed-based" -msgstr "Semillas" - -#: flatcamEditors/FlatCAMGeoEditor.py:498 flatcamGUI/PreferencesUI.py:5195 -#: flatcamGUI/PreferencesUI.py:5613 flatcamTools/ToolNonCopperClear.py:359 -#: flatcamTools/ToolPaint.py:262 -msgid "Straight lines" -msgstr "Lineas rectas" - -#: flatcamEditors/FlatCAMGeoEditor.py:505 +#: flatcamEditors/FlatCAMGeoEditor.py:507 msgid "Connect:" msgstr "Conectar:" -#: flatcamEditors/FlatCAMGeoEditor.py:507 flatcamGUI/PreferencesUI.py:5204 -#: flatcamGUI/PreferencesUI.py:5620 flatcamTools/ToolNonCopperClear.py:366 -#: flatcamTools/ToolPaint.py:269 -msgid "" -"Draw lines between resulting\n" -"segments to minimize tool lifts." -msgstr "" -"Dibuja líneas entre el resultado\n" -"Segmentos para minimizar elevaciones de herramientas." - -#: flatcamEditors/FlatCAMGeoEditor.py:515 +#: flatcamEditors/FlatCAMGeoEditor.py:517 msgid "Contour:" msgstr "Contorno:" -#: flatcamEditors/FlatCAMGeoEditor.py:517 flatcamGUI/PreferencesUI.py:5213 -#: flatcamGUI/PreferencesUI.py:5628 flatcamTools/ToolNonCopperClear.py:373 -#: flatcamTools/ToolPaint.py:276 -msgid "" -"Cut around the perimeter of the polygon\n" -"to trim rough edges." -msgstr "" -"Corta todo el perímetro del polígono.\n" -"Para recortar los bordes ásperos." - -#: flatcamEditors/FlatCAMGeoEditor.py:529 flatcamGUI/FlatCAMGUI.py:2089 +#: flatcamEditors/FlatCAMGeoEditor.py:530 flatcamGUI/FlatCAMGUI.py:2197 msgid "Paint" msgstr "Pintar" -#: flatcamEditors/FlatCAMGeoEditor.py:547 flatcamGUI/FlatCAMGUI.py:845 -#: flatcamGUI/FlatCAMGUI.py:2423 flatcamGUI/ObjectUI.py:1731 -#: flatcamTools/ToolPaint.py:41 flatcamTools/ToolPaint.py:533 +#: flatcamEditors/FlatCAMGeoEditor.py:548 flatcamGUI/FlatCAMGUI.py:909 +#: flatcamGUI/FlatCAMGUI.py:2588 flatcamGUI/ObjectUI.py:2057 +#: flatcamTools/ToolPaint.py:43 flatcamTools/ToolPaint.py:738 msgid "Paint Tool" msgstr "Herramienta de pintura" #: flatcamEditors/FlatCAMGeoEditor.py:584 -msgid "Paint cancelled. No shape selected." -msgstr "Pintura cancelada. Ninguna forma seleccionada." +#: flatcamEditors/FlatCAMGeoEditor.py:1056 +#: flatcamEditors/FlatCAMGeoEditor.py:3025 +#: flatcamEditors/FlatCAMGeoEditor.py:3053 +#: flatcamEditors/FlatCAMGeoEditor.py:3081 +#: flatcamEditors/FlatCAMGeoEditor.py:4502 +#: flatcamEditors/FlatCAMGrbEditor.py:5601 +msgid "Cancelled. No shape selected." +msgstr "Cancelado. Ninguna forma seleccionada." #: flatcamEditors/FlatCAMGeoEditor.py:597 -#: flatcamEditors/FlatCAMGeoEditor.py:2910 -#: flatcamEditors/FlatCAMGeoEditor.py:2940 -#: flatcamEditors/FlatCAMGeoEditor.py:2970 flatcamGUI/PreferencesUI.py:3871 -#: flatcamTools/ToolProperties.py:120 flatcamTools/ToolProperties.py:158 +#: flatcamEditors/FlatCAMGeoEditor.py:3043 +#: flatcamEditors/FlatCAMGeoEditor.py:3071 +#: flatcamEditors/FlatCAMGeoEditor.py:3099 flatcamGUI/PreferencesUI.py:4149 +#: flatcamTools/ToolProperties.py:117 flatcamTools/ToolProperties.py:162 msgid "Tools" msgstr "Herramientas" #: flatcamEditors/FlatCAMGeoEditor.py:608 #: flatcamEditors/FlatCAMGeoEditor.py:992 -#: flatcamEditors/FlatCAMGrbEditor.py:5096 -#: flatcamEditors/FlatCAMGrbEditor.py:5493 flatcamGUI/FlatCAMGUI.py:866 -#: flatcamGUI/FlatCAMGUI.py:2441 flatcamTools/ToolTransform.py:422 +#: flatcamEditors/FlatCAMGrbEditor.py:5140 +#: flatcamEditors/FlatCAMGrbEditor.py:5537 flatcamGUI/FlatCAMGUI.py:930 +#: flatcamGUI/FlatCAMGUI.py:2609 flatcamTools/ToolTransform.py:461 msgid "Transform Tool" msgstr "Herramienta de transformación" #: flatcamEditors/FlatCAMGeoEditor.py:609 #: flatcamEditors/FlatCAMGeoEditor.py:674 -#: flatcamEditors/FlatCAMGrbEditor.py:5097 -#: flatcamEditors/FlatCAMGrbEditor.py:5162 flatcamGUI/PreferencesUI.py:6238 -#: flatcamTools/ToolTransform.py:25 flatcamTools/ToolTransform.py:80 +#: flatcamEditors/FlatCAMGrbEditor.py:5141 +#: flatcamEditors/FlatCAMGrbEditor.py:5206 flatcamGUI/PreferencesUI.py:6725 +#: flatcamTools/ToolTransform.py:25 flatcamTools/ToolTransform.py:467 msgid "Rotate" msgstr "Girar" #: flatcamEditors/FlatCAMGeoEditor.py:610 -#: flatcamEditors/FlatCAMGrbEditor.py:5098 flatcamTools/ToolTransform.py:26 +#: flatcamEditors/FlatCAMGrbEditor.py:5142 flatcamTools/ToolTransform.py:26 msgid "Skew/Shear" msgstr "Sesgo / cizalla" #: flatcamEditors/FlatCAMGeoEditor.py:611 -#: flatcamEditors/FlatCAMGrbEditor.py:2671 -#: flatcamEditors/FlatCAMGrbEditor.py:5099 flatcamGUI/FlatCAMGUI.py:980 -#: flatcamGUI/FlatCAMGUI.py:2017 flatcamGUI/FlatCAMGUI.py:2132 -#: flatcamGUI/FlatCAMGUI.py:2549 flatcamGUI/ObjectUI.py:103 -#: flatcamGUI/ObjectUI.py:121 flatcamGUI/PreferencesUI.py:6288 -#: flatcamTools/ToolTransform.py:27 +#: flatcamEditors/FlatCAMGrbEditor.py:2677 +#: flatcamEditors/FlatCAMGrbEditor.py:5143 flatcamGUI/FlatCAMGUI.py:1048 +#: flatcamGUI/FlatCAMGUI.py:2125 flatcamGUI/FlatCAMGUI.py:2240 +#: flatcamGUI/FlatCAMGUI.py:2723 flatcamGUI/ObjectUI.py:124 +#: flatcamGUI/PreferencesUI.py:6775 flatcamTools/ToolTransform.py:27 msgid "Scale" msgstr "Escala" #: flatcamEditors/FlatCAMGeoEditor.py:612 -#: flatcamEditors/FlatCAMGrbEditor.py:5100 flatcamTools/ToolTransform.py:28 +#: flatcamEditors/FlatCAMGrbEditor.py:5144 flatcamTools/ToolTransform.py:28 msgid "Mirror (Flip)" msgstr "Espejo (Flip)" -#: flatcamEditors/FlatCAMGeoEditor.py:613 -#: flatcamEditors/FlatCAMGrbEditor.py:5101 flatcamGUI/ObjectUI.py:132 -#: flatcamGUI/ObjectUI.py:148 flatcamGUI/ObjectUI.py:1217 -#: flatcamGUI/ObjectUI.py:1916 flatcamGUI/PreferencesUI.py:5234 -#: flatcamGUI/PreferencesUI.py:6335 flatcamTools/ToolNonCopperClear.py:393 -#: flatcamTools/ToolTransform.py:29 -msgid "Offset" -msgstr "Compensar" - #: flatcamEditors/FlatCAMGeoEditor.py:626 -#: flatcamEditors/FlatCAMGrbEditor.py:5114 flatcamGUI/FlatCAMGUI.py:787 -#: flatcamGUI/FlatCAMGUI.py:2370 +#: flatcamEditors/FlatCAMGrbEditor.py:5158 flatcamGUI/FlatCAMGUI.py:841 +#: flatcamGUI/FlatCAMGUI.py:2524 msgid "Editor" msgstr "Editor" #: flatcamEditors/FlatCAMGeoEditor.py:658 -#: flatcamEditors/FlatCAMGrbEditor.py:5146 +#: flatcamEditors/FlatCAMGrbEditor.py:5190 msgid "Angle:" msgstr "Ángulo:" #: flatcamEditors/FlatCAMGeoEditor.py:660 -#: flatcamEditors/FlatCAMGrbEditor.py:5148 flatcamGUI/PreferencesUI.py:6248 -#: flatcamTools/ToolTransform.py:65 +#: flatcamEditors/FlatCAMGrbEditor.py:5192 flatcamGUI/PreferencesUI.py:6735 +#: flatcamTools/ToolTransform.py:63 msgid "" "Angle for Rotation action, in degrees.\n" "Float number between -360 and 359.\n" @@ -3813,7 +4117,7 @@ msgstr "" "Números negativos para movimiento CCW." #: flatcamEditors/FlatCAMGeoEditor.py:676 -#: flatcamEditors/FlatCAMGrbEditor.py:5164 +#: flatcamEditors/FlatCAMGrbEditor.py:5208 msgid "" "Rotate the selected shape(s).\n" "The point of reference is the middle of\n" @@ -3824,16 +4128,16 @@ msgstr "" "El cuadro delimitador para todas las formas seleccionadas." #: flatcamEditors/FlatCAMGeoEditor.py:699 -#: flatcamEditors/FlatCAMGrbEditor.py:5187 +#: flatcamEditors/FlatCAMGrbEditor.py:5231 msgid "Angle X:" msgstr "Ángulo X:" #: flatcamEditors/FlatCAMGeoEditor.py:701 #: flatcamEditors/FlatCAMGeoEditor.py:721 -#: flatcamEditors/FlatCAMGrbEditor.py:5189 -#: flatcamEditors/FlatCAMGrbEditor.py:5209 flatcamGUI/PreferencesUI.py:6267 -#: flatcamGUI/PreferencesUI.py:6281 flatcamTools/ToolCalibration.py:508 -#: flatcamTools/ToolCalibration.py:521 +#: flatcamEditors/FlatCAMGrbEditor.py:5233 +#: flatcamEditors/FlatCAMGrbEditor.py:5253 flatcamGUI/PreferencesUI.py:6754 +#: flatcamGUI/PreferencesUI.py:6768 flatcamTools/ToolCalibration.py:505 +#: flatcamTools/ToolCalibration.py:518 msgid "" "Angle for Skew action, in degrees.\n" "Float number between -360 and 359." @@ -3842,14 +4146,14 @@ msgstr "" "Número de flotación entre -360 y 359." #: flatcamEditors/FlatCAMGeoEditor.py:712 -#: flatcamEditors/FlatCAMGrbEditor.py:5200 flatcamTools/ToolTransform.py:109 +#: flatcamEditors/FlatCAMGrbEditor.py:5244 flatcamTools/ToolTransform.py:468 msgid "Skew X" msgstr "Sesgo x" #: flatcamEditors/FlatCAMGeoEditor.py:714 #: flatcamEditors/FlatCAMGeoEditor.py:734 -#: flatcamEditors/FlatCAMGrbEditor.py:5202 -#: flatcamEditors/FlatCAMGrbEditor.py:5222 +#: flatcamEditors/FlatCAMGrbEditor.py:5246 +#: flatcamEditors/FlatCAMGrbEditor.py:5266 msgid "" "Skew/shear the selected shape(s).\n" "The point of reference is the middle of\n" @@ -3860,34 +4164,34 @@ msgstr "" "El cuadro delimitador para todas las formas seleccionadas." #: flatcamEditors/FlatCAMGeoEditor.py:719 -#: flatcamEditors/FlatCAMGrbEditor.py:5207 +#: flatcamEditors/FlatCAMGrbEditor.py:5251 msgid "Angle Y:" msgstr "Ángulo Y:" #: flatcamEditors/FlatCAMGeoEditor.py:732 -#: flatcamEditors/FlatCAMGrbEditor.py:5220 flatcamTools/ToolTransform.py:131 +#: flatcamEditors/FlatCAMGrbEditor.py:5264 flatcamTools/ToolTransform.py:469 msgid "Skew Y" msgstr "Sesgo y" #: flatcamEditors/FlatCAMGeoEditor.py:760 -#: flatcamEditors/FlatCAMGrbEditor.py:5248 +#: flatcamEditors/FlatCAMGrbEditor.py:5292 msgid "Factor X:" msgstr "Factor X:" #: flatcamEditors/FlatCAMGeoEditor.py:762 -#: flatcamEditors/FlatCAMGrbEditor.py:5250 flatcamTools/ToolCalibration.py:472 +#: flatcamEditors/FlatCAMGrbEditor.py:5294 flatcamTools/ToolCalibration.py:469 msgid "Factor for Scale action over X axis." msgstr "Factor para la acción de escala sobre el eje X." #: flatcamEditors/FlatCAMGeoEditor.py:772 -#: flatcamEditors/FlatCAMGrbEditor.py:5260 flatcamTools/ToolTransform.py:158 +#: flatcamEditors/FlatCAMGrbEditor.py:5304 flatcamTools/ToolTransform.py:470 msgid "Scale X" msgstr "Escala x" #: flatcamEditors/FlatCAMGeoEditor.py:774 #: flatcamEditors/FlatCAMGeoEditor.py:793 -#: flatcamEditors/FlatCAMGrbEditor.py:5262 -#: flatcamEditors/FlatCAMGrbEditor.py:5281 +#: flatcamEditors/FlatCAMGrbEditor.py:5306 +#: flatcamEditors/FlatCAMGrbEditor.py:5325 msgid "" "Scale the selected shape(s).\n" "The point of reference depends on \n" @@ -3898,28 +4202,28 @@ msgstr "" "El estado de la casilla de verificación Escala de referencia." #: flatcamEditors/FlatCAMGeoEditor.py:779 -#: flatcamEditors/FlatCAMGrbEditor.py:5267 +#: flatcamEditors/FlatCAMGrbEditor.py:5311 msgid "Factor Y:" msgstr "Factor Y:" #: flatcamEditors/FlatCAMGeoEditor.py:781 -#: flatcamEditors/FlatCAMGrbEditor.py:5269 flatcamTools/ToolCalibration.py:484 +#: flatcamEditors/FlatCAMGrbEditor.py:5313 flatcamTools/ToolCalibration.py:481 msgid "Factor for Scale action over Y axis." msgstr "Factor de acción de escala sobre eje Y." #: flatcamEditors/FlatCAMGeoEditor.py:791 -#: flatcamEditors/FlatCAMGrbEditor.py:5279 flatcamTools/ToolTransform.py:179 +#: flatcamEditors/FlatCAMGrbEditor.py:5323 flatcamTools/ToolTransform.py:471 msgid "Scale Y" msgstr "Escala Y" #: flatcamEditors/FlatCAMGeoEditor.py:800 -#: flatcamEditors/FlatCAMGrbEditor.py:5288 flatcamGUI/PreferencesUI.py:6317 -#: flatcamTools/ToolTransform.py:192 +#: flatcamEditors/FlatCAMGrbEditor.py:5332 flatcamGUI/PreferencesUI.py:6804 +#: flatcamTools/ToolTransform.py:190 msgid "Link" msgstr "Enlazar" #: flatcamEditors/FlatCAMGeoEditor.py:802 -#: flatcamEditors/FlatCAMGrbEditor.py:5290 +#: flatcamEditors/FlatCAMGrbEditor.py:5334 msgid "" "Scale the selected shape(s)\n" "using the Scale Factor X for both axis." @@ -3928,13 +4232,13 @@ msgstr "" "Utilizando el Scale Factor X para ambos ejes." #: flatcamEditors/FlatCAMGeoEditor.py:808 -#: flatcamEditors/FlatCAMGrbEditor.py:5296 flatcamGUI/PreferencesUI.py:6325 -#: flatcamTools/ToolTransform.py:200 +#: flatcamEditors/FlatCAMGrbEditor.py:5340 flatcamGUI/PreferencesUI.py:6812 +#: flatcamTools/ToolTransform.py:197 msgid "Scale Reference" msgstr "Referencia de escala" #: flatcamEditors/FlatCAMGeoEditor.py:810 -#: flatcamEditors/FlatCAMGrbEditor.py:5298 +#: flatcamEditors/FlatCAMGrbEditor.py:5342 msgid "" "Scale the selected shape(s)\n" "using the origin reference when checked,\n" @@ -3947,24 +4251,24 @@ msgstr "" "de las formas seleccionadas cuando no está marcada." #: flatcamEditors/FlatCAMGeoEditor.py:838 -#: flatcamEditors/FlatCAMGrbEditor.py:5327 +#: flatcamEditors/FlatCAMGrbEditor.py:5371 msgid "Value X:" msgstr "Valor X:" #: flatcamEditors/FlatCAMGeoEditor.py:840 -#: flatcamEditors/FlatCAMGrbEditor.py:5329 +#: flatcamEditors/FlatCAMGrbEditor.py:5373 msgid "Value for Offset action on X axis." msgstr "Valor para la acción Offset en el eje X." #: flatcamEditors/FlatCAMGeoEditor.py:850 -#: flatcamEditors/FlatCAMGrbEditor.py:5339 flatcamTools/ToolTransform.py:227 +#: flatcamEditors/FlatCAMGrbEditor.py:5383 flatcamTools/ToolTransform.py:474 msgid "Offset X" msgstr "Offset X" #: flatcamEditors/FlatCAMGeoEditor.py:852 #: flatcamEditors/FlatCAMGeoEditor.py:872 -#: flatcamEditors/FlatCAMGrbEditor.py:5341 -#: flatcamEditors/FlatCAMGrbEditor.py:5361 +#: flatcamEditors/FlatCAMGrbEditor.py:5385 +#: flatcamEditors/FlatCAMGrbEditor.py:5405 msgid "" "Offset the selected shape(s).\n" "The point of reference is the middle of\n" @@ -3975,29 +4279,29 @@ msgstr "" "El cuadro delimitador para todas las formas seleccionadas.\n" #: flatcamEditors/FlatCAMGeoEditor.py:858 -#: flatcamEditors/FlatCAMGrbEditor.py:5347 +#: flatcamEditors/FlatCAMGrbEditor.py:5391 msgid "Value Y:" msgstr "Valor Y:" #: flatcamEditors/FlatCAMGeoEditor.py:860 -#: flatcamEditors/FlatCAMGrbEditor.py:5349 +#: flatcamEditors/FlatCAMGrbEditor.py:5393 msgid "Value for Offset action on Y axis." msgstr "Valor para la acción Offset en el eje Y." #: flatcamEditors/FlatCAMGeoEditor.py:870 -#: flatcamEditors/FlatCAMGrbEditor.py:5359 flatcamTools/ToolTransform.py:248 +#: flatcamEditors/FlatCAMGrbEditor.py:5403 flatcamTools/ToolTransform.py:475 msgid "Offset Y" msgstr "Offset Y" #: flatcamEditors/FlatCAMGeoEditor.py:901 -#: flatcamEditors/FlatCAMGrbEditor.py:5390 flatcamTools/ToolTransform.py:266 +#: flatcamEditors/FlatCAMGrbEditor.py:5434 flatcamTools/ToolTransform.py:476 msgid "Flip on X" msgstr "Voltear en X" #: flatcamEditors/FlatCAMGeoEditor.py:903 #: flatcamEditors/FlatCAMGeoEditor.py:910 -#: flatcamEditors/FlatCAMGrbEditor.py:5392 -#: flatcamEditors/FlatCAMGrbEditor.py:5399 +#: flatcamEditors/FlatCAMGrbEditor.py:5436 +#: flatcamEditors/FlatCAMGrbEditor.py:5443 msgid "" "Flip the selected shape(s) over the X axis.\n" "Does not create a new shape." @@ -4006,17 +4310,17 @@ msgstr "" "No crea una nueva forma." #: flatcamEditors/FlatCAMGeoEditor.py:908 -#: flatcamEditors/FlatCAMGrbEditor.py:5397 flatcamTools/ToolTransform.py:272 +#: flatcamEditors/FlatCAMGrbEditor.py:5441 flatcamTools/ToolTransform.py:477 msgid "Flip on Y" msgstr "Voltear en Y" #: flatcamEditors/FlatCAMGeoEditor.py:916 -#: flatcamEditors/FlatCAMGrbEditor.py:5405 +#: flatcamEditors/FlatCAMGrbEditor.py:5449 msgid "Ref Pt" msgstr "Punto de Ref" #: flatcamEditors/FlatCAMGeoEditor.py:918 -#: flatcamEditors/FlatCAMGrbEditor.py:5407 +#: flatcamEditors/FlatCAMGrbEditor.py:5451 msgid "" "Flip the selected shape(s)\n" "around the point in Point Entry Field.\n" @@ -4039,12 +4343,12 @@ msgstr "" "Campo de entrada de puntos y haga clic en Girar en X (Y)" #: flatcamEditors/FlatCAMGeoEditor.py:930 -#: flatcamEditors/FlatCAMGrbEditor.py:5419 +#: flatcamEditors/FlatCAMGrbEditor.py:5463 msgid "Point:" msgstr "Punto:" #: flatcamEditors/FlatCAMGeoEditor.py:932 -#: flatcamEditors/FlatCAMGrbEditor.py:5421 flatcamTools/ToolTransform.py:301 +#: flatcamEditors/FlatCAMGrbEditor.py:5465 flatcamTools/ToolTransform.py:300 msgid "" "Coordinates in format (x, y) used as reference for mirroring.\n" "The 'x' in (x, y) will be used when using Flip on X and\n" @@ -4056,7 +4360,7 @@ msgstr "" "la 'y' en (x, y) se usará cuando se use Flip en Y." #: flatcamEditors/FlatCAMGeoEditor.py:942 -#: flatcamEditors/FlatCAMGrbEditor.py:5433 flatcamTools/ToolTransform.py:312 +#: flatcamEditors/FlatCAMGrbEditor.py:5477 flatcamTools/ToolTransform.py:310 msgid "" "The point coordinates can be captured by\n" "left click on canvas together with pressing\n" @@ -4066,354 +4370,354 @@ msgstr "" "Haga clic izquierdo en el lienzo junto con la presión\n" "Tecla Shift. Luego haga clic en el botón Agregar para insertar." -#: flatcamEditors/FlatCAMGeoEditor.py:1057 -#: flatcamEditors/FlatCAMGrbEditor.py:5558 -msgid "Transformation cancelled. No shape selected." -msgstr "Transformación cancelada. Ninguna forma seleccionada." - -#: flatcamEditors/FlatCAMGeoEditor.py:1258 -#: flatcamEditors/FlatCAMGrbEditor.py:5742 +#: flatcamEditors/FlatCAMGeoEditor.py:1305 +#: flatcamEditors/FlatCAMGrbEditor.py:5785 msgid "No shape selected. Please Select a shape to rotate!" msgstr "" "Ninguna forma seleccionada. Por favor, seleccione una forma para rotar!" -#: flatcamEditors/FlatCAMGeoEditor.py:1261 -#: flatcamEditors/FlatCAMGrbEditor.py:5745 flatcamTools/ToolTransform.py:611 +#: flatcamEditors/FlatCAMGeoEditor.py:1308 +#: flatcamEditors/FlatCAMGrbEditor.py:5788 flatcamTools/ToolTransform.py:680 msgid "Appying Rotate" msgstr "Aplicando rotar" -#: flatcamEditors/FlatCAMGeoEditor.py:1290 -#: flatcamEditors/FlatCAMGrbEditor.py:5779 +#: flatcamEditors/FlatCAMGeoEditor.py:1334 +#: flatcamEditors/FlatCAMGrbEditor.py:5820 msgid "Done. Rotate completed." msgstr "Hecho. Rotación completada." -#: flatcamEditors/FlatCAMGeoEditor.py:1295 +#: flatcamEditors/FlatCAMGeoEditor.py:1336 msgid "Rotation action was not executed" msgstr "La acción de rotación no se ejecutó" -#: flatcamEditors/FlatCAMGeoEditor.py:1307 -#: flatcamEditors/FlatCAMGrbEditor.py:5800 +#: flatcamEditors/FlatCAMGeoEditor.py:1355 +#: flatcamEditors/FlatCAMGrbEditor.py:5839 msgid "No shape selected. Please Select a shape to flip!" msgstr "" "Ninguna forma seleccionada. Por favor, seleccione una forma para voltear!" -#: flatcamEditors/FlatCAMGeoEditor.py:1310 -#: flatcamEditors/FlatCAMGrbEditor.py:5803 flatcamTools/ToolTransform.py:664 +#: flatcamEditors/FlatCAMGeoEditor.py:1358 +#: flatcamEditors/FlatCAMGrbEditor.py:5842 flatcamTools/ToolTransform.py:729 msgid "Applying Flip" msgstr "Aplicando Voltear" -#: flatcamEditors/FlatCAMGeoEditor.py:1341 -#: flatcamEditors/FlatCAMGrbEditor.py:5843 flatcamTools/ToolTransform.py:707 +#: flatcamEditors/FlatCAMGeoEditor.py:1387 +#: flatcamEditors/FlatCAMGrbEditor.py:5880 flatcamTools/ToolTransform.py:770 msgid "Flip on the Y axis done" msgstr "Voltear sobre el eje Y hecho" -#: flatcamEditors/FlatCAMGeoEditor.py:1345 -#: flatcamEditors/FlatCAMGrbEditor.py:5852 flatcamTools/ToolTransform.py:717 +#: flatcamEditors/FlatCAMGeoEditor.py:1391 +#: flatcamEditors/FlatCAMGrbEditor.py:5889 flatcamTools/ToolTransform.py:779 msgid "Flip on the X axis done" msgstr "Voltear en el eje X hecho" -#: flatcamEditors/FlatCAMGeoEditor.py:1355 +#: flatcamEditors/FlatCAMGeoEditor.py:1399 msgid "Flip action was not executed" msgstr "La acción de voltear no se ejecutó" -#: flatcamEditors/FlatCAMGeoEditor.py:1365 -#: flatcamEditors/FlatCAMGrbEditor.py:5874 +#: flatcamEditors/FlatCAMGeoEditor.py:1417 +#: flatcamEditors/FlatCAMGrbEditor.py:5909 msgid "No shape selected. Please Select a shape to shear/skew!" msgstr "" "Ninguna forma seleccionada. Por favor, seleccione una forma para esquilar / " "sesgar!" -#: flatcamEditors/FlatCAMGeoEditor.py:1368 -#: flatcamEditors/FlatCAMGrbEditor.py:5877 flatcamTools/ToolTransform.py:742 +#: flatcamEditors/FlatCAMGeoEditor.py:1420 +#: flatcamEditors/FlatCAMGrbEditor.py:5912 flatcamTools/ToolTransform.py:802 msgid "Applying Skew" msgstr "Aplicando Sesgo" -#: flatcamEditors/FlatCAMGeoEditor.py:1394 -#: flatcamEditors/FlatCAMGrbEditor.py:5913 +#: flatcamEditors/FlatCAMGeoEditor.py:1443 +#: flatcamEditors/FlatCAMGrbEditor.py:5946 msgid "Skew on the X axis done" msgstr "Sesgar sobre el eje X hecho" -#: flatcamEditors/FlatCAMGeoEditor.py:1397 -#: flatcamEditors/FlatCAMGrbEditor.py:5915 +#: flatcamEditors/FlatCAMGeoEditor.py:1445 +#: flatcamEditors/FlatCAMGrbEditor.py:5948 msgid "Skew on the Y axis done" msgstr "Sesgar sobre el eje Y hecho" -#: flatcamEditors/FlatCAMGeoEditor.py:1401 +#: flatcamEditors/FlatCAMGeoEditor.py:1448 msgid "Skew action was not executed" msgstr "La acción sesgada no se ejecutó" -#: flatcamEditors/FlatCAMGeoEditor.py:1413 -#: flatcamEditors/FlatCAMGrbEditor.py:5939 +#: flatcamEditors/FlatCAMGeoEditor.py:1470 +#: flatcamEditors/FlatCAMGrbEditor.py:5970 msgid "No shape selected. Please Select a shape to scale!" msgstr "Ninguna forma seleccionada. Por favor, seleccione una forma a escala!" -#: flatcamEditors/FlatCAMGeoEditor.py:1416 -#: flatcamEditors/FlatCAMGrbEditor.py:5942 flatcamTools/ToolTransform.py:794 +#: flatcamEditors/FlatCAMGeoEditor.py:1473 +#: flatcamEditors/FlatCAMGrbEditor.py:5973 flatcamTools/ToolTransform.py:849 msgid "Applying Scale" msgstr "Aplicando la escala" -#: flatcamEditors/FlatCAMGeoEditor.py:1451 -#: flatcamEditors/FlatCAMGrbEditor.py:5981 +#: flatcamEditors/FlatCAMGeoEditor.py:1505 +#: flatcamEditors/FlatCAMGrbEditor.py:6010 msgid "Scale on the X axis done" msgstr "Escala en el eje X hecho" -#: flatcamEditors/FlatCAMGeoEditor.py:1454 -#: flatcamEditors/FlatCAMGrbEditor.py:5983 +#: flatcamEditors/FlatCAMGeoEditor.py:1507 +#: flatcamEditors/FlatCAMGrbEditor.py:6012 msgid "Scale on the Y axis done" msgstr "Escala en el eje Y hecho" -#: flatcamEditors/FlatCAMGeoEditor.py:1457 +#: flatcamEditors/FlatCAMGeoEditor.py:1509 msgid "Scale action was not executed" msgstr "La acción de escala no se ejecutó" -#: flatcamEditors/FlatCAMGeoEditor.py:1467 -#: flatcamEditors/FlatCAMGrbEditor.py:6000 +#: flatcamEditors/FlatCAMGeoEditor.py:1524 +#: flatcamEditors/FlatCAMGrbEditor.py:6029 msgid "No shape selected. Please Select a shape to offset!" msgstr "" "Ninguna forma seleccionada. Por favor, seleccione una forma para compensar!" -#: flatcamEditors/FlatCAMGeoEditor.py:1470 -#: flatcamEditors/FlatCAMGrbEditor.py:6003 flatcamTools/ToolTransform.py:849 +#: flatcamEditors/FlatCAMGeoEditor.py:1527 +#: flatcamEditors/FlatCAMGrbEditor.py:6032 flatcamTools/ToolTransform.py:901 msgid "Applying Offset" msgstr "Aplicando Offset" -#: flatcamEditors/FlatCAMGeoEditor.py:1483 -#: flatcamEditors/FlatCAMGrbEditor.py:6024 +#: flatcamEditors/FlatCAMGeoEditor.py:1537 +#: flatcamEditors/FlatCAMGrbEditor.py:6053 msgid "Offset on the X axis done" msgstr "Offset en el eje X hecho" -#: flatcamEditors/FlatCAMGeoEditor.py:1486 -#: flatcamEditors/FlatCAMGrbEditor.py:6026 +#: flatcamEditors/FlatCAMGeoEditor.py:1539 +#: flatcamEditors/FlatCAMGrbEditor.py:6055 msgid "Offset on the Y axis done" msgstr "Offset en el eje Y hecho" -#: flatcamEditors/FlatCAMGeoEditor.py:1490 +#: flatcamEditors/FlatCAMGeoEditor.py:1542 msgid "Offset action was not executed" msgstr "La acción de desplazamiento no se ejecutó" -#: flatcamEditors/FlatCAMGeoEditor.py:1494 -#: flatcamEditors/FlatCAMGrbEditor.py:6033 +#: flatcamEditors/FlatCAMGeoEditor.py:1546 +#: flatcamEditors/FlatCAMGrbEditor.py:6062 msgid "Rotate ..." msgstr "Girar ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1495 -#: flatcamEditors/FlatCAMGeoEditor.py:1550 -#: flatcamEditors/FlatCAMGeoEditor.py:1567 -#: flatcamEditors/FlatCAMGrbEditor.py:6034 -#: flatcamEditors/FlatCAMGrbEditor.py:6083 -#: flatcamEditors/FlatCAMGrbEditor.py:6098 +#: flatcamEditors/FlatCAMGeoEditor.py:1547 +#: flatcamEditors/FlatCAMGeoEditor.py:1602 +#: flatcamEditors/FlatCAMGeoEditor.py:1619 +#: flatcamEditors/FlatCAMGrbEditor.py:6063 +#: flatcamEditors/FlatCAMGrbEditor.py:6112 +#: flatcamEditors/FlatCAMGrbEditor.py:6127 msgid "Enter an Angle Value (degrees)" msgstr "Ingrese un valor de ángulo (grados)" -#: flatcamEditors/FlatCAMGeoEditor.py:1504 -#: flatcamEditors/FlatCAMGrbEditor.py:6042 +#: flatcamEditors/FlatCAMGeoEditor.py:1556 +#: flatcamEditors/FlatCAMGrbEditor.py:6071 msgid "Geometry shape rotate done" msgstr "Forma de geometría rotar hecho" -#: flatcamEditors/FlatCAMGeoEditor.py:1508 -#: flatcamEditors/FlatCAMGrbEditor.py:6045 +#: flatcamEditors/FlatCAMGeoEditor.py:1560 +#: flatcamEditors/FlatCAMGrbEditor.py:6074 msgid "Geometry shape rotate cancelled" msgstr "Rotación de forma de geometría cancelada" -#: flatcamEditors/FlatCAMGeoEditor.py:1513 -#: flatcamEditors/FlatCAMGrbEditor.py:6050 +#: flatcamEditors/FlatCAMGeoEditor.py:1565 +#: flatcamEditors/FlatCAMGrbEditor.py:6079 msgid "Offset on X axis ..." msgstr "Offset en el eje X ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1514 -#: flatcamEditors/FlatCAMGeoEditor.py:1533 -#: flatcamEditors/FlatCAMGrbEditor.py:6051 -#: flatcamEditors/FlatCAMGrbEditor.py:6068 +#: flatcamEditors/FlatCAMGeoEditor.py:1566 +#: flatcamEditors/FlatCAMGeoEditor.py:1585 +#: flatcamEditors/FlatCAMGrbEditor.py:6080 +#: flatcamEditors/FlatCAMGrbEditor.py:6097 msgid "Enter a distance Value" msgstr "Ingrese un valor de distancia" -#: flatcamEditors/FlatCAMGeoEditor.py:1523 -#: flatcamEditors/FlatCAMGrbEditor.py:6059 +#: flatcamEditors/FlatCAMGeoEditor.py:1575 +#: flatcamEditors/FlatCAMGrbEditor.py:6088 msgid "Geometry shape offset on X axis done" msgstr "Forma de geometría compensada en el eje X hecho" -#: flatcamEditors/FlatCAMGeoEditor.py:1527 -#: flatcamEditors/FlatCAMGrbEditor.py:6062 +#: flatcamEditors/FlatCAMGeoEditor.py:1579 +#: flatcamEditors/FlatCAMGrbEditor.py:6091 msgid "Geometry shape offset X cancelled" msgstr "Desplazamiento de forma de geometría X cancelado" -#: flatcamEditors/FlatCAMGeoEditor.py:1532 -#: flatcamEditors/FlatCAMGrbEditor.py:6067 +#: flatcamEditors/FlatCAMGeoEditor.py:1584 +#: flatcamEditors/FlatCAMGrbEditor.py:6096 msgid "Offset on Y axis ..." msgstr "Offset en eje Y ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1542 -#: flatcamEditors/FlatCAMGrbEditor.py:6076 +#: flatcamEditors/FlatCAMGeoEditor.py:1594 +#: flatcamEditors/FlatCAMGrbEditor.py:6105 msgid "Geometry shape offset on Y axis done" msgstr "Desplazamiento de forma de geometría en el eje Y hecho" -#: flatcamEditors/FlatCAMGeoEditor.py:1546 +#: flatcamEditors/FlatCAMGeoEditor.py:1598 msgid "Geometry shape offset on Y axis canceled" msgstr "Desplazamiento de forma de geometría en eje Y cancelado" -#: flatcamEditors/FlatCAMGeoEditor.py:1549 -#: flatcamEditors/FlatCAMGrbEditor.py:6082 +#: flatcamEditors/FlatCAMGeoEditor.py:1601 +#: flatcamEditors/FlatCAMGrbEditor.py:6111 msgid "Skew on X axis ..." msgstr "Sesgar en el eje X ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1559 -#: flatcamEditors/FlatCAMGrbEditor.py:6091 +#: flatcamEditors/FlatCAMGeoEditor.py:1611 +#: flatcamEditors/FlatCAMGrbEditor.py:6120 msgid "Geometry shape skew on X axis done" msgstr "Forma de geometría sesgada en el eje X hecho" -#: flatcamEditors/FlatCAMGeoEditor.py:1563 +#: flatcamEditors/FlatCAMGeoEditor.py:1615 msgid "Geometry shape skew on X axis canceled" msgstr "Forma geométrica sesgada en el eje X cancelada" -#: flatcamEditors/FlatCAMGeoEditor.py:1566 -#: flatcamEditors/FlatCAMGrbEditor.py:6097 +#: flatcamEditors/FlatCAMGeoEditor.py:1618 +#: flatcamEditors/FlatCAMGrbEditor.py:6126 msgid "Skew on Y axis ..." msgstr "Sesgar en el eje Y ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1576 -#: flatcamEditors/FlatCAMGrbEditor.py:6106 +#: flatcamEditors/FlatCAMGeoEditor.py:1628 +#: flatcamEditors/FlatCAMGrbEditor.py:6135 msgid "Geometry shape skew on Y axis done" msgstr "Forma de geometría sesgada en el eje Y hecho" -#: flatcamEditors/FlatCAMGeoEditor.py:1580 +#: flatcamEditors/FlatCAMGeoEditor.py:1632 msgid "Geometry shape skew on Y axis canceled" msgstr "Forma geométrica sesgada en el eje Y cancelada" -#: flatcamEditors/FlatCAMGeoEditor.py:1951 -#: flatcamEditors/FlatCAMGeoEditor.py:2016 -#: flatcamEditors/FlatCAMGrbEditor.py:1436 -#: flatcamEditors/FlatCAMGrbEditor.py:1514 +#: flatcamEditors/FlatCAMGeoEditor.py:2009 +#: flatcamEditors/FlatCAMGeoEditor.py:2080 +#: flatcamEditors/FlatCAMGrbEditor.py:1435 +#: flatcamEditors/FlatCAMGrbEditor.py:1513 msgid "Click on Center point ..." msgstr "Haga clic en el punto central ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1958 -#: flatcamEditors/FlatCAMGrbEditor.py:1446 +#: flatcamEditors/FlatCAMGeoEditor.py:2022 +#: flatcamEditors/FlatCAMGrbEditor.py:1445 msgid "Click on Perimeter point to complete ..." msgstr "Haga clic en el punto del perímetro para completar ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1990 +#: flatcamEditors/FlatCAMGeoEditor.py:2054 msgid "Done. Adding Circle completed." msgstr "Hecho. Añadiendo círculo completado." -#: flatcamEditors/FlatCAMGeoEditor.py:2038 -#: flatcamEditors/FlatCAMGrbEditor.py:1547 +#: flatcamEditors/FlatCAMGeoEditor.py:2108 +#: flatcamEditors/FlatCAMGrbEditor.py:1546 msgid "Click on Start point ..." msgstr "Haga clic en el punto de inicio ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2040 -#: flatcamEditors/FlatCAMGrbEditor.py:1549 +#: flatcamEditors/FlatCAMGeoEditor.py:2110 +#: flatcamEditors/FlatCAMGrbEditor.py:1548 msgid "Click on Point3 ..." msgstr "Haga clic en el punto 3 ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2042 -#: flatcamEditors/FlatCAMGrbEditor.py:1551 +#: flatcamEditors/FlatCAMGeoEditor.py:2112 +#: flatcamEditors/FlatCAMGrbEditor.py:1550 msgid "Click on Stop point ..." msgstr "Haga clic en el punto de parada ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2047 -#: flatcamEditors/FlatCAMGrbEditor.py:1556 +#: flatcamEditors/FlatCAMGeoEditor.py:2117 +#: flatcamEditors/FlatCAMGrbEditor.py:1555 msgid "Click on Stop point to complete ..." msgstr "Haga clic en el punto de parada para completar ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2049 -#: flatcamEditors/FlatCAMGrbEditor.py:1558 +#: flatcamEditors/FlatCAMGeoEditor.py:2119 +#: flatcamEditors/FlatCAMGrbEditor.py:1557 msgid "Click on Point2 to complete ..." msgstr "Haga clic en el punto 2 para completar ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2051 -#: flatcamEditors/FlatCAMGrbEditor.py:1560 +#: flatcamEditors/FlatCAMGeoEditor.py:2121 +#: flatcamEditors/FlatCAMGrbEditor.py:1559 msgid "Click on Center point to complete ..." msgstr "Haga clic en el punto central para completar ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2063 +#: flatcamEditors/FlatCAMGeoEditor.py:2133 #, python-format msgid "Direction: %s" msgstr "Direccion: %s" -#: flatcamEditors/FlatCAMGeoEditor.py:2077 -#: flatcamEditors/FlatCAMGrbEditor.py:1586 +#: flatcamEditors/FlatCAMGeoEditor.py:2147 +#: flatcamEditors/FlatCAMGrbEditor.py:1585 msgid "Mode: Start -> Stop -> Center. Click on Start point ..." msgstr "Modo: Inicio -> Detener -> Centro. Haga clic en el punto de inicio ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2080 -#: flatcamEditors/FlatCAMGrbEditor.py:1589 +#: flatcamEditors/FlatCAMGeoEditor.py:2150 +#: flatcamEditors/FlatCAMGrbEditor.py:1588 msgid "Mode: Point1 -> Point3 -> Point2. Click on Point1 ..." msgstr "Modo: Punto1 -> Punto3 -> Punto2. Haga clic en el punto 1 ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2083 -#: flatcamEditors/FlatCAMGrbEditor.py:1592 +#: flatcamEditors/FlatCAMGeoEditor.py:2153 +#: flatcamEditors/FlatCAMGrbEditor.py:1591 msgid "Mode: Center -> Start -> Stop. Click on Center point ..." msgstr "Modo: Centro -> Iniciar -> Detener. Haga clic en el punto central ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2224 +#: flatcamEditors/FlatCAMGeoEditor.py:2294 msgid "Done. Arc completed." msgstr "Hecho. Arco completado." -#: flatcamEditors/FlatCAMGeoEditor.py:2255 -#: flatcamEditors/FlatCAMGeoEditor.py:2322 +#: flatcamEditors/FlatCAMGeoEditor.py:2325 +#: flatcamEditors/FlatCAMGeoEditor.py:2398 msgid "Click on 1st corner ..." msgstr "Haga clic en la primera esquina ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2261 +#: flatcamEditors/FlatCAMGeoEditor.py:2337 msgid "Click on opposite corner to complete ..." msgstr "Haga clic en la esquina opuesta para completar ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2291 +#: flatcamEditors/FlatCAMGeoEditor.py:2367 msgid "Done. Rectangle completed." msgstr "Hecho. Rectángulo completado." -#: flatcamEditors/FlatCAMGeoEditor.py:2329 +#: flatcamEditors/FlatCAMGeoEditor.py:2411 flatcamTools/ToolNCC.py:1728 +#: flatcamTools/ToolPaint.py:1623 msgid "Click on next Point or click right mouse button to complete ..." msgstr "" "Haga clic en el siguiente punto o haga clic con el botón derecho del ratón " "para completar ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2360 +#: flatcamEditors/FlatCAMGeoEditor.py:2442 msgid "Done. Polygon completed." msgstr "Hecho. Polígono completado." -#: flatcamEditors/FlatCAMGeoEditor.py:2374 -#: flatcamEditors/FlatCAMGeoEditor.py:2439 -#: flatcamEditors/FlatCAMGrbEditor.py:1112 -#: flatcamEditors/FlatCAMGrbEditor.py:1323 +#: flatcamEditors/FlatCAMGeoEditor.py:2456 +#: flatcamEditors/FlatCAMGeoEditor.py:2521 +#: flatcamEditors/FlatCAMGrbEditor.py:1111 +#: flatcamEditors/FlatCAMGrbEditor.py:1322 msgid "Backtracked one point ..." msgstr "Retrocedido un punto ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2417 +#: flatcamEditors/FlatCAMGeoEditor.py:2499 msgid "Done. Path completed." msgstr "Hecho. Camino completado." -#: flatcamEditors/FlatCAMGeoEditor.py:2580 +#: flatcamEditors/FlatCAMGeoEditor.py:2658 +msgid "No shape selected. Select a shape to explode" +msgstr "Ninguna forma seleccionada. Selecciona una forma para explotar" + +#: flatcamEditors/FlatCAMGeoEditor.py:2691 msgid "Done. Polygons exploded into lines." msgstr "Hecho. Los polígonos explotaron en líneas." -#: flatcamEditors/FlatCAMGeoEditor.py:2612 +#: flatcamEditors/FlatCAMGeoEditor.py:2723 msgid "MOVE: No shape selected. Select a shape to move" msgstr "MOVER: No se seleccionó la forma. Selecciona una forma para mover" -#: flatcamEditors/FlatCAMGeoEditor.py:2615 -#: flatcamEditors/FlatCAMGeoEditor.py:2628 +#: flatcamEditors/FlatCAMGeoEditor.py:2726 +#: flatcamEditors/FlatCAMGeoEditor.py:2746 msgid " MOVE: Click on reference point ..." msgstr " MOVER: haga clic en el punto de referencia ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2619 +#: flatcamEditors/FlatCAMGeoEditor.py:2731 msgid " Click on destination point ..." msgstr " Haga clic en el punto de destino ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2653 +#: flatcamEditors/FlatCAMGeoEditor.py:2771 msgid "Done. Geometry(s) Move completed." msgstr "Hecho. Geometría (s) Movimiento completado." -#: flatcamEditors/FlatCAMGeoEditor.py:2783 +#: flatcamEditors/FlatCAMGeoEditor.py:2904 msgid "Done. Geometry(s) Copy completed." msgstr "Hecho. Geometría (s) Copia completada." -#: flatcamEditors/FlatCAMGeoEditor.py:2811 -#: flatcamEditors/FlatCAMGrbEditor.py:898 +#: flatcamEditors/FlatCAMGeoEditor.py:2935 +#: flatcamEditors/FlatCAMGrbEditor.py:897 msgid "Click on 1st point ..." msgstr "Haga clic en el primer punto ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2829 +#: flatcamEditors/FlatCAMGeoEditor.py:2959 msgid "" "Font not supported. Only Regular, Bold, Italic and BoldItalic are supported. " "Error" @@ -4421,96 +4725,132 @@ msgstr "" "Fuente no soportada. Solo se admiten las versiones Regular, Bold, Italic y " "BoldItalic. Error" -#: flatcamEditors/FlatCAMGeoEditor.py:2837 +#: flatcamEditors/FlatCAMGeoEditor.py:2967 msgid "No text to add." msgstr "No hay texto para agregar." -#: flatcamEditors/FlatCAMGeoEditor.py:2844 +#: flatcamEditors/FlatCAMGeoEditor.py:2977 msgid " Done. Adding Text completed." msgstr " Hecho. Agregando texto completado." -#: flatcamEditors/FlatCAMGeoEditor.py:2881 +#: flatcamEditors/FlatCAMGeoEditor.py:3014 msgid "Create buffer geometry ..." msgstr "Crear geometría de búfer ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2892 -#: flatcamEditors/FlatCAMGeoEditor.py:2922 -#: flatcamEditors/FlatCAMGeoEditor.py:2952 -msgid "Buffer cancelled. No shape selected." -msgstr "Buffer cancelado. Ninguna forma seleccionada." - -#: flatcamEditors/FlatCAMGeoEditor.py:2917 -#: flatcamEditors/FlatCAMGrbEditor.py:4950 +#: flatcamEditors/FlatCAMGeoEditor.py:3049 +#: flatcamEditors/FlatCAMGrbEditor.py:4994 msgid "Done. Buffer Tool completed." msgstr "Hecho. Herramienta de amortiguación completada." -#: flatcamEditors/FlatCAMGeoEditor.py:2947 +#: flatcamEditors/FlatCAMGeoEditor.py:3077 msgid "Done. Buffer Int Tool completed." msgstr "Hecho. Herramienta interna de búfer completada." -#: flatcamEditors/FlatCAMGeoEditor.py:2977 +#: flatcamEditors/FlatCAMGeoEditor.py:3105 msgid "Done. Buffer Ext Tool completed." msgstr "Hecho. Herramienta externa de búfer completada." -#: flatcamEditors/FlatCAMGeoEditor.py:3023 -#: flatcamEditors/FlatCAMGrbEditor.py:2152 +#: flatcamEditors/FlatCAMGeoEditor.py:3154 +#: flatcamEditors/FlatCAMGrbEditor.py:2151 msgid "Select a shape to act as deletion area ..." msgstr "Seleccione una forma para que actúe como área de eliminación ..." -#: flatcamEditors/FlatCAMGeoEditor.py:3025 -#: flatcamEditors/FlatCAMGeoEditor.py:3045 -#: flatcamEditors/FlatCAMGeoEditor.py:3051 -#: flatcamEditors/FlatCAMGrbEditor.py:2154 +#: flatcamEditors/FlatCAMGeoEditor.py:3156 +#: flatcamEditors/FlatCAMGeoEditor.py:3182 +#: flatcamEditors/FlatCAMGeoEditor.py:3188 +#: flatcamEditors/FlatCAMGrbEditor.py:2153 msgid "Click to pick-up the erase shape..." msgstr "Haga clic para recoger la forma de borrar ..." -#: flatcamEditors/FlatCAMGeoEditor.py:3055 -#: flatcamEditors/FlatCAMGrbEditor.py:2213 +#: flatcamEditors/FlatCAMGeoEditor.py:3192 +#: flatcamEditors/FlatCAMGrbEditor.py:2212 msgid "Click to erase ..." msgstr "Haga clic para borrar ..." -#: flatcamEditors/FlatCAMGeoEditor.py:3084 -#: flatcamEditors/FlatCAMGrbEditor.py:2246 +#: flatcamEditors/FlatCAMGeoEditor.py:3221 +#: flatcamEditors/FlatCAMGrbEditor.py:2245 msgid "Done. Eraser tool action completed." msgstr "Hecho. Se ha completado la acción de la herramienta de borrador." -#: flatcamEditors/FlatCAMGeoEditor.py:3131 +#: flatcamEditors/FlatCAMGeoEditor.py:3271 msgid "Create Paint geometry ..." msgstr "Crear geometría de pintura ..." -#: flatcamEditors/FlatCAMGeoEditor.py:3144 -#: flatcamEditors/FlatCAMGrbEditor.py:2402 +#: flatcamEditors/FlatCAMGeoEditor.py:3284 +#: flatcamEditors/FlatCAMGrbEditor.py:2408 msgid "Shape transformations ..." msgstr "Transformaciones de formas ..." -#: flatcamEditors/FlatCAMGeoEditor.py:3763 +#: flatcamEditors/FlatCAMGeoEditor.py:3340 flatcamGUI/PreferencesUI.py:4636 +msgid "Geometry Editor" +msgstr "Editor de geometría" + +#: flatcamEditors/FlatCAMGeoEditor.py:3346 +#: flatcamEditors/FlatCAMGrbEditor.py:2486 +#: flatcamEditors/FlatCAMGrbEditor.py:3846 flatcamGUI/ObjectUI.py:262 +#: flatcamGUI/ObjectUI.py:1495 flatcamGUI/ObjectUI.py:2244 +#: flatcamTools/ToolCutOut.py:96 +msgid "Type" +msgstr "Tipo" + +#: flatcamEditors/FlatCAMGeoEditor.py:3346 flatcamGUI/ObjectUI.py:217 +#: flatcamGUI/ObjectUI.py:741 flatcamGUI/ObjectUI.py:1431 +#: flatcamGUI/ObjectUI.py:2153 flatcamGUI/ObjectUI.py:2457 +#: flatcamGUI/ObjectUI.py:2524 flatcamTools/ToolCalibration.py:234 +#: flatcamTools/ToolFiducials.py:73 +msgid "Name" +msgstr "Nombre" + +#: flatcamEditors/FlatCAMGeoEditor.py:3588 +msgid "Ring" +msgstr "Anillo" + +#: flatcamEditors/FlatCAMGeoEditor.py:3590 +msgid "Line" +msgstr "Línea" + +#: flatcamEditors/FlatCAMGeoEditor.py:3592 flatcamGUI/FlatCAMGUI.py:2187 +#: flatcamGUI/PreferencesUI.py:5607 flatcamGUI/PreferencesUI.py:6131 +#: flatcamTools/ToolNCC.py:584 flatcamTools/ToolPaint.py:528 +msgid "Polygon" +msgstr "Polígono" + +#: flatcamEditors/FlatCAMGeoEditor.py:3594 +msgid "Multi-Line" +msgstr "Multilínea" + +#: flatcamEditors/FlatCAMGeoEditor.py:3596 +msgid "Multi-Polygon" +msgstr "Multi-polígono" + +#: flatcamEditors/FlatCAMGeoEditor.py:3603 +msgid "Geo Elem" +msgstr "Elemento de Geo" + +#: flatcamEditors/FlatCAMGeoEditor.py:4076 msgid "Editing MultiGeo Geometry, tool" msgstr "Edición de Geometría MultiGeo, herramienta" -#: flatcamEditors/FlatCAMGeoEditor.py:3765 +#: flatcamEditors/FlatCAMGeoEditor.py:4078 msgid "with diameter" msgstr "con diámetro" -#: flatcamEditors/FlatCAMGeoEditor.py:4169 -msgid "Copy cancelled. No shape selected." -msgstr "Copia cancelada. Ninguna forma seleccionada." - -#: flatcamEditors/FlatCAMGeoEditor.py:4176 flatcamGUI/FlatCAMGUI.py:3472 -#: flatcamGUI/FlatCAMGUI.py:3519 flatcamGUI/FlatCAMGUI.py:3538 -#: flatcamGUI/FlatCAMGUI.py:3679 flatcamGUI/FlatCAMGUI.py:3719 -#: flatcamGUI/FlatCAMGUI.py:3732 flatcamGUI/FlatCAMGUI.py:3749 +#: flatcamEditors/FlatCAMGeoEditor.py:4509 flatcamGUI/FlatCAMGUI.py:3695 +#: flatcamGUI/FlatCAMGUI.py:3741 flatcamGUI/FlatCAMGUI.py:3759 +#: flatcamGUI/FlatCAMGUI.py:3899 flatcamGUI/FlatCAMGUI.py:3938 +#: flatcamGUI/FlatCAMGUI.py:3950 flatcamGUI/FlatCAMGUI.py:3967 msgid "Click on target point." msgstr "Haga clic en el punto de destino." -#: flatcamEditors/FlatCAMGeoEditor.py:4479 -#: flatcamEditors/FlatCAMGeoEditor.py:4514 +#: flatcamEditors/FlatCAMGeoEditor.py:4823 +#: flatcamEditors/FlatCAMGeoEditor.py:4858 msgid "A selection of at least 2 geo items is required to do Intersection." msgstr "" "Se requiere una selección de al menos 2 elementos geo para hacer " "Intersección." -#: flatcamEditors/FlatCAMGeoEditor.py:4600 -#: flatcamEditors/FlatCAMGeoEditor.py:4704 +#: flatcamEditors/FlatCAMGeoEditor.py:4944 +#: flatcamEditors/FlatCAMGeoEditor.py:5048 msgid "" "Negative buffer value is not accepted. Use Buffer interior to generate an " "'inside' shape" @@ -4518,59 +4858,58 @@ msgstr "" "No se acepta el valor de búfer negativo. Usa el interior del amortiguador " "para generar una forma 'interior'" -#: flatcamEditors/FlatCAMGeoEditor.py:4610 -#: flatcamEditors/FlatCAMGeoEditor.py:4663 -#: flatcamEditors/FlatCAMGeoEditor.py:4713 +#: flatcamEditors/FlatCAMGeoEditor.py:4954 +#: flatcamEditors/FlatCAMGeoEditor.py:5007 +#: flatcamEditors/FlatCAMGeoEditor.py:5057 msgid "Nothing selected for buffering." msgstr "Nada seleccionado para el almacenamiento en búfer." -#: flatcamEditors/FlatCAMGeoEditor.py:4615 -#: flatcamEditors/FlatCAMGeoEditor.py:4667 -#: flatcamEditors/FlatCAMGeoEditor.py:4718 +#: flatcamEditors/FlatCAMGeoEditor.py:4959 +#: flatcamEditors/FlatCAMGeoEditor.py:5011 +#: flatcamEditors/FlatCAMGeoEditor.py:5062 msgid "Invalid distance for buffering." msgstr "Distancia no válida para el almacenamiento en búfer." -#: flatcamEditors/FlatCAMGeoEditor.py:4639 -#: flatcamEditors/FlatCAMGeoEditor.py:4738 +#: flatcamEditors/FlatCAMGeoEditor.py:4983 +#: flatcamEditors/FlatCAMGeoEditor.py:5082 msgid "Failed, the result is empty. Choose a different buffer value." msgstr "Falló, el resultado está vacío. Elija un valor de búfer diferente." -#: flatcamEditors/FlatCAMGeoEditor.py:4650 +#: flatcamEditors/FlatCAMGeoEditor.py:4994 msgid "Full buffer geometry created." msgstr "Geometría de búfer completa creada." -#: flatcamEditors/FlatCAMGeoEditor.py:4656 +#: flatcamEditors/FlatCAMGeoEditor.py:5000 msgid "Negative buffer value is not accepted." msgstr "No se acepta el valor negativo del búfer." -#: flatcamEditors/FlatCAMGeoEditor.py:4687 +#: flatcamEditors/FlatCAMGeoEditor.py:5031 msgid "Failed, the result is empty. Choose a smaller buffer value." msgstr "Falló, el resultado está vacío. Elija un valor de búfer más pequeño." -#: flatcamEditors/FlatCAMGeoEditor.py:4697 +#: flatcamEditors/FlatCAMGeoEditor.py:5041 msgid "Interior buffer geometry created." msgstr "Geometría de búfer interior creada." -#: flatcamEditors/FlatCAMGeoEditor.py:4748 +#: flatcamEditors/FlatCAMGeoEditor.py:5092 msgid "Exterior buffer geometry created." msgstr "Geometría de búfer exterior creada." -#: flatcamEditors/FlatCAMGeoEditor.py:4754 +#: flatcamEditors/FlatCAMGeoEditor.py:5098 #, python-format -msgid "Could not do Paint. Overlap value has to be less than 1.00 (100%%)." +msgid "Could not do Paint. Overlap value has to be less than 100%%." msgstr "" -"No se pudo hacer pintura. El valor de superposición debe ser inferior a 1.00 " -"(100%%)." +"No se pudo pintar. El valor de superposición debe ser inferior al 100 %%." -#: flatcamEditors/FlatCAMGeoEditor.py:4761 +#: flatcamEditors/FlatCAMGeoEditor.py:5105 msgid "Nothing selected for painting." msgstr "Nada seleccionado para pintar." -#: flatcamEditors/FlatCAMGeoEditor.py:4767 +#: flatcamEditors/FlatCAMGeoEditor.py:5111 msgid "Invalid value for" msgstr "Valor no válido para" -#: flatcamEditors/FlatCAMGeoEditor.py:4826 +#: flatcamEditors/FlatCAMGeoEditor.py:5170 msgid "" "Could not do Paint. Try a different combination of parameters. Or a " "different method of Paint" @@ -4578,7 +4917,7 @@ msgstr "" "No se pudo pintar. Pruebe con una combinación diferente de parámetros. O un " "método diferente de pintura" -#: flatcamEditors/FlatCAMGeoEditor.py:4840 +#: flatcamEditors/FlatCAMGeoEditor.py:5181 msgid "Paint done." msgstr "Pintura hecha." @@ -4593,7 +4932,7 @@ msgid "Aperture size is zero. It needs to be greater than zero." msgstr "El tamaño de la abertura es cero. Tiene que ser mayor que cero." #: flatcamEditors/FlatCAMGrbEditor.py:371 -#: flatcamEditors/FlatCAMGrbEditor.py:685 +#: flatcamEditors/FlatCAMGrbEditor.py:684 msgid "" "Incompatible aperture type. Select an aperture with type 'C', 'R' or 'O'." msgstr "" @@ -4614,173 +4953,167 @@ msgstr "" msgid "Click on the Pad Circular Array Start position" msgstr "Haga clic en la posición de inicio Pad Array Circular" -#: flatcamEditors/FlatCAMGrbEditor.py:711 +#: flatcamEditors/FlatCAMGrbEditor.py:710 msgid "Too many Pads for the selected spacing angle." msgstr "Demasiados pads para el ángulo de espaciado seleccionado." -#: flatcamEditors/FlatCAMGrbEditor.py:734 +#: flatcamEditors/FlatCAMGrbEditor.py:733 msgid "Done. Pad Array added." msgstr "Hecho. Pad Array añadido." -#: flatcamEditors/FlatCAMGrbEditor.py:759 +#: flatcamEditors/FlatCAMGrbEditor.py:758 msgid "Select shape(s) and then click ..." msgstr "Seleccione forma (s) y luego haga clic en ..." -#: flatcamEditors/FlatCAMGrbEditor.py:771 +#: flatcamEditors/FlatCAMGrbEditor.py:770 msgid "Failed. Nothing selected." msgstr "Ha fallado. Nada seleccionado." -#: flatcamEditors/FlatCAMGrbEditor.py:787 +#: flatcamEditors/FlatCAMGrbEditor.py:786 msgid "" "Failed. Poligonize works only on geometries belonging to the same aperture." msgstr "" "Ha fallado. Poligonize funciona solo en geometrías pertenecientes a la misma " "abertura." -#: flatcamEditors/FlatCAMGrbEditor.py:841 +#: flatcamEditors/FlatCAMGrbEditor.py:840 msgid "Done. Poligonize completed." msgstr "Hecho. Poligonize completado." -#: flatcamEditors/FlatCAMGrbEditor.py:896 -#: flatcamEditors/FlatCAMGrbEditor.py:1129 -#: flatcamEditors/FlatCAMGrbEditor.py:1153 +#: flatcamEditors/FlatCAMGrbEditor.py:895 +#: flatcamEditors/FlatCAMGrbEditor.py:1128 +#: flatcamEditors/FlatCAMGrbEditor.py:1152 msgid "Corner Mode 1: 45 degrees ..." msgstr "Modo esquina 1: 45 grados ..." -#: flatcamEditors/FlatCAMGrbEditor.py:908 -#: flatcamEditors/FlatCAMGrbEditor.py:1238 +#: flatcamEditors/FlatCAMGrbEditor.py:907 +#: flatcamEditors/FlatCAMGrbEditor.py:1237 msgid "Click on next Point or click Right mouse button to complete ..." msgstr "" "Haga clic en el siguiente punto o haga clic con el botón derecho del mouse " "para completar ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1117 -#: flatcamEditors/FlatCAMGrbEditor.py:1150 +#: flatcamEditors/FlatCAMGrbEditor.py:1116 +#: flatcamEditors/FlatCAMGrbEditor.py:1149 msgid "Corner Mode 2: Reverse 45 degrees ..." msgstr "Modo esquina 2: Invertir 45 grados ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1120 -#: flatcamEditors/FlatCAMGrbEditor.py:1147 +#: flatcamEditors/FlatCAMGrbEditor.py:1119 +#: flatcamEditors/FlatCAMGrbEditor.py:1146 msgid "Corner Mode 3: 90 degrees ..." msgstr "Modo esquina 3: 90 grados ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1123 -#: flatcamEditors/FlatCAMGrbEditor.py:1144 +#: flatcamEditors/FlatCAMGrbEditor.py:1122 +#: flatcamEditors/FlatCAMGrbEditor.py:1143 msgid "Corner Mode 4: Reverse 90 degrees ..." msgstr "Modo esquina 4: Invertir 90 grados ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1126 -#: flatcamEditors/FlatCAMGrbEditor.py:1141 +#: flatcamEditors/FlatCAMGrbEditor.py:1125 +#: flatcamEditors/FlatCAMGrbEditor.py:1140 msgid "Corner Mode 5: Free angle ..." msgstr "Modo esquina 5: ángulo libre ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1183 -#: flatcamEditors/FlatCAMGrbEditor.py:1359 -#: flatcamEditors/FlatCAMGrbEditor.py:1398 +#: flatcamEditors/FlatCAMGrbEditor.py:1182 +#: flatcamEditors/FlatCAMGrbEditor.py:1358 +#: flatcamEditors/FlatCAMGrbEditor.py:1397 msgid "Track Mode 1: 45 degrees ..." msgstr "Modo de pista 1: 45 grados ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1339 -#: flatcamEditors/FlatCAMGrbEditor.py:1393 +#: flatcamEditors/FlatCAMGrbEditor.py:1338 +#: flatcamEditors/FlatCAMGrbEditor.py:1392 msgid "Track Mode 2: Reverse 45 degrees ..." msgstr "Modo de pista 2: Invertir 45 grados ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1344 -#: flatcamEditors/FlatCAMGrbEditor.py:1388 +#: flatcamEditors/FlatCAMGrbEditor.py:1343 +#: flatcamEditors/FlatCAMGrbEditor.py:1387 msgid "Track Mode 3: 90 degrees ..." msgstr "Modo de pista 3: 90 grados ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1349 -#: flatcamEditors/FlatCAMGrbEditor.py:1383 +#: flatcamEditors/FlatCAMGrbEditor.py:1348 +#: flatcamEditors/FlatCAMGrbEditor.py:1382 msgid "Track Mode 4: Reverse 90 degrees ..." msgstr "Modo de pista 4: Invertir 90 grados ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1354 -#: flatcamEditors/FlatCAMGrbEditor.py:1378 +#: flatcamEditors/FlatCAMGrbEditor.py:1353 +#: flatcamEditors/FlatCAMGrbEditor.py:1377 msgid "Track Mode 5: Free angle ..." msgstr "Modo de pista 5: ángulo libre ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1779 +#: flatcamEditors/FlatCAMGrbEditor.py:1778 msgid "Scale the selected Gerber apertures ..." msgstr "Escala las aperturas seleccionadas de Gerber ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1821 +#: flatcamEditors/FlatCAMGrbEditor.py:1820 msgid "Buffer the selected apertures ..." msgstr "Buffer de las aberturas seleccionadas ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1863 +#: flatcamEditors/FlatCAMGrbEditor.py:1862 msgid "Mark polygon areas in the edited Gerber ..." msgstr "Marcar áreas de polígono en el Gerber editado ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1929 +#: flatcamEditors/FlatCAMGrbEditor.py:1928 msgid "Nothing selected to move" msgstr "Nada seleccionado para mover" -#: flatcamEditors/FlatCAMGrbEditor.py:2054 +#: flatcamEditors/FlatCAMGrbEditor.py:2053 msgid "Done. Apertures Move completed." msgstr "Hecho. Movimiento de aperturas completado." -#: flatcamEditors/FlatCAMGrbEditor.py:2136 +#: flatcamEditors/FlatCAMGrbEditor.py:2135 msgid "Done. Apertures copied." msgstr "Hecho. Aberturas copiadas." -#: flatcamEditors/FlatCAMGrbEditor.py:2447 flatcamGUI/FlatCAMGUI.py:2110 -#: flatcamGUI/PreferencesUI.py:2443 +#: flatcamEditors/FlatCAMGrbEditor.py:2453 flatcamGUI/FlatCAMGUI.py:2218 +#: flatcamGUI/PreferencesUI.py:2623 msgid "Gerber Editor" msgstr "Gerber Editor" -#: flatcamEditors/FlatCAMGrbEditor.py:2467 flatcamGUI/ObjectUI.py:223 -#: flatcamTools/ToolProperties.py:156 +#: flatcamEditors/FlatCAMGrbEditor.py:2473 flatcamGUI/ObjectUI.py:227 +#: flatcamTools/ToolProperties.py:159 msgid "Apertures" msgstr "Aberturas" -#: flatcamEditors/FlatCAMGrbEditor.py:2469 flatcamGUI/ObjectUI.py:225 +#: flatcamEditors/FlatCAMGrbEditor.py:2475 flatcamGUI/ObjectUI.py:229 msgid "Apertures Table for the Gerber Object." msgstr "Tabla de Aperturas para el Objeto Gerber." -#: flatcamEditors/FlatCAMGrbEditor.py:2480 -#: flatcamEditors/FlatCAMGrbEditor.py:3832 flatcamGUI/ObjectUI.py:258 +#: flatcamEditors/FlatCAMGrbEditor.py:2486 +#: flatcamEditors/FlatCAMGrbEditor.py:3846 flatcamGUI/ObjectUI.py:262 msgid "Code" msgstr "Código" -#: flatcamEditors/FlatCAMGrbEditor.py:2480 -#: flatcamEditors/FlatCAMGrbEditor.py:3832 flatcamGUI/ObjectUI.py:258 -#: flatcamGUI/ObjectUI.py:1217 flatcamGUI/ObjectUI.py:1916 -msgid "Type" -msgstr "Tipo" - -#: flatcamEditors/FlatCAMGrbEditor.py:2480 -#: flatcamEditors/FlatCAMGrbEditor.py:3832 flatcamGUI/ObjectUI.py:258 -#: flatcamGUI/PreferencesUI.py:1009 flatcamGUI/PreferencesUI.py:7270 -#: flatcamGUI/PreferencesUI.py:7299 flatcamGUI/PreferencesUI.py:7401 -#: flatcamTools/ToolCopperThieving.py:260 -#: flatcamTools/ToolCopperThieving.py:300 flatcamTools/ToolFiducials.py:156 +#: flatcamEditors/FlatCAMGrbEditor.py:2486 +#: flatcamEditors/FlatCAMGrbEditor.py:3846 flatcamGUI/ObjectUI.py:262 +#: flatcamGUI/PreferencesUI.py:1184 flatcamGUI/PreferencesUI.py:7776 +#: flatcamGUI/PreferencesUI.py:7805 flatcamGUI/PreferencesUI.py:7907 +#: flatcamTools/ToolCopperThieving.py:262 +#: flatcamTools/ToolCopperThieving.py:302 flatcamTools/ToolFiducials.py:156 msgid "Size" msgstr "Tamaño" -#: flatcamEditors/FlatCAMGrbEditor.py:2480 -#: flatcamEditors/FlatCAMGrbEditor.py:3832 flatcamGUI/ObjectUI.py:258 +#: flatcamEditors/FlatCAMGrbEditor.py:2486 +#: flatcamEditors/FlatCAMGrbEditor.py:3846 flatcamGUI/ObjectUI.py:262 msgid "Dim" msgstr "Dim" -#: flatcamEditors/FlatCAMGrbEditor.py:2484 flatcamGUI/ObjectUI.py:262 +#: flatcamEditors/FlatCAMGrbEditor.py:2490 flatcamGUI/ObjectUI.py:266 msgid "Index" msgstr "Índice" -#: flatcamEditors/FlatCAMGrbEditor.py:2486 -#: flatcamEditors/FlatCAMGrbEditor.py:2515 flatcamGUI/ObjectUI.py:264 +#: flatcamEditors/FlatCAMGrbEditor.py:2492 +#: flatcamEditors/FlatCAMGrbEditor.py:2521 flatcamGUI/ObjectUI.py:268 msgid "Aperture Code" msgstr "Código de apertura" -#: flatcamEditors/FlatCAMGrbEditor.py:2488 flatcamGUI/ObjectUI.py:266 +#: flatcamEditors/FlatCAMGrbEditor.py:2494 flatcamGUI/ObjectUI.py:270 msgid "Type of aperture: circular, rectangle, macros etc" msgstr "Tipo de apertura: circular, rectangular, macros, etc" -#: flatcamEditors/FlatCAMGrbEditor.py:2490 flatcamGUI/ObjectUI.py:268 +#: flatcamEditors/FlatCAMGrbEditor.py:2496 flatcamGUI/ObjectUI.py:272 msgid "Aperture Size:" msgstr "Tamaño de apertura:" -#: flatcamEditors/FlatCAMGrbEditor.py:2492 flatcamGUI/ObjectUI.py:270 +#: flatcamEditors/FlatCAMGrbEditor.py:2498 flatcamGUI/ObjectUI.py:274 msgid "" "Aperture Dimensions:\n" " - (width, height) for R, O type.\n" @@ -4790,15 +5123,15 @@ msgstr "" "  - (ancho, alto) para R, O tipo.\n" "  - (dia, nVertices) para tipo P" -#: flatcamEditors/FlatCAMGrbEditor.py:2516 flatcamGUI/PreferencesUI.py:2474 +#: flatcamEditors/FlatCAMGrbEditor.py:2522 flatcamGUI/PreferencesUI.py:2654 msgid "Code for the new aperture" msgstr "Código para la nueva apertura" -#: flatcamEditors/FlatCAMGrbEditor.py:2525 +#: flatcamEditors/FlatCAMGrbEditor.py:2531 msgid "Aperture Size" msgstr "Tamaño de apertura" -#: flatcamEditors/FlatCAMGrbEditor.py:2527 +#: flatcamEditors/FlatCAMGrbEditor.py:2533 msgid "" "Size for the new aperture.\n" "If aperture type is 'R' or 'O' then\n" @@ -4812,11 +5145,11 @@ msgstr "" "calculado como:\n" "sqrt (ancho ** 2 + altura ** 2)" -#: flatcamEditors/FlatCAMGrbEditor.py:2541 +#: flatcamEditors/FlatCAMGrbEditor.py:2547 msgid "Aperture Type" msgstr "Tipo de apertura" -#: flatcamEditors/FlatCAMGrbEditor.py:2543 +#: flatcamEditors/FlatCAMGrbEditor.py:2549 msgid "" "Select the type of new aperture. Can be:\n" "C = circular\n" @@ -4828,11 +5161,11 @@ msgstr "" "R = rectangular\n" "O = oblongo" -#: flatcamEditors/FlatCAMGrbEditor.py:2554 +#: flatcamEditors/FlatCAMGrbEditor.py:2560 msgid "Aperture Dim" msgstr "Apertura Dim" -#: flatcamEditors/FlatCAMGrbEditor.py:2556 +#: flatcamEditors/FlatCAMGrbEditor.py:2562 msgid "" "Dimensions for the new aperture.\n" "Active only for rectangular apertures (type R).\n" @@ -4842,39 +5175,39 @@ msgstr "" "Activo solo para aberturas rectangulares (tipo R).\n" "El formato es (ancho, alto)." -#: flatcamEditors/FlatCAMGrbEditor.py:2565 +#: flatcamEditors/FlatCAMGrbEditor.py:2571 msgid "Add/Delete Aperture" msgstr "Añadir / Eliminar Apertura" -#: flatcamEditors/FlatCAMGrbEditor.py:2567 +#: flatcamEditors/FlatCAMGrbEditor.py:2573 msgid "Add/Delete an aperture in the aperture table" msgstr "Añadir / Eliminar una apertura en la tabla de aperturas" -#: flatcamEditors/FlatCAMGrbEditor.py:2576 +#: flatcamEditors/FlatCAMGrbEditor.py:2582 msgid "Add a new aperture to the aperture list." msgstr "Agregar una nueva apertura a la lista de apertura." -#: flatcamEditors/FlatCAMGrbEditor.py:2581 +#: flatcamEditors/FlatCAMGrbEditor.py:2587 msgid "Delete a aperture in the aperture list" msgstr "Eliminar una abertura en la lista de aperturas" -#: flatcamEditors/FlatCAMGrbEditor.py:2598 +#: flatcamEditors/FlatCAMGrbEditor.py:2604 msgid "Buffer Aperture" msgstr "Apertura del tampón" -#: flatcamEditors/FlatCAMGrbEditor.py:2600 +#: flatcamEditors/FlatCAMGrbEditor.py:2606 msgid "Buffer a aperture in the aperture list" msgstr "Buffer de apertura en la lista de apertura" -#: flatcamEditors/FlatCAMGrbEditor.py:2613 flatcamGUI/PreferencesUI.py:2608 +#: flatcamEditors/FlatCAMGrbEditor.py:2619 flatcamGUI/PreferencesUI.py:2790 msgid "Buffer distance" msgstr "Dist. de buffer" -#: flatcamEditors/FlatCAMGrbEditor.py:2614 +#: flatcamEditors/FlatCAMGrbEditor.py:2620 msgid "Buffer corner" msgstr "Rincón del búfer" -#: flatcamEditors/FlatCAMGrbEditor.py:2616 +#: flatcamEditors/FlatCAMGrbEditor.py:2622 msgid "" "There are 3 types of corners:\n" " - 'Round': the corner is rounded.\n" @@ -4888,27 +5221,26 @@ msgstr "" "  - 'Biselado:' la esquina es una línea que conecta directamente las " "funciones que se encuentran en la esquina" -#: flatcamEditors/FlatCAMGrbEditor.py:2631 flatcamGUI/FlatCAMGUI.py:978 -#: flatcamGUI/FlatCAMGUI.py:2015 flatcamGUI/FlatCAMGUI.py:2087 -#: flatcamGUI/FlatCAMGUI.py:2130 flatcamGUI/FlatCAMGUI.py:2547 -#: flatcamGUI/PreferencesUI.py:6393 flatcamTools/ToolTransform.py:30 -#: flatcamTools/ToolTransform.py:349 +#: flatcamEditors/FlatCAMGrbEditor.py:2637 flatcamGUI/FlatCAMGUI.py:1046 +#: flatcamGUI/FlatCAMGUI.py:2123 flatcamGUI/FlatCAMGUI.py:2195 +#: flatcamGUI/FlatCAMGUI.py:2238 flatcamGUI/FlatCAMGUI.py:2721 +#: flatcamGUI/PreferencesUI.py:6880 flatcamTools/ToolTransform.py:30 msgid "Buffer" msgstr "Buffer" -#: flatcamEditors/FlatCAMGrbEditor.py:2646 +#: flatcamEditors/FlatCAMGrbEditor.py:2652 msgid "Scale Aperture" msgstr "Apertura de la escala" -#: flatcamEditors/FlatCAMGrbEditor.py:2648 +#: flatcamEditors/FlatCAMGrbEditor.py:2654 msgid "Scale a aperture in the aperture list" msgstr "Escala una abertura en la lista de aperturas" -#: flatcamEditors/FlatCAMGrbEditor.py:2656 flatcamGUI/PreferencesUI.py:2623 +#: flatcamEditors/FlatCAMGrbEditor.py:2662 flatcamGUI/PreferencesUI.py:2805 msgid "Scale factor" msgstr "Factor de escala" -#: flatcamEditors/FlatCAMGrbEditor.py:2658 +#: flatcamEditors/FlatCAMGrbEditor.py:2664 msgid "" "The factor by which to scale the selected aperture.\n" "Values can be between 0.0000 and 999.9999" @@ -4916,19 +5248,19 @@ msgstr "" "El factor por el cual escalar la apertura seleccionada.\n" "Los valores pueden estar entre 0.0000 y 999.9999" -#: flatcamEditors/FlatCAMGrbEditor.py:2686 +#: flatcamEditors/FlatCAMGrbEditor.py:2692 msgid "Mark polygons" msgstr "Marcar polígonos" -#: flatcamEditors/FlatCAMGrbEditor.py:2688 +#: flatcamEditors/FlatCAMGrbEditor.py:2694 msgid "Mark the polygon areas." msgstr "Marca las áreas del polígono." -#: flatcamEditors/FlatCAMGrbEditor.py:2696 +#: flatcamEditors/FlatCAMGrbEditor.py:2702 msgid "Area UPPER threshold" msgstr "Umbral SUPERIOR área" -#: flatcamEditors/FlatCAMGrbEditor.py:2698 +#: flatcamEditors/FlatCAMGrbEditor.py:2704 msgid "" "The threshold value, all areas less than this are marked.\n" "Can have a value between 0.0000 and 9999.9999" @@ -4936,11 +5268,11 @@ msgstr "" "El valor de umbral, todas las áreas menos que esto están marcadas.\n" "Puede tener un valor entre 0.0000 y 9999.9999" -#: flatcamEditors/FlatCAMGrbEditor.py:2705 +#: flatcamEditors/FlatCAMGrbEditor.py:2711 msgid "Area LOWER threshold" msgstr "Umbral inferior de la zona" -#: flatcamEditors/FlatCAMGrbEditor.py:2707 +#: flatcamEditors/FlatCAMGrbEditor.py:2713 msgid "" "The threshold value, all areas more than this are marked.\n" "Can have a value between 0.0000 and 9999.9999" @@ -4948,36 +5280,32 @@ msgstr "" "El valor de umbral, todas las áreas más que esto están marcadas.\n" "Puede tener un valor entre 0.0000 y 9999.9999" -#: flatcamEditors/FlatCAMGrbEditor.py:2721 +#: flatcamEditors/FlatCAMGrbEditor.py:2727 msgid "Mark" msgstr "Marque" -#: flatcamEditors/FlatCAMGrbEditor.py:2723 +#: flatcamEditors/FlatCAMGrbEditor.py:2729 msgid "Mark the polygons that fit within limits." msgstr "Marque los polígonos que se ajustan dentro de los límites." -#: flatcamEditors/FlatCAMGrbEditor.py:2729 +#: flatcamEditors/FlatCAMGrbEditor.py:2735 msgid "Delete all the marked polygons." msgstr "Eliminar todos los polígonos marcados." -#: flatcamEditors/FlatCAMGrbEditor.py:2733 -msgid "Clear" -msgstr "Limpiar" - -#: flatcamEditors/FlatCAMGrbEditor.py:2735 +#: flatcamEditors/FlatCAMGrbEditor.py:2741 msgid "Clear all the markings." msgstr "Borra todas las marcas." -#: flatcamEditors/FlatCAMGrbEditor.py:2755 flatcamGUI/FlatCAMGUI.py:963 -#: flatcamGUI/FlatCAMGUI.py:2015 flatcamGUI/FlatCAMGUI.py:2532 +#: flatcamEditors/FlatCAMGrbEditor.py:2761 flatcamGUI/FlatCAMGUI.py:1031 +#: flatcamGUI/FlatCAMGUI.py:2123 flatcamGUI/FlatCAMGUI.py:2706 msgid "Add Pad Array" msgstr "Agregar matriz de pad" -#: flatcamEditors/FlatCAMGrbEditor.py:2757 +#: flatcamEditors/FlatCAMGrbEditor.py:2763 msgid "Add an array of pads (linear or circular array)" msgstr "Añadir una matriz de pads (lineal o circular)" -#: flatcamEditors/FlatCAMGrbEditor.py:2763 +#: flatcamEditors/FlatCAMGrbEditor.py:2769 msgid "" "Select the type of pads array to create.\n" "It can be Linear X(Y) or Circular" @@ -4985,15 +5313,15 @@ msgstr "" "Seleccione el tipo de matriz de pads para crear.\n" "Puede ser Lineal X (Y) o Circular" -#: flatcamEditors/FlatCAMGrbEditor.py:2774 flatcamGUI/PreferencesUI.py:2511 +#: flatcamEditors/FlatCAMGrbEditor.py:2780 flatcamGUI/PreferencesUI.py:2691 msgid "Nr of pads" msgstr "Nº de almohadillas" -#: flatcamEditors/FlatCAMGrbEditor.py:2776 flatcamGUI/PreferencesUI.py:2513 +#: flatcamEditors/FlatCAMGrbEditor.py:2782 flatcamGUI/PreferencesUI.py:2693 msgid "Specify how many pads to be in the array." msgstr "Especifique cuántos pads estarán en la matriz." -#: flatcamEditors/FlatCAMGrbEditor.py:2825 +#: flatcamEditors/FlatCAMGrbEditor.py:2831 msgid "" "Angle at which the linear array is placed.\n" "The precision is of max 2 decimals.\n" @@ -5005,14 +5333,14 @@ msgstr "" "El valor mínimo es: -359.99 grados.\n" "El valor máximo es: 360.00 grados." -#: flatcamEditors/FlatCAMGrbEditor.py:3307 -#: flatcamEditors/FlatCAMGrbEditor.py:3311 +#: flatcamEditors/FlatCAMGrbEditor.py:3321 +#: flatcamEditors/FlatCAMGrbEditor.py:3325 msgid "Aperture code value is missing or wrong format. Add it and retry." msgstr "" "Falta el valor del código de apertura o el formato es incorrecto. Agrégalo y " "vuelve a intentarlo." -#: flatcamEditors/FlatCAMGrbEditor.py:3347 +#: flatcamEditors/FlatCAMGrbEditor.py:3361 msgid "" "Aperture dimensions value is missing or wrong format. Add it in format " "(width, height) and retry." @@ -5020,186 +5348,186 @@ msgstr "" "Falta el valor de las dimensiones de la abertura o el formato es incorrecto. " "Agréguelo en formato (ancho, alto) y vuelva a intentarlo." -#: flatcamEditors/FlatCAMGrbEditor.py:3360 +#: flatcamEditors/FlatCAMGrbEditor.py:3374 msgid "Aperture size value is missing or wrong format. Add it and retry." msgstr "" "Falta el valor del tamaño de la apertura o el formato es incorrecto. " "Agrégalo y vuelve a intentarlo." -#: flatcamEditors/FlatCAMGrbEditor.py:3371 +#: flatcamEditors/FlatCAMGrbEditor.py:3385 msgid "Aperture already in the aperture table." msgstr "Apertura ya en la mesa de apertura." -#: flatcamEditors/FlatCAMGrbEditor.py:3379 +#: flatcamEditors/FlatCAMGrbEditor.py:3393 msgid "Added new aperture with code" msgstr "Agregada nueva apertura con código" -#: flatcamEditors/FlatCAMGrbEditor.py:3408 +#: flatcamEditors/FlatCAMGrbEditor.py:3422 msgid " Select an aperture in Aperture Table" msgstr " Seleccione una abertura en la Mesa de Apertura" -#: flatcamEditors/FlatCAMGrbEditor.py:3416 +#: flatcamEditors/FlatCAMGrbEditor.py:3430 msgid "Select an aperture in Aperture Table -->" msgstr "Seleccione una abertura en la Tabla de Apertura ->" -#: flatcamEditors/FlatCAMGrbEditor.py:3439 +#: flatcamEditors/FlatCAMGrbEditor.py:3453 msgid "Deleted aperture with code" msgstr "Apertura eliminada con código" -#: flatcamEditors/FlatCAMGrbEditor.py:3924 +#: flatcamEditors/FlatCAMGrbEditor.py:3950 msgid "Loading Gerber into Editor" msgstr "Cargando Gerber en el Editor" -#: flatcamEditors/FlatCAMGrbEditor.py:4034 +#: flatcamEditors/FlatCAMGrbEditor.py:4078 msgid "Setting up the UI" msgstr "Configurar la IU" -#: flatcamEditors/FlatCAMGrbEditor.py:4035 +#: flatcamEditors/FlatCAMGrbEditor.py:4079 msgid "Adding geometry finished. Preparing the GUI" msgstr "Adición de geometría terminada. Preparando la GUI" -#: flatcamEditors/FlatCAMGrbEditor.py:4044 +#: flatcamEditors/FlatCAMGrbEditor.py:4088 msgid "Finished loading the Gerber object into the editor." msgstr "Terminó de cargar el objeto Gerber en el editor." -#: flatcamEditors/FlatCAMGrbEditor.py:4184 +#: flatcamEditors/FlatCAMGrbEditor.py:4228 msgid "" "There are no Aperture definitions in the file. Aborting Gerber creation." msgstr "" "No hay definiciones de Aperture en el archivo. Abortando la creación de " "Gerber." -#: flatcamEditors/FlatCAMGrbEditor.py:4194 +#: flatcamEditors/FlatCAMGrbEditor.py:4238 msgid "Creating Gerber." msgstr "Creación de Gerber." -#: flatcamEditors/FlatCAMGrbEditor.py:4203 +#: flatcamEditors/FlatCAMGrbEditor.py:4247 msgid "Done. Gerber editing finished." msgstr "La edición de gerber terminó." -#: flatcamEditors/FlatCAMGrbEditor.py:4222 +#: flatcamEditors/FlatCAMGrbEditor.py:4265 msgid "Cancelled. No aperture is selected" msgstr "Cancelado. No se selecciona ninguna apertura" -#: flatcamEditors/FlatCAMGrbEditor.py:4782 +#: flatcamEditors/FlatCAMGrbEditor.py:4826 msgid "Failed. No aperture geometry is selected." msgstr "Ha fallado. No se selecciona ninguna geometría de apertura." -#: flatcamEditors/FlatCAMGrbEditor.py:4791 -#: flatcamEditors/FlatCAMGrbEditor.py:5062 +#: flatcamEditors/FlatCAMGrbEditor.py:4835 +#: flatcamEditors/FlatCAMGrbEditor.py:5106 msgid "Done. Apertures geometry deleted." msgstr "Hecho. Geometría de las aberturas eliminadas." -#: flatcamEditors/FlatCAMGrbEditor.py:4934 +#: flatcamEditors/FlatCAMGrbEditor.py:4978 msgid "No aperture to buffer. Select at least one aperture and try again." msgstr "" "No hay apertura para amortiguar. Seleccione al menos una abertura e intente " "de nuevo." -#: flatcamEditors/FlatCAMGrbEditor.py:4946 +#: flatcamEditors/FlatCAMGrbEditor.py:4990 msgid "Failed." msgstr "Ha fallado." -#: flatcamEditors/FlatCAMGrbEditor.py:4965 +#: flatcamEditors/FlatCAMGrbEditor.py:5009 msgid "Scale factor value is missing or wrong format. Add it and retry." msgstr "" "Falta el valor del factor de escala o el formato es incorrecto. Agrégalo y " "vuelve a intentarlo." -#: flatcamEditors/FlatCAMGrbEditor.py:4997 +#: flatcamEditors/FlatCAMGrbEditor.py:5041 msgid "No aperture to scale. Select at least one aperture and try again." msgstr "" "Sin apertura a escala. Seleccione al menos una abertura e intente de nuevo." -#: flatcamEditors/FlatCAMGrbEditor.py:5013 +#: flatcamEditors/FlatCAMGrbEditor.py:5057 msgid "Done. Scale Tool completed." msgstr "Hecho. Herramienta de escala completada." -#: flatcamEditors/FlatCAMGrbEditor.py:5051 +#: flatcamEditors/FlatCAMGrbEditor.py:5095 msgid "Polygons marked." msgstr "Polígonos marcados." -#: flatcamEditors/FlatCAMGrbEditor.py:5054 +#: flatcamEditors/FlatCAMGrbEditor.py:5098 msgid "No polygons were marked. None fit within the limits." msgstr "No se marcaron polígonos. Ninguno encaja dentro de los límites." -#: flatcamEditors/FlatCAMGrbEditor.py:5783 +#: flatcamEditors/FlatCAMGrbEditor.py:5822 msgid "Rotation action was not executed." msgstr "La acción de Rotación no se ejecutó." -#: flatcamEditors/FlatCAMGrbEditor.py:5919 +#: flatcamEditors/FlatCAMGrbEditor.py:5950 msgid "Skew action was not executed." msgstr "La acción Sesgada no se ejecutó." -#: flatcamEditors/FlatCAMGrbEditor.py:5986 +#: flatcamEditors/FlatCAMGrbEditor.py:6015 msgid "Scale action was not executed." msgstr "La acción de Escala no se ejecutó." -#: flatcamEditors/FlatCAMGrbEditor.py:6029 +#: flatcamEditors/FlatCAMGrbEditor.py:6058 msgid "Offset action was not executed." msgstr "La acción de Desplazamiento no se ejecutó." -#: flatcamEditors/FlatCAMGrbEditor.py:6079 +#: flatcamEditors/FlatCAMGrbEditor.py:6108 msgid "Geometry shape offset Y cancelled" msgstr "Forma de geometría offset Y cancelada" -#: flatcamEditors/FlatCAMGrbEditor.py:6094 +#: flatcamEditors/FlatCAMGrbEditor.py:6123 msgid "Geometry shape skew X cancelled" msgstr "Forma geométrica sesgada X cancelada" -#: flatcamEditors/FlatCAMGrbEditor.py:6109 +#: flatcamEditors/FlatCAMGrbEditor.py:6138 msgid "Geometry shape skew Y cancelled" msgstr "Forma geométrica sesgada Y cancelada" -#: flatcamEditors/FlatCAMTextEditor.py:72 +#: flatcamEditors/FlatCAMTextEditor.py:74 msgid "Print Preview" msgstr "Vista previa de impres" -#: flatcamEditors/FlatCAMTextEditor.py:73 +#: flatcamEditors/FlatCAMTextEditor.py:75 msgid "Open a OS standard Preview Print window." msgstr "" "Abra una ventana de Vista previa de impresión estándar del sistema operativo." -#: flatcamEditors/FlatCAMTextEditor.py:76 +#: flatcamEditors/FlatCAMTextEditor.py:78 msgid "Print Code" msgstr "Imprimir código" -#: flatcamEditors/FlatCAMTextEditor.py:77 +#: flatcamEditors/FlatCAMTextEditor.py:79 msgid "Open a OS standard Print window." msgstr "Abra una ventana de impresión estándar del sistema operativo." -#: flatcamEditors/FlatCAMTextEditor.py:79 +#: flatcamEditors/FlatCAMTextEditor.py:81 msgid "Find in Code" msgstr "Encontr. en codigo" -#: flatcamEditors/FlatCAMTextEditor.py:80 +#: flatcamEditors/FlatCAMTextEditor.py:82 msgid "Will search and highlight in yellow the string in the Find box." msgstr "Buscará y resaltará en amarillo la cadena en el Encuentra caja." -#: flatcamEditors/FlatCAMTextEditor.py:84 +#: flatcamEditors/FlatCAMTextEditor.py:86 msgid "Find box. Enter here the strings to be searched in the text." msgstr "Encuentra caja. Ingrese aquí las cadenas a buscar en el texto." -#: flatcamEditors/FlatCAMTextEditor.py:86 +#: flatcamEditors/FlatCAMTextEditor.py:88 msgid "Replace With" msgstr "Reemplazar con" -#: flatcamEditors/FlatCAMTextEditor.py:87 +#: flatcamEditors/FlatCAMTextEditor.py:89 msgid "" "Will replace the string from the Find box with the one in the Replace box." msgstr "Reemplazará la cadena del cuadro Buscar con la del cuadro Reemplazar." -#: flatcamEditors/FlatCAMTextEditor.py:91 +#: flatcamEditors/FlatCAMTextEditor.py:93 msgid "String to replace the one in the Find box throughout the text." msgstr "Cadena para reemplazar la del cuadro Buscar en todo el texto." -#: flatcamEditors/FlatCAMTextEditor.py:93 flatcamGUI/ObjectUI.py:482 -#: flatcamGUI/ObjectUI.py:1809 flatcamGUI/PreferencesUI.py:2070 -#: flatcamGUI/PreferencesUI.py:4419 flatcamGUI/PreferencesUI.py:5647 +#: flatcamEditors/FlatCAMTextEditor.py:95 flatcamGUI/ObjectUI.py:485 +#: flatcamGUI/ObjectUI.py:2137 flatcamGUI/PreferencesUI.py:2250 +#: flatcamGUI/PreferencesUI.py:4712 msgid "All" msgstr "Todos" -#: flatcamEditors/FlatCAMTextEditor.py:94 +#: flatcamEditors/FlatCAMTextEditor.py:96 msgid "" "When checked it will replace all instances in the 'Find' box\n" "with the text in the 'Replace' box.." @@ -5207,162 +5535,171 @@ msgstr "" "Cuando está marcado, reemplazará todas las instancias en el cuadro 'Buscar'\n" "con el texto en el cuadro 'Reemplazar' .." -#: flatcamEditors/FlatCAMTextEditor.py:97 +#: flatcamEditors/FlatCAMTextEditor.py:99 msgid "Copy All" msgstr "Cópialo todo" -#: flatcamEditors/FlatCAMTextEditor.py:98 +#: flatcamEditors/FlatCAMTextEditor.py:100 msgid "Will copy all the text in the Code Editor to the clipboard." msgstr "Copiará todo el texto en el Editor de Código al portapapeles." -#: flatcamEditors/FlatCAMTextEditor.py:101 +#: flatcamEditors/FlatCAMTextEditor.py:103 msgid "Open Code" msgstr "Código abierto" -#: flatcamEditors/FlatCAMTextEditor.py:102 +#: flatcamEditors/FlatCAMTextEditor.py:104 msgid "Will open a text file in the editor." msgstr "Se abrirá un archivo de texto en el editor." -#: flatcamEditors/FlatCAMTextEditor.py:104 +#: flatcamEditors/FlatCAMTextEditor.py:106 msgid "Save Code" msgstr "Guardar código" -#: flatcamEditors/FlatCAMTextEditor.py:105 +#: flatcamEditors/FlatCAMTextEditor.py:107 msgid "Will save the text in the editor into a file." msgstr "Guardará el texto en el editor en un archivo." -#: flatcamEditors/FlatCAMTextEditor.py:107 +#: flatcamEditors/FlatCAMTextEditor.py:109 msgid "Run Code" msgstr "Ejecutar código" -#: flatcamEditors/FlatCAMTextEditor.py:108 +#: flatcamEditors/FlatCAMTextEditor.py:110 msgid "Will run the TCL commands found in the text file, one by one." msgstr "" "Ejecutará los comandos TCL encontrados en el archivo de texto, uno por uno." -#: flatcamEditors/FlatCAMTextEditor.py:182 +#: flatcamEditors/FlatCAMTextEditor.py:184 msgid "Open file" msgstr "Abrir documento" -#: flatcamEditors/FlatCAMTextEditor.py:213 -#: flatcamEditors/FlatCAMTextEditor.py:218 +#: flatcamEditors/FlatCAMTextEditor.py:215 +#: flatcamEditors/FlatCAMTextEditor.py:220 msgid "Export Code ..." msgstr "Exportar el código ..." -#: flatcamEditors/FlatCAMTextEditor.py:221 -msgid "Export Code cancelled." -msgstr "Exportación de Código cancelada." - -#: flatcamEditors/FlatCAMTextEditor.py:332 +#: flatcamEditors/FlatCAMTextEditor.py:334 msgid "Code Editor content copied to clipboard ..." msgstr "Contenido del editor de código copiado al portapapeles ..." -#: flatcamGUI/FlatCAMGUI.py:52 flatcamGUI/FlatCAMGUI.py:54 -#: flatcamGUI/FlatCAMGUI.py:2040 +#: flatcamGUI/FlatCAMGUI.py:66 flatcamGUI/FlatCAMGUI.py:68 +#: flatcamGUI/FlatCAMGUI.py:2148 msgid "Toggle Panel" msgstr "Panel de palanca" -#: flatcamGUI/FlatCAMGUI.py:64 +#: flatcamGUI/FlatCAMGUI.py:78 msgid "File" msgstr "Archivo" -#: flatcamGUI/FlatCAMGUI.py:69 +#: flatcamGUI/FlatCAMGUI.py:83 msgid "&New Project ...\tCtrl+N" msgstr "&Nuevo proyecto ...\tCtrl+N" -#: flatcamGUI/FlatCAMGUI.py:71 +#: flatcamGUI/FlatCAMGUI.py:85 msgid "Will create a new, blank project" msgstr "Creará un nuevo proyecto en blanco" -#: flatcamGUI/FlatCAMGUI.py:76 +#: flatcamGUI/FlatCAMGUI.py:90 msgid "&New" msgstr "&Nuevo" -#: flatcamGUI/FlatCAMGUI.py:80 +#: flatcamGUI/FlatCAMGUI.py:94 msgid "Geometry\tN" msgstr "Geometría\tN" -#: flatcamGUI/FlatCAMGUI.py:82 +#: flatcamGUI/FlatCAMGUI.py:96 msgid "Will create a new, empty Geometry Object." msgstr "Creará un nuevo objeto vacío de geometría." -#: flatcamGUI/FlatCAMGUI.py:84 +#: flatcamGUI/FlatCAMGUI.py:99 msgid "Gerber\tB" msgstr "Gerber\tB" -#: flatcamGUI/FlatCAMGUI.py:86 +#: flatcamGUI/FlatCAMGUI.py:101 msgid "Will create a new, empty Gerber Object." msgstr "Creará un nuevo objeto vacío de Gerber." -#: flatcamGUI/FlatCAMGUI.py:88 +#: flatcamGUI/FlatCAMGUI.py:104 msgid "Excellon\tL" msgstr "Excellon\tL" -#: flatcamGUI/FlatCAMGUI.py:90 +#: flatcamGUI/FlatCAMGUI.py:106 msgid "Will create a new, empty Excellon Object." msgstr "Creará un objeto Excellon nuevo y vacío." -#: flatcamGUI/FlatCAMGUI.py:94 +#: flatcamGUI/FlatCAMGUI.py:111 msgid "Document\tD" msgstr "Documento\tD" -#: flatcamGUI/FlatCAMGUI.py:96 +#: flatcamGUI/FlatCAMGUI.py:113 msgid "Will create a new, empty Document Object." msgstr "Creará un nuevo objeto de Documento vacío." -#: flatcamGUI/FlatCAMGUI.py:99 flatcamGUI/FlatCAMGUI.py:4111 +#: flatcamGUI/FlatCAMGUI.py:117 flatcamGUI/FlatCAMGUI.py:4327 #: flatcamTools/ToolPcbWizard.py:62 flatcamTools/ToolPcbWizard.py:69 msgid "Open" msgstr "Abierto" -#: flatcamGUI/FlatCAMGUI.py:103 +#: flatcamGUI/FlatCAMGUI.py:122 msgid "Open &Project ..." msgstr "Abierto &Project ..." -#: flatcamGUI/FlatCAMGUI.py:109 flatcamGUI/FlatCAMGUI.py:4121 +#: flatcamGUI/FlatCAMGUI.py:128 flatcamGUI/FlatCAMGUI.py:4337 msgid "Open &Gerber ...\tCtrl+G" msgstr "Abierto &Gerber ...\tCtrl+G" -#: flatcamGUI/FlatCAMGUI.py:114 flatcamGUI/FlatCAMGUI.py:4126 +#: flatcamGUI/FlatCAMGUI.py:133 flatcamGUI/FlatCAMGUI.py:4342 msgid "Open &Excellon ...\tCtrl+E" msgstr "Abierto &Excellon ...\tCtrl+E" -#: flatcamGUI/FlatCAMGUI.py:118 flatcamGUI/FlatCAMGUI.py:4131 +#: flatcamGUI/FlatCAMGUI.py:138 flatcamGUI/FlatCAMGUI.py:4347 msgid "Open G-&Code ..." msgstr "Abierto G-&Code ..." -#: flatcamGUI/FlatCAMGUI.py:124 +#: flatcamGUI/FlatCAMGUI.py:145 msgid "Open Config ..." msgstr "Abierto Config ..." -#: flatcamGUI/FlatCAMGUI.py:128 +#: flatcamGUI/FlatCAMGUI.py:150 msgid "Recent projects" msgstr "Proyectos recientes" -#: flatcamGUI/FlatCAMGUI.py:129 +#: flatcamGUI/FlatCAMGUI.py:152 msgid "Recent files" msgstr "Archivos recientes" -#: flatcamGUI/FlatCAMGUI.py:135 +#: flatcamGUI/FlatCAMGUI.py:155 flatcamGUI/FlatCAMGUI.py:738 +#: flatcamGUI/FlatCAMGUI.py:1324 +msgid "Save" +msgstr "Salvar" + +#: flatcamGUI/FlatCAMGUI.py:159 +msgid "&Save Project ...\tCtrl+S" +msgstr "Guardar proyecto...\tCtrl+S" + +#: flatcamGUI/FlatCAMGUI.py:164 +msgid "Save Project &As ...\tCtrl+Shift+S" +msgstr "Guardar proyecto como...\tCtrl+Shift+S" + +#: flatcamGUI/FlatCAMGUI.py:179 msgid "Scripting" msgstr "Scripting" -#: flatcamGUI/FlatCAMGUI.py:138 flatcamGUI/FlatCAMGUI.py:829 -#: flatcamGUI/FlatCAMGUI.py:2409 +#: flatcamGUI/FlatCAMGUI.py:183 flatcamGUI/FlatCAMGUI.py:888 +#: flatcamGUI/FlatCAMGUI.py:2567 msgid "New Script ..." msgstr "Nuevo Script ..." -#: flatcamGUI/FlatCAMGUI.py:139 flatcamGUI/FlatCAMGUI.py:831 -#: flatcamGUI/FlatCAMGUI.py:2411 +#: flatcamGUI/FlatCAMGUI.py:185 flatcamGUI/FlatCAMGUI.py:890 +#: flatcamGUI/FlatCAMGUI.py:2569 msgid "Open Script ..." msgstr "Abrir Script ..." -#: flatcamGUI/FlatCAMGUI.py:141 flatcamGUI/FlatCAMGUI.py:833 -#: flatcamGUI/FlatCAMGUI.py:2413 flatcamGUI/FlatCAMGUI.py:4100 +#: flatcamGUI/FlatCAMGUI.py:187 flatcamGUI/FlatCAMGUI.py:892 +#: flatcamGUI/FlatCAMGUI.py:2571 flatcamGUI/FlatCAMGUI.py:4316 msgid "Run Script ..." msgstr "Ejecutar Script ..." -#: flatcamGUI/FlatCAMGUI.py:143 flatcamGUI/FlatCAMGUI.py:4102 +#: flatcamGUI/FlatCAMGUI.py:189 flatcamGUI/FlatCAMGUI.py:4318 msgid "" "Will run the opened Tcl Script thus\n" "enabling the automation of certain\n" @@ -5372,47 +5709,47 @@ msgstr "" "permitiendo la automatización de ciertos\n" "Funciones de FlatCAM." -#: flatcamGUI/FlatCAMGUI.py:156 +#: flatcamGUI/FlatCAMGUI.py:203 msgid "Import" msgstr "Importar" -#: flatcamGUI/FlatCAMGUI.py:158 +#: flatcamGUI/FlatCAMGUI.py:205 msgid "&SVG as Geometry Object ..." msgstr "&SVG como objeto de geometría ..." -#: flatcamGUI/FlatCAMGUI.py:161 +#: flatcamGUI/FlatCAMGUI.py:208 msgid "&SVG as Gerber Object ..." msgstr "&SVG como objeto de Gerber ..." -#: flatcamGUI/FlatCAMGUI.py:166 +#: flatcamGUI/FlatCAMGUI.py:213 msgid "&DXF as Geometry Object ..." msgstr "&DXF como objeto de geometría ..." -#: flatcamGUI/FlatCAMGUI.py:169 +#: flatcamGUI/FlatCAMGUI.py:216 msgid "&DXF as Gerber Object ..." msgstr "&DXF como objeto de Gerber ..." -#: flatcamGUI/FlatCAMGUI.py:173 +#: flatcamGUI/FlatCAMGUI.py:220 msgid "HPGL2 as Geometry Object ..." msgstr "HPGL2 como objeto de geometría ..." -#: flatcamGUI/FlatCAMGUI.py:178 +#: flatcamGUI/FlatCAMGUI.py:226 msgid "Export" msgstr "Exportar" -#: flatcamGUI/FlatCAMGUI.py:181 +#: flatcamGUI/FlatCAMGUI.py:230 msgid "Export &SVG ..." msgstr "Exportar &SVG ..." -#: flatcamGUI/FlatCAMGUI.py:184 +#: flatcamGUI/FlatCAMGUI.py:234 msgid "Export DXF ..." msgstr "Exportar DXF ..." -#: flatcamGUI/FlatCAMGUI.py:189 +#: flatcamGUI/FlatCAMGUI.py:240 msgid "Export &PNG ..." msgstr "Exportar &PNG ..." -#: flatcamGUI/FlatCAMGUI.py:191 +#: flatcamGUI/FlatCAMGUI.py:242 msgid "" "Will export an image in PNG format,\n" "the saved image will contain the visual \n" @@ -5422,11 +5759,11 @@ msgstr "" "La imagen guardada contendrá lo visual.\n" "Información actualmente en FlatCAM Plot Area." -#: flatcamGUI/FlatCAMGUI.py:200 +#: flatcamGUI/FlatCAMGUI.py:251 msgid "Export &Excellon ..." msgstr "Exportación y Excellon ..." -#: flatcamGUI/FlatCAMGUI.py:202 +#: flatcamGUI/FlatCAMGUI.py:253 msgid "" "Will export an Excellon Object as Excellon file,\n" "the coordinates format, the file units and zeros\n" @@ -5436,11 +5773,11 @@ msgstr "" "El formato de las coordenadas, las unidades de archivo y los ceros.\n" "se configuran en Preferencias -> Exportación de Excellon." -#: flatcamGUI/FlatCAMGUI.py:209 +#: flatcamGUI/FlatCAMGUI.py:260 msgid "Export &Gerber ..." msgstr "Exportar &Gerber ..." -#: flatcamGUI/FlatCAMGUI.py:211 +#: flatcamGUI/FlatCAMGUI.py:262 msgid "" "Will export an Gerber Object as Gerber file,\n" "the coordinates format, the file units and zeros\n" @@ -5450,65 +5787,48 @@ msgstr "" "El formato de las coordenadas, las unidades de archivo y los ceros.\n" "se establecen en Preferencias -> Exportar Gerber." -#: flatcamGUI/FlatCAMGUI.py:229 +#: flatcamGUI/FlatCAMGUI.py:272 msgid "Backup" msgstr "Apoyo" -#: flatcamGUI/FlatCAMGUI.py:233 +#: flatcamGUI/FlatCAMGUI.py:277 msgid "Import Preferences from file ..." msgstr "Importar preferencias del archivo ..." -#: flatcamGUI/FlatCAMGUI.py:238 +#: flatcamGUI/FlatCAMGUI.py:283 msgid "Export Preferences to file ..." msgstr "Exportar preferencias a un archivo ..." -#: flatcamGUI/FlatCAMGUI.py:244 flatcamGUI/FlatCAMGUI.py:1614 +#: flatcamGUI/FlatCAMGUI.py:297 flatcamGUI/FlatCAMGUI.py:1715 msgid "Print (PDF)" msgstr "Imprimir (PDF)" -#: flatcamGUI/FlatCAMGUI.py:247 flatcamGUI/FlatCAMGUI.py:682 -#: flatcamGUI/FlatCAMGUI.py:1252 -msgid "Save" -msgstr "Salvar" - -#: flatcamGUI/FlatCAMGUI.py:251 -msgid "&Save Project ..." -msgstr "Salvar proyecto ..." - -#: flatcamGUI/FlatCAMGUI.py:256 -msgid "Save Project &As ...\tCtrl+S" -msgstr "Guardar proyecto como...\tCtrl+S" - -#: flatcamGUI/FlatCAMGUI.py:261 -msgid "Save Project C&opy ..." -msgstr "Guardar copia del proyecto ..." - -#: flatcamGUI/FlatCAMGUI.py:271 +#: flatcamGUI/FlatCAMGUI.py:305 msgid "E&xit" msgstr "Salida" -#: flatcamGUI/FlatCAMGUI.py:279 flatcamGUI/FlatCAMGUI.py:676 -#: flatcamGUI/FlatCAMGUI.py:2163 +#: flatcamGUI/FlatCAMGUI.py:313 flatcamGUI/FlatCAMGUI.py:732 +#: flatcamGUI/FlatCAMGUI.py:2271 msgid "Edit" msgstr "Editar" -#: flatcamGUI/FlatCAMGUI.py:283 +#: flatcamGUI/FlatCAMGUI.py:317 msgid "Edit Object\tE" msgstr "Editar objeto\tE" -#: flatcamGUI/FlatCAMGUI.py:285 +#: flatcamGUI/FlatCAMGUI.py:319 msgid "Close Editor\tCtrl+S" msgstr "Cerrar Editor\tCtrl+S" -#: flatcamGUI/FlatCAMGUI.py:294 +#: flatcamGUI/FlatCAMGUI.py:328 msgid "Conversion" msgstr "Conversión" -#: flatcamGUI/FlatCAMGUI.py:296 +#: flatcamGUI/FlatCAMGUI.py:330 msgid "&Join Geo/Gerber/Exc -> Geo" msgstr "Unirse Geo/Gerber/Exc -> Geo" -#: flatcamGUI/FlatCAMGUI.py:298 +#: flatcamGUI/FlatCAMGUI.py:332 msgid "" "Merge a selection of objects, which can be of type:\n" "- Gerber\n" @@ -5522,30 +5842,30 @@ msgstr "" "- Geometría\n" "en un nuevo objeto de geometría combo." -#: flatcamGUI/FlatCAMGUI.py:305 +#: flatcamGUI/FlatCAMGUI.py:339 msgid "Join Excellon(s) -> Excellon" msgstr "Únete a Excellon (s) -> Excellon" -#: flatcamGUI/FlatCAMGUI.py:307 +#: flatcamGUI/FlatCAMGUI.py:341 msgid "Merge a selection of Excellon objects into a new combo Excellon object." msgstr "" "Combine una selección de objetos de Excellon en un nuevo objeto de Excellon " "combinado." -#: flatcamGUI/FlatCAMGUI.py:310 +#: flatcamGUI/FlatCAMGUI.py:344 msgid "Join Gerber(s) -> Gerber" msgstr "Únete a Gerber (s) -> Gerber" -#: flatcamGUI/FlatCAMGUI.py:312 +#: flatcamGUI/FlatCAMGUI.py:346 msgid "Merge a selection of Gerber objects into a new combo Gerber object." msgstr "" "Combine una selección de objetos Gerber en un nuevo objeto combo Gerber." -#: flatcamGUI/FlatCAMGUI.py:317 +#: flatcamGUI/FlatCAMGUI.py:351 msgid "Convert Single to MultiGeo" msgstr "Convertir solo geo a multi geo" -#: flatcamGUI/FlatCAMGUI.py:319 +#: flatcamGUI/FlatCAMGUI.py:353 msgid "" "Will convert a Geometry object from single_geometry type\n" "to a multi_geometry type." @@ -5553,11 +5873,11 @@ msgstr "" "Convertirá un objeto de geometría de un tipo de geometría única\n" "a un tipo de geometría múltiple." -#: flatcamGUI/FlatCAMGUI.py:323 +#: flatcamGUI/FlatCAMGUI.py:357 msgid "Convert Multi to SingleGeo" msgstr "Convertir multi a solo Geo" -#: flatcamGUI/FlatCAMGUI.py:325 +#: flatcamGUI/FlatCAMGUI.py:359 msgid "" "Will convert a Geometry object from multi_geometry type\n" "to a single_geometry type." @@ -5565,734 +5885,744 @@ msgstr "" "Convertirá un objeto de geometría de tipo de geometría múltiple\n" "a un solo tipo de geometría." -#: flatcamGUI/FlatCAMGUI.py:332 +#: flatcamGUI/FlatCAMGUI.py:366 msgid "Convert Any to Geo" msgstr "Convertir cualquiera a Geo" -#: flatcamGUI/FlatCAMGUI.py:335 +#: flatcamGUI/FlatCAMGUI.py:369 msgid "Convert Any to Gerber" msgstr "Convertir cualquiera a Gerber" -#: flatcamGUI/FlatCAMGUI.py:341 +#: flatcamGUI/FlatCAMGUI.py:375 msgid "&Copy\tCtrl+C" msgstr "Dupdo\tCtrl+C" -#: flatcamGUI/FlatCAMGUI.py:346 +#: flatcamGUI/FlatCAMGUI.py:380 msgid "&Delete\tDEL" msgstr "Borrar\tDEL" -#: flatcamGUI/FlatCAMGUI.py:351 +#: flatcamGUI/FlatCAMGUI.py:385 msgid "Se&t Origin\tO" msgstr "Establecer origen\tO" -#: flatcamGUI/FlatCAMGUI.py:353 +#: flatcamGUI/FlatCAMGUI.py:387 +msgid "Move to Origin\tShift+O" +msgstr "Mover al origen\tShift+O" + +#: flatcamGUI/FlatCAMGUI.py:390 msgid "Jump to Location\tJ" msgstr "Ir a la ubicación\tJ" -#: flatcamGUI/FlatCAMGUI.py:358 +#: flatcamGUI/FlatCAMGUI.py:392 +msgid "Locate in Object\tShift+J" +msgstr "Localizar en Objeto\tShift+J" + +#: flatcamGUI/FlatCAMGUI.py:397 msgid "Toggle Units\tQ" msgstr "Unidades de palanca\tQ" -#: flatcamGUI/FlatCAMGUI.py:360 +#: flatcamGUI/FlatCAMGUI.py:399 msgid "&Select All\tCtrl+A" msgstr "Seleccionar todo\tCtrl+A" -#: flatcamGUI/FlatCAMGUI.py:365 +#: flatcamGUI/FlatCAMGUI.py:404 msgid "&Preferences\tShift+P" msgstr "Preferencias\tShift+P" -#: flatcamGUI/FlatCAMGUI.py:371 flatcamTools/ToolProperties.py:153 +#: flatcamGUI/FlatCAMGUI.py:410 flatcamTools/ToolProperties.py:155 msgid "Options" msgstr "Opciones" -#: flatcamGUI/FlatCAMGUI.py:373 +#: flatcamGUI/FlatCAMGUI.py:412 msgid "&Rotate Selection\tShift+(R)" msgstr "Rotar selección\tShift+(R)" -#: flatcamGUI/FlatCAMGUI.py:378 +#: flatcamGUI/FlatCAMGUI.py:417 msgid "&Skew on X axis\tShift+X" msgstr "Sesgo en el eje X\tShift+X" -#: flatcamGUI/FlatCAMGUI.py:380 +#: flatcamGUI/FlatCAMGUI.py:419 msgid "S&kew on Y axis\tShift+Y" msgstr "Sesgo en el eje Y\tShift+Y" -#: flatcamGUI/FlatCAMGUI.py:385 +#: flatcamGUI/FlatCAMGUI.py:424 msgid "Flip on &X axis\tX" msgstr "Voltear en el eje X\tX" -#: flatcamGUI/FlatCAMGUI.py:387 +#: flatcamGUI/FlatCAMGUI.py:426 msgid "Flip on &Y axis\tY" msgstr "Voltear en el ejeY\tY" -#: flatcamGUI/FlatCAMGUI.py:392 +#: flatcamGUI/FlatCAMGUI.py:431 msgid "View source\tAlt+S" msgstr "Ver fuente\tAlt+S" -#: flatcamGUI/FlatCAMGUI.py:394 +#: flatcamGUI/FlatCAMGUI.py:433 msgid "Tools DataBase\tCtrl+D" msgstr "DB de Herramientas\tCtrl+D" -#: flatcamGUI/FlatCAMGUI.py:401 flatcamGUI/FlatCAMGUI.py:2060 +#: flatcamGUI/FlatCAMGUI.py:440 flatcamGUI/FlatCAMGUI.py:2168 msgid "View" msgstr "Ver" -#: flatcamGUI/FlatCAMGUI.py:403 +#: flatcamGUI/FlatCAMGUI.py:442 msgid "Enable all plots\tAlt+1" msgstr "Habilitar todas las parcelas\tAlt+1" -#: flatcamGUI/FlatCAMGUI.py:405 +#: flatcamGUI/FlatCAMGUI.py:444 msgid "Disable all plots\tAlt+2" msgstr "Deshabilitar todas las parcelas\tAlt+2" -#: flatcamGUI/FlatCAMGUI.py:407 +#: flatcamGUI/FlatCAMGUI.py:446 msgid "Disable non-selected\tAlt+3" msgstr "Deshabilitar no seleccionado\tAlt+3" -#: flatcamGUI/FlatCAMGUI.py:411 +#: flatcamGUI/FlatCAMGUI.py:450 msgid "&Zoom Fit\tV" msgstr "Ajuste de zoom\tV" -#: flatcamGUI/FlatCAMGUI.py:413 +#: flatcamGUI/FlatCAMGUI.py:452 msgid "&Zoom In\t=" msgstr "Acercarse\t=" -#: flatcamGUI/FlatCAMGUI.py:415 +#: flatcamGUI/FlatCAMGUI.py:454 msgid "&Zoom Out\t-" msgstr "Disminuir el zoom\t-" -#: flatcamGUI/FlatCAMGUI.py:420 +#: flatcamGUI/FlatCAMGUI.py:459 msgid "Redraw All\tF5" msgstr "Redibujar todo\tF5" -#: flatcamGUI/FlatCAMGUI.py:424 +#: flatcamGUI/FlatCAMGUI.py:463 msgid "Toggle Code Editor\tShift+E" msgstr "Alternar Editor de Código\tShift+E" -#: flatcamGUI/FlatCAMGUI.py:427 +#: flatcamGUI/FlatCAMGUI.py:466 msgid "&Toggle FullScreen\tAlt+F10" msgstr "Alternar pantalla completa\tAlt+F10" -#: flatcamGUI/FlatCAMGUI.py:429 +#: flatcamGUI/FlatCAMGUI.py:468 msgid "&Toggle Plot Area\tCtrl+F10" msgstr "Alternar área de la parcela\tCtrl+F10" -#: flatcamGUI/FlatCAMGUI.py:431 +#: flatcamGUI/FlatCAMGUI.py:470 msgid "&Toggle Project/Sel/Tool\t`" msgstr "Palanca Proyecto / Sel / Tool\t`" -#: flatcamGUI/FlatCAMGUI.py:435 +#: flatcamGUI/FlatCAMGUI.py:474 msgid "&Toggle Grid Snap\tG" msgstr "Activar cuadrícula\tG" -#: flatcamGUI/FlatCAMGUI.py:437 +#: flatcamGUI/FlatCAMGUI.py:476 msgid "&Toggle Grid Lines\tAlt+G" msgstr "Alternar Líneas de Cuadrícula\tAlt+G" -#: flatcamGUI/FlatCAMGUI.py:439 +#: flatcamGUI/FlatCAMGUI.py:478 msgid "&Toggle Axis\tShift+G" msgstr "Eje de palanca\tShift+G" -#: flatcamGUI/FlatCAMGUI.py:441 +#: flatcamGUI/FlatCAMGUI.py:480 msgid "Toggle Workspace\tShift+W" msgstr "Alternar espacio de trabajo\tShift+W" -#: flatcamGUI/FlatCAMGUI.py:446 +#: flatcamGUI/FlatCAMGUI.py:485 msgid "Objects" msgstr "Objetos" -#: flatcamGUI/FlatCAMGUI.py:460 +#: flatcamGUI/FlatCAMGUI.py:499 msgid "&Command Line\tS" msgstr "Línea de comando\tS" -#: flatcamGUI/FlatCAMGUI.py:465 +#: flatcamGUI/FlatCAMGUI.py:504 msgid "Help" msgstr "Ayuda" -#: flatcamGUI/FlatCAMGUI.py:467 +#: flatcamGUI/FlatCAMGUI.py:506 msgid "Online Help\tF1" msgstr "Ayuda en Online\tF1" -#: flatcamGUI/FlatCAMGUI.py:477 +#: flatcamGUI/FlatCAMGUI.py:516 msgid "Report a bug" msgstr "Reportar un error" -#: flatcamGUI/FlatCAMGUI.py:480 +#: flatcamGUI/FlatCAMGUI.py:519 msgid "Excellon Specification" msgstr "Especificación de Excellon" -#: flatcamGUI/FlatCAMGUI.py:482 +#: flatcamGUI/FlatCAMGUI.py:521 msgid "Gerber Specification" msgstr "Especificación de Gerber" -#: flatcamGUI/FlatCAMGUI.py:487 +#: flatcamGUI/FlatCAMGUI.py:526 msgid "Shortcuts List\tF3" msgstr "Lista de accesos directos\tF3" -#: flatcamGUI/FlatCAMGUI.py:489 +#: flatcamGUI/FlatCAMGUI.py:528 msgid "YouTube Channel\tF4" msgstr "Canal de Youtube\tF4" -#: flatcamGUI/FlatCAMGUI.py:500 +#: flatcamGUI/FlatCAMGUI.py:539 msgid "Add Circle\tO" msgstr "Añadir círculo\tO" -#: flatcamGUI/FlatCAMGUI.py:503 +#: flatcamGUI/FlatCAMGUI.py:542 msgid "Add Arc\tA" msgstr "Añadir arco\tA" -#: flatcamGUI/FlatCAMGUI.py:506 +#: flatcamGUI/FlatCAMGUI.py:545 msgid "Add Rectangle\tR" msgstr "Añadir rectángulo\tR" -#: flatcamGUI/FlatCAMGUI.py:509 +#: flatcamGUI/FlatCAMGUI.py:548 msgid "Add Polygon\tN" msgstr "Añadir polígono\tN" -#: flatcamGUI/FlatCAMGUI.py:512 +#: flatcamGUI/FlatCAMGUI.py:551 msgid "Add Path\tP" msgstr "Añadir ruta\tP" -#: flatcamGUI/FlatCAMGUI.py:515 +#: flatcamGUI/FlatCAMGUI.py:554 msgid "Add Text\tT" msgstr "Añadir texto\tT" -#: flatcamGUI/FlatCAMGUI.py:518 +#: flatcamGUI/FlatCAMGUI.py:557 msgid "Polygon Union\tU" msgstr "Unión de polígonos\tU" -#: flatcamGUI/FlatCAMGUI.py:520 +#: flatcamGUI/FlatCAMGUI.py:559 msgid "Polygon Intersection\tE" msgstr "Intersección de polígonos\tE" -#: flatcamGUI/FlatCAMGUI.py:522 +#: flatcamGUI/FlatCAMGUI.py:561 msgid "Polygon Subtraction\tS" msgstr "Sustracción de polígonos\tS" -#: flatcamGUI/FlatCAMGUI.py:526 +#: flatcamGUI/FlatCAMGUI.py:565 msgid "Cut Path\tX" msgstr "Camino de corte\tX" -#: flatcamGUI/FlatCAMGUI.py:529 +#: flatcamGUI/FlatCAMGUI.py:569 msgid "Copy Geom\tC" msgstr "Copia Geo\tC" -#: flatcamGUI/FlatCAMGUI.py:531 +#: flatcamGUI/FlatCAMGUI.py:571 msgid "Delete Shape\tDEL" msgstr "Eliminar forma\tDEL" -#: flatcamGUI/FlatCAMGUI.py:535 flatcamGUI/FlatCAMGUI.py:622 +#: flatcamGUI/FlatCAMGUI.py:575 flatcamGUI/FlatCAMGUI.py:662 msgid "Move\tM" msgstr "Movimiento\tM" -#: flatcamGUI/FlatCAMGUI.py:537 +#: flatcamGUI/FlatCAMGUI.py:577 msgid "Buffer Tool\tB" msgstr "Herramienta amortiguadora\tB" -#: flatcamGUI/FlatCAMGUI.py:540 +#: flatcamGUI/FlatCAMGUI.py:580 msgid "Paint Tool\tI" msgstr "Herramienta de pintura\tI" -#: flatcamGUI/FlatCAMGUI.py:543 +#: flatcamGUI/FlatCAMGUI.py:583 msgid "Transform Tool\tAlt+R" msgstr "Herramienta de transformación\tAlt+R" -#: flatcamGUI/FlatCAMGUI.py:547 +#: flatcamGUI/FlatCAMGUI.py:587 msgid "Toggle Corner Snap\tK" msgstr "Alternar esquina esquina\tK" -#: flatcamGUI/FlatCAMGUI.py:553 +#: flatcamGUI/FlatCAMGUI.py:593 msgid ">Excellon Editor<" msgstr ">Excellon Editor<" -#: flatcamGUI/FlatCAMGUI.py:557 +#: flatcamGUI/FlatCAMGUI.py:597 msgid "Add Drill Array\tA" msgstr "Añadir matriz de perfor.\tA" -#: flatcamGUI/FlatCAMGUI.py:559 +#: flatcamGUI/FlatCAMGUI.py:599 msgid "Add Drill\tD" msgstr "Añadir taladro\tD" -#: flatcamGUI/FlatCAMGUI.py:563 +#: flatcamGUI/FlatCAMGUI.py:603 msgid "Add Slot Array\tQ" msgstr "Agregar matriz de ranuras\tQ" -#: flatcamGUI/FlatCAMGUI.py:565 +#: flatcamGUI/FlatCAMGUI.py:605 msgid "Add Slot\tW" msgstr "Agregar ranura\tW" -#: flatcamGUI/FlatCAMGUI.py:569 +#: flatcamGUI/FlatCAMGUI.py:609 msgid "Resize Drill(S)\tR" msgstr "Cambiar el tamaño de taladro (s)\tR" -#: flatcamGUI/FlatCAMGUI.py:572 flatcamGUI/FlatCAMGUI.py:616 +#: flatcamGUI/FlatCAMGUI.py:612 flatcamGUI/FlatCAMGUI.py:656 msgid "Copy\tC" msgstr "Dupdo\tC" -#: flatcamGUI/FlatCAMGUI.py:574 flatcamGUI/FlatCAMGUI.py:618 +#: flatcamGUI/FlatCAMGUI.py:614 flatcamGUI/FlatCAMGUI.py:658 msgid "Delete\tDEL" msgstr "Borrar\tDEL" -#: flatcamGUI/FlatCAMGUI.py:579 +#: flatcamGUI/FlatCAMGUI.py:619 msgid "Move Drill(s)\tM" msgstr "Mover taladro(s)\tM" -#: flatcamGUI/FlatCAMGUI.py:584 +#: flatcamGUI/FlatCAMGUI.py:624 msgid ">Gerber Editor<" msgstr ">Gerber Editor<" -#: flatcamGUI/FlatCAMGUI.py:588 +#: flatcamGUI/FlatCAMGUI.py:628 msgid "Add Pad\tP" msgstr "Añadir Pad\tP" -#: flatcamGUI/FlatCAMGUI.py:590 +#: flatcamGUI/FlatCAMGUI.py:630 msgid "Add Pad Array\tA" msgstr "Agregar una matriz de pad\tA" -#: flatcamGUI/FlatCAMGUI.py:592 +#: flatcamGUI/FlatCAMGUI.py:632 msgid "Add Track\tT" msgstr "Añadir pista\tT" -#: flatcamGUI/FlatCAMGUI.py:594 +#: flatcamGUI/FlatCAMGUI.py:634 msgid "Add Region\tN" msgstr "Añadir región\tN" -#: flatcamGUI/FlatCAMGUI.py:598 +#: flatcamGUI/FlatCAMGUI.py:638 msgid "Poligonize\tAlt+N" msgstr "Poligonize\tAlt+N" -#: flatcamGUI/FlatCAMGUI.py:600 +#: flatcamGUI/FlatCAMGUI.py:640 msgid "Add SemiDisc\tE" msgstr "Añadir medio disco\tE" -#: flatcamGUI/FlatCAMGUI.py:602 +#: flatcamGUI/FlatCAMGUI.py:642 msgid "Add Disc\tD" msgstr "Añadir disco\tD" -#: flatcamGUI/FlatCAMGUI.py:604 +#: flatcamGUI/FlatCAMGUI.py:644 msgid "Buffer\tB" msgstr "Buffer\tB" -#: flatcamGUI/FlatCAMGUI.py:606 +#: flatcamGUI/FlatCAMGUI.py:646 msgid "Scale\tS" msgstr "Escalar\tS" -#: flatcamGUI/FlatCAMGUI.py:608 +#: flatcamGUI/FlatCAMGUI.py:648 msgid "Mark Area\tAlt+A" msgstr "Marcar area\tAlt+A" -#: flatcamGUI/FlatCAMGUI.py:610 +#: flatcamGUI/FlatCAMGUI.py:650 msgid "Eraser\tCtrl+E" msgstr "Borrador\tCtrl+E" -#: flatcamGUI/FlatCAMGUI.py:612 +#: flatcamGUI/FlatCAMGUI.py:652 msgid "Transform\tAlt+R" msgstr "Transformar\tAlt+R" -#: flatcamGUI/FlatCAMGUI.py:639 +#: flatcamGUI/FlatCAMGUI.py:679 msgid "Enable Plot" msgstr "Habilitar Parcela" -#: flatcamGUI/FlatCAMGUI.py:641 +#: flatcamGUI/FlatCAMGUI.py:681 msgid "Disable Plot" msgstr "Desactivar parcela" -#: flatcamGUI/FlatCAMGUI.py:645 +#: flatcamGUI/FlatCAMGUI.py:685 msgid "Set Color" msgstr "Establecer color" -#: flatcamGUI/FlatCAMGUI.py:648 -msgid "Red" -msgstr "Rojo" - -#: flatcamGUI/FlatCAMGUI.py:651 -msgid "Blue" -msgstr "Azul" - -#: flatcamGUI/FlatCAMGUI.py:654 -msgid "Yellow" -msgstr "Amarillo" - -#: flatcamGUI/FlatCAMGUI.py:657 -msgid "Green" -msgstr "Verde" - -#: flatcamGUI/FlatCAMGUI.py:660 -msgid "Purple" -msgstr "Púrpura" - -#: flatcamGUI/FlatCAMGUI.py:663 -msgid "Brown" -msgstr "Marrón" - -#: flatcamGUI/FlatCAMGUI.py:666 -msgid "Custom" -msgstr "Personalizado" - -#: flatcamGUI/FlatCAMGUI.py:671 +#: flatcamGUI/FlatCAMGUI.py:727 msgid "Generate CNC" msgstr "Generar CNC" -#: flatcamGUI/FlatCAMGUI.py:673 +#: flatcamGUI/FlatCAMGUI.py:729 msgid "View Source" msgstr "Ver fuente" -#: flatcamGUI/FlatCAMGUI.py:686 flatcamGUI/FlatCAMGUI.py:2172 -#: flatcamTools/ToolProperties.py:30 +#: flatcamGUI/FlatCAMGUI.py:742 flatcamGUI/FlatCAMGUI.py:2280 +#: flatcamTools/ToolProperties.py:31 msgid "Properties" msgstr "Propiedades" -#: flatcamGUI/FlatCAMGUI.py:715 +#: flatcamGUI/FlatCAMGUI.py:771 msgid "File Toolbar" msgstr "Barra de herramientas de archivo" -#: flatcamGUI/FlatCAMGUI.py:719 +#: flatcamGUI/FlatCAMGUI.py:775 msgid "Edit Toolbar" msgstr "Barra de herramientas de edición" -#: flatcamGUI/FlatCAMGUI.py:723 +#: flatcamGUI/FlatCAMGUI.py:779 msgid "View Toolbar" msgstr "Barra de herramientas de ver" -#: flatcamGUI/FlatCAMGUI.py:727 +#: flatcamGUI/FlatCAMGUI.py:783 msgid "Shell Toolbar" msgstr "Barra de herramientas de Shell" -#: flatcamGUI/FlatCAMGUI.py:731 +#: flatcamGUI/FlatCAMGUI.py:787 msgid "Tools Toolbar" msgstr "Barra de herramientas de Herramientas" -#: flatcamGUI/FlatCAMGUI.py:735 +#: flatcamGUI/FlatCAMGUI.py:791 msgid "Excellon Editor Toolbar" msgstr "Barra de herramientas del editor de Excel" -#: flatcamGUI/FlatCAMGUI.py:741 +#: flatcamGUI/FlatCAMGUI.py:797 msgid "Geometry Editor Toolbar" msgstr "Barra de herramientas del editor de geometría" -#: flatcamGUI/FlatCAMGUI.py:745 +#: flatcamGUI/FlatCAMGUI.py:801 msgid "Gerber Editor Toolbar" msgstr "Barra de herramientas del editor Gerber" -#: flatcamGUI/FlatCAMGUI.py:749 +#: flatcamGUI/FlatCAMGUI.py:805 msgid "Grid Toolbar" msgstr "Barra de herramientas de cuadrícula" -#: flatcamGUI/FlatCAMGUI.py:772 flatcamGUI/FlatCAMGUI.py:2357 +#: flatcamGUI/FlatCAMGUI.py:826 flatcamGUI/FlatCAMGUI.py:2509 msgid "Open project" msgstr "Proyecto abierto" -#: flatcamGUI/FlatCAMGUI.py:774 flatcamGUI/FlatCAMGUI.py:2359 +#: flatcamGUI/FlatCAMGUI.py:828 flatcamGUI/FlatCAMGUI.py:2511 msgid "Save project" msgstr "Guardar proyecto" -#: flatcamGUI/FlatCAMGUI.py:780 flatcamGUI/FlatCAMGUI.py:2363 +#: flatcamGUI/FlatCAMGUI.py:834 flatcamGUI/FlatCAMGUI.py:2517 msgid "New Blank Geometry" msgstr "Nueva geometría en blanco" -#: flatcamGUI/FlatCAMGUI.py:782 flatcamGUI/FlatCAMGUI.py:2365 +#: flatcamGUI/FlatCAMGUI.py:836 flatcamGUI/FlatCAMGUI.py:2519 msgid "New Blank Gerber" msgstr "Nuevo Gerber en blanco" -#: flatcamGUI/FlatCAMGUI.py:784 flatcamGUI/FlatCAMGUI.py:2367 +#: flatcamGUI/FlatCAMGUI.py:838 flatcamGUI/FlatCAMGUI.py:2521 msgid "New Blank Excellon" msgstr "Nueva Excellon en blanco" -#: flatcamGUI/FlatCAMGUI.py:789 flatcamGUI/FlatCAMGUI.py:2373 +#: flatcamGUI/FlatCAMGUI.py:843 flatcamGUI/FlatCAMGUI.py:2527 msgid "Save Object and close the Editor" msgstr "Guardar Objeto y cerrar el Editor" -#: flatcamGUI/FlatCAMGUI.py:796 flatcamGUI/FlatCAMGUI.py:2380 +#: flatcamGUI/FlatCAMGUI.py:850 flatcamGUI/FlatCAMGUI.py:2534 msgid "&Delete" msgstr "Borrar" -#: flatcamGUI/FlatCAMGUI.py:799 flatcamGUI/FlatCAMGUI.py:1613 -#: flatcamGUI/FlatCAMGUI.py:1812 flatcamGUI/FlatCAMGUI.py:2383 -#: flatcamTools/ToolDistance.py:30 flatcamTools/ToolDistance.py:160 +#: flatcamGUI/FlatCAMGUI.py:853 flatcamGUI/FlatCAMGUI.py:1714 +#: flatcamGUI/FlatCAMGUI.py:1920 flatcamGUI/FlatCAMGUI.py:2537 +#: flatcamTools/ToolDistance.py:35 flatcamTools/ToolDistance.py:195 msgid "Distance Tool" msgstr "Herramienta de Dist" -#: flatcamGUI/FlatCAMGUI.py:801 flatcamGUI/FlatCAMGUI.py:2385 +#: flatcamGUI/FlatCAMGUI.py:855 flatcamGUI/FlatCAMGUI.py:2539 msgid "Distance Min Tool" msgstr "Herramienta Distancia Mínima" -#: flatcamGUI/FlatCAMGUI.py:803 flatcamGUI/FlatCAMGUI.py:1606 -#: flatcamGUI/FlatCAMGUI.py:2387 +#: flatcamGUI/FlatCAMGUI.py:857 flatcamGUI/FlatCAMGUI.py:1707 +#: flatcamGUI/FlatCAMGUI.py:2541 msgid "Set Origin" msgstr "Establecer origen" -#: flatcamGUI/FlatCAMGUI.py:805 flatcamGUI/FlatCAMGUI.py:2389 +#: flatcamGUI/FlatCAMGUI.py:859 +msgid "Move to Origin" +msgstr "Mover al origen" + +#: flatcamGUI/FlatCAMGUI.py:862 flatcamGUI/FlatCAMGUI.py:2543 msgid "Jump to Location" msgstr "Saltar a la ubicación" -#: flatcamGUI/FlatCAMGUI.py:811 flatcamGUI/FlatCAMGUI.py:2393 +#: flatcamGUI/FlatCAMGUI.py:864 flatcamGUI/FlatCAMGUI.py:1719 +#: flatcamGUI/FlatCAMGUI.py:2545 +msgid "Locate in Object" +msgstr "Localizar en objeto" + +#: flatcamGUI/FlatCAMGUI.py:870 flatcamGUI/FlatCAMGUI.py:2551 msgid "&Replot" msgstr "Replantear" -#: flatcamGUI/FlatCAMGUI.py:813 flatcamGUI/FlatCAMGUI.py:2395 +#: flatcamGUI/FlatCAMGUI.py:872 flatcamGUI/FlatCAMGUI.py:2553 msgid "&Clear plot" msgstr "Gráfico clara" -#: flatcamGUI/FlatCAMGUI.py:815 flatcamGUI/FlatCAMGUI.py:1609 -#: flatcamGUI/FlatCAMGUI.py:2397 +#: flatcamGUI/FlatCAMGUI.py:874 flatcamGUI/FlatCAMGUI.py:1710 +#: flatcamGUI/FlatCAMGUI.py:2555 msgid "Zoom In" msgstr "Acercarse" -#: flatcamGUI/FlatCAMGUI.py:817 flatcamGUI/FlatCAMGUI.py:1609 -#: flatcamGUI/FlatCAMGUI.py:2399 +#: flatcamGUI/FlatCAMGUI.py:876 flatcamGUI/FlatCAMGUI.py:1710 +#: flatcamGUI/FlatCAMGUI.py:2557 msgid "Zoom Out" msgstr "Disminuir el zoom" -#: flatcamGUI/FlatCAMGUI.py:819 flatcamGUI/FlatCAMGUI.py:1608 -#: flatcamGUI/FlatCAMGUI.py:2062 flatcamGUI/FlatCAMGUI.py:2401 +#: flatcamGUI/FlatCAMGUI.py:878 flatcamGUI/FlatCAMGUI.py:1709 +#: flatcamGUI/FlatCAMGUI.py:2170 flatcamGUI/FlatCAMGUI.py:2559 msgid "Zoom Fit" msgstr "Ajuste de zoom" -#: flatcamGUI/FlatCAMGUI.py:827 flatcamGUI/FlatCAMGUI.py:2407 +#: flatcamGUI/FlatCAMGUI.py:886 flatcamGUI/FlatCAMGUI.py:2565 msgid "&Command Line" msgstr "Línea de comando" -#: flatcamGUI/FlatCAMGUI.py:839 flatcamGUI/FlatCAMGUI.py:2417 +#: flatcamGUI/FlatCAMGUI.py:898 flatcamGUI/FlatCAMGUI.py:2577 msgid "2Sided Tool" msgstr "Herramienta de 2 Caras" -#: flatcamGUI/FlatCAMGUI.py:841 flatcamGUI/ObjectUI.py:588 -#: flatcamTools/ToolCutOut.py:436 +#: flatcamGUI/FlatCAMGUI.py:900 flatcamGUI/FlatCAMGUI.py:1725 +#: flatcamGUI/FlatCAMGUI.py:2579 +msgid "Align Objects Tool" +msgstr "Herram. de Alinear Objetos" + +#: flatcamGUI/FlatCAMGUI.py:902 flatcamGUI/FlatCAMGUI.py:1726 +#: flatcamGUI/FlatCAMGUI.py:2581 flatcamTools/ToolExtractDrills.py:393 +msgid "Extract Drills Tool" +msgstr "Herram. de Extracción de Taladros" + +#: flatcamGUI/FlatCAMGUI.py:905 flatcamGUI/ObjectUI.py:595 +#: flatcamTools/ToolCutOut.py:447 msgid "Cutout Tool" msgstr "Herramienta de Corte" -#: flatcamGUI/FlatCAMGUI.py:843 flatcamGUI/FlatCAMGUI.py:2421 -#: flatcamGUI/ObjectUI.py:566 flatcamGUI/ObjectUI.py:1749 -#: flatcamTools/ToolNonCopperClear.py:632 +#: flatcamGUI/FlatCAMGUI.py:907 flatcamGUI/FlatCAMGUI.py:2586 +#: flatcamGUI/ObjectUI.py:573 flatcamGUI/ObjectUI.py:2075 +#: flatcamTools/ToolNCC.py:974 msgid "NCC Tool" msgstr "Herramienta NCC" -#: flatcamGUI/FlatCAMGUI.py:849 flatcamGUI/FlatCAMGUI.py:2427 +#: flatcamGUI/FlatCAMGUI.py:913 flatcamGUI/FlatCAMGUI.py:2592 msgid "Panel Tool" msgstr "Herramienta de Panel" -#: flatcamGUI/FlatCAMGUI.py:851 flatcamGUI/FlatCAMGUI.py:2429 -#: flatcamTools/ToolFilm.py:578 +#: flatcamGUI/FlatCAMGUI.py:915 flatcamGUI/FlatCAMGUI.py:2594 +#: flatcamTools/ToolFilm.py:586 msgid "Film Tool" msgstr "Herramienta de Película" -#: flatcamGUI/FlatCAMGUI.py:853 flatcamGUI/FlatCAMGUI.py:2432 -#: flatcamTools/ToolSolderPaste.py:547 +#: flatcamGUI/FlatCAMGUI.py:917 flatcamGUI/FlatCAMGUI.py:2596 +#: flatcamTools/ToolSolderPaste.py:553 msgid "SolderPaste Tool" msgstr "Herramienta de Pasta" -#: flatcamGUI/FlatCAMGUI.py:855 flatcamGUI/FlatCAMGUI.py:2434 +#: flatcamGUI/FlatCAMGUI.py:919 flatcamGUI/FlatCAMGUI.py:2598 #: flatcamTools/ToolSub.py:35 msgid "Subtract Tool" msgstr "Herramienta de Sustracción" -#: flatcamGUI/FlatCAMGUI.py:857 flatcamTools/ToolRulesCheck.py:607 +#: flatcamGUI/FlatCAMGUI.py:921 flatcamGUI/FlatCAMGUI.py:2600 +#: flatcamTools/ToolRulesCheck.py:616 msgid "Rules Tool" msgstr "Herramienta de Reglas" -#: flatcamGUI/FlatCAMGUI.py:859 flatcamGUI/FlatCAMGUI.py:1624 -#: flatcamTools/ToolOptimal.py:34 flatcamTools/ToolOptimal.py:310 +#: flatcamGUI/FlatCAMGUI.py:923 flatcamGUI/FlatCAMGUI.py:1728 +#: flatcamGUI/FlatCAMGUI.py:2602 flatcamTools/ToolOptimal.py:34 +#: flatcamTools/ToolOptimal.py:308 msgid "Optimal Tool" msgstr "Herramienta de Óptima" -#: flatcamGUI/FlatCAMGUI.py:864 flatcamGUI/FlatCAMGUI.py:1622 -#: flatcamGUI/FlatCAMGUI.py:2439 +#: flatcamGUI/FlatCAMGUI.py:928 flatcamGUI/FlatCAMGUI.py:1725 +#: flatcamGUI/FlatCAMGUI.py:2607 msgid "Calculators Tool" msgstr "Herramienta de Calculadoras" -#: flatcamGUI/FlatCAMGUI.py:868 flatcamGUI/FlatCAMGUI.py:1625 -#: flatcamGUI/FlatCAMGUI.py:2443 flatcamTools/ToolQRCode.py:43 +#: flatcamGUI/FlatCAMGUI.py:932 flatcamGUI/FlatCAMGUI.py:1729 +#: flatcamGUI/FlatCAMGUI.py:2611 flatcamTools/ToolQRCode.py:43 #: flatcamTools/ToolQRCode.py:382 msgid "QRCode Tool" msgstr "Herramienta QRCode" -#: flatcamGUI/FlatCAMGUI.py:870 flatcamGUI/FlatCAMGUI.py:2445 -#: flatcamTools/ToolCopperThieving.py:40 flatcamTools/ToolCopperThieving.py:566 +#: flatcamGUI/FlatCAMGUI.py:934 flatcamGUI/FlatCAMGUI.py:2613 +#: flatcamTools/ToolCopperThieving.py:40 flatcamTools/ToolCopperThieving.py:569 msgid "Copper Thieving Tool" msgstr "Herramienta Thieving Tool" -#: flatcamGUI/FlatCAMGUI.py:873 flatcamGUI/FlatCAMGUI.py:1622 -#: flatcamGUI/FlatCAMGUI.py:2448 flatcamTools/ToolFiducials.py:33 -#: flatcamTools/ToolFiducials.py:393 +#: flatcamGUI/FlatCAMGUI.py:937 flatcamGUI/FlatCAMGUI.py:1726 +#: flatcamGUI/FlatCAMGUI.py:2616 flatcamTools/ToolFiducials.py:33 +#: flatcamTools/ToolFiducials.py:395 msgid "Fiducials Tool" msgstr "Herramienta de Fiduciales" -#: flatcamGUI/FlatCAMGUI.py:875 flatcamGUI/FlatCAMGUI.py:2450 -#: flatcamTools/ToolCalibration.py:37 flatcamTools/ToolCalibration.py:762 +#: flatcamGUI/FlatCAMGUI.py:939 flatcamGUI/FlatCAMGUI.py:2618 +#: flatcamTools/ToolCalibration.py:37 flatcamTools/ToolCalibration.py:759 msgid "Calibration Tool" msgstr "Herramienta de Calibración" -#: flatcamGUI/FlatCAMGUI.py:881 flatcamGUI/FlatCAMGUI.py:907 -#: flatcamGUI/FlatCAMGUI.py:959 flatcamGUI/FlatCAMGUI.py:2454 -#: flatcamGUI/FlatCAMGUI.py:2528 +#: flatcamGUI/FlatCAMGUI.py:941 flatcamGUI/FlatCAMGUI.py:1726 +msgid "Punch Gerber Tool" +msgstr "Herram. de Perforadora Gerber" + +#: flatcamGUI/FlatCAMGUI.py:943 flatcamTools/ToolInvertGerber.py:31 +msgid "Invert Gerber Tool" +msgstr "Herram. Invertir Gerber" + +#: flatcamGUI/FlatCAMGUI.py:949 flatcamGUI/FlatCAMGUI.py:975 +#: flatcamGUI/FlatCAMGUI.py:1027 flatcamGUI/FlatCAMGUI.py:2624 +#: flatcamGUI/FlatCAMGUI.py:2702 msgid "Select" msgstr "Seleccionar" -#: flatcamGUI/FlatCAMGUI.py:883 flatcamGUI/FlatCAMGUI.py:2456 +#: flatcamGUI/FlatCAMGUI.py:951 flatcamGUI/FlatCAMGUI.py:2626 msgid "Add Drill Hole" msgstr "Añadir taladro" -#: flatcamGUI/FlatCAMGUI.py:885 flatcamGUI/FlatCAMGUI.py:2458 +#: flatcamGUI/FlatCAMGUI.py:953 flatcamGUI/FlatCAMGUI.py:2628 msgid "Add Drill Hole Array" msgstr "Añadir matriz de taladro" -#: flatcamGUI/FlatCAMGUI.py:887 flatcamGUI/FlatCAMGUI.py:1897 -#: flatcamGUI/FlatCAMGUI.py:2150 flatcamGUI/FlatCAMGUI.py:2462 +#: flatcamGUI/FlatCAMGUI.py:955 flatcamGUI/FlatCAMGUI.py:2005 +#: flatcamGUI/FlatCAMGUI.py:2258 flatcamGUI/FlatCAMGUI.py:2632 msgid "Add Slot" msgstr "Agregar ranura" -#: flatcamGUI/FlatCAMGUI.py:889 flatcamGUI/FlatCAMGUI.py:1896 -#: flatcamGUI/FlatCAMGUI.py:2152 flatcamGUI/FlatCAMGUI.py:2464 +#: flatcamGUI/FlatCAMGUI.py:957 flatcamGUI/FlatCAMGUI.py:2004 +#: flatcamGUI/FlatCAMGUI.py:2260 flatcamGUI/FlatCAMGUI.py:2634 msgid "Add Slot Array" msgstr "Agregar matriz de ranuras" -#: flatcamGUI/FlatCAMGUI.py:891 flatcamGUI/FlatCAMGUI.py:2155 -#: flatcamGUI/FlatCAMGUI.py:2460 +#: flatcamGUI/FlatCAMGUI.py:959 flatcamGUI/FlatCAMGUI.py:2263 +#: flatcamGUI/FlatCAMGUI.py:2630 msgid "Resize Drill" msgstr "Redimensionar taladro" -#: flatcamGUI/FlatCAMGUI.py:895 flatcamGUI/FlatCAMGUI.py:2468 +#: flatcamGUI/FlatCAMGUI.py:963 flatcamGUI/FlatCAMGUI.py:2638 msgid "Copy Drill" msgstr "Copia de taladro" -#: flatcamGUI/FlatCAMGUI.py:897 flatcamGUI/FlatCAMGUI.py:2470 +#: flatcamGUI/FlatCAMGUI.py:965 flatcamGUI/FlatCAMGUI.py:2640 msgid "Delete Drill" msgstr "Eliminar taladro" -#: flatcamGUI/FlatCAMGUI.py:901 flatcamGUI/FlatCAMGUI.py:2474 +#: flatcamGUI/FlatCAMGUI.py:969 flatcamGUI/FlatCAMGUI.py:2644 msgid "Move Drill" msgstr "Mover taladro" -#: flatcamGUI/FlatCAMGUI.py:909 flatcamGUI/FlatCAMGUI.py:2480 +#: flatcamGUI/FlatCAMGUI.py:977 flatcamGUI/FlatCAMGUI.py:2652 msgid "Add Circle" msgstr "Añadir Círculo" -#: flatcamGUI/FlatCAMGUI.py:911 flatcamGUI/FlatCAMGUI.py:2482 +#: flatcamGUI/FlatCAMGUI.py:979 flatcamGUI/FlatCAMGUI.py:2654 msgid "Add Arc" msgstr "Añadir Arco" -#: flatcamGUI/FlatCAMGUI.py:913 flatcamGUI/FlatCAMGUI.py:2484 +#: flatcamGUI/FlatCAMGUI.py:981 flatcamGUI/FlatCAMGUI.py:2656 msgid "Add Rectangle" msgstr "Añadir Rectángulo" -#: flatcamGUI/FlatCAMGUI.py:917 flatcamGUI/FlatCAMGUI.py:2488 +#: flatcamGUI/FlatCAMGUI.py:985 flatcamGUI/FlatCAMGUI.py:2660 msgid "Add Path" msgstr "Añadir Ruta" -#: flatcamGUI/FlatCAMGUI.py:919 flatcamGUI/FlatCAMGUI.py:2490 +#: flatcamGUI/FlatCAMGUI.py:987 flatcamGUI/FlatCAMGUI.py:2662 msgid "Add Polygon" msgstr "Añadir Polígono" -#: flatcamGUI/FlatCAMGUI.py:922 flatcamGUI/FlatCAMGUI.py:2493 +#: flatcamGUI/FlatCAMGUI.py:990 flatcamGUI/FlatCAMGUI.py:2665 msgid "Add Text" msgstr "Añadir Texto" -#: flatcamGUI/FlatCAMGUI.py:924 flatcamGUI/FlatCAMGUI.py:2495 +#: flatcamGUI/FlatCAMGUI.py:992 flatcamGUI/FlatCAMGUI.py:2667 msgid "Add Buffer" msgstr "Añadir Buffer" -#: flatcamGUI/FlatCAMGUI.py:926 flatcamGUI/FlatCAMGUI.py:2497 +#: flatcamGUI/FlatCAMGUI.py:994 flatcamGUI/FlatCAMGUI.py:2669 msgid "Paint Shape" msgstr "Forma de pintura" -#: flatcamGUI/FlatCAMGUI.py:928 flatcamGUI/FlatCAMGUI.py:985 -#: flatcamGUI/FlatCAMGUI.py:2091 flatcamGUI/FlatCAMGUI.py:2136 -#: flatcamGUI/FlatCAMGUI.py:2499 flatcamGUI/FlatCAMGUI.py:2553 +#: flatcamGUI/FlatCAMGUI.py:996 flatcamGUI/FlatCAMGUI.py:1053 +#: flatcamGUI/FlatCAMGUI.py:2199 flatcamGUI/FlatCAMGUI.py:2244 +#: flatcamGUI/FlatCAMGUI.py:2671 flatcamGUI/FlatCAMGUI.py:2727 msgid "Eraser" msgstr "Borrador" -#: flatcamGUI/FlatCAMGUI.py:932 flatcamGUI/FlatCAMGUI.py:2503 +#: flatcamGUI/FlatCAMGUI.py:1000 flatcamGUI/FlatCAMGUI.py:2675 msgid "Polygon Union" msgstr "Unión de polígonos" -#: flatcamGUI/FlatCAMGUI.py:934 flatcamGUI/FlatCAMGUI.py:2505 +#: flatcamGUI/FlatCAMGUI.py:1002 flatcamGUI/FlatCAMGUI.py:2677 msgid "Polygon Explode" msgstr "Polígono explotar" -#: flatcamGUI/FlatCAMGUI.py:937 flatcamGUI/FlatCAMGUI.py:2508 +#: flatcamGUI/FlatCAMGUI.py:1005 flatcamGUI/FlatCAMGUI.py:2680 msgid "Polygon Intersection" msgstr "Intersección de polígonos" -#: flatcamGUI/FlatCAMGUI.py:939 flatcamGUI/FlatCAMGUI.py:2510 +#: flatcamGUI/FlatCAMGUI.py:1007 flatcamGUI/FlatCAMGUI.py:2682 msgid "Polygon Subtraction" msgstr "Sustracción de polígonos" -#: flatcamGUI/FlatCAMGUI.py:943 flatcamGUI/FlatCAMGUI.py:2514 +#: flatcamGUI/FlatCAMGUI.py:1011 flatcamGUI/FlatCAMGUI.py:2686 msgid "Cut Path" msgstr "Camino de Corte" -#: flatcamGUI/FlatCAMGUI.py:945 +#: flatcamGUI/FlatCAMGUI.py:1013 msgid "Copy Shape(s)" msgstr "Copiar Forma (s)" -#: flatcamGUI/FlatCAMGUI.py:948 +#: flatcamGUI/FlatCAMGUI.py:1016 msgid "Delete Shape '-'" msgstr "Eliminar Forma '-'" -#: flatcamGUI/FlatCAMGUI.py:950 flatcamGUI/FlatCAMGUI.py:993 -#: flatcamGUI/FlatCAMGUI.py:2103 flatcamGUI/FlatCAMGUI.py:2140 -#: flatcamGUI/FlatCAMGUI.py:2520 flatcamGUI/FlatCAMGUI.py:2561 +#: flatcamGUI/FlatCAMGUI.py:1018 flatcamGUI/FlatCAMGUI.py:1061 +#: flatcamGUI/FlatCAMGUI.py:2211 flatcamGUI/FlatCAMGUI.py:2248 +#: flatcamGUI/FlatCAMGUI.py:2692 flatcamGUI/FlatCAMGUI.py:2735 +#: flatcamGUI/ObjectUI.py:108 msgid "Transformations" msgstr "Transformaciones" -#: flatcamGUI/FlatCAMGUI.py:953 +#: flatcamGUI/FlatCAMGUI.py:1021 msgid "Move Objects " msgstr "Mover objetos " -#: flatcamGUI/FlatCAMGUI.py:961 flatcamGUI/FlatCAMGUI.py:2016 -#: flatcamGUI/FlatCAMGUI.py:2530 +#: flatcamGUI/FlatCAMGUI.py:1029 flatcamGUI/FlatCAMGUI.py:2124 +#: flatcamGUI/FlatCAMGUI.py:2704 msgid "Add Pad" msgstr "Añadir Pad" -#: flatcamGUI/FlatCAMGUI.py:965 flatcamGUI/FlatCAMGUI.py:2017 -#: flatcamGUI/FlatCAMGUI.py:2534 +#: flatcamGUI/FlatCAMGUI.py:1033 flatcamGUI/FlatCAMGUI.py:2125 +#: flatcamGUI/FlatCAMGUI.py:2708 msgid "Add Track" msgstr "Añadir Pista" -#: flatcamGUI/FlatCAMGUI.py:967 flatcamGUI/FlatCAMGUI.py:2016 -#: flatcamGUI/FlatCAMGUI.py:2536 +#: flatcamGUI/FlatCAMGUI.py:1035 flatcamGUI/FlatCAMGUI.py:2124 +#: flatcamGUI/FlatCAMGUI.py:2710 msgid "Add Region" msgstr "Añadir Región" -#: flatcamGUI/FlatCAMGUI.py:969 flatcamGUI/FlatCAMGUI.py:2122 -#: flatcamGUI/FlatCAMGUI.py:2538 +#: flatcamGUI/FlatCAMGUI.py:1037 flatcamGUI/FlatCAMGUI.py:2230 +#: flatcamGUI/FlatCAMGUI.py:2712 msgid "Poligonize" msgstr "Poligonizar" -#: flatcamGUI/FlatCAMGUI.py:972 flatcamGUI/FlatCAMGUI.py:2124 -#: flatcamGUI/FlatCAMGUI.py:2541 +#: flatcamGUI/FlatCAMGUI.py:1040 flatcamGUI/FlatCAMGUI.py:2232 +#: flatcamGUI/FlatCAMGUI.py:2715 msgid "SemiDisc" msgstr "Medio disco" -#: flatcamGUI/FlatCAMGUI.py:974 flatcamGUI/FlatCAMGUI.py:2126 -#: flatcamGUI/FlatCAMGUI.py:2543 +#: flatcamGUI/FlatCAMGUI.py:1042 flatcamGUI/FlatCAMGUI.py:2234 +#: flatcamGUI/FlatCAMGUI.py:2717 msgid "Disc" msgstr "Disco" -#: flatcamGUI/FlatCAMGUI.py:982 flatcamGUI/FlatCAMGUI.py:2134 -#: flatcamGUI/FlatCAMGUI.py:2551 +#: flatcamGUI/FlatCAMGUI.py:1050 flatcamGUI/FlatCAMGUI.py:2242 +#: flatcamGUI/FlatCAMGUI.py:2725 msgid "Mark Area" msgstr "Marcar area" -#: flatcamGUI/FlatCAMGUI.py:996 flatcamGUI/FlatCAMGUI.py:2016 -#: flatcamGUI/FlatCAMGUI.py:2107 flatcamGUI/FlatCAMGUI.py:2170 -#: flatcamGUI/FlatCAMGUI.py:2564 flatcamTools/ToolMove.py:28 +#: flatcamGUI/FlatCAMGUI.py:1064 flatcamGUI/FlatCAMGUI.py:2124 +#: flatcamGUI/FlatCAMGUI.py:2215 flatcamGUI/FlatCAMGUI.py:2278 +#: flatcamGUI/FlatCAMGUI.py:2738 flatcamTools/ToolMove.py:28 msgid "Move" msgstr "Movimiento" -#: flatcamGUI/FlatCAMGUI.py:1004 flatcamGUI/FlatCAMGUI.py:2571 +#: flatcamGUI/FlatCAMGUI.py:1072 flatcamGUI/FlatCAMGUI.py:2747 msgid "Snap to grid" msgstr "Encajar a la cuadricula" -#: flatcamGUI/FlatCAMGUI.py:1007 flatcamGUI/FlatCAMGUI.py:2574 +#: flatcamGUI/FlatCAMGUI.py:1075 flatcamGUI/FlatCAMGUI.py:2750 msgid "Grid X snapping distance" msgstr "Distancia de ajuste de la rejilla X" -#: flatcamGUI/FlatCAMGUI.py:1012 flatcamGUI/FlatCAMGUI.py:2579 +#: flatcamGUI/FlatCAMGUI.py:1080 flatcamGUI/FlatCAMGUI.py:2755 msgid "Grid Y snapping distance" msgstr "Distancia de ajuste de cuadrícula Y" -#: flatcamGUI/FlatCAMGUI.py:1018 flatcamGUI/FlatCAMGUI.py:2585 +#: flatcamGUI/FlatCAMGUI.py:1086 flatcamGUI/FlatCAMGUI.py:2761 msgid "" "When active, value on Grid_X\n" "is copied to the Grid_Y value." @@ -6300,63 +6630,64 @@ msgstr "" "Cuando está activo, el valor en Grid_X\n" "Se copia al valor Grid_Y." -#: flatcamGUI/FlatCAMGUI.py:1025 flatcamGUI/FlatCAMGUI.py:2592 +#: flatcamGUI/FlatCAMGUI.py:1093 flatcamGUI/FlatCAMGUI.py:2768 msgid "Snap to corner" msgstr "Ajustar a la esquina" -#: flatcamGUI/FlatCAMGUI.py:1029 flatcamGUI/FlatCAMGUI.py:2596 -#: flatcamGUI/PreferencesUI.py:984 +#: flatcamGUI/FlatCAMGUI.py:1097 flatcamGUI/FlatCAMGUI.py:2772 +#: flatcamGUI/PreferencesUI.py:1159 msgid "Max. magnet distance" msgstr "Distancia máxima del imán" -#: flatcamGUI/FlatCAMGUI.py:1063 +#: flatcamGUI/FlatCAMGUI.py:1134 msgid "Selected" msgstr "Seleccionado" -#: flatcamGUI/FlatCAMGUI.py:1090 flatcamGUI/FlatCAMGUI.py:1098 +#: flatcamGUI/FlatCAMGUI.py:1162 flatcamGUI/FlatCAMGUI.py:1170 msgid "Plot Area" msgstr "Área de la parcela" -#: flatcamGUI/FlatCAMGUI.py:1125 +#: flatcamGUI/FlatCAMGUI.py:1197 msgid "General" msgstr "General" -#: flatcamGUI/FlatCAMGUI.py:1140 flatcamTools/ToolCopperThieving.py:74 -#: flatcamTools/ToolDblSided.py:59 flatcamTools/ToolOptimal.py:71 -#: flatcamTools/ToolQRCode.py:77 +#: flatcamGUI/FlatCAMGUI.py:1212 flatcamTools/ToolCopperThieving.py:75 +#: flatcamTools/ToolDblSided.py:65 flatcamTools/ToolExtractDrills.py:61 +#: flatcamTools/ToolInvertGerber.py:72 flatcamTools/ToolOptimal.py:72 +#: flatcamTools/ToolPunchGerber.py:64 msgid "GERBER" msgstr "GERBER" -#: flatcamGUI/FlatCAMGUI.py:1150 flatcamTools/ToolDblSided.py:87 +#: flatcamGUI/FlatCAMGUI.py:1222 flatcamTools/ToolDblSided.py:93 msgid "EXCELLON" msgstr "EXCELLON" -#: flatcamGUI/FlatCAMGUI.py:1160 flatcamTools/ToolDblSided.py:115 +#: flatcamGUI/FlatCAMGUI.py:1232 flatcamTools/ToolDblSided.py:121 msgid "GEOMETRY" msgstr "GEOMETRÍA" -#: flatcamGUI/FlatCAMGUI.py:1170 +#: flatcamGUI/FlatCAMGUI.py:1242 msgid "CNC-JOB" msgstr "CNC-JOB" -#: flatcamGUI/FlatCAMGUI.py:1179 flatcamGUI/ObjectUI.py:555 -#: flatcamGUI/ObjectUI.py:1724 +#: flatcamGUI/FlatCAMGUI.py:1251 flatcamGUI/ObjectUI.py:562 +#: flatcamGUI/ObjectUI.py:2050 msgid "TOOLS" msgstr "HERRAMIENTAS" -#: flatcamGUI/FlatCAMGUI.py:1188 +#: flatcamGUI/FlatCAMGUI.py:1260 msgid "TOOLS 2" msgstr "HERRAMIENTAS 2" -#: flatcamGUI/FlatCAMGUI.py:1198 +#: flatcamGUI/FlatCAMGUI.py:1270 msgid "UTILITIES" msgstr "UTILIDADES" -#: flatcamGUI/FlatCAMGUI.py:1215 flatcamGUI/PreferencesUI.py:2833 +#: flatcamGUI/FlatCAMGUI.py:1287 flatcamGUI/PreferencesUI.py:3015 msgid "Restore Defaults" msgstr "Restaurar los valores predeterminados" -#: flatcamGUI/FlatCAMGUI.py:1218 +#: flatcamGUI/FlatCAMGUI.py:1290 msgid "" "Restore the entire set of default values\n" "to the initial values loaded after first launch." @@ -6364,15 +6695,19 @@ msgstr "" "Restaurar todo el conjunto de valores predeterminados\n" "a los valores iniciales cargados después del primer lanzamiento." -#: flatcamGUI/FlatCAMGUI.py:1223 +#: flatcamGUI/FlatCAMGUI.py:1295 msgid "Open Pref Folder" msgstr "Abrir Carpeta de Pref" -#: flatcamGUI/FlatCAMGUI.py:1226 +#: flatcamGUI/FlatCAMGUI.py:1298 msgid "Open the folder where FlatCAM save the preferences files." msgstr "Abra la carpeta donde FlatCAM guarda los archivos de preferencias." -#: flatcamGUI/FlatCAMGUI.py:1234 +#: flatcamGUI/FlatCAMGUI.py:1302 flatcamGUI/FlatCAMGUI.py:2477 +msgid "Clear GUI Settings" +msgstr "Borrar la configuración de la GUI" + +#: flatcamGUI/FlatCAMGUI.py:1306 msgid "" "Clear the GUI settings for FlatCAM,\n" "such as: layout, gui state, style, hdpi support etc." @@ -6380,15 +6715,15 @@ msgstr "" "Borrar la configuración de la GUI para FlatCAM,\n" "tales como: diseño, estado gui, estilo, soporte hdpi etc." -#: flatcamGUI/FlatCAMGUI.py:1245 +#: flatcamGUI/FlatCAMGUI.py:1317 msgid "Apply" msgstr "Aplicar" -#: flatcamGUI/FlatCAMGUI.py:1248 +#: flatcamGUI/FlatCAMGUI.py:1320 msgid "Apply the current preferences without saving to a file." msgstr "Aplique las preferencias actuales sin guardar en un archivo." -#: flatcamGUI/FlatCAMGUI.py:1255 +#: flatcamGUI/FlatCAMGUI.py:1327 msgid "" "Save the current settings in the 'current_defaults' file\n" "which is the file storing the working default preferences." @@ -6396,532 +6731,545 @@ msgstr "" "Guarde la configuración actual en el archivo 'current_defaults'\n" "que es el archivo que almacena las preferencias predeterminadas de trabajo." -#: flatcamGUI/FlatCAMGUI.py:1263 +#: flatcamGUI/FlatCAMGUI.py:1335 msgid "Will not save the changes and will close the preferences window." msgstr "No guardará los cambios y cerrará la ventana de preferencias." -#: flatcamGUI/FlatCAMGUI.py:1603 +#: flatcamGUI/FlatCAMGUI.py:1704 msgid "SHOW SHORTCUT LIST" msgstr "MOSTRAR LISTA DE ACCESO CORTO" -#: flatcamGUI/FlatCAMGUI.py:1603 +#: flatcamGUI/FlatCAMGUI.py:1704 msgid "Switch to Project Tab" msgstr "Cambiar a la Pestaña Proyecto" -#: flatcamGUI/FlatCAMGUI.py:1603 +#: flatcamGUI/FlatCAMGUI.py:1704 msgid "Switch to Selected Tab" msgstr "Cambiar a la Pestaña Seleccionada" -#: flatcamGUI/FlatCAMGUI.py:1604 +#: flatcamGUI/FlatCAMGUI.py:1705 msgid "Switch to Tool Tab" msgstr "Cambiar a la Pestaña de Herramientas" -#: flatcamGUI/FlatCAMGUI.py:1605 +#: flatcamGUI/FlatCAMGUI.py:1706 msgid "New Gerber" msgstr "Nuevo Gerber" -#: flatcamGUI/FlatCAMGUI.py:1605 +#: flatcamGUI/FlatCAMGUI.py:1706 msgid "Edit Object (if selected)" msgstr "Editar objeto (si está seleccionado)" -#: flatcamGUI/FlatCAMGUI.py:1605 +#: flatcamGUI/FlatCAMGUI.py:1706 msgid "Jump to Coordinates" msgstr "Saltar a coordenadas" -#: flatcamGUI/FlatCAMGUI.py:1606 +#: flatcamGUI/FlatCAMGUI.py:1707 msgid "New Excellon" msgstr "Nueva Excellon" -#: flatcamGUI/FlatCAMGUI.py:1606 +#: flatcamGUI/FlatCAMGUI.py:1707 msgid "Move Obj" msgstr "Mover objetos" -#: flatcamGUI/FlatCAMGUI.py:1606 +#: flatcamGUI/FlatCAMGUI.py:1707 msgid "New Geometry" msgstr "Nueva geometría" -#: flatcamGUI/FlatCAMGUI.py:1606 +#: flatcamGUI/FlatCAMGUI.py:1707 msgid "Change Units" msgstr "Cambiar unidades" -#: flatcamGUI/FlatCAMGUI.py:1607 +#: flatcamGUI/FlatCAMGUI.py:1708 msgid "Open Properties Tool" msgstr "Abrir herramienta de propiedades" -#: flatcamGUI/FlatCAMGUI.py:1607 +#: flatcamGUI/FlatCAMGUI.py:1708 msgid "Rotate by 90 degree CW" msgstr "Rotar 90 grados CW" -#: flatcamGUI/FlatCAMGUI.py:1607 +#: flatcamGUI/FlatCAMGUI.py:1708 msgid "Shell Toggle" msgstr "Palanca de 'Shell'" -#: flatcamGUI/FlatCAMGUI.py:1608 +#: flatcamGUI/FlatCAMGUI.py:1709 msgid "" "Add a Tool (when in Geometry Selected Tab or in Tools NCC or Tools Paint)" msgstr "" "Agregue una herramienta (cuando esté en la pestaña Geometría seleccionada o " "en Herramientas NCC o Herramientas de pintura)" -#: flatcamGUI/FlatCAMGUI.py:1609 +#: flatcamGUI/FlatCAMGUI.py:1710 msgid "Flip on X_axis" msgstr "Voltear sobre el eje X" -#: flatcamGUI/FlatCAMGUI.py:1609 +#: flatcamGUI/FlatCAMGUI.py:1710 msgid "Flip on Y_axis" msgstr "Voltear sobre el eje Y" -#: flatcamGUI/FlatCAMGUI.py:1612 +#: flatcamGUI/FlatCAMGUI.py:1713 msgid "Copy Obj" msgstr "Copiar objetos" -#: flatcamGUI/FlatCAMGUI.py:1612 +#: flatcamGUI/FlatCAMGUI.py:1713 msgid "Open Tools Database" msgstr "Abrir la DB de herramientas" -#: flatcamGUI/FlatCAMGUI.py:1613 +#: flatcamGUI/FlatCAMGUI.py:1714 msgid "Open Excellon File" msgstr "Abierto Excellon" -#: flatcamGUI/FlatCAMGUI.py:1613 +#: flatcamGUI/FlatCAMGUI.py:1714 msgid "Open Gerber File" msgstr "Abrir Gerber" -#: flatcamGUI/FlatCAMGUI.py:1613 +#: flatcamGUI/FlatCAMGUI.py:1714 msgid "New Project" msgstr "Nuevo Proyecto" -#: flatcamGUI/FlatCAMGUI.py:1614 flatcamTools/ToolPDF.py:42 +#: flatcamGUI/FlatCAMGUI.py:1715 flatcamTools/ToolPDF.py:42 msgid "PDF Import Tool" msgstr "Herramienta de Importación de PDF" -#: flatcamGUI/FlatCAMGUI.py:1614 -msgid "Save Project As" -msgstr "Guardar proyecto como" +#: flatcamGUI/FlatCAMGUI.py:1715 +msgid "Save Project" +msgstr "Guardar proyecto" -#: flatcamGUI/FlatCAMGUI.py:1614 +#: flatcamGUI/FlatCAMGUI.py:1715 msgid "Toggle Plot Area" msgstr "Alternar área de la parcela" -#: flatcamGUI/FlatCAMGUI.py:1617 +#: flatcamGUI/FlatCAMGUI.py:1718 msgid "Copy Obj_Name" msgstr "Copiar Nombre Obj" -#: flatcamGUI/FlatCAMGUI.py:1618 +#: flatcamGUI/FlatCAMGUI.py:1719 msgid "Toggle Code Editor" msgstr "Alternar editor de código" -#: flatcamGUI/FlatCAMGUI.py:1618 +#: flatcamGUI/FlatCAMGUI.py:1719 msgid "Toggle the axis" msgstr "Alternar el eje" -#: flatcamGUI/FlatCAMGUI.py:1618 flatcamGUI/FlatCAMGUI.py:1810 -#: flatcamGUI/FlatCAMGUI.py:1897 flatcamGUI/FlatCAMGUI.py:2019 +#: flatcamGUI/FlatCAMGUI.py:1719 flatcamGUI/FlatCAMGUI.py:1918 +#: flatcamGUI/FlatCAMGUI.py:2005 flatcamGUI/FlatCAMGUI.py:2127 msgid "Distance Minimum Tool" msgstr "Herramienta de Distancia Mínima" -#: flatcamGUI/FlatCAMGUI.py:1618 +#: flatcamGUI/FlatCAMGUI.py:1720 msgid "Open Preferences Window" msgstr "Abrir ventana de Preferencias" -#: flatcamGUI/FlatCAMGUI.py:1619 +#: flatcamGUI/FlatCAMGUI.py:1721 msgid "Rotate by 90 degree CCW" msgstr "Rotar en 90 grados CCW" -#: flatcamGUI/FlatCAMGUI.py:1619 +#: flatcamGUI/FlatCAMGUI.py:1721 msgid "Run a Script" msgstr "Ejecutar script TCL" -#: flatcamGUI/FlatCAMGUI.py:1619 +#: flatcamGUI/FlatCAMGUI.py:1721 msgid "Toggle the workspace" msgstr "Alternar espacio de trabajo" -#: flatcamGUI/FlatCAMGUI.py:1619 +#: flatcamGUI/FlatCAMGUI.py:1721 msgid "Skew on X axis" msgstr "Sesgar en el eje X" -#: flatcamGUI/FlatCAMGUI.py:1620 +#: flatcamGUI/FlatCAMGUI.py:1722 msgid "Skew on Y axis" msgstr "Sesgar en el eje Y" -#: flatcamGUI/FlatCAMGUI.py:1622 +#: flatcamGUI/FlatCAMGUI.py:1725 msgid "2-Sided PCB Tool" msgstr "Herra. de 2 lados" -#: flatcamGUI/FlatCAMGUI.py:1622 +#: flatcamGUI/FlatCAMGUI.py:1725 msgid "Transformations Tool" msgstr "Herramienta de Transformaciones" -#: flatcamGUI/FlatCAMGUI.py:1623 +#: flatcamGUI/FlatCAMGUI.py:1727 msgid "Solder Paste Dispensing Tool" msgstr "Herramienta de Dispensación de Pasta" -#: flatcamGUI/FlatCAMGUI.py:1624 +#: flatcamGUI/FlatCAMGUI.py:1728 msgid "Film PCB Tool" msgstr "Herramienta de Película" -#: flatcamGUI/FlatCAMGUI.py:1624 +#: flatcamGUI/FlatCAMGUI.py:1728 msgid "Non-Copper Clearing Tool" msgstr "Herramienta de Limpieza Sin Cobre" -#: flatcamGUI/FlatCAMGUI.py:1625 +#: flatcamGUI/FlatCAMGUI.py:1729 msgid "Paint Area Tool" msgstr "Herramienta de Area de Pintura" -#: flatcamGUI/FlatCAMGUI.py:1625 +#: flatcamGUI/FlatCAMGUI.py:1729 msgid "Rules Check Tool" msgstr "Herramienta de Verificación de Reglas" -#: flatcamGUI/FlatCAMGUI.py:1626 +#: flatcamGUI/FlatCAMGUI.py:1730 msgid "View File Source" msgstr "Ver fuente del archivo" -#: flatcamGUI/FlatCAMGUI.py:1627 +#: flatcamGUI/FlatCAMGUI.py:1731 msgid "Cutout PCB Tool" msgstr "Herra. de Corte" -#: flatcamGUI/FlatCAMGUI.py:1627 +#: flatcamGUI/FlatCAMGUI.py:1731 msgid "Enable all Plots" msgstr "Habilitar todas las parcelas" -#: flatcamGUI/FlatCAMGUI.py:1627 +#: flatcamGUI/FlatCAMGUI.py:1731 msgid "Disable all Plots" msgstr "Deshabilitar todas las parcelas" -#: flatcamGUI/FlatCAMGUI.py:1627 +#: flatcamGUI/FlatCAMGUI.py:1731 msgid "Disable Non-selected Plots" msgstr "Deshabilitar no seleccionado" -#: flatcamGUI/FlatCAMGUI.py:1628 +#: flatcamGUI/FlatCAMGUI.py:1732 msgid "Toggle Full Screen" msgstr "Alternar pantalla completa" -#: flatcamGUI/FlatCAMGUI.py:1631 +#: flatcamGUI/FlatCAMGUI.py:1735 msgid "Abort current task (gracefully)" msgstr "Abortar la tarea actual (con gracia)" -#: flatcamGUI/FlatCAMGUI.py:1634 +#: flatcamGUI/FlatCAMGUI.py:1738 +msgid "Save Project As" +msgstr "Guardar proyecto como" + +#: flatcamGUI/FlatCAMGUI.py:1739 +msgid "" +"Paste Special. Will convert a Windows path style to the one required in Tcl " +"Shell" +msgstr "" +"Pegado especial. Convertirá un estilo de ruta de Windows al requerido en Tcl " +"Shell" + +#: flatcamGUI/FlatCAMGUI.py:1742 msgid "Open Online Manual" msgstr "Abrir el manual en línea" -#: flatcamGUI/FlatCAMGUI.py:1635 +#: flatcamGUI/FlatCAMGUI.py:1743 msgid "Open Online Tutorials" msgstr "Abrir tutoriales en online" -#: flatcamGUI/FlatCAMGUI.py:1635 +#: flatcamGUI/FlatCAMGUI.py:1743 msgid "Refresh Plots" msgstr "Actualizar parcelas" -#: flatcamGUI/FlatCAMGUI.py:1635 flatcamTools/ToolSolderPaste.py:503 +#: flatcamGUI/FlatCAMGUI.py:1743 flatcamTools/ToolSolderPaste.py:509 msgid "Delete Object" msgstr "Eliminar objeto" -#: flatcamGUI/FlatCAMGUI.py:1635 +#: flatcamGUI/FlatCAMGUI.py:1743 msgid "Alternate: Delete Tool" msgstr "Alt.: Eliminar herramienta" -#: flatcamGUI/FlatCAMGUI.py:1636 +#: flatcamGUI/FlatCAMGUI.py:1744 msgid "(left to Key_1)Toogle Notebook Area (Left Side)" msgstr "(izquierda a Key_1) Área de Toogle Notebook (lado izquierdo)" -#: flatcamGUI/FlatCAMGUI.py:1636 +#: flatcamGUI/FlatCAMGUI.py:1744 msgid "En(Dis)able Obj Plot" msgstr "(Des)habilitar trazado Obj" -#: flatcamGUI/FlatCAMGUI.py:1637 +#: flatcamGUI/FlatCAMGUI.py:1745 msgid "Deselects all objects" msgstr "Desel. todos los objetos" -#: flatcamGUI/FlatCAMGUI.py:1651 +#: flatcamGUI/FlatCAMGUI.py:1759 msgid "Editor Shortcut list" msgstr "Lista de accesos directos del editor" -#: flatcamGUI/FlatCAMGUI.py:1805 +#: flatcamGUI/FlatCAMGUI.py:1913 msgid "GEOMETRY EDITOR" msgstr "EDITOR DE GEOMETRÍA" -#: flatcamGUI/FlatCAMGUI.py:1805 +#: flatcamGUI/FlatCAMGUI.py:1913 msgid "Draw an Arc" msgstr "Dibujar un arco" -#: flatcamGUI/FlatCAMGUI.py:1805 +#: flatcamGUI/FlatCAMGUI.py:1913 msgid "Copy Geo Item" msgstr "Copia Geo" -#: flatcamGUI/FlatCAMGUI.py:1806 +#: flatcamGUI/FlatCAMGUI.py:1914 msgid "Within Add Arc will toogle the ARC direction: CW or CCW" msgstr "Dentro de agregar arco alternará la dirección del ARCO: CW o CCW" -#: flatcamGUI/FlatCAMGUI.py:1806 +#: flatcamGUI/FlatCAMGUI.py:1914 msgid "Polygon Intersection Tool" msgstr "Herram. de Intersección Poli" -#: flatcamGUI/FlatCAMGUI.py:1807 +#: flatcamGUI/FlatCAMGUI.py:1915 msgid "Geo Paint Tool" msgstr "Herram. de pintura geo" -#: flatcamGUI/FlatCAMGUI.py:1807 flatcamGUI/FlatCAMGUI.py:1896 -#: flatcamGUI/FlatCAMGUI.py:2016 +#: flatcamGUI/FlatCAMGUI.py:1915 flatcamGUI/FlatCAMGUI.py:2004 +#: flatcamGUI/FlatCAMGUI.py:2124 msgid "Jump to Location (x, y)" msgstr "Saltar a la ubicación (x, y)" -#: flatcamGUI/FlatCAMGUI.py:1807 +#: flatcamGUI/FlatCAMGUI.py:1915 msgid "Toggle Corner Snap" msgstr "Alternar ajuste de esquina" -#: flatcamGUI/FlatCAMGUI.py:1807 +#: flatcamGUI/FlatCAMGUI.py:1915 msgid "Move Geo Item" msgstr "Mover elemento geo" -#: flatcamGUI/FlatCAMGUI.py:1808 +#: flatcamGUI/FlatCAMGUI.py:1916 msgid "Within Add Arc will cycle through the ARC modes" msgstr "Dentro de agregar arco, pasará por los modos de arco" -#: flatcamGUI/FlatCAMGUI.py:1808 +#: flatcamGUI/FlatCAMGUI.py:1916 msgid "Draw a Polygon" msgstr "Dibujar un polígono" -#: flatcamGUI/FlatCAMGUI.py:1808 +#: flatcamGUI/FlatCAMGUI.py:1916 msgid "Draw a Circle" msgstr "Dibuja un circulo" -#: flatcamGUI/FlatCAMGUI.py:1809 +#: flatcamGUI/FlatCAMGUI.py:1917 msgid "Draw a Path" msgstr "Dibujar un camino" -#: flatcamGUI/FlatCAMGUI.py:1809 +#: flatcamGUI/FlatCAMGUI.py:1917 msgid "Draw Rectangle" msgstr "Dibujar rectángulo" -#: flatcamGUI/FlatCAMGUI.py:1809 +#: flatcamGUI/FlatCAMGUI.py:1917 msgid "Polygon Subtraction Tool" msgstr "Herram. de Sustrac. de Polí" -#: flatcamGUI/FlatCAMGUI.py:1809 +#: flatcamGUI/FlatCAMGUI.py:1917 msgid "Add Text Tool" msgstr "Herramienta de Texto" -#: flatcamGUI/FlatCAMGUI.py:1810 +#: flatcamGUI/FlatCAMGUI.py:1918 msgid "Polygon Union Tool" msgstr "Herram. de Unión Poli" -#: flatcamGUI/FlatCAMGUI.py:1810 +#: flatcamGUI/FlatCAMGUI.py:1918 msgid "Flip shape on X axis" msgstr "Voltear en el eje X" -#: flatcamGUI/FlatCAMGUI.py:1810 +#: flatcamGUI/FlatCAMGUI.py:1918 msgid "Flip shape on Y axis" msgstr "Voltear en el eje Y" -#: flatcamGUI/FlatCAMGUI.py:1811 +#: flatcamGUI/FlatCAMGUI.py:1919 msgid "Skew shape on X axis" msgstr "Sesgar en el eje X" -#: flatcamGUI/FlatCAMGUI.py:1811 +#: flatcamGUI/FlatCAMGUI.py:1919 msgid "Skew shape on Y axis" msgstr "Sesgar en el eje Y" -#: flatcamGUI/FlatCAMGUI.py:1811 +#: flatcamGUI/FlatCAMGUI.py:1919 msgid "Editor Transformation Tool" msgstr "Herram. de transform. del editor" -#: flatcamGUI/FlatCAMGUI.py:1812 +#: flatcamGUI/FlatCAMGUI.py:1920 msgid "Offset shape on X axis" msgstr "Offset en el eje X" -#: flatcamGUI/FlatCAMGUI.py:1812 +#: flatcamGUI/FlatCAMGUI.py:1920 msgid "Offset shape on Y axis" msgstr "Offset en eje Y" -#: flatcamGUI/FlatCAMGUI.py:1813 flatcamGUI/FlatCAMGUI.py:1899 -#: flatcamGUI/FlatCAMGUI.py:2021 +#: flatcamGUI/FlatCAMGUI.py:1921 flatcamGUI/FlatCAMGUI.py:2007 +#: flatcamGUI/FlatCAMGUI.py:2129 msgid "Save Object and Exit Editor" msgstr "Guardar objeto y salir del editor" -#: flatcamGUI/FlatCAMGUI.py:1813 +#: flatcamGUI/FlatCAMGUI.py:1921 msgid "Polygon Cut Tool" msgstr "Herram. de Corte Poli" -#: flatcamGUI/FlatCAMGUI.py:1814 +#: flatcamGUI/FlatCAMGUI.py:1922 msgid "Rotate Geometry" msgstr "Rotar Geometría" -#: flatcamGUI/FlatCAMGUI.py:1814 +#: flatcamGUI/FlatCAMGUI.py:1922 msgid "Finish drawing for certain tools" msgstr "Terminar el dibujo de ciertas herramientas" -#: flatcamGUI/FlatCAMGUI.py:1814 flatcamGUI/FlatCAMGUI.py:1899 -#: flatcamGUI/FlatCAMGUI.py:2019 +#: flatcamGUI/FlatCAMGUI.py:1922 flatcamGUI/FlatCAMGUI.py:2007 +#: flatcamGUI/FlatCAMGUI.py:2127 msgid "Abort and return to Select" msgstr "Anular y volver a Seleccionar" -#: flatcamGUI/FlatCAMGUI.py:1815 flatcamGUI/FlatCAMGUI.py:2518 +#: flatcamGUI/FlatCAMGUI.py:1923 flatcamGUI/FlatCAMGUI.py:2690 msgid "Delete Shape" msgstr "Eliminar forma" -#: flatcamGUI/FlatCAMGUI.py:1895 +#: flatcamGUI/FlatCAMGUI.py:2003 msgid "EXCELLON EDITOR" msgstr "EDITOR DE EXCELLON" -#: flatcamGUI/FlatCAMGUI.py:1895 +#: flatcamGUI/FlatCAMGUI.py:2003 msgid "Copy Drill(s)" msgstr "Copia de taladro" -#: flatcamGUI/FlatCAMGUI.py:1895 flatcamGUI/FlatCAMGUI.py:2145 +#: flatcamGUI/FlatCAMGUI.py:2003 flatcamGUI/FlatCAMGUI.py:2253 msgid "Add Drill" msgstr "Añadir taladro" -#: flatcamGUI/FlatCAMGUI.py:1896 +#: flatcamGUI/FlatCAMGUI.py:2004 msgid "Move Drill(s)" msgstr "Mover taladro(s)" -#: flatcamGUI/FlatCAMGUI.py:1897 +#: flatcamGUI/FlatCAMGUI.py:2005 msgid "Add a new Tool" msgstr "Agregar una nueva herram" -#: flatcamGUI/FlatCAMGUI.py:1898 +#: flatcamGUI/FlatCAMGUI.py:2006 msgid "Delete Drill(s)" msgstr "Eliminar Taladro" -#: flatcamGUI/FlatCAMGUI.py:1898 +#: flatcamGUI/FlatCAMGUI.py:2006 msgid "Alternate: Delete Tool(s)" msgstr "Alt.: Eliminar herramienta (s)" -#: flatcamGUI/FlatCAMGUI.py:2015 +#: flatcamGUI/FlatCAMGUI.py:2123 msgid "GERBER EDITOR" msgstr "EDITOR GERBER" -#: flatcamGUI/FlatCAMGUI.py:2015 +#: flatcamGUI/FlatCAMGUI.py:2123 msgid "Add Disc" msgstr "Agregar disco" -#: flatcamGUI/FlatCAMGUI.py:2015 +#: flatcamGUI/FlatCAMGUI.py:2123 msgid "Add SemiDisc" msgstr "Añadir medio disco" -#: flatcamGUI/FlatCAMGUI.py:2017 +#: flatcamGUI/FlatCAMGUI.py:2125 msgid "Within Track & Region Tools will cycle in REVERSE the bend modes" msgstr "" "Dentro de la Pista y la Región, las herram.s alternarán en REVERSA los modos " "de plegado" -#: flatcamGUI/FlatCAMGUI.py:2018 +#: flatcamGUI/FlatCAMGUI.py:2126 msgid "Within Track & Region Tools will cycle FORWARD the bend modes" msgstr "" "Dentro de la Pista y la Región, las herram. avanzarán hacia adelante los " "modos de plegado" -#: flatcamGUI/FlatCAMGUI.py:2019 +#: flatcamGUI/FlatCAMGUI.py:2127 msgid "Alternate: Delete Apertures" msgstr "Alt.: Eliminar Aperturas" -#: flatcamGUI/FlatCAMGUI.py:2020 +#: flatcamGUI/FlatCAMGUI.py:2128 msgid "Eraser Tool" msgstr "Herramienta borrador" -#: flatcamGUI/FlatCAMGUI.py:2021 flatcamGUI/PreferencesUI.py:2634 +#: flatcamGUI/FlatCAMGUI.py:2129 flatcamGUI/PreferencesUI.py:2816 msgid "Mark Area Tool" msgstr "Herram. de Zona de Marca" -#: flatcamGUI/FlatCAMGUI.py:2021 +#: flatcamGUI/FlatCAMGUI.py:2129 msgid "Poligonize Tool" msgstr "Herram. de poligonización" -#: flatcamGUI/FlatCAMGUI.py:2021 +#: flatcamGUI/FlatCAMGUI.py:2129 msgid "Transformation Tool" msgstr "Herramienta de Transformación" -#: flatcamGUI/FlatCAMGUI.py:2038 +#: flatcamGUI/FlatCAMGUI.py:2146 msgid "Toggle Visibility" msgstr "Alternar visibilidad" -#: flatcamGUI/FlatCAMGUI.py:2044 +#: flatcamGUI/FlatCAMGUI.py:2152 msgid "New" msgstr "Nueva" -#: flatcamGUI/FlatCAMGUI.py:2046 flatcamTools/ToolCalibration.py:634 -msgid "Geometry" -msgstr "Geometría" - -#: flatcamGUI/FlatCAMGUI.py:2050 flatcamTools/ToolCalibration.py:197 -#: flatcamTools/ToolCalibration.py:634 flatcamTools/ToolFilm.py:359 +#: flatcamGUI/FlatCAMGUI.py:2158 flatcamGUI/PreferencesUI.py:8410 +#: flatcamTools/ToolAlignObjects.py:74 flatcamTools/ToolAlignObjects.py:110 +#: flatcamTools/ToolCalibration.py:197 flatcamTools/ToolCalibration.py:631 +#: flatcamTools/ToolCalibration.py:648 flatcamTools/ToolCalibration.py:807 +#: flatcamTools/ToolCalibration.py:815 flatcamTools/ToolCopperThieving.py:145 +#: flatcamTools/ToolCopperThieving.py:159 +#: flatcamTools/ToolCopperThieving.py:605 flatcamTools/ToolDblSided.py:226 +#: flatcamTools/ToolFilm.py:359 flatcamTools/ToolNCC.py:558 +#: flatcamTools/ToolNCC.py:1295 flatcamTools/ToolPaint.py:502 +#: flatcamTools/ToolPaint.py:706 flatcamTools/ToolPanelize.py:374 +#: flatcamTools/ToolPunchGerber.py:149 flatcamTools/ToolPunchGerber.py:164 msgid "Excellon" msgstr "Excellon" -#: flatcamGUI/FlatCAMGUI.py:2057 +#: flatcamGUI/FlatCAMGUI.py:2165 msgid "Grids" msgstr "Rejillas" -#: flatcamGUI/FlatCAMGUI.py:2064 +#: flatcamGUI/FlatCAMGUI.py:2172 msgid "Clear Plot" msgstr "Parcela clara" -#: flatcamGUI/FlatCAMGUI.py:2066 +#: flatcamGUI/FlatCAMGUI.py:2174 msgid "Replot" msgstr "Replantear" -#: flatcamGUI/FlatCAMGUI.py:2070 +#: flatcamGUI/FlatCAMGUI.py:2178 msgid "Geo Editor" msgstr "Geo Editor" -#: flatcamGUI/FlatCAMGUI.py:2072 +#: flatcamGUI/FlatCAMGUI.py:2180 msgid "Path" msgstr "Ruta" -#: flatcamGUI/FlatCAMGUI.py:2074 +#: flatcamGUI/FlatCAMGUI.py:2182 msgid "Rectangle" msgstr "Rectángulo" -#: flatcamGUI/FlatCAMGUI.py:2077 +#: flatcamGUI/FlatCAMGUI.py:2185 msgid "Circle" msgstr "Círculo" -#: flatcamGUI/FlatCAMGUI.py:2079 -msgid "Polygon" -msgstr "Polígono" - -#: flatcamGUI/FlatCAMGUI.py:2081 +#: flatcamGUI/FlatCAMGUI.py:2189 msgid "Arc" msgstr "Arco" -#: flatcamGUI/FlatCAMGUI.py:2095 +#: flatcamGUI/FlatCAMGUI.py:2203 msgid "Union" msgstr "Unión" -#: flatcamGUI/FlatCAMGUI.py:2097 +#: flatcamGUI/FlatCAMGUI.py:2205 msgid "Intersection" msgstr "Intersección" -#: flatcamGUI/FlatCAMGUI.py:2099 +#: flatcamGUI/FlatCAMGUI.py:2207 msgid "Subtraction" msgstr "Sustracción" -#: flatcamGUI/FlatCAMGUI.py:2101 flatcamGUI/ObjectUI.py:1811 -#: flatcamGUI/PreferencesUI.py:4421 +#: flatcamGUI/FlatCAMGUI.py:2209 flatcamGUI/ObjectUI.py:2139 +#: flatcamGUI/PreferencesUI.py:4714 msgid "Cut" msgstr "Cortar" -#: flatcamGUI/FlatCAMGUI.py:2112 +#: flatcamGUI/FlatCAMGUI.py:2220 msgid "Pad" msgstr "Pad" -#: flatcamGUI/FlatCAMGUI.py:2114 +#: flatcamGUI/FlatCAMGUI.py:2222 msgid "Pad Array" msgstr "Matriz de Pad" -#: flatcamGUI/FlatCAMGUI.py:2118 +#: flatcamGUI/FlatCAMGUI.py:2226 msgid "Track" msgstr "Pista" -#: flatcamGUI/FlatCAMGUI.py:2120 +#: flatcamGUI/FlatCAMGUI.py:2228 msgid "Region" msgstr "Región" -#: flatcamGUI/FlatCAMGUI.py:2143 +#: flatcamGUI/FlatCAMGUI.py:2251 msgid "Exc Editor" msgstr "Exc Editor" -#: flatcamGUI/FlatCAMGUI.py:2188 +#: flatcamGUI/FlatCAMGUI.py:2296 msgid "" "Relative neasurement.\n" "Reference is last click position" @@ -6929,7 +7277,7 @@ msgstr "" "Medida relativa.\n" "La referencia es la posición del último clic" -#: flatcamGUI/FlatCAMGUI.py:2194 +#: flatcamGUI/FlatCAMGUI.py:2302 msgid "" "Absolute neasurement.\n" "Reference is (X=0, Y= 0) position" @@ -6937,27 +7285,35 @@ msgstr "" "Medida absoluta.\n" "La referencia es (X = 0, Y = 0) posición" -#: flatcamGUI/FlatCAMGUI.py:2301 +#: flatcamGUI/FlatCAMGUI.py:2406 msgid "Lock Toolbars" msgstr "Bloquear barras de herram" -#: flatcamGUI/FlatCAMGUI.py:2419 +#: flatcamGUI/FlatCAMGUI.py:2465 +msgid "FlatCAM Preferences Folder opened." +msgstr "Carpeta de preferencias de FlatCAM abierta." + +#: flatcamGUI/FlatCAMGUI.py:2476 +msgid "Are you sure you want to delete the GUI Settings? \n" +msgstr "¿Está seguro de que desea eliminar la configuración de la GUI?\n" + +#: flatcamGUI/FlatCAMGUI.py:2584 msgid "&Cutout Tool" msgstr "Herramienta de recorte" -#: flatcamGUI/FlatCAMGUI.py:2478 +#: flatcamGUI/FlatCAMGUI.py:2650 msgid "Select 'Esc'" msgstr "Selecciona 'Esc'" -#: flatcamGUI/FlatCAMGUI.py:2516 +#: flatcamGUI/FlatCAMGUI.py:2688 msgid "Copy Objects" msgstr "Copiar objetos" -#: flatcamGUI/FlatCAMGUI.py:2524 +#: flatcamGUI/FlatCAMGUI.py:2696 msgid "Move Objects" msgstr "Mover objetos" -#: flatcamGUI/FlatCAMGUI.py:3087 +#: flatcamGUI/FlatCAMGUI.py:3312 msgid "" "Please first select a geometry item to be cutted\n" "then select the geometry item that will be cutted\n" @@ -6969,12 +7325,12 @@ msgstr "" "fuera del primer artículo. Al final presione la tecla ~ X ~ o\n" "el botón de la barra de herramientas." -#: flatcamGUI/FlatCAMGUI.py:3094 flatcamGUI/FlatCAMGUI.py:3254 -#: flatcamGUI/FlatCAMGUI.py:3299 flatcamGUI/FlatCAMGUI.py:3319 +#: flatcamGUI/FlatCAMGUI.py:3319 flatcamGUI/FlatCAMGUI.py:3478 +#: flatcamGUI/FlatCAMGUI.py:3523 flatcamGUI/FlatCAMGUI.py:3543 msgid "Warning" msgstr "Advertencia" -#: flatcamGUI/FlatCAMGUI.py:3249 +#: flatcamGUI/FlatCAMGUI.py:3473 msgid "" "Please select geometry items \n" "on which to perform Intersection Tool." @@ -6982,7 +7338,7 @@ msgstr "" "Por favor seleccione elementos de geometría\n" "en el que realizar Herramienta de Intersección." -#: flatcamGUI/FlatCAMGUI.py:3294 +#: flatcamGUI/FlatCAMGUI.py:3518 msgid "" "Please select geometry items \n" "on which to perform Substraction Tool." @@ -6990,7 +7346,7 @@ msgstr "" "Por favor seleccione elementos de geometría\n" "en el que realizar la Herramienta de Substracción." -#: flatcamGUI/FlatCAMGUI.py:3314 +#: flatcamGUI/FlatCAMGUI.py:3538 msgid "" "Please select geometry items \n" "on which to perform union." @@ -6998,61 +7354,62 @@ msgstr "" "Por favor seleccione elementos de geometría\n" "en el que realizar la Unión." -#: flatcamGUI/FlatCAMGUI.py:3394 flatcamGUI/FlatCAMGUI.py:3608 +#: flatcamGUI/FlatCAMGUI.py:3617 flatcamGUI/FlatCAMGUI.py:3828 msgid "Cancelled. Nothing selected to delete." msgstr "Cancelado. Nada seleccionado para eliminar." -#: flatcamGUI/FlatCAMGUI.py:3479 flatcamGUI/FlatCAMGUI.py:3726 +#: flatcamGUI/FlatCAMGUI.py:3701 flatcamGUI/FlatCAMGUI.py:3944 msgid "Cancelled. Nothing selected to copy." msgstr "Cancelado. Nada seleccionado para copiar." -#: flatcamGUI/FlatCAMGUI.py:3526 flatcamGUI/FlatCAMGUI.py:3756 +#: flatcamGUI/FlatCAMGUI.py:3747 flatcamGUI/FlatCAMGUI.py:3973 msgid "Cancelled. Nothing selected to move." msgstr "Cancelado. Nada seleccionado para moverse." -#: flatcamGUI/FlatCAMGUI.py:3782 +#: flatcamGUI/FlatCAMGUI.py:3999 msgid "New Tool ..." msgstr "Nueva herramienta ..." -#: flatcamGUI/FlatCAMGUI.py:3783 flatcamTools/ToolNonCopperClear.py:583 -#: flatcamTools/ToolPaint.py:494 flatcamTools/ToolSolderPaste.py:554 +#: flatcamGUI/FlatCAMGUI.py:4000 flatcamTools/ToolNCC.py:924 +#: flatcamTools/ToolPaint.py:850 flatcamTools/ToolSolderPaste.py:560 msgid "Enter a Tool Diameter" msgstr "Introduzca un diá. de herram" -#: flatcamGUI/FlatCAMGUI.py:3795 +#: flatcamGUI/FlatCAMGUI.py:4012 msgid "Adding Tool cancelled ..." msgstr "Añadiendo herramienta cancelada ..." -#: flatcamGUI/FlatCAMGUI.py:3808 +#: flatcamGUI/FlatCAMGUI.py:4025 msgid "Distance Tool exit..." msgstr "Salida de Herramienta de Distancia ..." -#: flatcamGUI/FlatCAMGUI.py:4018 flatcamGUI/FlatCAMGUI.py:4025 +#: flatcamGUI/FlatCAMGUI.py:4234 flatcamGUI/FlatCAMGUI.py:4241 msgid "Idle." msgstr "Ocioso." -#: flatcamGUI/FlatCAMGUI.py:4056 +#: flatcamGUI/FlatCAMGUI.py:4272 msgid "Application started ..." msgstr "Aplicacion iniciada ..." -#: flatcamGUI/FlatCAMGUI.py:4057 +#: flatcamGUI/FlatCAMGUI.py:4273 msgid "Hello!" msgstr "¡Hola!" -#: flatcamGUI/FlatCAMGUI.py:4115 +#: flatcamGUI/FlatCAMGUI.py:4331 msgid "Open Project ..." msgstr "Proyecto abierto ...Abierto &Project ..." -#: flatcamGUI/FlatCAMGUI.py:4141 +#: flatcamGUI/FlatCAMGUI.py:4357 msgid "Exit" msgstr "Salida" -#: flatcamGUI/GUIElements.py:2261 flatcamGUI/PreferencesUI.py:5265 -#: flatcamGUI/PreferencesUI.py:5825 flatcamTools/ToolFilm.py:219 +#: flatcamGUI/GUIElements.py:2513 flatcamGUI/PreferencesUI.py:6313 +#: flatcamTools/ToolDblSided.py:174 flatcamTools/ToolDblSided.py:389 +#: flatcamTools/ToolFilm.py:219 msgid "Reference" msgstr "Referencia" -#: flatcamGUI/GUIElements.py:2263 +#: flatcamGUI/GUIElements.py:2515 msgid "" "The reference can be:\n" "- Absolute -> the reference point is point (0,0)\n" @@ -7062,19 +7419,19 @@ msgstr "" "- Absoluto -> el punto de referencia es el punto (0,0)\n" "- Relativo -> el punto de referencia es la posición del mouse antes de Jump" -#: flatcamGUI/GUIElements.py:2268 +#: flatcamGUI/GUIElements.py:2520 msgid "Abs" msgstr "Abs" -#: flatcamGUI/GUIElements.py:2269 +#: flatcamGUI/GUIElements.py:2521 msgid "Relative" msgstr "Relativo" -#: flatcamGUI/GUIElements.py:2279 +#: flatcamGUI/GUIElements.py:2531 msgid "Location" msgstr "Ubicación" -#: flatcamGUI/GUIElements.py:2281 +#: flatcamGUI/GUIElements.py:2533 msgid "" "The Location value is a tuple (x,y).\n" "If the reference is Absolute then the Jump will be at the position (x,y).\n" @@ -7088,6 +7445,10 @@ msgstr "" "y)\n" "desde el punto de ubicación actual del mouse." +#: flatcamGUI/GUIElements.py:2573 +msgid "Save Log" +msgstr "Guardar Registro" + #: flatcamGUI/ObjectUI.py:38 msgid "FlatCAM Object" msgstr "Objeto FlatCAM" @@ -7110,15 +7471,11 @@ msgstr "" "Editar -> Preferencias -> General y verificar:\n" "'APP. NIVEL 'botón de radio." -#: flatcamGUI/ObjectUI.py:105 -msgid "Change the size of the object." -msgstr "Cambiar el tamaño del objeto." +#: flatcamGUI/ObjectUI.py:110 +msgid "Geometrical transformations of the current object." +msgstr "Transformaciones geométricas del objeto actual." -#: flatcamGUI/ObjectUI.py:111 -msgid "Factor" -msgstr "Factor" - -#: flatcamGUI/ObjectUI.py:113 +#: flatcamGUI/ObjectUI.py:119 msgid "" "Factor by which to multiply\n" "geometric features of this object.\n" @@ -7128,19 +7485,11 @@ msgstr "" "características geométricas de este objeto.\n" "Se permiten expresiones. Por ejemplo: 1 / 25.4" -#: flatcamGUI/ObjectUI.py:123 +#: flatcamGUI/ObjectUI.py:126 msgid "Perform scaling operation." msgstr "Realizar la operación de escalado." -#: flatcamGUI/ObjectUI.py:134 -msgid "Change the position of this object." -msgstr "Cambia la posición de este objeto." - -#: flatcamGUI/ObjectUI.py:139 -msgid "Vector" -msgstr "Vector" - -#: flatcamGUI/ObjectUI.py:141 +#: flatcamGUI/ObjectUI.py:137 msgid "" "Amount by which to move the object\n" "in the x and y axes in (x, y) format.\n" @@ -7150,60 +7499,53 @@ msgstr "" "en los ejes x e y en formato (x, y).\n" "Se permiten expresiones. Por ejemplo: (1/3.2, 0.5*3)" -#: flatcamGUI/ObjectUI.py:150 +#: flatcamGUI/ObjectUI.py:144 msgid "Perform the offset operation." msgstr "Realice la operación de desplazamiento." -#: flatcamGUI/ObjectUI.py:167 +#: flatcamGUI/ObjectUI.py:177 msgid "Gerber Object" msgstr "Objeto Gerber" -#: flatcamGUI/ObjectUI.py:182 flatcamGUI/ObjectUI.py:767 -#: flatcamGUI/ObjectUI.py:1205 flatcamGUI/ObjectUI.py:1905 -#: flatcamGUI/PreferencesUI.py:1783 flatcamGUI/PreferencesUI.py:3849 -#: flatcamGUI/PreferencesUI.py:4406 -msgid "Plot (show) this object." -msgstr "Trazar (mostrar) este objeto." - -#: flatcamGUI/ObjectUI.py:184 flatcamGUI/ObjectUI.py:765 -#: flatcamGUI/PreferencesUI.py:1781 flatcamGUI/PreferencesUI.py:2680 -#: flatcamGUI/PreferencesUI.py:3847 -msgid "Plot" -msgstr "Gráfico" - -#: flatcamGUI/ObjectUI.py:189 flatcamGUI/ObjectUI.py:726 -#: flatcamGUI/ObjectUI.py:1159 flatcamGUI/ObjectUI.py:1795 -#: flatcamGUI/PreferencesUI.py:1760 flatcamGUI/PreferencesUI.py:2674 -#: flatcamGUI/PreferencesUI.py:3843 flatcamGUI/PreferencesUI.py:4395 +#: flatcamGUI/ObjectUI.py:186 flatcamGUI/ObjectUI.py:729 +#: flatcamGUI/ObjectUI.py:1424 flatcamGUI/ObjectUI.py:2123 +#: flatcamGUI/PreferencesUI.py:1940 flatcamGUI/PreferencesUI.py:2856 +#: flatcamGUI/PreferencesUI.py:4121 flatcamGUI/PreferencesUI.py:4688 msgid "Plot Options" msgstr "Opciones de parcela" -#: flatcamGUI/ObjectUI.py:195 flatcamGUI/ObjectUI.py:727 -#: flatcamGUI/PreferencesUI.py:1767 flatcamGUI/PreferencesUI.py:2686 -#: flatcamGUI/PreferencesUI.py:7222 flatcamTools/ToolCopperThieving.py:190 +#: flatcamGUI/ObjectUI.py:192 flatcamGUI/ObjectUI.py:730 +#: flatcamGUI/PreferencesUI.py:1947 flatcamGUI/PreferencesUI.py:2868 +#: flatcamGUI/PreferencesUI.py:7728 flatcamTools/ToolCopperThieving.py:192 msgid "Solid" msgstr "Sólido" -#: flatcamGUI/ObjectUI.py:197 flatcamGUI/PreferencesUI.py:1769 +#: flatcamGUI/ObjectUI.py:194 flatcamGUI/PreferencesUI.py:1949 msgid "Solid color polygons." msgstr "Polígonos de color liso." -#: flatcamGUI/ObjectUI.py:203 +#: flatcamGUI/ObjectUI.py:200 msgid "Multi-Color" msgstr "Multicolor" -#: flatcamGUI/ObjectUI.py:205 flatcamGUI/PreferencesUI.py:1776 +#: flatcamGUI/ObjectUI.py:202 flatcamGUI/PreferencesUI.py:1956 msgid "Draw polygons in different colors." msgstr "Dibuja polígonos en diferentes colores." -#: flatcamGUI/ObjectUI.py:213 flatcamGUI/ObjectUI.py:738 -#: flatcamGUI/ObjectUI.py:1165 flatcamGUI/ObjectUI.py:1825 -#: flatcamGUI/ObjectUI.py:2128 flatcamGUI/ObjectUI.py:2194 -#: flatcamTools/ToolCalibration.py:235 flatcamTools/ToolFiducials.py:73 -msgid "Name" -msgstr "Nombre" +#: flatcamGUI/ObjectUI.py:208 flatcamGUI/ObjectUI.py:768 +#: flatcamGUI/PreferencesUI.py:1961 flatcamGUI/PreferencesUI.py:2862 +#: flatcamGUI/PreferencesUI.py:4125 +msgid "Plot" +msgstr "Gráfico" -#: flatcamGUI/ObjectUI.py:234 +#: flatcamGUI/ObjectUI.py:210 flatcamGUI/ObjectUI.py:770 +#: flatcamGUI/ObjectUI.py:1484 flatcamGUI/ObjectUI.py:2233 +#: flatcamGUI/PreferencesUI.py:1963 flatcamGUI/PreferencesUI.py:4127 +#: flatcamGUI/PreferencesUI.py:4699 +msgid "Plot (show) this object." +msgstr "Trazar (mostrar) este objeto." + +#: flatcamGUI/ObjectUI.py:238 msgid "" "Toggle the display of the Gerber Apertures Table.\n" "When unchecked, it will delete all mark shapes\n" @@ -7213,11 +7555,11 @@ msgstr "" "Cuando no está marcada, eliminará todas las formas de las marcas.\n" "que se dibujan en lienzo." -#: flatcamGUI/ObjectUI.py:244 +#: flatcamGUI/ObjectUI.py:248 msgid "Mark All" msgstr "Márc. todo" -#: flatcamGUI/ObjectUI.py:246 +#: flatcamGUI/ObjectUI.py:250 msgid "" "When checked it will display all the apertures.\n" "When unchecked, it will delete all mark shapes\n" @@ -7227,15 +7569,15 @@ msgstr "" "Cuando no está marcada, eliminará todas las formas de las marcas.\n" "que se dibujan en lienzo." -#: flatcamGUI/ObjectUI.py:274 +#: flatcamGUI/ObjectUI.py:278 msgid "Mark the aperture instances on canvas." msgstr "Marque las instancias de apertura en el lienzo." -#: flatcamGUI/ObjectUI.py:286 flatcamGUI/PreferencesUI.py:2014 +#: flatcamGUI/ObjectUI.py:290 flatcamGUI/PreferencesUI.py:2194 msgid "Isolation Routing" msgstr "Enrutamiento de aislamiento" -#: flatcamGUI/ObjectUI.py:288 flatcamGUI/PreferencesUI.py:2016 +#: flatcamGUI/ObjectUI.py:292 flatcamGUI/PreferencesUI.py:2196 msgid "" "Create a Geometry object with\n" "toolpaths to cut outside polygons." @@ -7243,7 +7585,7 @@ msgstr "" "Crear un objeto de geometría con\n" "Trayectorias para cortar polígonos exteriores." -#: flatcamGUI/ObjectUI.py:306 flatcamGUI/PreferencesUI.py:2219 +#: flatcamGUI/ObjectUI.py:310 flatcamGUI/PreferencesUI.py:2399 msgid "" "Choose what tool to use for Gerber isolation:\n" "'Circular' or 'V-shape'.\n" @@ -7255,31 +7597,37 @@ msgstr "" "Cuando se selecciona la 'forma de V', entonces la herramienta\n" "El diámetro dependerá de la profundidad de corte elegida." -#: flatcamGUI/ObjectUI.py:312 +#: flatcamGUI/ObjectUI.py:316 msgid "V-Shape" msgstr "Forma V" -#: flatcamGUI/ObjectUI.py:318 flatcamGUI/ObjectUI.py:1374 -#: flatcamGUI/PreferencesUI.py:2231 flatcamGUI/PreferencesUI.py:5055 -#: flatcamTools/ToolNonCopperClear.py:231 +#: flatcamGUI/ObjectUI.py:322 flatcamGUI/ObjectUI.py:1670 +#: flatcamGUI/PreferencesUI.py:2411 flatcamGUI/PreferencesUI.py:5351 +#: flatcamGUI/PreferencesUI.py:5917 flatcamGUI/PreferencesUI.py:5924 +#: flatcamTools/ToolNCC.py:233 flatcamTools/ToolNCC.py:240 +#: flatcamTools/ToolPaint.py:216 msgid "V-Tip Dia" msgstr "V-Tipo Dia" -#: flatcamGUI/ObjectUI.py:320 flatcamGUI/ObjectUI.py:1377 -#: flatcamGUI/PreferencesUI.py:2233 flatcamGUI/PreferencesUI.py:5057 -#: flatcamTools/ToolNonCopperClear.py:233 +#: flatcamGUI/ObjectUI.py:324 flatcamGUI/ObjectUI.py:1673 +#: flatcamGUI/PreferencesUI.py:2413 flatcamGUI/PreferencesUI.py:5353 +#: flatcamGUI/PreferencesUI.py:5919 flatcamTools/ToolNCC.py:235 +#: flatcamTools/ToolPaint.py:218 msgid "The tip diameter for V-Shape Tool" msgstr "El diámetro de la punta para la herramienta en forma de V" -#: flatcamGUI/ObjectUI.py:331 flatcamGUI/ObjectUI.py:1389 -#: flatcamGUI/PreferencesUI.py:2244 flatcamGUI/PreferencesUI.py:5067 -#: flatcamTools/ToolNonCopperClear.py:242 +#: flatcamGUI/ObjectUI.py:335 flatcamGUI/ObjectUI.py:1685 +#: flatcamGUI/PreferencesUI.py:2424 flatcamGUI/PreferencesUI.py:5363 +#: flatcamGUI/PreferencesUI.py:5930 flatcamGUI/PreferencesUI.py:5938 +#: flatcamTools/ToolNCC.py:246 flatcamTools/ToolNCC.py:254 +#: flatcamTools/ToolPaint.py:229 msgid "V-Tip Angle" msgstr "V-Tipo Ángulo" -#: flatcamGUI/ObjectUI.py:333 flatcamGUI/ObjectUI.py:1392 -#: flatcamGUI/PreferencesUI.py:2246 flatcamGUI/PreferencesUI.py:5069 -#: flatcamTools/ToolNonCopperClear.py:244 +#: flatcamGUI/ObjectUI.py:337 flatcamGUI/ObjectUI.py:1688 +#: flatcamGUI/PreferencesUI.py:2426 flatcamGUI/PreferencesUI.py:5365 +#: flatcamGUI/PreferencesUI.py:5932 flatcamTools/ToolNCC.py:248 +#: flatcamTools/ToolPaint.py:231 msgid "" "The tip angle for V-Shape Tool.\n" "In degree." @@ -7287,9 +7635,9 @@ msgstr "" "El ángulo de punta para la herramienta en forma de V.\n" "En grado." -#: flatcamGUI/ObjectUI.py:347 flatcamGUI/ObjectUI.py:1408 -#: flatcamGUI/PreferencesUI.py:2259 flatcamGUI/PreferencesUI.py:3963 -#: flatcamGUI/PreferencesUI.py:5330 flatcamTools/ToolCutOut.py:135 +#: flatcamGUI/ObjectUI.py:351 flatcamGUI/ObjectUI.py:1704 +#: flatcamGUI/PreferencesUI.py:2439 flatcamGUI/PreferencesUI.py:4243 +#: flatcamGUI/PreferencesUI.py:5669 flatcamTools/ToolCutOut.py:142 msgid "" "Cutting depth (negative)\n" "below the copper surface." @@ -7297,7 +7645,7 @@ msgstr "" "Profundidad de corte (negativo)\n" "debajo de la superficie de cobre." -#: flatcamGUI/ObjectUI.py:361 +#: flatcamGUI/ObjectUI.py:365 msgid "" "Diameter of the cutting tool.\n" "If you want to have an isolation path\n" @@ -7311,11 +7659,11 @@ msgstr "" "característica, use un valor negativo para\n" "este parámetro." -#: flatcamGUI/ObjectUI.py:377 flatcamGUI/PreferencesUI.py:2038 +#: flatcamGUI/ObjectUI.py:381 flatcamGUI/PreferencesUI.py:2218 msgid "# Passes" msgstr "# Pases" -#: flatcamGUI/ObjectUI.py:379 flatcamGUI/PreferencesUI.py:2040 +#: flatcamGUI/ObjectUI.py:383 flatcamGUI/PreferencesUI.py:2220 msgid "" "Width of the isolation gap in\n" "number (integer) of tool widths." @@ -7323,24 +7671,18 @@ msgstr "" "Ancho de la brecha de aislamiento en\n" "Número (entero) de anchos de herramienta." -#: flatcamGUI/ObjectUI.py:389 flatcamGUI/PreferencesUI.py:2050 +#: flatcamGUI/ObjectUI.py:394 flatcamGUI/PreferencesUI.py:2230 msgid "Pass overlap" msgstr "Superposición de pases" -#: flatcamGUI/ObjectUI.py:391 flatcamGUI/PreferencesUI.py:2052 -msgid "How much (fraction) of the tool width to overlap each tool pass." +#: flatcamGUI/ObjectUI.py:396 flatcamGUI/PreferencesUI.py:2232 +msgid "How much (percentage) of the tool width to overlap each tool pass." msgstr "" -"La cantidad (fracción) del ancho de la herramienta para superponer cada " -"pasada de herramienta." +"Cuánto (porcentaje) del ancho de la herramienta para superponer cada pasada " +"de herramienta." -#: flatcamGUI/ObjectUI.py:403 flatcamGUI/PreferencesUI.py:2077 -#: flatcamGUI/PreferencesUI.py:4372 flatcamGUI/PreferencesUI.py:5112 -#: flatcamTools/ToolNonCopperClear.py:162 -msgid "Milling Type" -msgstr "Tipo de fresado" - -#: flatcamGUI/ObjectUI.py:405 flatcamGUI/PreferencesUI.py:2079 -#: flatcamGUI/PreferencesUI.py:4374 +#: flatcamGUI/ObjectUI.py:410 flatcamGUI/PreferencesUI.py:2259 +#: flatcamGUI/PreferencesUI.py:4667 msgid "" "Milling type:\n" "- climb / best for precision milling and to reduce tool usage\n" @@ -7351,29 +7693,19 @@ msgstr "" "herramienta\n" "- convencional / útil cuando no hay compensación de contragolpe" -#: flatcamGUI/ObjectUI.py:409 flatcamGUI/PreferencesUI.py:2084 -#: flatcamGUI/PreferencesUI.py:4378 flatcamGUI/PreferencesUI.py:5119 -#: flatcamTools/ToolNonCopperClear.py:169 -msgid "Climb" -msgstr "Subida" - -#: flatcamGUI/ObjectUI.py:410 -msgid "Conventional" -msgstr "Convencional" - -#: flatcamGUI/ObjectUI.py:415 +#: flatcamGUI/ObjectUI.py:420 msgid "Combine" msgstr "Combinar" -#: flatcamGUI/ObjectUI.py:417 flatcamGUI/PreferencesUI.py:2091 +#: flatcamGUI/ObjectUI.py:422 flatcamGUI/PreferencesUI.py:2271 msgid "Combine all passes into one object" msgstr "Combina todos los pases en un objeto" -#: flatcamGUI/ObjectUI.py:421 flatcamGUI/PreferencesUI.py:2193 +#: flatcamGUI/ObjectUI.py:426 flatcamGUI/PreferencesUI.py:2373 msgid "\"Follow\"" msgstr "\"Seguir\"" -#: flatcamGUI/ObjectUI.py:422 flatcamGUI/PreferencesUI.py:2195 +#: flatcamGUI/ObjectUI.py:427 flatcamGUI/PreferencesUI.py:2375 msgid "" "Generate a 'Follow' geometry.\n" "This means that it will cut through\n" @@ -7383,11 +7715,11 @@ msgstr "" "Esto significa que cortará a través\n" "El medio de la traza." -#: flatcamGUI/ObjectUI.py:428 +#: flatcamGUI/ObjectUI.py:433 msgid "Except" msgstr "Excepto" -#: flatcamGUI/ObjectUI.py:431 +#: flatcamGUI/ObjectUI.py:436 msgid "" "When the isolation geometry is generated,\n" "by checking this, the area of the object bellow\n" @@ -7397,12 +7729,12 @@ msgstr "" "marcando esto, el área del objeto a continuación\n" "será restado de la geometría de aislamiento." -#: flatcamGUI/ObjectUI.py:453 flatcamTools/ToolNonCopperClear.py:82 -#: flatcamTools/ToolPaint.py:85 +#: flatcamGUI/ObjectUI.py:456 flatcamTools/ToolNCC.py:86 +#: flatcamTools/ToolPaint.py:80 msgid "Obj Type" msgstr "Tipo de obj" -#: flatcamGUI/ObjectUI.py:455 +#: flatcamGUI/ObjectUI.py:458 msgid "" "Specify the type of object to be excepted from isolation.\n" "It can be of type: Gerber or Geometry.\n" @@ -7414,22 +7746,22 @@ msgstr "" "Lo que se seleccione aquí dictará el tipo\n" "de objetos que llenarán el cuadro combinado 'Objeto'." -#: flatcamGUI/ObjectUI.py:468 flatcamGUI/PreferencesUI.py:7522 -#: flatcamTools/ToolCalibration.py:186 flatcamTools/ToolNonCopperClear.py:100 -#: flatcamTools/ToolPaint.py:103 flatcamTools/ToolPanelize.py:81 -#: flatcamTools/ToolPanelize.py:94 +#: flatcamGUI/ObjectUI.py:471 flatcamGUI/PreferencesUI.py:8028 +#: flatcamTools/ToolCalibration.py:186 flatcamTools/ToolNCC.py:109 +#: flatcamTools/ToolPaint.py:103 flatcamTools/ToolPanelize.py:100 +#: flatcamTools/ToolQRCode.py:78 msgid "Object" msgstr "Objeto" -#: flatcamGUI/ObjectUI.py:469 +#: flatcamGUI/ObjectUI.py:472 msgid "Object whose area will be removed from isolation geometry." msgstr "Objeto cuya área se eliminará de la geometría de aislamiento." -#: flatcamGUI/ObjectUI.py:476 flatcamGUI/PreferencesUI.py:2064 +#: flatcamGUI/ObjectUI.py:479 flatcamGUI/PreferencesUI.py:2244 msgid "Scope" msgstr "Alcance" -#: flatcamGUI/ObjectUI.py:478 flatcamGUI/PreferencesUI.py:2066 +#: flatcamGUI/ObjectUI.py:481 flatcamGUI/PreferencesUI.py:2246 msgid "" "Isolation scope. Choose what to isolate:\n" "- 'All' -> Isolate all the polygons in the object\n" @@ -7439,17 +7771,18 @@ msgstr "" "- 'Todos' -> Aislar todos los polígonos en el objeto\n" "- 'Selección' -> Aislar una selección de polígonos." -#: flatcamGUI/ObjectUI.py:483 flatcamGUI/PreferencesUI.py:602 -#: flatcamGUI/PreferencesUI.py:2071 flatcamGUI/PreferencesUI.py:5634 -#: flatcamTools/ToolPaint.py:294 +#: flatcamGUI/ObjectUI.py:486 flatcamGUI/PreferencesUI.py:624 +#: flatcamGUI/PreferencesUI.py:2251 flatcamGUI/PreferencesUI.py:5590 +#: flatcamGUI/PreferencesUI.py:6097 flatcamTools/ToolNCC.py:539 +#: flatcamTools/ToolPaint.py:456 msgid "Selection" msgstr "Selección" -#: flatcamGUI/ObjectUI.py:491 flatcamGUI/PreferencesUI.py:2272 +#: flatcamGUI/ObjectUI.py:494 flatcamGUI/PreferencesUI.py:2452 msgid "Isolation Type" msgstr "Tipo de aislamiento" -#: flatcamGUI/ObjectUI.py:493 flatcamGUI/PreferencesUI.py:2274 +#: flatcamGUI/ObjectUI.py:496 flatcamGUI/PreferencesUI.py:2454 msgid "" "Choose how the isolation will be executed:\n" "- 'Full' -> complete isolation of polygons\n" @@ -7469,24 +7802,24 @@ msgstr "" "el aislamiento solo se puede hacer cuando hay una abertura\n" "dentro del polígono (por ejemplo, el polígono tiene forma de 'rosquilla')." -#: flatcamGUI/ObjectUI.py:502 flatcamGUI/PreferencesUI.py:2283 -#: flatcamGUI/PreferencesUI.py:2304 +#: flatcamGUI/ObjectUI.py:505 flatcamGUI/PreferencesUI.py:2463 +#: flatcamGUI/PreferencesUI.py:2484 msgid "Full" msgstr "Completo" -#: flatcamGUI/ObjectUI.py:503 +#: flatcamGUI/ObjectUI.py:506 msgid "Ext" msgstr "Exterior" -#: flatcamGUI/ObjectUI.py:504 +#: flatcamGUI/ObjectUI.py:507 msgid "Int" msgstr "Interior" -#: flatcamGUI/ObjectUI.py:509 +#: flatcamGUI/ObjectUI.py:512 msgid "Generate Isolation Geometry" msgstr "Generar geo. de aislamiento" -#: flatcamGUI/ObjectUI.py:517 +#: flatcamGUI/ObjectUI.py:520 msgid "" "Create a Geometry object with toolpaths to cut \n" "isolation outside, inside or on both sides of the\n" @@ -7508,11 +7841,11 @@ msgstr "" "dentro de la función real de Gerber, use una herramienta negativa\n" "diámetro arriba." -#: flatcamGUI/ObjectUI.py:529 +#: flatcamGUI/ObjectUI.py:532 msgid "Buffer Solid Geometry" msgstr "Buffer la Geometria solida" -#: flatcamGUI/ObjectUI.py:531 +#: flatcamGUI/ObjectUI.py:534 msgid "" "This button is shown only when the Gerber file\n" "is loaded without buffering.\n" @@ -7524,11 +7857,11 @@ msgstr "" "Al hacer clic en esto, se creará la geometría almacenada\n" "requerido para el aislamiento." -#: flatcamGUI/ObjectUI.py:559 +#: flatcamGUI/ObjectUI.py:566 msgid "Clear N-copper" msgstr "N-cobre claro" -#: flatcamGUI/ObjectUI.py:561 flatcamGUI/PreferencesUI.py:5019 +#: flatcamGUI/ObjectUI.py:568 flatcamGUI/PreferencesUI.py:5312 msgid "" "Create a Geometry object with\n" "toolpaths to cut all non-copper regions." @@ -7536,8 +7869,8 @@ msgstr "" "Crear un objeto de geometría con\n" "Trayectorias para cortar todas las regiones sin cobre." -#: flatcamGUI/ObjectUI.py:568 flatcamGUI/ObjectUI.py:1751 -#: flatcamTools/ToolNonCopperClear.py:473 +#: flatcamGUI/ObjectUI.py:575 flatcamGUI/ObjectUI.py:2077 +#: flatcamTools/ToolNCC.py:599 msgid "" "Create the Geometry Object\n" "for non-copper routing." @@ -7545,11 +7878,11 @@ msgstr "" "Crear el objeto de geometría\n" "para enrutamiento sin cobre." -#: flatcamGUI/ObjectUI.py:581 +#: flatcamGUI/ObjectUI.py:588 msgid "Board cutout" msgstr "Corte del tablero" -#: flatcamGUI/ObjectUI.py:583 flatcamGUI/PreferencesUI.py:5303 +#: flatcamGUI/ObjectUI.py:590 flatcamGUI/PreferencesUI.py:5642 msgid "" "Create toolpaths to cut around\n" "the PCB and separate it from\n" @@ -7559,7 +7892,7 @@ msgstr "" "El PCB y lo separa de\n" "El tablero original." -#: flatcamGUI/ObjectUI.py:590 +#: flatcamGUI/ObjectUI.py:597 msgid "" "Generate the geometry for\n" "the board cutout." @@ -7567,11 +7900,11 @@ msgstr "" "Generar la geometría para\n" "El recorte del tablero." -#: flatcamGUI/ObjectUI.py:608 flatcamGUI/PreferencesUI.py:2101 +#: flatcamGUI/ObjectUI.py:615 flatcamGUI/PreferencesUI.py:2281 msgid "Non-copper regions" msgstr "Regiones no cobre" -#: flatcamGUI/ObjectUI.py:610 flatcamGUI/PreferencesUI.py:2103 +#: flatcamGUI/ObjectUI.py:617 flatcamGUI/PreferencesUI.py:2283 msgid "" "Create polygons covering the\n" "areas without copper on the PCB.\n" @@ -7585,12 +7918,12 @@ msgstr "" "objeto. Se puede usar para eliminar todo\n" "cobre de una región específica." -#: flatcamGUI/ObjectUI.py:620 flatcamGUI/ObjectUI.py:661 -#: flatcamGUI/PreferencesUI.py:2115 flatcamGUI/PreferencesUI.py:2148 +#: flatcamGUI/ObjectUI.py:627 flatcamGUI/ObjectUI.py:668 +#: flatcamGUI/PreferencesUI.py:2295 flatcamGUI/PreferencesUI.py:2328 msgid "Boundary Margin" msgstr "Margen límite" -#: flatcamGUI/ObjectUI.py:622 flatcamGUI/PreferencesUI.py:2117 +#: flatcamGUI/ObjectUI.py:629 flatcamGUI/PreferencesUI.py:2297 msgid "" "Specify the edge of the PCB\n" "by drawing a box around all\n" @@ -7602,27 +7935,27 @@ msgstr "" "objetos con este mínimo\n" "distancia." -#: flatcamGUI/ObjectUI.py:637 flatcamGUI/ObjectUI.py:675 -#: flatcamGUI/PreferencesUI.py:2130 flatcamGUI/PreferencesUI.py:2161 +#: flatcamGUI/ObjectUI.py:644 flatcamGUI/ObjectUI.py:682 +#: flatcamGUI/PreferencesUI.py:2310 flatcamGUI/PreferencesUI.py:2341 msgid "Rounded Geo" msgstr "Geo redondeado" -#: flatcamGUI/ObjectUI.py:639 flatcamGUI/PreferencesUI.py:2132 +#: flatcamGUI/ObjectUI.py:646 flatcamGUI/PreferencesUI.py:2312 msgid "Resulting geometry will have rounded corners." msgstr "La geometría resultante tendrá esquinas redondeadas." -#: flatcamGUI/ObjectUI.py:643 flatcamGUI/ObjectUI.py:684 -#: flatcamTools/ToolSolderPaste.py:133 +#: flatcamGUI/ObjectUI.py:650 flatcamGUI/ObjectUI.py:691 +#: flatcamTools/ToolSolderPaste.py:135 msgid "Generate Geo" msgstr "Generar Geo" -#: flatcamGUI/ObjectUI.py:653 flatcamGUI/PreferencesUI.py:2142 -#: flatcamGUI/PreferencesUI.py:7052 flatcamTools/ToolPanelize.py:95 +#: flatcamGUI/ObjectUI.py:660 flatcamGUI/PreferencesUI.py:2322 +#: flatcamGUI/PreferencesUI.py:7558 flatcamTools/ToolPanelize.py:101 #: flatcamTools/ToolQRCode.py:192 msgid "Bounding Box" msgstr "Cuadro delimitador" -#: flatcamGUI/ObjectUI.py:655 +#: flatcamGUI/ObjectUI.py:662 msgid "" "Create a geometry surrounding the Gerber object.\n" "Square shape." @@ -7630,7 +7963,7 @@ msgstr "" "Crea una geometría que rodea el objeto Gerber.\n" "Forma cuadrada." -#: flatcamGUI/ObjectUI.py:663 flatcamGUI/PreferencesUI.py:2150 +#: flatcamGUI/ObjectUI.py:670 flatcamGUI/PreferencesUI.py:2330 msgid "" "Distance of the edges of the box\n" "to the nearest polygon." @@ -7638,7 +7971,7 @@ msgstr "" "Distancia de los bordes de la caja.\n" "al polígono más cercano." -#: flatcamGUI/ObjectUI.py:677 flatcamGUI/PreferencesUI.py:2163 +#: flatcamGUI/ObjectUI.py:684 flatcamGUI/PreferencesUI.py:2343 msgid "" "If the bounding box is \n" "to have rounded corners\n" @@ -7650,33 +7983,31 @@ msgstr "" "su radio es igual a\n" "el margen." -#: flatcamGUI/ObjectUI.py:686 +#: flatcamGUI/ObjectUI.py:693 msgid "Generate the Geometry object." msgstr "Genera el objeto Geometry." -#: flatcamGUI/ObjectUI.py:715 +#: flatcamGUI/ObjectUI.py:720 msgid "Excellon Object" msgstr "Objeto Excellon" -#: flatcamGUI/ObjectUI.py:729 +#: flatcamGUI/ObjectUI.py:732 msgid "Solid circles." msgstr "Círculos sólidos." -#: flatcamGUI/ObjectUI.py:777 flatcamGUI/ObjectUI.py:1926 -#: flatcamTools/ToolProperties.py:161 +#: flatcamGUI/ObjectUI.py:780 flatcamGUI/ObjectUI.py:875 +#: flatcamGUI/ObjectUI.py:2254 flatcamGUI/PreferencesUI.py:3289 +#: flatcamTools/ToolProperties.py:166 msgid "Drills" msgstr "Taladros" -#: flatcamGUI/ObjectUI.py:777 flatcamGUI/ObjectUI.py:1926 -#: flatcamGUI/PreferencesUI.py:3683 flatcamTools/ToolProperties.py:162 +#: flatcamGUI/ObjectUI.py:780 flatcamGUI/ObjectUI.py:876 +#: flatcamGUI/ObjectUI.py:2254 flatcamGUI/PreferencesUI.py:3290 +#: flatcamGUI/PreferencesUI.py:3961 flatcamTools/ToolProperties.py:168 msgid "Slots" msgstr "Muesca" -#: flatcamGUI/ObjectUI.py:778 flatcamGUI/PreferencesUI.py:3289 -msgid "Offset Z" -msgstr "Offset Z" - -#: flatcamGUI/ObjectUI.py:782 +#: flatcamGUI/ObjectUI.py:785 msgid "" "This is the Tool Number.\n" "When ToolChange is checked, on toolchange event this value\n" @@ -7691,8 +8022,8 @@ msgstr "" "\n" "Aquí se seleccionan las herramientas para la generación de código G." -#: flatcamGUI/ObjectUI.py:787 flatcamGUI/ObjectUI.py:1230 -#: flatcamTools/ToolPaint.py:137 +#: flatcamGUI/ObjectUI.py:790 flatcamGUI/ObjectUI.py:1508 +#: flatcamTools/ToolPaint.py:142 msgid "" "Tool Diameter. It's value (in current FlatCAM units) \n" "is the cut width into the material." @@ -7700,7 +8031,7 @@ msgstr "" "Diámetro de herramienta. Su valor (en unidades actuales de FlatCAM)\n" "es el ancho de corte en el material." -#: flatcamGUI/ObjectUI.py:790 +#: flatcamGUI/ObjectUI.py:793 msgid "" "The number of Drill holes. Holes that are drilled with\n" "a drill bit." @@ -7708,7 +8039,7 @@ msgstr "" "El número de agujeros de taladros. Agujeros que se taladran con\n" "una broca." -#: flatcamGUI/ObjectUI.py:793 +#: flatcamGUI/ObjectUI.py:796 msgid "" "The number of Slot holes. Holes that are created by\n" "milling them with an endmill bit." @@ -7716,18 +8047,7 @@ msgstr "" "El número de agujeros de muesca. Agujeros creados por\n" "fresándolas con una broca de fresa." -#: flatcamGUI/ObjectUI.py:796 flatcamGUI/PreferencesUI.py:3291 -msgid "" -"Some drill bits (the larger ones) need to drill deeper\n" -"to create the desired exit hole diameter due of the tip shape.\n" -"The value here can compensate the Cut Z parameter." -msgstr "" -"Algunas brocas (las más grandes) necesitan profundizar más\n" -"para crear el diámetro del orificio de salida deseado debido a la forma de " -"la punta.\n" -"El valor aquí puede compensar el parámetro Z de corte." - -#: flatcamGUI/ObjectUI.py:800 +#: flatcamGUI/ObjectUI.py:799 msgid "" "Toggle display of the drills for the current tool.\n" "This does not select the tools for G-code generation." @@ -7735,20 +8055,60 @@ msgstr "" "Alternar la visualización de los ejercicios para la herramienta actual.\n" "Esto no selecciona las herramientas para la generación de código G." -#: flatcamGUI/ObjectUI.py:807 flatcamGUI/PreferencesUI.py:3069 -#: flatcamGUI/PreferencesUI.py:3947 -msgid "Create CNC Job" -msgstr "Crear trabajo CNC" - -#: flatcamGUI/ObjectUI.py:809 +#: flatcamGUI/ObjectUI.py:820 flatcamGUI/ObjectUI.py:1663 +#: flatcamTools/ToolNCC.py:334 flatcamTools/ToolPaint.py:317 msgid "" -"Create a CNC Job object\n" -"for this drill object." +"The data used for creating GCode.\n" +"Each tool store it's own set of such data." msgstr "" -"Crear un objeto de trabajo CNC\n" -"para este objeto de perforación." +"Los datos utilizados para crear GCode.\n" +"Cada herramienta almacena su propio conjunto de datos." -#: flatcamGUI/ObjectUI.py:822 flatcamGUI/PreferencesUI.py:3084 +#: flatcamGUI/ObjectUI.py:846 flatcamGUI/PreferencesUI.py:3266 +msgid "" +"Operation type:\n" +"- Drilling -> will drill the drills/slots associated with this tool\n" +"- Milling -> will mill the drills/slots" +msgstr "" +"Tipo de operación:\n" +"- Perforación -> perforará las perforaciones / ranuras asociadas con esta " +"herramienta\n" +"- Fresado -> fresará los taladros / ranuras" + +#: flatcamGUI/ObjectUI.py:852 flatcamGUI/PreferencesUI.py:3272 +msgid "Drilling" +msgstr "Perforación" + +#: flatcamGUI/ObjectUI.py:853 flatcamGUI/PreferencesUI.py:3273 +msgid "Milling" +msgstr "Fresado" + +#: flatcamGUI/ObjectUI.py:868 flatcamGUI/PreferencesUI.py:3282 +msgid "" +"Milling type:\n" +"- Drills -> will mill the drills associated with this tool\n" +"- Slots -> will mill the slots associated with this tool\n" +"- Both -> will mill both drills and mills or whatever is available" +msgstr "" +"Tipo de fresado:\n" +"- Taladros -> fresará los taladros asociados con esta herramienta\n" +"- Ranuras -> fresará las ranuras asociadas con esta herramienta\n" +"- Ambos -> fresarán taladros y molinos o lo que esté disponible" + +#: flatcamGUI/ObjectUI.py:877 flatcamGUI/PreferencesUI.py:3291 +#: flatcamGUI/PreferencesUI.py:6343 flatcamTools/ToolFilm.py:258 +msgid "Both" +msgstr "Ambas" + +#: flatcamGUI/ObjectUI.py:885 flatcamGUI/PreferencesUI.py:3298 +msgid "Milling Diameter" +msgstr "Diá. de fresado" + +#: flatcamGUI/ObjectUI.py:887 flatcamGUI/PreferencesUI.py:3300 +msgid "The diameter of the tool who will do the milling" +msgstr "El diámetro de la herramienta que hará el fresado" + +#: flatcamGUI/ObjectUI.py:901 flatcamGUI/PreferencesUI.py:3313 msgid "" "Drill depth (negative)\n" "below the copper surface." @@ -7756,7 +8116,33 @@ msgstr "" "Profundidad de perforación (negativo)\n" "debajo de la superficie de cobre." -#: flatcamGUI/ObjectUI.py:841 flatcamGUI/PreferencesUI.py:3102 +#: flatcamGUI/ObjectUI.py:920 flatcamGUI/ObjectUI.py:1722 +#: flatcamGUI/PreferencesUI.py:3331 flatcamGUI/PreferencesUI.py:4261 +#: flatcamGUI/PreferencesUI.py:5687 flatcamTools/ToolCutOut.py:160 +msgid "Multi-Depth" +msgstr "Profund. Múlti" + +#: flatcamGUI/ObjectUI.py:923 flatcamGUI/ObjectUI.py:1725 +#: flatcamGUI/PreferencesUI.py:3334 flatcamGUI/PreferencesUI.py:4264 +#: flatcamGUI/PreferencesUI.py:5690 flatcamTools/ToolCutOut.py:163 +msgid "" +"Use multiple passes to limit\n" +"the cut depth in each pass. Will\n" +"cut multiple times until Cut Z is\n" +"reached." +msgstr "" +"Usa múltiples pases para limitar\n" +"La profundidad de corte en cada pasada. Será\n" +"cortar varias veces hasta que el Corte Z sea\n" +"alcanzado." + +#: flatcamGUI/ObjectUI.py:936 flatcamGUI/ObjectUI.py:1739 +#: flatcamGUI/PreferencesUI.py:3346 flatcamGUI/PreferencesUI.py:5702 +#: flatcamTools/ToolCutOut.py:177 +msgid "Depth of each pass (positive)." +msgstr "Profundidad de cada pase (positivo)." + +#: flatcamGUI/ObjectUI.py:947 flatcamGUI/PreferencesUI.py:3354 msgid "" "Tool height when travelling\n" "across the XY plane." @@ -7764,61 +8150,16 @@ msgstr "" "Altura de herramienta al viajar\n" "A través del plano XY." -#: flatcamGUI/ObjectUI.py:858 flatcamGUI/ObjectUI.py:1478 -#: flatcamGUI/PreferencesUI.py:3117 flatcamGUI/PreferencesUI.py:4034 -msgid "Tool change" -msgstr "Cambio de herram" - -#: flatcamGUI/ObjectUI.py:860 flatcamGUI/PreferencesUI.py:3119 +#: flatcamGUI/ObjectUI.py:968 flatcamGUI/ObjectUI.py:1769 +#: flatcamGUI/PreferencesUI.py:4380 msgid "" -"Include tool-change sequence\n" -"in G-Code (Pause for tool change)." +"Cutting speed in the XY\n" +"plane in units per minute" msgstr "" -"Incluir secuencia de cambio de herramienta\n" -"en G-Code (Pausa para cambio de herramienta)." +"Velocidad de corte en el XY.\n" +"Avion en unidades por minuto" -#: flatcamGUI/ObjectUI.py:866 flatcamGUI/ObjectUI.py:1471 -msgid "Tool change Z" -msgstr "Cambio de herra. Z" - -#: flatcamGUI/ObjectUI.py:868 flatcamGUI/ObjectUI.py:1474 -#: flatcamGUI/PreferencesUI.py:3126 flatcamGUI/PreferencesUI.py:4047 -msgid "" -"Z-axis position (height) for\n" -"tool change." -msgstr "" -"Posición del eje Z (altura) para\n" -"cambio de herramienta." - -#: flatcamGUI/ObjectUI.py:888 flatcamGUI/PreferencesUI.py:3311 -msgid "" -"Height of the tool just after start.\n" -"Delete the value if you don't need this feature." -msgstr "" -"Altura de la herramienta justo después del arranque.\n" -"Elimine el valor si no necesita esta característica." - -#: flatcamGUI/ObjectUI.py:896 flatcamGUI/ObjectUI.py:1512 -#: flatcamGUI/PreferencesUI.py:3141 flatcamGUI/PreferencesUI.py:4066 -msgid "End move Z" -msgstr "Fin del movi. Z" - -#: flatcamGUI/ObjectUI.py:898 flatcamGUI/ObjectUI.py:1514 -#: flatcamGUI/PreferencesUI.py:3143 flatcamGUI/PreferencesUI.py:4068 -msgid "" -"Height of the tool after\n" -"the last move at the end of the job." -msgstr "" -"Altura de la herramienta después de\n" -"El último movimiento al final del trabajo." - -#: flatcamGUI/ObjectUI.py:915 flatcamGUI/ObjectUI.py:1545 -#: flatcamGUI/PreferencesUI.py:3158 flatcamGUI/PreferencesUI.py:4101 -#: flatcamGUI/PreferencesUI.py:6566 flatcamTools/ToolSolderPaste.py:264 -msgid "Feedrate Z" -msgstr "Avance Z" - -#: flatcamGUI/ObjectUI.py:917 flatcamGUI/PreferencesUI.py:3160 +#: flatcamGUI/ObjectUI.py:983 flatcamGUI/PreferencesUI.py:3427 msgid "" "Tool speed while drilling\n" "(in units per minute).\n" @@ -7830,12 +8171,12 @@ msgstr "" "La llamada velocidad de avance 'Plunge'.\n" "Esto es para el movimiento lineal G01." -#: flatcamGUI/ObjectUI.py:931 flatcamGUI/ObjectUI.py:1560 -#: flatcamGUI/PreferencesUI.py:3319 flatcamGUI/PreferencesUI.py:4210 +#: flatcamGUI/ObjectUI.py:998 flatcamGUI/ObjectUI.py:1796 +#: flatcamGUI/PreferencesUI.py:3597 flatcamGUI/PreferencesUI.py:4503 msgid "Feedrate Rapids" msgstr "Rápidos de avance" -#: flatcamGUI/ObjectUI.py:933 flatcamGUI/PreferencesUI.py:3321 +#: flatcamGUI/ObjectUI.py:1000 flatcamGUI/PreferencesUI.py:3599 msgid "" "Tool speed while drilling\n" "(in units per minute).\n" @@ -7849,12 +8190,26 @@ msgstr "" "Es útil solo para Marlin,\n" "Ignorar para cualquier otro caso." -#: flatcamGUI/ObjectUI.py:951 flatcamGUI/ObjectUI.py:1603 -#: flatcamGUI/PreferencesUI.py:4117 -msgid "Spindle speed" -msgstr "Eje de velocidad" +#: flatcamGUI/ObjectUI.py:1020 flatcamGUI/ObjectUI.py:1816 +#: flatcamGUI/PreferencesUI.py:4521 +msgid "Re-cut" +msgstr "Recortar" -#: flatcamGUI/ObjectUI.py:953 flatcamGUI/PreferencesUI.py:3175 +#: flatcamGUI/ObjectUI.py:1022 flatcamGUI/ObjectUI.py:1035 +#: flatcamGUI/ObjectUI.py:1818 flatcamGUI/ObjectUI.py:1830 +#: flatcamGUI/PreferencesUI.py:4523 flatcamGUI/PreferencesUI.py:4535 +msgid "" +"In order to remove possible\n" +"copper leftovers where first cut\n" +"meet with last cut, we generate an\n" +"extended cut over the first cut section." +msgstr "" +"Para eliminar posibles\n" +"sobras de cobre donde el primer corte\n" +"Nos reunimos con el último corte, generamos un\n" +"Corte extendido sobre la primera sección de corte." + +#: flatcamGUI/ObjectUI.py:1050 flatcamGUI/PreferencesUI.py:3442 msgid "" "Speed of the spindle\n" "in RPM (optional)" @@ -7862,8 +8217,8 @@ msgstr "" "Velocidad del husillo\n" "en RPM (opcional)" -#: flatcamGUI/ObjectUI.py:965 flatcamGUI/ObjectUI.py:1622 -#: flatcamGUI/PreferencesUI.py:3187 flatcamGUI/PreferencesUI.py:4135 +#: flatcamGUI/ObjectUI.py:1065 flatcamGUI/ObjectUI.py:1858 +#: flatcamGUI/PreferencesUI.py:3456 flatcamGUI/PreferencesUI.py:4427 msgid "" "Pause to allow the spindle to reach its\n" "speed before cutting." @@ -7871,26 +8226,116 @@ msgstr "" "Pausa para permitir que el husillo alcance su\n" "Velocidad antes del corte." -#: flatcamGUI/ObjectUI.py:974 flatcamGUI/ObjectUI.py:1632 -#: flatcamGUI/PreferencesUI.py:3193 flatcamGUI/PreferencesUI.py:4140 +#: flatcamGUI/ObjectUI.py:1076 flatcamGUI/ObjectUI.py:1868 +#: flatcamGUI/PreferencesUI.py:3464 flatcamGUI/PreferencesUI.py:4432 msgid "Number of time units for spindle to dwell." msgstr "Número de unidades de tiempo para que el husillo permanezca." -#: flatcamGUI/ObjectUI.py:984 flatcamGUI/PreferencesUI.py:3206 -msgid "" -"The preprocessor JSON file that dictates\n" -"Gcode output." -msgstr "" -"El archivo JSON del postprocesador que dicta\n" -"Salida de Gcode." +#: flatcamGUI/ObjectUI.py:1086 flatcamGUI/PreferencesUI.py:3563 +msgid "Offset Z" +msgstr "Offset Z" -#: flatcamGUI/ObjectUI.py:993 flatcamGUI/ObjectUI.py:1652 -#: flatcamGUI/PreferencesUI.py:3335 flatcamGUI/PreferencesUI.py:4251 +#: flatcamGUI/ObjectUI.py:1088 flatcamGUI/PreferencesUI.py:3565 +msgid "" +"Some drill bits (the larger ones) need to drill deeper\n" +"to create the desired exit hole diameter due of the tip shape.\n" +"The value here can compensate the Cut Z parameter." +msgstr "" +"Algunas brocas (las más grandes) necesitan profundizar más\n" +"para crear el diámetro del orificio de salida deseado debido a la forma de " +"la punta.\n" +"El valor aquí puede compensar el parámetro Z de corte." + +#: flatcamGUI/ObjectUI.py:1148 flatcamGUI/ObjectUI.py:1922 +#: flatcamTools/ToolNCC.py:492 flatcamTools/ToolPaint.py:423 +msgid "Apply parameters to all tools" +msgstr "Aplicar Parám. a todas las herramientas" + +#: flatcamGUI/ObjectUI.py:1150 flatcamGUI/ObjectUI.py:1924 +#: flatcamTools/ToolNCC.py:494 flatcamTools/ToolPaint.py:425 +msgid "" +"The parameters in the current form will be applied\n" +"on all the tools from the Tool Table." +msgstr "" +"Se aplicarán los parámetros en el formulario actual\n" +"en todas las herramientas de la tabla de herramientas." + +#: flatcamGUI/ObjectUI.py:1161 flatcamGUI/ObjectUI.py:1935 +#: flatcamTools/ToolNCC.py:505 flatcamTools/ToolPaint.py:436 +msgid "Common Parameters" +msgstr "Parámetros comunes" + +#: flatcamGUI/ObjectUI.py:1163 flatcamGUI/ObjectUI.py:1937 +#: flatcamTools/ToolNCC.py:507 flatcamTools/ToolPaint.py:438 +msgid "Parameters that are common for all tools." +msgstr "Parámetros que son comunes para todas las herramientas." + +#: flatcamGUI/ObjectUI.py:1168 flatcamGUI/ObjectUI.py:1942 +msgid "Tool change Z" +msgstr "Cambio de herra. Z" + +#: flatcamGUI/ObjectUI.py:1170 flatcamGUI/PreferencesUI.py:3372 +msgid "" +"Include tool-change sequence\n" +"in G-Code (Pause for tool change)." +msgstr "" +"Incluir secuencia de cambio de herramienta\n" +"en G-Code (Pausa para cambio de herramienta)." + +#: flatcamGUI/ObjectUI.py:1177 flatcamGUI/ObjectUI.py:1953 +#: flatcamGUI/PreferencesUI.py:3380 flatcamGUI/PreferencesUI.py:4327 +msgid "" +"Z-axis position (height) for\n" +"tool change." +msgstr "" +"Posición del eje Z (altura) para\n" +"cambio de herramienta." + +#: flatcamGUI/ObjectUI.py:1194 flatcamGUI/PreferencesUI.py:3588 +msgid "" +"Height of the tool just after start.\n" +"Delete the value if you don't need this feature." +msgstr "" +"Altura de la herramienta justo después del arranque.\n" +"Elimine el valor si no necesita esta característica." + +#: flatcamGUI/ObjectUI.py:1203 flatcamGUI/ObjectUI.py:1981 +#: flatcamGUI/PreferencesUI.py:3396 flatcamGUI/PreferencesUI.py:4346 +msgid "End move Z" +msgstr "Fin del movi. Z" + +#: flatcamGUI/ObjectUI.py:1205 flatcamGUI/ObjectUI.py:1983 +#: flatcamGUI/PreferencesUI.py:3398 flatcamGUI/PreferencesUI.py:4348 +msgid "" +"Height of the tool after\n" +"the last move at the end of the job." +msgstr "" +"Altura de la herramienta después de\n" +"El último movimiento al final del trabajo." + +#: flatcamGUI/ObjectUI.py:1222 flatcamGUI/ObjectUI.py:2000 +#: flatcamGUI/PreferencesUI.py:3413 flatcamGUI/PreferencesUI.py:4366 +msgid "End move X,Y" +msgstr "X, Y Fin del movimiento" + +#: flatcamGUI/ObjectUI.py:1224 flatcamGUI/ObjectUI.py:2002 +#: flatcamGUI/PreferencesUI.py:3415 flatcamGUI/PreferencesUI.py:4368 +msgid "" +"End move X,Y position. In format (x,y).\n" +"If no value is entered then there is no move\n" +"on X,Y plane at the end of the job." +msgstr "" +"Fin movimiento X, Y posición. En formato (x, y).\n" +"Si no se ingresa ningún valor, entonces no hay movimiento\n" +"en el plano X, Y al final del trabajo." + +#: flatcamGUI/ObjectUI.py:1234 flatcamGUI/ObjectUI.py:1876 +#: flatcamGUI/PreferencesUI.py:3613 flatcamGUI/PreferencesUI.py:4544 msgid "Probe Z depth" msgstr "Profundidad de la sonda Z" -#: flatcamGUI/ObjectUI.py:995 flatcamGUI/ObjectUI.py:1654 -#: flatcamGUI/PreferencesUI.py:3337 flatcamGUI/PreferencesUI.py:4253 +#: flatcamGUI/ObjectUI.py:1236 flatcamGUI/ObjectUI.py:1878 +#: flatcamGUI/PreferencesUI.py:3615 flatcamGUI/PreferencesUI.py:4546 msgid "" "The maximum depth that the probe is allowed\n" "to probe. Negative value, in current units." @@ -7898,45 +8343,71 @@ msgstr "" "The maximum depth that the probe is allowed\n" "to probe. Negative value, in current units." -#: flatcamGUI/ObjectUI.py:1009 flatcamGUI/ObjectUI.py:1669 -#: flatcamGUI/PreferencesUI.py:3348 flatcamGUI/PreferencesUI.py:4266 +#: flatcamGUI/ObjectUI.py:1252 flatcamGUI/ObjectUI.py:1893 +#: flatcamGUI/PreferencesUI.py:3626 flatcamGUI/PreferencesUI.py:4559 msgid "Feedrate Probe" msgstr "Sonda de avance" -#: flatcamGUI/ObjectUI.py:1011 flatcamGUI/ObjectUI.py:1671 -#: flatcamGUI/PreferencesUI.py:3350 flatcamGUI/PreferencesUI.py:4268 +#: flatcamGUI/ObjectUI.py:1254 flatcamGUI/ObjectUI.py:1895 +#: flatcamGUI/PreferencesUI.py:3628 flatcamGUI/PreferencesUI.py:4561 msgid "The feedrate used while the probe is probing." msgstr "La velocidad de avance utilizada mientras la sonda está sondeando." -#: flatcamGUI/ObjectUI.py:1037 flatcamGUI/PreferencesUI.py:3215 -msgid "Gcode" -msgstr "Gcode" +#: flatcamGUI/ObjectUI.py:1261 +msgid "e_fr_probe" +msgstr "e_fr_probe" -#: flatcamGUI/ObjectUI.py:1039 +#: flatcamGUI/ObjectUI.py:1270 +msgid "Preprocessor E" +msgstr "Postprocesador E" + +#: flatcamGUI/ObjectUI.py:1272 msgid "" -"Choose what to use for GCode generation:\n" -"'Drills', 'Slots' or 'Both'.\n" -"When choosing 'Slots' or 'Both', slots will be\n" -"converted to a series of drills." +"The preprocessor JSON file that dictates\n" +"Gcode output for Excellon Objects." msgstr "" -"Elija qué usar para la generación de GCode:\n" -"'Taladros', 'Muesca' o 'Ambos'.\n" -"Al elegir 'Muesca' o 'Ambos', los slots serán\n" -"convertido en una serie de simulacros." +"El archivo JSON del preprocesador que dicta\n" +"Salida de Gcode para objetos Excellon." -#: flatcamGUI/ObjectUI.py:1053 -msgid "Create Drills GCode" -msgstr "Crear taladros GCode" +#: flatcamGUI/ObjectUI.py:1282 +msgid "Preprocessor G" +msgstr "Postprocesador G" -#: flatcamGUI/ObjectUI.py:1055 -msgid "Generate the CNC Job." -msgstr "Generar el trabajo del CNC." +#: flatcamGUI/ObjectUI.py:1284 +msgid "" +"The preprocessor JSON file that dictates\n" +"Gcode output for Geometry (Milling) Objects." +msgstr "" +"El archivo JSON del preprocesador que dicta\n" +"Salida de Gcode para objetos de geometría (fresado)." -#: flatcamGUI/ObjectUI.py:1066 flatcamGUI/PreferencesUI.py:3233 -msgid "Mill Holes" -msgstr "Agujeros de molino" +#: flatcamGUI/ObjectUI.py:1308 flatcamGUI/ObjectUI.py:2026 +msgid "" +"Add / Select at least one tool in the tool-table.\n" +"Click the # header to select all, or Ctrl + LMB\n" +"for custom selection of tools." +msgstr "" +"Agregar / Seleccionar al menos una herramienta en la tabla de herramientas.\n" +"Haga clic en el encabezado # para seleccionar todo, o Ctrl + LMB\n" +"para la selección personalizada de herramientas." -#: flatcamGUI/ObjectUI.py:1068 +#: flatcamGUI/ObjectUI.py:1316 flatcamGUI/ObjectUI.py:2033 +msgid "Generate CNCJob object" +msgstr "Generar objeto CNCJob" + +#: flatcamGUI/ObjectUI.py:1318 +msgid "" +"Generate the CNC Job.\n" +"If milling then an additional Geometry object will be created" +msgstr "" +"Generar el trabajo del CNC.\n" +"Si se fresa, se creará un objeto Geometry adicional" + +#: flatcamGUI/ObjectUI.py:1335 +msgid "Milling Geometry" +msgstr "Geometría de fresado" + +#: flatcamGUI/ObjectUI.py:1337 msgid "" "Create Geometry for milling holes.\n" "Select from the Tools Table above the hole dias to be\n" @@ -7947,20 +8418,16 @@ msgstr "" "para\n" "molido. Use la columna # para hacer la selección." -#: flatcamGUI/ObjectUI.py:1074 flatcamGUI/PreferencesUI.py:3239 -msgid "Drill Tool dia" -msgstr "Diá de la herra. de Perfor" - -#: flatcamGUI/ObjectUI.py:1076 flatcamGUI/PreferencesUI.py:2027 -#: flatcamGUI/PreferencesUI.py:3241 +#: flatcamGUI/ObjectUI.py:1345 flatcamGUI/PreferencesUI.py:2207 +#: flatcamGUI/PreferencesUI.py:3514 msgid "Diameter of the cutting tool." msgstr "Diá. de la herramienta de corte." -#: flatcamGUI/ObjectUI.py:1083 -msgid "Mill Drills Geo" -msgstr "Fresas Geo" +#: flatcamGUI/ObjectUI.py:1355 +msgid "Mill Drills" +msgstr "Fresar los Taladros" -#: flatcamGUI/ObjectUI.py:1085 +#: flatcamGUI/ObjectUI.py:1357 msgid "" "Create the Geometry Object\n" "for milling DRILLS toolpaths." @@ -7968,23 +8435,11 @@ msgstr "" "Crear el objeto de geometría\n" "para fresar trayectorias de taladros." -#: flatcamGUI/ObjectUI.py:1099 flatcamGUI/PreferencesUI.py:3250 -msgid "Slot Tool dia" -msgstr "Diá. de la herra. de ranura" +#: flatcamGUI/ObjectUI.py:1375 +msgid "Mill Slots" +msgstr "Fresar las Ranuras" -#: flatcamGUI/ObjectUI.py:1101 flatcamGUI/PreferencesUI.py:3252 -msgid "" -"Diameter of the cutting tool\n" -"when milling slots." -msgstr "" -"Diámetro de la herramienta de corte\n" -"Al fresar ranuras." - -#: flatcamGUI/ObjectUI.py:1110 -msgid "Mill Slots Geo" -msgstr "Fresado de muesca Geo" - -#: flatcamGUI/ObjectUI.py:1112 +#: flatcamGUI/ObjectUI.py:1377 msgid "" "Create the Geometry Object\n" "for milling SLOTS toolpaths." @@ -7992,11 +8447,11 @@ msgstr "" "Crear el objeto de geometría\n" "para fresar recorridos de herramientas muesca." -#: flatcamGUI/ObjectUI.py:1152 flatcamTools/ToolCutOut.py:317 +#: flatcamGUI/ObjectUI.py:1419 flatcamTools/ToolCutOut.py:327 msgid "Geometry Object" msgstr "Objeto de geometría" -#: flatcamGUI/ObjectUI.py:1186 +#: flatcamGUI/ObjectUI.py:1465 msgid "" "Tools in this Geometry object used for cutting.\n" "The 'Offset' entry will set an offset for the cut.\n" @@ -8025,23 +8480,23 @@ msgstr "" "atenuado y Cut Z se calcula automáticamente a partir de la nueva\n" "mostró entradas de formulario de IU denominadas V-Tipo Dia y V-Tipo ángulo." -#: flatcamGUI/ObjectUI.py:1203 flatcamGUI/ObjectUI.py:1903 -#: flatcamGUI/PreferencesUI.py:4405 +#: flatcamGUI/ObjectUI.py:1482 flatcamGUI/ObjectUI.py:2231 +#: flatcamGUI/PreferencesUI.py:4698 msgid "Plot Object" msgstr "Trazar objeto" -#: flatcamGUI/ObjectUI.py:1217 flatcamGUI/ObjectUI.py:1916 -#: flatcamGUI/ObjectUI.py:1926 flatcamGUI/PreferencesUI.py:7241 -#: flatcamTools/ToolCopperThieving.py:220 +#: flatcamGUI/ObjectUI.py:1495 flatcamGUI/ObjectUI.py:2244 +#: flatcamGUI/ObjectUI.py:2254 flatcamGUI/PreferencesUI.py:7747 +#: flatcamTools/ToolCopperThieving.py:222 msgid "Dia" msgstr "Dia" -#: flatcamGUI/ObjectUI.py:1217 flatcamGUI/ObjectUI.py:1916 -#: flatcamTools/ToolNonCopperClear.py:120 flatcamTools/ToolPaint.py:123 +#: flatcamGUI/ObjectUI.py:1495 flatcamGUI/ObjectUI.py:2244 +#: flatcamTools/ToolNCC.py:132 flatcamTools/ToolPaint.py:128 msgid "TT" msgstr "TT" -#: flatcamGUI/ObjectUI.py:1224 +#: flatcamGUI/ObjectUI.py:1502 msgid "" "This is the Tool Number.\n" "When ToolChange is checked, on toolchange event this value\n" @@ -8052,7 +8507,7 @@ msgstr "" "este valor\n" "se mostrará como un T1, T2 ... Tn" -#: flatcamGUI/ObjectUI.py:1235 +#: flatcamGUI/ObjectUI.py:1513 msgid "" "The value for the Offset can be:\n" "- Path -> There is no offset, the tool cut will be done through the geometry " @@ -8069,7 +8524,7 @@ msgstr "" "- Fuera (lado) -> El corte de la herramienta seguirá la línea de geometría " "en el exterior." -#: flatcamGUI/ObjectUI.py:1242 +#: flatcamGUI/ObjectUI.py:1520 msgid "" "The (Operation) Type has only informative value. Usually the UI form " "values \n" @@ -8092,7 +8547,7 @@ msgstr "" "Para el aislamiento, necesitamos un avance más bajo, ya que utiliza una " "broca de fresado con una punta fina." -#: flatcamGUI/ObjectUI.py:1251 +#: flatcamGUI/ObjectUI.py:1529 msgid "" "The Tool Type (TT) can be:\n" "- Circular with 1 ... 4 teeth -> it is informative only. Being circular the " @@ -8123,7 +8578,7 @@ msgstr "" "Elegir el tipo de herramienta en forma de V automáticamente seleccionará el " "tipo de operación como aislamiento." -#: flatcamGUI/ObjectUI.py:1263 +#: flatcamGUI/ObjectUI.py:1541 msgid "" "Plot column. It is visible only for MultiGeo geometries, meaning geometries " "that holds the geometry\n" @@ -8141,7 +8596,7 @@ msgstr "" "puede habilitar / deshabilitar la trama en el lienzo\n" "para la herramienta correspondiente." -#: flatcamGUI/ObjectUI.py:1281 +#: flatcamGUI/ObjectUI.py:1559 msgid "" "The value to offset the cut when \n" "the Offset type selected is 'Offset'.\n" @@ -8153,7 +8608,13 @@ msgstr "" "El valor puede ser positivo para 'afuera'\n" "corte y negativo para corte 'interior'." -#: flatcamGUI/ObjectUI.py:1306 +#: flatcamGUI/ObjectUI.py:1578 flatcamTools/ToolNCC.py:209 +#: flatcamTools/ToolNCC.py:923 flatcamTools/ToolPaint.py:192 +#: flatcamTools/ToolPaint.py:849 flatcamTools/ToolSolderPaste.py:559 +msgid "New Tool" +msgstr "Nueva Herram" + +#: flatcamGUI/ObjectUI.py:1595 msgid "" "Add a new tool to the Tool Table\n" "with the specified diameter." @@ -8161,11 +8622,14 @@ msgstr "" "Agregar una nueva herramienta a la tabla de herramientas\n" "con el diámetro especificado." -#: flatcamGUI/ObjectUI.py:1314 -msgid "Add Tool from DataBase" -msgstr "Agregar herramienta desde DB" +#: flatcamGUI/ObjectUI.py:1600 flatcamTools/ToolNCC.py:300 +#: flatcamTools/ToolNCC.py:634 flatcamTools/ToolPaint.py:283 +#: flatcamTools/ToolPaint.py:679 +msgid "Add from DB" +msgstr "Agregar desde DB" -#: flatcamGUI/ObjectUI.py:1316 +#: flatcamGUI/ObjectUI.py:1602 flatcamTools/ToolNCC.py:302 +#: flatcamTools/ToolPaint.py:285 msgid "" "Add a new tool to the Tool Table\n" "from the Tool DataBase." @@ -8173,7 +8637,7 @@ msgstr "" "Agregar una nueva herramienta a la tabla de herramientas\n" "de la base de datos de herramientas." -#: flatcamGUI/ObjectUI.py:1326 +#: flatcamGUI/ObjectUI.py:1617 msgid "" "Copy a selection of tools in the Tool Table\n" "by first selecting a row in the Tool Table." @@ -8181,7 +8645,7 @@ msgstr "" "Copie una selección de herramientas en la tabla de herramientas\n" "seleccionando primero una fila en la Tabla de herramientas." -#: flatcamGUI/ObjectUI.py:1332 +#: flatcamGUI/ObjectUI.py:1623 msgid "" "Delete a selection of tools in the Tool Table\n" "by first selecting a row in the Tool Table." @@ -8189,38 +8653,7 @@ msgstr "" "Eliminar una selección de herramientas en la tabla de herramientas\n" "seleccionando primero una fila en la Tabla de herramientas." -#: flatcamGUI/ObjectUI.py:1356 -msgid "" -"The data used for creating GCode.\n" -"Each tool store it's own set of such data." -msgstr "" -"Los datos utilizados para crear GCode.\n" -"Cada herramienta almacena su propio conjunto de datos." - -#: flatcamGUI/ObjectUI.py:1426 flatcamGUI/PreferencesUI.py:3981 -#: flatcamGUI/PreferencesUI.py:5348 flatcamTools/ToolCutOut.py:153 -msgid "Multi-Depth" -msgstr "Profund. Múlti" - -#: flatcamGUI/ObjectUI.py:1429 flatcamGUI/PreferencesUI.py:3984 -#: flatcamGUI/PreferencesUI.py:5351 flatcamTools/ToolCutOut.py:156 -msgid "" -"Use multiple passes to limit\n" -"the cut depth in each pass. Will\n" -"cut multiple times until Cut Z is\n" -"reached." -msgstr "" -"Usa múltiples pases para limitar\n" -"La profundidad de corte en cada pasada. Será\n" -"cortar varias veces hasta que el Corte Z sea\n" -"alcanzado." - -#: flatcamGUI/ObjectUI.py:1443 flatcamGUI/PreferencesUI.py:5363 -#: flatcamTools/ToolCutOut.py:170 -msgid "Depth of each pass (positive)." -msgstr "Profundidad de cada pase (positivo)." - -#: flatcamGUI/ObjectUI.py:1454 flatcamGUI/PreferencesUI.py:4016 +#: flatcamGUI/ObjectUI.py:1750 flatcamGUI/PreferencesUI.py:4296 msgid "" "Height of the tool when\n" "moving without cutting." @@ -8228,28 +8661,7 @@ msgstr "" "Altura de la herramienta cuando\n" "Moviéndose sin cortar." -#: flatcamGUI/ObjectUI.py:1481 flatcamGUI/PreferencesUI.py:4037 -msgid "" -"Include tool-change sequence\n" -"in the Machine Code (Pause for tool change)." -msgstr "" -"Incluir secuencia de cambio de herramienta\n" -"en el código de máquina (pausa para cambio de herramienta)." - -#: flatcamGUI/ObjectUI.py:1531 flatcamGUI/PreferencesUI.py:4086 -#: flatcamGUI/PreferencesUI.py:6553 flatcamTools/ToolSolderPaste.py:252 -msgid "Feedrate X-Y" -msgstr "Avance X-Y" - -#: flatcamGUI/ObjectUI.py:1533 flatcamGUI/PreferencesUI.py:4088 -msgid "" -"Cutting speed in the XY\n" -"plane in units per minute" -msgstr "" -"Velocidad de corte en el XY.\n" -"Avion en unidades por minuto" - -#: flatcamGUI/ObjectUI.py:1547 flatcamGUI/PreferencesUI.py:4103 +#: flatcamGUI/ObjectUI.py:1783 flatcamGUI/PreferencesUI.py:4395 msgid "" "Cutting speed in the XY\n" "plane in units per minute.\n" @@ -8259,7 +8671,7 @@ msgstr "" "Plano en unidades por minuto.\n" "Se llama también Plunge." -#: flatcamGUI/ObjectUI.py:1562 flatcamGUI/PreferencesUI.py:4212 +#: flatcamGUI/ObjectUI.py:1798 flatcamGUI/PreferencesUI.py:4505 msgid "" "Cutting speed in the XY plane\n" "(in units per minute).\n" @@ -8273,24 +8685,7 @@ msgstr "" "Es útil solo para Marlin,\n" "Ignorar para cualquier otro caso." -#: flatcamGUI/ObjectUI.py:1580 flatcamGUI/PreferencesUI.py:4228 -msgid "Re-cut" -msgstr "Recortar" - -#: flatcamGUI/ObjectUI.py:1582 flatcamGUI/ObjectUI.py:1594 -#: flatcamGUI/PreferencesUI.py:4230 flatcamGUI/PreferencesUI.py:4242 -msgid "" -"In order to remove possible\n" -"copper leftovers where first cut\n" -"meet with last cut, we generate an\n" -"extended cut over the first cut section." -msgstr "" -"Para eliminar posibles\n" -"sobras de cobre donde el primer corte\n" -"Nos reunimos con el último corte, generamos un\n" -"Corte extendido sobre la primera sección de corte." - -#: flatcamGUI/ObjectUI.py:1606 flatcamGUI/PreferencesUI.py:4120 +#: flatcamGUI/ObjectUI.py:1842 flatcamGUI/PreferencesUI.py:4412 msgid "" "Speed of the spindle in RPM (optional).\n" "If LASER preprocessor is used,\n" @@ -8300,7 +8695,15 @@ msgstr "" "Si se utiliza el postprocesador LÁSER,\n" "Este valor es el poder del láser." -#: flatcamGUI/ObjectUI.py:1642 flatcamGUI/PreferencesUI.py:4157 +#: flatcamGUI/ObjectUI.py:1945 flatcamGUI/PreferencesUI.py:4317 +msgid "" +"Include tool-change sequence\n" +"in the Machine Code (Pause for tool change)." +msgstr "" +"Incluir secuencia de cambio de herramienta\n" +"en el código de máquina (pausa para cambio de herramienta)." + +#: flatcamGUI/ObjectUI.py:2014 flatcamGUI/PreferencesUI.py:4449 msgid "" "The Preprocessor file that dictates\n" "the Machine Code (like GCode, RML, HPGL) output." @@ -8308,41 +8711,15 @@ msgstr "" "El archivo de postprocesador que dicta\n" "la salida del código de máquina (como GCode, RML, HPGL)." -#: flatcamGUI/ObjectUI.py:1689 -msgid "Apply parameters to all tools" -msgstr "Aplicar parámetros a todas las herramientas." - -#: flatcamGUI/ObjectUI.py:1691 -msgid "" -"The parameters in the current form will be applied\n" -"on all the tools from the Tool Table." -msgstr "" -"Se aplicarán los parámetros en el formulario actual\n" -"en todas las herramientas de la tabla de herramientas." - -#: flatcamGUI/ObjectUI.py:1700 -msgid "" -"Add at least one tool in the tool-table.\n" -"Click the header to select all, or Ctrl + LMB\n" -"for custom selection of tools." -msgstr "" -"Agregue al menos una herramienta en la tabla de herramientas.\n" -"Haga clic en el encabezado para seleccionar todo, o Ctrl + LMB\n" -"para la selección personalizada de herramientas." - -#: flatcamGUI/ObjectUI.py:1707 -msgid "Generate CNCJob object" -msgstr "Generar objeto CNCJob" - -#: flatcamGUI/ObjectUI.py:1709 +#: flatcamGUI/ObjectUI.py:2035 msgid "Generate the CNC Job object." msgstr "Genere el objeto de trabajo CNC." -#: flatcamGUI/ObjectUI.py:1726 +#: flatcamGUI/ObjectUI.py:2052 msgid "Launch Paint Tool in Tools Tab." msgstr "Inicie la herramienta Pintura en la pestaña Herramientas." -#: flatcamGUI/ObjectUI.py:1734 flatcamGUI/PreferencesUI.py:5524 +#: flatcamGUI/ObjectUI.py:2060 flatcamGUI/PreferencesUI.py:5874 msgid "" "Creates tool paths to cover the\n" "whole area of a polygon (remove\n" @@ -8354,15 +8731,15 @@ msgstr "" "todo el cobre). Te harán preguntas\n" "Para hacer clic en el polígono deseado." -#: flatcamGUI/ObjectUI.py:1786 +#: flatcamGUI/ObjectUI.py:2115 msgid "CNC Job Object" msgstr "Objeto de trabajo CNC" -#: flatcamGUI/ObjectUI.py:1798 flatcamGUI/PreferencesUI.py:4410 +#: flatcamGUI/ObjectUI.py:2126 flatcamGUI/PreferencesUI.py:4703 msgid "Plot kind" msgstr "Tipo de trazado" -#: flatcamGUI/ObjectUI.py:1801 flatcamGUI/PreferencesUI.py:4412 +#: flatcamGUI/ObjectUI.py:2129 flatcamGUI/PreferencesUI.py:4705 msgid "" "This selects the kind of geometries on the canvas to plot.\n" "Those can be either of type 'Travel' which means the moves\n" @@ -8374,15 +8751,15 @@ msgstr "" "Por encima de la pieza de trabajo o puede ser de tipo 'Corte',\n" "Lo que significa los movimientos que cortan en el material." -#: flatcamGUI/ObjectUI.py:1810 flatcamGUI/PreferencesUI.py:4420 +#: flatcamGUI/ObjectUI.py:2138 flatcamGUI/PreferencesUI.py:4713 msgid "Travel" msgstr "Viajar" -#: flatcamGUI/ObjectUI.py:1814 flatcamGUI/PreferencesUI.py:4429 +#: flatcamGUI/ObjectUI.py:2142 flatcamGUI/PreferencesUI.py:4722 msgid "Display Annotation" msgstr "Mostrar anotación" -#: flatcamGUI/ObjectUI.py:1816 flatcamGUI/PreferencesUI.py:4431 +#: flatcamGUI/ObjectUI.py:2144 flatcamGUI/PreferencesUI.py:4724 msgid "" "This selects if to display text annotation on the plot.\n" "When checked it will display numbers in order for each end\n" @@ -8392,11 +8769,11 @@ msgstr "" "Cuando está marcado, mostrará números en orden para cada final.\n" "de una linea de viaje." -#: flatcamGUI/ObjectUI.py:1831 +#: flatcamGUI/ObjectUI.py:2159 msgid "Travelled dist." msgstr "Dist. recorrida" -#: flatcamGUI/ObjectUI.py:1833 flatcamGUI/ObjectUI.py:1838 +#: flatcamGUI/ObjectUI.py:2161 flatcamGUI/ObjectUI.py:2166 msgid "" "This is the total travelled distance on X-Y plane.\n" "In current units." @@ -8404,11 +8781,11 @@ msgstr "" "Esta es la distancia total recorrida en el plano X-Y.\n" "En unidades actuales." -#: flatcamGUI/ObjectUI.py:1843 +#: flatcamGUI/ObjectUI.py:2171 msgid "Estimated time" msgstr "Duración estimada" -#: flatcamGUI/ObjectUI.py:1845 flatcamGUI/ObjectUI.py:1850 +#: flatcamGUI/ObjectUI.py:2173 flatcamGUI/ObjectUI.py:2178 msgid "" "This is the estimated time to do the routing/drilling,\n" "without the time spent in ToolChange events." @@ -8416,11 +8793,11 @@ msgstr "" "Este es el tiempo estimado para hacer el enrutamiento / perforación,\n" "sin el tiempo dedicado a los eventos de cambio de herramienta." -#: flatcamGUI/ObjectUI.py:1885 +#: flatcamGUI/ObjectUI.py:2213 msgid "CNC Tools Table" msgstr "Tabla de herramientas CNC" -#: flatcamGUI/ObjectUI.py:1888 +#: flatcamGUI/ObjectUI.py:2216 msgid "" "Tools in this CNCJob object used for cutting.\n" "The tool diameter is used for plotting on canvas.\n" @@ -8443,24 +8820,24 @@ msgstr "" "C4),\n" "bola (B) o en forma de V (V)." -#: flatcamGUI/ObjectUI.py:1916 flatcamGUI/ObjectUI.py:1927 +#: flatcamGUI/ObjectUI.py:2244 flatcamGUI/ObjectUI.py:2255 msgid "P" msgstr "P" -#: flatcamGUI/ObjectUI.py:1937 +#: flatcamGUI/ObjectUI.py:2265 msgid "Update Plot" msgstr "Actualizar Trama" -#: flatcamGUI/ObjectUI.py:1939 +#: flatcamGUI/ObjectUI.py:2267 msgid "Update the plot." msgstr "Actualiza la trama." -#: flatcamGUI/ObjectUI.py:1946 flatcamGUI/PreferencesUI.py:4827 +#: flatcamGUI/ObjectUI.py:2274 flatcamGUI/PreferencesUI.py:5120 msgid "Export CNC Code" msgstr "Exportar código CNC" -#: flatcamGUI/ObjectUI.py:1948 flatcamGUI/PreferencesUI.py:4768 -#: flatcamGUI/PreferencesUI.py:4829 +#: flatcamGUI/ObjectUI.py:2276 flatcamGUI/PreferencesUI.py:5061 +#: flatcamGUI/PreferencesUI.py:5122 msgid "" "Export and save G-Code to\n" "make this object to a file." @@ -8468,12 +8845,12 @@ msgstr "" "Exportar y guardar código G a\n" "Hacer este objeto a un archivo." -#: flatcamGUI/ObjectUI.py:1954 +#: flatcamGUI/ObjectUI.py:2282 msgid "Prepend to CNC Code" msgstr "Anteponer al código del CNC" -#: flatcamGUI/ObjectUI.py:1956 flatcamGUI/ObjectUI.py:1963 -#: flatcamGUI/PreferencesUI.py:4784 +#: flatcamGUI/ObjectUI.py:2284 flatcamGUI/ObjectUI.py:2291 +#: flatcamGUI/PreferencesUI.py:5077 msgid "" "Type here any G-Code commands you would\n" "like to add at the beginning of the G-Code file." @@ -8481,12 +8858,12 @@ msgstr "" "Escribe aquí cualquier comando de G-Code que quieras\n" "Me gusta agregar al principio del archivo G-Code." -#: flatcamGUI/ObjectUI.py:1969 +#: flatcamGUI/ObjectUI.py:2297 msgid "Append to CNC Code" msgstr "Añadir al código CNC" -#: flatcamGUI/ObjectUI.py:1971 flatcamGUI/ObjectUI.py:1979 -#: flatcamGUI/PreferencesUI.py:4800 +#: flatcamGUI/ObjectUI.py:2299 flatcamGUI/ObjectUI.py:2307 +#: flatcamGUI/PreferencesUI.py:5093 msgid "" "Type here any G-Code commands you would\n" "like to append to the generated file.\n" @@ -8496,11 +8873,11 @@ msgstr "" "Me gusta adjuntar al archivo generado.\n" "Es decir: M2 (Fin del programa)" -#: flatcamGUI/ObjectUI.py:1993 flatcamGUI/PreferencesUI.py:4835 +#: flatcamGUI/ObjectUI.py:2321 flatcamGUI/PreferencesUI.py:5128 msgid "Toolchange G-Code" msgstr "Cambio de herra. G-Code" -#: flatcamGUI/ObjectUI.py:1996 flatcamGUI/PreferencesUI.py:4838 +#: flatcamGUI/ObjectUI.py:2324 flatcamGUI/PreferencesUI.py:5131 msgid "" "Type here any G-Code commands you would\n" "like to be executed when Toolchange event is encountered.\n" @@ -8522,7 +8899,7 @@ msgstr "" "que tiene 'toolchange_custom' en su nombre y esto está construido\n" "teniendo como plantilla el archivo posprocesador 'Toolchange Custom'." -#: flatcamGUI/ObjectUI.py:2011 +#: flatcamGUI/ObjectUI.py:2339 msgid "" "Type here any G-Code commands you would\n" "like to be executed when Toolchange event is encountered.\n" @@ -8540,11 +8917,11 @@ msgstr "" "ADVERTENCIA: solo se puede usar con un archivo de preprocesador\n" "que tiene 'toolchange_custom' en su nombre." -#: flatcamGUI/ObjectUI.py:2026 flatcamGUI/PreferencesUI.py:4877 +#: flatcamGUI/ObjectUI.py:2354 flatcamGUI/PreferencesUI.py:5170 msgid "Use Toolchange Macro" msgstr "Util. la herra. de cambio de macro" -#: flatcamGUI/ObjectUI.py:2028 flatcamGUI/PreferencesUI.py:4879 +#: flatcamGUI/ObjectUI.py:2356 flatcamGUI/PreferencesUI.py:5172 msgid "" "Check this box if you want to use\n" "a Custom Toolchange GCode (macro)." @@ -8552,7 +8929,7 @@ msgstr "" "Marque esta casilla si desea utilizar\n" "una herramienta personalizada para cambiar GCode (macro)." -#: flatcamGUI/ObjectUI.py:2036 flatcamGUI/PreferencesUI.py:4891 +#: flatcamGUI/ObjectUI.py:2364 flatcamGUI/PreferencesUI.py:5184 msgid "" "A list of the FlatCAM variables that can be used\n" "in the Toolchange event.\n" @@ -8562,74 +8939,76 @@ msgstr "" "en el evento Cambio de herramienta.\n" "Deben estar rodeados por el símbolo '%'" -#: flatcamGUI/ObjectUI.py:2043 flatcamGUI/PreferencesUI.py:2447 -#: flatcamGUI/PreferencesUI.py:3555 flatcamGUI/PreferencesUI.py:4347 -#: flatcamGUI/PreferencesUI.py:4898 flatcamGUI/PreferencesUI.py:5017 -#: flatcamGUI/PreferencesUI.py:5301 flatcamGUI/PreferencesUI.py:5458 -#: flatcamGUI/PreferencesUI.py:5676 flatcamGUI/PreferencesUI.py:5973 -#: flatcamGUI/PreferencesUI.py:6224 flatcamGUI/PreferencesUI.py:6438 -#: flatcamGUI/PreferencesUI.py:6663 flatcamGUI/PreferencesUI.py:6685 -#: flatcamGUI/PreferencesUI.py:6909 flatcamGUI/PreferencesUI.py:6946 -#: flatcamGUI/PreferencesUI.py:7140 flatcamGUI/PreferencesUI.py:7394 -#: flatcamGUI/PreferencesUI.py:7510 flatcamTools/ToolCopperThieving.py:89 -#: flatcamTools/ToolFiducials.py:149 flatcamTools/ToolNonCopperClear.py:315 +#: flatcamGUI/ObjectUI.py:2371 flatcamGUI/PreferencesUI.py:2627 +#: flatcamGUI/PreferencesUI.py:3833 flatcamGUI/PreferencesUI.py:4640 +#: flatcamGUI/PreferencesUI.py:5191 flatcamGUI/PreferencesUI.py:5310 +#: flatcamGUI/PreferencesUI.py:5640 flatcamGUI/PreferencesUI.py:5797 +#: flatcamGUI/PreferencesUI.py:6164 flatcamGUI/PreferencesUI.py:6461 +#: flatcamGUI/PreferencesUI.py:6711 flatcamGUI/PreferencesUI.py:6942 +#: flatcamGUI/PreferencesUI.py:7169 flatcamGUI/PreferencesUI.py:7191 +#: flatcamGUI/PreferencesUI.py:7415 flatcamGUI/PreferencesUI.py:7452 +#: flatcamGUI/PreferencesUI.py:7646 flatcamGUI/PreferencesUI.py:7900 +#: flatcamGUI/PreferencesUI.py:8016 flatcamGUI/PreferencesUI.py:8135 +#: flatcamGUI/PreferencesUI.py:8347 flatcamGUI/PreferencesUI.py:8556 +#: flatcamTools/ToolCopperThieving.py:90 flatcamTools/ToolFiducials.py:149 +#: flatcamTools/ToolInvertGerber.py:82 msgid "Parameters" msgstr "Parámetros" -#: flatcamGUI/ObjectUI.py:2046 flatcamGUI/PreferencesUI.py:4903 +#: flatcamGUI/ObjectUI.py:2374 flatcamGUI/PreferencesUI.py:5196 msgid "FlatCAM CNC parameters" msgstr "Parámetros de FlatCAM CNC" -#: flatcamGUI/ObjectUI.py:2047 flatcamGUI/PreferencesUI.py:4908 +#: flatcamGUI/ObjectUI.py:2375 flatcamGUI/PreferencesUI.py:5201 msgid "tool number" msgstr "número de herramienta" -#: flatcamGUI/ObjectUI.py:2048 flatcamGUI/PreferencesUI.py:4909 +#: flatcamGUI/ObjectUI.py:2376 flatcamGUI/PreferencesUI.py:5202 msgid "tool diameter" msgstr "diámetro de herramienta" -#: flatcamGUI/ObjectUI.py:2049 flatcamGUI/PreferencesUI.py:4910 +#: flatcamGUI/ObjectUI.py:2377 flatcamGUI/PreferencesUI.py:5203 msgid "for Excellon, total number of drills" msgstr "para Excellon, núm. total de taladros" -#: flatcamGUI/ObjectUI.py:2051 flatcamGUI/PreferencesUI.py:4912 +#: flatcamGUI/ObjectUI.py:2379 flatcamGUI/PreferencesUI.py:5205 msgid "X coord for Toolchange" msgstr "Coord. X para Cambio de Herramienta" -#: flatcamGUI/ObjectUI.py:2052 flatcamGUI/PreferencesUI.py:4913 +#: flatcamGUI/ObjectUI.py:2380 flatcamGUI/PreferencesUI.py:5206 msgid "Y coord for Toolchange" msgstr "Coord. Y para Cambio de Herramienta" -#: flatcamGUI/ObjectUI.py:2053 flatcamGUI/PreferencesUI.py:4915 +#: flatcamGUI/ObjectUI.py:2381 flatcamGUI/PreferencesUI.py:5208 msgid "Z coord for Toolchange" msgstr "Coord Z para cambio de herramientas" -#: flatcamGUI/ObjectUI.py:2054 +#: flatcamGUI/ObjectUI.py:2382 msgid "depth where to cut" msgstr "profundidad donde cortar" -#: flatcamGUI/ObjectUI.py:2055 +#: flatcamGUI/ObjectUI.py:2383 msgid "height where to travel" msgstr "altura donde viajar" -#: flatcamGUI/ObjectUI.py:2056 flatcamGUI/PreferencesUI.py:4918 +#: flatcamGUI/ObjectUI.py:2384 flatcamGUI/PreferencesUI.py:5211 msgid "the step value for multidepth cut" msgstr "el valor del paso para corte de profundidad múltiple" -#: flatcamGUI/ObjectUI.py:2058 flatcamGUI/PreferencesUI.py:4920 +#: flatcamGUI/ObjectUI.py:2386 flatcamGUI/PreferencesUI.py:5213 msgid "the value for the spindle speed" msgstr "el valor de la velocidad del husillo" -#: flatcamGUI/ObjectUI.py:2060 +#: flatcamGUI/ObjectUI.py:2388 msgid "time to dwell to allow the spindle to reach it's set RPM" msgstr "" "tiempo de espera para permitir que el husillo alcance su RPM establecido" -#: flatcamGUI/ObjectUI.py:2076 +#: flatcamGUI/ObjectUI.py:2404 msgid "View CNC Code" msgstr "Ver código CNC" -#: flatcamGUI/ObjectUI.py:2078 +#: flatcamGUI/ObjectUI.py:2406 msgid "" "Opens TAB to view/modify/print G-Code\n" "file." @@ -8637,11 +9016,11 @@ msgstr "" "Abre la pestaña para ver / modificar / imprimir el código G\n" "expediente." -#: flatcamGUI/ObjectUI.py:2083 +#: flatcamGUI/ObjectUI.py:2411 msgid "Save CNC Code" msgstr "Guardar código CNC" -#: flatcamGUI/ObjectUI.py:2085 +#: flatcamGUI/ObjectUI.py:2413 msgid "" "Opens dialog to save G-Code\n" "file." @@ -8649,85 +9028,81 @@ msgstr "" "Abre el diálogo para guardar el código G\n" "expediente." -#: flatcamGUI/ObjectUI.py:2116 +#: flatcamGUI/ObjectUI.py:2447 msgid "Script Object" msgstr "Objeto de script" -#: flatcamGUI/ObjectUI.py:2138 flatcamGUI/ObjectUI.py:2211 +#: flatcamGUI/ObjectUI.py:2467 flatcamGUI/ObjectUI.py:2541 msgid "Auto Completer" msgstr "Autocompletador" -#: flatcamGUI/ObjectUI.py:2140 +#: flatcamGUI/ObjectUI.py:2469 msgid "This selects if the auto completer is enabled in the Script Editor." msgstr "" "Esto selecciona si el autocompletador está habilitado en el Editor de " "secuencias de comandos." -#: flatcamGUI/ObjectUI.py:2182 +#: flatcamGUI/ObjectUI.py:2514 msgid "Document Object" msgstr "Objeto de Documento" -#: flatcamGUI/ObjectUI.py:2213 +#: flatcamGUI/ObjectUI.py:2543 msgid "This selects if the auto completer is enabled in the Document Editor." msgstr "" "Esto selecciona si el autocompletador está habilitado en el Editor de " "Documentos." -#: flatcamGUI/ObjectUI.py:2231 +#: flatcamGUI/ObjectUI.py:2561 msgid "Font Type" msgstr "Tipo de Fuente" -#: flatcamGUI/ObjectUI.py:2248 flatcamGUI/PreferencesUI.py:1103 +#: flatcamGUI/ObjectUI.py:2578 flatcamGUI/PreferencesUI.py:1278 msgid "Font Size" msgstr "Tamaño de Fuente" -#: flatcamGUI/ObjectUI.py:2284 +#: flatcamGUI/ObjectUI.py:2614 msgid "Alignment" msgstr "Alineación" -#: flatcamGUI/ObjectUI.py:2289 +#: flatcamGUI/ObjectUI.py:2619 msgid "Align Left" msgstr "Alinear a la izquierda" -#: flatcamGUI/ObjectUI.py:2294 -msgid "Center" -msgstr "Centrar" - -#: flatcamGUI/ObjectUI.py:2299 +#: flatcamGUI/ObjectUI.py:2629 msgid "Align Right" msgstr "Alinear a la derecha" -#: flatcamGUI/ObjectUI.py:2304 +#: flatcamGUI/ObjectUI.py:2634 msgid "Justify" msgstr "Alinear Justificar" -#: flatcamGUI/ObjectUI.py:2311 +#: flatcamGUI/ObjectUI.py:2641 msgid "Font Color" msgstr "Color de Fuente" -#: flatcamGUI/ObjectUI.py:2313 +#: flatcamGUI/ObjectUI.py:2643 msgid "Set the font color for the selected text" msgstr "Establecer el color de fuente para el texto seleccionado" -#: flatcamGUI/ObjectUI.py:2327 +#: flatcamGUI/ObjectUI.py:2657 msgid "Selection Color" msgstr "Color de seleccion" -#: flatcamGUI/ObjectUI.py:2329 +#: flatcamGUI/ObjectUI.py:2659 msgid "Set the selection color when doing text selection." msgstr "Establezca el color de selección al hacer la selección de texto." -#: flatcamGUI/ObjectUI.py:2343 +#: flatcamGUI/ObjectUI.py:2673 msgid "Tab Size" msgstr "Tamaño de Pestaña" -#: flatcamGUI/ObjectUI.py:2345 +#: flatcamGUI/ObjectUI.py:2675 msgid "Set the tab size. In pixels. Default value is 80 pixels." msgstr "" "Establece el tamaño de la pestaña. En píxeles El valor predeterminado es 80 " "píxeles." -#: flatcamGUI/PlotCanvasLegacy.py:1254 +#: flatcamGUI/PlotCanvasLegacy.py:1301 msgid "" "Could not annotate due of a difference between the number of text elements " "and the number of text positions." @@ -8735,31 +9110,35 @@ msgstr "" "No se pudo anotar debido a una diferencia entre el número de elementos de " "texto y el número de posiciones de texto." -#: flatcamGUI/PreferencesUI.py:324 +#: flatcamGUI/PreferencesUI.py:343 msgid "GUI Preferences" msgstr "Preferencias de GUI" -#: flatcamGUI/PreferencesUI.py:334 +#: flatcamGUI/PreferencesUI.py:353 msgid "Theme" msgstr "Tema" -#: flatcamGUI/PreferencesUI.py:336 -msgid "Select a theme for FlatCAM." -msgstr "Seleccione un tema para FlatCAM." +#: flatcamGUI/PreferencesUI.py:355 +msgid "" +"Select a theme for FlatCAM.\n" +"It will theme the plot area." +msgstr "" +"Seleccione un tema para FlatCAM.\n" +"Será el tema del área de la trama." -#: flatcamGUI/PreferencesUI.py:340 +#: flatcamGUI/PreferencesUI.py:360 msgid "Light" msgstr "Ligera" -#: flatcamGUI/PreferencesUI.py:341 +#: flatcamGUI/PreferencesUI.py:361 msgid "Dark" msgstr "Oscuro" -#: flatcamGUI/PreferencesUI.py:348 +#: flatcamGUI/PreferencesUI.py:368 msgid "Use Gray Icons" msgstr "Use iconos grises" -#: flatcamGUI/PreferencesUI.py:350 +#: flatcamGUI/PreferencesUI.py:370 msgid "" "Check this box to use a set of icons with\n" "a lighter (gray) color. To be used when a\n" @@ -8769,23 +9148,25 @@ msgstr "" "un color más claro (gris). Para ser utilizado cuando un\n" "Se aplica el tema oscuro completo." -#: flatcamGUI/PreferencesUI.py:356 +#: flatcamGUI/PreferencesUI.py:376 msgid "Apply Theme" msgstr "Aplicar tema" -#: flatcamGUI/PreferencesUI.py:358 +#: flatcamGUI/PreferencesUI.py:378 msgid "" "Select a theme for FlatCAM.\n" +"It will theme the plot area.\n" "The application will restart after change." msgstr "" "Seleccione un tema para FlatCAM.\n" +"Tematizará el área de trazado.\n" "La aplicación se reiniciará después del cambio." -#: flatcamGUI/PreferencesUI.py:369 +#: flatcamGUI/PreferencesUI.py:390 msgid "Layout" msgstr "Diseño" -#: flatcamGUI/PreferencesUI.py:371 +#: flatcamGUI/PreferencesUI.py:392 msgid "" "Select an layout for FlatCAM.\n" "It is applied immediately." @@ -8793,11 +9174,11 @@ msgstr "" "Seleccione un diseño para FlatCAM.\n" "Se aplica de inmediato." -#: flatcamGUI/PreferencesUI.py:390 +#: flatcamGUI/PreferencesUI.py:412 msgid "Style" msgstr "Estilo" -#: flatcamGUI/PreferencesUI.py:392 +#: flatcamGUI/PreferencesUI.py:414 msgid "" "Select an style for FlatCAM.\n" "It will be applied at the next app start." @@ -8805,11 +9186,11 @@ msgstr "" "Seleccione un estilo para FlatCAM.\n" "Se aplicará en el próximo inicio de la aplicación." -#: flatcamGUI/PreferencesUI.py:406 +#: flatcamGUI/PreferencesUI.py:428 msgid "Activate HDPI Support" msgstr "Activar soporte HDPI" -#: flatcamGUI/PreferencesUI.py:408 +#: flatcamGUI/PreferencesUI.py:430 msgid "" "Enable High DPI support for FlatCAM.\n" "It will be applied at the next app start." @@ -8817,11 +9198,11 @@ msgstr "" "Habilitar el soporte de alta DPI para FlatCAM.\n" "Se aplicará en el próximo inicio de la aplicación." -#: flatcamGUI/PreferencesUI.py:422 +#: flatcamGUI/PreferencesUI.py:444 msgid "Display Hover Shape" msgstr "Mostrar forma de desplazamiento" -#: flatcamGUI/PreferencesUI.py:424 +#: flatcamGUI/PreferencesUI.py:446 msgid "" "Enable display of a hover shape for FlatCAM objects.\n" "It is displayed whenever the mouse cursor is hovering\n" @@ -8831,11 +9212,11 @@ msgstr "" "Se muestra cada vez que el cursor del mouse se desplaza\n" "sobre cualquier tipo de objeto no seleccionado." -#: flatcamGUI/PreferencesUI.py:431 +#: flatcamGUI/PreferencesUI.py:453 msgid "Display Selection Shape" msgstr "Mostrar forma de selección" -#: flatcamGUI/PreferencesUI.py:433 +#: flatcamGUI/PreferencesUI.py:455 msgid "" "Enable the display of a selection shape for FlatCAM objects.\n" "It is displayed whenever the mouse selects an object\n" @@ -8847,30 +9228,30 @@ msgstr "" "ya sea haciendo clic o arrastrando el mouse de izquierda a derecha o\n" "De derecha a izquierda." -#: flatcamGUI/PreferencesUI.py:446 +#: flatcamGUI/PreferencesUI.py:468 msgid "Left-Right Selection Color" msgstr "Color de selección izquierda-derecha" -#: flatcamGUI/PreferencesUI.py:449 flatcamGUI/PreferencesUI.py:515 -#: flatcamGUI/PreferencesUI.py:1882 flatcamGUI/PreferencesUI.py:2903 -#: flatcamGUI/PreferencesUI.py:3894 flatcamGUI/PreferencesUI.py:4534 -#: flatcamGUI/PreferencesUI.py:4600 flatcamTools/ToolRulesCheck.py:179 +#: flatcamGUI/PreferencesUI.py:471 flatcamGUI/PreferencesUI.py:537 +#: flatcamGUI/PreferencesUI.py:2062 flatcamGUI/PreferencesUI.py:3085 +#: flatcamGUI/PreferencesUI.py:4174 flatcamGUI/PreferencesUI.py:4827 +#: flatcamGUI/PreferencesUI.py:4893 flatcamTools/ToolRulesCheck.py:186 msgid "Outline" msgstr "Contorno" -#: flatcamGUI/PreferencesUI.py:451 +#: flatcamGUI/PreferencesUI.py:473 msgid "Set the line color for the 'left to right' selection box." msgstr "" "Establezca el color de línea para el cuadro de selección 'de izquierda a " "derecha'." -#: flatcamGUI/PreferencesUI.py:465 flatcamGUI/PreferencesUI.py:532 -#: flatcamGUI/PreferencesUI.py:1899 flatcamGUI/PreferencesUI.py:2920 -#: flatcamGUI/PreferencesUI.py:4551 flatcamGUI/PreferencesUI.py:4617 +#: flatcamGUI/PreferencesUI.py:487 flatcamGUI/PreferencesUI.py:554 +#: flatcamGUI/PreferencesUI.py:2079 flatcamGUI/PreferencesUI.py:3102 +#: flatcamGUI/PreferencesUI.py:4844 flatcamGUI/PreferencesUI.py:4910 msgid "Fill" msgstr "Llenado" -#: flatcamGUI/PreferencesUI.py:467 +#: flatcamGUI/PreferencesUI.py:489 msgid "" "Set the fill color for the selection box\n" "in case that the selection is done from left to right.\n" @@ -8882,29 +9263,29 @@ msgstr "" "Los primeros 6 dígitos son el color y los 2 últimos.\n" "Los dígitos son para el nivel alfa (transparencia)." -#: flatcamGUI/PreferencesUI.py:485 flatcamGUI/PreferencesUI.py:552 -#: flatcamGUI/PreferencesUI.py:1918 flatcamGUI/PreferencesUI.py:2939 -#: flatcamGUI/PreferencesUI.py:4570 +#: flatcamGUI/PreferencesUI.py:507 flatcamGUI/PreferencesUI.py:574 +#: flatcamGUI/PreferencesUI.py:2098 flatcamGUI/PreferencesUI.py:3121 +#: flatcamGUI/PreferencesUI.py:4863 msgid "Alpha" msgstr "Alfa" -#: flatcamGUI/PreferencesUI.py:487 +#: flatcamGUI/PreferencesUI.py:509 msgid "Set the fill transparency for the 'left to right' selection box." msgstr "" "Establezca la transparencia de relleno para el cuadro de selección 'de " "izquierda a derecha'." -#: flatcamGUI/PreferencesUI.py:511 +#: flatcamGUI/PreferencesUI.py:533 msgid "Right-Left Selection Color" msgstr "Color de selección derecha-izquierda" -#: flatcamGUI/PreferencesUI.py:517 +#: flatcamGUI/PreferencesUI.py:539 msgid "Set the line color for the 'right to left' selection box." msgstr "" "Establezca el color de línea para el cuadro de selección 'de derecha a " "izquierda'." -#: flatcamGUI/PreferencesUI.py:534 +#: flatcamGUI/PreferencesUI.py:556 msgid "" "Set the fill color for the selection box\n" "in case that the selection is done from right to left.\n" @@ -8916,46 +9297,46 @@ msgstr "" "Los primeros 6 dígitos son el color y los 2 últimos.\n" "Los dígitos son para el nivel alfa (transparencia)." -#: flatcamGUI/PreferencesUI.py:554 +#: flatcamGUI/PreferencesUI.py:576 msgid "Set the fill transparency for selection 'right to left' box." msgstr "" "Establezca la transparencia de relleno para el cuadro de selección \"de " "derecha a izquierda\"." -#: flatcamGUI/PreferencesUI.py:581 +#: flatcamGUI/PreferencesUI.py:603 msgid "Editor Color" msgstr "Color del editor" -#: flatcamGUI/PreferencesUI.py:585 +#: flatcamGUI/PreferencesUI.py:607 msgid "Drawing" msgstr "Dibujo" -#: flatcamGUI/PreferencesUI.py:587 +#: flatcamGUI/PreferencesUI.py:609 msgid "Set the color for the shape." msgstr "Establecer el color de la forma." -#: flatcamGUI/PreferencesUI.py:604 +#: flatcamGUI/PreferencesUI.py:626 msgid "Set the color of the shape when selected." msgstr "Establecer el color de la forma cuando se selecciona." -#: flatcamGUI/PreferencesUI.py:627 +#: flatcamGUI/PreferencesUI.py:649 msgid "Project Items Color" msgstr "Color de los elementos del proyecto" -#: flatcamGUI/PreferencesUI.py:631 +#: flatcamGUI/PreferencesUI.py:653 msgid "Enabled" msgstr "Habilitado" -#: flatcamGUI/PreferencesUI.py:633 +#: flatcamGUI/PreferencesUI.py:655 msgid "Set the color of the items in Project Tab Tree." msgstr "" "Establecer el color de los elementos en el árbol de pestañas del proyecto." -#: flatcamGUI/PreferencesUI.py:647 +#: flatcamGUI/PreferencesUI.py:669 msgid "Disabled" msgstr "Discapacitado" -#: flatcamGUI/PreferencesUI.py:649 +#: flatcamGUI/PreferencesUI.py:671 msgid "" "Set the color of the items in Project Tab Tree,\n" "for the case when the items are disabled." @@ -8963,7 +9344,11 @@ msgstr "" "Establecer el color de los elementos en el árbol de pestañas del proyecto,\n" "para el caso cuando los elementos están deshabilitados." -#: flatcamGUI/PreferencesUI.py:667 +#: flatcamGUI/PreferencesUI.py:687 +msgid "Project AutoHide" +msgstr "Proyecto auto ocultar" + +#: flatcamGUI/PreferencesUI.py:689 msgid "" "Check this box if you want the project/selected/tool tab area to\n" "hide automatically when there are no objects loaded and\n" @@ -8974,43 +9359,43 @@ msgstr "" "Se oculta automáticamente cuando no hay objetos cargados y\n" "para mostrar cada vez que se crea un nuevo objeto." -#: flatcamGUI/PreferencesUI.py:934 +#: flatcamGUI/PreferencesUI.py:1109 msgid "App Settings" msgstr "Configuración de Aplicación" -#: flatcamGUI/PreferencesUI.py:955 +#: flatcamGUI/PreferencesUI.py:1130 msgid "Grid Settings" msgstr "Configuración de cuadrícula" -#: flatcamGUI/PreferencesUI.py:959 +#: flatcamGUI/PreferencesUI.py:1134 msgid "X value" msgstr "Valor X" -#: flatcamGUI/PreferencesUI.py:961 +#: flatcamGUI/PreferencesUI.py:1136 msgid "This is the Grid snap value on X axis." msgstr "Este es el valor de ajuste de cuadrícula en el eje X." -#: flatcamGUI/PreferencesUI.py:971 +#: flatcamGUI/PreferencesUI.py:1146 msgid "Y value" msgstr "Valor Y" -#: flatcamGUI/PreferencesUI.py:973 +#: flatcamGUI/PreferencesUI.py:1148 msgid "This is the Grid snap value on Y axis." msgstr "Este es el valor de ajuste de cuadrícula en el eje Y." -#: flatcamGUI/PreferencesUI.py:983 +#: flatcamGUI/PreferencesUI.py:1158 msgid "Snap Max" msgstr "Máx. de ajuste" -#: flatcamGUI/PreferencesUI.py:998 +#: flatcamGUI/PreferencesUI.py:1173 msgid "Workspace Settings" msgstr "Configuración del espacio de trabajo" -#: flatcamGUI/PreferencesUI.py:1001 +#: flatcamGUI/PreferencesUI.py:1176 msgid "Active" msgstr "Activo" -#: flatcamGUI/PreferencesUI.py:1003 +#: flatcamGUI/PreferencesUI.py:1178 msgid "" "Draw a delimiting rectangle on canvas.\n" "The purpose is to illustrate the limits for our work." @@ -9018,7 +9403,7 @@ msgstr "" "Dibuja un rectángulo delimitador en el lienzo.\n" "El propósito es ilustrar los límites de nuestro trabajo." -#: flatcamGUI/PreferencesUI.py:1011 +#: flatcamGUI/PreferencesUI.py:1186 msgid "" "Select the type of rectangle to be used on canvas,\n" "as valid workspace." @@ -9026,12 +9411,12 @@ msgstr "" "Seleccione el tipo de rectángulo a utilizar en el lienzo,\n" "como espacio de trabajo válido." -#: flatcamGUI/PreferencesUI.py:1077 +#: flatcamGUI/PreferencesUI.py:1252 msgid "Orientation" msgstr "Orientación" -#: flatcamGUI/PreferencesUI.py:1078 flatcamGUI/PreferencesUI.py:5884 -#: flatcamTools/ToolFilm.py:420 +#: flatcamGUI/PreferencesUI.py:1253 flatcamGUI/PreferencesUI.py:6372 +#: flatcamTools/ToolFilm.py:422 msgid "" "Can be:\n" "- Portrait\n" @@ -9041,21 +9426,21 @@ msgstr "" "- retrato\n" "- paisaje" -#: flatcamGUI/PreferencesUI.py:1082 flatcamGUI/PreferencesUI.py:5888 -#: flatcamTools/ToolFilm.py:424 +#: flatcamGUI/PreferencesUI.py:1257 flatcamGUI/PreferencesUI.py:6376 +#: flatcamTools/ToolFilm.py:426 msgid "Portrait" msgstr "Retrato" -#: flatcamGUI/PreferencesUI.py:1083 flatcamGUI/PreferencesUI.py:5889 -#: flatcamTools/ToolFilm.py:425 +#: flatcamGUI/PreferencesUI.py:1258 flatcamGUI/PreferencesUI.py:6377 +#: flatcamTools/ToolFilm.py:427 msgid "Landscape" msgstr "Paisaje" -#: flatcamGUI/PreferencesUI.py:1107 +#: flatcamGUI/PreferencesUI.py:1282 msgid "Notebook" msgstr "Cuaderno" -#: flatcamGUI/PreferencesUI.py:1109 +#: flatcamGUI/PreferencesUI.py:1284 msgid "" "This sets the font size for the elements found in the Notebook.\n" "The notebook is the collapsible area in the left side of the GUI,\n" @@ -9066,19 +9451,19 @@ msgstr "" "El cuaderno es el área plegable en el lado izquierdo de la GUI,\n" "e incluye las pestañas Proyecto, Seleccionado y Herramienta." -#: flatcamGUI/PreferencesUI.py:1128 +#: flatcamGUI/PreferencesUI.py:1303 msgid "Axis" msgstr "Eje" -#: flatcamGUI/PreferencesUI.py:1130 +#: flatcamGUI/PreferencesUI.py:1305 msgid "This sets the font size for canvas axis." msgstr "Esto establece el tamaño de fuente para el eje del lienzo." -#: flatcamGUI/PreferencesUI.py:1147 +#: flatcamGUI/PreferencesUI.py:1322 msgid "Textbox" msgstr "Caja de texto" -#: flatcamGUI/PreferencesUI.py:1149 +#: flatcamGUI/PreferencesUI.py:1324 msgid "" "This sets the font size for the Textbox GUI\n" "elements that are used in FlatCAM." @@ -9086,15 +9471,15 @@ msgstr "" "Esto establece el tamaño de fuente para la GUI del cuadro de texto\n" "elementos que se usan en FlatCAM." -#: flatcamGUI/PreferencesUI.py:1175 +#: flatcamGUI/PreferencesUI.py:1350 msgid "Mouse Settings" msgstr "Configuraciones del mouse" -#: flatcamGUI/PreferencesUI.py:1179 +#: flatcamGUI/PreferencesUI.py:1354 msgid "Cursor Shape" msgstr "Forma del cursor" -#: flatcamGUI/PreferencesUI.py:1181 +#: flatcamGUI/PreferencesUI.py:1356 msgid "" "Choose a mouse cursor shape.\n" "- Small -> with a customizable size.\n" @@ -9104,47 +9489,47 @@ msgstr "" "- Pequeño -> con un tamaño personalizable.\n" "- Grande -> Líneas infinitas" -#: flatcamGUI/PreferencesUI.py:1187 +#: flatcamGUI/PreferencesUI.py:1362 msgid "Small" msgstr "Pequeño" -#: flatcamGUI/PreferencesUI.py:1188 +#: flatcamGUI/PreferencesUI.py:1363 msgid "Big" msgstr "Grande" -#: flatcamGUI/PreferencesUI.py:1195 +#: flatcamGUI/PreferencesUI.py:1370 msgid "Cursor Size" msgstr "Tamaño del cursor" -#: flatcamGUI/PreferencesUI.py:1197 +#: flatcamGUI/PreferencesUI.py:1372 msgid "Set the size of the mouse cursor, in pixels." msgstr "Establezca el tamaño del cursor del mouse, en píxeles." -#: flatcamGUI/PreferencesUI.py:1208 +#: flatcamGUI/PreferencesUI.py:1383 msgid "Cursor Width" msgstr "Ancho del cursor" -#: flatcamGUI/PreferencesUI.py:1210 +#: flatcamGUI/PreferencesUI.py:1385 msgid "Set the line width of the mouse cursor, in pixels." msgstr "Establezca el ancho de línea del cursor del mouse, en píxeles." -#: flatcamGUI/PreferencesUI.py:1221 flatcamGUI/PreferencesUI.py:1228 +#: flatcamGUI/PreferencesUI.py:1396 flatcamGUI/PreferencesUI.py:1403 msgid "Cursor Color" msgstr "Color del cursor" -#: flatcamGUI/PreferencesUI.py:1223 +#: flatcamGUI/PreferencesUI.py:1398 msgid "Check this box to color mouse cursor." msgstr "Marque esta casilla para colorear el cursor del mouse." -#: flatcamGUI/PreferencesUI.py:1230 +#: flatcamGUI/PreferencesUI.py:1405 msgid "Set the color of the mouse cursor." msgstr "Establece el color del cursor del mouse." -#: flatcamGUI/PreferencesUI.py:1253 +#: flatcamGUI/PreferencesUI.py:1428 msgid "Pan Button" msgstr "Botón de pan" -#: flatcamGUI/PreferencesUI.py:1255 +#: flatcamGUI/PreferencesUI.py:1430 msgid "" "Select the mouse button to use for panning:\n" "- MMB --> Middle Mouse Button\n" @@ -9154,35 +9539,35 @@ msgstr "" "- MMB -> Botón Central Del Ratón\n" "- RMB -> Botón derecho del ratón" -#: flatcamGUI/PreferencesUI.py:1259 +#: flatcamGUI/PreferencesUI.py:1434 msgid "MMB" msgstr "MMB" -#: flatcamGUI/PreferencesUI.py:1260 +#: flatcamGUI/PreferencesUI.py:1435 msgid "RMB" msgstr "RMB" -#: flatcamGUI/PreferencesUI.py:1266 +#: flatcamGUI/PreferencesUI.py:1441 msgid "Multiple Selection" msgstr "Selección múltiple" -#: flatcamGUI/PreferencesUI.py:1268 +#: flatcamGUI/PreferencesUI.py:1443 msgid "Select the key used for multiple selection." msgstr "Seleccione la clave utilizada para la selección múltiple." -#: flatcamGUI/PreferencesUI.py:1270 +#: flatcamGUI/PreferencesUI.py:1445 msgid "CTRL" msgstr "CTRL" -#: flatcamGUI/PreferencesUI.py:1271 +#: flatcamGUI/PreferencesUI.py:1446 msgid "SHIFT" msgstr "SHIFT" -#: flatcamGUI/PreferencesUI.py:1282 +#: flatcamGUI/PreferencesUI.py:1457 msgid "Delete object confirmation" msgstr "Eliminar confirmación de objeto" -#: flatcamGUI/PreferencesUI.py:1284 +#: flatcamGUI/PreferencesUI.py:1459 msgid "" "When checked the application will ask for user confirmation\n" "whenever the Delete object(s) event is triggered, either by\n" @@ -9192,11 +9577,11 @@ msgstr "" "cada vez que se desencadena el evento Eliminar objeto (s), ya sea por\n" "acceso directo al menú o acceso directo a teclas." -#: flatcamGUI/PreferencesUI.py:1291 +#: flatcamGUI/PreferencesUI.py:1466 msgid "\"Open\" behavior" msgstr "Comportamiento \"abierto\"" -#: flatcamGUI/PreferencesUI.py:1293 +#: flatcamGUI/PreferencesUI.py:1468 msgid "" "When checked the path for the last saved file is used when saving files,\n" "and the path for the last opened file is used when opening files.\n" @@ -9211,7 +9596,11 @@ msgstr "" "Cuando no está marcada, la ruta para abrir archivos es la última utilizada:\n" "ruta para guardar archivos o la ruta para abrir archivos." -#: flatcamGUI/PreferencesUI.py:1304 +#: flatcamGUI/PreferencesUI.py:1477 +msgid "Enable ToolTips" +msgstr "Hab. info sobre Herram" + +#: flatcamGUI/PreferencesUI.py:1479 msgid "" "Check this box if you want to have toolTips displayed\n" "when hovering with mouse over items throughout the App." @@ -9219,11 +9608,11 @@ msgstr "" "Marque esta casilla si desea que se muestre información sobre herramientas\n" "al pasar el mouse sobre los elementos de la aplicación." -#: flatcamGUI/PreferencesUI.py:1311 +#: flatcamGUI/PreferencesUI.py:1486 msgid "Allow Machinist Unsafe Settings" msgstr "Permitir configuraciones inseguras de Maquinista" -#: flatcamGUI/PreferencesUI.py:1313 +#: flatcamGUI/PreferencesUI.py:1488 msgid "" "If checked, some of the application settings will be allowed\n" "to have values that are usually unsafe to use.\n" @@ -9239,11 +9628,11 @@ msgstr "" "Se aplicará en el próximo inicio de la aplicación.\n" "<>: ¡No cambie esto a menos que sepa lo que está haciendo!" -#: flatcamGUI/PreferencesUI.py:1324 +#: flatcamGUI/PreferencesUI.py:1500 msgid "Bookmarks limit" msgstr "Límite de Marcadores" -#: flatcamGUI/PreferencesUI.py:1326 +#: flatcamGUI/PreferencesUI.py:1502 msgid "" "The maximum number of bookmarks that may be installed in the menu.\n" "The number of bookmarks in the bookmark manager may be greater\n" @@ -9253,27 +9642,27 @@ msgstr "" "El número de marcadores en el administrador de marcadores puede ser mayor\n" "pero el menú solo tendrá una cantidad considerable." -#: flatcamGUI/PreferencesUI.py:1335 +#: flatcamGUI/PreferencesUI.py:1511 msgid "Activity Icon" msgstr "Ícono de actividad" -#: flatcamGUI/PreferencesUI.py:1337 +#: flatcamGUI/PreferencesUI.py:1513 msgid "Select the GIF that show activity when FlatCAM is active." msgstr "Seleccione el GIF que muestra actividad cuando FlatCAM está activo." -#: flatcamGUI/PreferencesUI.py:1395 +#: flatcamGUI/PreferencesUI.py:1571 msgid "App Preferences" msgstr "Preferencias de la aplicación" -#: flatcamGUI/PreferencesUI.py:1405 flatcamGUI/PreferencesUI.py:1811 -#: flatcamGUI/PreferencesUI.py:2359 flatcamGUI/PreferencesUI.py:2804 -#: flatcamGUI/PreferencesUI.py:3417 flatcamTools/ToolDistance.py:49 -#: flatcamTools/ToolDistanceMin.py:49 flatcamTools/ToolPcbWizard.py:127 -#: flatcamTools/ToolProperties.py:152 +#: flatcamGUI/PreferencesUI.py:1581 flatcamGUI/PreferencesUI.py:1991 +#: flatcamGUI/PreferencesUI.py:2539 flatcamGUI/PreferencesUI.py:2986 +#: flatcamGUI/PreferencesUI.py:3695 flatcamTools/ToolDistance.py:56 +#: flatcamTools/ToolDistanceMin.py:50 flatcamTools/ToolPcbWizard.py:127 +#: flatcamTools/ToolProperties.py:154 msgid "Units" msgstr "Unidades" -#: flatcamGUI/PreferencesUI.py:1406 +#: flatcamGUI/PreferencesUI.py:1582 msgid "" "The default value for FlatCAM units.\n" "Whatever is selected here is set every time\n" @@ -9283,22 +9672,22 @@ msgstr "" "Lo que se selecciona aquí se establece cada vez\n" "Se inicia FLatCAM." -#: flatcamGUI/PreferencesUI.py:1409 flatcamGUI/PreferencesUI.py:1817 -#: flatcamGUI/PreferencesUI.py:2365 flatcamGUI/PreferencesUI.py:2815 -#: flatcamGUI/PreferencesUI.py:3423 flatcamTools/ToolCalculators.py:62 +#: flatcamGUI/PreferencesUI.py:1585 flatcamGUI/PreferencesUI.py:1997 +#: flatcamGUI/PreferencesUI.py:2545 flatcamGUI/PreferencesUI.py:2997 +#: flatcamGUI/PreferencesUI.py:3701 flatcamTools/ToolCalculators.py:62 #: flatcamTools/ToolPcbWizard.py:126 msgid "MM" msgstr "MM" -#: flatcamGUI/PreferencesUI.py:1410 +#: flatcamGUI/PreferencesUI.py:1586 msgid "IN" msgstr "IN" -#: flatcamGUI/PreferencesUI.py:1416 +#: flatcamGUI/PreferencesUI.py:1592 msgid "Precision MM" msgstr "Precisión MM" -#: flatcamGUI/PreferencesUI.py:1418 +#: flatcamGUI/PreferencesUI.py:1594 msgid "" "The number of decimals used throughout the application\n" "when the set units are in METRIC system.\n" @@ -9308,11 +9697,11 @@ msgstr "" "cuando las unidades configuradas están en el sistema METRIC.\n" "Cualquier cambio aquí requiere un reinicio de la aplicación." -#: flatcamGUI/PreferencesUI.py:1430 +#: flatcamGUI/PreferencesUI.py:1606 msgid "Precision INCH" msgstr "Precisión PULGADA" -#: flatcamGUI/PreferencesUI.py:1432 +#: flatcamGUI/PreferencesUI.py:1608 msgid "" "The number of decimals used throughout the application\n" "when the set units are in INCH system.\n" @@ -9322,11 +9711,11 @@ msgstr "" "cuando las unidades configuradas están en el sistema PULGADA.\n" "Cualquier cambio aquí requiere un reinicio de la aplicación." -#: flatcamGUI/PreferencesUI.py:1444 +#: flatcamGUI/PreferencesUI.py:1620 msgid "Graphic Engine" msgstr "Motor gráfico" -#: flatcamGUI/PreferencesUI.py:1445 +#: flatcamGUI/PreferencesUI.py:1621 msgid "" "Choose what graphic engine to use in FlatCAM.\n" "Legacy(2D) -> reduced functionality, slow performance but enhanced " @@ -9346,19 +9735,19 @@ msgstr "" "tanto\n" "use el modo Legacy (2D)." -#: flatcamGUI/PreferencesUI.py:1451 +#: flatcamGUI/PreferencesUI.py:1627 msgid "Legacy(2D)" msgstr "Legado (2D)" -#: flatcamGUI/PreferencesUI.py:1452 +#: flatcamGUI/PreferencesUI.py:1628 msgid "OpenGL(3D)" msgstr "OpenGL(3D)" -#: flatcamGUI/PreferencesUI.py:1464 +#: flatcamGUI/PreferencesUI.py:1640 msgid "APP. LEVEL" msgstr "Nivel de aplicación" -#: flatcamGUI/PreferencesUI.py:1465 +#: flatcamGUI/PreferencesUI.py:1641 msgid "" "Choose the default level of usage for FlatCAM.\n" "BASIC level -> reduced functionality, best for beginner's.\n" @@ -9374,11 +9763,11 @@ msgstr "" "La elección aquí influirá en los parámetros en\n" "La pestaña seleccionada para todo tipo de objetos FlatCAM." -#: flatcamGUI/PreferencesUI.py:1477 +#: flatcamGUI/PreferencesUI.py:1653 msgid "Portable app" msgstr "Aplicación portátil" -#: flatcamGUI/PreferencesUI.py:1478 +#: flatcamGUI/PreferencesUI.py:1654 msgid "" "Choose if the application should run as portable.\n" "\n" @@ -9392,19 +9781,19 @@ msgstr "" "lo que significa que los archivos de preferencias se guardarán\n" "en la carpeta de la aplicación, en la subcarpeta lib \\ config." -#: flatcamGUI/PreferencesUI.py:1491 +#: flatcamGUI/PreferencesUI.py:1667 msgid "Languages" msgstr "Idiomas" -#: flatcamGUI/PreferencesUI.py:1492 +#: flatcamGUI/PreferencesUI.py:1668 msgid "Set the language used throughout FlatCAM." msgstr "Establezca el idioma utilizado en FlatCAM." -#: flatcamGUI/PreferencesUI.py:1498 +#: flatcamGUI/PreferencesUI.py:1674 msgid "Apply Language" msgstr "Aplicar idioma" -#: flatcamGUI/PreferencesUI.py:1499 +#: flatcamGUI/PreferencesUI.py:1675 msgid "" "Set the language used throughout FlatCAM.\n" "The app will restart after click." @@ -9412,33 +9801,33 @@ msgstr "" "Establezca el idioma utilizado en FlatCAM.\n" "La aplicación se reiniciará después de hacer clic." -#: flatcamGUI/PreferencesUI.py:1513 +#: flatcamGUI/PreferencesUI.py:1689 msgid "Startup Settings" msgstr "Configuraciones de inicio" -#: flatcamGUI/PreferencesUI.py:1517 +#: flatcamGUI/PreferencesUI.py:1693 msgid "Splash Screen" msgstr "Pantalla de bienvenida" -#: flatcamGUI/PreferencesUI.py:1519 +#: flatcamGUI/PreferencesUI.py:1695 msgid "Enable display of the splash screen at application startup." msgstr "" "Habilite la visualización de la pantalla de inicio al iniciar la aplicación." -#: flatcamGUI/PreferencesUI.py:1531 +#: flatcamGUI/PreferencesUI.py:1707 msgid "Sys Tray Icon" msgstr "Icono de la Sys Tray" -#: flatcamGUI/PreferencesUI.py:1533 +#: flatcamGUI/PreferencesUI.py:1709 msgid "Enable display of FlatCAM icon in Sys Tray." msgstr "" "Habilite la visualización del icono de FlatCAM en la bandeja del sistema." -#: flatcamGUI/PreferencesUI.py:1538 +#: flatcamGUI/PreferencesUI.py:1714 msgid "Show Shell" msgstr "Mostrar la línea de comando" -#: flatcamGUI/PreferencesUI.py:1540 +#: flatcamGUI/PreferencesUI.py:1716 msgid "" "Check this box if you want the shell to\n" "start automatically at startup." @@ -9446,11 +9835,11 @@ msgstr "" "Marque esta casilla si desea que el shell\n" "iniciar automáticamente en el inicio." -#: flatcamGUI/PreferencesUI.py:1547 +#: flatcamGUI/PreferencesUI.py:1723 msgid "Show Project" msgstr "Mostrar proyecto" -#: flatcamGUI/PreferencesUI.py:1549 +#: flatcamGUI/PreferencesUI.py:1725 msgid "" "Check this box if you want the project/selected/tool tab area to\n" "to be shown automatically at startup." @@ -9459,11 +9848,11 @@ msgstr "" "seleccionado / herramienta\n" "para ser mostrado automáticamente en el inicio." -#: flatcamGUI/PreferencesUI.py:1555 +#: flatcamGUI/PreferencesUI.py:1731 msgid "Version Check" msgstr "Verificación de versión" -#: flatcamGUI/PreferencesUI.py:1557 +#: flatcamGUI/PreferencesUI.py:1733 msgid "" "Check this box if you want to check\n" "for a new version automatically at startup." @@ -9471,11 +9860,11 @@ msgstr "" "Marque esta casilla si desea marcar\n" "para una nueva versión automáticamente en el inicio." -#: flatcamGUI/PreferencesUI.py:1564 +#: flatcamGUI/PreferencesUI.py:1740 msgid "Send Statistics" msgstr "Enviar estadísticas" -#: flatcamGUI/PreferencesUI.py:1566 +#: flatcamGUI/PreferencesUI.py:1742 msgid "" "Check this box if you agree to send anonymous\n" "stats automatically at startup, to help improve FlatCAM." @@ -9483,11 +9872,11 @@ msgstr "" "Marque esta casilla si acepta enviar anónimo\n" "Estadísticas automáticamente en el inicio, para ayudar a mejorar FlatCAM." -#: flatcamGUI/PreferencesUI.py:1580 +#: flatcamGUI/PreferencesUI.py:1756 msgid "Workers number" msgstr "Número de trabajadores" -#: flatcamGUI/PreferencesUI.py:1582 flatcamGUI/PreferencesUI.py:1591 +#: flatcamGUI/PreferencesUI.py:1758 msgid "" "The number of Qthreads made available to the App.\n" "A bigger number may finish the jobs more quickly but\n" @@ -9504,35 +9893,35 @@ msgstr "" "El valor predeterminado es 2.\n" "Después del cambio, se aplicará en el próximo inicio de la aplicación." -#: flatcamGUI/PreferencesUI.py:1604 +#: flatcamGUI/PreferencesUI.py:1772 msgid "Geo Tolerance" msgstr "Geo Tolerancia" -#: flatcamGUI/PreferencesUI.py:1606 flatcamGUI/PreferencesUI.py:1615 +#: flatcamGUI/PreferencesUI.py:1774 msgid "" "This value can counter the effect of the Circle Steps\n" -"parameter. Default value is 0.01.\n" +"parameter. Default value is 0.005.\n" "A lower value will increase the detail both in image\n" "and in Gcode for the circles, with a higher cost in\n" "performance. Higher value will provide more\n" "performance at the expense of level of detail." msgstr "" -"Este valor puede contrarrestar el efecto de los pasos del círculo.\n" -"parámetro. El valor predeterminado es 0.01.\n" -"Un valor más bajo aumentará el detalle tanto en la imagen.\n" +"Este valor puede contrarrestar el efecto de los Pasos circulares\n" +"parámetro. El valor predeterminado es 0.005.\n" +"Un valor más bajo aumentará el detalle tanto en la imagen\n" "y en Gcode para los círculos, con un mayor costo en\n" "actuación. Un valor más alto proporcionará más\n" -"Rendimiento a expensas del nivel de detalle." +"rendimiento a expensas del nivel de detalle." -#: flatcamGUI/PreferencesUI.py:1634 +#: flatcamGUI/PreferencesUI.py:1794 msgid "Save Settings" msgstr "Configuraciones para guardar" -#: flatcamGUI/PreferencesUI.py:1638 +#: flatcamGUI/PreferencesUI.py:1798 msgid "Save Compressed Project" msgstr "Guardar proyecto comprimido" -#: flatcamGUI/PreferencesUI.py:1640 +#: flatcamGUI/PreferencesUI.py:1800 msgid "" "Whether to save a compressed or uncompressed project.\n" "When checked it will save a compressed FlatCAM project." @@ -9540,11 +9929,11 @@ msgstr "" "Ya sea para guardar un proyecto comprimido o sin comprimir.\n" "Cuando esté marcado, guardará un proyecto comprimido de FlatCAM." -#: flatcamGUI/PreferencesUI.py:1649 +#: flatcamGUI/PreferencesUI.py:1809 msgid "Compression" msgstr "Compresión" -#: flatcamGUI/PreferencesUI.py:1651 +#: flatcamGUI/PreferencesUI.py:1811 msgid "" "The level of compression used when saving\n" "a FlatCAM project. Higher value means better compression\n" @@ -9554,64 +9943,94 @@ msgstr "" "Un proyecto FlatCAM. Un valor más alto significa una mejor compresión\n" "pero requieren más uso de RAM y más tiempo de procesamiento." -#: flatcamGUI/PreferencesUI.py:1671 +#: flatcamGUI/PreferencesUI.py:1822 +msgid "Enable Auto Save" +msgstr "Habilitar guardado auto" + +#: flatcamGUI/PreferencesUI.py:1824 +msgid "" +"Check to enable the autosave feature.\n" +"When enabled, the application will try to save a project\n" +"at the set interval." +msgstr "" +"Marque para habilitar la función de autoguardado.\n" +"Cuando está habilitada, la aplicación intentará guardar un proyecto.\n" +"en el intervalo establecido." + +#: flatcamGUI/PreferencesUI.py:1834 +msgid "Interval" +msgstr "Intervalo" + +#: flatcamGUI/PreferencesUI.py:1836 +msgid "" +"Time interval for autosaving. In milliseconds.\n" +"The application will try to save periodically but only\n" +"if the project was saved manually at least once.\n" +"While active, some operations may block this feature." +msgstr "" +"Intervalo de tiempo para guardar automáticamente. En milisegundos\n" +"La aplicación intentará guardar periódicamente pero solo\n" +"si el proyecto se guardó manualmente al menos una vez.\n" +"Mientras está activo, algunas operaciones pueden bloquear esta función." + +#: flatcamGUI/PreferencesUI.py:1852 msgid "Text to PDF parameters" msgstr "Parámetros de texto a PDF" -#: flatcamGUI/PreferencesUI.py:1673 +#: flatcamGUI/PreferencesUI.py:1854 msgid "Used when saving text in Code Editor or in FlatCAM Document objects." msgstr "" "Se utiliza al guardar texto en el Editor de código o en objetos de documento " "FlatCAM." -#: flatcamGUI/PreferencesUI.py:1682 +#: flatcamGUI/PreferencesUI.py:1863 msgid "Top Margin" msgstr "Margen superior" -#: flatcamGUI/PreferencesUI.py:1684 +#: flatcamGUI/PreferencesUI.py:1865 msgid "Distance between text body and the top of the PDF file." msgstr "" "Distancia entre el cuerpo del texto y la parte superior del archivo PDF." -#: flatcamGUI/PreferencesUI.py:1695 +#: flatcamGUI/PreferencesUI.py:1876 msgid "Bottom Margin" msgstr "Margen inferior" -#: flatcamGUI/PreferencesUI.py:1697 +#: flatcamGUI/PreferencesUI.py:1878 msgid "Distance between text body and the bottom of the PDF file." msgstr "" "Distancia entre el cuerpo del texto y la parte inferior del archivo PDF." -#: flatcamGUI/PreferencesUI.py:1708 +#: flatcamGUI/PreferencesUI.py:1889 msgid "Left Margin" msgstr "Margen izquierdo" -#: flatcamGUI/PreferencesUI.py:1710 +#: flatcamGUI/PreferencesUI.py:1891 msgid "Distance between text body and the left of the PDF file." msgstr "Distancia entre el cuerpo del texto y la izquierda del archivo PDF." -#: flatcamGUI/PreferencesUI.py:1721 +#: flatcamGUI/PreferencesUI.py:1902 msgid "Right Margin" msgstr "Margen derecho" -#: flatcamGUI/PreferencesUI.py:1723 +#: flatcamGUI/PreferencesUI.py:1904 msgid "Distance between text body and the right of the PDF file." msgstr "Distancia entre el cuerpo del texto y la derecha del archivo PDF." -#: flatcamGUI/PreferencesUI.py:1756 +#: flatcamGUI/PreferencesUI.py:1936 msgid "Gerber General" msgstr "Gerber General" -#: flatcamGUI/PreferencesUI.py:1774 +#: flatcamGUI/PreferencesUI.py:1954 msgid "M-Color" msgstr "M-Color" -#: flatcamGUI/PreferencesUI.py:1788 flatcamGUI/PreferencesUI.py:3859 -#: flatcamGUI/PreferencesUI.py:4442 flatcamGUI/PreferencesUI.py:7148 +#: flatcamGUI/PreferencesUI.py:1968 flatcamGUI/PreferencesUI.py:4137 +#: flatcamGUI/PreferencesUI.py:4735 flatcamGUI/PreferencesUI.py:7654 msgid "Circle Steps" msgstr "Pasos del círculo" -#: flatcamGUI/PreferencesUI.py:1790 +#: flatcamGUI/PreferencesUI.py:1970 msgid "" "The number of circle steps for Gerber \n" "circular aperture linear approximation." @@ -9619,11 +10038,11 @@ msgstr "" "El número de pasos de círculo para Gerber\n" "Apertura circular de aproximación lineal." -#: flatcamGUI/PreferencesUI.py:1802 +#: flatcamGUI/PreferencesUI.py:1982 msgid "Default Values" msgstr "Valores predeterminados" -#: flatcamGUI/PreferencesUI.py:1804 +#: flatcamGUI/PreferencesUI.py:1984 msgid "" "Those values will be used as fallback values\n" "in case that they are not found in the Gerber file." @@ -9631,25 +10050,25 @@ msgstr "" "Esos valores se usarán como valores de reserva\n" "en caso de que no se encuentren en el archivo Gerber." -#: flatcamGUI/PreferencesUI.py:1813 flatcamGUI/PreferencesUI.py:1819 -#: flatcamGUI/PreferencesUI.py:2361 flatcamGUI/PreferencesUI.py:2367 +#: flatcamGUI/PreferencesUI.py:1993 flatcamGUI/PreferencesUI.py:1999 +#: flatcamGUI/PreferencesUI.py:2541 flatcamGUI/PreferencesUI.py:2547 msgid "The units used in the Gerber file." msgstr "Las unidades utilizadas en el archivo Gerber." -#: flatcamGUI/PreferencesUI.py:1816 flatcamGUI/PreferencesUI.py:2364 -#: flatcamGUI/PreferencesUI.py:2728 flatcamGUI/PreferencesUI.py:2814 -#: flatcamGUI/PreferencesUI.py:3422 flatcamTools/ToolCalculators.py:61 +#: flatcamGUI/PreferencesUI.py:1996 flatcamGUI/PreferencesUI.py:2544 +#: flatcamGUI/PreferencesUI.py:2910 flatcamGUI/PreferencesUI.py:2996 +#: flatcamGUI/PreferencesUI.py:3700 flatcamTools/ToolCalculators.py:61 #: flatcamTools/ToolPcbWizard.py:125 msgid "INCH" msgstr "PULGADA" -#: flatcamGUI/PreferencesUI.py:1826 flatcamGUI/PreferencesUI.py:2413 -#: flatcamGUI/PreferencesUI.py:2786 flatcamGUI/PreferencesUI.py:3490 +#: flatcamGUI/PreferencesUI.py:2006 flatcamGUI/PreferencesUI.py:2593 +#: flatcamGUI/PreferencesUI.py:2968 flatcamGUI/PreferencesUI.py:3768 msgid "Zeros" msgstr "Ceros" -#: flatcamGUI/PreferencesUI.py:1829 flatcamGUI/PreferencesUI.py:1839 -#: flatcamGUI/PreferencesUI.py:2416 flatcamGUI/PreferencesUI.py:2426 +#: flatcamGUI/PreferencesUI.py:2009 flatcamGUI/PreferencesUI.py:2019 +#: flatcamGUI/PreferencesUI.py:2596 flatcamGUI/PreferencesUI.py:2606 msgid "" "This sets the type of Gerber zeros.\n" "If LZ then Leading Zeros are removed and\n" @@ -9663,23 +10082,23 @@ msgstr "" "Si se comprueba TZ, se eliminan los ceros finales\n" "y Leading Zeros se mantienen." -#: flatcamGUI/PreferencesUI.py:1836 flatcamGUI/PreferencesUI.py:2423 -#: flatcamGUI/PreferencesUI.py:2799 flatcamGUI/PreferencesUI.py:3500 +#: flatcamGUI/PreferencesUI.py:2016 flatcamGUI/PreferencesUI.py:2603 +#: flatcamGUI/PreferencesUI.py:2981 flatcamGUI/PreferencesUI.py:3778 #: flatcamTools/ToolPcbWizard.py:111 msgid "LZ" msgstr "LZ" -#: flatcamGUI/PreferencesUI.py:1837 flatcamGUI/PreferencesUI.py:2424 -#: flatcamGUI/PreferencesUI.py:2800 flatcamGUI/PreferencesUI.py:3501 +#: flatcamGUI/PreferencesUI.py:2017 flatcamGUI/PreferencesUI.py:2604 +#: flatcamGUI/PreferencesUI.py:2982 flatcamGUI/PreferencesUI.py:3779 #: flatcamTools/ToolPcbWizard.py:112 msgid "TZ" msgstr "TZ" -#: flatcamGUI/PreferencesUI.py:1855 +#: flatcamGUI/PreferencesUI.py:2035 msgid "Clean Apertures" msgstr "Aberturas limpias" -#: flatcamGUI/PreferencesUI.py:1857 +#: flatcamGUI/PreferencesUI.py:2037 msgid "" "Will remove apertures that do not have geometry\n" "thus lowering the number of apertures in the Gerber object." @@ -9687,11 +10106,11 @@ msgstr "" "Eliminará las aberturas que no tengan geometría\n" "bajando así el número de aberturas en el objeto Gerber." -#: flatcamGUI/PreferencesUI.py:1863 +#: flatcamGUI/PreferencesUI.py:2043 msgid "Polarity change buffer" msgstr "Cambio de polaridad buffer" -#: flatcamGUI/PreferencesUI.py:1865 +#: flatcamGUI/PreferencesUI.py:2045 msgid "" "Will apply extra buffering for the\n" "solid geometry when we have polarity changes.\n" @@ -9703,17 +10122,17 @@ msgstr "" "Puede ayudar a cargar archivos Gerber que de otra manera\n" "No cargar correctamente." -#: flatcamGUI/PreferencesUI.py:1878 +#: flatcamGUI/PreferencesUI.py:2058 msgid "Gerber Object Color" msgstr "Color de objeto Gerber" -#: flatcamGUI/PreferencesUI.py:1884 flatcamGUI/PreferencesUI.py:2905 -#: flatcamGUI/PreferencesUI.py:3896 +#: flatcamGUI/PreferencesUI.py:2064 flatcamGUI/PreferencesUI.py:3087 +#: flatcamGUI/PreferencesUI.py:4176 msgid "Set the line color for plotted objects." msgstr "Establecer el color de la línea para los objetos trazados." -#: flatcamGUI/PreferencesUI.py:1901 flatcamGUI/PreferencesUI.py:2922 -#: flatcamGUI/PreferencesUI.py:4553 flatcamGUI/PreferencesUI.py:4619 +#: flatcamGUI/PreferencesUI.py:2081 flatcamGUI/PreferencesUI.py:3104 +#: flatcamGUI/PreferencesUI.py:4846 flatcamGUI/PreferencesUI.py:4912 msgid "" "Set the fill color for plotted objects.\n" "First 6 digits are the color and the last 2\n" @@ -9723,34 +10142,29 @@ msgstr "" "Los primeros 6 dígitos son el color y los 2 últimos.\n" "Los dígitos son para el nivel alfa (transparencia)." -#: flatcamGUI/PreferencesUI.py:1920 flatcamGUI/PreferencesUI.py:2941 -#: flatcamGUI/PreferencesUI.py:4572 +#: flatcamGUI/PreferencesUI.py:2100 flatcamGUI/PreferencesUI.py:3123 +#: flatcamGUI/PreferencesUI.py:4865 msgid "Set the fill transparency for plotted objects." msgstr "Establecer la transparencia de relleno para los objetos trazados." -#: flatcamGUI/PreferencesUI.py:2011 +#: flatcamGUI/PreferencesUI.py:2191 msgid "Gerber Options" msgstr "Opciones de gerber" -#: flatcamGUI/PreferencesUI.py:2085 flatcamGUI/PreferencesUI.py:4379 -#: flatcamGUI/PreferencesUI.py:5120 flatcamTools/ToolNonCopperClear.py:170 -msgid "Conv." -msgstr "Conv." - -#: flatcamGUI/PreferencesUI.py:2089 +#: flatcamGUI/PreferencesUI.py:2269 msgid "Combine Passes" msgstr "Combinar pases" -#: flatcamGUI/PreferencesUI.py:2177 +#: flatcamGUI/PreferencesUI.py:2357 msgid "Gerber Adv. Options" msgstr "Opciones avan. de Gerber" -#: flatcamGUI/PreferencesUI.py:2181 flatcamGUI/PreferencesUI.py:3278 -#: flatcamGUI/PreferencesUI.py:4179 +#: flatcamGUI/PreferencesUI.py:2361 flatcamGUI/PreferencesUI.py:3551 +#: flatcamGUI/PreferencesUI.py:4472 msgid "Advanced Options" msgstr "Opciones avanzadas" -#: flatcamGUI/PreferencesUI.py:2183 +#: flatcamGUI/PreferencesUI.py:2363 msgid "" "A list of Gerber advanced parameters.\n" "Those parameters are available only for\n" @@ -9760,11 +10174,11 @@ msgstr "" "Esos parámetros están disponibles sólo para\n" "Aplicación avanzada Nivel." -#: flatcamGUI/PreferencesUI.py:2202 +#: flatcamGUI/PreferencesUI.py:2382 msgid "Table Show/Hide" msgstr "Mostrar / ocultar tabla" -#: flatcamGUI/PreferencesUI.py:2204 +#: flatcamGUI/PreferencesUI.py:2384 msgid "" "Toggle the display of the Gerber Apertures Table.\n" "Also, on hide, it will delete all mark shapes\n" @@ -9774,15 +10188,15 @@ msgstr "" "Además, en hide, borrará todas las formas de marca.\n" "que se dibujan sobre lienzo." -#: flatcamGUI/PreferencesUI.py:2284 +#: flatcamGUI/PreferencesUI.py:2464 msgid "Exterior" msgstr "Exterior" -#: flatcamGUI/PreferencesUI.py:2285 +#: flatcamGUI/PreferencesUI.py:2465 msgid "Interior" msgstr "Interior" -#: flatcamGUI/PreferencesUI.py:2298 +#: flatcamGUI/PreferencesUI.py:2478 msgid "" "Buffering type:\n" "- None --> best performance, fast file loading but no so good display\n" @@ -9796,19 +10210,19 @@ msgstr "" "predeterminado.\n" "<>: ¡No cambie esto a menos que sepa lo que está haciendo!" -#: flatcamGUI/PreferencesUI.py:2303 flatcamGUI/PreferencesUI.py:5852 -#: flatcamGUI/PreferencesUI.py:7446 flatcamTools/ToolFiducials.py:201 -#: flatcamTools/ToolFilm.py:255 flatcamTools/ToolProperties.py:411 -#: flatcamTools/ToolProperties.py:426 flatcamTools/ToolProperties.py:429 -#: flatcamTools/ToolProperties.py:432 flatcamTools/ToolProperties.py:456 +#: flatcamGUI/PreferencesUI.py:2483 flatcamGUI/PreferencesUI.py:6340 +#: flatcamGUI/PreferencesUI.py:7952 flatcamTools/ToolFiducials.py:201 +#: flatcamTools/ToolFilm.py:255 flatcamTools/ToolProperties.py:452 +#: flatcamTools/ToolProperties.py:455 flatcamTools/ToolProperties.py:458 +#: flatcamTools/ToolProperties.py:483 msgid "None" msgstr "Ninguno" -#: flatcamGUI/PreferencesUI.py:2309 +#: flatcamGUI/PreferencesUI.py:2489 msgid "Simplify" msgstr "Simplificar" -#: flatcamGUI/PreferencesUI.py:2311 +#: flatcamGUI/PreferencesUI.py:2491 msgid "" "When checked all the Gerber polygons will be\n" "loaded with simplification having a set tolerance.\n" @@ -9818,23 +10232,23 @@ msgstr "" "cargado de simplificación con una tolerancia establecida.\n" "<>: ¡No cambie esto a menos que sepa lo que está haciendo!" -#: flatcamGUI/PreferencesUI.py:2318 +#: flatcamGUI/PreferencesUI.py:2498 msgid "Tolerance" msgstr "Tolerancia" -#: flatcamGUI/PreferencesUI.py:2319 +#: flatcamGUI/PreferencesUI.py:2499 msgid "Tolerance for polygon simplification." msgstr "Tolerancia para la simplificación de polígonos." -#: flatcamGUI/PreferencesUI.py:2344 +#: flatcamGUI/PreferencesUI.py:2524 msgid "Gerber Export" msgstr "Gerber Export" -#: flatcamGUI/PreferencesUI.py:2348 flatcamGUI/PreferencesUI.py:3406 +#: flatcamGUI/PreferencesUI.py:2528 flatcamGUI/PreferencesUI.py:3684 msgid "Export Options" msgstr "Opciones de export" -#: flatcamGUI/PreferencesUI.py:2350 +#: flatcamGUI/PreferencesUI.py:2530 msgid "" "The parameters set here are used in the file exported\n" "when using the File -> Export -> Export Gerber menu entry." @@ -9842,11 +10256,11 @@ msgstr "" "Los parámetros establecidos aquí se utilizan en el archivo exportado.\n" "cuando se usa la entrada de menú Archivo -> Exportar -> Exportar Gerber." -#: flatcamGUI/PreferencesUI.py:2373 flatcamGUI/PreferencesUI.py:3431 +#: flatcamGUI/PreferencesUI.py:2553 flatcamGUI/PreferencesUI.py:3709 msgid "Int/Decimals" msgstr "Entero/Decimales" -#: flatcamGUI/PreferencesUI.py:2375 +#: flatcamGUI/PreferencesUI.py:2555 msgid "" "The number of digits in the whole part of the number\n" "and in the fractional part of the number." @@ -9854,7 +10268,7 @@ msgstr "" "El número de dígitos en la parte entera del número.\n" "y en la parte fraccionaria del número." -#: flatcamGUI/PreferencesUI.py:2388 +#: flatcamGUI/PreferencesUI.py:2568 msgid "" "This numbers signify the number of digits in\n" "the whole part of Gerber coordinates." @@ -9862,7 +10276,7 @@ msgstr "" "Estos números significan el número de dígitos en\n" "Toda la parte de Gerber coordina." -#: flatcamGUI/PreferencesUI.py:2404 +#: flatcamGUI/PreferencesUI.py:2584 msgid "" "This numbers signify the number of digits in\n" "the decimal part of Gerber coordinates." @@ -9870,16 +10284,16 @@ msgstr "" "Estos números significan el número de dígitos en\n" "La parte decimal de las coordenadas de gerber." -#: flatcamGUI/PreferencesUI.py:2449 +#: flatcamGUI/PreferencesUI.py:2629 msgid "A list of Gerber Editor parameters." msgstr "Una lista de los parámetros del editor Gerber." -#: flatcamGUI/PreferencesUI.py:2457 flatcamGUI/PreferencesUI.py:3565 -#: flatcamGUI/PreferencesUI.py:4357 flatcamGUI/PreferencesUI.py:7109 +#: flatcamGUI/PreferencesUI.py:2637 flatcamGUI/PreferencesUI.py:3843 +#: flatcamGUI/PreferencesUI.py:4650 flatcamGUI/PreferencesUI.py:7615 msgid "Selection limit" msgstr "Límite de selección" -#: flatcamGUI/PreferencesUI.py:2459 +#: flatcamGUI/PreferencesUI.py:2639 msgid "" "Set the number of selected Gerber geometry\n" "items above which the utility geometry\n" @@ -9893,23 +10307,23 @@ msgstr "" "Aumenta el rendimiento al mover un\n" "Gran cantidad de elementos geométricos." -#: flatcamGUI/PreferencesUI.py:2472 +#: flatcamGUI/PreferencesUI.py:2652 msgid "New Aperture code" msgstr "Nuevo Código de Aper" -#: flatcamGUI/PreferencesUI.py:2485 +#: flatcamGUI/PreferencesUI.py:2665 msgid "New Aperture size" msgstr "Nuevo Tamaño de Aper" -#: flatcamGUI/PreferencesUI.py:2487 +#: flatcamGUI/PreferencesUI.py:2667 msgid "Size for the new aperture" msgstr "Tamaño para la Nueva Aper" -#: flatcamGUI/PreferencesUI.py:2498 +#: flatcamGUI/PreferencesUI.py:2678 msgid "New Aperture type" msgstr "Nuevo Tipo de Aper" -#: flatcamGUI/PreferencesUI.py:2500 +#: flatcamGUI/PreferencesUI.py:2680 msgid "" "Type for the new aperture.\n" "Can be 'C', 'R' or 'O'." @@ -9917,35 +10331,42 @@ msgstr "" "Escriba para la nueva apertura.\n" "Puede ser 'C', 'R' u 'O'." -#: flatcamGUI/PreferencesUI.py:2522 +#: flatcamGUI/PreferencesUI.py:2702 msgid "Aperture Dimensions" msgstr "Dim. de apertura" -#: flatcamGUI/PreferencesUI.py:2524 flatcamGUI/PreferencesUI.py:3877 -#: flatcamGUI/PreferencesUI.py:5029 -msgid "Diameters of the cutting tools, separated by ','" -msgstr "Diámetros de las herramientas de corte, separados por ','" +#: flatcamGUI/PreferencesUI.py:2704 flatcamGUI/PreferencesUI.py:4155 +#: flatcamGUI/PreferencesUI.py:5322 flatcamGUI/PreferencesUI.py:5889 +#: flatcamGUI/PreferencesUI.py:6955 +msgid "" +"Diameters of the tools, separated by comma.\n" +"The value of the diameter has to use the dot decimals separator.\n" +"Valid values: 0.3, 1.0" +msgstr "" +"Diámetros de las herramientas, separados por comas.\n" +"El valor del diámetro tiene que usar el separador de decimales de punto.\n" +"Valores válidos: 0.3, 1.0" -#: flatcamGUI/PreferencesUI.py:2530 +#: flatcamGUI/PreferencesUI.py:2712 msgid "Linear Pad Array" msgstr "Matriz lineal de Almohadilla" -#: flatcamGUI/PreferencesUI.py:2534 flatcamGUI/PreferencesUI.py:3609 -#: flatcamGUI/PreferencesUI.py:3757 +#: flatcamGUI/PreferencesUI.py:2716 flatcamGUI/PreferencesUI.py:3887 +#: flatcamGUI/PreferencesUI.py:4035 msgid "Linear Direction" msgstr "Direccion lineal" -#: flatcamGUI/PreferencesUI.py:2574 +#: flatcamGUI/PreferencesUI.py:2756 msgid "Circular Pad Array" msgstr "Matriz de Almohadilla Circ" -#: flatcamGUI/PreferencesUI.py:2578 flatcamGUI/PreferencesUI.py:3655 -#: flatcamGUI/PreferencesUI.py:3805 +#: flatcamGUI/PreferencesUI.py:2760 flatcamGUI/PreferencesUI.py:3933 +#: flatcamGUI/PreferencesUI.py:4083 msgid "Circular Direction" msgstr "Dirección circular" -#: flatcamGUI/PreferencesUI.py:2580 flatcamGUI/PreferencesUI.py:3657 -#: flatcamGUI/PreferencesUI.py:3807 +#: flatcamGUI/PreferencesUI.py:2762 flatcamGUI/PreferencesUI.py:3935 +#: flatcamGUI/PreferencesUI.py:4085 msgid "" "Direction for circular array.\n" "Can be CW = clockwise or CCW = counter clockwise." @@ -9953,48 +10374,48 @@ msgstr "" "Dirección para matriz circular.\n" "Puede ser CW = en sentido horario o CCW = en sentido antihorario." -#: flatcamGUI/PreferencesUI.py:2591 flatcamGUI/PreferencesUI.py:3668 -#: flatcamGUI/PreferencesUI.py:3818 +#: flatcamGUI/PreferencesUI.py:2773 flatcamGUI/PreferencesUI.py:3946 +#: flatcamGUI/PreferencesUI.py:4096 msgid "Circular Angle" msgstr "Ángulo circular" -#: flatcamGUI/PreferencesUI.py:2610 +#: flatcamGUI/PreferencesUI.py:2792 msgid "Distance at which to buffer the Gerber element." msgstr "Distancia a la que buffer el elemento Gerber." -#: flatcamGUI/PreferencesUI.py:2619 +#: flatcamGUI/PreferencesUI.py:2801 msgid "Scale Tool" msgstr "Herramienta de escala" -#: flatcamGUI/PreferencesUI.py:2625 +#: flatcamGUI/PreferencesUI.py:2807 msgid "Factor to scale the Gerber element." msgstr "Factoriza para escalar el elemento Gerber." -#: flatcamGUI/PreferencesUI.py:2638 +#: flatcamGUI/PreferencesUI.py:2820 msgid "Threshold low" msgstr "Umbral bajo" -#: flatcamGUI/PreferencesUI.py:2640 +#: flatcamGUI/PreferencesUI.py:2822 msgid "Threshold value under which the apertures are not marked." msgstr "Valor de umbral por debajo del cual las aberturas no están marcadas." -#: flatcamGUI/PreferencesUI.py:2650 +#: flatcamGUI/PreferencesUI.py:2832 msgid "Threshold high" msgstr "Umbral alto" -#: flatcamGUI/PreferencesUI.py:2652 +#: flatcamGUI/PreferencesUI.py:2834 msgid "Threshold value over which the apertures are not marked." msgstr "Valor umbral sobre el cual las aberturas no están marcadas." -#: flatcamGUI/PreferencesUI.py:2670 +#: flatcamGUI/PreferencesUI.py:2852 msgid "Excellon General" msgstr "Excellon General" -#: flatcamGUI/PreferencesUI.py:2703 +#: flatcamGUI/PreferencesUI.py:2885 msgid "Excellon Format" msgstr "Formato Excellon" -#: flatcamGUI/PreferencesUI.py:2705 +#: flatcamGUI/PreferencesUI.py:2887 msgid "" "The NC drill files, usually named Excellon files\n" "are files that can be found in different formats.\n" @@ -10036,12 +10457,12 @@ msgstr "" "Sprint Layout 2: 4 PULGADAS LZ\n" "KiCAD 3: 5 PULGADAS TZ" -#: flatcamGUI/PreferencesUI.py:2729 +#: flatcamGUI/PreferencesUI.py:2911 msgid "Default values for INCH are 2:4" msgstr "Los valores predeterminados para INCH son 2:4" -#: flatcamGUI/PreferencesUI.py:2736 flatcamGUI/PreferencesUI.py:2765 -#: flatcamGUI/PreferencesUI.py:3445 +#: flatcamGUI/PreferencesUI.py:2918 flatcamGUI/PreferencesUI.py:2947 +#: flatcamGUI/PreferencesUI.py:3723 msgid "" "This numbers signify the number of digits in\n" "the whole part of Excellon coordinates." @@ -10049,8 +10470,8 @@ msgstr "" "Estos números significan el número de dígitos en\n" "Coordina toda la parte de Excellon." -#: flatcamGUI/PreferencesUI.py:2749 flatcamGUI/PreferencesUI.py:2778 -#: flatcamGUI/PreferencesUI.py:3458 +#: flatcamGUI/PreferencesUI.py:2931 flatcamGUI/PreferencesUI.py:2960 +#: flatcamGUI/PreferencesUI.py:3736 msgid "" "This numbers signify the number of digits in\n" "the decimal part of Excellon coordinates." @@ -10058,15 +10479,15 @@ msgstr "" "Estos números significan el número de dígitos en\n" "La parte decimal de las coordenadas de Excellon." -#: flatcamGUI/PreferencesUI.py:2757 +#: flatcamGUI/PreferencesUI.py:2939 msgid "METRIC" msgstr "MÉTRICO" -#: flatcamGUI/PreferencesUI.py:2758 +#: flatcamGUI/PreferencesUI.py:2940 msgid "Default values for METRIC are 3:3" msgstr "Los valores predeterminados para Métrica son 3: 3" -#: flatcamGUI/PreferencesUI.py:2789 +#: flatcamGUI/PreferencesUI.py:2971 msgid "" "This sets the type of Excellon zeros.\n" "If LZ then Leading Zeros are kept and\n" @@ -10086,7 +10507,7 @@ msgstr "" "Esto se usa cuando no hay información\n" "almacenado en el archivo Excellon." -#: flatcamGUI/PreferencesUI.py:2807 +#: flatcamGUI/PreferencesUI.py:2989 msgid "" "This sets the default units of Excellon files.\n" "If it is not detected in the parsed file the value here\n" @@ -10098,7 +10519,7 @@ msgstr "" "serán utilizados. Algunos archivos de Excellon no tienen un encabezado\n" "por lo tanto este parámetro será utilizado." -#: flatcamGUI/PreferencesUI.py:2817 +#: flatcamGUI/PreferencesUI.py:2999 msgid "" "This sets the units of Excellon files.\n" "Some Excellon files don't have an header\n" @@ -10108,19 +10529,19 @@ msgstr "" "Algunos archivos de Excellon no tienen un encabezado\n" "por lo tanto este parámetro será utilizado." -#: flatcamGUI/PreferencesUI.py:2825 +#: flatcamGUI/PreferencesUI.py:3007 msgid "Update Export settings" msgstr "Actualizar configuración de exportación" -#: flatcamGUI/PreferencesUI.py:2842 +#: flatcamGUI/PreferencesUI.py:3024 msgid "Excellon Optimization" msgstr "Optimización Excellon" -#: flatcamGUI/PreferencesUI.py:2845 +#: flatcamGUI/PreferencesUI.py:3027 msgid "Algorithm:" msgstr "Algoritmo:" -#: flatcamGUI/PreferencesUI.py:2847 flatcamGUI/PreferencesUI.py:2863 +#: flatcamGUI/PreferencesUI.py:3029 flatcamGUI/PreferencesUI.py:3045 msgid "" "This sets the optimization type for the Excellon drill path.\n" "If <> is checked then Google OR-Tools algorithm with\n" @@ -10146,20 +10567,20 @@ msgstr "" "utiliza\n" "Algoritmo de vendedor ambulante para la optimización de rutas." -#: flatcamGUI/PreferencesUI.py:2858 +#: flatcamGUI/PreferencesUI.py:3040 msgid "MetaHeuristic" msgstr "MetaHeuristic" -#: flatcamGUI/PreferencesUI.py:2860 +#: flatcamGUI/PreferencesUI.py:3042 msgid "TSA" msgstr "TSA" -#: flatcamGUI/PreferencesUI.py:2877 flatcamGUI/PreferencesUI.py:3192 -#: flatcamGUI/PreferencesUI.py:4138 +#: flatcamGUI/PreferencesUI.py:3059 flatcamGUI/PreferencesUI.py:3463 +#: flatcamGUI/PreferencesUI.py:4430 msgid "Duration" msgstr "Duración" -#: flatcamGUI/PreferencesUI.py:2880 +#: flatcamGUI/PreferencesUI.py:3062 msgid "" "When OR-Tools Metaheuristic (MH) is enabled there is a\n" "maximum threshold for how much time is spent doing the\n" @@ -10171,15 +10592,19 @@ msgstr "" "Optimización del camino. Esta duración máxima se establece aquí.\n" "En segundos." -#: flatcamGUI/PreferencesUI.py:2899 +#: flatcamGUI/PreferencesUI.py:3081 msgid "Excellon Object Color" msgstr "Color del objeto Excellon" -#: flatcamGUI/PreferencesUI.py:3065 +#: flatcamGUI/PreferencesUI.py:3247 msgid "Excellon Options" msgstr "Excellon Opciones" -#: flatcamGUI/PreferencesUI.py:3071 +#: flatcamGUI/PreferencesUI.py:3251 flatcamGUI/PreferencesUI.py:4227 +msgid "Create CNC Job" +msgstr "Crear trabajo CNC" + +#: flatcamGUI/PreferencesUI.py:3253 msgid "" "Parameters used to create a CNC Job object\n" "for this drill object." @@ -10187,11 +10612,27 @@ msgstr "" "Parámetros utilizados para crear un objeto de trabajo CNC\n" "para este objeto taladro." -#: flatcamGUI/PreferencesUI.py:3185 flatcamGUI/PreferencesUI.py:4133 +#: flatcamGUI/PreferencesUI.py:3370 flatcamGUI/PreferencesUI.py:4314 +msgid "Tool change" +msgstr "Cambio de herram" + +#: flatcamGUI/PreferencesUI.py:3454 flatcamGUI/PreferencesUI.py:4425 msgid "Enable Dwell" msgstr "Habilitar Permanencia" -#: flatcamGUI/PreferencesUI.py:3217 +#: flatcamGUI/PreferencesUI.py:3477 +msgid "" +"The preprocessor JSON file that dictates\n" +"Gcode output." +msgstr "" +"El archivo JSON del postprocesador que dicta\n" +"Salida de Gcode." + +#: flatcamGUI/PreferencesUI.py:3488 +msgid "Gcode" +msgstr "Gcode" + +#: flatcamGUI/PreferencesUI.py:3490 msgid "" "Choose what to use for GCode generation:\n" "'Drills', 'Slots' or 'Both'.\n" @@ -10203,15 +10644,35 @@ msgstr "" "Al elegir 'Ranuras' o 'Ambos', las ranuras serán\n" "convertido en taladros." -#: flatcamGUI/PreferencesUI.py:3235 +#: flatcamGUI/PreferencesUI.py:3506 +msgid "Mill Holes" +msgstr "Agujeros de molino" + +#: flatcamGUI/PreferencesUI.py:3508 msgid "Create Geometry for milling holes." msgstr "Crear geometría para fresar agujeros." -#: flatcamGUI/PreferencesUI.py:3271 +#: flatcamGUI/PreferencesUI.py:3512 +msgid "Drill Tool dia" +msgstr "Diá de la herra. de Perfor" + +#: flatcamGUI/PreferencesUI.py:3523 +msgid "Slot Tool dia" +msgstr "Diá. de la herra. de ranura" + +#: flatcamGUI/PreferencesUI.py:3525 +msgid "" +"Diameter of the cutting tool\n" +"when milling slots." +msgstr "" +"Diámetro de la herramienta de corte\n" +"Al fresar ranuras." + +#: flatcamGUI/PreferencesUI.py:3544 msgid "Excellon Adv. Options" msgstr "Excellon Adv. Opciones" -#: flatcamGUI/PreferencesUI.py:3280 +#: flatcamGUI/PreferencesUI.py:3553 msgid "" "A list of Excellon advanced parameters.\n" "Those parameters are available only for\n" @@ -10221,19 +10682,19 @@ msgstr "" "Esos parámetros están disponibles sólo para\n" "Aplicación avanzada Nivel." -#: flatcamGUI/PreferencesUI.py:3301 +#: flatcamGUI/PreferencesUI.py:3576 msgid "Toolchange X,Y" msgstr "Cambio de herra X, Y" -#: flatcamGUI/PreferencesUI.py:3303 flatcamGUI/PreferencesUI.py:4193 +#: flatcamGUI/PreferencesUI.py:3578 flatcamGUI/PreferencesUI.py:4486 msgid "Toolchange X,Y position." msgstr "Cambio de herra X, posición Y." -#: flatcamGUI/PreferencesUI.py:3360 flatcamGUI/PreferencesUI.py:4280 +#: flatcamGUI/PreferencesUI.py:3638 flatcamGUI/PreferencesUI.py:4573 msgid "Spindle direction" msgstr "Dirección del motor" -#: flatcamGUI/PreferencesUI.py:3362 flatcamGUI/PreferencesUI.py:4282 +#: flatcamGUI/PreferencesUI.py:3640 flatcamGUI/PreferencesUI.py:4575 msgid "" "This sets the direction that the spindle is rotating.\n" "It can be either:\n" @@ -10245,11 +10706,11 @@ msgstr "" "- CW = en el sentido de las agujas del reloj o\n" "- CCW = a la izquierda" -#: flatcamGUI/PreferencesUI.py:3373 flatcamGUI/PreferencesUI.py:4294 +#: flatcamGUI/PreferencesUI.py:3651 flatcamGUI/PreferencesUI.py:4587 msgid "Fast Plunge" msgstr "Salto rápido" -#: flatcamGUI/PreferencesUI.py:3375 flatcamGUI/PreferencesUI.py:4296 +#: flatcamGUI/PreferencesUI.py:3653 flatcamGUI/PreferencesUI.py:4589 msgid "" "By checking this, the vertical move from\n" "Z_Toolchange to Z_move is done with G0,\n" @@ -10261,11 +10722,11 @@ msgstr "" "es decir, la velocidad más rápida disponible.\n" "ADVERTENCIA: el movimiento se realiza en Toolchange X, Y coords." -#: flatcamGUI/PreferencesUI.py:3382 +#: flatcamGUI/PreferencesUI.py:3660 msgid "Fast Retract" msgstr "Retracción rápida" -#: flatcamGUI/PreferencesUI.py:3384 +#: flatcamGUI/PreferencesUI.py:3662 msgid "" "Exit hole strategy.\n" " - When uncheked, while exiting the drilled hole the drill bit\n" @@ -10283,11 +10744,11 @@ msgstr "" "Z_move\n" "(altura de recorrido) se realiza lo más rápido posible (G0) en un movimiento." -#: flatcamGUI/PreferencesUI.py:3402 +#: flatcamGUI/PreferencesUI.py:3680 msgid "Excellon Export" msgstr "Excellon Exportar" -#: flatcamGUI/PreferencesUI.py:3408 +#: flatcamGUI/PreferencesUI.py:3686 msgid "" "The parameters set here are used in the file exported\n" "when using the File -> Export -> Export Excellon menu entry." @@ -10296,11 +10757,11 @@ msgstr "" "cuando se utiliza la entrada de menú Archivo -> Exportar -> Exportar " "Excellon." -#: flatcamGUI/PreferencesUI.py:3419 flatcamGUI/PreferencesUI.py:3425 +#: flatcamGUI/PreferencesUI.py:3697 flatcamGUI/PreferencesUI.py:3703 msgid "The units used in the Excellon file." msgstr "Las unidades utilizadas en el archivo Excellon." -#: flatcamGUI/PreferencesUI.py:3433 +#: flatcamGUI/PreferencesUI.py:3711 msgid "" "The NC drill files, usually named Excellon files\n" "are files that can be found in different formats.\n" @@ -10312,11 +10773,11 @@ msgstr "" "Aquí configuramos el formato utilizado cuando el proporcionado\n" "Las coordenadas no están usando el punto." -#: flatcamGUI/PreferencesUI.py:3467 +#: flatcamGUI/PreferencesUI.py:3745 msgid "Format" msgstr "Formato" -#: flatcamGUI/PreferencesUI.py:3469 flatcamGUI/PreferencesUI.py:3479 +#: flatcamGUI/PreferencesUI.py:3747 flatcamGUI/PreferencesUI.py:3757 msgid "" "Select the kind of coordinates format used.\n" "Coordinates can be saved with decimal point or without.\n" @@ -10332,15 +10793,15 @@ msgstr "" "También deberá especificarse si LZ = ceros iniciales se mantienen\n" "o TZ = ceros finales se mantienen." -#: flatcamGUI/PreferencesUI.py:3476 +#: flatcamGUI/PreferencesUI.py:3754 msgid "Decimal" msgstr "Decimal" -#: flatcamGUI/PreferencesUI.py:3477 +#: flatcamGUI/PreferencesUI.py:3755 msgid "No-Decimal" msgstr "Sin-Decimal" -#: flatcamGUI/PreferencesUI.py:3493 +#: flatcamGUI/PreferencesUI.py:3771 msgid "" "This sets the type of Excellon zeros.\n" "If LZ then Leading Zeros are kept and\n" @@ -10354,7 +10815,7 @@ msgstr "" "Si se comprueba TZ, se mantienen los ceros finales.\n" "y Leading Zeros se eliminan." -#: flatcamGUI/PreferencesUI.py:3503 +#: flatcamGUI/PreferencesUI.py:3781 msgid "" "This sets the default type of Excellon zeros.\n" "If LZ then Leading Zeros are kept and\n" @@ -10368,11 +10829,11 @@ msgstr "" "Si se comprueba TZ, se mantienen los ceros finales.\n" "y se eliminan los ceros iniciales." -#: flatcamGUI/PreferencesUI.py:3513 +#: flatcamGUI/PreferencesUI.py:3791 msgid "Slot type" msgstr "Tipo de ranura" -#: flatcamGUI/PreferencesUI.py:3516 flatcamGUI/PreferencesUI.py:3526 +#: flatcamGUI/PreferencesUI.py:3794 flatcamGUI/PreferencesUI.py:3804 msgid "" "This sets how the slots will be exported.\n" "If ROUTED then the slots will be routed\n" @@ -10386,19 +10847,19 @@ msgstr "" "Si PERFORADO (G85), las ranuras se exportarán\n" "utilizando el comando Ranura perforada (G85)." -#: flatcamGUI/PreferencesUI.py:3523 +#: flatcamGUI/PreferencesUI.py:3801 msgid "Routed" msgstr "Enrutado" -#: flatcamGUI/PreferencesUI.py:3524 +#: flatcamGUI/PreferencesUI.py:3802 msgid "Drilled(G85)" msgstr "Perforado (G85)" -#: flatcamGUI/PreferencesUI.py:3557 +#: flatcamGUI/PreferencesUI.py:3835 msgid "A list of Excellon Editor parameters." msgstr "Una lista de los parámetros de Excellon Editor." -#: flatcamGUI/PreferencesUI.py:3567 +#: flatcamGUI/PreferencesUI.py:3845 msgid "" "Set the number of selected Excellon geometry\n" "items above which the utility geometry\n" @@ -10412,19 +10873,20 @@ msgstr "" "Aumenta el rendimiento al mover un\n" "Gran cantidad de elementos geométricos." -#: flatcamGUI/PreferencesUI.py:3580 flatcamGUI/PreferencesUI.py:5100 -msgid "New Tool Dia" -msgstr "Nueva Herra. Dia" +#: flatcamGUI/PreferencesUI.py:3858 flatcamGUI/PreferencesUI.py:5396 +#: flatcamGUI/PreferencesUI.py:5962 +msgid "New Dia" +msgstr "Nuevo dia" -#: flatcamGUI/PreferencesUI.py:3605 +#: flatcamGUI/PreferencesUI.py:3883 msgid "Linear Drill Array" msgstr "Matriz de taladro lineal" -#: flatcamGUI/PreferencesUI.py:3651 +#: flatcamGUI/PreferencesUI.py:3929 msgid "Circular Drill Array" msgstr "Matriz de Taladro Circ" -#: flatcamGUI/PreferencesUI.py:3721 +#: flatcamGUI/PreferencesUI.py:3999 msgid "" "Angle at which the slot is placed.\n" "The precision is of max 2 decimals.\n" @@ -10436,19 +10898,19 @@ msgstr "" "El valor mínimo es: -359.99 grados.\n" "El valor máximo es: 360.00 grados." -#: flatcamGUI/PreferencesUI.py:3740 +#: flatcamGUI/PreferencesUI.py:4018 msgid "Linear Slot Array" msgstr "Matriz Lin de Ranuras" -#: flatcamGUI/PreferencesUI.py:3801 +#: flatcamGUI/PreferencesUI.py:4079 msgid "Circular Slot Array" msgstr "Matriz Circ de Ranura" -#: flatcamGUI/PreferencesUI.py:3839 +#: flatcamGUI/PreferencesUI.py:4117 msgid "Geometry General" msgstr "Geometría General" -#: flatcamGUI/PreferencesUI.py:3861 +#: flatcamGUI/PreferencesUI.py:4139 msgid "" "The number of circle steps for Geometry \n" "circle and arc shapes linear approximation." @@ -10456,15 +10918,20 @@ msgstr "" "El número de pasos de círculo para Geometría\n" "Círculo y arcos de aproximación lineal." -#: flatcamGUI/PreferencesUI.py:3890 +#: flatcamGUI/PreferencesUI.py:4153 flatcamGUI/PreferencesUI.py:5320 +#: flatcamGUI/PreferencesUI.py:5887 flatcamGUI/PreferencesUI.py:6953 +msgid "Tools Dia" +msgstr "Diá. de Herram" + +#: flatcamGUI/PreferencesUI.py:4170 msgid "Geometry Object Color" msgstr "Color del objeto de Geometría" -#: flatcamGUI/PreferencesUI.py:3941 +#: flatcamGUI/PreferencesUI.py:4221 msgid "Geometry Options" msgstr "Opc. de geometría" -#: flatcamGUI/PreferencesUI.py:3949 +#: flatcamGUI/PreferencesUI.py:4229 msgid "" "Create a CNC Job object\n" "tracing the contours of this\n" @@ -10474,11 +10941,11 @@ msgstr "" "trazando los contornos de este\n" "Objeto de geometría." -#: flatcamGUI/PreferencesUI.py:3993 +#: flatcamGUI/PreferencesUI.py:4273 msgid "Depth/Pass" msgstr "Profund. / Pase" -#: flatcamGUI/PreferencesUI.py:3995 +#: flatcamGUI/PreferencesUI.py:4275 msgid "" "The depth to cut on each pass,\n" "when multidepth is enabled.\n" @@ -10492,11 +10959,11 @@ msgstr "" "Es una fracción de la profundidad.\n" "que tiene valor negativo." -#: flatcamGUI/PreferencesUI.py:4173 +#: flatcamGUI/PreferencesUI.py:4466 msgid "Geometry Adv. Options" msgstr "Geometría Adv. Opciones" -#: flatcamGUI/PreferencesUI.py:4181 +#: flatcamGUI/PreferencesUI.py:4474 msgid "" "A list of Geometry advanced parameters.\n" "Those parameters are available only for\n" @@ -10506,13 +10973,13 @@ msgstr "" "Esos parámetros están disponibles sólo para\n" "Aplicación avanzada Nivel." -#: flatcamGUI/PreferencesUI.py:4191 flatcamGUI/PreferencesUI.py:6539 -#: flatcamGUI/PreferencesUI.py:7586 flatcamTools/ToolCalibration.py:125 -#: flatcamTools/ToolSolderPaste.py:239 +#: flatcamGUI/PreferencesUI.py:4484 flatcamGUI/PreferencesUI.py:7045 +#: flatcamGUI/PreferencesUI.py:8092 flatcamTools/ToolCalibration.py:125 +#: flatcamTools/ToolSolderPaste.py:241 msgid "Toolchange X-Y" msgstr "Cambio de herra X, Y" -#: flatcamGUI/PreferencesUI.py:4202 +#: flatcamGUI/PreferencesUI.py:4495 msgid "" "Height of the tool just after starting the work.\n" "Delete the value if you don't need this feature." @@ -10520,11 +10987,11 @@ msgstr "" "Altura de la herramienta justo después de comenzar el trabajo.\n" "Elimine el valor si no necesita esta característica." -#: flatcamGUI/PreferencesUI.py:4304 +#: flatcamGUI/PreferencesUI.py:4597 msgid "Segment X size" msgstr "Tamaño del Seg. X" -#: flatcamGUI/PreferencesUI.py:4306 +#: flatcamGUI/PreferencesUI.py:4599 msgid "" "The size of the trace segment on the X axis.\n" "Useful for auto-leveling.\n" @@ -10534,11 +11001,11 @@ msgstr "" "Útil para la autonivelación.\n" "Un valor de 0 significa que no hay segmentación en el eje X." -#: flatcamGUI/PreferencesUI.py:4320 +#: flatcamGUI/PreferencesUI.py:4613 msgid "Segment Y size" msgstr "Tamaño del Seg. Y" -#: flatcamGUI/PreferencesUI.py:4322 +#: flatcamGUI/PreferencesUI.py:4615 msgid "" "The size of the trace segment on the Y axis.\n" "Useful for auto-leveling.\n" @@ -10548,15 +11015,11 @@ msgstr "" "Útil para la autonivelación.\n" "Un valor de 0 significa que no hay segmentación en el eje Y." -#: flatcamGUI/PreferencesUI.py:4343 -msgid "Geometry Editor" -msgstr "Editor de geometría" - -#: flatcamGUI/PreferencesUI.py:4349 +#: flatcamGUI/PreferencesUI.py:4642 msgid "A list of Geometry Editor parameters." msgstr "Una lista de parámetros del editor de geometría." -#: flatcamGUI/PreferencesUI.py:4359 flatcamGUI/PreferencesUI.py:7111 +#: flatcamGUI/PreferencesUI.py:4652 flatcamGUI/PreferencesUI.py:7617 msgid "" "Set the number of selected geometry\n" "items above which the utility geometry\n" @@ -10570,11 +11033,11 @@ msgstr "" "Aumenta el rendimiento al mover un\n" "Gran cantidad de elementos geométricos." -#: flatcamGUI/PreferencesUI.py:4391 +#: flatcamGUI/PreferencesUI.py:4684 msgid "CNC Job General" msgstr "CNC trabajo general" -#: flatcamGUI/PreferencesUI.py:4444 +#: flatcamGUI/PreferencesUI.py:4737 msgid "" "The number of circle steps for GCode \n" "circle and arc shapes linear approximation." @@ -10582,11 +11045,11 @@ msgstr "" "El número de pasos de círculo para GCode \n" "Círculo y arcos de aproximación lineal." -#: flatcamGUI/PreferencesUI.py:4453 +#: flatcamGUI/PreferencesUI.py:4746 msgid "Travel dia" msgstr "Dia de Viaje" -#: flatcamGUI/PreferencesUI.py:4455 +#: flatcamGUI/PreferencesUI.py:4748 msgid "" "The width of the travel lines to be\n" "rendered in the plot." @@ -10594,15 +11057,15 @@ msgstr "" "El ancho de las líneas de viaje a ser\n" "prestados en la trama." -#: flatcamGUI/PreferencesUI.py:4468 +#: flatcamGUI/PreferencesUI.py:4761 msgid "G-code Decimals" msgstr "Decimales del código G" -#: flatcamGUI/PreferencesUI.py:4471 flatcamTools/ToolFiducials.py:74 +#: flatcamGUI/PreferencesUI.py:4764 flatcamTools/ToolFiducials.py:74 msgid "Coordinates" msgstr "Coordenadas" -#: flatcamGUI/PreferencesUI.py:4473 +#: flatcamGUI/PreferencesUI.py:4766 msgid "" "The number of decimals to be used for \n" "the X, Y, Z coordinates in CNC code (GCODE, etc.)" @@ -10610,11 +11073,11 @@ msgstr "" "El número de decimales a utilizar para\n" "Las coordenadas X, Y, Z en código CNC (GCODE, etc.)" -#: flatcamGUI/PreferencesUI.py:4484 flatcamTools/ToolProperties.py:492 +#: flatcamGUI/PreferencesUI.py:4777 flatcamTools/ToolProperties.py:519 msgid "Feedrate" msgstr "Avance" -#: flatcamGUI/PreferencesUI.py:4486 +#: flatcamGUI/PreferencesUI.py:4779 msgid "" "The number of decimals to be used for \n" "the Feedrate parameter in CNC code (GCODE, etc.)" @@ -10622,11 +11085,11 @@ msgstr "" "El número de decimales a utilizar para\n" "El parámetro de avance en código CNC (GCODE, etc.)" -#: flatcamGUI/PreferencesUI.py:4497 +#: flatcamGUI/PreferencesUI.py:4790 msgid "Coordinates type" msgstr "Tipo de coordenadas" -#: flatcamGUI/PreferencesUI.py:4499 +#: flatcamGUI/PreferencesUI.py:4792 msgid "" "The type of coordinates to be used in Gcode.\n" "Can be:\n" @@ -10638,19 +11101,19 @@ msgstr "" "- G90 absoluto -> la referencia es el origen x = 0, y = 0\n" "- Incremental G91 -> la referencia es la posición anterior" -#: flatcamGUI/PreferencesUI.py:4505 +#: flatcamGUI/PreferencesUI.py:4798 msgid "Absolute G90" msgstr "Absoluto G90" -#: flatcamGUI/PreferencesUI.py:4506 +#: flatcamGUI/PreferencesUI.py:4799 msgid "Incremental G91" msgstr "G91 incremental" -#: flatcamGUI/PreferencesUI.py:4516 +#: flatcamGUI/PreferencesUI.py:4809 msgid "Force Windows style line-ending" msgstr "Forzar el final de línea al estilo de Windows" -#: flatcamGUI/PreferencesUI.py:4518 +#: flatcamGUI/PreferencesUI.py:4811 msgid "" "When checked will force a Windows style line-ending\n" "(\\r\\n) on non-Windows OS's." @@ -10658,35 +11121,35 @@ msgstr "" "Cuando está marcado, forzará un final de línea de estilo Windows\n" "(\\r \\n) en sistemas operativos que no sean de Windows." -#: flatcamGUI/PreferencesUI.py:4530 +#: flatcamGUI/PreferencesUI.py:4823 msgid "Travel Line Color" msgstr "Color de Línea de Viaje" -#: flatcamGUI/PreferencesUI.py:4536 +#: flatcamGUI/PreferencesUI.py:4829 msgid "Set the travel line color for plotted objects." msgstr "Establezca el color de la línea de viaje para los objetos trazados." -#: flatcamGUI/PreferencesUI.py:4596 +#: flatcamGUI/PreferencesUI.py:4889 msgid "CNCJob Object Color" msgstr "Color de objeto CNCJob" -#: flatcamGUI/PreferencesUI.py:4602 +#: flatcamGUI/PreferencesUI.py:4895 msgid "Set the color for plotted objects." msgstr "Establecer el color para los objetos trazados." -#: flatcamGUI/PreferencesUI.py:4762 +#: flatcamGUI/PreferencesUI.py:5055 msgid "CNC Job Options" msgstr "Opciones de trabajo CNC" -#: flatcamGUI/PreferencesUI.py:4766 +#: flatcamGUI/PreferencesUI.py:5059 msgid "Export G-Code" msgstr "Exportar G-Code" -#: flatcamGUI/PreferencesUI.py:4782 +#: flatcamGUI/PreferencesUI.py:5075 msgid "Prepend to G-Code" msgstr "Prefijo al código G" -#: flatcamGUI/PreferencesUI.py:4791 +#: flatcamGUI/PreferencesUI.py:5084 msgid "" "Type here any G-Code commands you would like to add at the beginning of the " "G-Code file." @@ -10694,11 +11157,11 @@ msgstr "" "Escriba aquí los comandos de G-Code que le gustaría agregar al comienzo del " "archivo de G-Code." -#: flatcamGUI/PreferencesUI.py:4798 +#: flatcamGUI/PreferencesUI.py:5091 msgid "Append to G-Code" msgstr "Adjuntar al código G" -#: flatcamGUI/PreferencesUI.py:4808 +#: flatcamGUI/PreferencesUI.py:5101 msgid "" "Type here any G-Code commands you would like to append to the generated " "file.\n" @@ -10708,11 +11171,11 @@ msgstr "" "generado.\n" "Por ejemplo: M2 (Fin del programa)" -#: flatcamGUI/PreferencesUI.py:4824 +#: flatcamGUI/PreferencesUI.py:5117 msgid "CNC Job Adv. Options" msgstr "CNCJob Adv. Opciones" -#: flatcamGUI/PreferencesUI.py:4861 +#: flatcamGUI/PreferencesUI.py:5154 msgid "" "Type here any G-Code commands you would like to be executed when Toolchange " "event is encountered.\n" @@ -10728,47 +11191,48 @@ msgstr "" "ADVERTENCIA: solo se puede usar con un archivo de preprocesador que tenga " "'toolchange_custom' en su nombre." -#: flatcamGUI/PreferencesUI.py:4916 +#: flatcamGUI/PreferencesUI.py:5209 msgid "Z depth for the cut" msgstr "Profundidad Z para el corte" -#: flatcamGUI/PreferencesUI.py:4917 +#: flatcamGUI/PreferencesUI.py:5210 msgid "Z height for travel" msgstr "Altura Z para viajar" -#: flatcamGUI/PreferencesUI.py:4923 +#: flatcamGUI/PreferencesUI.py:5216 msgid "dwelltime = time to dwell to allow the spindle to reach it's set RPM" msgstr "" "dwelltime = tiempo de espera para permitir que el husillo alcance su RPM " "establecido" -#: flatcamGUI/PreferencesUI.py:4942 +#: flatcamGUI/PreferencesUI.py:5235 msgid "Annotation Size" msgstr "Tamaño de la anotación" -#: flatcamGUI/PreferencesUI.py:4944 +#: flatcamGUI/PreferencesUI.py:5237 msgid "The font size of the annotation text. In pixels." msgstr "El tamaño de fuente del texto de anotación. En píxeles." -#: flatcamGUI/PreferencesUI.py:4954 +#: flatcamGUI/PreferencesUI.py:5247 msgid "Annotation Color" msgstr "Color de anotación" -#: flatcamGUI/PreferencesUI.py:4956 +#: flatcamGUI/PreferencesUI.py:5249 msgid "Set the font color for the annotation texts." msgstr "Establecer el color de fuente para los textos de anotación." -#: flatcamGUI/PreferencesUI.py:5013 +#: flatcamGUI/PreferencesUI.py:5306 msgid "NCC Tool Options" msgstr "Opc. de herra. NCC" -#: flatcamGUI/PreferencesUI.py:5027 flatcamGUI/PreferencesUI.py:6449 -msgid "Tools dia" -msgstr "Herra. dia" +#: flatcamGUI/PreferencesUI.py:5328 flatcamGUI/PreferencesUI.py:5896 +msgid "Comma separated values" +msgstr "Valores Separados por Comas" -#: flatcamGUI/PreferencesUI.py:5038 flatcamGUI/PreferencesUI.py:5046 -#: flatcamTools/ToolNonCopperClear.py:215 -#: flatcamTools/ToolNonCopperClear.py:223 +#: flatcamGUI/PreferencesUI.py:5334 flatcamGUI/PreferencesUI.py:5342 +#: flatcamGUI/PreferencesUI.py:5903 flatcamTools/ToolNCC.py:215 +#: flatcamTools/ToolNCC.py:223 flatcamTools/ToolPaint.py:198 +#: flatcamTools/ToolPaint.py:206 msgid "" "Default tool type:\n" "- 'V-shape'\n" @@ -10778,13 +11242,15 @@ msgstr "" "- 'Forma V'\n" "- circular" -#: flatcamGUI/PreferencesUI.py:5043 flatcamTools/ToolNonCopperClear.py:220 +#: flatcamGUI/PreferencesUI.py:5339 flatcamGUI/PreferencesUI.py:5908 +#: flatcamTools/ToolNCC.py:220 flatcamTools/ToolPaint.py:203 msgid "V-shape" msgstr "Forma V" -#: flatcamGUI/PreferencesUI.py:5083 flatcamGUI/PreferencesUI.py:5092 -#: flatcamTools/ToolNonCopperClear.py:256 -#: flatcamTools/ToolNonCopperClear.py:264 +#: flatcamGUI/PreferencesUI.py:5379 flatcamGUI/PreferencesUI.py:5388 +#: flatcamGUI/PreferencesUI.py:5946 flatcamGUI/PreferencesUI.py:5955 +#: flatcamTools/ToolNCC.py:262 flatcamTools/ToolNCC.py:271 +#: flatcamTools/ToolPaint.py:245 flatcamTools/ToolPaint.py:254 msgid "" "Depth of cut into material. Negative value.\n" "In FlatCAM units." @@ -10792,35 +11258,26 @@ msgstr "" "Profundidad de corte en el material. Valor negativo.\n" "En unidades FlatCAM." -#: flatcamGUI/PreferencesUI.py:5102 -msgid "The new tool diameter (cut width) to add in the tool table." -msgstr "" -"El nuevo diámetro de herramienta (ancho de corte) para agregar en la tabla " -"de herramientas." - -#: flatcamGUI/PreferencesUI.py:5114 flatcamGUI/PreferencesUI.py:5122 -#: flatcamTools/ToolNonCopperClear.py:164 -#: flatcamTools/ToolNonCopperClear.py:172 +#: flatcamGUI/PreferencesUI.py:5398 flatcamGUI/PreferencesUI.py:5964 +#: flatcamTools/ToolNCC.py:280 flatcamTools/ToolPaint.py:263 msgid "" -"Milling type when the selected tool is of type: 'iso_op':\n" -"- climb / best for precision milling and to reduce tool usage\n" -"- conventional / useful when there is no backlash compensation" +"Diameter for the new tool to add in the Tool Table.\n" +"If the tool is V-shape type then this value is automatically\n" +"calculated from the other parameters." msgstr "" -"Tipo de fresado cuando la herramienta seleccionada es de tipo: 'iso_op':\n" -"- ascenso / mejor para fresado de precisión y para reducir el uso de " -"herramientas\n" -"- convencional / útil cuando no hay compensación de reacción" +"Diámetro de la nueva herramienta para agregar en la Tabla de herramientas.\n" +"Si la herramienta es de tipo V, este valor es automáticamente\n" +"calculado a partir de los otros parámetros." -#: flatcamGUI/PreferencesUI.py:5131 flatcamGUI/PreferencesUI.py:5546 -#: flatcamTools/ToolNonCopperClear.py:181 flatcamTools/ToolPaint.py:153 +#: flatcamGUI/PreferencesUI.py:5435 flatcamGUI/PreferencesUI.py:5981 +#: flatcamTools/ToolNCC.py:174 flatcamTools/ToolPaint.py:158 msgid "Tool order" msgstr "Orden de la Herram" -#: flatcamGUI/PreferencesUI.py:5132 flatcamGUI/PreferencesUI.py:5142 -#: flatcamGUI/PreferencesUI.py:5547 flatcamGUI/PreferencesUI.py:5557 -#: flatcamTools/ToolNonCopperClear.py:182 -#: flatcamTools/ToolNonCopperClear.py:192 flatcamTools/ToolPaint.py:154 -#: flatcamTools/ToolPaint.py:164 +#: flatcamGUI/PreferencesUI.py:5436 flatcamGUI/PreferencesUI.py:5446 +#: flatcamGUI/PreferencesUI.py:5982 flatcamTools/ToolNCC.py:175 +#: flatcamTools/ToolNCC.py:185 flatcamTools/ToolPaint.py:159 +#: flatcamTools/ToolPaint.py:169 msgid "" "This set the way that the tools in the tools table are used.\n" "'No' --> means that the used order is the one in the tool table\n" @@ -10841,69 +11298,39 @@ msgstr "" "orden\n" "en reversa y deshabilitar este control." -#: flatcamGUI/PreferencesUI.py:5140 flatcamGUI/PreferencesUI.py:5555 -#: flatcamTools/ToolNonCopperClear.py:190 flatcamTools/ToolPaint.py:162 +#: flatcamGUI/PreferencesUI.py:5444 flatcamGUI/PreferencesUI.py:5990 +#: flatcamTools/ToolNCC.py:183 flatcamTools/ToolPaint.py:167 msgid "Forward" msgstr "Adelante" -#: flatcamGUI/PreferencesUI.py:5141 flatcamGUI/PreferencesUI.py:5556 -#: flatcamTools/ToolNonCopperClear.py:191 flatcamTools/ToolPaint.py:163 +#: flatcamGUI/PreferencesUI.py:5445 flatcamGUI/PreferencesUI.py:5991 +#: flatcamTools/ToolNCC.py:184 flatcamTools/ToolPaint.py:168 msgid "Reverse" msgstr "Atras" -#: flatcamGUI/PreferencesUI.py:5154 flatcamTools/ToolNonCopperClear.py:321 +#: flatcamGUI/PreferencesUI.py:5545 +msgid "Offset value" +msgstr "Valor de Comp" + +#: flatcamGUI/PreferencesUI.py:5547 msgid "" -"How much (fraction) of the tool width to overlap each tool pass.\n" -"Adjust the value starting with lower values\n" -"and increasing it if areas that should be cleared are still \n" -"not cleared.\n" -"Lower values = faster processing, faster execution on CNC.\n" -"Higher values = slow processing and slow execution on CNC\n" -"due of too many paths." +"If used, it will add an offset to the copper features.\n" +"The copper clearing will finish to a distance\n" +"from the copper features.\n" +"The value can be between 0.0 and 9999.9 FlatCAM units." msgstr "" -"Cuánta (fracción) del ancho de la herramienta se superponen con cada pasada " -"de herramienta\n" -"Ajuste el valor comenzando con valores más bajos\n" -"y aumentándolo si las áreas que deben ser despejadas son todavía\n" -"no borrado.\n" -"Valores más bajos = procesamiento más rápido, ejecución más rápida en PCB.\n" -"Valores más altos = procesamiento lento y ejecución lenta en CNC\n" -"debido a demasiados caminos." +"Si se usa, agregará un desplazamiento a las características de cobre.\n" +"El claro de cobre terminará a cierta distancia.\n" +"de las características de cobre.\n" +"El valor puede estar entre 0 y 9999.9 unidades FlatCAM." -#: flatcamGUI/PreferencesUI.py:5173 flatcamGUI/PreferencesUI.py:7177 -#: flatcamGUI/PreferencesUI.py:7419 flatcamGUI/PreferencesUI.py:7483 -#: flatcamTools/ToolCopperThieving.py:113 flatcamTools/ToolFiducials.py:174 -#: flatcamTools/ToolFiducials.py:237 flatcamTools/ToolNonCopperClear.py:339 -msgid "Bounding box margin." -msgstr "Margen de cuadro delimitador." - -#: flatcamGUI/PreferencesUI.py:5186 flatcamGUI/PreferencesUI.py:5604 -#: flatcamTools/ToolNonCopperClear.py:350 -msgid "" -"Algorithm for non-copper clearing:
Standard: Fixed step inwards." -"
Seed-based: Outwards from seed.
Line-based: Parallel " -"lines." -msgstr "" -"Algoritmo para limpieza sin cobre:
Estándar : paso fijo hacia " -"el interior.
basado en semillas : hacia afuera desde el origen. " -"
basado en líneas : Líneas paralelas." - -#: flatcamGUI/PreferencesUI.py:5202 flatcamGUI/PreferencesUI.py:5618 -#: flatcamTools/ToolNonCopperClear.py:364 flatcamTools/ToolPaint.py:267 -msgid "Connect" -msgstr "Conectar" - -#: flatcamGUI/PreferencesUI.py:5211 flatcamGUI/PreferencesUI.py:5626 -#: flatcamTools/ToolNonCopperClear.py:371 flatcamTools/ToolPaint.py:274 -msgid "Contour" -msgstr "Contorno" - -#: flatcamGUI/PreferencesUI.py:5220 flatcamTools/ToolNonCopperClear.py:379 -#: flatcamTools/ToolPaint.py:281 +#: flatcamGUI/PreferencesUI.py:5567 flatcamGUI/PreferencesUI.py:6083 +#: flatcamGUI/PreferencesUI.py:6084 flatcamTools/ToolNCC.py:512 +#: flatcamTools/ToolPaint.py:442 msgid "Rest Machining" msgstr "Mecanizado de descanso" -#: flatcamGUI/PreferencesUI.py:5222 flatcamTools/ToolNonCopperClear.py:381 +#: flatcamGUI/PreferencesUI.py:5569 flatcamTools/ToolNCC.py:516 msgid "" "If checked, use 'rest machining'.\n" "Basically it will clear copper outside PCB features,\n" @@ -10922,82 +11349,66 @@ msgstr "" "no más cobre para limpiar o no hay más herramientas.\n" "Si no está marcado, use el algoritmo estándar." -#: flatcamGUI/PreferencesUI.py:5236 flatcamTools/ToolNonCopperClear.py:395 -#: flatcamTools/ToolNonCopperClear.py:405 +#: flatcamGUI/PreferencesUI.py:5588 flatcamGUI/PreferencesUI.py:6119 +#: flatcamGUI/PreferencesUI.py:7696 flatcamTools/ToolCopperThieving.py:127 +#: flatcamTools/ToolNCC.py:535 flatcamTools/ToolNCC.py:1311 +#: flatcamTools/ToolNCC.py:1642 flatcamTools/ToolNCC.py:1930 +#: flatcamTools/ToolNCC.py:1985 flatcamTools/ToolPaint.py:486 +#: flatcamTools/ToolPaint.py:946 flatcamTools/ToolPaint.py:1447 +msgid "Area Selection" +msgstr "Selección de área" + +#: flatcamGUI/PreferencesUI.py:5588 flatcamGUI/PreferencesUI.py:6119 +#: flatcamGUI/PreferencesUI.py:7697 flatcamTools/ToolCopperThieving.py:128 +#: flatcamTools/ToolDblSided.py:217 flatcamTools/ToolNCC.py:535 +#: flatcamTools/ToolNCC.py:1658 flatcamTools/ToolNCC.py:1936 +#: flatcamTools/ToolNCC.py:1993 flatcamTools/ToolNCC.py:2301 +#: flatcamTools/ToolNCC.py:2581 flatcamTools/ToolNCC.py:3007 +#: flatcamTools/ToolPaint.py:486 flatcamTools/ToolPaint.py:931 +#: flatcamTools/ToolPaint.py:1463 tclCommands/TclCommandCopperClear.py:192 +#: tclCommands/TclCommandPaint.py:166 +msgid "Reference Object" +msgstr "Objeto de referencia" + +#: flatcamGUI/PreferencesUI.py:5592 flatcamTools/ToolNCC.py:541 msgid "" -"If used, it will add an offset to the copper features.\n" -"The copper clearing will finish to a distance\n" -"from the copper features.\n" -"The value can be between 0 and 10 FlatCAM units." -msgstr "" -"Si se usa, agregará un desplazamiento a las características de cobre.\n" -"El claro de cobre terminará a cierta distancia.\n" -"de las características de cobre.\n" -"El valor puede estar entre 0 y 10 unidades FlatCAM." - -#: flatcamGUI/PreferencesUI.py:5245 flatcamTools/ToolNonCopperClear.py:403 -msgid "Offset value" -msgstr "Valor de Comp" - -#: flatcamGUI/PreferencesUI.py:5247 -msgid "" -"If used, it will add an offset to the copper features.\n" -"The copper clearing will finish to a distance\n" -"from the copper features.\n" -"The value can be between 0.0 and 9999.9 FlatCAM units." -msgstr "" -"Si se usa, agregará un desplazamiento a las características de cobre.\n" -"El claro de cobre terminará a cierta distancia.\n" -"de las características de cobre.\n" -"El valor puede estar entre 0 y 9999.9 unidades FlatCAM." - -#: flatcamGUI/PreferencesUI.py:5262 flatcamGUI/PreferencesUI.py:7189 -#: flatcamTools/ToolCopperThieving.py:125 -#: flatcamTools/ToolNonCopperClear.py:429 -msgid "Itself" -msgstr "Sí mismo" - -#: flatcamGUI/PreferencesUI.py:5263 flatcamGUI/PreferencesUI.py:5646 -msgid "Area" -msgstr "Zona" - -#: flatcamGUI/PreferencesUI.py:5264 flatcamGUI/PreferencesUI.py:5648 -msgid "Ref" -msgstr "Ref" - -#: flatcamGUI/PreferencesUI.py:5267 -msgid "" -"- 'Itself' - the non copper clearing extent\n" -"is based on the object that is copper cleared.\n" +"Selection of area to be processed.\n" +"- 'Itself' - the processing extent is based on the object that is " +"processed.\n" " - 'Area Selection' - left mouse click to start selection of the area to be " -"painted.\n" -"Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple " -"areas.\n" -"- 'Reference Object' - will do non copper clearing within the area\n" -"specified by another object." +"processed.\n" +"- 'Reference Object' - will process the area specified by another object." msgstr "" -"- 'Sí mismo' - la extensión de limpieza sin cobre\n" -"se basa en el objeto que es cobre despejado.\n" -"  - 'Selección de área': haga clic con el botón izquierdo del mouse para " -"iniciar la selección del área a pintar.\n" -"Mantener presionada una tecla modificadora (CTRL o SHIFT) permitirá agregar " -"múltiples áreas.\n" -"- 'Objeto de referencia' - hará una limpieza sin cobre dentro del área\n" -"especificado por otro objeto." +"Selección del área a procesar.\n" +"- 'Sí mismo': la extensión del procesamiento se basa en el objeto que se " +"procesa.\n" +"- 'Selección de área': haga clic con el botón izquierdo del mouse para " +"iniciar la selección del área a procesar.\n" +"- 'Objeto de referencia': procesará el área especificada por otro objeto." -#: flatcamGUI/PreferencesUI.py:5279 flatcamGUI/PreferencesUI.py:5654 +#: flatcamGUI/PreferencesUI.py:5601 flatcamGUI/PreferencesUI.py:6125 +#: flatcamTools/ToolNCC.py:578 flatcamTools/ToolPaint.py:522 +msgid "Shape" +msgstr "Forma" + +#: flatcamGUI/PreferencesUI.py:5603 flatcamGUI/PreferencesUI.py:6127 +#: flatcamTools/ToolNCC.py:580 flatcamTools/ToolPaint.py:524 +msgid "The kind of selection shape used for area selection." +msgstr "El tipo de forma de selección utilizada para la selección de área." + +#: flatcamGUI/PreferencesUI.py:5618 flatcamGUI/PreferencesUI.py:6142 msgid "Normal" msgstr "Normal" -#: flatcamGUI/PreferencesUI.py:5280 flatcamGUI/PreferencesUI.py:5655 +#: flatcamGUI/PreferencesUI.py:5619 flatcamGUI/PreferencesUI.py:6143 msgid "Progressive" msgstr "Progresivo" -#: flatcamGUI/PreferencesUI.py:5281 +#: flatcamGUI/PreferencesUI.py:5620 msgid "NCC Plotting" msgstr "Trazado NCC" -#: flatcamGUI/PreferencesUI.py:5283 +#: flatcamGUI/PreferencesUI.py:5622 msgid "" "- 'Normal' - normal plotting, done at the end of the NCC job\n" "- 'Progressive' - after each shape is generated it will be plotted." @@ -11005,16 +11416,16 @@ msgstr "" "- 'Normal': trazado normal, realizado al final del trabajo de NCC\n" "- 'Progresivo': después de generar cada forma, se trazará." -#: flatcamGUI/PreferencesUI.py:5297 +#: flatcamGUI/PreferencesUI.py:5636 msgid "Cutout Tool Options" msgstr "Opc. de herra. de recorte" -#: flatcamGUI/PreferencesUI.py:5312 flatcamTools/ToolCalculators.py:123 -#: flatcamTools/ToolCutOut.py:123 +#: flatcamGUI/PreferencesUI.py:5651 flatcamTools/ToolCalculators.py:123 +#: flatcamTools/ToolCutOut.py:130 msgid "Tool Diameter" msgstr "Diá. de Herram" -#: flatcamGUI/PreferencesUI.py:5314 flatcamTools/ToolCutOut.py:125 +#: flatcamGUI/PreferencesUI.py:5653 flatcamTools/ToolCutOut.py:132 msgid "" "Diameter of the tool used to cutout\n" "the PCB shape out of the surrounding material." @@ -11022,11 +11433,11 @@ msgstr "" "Diámetro de la herramienta utilizada para cortar\n" "La forma de PCB fuera del material circundante." -#: flatcamGUI/PreferencesUI.py:5369 flatcamTools/ToolCutOut.py:104 +#: flatcamGUI/PreferencesUI.py:5708 msgid "Object kind" msgstr "Tipo de objeto" -#: flatcamGUI/PreferencesUI.py:5371 flatcamTools/ToolCutOut.py:106 +#: flatcamGUI/PreferencesUI.py:5710 flatcamTools/ToolCutOut.py:78 msgid "" "Choice of what kind the object we want to cutout is.
- Single: " "contain a single PCB Gerber outline object.
- Panel: a panel PCB " @@ -11038,15 +11449,15 @@ msgstr "" "un panel de PCB Gerber objeto, que se hace\n" "de muchos esquemas de PCB individuales." -#: flatcamGUI/PreferencesUI.py:5378 flatcamTools/ToolCutOut.py:112 +#: flatcamGUI/PreferencesUI.py:5717 flatcamTools/ToolCutOut.py:84 msgid "Single" msgstr "Soltero" -#: flatcamGUI/PreferencesUI.py:5379 flatcamTools/ToolCutOut.py:113 +#: flatcamGUI/PreferencesUI.py:5718 flatcamTools/ToolCutOut.py:85 msgid "Panel" msgstr "Panel" -#: flatcamGUI/PreferencesUI.py:5386 flatcamTools/ToolCutOut.py:186 +#: flatcamGUI/PreferencesUI.py:5725 flatcamTools/ToolCutOut.py:193 msgid "" "Margin over bounds. A positive value here\n" "will make the cutout of the PCB further from\n" @@ -11056,11 +11467,11 @@ msgstr "" "hará que el corte de la PCB esté más alejado de\n" "el borde real de PCB" -#: flatcamGUI/PreferencesUI.py:5399 flatcamTools/ToolCutOut.py:197 +#: flatcamGUI/PreferencesUI.py:5738 flatcamTools/ToolCutOut.py:204 msgid "Gap size" msgstr "Tamaño de la brecha" -#: flatcamGUI/PreferencesUI.py:5401 flatcamTools/ToolCutOut.py:199 +#: flatcamGUI/PreferencesUI.py:5740 flatcamTools/ToolCutOut.py:206 msgid "" "The size of the bridge gaps in the cutout\n" "used to keep the board connected to\n" @@ -11072,11 +11483,11 @@ msgstr "" "el material circundante (el\n" "de la cual se corta el PCB)." -#: flatcamGUI/PreferencesUI.py:5415 flatcamTools/ToolCutOut.py:241 +#: flatcamGUI/PreferencesUI.py:5754 flatcamTools/ToolCutOut.py:250 msgid "Gaps" msgstr "Brechas" -#: flatcamGUI/PreferencesUI.py:5417 +#: flatcamGUI/PreferencesUI.py:5756 msgid "" "Number of gaps used for the cutout.\n" "There can be maximum 8 bridges/gaps.\n" @@ -11100,11 +11511,11 @@ msgstr "" "- 2tb - 2 * top + 2 * bottom\n" "- 8 - 2 * izquierda + 2 * derecha + 2 * arriba + 2 * abajo" -#: flatcamGUI/PreferencesUI.py:5439 flatcamTools/ToolCutOut.py:216 +#: flatcamGUI/PreferencesUI.py:5778 flatcamTools/ToolCutOut.py:223 msgid "Convex Shape" msgstr "Forma convexa" -#: flatcamGUI/PreferencesUI.py:5441 flatcamTools/ToolCutOut.py:219 +#: flatcamGUI/PreferencesUI.py:5780 flatcamTools/ToolCutOut.py:226 msgid "" "Create a convex shape surrounding the entire PCB.\n" "Used only if the source object type is Gerber." @@ -11112,11 +11523,11 @@ msgstr "" "Crea una forma convexa que rodea toda la PCB.\n" "Se usa solo si el tipo de objeto de origen es Gerber." -#: flatcamGUI/PreferencesUI.py:5454 +#: flatcamGUI/PreferencesUI.py:5793 msgid "2Sided Tool Options" msgstr "Opc. de herra. de 2 caras" -#: flatcamGUI/PreferencesUI.py:5460 +#: flatcamGUI/PreferencesUI.py:5799 msgid "" "A tool to help in creating a double sided\n" "PCB using alignment holes." @@ -11124,36 +11535,41 @@ msgstr "" "Una herramienta para ayudar en la creación de una doble cara.\n" "PCB utilizando orificios de alineación." -#: flatcamGUI/PreferencesUI.py:5474 +#: flatcamGUI/PreferencesUI.py:5813 msgid "Drill dia" msgstr "Diá. del taladro" -#: flatcamGUI/PreferencesUI.py:5476 flatcamTools/ToolDblSided.py:274 -#: flatcamTools/ToolDblSided.py:285 +#: flatcamGUI/PreferencesUI.py:5815 flatcamTools/ToolDblSided.py:364 +#: flatcamTools/ToolDblSided.py:369 msgid "Diameter of the drill for the alignment holes." msgstr "Diámetro del taladro para los orificios de alineación." -#: flatcamGUI/PreferencesUI.py:5485 flatcamTools/ToolDblSided.py:146 -msgid "Mirror Axis:" -msgstr "Eje del espejo:" +#: flatcamGUI/PreferencesUI.py:5822 flatcamTools/ToolDblSided.py:378 +msgid "Align Axis" +msgstr "Alinear eje" -#: flatcamGUI/PreferencesUI.py:5487 flatcamTools/ToolDblSided.py:147 +#: flatcamGUI/PreferencesUI.py:5824 flatcamGUI/PreferencesUI.py:5837 +#: flatcamTools/ToolDblSided.py:166 flatcamTools/ToolDblSided.py:380 msgid "Mirror vertically (X) or horizontally (Y)." msgstr "Espejo verticalmente (X) u horizontal (Y)." -#: flatcamGUI/PreferencesUI.py:5496 flatcamTools/ToolDblSided.py:156 +#: flatcamGUI/PreferencesUI.py:5835 +msgid "Mirror Axis:" +msgstr "Eje del espejo:" + +#: flatcamGUI/PreferencesUI.py:5846 flatcamTools/ToolDblSided.py:182 msgid "Point" msgstr "Punto" -#: flatcamGUI/PreferencesUI.py:5497 flatcamTools/ToolDblSided.py:157 +#: flatcamGUI/PreferencesUI.py:5847 flatcamTools/ToolDblSided.py:183 msgid "Box" msgstr "Caja" -#: flatcamGUI/PreferencesUI.py:5498 flatcamTools/ToolDblSided.py:158 +#: flatcamGUI/PreferencesUI.py:5848 msgid "Axis Ref" msgstr "Ref. del eje" -#: flatcamGUI/PreferencesUI.py:5500 flatcamTools/ToolDblSided.py:160 +#: flatcamGUI/PreferencesUI.py:5850 msgid "" "The axis should pass through a point or cut\n" " a specified box (in a FlatCAM object) through \n" @@ -11163,48 +11579,68 @@ msgstr "" "  un cuadro especificado (en un objeto FlatCAM) a través de\n" "El centro." -#: flatcamGUI/PreferencesUI.py:5516 +#: flatcamGUI/PreferencesUI.py:5866 msgid "Paint Tool Options" msgstr "Opc. de herra. de pintura" -#: flatcamGUI/PreferencesUI.py:5522 +#: flatcamGUI/PreferencesUI.py:5872 msgid "Parameters:" msgstr "Parámetros:" -#: flatcamGUI/PreferencesUI.py:5636 flatcamTools/ToolPaint.py:296 -#: flatcamTools/ToolPaint.py:313 +#: flatcamGUI/PreferencesUI.py:6086 flatcamTools/ToolPaint.py:445 msgid "" -"How to select Polygons to be painted.\n" +"If checked, use 'rest machining'.\n" +"Basically it will clear copper outside PCB features,\n" +"using the biggest tool and continue with the next tools,\n" +"from bigger to smaller, to clear areas of copper that\n" +"could not be cleared by previous tool, until there is\n" +"no more copper to clear or there are no more tools.\n" +"\n" +"If not checked, use the standard algorithm." +msgstr "" +"Si está marcado, use 'mecanizado en reposo'.\n" +"Básicamente eliminará el cobre fuera de las características de la PCB,\n" +"utilizando la herramienta más grande y continúe con las siguientes " +"herramientas,\n" +"de mayor a menor, para limpiar áreas de cobre que\n" +"no se pudo borrar con la herramienta anterior, hasta que haya\n" +"no más cobre para limpiar o no hay más herramientas.\n" +"\n" +"Si no está marcado, use el algoritmo estándar." + +#: flatcamGUI/PreferencesUI.py:6099 flatcamTools/ToolPaint.py:458 +msgid "" +"Selection of area to be processed.\n" "- 'Polygon Selection' - left mouse click to add/remove polygons to be " -"painted.\n" +"processed.\n" "- 'Area Selection' - left mouse click to start selection of the area to be " -"painted.\n" +"processed.\n" "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple " "areas.\n" -"- 'All Polygons' - the Paint will start after click.\n" -"- 'Reference Object' - will do non copper clearing within the area\n" -"specified by another object." +"- 'All Polygons' - the process will start after click.\n" +"- 'Reference Object' - will process the area specified by another object." msgstr "" -"Cómo seleccionar polígonos para pintar.\n" +"Selección del área a procesar.\n" "- 'Selección de polígonos': haga clic con el botón izquierdo del mouse para " -"agregar / eliminar polígonos a pintar.\n" +"agregar / eliminar polígonos que se procesarán.\n" "- 'Selección de área': haga clic con el botón izquierdo del mouse para " -"iniciar la selección del área a pintar.\n" +"iniciar la selección del área a procesar.\n" "Mantener presionada una tecla modificadora (CTRL o SHIFT) permitirá agregar " "múltiples áreas.\n" -"- 'Todos los polígonos': la pintura comenzará después de hacer clic.\n" -"- 'Objeto de referencia' - hará una limpieza sin cobre dentro del área\n" -"especificado por otro objeto." +"- 'Todos los polígonos': el proceso comenzará después de hacer clic.\n" +"- 'Objeto de referencia': procesará el área especificada por otro objeto." -#: flatcamGUI/PreferencesUI.py:5645 -msgid "Sel" -msgstr "Seleccionar" +#: flatcamGUI/PreferencesUI.py:6119 flatcamTools/ToolPaint.py:486 +#: flatcamTools/ToolPaint.py:942 flatcamTools/ToolPaint.py:1427 +#: tclCommands/TclCommandPaint.py:164 +msgid "Polygon Selection" +msgstr "Selección de polígono" -#: flatcamGUI/PreferencesUI.py:5656 +#: flatcamGUI/PreferencesUI.py:6144 msgid "Paint Plotting" msgstr "Trazado de pintura" -#: flatcamGUI/PreferencesUI.py:5658 +#: flatcamGUI/PreferencesUI.py:6146 msgid "" "- 'Normal' - normal plotting, done at the end of the Paint job\n" "- 'Progressive' - after each shape is generated it will be plotted." @@ -11212,11 +11648,11 @@ msgstr "" "- 'Normal': trazado normal, realizado al final del trabajo de Pintura\n" "- 'Progresivo': después de generar cada forma, se trazará." -#: flatcamGUI/PreferencesUI.py:5672 +#: flatcamGUI/PreferencesUI.py:6160 msgid "Film Tool Options" msgstr "Opc. de herra. de película" -#: flatcamGUI/PreferencesUI.py:5678 +#: flatcamGUI/PreferencesUI.py:6166 msgid "" "Create a PCB film from a Gerber or Geometry\n" "FlatCAM object.\n" @@ -11226,11 +11662,11 @@ msgstr "" "Objeto FlatCAM.\n" "El archivo se guarda en formato SVG." -#: flatcamGUI/PreferencesUI.py:5689 +#: flatcamGUI/PreferencesUI.py:6177 msgid "Film Type" msgstr "Tipo de Filme" -#: flatcamGUI/PreferencesUI.py:5691 flatcamTools/ToolFilm.py:300 +#: flatcamGUI/PreferencesUI.py:6179 flatcamTools/ToolFilm.py:300 msgid "" "Generate a Positive black film or a Negative film.\n" "Positive means that it will print the features\n" @@ -11246,20 +11682,20 @@ msgstr "" "Con blanco sobre un lienzo negro.\n" "El formato de la película es SVG." -#: flatcamGUI/PreferencesUI.py:5702 +#: flatcamGUI/PreferencesUI.py:6190 msgid "Film Color" msgstr "Color de la película" -#: flatcamGUI/PreferencesUI.py:5704 +#: flatcamGUI/PreferencesUI.py:6192 msgid "Set the film color when positive film is selected." msgstr "" "Establezca el color de la película cuando se selecciona película positiva." -#: flatcamGUI/PreferencesUI.py:5727 flatcamTools/ToolFilm.py:316 +#: flatcamGUI/PreferencesUI.py:6215 flatcamTools/ToolFilm.py:316 msgid "Border" msgstr "Frontera" -#: flatcamGUI/PreferencesUI.py:5729 flatcamTools/ToolFilm.py:318 +#: flatcamGUI/PreferencesUI.py:6217 flatcamTools/ToolFilm.py:318 msgid "" "Specify a border around the object.\n" "Only for negative film.\n" @@ -11279,11 +11715,11 @@ msgstr "" "Color blanco como el resto y que puede confundir con el\n" "Entorno si no fuera por esta frontera." -#: flatcamGUI/PreferencesUI.py:5746 flatcamTools/ToolFilm.py:283 +#: flatcamGUI/PreferencesUI.py:6234 flatcamTools/ToolFilm.py:283 msgid "Scale Stroke" msgstr "Trazo de escala" -#: flatcamGUI/PreferencesUI.py:5748 flatcamTools/ToolFilm.py:285 +#: flatcamGUI/PreferencesUI.py:6236 flatcamTools/ToolFilm.py:285 msgid "" "Scale the line stroke thickness of each feature in the SVG file.\n" "It means that the line that envelope each SVG feature will be thicker or " @@ -11296,11 +11732,11 @@ msgstr "" "por lo tanto, las características finas pueden verse más afectadas por este " "parámetro." -#: flatcamGUI/PreferencesUI.py:5755 flatcamTools/ToolFilm.py:141 +#: flatcamGUI/PreferencesUI.py:6243 flatcamTools/ToolFilm.py:141 msgid "Film Adjustments" msgstr "Ajustes de la película" -#: flatcamGUI/PreferencesUI.py:5757 flatcamTools/ToolFilm.py:143 +#: flatcamGUI/PreferencesUI.py:6245 flatcamTools/ToolFilm.py:143 msgid "" "Sometime the printers will distort the print shape, especially the Laser " "types.\n" @@ -11311,11 +11747,11 @@ msgstr "" "Esta sección proporciona las herramientas para compensar las distorsiones de " "impresión." -#: flatcamGUI/PreferencesUI.py:5764 flatcamTools/ToolFilm.py:150 +#: flatcamGUI/PreferencesUI.py:6252 flatcamTools/ToolFilm.py:150 msgid "Scale Film geometry" msgstr "Escalar la Geo de la Película" -#: flatcamGUI/PreferencesUI.py:5766 flatcamTools/ToolFilm.py:152 +#: flatcamGUI/PreferencesUI.py:6254 flatcamTools/ToolFilm.py:152 msgid "" "A value greater than 1 will stretch the film\n" "while a value less than 1 will jolt it." @@ -11323,21 +11759,21 @@ msgstr "" "Un valor mayor que 1 estirará la película\n" "mientras que un valor menor que 1 lo sacudirá." -#: flatcamGUI/PreferencesUI.py:5776 flatcamGUI/PreferencesUI.py:6296 -#: flatcamTools/ToolFilm.py:162 flatcamTools/ToolTransform.py:148 +#: flatcamGUI/PreferencesUI.py:6264 flatcamGUI/PreferencesUI.py:6783 +#: flatcamTools/ToolFilm.py:162 flatcamTools/ToolTransform.py:149 msgid "X factor" msgstr "Factor X" -#: flatcamGUI/PreferencesUI.py:5785 flatcamGUI/PreferencesUI.py:6309 +#: flatcamGUI/PreferencesUI.py:6273 flatcamGUI/PreferencesUI.py:6796 #: flatcamTools/ToolFilm.py:171 flatcamTools/ToolTransform.py:169 msgid "Y factor" msgstr "Factor Y" -#: flatcamGUI/PreferencesUI.py:5795 flatcamTools/ToolFilm.py:189 +#: flatcamGUI/PreferencesUI.py:6283 flatcamTools/ToolFilm.py:189 msgid "Skew Film geometry" msgstr "Incline la Geo de la Película" -#: flatcamGUI/PreferencesUI.py:5797 flatcamTools/ToolFilm.py:191 +#: flatcamGUI/PreferencesUI.py:6285 flatcamTools/ToolFilm.py:191 msgid "" "Positive values will skew to the right\n" "while negative values will skew to the left." @@ -11345,17 +11781,17 @@ msgstr "" "Los valores positivos se sesgarán a la derecha.\n" "mientras que los valores negativos se desviarán a la izquierda." -#: flatcamGUI/PreferencesUI.py:5807 flatcamGUI/PreferencesUI.py:6265 +#: flatcamGUI/PreferencesUI.py:6295 flatcamGUI/PreferencesUI.py:6752 #: flatcamTools/ToolFilm.py:201 flatcamTools/ToolTransform.py:98 msgid "X angle" msgstr "Ángulo X" -#: flatcamGUI/PreferencesUI.py:5816 flatcamGUI/PreferencesUI.py:6279 -#: flatcamTools/ToolFilm.py:210 flatcamTools/ToolTransform.py:120 +#: flatcamGUI/PreferencesUI.py:6304 flatcamGUI/PreferencesUI.py:6766 +#: flatcamTools/ToolFilm.py:210 flatcamTools/ToolTransform.py:119 msgid "Y angle" msgstr "Ángulo Y" -#: flatcamGUI/PreferencesUI.py:5827 flatcamTools/ToolFilm.py:221 +#: flatcamGUI/PreferencesUI.py:6315 flatcamTools/ToolFilm.py:221 msgid "" "The reference point to be used as origin for the skew.\n" "It can be one of the four points of the geometry bounding box." @@ -11363,57 +11799,53 @@ msgstr "" "El punto de referencia que se utilizará como origen para el sesgo.\n" "Puede ser uno de los cuatro puntos del cuadro delimitador de geometría." -#: flatcamGUI/PreferencesUI.py:5830 flatcamTools/ToolFiducials.py:87 +#: flatcamGUI/PreferencesUI.py:6318 flatcamTools/ToolFiducials.py:87 #: flatcamTools/ToolFilm.py:224 msgid "Bottom Left" msgstr "Abajo a la izquierda" -#: flatcamGUI/PreferencesUI.py:5831 flatcamTools/ToolFilm.py:225 +#: flatcamGUI/PreferencesUI.py:6319 flatcamTools/ToolFilm.py:225 msgid "Top Left" msgstr "Arriba a la izquierda" -#: flatcamGUI/PreferencesUI.py:5832 flatcamTools/ToolFilm.py:226 +#: flatcamGUI/PreferencesUI.py:6320 flatcamTools/ToolFilm.py:226 msgid "Bottom Right" msgstr "Abajo a la derecha" -#: flatcamGUI/PreferencesUI.py:5833 flatcamTools/ToolFilm.py:227 +#: flatcamGUI/PreferencesUI.py:6321 flatcamTools/ToolFilm.py:227 msgid "Top right" msgstr "Arriba a la derecha" -#: flatcamGUI/PreferencesUI.py:5841 flatcamTools/ToolFilm.py:244 +#: flatcamGUI/PreferencesUI.py:6329 flatcamTools/ToolFilm.py:244 msgid "Mirror Film geometry" msgstr "Refleja la Geo de la Película" -#: flatcamGUI/PreferencesUI.py:5843 flatcamTools/ToolFilm.py:246 +#: flatcamGUI/PreferencesUI.py:6331 flatcamTools/ToolFilm.py:246 msgid "Mirror the film geometry on the selected axis or on both." msgstr "Refleje la geometría de la película en el eje seleccionado o en ambos." -#: flatcamGUI/PreferencesUI.py:5855 flatcamTools/ToolFilm.py:258 -msgid "Both" -msgstr "Ambas" - -#: flatcamGUI/PreferencesUI.py:5857 flatcamTools/ToolFilm.py:260 +#: flatcamGUI/PreferencesUI.py:6345 flatcamTools/ToolFilm.py:260 msgid "Mirror axis" msgstr "Eje espejo" -#: flatcamGUI/PreferencesUI.py:5867 flatcamTools/ToolFilm.py:403 +#: flatcamGUI/PreferencesUI.py:6355 flatcamTools/ToolFilm.py:405 msgid "SVG" msgstr "SVG" -#: flatcamGUI/PreferencesUI.py:5868 flatcamTools/ToolFilm.py:404 +#: flatcamGUI/PreferencesUI.py:6356 flatcamTools/ToolFilm.py:406 msgid "PNG" msgstr "PNG" -#: flatcamGUI/PreferencesUI.py:5869 flatcamTools/ToolFilm.py:405 +#: flatcamGUI/PreferencesUI.py:6357 flatcamTools/ToolFilm.py:407 msgid "PDF" msgstr "PDF" -#: flatcamGUI/PreferencesUI.py:5872 flatcamTools/ToolFilm.py:298 -#: flatcamTools/ToolFilm.py:408 +#: flatcamGUI/PreferencesUI.py:6360 flatcamTools/ToolFilm.py:298 +#: flatcamTools/ToolFilm.py:410 msgid "Film Type:" msgstr "Tipo de filme:" -#: flatcamGUI/PreferencesUI.py:5874 flatcamTools/ToolFilm.py:410 +#: flatcamGUI/PreferencesUI.py:6362 flatcamTools/ToolFilm.py:412 msgid "" "The file type of the saved film. Can be:\n" "- 'SVG' -> open-source vectorial format\n" @@ -11425,23 +11857,23 @@ msgstr "" "- 'PNG' -> imagen de trama\n" "- 'PDF' -> formato de documento portátil" -#: flatcamGUI/PreferencesUI.py:5883 flatcamTools/ToolFilm.py:419 +#: flatcamGUI/PreferencesUI.py:6371 flatcamTools/ToolFilm.py:421 msgid "Page Orientation" msgstr "Orient. de la página" -#: flatcamGUI/PreferencesUI.py:5896 flatcamTools/ToolFilm.py:432 +#: flatcamGUI/PreferencesUI.py:6384 flatcamTools/ToolFilm.py:434 msgid "Page Size" msgstr "Tamaño de página" -#: flatcamGUI/PreferencesUI.py:5897 flatcamTools/ToolFilm.py:433 +#: flatcamGUI/PreferencesUI.py:6385 flatcamTools/ToolFilm.py:435 msgid "A selection of standard ISO 216 page sizes." msgstr "Una selección de tamaños de página estándar ISO 216." -#: flatcamGUI/PreferencesUI.py:5969 +#: flatcamGUI/PreferencesUI.py:6457 msgid "Panelize Tool Options" msgstr "Opc. de la herra. Panelizar" -#: flatcamGUI/PreferencesUI.py:5975 +#: flatcamGUI/PreferencesUI.py:6463 msgid "" "Create an object that contains an array of (x, y) elements,\n" "each element is a copy of the source object spaced\n" @@ -11451,11 +11883,11 @@ msgstr "" "Cada elemento es una copia del objeto fuente espaciado.\n" "a una distancia X, distancia Y entre sí." -#: flatcamGUI/PreferencesUI.py:5992 flatcamTools/ToolPanelize.py:160 +#: flatcamGUI/PreferencesUI.py:6480 flatcamTools/ToolPanelize.py:163 msgid "Spacing cols" msgstr "Col. de espaciado" -#: flatcamGUI/PreferencesUI.py:5994 flatcamTools/ToolPanelize.py:162 +#: flatcamGUI/PreferencesUI.py:6482 flatcamTools/ToolPanelize.py:165 msgid "" "Spacing between columns of the desired panel.\n" "In current units." @@ -11463,11 +11895,11 @@ msgstr "" "Espaciado entre columnas del panel deseado.\n" "En unidades actuales." -#: flatcamGUI/PreferencesUI.py:6006 flatcamTools/ToolPanelize.py:172 +#: flatcamGUI/PreferencesUI.py:6494 flatcamTools/ToolPanelize.py:175 msgid "Spacing rows" msgstr "Separación de filas" -#: flatcamGUI/PreferencesUI.py:6008 flatcamTools/ToolPanelize.py:174 +#: flatcamGUI/PreferencesUI.py:6496 flatcamTools/ToolPanelize.py:177 msgid "" "Spacing between rows of the desired panel.\n" "In current units." @@ -11475,36 +11907,31 @@ msgstr "" "Espaciado entre filas del panel deseado.\n" "En unidades actuales." -#: flatcamGUI/PreferencesUI.py:6019 flatcamTools/ToolPanelize.py:183 +#: flatcamGUI/PreferencesUI.py:6507 flatcamTools/ToolPanelize.py:186 msgid "Columns" msgstr "Columnas" -#: flatcamGUI/PreferencesUI.py:6021 flatcamTools/ToolPanelize.py:185 +#: flatcamGUI/PreferencesUI.py:6509 flatcamTools/ToolPanelize.py:188 msgid "Number of columns of the desired panel" msgstr "Número de columnas del panel deseado" -#: flatcamGUI/PreferencesUI.py:6031 flatcamTools/ToolPanelize.py:193 +#: flatcamGUI/PreferencesUI.py:6519 flatcamTools/ToolPanelize.py:196 msgid "Rows" msgstr "Filas" -#: flatcamGUI/PreferencesUI.py:6033 flatcamTools/ToolPanelize.py:195 +#: flatcamGUI/PreferencesUI.py:6521 flatcamTools/ToolPanelize.py:198 msgid "Number of rows of the desired panel" msgstr "Número de filas del panel deseado" -#: flatcamGUI/PreferencesUI.py:6039 flatcamTools/ToolCalibration.py:196 -#: flatcamTools/ToolCalibration.py:634 flatcamTools/ToolPanelize.py:201 -msgid "Gerber" -msgstr "Gerber" - -#: flatcamGUI/PreferencesUI.py:6040 flatcamTools/ToolPanelize.py:202 +#: flatcamGUI/PreferencesUI.py:6528 flatcamTools/ToolPanelize.py:205 msgid "Geo" msgstr "Geo" -#: flatcamGUI/PreferencesUI.py:6041 flatcamTools/ToolPanelize.py:203 +#: flatcamGUI/PreferencesUI.py:6529 flatcamTools/ToolPanelize.py:206 msgid "Panel Type" msgstr "Tipo de panel" -#: flatcamGUI/PreferencesUI.py:6043 +#: flatcamGUI/PreferencesUI.py:6531 msgid "" "Choose the type of object for the panel object:\n" "- Gerber\n" @@ -11514,11 +11941,11 @@ msgstr "" "- Gerber\n" "- Geometría" -#: flatcamGUI/PreferencesUI.py:6052 +#: flatcamGUI/PreferencesUI.py:6540 msgid "Constrain within" msgstr "Restringir dentro de" -#: flatcamGUI/PreferencesUI.py:6054 flatcamTools/ToolPanelize.py:215 +#: flatcamGUI/PreferencesUI.py:6542 flatcamTools/ToolPanelize.py:218 msgid "" "Area define by DX and DY within to constrain the panel.\n" "DX and DY values are in current units.\n" @@ -11532,11 +11959,11 @@ msgstr "" "El panel final tendrá tantas columnas y filas como\n" "encajan completamente dentro del área seleccionada." -#: flatcamGUI/PreferencesUI.py:6067 flatcamTools/ToolPanelize.py:227 +#: flatcamGUI/PreferencesUI.py:6555 flatcamTools/ToolPanelize.py:230 msgid "Width (DX)" msgstr "Ancho (DX)" -#: flatcamGUI/PreferencesUI.py:6069 flatcamTools/ToolPanelize.py:229 +#: flatcamGUI/PreferencesUI.py:6557 flatcamTools/ToolPanelize.py:232 msgid "" "The width (DX) within which the panel must fit.\n" "In current units." @@ -11544,11 +11971,11 @@ msgstr "" "El ancho (DX) dentro del cual debe caber el panel.\n" "En unidades actuales." -#: flatcamGUI/PreferencesUI.py:6080 flatcamTools/ToolPanelize.py:238 +#: flatcamGUI/PreferencesUI.py:6568 flatcamTools/ToolPanelize.py:241 msgid "Height (DY)" msgstr "Altura (DY)" -#: flatcamGUI/PreferencesUI.py:6082 flatcamTools/ToolPanelize.py:240 +#: flatcamGUI/PreferencesUI.py:6570 flatcamTools/ToolPanelize.py:243 msgid "" "The height (DY)within which the panel must fit.\n" "In current units." @@ -11556,15 +11983,15 @@ msgstr "" "La altura (DY) dentro de la cual debe caber el panel.\n" "En unidades actuales." -#: flatcamGUI/PreferencesUI.py:6096 +#: flatcamGUI/PreferencesUI.py:6584 msgid "Calculators Tool Options" msgstr "Opc. de herra. de calculadoras" -#: flatcamGUI/PreferencesUI.py:6100 flatcamTools/ToolCalculators.py:25 +#: flatcamGUI/PreferencesUI.py:6588 flatcamTools/ToolCalculators.py:25 msgid "V-Shape Tool Calculator" msgstr "Calc. de herra. en forma de V" -#: flatcamGUI/PreferencesUI.py:6102 +#: flatcamGUI/PreferencesUI.py:6590 msgid "" "Calculate the tool diameter for a given V-shape tool,\n" "having the tip diameter, tip angle and\n" @@ -11575,11 +12002,11 @@ msgstr "" "teniendo el diámetro de la punta, el ángulo de la punta y\n" "Profundidad de corte como parámetros." -#: flatcamGUI/PreferencesUI.py:6117 flatcamTools/ToolCalculators.py:94 +#: flatcamGUI/PreferencesUI.py:6607 flatcamTools/ToolCalculators.py:94 msgid "Tip Diameter" msgstr "Diá. de la punta" -#: flatcamGUI/PreferencesUI.py:6119 flatcamTools/ToolCalculators.py:102 +#: flatcamGUI/PreferencesUI.py:6609 flatcamTools/ToolCalculators.py:102 msgid "" "This is the tool tip diameter.\n" "It is specified by manufacturer." @@ -11587,11 +12014,11 @@ msgstr "" "Este es el diámetro de la punta de la herramienta.\n" "Está especificado por el fabricante." -#: flatcamGUI/PreferencesUI.py:6131 flatcamTools/ToolCalculators.py:105 +#: flatcamGUI/PreferencesUI.py:6621 flatcamTools/ToolCalculators.py:105 msgid "Tip Angle" msgstr "Ángulo de la punta" -#: flatcamGUI/PreferencesUI.py:6133 +#: flatcamGUI/PreferencesUI.py:6623 msgid "" "This is the angle on the tip of the tool.\n" "It is specified by manufacturer." @@ -11599,7 +12026,7 @@ msgstr "" "Este es el ángulo en la punta de la herramienta.\n" "Está especificado por el fabricante." -#: flatcamGUI/PreferencesUI.py:6147 +#: flatcamGUI/PreferencesUI.py:6637 msgid "" "This is depth to cut into material.\n" "In the CNCJob object it is the CutZ parameter." @@ -11607,11 +12034,11 @@ msgstr "" "Esta es la profundidad para cortar en material.\n" "En el objeto de trabajo CNC es el parámetro CutZ." -#: flatcamGUI/PreferencesUI.py:6154 flatcamTools/ToolCalculators.py:27 +#: flatcamGUI/PreferencesUI.py:6644 flatcamTools/ToolCalculators.py:27 msgid "ElectroPlating Calculator" msgstr "Calculadora de electrochapado" -#: flatcamGUI/PreferencesUI.py:6156 flatcamTools/ToolCalculators.py:158 +#: flatcamGUI/PreferencesUI.py:6646 flatcamTools/ToolCalculators.py:158 msgid "" "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 " @@ -11622,27 +12049,27 @@ msgstr "" "Utilizando un método como tinta de grahite o tinta de hipofosfito de calcio " "o cloruro de paladio." -#: flatcamGUI/PreferencesUI.py:6170 flatcamTools/ToolCalculators.py:167 +#: flatcamGUI/PreferencesUI.py:6657 flatcamTools/ToolCalculators.py:167 msgid "Board Length" msgstr "Longitud del tablero" -#: flatcamGUI/PreferencesUI.py:6172 flatcamTools/ToolCalculators.py:173 +#: flatcamGUI/PreferencesUI.py:6659 flatcamTools/ToolCalculators.py:173 msgid "This is the board length. In centimeters." msgstr "Esta es la longitud del tablero. En centímetros." -#: flatcamGUI/PreferencesUI.py:6182 flatcamTools/ToolCalculators.py:175 +#: flatcamGUI/PreferencesUI.py:6669 flatcamTools/ToolCalculators.py:175 msgid "Board Width" msgstr "Ancho del tablero" -#: flatcamGUI/PreferencesUI.py:6184 flatcamTools/ToolCalculators.py:181 +#: flatcamGUI/PreferencesUI.py:6671 flatcamTools/ToolCalculators.py:181 msgid "This is the board width.In centimeters." msgstr "Este es el ancho de la tabla. En centímetros." -#: flatcamGUI/PreferencesUI.py:6189 flatcamTools/ToolCalculators.py:183 +#: flatcamGUI/PreferencesUI.py:6676 flatcamTools/ToolCalculators.py:183 msgid "Current Density" msgstr "Densidad actual" -#: flatcamGUI/PreferencesUI.py:6195 flatcamTools/ToolCalculators.py:190 +#: flatcamGUI/PreferencesUI.py:6682 flatcamTools/ToolCalculators.py:190 msgid "" "Current density to pass through the board. \n" "In Amps per Square Feet ASF." @@ -11650,11 +12077,11 @@ msgstr "" "Densidad de corriente para pasar por el tablero.\n" "En amperios por pies cuadrados ASF." -#: flatcamGUI/PreferencesUI.py:6201 flatcamTools/ToolCalculators.py:193 +#: flatcamGUI/PreferencesUI.py:6688 flatcamTools/ToolCalculators.py:193 msgid "Copper Growth" msgstr "Crecimiento de cobre" -#: flatcamGUI/PreferencesUI.py:6207 flatcamTools/ToolCalculators.py:200 +#: flatcamGUI/PreferencesUI.py:6694 flatcamTools/ToolCalculators.py:200 msgid "" "How thick the copper growth is intended to be.\n" "In microns." @@ -11662,11 +12089,11 @@ msgstr "" "Qué tan grueso pretende ser el crecimiento del cobre.\n" "En micras." -#: flatcamGUI/PreferencesUI.py:6220 +#: flatcamGUI/PreferencesUI.py:6707 msgid "Transform Tool Options" msgstr "Opc. de herra. de transformación" -#: flatcamGUI/PreferencesUI.py:6226 +#: flatcamGUI/PreferencesUI.py:6713 msgid "" "Various transformations that can be applied\n" "on a FlatCAM object." @@ -11674,19 +12101,19 @@ msgstr "" "Diversas transformaciones que se pueden aplicar.\n" "en un objeto FlatCAM." -#: flatcamGUI/PreferencesUI.py:6257 +#: flatcamGUI/PreferencesUI.py:6744 msgid "Skew" msgstr "Sesgar" -#: flatcamGUI/PreferencesUI.py:6298 flatcamTools/ToolTransform.py:150 +#: flatcamGUI/PreferencesUI.py:6785 flatcamTools/ToolTransform.py:151 msgid "Factor for scaling on X axis." msgstr "Factor de escalado en eje X." -#: flatcamGUI/PreferencesUI.py:6311 flatcamTools/ToolTransform.py:171 +#: flatcamGUI/PreferencesUI.py:6798 flatcamTools/ToolTransform.py:171 msgid "Factor for scaling on Y axis." msgstr "Factor de escalado en eje Y." -#: flatcamGUI/PreferencesUI.py:6319 flatcamTools/ToolTransform.py:194 +#: flatcamGUI/PreferencesUI.py:6806 flatcamTools/ToolTransform.py:192 msgid "" "Scale the selected object(s)\n" "using the Scale_X factor for both axis." @@ -11694,7 +12121,7 @@ msgstr "" "Escala el (los) objeto (s) seleccionado (s)\n" "utilizando el factor de escala X para ambos ejes." -#: flatcamGUI/PreferencesUI.py:6327 flatcamTools/ToolTransform.py:202 +#: flatcamGUI/PreferencesUI.py:6814 flatcamTools/ToolTransform.py:199 msgid "" "Scale the selected object(s)\n" "using the origin reference when checked,\n" @@ -11706,32 +12133,32 @@ msgstr "" "y el centro del cuadro delimitador más grande.\n" "de los objetos seleccionados cuando no está marcada." -#: flatcamGUI/PreferencesUI.py:6343 flatcamTools/ToolTransform.py:217 +#: flatcamGUI/PreferencesUI.py:6830 flatcamTools/ToolTransform.py:218 msgid "X val" msgstr "Valor X" -#: flatcamGUI/PreferencesUI.py:6345 flatcamTools/ToolTransform.py:219 +#: flatcamGUI/PreferencesUI.py:6832 flatcamTools/ToolTransform.py:220 msgid "Distance to offset on X axis. In current units." msgstr "Distancia a desplazamiento en el eje X. En unidades actuales." -#: flatcamGUI/PreferencesUI.py:6356 flatcamTools/ToolTransform.py:238 +#: flatcamGUI/PreferencesUI.py:6843 flatcamTools/ToolTransform.py:238 msgid "Y val" msgstr "Valor Y" -#: flatcamGUI/PreferencesUI.py:6358 flatcamTools/ToolTransform.py:240 +#: flatcamGUI/PreferencesUI.py:6845 flatcamTools/ToolTransform.py:240 msgid "Distance to offset on Y axis. In current units." msgstr "Distancia a desplazamiento en el eje Y. En unidades actuales." -#: flatcamGUI/PreferencesUI.py:6364 flatcamTools/ToolDblSided.py:62 -#: flatcamTools/ToolDblSided.py:90 flatcamTools/ToolDblSided.py:120 +#: flatcamGUI/PreferencesUI.py:6851 flatcamTools/ToolDblSided.py:68 +#: flatcamTools/ToolDblSided.py:96 flatcamTools/ToolDblSided.py:126 msgid "Mirror" msgstr "Espejo" -#: flatcamGUI/PreferencesUI.py:6368 flatcamTools/ToolTransform.py:285 +#: flatcamGUI/PreferencesUI.py:6855 flatcamTools/ToolTransform.py:284 msgid "Mirror Reference" msgstr "Espejo de referencia" -#: flatcamGUI/PreferencesUI.py:6370 flatcamTools/ToolTransform.py:287 +#: flatcamGUI/PreferencesUI.py:6857 flatcamTools/ToolTransform.py:286 msgid "" "Flip the selected object(s)\n" "around the point in Point Entry Field.\n" @@ -11753,11 +12180,11 @@ msgstr "" "O ingrese las coords en formato (x, y) en el\n" "Campo de entrada de puntos y haga clic en Girar en X (Y)" -#: flatcamGUI/PreferencesUI.py:6381 +#: flatcamGUI/PreferencesUI.py:6868 msgid "Mirror Reference point" msgstr "Punto de Ref del Espejo" -#: flatcamGUI/PreferencesUI.py:6383 +#: flatcamGUI/PreferencesUI.py:6870 msgid "" "Coordinates in format (x, y) used as reference for mirroring.\n" "The 'x' in (x, y) will be used when using Flip on X and\n" @@ -11768,12 +12195,12 @@ msgstr "" "La 'x' en (x, y) se usará cuando se use voltear en X y\n" "la 'y' en (x, y) se usará cuando se use voltear en Y y" -#: flatcamGUI/PreferencesUI.py:6396 flatcamTools/ToolDistance.py:355 -#: flatcamTools/ToolDistanceMin.py:284 flatcamTools/ToolTransform.py:332 +#: flatcamGUI/PreferencesUI.py:6883 flatcamTools/ToolDistance.py:496 +#: flatcamTools/ToolDistanceMin.py:287 flatcamTools/ToolTransform.py:333 msgid "Distance" msgstr "Distancia" -#: flatcamGUI/PreferencesUI.py:6398 flatcamTools/ToolTransform.py:334 +#: flatcamGUI/PreferencesUI.py:6885 flatcamTools/ToolTransform.py:335 msgid "" "A positive value will create the effect of dilation,\n" "while a negative value will create the effect of erosion.\n" @@ -11785,12 +12212,26 @@ msgstr "" "Cada elemento de geometría del objeto se incrementará\n" "o disminuido con la 'distancia'." -#: flatcamGUI/PreferencesUI.py:6414 flatcamGUI/PreferencesUI.py:7057 -#: flatcamTools/ToolQRCode.py:197 flatcamTools/ToolTransform.py:361 +#: flatcamGUI/PreferencesUI.py:6902 flatcamTools/ToolTransform.py:360 +msgid "" +"A positive value will create the effect of dilation,\n" +"while a negative value will create the effect of erosion.\n" +"Each geometry element of the object will be increased\n" +"or decreased to fit the 'Value'. Value is a percentage\n" +"of the initial dimension." +msgstr "" +"Un valor positivo creará el efecto de dilatación,\n" +"mientras que un valor negativo creará el efecto de la erosión.\n" +"Cada elemento de geometría del objeto se incrementará\n" +"o disminuido para ajustarse al 'Valor'. El Valor es un porcentaje\n" +"de la dimensión inicial." + +#: flatcamGUI/PreferencesUI.py:6919 flatcamGUI/PreferencesUI.py:7563 +#: flatcamTools/ToolQRCode.py:197 flatcamTools/ToolTransform.py:384 msgid "Rounded" msgstr "Redondeado" -#: flatcamGUI/PreferencesUI.py:6416 flatcamTools/ToolTransform.py:363 +#: flatcamGUI/PreferencesUI.py:6921 flatcamTools/ToolTransform.py:386 msgid "" "If checked then the buffer will surround the buffered shape,\n" "every corner will be rounded.\n" @@ -11802,11 +12243,11 @@ msgstr "" "Si no está marcado, el búfer seguirá la geometría exacta\n" "de la forma amortiguada." -#: flatcamGUI/PreferencesUI.py:6434 +#: flatcamGUI/PreferencesUI.py:6938 msgid "SolderPaste Tool Options" msgstr "Opc de Herram. de Pasta" -#: flatcamGUI/PreferencesUI.py:6440 +#: flatcamGUI/PreferencesUI.py:6944 msgid "" "A tool to create GCode for dispensing\n" "solder paste onto a PCB." @@ -11814,49 +12255,45 @@ msgstr "" "Una herramienta para crear GCode para dispensar\n" "pasta de soldadura en una PCB." -#: flatcamGUI/PreferencesUI.py:6451 -msgid "Diameters of nozzle tools, separated by ','" -msgstr "Diámetros de las herramientas de boquilla, separadas por ','" - -#: flatcamGUI/PreferencesUI.py:6459 +#: flatcamGUI/PreferencesUI.py:6965 msgid "New Nozzle Dia" msgstr "Nuevo diá de boquilla" -#: flatcamGUI/PreferencesUI.py:6461 flatcamTools/ToolSolderPaste.py:106 +#: flatcamGUI/PreferencesUI.py:6967 flatcamTools/ToolSolderPaste.py:108 msgid "Diameter for the new Nozzle tool to add in the Tool Table" msgstr "" "Diámetro para la nueva herramienta de boquillas para agregar en la tabla de " "herramientas" -#: flatcamGUI/PreferencesUI.py:6477 flatcamTools/ToolSolderPaste.py:182 +#: flatcamGUI/PreferencesUI.py:6983 flatcamTools/ToolSolderPaste.py:184 msgid "Z Dispense Start" msgstr "Inicio de dispen. Z" -#: flatcamGUI/PreferencesUI.py:6479 flatcamTools/ToolSolderPaste.py:184 +#: flatcamGUI/PreferencesUI.py:6985 flatcamTools/ToolSolderPaste.py:186 msgid "The height (Z) when solder paste dispensing starts." msgstr "La altura (Z) cuando comienza la dispensación de pasta de soldadura." -#: flatcamGUI/PreferencesUI.py:6490 flatcamTools/ToolSolderPaste.py:194 +#: flatcamGUI/PreferencesUI.py:6996 flatcamTools/ToolSolderPaste.py:196 msgid "Z Dispense" msgstr "Dispensación Z" -#: flatcamGUI/PreferencesUI.py:6492 flatcamTools/ToolSolderPaste.py:196 +#: flatcamGUI/PreferencesUI.py:6998 flatcamTools/ToolSolderPaste.py:198 msgid "The height (Z) when doing solder paste dispensing." msgstr "La altura (Z) al dispensar pasta de soldadura." -#: flatcamGUI/PreferencesUI.py:6503 flatcamTools/ToolSolderPaste.py:206 +#: flatcamGUI/PreferencesUI.py:7009 flatcamTools/ToolSolderPaste.py:208 msgid "Z Dispense Stop" msgstr "Parada de dispen. Z" -#: flatcamGUI/PreferencesUI.py:6505 flatcamTools/ToolSolderPaste.py:208 +#: flatcamGUI/PreferencesUI.py:7011 flatcamTools/ToolSolderPaste.py:210 msgid "The height (Z) when solder paste dispensing stops." msgstr "La altura (Z) cuando se detiene la dispensación de pasta de soldadura." -#: flatcamGUI/PreferencesUI.py:6516 flatcamTools/ToolSolderPaste.py:218 +#: flatcamGUI/PreferencesUI.py:7022 flatcamTools/ToolSolderPaste.py:220 msgid "Z Travel" msgstr "Viajar Z" -#: flatcamGUI/PreferencesUI.py:6518 flatcamTools/ToolSolderPaste.py:220 +#: flatcamGUI/PreferencesUI.py:7024 flatcamTools/ToolSolderPaste.py:222 msgid "" "The height (Z) for travel between pads\n" "(without dispensing solder paste)." @@ -11864,15 +12301,15 @@ msgstr "" "La altura (Z) para viajar entre almohadillas\n" "(sin dispensar pasta de soldadura)." -#: flatcamGUI/PreferencesUI.py:6530 flatcamTools/ToolSolderPaste.py:231 +#: flatcamGUI/PreferencesUI.py:7036 flatcamTools/ToolSolderPaste.py:233 msgid "Z Toolchange" msgstr "Cambio de herra. Z" -#: flatcamGUI/PreferencesUI.py:6532 flatcamTools/ToolSolderPaste.py:233 +#: flatcamGUI/PreferencesUI.py:7038 flatcamTools/ToolSolderPaste.py:235 msgid "The height (Z) for tool (nozzle) change." msgstr "La altura (Z) para el cambio de herramienta (boquilla)." -#: flatcamGUI/PreferencesUI.py:6541 flatcamTools/ToolSolderPaste.py:241 +#: flatcamGUI/PreferencesUI.py:7047 flatcamTools/ToolSolderPaste.py:243 msgid "" "The X,Y location for tool (nozzle) change.\n" "The format is (x, y) where x and y are real numbers." @@ -11880,11 +12317,11 @@ msgstr "" "La ubicación X, Y para el cambio de herramienta (boquilla).\n" "El formato es (x, y) donde x e y son números reales." -#: flatcamGUI/PreferencesUI.py:6555 flatcamTools/ToolSolderPaste.py:254 +#: flatcamGUI/PreferencesUI.py:7061 flatcamTools/ToolSolderPaste.py:256 msgid "Feedrate (speed) while moving on the X-Y plane." msgstr "Avance (velocidad) mientras se mueve en el plano X-Y." -#: flatcamGUI/PreferencesUI.py:6568 flatcamTools/ToolSolderPaste.py:266 +#: flatcamGUI/PreferencesUI.py:7074 flatcamTools/ToolSolderPaste.py:268 msgid "" "Feedrate (speed) while moving vertically\n" "(on Z plane)." @@ -11892,11 +12329,11 @@ msgstr "" "Avance (velocidad) mientras se mueve verticalmente\n" "(en el plano Z)." -#: flatcamGUI/PreferencesUI.py:6580 flatcamTools/ToolSolderPaste.py:277 +#: flatcamGUI/PreferencesUI.py:7086 flatcamTools/ToolSolderPaste.py:279 msgid "Feedrate Z Dispense" msgstr "Avance de Dispens. Z" -#: flatcamGUI/PreferencesUI.py:6582 +#: flatcamGUI/PreferencesUI.py:7088 msgid "" "Feedrate (speed) while moving up vertically\n" "to Dispense position (on Z plane)." @@ -11904,11 +12341,11 @@ msgstr "" "Avance (velocidad) mientras se mueve verticalmente\n" "para dispensar la posición (en el plano Z)." -#: flatcamGUI/PreferencesUI.py:6593 flatcamTools/ToolSolderPaste.py:289 +#: flatcamGUI/PreferencesUI.py:7099 flatcamTools/ToolSolderPaste.py:291 msgid "Spindle Speed FWD" msgstr "Veloc. del husillo FWD" -#: flatcamGUI/PreferencesUI.py:6595 flatcamTools/ToolSolderPaste.py:291 +#: flatcamGUI/PreferencesUI.py:7101 flatcamTools/ToolSolderPaste.py:293 msgid "" "The dispenser speed while pushing solder paste\n" "through the dispenser nozzle." @@ -11916,19 +12353,19 @@ msgstr "" "La velocidad del dispensador mientras empuja la pasta de soldadura\n" "a través de la boquilla dispensadora." -#: flatcamGUI/PreferencesUI.py:6607 flatcamTools/ToolSolderPaste.py:302 +#: flatcamGUI/PreferencesUI.py:7113 flatcamTools/ToolSolderPaste.py:304 msgid "Dwell FWD" msgstr "Morar FWD" -#: flatcamGUI/PreferencesUI.py:6609 flatcamTools/ToolSolderPaste.py:304 +#: flatcamGUI/PreferencesUI.py:7115 flatcamTools/ToolSolderPaste.py:306 msgid "Pause after solder dispensing." msgstr "Pausa después de la dispensación de soldadura." -#: flatcamGUI/PreferencesUI.py:6619 flatcamTools/ToolSolderPaste.py:313 +#: flatcamGUI/PreferencesUI.py:7125 flatcamTools/ToolSolderPaste.py:315 msgid "Spindle Speed REV" msgstr "Veloc. del husillo REV" -#: flatcamGUI/PreferencesUI.py:6621 flatcamTools/ToolSolderPaste.py:315 +#: flatcamGUI/PreferencesUI.py:7127 flatcamTools/ToolSolderPaste.py:317 msgid "" "The dispenser speed while retracting solder paste\n" "through the dispenser nozzle." @@ -11936,11 +12373,11 @@ msgstr "" "La velocidad del dispensador mientras se retrae la pasta de soldadura\n" "a través de la boquilla dispensadora." -#: flatcamGUI/PreferencesUI.py:6633 flatcamTools/ToolSolderPaste.py:326 +#: flatcamGUI/PreferencesUI.py:7139 flatcamTools/ToolSolderPaste.py:328 msgid "Dwell REV" msgstr "Morar REV" -#: flatcamGUI/PreferencesUI.py:6635 flatcamTools/ToolSolderPaste.py:328 +#: flatcamGUI/PreferencesUI.py:7141 flatcamTools/ToolSolderPaste.py:330 msgid "" "Pause after solder paste dispenser retracted,\n" "to allow pressure equilibrium." @@ -11948,15 +12385,15 @@ msgstr "" "Pausa después de que el dispensador de pasta de soldadura se retraiga,\n" "para permitir el equilibrio de presión." -#: flatcamGUI/PreferencesUI.py:6644 flatcamTools/ToolSolderPaste.py:336 +#: flatcamGUI/PreferencesUI.py:7150 flatcamTools/ToolSolderPaste.py:338 msgid "Files that control the GCode generation." msgstr "Archivos que controlan la generación de GCode." -#: flatcamGUI/PreferencesUI.py:6659 +#: flatcamGUI/PreferencesUI.py:7165 msgid "Substractor Tool Options" msgstr "Opc. de herra. de substractor" -#: flatcamGUI/PreferencesUI.py:6665 +#: flatcamGUI/PreferencesUI.py:7171 msgid "" "A tool to substract one Gerber or Geometry object\n" "from another of the same type." @@ -11964,21 +12401,21 @@ msgstr "" "Una herramienta para restar un objeto Gerber o Geometry\n" "de otro del mismo tipo." -#: flatcamGUI/PreferencesUI.py:6670 flatcamTools/ToolSub.py:149 +#: flatcamGUI/PreferencesUI.py:7176 flatcamTools/ToolSub.py:155 msgid "Close paths" msgstr "Caminos cercanos" -#: flatcamGUI/PreferencesUI.py:6671 +#: flatcamGUI/PreferencesUI.py:7177 msgid "" "Checking this will close the paths cut by the Geometry substractor object." msgstr "" "Marcar esto cerrará los caminos cortados por el objeto sustrato Geometry." -#: flatcamGUI/PreferencesUI.py:6682 +#: flatcamGUI/PreferencesUI.py:7188 msgid "Check Rules Tool Options" msgstr "Opciones de la Herram. Verifique Reglas" -#: flatcamGUI/PreferencesUI.py:6687 +#: flatcamGUI/PreferencesUI.py:7193 msgid "" "A tool to check if Gerber files are within a set\n" "of Manufacturing Rules." @@ -11987,38 +12424,38 @@ msgstr "" "conjunto\n" "de las normas de fabricación." -#: flatcamGUI/PreferencesUI.py:6697 flatcamTools/ToolRulesCheck.py:256 -#: flatcamTools/ToolRulesCheck.py:920 +#: flatcamGUI/PreferencesUI.py:7203 flatcamTools/ToolRulesCheck.py:265 +#: flatcamTools/ToolRulesCheck.py:929 msgid "Trace Size" msgstr "Tamaño de traza" -#: flatcamGUI/PreferencesUI.py:6699 flatcamTools/ToolRulesCheck.py:258 +#: flatcamGUI/PreferencesUI.py:7205 flatcamTools/ToolRulesCheck.py:267 msgid "This checks if the minimum size for traces is met." msgstr "Esto comprueba si se cumple el tamaño mínimo para las trazas." -#: flatcamGUI/PreferencesUI.py:6709 flatcamGUI/PreferencesUI.py:6729 -#: flatcamGUI/PreferencesUI.py:6749 flatcamGUI/PreferencesUI.py:6769 -#: flatcamGUI/PreferencesUI.py:6789 flatcamGUI/PreferencesUI.py:6809 -#: flatcamGUI/PreferencesUI.py:6829 flatcamGUI/PreferencesUI.py:6849 -#: flatcamGUI/PreferencesUI.py:6871 flatcamGUI/PreferencesUI.py:6891 -#: flatcamTools/ToolRulesCheck.py:268 flatcamTools/ToolRulesCheck.py:290 -#: flatcamTools/ToolRulesCheck.py:313 flatcamTools/ToolRulesCheck.py:336 -#: flatcamTools/ToolRulesCheck.py:359 flatcamTools/ToolRulesCheck.py:382 -#: flatcamTools/ToolRulesCheck.py:405 flatcamTools/ToolRulesCheck.py:428 -#: flatcamTools/ToolRulesCheck.py:453 flatcamTools/ToolRulesCheck.py:476 +#: flatcamGUI/PreferencesUI.py:7215 flatcamGUI/PreferencesUI.py:7235 +#: flatcamGUI/PreferencesUI.py:7255 flatcamGUI/PreferencesUI.py:7275 +#: flatcamGUI/PreferencesUI.py:7295 flatcamGUI/PreferencesUI.py:7315 +#: flatcamGUI/PreferencesUI.py:7335 flatcamGUI/PreferencesUI.py:7355 +#: flatcamGUI/PreferencesUI.py:7377 flatcamGUI/PreferencesUI.py:7397 +#: flatcamTools/ToolRulesCheck.py:277 flatcamTools/ToolRulesCheck.py:299 +#: flatcamTools/ToolRulesCheck.py:322 flatcamTools/ToolRulesCheck.py:345 +#: flatcamTools/ToolRulesCheck.py:368 flatcamTools/ToolRulesCheck.py:391 +#: flatcamTools/ToolRulesCheck.py:414 flatcamTools/ToolRulesCheck.py:437 +#: flatcamTools/ToolRulesCheck.py:462 flatcamTools/ToolRulesCheck.py:485 msgid "Min value" msgstr "Valor mínimo" -#: flatcamGUI/PreferencesUI.py:6711 flatcamTools/ToolRulesCheck.py:270 +#: flatcamGUI/PreferencesUI.py:7217 flatcamTools/ToolRulesCheck.py:279 msgid "Minimum acceptable trace size." msgstr "Tamaño de traza mínimo aceptable." -#: flatcamGUI/PreferencesUI.py:6716 flatcamTools/ToolRulesCheck.py:277 -#: flatcamTools/ToolRulesCheck.py:1148 flatcamTools/ToolRulesCheck.py:1178 +#: flatcamGUI/PreferencesUI.py:7222 flatcamTools/ToolRulesCheck.py:286 +#: flatcamTools/ToolRulesCheck.py:1157 flatcamTools/ToolRulesCheck.py:1187 msgid "Copper to Copper clearance" msgstr "Distancia de Cobre a Cobre" -#: flatcamGUI/PreferencesUI.py:6718 flatcamTools/ToolRulesCheck.py:279 +#: flatcamGUI/PreferencesUI.py:7224 flatcamTools/ToolRulesCheck.py:288 msgid "" "This checks if the minimum clearance between copper\n" "features is met." @@ -12026,23 +12463,23 @@ msgstr "" "Esto comprueba si la distancia mínima entre cobre\n" "huellas se cumplen." -#: flatcamGUI/PreferencesUI.py:6731 flatcamGUI/PreferencesUI.py:6751 -#: flatcamGUI/PreferencesUI.py:6771 flatcamGUI/PreferencesUI.py:6791 -#: flatcamGUI/PreferencesUI.py:6811 flatcamGUI/PreferencesUI.py:6831 -#: flatcamGUI/PreferencesUI.py:6893 flatcamTools/ToolRulesCheck.py:292 -#: flatcamTools/ToolRulesCheck.py:315 flatcamTools/ToolRulesCheck.py:338 -#: flatcamTools/ToolRulesCheck.py:361 flatcamTools/ToolRulesCheck.py:384 -#: flatcamTools/ToolRulesCheck.py:407 flatcamTools/ToolRulesCheck.py:455 +#: flatcamGUI/PreferencesUI.py:7237 flatcamGUI/PreferencesUI.py:7257 +#: flatcamGUI/PreferencesUI.py:7277 flatcamGUI/PreferencesUI.py:7297 +#: flatcamGUI/PreferencesUI.py:7317 flatcamGUI/PreferencesUI.py:7337 +#: flatcamGUI/PreferencesUI.py:7399 flatcamTools/ToolRulesCheck.py:301 +#: flatcamTools/ToolRulesCheck.py:324 flatcamTools/ToolRulesCheck.py:347 +#: flatcamTools/ToolRulesCheck.py:370 flatcamTools/ToolRulesCheck.py:393 +#: flatcamTools/ToolRulesCheck.py:416 flatcamTools/ToolRulesCheck.py:464 msgid "Minimum acceptable clearance value." msgstr "Valor mínimo de distancia aceptable." -#: flatcamGUI/PreferencesUI.py:6736 flatcamTools/ToolRulesCheck.py:300 -#: flatcamTools/ToolRulesCheck.py:1208 flatcamTools/ToolRulesCheck.py:1214 -#: flatcamTools/ToolRulesCheck.py:1227 flatcamTools/ToolRulesCheck.py:1234 +#: flatcamGUI/PreferencesUI.py:7242 flatcamTools/ToolRulesCheck.py:309 +#: flatcamTools/ToolRulesCheck.py:1217 flatcamTools/ToolRulesCheck.py:1223 +#: flatcamTools/ToolRulesCheck.py:1236 flatcamTools/ToolRulesCheck.py:1243 msgid "Copper to Outline clearance" msgstr "Distancia de Cobre a Contorno" -#: flatcamGUI/PreferencesUI.py:6738 flatcamTools/ToolRulesCheck.py:302 +#: flatcamGUI/PreferencesUI.py:7244 flatcamTools/ToolRulesCheck.py:311 msgid "" "This checks if the minimum clearance between copper\n" "features and the outline is met." @@ -12050,11 +12487,11 @@ msgstr "" "Esto comprueba si la distancia mínima entre cobre\n" "huellas y el esquema se cumple." -#: flatcamGUI/PreferencesUI.py:6756 flatcamTools/ToolRulesCheck.py:323 +#: flatcamGUI/PreferencesUI.py:7262 flatcamTools/ToolRulesCheck.py:332 msgid "Silk to Silk Clearance" msgstr "Distancia de Serigrafía a Serigrafía" -#: flatcamGUI/PreferencesUI.py:6758 flatcamTools/ToolRulesCheck.py:325 +#: flatcamGUI/PreferencesUI.py:7264 flatcamTools/ToolRulesCheck.py:334 msgid "" "This checks if the minimum clearance between silkscreen\n" "features and silkscreen features is met." @@ -12062,13 +12499,13 @@ msgstr "" "Esto comprueba si la distancia mínima entre serigrafía\n" "huellas y huellas de serigrafía se cumplen." -#: flatcamGUI/PreferencesUI.py:6776 flatcamTools/ToolRulesCheck.py:346 -#: flatcamTools/ToolRulesCheck.py:1317 flatcamTools/ToolRulesCheck.py:1323 -#: flatcamTools/ToolRulesCheck.py:1341 +#: flatcamGUI/PreferencesUI.py:7282 flatcamTools/ToolRulesCheck.py:355 +#: flatcamTools/ToolRulesCheck.py:1326 flatcamTools/ToolRulesCheck.py:1332 +#: flatcamTools/ToolRulesCheck.py:1350 msgid "Silk to Solder Mask Clearance" msgstr "Serigrafía para Soldar Máscara Distancia" -#: flatcamGUI/PreferencesUI.py:6778 flatcamTools/ToolRulesCheck.py:348 +#: flatcamGUI/PreferencesUI.py:7284 flatcamTools/ToolRulesCheck.py:357 msgid "" "This checks if the minimum clearance between silkscreen\n" "features and soldermask features is met." @@ -12076,13 +12513,13 @@ msgstr "" "Esto comprueba si la distancia mínima entre serigrafía\n" "Traces y soldermask traces se cumplen." -#: flatcamGUI/PreferencesUI.py:6796 flatcamTools/ToolRulesCheck.py:369 -#: flatcamTools/ToolRulesCheck.py:1371 flatcamTools/ToolRulesCheck.py:1377 -#: flatcamTools/ToolRulesCheck.py:1391 flatcamTools/ToolRulesCheck.py:1398 +#: flatcamGUI/PreferencesUI.py:7302 flatcamTools/ToolRulesCheck.py:378 +#: flatcamTools/ToolRulesCheck.py:1380 flatcamTools/ToolRulesCheck.py:1386 +#: flatcamTools/ToolRulesCheck.py:1400 flatcamTools/ToolRulesCheck.py:1407 msgid "Silk to Outline Clearance" msgstr "Serigrafía para Contorno Distancia" -#: flatcamGUI/PreferencesUI.py:6798 flatcamTools/ToolRulesCheck.py:371 +#: flatcamGUI/PreferencesUI.py:7304 flatcamTools/ToolRulesCheck.py:380 msgid "" "This checks if the minimum clearance between silk\n" "features and the outline is met." @@ -12090,12 +12527,12 @@ msgstr "" "Esto verifica si el espacio libre mínimo entre la serigrafía\n" "huellas y el contorno se cumple." -#: flatcamGUI/PreferencesUI.py:6816 flatcamTools/ToolRulesCheck.py:392 -#: flatcamTools/ToolRulesCheck.py:1409 flatcamTools/ToolRulesCheck.py:1436 +#: flatcamGUI/PreferencesUI.py:7322 flatcamTools/ToolRulesCheck.py:401 +#: flatcamTools/ToolRulesCheck.py:1418 flatcamTools/ToolRulesCheck.py:1445 msgid "Minimum Solder Mask Sliver" msgstr "Astilla de máscara de soldadura mínima" -#: flatcamGUI/PreferencesUI.py:6818 flatcamTools/ToolRulesCheck.py:394 +#: flatcamGUI/PreferencesUI.py:7324 flatcamTools/ToolRulesCheck.py:403 msgid "" "This checks if the minimum clearance between soldermask\n" "features and soldermask features is met." @@ -12103,13 +12540,13 @@ msgstr "" "Esto verifica si la distancia mínima entre la máscara de soldadura\n" "rastros y rastros de máscara de soldadura se cumplen." -#: flatcamGUI/PreferencesUI.py:6836 flatcamTools/ToolRulesCheck.py:415 -#: flatcamTools/ToolRulesCheck.py:1474 flatcamTools/ToolRulesCheck.py:1480 -#: flatcamTools/ToolRulesCheck.py:1496 flatcamTools/ToolRulesCheck.py:1503 +#: flatcamGUI/PreferencesUI.py:7342 flatcamTools/ToolRulesCheck.py:424 +#: flatcamTools/ToolRulesCheck.py:1483 flatcamTools/ToolRulesCheck.py:1489 +#: flatcamTools/ToolRulesCheck.py:1505 flatcamTools/ToolRulesCheck.py:1512 msgid "Minimum Annular Ring" msgstr "Anillo anular mínimo" -#: flatcamGUI/PreferencesUI.py:6838 flatcamTools/ToolRulesCheck.py:417 +#: flatcamGUI/PreferencesUI.py:7344 flatcamTools/ToolRulesCheck.py:426 msgid "" "This checks if the minimum copper ring left by drilling\n" "a hole into a pad is met." @@ -12117,16 +12554,16 @@ msgstr "" "Esto verifica si queda el anillo de cobre mínimo al perforar\n" "Se encuentra un agujero en una almohadilla." -#: flatcamGUI/PreferencesUI.py:6851 flatcamTools/ToolRulesCheck.py:430 +#: flatcamGUI/PreferencesUI.py:7357 flatcamTools/ToolRulesCheck.py:439 msgid "Minimum acceptable ring value." msgstr "Valor mínimo aceptable del anillo." -#: flatcamGUI/PreferencesUI.py:6858 flatcamTools/ToolRulesCheck.py:440 -#: flatcamTools/ToolRulesCheck.py:864 +#: flatcamGUI/PreferencesUI.py:7364 flatcamTools/ToolRulesCheck.py:449 +#: flatcamTools/ToolRulesCheck.py:873 msgid "Hole to Hole Clearance" msgstr "Distancia entre Agujeros" -#: flatcamGUI/PreferencesUI.py:6860 flatcamTools/ToolRulesCheck.py:442 +#: flatcamGUI/PreferencesUI.py:7366 flatcamTools/ToolRulesCheck.py:451 msgid "" "This checks if the minimum clearance between a drill hole\n" "and another drill hole is met." @@ -12134,16 +12571,16 @@ msgstr "" "Esto verifica si la distancia mínima entre un taladro\n" "y se encuentra otro taladro." -#: flatcamGUI/PreferencesUI.py:6873 flatcamTools/ToolRulesCheck.py:478 +#: flatcamGUI/PreferencesUI.py:7379 flatcamTools/ToolRulesCheck.py:487 msgid "Minimum acceptable drill size." msgstr "Tamaño mínimo aceptable de perforación." -#: flatcamGUI/PreferencesUI.py:6878 flatcamTools/ToolRulesCheck.py:463 -#: flatcamTools/ToolRulesCheck.py:838 +#: flatcamGUI/PreferencesUI.py:7384 flatcamTools/ToolRulesCheck.py:472 +#: flatcamTools/ToolRulesCheck.py:847 msgid "Hole Size" msgstr "Tamaño del Agujero" -#: flatcamGUI/PreferencesUI.py:6880 flatcamTools/ToolRulesCheck.py:465 +#: flatcamGUI/PreferencesUI.py:7386 flatcamTools/ToolRulesCheck.py:474 msgid "" "This checks if the drill holes\n" "sizes are above the threshold." @@ -12151,11 +12588,11 @@ msgstr "" "Esto comprueba si los agujeros de perforación\n" "Los tamaños están por encima del umbral." -#: flatcamGUI/PreferencesUI.py:6905 +#: flatcamGUI/PreferencesUI.py:7411 msgid "Optimal Tool Options" msgstr "Opciones de Herram. Óptimas" -#: flatcamGUI/PreferencesUI.py:6911 +#: flatcamGUI/PreferencesUI.py:7417 msgid "" "A tool to find the minimum distance between\n" "every two Gerber geometric elements" @@ -12163,20 +12600,20 @@ msgstr "" "Una herramienta para encontrar la distancia mínima entre\n" "cada dos elementos geométricos de Gerber" -#: flatcamGUI/PreferencesUI.py:6926 flatcamTools/ToolOptimal.py:78 +#: flatcamGUI/PreferencesUI.py:7432 flatcamTools/ToolOptimal.py:79 msgid "Precision" msgstr "Precisión" -#: flatcamGUI/PreferencesUI.py:6928 +#: flatcamGUI/PreferencesUI.py:7434 msgid "Number of decimals for the distances and coordinates in this tool." msgstr "" "Número de decimales para las distancias y coordenadas en esta herramienta." -#: flatcamGUI/PreferencesUI.py:6942 +#: flatcamGUI/PreferencesUI.py:7448 msgid "QRCode Tool Options" msgstr "Opciones de la herram. QRCode" -#: flatcamGUI/PreferencesUI.py:6948 +#: flatcamGUI/PreferencesUI.py:7454 msgid "" "A tool to create a QRCode that can be inserted\n" "into a selected Gerber file, or it can be exported as a file." @@ -12184,11 +12621,11 @@ msgstr "" "Una herramienta para crear un QRCode que se puede insertar\n" "en un archivo Gerber seleccionado, o puede exportarse como un archivo." -#: flatcamGUI/PreferencesUI.py:6960 flatcamTools/ToolQRCode.py:99 +#: flatcamGUI/PreferencesUI.py:7466 flatcamTools/ToolQRCode.py:100 msgid "Version" msgstr "Versión" -#: flatcamGUI/PreferencesUI.py:6962 flatcamTools/ToolQRCode.py:101 +#: flatcamGUI/PreferencesUI.py:7468 flatcamTools/ToolQRCode.py:102 msgid "" "QRCode version can have values from 1 (21x21 boxes)\n" "to 40 (177x177 boxes)." @@ -12196,12 +12633,12 @@ msgstr "" "La versión de QRCode puede tener valores de 1 (21x21 elementos)\n" "a 40 (177x177 elementos)." -#: flatcamGUI/PreferencesUI.py:6973 flatcamTools/ToolQRCode.py:112 +#: flatcamGUI/PreferencesUI.py:7479 flatcamTools/ToolQRCode.py:113 msgid "Error correction" msgstr "Corrección de error" -#: flatcamGUI/PreferencesUI.py:6975 flatcamGUI/PreferencesUI.py:6986 -#: flatcamTools/ToolQRCode.py:114 flatcamTools/ToolQRCode.py:125 +#: flatcamGUI/PreferencesUI.py:7481 flatcamGUI/PreferencesUI.py:7492 +#: flatcamTools/ToolQRCode.py:115 flatcamTools/ToolQRCode.py:126 #, python-format msgid "" "Parameter that controls the error correction used for the QR Code.\n" @@ -12217,11 +12654,11 @@ msgstr "" "Q = se puede corregir un máximo de 25%% de errores\n" "H = máximo 30 %% de errores pueden ser corregidos." -#: flatcamGUI/PreferencesUI.py:6996 flatcamTools/ToolQRCode.py:135 +#: flatcamGUI/PreferencesUI.py:7502 flatcamTools/ToolQRCode.py:136 msgid "Box Size" msgstr "Tamaño de Elementos" -#: flatcamGUI/PreferencesUI.py:6998 flatcamTools/ToolQRCode.py:137 +#: flatcamGUI/PreferencesUI.py:7504 flatcamTools/ToolQRCode.py:138 msgid "" "Box size control the overall size of the QRcode\n" "by adjusting the size of each box in the code." @@ -12229,11 +12666,11 @@ msgstr "" "El tamaño del elemento controla el tamaño general del código QR\n" "ajustando el tamaño de cada cuadro en el código." -#: flatcamGUI/PreferencesUI.py:7009 flatcamTools/ToolQRCode.py:148 +#: flatcamGUI/PreferencesUI.py:7515 flatcamTools/ToolQRCode.py:149 msgid "Border Size" msgstr "Tamaño de borde" -#: flatcamGUI/PreferencesUI.py:7011 flatcamTools/ToolQRCode.py:150 +#: flatcamGUI/PreferencesUI.py:7517 flatcamTools/ToolQRCode.py:151 msgid "" "Size of the QRCode border. How many boxes thick is the border.\n" "Default value is 4. The width of the clearance around the QRCode." @@ -12242,23 +12679,23 @@ msgstr "" "El valor predeterminado es 4. El ancho del espacio libre alrededor del " "Código QR." -#: flatcamGUI/PreferencesUI.py:7022 flatcamTools/ToolQRCode.py:162 +#: flatcamGUI/PreferencesUI.py:7528 flatcamTools/ToolQRCode.py:162 msgid "QRCode Data" msgstr "Datos de QRCode" -#: flatcamGUI/PreferencesUI.py:7024 flatcamTools/ToolQRCode.py:164 +#: flatcamGUI/PreferencesUI.py:7530 flatcamTools/ToolQRCode.py:164 msgid "QRCode Data. Alphanumeric text to be encoded in the QRCode." msgstr "Datos de QRCode. Texto alfanumérico a codificar en el Código QR." -#: flatcamGUI/PreferencesUI.py:7028 flatcamTools/ToolQRCode.py:168 +#: flatcamGUI/PreferencesUI.py:7534 flatcamTools/ToolQRCode.py:168 msgid "Add here the text to be included in the QRCode..." msgstr "Agregue aquí el texto que se incluirá en el QRCode ..." -#: flatcamGUI/PreferencesUI.py:7034 flatcamTools/ToolQRCode.py:174 +#: flatcamGUI/PreferencesUI.py:7540 flatcamTools/ToolQRCode.py:174 msgid "Polarity" msgstr "Polaridad" -#: flatcamGUI/PreferencesUI.py:7036 flatcamTools/ToolQRCode.py:176 +#: flatcamGUI/PreferencesUI.py:7542 flatcamTools/ToolQRCode.py:176 msgid "" "Choose the polarity of the QRCode.\n" "It can be drawn in a negative way (squares are clear)\n" @@ -12268,17 +12705,17 @@ msgstr "" "Se puede dibujar de forma negativa (los cuadrados son claros)\n" "o de manera positiva (los cuadrados son opacos)." -#: flatcamGUI/PreferencesUI.py:7040 flatcamTools/ToolFilm.py:296 +#: flatcamGUI/PreferencesUI.py:7546 flatcamTools/ToolFilm.py:296 #: flatcamTools/ToolQRCode.py:180 msgid "Negative" msgstr "Negativa" -#: flatcamGUI/PreferencesUI.py:7041 flatcamTools/ToolFilm.py:295 +#: flatcamGUI/PreferencesUI.py:7547 flatcamTools/ToolFilm.py:295 #: flatcamTools/ToolQRCode.py:181 msgid "Positive" msgstr "Positivo" -#: flatcamGUI/PreferencesUI.py:7043 flatcamTools/ToolQRCode.py:183 +#: flatcamGUI/PreferencesUI.py:7549 flatcamTools/ToolQRCode.py:183 msgid "" "Choose the type of QRCode to be created.\n" "If added on a Silkscreen Gerber file the QRCode may\n" @@ -12290,7 +12727,7 @@ msgstr "" "ser agregado como positivo Si se agrega a un cobre Gerber\n" "entonces quizás el QRCode se pueda agregar como negativo." -#: flatcamGUI/PreferencesUI.py:7054 flatcamGUI/PreferencesUI.py:7060 +#: flatcamGUI/PreferencesUI.py:7560 flatcamGUI/PreferencesUI.py:7566 #: flatcamTools/ToolQRCode.py:194 flatcamTools/ToolQRCode.py:200 msgid "" "The bounding box, meaning the empty space that surrounds\n" @@ -12299,29 +12736,29 @@ msgstr "" "El cuadro delimitador, que significa el espacio vacío que rodea\n" "La geometría QRCode, puede tener una forma redondeada o cuadrada." -#: flatcamGUI/PreferencesUI.py:7067 flatcamTools/ToolQRCode.py:228 +#: flatcamGUI/PreferencesUI.py:7573 flatcamTools/ToolQRCode.py:228 msgid "Fill Color" msgstr "Color de relleno" -#: flatcamGUI/PreferencesUI.py:7069 flatcamTools/ToolQRCode.py:230 +#: flatcamGUI/PreferencesUI.py:7575 flatcamTools/ToolQRCode.py:230 msgid "Set the QRCode fill color (squares color)." msgstr "" "Establezca el color de relleno del código QR (color de cuadrados / " "elementos)." -#: flatcamGUI/PreferencesUI.py:7088 flatcamTools/ToolQRCode.py:252 +#: flatcamGUI/PreferencesUI.py:7594 flatcamTools/ToolQRCode.py:252 msgid "Back Color" msgstr "Color de fondo" -#: flatcamGUI/PreferencesUI.py:7090 flatcamTools/ToolQRCode.py:254 +#: flatcamGUI/PreferencesUI.py:7596 flatcamTools/ToolQRCode.py:254 msgid "Set the QRCode background color." msgstr "Establece el color de fondo del QRCode." -#: flatcamGUI/PreferencesUI.py:7130 +#: flatcamGUI/PreferencesUI.py:7636 msgid "Copper Thieving Tool Options" msgstr "Opc. de Herram. de Copper Thieving" -#: flatcamGUI/PreferencesUI.py:7142 +#: flatcamGUI/PreferencesUI.py:7648 msgid "" "A tool to generate a Copper Thieving that can be added\n" "to a selected Gerber file." @@ -12329,16 +12766,16 @@ msgstr "" "Una herramienta para generar un ladrón de cobre que se puede agregar\n" "a un archivo Gerber seleccionado." -#: flatcamGUI/PreferencesUI.py:7150 +#: flatcamGUI/PreferencesUI.py:7656 msgid "Number of steps (lines) used to interpolate circles." msgstr "Número de pasos (líneas) utilizados para interpolar círculos." -#: flatcamGUI/PreferencesUI.py:7160 flatcamGUI/PreferencesUI.py:7364 -#: flatcamTools/ToolCopperThieving.py:96 flatcamTools/ToolCopperThieving.py:429 +#: flatcamGUI/PreferencesUI.py:7666 flatcamGUI/PreferencesUI.py:7870 +#: flatcamTools/ToolCopperThieving.py:97 flatcamTools/ToolCopperThieving.py:432 msgid "Clearance" msgstr "Despeje" -#: flatcamGUI/PreferencesUI.py:7162 +#: flatcamGUI/PreferencesUI.py:7668 msgid "" "This set the distance between the copper Thieving components\n" "(the polygon fill may be split in multiple polygons)\n" @@ -12348,22 +12785,11 @@ msgstr "" "(el relleno de polígono puede dividirse en múltiples polígonos)\n" "y las huellas de cobre en el archivo Gerber." -#: flatcamGUI/PreferencesUI.py:7190 flatcamTools/ToolCopperThieving.py:126 -#: flatcamTools/ToolNonCopperClear.py:430 flatcamTools/ToolPaint.py:308 -msgid "Area Selection" -msgstr "Selección de área" - -#: flatcamGUI/PreferencesUI.py:7191 flatcamTools/ToolCopperThieving.py:127 -#: flatcamTools/ToolNonCopperClear.py:431 flatcamTools/ToolPaint.py:310 -msgid "Reference Object" -msgstr "Objeto de referencia" - -#: flatcamGUI/PreferencesUI.py:7193 flatcamTools/ToolCopperThieving.py:129 -#: flatcamTools/ToolNonCopperClear.py:433 +#: flatcamGUI/PreferencesUI.py:7699 flatcamTools/ToolCopperThieving.py:130 msgid "Reference:" msgstr "Referencia:" -#: flatcamGUI/PreferencesUI.py:7195 +#: flatcamGUI/PreferencesUI.py:7701 msgid "" "- 'Itself' - the copper Thieving extent is based on the object extent.\n" "- 'Area Selection' - left mouse click to start selection of the area to be " @@ -12378,20 +12804,24 @@ msgstr "" "- 'Objeto de referencia': robará cobre dentro del área especificada por otro " "objeto." -#: flatcamGUI/PreferencesUI.py:7204 flatcamTools/ToolCopperThieving.py:170 +#: flatcamGUI/PreferencesUI.py:7710 flatcamGUI/PreferencesUI.py:8175 +#: flatcamGUI/PreferencesUI.py:8287 flatcamGUI/PreferencesUI.py:8387 +#: flatcamGUI/PreferencesUI.py:8501 flatcamTools/ToolCopperThieving.py:172 +#: flatcamTools/ToolExtractDrills.py:102 flatcamTools/ToolExtractDrills.py:240 +#: flatcamTools/ToolPunchGerber.py:113 flatcamTools/ToolPunchGerber.py:268 msgid "Rectangular" msgstr "Rectangular" -#: flatcamGUI/PreferencesUI.py:7205 flatcamTools/ToolCopperThieving.py:171 +#: flatcamGUI/PreferencesUI.py:7711 flatcamTools/ToolCopperThieving.py:173 msgid "Minimal" msgstr "Mínimo" -#: flatcamGUI/PreferencesUI.py:7207 flatcamTools/ToolCopperThieving.py:173 +#: flatcamGUI/PreferencesUI.py:7713 flatcamTools/ToolCopperThieving.py:175 #: flatcamTools/ToolFilm.py:113 msgid "Box Type:" msgstr "Tipo de cercado:" -#: flatcamGUI/PreferencesUI.py:7209 flatcamTools/ToolCopperThieving.py:175 +#: flatcamGUI/PreferencesUI.py:7715 flatcamTools/ToolCopperThieving.py:177 msgid "" "- 'Rectangular' - the bounding box will be of rectangular shape.\n" "- 'Minimal' - the bounding box will be the convex hull shape." @@ -12399,23 +12829,23 @@ msgstr "" "- 'Rectangular': el cuadro delimitador tendrá forma rectangular.\n" "- 'Mínimo': el cuadro delimitador tendrá forma de casco convexo." -#: flatcamGUI/PreferencesUI.py:7223 flatcamTools/ToolCopperThieving.py:191 +#: flatcamGUI/PreferencesUI.py:7729 flatcamTools/ToolCopperThieving.py:193 msgid "Dots Grid" msgstr "Cuadrícula de puntos" -#: flatcamGUI/PreferencesUI.py:7224 flatcamTools/ToolCopperThieving.py:192 +#: flatcamGUI/PreferencesUI.py:7730 flatcamTools/ToolCopperThieving.py:194 msgid "Squares Grid" msgstr "Cuadrícula de cuadrados" -#: flatcamGUI/PreferencesUI.py:7225 flatcamTools/ToolCopperThieving.py:193 +#: flatcamGUI/PreferencesUI.py:7731 flatcamTools/ToolCopperThieving.py:195 msgid "Lines Grid" msgstr "Cuadrícula de líneas" -#: flatcamGUI/PreferencesUI.py:7227 flatcamTools/ToolCopperThieving.py:195 +#: flatcamGUI/PreferencesUI.py:7733 flatcamTools/ToolCopperThieving.py:197 msgid "Fill Type:" msgstr "Tipo de relleno:" -#: flatcamGUI/PreferencesUI.py:7229 flatcamTools/ToolCopperThieving.py:197 +#: flatcamGUI/PreferencesUI.py:7735 flatcamTools/ToolCopperThieving.py:199 msgid "" "- 'Solid' - copper thieving will be a solid polygon.\n" "- 'Dots Grid' - the empty area will be filled with a pattern of dots.\n" @@ -12429,54 +12859,54 @@ msgstr "" "cuadrados.\n" "- 'Cuadrícula de líneas': el área vacía se rellenará con un patrón de líneas." -#: flatcamGUI/PreferencesUI.py:7237 flatcamTools/ToolCopperThieving.py:216 +#: flatcamGUI/PreferencesUI.py:7743 flatcamTools/ToolCopperThieving.py:218 msgid "Dots Grid Parameters" msgstr "Parámetros de cuadrícula de puntos" -#: flatcamGUI/PreferencesUI.py:7243 flatcamTools/ToolCopperThieving.py:222 +#: flatcamGUI/PreferencesUI.py:7749 flatcamTools/ToolCopperThieving.py:224 msgid "Dot diameter in Dots Grid." msgstr "Diámetro de punto en cuadrícula de puntos." -#: flatcamGUI/PreferencesUI.py:7254 flatcamGUI/PreferencesUI.py:7283 -#: flatcamGUI/PreferencesUI.py:7312 flatcamTools/ToolCopperThieving.py:233 -#: flatcamTools/ToolCopperThieving.py:273 -#: flatcamTools/ToolCopperThieving.py:313 +#: flatcamGUI/PreferencesUI.py:7760 flatcamGUI/PreferencesUI.py:7789 +#: flatcamGUI/PreferencesUI.py:7818 flatcamTools/ToolCopperThieving.py:235 +#: flatcamTools/ToolCopperThieving.py:275 +#: flatcamTools/ToolCopperThieving.py:315 msgid "Spacing" msgstr "Spacing" -#: flatcamGUI/PreferencesUI.py:7256 flatcamTools/ToolCopperThieving.py:235 +#: flatcamGUI/PreferencesUI.py:7762 flatcamTools/ToolCopperThieving.py:237 msgid "Distance between each two dots in Dots Grid." msgstr "Distancia entre cada dos puntos en la cuadrícula de puntos." -#: flatcamGUI/PreferencesUI.py:7266 flatcamTools/ToolCopperThieving.py:256 +#: flatcamGUI/PreferencesUI.py:7772 flatcamTools/ToolCopperThieving.py:258 msgid "Squares Grid Parameters" msgstr "Parámetros de la cuadrícula de cuadrados" -#: flatcamGUI/PreferencesUI.py:7272 flatcamTools/ToolCopperThieving.py:262 +#: flatcamGUI/PreferencesUI.py:7778 flatcamTools/ToolCopperThieving.py:264 msgid "Square side size in Squares Grid." msgstr "Tamaño del lado cuadrado en cuadrícula de cuadrados." -#: flatcamGUI/PreferencesUI.py:7285 flatcamTools/ToolCopperThieving.py:275 +#: flatcamGUI/PreferencesUI.py:7791 flatcamTools/ToolCopperThieving.py:277 msgid "Distance between each two squares in Squares Grid." msgstr "Distancia entre cada dos cuadrados en la cuadrícula de cuadrados." -#: flatcamGUI/PreferencesUI.py:7295 flatcamTools/ToolCopperThieving.py:296 +#: flatcamGUI/PreferencesUI.py:7801 flatcamTools/ToolCopperThieving.py:298 msgid "Lines Grid Parameters" msgstr "Parámetros de cuadrícula de líneas" -#: flatcamGUI/PreferencesUI.py:7301 flatcamTools/ToolCopperThieving.py:302 +#: flatcamGUI/PreferencesUI.py:7807 flatcamTools/ToolCopperThieving.py:304 msgid "Line thickness size in Lines Grid." msgstr "Tamaño del grosor de línea en la cuadrícula de líneas." -#: flatcamGUI/PreferencesUI.py:7314 flatcamTools/ToolCopperThieving.py:315 +#: flatcamGUI/PreferencesUI.py:7820 flatcamTools/ToolCopperThieving.py:317 msgid "Distance between each two lines in Lines Grid." msgstr "Distancia entre cada dos líneas en la cuadrícula de líneas." -#: flatcamGUI/PreferencesUI.py:7324 flatcamTools/ToolCopperThieving.py:353 +#: flatcamGUI/PreferencesUI.py:7830 flatcamTools/ToolCopperThieving.py:355 msgid "Robber Bar Parameters" msgstr "Parámetros de la Robber Bar" -#: flatcamGUI/PreferencesUI.py:7326 flatcamTools/ToolCopperThieving.py:355 +#: flatcamGUI/PreferencesUI.py:7832 flatcamTools/ToolCopperThieving.py:357 msgid "" "Parameters used for the robber bar.\n" "Robber bar = copper border to help in pattern hole plating." @@ -12484,27 +12914,27 @@ msgstr "" "Parámetros utilizados para la Robber Bar.\n" "Robber Bar = borde de cobre para ayudar en el enchapado de agujeros." -#: flatcamGUI/PreferencesUI.py:7334 flatcamTools/ToolCopperThieving.py:363 +#: flatcamGUI/PreferencesUI.py:7840 flatcamTools/ToolCopperThieving.py:365 msgid "Bounding box margin for robber bar." msgstr "Margen límite del recinto para Robber Bar." -#: flatcamGUI/PreferencesUI.py:7345 flatcamTools/ToolCopperThieving.py:374 +#: flatcamGUI/PreferencesUI.py:7851 flatcamTools/ToolCopperThieving.py:376 msgid "Thickness" msgstr "Espesor" -#: flatcamGUI/PreferencesUI.py:7347 flatcamTools/ToolCopperThieving.py:376 +#: flatcamGUI/PreferencesUI.py:7853 flatcamTools/ToolCopperThieving.py:378 msgid "The robber bar thickness." msgstr "El grosor de la Robber Bar." -#: flatcamGUI/PreferencesUI.py:7357 flatcamTools/ToolCopperThieving.py:407 +#: flatcamGUI/PreferencesUI.py:7863 flatcamTools/ToolCopperThieving.py:409 msgid "Pattern Plating Mask" msgstr "Máscara de baño de patrones" -#: flatcamGUI/PreferencesUI.py:7359 flatcamTools/ToolCopperThieving.py:409 +#: flatcamGUI/PreferencesUI.py:7865 flatcamTools/ToolCopperThieving.py:411 msgid "Generate a mask for pattern plating." msgstr "Genere una máscara para el enchapado de patrones." -#: flatcamGUI/PreferencesUI.py:7366 flatcamTools/ToolCopperThieving.py:431 +#: flatcamGUI/PreferencesUI.py:7872 flatcamTools/ToolCopperThieving.py:434 msgid "" "The distance between the possible copper thieving elements\n" "and/or robber bar and the actual openings in the mask." @@ -12512,16 +12942,17 @@ msgstr "" "La distancia entre los posibles elementos de Copper Thieving.\n" "y / o Robber Bar y las aberturas reales en la máscara." -#: flatcamGUI/PreferencesUI.py:7385 +#: flatcamGUI/PreferencesUI.py:7891 msgid "Fiducials Tool Options" msgstr "Opc. de Herram. Fiduciales" -#: flatcamGUI/PreferencesUI.py:7396 flatcamGUI/PreferencesUI.py:7512 -#: flatcamTools/ToolCopperThieving.py:91 flatcamTools/ToolFiducials.py:151 +#: flatcamGUI/PreferencesUI.py:7902 flatcamGUI/PreferencesUI.py:8018 +#: flatcamGUI/PreferencesUI.py:8137 flatcamGUI/PreferencesUI.py:8349 +#: flatcamTools/ToolCopperThieving.py:92 flatcamTools/ToolFiducials.py:151 msgid "Parameters used for this tool." msgstr "Parámetros utilizados para esta herramienta." -#: flatcamGUI/PreferencesUI.py:7403 flatcamTools/ToolFiducials.py:158 +#: flatcamGUI/PreferencesUI.py:7909 flatcamTools/ToolFiducials.py:158 msgid "" "This set the fiducial diameter if fiducial type is circular,\n" "otherwise is the size of the fiducial.\n" @@ -12531,19 +12962,19 @@ msgstr "" "de lo contrario es el tamaño del fiducial.\n" "La apertura de la máscara de soldadura es el doble que eso." -#: flatcamGUI/PreferencesUI.py:7431 flatcamTools/ToolFiducials.py:186 +#: flatcamGUI/PreferencesUI.py:7937 flatcamTools/ToolFiducials.py:186 msgid "Auto" msgstr "Auto" -#: flatcamGUI/PreferencesUI.py:7432 flatcamTools/ToolFiducials.py:187 +#: flatcamGUI/PreferencesUI.py:7938 flatcamTools/ToolFiducials.py:187 msgid "Manual" msgstr "Manual" -#: flatcamGUI/PreferencesUI.py:7434 flatcamTools/ToolFiducials.py:189 +#: flatcamGUI/PreferencesUI.py:7940 flatcamTools/ToolFiducials.py:189 msgid "Mode:" msgstr "Modo:" -#: flatcamGUI/PreferencesUI.py:7436 +#: flatcamGUI/PreferencesUI.py:7942 msgid "" "- 'Auto' - automatic placement of fiducials in the corners of the bounding " "box.\n" @@ -12553,19 +12984,19 @@ msgstr "" "delimitador.\n" "- 'Manual' - colocación manual de fiduciales." -#: flatcamGUI/PreferencesUI.py:7444 flatcamTools/ToolFiducials.py:199 +#: flatcamGUI/PreferencesUI.py:7950 flatcamTools/ToolFiducials.py:199 msgid "Up" msgstr "Arriba" -#: flatcamGUI/PreferencesUI.py:7445 flatcamTools/ToolFiducials.py:200 +#: flatcamGUI/PreferencesUI.py:7951 flatcamTools/ToolFiducials.py:200 msgid "Down" msgstr "Abajo" -#: flatcamGUI/PreferencesUI.py:7448 flatcamTools/ToolFiducials.py:203 +#: flatcamGUI/PreferencesUI.py:7954 flatcamTools/ToolFiducials.py:203 msgid "Second fiducial" msgstr "Segundo fiducial" -#: flatcamGUI/PreferencesUI.py:7450 flatcamTools/ToolFiducials.py:205 +#: flatcamGUI/PreferencesUI.py:7956 flatcamTools/ToolFiducials.py:205 msgid "" "The position for the second fiducial.\n" "- 'Up' - the order is: bottom-left, top-left, top-right.\n" @@ -12580,19 +13011,19 @@ msgstr "" "- 'Ninguno' - no hay un segundo fiducial. El orden es: abajo a la izquierda, " "arriba a la derecha." -#: flatcamGUI/PreferencesUI.py:7466 flatcamTools/ToolFiducials.py:221 +#: flatcamGUI/PreferencesUI.py:7972 flatcamTools/ToolFiducials.py:221 msgid "Cross" msgstr "Cruce" -#: flatcamGUI/PreferencesUI.py:7467 flatcamTools/ToolFiducials.py:222 +#: flatcamGUI/PreferencesUI.py:7973 flatcamTools/ToolFiducials.py:222 msgid "Chess" msgstr "Ajedrez" -#: flatcamGUI/PreferencesUI.py:7470 flatcamTools/ToolFiducials.py:224 +#: flatcamGUI/PreferencesUI.py:7976 flatcamTools/ToolFiducials.py:224 msgid "Fiducial Type" msgstr "Tipo fiducial" -#: flatcamGUI/PreferencesUI.py:7472 flatcamTools/ToolFiducials.py:226 +#: flatcamGUI/PreferencesUI.py:7978 flatcamTools/ToolFiducials.py:226 msgid "" "The type of fiducial.\n" "- 'Circular' - this is the regular fiducial.\n" @@ -12604,19 +13035,19 @@ msgstr "" "- 'Cruce' - líneas cruzadas fiduciales.\n" "- 'Ajedrez' - patrón de ajedrez fiducial." -#: flatcamGUI/PreferencesUI.py:7481 flatcamTools/ToolFiducials.py:235 +#: flatcamGUI/PreferencesUI.py:7987 flatcamTools/ToolFiducials.py:235 msgid "Line thickness" msgstr "Grosor de la línea" -#: flatcamGUI/PreferencesUI.py:7501 +#: flatcamGUI/PreferencesUI.py:8007 msgid "Calibration Tool Options" msgstr "Opc. de Herram. de Calibración" -#: flatcamGUI/PreferencesUI.py:7517 flatcamTools/ToolCalibration.py:181 +#: flatcamGUI/PreferencesUI.py:8023 flatcamTools/ToolCalibration.py:181 msgid "Source Type" msgstr "Tipo de Fuente" -#: flatcamGUI/PreferencesUI.py:7518 flatcamTools/ToolCalibration.py:182 +#: flatcamGUI/PreferencesUI.py:8024 flatcamTools/ToolCalibration.py:182 msgid "" "The source of calibration points.\n" "It can be:\n" @@ -12630,27 +13061,27 @@ msgstr "" "- Libre -> haga clic libremente en el lienzo para adquirir los puntos de " "calibración" -#: flatcamGUI/PreferencesUI.py:7523 flatcamTools/ToolCalibration.py:187 +#: flatcamGUI/PreferencesUI.py:8029 flatcamTools/ToolCalibration.py:187 msgid "Free" msgstr "Libre" -#: flatcamGUI/PreferencesUI.py:7537 flatcamTools/ToolCalibration.py:76 +#: flatcamGUI/PreferencesUI.py:8043 flatcamTools/ToolCalibration.py:76 msgid "Height (Z) for travelling between the points." msgstr "Altura (Z) para viajar entre los puntos." -#: flatcamGUI/PreferencesUI.py:7549 flatcamTools/ToolCalibration.py:88 +#: flatcamGUI/PreferencesUI.py:8055 flatcamTools/ToolCalibration.py:88 msgid "Verification Z" msgstr "Verificación Z" -#: flatcamGUI/PreferencesUI.py:7551 flatcamTools/ToolCalibration.py:90 +#: flatcamGUI/PreferencesUI.py:8057 flatcamTools/ToolCalibration.py:90 msgid "Height (Z) for checking the point." msgstr "Altura (Z) para verificar el punto." -#: flatcamGUI/PreferencesUI.py:7563 flatcamTools/ToolCalibration.py:102 +#: flatcamGUI/PreferencesUI.py:8069 flatcamTools/ToolCalibration.py:102 msgid "Zero Z tool" msgstr "Cero la Z para Herram." -#: flatcamGUI/PreferencesUI.py:7565 flatcamTools/ToolCalibration.py:104 +#: flatcamGUI/PreferencesUI.py:8071 flatcamTools/ToolCalibration.py:104 msgid "" "Include a sequence to zero the height (Z)\n" "of the verification tool." @@ -12658,11 +13089,11 @@ msgstr "" "Incluya una secuencia para poner a cero la altura (Z)\n" "de la herramienta de verificación." -#: flatcamGUI/PreferencesUI.py:7574 flatcamTools/ToolCalibration.py:113 +#: flatcamGUI/PreferencesUI.py:8080 flatcamTools/ToolCalibration.py:113 msgid "Height (Z) for mounting the verification probe." msgstr "Altura (Z) para montar la sonda de verificación." -#: flatcamGUI/PreferencesUI.py:7588 flatcamTools/ToolCalibration.py:127 +#: flatcamGUI/PreferencesUI.py:8094 flatcamTools/ToolCalibration.py:127 msgid "" "Toolchange X,Y position.\n" "If no value is entered then the current\n" @@ -12672,11 +13103,11 @@ msgstr "" "Si no se ingresa ningún valor, entonces el actual\n" "(x, y) se utilizará el punto," -#: flatcamGUI/PreferencesUI.py:7599 flatcamTools/ToolCalibration.py:153 +#: flatcamGUI/PreferencesUI.py:8105 flatcamTools/ToolCalibration.py:153 msgid "Second point" msgstr "Segundo punto" -#: flatcamGUI/PreferencesUI.py:7601 flatcamTools/ToolCalibration.py:155 +#: flatcamGUI/PreferencesUI.py:8107 flatcamTools/ToolCalibration.py:155 msgid "" "Second point in the Gcode verification can be:\n" "- top-left -> the user will align the PCB vertically\n" @@ -12686,45 +13117,251 @@ msgstr "" "- arriba a la izquierda -> el usuario alineará la PCB verticalmente\n" "- abajo a la derecha -> el usuario alineará la PCB horizontalmente" -#: flatcamGUI/PreferencesUI.py:7605 flatcamTools/ToolCalibration.py:159 -msgid "Top-Left" -msgstr "Arriba a la izquierda" +#: flatcamGUI/PreferencesUI.py:8126 +msgid "Extract Drills Options" +msgstr "Opciones de Extracción de Taladros" -#: flatcamGUI/PreferencesUI.py:7606 flatcamTools/ToolCalibration.py:160 -msgid "Bottom-Right" -msgstr "Abajo a la derecha" +#: flatcamGUI/PreferencesUI.py:8141 flatcamGUI/PreferencesUI.py:8353 +#: flatcamTools/ToolExtractDrills.py:68 flatcamTools/ToolPunchGerber.py:75 +msgid "Processed Pads Type" +msgstr "Tipo de almohadillas procesadas" -#: flatcamGUI/PreferencesUI.py:7620 +#: flatcamGUI/PreferencesUI.py:8143 flatcamGUI/PreferencesUI.py:8355 +#: flatcamTools/ToolExtractDrills.py:70 flatcamTools/ToolPunchGerber.py:77 +msgid "" +"The type of pads shape to be processed.\n" +"If the PCB has many SMD pads with rectangular pads,\n" +"disable the Rectangular aperture." +msgstr "" +"El tipo de forma de almohadillas que se procesará.\n" +"Si la PCB tiene muchas almohadillas SMD con almohadillas rectangulares,\n" +"deshabilitar la apertura rectangular." + +#: flatcamGUI/PreferencesUI.py:8153 flatcamGUI/PreferencesUI.py:8365 +#: flatcamTools/ToolExtractDrills.py:80 flatcamTools/ToolPunchGerber.py:91 +msgid "Process Circular Pads." +msgstr "Proceso de Almohadillas Circulares." + +#: flatcamGUI/PreferencesUI.py:8159 flatcamGUI/PreferencesUI.py:8261 +#: flatcamGUI/PreferencesUI.py:8371 flatcamGUI/PreferencesUI.py:8475 +#: flatcamTools/ToolExtractDrills.py:86 flatcamTools/ToolExtractDrills.py:214 +#: flatcamTools/ToolPunchGerber.py:97 flatcamTools/ToolPunchGerber.py:242 +msgid "Oblong" +msgstr "Oblongo" + +#: flatcamGUI/PreferencesUI.py:8161 flatcamGUI/PreferencesUI.py:8373 +#: flatcamTools/ToolExtractDrills.py:88 flatcamTools/ToolPunchGerber.py:99 +msgid "Process Oblong Pads." +msgstr "Procesar almohadillas oblongas." + +#: flatcamGUI/PreferencesUI.py:8169 flatcamGUI/PreferencesUI.py:8381 +#: flatcamTools/ToolExtractDrills.py:96 flatcamTools/ToolPunchGerber.py:107 +msgid "Process Square Pads." +msgstr "Procesar almohadillas cuadradas." + +#: flatcamGUI/PreferencesUI.py:8177 flatcamGUI/PreferencesUI.py:8389 +#: flatcamTools/ToolExtractDrills.py:104 flatcamTools/ToolPunchGerber.py:115 +msgid "Process Rectangular Pads." +msgstr "Proceso Almohadillas Rectangulares." + +#: flatcamGUI/PreferencesUI.py:8183 flatcamGUI/PreferencesUI.py:8300 +#: flatcamGUI/PreferencesUI.py:8395 flatcamGUI/PreferencesUI.py:8514 +#: flatcamTools/ToolExtractDrills.py:110 flatcamTools/ToolExtractDrills.py:253 +#: flatcamTools/ToolProperties.py:172 flatcamTools/ToolPunchGerber.py:121 +#: flatcamTools/ToolPunchGerber.py:281 +msgid "Others" +msgstr "Otros" + +#: flatcamGUI/PreferencesUI.py:8185 flatcamGUI/PreferencesUI.py:8397 +#: flatcamTools/ToolExtractDrills.py:112 flatcamTools/ToolPunchGerber.py:123 +msgid "Process pads not in the categories above." +msgstr "Procese los pads no en las categorías anteriores." + +#: flatcamGUI/PreferencesUI.py:8198 flatcamGUI/PreferencesUI.py:8222 +#: flatcamGUI/PreferencesUI.py:8411 flatcamGUI/PreferencesUI.py:8436 +#: flatcamTools/ToolExtractDrills.py:139 flatcamTools/ToolExtractDrills.py:156 +#: flatcamTools/ToolPunchGerber.py:150 flatcamTools/ToolPunchGerber.py:184 +msgid "Fixed Diameter" +msgstr "Diámetro fijo" + +#: flatcamGUI/PreferencesUI.py:8199 flatcamGUI/PreferencesUI.py:8239 +#: flatcamGUI/PreferencesUI.py:8412 flatcamGUI/PreferencesUI.py:8453 +#: flatcamTools/ToolExtractDrills.py:140 flatcamTools/ToolExtractDrills.py:192 +#: flatcamTools/ToolPunchGerber.py:151 flatcamTools/ToolPunchGerber.py:214 +msgid "Fixed Annular Ring" +msgstr "Anillo anular fijo" + +#: flatcamGUI/PreferencesUI.py:8200 flatcamGUI/PreferencesUI.py:8413 +#: flatcamTools/ToolExtractDrills.py:141 flatcamTools/ToolPunchGerber.py:152 +msgid "Proportional" +msgstr "Proporcional" + +#: flatcamGUI/PreferencesUI.py:8206 flatcamTools/ToolExtractDrills.py:130 +msgid "" +"The method for processing pads. Can be:\n" +"- Fixed Diameter -> all holes will have a set size\n" +"- Fixed Annular Ring -> all holes will have a set annular ring\n" +"- Proportional -> each hole size will be a fraction of the pad size" +msgstr "" +"El método para procesar almohadillas. Puede ser:\n" +"- Diámetro fijo -> todos los agujeros tendrán un tamaño establecido\n" +"- Anillo anular fijo -> todos los agujeros tendrán un anillo anular " +"establecido\n" +"- Proporcional -> cada tamaño de agujero será una fracción del tamaño de la " +"almohadilla" + +#: flatcamGUI/PreferencesUI.py:8232 flatcamGUI/PreferencesUI.py:8446 +#: flatcamTools/ToolExtractDrills.py:166 flatcamTools/ToolPunchGerber.py:194 +msgid "Fixed hole diameter." +msgstr "Diámetro fijo del agujero." + +#: flatcamGUI/PreferencesUI.py:8241 flatcamGUI/PreferencesUI.py:8455 +#: flatcamTools/ToolExtractDrills.py:194 flatcamTools/ToolPunchGerber.py:216 +msgid "" +"The size of annular ring.\n" +"The copper sliver between the hole exterior\n" +"and the margin of the copper pad." +msgstr "" +"El tamaño del anillo anular.\n" +"La astilla de cobre entre el exterior del agujero\n" +"y el margen de la almohadilla de cobre." + +#: flatcamGUI/PreferencesUI.py:8250 flatcamGUI/PreferencesUI.py:8464 +#: flatcamTools/ToolExtractDrills.py:203 flatcamTools/ToolPunchGerber.py:231 +msgid "The size of annular ring for circular pads." +msgstr "El tamaño del anillo anular para almohadillas circulares." + +#: flatcamGUI/PreferencesUI.py:8263 flatcamGUI/PreferencesUI.py:8477 +#: flatcamTools/ToolExtractDrills.py:216 flatcamTools/ToolPunchGerber.py:244 +msgid "The size of annular ring for oblong pads." +msgstr "El tamaño del anillo anular para almohadillas oblongas." + +#: flatcamGUI/PreferencesUI.py:8276 flatcamGUI/PreferencesUI.py:8490 +#: flatcamTools/ToolExtractDrills.py:229 flatcamTools/ToolPunchGerber.py:257 +msgid "The size of annular ring for square pads." +msgstr "El tamaño del anillo anular para almohadillas cuadradas." + +#: flatcamGUI/PreferencesUI.py:8289 flatcamGUI/PreferencesUI.py:8503 +#: flatcamTools/ToolExtractDrills.py:242 flatcamTools/ToolPunchGerber.py:270 +msgid "The size of annular ring for rectangular pads." +msgstr "El tamaño del anillo anular para almohadillas rectangulares." + +#: flatcamGUI/PreferencesUI.py:8302 flatcamGUI/PreferencesUI.py:8516 +#: flatcamTools/ToolExtractDrills.py:255 flatcamTools/ToolPunchGerber.py:283 +msgid "The size of annular ring for other pads." +msgstr "El tamaño del anillo anular para otras almohadillas." + +#: flatcamGUI/PreferencesUI.py:8312 flatcamGUI/PreferencesUI.py:8526 +#: flatcamTools/ToolExtractDrills.py:276 flatcamTools/ToolPunchGerber.py:299 +msgid "Proportional Diameter" +msgstr "Diá. proporcional" + +#: flatcamGUI/PreferencesUI.py:8321 flatcamGUI/PreferencesUI.py:8535 +msgid "Factor" +msgstr "Factor" + +#: flatcamGUI/PreferencesUI.py:8323 flatcamGUI/PreferencesUI.py:8537 +#: flatcamTools/ToolExtractDrills.py:287 flatcamTools/ToolPunchGerber.py:310 +msgid "" +"Proportional Diameter.\n" +"The hole diameter will be a fraction of the pad size." +msgstr "" +"Diámetro proporcional.\n" +"El diámetro del agujero será una fracción del tamaño de la almohadilla." + +#: flatcamGUI/PreferencesUI.py:8338 +msgid "Punch Gerber Options" +msgstr "Opciones de Perforadora Gerber" + +#: flatcamGUI/PreferencesUI.py:8419 flatcamTools/ToolPunchGerber.py:141 +msgid "" +"The punch hole source can be:\n" +"- Excellon Object-> the Excellon object drills center will serve as " +"reference.\n" +"- Fixed Diameter -> will try to use the pads center as reference adding " +"fixed diameter holes.\n" +"- Fixed Annular Ring -> will try to keep a set annular ring.\n" +"- Proportional -> will make a Gerber punch hole having the diameter a " +"percentage of the pad diameter.\n" +msgstr "" +"La fuente del orificio de perforación puede ser:\n" +"- Objeto Excellon-> el centro de perforación de objetos Excellon servirá " +"como referencia.\n" +"- Diámetro fijo -> intentará usar el centro de las almohadillas como " +"referencia agregando agujeros de diámetro fijo.\n" +"- Anillo anular fijo -> intentará mantener un anillo anular establecido.\n" +"- Proporcional -> hará un orificio de perforación Gerber con un diámetro del " +"porcentaje del diámetro de la almohadilla.\n" + +#: flatcamGUI/PreferencesUI.py:8552 +msgid "Invert Gerber Tool Options" +msgstr "Opciones de la herram. Invertir Gerber" + +#: flatcamGUI/PreferencesUI.py:8558 +msgid "" +"A tool to invert Gerber geometry from positive to negative\n" +"and in revers." +msgstr "" +"Una herramienta para invertir la geometría de Gerber de positivo a negativo\n" +"y a la inversa." + +#: flatcamGUI/PreferencesUI.py:8572 flatcamTools/ToolInvertGerber.py:90 +msgid "" +"Distance by which to avoid\n" +"the edges of the Gerber object." +msgstr "" +"Distancia por la cual evitar\n" +"Los bordes del objeto Gerber." + +#: flatcamGUI/PreferencesUI.py:8583 flatcamTools/ToolInvertGerber.py:101 +msgid "Lines Join Style" +msgstr "Estilo de unión de líneas" + +#: flatcamGUI/PreferencesUI.py:8585 flatcamTools/ToolInvertGerber.py:103 +msgid "" +"The way that the lines in the object outline will be joined.\n" +"Can be:\n" +"- rounded -> an arc is added between two joining lines\n" +"- square -> the lines meet in 90 degrees angle\n" +"- bevel -> the lines are joined by a third line" +msgstr "" +"La forma en que se unirán las líneas en el contorno del objeto.\n" +"Puede ser:\n" +"- redondeado -> se agrega un arco entre dos líneas de unión\n" +"- cuadrado -> las líneas se encuentran en un ángulo de 90 grados\n" +"- bisel -> las líneas están unidas por una tercera línea" + +#: flatcamGUI/PreferencesUI.py:8608 msgid "Excellon File associations" msgstr "Excellon File asociaciones" -#: flatcamGUI/PreferencesUI.py:7633 flatcamGUI/PreferencesUI.py:7706 -#: flatcamGUI/PreferencesUI.py:7776 flatcamGUI/PreferencesUI.py:7846 +#: flatcamGUI/PreferencesUI.py:8621 flatcamGUI/PreferencesUI.py:8694 +#: flatcamGUI/PreferencesUI.py:8764 flatcamGUI/PreferencesUI.py:8834 msgid "Restore" msgstr "Restaurar" -#: flatcamGUI/PreferencesUI.py:7634 flatcamGUI/PreferencesUI.py:7707 -#: flatcamGUI/PreferencesUI.py:7777 +#: flatcamGUI/PreferencesUI.py:8622 flatcamGUI/PreferencesUI.py:8695 +#: flatcamGUI/PreferencesUI.py:8765 msgid "Restore the extension list to the default state." msgstr "Restaurar la lista de extensiones al estado predeterminado." -#: flatcamGUI/PreferencesUI.py:7635 flatcamGUI/PreferencesUI.py:7708 -#: flatcamGUI/PreferencesUI.py:7778 flatcamGUI/PreferencesUI.py:7848 +#: flatcamGUI/PreferencesUI.py:8623 flatcamGUI/PreferencesUI.py:8696 +#: flatcamGUI/PreferencesUI.py:8766 flatcamGUI/PreferencesUI.py:8836 msgid "Delete All" msgstr "Eliminar todosEliminar taladro" -#: flatcamGUI/PreferencesUI.py:7636 flatcamGUI/PreferencesUI.py:7709 -#: flatcamGUI/PreferencesUI.py:7779 +#: flatcamGUI/PreferencesUI.py:8624 flatcamGUI/PreferencesUI.py:8697 +#: flatcamGUI/PreferencesUI.py:8767 msgid "Delete all extensions from the list." msgstr "Eliminar todas las extensiones de la lista." -#: flatcamGUI/PreferencesUI.py:7644 flatcamGUI/PreferencesUI.py:7717 -#: flatcamGUI/PreferencesUI.py:7787 +#: flatcamGUI/PreferencesUI.py:8632 flatcamGUI/PreferencesUI.py:8705 +#: flatcamGUI/PreferencesUI.py:8775 msgid "Extensions list" msgstr "Lista de extensiones" -#: flatcamGUI/PreferencesUI.py:7646 flatcamGUI/PreferencesUI.py:7719 -#: flatcamGUI/PreferencesUI.py:7789 +#: flatcamGUI/PreferencesUI.py:8634 flatcamGUI/PreferencesUI.py:8707 +#: flatcamGUI/PreferencesUI.py:8777 msgid "" "List of file extensions to be\n" "associated with FlatCAM." @@ -12732,43 +13369,43 @@ msgstr "" "Lista de extensiones de archivo para ser\n" "asociado con FlatCAM." -#: flatcamGUI/PreferencesUI.py:7666 flatcamGUI/PreferencesUI.py:7739 -#: flatcamGUI/PreferencesUI.py:7808 flatcamGUI/PreferencesUI.py:7880 +#: flatcamGUI/PreferencesUI.py:8654 flatcamGUI/PreferencesUI.py:8727 +#: flatcamGUI/PreferencesUI.py:8796 flatcamGUI/PreferencesUI.py:8868 msgid "Extension" msgstr "ExtensiónLista de extensiones" -#: flatcamGUI/PreferencesUI.py:7667 flatcamGUI/PreferencesUI.py:7740 -#: flatcamGUI/PreferencesUI.py:7809 +#: flatcamGUI/PreferencesUI.py:8655 flatcamGUI/PreferencesUI.py:8728 +#: flatcamGUI/PreferencesUI.py:8797 msgid "A file extension to be added or deleted to the list." msgstr "Una extensión de archivo para agregar o eliminar a la lista." -#: flatcamGUI/PreferencesUI.py:7675 flatcamGUI/PreferencesUI.py:7748 -#: flatcamGUI/PreferencesUI.py:7817 +#: flatcamGUI/PreferencesUI.py:8663 flatcamGUI/PreferencesUI.py:8736 +#: flatcamGUI/PreferencesUI.py:8805 msgid "Add Extension" msgstr "Agregar extensión" -#: flatcamGUI/PreferencesUI.py:7676 flatcamGUI/PreferencesUI.py:7749 -#: flatcamGUI/PreferencesUI.py:7818 +#: flatcamGUI/PreferencesUI.py:8664 flatcamGUI/PreferencesUI.py:8737 +#: flatcamGUI/PreferencesUI.py:8806 msgid "Add a file extension to the list" msgstr "Agregar una extensión de archivo a la lista" -#: flatcamGUI/PreferencesUI.py:7677 flatcamGUI/PreferencesUI.py:7750 -#: flatcamGUI/PreferencesUI.py:7819 +#: flatcamGUI/PreferencesUI.py:8665 flatcamGUI/PreferencesUI.py:8738 +#: flatcamGUI/PreferencesUI.py:8807 msgid "Delete Extension" msgstr "Eliminar extensión" -#: flatcamGUI/PreferencesUI.py:7678 flatcamGUI/PreferencesUI.py:7751 -#: flatcamGUI/PreferencesUI.py:7820 +#: flatcamGUI/PreferencesUI.py:8666 flatcamGUI/PreferencesUI.py:8739 +#: flatcamGUI/PreferencesUI.py:8808 msgid "Delete a file extension from the list" msgstr "Eliminar una extensión de archivo de la lista" -#: flatcamGUI/PreferencesUI.py:7685 flatcamGUI/PreferencesUI.py:7758 -#: flatcamGUI/PreferencesUI.py:7827 +#: flatcamGUI/PreferencesUI.py:8673 flatcamGUI/PreferencesUI.py:8746 +#: flatcamGUI/PreferencesUI.py:8815 msgid "Apply Association" msgstr "Aplicar asociación" -#: flatcamGUI/PreferencesUI.py:7686 flatcamGUI/PreferencesUI.py:7759 -#: flatcamGUI/PreferencesUI.py:7828 +#: flatcamGUI/PreferencesUI.py:8674 flatcamGUI/PreferencesUI.py:8747 +#: flatcamGUI/PreferencesUI.py:8816 msgid "" "Apply the file associations between\n" "FlatCAM and the files with above extensions.\n" @@ -12780,33 +13417,33 @@ msgstr "" "Estarán activos después del próximo inicio de sesión.\n" "Esto funciona solo en Windows." -#: flatcamGUI/PreferencesUI.py:7703 +#: flatcamGUI/PreferencesUI.py:8691 msgid "GCode File associations" msgstr "Asociaciones de archivos GCode" -#: flatcamGUI/PreferencesUI.py:7773 +#: flatcamGUI/PreferencesUI.py:8761 msgid "Gerber File associations" msgstr "Asociaciones de archivos Gerber" -#: flatcamGUI/PreferencesUI.py:7843 +#: flatcamGUI/PreferencesUI.py:8831 msgid "Autocompleter Keywords" msgstr "Palabras clave de autocompletador" -#: flatcamGUI/PreferencesUI.py:7847 +#: flatcamGUI/PreferencesUI.py:8835 msgid "Restore the autocompleter keywords list to the default state." msgstr "" "Restaure la lista de palabras clave de autocompletador al estado " "predeterminado." -#: flatcamGUI/PreferencesUI.py:7849 +#: flatcamGUI/PreferencesUI.py:8837 msgid "Delete all autocompleter keywords from the list." msgstr "Elimine todas las palabras clave de autocompletador de la lista." -#: flatcamGUI/PreferencesUI.py:7857 +#: flatcamGUI/PreferencesUI.py:8845 msgid "Keywords list" msgstr "Lista de palabras clave" -#: flatcamGUI/PreferencesUI.py:7859 +#: flatcamGUI/PreferencesUI.py:8847 msgid "" "List of keywords used by\n" "the autocompleter in FlatCAM.\n" @@ -12818,31 +13455,31 @@ msgstr "" "El autocompletador está instalado\n" "en el Editor de Código y para el Tcl Shell." -#: flatcamGUI/PreferencesUI.py:7881 +#: flatcamGUI/PreferencesUI.py:8869 msgid "A keyword to be added or deleted to the list." msgstr "Una palabra clave para agregar o eliminar a la lista." -#: flatcamGUI/PreferencesUI.py:7889 +#: flatcamGUI/PreferencesUI.py:8877 msgid "Add keyword" msgstr "Agregar palabra clave" -#: flatcamGUI/PreferencesUI.py:7890 +#: flatcamGUI/PreferencesUI.py:8878 msgid "Add a keyword to the list" msgstr "Agregar una palabra clave a la lista" -#: flatcamGUI/PreferencesUI.py:7891 +#: flatcamGUI/PreferencesUI.py:8879 msgid "Delete keyword" msgstr "Eliminar palabra clave" -#: flatcamGUI/PreferencesUI.py:7892 +#: flatcamGUI/PreferencesUI.py:8880 msgid "Delete a keyword from the list" msgstr "Eliminar una palabra clave de la lista" -#: flatcamParsers/ParseExcellon.py:314 +#: flatcamParsers/ParseExcellon.py:315 msgid "This is GCODE mark" msgstr "Esta es la marca GCODE" -#: flatcamParsers/ParseExcellon.py:431 +#: flatcamParsers/ParseExcellon.py:432 msgid "" "No tool diameter info's. See shell.\n" "A tool change event: T" @@ -12850,7 +13487,7 @@ msgstr "" "No hay información de diámetro de herramienta. Ver caparazón.\n" "Un evento de cambio de herramienta: T" -#: flatcamParsers/ParseExcellon.py:434 +#: flatcamParsers/ParseExcellon.py:435 msgid "" "was found but the Excellon file have no informations regarding the tool " "diameters therefore the application will try to load it by using some 'fake' " @@ -12864,13 +13501,13 @@ msgstr "" "El usuario necesita editar el objeto Excellon resultante y cambiar los " "diámetros para reflejar los diámetros reales." -#: flatcamParsers/ParseExcellon.py:886 flatcamTools/ToolSolderPaste.py:1330 +#: flatcamParsers/ParseExcellon.py:897 flatcamTools/ToolSolderPaste.py:1327 msgid "An internal error has ocurred. See shell.\n" msgstr "" "Ha ocurrido un error interno. Ver caparazón.\n" "\n" -#: flatcamParsers/ParseExcellon.py:889 +#: flatcamParsers/ParseExcellon.py:900 msgid "" "Excellon Parser error.\n" "Parsing Failed. Line" @@ -12878,7 +13515,7 @@ msgstr "" "Error del analizador Excellon.\n" "El análisis falló. Línea" -#: flatcamParsers/ParseExcellon.py:973 +#: flatcamParsers/ParseExcellon.py:982 msgid "" "Excellon.create_geometry() -> a drill location was skipped due of not having " "a tool associated.\n" @@ -12896,22 +13533,22 @@ msgstr "Fuente no compatible, prueba con otra." msgid "Gerber processing. Parsing" msgstr "Procesamiento de Gerber. Analizando" -#: flatcamParsers/ParseGerber.py:426 flatcamParsers/ParseHPGL2.py:176 +#: flatcamParsers/ParseGerber.py:426 flatcamParsers/ParseHPGL2.py:178 msgid "lines" msgstr "líneas" -#: flatcamParsers/ParseGerber.py:970 flatcamParsers/ParseGerber.py:1065 -#: flatcamParsers/ParseHPGL2.py:269 flatcamParsers/ParseHPGL2.py:283 -#: flatcamParsers/ParseHPGL2.py:302 flatcamParsers/ParseHPGL2.py:326 -#: flatcamParsers/ParseHPGL2.py:361 +#: flatcamParsers/ParseGerber.py:1002 flatcamParsers/ParseGerber.py:1102 +#: flatcamParsers/ParseHPGL2.py:271 flatcamParsers/ParseHPGL2.py:285 +#: flatcamParsers/ParseHPGL2.py:304 flatcamParsers/ParseHPGL2.py:328 +#: flatcamParsers/ParseHPGL2.py:363 msgid "Coordinates missing, line ignored" msgstr "Coordenadas faltantes, línea ignorada" -#: flatcamParsers/ParseGerber.py:972 flatcamParsers/ParseGerber.py:1067 +#: flatcamParsers/ParseGerber.py:1004 flatcamParsers/ParseGerber.py:1104 msgid "GERBER file might be CORRUPT. Check the file !!!" msgstr "GERBER archivo podría ser Dañado. Revisa el archivo !!!" -#: flatcamParsers/ParseGerber.py:1021 +#: flatcamParsers/ParseGerber.py:1058 msgid "" "Region does not have enough points. File will be processed but there are " "parser errors. Line number" @@ -12919,66 +13556,214 @@ msgstr "" "Región no tiene suficientes puntos. El archivo será procesado pero hay " "errores del analizador. Línea de números: %s" -#: flatcamParsers/ParseGerber.py:1421 flatcamParsers/ParseHPGL2.py:396 +#: flatcamParsers/ParseGerber.py:1488 flatcamParsers/ParseHPGL2.py:398 msgid "Gerber processing. Joining polygons" msgstr "Procesamiento de Gerber. Unir polígonos" -#: flatcamParsers/ParseGerber.py:1438 +#: flatcamParsers/ParseGerber.py:1505 msgid "Gerber processing. Applying Gerber polarity." msgstr "Procesamiento de Gerber. Aplicando la polaridad de Gerber." -#: flatcamParsers/ParseGerber.py:1498 +#: flatcamParsers/ParseGerber.py:1565 msgid "Gerber Line" msgstr "Linea Gerber" -#: flatcamParsers/ParseGerber.py:1498 +#: flatcamParsers/ParseGerber.py:1565 msgid "Gerber Line Content" msgstr "Contenido de la línea Gerber" -#: flatcamParsers/ParseGerber.py:1500 +#: flatcamParsers/ParseGerber.py:1567 msgid "Gerber Parser ERROR" msgstr "Analizador Gerber ERROR" -#: flatcamParsers/ParseGerber.py:1884 +#: flatcamParsers/ParseGerber.py:1956 msgid "Gerber Scale done." msgstr "Escala de Gerber hecha." -#: flatcamParsers/ParseGerber.py:1977 +#: flatcamParsers/ParseGerber.py:2049 msgid "Gerber Offset done." msgstr "Gerber Offset hecho." -#: flatcamParsers/ParseGerber.py:2054 +#: flatcamParsers/ParseGerber.py:2126 msgid "Gerber Mirror done." msgstr "Espejo Gerber hecho." -#: flatcamParsers/ParseGerber.py:2128 +#: flatcamParsers/ParseGerber.py:2200 msgid "Gerber Skew done." msgstr "Gerber Sesgo hecho." -#: flatcamParsers/ParseGerber.py:2192 +#: flatcamParsers/ParseGerber.py:2263 msgid "Gerber Rotate done." msgstr "Rotar Gerber hecho." -#: flatcamParsers/ParseGerber.py:2273 +#: flatcamParsers/ParseGerber.py:2419 msgid "Gerber Buffer done." msgstr "Gerber Buffer hecho." -#: flatcamParsers/ParseHPGL2.py:176 +#: flatcamParsers/ParseHPGL2.py:178 msgid "HPGL2 processing. Parsing" msgstr "Procesamiento de HPGL2 . Analizando" -#: flatcamParsers/ParseHPGL2.py:408 +#: flatcamParsers/ParseHPGL2.py:410 msgid "HPGL2 Line" msgstr "Línea HPGL2" -#: flatcamParsers/ParseHPGL2.py:408 +#: flatcamParsers/ParseHPGL2.py:410 msgid "HPGL2 Line Content" msgstr "Contenido de línea HPGL2" -#: flatcamParsers/ParseHPGL2.py:409 +#: flatcamParsers/ParseHPGL2.py:411 msgid "HPGL2 Parser ERROR" msgstr "Analizador HPGL2 ERROR" +#: flatcamTools/ToolAlignObjects.py:32 +msgid "Align Objects" +msgstr "Alinear objetos" + +#: flatcamTools/ToolAlignObjects.py:61 +msgid "MOVING object" +msgstr "Objeto en movimiento" + +#: flatcamTools/ToolAlignObjects.py:65 +msgid "" +"Specify the type of object to be aligned.\n" +"It can be of type: Gerber or Excellon.\n" +"The selection here decide the type of objects that will be\n" +"in the Object combobox." +msgstr "" +"Especifique el tipo de objeto a alinear.\n" +"Puede ser de tipo: Gerber o Excellon.\n" +"La selección aquí decide el tipo de objetos que serán\n" +"en el cuadro combinado Objeto." + +#: flatcamTools/ToolAlignObjects.py:86 +msgid "Object to be aligned." +msgstr "Objeto a alinear." + +#: flatcamTools/ToolAlignObjects.py:98 +msgid "TARGET object" +msgstr "Objeto OBJETIVO" + +#: flatcamTools/ToolAlignObjects.py:100 +msgid "" +"Specify the type of object to be aligned to.\n" +"It can be of type: Gerber or Excellon.\n" +"The selection here decide the type of objects that will be\n" +"in the Object combobox." +msgstr "" +"Especifique el tipo de objeto a alinear.\n" +"Puede ser de tipo: Gerber o Excellon.\n" +"La selección aquí decide el tipo de objetos que serán\n" +"en el cuadro combinado Objeto." + +#: flatcamTools/ToolAlignObjects.py:122 +msgid "Object to be aligned to. Aligner." +msgstr "Objeto a alinear. Alineador." + +#: flatcamTools/ToolAlignObjects.py:135 +msgid "Alignment Type" +msgstr "Tipo de alineación" + +#: flatcamTools/ToolAlignObjects.py:137 +msgid "" +"The type of alignment can be:\n" +"- Single Point -> it require a single point of sync, the action will be a " +"translation\n" +"- Dual Point -> it require two points of sync, the action will be " +"translation followed by rotation" +msgstr "" +"El tipo de alineación puede ser:\n" +"- Punto único -> requiere un único punto de sincronización, la acción será " +"una traducción\n" +"- Punto doble -> requiere dos puntos de sincronización, la acción será " +"traslación seguida de rotación" + +#: flatcamTools/ToolAlignObjects.py:143 +msgid "Single Point" +msgstr "Punto único" + +#: flatcamTools/ToolAlignObjects.py:144 +msgid "Dual Point" +msgstr "Punto doble" + +#: flatcamTools/ToolAlignObjects.py:159 +msgid "Align Object" +msgstr "Alinear objeto" + +#: flatcamTools/ToolAlignObjects.py:161 +msgid "" +"Align the specified object to the aligner object.\n" +"If only one point is used then it assumes translation.\n" +"If tho points are used it assume translation and rotation." +msgstr "" +"Alinee el objeto especificado con el objeto alineador.\n" +"Si solo se utiliza un punto, se supone que se traduce.\n" +"Si se utilizan estos puntos, se supone traslación y rotación." + +#: flatcamTools/ToolAlignObjects.py:176 flatcamTools/ToolCalculators.py:246 +#: flatcamTools/ToolCalibration.py:683 flatcamTools/ToolCopperThieving.py:485 +#: flatcamTools/ToolCutOut.py:372 flatcamTools/ToolDblSided.py:472 +#: flatcamTools/ToolExtractDrills.py:310 flatcamTools/ToolFiducials.py:318 +#: flatcamTools/ToolFilm.py:520 flatcamTools/ToolInvertGerber.py:140 +#: flatcamTools/ToolNCC.py:612 flatcamTools/ToolOptimal.py:238 +#: flatcamTools/ToolPaint.py:556 flatcamTools/ToolPanelize.py:269 +#: flatcamTools/ToolPunchGerber.py:339 flatcamTools/ToolQRCode.py:314 +#: flatcamTools/ToolRulesCheck.py:516 flatcamTools/ToolSolderPaste.py:474 +#: flatcamTools/ToolSub.py:176 flatcamTools/ToolTransform.py:399 +msgid "Reset Tool" +msgstr "Restablecer la Herramienta" + +#: flatcamTools/ToolAlignObjects.py:178 flatcamTools/ToolCalculators.py:248 +#: flatcamTools/ToolCalibration.py:685 flatcamTools/ToolCopperThieving.py:487 +#: flatcamTools/ToolCutOut.py:374 flatcamTools/ToolDblSided.py:474 +#: flatcamTools/ToolExtractDrills.py:312 flatcamTools/ToolFiducials.py:320 +#: flatcamTools/ToolFilm.py:522 flatcamTools/ToolInvertGerber.py:142 +#: flatcamTools/ToolNCC.py:614 flatcamTools/ToolOptimal.py:240 +#: flatcamTools/ToolPaint.py:558 flatcamTools/ToolPanelize.py:271 +#: flatcamTools/ToolPunchGerber.py:341 flatcamTools/ToolQRCode.py:316 +#: flatcamTools/ToolRulesCheck.py:518 flatcamTools/ToolSolderPaste.py:476 +#: flatcamTools/ToolSub.py:178 flatcamTools/ToolTransform.py:401 +msgid "Will reset the tool parameters." +msgstr "Restablecerá los parámetros de la herramienta." + +#: flatcamTools/ToolAlignObjects.py:244 +msgid "Align Tool" +msgstr "Herram. de Alineación" + +#: flatcamTools/ToolAlignObjects.py:289 +msgid "There is no aligned FlatCAM object selected..." +msgstr "No hay ningún objeto FlatCAM alineado seleccionado ..." + +#: flatcamTools/ToolAlignObjects.py:299 +msgid "There is no aligner FlatCAM object selected..." +msgstr "No hay ningún objeto FlatCAM alineador seleccionado ..." + +#: flatcamTools/ToolAlignObjects.py:325 flatcamTools/ToolAlignObjects.py:385 +msgid "First Point" +msgstr "Primer Punto" + +#: flatcamTools/ToolAlignObjects.py:325 flatcamTools/ToolAlignObjects.py:400 +msgid "Click on the START point." +msgstr "Haga clic en el punto de INICIO." + +#: flatcamTools/ToolAlignObjects.py:380 flatcamTools/ToolCalibration.py:920 +msgid "Cancelled by user request." +msgstr "Cancelado por solicitud del usuario." + +#: flatcamTools/ToolAlignObjects.py:385 flatcamTools/ToolAlignObjects.py:407 +msgid "Click on the DESTINATION point." +msgstr "Haga clic en el punto DESTINO." + +#: flatcamTools/ToolAlignObjects.py:385 flatcamTools/ToolAlignObjects.py:400 +#: flatcamTools/ToolAlignObjects.py:407 +msgid " Or right click to cancel." +msgstr " O haga clic derecho para cancelar." + +#: flatcamTools/ToolAlignObjects.py:400 flatcamTools/ToolAlignObjects.py:407 +#: flatcamTools/ToolFiducials.py:111 +msgid "Second Point" +msgstr "Segundo punto" + #: flatcamTools/ToolCalculators.py:24 msgid "Calculators" msgstr "Calculadoras" @@ -13065,7 +13850,7 @@ msgstr "" "Calcule el valor de intensidad actual y el tiempo del procedimiento,\n" "dependiendo de los parámetros anteriores" -#: flatcamTools/ToolCalculators.py:285 +#: flatcamTools/ToolCalculators.py:299 msgid "Calc. Tool" msgstr "Calc. Herramienta" @@ -13091,82 +13876,78 @@ msgstr "" "Esos cuatro puntos deberían estar en los cuatro\n" "(tanto como sea posible) esquinas del objeto." -#: flatcamTools/ToolCalibration.py:193 flatcamTools/ToolCutOut.py:80 -#: flatcamTools/ToolFilm.py:78 flatcamTools/ToolImage.py:55 -#: flatcamTools/ToolPanelize.py:66 flatcamTools/ToolProperties.py:169 +#: flatcamTools/ToolCalibration.py:193 flatcamTools/ToolFilm.py:76 +#: flatcamTools/ToolImage.py:54 flatcamTools/ToolPanelize.py:78 +#: flatcamTools/ToolProperties.py:177 msgid "Object Type" msgstr "Tipo de objeto" -#: flatcamTools/ToolCalibration.py:211 +#: flatcamTools/ToolCalibration.py:210 msgid "Source object selection" msgstr "Selección de objeto de origen" -#: flatcamTools/ToolCalibration.py:213 +#: flatcamTools/ToolCalibration.py:212 msgid "FlatCAM Object to be used as a source for reference points." msgstr "Objeto FlatCAM que se utilizará como fuente de puntos de referencia." -#: flatcamTools/ToolCalibration.py:219 +#: flatcamTools/ToolCalibration.py:218 msgid "Calibration Points" msgstr "Puntos de calibración" -#: flatcamTools/ToolCalibration.py:221 +#: flatcamTools/ToolCalibration.py:220 msgid "" "Contain the expected calibration points and the\n" "ones measured." msgstr "" "Contiene los puntos de calibración esperados y el\n" -"los medidos" +"los medidos." -#: flatcamTools/ToolCalibration.py:236 flatcamTools/ToolSub.py:74 -#: flatcamTools/ToolSub.py:126 +#: flatcamTools/ToolCalibration.py:235 flatcamTools/ToolSub.py:76 +#: flatcamTools/ToolSub.py:131 msgid "Target" msgstr "Objetivo" -#: flatcamTools/ToolCalibration.py:237 +#: flatcamTools/ToolCalibration.py:236 msgid "Found Delta" msgstr "Delta encontrado" -#: flatcamTools/ToolCalibration.py:249 +#: flatcamTools/ToolCalibration.py:248 msgid "Bot Left X" msgstr "Abajo a la izquierda X" -#: flatcamTools/ToolCalibration.py:258 +#: flatcamTools/ToolCalibration.py:257 msgid "Bot Left Y" msgstr "Abajo a la izquierda Y" -#: flatcamTools/ToolCalibration.py:266 flatcamTools/ToolCalibration.py:267 -msgid "Origin" -msgstr "Origen" - -#: flatcamTools/ToolCalibration.py:278 +#: flatcamTools/ToolCalibration.py:275 msgid "Bot Right X" msgstr "Abajo a la derecho X" -#: flatcamTools/ToolCalibration.py:288 +#: flatcamTools/ToolCalibration.py:285 msgid "Bot Right Y" msgstr "Abajo a la derecho Y" -#: flatcamTools/ToolCalibration.py:303 +#: flatcamTools/ToolCalibration.py:300 msgid "Top Left X" msgstr "Arriba a la izquierda X" -#: flatcamTools/ToolCalibration.py:312 +#: flatcamTools/ToolCalibration.py:309 msgid "Top Left Y" msgstr "Arriba a la izquierda Y" -#: flatcamTools/ToolCalibration.py:327 +#: flatcamTools/ToolCalibration.py:324 msgid "Top Right X" msgstr "Arriba a la derecho X" -#: flatcamTools/ToolCalibration.py:337 +#: flatcamTools/ToolCalibration.py:334 msgid "Top Right Y" msgstr "Arriba a la derecho Y" -#: flatcamTools/ToolCalibration.py:370 +#: flatcamTools/ToolCalibration.py:367 msgid "Get Points" msgstr "Obtener puntos" -#: flatcamTools/ToolCalibration.py:372 +#: flatcamTools/ToolCalibration.py:369 msgid "" "Pick four points by clicking on canvas if the source choice\n" "is 'free' or inside the object geometry if the source is 'object'.\n" @@ -13179,11 +13960,11 @@ msgstr "" "Esos cuatro puntos deben estar en los cuatro cuadrados de\n" "el objeto." -#: flatcamTools/ToolCalibration.py:393 +#: flatcamTools/ToolCalibration.py:390 msgid "STEP 2: Verification GCode" msgstr "PASO 2: Verificación GCode" -#: flatcamTools/ToolCalibration.py:395 flatcamTools/ToolCalibration.py:408 +#: flatcamTools/ToolCalibration.py:392 flatcamTools/ToolCalibration.py:405 msgid "" "Generate GCode file to locate and align the PCB by using\n" "the four points acquired above.\n" @@ -13203,15 +13984,15 @@ msgstr "" "a la derecha.\n" "- cuarto punto -> punto de verificación final. Solo para evaluación." -#: flatcamTools/ToolCalibration.py:406 flatcamTools/ToolSolderPaste.py:347 +#: flatcamTools/ToolCalibration.py:403 flatcamTools/ToolSolderPaste.py:349 msgid "Generate GCode" msgstr "Generar GCode" -#: flatcamTools/ToolCalibration.py:432 +#: flatcamTools/ToolCalibration.py:429 msgid "STEP 3: Adjustments" msgstr "PASO 3: Ajustes" -#: flatcamTools/ToolCalibration.py:434 flatcamTools/ToolCalibration.py:443 +#: flatcamTools/ToolCalibration.py:431 flatcamTools/ToolCalibration.py:440 msgid "" "Calculate Scale and Skew factors based on the differences (delta)\n" "found when checking the PCB pattern. The differences must be filled\n" @@ -13221,15 +14002,15 @@ msgstr "" "encontrado al verificar el patrón de PCB. Las diferencias deben llenarse\n" "en los campos encontrados (Delta)." -#: flatcamTools/ToolCalibration.py:441 +#: flatcamTools/ToolCalibration.py:438 msgid "Calculate Factors" msgstr "Calcular factores" -#: flatcamTools/ToolCalibration.py:463 +#: flatcamTools/ToolCalibration.py:460 msgid "STEP 4: Adjusted GCode" msgstr "PASO 4: Código GC ajustado" -#: flatcamTools/ToolCalibration.py:465 +#: flatcamTools/ToolCalibration.py:462 msgid "" "Generate verification GCode file adjusted with\n" "the factors above." @@ -13237,43 +14018,43 @@ msgstr "" "Generar un archivo GCode de verificación ajustado con\n" "Los factores anteriores." -#: flatcamTools/ToolCalibration.py:470 +#: flatcamTools/ToolCalibration.py:467 msgid "Scale Factor X:" msgstr "Factor de escala X:" -#: flatcamTools/ToolCalibration.py:482 +#: flatcamTools/ToolCalibration.py:479 msgid "Scale Factor Y:" msgstr "Factor de escala Y:" -#: flatcamTools/ToolCalibration.py:494 +#: flatcamTools/ToolCalibration.py:491 msgid "Apply Scale Factors" msgstr "Aplicar factores de escala" -#: flatcamTools/ToolCalibration.py:496 +#: flatcamTools/ToolCalibration.py:493 msgid "Apply Scale factors on the calibration points." msgstr "Aplicar factores de escala en los puntos de calibración." -#: flatcamTools/ToolCalibration.py:506 +#: flatcamTools/ToolCalibration.py:503 msgid "Skew Angle X:" msgstr "Ángulo de Sesgar X:" -#: flatcamTools/ToolCalibration.py:519 +#: flatcamTools/ToolCalibration.py:516 msgid "Skew Angle Y:" msgstr "Ángulo de Sesgar Y:" -#: flatcamTools/ToolCalibration.py:532 +#: flatcamTools/ToolCalibration.py:529 msgid "Apply Skew Factors" msgstr "Aplicar factores Sesgados" -#: flatcamTools/ToolCalibration.py:534 +#: flatcamTools/ToolCalibration.py:531 msgid "Apply Skew factors on the calibration points." msgstr "Aplicar factores de inclinación en los puntos de calibración." -#: flatcamTools/ToolCalibration.py:603 +#: flatcamTools/ToolCalibration.py:600 msgid "Generate Adjusted GCode" msgstr "Generar código GC ajustado" -#: flatcamTools/ToolCalibration.py:605 +#: flatcamTools/ToolCalibration.py:602 msgid "" "Generate verification GCode file adjusted with\n" "the factors set above.\n" @@ -13285,11 +14066,11 @@ msgstr "" "Los parámetros GCode se pueden reajustar\n" "antes de hacer clic en este botón." -#: flatcamTools/ToolCalibration.py:626 +#: flatcamTools/ToolCalibration.py:623 msgid "STEP 5: Calibrate FlatCAM Objects" msgstr "PASO 5: Calibrar objetos FlatCAM" -#: flatcamTools/ToolCalibration.py:628 +#: flatcamTools/ToolCalibration.py:625 msgid "" "Adjust the FlatCAM objects\n" "with the factors determined and verified above." @@ -13297,27 +14078,27 @@ msgstr "" "Ajuste los objetos FlatCAM\n" "con los factores determinados y verificados anteriormente." -#: flatcamTools/ToolCalibration.py:641 +#: flatcamTools/ToolCalibration.py:637 msgid "Adjusted object type" msgstr "Tipo de objeto ajustado" -#: flatcamTools/ToolCalibration.py:643 +#: flatcamTools/ToolCalibration.py:638 msgid "Type of the FlatCAM Object to be adjusted." msgstr "Tipo del objeto FlatCAM que se ajustará." -#: flatcamTools/ToolCalibration.py:654 +#: flatcamTools/ToolCalibration.py:651 msgid "Adjusted object selection" msgstr "Selección de objeto ajustada" -#: flatcamTools/ToolCalibration.py:656 +#: flatcamTools/ToolCalibration.py:653 msgid "The FlatCAM Object to be adjusted." msgstr "El objeto FlatCAM a ajustar." -#: flatcamTools/ToolCalibration.py:663 +#: flatcamTools/ToolCalibration.py:660 msgid "Calibrate" msgstr "Calibrar" -#: flatcamTools/ToolCalibration.py:665 +#: flatcamTools/ToolCalibration.py:662 msgid "" "Adjust (scale and/or skew) the objects\n" "with the factors determined above." @@ -13325,83 +14106,63 @@ msgstr "" "Ajustar (escalar y / o sesgar) los objetos\n" "con los factores determinados anteriormente." -#: flatcamTools/ToolCalibration.py:686 flatcamTools/ToolCopperThieving.py:482 -#: flatcamTools/ToolCutOut.py:362 flatcamTools/ToolDblSided.py:405 -#: flatcamTools/ToolFiducials.py:316 flatcamTools/ToolFilm.py:518 -#: flatcamTools/ToolNonCopperClear.py:486 flatcamTools/ToolOptimal.py:237 -#: flatcamTools/ToolPaint.py:372 flatcamTools/ToolPanelize.py:266 -#: flatcamTools/ToolQRCode.py:314 flatcamTools/ToolRulesCheck.py:507 -#: flatcamTools/ToolSolderPaste.py:470 flatcamTools/ToolSub.py:170 -msgid "Reset Tool" -msgstr "Restablecer la Herramienta" +#: flatcamTools/ToolCalibration.py:770 flatcamTools/ToolCalibration.py:771 +msgid "Origin" +msgstr "Origen" -#: flatcamTools/ToolCalibration.py:688 flatcamTools/ToolCopperThieving.py:484 -#: flatcamTools/ToolCutOut.py:364 flatcamTools/ToolDblSided.py:407 -#: flatcamTools/ToolFiducials.py:318 flatcamTools/ToolFilm.py:520 -#: flatcamTools/ToolNonCopperClear.py:488 flatcamTools/ToolOptimal.py:239 -#: flatcamTools/ToolPaint.py:374 flatcamTools/ToolPanelize.py:268 -#: flatcamTools/ToolQRCode.py:316 flatcamTools/ToolRulesCheck.py:509 -#: flatcamTools/ToolSolderPaste.py:472 flatcamTools/ToolSub.py:172 -msgid "Will reset the tool parameters." -msgstr "Restablecerá los parámetros de la herramienta." - -#: flatcamTools/ToolCalibration.py:792 +#: flatcamTools/ToolCalibration.py:800 msgid "Tool initialized" msgstr "Herramienta inicializada" -#: flatcamTools/ToolCalibration.py:824 +#: flatcamTools/ToolCalibration.py:838 msgid "There is no source FlatCAM object selected..." msgstr "No hay ningún objeto FlatCAM de origen seleccionado ..." -#: flatcamTools/ToolCalibration.py:845 +#: flatcamTools/ToolCalibration.py:859 msgid "Get First calibration point. Bottom Left..." msgstr "Obtenga el primer punto de calibración. Abajo a la izquierda ..." -#: flatcamTools/ToolCalibration.py:906 -msgid "Cancelled by user request." -msgstr "Cancelado por solicitud del usuario." - -#: flatcamTools/ToolCalibration.py:912 +#: flatcamTools/ToolCalibration.py:926 msgid "Get Second calibration point. Bottom Right (Top Left)..." msgstr "" "Obtenga el segundo punto de calibración. Abajo a la derecha (arriba a la " "izquierda) ..." -#: flatcamTools/ToolCalibration.py:916 +#: flatcamTools/ToolCalibration.py:930 msgid "Get Third calibration point. Top Left (Bottom Right)..." msgstr "" "Obtenga el tercer punto de calibración. Arriba a la izquierda, abajo a la " "derecha)..." -#: flatcamTools/ToolCalibration.py:920 +#: flatcamTools/ToolCalibration.py:934 msgid "Get Forth calibration point. Top Right..." msgstr "Obtenga el punto de calibración Forth. Parte superior derecha..." -#: flatcamTools/ToolCalibration.py:924 +#: flatcamTools/ToolCalibration.py:938 msgid "Done. All four points have been acquired." msgstr "Hecho. Los cuatro puntos han sido adquiridos." -#: flatcamTools/ToolCalibration.py:955 +#: flatcamTools/ToolCalibration.py:969 msgid "Verification GCode for FlatCAM Calibration Tool" msgstr "Verificación GCode para la herramienta de calibración FlatCAM" -#: flatcamTools/ToolCalibration.py:967 flatcamTools/ToolCalibration.py:1053 +#: flatcamTools/ToolCalibration.py:981 flatcamTools/ToolCalibration.py:1067 msgid "Gcode Viewer" msgstr "Visor de Gcode" -#: flatcamTools/ToolCalibration.py:983 +#: flatcamTools/ToolCalibration.py:997 msgid "Cancelled. Four points are needed for GCode generation." msgstr "Cancelado. Se necesitan cuatro puntos para la generación de GCode." -#: flatcamTools/ToolCalibration.py:1239 flatcamTools/ToolCalibration.py:1335 +#: flatcamTools/ToolCalibration.py:1253 flatcamTools/ToolCalibration.py:1349 msgid "There is no FlatCAM object selected..." msgstr "No hay ningún objeto FlatCAM seleccionado ..." -#: flatcamTools/ToolCopperThieving.py:76 flatcamTools/ToolFiducials.py:260 +#: flatcamTools/ToolCopperThieving.py:77 flatcamTools/ToolFiducials.py:261 msgid "Gerber Object to which will be added a copper thieving." msgstr "Gerber Objeto al que se agregará un Copper Thieving." -#: flatcamTools/ToolCopperThieving.py:98 +#: flatcamTools/ToolCopperThieving.py:99 msgid "" "This set the distance between the copper thieving components\n" "(the polygon fill may be split in multiple polygons)\n" @@ -13411,7 +14172,7 @@ msgstr "" "(el relleno de polígono puede dividirse en múltiples polígonos)\n" "y las rastros de cobre en el archivo Gerber." -#: flatcamTools/ToolCopperThieving.py:131 +#: flatcamTools/ToolCopperThieving.py:132 msgid "" "- 'Itself' - the copper thieving extent is based on the object extent.\n" "- 'Area Selection' - left mouse click to start selection of the area to be " @@ -13426,12 +14187,12 @@ msgstr "" "- 'Objeto de referencia': 'Copper Thieving' dentro del área especificada por " "otro objeto." -#: flatcamTools/ToolCopperThieving.py:138 -#: flatcamTools/ToolNonCopperClear.py:445 flatcamTools/ToolPaint.py:326 +#: flatcamTools/ToolCopperThieving.py:139 flatcamTools/ToolNCC.py:552 +#: flatcamTools/ToolPaint.py:496 msgid "Ref. Type" msgstr "Tipo de Ref" -#: flatcamTools/ToolCopperThieving.py:140 +#: flatcamTools/ToolCopperThieving.py:141 msgid "" "The type of FlatCAM object to be used as copper thieving reference.\n" "It can be Gerber, Excellon or Geometry." @@ -13440,37 +14201,22 @@ msgstr "" "Thieving'.\n" "Puede ser Gerber, Excellon o Geometry." -#: flatcamTools/ToolCopperThieving.py:144 flatcamTools/ToolDblSided.py:215 -#: flatcamTools/ToolNonCopperClear.py:451 flatcamTools/ToolPaint.py:332 -msgid "Reference Gerber" -msgstr "Gerber de referencia" - -#: flatcamTools/ToolCopperThieving.py:145 flatcamTools/ToolDblSided.py:216 -#: flatcamTools/ToolNonCopperClear.py:452 flatcamTools/ToolPaint.py:333 -msgid "Reference Excellon" -msgstr "Excellon de referencia" - -#: flatcamTools/ToolCopperThieving.py:146 flatcamTools/ToolDblSided.py:217 -#: flatcamTools/ToolNonCopperClear.py:453 flatcamTools/ToolPaint.py:334 -msgid "Reference Geometry" -msgstr "Geometría de referencia" - -#: flatcamTools/ToolCopperThieving.py:151 -#: flatcamTools/ToolNonCopperClear.py:456 flatcamTools/ToolPaint.py:337 +#: flatcamTools/ToolCopperThieving.py:150 flatcamTools/ToolNCC.py:562 +#: flatcamTools/ToolPaint.py:506 msgid "Ref. Object" msgstr "Objeto de Ref" -#: flatcamTools/ToolCopperThieving.py:153 -#: flatcamTools/ToolNonCopperClear.py:458 flatcamTools/ToolPaint.py:339 +#: flatcamTools/ToolCopperThieving.py:152 flatcamTools/ToolNCC.py:564 +#: flatcamTools/ToolPaint.py:508 msgid "The FlatCAM object to be used as non copper clearing reference." msgstr "" "El objeto FlatCAM que se utilizará como referencia de compensación sin cobre." -#: flatcamTools/ToolCopperThieving.py:326 +#: flatcamTools/ToolCopperThieving.py:328 msgid "Insert Copper thieving" msgstr "Insertar Copper thieving" -#: flatcamTools/ToolCopperThieving.py:328 +#: flatcamTools/ToolCopperThieving.py:330 msgid "" "Will add a polygon (may be split in multiple parts)\n" "that will surround the actual Gerber traces at a certain distance." @@ -13478,11 +14224,11 @@ msgstr "" "Agregará un polígono (puede dividirse en varias partes)\n" "eso rodeará las huellas reales de Gerber a cierta distancia." -#: flatcamTools/ToolCopperThieving.py:387 +#: flatcamTools/ToolCopperThieving.py:389 msgid "Insert Robber Bar" msgstr "Insertar Robber Bar" -#: flatcamTools/ToolCopperThieving.py:389 +#: flatcamTools/ToolCopperThieving.py:391 msgid "" "Will add a polygon with a defined thickness\n" "that will surround the actual Gerber object\n" @@ -13494,11 +14240,11 @@ msgstr "" "a cierta distancia.\n" "Se requiere cuando se hace un patrón de agujeros." -#: flatcamTools/ToolCopperThieving.py:413 +#: flatcamTools/ToolCopperThieving.py:415 msgid "Select Soldermask object" msgstr "Seleccionar objeto Soldermask" -#: flatcamTools/ToolCopperThieving.py:415 +#: flatcamTools/ToolCopperThieving.py:417 msgid "" "Gerber Object with the soldermask.\n" "It will be used as a base for\n" @@ -13508,11 +14254,11 @@ msgstr "" "Se utilizará como base para\n" "El patrón de la máscara de recubrimiento." -#: flatcamTools/ToolCopperThieving.py:443 +#: flatcamTools/ToolCopperThieving.py:446 msgid "Plated area" msgstr "Área chapada" -#: flatcamTools/ToolCopperThieving.py:445 +#: flatcamTools/ToolCopperThieving.py:448 msgid "" "The area to be plated by pattern plating.\n" "Basically is made from the openings in the plating mask.\n" @@ -13531,19 +14277,19 @@ msgstr "" "un poco más grande que las almohadillas de cobre, y esta área es\n" "calculado a partir de las aberturas de la máscara de soldadura." -#: flatcamTools/ToolCopperThieving.py:456 +#: flatcamTools/ToolCopperThieving.py:459 msgid "mm" msgstr "mm" -#: flatcamTools/ToolCopperThieving.py:458 +#: flatcamTools/ToolCopperThieving.py:461 msgid "in" msgstr "in" -#: flatcamTools/ToolCopperThieving.py:465 +#: flatcamTools/ToolCopperThieving.py:468 msgid "Generate pattern plating mask" msgstr "Generar máscara de recubrimiento de patrón" -#: flatcamTools/ToolCopperThieving.py:467 +#: flatcamTools/ToolCopperThieving.py:470 msgid "" "Will add to the soldermask gerber geometry\n" "the geometries of the copper thieving and/or\n" @@ -13553,137 +14299,138 @@ msgstr "" "Las geometrías de Copper Thieving y / o\n" "la Robber Bar si esos fueron generados." -#: flatcamTools/ToolCopperThieving.py:620 -#: flatcamTools/ToolCopperThieving.py:645 +#: flatcamTools/ToolCopperThieving.py:626 +#: flatcamTools/ToolCopperThieving.py:651 msgid "Lines Grid works only for 'itself' reference ..." msgstr "La cuadrícula de líneas funciona solo para referencia 'sí mismo' ..." -#: flatcamTools/ToolCopperThieving.py:631 +#: flatcamTools/ToolCopperThieving.py:637 msgid "Solid fill selected." msgstr "Relleno sólido seleccionado." -#: flatcamTools/ToolCopperThieving.py:636 +#: flatcamTools/ToolCopperThieving.py:642 msgid "Dots grid fill selected." msgstr "Relleno de cuadrícula de puntos seleccionado." -#: flatcamTools/ToolCopperThieving.py:641 +#: flatcamTools/ToolCopperThieving.py:647 msgid "Squares grid fill selected." msgstr "Rellenar cuadrícula de cuadrados seleccionados." -#: flatcamTools/ToolCopperThieving.py:662 -#: flatcamTools/ToolCopperThieving.py:744 -#: flatcamTools/ToolCopperThieving.py:1340 flatcamTools/ToolDblSided.py:564 -#: flatcamTools/ToolFiducials.py:464 flatcamTools/ToolFiducials.py:741 -#: flatcamTools/ToolOptimal.py:342 flatcamTools/ToolQRCode.py:424 +#: flatcamTools/ToolCopperThieving.py:668 +#: flatcamTools/ToolCopperThieving.py:750 +#: flatcamTools/ToolCopperThieving.py:1346 flatcamTools/ToolDblSided.py:658 +#: flatcamTools/ToolExtractDrills.py:436 flatcamTools/ToolFiducials.py:466 +#: flatcamTools/ToolFiducials.py:743 flatcamTools/ToolOptimal.py:343 +#: flatcamTools/ToolPunchGerber.py:512 flatcamTools/ToolQRCode.py:426 msgid "There is no Gerber object loaded ..." msgstr "No hay ningún objeto Gerber cargado ..." -#: flatcamTools/ToolCopperThieving.py:675 -#: flatcamTools/ToolCopperThieving.py:1268 +#: flatcamTools/ToolCopperThieving.py:681 +#: flatcamTools/ToolCopperThieving.py:1274 msgid "Append geometry" msgstr "Añadir geometría" -#: flatcamTools/ToolCopperThieving.py:719 -#: flatcamTools/ToolCopperThieving.py:1301 -#: flatcamTools/ToolCopperThieving.py:1454 +#: flatcamTools/ToolCopperThieving.py:725 +#: flatcamTools/ToolCopperThieving.py:1307 +#: flatcamTools/ToolCopperThieving.py:1460 msgid "Append source file" msgstr "Agregar archivo fuente" -#: flatcamTools/ToolCopperThieving.py:727 -#: flatcamTools/ToolCopperThieving.py:1309 +#: flatcamTools/ToolCopperThieving.py:733 +#: flatcamTools/ToolCopperThieving.py:1315 msgid "Copper Thieving Tool done." msgstr "Herramienta Copper Thieving hecha." -#: flatcamTools/ToolCopperThieving.py:754 -#: flatcamTools/ToolCopperThieving.py:787 flatcamTools/ToolCutOut.py:468 -#: flatcamTools/ToolCutOut.py:642 flatcamTools/ToolNonCopperClear.py:1151 -#: flatcamTools/ToolNonCopperClear.py:1192 -#: flatcamTools/ToolNonCopperClear.py:1224 flatcamTools/ToolPaint.py:1074 -#: flatcamTools/ToolPanelize.py:401 flatcamTools/ToolPanelize.py:416 -#: flatcamTools/ToolSub.py:288 flatcamTools/ToolSub.py:301 -#: flatcamTools/ToolSub.py:492 flatcamTools/ToolSub.py:507 -#: tclCommands/TclCommandCopperClear.py:97 -#: tclCommands/TclCommandCopperClear.py:146 tclCommands/TclCommandPaint.py:97 +#: flatcamTools/ToolCopperThieving.py:760 +#: flatcamTools/ToolCopperThieving.py:793 flatcamTools/ToolCutOut.py:480 +#: flatcamTools/ToolCutOut.py:667 flatcamTools/ToolInvertGerber.py:208 +#: flatcamTools/ToolNCC.py:1594 flatcamTools/ToolNCC.py:1635 +#: flatcamTools/ToolNCC.py:1664 flatcamTools/ToolPaint.py:1469 +#: flatcamTools/ToolPanelize.py:413 flatcamTools/ToolPanelize.py:428 +#: flatcamTools/ToolSub.py:294 flatcamTools/ToolSub.py:307 +#: flatcamTools/ToolSub.py:498 flatcamTools/ToolSub.py:513 +#: tclCommands/TclCommandCopperClear.py:97 tclCommands/TclCommandPaint.py:99 msgid "Could not retrieve object" msgstr "No se pudo recuperar el objeto" -#: flatcamTools/ToolCopperThieving.py:764 -#: flatcamTools/ToolNonCopperClear.py:1205 +#: flatcamTools/ToolCopperThieving.py:770 flatcamTools/ToolNCC.py:1643 msgid "Click the start point of the area." msgstr "Haga clic en el punto de inicio del área." -#: flatcamTools/ToolCopperThieving.py:815 +#: flatcamTools/ToolCopperThieving.py:821 msgid "Click the end point of the filling area." msgstr "Haga clic en el punto final del área de relleno." -#: flatcamTools/ToolCopperThieving.py:821 -#: flatcamTools/ToolNonCopperClear.py:1261 flatcamTools/ToolPaint.py:1201 +#: flatcamTools/ToolCopperThieving.py:827 flatcamTools/ToolNCC.py:1705 +#: flatcamTools/ToolNCC.py:1757 flatcamTools/ToolPaint.py:1601 +#: flatcamTools/ToolPaint.py:1652 msgid "Zone added. Click to start adding next zone or right click to finish." msgstr "" "Zona agregada. Haga clic para comenzar a agregar la siguiente zona o haga " "clic con el botón derecho para finalizar." -#: flatcamTools/ToolCopperThieving.py:937 -#: flatcamTools/ToolCopperThieving.py:941 -#: flatcamTools/ToolCopperThieving.py:1002 +#: flatcamTools/ToolCopperThieving.py:943 +#: flatcamTools/ToolCopperThieving.py:947 +#: flatcamTools/ToolCopperThieving.py:1008 msgid "Thieving" msgstr "Ladrón" -#: flatcamTools/ToolCopperThieving.py:948 +#: flatcamTools/ToolCopperThieving.py:954 msgid "Copper Thieving Tool started. Reading parameters." msgstr "Herramienta de Copper Thieving iniciada. Parámetros de lectura." -#: flatcamTools/ToolCopperThieving.py:973 +#: flatcamTools/ToolCopperThieving.py:979 msgid "Copper Thieving Tool. Preparing isolation polygons." msgstr "Herramienta Copper Thieving. Preparación de polígonos de aislamiento." -#: flatcamTools/ToolCopperThieving.py:1018 +#: flatcamTools/ToolCopperThieving.py:1024 msgid "Copper Thieving Tool. Preparing areas to fill with copper." msgstr "" "Herramienta Copper Thieving. Preparación de áreas para rellenar con cobre." -#: flatcamTools/ToolCopperThieving.py:1029 flatcamTools/ToolOptimal.py:349 -#: flatcamTools/ToolPanelize.py:793 flatcamTools/ToolRulesCheck.py:1118 +#: flatcamTools/ToolCopperThieving.py:1035 flatcamTools/ToolOptimal.py:350 +#: flatcamTools/ToolPanelize.py:802 flatcamTools/ToolRulesCheck.py:1127 msgid "Working..." msgstr "Trabajando..." -#: flatcamTools/ToolCopperThieving.py:1056 +#: flatcamTools/ToolCopperThieving.py:1062 msgid "Geometry not supported for bounding box" msgstr "Geometría no admitida para cuadro delimitador" -#: flatcamTools/ToolCopperThieving.py:1062 -#: flatcamTools/ToolNonCopperClear.py:1513 flatcamTools/ToolPaint.py:2673 +#: flatcamTools/ToolCopperThieving.py:1068 flatcamTools/ToolNCC.py:1928 +#: flatcamTools/ToolNCC.py:1983 flatcamTools/ToolNCC.py:2987 +#: flatcamTools/ToolPaint.py:3375 msgid "No object available." msgstr "No hay objeto disponible." -#: flatcamTools/ToolCopperThieving.py:1099 -#: flatcamTools/ToolNonCopperClear.py:1555 +#: flatcamTools/ToolCopperThieving.py:1105 flatcamTools/ToolNCC.py:1953 +#: flatcamTools/ToolNCC.py:2006 flatcamTools/ToolNCC.py:3029 msgid "The reference object type is not supported." msgstr "El tipo de objeto de referencia no es compatible." -#: flatcamTools/ToolCopperThieving.py:1104 +#: flatcamTools/ToolCopperThieving.py:1110 msgid "Copper Thieving Tool. Appending new geometry and buffering." msgstr "" "Herramienta Coppe Thieving. Anexar nueva geometría y almacenamiento en búfer." -#: flatcamTools/ToolCopperThieving.py:1120 +#: flatcamTools/ToolCopperThieving.py:1126 msgid "Create geometry" msgstr "Crear geometría" -#: flatcamTools/ToolCopperThieving.py:1320 -#: flatcamTools/ToolCopperThieving.py:1324 +#: flatcamTools/ToolCopperThieving.py:1326 +#: flatcamTools/ToolCopperThieving.py:1330 msgid "P-Plating Mask" msgstr "Mascarilla P" -#: flatcamTools/ToolCopperThieving.py:1346 +#: flatcamTools/ToolCopperThieving.py:1352 msgid "Append PP-M geometry" msgstr "Añadir geometría de máscara de recubrimiento P" -#: flatcamTools/ToolCopperThieving.py:1472 +#: flatcamTools/ToolCopperThieving.py:1478 msgid "Generating Pattern Plating Mask done." msgstr "Generando patrón de recubrimiento de máscara hecho." -#: flatcamTools/ToolCopperThieving.py:1544 +#: flatcamTools/ToolCopperThieving.py:1550 msgid "Copper Thieving Tool exit." msgstr "Salida de herramienta de Copper Thieving." @@ -13691,7 +14438,19 @@ msgstr "Salida de herramienta de Copper Thieving." msgid "Cutout PCB" msgstr "PCB de corte" -#: flatcamTools/ToolCutOut.py:82 +#: flatcamTools/ToolCutOut.py:70 flatcamTools/ToolPanelize.py:54 +msgid "Source Object" +msgstr "Objeto fuente" + +#: flatcamTools/ToolCutOut.py:71 +msgid "Object to be cutout" +msgstr "Objeto a recortar" + +#: flatcamTools/ToolCutOut.py:76 +msgid "Kind" +msgstr "Tipo" + +#: flatcamTools/ToolCutOut.py:98 msgid "" "Specify the type of object to be cutout.\n" "It can be of type: Gerber or Geometry.\n" @@ -13703,19 +14462,19 @@ msgstr "" "Lo que se seleccione aquí dictará el tipo\n" "de objetos que llenarán el cuadro combinado 'Objeto'." -#: flatcamTools/ToolCutOut.py:91 flatcamTools/ToolCutOut.py:92 -msgid "Object to be cutout" -msgstr "Objeto a recortar" +#: flatcamTools/ToolCutOut.py:122 +msgid "Tool Parameters" +msgstr "Parámetros de Herram." -#: flatcamTools/ToolCutOut.py:230 +#: flatcamTools/ToolCutOut.py:239 msgid "A. Automatic Bridge Gaps" msgstr "A. Brechas automáticas del puente" -#: flatcamTools/ToolCutOut.py:232 +#: flatcamTools/ToolCutOut.py:241 msgid "This section handle creation of automatic bridge gaps." msgstr "Esta sección maneja la creación de espacios de puente automáticos." -#: flatcamTools/ToolCutOut.py:243 +#: flatcamTools/ToolCutOut.py:252 msgid "" "Number of gaps used for the Automatic cutout.\n" "There can be maximum 8 bridges/gaps.\n" @@ -13739,11 +14498,11 @@ msgstr "" "- 2tb - 2 * arriba + 2 * abajo\n" "- 8 - 2 * izquierda + 2 * derecha + 2 * arriba + 2 * abajo" -#: flatcamTools/ToolCutOut.py:264 +#: flatcamTools/ToolCutOut.py:273 msgid "Generate Freeform Geometry" msgstr "Generar geometría de forma libre" -#: flatcamTools/ToolCutOut.py:266 +#: flatcamTools/ToolCutOut.py:275 msgid "" "Cutout the selected object.\n" "The cutout shape can be of any shape.\n" @@ -13753,11 +14512,11 @@ msgstr "" "La forma recortada puede ser de cualquier forma.\n" "Útil cuando la PCB tiene una forma no rectangular." -#: flatcamTools/ToolCutOut.py:278 +#: flatcamTools/ToolCutOut.py:287 msgid "Generate Rectangular Geometry" msgstr "Generar geometría rectangular" -#: flatcamTools/ToolCutOut.py:280 +#: flatcamTools/ToolCutOut.py:289 msgid "" "Cutout the selected object.\n" "The resulting cutout shape is\n" @@ -13769,11 +14528,11 @@ msgstr "" "siempre una forma rectangular y será\n" "El cuadro delimitador del objeto." -#: flatcamTools/ToolCutOut.py:299 +#: flatcamTools/ToolCutOut.py:308 msgid "B. Manual Bridge Gaps" msgstr "B. Brechas manuales del puente" -#: flatcamTools/ToolCutOut.py:301 +#: flatcamTools/ToolCutOut.py:310 msgid "" "This section handle creation of manual bridge gaps.\n" "This is done by mouse clicking on the perimeter of the\n" @@ -13783,15 +14542,15 @@ msgstr "" "Esto se hace haciendo clic con el mouse en el perímetro del\n" "Objeto de geometría que se utiliza como objeto recortado. " -#: flatcamTools/ToolCutOut.py:319 +#: flatcamTools/ToolCutOut.py:329 msgid "Geometry object used to create the manual cutout." msgstr "Objeto de geometría utilizado para crear el recorte manual." -#: flatcamTools/ToolCutOut.py:328 +#: flatcamTools/ToolCutOut.py:338 msgid "Generate Manual Geometry" msgstr "Generar geometría manual" -#: flatcamTools/ToolCutOut.py:330 +#: flatcamTools/ToolCutOut.py:340 msgid "" "If the object to be cutout is a Gerber\n" "first create a Geometry that surrounds it,\n" @@ -13804,11 +14563,11 @@ msgstr "" "Seleccione el archivo fuente de Gerber en el cuadro combinado de objeto " "superior." -#: flatcamTools/ToolCutOut.py:343 +#: flatcamTools/ToolCutOut.py:353 msgid "Manual Add Bridge Gaps" msgstr "Agregar huecos de puente manuales" -#: flatcamTools/ToolCutOut.py:345 +#: flatcamTools/ToolCutOut.py:355 msgid "" "Use the left mouse button (LMB) click\n" "to create a bridge gap to separate the PCB from\n" @@ -13822,7 +14581,7 @@ msgstr "" "El clic LMB debe hacerse en el perímetro de\n" "El objeto Geometry utilizado como geometría de recorte." -#: flatcamTools/ToolCutOut.py:473 +#: flatcamTools/ToolCutOut.py:485 msgid "" "There is no object selected for Cutout.\n" "Select one and try again." @@ -13830,16 +14589,17 @@ msgstr "" "No hay ningún objeto seleccionado para Recorte.\n" "Seleccione uno e intente nuevamente." -#: flatcamTools/ToolCutOut.py:479 flatcamTools/ToolCutOut.py:651 -#: flatcamTools/ToolCutOut.py:795 flatcamTools/ToolCutOut.py:877 +#: flatcamTools/ToolCutOut.py:491 flatcamTools/ToolCutOut.py:676 +#: flatcamTools/ToolCutOut.py:839 flatcamTools/ToolCutOut.py:921 +#: tclCommands/TclCommandGeoCutout.py:185 msgid "Tool Diameter is zero value. Change it to a positive real number." msgstr "Diá. de herramienta es valor cero. Cámbielo a un número real positivo." -#: flatcamTools/ToolCutOut.py:493 flatcamTools/ToolCutOut.py:666 +#: flatcamTools/ToolCutOut.py:505 flatcamTools/ToolCutOut.py:691 msgid "Number of gaps value is missing. Add it and retry." msgstr "Falta el valor del número de huecos. Añádelo y vuelve a intentarlo." -#: flatcamTools/ToolCutOut.py:498 flatcamTools/ToolCutOut.py:670 +#: flatcamTools/ToolCutOut.py:510 flatcamTools/ToolCutOut.py:695 msgid "" "Gaps value can be only one of: 'None', 'lr', 'tb', '2lr', '2tb', 4 or 8. " "Fill in a correct value and retry. " @@ -13847,7 +14607,7 @@ msgstr "" "El valor de las brechas solo puede ser uno de: 'Ninguno', 'lr', 'tb', '2lr', " "'2tb', 4 u 8. Complete un valor correcto y vuelva a intentarlo. " -#: flatcamTools/ToolCutOut.py:503 flatcamTools/ToolCutOut.py:676 +#: flatcamTools/ToolCutOut.py:515 flatcamTools/ToolCutOut.py:701 msgid "" "Cutout operation cannot be done on a multi-geo Geometry.\n" "Optionally, this Multi-geo Geometry can be converted to Single-geo " @@ -13859,40 +14619,45 @@ msgstr "" "Single-Geo,\n" "y después de eso realiza el recorte." -#: flatcamTools/ToolCutOut.py:625 flatcamTools/ToolCutOut.py:784 +#: flatcamTools/ToolCutOut.py:650 flatcamTools/ToolCutOut.py:828 msgid "Any form CutOut operation finished." msgstr "Cualquier forma de operación de corte finalizada." -#: flatcamTools/ToolCutOut.py:646 flatcamTools/ToolNonCopperClear.py:1155 -#: flatcamTools/ToolPaint.py:994 flatcamTools/ToolPanelize.py:406 -#: tclCommands/TclCommandBbox.py:70 tclCommands/TclCommandNregions.py:70 +#: flatcamTools/ToolCutOut.py:671 flatcamTools/ToolInvertGerber.py:214 +#: flatcamTools/ToolNCC.py:1598 flatcamTools/ToolPaint.py:1392 +#: flatcamTools/ToolPanelize.py:418 tclCommands/TclCommandBbox.py:72 +#: tclCommands/TclCommandNregions.py:72 msgid "Object not found" msgstr "Objeto no encontrado" -#: flatcamTools/ToolCutOut.py:789 +#: flatcamTools/ToolCutOut.py:814 +msgid "Rectangular cutout with negative margin is not possible." +msgstr "El corte rectangular con margen negativo no es posible." + +#: flatcamTools/ToolCutOut.py:833 msgid "" "Click on the selected geometry object perimeter to create a bridge gap ..." msgstr "" "Haga clic en el perímetro del objeto de geometría seleccionado para crear un " "espacio de puente ..." -#: flatcamTools/ToolCutOut.py:806 flatcamTools/ToolCutOut.py:832 +#: flatcamTools/ToolCutOut.py:850 flatcamTools/ToolCutOut.py:876 msgid "Could not retrieve Geometry object" msgstr "No se pudo recuperar el objeto Geometry" -#: flatcamTools/ToolCutOut.py:837 +#: flatcamTools/ToolCutOut.py:881 msgid "Geometry object for manual cutout not found" msgstr "Objeto de geometría para corte manual no encontrado" -#: flatcamTools/ToolCutOut.py:847 +#: flatcamTools/ToolCutOut.py:891 msgid "Added manual Bridge Gap." msgstr "Se agregó brecha de puente manual." -#: flatcamTools/ToolCutOut.py:859 +#: flatcamTools/ToolCutOut.py:903 msgid "Could not retrieve Gerber object" msgstr "No se pudo recuperar el objeto Gerber" -#: flatcamTools/ToolCutOut.py:864 +#: flatcamTools/ToolCutOut.py:908 msgid "" "There is no Gerber object selected for Cutout.\n" "Select one and try again." @@ -13900,7 +14665,7 @@ msgstr "" "No hay ningún objeto Gerber seleccionado para Recorte.\n" "Seleccione uno e intente nuevamente." -#: flatcamTools/ToolCutOut.py:870 +#: flatcamTools/ToolCutOut.py:914 msgid "" "The selected object has to be of Gerber type.\n" "Select a Gerber file and try again." @@ -13908,11 +14673,11 @@ msgstr "" "El objeto seleccionado debe ser del tipo Gerber.\n" "Seleccione un archivo Gerber e intente nuevamente." -#: flatcamTools/ToolCutOut.py:905 +#: flatcamTools/ToolCutOut.py:949 msgid "Geometry not supported for cutout" msgstr "Geometría no admitida para recorte" -#: flatcamTools/ToolCutOut.py:960 +#: flatcamTools/ToolCutOut.py:1007 msgid "Making manual bridge gap..." msgstr "Hacer un puente manual ..." @@ -13920,12 +14685,20 @@ msgstr "Hacer un puente manual ..." msgid "2-Sided PCB" msgstr "PCB a 2 caras" -#: flatcamTools/ToolDblSided.py:60 +#: flatcamTools/ToolDblSided.py:53 +msgid "Mirror Operation" +msgstr "Operación Espejo" + +#: flatcamTools/ToolDblSided.py:54 +msgid "Objects to be mirrored" +msgstr "Objetos a ser reflejados" + +#: flatcamTools/ToolDblSided.py:66 msgid "Gerber to be mirrored" msgstr "Gerber para ser reflejado" -#: flatcamTools/ToolDblSided.py:64 flatcamTools/ToolDblSided.py:92 -#: flatcamTools/ToolDblSided.py:122 +#: flatcamTools/ToolDblSided.py:70 flatcamTools/ToolDblSided.py:98 +#: flatcamTools/ToolDblSided.py:128 msgid "" "Mirrors (flips) the specified object around \n" "the specified axis. Does not create a new \n" @@ -13935,41 +14708,53 @@ msgstr "" "El eje especificado. No crea un nuevo\n" "objeto, pero lo modifica." -#: flatcamTools/ToolDblSided.py:88 +#: flatcamTools/ToolDblSided.py:94 msgid "Excellon Object to be mirrored." msgstr "Excellon Objeto a ser reflejado." -#: flatcamTools/ToolDblSided.py:117 +#: flatcamTools/ToolDblSided.py:123 msgid "Geometry Obj to be mirrored." msgstr "Obj de geometría para ser reflejado." -#: flatcamTools/ToolDblSided.py:179 -msgid "Point/Box Reference" -msgstr "Punto/caja de referencia" +#: flatcamTools/ToolDblSided.py:159 +msgid "Mirror Parameters" +msgstr "Parámetros de Espejo" -#: flatcamTools/ToolDblSided.py:181 +#: flatcamTools/ToolDblSided.py:160 +msgid "Parameters for the mirror operation" +msgstr "Parámetros para la operación Reflejar" + +#: flatcamTools/ToolDblSided.py:165 +msgid "Mirror Axis" +msgstr "Eje espejo" + +#: flatcamTools/ToolDblSided.py:176 msgid "" -"If 'Point' is selected above it store the coordinates (x, y) through which\n" -"the mirroring axis passes.\n" -"If 'Box' is selected above, select here a FlatCAM object (Gerber, Exc or " -"Geo).\n" -"Through the center of this object pass the mirroring axis selected above." +"The coordinates used as reference for the mirror operation.\n" +"Can be:\n" +"- Point -> a set of coordinates (x,y) around which the object is mirrored\n" +"- Box -> a set of coordinates (x, y) obtained from the center of the\n" +"bounding box of another object selected below" msgstr "" -"Si se selecciona 'Punto' encima, almacena las coordenadas (x, y) a través de " -"las cuales\n" -"el eje reflejado pasa.\n" -"Si se selecciona 'Box' arriba, seleccione aquí un objeto FlatCAM (Gerber, " -"Exc o Geo).\n" -"A través del centro de este objeto pasa el eje reflejado seleccionado " -"anteriormente." +"Las coordenadas utilizadas como referencia para la operación espejo.\n" +"Puede ser:\n" +"- Punto -> un conjunto de coordenadas (x, y) alrededor del cual se refleja " +"el objeto\n" +"- Cuadro -> un conjunto de coordenadas (x, y) obtenidas del centro de la\n" +"cuadro delimitador de otro objeto seleccionado a continuación" -#: flatcamTools/ToolDblSided.py:189 +#: flatcamTools/ToolDblSided.py:190 +msgid "Point coordinates" +msgstr "Coordenadas de puntos" + +#: flatcamTools/ToolDblSided.py:195 msgid "" "Add the coordinates in format (x, y) through which the mirroring " "axis \n" " selected in 'MIRROR AXIS' pass.\n" "The (x, y) coordinates are captured by pressing SHIFT key\n" -"and left mouse button click on canvas or you can enter the coords manually." +"and left mouse button click on canvas or you can enter the coordinates " +"manually." msgstr "" "Agregue las coordenadas en formato (x, y) a través del cual el eje " "de reflejo\n" @@ -13978,102 +14763,61 @@ msgstr "" "y haga clic con el botón izquierdo del mouse en el lienzo o puede ingresar " "las coordenadas manualmente." -#: flatcamTools/ToolDblSided.py:230 -msgid "Alignment Drill Coordinates" -msgstr "Taladro de alineación Coords" - -#: flatcamTools/ToolDblSided.py:232 +#: flatcamTools/ToolDblSided.py:219 msgid "" -"Alignment holes (x1, y1), (x2, y2), ... on one side of the mirror axis. For " -"each set of (x, y) coordinates\n" -"entered here, a pair of drills will be created:\n" -"\n" -"- one drill at the coordinates from the field\n" -"- one drill in mirror position over the axis selected above in the 'Mirror " -"Axis'." +"It can be of type: Gerber or Excellon or Geometry.\n" +"The coordinates of the center of the bounding box are used\n" +"as reference for mirror operation." msgstr "" -"Agujeros de alineación (x1, y1), (x2, y2), ... en un lado del eje del " -"espejo. Para cada conjunto de coordenadas (x, y)\n" -"ingresado aquí, se crearán un par de simulacros:\n" -"\n" -"- un ejercicio en las coordenadas del campo\n" -"- un taladro en posición de espejo sobre el eje seleccionado anteriormente " -"en el 'Eje de espejo'." +"Puede ser de tipo: Gerber o Excellon o Geometry.\n" +"Se utilizan las coordenadas del centro del cuadro delimitador.\n" +"como referencia para la operación del espejo." -#: flatcamTools/ToolDblSided.py:247 +#: flatcamTools/ToolDblSided.py:253 +msgid "Bounds Values" +msgstr "Valores de límites" + +#: flatcamTools/ToolDblSided.py:255 msgid "" -"Add alignment drill holes coords in the format: (x1, y1), (x2, y2), ... \n" -"on one side of the mirror axis.\n" -"\n" -"The coordinates set can be obtained:\n" -"- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" -"- press SHIFT key and left mouse clicking on canvas. Then Ctrl+V in the " -"field.\n" -"- press SHIFT key and left mouse clicking on canvas. Then RMB click in the " -"field and click Paste.\n" -"- by entering the coords manually in the format: (x1, y1), (x2, y2), ..." +"Select on canvas the object(s)\n" +"for which to calculate bounds values." msgstr "" -"Agregue alineaciones de taladros de alineación en el formato: (x1, y1), (x2, " -"y2), ...\n" -"en un lado del eje del espejo.\n" -"\n" -"El conjunto de coordenadas se puede obtener:\n" -"- presione la tecla SHIFT y haga clic con el botón izquierdo del mouse en el " -"lienzo. Luego haga clic en Agregar.\n" -"- presione la tecla SHIFT y haga clic con el botón izquierdo del mouse en el " -"lienzo. Luego CTRL + V en el campo.\n" -"- presione la tecla SHIFT y haga clic con el botón izquierdo del mouse en el " -"lienzo. Luego, haga clic en RMB en el campo y haga clic en Pegar.\n" -"- ingresando las coordenadas manualmente en el formato: (x1, y1), (x2, " -"y2), ..." +"Seleccione en lienzo los objetos\n" +"para el cual calcular valores de límites." -#: flatcamTools/ToolDblSided.py:272 -msgid "Alignment Drill Diameter" -msgstr "Diá. de taladro de alineación" - -#: flatcamTools/ToolDblSided.py:292 -msgid "Create Excellon Object" -msgstr "Crear objeto Excellon" - -#: flatcamTools/ToolDblSided.py:294 -msgid "" -"Creates an Excellon Object containing the\n" -"specified alignment holes and their mirror\n" -"images." -msgstr "" -"Crea un objeto Excellon que contiene el\n" -"agujeros de alineación especificados y su espejo\n" -"imágenes." - -#: flatcamTools/ToolDblSided.py:323 +#: flatcamTools/ToolDblSided.py:265 msgid "X min" msgstr "X min" -#: flatcamTools/ToolDblSided.py:325 flatcamTools/ToolDblSided.py:339 +#: flatcamTools/ToolDblSided.py:267 flatcamTools/ToolDblSided.py:281 msgid "Minimum location." msgstr "Ubicacion minima." -#: flatcamTools/ToolDblSided.py:337 +#: flatcamTools/ToolDblSided.py:279 msgid "Y min" msgstr "Y min" -#: flatcamTools/ToolDblSided.py:351 +#: flatcamTools/ToolDblSided.py:293 msgid "X max" msgstr "X max" -#: flatcamTools/ToolDblSided.py:353 flatcamTools/ToolDblSided.py:367 +#: flatcamTools/ToolDblSided.py:295 flatcamTools/ToolDblSided.py:309 msgid "Maximum location." msgstr "Máxima ubicación." -#: flatcamTools/ToolDblSided.py:365 +#: flatcamTools/ToolDblSided.py:307 msgid "Y max" msgstr "Y max" -#: flatcamTools/ToolDblSided.py:377 +#: flatcamTools/ToolDblSided.py:318 +msgid "Center point coordinates" +msgstr "Coords del punto central" + +#: flatcamTools/ToolDblSided.py:320 msgid "Centroid" msgstr "Centroide" -#: flatcamTools/ToolDblSided.py:379 +#: flatcamTools/ToolDblSided.py:322 msgid "" "The center point location for the rectangular\n" "bounding shape. Centroid. Format is (x, y)." @@ -14081,11 +14825,11 @@ msgstr "" "La ubicación del punto central para el rectangular\n" "forma delimitadora. Centroide. El formato es (x, y)." -#: flatcamTools/ToolDblSided.py:388 +#: flatcamTools/ToolDblSided.py:331 msgid "Calculate Bounds Values" msgstr "Calcular valores de límites" -#: flatcamTools/ToolDblSided.py:390 +#: flatcamTools/ToolDblSided.py:333 msgid "" "Calculate the enveloping rectangular shape coordinates,\n" "for the selection of objects.\n" @@ -14095,11 +14839,106 @@ msgstr "" "para la selección de objetos.\n" "La forma de la envoltura es paralela al eje X, Y." -#: flatcamTools/ToolDblSided.py:462 +#: flatcamTools/ToolDblSided.py:353 +msgid "PCB Alignment" +msgstr "Alineación de PCB" + +#: flatcamTools/ToolDblSided.py:355 flatcamTools/ToolDblSided.py:457 +msgid "" +"Creates an Excellon Object containing the\n" +"specified alignment holes and their mirror\n" +"images." +msgstr "" +"Crea un objeto Excellon que contiene el\n" +"agujeros de alineación especificados y su espejo\n" +"imágenes." + +#: flatcamTools/ToolDblSided.py:362 +msgid "Drill Diameter" +msgstr "Diá del Taladro" + +#: flatcamTools/ToolDblSided.py:391 flatcamTools/ToolDblSided.py:398 +msgid "" +"The reference point used to create the second alignment drill\n" +"from the first alignment drill, by doing mirror.\n" +"It can be modified in the Mirror Parameters -> Reference section" +msgstr "" +"El punto de referencia utilizado para crear el segundo ejercicio de " +"alineación.\n" +"desde el primer ejercicio de alineación, haciendo espejo.\n" +"Se puede modificar en la sección Parámetros Espejo -> Referencia" + +#: flatcamTools/ToolDblSided.py:411 +msgid "Alignment Drill Coordinates" +msgstr "Taladro de alineación Coords" + +#: flatcamTools/ToolDblSided.py:413 +msgid "" +"Alignment holes (x1, y1), (x2, y2), ... on one side of the mirror axis. For " +"each set of (x, y) coordinates\n" +"entered here, a pair of drills will be created:\n" +"\n" +"- one drill at the coordinates from the field\n" +"- one drill in mirror position over the axis selected above in the 'Align " +"Axis'." +msgstr "" +"Agujeros de alineación (x1, y1), (x2, y2), ... en un lado del eje del " +"espejo. Para cada conjunto de coordenadas (x, y)\n" +"ingresado aquí, se crearán un par de simulacros:\n" +"\n" +"- un ejercicio en las coordenadas del campo\n" +"- un taladro en posición de espejo sobre el eje seleccionado arriba en " +"'Alinear eje'." + +#: flatcamTools/ToolDblSided.py:421 +msgid "Drill coordinates" +msgstr "Coords de Perforación" + +#: flatcamTools/ToolDblSided.py:428 +msgid "" +"Add alignment drill holes coordinates in the format: (x1, y1), (x2, " +"y2), ... \n" +"on one side of the alignment axis.\n" +"\n" +"The coordinates set can be obtained:\n" +"- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" +"- press SHIFT key and left mouse clicking on canvas. Then Ctrl+V in the " +"field.\n" +"- press SHIFT key and left mouse clicking on canvas. Then RMB click in the " +"field and click Paste.\n" +"- by entering the coords manually in the format: (x1, y1), (x2, y2), ..." +msgstr "" +"Agregue coordenadas de taladros de alineación en el formato: (x1, y1), (x2, " +"y2), ...\n" +"en un lado del eje de alineación.\n" +"\n" +"El conjunto de coordenadas se puede obtener:\n" +"- presione la tecla SHIFT y haga clic con el botón izquierdo del mouse en el " +"lienzo. Luego haga clic en Agregar.\n" +"- presione la tecla SHIFT y haga clic con el botón izquierdo en el lienzo " +"Luego Ctrl + V en el campo.\n" +"- presione la tecla SHIFT y haga clic con el botón izquierdo del mouse en el " +"lienzo. Luego, haga clic en RMB en el campo y haga clic en Pegar.\n" +"- ingresando las coordenadas manualmente en el formato: (x1, y1), (x2, " +"y2), ..." + +#: flatcamTools/ToolDblSided.py:443 +msgid "Delete Last" +msgstr "Eliminar último" + +#: flatcamTools/ToolDblSided.py:445 +msgid "Delete the last coordinates tuple in the list." +msgstr "Eliminar la última tupla de coordenadas en la lista." + +#: flatcamTools/ToolDblSided.py:455 +msgid "Create Excellon Object" +msgstr "Crear objeto Excellon" + +#: flatcamTools/ToolDblSided.py:542 msgid "2-Sided Tool" msgstr "Herra. de 2 lados" -#: flatcamTools/ToolDblSided.py:493 +#: flatcamTools/ToolDblSided.py:582 msgid "" "'Point' reference is selected and 'Point' coordinates are missing. Add them " "and retry." @@ -14107,55 +14946,34 @@ msgstr "" "Se selecciona la referencia 'Punto' y faltan las coordenadas 'Punto'. " "Añádelos y vuelve a intentarlo." -#: flatcamTools/ToolDblSided.py:512 +#: flatcamTools/ToolDblSided.py:601 msgid "There is no Box reference object loaded. Load one and retry." msgstr "" "No hay ningún objeto de referencia de cuadro cargado. Cargue uno y vuelva a " "intentarlo." -#: flatcamTools/ToolDblSided.py:524 +#: flatcamTools/ToolDblSided.py:613 msgid "No value or wrong format in Drill Dia entry. Add it and retry." msgstr "" "Sin valor o formato incorrecto en la entrada de diá. de perforación. Añádelo " "y vuelve a intentarlo." -#: flatcamTools/ToolDblSided.py:532 +#: flatcamTools/ToolDblSided.py:624 msgid "There are no Alignment Drill Coordinates to use. Add them and retry." msgstr "" "No hay coordenadas de taladro de alineación para usar. Añádelos y vuelve a " "intentarlo." -#: flatcamTools/ToolDblSided.py:555 +#: flatcamTools/ToolDblSided.py:649 msgid "Excellon object with alignment drills created..." msgstr "Objeto Excellon con taladros de alineación creados ..." -#: flatcamTools/ToolDblSided.py:568 flatcamTools/ToolDblSided.py:611 -#: flatcamTools/ToolDblSided.py:655 +#: flatcamTools/ToolDblSided.py:662 flatcamTools/ToolDblSided.py:705 +#: flatcamTools/ToolDblSided.py:749 msgid "Only Gerber, Excellon and Geometry objects can be mirrored." msgstr "Solo los objetos Gerber, Excellon y Geometry se pueden reflejar." -#: flatcamTools/ToolDblSided.py:578 -msgid "" -"'Point' coordinates missing. Using Origin (0, 0) as mirroring reference." -msgstr "" -"'Punto 'coordenadas faltantes. Usando origen (0, 0) como reflejo de " -"referencia." - -#: flatcamTools/ToolDblSided.py:588 flatcamTools/ToolDblSided.py:632 -#: flatcamTools/ToolDblSided.py:669 -msgid "There is no Box object loaded ..." -msgstr "No hay ningún objeto caja cargado ..." - -#: flatcamTools/ToolDblSided.py:598 flatcamTools/ToolDblSided.py:642 -#: flatcamTools/ToolDblSided.py:679 -msgid "was mirrored" -msgstr "fue reflejado" - -#: flatcamTools/ToolDblSided.py:607 -msgid "There is no Excellon object loaded ..." -msgstr "No hay ningún objeto Excellon cargado ..." - -#: flatcamTools/ToolDblSided.py:622 +#: flatcamTools/ToolDblSided.py:672 flatcamTools/ToolDblSided.py:716 msgid "" "There are no Point coordinates in the Point field. Add coords and try " "again ..." @@ -14163,98 +14981,137 @@ msgstr "" "No hay coordenadas de punto en el campo Punto. Agregue coords e intente " "nuevamente ..." -#: flatcamTools/ToolDblSided.py:651 +#: flatcamTools/ToolDblSided.py:682 flatcamTools/ToolDblSided.py:726 +#: flatcamTools/ToolDblSided.py:763 +msgid "There is no Box object loaded ..." +msgstr "No hay ningún objeto caja cargado ..." + +#: flatcamTools/ToolDblSided.py:692 flatcamTools/ToolDblSided.py:736 +#: flatcamTools/ToolDblSided.py:773 +msgid "was mirrored" +msgstr "fue reflejado" + +#: flatcamTools/ToolDblSided.py:701 flatcamTools/ToolPunchGerber.py:533 +msgid "There is no Excellon object loaded ..." +msgstr "No hay ningún objeto Excellon cargado ..." + +#: flatcamTools/ToolDblSided.py:745 msgid "There is no Geometry object loaded ..." msgstr "No hay ningún objeto de geometría cargado ..." -#: flatcamTools/ToolDistance.py:50 flatcamTools/ToolDistanceMin.py:50 +#: flatcamTools/ToolDistance.py:57 flatcamTools/ToolDistanceMin.py:51 msgid "Those are the units in which the distance is measured." msgstr "Esas son las unidades en las que se mide la distancia." -#: flatcamTools/ToolDistance.py:51 flatcamTools/ToolDistanceMin.py:51 +#: flatcamTools/ToolDistance.py:58 flatcamTools/ToolDistanceMin.py:52 msgid "METRIC (mm)" msgstr "MÉTRICO (mm)" -#: flatcamTools/ToolDistance.py:51 flatcamTools/ToolDistanceMin.py:51 +#: flatcamTools/ToolDistance.py:58 flatcamTools/ToolDistanceMin.py:52 msgid "INCH (in)" msgstr "PULGADA (en)" -#: flatcamTools/ToolDistance.py:54 +#: flatcamTools/ToolDistance.py:64 +msgid "Snap to center" +msgstr "Ajustar al centro" + +#: flatcamTools/ToolDistance.py:66 +msgid "" +"Mouse cursor will snap to the center of the pad/drill\n" +"when it is hovering over the geometry of the pad/drill." +msgstr "" +"El cursor del mouse se ajustará al centro de la almohadilla / taladro\n" +"cuando se cierne sobre la geometría de la almohadilla / taladro." + +#: flatcamTools/ToolDistance.py:76 msgid "Start Coords" msgstr "Iniciar coordenadas" -#: flatcamTools/ToolDistance.py:55 flatcamTools/ToolDistance.py:75 +#: flatcamTools/ToolDistance.py:77 flatcamTools/ToolDistance.py:82 msgid "This is measuring Start point coordinates." msgstr "Esto mide las coordenadas del punto de inicio." -#: flatcamTools/ToolDistance.py:57 +#: flatcamTools/ToolDistance.py:87 msgid "Stop Coords" msgstr "Detener coordenadas" -#: flatcamTools/ToolDistance.py:58 flatcamTools/ToolDistance.py:80 +#: flatcamTools/ToolDistance.py:88 flatcamTools/ToolDistance.py:93 msgid "This is the measuring Stop point coordinates." msgstr "Estas son las coordenadas del punto de parada de medición." -#: flatcamTools/ToolDistance.py:60 flatcamTools/ToolDistanceMin.py:62 +#: flatcamTools/ToolDistance.py:98 flatcamTools/ToolDistanceMin.py:63 msgid "Dx" msgstr "Dx" -#: flatcamTools/ToolDistance.py:61 flatcamTools/ToolDistance.py:85 -#: flatcamTools/ToolDistanceMin.py:63 flatcamTools/ToolDistanceMin.py:92 +#: flatcamTools/ToolDistance.py:99 flatcamTools/ToolDistance.py:104 +#: flatcamTools/ToolDistanceMin.py:64 flatcamTools/ToolDistanceMin.py:93 msgid "This is the distance measured over the X axis." msgstr "Esta es la distancia medida sobre el eje X." -#: flatcamTools/ToolDistance.py:63 flatcamTools/ToolDistanceMin.py:65 +#: flatcamTools/ToolDistance.py:109 flatcamTools/ToolDistanceMin.py:66 msgid "Dy" msgstr "Dy" -#: flatcamTools/ToolDistance.py:64 flatcamTools/ToolDistance.py:90 -#: flatcamTools/ToolDistanceMin.py:66 flatcamTools/ToolDistanceMin.py:97 +#: flatcamTools/ToolDistance.py:110 flatcamTools/ToolDistance.py:115 +#: flatcamTools/ToolDistanceMin.py:67 flatcamTools/ToolDistanceMin.py:98 msgid "This is the distance measured over the Y axis." msgstr "Esta es la distancia medida sobre el eje Y." -#: flatcamTools/ToolDistance.py:67 flatcamTools/ToolDistance.py:95 -#: flatcamTools/ToolDistanceMin.py:69 flatcamTools/ToolDistanceMin.py:102 +#: flatcamTools/ToolDistance.py:121 flatcamTools/ToolDistance.py:126 +#: flatcamTools/ToolDistanceMin.py:70 flatcamTools/ToolDistanceMin.py:103 msgid "This is orientation angle of the measuring line." msgstr "Este es el ángulo de orientación de la línea de medición." -#: flatcamTools/ToolDistance.py:69 flatcamTools/ToolDistanceMin.py:71 +#: flatcamTools/ToolDistance.py:131 flatcamTools/ToolDistanceMin.py:72 msgid "DISTANCE" msgstr "DISTANCIA" -#: flatcamTools/ToolDistance.py:70 flatcamTools/ToolDistance.py:100 +#: flatcamTools/ToolDistance.py:132 flatcamTools/ToolDistance.py:137 msgid "This is the point to point Euclidian distance." msgstr "Este es el punto a punto de la distancia euclidiana." -#: flatcamTools/ToolDistance.py:102 flatcamTools/ToolDistanceMin.py:114 +#: flatcamTools/ToolDistance.py:142 flatcamTools/ToolDistance.py:337 +#: flatcamTools/ToolDistanceMin.py:115 msgid "Measure" msgstr "Medida" -#: flatcamTools/ToolDistance.py:212 +#: flatcamTools/ToolDistance.py:272 +msgid "Working" +msgstr "Trabajando" + +#: flatcamTools/ToolDistance.py:277 msgid "MEASURING: Click on the Start point ..." msgstr "MEDICIÓN: haga clic en el punto de inicio ..." -#: flatcamTools/ToolDistance.py:345 +#: flatcamTools/ToolDistance.py:387 +msgid "Distance Tool finished." +msgstr "Herramienta de Distancia terminada." + +#: flatcamTools/ToolDistance.py:455 +msgid "Pads overlapped. Aborting." +msgstr "Almohadillas superpuestas. Abortar." + +#: flatcamTools/ToolDistance.py:485 msgid "MEASURING: Click on the Destination point ..." msgstr "MEDICIÓN: haga clic en el punto de destino ..." -#: flatcamTools/ToolDistance.py:353 flatcamTools/ToolDistanceMin.py:282 +#: flatcamTools/ToolDistance.py:494 flatcamTools/ToolDistanceMin.py:285 msgid "MEASURING" msgstr "MEDICIÓN" -#: flatcamTools/ToolDistance.py:354 flatcamTools/ToolDistanceMin.py:283 +#: flatcamTools/ToolDistance.py:495 flatcamTools/ToolDistanceMin.py:286 msgid "Result" msgstr "Resultado" -#: flatcamTools/ToolDistanceMin.py:31 flatcamTools/ToolDistanceMin.py:152 +#: flatcamTools/ToolDistanceMin.py:32 flatcamTools/ToolDistanceMin.py:144 msgid "Minimum Distance Tool" msgstr "Herramienta de Distancia Mínima" -#: flatcamTools/ToolDistanceMin.py:54 +#: flatcamTools/ToolDistanceMin.py:55 msgid "First object point" msgstr "Primer punto" -#: flatcamTools/ToolDistanceMin.py:55 flatcamTools/ToolDistanceMin.py:80 +#: flatcamTools/ToolDistanceMin.py:56 flatcamTools/ToolDistanceMin.py:81 msgid "" "This is first object point coordinates.\n" "This is the start point for measuring distance." @@ -14262,11 +15119,11 @@ msgstr "" "Este es el primer objeto de coordenadas de puntos.\n" "Este es el punto de partida para medir la distancia." -#: flatcamTools/ToolDistanceMin.py:58 +#: flatcamTools/ToolDistanceMin.py:59 msgid "Second object point" msgstr "Segundo punto" -#: flatcamTools/ToolDistanceMin.py:59 flatcamTools/ToolDistanceMin.py:86 +#: flatcamTools/ToolDistanceMin.py:60 flatcamTools/ToolDistanceMin.py:87 msgid "" "This is second object point coordinates.\n" "This is the end point for measuring distance." @@ -14274,42 +15131,59 @@ msgstr "" "Este es el segundo objeto de coordenadas de puntos.\n" "Este es el punto final para medir la distancia." -#: flatcamTools/ToolDistanceMin.py:72 flatcamTools/ToolDistanceMin.py:107 +#: flatcamTools/ToolDistanceMin.py:73 flatcamTools/ToolDistanceMin.py:108 msgid "This is the point to point Euclidean distance." msgstr "Este es el punto a punto de la distancia euclidiana." -#: flatcamTools/ToolDistanceMin.py:74 +#: flatcamTools/ToolDistanceMin.py:75 msgid "Half Point" msgstr "Punto Medio" -#: flatcamTools/ToolDistanceMin.py:75 flatcamTools/ToolDistanceMin.py:112 +#: flatcamTools/ToolDistanceMin.py:76 flatcamTools/ToolDistanceMin.py:113 msgid "This is the middle point of the point to point Euclidean distance." msgstr "Este es el punto medio de la distancia euclidiana punto a punto." -#: flatcamTools/ToolDistanceMin.py:117 +#: flatcamTools/ToolDistanceMin.py:118 msgid "Jump to Half Point" msgstr "Saltar a Medio Punto" -#: flatcamTools/ToolDistanceMin.py:163 +#: flatcamTools/ToolDistanceMin.py:155 msgid "" "Select two objects and no more, to measure the distance between them ..." msgstr "" "Seleccione dos objetos y no más, para medir la distancia entre ellos ..." -#: flatcamTools/ToolDistanceMin.py:204 flatcamTools/ToolDistanceMin.py:214 -#: flatcamTools/ToolDistanceMin.py:223 flatcamTools/ToolDistanceMin.py:244 +#: flatcamTools/ToolDistanceMin.py:196 flatcamTools/ToolDistanceMin.py:217 +#: flatcamTools/ToolDistanceMin.py:226 flatcamTools/ToolDistanceMin.py:247 msgid "Select two objects and no more. Currently the selection has objects: " msgstr "" "Seleccione dos objetos y no más. Actualmente la selección tiene objetos: " -#: flatcamTools/ToolDistanceMin.py:291 +#: flatcamTools/ToolDistanceMin.py:294 msgid "Objects intersects or touch at" msgstr "Los objetos se cruzan o tocan" -#: flatcamTools/ToolDistanceMin.py:297 +#: flatcamTools/ToolDistanceMin.py:300 msgid "Jumped to the half point between the two selected objects" msgstr "Saltó al punto medio entre los dos objetos seleccionados" +#: flatcamTools/ToolExtractDrills.py:29 flatcamTools/ToolExtractDrills.py:295 +msgid "Extract Drills" +msgstr "Extraer Taladros" + +#: flatcamTools/ToolExtractDrills.py:62 +msgid "Gerber from which to extract drill holes" +msgstr "Gerber de donde extraer agujeros de perforación" + +#: flatcamTools/ToolExtractDrills.py:297 +msgid "Extract drills from a given Gerber file." +msgstr "Extraer simulacros de un archivo Gerber dado." + +#: flatcamTools/ToolExtractDrills.py:478 flatcamTools/ToolExtractDrills.py:563 +#: flatcamTools/ToolExtractDrills.py:648 +msgid "No drills extracted. Try different parameters." +msgstr "No se extraen taladros. Prueba diferentes parámetros." + #: flatcamTools/ToolFiducials.py:56 msgid "Fiducials Coordinates" msgstr "Coordenadas Fiduciales" @@ -14326,10 +15200,6 @@ msgstr "" msgid "Top Right" msgstr "Arriba a la derecha" -#: flatcamTools/ToolFiducials.py:111 -msgid "Second Point" -msgstr "Segundo punto" - #: flatcamTools/ToolFiducials.py:191 msgid "" "- 'Auto' - automatic placement of fiducials in the corners of the bounding " @@ -14340,31 +15210,31 @@ msgstr "" "delimitador.\n" " - 'Manual' - colocación manual de fiduciales." -#: flatcamTools/ToolFiducials.py:258 +#: flatcamTools/ToolFiducials.py:259 msgid "Copper Gerber" msgstr "Cobre Gerber" -#: flatcamTools/ToolFiducials.py:267 +#: flatcamTools/ToolFiducials.py:268 msgid "Add Fiducial" msgstr "Añadir Fiducial" -#: flatcamTools/ToolFiducials.py:269 +#: flatcamTools/ToolFiducials.py:270 msgid "Will add a polygon on the copper layer to serve as fiducial." msgstr "Agregará un polígono en la capa de cobre para servir como fiducial." -#: flatcamTools/ToolFiducials.py:285 +#: flatcamTools/ToolFiducials.py:286 msgid "Soldermask Gerber" msgstr "Soldermask Gerber" -#: flatcamTools/ToolFiducials.py:287 +#: flatcamTools/ToolFiducials.py:288 msgid "The Soldermask Gerber object." msgstr "El objeto Soldermask Gerber." -#: flatcamTools/ToolFiducials.py:298 +#: flatcamTools/ToolFiducials.py:300 msgid "Add Soldermask Opening" msgstr "Agregar apertura de Soldermask" -#: flatcamTools/ToolFiducials.py:300 +#: flatcamTools/ToolFiducials.py:302 msgid "" "Will add a polygon on the soldermask layer\n" "to serve as fiducial opening.\n" @@ -14376,25 +15246,25 @@ msgstr "" "El diámetro siempre es el doble del diámetro.\n" "para el cobre fiducial." -#: flatcamTools/ToolFiducials.py:514 +#: flatcamTools/ToolFiducials.py:516 msgid "Click to add first Fiducial. Bottom Left..." msgstr "Haga clic para agregar primero Fiducial. Abajo a la izquierda ..." -#: flatcamTools/ToolFiducials.py:778 +#: flatcamTools/ToolFiducials.py:780 msgid "Click to add the last fiducial. Top Right..." msgstr "Haga clic para agregar el último fiducial. Parte superior derecha..." -#: flatcamTools/ToolFiducials.py:783 +#: flatcamTools/ToolFiducials.py:785 msgid "Click to add the second fiducial. Top Left or Bottom Right..." msgstr "" "Haga clic para agregar el segundo fiducial. Arriba a la izquierda o abajo a " "la derecha ..." -#: flatcamTools/ToolFiducials.py:786 flatcamTools/ToolFiducials.py:795 +#: flatcamTools/ToolFiducials.py:788 flatcamTools/ToolFiducials.py:797 msgid "Done. All fiducials have been added." msgstr "Hecho. Se han agregado todos los fiduciales." -#: flatcamTools/ToolFiducials.py:872 +#: flatcamTools/ToolFiducials.py:874 msgid "Fiducials Tool exit." msgstr "Herram. Fiduciales de salida." @@ -14402,7 +15272,7 @@ msgstr "Herram. Fiduciales de salida." msgid "Film PCB" msgstr "Película de PCB" -#: flatcamTools/ToolFilm.py:80 +#: flatcamTools/ToolFilm.py:78 msgid "" "Specify the type of object for which to create the film.\n" "The object can be of type: Gerber or Geometry.\n" @@ -14414,11 +15284,11 @@ msgstr "" "La selección aquí decide el tipo de objetos que serán\n" "en el cuadro combinado de objeto de película." -#: flatcamTools/ToolFilm.py:94 +#: flatcamTools/ToolFilm.py:92 msgid "Film Object" msgstr "Objeto de la película" -#: flatcamTools/ToolFilm.py:96 +#: flatcamTools/ToolFilm.py:94 msgid "Object for which to create the film." msgstr "Objeto para el cual crear la película." @@ -14434,7 +15304,7 @@ msgstr "" "aquí decide el tipo de objetos que serán\n" "en el cuadro combinado Objeto de caja." -#: flatcamTools/ToolFilm.py:129 flatcamTools/ToolPanelize.py:136 +#: flatcamTools/ToolFilm.py:129 msgid "Box Object" msgstr "Objeto de caja" @@ -14499,33 +15369,33 @@ msgstr "" "Retire la geometría de Excellon de la película para crear los agujeros en " "las almohadillas." -#: flatcamTools/ToolFilm.py:379 +#: flatcamTools/ToolFilm.py:381 msgid "Punch Size" msgstr "Tamaño de perforación" -#: flatcamTools/ToolFilm.py:380 +#: flatcamTools/ToolFilm.py:382 msgid "The value here will control how big is the punch hole in the pads." msgstr "" "El valor aquí controlará qué tan grande es el agujero de perforación en los " "pads." -#: flatcamTools/ToolFilm.py:500 +#: flatcamTools/ToolFilm.py:502 msgid "Save Film" msgstr "Guardar película" -#: flatcamTools/ToolFilm.py:502 +#: flatcamTools/ToolFilm.py:504 msgid "" "Create a Film for the selected object, within\n" "the specified box. Does not create a new \n" " FlatCAM object, but directly save it in the\n" "selected format." msgstr "" -"Crear una película para el objeto seleccionado, dentro de\n" -"la casilla especificada No crea un nuevo\n" +"Crear una Película para el objeto seleccionado, dentro de\n" +"El cuadro especificado. No crea un nuevo\n" "Objeto FlatCAM, pero guárdelo directamente en el\n" -"formato seleccionado" +"formato seleccionado." -#: flatcamTools/ToolFilm.py:652 +#: flatcamTools/ToolFilm.py:664 msgid "" "Using the Pad center does not work on Geometry objects. Only a Gerber object " "has pads." @@ -14533,42 +15403,38 @@ msgstr "" "El uso del centro de almohadilla no funciona en objetos de geometría. Solo " "un objeto Gerber tiene almohadillas." -#: flatcamTools/ToolFilm.py:662 +#: flatcamTools/ToolFilm.py:674 msgid "No FlatCAM object selected. Load an object for Film and retry." msgstr "" "No se ha seleccionado ningún objeto FlatCAM. Cargue un objeto para Película " "y vuelva a intentarlo." -#: flatcamTools/ToolFilm.py:669 +#: flatcamTools/ToolFilm.py:681 msgid "No FlatCAM object selected. Load an object for Box and retry." msgstr "" "No se ha seleccionado ningún objeto FlatCAM. Cargue un objeto para Box y " "vuelva a intentarlo." -#: flatcamTools/ToolFilm.py:673 +#: flatcamTools/ToolFilm.py:685 msgid "No FlatCAM object selected." msgstr "No se ha seleccionado ningún objeto FlatCAM." -#: flatcamTools/ToolFilm.py:684 +#: flatcamTools/ToolFilm.py:696 msgid "Generating Film ..." msgstr "Generando película ..." -#: flatcamTools/ToolFilm.py:733 flatcamTools/ToolFilm.py:737 +#: flatcamTools/ToolFilm.py:745 flatcamTools/ToolFilm.py:749 msgid "Export positive film" msgstr "Exportar película positiva" -#: flatcamTools/ToolFilm.py:742 -msgid "Export positive film cancelled." -msgstr "Exportación de película positiva cancelada." - -#: flatcamTools/ToolFilm.py:770 +#: flatcamTools/ToolFilm.py:782 msgid "" "No Excellon object selected. Load an object for punching reference and retry." msgstr "" "No se seleccionó ningún objeto Excellon. Cargue un objeto para perforar la " "referencia y vuelva a intentarlo." -#: flatcamTools/ToolFilm.py:794 +#: flatcamTools/ToolFilm.py:806 msgid "" " Could not generate punched hole film because the punch hole sizeis bigger " "than some of the apertures in the Gerber object." @@ -14577,7 +15443,7 @@ msgstr "" "agujero perforado es más grande que algunas de las aberturas en el objeto " "Gerber." -#: flatcamTools/ToolFilm.py:806 +#: flatcamTools/ToolFilm.py:818 msgid "" "Could not generate punched hole film because the punch hole sizeis bigger " "than some of the apertures in the Gerber object." @@ -14586,7 +15452,7 @@ msgstr "" "agujero perforado es más grande que algunas de las aberturas en el objeto " "Gerber." -#: flatcamTools/ToolFilm.py:824 +#: flatcamTools/ToolFilm.py:836 msgid "" "Could not generate punched hole film because the newly created object " "geometry is the same as the one in the source object geometry..." @@ -14595,24 +15461,20 @@ msgstr "" "objeto recién creada es la misma que la de la geometría del objeto de " "origen ..." -#: flatcamTools/ToolFilm.py:879 flatcamTools/ToolFilm.py:883 +#: flatcamTools/ToolFilm.py:891 flatcamTools/ToolFilm.py:895 msgid "Export negative film" msgstr "Exportar película negativa" -#: flatcamTools/ToolFilm.py:888 -msgid "Export negative film cancelled." -msgstr "Película negativa de exportación cancelada." - -#: flatcamTools/ToolFilm.py:944 flatcamTools/ToolFilm.py:1122 -#: flatcamTools/ToolPanelize.py:421 +#: flatcamTools/ToolFilm.py:956 flatcamTools/ToolFilm.py:1139 +#: flatcamTools/ToolPanelize.py:433 msgid "No object Box. Using instead" msgstr "Sin objeto Caja. Usando en su lugar" -#: flatcamTools/ToolFilm.py:1060 flatcamTools/ToolFilm.py:1235 +#: flatcamTools/ToolFilm.py:1072 flatcamTools/ToolFilm.py:1252 msgid "Film file exported to" msgstr "Archivo de película exportado a" -#: flatcamTools/ToolFilm.py:1063 flatcamTools/ToolFilm.py:1238 +#: flatcamTools/ToolFilm.py:1075 flatcamTools/ToolFilm.py:1255 msgid "Generating Film ... Please wait." msgstr "Generando Película ... Por favor espere." @@ -14624,7 +15486,7 @@ msgstr "Imagen como objeto" msgid "Image to PCB" msgstr "Imagen a PCB" -#: flatcamTools/ToolImage.py:57 +#: flatcamTools/ToolImage.py:56 msgid "" "Specify the type of object to create from the image.\n" "It can be of type: Gerber or Geometry." @@ -14632,23 +15494,23 @@ msgstr "" "Especifique el tipo de objeto a crear a partir de la imagen.\n" "Puede ser de tipo: Gerber o Geometría." -#: flatcamTools/ToolImage.py:66 +#: flatcamTools/ToolImage.py:65 msgid "DPI value" msgstr "Valor de DPI" -#: flatcamTools/ToolImage.py:67 +#: flatcamTools/ToolImage.py:66 msgid "Specify a DPI value for the image." msgstr "Especifique un valor de DPI para la imagen." -#: flatcamTools/ToolImage.py:73 +#: flatcamTools/ToolImage.py:72 msgid "Level of detail" msgstr "Nivel de detalle" -#: flatcamTools/ToolImage.py:82 +#: flatcamTools/ToolImage.py:81 msgid "Image type" msgstr "Tipo de imagen" -#: flatcamTools/ToolImage.py:84 +#: flatcamTools/ToolImage.py:83 msgid "" "Choose a method for the image interpretation.\n" "B/W means a black & white image. Color means a colored image." @@ -14657,12 +15519,12 @@ msgstr "" "B / N significa una imagen en blanco y negro. Color significa una imagen en " "color." -#: flatcamTools/ToolImage.py:93 flatcamTools/ToolImage.py:108 -#: flatcamTools/ToolImage.py:121 flatcamTools/ToolImage.py:134 +#: flatcamTools/ToolImage.py:92 flatcamTools/ToolImage.py:107 +#: flatcamTools/ToolImage.py:120 flatcamTools/ToolImage.py:133 msgid "Mask value" msgstr "Valor de la máscara" -#: flatcamTools/ToolImage.py:95 +#: flatcamTools/ToolImage.py:94 msgid "" "Mask for monochrome image.\n" "Takes values between [0 ... 255].\n" @@ -14678,7 +15540,7 @@ msgstr "" "0 significa sin detalles y 255 significa todo\n" "(que es totalmente negro)" -#: flatcamTools/ToolImage.py:110 +#: flatcamTools/ToolImage.py:109 msgid "" "Mask for RED color.\n" "Takes values between [0 ... 255].\n" @@ -14690,7 +15552,7 @@ msgstr "" "Decide el nivel de detalles a incluir\n" "en la geometría resultante." -#: flatcamTools/ToolImage.py:123 +#: flatcamTools/ToolImage.py:122 msgid "" "Mask for GREEN color.\n" "Takes values between [0 ... 255].\n" @@ -14702,7 +15564,7 @@ msgstr "" "Decide el nivel de detalles a incluir\n" "en la geometría resultante." -#: flatcamTools/ToolImage.py:136 +#: flatcamTools/ToolImage.py:135 msgid "" "Mask for BLUE color.\n" "Takes values between [0 ... 255].\n" @@ -14714,33 +15576,59 @@ msgstr "" "Decide el nivel de detalles a incluir\n" "en la geometría resultante." -#: flatcamTools/ToolImage.py:144 +#: flatcamTools/ToolImage.py:143 msgid "Import image" msgstr "Importar imagen" -#: flatcamTools/ToolImage.py:146 +#: flatcamTools/ToolImage.py:145 msgid "Open a image of raster type and then import it in FlatCAM." msgstr "Abra una imagen de tipo ráster y luego impórtela en FlatCAM." -#: flatcamTools/ToolImage.py:183 +#: flatcamTools/ToolImage.py:182 msgid "Image Tool" msgstr "Herra. de imagen" -#: flatcamTools/ToolImage.py:235 flatcamTools/ToolImage.py:238 +#: flatcamTools/ToolImage.py:234 flatcamTools/ToolImage.py:237 msgid "Import IMAGE" msgstr "Importar IMAGEN" -#: flatcamTools/ToolImage.py:286 +#: flatcamTools/ToolImage.py:285 msgid "Importing Image" msgstr "Importando imagen" +#: flatcamTools/ToolInvertGerber.py:74 +msgid "Gerber object that will be inverted." +msgstr "Objeto de Gerber que se invertirá." + +#: flatcamTools/ToolInvertGerber.py:83 +msgid "Parameters for this tool" +msgstr "Parámetros para esta herram." + +#: flatcamTools/ToolInvertGerber.py:123 +msgid "Invert Gerber" +msgstr "Invertir Gerber" + +#: flatcamTools/ToolInvertGerber.py:125 +msgid "" +"Will invert the Gerber object: areas that have copper\n" +"will be empty of copper and previous empty area will be\n" +"filled with copper." +msgstr "" +"Invertirá el objeto Gerber: áreas que tienen cobre.\n" +"estará vacío de cobre y el área vacía anterior será\n" +"lleno de cobre." + +#: flatcamTools/ToolInvertGerber.py:184 +msgid "Invert Tool" +msgstr "Herram. de Inversión" + #: flatcamTools/ToolMove.py:103 msgid "MOVE: Click on the Start point ..." msgstr "MOVER: haga clic en el punto de inicio ..." #: flatcamTools/ToolMove.py:114 -msgid "MOVE action cancelled. No object(s) to move." -msgstr "MOVER acción cancelada. Ningún objeto (s) para mover." +msgid "Cancelled. No object(s) to move." +msgstr "Cancelado. Ningún objeto (s) para mover." #: flatcamTools/ToolMove.py:141 msgid "MOVE: Click on the Destination point ..." @@ -14754,19 +15642,15 @@ msgstr "Movedizo..." msgid "No object(s) selected." msgstr "No hay objetos seleccionados." -#: flatcamTools/ToolMove.py:212 +#: flatcamTools/ToolMove.py:222 msgid "Error when mouse left click." msgstr "Error al hacer clic con el botón izquierdo del mouse." -#: flatcamTools/ToolMove.py:260 -msgid "Move action cancelled." -msgstr "Mover acción cancelada." - -#: flatcamTools/ToolNonCopperClear.py:38 +#: flatcamTools/ToolNCC.py:42 msgid "Non-Copper Clearing" msgstr "Compensación sin cobre" -#: flatcamTools/ToolNonCopperClear.py:84 +#: flatcamTools/ToolNCC.py:88 msgid "" "Specify the type of object to be cleared of excess copper.\n" "It can be of type: Gerber or Geometry.\n" @@ -14778,11 +15662,11 @@ msgstr "" "Lo que se seleccione aquí dictará el tipo\n" "de objetos que llenarán el cuadro combinado 'Objeto'." -#: flatcamTools/ToolNonCopperClear.py:101 +#: flatcamTools/ToolNCC.py:110 msgid "Object to be cleared of excess copper." msgstr "Objeto a eliminar del exceso de cobre." -#: flatcamTools/ToolNonCopperClear.py:111 +#: flatcamTools/ToolNCC.py:122 msgid "" "Tools pool from which the algorithm\n" "will pick the ones used for copper clearing." @@ -14790,11 +15674,7 @@ msgstr "" "Conjunto de herramientas desde el cual el algoritmo\n" "elegirá los utilizados para la limpieza de cobre." -#: flatcamTools/ToolNonCopperClear.py:120 -msgid "Operation" -msgstr "Operación" - -#: flatcamTools/ToolNonCopperClear.py:126 +#: flatcamTools/ToolNCC.py:138 msgid "" "This is the Tool Number.\n" "Non copper clearing will start with the tool with the biggest \n" @@ -14811,7 +15691,7 @@ msgstr "" "en la geometría resultante. Esto es porque con algunas herramientas\n" "Esta función no podrá crear geometría de pintura." -#: flatcamTools/ToolNonCopperClear.py:134 +#: flatcamTools/ToolNCC.py:146 msgid "" "Tool Diameter. It's value (in current FlatCAM units)\n" "is the cut width into the material." @@ -14819,7 +15699,7 @@ msgstr "" "Diámetro de herramienta. Su valor (en unidades actuales de FlatCAM)\n" "es el ancho de corte en el material." -#: flatcamTools/ToolNonCopperClear.py:138 +#: flatcamTools/ToolNCC.py:150 msgid "" "The Tool Type (TT) can be:\n" "- Circular with 1 ... 4 teeth -> it is informative only. Being circular,\n" @@ -14857,33 +15737,7 @@ msgstr "" "seleccionará el Tipo de operación\n" "en la geometría resultante como aislamiento." -#: flatcamTools/ToolNonCopperClear.py:151 -msgid "" -"The 'Operation' can be:\n" -"- Isolation -> will ensure that the non-copper clearing is always complete.\n" -"If it's not successful then the non-copper clearing will fail, too.\n" -"- Clear -> the regular non-copper clearing." -msgstr "" -"La 'Operación' puede ser:\n" -"- Aislamiento -> asegurará que la limpieza sin cobre esté siempre completa.\n" -"Si no tiene éxito, la limpieza sin cobre también fallará.\n" -"- Borrar -> la limpieza regular sin cobre." - -#: flatcamTools/ToolNonCopperClear.py:209 -msgid "Tool Selection" -msgstr "Sel. de Herram" - -#: flatcamTools/ToolNonCopperClear.py:273 -msgid "" -"Diameter for the new tool to add in the Tool Table.\n" -"If the tool is V-shape type then this value is automatically\n" -"calculated from the other parameters." -msgstr "" -"Diámetro de la nueva herramienta para agregar en la Tabla de herramientas.\n" -"Si la herramienta es de tipo V, este valor es automáticamente\n" -"calculado a partir de los otros parámetros." - -#: flatcamTools/ToolNonCopperClear.py:288 flatcamTools/ToolPaint.py:190 +#: flatcamTools/ToolNCC.py:296 flatcamTools/ToolPaint.py:279 msgid "" "Add a new tool to the Tool Table\n" "with the diameter specified above." @@ -14891,8 +15745,8 @@ msgstr "" "Agregar una nueva herramienta a la tabla de herramientas\n" "con el diámetro especificado anteriormente." -#: flatcamTools/ToolNonCopperClear.py:300 flatcamTools/ToolPaint.py:202 -#: flatcamTools/ToolSolderPaste.py:129 +#: flatcamTools/ToolNCC.py:318 flatcamTools/ToolPaint.py:301 +#: flatcamTools/ToolSolderPaste.py:131 msgid "" "Delete a selection of tools in the Tool Table\n" "by first selecting a row(s) in the Tool Table." @@ -14900,23 +15754,7 @@ msgstr "" "Eliminar una selección de herramientas en la tabla de herramientas\n" "seleccionando primero una (s) fila (s) en la Tabla de herramientas." -#: flatcamTools/ToolNonCopperClear.py:435 -msgid "" -"- 'Itself' - the non copper clearing extent is based on the object that is " -"copper cleared.\n" -" - 'Area Selection' - left mouse click to start selection of the area to be " -"painted.\n" -"- 'Reference Object' - will do non copper clearing within the area specified " -"by another object." -msgstr "" -"- 'Sí mismo': la extensión de limpieza sin cobre se basa en el objeto que se " -"limpia con cobre.\n" -"- 'Selección de área': haga clic con el botón izquierdo del mouse para " -"iniciar la selección del área a pintar.\n" -"- 'Objeto de referencia': hará una limpieza sin cobre dentro del área " -"especificada por otro objeto." - -#: flatcamTools/ToolNonCopperClear.py:447 +#: flatcamTools/ToolNCC.py:554 msgid "" "The type of FlatCAM object to be used as non copper clearing reference.\n" "It can be Gerber, Excellon or Geometry." @@ -14925,121 +15763,126 @@ msgstr "" "sin cobre.\n" "Puede ser Gerber, Excellon o Geometry." -#: flatcamTools/ToolNonCopperClear.py:471 +#: flatcamTools/ToolNCC.py:597 flatcamTools/ToolPaint.py:537 msgid "Generate Geometry" msgstr "Generar Geometría" -#: flatcamTools/ToolNonCopperClear.py:582 flatcamTools/ToolPaint.py:493 -#: flatcamTools/ToolSolderPaste.py:553 -msgid "New Tool" -msgstr "Nueva Herram" - -#: flatcamTools/ToolNonCopperClear.py:981 flatcamTools/ToolPaint.py:766 -#: flatcamTools/ToolSolderPaste.py:887 +#: flatcamTools/ToolNCC.py:1420 flatcamTools/ToolPaint.py:1179 +#: flatcamTools/ToolSolderPaste.py:888 msgid "Please enter a tool diameter to add, in Float format." msgstr "Ingrese un diámetro de herramienta para agregar, en formato decimal." -#: flatcamTools/ToolNonCopperClear.py:1012 flatcamTools/ToolPaint.py:791 -msgid "Adding tool cancelled. Tool already in Tool Table." -msgstr "" -"Agregando herramienta cancelada. Herramienta ya en la tabla de herramientas." +#: flatcamTools/ToolNCC.py:1451 flatcamTools/ToolNCC.py:4008 +#: flatcamTools/ToolPaint.py:1203 flatcamTools/ToolPaint.py:3598 +#: flatcamTools/ToolSolderPaste.py:917 +msgid "Cancelled. Tool already in Tool Table." +msgstr "Cancelado. Herramienta ya en la tabla de herramientas." -#: flatcamTools/ToolNonCopperClear.py:1017 flatcamTools/ToolPaint.py:797 +#: flatcamTools/ToolNCC.py:1458 flatcamTools/ToolNCC.py:4025 +#: flatcamTools/ToolPaint.py:1208 flatcamTools/ToolPaint.py:3615 msgid "New tool added to Tool Table." msgstr "Nueva herramienta agregada a la Tabla de herramientas." -#: flatcamTools/ToolNonCopperClear.py:1061 flatcamTools/ToolPaint.py:843 +#: flatcamTools/ToolNCC.py:1502 flatcamTools/ToolPaint.py:1252 msgid "Tool from Tool Table was edited." msgstr "Se editó la herramienta de la tabla de herramientas." -#: flatcamTools/ToolNonCopperClear.py:1072 flatcamTools/ToolPaint.py:855 -#: flatcamTools/ToolSolderPaste.py:978 -msgid "Edit cancelled. New diameter value is already in the Tool Table." +#: flatcamTools/ToolNCC.py:1514 flatcamTools/ToolPaint.py:1264 +#: flatcamTools/ToolSolderPaste.py:977 +msgid "Cancelled. New diameter value is already in the Tool Table." msgstr "" -"Editar cancelado El nuevo valor del diámetro ya está en la Tabla de " -"herramientas." +"Cancelado. El nuevo valor del diámetro ya está en la Tabla de herramientas." -#: flatcamTools/ToolNonCopperClear.py:1119 flatcamTools/ToolPaint.py:953 +#: flatcamTools/ToolNCC.py:1566 flatcamTools/ToolPaint.py:1362 msgid "Delete failed. Select a tool to delete." msgstr "Eliminar falló. Seleccione una herramienta para eliminar." -#: flatcamTools/ToolNonCopperClear.py:1124 flatcamTools/ToolPaint.py:959 +#: flatcamTools/ToolNCC.py:1572 flatcamTools/ToolPaint.py:1368 msgid "Tool(s) deleted from Tool Table." msgstr "Herramienta (s) eliminada de la tabla de herramientas." -#: flatcamTools/ToolNonCopperClear.py:1171 +#: flatcamTools/ToolNCC.py:1614 msgid "Wrong Tool Dia value format entered, use a number." msgstr "" "Se ingresó un formato de valor de Diámetro de herramienta incorrecta, use un " "número." -#: flatcamTools/ToolNonCopperClear.py:1180 flatcamTools/ToolPaint.py:1023 +#: flatcamTools/ToolNCC.py:1623 flatcamTools/ToolPaint.py:1419 msgid "No selected tools in Tool Table." msgstr "Seleccione una herramienta en la tabla de herramientas." -#: flatcamTools/ToolNonCopperClear.py:1255 flatcamTools/ToolPaint.py:1195 +#: flatcamTools/ToolNCC.py:1699 flatcamTools/ToolPaint.py:1595 msgid "Click the end point of the paint area." msgstr "Haga clic en el punto final del área de pintura." -#: flatcamTools/ToolNonCopperClear.py:1410 -#: flatcamTools/ToolNonCopperClear.py:1412 -msgid "Non-Copper clearing ..." -msgstr "Limpieza sin cobre ..." - -#: flatcamTools/ToolNonCopperClear.py:1422 -msgid "NCC Tool started. Reading parameters." -msgstr "Herramienta NCC iniciada. Parámetros de lectura." - -#: flatcamTools/ToolNonCopperClear.py:1485 +#: flatcamTools/ToolNCC.py:1971 flatcamTools/ToolNCC.py:2959 msgid "NCC Tool. Preparing non-copper polygons." msgstr "Herramienta NCC. Preparación de polígonos sin cobre." -#: flatcamTools/ToolNonCopperClear.py:1581 +#: flatcamTools/ToolNCC.py:2030 flatcamTools/ToolNCC.py:3087 +msgid "NCC Tool. Calculate 'empty' area." +msgstr "Herramienta NCC. Calcule el área 'vacía'." + +#: flatcamTools/ToolNCC.py:2049 flatcamTools/ToolNCC.py:2155 +#: flatcamTools/ToolNCC.py:2169 flatcamTools/ToolNCC.py:3100 +#: flatcamTools/ToolNCC.py:3205 flatcamTools/ToolNCC.py:3220 +#: flatcamTools/ToolNCC.py:3486 flatcamTools/ToolNCC.py:3587 +#: flatcamTools/ToolNCC.py:3602 +msgid "Buffering finished" +msgstr "Buffering terminado" + +#: flatcamTools/ToolNCC.py:2057 flatcamTools/ToolNCC.py:2176 +#: flatcamTools/ToolNCC.py:3108 flatcamTools/ToolNCC.py:3227 +#: flatcamTools/ToolNCC.py:3493 flatcamTools/ToolNCC.py:3609 +msgid "Could not get the extent of the area to be non copper cleared." +msgstr "" +"No se pudo obtener la extensión del área que no fue limpiada con cobre." + +#: flatcamTools/ToolNCC.py:2084 flatcamTools/ToolNCC.py:2162 +#: flatcamTools/ToolNCC.py:3135 flatcamTools/ToolNCC.py:3212 +#: flatcamTools/ToolNCC.py:3513 flatcamTools/ToolNCC.py:3594 +msgid "" +"Isolation geometry is broken. Margin is less than isolation tool diameter." +msgstr "" +"La geometría de aislamiento está rota. El margen es menor que el diámetro de " +"la herramienta de aislamiento." + +#: flatcamTools/ToolNCC.py:2179 flatcamTools/ToolNCC.py:3231 +#: flatcamTools/ToolNCC.py:3612 +msgid "The selected object is not suitable for copper clearing." +msgstr "El objeto seleccionado no es adecuado para la limpieza de cobre." + +#: flatcamTools/ToolNCC.py:2186 flatcamTools/ToolNCC.py:3238 +msgid "NCC Tool. Finished calculation of 'empty' area." +msgstr "Herramienta NCC. Cálculo finalizado del área 'vacía'." + +#: flatcamTools/ToolNCC.py:2217 flatcamTools/ToolNCC.py:2219 +#: flatcamTools/ToolNCC.py:2911 flatcamTools/ToolNCC.py:2913 +msgid "Non-Copper clearing ..." +msgstr "Limpieza sin cobre ..." + +#: flatcamTools/ToolNCC.py:2273 flatcamTools/ToolNCC.py:3055 msgid "" "NCC Tool. Finished non-copper polygons. Normal copper clearing task started." msgstr "" "Herramienta NCC. Polígonos terminados sin cobre. Se inició la tarea normal " "de limpieza de cobre." -#: flatcamTools/ToolNonCopperClear.py:1613 -msgid "NCC Tool. Calculate 'empty' area." -msgstr "Herramienta NCC. Calcule el área 'vacía'." +#: flatcamTools/ToolNCC.py:2307 flatcamTools/ToolNCC.py:2587 +msgid "NCC Tool failed creating bounding box." +msgstr "La herramienta NCC no pudo crear el cuadro delimitador." -#: flatcamTools/ToolNonCopperClear.py:1626 -#: flatcamTools/ToolNonCopperClear.py:1723 -#: flatcamTools/ToolNonCopperClear.py:1735 -#: flatcamTools/ToolNonCopperClear.py:2018 -#: flatcamTools/ToolNonCopperClear.py:2114 -#: flatcamTools/ToolNonCopperClear.py:2126 -msgid "Buffering finished" -msgstr "Buffering terminado" +#: flatcamTools/ToolNCC.py:2321 flatcamTools/ToolNCC.py:2604 +#: flatcamTools/ToolNCC.py:3251 flatcamTools/ToolNCC.py:3637 +msgid "NCC Tool clearing with tool diameter" +msgstr "La Herram. NCC se está limpiando con el diá. de la herramienta" -#: flatcamTools/ToolNonCopperClear.py:1742 -#: flatcamTools/ToolNonCopperClear.py:2132 -msgid "The selected object is not suitable for copper clearing." -msgstr "El objeto seleccionado no es adecuado para la limpieza de cobre." - -#: flatcamTools/ToolNonCopperClear.py:1747 -#: flatcamTools/ToolNonCopperClear.py:2137 -msgid "Could not get the extent of the area to be non copper cleared." -msgstr "" -"No se pudo obtener la extensión del área que no fue limpiada con cobre." - -#: flatcamTools/ToolNonCopperClear.py:1754 -msgid "NCC Tool. Finished calculation of 'empty' area." -msgstr "Herramienta NCC. Cálculo finalizado del área 'vacía'." - -#: flatcamTools/ToolNonCopperClear.py:1768 -#: flatcamTools/ToolNonCopperClear.py:2162 -msgid "NCC Tool clearing with tool diameter = " -msgstr "Herram. NCC se está limpiando con el diá de la herram. = " - -#: flatcamTools/ToolNonCopperClear.py:1771 -#: flatcamTools/ToolNonCopperClear.py:2165 +#: flatcamTools/ToolNCC.py:2321 flatcamTools/ToolNCC.py:2604 +#: flatcamTools/ToolNCC.py:3251 flatcamTools/ToolNCC.py:3637 msgid "started." msgstr "empezado." -#: flatcamTools/ToolNonCopperClear.py:1947 +#: flatcamTools/ToolNCC.py:2513 flatcamTools/ToolNCC.py:3412 msgid "" "There is no NCC Geometry in the file.\n" "Usually it means that the tool diameter is too big for the painted " @@ -15051,26 +15894,26 @@ msgstr "" "grande para la geometría pintada.\n" "Cambie los parámetros de pintura e intente nuevamente." -#: flatcamTools/ToolNonCopperClear.py:1967 +#: flatcamTools/ToolNCC.py:2522 flatcamTools/ToolNCC.py:3421 msgid "NCC Tool clear all done." msgstr "Herramienta NCC borrar todo hecho." -#: flatcamTools/ToolNonCopperClear.py:1969 +#: flatcamTools/ToolNCC.py:2525 flatcamTools/ToolNCC.py:3424 msgid "NCC Tool clear all done but the copper features isolation is broken for" msgstr "" "La herramienta NCC borra todo, pero el aislamiento de las características de " "cobre está roto por" -#: flatcamTools/ToolNonCopperClear.py:1972 -#: flatcamTools/ToolNonCopperClear.py:2341 +#: flatcamTools/ToolNCC.py:2527 flatcamTools/ToolNCC.py:2812 +#: flatcamTools/ToolNCC.py:3426 flatcamTools/ToolNCC.py:3809 msgid "tools" msgstr "herramientas" -#: flatcamTools/ToolNonCopperClear.py:2337 +#: flatcamTools/ToolNCC.py:2808 flatcamTools/ToolNCC.py:3805 msgid "NCC Tool Rest Machining clear all done." msgstr "NCC herramienta de mecanizado de reposo claro todo hecho." -#: flatcamTools/ToolNonCopperClear.py:2340 +#: flatcamTools/ToolNCC.py:2811 flatcamTools/ToolNCC.py:3808 msgid "" "NCC Tool Rest Machining clear all done but the copper features isolation is " "broken for" @@ -15078,7 +15921,11 @@ msgstr "" "El mecanizado de reposo de herramientas NCC está claro, pero el aislamiento " "de características de cobre está roto por" -#: flatcamTools/ToolNonCopperClear.py:2787 +#: flatcamTools/ToolNCC.py:2923 +msgid "NCC Tool started. Reading parameters." +msgstr "Herramienta NCC iniciada. Parámetros de lectura." + +#: flatcamTools/ToolNCC.py:3901 msgid "" "Try to use the Buffering Type = Full in Preferences -> Gerber General. " "Reload the Gerber file after this change." @@ -15087,43 +15934,43 @@ msgstr "" "Preferencias -> Gerber General. Vuelva a cargar el archivo Gerber después de " "este cambio." -#: flatcamTools/ToolOptimal.py:79 +#: flatcamTools/ToolOptimal.py:80 msgid "Number of decimals kept for found distances." msgstr "Número de decimales guardados para distancias encontradas." -#: flatcamTools/ToolOptimal.py:87 +#: flatcamTools/ToolOptimal.py:88 msgid "Minimum distance" msgstr "Distancia minima" -#: flatcamTools/ToolOptimal.py:88 +#: flatcamTools/ToolOptimal.py:89 msgid "Display minimum distance between copper features." msgstr "Mostrar la distancia mínima entre las características de cobre." -#: flatcamTools/ToolOptimal.py:92 +#: flatcamTools/ToolOptimal.py:93 msgid "Determined" msgstr "Determinado" -#: flatcamTools/ToolOptimal.py:106 +#: flatcamTools/ToolOptimal.py:107 msgid "Occurring" msgstr "Ocurriendo" -#: flatcamTools/ToolOptimal.py:107 +#: flatcamTools/ToolOptimal.py:108 msgid "How many times this minimum is found." msgstr "Cuántas veces se encuentra este mínimo." -#: flatcamTools/ToolOptimal.py:113 +#: flatcamTools/ToolOptimal.py:114 msgid "Minimum points coordinates" msgstr "Coordenadas de puntos mínimos" -#: flatcamTools/ToolOptimal.py:114 flatcamTools/ToolOptimal.py:120 +#: flatcamTools/ToolOptimal.py:115 flatcamTools/ToolOptimal.py:121 msgid "Coordinates for points where minimum distance was found." msgstr "Coordenadas para los puntos donde se encontró la distancia mínima." -#: flatcamTools/ToolOptimal.py:133 flatcamTools/ToolOptimal.py:209 +#: flatcamTools/ToolOptimal.py:134 flatcamTools/ToolOptimal.py:210 msgid "Jump to selected position" msgstr "Saltar a la posición seleccionada" -#: flatcamTools/ToolOptimal.py:135 flatcamTools/ToolOptimal.py:211 +#: flatcamTools/ToolOptimal.py:136 flatcamTools/ToolOptimal.py:212 msgid "" "Select a position in the Locations text box and then\n" "click this button." @@ -15131,11 +15978,11 @@ msgstr "" "Seleccione una posición en el cuadro de texto Ubicaciones y luego\n" "haga clic en este botón." -#: flatcamTools/ToolOptimal.py:143 +#: flatcamTools/ToolOptimal.py:144 msgid "Other distances" msgstr "Otras distancias" -#: flatcamTools/ToolOptimal.py:144 +#: flatcamTools/ToolOptimal.py:145 msgid "" "Will display other distances in the Gerber file ordered from\n" "the minimum to the maximum, not including the absolute minimum." @@ -15143,13 +15990,13 @@ msgstr "" "Mostrará otras distancias en el archivo Gerber ordenado a\n" "el mínimo al máximo, sin incluir el mínimo absoluto." -#: flatcamTools/ToolOptimal.py:149 +#: flatcamTools/ToolOptimal.py:150 msgid "Other distances points coordinates" msgstr "Otras distancias puntos coordenadas" -#: flatcamTools/ToolOptimal.py:150 flatcamTools/ToolOptimal.py:164 -#: flatcamTools/ToolOptimal.py:171 flatcamTools/ToolOptimal.py:188 -#: flatcamTools/ToolOptimal.py:195 +#: flatcamTools/ToolOptimal.py:151 flatcamTools/ToolOptimal.py:165 +#: flatcamTools/ToolOptimal.py:172 flatcamTools/ToolOptimal.py:189 +#: flatcamTools/ToolOptimal.py:196 msgid "" "Other distances and the coordinates for points\n" "where the distance was found." @@ -15157,19 +16004,19 @@ msgstr "" "Otras distancias y las coordenadas de los puntos.\n" "donde se encontró la distancia." -#: flatcamTools/ToolOptimal.py:163 +#: flatcamTools/ToolOptimal.py:164 msgid "Gerber distances" msgstr "Distancias de Gerber" -#: flatcamTools/ToolOptimal.py:187 +#: flatcamTools/ToolOptimal.py:188 msgid "Points coordinates" msgstr "Coordenadas de puntos" -#: flatcamTools/ToolOptimal.py:219 +#: flatcamTools/ToolOptimal.py:220 msgid "Find Minimum" msgstr "Encuentra mínimo" -#: flatcamTools/ToolOptimal.py:221 +#: flatcamTools/ToolOptimal.py:222 msgid "" "Calculate the minimum distance between copper features,\n" "this will allow the determination of the right tool to\n" @@ -15179,11 +16026,11 @@ msgstr "" "esto permitirá determinar la herramienta adecuada para\n" "utilizar para aislamiento o limpieza de cobre." -#: flatcamTools/ToolOptimal.py:346 +#: flatcamTools/ToolOptimal.py:347 msgid "Only Gerber objects can be evaluated." msgstr "Solo se pueden evaluar los objetos de Gerber." -#: flatcamTools/ToolOptimal.py:352 +#: flatcamTools/ToolOptimal.py:353 msgid "" "Optimal Tool. Started to search for the minimum distance between copper " "features." @@ -15191,15 +16038,15 @@ msgstr "" "Herramienta óptima. Comenzó a buscar la distancia mínima entre las " "características de cobre." -#: flatcamTools/ToolOptimal.py:362 +#: flatcamTools/ToolOptimal.py:363 msgid "Optimal Tool. Parsing geometry for aperture" msgstr "Herramienta óptima. Análisis de geometría para apertura" -#: flatcamTools/ToolOptimal.py:373 +#: flatcamTools/ToolOptimal.py:374 msgid "Optimal Tool. Creating a buffer for the object geometry." msgstr "Herramienta óptima. Crear un búfer para la geometría del objeto." -#: flatcamTools/ToolOptimal.py:383 +#: flatcamTools/ToolOptimal.py:384 msgid "" "The Gerber object has one Polygon as geometry.\n" "There are no distances between geometry elements to be found." @@ -15207,18 +16054,18 @@ msgstr "" "El objeto Gerber tiene un Polígono como geometría.\n" "No hay distancias entre los elementos de geometría que se encuentran." -#: flatcamTools/ToolOptimal.py:388 +#: flatcamTools/ToolOptimal.py:389 msgid "" "Optimal Tool. Finding the distances between each two elements. Iterations" msgstr "" "Herramienta óptima. Encontrar las distancias entre cada dos elementos. " "Iteraciones" -#: flatcamTools/ToolOptimal.py:423 +#: flatcamTools/ToolOptimal.py:424 msgid "Optimal Tool. Finding the minimum distance." msgstr "Herramienta óptima. Encontrar la distancia mínima." -#: flatcamTools/ToolOptimal.py:439 +#: flatcamTools/ToolOptimal.py:440 msgid "Optimal Tool. Finished successfully." msgstr "Herramienta óptima. Terminado con éxito." @@ -15247,7 +16094,7 @@ msgstr "El archivo PDF abierto ha fallado." msgid "Rendered" msgstr "Rendido" -#: flatcamTools/ToolPaint.py:87 +#: flatcamTools/ToolPaint.py:82 msgid "" "Specify the type of object to be painted.\n" "It can be of type: Gerber or Geometry.\n" @@ -15263,7 +16110,7 @@ msgstr "" msgid "Object to be painted." msgstr "Objeto a pintar." -#: flatcamTools/ToolPaint.py:114 +#: flatcamTools/ToolPaint.py:117 msgid "" "Tools pool from which the algorithm\n" "will pick the ones used for painting." @@ -15271,7 +16118,7 @@ msgstr "" "Conjunto de herramientas desde el cual el algoritmo\n" "elegirá los que se usan para pintar." -#: flatcamTools/ToolPaint.py:129 +#: flatcamTools/ToolPaint.py:134 msgid "" "This is the Tool Number.\n" "Painting will start with the tool with the biggest diameter,\n" @@ -15287,7 +16134,7 @@ msgstr "" "en la geometría resultante. Esto es porque con algunas herramientas\n" "Esta función no podrá crear geometría de pintura." -#: flatcamTools/ToolPaint.py:141 +#: flatcamTools/ToolPaint.py:146 msgid "" "The Tool Type (TT) can be:
- Circular with 1 ... 4 teeth -> it is " "informative only. Being circular,
the cut width in material is exactly " @@ -15313,52 +16160,7 @@ msgstr "" "automáticamente el Tipo de operación en la geometría resultante como " "Aislamiento." -#: flatcamTools/ToolPaint.py:178 -msgid "Diameter for the new tool." -msgstr "Diámetro para la nueva herramienta." - -#: flatcamTools/ToolPaint.py:253 -msgid "" -"Algorithm for painting:\n" -"- Standard: Fixed step inwards.\n" -"- Seed-based: Outwards from seed.\n" -"- Line-based: Parallel lines." -msgstr "" -"Algoritmo para pintar:\n" -"- Estándar: paso fijo hacia adentro.\n" -"- Basado en semillas: hacia afuera de la semilla.\n" -"- Basado en líneas: líneas paralelas." - -#: flatcamTools/ToolPaint.py:283 -msgid "" -"If checked, use 'rest machining'.\n" -"Basically it will clear copper outside PCB features,\n" -"using the biggest tool and continue with the next tools,\n" -"from bigger to smaller, to clear areas of copper that\n" -"could not be cleared by previous tool, until there is\n" -"no more copper to clear or there are no more tools.\n" -"\n" -"If not checked, use the standard algorithm." -msgstr "" -"Si está marcado, use 'mecanizado en reposo'.\n" -"Básicamente eliminará el cobre fuera de las características de la PCB,\n" -"utilizando la herramienta más grande y continúe con las siguientes " -"herramientas,\n" -"de mayor a menor, para limpiar áreas de cobre que\n" -"no se pudo borrar con la herramienta anterior, hasta que haya\n" -"no más cobre para limpiar o no hay más herramientas.\n" -"\n" -"Si no está marcado, use el algoritmo estándar." - -#: flatcamTools/ToolPaint.py:307 -msgid "Polygon Selection" -msgstr "Selección de polígono" - -#: flatcamTools/ToolPaint.py:309 -msgid "All Polygons" -msgstr "Todos los polígonos" - -#: flatcamTools/ToolPaint.py:328 +#: flatcamTools/ToolPaint.py:498 msgid "" "The type of FlatCAM object to be used as paint reference.\n" "It can be Gerber, Excellon or Geometry." @@ -15366,11 +16168,7 @@ msgstr "" "El tipo de objeto FlatCAM que se utilizará como referencia de pintura.\n" "Puede ser Gerber, Excellon o Geometry." -#: flatcamTools/ToolPaint.py:353 -msgid "Create Paint Geometry" -msgstr "Crear geometría de pintura" - -#: flatcamTools/ToolPaint.py:355 +#: flatcamTools/ToolPaint.py:539 msgid "" "- 'Area Selection' - left mouse click to start selection of the area to be " "painted.\n" @@ -15388,72 +16186,99 @@ msgstr "" "- 'Objeto de referencia' - hará una limpieza sin cobre dentro del área\n" "especificado por otro objeto." -#: flatcamTools/ToolPaint.py:973 -msgid "Paint Tool. Reading parameters." -msgstr "Herramienta de pintura. Parámetros de lectura." - -#: flatcamTools/ToolPaint.py:988 +#: flatcamTools/ToolPaint.py:1388 #, python-format msgid "Could not retrieve object: %s" msgstr "No se pudo recuperar el objeto: %s" -#: flatcamTools/ToolPaint.py:1002 +#: flatcamTools/ToolPaint.py:1398 msgid "Can't do Paint on MultiGeo geometries" msgstr "No se puede Pintar en geometrías de geo-múltiple" -#: flatcamTools/ToolPaint.py:1035 +#: flatcamTools/ToolPaint.py:1428 msgid "Click on a polygon to paint it." msgstr "Haga clic en un polígono para pintarlo." -#: flatcamTools/ToolPaint.py:1054 +#: flatcamTools/ToolPaint.py:1448 msgid "Click the start point of the paint area." msgstr "Haga clic en el punto de inicio del área de pintura." -#: flatcamTools/ToolPaint.py:1122 +#: flatcamTools/ToolPaint.py:1513 msgid "Click to add next polygon or right click to start painting." msgstr "" "Haga clic para agregar el siguiente polígono o haga clic con el botón " "derecho para comenzar a pintar." -#: flatcamTools/ToolPaint.py:1135 +#: flatcamTools/ToolPaint.py:1526 msgid "Click to add/remove next polygon or right click to start painting." msgstr "" "Haga clic para agregar / eliminar el siguiente polígono o haga clic con el " "botón derecho para comenzar a pintar." -#: flatcamTools/ToolPaint.py:1344 flatcamTools/ToolPaint.py:1347 -#: flatcamTools/ToolPaint.py:1349 flatcamTools/ToolPaint.py:1987 -#: flatcamTools/ToolPaint.py:1991 flatcamTools/ToolPaint.py:1994 -#: flatcamTools/ToolPaint.py:2276 flatcamTools/ToolPaint.py:2281 -#: flatcamTools/ToolPaint.py:2284 flatcamTools/ToolPaint.py:2458 -#: flatcamTools/ToolPaint.py:2465 -msgid "Paint Tool." -msgstr "Herramienta de Pintura." +#: flatcamTools/ToolPaint.py:2024 +msgid "Painting polygon with method: lines." +msgstr "Pintura poligonal con método: líneas." -#: flatcamTools/ToolPaint.py:1344 flatcamTools/ToolPaint.py:1347 -#: flatcamTools/ToolPaint.py:1349 -msgid "Normal painting polygon task started." -msgstr "Se inició la tarea normal de polígono de pintura." +#: flatcamTools/ToolPaint.py:2036 +msgid "Failed. Painting polygon with method: seed." +msgstr "Ha fallado. Pintura poligonal con método: semilla." -#: flatcamTools/ToolPaint.py:1345 flatcamTools/ToolPaint.py:1706 -#: flatcamTools/ToolPaint.py:1988 flatcamTools/ToolPaint.py:2278 -#: flatcamTools/ToolPaint.py:2460 -msgid "Buffering geometry..." -msgstr "Almacenar la geometría ..." +#: flatcamTools/ToolPaint.py:2047 +msgid "Failed. Painting polygon with method: standard." +msgstr "Ha fallado. Pintura poligonal con método: estándar." -#: flatcamTools/ToolPaint.py:1367 -msgid "No polygon found." -msgstr "No se encontró polígono." - -#: flatcamTools/ToolPaint.py:1401 -msgid "Painting polygon..." -msgstr "Pintar polígono ..." - -#: flatcamTools/ToolPaint.py:1448 +#: flatcamTools/ToolPaint.py:2063 msgid "Geometry could not be painted completely" msgstr "La Geometría no se pudo pintar completamente" -#: flatcamTools/ToolPaint.py:1481 +#: flatcamTools/ToolPaint.py:2092 flatcamTools/ToolPaint.py:2095 +#: flatcamTools/ToolPaint.py:2103 flatcamTools/ToolPaint.py:2406 +#: flatcamTools/ToolPaint.py:2409 flatcamTools/ToolPaint.py:2417 +#: flatcamTools/ToolPaint.py:2905 flatcamTools/ToolPaint.py:2908 +#: flatcamTools/ToolPaint.py:2914 +msgid "Paint Tool." +msgstr "Herramienta de Pintura." + +#: flatcamTools/ToolPaint.py:2092 flatcamTools/ToolPaint.py:2095 +#: flatcamTools/ToolPaint.py:2103 +msgid "Normal painting polygon task started." +msgstr "Se inició la tarea normal de polígono de pintura." + +#: flatcamTools/ToolPaint.py:2093 flatcamTools/ToolPaint.py:2407 +#: flatcamTools/ToolPaint.py:2906 +msgid "Buffering geometry..." +msgstr "Almacenar la geometría ..." + +#: flatcamTools/ToolPaint.py:2115 flatcamTools/ToolPaint.py:2424 +#: flatcamTools/ToolPaint.py:2922 +msgid "No polygon found." +msgstr "No se encontró polígono." + +#: flatcamTools/ToolPaint.py:2145 +msgid "Painting polygon..." +msgstr "Pintar polígono ..." + +#: flatcamTools/ToolPaint.py:2155 flatcamTools/ToolPaint.py:2470 +#: flatcamTools/ToolPaint.py:2660 flatcamTools/ToolPaint.py:2968 +#: flatcamTools/ToolPaint.py:3147 +msgid "Painting with tool diameter = " +msgstr "Pintar con diá de herram. = " + +#: flatcamTools/ToolPaint.py:2156 flatcamTools/ToolPaint.py:2471 +#: flatcamTools/ToolPaint.py:2661 flatcamTools/ToolPaint.py:2969 +#: flatcamTools/ToolPaint.py:3148 +msgid "started" +msgstr "empezado" + +#: flatcamTools/ToolPaint.py:2181 flatcamTools/ToolPaint.py:2497 +#: flatcamTools/ToolPaint.py:2687 flatcamTools/ToolPaint.py:2995 +#: flatcamTools/ToolPaint.py:3174 +msgid "Margin parameter too big. Tool is not used" +msgstr "El parámetro de margen es demasiado grande. La herramienta no se usa" + +#: flatcamTools/ToolPaint.py:2239 flatcamTools/ToolPaint.py:2566 +#: flatcamTools/ToolPaint.py:2744 flatcamTools/ToolPaint.py:3058 +#: flatcamTools/ToolPaint.py:3236 msgid "" "Could not do Paint. Try a different combination of parameters. Or a " "different strategy of paint" @@ -15461,9 +16286,9 @@ msgstr "" "No se pudo Pintar. Pruebe con una combinación diferente de parámetros. O una " "estrategia diferente de pintura" -#: flatcamTools/ToolPaint.py:1533 flatcamTools/ToolPaint.py:1967 -#: flatcamTools/ToolPaint.py:2117 flatcamTools/ToolPaint.py:2438 -#: flatcamTools/ToolPaint.py:2592 +#: flatcamTools/ToolPaint.py:2296 flatcamTools/ToolPaint.py:2632 +#: flatcamTools/ToolPaint.py:2801 flatcamTools/ToolPaint.py:3119 +#: flatcamTools/ToolPaint.py:3298 msgid "" "There is no Painting Geometry in the file.\n" "Usually it means that the tool diameter is too big for the painted " @@ -15475,80 +16300,66 @@ msgstr "" "grande para la geometría pintada.\n" "Cambie los parámetros de pintura e intente nuevamente." -#: flatcamTools/ToolPaint.py:1539 +#: flatcamTools/ToolPaint.py:2319 +msgid "Paint Single failed." +msgstr "La pintura sola falló." + +#: flatcamTools/ToolPaint.py:2325 msgid "Paint Single Done." msgstr "Pintar solo hecho." -#: flatcamTools/ToolPaint.py:1571 flatcamTools/ToolPaint.py:2145 -#: flatcamTools/ToolPaint.py:2620 +#: flatcamTools/ToolPaint.py:2327 flatcamTools/ToolPaint.py:2837 +#: flatcamTools/ToolPaint.py:3334 msgid "Polygon Paint started ..." msgstr "Polygon Pinta comenzó ..." -#: flatcamTools/ToolPaint.py:1623 flatcamTools/ToolPaint.py:2207 +#: flatcamTools/ToolPaint.py:2406 flatcamTools/ToolPaint.py:2409 +#: flatcamTools/ToolPaint.py:2417 +msgid "Paint all polygons task started." +msgstr "La tarea de pintar todos los polígonos comenzó." + +#: flatcamTools/ToolPaint.py:2448 flatcamTools/ToolPaint.py:2946 msgid "Painting polygons..." msgstr "Pintar polígonos ..." -#: flatcamTools/ToolPaint.py:1705 flatcamTools/ToolPaint.py:1708 -#: flatcamTools/ToolPaint.py:1710 -msgid "Paint Tool. Normal painting all task started." -msgstr "Herramienta de pintura. La pintura normal comenzó toda tarea." - -#: flatcamTools/ToolPaint.py:1744 flatcamTools/ToolPaint.py:2023 -#: flatcamTools/ToolPaint.py:2325 flatcamTools/ToolPaint.py:2501 -msgid "Painting with tool diameter = " -msgstr "Pintar con diá de herram. = " - -#: flatcamTools/ToolPaint.py:1747 flatcamTools/ToolPaint.py:2026 -#: flatcamTools/ToolPaint.py:2328 flatcamTools/ToolPaint.py:2504 -msgid "started" -msgstr "empezado" - -#: flatcamTools/ToolPaint.py:1976 +#: flatcamTools/ToolPaint.py:2641 msgid "Paint All Done." msgstr "Pintar todo listo." -#: flatcamTools/ToolPaint.py:1987 flatcamTools/ToolPaint.py:1991 -#: flatcamTools/ToolPaint.py:1994 -msgid "Rest machining painting all task started." -msgstr "Resto mecanizado pintando toda la tarea iniciada." - -#: flatcamTools/ToolPaint.py:2072 flatcamTools/ToolPaint.py:2388 -#: flatcamTools/ToolPaint.py:2548 -msgid "" -"Could not do Paint All. Try a different combination of parameters. Or a " -"different Method of paint" -msgstr "" -"No se pudo Pintar Todo. Pruebe con una combinación diferente de parámetros. " -"O un método diferente de pintura" - -#: flatcamTools/ToolPaint.py:2126 flatcamTools/ToolPaint.py:2601 +#: flatcamTools/ToolPaint.py:2810 flatcamTools/ToolPaint.py:3307 msgid "Paint All with Rest-Machining done." msgstr "Pinte Todo con el mecanizado de descanso hecho." -#: flatcamTools/ToolPaint.py:2277 flatcamTools/ToolPaint.py:2281 -#: flatcamTools/ToolPaint.py:2284 -msgid "Normal painting area task started." -msgstr "Se inició la tarea normal del área de pintura." +#: flatcamTools/ToolPaint.py:2829 +msgid "Paint All failed." +msgstr "Pintar todo falló." -#: flatcamTools/ToolPaint.py:2447 +#: flatcamTools/ToolPaint.py:2835 +msgid "Paint Poly All Done." +msgstr "Pintar todos los polígonos está hecho." + +#: flatcamTools/ToolPaint.py:2905 flatcamTools/ToolPaint.py:2908 +#: flatcamTools/ToolPaint.py:2914 +msgid "Painting area task started." +msgstr "La tarea del área de pintura comenzó." + +#: flatcamTools/ToolPaint.py:3128 msgid "Paint Area Done." msgstr "Área de pintura hecha." -#: flatcamTools/ToolPaint.py:2459 flatcamTools/ToolPaint.py:2465 -msgid "Rest machining painting area task started." -msgstr "Se inició la tarea de área de pintura de mecanizado en reposo." +#: flatcamTools/ToolPaint.py:3326 +msgid "Paint Area failed." +msgstr "Pintar el área falló." -#: flatcamTools/ToolPaint.py:2462 -msgid "Paint Tool. Rest machining painting area task started." -msgstr "" -"Herramienta de pintura. Se inició la tarea de área de pintura de mecanizado " -"de descanso." +#: flatcamTools/ToolPaint.py:3332 +msgid "Paint Poly Area Done." +msgstr "Pintar el área de polígonos está hecho." #: flatcamTools/ToolPanelize.py:34 msgid "Panelize PCB" msgstr "Panelizar PCB" -#: flatcamTools/ToolPanelize.py:68 +#: flatcamTools/ToolPanelize.py:56 msgid "" "Specify the type of object to be panelized\n" "It can be of type: Gerber, Excellon or Geometry.\n" @@ -15560,7 +16371,7 @@ msgstr "" "La selección aquí decide el tipo de objetos que serán\n" "en el cuadro combinado Objeto." -#: flatcamTools/ToolPanelize.py:83 +#: flatcamTools/ToolPanelize.py:89 msgid "" "Object to be panelized. This means that it will\n" "be duplicated in an array of rows and columns." @@ -15568,11 +16379,11 @@ msgstr "" "Objeto a ser panelizado. Esto significa que lo hará\n" "ser duplicado en una matriz de filas y columnas." -#: flatcamTools/ToolPanelize.py:96 +#: flatcamTools/ToolPanelize.py:102 msgid "Penelization Reference" msgstr "Ref. de penelización" -#: flatcamTools/ToolPanelize.py:98 +#: flatcamTools/ToolPanelize.py:104 msgid "" "Choose the reference for panelization:\n" "- Object = the bounding box of a different object\n" @@ -15592,11 +16403,11 @@ msgstr "" "a este objeto de referencia, por lo tanto, manteniendo el panelizado\n" "objetos sincronizados." -#: flatcamTools/ToolPanelize.py:121 +#: flatcamTools/ToolPanelize.py:125 msgid "Box Type" msgstr "Tipo de caja" -#: flatcamTools/ToolPanelize.py:123 +#: flatcamTools/ToolPanelize.py:127 msgid "" "Specify the type of object to be used as an container for\n" "panelization. It can be: Gerber or Geometry type.\n" @@ -15608,7 +16419,7 @@ msgstr "" "La selección aquí decide el tipo de objetos que serán\n" "en el cuadro combinado Objeto de caja." -#: flatcamTools/ToolPanelize.py:138 +#: flatcamTools/ToolPanelize.py:141 msgid "" "The actual object that is used a container for the\n" " selected object that is to be panelized." @@ -15616,11 +16427,11 @@ msgstr "" "El objeto real que se utiliza como contenedor para\n" " objeto seleccionado que se va a panelizar." -#: flatcamTools/ToolPanelize.py:144 +#: flatcamTools/ToolPanelize.py:147 msgid "Panel Data" msgstr "Datos del panel" -#: flatcamTools/ToolPanelize.py:146 +#: flatcamTools/ToolPanelize.py:149 msgid "" "This informations will shape the resulting panel.\n" "The number of rows and columns will set how many\n" @@ -15636,7 +16447,7 @@ msgstr "" "Los espacios establecerán la distancia entre dos\n" "elementos de la matriz de paneles." -#: flatcamTools/ToolPanelize.py:205 +#: flatcamTools/ToolPanelize.py:208 msgid "" "Choose the type of object for the panel object:\n" "- Geometry\n" @@ -15646,15 +16457,15 @@ msgstr "" "- Geometría\n" "- Gerber" -#: flatcamTools/ToolPanelize.py:213 +#: flatcamTools/ToolPanelize.py:216 msgid "Constrain panel within" msgstr "Restrinja el panel dentro de" -#: flatcamTools/ToolPanelize.py:249 +#: flatcamTools/ToolPanelize.py:252 msgid "Panelize Object" msgstr "Panelizar objeto" -#: flatcamTools/ToolPanelize.py:251 flatcamTools/ToolRulesCheck.py:492 +#: flatcamTools/ToolPanelize.py:254 flatcamTools/ToolRulesCheck.py:501 msgid "" "Panelize the specified object around the specified box.\n" "In other words it creates multiple copies of the source object,\n" @@ -15664,32 +16475,32 @@ msgstr "" "En otras palabras, crea múltiples copias del objeto fuente,\n" "dispuestos en una matriz 2D de filas y columnas." -#: flatcamTools/ToolPanelize.py:319 +#: flatcamTools/ToolPanelize.py:322 msgid "Panel. Tool" msgstr "Herra. de Panel" -#: flatcamTools/ToolPanelize.py:448 +#: flatcamTools/ToolPanelize.py:460 msgid "Columns or Rows are zero value. Change them to a positive integer." msgstr "" "Las columnas o filas son de valor cero. Cámbialos a un entero positivo." -#: flatcamTools/ToolPanelize.py:485 +#: flatcamTools/ToolPanelize.py:497 msgid "Generating panel ... " msgstr "Panel generador … " -#: flatcamTools/ToolPanelize.py:768 +#: flatcamTools/ToolPanelize.py:777 msgid "Generating panel ... Adding the Gerber code." msgstr "Generando panel ... Agregando el código Gerber." -#: flatcamTools/ToolPanelize.py:779 +#: flatcamTools/ToolPanelize.py:788 msgid "Generating panel... Spawning copies" msgstr "Generando panel ... Generando copias" -#: flatcamTools/ToolPanelize.py:786 +#: flatcamTools/ToolPanelize.py:795 msgid "Panel done..." msgstr "Panel hecho ..." -#: flatcamTools/ToolPanelize.py:789 +#: flatcamTools/ToolPanelize.py:798 #, python-brace-format msgid "" "{text} Too big for the constrain area. Final panel has {col} columns and " @@ -15698,7 +16509,7 @@ msgstr "" "{text} Demasiado grande para el área de restricción. El panel final tiene " "{col} columnas y {row} filas" -#: flatcamTools/ToolPanelize.py:798 +#: flatcamTools/ToolPanelize.py:807 msgid "Panel created successfully." msgstr "Panel creado con éxito." @@ -15838,163 +16649,214 @@ msgstr "PcbWizard .INF archivo cargado." msgid "Main PcbWizard Excellon file loaded." msgstr "Archivo PcbWizard Excellon principal cargado." -#: flatcamTools/ToolPcbWizard.py:431 +#: flatcamTools/ToolPcbWizard.py:428 msgid "Cannot parse file" msgstr "No se puede analizar el archivo" -#: flatcamTools/ToolPcbWizard.py:456 +#: flatcamTools/ToolPcbWizard.py:452 msgid "Importing Excellon." msgstr "Importando Excellon." -#: flatcamTools/ToolPcbWizard.py:463 +#: flatcamTools/ToolPcbWizard.py:459 msgid "Import Excellon file failed." msgstr "Error al importar el archivo Excellon." -#: flatcamTools/ToolPcbWizard.py:471 +#: flatcamTools/ToolPcbWizard.py:467 msgid "Imported" msgstr "Importado" -#: flatcamTools/ToolPcbWizard.py:475 +#: flatcamTools/ToolPcbWizard.py:471 msgid "Excellon merging is in progress. Please wait..." msgstr "La fusión de Excellon está en progreso. Por favor espera..." -#: flatcamTools/ToolPcbWizard.py:478 +#: flatcamTools/ToolPcbWizard.py:474 msgid "The imported Excellon file is None." msgstr "El archivo Excellon importado es Ninguno." -#: flatcamTools/ToolProperties.py:119 -msgid "Properties Tool was not displayed. No object selected." -msgstr "La herramienta Propiedades no se mostró. Ningún objeto seleccionado." - -#: flatcamTools/ToolProperties.py:134 +#: flatcamTools/ToolProperties.py:131 msgid "Object Properties are displayed." msgstr "Se muestran las propiedades del objeto." -#: flatcamTools/ToolProperties.py:135 +#: flatcamTools/ToolProperties.py:136 msgid "Properties Tool" msgstr "Herra. de Propiedades" -#: flatcamTools/ToolProperties.py:149 +#: flatcamTools/ToolProperties.py:150 msgid "TYPE" msgstr "TIPO" -#: flatcamTools/ToolProperties.py:150 +#: flatcamTools/ToolProperties.py:151 msgid "NAME" msgstr "NOMBRE" -#: flatcamTools/ToolProperties.py:151 +#: flatcamTools/ToolProperties.py:153 msgid "Dimensions" msgstr "Dimensiones" -#: flatcamTools/ToolProperties.py:165 -msgid "Others" -msgstr "Otros" - -#: flatcamTools/ToolProperties.py:172 +#: flatcamTools/ToolProperties.py:181 msgid "Geo Type" msgstr "Tipo de Geo" -#: flatcamTools/ToolProperties.py:173 +#: flatcamTools/ToolProperties.py:184 msgid "Single-Geo" msgstr "Geo. individual" -#: flatcamTools/ToolProperties.py:173 +#: flatcamTools/ToolProperties.py:185 msgid "Multi-Geo" msgstr "Geo. múltiple" -#: flatcamTools/ToolProperties.py:181 +#: flatcamTools/ToolProperties.py:196 msgid "Calculating dimensions ... Please wait." msgstr "Calculando dimensiones ... Por favor espere." -#: flatcamTools/ToolProperties.py:321 flatcamTools/ToolProperties.py:325 -#: flatcamTools/ToolProperties.py:327 +#: flatcamTools/ToolProperties.py:339 flatcamTools/ToolProperties.py:343 +#: flatcamTools/ToolProperties.py:345 msgid "Inch" msgstr "Pulgada" -#: flatcamTools/ToolProperties.py:321 flatcamTools/ToolProperties.py:326 -#: flatcamTools/ToolProperties.py:328 +#: flatcamTools/ToolProperties.py:339 flatcamTools/ToolProperties.py:344 +#: flatcamTools/ToolProperties.py:346 msgid "Metric" msgstr "Métrico" -#: flatcamTools/ToolProperties.py:401 flatcamTools/ToolProperties.py:459 +#: flatcamTools/ToolProperties.py:421 flatcamTools/ToolProperties.py:486 msgid "Drills number" msgstr "Número de taladros" -#: flatcamTools/ToolProperties.py:402 flatcamTools/ToolProperties.py:461 +#: flatcamTools/ToolProperties.py:422 flatcamTools/ToolProperties.py:488 msgid "Slots number" msgstr "Número de tragamonedas" -#: flatcamTools/ToolProperties.py:404 +#: flatcamTools/ToolProperties.py:424 msgid "Drills total number:" msgstr "Número total de taladros:" -#: flatcamTools/ToolProperties.py:405 +#: flatcamTools/ToolProperties.py:425 msgid "Slots total number:" msgstr "Número total de tragamonedas:" -#: flatcamTools/ToolProperties.py:411 flatcamTools/ToolProperties.py:426 -#: flatcamTools/ToolProperties.py:429 flatcamTools/ToolProperties.py:432 -#: flatcamTools/ToolProperties.py:456 +#: flatcamTools/ToolProperties.py:452 flatcamTools/ToolProperties.py:455 +#: flatcamTools/ToolProperties.py:458 flatcamTools/ToolProperties.py:483 msgid "Present" msgstr "Presente" -#: flatcamTools/ToolProperties.py:427 flatcamTools/ToolProperties.py:457 +#: flatcamTools/ToolProperties.py:453 flatcamTools/ToolProperties.py:484 msgid "Solid Geometry" msgstr "Geometria solida" -#: flatcamTools/ToolProperties.py:430 +#: flatcamTools/ToolProperties.py:456 msgid "GCode Text" msgstr "GCode texto" -#: flatcamTools/ToolProperties.py:433 +#: flatcamTools/ToolProperties.py:459 msgid "GCode Geometry" msgstr "Geometría GCode" -#: flatcamTools/ToolProperties.py:435 +#: flatcamTools/ToolProperties.py:462 msgid "Data" msgstr "Datos" -#: flatcamTools/ToolProperties.py:468 +#: flatcamTools/ToolProperties.py:495 msgid "Depth of Cut" msgstr "Profundidad del corte" -#: flatcamTools/ToolProperties.py:480 +#: flatcamTools/ToolProperties.py:507 msgid "Clearance Height" msgstr "Altura libre" -#: flatcamTools/ToolProperties.py:512 +#: flatcamTools/ToolProperties.py:539 msgid "Routing time" msgstr "Tiempo de enrutamiento" -#: flatcamTools/ToolProperties.py:519 +#: flatcamTools/ToolProperties.py:546 msgid "Travelled distance" msgstr "Distancia recorrida" -#: flatcamTools/ToolProperties.py:560 +#: flatcamTools/ToolProperties.py:564 msgid "Width" msgstr "Anchura" -#: flatcamTools/ToolProperties.py:566 flatcamTools/ToolProperties.py:574 +#: flatcamTools/ToolProperties.py:570 flatcamTools/ToolProperties.py:578 msgid "Box Area" msgstr "Área de caja" -#: flatcamTools/ToolProperties.py:569 flatcamTools/ToolProperties.py:577 +#: flatcamTools/ToolProperties.py:573 flatcamTools/ToolProperties.py:581 msgid "Convex_Hull Area" msgstr "Área de casco convexo" -#: flatcamTools/ToolProperties.py:583 flatcamTools/ToolProperties.py:585 +#: flatcamTools/ToolProperties.py:588 flatcamTools/ToolProperties.py:591 msgid "Copper Area" msgstr "Área de cobre" -#: flatcamTools/ToolQRCode.py:79 +#: flatcamTools/ToolPunchGerber.py:30 flatcamTools/ToolPunchGerber.py:323 +msgid "Punch Gerber" +msgstr "Gerber Perforadora" + +#: flatcamTools/ToolPunchGerber.py:65 +msgid "Gerber into which to punch holes" +msgstr "Gerber en el que hacer agujeros" + +#: flatcamTools/ToolPunchGerber.py:85 +msgid "ALL" +msgstr "TODAS" + +#: flatcamTools/ToolPunchGerber.py:166 +msgid "" +"Remove the geometry of Excellon from the Gerber to create the holes in pads." +msgstr "" +"Retire la geometría de Excellon del Gerber para crear los agujeros en las " +"almohadillas." + +#: flatcamTools/ToolPunchGerber.py:325 +msgid "" +"Create a Gerber object from the selected object, within\n" +"the specified box." +msgstr "" +"Cree un objeto Gerber a partir del objeto seleccionado, dentro de\n" +"El cuadro especificado." + +#: flatcamTools/ToolPunchGerber.py:425 +msgid "Punch Tool" +msgstr "Herram. de Perforación" + +#: flatcamTools/ToolPunchGerber.py:599 +msgid "The value of the fixed diameter is 0.0. Aborting." +msgstr "El valor del diámetro fijo es 0.0. Abortar." + +#: flatcamTools/ToolPunchGerber.py:607 +msgid "" +" Could not generate punched hole Gerber because the punch hole sizeis bigger " +"than some of the apertures in the Gerber object." +msgstr "" +" No se pudo generar el agujero perforado Gerber porque el tamaño del agujero " +"perforado es más grande que algunas de las aberturas en el objeto Gerber." + +#: flatcamTools/ToolPunchGerber.py:619 +msgid "" +"Could not generate punched hole Gerber because the punch hole sizeis bigger " +"than some of the apertures in the Gerber object." +msgstr "" +"No se pudo generar el agujero perforado Gerber porque el tamaño del agujero " +"perforado es mayor que algunas de las aberturas en el objeto Gerber." + +#: flatcamTools/ToolPunchGerber.py:656 +msgid "" +"Could not generate punched hole Gerber because the newly created object " +"geometry is the same as the one in the source object geometry..." +msgstr "" +"No se pudo generar el agujero perforado Gerber porque la geometría del " +"objeto recién creada es la misma que la de la geometría del objeto de " +"origen ..." + +#: flatcamTools/ToolQRCode.py:80 msgid "Gerber Object to which the QRCode will be added." msgstr "Objeto Gerber al que se agregará el QRCode." -#: flatcamTools/ToolQRCode.py:92 +#: flatcamTools/ToolQRCode.py:93 msgid "QRCode Parameters" msgstr "Parámetros QRCode" -#: flatcamTools/ToolQRCode.py:94 +#: flatcamTools/ToolQRCode.py:95 msgid "The parameters used to shape the QRCode." msgstr "Los parámetros utilizados para dar forma al QRCode." @@ -16038,31 +16900,27 @@ msgstr "Insertar QRCode" msgid "Create the QRCode object." msgstr "Crea el objeto QRCode." -#: flatcamTools/ToolQRCode.py:413 flatcamTools/ToolQRCode.py:748 -#: flatcamTools/ToolQRCode.py:797 +#: flatcamTools/ToolQRCode.py:415 flatcamTools/ToolQRCode.py:750 +#: flatcamTools/ToolQRCode.py:799 msgid "Cancelled. There is no QRCode Data in the text box." msgstr "Cancelado. No hay datos de QRCode en el cuadro de texto." -#: flatcamTools/ToolQRCode.py:432 +#: flatcamTools/ToolQRCode.py:434 msgid "Generating QRCode geometry" msgstr "Generando geometría QRCode" -#: flatcamTools/ToolQRCode.py:472 +#: flatcamTools/ToolQRCode.py:474 msgid "Click on the Destination point ..." msgstr "Haga clic en el punto de destino ..." -#: flatcamTools/ToolQRCode.py:587 +#: flatcamTools/ToolQRCode.py:589 msgid "QRCode Tool done." msgstr "Herramienta QRCode hecha." -#: flatcamTools/ToolQRCode.py:780 flatcamTools/ToolQRCode.py:784 +#: flatcamTools/ToolQRCode.py:782 flatcamTools/ToolQRCode.py:786 msgid "Export PNG" msgstr "Exportar PNG" -#: flatcamTools/ToolQRCode.py:789 -msgid " Export PNG cancelled." -msgstr " Exportación PNG cancelada." - #: flatcamTools/ToolRulesCheck.py:33 msgid "Check Rules" msgstr "Verificar Reglas" @@ -16075,79 +16933,79 @@ msgstr "Archivos Gerber" msgid "Gerber objects for which to check rules." msgstr "Objetos de Gerber para los cuales verificar las reglas." -#: flatcamTools/ToolRulesCheck.py:77 +#: flatcamTools/ToolRulesCheck.py:78 msgid "Top" msgstr "Top" -#: flatcamTools/ToolRulesCheck.py:79 +#: flatcamTools/ToolRulesCheck.py:80 msgid "The Top Gerber Copper object for which rules are checked." msgstr "El objeto de cobre Top Gerber para el que se verifican las reglas." -#: flatcamTools/ToolRulesCheck.py:94 +#: flatcamTools/ToolRulesCheck.py:96 msgid "Bottom" msgstr "Inferior" -#: flatcamTools/ToolRulesCheck.py:96 +#: flatcamTools/ToolRulesCheck.py:98 msgid "The Bottom Gerber Copper object for which rules are checked." msgstr "" "El objeto de cobre de Gerber inferior para el que se verifican las reglas." -#: flatcamTools/ToolRulesCheck.py:111 +#: flatcamTools/ToolRulesCheck.py:114 msgid "SM Top" msgstr "SM Top" -#: flatcamTools/ToolRulesCheck.py:113 +#: flatcamTools/ToolRulesCheck.py:116 msgid "The Top Gerber Solder Mask object for which rules are checked." msgstr "" "El objeto Máscara de soldadura de Gerber superior para el que se verifican " "las reglas." -#: flatcamTools/ToolRulesCheck.py:128 +#: flatcamTools/ToolRulesCheck.py:132 msgid "SM Bottom" msgstr "SM Inferior" -#: flatcamTools/ToolRulesCheck.py:130 +#: flatcamTools/ToolRulesCheck.py:134 msgid "The Bottom Gerber Solder Mask object for which rules are checked." msgstr "" "El objeto de máscara de soldadura de Gerber inferior para el que se " "verifican las reglas." -#: flatcamTools/ToolRulesCheck.py:145 +#: flatcamTools/ToolRulesCheck.py:150 msgid "Silk Top" msgstr "Top de serigrafía" -#: flatcamTools/ToolRulesCheck.py:147 +#: flatcamTools/ToolRulesCheck.py:152 msgid "The Top Gerber Silkscreen object for which rules are checked." msgstr "" "El objeto de serigrafía Top Gerber para el que se verifican las reglas." -#: flatcamTools/ToolRulesCheck.py:162 +#: flatcamTools/ToolRulesCheck.py:168 msgid "Silk Bottom" msgstr "Serigrafía Inferior" -#: flatcamTools/ToolRulesCheck.py:164 +#: flatcamTools/ToolRulesCheck.py:170 msgid "The Bottom Gerber Silkscreen object for which rules are checked." msgstr "" "El objeto Serigrafía inferior de Gerber para el que se verifican las reglas." -#: flatcamTools/ToolRulesCheck.py:181 +#: flatcamTools/ToolRulesCheck.py:188 msgid "The Gerber Outline (Cutout) object for which rules are checked." msgstr "" "El objeto Esquema de Gerber (Recorte) para el que se verifican las reglas." -#: flatcamTools/ToolRulesCheck.py:192 +#: flatcamTools/ToolRulesCheck.py:199 msgid "Excellon Objects" msgstr "Objetos Excellon" -#: flatcamTools/ToolRulesCheck.py:194 +#: flatcamTools/ToolRulesCheck.py:201 msgid "Excellon objects for which to check rules." msgstr "Excellon objetos para los cuales verificar las reglas." -#: flatcamTools/ToolRulesCheck.py:205 +#: flatcamTools/ToolRulesCheck.py:213 msgid "Excellon 1" msgstr "Excellon 1" -#: flatcamTools/ToolRulesCheck.py:207 +#: flatcamTools/ToolRulesCheck.py:215 msgid "" "Excellon object for which to check rules.\n" "Holds the plated holes or a general Excellon file content." @@ -16155,11 +17013,11 @@ msgstr "" "Objeto Excellon para el cual verificar las reglas.\n" "Contiene los agujeros chapados o un contenido general del archivo Excellon." -#: flatcamTools/ToolRulesCheck.py:223 +#: flatcamTools/ToolRulesCheck.py:232 msgid "Excellon 2" msgstr "Excellon 2" -#: flatcamTools/ToolRulesCheck.py:225 +#: flatcamTools/ToolRulesCheck.py:234 msgid "" "Excellon object for which to check rules.\n" "Holds the non-plated holes." @@ -16167,35 +17025,35 @@ msgstr "" "Objeto Excellon para el cual verificar las reglas.\n" "Sostiene los agujeros no chapados." -#: flatcamTools/ToolRulesCheck.py:238 +#: flatcamTools/ToolRulesCheck.py:247 msgid "All Rules" msgstr "Todas las reglas" -#: flatcamTools/ToolRulesCheck.py:240 +#: flatcamTools/ToolRulesCheck.py:249 msgid "This check/uncheck all the rules below." msgstr "Esto marca / desmarca todas las reglas a continuación." -#: flatcamTools/ToolRulesCheck.py:490 +#: flatcamTools/ToolRulesCheck.py:499 msgid "Run Rules Check" msgstr "Ejecutar Reglas Verificar" -#: flatcamTools/ToolRulesCheck.py:1149 flatcamTools/ToolRulesCheck.py:1209 -#: flatcamTools/ToolRulesCheck.py:1246 flatcamTools/ToolRulesCheck.py:1318 -#: flatcamTools/ToolRulesCheck.py:1372 flatcamTools/ToolRulesCheck.py:1410 -#: flatcamTools/ToolRulesCheck.py:1475 +#: flatcamTools/ToolRulesCheck.py:1158 flatcamTools/ToolRulesCheck.py:1218 +#: flatcamTools/ToolRulesCheck.py:1255 flatcamTools/ToolRulesCheck.py:1327 +#: flatcamTools/ToolRulesCheck.py:1381 flatcamTools/ToolRulesCheck.py:1419 +#: flatcamTools/ToolRulesCheck.py:1484 msgid "Value is not valid." msgstr "El valor no es valido." -#: flatcamTools/ToolRulesCheck.py:1163 +#: flatcamTools/ToolRulesCheck.py:1172 msgid "TOP -> Copper to Copper clearance" msgstr "ARRIBA -> Separación de Cobre a Cobre" -#: flatcamTools/ToolRulesCheck.py:1174 +#: flatcamTools/ToolRulesCheck.py:1183 msgid "BOTTOM -> Copper to Copper clearance" msgstr "ABAJO -> Separación de Cobre a Cobre" -#: flatcamTools/ToolRulesCheck.py:1179 flatcamTools/ToolRulesCheck.py:1273 -#: flatcamTools/ToolRulesCheck.py:1437 +#: flatcamTools/ToolRulesCheck.py:1188 flatcamTools/ToolRulesCheck.py:1282 +#: flatcamTools/ToolRulesCheck.py:1446 msgid "" "At least one Gerber object has to be selected for this rule but none is " "selected." @@ -16203,14 +17061,14 @@ msgstr "" "Se debe seleccionar al menos un objeto Gerber para esta regla, pero no se " "selecciona ninguno." -#: flatcamTools/ToolRulesCheck.py:1215 +#: flatcamTools/ToolRulesCheck.py:1224 msgid "" "One of the copper Gerber objects or the Outline Gerber object is not valid." msgstr "" "Uno de los objetos de cobre de Gerber o el objeto de contorno de Gerber no " "es válido." -#: flatcamTools/ToolRulesCheck.py:1228 flatcamTools/ToolRulesCheck.py:1392 +#: flatcamTools/ToolRulesCheck.py:1237 flatcamTools/ToolRulesCheck.py:1401 msgid "" "Outline Gerber object presence is mandatory for this rule but it is not " "selected." @@ -16218,31 +17076,31 @@ msgstr "" "La presencia del objeto Contorno Gerber es obligatoria para esta regla, pero " "no está seleccionada." -#: flatcamTools/ToolRulesCheck.py:1245 flatcamTools/ToolRulesCheck.py:1272 +#: flatcamTools/ToolRulesCheck.py:1254 flatcamTools/ToolRulesCheck.py:1281 msgid "Silk to Silk clearance" msgstr "Distancia de Serigrafía a Serigrafía" -#: flatcamTools/ToolRulesCheck.py:1258 +#: flatcamTools/ToolRulesCheck.py:1267 msgid "TOP -> Silk to Silk clearance" msgstr "ARRIBA -> Distancia de Serigrafía a Serigrafía" -#: flatcamTools/ToolRulesCheck.py:1268 +#: flatcamTools/ToolRulesCheck.py:1277 msgid "BOTTOM -> Silk to Silk clearance" msgstr "ABAJO -> Distancia de Serigrafía a Serigrafía" -#: flatcamTools/ToolRulesCheck.py:1324 +#: flatcamTools/ToolRulesCheck.py:1333 msgid "One or more of the Gerber objects is not valid." msgstr "Uno o más de los objetos de Gerber no son válidos." -#: flatcamTools/ToolRulesCheck.py:1332 +#: flatcamTools/ToolRulesCheck.py:1341 msgid "TOP -> Silk to Solder Mask Clearance" msgstr "ARRIBA -> Distancia entre la Máscara de Soldadura y la Serigrafía" -#: flatcamTools/ToolRulesCheck.py:1338 +#: flatcamTools/ToolRulesCheck.py:1347 msgid "BOTTOM -> Silk to Solder Mask Clearance" msgstr "ABAJO -> Distancia entre la Máscara de Soldadura y la Serigrafía" -#: flatcamTools/ToolRulesCheck.py:1342 +#: flatcamTools/ToolRulesCheck.py:1351 msgid "" "Both Silk and Solder Mask Gerber objects has to be either both Top or both " "Bottom." @@ -16250,62 +17108,62 @@ msgstr "" "Tanto los objetos de Serigrafía como los de Máscara de soldadura Gerber " "deben ser tanto Superior como Inferior." -#: flatcamTools/ToolRulesCheck.py:1378 +#: flatcamTools/ToolRulesCheck.py:1387 msgid "" "One of the Silk Gerber objects or the Outline Gerber object is not valid." msgstr "" "Uno de los objetos de Serigrafía Gerber o el objeto Contorno Gerber no es " "válido." -#: flatcamTools/ToolRulesCheck.py:1422 +#: flatcamTools/ToolRulesCheck.py:1431 msgid "TOP -> Minimum Solder Mask Sliver" msgstr "ARRIBA -> Astilla de máscara de soldadura mínima" -#: flatcamTools/ToolRulesCheck.py:1432 +#: flatcamTools/ToolRulesCheck.py:1441 msgid "BOTTOM -> Minimum Solder Mask Sliver" msgstr "ABAJO -> Astilla de máscara de soldadura mínima" -#: flatcamTools/ToolRulesCheck.py:1481 +#: flatcamTools/ToolRulesCheck.py:1490 msgid "One of the Copper Gerber objects or the Excellon objects is not valid." msgstr "Uno de los objetos de Cobre Gerber u objetos de Excellon no es válido." -#: flatcamTools/ToolRulesCheck.py:1497 +#: flatcamTools/ToolRulesCheck.py:1506 msgid "" "Excellon object presence is mandatory for this rule but none is selected." msgstr "" "La presencia de objetos Excellon es obligatoria para esta regla, pero no se " "selecciona ninguna." -#: flatcamTools/ToolRulesCheck.py:1570 flatcamTools/ToolRulesCheck.py:1583 -#: flatcamTools/ToolRulesCheck.py:1594 flatcamTools/ToolRulesCheck.py:1607 +#: flatcamTools/ToolRulesCheck.py:1579 flatcamTools/ToolRulesCheck.py:1592 +#: flatcamTools/ToolRulesCheck.py:1603 flatcamTools/ToolRulesCheck.py:1616 msgid "STATUS" msgstr "ESTADO" -#: flatcamTools/ToolRulesCheck.py:1573 flatcamTools/ToolRulesCheck.py:1597 +#: flatcamTools/ToolRulesCheck.py:1582 flatcamTools/ToolRulesCheck.py:1606 msgid "FAILED" msgstr "HA FALLADO" -#: flatcamTools/ToolRulesCheck.py:1586 flatcamTools/ToolRulesCheck.py:1610 +#: flatcamTools/ToolRulesCheck.py:1595 flatcamTools/ToolRulesCheck.py:1619 msgid "PASSED" msgstr "PASADO" -#: flatcamTools/ToolRulesCheck.py:1587 flatcamTools/ToolRulesCheck.py:1611 +#: flatcamTools/ToolRulesCheck.py:1596 flatcamTools/ToolRulesCheck.py:1620 msgid "Violations: There are no violations for the current rule." msgstr "Infracciones: no hay infracciones para la regla actual." -#: flatcamTools/ToolShell.py:70 flatcamTools/ToolShell.py:72 -msgid "...proccessing..." -msgstr "...procesando ..." +#: flatcamTools/ToolShell.py:72 flatcamTools/ToolShell.py:74 +msgid "...processing..." +msgstr "…procesando..." -#: flatcamTools/ToolSolderPaste.py:37 +#: flatcamTools/ToolSolderPaste.py:38 msgid "Solder Paste Tool" msgstr "Herra. de Pasta de Soldadura" -#: flatcamTools/ToolSolderPaste.py:68 +#: flatcamTools/ToolSolderPaste.py:70 msgid "Gerber Solder paste object. " msgstr "Gerber Soldadura pegar objeto. " -#: flatcamTools/ToolSolderPaste.py:75 +#: flatcamTools/ToolSolderPaste.py:77 msgid "" "Tools pool from which the algorithm\n" "will pick the ones used for dispensing solder paste." @@ -16313,7 +17171,7 @@ msgstr "" "Conjunto de herramientas desde el cual el algoritmo\n" "elegirá los que se usan para dispensar pasta de soldadura." -#: flatcamTools/ToolSolderPaste.py:90 +#: flatcamTools/ToolSolderPaste.py:92 msgid "" "This is the Tool Number.\n" "The solder dispensing will start with the tool with the biggest \n" @@ -16328,7 +17186,7 @@ msgstr "" "  con soldadura en pasta, la aplicación emitirá un cuadro de mensaje de " "advertencia." -#: flatcamTools/ToolSolderPaste.py:97 +#: flatcamTools/ToolSolderPaste.py:99 msgid "" "Nozzle tool Diameter. It's value (in current FlatCAM units)\n" "is the width of the solder paste dispensed." @@ -16337,11 +17195,11 @@ msgstr "" "FlatCAM)\n" "es el ancho de la pasta de soldadura dispensada." -#: flatcamTools/ToolSolderPaste.py:104 +#: flatcamTools/ToolSolderPaste.py:106 msgid "New Nozzle Tool" msgstr "Nueva herra. de boquilla" -#: flatcamTools/ToolSolderPaste.py:123 +#: flatcamTools/ToolSolderPaste.py:125 msgid "" "Add a new nozzle tool to the Tool Table\n" "with the diameter specified above." @@ -16349,15 +17207,15 @@ msgstr "" "Agregue una nueva herramienta de boquilla a la tabla de herramientas\n" "con el diámetro especificado anteriormente." -#: flatcamTools/ToolSolderPaste.py:135 +#: flatcamTools/ToolSolderPaste.py:137 msgid "Generate solder paste dispensing geometry." msgstr "Generar geometría de dispensación de pasta de soldadura." -#: flatcamTools/ToolSolderPaste.py:154 +#: flatcamTools/ToolSolderPaste.py:156 msgid "STEP 1" msgstr "PASO 1" -#: flatcamTools/ToolSolderPaste.py:156 +#: flatcamTools/ToolSolderPaste.py:158 msgid "" "First step is to select a number of nozzle tools for usage\n" "and then optionally modify the GCode parameters bellow." @@ -16366,7 +17224,7 @@ msgstr "" "uso\n" "y luego opcionalmente modificar los parámetros GCode a continuación." -#: flatcamTools/ToolSolderPaste.py:159 +#: flatcamTools/ToolSolderPaste.py:161 msgid "" "Select tools.\n" "Modify parameters." @@ -16374,7 +17232,7 @@ msgstr "" "Seleccionar herramientas.\n" "Modificar parámetros." -#: flatcamTools/ToolSolderPaste.py:279 +#: flatcamTools/ToolSolderPaste.py:281 msgid "" "Feedrate (speed) while moving up vertically\n" " to Dispense position (on Z plane)." @@ -16382,7 +17240,7 @@ msgstr "" "Avance (velocidad) mientras se mueve verticalmente\n" "  para dispensar la posición (en el plano Z)." -#: flatcamTools/ToolSolderPaste.py:349 +#: flatcamTools/ToolSolderPaste.py:351 msgid "" "Generate GCode for Solder Paste dispensing\n" "on PCB pads." @@ -16390,11 +17248,11 @@ msgstr "" "Generar GCodelo para dispensar pasta de soldadura\n" "en almohadillas de PCB." -#: flatcamTools/ToolSolderPaste.py:370 +#: flatcamTools/ToolSolderPaste.py:372 msgid "STEP 2" msgstr "PASO 2" -#: flatcamTools/ToolSolderPaste.py:372 +#: flatcamTools/ToolSolderPaste.py:374 msgid "" "Second step is to create a solder paste dispensing\n" "geometry out of an Solder Paste Mask Gerber file." @@ -16402,11 +17260,11 @@ msgstr "" "El segundo paso es crear una dispensación de pasta de soldadura\n" "geometría de un archivo Gerber de máscara de pasta de soldadura." -#: flatcamTools/ToolSolderPaste.py:388 +#: flatcamTools/ToolSolderPaste.py:391 msgid "Geo Result" msgstr "Resultado Geo" -#: flatcamTools/ToolSolderPaste.py:390 +#: flatcamTools/ToolSolderPaste.py:393 msgid "" "Geometry Solder Paste object.\n" "The name of the object has to end in:\n" @@ -16416,11 +17274,11 @@ msgstr "" "El nombre del objeto tiene que terminar en:\n" "'_solderpaste' como protección." -#: flatcamTools/ToolSolderPaste.py:399 +#: flatcamTools/ToolSolderPaste.py:402 msgid "STEP 3" msgstr "PASO 3" -#: flatcamTools/ToolSolderPaste.py:401 +#: flatcamTools/ToolSolderPaste.py:404 msgid "" "Third step is to select a solder paste dispensing geometry,\n" "and then generate a CNCJob object.\n" @@ -16437,11 +17295,11 @@ msgstr "" "primero necesitas generar una geometría con esos nuevos parámetros,\n" "y solo después de eso puede generar un CNCJob actualizado." -#: flatcamTools/ToolSolderPaste.py:421 +#: flatcamTools/ToolSolderPaste.py:425 msgid "CNC Result" msgstr "Resultado del CNC" -#: flatcamTools/ToolSolderPaste.py:423 +#: flatcamTools/ToolSolderPaste.py:427 msgid "" "CNCJob Solder paste object.\n" "In order to enable the GCode save section,\n" @@ -16453,11 +17311,11 @@ msgstr "" "el nombre del objeto debe terminar en:\n" "'_solderpaste' como protección." -#: flatcamTools/ToolSolderPaste.py:433 +#: flatcamTools/ToolSolderPaste.py:437 msgid "View GCode" msgstr "Ver GCode" -#: flatcamTools/ToolSolderPaste.py:435 +#: flatcamTools/ToolSolderPaste.py:439 msgid "" "View the generated GCode for Solder Paste dispensing\n" "on PCB pads." @@ -16465,11 +17323,11 @@ msgstr "" "Ver el GCode generado para la dispensación de pasta de soldadura\n" "en almohadillas de PCB." -#: flatcamTools/ToolSolderPaste.py:445 +#: flatcamTools/ToolSolderPaste.py:449 msgid "Save GCode" msgstr "Guardar GCode" -#: flatcamTools/ToolSolderPaste.py:447 +#: flatcamTools/ToolSolderPaste.py:451 msgid "" "Save the generated GCode for Solder Paste dispensing\n" "on PCB pads, to a file." @@ -16477,11 +17335,11 @@ msgstr "" "Guarde el GCode generado para la dispensación de pasta de soldadura\n" "en almohadillas de PCB, a un archivo." -#: flatcamTools/ToolSolderPaste.py:457 +#: flatcamTools/ToolSolderPaste.py:461 msgid "STEP 4" msgstr "PASO 4" -#: flatcamTools/ToolSolderPaste.py:459 +#: flatcamTools/ToolSolderPaste.py:463 msgid "" "Fourth step (and last) is to select a CNCJob made from \n" "a solder paste dispensing geometry, and then view/save it's GCode." @@ -16490,93 +17348,87 @@ msgstr "" "una geometría de dispensación de pasta de soldadura, y luego ver / guardar " "su código GC." -#: flatcamTools/ToolSolderPaste.py:917 -msgid "Adding Nozzle tool cancelled. Tool already in Tool Table." -msgstr "" -"Se ha cancelado la adición de la herramienta Boquilla. Herramienta ya en la " -"tabla de herramientas." - -#: flatcamTools/ToolSolderPaste.py:923 +#: flatcamTools/ToolSolderPaste.py:922 msgid "New Nozzle tool added to Tool Table." msgstr "Nueva herramienta de boquillas agregada a la tabla de herramientas." -#: flatcamTools/ToolSolderPaste.py:966 +#: flatcamTools/ToolSolderPaste.py:965 msgid "Nozzle tool from Tool Table was edited." msgstr "Nueva herramienta de boquillas agregada a la tabla de herramientas." -#: flatcamTools/ToolSolderPaste.py:1024 +#: flatcamTools/ToolSolderPaste.py:1023 msgid "Delete failed. Select a Nozzle tool to delete." msgstr "" "Eliminar falló. Seleccione una herramienta de inyectores para eliminar." -#: flatcamTools/ToolSolderPaste.py:1030 +#: flatcamTools/ToolSolderPaste.py:1029 msgid "Nozzle tool(s) deleted from Tool Table." msgstr "Herramienta de boquilla (s) eliminada de la tabla de herramientas." -#: flatcamTools/ToolSolderPaste.py:1086 +#: flatcamTools/ToolSolderPaste.py:1085 msgid "No SolderPaste mask Gerber object loaded." msgstr "No se ha cargado el objeto Gerber de máscara de pasta de soldadura." -#: flatcamTools/ToolSolderPaste.py:1104 +#: flatcamTools/ToolSolderPaste.py:1103 msgid "Creating Solder Paste dispensing geometry." msgstr "Creación de geometría de dispensación de pasta de soldadura." -#: flatcamTools/ToolSolderPaste.py:1117 +#: flatcamTools/ToolSolderPaste.py:1116 msgid "No Nozzle tools in the tool table." msgstr "No hay herramientas de boquilla en la mesa de herramientas." -#: flatcamTools/ToolSolderPaste.py:1244 +#: flatcamTools/ToolSolderPaste.py:1242 msgid "Cancelled. Empty file, it has no geometry..." msgstr "Cancelado. Archivo vacío, no tiene geometría ..." -#: flatcamTools/ToolSolderPaste.py:1248 +#: flatcamTools/ToolSolderPaste.py:1245 msgid "Solder Paste geometry generated successfully" msgstr "Geometría de pasta de soldadura generada con éxito" -#: flatcamTools/ToolSolderPaste.py:1255 +#: flatcamTools/ToolSolderPaste.py:1252 msgid "Some or all pads have no solder due of inadequate nozzle diameters..." msgstr "" "Algunas o todas las almohadillas no tienen soldadura debido a los diámetros " "de boquilla inadecuados ..." -#: flatcamTools/ToolSolderPaste.py:1269 +#: flatcamTools/ToolSolderPaste.py:1266 msgid "Generating Solder Paste dispensing geometry..." msgstr "Generando geometría de dispensación de pasta de soldadura ..." -#: flatcamTools/ToolSolderPaste.py:1289 +#: flatcamTools/ToolSolderPaste.py:1286 msgid "There is no Geometry object available." msgstr "No hay ningún objeto de Geometría disponible." -#: flatcamTools/ToolSolderPaste.py:1294 +#: flatcamTools/ToolSolderPaste.py:1291 msgid "This Geometry can't be processed. NOT a solder_paste_tool geometry." msgstr "" "Esta Geometría no se puede procesar. NO es una geometría solder_paste_tool." -#: flatcamTools/ToolSolderPaste.py:1401 +#: flatcamTools/ToolSolderPaste.py:1392 msgid "ToolSolderPaste CNCjob created" msgstr "Herramienta soldar pegar CNCjob creado" -#: flatcamTools/ToolSolderPaste.py:1422 +#: flatcamTools/ToolSolderPaste.py:1411 msgid "SP GCode Editor" msgstr "SP GCode editor" -#: flatcamTools/ToolSolderPaste.py:1434 flatcamTools/ToolSolderPaste.py:1439 -#: flatcamTools/ToolSolderPaste.py:1494 +#: flatcamTools/ToolSolderPaste.py:1423 flatcamTools/ToolSolderPaste.py:1428 +#: flatcamTools/ToolSolderPaste.py:1483 msgid "" "This CNCJob object can't be processed. NOT a solder_paste_tool CNCJob object." msgstr "" "Este objeto CNCJob no se puede procesar. NO es un objeto CNCJob de " "herramienta de pasta de soldadura." -#: flatcamTools/ToolSolderPaste.py:1464 +#: flatcamTools/ToolSolderPaste.py:1453 msgid "No Gcode in the object" msgstr "No Gcode en el objeto" -#: flatcamTools/ToolSolderPaste.py:1504 +#: flatcamTools/ToolSolderPaste.py:1493 msgid "Export GCode ..." msgstr "Exportar GCode ..." -#: flatcamTools/ToolSolderPaste.py:1552 +#: flatcamTools/ToolSolderPaste.py:1541 msgid "Solder paste dispenser GCode file saved to" msgstr "Dispensador de pasta de soldadura Archivo GCode guardado en: %s" @@ -16584,7 +17436,7 @@ msgstr "Dispensador de pasta de soldadura Archivo GCode guardado en: %s" msgid "Gerber Objects" msgstr "Objetos Gerber" -#: flatcamTools/ToolSub.py:76 +#: flatcamTools/ToolSub.py:78 msgid "" "Gerber object from which to subtract\n" "the subtractor Gerber object." @@ -16592,11 +17444,11 @@ msgstr "" "Objeto de Gerber para restar\n" "El sustractor del objeto Gerber." -#: flatcamTools/ToolSub.py:88 flatcamTools/ToolSub.py:140 +#: flatcamTools/ToolSub.py:91 flatcamTools/ToolSub.py:146 msgid "Subtractor" msgstr "Sustractor" -#: flatcamTools/ToolSub.py:90 +#: flatcamTools/ToolSub.py:93 msgid "" "Gerber object that will be subtracted\n" "from the target Gerber object." @@ -16604,11 +17456,11 @@ msgstr "" "Objeto de Gerber que se restará\n" "del objeto objetivo de Gerber." -#: flatcamTools/ToolSub.py:97 +#: flatcamTools/ToolSub.py:100 msgid "Substract Gerber" msgstr "Restar Gerber" -#: flatcamTools/ToolSub.py:99 +#: flatcamTools/ToolSub.py:102 msgid "" "Will remove the area occupied by the subtractor\n" "Gerber from the Target Gerber.\n" @@ -16620,11 +17472,11 @@ msgstr "" "Se puede utilizar para eliminar la serigrafía superpuesta\n" "sobre la máscara de soldadura." -#: flatcamTools/ToolSub.py:117 +#: flatcamTools/ToolSub.py:120 msgid "Geometry Objects" msgstr "Objetos de Geometría" -#: flatcamTools/ToolSub.py:128 +#: flatcamTools/ToolSub.py:133 msgid "" "Geometry object from which to subtract\n" "the subtractor Geometry object." @@ -16632,7 +17484,7 @@ msgstr "" "Objeto de Geometría del cual restar\n" "El objeto de Geometría de sustractor." -#: flatcamTools/ToolSub.py:142 +#: flatcamTools/ToolSub.py:148 msgid "" "Geometry object that will be subtracted\n" "from the target Geometry object." @@ -16640,17 +17492,17 @@ msgstr "" "Objeto de Geometría que se restará\n" "del objeto de Geometría de destino." -#: flatcamTools/ToolSub.py:150 +#: flatcamTools/ToolSub.py:156 msgid "" "Checking this will close the paths cut by the Geometry subtractor object." msgstr "" "Marcar esto cerrará los caminos cortados por el objeto sustrato Geometry." -#: flatcamTools/ToolSub.py:153 +#: flatcamTools/ToolSub.py:159 msgid "Subtract Geometry" msgstr "Restar Geometría" -#: flatcamTools/ToolSub.py:155 +#: flatcamTools/ToolSub.py:161 msgid "" "Will remove the area occupied by the subtractor\n" "Geometry from the Target Geometry." @@ -16658,57 +17510,57 @@ msgstr "" "Eliminará el área ocupada por el sustractor\n" "Geometría de la Geometría Objetivo." -#: flatcamTools/ToolSub.py:262 +#: flatcamTools/ToolSub.py:263 msgid "Sub Tool" msgstr "Herra. de resta" -#: flatcamTools/ToolSub.py:278 flatcamTools/ToolSub.py:483 +#: flatcamTools/ToolSub.py:284 flatcamTools/ToolSub.py:489 msgid "No Target object loaded." msgstr "No se ha cargado ningún objeto de destino." -#: flatcamTools/ToolSub.py:281 +#: flatcamTools/ToolSub.py:287 msgid "Loading geometry from Gerber objects." msgstr "Cargando geometría de objetos Gerber." -#: flatcamTools/ToolSub.py:293 flatcamTools/ToolSub.py:498 +#: flatcamTools/ToolSub.py:299 flatcamTools/ToolSub.py:504 msgid "No Subtractor object loaded." msgstr "No se ha cargado ningún objeto Subtractor." -#: flatcamTools/ToolSub.py:325 +#: flatcamTools/ToolSub.py:331 msgid "Processing geometry from Subtractor Gerber object." msgstr "Procesamiento de geometría del objeto sustractor Gerber." -#: flatcamTools/ToolSub.py:346 +#: flatcamTools/ToolSub.py:352 msgid "Parsing geometry for aperture" msgstr "Análisis de geometría para apertura" -#: flatcamTools/ToolSub.py:407 +#: flatcamTools/ToolSub.py:413 msgid "Finished parsing geometry for aperture" msgstr "Geometría de análisis terminada para apertura" -#: flatcamTools/ToolSub.py:452 flatcamTools/ToolSub.py:655 +#: flatcamTools/ToolSub.py:458 flatcamTools/ToolSub.py:661 msgid "Generating new object ..." msgstr "Generando nuevo objeto ..." -#: flatcamTools/ToolSub.py:456 flatcamTools/ToolSub.py:659 -#: flatcamTools/ToolSub.py:740 +#: flatcamTools/ToolSub.py:462 flatcamTools/ToolSub.py:665 +#: flatcamTools/ToolSub.py:746 msgid "Generating new object failed." msgstr "Generando nuevo objeto falló." -#: flatcamTools/ToolSub.py:461 flatcamTools/ToolSub.py:665 +#: flatcamTools/ToolSub.py:467 flatcamTools/ToolSub.py:671 msgid "Created" msgstr "Creado" -#: flatcamTools/ToolSub.py:512 +#: flatcamTools/ToolSub.py:518 msgid "Currently, the Subtractor geometry cannot be of type Multigeo." msgstr "" "Actualmente, la geometría del sustractor no puede ser del tipo Multigeo." -#: flatcamTools/ToolSub.py:557 +#: flatcamTools/ToolSub.py:563 msgid "Parsing solid_geometry ..." msgstr "Analizando solid_geometry ..." -#: flatcamTools/ToolSub.py:559 +#: flatcamTools/ToolSub.py:565 msgid "Parsing solid_geometry for tool" msgstr "Análisis de geometría para herramienta" @@ -16716,7 +17568,7 @@ msgstr "Análisis de geometría para herramienta" msgid "Object Transform" msgstr "Transform. de objetos" -#: flatcamTools/ToolTransform.py:82 +#: flatcamTools/ToolTransform.py:79 msgid "" "Rotate the selected object(s).\n" "The point of reference is the middle of\n" @@ -16726,7 +17578,7 @@ msgstr "" "El punto de referencia es el medio de\n" "el cuadro delimitador para todos los objetos seleccionados." -#: flatcamTools/ToolTransform.py:100 flatcamTools/ToolTransform.py:122 +#: flatcamTools/ToolTransform.py:100 flatcamTools/ToolTransform.py:121 msgid "" "Angle for Skew action, in degrees.\n" "Float number between -360 and 360." @@ -16734,7 +17586,7 @@ msgstr "" "Ángulo para sesgo de acción, en grados.\n" "Número de flotación entre -360 y 360." -#: flatcamTools/ToolTransform.py:111 flatcamTools/ToolTransform.py:133 +#: flatcamTools/ToolTransform.py:110 flatcamTools/ToolTransform.py:131 msgid "" "Skew/shear the selected object(s).\n" "The point of reference is the middle of\n" @@ -16744,7 +17596,7 @@ msgstr "" "El punto de referencia es el medio de\n" "el cuadro delimitador para todos los objetos seleccionados." -#: flatcamTools/ToolTransform.py:160 flatcamTools/ToolTransform.py:181 +#: flatcamTools/ToolTransform.py:160 flatcamTools/ToolTransform.py:180 msgid "" "Scale the selected object(s).\n" "The point of reference depends on \n" @@ -16754,7 +17606,7 @@ msgstr "" "El punto de referencia depende de\n" "el estado de la casilla de verificación Escalar referencia." -#: flatcamTools/ToolTransform.py:229 flatcamTools/ToolTransform.py:250 +#: flatcamTools/ToolTransform.py:229 flatcamTools/ToolTransform.py:249 msgid "" "Offset the selected object(s).\n" "The point of reference is the middle of\n" @@ -16764,196 +17616,607 @@ msgstr "" "El punto de referencia es el medio de\n" "el cuadro delimitador para todos los objetos seleccionados.\n" -#: flatcamTools/ToolTransform.py:268 flatcamTools/ToolTransform.py:274 +#: flatcamTools/ToolTransform.py:269 flatcamTools/ToolTransform.py:274 msgid "Flip the selected object(s) over the X axis." msgstr "Voltee los objetos seleccionados sobre el eje X." -#: flatcamTools/ToolTransform.py:299 +#: flatcamTools/ToolTransform.py:298 msgid "Ref. Point" msgstr "Punto de Ref" -#: flatcamTools/ToolTransform.py:351 +#: flatcamTools/ToolTransform.py:349 msgid "" "Create the buffer effect on each geometry,\n" -"element from the selected object." +"element from the selected object, using the distance." msgstr "" "Crea el efecto de amortiguación en cada geometría,\n" -"elemento del objeto seleccionado." +"elemento del objeto seleccionado, utilizando la distancia." -#: flatcamTools/ToolTransform.py:498 +#: flatcamTools/ToolTransform.py:375 +msgid "" +"Create the buffer effect on each geometry,\n" +"element from the selected object, using the factor." +msgstr "" +"Crea el efecto de amortiguación en cada geometría,\n" +"elemento del objeto seleccionado, utilizando el factor." + +#: flatcamTools/ToolTransform.py:480 +msgid "Buffer D" +msgstr "Buffer D" + +#: flatcamTools/ToolTransform.py:481 +msgid "Buffer F" +msgstr "Buffer F" + +#: flatcamTools/ToolTransform.py:558 msgid "Rotate transformation can not be done for a value of 0." msgstr "La transformación de rotación no se puede hacer para un valor de 0." -#: flatcamTools/ToolTransform.py:537 flatcamTools/ToolTransform.py:560 +#: flatcamTools/ToolTransform.py:597 flatcamTools/ToolTransform.py:620 msgid "Scale transformation can not be done for a factor of 0 or 1." msgstr "La transformación de escala no se puede hacer para un factor de 0 o 1." -#: flatcamTools/ToolTransform.py:575 flatcamTools/ToolTransform.py:585 +#: flatcamTools/ToolTransform.py:635 flatcamTools/ToolTransform.py:645 msgid "Offset transformation can not be done for a value of 0." msgstr "" "La transformación de compensación no se puede hacer para un valor de 0." -#: flatcamTools/ToolTransform.py:608 +#: flatcamTools/ToolTransform.py:677 msgid "No object selected. Please Select an object to rotate!" msgstr "" "Ningún objeto seleccionado. Por favor, seleccione un objeto para rotar!" -#: flatcamTools/ToolTransform.py:636 +#: flatcamTools/ToolTransform.py:703 msgid "CNCJob objects can't be rotated." msgstr "Los objetos de CNCJob no se pueden girar." -#: flatcamTools/ToolTransform.py:644 +#: flatcamTools/ToolTransform.py:711 msgid "Rotate done" msgstr "Rotar hecho" -#: flatcamTools/ToolTransform.py:649 flatcamTools/ToolTransform.py:724 -#: flatcamTools/ToolTransform.py:779 flatcamTools/ToolTransform.py:838 -#: flatcamTools/ToolTransform.py:874 flatcamTools/ToolTransform.py:910 +#: flatcamTools/ToolTransform.py:714 flatcamTools/ToolTransform.py:784 +#: flatcamTools/ToolTransform.py:834 flatcamTools/ToolTransform.py:890 +#: flatcamTools/ToolTransform.py:922 flatcamTools/ToolTransform.py:958 msgid "Due of" msgstr "Debido a" -#: flatcamTools/ToolTransform.py:649 flatcamTools/ToolTransform.py:724 -#: flatcamTools/ToolTransform.py:779 flatcamTools/ToolTransform.py:838 -#: flatcamTools/ToolTransform.py:874 flatcamTools/ToolTransform.py:910 +#: flatcamTools/ToolTransform.py:714 flatcamTools/ToolTransform.py:784 +#: flatcamTools/ToolTransform.py:834 flatcamTools/ToolTransform.py:890 +#: flatcamTools/ToolTransform.py:922 flatcamTools/ToolTransform.py:958 msgid "action was not executed." msgstr "la acción no se ejecutó." -#: flatcamTools/ToolTransform.py:661 +#: flatcamTools/ToolTransform.py:726 msgid "No object selected. Please Select an object to flip" msgstr "Ningún objeto seleccionado. Seleccione un objeto para voltear" -#: flatcamTools/ToolTransform.py:696 +#: flatcamTools/ToolTransform.py:759 msgid "CNCJob objects can't be mirrored/flipped." msgstr "Los objetos de CNCJob no se pueden reflejar / voltear." -#: flatcamTools/ToolTransform.py:734 +#: flatcamTools/ToolTransform.py:794 msgid "Skew transformation can not be done for 0, 90 and 180 degrees." msgstr "La transformación oblicua no se puede hacer para 0, 90 y 180 grados." -#: flatcamTools/ToolTransform.py:739 +#: flatcamTools/ToolTransform.py:799 msgid "No object selected. Please Select an object to shear/skew!" msgstr "" "Ningún objeto seleccionado. ¡Seleccione un objeto para cortar / sesgar!" -#: flatcamTools/ToolTransform.py:761 +#: flatcamTools/ToolTransform.py:819 msgid "CNCJob objects can't be skewed." msgstr "Los objetos de CNCJob no se pueden sesgar." -#: flatcamTools/ToolTransform.py:774 +#: flatcamTools/ToolTransform.py:831 msgid "Skew on the" msgstr "Sesgar en el" -#: flatcamTools/ToolTransform.py:774 flatcamTools/ToolTransform.py:834 -#: flatcamTools/ToolTransform.py:869 +#: flatcamTools/ToolTransform.py:831 flatcamTools/ToolTransform.py:887 +#: flatcamTools/ToolTransform.py:919 msgid "axis done" msgstr "eje hecho" -#: flatcamTools/ToolTransform.py:791 +#: flatcamTools/ToolTransform.py:846 msgid "No object selected. Please Select an object to scale!" msgstr "" "Ningún objeto seleccionado. Por favor, seleccione un objeto para escalar!" -#: flatcamTools/ToolTransform.py:824 +#: flatcamTools/ToolTransform.py:877 msgid "CNCJob objects can't be scaled." msgstr "Los objetos de CNCJob no se pueden escalar." -#: flatcamTools/ToolTransform.py:834 +#: flatcamTools/ToolTransform.py:887 msgid "Scale on the" msgstr "Escala en el" -#: flatcamTools/ToolTransform.py:846 +#: flatcamTools/ToolTransform.py:898 msgid "No object selected. Please Select an object to offset!" msgstr "" "Ningún objeto seleccionado. Por favor, seleccione un objeto para compensar!" -#: flatcamTools/ToolTransform.py:855 +#: flatcamTools/ToolTransform.py:905 msgid "CNCJob objects can't be offset." msgstr "Los objetos CNCJob no se pueden compensar." -#: flatcamTools/ToolTransform.py:869 +#: flatcamTools/ToolTransform.py:919 msgid "Offset on the" msgstr "Offset en el" -#: flatcamTools/ToolTransform.py:881 +#: flatcamTools/ToolTransform.py:929 msgid "No object selected. Please Select an object to buffer!" msgstr "" "Ningún objeto seleccionado. Por favor, seleccione un objeto para almacenar!" -#: flatcamTools/ToolTransform.py:884 +#: flatcamTools/ToolTransform.py:932 msgid "Applying Buffer" msgstr "Aplicando Tampón" -#: flatcamTools/ToolTransform.py:888 +#: flatcamTools/ToolTransform.py:936 msgid "CNCJob objects can't be buffered." msgstr "Los objetos CNCJob no se pueden almacenar en búfer." -#: flatcamTools/ToolTransform.py:905 +#: flatcamTools/ToolTransform.py:953 msgid "Buffer done" msgstr "Tampón hecho" -#: tclCommands/TclCommandBbox.py:74 tclCommands/TclCommandNregions.py:73 +#: tclCommands/TclCommandBbox.py:76 tclCommands/TclCommandNregions.py:75 msgid "Expected FlatCAMGerber or FlatCAMGeometry, got" msgstr "FlatCAMGerber o FlatCAMGeometry esperado, obtuve" -#: tclCommands/TclCommandBounds.py:64 tclCommands/TclCommandBounds.py:68 +#: tclCommands/TclCommandBounds.py:67 tclCommands/TclCommandBounds.py:71 msgid "Expected a list of objects names separated by comma. Got" msgstr "Se esperaba una lista de nombres de objetos separados por comas. Tiene" -#: tclCommands/TclCommandBounds.py:79 +#: tclCommands/TclCommandBounds.py:82 msgid "TclCommand Bounds done." msgstr "TclCommand Bounds hecho." -#: tclCommands/TclCommandCopperClear.py:242 tclCommands/TclCommandPaint.py:240 -msgid "Expected -box ." -msgstr "Se esperaba -box ." - -#: tclCommands/TclCommandCopperClear.py:251 tclCommands/TclCommandPaint.py:249 -#: tclCommands/TclCommandScale.py:75 +#: tclCommands/TclCommandCopperClear.py:276 tclCommands/TclCommandPaint.py:272 +#: tclCommands/TclCommandScale.py:81 msgid "Could not retrieve box object" msgstr "No se pudo recuperar el objeto" -#: tclCommands/TclCommandCopperClear.py:273 -msgid "" -"None of the following args: 'ref', 'all' were found or none was set to 1.\n" -"Copper clearing failed." -msgstr "" -"Ninguno de los siguientes argumentos: 'ref', 'all' se encontraron o ninguno " -"se estableció en 1.\n" -"La limpieza de cobre falló." +#: tclCommands/TclCommandCopperClear.py:299 +msgid "Expected either -box or -all." +msgstr "Se esperaba -box o -all." -#: tclCommands/TclCommandPaint.py:217 +#: tclCommands/TclCommandGeoCutout.py:148 +msgid "" +"The name of the object for which cutout is done is missing. Add it and retry." +msgstr "" +"Falta el nombre del objeto para el que se realiza el recorte. Añádelo y " +"vuelve a intentarlo." + +#: tclCommands/TclCommandGeoCutout.py:190 +msgid "Gaps value can be only one of: 'lr', 'tb', '2lr', '2tb', 4 or 8." +msgstr "" +"El valor de las brechas solo puede ser uno de: 'Ninguno', 'lr', 'tb', '2lr', " +"'2tb', 4 u 8." + +#: tclCommands/TclCommandGeoCutout.py:302 +#: tclCommands/TclCommandGeoCutout.py:360 +msgid "Any-form Cutout operation finished." +msgstr "Operación de recorte de cualquier forma finalizada." + +#: tclCommands/TclCommandGeoCutout.py:366 +msgid "Cancelled. Object type is not supported." +msgstr "Cancelado. El tipo de objeto no es compatible." + +#: tclCommands/TclCommandHelp.py:74 +msgid "Available commands:" +msgstr "Comandos disponibles:" + +#: tclCommands/TclCommandHelp.py:112 +msgid "Type help for usage." +msgstr "Escriba help para su uso." + +#: tclCommands/TclCommandHelp.py:112 +msgid "Example: help open_gerber" +msgstr "Ejemplo: help open_gerber" + +#: tclCommands/TclCommandPaint.py:244 msgid "Expected -x and -y ." msgstr "Esperado -x y -y ." -#: tclCommands/TclCommandPaint.py:268 +#: tclCommands/TclCommandPaint.py:265 +msgid "Expected -box ." +msgstr "Se esperaba -box ." + +#: tclCommands/TclCommandPaint.py:286 msgid "" -"There was none of the following args: 'ref', 'single', 'all'.\n" +"None of the following args: 'box', 'single', 'all' were used.\n" "Paint failed." msgstr "" -"No hubo ninguno de los siguientes argumentos: 'ref', 'single', 'all'.\n" +"Ninguno de los siguientes argumentos: 'box', 'single', 'all' fueron " +"utilizados.\n" "La pintura falló." -#: tclCommands/TclCommandScale.py:95 -msgid "Expected -origin or -origin or -origin
." -msgstr "Esperado -origin o -origin o -origin
." +#: tclCommands/TclCommandScale.py:106 +msgid "" +"Expected -origin or -origin or -origin
or - " +"origin 3.0,4.2." +msgstr "" +"Esperado -origin o -origin o -origin
o - " +"origin 3.0,4.2." -#: tclCommands/TclCommandScale.py:104 +#: tclCommands/TclCommandScale.py:119 msgid "Expected -x -y ." msgstr "Expected -x -y ." -#: tclCommands/TclCommandSetOrigin.py:91 +#: tclCommands/TclCommandSetOrigin.py:95 msgid "Expected a pair of (x, y) coordinates. Got" msgstr "Se esperaba un par de coordenadas (x, y). Tiene" -#: tclCommands/TclCommandSetOrigin.py:98 +#: tclCommands/TclCommandSetOrigin.py:102 msgid "Origin set by offsetting all loaded objects with " msgstr "Origen establecido al compensar todos los objetos cargados con " -#: tclCommands/TclCommandSubtractRectangle.py:58 +#: tclCommands/TclCommandSubtractRectangle.py:62 msgid "No Geometry name in args. Provide a name and try again." msgstr "" "Sin nombre de geometría en args. Proporcione un nombre e intente nuevamente." +#~ msgid "Executing Tcl Script ..." +#~ msgstr "Ejecutando Tcl Script ..." + +#~ msgid "Open cancelled." +#~ msgstr "Abierto cancelado." + +#~ msgid "Preferences default restore was cancelled." +#~ msgstr "La restauración predeterminada de preferencias fue cancelada." + +#~ msgid "FlatCAM preferences import cancelled." +#~ msgstr "Importación de preferencias de FlatCAM cancelada." + +#~ msgid "FlatCAM preferences export cancelled." +#~ msgstr "Exportación de preferencias de FlatCAM cancelada." + +#~ msgid "Multigeo. Geometry merging finished" +#~ msgstr "Multi Geo. Geometría fusionada terminada" + +#~ msgid "Units conversion cancelled." +#~ msgstr "Conversión de unidades cancelada." + +#~ msgid "Open Gerber cancelled." +#~ msgstr "Abierto Gerber cancelado." + +#~ msgid " Open Excellon cancelled." +#~ msgstr " Abierto Excellon cancelado." + +#~ msgid "Open G-Code cancelled." +#~ msgstr "Abierto G-Code cancelado." + +#~ msgid "Open Project cancelled." +#~ msgstr "Proyecto abierto cancelado." + +#~ msgid "Open HPGL2 file cancelled." +#~ msgstr "Abrir el archivo HPGL2 cancelado." + +#~ msgid "Open Config cancelled." +#~ msgstr "Configuración abierta cancelada." + +#~ msgid " Export SVG cancelled." +#~ msgstr " Exportar SVG cancelado." + +#~ msgid "Export PNG cancelled." +#~ msgstr "Exportación PNG cancelada." + +#~ msgid "No object selected. Please select an Gerber object to export." +#~ msgstr "" +#~ "Ningún objeto seleccionado. Por favor, seleccione un objeto Gerber para " +#~ "exportar." + +#~ msgid "Save Gerber source file cancelled." +#~ msgstr "Guardar el archivo fuente de Gerber cancelado." + +#~ msgid "No object selected. Please select an Script object to export." +#~ msgstr "" +#~ "Ningún objeto seleccionado. Seleccione un objeto Script para exportar." + +#~ msgid "Save Script source file cancelled." +#~ msgstr "Guardar archivo fuente de script cancelado." + +#~ msgid "No object selected. Please select an Document object to export." +#~ msgstr "" +#~ "Ningún objeto seleccionado. Seleccione un objeto de documento para " +#~ "exportar." + +#~ msgid "Save Document source file cancelled." +#~ msgstr "Guardar Documento fuente archivo cancelado." + +#~ msgid "No object selected. Please select an Excellon object to export." +#~ msgstr "" +#~ "Ningún objeto seleccionado. Por favor, seleccione un objeto Excellon para " +#~ "exportar." + +#~ msgid "Saving Excellon source file cancelled." +#~ msgstr "Guardando el archivo fuente Excellon cancelado." + +#~ msgid "No object selected. Please Select an Excellon object to export." +#~ msgstr "" +#~ "Ningún objeto seleccionado. Seleccione un objeto Excellon para exportar." + +#~ msgid "Export Excellon cancelled." +#~ msgstr "Exportación Excellon cancelada." + +#~ msgid "No object selected. Please Select an Gerber object to export." +#~ msgstr "" +#~ "Ningún objeto seleccionado. Seleccione un objeto Gerber para exportar." + +#~ msgid "Export Gerber cancelled." +#~ msgstr "Exportación Gerber cancelada." + +#~ msgid "Export DXF cancelled." +#~ msgstr "Exportación DXF cancelada." + +#~ msgid "Open SVG cancelled." +#~ msgstr "Abrir SVG cancelado." + +#~ msgid "Open DXF cancelled." +#~ msgstr "Abrir DXF cancelado." + +#~ msgid "Open TCL script cancelled." +#~ msgstr "Abrir el script TCL cancelado." + +#~ msgid "Run TCL script cancelled." +#~ msgstr "Ejecutar script TCL cancelado." + +#~ msgid "Save Project cancelled." +#~ msgstr "Guardar Proyecto cancelado." + +#~ msgid "Save Object PDF cancelled." +#~ msgstr "Guardar objeto PDF cancelado." + +#~ msgid "Shows list of commands." +#~ msgstr "Muestra la lista de comandos." + +#~ msgid "FlatCAM bookmarks export cancelled." +#~ msgstr "Exportación de marcadores de FlatCAM cancelada." + +#~ msgid "FlatCAM bookmarks import cancelled." +#~ msgstr "Se canceló la importación de marcadores de FlatCAM." + +#~ msgid "FlatCAM Tools DB export cancelled." +#~ msgstr "Exportación de DB de herramientas FlatCAM cancelada." + +#~ msgid "FlatCAM Tools DB import cancelled." +#~ msgstr "Se ha cancelado la importación de DB de herramientas FlatCAM." + +#~ msgid "" +#~ "Wrong value format for self.defaults[\"z_pdepth\"] or self." +#~ "options[\"z_pdepth\"]" +#~ msgstr "" +#~ "Formato de valor incorrecto para self.defaults [\"z_pdepth\"] o self." +#~ "options [\"z_pdepth\"]" + +#~ msgid "" +#~ "Wrong value format for self.defaults[\"feedrate_probe\"] or self." +#~ "options[\"feedrate_probe\"]" +#~ msgstr "" +#~ "Formato de valor incorrecto para self.defaults [\"feedrate_probe\"] o " +#~ "self.options [\"feedrate_probe\"]" + +#~ msgid "Starting G-Code..." +#~ msgstr "Iniciando el código G ..." + +#~ msgid "" +#~ "Algorithm to paint the polygon:
Standard: Fixed step inwards." +#~ "
Seed-based: Outwards from seed." +#~ msgstr "" +#~ "Algoritmo para pintar el polígono:
Estándar : Paso fijo hacia " +#~ "adentro.
Basado en semillas : Hacia afuera desde las semillas." + +#~ msgid "Seed-based" +#~ msgstr "Semillas" + +#~ msgid "Straight lines" +#~ msgstr "Lineas rectas" + +#~ msgid "Paint cancelled. No shape selected." +#~ msgstr "Pintura cancelada. Ninguna forma seleccionada." + +#~ msgid "Transformation cancelled. No shape selected." +#~ msgstr "Transformación cancelada. Ninguna forma seleccionada." + +#~ msgid "Buffer cancelled. No shape selected." +#~ msgstr "Buffer cancelado. Ninguna forma seleccionada." + +#~ msgid "Export Code cancelled." +#~ msgstr "Exportación de Código cancelada." + +#~ msgid "&Save Project ..." +#~ msgstr "Salvar proyecto ..." + +#~ msgid "Save Project C&opy ..." +#~ msgstr "Guardar copia del proyecto ..." + +#~ msgid "Change the size of the object." +#~ msgstr "Cambiar el tamaño del objeto." + +#~ msgid "Change the position of this object." +#~ msgstr "Cambia la posición de este objeto." + +#~ msgid "Vector" +#~ msgstr "Vector" + +#~ msgid "" +#~ "Create a CNC Job object\n" +#~ "for this drill object." +#~ msgstr "" +#~ "Crear un objeto de trabajo CNC\n" +#~ "para este objeto de perforación." + +#~ msgid "" +#~ "Choose what to use for GCode generation:\n" +#~ "'Drills', 'Slots' or 'Both'.\n" +#~ "When choosing 'Slots' or 'Both', slots will be\n" +#~ "converted to a series of drills." +#~ msgstr "" +#~ "Elija qué usar para la generación de GCode:\n" +#~ "'Taladros', 'Muesca' o 'Ambos'.\n" +#~ "Al elegir 'Muesca' o 'Ambos', los slots serán\n" +#~ "convertido en una serie de simulacros." + +#~ msgid "Generate the CNC Job." +#~ msgstr "Generar el trabajo del CNC." + +#~ msgid "Add Tool from DataBase" +#~ msgstr "Agregar herramienta desde DB" + +#~ msgid "Select a theme for FlatCAM." +#~ msgstr "Seleccione un tema para FlatCAM." + +#~ msgid "Conv." +#~ msgstr "Conv." + +#~ msgid "Diameters of the cutting tools, separated by ','" +#~ msgstr "Diámetros de las herramientas de corte, separados por ','" + +#~ msgid "Tools dia" +#~ msgstr "Herra. dia" + +#~ msgid "The new tool diameter (cut width) to add in the tool table." +#~ msgstr "" +#~ "El nuevo diámetro de herramienta (ancho de corte) para agregar en la " +#~ "tabla de herramientas." + +#~ msgid "" +#~ "Algorithm for non-copper clearing:
Standard: Fixed step inwards." +#~ "
Seed-based: Outwards from seed.
Line-based: Parallel " +#~ "lines." +#~ msgstr "" +#~ "Algoritmo para limpieza sin cobre:
Estándar : paso fijo " +#~ "hacia el interior.
basado en semillas : hacia afuera desde " +#~ "el origen.
basado en líneas : Líneas paralelas." + +#~ msgid "Area" +#~ msgstr "Zona" + +#~ msgid "Ref" +#~ msgstr "Ref" + +#~ msgid "" +#~ "- 'Itself' - the non copper clearing extent\n" +#~ "is based on the object that is copper cleared.\n" +#~ " - 'Area Selection' - left mouse click to start selection of the area to " +#~ "be painted.\n" +#~ "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple " +#~ "areas.\n" +#~ "- 'Reference Object' - will do non copper clearing within the area\n" +#~ "specified by another object." +#~ msgstr "" +#~ "- 'Sí mismo' - la extensión de limpieza sin cobre\n" +#~ "se basa en el objeto que es cobre despejado.\n" +#~ "  - 'Selección de área': haga clic con el botón izquierdo del mouse para " +#~ "iniciar la selección del área a pintar.\n" +#~ "Mantener presionada una tecla modificadora (CTRL o SHIFT) permitirá " +#~ "agregar múltiples áreas.\n" +#~ "- 'Objeto de referencia' - hará una limpieza sin cobre dentro del área\n" +#~ "especificado por otro objeto." + +#~ msgid "Sel" +#~ msgstr "Seleccionar" + +#~ msgid "Diameters of nozzle tools, separated by ','" +#~ msgstr "Diámetros de las herramientas de boquilla, separadas por ','" + +#~ msgid "Reference Gerber" +#~ msgstr "Gerber de referencia" + +#~ msgid "Reference Excellon" +#~ msgstr "Excellon de referencia" + +#~ msgid "Reference Geometry" +#~ msgstr "Geometría de referencia" + +#~ msgid "Point/Box Reference" +#~ msgstr "Punto/caja de referencia" + +#~ msgid "" +#~ "If 'Point' is selected above it store the coordinates (x, y) through " +#~ "which\n" +#~ "the mirroring axis passes.\n" +#~ "If 'Box' is selected above, select here a FlatCAM object (Gerber, Exc or " +#~ "Geo).\n" +#~ "Through the center of this object pass the mirroring axis selected above." +#~ msgstr "" +#~ "Si se selecciona 'Punto' encima, almacena las coordenadas (x, y) a través " +#~ "de las cuales\n" +#~ "el eje reflejado pasa.\n" +#~ "Si se selecciona 'Box' arriba, seleccione aquí un objeto FlatCAM (Gerber, " +#~ "Exc o Geo).\n" +#~ "A través del centro de este objeto pasa el eje reflejado seleccionado " +#~ "anteriormente." + +#~ msgid "Alignment Drill Diameter" +#~ msgstr "Diá. de taladro de alineación" + +#~ msgid "" +#~ "'Point' coordinates missing. Using Origin (0, 0) as mirroring reference." +#~ msgstr "" +#~ "'Punto 'coordenadas faltantes. Usando origen (0, 0) como reflejo de " +#~ "referencia." + +#~ msgid "Export positive film cancelled." +#~ msgstr "Exportación de película positiva cancelada." + +#~ msgid "Export negative film cancelled." +#~ msgstr "Película negativa de exportación cancelada." + +#~ msgid "Move action cancelled." +#~ msgstr "Mover acción cancelada." + +#~ msgid "Diameter for the new tool." +#~ msgstr "Diámetro para la nueva herramienta." + +#~ msgid "Create Paint Geometry" +#~ msgstr "Crear geometría de pintura" + +#~ msgid "Paint Tool. Reading parameters." +#~ msgstr "Herramienta de pintura. Parámetros de lectura." + +#~ msgid "Paint Tool. Normal painting all task started." +#~ msgstr "Herramienta de pintura. La pintura normal comenzó toda tarea." + +#~ msgid "Rest machining painting all task started." +#~ msgstr "Resto mecanizado pintando toda la tarea iniciada." + +#~ msgid "" +#~ "Could not do Paint All. Try a different combination of parameters. Or a " +#~ "different Method of paint" +#~ msgstr "" +#~ "No se pudo Pintar Todo. Pruebe con una combinación diferente de " +#~ "parámetros. O un método diferente de pintura" + +#~ msgid "Rest machining painting area task started." +#~ msgstr "Se inició la tarea de área de pintura de mecanizado en reposo." + +#~ msgid "Paint Tool. Rest machining painting area task started." +#~ msgstr "" +#~ "Herramienta de pintura. Se inició la tarea de área de pintura de " +#~ "mecanizado de descanso." + +#~ msgid "Properties Tool was not displayed. No object selected." +#~ msgstr "" +#~ "La herramienta Propiedades no se mostró. Ningún objeto seleccionado." + +#~ msgid " Export PNG cancelled." +#~ msgstr " Exportación PNG cancelada." + +#~ msgid "Adding Nozzle tool cancelled. Tool already in Tool Table." +#~ msgstr "" +#~ "Se ha cancelado la adición de la herramienta Boquilla. Herramienta ya en " +#~ "la tabla de herramientas." + +#~ msgid "" +#~ "None of the following args: 'ref', 'all' were found or none was set to " +#~ "1.\n" +#~ "Copper clearing failed." +#~ msgstr "" +#~ "Ninguno de los siguientes argumentos: 'ref', 'all' se encontraron o " +#~ "ninguno se estableció en 1.\n" +#~ "La limpieza de cobre falló." + #~ msgid "PostProcessor" #~ msgstr "Postprocesador" @@ -16981,9 +18244,6 @@ msgstr "" #~ msgid "Optimization Time" #~ msgstr "Tiempo de optimización" -#~ msgid "Defaults" -#~ msgstr "Valores predeterminados" - #~ msgid "Coordinates decimals" #~ msgstr "Coordina decimales" @@ -17055,9 +18315,6 @@ msgstr "" #~ msgid "Wk. size" #~ msgstr "Tamaño del ET" -#~ msgid "Plot Line" -#~ msgstr "Lin. Gráfico" - #~ msgid "Sel. Fill" #~ msgstr "El relleno de Sel" @@ -17094,12 +18351,6 @@ msgstr "" #~ msgid "Project at StartUp" #~ msgstr "Proyecto en el inicio" -#~ msgid "Project AutoHide" -#~ msgstr "Proyecto auto ocultar" - -#~ msgid "Enable ToolTips" -#~ msgstr "Hab. info sobre Herram" - #~ msgid "Mouse Cursor" #~ msgstr "Cursor del Mouse" @@ -17123,9 +18374,6 @@ msgstr "" #~ msgid "G-code does not have a units code: either G20 or G21" #~ msgstr "El código G no tiene un código de unidades: G20 o G21" -#~ msgid "No shape selected. Select a shape to explode" -#~ msgstr "Ninguna forma seleccionada. Selecciona una forma para explotar" - #, python-brace-format #~ msgid "" #~ "[selected] {kind} created/selected: {name}" @@ -17443,12 +18691,6 @@ msgstr "" #~ msgid "Geometry Reference Box Object" #~ msgstr "Obj. de cuadro de ref. de Geometría" -#~ msgid "Single Polygon" -#~ msgstr "Polígono único" - -#~ msgid "Painting polygon at location" -#~ msgstr "Pintar polígono en la ubicación" - #, fuzzy #~| msgid "{l_save}/Project_{date}" #~ msgid "{l_save}/FlatCAM_Bookmarks_{date}" @@ -17656,9 +18898,6 @@ msgstr "" #~ msgid "FILE ASSOCIATIONS" #~ msgstr "ASOCIACIONES DE ARCHIVOS" -#~ msgid "Advanced Param." -#~ msgstr "Parám. avanzados" - #~ msgid "MH" #~ msgstr "MH" @@ -18587,9 +19826,6 @@ msgstr "" #~ msgid "Save &Defaults" #~ msgstr "Guardar y valores predeterminados" -#~ msgid "Line" -#~ msgstr "Línea" - #~ msgid "" #~ "How much (fraction) of the tool width to overlap each tool pass.\n" #~ "Example:\n" diff --git a/locale/fr/LC_MESSAGES/strings.mo b/locale/fr/LC_MESSAGES/strings.mo index e69e52efc9f8297dbcbb5382fa6a98e7634f9ecc..6679be5f5e9a1e392571977b3e5275116860edc2 100644 GIT binary patch delta 88161 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 delta 76006 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 XY(@UV{B5RP{IWM_+KayMt~LHYAOK2! diff --git a/locale/fr/LC_MESSAGES/strings.po b/locale/fr/LC_MESSAGES/strings.po index ad897b9b..9af1318e 100644 --- a/locale/fr/LC_MESSAGES/strings.po +++ b/locale/fr/LC_MESSAGES/strings.po @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2019-12-28 20:27+0200\n" -"PO-Revision-Date: 2019-12-28 20:29+0200\n" +"POT-Creation-Date: 2020-04-25 15:00+0300\n" +"PO-Revision-Date: 2020-04-25 15:45+0300\n" "Last-Translator: \n" "Language-Team: \n" "Language: fr\n" @@ -22,17 +22,45 @@ msgstr "" "X-Poedit-SearchPathExcluded-1: doc\n" "X-Poedit-SearchPathExcluded-2: tests\n" -#: FlatCAMApp.py:1040 +#: FlatCAMApp.py:789 FlatCAMApp.py:821 FlatCAMCommon.py:1925 +#: FlatCAMCommon.py:2040 flatcamEditors/FlatCAMGeoEditor.py:500 +#: flatcamEditors/FlatCAMGeoEditor.py:570 +#: flatcamEditors/FlatCAMGeoEditor.py:5152 flatcamGUI/PreferencesUI.py:5509 +#: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 +#: flatcamTools/ToolNCC.py:2396 flatcamTools/ToolNCC.py:2424 +#: flatcamTools/ToolNCC.py:2694 flatcamTools/ToolNCC.py:2726 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:1843 +#: tclCommands/TclCommandCopperClear.py:128 +#: tclCommands/TclCommandCopperClear.py:136 tclCommands/TclCommandPaint.py:127 +msgid "Seed" +msgstr "La graine" + +#: FlatCAMApp.py:795 flatcamGUI/PreferencesUI.py:5588 +#: flatcamGUI/PreferencesUI.py:7695 flatcamTools/ToolCopperThieving.py:126 +#: flatcamTools/ToolNCC.py:535 flatcamTools/ToolNCC.py:1301 +#: flatcamTools/ToolNCC.py:1629 flatcamTools/ToolNCC.py:1914 +#: flatcamTools/ToolNCC.py:1978 flatcamTools/ToolNCC.py:2962 +#: flatcamTools/ToolNCC.py:2971 tclCommands/TclCommandCopperClear.py:190 +msgid "Itself" +msgstr "Lui-même" + +#: FlatCAMApp.py:822 flatcamGUI/PreferencesUI.py:6119 +#: flatcamTools/ToolPaint.py:486 flatcamTools/ToolPaint.py:1422 +#: tclCommands/TclCommandPaint.py:162 +msgid "All Polygons" +msgstr "Tous les polygones" + +#: FlatCAMApp.py:1129 msgid "FlatCAM is initializing ..." msgstr "FlatCAM est en cours d'initialisation ..." -#: FlatCAMApp.py:1669 +#: FlatCAMApp.py:1814 msgid "Could not find the Language files. The App strings are missing." msgstr "" "Impossible de trouver les fichiers de langue. Les chaînes de l'application " "sont manquantes." -#: FlatCAMApp.py:1763 +#: FlatCAMApp.py:1908 msgid "" "FlatCAM is initializing ...\n" "Canvas initialization started." @@ -40,7 +68,7 @@ msgstr "" "FlatCAM est en cours d'initialisation ...\n" "L'initialisation de la toile a commencé." -#: FlatCAMApp.py:1781 +#: FlatCAMApp.py:1928 msgid "" "FlatCAM is initializing ...\n" "Canvas initialization started.\n" @@ -50,69 +78,67 @@ msgstr "" "L'initialisation de la toile a commencé.\n" "Initialisation de la toile terminée en" -#: FlatCAMApp.py:2401 -msgid "" -"Type >help< to get started\n" -"\n" -msgstr "" -"Tapez >help< pour commencer\n" -"\n" +#: FlatCAMApp.py:2570 flatcamGUI/GUIElements.py:2592 +msgid "Type >help< to get started" +msgstr "Tapez >help< pour commencer" -#: FlatCAMApp.py:2627 FlatCAMApp.py:9020 +#: FlatCAMApp.py:2822 FlatCAMApp.py:9400 msgid "New Project - Not saved" msgstr "Nouveau projet - Non enregistré" -#: FlatCAMApp.py:2702 FlatCAMApp.py:9088 FlatCAMApp.py:9125 FlatCAMApp.py:9166 -#: FlatCAMApp.py:9237 FlatCAMApp.py:9991 FlatCAMApp.py:11174 -#: FlatCAMApp.py:11233 -msgid "" -"Canvas initialization started.\n" -"Canvas initialization finished in" -msgstr "" -"L'initialisation de la toile a commencé.\n" -"Initialisation de la toile terminée en" - -#: FlatCAMApp.py:2704 -msgid "Executing Tcl Script ..." -msgstr "Exécution du script Tcl ..." - -#: FlatCAMApp.py:2719 +#: FlatCAMApp.py:2918 msgid "" "Found old default preferences files. Please reboot the application to update." msgstr "" "Anciens fichiers de préférences par défaut trouvés. Veuillez redémarrer " "l'application pour la mettre à jour." -#: FlatCAMApp.py:2763 ObjectCollection.py:90 flatcamTools/ToolImage.py:248 +#: FlatCAMApp.py:2969 FlatCAMApp.py:3889 FlatCAMApp.py:3938 FlatCAMApp.py:3993 +#: FlatCAMApp.py:4068 FlatCAMApp.py:6117 FlatCAMApp.py:9484 FlatCAMApp.py:9521 +#: FlatCAMApp.py:9563 FlatCAMApp.py:9592 FlatCAMApp.py:9632 FlatCAMApp.py:9657 +#: FlatCAMApp.py:9709 FlatCAMApp.py:9745 FlatCAMApp.py:9791 FlatCAMApp.py:9832 +#: FlatCAMApp.py:9873 FlatCAMApp.py:9914 FlatCAMApp.py:9955 FlatCAMApp.py:9999 +#: FlatCAMApp.py:10055 FlatCAMApp.py:10087 FlatCAMApp.py:10119 +#: FlatCAMApp.py:10356 FlatCAMApp.py:10400 FlatCAMApp.py:10477 +#: FlatCAMApp.py:10532 FlatCAMCommon.py:371 FlatCAMCommon.py:413 +#: FlatCAMCommon.py:1107 FlatCAMCommon.py:1153 FlatCAMCommon.py:2537 +#: FlatCAMCommon.py:2583 ObjectCollection.py:122 +#: flatcamEditors/FlatCAMExcEditor.py:1024 +#: flatcamEditors/FlatCAMExcEditor.py:1092 +#: flatcamEditors/FlatCAMTextEditor.py:223 flatcamGUI/FlatCAMGUI.py:3389 +#: flatcamGUI/FlatCAMGUI.py:3601 flatcamGUI/FlatCAMGUI.py:3812 +#: flatcamTools/ToolFilm.py:754 flatcamTools/ToolFilm.py:900 +#: flatcamTools/ToolImage.py:247 flatcamTools/ToolMove.py:270 #: flatcamTools/ToolPcbWizard.py:301 flatcamTools/ToolPcbWizard.py:324 -msgid "Open cancelled." -msgstr "Ouvert annulé." +#: flatcamTools/ToolQRCode.py:791 flatcamTools/ToolQRCode.py:838 +msgid "Cancelled." +msgstr "Annulé." -#: FlatCAMApp.py:2779 +#: FlatCAMApp.py:2985 msgid "Open Config file failed." msgstr "Le fichier de configuration ouvert a échoué." -#: FlatCAMApp.py:2794 +#: FlatCAMApp.py:3000 msgid "Open Script file failed." msgstr "Le fichier de script ouvert a échoué." -#: FlatCAMApp.py:2820 +#: FlatCAMApp.py:3026 msgid "Open Excellon file failed." msgstr "Le fichier de Excellon ouvert a échoué." -#: FlatCAMApp.py:2833 +#: FlatCAMApp.py:3039 msgid "Open GCode file failed." msgstr "Le fichier de G-code ouvert a échoué." -#: FlatCAMApp.py:2846 +#: FlatCAMApp.py:3052 msgid "Open Gerber file failed." msgstr "Le fichier de Gerber ouvert a échoué." -#: FlatCAMApp.py:3201 +#: FlatCAMApp.py:3429 msgid "Select a Geometry, Gerber or Excellon Object to edit." msgstr "Sélectionnez un objet Geometry, Gerber ou Excellon à modifier." -#: FlatCAMApp.py:3216 +#: FlatCAMApp.py:3444 msgid "" "Simultaneous editing of tools geometry in a MultiGeo Geometry is not " "possible.\n" @@ -122,98 +148,96 @@ msgstr "" "n'est pas possible.\n" "Modifiez une seule géométrie à la fois." -#: FlatCAMApp.py:3271 +#: FlatCAMApp.py:3502 msgid "Editor is activated ..." msgstr "L'éditeur est activé ..." -#: FlatCAMApp.py:3292 +#: FlatCAMApp.py:3523 msgid "Do you want to save the edited object?" msgstr "Voulez-vous enregistrer l'objet édité?" -#: FlatCAMApp.py:3293 flatcamGUI/FlatCAMGUI.py:2165 +#: FlatCAMApp.py:3524 flatcamGUI/FlatCAMGUI.py:2273 msgid "Close Editor" msgstr "Fermer l'éditeur" -#: FlatCAMApp.py:3296 FlatCAMApp.py:4014 FlatCAMApp.py:5067 FlatCAMApp.py:7724 -#: FlatCAMApp.py:7750 FlatCAMApp.py:8927 FlatCAMTranslation.py:108 -#: FlatCAMTranslation.py:193 +#: FlatCAMApp.py:3527 FlatCAMApp.py:5169 FlatCAMApp.py:8030 FlatCAMApp.py:8056 +#: FlatCAMApp.py:9305 FlatCAMTranslation.py:108 FlatCAMTranslation.py:199 +#: flatcamGUI/FlatCAMGUI.py:2479 msgid "Yes" msgstr "Oui" -#: FlatCAMApp.py:3297 FlatCAMApp.py:4015 FlatCAMApp.py:5068 FlatCAMApp.py:7725 -#: FlatCAMApp.py:7751 FlatCAMApp.py:8928 FlatCAMTranslation.py:109 -#: FlatCAMTranslation.py:194 flatcamGUI/PreferencesUI.py:5139 -#: flatcamGUI/PreferencesUI.py:5554 flatcamTools/ToolNonCopperClear.py:189 -#: flatcamTools/ToolPaint.py:161 +#: FlatCAMApp.py:3528 FlatCAMApp.py:5170 FlatCAMApp.py:8031 FlatCAMApp.py:8057 +#: FlatCAMApp.py:9306 FlatCAMTranslation.py:109 FlatCAMTranslation.py:200 +#: flatcamGUI/FlatCAMGUI.py:2480 flatcamGUI/PreferencesUI.py:5443 +#: flatcamGUI/PreferencesUI.py:5989 flatcamTools/ToolNCC.py:182 +#: flatcamTools/ToolPaint.py:166 msgid "No" msgstr "Non" -#: FlatCAMApp.py:3298 FlatCAMApp.py:5069 FlatCAMApp.py:5925 FlatCAMApp.py:7006 -#: FlatCAMApp.py:8929 FlatCAMCommon.py:571 flatcamGUI/FlatCAMGUI.py:1260 +#: FlatCAMApp.py:3529 FlatCAMApp.py:5171 FlatCAMApp.py:6055 FlatCAMApp.py:7006 +#: FlatCAMApp.py:9307 FlatCAMCommon.py:572 FlatCAMCommon.py:2127 +#: flatcamGUI/FlatCAMGUI.py:1332 msgid "Cancel" msgstr "Annuler" -#: FlatCAMApp.py:3326 +#: FlatCAMApp.py:3561 msgid "Object empty after edit." msgstr "Objet vide après édition." -#: FlatCAMApp.py:3375 FlatCAMApp.py:3395 FlatCAMApp.py:3410 +#: FlatCAMApp.py:3565 FlatCAMApp.py:3586 FlatCAMApp.py:3608 +msgid "Editor exited. Editor content saved." +msgstr "L'éditeur est sorti. Contenu de l'éditeur enregistré." + +#: FlatCAMApp.py:3612 FlatCAMApp.py:3635 FlatCAMApp.py:3653 msgid "Select a Gerber, Geometry or Excellon Object to update." msgstr "Sélectionnez un objet Gerber, Geometry ou Excellon à mettre à jour." -#: FlatCAMApp.py:3379 +#: FlatCAMApp.py:3615 msgid "is updated, returning to App..." msgstr "est mis à jour, revenant à l'App ..." -#: FlatCAMApp.py:3774 FlatCAMApp.py:3888 FlatCAMApp.py:4929 +#: FlatCAMApp.py:3622 +msgid "Editor exited. Editor content was not saved." +msgstr "L'éditeur est sorti. Le contenu de l'éditeur n'a pas été enregistré." + +#: FlatCAMApp.py:3815 FlatCAMApp.py:3946 FlatCAMApp.py:5018 msgid "Could not load defaults file." msgstr "Impossible de charger le fichier par défaut." -#: FlatCAMApp.py:3786 FlatCAMApp.py:3896 FlatCAMApp.py:4938 +#: FlatCAMApp.py:3827 FlatCAMApp.py:3954 FlatCAMApp.py:5027 msgid "Failed to parse defaults file." msgstr "Échec de l'analyse du fichier par défaut." -#: FlatCAMApp.py:3831 -msgid "Preferences default restore was cancelled." -msgstr "La restauration par défaut des préférences a été annulée." - -#: FlatCAMApp.py:3839 FlatCAMApp.py:5017 +#: FlatCAMApp.py:3897 FlatCAMApp.py:5119 msgid "Could not load factory defaults file." msgstr "Impossible de charger le fichier de paramètres d'usine." -#: FlatCAMApp.py:3847 FlatCAMApp.py:5027 +#: FlatCAMApp.py:3905 FlatCAMApp.py:5129 msgid "Failed to parse factory defaults file." msgstr "Échec de l'analyse du fichier des paramètres d'usine." -#: FlatCAMApp.py:3855 +#: FlatCAMApp.py:3913 msgid "Preferences default values are restored." msgstr "Les valeurs par défaut des préférences sont restaurées." -#: FlatCAMApp.py:3870 FlatCAMApp.py:3874 +#: FlatCAMApp.py:3928 FlatCAMApp.py:3932 msgid "Import FlatCAM Preferences" msgstr "Importer les préférences FlatCAM" -#: FlatCAMApp.py:3880 -msgid "FlatCAM preferences import cancelled." -msgstr "Importation des préférences FlatCAM annulée." - -#: FlatCAMApp.py:3904 +#: FlatCAMApp.py:3962 msgid "Imported Defaults from" msgstr "Valeurs par défaut importées de" -#: FlatCAMApp.py:3924 FlatCAMApp.py:3929 +#: FlatCAMApp.py:3982 FlatCAMApp.py:3987 msgid "Export FlatCAM Preferences" msgstr "Exporter les préférences FlatCAM" -#: FlatCAMApp.py:3936 -msgid "FlatCAM preferences export cancelled." -msgstr "Exportation des préférences FlatCAM annulée." - -#: FlatCAMApp.py:3945 FlatCAMApp.py:10389 FlatCAMApp.py:10437 -#: FlatCAMApp.py:10560 FlatCAMApp.py:10699 FlatCAMCommon.py:378 -#: FlatCAMCommon.py:1114 FlatCAMObj.py:6903 -#: flatcamEditors/FlatCAMTextEditor.py:274 flatcamTools/ToolFilm.py:1019 -#: flatcamTools/ToolFilm.py:1195 flatcamTools/ToolSolderPaste.py:1544 +#: FlatCAMApp.py:4002 FlatCAMApp.py:4076 FlatCAMApp.py:10776 +#: FlatCAMApp.py:10824 FlatCAMApp.py:10950 FlatCAMApp.py:11087 +#: FlatCAMCommon.py:379 FlatCAMCommon.py:1115 FlatCAMCommon.py:2545 +#: FlatCAMObj.py:7484 flatcamEditors/FlatCAMTextEditor.py:276 +#: flatcamTools/ToolFilm.py:1031 flatcamTools/ToolFilm.py:1212 +#: flatcamTools/ToolSolderPaste.py:1533 msgid "" "Permission denied, saving not possible.\n" "Most likely another app is holding the file open and not accessible." @@ -222,108 +246,108 @@ msgstr "" "Très probablement, une autre application tient le fichier ouvert et n'est " "pas accessible." -#: FlatCAMApp.py:3957 +#: FlatCAMApp.py:4014 msgid "Could not load preferences file." msgstr "Impossible de charger le fichier de préférences." -#: FlatCAMApp.py:3976 FlatCAMApp.py:4985 +#: FlatCAMApp.py:4033 FlatCAMApp.py:4100 FlatCAMApp.py:5046 msgid "Failed to write defaults to file." msgstr "Échec d'écriture par défaut dans le fichier." -#: FlatCAMApp.py:3981 +#: FlatCAMApp.py:4038 msgid "Exported preferences to" msgstr "Préférences exportées vers" -#: FlatCAMApp.py:3998 -msgid "FlatCAM Preferences Folder opened." -msgstr "Dossier Préférences FlatCAM ouvert." +#: FlatCAMApp.py:4058 FlatCAMApp.py:4063 +msgid "Save to file" +msgstr "Enregistrer dans un fichier" -#: FlatCAMApp.py:4009 -msgid "Are you sure you want to delete the GUI Settings? \n" -msgstr "Êtes-vous sûr de vouloir supprimer les paramètres de GUI?\n" +#: FlatCAMApp.py:4087 +msgid "Could not load the file." +msgstr "Impossible de charger le fichier." -#: FlatCAMApp.py:4012 flatcamGUI/FlatCAMGUI.py:1230 -msgid "Clear GUI Settings" -msgstr "Effacer les param. de GUI" +#: FlatCAMApp.py:4103 +msgid "Exported file to" +msgstr "Fichier exporté vers" -#: FlatCAMApp.py:4109 +#: FlatCAMApp.py:4186 msgid "Failed to open recent files file for writing." msgstr "Échec d'ouverture du fichier récent en écriture." -#: FlatCAMApp.py:4120 +#: FlatCAMApp.py:4197 msgid "Failed to open recent projects file for writing." msgstr "Échec d'ouverture du fichier de projets récents en écriture." -#: FlatCAMApp.py:4205 FlatCAMApp.py:10900 FlatCAMApp.py:10961 -#: FlatCAMApp.py:11090 FlatCAMObj.py:5050 -#: flatcamEditors/FlatCAMGrbEditor.py:4187 flatcamTools/ToolPcbWizard.py:437 +#: FlatCAMApp.py:4282 FlatCAMApp.py:11283 FlatCAMApp.py:11342 +#: FlatCAMApp.py:11470 FlatCAMApp.py:12196 FlatCAMObj.py:5605 +#: flatcamEditors/FlatCAMGrbEditor.py:4231 flatcamTools/ToolPcbWizard.py:433 msgid "An internal error has occurred. See shell.\n" msgstr "Une erreur interne s'est produite. Voir shell.\n" -#: FlatCAMApp.py:4206 +#: FlatCAMApp.py:4283 #, python-brace-format msgid "" "Object ({kind}) failed because: {error} \n" "\n" msgstr "L'objet ({kind}) a échoué car: {error}\n" -#: FlatCAMApp.py:4221 +#: FlatCAMApp.py:4298 msgid "Converting units to " msgstr "Conversion d'unités en " -#: FlatCAMApp.py:4324 +#: FlatCAMApp.py:4411 msgid "CREATE A NEW FLATCAM TCL SCRIPT" msgstr "CRÉER UN NOUVEAU SCRIPT FLATCAM TCL" -#: FlatCAMApp.py:4325 +#: FlatCAMApp.py:4412 msgid "TCL Tutorial is here" msgstr "Le didacticiel TCL est ici" -#: FlatCAMApp.py:4327 +#: FlatCAMApp.py:4414 msgid "FlatCAM commands list" msgstr "Liste des commandes FlatCAM" -#: FlatCAMApp.py:4378 FlatCAMApp.py:4384 FlatCAMApp.py:4390 FlatCAMApp.py:4396 -#: FlatCAMApp.py:4402 FlatCAMApp.py:4408 +#: FlatCAMApp.py:4465 FlatCAMApp.py:4471 FlatCAMApp.py:4477 FlatCAMApp.py:4483 +#: FlatCAMApp.py:4489 FlatCAMApp.py:4495 msgid "created/selected" msgstr "créé / sélectionné" -#: FlatCAMApp.py:4423 FlatCAMApp.py:7086 FlatCAMObj.py:271 FlatCAMObj.py:302 -#: FlatCAMObj.py:318 FlatCAMObj.py:398 flatcamTools/ToolCopperThieving.py:1476 -#: flatcamTools/ToolFiducials.py:807 flatcamTools/ToolMove.py:220 -#: flatcamTools/ToolQRCode.py:726 +#: FlatCAMApp.py:4510 FlatCAMApp.py:7092 FlatCAMObj.py:278 FlatCAMObj.py:309 +#: FlatCAMObj.py:325 FlatCAMObj.py:405 flatcamTools/ToolCopperThieving.py:1482 +#: flatcamTools/ToolFiducials.py:809 flatcamTools/ToolMove.py:230 +#: flatcamTools/ToolQRCode.py:728 msgid "Plotting" msgstr "Traçage" -#: FlatCAMApp.py:4486 flatcamGUI/FlatCAMGUI.py:491 +#: FlatCAMApp.py:4573 flatcamGUI/FlatCAMGUI.py:530 msgid "About FlatCAM" msgstr "À propos de FlatCAM" -#: FlatCAMApp.py:4512 +#: FlatCAMApp.py:4599 msgid "2D Computer-Aided Printed Circuit Board Manufacturing" msgstr "Fabrication de cartes de circuits imprimés 2D assistées par ordinateur" -#: FlatCAMApp.py:4513 +#: FlatCAMApp.py:4600 msgid "Development" msgstr "Développement" -#: FlatCAMApp.py:4514 +#: FlatCAMApp.py:4601 msgid "DOWNLOAD" msgstr "TÉLÉCHARGER" -#: FlatCAMApp.py:4515 +#: FlatCAMApp.py:4602 msgid "Issue tracker" msgstr "Traqueur d'incidents" -#: FlatCAMApp.py:4519 FlatCAMApp.py:4860 +#: FlatCAMApp.py:4606 FlatCAMApp.py:4948 flatcamGUI/GUIElements.py:2583 msgid "Close" msgstr "Proche" -#: FlatCAMApp.py:4534 +#: FlatCAMApp.py:4621 msgid "Licensed under the MIT license" msgstr "Sous licence MIT" -#: FlatCAMApp.py:4543 +#: FlatCAMApp.py:4630 msgid "" "Permission is hereby granted, free of charge, to any person obtaining a " "copy\n" @@ -375,7 +399,7 @@ msgstr "" "DANS\n" "LES LOGICIELS." -#: FlatCAMApp.py:4565 +#: FlatCAMApp.py:4652 msgid "" "Some of the icons used are from the following sources:

Icônes de " "oNline Web Fonts" -#: FlatCAMApp.py:4597 +#: FlatCAMApp.py:4685 msgid "Splash" msgstr "Éclaboussure" -#: FlatCAMApp.py:4603 +#: FlatCAMApp.py:4691 msgid "Programmers" msgstr "Programmeurs" -#: FlatCAMApp.py:4609 +#: FlatCAMApp.py:4697 msgid "Translators" msgstr "Traducteurs" -#: FlatCAMApp.py:4615 +#: FlatCAMApp.py:4703 msgid "License" msgstr "Licence" -#: FlatCAMApp.py:4621 +#: FlatCAMApp.py:4709 msgid "Attributions" msgstr "Attributions" -#: FlatCAMApp.py:4644 +#: FlatCAMApp.py:4732 msgid "Programmer" msgstr "Programmeur" -#: FlatCAMApp.py:4645 +#: FlatCAMApp.py:4733 msgid "Status" msgstr "Statut" -#: FlatCAMApp.py:4646 FlatCAMApp.py:4724 +#: FlatCAMApp.py:4734 FlatCAMApp.py:4812 msgid "E-mail" msgstr "Email" -#: FlatCAMApp.py:4654 +#: FlatCAMApp.py:4742 msgid "BETA Maintainer >= 2019" msgstr "Mainteneur BETA> = 2019" -#: FlatCAMApp.py:4721 +#: FlatCAMApp.py:4809 msgid "Language" msgstr "La langue" -#: FlatCAMApp.py:4722 +#: FlatCAMApp.py:4810 msgid "Translator" msgstr "Traducteur" -#: FlatCAMApp.py:4723 +#: FlatCAMApp.py:4811 msgid "Corrections" msgstr "Les corrections" -#: FlatCAMApp.py:4832 FlatCAMApp.py:4840 FlatCAMApp.py:7769 -#: flatcamGUI/FlatCAMGUI.py:473 +#: FlatCAMApp.py:4920 FlatCAMApp.py:4928 FlatCAMApp.py:8075 +#: flatcamGUI/FlatCAMGUI.py:512 msgid "Bookmarks Manager" msgstr "Gestionnaire de favoris" -#: FlatCAMApp.py:4851 +#: FlatCAMApp.py:4939 msgid "" "This entry will resolve to another website if:\n" "\n" @@ -464,27 +488,27 @@ msgstr "" "Si vous ne pouvez pas obtenir d'informations sur FlatCAM beta\n" "utilisez le lien de chaîne YouTube dans le menu Aide." -#: FlatCAMApp.py:4858 +#: FlatCAMApp.py:4946 msgid "Alternative website" msgstr "Site alternatif" -#: FlatCAMApp.py:4989 FlatCAMApp.py:7733 +#: FlatCAMApp.py:5050 FlatCAMApp.py:8039 msgid "Preferences saved." msgstr "Préférences enregistrées." -#: FlatCAMApp.py:5043 +#: FlatCAMApp.py:5145 msgid "Failed to write factory defaults to file." msgstr "Échec de l'écriture des paramètres d'usine par défaut dans le fichier." -#: FlatCAMApp.py:5047 +#: FlatCAMApp.py:5149 msgid "Factory defaults saved." msgstr "Les paramètres d'usine par défaut ont été enregistrés." -#: FlatCAMApp.py:5057 flatcamGUI/FlatCAMGUI.py:3962 +#: FlatCAMApp.py:5159 flatcamGUI/FlatCAMGUI.py:4178 msgid "Application is saving the project. Please wait ..." msgstr "L'application enregistre le projet. S'il vous plaît, attendez ..." -#: FlatCAMApp.py:5062 FlatCAMTranslation.py:188 +#: FlatCAMApp.py:5164 FlatCAMTranslation.py:194 msgid "" "There are files/objects modified in FlatCAM. \n" "Do you want to Save the project?" @@ -492,30 +516,30 @@ msgstr "" "Il y a des fichiers / objets modifiés dans FlatCAM.\n" "Voulez-vous enregistrer le projet?" -#: FlatCAMApp.py:5065 FlatCAMApp.py:8925 FlatCAMTranslation.py:191 +#: FlatCAMApp.py:5167 FlatCAMApp.py:9303 FlatCAMTranslation.py:197 msgid "Save changes" msgstr "Sauvegarder les modifications" -#: FlatCAMApp.py:5306 +#: FlatCAMApp.py:5423 msgid "Selected Excellon file extensions registered with FlatCAM." msgstr "" "Extensions de fichier Excellon sélectionnées enregistrées avec FlatCAM." -#: FlatCAMApp.py:5328 +#: FlatCAMApp.py:5445 msgid "Selected GCode file extensions registered with FlatCAM." msgstr "Extensions de fichier GCode sélectionnées enregistrées avec FlatCAM." -#: FlatCAMApp.py:5350 +#: FlatCAMApp.py:5467 msgid "Selected Gerber file extensions registered with FlatCAM." msgstr "Extensions de fichiers Gerber sélectionnées enregistrées avec FlatCAM." -#: FlatCAMApp.py:5538 FlatCAMApp.py:5595 FlatCAMApp.py:5623 +#: FlatCAMApp.py:5655 FlatCAMApp.py:5714 FlatCAMApp.py:5742 msgid "At least two objects are required for join. Objects currently selected" msgstr "" "Au moins deux objets sont requis pour la jointure. Objets actuellement " "sélectionnés" -#: FlatCAMApp.py:5547 +#: FlatCAMApp.py:5664 msgid "" "Failed join. The Geometry objects are of different types.\n" "At least one is MultiGeo type and the other is SingleGeo type. A possibility " @@ -532,51 +556,47 @@ msgstr "" "attendu.\n" "Vérifiez le GCODE généré." -#: FlatCAMApp.py:5559 -msgid "Multigeo. Geometry merging finished" -msgstr "Multigeo. Fusion de la géométrie terminée" - -#: FlatCAMApp.py:5568 +#: FlatCAMApp.py:5676 FlatCAMApp.py:5686 msgid "Geometry merging finished" msgstr "Fusion de la géométrie terminée" -#: FlatCAMApp.py:5590 +#: FlatCAMApp.py:5709 msgid "Failed. Excellon joining works only on Excellon objects." msgstr "Échoué. Excellon rejoindre ne travaille que sur des objets Excellon." -#: FlatCAMApp.py:5600 +#: FlatCAMApp.py:5719 msgid "Excellon merging finished" msgstr "Fusion de la Excellon terminée" -#: FlatCAMApp.py:5618 +#: FlatCAMApp.py:5737 msgid "Failed. Gerber joining works only on Gerber objects." msgstr "Échoué. La jonction de Gerber ne fonctionne que sur des objets Gerber." -#: FlatCAMApp.py:5628 +#: FlatCAMApp.py:5747 msgid "Gerber merging finished" msgstr "Fusion de Gerber terminée" -#: FlatCAMApp.py:5648 FlatCAMApp.py:5683 +#: FlatCAMApp.py:5767 FlatCAMApp.py:5802 msgid "Failed. Select a Geometry Object and try again." msgstr "Échoué. Sélectionnez un objet de géométrie et réessayez." -#: FlatCAMApp.py:5652 FlatCAMApp.py:5688 +#: FlatCAMApp.py:5771 FlatCAMApp.py:5807 msgid "Expected a FlatCAMGeometry, got" msgstr "Échoué. Sélectionnez un objet de géométrie et réessayez" -#: FlatCAMApp.py:5665 +#: FlatCAMApp.py:5784 msgid "A Geometry object was converted to MultiGeo type." msgstr "Un objet Geometry a été converti en type MultiGeo." -#: FlatCAMApp.py:5703 +#: FlatCAMApp.py:5822 msgid "A Geometry object was converted to SingleGeo type." msgstr "Un objet Geometry a été converti en type SingleGeo." -#: FlatCAMApp.py:5919 +#: FlatCAMApp.py:6049 msgid "Toggle Units" msgstr "Basculer les Unités" -#: FlatCAMApp.py:5921 +#: FlatCAMApp.py:6051 msgid "" "Changing the units of the project\n" "will scale all objects.\n" @@ -588,29 +608,25 @@ msgstr "" "\n" "Voulez-vous continuer?" -#: FlatCAMApp.py:5924 FlatCAMApp.py:6929 FlatCAMApp.py:7005 FlatCAMApp.py:9290 -#: FlatCAMApp.py:9304 FlatCAMApp.py:9658 FlatCAMApp.py:9669 +#: FlatCAMApp.py:6054 FlatCAMApp.py:6928 FlatCAMApp.py:7005 FlatCAMApp.py:9676 +#: FlatCAMApp.py:9690 FlatCAMApp.py:10025 FlatCAMApp.py:10035 msgid "Ok" msgstr "D'accord" -#: FlatCAMApp.py:5973 +#: FlatCAMApp.py:6103 msgid "Converted units to" msgstr "Unités converties en" -#: FlatCAMApp.py:5987 -msgid "Units conversion cancelled." -msgstr "La conversion des unités a été annulée." - -#: FlatCAMApp.py:6613 +#: FlatCAMApp.py:6743 msgid "Detachable Tabs" msgstr "Onglets détachables" -#: FlatCAMApp.py:6828 FlatCAMApp.py:6889 FlatCAMApp.py:7560 FlatCAMApp.py:7622 -#: FlatCAMApp.py:7688 +#: FlatCAMApp.py:6817 FlatCAMApp.py:6861 FlatCAMApp.py:6889 FlatCAMApp.py:7822 +#: FlatCAMApp.py:7890 FlatCAMApp.py:7994 msgid "Preferences" msgstr "Préférences" -#: FlatCAMApp.py:6831 +#: FlatCAMApp.py:6823 msgid "Preferences applied." msgstr "Préférences appliquées." @@ -618,20 +634,20 @@ msgstr "Préférences appliquées." msgid "Preferences closed without saving." msgstr "Les préférences se sont fermées sans enregistrer." -#: FlatCAMApp.py:6917 flatcamTools/ToolNonCopperClear.py:591 -#: flatcamTools/ToolNonCopperClear.py:987 flatcamTools/ToolPaint.py:502 -#: flatcamTools/ToolSolderPaste.py:562 flatcamTools/ToolSolderPaste.py:892 +#: FlatCAMApp.py:6917 flatcamTools/ToolNCC.py:932 flatcamTools/ToolNCC.py:1426 +#: flatcamTools/ToolPaint.py:858 flatcamTools/ToolSolderPaste.py:568 +#: flatcamTools/ToolSolderPaste.py:893 msgid "Please enter a tool diameter with non-zero value, in Float format." msgstr "" "Veuillez saisir un diamètre d’outil avec une valeur non nulle, au format " "réel." -#: FlatCAMApp.py:6922 flatcamTools/ToolNonCopperClear.py:595 -#: flatcamTools/ToolPaint.py:506 flatcamTools/ToolSolderPaste.py:566 +#: FlatCAMApp.py:6921 flatcamTools/ToolNCC.py:936 flatcamTools/ToolPaint.py:862 +#: flatcamTools/ToolSolderPaste.py:572 msgid "Adding Tool cancelled" msgstr "Outil d'ajout annulé" -#: FlatCAMApp.py:6925 +#: FlatCAMApp.py:6924 msgid "" "Adding Tool works only when Advanced is checked.\n" "Go to Preferences -> General - Show Advanced Options." @@ -651,107 +667,149 @@ msgstr "" "Êtes-vous sûr de vouloir supprimer définitivement\n" "les objets sélectionnés?" -#: FlatCAMApp.py:7034 +#: FlatCAMApp.py:7041 msgid "Object(s) deleted" msgstr "Objet (s) supprimé (s)" -#: FlatCAMApp.py:7038 flatcamTools/ToolDblSided.py:713 +#: FlatCAMApp.py:7045 FlatCAMApp.py:7200 flatcamTools/ToolDblSided.py:819 msgid "Failed. No object(s) selected..." msgstr "Échoué. Aucun objet sélectionné ..." -#: FlatCAMApp.py:7040 +#: FlatCAMApp.py:7047 msgid "Save the work in Editor and try again ..." msgstr "Enregistrez le travail dans l'éditeur et réessayez ..." -#: FlatCAMApp.py:7070 +#: FlatCAMApp.py:7076 msgid "Object deleted" msgstr "Objet supprimé" -#: FlatCAMApp.py:7097 +#: FlatCAMApp.py:7103 msgid "Click to set the origin ..." msgstr "Cliquez pour définir l'origine ..." -#: FlatCAMApp.py:7119 +#: FlatCAMApp.py:7125 msgid "Setting Origin..." msgstr "Réglage de l'Origine ..." -#: FlatCAMApp.py:7131 +#: FlatCAMApp.py:7138 FlatCAMApp.py:7240 msgid "Origin set" msgstr "Ensemble d'origine" -#: FlatCAMApp.py:7138 +#: FlatCAMApp.py:7155 msgid "Origin coordinates specified but incomplete." msgstr "Coordonnées d'origine spécifiées mais incomplètes." -#: FlatCAMApp.py:7197 +#: FlatCAMApp.py:7196 +msgid "Moving to Origin..." +msgstr "Déplacement vers l'origine ..." + +#: FlatCAMApp.py:7277 msgid "Jump to ..." msgstr "Sauter à ..." -#: FlatCAMApp.py:7198 +#: FlatCAMApp.py:7278 msgid "Enter the coordinates in format X,Y:" msgstr "Entrez les coordonnées au format X, Y:" -#: FlatCAMApp.py:7208 +#: FlatCAMApp.py:7288 msgid "Wrong coordinates. Enter coordinates in format: X,Y" msgstr "Mauvaises coordonnées. Entrez les coordonnées au format: X, Y" -#: FlatCAMApp.py:7288 flatcamEditors/FlatCAMExcEditor.py:3599 -#: flatcamEditors/FlatCAMExcEditor.py:3607 -#: flatcamEditors/FlatCAMGeoEditor.py:4036 -#: flatcamEditors/FlatCAMGeoEditor.py:4051 -#: flatcamEditors/FlatCAMGrbEditor.py:1086 -#: flatcamEditors/FlatCAMGrbEditor.py:1203 -#: flatcamEditors/FlatCAMGrbEditor.py:1489 -#: flatcamEditors/FlatCAMGrbEditor.py:1758 -#: flatcamEditors/FlatCAMGrbEditor.py:4445 -#: flatcamEditors/FlatCAMGrbEditor.py:4460 flatcamGUI/FlatCAMGUI.py:3145 -#: flatcamGUI/FlatCAMGUI.py:3157 +#: FlatCAMApp.py:7366 FlatCAMApp.py:7515 +#: flatcamEditors/FlatCAMExcEditor.py:3622 +#: flatcamEditors/FlatCAMExcEditor.py:3630 +#: flatcamEditors/FlatCAMGeoEditor.py:4349 +#: flatcamEditors/FlatCAMGeoEditor.py:4363 +#: flatcamEditors/FlatCAMGrbEditor.py:1085 +#: flatcamEditors/FlatCAMGrbEditor.py:1202 +#: flatcamEditors/FlatCAMGrbEditor.py:1488 +#: flatcamEditors/FlatCAMGrbEditor.py:1757 +#: flatcamEditors/FlatCAMGrbEditor.py:4489 +#: flatcamEditors/FlatCAMGrbEditor.py:4504 flatcamGUI/FlatCAMGUI.py:3370 +#: flatcamGUI/FlatCAMGUI.py:3382 flatcamTools/ToolAlignObjects.py:393 +#: flatcamTools/ToolAlignObjects.py:415 msgid "Done." msgstr "Terminé." -#: FlatCAMApp.py:7440 FlatCAMApp.py:7511 +#: FlatCAMApp.py:7381 FlatCAMApp.py:9672 FlatCAMApp.py:9768 FlatCAMApp.py:9810 +#: FlatCAMApp.py:9851 FlatCAMApp.py:9892 FlatCAMApp.py:9933 FlatCAMApp.py:9977 +#: FlatCAMApp.py:10021 FlatCAMApp.py:10510 FlatCAMApp.py:10514 +#: flatcamTools/ToolProperties.py:116 +msgid "No object selected." +msgstr "Aucun objet sélectionné." + +#: FlatCAMApp.py:7400 +msgid "Bottom-Left" +msgstr "En bas à gauche" + +#: FlatCAMApp.py:7401 flatcamGUI/PreferencesUI.py:8111 +#: flatcamTools/ToolCalibration.py:159 +msgid "Top-Left" +msgstr "En haut à gauche" + +#: FlatCAMApp.py:7402 flatcamGUI/PreferencesUI.py:8112 +#: flatcamTools/ToolCalibration.py:160 +msgid "Bottom-Right" +msgstr "En bas à droite" + +#: FlatCAMApp.py:7403 +msgid "Top-Right" +msgstr "En haut à droite" + +#: FlatCAMApp.py:7404 flatcamGUI/ObjectUI.py:2624 +msgid "Center" +msgstr "Centre" + +#: FlatCAMApp.py:7424 +msgid "Locate ..." +msgstr "Localiser ..." + +#: FlatCAMApp.py:7685 FlatCAMApp.py:7762 msgid "No object is selected. Select an object and try again." msgstr "Aucun objet n'est sélectionné. Sélectionnez un objet et réessayez." -#: FlatCAMApp.py:7531 +#: FlatCAMApp.py:7788 msgid "" "Aborting. The current task will be gracefully closed as soon as possible..." msgstr "" "Abandonner La tâche en cours sera clôturée dans les meilleurs délais ..." -#: FlatCAMApp.py:7537 +#: FlatCAMApp.py:7794 msgid "The current task was gracefully closed on user request..." msgstr "" "La tâche en cours a été fermée avec élégance à la demande de " "l'utilisateur ..." -#: FlatCAMApp.py:7619 +#: FlatCAMApp.py:7887 msgid "Preferences edited but not saved." msgstr "Préférences modifiées mais non enregistrées." -#: FlatCAMApp.py:7633 FlatCAMApp.py:7645 FlatCAMApp.py:7662 FlatCAMApp.py:7679 -#: FlatCAMApp.py:7739 FlatCAMCommon.py:1181 FlatCAMCommon.py:1356 -#: FlatCAMObj.py:4256 +#: FlatCAMApp.py:7904 FlatCAMApp.py:7932 FlatCAMApp.py:7959 FlatCAMApp.py:7978 +#: FlatCAMApp.py:8045 FlatCAMCommon.py:1182 FlatCAMCommon.py:1357 +#: FlatCAMCommon.py:2612 FlatCAMCommon.py:2820 FlatCAMObj.py:4798 +#: flatcamTools/ToolNCC.py:3958 flatcamTools/ToolNCC.py:4042 +#: flatcamTools/ToolPaint.py:3548 flatcamTools/ToolPaint.py:3633 msgid "Tools Database" msgstr "Base de données d'outils" -#: FlatCAMApp.py:7659 +#: FlatCAMApp.py:7956 msgid "Tools in Tools Database edited but not saved." msgstr "" "Les outils de la base de données d'outils ont été modifiés mais pas " "enregistrés." -#: FlatCAMApp.py:7683 +#: FlatCAMApp.py:7982 flatcamTools/ToolNCC.py:3965 +#: flatcamTools/ToolPaint.py:3555 msgid "Tool from DB added in Tool Table." msgstr "Outil de la base de données ajouté dans la table d'outils." -#: FlatCAMApp.py:7685 +#: FlatCAMApp.py:7984 msgid "Adding tool from DB is not allowed for this object." msgstr "" "L'ajout d'outil à partir de la base de données n'est pas autorisé pour cet " "objet." -#: FlatCAMApp.py:7719 +#: FlatCAMApp.py:8025 msgid "" "One or more values are changed.\n" "Do you want to save the Preferences?" @@ -759,11 +817,11 @@ msgstr "" "Une ou plusieurs valeurs sont modifiées.\n" "Voulez-vous enregistrer les préférences?" -#: FlatCAMApp.py:7721 flatcamGUI/FlatCAMGUI.py:222 +#: FlatCAMApp.py:8027 flatcamGUI/FlatCAMGUI.py:291 msgid "Save Preferences" msgstr "Enregistrer les préf" -#: FlatCAMApp.py:7745 +#: FlatCAMApp.py:8051 msgid "" "One or more Tools are edited.\n" "Do you want to update the Tools Database?" @@ -771,175 +829,177 @@ msgstr "" "Un ou plusieurs outils sont modifiés.\n" "Voulez-vous mettre à jour la base de données d'outils?" -#: FlatCAMApp.py:7747 +#: FlatCAMApp.py:8053 msgid "Save Tools Database" msgstr "Enregistrer la base de données d'outils" -#: FlatCAMApp.py:7766 FlatCAMApp.py:9897 FlatCAMObj.py:6509 +#: FlatCAMApp.py:8072 FlatCAMApp.py:10259 FlatCAMObj.py:7089 msgid "Code Editor" msgstr "Éditeur de code" -#: FlatCAMApp.py:7784 +#: FlatCAMApp.py:8094 msgid "No object selected to Flip on Y axis." msgstr "Aucun objet sélectionné pour basculer sur l’axe Y." -#: FlatCAMApp.py:7810 +#: FlatCAMApp.py:8120 msgid "Flip on Y axis done." msgstr "Tournez sur l'axe des Y fait." -#: FlatCAMApp.py:7812 FlatCAMApp.py:7854 -#: flatcamEditors/FlatCAMGrbEditor.py:5858 +#: FlatCAMApp.py:8122 FlatCAMApp.py:8170 +#: flatcamEditors/FlatCAMGrbEditor.py:5893 msgid "Flip action was not executed." msgstr "L'Action de retournement n'a pas été exécutée." -#: FlatCAMApp.py:7826 +#: FlatCAMApp.py:8142 msgid "No object selected to Flip on X axis." msgstr "Aucun objet sélectionné pour basculer sur l’axe X." -#: FlatCAMApp.py:7852 +#: FlatCAMApp.py:8168 msgid "Flip on X axis done." msgstr "Tournez sur l'axe X fait." -#: FlatCAMApp.py:7868 +#: FlatCAMApp.py:8190 msgid "No object selected to Rotate." msgstr "Aucun objet sélectionné pour faire pivoter." -#: FlatCAMApp.py:7871 FlatCAMApp.py:7918 FlatCAMApp.py:7951 +#: FlatCAMApp.py:8193 FlatCAMApp.py:8246 FlatCAMApp.py:8285 msgid "Transform" msgstr "Transformer" -#: FlatCAMApp.py:7871 FlatCAMApp.py:7918 FlatCAMApp.py:7951 +#: FlatCAMApp.py:8193 FlatCAMApp.py:8246 FlatCAMApp.py:8285 msgid "Enter the Angle value:" msgstr "Entrez la valeur de l'angle:" -#: FlatCAMApp.py:7902 +#: FlatCAMApp.py:8224 msgid "Rotation done." msgstr "Rotation effectuée." -#: FlatCAMApp.py:7904 +#: FlatCAMApp.py:8226 msgid "Rotation movement was not executed." msgstr "Le mouvement de rotation n'a pas été exécuté." -#: FlatCAMApp.py:7916 +#: FlatCAMApp.py:8244 msgid "No object selected to Skew/Shear on X axis." msgstr "Aucun objet sélectionné pour incliner / cisailler sur l'axe X." -#: FlatCAMApp.py:7938 +#: FlatCAMApp.py:8266 msgid "Skew on X axis done." msgstr "Inclinaison sur l'axe X terminée." -#: FlatCAMApp.py:7949 +#: FlatCAMApp.py:8283 msgid "No object selected to Skew/Shear on Y axis." msgstr "" "Aucun objet sélectionné pour incliner / cisailler sur l'axe des ordonnées." -#: FlatCAMApp.py:7971 +#: FlatCAMApp.py:8305 msgid "Skew on Y axis done." msgstr "Inclinaison sur l'axe des Y faite." -#: FlatCAMApp.py:8119 FlatCAMApp.py:8166 flatcamGUI/FlatCAMGUI.py:449 -#: flatcamGUI/FlatCAMGUI.py:1612 +#: FlatCAMApp.py:8458 FlatCAMApp.py:8505 flatcamGUI/FlatCAMGUI.py:488 +#: flatcamGUI/FlatCAMGUI.py:1713 msgid "Select All" msgstr "Tout sélectionner" -#: FlatCAMApp.py:8123 FlatCAMApp.py:8170 flatcamGUI/FlatCAMGUI.py:451 +#: FlatCAMApp.py:8462 FlatCAMApp.py:8509 flatcamGUI/FlatCAMGUI.py:490 msgid "Deselect All" msgstr "Tout déselectionner" -#: FlatCAMApp.py:8186 +#: FlatCAMApp.py:8525 msgid "All objects are selected." msgstr "Tous les objets sont sélectionnés." -#: FlatCAMApp.py:8196 +#: FlatCAMApp.py:8535 msgid "Objects selection is cleared." msgstr "La sélection des objets est effacée." -#: FlatCAMApp.py:8216 flatcamGUI/FlatCAMGUI.py:1605 +#: FlatCAMApp.py:8555 flatcamGUI/FlatCAMGUI.py:1706 msgid "Grid On/Off" msgstr "Grille On/Off" -#: FlatCAMApp.py:8228 flatcamEditors/FlatCAMGeoEditor.py:940 -#: flatcamEditors/FlatCAMGrbEditor.py:2574 -#: flatcamEditors/FlatCAMGrbEditor.py:5431 flatcamGUI/ObjectUI.py:1304 -#: flatcamTools/ToolDblSided.py:187 flatcamTools/ToolDblSided.py:245 -#: flatcamTools/ToolNonCopperClear.py:286 flatcamTools/ToolPaint.py:188 -#: flatcamTools/ToolSolderPaste.py:121 flatcamTools/ToolSolderPaste.py:591 -#: flatcamTools/ToolTransform.py:310 +#: FlatCAMApp.py:8567 flatcamEditors/FlatCAMGeoEditor.py:940 +#: flatcamEditors/FlatCAMGrbEditor.py:2580 +#: flatcamEditors/FlatCAMGrbEditor.py:5475 flatcamGUI/ObjectUI.py:1593 +#: flatcamTools/ToolDblSided.py:193 flatcamTools/ToolDblSided.py:426 +#: flatcamTools/ToolNCC.py:294 flatcamTools/ToolNCC.py:631 +#: flatcamTools/ToolPaint.py:277 flatcamTools/ToolPaint.py:676 +#: flatcamTools/ToolSolderPaste.py:123 flatcamTools/ToolSolderPaste.py:597 +#: flatcamTools/ToolTransform.py:479 msgid "Add" msgstr "Ajouter" -#: FlatCAMApp.py:8230 FlatCAMObj.py:3963 -#: flatcamEditors/FlatCAMGrbEditor.py:2579 -#: flatcamEditors/FlatCAMGrbEditor.py:2727 flatcamGUI/FlatCAMGUI.py:680 -#: flatcamGUI/FlatCAMGUI.py:991 flatcamGUI/FlatCAMGUI.py:2018 -#: flatcamGUI/FlatCAMGUI.py:2161 flatcamGUI/FlatCAMGUI.py:2559 -#: flatcamGUI/ObjectUI.py:1330 flatcamTools/ToolNonCopperClear.py:298 -#: flatcamTools/ToolPaint.py:200 flatcamTools/ToolSolderPaste.py:127 -#: flatcamTools/ToolSolderPaste.py:594 +#: FlatCAMApp.py:8569 FlatCAMObj.py:4416 +#: flatcamEditors/FlatCAMGrbEditor.py:2585 +#: flatcamEditors/FlatCAMGrbEditor.py:2733 flatcamGUI/FlatCAMGUI.py:736 +#: flatcamGUI/FlatCAMGUI.py:1059 flatcamGUI/FlatCAMGUI.py:2126 +#: flatcamGUI/FlatCAMGUI.py:2269 flatcamGUI/FlatCAMGUI.py:2733 +#: flatcamGUI/ObjectUI.py:1621 flatcamTools/ToolNCC.py:316 +#: flatcamTools/ToolNCC.py:637 flatcamTools/ToolPaint.py:299 +#: flatcamTools/ToolPaint.py:682 flatcamTools/ToolSolderPaste.py:129 +#: flatcamTools/ToolSolderPaste.py:600 msgid "Delete" msgstr "Effacer" -#: FlatCAMApp.py:8243 +#: FlatCAMApp.py:8582 msgid "New Grid ..." msgstr "Nouvelle grille ..." -#: FlatCAMApp.py:8244 +#: FlatCAMApp.py:8583 msgid "Enter a Grid Value:" msgstr "Entrez une valeur de grille:" -#: FlatCAMApp.py:8252 FlatCAMApp.py:8279 +#: FlatCAMApp.py:8591 FlatCAMApp.py:8618 msgid "Please enter a grid value with non-zero value, in Float format." msgstr "" "Veuillez entrer une valeur de grille avec une valeur non nulle, au format " "réel." -#: FlatCAMApp.py:8258 +#: FlatCAMApp.py:8597 msgid "New Grid added" msgstr "Nouvelle grille ajoutée" -#: FlatCAMApp.py:8261 +#: FlatCAMApp.py:8600 msgid "Grid already exists" msgstr "La grille existe déjà" -#: FlatCAMApp.py:8264 +#: FlatCAMApp.py:8603 msgid "Adding New Grid cancelled" msgstr "Ajout d'une nouvelle grille annulée" -#: FlatCAMApp.py:8286 +#: FlatCAMApp.py:8625 msgid " Grid Value does not exist" msgstr " Grid Value does not exist" -#: FlatCAMApp.py:8289 +#: FlatCAMApp.py:8628 msgid "Grid Value deleted" msgstr "Valeur de grille supprimée" -#: FlatCAMApp.py:8292 +#: FlatCAMApp.py:8631 msgid "Delete Grid value cancelled" msgstr "Supprimer la valeur de grille annulée" -#: FlatCAMApp.py:8298 +#: FlatCAMApp.py:8637 msgid "Key Shortcut List" msgstr "Liste de raccourcis clavier" -#: FlatCAMApp.py:8332 +#: FlatCAMApp.py:8671 msgid " No object selected to copy it's name" msgstr " Aucun objet sélectionné pour copier son nom" -#: FlatCAMApp.py:8336 +#: FlatCAMApp.py:8675 msgid "Name copied on clipboard ..." msgstr "Nom copié dans le presse-papiers ..." -#: FlatCAMApp.py:8534 flatcamEditors/FlatCAMGrbEditor.py:4377 +#: FlatCAMApp.py:8888 flatcamEditors/FlatCAMGrbEditor.py:4421 msgid "Coordinates copied to clipboard." msgstr "Coordonnées copiées dans le presse-papier." -#: FlatCAMApp.py:8762 FlatCAMApp.py:8768 FlatCAMApp.py:8774 FlatCAMApp.py:8780 -#: ObjectCollection.py:797 ObjectCollection.py:803 ObjectCollection.py:809 -#: ObjectCollection.py:815 ObjectCollection.py:821 ObjectCollection.py:827 +#: FlatCAMApp.py:9127 FlatCAMApp.py:9133 FlatCAMApp.py:9139 FlatCAMApp.py:9145 +#: ObjectCollection.py:911 ObjectCollection.py:917 ObjectCollection.py:923 +#: ObjectCollection.py:929 ObjectCollection.py:935 ObjectCollection.py:941 msgid "selected" msgstr "choisi" -#: FlatCAMApp.py:8922 +#: FlatCAMApp.py:9300 msgid "" "There are files/objects opened in FlatCAM.\n" "Creating a New project will delete them.\n" @@ -949,380 +1009,278 @@ msgstr "" "La création d'un nouveau projet les supprimera.\n" "Voulez-vous enregistrer le projet?" -#: FlatCAMApp.py:8944 +#: FlatCAMApp.py:9321 msgid "New Project created" msgstr "Nouveau projet créé" -#: FlatCAMApp.py:9079 FlatCAMApp.py:9083 flatcamGUI/FlatCAMGUI.py:767 -#: flatcamGUI/FlatCAMGUI.py:2352 +#: FlatCAMApp.py:9468 FlatCAMApp.py:9472 flatcamGUI/FlatCAMGUI.py:821 +#: flatcamGUI/FlatCAMGUI.py:2504 msgid "Open Gerber" msgstr "Gerber ouvert" -#: FlatCAMApp.py:9090 +#: FlatCAMApp.py:9477 FlatCAMApp.py:9514 FlatCAMApp.py:9556 FlatCAMApp.py:9625 +#: FlatCAMApp.py:10378 FlatCAMApp.py:11553 FlatCAMApp.py:11614 +msgid "" +"Canvas initialization started.\n" +"Canvas initialization finished in" +msgstr "" +"L'initialisation de la toile a commencé.\n" +"Initialisation de la toile terminée en" + +#: FlatCAMApp.py:9479 msgid "Opening Gerber file." msgstr "Ouvrir le fichier Gerber." -#: FlatCAMApp.py:9096 -msgid "Open Gerber cancelled." -msgstr "Ouvert Gerber annulé." - -#: FlatCAMApp.py:9117 FlatCAMApp.py:9121 flatcamGUI/FlatCAMGUI.py:769 -#: flatcamGUI/FlatCAMGUI.py:2354 +#: FlatCAMApp.py:9506 FlatCAMApp.py:9510 flatcamGUI/FlatCAMGUI.py:823 +#: flatcamGUI/FlatCAMGUI.py:2506 msgid "Open Excellon" msgstr "Excellon ouvert" -#: FlatCAMApp.py:9127 +#: FlatCAMApp.py:9516 msgid "Opening Excellon file." msgstr "Ouverture du fichier Excellon." -#: FlatCAMApp.py:9133 -msgid " Open Excellon cancelled." -msgstr " Ouvert Excellon annulé." - -#: FlatCAMApp.py:9157 FlatCAMApp.py:9161 +#: FlatCAMApp.py:9547 FlatCAMApp.py:9551 msgid "Open G-Code" msgstr "G-code ouvert" -#: FlatCAMApp.py:9168 +#: FlatCAMApp.py:9558 msgid "Opening G-Code file." msgstr "Ouverture du fichier G-Code." -#: FlatCAMApp.py:9174 -msgid "Open G-Code cancelled." -msgstr "Ouvert G-code annulé." - -#: FlatCAMApp.py:9192 FlatCAMApp.py:9195 flatcamGUI/FlatCAMGUI.py:1614 +#: FlatCAMApp.py:9581 FlatCAMApp.py:9584 flatcamGUI/FlatCAMGUI.py:1715 msgid "Open Project" msgstr "Projet ouvert" -#: FlatCAMApp.py:9204 -msgid "Open Project cancelled." -msgstr "Projet ouvert annulé." - -#: FlatCAMApp.py:9228 FlatCAMApp.py:9232 +#: FlatCAMApp.py:9616 FlatCAMApp.py:9620 msgid "Open HPGL2" msgstr "Ouvrir le HPGL2" -#: FlatCAMApp.py:9239 +#: FlatCAMApp.py:9627 msgid "Opening HPGL2 file." msgstr "Ouvrir le fichier HPGL2." -#: FlatCAMApp.py:9244 -msgid "Open HPGL2 file cancelled." -msgstr "Ouvrir HPGL2annulé." - -#: FlatCAMApp.py:9262 FlatCAMApp.py:9265 +#: FlatCAMApp.py:9650 FlatCAMApp.py:9653 msgid "Open Configuration File" msgstr "Ouvrir le fichier de configuration" -#: FlatCAMApp.py:9270 -msgid "Open Config cancelled." -msgstr "Configuration ouverte annulée." - -#: FlatCAMApp.py:9286 FlatCAMApp.py:9654 FlatCAMApp.py:10124 -#: FlatCAMApp.py:10128 -msgid "No object selected." -msgstr "Aucun objet sélectionné." - -#: FlatCAMApp.py:9287 FlatCAMApp.py:9655 +#: FlatCAMApp.py:9673 FlatCAMApp.py:10022 msgid "Please Select a Geometry object to export" msgstr "Veuillez sélectionner un objet de géométrie à exporter" -#: FlatCAMApp.py:9301 +#: FlatCAMApp.py:9687 msgid "Only Geometry, Gerber and CNCJob objects can be used." msgstr "Seuls les objets Geometry, Gerber et CNCJob peuvent être utilisés." -#: FlatCAMApp.py:9314 FlatCAMApp.py:9318 flatcamTools/ToolQRCode.py:827 -#: flatcamTools/ToolQRCode.py:831 +#: FlatCAMApp.py:9700 FlatCAMApp.py:9704 flatcamTools/ToolQRCode.py:829 +#: flatcamTools/ToolQRCode.py:833 msgid "Export SVG" msgstr "Exporter en SVG" -#: FlatCAMApp.py:9324 flatcamTools/ToolQRCode.py:836 -msgid " Export SVG cancelled." -msgstr " Export SVG annulé." - -#: FlatCAMApp.py:9345 +#: FlatCAMApp.py:9730 msgid "Data must be a 3D array with last dimension 3 or 4" msgstr "" "Les données doivent être un tableau 3D avec la dernière dimension 3 ou 4" -#: FlatCAMApp.py:9351 FlatCAMApp.py:9355 +#: FlatCAMApp.py:9736 FlatCAMApp.py:9740 msgid "Export PNG Image" msgstr "Exporter une image PNG" -#: FlatCAMApp.py:9360 -msgid "Export PNG cancelled." -msgstr "Exportation PNG annulée." - -#: FlatCAMApp.py:9384 -msgid "No object selected. Please select an Gerber object to export." -msgstr "" -"Aucun objet sélectionné. Veuillez sélectionner un objet Gerber à exporter." - -#: FlatCAMApp.py:9390 FlatCAMApp.py:9613 +#: FlatCAMApp.py:9774 FlatCAMApp.py:9982 msgid "Failed. Only Gerber objects can be saved as Gerber files..." msgstr "" "Échoué. Seuls les objets Gerber peuvent être enregistrés en tant que " "fichiers Gerber ..." -#: FlatCAMApp.py:9402 +#: FlatCAMApp.py:9786 msgid "Save Gerber source file" msgstr "Enregistrer le fichier source Gerber" -#: FlatCAMApp.py:9408 -msgid "Save Gerber source file cancelled." -msgstr "Enregistrer le fichier source Gerber annulé." - -#: FlatCAMApp.py:9428 -msgid "No object selected. Please select an Script object to export." -msgstr "" -"Aucun objet sélectionné. Veuillez sélectionner un objet de script à exporter." - -#: FlatCAMApp.py:9434 +#: FlatCAMApp.py:9815 msgid "Failed. Only Script objects can be saved as TCL Script files..." msgstr "" "Échoué. Seuls les objets de script peuvent être enregistrés en tant que " "fichiers de script TCL ..." -#: FlatCAMApp.py:9446 +#: FlatCAMApp.py:9827 msgid "Save Script source file" msgstr "Enregistrer le fichier source du script" -#: FlatCAMApp.py:9452 -msgid "Save Script source file cancelled." -msgstr "Enregistrer le fichier source du script annulé." - -#: FlatCAMApp.py:9472 -msgid "No object selected. Please select an Document object to export." -msgstr "" -"Aucun objet sélectionné. Veuillez sélectionner un objet Document à exporter." - -#: FlatCAMApp.py:9478 +#: FlatCAMApp.py:9856 msgid "Failed. Only Document objects can be saved as Document files..." msgstr "" "Échoué. Seuls les objets Document peuvent être enregistrés en tant que " "fichiers Document ..." -#: FlatCAMApp.py:9490 +#: FlatCAMApp.py:9868 msgid "Save Document source file" msgstr "Enregistrer le fichier source du document" -#: FlatCAMApp.py:9496 -msgid "Save Document source file cancelled." -msgstr "Enregistrer le fichier source du document annulé." - -#: FlatCAMApp.py:9516 -msgid "No object selected. Please select an Excellon object to export." -msgstr "" -"Aucun objet sélectionné. Veuillez sélectionner un objet Excellon à exporter." - -#: FlatCAMApp.py:9522 FlatCAMApp.py:9566 FlatCAMApp.py:10473 +#: FlatCAMApp.py:9897 FlatCAMApp.py:9938 FlatCAMApp.py:10863 msgid "Failed. Only Excellon objects can be saved as Excellon files..." msgstr "" "Échoué. Seuls les objets Excellon peuvent être enregistrés en tant que " "fichiers Excellon ..." -#: FlatCAMApp.py:9530 FlatCAMApp.py:9534 +#: FlatCAMApp.py:9905 FlatCAMApp.py:9909 msgid "Save Excellon source file" msgstr "Enregistrer le fichier source Excellon" -#: FlatCAMApp.py:9540 -msgid "Saving Excellon source file cancelled." -msgstr "Enregistrement du fichier source Excellon annulé." - -#: FlatCAMApp.py:9560 -msgid "No object selected. Please Select an Excellon object to export." -msgstr "" -"Aucun objet sélectionné. Veuillez sélectionner un objet Excellon à exporter." - -#: FlatCAMApp.py:9574 FlatCAMApp.py:9578 +#: FlatCAMApp.py:9946 FlatCAMApp.py:9950 msgid "Export Excellon" msgstr "Exporter Excellon" -#: FlatCAMApp.py:9584 -msgid "Export Excellon cancelled." -msgstr "Exporter Excellon annulé." - -#: FlatCAMApp.py:9607 -msgid "No object selected. Please Select an Gerber object to export." -msgstr "" -"Aucun objet sélectionné. Veuillez sélectionner un objet Gerber à exporter." - -#: FlatCAMApp.py:9621 FlatCAMApp.py:9625 +#: FlatCAMApp.py:9990 FlatCAMApp.py:9994 msgid "Export Gerber" msgstr "Export Gerber" -#: FlatCAMApp.py:9631 -msgid "Export Gerber cancelled." -msgstr "Export Gerber annulé." - -#: FlatCAMApp.py:9666 +#: FlatCAMApp.py:10032 msgid "Only Geometry objects can be used." msgstr "Seuls les objets de géométrie peuvent être utilisés." -#: FlatCAMApp.py:9680 FlatCAMApp.py:9684 +#: FlatCAMApp.py:10046 FlatCAMApp.py:10050 msgid "Export DXF" msgstr "Exportation DXF" -#: FlatCAMApp.py:9691 -msgid "Export DXF cancelled." -msgstr "Exportation DXF annulée." - -#: FlatCAMApp.py:9711 FlatCAMApp.py:9714 +#: FlatCAMApp.py:10075 FlatCAMApp.py:10078 msgid "Import SVG" msgstr "Importer SVG" -#: FlatCAMApp.py:9724 -msgid "Open SVG cancelled." -msgstr "Ouvrir SVG annulé." - -#: FlatCAMApp.py:9743 FlatCAMApp.py:9747 +#: FlatCAMApp.py:10106 FlatCAMApp.py:10110 msgid "Import DXF" msgstr "Importation DXF" -#: FlatCAMApp.py:9757 -msgid "Open DXF cancelled." -msgstr "Ouvrir DXF annulé." - -#: FlatCAMApp.py:9799 +#: FlatCAMApp.py:10161 msgid "Viewing the source code of the selected object." msgstr "Affichage du code source de l'objet sélectionné." -#: FlatCAMApp.py:9800 FlatCAMObj.py:6495 FlatCAMObj.py:7225 +#: FlatCAMApp.py:10162 FlatCAMObj.py:7075 FlatCAMObj.py:7852 msgid "Loading..." msgstr "Chargement..." -#: FlatCAMApp.py:9806 FlatCAMApp.py:9810 +#: FlatCAMApp.py:10168 FlatCAMApp.py:10172 msgid "Select an Gerber or Excellon file to view it's source file." msgstr "" "Sélectionnez un fichier Gerber ou Excellon pour afficher son fichier source." -#: FlatCAMApp.py:9824 +#: FlatCAMApp.py:10186 msgid "Source Editor" msgstr "Éditeur de source" -#: FlatCAMApp.py:9864 FlatCAMApp.py:9871 +#: FlatCAMApp.py:10226 FlatCAMApp.py:10233 msgid "There is no selected object for which to see it's source file code." msgstr "" "Il n'y a pas d'objet sélectionné pour lequel voir son code de fichier source." -#: FlatCAMApp.py:9883 +#: FlatCAMApp.py:10245 msgid "Failed to load the source code for the selected object" msgstr "Échec du chargement du code source pour l'objet sélectionné" -#: FlatCAMApp.py:9925 +#: FlatCAMApp.py:10281 +msgid "Go to Line ..." +msgstr "Aller à la ligne ..." + +#: FlatCAMApp.py:10282 +msgid "Line:" +msgstr "Ligne:" + +#: FlatCAMApp.py:10311 msgid "New TCL script file created in Code Editor." msgstr "Nouveau fichier de script TCL créé dans l'éditeur de code." -#: FlatCAMApp.py:9963 FlatCAMApp.py:9965 +#: FlatCAMApp.py:10350 FlatCAMApp.py:10352 msgid "Open TCL script" msgstr "Ouvrir le script TCL" -#: FlatCAMApp.py:9969 -msgid "Open TCL script cancelled." -msgstr "Ouvrir le script TCL annulé." - -#: FlatCAMApp.py:9993 +#: FlatCAMApp.py:10380 msgid "Executing FlatCAMScript file." msgstr "Exécution du fichier FlatCAMScript." -#: FlatCAMApp.py:10000 FlatCAMApp.py:10003 +#: FlatCAMApp.py:10388 FlatCAMApp.py:10391 msgid "Run TCL script" msgstr "Exécuter le script TCL" -#: FlatCAMApp.py:10013 -msgid "Run TCL script cancelled." -msgstr "Exécuter le script TCL annulé." - -#: FlatCAMApp.py:10029 +#: FlatCAMApp.py:10415 msgid "TCL script file opened in Code Editor and executed." msgstr "Fichier de script TCL ouvert dans l'éditeur de code et exécuté." -#: FlatCAMApp.py:10080 FlatCAMApp.py:10086 +#: FlatCAMApp.py:10466 FlatCAMApp.py:10472 msgid "Save Project As ..." msgstr "Enregistrer le projet sous ..." -#: FlatCAMApp.py:10082 flatcamGUI/FlatCAMGUI.py:1051 -#: flatcamGUI/FlatCAMGUI.py:2053 +#: FlatCAMApp.py:10468 flatcamGUI/FlatCAMGUI.py:1119 +#: flatcamGUI/FlatCAMGUI.py:2161 msgid "Project" msgstr "Projet" -#: FlatCAMApp.py:10091 -msgid "Save Project cancelled." -msgstr "Enregistrer le projet annulé." - -#: FlatCAMApp.py:10121 +#: FlatCAMApp.py:10507 msgid "FlatCAM objects print" msgstr "Impression d'objets FlatCAM" -#: FlatCAMApp.py:10134 FlatCAMApp.py:10141 +#: FlatCAMApp.py:10520 FlatCAMApp.py:10527 msgid "Save Object as PDF ..." msgstr "Enregistrer l'objet au format PDF ...Enregistrer le projet sous ..." -#: FlatCAMApp.py:10146 -msgid "Save Object PDF cancelled." -msgstr "Enregistrer l'objet PDF annulé." - -#: FlatCAMApp.py:10150 +#: FlatCAMApp.py:10536 msgid "Printing PDF ... Please wait." msgstr "Impression du PDF ... Veuillez patienter." -#: FlatCAMApp.py:10329 +#: FlatCAMApp.py:10715 msgid "PDF file saved to" msgstr "Fichier PDF enregistré dans" -#: FlatCAMApp.py:10353 +#: FlatCAMApp.py:10740 msgid "Exporting SVG" msgstr "Exporter du SVG" -#: FlatCAMApp.py:10397 +#: FlatCAMApp.py:10783 msgid "SVG file exported to" msgstr "Fichier SVG exporté vers" -#: FlatCAMApp.py:10422 +#: FlatCAMApp.py:10809 msgid "" "Save cancelled because source file is empty. Try to export the Gerber file." msgstr "" "Enregistrement annulé car le fichier source est vide. Essayez d'exporter le " "fichier Gerber." -#: FlatCAMApp.py:10568 +#: FlatCAMApp.py:10957 msgid "Excellon file exported to" msgstr "Fichier Excellon exporté vers" -#: FlatCAMApp.py:10577 +#: FlatCAMApp.py:10966 msgid "Exporting Excellon" msgstr "Exporter Excellon" -#: FlatCAMApp.py:10583 FlatCAMApp.py:10591 +#: FlatCAMApp.py:10971 FlatCAMApp.py:10978 msgid "Could not export Excellon file." msgstr "Impossible d'exporter le fichier Excellon." -#: FlatCAMApp.py:10707 +#: FlatCAMApp.py:11094 msgid "Gerber file exported to" msgstr "Fichier Gerber exporté vers" -#: FlatCAMApp.py:10715 +#: FlatCAMApp.py:11102 msgid "Exporting Gerber" msgstr "Exporter Gerber" -#: FlatCAMApp.py:10721 FlatCAMApp.py:10729 +#: FlatCAMApp.py:11107 FlatCAMApp.py:11114 msgid "Could not export Gerber file." msgstr "Impossible d'exporter le fichier Gerber." -#: FlatCAMApp.py:10763 +#: FlatCAMApp.py:11149 msgid "DXF file exported to" msgstr "Fichier DXF exporté vers" -#: FlatCAMApp.py:10769 +#: FlatCAMApp.py:11155 msgid "Exporting DXF" msgstr "Exportation DXF" -#: FlatCAMApp.py:10774 FlatCAMApp.py:10781 +#: FlatCAMApp.py:11160 FlatCAMApp.py:11167 msgid "Could not export DXF file." msgstr "Impossible d'exporter le fichier DXF." -#: FlatCAMApp.py:10804 FlatCAMApp.py:10847 flatcamTools/ToolImage.py:278 +#: FlatCAMApp.py:11190 FlatCAMApp.py:11232 flatcamTools/ToolImage.py:277 msgid "" "Not supported type is picked as parameter. Only Geometry and Gerber are " "supported" @@ -1330,81 +1288,81 @@ msgstr "" "Le type non pris en charge est sélectionné en tant que paramètre. Seuls " "Geometry et Gerber sont supportés" -#: FlatCAMApp.py:10814 +#: FlatCAMApp.py:11200 msgid "Importing SVG" msgstr "Importer du SVG" -#: FlatCAMApp.py:10825 FlatCAMApp.py:10867 FlatCAMApp.py:10926 -#: FlatCAMApp.py:10993 FlatCAMApp.py:11056 FlatCAMApp.py:11123 -#: FlatCAMApp.py:11161 flatcamTools/ToolImage.py:298 +#: FlatCAMApp.py:11211 FlatCAMApp.py:11251 FlatCAMApp.py:11309 +#: FlatCAMApp.py:11374 FlatCAMApp.py:11438 FlatCAMApp.py:11503 +#: FlatCAMApp.py:11540 flatcamTools/ToolImage.py:297 #: flatcamTools/ToolPDF.py:225 msgid "Opened" msgstr "Ouvert" -#: FlatCAMApp.py:10856 +#: FlatCAMApp.py:11241 msgid "Importing DXF" msgstr "Importation de DXF" -#: FlatCAMApp.py:10892 FlatCAMApp.py:11082 +#: FlatCAMApp.py:11275 FlatCAMApp.py:11462 msgid "Failed to open file" msgstr "Échec de l'ouverture du fichier" -#: FlatCAMApp.py:10895 FlatCAMApp.py:11085 +#: FlatCAMApp.py:11278 FlatCAMApp.py:11465 msgid "Failed to parse file" msgstr "Échec de l'analyse du fichier" -#: FlatCAMApp.py:10907 +#: FlatCAMApp.py:11290 msgid "Object is not Gerber file or empty. Aborting object creation." msgstr "" "L'objet n'est pas un fichier Gerber ou vide. Abandon de la création d'objet." -#: FlatCAMApp.py:10912 +#: FlatCAMApp.py:11295 msgid "Opening Gerber" msgstr "Ouverture Gerber" -#: FlatCAMApp.py:10919 +#: FlatCAMApp.py:11302 msgid " Open Gerber failed. Probable not a Gerber file." msgstr " Open Gerber a échoué. Probablement pas un fichier Gerber." -#: FlatCAMApp.py:10951 flatcamTools/ToolPcbWizard.py:427 +#: FlatCAMApp.py:11333 flatcamTools/ToolPcbWizard.py:425 msgid "This is not Excellon file." msgstr "Ce n'est pas un fichier Excellon." -#: FlatCAMApp.py:10955 +#: FlatCAMApp.py:11337 msgid "Cannot open file" msgstr "Ne peut pas ouvrir le fichier" -#: FlatCAMApp.py:10975 flatcamTools/ToolPDF.py:275 -#: flatcamTools/ToolPcbWizard.py:451 +#: FlatCAMApp.py:11356 flatcamTools/ToolPDF.py:275 +#: flatcamTools/ToolPcbWizard.py:447 msgid "No geometry found in file" msgstr "Aucune géométrie trouvée dans le fichier" -#: FlatCAMApp.py:10978 +#: FlatCAMApp.py:11359 msgid "Opening Excellon." msgstr "Ouverture Excellon." -#: FlatCAMApp.py:10985 +#: FlatCAMApp.py:11366 msgid "Open Excellon file failed. Probable not an Excellon file." msgstr "" "Le fichier Open Excellon a échoué. Probablement pas un fichier Excellon." -#: FlatCAMApp.py:11016 +#: FlatCAMApp.py:11398 msgid "Reading GCode file" msgstr "Lecture du fichier GCode" -#: FlatCAMApp.py:11023 +#: FlatCAMApp.py:11405 msgid "Failed to open" msgstr "Impossible d'ouvrir" -#: FlatCAMApp.py:11031 +#: FlatCAMApp.py:11413 msgid "This is not GCODE" msgstr "Ce n'est pas GCODE" -#: FlatCAMApp.py:11036 +#: FlatCAMApp.py:11418 msgid "Opening G-Code." msgstr "Ouverture G-Code." -#: FlatCAMApp.py:11045 +#: FlatCAMApp.py:11427 msgid "" "Failed to create CNCJob Object. Probable not a GCode file. Try to load it " "from File menu.\n" @@ -1416,124 +1374,104 @@ msgstr "" "La tentative de création d'un objet FlatCAM CNCJob à partir d'un fichier G-" "Code a échoué pendant le traitement" -#: FlatCAMApp.py:11104 +#: FlatCAMApp.py:11484 msgid "Object is not HPGL2 file or empty. Aborting object creation." msgstr "" "L'objet n'est pas un fichier HPGL2 ou vide. Abandon de la création d'objet." -#: FlatCAMApp.py:11109 +#: FlatCAMApp.py:11489 msgid "Opening HPGL2" msgstr "Ouverture HPGL2" -#: FlatCAMApp.py:11116 +#: FlatCAMApp.py:11496 msgid " Open HPGL2 failed. Probable not a HPGL2 file." msgstr " Open HPGL2 a échoué. Probablement pas un fichier HPGL2 ." -#: FlatCAMApp.py:11137 +#: FlatCAMApp.py:11516 msgid "Opening TCL Script..." msgstr "Ouverture du script TCL ..." -#: FlatCAMApp.py:11145 +#: FlatCAMApp.py:11524 msgid "TCL script file opened in Code Editor." msgstr "Fichier de script TCL ouvert dans l'éditeur de code." -#: FlatCAMApp.py:11148 +#: FlatCAMApp.py:11527 msgid "Failed to open TCL Script." msgstr "Impossible d'ouvrir le script TCL." -#: FlatCAMApp.py:11176 +#: FlatCAMApp.py:11555 msgid "Opening FlatCAM Config file." msgstr "Ouverture du fichier FlatCAM Config." -#: FlatCAMApp.py:11204 +#: FlatCAMApp.py:11583 msgid "Failed to open config file" msgstr "Impossible d'ouvrir le fichier de configuration" -#: FlatCAMApp.py:11230 +#: FlatCAMApp.py:11611 msgid "Loading Project ... Please Wait ..." msgstr "Chargement du projet ... Veuillez patienter ..." -#: FlatCAMApp.py:11235 +#: FlatCAMApp.py:11616 msgid "Opening FlatCAM Project file." msgstr "Ouverture du fichier de projet FlatCAM." -#: FlatCAMApp.py:11245 FlatCAMApp.py:11263 +#: FlatCAMApp.py:11626 FlatCAMApp.py:11644 msgid "Failed to open project file" msgstr "Impossible d'ouvrir le fichier de projet" -#: FlatCAMApp.py:11300 +#: FlatCAMApp.py:11681 msgid "Loading Project ... restoring" msgstr "Chargement du projet ... en cours de restauration" -#: FlatCAMApp.py:11310 +#: FlatCAMApp.py:11691 msgid "Project loaded from" msgstr "Projet chargé à partir de" -#: FlatCAMApp.py:11373 +#: FlatCAMApp.py:11760 msgid "Redrawing all objects" msgstr "Redessiner tous les objets" -#: FlatCAMApp.py:11405 -msgid "Available commands:\n" -msgstr "Commandes disponibles:\n" - -#: FlatCAMApp.py:11407 -msgid "" -"\n" -"\n" -"Type help for usage.\n" -" Example: help open_gerber" -msgstr "" -"\n" -"\n" -"Tapez help pour l'utiliser.\n" -" Exemple: help open_gerber" - -#: FlatCAMApp.py:11557 -msgid "Shows list of commands." -msgstr "Affiche la liste des commandes." - -#: FlatCAMApp.py:11619 +#: FlatCAMApp.py:11849 msgid "Failed to load recent item list." msgstr "Échec du chargement de la liste des éléments récents." -#: FlatCAMApp.py:11627 +#: FlatCAMApp.py:11856 msgid "Failed to parse recent item list." msgstr "Échec de l'analyse de la liste des éléments récents." -#: FlatCAMApp.py:11638 +#: FlatCAMApp.py:11866 msgid "Failed to load recent projects item list." msgstr "Échec du chargement de la liste d'éléments des projets récents." -#: FlatCAMApp.py:11646 +#: FlatCAMApp.py:11873 msgid "Failed to parse recent project item list." msgstr "Échec de l'analyse de la liste des éléments de projet récents." -#: FlatCAMApp.py:11706 +#: FlatCAMApp.py:11934 msgid "Clear Recent projects" msgstr "Effacer les projets récents" -#: FlatCAMApp.py:11730 +#: FlatCAMApp.py:11958 msgid "Clear Recent files" msgstr "Effacer les fichiers récents" -#: FlatCAMApp.py:11747 flatcamGUI/FlatCAMGUI.py:1276 +#: FlatCAMApp.py:11980 flatcamGUI/FlatCAMGUI.py:1348 msgid "Shortcut Key List" msgstr "Liste des touches de raccourci" -#: FlatCAMApp.py:11821 +#: FlatCAMApp.py:12054 msgid "Selected Tab - Choose an Item from Project Tab" msgstr "Onglet sélectionné - Choisissez un élément dans l'onglet Projet" -#: FlatCAMApp.py:11822 +#: FlatCAMApp.py:12055 msgid "Details" msgstr "Détails" -#: FlatCAMApp.py:11824 +#: FlatCAMApp.py:12057 msgid "The normal flow when working in FlatCAM is the following:" msgstr "Le flux normal lorsque vous travaillez dans FlatCAM est le suivant:" -#: FlatCAMApp.py:11825 +#: FlatCAMApp.py:12058 msgid "" "Load/Import a Gerber, Excellon, Gcode, DXF, Raster Image or SVG file into " "FlatCAM using either the toolbars, key shortcuts or even dragging and " @@ -1543,7 +1481,7 @@ msgstr "" "SVG dans FlatCAM à l'aide des barres d'outils, des raccourcis clavier ou " "même en glissant-déposant les fichiers sur l'interface graphique." -#: FlatCAMApp.py:11828 +#: FlatCAMApp.py:12061 msgid "" "You can also load a FlatCAM project by double clicking on the project file, " "drag and drop of the file into the FLATCAM GUI or through the menu (or " @@ -1554,7 +1492,7 @@ msgstr "" "FLATCAM ou par le biais du menu (ou de la barre d’outils) proposé dans " "l’application." -#: FlatCAMApp.py:11831 +#: FlatCAMApp.py:12064 msgid "" "Once an object is available in the Project Tab, by selecting it and then " "focusing on SELECTED TAB (more simpler is to double click the object name in " @@ -1567,7 +1505,7 @@ msgstr "" "TAB sera mis à jour avec les propriétés de l'objet en fonction de son type: " "Gerber, Excellon, géométrie ou objet CNCJob." -#: FlatCAMApp.py:11835 +#: FlatCAMApp.py:12068 msgid "" "If the selection of the object is done on the canvas by single click " "instead, and the SELECTED TAB is in focus, again the object properties will " @@ -1581,7 +1519,7 @@ msgstr "" "l'objet sur la toile pour amener l'onglet sélectionné et le renseigner même " "s'il n'était pas net." -#: FlatCAMApp.py:11839 +#: FlatCAMApp.py:12072 msgid "" "You can change the parameters in this screen and the flow direction is like " "this:" @@ -1589,7 +1527,7 @@ msgstr "" "Vous pouvez modifier les paramètres dans cet écran et le sens du flux est le " "suivant:" -#: FlatCAMApp.py:11840 +#: FlatCAMApp.py:12073 msgid "" "Gerber/Excellon Object --> Change Parameter --> Generate Geometry --> " "Geometry Object --> Add tools (change param in Selected Tab) --> Generate " @@ -1602,7 +1540,7 @@ msgstr "" "Vérifier le GCode (via Edition CNC Code) et / ou ajouter / ajouter au code " "GCode (à nouveau dans l’onglet SÉLECTIONNÉ) -> Enregistrer le code GC." -#: FlatCAMApp.py:11844 +#: FlatCAMApp.py:12077 msgid "" "A list of key shortcuts is available through an menu entry in Help --> " "Shortcuts List or through its own key shortcut: F3." @@ -1610,104 +1548,168 @@ msgstr "" "Une liste des raccourcis clavier est disponible via une entrée de menu dans " "Aide -> Liste des raccourcis ou via son propre raccourci clavier: F3." -#: FlatCAMApp.py:11906 +#: FlatCAMApp.py:12141 msgid "Failed checking for latest version. Could not connect." msgstr "" "Échec de la vérification de la dernière version. N'a pas pu se connecter." -#: FlatCAMApp.py:11914 +#: FlatCAMApp.py:12148 msgid "Could not parse information about latest version." msgstr "Impossible d'analyser les informations sur la dernière version." -#: FlatCAMApp.py:11925 +#: FlatCAMApp.py:12158 msgid "FlatCAM is up to date!" msgstr "FlatCAM est à jour!" -#: FlatCAMApp.py:11930 +#: FlatCAMApp.py:12163 msgid "Newer Version Available" msgstr "Nouvelle version disponible" -#: FlatCAMApp.py:11931 -msgid "" -"There is a newer version of FlatCAM available for download:\n" -"\n" -msgstr "" -"Une version plus récente de FlatCAM est disponible au téléchargement:\n" -"\n" +#: FlatCAMApp.py:12165 +msgid "There is a newer version of FlatCAM available for download:" +msgstr "Une version plus récente de FlatCAM est disponible au téléchargement:" -#: FlatCAMApp.py:11933 +#: FlatCAMApp.py:12169 msgid "info" msgstr "info" -#: FlatCAMApp.py:12012 +#: FlatCAMApp.py:12197 +msgid "" +"OpenGL canvas initialization failed. HW or HW configuration not supported." +"Change the graphic engine to Legacy(2D) in Edit -> Preferences -> General " +"tab.\n" +"\n" +msgstr "" +"L'initialisation du canevas OpenGL a échoué. La configuration matérielle ou " +"matérielle n'est pas prise en charge. Modifiez le moteur graphique en Hérité " +"(2D) dans Edition -> Préférences -> onglet Général.\n" +"\n" + +#: FlatCAMApp.py:12276 msgid "All plots disabled." msgstr "Toutes les parcelles désactivées." -#: FlatCAMApp.py:12019 +#: FlatCAMApp.py:12283 msgid "All non selected plots disabled." msgstr "Toutes les parcelles non sélectionnées sont désactivées." -#: FlatCAMApp.py:12026 +#: FlatCAMApp.py:12290 msgid "All plots enabled." msgstr "Toutes les parcelles activées." -#: FlatCAMApp.py:12033 +#: FlatCAMApp.py:12296 msgid "Selected plots enabled..." msgstr "Parcelles sélectionnées activées ..." -#: FlatCAMApp.py:12042 +#: FlatCAMApp.py:12304 msgid "Selected plots disabled..." msgstr "Parcelles sélectionnées désactivées ..." -#: FlatCAMApp.py:12061 +#: FlatCAMApp.py:12337 msgid "Enabling plots ..." msgstr "Activation des parcelles ..." -#: FlatCAMApp.py:12101 +#: FlatCAMApp.py:12389 msgid "Disabling plots ..." msgstr "Désactiver les parcelles ..." -#: FlatCAMApp.py:12123 +#: FlatCAMApp.py:12412 msgid "Working ..." msgstr "Travail ..." -#: FlatCAMApp.py:12224 +#: FlatCAMApp.py:12467 flatcamGUI/FlatCAMGUI.py:688 +msgid "Red" +msgstr "Rouge" + +#: FlatCAMApp.py:12469 flatcamGUI/FlatCAMGUI.py:691 +msgid "Blue" +msgstr "Bleu" + +#: FlatCAMApp.py:12472 flatcamGUI/FlatCAMGUI.py:694 +msgid "Yellow" +msgstr "Jaune" + +#: FlatCAMApp.py:12474 flatcamGUI/FlatCAMGUI.py:697 +msgid "Green" +msgstr "Vert" + +#: FlatCAMApp.py:12476 flatcamGUI/FlatCAMGUI.py:700 +msgid "Purple" +msgstr "Violet" + +#: FlatCAMApp.py:12478 flatcamGUI/FlatCAMGUI.py:703 +msgid "Brown" +msgstr "Marron" + +#: FlatCAMApp.py:12480 FlatCAMApp.py:12536 flatcamGUI/FlatCAMGUI.py:706 +msgid "White" +msgstr "Blanche" + +#: FlatCAMApp.py:12482 flatcamGUI/FlatCAMGUI.py:709 +msgid "Black" +msgstr "Noire" + +#: FlatCAMApp.py:12485 flatcamGUI/FlatCAMGUI.py:714 +msgid "Custom" +msgstr "Personnalisé" + +#: FlatCAMApp.py:12495 flatcamGUI/FlatCAMGUI.py:722 +msgid "Default" +msgstr "Défaut" + +#: FlatCAMApp.py:12519 flatcamGUI/FlatCAMGUI.py:719 +msgid "Opacity" +msgstr "Opacité" + +#: FlatCAMApp.py:12521 +msgid "Set alpha level ..." +msgstr "Définir le niveau alpha ..." + +#: FlatCAMApp.py:12521 flatcamGUI/PreferencesUI.py:6900 +#: flatcamGUI/PreferencesUI.py:8230 flatcamGUI/PreferencesUI.py:8444 +#: flatcamTools/ToolExtractDrills.py:164 flatcamTools/ToolExtractDrills.py:285 +#: flatcamTools/ToolPunchGerber.py:192 flatcamTools/ToolPunchGerber.py:308 +#: flatcamTools/ToolTransform.py:358 +msgid "Value" +msgstr "Valeur" + +#: FlatCAMApp.py:12597 msgid "Saving FlatCAM Project" msgstr "Enregistrement du projet FlatCAM" -#: FlatCAMApp.py:12243 FlatCAMApp.py:12280 +#: FlatCAMApp.py:12618 FlatCAMApp.py:12654 msgid "Project saved to" msgstr "Projet enregistré dans" -#: FlatCAMApp.py:12250 +#: FlatCAMApp.py:12625 msgid "The object is used by another application." msgstr "L'objet est utilisé par une autre application." -#: FlatCAMApp.py:12264 +#: FlatCAMApp.py:12639 msgid "Failed to verify project file" msgstr "Échec de la vérification du fichier de projet" -#: FlatCAMApp.py:12264 FlatCAMApp.py:12272 FlatCAMApp.py:12283 +#: FlatCAMApp.py:12639 FlatCAMApp.py:12647 FlatCAMApp.py:12657 msgid "Retry to save it." msgstr "Réessayez de le sauvegarder." -#: FlatCAMApp.py:12272 FlatCAMApp.py:12283 +#: FlatCAMApp.py:12647 FlatCAMApp.py:12657 msgid "Failed to parse saved project file" msgstr "Échec de l'analyse du fichier de projet enregistré" -#: FlatCAMApp.py:12398 +#: FlatCAMApp.py:13139 msgid "The user requested a graceful exit of the current task." msgstr "L'utilisateur a demandé une sortie en douceur de la tâche en cours." -#: FlatCAMCommon.py:136 FlatCAMCommon.py:163 +#: FlatCAMCommon.py:137 FlatCAMCommon.py:164 msgid "Title" msgstr "Titre" -#: FlatCAMCommon.py:137 FlatCAMCommon.py:167 +#: FlatCAMCommon.py:138 FlatCAMCommon.py:168 msgid "Web Link" msgstr "Lien Web" -#: FlatCAMCommon.py:141 +#: FlatCAMCommon.py:142 msgid "" "Index.\n" "The rows in gray color will populate the Bookmarks menu.\n" @@ -1717,7 +1719,7 @@ msgstr "" "Les lignes de couleur grise rempliront le menu Favoris.\n" "Le nombre de lignes de couleur grises est défini dans Préférences." -#: FlatCAMCommon.py:145 +#: FlatCAMCommon.py:146 msgid "" "Description of the link that is set as an menu action.\n" "Try to keep it short because it is installed as a menu item." @@ -1725,95 +1727,87 @@ msgstr "" "Description du lien défini en tant qu'action de menu.\n" "Essayez de rester bref car il est installé en tant qu'élément de menu." -#: FlatCAMCommon.py:148 +#: FlatCAMCommon.py:149 msgid "Web Link. E.g: https://your_website.org " msgstr "Lien Web. Par exemple: https://your_website.org " -#: FlatCAMCommon.py:157 +#: FlatCAMCommon.py:158 msgid "New Bookmark" msgstr "Nouveau Favori" -#: FlatCAMCommon.py:176 +#: FlatCAMCommon.py:177 msgid "Add Entry" msgstr "Ajouter une entrée" -#: FlatCAMCommon.py:177 +#: FlatCAMCommon.py:178 msgid "Remove Entry" msgstr "Supprimer l'entrée" -#: FlatCAMCommon.py:178 +#: FlatCAMCommon.py:179 msgid "Export List" msgstr "Exporter la liste" -#: FlatCAMCommon.py:179 +#: FlatCAMCommon.py:180 msgid "Import List" msgstr "Importer la liste" -#: FlatCAMCommon.py:260 +#: FlatCAMCommon.py:261 msgid "Title entry is empty." msgstr "L'entrée de titre est vide." -#: FlatCAMCommon.py:269 +#: FlatCAMCommon.py:270 msgid "Web link entry is empty." msgstr "L'entrée du lien Web est vide." -#: FlatCAMCommon.py:277 +#: FlatCAMCommon.py:278 msgid "Either the Title or the Weblink already in the table." msgstr "Soit le titre ou le lien Web déjà dans le tableau." -#: FlatCAMCommon.py:297 +#: FlatCAMCommon.py:298 msgid "Bookmark added." msgstr "Signet ajouté." -#: FlatCAMCommon.py:314 +#: FlatCAMCommon.py:315 msgid "This bookmark can not be removed" msgstr "Ce marque-page ne peut être supprimé" -#: FlatCAMCommon.py:345 +#: FlatCAMCommon.py:346 msgid "Bookmark removed." msgstr "Signet supprimé." -#: FlatCAMCommon.py:360 +#: FlatCAMCommon.py:361 msgid "Export FlatCAM Bookmarks" msgstr "Exporter les signets FlatCAM" -#: FlatCAMCommon.py:363 flatcamGUI/FlatCAMGUI.py:470 +#: FlatCAMCommon.py:364 flatcamGUI/FlatCAMGUI.py:509 msgid "Bookmarks" msgstr "Favoris" -#: FlatCAMCommon.py:370 -msgid "FlatCAM bookmarks export cancelled." -msgstr "Exportation des favoris FlatCAM annulée." - -#: FlatCAMCommon.py:389 FlatCAMCommon.py:419 +#: FlatCAMCommon.py:390 FlatCAMCommon.py:420 msgid "Could not load bookmarks file." msgstr "Impossible de charger le fichier de favoris." -#: FlatCAMCommon.py:399 +#: FlatCAMCommon.py:400 msgid "Failed to write bookmarks to file." msgstr "Échec de l'écriture des favoris dans le fichier." -#: FlatCAMCommon.py:401 +#: FlatCAMCommon.py:402 msgid "Exported bookmarks to" msgstr "Favoris exportés vers" -#: FlatCAMCommon.py:407 +#: FlatCAMCommon.py:408 msgid "Import FlatCAM Bookmarks" msgstr "Importer des favoris FlatCAM" -#: FlatCAMCommon.py:412 -msgid "FlatCAM bookmarks import cancelled." -msgstr "Importation de favoris FlatCAM annulée." - -#: FlatCAMCommon.py:426 +#: FlatCAMCommon.py:427 msgid "Imported Bookmarks from" msgstr "Favoris importés de" -#: FlatCAMCommon.py:529 +#: FlatCAMCommon.py:530 msgid "Add Geometry Tool in DB" msgstr "Ajouter un outil de géométrie dans la BD" -#: FlatCAMCommon.py:531 +#: FlatCAMCommon.py:532 FlatCAMCommon.py:2087 msgid "" "Add a new tool in the Tools Database.\n" "It will be used in the Geometry UI.\n" @@ -1823,38 +1817,38 @@ msgstr "" "Il sera utilisé dans l'interface utilisateur de géométrie.\n" "Vous pouvez le modifier après l'avoir ajouté." -#: FlatCAMCommon.py:545 +#: FlatCAMCommon.py:546 FlatCAMCommon.py:2101 msgid "Delete Tool from DB" msgstr "Supprimer l'outil de la BD" -#: FlatCAMCommon.py:547 +#: FlatCAMCommon.py:548 FlatCAMCommon.py:2103 msgid "Remove a selection of tools in the Tools Database." msgstr "Supprimez une sélection d'outils dans la base de données d'outils." -#: FlatCAMCommon.py:551 +#: FlatCAMCommon.py:552 FlatCAMCommon.py:2107 msgid "Export DB" msgstr "Exporter la BD" -#: FlatCAMCommon.py:553 +#: FlatCAMCommon.py:554 FlatCAMCommon.py:2109 msgid "Save the Tools Database to a custom text file." msgstr "" "Enregistrez la base de données d'outils dans un fichier texte personnalisé." -#: FlatCAMCommon.py:557 +#: FlatCAMCommon.py:558 FlatCAMCommon.py:2113 msgid "Import DB" msgstr "Importer une BD" -#: FlatCAMCommon.py:559 +#: FlatCAMCommon.py:560 FlatCAMCommon.py:2115 msgid "Load the Tools Database information's from a custom text file." msgstr "" "Chargez les informations de la base de données d'outils à partir d'un " "fichier texte personnalisé." -#: FlatCAMCommon.py:563 +#: FlatCAMCommon.py:564 FlatCAMCommon.py:2119 msgid "Add Tool from Tools DB" msgstr "Ajouter un outil à partir de la base de données d'outils" -#: FlatCAMCommon.py:565 +#: FlatCAMCommon.py:566 FlatCAMCommon.py:2121 msgid "" "Add a new tool in the Tools Table of the\n" "active Geometry object after selecting a tool\n" @@ -1864,135 +1858,144 @@ msgstr "" "objet Geometry actif après avoir sélectionné un outil\n" "dans la base de données des outils." -#: FlatCAMCommon.py:601 FlatCAMCommon.py:1276 +#: FlatCAMCommon.py:602 FlatCAMCommon.py:1277 FlatCAMCommon.py:1531 msgid "Tool Name" msgstr "Nom de l'outil" -#: FlatCAMCommon.py:602 FlatCAMCommon.py:1278 -#: flatcamEditors/FlatCAMExcEditor.py:1602 flatcamGUI/ObjectUI.py:1295 -#: flatcamTools/ToolNonCopperClear.py:271 flatcamTools/ToolPaint.py:176 +#: FlatCAMCommon.py:603 FlatCAMCommon.py:1279 FlatCAMCommon.py:1544 +#: flatcamEditors/FlatCAMExcEditor.py:1605 flatcamGUI/ObjectUI.py:1343 +#: flatcamGUI/ObjectUI.py:1581 flatcamGUI/PreferencesUI.py:5971 +#: flatcamTools/ToolNCC.py:278 flatcamTools/ToolNCC.py:287 +#: flatcamTools/ToolPaint.py:261 msgid "Tool Dia" msgstr "Dia. de l'outil" -#: FlatCAMCommon.py:603 FlatCAMCommon.py:1280 flatcamGUI/ObjectUI.py:1278 +#: FlatCAMCommon.py:604 FlatCAMCommon.py:1281 FlatCAMCommon.py:1725 +#: flatcamGUI/ObjectUI.py:1556 msgid "Tool Offset" msgstr "Décalage d'outil" -#: FlatCAMCommon.py:604 FlatCAMCommon.py:1282 +#: FlatCAMCommon.py:605 FlatCAMCommon.py:1283 FlatCAMCommon.py:1742 msgid "Custom Offset" msgstr "Décalage personnalisé" -#: FlatCAMCommon.py:605 FlatCAMCommon.py:1284 flatcamGUI/ObjectUI.py:304 -#: flatcamGUI/PreferencesUI.py:2217 flatcamGUI/PreferencesUI.py:5036 -#: flatcamTools/ToolNonCopperClear.py:213 +#: FlatCAMCommon.py:606 FlatCAMCommon.py:1285 FlatCAMCommon.py:1709 +#: flatcamGUI/ObjectUI.py:308 flatcamGUI/PreferencesUI.py:2397 +#: flatcamGUI/PreferencesUI.py:5332 flatcamGUI/PreferencesUI.py:5901 +#: flatcamGUI/PreferencesUI.py:5911 flatcamTools/ToolNCC.py:213 +#: flatcamTools/ToolNCC.py:227 flatcamTools/ToolPaint.py:196 msgid "Tool Type" msgstr "Type d'outil" -#: FlatCAMCommon.py:606 FlatCAMCommon.py:1286 +#: FlatCAMCommon.py:607 FlatCAMCommon.py:1287 FlatCAMCommon.py:1557 msgid "Tool Shape" msgstr "Forme d'outil" -#: FlatCAMCommon.py:607 FlatCAMCommon.py:1289 flatcamGUI/ObjectUI.py:345 -#: flatcamGUI/ObjectUI.py:820 flatcamGUI/ObjectUI.py:1405 -#: flatcamGUI/ObjectUI.py:1926 flatcamGUI/PreferencesUI.py:2257 -#: flatcamGUI/PreferencesUI.py:3082 flatcamGUI/PreferencesUI.py:3961 -#: flatcamGUI/PreferencesUI.py:5081 flatcamGUI/PreferencesUI.py:5327 -#: flatcamGUI/PreferencesUI.py:6145 flatcamTools/ToolCalculators.py:114 -#: flatcamTools/ToolCutOut.py:132 flatcamTools/ToolNonCopperClear.py:254 +#: FlatCAMCommon.py:608 FlatCAMCommon.py:1290 FlatCAMCommon.py:1573 +#: flatcamGUI/ObjectUI.py:349 flatcamGUI/ObjectUI.py:899 +#: flatcamGUI/ObjectUI.py:1701 flatcamGUI/ObjectUI.py:2254 +#: flatcamGUI/PreferencesUI.py:2437 flatcamGUI/PreferencesUI.py:3311 +#: flatcamGUI/PreferencesUI.py:4241 flatcamGUI/PreferencesUI.py:5377 +#: flatcamGUI/PreferencesUI.py:5666 flatcamGUI/PreferencesUI.py:5944 +#: flatcamGUI/PreferencesUI.py:5952 flatcamGUI/PreferencesUI.py:6635 +#: flatcamTools/ToolCalculators.py:114 flatcamTools/ToolCutOut.py:139 +#: flatcamTools/ToolNCC.py:260 flatcamTools/ToolNCC.py:268 +#: flatcamTools/ToolPaint.py:243 msgid "Cut Z" msgstr "Couper Z" -#: FlatCAMCommon.py:608 FlatCAMCommon.py:1291 +#: FlatCAMCommon.py:609 FlatCAMCommon.py:1292 FlatCAMCommon.py:1587 msgid "MultiDepth" msgstr "Multi-profondeur" -#: FlatCAMCommon.py:609 FlatCAMCommon.py:1293 +#: FlatCAMCommon.py:610 FlatCAMCommon.py:1294 FlatCAMCommon.py:1600 msgid "DPP" msgstr "DPP" -#: FlatCAMCommon.py:610 FlatCAMCommon.py:1295 +#: FlatCAMCommon.py:611 FlatCAMCommon.py:1296 FlatCAMCommon.py:1756 msgid "V-Dia" msgstr "Dia. en V" -#: FlatCAMCommon.py:611 FlatCAMCommon.py:1297 +#: FlatCAMCommon.py:612 FlatCAMCommon.py:1298 FlatCAMCommon.py:1770 msgid "V-Angle" msgstr "Angle en V" -#: FlatCAMCommon.py:612 FlatCAMCommon.py:1299 flatcamGUI/ObjectUI.py:839 -#: flatcamGUI/ObjectUI.py:1452 flatcamGUI/PreferencesUI.py:3100 -#: flatcamGUI/PreferencesUI.py:4014 flatcamGUI/PreferencesUI.py:7535 +#: FlatCAMCommon.py:613 FlatCAMCommon.py:1300 FlatCAMCommon.py:1614 +#: FlatCAMObj.py:3661 FlatCAMObj.py:5486 flatcamGUI/ObjectUI.py:945 +#: flatcamGUI/ObjectUI.py:1748 flatcamGUI/PreferencesUI.py:3352 +#: flatcamGUI/PreferencesUI.py:4294 flatcamGUI/PreferencesUI.py:8041 #: flatcamTools/ToolCalibration.py:74 msgid "Travel Z" msgstr "Voyage Z" -#: FlatCAMCommon.py:613 FlatCAMCommon.py:1301 +#: FlatCAMCommon.py:614 FlatCAMCommon.py:1302 msgid "FR" msgstr "Avance" -#: FlatCAMCommon.py:614 FlatCAMCommon.py:1303 +#: FlatCAMCommon.py:615 FlatCAMCommon.py:1304 msgid "FR Z" msgstr "Avance Z" -#: FlatCAMCommon.py:615 FlatCAMCommon.py:1305 +#: FlatCAMCommon.py:616 FlatCAMCommon.py:1306 FlatCAMCommon.py:1784 msgid "FR Rapids" msgstr "Avance Rapides" -#: FlatCAMCommon.py:616 FlatCAMCommon.py:1307 flatcamGUI/PreferencesUI.py:3173 +#: FlatCAMCommon.py:617 FlatCAMCommon.py:1308 FlatCAMCommon.py:1657 +#: flatcamGUI/PreferencesUI.py:3440 msgid "Spindle Speed" msgstr "Vitesse de broche" -#: FlatCAMCommon.py:617 FlatCAMCommon.py:1309 flatcamGUI/ObjectUI.py:963 -#: flatcamGUI/ObjectUI.py:1619 +#: FlatCAMCommon.py:618 FlatCAMCommon.py:1310 FlatCAMCommon.py:1672 +#: flatcamGUI/ObjectUI.py:1063 flatcamGUI/ObjectUI.py:1855 msgid "Dwell" msgstr "Habiter" -#: FlatCAMCommon.py:618 FlatCAMCommon.py:1311 +#: FlatCAMCommon.py:619 FlatCAMCommon.py:1312 FlatCAMCommon.py:1685 msgid "Dwelltime" msgstr "Temps d'attente" -#: FlatCAMCommon.py:619 FlatCAMCommon.py:1313 flatcamGUI/ObjectUI.py:982 -#: flatcamGUI/ObjectUI.py:1640 flatcamGUI/PreferencesUI.py:3204 -#: flatcamGUI/PreferencesUI.py:4155 flatcamGUI/PreferencesUI.py:6642 -#: flatcamTools/ToolSolderPaste.py:334 +#: FlatCAMCommon.py:620 FlatCAMCommon.py:1314 flatcamGUI/ObjectUI.py:2012 +#: flatcamGUI/PreferencesUI.py:3475 flatcamGUI/PreferencesUI.py:4447 +#: flatcamGUI/PreferencesUI.py:7148 flatcamTools/ToolSolderPaste.py:336 msgid "Preprocessor" msgstr "Post-processeur" -#: FlatCAMCommon.py:620 FlatCAMCommon.py:1315 +#: FlatCAMCommon.py:621 FlatCAMCommon.py:1316 FlatCAMCommon.py:1800 msgid "ExtraCut" msgstr "Coupe supp." -#: FlatCAMCommon.py:621 FlatCAMCommon.py:1317 +#: FlatCAMCommon.py:622 FlatCAMCommon.py:1318 FlatCAMCommon.py:1815 msgid "E-Cut Length" -msgstr "Longueur Coupe supp." +msgstr "L-Coupe supp." -#: FlatCAMCommon.py:622 FlatCAMCommon.py:1319 +#: FlatCAMCommon.py:623 FlatCAMCommon.py:1320 msgid "Toolchange" msgstr "Changement d'outil" -#: FlatCAMCommon.py:623 FlatCAMCommon.py:1321 +#: FlatCAMCommon.py:624 FlatCAMCommon.py:1322 msgid "Toolchange XY" msgstr "Changement d'outils X, Y" -#: FlatCAMCommon.py:624 FlatCAMCommon.py:1323 flatcamGUI/PreferencesUI.py:3124 -#: flatcamGUI/PreferencesUI.py:4044 flatcamGUI/PreferencesUI.py:7572 +#: FlatCAMCommon.py:625 FlatCAMCommon.py:1324 flatcamGUI/PreferencesUI.py:3378 +#: flatcamGUI/PreferencesUI.py:4324 flatcamGUI/PreferencesUI.py:8078 #: flatcamTools/ToolCalibration.py:111 msgid "Toolchange Z" msgstr "Changement d'outil Z" -#: FlatCAMCommon.py:625 FlatCAMCommon.py:1325 flatcamGUI/ObjectUI.py:886 -#: flatcamGUI/PreferencesUI.py:3309 flatcamGUI/PreferencesUI.py:4200 +#: FlatCAMCommon.py:626 FlatCAMCommon.py:1326 flatcamGUI/ObjectUI.py:1192 +#: flatcamGUI/PreferencesUI.py:3586 flatcamGUI/PreferencesUI.py:4493 msgid "Start Z" msgstr "Démarrer Z" -#: FlatCAMCommon.py:626 FlatCAMCommon.py:1328 +#: FlatCAMCommon.py:627 FlatCAMCommon.py:1329 msgid "End Z" msgstr "Fin Z" -#: FlatCAMCommon.py:630 +#: FlatCAMCommon.py:631 msgid "Tool Index." msgstr "Index d'outils." -#: FlatCAMCommon.py:632 +#: FlatCAMCommon.py:633 FlatCAMCommon.py:1533 msgid "" "Tool name.\n" "This is not used in the app, it's function\n" @@ -2002,11 +2005,11 @@ msgstr "" "Ce n'est pas utilisé dans l'application, c'est la fonction\n" "est de servir de note pour le u." -#: FlatCAMCommon.py:636 +#: FlatCAMCommon.py:637 FlatCAMCommon.py:1546 msgid "Tool Diameter." msgstr "Diamètre de l'outil." -#: FlatCAMCommon.py:638 +#: FlatCAMCommon.py:639 FlatCAMCommon.py:1727 msgid "" "Tool Offset.\n" "Can be of a few types:\n" @@ -2023,7 +2026,7 @@ msgstr "" "Personnalisé = décalage personnalisé à l'aide de la valeur de décalage " "personnalisé" -#: FlatCAMCommon.py:645 +#: FlatCAMCommon.py:646 FlatCAMCommon.py:1744 msgid "" "Custom Offset.\n" "A value to be used as offset from the current path." @@ -2031,7 +2034,7 @@ msgstr "" "Décalage personnalisé.\n" "Une valeur à utiliser comme décalage par rapport au chemin actuel." -#: FlatCAMCommon.py:648 +#: FlatCAMCommon.py:649 FlatCAMCommon.py:1711 msgid "" "Tool Type.\n" "Can be:\n" @@ -2045,7 +2048,7 @@ msgstr "" "Rugueux = coupe grossière, faible avance, passes multiples\n" "Finition = coupe de finition, avance élevée" -#: FlatCAMCommon.py:654 +#: FlatCAMCommon.py:655 FlatCAMCommon.py:1559 msgid "" "Tool Shape. \n" "Can be:\n" @@ -2059,7 +2062,7 @@ msgstr "" "B = outil de fraisage à pointe sphérique\n" "V = outil de fraisage en forme de V" -#: FlatCAMCommon.py:660 +#: FlatCAMCommon.py:661 FlatCAMCommon.py:1575 msgid "" "Cutting Depth.\n" "The depth at which to cut into material." @@ -2067,7 +2070,7 @@ msgstr "" "Profondeur de coupe.\n" "La profondeur à laquelle couper en matériau." -#: FlatCAMCommon.py:663 +#: FlatCAMCommon.py:664 FlatCAMCommon.py:1589 msgid "" "Multi Depth.\n" "Selecting this will allow cutting in multiple passes,\n" @@ -2078,7 +2081,7 @@ msgstr "" "chaque passe en ajoutant une profondeur de paramètre DPP (profondeur par " "passe)." -#: FlatCAMCommon.py:667 +#: FlatCAMCommon.py:668 FlatCAMCommon.py:1602 msgid "" "DPP. Depth per Pass.\n" "The value used to cut into material on each pass." @@ -2086,7 +2089,7 @@ msgstr "" "DPP. Profondeur par passe.\n" "La valeur utilisée pour couper le matériau à chaque passage." -#: FlatCAMCommon.py:670 +#: FlatCAMCommon.py:671 FlatCAMCommon.py:1758 msgid "" "V-Dia.\n" "Diameter of the tip for V-Shape Tools." @@ -2094,7 +2097,7 @@ msgstr "" "Diamètre en V.\n" "Diamètre de la pointe pour les outils en forme de V." -#: FlatCAMCommon.py:673 +#: FlatCAMCommon.py:674 FlatCAMCommon.py:1772 msgid "" "V-Agle.\n" "Angle at the tip for the V-Shape Tools." @@ -2102,7 +2105,7 @@ msgstr "" "V-Agle.\n" "Angle à la pointe pour les outils en forme de V." -#: FlatCAMCommon.py:676 +#: FlatCAMCommon.py:677 FlatCAMCommon.py:1616 msgid "" "Clearance Height.\n" "Height at which the milling bit will travel between cuts,\n" @@ -2112,7 +2115,7 @@ msgstr "" "Hauteur à laquelle la fraise se déplacera entre les coupes,\n" "au-dessus de la surface du matériau, en évitant tous les luminaires." -#: FlatCAMCommon.py:680 +#: FlatCAMCommon.py:681 msgid "" "FR. Feedrate\n" "The speed on XY plane used while cutting into material." @@ -2120,7 +2123,7 @@ msgstr "" "FR. Vitesse d'avance\n" "La vitesse sur le plan XY utilisée lors de la découpe du matériau." -#: FlatCAMCommon.py:683 +#: FlatCAMCommon.py:684 msgid "" "FR Z. Feedrate Z\n" "The speed on Z plane." @@ -2128,7 +2131,7 @@ msgstr "" "FR Z. Avance Z\n" "La vitesse sur le plan Z." -#: FlatCAMCommon.py:686 +#: FlatCAMCommon.py:687 FlatCAMCommon.py:1786 msgid "" "FR Rapids. Feedrate Rapids\n" "Speed used while moving as fast as possible.\n" @@ -2141,7 +2144,7 @@ msgstr "" "utiliser\n" "la commande G0 g-code. Principalement des imprimantes 3D." -#: FlatCAMCommon.py:691 +#: FlatCAMCommon.py:692 FlatCAMCommon.py:1659 msgid "" "Spindle Speed.\n" "If it's left empty it will not be used.\n" @@ -2151,7 +2154,7 @@ msgstr "" "S'il est laissé vide, il ne sera pas utilisé.\n" "La vitesse du moteur en tr / min." -#: FlatCAMCommon.py:695 +#: FlatCAMCommon.py:696 FlatCAMCommon.py:1674 msgid "" "Dwell.\n" "Check this if a delay is needed to allow\n" @@ -2161,7 +2164,7 @@ msgstr "" "Cochez cette case si un délai est nécessaire pour permettre\n" "le moteur pour atteindre sa vitesse définie." -#: FlatCAMCommon.py:699 +#: FlatCAMCommon.py:700 FlatCAMCommon.py:1687 msgid "" "Dwell Time.\n" "A delay used to allow the motor spindle reach it's set speed." @@ -2169,7 +2172,7 @@ msgstr "" "Temps d'attente.\n" "Un délai utilisé pour permettre au moteur d'atteindre sa vitesse définie." -#: FlatCAMCommon.py:702 +#: FlatCAMCommon.py:703 msgid "" "Preprocessor.\n" "A selection of files that will alter the generated G-code\n" @@ -2179,7 +2182,7 @@ msgstr "" "Une sélection de fichiers qui modifieront le G-code généré\n" "pour s'adapter à un certain nombre de cas d'utilisation." -#: FlatCAMCommon.py:706 +#: FlatCAMCommon.py:707 FlatCAMCommon.py:1802 msgid "" "Extra Cut.\n" "If checked, after a isolation is finished an extra cut\n" @@ -2193,7 +2196,7 @@ msgstr "" "tel que ce point est couvert par cette coupe supplémentaire\n" "assurer une isolation complète." -#: FlatCAMCommon.py:712 +#: FlatCAMCommon.py:713 FlatCAMCommon.py:1817 msgid "" "Extra Cut length.\n" "If checked, after a isolation is finished an extra cut\n" @@ -2209,7 +2212,7 @@ msgstr "" "assurer une isolation complète. C'est la longueur de\n" "la coupe supplémentaire." -#: FlatCAMCommon.py:719 +#: FlatCAMCommon.py:720 msgid "" "Toolchange.\n" "It will create a toolchange event.\n" @@ -2221,7 +2224,7 @@ msgstr "" "Le type de changement d'outils est déterminé par\n" "le fichier du préprocesseur." -#: FlatCAMCommon.py:724 +#: FlatCAMCommon.py:725 msgid "" "Toolchange XY.\n" "A set of coordinates in the format (x, y).\n" @@ -2233,7 +2236,7 @@ msgstr "" "Déterminera la position cartésienne du point\n" "où l'événement de changement d'outil a lieu." -#: FlatCAMCommon.py:729 +#: FlatCAMCommon.py:730 msgid "" "Toolchange Z.\n" "The position on Z plane where the tool change event take place." @@ -2241,7 +2244,7 @@ msgstr "" "Changement d'outil Z.\n" "La position sur le plan Z où l'événement de changement d'outil a lieu." -#: FlatCAMCommon.py:732 +#: FlatCAMCommon.py:733 msgid "" "Start Z.\n" "If it's left empty it will not be used.\n" @@ -2252,7 +2255,7 @@ msgstr "" "Une position sur le plan Z pour se déplacer immédiatement après le début du " "travail." -#: FlatCAMCommon.py:736 +#: FlatCAMCommon.py:737 msgid "" "End Z.\n" "A position on Z plane to move immediately after job stop." @@ -2261,352 +2264,731 @@ msgstr "" "Une position sur le plan Z pour se déplacer immédiatement après l'arrêt du " "travail." -#: FlatCAMCommon.py:748 FlatCAMCommon.py:1125 FlatCAMCommon.py:1159 +#: FlatCAMCommon.py:749 FlatCAMCommon.py:1126 FlatCAMCommon.py:1160 +#: FlatCAMCommon.py:2335 FlatCAMCommon.py:2556 FlatCAMCommon.py:2590 msgid "Could not load Tools DB file." msgstr "Impossible de charger le fichier BD des outils." -#: FlatCAMCommon.py:756 FlatCAMCommon.py:1167 +#: FlatCAMCommon.py:757 FlatCAMCommon.py:1168 FlatCAMCommon.py:2343 +#: FlatCAMCommon.py:2598 msgid "Failed to parse Tools DB file." msgstr "Échec de l'analyse du fichier BD des outils." -#: FlatCAMCommon.py:759 FlatCAMCommon.py:1170 +#: FlatCAMCommon.py:760 FlatCAMCommon.py:1171 FlatCAMCommon.py:2346 +#: FlatCAMCommon.py:2601 msgid "Loaded FlatCAM Tools DB from" msgstr "Base de données des outils FlatCAM chargée depuis" -#: FlatCAMCommon.py:765 +#: FlatCAMCommon.py:766 FlatCAMCommon.py:2260 msgid "Add to DB" msgstr "Ajouter à la BD" -#: FlatCAMCommon.py:767 +#: FlatCAMCommon.py:768 FlatCAMCommon.py:2263 msgid "Copy from DB" msgstr "Copier depuis BD" -#: FlatCAMCommon.py:769 +#: FlatCAMCommon.py:770 FlatCAMCommon.py:2266 msgid "Delete from DB" msgstr "Supprimer de la BD" -#: FlatCAMCommon.py:1046 +#: FlatCAMCommon.py:1047 FlatCAMCommon.py:2473 msgid "Tool added to DB." msgstr "Outil ajouté à BD." -#: FlatCAMCommon.py:1067 +#: FlatCAMCommon.py:1068 FlatCAMCommon.py:2497 msgid "Tool copied from Tools DB." msgstr "Outil copié à partir de la BD d'outils." -#: FlatCAMCommon.py:1085 +#: FlatCAMCommon.py:1086 FlatCAMCommon.py:2516 msgid "Tool removed from Tools DB." msgstr "Outil supprimé de la BD d'outils." -#: FlatCAMCommon.py:1096 +#: FlatCAMCommon.py:1097 FlatCAMCommon.py:2527 msgid "Export Tools Database" msgstr "Exporter la BD des outils" -#: FlatCAMCommon.py:1099 +#: FlatCAMCommon.py:1100 FlatCAMCommon.py:2530 msgid "Tools_Database" msgstr "Base de données d'outils" -#: FlatCAMCommon.py:1106 -msgid "FlatCAM Tools DB export cancelled." -msgstr "Exportation de la base de données des outils FlatCAM annulée." - -#: FlatCAMCommon.py:1136 FlatCAMCommon.py:1139 FlatCAMCommon.py:1191 +#: FlatCAMCommon.py:1137 FlatCAMCommon.py:1140 FlatCAMCommon.py:1192 +#: FlatCAMCommon.py:2567 FlatCAMCommon.py:2570 FlatCAMCommon.py:2622 msgid "Failed to write Tools DB to file." msgstr "Échec de l'écriture de la base de données des outils dans le fichier." -#: FlatCAMCommon.py:1142 +#: FlatCAMCommon.py:1143 FlatCAMCommon.py:2573 msgid "Exported Tools DB to" msgstr "Base de données d'outils exportée vers" -#: FlatCAMCommon.py:1149 +#: FlatCAMCommon.py:1150 FlatCAMCommon.py:2580 msgid "Import FlatCAM Tools DB" msgstr "Importer la BD des outils FlatCAM" -#: FlatCAMCommon.py:1152 -msgid "FlatCAM Tools DB import cancelled." -msgstr "Importation de la BD des outils FlatCAM annulée." - -#: FlatCAMCommon.py:1195 +#: FlatCAMCommon.py:1196 FlatCAMCommon.py:2626 msgid "Saved Tools DB." msgstr "Sauvegarde de la BD des outils." -#: FlatCAMCommon.py:1342 +#: FlatCAMCommon.py:1343 FlatCAMCommon.py:2807 msgid "No Tool/row selected in the Tools Database table" msgstr "Aucun outil / ligne sélectionné dans le tableau de la BD d'outils" -#: FlatCAMCommon.py:1360 +#: FlatCAMCommon.py:1361 FlatCAMCommon.py:2824 msgid "Cancelled adding tool from DB." msgstr "Outil d'ajout de la BD annulé." -#: FlatCAMObj.py:257 +#: FlatCAMCommon.py:1462 +msgid "Basic Geo Parameters" +msgstr "Paramètres Geo de base" + +#: FlatCAMCommon.py:1474 +msgid "Advanced Geo Parameters" +msgstr "Paramètres Geo avancés" + +#: FlatCAMCommon.py:1486 +msgid "NCC Parameters" +msgstr "Paramètres NCC" + +#: FlatCAMCommon.py:1498 +msgid "Paint Parameters" +msgstr "Paramètres de Peindre" + +#: FlatCAMCommon.py:1629 flatcamGUI/ObjectUI.py:966 flatcamGUI/ObjectUI.py:1767 +#: flatcamGUI/PreferencesUI.py:4378 flatcamGUI/PreferencesUI.py:7059 +#: flatcamTools/ToolSolderPaste.py:254 +msgid "Feedrate X-Y" +msgstr "Avance X-Y" + +#: FlatCAMCommon.py:1631 +msgid "" +"Feedrate X-Y. Feedrate\n" +"The speed on XY plane used while cutting into material." +msgstr "" +"Avance X-Y. Vitesse d'avance\n" +"La vitesse sur le plan XY utilisée lors de la découpe du matériau." + +#: FlatCAMCommon.py:1643 flatcamGUI/ObjectUI.py:981 flatcamGUI/ObjectUI.py:1781 +#: flatcamGUI/PreferencesUI.py:3425 flatcamGUI/PreferencesUI.py:4393 +#: flatcamGUI/PreferencesUI.py:7072 flatcamTools/ToolSolderPaste.py:266 +msgid "Feedrate Z" +msgstr "Avance Z" + +#: FlatCAMCommon.py:1645 +msgid "" +"Feedrate Z\n" +"The speed on Z plane." +msgstr "" +"Avance Z\n" +"La vitesse sur l'avion Z." + +#: FlatCAMCommon.py:1843 flatcamGUI/ObjectUI.py:844 +#: flatcamGUI/PreferencesUI.py:3264 flatcamTools/ToolNCC.py:341 +msgid "Operation" +msgstr "Opération" + +#: FlatCAMCommon.py:1845 flatcamTools/ToolNCC.py:343 +msgid "" +"The 'Operation' can be:\n" +"- Isolation -> will ensure that the non-copper clearing is always complete.\n" +"If it's not successful then the non-copper clearing will fail, too.\n" +"- Clear -> the regular non-copper clearing." +msgstr "" +"L'opération peut être:\n" +"- Isolement -> veillera à ce que la clairance sans cuivre soit toujours " +"complète.\n" +"Si cela ne réussit pas, alors le clearing sans cuivre échouera aussi.\n" +"- Clair -> le clearing régulier sans cuivre." + +#: FlatCAMCommon.py:1852 flatcamEditors/FlatCAMGrbEditor.py:2739 +#: flatcamGUI/GUIElements.py:2577 flatcamTools/ToolNCC.py:350 +msgid "Clear" +msgstr "Effacer" + +#: FlatCAMCommon.py:1853 flatcamTools/ToolNCC.py:351 +#: flatcamTools/ToolNCC.py:1618 +msgid "Isolation" +msgstr "Isolement" + +#: FlatCAMCommon.py:1861 flatcamGUI/ObjectUI.py:408 flatcamGUI/ObjectUI.py:866 +#: flatcamGUI/PreferencesUI.py:2257 flatcamGUI/PreferencesUI.py:3280 +#: flatcamGUI/PreferencesUI.py:4665 flatcamGUI/PreferencesUI.py:5416 +#: flatcamTools/ToolNCC.py:359 +msgid "Milling Type" +msgstr "Type de fraisage" + +#: FlatCAMCommon.py:1863 FlatCAMCommon.py:1871 flatcamGUI/PreferencesUI.py:5418 +#: flatcamGUI/PreferencesUI.py:5426 flatcamTools/ToolNCC.py:361 +#: flatcamTools/ToolNCC.py:369 +msgid "" +"Milling type when the selected tool is of type: 'iso_op':\n" +"- climb / best for precision milling and to reduce tool usage\n" +"- conventional / useful when there is no backlash compensation" +msgstr "" +"Type de fraisage lorsque l'outil sélectionné est de type: 'iso_op':\n" +"- montée / idéal pour le fraisage de précision et pour réduire l'utilisation " +"d'outils\n" +"- conventionnel / utile quand il n'y a pas de compensation de jeu" + +#: FlatCAMCommon.py:1868 flatcamGUI/ObjectUI.py:414 +#: flatcamGUI/PreferencesUI.py:2264 flatcamGUI/PreferencesUI.py:4671 +#: flatcamGUI/PreferencesUI.py:5423 flatcamTools/ToolNCC.py:366 +msgid "Climb" +msgstr "Monté" + +#: FlatCAMCommon.py:1869 flatcamGUI/ObjectUI.py:415 +#: flatcamGUI/PreferencesUI.py:2265 flatcamGUI/PreferencesUI.py:4672 +#: flatcamGUI/PreferencesUI.py:5424 flatcamTools/ToolNCC.py:367 +msgid "Conventional" +msgstr "Conventionnel" + +#: FlatCAMCommon.py:1881 FlatCAMCommon.py:1990 +#: flatcamEditors/FlatCAMGeoEditor.py:452 flatcamGUI/PreferencesUI.py:5461 +#: flatcamGUI/PreferencesUI.py:6002 flatcamTools/ToolNCC.py:382 +#: flatcamTools/ToolPaint.py:329 +msgid "Overlap" +msgstr "Chevauchement" + +#: FlatCAMCommon.py:1883 flatcamGUI/PreferencesUI.py:5463 +#: flatcamTools/ToolNCC.py:384 +msgid "" +"How much (percentage) of the tool width to overlap each tool pass.\n" +"Adjust the value starting with lower values\n" +"and increasing it if areas that should be cleared are still \n" +"not cleared.\n" +"Lower values = faster processing, faster execution on CNC.\n" +"Higher values = slow processing and slow execution on CNC\n" +"due of too many paths." +msgstr "" +"La quantité (pourcentage) de la largeur d'outil qui chevauche chaque passe " +"d'outil.\n" +"Ajustez la valeur en commençant par des valeurs inférieures\n" +"et l'augmenter si les zones qui doivent être nettoyées sont encore\n" +"pas effacé.\n" +"Valeurs inférieures = traitement plus rapide, exécution plus rapide sur " +"CNC.\n" +"Valeurs supérieures = traitement lent et exécution lente sur CNC\n" +"en raison de trop de chemins." + +#: FlatCAMCommon.py:1902 FlatCAMCommon.py:2011 +#: flatcamEditors/FlatCAMGeoEditor.py:472 flatcamGUI/PreferencesUI.py:5481 +#: flatcamGUI/PreferencesUI.py:5723 flatcamGUI/PreferencesUI.py:6022 +#: flatcamGUI/PreferencesUI.py:7681 flatcamGUI/PreferencesUI.py:7838 +#: flatcamGUI/PreferencesUI.py:7923 flatcamGUI/PreferencesUI.py:8570 +#: flatcamGUI/PreferencesUI.py:8578 flatcamTools/ToolCopperThieving.py:112 +#: flatcamTools/ToolCopperThieving.py:363 flatcamTools/ToolCutOut.py:191 +#: flatcamTools/ToolFiducials.py:172 flatcamTools/ToolInvertGerber.py:88 +#: flatcamTools/ToolInvertGerber.py:96 flatcamTools/ToolNCC.py:403 +#: flatcamTools/ToolPaint.py:350 +msgid "Margin" +msgstr "Marge" + +#: FlatCAMCommon.py:1904 flatcamGUI/PreferencesUI.py:5483 +#: flatcamGUI/PreferencesUI.py:7683 flatcamGUI/PreferencesUI.py:7925 +#: flatcamGUI/PreferencesUI.py:7989 flatcamTools/ToolCopperThieving.py:114 +#: flatcamTools/ToolFiducials.py:174 flatcamTools/ToolFiducials.py:237 +#: flatcamTools/ToolNCC.py:405 +msgid "Bounding box margin." +msgstr "Marge du cadre de sélection." + +#: FlatCAMCommon.py:1915 FlatCAMCommon.py:2026 +#: flatcamEditors/FlatCAMGeoEditor.py:486 flatcamGUI/PreferencesUI.py:5494 +#: flatcamGUI/PreferencesUI.py:6037 flatcamGUI/PreferencesUI.py:8204 +#: flatcamGUI/PreferencesUI.py:8417 flatcamTools/ToolExtractDrills.py:128 +#: flatcamTools/ToolNCC.py:416 flatcamTools/ToolPaint.py:365 +#: flatcamTools/ToolPunchGerber.py:139 +msgid "Method" +msgstr "Méthode" + +#: FlatCAMCommon.py:1917 flatcamGUI/PreferencesUI.py:5496 +#: flatcamTools/ToolNCC.py:418 +msgid "" +"Algorithm for copper clearing:\n" +"- Standard: Fixed step inwards.\n" +"- Seed-based: Outwards from seed.\n" +"- Line-based: Parallel lines." +msgstr "" +"Algorithme de compensation du cuivre:\n" +"- Standard: pas fixe vers l'intérieur.\n" +"- À base de graines: à l'extérieur des graines.\n" +"- Ligne: lignes parallèles." + +#: FlatCAMCommon.py:1925 FlatCAMCommon.py:2040 +#: flatcamEditors/FlatCAMGeoEditor.py:500 flatcamGUI/PreferencesUI.py:5509 +#: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 +#: flatcamTools/ToolNCC.py:2390 flatcamTools/ToolNCC.py:2419 +#: flatcamTools/ToolNCC.py:2688 flatcamTools/ToolNCC.py:2720 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:1829 +#: tclCommands/TclCommandCopperClear.py:126 +#: tclCommands/TclCommandCopperClear.py:134 tclCommands/TclCommandPaint.py:125 +msgid "Standard" +msgstr "La norme" + +#: FlatCAMCommon.py:1925 FlatCAMCommon.py:2040 +#: flatcamEditors/FlatCAMGeoEditor.py:500 +#: flatcamEditors/FlatCAMGeoEditor.py:5156 flatcamGUI/PreferencesUI.py:5509 +#: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:699 +#: flatcamTools/ToolPaint.py:1857 tclCommands/TclCommandCopperClear.py:130 +#: tclCommands/TclCommandPaint.py:129 +msgid "Lines" +msgstr "Lignes" + +#: FlatCAMCommon.py:1933 FlatCAMCommon.py:2051 flatcamGUI/PreferencesUI.py:5516 +#: flatcamGUI/PreferencesUI.py:6063 flatcamTools/ToolNCC.py:439 +#: flatcamTools/ToolPaint.py:401 +msgid "Connect" +msgstr "Relier" + +#: FlatCAMCommon.py:1937 FlatCAMCommon.py:2054 +#: flatcamEditors/FlatCAMGeoEditor.py:509 flatcamGUI/PreferencesUI.py:5518 +#: flatcamGUI/PreferencesUI.py:6065 flatcamTools/ToolNCC.py:443 +#: flatcamTools/ToolPaint.py:404 +msgid "" +"Draw lines between resulting\n" +"segments to minimize tool lifts." +msgstr "" +"Tracez des lignes entre les résultats\n" +"segments pour minimiser les montées d’outil." + +#: FlatCAMCommon.py:1943 FlatCAMCommon.py:2058 flatcamGUI/PreferencesUI.py:5525 +#: flatcamGUI/PreferencesUI.py:6071 flatcamTools/ToolNCC.py:449 +#: flatcamTools/ToolPaint.py:408 +msgid "Contour" +msgstr "Contour" + +#: FlatCAMCommon.py:1947 FlatCAMCommon.py:2061 +#: flatcamEditors/FlatCAMGeoEditor.py:519 flatcamGUI/PreferencesUI.py:5527 +#: flatcamGUI/PreferencesUI.py:6073 flatcamTools/ToolNCC.py:453 +#: flatcamTools/ToolPaint.py:411 +msgid "" +"Cut around the perimeter of the polygon\n" +"to trim rough edges." +msgstr "" +"Couper autour du périmètre du polygone\n" +"pour couper les bords rugueux." + +#: FlatCAMCommon.py:1953 flatcamEditors/FlatCAMGeoEditor.py:613 +#: flatcamEditors/FlatCAMGrbEditor.py:5145 flatcamGUI/ObjectUI.py:142 +#: flatcamGUI/ObjectUI.py:1495 flatcamGUI/ObjectUI.py:2244 +#: flatcamGUI/PreferencesUI.py:5534 flatcamGUI/PreferencesUI.py:6822 +#: flatcamTools/ToolNCC.py:459 flatcamTools/ToolTransform.py:29 +msgid "Offset" +msgstr "Décalage" + +#: FlatCAMCommon.py:1957 flatcamGUI/PreferencesUI.py:5536 +#: flatcamTools/ToolNCC.py:463 +msgid "" +"If used, it will add an offset to the copper features.\n" +"The copper clearing will finish to a distance\n" +"from the copper features.\n" +"The value can be between 0 and 10 FlatCAM units." +msgstr "" +"S'il est utilisé, cela ajoutera un décalage aux entités en cuivre.\n" +"La clairière de cuivre finira à distance\n" +"des caractéristiques de cuivre.\n" +"La valeur peut être comprise entre 0 et 10 unités FlatCAM." + +#: FlatCAMCommon.py:1992 flatcamEditors/FlatCAMGeoEditor.py:454 +#: flatcamGUI/PreferencesUI.py:6004 flatcamTools/ToolPaint.py:331 +msgid "" +"How much (percentage) of the tool width to overlap each tool pass.\n" +"Adjust the value starting with lower values\n" +"and increasing it if areas that should be painted are still \n" +"not painted.\n" +"Lower values = faster processing, faster execution on CNC.\n" +"Higher values = slow processing and slow execution on CNC\n" +"due of too many paths." +msgstr "" +"La quantité (pourcentage) de la largeur d'outil qui chevauche chaque passe " +"d'outil.\n" +"Ajustez la valeur en commençant par des valeurs inférieures\n" +"et l'augmenter si les zones à peindre sont encore\n" +"pas peint.\n" +"Valeurs inférieures = traitement plus rapide, exécution plus rapide sur " +"CNC.\n" +"Valeurs supérieures = traitement lent et exécution lente sur CNC\n" +"en raison de trop de chemins." + +#: FlatCAMCommon.py:2013 flatcamEditors/FlatCAMGeoEditor.py:474 +#: flatcamGUI/PreferencesUI.py:6024 flatcamTools/ToolPaint.py:352 +msgid "" +"Distance by which to avoid\n" +"the edges of the polygon to\n" +"be painted." +msgstr "" +"Distance à éviter\n" +"les bords du polygone à\n" +"être peint." + +#: FlatCAMCommon.py:2028 flatcamGUI/PreferencesUI.py:6039 +#: flatcamTools/ToolPaint.py:367 +msgid "" +"Algorithm for painting:\n" +"- Standard: Fixed step inwards.\n" +"- Seed-based: Outwards from seed.\n" +"- Line-based: Parallel lines.\n" +"- Laser-lines: Active only for Gerber objects.\n" +"Will create lines that follow the traces.\n" +"- Combo: In case of failure a new method will be picked from the above\n" +"in the order specified." +msgstr "" +"Algorithme de peinture:\n" +"- Standard: pas fixe vers l'intérieur.\n" +"- À base de graines: à l'extérieur des graines.\n" +"- Ligne: lignes parallèles.\n" +"- Lignes laser: Actif uniquement pour les objets Gerber.\n" +"Créera des lignes qui suivent les traces.\n" +"- Combo: En cas d'échec, une nouvelle méthode sera choisie parmi les " +"précédentes\n" +"dans l'ordre spécifié." + +#: FlatCAMCommon.py:2040 FlatCAMCommon.py:2042 flatcamGUI/PreferencesUI.py:6056 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:392 +#: flatcamTools/ToolPaint.py:693 flatcamTools/ToolPaint.py:698 +#: flatcamTools/ToolPaint.py:1871 tclCommands/TclCommandPaint.py:131 +msgid "Laser_lines" +msgstr "Lignes_laser" + +#: FlatCAMCommon.py:2040 flatcamGUI/PreferencesUI.py:6056 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:2022 +#: tclCommands/TclCommandPaint.py:133 +msgid "Combo" +msgstr "Combo" + +#: FlatCAMCommon.py:2085 +msgid "Add Tool in DB" +msgstr "Ajouter un Outil dans la BD" + +#: FlatCAMObj.py:264 msgid "Name changed from" msgstr "Nom changé de" -#: FlatCAMObj.py:257 +#: FlatCAMObj.py:264 msgid "to" msgstr "à" -#: FlatCAMObj.py:268 +#: FlatCAMObj.py:275 msgid "Offsetting..." msgstr "Compenser ..." -#: FlatCAMObj.py:282 FlatCAMObj.py:287 +#: FlatCAMObj.py:289 FlatCAMObj.py:294 msgid "Scaling could not be executed." msgstr "La mise à l'échelle n'a pas pu être exécutée." -#: FlatCAMObj.py:291 FlatCAMObj.py:299 +#: FlatCAMObj.py:298 FlatCAMObj.py:306 msgid "Scale done." msgstr "Échelle terminée." -#: FlatCAMObj.py:297 +#: FlatCAMObj.py:304 msgid "Scaling..." msgstr "Mise à l'échelle..." -#: FlatCAMObj.py:315 +#: FlatCAMObj.py:322 msgid "Skewing..." msgstr "Fausser..." -#: FlatCAMObj.py:736 FlatCAMObj.py:2746 FlatCAMObj.py:3968 -#: flatcamGUI/PreferencesUI.py:1470 flatcamGUI/PreferencesUI.py:2859 +#: FlatCAMObj.py:743 FlatCAMObj.py:831 flatcamGUI/ObjectUI.py:449 +#: flatcamGUI/PreferencesUI.py:6527 flatcamTools/ToolAlignObjects.py:73 +#: flatcamTools/ToolAlignObjects.py:109 flatcamTools/ToolCalibration.py:196 +#: flatcamTools/ToolCalibration.py:631 flatcamTools/ToolCalibration.py:648 +#: flatcamTools/ToolCalibration.py:807 flatcamTools/ToolCalibration.py:815 +#: flatcamTools/ToolCopperThieving.py:145 +#: flatcamTools/ToolCopperThieving.py:159 +#: flatcamTools/ToolCopperThieving.py:605 flatcamTools/ToolCutOut.py:92 +#: flatcamTools/ToolDblSided.py:225 flatcamTools/ToolFilm.py:69 +#: flatcamTools/ToolFilm.py:102 flatcamTools/ToolFilm.py:549 +#: flatcamTools/ToolFilm.py:557 flatcamTools/ToolImage.py:49 +#: flatcamTools/ToolImage.py:252 flatcamTools/ToolImage.py:273 +#: flatcamTools/ToolNCC.py:96 flatcamTools/ToolNCC.py:558 +#: flatcamTools/ToolNCC.py:1295 flatcamTools/ToolPaint.py:502 +#: flatcamTools/ToolPaint.py:706 flatcamTools/ToolPanelize.py:118 +#: flatcamTools/ToolPanelize.py:204 flatcamTools/ToolPanelize.py:374 +#: flatcamTools/ToolPanelize.py:391 +msgid "Gerber" +msgstr "Gerber" + +#: FlatCAMObj.py:743 FlatCAMObj.py:831 flatcamGUI/FlatCAMGUI.py:2154 +#: flatcamGUI/ObjectUI.py:449 flatcamTools/ToolCalibration.py:631 +#: flatcamTools/ToolCalibration.py:648 flatcamTools/ToolCalibration.py:815 +#: flatcamTools/ToolCopperThieving.py:145 +#: flatcamTools/ToolCopperThieving.py:159 +#: flatcamTools/ToolCopperThieving.py:605 flatcamTools/ToolCutOut.py:93 +#: flatcamTools/ToolDblSided.py:227 flatcamTools/ToolFilm.py:69 +#: flatcamTools/ToolFilm.py:102 flatcamTools/ToolFilm.py:549 +#: flatcamTools/ToolFilm.py:557 flatcamTools/ToolImage.py:49 +#: flatcamTools/ToolImage.py:271 flatcamTools/ToolNCC.py:95 +#: flatcamTools/ToolNCC.py:558 flatcamTools/ToolNCC.py:1295 +#: flatcamTools/ToolPaint.py:502 flatcamTools/ToolPaint.py:706 +#: flatcamTools/ToolPanelize.py:118 flatcamTools/ToolPanelize.py:374 +#: flatcamTools/ToolPanelize.py:391 +msgid "Geometry" +msgstr "Géométrie" + +#: FlatCAMObj.py:755 FlatCAMObj.py:2957 FlatCAMObj.py:4421 +#: flatcamGUI/PreferencesUI.py:1646 flatcamGUI/PreferencesUI.py:3041 msgid "Basic" msgstr "De base" -#: FlatCAMObj.py:763 FlatCAMObj.py:2758 FlatCAMObj.py:3989 -#: flatcamGUI/PreferencesUI.py:1471 +#: FlatCAMObj.py:782 FlatCAMObj.py:2970 FlatCAMObj.py:4442 +#: flatcamGUI/PreferencesUI.py:1647 msgid "Advanced" msgstr "Avancé" -#: FlatCAMObj.py:980 +#: FlatCAMObj.py:998 msgid "Buffering solid geometry" msgstr "Mise en tampon de la géométrie solide" -#: FlatCAMObj.py:983 camlib.py:965 flatcamGUI/PreferencesUI.py:2296 -#: flatcamTools/ToolCopperThieving.py:1011 -#: flatcamTools/ToolCopperThieving.py:1200 -#: flatcamTools/ToolCopperThieving.py:1212 -#: flatcamTools/ToolNonCopperClear.py:1624 -#: flatcamTools/ToolNonCopperClear.py:1721 -#: flatcamTools/ToolNonCopperClear.py:1732 -#: flatcamTools/ToolNonCopperClear.py:2015 -#: flatcamTools/ToolNonCopperClear.py:2111 -#: flatcamTools/ToolNonCopperClear.py:2123 +#: FlatCAMObj.py:1001 camlib.py:979 flatcamGUI/PreferencesUI.py:2476 +#: flatcamTools/ToolCopperThieving.py:1017 +#: flatcamTools/ToolCopperThieving.py:1206 +#: flatcamTools/ToolCopperThieving.py:1218 flatcamTools/ToolNCC.py:2045 +#: flatcamTools/ToolNCC.py:2153 flatcamTools/ToolNCC.py:2167 +#: flatcamTools/ToolNCC.py:3098 flatcamTools/ToolNCC.py:3203 +#: flatcamTools/ToolNCC.py:3218 flatcamTools/ToolNCC.py:3484 +#: flatcamTools/ToolNCC.py:3585 flatcamTools/ToolNCC.py:3600 msgid "Buffering" msgstr "Mise en mémoire tampon" -#: FlatCAMObj.py:989 +#: FlatCAMObj.py:1007 msgid "Done" msgstr "Terminé" -#: FlatCAMObj.py:1040 +#: FlatCAMObj.py:1032 FlatCAMObj.py:1058 +msgid "Operation could not be done." +msgstr "L'opération n'a pas pu être effectuée." + +#: FlatCAMObj.py:1075 msgid "Isolating..." msgstr "Isoler ..." -#: FlatCAMObj.py:1099 +#: FlatCAMObj.py:1134 msgid "Click on a polygon to isolate it." msgstr "Cliquez sur un polygone pour l'isoler." -#: FlatCAMObj.py:1138 FlatCAMObj.py:1243 flatcamTools/ToolPaint.py:1120 +#: FlatCAMObj.py:1173 FlatCAMObj.py:1277 flatcamTools/ToolPaint.py:1511 msgid "Added polygon" msgstr "Polygone ajouté" -#: FlatCAMObj.py:1140 FlatCAMObj.py:1245 +#: FlatCAMObj.py:1174 FlatCAMObj.py:1279 msgid "Click to add next polygon or right click to start isolation." msgstr "" "Cliquez pour ajouter le polygone suivant ou cliquez avec le bouton droit " "pour démarrer l'isolement." -#: FlatCAMObj.py:1152 flatcamTools/ToolPaint.py:1134 +#: FlatCAMObj.py:1186 flatcamTools/ToolPaint.py:1525 msgid "Removed polygon" msgstr "Polygone supprimé" -#: FlatCAMObj.py:1153 +#: FlatCAMObj.py:1187 msgid "Click to add/remove next polygon or right click to start isolation." msgstr "" "Cliquez pour ajouter / supprimer le polygone suivant ou cliquez avec le " "bouton droit pour démarrer l'isolement." -#: FlatCAMObj.py:1158 flatcamTools/ToolPaint.py:1140 +#: FlatCAMObj.py:1192 flatcamTools/ToolPaint.py:1531 msgid "No polygon detected under click position." msgstr "Aucun polygone détecté sous la position du clic." -#: FlatCAMObj.py:1179 flatcamTools/ToolPaint.py:1169 +#: FlatCAMObj.py:1213 flatcamTools/ToolPaint.py:1560 msgid "List of single polygons is empty. Aborting." msgstr "La liste des polygones simples est vide. Abandon." -#: FlatCAMObj.py:1248 +#: FlatCAMObj.py:1282 msgid "No polygon in selection." msgstr "Aucun polygone dans la sélection." -#: FlatCAMObj.py:1324 FlatCAMObj.py:1457 -#: flatcamTools/ToolNonCopperClear.py:1653 -#: flatcamTools/ToolNonCopperClear.py:2039 -msgid "Isolation geometry could not be generated." -msgstr "La géométrie d'isolation n'a pas pu être générée." - -#: FlatCAMObj.py:1374 FlatCAMObj.py:3637 FlatCAMObj.py:3922 FlatCAMObj.py:4221 +#: FlatCAMObj.py:1394 FlatCAMObj.py:1542 FlatCAMObj.py:4055 FlatCAMObj.py:4375 +#: FlatCAMObj.py:4762 msgid "Rough" msgstr "Rugueux" -#: FlatCAMObj.py:1400 FlatCAMObj.py:1480 +#: FlatCAMObj.py:1410 FlatCAMObj.py:1489 flatcamTools/ToolNCC.py:2081 +#: flatcamTools/ToolNCC.py:3132 flatcamTools/ToolNCC.py:3511 +msgid "Isolation geometry could not be generated." +msgstr "La géométrie d'isolation n'a pas pu être générée." + +#: FlatCAMObj.py:1435 FlatCAMObj.py:1567 msgid "Isolation geometry created" msgstr "Géométrie d'isolement créée" -#: FlatCAMObj.py:1409 FlatCAMObj.py:1487 +#: FlatCAMObj.py:1444 FlatCAMObj.py:1574 msgid "Subtracting Geo" msgstr "Soustraction Geo" -#: FlatCAMObj.py:1807 +#: FlatCAMObj.py:1899 msgid "Plotting Apertures" msgstr "Traçage des ouvertures" -#: FlatCAMObj.py:2573 flatcamEditors/FlatCAMExcEditor.py:2427 +#: FlatCAMObj.py:2753 flatcamEditors/FlatCAMExcEditor.py:2453 msgid "Total Drills" msgstr "Total Forage" -#: FlatCAMObj.py:2605 flatcamEditors/FlatCAMExcEditor.py:2459 +#: FlatCAMObj.py:2784 flatcamEditors/FlatCAMExcEditor.py:2485 msgid "Total Slots" msgstr "Total de Fentes" -#: FlatCAMObj.py:3060 FlatCAMObj.py:3155 FlatCAMObj.py:3276 +#: FlatCAMObj.py:2857 FlatCAMObj.py:3069 FlatCAMObj.py:3085 FlatCAMObj.py:3089 +#: FlatCAMObj.py:4242 FlatCAMObj.py:4667 FlatCAMObj.py:4703 +#: flatcamGUI/ObjectUI.py:817 flatcamGUI/ObjectUI.py:1660 +#: flatcamTools/ToolNCC.py:331 flatcamTools/ToolNCC.py:797 +#: flatcamTools/ToolNCC.py:811 flatcamTools/ToolNCC.py:1191 +#: flatcamTools/ToolPaint.py:314 flatcamTools/ToolPaint.py:767 +#: flatcamTools/ToolPaint.py:779 flatcamTools/ToolPaint.py:1166 +msgid "Parameters for" +msgstr "Paramètres pour" + +#: FlatCAMObj.py:2857 FlatCAMObj.py:3089 FlatCAMObj.py:4242 FlatCAMObj.py:4703 +#: flatcamTools/ToolNCC.py:811 flatcamTools/ToolNCC.py:1191 +#: flatcamTools/ToolPaint.py:779 flatcamTools/ToolPaint.py:1166 +msgid "Multiple Tools" +msgstr "Outils multiples" + +#: FlatCAMObj.py:3069 +msgid "No Tool Selected" +msgstr "Aucun Outil sélectionné" + +#: FlatCAMObj.py:3085 FlatCAMObj.py:3427 FlatCAMObj.py:4667 +#: flatcamEditors/FlatCAMGeoEditor.py:406 flatcamGUI/FlatCAMGUI.py:496 +#: flatcamGUI/FlatCAMGUI.py:1143 flatcamGUI/ObjectUI.py:817 +#: flatcamGUI/ObjectUI.py:1660 flatcamTools/ToolNCC.py:331 +#: flatcamTools/ToolNCC.py:797 flatcamTools/ToolPaint.py:314 +#: flatcamTools/ToolPaint.py:767 +msgid "Tool" +msgstr "Outil" + +#: FlatCAMObj.py:3419 FlatCAMObj.py:3512 FlatCAMObj.py:3700 msgid "Please select one or more tools from the list and try again." msgstr "" "Veuillez sélectionner un ou plusieurs outils dans la liste et réessayer." -#: FlatCAMObj.py:3067 +#: FlatCAMObj.py:3426 msgid "Milling tool for DRILLS is larger than hole size. Cancelled." msgstr "" "L'outil de fraisage pour PERÇAGES est supérieur à la taille du trou. Annulé." -#: FlatCAMObj.py:3068 FlatCAMObj.py:4533 flatcamEditors/FlatCAMGeoEditor.py:408 -#: flatcamGUI/FlatCAMGUI.py:457 flatcamGUI/FlatCAMGUI.py:1072 -#: flatcamGUI/ObjectUI.py:1353 -msgid "Tool" -msgstr "Outil" - -#: FlatCAMObj.py:3084 FlatCAMObj.py:3177 FlatCAMObj.py:3295 +#: FlatCAMObj.py:3442 FlatCAMObj.py:3533 FlatCAMObj.py:3719 +#: tclCommands/TclCommandDrillcncjob.py:194 msgid "Tool_nr" msgstr "Numéro d'outil" -#: FlatCAMObj.py:3084 FlatCAMObj.py:3177 FlatCAMObj.py:3295 -#: flatcamEditors/FlatCAMExcEditor.py:1582 -#: flatcamEditors/FlatCAMExcEditor.py:3048 flatcamGUI/ObjectUI.py:777 -#: flatcamTools/ToolNonCopperClear.py:120 flatcamTools/ToolPaint.py:123 -#: flatcamTools/ToolPcbWizard.py:76 flatcamTools/ToolProperties.py:396 -#: flatcamTools/ToolProperties.py:449 flatcamTools/ToolSolderPaste.py:84 +#: FlatCAMObj.py:3442 FlatCAMObj.py:3533 FlatCAMObj.py:3719 +#: flatcamEditors/FlatCAMExcEditor.py:1585 +#: flatcamEditors/FlatCAMExcEditor.py:3069 flatcamGUI/ObjectUI.py:780 +#: flatcamTools/ToolNCC.py:132 flatcamTools/ToolPaint.py:128 +#: flatcamTools/ToolPcbWizard.py:76 flatcamTools/ToolProperties.py:416 +#: flatcamTools/ToolProperties.py:476 flatcamTools/ToolSolderPaste.py:86 +#: tclCommands/TclCommandDrillcncjob.py:194 msgid "Diameter" msgstr "Diamètre" -#: FlatCAMObj.py:3084 FlatCAMObj.py:3177 FlatCAMObj.py:3295 +#: FlatCAMObj.py:3442 FlatCAMObj.py:3533 FlatCAMObj.py:3719 +#: tclCommands/TclCommandDrillcncjob.py:194 msgid "Drills_Nr" msgstr "Forets Nr" -#: FlatCAMObj.py:3084 FlatCAMObj.py:3177 FlatCAMObj.py:3295 +#: FlatCAMObj.py:3442 FlatCAMObj.py:3533 FlatCAMObj.py:3719 +#: tclCommands/TclCommandDrillcncjob.py:194 msgid "Slots_Nr" msgstr "Fentes Nr" -#: FlatCAMObj.py:3164 +#: FlatCAMObj.py:3521 msgid "Milling tool for SLOTS is larger than hole size. Cancelled." msgstr "" "L'outil de fraisage pour FENTES est supérieur à la taille du trou. Annulé." -#: FlatCAMObj.py:3336 -msgid "" -"Wrong value format for self.defaults[\"z_pdepth\"] or self.options[\"z_pdepth" -"\"]" -msgstr "" -"Format de valeur incorrect pour self.defaults [\"z_pdepth\"] ou self.options " -"[\"z_pdepth\"]" +#: FlatCAMObj.py:3626 FlatCAMObj.py:5451 +msgid "Focus Z" +msgstr "Focus Z" -#: FlatCAMObj.py:3347 -msgid "" -"Wrong value format for self.defaults[\"feedrate_probe\"] or self." -"options[\"feedrate_probe\"]" -msgstr "" -"Format de valeur incorrect pour self.defaults [\"feedrate_probe\"] ou self." -"options [\"feedrate_probe\"]" +#: FlatCAMObj.py:3645 FlatCAMObj.py:5470 +msgid "Laser Power" +msgstr "Puissance laser" -#: FlatCAMObj.py:3377 FlatCAMObj.py:5354 FlatCAMObj.py:5358 FlatCAMObj.py:5493 +#: FlatCAMObj.py:3677 FlatCAMObj.py:5502 flatcamGUI/ObjectUI.py:1048 +#: flatcamGUI/ObjectUI.py:1839 flatcamGUI/PreferencesUI.py:4409 +msgid "Spindle speed" +msgstr "Vitesse de broche" + +#: FlatCAMObj.py:3776 FlatCAMObj.py:5911 FlatCAMObj.py:5915 FlatCAMObj.py:6060 msgid "Generating CNC Code" msgstr "Génération de code CNC" -#: FlatCAMObj.py:3637 FlatCAMObj.py:4632 FlatCAMObj.py:4633 FlatCAMObj.py:4642 +#: FlatCAMObj.py:3966 flatcamTools/ToolNCC.py:918 flatcamTools/ToolPaint.py:844 +msgid "Current Tool parameters were applied to all tools." +msgstr "Les paramètres d'outil actuels ont été appliqués à tous les outils." + +#: FlatCAMObj.py:4055 FlatCAMObj.py:5115 FlatCAMObj.py:5116 FlatCAMObj.py:5125 msgid "Iso" msgstr "Iso" -#: FlatCAMObj.py:3637 +#: FlatCAMObj.py:4055 msgid "Finish" msgstr "Finition" -#: FlatCAMObj.py:3957 +#: FlatCAMObj.py:4410 msgid "Add from Tool DB" msgstr "Ajouter à partir de la BD d'outils" -#: FlatCAMObj.py:3960 flatcamGUI/FlatCAMGUI.py:678 flatcamGUI/FlatCAMGUI.py:794 -#: flatcamGUI/FlatCAMGUI.py:989 flatcamGUI/FlatCAMGUI.py:2015 -#: flatcamGUI/FlatCAMGUI.py:2159 flatcamGUI/FlatCAMGUI.py:2378 -#: flatcamGUI/FlatCAMGUI.py:2557 flatcamGUI/ObjectUI.py:1324 -#: flatcamTools/ToolPanelize.py:534 flatcamTools/ToolPanelize.py:561 -#: flatcamTools/ToolPanelize.py:660 flatcamTools/ToolPanelize.py:694 -#: flatcamTools/ToolPanelize.py:759 +#: FlatCAMObj.py:4413 flatcamGUI/FlatCAMGUI.py:734 flatcamGUI/FlatCAMGUI.py:848 +#: flatcamGUI/FlatCAMGUI.py:1057 flatcamGUI/FlatCAMGUI.py:2123 +#: flatcamGUI/FlatCAMGUI.py:2267 flatcamGUI/FlatCAMGUI.py:2532 +#: flatcamGUI/FlatCAMGUI.py:2731 flatcamGUI/ObjectUI.py:1615 +#: flatcamTools/ToolPanelize.py:543 flatcamTools/ToolPanelize.py:570 +#: flatcamTools/ToolPanelize.py:669 flatcamTools/ToolPanelize.py:703 +#: flatcamTools/ToolPanelize.py:768 msgid "Copy" msgstr "Copie" -#: FlatCAMObj.py:4054 FlatCAMObj.py:4397 FlatCAMObj.py:5107 FlatCAMObj.py:5744 -#: flatcamEditors/FlatCAMExcEditor.py:2534 -#: flatcamEditors/FlatCAMGeoEditor.py:1078 -#: flatcamEditors/FlatCAMGeoEditor.py:1112 -#: flatcamEditors/FlatCAMGeoEditor.py:1133 -#: flatcamEditors/FlatCAMGeoEditor.py:1154 -#: flatcamEditors/FlatCAMGeoEditor.py:1191 -#: flatcamEditors/FlatCAMGeoEditor.py:1219 -#: flatcamEditors/FlatCAMGeoEditor.py:1240 -#: flatcamTools/ToolNonCopperClear.py:1052 -#: flatcamTools/ToolNonCopperClear.py:1461 flatcamTools/ToolPaint.py:835 -#: flatcamTools/ToolPaint.py:1019 flatcamTools/ToolPaint.py:2198 -#: flatcamTools/ToolSolderPaste.py:882 flatcamTools/ToolSolderPaste.py:957 +#: FlatCAMObj.py:4507 FlatCAMObj.py:4941 FlatCAMObj.py:5661 FlatCAMObj.py:6307 +#: flatcamEditors/FlatCAMExcEditor.py:2560 +#: flatcamEditors/FlatCAMGeoEditor.py:1077 +#: flatcamEditors/FlatCAMGeoEditor.py:1118 +#: flatcamEditors/FlatCAMGeoEditor.py:1146 +#: flatcamEditors/FlatCAMGeoEditor.py:1174 +#: flatcamEditors/FlatCAMGeoEditor.py:1218 +#: flatcamEditors/FlatCAMGeoEditor.py:1253 +#: flatcamEditors/FlatCAMGeoEditor.py:1281 flatcamTools/ToolNCC.py:1493 +#: flatcamTools/ToolPaint.py:1244 flatcamTools/ToolPaint.py:1415 +#: flatcamTools/ToolSolderPaste.py:883 flatcamTools/ToolSolderPaste.py:956 msgid "Wrong value format entered, use a number." msgstr "Mauvais format de valeur entré, utilisez un nombre." -#: FlatCAMObj.py:4240 +#: FlatCAMObj.py:4781 msgid "Tool added in Tool Table." msgstr "Outil ajouté dans la table d'outils." -#: FlatCAMObj.py:4347 FlatCAMObj.py:4356 +#: FlatCAMObj.py:4890 FlatCAMObj.py:4899 msgid "Failed. Select a tool to copy." msgstr "Échoué. Sélectionnez un outil à copier." -#: FlatCAMObj.py:4383 +#: FlatCAMObj.py:4928 msgid "Tool was copied in Tool Table." msgstr "L'outil a été copié dans la table d'outils." -#: FlatCAMObj.py:4411 +#: FlatCAMObj.py:4955 msgid "Tool was edited in Tool Table." msgstr "L'outil a été édité dans Tool Table." -#: FlatCAMObj.py:4440 FlatCAMObj.py:4449 +#: FlatCAMObj.py:4984 FlatCAMObj.py:4993 msgid "Failed. Select a tool to delete." msgstr "Échoué. Sélectionnez un outil à supprimer." -#: FlatCAMObj.py:4472 +#: FlatCAMObj.py:5017 msgid "Tool was deleted in Tool Table." msgstr "L'outil a été supprimé dans la table d'outils." -#: FlatCAMObj.py:4533 flatcamGUI/ObjectUI.py:1353 -msgid "Parameters for" -msgstr "Paramètres pour" - -#: FlatCAMObj.py:4967 +#: FlatCAMObj.py:5523 msgid "This Geometry can't be processed because it is" msgstr "Cette géométrie ne peut pas être traitée car elle est" -#: FlatCAMObj.py:4969 +#: FlatCAMObj.py:5523 msgid "geometry" msgstr "geometry" -#: FlatCAMObj.py:5012 +#: FlatCAMObj.py:5564 msgid "Failed. No tool selected in the tool table ..." msgstr "Échoué. Aucun outil sélectionné dans la table d'outils ..." -#: FlatCAMObj.py:5112 FlatCAMObj.py:5264 +#: FlatCAMObj.py:5667 FlatCAMObj.py:5820 msgid "" "Tool Offset is selected in Tool Table but no value is provided.\n" "Add a Tool Offset or change the Offset Type." @@ -2615,44 +2997,44 @@ msgstr "" "n’est fournie.\n" "Ajoutez un décalage d'outil ou changez le type de décalage." -#: FlatCAMObj.py:5177 FlatCAMObj.py:5325 +#: FlatCAMObj.py:5733 FlatCAMObj.py:5882 msgid "G-Code parsing in progress..." msgstr "Analyse du code G en cours ..." -#: FlatCAMObj.py:5179 FlatCAMObj.py:5327 +#: FlatCAMObj.py:5735 FlatCAMObj.py:5884 msgid "G-Code parsing finished..." msgstr "L'analyse du code G est terminée ..." -#: FlatCAMObj.py:5187 +#: FlatCAMObj.py:5743 msgid "Finished G-Code processing" msgstr "Traitement du code G terminé" -#: FlatCAMObj.py:5189 FlatCAMObj.py:5339 +#: FlatCAMObj.py:5745 FlatCAMObj.py:5896 msgid "G-Code processing failed with error" msgstr "Le traitement du code G a échoué avec une erreur" -#: FlatCAMObj.py:5234 flatcamTools/ToolSolderPaste.py:1303 +#: FlatCAMObj.py:5790 flatcamTools/ToolSolderPaste.py:1300 msgid "Cancelled. Empty file, it has no geometry" msgstr "Annulé. Fichier vide, il n'a pas de géométrie" -#: FlatCAMObj.py:5337 FlatCAMObj.py:5486 +#: FlatCAMObj.py:5894 FlatCAMObj.py:6055 msgid "Finished G-Code processing..." msgstr "Traitement terminé du code G ..." -#: FlatCAMObj.py:5356 FlatCAMObj.py:5360 FlatCAMObj.py:5496 +#: FlatCAMObj.py:5913 FlatCAMObj.py:5917 FlatCAMObj.py:6062 msgid "CNCjob created" msgstr "CNCjob créé" -#: FlatCAMObj.py:5527 FlatCAMObj.py:5536 flatcamParsers/ParseGerber.py:1794 -#: flatcamParsers/ParseGerber.py:1804 +#: FlatCAMObj.py:6092 FlatCAMObj.py:6101 flatcamParsers/ParseGerber.py:1866 +#: flatcamParsers/ParseGerber.py:1876 msgid "Scale factor has to be a number: integer or float." msgstr "Le facteur d'échelle doit être un nombre: entier ou réel." -#: FlatCAMObj.py:5600 +#: FlatCAMObj.py:6164 msgid "Geometry Scale done." msgstr "Échelle de géométrie terminée." -#: FlatCAMObj.py:5617 flatcamParsers/ParseGerber.py:1920 +#: FlatCAMObj.py:6181 flatcamParsers/ParseGerber.py:1992 msgid "" "An (x,y) pair of values are needed. Probable you entered only one value in " "the Offset field." @@ -2660,11 +3042,11 @@ msgstr "" "Une paire de valeurs (x, y) est nécessaire. Vous avez probablement entré une " "seule valeur dans le champ Décalage." -#: FlatCAMObj.py:5674 +#: FlatCAMObj.py:6237 msgid "Geometry Offset done." msgstr "Décalage de géométrie effectué." -#: FlatCAMObj.py:5703 +#: FlatCAMObj.py:6266 msgid "" "The Toolchange X,Y field in Edit -> Preferences has to be in the format (x, " "y)\n" @@ -2674,43 +3056,43 @@ msgstr "" "y)\n" "mais maintenant il n'y a qu'une seule valeur, pas deux." -#: FlatCAMObj.py:6388 FlatCAMObj.py:7175 FlatCAMObj.py:7371 +#: FlatCAMObj.py:6956 FlatCAMObj.py:7802 FlatCAMObj.py:7999 msgid "Basic" msgstr "De base" -#: FlatCAMObj.py:6394 FlatCAMObj.py:7179 FlatCAMObj.py:7375 +#: FlatCAMObj.py:6962 FlatCAMObj.py:7806 FlatCAMObj.py:8003 msgid "Advanced" msgstr "Avancé" -#: FlatCAMObj.py:6437 +#: FlatCAMObj.py:7005 msgid "Plotting..." msgstr "Traçage..." -#: FlatCAMObj.py:6460 FlatCAMObj.py:6465 flatcamTools/ToolSolderPaste.py:1509 +#: FlatCAMObj.py:7034 FlatCAMObj.py:7039 flatcamTools/ToolSolderPaste.py:1498 msgid "Export Machine Code ..." msgstr "Exporter le code machine ..." -#: FlatCAMObj.py:6470 flatcamTools/ToolSolderPaste.py:1513 +#: FlatCAMObj.py:7044 flatcamTools/ToolSolderPaste.py:1502 msgid "Export Machine Code cancelled ..." msgstr "Exporter le code machine annulé ..." -#: FlatCAMObj.py:6492 +#: FlatCAMObj.py:7065 msgid "Machine Code file saved to" msgstr "Fichier de code machine enregistré dans" -#: FlatCAMObj.py:6546 flatcamTools/ToolCalibration.py:1083 +#: FlatCAMObj.py:7126 flatcamTools/ToolCalibration.py:1097 msgid "Loaded Machine Code into Code Editor" msgstr "Code machine chargé dans l'éditeur de code" -#: FlatCAMObj.py:6684 +#: FlatCAMObj.py:7265 msgid "This CNCJob object can't be processed because it is a" msgstr "Cet objet CNCJob ne peut pas être traité car il est" -#: FlatCAMObj.py:6686 +#: FlatCAMObj.py:7267 msgid "CNCJob object" msgstr "Objet CNCJob" -#: FlatCAMObj.py:6866 +#: FlatCAMObj.py:7447 msgid "" "G-code does not have a G94 code and we will not include the code in the " "'Prepend to GCode' text box" @@ -2718,39 +3100,39 @@ msgstr "" "Le code G n'a pas de code G94 et nous n'inclurons pas le code dans la zone " "de texte 'Prepend to GCode'" -#: FlatCAMObj.py:6877 +#: FlatCAMObj.py:7458 msgid "Cancelled. The Toolchange Custom code is enabled but it's empty." msgstr "Annulé. Le code personnalisé Toolchange est activé mais vide." -#: FlatCAMObj.py:6882 +#: FlatCAMObj.py:7463 msgid "Toolchange G-code was replaced by a custom code." msgstr "Toolchange G-code a été remplacé par un code personnalisé." -#: FlatCAMObj.py:6899 flatcamEditors/FlatCAMTextEditor.py:270 -#: flatcamTools/ToolSolderPaste.py:1540 +#: FlatCAMObj.py:7480 flatcamEditors/FlatCAMTextEditor.py:272 +#: flatcamTools/ToolSolderPaste.py:1529 msgid "No such file or directory" msgstr "Aucun fichier ou répertoire de ce nom" -#: FlatCAMObj.py:6913 flatcamEditors/FlatCAMTextEditor.py:282 +#: FlatCAMObj.py:7494 flatcamEditors/FlatCAMTextEditor.py:284 msgid "Saved to" msgstr "Enregistré dans" -#: FlatCAMObj.py:6923 FlatCAMObj.py:6933 +#: FlatCAMObj.py:7511 FlatCAMObj.py:7521 msgid "" "The used preprocessor file has to have in it's name: 'toolchange_custom'" msgstr "" "Le fichier de post-traitement utilisé doit avoir pour nom: " "'toolchange_custom'" -#: FlatCAMObj.py:6937 +#: FlatCAMObj.py:7524 msgid "There is no preprocessor file." msgstr "Il n'y a pas de fichier de post-processeur." -#: FlatCAMObj.py:7194 +#: FlatCAMObj.py:7821 msgid "Script Editor" msgstr "Éditeur de script" -#: FlatCAMObj.py:7475 +#: FlatCAMObj.py:8103 msgid "Document Editor" msgstr "Éditeur de Document" @@ -2758,6 +3140,16 @@ msgstr "Éditeur de Document" msgid "processes running." msgstr "processus en cours d'exécution." +#: FlatCAMTool.py:245 FlatCAMTool.py:252 flatcamGUI/ObjectUI.py:156 +#: flatcamGUI/ObjectUI.py:163 +msgid "Edited value is out of range" +msgstr "La valeur modifiée est hors limites" + +#: FlatCAMTool.py:247 FlatCAMTool.py:254 flatcamGUI/ObjectUI.py:158 +#: flatcamGUI/ObjectUI.py:165 +msgid "Edited value is within limits." +msgstr "La valeur modifiée est dans les limites." + #: FlatCAMTranslation.py:103 msgid "The application will restart." msgstr "L'application va redémarrer." @@ -2770,68 +3162,68 @@ msgstr "Etes-vous sûr de vouloir changer la langue actuelle en" msgid "Apply Language ..." msgstr "Appliquer la langue ..." -#: ObjectCollection.py:459 +#: ObjectCollection.py:506 #, python-brace-format msgid "Object renamed from {old} to {new}" msgstr "Objet renommé de {old} à {new}" -#: ObjectCollection.py:858 +#: ObjectCollection.py:972 msgid "Cause of error" msgstr "Cause d'erreur" -#: camlib.py:590 +#: camlib.py:593 msgid "self.solid_geometry is neither BaseGeometry or list." msgstr "self.solid_geometry n'est ni BaseGeometry ni une liste." -#: camlib.py:953 +#: camlib.py:968 msgid "Pass" msgstr "Passer" -#: camlib.py:974 +#: camlib.py:988 msgid "Get Exteriors" msgstr "Obtenez des extérieurs" -#: camlib.py:977 +#: camlib.py:991 msgid "Get Interiors" msgstr "Obtenez des intérieurs" -#: camlib.py:1964 +#: camlib.py:2172 msgid "Object was mirrored" msgstr "L'objet a été reflété" -#: camlib.py:1967 +#: camlib.py:2175 msgid "Failed to mirror. No object selected" msgstr "Impossible de refléter. Aucun objet sélectionné" -#: camlib.py:2036 +#: camlib.py:2244 msgid "Object was rotated" msgstr "L'objet a été tourné" -#: camlib.py:2039 +#: camlib.py:2247 msgid "Failed to rotate. No object selected" msgstr "Échec de la rotation. Aucun objet sélectionné" -#: camlib.py:2107 +#: camlib.py:2314 msgid "Object was skewed" msgstr "L'objet était de biaiser" -#: camlib.py:2110 +#: camlib.py:2317 msgid "Failed to skew. No object selected" msgstr "Impossible de biaiser. Aucun objet sélectionné" -#: camlib.py:2179 +#: camlib.py:2392 msgid "Object was buffered" msgstr "L'objet a été tamponnées" -#: camlib.py:2181 +#: camlib.py:2394 msgid "Failed to buffer. No object selected" msgstr "Échec de la mise en buffer. Aucun objet sélectionné" -#: camlib.py:2378 +#: camlib.py:2599 msgid "There is no such parameter" msgstr "Il n'y a pas de tel paramètre" -#: camlib.py:2454 +#: camlib.py:2659 camlib.py:2892 camlib.py:3121 camlib.py:3343 msgid "" "The Cut Z parameter has positive value. It is the depth value to drill into " "material.\n" @@ -2845,11 +3237,12 @@ msgstr "" "s'agisse d'une faute de frappe; par conséquent, l'application convertira la " "valeur en valeur négative. Vérifiez le code CNC résultant (Gcode, etc.)." -#: camlib.py:2462 camlib.py:3181 camlib.py:3539 +#: camlib.py:2667 camlib.py:2902 camlib.py:3131 camlib.py:3353 camlib.py:3639 +#: camlib.py:4008 msgid "The Cut Z parameter is zero. There will be no cut, skipping file" msgstr "Le paramètre Cut Z est zéro. Il n'y aura pas de fichier coupé, sautant" -#: camlib.py:2475 camlib.py:3512 +#: camlib.py:2678 camlib.py:3976 msgid "" "The Toolchange X,Y field in Edit -> Preferences has to be in the format (x, " "y) \n" @@ -2859,31 +3252,39 @@ msgstr "" "y)\n" "mais maintenant il n'y a qu'une seule valeur, pas deux. " -#: camlib.py:2550 +#: camlib.py:2687 camlib.py:3590 camlib.py:3958 +msgid "" +"The End Move X,Y field in Edit -> Preferences has to be in the format (x, y) " +"but now there is only one value, not two." +msgstr "" +"Le champ Fin du déplacement X, Y dans Edition -> Préférences doit être au " +"format (x, y) mais maintenant il n'y a qu'une seule valeur, pas deux." + +#: camlib.py:2775 msgid "Creating a list of points to drill..." msgstr "Création d'une liste de points à explorer ..." -#: camlib.py:2632 +#: camlib.py:2865 camlib.py:3737 camlib.py:4112 msgid "Starting G-Code" msgstr "Démarrer le GCode" -#: camlib.py:2727 camlib.py:2870 camlib.py:2972 camlib.py:3292 camlib.py:3653 +#: camlib.py:3006 camlib.py:3225 camlib.py:3389 camlib.py:3750 camlib.py:4123 msgid "Starting G-Code for tool with diameter" msgstr "Code G de départ pour outil avec diamètre" -#: camlib.py:2783 camlib.py:2926 camlib.py:3029 +#: camlib.py:3089 camlib.py:3307 camlib.py:3475 msgid "G91 coordinates not implemented" msgstr "Coordonnées G91 non implémentées" -#: camlib.py:2789 camlib.py:2933 camlib.py:3035 +#: camlib.py:3095 camlib.py:3314 camlib.py:3481 msgid "The loaded Excellon file has no drills" msgstr "Le fichier Excellon chargé n'a pas d'exercices" -#: camlib.py:3058 +#: camlib.py:3504 msgid "Finished G-Code generation..." msgstr "Fini la génération de code G ..." -#: camlib.py:3153 +#: camlib.py:3608 msgid "" "The Toolchange X,Y field in Edit -> Preferences has to be in the format (x, " "y) \n" @@ -2893,7 +3294,7 @@ msgstr "" "y)\n" "mais maintenant il n'y a qu'une seule valeur, pas deux." -#: camlib.py:3166 camlib.py:3525 +#: camlib.py:3622 camlib.py:3991 msgid "" "Cut_Z parameter is None or zero. Most likely a bad combinations of other " "parameters." @@ -2901,7 +3302,7 @@ msgstr "" "Le paramètre Cut_Z est Aucun ou zéro. Très probablement une mauvaise " "combinaison d'autres paramètres." -#: camlib.py:3173 camlib.py:3531 +#: camlib.py:3631 camlib.py:4000 msgid "" "The Cut Z parameter has positive value. It is the depth value to cut into " "material.\n" @@ -2915,11 +3316,11 @@ msgstr "" "s'agisse d'une faute de frappe. Par conséquent, l'application convertira la " "valeur en valeur négative. Vérifiez le code CNC résultant (Gcode, etc.)." -#: camlib.py:3186 camlib.py:3545 +#: camlib.py:3644 camlib.py:4014 msgid "Travel Z parameter is None or zero." msgstr "Le paramètre Voyage Z est Aucun ou zéro." -#: camlib.py:3191 camlib.py:3550 +#: camlib.py:3649 camlib.py:4019 msgid "" "The Travel Z parameter has negative value. It is the height value to travel " "between cuts.\n" @@ -2933,38 +3334,34 @@ msgstr "" "s'agisse d'une faute de frappe. Par conséquent, l'application convertira la " "valeur en valeur positive. Vérifiez le code CNC résultant (Gcode, etc.)." -#: camlib.py:3199 camlib.py:3558 +#: camlib.py:3657 camlib.py:4027 msgid "The Z Travel parameter is zero. This is dangerous, skipping file" msgstr "Le paramètre Z voyage est zéro. Ceci est dangereux, ignorer le fichier" -#: camlib.py:3218 camlib.py:3580 +#: camlib.py:3676 camlib.py:4050 msgid "Indexing geometry before generating G-Code..." msgstr "Indexer la géométrie avant de générer le code G ..." -#: camlib.py:3279 camlib.py:3642 -msgid "Starting G-Code..." -msgstr "Démarrer G-Code ..." - -#: camlib.py:3362 camlib.py:3724 +#: camlib.py:3820 camlib.py:4192 msgid "Finished G-Code generation" msgstr "Génération de code G terminée" -#: camlib.py:3364 +#: camlib.py:3820 msgid "paths traced" msgstr "chemins tracés" -#: camlib.py:3399 +#: camlib.py:3853 msgid "Expected a Geometry, got" msgstr "Attendait une géométrie, eu" -#: camlib.py:3406 +#: camlib.py:3860 msgid "" "Trying to generate a CNC Job from a Geometry object without solid_geometry." msgstr "" "Essayer de générer un travail CNC à partir d'un objet de géométrie sans " "solid_geometry." -#: camlib.py:3446 +#: camlib.py:3901 msgid "" "The Tool Offset value is too negative to use for the current_geometry.\n" "Raise the value (in module) and try again." @@ -2973,35 +3370,35 @@ msgstr "" "utilisée pour current_geometry.\n" "Augmentez la valeur (dans le module) et essayez à nouveau." -#: camlib.py:3724 +#: camlib.py:4192 msgid " paths traced." msgstr " chemins tracés." -#: camlib.py:3752 +#: camlib.py:4220 msgid "There is no tool data in the SolderPaste geometry." msgstr "Il n'y a pas de données d'outil dans la géométrie SolderPaste." -#: camlib.py:3839 +#: camlib.py:4306 msgid "Finished SolderPste G-Code generation" msgstr "Génération de G-Code SolderPaste fini" -#: camlib.py:3841 +#: camlib.py:4306 msgid "paths traced." msgstr "chemins tracés." -#: camlib.py:4097 +#: camlib.py:4566 msgid "Parsing GCode file. Number of lines" msgstr "Analyse du fichier GCode. Nombre de lignes" -#: camlib.py:4204 +#: camlib.py:4673 msgid "Creating Geometry from the parsed GCode file. " msgstr "Création d'une géométrie à partir du fichier GCode analysé. " -#: camlib.py:4345 camlib.py:4629 camlib.py:4732 camlib.py:4801 +#: camlib.py:4816 camlib.py:5101 camlib.py:5204 camlib.py:5360 msgid "G91 coordinates not implemented ..." msgstr "Coordonnées G91 non implémentées ..." -#: camlib.py:4476 +#: camlib.py:4948 msgid "Unifying Geometry from parsed Geometry segments" msgstr "Unifier la géométrie à partir de segments de géométrie analysés" @@ -3031,11 +3428,11 @@ msgstr "" #: flatcamEditors/FlatCAMExcEditor.py:193 #: flatcamEditors/FlatCAMExcEditor.py:416 #: flatcamEditors/FlatCAMExcEditor.py:637 -#: flatcamEditors/FlatCAMExcEditor.py:1155 -#: flatcamEditors/FlatCAMExcEditor.py:1182 +#: flatcamEditors/FlatCAMExcEditor.py:1152 +#: flatcamEditors/FlatCAMExcEditor.py:1179 #: flatcamEditors/FlatCAMGrbEditor.py:471 -#: flatcamEditors/FlatCAMGrbEditor.py:1936 -#: flatcamEditors/FlatCAMGrbEditor.py:1966 +#: flatcamEditors/FlatCAMGrbEditor.py:1935 +#: flatcamEditors/FlatCAMGrbEditor.py:1965 msgid "Click on target location ..." msgstr "Cliquez sur l'emplacement cible ..." @@ -3069,8 +3466,8 @@ msgstr "Pour ajouter un trou de fente, sélectionnez d'abord un outil" #: flatcamEditors/FlatCAMExcEditor.py:455 #: flatcamEditors/FlatCAMExcEditor.py:462 -#: flatcamEditors/FlatCAMExcEditor.py:744 -#: flatcamEditors/FlatCAMExcEditor.py:751 +#: flatcamEditors/FlatCAMExcEditor.py:743 +#: flatcamEditors/FlatCAMExcEditor.py:750 msgid "Value is missing or wrong format. Add it and retry." msgstr "Valeur manquante ou format incorrect. Ajoutez-le et réessayez." @@ -3089,75 +3486,69 @@ msgid "Click on the Slot Circular Array Start position" msgstr "" "Cliquez sur la position de départ de la matrice circulaire du trou de fente" -#: flatcamEditors/FlatCAMExcEditor.py:682 -#: flatcamEditors/FlatCAMGrbEditor.py:520 +#: flatcamEditors/FlatCAMExcEditor.py:681 +#: flatcamEditors/FlatCAMGrbEditor.py:519 msgid "The value is mistyped. Check the value." msgstr "La valeur est mal typée. Vérifiez la valeur." -#: flatcamEditors/FlatCAMExcEditor.py:861 +#: flatcamEditors/FlatCAMExcEditor.py:860 msgid "Too many Slots for the selected spacing angle." msgstr "Trop de trous de fente pour l'angle d'espacement sélectionné." -#: flatcamEditors/FlatCAMExcEditor.py:884 +#: flatcamEditors/FlatCAMExcEditor.py:883 msgid "Done. Slot Array added." msgstr "Terminé. Tableau de trous de fente ajouté." -#: flatcamEditors/FlatCAMExcEditor.py:906 +#: flatcamEditors/FlatCAMExcEditor.py:905 msgid "Click on the Drill(s) to resize ..." msgstr "Cliquez sur les forets pour redimensionner ..." -#: flatcamEditors/FlatCAMExcEditor.py:936 +#: flatcamEditors/FlatCAMExcEditor.py:935 msgid "Resize drill(s) failed. Please enter a diameter for resize." msgstr "" "Redimensionner les trous de forage a échoué. Veuillez entrer un diamètre " "pour le redimensionner." -#: flatcamEditors/FlatCAMExcEditor.py:1026 -#: flatcamEditors/FlatCAMExcEditor.py:1095 flatcamGUI/FlatCAMGUI.py:3165 -#: flatcamGUI/FlatCAMGUI.py:3377 flatcamGUI/FlatCAMGUI.py:3591 -msgid "Cancelled." -msgstr "Annulé." - -#: flatcamEditors/FlatCAMExcEditor.py:1116 +#: flatcamEditors/FlatCAMExcEditor.py:1113 msgid "Done. Drill/Slot Resize completed." msgstr "" "Terminé. Le redimensionnement des trous de forage / rainure est terminé." -#: flatcamEditors/FlatCAMExcEditor.py:1119 +#: flatcamEditors/FlatCAMExcEditor.py:1116 msgid "Cancelled. No drills/slots selected for resize ..." msgstr "" "Annulé. Aucun trou de perçage / rainure sélectionné pour le " "redimensionnement ..." -#: flatcamEditors/FlatCAMExcEditor.py:1157 -#: flatcamEditors/FlatCAMGrbEditor.py:1938 +#: flatcamEditors/FlatCAMExcEditor.py:1154 +#: flatcamEditors/FlatCAMGrbEditor.py:1937 msgid "Click on reference location ..." msgstr "Cliquez sur l'emplacement de référence ..." -#: flatcamEditors/FlatCAMExcEditor.py:1214 +#: flatcamEditors/FlatCAMExcEditor.py:1211 msgid "Done. Drill(s) Move completed." msgstr "Terminé. Foret (s) Déplacement terminé." -#: flatcamEditors/FlatCAMExcEditor.py:1322 +#: flatcamEditors/FlatCAMExcEditor.py:1319 msgid "Done. Drill(s) copied." msgstr "Terminé. Percer des trous copiés." -#: flatcamEditors/FlatCAMExcEditor.py:1555 flatcamGUI/PreferencesUI.py:3551 +#: flatcamEditors/FlatCAMExcEditor.py:1558 flatcamGUI/PreferencesUI.py:3829 msgid "Excellon Editor" msgstr "Excellent éditeur" -#: flatcamEditors/FlatCAMExcEditor.py:1562 -#: flatcamEditors/FlatCAMGrbEditor.py:2454 +#: flatcamEditors/FlatCAMExcEditor.py:1565 +#: flatcamEditors/FlatCAMGrbEditor.py:2460 msgid "Name:" msgstr "Nom:" -#: flatcamEditors/FlatCAMExcEditor.py:1568 flatcamGUI/ObjectUI.py:757 -#: flatcamGUI/ObjectUI.py:1184 flatcamTools/ToolNonCopperClear.py:109 -#: flatcamTools/ToolPaint.py:112 flatcamTools/ToolSolderPaste.py:73 +#: flatcamEditors/FlatCAMExcEditor.py:1571 flatcamGUI/ObjectUI.py:760 +#: flatcamGUI/ObjectUI.py:1463 flatcamTools/ToolNCC.py:120 +#: flatcamTools/ToolPaint.py:115 flatcamTools/ToolSolderPaste.py:75 msgid "Tools Table" msgstr "Tableau des outils" -#: flatcamEditors/FlatCAMExcEditor.py:1570 flatcamGUI/ObjectUI.py:759 +#: flatcamEditors/FlatCAMExcEditor.py:1573 flatcamGUI/ObjectUI.py:762 msgid "" "Tools in this Excellon object\n" "when are used for drilling." @@ -3165,11 +3556,11 @@ msgstr "" "Outils dans cet objet Excellon\n" "quand sont utilisés pour le forage." -#: flatcamEditors/FlatCAMExcEditor.py:1590 +#: flatcamEditors/FlatCAMExcEditor.py:1593 msgid "Add/Delete Tool" msgstr "Ajouter / Supprimer un outil" -#: flatcamEditors/FlatCAMExcEditor.py:1592 +#: flatcamEditors/FlatCAMExcEditor.py:1595 msgid "" "Add/Delete a tool to the tool list\n" "for this Excellon object." @@ -3177,16 +3568,16 @@ msgstr "" "Ajouter / Supprimer un outil à la liste d'outils\n" "pour cet objet Excellon." -#: flatcamEditors/FlatCAMExcEditor.py:1604 flatcamGUI/ObjectUI.py:1297 -#: flatcamGUI/PreferencesUI.py:3582 +#: flatcamEditors/FlatCAMExcEditor.py:1607 flatcamGUI/ObjectUI.py:1583 +#: flatcamGUI/PreferencesUI.py:3860 msgid "Diameter for the new tool" msgstr "Diamètre pour le nouvel outil" -#: flatcamEditors/FlatCAMExcEditor.py:1614 +#: flatcamEditors/FlatCAMExcEditor.py:1617 msgid "Add Tool" msgstr "Ajouter un Outil" -#: flatcamEditors/FlatCAMExcEditor.py:1616 +#: flatcamEditors/FlatCAMExcEditor.py:1619 msgid "" "Add a new tool to the tool list\n" "with the diameter specified above." @@ -3194,11 +3585,11 @@ msgstr "" "Ajouter un nouvel outil à la liste d'outils\n" "avec le diamètre spécifié ci-dessus." -#: flatcamEditors/FlatCAMExcEditor.py:1628 +#: flatcamEditors/FlatCAMExcEditor.py:1631 msgid "Delete Tool" msgstr "Supprimer l'outil" -#: flatcamEditors/FlatCAMExcEditor.py:1630 +#: flatcamEditors/FlatCAMExcEditor.py:1633 msgid "" "Delete a tool in the tool list\n" "by selecting a row in the tool table." @@ -3206,40 +3597,40 @@ msgstr "" "Supprimer un outil dans la liste des outils\n" "en sélectionnant une ligne dans la table d'outils." -#: flatcamEditors/FlatCAMExcEditor.py:1648 flatcamGUI/FlatCAMGUI.py:1896 +#: flatcamEditors/FlatCAMExcEditor.py:1651 flatcamGUI/FlatCAMGUI.py:2004 msgid "Resize Drill(s)" msgstr "Redim. les Forets" -#: flatcamEditors/FlatCAMExcEditor.py:1650 +#: flatcamEditors/FlatCAMExcEditor.py:1653 msgid "Resize a drill or a selection of drills." msgstr "Redimensionnez une perceuse ou une sélection d'exercices." -#: flatcamEditors/FlatCAMExcEditor.py:1657 +#: flatcamEditors/FlatCAMExcEditor.py:1660 msgid "Resize Dia" msgstr "Redim. le dia" -#: flatcamEditors/FlatCAMExcEditor.py:1659 +#: flatcamEditors/FlatCAMExcEditor.py:1662 msgid "Diameter to resize to." msgstr "Diamètre à redimensionner." -#: flatcamEditors/FlatCAMExcEditor.py:1670 +#: flatcamEditors/FlatCAMExcEditor.py:1673 msgid "Resize" msgstr "Redimensionner" -#: flatcamEditors/FlatCAMExcEditor.py:1672 +#: flatcamEditors/FlatCAMExcEditor.py:1675 msgid "Resize drill(s)" msgstr "Redimensionner les forets" -#: flatcamEditors/FlatCAMExcEditor.py:1697 flatcamGUI/FlatCAMGUI.py:1895 -#: flatcamGUI/FlatCAMGUI.py:2147 +#: flatcamEditors/FlatCAMExcEditor.py:1700 flatcamGUI/FlatCAMGUI.py:2003 +#: flatcamGUI/FlatCAMGUI.py:2255 msgid "Add Drill Array" msgstr "Ajouter un Tableau de Forage" -#: flatcamEditors/FlatCAMExcEditor.py:1699 +#: flatcamEditors/FlatCAMExcEditor.py:1702 msgid "Add an array of drills (linear or circular array)" msgstr "Ajouter un tableau de trous de forage (tableau linéaire ou circulaire)" -#: flatcamEditors/FlatCAMExcEditor.py:1705 +#: flatcamEditors/FlatCAMExcEditor.py:1708 msgid "" "Select the type of drills array to create.\n" "It can be Linear X(Y) or Circular" @@ -3247,43 +3638,48 @@ msgstr "" "Sélectionnez le type de matrice de trous à créer.\n" "Il peut être Linéaire X (Y) ou Circulaire" -#: flatcamEditors/FlatCAMExcEditor.py:1708 -#: flatcamEditors/FlatCAMExcEditor.py:1922 -#: flatcamEditors/FlatCAMGrbEditor.py:2766 +#: flatcamEditors/FlatCAMExcEditor.py:1711 +#: flatcamEditors/FlatCAMExcEditor.py:1925 +#: flatcamEditors/FlatCAMGrbEditor.py:2772 msgid "Linear" msgstr "Linéaire" -#: flatcamEditors/FlatCAMExcEditor.py:1709 -#: flatcamEditors/FlatCAMExcEditor.py:1923 -#: flatcamEditors/FlatCAMGrbEditor.py:2767 flatcamGUI/ObjectUI.py:311 -#: flatcamGUI/PreferencesUI.py:5044 flatcamGUI/PreferencesUI.py:7465 -#: flatcamTools/ToolFiducials.py:220 flatcamTools/ToolNonCopperClear.py:221 +#: flatcamEditors/FlatCAMExcEditor.py:1712 +#: flatcamEditors/FlatCAMExcEditor.py:1926 +#: flatcamEditors/FlatCAMGrbEditor.py:2773 flatcamGUI/ObjectUI.py:315 +#: flatcamGUI/PreferencesUI.py:5340 flatcamGUI/PreferencesUI.py:5909 +#: flatcamGUI/PreferencesUI.py:7971 flatcamGUI/PreferencesUI.py:8151 +#: flatcamGUI/PreferencesUI.py:8248 flatcamGUI/PreferencesUI.py:8363 +#: flatcamGUI/PreferencesUI.py:8462 flatcamTools/ToolExtractDrills.py:78 +#: flatcamTools/ToolExtractDrills.py:201 flatcamTools/ToolFiducials.py:220 +#: flatcamTools/ToolNCC.py:221 flatcamTools/ToolPaint.py:204 +#: flatcamTools/ToolPunchGerber.py:89 flatcamTools/ToolPunchGerber.py:229 msgid "Circular" msgstr "Circulaire" -#: flatcamEditors/FlatCAMExcEditor.py:1717 flatcamGUI/PreferencesUI.py:3593 +#: flatcamEditors/FlatCAMExcEditor.py:1720 flatcamGUI/PreferencesUI.py:3871 msgid "Nr of drills" msgstr "Nb de Forages" -#: flatcamEditors/FlatCAMExcEditor.py:1718 flatcamGUI/PreferencesUI.py:3595 +#: flatcamEditors/FlatCAMExcEditor.py:1721 flatcamGUI/PreferencesUI.py:3873 msgid "Specify how many drills to be in the array." msgstr "Spécifiez combien d'exercices doivent figurer dans le tableau." -#: flatcamEditors/FlatCAMExcEditor.py:1736 -#: flatcamEditors/FlatCAMExcEditor.py:1786 -#: flatcamEditors/FlatCAMExcEditor.py:1858 -#: flatcamEditors/FlatCAMExcEditor.py:1951 -#: flatcamEditors/FlatCAMExcEditor.py:2002 -#: flatcamEditors/FlatCAMGrbEditor.py:1572 -#: flatcamEditors/FlatCAMGrbEditor.py:2795 -#: flatcamEditors/FlatCAMGrbEditor.py:2844 flatcamGUI/PreferencesUI.py:3703 +#: flatcamEditors/FlatCAMExcEditor.py:1739 +#: flatcamEditors/FlatCAMExcEditor.py:1789 +#: flatcamEditors/FlatCAMExcEditor.py:1861 +#: flatcamEditors/FlatCAMExcEditor.py:1954 +#: flatcamEditors/FlatCAMExcEditor.py:2005 +#: flatcamEditors/FlatCAMGrbEditor.py:1571 +#: flatcamEditors/FlatCAMGrbEditor.py:2801 +#: flatcamEditors/FlatCAMGrbEditor.py:2850 flatcamGUI/PreferencesUI.py:3981 msgid "Direction" msgstr "Direction" -#: flatcamEditors/FlatCAMExcEditor.py:1738 -#: flatcamEditors/FlatCAMExcEditor.py:1953 -#: flatcamEditors/FlatCAMGrbEditor.py:2797 flatcamGUI/PreferencesUI.py:2536 -#: flatcamGUI/PreferencesUI.py:3611 flatcamGUI/PreferencesUI.py:3759 +#: flatcamEditors/FlatCAMExcEditor.py:1741 +#: flatcamEditors/FlatCAMExcEditor.py:1956 +#: flatcamEditors/FlatCAMGrbEditor.py:2803 flatcamGUI/PreferencesUI.py:2718 +#: flatcamGUI/PreferencesUI.py:3889 flatcamGUI/PreferencesUI.py:4037 msgid "" "Direction on which the linear array is oriented:\n" "- 'X' - horizontal axis \n" @@ -3295,62 +3691,62 @@ msgstr "" "- 'Y' - axe vertical ou\n" "- 'Angle' - un angle personnalisé pour l'inclinaison du tableau" -#: flatcamEditors/FlatCAMExcEditor.py:1745 -#: flatcamEditors/FlatCAMExcEditor.py:1867 -#: flatcamEditors/FlatCAMExcEditor.py:1960 -#: flatcamEditors/FlatCAMGrbEditor.py:2804 flatcamGUI/PreferencesUI.py:2542 -#: flatcamGUI/PreferencesUI.py:3617 flatcamGUI/PreferencesUI.py:3712 -#: flatcamGUI/PreferencesUI.py:3765 flatcamGUI/PreferencesUI.py:5853 +#: flatcamEditors/FlatCAMExcEditor.py:1748 +#: flatcamEditors/FlatCAMExcEditor.py:1870 +#: flatcamEditors/FlatCAMExcEditor.py:1963 +#: flatcamEditors/FlatCAMGrbEditor.py:2810 flatcamGUI/PreferencesUI.py:2724 +#: flatcamGUI/PreferencesUI.py:3895 flatcamGUI/PreferencesUI.py:3990 +#: flatcamGUI/PreferencesUI.py:4043 flatcamGUI/PreferencesUI.py:6341 #: flatcamTools/ToolFilm.py:256 msgid "X" msgstr "X" -#: flatcamEditors/FlatCAMExcEditor.py:1746 -#: flatcamEditors/FlatCAMExcEditor.py:1868 -#: flatcamEditors/FlatCAMExcEditor.py:1961 -#: flatcamEditors/FlatCAMGrbEditor.py:2805 flatcamGUI/PreferencesUI.py:2543 -#: flatcamGUI/PreferencesUI.py:3618 flatcamGUI/PreferencesUI.py:3713 -#: flatcamGUI/PreferencesUI.py:3766 flatcamGUI/PreferencesUI.py:5854 +#: flatcamEditors/FlatCAMExcEditor.py:1749 +#: flatcamEditors/FlatCAMExcEditor.py:1871 +#: flatcamEditors/FlatCAMExcEditor.py:1964 +#: flatcamEditors/FlatCAMGrbEditor.py:2811 flatcamGUI/PreferencesUI.py:2725 +#: flatcamGUI/PreferencesUI.py:3896 flatcamGUI/PreferencesUI.py:3991 +#: flatcamGUI/PreferencesUI.py:4044 flatcamGUI/PreferencesUI.py:6342 #: flatcamTools/ToolFilm.py:257 msgid "Y" msgstr "Y" -#: flatcamEditors/FlatCAMExcEditor.py:1747 -#: flatcamEditors/FlatCAMExcEditor.py:1764 -#: flatcamEditors/FlatCAMExcEditor.py:1798 -#: flatcamEditors/FlatCAMExcEditor.py:1869 -#: flatcamEditors/FlatCAMExcEditor.py:1873 -#: flatcamEditors/FlatCAMExcEditor.py:1962 -#: flatcamEditors/FlatCAMExcEditor.py:1980 -#: flatcamEditors/FlatCAMExcEditor.py:2014 -#: flatcamEditors/FlatCAMGrbEditor.py:2806 -#: flatcamEditors/FlatCAMGrbEditor.py:2823 -#: flatcamEditors/FlatCAMGrbEditor.py:2859 flatcamGUI/PreferencesUI.py:2544 -#: flatcamGUI/PreferencesUI.py:2562 flatcamGUI/PreferencesUI.py:3619 -#: flatcamGUI/PreferencesUI.py:3638 flatcamGUI/PreferencesUI.py:3714 -#: flatcamGUI/PreferencesUI.py:3719 flatcamGUI/PreferencesUI.py:3767 -#: flatcamGUI/PreferencesUI.py:3788 flatcamGUI/PreferencesUI.py:6246 -#: flatcamTools/ToolDistance.py:66 flatcamTools/ToolDistanceMin.py:68 -#: flatcamTools/ToolTransform.py:63 +#: flatcamEditors/FlatCAMExcEditor.py:1750 +#: flatcamEditors/FlatCAMExcEditor.py:1767 +#: flatcamEditors/FlatCAMExcEditor.py:1801 +#: flatcamEditors/FlatCAMExcEditor.py:1872 +#: flatcamEditors/FlatCAMExcEditor.py:1876 +#: flatcamEditors/FlatCAMExcEditor.py:1965 +#: flatcamEditors/FlatCAMExcEditor.py:1983 +#: flatcamEditors/FlatCAMExcEditor.py:2017 +#: flatcamEditors/FlatCAMGrbEditor.py:2812 +#: flatcamEditors/FlatCAMGrbEditor.py:2829 +#: flatcamEditors/FlatCAMGrbEditor.py:2865 flatcamGUI/PreferencesUI.py:2726 +#: flatcamGUI/PreferencesUI.py:2744 flatcamGUI/PreferencesUI.py:3897 +#: flatcamGUI/PreferencesUI.py:3916 flatcamGUI/PreferencesUI.py:3992 +#: flatcamGUI/PreferencesUI.py:3997 flatcamGUI/PreferencesUI.py:4045 +#: flatcamGUI/PreferencesUI.py:4066 flatcamGUI/PreferencesUI.py:6733 +#: flatcamTools/ToolDistance.py:120 flatcamTools/ToolDistanceMin.py:69 +#: flatcamTools/ToolTransform.py:61 msgid "Angle" msgstr "Angle" -#: flatcamEditors/FlatCAMExcEditor.py:1751 -#: flatcamEditors/FlatCAMExcEditor.py:1966 -#: flatcamEditors/FlatCAMGrbEditor.py:2810 flatcamGUI/PreferencesUI.py:2550 -#: flatcamGUI/PreferencesUI.py:3625 flatcamGUI/PreferencesUI.py:3773 +#: flatcamEditors/FlatCAMExcEditor.py:1754 +#: flatcamEditors/FlatCAMExcEditor.py:1969 +#: flatcamEditors/FlatCAMGrbEditor.py:2816 flatcamGUI/PreferencesUI.py:2732 +#: flatcamGUI/PreferencesUI.py:3903 flatcamGUI/PreferencesUI.py:4051 msgid "Pitch" msgstr "Pas" -#: flatcamEditors/FlatCAMExcEditor.py:1753 -#: flatcamEditors/FlatCAMExcEditor.py:1968 -#: flatcamEditors/FlatCAMGrbEditor.py:2812 flatcamGUI/PreferencesUI.py:2552 -#: flatcamGUI/PreferencesUI.py:3627 flatcamGUI/PreferencesUI.py:3775 +#: flatcamEditors/FlatCAMExcEditor.py:1756 +#: flatcamEditors/FlatCAMExcEditor.py:1971 +#: flatcamEditors/FlatCAMGrbEditor.py:2818 flatcamGUI/PreferencesUI.py:2734 +#: flatcamGUI/PreferencesUI.py:3905 flatcamGUI/PreferencesUI.py:4053 msgid "Pitch = Distance between elements of the array." msgstr "Pas = Distance entre les éléments du tableau." -#: flatcamEditors/FlatCAMExcEditor.py:1766 -#: flatcamEditors/FlatCAMExcEditor.py:1982 +#: flatcamEditors/FlatCAMExcEditor.py:1769 +#: flatcamEditors/FlatCAMExcEditor.py:1985 msgid "" "Angle at which the linear array is placed.\n" "The precision is of max 2 decimals.\n" @@ -3362,9 +3758,9 @@ msgstr "" "La valeur minimale est: -360 degrés.\n" "La valeur maximale est: 360,00 degrés." -#: flatcamEditors/FlatCAMExcEditor.py:1787 -#: flatcamEditors/FlatCAMExcEditor.py:2003 -#: flatcamEditors/FlatCAMGrbEditor.py:2846 +#: flatcamEditors/FlatCAMExcEditor.py:1790 +#: flatcamEditors/FlatCAMExcEditor.py:2006 +#: flatcamEditors/FlatCAMGrbEditor.py:2852 msgid "" "Direction for circular array.Can be CW = clockwise or CCW = counter " "clockwise." @@ -3372,36 +3768,36 @@ msgstr "" "Direction pour tableau circulaire. Peut être CW = sens horaire ou CCW = sens " "antihoraire." -#: flatcamEditors/FlatCAMExcEditor.py:1794 -#: flatcamEditors/FlatCAMExcEditor.py:2010 -#: flatcamEditors/FlatCAMGrbEditor.py:2854 flatcamGUI/PreferencesUI.py:2584 -#: flatcamGUI/PreferencesUI.py:3368 flatcamGUI/PreferencesUI.py:3661 -#: flatcamGUI/PreferencesUI.py:3811 flatcamGUI/PreferencesUI.py:4288 +#: flatcamEditors/FlatCAMExcEditor.py:1797 +#: flatcamEditors/FlatCAMExcEditor.py:2013 +#: flatcamEditors/FlatCAMGrbEditor.py:2860 flatcamGUI/PreferencesUI.py:2766 +#: flatcamGUI/PreferencesUI.py:3646 flatcamGUI/PreferencesUI.py:3939 +#: flatcamGUI/PreferencesUI.py:4089 flatcamGUI/PreferencesUI.py:4581 msgid "CW" msgstr "CW" -#: flatcamEditors/FlatCAMExcEditor.py:1795 -#: flatcamEditors/FlatCAMExcEditor.py:2011 -#: flatcamEditors/FlatCAMGrbEditor.py:2855 flatcamGUI/PreferencesUI.py:2585 -#: flatcamGUI/PreferencesUI.py:3369 flatcamGUI/PreferencesUI.py:3662 -#: flatcamGUI/PreferencesUI.py:3812 flatcamGUI/PreferencesUI.py:4289 +#: flatcamEditors/FlatCAMExcEditor.py:1798 +#: flatcamEditors/FlatCAMExcEditor.py:2014 +#: flatcamEditors/FlatCAMGrbEditor.py:2861 flatcamGUI/PreferencesUI.py:2767 +#: flatcamGUI/PreferencesUI.py:3647 flatcamGUI/PreferencesUI.py:3940 +#: flatcamGUI/PreferencesUI.py:4090 flatcamGUI/PreferencesUI.py:4582 msgid "CCW" msgstr "CCW" -#: flatcamEditors/FlatCAMExcEditor.py:1799 -#: flatcamEditors/FlatCAMExcEditor.py:2015 -#: flatcamEditors/FlatCAMGrbEditor.py:2861 flatcamGUI/PreferencesUI.py:2564 -#: flatcamGUI/PreferencesUI.py:2593 flatcamGUI/PreferencesUI.py:3640 -#: flatcamGUI/PreferencesUI.py:3670 flatcamGUI/PreferencesUI.py:3790 -#: flatcamGUI/PreferencesUI.py:3820 +#: flatcamEditors/FlatCAMExcEditor.py:1802 +#: flatcamEditors/FlatCAMExcEditor.py:2018 +#: flatcamEditors/FlatCAMGrbEditor.py:2867 flatcamGUI/PreferencesUI.py:2746 +#: flatcamGUI/PreferencesUI.py:2775 flatcamGUI/PreferencesUI.py:3918 +#: flatcamGUI/PreferencesUI.py:3948 flatcamGUI/PreferencesUI.py:4068 +#: flatcamGUI/PreferencesUI.py:4098 msgid "Angle at which each element in circular array is placed." msgstr "Angle auquel chaque élément du tableau circulaire est placé." -#: flatcamEditors/FlatCAMExcEditor.py:1833 +#: flatcamEditors/FlatCAMExcEditor.py:1836 msgid "Slot Parameters" msgstr "Paramètres de Fente" -#: flatcamEditors/FlatCAMExcEditor.py:1835 +#: flatcamEditors/FlatCAMExcEditor.py:1838 msgid "" "Parameters for adding a slot (hole with oval shape)\n" "either single or as an part of an array." @@ -3409,16 +3805,16 @@ msgstr "" "Paramètres pour l'ajout d'une fente (trou de forme ovale)\n" "soit seul, soit faisant partie d'un tableau." -#: flatcamEditors/FlatCAMExcEditor.py:1844 flatcamGUI/PreferencesUI.py:3687 -#: flatcamTools/ToolProperties.py:555 +#: flatcamEditors/FlatCAMExcEditor.py:1847 flatcamGUI/PreferencesUI.py:3965 +#: flatcamTools/ToolProperties.py:559 msgid "Length" msgstr "Longueur" -#: flatcamEditors/FlatCAMExcEditor.py:1846 flatcamGUI/PreferencesUI.py:3689 +#: flatcamEditors/FlatCAMExcEditor.py:1849 flatcamGUI/PreferencesUI.py:3967 msgid "Length = The length of the slot." msgstr "Longueur = La longueur de la fente." -#: flatcamEditors/FlatCAMExcEditor.py:1860 flatcamGUI/PreferencesUI.py:3705 +#: flatcamEditors/FlatCAMExcEditor.py:1863 flatcamGUI/PreferencesUI.py:3983 msgid "" "Direction on which the slot is oriented:\n" "- 'X' - horizontal axis \n" @@ -3430,7 +3826,7 @@ msgstr "" "- 'Y' - axe vertical ou\n" "- 'Angle' - un angle personnalisé pour l'inclinaison de la fente" -#: flatcamEditors/FlatCAMExcEditor.py:1875 +#: flatcamEditors/FlatCAMExcEditor.py:1878 msgid "" "Angle at which the slot is placed.\n" "The precision is of max 2 decimals.\n" @@ -3442,15 +3838,15 @@ msgstr "" "La valeur minimale est: -360 degrés.\n" "La valeur maximale est: 360,00 degrés." -#: flatcamEditors/FlatCAMExcEditor.py:1908 +#: flatcamEditors/FlatCAMExcEditor.py:1911 msgid "Slot Array Parameters" msgstr "Param. de la Matrice de Fentes" -#: flatcamEditors/FlatCAMExcEditor.py:1910 +#: flatcamEditors/FlatCAMExcEditor.py:1913 msgid "Parameters for the array of slots (linear or circular array)" msgstr "Paramètres pour la Matrice de Fente (matrice linéaire ou circulaire)" -#: flatcamEditors/FlatCAMExcEditor.py:1919 +#: flatcamEditors/FlatCAMExcEditor.py:1922 msgid "" "Select the type of slot array to create.\n" "It can be Linear X(Y) or Circular" @@ -3458,15 +3854,15 @@ msgstr "" "Sélectionnez le type de matrice à percer.\n" "Il peut être linéaire X (Y) ou circulaire" -#: flatcamEditors/FlatCAMExcEditor.py:1931 flatcamGUI/PreferencesUI.py:3744 +#: flatcamEditors/FlatCAMExcEditor.py:1934 flatcamGUI/PreferencesUI.py:4022 msgid "Nr of slots" msgstr "Nb de Fentes" -#: flatcamEditors/FlatCAMExcEditor.py:1932 flatcamGUI/PreferencesUI.py:3746 +#: flatcamEditors/FlatCAMExcEditor.py:1935 flatcamGUI/PreferencesUI.py:4024 msgid "Specify how many slots to be in the array." msgstr "Spécifiez le nombre de Fente dans le Tableau." -#: flatcamEditors/FlatCAMExcEditor.py:2546 +#: flatcamEditors/FlatCAMExcEditor.py:2571 msgid "" "Tool already in the original or actual tool list.\n" "Save and reedit Excellon if you need to add this tool. " @@ -3474,51 +3870,51 @@ msgstr "" "Outil déjà dans la liste d'outils d'origine ou réelle.\n" "Enregistrez et rééditez Excellon si vous devez ajouter cet outil. " -#: flatcamEditors/FlatCAMExcEditor.py:2555 flatcamGUI/FlatCAMGUI.py:3792 +#: flatcamEditors/FlatCAMExcEditor.py:2580 flatcamGUI/FlatCAMGUI.py:4009 msgid "Added new tool with dia" msgstr "Ajout d'un nouvel outil avec dia" -#: flatcamEditors/FlatCAMExcEditor.py:2589 +#: flatcamEditors/FlatCAMExcEditor.py:2613 msgid "Select a tool in Tool Table" msgstr "Sélectionner un outil dans la table d'outils" -#: flatcamEditors/FlatCAMExcEditor.py:2622 +#: flatcamEditors/FlatCAMExcEditor.py:2643 msgid "Deleted tool with diameter" msgstr "Outil supprimé avec diamètre" -#: flatcamEditors/FlatCAMExcEditor.py:2772 +#: flatcamEditors/FlatCAMExcEditor.py:2793 msgid "Done. Tool edit completed." msgstr "Terminé. L'édition de l'outil est terminée." -#: flatcamEditors/FlatCAMExcEditor.py:3324 +#: flatcamEditors/FlatCAMExcEditor.py:3350 msgid "There are no Tools definitions in the file. Aborting Excellon creation." msgstr "" "Il n'y a pas de définition d'outils dans le fichier. Abandon de la création " "Excellon." -#: flatcamEditors/FlatCAMExcEditor.py:3328 +#: flatcamEditors/FlatCAMExcEditor.py:3354 msgid "An internal error has ocurred. See Shell.\n" msgstr "Une erreur interne s'est produite. Voir Shell.\n" -#: flatcamEditors/FlatCAMExcEditor.py:3333 +#: flatcamEditors/FlatCAMExcEditor.py:3359 msgid "Creating Excellon." msgstr "Créer Excellon." -#: flatcamEditors/FlatCAMExcEditor.py:3347 +#: flatcamEditors/FlatCAMExcEditor.py:3371 msgid "Excellon editing finished." msgstr "Excellon édition terminée." -#: flatcamEditors/FlatCAMExcEditor.py:3365 +#: flatcamEditors/FlatCAMExcEditor.py:3388 msgid "Cancelled. There is no Tool/Drill selected" msgstr "Annulé. Aucun Outil/Foret sélectionné" -#: flatcamEditors/FlatCAMExcEditor.py:3978 +#: flatcamEditors/FlatCAMExcEditor.py:4001 msgid "Done. Drill(s) deleted." msgstr "Terminé. Percer des trous supprimés." -#: flatcamEditors/FlatCAMExcEditor.py:4051 -#: flatcamEditors/FlatCAMExcEditor.py:4061 -#: flatcamEditors/FlatCAMGrbEditor.py:4853 +#: flatcamEditors/FlatCAMExcEditor.py:4074 +#: flatcamEditors/FlatCAMExcEditor.py:4084 +#: flatcamEditors/FlatCAMGrbEditor.py:4897 msgid "Click on the circular array Center position" msgstr "Cliquez sur le tableau circulaire Position centrale" @@ -3545,18 +3941,24 @@ msgstr "" "fonctionnalités réunies dans le coin" #: flatcamEditors/FlatCAMGeoEditor.py:95 -#: flatcamEditors/FlatCAMGrbEditor.py:2622 +#: flatcamEditors/FlatCAMGrbEditor.py:2628 msgid "Round" msgstr "Rond" #: flatcamEditors/FlatCAMGeoEditor.py:96 -#: flatcamEditors/FlatCAMGrbEditor.py:2623 flatcamGUI/PreferencesUI.py:7058 +#: flatcamEditors/FlatCAMGrbEditor.py:2629 flatcamGUI/PreferencesUI.py:5606 +#: flatcamGUI/PreferencesUI.py:6130 flatcamGUI/PreferencesUI.py:7564 +#: flatcamGUI/PreferencesUI.py:8167 flatcamGUI/PreferencesUI.py:8274 +#: flatcamGUI/PreferencesUI.py:8379 flatcamGUI/PreferencesUI.py:8488 +#: flatcamTools/ToolExtractDrills.py:94 flatcamTools/ToolExtractDrills.py:227 +#: flatcamTools/ToolNCC.py:583 flatcamTools/ToolPaint.py:527 +#: flatcamTools/ToolPunchGerber.py:105 flatcamTools/ToolPunchGerber.py:255 #: flatcamTools/ToolQRCode.py:198 msgid "Square" msgstr "Carré" #: flatcamEditors/FlatCAMGeoEditor.py:97 -#: flatcamEditors/FlatCAMGrbEditor.py:2624 +#: flatcamEditors/FlatCAMGrbEditor.py:2630 msgid "Beveled" msgstr "Biseauté" @@ -3573,18 +3975,18 @@ msgid "Full Buffer" msgstr "Plein tampon" #: flatcamEditors/FlatCAMGeoEditor.py:133 -#: flatcamEditors/FlatCAMGeoEditor.py:2885 flatcamGUI/FlatCAMGUI.py:1805 -#: flatcamGUI/PreferencesUI.py:2604 +#: flatcamEditors/FlatCAMGeoEditor.py:3018 flatcamGUI/FlatCAMGUI.py:1913 +#: flatcamGUI/PreferencesUI.py:2786 msgid "Buffer Tool" msgstr "Outil Tampon" #: flatcamEditors/FlatCAMGeoEditor.py:145 #: flatcamEditors/FlatCAMGeoEditor.py:162 #: flatcamEditors/FlatCAMGeoEditor.py:179 -#: flatcamEditors/FlatCAMGeoEditor.py:2904 -#: flatcamEditors/FlatCAMGeoEditor.py:2934 -#: flatcamEditors/FlatCAMGeoEditor.py:2964 -#: flatcamEditors/FlatCAMGrbEditor.py:4906 +#: flatcamEditors/FlatCAMGeoEditor.py:3037 +#: flatcamEditors/FlatCAMGeoEditor.py:3065 +#: flatcamEditors/FlatCAMGeoEditor.py:3093 +#: flatcamEditors/FlatCAMGrbEditor.py:4950 msgid "Buffer distance value is missing or wrong format. Add it and retry." msgstr "" "La valeur de la distance tampon est un format manquant ou incorrect. Ajoutez-" @@ -3594,7 +3996,7 @@ msgstr "" msgid "Font" msgstr "Police" -#: flatcamEditors/FlatCAMGeoEditor.py:324 flatcamGUI/FlatCAMGUI.py:2085 +#: flatcamEditors/FlatCAMGeoEditor.py:324 flatcamGUI/FlatCAMGUI.py:2193 msgid "Text" msgstr "Texte" @@ -3602,210 +4004,112 @@ msgstr "Texte" msgid "Text Tool" msgstr "Outil Texte" -#: flatcamEditors/FlatCAMGeoEditor.py:442 flatcamGUI/ObjectUI.py:359 -#: flatcamGUI/PreferencesUI.py:2025 flatcamGUI/PreferencesUI.py:3875 -#: flatcamGUI/PreferencesUI.py:5535 +#: flatcamEditors/FlatCAMGeoEditor.py:440 flatcamGUI/ObjectUI.py:363 +#: flatcamGUI/PreferencesUI.py:2205 msgid "Tool dia" msgstr "Outil dia" -#: flatcamEditors/FlatCAMGeoEditor.py:444 flatcamGUI/PreferencesUI.py:5537 +#: flatcamEditors/FlatCAMGeoEditor.py:442 +msgid "Diameter of the tool to be used in the operation." +msgstr "Diamètre de l'outil à utiliser dans l'opération." + +#: flatcamEditors/FlatCAMGeoEditor.py:488 msgid "" -"Diameter of the tool to\n" -"be used in the operation." +"Algorithm to paint the polygons:\n" +"- Standard: Fixed step inwards.\n" +"- Seed-based: Outwards from seed.\n" +"- Line-based: Parallel lines." msgstr "" -"Diamètre de l'outil à\n" -"être utilisé dans l'opération." +"Algorithme pour peindre les polygones:\n" +"- Standard: pas fixe vers l'intérieur.\n" +"- À base de graines: à l'extérieur des graines.\n" +"- Ligne: lignes parallèles." -#: flatcamEditors/FlatCAMGeoEditor.py:455 flatcamGUI/PreferencesUI.py:5152 -#: flatcamGUI/PreferencesUI.py:5567 flatcamTools/ToolNonCopperClear.py:319 -#: flatcamTools/ToolPaint.py:219 -msgid "Overlap Rate" -msgstr "Taux de chevauchement" - -#: flatcamEditors/FlatCAMGeoEditor.py:457 flatcamGUI/PreferencesUI.py:5569 -#: flatcamTools/ToolPaint.py:221 -msgid "" -"How much (fraction) of the tool width to overlap each tool pass.\n" -"Adjust the value starting with lower values\n" -"and increasing it if areas that should be painted are still \n" -"not painted.\n" -"Lower values = faster processing, faster execution on CNC.\n" -"Higher values = slow processing and slow execution on CNC\n" -"due of too many paths." -msgstr "" -"Combien (fraction) de la largeur de l'outil doit chevaucher chaque passe-" -"outil.\n" -"Ajuster la valeur en commençant par les valeurs les plus basses\n" -"et augmenter si les zones qui devraient être peintes sont encore\n" -"pas peint.\n" -"Des valeurs plus faibles = traitement plus rapide, exécution plus rapide sur " -"le PCB.\n" -"Valeurs plus élevées = traitement lent et exécution lente sur la CNC\n" -"à cause de trop de chemins." - -#: flatcamEditors/FlatCAMGeoEditor.py:475 flatcamGUI/PreferencesUI.py:5171 -#: flatcamGUI/PreferencesUI.py:5384 flatcamGUI/PreferencesUI.py:5587 -#: flatcamGUI/PreferencesUI.py:7175 flatcamGUI/PreferencesUI.py:7332 -#: flatcamGUI/PreferencesUI.py:7417 flatcamTools/ToolCopperThieving.py:111 -#: flatcamTools/ToolCopperThieving.py:361 flatcamTools/ToolCutOut.py:184 -#: flatcamTools/ToolFiducials.py:172 flatcamTools/ToolNonCopperClear.py:337 -#: flatcamTools/ToolPaint.py:238 -msgid "Margin" -msgstr "Marge" - -#: flatcamEditors/FlatCAMGeoEditor.py:477 flatcamGUI/PreferencesUI.py:5589 -#: flatcamTools/ToolPaint.py:240 -msgid "" -"Distance by which to avoid\n" -"the edges of the polygon to\n" -"be painted." -msgstr "" -"Distance à éviter\n" -"les bords du polygone à\n" -"être peint." - -#: flatcamEditors/FlatCAMGeoEditor.py:489 flatcamGUI/PreferencesUI.py:5184 -#: flatcamGUI/PreferencesUI.py:5602 flatcamTools/ToolNonCopperClear.py:348 -#: flatcamTools/ToolPaint.py:251 -msgid "Method" -msgstr "Méthode" - -#: flatcamEditors/FlatCAMGeoEditor.py:491 -msgid "" -"Algorithm to paint the polygon:
Standard: Fixed step inwards." -"
Seed-based: Outwards from seed." -msgstr "" -"Algorithme pour peindre le polygone:
Standard: pas fixe vers " -"l’intérieur.
Basé sur les semences:vers l’extérieur depuis les " -"semences." - -#: flatcamEditors/FlatCAMGeoEditor.py:496 flatcamGUI/PreferencesUI.py:5193 -#: flatcamGUI/PreferencesUI.py:5611 flatcamTools/ToolNonCopperClear.py:357 -#: flatcamTools/ToolPaint.py:260 -msgid "Standard" -msgstr "La norme" - -#: flatcamEditors/FlatCAMGeoEditor.py:497 flatcamGUI/PreferencesUI.py:5194 -#: flatcamGUI/PreferencesUI.py:5612 flatcamTools/ToolNonCopperClear.py:358 -#: flatcamTools/ToolPaint.py:261 -msgid "Seed-based" -msgstr "À base de semences" - -#: flatcamEditors/FlatCAMGeoEditor.py:498 flatcamGUI/PreferencesUI.py:5195 -#: flatcamGUI/PreferencesUI.py:5613 flatcamTools/ToolNonCopperClear.py:359 -#: flatcamTools/ToolPaint.py:262 -msgid "Straight lines" -msgstr "Lignes droites" - -#: flatcamEditors/FlatCAMGeoEditor.py:505 +#: flatcamEditors/FlatCAMGeoEditor.py:507 msgid "Connect:" msgstr "Relier:" -#: flatcamEditors/FlatCAMGeoEditor.py:507 flatcamGUI/PreferencesUI.py:5204 -#: flatcamGUI/PreferencesUI.py:5620 flatcamTools/ToolNonCopperClear.py:366 -#: flatcamTools/ToolPaint.py:269 -msgid "" -"Draw lines between resulting\n" -"segments to minimize tool lifts." -msgstr "" -"Tracez des lignes entre les résultats\n" -"segments pour minimiser les montées d’outil." - -#: flatcamEditors/FlatCAMGeoEditor.py:515 +#: flatcamEditors/FlatCAMGeoEditor.py:517 msgid "Contour:" msgstr "Contour:" -#: flatcamEditors/FlatCAMGeoEditor.py:517 flatcamGUI/PreferencesUI.py:5213 -#: flatcamGUI/PreferencesUI.py:5628 flatcamTools/ToolNonCopperClear.py:373 -#: flatcamTools/ToolPaint.py:276 -msgid "" -"Cut around the perimeter of the polygon\n" -"to trim rough edges." -msgstr "" -"Couper autour du périmètre du polygone\n" -"pour couper les bords rugueux." - -#: flatcamEditors/FlatCAMGeoEditor.py:529 flatcamGUI/FlatCAMGUI.py:2089 +#: flatcamEditors/FlatCAMGeoEditor.py:530 flatcamGUI/FlatCAMGUI.py:2197 msgid "Paint" msgstr "Peindre" -#: flatcamEditors/FlatCAMGeoEditor.py:547 flatcamGUI/FlatCAMGUI.py:845 -#: flatcamGUI/FlatCAMGUI.py:2423 flatcamGUI/ObjectUI.py:1731 -#: flatcamTools/ToolPaint.py:41 flatcamTools/ToolPaint.py:533 +#: flatcamEditors/FlatCAMGeoEditor.py:548 flatcamGUI/FlatCAMGUI.py:909 +#: flatcamGUI/FlatCAMGUI.py:2588 flatcamGUI/ObjectUI.py:2057 +#: flatcamTools/ToolPaint.py:43 flatcamTools/ToolPaint.py:738 msgid "Paint Tool" msgstr "Outil de Peinture" #: flatcamEditors/FlatCAMGeoEditor.py:584 -msgid "Paint cancelled. No shape selected." -msgstr "Peinture annulée. Aucune forme sélectionnée." +#: flatcamEditors/FlatCAMGeoEditor.py:1056 +#: flatcamEditors/FlatCAMGeoEditor.py:3025 +#: flatcamEditors/FlatCAMGeoEditor.py:3053 +#: flatcamEditors/FlatCAMGeoEditor.py:3081 +#: flatcamEditors/FlatCAMGeoEditor.py:4502 +#: flatcamEditors/FlatCAMGrbEditor.py:5601 +msgid "Cancelled. No shape selected." +msgstr "Annulé. Aucune forme sélectionnée." #: flatcamEditors/FlatCAMGeoEditor.py:597 -#: flatcamEditors/FlatCAMGeoEditor.py:2910 -#: flatcamEditors/FlatCAMGeoEditor.py:2940 -#: flatcamEditors/FlatCAMGeoEditor.py:2970 flatcamGUI/PreferencesUI.py:3871 -#: flatcamTools/ToolProperties.py:120 flatcamTools/ToolProperties.py:158 +#: flatcamEditors/FlatCAMGeoEditor.py:3043 +#: flatcamEditors/FlatCAMGeoEditor.py:3071 +#: flatcamEditors/FlatCAMGeoEditor.py:3099 flatcamGUI/PreferencesUI.py:4149 +#: flatcamTools/ToolProperties.py:117 flatcamTools/ToolProperties.py:162 msgid "Tools" msgstr "Outils" #: flatcamEditors/FlatCAMGeoEditor.py:608 #: flatcamEditors/FlatCAMGeoEditor.py:992 -#: flatcamEditors/FlatCAMGrbEditor.py:5096 -#: flatcamEditors/FlatCAMGrbEditor.py:5493 flatcamGUI/FlatCAMGUI.py:866 -#: flatcamGUI/FlatCAMGUI.py:2441 flatcamTools/ToolTransform.py:422 +#: flatcamEditors/FlatCAMGrbEditor.py:5140 +#: flatcamEditors/FlatCAMGrbEditor.py:5537 flatcamGUI/FlatCAMGUI.py:930 +#: flatcamGUI/FlatCAMGUI.py:2609 flatcamTools/ToolTransform.py:461 msgid "Transform Tool" msgstr "Outil de Transformation" #: flatcamEditors/FlatCAMGeoEditor.py:609 #: flatcamEditors/FlatCAMGeoEditor.py:674 -#: flatcamEditors/FlatCAMGrbEditor.py:5097 -#: flatcamEditors/FlatCAMGrbEditor.py:5162 flatcamGUI/PreferencesUI.py:6238 -#: flatcamTools/ToolTransform.py:25 flatcamTools/ToolTransform.py:80 +#: flatcamEditors/FlatCAMGrbEditor.py:5141 +#: flatcamEditors/FlatCAMGrbEditor.py:5206 flatcamGUI/PreferencesUI.py:6725 +#: flatcamTools/ToolTransform.py:25 flatcamTools/ToolTransform.py:467 msgid "Rotate" msgstr "Tourner" #: flatcamEditors/FlatCAMGeoEditor.py:610 -#: flatcamEditors/FlatCAMGrbEditor.py:5098 flatcamTools/ToolTransform.py:26 +#: flatcamEditors/FlatCAMGrbEditor.py:5142 flatcamTools/ToolTransform.py:26 msgid "Skew/Shear" msgstr "Inclinaison/Cisaillement" #: flatcamEditors/FlatCAMGeoEditor.py:611 -#: flatcamEditors/FlatCAMGrbEditor.py:2671 -#: flatcamEditors/FlatCAMGrbEditor.py:5099 flatcamGUI/FlatCAMGUI.py:980 -#: flatcamGUI/FlatCAMGUI.py:2017 flatcamGUI/FlatCAMGUI.py:2132 -#: flatcamGUI/FlatCAMGUI.py:2549 flatcamGUI/ObjectUI.py:103 -#: flatcamGUI/ObjectUI.py:121 flatcamGUI/PreferencesUI.py:6288 -#: flatcamTools/ToolTransform.py:27 +#: flatcamEditors/FlatCAMGrbEditor.py:2677 +#: flatcamEditors/FlatCAMGrbEditor.py:5143 flatcamGUI/FlatCAMGUI.py:1048 +#: flatcamGUI/FlatCAMGUI.py:2125 flatcamGUI/FlatCAMGUI.py:2240 +#: flatcamGUI/FlatCAMGUI.py:2723 flatcamGUI/ObjectUI.py:124 +#: flatcamGUI/PreferencesUI.py:6775 flatcamTools/ToolTransform.py:27 msgid "Scale" msgstr "Mise à l'échelle" #: flatcamEditors/FlatCAMGeoEditor.py:612 -#: flatcamEditors/FlatCAMGrbEditor.py:5100 flatcamTools/ToolTransform.py:28 +#: flatcamEditors/FlatCAMGrbEditor.py:5144 flatcamTools/ToolTransform.py:28 msgid "Mirror (Flip)" msgstr "Miroir (flip)" -#: flatcamEditors/FlatCAMGeoEditor.py:613 -#: flatcamEditors/FlatCAMGrbEditor.py:5101 flatcamGUI/ObjectUI.py:132 -#: flatcamGUI/ObjectUI.py:148 flatcamGUI/ObjectUI.py:1217 -#: flatcamGUI/ObjectUI.py:1916 flatcamGUI/PreferencesUI.py:5234 -#: flatcamGUI/PreferencesUI.py:6335 flatcamTools/ToolNonCopperClear.py:393 -#: flatcamTools/ToolTransform.py:29 -msgid "Offset" -msgstr "Décalage" - #: flatcamEditors/FlatCAMGeoEditor.py:626 -#: flatcamEditors/FlatCAMGrbEditor.py:5114 flatcamGUI/FlatCAMGUI.py:787 -#: flatcamGUI/FlatCAMGUI.py:2370 +#: flatcamEditors/FlatCAMGrbEditor.py:5158 flatcamGUI/FlatCAMGUI.py:841 +#: flatcamGUI/FlatCAMGUI.py:2524 msgid "Editor" msgstr "Éditeur" #: flatcamEditors/FlatCAMGeoEditor.py:658 -#: flatcamEditors/FlatCAMGrbEditor.py:5146 +#: flatcamEditors/FlatCAMGrbEditor.py:5190 msgid "Angle:" msgstr "Angle:" #: flatcamEditors/FlatCAMGeoEditor.py:660 -#: flatcamEditors/FlatCAMGrbEditor.py:5148 flatcamGUI/PreferencesUI.py:6248 -#: flatcamTools/ToolTransform.py:65 +#: flatcamEditors/FlatCAMGrbEditor.py:5192 flatcamGUI/PreferencesUI.py:6735 +#: flatcamTools/ToolTransform.py:63 msgid "" "Angle for Rotation action, in degrees.\n" "Float number between -360 and 359.\n" @@ -3818,7 +4122,7 @@ msgstr "" "Nombres négatifs pour le mouvement CCW." #: flatcamEditors/FlatCAMGeoEditor.py:676 -#: flatcamEditors/FlatCAMGrbEditor.py:5164 +#: flatcamEditors/FlatCAMGrbEditor.py:5208 msgid "" "Rotate the selected shape(s).\n" "The point of reference is the middle of\n" @@ -3829,16 +4133,16 @@ msgstr "" "le cadre de sélection pour toutes les formes sélectionnées." #: flatcamEditors/FlatCAMGeoEditor.py:699 -#: flatcamEditors/FlatCAMGrbEditor.py:5187 +#: flatcamEditors/FlatCAMGrbEditor.py:5231 msgid "Angle X:" msgstr "Angle X:" #: flatcamEditors/FlatCAMGeoEditor.py:701 #: flatcamEditors/FlatCAMGeoEditor.py:721 -#: flatcamEditors/FlatCAMGrbEditor.py:5189 -#: flatcamEditors/FlatCAMGrbEditor.py:5209 flatcamGUI/PreferencesUI.py:6267 -#: flatcamGUI/PreferencesUI.py:6281 flatcamTools/ToolCalibration.py:508 -#: flatcamTools/ToolCalibration.py:521 +#: flatcamEditors/FlatCAMGrbEditor.py:5233 +#: flatcamEditors/FlatCAMGrbEditor.py:5253 flatcamGUI/PreferencesUI.py:6754 +#: flatcamGUI/PreferencesUI.py:6768 flatcamTools/ToolCalibration.py:505 +#: flatcamTools/ToolCalibration.py:518 msgid "" "Angle for Skew action, in degrees.\n" "Float number between -360 and 359." @@ -3847,14 +4151,14 @@ msgstr "" "Nombre flottant entre -360 et 359." #: flatcamEditors/FlatCAMGeoEditor.py:712 -#: flatcamEditors/FlatCAMGrbEditor.py:5200 flatcamTools/ToolTransform.py:109 +#: flatcamEditors/FlatCAMGrbEditor.py:5244 flatcamTools/ToolTransform.py:468 msgid "Skew X" msgstr "Fausser X" #: flatcamEditors/FlatCAMGeoEditor.py:714 #: flatcamEditors/FlatCAMGeoEditor.py:734 -#: flatcamEditors/FlatCAMGrbEditor.py:5202 -#: flatcamEditors/FlatCAMGrbEditor.py:5222 +#: flatcamEditors/FlatCAMGrbEditor.py:5246 +#: flatcamEditors/FlatCAMGrbEditor.py:5266 msgid "" "Skew/shear the selected shape(s).\n" "The point of reference is the middle of\n" @@ -3865,34 +4169,34 @@ msgstr "" "le cadre de sélection pour toutes les formes sélectionnées." #: flatcamEditors/FlatCAMGeoEditor.py:719 -#: flatcamEditors/FlatCAMGrbEditor.py:5207 +#: flatcamEditors/FlatCAMGrbEditor.py:5251 msgid "Angle Y:" msgstr "Angle Y:" #: flatcamEditors/FlatCAMGeoEditor.py:732 -#: flatcamEditors/FlatCAMGrbEditor.py:5220 flatcamTools/ToolTransform.py:131 +#: flatcamEditors/FlatCAMGrbEditor.py:5264 flatcamTools/ToolTransform.py:469 msgid "Skew Y" msgstr "Fausser Y" #: flatcamEditors/FlatCAMGeoEditor.py:760 -#: flatcamEditors/FlatCAMGrbEditor.py:5248 +#: flatcamEditors/FlatCAMGrbEditor.py:5292 msgid "Factor X:" msgstr "Facteur X:" #: flatcamEditors/FlatCAMGeoEditor.py:762 -#: flatcamEditors/FlatCAMGrbEditor.py:5250 flatcamTools/ToolCalibration.py:472 +#: flatcamEditors/FlatCAMGrbEditor.py:5294 flatcamTools/ToolCalibration.py:469 msgid "Factor for Scale action over X axis." msgstr "Facteur pour l'action de mise à l'échelle sur l'axe X." #: flatcamEditors/FlatCAMGeoEditor.py:772 -#: flatcamEditors/FlatCAMGrbEditor.py:5260 flatcamTools/ToolTransform.py:158 +#: flatcamEditors/FlatCAMGrbEditor.py:5304 flatcamTools/ToolTransform.py:470 msgid "Scale X" msgstr "Mise à l'échelle X" #: flatcamEditors/FlatCAMGeoEditor.py:774 #: flatcamEditors/FlatCAMGeoEditor.py:793 -#: flatcamEditors/FlatCAMGrbEditor.py:5262 -#: flatcamEditors/FlatCAMGrbEditor.py:5281 +#: flatcamEditors/FlatCAMGrbEditor.py:5306 +#: flatcamEditors/FlatCAMGrbEditor.py:5325 msgid "" "Scale the selected shape(s).\n" "The point of reference depends on \n" @@ -3903,28 +4207,28 @@ msgstr "" "l'état de la case à cocher référence d'échelle." #: flatcamEditors/FlatCAMGeoEditor.py:779 -#: flatcamEditors/FlatCAMGrbEditor.py:5267 +#: flatcamEditors/FlatCAMGrbEditor.py:5311 msgid "Factor Y:" msgstr "Facteur Y:" #: flatcamEditors/FlatCAMGeoEditor.py:781 -#: flatcamEditors/FlatCAMGrbEditor.py:5269 flatcamTools/ToolCalibration.py:484 +#: flatcamEditors/FlatCAMGrbEditor.py:5313 flatcamTools/ToolCalibration.py:481 msgid "Factor for Scale action over Y axis." msgstr "Facteur de Mise à l'échelle de l'action sur l'axe des ordonnées." #: flatcamEditors/FlatCAMGeoEditor.py:791 -#: flatcamEditors/FlatCAMGrbEditor.py:5279 flatcamTools/ToolTransform.py:179 +#: flatcamEditors/FlatCAMGrbEditor.py:5323 flatcamTools/ToolTransform.py:471 msgid "Scale Y" msgstr "Mise à l'échelle Y" #: flatcamEditors/FlatCAMGeoEditor.py:800 -#: flatcamEditors/FlatCAMGrbEditor.py:5288 flatcamGUI/PreferencesUI.py:6317 -#: flatcamTools/ToolTransform.py:192 +#: flatcamEditors/FlatCAMGrbEditor.py:5332 flatcamGUI/PreferencesUI.py:6804 +#: flatcamTools/ToolTransform.py:190 msgid "Link" msgstr "Lien" #: flatcamEditors/FlatCAMGeoEditor.py:802 -#: flatcamEditors/FlatCAMGrbEditor.py:5290 +#: flatcamEditors/FlatCAMGrbEditor.py:5334 msgid "" "Scale the selected shape(s)\n" "using the Scale Factor X for both axis." @@ -3933,13 +4237,13 @@ msgstr "" "en utilisant le facteur d'échelle X pour les deux axes." #: flatcamEditors/FlatCAMGeoEditor.py:808 -#: flatcamEditors/FlatCAMGrbEditor.py:5296 flatcamGUI/PreferencesUI.py:6325 -#: flatcamTools/ToolTransform.py:200 +#: flatcamEditors/FlatCAMGrbEditor.py:5340 flatcamGUI/PreferencesUI.py:6812 +#: flatcamTools/ToolTransform.py:197 msgid "Scale Reference" msgstr "Référence d'échelle" #: flatcamEditors/FlatCAMGeoEditor.py:810 -#: flatcamEditors/FlatCAMGrbEditor.py:5298 +#: flatcamEditors/FlatCAMGrbEditor.py:5342 msgid "" "Scale the selected shape(s)\n" "using the origin reference when checked,\n" @@ -3952,24 +4256,24 @@ msgstr "" "des formes sélectionnées quand elle est décochée." #: flatcamEditors/FlatCAMGeoEditor.py:838 -#: flatcamEditors/FlatCAMGrbEditor.py:5327 +#: flatcamEditors/FlatCAMGrbEditor.py:5371 msgid "Value X:" msgstr "Valeur X:" #: flatcamEditors/FlatCAMGeoEditor.py:840 -#: flatcamEditors/FlatCAMGrbEditor.py:5329 +#: flatcamEditors/FlatCAMGrbEditor.py:5373 msgid "Value for Offset action on X axis." msgstr "Valeur pour l'action de décalage sur l'axe X." #: flatcamEditors/FlatCAMGeoEditor.py:850 -#: flatcamEditors/FlatCAMGrbEditor.py:5339 flatcamTools/ToolTransform.py:227 +#: flatcamEditors/FlatCAMGrbEditor.py:5383 flatcamTools/ToolTransform.py:474 msgid "Offset X" msgstr "Décalage X" #: flatcamEditors/FlatCAMGeoEditor.py:852 #: flatcamEditors/FlatCAMGeoEditor.py:872 -#: flatcamEditors/FlatCAMGrbEditor.py:5341 -#: flatcamEditors/FlatCAMGrbEditor.py:5361 +#: flatcamEditors/FlatCAMGrbEditor.py:5385 +#: flatcamEditors/FlatCAMGrbEditor.py:5405 msgid "" "Offset the selected shape(s).\n" "The point of reference is the middle of\n" @@ -3980,29 +4284,29 @@ msgstr "" "le cadre de sélection pour toutes les formes sélectionnées.\n" #: flatcamEditors/FlatCAMGeoEditor.py:858 -#: flatcamEditors/FlatCAMGrbEditor.py:5347 +#: flatcamEditors/FlatCAMGrbEditor.py:5391 msgid "Value Y:" msgstr "Valeur Y:" #: flatcamEditors/FlatCAMGeoEditor.py:860 -#: flatcamEditors/FlatCAMGrbEditor.py:5349 +#: flatcamEditors/FlatCAMGrbEditor.py:5393 msgid "Value for Offset action on Y axis." msgstr "Valeur pour l'action de décalage sur l'axe Y." #: flatcamEditors/FlatCAMGeoEditor.py:870 -#: flatcamEditors/FlatCAMGrbEditor.py:5359 flatcamTools/ToolTransform.py:248 +#: flatcamEditors/FlatCAMGrbEditor.py:5403 flatcamTools/ToolTransform.py:475 msgid "Offset Y" msgstr "Décalage Y" #: flatcamEditors/FlatCAMGeoEditor.py:901 -#: flatcamEditors/FlatCAMGrbEditor.py:5390 flatcamTools/ToolTransform.py:266 +#: flatcamEditors/FlatCAMGrbEditor.py:5434 flatcamTools/ToolTransform.py:476 msgid "Flip on X" msgstr "Miroir sur X" #: flatcamEditors/FlatCAMGeoEditor.py:903 #: flatcamEditors/FlatCAMGeoEditor.py:910 -#: flatcamEditors/FlatCAMGrbEditor.py:5392 -#: flatcamEditors/FlatCAMGrbEditor.py:5399 +#: flatcamEditors/FlatCAMGrbEditor.py:5436 +#: flatcamEditors/FlatCAMGrbEditor.py:5443 msgid "" "Flip the selected shape(s) over the X axis.\n" "Does not create a new shape." @@ -4011,17 +4315,17 @@ msgstr "" "Ne crée pas une nouvelle forme." #: flatcamEditors/FlatCAMGeoEditor.py:908 -#: flatcamEditors/FlatCAMGrbEditor.py:5397 flatcamTools/ToolTransform.py:272 +#: flatcamEditors/FlatCAMGrbEditor.py:5441 flatcamTools/ToolTransform.py:477 msgid "Flip on Y" msgstr "Miroir sur Y" #: flatcamEditors/FlatCAMGeoEditor.py:916 -#: flatcamEditors/FlatCAMGrbEditor.py:5405 +#: flatcamEditors/FlatCAMGrbEditor.py:5449 msgid "Ref Pt" msgstr "Point de réf" #: flatcamEditors/FlatCAMGeoEditor.py:918 -#: flatcamEditors/FlatCAMGrbEditor.py:5407 +#: flatcamEditors/FlatCAMGrbEditor.py:5451 msgid "" "Flip the selected shape(s)\n" "around the point in Point Entry Field.\n" @@ -4044,12 +4348,12 @@ msgstr "" "Pointez sur le champ Entrée et cliquez sur Basculer sur X (Y)." #: flatcamEditors/FlatCAMGeoEditor.py:930 -#: flatcamEditors/FlatCAMGrbEditor.py:5419 +#: flatcamEditors/FlatCAMGrbEditor.py:5463 msgid "Point:" msgstr "Point:" #: flatcamEditors/FlatCAMGeoEditor.py:932 -#: flatcamEditors/FlatCAMGrbEditor.py:5421 flatcamTools/ToolTransform.py:301 +#: flatcamEditors/FlatCAMGrbEditor.py:5465 flatcamTools/ToolTransform.py:300 msgid "" "Coordinates in format (x, y) used as reference for mirroring.\n" "The 'x' in (x, y) will be used when using Flip on X and\n" @@ -4061,7 +4365,7 @@ msgstr "" "le 'y' dans (x, y) sera utilisé lors de l'utilisation de Flip sur Y." #: flatcamEditors/FlatCAMGeoEditor.py:942 -#: flatcamEditors/FlatCAMGrbEditor.py:5433 flatcamTools/ToolTransform.py:312 +#: flatcamEditors/FlatCAMGrbEditor.py:5477 flatcamTools/ToolTransform.py:310 msgid "" "The point coordinates can be captured by\n" "left click on canvas together with pressing\n" @@ -4071,357 +4375,357 @@ msgstr "" "clic gauche sur la toile avec appui\n" "Touche Majuscule. Puis cliquez sur le bouton Ajouter pour insérer." -#: flatcamEditors/FlatCAMGeoEditor.py:1057 -#: flatcamEditors/FlatCAMGrbEditor.py:5558 -msgid "Transformation cancelled. No shape selected." -msgstr "Transformation annulée. Aucune forme sélectionnée." - -#: flatcamEditors/FlatCAMGeoEditor.py:1258 -#: flatcamEditors/FlatCAMGrbEditor.py:5742 +#: flatcamEditors/FlatCAMGeoEditor.py:1305 +#: flatcamEditors/FlatCAMGrbEditor.py:5785 msgid "No shape selected. Please Select a shape to rotate!" msgstr "" "Aucune forme sélectionnée. Veuillez sélectionner une forme à faire pivoter!" -#: flatcamEditors/FlatCAMGeoEditor.py:1261 -#: flatcamEditors/FlatCAMGrbEditor.py:5745 flatcamTools/ToolTransform.py:611 +#: flatcamEditors/FlatCAMGeoEditor.py:1308 +#: flatcamEditors/FlatCAMGrbEditor.py:5788 flatcamTools/ToolTransform.py:680 msgid "Appying Rotate" msgstr "Appliquer la Rotation" -#: flatcamEditors/FlatCAMGeoEditor.py:1290 -#: flatcamEditors/FlatCAMGrbEditor.py:5779 +#: flatcamEditors/FlatCAMGeoEditor.py:1334 +#: flatcamEditors/FlatCAMGrbEditor.py:5820 msgid "Done. Rotate completed." msgstr "Terminé. Rotation terminée." -#: flatcamEditors/FlatCAMGeoEditor.py:1295 +#: flatcamEditors/FlatCAMGeoEditor.py:1336 msgid "Rotation action was not executed" msgstr "L'action de rotation n'a pas été exécutée" -#: flatcamEditors/FlatCAMGeoEditor.py:1307 -#: flatcamEditors/FlatCAMGrbEditor.py:5800 +#: flatcamEditors/FlatCAMGeoEditor.py:1355 +#: flatcamEditors/FlatCAMGrbEditor.py:5839 msgid "No shape selected. Please Select a shape to flip!" msgstr "" "Aucune forme sélectionnée. Veuillez sélectionner une forme à retourner!" -#: flatcamEditors/FlatCAMGeoEditor.py:1310 -#: flatcamEditors/FlatCAMGrbEditor.py:5803 flatcamTools/ToolTransform.py:664 +#: flatcamEditors/FlatCAMGeoEditor.py:1358 +#: flatcamEditors/FlatCAMGrbEditor.py:5842 flatcamTools/ToolTransform.py:729 msgid "Applying Flip" msgstr "Appliquer Flip" -#: flatcamEditors/FlatCAMGeoEditor.py:1341 -#: flatcamEditors/FlatCAMGrbEditor.py:5843 flatcamTools/ToolTransform.py:707 +#: flatcamEditors/FlatCAMGeoEditor.py:1387 +#: flatcamEditors/FlatCAMGrbEditor.py:5880 flatcamTools/ToolTransform.py:770 msgid "Flip on the Y axis done" msgstr "Tournez sur l'axe des Y fait" -#: flatcamEditors/FlatCAMGeoEditor.py:1345 -#: flatcamEditors/FlatCAMGrbEditor.py:5852 flatcamTools/ToolTransform.py:717 +#: flatcamEditors/FlatCAMGeoEditor.py:1391 +#: flatcamEditors/FlatCAMGrbEditor.py:5889 flatcamTools/ToolTransform.py:779 msgid "Flip on the X axis done" msgstr "Tournez sur l'axe X terminé" -#: flatcamEditors/FlatCAMGeoEditor.py:1355 +#: flatcamEditors/FlatCAMGeoEditor.py:1399 msgid "Flip action was not executed" msgstr "L'action Flip n'a pas été exécutée" -#: flatcamEditors/FlatCAMGeoEditor.py:1365 -#: flatcamEditors/FlatCAMGrbEditor.py:5874 +#: flatcamEditors/FlatCAMGeoEditor.py:1417 +#: flatcamEditors/FlatCAMGrbEditor.py:5909 msgid "No shape selected. Please Select a shape to shear/skew!" msgstr "" "Aucune forme sélectionnée. Veuillez sélectionner une forme pour cisailler / " "incliner!" -#: flatcamEditors/FlatCAMGeoEditor.py:1368 -#: flatcamEditors/FlatCAMGrbEditor.py:5877 flatcamTools/ToolTransform.py:742 +#: flatcamEditors/FlatCAMGeoEditor.py:1420 +#: flatcamEditors/FlatCAMGrbEditor.py:5912 flatcamTools/ToolTransform.py:802 msgid "Applying Skew" msgstr "Application de l'inclinaison" -#: flatcamEditors/FlatCAMGeoEditor.py:1394 -#: flatcamEditors/FlatCAMGrbEditor.py:5913 +#: flatcamEditors/FlatCAMGeoEditor.py:1443 +#: flatcamEditors/FlatCAMGrbEditor.py:5946 msgid "Skew on the X axis done" msgstr "Inclinaison sur l'axe X terminée" -#: flatcamEditors/FlatCAMGeoEditor.py:1397 -#: flatcamEditors/FlatCAMGrbEditor.py:5915 +#: flatcamEditors/FlatCAMGeoEditor.py:1445 +#: flatcamEditors/FlatCAMGrbEditor.py:5948 msgid "Skew on the Y axis done" msgstr "Inclinaison sur l'axe des Y faite" -#: flatcamEditors/FlatCAMGeoEditor.py:1401 +#: flatcamEditors/FlatCAMGeoEditor.py:1448 msgid "Skew action was not executed" msgstr "L'action de biais n'a pas été exécutée" -#: flatcamEditors/FlatCAMGeoEditor.py:1413 -#: flatcamEditors/FlatCAMGrbEditor.py:5939 +#: flatcamEditors/FlatCAMGeoEditor.py:1470 +#: flatcamEditors/FlatCAMGrbEditor.py:5970 msgid "No shape selected. Please Select a shape to scale!" msgstr "" "Aucune forme sélectionnée. Veuillez sélectionner une forme à mettre à " "l'échelle!" -#: flatcamEditors/FlatCAMGeoEditor.py:1416 -#: flatcamEditors/FlatCAMGrbEditor.py:5942 flatcamTools/ToolTransform.py:794 +#: flatcamEditors/FlatCAMGeoEditor.py:1473 +#: flatcamEditors/FlatCAMGrbEditor.py:5973 flatcamTools/ToolTransform.py:849 msgid "Applying Scale" msgstr "Échelle d'application" -#: flatcamEditors/FlatCAMGeoEditor.py:1451 -#: flatcamEditors/FlatCAMGrbEditor.py:5981 +#: flatcamEditors/FlatCAMGeoEditor.py:1505 +#: flatcamEditors/FlatCAMGrbEditor.py:6010 msgid "Scale on the X axis done" msgstr "Échelle terminée sur l'axe X" -#: flatcamEditors/FlatCAMGeoEditor.py:1454 -#: flatcamEditors/FlatCAMGrbEditor.py:5983 +#: flatcamEditors/FlatCAMGeoEditor.py:1507 +#: flatcamEditors/FlatCAMGrbEditor.py:6012 msgid "Scale on the Y axis done" msgstr "Echelle terminée sur l'axe des Y" -#: flatcamEditors/FlatCAMGeoEditor.py:1457 +#: flatcamEditors/FlatCAMGeoEditor.py:1509 msgid "Scale action was not executed" msgstr "L'action d'échelle n'a pas été exécutée" -#: flatcamEditors/FlatCAMGeoEditor.py:1467 -#: flatcamEditors/FlatCAMGrbEditor.py:6000 +#: flatcamEditors/FlatCAMGeoEditor.py:1524 +#: flatcamEditors/FlatCAMGrbEditor.py:6029 msgid "No shape selected. Please Select a shape to offset!" msgstr "" "Aucune forme sélectionnée. Veuillez sélectionner une forme à compenser!" -#: flatcamEditors/FlatCAMGeoEditor.py:1470 -#: flatcamEditors/FlatCAMGrbEditor.py:6003 flatcamTools/ToolTransform.py:849 +#: flatcamEditors/FlatCAMGeoEditor.py:1527 +#: flatcamEditors/FlatCAMGrbEditor.py:6032 flatcamTools/ToolTransform.py:901 msgid "Applying Offset" msgstr "Appliquer un Décalage" -#: flatcamEditors/FlatCAMGeoEditor.py:1483 -#: flatcamEditors/FlatCAMGrbEditor.py:6024 +#: flatcamEditors/FlatCAMGeoEditor.py:1537 +#: flatcamEditors/FlatCAMGrbEditor.py:6053 msgid "Offset on the X axis done" msgstr "Décalage sur l'axe X terminé" -#: flatcamEditors/FlatCAMGeoEditor.py:1486 -#: flatcamEditors/FlatCAMGrbEditor.py:6026 +#: flatcamEditors/FlatCAMGeoEditor.py:1539 +#: flatcamEditors/FlatCAMGrbEditor.py:6055 msgid "Offset on the Y axis done" msgstr "Décalage sur l'axe Y terminé" -#: flatcamEditors/FlatCAMGeoEditor.py:1490 +#: flatcamEditors/FlatCAMGeoEditor.py:1542 msgid "Offset action was not executed" msgstr "L'action offset n'a pas été exécutée" -#: flatcamEditors/FlatCAMGeoEditor.py:1494 -#: flatcamEditors/FlatCAMGrbEditor.py:6033 +#: flatcamEditors/FlatCAMGeoEditor.py:1546 +#: flatcamEditors/FlatCAMGrbEditor.py:6062 msgid "Rotate ..." msgstr "Tourner ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1495 -#: flatcamEditors/FlatCAMGeoEditor.py:1550 -#: flatcamEditors/FlatCAMGeoEditor.py:1567 -#: flatcamEditors/FlatCAMGrbEditor.py:6034 -#: flatcamEditors/FlatCAMGrbEditor.py:6083 -#: flatcamEditors/FlatCAMGrbEditor.py:6098 +#: flatcamEditors/FlatCAMGeoEditor.py:1547 +#: flatcamEditors/FlatCAMGeoEditor.py:1602 +#: flatcamEditors/FlatCAMGeoEditor.py:1619 +#: flatcamEditors/FlatCAMGrbEditor.py:6063 +#: flatcamEditors/FlatCAMGrbEditor.py:6112 +#: flatcamEditors/FlatCAMGrbEditor.py:6127 msgid "Enter an Angle Value (degrees)" msgstr "Entrer une valeur d'angle (degrés)" -#: flatcamEditors/FlatCAMGeoEditor.py:1504 -#: flatcamEditors/FlatCAMGrbEditor.py:6042 +#: flatcamEditors/FlatCAMGeoEditor.py:1556 +#: flatcamEditors/FlatCAMGrbEditor.py:6071 msgid "Geometry shape rotate done" msgstr "Rotation de la forme géométrique effectuée" -#: flatcamEditors/FlatCAMGeoEditor.py:1508 -#: flatcamEditors/FlatCAMGrbEditor.py:6045 +#: flatcamEditors/FlatCAMGeoEditor.py:1560 +#: flatcamEditors/FlatCAMGrbEditor.py:6074 msgid "Geometry shape rotate cancelled" msgstr "Rotation de la forme géométrique annulée" -#: flatcamEditors/FlatCAMGeoEditor.py:1513 -#: flatcamEditors/FlatCAMGrbEditor.py:6050 +#: flatcamEditors/FlatCAMGeoEditor.py:1565 +#: flatcamEditors/FlatCAMGrbEditor.py:6079 msgid "Offset on X axis ..." msgstr "Décalage sur l'axe des X ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1514 -#: flatcamEditors/FlatCAMGeoEditor.py:1533 -#: flatcamEditors/FlatCAMGrbEditor.py:6051 -#: flatcamEditors/FlatCAMGrbEditor.py:6068 +#: flatcamEditors/FlatCAMGeoEditor.py:1566 +#: flatcamEditors/FlatCAMGeoEditor.py:1585 +#: flatcamEditors/FlatCAMGrbEditor.py:6080 +#: flatcamEditors/FlatCAMGrbEditor.py:6097 msgid "Enter a distance Value" msgstr "Entrez une valeur de distance" -#: flatcamEditors/FlatCAMGeoEditor.py:1523 -#: flatcamEditors/FlatCAMGrbEditor.py:6059 +#: flatcamEditors/FlatCAMGeoEditor.py:1575 +#: flatcamEditors/FlatCAMGrbEditor.py:6088 msgid "Geometry shape offset on X axis done" msgstr "Géométrie décalée sur l'axe des X effectuée" -#: flatcamEditors/FlatCAMGeoEditor.py:1527 -#: flatcamEditors/FlatCAMGrbEditor.py:6062 +#: flatcamEditors/FlatCAMGeoEditor.py:1579 +#: flatcamEditors/FlatCAMGrbEditor.py:6091 msgid "Geometry shape offset X cancelled" msgstr "Décalage géométrique X annulé" -#: flatcamEditors/FlatCAMGeoEditor.py:1532 -#: flatcamEditors/FlatCAMGrbEditor.py:6067 +#: flatcamEditors/FlatCAMGeoEditor.py:1584 +#: flatcamEditors/FlatCAMGrbEditor.py:6096 msgid "Offset on Y axis ..." msgstr "Décalage sur l'axe Y ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1542 -#: flatcamEditors/FlatCAMGrbEditor.py:6076 +#: flatcamEditors/FlatCAMGeoEditor.py:1594 +#: flatcamEditors/FlatCAMGrbEditor.py:6105 msgid "Geometry shape offset on Y axis done" msgstr "Géométrie décalée sur l'axe des Y effectuée" -#: flatcamEditors/FlatCAMGeoEditor.py:1546 +#: flatcamEditors/FlatCAMGeoEditor.py:1598 msgid "Geometry shape offset on Y axis canceled" msgstr "Décalage de la forme de la géométrie sur l'axe des Y" -#: flatcamEditors/FlatCAMGeoEditor.py:1549 -#: flatcamEditors/FlatCAMGrbEditor.py:6082 +#: flatcamEditors/FlatCAMGeoEditor.py:1601 +#: flatcamEditors/FlatCAMGrbEditor.py:6111 msgid "Skew on X axis ..." msgstr "Skew on X axis ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1559 -#: flatcamEditors/FlatCAMGrbEditor.py:6091 +#: flatcamEditors/FlatCAMGeoEditor.py:1611 +#: flatcamEditors/FlatCAMGrbEditor.py:6120 msgid "Geometry shape skew on X axis done" msgstr "Forme de la géométrie inclinée sur l'axe X terminée" -#: flatcamEditors/FlatCAMGeoEditor.py:1563 +#: flatcamEditors/FlatCAMGeoEditor.py:1615 msgid "Geometry shape skew on X axis canceled" msgstr "Géométrie inclinée sur l'axe X annulée" -#: flatcamEditors/FlatCAMGeoEditor.py:1566 -#: flatcamEditors/FlatCAMGrbEditor.py:6097 +#: flatcamEditors/FlatCAMGeoEditor.py:1618 +#: flatcamEditors/FlatCAMGrbEditor.py:6126 msgid "Skew on Y axis ..." msgstr "Inclinez sur l'axe Y ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1576 -#: flatcamEditors/FlatCAMGrbEditor.py:6106 +#: flatcamEditors/FlatCAMGeoEditor.py:1628 +#: flatcamEditors/FlatCAMGrbEditor.py:6135 msgid "Geometry shape skew on Y axis done" msgstr "Géométrie inclinée sur l'axe des Y" -#: flatcamEditors/FlatCAMGeoEditor.py:1580 +#: flatcamEditors/FlatCAMGeoEditor.py:1632 msgid "Geometry shape skew on Y axis canceled" msgstr "Géométrie inclinée sur l'axe des Y oblitérée" -#: flatcamEditors/FlatCAMGeoEditor.py:1951 -#: flatcamEditors/FlatCAMGeoEditor.py:2016 -#: flatcamEditors/FlatCAMGrbEditor.py:1436 -#: flatcamEditors/FlatCAMGrbEditor.py:1514 +#: flatcamEditors/FlatCAMGeoEditor.py:2009 +#: flatcamEditors/FlatCAMGeoEditor.py:2080 +#: flatcamEditors/FlatCAMGrbEditor.py:1435 +#: flatcamEditors/FlatCAMGrbEditor.py:1513 msgid "Click on Center point ..." msgstr "Cliquez sur Point central ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1958 -#: flatcamEditors/FlatCAMGrbEditor.py:1446 +#: flatcamEditors/FlatCAMGeoEditor.py:2022 +#: flatcamEditors/FlatCAMGrbEditor.py:1445 msgid "Click on Perimeter point to complete ..." msgstr "Cliquez sur le point du périmètre pour terminer ..." -#: flatcamEditors/FlatCAMGeoEditor.py:1990 +#: flatcamEditors/FlatCAMGeoEditor.py:2054 msgid "Done. Adding Circle completed." msgstr "Terminé. Ajout du cercle terminé." -#: flatcamEditors/FlatCAMGeoEditor.py:2038 -#: flatcamEditors/FlatCAMGrbEditor.py:1547 +#: flatcamEditors/FlatCAMGeoEditor.py:2108 +#: flatcamEditors/FlatCAMGrbEditor.py:1546 msgid "Click on Start point ..." msgstr "Cliquez sur le point de départ ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2040 -#: flatcamEditors/FlatCAMGrbEditor.py:1549 +#: flatcamEditors/FlatCAMGeoEditor.py:2110 +#: flatcamEditors/FlatCAMGrbEditor.py:1548 msgid "Click on Point3 ..." msgstr "Cliquez sur le point 3 ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2042 -#: flatcamEditors/FlatCAMGrbEditor.py:1551 +#: flatcamEditors/FlatCAMGeoEditor.py:2112 +#: flatcamEditors/FlatCAMGrbEditor.py:1550 msgid "Click on Stop point ..." msgstr "Cliquez sur le point d'arrêt ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2047 -#: flatcamEditors/FlatCAMGrbEditor.py:1556 +#: flatcamEditors/FlatCAMGeoEditor.py:2117 +#: flatcamEditors/FlatCAMGrbEditor.py:1555 msgid "Click on Stop point to complete ..." msgstr "Cliquez sur le point d'arrêt pour terminer ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2049 -#: flatcamEditors/FlatCAMGrbEditor.py:1558 +#: flatcamEditors/FlatCAMGeoEditor.py:2119 +#: flatcamEditors/FlatCAMGrbEditor.py:1557 msgid "Click on Point2 to complete ..." msgstr "Cliquez sur le point 2 pour compléter ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2051 -#: flatcamEditors/FlatCAMGrbEditor.py:1560 +#: flatcamEditors/FlatCAMGeoEditor.py:2121 +#: flatcamEditors/FlatCAMGrbEditor.py:1559 msgid "Click on Center point to complete ..." msgstr "Cliquez sur le point central pour terminer ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2063 +#: flatcamEditors/FlatCAMGeoEditor.py:2133 #, python-format msgid "Direction: %s" msgstr "Direction: %s" -#: flatcamEditors/FlatCAMGeoEditor.py:2077 -#: flatcamEditors/FlatCAMGrbEditor.py:1586 +#: flatcamEditors/FlatCAMGeoEditor.py:2147 +#: flatcamEditors/FlatCAMGrbEditor.py:1585 msgid "Mode: Start -> Stop -> Center. Click on Start point ..." msgstr "" "Mode: Démarrer -> Arrêter -> Centre. Cliquez sur le point de départ ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2080 -#: flatcamEditors/FlatCAMGrbEditor.py:1589 +#: flatcamEditors/FlatCAMGeoEditor.py:2150 +#: flatcamEditors/FlatCAMGrbEditor.py:1588 msgid "Mode: Point1 -> Point3 -> Point2. Click on Point1 ..." msgstr "Mode: Point 1 -> Point 3 -> Point 2. Cliquez sur Point 1 ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2083 -#: flatcamEditors/FlatCAMGrbEditor.py:1592 +#: flatcamEditors/FlatCAMGeoEditor.py:2153 +#: flatcamEditors/FlatCAMGrbEditor.py:1591 msgid "Mode: Center -> Start -> Stop. Click on Center point ..." msgstr "Mode: Centre -> Démarrer -> Arrêter. Cliquez sur Point central ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2224 +#: flatcamEditors/FlatCAMGeoEditor.py:2294 msgid "Done. Arc completed." msgstr "Terminé. Arc terminé." -#: flatcamEditors/FlatCAMGeoEditor.py:2255 -#: flatcamEditors/FlatCAMGeoEditor.py:2322 +#: flatcamEditors/FlatCAMGeoEditor.py:2325 +#: flatcamEditors/FlatCAMGeoEditor.py:2398 msgid "Click on 1st corner ..." msgstr "Cliquez sur le 1er coin ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2261 +#: flatcamEditors/FlatCAMGeoEditor.py:2337 msgid "Click on opposite corner to complete ..." msgstr "Cliquez sur le coin opposé pour terminer ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2291 +#: flatcamEditors/FlatCAMGeoEditor.py:2367 msgid "Done. Rectangle completed." msgstr "Terminé. Rectangle complété." -#: flatcamEditors/FlatCAMGeoEditor.py:2329 +#: flatcamEditors/FlatCAMGeoEditor.py:2411 flatcamTools/ToolNCC.py:1728 +#: flatcamTools/ToolPaint.py:1623 msgid "Click on next Point or click right mouse button to complete ..." msgstr "" "Cliquez sur le point suivant ou cliquez avec le bouton droit de la souris " "pour terminer ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2360 +#: flatcamEditors/FlatCAMGeoEditor.py:2442 msgid "Done. Polygon completed." msgstr "Terminé. Le polygone est terminé." -#: flatcamEditors/FlatCAMGeoEditor.py:2374 -#: flatcamEditors/FlatCAMGeoEditor.py:2439 -#: flatcamEditors/FlatCAMGrbEditor.py:1112 -#: flatcamEditors/FlatCAMGrbEditor.py:1323 +#: flatcamEditors/FlatCAMGeoEditor.py:2456 +#: flatcamEditors/FlatCAMGeoEditor.py:2521 +#: flatcamEditors/FlatCAMGrbEditor.py:1111 +#: flatcamEditors/FlatCAMGrbEditor.py:1322 msgid "Backtracked one point ..." msgstr "Retracé un point ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2417 +#: flatcamEditors/FlatCAMGeoEditor.py:2499 msgid "Done. Path completed." msgstr "Terminé. Chemin complété." -#: flatcamEditors/FlatCAMGeoEditor.py:2580 +#: flatcamEditors/FlatCAMGeoEditor.py:2658 +msgid "No shape selected. Select a shape to explode" +msgstr "Aucune forme sélectionnée. Sélectionnez une forme à exploser" + +#: flatcamEditors/FlatCAMGeoEditor.py:2691 msgid "Done. Polygons exploded into lines." msgstr "Terminé. Les polygones ont explosé en lignes." -#: flatcamEditors/FlatCAMGeoEditor.py:2612 +#: flatcamEditors/FlatCAMGeoEditor.py:2723 msgid "MOVE: No shape selected. Select a shape to move" msgstr "Déplacer: Aucune forme sélectionnée. Sélectionnez une forme à déplacer" -#: flatcamEditors/FlatCAMGeoEditor.py:2615 -#: flatcamEditors/FlatCAMGeoEditor.py:2628 +#: flatcamEditors/FlatCAMGeoEditor.py:2726 +#: flatcamEditors/FlatCAMGeoEditor.py:2746 msgid " MOVE: Click on reference point ..." msgstr " Déplacer: Cliquez sur le point de référence ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2619 +#: flatcamEditors/FlatCAMGeoEditor.py:2731 msgid " Click on destination point ..." msgstr " Cliquez sur le point de destination ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2653 +#: flatcamEditors/FlatCAMGeoEditor.py:2771 msgid "Done. Geometry(s) Move completed." msgstr "Terminé. Géométrie (s) Déplacement terminé." -#: flatcamEditors/FlatCAMGeoEditor.py:2783 +#: flatcamEditors/FlatCAMGeoEditor.py:2904 msgid "Done. Geometry(s) Copy completed." msgstr "Terminé. Géométrie (s) Copie terminée." -#: flatcamEditors/FlatCAMGeoEditor.py:2811 -#: flatcamEditors/FlatCAMGrbEditor.py:898 +#: flatcamEditors/FlatCAMGeoEditor.py:2935 +#: flatcamEditors/FlatCAMGrbEditor.py:897 msgid "Click on 1st point ..." msgstr "Cliquez sur le 1er point ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2829 +#: flatcamEditors/FlatCAMGeoEditor.py:2959 msgid "" "Font not supported. Only Regular, Bold, Italic and BoldItalic are supported. " "Error" @@ -4429,96 +4733,132 @@ msgstr "" "Police non supportée. Seuls les formats Normal, Gras, Italique et " "GrasItalique sont pris en charge. Erreur" -#: flatcamEditors/FlatCAMGeoEditor.py:2837 +#: flatcamEditors/FlatCAMGeoEditor.py:2967 msgid "No text to add." msgstr "Pas de texte à ajouter." -#: flatcamEditors/FlatCAMGeoEditor.py:2844 +#: flatcamEditors/FlatCAMGeoEditor.py:2977 msgid " Done. Adding Text completed." msgstr " Terminé. Ajout de texte terminé." -#: flatcamEditors/FlatCAMGeoEditor.py:2881 +#: flatcamEditors/FlatCAMGeoEditor.py:3014 msgid "Create buffer geometry ..." msgstr "Créer une géométrie tampon ..." -#: flatcamEditors/FlatCAMGeoEditor.py:2892 -#: flatcamEditors/FlatCAMGeoEditor.py:2922 -#: flatcamEditors/FlatCAMGeoEditor.py:2952 -msgid "Buffer cancelled. No shape selected." -msgstr "Tampon annulé. Aucune forme sélectionnée." - -#: flatcamEditors/FlatCAMGeoEditor.py:2917 -#: flatcamEditors/FlatCAMGrbEditor.py:4950 +#: flatcamEditors/FlatCAMGeoEditor.py:3049 +#: flatcamEditors/FlatCAMGrbEditor.py:4994 msgid "Done. Buffer Tool completed." msgstr "Terminé. L'outil Tampon est terminé." -#: flatcamEditors/FlatCAMGeoEditor.py:2947 +#: flatcamEditors/FlatCAMGeoEditor.py:3077 msgid "Done. Buffer Int Tool completed." msgstr "Terminé. L'outil Intérieur du Tampon est terminé." -#: flatcamEditors/FlatCAMGeoEditor.py:2977 +#: flatcamEditors/FlatCAMGeoEditor.py:3105 msgid "Done. Buffer Ext Tool completed." msgstr "Terminé. L'outil Extérieur du Tampon est terminé." -#: flatcamEditors/FlatCAMGeoEditor.py:3023 -#: flatcamEditors/FlatCAMGrbEditor.py:2152 +#: flatcamEditors/FlatCAMGeoEditor.py:3154 +#: flatcamEditors/FlatCAMGrbEditor.py:2151 msgid "Select a shape to act as deletion area ..." msgstr "Sélectionnez une forme pour agir comme zone de suppression ..." -#: flatcamEditors/FlatCAMGeoEditor.py:3025 -#: flatcamEditors/FlatCAMGeoEditor.py:3045 -#: flatcamEditors/FlatCAMGeoEditor.py:3051 -#: flatcamEditors/FlatCAMGrbEditor.py:2154 +#: flatcamEditors/FlatCAMGeoEditor.py:3156 +#: flatcamEditors/FlatCAMGeoEditor.py:3182 +#: flatcamEditors/FlatCAMGeoEditor.py:3188 +#: flatcamEditors/FlatCAMGrbEditor.py:2153 msgid "Click to pick-up the erase shape..." msgstr "Cliquez pour récupérer la forme à effacer ..." -#: flatcamEditors/FlatCAMGeoEditor.py:3055 -#: flatcamEditors/FlatCAMGrbEditor.py:2213 +#: flatcamEditors/FlatCAMGeoEditor.py:3192 +#: flatcamEditors/FlatCAMGrbEditor.py:2212 msgid "Click to erase ..." msgstr "Cliquez pour effacer ..." -#: flatcamEditors/FlatCAMGeoEditor.py:3084 -#: flatcamEditors/FlatCAMGrbEditor.py:2246 +#: flatcamEditors/FlatCAMGeoEditor.py:3221 +#: flatcamEditors/FlatCAMGrbEditor.py:2245 msgid "Done. Eraser tool action completed." msgstr "Terminé. Action de l’outil gomme terminée." -#: flatcamEditors/FlatCAMGeoEditor.py:3131 +#: flatcamEditors/FlatCAMGeoEditor.py:3271 msgid "Create Paint geometry ..." msgstr "Créer une géométrie de peinture ..." -#: flatcamEditors/FlatCAMGeoEditor.py:3144 -#: flatcamEditors/FlatCAMGrbEditor.py:2402 +#: flatcamEditors/FlatCAMGeoEditor.py:3284 +#: flatcamEditors/FlatCAMGrbEditor.py:2408 msgid "Shape transformations ..." msgstr "Transformations de forme ..." -#: flatcamEditors/FlatCAMGeoEditor.py:3763 +#: flatcamEditors/FlatCAMGeoEditor.py:3340 flatcamGUI/PreferencesUI.py:4636 +msgid "Geometry Editor" +msgstr "Éditeur de Géométrie" + +#: flatcamEditors/FlatCAMGeoEditor.py:3346 +#: flatcamEditors/FlatCAMGrbEditor.py:2486 +#: flatcamEditors/FlatCAMGrbEditor.py:3846 flatcamGUI/ObjectUI.py:262 +#: flatcamGUI/ObjectUI.py:1495 flatcamGUI/ObjectUI.py:2244 +#: flatcamTools/ToolCutOut.py:96 +msgid "Type" +msgstr "Type" + +#: flatcamEditors/FlatCAMGeoEditor.py:3346 flatcamGUI/ObjectUI.py:217 +#: flatcamGUI/ObjectUI.py:741 flatcamGUI/ObjectUI.py:1431 +#: flatcamGUI/ObjectUI.py:2153 flatcamGUI/ObjectUI.py:2457 +#: flatcamGUI/ObjectUI.py:2524 flatcamTools/ToolCalibration.py:234 +#: flatcamTools/ToolFiducials.py:73 +msgid "Name" +msgstr "Nom" + +#: flatcamEditors/FlatCAMGeoEditor.py:3588 +msgid "Ring" +msgstr "L'anneau" + +#: flatcamEditors/FlatCAMGeoEditor.py:3590 +msgid "Line" +msgstr "Ligne" + +#: flatcamEditors/FlatCAMGeoEditor.py:3592 flatcamGUI/FlatCAMGUI.py:2187 +#: flatcamGUI/PreferencesUI.py:5607 flatcamGUI/PreferencesUI.py:6131 +#: flatcamTools/ToolNCC.py:584 flatcamTools/ToolPaint.py:528 +msgid "Polygon" +msgstr "Polygone" + +#: flatcamEditors/FlatCAMGeoEditor.py:3594 +msgid "Multi-Line" +msgstr "Multi-ligne" + +#: flatcamEditors/FlatCAMGeoEditor.py:3596 +msgid "Multi-Polygon" +msgstr "Multi-polygone" + +#: flatcamEditors/FlatCAMGeoEditor.py:3603 +msgid "Geo Elem" +msgstr "Élém. de Géo" + +#: flatcamEditors/FlatCAMGeoEditor.py:4076 msgid "Editing MultiGeo Geometry, tool" msgstr "Modification de la géométrie MultiGeo, outil" -#: flatcamEditors/FlatCAMGeoEditor.py:3765 +#: flatcamEditors/FlatCAMGeoEditor.py:4078 msgid "with diameter" msgstr "avec diamètre" -#: flatcamEditors/FlatCAMGeoEditor.py:4169 -msgid "Copy cancelled. No shape selected." -msgstr "Copie annulée. Aucune forme sélectionnée." - -#: flatcamEditors/FlatCAMGeoEditor.py:4176 flatcamGUI/FlatCAMGUI.py:3472 -#: flatcamGUI/FlatCAMGUI.py:3519 flatcamGUI/FlatCAMGUI.py:3538 -#: flatcamGUI/FlatCAMGUI.py:3679 flatcamGUI/FlatCAMGUI.py:3719 -#: flatcamGUI/FlatCAMGUI.py:3732 flatcamGUI/FlatCAMGUI.py:3749 +#: flatcamEditors/FlatCAMGeoEditor.py:4509 flatcamGUI/FlatCAMGUI.py:3695 +#: flatcamGUI/FlatCAMGUI.py:3741 flatcamGUI/FlatCAMGUI.py:3759 +#: flatcamGUI/FlatCAMGUI.py:3899 flatcamGUI/FlatCAMGUI.py:3938 +#: flatcamGUI/FlatCAMGUI.py:3950 flatcamGUI/FlatCAMGUI.py:3967 msgid "Click on target point." msgstr "Cliquez sur le point cible." -#: flatcamEditors/FlatCAMGeoEditor.py:4479 -#: flatcamEditors/FlatCAMGeoEditor.py:4514 +#: flatcamEditors/FlatCAMGeoEditor.py:4823 +#: flatcamEditors/FlatCAMGeoEditor.py:4858 msgid "A selection of at least 2 geo items is required to do Intersection." msgstr "" "Une sélection d'au moins 2 éléments géographiques est requise pour effectuer " "Intersection." -#: flatcamEditors/FlatCAMGeoEditor.py:4600 -#: flatcamEditors/FlatCAMGeoEditor.py:4704 +#: flatcamEditors/FlatCAMGeoEditor.py:4944 +#: flatcamEditors/FlatCAMGeoEditor.py:5048 msgid "" "Negative buffer value is not accepted. Use Buffer interior to generate an " "'inside' shape" @@ -4526,61 +4866,61 @@ msgstr "" "La valeur de tampon négative n'est pas acceptée. Utiliser l'intérieur du " "tampon pour générer une forme «intérieure»" -#: flatcamEditors/FlatCAMGeoEditor.py:4610 -#: flatcamEditors/FlatCAMGeoEditor.py:4663 -#: flatcamEditors/FlatCAMGeoEditor.py:4713 +#: flatcamEditors/FlatCAMGeoEditor.py:4954 +#: flatcamEditors/FlatCAMGeoEditor.py:5007 +#: flatcamEditors/FlatCAMGeoEditor.py:5057 msgid "Nothing selected for buffering." msgstr "Aucune sélection pour la mise en mémoire tampon." -#: flatcamEditors/FlatCAMGeoEditor.py:4615 -#: flatcamEditors/FlatCAMGeoEditor.py:4667 -#: flatcamEditors/FlatCAMGeoEditor.py:4718 +#: flatcamEditors/FlatCAMGeoEditor.py:4959 +#: flatcamEditors/FlatCAMGeoEditor.py:5011 +#: flatcamEditors/FlatCAMGeoEditor.py:5062 msgid "Invalid distance for buffering." msgstr "Distance non valide pour la mise en mémoire tampon." -#: flatcamEditors/FlatCAMGeoEditor.py:4639 -#: flatcamEditors/FlatCAMGeoEditor.py:4738 +#: flatcamEditors/FlatCAMGeoEditor.py:4983 +#: flatcamEditors/FlatCAMGeoEditor.py:5082 msgid "Failed, the result is empty. Choose a different buffer value." msgstr "" "Echec, le résultat est vide. Choisissez une valeur de tampon différente." -#: flatcamEditors/FlatCAMGeoEditor.py:4650 +#: flatcamEditors/FlatCAMGeoEditor.py:4994 msgid "Full buffer geometry created." msgstr "Géométrie de tampon complète créée." -#: flatcamEditors/FlatCAMGeoEditor.py:4656 +#: flatcamEditors/FlatCAMGeoEditor.py:5000 msgid "Negative buffer value is not accepted." msgstr "La valeur de tampon négative n'est pas acceptée." -#: flatcamEditors/FlatCAMGeoEditor.py:4687 +#: flatcamEditors/FlatCAMGeoEditor.py:5031 msgid "Failed, the result is empty. Choose a smaller buffer value." msgstr "" "Echec, le résultat est vide. Choisissez une valeur de tampon plus petite." -#: flatcamEditors/FlatCAMGeoEditor.py:4697 +#: flatcamEditors/FlatCAMGeoEditor.py:5041 msgid "Interior buffer geometry created." msgstr "Géométrie du tampon intérieur créée." -#: flatcamEditors/FlatCAMGeoEditor.py:4748 +#: flatcamEditors/FlatCAMGeoEditor.py:5092 msgid "Exterior buffer geometry created." msgstr "Géométrie tampon externe créée." -#: flatcamEditors/FlatCAMGeoEditor.py:4754 +#: flatcamEditors/FlatCAMGeoEditor.py:5098 #, python-format -msgid "Could not do Paint. Overlap value has to be less than 1.00 (100%%)." +msgid "Could not do Paint. Overlap value has to be less than 100%%." msgstr "" -"Impossible de faire de la peinture. La valeur de chevauchement doit être " -"inférieure à 1,00 (100%%)." +"Impossible de peindre. La valeur de chevauchement doit être inférieure à 100 " +"%%." -#: flatcamEditors/FlatCAMGeoEditor.py:4761 +#: flatcamEditors/FlatCAMGeoEditor.py:5105 msgid "Nothing selected for painting." msgstr "Rien de sélectionné pour la peinture." -#: flatcamEditors/FlatCAMGeoEditor.py:4767 +#: flatcamEditors/FlatCAMGeoEditor.py:5111 msgid "Invalid value for" msgstr "Invalid value for" -#: flatcamEditors/FlatCAMGeoEditor.py:4826 +#: flatcamEditors/FlatCAMGeoEditor.py:5170 msgid "" "Could not do Paint. Try a different combination of parameters. Or a " "different method of Paint" @@ -4588,7 +4928,7 @@ msgstr "" "Impossible de faire de la peinture. Essayez une combinaison de paramètres " "différente. Ou une autre méthode de peinture" -#: flatcamEditors/FlatCAMGeoEditor.py:4840 +#: flatcamEditors/FlatCAMGeoEditor.py:5181 msgid "Paint done." msgstr "Peinture faite." @@ -4604,7 +4944,7 @@ msgid "Aperture size is zero. It needs to be greater than zero." msgstr "La taille de l'ouverture est zéro. Il doit être supérieur à zéro." #: flatcamEditors/FlatCAMGrbEditor.py:371 -#: flatcamEditors/FlatCAMGrbEditor.py:685 +#: flatcamEditors/FlatCAMGrbEditor.py:684 msgid "" "Incompatible aperture type. Select an aperture with type 'C', 'R' or 'O'." msgstr "" @@ -4625,173 +4965,167 @@ msgstr "" msgid "Click on the Pad Circular Array Start position" msgstr "Cliquez sur le Tableau circulaire du Pad position de départ" -#: flatcamEditors/FlatCAMGrbEditor.py:711 +#: flatcamEditors/FlatCAMGrbEditor.py:710 msgid "Too many Pads for the selected spacing angle." msgstr "Trop de pads pour l'angle d'espacement sélectionné." -#: flatcamEditors/FlatCAMGrbEditor.py:734 +#: flatcamEditors/FlatCAMGrbEditor.py:733 msgid "Done. Pad Array added." msgstr "Terminé. Pad Tableau ajouté." -#: flatcamEditors/FlatCAMGrbEditor.py:759 +#: flatcamEditors/FlatCAMGrbEditor.py:758 msgid "Select shape(s) and then click ..." msgstr "Sélectionnez forme (s) puis cliquez sur ..." -#: flatcamEditors/FlatCAMGrbEditor.py:771 +#: flatcamEditors/FlatCAMGrbEditor.py:770 msgid "Failed. Nothing selected." msgstr "Échoué. Rien de sélectionné." -#: flatcamEditors/FlatCAMGrbEditor.py:787 +#: flatcamEditors/FlatCAMGrbEditor.py:786 msgid "" "Failed. Poligonize works only on geometries belonging to the same aperture." msgstr "" "Échoué. Poligonize ne fonctionne que sur les géométries appartenant à la " "même ouverture." -#: flatcamEditors/FlatCAMGrbEditor.py:841 +#: flatcamEditors/FlatCAMGrbEditor.py:840 msgid "Done. Poligonize completed." msgstr "Terminé. Polygoniser terminé." -#: flatcamEditors/FlatCAMGrbEditor.py:896 -#: flatcamEditors/FlatCAMGrbEditor.py:1129 -#: flatcamEditors/FlatCAMGrbEditor.py:1153 +#: flatcamEditors/FlatCAMGrbEditor.py:895 +#: flatcamEditors/FlatCAMGrbEditor.py:1128 +#: flatcamEditors/FlatCAMGrbEditor.py:1152 msgid "Corner Mode 1: 45 degrees ..." msgstr "Mode d'angle 1: 45 degrés ..." -#: flatcamEditors/FlatCAMGrbEditor.py:908 -#: flatcamEditors/FlatCAMGrbEditor.py:1238 +#: flatcamEditors/FlatCAMGrbEditor.py:907 +#: flatcamEditors/FlatCAMGrbEditor.py:1237 msgid "Click on next Point or click Right mouse button to complete ..." msgstr "" "Cliquez sur le prochain point ou cliquez avec le bouton droit de la souris " "pour terminer ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1117 -#: flatcamEditors/FlatCAMGrbEditor.py:1150 +#: flatcamEditors/FlatCAMGrbEditor.py:1116 +#: flatcamEditors/FlatCAMGrbEditor.py:1149 msgid "Corner Mode 2: Reverse 45 degrees ..." msgstr "Mode de Coin 2: Inverse de 45 degrés ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1120 -#: flatcamEditors/FlatCAMGrbEditor.py:1147 +#: flatcamEditors/FlatCAMGrbEditor.py:1119 +#: flatcamEditors/FlatCAMGrbEditor.py:1146 msgid "Corner Mode 3: 90 degrees ..." msgstr "Mode de Coin 3: 90 degrés ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1123 -#: flatcamEditors/FlatCAMGrbEditor.py:1144 +#: flatcamEditors/FlatCAMGrbEditor.py:1122 +#: flatcamEditors/FlatCAMGrbEditor.py:1143 msgid "Corner Mode 4: Reverse 90 degrees ..." msgstr "Mode de Coin 4: inverser de 90 degrés ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1126 -#: flatcamEditors/FlatCAMGrbEditor.py:1141 +#: flatcamEditors/FlatCAMGrbEditor.py:1125 +#: flatcamEditors/FlatCAMGrbEditor.py:1140 msgid "Corner Mode 5: Free angle ..." msgstr "Mode de Coin 5: Angle libre ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1183 -#: flatcamEditors/FlatCAMGrbEditor.py:1359 -#: flatcamEditors/FlatCAMGrbEditor.py:1398 +#: flatcamEditors/FlatCAMGrbEditor.py:1182 +#: flatcamEditors/FlatCAMGrbEditor.py:1358 +#: flatcamEditors/FlatCAMGrbEditor.py:1397 msgid "Track Mode 1: 45 degrees ..." msgstr "Mode de Piste 1: 45 degrés ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1339 -#: flatcamEditors/FlatCAMGrbEditor.py:1393 +#: flatcamEditors/FlatCAMGrbEditor.py:1338 +#: flatcamEditors/FlatCAMGrbEditor.py:1392 msgid "Track Mode 2: Reverse 45 degrees ..." msgstr "Mode de Piste 2: Recul de 45 degrés ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1344 -#: flatcamEditors/FlatCAMGrbEditor.py:1388 +#: flatcamEditors/FlatCAMGrbEditor.py:1343 +#: flatcamEditors/FlatCAMGrbEditor.py:1387 msgid "Track Mode 3: 90 degrees ..." msgstr "Mode de Piste 3: 90 degrés ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1349 -#: flatcamEditors/FlatCAMGrbEditor.py:1383 +#: flatcamEditors/FlatCAMGrbEditor.py:1348 +#: flatcamEditors/FlatCAMGrbEditor.py:1382 msgid "Track Mode 4: Reverse 90 degrees ..." msgstr "Mode de Piste 4: Recul de 90 degrés ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1354 -#: flatcamEditors/FlatCAMGrbEditor.py:1378 +#: flatcamEditors/FlatCAMGrbEditor.py:1353 +#: flatcamEditors/FlatCAMGrbEditor.py:1377 msgid "Track Mode 5: Free angle ..." msgstr "Mode de Piste 5: Angle libre ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1779 +#: flatcamEditors/FlatCAMGrbEditor.py:1778 msgid "Scale the selected Gerber apertures ..." msgstr "Mettez à l'échelle les ouvertures de Gerber sélectionnées ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1821 +#: flatcamEditors/FlatCAMGrbEditor.py:1820 msgid "Buffer the selected apertures ..." msgstr "Tamponner les ouvertures sélectionnées ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1863 +#: flatcamEditors/FlatCAMGrbEditor.py:1862 msgid "Mark polygon areas in the edited Gerber ..." msgstr "Marquer les zones polygonales dans le Gerber édité ..." -#: flatcamEditors/FlatCAMGrbEditor.py:1929 +#: flatcamEditors/FlatCAMGrbEditor.py:1928 msgid "Nothing selected to move" msgstr "Rien de sélectionné pour bouger" -#: flatcamEditors/FlatCAMGrbEditor.py:2054 +#: flatcamEditors/FlatCAMGrbEditor.py:2053 msgid "Done. Apertures Move completed." msgstr "Terminé. Déplacement des ouvertures terminé." -#: flatcamEditors/FlatCAMGrbEditor.py:2136 +#: flatcamEditors/FlatCAMGrbEditor.py:2135 msgid "Done. Apertures copied." msgstr "Terminé. Ouvertures copiées." -#: flatcamEditors/FlatCAMGrbEditor.py:2447 flatcamGUI/FlatCAMGUI.py:2110 -#: flatcamGUI/PreferencesUI.py:2443 +#: flatcamEditors/FlatCAMGrbEditor.py:2453 flatcamGUI/FlatCAMGUI.py:2218 +#: flatcamGUI/PreferencesUI.py:2623 msgid "Gerber Editor" msgstr "Gerber éditeur" -#: flatcamEditors/FlatCAMGrbEditor.py:2467 flatcamGUI/ObjectUI.py:223 -#: flatcamTools/ToolProperties.py:156 +#: flatcamEditors/FlatCAMGrbEditor.py:2473 flatcamGUI/ObjectUI.py:227 +#: flatcamTools/ToolProperties.py:159 msgid "Apertures" msgstr "Les ouvertures" -#: flatcamEditors/FlatCAMGrbEditor.py:2469 flatcamGUI/ObjectUI.py:225 +#: flatcamEditors/FlatCAMGrbEditor.py:2475 flatcamGUI/ObjectUI.py:229 msgid "Apertures Table for the Gerber Object." msgstr "Tableau des Ouvertures pour l'objet Gerber." -#: flatcamEditors/FlatCAMGrbEditor.py:2480 -#: flatcamEditors/FlatCAMGrbEditor.py:3832 flatcamGUI/ObjectUI.py:258 +#: flatcamEditors/FlatCAMGrbEditor.py:2486 +#: flatcamEditors/FlatCAMGrbEditor.py:3846 flatcamGUI/ObjectUI.py:262 msgid "Code" msgstr "Code" -#: flatcamEditors/FlatCAMGrbEditor.py:2480 -#: flatcamEditors/FlatCAMGrbEditor.py:3832 flatcamGUI/ObjectUI.py:258 -#: flatcamGUI/ObjectUI.py:1217 flatcamGUI/ObjectUI.py:1916 -msgid "Type" -msgstr "Type" - -#: flatcamEditors/FlatCAMGrbEditor.py:2480 -#: flatcamEditors/FlatCAMGrbEditor.py:3832 flatcamGUI/ObjectUI.py:258 -#: flatcamGUI/PreferencesUI.py:1009 flatcamGUI/PreferencesUI.py:7270 -#: flatcamGUI/PreferencesUI.py:7299 flatcamGUI/PreferencesUI.py:7401 -#: flatcamTools/ToolCopperThieving.py:260 -#: flatcamTools/ToolCopperThieving.py:300 flatcamTools/ToolFiducials.py:156 +#: flatcamEditors/FlatCAMGrbEditor.py:2486 +#: flatcamEditors/FlatCAMGrbEditor.py:3846 flatcamGUI/ObjectUI.py:262 +#: flatcamGUI/PreferencesUI.py:1184 flatcamGUI/PreferencesUI.py:7776 +#: flatcamGUI/PreferencesUI.py:7805 flatcamGUI/PreferencesUI.py:7907 +#: flatcamTools/ToolCopperThieving.py:262 +#: flatcamTools/ToolCopperThieving.py:302 flatcamTools/ToolFiducials.py:156 msgid "Size" msgstr "Taille" -#: flatcamEditors/FlatCAMGrbEditor.py:2480 -#: flatcamEditors/FlatCAMGrbEditor.py:3832 flatcamGUI/ObjectUI.py:258 +#: flatcamEditors/FlatCAMGrbEditor.py:2486 +#: flatcamEditors/FlatCAMGrbEditor.py:3846 flatcamGUI/ObjectUI.py:262 msgid "Dim" msgstr "Dim" -#: flatcamEditors/FlatCAMGrbEditor.py:2484 flatcamGUI/ObjectUI.py:262 +#: flatcamEditors/FlatCAMGrbEditor.py:2490 flatcamGUI/ObjectUI.py:266 msgid "Index" msgstr "Indice" -#: flatcamEditors/FlatCAMGrbEditor.py:2486 -#: flatcamEditors/FlatCAMGrbEditor.py:2515 flatcamGUI/ObjectUI.py:264 +#: flatcamEditors/FlatCAMGrbEditor.py:2492 +#: flatcamEditors/FlatCAMGrbEditor.py:2521 flatcamGUI/ObjectUI.py:268 msgid "Aperture Code" msgstr "Code d'Ouverture" -#: flatcamEditors/FlatCAMGrbEditor.py:2488 flatcamGUI/ObjectUI.py:266 +#: flatcamEditors/FlatCAMGrbEditor.py:2494 flatcamGUI/ObjectUI.py:270 msgid "Type of aperture: circular, rectangle, macros etc" msgstr "Type d'ouverture: circulaire, rectangle, macros, etc" -#: flatcamEditors/FlatCAMGrbEditor.py:2490 flatcamGUI/ObjectUI.py:268 +#: flatcamEditors/FlatCAMGrbEditor.py:2496 flatcamGUI/ObjectUI.py:272 msgid "Aperture Size:" msgstr "Taille d'Ouverture:" -#: flatcamEditors/FlatCAMGrbEditor.py:2492 flatcamGUI/ObjectUI.py:270 +#: flatcamEditors/FlatCAMGrbEditor.py:2498 flatcamGUI/ObjectUI.py:274 msgid "" "Aperture Dimensions:\n" " - (width, height) for R, O type.\n" @@ -4801,15 +5135,15 @@ msgstr "" "  - (largeur, hauteur) pour le type R, O.\n" "  - (dia, nVertices) pour le type P" -#: flatcamEditors/FlatCAMGrbEditor.py:2516 flatcamGUI/PreferencesUI.py:2474 +#: flatcamEditors/FlatCAMGrbEditor.py:2522 flatcamGUI/PreferencesUI.py:2654 msgid "Code for the new aperture" msgstr "Code pour la nouvelle ouverture" -#: flatcamEditors/FlatCAMGrbEditor.py:2525 +#: flatcamEditors/FlatCAMGrbEditor.py:2531 msgid "Aperture Size" msgstr "Taille d'ouverture" -#: flatcamEditors/FlatCAMGrbEditor.py:2527 +#: flatcamEditors/FlatCAMGrbEditor.py:2533 msgid "" "Size for the new aperture.\n" "If aperture type is 'R' or 'O' then\n" @@ -4823,11 +5157,11 @@ msgstr "" "calculé comme:\n" "sqrt (largeur ** 2 + hauteur ** 2)" -#: flatcamEditors/FlatCAMGrbEditor.py:2541 +#: flatcamEditors/FlatCAMGrbEditor.py:2547 msgid "Aperture Type" msgstr "Type d'ouverture" -#: flatcamEditors/FlatCAMGrbEditor.py:2543 +#: flatcamEditors/FlatCAMGrbEditor.py:2549 msgid "" "Select the type of new aperture. Can be:\n" "C = circular\n" @@ -4839,11 +5173,11 @@ msgstr "" "R = rectangulaire\n" "O = oblong" -#: flatcamEditors/FlatCAMGrbEditor.py:2554 +#: flatcamEditors/FlatCAMGrbEditor.py:2560 msgid "Aperture Dim" msgstr "Dim. d'Ouverture" -#: flatcamEditors/FlatCAMGrbEditor.py:2556 +#: flatcamEditors/FlatCAMGrbEditor.py:2562 msgid "" "Dimensions for the new aperture.\n" "Active only for rectangular apertures (type R).\n" @@ -4853,39 +5187,39 @@ msgstr "" "Actif uniquement pour les ouvertures rectangulaires (type R).\n" "Le format est (largeur, hauteur)" -#: flatcamEditors/FlatCAMGrbEditor.py:2565 +#: flatcamEditors/FlatCAMGrbEditor.py:2571 msgid "Add/Delete Aperture" msgstr "Ajouter / Supprimer une Ouverture" -#: flatcamEditors/FlatCAMGrbEditor.py:2567 +#: flatcamEditors/FlatCAMGrbEditor.py:2573 msgid "Add/Delete an aperture in the aperture table" msgstr "Ajouter / Supprimer une ouverture dans la table des ouvertures" -#: flatcamEditors/FlatCAMGrbEditor.py:2576 +#: flatcamEditors/FlatCAMGrbEditor.py:2582 msgid "Add a new aperture to the aperture list." msgstr "Ajoutez une nouvelle ouverture à la liste des ouvertures." -#: flatcamEditors/FlatCAMGrbEditor.py:2581 +#: flatcamEditors/FlatCAMGrbEditor.py:2587 msgid "Delete a aperture in the aperture list" msgstr "Supprimer une ouverture dans la liste des ouvertures" -#: flatcamEditors/FlatCAMGrbEditor.py:2598 +#: flatcamEditors/FlatCAMGrbEditor.py:2604 msgid "Buffer Aperture" msgstr "Ouverture du Tampon" -#: flatcamEditors/FlatCAMGrbEditor.py:2600 +#: flatcamEditors/FlatCAMGrbEditor.py:2606 msgid "Buffer a aperture in the aperture list" msgstr "Buffer une ouverture dans la liste des ouvertures" -#: flatcamEditors/FlatCAMGrbEditor.py:2613 flatcamGUI/PreferencesUI.py:2608 +#: flatcamEditors/FlatCAMGrbEditor.py:2619 flatcamGUI/PreferencesUI.py:2790 msgid "Buffer distance" msgstr "Distance Tampon" -#: flatcamEditors/FlatCAMGrbEditor.py:2614 +#: flatcamEditors/FlatCAMGrbEditor.py:2620 msgid "Buffer corner" msgstr "Coin Tampon" -#: flatcamEditors/FlatCAMGrbEditor.py:2616 +#: flatcamEditors/FlatCAMGrbEditor.py:2622 msgid "" "There are 3 types of corners:\n" " - 'Round': the corner is rounded.\n" @@ -4899,27 +5233,26 @@ msgstr "" "  - \"Biseauté:\" le coin est une ligne qui relie directement les " "fonctionnalités réunies dans le coin" -#: flatcamEditors/FlatCAMGrbEditor.py:2631 flatcamGUI/FlatCAMGUI.py:978 -#: flatcamGUI/FlatCAMGUI.py:2015 flatcamGUI/FlatCAMGUI.py:2087 -#: flatcamGUI/FlatCAMGUI.py:2130 flatcamGUI/FlatCAMGUI.py:2547 -#: flatcamGUI/PreferencesUI.py:6393 flatcamTools/ToolTransform.py:30 -#: flatcamTools/ToolTransform.py:349 +#: flatcamEditors/FlatCAMGrbEditor.py:2637 flatcamGUI/FlatCAMGUI.py:1046 +#: flatcamGUI/FlatCAMGUI.py:2123 flatcamGUI/FlatCAMGUI.py:2195 +#: flatcamGUI/FlatCAMGUI.py:2238 flatcamGUI/FlatCAMGUI.py:2721 +#: flatcamGUI/PreferencesUI.py:6880 flatcamTools/ToolTransform.py:30 msgid "Buffer" msgstr "Tampon" -#: flatcamEditors/FlatCAMGrbEditor.py:2646 +#: flatcamEditors/FlatCAMGrbEditor.py:2652 msgid "Scale Aperture" msgstr "Échelle d'Ouverture" -#: flatcamEditors/FlatCAMGrbEditor.py:2648 +#: flatcamEditors/FlatCAMGrbEditor.py:2654 msgid "Scale a aperture in the aperture list" msgstr "Mettre à l'échelle une ouverture dans la liste des ouvertures" -#: flatcamEditors/FlatCAMGrbEditor.py:2656 flatcamGUI/PreferencesUI.py:2623 +#: flatcamEditors/FlatCAMGrbEditor.py:2662 flatcamGUI/PreferencesUI.py:2805 msgid "Scale factor" msgstr "Facteur d'échelle" -#: flatcamEditors/FlatCAMGrbEditor.py:2658 +#: flatcamEditors/FlatCAMGrbEditor.py:2664 msgid "" "The factor by which to scale the selected aperture.\n" "Values can be between 0.0000 and 999.9999" @@ -4927,19 +5260,19 @@ msgstr "" "Le facteur par lequel mettre à l'échelle l'ouverture sélectionnée.\n" "Les valeurs peuvent être comprises entre 0,0000 et 999,9999" -#: flatcamEditors/FlatCAMGrbEditor.py:2686 +#: flatcamEditors/FlatCAMGrbEditor.py:2692 msgid "Mark polygons" msgstr "Marquer des polygones" -#: flatcamEditors/FlatCAMGrbEditor.py:2688 +#: flatcamEditors/FlatCAMGrbEditor.py:2694 msgid "Mark the polygon areas." msgstr "Marquez les zones polygonales." -#: flatcamEditors/FlatCAMGrbEditor.py:2696 +#: flatcamEditors/FlatCAMGrbEditor.py:2702 msgid "Area UPPER threshold" msgstr "Seuil de la zone supérieure" -#: flatcamEditors/FlatCAMGrbEditor.py:2698 +#: flatcamEditors/FlatCAMGrbEditor.py:2704 msgid "" "The threshold value, all areas less than this are marked.\n" "Can have a value between 0.0000 and 9999.9999" @@ -4947,11 +5280,11 @@ msgstr "" "La valeur de seuil, toutes les zones inférieures à celle-ci sont marquées.\n" "Peut avoir une valeur comprise entre 0.0000 et 9999.9999" -#: flatcamEditors/FlatCAMGrbEditor.py:2705 +#: flatcamEditors/FlatCAMGrbEditor.py:2711 msgid "Area LOWER threshold" msgstr "Zone inférieure seuil" -#: flatcamEditors/FlatCAMGrbEditor.py:2707 +#: flatcamEditors/FlatCAMGrbEditor.py:2713 msgid "" "The threshold value, all areas more than this are marked.\n" "Can have a value between 0.0000 and 9999.9999" @@ -4959,36 +5292,32 @@ msgstr "" "La valeur de seuil, toutes les zones plus que cela sont marquées.\n" "Peut avoir une valeur comprise entre 0.0000 et 9999.9999" -#: flatcamEditors/FlatCAMGrbEditor.py:2721 +#: flatcamEditors/FlatCAMGrbEditor.py:2727 msgid "Mark" msgstr "Marque" -#: flatcamEditors/FlatCAMGrbEditor.py:2723 +#: flatcamEditors/FlatCAMGrbEditor.py:2729 msgid "Mark the polygons that fit within limits." msgstr "Marquez les polygones qui correspondent aux limites." -#: flatcamEditors/FlatCAMGrbEditor.py:2729 +#: flatcamEditors/FlatCAMGrbEditor.py:2735 msgid "Delete all the marked polygons." msgstr "Supprimer tous les polygones marqués." -#: flatcamEditors/FlatCAMGrbEditor.py:2733 -msgid "Clear" -msgstr "Effacer" - -#: flatcamEditors/FlatCAMGrbEditor.py:2735 +#: flatcamEditors/FlatCAMGrbEditor.py:2741 msgid "Clear all the markings." msgstr "Effacer toutes les marques." -#: flatcamEditors/FlatCAMGrbEditor.py:2755 flatcamGUI/FlatCAMGUI.py:963 -#: flatcamGUI/FlatCAMGUI.py:2015 flatcamGUI/FlatCAMGUI.py:2532 +#: flatcamEditors/FlatCAMGrbEditor.py:2761 flatcamGUI/FlatCAMGUI.py:1031 +#: flatcamGUI/FlatCAMGUI.py:2123 flatcamGUI/FlatCAMGUI.py:2706 msgid "Add Pad Array" msgstr "Ajouter un Tableau de Pads" -#: flatcamEditors/FlatCAMGrbEditor.py:2757 +#: flatcamEditors/FlatCAMGrbEditor.py:2763 msgid "Add an array of pads (linear or circular array)" msgstr "Ajouter un tableau de pads (tableau linéaire ou circulaire)" -#: flatcamEditors/FlatCAMGrbEditor.py:2763 +#: flatcamEditors/FlatCAMGrbEditor.py:2769 msgid "" "Select the type of pads array to create.\n" "It can be Linear X(Y) or Circular" @@ -4996,15 +5325,15 @@ msgstr "" "Sélectionnez le type de tableau de pads à créer.\n" "Il peut être linéaire X (Y) ou circulaire" -#: flatcamEditors/FlatCAMGrbEditor.py:2774 flatcamGUI/PreferencesUI.py:2511 +#: flatcamEditors/FlatCAMGrbEditor.py:2780 flatcamGUI/PreferencesUI.py:2691 msgid "Nr of pads" msgstr "Nombre de pads" -#: flatcamEditors/FlatCAMGrbEditor.py:2776 flatcamGUI/PreferencesUI.py:2513 +#: flatcamEditors/FlatCAMGrbEditor.py:2782 flatcamGUI/PreferencesUI.py:2693 msgid "Specify how many pads to be in the array." msgstr "Spécifiez combien de pads doivent être dans le tableau." -#: flatcamEditors/FlatCAMGrbEditor.py:2825 +#: flatcamEditors/FlatCAMGrbEditor.py:2831 msgid "" "Angle at which the linear array is placed.\n" "The precision is of max 2 decimals.\n" @@ -5016,14 +5345,14 @@ msgstr "" "La valeur minimale est: -359,99 degrés.\n" "La valeur maximale est: 360,00 degrés." -#: flatcamEditors/FlatCAMGrbEditor.py:3307 -#: flatcamEditors/FlatCAMGrbEditor.py:3311 +#: flatcamEditors/FlatCAMGrbEditor.py:3321 +#: flatcamEditors/FlatCAMGrbEditor.py:3325 msgid "Aperture code value is missing or wrong format. Add it and retry." msgstr "" "La valeur du code d'ouverture est manquante ou le format est incorrect. " "Ajoutez-le et réessayez." -#: flatcamEditors/FlatCAMGrbEditor.py:3347 +#: flatcamEditors/FlatCAMGrbEditor.py:3361 msgid "" "Aperture dimensions value is missing or wrong format. Add it in format " "(width, height) and retry." @@ -5031,189 +5360,189 @@ msgstr "" "La valeur des dimensions d’ouverture est manquante ou d’un format incorrect. " "Ajoutez-le au format (largeur, hauteur) et réessayez." -#: flatcamEditors/FlatCAMGrbEditor.py:3360 +#: flatcamEditors/FlatCAMGrbEditor.py:3374 msgid "Aperture size value is missing or wrong format. Add it and retry." msgstr "" "La valeur de la taille d’ouverture est manquante ou d’un format incorrect. " "Ajoutez-le et réessayez." -#: flatcamEditors/FlatCAMGrbEditor.py:3371 +#: flatcamEditors/FlatCAMGrbEditor.py:3385 msgid "Aperture already in the aperture table." msgstr "Ouverture déjà dans la table des ouvertures." -#: flatcamEditors/FlatCAMGrbEditor.py:3379 +#: flatcamEditors/FlatCAMGrbEditor.py:3393 msgid "Added new aperture with code" msgstr "Ajout d'une nouvelle ouverture avec code" -#: flatcamEditors/FlatCAMGrbEditor.py:3408 +#: flatcamEditors/FlatCAMGrbEditor.py:3422 msgid " Select an aperture in Aperture Table" msgstr " Sélectionnez une ouverture dans le Tableau des Ouvertures" -#: flatcamEditors/FlatCAMGrbEditor.py:3416 +#: flatcamEditors/FlatCAMGrbEditor.py:3430 msgid "Select an aperture in Aperture Table -->" msgstr "Sélectionnez une ouverture dans le Tableau des Ouvertures -->" -#: flatcamEditors/FlatCAMGrbEditor.py:3439 +#: flatcamEditors/FlatCAMGrbEditor.py:3453 msgid "Deleted aperture with code" msgstr "Ouverture supprimée avec code" -#: flatcamEditors/FlatCAMGrbEditor.py:3924 +#: flatcamEditors/FlatCAMGrbEditor.py:3950 msgid "Loading Gerber into Editor" msgstr "Chargement de Gerber dans l'éditeur" -#: flatcamEditors/FlatCAMGrbEditor.py:4034 +#: flatcamEditors/FlatCAMGrbEditor.py:4078 msgid "Setting up the UI" msgstr "Configuration de IU" -#: flatcamEditors/FlatCAMGrbEditor.py:4035 +#: flatcamEditors/FlatCAMGrbEditor.py:4079 msgid "Adding geometry finished. Preparing the GUI" msgstr "Ajout de la géométrie terminé. Préparation de l'interface graphique" -#: flatcamEditors/FlatCAMGrbEditor.py:4044 +#: flatcamEditors/FlatCAMGrbEditor.py:4088 msgid "Finished loading the Gerber object into the editor." msgstr "Le chargement de l'objet Gerber dans l'éditeur est terminé." -#: flatcamEditors/FlatCAMGrbEditor.py:4184 +#: flatcamEditors/FlatCAMGrbEditor.py:4228 msgid "" "There are no Aperture definitions in the file. Aborting Gerber creation." msgstr "" "Il n'y a pas de définitions d'ouverture dans le fichier. Abandon de la " "création de Gerber." -#: flatcamEditors/FlatCAMGrbEditor.py:4194 +#: flatcamEditors/FlatCAMGrbEditor.py:4238 msgid "Creating Gerber." msgstr "Créer Gerber." -#: flatcamEditors/FlatCAMGrbEditor.py:4203 +#: flatcamEditors/FlatCAMGrbEditor.py:4247 msgid "Done. Gerber editing finished." msgstr "Terminé. Gerber édition terminée." -#: flatcamEditors/FlatCAMGrbEditor.py:4222 +#: flatcamEditors/FlatCAMGrbEditor.py:4265 msgid "Cancelled. No aperture is selected" msgstr "Annulé. Aucune ouverture n'est sélectionnée" -#: flatcamEditors/FlatCAMGrbEditor.py:4782 +#: flatcamEditors/FlatCAMGrbEditor.py:4826 msgid "Failed. No aperture geometry is selected." msgstr "Échoué. Aucune géométrie d'ouverture n'est sélectionnée." -#: flatcamEditors/FlatCAMGrbEditor.py:4791 -#: flatcamEditors/FlatCAMGrbEditor.py:5062 +#: flatcamEditors/FlatCAMGrbEditor.py:4835 +#: flatcamEditors/FlatCAMGrbEditor.py:5106 msgid "Done. Apertures geometry deleted." msgstr "Terminé. Géométrie des ouvertures supprimée." -#: flatcamEditors/FlatCAMGrbEditor.py:4934 +#: flatcamEditors/FlatCAMGrbEditor.py:4978 msgid "No aperture to buffer. Select at least one aperture and try again." msgstr "" "Pas d'ouverture à tamponner. Sélectionnez au moins une ouverture et " "réessayez." -#: flatcamEditors/FlatCAMGrbEditor.py:4946 +#: flatcamEditors/FlatCAMGrbEditor.py:4990 msgid "Failed." msgstr "Échoué." -#: flatcamEditors/FlatCAMGrbEditor.py:4965 +#: flatcamEditors/FlatCAMGrbEditor.py:5009 msgid "Scale factor value is missing or wrong format. Add it and retry." msgstr "" "La valeur du facteur d'échelle est manquante ou d'un format incorrect. " "Ajoutez-le et réessayez." -#: flatcamEditors/FlatCAMGrbEditor.py:4997 +#: flatcamEditors/FlatCAMGrbEditor.py:5041 msgid "No aperture to scale. Select at least one aperture and try again." msgstr "" "Pas d'ouverture à l'échelle. Sélectionnez au moins une ouverture et " "réessayez." -#: flatcamEditors/FlatCAMGrbEditor.py:5013 +#: flatcamEditors/FlatCAMGrbEditor.py:5057 msgid "Done. Scale Tool completed." msgstr "Terminé. Outil d'échelle terminé." -#: flatcamEditors/FlatCAMGrbEditor.py:5051 +#: flatcamEditors/FlatCAMGrbEditor.py:5095 msgid "Polygons marked." msgstr "Polygones marqués." -#: flatcamEditors/FlatCAMGrbEditor.py:5054 +#: flatcamEditors/FlatCAMGrbEditor.py:5098 msgid "No polygons were marked. None fit within the limits." msgstr "Aucun polygone n'a été marqué. Aucun ne rentre dans les limites." -#: flatcamEditors/FlatCAMGrbEditor.py:5783 +#: flatcamEditors/FlatCAMGrbEditor.py:5822 msgid "Rotation action was not executed." msgstr "L'action de rotation n'a pas été exécutée." -#: flatcamEditors/FlatCAMGrbEditor.py:5919 +#: flatcamEditors/FlatCAMGrbEditor.py:5950 msgid "Skew action was not executed." msgstr "L'action fausser n'a pas été exécutée." -#: flatcamEditors/FlatCAMGrbEditor.py:5986 +#: flatcamEditors/FlatCAMGrbEditor.py:6015 msgid "Scale action was not executed." msgstr "L'action d'échelle n'a pas été exécutée." -#: flatcamEditors/FlatCAMGrbEditor.py:6029 +#: flatcamEditors/FlatCAMGrbEditor.py:6058 msgid "Offset action was not executed." msgstr "L'action decalage n'a pas été exécutée." -#: flatcamEditors/FlatCAMGrbEditor.py:6079 +#: flatcamEditors/FlatCAMGrbEditor.py:6108 msgid "Geometry shape offset Y cancelled" msgstr "Décalage géométrique de la forme Y annulé" -#: flatcamEditors/FlatCAMGrbEditor.py:6094 +#: flatcamEditors/FlatCAMGrbEditor.py:6123 msgid "Geometry shape skew X cancelled" msgstr "Fausser géométrique de la forme X annulé" -#: flatcamEditors/FlatCAMGrbEditor.py:6109 +#: flatcamEditors/FlatCAMGrbEditor.py:6138 msgid "Geometry shape skew Y cancelled" msgstr "Fausser géométrique de la forme Y annulé" -#: flatcamEditors/FlatCAMTextEditor.py:72 +#: flatcamEditors/FlatCAMTextEditor.py:74 msgid "Print Preview" msgstr "Aperçu avant imp" -#: flatcamEditors/FlatCAMTextEditor.py:73 +#: flatcamEditors/FlatCAMTextEditor.py:75 msgid "Open a OS standard Preview Print window." msgstr "" "Ouvrez une fenêtre d'aperçu avant impression standard du système " "d'exploitation." -#: flatcamEditors/FlatCAMTextEditor.py:76 +#: flatcamEditors/FlatCAMTextEditor.py:78 msgid "Print Code" msgstr "Code d'impression" -#: flatcamEditors/FlatCAMTextEditor.py:77 +#: flatcamEditors/FlatCAMTextEditor.py:79 msgid "Open a OS standard Print window." msgstr "Ouvrez une fenêtre d'impression standard du système d'exploitation." -#: flatcamEditors/FlatCAMTextEditor.py:79 +#: flatcamEditors/FlatCAMTextEditor.py:81 msgid "Find in Code" msgstr "Trouver dans le code" -#: flatcamEditors/FlatCAMTextEditor.py:80 +#: flatcamEditors/FlatCAMTextEditor.py:82 msgid "Will search and highlight in yellow the string in the Find box." msgstr "Recherche et surligne en jaune la chaîne dans la zone de recherche." -#: flatcamEditors/FlatCAMTextEditor.py:84 +#: flatcamEditors/FlatCAMTextEditor.py:86 msgid "Find box. Enter here the strings to be searched in the text." msgstr "Boîte de recherche. Entrez ici les chaînes à rechercher dans le texte." -#: flatcamEditors/FlatCAMTextEditor.py:86 +#: flatcamEditors/FlatCAMTextEditor.py:88 msgid "Replace With" msgstr "Remplacer par" -#: flatcamEditors/FlatCAMTextEditor.py:87 +#: flatcamEditors/FlatCAMTextEditor.py:89 msgid "" "Will replace the string from the Find box with the one in the Replace box." msgstr "" "Remplacera la chaîne de la zone Rechercher par celle de la zone Remplacer." -#: flatcamEditors/FlatCAMTextEditor.py:91 +#: flatcamEditors/FlatCAMTextEditor.py:93 msgid "String to replace the one in the Find box throughout the text." msgstr "Chaîne pour remplacer celle de la zone Rechercher dans tout le texte." -#: flatcamEditors/FlatCAMTextEditor.py:93 flatcamGUI/ObjectUI.py:482 -#: flatcamGUI/ObjectUI.py:1809 flatcamGUI/PreferencesUI.py:2070 -#: flatcamGUI/PreferencesUI.py:4419 flatcamGUI/PreferencesUI.py:5647 +#: flatcamEditors/FlatCAMTextEditor.py:95 flatcamGUI/ObjectUI.py:485 +#: flatcamGUI/ObjectUI.py:2137 flatcamGUI/PreferencesUI.py:2250 +#: flatcamGUI/PreferencesUI.py:4712 msgid "All" msgstr "Tout" -#: flatcamEditors/FlatCAMTextEditor.py:94 +#: flatcamEditors/FlatCAMTextEditor.py:96 msgid "" "When checked it will replace all instances in the 'Find' box\n" "with the text in the 'Replace' box.." @@ -5222,162 +5551,171 @@ msgstr "" "'Rechercher'\n" "avec le texte dans la case 'Remplacer' .." -#: flatcamEditors/FlatCAMTextEditor.py:97 +#: flatcamEditors/FlatCAMTextEditor.py:99 msgid "Copy All" msgstr "Tout copier" -#: flatcamEditors/FlatCAMTextEditor.py:98 +#: flatcamEditors/FlatCAMTextEditor.py:100 msgid "Will copy all the text in the Code Editor to the clipboard." msgstr "Copiera tout le texte de l'éditeur de code dans le presse-papiers." -#: flatcamEditors/FlatCAMTextEditor.py:101 +#: flatcamEditors/FlatCAMTextEditor.py:103 msgid "Open Code" msgstr "Code ouvert" -#: flatcamEditors/FlatCAMTextEditor.py:102 +#: flatcamEditors/FlatCAMTextEditor.py:104 msgid "Will open a text file in the editor." msgstr "Va ouvrir un fichier texte dans l'éditeur." -#: flatcamEditors/FlatCAMTextEditor.py:104 +#: flatcamEditors/FlatCAMTextEditor.py:106 msgid "Save Code" msgstr "Enregistrer le code" -#: flatcamEditors/FlatCAMTextEditor.py:105 +#: flatcamEditors/FlatCAMTextEditor.py:107 msgid "Will save the text in the editor into a file." msgstr "Va enregistrer le texte dans l'éditeur dans un fichier." -#: flatcamEditors/FlatCAMTextEditor.py:107 +#: flatcamEditors/FlatCAMTextEditor.py:109 msgid "Run Code" msgstr "Code d'exécution" -#: flatcamEditors/FlatCAMTextEditor.py:108 +#: flatcamEditors/FlatCAMTextEditor.py:110 msgid "Will run the TCL commands found in the text file, one by one." msgstr "" "Va exécuter les commandes TCL trouvées dans le fichier texte, une par une." -#: flatcamEditors/FlatCAMTextEditor.py:182 +#: flatcamEditors/FlatCAMTextEditor.py:184 msgid "Open file" msgstr "Fichier ouvert" -#: flatcamEditors/FlatCAMTextEditor.py:213 -#: flatcamEditors/FlatCAMTextEditor.py:218 +#: flatcamEditors/FlatCAMTextEditor.py:215 +#: flatcamEditors/FlatCAMTextEditor.py:220 msgid "Export Code ..." msgstr "Exporter le code ..." -#: flatcamEditors/FlatCAMTextEditor.py:221 -msgid "Export Code cancelled." -msgstr "Code d'exportation annulé." - -#: flatcamEditors/FlatCAMTextEditor.py:332 +#: flatcamEditors/FlatCAMTextEditor.py:334 msgid "Code Editor content copied to clipboard ..." msgstr "Contenu de l'éditeur de code copié dans le Presse-papiers ..." -#: flatcamGUI/FlatCAMGUI.py:52 flatcamGUI/FlatCAMGUI.py:54 -#: flatcamGUI/FlatCAMGUI.py:2040 +#: flatcamGUI/FlatCAMGUI.py:66 flatcamGUI/FlatCAMGUI.py:68 +#: flatcamGUI/FlatCAMGUI.py:2148 msgid "Toggle Panel" msgstr "Basculer le Panneau" -#: flatcamGUI/FlatCAMGUI.py:64 +#: flatcamGUI/FlatCAMGUI.py:78 msgid "File" msgstr "Fichier" -#: flatcamGUI/FlatCAMGUI.py:69 +#: flatcamGUI/FlatCAMGUI.py:83 msgid "&New Project ...\tCtrl+N" msgstr "Nouveau projet ...\tCtrl+N" -#: flatcamGUI/FlatCAMGUI.py:71 +#: flatcamGUI/FlatCAMGUI.py:85 msgid "Will create a new, blank project" msgstr "Va créer un nouveau projet vierge" -#: flatcamGUI/FlatCAMGUI.py:76 +#: flatcamGUI/FlatCAMGUI.py:90 msgid "&New" msgstr "Nouveau" -#: flatcamGUI/FlatCAMGUI.py:80 +#: flatcamGUI/FlatCAMGUI.py:94 msgid "Geometry\tN" msgstr "Géométrie\tN" -#: flatcamGUI/FlatCAMGUI.py:82 +#: flatcamGUI/FlatCAMGUI.py:96 msgid "Will create a new, empty Geometry Object." msgstr "Crée un nouvel objet de géométrie vide." -#: flatcamGUI/FlatCAMGUI.py:84 +#: flatcamGUI/FlatCAMGUI.py:99 msgid "Gerber\tB" msgstr "Gerber\tB" -#: flatcamGUI/FlatCAMGUI.py:86 +#: flatcamGUI/FlatCAMGUI.py:101 msgid "Will create a new, empty Gerber Object." msgstr "Crée un nouvel objet Gerber vide." -#: flatcamGUI/FlatCAMGUI.py:88 +#: flatcamGUI/FlatCAMGUI.py:104 msgid "Excellon\tL" msgstr "Excellon\tL" -#: flatcamGUI/FlatCAMGUI.py:90 +#: flatcamGUI/FlatCAMGUI.py:106 msgid "Will create a new, empty Excellon Object." msgstr "Va créer un nouvel objet vide vide." -#: flatcamGUI/FlatCAMGUI.py:94 +#: flatcamGUI/FlatCAMGUI.py:111 msgid "Document\tD" msgstr "Document\tD" -#: flatcamGUI/FlatCAMGUI.py:96 +#: flatcamGUI/FlatCAMGUI.py:113 msgid "Will create a new, empty Document Object." msgstr "Crée un nouvel objet de document vide." -#: flatcamGUI/FlatCAMGUI.py:99 flatcamGUI/FlatCAMGUI.py:4111 +#: flatcamGUI/FlatCAMGUI.py:117 flatcamGUI/FlatCAMGUI.py:4327 #: flatcamTools/ToolPcbWizard.py:62 flatcamTools/ToolPcbWizard.py:69 msgid "Open" msgstr "Ouvert" -#: flatcamGUI/FlatCAMGUI.py:103 +#: flatcamGUI/FlatCAMGUI.py:122 msgid "Open &Project ..." msgstr "Projet ouvert ..." -#: flatcamGUI/FlatCAMGUI.py:109 flatcamGUI/FlatCAMGUI.py:4121 +#: flatcamGUI/FlatCAMGUI.py:128 flatcamGUI/FlatCAMGUI.py:4337 msgid "Open &Gerber ...\tCtrl+G" msgstr "Gerber ouvert...\tCtrl+G" -#: flatcamGUI/FlatCAMGUI.py:114 flatcamGUI/FlatCAMGUI.py:4126 +#: flatcamGUI/FlatCAMGUI.py:133 flatcamGUI/FlatCAMGUI.py:4342 msgid "Open &Excellon ...\tCtrl+E" msgstr "Excellon ouvert ...\tCtrl+E" -#: flatcamGUI/FlatCAMGUI.py:118 flatcamGUI/FlatCAMGUI.py:4131 +#: flatcamGUI/FlatCAMGUI.py:138 flatcamGUI/FlatCAMGUI.py:4347 msgid "Open G-&Code ..." msgstr "Ouvrir G-Code ..." -#: flatcamGUI/FlatCAMGUI.py:124 +#: flatcamGUI/FlatCAMGUI.py:145 msgid "Open Config ..." msgstr "Ouvrez la configuration ..." -#: flatcamGUI/FlatCAMGUI.py:128 +#: flatcamGUI/FlatCAMGUI.py:150 msgid "Recent projects" msgstr "Les projets récents" -#: flatcamGUI/FlatCAMGUI.py:129 +#: flatcamGUI/FlatCAMGUI.py:152 msgid "Recent files" msgstr "Fichiers récents" -#: flatcamGUI/FlatCAMGUI.py:135 +#: flatcamGUI/FlatCAMGUI.py:155 flatcamGUI/FlatCAMGUI.py:738 +#: flatcamGUI/FlatCAMGUI.py:1324 +msgid "Save" +msgstr "Sauver" + +#: flatcamGUI/FlatCAMGUI.py:159 +msgid "&Save Project ...\tCtrl+S" +msgstr "Sauvegarder le projet...\tCtrl+S" + +#: flatcamGUI/FlatCAMGUI.py:164 +msgid "Save Project &As ...\tCtrl+Shift+S" +msgstr "Enregistrer le projet sous...\tCtrl+Shift+S" + +#: flatcamGUI/FlatCAMGUI.py:179 msgid "Scripting" msgstr "Scripting" -#: flatcamGUI/FlatCAMGUI.py:138 flatcamGUI/FlatCAMGUI.py:829 -#: flatcamGUI/FlatCAMGUI.py:2409 +#: flatcamGUI/FlatCAMGUI.py:183 flatcamGUI/FlatCAMGUI.py:888 +#: flatcamGUI/FlatCAMGUI.py:2567 msgid "New Script ..." msgstr "Nouveau script ..." -#: flatcamGUI/FlatCAMGUI.py:139 flatcamGUI/FlatCAMGUI.py:831 -#: flatcamGUI/FlatCAMGUI.py:2411 +#: flatcamGUI/FlatCAMGUI.py:185 flatcamGUI/FlatCAMGUI.py:890 +#: flatcamGUI/FlatCAMGUI.py:2569 msgid "Open Script ..." msgstr "Script ouvert ..." -#: flatcamGUI/FlatCAMGUI.py:141 flatcamGUI/FlatCAMGUI.py:833 -#: flatcamGUI/FlatCAMGUI.py:2413 flatcamGUI/FlatCAMGUI.py:4100 +#: flatcamGUI/FlatCAMGUI.py:187 flatcamGUI/FlatCAMGUI.py:892 +#: flatcamGUI/FlatCAMGUI.py:2571 flatcamGUI/FlatCAMGUI.py:4316 msgid "Run Script ..." msgstr "Exécutez le script ..." -#: flatcamGUI/FlatCAMGUI.py:143 flatcamGUI/FlatCAMGUI.py:4102 +#: flatcamGUI/FlatCAMGUI.py:189 flatcamGUI/FlatCAMGUI.py:4318 msgid "" "Will run the opened Tcl Script thus\n" "enabling the automation of certain\n" @@ -5387,47 +5725,47 @@ msgstr "" "permettant l’automatisation de certaines\n" "fonctions de FlatCAM." -#: flatcamGUI/FlatCAMGUI.py:156 +#: flatcamGUI/FlatCAMGUI.py:203 msgid "Import" msgstr "Importation" -#: flatcamGUI/FlatCAMGUI.py:158 +#: flatcamGUI/FlatCAMGUI.py:205 msgid "&SVG as Geometry Object ..." msgstr "SVG comme objet de géométrie ..." -#: flatcamGUI/FlatCAMGUI.py:161 +#: flatcamGUI/FlatCAMGUI.py:208 msgid "&SVG as Gerber Object ..." msgstr "SVG comme objet Gerber ..." -#: flatcamGUI/FlatCAMGUI.py:166 +#: flatcamGUI/FlatCAMGUI.py:213 msgid "&DXF as Geometry Object ..." msgstr "DXF comme objet de géométrie ..." -#: flatcamGUI/FlatCAMGUI.py:169 +#: flatcamGUI/FlatCAMGUI.py:216 msgid "&DXF as Gerber Object ..." msgstr "DXF en tant qu'objet Gerber ..." -#: flatcamGUI/FlatCAMGUI.py:173 +#: flatcamGUI/FlatCAMGUI.py:220 msgid "HPGL2 as Geometry Object ..." msgstr "HPGL2 comme objet géométrique ..." -#: flatcamGUI/FlatCAMGUI.py:178 +#: flatcamGUI/FlatCAMGUI.py:226 msgid "Export" msgstr "Exportation" -#: flatcamGUI/FlatCAMGUI.py:181 +#: flatcamGUI/FlatCAMGUI.py:230 msgid "Export &SVG ..." msgstr "Exporter SVG ..." -#: flatcamGUI/FlatCAMGUI.py:184 +#: flatcamGUI/FlatCAMGUI.py:234 msgid "Export DXF ..." msgstr "Exporter DXF ..." -#: flatcamGUI/FlatCAMGUI.py:189 +#: flatcamGUI/FlatCAMGUI.py:240 msgid "Export &PNG ..." msgstr "Exporter PNG ..." -#: flatcamGUI/FlatCAMGUI.py:191 +#: flatcamGUI/FlatCAMGUI.py:242 msgid "" "Will export an image in PNG format,\n" "the saved image will contain the visual \n" @@ -5437,11 +5775,11 @@ msgstr "" "l'image enregistrée contiendra le visuel\n" "informations actuellement dans la zone de tracé FlatCAM." -#: flatcamGUI/FlatCAMGUI.py:200 +#: flatcamGUI/FlatCAMGUI.py:251 msgid "Export &Excellon ..." msgstr "Exporter Excellon ..." -#: flatcamGUI/FlatCAMGUI.py:202 +#: flatcamGUI/FlatCAMGUI.py:253 msgid "" "Will export an Excellon Object as Excellon file,\n" "the coordinates format, the file units and zeros\n" @@ -5451,11 +5789,11 @@ msgstr "" "le format des coordonnées, les unités de fichier et les zéros\n" "sont définies dans Préférences -> Excellon Export." -#: flatcamGUI/FlatCAMGUI.py:209 +#: flatcamGUI/FlatCAMGUI.py:260 msgid "Export &Gerber ..." msgstr "Exporter Gerber ..." -#: flatcamGUI/FlatCAMGUI.py:211 +#: flatcamGUI/FlatCAMGUI.py:262 msgid "" "Will export an Gerber Object as Gerber file,\n" "the coordinates format, the file units and zeros\n" @@ -5465,65 +5803,48 @@ msgstr "" "le format des coordonnées, les unités de fichier et les zéros\n" "sont définies dans Préférences -> Exportation Gerber." -#: flatcamGUI/FlatCAMGUI.py:229 +#: flatcamGUI/FlatCAMGUI.py:272 msgid "Backup" msgstr "Sauvegarde" -#: flatcamGUI/FlatCAMGUI.py:233 +#: flatcamGUI/FlatCAMGUI.py:277 msgid "Import Preferences from file ..." msgstr "Importer les préférences du fichier ..." -#: flatcamGUI/FlatCAMGUI.py:238 +#: flatcamGUI/FlatCAMGUI.py:283 msgid "Export Preferences to file ..." msgstr "Exporter les préférences dans un fichier ..." -#: flatcamGUI/FlatCAMGUI.py:244 flatcamGUI/FlatCAMGUI.py:1614 +#: flatcamGUI/FlatCAMGUI.py:297 flatcamGUI/FlatCAMGUI.py:1715 msgid "Print (PDF)" msgstr "Imprimer (PDF)" -#: flatcamGUI/FlatCAMGUI.py:247 flatcamGUI/FlatCAMGUI.py:682 -#: flatcamGUI/FlatCAMGUI.py:1252 -msgid "Save" -msgstr "Sauver" - -#: flatcamGUI/FlatCAMGUI.py:251 -msgid "&Save Project ..." -msgstr "Sauvegarder le projet ..." - -#: flatcamGUI/FlatCAMGUI.py:256 -msgid "Save Project &As ...\tCtrl+S" -msgstr "Enregistrer le projet sous...\tCtrl+S" - -#: flatcamGUI/FlatCAMGUI.py:261 -msgid "Save Project C&opy ..." -msgstr "Enregistrer la copie du projet ..." - -#: flatcamGUI/FlatCAMGUI.py:271 +#: flatcamGUI/FlatCAMGUI.py:305 msgid "E&xit" msgstr "Sortie" -#: flatcamGUI/FlatCAMGUI.py:279 flatcamGUI/FlatCAMGUI.py:676 -#: flatcamGUI/FlatCAMGUI.py:2163 +#: flatcamGUI/FlatCAMGUI.py:313 flatcamGUI/FlatCAMGUI.py:732 +#: flatcamGUI/FlatCAMGUI.py:2271 msgid "Edit" msgstr "Modifier" -#: flatcamGUI/FlatCAMGUI.py:283 +#: flatcamGUI/FlatCAMGUI.py:317 msgid "Edit Object\tE" msgstr "Editer un objet\tE" -#: flatcamGUI/FlatCAMGUI.py:285 +#: flatcamGUI/FlatCAMGUI.py:319 msgid "Close Editor\tCtrl+S" msgstr "Fermer l'éditeur\tCtrl+S" -#: flatcamGUI/FlatCAMGUI.py:294 +#: flatcamGUI/FlatCAMGUI.py:328 msgid "Conversion" msgstr "Conversion" -#: flatcamGUI/FlatCAMGUI.py:296 +#: flatcamGUI/FlatCAMGUI.py:330 msgid "&Join Geo/Gerber/Exc -> Geo" msgstr "Rejoindre Geo/Gerber/Exc -> Geo" -#: flatcamGUI/FlatCAMGUI.py:298 +#: flatcamGUI/FlatCAMGUI.py:332 msgid "" "Merge a selection of objects, which can be of type:\n" "- Gerber\n" @@ -5537,30 +5858,30 @@ msgstr "" "- Géométrie\n" "dans un nouvel objet de géométrie combo." -#: flatcamGUI/FlatCAMGUI.py:305 +#: flatcamGUI/FlatCAMGUI.py:339 msgid "Join Excellon(s) -> Excellon" msgstr "Rejoignez Excellon(s) -> Excellon" -#: flatcamGUI/FlatCAMGUI.py:307 +#: flatcamGUI/FlatCAMGUI.py:341 msgid "Merge a selection of Excellon objects into a new combo Excellon object." msgstr "" "Fusionner une sélection d'objets Excellon dans un nouvel objet Excellon " "combo." -#: flatcamGUI/FlatCAMGUI.py:310 +#: flatcamGUI/FlatCAMGUI.py:344 msgid "Join Gerber(s) -> Gerber" msgstr "Rejoindre Gerber(s) -> Gerber" -#: flatcamGUI/FlatCAMGUI.py:312 +#: flatcamGUI/FlatCAMGUI.py:346 msgid "Merge a selection of Gerber objects into a new combo Gerber object." msgstr "" "Fusionner une sélection d'objets Gerber dans un nouvel objet Gerber combiné." -#: flatcamGUI/FlatCAMGUI.py:317 +#: flatcamGUI/FlatCAMGUI.py:351 msgid "Convert Single to MultiGeo" msgstr "Convertir Unique en MultiGeo" -#: flatcamGUI/FlatCAMGUI.py:319 +#: flatcamGUI/FlatCAMGUI.py:353 msgid "" "Will convert a Geometry object from single_geometry type\n" "to a multi_geometry type." @@ -5568,11 +5889,11 @@ msgstr "" "Convertira un objet Geometry à partir d'un type de géométrie unique\n" "à un type multi géométrie." -#: flatcamGUI/FlatCAMGUI.py:323 +#: flatcamGUI/FlatCAMGUI.py:357 msgid "Convert Multi to SingleGeo" msgstr "Convertir Multi en Unique Geo" -#: flatcamGUI/FlatCAMGUI.py:325 +#: flatcamGUI/FlatCAMGUI.py:359 msgid "" "Will convert a Geometry object from multi_geometry type\n" "to a single_geometry type." @@ -5580,734 +5901,744 @@ msgstr "" "Convertira un objet Geometry de type multi geometry\n" "à un seul type de géométrie." -#: flatcamGUI/FlatCAMGUI.py:332 +#: flatcamGUI/FlatCAMGUI.py:366 msgid "Convert Any to Geo" msgstr "Convertir n'importe quel en Geo" -#: flatcamGUI/FlatCAMGUI.py:335 +#: flatcamGUI/FlatCAMGUI.py:369 msgid "Convert Any to Gerber" msgstr "Convertir n'importe lequel en gerber" -#: flatcamGUI/FlatCAMGUI.py:341 +#: flatcamGUI/FlatCAMGUI.py:375 msgid "&Copy\tCtrl+C" msgstr "Copie\tCtrl+C" -#: flatcamGUI/FlatCAMGUI.py:346 +#: flatcamGUI/FlatCAMGUI.py:380 msgid "&Delete\tDEL" msgstr "Supprimer\tDEL" -#: flatcamGUI/FlatCAMGUI.py:351 +#: flatcamGUI/FlatCAMGUI.py:385 msgid "Se&t Origin\tO" msgstr "Définir L'origine\tO" -#: flatcamGUI/FlatCAMGUI.py:353 +#: flatcamGUI/FlatCAMGUI.py:387 +msgid "Move to Origin\tShift+O" +msgstr "Déplacer vers l'origine\tShift+O" + +#: flatcamGUI/FlatCAMGUI.py:390 msgid "Jump to Location\tJ" msgstr "Aller à l'emplacement\tJ" -#: flatcamGUI/FlatCAMGUI.py:358 +#: flatcamGUI/FlatCAMGUI.py:392 +msgid "Locate in Object\tShift+J" +msgstr "Localiser dans l'objet\tShift+J" + +#: flatcamGUI/FlatCAMGUI.py:397 msgid "Toggle Units\tQ" msgstr "Basculer les Unités\tQ" -#: flatcamGUI/FlatCAMGUI.py:360 +#: flatcamGUI/FlatCAMGUI.py:399 msgid "&Select All\tCtrl+A" msgstr "Tout sélectionner\tCtrl+A" -#: flatcamGUI/FlatCAMGUI.py:365 +#: flatcamGUI/FlatCAMGUI.py:404 msgid "&Preferences\tShift+P" msgstr "Préférences\tShift+P" -#: flatcamGUI/FlatCAMGUI.py:371 flatcamTools/ToolProperties.py:153 +#: flatcamGUI/FlatCAMGUI.py:410 flatcamTools/ToolProperties.py:155 msgid "Options" msgstr "Les options" -#: flatcamGUI/FlatCAMGUI.py:373 +#: flatcamGUI/FlatCAMGUI.py:412 msgid "&Rotate Selection\tShift+(R)" msgstr "Faire pivoter la sélection\tShift+(R)" -#: flatcamGUI/FlatCAMGUI.py:378 +#: flatcamGUI/FlatCAMGUI.py:417 msgid "&Skew on X axis\tShift+X" msgstr "Fausser sur l'axe X\tShift+X" -#: flatcamGUI/FlatCAMGUI.py:380 +#: flatcamGUI/FlatCAMGUI.py:419 msgid "S&kew on Y axis\tShift+Y" msgstr "Fausser sur l'axe Y\tShift+Y" -#: flatcamGUI/FlatCAMGUI.py:385 +#: flatcamGUI/FlatCAMGUI.py:424 msgid "Flip on &X axis\tX" msgstr "Miroir sur l'axe X\tX" -#: flatcamGUI/FlatCAMGUI.py:387 +#: flatcamGUI/FlatCAMGUI.py:426 msgid "Flip on &Y axis\tY" msgstr "Miroir sur l'axe Y\tY" -#: flatcamGUI/FlatCAMGUI.py:392 +#: flatcamGUI/FlatCAMGUI.py:431 msgid "View source\tAlt+S" msgstr "Voir la source\tAlt+S" -#: flatcamGUI/FlatCAMGUI.py:394 +#: flatcamGUI/FlatCAMGUI.py:433 msgid "Tools DataBase\tCtrl+D" msgstr "Base de Données d'outils\tCtrl+D" -#: flatcamGUI/FlatCAMGUI.py:401 flatcamGUI/FlatCAMGUI.py:2060 +#: flatcamGUI/FlatCAMGUI.py:440 flatcamGUI/FlatCAMGUI.py:2168 msgid "View" msgstr "Vue" -#: flatcamGUI/FlatCAMGUI.py:403 +#: flatcamGUI/FlatCAMGUI.py:442 msgid "Enable all plots\tAlt+1" msgstr "Activer tous les dessins\tAlt+1" -#: flatcamGUI/FlatCAMGUI.py:405 +#: flatcamGUI/FlatCAMGUI.py:444 msgid "Disable all plots\tAlt+2" msgstr "Désactiver tous les dessins\tAlt+2" -#: flatcamGUI/FlatCAMGUI.py:407 +#: flatcamGUI/FlatCAMGUI.py:446 msgid "Disable non-selected\tAlt+3" msgstr "Désactiver les non sélectionnés\tAlt+3" -#: flatcamGUI/FlatCAMGUI.py:411 +#: flatcamGUI/FlatCAMGUI.py:450 msgid "&Zoom Fit\tV" msgstr "Ajustement du Zoom\tV" -#: flatcamGUI/FlatCAMGUI.py:413 +#: flatcamGUI/FlatCAMGUI.py:452 msgid "&Zoom In\t=" msgstr "Agrandir\t=" -#: flatcamGUI/FlatCAMGUI.py:415 +#: flatcamGUI/FlatCAMGUI.py:454 msgid "&Zoom Out\t-" msgstr "Dézoomer\t-" -#: flatcamGUI/FlatCAMGUI.py:420 +#: flatcamGUI/FlatCAMGUI.py:459 msgid "Redraw All\tF5" msgstr "Tout redessiner\tF5" -#: flatcamGUI/FlatCAMGUI.py:424 +#: flatcamGUI/FlatCAMGUI.py:463 msgid "Toggle Code Editor\tShift+E" msgstr "Basculer l'éditeur de code\tShift+E" -#: flatcamGUI/FlatCAMGUI.py:427 +#: flatcamGUI/FlatCAMGUI.py:466 msgid "&Toggle FullScreen\tAlt+F10" msgstr "Passer en plein écran\tAlt+F10" -#: flatcamGUI/FlatCAMGUI.py:429 +#: flatcamGUI/FlatCAMGUI.py:468 msgid "&Toggle Plot Area\tCtrl+F10" msgstr "Basculer la zone de tracé\tCtrl+F10" -#: flatcamGUI/FlatCAMGUI.py:431 +#: flatcamGUI/FlatCAMGUI.py:470 msgid "&Toggle Project/Sel/Tool\t`" msgstr "Basculer Projet / Sel / Outil\t`" -#: flatcamGUI/FlatCAMGUI.py:435 +#: flatcamGUI/FlatCAMGUI.py:474 msgid "&Toggle Grid Snap\tG" msgstr "Basculer la grille\tG" -#: flatcamGUI/FlatCAMGUI.py:437 +#: flatcamGUI/FlatCAMGUI.py:476 msgid "&Toggle Grid Lines\tAlt+G" msgstr "Basculer les lignes de la grille\tAlt+G" -#: flatcamGUI/FlatCAMGUI.py:439 +#: flatcamGUI/FlatCAMGUI.py:478 msgid "&Toggle Axis\tShift+G" msgstr "Basculer l'axe\tShift+G" -#: flatcamGUI/FlatCAMGUI.py:441 +#: flatcamGUI/FlatCAMGUI.py:480 msgid "Toggle Workspace\tShift+W" msgstr "Basculer l'espace de travail\tShift+W" -#: flatcamGUI/FlatCAMGUI.py:446 +#: flatcamGUI/FlatCAMGUI.py:485 msgid "Objects" msgstr "Objets" -#: flatcamGUI/FlatCAMGUI.py:460 +#: flatcamGUI/FlatCAMGUI.py:499 msgid "&Command Line\tS" msgstr "&Ligne de commande\tS" -#: flatcamGUI/FlatCAMGUI.py:465 +#: flatcamGUI/FlatCAMGUI.py:504 msgid "Help" msgstr "Aide" -#: flatcamGUI/FlatCAMGUI.py:467 +#: flatcamGUI/FlatCAMGUI.py:506 msgid "Online Help\tF1" msgstr "Aide en ligne\tF1" -#: flatcamGUI/FlatCAMGUI.py:477 +#: flatcamGUI/FlatCAMGUI.py:516 msgid "Report a bug" msgstr "Signaler une erreur" -#: flatcamGUI/FlatCAMGUI.py:480 +#: flatcamGUI/FlatCAMGUI.py:519 msgid "Excellon Specification" msgstr "Excellon Spécification" -#: flatcamGUI/FlatCAMGUI.py:482 +#: flatcamGUI/FlatCAMGUI.py:521 msgid "Gerber Specification" msgstr "Gerber Spécifications" -#: flatcamGUI/FlatCAMGUI.py:487 +#: flatcamGUI/FlatCAMGUI.py:526 msgid "Shortcuts List\tF3" msgstr "Liste des raccourcis\tF3" -#: flatcamGUI/FlatCAMGUI.py:489 +#: flatcamGUI/FlatCAMGUI.py:528 msgid "YouTube Channel\tF4" msgstr "Chaîne Youtube\tF4" -#: flatcamGUI/FlatCAMGUI.py:500 +#: flatcamGUI/FlatCAMGUI.py:539 msgid "Add Circle\tO" msgstr "Ajouter un Cercle\tO" -#: flatcamGUI/FlatCAMGUI.py:503 +#: flatcamGUI/FlatCAMGUI.py:542 msgid "Add Arc\tA" msgstr "Ajouter un Arc\tA" -#: flatcamGUI/FlatCAMGUI.py:506 +#: flatcamGUI/FlatCAMGUI.py:545 msgid "Add Rectangle\tR" msgstr "Ajouter un Rectangle\tR" -#: flatcamGUI/FlatCAMGUI.py:509 +#: flatcamGUI/FlatCAMGUI.py:548 msgid "Add Polygon\tN" msgstr "Ajouter un Polygone\tN" -#: flatcamGUI/FlatCAMGUI.py:512 +#: flatcamGUI/FlatCAMGUI.py:551 msgid "Add Path\tP" msgstr "Ajouter un Chemin\tP" -#: flatcamGUI/FlatCAMGUI.py:515 +#: flatcamGUI/FlatCAMGUI.py:554 msgid "Add Text\tT" msgstr "Ajouter du Texte\tT" -#: flatcamGUI/FlatCAMGUI.py:518 +#: flatcamGUI/FlatCAMGUI.py:557 msgid "Polygon Union\tU" msgstr "Union de Polygones\tU" -#: flatcamGUI/FlatCAMGUI.py:520 +#: flatcamGUI/FlatCAMGUI.py:559 msgid "Polygon Intersection\tE" msgstr "Intersection de Polygones\tE" -#: flatcamGUI/FlatCAMGUI.py:522 +#: flatcamGUI/FlatCAMGUI.py:561 msgid "Polygon Subtraction\tS" msgstr "Soustraction de Polygone\tS" -#: flatcamGUI/FlatCAMGUI.py:526 +#: flatcamGUI/FlatCAMGUI.py:565 msgid "Cut Path\tX" msgstr "Chemin Coupé\tX" -#: flatcamGUI/FlatCAMGUI.py:529 +#: flatcamGUI/FlatCAMGUI.py:569 msgid "Copy Geom\tC" msgstr "Copier la Géométrie\tC" -#: flatcamGUI/FlatCAMGUI.py:531 +#: flatcamGUI/FlatCAMGUI.py:571 msgid "Delete Shape\tDEL" msgstr "Supprimer la Forme\tDEL" -#: flatcamGUI/FlatCAMGUI.py:535 flatcamGUI/FlatCAMGUI.py:622 +#: flatcamGUI/FlatCAMGUI.py:575 flatcamGUI/FlatCAMGUI.py:662 msgid "Move\tM" msgstr "Déplacer\tM" -#: flatcamGUI/FlatCAMGUI.py:537 +#: flatcamGUI/FlatCAMGUI.py:577 msgid "Buffer Tool\tB" msgstr "Outil Tampon\tB" -#: flatcamGUI/FlatCAMGUI.py:540 +#: flatcamGUI/FlatCAMGUI.py:580 msgid "Paint Tool\tI" msgstr "Outil de Peinture\tI" -#: flatcamGUI/FlatCAMGUI.py:543 +#: flatcamGUI/FlatCAMGUI.py:583 msgid "Transform Tool\tAlt+R" msgstr "Outil de Transformation\tAlt+R" -#: flatcamGUI/FlatCAMGUI.py:547 +#: flatcamGUI/FlatCAMGUI.py:587 msgid "Toggle Corner Snap\tK" msgstr "Basculer le Coin accrocher\tK" -#: flatcamGUI/FlatCAMGUI.py:553 +#: flatcamGUI/FlatCAMGUI.py:593 msgid ">Excellon Editor<" msgstr ">Excellent Éditeur<" -#: flatcamGUI/FlatCAMGUI.py:557 +#: flatcamGUI/FlatCAMGUI.py:597 msgid "Add Drill Array\tA" msgstr "Ajouter un Tableau de Forage\tA" -#: flatcamGUI/FlatCAMGUI.py:559 +#: flatcamGUI/FlatCAMGUI.py:599 msgid "Add Drill\tD" msgstr "Ajouter une Forage\tD" -#: flatcamGUI/FlatCAMGUI.py:563 +#: flatcamGUI/FlatCAMGUI.py:603 msgid "Add Slot Array\tQ" msgstr "Ajouter un Tableau de Fente\tQ" -#: flatcamGUI/FlatCAMGUI.py:565 +#: flatcamGUI/FlatCAMGUI.py:605 msgid "Add Slot\tW" msgstr "Ajouter une Fente\tW" -#: flatcamGUI/FlatCAMGUI.py:569 +#: flatcamGUI/FlatCAMGUI.py:609 msgid "Resize Drill(S)\tR" msgstr "Redimensionner le Foret\tR" -#: flatcamGUI/FlatCAMGUI.py:572 flatcamGUI/FlatCAMGUI.py:616 +#: flatcamGUI/FlatCAMGUI.py:612 flatcamGUI/FlatCAMGUI.py:656 msgid "Copy\tC" msgstr "Copie\tC" -#: flatcamGUI/FlatCAMGUI.py:574 flatcamGUI/FlatCAMGUI.py:618 +#: flatcamGUI/FlatCAMGUI.py:614 flatcamGUI/FlatCAMGUI.py:658 msgid "Delete\tDEL" msgstr "Supprimer\tDEL" -#: flatcamGUI/FlatCAMGUI.py:579 +#: flatcamGUI/FlatCAMGUI.py:619 msgid "Move Drill(s)\tM" msgstr "Déplacer les Forets\tM" -#: flatcamGUI/FlatCAMGUI.py:584 +#: flatcamGUI/FlatCAMGUI.py:624 msgid ">Gerber Editor<" msgstr ">Gerber Éditeur<" -#: flatcamGUI/FlatCAMGUI.py:588 +#: flatcamGUI/FlatCAMGUI.py:628 msgid "Add Pad\tP" msgstr "Ajouter un Pad\tP" -#: flatcamGUI/FlatCAMGUI.py:590 +#: flatcamGUI/FlatCAMGUI.py:630 msgid "Add Pad Array\tA" msgstr "Ajouter un Tableau de Pad\tA" -#: flatcamGUI/FlatCAMGUI.py:592 +#: flatcamGUI/FlatCAMGUI.py:632 msgid "Add Track\tT" msgstr "Ajouter une Piste\tT" -#: flatcamGUI/FlatCAMGUI.py:594 +#: flatcamGUI/FlatCAMGUI.py:634 msgid "Add Region\tN" msgstr "Ajouter une Région\tN" -#: flatcamGUI/FlatCAMGUI.py:598 +#: flatcamGUI/FlatCAMGUI.py:638 msgid "Poligonize\tAlt+N" msgstr "Polygoniser\tAlt+N" -#: flatcamGUI/FlatCAMGUI.py:600 +#: flatcamGUI/FlatCAMGUI.py:640 msgid "Add SemiDisc\tE" msgstr "Ajouter un Semi-Disque\tE" -#: flatcamGUI/FlatCAMGUI.py:602 +#: flatcamGUI/FlatCAMGUI.py:642 msgid "Add Disc\tD" msgstr "Ajouter un Disque\tD" -#: flatcamGUI/FlatCAMGUI.py:604 +#: flatcamGUI/FlatCAMGUI.py:644 msgid "Buffer\tB" msgstr "Tampon\tB" -#: flatcamGUI/FlatCAMGUI.py:606 +#: flatcamGUI/FlatCAMGUI.py:646 msgid "Scale\tS" msgstr "Échelle\tS" -#: flatcamGUI/FlatCAMGUI.py:608 +#: flatcamGUI/FlatCAMGUI.py:648 msgid "Mark Area\tAlt+A" msgstr "Zone de Marque\tAlt+A" -#: flatcamGUI/FlatCAMGUI.py:610 +#: flatcamGUI/FlatCAMGUI.py:650 msgid "Eraser\tCtrl+E" msgstr "La Gomme\tCtrl+E" -#: flatcamGUI/FlatCAMGUI.py:612 +#: flatcamGUI/FlatCAMGUI.py:652 msgid "Transform\tAlt+R" msgstr "Transformation\tAlt+R" -#: flatcamGUI/FlatCAMGUI.py:639 +#: flatcamGUI/FlatCAMGUI.py:679 msgid "Enable Plot" msgstr "Activer le Tracé" -#: flatcamGUI/FlatCAMGUI.py:641 +#: flatcamGUI/FlatCAMGUI.py:681 msgid "Disable Plot" msgstr "Désactiver le Tracé" -#: flatcamGUI/FlatCAMGUI.py:645 +#: flatcamGUI/FlatCAMGUI.py:685 msgid "Set Color" msgstr "Définir la couleur" -#: flatcamGUI/FlatCAMGUI.py:648 -msgid "Red" -msgstr "Rouge" - -#: flatcamGUI/FlatCAMGUI.py:651 -msgid "Blue" -msgstr "Bleu" - -#: flatcamGUI/FlatCAMGUI.py:654 -msgid "Yellow" -msgstr "Jaune" - -#: flatcamGUI/FlatCAMGUI.py:657 -msgid "Green" -msgstr "Vert" - -#: flatcamGUI/FlatCAMGUI.py:660 -msgid "Purple" -msgstr "Violet" - -#: flatcamGUI/FlatCAMGUI.py:663 -msgid "Brown" -msgstr "Marron" - -#: flatcamGUI/FlatCAMGUI.py:666 -msgid "Custom" -msgstr "Personnalisé" - -#: flatcamGUI/FlatCAMGUI.py:671 +#: flatcamGUI/FlatCAMGUI.py:727 msgid "Generate CNC" msgstr "Générer CNC" -#: flatcamGUI/FlatCAMGUI.py:673 +#: flatcamGUI/FlatCAMGUI.py:729 msgid "View Source" msgstr "Voir la source" -#: flatcamGUI/FlatCAMGUI.py:686 flatcamGUI/FlatCAMGUI.py:2172 -#: flatcamTools/ToolProperties.py:30 +#: flatcamGUI/FlatCAMGUI.py:742 flatcamGUI/FlatCAMGUI.py:2280 +#: flatcamTools/ToolProperties.py:31 msgid "Properties" msgstr "Propriétés" -#: flatcamGUI/FlatCAMGUI.py:715 +#: flatcamGUI/FlatCAMGUI.py:771 msgid "File Toolbar" msgstr "Barre d'outils de fichiers" -#: flatcamGUI/FlatCAMGUI.py:719 +#: flatcamGUI/FlatCAMGUI.py:775 msgid "Edit Toolbar" msgstr "Barre d'outils de editer" -#: flatcamGUI/FlatCAMGUI.py:723 +#: flatcamGUI/FlatCAMGUI.py:779 msgid "View Toolbar" msgstr "Barre d'outils de vue" -#: flatcamGUI/FlatCAMGUI.py:727 +#: flatcamGUI/FlatCAMGUI.py:783 msgid "Shell Toolbar" msgstr "Barre d'outils Shell" -#: flatcamGUI/FlatCAMGUI.py:731 +#: flatcamGUI/FlatCAMGUI.py:787 msgid "Tools Toolbar" msgstr "Barre d'outils de outils" -#: flatcamGUI/FlatCAMGUI.py:735 +#: flatcamGUI/FlatCAMGUI.py:791 msgid "Excellon Editor Toolbar" msgstr "Barre d'outils de l'éditeur Excellon" -#: flatcamGUI/FlatCAMGUI.py:741 +#: flatcamGUI/FlatCAMGUI.py:797 msgid "Geometry Editor Toolbar" msgstr "Barre d'outils de l'éditeur de Géométrie" -#: flatcamGUI/FlatCAMGUI.py:745 +#: flatcamGUI/FlatCAMGUI.py:801 msgid "Gerber Editor Toolbar" msgstr "Barre d'outils de l'éditeur Gerber" -#: flatcamGUI/FlatCAMGUI.py:749 +#: flatcamGUI/FlatCAMGUI.py:805 msgid "Grid Toolbar" msgstr "Barre d'outils de la Grille" -#: flatcamGUI/FlatCAMGUI.py:772 flatcamGUI/FlatCAMGUI.py:2357 +#: flatcamGUI/FlatCAMGUI.py:826 flatcamGUI/FlatCAMGUI.py:2509 msgid "Open project" msgstr "Projet ouvert" -#: flatcamGUI/FlatCAMGUI.py:774 flatcamGUI/FlatCAMGUI.py:2359 +#: flatcamGUI/FlatCAMGUI.py:828 flatcamGUI/FlatCAMGUI.py:2511 msgid "Save project" msgstr "Sauvegarder le projet" -#: flatcamGUI/FlatCAMGUI.py:780 flatcamGUI/FlatCAMGUI.py:2363 +#: flatcamGUI/FlatCAMGUI.py:834 flatcamGUI/FlatCAMGUI.py:2517 msgid "New Blank Geometry" msgstr "Nouvelle Géométrie vierge" -#: flatcamGUI/FlatCAMGUI.py:782 flatcamGUI/FlatCAMGUI.py:2365 +#: flatcamGUI/FlatCAMGUI.py:836 flatcamGUI/FlatCAMGUI.py:2519 msgid "New Blank Gerber" msgstr "Nouveau Gerber vierge" -#: flatcamGUI/FlatCAMGUI.py:784 flatcamGUI/FlatCAMGUI.py:2367 +#: flatcamGUI/FlatCAMGUI.py:838 flatcamGUI/FlatCAMGUI.py:2521 msgid "New Blank Excellon" msgstr "Nouveau Excellon vierge" -#: flatcamGUI/FlatCAMGUI.py:789 flatcamGUI/FlatCAMGUI.py:2373 +#: flatcamGUI/FlatCAMGUI.py:843 flatcamGUI/FlatCAMGUI.py:2527 msgid "Save Object and close the Editor" msgstr "Enregistrer un objet et fermer l'éditeur" -#: flatcamGUI/FlatCAMGUI.py:796 flatcamGUI/FlatCAMGUI.py:2380 +#: flatcamGUI/FlatCAMGUI.py:850 flatcamGUI/FlatCAMGUI.py:2534 msgid "&Delete" msgstr "Supprimer" -#: flatcamGUI/FlatCAMGUI.py:799 flatcamGUI/FlatCAMGUI.py:1613 -#: flatcamGUI/FlatCAMGUI.py:1812 flatcamGUI/FlatCAMGUI.py:2383 -#: flatcamTools/ToolDistance.py:30 flatcamTools/ToolDistance.py:160 +#: flatcamGUI/FlatCAMGUI.py:853 flatcamGUI/FlatCAMGUI.py:1714 +#: flatcamGUI/FlatCAMGUI.py:1920 flatcamGUI/FlatCAMGUI.py:2537 +#: flatcamTools/ToolDistance.py:35 flatcamTools/ToolDistance.py:195 msgid "Distance Tool" msgstr "Outil de Distance" -#: flatcamGUI/FlatCAMGUI.py:801 flatcamGUI/FlatCAMGUI.py:2385 +#: flatcamGUI/FlatCAMGUI.py:855 flatcamGUI/FlatCAMGUI.py:2539 msgid "Distance Min Tool" msgstr "Outil Distance Min" -#: flatcamGUI/FlatCAMGUI.py:803 flatcamGUI/FlatCAMGUI.py:1606 -#: flatcamGUI/FlatCAMGUI.py:2387 +#: flatcamGUI/FlatCAMGUI.py:857 flatcamGUI/FlatCAMGUI.py:1707 +#: flatcamGUI/FlatCAMGUI.py:2541 msgid "Set Origin" msgstr "Définir l'origine" -#: flatcamGUI/FlatCAMGUI.py:805 flatcamGUI/FlatCAMGUI.py:2389 +#: flatcamGUI/FlatCAMGUI.py:859 +msgid "Move to Origin" +msgstr "Déplacer vers l'origine" + +#: flatcamGUI/FlatCAMGUI.py:862 flatcamGUI/FlatCAMGUI.py:2543 msgid "Jump to Location" msgstr "Aller à l'emplacement" -#: flatcamGUI/FlatCAMGUI.py:811 flatcamGUI/FlatCAMGUI.py:2393 +#: flatcamGUI/FlatCAMGUI.py:864 flatcamGUI/FlatCAMGUI.py:1719 +#: flatcamGUI/FlatCAMGUI.py:2545 +msgid "Locate in Object" +msgstr "Localiser dans l'objet" + +#: flatcamGUI/FlatCAMGUI.py:870 flatcamGUI/FlatCAMGUI.py:2551 msgid "&Replot" msgstr "Re-Tracé" -#: flatcamGUI/FlatCAMGUI.py:813 flatcamGUI/FlatCAMGUI.py:2395 +#: flatcamGUI/FlatCAMGUI.py:872 flatcamGUI/FlatCAMGUI.py:2553 msgid "&Clear plot" msgstr "Effacer la Trace" -#: flatcamGUI/FlatCAMGUI.py:815 flatcamGUI/FlatCAMGUI.py:1609 -#: flatcamGUI/FlatCAMGUI.py:2397 +#: flatcamGUI/FlatCAMGUI.py:874 flatcamGUI/FlatCAMGUI.py:1710 +#: flatcamGUI/FlatCAMGUI.py:2555 msgid "Zoom In" msgstr "Agrandir" -#: flatcamGUI/FlatCAMGUI.py:817 flatcamGUI/FlatCAMGUI.py:1609 -#: flatcamGUI/FlatCAMGUI.py:2399 +#: flatcamGUI/FlatCAMGUI.py:876 flatcamGUI/FlatCAMGUI.py:1710 +#: flatcamGUI/FlatCAMGUI.py:2557 msgid "Zoom Out" msgstr "Dézoomer" -#: flatcamGUI/FlatCAMGUI.py:819 flatcamGUI/FlatCAMGUI.py:1608 -#: flatcamGUI/FlatCAMGUI.py:2062 flatcamGUI/FlatCAMGUI.py:2401 +#: flatcamGUI/FlatCAMGUI.py:878 flatcamGUI/FlatCAMGUI.py:1709 +#: flatcamGUI/FlatCAMGUI.py:2170 flatcamGUI/FlatCAMGUI.py:2559 msgid "Zoom Fit" msgstr "Ajustement du Zoom" -#: flatcamGUI/FlatCAMGUI.py:827 flatcamGUI/FlatCAMGUI.py:2407 +#: flatcamGUI/FlatCAMGUI.py:886 flatcamGUI/FlatCAMGUI.py:2565 msgid "&Command Line" msgstr "&Ligne de commande" -#: flatcamGUI/FlatCAMGUI.py:839 flatcamGUI/FlatCAMGUI.py:2417 +#: flatcamGUI/FlatCAMGUI.py:898 flatcamGUI/FlatCAMGUI.py:2577 msgid "2Sided Tool" msgstr "Outil 2 faces" -#: flatcamGUI/FlatCAMGUI.py:841 flatcamGUI/ObjectUI.py:588 -#: flatcamTools/ToolCutOut.py:436 +#: flatcamGUI/FlatCAMGUI.py:900 flatcamGUI/FlatCAMGUI.py:1725 +#: flatcamGUI/FlatCAMGUI.py:2579 +msgid "Align Objects Tool" +msgstr "Outil Aligner les objets" + +#: flatcamGUI/FlatCAMGUI.py:902 flatcamGUI/FlatCAMGUI.py:1726 +#: flatcamGUI/FlatCAMGUI.py:2581 flatcamTools/ToolExtractDrills.py:393 +msgid "Extract Drills Tool" +msgstr "Outil d'extraction de forets" + +#: flatcamGUI/FlatCAMGUI.py:905 flatcamGUI/ObjectUI.py:595 +#: flatcamTools/ToolCutOut.py:447 msgid "Cutout Tool" msgstr "Outil de Découpe" -#: flatcamGUI/FlatCAMGUI.py:843 flatcamGUI/FlatCAMGUI.py:2421 -#: flatcamGUI/ObjectUI.py:566 flatcamGUI/ObjectUI.py:1749 -#: flatcamTools/ToolNonCopperClear.py:632 +#: flatcamGUI/FlatCAMGUI.py:907 flatcamGUI/FlatCAMGUI.py:2586 +#: flatcamGUI/ObjectUI.py:573 flatcamGUI/ObjectUI.py:2075 +#: flatcamTools/ToolNCC.py:974 msgid "NCC Tool" msgstr "Outil de la NCC" -#: flatcamGUI/FlatCAMGUI.py:849 flatcamGUI/FlatCAMGUI.py:2427 +#: flatcamGUI/FlatCAMGUI.py:913 flatcamGUI/FlatCAMGUI.py:2592 msgid "Panel Tool" msgstr "Outil de Panneau" -#: flatcamGUI/FlatCAMGUI.py:851 flatcamGUI/FlatCAMGUI.py:2429 -#: flatcamTools/ToolFilm.py:578 +#: flatcamGUI/FlatCAMGUI.py:915 flatcamGUI/FlatCAMGUI.py:2594 +#: flatcamTools/ToolFilm.py:586 msgid "Film Tool" msgstr "Outil de Film" -#: flatcamGUI/FlatCAMGUI.py:853 flatcamGUI/FlatCAMGUI.py:2432 -#: flatcamTools/ToolSolderPaste.py:547 +#: flatcamGUI/FlatCAMGUI.py:917 flatcamGUI/FlatCAMGUI.py:2596 +#: flatcamTools/ToolSolderPaste.py:553 msgid "SolderPaste Tool" msgstr "Outil de Pâte à souder" -#: flatcamGUI/FlatCAMGUI.py:855 flatcamGUI/FlatCAMGUI.py:2434 +#: flatcamGUI/FlatCAMGUI.py:919 flatcamGUI/FlatCAMGUI.py:2598 #: flatcamTools/ToolSub.py:35 msgid "Subtract Tool" msgstr "Outil de Soustraction" -#: flatcamGUI/FlatCAMGUI.py:857 flatcamTools/ToolRulesCheck.py:607 +#: flatcamGUI/FlatCAMGUI.py:921 flatcamGUI/FlatCAMGUI.py:2600 +#: flatcamTools/ToolRulesCheck.py:616 msgid "Rules Tool" msgstr "Outil de Règles" -#: flatcamGUI/FlatCAMGUI.py:859 flatcamGUI/FlatCAMGUI.py:1624 -#: flatcamTools/ToolOptimal.py:34 flatcamTools/ToolOptimal.py:310 +#: flatcamGUI/FlatCAMGUI.py:923 flatcamGUI/FlatCAMGUI.py:1728 +#: flatcamGUI/FlatCAMGUI.py:2602 flatcamTools/ToolOptimal.py:34 +#: flatcamTools/ToolOptimal.py:308 msgid "Optimal Tool" msgstr "Outil de Optimal" -#: flatcamGUI/FlatCAMGUI.py:864 flatcamGUI/FlatCAMGUI.py:1622 -#: flatcamGUI/FlatCAMGUI.py:2439 +#: flatcamGUI/FlatCAMGUI.py:928 flatcamGUI/FlatCAMGUI.py:1725 +#: flatcamGUI/FlatCAMGUI.py:2607 msgid "Calculators Tool" msgstr "Outil de Calcul" -#: flatcamGUI/FlatCAMGUI.py:868 flatcamGUI/FlatCAMGUI.py:1625 -#: flatcamGUI/FlatCAMGUI.py:2443 flatcamTools/ToolQRCode.py:43 +#: flatcamGUI/FlatCAMGUI.py:932 flatcamGUI/FlatCAMGUI.py:1729 +#: flatcamGUI/FlatCAMGUI.py:2611 flatcamTools/ToolQRCode.py:43 #: flatcamTools/ToolQRCode.py:382 msgid "QRCode Tool" msgstr "Outil QRCode" -#: flatcamGUI/FlatCAMGUI.py:870 flatcamGUI/FlatCAMGUI.py:2445 -#: flatcamTools/ToolCopperThieving.py:40 flatcamTools/ToolCopperThieving.py:566 +#: flatcamGUI/FlatCAMGUI.py:934 flatcamGUI/FlatCAMGUI.py:2613 +#: flatcamTools/ToolCopperThieving.py:40 flatcamTools/ToolCopperThieving.py:569 msgid "Copper Thieving Tool" msgstr "Outil de Copper Thieving" -#: flatcamGUI/FlatCAMGUI.py:873 flatcamGUI/FlatCAMGUI.py:1622 -#: flatcamGUI/FlatCAMGUI.py:2448 flatcamTools/ToolFiducials.py:33 -#: flatcamTools/ToolFiducials.py:393 +#: flatcamGUI/FlatCAMGUI.py:937 flatcamGUI/FlatCAMGUI.py:1726 +#: flatcamGUI/FlatCAMGUI.py:2616 flatcamTools/ToolFiducials.py:33 +#: flatcamTools/ToolFiducials.py:395 msgid "Fiducials Tool" msgstr "Outil Fiduciaire" -#: flatcamGUI/FlatCAMGUI.py:875 flatcamGUI/FlatCAMGUI.py:2450 -#: flatcamTools/ToolCalibration.py:37 flatcamTools/ToolCalibration.py:762 +#: flatcamGUI/FlatCAMGUI.py:939 flatcamGUI/FlatCAMGUI.py:2618 +#: flatcamTools/ToolCalibration.py:37 flatcamTools/ToolCalibration.py:759 msgid "Calibration Tool" msgstr "Outil d'Étalonnage" -#: flatcamGUI/FlatCAMGUI.py:881 flatcamGUI/FlatCAMGUI.py:907 -#: flatcamGUI/FlatCAMGUI.py:959 flatcamGUI/FlatCAMGUI.py:2454 -#: flatcamGUI/FlatCAMGUI.py:2528 +#: flatcamGUI/FlatCAMGUI.py:941 flatcamGUI/FlatCAMGUI.py:1726 +msgid "Punch Gerber Tool" +msgstr "Outil de poinçonnage Gerber" + +#: flatcamGUI/FlatCAMGUI.py:943 flatcamTools/ToolInvertGerber.py:31 +msgid "Invert Gerber Tool" +msgstr "Outil de Inverser Gerber" + +#: flatcamGUI/FlatCAMGUI.py:949 flatcamGUI/FlatCAMGUI.py:975 +#: flatcamGUI/FlatCAMGUI.py:1027 flatcamGUI/FlatCAMGUI.py:2624 +#: flatcamGUI/FlatCAMGUI.py:2702 msgid "Select" msgstr "Sélectionner" -#: flatcamGUI/FlatCAMGUI.py:883 flatcamGUI/FlatCAMGUI.py:2456 +#: flatcamGUI/FlatCAMGUI.py:951 flatcamGUI/FlatCAMGUI.py:2626 msgid "Add Drill Hole" msgstr "Ajouter une Forage" -#: flatcamGUI/FlatCAMGUI.py:885 flatcamGUI/FlatCAMGUI.py:2458 +#: flatcamGUI/FlatCAMGUI.py:953 flatcamGUI/FlatCAMGUI.py:2628 msgid "Add Drill Hole Array" msgstr "Ajouter un Tableau de Forage" -#: flatcamGUI/FlatCAMGUI.py:887 flatcamGUI/FlatCAMGUI.py:1897 -#: flatcamGUI/FlatCAMGUI.py:2150 flatcamGUI/FlatCAMGUI.py:2462 +#: flatcamGUI/FlatCAMGUI.py:955 flatcamGUI/FlatCAMGUI.py:2005 +#: flatcamGUI/FlatCAMGUI.py:2258 flatcamGUI/FlatCAMGUI.py:2632 msgid "Add Slot" msgstr "Ajouter une Fente" -#: flatcamGUI/FlatCAMGUI.py:889 flatcamGUI/FlatCAMGUI.py:1896 -#: flatcamGUI/FlatCAMGUI.py:2152 flatcamGUI/FlatCAMGUI.py:2464 +#: flatcamGUI/FlatCAMGUI.py:957 flatcamGUI/FlatCAMGUI.py:2004 +#: flatcamGUI/FlatCAMGUI.py:2260 flatcamGUI/FlatCAMGUI.py:2634 msgid "Add Slot Array" msgstr "Ajouter un Tableau de Fente" -#: flatcamGUI/FlatCAMGUI.py:891 flatcamGUI/FlatCAMGUI.py:2155 -#: flatcamGUI/FlatCAMGUI.py:2460 +#: flatcamGUI/FlatCAMGUI.py:959 flatcamGUI/FlatCAMGUI.py:2263 +#: flatcamGUI/FlatCAMGUI.py:2630 msgid "Resize Drill" msgstr "Redimensionner Forage" -#: flatcamGUI/FlatCAMGUI.py:895 flatcamGUI/FlatCAMGUI.py:2468 +#: flatcamGUI/FlatCAMGUI.py:963 flatcamGUI/FlatCAMGUI.py:2638 msgid "Copy Drill" msgstr "Copier une Forage" -#: flatcamGUI/FlatCAMGUI.py:897 flatcamGUI/FlatCAMGUI.py:2470 +#: flatcamGUI/FlatCAMGUI.py:965 flatcamGUI/FlatCAMGUI.py:2640 msgid "Delete Drill" msgstr "Supprimer une Forage" -#: flatcamGUI/FlatCAMGUI.py:901 flatcamGUI/FlatCAMGUI.py:2474 +#: flatcamGUI/FlatCAMGUI.py:969 flatcamGUI/FlatCAMGUI.py:2644 msgid "Move Drill" msgstr "Déplacer uen Forage" -#: flatcamGUI/FlatCAMGUI.py:909 flatcamGUI/FlatCAMGUI.py:2480 +#: flatcamGUI/FlatCAMGUI.py:977 flatcamGUI/FlatCAMGUI.py:2652 msgid "Add Circle" msgstr "Ajouter un Cercle" -#: flatcamGUI/FlatCAMGUI.py:911 flatcamGUI/FlatCAMGUI.py:2482 +#: flatcamGUI/FlatCAMGUI.py:979 flatcamGUI/FlatCAMGUI.py:2654 msgid "Add Arc" msgstr "Ajouter un Arc" -#: flatcamGUI/FlatCAMGUI.py:913 flatcamGUI/FlatCAMGUI.py:2484 +#: flatcamGUI/FlatCAMGUI.py:981 flatcamGUI/FlatCAMGUI.py:2656 msgid "Add Rectangle" msgstr "Ajouter un Rectangle" -#: flatcamGUI/FlatCAMGUI.py:917 flatcamGUI/FlatCAMGUI.py:2488 +#: flatcamGUI/FlatCAMGUI.py:985 flatcamGUI/FlatCAMGUI.py:2660 msgid "Add Path" msgstr "Ajouter un Chemin" -#: flatcamGUI/FlatCAMGUI.py:919 flatcamGUI/FlatCAMGUI.py:2490 +#: flatcamGUI/FlatCAMGUI.py:987 flatcamGUI/FlatCAMGUI.py:2662 msgid "Add Polygon" msgstr "Ajouter un Polygone" -#: flatcamGUI/FlatCAMGUI.py:922 flatcamGUI/FlatCAMGUI.py:2493 +#: flatcamGUI/FlatCAMGUI.py:990 flatcamGUI/FlatCAMGUI.py:2665 msgid "Add Text" msgstr "Ajouter du Texte" -#: flatcamGUI/FlatCAMGUI.py:924 flatcamGUI/FlatCAMGUI.py:2495 +#: flatcamGUI/FlatCAMGUI.py:992 flatcamGUI/FlatCAMGUI.py:2667 msgid "Add Buffer" msgstr "Ajouter un Tampon" -#: flatcamGUI/FlatCAMGUI.py:926 flatcamGUI/FlatCAMGUI.py:2497 +#: flatcamGUI/FlatCAMGUI.py:994 flatcamGUI/FlatCAMGUI.py:2669 msgid "Paint Shape" msgstr "Peindre une Forme" -#: flatcamGUI/FlatCAMGUI.py:928 flatcamGUI/FlatCAMGUI.py:985 -#: flatcamGUI/FlatCAMGUI.py:2091 flatcamGUI/FlatCAMGUI.py:2136 -#: flatcamGUI/FlatCAMGUI.py:2499 flatcamGUI/FlatCAMGUI.py:2553 +#: flatcamGUI/FlatCAMGUI.py:996 flatcamGUI/FlatCAMGUI.py:1053 +#: flatcamGUI/FlatCAMGUI.py:2199 flatcamGUI/FlatCAMGUI.py:2244 +#: flatcamGUI/FlatCAMGUI.py:2671 flatcamGUI/FlatCAMGUI.py:2727 msgid "Eraser" msgstr "La Gomme" -#: flatcamGUI/FlatCAMGUI.py:932 flatcamGUI/FlatCAMGUI.py:2503 +#: flatcamGUI/FlatCAMGUI.py:1000 flatcamGUI/FlatCAMGUI.py:2675 msgid "Polygon Union" msgstr "Union de Polygones" -#: flatcamGUI/FlatCAMGUI.py:934 flatcamGUI/FlatCAMGUI.py:2505 +#: flatcamGUI/FlatCAMGUI.py:1002 flatcamGUI/FlatCAMGUI.py:2677 msgid "Polygon Explode" msgstr "Éclatement de polygone" -#: flatcamGUI/FlatCAMGUI.py:937 flatcamGUI/FlatCAMGUI.py:2508 +#: flatcamGUI/FlatCAMGUI.py:1005 flatcamGUI/FlatCAMGUI.py:2680 msgid "Polygon Intersection" msgstr "Intersection de Polygones" -#: flatcamGUI/FlatCAMGUI.py:939 flatcamGUI/FlatCAMGUI.py:2510 +#: flatcamGUI/FlatCAMGUI.py:1007 flatcamGUI/FlatCAMGUI.py:2682 msgid "Polygon Subtraction" msgstr "Soustraction de Polygone" -#: flatcamGUI/FlatCAMGUI.py:943 flatcamGUI/FlatCAMGUI.py:2514 +#: flatcamGUI/FlatCAMGUI.py:1011 flatcamGUI/FlatCAMGUI.py:2686 msgid "Cut Path" msgstr "Chemin Coupé" -#: flatcamGUI/FlatCAMGUI.py:945 +#: flatcamGUI/FlatCAMGUI.py:1013 msgid "Copy Shape(s)" msgstr "Copier les Formes" -#: flatcamGUI/FlatCAMGUI.py:948 +#: flatcamGUI/FlatCAMGUI.py:1016 msgid "Delete Shape '-'" msgstr "Supprimer la Forme" -#: flatcamGUI/FlatCAMGUI.py:950 flatcamGUI/FlatCAMGUI.py:993 -#: flatcamGUI/FlatCAMGUI.py:2103 flatcamGUI/FlatCAMGUI.py:2140 -#: flatcamGUI/FlatCAMGUI.py:2520 flatcamGUI/FlatCAMGUI.py:2561 +#: flatcamGUI/FlatCAMGUI.py:1018 flatcamGUI/FlatCAMGUI.py:1061 +#: flatcamGUI/FlatCAMGUI.py:2211 flatcamGUI/FlatCAMGUI.py:2248 +#: flatcamGUI/FlatCAMGUI.py:2692 flatcamGUI/FlatCAMGUI.py:2735 +#: flatcamGUI/ObjectUI.py:108 msgid "Transformations" msgstr "Transformations" -#: flatcamGUI/FlatCAMGUI.py:953 +#: flatcamGUI/FlatCAMGUI.py:1021 msgid "Move Objects " msgstr "Déplacer des objets " -#: flatcamGUI/FlatCAMGUI.py:961 flatcamGUI/FlatCAMGUI.py:2016 -#: flatcamGUI/FlatCAMGUI.py:2530 +#: flatcamGUI/FlatCAMGUI.py:1029 flatcamGUI/FlatCAMGUI.py:2124 +#: flatcamGUI/FlatCAMGUI.py:2704 msgid "Add Pad" msgstr "Ajouter un Pad" -#: flatcamGUI/FlatCAMGUI.py:965 flatcamGUI/FlatCAMGUI.py:2017 -#: flatcamGUI/FlatCAMGUI.py:2534 +#: flatcamGUI/FlatCAMGUI.py:1033 flatcamGUI/FlatCAMGUI.py:2125 +#: flatcamGUI/FlatCAMGUI.py:2708 msgid "Add Track" msgstr "Ajouter une Piste" -#: flatcamGUI/FlatCAMGUI.py:967 flatcamGUI/FlatCAMGUI.py:2016 -#: flatcamGUI/FlatCAMGUI.py:2536 +#: flatcamGUI/FlatCAMGUI.py:1035 flatcamGUI/FlatCAMGUI.py:2124 +#: flatcamGUI/FlatCAMGUI.py:2710 msgid "Add Region" msgstr "Ajouter une Région" -#: flatcamGUI/FlatCAMGUI.py:969 flatcamGUI/FlatCAMGUI.py:2122 -#: flatcamGUI/FlatCAMGUI.py:2538 +#: flatcamGUI/FlatCAMGUI.py:1037 flatcamGUI/FlatCAMGUI.py:2230 +#: flatcamGUI/FlatCAMGUI.py:2712 msgid "Poligonize" msgstr "Polygoniser" -#: flatcamGUI/FlatCAMGUI.py:972 flatcamGUI/FlatCAMGUI.py:2124 -#: flatcamGUI/FlatCAMGUI.py:2541 +#: flatcamGUI/FlatCAMGUI.py:1040 flatcamGUI/FlatCAMGUI.py:2232 +#: flatcamGUI/FlatCAMGUI.py:2715 msgid "SemiDisc" msgstr "Semi Disque" -#: flatcamGUI/FlatCAMGUI.py:974 flatcamGUI/FlatCAMGUI.py:2126 -#: flatcamGUI/FlatCAMGUI.py:2543 +#: flatcamGUI/FlatCAMGUI.py:1042 flatcamGUI/FlatCAMGUI.py:2234 +#: flatcamGUI/FlatCAMGUI.py:2717 msgid "Disc" msgstr "Disque" -#: flatcamGUI/FlatCAMGUI.py:982 flatcamGUI/FlatCAMGUI.py:2134 -#: flatcamGUI/FlatCAMGUI.py:2551 +#: flatcamGUI/FlatCAMGUI.py:1050 flatcamGUI/FlatCAMGUI.py:2242 +#: flatcamGUI/FlatCAMGUI.py:2725 msgid "Mark Area" msgstr "Zone de Marque" -#: flatcamGUI/FlatCAMGUI.py:996 flatcamGUI/FlatCAMGUI.py:2016 -#: flatcamGUI/FlatCAMGUI.py:2107 flatcamGUI/FlatCAMGUI.py:2170 -#: flatcamGUI/FlatCAMGUI.py:2564 flatcamTools/ToolMove.py:28 +#: flatcamGUI/FlatCAMGUI.py:1064 flatcamGUI/FlatCAMGUI.py:2124 +#: flatcamGUI/FlatCAMGUI.py:2215 flatcamGUI/FlatCAMGUI.py:2278 +#: flatcamGUI/FlatCAMGUI.py:2738 flatcamTools/ToolMove.py:28 msgid "Move" msgstr "Déplacer" -#: flatcamGUI/FlatCAMGUI.py:1004 flatcamGUI/FlatCAMGUI.py:2571 +#: flatcamGUI/FlatCAMGUI.py:1072 flatcamGUI/FlatCAMGUI.py:2747 msgid "Snap to grid" msgstr "Aligner sur la Grille" -#: flatcamGUI/FlatCAMGUI.py:1007 flatcamGUI/FlatCAMGUI.py:2574 +#: flatcamGUI/FlatCAMGUI.py:1075 flatcamGUI/FlatCAMGUI.py:2750 msgid "Grid X snapping distance" msgstr "Distance d'accrochage de la grille X" -#: flatcamGUI/FlatCAMGUI.py:1012 flatcamGUI/FlatCAMGUI.py:2579 +#: flatcamGUI/FlatCAMGUI.py:1080 flatcamGUI/FlatCAMGUI.py:2755 msgid "Grid Y snapping distance" msgstr "Distance d'accrochage de la grille Y" -#: flatcamGUI/FlatCAMGUI.py:1018 flatcamGUI/FlatCAMGUI.py:2585 +#: flatcamGUI/FlatCAMGUI.py:1086 flatcamGUI/FlatCAMGUI.py:2761 msgid "" "When active, value on Grid_X\n" "is copied to the Grid_Y value." @@ -6315,63 +6646,64 @@ msgstr "" "Lorsque actif, valeur sur Grid_X\n" "est copié dans la valeur Grid_Y." -#: flatcamGUI/FlatCAMGUI.py:1025 flatcamGUI/FlatCAMGUI.py:2592 +#: flatcamGUI/FlatCAMGUI.py:1093 flatcamGUI/FlatCAMGUI.py:2768 msgid "Snap to corner" msgstr "Accrocher au coin" -#: flatcamGUI/FlatCAMGUI.py:1029 flatcamGUI/FlatCAMGUI.py:2596 -#: flatcamGUI/PreferencesUI.py:984 +#: flatcamGUI/FlatCAMGUI.py:1097 flatcamGUI/FlatCAMGUI.py:2772 +#: flatcamGUI/PreferencesUI.py:1159 msgid "Max. magnet distance" msgstr "Max. distance d'aimant" -#: flatcamGUI/FlatCAMGUI.py:1063 +#: flatcamGUI/FlatCAMGUI.py:1134 msgid "Selected" msgstr "Choisi" -#: flatcamGUI/FlatCAMGUI.py:1090 flatcamGUI/FlatCAMGUI.py:1098 +#: flatcamGUI/FlatCAMGUI.py:1162 flatcamGUI/FlatCAMGUI.py:1170 msgid "Plot Area" msgstr "Zone de Dessin" -#: flatcamGUI/FlatCAMGUI.py:1125 +#: flatcamGUI/FlatCAMGUI.py:1197 msgid "General" msgstr "Général" -#: flatcamGUI/FlatCAMGUI.py:1140 flatcamTools/ToolCopperThieving.py:74 -#: flatcamTools/ToolDblSided.py:59 flatcamTools/ToolOptimal.py:71 -#: flatcamTools/ToolQRCode.py:77 +#: flatcamGUI/FlatCAMGUI.py:1212 flatcamTools/ToolCopperThieving.py:75 +#: flatcamTools/ToolDblSided.py:65 flatcamTools/ToolExtractDrills.py:61 +#: flatcamTools/ToolInvertGerber.py:72 flatcamTools/ToolOptimal.py:72 +#: flatcamTools/ToolPunchGerber.py:64 msgid "GERBER" msgstr "GERBER" -#: flatcamGUI/FlatCAMGUI.py:1150 flatcamTools/ToolDblSided.py:87 +#: flatcamGUI/FlatCAMGUI.py:1222 flatcamTools/ToolDblSided.py:93 msgid "EXCELLON" msgstr "EXCELLON" -#: flatcamGUI/FlatCAMGUI.py:1160 flatcamTools/ToolDblSided.py:115 +#: flatcamGUI/FlatCAMGUI.py:1232 flatcamTools/ToolDblSided.py:121 msgid "GEOMETRY" msgstr "GÉOMÉTRIE" -#: flatcamGUI/FlatCAMGUI.py:1170 +#: flatcamGUI/FlatCAMGUI.py:1242 msgid "CNC-JOB" msgstr "CNC-JOB" -#: flatcamGUI/FlatCAMGUI.py:1179 flatcamGUI/ObjectUI.py:555 -#: flatcamGUI/ObjectUI.py:1724 +#: flatcamGUI/FlatCAMGUI.py:1251 flatcamGUI/ObjectUI.py:562 +#: flatcamGUI/ObjectUI.py:2050 msgid "TOOLS" msgstr "OUTILS" -#: flatcamGUI/FlatCAMGUI.py:1188 +#: flatcamGUI/FlatCAMGUI.py:1260 msgid "TOOLS 2" msgstr "OUTILS 2" -#: flatcamGUI/FlatCAMGUI.py:1198 +#: flatcamGUI/FlatCAMGUI.py:1270 msgid "UTILITIES" msgstr "UTILITAIRES" -#: flatcamGUI/FlatCAMGUI.py:1215 flatcamGUI/PreferencesUI.py:2833 +#: flatcamGUI/FlatCAMGUI.py:1287 flatcamGUI/PreferencesUI.py:3015 msgid "Restore Defaults" msgstr "Restaurer les valeurs par défaut" -#: flatcamGUI/FlatCAMGUI.py:1218 +#: flatcamGUI/FlatCAMGUI.py:1290 msgid "" "Restore the entire set of default values\n" "to the initial values loaded after first launch." @@ -6379,15 +6711,19 @@ msgstr "" "Restaurer l'ensemble complet des valeurs par défaut\n" "aux valeurs initiales chargées après le premier lancement." -#: flatcamGUI/FlatCAMGUI.py:1223 +#: flatcamGUI/FlatCAMGUI.py:1295 msgid "Open Pref Folder" msgstr "Ouvrir le dossier Pref" -#: flatcamGUI/FlatCAMGUI.py:1226 +#: flatcamGUI/FlatCAMGUI.py:1298 msgid "Open the folder where FlatCAM save the preferences files." msgstr "Ouvrez le dossier où FlatCAM enregistre les fichiers de préférences." -#: flatcamGUI/FlatCAMGUI.py:1234 +#: flatcamGUI/FlatCAMGUI.py:1302 flatcamGUI/FlatCAMGUI.py:2477 +msgid "Clear GUI Settings" +msgstr "Effacer les param. de GUI" + +#: flatcamGUI/FlatCAMGUI.py:1306 msgid "" "Clear the GUI settings for FlatCAM,\n" "such as: layout, gui state, style, hdpi support etc." @@ -6395,15 +6731,15 @@ msgstr "" "Effacer les paramètres de l'interface graphique pour FlatCAM,\n" "tels que: mise en page, état graphique, style, support hdpi, etc." -#: flatcamGUI/FlatCAMGUI.py:1245 +#: flatcamGUI/FlatCAMGUI.py:1317 msgid "Apply" msgstr "Appliquer" -#: flatcamGUI/FlatCAMGUI.py:1248 +#: flatcamGUI/FlatCAMGUI.py:1320 msgid "Apply the current preferences without saving to a file." msgstr "Appliquez les préférences actuelles sans enregistrer dans un fichier." -#: flatcamGUI/FlatCAMGUI.py:1255 +#: flatcamGUI/FlatCAMGUI.py:1327 msgid "" "Save the current settings in the 'current_defaults' file\n" "which is the file storing the working default preferences." @@ -6411,532 +6747,545 @@ msgstr "" "Enregistrer les paramètres actuels dans le fichier 'current_defaults'\n" "qui est le fichier stockant les préférences de travail par défaut." -#: flatcamGUI/FlatCAMGUI.py:1263 +#: flatcamGUI/FlatCAMGUI.py:1335 msgid "Will not save the changes and will close the preferences window." msgstr "" "N'enregistrera pas les modifications et fermera la fenêtre des préférences." -#: flatcamGUI/FlatCAMGUI.py:1603 +#: flatcamGUI/FlatCAMGUI.py:1704 msgid "SHOW SHORTCUT LIST" msgstr "MONTRER LISTE DES RACCOURCIS" -#: flatcamGUI/FlatCAMGUI.py:1603 +#: flatcamGUI/FlatCAMGUI.py:1704 msgid "Switch to Project Tab" msgstr "Passer à l'onglet Projet" -#: flatcamGUI/FlatCAMGUI.py:1603 +#: flatcamGUI/FlatCAMGUI.py:1704 msgid "Switch to Selected Tab" msgstr "Passer à l'onglet Sélectionné" -#: flatcamGUI/FlatCAMGUI.py:1604 +#: flatcamGUI/FlatCAMGUI.py:1705 msgid "Switch to Tool Tab" msgstr "Basculer vers l'onglet Outil" -#: flatcamGUI/FlatCAMGUI.py:1605 +#: flatcamGUI/FlatCAMGUI.py:1706 msgid "New Gerber" msgstr "Nouveau Gerber" -#: flatcamGUI/FlatCAMGUI.py:1605 +#: flatcamGUI/FlatCAMGUI.py:1706 msgid "Edit Object (if selected)" msgstr "Editer objet (si sélectionné)" -#: flatcamGUI/FlatCAMGUI.py:1605 +#: flatcamGUI/FlatCAMGUI.py:1706 msgid "Jump to Coordinates" msgstr "Aller aux coordonnées" -#: flatcamGUI/FlatCAMGUI.py:1606 +#: flatcamGUI/FlatCAMGUI.py:1707 msgid "New Excellon" msgstr "Nouvelle Excellon" -#: flatcamGUI/FlatCAMGUI.py:1606 +#: flatcamGUI/FlatCAMGUI.py:1707 msgid "Move Obj" msgstr "Déplacer Obj" -#: flatcamGUI/FlatCAMGUI.py:1606 +#: flatcamGUI/FlatCAMGUI.py:1707 msgid "New Geometry" msgstr "Nouvelle Géométrie" -#: flatcamGUI/FlatCAMGUI.py:1606 +#: flatcamGUI/FlatCAMGUI.py:1707 msgid "Change Units" msgstr "Changer d'unités" -#: flatcamGUI/FlatCAMGUI.py:1607 +#: flatcamGUI/FlatCAMGUI.py:1708 msgid "Open Properties Tool" msgstr "Ouvrir les Propriétés" -#: flatcamGUI/FlatCAMGUI.py:1607 +#: flatcamGUI/FlatCAMGUI.py:1708 msgid "Rotate by 90 degree CW" msgstr "Rotation de 90 degrés CW" -#: flatcamGUI/FlatCAMGUI.py:1607 +#: flatcamGUI/FlatCAMGUI.py:1708 msgid "Shell Toggle" msgstr "Shell bascule" -#: flatcamGUI/FlatCAMGUI.py:1608 +#: flatcamGUI/FlatCAMGUI.py:1709 msgid "" "Add a Tool (when in Geometry Selected Tab or in Tools NCC or Tools Paint)" msgstr "" "Ajouter un outil (dans l'onglet Géométrie sélectionnée ou dans Outils NCC ou " "Outils de Peinture)" -#: flatcamGUI/FlatCAMGUI.py:1609 +#: flatcamGUI/FlatCAMGUI.py:1710 msgid "Flip on X_axis" msgstr "Miroir sur l'axe des X" -#: flatcamGUI/FlatCAMGUI.py:1609 +#: flatcamGUI/FlatCAMGUI.py:1710 msgid "Flip on Y_axis" msgstr "Miroir sur l'axe des Y" -#: flatcamGUI/FlatCAMGUI.py:1612 +#: flatcamGUI/FlatCAMGUI.py:1713 msgid "Copy Obj" msgstr "Copier Obj" -#: flatcamGUI/FlatCAMGUI.py:1612 +#: flatcamGUI/FlatCAMGUI.py:1713 msgid "Open Tools Database" msgstr "Ouvrir la BD des outils" -#: flatcamGUI/FlatCAMGUI.py:1613 +#: flatcamGUI/FlatCAMGUI.py:1714 msgid "Open Excellon File" msgstr "Ouvrir le fichier Excellon" -#: flatcamGUI/FlatCAMGUI.py:1613 +#: flatcamGUI/FlatCAMGUI.py:1714 msgid "Open Gerber File" msgstr "Ouvrir le fichier Gerber" -#: flatcamGUI/FlatCAMGUI.py:1613 +#: flatcamGUI/FlatCAMGUI.py:1714 msgid "New Project" msgstr "Nouveau Projet" -#: flatcamGUI/FlatCAMGUI.py:1614 flatcamTools/ToolPDF.py:42 +#: flatcamGUI/FlatCAMGUI.py:1715 flatcamTools/ToolPDF.py:42 msgid "PDF Import Tool" msgstr "Outil d'importation PDF" -#: flatcamGUI/FlatCAMGUI.py:1614 -msgid "Save Project As" -msgstr "Enregistrer le projet sous" +#: flatcamGUI/FlatCAMGUI.py:1715 +msgid "Save Project" +msgstr "Sauvegarder le projet" -#: flatcamGUI/FlatCAMGUI.py:1614 +#: flatcamGUI/FlatCAMGUI.py:1715 msgid "Toggle Plot Area" msgstr "Basculer la Zone de Tracé" -#: flatcamGUI/FlatCAMGUI.py:1617 +#: flatcamGUI/FlatCAMGUI.py:1718 msgid "Copy Obj_Name" msgstr "Copier Nom Obj" -#: flatcamGUI/FlatCAMGUI.py:1618 +#: flatcamGUI/FlatCAMGUI.py:1719 msgid "Toggle Code Editor" msgstr "Basculer l'éditeur de Code" -#: flatcamGUI/FlatCAMGUI.py:1618 +#: flatcamGUI/FlatCAMGUI.py:1719 msgid "Toggle the axis" msgstr "Basculer l'axe" -#: flatcamGUI/FlatCAMGUI.py:1618 flatcamGUI/FlatCAMGUI.py:1810 -#: flatcamGUI/FlatCAMGUI.py:1897 flatcamGUI/FlatCAMGUI.py:2019 +#: flatcamGUI/FlatCAMGUI.py:1719 flatcamGUI/FlatCAMGUI.py:1918 +#: flatcamGUI/FlatCAMGUI.py:2005 flatcamGUI/FlatCAMGUI.py:2127 msgid "Distance Minimum Tool" msgstr "Outil de Distance Minimum" -#: flatcamGUI/FlatCAMGUI.py:1618 +#: flatcamGUI/FlatCAMGUI.py:1720 msgid "Open Preferences Window" msgstr "Ouvrir la fenêtre de Préférences" -#: flatcamGUI/FlatCAMGUI.py:1619 +#: flatcamGUI/FlatCAMGUI.py:1721 msgid "Rotate by 90 degree CCW" msgstr "Faire pivoter de 90 degrés dans le sens anti-horaire" -#: flatcamGUI/FlatCAMGUI.py:1619 +#: flatcamGUI/FlatCAMGUI.py:1721 msgid "Run a Script" msgstr "Exécuter un script" -#: flatcamGUI/FlatCAMGUI.py:1619 +#: flatcamGUI/FlatCAMGUI.py:1721 msgid "Toggle the workspace" msgstr "Basculer l'espace de travail" -#: flatcamGUI/FlatCAMGUI.py:1619 +#: flatcamGUI/FlatCAMGUI.py:1721 msgid "Skew on X axis" msgstr "Fausser sur l'axe X" -#: flatcamGUI/FlatCAMGUI.py:1620 +#: flatcamGUI/FlatCAMGUI.py:1722 msgid "Skew on Y axis" msgstr "Fausser sur l'axe Y" -#: flatcamGUI/FlatCAMGUI.py:1622 +#: flatcamGUI/FlatCAMGUI.py:1725 msgid "2-Sided PCB Tool" msgstr "Outil de PCB double face" -#: flatcamGUI/FlatCAMGUI.py:1622 +#: flatcamGUI/FlatCAMGUI.py:1725 msgid "Transformations Tool" msgstr "Outil de Transformation" -#: flatcamGUI/FlatCAMGUI.py:1623 +#: flatcamGUI/FlatCAMGUI.py:1727 msgid "Solder Paste Dispensing Tool" msgstr "Outil d'application de Pâte à souder" -#: flatcamGUI/FlatCAMGUI.py:1624 +#: flatcamGUI/FlatCAMGUI.py:1728 msgid "Film PCB Tool" msgstr "Outil de PCB film" -#: flatcamGUI/FlatCAMGUI.py:1624 +#: flatcamGUI/FlatCAMGUI.py:1728 msgid "Non-Copper Clearing Tool" msgstr "Outil de Nettoyage sans Cuivre" -#: flatcamGUI/FlatCAMGUI.py:1625 +#: flatcamGUI/FlatCAMGUI.py:1729 msgid "Paint Area Tool" msgstr "Outil de Zone de Peinture" -#: flatcamGUI/FlatCAMGUI.py:1625 +#: flatcamGUI/FlatCAMGUI.py:1729 msgid "Rules Check Tool" msgstr "Outil de Vérification des Règles" -#: flatcamGUI/FlatCAMGUI.py:1626 +#: flatcamGUI/FlatCAMGUI.py:1730 msgid "View File Source" msgstr "Voir le fichier Source" -#: flatcamGUI/FlatCAMGUI.py:1627 +#: flatcamGUI/FlatCAMGUI.py:1731 msgid "Cutout PCB Tool" msgstr "Outil de Découpe PCB" -#: flatcamGUI/FlatCAMGUI.py:1627 +#: flatcamGUI/FlatCAMGUI.py:1731 msgid "Enable all Plots" msgstr "Activer tous les Dessins" -#: flatcamGUI/FlatCAMGUI.py:1627 +#: flatcamGUI/FlatCAMGUI.py:1731 msgid "Disable all Plots" msgstr "Désactiver tous les Dessins" -#: flatcamGUI/FlatCAMGUI.py:1627 +#: flatcamGUI/FlatCAMGUI.py:1731 msgid "Disable Non-selected Plots" msgstr "Désactiver les Dessins non sélectionnés" -#: flatcamGUI/FlatCAMGUI.py:1628 +#: flatcamGUI/FlatCAMGUI.py:1732 msgid "Toggle Full Screen" msgstr "Passer en plein écran" -#: flatcamGUI/FlatCAMGUI.py:1631 +#: flatcamGUI/FlatCAMGUI.py:1735 msgid "Abort current task (gracefully)" msgstr "Abandonner la tâche en cours (avec élégance)" -#: flatcamGUI/FlatCAMGUI.py:1634 +#: flatcamGUI/FlatCAMGUI.py:1738 +msgid "Save Project As" +msgstr "Enregistrer le projet sous" + +#: flatcamGUI/FlatCAMGUI.py:1739 +msgid "" +"Paste Special. Will convert a Windows path style to the one required in Tcl " +"Shell" +msgstr "" +"Collage spécial. Convertira un style de chemin d'accès Windows en celui " +"requis dans Tcl Shell" + +#: flatcamGUI/FlatCAMGUI.py:1742 msgid "Open Online Manual" msgstr "Ouvrir le manuel en ligne" -#: flatcamGUI/FlatCAMGUI.py:1635 +#: flatcamGUI/FlatCAMGUI.py:1743 msgid "Open Online Tutorials" msgstr "Ouvrir des tutoriels en ligne" -#: flatcamGUI/FlatCAMGUI.py:1635 +#: flatcamGUI/FlatCAMGUI.py:1743 msgid "Refresh Plots" msgstr "Actualiser les Dessins" -#: flatcamGUI/FlatCAMGUI.py:1635 flatcamTools/ToolSolderPaste.py:503 +#: flatcamGUI/FlatCAMGUI.py:1743 flatcamTools/ToolSolderPaste.py:509 msgid "Delete Object" msgstr "Supprimer un objet" -#: flatcamGUI/FlatCAMGUI.py:1635 +#: flatcamGUI/FlatCAMGUI.py:1743 msgid "Alternate: Delete Tool" msgstr "Autre: Suppression de Outil" -#: flatcamGUI/FlatCAMGUI.py:1636 +#: flatcamGUI/FlatCAMGUI.py:1744 msgid "(left to Key_1)Toogle Notebook Area (Left Side)" msgstr "(à gauche de Key_1) Basculer la zone du bloc-notes (côté gauche)" -#: flatcamGUI/FlatCAMGUI.py:1636 +#: flatcamGUI/FlatCAMGUI.py:1744 msgid "En(Dis)able Obj Plot" msgstr "(Dés)activer Obj Dessin" -#: flatcamGUI/FlatCAMGUI.py:1637 +#: flatcamGUI/FlatCAMGUI.py:1745 msgid "Deselects all objects" msgstr "Désélectionne tous les objets" -#: flatcamGUI/FlatCAMGUI.py:1651 +#: flatcamGUI/FlatCAMGUI.py:1759 msgid "Editor Shortcut list" msgstr "Liste des raccourcis de l'éditeur" -#: flatcamGUI/FlatCAMGUI.py:1805 +#: flatcamGUI/FlatCAMGUI.py:1913 msgid "GEOMETRY EDITOR" msgstr "EDITEUR DE GEOMETRIE" -#: flatcamGUI/FlatCAMGUI.py:1805 +#: flatcamGUI/FlatCAMGUI.py:1913 msgid "Draw an Arc" msgstr "Dessiner un arc" -#: flatcamGUI/FlatCAMGUI.py:1805 +#: flatcamGUI/FlatCAMGUI.py:1913 msgid "Copy Geo Item" msgstr "Copier un élém. de Géo" -#: flatcamGUI/FlatCAMGUI.py:1806 +#: flatcamGUI/FlatCAMGUI.py:1914 msgid "Within Add Arc will toogle the ARC direction: CW or CCW" msgstr "Dans Ajouter un arc va toogle la direction de l'ARC: CW ou CCW" -#: flatcamGUI/FlatCAMGUI.py:1806 +#: flatcamGUI/FlatCAMGUI.py:1914 msgid "Polygon Intersection Tool" msgstr "Outil d'intersection de polygones" -#: flatcamGUI/FlatCAMGUI.py:1807 +#: flatcamGUI/FlatCAMGUI.py:1915 msgid "Geo Paint Tool" msgstr "Outil de peinture géo" -#: flatcamGUI/FlatCAMGUI.py:1807 flatcamGUI/FlatCAMGUI.py:1896 -#: flatcamGUI/FlatCAMGUI.py:2016 +#: flatcamGUI/FlatCAMGUI.py:1915 flatcamGUI/FlatCAMGUI.py:2004 +#: flatcamGUI/FlatCAMGUI.py:2124 msgid "Jump to Location (x, y)" msgstr "Aller à l'emplacement (x, y)" -#: flatcamGUI/FlatCAMGUI.py:1807 +#: flatcamGUI/FlatCAMGUI.py:1915 msgid "Toggle Corner Snap" msgstr "Basculement d'angle" -#: flatcamGUI/FlatCAMGUI.py:1807 +#: flatcamGUI/FlatCAMGUI.py:1915 msgid "Move Geo Item" msgstr "Déplacer un élément de géométrie" -#: flatcamGUI/FlatCAMGUI.py:1808 +#: flatcamGUI/FlatCAMGUI.py:1916 msgid "Within Add Arc will cycle through the ARC modes" msgstr "Dans Ajouter Arc passera en revue les modes ARC" -#: flatcamGUI/FlatCAMGUI.py:1808 +#: flatcamGUI/FlatCAMGUI.py:1916 msgid "Draw a Polygon" msgstr "Dessine un polygone" -#: flatcamGUI/FlatCAMGUI.py:1808 +#: flatcamGUI/FlatCAMGUI.py:1916 msgid "Draw a Circle" msgstr "Dessiner un cercle" -#: flatcamGUI/FlatCAMGUI.py:1809 +#: flatcamGUI/FlatCAMGUI.py:1917 msgid "Draw a Path" msgstr "Dessiner un chemin" -#: flatcamGUI/FlatCAMGUI.py:1809 +#: flatcamGUI/FlatCAMGUI.py:1917 msgid "Draw Rectangle" msgstr "Dessiner un rectangle" -#: flatcamGUI/FlatCAMGUI.py:1809 +#: flatcamGUI/FlatCAMGUI.py:1917 msgid "Polygon Subtraction Tool" msgstr "Outil de soustraction de polygone" -#: flatcamGUI/FlatCAMGUI.py:1809 +#: flatcamGUI/FlatCAMGUI.py:1917 msgid "Add Text Tool" msgstr "Ajouter un outil de texte" -#: flatcamGUI/FlatCAMGUI.py:1810 +#: flatcamGUI/FlatCAMGUI.py:1918 msgid "Polygon Union Tool" msgstr "Outil union de polygones" -#: flatcamGUI/FlatCAMGUI.py:1810 +#: flatcamGUI/FlatCAMGUI.py:1918 msgid "Flip shape on X axis" msgstr "Refléter la forme sur l'axe X" -#: flatcamGUI/FlatCAMGUI.py:1810 +#: flatcamGUI/FlatCAMGUI.py:1918 msgid "Flip shape on Y axis" msgstr "Refléter la forme sur l'axe Y" -#: flatcamGUI/FlatCAMGUI.py:1811 +#: flatcamGUI/FlatCAMGUI.py:1919 msgid "Skew shape on X axis" msgstr "Fausser de la forme sur l'axe X" -#: flatcamGUI/FlatCAMGUI.py:1811 +#: flatcamGUI/FlatCAMGUI.py:1919 msgid "Skew shape on Y axis" msgstr "Fausser de la forme sur l'axe Y" -#: flatcamGUI/FlatCAMGUI.py:1811 +#: flatcamGUI/FlatCAMGUI.py:1919 msgid "Editor Transformation Tool" msgstr "Outil de transformation de l'éditeur" -#: flatcamGUI/FlatCAMGUI.py:1812 +#: flatcamGUI/FlatCAMGUI.py:1920 msgid "Offset shape on X axis" msgstr "Forme décalée sur l'axe X" -#: flatcamGUI/FlatCAMGUI.py:1812 +#: flatcamGUI/FlatCAMGUI.py:1920 msgid "Offset shape on Y axis" msgstr "Forme décalée sur l'axe Y" -#: flatcamGUI/FlatCAMGUI.py:1813 flatcamGUI/FlatCAMGUI.py:1899 -#: flatcamGUI/FlatCAMGUI.py:2021 +#: flatcamGUI/FlatCAMGUI.py:1921 flatcamGUI/FlatCAMGUI.py:2007 +#: flatcamGUI/FlatCAMGUI.py:2129 msgid "Save Object and Exit Editor" msgstr "Enregistrer l'objet et quitter l'éditeur" -#: flatcamGUI/FlatCAMGUI.py:1813 +#: flatcamGUI/FlatCAMGUI.py:1921 msgid "Polygon Cut Tool" msgstr "Outil de coupe de polygone" -#: flatcamGUI/FlatCAMGUI.py:1814 +#: flatcamGUI/FlatCAMGUI.py:1922 msgid "Rotate Geometry" msgstr "Faire pivoter la géométrie" -#: flatcamGUI/FlatCAMGUI.py:1814 +#: flatcamGUI/FlatCAMGUI.py:1922 msgid "Finish drawing for certain tools" msgstr "Terminer le dessin pour certains outils" -#: flatcamGUI/FlatCAMGUI.py:1814 flatcamGUI/FlatCAMGUI.py:1899 -#: flatcamGUI/FlatCAMGUI.py:2019 +#: flatcamGUI/FlatCAMGUI.py:1922 flatcamGUI/FlatCAMGUI.py:2007 +#: flatcamGUI/FlatCAMGUI.py:2127 msgid "Abort and return to Select" msgstr "Abort and return to Select" -#: flatcamGUI/FlatCAMGUI.py:1815 flatcamGUI/FlatCAMGUI.py:2518 +#: flatcamGUI/FlatCAMGUI.py:1923 flatcamGUI/FlatCAMGUI.py:2690 msgid "Delete Shape" msgstr "Supprimer la forme" -#: flatcamGUI/FlatCAMGUI.py:1895 +#: flatcamGUI/FlatCAMGUI.py:2003 msgid "EXCELLON EDITOR" msgstr "ÉDITEUR EXCELLON" -#: flatcamGUI/FlatCAMGUI.py:1895 +#: flatcamGUI/FlatCAMGUI.py:2003 msgid "Copy Drill(s)" msgstr "Copier les Forets" -#: flatcamGUI/FlatCAMGUI.py:1895 flatcamGUI/FlatCAMGUI.py:2145 +#: flatcamGUI/FlatCAMGUI.py:2003 flatcamGUI/FlatCAMGUI.py:2253 msgid "Add Drill" msgstr "Ajouter une Foret" -#: flatcamGUI/FlatCAMGUI.py:1896 +#: flatcamGUI/FlatCAMGUI.py:2004 msgid "Move Drill(s)" msgstr "Déplacer les Forets" -#: flatcamGUI/FlatCAMGUI.py:1897 +#: flatcamGUI/FlatCAMGUI.py:2005 msgid "Add a new Tool" msgstr "Ajouter un nouvel outil" -#: flatcamGUI/FlatCAMGUI.py:1898 +#: flatcamGUI/FlatCAMGUI.py:2006 msgid "Delete Drill(s)" msgstr "Supprimer les Forets" -#: flatcamGUI/FlatCAMGUI.py:1898 +#: flatcamGUI/FlatCAMGUI.py:2006 msgid "Alternate: Delete Tool(s)" msgstr "Autre: Supprimer outil(s)" -#: flatcamGUI/FlatCAMGUI.py:2015 +#: flatcamGUI/FlatCAMGUI.py:2123 msgid "GERBER EDITOR" msgstr "GERBER ÉDITEUR" -#: flatcamGUI/FlatCAMGUI.py:2015 +#: flatcamGUI/FlatCAMGUI.py:2123 msgid "Add Disc" msgstr "Ajouter un Disque" -#: flatcamGUI/FlatCAMGUI.py:2015 +#: flatcamGUI/FlatCAMGUI.py:2123 msgid "Add SemiDisc" msgstr "Ajouter un Semi-disque" -#: flatcamGUI/FlatCAMGUI.py:2017 +#: flatcamGUI/FlatCAMGUI.py:2125 msgid "Within Track & Region Tools will cycle in REVERSE the bend modes" msgstr "" "Dans les Outils de Piste et de Région, les modes de pliage sont inversés" -#: flatcamGUI/FlatCAMGUI.py:2018 +#: flatcamGUI/FlatCAMGUI.py:2126 msgid "Within Track & Region Tools will cycle FORWARD the bend modes" msgstr "" "Dans les Outils de Piste et de Région, les modes de pliage sont répétés en " "boucle" -#: flatcamGUI/FlatCAMGUI.py:2019 +#: flatcamGUI/FlatCAMGUI.py:2127 msgid "Alternate: Delete Apertures" msgstr "Autre: Supprimer les ouvertures" -#: flatcamGUI/FlatCAMGUI.py:2020 +#: flatcamGUI/FlatCAMGUI.py:2128 msgid "Eraser Tool" msgstr "Outil pour Effacer" -#: flatcamGUI/FlatCAMGUI.py:2021 flatcamGUI/PreferencesUI.py:2634 +#: flatcamGUI/FlatCAMGUI.py:2129 flatcamGUI/PreferencesUI.py:2816 msgid "Mark Area Tool" msgstr "Outil Zone de Marquage" -#: flatcamGUI/FlatCAMGUI.py:2021 +#: flatcamGUI/FlatCAMGUI.py:2129 msgid "Poligonize Tool" msgstr "Outil Polygoniser" -#: flatcamGUI/FlatCAMGUI.py:2021 +#: flatcamGUI/FlatCAMGUI.py:2129 msgid "Transformation Tool" msgstr "Outil de Transformation" -#: flatcamGUI/FlatCAMGUI.py:2038 +#: flatcamGUI/FlatCAMGUI.py:2146 msgid "Toggle Visibility" msgstr "Basculer la Visibilité" -#: flatcamGUI/FlatCAMGUI.py:2044 +#: flatcamGUI/FlatCAMGUI.py:2152 msgid "New" msgstr "Nouveau" -#: flatcamGUI/FlatCAMGUI.py:2046 flatcamTools/ToolCalibration.py:634 -msgid "Geometry" -msgstr "Géométrie" - -#: flatcamGUI/FlatCAMGUI.py:2050 flatcamTools/ToolCalibration.py:197 -#: flatcamTools/ToolCalibration.py:634 flatcamTools/ToolFilm.py:359 +#: flatcamGUI/FlatCAMGUI.py:2158 flatcamGUI/PreferencesUI.py:8410 +#: flatcamTools/ToolAlignObjects.py:74 flatcamTools/ToolAlignObjects.py:110 +#: flatcamTools/ToolCalibration.py:197 flatcamTools/ToolCalibration.py:631 +#: flatcamTools/ToolCalibration.py:648 flatcamTools/ToolCalibration.py:807 +#: flatcamTools/ToolCalibration.py:815 flatcamTools/ToolCopperThieving.py:145 +#: flatcamTools/ToolCopperThieving.py:159 +#: flatcamTools/ToolCopperThieving.py:605 flatcamTools/ToolDblSided.py:226 +#: flatcamTools/ToolFilm.py:359 flatcamTools/ToolNCC.py:558 +#: flatcamTools/ToolNCC.py:1295 flatcamTools/ToolPaint.py:502 +#: flatcamTools/ToolPaint.py:706 flatcamTools/ToolPanelize.py:374 +#: flatcamTools/ToolPunchGerber.py:149 flatcamTools/ToolPunchGerber.py:164 msgid "Excellon" msgstr "Excellon" -#: flatcamGUI/FlatCAMGUI.py:2057 +#: flatcamGUI/FlatCAMGUI.py:2165 msgid "Grids" msgstr "Des grilles" -#: flatcamGUI/FlatCAMGUI.py:2064 +#: flatcamGUI/FlatCAMGUI.py:2172 msgid "Clear Plot" msgstr "Effacer le Dessin" -#: flatcamGUI/FlatCAMGUI.py:2066 +#: flatcamGUI/FlatCAMGUI.py:2174 msgid "Replot" msgstr "Re-Tracé" -#: flatcamGUI/FlatCAMGUI.py:2070 +#: flatcamGUI/FlatCAMGUI.py:2178 msgid "Geo Editor" msgstr "Éditeur de Géo" -#: flatcamGUI/FlatCAMGUI.py:2072 +#: flatcamGUI/FlatCAMGUI.py:2180 msgid "Path" msgstr "Chemin" -#: flatcamGUI/FlatCAMGUI.py:2074 +#: flatcamGUI/FlatCAMGUI.py:2182 msgid "Rectangle" msgstr "Rectangle" -#: flatcamGUI/FlatCAMGUI.py:2077 +#: flatcamGUI/FlatCAMGUI.py:2185 msgid "Circle" msgstr "Cercle" -#: flatcamGUI/FlatCAMGUI.py:2079 -msgid "Polygon" -msgstr "Polygone" - -#: flatcamGUI/FlatCAMGUI.py:2081 +#: flatcamGUI/FlatCAMGUI.py:2189 msgid "Arc" msgstr "Arc" -#: flatcamGUI/FlatCAMGUI.py:2095 +#: flatcamGUI/FlatCAMGUI.py:2203 msgid "Union" msgstr "Union" -#: flatcamGUI/FlatCAMGUI.py:2097 +#: flatcamGUI/FlatCAMGUI.py:2205 msgid "Intersection" msgstr "Intersection" -#: flatcamGUI/FlatCAMGUI.py:2099 +#: flatcamGUI/FlatCAMGUI.py:2207 msgid "Subtraction" msgstr "Soustraction" -#: flatcamGUI/FlatCAMGUI.py:2101 flatcamGUI/ObjectUI.py:1811 -#: flatcamGUI/PreferencesUI.py:4421 +#: flatcamGUI/FlatCAMGUI.py:2209 flatcamGUI/ObjectUI.py:2139 +#: flatcamGUI/PreferencesUI.py:4714 msgid "Cut" msgstr "Couper" -#: flatcamGUI/FlatCAMGUI.py:2112 +#: flatcamGUI/FlatCAMGUI.py:2220 msgid "Pad" msgstr "Pad" -#: flatcamGUI/FlatCAMGUI.py:2114 +#: flatcamGUI/FlatCAMGUI.py:2222 msgid "Pad Array" msgstr "Tableau Pad" -#: flatcamGUI/FlatCAMGUI.py:2118 +#: flatcamGUI/FlatCAMGUI.py:2226 msgid "Track" msgstr "Piste" -#: flatcamGUI/FlatCAMGUI.py:2120 +#: flatcamGUI/FlatCAMGUI.py:2228 msgid "Region" msgstr "Région" -#: flatcamGUI/FlatCAMGUI.py:2143 +#: flatcamGUI/FlatCAMGUI.py:2251 msgid "Exc Editor" msgstr "Éditeur Excellon" -#: flatcamGUI/FlatCAMGUI.py:2188 +#: flatcamGUI/FlatCAMGUI.py:2296 msgid "" "Relative neasurement.\n" "Reference is last click position" @@ -6944,7 +7293,7 @@ msgstr "" "Mesure relative\n" "La référence est la position du dernier clic" -#: flatcamGUI/FlatCAMGUI.py:2194 +#: flatcamGUI/FlatCAMGUI.py:2302 msgid "" "Absolute neasurement.\n" "Reference is (X=0, Y= 0) position" @@ -6952,27 +7301,35 @@ msgstr "" "Mesure absolue.\n" "La référence est (X = 0, Y = 0) position" -#: flatcamGUI/FlatCAMGUI.py:2301 +#: flatcamGUI/FlatCAMGUI.py:2406 msgid "Lock Toolbars" msgstr "Verrouiller les barres d'outils" -#: flatcamGUI/FlatCAMGUI.py:2419 +#: flatcamGUI/FlatCAMGUI.py:2465 +msgid "FlatCAM Preferences Folder opened." +msgstr "Dossier Préférences FlatCAM ouvert." + +#: flatcamGUI/FlatCAMGUI.py:2476 +msgid "Are you sure you want to delete the GUI Settings? \n" +msgstr "Êtes-vous sûr de vouloir supprimer les paramètres de GUI?\n" + +#: flatcamGUI/FlatCAMGUI.py:2584 msgid "&Cutout Tool" msgstr "Outil de Découpe" -#: flatcamGUI/FlatCAMGUI.py:2478 +#: flatcamGUI/FlatCAMGUI.py:2650 msgid "Select 'Esc'" msgstr "Sélectionnez 'Esc'" -#: flatcamGUI/FlatCAMGUI.py:2516 +#: flatcamGUI/FlatCAMGUI.py:2688 msgid "Copy Objects" msgstr "Copier des objets" -#: flatcamGUI/FlatCAMGUI.py:2524 +#: flatcamGUI/FlatCAMGUI.py:2696 msgid "Move Objects" msgstr "Déplacer des objets" -#: flatcamGUI/FlatCAMGUI.py:3087 +#: flatcamGUI/FlatCAMGUI.py:3312 msgid "" "Please first select a geometry item to be cutted\n" "then select the geometry item that will be cutted\n" @@ -6984,12 +7341,12 @@ msgstr "" "sur le premier article. Appuyez à la fin de la touche ~ X ~ ou\n" "le bouton de la barre d'outils." -#: flatcamGUI/FlatCAMGUI.py:3094 flatcamGUI/FlatCAMGUI.py:3254 -#: flatcamGUI/FlatCAMGUI.py:3299 flatcamGUI/FlatCAMGUI.py:3319 +#: flatcamGUI/FlatCAMGUI.py:3319 flatcamGUI/FlatCAMGUI.py:3478 +#: flatcamGUI/FlatCAMGUI.py:3523 flatcamGUI/FlatCAMGUI.py:3543 msgid "Warning" msgstr "Attention" -#: flatcamGUI/FlatCAMGUI.py:3249 +#: flatcamGUI/FlatCAMGUI.py:3473 msgid "" "Please select geometry items \n" "on which to perform Intersection Tool." @@ -6997,7 +7354,7 @@ msgstr "" "Veuillez sélectionner des éléments de géométrie\n" "sur lequel exécuter l'outil Intersection." -#: flatcamGUI/FlatCAMGUI.py:3294 +#: flatcamGUI/FlatCAMGUI.py:3518 msgid "" "Please select geometry items \n" "on which to perform Substraction Tool." @@ -7005,7 +7362,7 @@ msgstr "" "Veuillez sélectionner des éléments de géométrie\n" "sur lequel effectuer l'outil de Soustraction." -#: flatcamGUI/FlatCAMGUI.py:3314 +#: flatcamGUI/FlatCAMGUI.py:3538 msgid "" "Please select geometry items \n" "on which to perform union." @@ -7013,61 +7370,62 @@ msgstr "" "Veuillez sélectionner des éléments de géométrie\n" "sur lequel effectuer l'union." -#: flatcamGUI/FlatCAMGUI.py:3394 flatcamGUI/FlatCAMGUI.py:3608 +#: flatcamGUI/FlatCAMGUI.py:3617 flatcamGUI/FlatCAMGUI.py:3828 msgid "Cancelled. Nothing selected to delete." msgstr "Annulé. Rien de sélectionné à supprimer." -#: flatcamGUI/FlatCAMGUI.py:3479 flatcamGUI/FlatCAMGUI.py:3726 +#: flatcamGUI/FlatCAMGUI.py:3701 flatcamGUI/FlatCAMGUI.py:3944 msgid "Cancelled. Nothing selected to copy." msgstr "Annulé. Rien n'est sélectionné pour copier." -#: flatcamGUI/FlatCAMGUI.py:3526 flatcamGUI/FlatCAMGUI.py:3756 +#: flatcamGUI/FlatCAMGUI.py:3747 flatcamGUI/FlatCAMGUI.py:3973 msgid "Cancelled. Nothing selected to move." msgstr "Annulé. Rien de sélectionné pour bouger." -#: flatcamGUI/FlatCAMGUI.py:3782 +#: flatcamGUI/FlatCAMGUI.py:3999 msgid "New Tool ..." msgstr "Nouvel outil ..." -#: flatcamGUI/FlatCAMGUI.py:3783 flatcamTools/ToolNonCopperClear.py:583 -#: flatcamTools/ToolPaint.py:494 flatcamTools/ToolSolderPaste.py:554 +#: flatcamGUI/FlatCAMGUI.py:4000 flatcamTools/ToolNCC.py:924 +#: flatcamTools/ToolPaint.py:850 flatcamTools/ToolSolderPaste.py:560 msgid "Enter a Tool Diameter" msgstr "Entrer un diamètre d'outil" -#: flatcamGUI/FlatCAMGUI.py:3795 +#: flatcamGUI/FlatCAMGUI.py:4012 msgid "Adding Tool cancelled ..." msgstr "Ajout de l'outil annulé ..." -#: flatcamGUI/FlatCAMGUI.py:3808 +#: flatcamGUI/FlatCAMGUI.py:4025 msgid "Distance Tool exit..." msgstr "Distance Outil sortie ..." -#: flatcamGUI/FlatCAMGUI.py:4018 flatcamGUI/FlatCAMGUI.py:4025 +#: flatcamGUI/FlatCAMGUI.py:4234 flatcamGUI/FlatCAMGUI.py:4241 msgid "Idle." msgstr "Au repos." -#: flatcamGUI/FlatCAMGUI.py:4056 +#: flatcamGUI/FlatCAMGUI.py:4272 msgid "Application started ..." msgstr "L'application a commencé ..." -#: flatcamGUI/FlatCAMGUI.py:4057 +#: flatcamGUI/FlatCAMGUI.py:4273 msgid "Hello!" msgstr "Salut!" -#: flatcamGUI/FlatCAMGUI.py:4115 +#: flatcamGUI/FlatCAMGUI.py:4331 msgid "Open Project ..." msgstr "Projet ouvert ..." -#: flatcamGUI/FlatCAMGUI.py:4141 +#: flatcamGUI/FlatCAMGUI.py:4357 msgid "Exit" msgstr "Sortie" -#: flatcamGUI/GUIElements.py:2261 flatcamGUI/PreferencesUI.py:5265 -#: flatcamGUI/PreferencesUI.py:5825 flatcamTools/ToolFilm.py:219 +#: flatcamGUI/GUIElements.py:2513 flatcamGUI/PreferencesUI.py:6313 +#: flatcamTools/ToolDblSided.py:174 flatcamTools/ToolDblSided.py:389 +#: flatcamTools/ToolFilm.py:219 msgid "Reference" msgstr "Référence" -#: flatcamGUI/GUIElements.py:2263 +#: flatcamGUI/GUIElements.py:2515 msgid "" "The reference can be:\n" "- Absolute -> the reference point is point (0,0)\n" @@ -7077,19 +7435,19 @@ msgstr "" "- Absolue -> le point de référence est le point (0,0)\n" "- Relatif -> le point de référence est la position de la souris avant le saut" -#: flatcamGUI/GUIElements.py:2268 +#: flatcamGUI/GUIElements.py:2520 msgid "Abs" msgstr "Abs" -#: flatcamGUI/GUIElements.py:2269 +#: flatcamGUI/GUIElements.py:2521 msgid "Relative" msgstr "Relatif" -#: flatcamGUI/GUIElements.py:2279 +#: flatcamGUI/GUIElements.py:2531 msgid "Location" msgstr "Emplacement" -#: flatcamGUI/GUIElements.py:2281 +#: flatcamGUI/GUIElements.py:2533 msgid "" "The Location value is a tuple (x,y).\n" "If the reference is Absolute then the Jump will be at the position (x,y).\n" @@ -7101,6 +7459,10 @@ msgstr "" "Si la référence est relative, le saut sera à la distance (x, y)\n" "à partir du point d'emplacement actuel de la souris." +#: flatcamGUI/GUIElements.py:2573 +msgid "Save Log" +msgstr "Enregistrer le journal" + #: flatcamGUI/ObjectUI.py:38 msgid "FlatCAM Object" msgstr "Objet FlatCAM" @@ -7123,15 +7485,11 @@ msgstr "" "Édition -> Préférences -> Général et vérifiez:\n" "Bouton radio 'APP. NIVEAU'." -#: flatcamGUI/ObjectUI.py:105 -msgid "Change the size of the object." -msgstr "Changer la taille de l'objet." +#: flatcamGUI/ObjectUI.py:110 +msgid "Geometrical transformations of the current object." +msgstr "Transformations géométriques de l'objet courant." -#: flatcamGUI/ObjectUI.py:111 -msgid "Factor" -msgstr "Facteur" - -#: flatcamGUI/ObjectUI.py:113 +#: flatcamGUI/ObjectUI.py:119 msgid "" "Factor by which to multiply\n" "geometric features of this object.\n" @@ -7141,19 +7499,11 @@ msgstr "" "caractéristiques géométriques de cet objet.\n" "Les expressions sont autorisées. Par exemple: 1 / 25.4" -#: flatcamGUI/ObjectUI.py:123 +#: flatcamGUI/ObjectUI.py:126 msgid "Perform scaling operation." msgstr "Effectuer l'opération de mise à l'échelle." -#: flatcamGUI/ObjectUI.py:134 -msgid "Change the position of this object." -msgstr "Changer la position de cet objet." - -#: flatcamGUI/ObjectUI.py:139 -msgid "Vector" -msgstr "Vecteur" - -#: flatcamGUI/ObjectUI.py:141 +#: flatcamGUI/ObjectUI.py:137 msgid "" "Amount by which to move the object\n" "in the x and y axes in (x, y) format.\n" @@ -7163,60 +7513,53 @@ msgstr "" "dans les axes x et y au format (x, y).\n" "Les expressions sont autorisées. Par exemple: (1/3.2, 0.5*3)" -#: flatcamGUI/ObjectUI.py:150 +#: flatcamGUI/ObjectUI.py:144 msgid "Perform the offset operation." msgstr "Effectuer l'opération de décalage." -#: flatcamGUI/ObjectUI.py:167 +#: flatcamGUI/ObjectUI.py:177 msgid "Gerber Object" msgstr "Objet de Gerber" -#: flatcamGUI/ObjectUI.py:182 flatcamGUI/ObjectUI.py:767 -#: flatcamGUI/ObjectUI.py:1205 flatcamGUI/ObjectUI.py:1905 -#: flatcamGUI/PreferencesUI.py:1783 flatcamGUI/PreferencesUI.py:3849 -#: flatcamGUI/PreferencesUI.py:4406 -msgid "Plot (show) this object." -msgstr "Tracer (afficher) cet objet." - -#: flatcamGUI/ObjectUI.py:184 flatcamGUI/ObjectUI.py:765 -#: flatcamGUI/PreferencesUI.py:1781 flatcamGUI/PreferencesUI.py:2680 -#: flatcamGUI/PreferencesUI.py:3847 -msgid "Plot" -msgstr "Dessin" - -#: flatcamGUI/ObjectUI.py:189 flatcamGUI/ObjectUI.py:726 -#: flatcamGUI/ObjectUI.py:1159 flatcamGUI/ObjectUI.py:1795 -#: flatcamGUI/PreferencesUI.py:1760 flatcamGUI/PreferencesUI.py:2674 -#: flatcamGUI/PreferencesUI.py:3843 flatcamGUI/PreferencesUI.py:4395 +#: flatcamGUI/ObjectUI.py:186 flatcamGUI/ObjectUI.py:729 +#: flatcamGUI/ObjectUI.py:1424 flatcamGUI/ObjectUI.py:2123 +#: flatcamGUI/PreferencesUI.py:1940 flatcamGUI/PreferencesUI.py:2856 +#: flatcamGUI/PreferencesUI.py:4121 flatcamGUI/PreferencesUI.py:4688 msgid "Plot Options" msgstr "Options de Tracé" -#: flatcamGUI/ObjectUI.py:195 flatcamGUI/ObjectUI.py:727 -#: flatcamGUI/PreferencesUI.py:1767 flatcamGUI/PreferencesUI.py:2686 -#: flatcamGUI/PreferencesUI.py:7222 flatcamTools/ToolCopperThieving.py:190 +#: flatcamGUI/ObjectUI.py:192 flatcamGUI/ObjectUI.py:730 +#: flatcamGUI/PreferencesUI.py:1947 flatcamGUI/PreferencesUI.py:2868 +#: flatcamGUI/PreferencesUI.py:7728 flatcamTools/ToolCopperThieving.py:192 msgid "Solid" msgstr "Solide" -#: flatcamGUI/ObjectUI.py:197 flatcamGUI/PreferencesUI.py:1769 +#: flatcamGUI/ObjectUI.py:194 flatcamGUI/PreferencesUI.py:1949 msgid "Solid color polygons." msgstr "Polygones de couleur unie." -#: flatcamGUI/ObjectUI.py:203 +#: flatcamGUI/ObjectUI.py:200 msgid "Multi-Color" msgstr "Multicolore" -#: flatcamGUI/ObjectUI.py:205 flatcamGUI/PreferencesUI.py:1776 +#: flatcamGUI/ObjectUI.py:202 flatcamGUI/PreferencesUI.py:1956 msgid "Draw polygons in different colors." msgstr "Dessine des polygones de différentes couleurs." -#: flatcamGUI/ObjectUI.py:213 flatcamGUI/ObjectUI.py:738 -#: flatcamGUI/ObjectUI.py:1165 flatcamGUI/ObjectUI.py:1825 -#: flatcamGUI/ObjectUI.py:2128 flatcamGUI/ObjectUI.py:2194 -#: flatcamTools/ToolCalibration.py:235 flatcamTools/ToolFiducials.py:73 -msgid "Name" -msgstr "Nom" +#: flatcamGUI/ObjectUI.py:208 flatcamGUI/ObjectUI.py:768 +#: flatcamGUI/PreferencesUI.py:1961 flatcamGUI/PreferencesUI.py:2862 +#: flatcamGUI/PreferencesUI.py:4125 +msgid "Plot" +msgstr "Dessin" -#: flatcamGUI/ObjectUI.py:234 +#: flatcamGUI/ObjectUI.py:210 flatcamGUI/ObjectUI.py:770 +#: flatcamGUI/ObjectUI.py:1484 flatcamGUI/ObjectUI.py:2233 +#: flatcamGUI/PreferencesUI.py:1963 flatcamGUI/PreferencesUI.py:4127 +#: flatcamGUI/PreferencesUI.py:4699 +msgid "Plot (show) this object." +msgstr "Tracer (afficher) cet objet." + +#: flatcamGUI/ObjectUI.py:238 msgid "" "Toggle the display of the Gerber Apertures Table.\n" "When unchecked, it will delete all mark shapes\n" @@ -7227,11 +7570,11 @@ msgstr "" "supprimées\n" "qui sont dessinés sur une toile." -#: flatcamGUI/ObjectUI.py:244 +#: flatcamGUI/ObjectUI.py:248 msgid "Mark All" msgstr "Marquer tout" -#: flatcamGUI/ObjectUI.py:246 +#: flatcamGUI/ObjectUI.py:250 msgid "" "When checked it will display all the apertures.\n" "When unchecked, it will delete all mark shapes\n" @@ -7242,15 +7585,15 @@ msgstr "" "supprimées\n" "qui sont dessinés sur une toile." -#: flatcamGUI/ObjectUI.py:274 +#: flatcamGUI/ObjectUI.py:278 msgid "Mark the aperture instances on canvas." msgstr "Marquez les occurrences d’ouverture sur la toile." -#: flatcamGUI/ObjectUI.py:286 flatcamGUI/PreferencesUI.py:2014 +#: flatcamGUI/ObjectUI.py:290 flatcamGUI/PreferencesUI.py:2194 msgid "Isolation Routing" msgstr "Routage d'isolement" -#: flatcamGUI/ObjectUI.py:288 flatcamGUI/PreferencesUI.py:2016 +#: flatcamGUI/ObjectUI.py:292 flatcamGUI/PreferencesUI.py:2196 msgid "" "Create a Geometry object with\n" "toolpaths to cut outside polygons." @@ -7258,7 +7601,7 @@ msgstr "" "Créez un objet de géométrie avec\n" "parcours d’outils pour couper des polygones extérieurs." -#: flatcamGUI/ObjectUI.py:306 flatcamGUI/PreferencesUI.py:2219 +#: flatcamGUI/ObjectUI.py:310 flatcamGUI/PreferencesUI.py:2399 msgid "" "Choose what tool to use for Gerber isolation:\n" "'Circular' or 'V-shape'.\n" @@ -7270,31 +7613,37 @@ msgstr "" "Lorsque la \"forme en V\" est sélectionnée, l'outil\n" "Le diamètre dépendra de la profondeur de coupe choisie." -#: flatcamGUI/ObjectUI.py:312 +#: flatcamGUI/ObjectUI.py:316 msgid "V-Shape" msgstr "Forme en V" -#: flatcamGUI/ObjectUI.py:318 flatcamGUI/ObjectUI.py:1374 -#: flatcamGUI/PreferencesUI.py:2231 flatcamGUI/PreferencesUI.py:5055 -#: flatcamTools/ToolNonCopperClear.py:231 +#: flatcamGUI/ObjectUI.py:322 flatcamGUI/ObjectUI.py:1670 +#: flatcamGUI/PreferencesUI.py:2411 flatcamGUI/PreferencesUI.py:5351 +#: flatcamGUI/PreferencesUI.py:5917 flatcamGUI/PreferencesUI.py:5924 +#: flatcamTools/ToolNCC.py:233 flatcamTools/ToolNCC.py:240 +#: flatcamTools/ToolPaint.py:216 msgid "V-Tip Dia" msgstr "Dia V-Tip" -#: flatcamGUI/ObjectUI.py:320 flatcamGUI/ObjectUI.py:1377 -#: flatcamGUI/PreferencesUI.py:2233 flatcamGUI/PreferencesUI.py:5057 -#: flatcamTools/ToolNonCopperClear.py:233 +#: flatcamGUI/ObjectUI.py:324 flatcamGUI/ObjectUI.py:1673 +#: flatcamGUI/PreferencesUI.py:2413 flatcamGUI/PreferencesUI.py:5353 +#: flatcamGUI/PreferencesUI.py:5919 flatcamTools/ToolNCC.py:235 +#: flatcamTools/ToolPaint.py:218 msgid "The tip diameter for V-Shape Tool" msgstr "Le diamètre de la pointe pour l'outil en forme de V" -#: flatcamGUI/ObjectUI.py:331 flatcamGUI/ObjectUI.py:1389 -#: flatcamGUI/PreferencesUI.py:2244 flatcamGUI/PreferencesUI.py:5067 -#: flatcamTools/ToolNonCopperClear.py:242 +#: flatcamGUI/ObjectUI.py:335 flatcamGUI/ObjectUI.py:1685 +#: flatcamGUI/PreferencesUI.py:2424 flatcamGUI/PreferencesUI.py:5363 +#: flatcamGUI/PreferencesUI.py:5930 flatcamGUI/PreferencesUI.py:5938 +#: flatcamTools/ToolNCC.py:246 flatcamTools/ToolNCC.py:254 +#: flatcamTools/ToolPaint.py:229 msgid "V-Tip Angle" msgstr "Angle en V-tip" -#: flatcamGUI/ObjectUI.py:333 flatcamGUI/ObjectUI.py:1392 -#: flatcamGUI/PreferencesUI.py:2246 flatcamGUI/PreferencesUI.py:5069 -#: flatcamTools/ToolNonCopperClear.py:244 +#: flatcamGUI/ObjectUI.py:337 flatcamGUI/ObjectUI.py:1688 +#: flatcamGUI/PreferencesUI.py:2426 flatcamGUI/PreferencesUI.py:5365 +#: flatcamGUI/PreferencesUI.py:5932 flatcamTools/ToolNCC.py:248 +#: flatcamTools/ToolPaint.py:231 msgid "" "The tip angle for V-Shape Tool.\n" "In degree." @@ -7302,9 +7651,9 @@ msgstr "" "L'angle de pointe pour l'outil en forme de V\n" "En degré." -#: flatcamGUI/ObjectUI.py:347 flatcamGUI/ObjectUI.py:1408 -#: flatcamGUI/PreferencesUI.py:2259 flatcamGUI/PreferencesUI.py:3963 -#: flatcamGUI/PreferencesUI.py:5330 flatcamTools/ToolCutOut.py:135 +#: flatcamGUI/ObjectUI.py:351 flatcamGUI/ObjectUI.py:1704 +#: flatcamGUI/PreferencesUI.py:2439 flatcamGUI/PreferencesUI.py:4243 +#: flatcamGUI/PreferencesUI.py:5669 flatcamTools/ToolCutOut.py:142 msgid "" "Cutting depth (negative)\n" "below the copper surface." @@ -7312,7 +7661,7 @@ msgstr "" "Profondeur de coupe (négatif)\n" "sous la surface de cuivre." -#: flatcamGUI/ObjectUI.py:361 +#: flatcamGUI/ObjectUI.py:365 msgid "" "Diameter of the cutting tool.\n" "If you want to have an isolation path\n" @@ -7326,11 +7675,11 @@ msgstr "" "fonction, utilisez une valeur négative pour\n" "ce paramètre." -#: flatcamGUI/ObjectUI.py:377 flatcamGUI/PreferencesUI.py:2038 +#: flatcamGUI/ObjectUI.py:381 flatcamGUI/PreferencesUI.py:2218 msgid "# Passes" msgstr "# Passes" -#: flatcamGUI/ObjectUI.py:379 flatcamGUI/PreferencesUI.py:2040 +#: flatcamGUI/ObjectUI.py:383 flatcamGUI/PreferencesUI.py:2220 msgid "" "Width of the isolation gap in\n" "number (integer) of tool widths." @@ -7338,24 +7687,18 @@ msgstr "" "Largeur du fossé d'isolement dans\n" "nombre (entier) de largeurs d'outil." -#: flatcamGUI/ObjectUI.py:389 flatcamGUI/PreferencesUI.py:2050 +#: flatcamGUI/ObjectUI.py:394 flatcamGUI/PreferencesUI.py:2230 msgid "Pass overlap" msgstr "Passe chevauchement" -#: flatcamGUI/ObjectUI.py:391 flatcamGUI/PreferencesUI.py:2052 -msgid "How much (fraction) of the tool width to overlap each tool pass." +#: flatcamGUI/ObjectUI.py:396 flatcamGUI/PreferencesUI.py:2232 +msgid "How much (percentage) of the tool width to overlap each tool pass." msgstr "" -"La quantité (fraction) de la largeur de l'outil qui chevauche chaque passe " +"La quantité (pourcentage) de la largeur d'outil qui chevauche chaque passe " "d'outil." -#: flatcamGUI/ObjectUI.py:403 flatcamGUI/PreferencesUI.py:2077 -#: flatcamGUI/PreferencesUI.py:4372 flatcamGUI/PreferencesUI.py:5112 -#: flatcamTools/ToolNonCopperClear.py:162 -msgid "Milling Type" -msgstr "Type de fraisage" - -#: flatcamGUI/ObjectUI.py:405 flatcamGUI/PreferencesUI.py:2079 -#: flatcamGUI/PreferencesUI.py:4374 +#: flatcamGUI/ObjectUI.py:410 flatcamGUI/PreferencesUI.py:2259 +#: flatcamGUI/PreferencesUI.py:4667 msgid "" "Milling type:\n" "- climb / best for precision milling and to reduce tool usage\n" @@ -7366,29 +7709,19 @@ msgstr "" "d'outils\n" "- conventionnel / utile quand il n'y a pas de compensation de jeu" -#: flatcamGUI/ObjectUI.py:409 flatcamGUI/PreferencesUI.py:2084 -#: flatcamGUI/PreferencesUI.py:4378 flatcamGUI/PreferencesUI.py:5119 -#: flatcamTools/ToolNonCopperClear.py:169 -msgid "Climb" -msgstr "Monté" - -#: flatcamGUI/ObjectUI.py:410 -msgid "Conventional" -msgstr "Conventionnel" - -#: flatcamGUI/ObjectUI.py:415 +#: flatcamGUI/ObjectUI.py:420 msgid "Combine" msgstr "Combiner" -#: flatcamGUI/ObjectUI.py:417 flatcamGUI/PreferencesUI.py:2091 +#: flatcamGUI/ObjectUI.py:422 flatcamGUI/PreferencesUI.py:2271 msgid "Combine all passes into one object" msgstr "Combine tous les passages dans un objet" -#: flatcamGUI/ObjectUI.py:421 flatcamGUI/PreferencesUI.py:2193 +#: flatcamGUI/ObjectUI.py:426 flatcamGUI/PreferencesUI.py:2373 msgid "\"Follow\"" msgstr "\"Suivre\"" -#: flatcamGUI/ObjectUI.py:422 flatcamGUI/PreferencesUI.py:2195 +#: flatcamGUI/ObjectUI.py:427 flatcamGUI/PreferencesUI.py:2375 msgid "" "Generate a 'Follow' geometry.\n" "This means that it will cut through\n" @@ -7398,11 +7731,11 @@ msgstr "" "Cela signifie qu'il va couper à travers\n" "le milieu de la trace." -#: flatcamGUI/ObjectUI.py:428 +#: flatcamGUI/ObjectUI.py:433 msgid "Except" msgstr "Sauf" -#: flatcamGUI/ObjectUI.py:431 +#: flatcamGUI/ObjectUI.py:436 msgid "" "When the isolation geometry is generated,\n" "by checking this, the area of the object bellow\n" @@ -7412,12 +7745,12 @@ msgstr "" "en cochant cela, la zone de l'objet ci-dessous\n" "sera soustrait de la géométrie d'isolation." -#: flatcamGUI/ObjectUI.py:453 flatcamTools/ToolNonCopperClear.py:82 -#: flatcamTools/ToolPaint.py:85 +#: flatcamGUI/ObjectUI.py:456 flatcamTools/ToolNCC.py:86 +#: flatcamTools/ToolPaint.py:80 msgid "Obj Type" msgstr "Type d'objet" -#: flatcamGUI/ObjectUI.py:455 +#: flatcamGUI/ObjectUI.py:458 msgid "" "Specify the type of object to be excepted from isolation.\n" "It can be of type: Gerber or Geometry.\n" @@ -7429,22 +7762,22 @@ msgstr "" "Ce qui est sélectionné ici dictera le genre\n" "des objets qui vont remplir la liste déroulante 'Object'." -#: flatcamGUI/ObjectUI.py:468 flatcamGUI/PreferencesUI.py:7522 -#: flatcamTools/ToolCalibration.py:186 flatcamTools/ToolNonCopperClear.py:100 -#: flatcamTools/ToolPaint.py:103 flatcamTools/ToolPanelize.py:81 -#: flatcamTools/ToolPanelize.py:94 +#: flatcamGUI/ObjectUI.py:471 flatcamGUI/PreferencesUI.py:8028 +#: flatcamTools/ToolCalibration.py:186 flatcamTools/ToolNCC.py:109 +#: flatcamTools/ToolPaint.py:103 flatcamTools/ToolPanelize.py:100 +#: flatcamTools/ToolQRCode.py:78 msgid "Object" msgstr "Objet" -#: flatcamGUI/ObjectUI.py:469 +#: flatcamGUI/ObjectUI.py:472 msgid "Object whose area will be removed from isolation geometry." msgstr "Objet dont l'aire sera retirée de la géométrie d'isolation." -#: flatcamGUI/ObjectUI.py:476 flatcamGUI/PreferencesUI.py:2064 +#: flatcamGUI/ObjectUI.py:479 flatcamGUI/PreferencesUI.py:2244 msgid "Scope" msgstr "Portée" -#: flatcamGUI/ObjectUI.py:478 flatcamGUI/PreferencesUI.py:2066 +#: flatcamGUI/ObjectUI.py:481 flatcamGUI/PreferencesUI.py:2246 msgid "" "Isolation scope. Choose what to isolate:\n" "- 'All' -> Isolate all the polygons in the object\n" @@ -7454,17 +7787,18 @@ msgstr "" "- 'Tout' -> Isoler tous les polygones de l'objet\n" "- 'Sélection' -> Isoler une sélection de polygones." -#: flatcamGUI/ObjectUI.py:483 flatcamGUI/PreferencesUI.py:602 -#: flatcamGUI/PreferencesUI.py:2071 flatcamGUI/PreferencesUI.py:5634 -#: flatcamTools/ToolPaint.py:294 +#: flatcamGUI/ObjectUI.py:486 flatcamGUI/PreferencesUI.py:624 +#: flatcamGUI/PreferencesUI.py:2251 flatcamGUI/PreferencesUI.py:5590 +#: flatcamGUI/PreferencesUI.py:6097 flatcamTools/ToolNCC.py:539 +#: flatcamTools/ToolPaint.py:456 msgid "Selection" msgstr "Sélection" -#: flatcamGUI/ObjectUI.py:491 flatcamGUI/PreferencesUI.py:2272 +#: flatcamGUI/ObjectUI.py:494 flatcamGUI/PreferencesUI.py:2452 msgid "Isolation Type" msgstr "Type d'isolement" -#: flatcamGUI/ObjectUI.py:493 flatcamGUI/PreferencesUI.py:2274 +#: flatcamGUI/ObjectUI.py:496 flatcamGUI/PreferencesUI.py:2454 msgid "" "Choose how the isolation will be executed:\n" "- 'Full' -> complete isolation of polygons\n" @@ -7485,24 +7819,24 @@ msgstr "" "à l'intérieur du polygone (par exemple, le polygone est une forme de `` " "beignet '')." -#: flatcamGUI/ObjectUI.py:502 flatcamGUI/PreferencesUI.py:2283 -#: flatcamGUI/PreferencesUI.py:2304 +#: flatcamGUI/ObjectUI.py:505 flatcamGUI/PreferencesUI.py:2463 +#: flatcamGUI/PreferencesUI.py:2484 msgid "Full" msgstr "Plein" -#: flatcamGUI/ObjectUI.py:503 +#: flatcamGUI/ObjectUI.py:506 msgid "Ext" msgstr "Ext" -#: flatcamGUI/ObjectUI.py:504 +#: flatcamGUI/ObjectUI.py:507 msgid "Int" msgstr "Int" -#: flatcamGUI/ObjectUI.py:509 +#: flatcamGUI/ObjectUI.py:512 msgid "Generate Isolation Geometry" msgstr "Générer une géométrie d'isolation" -#: flatcamGUI/ObjectUI.py:517 +#: flatcamGUI/ObjectUI.py:520 msgid "" "Create a Geometry object with toolpaths to cut \n" "isolation outside, inside or on both sides of the\n" @@ -7524,11 +7858,11 @@ msgstr "" "à l'intérieur de la fonction Gerber, utilisez un outil négatif\n" "diamètre ci-dessus." -#: flatcamGUI/ObjectUI.py:529 +#: flatcamGUI/ObjectUI.py:532 msgid "Buffer Solid Geometry" msgstr "Tampon Géométrie Solide" -#: flatcamGUI/ObjectUI.py:531 +#: flatcamGUI/ObjectUI.py:534 msgid "" "This button is shown only when the Gerber file\n" "is loaded without buffering.\n" @@ -7540,11 +7874,11 @@ msgstr "" "En cliquant sur cela créera la géométrie en mémoire tampon\n" "requis pour l'isolement." -#: flatcamGUI/ObjectUI.py:559 +#: flatcamGUI/ObjectUI.py:566 msgid "Clear N-copper" msgstr "N-Cuivre Clair" -#: flatcamGUI/ObjectUI.py:561 flatcamGUI/PreferencesUI.py:5019 +#: flatcamGUI/ObjectUI.py:568 flatcamGUI/PreferencesUI.py:5312 msgid "" "Create a Geometry object with\n" "toolpaths to cut all non-copper regions." @@ -7552,8 +7886,8 @@ msgstr "" "Créez un objet de géométrie avec\n" "des parcours pour couper toutes les régions non-cuivre." -#: flatcamGUI/ObjectUI.py:568 flatcamGUI/ObjectUI.py:1751 -#: flatcamTools/ToolNonCopperClear.py:473 +#: flatcamGUI/ObjectUI.py:575 flatcamGUI/ObjectUI.py:2077 +#: flatcamTools/ToolNCC.py:599 msgid "" "Create the Geometry Object\n" "for non-copper routing." @@ -7561,11 +7895,11 @@ msgstr "" "Créer l'objet de géométrie\n" "pour un routage non-cuivre." -#: flatcamGUI/ObjectUI.py:581 +#: flatcamGUI/ObjectUI.py:588 msgid "Board cutout" msgstr "Découpe de la planche" -#: flatcamGUI/ObjectUI.py:583 flatcamGUI/PreferencesUI.py:5303 +#: flatcamGUI/ObjectUI.py:590 flatcamGUI/PreferencesUI.py:5642 msgid "" "Create toolpaths to cut around\n" "the PCB and separate it from\n" @@ -7575,7 +7909,7 @@ msgstr "" "le PCB et séparez-le de\n" "la planche d'origine." -#: flatcamGUI/ObjectUI.py:590 +#: flatcamGUI/ObjectUI.py:597 msgid "" "Generate the geometry for\n" "the board cutout." @@ -7583,11 +7917,11 @@ msgstr "" "Générer la géométrie pour\n" "la découpe de la planche." -#: flatcamGUI/ObjectUI.py:608 flatcamGUI/PreferencesUI.py:2101 +#: flatcamGUI/ObjectUI.py:615 flatcamGUI/PreferencesUI.py:2281 msgid "Non-copper regions" msgstr "Régions non-cuivre" -#: flatcamGUI/ObjectUI.py:610 flatcamGUI/PreferencesUI.py:2103 +#: flatcamGUI/ObjectUI.py:617 flatcamGUI/PreferencesUI.py:2283 msgid "" "Create polygons covering the\n" "areas without copper on the PCB.\n" @@ -7601,12 +7935,12 @@ msgstr "" "objet. Peut être utilisé pour tout enlever\n" "cuivre provenant d'une région spécifiée." -#: flatcamGUI/ObjectUI.py:620 flatcamGUI/ObjectUI.py:661 -#: flatcamGUI/PreferencesUI.py:2115 flatcamGUI/PreferencesUI.py:2148 +#: flatcamGUI/ObjectUI.py:627 flatcamGUI/ObjectUI.py:668 +#: flatcamGUI/PreferencesUI.py:2295 flatcamGUI/PreferencesUI.py:2328 msgid "Boundary Margin" msgstr "Marge limite" -#: flatcamGUI/ObjectUI.py:622 flatcamGUI/PreferencesUI.py:2117 +#: flatcamGUI/ObjectUI.py:629 flatcamGUI/PreferencesUI.py:2297 msgid "" "Specify the edge of the PCB\n" "by drawing a box around all\n" @@ -7618,27 +7952,27 @@ msgstr "" "objets avec ce minimum\n" "distance." -#: flatcamGUI/ObjectUI.py:637 flatcamGUI/ObjectUI.py:675 -#: flatcamGUI/PreferencesUI.py:2130 flatcamGUI/PreferencesUI.py:2161 +#: flatcamGUI/ObjectUI.py:644 flatcamGUI/ObjectUI.py:682 +#: flatcamGUI/PreferencesUI.py:2310 flatcamGUI/PreferencesUI.py:2341 msgid "Rounded Geo" msgstr "Géométrie Arrondie" -#: flatcamGUI/ObjectUI.py:639 flatcamGUI/PreferencesUI.py:2132 +#: flatcamGUI/ObjectUI.py:646 flatcamGUI/PreferencesUI.py:2312 msgid "Resulting geometry will have rounded corners." msgstr "La géométrie résultante aura des coins arrondis." -#: flatcamGUI/ObjectUI.py:643 flatcamGUI/ObjectUI.py:684 -#: flatcamTools/ToolSolderPaste.py:133 +#: flatcamGUI/ObjectUI.py:650 flatcamGUI/ObjectUI.py:691 +#: flatcamTools/ToolSolderPaste.py:135 msgid "Generate Geo" msgstr "Générer de la Géo" -#: flatcamGUI/ObjectUI.py:653 flatcamGUI/PreferencesUI.py:2142 -#: flatcamGUI/PreferencesUI.py:7052 flatcamTools/ToolPanelize.py:95 +#: flatcamGUI/ObjectUI.py:660 flatcamGUI/PreferencesUI.py:2322 +#: flatcamGUI/PreferencesUI.py:7558 flatcamTools/ToolPanelize.py:101 #: flatcamTools/ToolQRCode.py:192 msgid "Bounding Box" msgstr "Cadre de sélection" -#: flatcamGUI/ObjectUI.py:655 +#: flatcamGUI/ObjectUI.py:662 msgid "" "Create a geometry surrounding the Gerber object.\n" "Square shape." @@ -7646,7 +7980,7 @@ msgstr "" "Créez une géométrie entourant l'objet Gerber.\n" "Forme carree." -#: flatcamGUI/ObjectUI.py:663 flatcamGUI/PreferencesUI.py:2150 +#: flatcamGUI/ObjectUI.py:670 flatcamGUI/PreferencesUI.py:2330 msgid "" "Distance of the edges of the box\n" "to the nearest polygon." @@ -7654,7 +7988,7 @@ msgstr "" "Distance des bords de la boîte\n" "au polygone le plus proche." -#: flatcamGUI/ObjectUI.py:677 flatcamGUI/PreferencesUI.py:2163 +#: flatcamGUI/ObjectUI.py:684 flatcamGUI/PreferencesUI.py:2343 msgid "" "If the bounding box is \n" "to have rounded corners\n" @@ -7666,33 +8000,31 @@ msgstr "" "leur rayon est égal à\n" "la marge." -#: flatcamGUI/ObjectUI.py:686 +#: flatcamGUI/ObjectUI.py:693 msgid "Generate the Geometry object." msgstr "Générez l'objet Geometry." -#: flatcamGUI/ObjectUI.py:715 +#: flatcamGUI/ObjectUI.py:720 msgid "Excellon Object" msgstr "Excellent objet" -#: flatcamGUI/ObjectUI.py:729 +#: flatcamGUI/ObjectUI.py:732 msgid "Solid circles." msgstr "Cercles pleins." -#: flatcamGUI/ObjectUI.py:777 flatcamGUI/ObjectUI.py:1926 -#: flatcamTools/ToolProperties.py:161 +#: flatcamGUI/ObjectUI.py:780 flatcamGUI/ObjectUI.py:875 +#: flatcamGUI/ObjectUI.py:2254 flatcamGUI/PreferencesUI.py:3289 +#: flatcamTools/ToolProperties.py:166 msgid "Drills" msgstr "Forage" -#: flatcamGUI/ObjectUI.py:777 flatcamGUI/ObjectUI.py:1926 -#: flatcamGUI/PreferencesUI.py:3683 flatcamTools/ToolProperties.py:162 +#: flatcamGUI/ObjectUI.py:780 flatcamGUI/ObjectUI.py:876 +#: flatcamGUI/ObjectUI.py:2254 flatcamGUI/PreferencesUI.py:3290 +#: flatcamGUI/PreferencesUI.py:3961 flatcamTools/ToolProperties.py:168 msgid "Slots" msgstr "Fentes" -#: flatcamGUI/ObjectUI.py:778 flatcamGUI/PreferencesUI.py:3289 -msgid "Offset Z" -msgstr "Décalage Z" - -#: flatcamGUI/ObjectUI.py:782 +#: flatcamGUI/ObjectUI.py:785 msgid "" "This is the Tool Number.\n" "When ToolChange is checked, on toolchange event this value\n" @@ -7707,8 +8039,8 @@ msgstr "" "\n" "Ici, les outils sont sélectionnés pour la génération de code G." -#: flatcamGUI/ObjectUI.py:787 flatcamGUI/ObjectUI.py:1230 -#: flatcamTools/ToolPaint.py:137 +#: flatcamGUI/ObjectUI.py:790 flatcamGUI/ObjectUI.py:1508 +#: flatcamTools/ToolPaint.py:142 msgid "" "Tool Diameter. It's value (in current FlatCAM units) \n" "is the cut width into the material." @@ -7716,7 +8048,7 @@ msgstr "" "Diamètre de l'outil. C'est sa valeur (en unités FlatCAM actuelles)\n" "est la largeur de coupe dans le matériau." -#: flatcamGUI/ObjectUI.py:790 +#: flatcamGUI/ObjectUI.py:793 msgid "" "The number of Drill holes. Holes that are drilled with\n" "a drill bit." @@ -7724,7 +8056,7 @@ msgstr "" "Le nombre de trous de forage. Trous percés de\n" "un foret." -#: flatcamGUI/ObjectUI.py:793 +#: flatcamGUI/ObjectUI.py:796 msgid "" "The number of Slot holes. Holes that are created by\n" "milling them with an endmill bit." @@ -7732,18 +8064,7 @@ msgstr "" "Le nombre de trous de fente. Trous créés par\n" "les fraiser avec un bit de fraise." -#: flatcamGUI/ObjectUI.py:796 flatcamGUI/PreferencesUI.py:3291 -msgid "" -"Some drill bits (the larger ones) need to drill deeper\n" -"to create the desired exit hole diameter due of the tip shape.\n" -"The value here can compensate the Cut Z parameter." -msgstr "" -"Certains forets (les plus gros) doivent forer plus profondément\n" -"pour créer le diamètre du trou de sortie souhaité en raison de la forme de " -"la pointe.\n" -"La valeur ici peut compenser le paramètre Cut Z." - -#: flatcamGUI/ObjectUI.py:800 +#: flatcamGUI/ObjectUI.py:799 msgid "" "Toggle display of the drills for the current tool.\n" "This does not select the tools for G-code generation." @@ -7751,20 +8072,60 @@ msgstr "" "Basculer l'affichage des exercices pour l'outil actuel.\n" "Cela ne sélectionne pas les outils pour la génération de G-code." -#: flatcamGUI/ObjectUI.py:807 flatcamGUI/PreferencesUI.py:3069 -#: flatcamGUI/PreferencesUI.py:3947 -msgid "Create CNC Job" -msgstr "Créer un travail CNC" - -#: flatcamGUI/ObjectUI.py:809 +#: flatcamGUI/ObjectUI.py:820 flatcamGUI/ObjectUI.py:1663 +#: flatcamTools/ToolNCC.py:334 flatcamTools/ToolPaint.py:317 msgid "" -"Create a CNC Job object\n" -"for this drill object." +"The data used for creating GCode.\n" +"Each tool store it's own set of such data." msgstr "" -"Créer un objet de travail CNC\n" -"pour cet objet de forage." +"Les données utilisées pour créer le GCode.\n" +"Chaque outil stocke son propre ensemble de données." -#: flatcamGUI/ObjectUI.py:822 flatcamGUI/PreferencesUI.py:3084 +#: flatcamGUI/ObjectUI.py:846 flatcamGUI/PreferencesUI.py:3266 +msgid "" +"Operation type:\n" +"- Drilling -> will drill the drills/slots associated with this tool\n" +"- Milling -> will mill the drills/slots" +msgstr "" +"Type d'opération:\n" +"- Perçage -> va percer les forets / emplacements associés à cet outil\n" +"- Fraisage -> fraisera les forets / fentes" + +#: flatcamGUI/ObjectUI.py:852 flatcamGUI/PreferencesUI.py:3272 +msgid "Drilling" +msgstr "Forage" + +#: flatcamGUI/ObjectUI.py:853 flatcamGUI/PreferencesUI.py:3273 +msgid "Milling" +msgstr "Fraisage" + +#: flatcamGUI/ObjectUI.py:868 flatcamGUI/PreferencesUI.py:3282 +msgid "" +"Milling type:\n" +"- Drills -> will mill the drills associated with this tool\n" +"- Slots -> will mill the slots associated with this tool\n" +"- Both -> will mill both drills and mills or whatever is available" +msgstr "" +"Type de fraisage:\n" +"- Forets -> fraisera les forets associés à cet outil\n" +"- Slots -> fraisera les slots associés à cet outil\n" +"- Les deux -> fraisera les forets et les fraises ou tout ce qui est " +"disponible" + +#: flatcamGUI/ObjectUI.py:877 flatcamGUI/PreferencesUI.py:3291 +#: flatcamGUI/PreferencesUI.py:6343 flatcamTools/ToolFilm.py:258 +msgid "Both" +msgstr "Tous les deux" + +#: flatcamGUI/ObjectUI.py:885 flatcamGUI/PreferencesUI.py:3298 +msgid "Milling Diameter" +msgstr "Dia. de fraisage" + +#: flatcamGUI/ObjectUI.py:887 flatcamGUI/PreferencesUI.py:3300 +msgid "The diameter of the tool who will do the milling" +msgstr "Le diamètre de l'outil qui fera le fraisage" + +#: flatcamGUI/ObjectUI.py:901 flatcamGUI/PreferencesUI.py:3313 msgid "" "Drill depth (negative)\n" "below the copper surface." @@ -7772,7 +8133,33 @@ msgstr "" "Profondeur de forage (négatif)\n" "sous la surface de cuivre." -#: flatcamGUI/ObjectUI.py:841 flatcamGUI/PreferencesUI.py:3102 +#: flatcamGUI/ObjectUI.py:920 flatcamGUI/ObjectUI.py:1722 +#: flatcamGUI/PreferencesUI.py:3331 flatcamGUI/PreferencesUI.py:4261 +#: flatcamGUI/PreferencesUI.py:5687 flatcamTools/ToolCutOut.py:160 +msgid "Multi-Depth" +msgstr "Multi-profondeur" + +#: flatcamGUI/ObjectUI.py:923 flatcamGUI/ObjectUI.py:1725 +#: flatcamGUI/PreferencesUI.py:3334 flatcamGUI/PreferencesUI.py:4264 +#: flatcamGUI/PreferencesUI.py:5690 flatcamTools/ToolCutOut.py:163 +msgid "" +"Use multiple passes to limit\n" +"the cut depth in each pass. Will\n" +"cut multiple times until Cut Z is\n" +"reached." +msgstr "" +"Utilisez plusieurs passes pour limiter\n" +"la profondeur de coupe à chaque passage. Volonté\n" +"couper plusieurs fois jusqu'à ce que Cut Z soit\n" +"atteint." + +#: flatcamGUI/ObjectUI.py:936 flatcamGUI/ObjectUI.py:1739 +#: flatcamGUI/PreferencesUI.py:3346 flatcamGUI/PreferencesUI.py:5702 +#: flatcamTools/ToolCutOut.py:177 +msgid "Depth of each pass (positive)." +msgstr "Profondeur de chaque passage (positif)." + +#: flatcamGUI/ObjectUI.py:947 flatcamGUI/PreferencesUI.py:3354 msgid "" "Tool height when travelling\n" "across the XY plane." @@ -7780,61 +8167,16 @@ msgstr "" "Hauteur de l'outil en voyage\n" "à travers le plan XY." -#: flatcamGUI/ObjectUI.py:858 flatcamGUI/ObjectUI.py:1478 -#: flatcamGUI/PreferencesUI.py:3117 flatcamGUI/PreferencesUI.py:4034 -msgid "Tool change" -msgstr "Changement d'outil" - -#: flatcamGUI/ObjectUI.py:860 flatcamGUI/PreferencesUI.py:3119 +#: flatcamGUI/ObjectUI.py:968 flatcamGUI/ObjectUI.py:1769 +#: flatcamGUI/PreferencesUI.py:4380 msgid "" -"Include tool-change sequence\n" -"in G-Code (Pause for tool change)." +"Cutting speed in the XY\n" +"plane in units per minute" msgstr "" -"Inclure la séquence de changement d'outil\n" -"dans G-Code (Pause pour changement d’outil)." +"Vitesse de coupe dans le XY\n" +"avion en unités par minute" -#: flatcamGUI/ObjectUI.py:866 flatcamGUI/ObjectUI.py:1471 -msgid "Tool change Z" -msgstr "Changement d'outil Z" - -#: flatcamGUI/ObjectUI.py:868 flatcamGUI/ObjectUI.py:1474 -#: flatcamGUI/PreferencesUI.py:3126 flatcamGUI/PreferencesUI.py:4047 -msgid "" -"Z-axis position (height) for\n" -"tool change." -msgstr "" -"Position de l'axe Z (hauteur) pour\n" -"changement d'outil." - -#: flatcamGUI/ObjectUI.py:888 flatcamGUI/PreferencesUI.py:3311 -msgid "" -"Height of the tool just after start.\n" -"Delete the value if you don't need this feature." -msgstr "" -"Hauteur de l'outil juste après le démarrage.\n" -"Supprimez la valeur si vous n'avez pas besoin de cette fonctionnalité." - -#: flatcamGUI/ObjectUI.py:896 flatcamGUI/ObjectUI.py:1512 -#: flatcamGUI/PreferencesUI.py:3141 flatcamGUI/PreferencesUI.py:4066 -msgid "End move Z" -msgstr "Fin du mouve. Z" - -#: flatcamGUI/ObjectUI.py:898 flatcamGUI/ObjectUI.py:1514 -#: flatcamGUI/PreferencesUI.py:3143 flatcamGUI/PreferencesUI.py:4068 -msgid "" -"Height of the tool after\n" -"the last move at the end of the job." -msgstr "" -"Hauteur de l'outil après\n" -"le dernier mouvement à la fin du travail." - -#: flatcamGUI/ObjectUI.py:915 flatcamGUI/ObjectUI.py:1545 -#: flatcamGUI/PreferencesUI.py:3158 flatcamGUI/PreferencesUI.py:4101 -#: flatcamGUI/PreferencesUI.py:6566 flatcamTools/ToolSolderPaste.py:264 -msgid "Feedrate Z" -msgstr "Avance Z" - -#: flatcamGUI/ObjectUI.py:917 flatcamGUI/PreferencesUI.py:3160 +#: flatcamGUI/ObjectUI.py:983 flatcamGUI/PreferencesUI.py:3427 msgid "" "Tool speed while drilling\n" "(in units per minute).\n" @@ -7846,12 +8188,12 @@ msgstr "" "Ce qu'on appelle \"avance\".\n" "Ceci est pour le mouvement linéaire G01." -#: flatcamGUI/ObjectUI.py:931 flatcamGUI/ObjectUI.py:1560 -#: flatcamGUI/PreferencesUI.py:3319 flatcamGUI/PreferencesUI.py:4210 +#: flatcamGUI/ObjectUI.py:998 flatcamGUI/ObjectUI.py:1796 +#: flatcamGUI/PreferencesUI.py:3597 flatcamGUI/PreferencesUI.py:4503 msgid "Feedrate Rapids" msgstr "Avance rapide" -#: flatcamGUI/ObjectUI.py:933 flatcamGUI/PreferencesUI.py:3321 +#: flatcamGUI/ObjectUI.py:1000 flatcamGUI/PreferencesUI.py:3599 msgid "" "Tool speed while drilling\n" "(in units per minute).\n" @@ -7865,12 +8207,26 @@ msgstr "" "C'est utile seulement pour Marlin,\n" "ignorer pour les autres cas." -#: flatcamGUI/ObjectUI.py:951 flatcamGUI/ObjectUI.py:1603 -#: flatcamGUI/PreferencesUI.py:4117 -msgid "Spindle speed" -msgstr "Vitesse de broche" +#: flatcamGUI/ObjectUI.py:1020 flatcamGUI/ObjectUI.py:1816 +#: flatcamGUI/PreferencesUI.py:4521 +msgid "Re-cut" +msgstr "Re-coupé" -#: flatcamGUI/ObjectUI.py:953 flatcamGUI/PreferencesUI.py:3175 +#: flatcamGUI/ObjectUI.py:1022 flatcamGUI/ObjectUI.py:1035 +#: flatcamGUI/ObjectUI.py:1818 flatcamGUI/ObjectUI.py:1830 +#: flatcamGUI/PreferencesUI.py:4523 flatcamGUI/PreferencesUI.py:4535 +msgid "" +"In order to remove possible\n" +"copper leftovers where first cut\n" +"meet with last cut, we generate an\n" +"extended cut over the first cut section." +msgstr "" +"Afin de supprimer possible\n" +"restes de cuivre où la première coupe\n" +"rencontre avec la dernière coupe, nous générons un\n" +"coupe étendue sur la première section coupée." + +#: flatcamGUI/ObjectUI.py:1050 flatcamGUI/PreferencesUI.py:3442 msgid "" "Speed of the spindle\n" "in RPM (optional)" @@ -7878,8 +8234,8 @@ msgstr "" "Vitesse de la broche\n" "en tours / minute (optionnel)" -#: flatcamGUI/ObjectUI.py:965 flatcamGUI/ObjectUI.py:1622 -#: flatcamGUI/PreferencesUI.py:3187 flatcamGUI/PreferencesUI.py:4135 +#: flatcamGUI/ObjectUI.py:1065 flatcamGUI/ObjectUI.py:1858 +#: flatcamGUI/PreferencesUI.py:3456 flatcamGUI/PreferencesUI.py:4427 msgid "" "Pause to allow the spindle to reach its\n" "speed before cutting." @@ -7887,26 +8243,116 @@ msgstr "" "Pause pour permettre à la broche d’atteindre son\n" "vitesse avant de couper." -#: flatcamGUI/ObjectUI.py:974 flatcamGUI/ObjectUI.py:1632 -#: flatcamGUI/PreferencesUI.py:3193 flatcamGUI/PreferencesUI.py:4140 +#: flatcamGUI/ObjectUI.py:1076 flatcamGUI/ObjectUI.py:1868 +#: flatcamGUI/PreferencesUI.py:3464 flatcamGUI/PreferencesUI.py:4432 msgid "Number of time units for spindle to dwell." msgstr "Nombre d'unités de temps pendant lesquelles la broche s'arrête." -#: flatcamGUI/ObjectUI.py:984 flatcamGUI/PreferencesUI.py:3206 -msgid "" -"The preprocessor JSON file that dictates\n" -"Gcode output." -msgstr "" -"Le fichier JSON post-processeur qui dicte\n" -"Sortie Gcode." +#: flatcamGUI/ObjectUI.py:1086 flatcamGUI/PreferencesUI.py:3563 +msgid "Offset Z" +msgstr "Décalage Z" -#: flatcamGUI/ObjectUI.py:993 flatcamGUI/ObjectUI.py:1652 -#: flatcamGUI/PreferencesUI.py:3335 flatcamGUI/PreferencesUI.py:4251 +#: flatcamGUI/ObjectUI.py:1088 flatcamGUI/PreferencesUI.py:3565 +msgid "" +"Some drill bits (the larger ones) need to drill deeper\n" +"to create the desired exit hole diameter due of the tip shape.\n" +"The value here can compensate the Cut Z parameter." +msgstr "" +"Certains forets (les plus gros) doivent forer plus profondément\n" +"pour créer le diamètre du trou de sortie souhaité en raison de la forme de " +"la pointe.\n" +"La valeur ici peut compenser le paramètre Cut Z." + +#: flatcamGUI/ObjectUI.py:1148 flatcamGUI/ObjectUI.py:1922 +#: flatcamTools/ToolNCC.py:492 flatcamTools/ToolPaint.py:423 +msgid "Apply parameters to all tools" +msgstr "Appliquer des paramètres à tous les outils" + +#: flatcamGUI/ObjectUI.py:1150 flatcamGUI/ObjectUI.py:1924 +#: flatcamTools/ToolNCC.py:494 flatcamTools/ToolPaint.py:425 +msgid "" +"The parameters in the current form will be applied\n" +"on all the tools from the Tool Table." +msgstr "" +"Les paramètres du formulaire actuel seront appliqués\n" +"sur tous les outils de la table d'outils." + +#: flatcamGUI/ObjectUI.py:1161 flatcamGUI/ObjectUI.py:1935 +#: flatcamTools/ToolNCC.py:505 flatcamTools/ToolPaint.py:436 +msgid "Common Parameters" +msgstr "Paramètres communs" + +#: flatcamGUI/ObjectUI.py:1163 flatcamGUI/ObjectUI.py:1937 +#: flatcamTools/ToolNCC.py:507 flatcamTools/ToolPaint.py:438 +msgid "Parameters that are common for all tools." +msgstr "Paramètres communs à tous les outils." + +#: flatcamGUI/ObjectUI.py:1168 flatcamGUI/ObjectUI.py:1942 +msgid "Tool change Z" +msgstr "Changement d'outil Z" + +#: flatcamGUI/ObjectUI.py:1170 flatcamGUI/PreferencesUI.py:3372 +msgid "" +"Include tool-change sequence\n" +"in G-Code (Pause for tool change)." +msgstr "" +"Inclure la séquence de changement d'outil\n" +"dans G-Code (Pause pour changement d’outil)." + +#: flatcamGUI/ObjectUI.py:1177 flatcamGUI/ObjectUI.py:1953 +#: flatcamGUI/PreferencesUI.py:3380 flatcamGUI/PreferencesUI.py:4327 +msgid "" +"Z-axis position (height) for\n" +"tool change." +msgstr "" +"Position de l'axe Z (hauteur) pour\n" +"changement d'outil." + +#: flatcamGUI/ObjectUI.py:1194 flatcamGUI/PreferencesUI.py:3588 +msgid "" +"Height of the tool just after start.\n" +"Delete the value if you don't need this feature." +msgstr "" +"Hauteur de l'outil juste après le démarrage.\n" +"Supprimez la valeur si vous n'avez pas besoin de cette fonctionnalité." + +#: flatcamGUI/ObjectUI.py:1203 flatcamGUI/ObjectUI.py:1981 +#: flatcamGUI/PreferencesUI.py:3396 flatcamGUI/PreferencesUI.py:4346 +msgid "End move Z" +msgstr "Fin du mouve. Z" + +#: flatcamGUI/ObjectUI.py:1205 flatcamGUI/ObjectUI.py:1983 +#: flatcamGUI/PreferencesUI.py:3398 flatcamGUI/PreferencesUI.py:4348 +msgid "" +"Height of the tool after\n" +"the last move at the end of the job." +msgstr "" +"Hauteur de l'outil après\n" +"le dernier mouvement à la fin du travail." + +#: flatcamGUI/ObjectUI.py:1222 flatcamGUI/ObjectUI.py:2000 +#: flatcamGUI/PreferencesUI.py:3413 flatcamGUI/PreferencesUI.py:4366 +msgid "End move X,Y" +msgstr "Fin de coup X, Y" + +#: flatcamGUI/ObjectUI.py:1224 flatcamGUI/ObjectUI.py:2002 +#: flatcamGUI/PreferencesUI.py:3415 flatcamGUI/PreferencesUI.py:4368 +msgid "" +"End move X,Y position. In format (x,y).\n" +"If no value is entered then there is no move\n" +"on X,Y plane at the end of the job." +msgstr "" +"Fin du mouvement en position X, Y. Au format (x, y).\n" +"Si aucune valeur n'est entrée, il n'y a pas de mouvement\n" +"sur l'avion X, Y à la fin du travail." + +#: flatcamGUI/ObjectUI.py:1234 flatcamGUI/ObjectUI.py:1876 +#: flatcamGUI/PreferencesUI.py:3613 flatcamGUI/PreferencesUI.py:4544 msgid "Probe Z depth" msgstr "Prof.r de la sonde Z" -#: flatcamGUI/ObjectUI.py:995 flatcamGUI/ObjectUI.py:1654 -#: flatcamGUI/PreferencesUI.py:3337 flatcamGUI/PreferencesUI.py:4253 +#: flatcamGUI/ObjectUI.py:1236 flatcamGUI/ObjectUI.py:1878 +#: flatcamGUI/PreferencesUI.py:3615 flatcamGUI/PreferencesUI.py:4546 msgid "" "The maximum depth that the probe is allowed\n" "to probe. Negative value, in current units." @@ -7914,45 +8360,71 @@ msgstr "" "La profondeur maximale autorisée pour la sonde\n" "sonder. Valeur négative, en unités actuelles." -#: flatcamGUI/ObjectUI.py:1009 flatcamGUI/ObjectUI.py:1669 -#: flatcamGUI/PreferencesUI.py:3348 flatcamGUI/PreferencesUI.py:4266 +#: flatcamGUI/ObjectUI.py:1252 flatcamGUI/ObjectUI.py:1893 +#: flatcamGUI/PreferencesUI.py:3626 flatcamGUI/PreferencesUI.py:4559 msgid "Feedrate Probe" msgstr "Sonde d'avance" -#: flatcamGUI/ObjectUI.py:1011 flatcamGUI/ObjectUI.py:1671 -#: flatcamGUI/PreferencesUI.py:3350 flatcamGUI/PreferencesUI.py:4268 +#: flatcamGUI/ObjectUI.py:1254 flatcamGUI/ObjectUI.py:1895 +#: flatcamGUI/PreferencesUI.py:3628 flatcamGUI/PreferencesUI.py:4561 msgid "The feedrate used while the probe is probing." msgstr "L'avance utilisée pendant le sondage." -#: flatcamGUI/ObjectUI.py:1037 flatcamGUI/PreferencesUI.py:3215 -msgid "Gcode" -msgstr "Gcode" +#: flatcamGUI/ObjectUI.py:1261 +msgid "e_fr_probe" +msgstr "e_fr_probe" -#: flatcamGUI/ObjectUI.py:1039 +#: flatcamGUI/ObjectUI.py:1270 +msgid "Preprocessor E" +msgstr "Post-processeur E" + +#: flatcamGUI/ObjectUI.py:1272 msgid "" -"Choose what to use for GCode generation:\n" -"'Drills', 'Slots' or 'Both'.\n" -"When choosing 'Slots' or 'Both', slots will be\n" -"converted to a series of drills." +"The preprocessor JSON file that dictates\n" +"Gcode output for Excellon Objects." msgstr "" -"Choisissez ce qu'il faut utiliser pour la génération de GCode:\n" -"«Forages», «Fentes» ou «Les deux».\n" -"Lorsque vous choisissez \"Fentes\" ou \"Les deux\", les slots seront\n" -"converti en une série d'exercices." +"Le fichier JSON du préprocesseur qui dicte\n" +"Sortie Gcode pour Excellon Objects." -#: flatcamGUI/ObjectUI.py:1053 -msgid "Create Drills GCode" -msgstr "Créer un forage GCode" +#: flatcamGUI/ObjectUI.py:1282 +msgid "Preprocessor G" +msgstr "Post-processeur G" -#: flatcamGUI/ObjectUI.py:1055 -msgid "Generate the CNC Job." -msgstr "Générez le travail CNC." +#: flatcamGUI/ObjectUI.py:1284 +msgid "" +"The preprocessor JSON file that dictates\n" +"Gcode output for Geometry (Milling) Objects." +msgstr "" +"Le fichier JSON du préprocesseur qui dicte\n" +"Sortie Gcode pour les objets de géométrie (fraisage)." -#: flatcamGUI/ObjectUI.py:1066 flatcamGUI/PreferencesUI.py:3233 -msgid "Mill Holes" -msgstr "Fraiser les Trous" +#: flatcamGUI/ObjectUI.py:1308 flatcamGUI/ObjectUI.py:2026 +msgid "" +"Add / Select at least one tool in the tool-table.\n" +"Click the # header to select all, or Ctrl + LMB\n" +"for custom selection of tools." +msgstr "" +"Ajoutez / sélectionnez au moins un outil dans la table d'outils.\n" +"Cliquez sur l'en-tête # pour tout sélectionner ou sur Ctrl + LMB\n" +"pour une sélection personnalisée d'outils." -#: flatcamGUI/ObjectUI.py:1068 +#: flatcamGUI/ObjectUI.py:1316 flatcamGUI/ObjectUI.py:2033 +msgid "Generate CNCJob object" +msgstr "Générer un objet CNCJob" + +#: flatcamGUI/ObjectUI.py:1318 +msgid "" +"Generate the CNC Job.\n" +"If milling then an additional Geometry object will be created" +msgstr "" +"Générez le travail CNC.\n" +"En cas de fraisage, un objet Geometry supplémentaire sera créé" + +#: flatcamGUI/ObjectUI.py:1335 +msgid "Milling Geometry" +msgstr "Géo. de fraisage" + +#: flatcamGUI/ObjectUI.py:1337 msgid "" "Create Geometry for milling holes.\n" "Select from the Tools Table above the hole dias to be\n" @@ -7962,20 +8434,16 @@ msgstr "" "Sélectionnez dans le tableau des outils au-dessus du diamètre du trou à\n" "fraisé. Utilisez la colonne # pour effectuer la sélection." -#: flatcamGUI/ObjectUI.py:1074 flatcamGUI/PreferencesUI.py:3239 -msgid "Drill Tool dia" -msgstr "Dia. de l'outil de forage" - -#: flatcamGUI/ObjectUI.py:1076 flatcamGUI/PreferencesUI.py:2027 -#: flatcamGUI/PreferencesUI.py:3241 +#: flatcamGUI/ObjectUI.py:1345 flatcamGUI/PreferencesUI.py:2207 +#: flatcamGUI/PreferencesUI.py:3514 msgid "Diameter of the cutting tool." msgstr "Diamètre de l'outil de coupe." -#: flatcamGUI/ObjectUI.py:1083 -msgid "Mill Drills Geo" -msgstr "Fraiser Géo des Trous" +#: flatcamGUI/ObjectUI.py:1355 +msgid "Mill Drills" +msgstr "Fraiser les Forets" -#: flatcamGUI/ObjectUI.py:1085 +#: flatcamGUI/ObjectUI.py:1357 msgid "" "Create the Geometry Object\n" "for milling DRILLS toolpaths." @@ -7983,23 +8451,11 @@ msgstr "" "Créer l'objet de géométrie\n" "pour fraiser des parcours d’outils." -#: flatcamGUI/ObjectUI.py:1099 flatcamGUI/PreferencesUI.py:3250 -msgid "Slot Tool dia" -msgstr "Fente outil dia" +#: flatcamGUI/ObjectUI.py:1375 +msgid "Mill Slots" +msgstr "Fraiser les Fentes" -#: flatcamGUI/ObjectUI.py:1101 flatcamGUI/PreferencesUI.py:3252 -msgid "" -"Diameter of the cutting tool\n" -"when milling slots." -msgstr "" -"Diamètre de l'outil de coupe\n" -"lors du fraisage des fentes." - -#: flatcamGUI/ObjectUI.py:1110 -msgid "Mill Slots Geo" -msgstr "Fraiser la Géo de la Fente" - -#: flatcamGUI/ObjectUI.py:1112 +#: flatcamGUI/ObjectUI.py:1377 msgid "" "Create the Geometry Object\n" "for milling SLOTS toolpaths." @@ -8007,11 +8463,11 @@ msgstr "" "Créer l'objet de géométrie\n" "pour fraiser des parcours d’outils." -#: flatcamGUI/ObjectUI.py:1152 flatcamTools/ToolCutOut.py:317 +#: flatcamGUI/ObjectUI.py:1419 flatcamTools/ToolCutOut.py:327 msgid "Geometry Object" msgstr "Objet de géométrie" -#: flatcamGUI/ObjectUI.py:1186 +#: flatcamGUI/ObjectUI.py:1465 msgid "" "Tools in this Geometry object used for cutting.\n" "The 'Offset' entry will set an offset for the cut.\n" @@ -8042,23 +8498,23 @@ msgstr "" "a montré des entrées de formulaire d’interface utilisateur nommées V-Tip Dia " "et V-Tip Angle." -#: flatcamGUI/ObjectUI.py:1203 flatcamGUI/ObjectUI.py:1903 -#: flatcamGUI/PreferencesUI.py:4405 +#: flatcamGUI/ObjectUI.py:1482 flatcamGUI/ObjectUI.py:2231 +#: flatcamGUI/PreferencesUI.py:4698 msgid "Plot Object" msgstr "Dessiner un objet" -#: flatcamGUI/ObjectUI.py:1217 flatcamGUI/ObjectUI.py:1916 -#: flatcamGUI/ObjectUI.py:1926 flatcamGUI/PreferencesUI.py:7241 -#: flatcamTools/ToolCopperThieving.py:220 +#: flatcamGUI/ObjectUI.py:1495 flatcamGUI/ObjectUI.py:2244 +#: flatcamGUI/ObjectUI.py:2254 flatcamGUI/PreferencesUI.py:7747 +#: flatcamTools/ToolCopperThieving.py:222 msgid "Dia" msgstr "Dia" -#: flatcamGUI/ObjectUI.py:1217 flatcamGUI/ObjectUI.py:1916 -#: flatcamTools/ToolNonCopperClear.py:120 flatcamTools/ToolPaint.py:123 +#: flatcamGUI/ObjectUI.py:1495 flatcamGUI/ObjectUI.py:2244 +#: flatcamTools/ToolNCC.py:132 flatcamTools/ToolPaint.py:128 msgid "TT" msgstr "TT" -#: flatcamGUI/ObjectUI.py:1224 +#: flatcamGUI/ObjectUI.py:1502 msgid "" "This is the Tool Number.\n" "When ToolChange is checked, on toolchange event this value\n" @@ -8069,7 +8525,7 @@ msgstr "" "cette valeur\n" "sera montré comme un T1, T2 ... Tn" -#: flatcamGUI/ObjectUI.py:1235 +#: flatcamGUI/ObjectUI.py:1513 msgid "" "The value for the Offset can be:\n" "- Path -> There is no offset, the tool cut will be done through the geometry " @@ -8085,7 +8541,7 @@ msgstr "" "créer une \"poche\".\n" "- Extérieur -> L'outil coupé suivra la ligne géométrique à l'extérieur." -#: flatcamGUI/ObjectUI.py:1242 +#: flatcamGUI/ObjectUI.py:1520 msgid "" "The (Operation) Type has only informative value. Usually the UI form " "values \n" @@ -8107,7 +8563,7 @@ msgstr "" "Pour l'isolation, nous avons besoin d'une vitesse d'avance plus faible car " "elle utilise un foret à pointe fine." -#: flatcamGUI/ObjectUI.py:1251 +#: flatcamGUI/ObjectUI.py:1529 msgid "" "The Tool Type (TT) can be:\n" "- Circular with 1 ... 4 teeth -> it is informative only. Being circular the " @@ -8137,7 +8593,7 @@ msgstr "" "Le choix du type d'outil en forme de V sélectionne automatiquement le type " "d'opération comme isolement." -#: flatcamGUI/ObjectUI.py:1263 +#: flatcamGUI/ObjectUI.py:1541 msgid "" "Plot column. It is visible only for MultiGeo geometries, meaning geometries " "that holds the geometry\n" @@ -8155,7 +8611,7 @@ msgstr "" "activer / désactiver le tracé sur le canevas.\n" "pour l'outil correspondant." -#: flatcamGUI/ObjectUI.py:1281 +#: flatcamGUI/ObjectUI.py:1559 msgid "" "The value to offset the cut when \n" "the Offset type selected is 'Offset'.\n" @@ -8167,7 +8623,13 @@ msgstr "" "La valeur peut être positive pour 'dehors'\n" "coupé et négatif pour «à l'intérieur» coupé." -#: flatcamGUI/ObjectUI.py:1306 +#: flatcamGUI/ObjectUI.py:1578 flatcamTools/ToolNCC.py:209 +#: flatcamTools/ToolNCC.py:923 flatcamTools/ToolPaint.py:192 +#: flatcamTools/ToolPaint.py:849 flatcamTools/ToolSolderPaste.py:559 +msgid "New Tool" +msgstr "Nouvel Outil" + +#: flatcamGUI/ObjectUI.py:1595 msgid "" "Add a new tool to the Tool Table\n" "with the specified diameter." @@ -8175,11 +8637,14 @@ msgstr "" "Ajouter un nouvel outil à la table d'outils\n" "avec le diamètre spécifié." -#: flatcamGUI/ObjectUI.py:1314 -msgid "Add Tool from DataBase" -msgstr "Ajouter un outil à partir de la BD" +#: flatcamGUI/ObjectUI.py:1600 flatcamTools/ToolNCC.py:300 +#: flatcamTools/ToolNCC.py:634 flatcamTools/ToolPaint.py:283 +#: flatcamTools/ToolPaint.py:679 +msgid "Add from DB" +msgstr "Ajouter depuis la BD" -#: flatcamGUI/ObjectUI.py:1316 +#: flatcamGUI/ObjectUI.py:1602 flatcamTools/ToolNCC.py:302 +#: flatcamTools/ToolPaint.py:285 msgid "" "Add a new tool to the Tool Table\n" "from the Tool DataBase." @@ -8187,7 +8652,7 @@ msgstr "" "Ajouter un nouvel outil à la table d'outils\n" "à partir de la base de données d'outils." -#: flatcamGUI/ObjectUI.py:1326 +#: flatcamGUI/ObjectUI.py:1617 msgid "" "Copy a selection of tools in the Tool Table\n" "by first selecting a row in the Tool Table." @@ -8195,7 +8660,7 @@ msgstr "" "Copier une sélection d'outils dans la table d'outils\n" "en sélectionnant d'abord une ligne dans la table d'outils." -#: flatcamGUI/ObjectUI.py:1332 +#: flatcamGUI/ObjectUI.py:1623 msgid "" "Delete a selection of tools in the Tool Table\n" "by first selecting a row in the Tool Table." @@ -8203,38 +8668,7 @@ msgstr "" "Supprimer une sélection d'outils dans la table d'outils\n" "en sélectionnant d'abord une ligne dans la table d'outils." -#: flatcamGUI/ObjectUI.py:1356 -msgid "" -"The data used for creating GCode.\n" -"Each tool store it's own set of such data." -msgstr "" -"Les données utilisées pour créer le GCode.\n" -"Chaque outil stocke son propre ensemble de données." - -#: flatcamGUI/ObjectUI.py:1426 flatcamGUI/PreferencesUI.py:3981 -#: flatcamGUI/PreferencesUI.py:5348 flatcamTools/ToolCutOut.py:153 -msgid "Multi-Depth" -msgstr "Multi-profondeur" - -#: flatcamGUI/ObjectUI.py:1429 flatcamGUI/PreferencesUI.py:3984 -#: flatcamGUI/PreferencesUI.py:5351 flatcamTools/ToolCutOut.py:156 -msgid "" -"Use multiple passes to limit\n" -"the cut depth in each pass. Will\n" -"cut multiple times until Cut Z is\n" -"reached." -msgstr "" -"Utilisez plusieurs passes pour limiter\n" -"la profondeur de coupe à chaque passage. Volonté\n" -"couper plusieurs fois jusqu'à ce que Cut Z soit\n" -"atteint." - -#: flatcamGUI/ObjectUI.py:1443 flatcamGUI/PreferencesUI.py:5363 -#: flatcamTools/ToolCutOut.py:170 -msgid "Depth of each pass (positive)." -msgstr "Profondeur de chaque passage (positif)." - -#: flatcamGUI/ObjectUI.py:1454 flatcamGUI/PreferencesUI.py:4016 +#: flatcamGUI/ObjectUI.py:1750 flatcamGUI/PreferencesUI.py:4296 msgid "" "Height of the tool when\n" "moving without cutting." @@ -8242,28 +8676,7 @@ msgstr "" "Hauteur de l'outil quand\n" "se déplacer sans couper." -#: flatcamGUI/ObjectUI.py:1481 flatcamGUI/PreferencesUI.py:4037 -msgid "" -"Include tool-change sequence\n" -"in the Machine Code (Pause for tool change)." -msgstr "" -"Inclure la séquence de changement d'outil\n" -"dans le code machine (pause pour changement d'outil)." - -#: flatcamGUI/ObjectUI.py:1531 flatcamGUI/PreferencesUI.py:4086 -#: flatcamGUI/PreferencesUI.py:6553 flatcamTools/ToolSolderPaste.py:252 -msgid "Feedrate X-Y" -msgstr "Avance X-Y" - -#: flatcamGUI/ObjectUI.py:1533 flatcamGUI/PreferencesUI.py:4088 -msgid "" -"Cutting speed in the XY\n" -"plane in units per minute" -msgstr "" -"Vitesse de coupe dans le XY\n" -"avion en unités par minute" - -#: flatcamGUI/ObjectUI.py:1547 flatcamGUI/PreferencesUI.py:4103 +#: flatcamGUI/ObjectUI.py:1783 flatcamGUI/PreferencesUI.py:4395 msgid "" "Cutting speed in the XY\n" "plane in units per minute.\n" @@ -8273,7 +8686,7 @@ msgstr "" "avion en unités par minute.\n" "Cela s'appelle aussi plonger." -#: flatcamGUI/ObjectUI.py:1562 flatcamGUI/PreferencesUI.py:4212 +#: flatcamGUI/ObjectUI.py:1798 flatcamGUI/PreferencesUI.py:4505 msgid "" "Cutting speed in the XY plane\n" "(in units per minute).\n" @@ -8287,24 +8700,7 @@ msgstr "" "C'est utile seulement pour Marlin,\n" "ignorer pour les autres cas." -#: flatcamGUI/ObjectUI.py:1580 flatcamGUI/PreferencesUI.py:4228 -msgid "Re-cut" -msgstr "Re-coupé" - -#: flatcamGUI/ObjectUI.py:1582 flatcamGUI/ObjectUI.py:1594 -#: flatcamGUI/PreferencesUI.py:4230 flatcamGUI/PreferencesUI.py:4242 -msgid "" -"In order to remove possible\n" -"copper leftovers where first cut\n" -"meet with last cut, we generate an\n" -"extended cut over the first cut section." -msgstr "" -"Afin de supprimer possible\n" -"restes de cuivre où la première coupe\n" -"rencontre avec la dernière coupe, nous générons un\n" -"coupe étendue sur la première section coupée." - -#: flatcamGUI/ObjectUI.py:1606 flatcamGUI/PreferencesUI.py:4120 +#: flatcamGUI/ObjectUI.py:1842 flatcamGUI/PreferencesUI.py:4412 msgid "" "Speed of the spindle in RPM (optional).\n" "If LASER preprocessor is used,\n" @@ -8314,7 +8710,15 @@ msgstr "" "Si le post-processeur LASER est utilisé,\n" "cette valeur est la puissance du laser." -#: flatcamGUI/ObjectUI.py:1642 flatcamGUI/PreferencesUI.py:4157 +#: flatcamGUI/ObjectUI.py:1945 flatcamGUI/PreferencesUI.py:4317 +msgid "" +"Include tool-change sequence\n" +"in the Machine Code (Pause for tool change)." +msgstr "" +"Inclure la séquence de changement d'outil\n" +"dans le code machine (pause pour changement d'outil)." + +#: flatcamGUI/ObjectUI.py:2014 flatcamGUI/PreferencesUI.py:4449 msgid "" "The Preprocessor file that dictates\n" "the Machine Code (like GCode, RML, HPGL) output." @@ -8322,41 +8726,15 @@ msgstr "" "Le fichier post-processeur qui dicte\n" "le code machine (comme GCode, RML, HPGL." -#: flatcamGUI/ObjectUI.py:1689 -msgid "Apply parameters to all tools" -msgstr "Appliquer des paramètres à tous les outils" - -#: flatcamGUI/ObjectUI.py:1691 -msgid "" -"The parameters in the current form will be applied\n" -"on all the tools from the Tool Table." -msgstr "" -"Les paramètres du formulaire actuel seront appliqués\n" -"sur tous les outils de la table d'outils." - -#: flatcamGUI/ObjectUI.py:1700 -msgid "" -"Add at least one tool in the tool-table.\n" -"Click the header to select all, or Ctrl + LMB\n" -"for custom selection of tools." -msgstr "" -"Ajoutez au moins un outil dans la table d'outils.\n" -"Cliquez sur l'en-tête pour tout sélectionner, ou Ctrl + LMB\n" -"pour la sélection personnalisée des outils." - -#: flatcamGUI/ObjectUI.py:1707 -msgid "Generate CNCJob object" -msgstr "Générer un objet CNCJob" - -#: flatcamGUI/ObjectUI.py:1709 +#: flatcamGUI/ObjectUI.py:2035 msgid "Generate the CNC Job object." msgstr "Générez l'objet Travail CNC." -#: flatcamGUI/ObjectUI.py:1726 +#: flatcamGUI/ObjectUI.py:2052 msgid "Launch Paint Tool in Tools Tab." msgstr "Lancer L'outil de Peinture dans l'onglet Outils." -#: flatcamGUI/ObjectUI.py:1734 flatcamGUI/PreferencesUI.py:5524 +#: flatcamGUI/ObjectUI.py:2060 flatcamGUI/PreferencesUI.py:5874 msgid "" "Creates tool paths to cover the\n" "whole area of a polygon (remove\n" @@ -8368,15 +8746,15 @@ msgstr "" "tout en cuivre). Tu vas être interrogé\n" "cliquer sur le polygone désiré." -#: flatcamGUI/ObjectUI.py:1786 +#: flatcamGUI/ObjectUI.py:2115 msgid "CNC Job Object" msgstr "Objet de travail CNC" -#: flatcamGUI/ObjectUI.py:1798 flatcamGUI/PreferencesUI.py:4410 +#: flatcamGUI/ObjectUI.py:2126 flatcamGUI/PreferencesUI.py:4703 msgid "Plot kind" msgstr "Dessiner genre" -#: flatcamGUI/ObjectUI.py:1801 flatcamGUI/PreferencesUI.py:4412 +#: flatcamGUI/ObjectUI.py:2129 flatcamGUI/PreferencesUI.py:4705 msgid "" "This selects the kind of geometries on the canvas to plot.\n" "Those can be either of type 'Travel' which means the moves\n" @@ -8388,15 +8766,15 @@ msgstr "" "au-dessus de la pièce ou il peut être de type 'Couper',\n" "ce qui signifie les mouvements qui coupent dans le matériau." -#: flatcamGUI/ObjectUI.py:1810 flatcamGUI/PreferencesUI.py:4420 +#: flatcamGUI/ObjectUI.py:2138 flatcamGUI/PreferencesUI.py:4713 msgid "Travel" msgstr "Voyage" -#: flatcamGUI/ObjectUI.py:1814 flatcamGUI/PreferencesUI.py:4429 +#: flatcamGUI/ObjectUI.py:2142 flatcamGUI/PreferencesUI.py:4722 msgid "Display Annotation" msgstr "Afficher l'annotation" -#: flatcamGUI/ObjectUI.py:1816 flatcamGUI/PreferencesUI.py:4431 +#: flatcamGUI/ObjectUI.py:2144 flatcamGUI/PreferencesUI.py:4724 msgid "" "This selects if to display text annotation on the plot.\n" "When checked it will display numbers in order for each end\n" @@ -8406,11 +8784,11 @@ msgstr "" "Lorsque coché, il affichera les numéros dans l'ordre pour chaque extrémité\n" "d'une ligne de voyage." -#: flatcamGUI/ObjectUI.py:1831 +#: flatcamGUI/ObjectUI.py:2159 msgid "Travelled dist." msgstr "Dist. parcourue" -#: flatcamGUI/ObjectUI.py:1833 flatcamGUI/ObjectUI.py:1838 +#: flatcamGUI/ObjectUI.py:2161 flatcamGUI/ObjectUI.py:2166 msgid "" "This is the total travelled distance on X-Y plane.\n" "In current units." @@ -8418,11 +8796,11 @@ msgstr "" "C’est la distance totale parcourue sur l’avion X-Y.\n" "En unités actuelles." -#: flatcamGUI/ObjectUI.py:1843 +#: flatcamGUI/ObjectUI.py:2171 msgid "Estimated time" msgstr "Temps estimé" -#: flatcamGUI/ObjectUI.py:1845 flatcamGUI/ObjectUI.py:1850 +#: flatcamGUI/ObjectUI.py:2173 flatcamGUI/ObjectUI.py:2178 msgid "" "This is the estimated time to do the routing/drilling,\n" "without the time spent in ToolChange events." @@ -8430,11 +8808,11 @@ msgstr "" "Ceci est le temps estimé pour faire le routage / forage,\n" "sans le temps passé dans les événements ToolChange." -#: flatcamGUI/ObjectUI.py:1885 +#: flatcamGUI/ObjectUI.py:2213 msgid "CNC Tools Table" msgstr "Table d'outils CNC" -#: flatcamGUI/ObjectUI.py:1888 +#: flatcamGUI/ObjectUI.py:2216 msgid "" "Tools in this CNCJob object used for cutting.\n" "The tool diameter is used for plotting on canvas.\n" @@ -8457,24 +8835,24 @@ msgstr "" "Le 'type d'outil' (TT) peut être circulaire avec 1 à 4 dents (C1..C4),\n" "balle (B) ou en forme de V (V)." -#: flatcamGUI/ObjectUI.py:1916 flatcamGUI/ObjectUI.py:1927 +#: flatcamGUI/ObjectUI.py:2244 flatcamGUI/ObjectUI.py:2255 msgid "P" msgstr "P" -#: flatcamGUI/ObjectUI.py:1937 +#: flatcamGUI/ObjectUI.py:2265 msgid "Update Plot" msgstr "Mise à jour du Tracé" -#: flatcamGUI/ObjectUI.py:1939 +#: flatcamGUI/ObjectUI.py:2267 msgid "Update the plot." msgstr "Mettre à jour le dessin." -#: flatcamGUI/ObjectUI.py:1946 flatcamGUI/PreferencesUI.py:4827 +#: flatcamGUI/ObjectUI.py:2274 flatcamGUI/PreferencesUI.py:5120 msgid "Export CNC Code" msgstr "Exporter le code CNC" -#: flatcamGUI/ObjectUI.py:1948 flatcamGUI/PreferencesUI.py:4768 -#: flatcamGUI/PreferencesUI.py:4829 +#: flatcamGUI/ObjectUI.py:2276 flatcamGUI/PreferencesUI.py:5061 +#: flatcamGUI/PreferencesUI.py:5122 msgid "" "Export and save G-Code to\n" "make this object to a file." @@ -8482,12 +8860,12 @@ msgstr "" "Exporter et sauvegarder le code G dans\n" "transformez cet objet en fichier." -#: flatcamGUI/ObjectUI.py:1954 +#: flatcamGUI/ObjectUI.py:2282 msgid "Prepend to CNC Code" msgstr "Ajouter au début un code CNC" -#: flatcamGUI/ObjectUI.py:1956 flatcamGUI/ObjectUI.py:1963 -#: flatcamGUI/PreferencesUI.py:4784 +#: flatcamGUI/ObjectUI.py:2284 flatcamGUI/ObjectUI.py:2291 +#: flatcamGUI/PreferencesUI.py:5077 msgid "" "Type here any G-Code commands you would\n" "like to add at the beginning of the G-Code file." @@ -8495,12 +8873,12 @@ msgstr "" "Tapez ici toutes les commandes G-Code que vous feriez\n" "souhaite ajouter au début du fichier G-Code." -#: flatcamGUI/ObjectUI.py:1969 +#: flatcamGUI/ObjectUI.py:2297 msgid "Append to CNC Code" msgstr "Ajouter au code CNC final" -#: flatcamGUI/ObjectUI.py:1971 flatcamGUI/ObjectUI.py:1979 -#: flatcamGUI/PreferencesUI.py:4800 +#: flatcamGUI/ObjectUI.py:2299 flatcamGUI/ObjectUI.py:2307 +#: flatcamGUI/PreferencesUI.py:5093 msgid "" "Type here any G-Code commands you would\n" "like to append to the generated file.\n" @@ -8510,11 +8888,11 @@ msgstr "" "tiens à ajouter à la fin du fichier généré.\n" "I.e .: M2 (fin du programme)" -#: flatcamGUI/ObjectUI.py:1993 flatcamGUI/PreferencesUI.py:4835 +#: flatcamGUI/ObjectUI.py:2321 flatcamGUI/PreferencesUI.py:5128 msgid "Toolchange G-Code" msgstr "Code de changement d'outils" -#: flatcamGUI/ObjectUI.py:1996 flatcamGUI/PreferencesUI.py:4838 +#: flatcamGUI/ObjectUI.py:2324 flatcamGUI/PreferencesUI.py:5131 msgid "" "Type here any G-Code commands you would\n" "like to be executed when Toolchange event is encountered.\n" @@ -8536,7 +8914,7 @@ msgstr "" "qui a 'toolchange_custom' dans son nom et qui est construit\n" "ayant comme modèle le fichier posprocessor 'Toolchange Custom'." -#: flatcamGUI/ObjectUI.py:2011 +#: flatcamGUI/ObjectUI.py:2339 msgid "" "Type here any G-Code commands you would\n" "like to be executed when Toolchange event is encountered.\n" @@ -8554,11 +8932,11 @@ msgstr "" "WARNING: it can be used only with a preprocessor file\n" "that has 'toolchange_custom' in it's name." -#: flatcamGUI/ObjectUI.py:2026 flatcamGUI/PreferencesUI.py:4877 +#: flatcamGUI/ObjectUI.py:2354 flatcamGUI/PreferencesUI.py:5170 msgid "Use Toolchange Macro" msgstr "Utiliser la macro Toolchange" -#: flatcamGUI/ObjectUI.py:2028 flatcamGUI/PreferencesUI.py:4879 +#: flatcamGUI/ObjectUI.py:2356 flatcamGUI/PreferencesUI.py:5172 msgid "" "Check this box if you want to use\n" "a Custom Toolchange GCode (macro)." @@ -8566,7 +8944,7 @@ msgstr "" "Cochez cette case si vous souhaitez utiliser\n" "un GCode personnalisé Toolchange (macro)." -#: flatcamGUI/ObjectUI.py:2036 flatcamGUI/PreferencesUI.py:4891 +#: flatcamGUI/ObjectUI.py:2364 flatcamGUI/PreferencesUI.py:5184 msgid "" "A list of the FlatCAM variables that can be used\n" "in the Toolchange event.\n" @@ -8576,74 +8954,76 @@ msgstr "" "dans l'événement Toolchange.\n" "Ils doivent être entourés du symbole '%%'" -#: flatcamGUI/ObjectUI.py:2043 flatcamGUI/PreferencesUI.py:2447 -#: flatcamGUI/PreferencesUI.py:3555 flatcamGUI/PreferencesUI.py:4347 -#: flatcamGUI/PreferencesUI.py:4898 flatcamGUI/PreferencesUI.py:5017 -#: flatcamGUI/PreferencesUI.py:5301 flatcamGUI/PreferencesUI.py:5458 -#: flatcamGUI/PreferencesUI.py:5676 flatcamGUI/PreferencesUI.py:5973 -#: flatcamGUI/PreferencesUI.py:6224 flatcamGUI/PreferencesUI.py:6438 -#: flatcamGUI/PreferencesUI.py:6663 flatcamGUI/PreferencesUI.py:6685 -#: flatcamGUI/PreferencesUI.py:6909 flatcamGUI/PreferencesUI.py:6946 -#: flatcamGUI/PreferencesUI.py:7140 flatcamGUI/PreferencesUI.py:7394 -#: flatcamGUI/PreferencesUI.py:7510 flatcamTools/ToolCopperThieving.py:89 -#: flatcamTools/ToolFiducials.py:149 flatcamTools/ToolNonCopperClear.py:315 +#: flatcamGUI/ObjectUI.py:2371 flatcamGUI/PreferencesUI.py:2627 +#: flatcamGUI/PreferencesUI.py:3833 flatcamGUI/PreferencesUI.py:4640 +#: flatcamGUI/PreferencesUI.py:5191 flatcamGUI/PreferencesUI.py:5310 +#: flatcamGUI/PreferencesUI.py:5640 flatcamGUI/PreferencesUI.py:5797 +#: flatcamGUI/PreferencesUI.py:6164 flatcamGUI/PreferencesUI.py:6461 +#: flatcamGUI/PreferencesUI.py:6711 flatcamGUI/PreferencesUI.py:6942 +#: flatcamGUI/PreferencesUI.py:7169 flatcamGUI/PreferencesUI.py:7191 +#: flatcamGUI/PreferencesUI.py:7415 flatcamGUI/PreferencesUI.py:7452 +#: flatcamGUI/PreferencesUI.py:7646 flatcamGUI/PreferencesUI.py:7900 +#: flatcamGUI/PreferencesUI.py:8016 flatcamGUI/PreferencesUI.py:8135 +#: flatcamGUI/PreferencesUI.py:8347 flatcamGUI/PreferencesUI.py:8556 +#: flatcamTools/ToolCopperThieving.py:90 flatcamTools/ToolFiducials.py:149 +#: flatcamTools/ToolInvertGerber.py:82 msgid "Parameters" msgstr "Paramètres" -#: flatcamGUI/ObjectUI.py:2046 flatcamGUI/PreferencesUI.py:4903 +#: flatcamGUI/ObjectUI.py:2374 flatcamGUI/PreferencesUI.py:5196 msgid "FlatCAM CNC parameters" msgstr "Paramètres CNC FlatCAM" -#: flatcamGUI/ObjectUI.py:2047 flatcamGUI/PreferencesUI.py:4908 +#: flatcamGUI/ObjectUI.py:2375 flatcamGUI/PreferencesUI.py:5201 msgid "tool number" msgstr "numéro d'outil" -#: flatcamGUI/ObjectUI.py:2048 flatcamGUI/PreferencesUI.py:4909 +#: flatcamGUI/ObjectUI.py:2376 flatcamGUI/PreferencesUI.py:5202 msgid "tool diameter" msgstr "diamètre de l'outil" -#: flatcamGUI/ObjectUI.py:2049 flatcamGUI/PreferencesUI.py:4910 +#: flatcamGUI/ObjectUI.py:2377 flatcamGUI/PreferencesUI.py:5203 msgid "for Excellon, total number of drills" msgstr "pour Excellon, nombre total de trous de forage" -#: flatcamGUI/ObjectUI.py:2051 flatcamGUI/PreferencesUI.py:4912 +#: flatcamGUI/ObjectUI.py:2379 flatcamGUI/PreferencesUI.py:5205 msgid "X coord for Toolchange" msgstr "Coord X pour changement d'outil" -#: flatcamGUI/ObjectUI.py:2052 flatcamGUI/PreferencesUI.py:4913 +#: flatcamGUI/ObjectUI.py:2380 flatcamGUI/PreferencesUI.py:5206 msgid "Y coord for Toolchange" msgstr "Coord Y pour changement d'outil" -#: flatcamGUI/ObjectUI.py:2053 flatcamGUI/PreferencesUI.py:4915 +#: flatcamGUI/ObjectUI.py:2381 flatcamGUI/PreferencesUI.py:5208 msgid "Z coord for Toolchange" msgstr "Coords Z pour le Changement d'Outil" -#: flatcamGUI/ObjectUI.py:2054 +#: flatcamGUI/ObjectUI.py:2382 msgid "depth where to cut" msgstr "profondeur où couper" -#: flatcamGUI/ObjectUI.py:2055 +#: flatcamGUI/ObjectUI.py:2383 msgid "height where to travel" msgstr "hauteur où voyager" -#: flatcamGUI/ObjectUI.py:2056 flatcamGUI/PreferencesUI.py:4918 +#: flatcamGUI/ObjectUI.py:2384 flatcamGUI/PreferencesUI.py:5211 msgid "the step value for multidepth cut" msgstr "la valeur de pas pour la coupe multiple" -#: flatcamGUI/ObjectUI.py:2058 flatcamGUI/PreferencesUI.py:4920 +#: flatcamGUI/ObjectUI.py:2386 flatcamGUI/PreferencesUI.py:5213 msgid "the value for the spindle speed" msgstr "la valeur de la vitesse de broche" -#: flatcamGUI/ObjectUI.py:2060 +#: flatcamGUI/ObjectUI.py:2388 msgid "time to dwell to allow the spindle to reach it's set RPM" msgstr "" "temps de repos pour permettre à la broche d'atteindre son régime défini" -#: flatcamGUI/ObjectUI.py:2076 +#: flatcamGUI/ObjectUI.py:2404 msgid "View CNC Code" msgstr "Voir le code CNC" -#: flatcamGUI/ObjectUI.py:2078 +#: flatcamGUI/ObjectUI.py:2406 msgid "" "Opens TAB to view/modify/print G-Code\n" "file." @@ -8651,11 +9031,11 @@ msgstr "" "Ouvre l'onglet pour afficher / modifier / imprimer le code G\n" "fichier." -#: flatcamGUI/ObjectUI.py:2083 +#: flatcamGUI/ObjectUI.py:2411 msgid "Save CNC Code" msgstr "Enregistrer le code CNC" -#: flatcamGUI/ObjectUI.py:2085 +#: flatcamGUI/ObjectUI.py:2413 msgid "" "Opens dialog to save G-Code\n" "file." @@ -8663,85 +9043,81 @@ msgstr "" "Ouvre la boîte de dialogue pour enregistrer le code G\n" "fichier." -#: flatcamGUI/ObjectUI.py:2116 +#: flatcamGUI/ObjectUI.py:2447 msgid "Script Object" msgstr "Objet de script" -#: flatcamGUI/ObjectUI.py:2138 flatcamGUI/ObjectUI.py:2211 +#: flatcamGUI/ObjectUI.py:2467 flatcamGUI/ObjectUI.py:2541 msgid "Auto Completer" msgstr "Compléteur automatique" -#: flatcamGUI/ObjectUI.py:2140 +#: flatcamGUI/ObjectUI.py:2469 msgid "This selects if the auto completer is enabled in the Script Editor." msgstr "" "Ceci sélectionne si le compléteur automatique est activé dans l'éditeur de " "script." -#: flatcamGUI/ObjectUI.py:2182 +#: flatcamGUI/ObjectUI.py:2514 msgid "Document Object" msgstr "Objet de Document" -#: flatcamGUI/ObjectUI.py:2213 +#: flatcamGUI/ObjectUI.py:2543 msgid "This selects if the auto completer is enabled in the Document Editor." msgstr "" "Ceci sélectionne si le compléteur automatique est activé dans l'éditeur de " "document." -#: flatcamGUI/ObjectUI.py:2231 +#: flatcamGUI/ObjectUI.py:2561 msgid "Font Type" msgstr "Type de Police" -#: flatcamGUI/ObjectUI.py:2248 flatcamGUI/PreferencesUI.py:1103 +#: flatcamGUI/ObjectUI.py:2578 flatcamGUI/PreferencesUI.py:1278 msgid "Font Size" msgstr "Taille de Police" -#: flatcamGUI/ObjectUI.py:2284 +#: flatcamGUI/ObjectUI.py:2614 msgid "Alignment" msgstr "Alignement" -#: flatcamGUI/ObjectUI.py:2289 +#: flatcamGUI/ObjectUI.py:2619 msgid "Align Left" msgstr "Alignez à gauche" -#: flatcamGUI/ObjectUI.py:2294 -msgid "Center" -msgstr "Centre" - -#: flatcamGUI/ObjectUI.py:2299 +#: flatcamGUI/ObjectUI.py:2629 msgid "Align Right" msgstr "Aligner à droite" -#: flatcamGUI/ObjectUI.py:2304 +#: flatcamGUI/ObjectUI.py:2634 msgid "Justify" msgstr "Aligner à justifier" -#: flatcamGUI/ObjectUI.py:2311 +#: flatcamGUI/ObjectUI.py:2641 msgid "Font Color" msgstr "Couleur de la Police" -#: flatcamGUI/ObjectUI.py:2313 +#: flatcamGUI/ObjectUI.py:2643 msgid "Set the font color for the selected text" msgstr "Définir la couleur de la police pour le texte sélectionné" -#: flatcamGUI/ObjectUI.py:2327 +#: flatcamGUI/ObjectUI.py:2657 msgid "Selection Color" msgstr "Couleur de sélection" -#: flatcamGUI/ObjectUI.py:2329 +#: flatcamGUI/ObjectUI.py:2659 msgid "Set the selection color when doing text selection." msgstr "Définissez la couleur de sélection lors de la sélection du texte." -#: flatcamGUI/ObjectUI.py:2343 +#: flatcamGUI/ObjectUI.py:2673 msgid "Tab Size" msgstr "Taille de l'onglet" -#: flatcamGUI/ObjectUI.py:2345 +#: flatcamGUI/ObjectUI.py:2675 msgid "Set the tab size. In pixels. Default value is 80 pixels." msgstr "" "Définissez la taille de l'onglet. En pixels. La valeur par défaut est 80 " "pixels." -#: flatcamGUI/PlotCanvasLegacy.py:1254 +#: flatcamGUI/PlotCanvasLegacy.py:1301 msgid "" "Could not annotate due of a difference between the number of text elements " "and the number of text positions." @@ -8749,31 +9125,35 @@ msgstr "" "Impossible d'annoter en raison d'une différence entre le nombre d'éléments " "de texte et le nombre de positions de texte." -#: flatcamGUI/PreferencesUI.py:324 +#: flatcamGUI/PreferencesUI.py:343 msgid "GUI Preferences" msgstr "Préférences de GUI" -#: flatcamGUI/PreferencesUI.py:334 +#: flatcamGUI/PreferencesUI.py:353 msgid "Theme" msgstr "Thème" -#: flatcamGUI/PreferencesUI.py:336 -msgid "Select a theme for FlatCAM." -msgstr "Sélectionnez un thème pour FlatCAM." +#: flatcamGUI/PreferencesUI.py:355 +msgid "" +"Select a theme for FlatCAM.\n" +"It will theme the plot area." +msgstr "" +"Sélectionnez un thème pour FlatCAM.\n" +"Il aura pour thème la zone de traçage." -#: flatcamGUI/PreferencesUI.py:340 +#: flatcamGUI/PreferencesUI.py:360 msgid "Light" msgstr "Lumière" -#: flatcamGUI/PreferencesUI.py:341 +#: flatcamGUI/PreferencesUI.py:361 msgid "Dark" msgstr "Noir" -#: flatcamGUI/PreferencesUI.py:348 +#: flatcamGUI/PreferencesUI.py:368 msgid "Use Gray Icons" msgstr "Utiliser des icônes grises" -#: flatcamGUI/PreferencesUI.py:350 +#: flatcamGUI/PreferencesUI.py:370 msgid "" "Check this box to use a set of icons with\n" "a lighter (gray) color. To be used when a\n" @@ -8783,23 +9163,25 @@ msgstr "" "une couleur plus claire (grise). À utiliser lorsqu'un\n" "le thème sombre complet est appliqué." -#: flatcamGUI/PreferencesUI.py:356 +#: flatcamGUI/PreferencesUI.py:376 msgid "Apply Theme" msgstr "Appliquer le thème" -#: flatcamGUI/PreferencesUI.py:358 +#: flatcamGUI/PreferencesUI.py:378 msgid "" "Select a theme for FlatCAM.\n" +"It will theme the plot area.\n" "The application will restart after change." msgstr "" "Sélectionnez un thème pour FlatCAM.\n" -"L'application va redémarrer après le changement." +"Il aura pour thème la zone de traçage.\n" +"L'application redémarrera après le changement." -#: flatcamGUI/PreferencesUI.py:369 +#: flatcamGUI/PreferencesUI.py:390 msgid "Layout" msgstr "Disposition" -#: flatcamGUI/PreferencesUI.py:371 +#: flatcamGUI/PreferencesUI.py:392 msgid "" "Select an layout for FlatCAM.\n" "It is applied immediately." @@ -8807,11 +9189,11 @@ msgstr "" "Sélectionnez une mise en page pour FlatCAM.\n" "Il est appliqué immédiatement." -#: flatcamGUI/PreferencesUI.py:390 +#: flatcamGUI/PreferencesUI.py:412 msgid "Style" msgstr "Style" -#: flatcamGUI/PreferencesUI.py:392 +#: flatcamGUI/PreferencesUI.py:414 msgid "" "Select an style for FlatCAM.\n" "It will be applied at the next app start." @@ -8819,11 +9201,11 @@ msgstr "" "Sélectionnez un style pour FlatCAM.\n" "Il sera appliqué au prochain démarrage de l'application." -#: flatcamGUI/PreferencesUI.py:406 +#: flatcamGUI/PreferencesUI.py:428 msgid "Activate HDPI Support" msgstr "Activer le support HDPI" -#: flatcamGUI/PreferencesUI.py:408 +#: flatcamGUI/PreferencesUI.py:430 msgid "" "Enable High DPI support for FlatCAM.\n" "It will be applied at the next app start." @@ -8831,11 +9213,11 @@ msgstr "" "Activer la prise en charge haute DPI pour FlatCAM.\n" "Il sera appliqué au prochain démarrage de l'application." -#: flatcamGUI/PreferencesUI.py:422 +#: flatcamGUI/PreferencesUI.py:444 msgid "Display Hover Shape" msgstr "Afficher la forme de survol" -#: flatcamGUI/PreferencesUI.py:424 +#: flatcamGUI/PreferencesUI.py:446 msgid "" "Enable display of a hover shape for FlatCAM objects.\n" "It is displayed whenever the mouse cursor is hovering\n" @@ -8846,11 +9228,11 @@ msgstr "" "stationnaire\n" "sur tout type d'objet non sélectionné." -#: flatcamGUI/PreferencesUI.py:431 +#: flatcamGUI/PreferencesUI.py:453 msgid "Display Selection Shape" msgstr "Afficher la forme de sélection" -#: flatcamGUI/PreferencesUI.py:433 +#: flatcamGUI/PreferencesUI.py:455 msgid "" "Enable the display of a selection shape for FlatCAM objects.\n" "It is displayed whenever the mouse selects an object\n" @@ -8862,29 +9244,29 @@ msgstr "" "soit en cliquant ou en faisant glisser la souris de gauche à droite ou\n" "de droite à gauche." -#: flatcamGUI/PreferencesUI.py:446 +#: flatcamGUI/PreferencesUI.py:468 msgid "Left-Right Selection Color" msgstr "Couleur de sélection gauche-droite" -#: flatcamGUI/PreferencesUI.py:449 flatcamGUI/PreferencesUI.py:515 -#: flatcamGUI/PreferencesUI.py:1882 flatcamGUI/PreferencesUI.py:2903 -#: flatcamGUI/PreferencesUI.py:3894 flatcamGUI/PreferencesUI.py:4534 -#: flatcamGUI/PreferencesUI.py:4600 flatcamTools/ToolRulesCheck.py:179 +#: flatcamGUI/PreferencesUI.py:471 flatcamGUI/PreferencesUI.py:537 +#: flatcamGUI/PreferencesUI.py:2062 flatcamGUI/PreferencesUI.py:3085 +#: flatcamGUI/PreferencesUI.py:4174 flatcamGUI/PreferencesUI.py:4827 +#: flatcamGUI/PreferencesUI.py:4893 flatcamTools/ToolRulesCheck.py:186 msgid "Outline" msgstr "Contour" -#: flatcamGUI/PreferencesUI.py:451 +#: flatcamGUI/PreferencesUI.py:473 msgid "Set the line color for the 'left to right' selection box." msgstr "" "Définissez la couleur de ligne pour la zone de sélection \"gauche à droite\"." -#: flatcamGUI/PreferencesUI.py:465 flatcamGUI/PreferencesUI.py:532 -#: flatcamGUI/PreferencesUI.py:1899 flatcamGUI/PreferencesUI.py:2920 -#: flatcamGUI/PreferencesUI.py:4551 flatcamGUI/PreferencesUI.py:4617 +#: flatcamGUI/PreferencesUI.py:487 flatcamGUI/PreferencesUI.py:554 +#: flatcamGUI/PreferencesUI.py:2079 flatcamGUI/PreferencesUI.py:3102 +#: flatcamGUI/PreferencesUI.py:4844 flatcamGUI/PreferencesUI.py:4910 msgid "Fill" msgstr "Contenu" -#: flatcamGUI/PreferencesUI.py:467 +#: flatcamGUI/PreferencesUI.py:489 msgid "" "Set the fill color for the selection box\n" "in case that the selection is done from left to right.\n" @@ -8896,28 +9278,28 @@ msgstr "" "Les 6 premiers chiffres correspondent à la couleur et les 2 derniers\n" "les chiffres correspondent au niveau alpha (transparence)." -#: flatcamGUI/PreferencesUI.py:485 flatcamGUI/PreferencesUI.py:552 -#: flatcamGUI/PreferencesUI.py:1918 flatcamGUI/PreferencesUI.py:2939 -#: flatcamGUI/PreferencesUI.py:4570 +#: flatcamGUI/PreferencesUI.py:507 flatcamGUI/PreferencesUI.py:574 +#: flatcamGUI/PreferencesUI.py:2098 flatcamGUI/PreferencesUI.py:3121 +#: flatcamGUI/PreferencesUI.py:4863 msgid "Alpha" msgstr "Alpha" -#: flatcamGUI/PreferencesUI.py:487 +#: flatcamGUI/PreferencesUI.py:509 msgid "Set the fill transparency for the 'left to right' selection box." msgstr "" "Définissez la transparence de remplissage pour la zone de sélection \"gauche " "à droite\"." -#: flatcamGUI/PreferencesUI.py:511 +#: flatcamGUI/PreferencesUI.py:533 msgid "Right-Left Selection Color" msgstr "Couleur de sélection droite-gauche" -#: flatcamGUI/PreferencesUI.py:517 +#: flatcamGUI/PreferencesUI.py:539 msgid "Set the line color for the 'right to left' selection box." msgstr "" "Définissez la couleur de ligne pour la zone de sélection «droite à gauche»." -#: flatcamGUI/PreferencesUI.py:534 +#: flatcamGUI/PreferencesUI.py:556 msgid "" "Set the fill color for the selection box\n" "in case that the selection is done from right to left.\n" @@ -8929,46 +9311,46 @@ msgstr "" "Les 6 premiers chiffres correspondent à la couleur et les 2 derniers\n" "les chiffres correspondent au niveau alpha (transparence)." -#: flatcamGUI/PreferencesUI.py:554 +#: flatcamGUI/PreferencesUI.py:576 msgid "Set the fill transparency for selection 'right to left' box." msgstr "" "Définissez la transparence de remplissage pour la zone de sélection \"Droite " "à gauche\"." -#: flatcamGUI/PreferencesUI.py:581 +#: flatcamGUI/PreferencesUI.py:603 msgid "Editor Color" msgstr "Couleur de l'éditeur" -#: flatcamGUI/PreferencesUI.py:585 +#: flatcamGUI/PreferencesUI.py:607 msgid "Drawing" msgstr "Dessin" -#: flatcamGUI/PreferencesUI.py:587 +#: flatcamGUI/PreferencesUI.py:609 msgid "Set the color for the shape." msgstr "Définissez la couleur pour la forme." -#: flatcamGUI/PreferencesUI.py:604 +#: flatcamGUI/PreferencesUI.py:626 msgid "Set the color of the shape when selected." msgstr "Définit la couleur de la forme lorsqu'elle est sélectionnée." -#: flatcamGUI/PreferencesUI.py:627 +#: flatcamGUI/PreferencesUI.py:649 msgid "Project Items Color" msgstr "Éléments du projet Couleur" -#: flatcamGUI/PreferencesUI.py:631 +#: flatcamGUI/PreferencesUI.py:653 msgid "Enabled" msgstr "Activé" -#: flatcamGUI/PreferencesUI.py:633 +#: flatcamGUI/PreferencesUI.py:655 msgid "Set the color of the items in Project Tab Tree." msgstr "" "Définissez la couleur des éléments dans l'arborescence de l'onglet Projet." -#: flatcamGUI/PreferencesUI.py:647 +#: flatcamGUI/PreferencesUI.py:669 msgid "Disabled" msgstr "Désactivé" -#: flatcamGUI/PreferencesUI.py:649 +#: flatcamGUI/PreferencesUI.py:671 msgid "" "Set the color of the items in Project Tab Tree,\n" "for the case when the items are disabled." @@ -8976,7 +9358,11 @@ msgstr "" "Définir la couleur des éléments dans l'arborescence de l'onglet Projet,\n" "pour le cas où les éléments sont désactivés." -#: flatcamGUI/PreferencesUI.py:667 +#: flatcamGUI/PreferencesUI.py:687 +msgid "Project AutoHide" +msgstr "Masquer auto le projet" + +#: flatcamGUI/PreferencesUI.py:689 msgid "" "Check this box if you want the project/selected/tool tab area to\n" "hide automatically when there are no objects loaded and\n" @@ -8987,43 +9373,43 @@ msgstr "" "se cacher automatiquement quand il n'y a pas d'objets chargés et\n" "pour montrer chaque fois qu'un nouvel objet est créé." -#: flatcamGUI/PreferencesUI.py:934 +#: flatcamGUI/PreferencesUI.py:1109 msgid "App Settings" msgstr "Paramètres de l'application" -#: flatcamGUI/PreferencesUI.py:955 +#: flatcamGUI/PreferencesUI.py:1130 msgid "Grid Settings" msgstr "Paramètres de la grille" -#: flatcamGUI/PreferencesUI.py:959 +#: flatcamGUI/PreferencesUI.py:1134 msgid "X value" msgstr "Valeur X" -#: flatcamGUI/PreferencesUI.py:961 +#: flatcamGUI/PreferencesUI.py:1136 msgid "This is the Grid snap value on X axis." msgstr "Il s'agit de la valeur d'accrochage de la grille sur l'axe des X." -#: flatcamGUI/PreferencesUI.py:971 +#: flatcamGUI/PreferencesUI.py:1146 msgid "Y value" msgstr "Valeur Y" -#: flatcamGUI/PreferencesUI.py:973 +#: flatcamGUI/PreferencesUI.py:1148 msgid "This is the Grid snap value on Y axis." msgstr "Il s'agit de la valeur d'accrochage de la grille sur l'axe des Y." -#: flatcamGUI/PreferencesUI.py:983 +#: flatcamGUI/PreferencesUI.py:1158 msgid "Snap Max" msgstr "Accrocher max" -#: flatcamGUI/PreferencesUI.py:998 +#: flatcamGUI/PreferencesUI.py:1173 msgid "Workspace Settings" msgstr "Paramètres de l'espace de travail" -#: flatcamGUI/PreferencesUI.py:1001 +#: flatcamGUI/PreferencesUI.py:1176 msgid "Active" msgstr "Actif" -#: flatcamGUI/PreferencesUI.py:1003 +#: flatcamGUI/PreferencesUI.py:1178 msgid "" "Draw a delimiting rectangle on canvas.\n" "The purpose is to illustrate the limits for our work." @@ -9031,7 +9417,7 @@ msgstr "" "Dessinez un rectangle de délimitation sur la toile.\n" "Le but est d’illustrer les limites de notre travail." -#: flatcamGUI/PreferencesUI.py:1011 +#: flatcamGUI/PreferencesUI.py:1186 msgid "" "Select the type of rectangle to be used on canvas,\n" "as valid workspace." @@ -9039,12 +9425,12 @@ msgstr "" "Sélectionnez le type de rectangle à utiliser sur la toile,\n" "comme espace de travail valide." -#: flatcamGUI/PreferencesUI.py:1077 +#: flatcamGUI/PreferencesUI.py:1252 msgid "Orientation" msgstr "Orientation" -#: flatcamGUI/PreferencesUI.py:1078 flatcamGUI/PreferencesUI.py:5884 -#: flatcamTools/ToolFilm.py:420 +#: flatcamGUI/PreferencesUI.py:1253 flatcamGUI/PreferencesUI.py:6372 +#: flatcamTools/ToolFilm.py:422 msgid "" "Can be:\n" "- Portrait\n" @@ -9054,21 +9440,21 @@ msgstr "" "- Portrait\n" "- Paysage" -#: flatcamGUI/PreferencesUI.py:1082 flatcamGUI/PreferencesUI.py:5888 -#: flatcamTools/ToolFilm.py:424 +#: flatcamGUI/PreferencesUI.py:1257 flatcamGUI/PreferencesUI.py:6376 +#: flatcamTools/ToolFilm.py:426 msgid "Portrait" msgstr "Portrait" -#: flatcamGUI/PreferencesUI.py:1083 flatcamGUI/PreferencesUI.py:5889 -#: flatcamTools/ToolFilm.py:425 +#: flatcamGUI/PreferencesUI.py:1258 flatcamGUI/PreferencesUI.py:6377 +#: flatcamTools/ToolFilm.py:427 msgid "Landscape" msgstr "Paysage" -#: flatcamGUI/PreferencesUI.py:1107 +#: flatcamGUI/PreferencesUI.py:1282 msgid "Notebook" msgstr "Carnet" -#: flatcamGUI/PreferencesUI.py:1109 +#: flatcamGUI/PreferencesUI.py:1284 msgid "" "This sets the font size for the elements found in the Notebook.\n" "The notebook is the collapsible area in the left side of the GUI,\n" @@ -9080,19 +9466,19 @@ msgstr "" "graphique,\n" "et incluez les onglets Projet, Sélectionné et Outil." -#: flatcamGUI/PreferencesUI.py:1128 +#: flatcamGUI/PreferencesUI.py:1303 msgid "Axis" msgstr "Axe" -#: flatcamGUI/PreferencesUI.py:1130 +#: flatcamGUI/PreferencesUI.py:1305 msgid "This sets the font size for canvas axis." msgstr "Ceci définit la taille de la police pour l'axe de la toile." -#: flatcamGUI/PreferencesUI.py:1147 +#: flatcamGUI/PreferencesUI.py:1322 msgid "Textbox" msgstr "Zone de texte" -#: flatcamGUI/PreferencesUI.py:1149 +#: flatcamGUI/PreferencesUI.py:1324 msgid "" "This sets the font size for the Textbox GUI\n" "elements that are used in FlatCAM." @@ -9101,15 +9487,15 @@ msgstr "" "texte\n" "éléments utilisés dans FlatCAM." -#: flatcamGUI/PreferencesUI.py:1175 +#: flatcamGUI/PreferencesUI.py:1350 msgid "Mouse Settings" msgstr "Paramètres de la souris" -#: flatcamGUI/PreferencesUI.py:1179 +#: flatcamGUI/PreferencesUI.py:1354 msgid "Cursor Shape" msgstr "Forme du curseur" -#: flatcamGUI/PreferencesUI.py:1181 +#: flatcamGUI/PreferencesUI.py:1356 msgid "" "Choose a mouse cursor shape.\n" "- Small -> with a customizable size.\n" @@ -9119,47 +9505,47 @@ msgstr "" "- Petit -> avec une taille personnalisable.\n" "- Grand -> Lignes infinies" -#: flatcamGUI/PreferencesUI.py:1187 +#: flatcamGUI/PreferencesUI.py:1362 msgid "Small" msgstr "Petit" -#: flatcamGUI/PreferencesUI.py:1188 +#: flatcamGUI/PreferencesUI.py:1363 msgid "Big" msgstr "Grand" -#: flatcamGUI/PreferencesUI.py:1195 +#: flatcamGUI/PreferencesUI.py:1370 msgid "Cursor Size" msgstr "Taille du curseur" -#: flatcamGUI/PreferencesUI.py:1197 +#: flatcamGUI/PreferencesUI.py:1372 msgid "Set the size of the mouse cursor, in pixels." msgstr "Définissez la taille du curseur de la souris, en pixels." -#: flatcamGUI/PreferencesUI.py:1208 +#: flatcamGUI/PreferencesUI.py:1383 msgid "Cursor Width" msgstr "Largeur du curseur" -#: flatcamGUI/PreferencesUI.py:1210 +#: flatcamGUI/PreferencesUI.py:1385 msgid "Set the line width of the mouse cursor, in pixels." msgstr "Définissez la largeur de ligne du curseur de la souris, en pixels." -#: flatcamGUI/PreferencesUI.py:1221 flatcamGUI/PreferencesUI.py:1228 +#: flatcamGUI/PreferencesUI.py:1396 flatcamGUI/PreferencesUI.py:1403 msgid "Cursor Color" msgstr "Couleur du curseur" -#: flatcamGUI/PreferencesUI.py:1223 +#: flatcamGUI/PreferencesUI.py:1398 msgid "Check this box to color mouse cursor." msgstr "Cochez cette case pour colorer le curseur de la souris." -#: flatcamGUI/PreferencesUI.py:1230 +#: flatcamGUI/PreferencesUI.py:1405 msgid "Set the color of the mouse cursor." msgstr "Définissez la couleur du curseur de la souris." -#: flatcamGUI/PreferencesUI.py:1253 +#: flatcamGUI/PreferencesUI.py:1428 msgid "Pan Button" msgstr "Bouton pan" -#: flatcamGUI/PreferencesUI.py:1255 +#: flatcamGUI/PreferencesUI.py:1430 msgid "" "Select the mouse button to use for panning:\n" "- MMB --> Middle Mouse Button\n" @@ -9169,35 +9555,35 @@ msgstr "" "- MMB -> Bouton central de la souris\n" "- RMB -> bouton droit de la souris" -#: flatcamGUI/PreferencesUI.py:1259 +#: flatcamGUI/PreferencesUI.py:1434 msgid "MMB" msgstr "MMB" -#: flatcamGUI/PreferencesUI.py:1260 +#: flatcamGUI/PreferencesUI.py:1435 msgid "RMB" msgstr "RMB" -#: flatcamGUI/PreferencesUI.py:1266 +#: flatcamGUI/PreferencesUI.py:1441 msgid "Multiple Selection" msgstr "Sélection multiple" -#: flatcamGUI/PreferencesUI.py:1268 +#: flatcamGUI/PreferencesUI.py:1443 msgid "Select the key used for multiple selection." msgstr "Sélectionnez la clé utilisée pour la sélection multiple." -#: flatcamGUI/PreferencesUI.py:1270 +#: flatcamGUI/PreferencesUI.py:1445 msgid "CTRL" msgstr "CTRL" -#: flatcamGUI/PreferencesUI.py:1271 +#: flatcamGUI/PreferencesUI.py:1446 msgid "SHIFT" msgstr "SHIFT" -#: flatcamGUI/PreferencesUI.py:1282 +#: flatcamGUI/PreferencesUI.py:1457 msgid "Delete object confirmation" msgstr "Supprimer la conf. de l'objet" -#: flatcamGUI/PreferencesUI.py:1284 +#: flatcamGUI/PreferencesUI.py:1459 msgid "" "When checked the application will ask for user confirmation\n" "whenever the Delete object(s) event is triggered, either by\n" @@ -9207,11 +9593,11 @@ msgstr "" "chaque fois que l'événement Delete object (s) est déclenché, soit par\n" "raccourci de menu ou raccourci clavier." -#: flatcamGUI/PreferencesUI.py:1291 +#: flatcamGUI/PreferencesUI.py:1466 msgid "\"Open\" behavior" msgstr "Comportement \"ouvert\"" -#: flatcamGUI/PreferencesUI.py:1293 +#: flatcamGUI/PreferencesUI.py:1468 msgid "" "When checked the path for the last saved file is used when saving files,\n" "and the path for the last opened file is used when opening files.\n" @@ -9228,7 +9614,11 @@ msgstr "" "dernier: soit le\n" "chemin pour sauvegarder les fichiers ou chemin pour ouvrir les fichiers." -#: flatcamGUI/PreferencesUI.py:1304 +#: flatcamGUI/PreferencesUI.py:1477 +msgid "Enable ToolTips" +msgstr "Activer les info-bulles" + +#: flatcamGUI/PreferencesUI.py:1479 msgid "" "Check this box if you want to have toolTips displayed\n" "when hovering with mouse over items throughout the App." @@ -9236,11 +9626,11 @@ msgstr "" "Cochez cette case si vous souhaitez afficher les info-bulles\n" "lorsque vous survolez avec la souris sur des éléments dans l’application." -#: flatcamGUI/PreferencesUI.py:1311 +#: flatcamGUI/PreferencesUI.py:1486 msgid "Allow Machinist Unsafe Settings" msgstr "Autoriser les paramètres dangereux du machiniste" -#: flatcamGUI/PreferencesUI.py:1313 +#: flatcamGUI/PreferencesUI.py:1488 msgid "" "If checked, some of the application settings will be allowed\n" "to have values that are usually unsafe to use.\n" @@ -9257,11 +9647,11 @@ msgstr "" "<>: Ne changez rien à moins que vous sachiez ce que vous " "faites !!!" -#: flatcamGUI/PreferencesUI.py:1324 +#: flatcamGUI/PreferencesUI.py:1500 msgid "Bookmarks limit" msgstr "Limite de favoris" -#: flatcamGUI/PreferencesUI.py:1326 +#: flatcamGUI/PreferencesUI.py:1502 msgid "" "The maximum number of bookmarks that may be installed in the menu.\n" "The number of bookmarks in the bookmark manager may be greater\n" @@ -9271,27 +9661,27 @@ msgstr "" "Le nombre de signets dans le gestionnaire de favoris peut être supérieur\n" "mais le menu tiendra seulement beaucoup." -#: flatcamGUI/PreferencesUI.py:1335 +#: flatcamGUI/PreferencesUI.py:1511 msgid "Activity Icon" msgstr "Icône d'activité" -#: flatcamGUI/PreferencesUI.py:1337 +#: flatcamGUI/PreferencesUI.py:1513 msgid "Select the GIF that show activity when FlatCAM is active." msgstr "Sélectionnez le GIF qui affiche l'activité lorsque FlatCAM est actif." -#: flatcamGUI/PreferencesUI.py:1395 +#: flatcamGUI/PreferencesUI.py:1571 msgid "App Preferences" msgstr "Préférences de l'app" -#: flatcamGUI/PreferencesUI.py:1405 flatcamGUI/PreferencesUI.py:1811 -#: flatcamGUI/PreferencesUI.py:2359 flatcamGUI/PreferencesUI.py:2804 -#: flatcamGUI/PreferencesUI.py:3417 flatcamTools/ToolDistance.py:49 -#: flatcamTools/ToolDistanceMin.py:49 flatcamTools/ToolPcbWizard.py:127 -#: flatcamTools/ToolProperties.py:152 +#: flatcamGUI/PreferencesUI.py:1581 flatcamGUI/PreferencesUI.py:1991 +#: flatcamGUI/PreferencesUI.py:2539 flatcamGUI/PreferencesUI.py:2986 +#: flatcamGUI/PreferencesUI.py:3695 flatcamTools/ToolDistance.py:56 +#: flatcamTools/ToolDistanceMin.py:50 flatcamTools/ToolPcbWizard.py:127 +#: flatcamTools/ToolProperties.py:154 msgid "Units" msgstr "Unités" -#: flatcamGUI/PreferencesUI.py:1406 +#: flatcamGUI/PreferencesUI.py:1582 msgid "" "The default value for FlatCAM units.\n" "Whatever is selected here is set every time\n" @@ -9301,22 +9691,22 @@ msgstr "" "Tout ce qui est sélectionné ici est défini à chaque fois\n" "FLatCAM est démarré." -#: flatcamGUI/PreferencesUI.py:1409 flatcamGUI/PreferencesUI.py:1817 -#: flatcamGUI/PreferencesUI.py:2365 flatcamGUI/PreferencesUI.py:2815 -#: flatcamGUI/PreferencesUI.py:3423 flatcamTools/ToolCalculators.py:62 +#: flatcamGUI/PreferencesUI.py:1585 flatcamGUI/PreferencesUI.py:1997 +#: flatcamGUI/PreferencesUI.py:2545 flatcamGUI/PreferencesUI.py:2997 +#: flatcamGUI/PreferencesUI.py:3701 flatcamTools/ToolCalculators.py:62 #: flatcamTools/ToolPcbWizard.py:126 msgid "MM" msgstr "MM" -#: flatcamGUI/PreferencesUI.py:1410 +#: flatcamGUI/PreferencesUI.py:1586 msgid "IN" msgstr "PO" -#: flatcamGUI/PreferencesUI.py:1416 +#: flatcamGUI/PreferencesUI.py:1592 msgid "Precision MM" msgstr "Précision MM" -#: flatcamGUI/PreferencesUI.py:1418 +#: flatcamGUI/PreferencesUI.py:1594 msgid "" "The number of decimals used throughout the application\n" "when the set units are in METRIC system.\n" @@ -9326,11 +9716,11 @@ msgstr "" "lorsque les unités définies sont dans le système METRIC.\n" "Toute modification ici nécessite un redémarrage de l'application." -#: flatcamGUI/PreferencesUI.py:1430 +#: flatcamGUI/PreferencesUI.py:1606 msgid "Precision INCH" msgstr "Précision INCH" -#: flatcamGUI/PreferencesUI.py:1432 +#: flatcamGUI/PreferencesUI.py:1608 msgid "" "The number of decimals used throughout the application\n" "when the set units are in INCH system.\n" @@ -9340,11 +9730,11 @@ msgstr "" "lorsque les unités définies sont dans le système INCH.\n" "Toute modification ici nécessite un redémarrage de l'application." -#: flatcamGUI/PreferencesUI.py:1444 +#: flatcamGUI/PreferencesUI.py:1620 msgid "Graphic Engine" msgstr "Moteur graphique" -#: flatcamGUI/PreferencesUI.py:1445 +#: flatcamGUI/PreferencesUI.py:1621 msgid "" "Choose what graphic engine to use in FlatCAM.\n" "Legacy(2D) -> reduced functionality, slow performance but enhanced " @@ -9364,19 +9754,19 @@ msgstr "" "donc\n" "utilisez le mode Héritage (2D)." -#: flatcamGUI/PreferencesUI.py:1451 +#: flatcamGUI/PreferencesUI.py:1627 msgid "Legacy(2D)" msgstr "Heritage(2D)" -#: flatcamGUI/PreferencesUI.py:1452 +#: flatcamGUI/PreferencesUI.py:1628 msgid "OpenGL(3D)" msgstr "OpenGL(3D)" -#: flatcamGUI/PreferencesUI.py:1464 +#: flatcamGUI/PreferencesUI.py:1640 msgid "APP. LEVEL" msgstr "APP. NIVEAU" -#: flatcamGUI/PreferencesUI.py:1465 +#: flatcamGUI/PreferencesUI.py:1641 msgid "" "Choose the default level of usage for FlatCAM.\n" "BASIC level -> reduced functionality, best for beginner's.\n" @@ -9392,11 +9782,11 @@ msgstr "" "Le choix ici influencera les paramètres dans\n" "l'onglet Sélectionné pour toutes sortes d'objets FlatCAM." -#: flatcamGUI/PreferencesUI.py:1477 +#: flatcamGUI/PreferencesUI.py:1653 msgid "Portable app" msgstr "App. portable" -#: flatcamGUI/PreferencesUI.py:1478 +#: flatcamGUI/PreferencesUI.py:1654 msgid "" "Choose if the application should run as portable.\n" "\n" @@ -9410,19 +9800,19 @@ msgstr "" "ce qui signifie que les fichiers de préférences seront sauvegardés\n" "dans le dossier de l'application, dans le sous-dossier lib\\config." -#: flatcamGUI/PreferencesUI.py:1491 +#: flatcamGUI/PreferencesUI.py:1667 msgid "Languages" msgstr "Langages" -#: flatcamGUI/PreferencesUI.py:1492 +#: flatcamGUI/PreferencesUI.py:1668 msgid "Set the language used throughout FlatCAM." msgstr "Définissez la langue utilisée dans FlatCAM." -#: flatcamGUI/PreferencesUI.py:1498 +#: flatcamGUI/PreferencesUI.py:1674 msgid "Apply Language" msgstr "Appliquer la langue" -#: flatcamGUI/PreferencesUI.py:1499 +#: flatcamGUI/PreferencesUI.py:1675 msgid "" "Set the language used throughout FlatCAM.\n" "The app will restart after click." @@ -9430,32 +9820,32 @@ msgstr "" "Définissez la langue utilisée dans FlatCAM.\n" "L'application redémarrera après un clic." -#: flatcamGUI/PreferencesUI.py:1513 +#: flatcamGUI/PreferencesUI.py:1689 msgid "Startup Settings" msgstr "Paramètres de démarrage" -#: flatcamGUI/PreferencesUI.py:1517 +#: flatcamGUI/PreferencesUI.py:1693 msgid "Splash Screen" msgstr "Écran de démarrage" -#: flatcamGUI/PreferencesUI.py:1519 +#: flatcamGUI/PreferencesUI.py:1695 msgid "Enable display of the splash screen at application startup." msgstr "" "Activer l'affichage de l'écran de démarrage au démarrage de l'application." -#: flatcamGUI/PreferencesUI.py:1531 +#: flatcamGUI/PreferencesUI.py:1707 msgid "Sys Tray Icon" msgstr "Icône Sys Tray" -#: flatcamGUI/PreferencesUI.py:1533 +#: flatcamGUI/PreferencesUI.py:1709 msgid "Enable display of FlatCAM icon in Sys Tray." msgstr "Activer l’affichage de l’icône FlatCAM dans Sys Tray." -#: flatcamGUI/PreferencesUI.py:1538 +#: flatcamGUI/PreferencesUI.py:1714 msgid "Show Shell" msgstr "Afficher la ligne de commande" -#: flatcamGUI/PreferencesUI.py:1540 +#: flatcamGUI/PreferencesUI.py:1716 msgid "" "Check this box if you want the shell to\n" "start automatically at startup." @@ -9463,11 +9853,11 @@ msgstr "" "Cochez cette case si vous voulez que le shell\n" "démarrer automatiquement au démarrage." -#: flatcamGUI/PreferencesUI.py:1547 +#: flatcamGUI/PreferencesUI.py:1723 msgid "Show Project" msgstr "Afficher le projet" -#: flatcamGUI/PreferencesUI.py:1549 +#: flatcamGUI/PreferencesUI.py:1725 msgid "" "Check this box if you want the project/selected/tool tab area to\n" "to be shown automatically at startup." @@ -9476,11 +9866,11 @@ msgstr "" "outil\n" "à afficher automatiquement au démarrage." -#: flatcamGUI/PreferencesUI.py:1555 +#: flatcamGUI/PreferencesUI.py:1731 msgid "Version Check" msgstr "Vérification de version" -#: flatcamGUI/PreferencesUI.py:1557 +#: flatcamGUI/PreferencesUI.py:1733 msgid "" "Check this box if you want to check\n" "for a new version automatically at startup." @@ -9488,11 +9878,11 @@ msgstr "" "Cochez cette case si vous voulez vérifier\n" "pour une nouvelle version automatiquement au démarrage." -#: flatcamGUI/PreferencesUI.py:1564 +#: flatcamGUI/PreferencesUI.py:1740 msgid "Send Statistics" msgstr "Envoyer des statistiques" -#: flatcamGUI/PreferencesUI.py:1566 +#: flatcamGUI/PreferencesUI.py:1742 msgid "" "Check this box if you agree to send anonymous\n" "stats automatically at startup, to help improve FlatCAM." @@ -9500,11 +9890,11 @@ msgstr "" "Cochez cette case si vous acceptez d'envoyer un message anonyme\n" "stats automatiquement au démarrage, pour aider à améliorer FlatCAM." -#: flatcamGUI/PreferencesUI.py:1580 +#: flatcamGUI/PreferencesUI.py:1756 msgid "Workers number" msgstr "No de travailleurs" -#: flatcamGUI/PreferencesUI.py:1582 flatcamGUI/PreferencesUI.py:1591 +#: flatcamGUI/PreferencesUI.py:1758 msgid "" "The number of Qthreads made available to the App.\n" "A bigger number may finish the jobs more quickly but\n" @@ -9520,35 +9910,35 @@ msgstr "" "La valeur par défaut est 2.\n" "Après modification, il sera appliqué au prochain démarrage de l'application." -#: flatcamGUI/PreferencesUI.py:1604 +#: flatcamGUI/PreferencesUI.py:1772 msgid "Geo Tolerance" msgstr "Géo Tolérance" -#: flatcamGUI/PreferencesUI.py:1606 flatcamGUI/PreferencesUI.py:1615 +#: flatcamGUI/PreferencesUI.py:1774 msgid "" "This value can counter the effect of the Circle Steps\n" -"parameter. Default value is 0.01.\n" +"parameter. Default value is 0.005.\n" "A lower value will increase the detail both in image\n" "and in Gcode for the circles, with a higher cost in\n" "performance. Higher value will provide more\n" "performance at the expense of level of detail." msgstr "" "Cette valeur peut contrer l’effet des Pas de cercle.\n" -"paramètre. La valeur par défaut est 0.01.\n" +"paramètre. La valeur par défaut est 0.005.\n" "Une valeur inférieure augmentera le détail à la fois dans l'image\n" "et en Gcode pour les cercles, avec un coût plus élevé en\n" "performance. Une valeur plus élevée fournira plus\n" "performance au détriment du niveau de détail." -#: flatcamGUI/PreferencesUI.py:1634 +#: flatcamGUI/PreferencesUI.py:1794 msgid "Save Settings" msgstr "Paramètres d'enregistrement" -#: flatcamGUI/PreferencesUI.py:1638 +#: flatcamGUI/PreferencesUI.py:1798 msgid "Save Compressed Project" msgstr "Enregistrer le projet compressé" -#: flatcamGUI/PreferencesUI.py:1640 +#: flatcamGUI/PreferencesUI.py:1800 msgid "" "Whether to save a compressed or uncompressed project.\n" "When checked it will save a compressed FlatCAM project." @@ -9556,11 +9946,11 @@ msgstr "" "Que ce soit pour sauvegarder un projet compressé ou non compressé.\n" "Lorsque coché, un projet FlatCAM compressé sera enregistré." -#: flatcamGUI/PreferencesUI.py:1649 +#: flatcamGUI/PreferencesUI.py:1809 msgid "Compression" msgstr "Compression" -#: flatcamGUI/PreferencesUI.py:1651 +#: flatcamGUI/PreferencesUI.py:1811 msgid "" "The level of compression used when saving\n" "a FlatCAM project. Higher value means better compression\n" @@ -9571,62 +9961,93 @@ msgstr "" "compression\n" "mais nécessitent plus d’utilisation de RAM et plus de temps de traitement." -#: flatcamGUI/PreferencesUI.py:1671 +#: flatcamGUI/PreferencesUI.py:1822 +msgid "Enable Auto Save" +msgstr "Activer l'enregistrement auto" + +#: flatcamGUI/PreferencesUI.py:1824 +msgid "" +"Check to enable the autosave feature.\n" +"When enabled, the application will try to save a project\n" +"at the set interval." +msgstr "" +"Cochez pour activer la fonction d'enregistrement automatique.\n" +"Lorsqu'elle est activée, l'application essaiera d'enregistrer un projet\n" +"à l'intervalle défini." + +#: flatcamGUI/PreferencesUI.py:1834 +msgid "Interval" +msgstr "Intervalle" + +#: flatcamGUI/PreferencesUI.py:1836 +msgid "" +"Time interval for autosaving. In milliseconds.\n" +"The application will try to save periodically but only\n" +"if the project was saved manually at least once.\n" +"While active, some operations may block this feature." +msgstr "" +"Intervalle de temps pour l'enregistrement automatique. En millisecondes.\n" +"L'application essaiera de sauvegarder périodiquement mais seulement\n" +"si le projet a été enregistré manuellement au moins une fois.\n" +"Lorsqu'elles sont actives, certaines opérations peuvent bloquer cette " +"fonctionnalité." + +#: flatcamGUI/PreferencesUI.py:1852 msgid "Text to PDF parameters" msgstr "Paramètres texte en PDF" -#: flatcamGUI/PreferencesUI.py:1673 +#: flatcamGUI/PreferencesUI.py:1854 msgid "Used when saving text in Code Editor or in FlatCAM Document objects." msgstr "" "Utilisé lors de l'enregistrement de texte dans l'éditeur de code ou dans des " "objets de document FlatCAM." -#: flatcamGUI/PreferencesUI.py:1682 +#: flatcamGUI/PreferencesUI.py:1863 msgid "Top Margin" msgstr "Marge supérieure" -#: flatcamGUI/PreferencesUI.py:1684 +#: flatcamGUI/PreferencesUI.py:1865 msgid "Distance between text body and the top of the PDF file." msgstr "Distance entre le corps du texte et le haut du fichier PDF." -#: flatcamGUI/PreferencesUI.py:1695 +#: flatcamGUI/PreferencesUI.py:1876 msgid "Bottom Margin" msgstr "Marge inférieure" -#: flatcamGUI/PreferencesUI.py:1697 +#: flatcamGUI/PreferencesUI.py:1878 msgid "Distance between text body and the bottom of the PDF file." msgstr "Distance entre le corps du texte et le bas du fichier PDF." -#: flatcamGUI/PreferencesUI.py:1708 +#: flatcamGUI/PreferencesUI.py:1889 msgid "Left Margin" msgstr "Marge de gauche" -#: flatcamGUI/PreferencesUI.py:1710 +#: flatcamGUI/PreferencesUI.py:1891 msgid "Distance between text body and the left of the PDF file." msgstr "Distance entre le corps du texte et la gauche du fichier PDF." -#: flatcamGUI/PreferencesUI.py:1721 +#: flatcamGUI/PreferencesUI.py:1902 msgid "Right Margin" msgstr "Marge droite" -#: flatcamGUI/PreferencesUI.py:1723 +#: flatcamGUI/PreferencesUI.py:1904 msgid "Distance between text body and the right of the PDF file." msgstr "Distance entre le corps du texte et la droite du fichier PDF." -#: flatcamGUI/PreferencesUI.py:1756 +#: flatcamGUI/PreferencesUI.py:1936 msgid "Gerber General" msgstr "Gerber Général" -#: flatcamGUI/PreferencesUI.py:1774 +#: flatcamGUI/PreferencesUI.py:1954 msgid "M-Color" msgstr "Couleur-M" -#: flatcamGUI/PreferencesUI.py:1788 flatcamGUI/PreferencesUI.py:3859 -#: flatcamGUI/PreferencesUI.py:4442 flatcamGUI/PreferencesUI.py:7148 +#: flatcamGUI/PreferencesUI.py:1968 flatcamGUI/PreferencesUI.py:4137 +#: flatcamGUI/PreferencesUI.py:4735 flatcamGUI/PreferencesUI.py:7654 msgid "Circle Steps" msgstr "Étapes de cercle" -#: flatcamGUI/PreferencesUI.py:1790 +#: flatcamGUI/PreferencesUI.py:1970 msgid "" "The number of circle steps for Gerber \n" "circular aperture linear approximation." @@ -9634,11 +10055,11 @@ msgstr "" "Le nombre d'étapes du cercle pour Gerber\n" "approximation linéaire ouverture circulaire." -#: flatcamGUI/PreferencesUI.py:1802 +#: flatcamGUI/PreferencesUI.py:1982 msgid "Default Values" msgstr "Défauts" -#: flatcamGUI/PreferencesUI.py:1804 +#: flatcamGUI/PreferencesUI.py:1984 msgid "" "Those values will be used as fallback values\n" "in case that they are not found in the Gerber file." @@ -9646,25 +10067,25 @@ msgstr "" "Ces valeurs seront utilisées comme valeurs de secours\n" "au cas où ils ne seraient pas trouvés dans le fichier Gerber." -#: flatcamGUI/PreferencesUI.py:1813 flatcamGUI/PreferencesUI.py:1819 -#: flatcamGUI/PreferencesUI.py:2361 flatcamGUI/PreferencesUI.py:2367 +#: flatcamGUI/PreferencesUI.py:1993 flatcamGUI/PreferencesUI.py:1999 +#: flatcamGUI/PreferencesUI.py:2541 flatcamGUI/PreferencesUI.py:2547 msgid "The units used in the Gerber file." msgstr "Les unités utilisées dans le fichier Gerber." -#: flatcamGUI/PreferencesUI.py:1816 flatcamGUI/PreferencesUI.py:2364 -#: flatcamGUI/PreferencesUI.py:2728 flatcamGUI/PreferencesUI.py:2814 -#: flatcamGUI/PreferencesUI.py:3422 flatcamTools/ToolCalculators.py:61 +#: flatcamGUI/PreferencesUI.py:1996 flatcamGUI/PreferencesUI.py:2544 +#: flatcamGUI/PreferencesUI.py:2910 flatcamGUI/PreferencesUI.py:2996 +#: flatcamGUI/PreferencesUI.py:3700 flatcamTools/ToolCalculators.py:61 #: flatcamTools/ToolPcbWizard.py:125 msgid "INCH" msgstr "PO" -#: flatcamGUI/PreferencesUI.py:1826 flatcamGUI/PreferencesUI.py:2413 -#: flatcamGUI/PreferencesUI.py:2786 flatcamGUI/PreferencesUI.py:3490 +#: flatcamGUI/PreferencesUI.py:2006 flatcamGUI/PreferencesUI.py:2593 +#: flatcamGUI/PreferencesUI.py:2968 flatcamGUI/PreferencesUI.py:3768 msgid "Zeros" msgstr "Zéros" -#: flatcamGUI/PreferencesUI.py:1829 flatcamGUI/PreferencesUI.py:1839 -#: flatcamGUI/PreferencesUI.py:2416 flatcamGUI/PreferencesUI.py:2426 +#: flatcamGUI/PreferencesUI.py:2009 flatcamGUI/PreferencesUI.py:2019 +#: flatcamGUI/PreferencesUI.py:2596 flatcamGUI/PreferencesUI.py:2606 msgid "" "This sets the type of Gerber zeros.\n" "If LZ then Leading Zeros are removed and\n" @@ -9678,23 +10099,23 @@ msgstr "" "Si TZ est coché, les zéros de fin sont supprimés\n" "et les principaux zéros sont conservés." -#: flatcamGUI/PreferencesUI.py:1836 flatcamGUI/PreferencesUI.py:2423 -#: flatcamGUI/PreferencesUI.py:2799 flatcamGUI/PreferencesUI.py:3500 +#: flatcamGUI/PreferencesUI.py:2016 flatcamGUI/PreferencesUI.py:2603 +#: flatcamGUI/PreferencesUI.py:2981 flatcamGUI/PreferencesUI.py:3778 #: flatcamTools/ToolPcbWizard.py:111 msgid "LZ" msgstr "LZ" -#: flatcamGUI/PreferencesUI.py:1837 flatcamGUI/PreferencesUI.py:2424 -#: flatcamGUI/PreferencesUI.py:2800 flatcamGUI/PreferencesUI.py:3501 +#: flatcamGUI/PreferencesUI.py:2017 flatcamGUI/PreferencesUI.py:2604 +#: flatcamGUI/PreferencesUI.py:2982 flatcamGUI/PreferencesUI.py:3779 #: flatcamTools/ToolPcbWizard.py:112 msgid "TZ" msgstr "TZ" -#: flatcamGUI/PreferencesUI.py:1855 +#: flatcamGUI/PreferencesUI.py:2035 msgid "Clean Apertures" msgstr "Ouvertures propres" -#: flatcamGUI/PreferencesUI.py:1857 +#: flatcamGUI/PreferencesUI.py:2037 msgid "" "Will remove apertures that do not have geometry\n" "thus lowering the number of apertures in the Gerber object." @@ -9702,11 +10123,11 @@ msgstr "" "Supprime les ouvertures qui n'ont pas de géométrie\n" "abaissant ainsi le nombre d'ouvertures dans l'objet Gerber." -#: flatcamGUI/PreferencesUI.py:1863 +#: flatcamGUI/PreferencesUI.py:2043 msgid "Polarity change buffer" msgstr "Tampon de changement de polarité" -#: flatcamGUI/PreferencesUI.py:1865 +#: flatcamGUI/PreferencesUI.py:2045 msgid "" "Will apply extra buffering for the\n" "solid geometry when we have polarity changes.\n" @@ -9718,17 +10139,17 @@ msgstr "" "Peut aider à charger des fichiers Gerber qui autrement\n" "ne se charge pas correctement." -#: flatcamGUI/PreferencesUI.py:1878 +#: flatcamGUI/PreferencesUI.py:2058 msgid "Gerber Object Color" msgstr "Couleur d'objet Gerber" -#: flatcamGUI/PreferencesUI.py:1884 flatcamGUI/PreferencesUI.py:2905 -#: flatcamGUI/PreferencesUI.py:3896 +#: flatcamGUI/PreferencesUI.py:2064 flatcamGUI/PreferencesUI.py:3087 +#: flatcamGUI/PreferencesUI.py:4176 msgid "Set the line color for plotted objects." msgstr "Définissez la couleur de trait pour les objets tracés." -#: flatcamGUI/PreferencesUI.py:1901 flatcamGUI/PreferencesUI.py:2922 -#: flatcamGUI/PreferencesUI.py:4553 flatcamGUI/PreferencesUI.py:4619 +#: flatcamGUI/PreferencesUI.py:2081 flatcamGUI/PreferencesUI.py:3104 +#: flatcamGUI/PreferencesUI.py:4846 flatcamGUI/PreferencesUI.py:4912 msgid "" "Set the fill color for plotted objects.\n" "First 6 digits are the color and the last 2\n" @@ -9738,34 +10159,29 @@ msgstr "" "Les 6 premiers chiffres correspondent à la couleur et les 2 derniers\n" "les chiffres correspondent au niveau alpha (transparence)." -#: flatcamGUI/PreferencesUI.py:1920 flatcamGUI/PreferencesUI.py:2941 -#: flatcamGUI/PreferencesUI.py:4572 +#: flatcamGUI/PreferencesUI.py:2100 flatcamGUI/PreferencesUI.py:3123 +#: flatcamGUI/PreferencesUI.py:4865 msgid "Set the fill transparency for plotted objects." msgstr "Définissez la transparence de remplissage pour les objets tracés." -#: flatcamGUI/PreferencesUI.py:2011 +#: flatcamGUI/PreferencesUI.py:2191 msgid "Gerber Options" msgstr "Options de Gerber" -#: flatcamGUI/PreferencesUI.py:2085 flatcamGUI/PreferencesUI.py:4379 -#: flatcamGUI/PreferencesUI.py:5120 flatcamTools/ToolNonCopperClear.py:170 -msgid "Conv." -msgstr "Conv." - -#: flatcamGUI/PreferencesUI.py:2089 +#: flatcamGUI/PreferencesUI.py:2269 msgid "Combine Passes" msgstr "Combiner les passes" -#: flatcamGUI/PreferencesUI.py:2177 +#: flatcamGUI/PreferencesUI.py:2357 msgid "Gerber Adv. Options" msgstr "Options avancées Gerber" -#: flatcamGUI/PreferencesUI.py:2181 flatcamGUI/PreferencesUI.py:3278 -#: flatcamGUI/PreferencesUI.py:4179 +#: flatcamGUI/PreferencesUI.py:2361 flatcamGUI/PreferencesUI.py:3551 +#: flatcamGUI/PreferencesUI.py:4472 msgid "Advanced Options" msgstr "Options avancées" -#: flatcamGUI/PreferencesUI.py:2183 +#: flatcamGUI/PreferencesUI.py:2363 msgid "" "A list of Gerber advanced parameters.\n" "Those parameters are available only for\n" @@ -9775,11 +10191,11 @@ msgstr "" "Ces paramètres ne sont disponibles que pour\n" "App avancée. Niveau." -#: flatcamGUI/PreferencesUI.py:2202 +#: flatcamGUI/PreferencesUI.py:2382 msgid "Table Show/Hide" msgstr "Tableau Afficher/Masquer" -#: flatcamGUI/PreferencesUI.py:2204 +#: flatcamGUI/PreferencesUI.py:2384 msgid "" "Toggle the display of the Gerber Apertures Table.\n" "Also, on hide, it will delete all mark shapes\n" @@ -9789,15 +10205,15 @@ msgstr "" "En outre, sur cacher, il va supprimer toutes les formes de marque\n" "qui sont dessinés sur une toile." -#: flatcamGUI/PreferencesUI.py:2284 +#: flatcamGUI/PreferencesUI.py:2464 msgid "Exterior" msgstr "Extérieur" -#: flatcamGUI/PreferencesUI.py:2285 +#: flatcamGUI/PreferencesUI.py:2465 msgid "Interior" msgstr "Intérieur" -#: flatcamGUI/PreferencesUI.py:2298 +#: flatcamGUI/PreferencesUI.py:2478 msgid "" "Buffering type:\n" "- None --> best performance, fast file loading but no so good display\n" @@ -9811,19 +10227,19 @@ msgstr "" "par défaut.\n" "<< AVERTISSEMENT >>: Ne changez cela que si vous savez ce que vous faites !!!" -#: flatcamGUI/PreferencesUI.py:2303 flatcamGUI/PreferencesUI.py:5852 -#: flatcamGUI/PreferencesUI.py:7446 flatcamTools/ToolFiducials.py:201 -#: flatcamTools/ToolFilm.py:255 flatcamTools/ToolProperties.py:411 -#: flatcamTools/ToolProperties.py:426 flatcamTools/ToolProperties.py:429 -#: flatcamTools/ToolProperties.py:432 flatcamTools/ToolProperties.py:456 +#: flatcamGUI/PreferencesUI.py:2483 flatcamGUI/PreferencesUI.py:6340 +#: flatcamGUI/PreferencesUI.py:7952 flatcamTools/ToolFiducials.py:201 +#: flatcamTools/ToolFilm.py:255 flatcamTools/ToolProperties.py:452 +#: flatcamTools/ToolProperties.py:455 flatcamTools/ToolProperties.py:458 +#: flatcamTools/ToolProperties.py:483 msgid "None" msgstr "Aucun" -#: flatcamGUI/PreferencesUI.py:2309 +#: flatcamGUI/PreferencesUI.py:2489 msgid "Simplify" msgstr "Simplifier" -#: flatcamGUI/PreferencesUI.py:2311 +#: flatcamGUI/PreferencesUI.py:2491 msgid "" "When checked all the Gerber polygons will be\n" "loaded with simplification having a set tolerance.\n" @@ -9833,23 +10249,23 @@ msgstr "" "chargé de simplification ayant une tolérance définie.\n" "<< AVERTISSEMENT >>: Ne changez cela que si vous savez ce que vous faites !!!" -#: flatcamGUI/PreferencesUI.py:2318 +#: flatcamGUI/PreferencesUI.py:2498 msgid "Tolerance" msgstr "Tolérance" -#: flatcamGUI/PreferencesUI.py:2319 +#: flatcamGUI/PreferencesUI.py:2499 msgid "Tolerance for polygon simplification." msgstr "Tolérance pour la simplification des polygones." -#: flatcamGUI/PreferencesUI.py:2344 +#: flatcamGUI/PreferencesUI.py:2524 msgid "Gerber Export" msgstr "Gerber exportation" -#: flatcamGUI/PreferencesUI.py:2348 flatcamGUI/PreferencesUI.py:3406 +#: flatcamGUI/PreferencesUI.py:2528 flatcamGUI/PreferencesUI.py:3684 msgid "Export Options" msgstr "Options d'exportation" -#: flatcamGUI/PreferencesUI.py:2350 +#: flatcamGUI/PreferencesUI.py:2530 msgid "" "The parameters set here are used in the file exported\n" "when using the File -> Export -> Export Gerber menu entry." @@ -9858,11 +10274,11 @@ msgstr "" "lors de l'utilisation de l'entrée de menu Fichier -> Exporter -> Exporter " "Gerber." -#: flatcamGUI/PreferencesUI.py:2373 flatcamGUI/PreferencesUI.py:3431 +#: flatcamGUI/PreferencesUI.py:2553 flatcamGUI/PreferencesUI.py:3709 msgid "Int/Decimals" msgstr "Entiers/Décim" -#: flatcamGUI/PreferencesUI.py:2375 +#: flatcamGUI/PreferencesUI.py:2555 msgid "" "The number of digits in the whole part of the number\n" "and in the fractional part of the number." @@ -9870,7 +10286,7 @@ msgstr "" "Le nombre de chiffres dans la partie entière du numéro\n" "et dans la fraction du nombre." -#: flatcamGUI/PreferencesUI.py:2388 +#: flatcamGUI/PreferencesUI.py:2568 msgid "" "This numbers signify the number of digits in\n" "the whole part of Gerber coordinates." @@ -9878,7 +10294,7 @@ msgstr "" "Ces chiffres représentent le nombre de chiffres en\n" "toute la partie des coordonnées de Gerber." -#: flatcamGUI/PreferencesUI.py:2404 +#: flatcamGUI/PreferencesUI.py:2584 msgid "" "This numbers signify the number of digits in\n" "the decimal part of Gerber coordinates." @@ -9886,16 +10302,16 @@ msgstr "" "Ces chiffres représentent le nombre de chiffres en\n" "la partie décimale des coordonnées de Gerber." -#: flatcamGUI/PreferencesUI.py:2449 +#: flatcamGUI/PreferencesUI.py:2629 msgid "A list of Gerber Editor parameters." msgstr "Une liste de paramètres de l'éditeur Gerber." -#: flatcamGUI/PreferencesUI.py:2457 flatcamGUI/PreferencesUI.py:3565 -#: flatcamGUI/PreferencesUI.py:4357 flatcamGUI/PreferencesUI.py:7109 +#: flatcamGUI/PreferencesUI.py:2637 flatcamGUI/PreferencesUI.py:3843 +#: flatcamGUI/PreferencesUI.py:4650 flatcamGUI/PreferencesUI.py:7615 msgid "Selection limit" msgstr "Limite de sélection" -#: flatcamGUI/PreferencesUI.py:2459 +#: flatcamGUI/PreferencesUI.py:2639 msgid "" "Set the number of selected Gerber geometry\n" "items above which the utility geometry\n" @@ -9909,23 +10325,23 @@ msgstr "" "Augmente les performances lors du déplacement d'un\n" "grand nombre d'éléments géométriques." -#: flatcamGUI/PreferencesUI.py:2472 +#: flatcamGUI/PreferencesUI.py:2652 msgid "New Aperture code" msgstr "Nouveau code d'ouverture" -#: flatcamGUI/PreferencesUI.py:2485 +#: flatcamGUI/PreferencesUI.py:2665 msgid "New Aperture size" msgstr "Nouvelle taille d'ouverture" -#: flatcamGUI/PreferencesUI.py:2487 +#: flatcamGUI/PreferencesUI.py:2667 msgid "Size for the new aperture" msgstr "Taille pour la nouvelle ouverture" -#: flatcamGUI/PreferencesUI.py:2498 +#: flatcamGUI/PreferencesUI.py:2678 msgid "New Aperture type" msgstr "Nouveau type d'ouverture" -#: flatcamGUI/PreferencesUI.py:2500 +#: flatcamGUI/PreferencesUI.py:2680 msgid "" "Type for the new aperture.\n" "Can be 'C', 'R' or 'O'." @@ -9933,35 +10349,42 @@ msgstr "" "Tapez pour la nouvelle ouverture.\n" "Peut être 'C', 'R' ou 'O'." -#: flatcamGUI/PreferencesUI.py:2522 +#: flatcamGUI/PreferencesUI.py:2702 msgid "Aperture Dimensions" msgstr "Dimensions d'ouverture" -#: flatcamGUI/PreferencesUI.py:2524 flatcamGUI/PreferencesUI.py:3877 -#: flatcamGUI/PreferencesUI.py:5029 -msgid "Diameters of the cutting tools, separated by ','" -msgstr "Diamètres des outils de coupe, séparés par ','" +#: flatcamGUI/PreferencesUI.py:2704 flatcamGUI/PreferencesUI.py:4155 +#: flatcamGUI/PreferencesUI.py:5322 flatcamGUI/PreferencesUI.py:5889 +#: flatcamGUI/PreferencesUI.py:6955 +msgid "" +"Diameters of the tools, separated by comma.\n" +"The value of the diameter has to use the dot decimals separator.\n" +"Valid values: 0.3, 1.0" +msgstr "" +"Diamètres des outils, séparés par une virgule.\n" +"La valeur du diamètre doit utiliser le séparateur de décimales de points.\n" +"Valeurs valides: 0,3, 1,0" -#: flatcamGUI/PreferencesUI.py:2530 +#: flatcamGUI/PreferencesUI.py:2712 msgid "Linear Pad Array" msgstr "Tableau de Pad Linéaire" -#: flatcamGUI/PreferencesUI.py:2534 flatcamGUI/PreferencesUI.py:3609 -#: flatcamGUI/PreferencesUI.py:3757 +#: flatcamGUI/PreferencesUI.py:2716 flatcamGUI/PreferencesUI.py:3887 +#: flatcamGUI/PreferencesUI.py:4035 msgid "Linear Direction" msgstr "Direction linéaire" -#: flatcamGUI/PreferencesUI.py:2574 +#: flatcamGUI/PreferencesUI.py:2756 msgid "Circular Pad Array" msgstr "Tableau de Pad Circulaire" -#: flatcamGUI/PreferencesUI.py:2578 flatcamGUI/PreferencesUI.py:3655 -#: flatcamGUI/PreferencesUI.py:3805 +#: flatcamGUI/PreferencesUI.py:2760 flatcamGUI/PreferencesUI.py:3933 +#: flatcamGUI/PreferencesUI.py:4083 msgid "Circular Direction" msgstr "Direction circulaire" -#: flatcamGUI/PreferencesUI.py:2580 flatcamGUI/PreferencesUI.py:3657 -#: flatcamGUI/PreferencesUI.py:3807 +#: flatcamGUI/PreferencesUI.py:2762 flatcamGUI/PreferencesUI.py:3935 +#: flatcamGUI/PreferencesUI.py:4085 msgid "" "Direction for circular array.\n" "Can be CW = clockwise or CCW = counter clockwise." @@ -9969,48 +10392,48 @@ msgstr "" "Direction pour tableau circulaire.\n" "Peut être CW = sens horaire ou CCW = sens antihoraire." -#: flatcamGUI/PreferencesUI.py:2591 flatcamGUI/PreferencesUI.py:3668 -#: flatcamGUI/PreferencesUI.py:3818 +#: flatcamGUI/PreferencesUI.py:2773 flatcamGUI/PreferencesUI.py:3946 +#: flatcamGUI/PreferencesUI.py:4096 msgid "Circular Angle" msgstr "Angle Circulaire" -#: flatcamGUI/PreferencesUI.py:2610 +#: flatcamGUI/PreferencesUI.py:2792 msgid "Distance at which to buffer the Gerber element." msgstr "Distance à laquelle tamponner l'élément de Gerber." -#: flatcamGUI/PreferencesUI.py:2619 +#: flatcamGUI/PreferencesUI.py:2801 msgid "Scale Tool" msgstr "Outil d'échelle" -#: flatcamGUI/PreferencesUI.py:2625 +#: flatcamGUI/PreferencesUI.py:2807 msgid "Factor to scale the Gerber element." msgstr "Facteur d'échelle de l'élément de Gerber." -#: flatcamGUI/PreferencesUI.py:2638 +#: flatcamGUI/PreferencesUI.py:2820 msgid "Threshold low" msgstr "Seuil bas" -#: flatcamGUI/PreferencesUI.py:2640 +#: flatcamGUI/PreferencesUI.py:2822 msgid "Threshold value under which the apertures are not marked." msgstr "Valeur seuil sous laquelle les ouvertures ne sont pas marquées." -#: flatcamGUI/PreferencesUI.py:2650 +#: flatcamGUI/PreferencesUI.py:2832 msgid "Threshold high" msgstr "Seuil haut" -#: flatcamGUI/PreferencesUI.py:2652 +#: flatcamGUI/PreferencesUI.py:2834 msgid "Threshold value over which the apertures are not marked." msgstr "Valeur seuil sur laquelle les ouvertures ne sont pas marquées." -#: flatcamGUI/PreferencesUI.py:2670 +#: flatcamGUI/PreferencesUI.py:2852 msgid "Excellon General" msgstr "Excellon Général" -#: flatcamGUI/PreferencesUI.py:2703 +#: flatcamGUI/PreferencesUI.py:2885 msgid "Excellon Format" msgstr "Format Excellon" -#: flatcamGUI/PreferencesUI.py:2705 +#: flatcamGUI/PreferencesUI.py:2887 msgid "" "The NC drill files, usually named Excellon files\n" "are files that can be found in different formats.\n" @@ -10052,12 +10475,12 @@ msgstr "" "Sprint Layout 2: 4 INCH LZ\n" "KiCAD 3: 5 IN TZ" -#: flatcamGUI/PreferencesUI.py:2729 +#: flatcamGUI/PreferencesUI.py:2911 msgid "Default values for INCH are 2:4" msgstr "Les valeurs par défaut pour INCH sont 2: 4" -#: flatcamGUI/PreferencesUI.py:2736 flatcamGUI/PreferencesUI.py:2765 -#: flatcamGUI/PreferencesUI.py:3445 +#: flatcamGUI/PreferencesUI.py:2918 flatcamGUI/PreferencesUI.py:2947 +#: flatcamGUI/PreferencesUI.py:3723 msgid "" "This numbers signify the number of digits in\n" "the whole part of Excellon coordinates." @@ -10065,8 +10488,8 @@ msgstr "" "Ces chiffres représentent le nombre de chiffres en\n" "toute la partie des coordonnées Excellon." -#: flatcamGUI/PreferencesUI.py:2749 flatcamGUI/PreferencesUI.py:2778 -#: flatcamGUI/PreferencesUI.py:3458 +#: flatcamGUI/PreferencesUI.py:2931 flatcamGUI/PreferencesUI.py:2960 +#: flatcamGUI/PreferencesUI.py:3736 msgid "" "This numbers signify the number of digits in\n" "the decimal part of Excellon coordinates." @@ -10074,15 +10497,15 @@ msgstr "" "Ces chiffres représentent le nombre de chiffres en\n" "la partie décimale des coordonnées Excellon." -#: flatcamGUI/PreferencesUI.py:2757 +#: flatcamGUI/PreferencesUI.py:2939 msgid "METRIC" msgstr "MÉTRIQUE" -#: flatcamGUI/PreferencesUI.py:2758 +#: flatcamGUI/PreferencesUI.py:2940 msgid "Default values for METRIC are 3:3" msgstr "Les valeurs par défaut pour MÉTRIQUE sont 3: 3" -#: flatcamGUI/PreferencesUI.py:2789 +#: flatcamGUI/PreferencesUI.py:2971 msgid "" "This sets the type of Excellon zeros.\n" "If LZ then Leading Zeros are kept and\n" @@ -10102,7 +10525,7 @@ msgstr "" "Ceci est utilisé lorsqu'il n'y a pas d'informations\n" "stocké dans le fichier Excellon." -#: flatcamGUI/PreferencesUI.py:2807 +#: flatcamGUI/PreferencesUI.py:2989 msgid "" "This sets the default units of Excellon files.\n" "If it is not detected in the parsed file the value here\n" @@ -10114,7 +10537,7 @@ msgstr "" "sera utilisé. Certains fichiers Excellon n’ont pas d’en-tête\n" "donc ce paramètre sera utilisé." -#: flatcamGUI/PreferencesUI.py:2817 +#: flatcamGUI/PreferencesUI.py:2999 msgid "" "This sets the units of Excellon files.\n" "Some Excellon files don't have an header\n" @@ -10124,19 +10547,19 @@ msgstr "" "Certains fichiers Excellon n'ont pas d'en-tête\n" "donc ce paramètre sera utilisé." -#: flatcamGUI/PreferencesUI.py:2825 +#: flatcamGUI/PreferencesUI.py:3007 msgid "Update Export settings" msgstr "Mettre à jour les param d'export" -#: flatcamGUI/PreferencesUI.py:2842 +#: flatcamGUI/PreferencesUI.py:3024 msgid "Excellon Optimization" msgstr "Optimisation Excellon" -#: flatcamGUI/PreferencesUI.py:2845 +#: flatcamGUI/PreferencesUI.py:3027 msgid "Algorithm:" msgstr "Algorithme:" -#: flatcamGUI/PreferencesUI.py:2847 flatcamGUI/PreferencesUI.py:2863 +#: flatcamGUI/PreferencesUI.py:3029 flatcamGUI/PreferencesUI.py:3045 msgid "" "This sets the optimization type for the Excellon drill path.\n" "If <> is checked then Google OR-Tools algorithm with\n" @@ -10159,20 +10582,20 @@ msgstr "" "Si ce contrôle est désactivé, FlatCAM fonctionne en mode 32 bits et utilise\n" "Algorithme Travelling Salesman pour l’optimisation des chemins." -#: flatcamGUI/PreferencesUI.py:2858 +#: flatcamGUI/PreferencesUI.py:3040 msgid "MetaHeuristic" msgstr "MetaHeuristic" -#: flatcamGUI/PreferencesUI.py:2860 +#: flatcamGUI/PreferencesUI.py:3042 msgid "TSA" msgstr "TSA" -#: flatcamGUI/PreferencesUI.py:2877 flatcamGUI/PreferencesUI.py:3192 -#: flatcamGUI/PreferencesUI.py:4138 +#: flatcamGUI/PreferencesUI.py:3059 flatcamGUI/PreferencesUI.py:3463 +#: flatcamGUI/PreferencesUI.py:4430 msgid "Duration" msgstr "Durée" -#: flatcamGUI/PreferencesUI.py:2880 +#: flatcamGUI/PreferencesUI.py:3062 msgid "" "When OR-Tools Metaheuristic (MH) is enabled there is a\n" "maximum threshold for how much time is spent doing the\n" @@ -10184,15 +10607,19 @@ msgstr "" "optimisation du chemin. Cette durée maximale est définie ici.\n" "En secondes." -#: flatcamGUI/PreferencesUI.py:2899 +#: flatcamGUI/PreferencesUI.py:3081 msgid "Excellon Object Color" msgstr "Couleur d'objet Excellon" -#: flatcamGUI/PreferencesUI.py:3065 +#: flatcamGUI/PreferencesUI.py:3247 msgid "Excellon Options" msgstr "Les options Excellon" -#: flatcamGUI/PreferencesUI.py:3071 +#: flatcamGUI/PreferencesUI.py:3251 flatcamGUI/PreferencesUI.py:4227 +msgid "Create CNC Job" +msgstr "Créer un travail CNC" + +#: flatcamGUI/PreferencesUI.py:3253 msgid "" "Parameters used to create a CNC Job object\n" "for this drill object." @@ -10200,11 +10627,27 @@ msgstr "" "Paramètres utilisés pour créer un objet Travail CNC\n" "pour cet objet de forage." -#: flatcamGUI/PreferencesUI.py:3185 flatcamGUI/PreferencesUI.py:4133 +#: flatcamGUI/PreferencesUI.py:3370 flatcamGUI/PreferencesUI.py:4314 +msgid "Tool change" +msgstr "Changement d'outil" + +#: flatcamGUI/PreferencesUI.py:3454 flatcamGUI/PreferencesUI.py:4425 msgid "Enable Dwell" msgstr "Activer la Pause" -#: flatcamGUI/PreferencesUI.py:3217 +#: flatcamGUI/PreferencesUI.py:3477 +msgid "" +"The preprocessor JSON file that dictates\n" +"Gcode output." +msgstr "" +"Le fichier JSON post-processeur qui dicte\n" +"Sortie Gcode." + +#: flatcamGUI/PreferencesUI.py:3488 +msgid "Gcode" +msgstr "Gcode" + +#: flatcamGUI/PreferencesUI.py:3490 msgid "" "Choose what to use for GCode generation:\n" "'Drills', 'Slots' or 'Both'.\n" @@ -10216,15 +10659,35 @@ msgstr "" "Lorsque vous choisissez \"Fentes\" ou \"Les Deux\", les fentes seront\n" "converti en forages." -#: flatcamGUI/PreferencesUI.py:3235 +#: flatcamGUI/PreferencesUI.py:3506 +msgid "Mill Holes" +msgstr "Fraiser les Trous" + +#: flatcamGUI/PreferencesUI.py:3508 msgid "Create Geometry for milling holes." msgstr "Créer une géométrie pour fraiser des trous." -#: flatcamGUI/PreferencesUI.py:3271 +#: flatcamGUI/PreferencesUI.py:3512 +msgid "Drill Tool dia" +msgstr "Dia. de l'outil de forage" + +#: flatcamGUI/PreferencesUI.py:3523 +msgid "Slot Tool dia" +msgstr "Fente outil dia" + +#: flatcamGUI/PreferencesUI.py:3525 +msgid "" +"Diameter of the cutting tool\n" +"when milling slots." +msgstr "" +"Diamètre de l'outil de coupe\n" +"lors du fraisage des fentes." + +#: flatcamGUI/PreferencesUI.py:3544 msgid "Excellon Adv. Options" msgstr "Excellon Opt. avancées" -#: flatcamGUI/PreferencesUI.py:3280 +#: flatcamGUI/PreferencesUI.py:3553 msgid "" "A list of Excellon advanced parameters.\n" "Those parameters are available only for\n" @@ -10234,19 +10697,19 @@ msgstr "" "Ces paramètres ne sont disponibles que pour\n" "App avancée. Niveau." -#: flatcamGUI/PreferencesUI.py:3301 +#: flatcamGUI/PreferencesUI.py:3576 msgid "Toolchange X,Y" msgstr "Changement d'outils X, Y" -#: flatcamGUI/PreferencesUI.py:3303 flatcamGUI/PreferencesUI.py:4193 +#: flatcamGUI/PreferencesUI.py:3578 flatcamGUI/PreferencesUI.py:4486 msgid "Toolchange X,Y position." msgstr "Changement d'outil en position X et Y." -#: flatcamGUI/PreferencesUI.py:3360 flatcamGUI/PreferencesUI.py:4280 +#: flatcamGUI/PreferencesUI.py:3638 flatcamGUI/PreferencesUI.py:4573 msgid "Spindle direction" msgstr "Direction du moteur" -#: flatcamGUI/PreferencesUI.py:3362 flatcamGUI/PreferencesUI.py:4282 +#: flatcamGUI/PreferencesUI.py:3640 flatcamGUI/PreferencesUI.py:4575 msgid "" "This sets the direction that the spindle is rotating.\n" "It can be either:\n" @@ -10258,11 +10721,11 @@ msgstr "" "- CW = dans le sens des aiguilles d'une montre ou\n" "- CCW = dans le sens antihoraire" -#: flatcamGUI/PreferencesUI.py:3373 flatcamGUI/PreferencesUI.py:4294 +#: flatcamGUI/PreferencesUI.py:3651 flatcamGUI/PreferencesUI.py:4587 msgid "Fast Plunge" msgstr "Plongée rapide" -#: flatcamGUI/PreferencesUI.py:3375 flatcamGUI/PreferencesUI.py:4296 +#: flatcamGUI/PreferencesUI.py:3653 flatcamGUI/PreferencesUI.py:4589 msgid "" "By checking this, the vertical move from\n" "Z_Toolchange to Z_move is done with G0,\n" @@ -10275,11 +10738,11 @@ msgstr "" "AVERTISSEMENT: le déplacement est effectué à l'aide de Toolchange X, Y " "coords." -#: flatcamGUI/PreferencesUI.py:3382 +#: flatcamGUI/PreferencesUI.py:3660 msgid "Fast Retract" msgstr "Retrait Rapide" -#: flatcamGUI/PreferencesUI.py:3384 +#: flatcamGUI/PreferencesUI.py:3662 msgid "" "Exit hole strategy.\n" " - When uncheked, while exiting the drilled hole the drill bit\n" @@ -10298,11 +10761,11 @@ msgstr "" "(hauteur de déplacement) est fait aussi vite que possible (G0) en un seul " "mouvement." -#: flatcamGUI/PreferencesUI.py:3402 +#: flatcamGUI/PreferencesUI.py:3680 msgid "Excellon Export" msgstr "Excellon exportation" -#: flatcamGUI/PreferencesUI.py:3408 +#: flatcamGUI/PreferencesUI.py:3686 msgid "" "The parameters set here are used in the file exported\n" "when using the File -> Export -> Export Excellon menu entry." @@ -10311,11 +10774,11 @@ msgstr "" "lors de l'utilisation de l'entrée de menu Fichier -> Exporter -> Exporter " "Excellon." -#: flatcamGUI/PreferencesUI.py:3419 flatcamGUI/PreferencesUI.py:3425 +#: flatcamGUI/PreferencesUI.py:3697 flatcamGUI/PreferencesUI.py:3703 msgid "The units used in the Excellon file." msgstr "Les unités utilisées dans le fichier Excellon." -#: flatcamGUI/PreferencesUI.py:3433 +#: flatcamGUI/PreferencesUI.py:3711 msgid "" "The NC drill files, usually named Excellon files\n" "are files that can be found in different formats.\n" @@ -10327,11 +10790,11 @@ msgstr "" "Ici, nous définissons le format utilisé lorsque le\n" "les coordonnées n'utilisent pas de période." -#: flatcamGUI/PreferencesUI.py:3467 +#: flatcamGUI/PreferencesUI.py:3745 msgid "Format" msgstr "Format" -#: flatcamGUI/PreferencesUI.py:3469 flatcamGUI/PreferencesUI.py:3479 +#: flatcamGUI/PreferencesUI.py:3747 flatcamGUI/PreferencesUI.py:3757 msgid "" "Select the kind of coordinates format used.\n" "Coordinates can be saved with decimal point or without.\n" @@ -10347,15 +10810,15 @@ msgstr "" "De plus, il faudra préciser si LZ = zéros non significatifs sont conservés\n" "ou TZ = les zéros de fin sont conservés." -#: flatcamGUI/PreferencesUI.py:3476 +#: flatcamGUI/PreferencesUI.py:3754 msgid "Decimal" msgstr "Décimal" -#: flatcamGUI/PreferencesUI.py:3477 +#: flatcamGUI/PreferencesUI.py:3755 msgid "No-Decimal" msgstr "Aucune décimale" -#: flatcamGUI/PreferencesUI.py:3493 +#: flatcamGUI/PreferencesUI.py:3771 msgid "" "This sets the type of Excellon zeros.\n" "If LZ then Leading Zeros are kept and\n" @@ -10369,7 +10832,7 @@ msgstr "" "Si TZ est coché, les zéros suivants sont conservés\n" "et les zéros non significatifs sont supprimés." -#: flatcamGUI/PreferencesUI.py:3503 +#: flatcamGUI/PreferencesUI.py:3781 msgid "" "This sets the default type of Excellon zeros.\n" "If LZ then Leading Zeros are kept and\n" @@ -10383,11 +10846,11 @@ msgstr "" "Si TZ est coché, les zéros suivants sont conservés\n" "et les zéros non significatifs sont supprimés." -#: flatcamGUI/PreferencesUI.py:3513 +#: flatcamGUI/PreferencesUI.py:3791 msgid "Slot type" msgstr "Type d'fentes" -#: flatcamGUI/PreferencesUI.py:3516 flatcamGUI/PreferencesUI.py:3526 +#: flatcamGUI/PreferencesUI.py:3794 flatcamGUI/PreferencesUI.py:3804 msgid "" "This sets how the slots will be exported.\n" "If ROUTED then the slots will be routed\n" @@ -10401,19 +10864,19 @@ msgstr "" "Si percé (G85) les emplacements seront exportés\n" "en utilisant la commande slot foré (G85)." -#: flatcamGUI/PreferencesUI.py:3523 +#: flatcamGUI/PreferencesUI.py:3801 msgid "Routed" msgstr "Routé" -#: flatcamGUI/PreferencesUI.py:3524 +#: flatcamGUI/PreferencesUI.py:3802 msgid "Drilled(G85)" msgstr "Percé(G85)" -#: flatcamGUI/PreferencesUI.py:3557 +#: flatcamGUI/PreferencesUI.py:3835 msgid "A list of Excellon Editor parameters." msgstr "Une liste des paramètres de l'éditeur Excellon." -#: flatcamGUI/PreferencesUI.py:3567 +#: flatcamGUI/PreferencesUI.py:3845 msgid "" "Set the number of selected Excellon geometry\n" "items above which the utility geometry\n" @@ -10427,19 +10890,20 @@ msgstr "" "Augmente les performances lors du déplacement d'un\n" "grand nombre d'éléments géométriques." -#: flatcamGUI/PreferencesUI.py:3580 flatcamGUI/PreferencesUI.py:5100 -msgid "New Tool Dia" -msgstr "Nouvel Outil Dia" +#: flatcamGUI/PreferencesUI.py:3858 flatcamGUI/PreferencesUI.py:5396 +#: flatcamGUI/PreferencesUI.py:5962 +msgid "New Dia" +msgstr "Nouvel Dia" -#: flatcamGUI/PreferencesUI.py:3605 +#: flatcamGUI/PreferencesUI.py:3883 msgid "Linear Drill Array" msgstr "Matrice de Forage Linéaire" -#: flatcamGUI/PreferencesUI.py:3651 +#: flatcamGUI/PreferencesUI.py:3929 msgid "Circular Drill Array" msgstr "Matrice de Forage Circulaires" -#: flatcamGUI/PreferencesUI.py:3721 +#: flatcamGUI/PreferencesUI.py:3999 msgid "" "Angle at which the slot is placed.\n" "The precision is of max 2 decimals.\n" @@ -10451,19 +10915,19 @@ msgstr "" "La valeur minimale est: -359,99 degrés.\n" "La valeur maximale est: 360,00 degrés." -#: flatcamGUI/PreferencesUI.py:3740 +#: flatcamGUI/PreferencesUI.py:4018 msgid "Linear Slot Array" msgstr "Matrice de Fente Linéaire" -#: flatcamGUI/PreferencesUI.py:3801 +#: flatcamGUI/PreferencesUI.py:4079 msgid "Circular Slot Array" msgstr "Matrice de Fente Circulaire" -#: flatcamGUI/PreferencesUI.py:3839 +#: flatcamGUI/PreferencesUI.py:4117 msgid "Geometry General" msgstr "Géométrie Général" -#: flatcamGUI/PreferencesUI.py:3861 +#: flatcamGUI/PreferencesUI.py:4139 msgid "" "The number of circle steps for Geometry \n" "circle and arc shapes linear approximation." @@ -10471,15 +10935,20 @@ msgstr "" "Nombre d'étapes de cercle pour Géométrie\n" "approximation linéaire des formes de cercle et d'arc." -#: flatcamGUI/PreferencesUI.py:3890 +#: flatcamGUI/PreferencesUI.py:4153 flatcamGUI/PreferencesUI.py:5320 +#: flatcamGUI/PreferencesUI.py:5887 flatcamGUI/PreferencesUI.py:6953 +msgid "Tools Dia" +msgstr "Dia. de l'outils" + +#: flatcamGUI/PreferencesUI.py:4170 msgid "Geometry Object Color" msgstr "Couleur de l'objet Géométrie" -#: flatcamGUI/PreferencesUI.py:3941 +#: flatcamGUI/PreferencesUI.py:4221 msgid "Geometry Options" msgstr "Options de Géométrie" -#: flatcamGUI/PreferencesUI.py:3949 +#: flatcamGUI/PreferencesUI.py:4229 msgid "" "Create a CNC Job object\n" "tracing the contours of this\n" @@ -10489,11 +10958,11 @@ msgstr "" "traçant les contours de cette\n" "Objet de géométrie." -#: flatcamGUI/PreferencesUI.py:3993 +#: flatcamGUI/PreferencesUI.py:4273 msgid "Depth/Pass" msgstr "Profondeur/Pass" -#: flatcamGUI/PreferencesUI.py:3995 +#: flatcamGUI/PreferencesUI.py:4275 msgid "" "The depth to cut on each pass,\n" "when multidepth is enabled.\n" @@ -10507,11 +10976,11 @@ msgstr "" "c'est une fraction de la profondeur\n" "qui a une valeur négative." -#: flatcamGUI/PreferencesUI.py:4173 +#: flatcamGUI/PreferencesUI.py:4466 msgid "Geometry Adv. Options" msgstr "Géométrie Adv. Les options" -#: flatcamGUI/PreferencesUI.py:4181 +#: flatcamGUI/PreferencesUI.py:4474 msgid "" "A list of Geometry advanced parameters.\n" "Those parameters are available only for\n" @@ -10521,13 +10990,13 @@ msgstr "" "Ces paramètres ne sont disponibles que pour\n" "App avancée. Niveau." -#: flatcamGUI/PreferencesUI.py:4191 flatcamGUI/PreferencesUI.py:6539 -#: flatcamGUI/PreferencesUI.py:7586 flatcamTools/ToolCalibration.py:125 -#: flatcamTools/ToolSolderPaste.py:239 +#: flatcamGUI/PreferencesUI.py:4484 flatcamGUI/PreferencesUI.py:7045 +#: flatcamGUI/PreferencesUI.py:8092 flatcamTools/ToolCalibration.py:125 +#: flatcamTools/ToolSolderPaste.py:241 msgid "Toolchange X-Y" msgstr "Changement d'outils X-Y" -#: flatcamGUI/PreferencesUI.py:4202 +#: flatcamGUI/PreferencesUI.py:4495 msgid "" "Height of the tool just after starting the work.\n" "Delete the value if you don't need this feature." @@ -10535,11 +11004,11 @@ msgstr "" "Hauteur de l'outil juste après le début du travail.\n" "Supprimez la valeur si vous n'avez pas besoin de cette fonctionnalité." -#: flatcamGUI/PreferencesUI.py:4304 +#: flatcamGUI/PreferencesUI.py:4597 msgid "Segment X size" msgstr "Taille du seg. X" -#: flatcamGUI/PreferencesUI.py:4306 +#: flatcamGUI/PreferencesUI.py:4599 msgid "" "The size of the trace segment on the X axis.\n" "Useful for auto-leveling.\n" @@ -10549,11 +11018,11 @@ msgstr "" "Utile pour le nivellement automatique.\n" "Une valeur de 0 signifie aucune segmentation sur l'axe X." -#: flatcamGUI/PreferencesUI.py:4320 +#: flatcamGUI/PreferencesUI.py:4613 msgid "Segment Y size" msgstr "Taille du seg. Y" -#: flatcamGUI/PreferencesUI.py:4322 +#: flatcamGUI/PreferencesUI.py:4615 msgid "" "The size of the trace segment on the Y axis.\n" "Useful for auto-leveling.\n" @@ -10563,15 +11032,11 @@ msgstr "" "Utile pour le nivellement automatique.\n" "Une valeur de 0 signifie aucune segmentation sur l'axe Y." -#: flatcamGUI/PreferencesUI.py:4343 -msgid "Geometry Editor" -msgstr "Éditeur de Géométrie" - -#: flatcamGUI/PreferencesUI.py:4349 +#: flatcamGUI/PreferencesUI.py:4642 msgid "A list of Geometry Editor parameters." msgstr "Une liste de paramètres de L'éditeur de Géométrie." -#: flatcamGUI/PreferencesUI.py:4359 flatcamGUI/PreferencesUI.py:7111 +#: flatcamGUI/PreferencesUI.py:4652 flatcamGUI/PreferencesUI.py:7617 msgid "" "Set the number of selected geometry\n" "items above which the utility geometry\n" @@ -10585,11 +11050,11 @@ msgstr "" "Augmente les performances lors du déplacement d'un\n" "grand nombre d'éléments géométriques." -#: flatcamGUI/PreferencesUI.py:4391 +#: flatcamGUI/PreferencesUI.py:4684 msgid "CNC Job General" msgstr "CNCJob Général" -#: flatcamGUI/PreferencesUI.py:4444 +#: flatcamGUI/PreferencesUI.py:4737 msgid "" "The number of circle steps for GCode \n" "circle and arc shapes linear approximation." @@ -10597,11 +11062,11 @@ msgstr "" "Nombre d'étapes du cercle pour GCode\n" "approximation linéaire des formes de cercle et d'arc." -#: flatcamGUI/PreferencesUI.py:4453 +#: flatcamGUI/PreferencesUI.py:4746 msgid "Travel dia" msgstr "Voyage DIa" -#: flatcamGUI/PreferencesUI.py:4455 +#: flatcamGUI/PreferencesUI.py:4748 msgid "" "The width of the travel lines to be\n" "rendered in the plot." @@ -10609,15 +11074,15 @@ msgstr "" "La largeur des lignes de voyage à être\n" "rendu dans l'intrigue." -#: flatcamGUI/PreferencesUI.py:4468 +#: flatcamGUI/PreferencesUI.py:4761 msgid "G-code Decimals" msgstr "Décimales G-code" -#: flatcamGUI/PreferencesUI.py:4471 flatcamTools/ToolFiducials.py:74 +#: flatcamGUI/PreferencesUI.py:4764 flatcamTools/ToolFiducials.py:74 msgid "Coordinates" msgstr "Coordonnées" -#: flatcamGUI/PreferencesUI.py:4473 +#: flatcamGUI/PreferencesUI.py:4766 msgid "" "The number of decimals to be used for \n" "the X, Y, Z coordinates in CNC code (GCODE, etc.)" @@ -10625,11 +11090,11 @@ msgstr "" "Le nombre de décimales à utiliser pour\n" "les coordonnées X, Y, Z en code CNC (GCODE, etc.)" -#: flatcamGUI/PreferencesUI.py:4484 flatcamTools/ToolProperties.py:492 +#: flatcamGUI/PreferencesUI.py:4777 flatcamTools/ToolProperties.py:519 msgid "Feedrate" msgstr "Vitesse d'avance" -#: flatcamGUI/PreferencesUI.py:4486 +#: flatcamGUI/PreferencesUI.py:4779 msgid "" "The number of decimals to be used for \n" "the Feedrate parameter in CNC code (GCODE, etc.)" @@ -10637,11 +11102,11 @@ msgstr "" "Le nombre de décimales à utiliser pour\n" "le paramètre Feedrate en code CNC (GCODE, etc.)" -#: flatcamGUI/PreferencesUI.py:4497 +#: flatcamGUI/PreferencesUI.py:4790 msgid "Coordinates type" msgstr "Type de coord" -#: flatcamGUI/PreferencesUI.py:4499 +#: flatcamGUI/PreferencesUI.py:4792 msgid "" "The type of coordinates to be used in Gcode.\n" "Can be:\n" @@ -10653,19 +11118,19 @@ msgstr "" "- G90 absolu -> la référence est l'origine x = 0, y = 0\n" "- Incrémental G91 -> la référence est la position précédente" -#: flatcamGUI/PreferencesUI.py:4505 +#: flatcamGUI/PreferencesUI.py:4798 msgid "Absolute G90" msgstr "G90 absolu" -#: flatcamGUI/PreferencesUI.py:4506 +#: flatcamGUI/PreferencesUI.py:4799 msgid "Incremental G91" msgstr "G91 incrémentiel" -#: flatcamGUI/PreferencesUI.py:4516 +#: flatcamGUI/PreferencesUI.py:4809 msgid "Force Windows style line-ending" msgstr "Forcer la fin de ligne de style Windows" -#: flatcamGUI/PreferencesUI.py:4518 +#: flatcamGUI/PreferencesUI.py:4811 msgid "" "When checked will force a Windows style line-ending\n" "(\\r\\n) on non-Windows OS's." @@ -10673,36 +11138,36 @@ msgstr "" "Lorsqu'elle est cochée, la fin de ligne de style Windows\n" "(\\r \\n) sur les systèmes d'exploitation non Windows." -#: flatcamGUI/PreferencesUI.py:4530 +#: flatcamGUI/PreferencesUI.py:4823 msgid "Travel Line Color" msgstr "Couleur de la ligne de voyage" -#: flatcamGUI/PreferencesUI.py:4536 +#: flatcamGUI/PreferencesUI.py:4829 msgid "Set the travel line color for plotted objects." msgstr "" "Définissez la couleur de la ligne de déplacement pour les objets tracés." -#: flatcamGUI/PreferencesUI.py:4596 +#: flatcamGUI/PreferencesUI.py:4889 msgid "CNCJob Object Color" msgstr "Couleur d'objet CNCJob" -#: flatcamGUI/PreferencesUI.py:4602 +#: flatcamGUI/PreferencesUI.py:4895 msgid "Set the color for plotted objects." msgstr "Définissez la couleur des objets tracés." -#: flatcamGUI/PreferencesUI.py:4762 +#: flatcamGUI/PreferencesUI.py:5055 msgid "CNC Job Options" msgstr "Options CNCjob" -#: flatcamGUI/PreferencesUI.py:4766 +#: flatcamGUI/PreferencesUI.py:5059 msgid "Export G-Code" msgstr "Exporter le code G" -#: flatcamGUI/PreferencesUI.py:4782 +#: flatcamGUI/PreferencesUI.py:5075 msgid "Prepend to G-Code" msgstr "Préfixer au G-Code" -#: flatcamGUI/PreferencesUI.py:4791 +#: flatcamGUI/PreferencesUI.py:5084 msgid "" "Type here any G-Code commands you would like to add at the beginning of the " "G-Code file." @@ -10710,11 +11175,11 @@ msgstr "" "Tapez ici toutes les commandes G-Code que vous souhaitez ajouter au début du " "fichier G-Code." -#: flatcamGUI/PreferencesUI.py:4798 +#: flatcamGUI/PreferencesUI.py:5091 msgid "Append to G-Code" msgstr "Ajouter au G-Code" -#: flatcamGUI/PreferencesUI.py:4808 +#: flatcamGUI/PreferencesUI.py:5101 msgid "" "Type here any G-Code commands you would like to append to the generated " "file.\n" @@ -10724,11 +11189,11 @@ msgstr "" "généré.\n" "Par exemple: M2 (Fin du programme)" -#: flatcamGUI/PreferencesUI.py:4824 +#: flatcamGUI/PreferencesUI.py:5117 msgid "CNC Job Adv. Options" msgstr "Options avan. de CNCjob" -#: flatcamGUI/PreferencesUI.py:4861 +#: flatcamGUI/PreferencesUI.py:5154 msgid "" "Type here any G-Code commands you would like to be executed when Toolchange " "event is encountered.\n" @@ -10745,47 +11210,48 @@ msgstr "" "AVERTISSEMENT: il ne peut être utilisé qu'avec un fichier de préprocesseur " "qui a «toolchange_custom» dans son nom." -#: flatcamGUI/PreferencesUI.py:4916 +#: flatcamGUI/PreferencesUI.py:5209 msgid "Z depth for the cut" msgstr "Z profondeur pour la coupe" -#: flatcamGUI/PreferencesUI.py:4917 +#: flatcamGUI/PreferencesUI.py:5210 msgid "Z height for travel" msgstr "Z hauteur pour le voyage" -#: flatcamGUI/PreferencesUI.py:4923 +#: flatcamGUI/PreferencesUI.py:5216 msgid "dwelltime = time to dwell to allow the spindle to reach it's set RPM" msgstr "" "dwelltime = temps de repos pour permettre à la broche d'atteindre son régime " "défini" -#: flatcamGUI/PreferencesUI.py:4942 +#: flatcamGUI/PreferencesUI.py:5235 msgid "Annotation Size" msgstr "Taille de l'annotation" -#: flatcamGUI/PreferencesUI.py:4944 +#: flatcamGUI/PreferencesUI.py:5237 msgid "The font size of the annotation text. In pixels." msgstr "La taille de la police du texte d'annotation. En pixels." -#: flatcamGUI/PreferencesUI.py:4954 +#: flatcamGUI/PreferencesUI.py:5247 msgid "Annotation Color" msgstr "Couleur de l'annotation" -#: flatcamGUI/PreferencesUI.py:4956 +#: flatcamGUI/PreferencesUI.py:5249 msgid "Set the font color for the annotation texts." msgstr "Définissez la couleur de la police pour les textes d'annotation." -#: flatcamGUI/PreferencesUI.py:5013 +#: flatcamGUI/PreferencesUI.py:5306 msgid "NCC Tool Options" msgstr "Options de L'outil de la NCC" -#: flatcamGUI/PreferencesUI.py:5027 flatcamGUI/PreferencesUI.py:6449 -msgid "Tools dia" -msgstr "Outils dia" +#: flatcamGUI/PreferencesUI.py:5328 flatcamGUI/PreferencesUI.py:5896 +msgid "Comma separated values" +msgstr "Valeurs séparées par des virgules" -#: flatcamGUI/PreferencesUI.py:5038 flatcamGUI/PreferencesUI.py:5046 -#: flatcamTools/ToolNonCopperClear.py:215 -#: flatcamTools/ToolNonCopperClear.py:223 +#: flatcamGUI/PreferencesUI.py:5334 flatcamGUI/PreferencesUI.py:5342 +#: flatcamGUI/PreferencesUI.py:5903 flatcamTools/ToolNCC.py:215 +#: flatcamTools/ToolNCC.py:223 flatcamTools/ToolPaint.py:198 +#: flatcamTools/ToolPaint.py:206 msgid "" "Default tool type:\n" "- 'V-shape'\n" @@ -10795,13 +11261,15 @@ msgstr "" "- 'Forme en V'\n" "- circulaire" -#: flatcamGUI/PreferencesUI.py:5043 flatcamTools/ToolNonCopperClear.py:220 +#: flatcamGUI/PreferencesUI.py:5339 flatcamGUI/PreferencesUI.py:5908 +#: flatcamTools/ToolNCC.py:220 flatcamTools/ToolPaint.py:203 msgid "V-shape" msgstr "Forme en V" -#: flatcamGUI/PreferencesUI.py:5083 flatcamGUI/PreferencesUI.py:5092 -#: flatcamTools/ToolNonCopperClear.py:256 -#: flatcamTools/ToolNonCopperClear.py:264 +#: flatcamGUI/PreferencesUI.py:5379 flatcamGUI/PreferencesUI.py:5388 +#: flatcamGUI/PreferencesUI.py:5946 flatcamGUI/PreferencesUI.py:5955 +#: flatcamTools/ToolNCC.py:262 flatcamTools/ToolNCC.py:271 +#: flatcamTools/ToolPaint.py:245 flatcamTools/ToolPaint.py:254 msgid "" "Depth of cut into material. Negative value.\n" "In FlatCAM units." @@ -10809,35 +11277,26 @@ msgstr "" "Profondeur de la coupe dans le matériau. Valeur négative.\n" "En unités FlatCAM." -#: flatcamGUI/PreferencesUI.py:5102 -msgid "The new tool diameter (cut width) to add in the tool table." -msgstr "" -"Le nouveau diamètre d'outil (largeur de coupe) à ajouter dans la table " -"d'outils." - -#: flatcamGUI/PreferencesUI.py:5114 flatcamGUI/PreferencesUI.py:5122 -#: flatcamTools/ToolNonCopperClear.py:164 -#: flatcamTools/ToolNonCopperClear.py:172 +#: flatcamGUI/PreferencesUI.py:5398 flatcamGUI/PreferencesUI.py:5964 +#: flatcamTools/ToolNCC.py:280 flatcamTools/ToolPaint.py:263 msgid "" -"Milling type when the selected tool is of type: 'iso_op':\n" -"- climb / best for precision milling and to reduce tool usage\n" -"- conventional / useful when there is no backlash compensation" +"Diameter for the new tool to add in the Tool Table.\n" +"If the tool is V-shape type then this value is automatically\n" +"calculated from the other parameters." msgstr "" -"Type de fraisage lorsque l'outil sélectionné est de type: 'iso_op':\n" -"- montée / idéal pour le fraisage de précision et pour réduire l'utilisation " -"d'outils\n" -"- conventionnel / utile quand il n'y a pas de compensation de jeu" +"Diamètre du nouvel outil à ajouter dans la table d'outils.\n" +"Si l'outil est de type V, cette valeur est automatiquement\n" +"calculé à partir des autres paramètres." -#: flatcamGUI/PreferencesUI.py:5131 flatcamGUI/PreferencesUI.py:5546 -#: flatcamTools/ToolNonCopperClear.py:181 flatcamTools/ToolPaint.py:153 +#: flatcamGUI/PreferencesUI.py:5435 flatcamGUI/PreferencesUI.py:5981 +#: flatcamTools/ToolNCC.py:174 flatcamTools/ToolPaint.py:158 msgid "Tool order" msgstr "L'ordre des Outils" -#: flatcamGUI/PreferencesUI.py:5132 flatcamGUI/PreferencesUI.py:5142 -#: flatcamGUI/PreferencesUI.py:5547 flatcamGUI/PreferencesUI.py:5557 -#: flatcamTools/ToolNonCopperClear.py:182 -#: flatcamTools/ToolNonCopperClear.py:192 flatcamTools/ToolPaint.py:154 -#: flatcamTools/ToolPaint.py:164 +#: flatcamGUI/PreferencesUI.py:5436 flatcamGUI/PreferencesUI.py:5446 +#: flatcamGUI/PreferencesUI.py:5982 flatcamTools/ToolNCC.py:175 +#: flatcamTools/ToolNCC.py:185 flatcamTools/ToolPaint.py:159 +#: flatcamTools/ToolPaint.py:169 msgid "" "This set the way that the tools in the tools table are used.\n" "'No' --> means that the used order is the one in the tool table\n" @@ -10859,70 +11318,39 @@ msgstr "" "commande\n" "en sens inverse et désactivez ce contrôle." -#: flatcamGUI/PreferencesUI.py:5140 flatcamGUI/PreferencesUI.py:5555 -#: flatcamTools/ToolNonCopperClear.py:190 flatcamTools/ToolPaint.py:162 +#: flatcamGUI/PreferencesUI.py:5444 flatcamGUI/PreferencesUI.py:5990 +#: flatcamTools/ToolNCC.py:183 flatcamTools/ToolPaint.py:167 msgid "Forward" msgstr "L'avant" -#: flatcamGUI/PreferencesUI.py:5141 flatcamGUI/PreferencesUI.py:5556 -#: flatcamTools/ToolNonCopperClear.py:191 flatcamTools/ToolPaint.py:163 +#: flatcamGUI/PreferencesUI.py:5445 flatcamGUI/PreferencesUI.py:5991 +#: flatcamTools/ToolNCC.py:184 flatcamTools/ToolPaint.py:168 msgid "Reverse" msgstr "Inverse" -#: flatcamGUI/PreferencesUI.py:5154 flatcamTools/ToolNonCopperClear.py:321 +#: flatcamGUI/PreferencesUI.py:5545 +msgid "Offset value" +msgstr "Valeur de Décalage" + +#: flatcamGUI/PreferencesUI.py:5547 msgid "" -"How much (fraction) of the tool width to overlap each tool pass.\n" -"Adjust the value starting with lower values\n" -"and increasing it if areas that should be cleared are still \n" -"not cleared.\n" -"Lower values = faster processing, faster execution on CNC.\n" -"Higher values = slow processing and slow execution on CNC\n" -"due of too many paths." +"If used, it will add an offset to the copper features.\n" +"The copper clearing will finish to a distance\n" +"from the copper features.\n" +"The value can be between 0.0 and 9999.9 FlatCAM units." msgstr "" -"Combien (fraction) de la largeur de l'outil doit chevaucher chaque passe-" -"outil.\n" -"Ajuster la valeur en commençant par les valeurs les plus basses\n" -"et augmenter si les zones qui doivent être effacées sont encore\n" -"pas effacé.\n" -"Des valeurs plus faibles = traitement plus rapide, exécution plus rapide sur " -"le PCB.\n" -"Valeurs plus élevées = traitement lent et exécution lente sur la CNC\n" -"à cause de trop de chemins." +"S'il est utilisé, cela ajoutera un décalage aux entités en cuivre.\n" +"La clairière de cuivre finira à distance\n" +"des caractéristiques de cuivre.\n" +"La valeur peut être comprise entre 0 et 9999.9 unités FlatCAM." -#: flatcamGUI/PreferencesUI.py:5173 flatcamGUI/PreferencesUI.py:7177 -#: flatcamGUI/PreferencesUI.py:7419 flatcamGUI/PreferencesUI.py:7483 -#: flatcamTools/ToolCopperThieving.py:113 flatcamTools/ToolFiducials.py:174 -#: flatcamTools/ToolFiducials.py:237 flatcamTools/ToolNonCopperClear.py:339 -msgid "Bounding box margin." -msgstr "Marge du cadre de sélection." - -#: flatcamGUI/PreferencesUI.py:5186 flatcamGUI/PreferencesUI.py:5604 -#: flatcamTools/ToolNonCopperClear.py:350 -msgid "" -"Algorithm for non-copper clearing:
Standard: Fixed step inwards." -"
Seed-based: Outwards from seed.
Line-based: Parallel " -"lines." -msgstr "" -"Algorithme pour le clearing sans cuivre:
Standard: incrémentation " -"fixe.
Basé sur les Semences : Sortant des semences
Basé " -"sur les Lignes : lignes parallèles." - -#: flatcamGUI/PreferencesUI.py:5202 flatcamGUI/PreferencesUI.py:5618 -#: flatcamTools/ToolNonCopperClear.py:364 flatcamTools/ToolPaint.py:267 -msgid "Connect" -msgstr "Relier" - -#: flatcamGUI/PreferencesUI.py:5211 flatcamGUI/PreferencesUI.py:5626 -#: flatcamTools/ToolNonCopperClear.py:371 flatcamTools/ToolPaint.py:274 -msgid "Contour" -msgstr "Contour" - -#: flatcamGUI/PreferencesUI.py:5220 flatcamTools/ToolNonCopperClear.py:379 -#: flatcamTools/ToolPaint.py:281 +#: flatcamGUI/PreferencesUI.py:5567 flatcamGUI/PreferencesUI.py:6083 +#: flatcamGUI/PreferencesUI.py:6084 flatcamTools/ToolNCC.py:512 +#: flatcamTools/ToolPaint.py:442 msgid "Rest Machining" msgstr "Usinage de Repos" -#: flatcamGUI/PreferencesUI.py:5222 flatcamTools/ToolNonCopperClear.py:381 +#: flatcamGUI/PreferencesUI.py:5569 flatcamTools/ToolNCC.py:516 msgid "" "If checked, use 'rest machining'.\n" "Basically it will clear copper outside PCB features,\n" @@ -10940,82 +11368,65 @@ msgstr "" "plus de cuivre à nettoyer ou il n'y a plus d'outils.\n" "Si non coché, utilisez l'algorithme standard." -#: flatcamGUI/PreferencesUI.py:5236 flatcamTools/ToolNonCopperClear.py:395 -#: flatcamTools/ToolNonCopperClear.py:405 +#: flatcamGUI/PreferencesUI.py:5588 flatcamGUI/PreferencesUI.py:6119 +#: flatcamGUI/PreferencesUI.py:7696 flatcamTools/ToolCopperThieving.py:127 +#: flatcamTools/ToolNCC.py:535 flatcamTools/ToolNCC.py:1311 +#: flatcamTools/ToolNCC.py:1642 flatcamTools/ToolNCC.py:1930 +#: flatcamTools/ToolNCC.py:1985 flatcamTools/ToolPaint.py:486 +#: flatcamTools/ToolPaint.py:946 flatcamTools/ToolPaint.py:1447 +msgid "Area Selection" +msgstr "Sélection de zone" + +#: flatcamGUI/PreferencesUI.py:5588 flatcamGUI/PreferencesUI.py:6119 +#: flatcamGUI/PreferencesUI.py:7697 flatcamTools/ToolCopperThieving.py:128 +#: flatcamTools/ToolDblSided.py:217 flatcamTools/ToolNCC.py:535 +#: flatcamTools/ToolNCC.py:1658 flatcamTools/ToolNCC.py:1936 +#: flatcamTools/ToolNCC.py:1993 flatcamTools/ToolNCC.py:2301 +#: flatcamTools/ToolNCC.py:2581 flatcamTools/ToolNCC.py:3007 +#: flatcamTools/ToolPaint.py:486 flatcamTools/ToolPaint.py:931 +#: flatcamTools/ToolPaint.py:1463 tclCommands/TclCommandCopperClear.py:192 +#: tclCommands/TclCommandPaint.py:166 +msgid "Reference Object" +msgstr "Objet de référence" + +#: flatcamGUI/PreferencesUI.py:5592 flatcamTools/ToolNCC.py:541 msgid "" -"If used, it will add an offset to the copper features.\n" -"The copper clearing will finish to a distance\n" -"from the copper features.\n" -"The value can be between 0 and 10 FlatCAM units." -msgstr "" -"S'il est utilisé, cela ajoutera un décalage aux entités en cuivre.\n" -"La clairière de cuivre finira à distance\n" -"des caractéristiques de cuivre.\n" -"La valeur peut être comprise entre 0 et 10 unités FlatCAM." - -#: flatcamGUI/PreferencesUI.py:5245 flatcamTools/ToolNonCopperClear.py:403 -msgid "Offset value" -msgstr "Valeur de Décalage" - -#: flatcamGUI/PreferencesUI.py:5247 -msgid "" -"If used, it will add an offset to the copper features.\n" -"The copper clearing will finish to a distance\n" -"from the copper features.\n" -"The value can be between 0.0 and 9999.9 FlatCAM units." -msgstr "" -"S'il est utilisé, cela ajoutera un décalage aux entités en cuivre.\n" -"La clairière de cuivre finira à distance\n" -"des caractéristiques de cuivre.\n" -"La valeur peut être comprise entre 0 et 9999.9 unités FlatCAM." - -#: flatcamGUI/PreferencesUI.py:5262 flatcamGUI/PreferencesUI.py:7189 -#: flatcamTools/ToolCopperThieving.py:125 -#: flatcamTools/ToolNonCopperClear.py:429 -msgid "Itself" -msgstr "Lui-même" - -#: flatcamGUI/PreferencesUI.py:5263 flatcamGUI/PreferencesUI.py:5646 -msgid "Area" -msgstr "Zone" - -#: flatcamGUI/PreferencesUI.py:5264 flatcamGUI/PreferencesUI.py:5648 -msgid "Ref" -msgstr "Réf" - -#: flatcamGUI/PreferencesUI.py:5267 -msgid "" -"- 'Itself' - the non copper clearing extent\n" -"is based on the object that is copper cleared.\n" +"Selection of area to be processed.\n" +"- 'Itself' - the processing extent is based on the object that is " +"processed.\n" " - 'Area Selection' - left mouse click to start selection of the area to be " -"painted.\n" -"Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple " -"areas.\n" -"- 'Reference Object' - will do non copper clearing within the area\n" -"specified by another object." +"processed.\n" +"- 'Reference Object' - will process the area specified by another object." msgstr "" -"- \"Lui-même\" - l'étendue du clearing non en cuivre\n" -"est basé sur l'objet qui est en cuivre effacé.\n" -"- 'Sélection de zone' - cliquez avec le bouton gauche de la souris pour " -"lancer la sélection de la zone à peindre.\n" -"En maintenant une touche de modification enfoncée (CTRL ou SHIFT), vous " -"pourrez ajouter plusieurs zones.\n" -"- 'Objet de référence' - effectuera un nettoyage sans cuivre dans la zone\n" -"spécifié par un autre objet." +"Sélection de la zone à traiter.\n" +"- «Lui-même» - l'étendue du traitement est basée sur l'objet traité.\n" +"- «Sélection de zone» - clic gauche de la souris pour démarrer la sélection " +"de la zone à traiter.\n" +"- 'Objet de référence' - traitera la zone spécifiée par un autre objet." -#: flatcamGUI/PreferencesUI.py:5279 flatcamGUI/PreferencesUI.py:5654 +#: flatcamGUI/PreferencesUI.py:5601 flatcamGUI/PreferencesUI.py:6125 +#: flatcamTools/ToolNCC.py:578 flatcamTools/ToolPaint.py:522 +msgid "Shape" +msgstr "Forme" + +#: flatcamGUI/PreferencesUI.py:5603 flatcamGUI/PreferencesUI.py:6127 +#: flatcamTools/ToolNCC.py:580 flatcamTools/ToolPaint.py:524 +msgid "The kind of selection shape used for area selection." +msgstr "Type de forme de sélection utilisé pour la sélection de zone." + +#: flatcamGUI/PreferencesUI.py:5618 flatcamGUI/PreferencesUI.py:6142 msgid "Normal" msgstr "Ordinaire" -#: flatcamGUI/PreferencesUI.py:5280 flatcamGUI/PreferencesUI.py:5655 +#: flatcamGUI/PreferencesUI.py:5619 flatcamGUI/PreferencesUI.py:6143 msgid "Progressive" msgstr "Progressif" -#: flatcamGUI/PreferencesUI.py:5281 +#: flatcamGUI/PreferencesUI.py:5620 msgid "NCC Plotting" msgstr "Dessin de la NCC" -#: flatcamGUI/PreferencesUI.py:5283 +#: flatcamGUI/PreferencesUI.py:5622 msgid "" "- 'Normal' - normal plotting, done at the end of the NCC job\n" "- 'Progressive' - after each shape is generated it will be plotted." @@ -11023,16 +11434,16 @@ msgstr "" "- 'Normal' - tracé normal, effectué à la fin du travail de la NCC\n" "- 'Progressif' - après chaque forme générée, elle sera tracée." -#: flatcamGUI/PreferencesUI.py:5297 +#: flatcamGUI/PreferencesUI.py:5636 msgid "Cutout Tool Options" msgstr "Options de l'Outil de Découpe" -#: flatcamGUI/PreferencesUI.py:5312 flatcamTools/ToolCalculators.py:123 -#: flatcamTools/ToolCutOut.py:123 +#: flatcamGUI/PreferencesUI.py:5651 flatcamTools/ToolCalculators.py:123 +#: flatcamTools/ToolCutOut.py:130 msgid "Tool Diameter" msgstr "Dia de l'outil" -#: flatcamGUI/PreferencesUI.py:5314 flatcamTools/ToolCutOut.py:125 +#: flatcamGUI/PreferencesUI.py:5653 flatcamTools/ToolCutOut.py:132 msgid "" "Diameter of the tool used to cutout\n" "the PCB shape out of the surrounding material." @@ -11040,11 +11451,11 @@ msgstr "" "Diamètre de l'outil utilisé pour la découpe\n" "la forme de PCB hors du matériau environnant." -#: flatcamGUI/PreferencesUI.py:5369 flatcamTools/ToolCutOut.py:104 +#: flatcamGUI/PreferencesUI.py:5708 msgid "Object kind" msgstr "Type d'objet" -#: flatcamGUI/PreferencesUI.py:5371 flatcamTools/ToolCutOut.py:106 +#: flatcamGUI/PreferencesUI.py:5710 flatcamTools/ToolCutOut.py:78 msgid "" "Choice of what kind the object we want to cutout is.
- Single: " "contain a single PCB Gerber outline object.
- Panel: a panel PCB " @@ -11056,15 +11467,15 @@ msgstr "" "est fait\n" "sur beaucoup de contours individuels de PCB." -#: flatcamGUI/PreferencesUI.py:5378 flatcamTools/ToolCutOut.py:112 +#: flatcamGUI/PreferencesUI.py:5717 flatcamTools/ToolCutOut.py:84 msgid "Single" msgstr "Seul" -#: flatcamGUI/PreferencesUI.py:5379 flatcamTools/ToolCutOut.py:113 +#: flatcamGUI/PreferencesUI.py:5718 flatcamTools/ToolCutOut.py:85 msgid "Panel" msgstr "Panneau" -#: flatcamGUI/PreferencesUI.py:5386 flatcamTools/ToolCutOut.py:186 +#: flatcamGUI/PreferencesUI.py:5725 flatcamTools/ToolCutOut.py:193 msgid "" "Margin over bounds. A positive value here\n" "will make the cutout of the PCB further from\n" @@ -11074,11 +11485,11 @@ msgstr "" "fera la découpe du PCB plus loin de\n" "la frontière de PCB" -#: flatcamGUI/PreferencesUI.py:5399 flatcamTools/ToolCutOut.py:197 +#: flatcamGUI/PreferencesUI.py:5738 flatcamTools/ToolCutOut.py:204 msgid "Gap size" msgstr "Taille de l'espace" -#: flatcamGUI/PreferencesUI.py:5401 flatcamTools/ToolCutOut.py:199 +#: flatcamGUI/PreferencesUI.py:5740 flatcamTools/ToolCutOut.py:206 msgid "" "The size of the bridge gaps in the cutout\n" "used to keep the board connected to\n" @@ -11090,11 +11501,11 @@ msgstr "" "le matériau environnant (celui\n" "à partir duquel le circuit imprimé est découpé)." -#: flatcamGUI/PreferencesUI.py:5415 flatcamTools/ToolCutOut.py:241 +#: flatcamGUI/PreferencesUI.py:5754 flatcamTools/ToolCutOut.py:250 msgid "Gaps" msgstr "Lacunes" -#: flatcamGUI/PreferencesUI.py:5417 +#: flatcamGUI/PreferencesUI.py:5756 msgid "" "Number of gaps used for the cutout.\n" "There can be maximum 8 bridges/gaps.\n" @@ -11118,11 +11529,11 @@ msgstr "" "- 2tb - 2 * Haut + 2 * Bas\n" "- 8 - 2 * gauche + 2 * droite + 2 * en haut + 2 * en bas" -#: flatcamGUI/PreferencesUI.py:5439 flatcamTools/ToolCutOut.py:216 +#: flatcamGUI/PreferencesUI.py:5778 flatcamTools/ToolCutOut.py:223 msgid "Convex Shape" msgstr "Forme convexe" -#: flatcamGUI/PreferencesUI.py:5441 flatcamTools/ToolCutOut.py:219 +#: flatcamGUI/PreferencesUI.py:5780 flatcamTools/ToolCutOut.py:226 msgid "" "Create a convex shape surrounding the entire PCB.\n" "Used only if the source object type is Gerber." @@ -11130,11 +11541,11 @@ msgstr "" "Créez une forme convexe entourant tout le circuit imprimé.\n" "Utilisé uniquement si le type d'objet source est Gerber." -#: flatcamGUI/PreferencesUI.py:5454 +#: flatcamGUI/PreferencesUI.py:5793 msgid "2Sided Tool Options" msgstr "Options des Outils 2 faces" -#: flatcamGUI/PreferencesUI.py:5460 +#: flatcamGUI/PreferencesUI.py:5799 msgid "" "A tool to help in creating a double sided\n" "PCB using alignment holes." @@ -11142,36 +11553,41 @@ msgstr "" "Un outil pour aider à créer un double face\n" "PCB utilisant des trous d'alignement." -#: flatcamGUI/PreferencesUI.py:5474 +#: flatcamGUI/PreferencesUI.py:5813 msgid "Drill dia" msgstr "Forage dia" -#: flatcamGUI/PreferencesUI.py:5476 flatcamTools/ToolDblSided.py:274 -#: flatcamTools/ToolDblSided.py:285 +#: flatcamGUI/PreferencesUI.py:5815 flatcamTools/ToolDblSided.py:364 +#: flatcamTools/ToolDblSided.py:369 msgid "Diameter of the drill for the alignment holes." msgstr "Diamètre du foret pour les trous d'alignement." -#: flatcamGUI/PreferencesUI.py:5485 flatcamTools/ToolDblSided.py:146 -msgid "Mirror Axis:" -msgstr "Axe du miroir:" +#: flatcamGUI/PreferencesUI.py:5822 flatcamTools/ToolDblSided.py:378 +msgid "Align Axis" +msgstr "Aligner l'axe" -#: flatcamGUI/PreferencesUI.py:5487 flatcamTools/ToolDblSided.py:147 +#: flatcamGUI/PreferencesUI.py:5824 flatcamGUI/PreferencesUI.py:5837 +#: flatcamTools/ToolDblSided.py:166 flatcamTools/ToolDblSided.py:380 msgid "Mirror vertically (X) or horizontally (Y)." msgstr "Miroir verticalement (X) ou horizontalement (Y)." -#: flatcamGUI/PreferencesUI.py:5496 flatcamTools/ToolDblSided.py:156 +#: flatcamGUI/PreferencesUI.py:5835 +msgid "Mirror Axis:" +msgstr "Axe du miroir:" + +#: flatcamGUI/PreferencesUI.py:5846 flatcamTools/ToolDblSided.py:182 msgid "Point" msgstr "Point" -#: flatcamGUI/PreferencesUI.py:5497 flatcamTools/ToolDblSided.py:157 +#: flatcamGUI/PreferencesUI.py:5847 flatcamTools/ToolDblSided.py:183 msgid "Box" msgstr "Box" -#: flatcamGUI/PreferencesUI.py:5498 flatcamTools/ToolDblSided.py:158 +#: flatcamGUI/PreferencesUI.py:5848 msgid "Axis Ref" msgstr "Réf d'axe" -#: flatcamGUI/PreferencesUI.py:5500 flatcamTools/ToolDblSided.py:160 +#: flatcamGUI/PreferencesUI.py:5850 msgid "" "The axis should pass through a point or cut\n" " a specified box (in a FlatCAM object) through \n" @@ -11181,48 +11597,67 @@ msgstr "" "une zone spécifiée (dans un objet FlatCAM) via\n" "le centre." -#: flatcamGUI/PreferencesUI.py:5516 +#: flatcamGUI/PreferencesUI.py:5866 msgid "Paint Tool Options" msgstr "Options de l'Outil de Peinture" -#: flatcamGUI/PreferencesUI.py:5522 +#: flatcamGUI/PreferencesUI.py:5872 msgid "Parameters:" msgstr "Paramètres:" -#: flatcamGUI/PreferencesUI.py:5636 flatcamTools/ToolPaint.py:296 -#: flatcamTools/ToolPaint.py:313 +#: flatcamGUI/PreferencesUI.py:6086 flatcamTools/ToolPaint.py:445 msgid "" -"How to select Polygons to be painted.\n" +"If checked, use 'rest machining'.\n" +"Basically it will clear copper outside PCB features,\n" +"using the biggest tool and continue with the next tools,\n" +"from bigger to smaller, to clear areas of copper that\n" +"could not be cleared by previous tool, until there is\n" +"no more copper to clear or there are no more tools.\n" +"\n" +"If not checked, use the standard algorithm." +msgstr "" +"Si coché, utilisez 'repos usining'.\n" +"Fondamentalement, il nettoiera le cuivre en dehors des circuits imprimés,\n" +"en utilisant le plus gros outil et continuer avec les outils suivants,\n" +"du plus grand au plus petit, pour nettoyer les zones de cuivre\n" +"ne pouvait pas être effacé par l’outil précédent, jusqu’à ce que\n" +"plus de cuivre à nettoyer ou il n'y a plus d'outils.\n" +"\n" +"Si non coché, utilisez l'algorithme standard." + +#: flatcamGUI/PreferencesUI.py:6099 flatcamTools/ToolPaint.py:458 +msgid "" +"Selection of area to be processed.\n" "- 'Polygon Selection' - left mouse click to add/remove polygons to be " -"painted.\n" +"processed.\n" "- 'Area Selection' - left mouse click to start selection of the area to be " -"painted.\n" +"processed.\n" "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple " "areas.\n" -"- 'All Polygons' - the Paint will start after click.\n" -"- 'Reference Object' - will do non copper clearing within the area\n" -"specified by another object." +"- 'All Polygons' - the process will start after click.\n" +"- 'Reference Object' - will process the area specified by another object." msgstr "" -"Comment sélectionner les polygones à peindre.\n" -"- 'Sélection de polygone' - clic gauche de la souris pour ajouter / " -"supprimer des polygones à peindre.\n" +"Sélection de la zone à traiter.\n" +"- «Sélection de polygone» - clic gauche de la souris pour ajouter / " +"supprimer des polygones à traiter.\n" "- «Sélection de zone» - clic gauche de la souris pour démarrer la sélection " -"de la zone à peindre.\n" -"Maintenir une touche de modification enfoncée (CTRL ou SHIFT) permettra " +"de la zone à traiter.\n" +"Maintenir une touche de modification enfoncée (CTRL ou MAJ) permettra " "d'ajouter plusieurs zones.\n" -"- «Tous les polygones» - la peinture démarre après le clic.\n" -"- «Objet de référence» - effectuera un nettoyage sans cuivre dans la zone\n" -"spécifié par un autre objet." +"- «Tous les polygones» - le processus démarrera après le clic.\n" +"- «Objet de reference» - traitera la zone spécifiée par un autre objet." -#: flatcamGUI/PreferencesUI.py:5645 -msgid "Sel" -msgstr "Sél" +#: flatcamGUI/PreferencesUI.py:6119 flatcamTools/ToolPaint.py:486 +#: flatcamTools/ToolPaint.py:942 flatcamTools/ToolPaint.py:1427 +#: tclCommands/TclCommandPaint.py:164 +msgid "Polygon Selection" +msgstr "Sélection de polygone" -#: flatcamGUI/PreferencesUI.py:5656 +#: flatcamGUI/PreferencesUI.py:6144 msgid "Paint Plotting" msgstr "Peinture dessin" -#: flatcamGUI/PreferencesUI.py:5658 +#: flatcamGUI/PreferencesUI.py:6146 msgid "" "- 'Normal' - normal plotting, done at the end of the Paint job\n" "- 'Progressive' - after each shape is generated it will be plotted." @@ -11230,11 +11665,11 @@ msgstr "" "- 'Normal' - traçage normal, effectué à la fin du travail de peinture\n" "- 'Progressif' - après chaque forme générée, elle sera tracée." -#: flatcamGUI/PreferencesUI.py:5672 +#: flatcamGUI/PreferencesUI.py:6160 msgid "Film Tool Options" msgstr "Options de l'Outil de Film" -#: flatcamGUI/PreferencesUI.py:5678 +#: flatcamGUI/PreferencesUI.py:6166 msgid "" "Create a PCB film from a Gerber or Geometry\n" "FlatCAM object.\n" @@ -11244,11 +11679,11 @@ msgstr "" "Objet FlatCAM.\n" "Le fichier est enregistré au format SVG." -#: flatcamGUI/PreferencesUI.py:5689 +#: flatcamGUI/PreferencesUI.py:6177 msgid "Film Type" msgstr "Type de Film" -#: flatcamGUI/PreferencesUI.py:5691 flatcamTools/ToolFilm.py:300 +#: flatcamGUI/PreferencesUI.py:6179 flatcamTools/ToolFilm.py:300 msgid "" "Generate a Positive black film or a Negative film.\n" "Positive means that it will print the features\n" @@ -11264,19 +11699,19 @@ msgstr "" "avec du blanc sur une toile noire.\n" "Le format de film est SVG." -#: flatcamGUI/PreferencesUI.py:5702 +#: flatcamGUI/PreferencesUI.py:6190 msgid "Film Color" msgstr "Couleur du film" -#: flatcamGUI/PreferencesUI.py:5704 +#: flatcamGUI/PreferencesUI.py:6192 msgid "Set the film color when positive film is selected." msgstr "Définissez la couleur du film lorsque le film positif est sélectionné." -#: flatcamGUI/PreferencesUI.py:5727 flatcamTools/ToolFilm.py:316 +#: flatcamGUI/PreferencesUI.py:6215 flatcamTools/ToolFilm.py:316 msgid "Border" msgstr "Bordure" -#: flatcamGUI/PreferencesUI.py:5729 flatcamTools/ToolFilm.py:318 +#: flatcamGUI/PreferencesUI.py:6217 flatcamTools/ToolFilm.py:318 msgid "" "Specify a border around the object.\n" "Only for negative film.\n" @@ -11296,11 +11731,11 @@ msgstr "" "couleur blanche comme le reste et qui peut confondre avec le\n" "environnement si pas pour cette frontière." -#: flatcamGUI/PreferencesUI.py:5746 flatcamTools/ToolFilm.py:283 +#: flatcamGUI/PreferencesUI.py:6234 flatcamTools/ToolFilm.py:283 msgid "Scale Stroke" msgstr "Course de l'échelle" -#: flatcamGUI/PreferencesUI.py:5748 flatcamTools/ToolFilm.py:285 +#: flatcamGUI/PreferencesUI.py:6236 flatcamTools/ToolFilm.py:285 msgid "" "Scale the line stroke thickness of each feature in the SVG file.\n" "It means that the line that envelope each SVG feature will be thicker or " @@ -11313,11 +11748,11 @@ msgstr "" "par conséquent, les caractéristiques fines peuvent être plus affectées par " "ce paramètre." -#: flatcamGUI/PreferencesUI.py:5755 flatcamTools/ToolFilm.py:141 +#: flatcamGUI/PreferencesUI.py:6243 flatcamTools/ToolFilm.py:141 msgid "Film Adjustments" msgstr "Ajustements de film" -#: flatcamGUI/PreferencesUI.py:5757 flatcamTools/ToolFilm.py:143 +#: flatcamGUI/PreferencesUI.py:6245 flatcamTools/ToolFilm.py:143 msgid "" "Sometime the printers will distort the print shape, especially the Laser " "types.\n" @@ -11328,11 +11763,11 @@ msgstr "" "Cette section fournit les outils permettant de compenser les distorsions " "d’impression." -#: flatcamGUI/PreferencesUI.py:5764 flatcamTools/ToolFilm.py:150 +#: flatcamGUI/PreferencesUI.py:6252 flatcamTools/ToolFilm.py:150 msgid "Scale Film geometry" msgstr "Mettre à l'échelle la géo du film" -#: flatcamGUI/PreferencesUI.py:5766 flatcamTools/ToolFilm.py:152 +#: flatcamGUI/PreferencesUI.py:6254 flatcamTools/ToolFilm.py:152 msgid "" "A value greater than 1 will stretch the film\n" "while a value less than 1 will jolt it." @@ -11340,21 +11775,21 @@ msgstr "" "Une valeur supérieure à 1 étendra le film\n" "alors qu'une valeur inférieure à 1 la secouera." -#: flatcamGUI/PreferencesUI.py:5776 flatcamGUI/PreferencesUI.py:6296 -#: flatcamTools/ToolFilm.py:162 flatcamTools/ToolTransform.py:148 +#: flatcamGUI/PreferencesUI.py:6264 flatcamGUI/PreferencesUI.py:6783 +#: flatcamTools/ToolFilm.py:162 flatcamTools/ToolTransform.py:149 msgid "X factor" msgstr "Facteur X" -#: flatcamGUI/PreferencesUI.py:5785 flatcamGUI/PreferencesUI.py:6309 +#: flatcamGUI/PreferencesUI.py:6273 flatcamGUI/PreferencesUI.py:6796 #: flatcamTools/ToolFilm.py:171 flatcamTools/ToolTransform.py:169 msgid "Y factor" msgstr "Facteur Y" -#: flatcamGUI/PreferencesUI.py:5795 flatcamTools/ToolFilm.py:189 +#: flatcamGUI/PreferencesUI.py:6283 flatcamTools/ToolFilm.py:189 msgid "Skew Film geometry" msgstr "Inclinez la géo du film" -#: flatcamGUI/PreferencesUI.py:5797 flatcamTools/ToolFilm.py:191 +#: flatcamGUI/PreferencesUI.py:6285 flatcamTools/ToolFilm.py:191 msgid "" "Positive values will skew to the right\n" "while negative values will skew to the left." @@ -11362,17 +11797,17 @@ msgstr "" "Les valeurs positives seront biaisées vers la droite\n" "tandis que les valeurs négatives inclineront vers la gauche." -#: flatcamGUI/PreferencesUI.py:5807 flatcamGUI/PreferencesUI.py:6265 +#: flatcamGUI/PreferencesUI.py:6295 flatcamGUI/PreferencesUI.py:6752 #: flatcamTools/ToolFilm.py:201 flatcamTools/ToolTransform.py:98 msgid "X angle" msgstr "Angle X" -#: flatcamGUI/PreferencesUI.py:5816 flatcamGUI/PreferencesUI.py:6279 -#: flatcamTools/ToolFilm.py:210 flatcamTools/ToolTransform.py:120 +#: flatcamGUI/PreferencesUI.py:6304 flatcamGUI/PreferencesUI.py:6766 +#: flatcamTools/ToolFilm.py:210 flatcamTools/ToolTransform.py:119 msgid "Y angle" msgstr "Angle Y" -#: flatcamGUI/PreferencesUI.py:5827 flatcamTools/ToolFilm.py:221 +#: flatcamGUI/PreferencesUI.py:6315 flatcamTools/ToolFilm.py:221 msgid "" "The reference point to be used as origin for the skew.\n" "It can be one of the four points of the geometry bounding box." @@ -11380,57 +11815,53 @@ msgstr "" "Le point de référence à utiliser comme origine pour l'inclinaison.\n" "Ce peut être l'un des quatre points de la boîte englobante de la géométrie." -#: flatcamGUI/PreferencesUI.py:5830 flatcamTools/ToolFiducials.py:87 +#: flatcamGUI/PreferencesUI.py:6318 flatcamTools/ToolFiducials.py:87 #: flatcamTools/ToolFilm.py:224 msgid "Bottom Left" msgstr "En bas à gauche" -#: flatcamGUI/PreferencesUI.py:5831 flatcamTools/ToolFilm.py:225 +#: flatcamGUI/PreferencesUI.py:6319 flatcamTools/ToolFilm.py:225 msgid "Top Left" msgstr "En haut à gauche" -#: flatcamGUI/PreferencesUI.py:5832 flatcamTools/ToolFilm.py:226 +#: flatcamGUI/PreferencesUI.py:6320 flatcamTools/ToolFilm.py:226 msgid "Bottom Right" msgstr "En bas à droite" -#: flatcamGUI/PreferencesUI.py:5833 flatcamTools/ToolFilm.py:227 +#: flatcamGUI/PreferencesUI.py:6321 flatcamTools/ToolFilm.py:227 msgid "Top right" msgstr "En haut à droite" -#: flatcamGUI/PreferencesUI.py:5841 flatcamTools/ToolFilm.py:244 +#: flatcamGUI/PreferencesUI.py:6329 flatcamTools/ToolFilm.py:244 msgid "Mirror Film geometry" msgstr "Refléter la géo du film" -#: flatcamGUI/PreferencesUI.py:5843 flatcamTools/ToolFilm.py:246 +#: flatcamGUI/PreferencesUI.py:6331 flatcamTools/ToolFilm.py:246 msgid "Mirror the film geometry on the selected axis or on both." msgstr "Reflétez la géométrie du film sur l'axe sélectionné ou sur les deux." -#: flatcamGUI/PreferencesUI.py:5855 flatcamTools/ToolFilm.py:258 -msgid "Both" -msgstr "Tous les deux" - -#: flatcamGUI/PreferencesUI.py:5857 flatcamTools/ToolFilm.py:260 +#: flatcamGUI/PreferencesUI.py:6345 flatcamTools/ToolFilm.py:260 msgid "Mirror axis" msgstr "Axe du miroir" -#: flatcamGUI/PreferencesUI.py:5867 flatcamTools/ToolFilm.py:403 +#: flatcamGUI/PreferencesUI.py:6355 flatcamTools/ToolFilm.py:405 msgid "SVG" msgstr "SVG" -#: flatcamGUI/PreferencesUI.py:5868 flatcamTools/ToolFilm.py:404 +#: flatcamGUI/PreferencesUI.py:6356 flatcamTools/ToolFilm.py:406 msgid "PNG" msgstr "PNG" -#: flatcamGUI/PreferencesUI.py:5869 flatcamTools/ToolFilm.py:405 +#: flatcamGUI/PreferencesUI.py:6357 flatcamTools/ToolFilm.py:407 msgid "PDF" msgstr "PDF" -#: flatcamGUI/PreferencesUI.py:5872 flatcamTools/ToolFilm.py:298 -#: flatcamTools/ToolFilm.py:408 +#: flatcamGUI/PreferencesUI.py:6360 flatcamTools/ToolFilm.py:298 +#: flatcamTools/ToolFilm.py:410 msgid "Film Type:" msgstr "Type de Film:" -#: flatcamGUI/PreferencesUI.py:5874 flatcamTools/ToolFilm.py:410 +#: flatcamGUI/PreferencesUI.py:6362 flatcamTools/ToolFilm.py:412 msgid "" "The file type of the saved film. Can be:\n" "- 'SVG' -> open-source vectorial format\n" @@ -11442,23 +11873,23 @@ msgstr "" "- 'PNG' -> image raster\n" "- 'PDF' -> format de document portable" -#: flatcamGUI/PreferencesUI.py:5883 flatcamTools/ToolFilm.py:419 +#: flatcamGUI/PreferencesUI.py:6371 flatcamTools/ToolFilm.py:421 msgid "Page Orientation" msgstr "Orientation de la page" -#: flatcamGUI/PreferencesUI.py:5896 flatcamTools/ToolFilm.py:432 +#: flatcamGUI/PreferencesUI.py:6384 flatcamTools/ToolFilm.py:434 msgid "Page Size" msgstr "Taille de la page" -#: flatcamGUI/PreferencesUI.py:5897 flatcamTools/ToolFilm.py:433 +#: flatcamGUI/PreferencesUI.py:6385 flatcamTools/ToolFilm.py:435 msgid "A selection of standard ISO 216 page sizes." msgstr "Une sélection de formats de page ISO 216 standard." -#: flatcamGUI/PreferencesUI.py:5969 +#: flatcamGUI/PreferencesUI.py:6457 msgid "Panelize Tool Options" msgstr "Options de l'Outil Panéliser" -#: flatcamGUI/PreferencesUI.py:5975 +#: flatcamGUI/PreferencesUI.py:6463 msgid "" "Create an object that contains an array of (x, y) elements,\n" "each element is a copy of the source object spaced\n" @@ -11468,11 +11899,11 @@ msgstr "" "chaque élément est une copie de l'objet source espacé\n" "à une distance X, Y distance les uns des autres." -#: flatcamGUI/PreferencesUI.py:5992 flatcamTools/ToolPanelize.py:160 +#: flatcamGUI/PreferencesUI.py:6480 flatcamTools/ToolPanelize.py:163 msgid "Spacing cols" msgstr "Colonnes d'espacement" -#: flatcamGUI/PreferencesUI.py:5994 flatcamTools/ToolPanelize.py:162 +#: flatcamGUI/PreferencesUI.py:6482 flatcamTools/ToolPanelize.py:165 msgid "" "Spacing between columns of the desired panel.\n" "In current units." @@ -11480,11 +11911,11 @@ msgstr "" "Espacement entre les colonnes du panneau souhaité.\n" "En unités actuelles." -#: flatcamGUI/PreferencesUI.py:6006 flatcamTools/ToolPanelize.py:172 +#: flatcamGUI/PreferencesUI.py:6494 flatcamTools/ToolPanelize.py:175 msgid "Spacing rows" msgstr "Lignes d'espacement" -#: flatcamGUI/PreferencesUI.py:6008 flatcamTools/ToolPanelize.py:174 +#: flatcamGUI/PreferencesUI.py:6496 flatcamTools/ToolPanelize.py:177 msgid "" "Spacing between rows of the desired panel.\n" "In current units." @@ -11492,36 +11923,31 @@ msgstr "" "Espacement entre les lignes du panneau souhaité.\n" "En unités actuelles." -#: flatcamGUI/PreferencesUI.py:6019 flatcamTools/ToolPanelize.py:183 +#: flatcamGUI/PreferencesUI.py:6507 flatcamTools/ToolPanelize.py:186 msgid "Columns" msgstr "Colonnes" -#: flatcamGUI/PreferencesUI.py:6021 flatcamTools/ToolPanelize.py:185 +#: flatcamGUI/PreferencesUI.py:6509 flatcamTools/ToolPanelize.py:188 msgid "Number of columns of the desired panel" msgstr "Nombre de colonnes du panneau désiré" -#: flatcamGUI/PreferencesUI.py:6031 flatcamTools/ToolPanelize.py:193 +#: flatcamGUI/PreferencesUI.py:6519 flatcamTools/ToolPanelize.py:196 msgid "Rows" msgstr "Lignes" -#: flatcamGUI/PreferencesUI.py:6033 flatcamTools/ToolPanelize.py:195 +#: flatcamGUI/PreferencesUI.py:6521 flatcamTools/ToolPanelize.py:198 msgid "Number of rows of the desired panel" msgstr "Nombre de lignes du panneau désiré" -#: flatcamGUI/PreferencesUI.py:6039 flatcamTools/ToolCalibration.py:196 -#: flatcamTools/ToolCalibration.py:634 flatcamTools/ToolPanelize.py:201 -msgid "Gerber" -msgstr "Gerber" - -#: flatcamGUI/PreferencesUI.py:6040 flatcamTools/ToolPanelize.py:202 +#: flatcamGUI/PreferencesUI.py:6528 flatcamTools/ToolPanelize.py:205 msgid "Geo" msgstr "Géo" -#: flatcamGUI/PreferencesUI.py:6041 flatcamTools/ToolPanelize.py:203 +#: flatcamGUI/PreferencesUI.py:6529 flatcamTools/ToolPanelize.py:206 msgid "Panel Type" msgstr "Type de Panneau" -#: flatcamGUI/PreferencesUI.py:6043 +#: flatcamGUI/PreferencesUI.py:6531 msgid "" "Choose the type of object for the panel object:\n" "- Gerber\n" @@ -11531,11 +11957,11 @@ msgstr "" "- Gerber\n" "- Géométrie" -#: flatcamGUI/PreferencesUI.py:6052 +#: flatcamGUI/PreferencesUI.py:6540 msgid "Constrain within" msgstr "Contraindre à l'intérieur" -#: flatcamGUI/PreferencesUI.py:6054 flatcamTools/ToolPanelize.py:215 +#: flatcamGUI/PreferencesUI.py:6542 flatcamTools/ToolPanelize.py:218 msgid "" "Area define by DX and DY within to constrain the panel.\n" "DX and DY values are in current units.\n" @@ -11549,11 +11975,11 @@ msgstr "" "le panneau final aura autant de colonnes et de lignes que\n" "ils correspondent parfaitement à la zone sélectionnée." -#: flatcamGUI/PreferencesUI.py:6067 flatcamTools/ToolPanelize.py:227 +#: flatcamGUI/PreferencesUI.py:6555 flatcamTools/ToolPanelize.py:230 msgid "Width (DX)" msgstr "Largeur (DX)" -#: flatcamGUI/PreferencesUI.py:6069 flatcamTools/ToolPanelize.py:229 +#: flatcamGUI/PreferencesUI.py:6557 flatcamTools/ToolPanelize.py:232 msgid "" "The width (DX) within which the panel must fit.\n" "In current units." @@ -11561,11 +11987,11 @@ msgstr "" "La largeur (DX) dans laquelle le panneau doit tenir.\n" "En unités actuelles." -#: flatcamGUI/PreferencesUI.py:6080 flatcamTools/ToolPanelize.py:238 +#: flatcamGUI/PreferencesUI.py:6568 flatcamTools/ToolPanelize.py:241 msgid "Height (DY)" msgstr "Hauteur (DY)" -#: flatcamGUI/PreferencesUI.py:6082 flatcamTools/ToolPanelize.py:240 +#: flatcamGUI/PreferencesUI.py:6570 flatcamTools/ToolPanelize.py:243 msgid "" "The height (DY)within which the panel must fit.\n" "In current units." @@ -11573,15 +11999,15 @@ msgstr "" "La hauteur (DY) à laquelle le panneau doit s’adapter.\n" "En unités actuelles." -#: flatcamGUI/PreferencesUI.py:6096 +#: flatcamGUI/PreferencesUI.py:6584 msgid "Calculators Tool Options" msgstr "Options de l'Outil Calcul" -#: flatcamGUI/PreferencesUI.py:6100 flatcamTools/ToolCalculators.py:25 +#: flatcamGUI/PreferencesUI.py:6588 flatcamTools/ToolCalculators.py:25 msgid "V-Shape Tool Calculator" msgstr "Calculateur d'Outils en V" -#: flatcamGUI/PreferencesUI.py:6102 +#: flatcamGUI/PreferencesUI.py:6590 msgid "" "Calculate the tool diameter for a given V-shape tool,\n" "having the tip diameter, tip angle and\n" @@ -11591,11 +12017,11 @@ msgstr "" "ayant le diamètre de la pointe, son angle et\n" "profondeur de coupe en tant que paramètres." -#: flatcamGUI/PreferencesUI.py:6117 flatcamTools/ToolCalculators.py:94 +#: flatcamGUI/PreferencesUI.py:6607 flatcamTools/ToolCalculators.py:94 msgid "Tip Diameter" msgstr "Dia de la pointe" -#: flatcamGUI/PreferencesUI.py:6119 flatcamTools/ToolCalculators.py:102 +#: flatcamGUI/PreferencesUI.py:6609 flatcamTools/ToolCalculators.py:102 msgid "" "This is the tool tip diameter.\n" "It is specified by manufacturer." @@ -11603,11 +12029,11 @@ msgstr "" "C'est le diamètre de la pointe de l'outil.\n" "Il est spécifié par le fabricant." -#: flatcamGUI/PreferencesUI.py:6131 flatcamTools/ToolCalculators.py:105 +#: flatcamGUI/PreferencesUI.py:6621 flatcamTools/ToolCalculators.py:105 msgid "Tip Angle" msgstr "Angle de pointe" -#: flatcamGUI/PreferencesUI.py:6133 +#: flatcamGUI/PreferencesUI.py:6623 msgid "" "This is the angle on the tip of the tool.\n" "It is specified by manufacturer." @@ -11615,7 +12041,7 @@ msgstr "" "C'est l'angle sur la pointe de l'outil.\n" "Il est spécifié par le fabricant." -#: flatcamGUI/PreferencesUI.py:6147 +#: flatcamGUI/PreferencesUI.py:6637 msgid "" "This is depth to cut into material.\n" "In the CNCJob object it is the CutZ parameter." @@ -11623,11 +12049,11 @@ msgstr "" "C'est la profondeur à couper dans le matériau.\n" "Dans l'objet CNCJob, il s'agit du paramètre CutZ." -#: flatcamGUI/PreferencesUI.py:6154 flatcamTools/ToolCalculators.py:27 +#: flatcamGUI/PreferencesUI.py:6644 flatcamTools/ToolCalculators.py:27 msgid "ElectroPlating Calculator" msgstr "Calculateur d'électrodéposition" -#: flatcamGUI/PreferencesUI.py:6156 flatcamTools/ToolCalculators.py:158 +#: flatcamGUI/PreferencesUI.py:6646 flatcamTools/ToolCalculators.py:158 msgid "" "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 " @@ -11638,27 +12064,27 @@ msgstr "" "en utilisant une méthode comme l’encre grahite, l’encre hypophosphite de " "calcium ou le chlorure de palladium." -#: flatcamGUI/PreferencesUI.py:6170 flatcamTools/ToolCalculators.py:167 +#: flatcamGUI/PreferencesUI.py:6657 flatcamTools/ToolCalculators.py:167 msgid "Board Length" msgstr "Longueur" -#: flatcamGUI/PreferencesUI.py:6172 flatcamTools/ToolCalculators.py:173 +#: flatcamGUI/PreferencesUI.py:6659 flatcamTools/ToolCalculators.py:173 msgid "This is the board length. In centimeters." msgstr "Ceci est la longueur du conseil. En centimètres." -#: flatcamGUI/PreferencesUI.py:6182 flatcamTools/ToolCalculators.py:175 +#: flatcamGUI/PreferencesUI.py:6669 flatcamTools/ToolCalculators.py:175 msgid "Board Width" msgstr "Largeur" -#: flatcamGUI/PreferencesUI.py:6184 flatcamTools/ToolCalculators.py:181 +#: flatcamGUI/PreferencesUI.py:6671 flatcamTools/ToolCalculators.py:181 msgid "This is the board width.In centimeters." msgstr "C'est la largeur de la planche.En centimètres." -#: flatcamGUI/PreferencesUI.py:6189 flatcamTools/ToolCalculators.py:183 +#: flatcamGUI/PreferencesUI.py:6676 flatcamTools/ToolCalculators.py:183 msgid "Current Density" msgstr "Densité de courant" -#: flatcamGUI/PreferencesUI.py:6195 flatcamTools/ToolCalculators.py:190 +#: flatcamGUI/PreferencesUI.py:6682 flatcamTools/ToolCalculators.py:190 msgid "" "Current density to pass through the board. \n" "In Amps per Square Feet ASF." @@ -11666,11 +12092,11 @@ msgstr "" "Densité de courant électrique à traverser le tableau.\n" "En ampères par pieds carrés ASF." -#: flatcamGUI/PreferencesUI.py:6201 flatcamTools/ToolCalculators.py:193 +#: flatcamGUI/PreferencesUI.py:6688 flatcamTools/ToolCalculators.py:193 msgid "Copper Growth" msgstr "Croissance du cuivre" -#: flatcamGUI/PreferencesUI.py:6207 flatcamTools/ToolCalculators.py:200 +#: flatcamGUI/PreferencesUI.py:6694 flatcamTools/ToolCalculators.py:200 msgid "" "How thick the copper growth is intended to be.\n" "In microns." @@ -11678,11 +12104,11 @@ msgstr "" "Quelle épaisseur doit avoir la croissance du cuivre.\n" "En microns." -#: flatcamGUI/PreferencesUI.py:6220 +#: flatcamGUI/PreferencesUI.py:6707 msgid "Transform Tool Options" msgstr "Options de l'Outil de Transformation" -#: flatcamGUI/PreferencesUI.py:6226 +#: flatcamGUI/PreferencesUI.py:6713 msgid "" "Various transformations that can be applied\n" "on a FlatCAM object." @@ -11690,19 +12116,19 @@ msgstr "" "Diverses transformations pouvant être appliquées\n" "sur un objet FlatCAM." -#: flatcamGUI/PreferencesUI.py:6257 +#: flatcamGUI/PreferencesUI.py:6744 msgid "Skew" msgstr "Fausser" -#: flatcamGUI/PreferencesUI.py:6298 flatcamTools/ToolTransform.py:150 +#: flatcamGUI/PreferencesUI.py:6785 flatcamTools/ToolTransform.py:151 msgid "Factor for scaling on X axis." msgstr "Facteur de mise à l'échelle sur l'axe X." -#: flatcamGUI/PreferencesUI.py:6311 flatcamTools/ToolTransform.py:171 +#: flatcamGUI/PreferencesUI.py:6798 flatcamTools/ToolTransform.py:171 msgid "Factor for scaling on Y axis." msgstr "Facteur de mise à l'échelle sur l'axe Y." -#: flatcamGUI/PreferencesUI.py:6319 flatcamTools/ToolTransform.py:194 +#: flatcamGUI/PreferencesUI.py:6806 flatcamTools/ToolTransform.py:192 msgid "" "Scale the selected object(s)\n" "using the Scale_X factor for both axis." @@ -11710,7 +12136,7 @@ msgstr "" "Mettre à l'échelle le ou les objets sélectionnés\n" "en utilisant le facteur d'échelle X pour les deux axes." -#: flatcamGUI/PreferencesUI.py:6327 flatcamTools/ToolTransform.py:202 +#: flatcamGUI/PreferencesUI.py:6814 flatcamTools/ToolTransform.py:199 msgid "" "Scale the selected object(s)\n" "using the origin reference when checked,\n" @@ -11722,32 +12148,32 @@ msgstr "" "et le centre de la plus grande boîte englobante\n" "des objets sélectionnés lorsqu'il est décoché." -#: flatcamGUI/PreferencesUI.py:6343 flatcamTools/ToolTransform.py:217 +#: flatcamGUI/PreferencesUI.py:6830 flatcamTools/ToolTransform.py:218 msgid "X val" msgstr "Valeur X" -#: flatcamGUI/PreferencesUI.py:6345 flatcamTools/ToolTransform.py:219 +#: flatcamGUI/PreferencesUI.py:6832 flatcamTools/ToolTransform.py:220 msgid "Distance to offset on X axis. In current units." msgstr "Distance à compenser sur l'axe X. En unités actuelles." -#: flatcamGUI/PreferencesUI.py:6356 flatcamTools/ToolTransform.py:238 +#: flatcamGUI/PreferencesUI.py:6843 flatcamTools/ToolTransform.py:238 msgid "Y val" msgstr "Valeur Y" -#: flatcamGUI/PreferencesUI.py:6358 flatcamTools/ToolTransform.py:240 +#: flatcamGUI/PreferencesUI.py:6845 flatcamTools/ToolTransform.py:240 msgid "Distance to offset on Y axis. In current units." msgstr "Distance à compenser sur l'axe X. En unités actuelles." -#: flatcamGUI/PreferencesUI.py:6364 flatcamTools/ToolDblSided.py:62 -#: flatcamTools/ToolDblSided.py:90 flatcamTools/ToolDblSided.py:120 +#: flatcamGUI/PreferencesUI.py:6851 flatcamTools/ToolDblSided.py:68 +#: flatcamTools/ToolDblSided.py:96 flatcamTools/ToolDblSided.py:126 msgid "Mirror" msgstr "Miroir" -#: flatcamGUI/PreferencesUI.py:6368 flatcamTools/ToolTransform.py:285 +#: flatcamGUI/PreferencesUI.py:6855 flatcamTools/ToolTransform.py:284 msgid "Mirror Reference" msgstr "Référence du miroir" -#: flatcamGUI/PreferencesUI.py:6370 flatcamTools/ToolTransform.py:287 +#: flatcamGUI/PreferencesUI.py:6857 flatcamTools/ToolTransform.py:286 msgid "" "Flip the selected object(s)\n" "around the point in Point Entry Field.\n" @@ -11769,11 +12195,11 @@ msgstr "" "Ou entrez les coordonnées au format (x, y) dans le champ\n" "Pointez sur le champ Entrée et cliquez sur Basculer sur X (Y)." -#: flatcamGUI/PreferencesUI.py:6381 +#: flatcamGUI/PreferencesUI.py:6868 msgid "Mirror Reference point" msgstr "Miroir Point de référence" -#: flatcamGUI/PreferencesUI.py:6383 +#: flatcamGUI/PreferencesUI.py:6870 msgid "" "Coordinates in format (x, y) used as reference for mirroring.\n" "The 'x' in (x, y) will be used when using Flip on X and\n" @@ -11784,12 +12210,12 @@ msgstr "" "Le \"x\" dans (x, y) sera utilisé lors de l'utilisation de Flip sur X et\n" "le 'y' dans (x, y) sera utilisé lors de l'utilisation de Flip sur Y et" -#: flatcamGUI/PreferencesUI.py:6396 flatcamTools/ToolDistance.py:355 -#: flatcamTools/ToolDistanceMin.py:284 flatcamTools/ToolTransform.py:332 +#: flatcamGUI/PreferencesUI.py:6883 flatcamTools/ToolDistance.py:496 +#: flatcamTools/ToolDistanceMin.py:287 flatcamTools/ToolTransform.py:333 msgid "Distance" msgstr "Distance" -#: flatcamGUI/PreferencesUI.py:6398 flatcamTools/ToolTransform.py:334 +#: flatcamGUI/PreferencesUI.py:6885 flatcamTools/ToolTransform.py:335 msgid "" "A positive value will create the effect of dilation,\n" "while a negative value will create the effect of erosion.\n" @@ -11801,12 +12227,26 @@ msgstr "" "Chaque élément de géométrie de l'objet sera augmenté\n" "ou diminué avec la «distance»." -#: flatcamGUI/PreferencesUI.py:6414 flatcamGUI/PreferencesUI.py:7057 -#: flatcamTools/ToolQRCode.py:197 flatcamTools/ToolTransform.py:361 +#: flatcamGUI/PreferencesUI.py:6902 flatcamTools/ToolTransform.py:360 +msgid "" +"A positive value will create the effect of dilation,\n" +"while a negative value will create the effect of erosion.\n" +"Each geometry element of the object will be increased\n" +"or decreased to fit the 'Value'. Value is a percentage\n" +"of the initial dimension." +msgstr "" +"Une valeur positive créera l'effet de dilatation,\n" +"tandis qu'une valeur négative créera l'effet de l'érosion.\n" +"Chaque élément de géométrie de l'objet sera augmenté\n" +"ou diminué pour correspondre à la «valeur». La valeur est un pourcentage\n" +"de la dimension initiale." + +#: flatcamGUI/PreferencesUI.py:6919 flatcamGUI/PreferencesUI.py:7563 +#: flatcamTools/ToolQRCode.py:197 flatcamTools/ToolTransform.py:384 msgid "Rounded" msgstr "Arrondi" -#: flatcamGUI/PreferencesUI.py:6416 flatcamTools/ToolTransform.py:363 +#: flatcamGUI/PreferencesUI.py:6921 flatcamTools/ToolTransform.py:386 msgid "" "If checked then the buffer will surround the buffered shape,\n" "every corner will be rounded.\n" @@ -11818,11 +12258,11 @@ msgstr "" "S'il n'est pas coché, le tampon suivra la géométrie exacte\n" "de la forme tamponnée." -#: flatcamGUI/PreferencesUI.py:6434 +#: flatcamGUI/PreferencesUI.py:6938 msgid "SolderPaste Tool Options" msgstr "Options de l'Outil Pâte à souder" -#: flatcamGUI/PreferencesUI.py:6440 +#: flatcamGUI/PreferencesUI.py:6944 msgid "" "A tool to create GCode for dispensing\n" "solder paste onto a PCB." @@ -11830,47 +12270,43 @@ msgstr "" "Un outil pour créer le GCode pour la distribution\n" "souder la pâte sur un PCB." -#: flatcamGUI/PreferencesUI.py:6451 -msgid "Diameters of nozzle tools, separated by ','" -msgstr "Diamètres des outils de buse, séparés par ','" - -#: flatcamGUI/PreferencesUI.py:6459 +#: flatcamGUI/PreferencesUI.py:6965 msgid "New Nozzle Dia" msgstr "Nouvelle Buse Dia" -#: flatcamGUI/PreferencesUI.py:6461 flatcamTools/ToolSolderPaste.py:106 +#: flatcamGUI/PreferencesUI.py:6967 flatcamTools/ToolSolderPaste.py:108 msgid "Diameter for the new Nozzle tool to add in the Tool Table" msgstr "Diamètre du nouvel outil Buse à ajouter dans le tableau des outils" -#: flatcamGUI/PreferencesUI.py:6477 flatcamTools/ToolSolderPaste.py:182 +#: flatcamGUI/PreferencesUI.py:6983 flatcamTools/ToolSolderPaste.py:184 msgid "Z Dispense Start" msgstr "Z début de la distribution" -#: flatcamGUI/PreferencesUI.py:6479 flatcamTools/ToolSolderPaste.py:184 +#: flatcamGUI/PreferencesUI.py:6985 flatcamTools/ToolSolderPaste.py:186 msgid "The height (Z) when solder paste dispensing starts." msgstr "La hauteur (Z) au début de la distribution de la pâte à braser." -#: flatcamGUI/PreferencesUI.py:6490 flatcamTools/ToolSolderPaste.py:194 +#: flatcamGUI/PreferencesUI.py:6996 flatcamTools/ToolSolderPaste.py:196 msgid "Z Dispense" msgstr "Z dispenser" -#: flatcamGUI/PreferencesUI.py:6492 flatcamTools/ToolSolderPaste.py:196 +#: flatcamGUI/PreferencesUI.py:6998 flatcamTools/ToolSolderPaste.py:198 msgid "The height (Z) when doing solder paste dispensing." msgstr "La hauteur (Z) lors de la distribution de la pâte à braser." -#: flatcamGUI/PreferencesUI.py:6503 flatcamTools/ToolSolderPaste.py:206 +#: flatcamGUI/PreferencesUI.py:7009 flatcamTools/ToolSolderPaste.py:208 msgid "Z Dispense Stop" msgstr "Z arrêt de distribution" -#: flatcamGUI/PreferencesUI.py:6505 flatcamTools/ToolSolderPaste.py:208 +#: flatcamGUI/PreferencesUI.py:7011 flatcamTools/ToolSolderPaste.py:210 msgid "The height (Z) when solder paste dispensing stops." msgstr "La hauteur (Z) lorsque la distribution de la pâte à braser s’arrête." -#: flatcamGUI/PreferencesUI.py:6516 flatcamTools/ToolSolderPaste.py:218 +#: flatcamGUI/PreferencesUI.py:7022 flatcamTools/ToolSolderPaste.py:220 msgid "Z Travel" msgstr "Z Voyage" -#: flatcamGUI/PreferencesUI.py:6518 flatcamTools/ToolSolderPaste.py:220 +#: flatcamGUI/PreferencesUI.py:7024 flatcamTools/ToolSolderPaste.py:222 msgid "" "The height (Z) for travel between pads\n" "(without dispensing solder paste)." @@ -11878,15 +12314,15 @@ msgstr "" "La hauteur (Z) pour le déplacement entre les patins\n" "(sans distribution de pâte à braser)." -#: flatcamGUI/PreferencesUI.py:6530 flatcamTools/ToolSolderPaste.py:231 +#: flatcamGUI/PreferencesUI.py:7036 flatcamTools/ToolSolderPaste.py:233 msgid "Z Toolchange" msgstr "Changement d'outil Z" -#: flatcamGUI/PreferencesUI.py:6532 flatcamTools/ToolSolderPaste.py:233 +#: flatcamGUI/PreferencesUI.py:7038 flatcamTools/ToolSolderPaste.py:235 msgid "The height (Z) for tool (nozzle) change." msgstr "La hauteur (Z) de l'outil (buse) change." -#: flatcamGUI/PreferencesUI.py:6541 flatcamTools/ToolSolderPaste.py:241 +#: flatcamGUI/PreferencesUI.py:7047 flatcamTools/ToolSolderPaste.py:243 msgid "" "The X,Y location for tool (nozzle) change.\n" "The format is (x, y) where x and y are real numbers." @@ -11894,11 +12330,11 @@ msgstr "" "L'emplacement X, Y de l'outil (buse) change.\n" "Le format est (x, y) où x et y sont des nombres réels." -#: flatcamGUI/PreferencesUI.py:6555 flatcamTools/ToolSolderPaste.py:254 +#: flatcamGUI/PreferencesUI.py:7061 flatcamTools/ToolSolderPaste.py:256 msgid "Feedrate (speed) while moving on the X-Y plane." msgstr "Avance (vitesse) en se déplaçant sur le plan X-Y." -#: flatcamGUI/PreferencesUI.py:6568 flatcamTools/ToolSolderPaste.py:266 +#: flatcamGUI/PreferencesUI.py:7074 flatcamTools/ToolSolderPaste.py:268 msgid "" "Feedrate (speed) while moving vertically\n" "(on Z plane)." @@ -11906,11 +12342,11 @@ msgstr "" "Avance (vitesse) en se déplaçant verticalement\n" "(sur le plan Z)." -#: flatcamGUI/PreferencesUI.py:6580 flatcamTools/ToolSolderPaste.py:277 +#: flatcamGUI/PreferencesUI.py:7086 flatcamTools/ToolSolderPaste.py:279 msgid "Feedrate Z Dispense" msgstr "Avance Z Distribution" -#: flatcamGUI/PreferencesUI.py:6582 +#: flatcamGUI/PreferencesUI.py:7088 msgid "" "Feedrate (speed) while moving up vertically\n" "to Dispense position (on Z plane)." @@ -11918,11 +12354,11 @@ msgstr "" "Avance (vitesse) en montant verticalement\n" "position de distribution (sur le plan Z)." -#: flatcamGUI/PreferencesUI.py:6593 flatcamTools/ToolSolderPaste.py:289 +#: flatcamGUI/PreferencesUI.py:7099 flatcamTools/ToolSolderPaste.py:291 msgid "Spindle Speed FWD" msgstr "Vitesse de Rot FWD" -#: flatcamGUI/PreferencesUI.py:6595 flatcamTools/ToolSolderPaste.py:291 +#: flatcamGUI/PreferencesUI.py:7101 flatcamTools/ToolSolderPaste.py:293 msgid "" "The dispenser speed while pushing solder paste\n" "through the dispenser nozzle." @@ -11930,19 +12366,19 @@ msgstr "" "La vitesse du distributeur en poussant la pâte à souder\n" "à travers la buse du distributeur." -#: flatcamGUI/PreferencesUI.py:6607 flatcamTools/ToolSolderPaste.py:302 +#: flatcamGUI/PreferencesUI.py:7113 flatcamTools/ToolSolderPaste.py:304 msgid "Dwell FWD" msgstr "Habiter AVANT" -#: flatcamGUI/PreferencesUI.py:6609 flatcamTools/ToolSolderPaste.py:304 +#: flatcamGUI/PreferencesUI.py:7115 flatcamTools/ToolSolderPaste.py:306 msgid "Pause after solder dispensing." msgstr "Pause après la distribution de la brasure." -#: flatcamGUI/PreferencesUI.py:6619 flatcamTools/ToolSolderPaste.py:313 +#: flatcamGUI/PreferencesUI.py:7125 flatcamTools/ToolSolderPaste.py:315 msgid "Spindle Speed REV" msgstr "Vitesse du moteur en REV" -#: flatcamGUI/PreferencesUI.py:6621 flatcamTools/ToolSolderPaste.py:315 +#: flatcamGUI/PreferencesUI.py:7127 flatcamTools/ToolSolderPaste.py:317 msgid "" "The dispenser speed while retracting solder paste\n" "through the dispenser nozzle." @@ -11950,11 +12386,11 @@ msgstr "" "La vitesse du distributeur lors du retrait de la pâte à souder\n" "à travers la buse du distributeur." -#: flatcamGUI/PreferencesUI.py:6633 flatcamTools/ToolSolderPaste.py:326 +#: flatcamGUI/PreferencesUI.py:7139 flatcamTools/ToolSolderPaste.py:328 msgid "Dwell REV" msgstr "Habiter INVERSE" -#: flatcamGUI/PreferencesUI.py:6635 flatcamTools/ToolSolderPaste.py:328 +#: flatcamGUI/PreferencesUI.py:7141 flatcamTools/ToolSolderPaste.py:330 msgid "" "Pause after solder paste dispenser retracted,\n" "to allow pressure equilibrium." @@ -11962,15 +12398,15 @@ msgstr "" "Pause après rétraction du distributeur de pâte à souder,\n" "permettre l'équilibre de la pression." -#: flatcamGUI/PreferencesUI.py:6644 flatcamTools/ToolSolderPaste.py:336 +#: flatcamGUI/PreferencesUI.py:7150 flatcamTools/ToolSolderPaste.py:338 msgid "Files that control the GCode generation." msgstr "Fichiers qui contrôlent la génération de GCode." -#: flatcamGUI/PreferencesUI.py:6659 +#: flatcamGUI/PreferencesUI.py:7165 msgid "Substractor Tool Options" msgstr "Options de l'Outil Soustracteur" -#: flatcamGUI/PreferencesUI.py:6665 +#: flatcamGUI/PreferencesUI.py:7171 msgid "" "A tool to substract one Gerber or Geometry object\n" "from another of the same type." @@ -11978,22 +12414,22 @@ msgstr "" "Un outil pour soustraire un objet Gerber ou Geometry\n" "d'un autre du même type." -#: flatcamGUI/PreferencesUI.py:6670 flatcamTools/ToolSub.py:149 +#: flatcamGUI/PreferencesUI.py:7176 flatcamTools/ToolSub.py:155 msgid "Close paths" msgstr "Fermer les chemins" -#: flatcamGUI/PreferencesUI.py:6671 +#: flatcamGUI/PreferencesUI.py:7177 msgid "" "Checking this will close the paths cut by the Geometry substractor object." msgstr "" "En cochant cette case, vous fermez les chemins coupés par l'objet " "soustracteur de géométrie." -#: flatcamGUI/PreferencesUI.py:6682 +#: flatcamGUI/PreferencesUI.py:7188 msgid "Check Rules Tool Options" msgstr "Options de l'outil de Vérif. des Règles" -#: flatcamGUI/PreferencesUI.py:6687 +#: flatcamGUI/PreferencesUI.py:7193 msgid "" "A tool to check if Gerber files are within a set\n" "of Manufacturing Rules." @@ -12001,38 +12437,38 @@ msgstr "" "Un outil pour vérifier si les fichiers Gerber sont dans un ensemble\n" "des règles de fabrication." -#: flatcamGUI/PreferencesUI.py:6697 flatcamTools/ToolRulesCheck.py:256 -#: flatcamTools/ToolRulesCheck.py:920 +#: flatcamGUI/PreferencesUI.py:7203 flatcamTools/ToolRulesCheck.py:265 +#: flatcamTools/ToolRulesCheck.py:929 msgid "Trace Size" msgstr "Taille de trace" -#: flatcamGUI/PreferencesUI.py:6699 flatcamTools/ToolRulesCheck.py:258 +#: flatcamGUI/PreferencesUI.py:7205 flatcamTools/ToolRulesCheck.py:267 msgid "This checks if the minimum size for traces is met." msgstr "Ceci vérifie si la taille minimale des traces est respectée." -#: flatcamGUI/PreferencesUI.py:6709 flatcamGUI/PreferencesUI.py:6729 -#: flatcamGUI/PreferencesUI.py:6749 flatcamGUI/PreferencesUI.py:6769 -#: flatcamGUI/PreferencesUI.py:6789 flatcamGUI/PreferencesUI.py:6809 -#: flatcamGUI/PreferencesUI.py:6829 flatcamGUI/PreferencesUI.py:6849 -#: flatcamGUI/PreferencesUI.py:6871 flatcamGUI/PreferencesUI.py:6891 -#: flatcamTools/ToolRulesCheck.py:268 flatcamTools/ToolRulesCheck.py:290 -#: flatcamTools/ToolRulesCheck.py:313 flatcamTools/ToolRulesCheck.py:336 -#: flatcamTools/ToolRulesCheck.py:359 flatcamTools/ToolRulesCheck.py:382 -#: flatcamTools/ToolRulesCheck.py:405 flatcamTools/ToolRulesCheck.py:428 -#: flatcamTools/ToolRulesCheck.py:453 flatcamTools/ToolRulesCheck.py:476 +#: flatcamGUI/PreferencesUI.py:7215 flatcamGUI/PreferencesUI.py:7235 +#: flatcamGUI/PreferencesUI.py:7255 flatcamGUI/PreferencesUI.py:7275 +#: flatcamGUI/PreferencesUI.py:7295 flatcamGUI/PreferencesUI.py:7315 +#: flatcamGUI/PreferencesUI.py:7335 flatcamGUI/PreferencesUI.py:7355 +#: flatcamGUI/PreferencesUI.py:7377 flatcamGUI/PreferencesUI.py:7397 +#: flatcamTools/ToolRulesCheck.py:277 flatcamTools/ToolRulesCheck.py:299 +#: flatcamTools/ToolRulesCheck.py:322 flatcamTools/ToolRulesCheck.py:345 +#: flatcamTools/ToolRulesCheck.py:368 flatcamTools/ToolRulesCheck.py:391 +#: flatcamTools/ToolRulesCheck.py:414 flatcamTools/ToolRulesCheck.py:437 +#: flatcamTools/ToolRulesCheck.py:462 flatcamTools/ToolRulesCheck.py:485 msgid "Min value" msgstr "Valeur min" -#: flatcamGUI/PreferencesUI.py:6711 flatcamTools/ToolRulesCheck.py:270 +#: flatcamGUI/PreferencesUI.py:7217 flatcamTools/ToolRulesCheck.py:279 msgid "Minimum acceptable trace size." msgstr "Taille de trace minimale acceptable." -#: flatcamGUI/PreferencesUI.py:6716 flatcamTools/ToolRulesCheck.py:277 -#: flatcamTools/ToolRulesCheck.py:1148 flatcamTools/ToolRulesCheck.py:1178 +#: flatcamGUI/PreferencesUI.py:7222 flatcamTools/ToolRulesCheck.py:286 +#: flatcamTools/ToolRulesCheck.py:1157 flatcamTools/ToolRulesCheck.py:1187 msgid "Copper to Copper clearance" msgstr "Distance de cuivre à cuivre" -#: flatcamGUI/PreferencesUI.py:6718 flatcamTools/ToolRulesCheck.py:279 +#: flatcamGUI/PreferencesUI.py:7224 flatcamTools/ToolRulesCheck.py:288 msgid "" "This checks if the minimum clearance between copper\n" "features is met." @@ -12040,23 +12476,23 @@ msgstr "" "Ceci vérifie si le jeu minimum entre le cuivre\n" "traces est rencontré." -#: flatcamGUI/PreferencesUI.py:6731 flatcamGUI/PreferencesUI.py:6751 -#: flatcamGUI/PreferencesUI.py:6771 flatcamGUI/PreferencesUI.py:6791 -#: flatcamGUI/PreferencesUI.py:6811 flatcamGUI/PreferencesUI.py:6831 -#: flatcamGUI/PreferencesUI.py:6893 flatcamTools/ToolRulesCheck.py:292 -#: flatcamTools/ToolRulesCheck.py:315 flatcamTools/ToolRulesCheck.py:338 -#: flatcamTools/ToolRulesCheck.py:361 flatcamTools/ToolRulesCheck.py:384 -#: flatcamTools/ToolRulesCheck.py:407 flatcamTools/ToolRulesCheck.py:455 +#: flatcamGUI/PreferencesUI.py:7237 flatcamGUI/PreferencesUI.py:7257 +#: flatcamGUI/PreferencesUI.py:7277 flatcamGUI/PreferencesUI.py:7297 +#: flatcamGUI/PreferencesUI.py:7317 flatcamGUI/PreferencesUI.py:7337 +#: flatcamGUI/PreferencesUI.py:7399 flatcamTools/ToolRulesCheck.py:301 +#: flatcamTools/ToolRulesCheck.py:324 flatcamTools/ToolRulesCheck.py:347 +#: flatcamTools/ToolRulesCheck.py:370 flatcamTools/ToolRulesCheck.py:393 +#: flatcamTools/ToolRulesCheck.py:416 flatcamTools/ToolRulesCheck.py:464 msgid "Minimum acceptable clearance value." msgstr "Distance minimale acceptable." -#: flatcamGUI/PreferencesUI.py:6736 flatcamTools/ToolRulesCheck.py:300 -#: flatcamTools/ToolRulesCheck.py:1208 flatcamTools/ToolRulesCheck.py:1214 -#: flatcamTools/ToolRulesCheck.py:1227 flatcamTools/ToolRulesCheck.py:1234 +#: flatcamGUI/PreferencesUI.py:7242 flatcamTools/ToolRulesCheck.py:309 +#: flatcamTools/ToolRulesCheck.py:1217 flatcamTools/ToolRulesCheck.py:1223 +#: flatcamTools/ToolRulesCheck.py:1236 flatcamTools/ToolRulesCheck.py:1243 msgid "Copper to Outline clearance" msgstr "Cuivre à la distance de contour" -#: flatcamGUI/PreferencesUI.py:6738 flatcamTools/ToolRulesCheck.py:302 +#: flatcamGUI/PreferencesUI.py:7244 flatcamTools/ToolRulesCheck.py:311 msgid "" "This checks if the minimum clearance between copper\n" "features and the outline is met." @@ -12064,11 +12500,11 @@ msgstr "" "Ceci vérifie si la distance minimale entre le cuivre\n" "traces et le contour est rencontré." -#: flatcamGUI/PreferencesUI.py:6756 flatcamTools/ToolRulesCheck.py:323 +#: flatcamGUI/PreferencesUI.py:7262 flatcamTools/ToolRulesCheck.py:332 msgid "Silk to Silk Clearance" msgstr "Sérigraphie à sérigraphie distance" -#: flatcamGUI/PreferencesUI.py:6758 flatcamTools/ToolRulesCheck.py:325 +#: flatcamGUI/PreferencesUI.py:7264 flatcamTools/ToolRulesCheck.py:334 msgid "" "This checks if the minimum clearance between silkscreen\n" "features and silkscreen features is met." @@ -12076,13 +12512,13 @@ msgstr "" "Ceci vérifie si la distance minimale entre sérigraphie\n" "les fonctionnalités et les fonctions de sérigraphie sont remplies." -#: flatcamGUI/PreferencesUI.py:6776 flatcamTools/ToolRulesCheck.py:346 -#: flatcamTools/ToolRulesCheck.py:1317 flatcamTools/ToolRulesCheck.py:1323 -#: flatcamTools/ToolRulesCheck.py:1341 +#: flatcamGUI/PreferencesUI.py:7282 flatcamTools/ToolRulesCheck.py:355 +#: flatcamTools/ToolRulesCheck.py:1326 flatcamTools/ToolRulesCheck.py:1332 +#: flatcamTools/ToolRulesCheck.py:1350 msgid "Silk to Solder Mask Clearance" msgstr "Distance de sérigraphie à masque de soudure" -#: flatcamGUI/PreferencesUI.py:6778 flatcamTools/ToolRulesCheck.py:348 +#: flatcamGUI/PreferencesUI.py:7284 flatcamTools/ToolRulesCheck.py:357 msgid "" "This checks if the minimum clearance between silkscreen\n" "features and soldermask features is met." @@ -12090,13 +12526,13 @@ msgstr "" "Ceci vérifie si la distance minimale entre sérigraphie\n" "les fonctionnalités et les fonctionnalités soldermask sont remplies." -#: flatcamGUI/PreferencesUI.py:6796 flatcamTools/ToolRulesCheck.py:369 -#: flatcamTools/ToolRulesCheck.py:1371 flatcamTools/ToolRulesCheck.py:1377 -#: flatcamTools/ToolRulesCheck.py:1391 flatcamTools/ToolRulesCheck.py:1398 +#: flatcamGUI/PreferencesUI.py:7302 flatcamTools/ToolRulesCheck.py:378 +#: flatcamTools/ToolRulesCheck.py:1380 flatcamTools/ToolRulesCheck.py:1386 +#: flatcamTools/ToolRulesCheck.py:1400 flatcamTools/ToolRulesCheck.py:1407 msgid "Silk to Outline Clearance" msgstr "Sérigraphie à contour distance" -#: flatcamGUI/PreferencesUI.py:6798 flatcamTools/ToolRulesCheck.py:371 +#: flatcamGUI/PreferencesUI.py:7304 flatcamTools/ToolRulesCheck.py:380 msgid "" "This checks if the minimum clearance between silk\n" "features and the outline is met." @@ -12104,12 +12540,12 @@ msgstr "" "Ceci vérifie si la distance minimale entre sérigraphie\n" "traces et le contour est rencontré." -#: flatcamGUI/PreferencesUI.py:6816 flatcamTools/ToolRulesCheck.py:392 -#: flatcamTools/ToolRulesCheck.py:1409 flatcamTools/ToolRulesCheck.py:1436 +#: flatcamGUI/PreferencesUI.py:7322 flatcamTools/ToolRulesCheck.py:401 +#: flatcamTools/ToolRulesCheck.py:1418 flatcamTools/ToolRulesCheck.py:1445 msgid "Minimum Solder Mask Sliver" msgstr "Ruban de masque de soudure minimum" -#: flatcamGUI/PreferencesUI.py:6818 flatcamTools/ToolRulesCheck.py:394 +#: flatcamGUI/PreferencesUI.py:7324 flatcamTools/ToolRulesCheck.py:403 msgid "" "This checks if the minimum clearance between soldermask\n" "features and soldermask features is met." @@ -12117,13 +12553,13 @@ msgstr "" "Cette vérifie si la distance minimale entre soldermask\n" "traces et soldermask traces est rencontré." -#: flatcamGUI/PreferencesUI.py:6836 flatcamTools/ToolRulesCheck.py:415 -#: flatcamTools/ToolRulesCheck.py:1474 flatcamTools/ToolRulesCheck.py:1480 -#: flatcamTools/ToolRulesCheck.py:1496 flatcamTools/ToolRulesCheck.py:1503 +#: flatcamGUI/PreferencesUI.py:7342 flatcamTools/ToolRulesCheck.py:424 +#: flatcamTools/ToolRulesCheck.py:1483 flatcamTools/ToolRulesCheck.py:1489 +#: flatcamTools/ToolRulesCheck.py:1505 flatcamTools/ToolRulesCheck.py:1512 msgid "Minimum Annular Ring" msgstr "Anneau Minimum" -#: flatcamGUI/PreferencesUI.py:6838 flatcamTools/ToolRulesCheck.py:417 +#: flatcamGUI/PreferencesUI.py:7344 flatcamTools/ToolRulesCheck.py:426 msgid "" "This checks if the minimum copper ring left by drilling\n" "a hole into a pad is met." @@ -12131,16 +12567,16 @@ msgstr "" "Ceci vérifie si l'anneau de cuivre minimum laissé par le forage\n" "un trou dans un pad est rencontré." -#: flatcamGUI/PreferencesUI.py:6851 flatcamTools/ToolRulesCheck.py:430 +#: flatcamGUI/PreferencesUI.py:7357 flatcamTools/ToolRulesCheck.py:439 msgid "Minimum acceptable ring value." msgstr "Valeur de sonnerie minimale acceptable." -#: flatcamGUI/PreferencesUI.py:6858 flatcamTools/ToolRulesCheck.py:440 -#: flatcamTools/ToolRulesCheck.py:864 +#: flatcamGUI/PreferencesUI.py:7364 flatcamTools/ToolRulesCheck.py:449 +#: flatcamTools/ToolRulesCheck.py:873 msgid "Hole to Hole Clearance" msgstr "Distance trou à trou" -#: flatcamGUI/PreferencesUI.py:6860 flatcamTools/ToolRulesCheck.py:442 +#: flatcamGUI/PreferencesUI.py:7366 flatcamTools/ToolRulesCheck.py:451 msgid "" "This checks if the minimum clearance between a drill hole\n" "and another drill hole is met." @@ -12148,16 +12584,16 @@ msgstr "" "Ceci vérifie si le jeu minimum entre un trou de forage\n" "et un autre trou de forage est rencontré." -#: flatcamGUI/PreferencesUI.py:6873 flatcamTools/ToolRulesCheck.py:478 +#: flatcamGUI/PreferencesUI.py:7379 flatcamTools/ToolRulesCheck.py:487 msgid "Minimum acceptable drill size." msgstr "Taille minimale acceptable du foret." -#: flatcamGUI/PreferencesUI.py:6878 flatcamTools/ToolRulesCheck.py:463 -#: flatcamTools/ToolRulesCheck.py:838 +#: flatcamGUI/PreferencesUI.py:7384 flatcamTools/ToolRulesCheck.py:472 +#: flatcamTools/ToolRulesCheck.py:847 msgid "Hole Size" msgstr "Taille du trou" -#: flatcamGUI/PreferencesUI.py:6880 flatcamTools/ToolRulesCheck.py:465 +#: flatcamGUI/PreferencesUI.py:7386 flatcamTools/ToolRulesCheck.py:474 msgid "" "This checks if the drill holes\n" "sizes are above the threshold." @@ -12165,11 +12601,11 @@ msgstr "" "Ceci vérifie si les trous de forage\n" "les tailles sont au dessus du seuil." -#: flatcamGUI/PreferencesUI.py:6905 +#: flatcamGUI/PreferencesUI.py:7411 msgid "Optimal Tool Options" msgstr "Options de l'outil 'Optimal'" -#: flatcamGUI/PreferencesUI.py:6911 +#: flatcamGUI/PreferencesUI.py:7417 msgid "" "A tool to find the minimum distance between\n" "every two Gerber geometric elements" @@ -12177,20 +12613,20 @@ msgstr "" "Un outil pour trouver la distance minimale entre\n" "tous les deux éléments géométriques de Gerber" -#: flatcamGUI/PreferencesUI.py:6926 flatcamTools/ToolOptimal.py:78 +#: flatcamGUI/PreferencesUI.py:7432 flatcamTools/ToolOptimal.py:79 msgid "Precision" msgstr "Précision" -#: flatcamGUI/PreferencesUI.py:6928 +#: flatcamGUI/PreferencesUI.py:7434 msgid "Number of decimals for the distances and coordinates in this tool." msgstr "" "Nombre de décimales pour les distances et les coordonnées dans cet outil." -#: flatcamGUI/PreferencesUI.py:6942 +#: flatcamGUI/PreferencesUI.py:7448 msgid "QRCode Tool Options" msgstr "Options de l'outil QRCode" -#: flatcamGUI/PreferencesUI.py:6948 +#: flatcamGUI/PreferencesUI.py:7454 msgid "" "A tool to create a QRCode that can be inserted\n" "into a selected Gerber file, or it can be exported as a file." @@ -12199,11 +12635,11 @@ msgstr "" "dans un fichier Gerber sélectionné, ou il peut être exporté en tant que " "fichier." -#: flatcamGUI/PreferencesUI.py:6960 flatcamTools/ToolQRCode.py:99 +#: flatcamGUI/PreferencesUI.py:7466 flatcamTools/ToolQRCode.py:100 msgid "Version" msgstr "Version" -#: flatcamGUI/PreferencesUI.py:6962 flatcamTools/ToolQRCode.py:101 +#: flatcamGUI/PreferencesUI.py:7468 flatcamTools/ToolQRCode.py:102 msgid "" "QRCode version can have values from 1 (21x21 boxes)\n" "to 40 (177x177 boxes)." @@ -12211,12 +12647,12 @@ msgstr "" "La version QRCode peut avoir des valeurs de 1 (éléments 21x21)\n" "jusqu'à 40 (éléments 177x177)." -#: flatcamGUI/PreferencesUI.py:6973 flatcamTools/ToolQRCode.py:112 +#: flatcamGUI/PreferencesUI.py:7479 flatcamTools/ToolQRCode.py:113 msgid "Error correction" msgstr "Correction des erreurs" -#: flatcamGUI/PreferencesUI.py:6975 flatcamGUI/PreferencesUI.py:6986 -#: flatcamTools/ToolQRCode.py:114 flatcamTools/ToolQRCode.py:125 +#: flatcamGUI/PreferencesUI.py:7481 flatcamGUI/PreferencesUI.py:7492 +#: flatcamTools/ToolQRCode.py:115 flatcamTools/ToolQRCode.py:126 #, python-format msgid "" "Parameter that controls the error correction used for the QR Code.\n" @@ -12231,11 +12667,11 @@ msgstr "" "Q = 25 %% maximum d'erreurs peuvent être corrigées\n" "H = maximum 30 %% d'erreurs peuvent être corrigées." -#: flatcamGUI/PreferencesUI.py:6996 flatcamTools/ToolQRCode.py:135 +#: flatcamGUI/PreferencesUI.py:7502 flatcamTools/ToolQRCode.py:136 msgid "Box Size" msgstr "Taille d'élément" -#: flatcamGUI/PreferencesUI.py:6998 flatcamTools/ToolQRCode.py:137 +#: flatcamGUI/PreferencesUI.py:7504 flatcamTools/ToolQRCode.py:138 msgid "" "Box size control the overall size of the QRcode\n" "by adjusting the size of each box in the code." @@ -12243,11 +12679,11 @@ msgstr "" "La taille de l'élément contrôle la taille globale du QRcode\n" "en ajustant la taille de chaque case du code." -#: flatcamGUI/PreferencesUI.py:7009 flatcamTools/ToolQRCode.py:148 +#: flatcamGUI/PreferencesUI.py:7515 flatcamTools/ToolQRCode.py:149 msgid "Border Size" msgstr "Taille de bordure" -#: flatcamGUI/PreferencesUI.py:7011 flatcamTools/ToolQRCode.py:150 +#: flatcamGUI/PreferencesUI.py:7517 flatcamTools/ToolQRCode.py:151 msgid "" "Size of the QRCode border. How many boxes thick is the border.\n" "Default value is 4. The width of the clearance around the QRCode." @@ -12255,23 +12691,23 @@ msgstr "" "Taille de la bordure QRCode. Combien d'éléments sont épais la bordure.\n" "La valeur par défaut est 4. La largeur du jeu autour du QRCode." -#: flatcamGUI/PreferencesUI.py:7022 flatcamTools/ToolQRCode.py:162 +#: flatcamGUI/PreferencesUI.py:7528 flatcamTools/ToolQRCode.py:162 msgid "QRCode Data" msgstr "Données QRCode" -#: flatcamGUI/PreferencesUI.py:7024 flatcamTools/ToolQRCode.py:164 +#: flatcamGUI/PreferencesUI.py:7530 flatcamTools/ToolQRCode.py:164 msgid "QRCode Data. Alphanumeric text to be encoded in the QRCode." msgstr "Données QRCode. Texte alphanumérique à encoder dans le QRCode." -#: flatcamGUI/PreferencesUI.py:7028 flatcamTools/ToolQRCode.py:168 +#: flatcamGUI/PreferencesUI.py:7534 flatcamTools/ToolQRCode.py:168 msgid "Add here the text to be included in the QRCode..." msgstr "Ajoutez ici le texte à inclure dans le QRCode ..." -#: flatcamGUI/PreferencesUI.py:7034 flatcamTools/ToolQRCode.py:174 +#: flatcamGUI/PreferencesUI.py:7540 flatcamTools/ToolQRCode.py:174 msgid "Polarity" msgstr "Polarité" -#: flatcamGUI/PreferencesUI.py:7036 flatcamTools/ToolQRCode.py:176 +#: flatcamGUI/PreferencesUI.py:7542 flatcamTools/ToolQRCode.py:176 msgid "" "Choose the polarity of the QRCode.\n" "It can be drawn in a negative way (squares are clear)\n" @@ -12281,17 +12717,17 @@ msgstr "" "Il peut être dessiné de manière négative (les carrés sont clairs)\n" "ou d'une manière positive (les carrés sont opaques)." -#: flatcamGUI/PreferencesUI.py:7040 flatcamTools/ToolFilm.py:296 +#: flatcamGUI/PreferencesUI.py:7546 flatcamTools/ToolFilm.py:296 #: flatcamTools/ToolQRCode.py:180 msgid "Negative" msgstr "Négatif" -#: flatcamGUI/PreferencesUI.py:7041 flatcamTools/ToolFilm.py:295 +#: flatcamGUI/PreferencesUI.py:7547 flatcamTools/ToolFilm.py:295 #: flatcamTools/ToolQRCode.py:181 msgid "Positive" msgstr "Positif" -#: flatcamGUI/PreferencesUI.py:7043 flatcamTools/ToolQRCode.py:183 +#: flatcamGUI/PreferencesUI.py:7549 flatcamTools/ToolQRCode.py:183 msgid "" "Choose the type of QRCode to be created.\n" "If added on a Silkscreen Gerber file the QRCode may\n" @@ -12303,7 +12739,7 @@ msgstr "" "être ajouté comme positif. S'il est ajouté à un Gerber de cuivre\n" "fichier alors peut-être le QRCode peut être ajouté comme négatif." -#: flatcamGUI/PreferencesUI.py:7054 flatcamGUI/PreferencesUI.py:7060 +#: flatcamGUI/PreferencesUI.py:7560 flatcamGUI/PreferencesUI.py:7566 #: flatcamTools/ToolQRCode.py:194 flatcamTools/ToolQRCode.py:200 msgid "" "The bounding box, meaning the empty space that surrounds\n" @@ -12312,27 +12748,27 @@ msgstr "" "La boîte englobante, ce qui signifie l'espace vide qui entoure\n" "la géométrie QRCode, peut avoir une forme arrondie ou carrée." -#: flatcamGUI/PreferencesUI.py:7067 flatcamTools/ToolQRCode.py:228 +#: flatcamGUI/PreferencesUI.py:7573 flatcamTools/ToolQRCode.py:228 msgid "Fill Color" msgstr "La couleur de remplissage" -#: flatcamGUI/PreferencesUI.py:7069 flatcamTools/ToolQRCode.py:230 +#: flatcamGUI/PreferencesUI.py:7575 flatcamTools/ToolQRCode.py:230 msgid "Set the QRCode fill color (squares color)." msgstr "Définissez la couleur de remplissage QRCode (couleur des éléments)." -#: flatcamGUI/PreferencesUI.py:7088 flatcamTools/ToolQRCode.py:252 +#: flatcamGUI/PreferencesUI.py:7594 flatcamTools/ToolQRCode.py:252 msgid "Back Color" msgstr "Couleur de fond" -#: flatcamGUI/PreferencesUI.py:7090 flatcamTools/ToolQRCode.py:254 +#: flatcamGUI/PreferencesUI.py:7596 flatcamTools/ToolQRCode.py:254 msgid "Set the QRCode background color." msgstr "Définissez la couleur d'arrière-plan QRCode." -#: flatcamGUI/PreferencesUI.py:7130 +#: flatcamGUI/PreferencesUI.py:7636 msgid "Copper Thieving Tool Options" msgstr "Options d'outils de Copper Thieving" -#: flatcamGUI/PreferencesUI.py:7142 +#: flatcamGUI/PreferencesUI.py:7648 msgid "" "A tool to generate a Copper Thieving that can be added\n" "to a selected Gerber file." @@ -12340,16 +12776,16 @@ msgstr "" "Un outil pour générer un Copper Thieving qui peut être ajouté\n" "dans un fichier Gerber sélectionné." -#: flatcamGUI/PreferencesUI.py:7150 +#: flatcamGUI/PreferencesUI.py:7656 msgid "Number of steps (lines) used to interpolate circles." msgstr "Nombre d'étapes (lignes) utilisées pour interpoler les cercles." -#: flatcamGUI/PreferencesUI.py:7160 flatcamGUI/PreferencesUI.py:7364 -#: flatcamTools/ToolCopperThieving.py:96 flatcamTools/ToolCopperThieving.py:429 +#: flatcamGUI/PreferencesUI.py:7666 flatcamGUI/PreferencesUI.py:7870 +#: flatcamTools/ToolCopperThieving.py:97 flatcamTools/ToolCopperThieving.py:432 msgid "Clearance" msgstr "Dégagement" -#: flatcamGUI/PreferencesUI.py:7162 +#: flatcamGUI/PreferencesUI.py:7668 msgid "" "This set the distance between the copper Thieving components\n" "(the polygon fill may be split in multiple polygons)\n" @@ -12359,22 +12795,11 @@ msgstr "" "(le remplissage du polygone peut être divisé en plusieurs polygones)\n" "et les traces de cuivre dans le fichier Gerber." -#: flatcamGUI/PreferencesUI.py:7190 flatcamTools/ToolCopperThieving.py:126 -#: flatcamTools/ToolNonCopperClear.py:430 flatcamTools/ToolPaint.py:308 -msgid "Area Selection" -msgstr "Sélection de zone" - -#: flatcamGUI/PreferencesUI.py:7191 flatcamTools/ToolCopperThieving.py:127 -#: flatcamTools/ToolNonCopperClear.py:431 flatcamTools/ToolPaint.py:310 -msgid "Reference Object" -msgstr "Objet de référence" - -#: flatcamGUI/PreferencesUI.py:7193 flatcamTools/ToolCopperThieving.py:129 -#: flatcamTools/ToolNonCopperClear.py:433 +#: flatcamGUI/PreferencesUI.py:7699 flatcamTools/ToolCopperThieving.py:130 msgid "Reference:" msgstr "Référence:" -#: flatcamGUI/PreferencesUI.py:7195 +#: flatcamGUI/PreferencesUI.py:7701 msgid "" "- 'Itself' - the copper Thieving extent is based on the object extent.\n" "- 'Area Selection' - left mouse click to start selection of the area to be " @@ -12389,20 +12814,24 @@ msgstr "" "- «Objet de référence» - effectuera un vol de cuivre dans la zone spécifiée " "par un autre objet." -#: flatcamGUI/PreferencesUI.py:7204 flatcamTools/ToolCopperThieving.py:170 +#: flatcamGUI/PreferencesUI.py:7710 flatcamGUI/PreferencesUI.py:8175 +#: flatcamGUI/PreferencesUI.py:8287 flatcamGUI/PreferencesUI.py:8387 +#: flatcamGUI/PreferencesUI.py:8501 flatcamTools/ToolCopperThieving.py:172 +#: flatcamTools/ToolExtractDrills.py:102 flatcamTools/ToolExtractDrills.py:240 +#: flatcamTools/ToolPunchGerber.py:113 flatcamTools/ToolPunchGerber.py:268 msgid "Rectangular" msgstr "Rectangulaire" -#: flatcamGUI/PreferencesUI.py:7205 flatcamTools/ToolCopperThieving.py:171 +#: flatcamGUI/PreferencesUI.py:7711 flatcamTools/ToolCopperThieving.py:173 msgid "Minimal" msgstr "Minimal" -#: flatcamGUI/PreferencesUI.py:7207 flatcamTools/ToolCopperThieving.py:173 +#: flatcamGUI/PreferencesUI.py:7713 flatcamTools/ToolCopperThieving.py:175 #: flatcamTools/ToolFilm.py:113 msgid "Box Type:" msgstr "Type de Box:" -#: flatcamGUI/PreferencesUI.py:7209 flatcamTools/ToolCopperThieving.py:175 +#: flatcamGUI/PreferencesUI.py:7715 flatcamTools/ToolCopperThieving.py:177 msgid "" "- 'Rectangular' - the bounding box will be of rectangular shape.\n" "- 'Minimal' - the bounding box will be the convex hull shape." @@ -12410,23 +12839,23 @@ msgstr "" "- 'Rectangulaire' - le cadre de délimitation sera de forme rectangulaire.\n" "- 'Minimal' - le cadre de délimitation aura la forme d'une coque convexe." -#: flatcamGUI/PreferencesUI.py:7223 flatcamTools/ToolCopperThieving.py:191 +#: flatcamGUI/PreferencesUI.py:7729 flatcamTools/ToolCopperThieving.py:193 msgid "Dots Grid" msgstr "Grille de points" -#: flatcamGUI/PreferencesUI.py:7224 flatcamTools/ToolCopperThieving.py:192 +#: flatcamGUI/PreferencesUI.py:7730 flatcamTools/ToolCopperThieving.py:194 msgid "Squares Grid" msgstr "Grille de carrés" -#: flatcamGUI/PreferencesUI.py:7225 flatcamTools/ToolCopperThieving.py:193 +#: flatcamGUI/PreferencesUI.py:7731 flatcamTools/ToolCopperThieving.py:195 msgid "Lines Grid" msgstr "Grille de lignes" -#: flatcamGUI/PreferencesUI.py:7227 flatcamTools/ToolCopperThieving.py:195 +#: flatcamGUI/PreferencesUI.py:7733 flatcamTools/ToolCopperThieving.py:197 msgid "Fill Type:" msgstr "Type de remplissage:" -#: flatcamGUI/PreferencesUI.py:7229 flatcamTools/ToolCopperThieving.py:197 +#: flatcamGUI/PreferencesUI.py:7735 flatcamTools/ToolCopperThieving.py:199 msgid "" "- 'Solid' - copper thieving will be a solid polygon.\n" "- 'Dots Grid' - the empty area will be filled with a pattern of dots.\n" @@ -12438,54 +12867,54 @@ msgstr "" "- 'Grille de carrés' - la zone vide sera remplie d'un motif de carrés.\n" "- 'Grille de lignes' - la zone vide sera remplie d'un motif de lignes." -#: flatcamGUI/PreferencesUI.py:7237 flatcamTools/ToolCopperThieving.py:216 +#: flatcamGUI/PreferencesUI.py:7743 flatcamTools/ToolCopperThieving.py:218 msgid "Dots Grid Parameters" msgstr "Paramètres de la grille de points" -#: flatcamGUI/PreferencesUI.py:7243 flatcamTools/ToolCopperThieving.py:222 +#: flatcamGUI/PreferencesUI.py:7749 flatcamTools/ToolCopperThieving.py:224 msgid "Dot diameter in Dots Grid." msgstr "Diamètre des points dans la grille des points." -#: flatcamGUI/PreferencesUI.py:7254 flatcamGUI/PreferencesUI.py:7283 -#: flatcamGUI/PreferencesUI.py:7312 flatcamTools/ToolCopperThieving.py:233 -#: flatcamTools/ToolCopperThieving.py:273 -#: flatcamTools/ToolCopperThieving.py:313 +#: flatcamGUI/PreferencesUI.py:7760 flatcamGUI/PreferencesUI.py:7789 +#: flatcamGUI/PreferencesUI.py:7818 flatcamTools/ToolCopperThieving.py:235 +#: flatcamTools/ToolCopperThieving.py:275 +#: flatcamTools/ToolCopperThieving.py:315 msgid "Spacing" msgstr "Espacement" -#: flatcamGUI/PreferencesUI.py:7256 flatcamTools/ToolCopperThieving.py:235 +#: flatcamGUI/PreferencesUI.py:7762 flatcamTools/ToolCopperThieving.py:237 msgid "Distance between each two dots in Dots Grid." msgstr "Distance entre deux points dans la grille de points." -#: flatcamGUI/PreferencesUI.py:7266 flatcamTools/ToolCopperThieving.py:256 +#: flatcamGUI/PreferencesUI.py:7772 flatcamTools/ToolCopperThieving.py:258 msgid "Squares Grid Parameters" msgstr "Paramètres de la grille des carrés" -#: flatcamGUI/PreferencesUI.py:7272 flatcamTools/ToolCopperThieving.py:262 +#: flatcamGUI/PreferencesUI.py:7778 flatcamTools/ToolCopperThieving.py:264 msgid "Square side size in Squares Grid." msgstr "Taille du côté carré dans la grille des carrés." -#: flatcamGUI/PreferencesUI.py:7285 flatcamTools/ToolCopperThieving.py:275 +#: flatcamGUI/PreferencesUI.py:7791 flatcamTools/ToolCopperThieving.py:277 msgid "Distance between each two squares in Squares Grid." msgstr "Distance entre deux carrés dans la grille des carrés." -#: flatcamGUI/PreferencesUI.py:7295 flatcamTools/ToolCopperThieving.py:296 +#: flatcamGUI/PreferencesUI.py:7801 flatcamTools/ToolCopperThieving.py:298 msgid "Lines Grid Parameters" msgstr "Paramètres de grille de lignes" -#: flatcamGUI/PreferencesUI.py:7301 flatcamTools/ToolCopperThieving.py:302 +#: flatcamGUI/PreferencesUI.py:7807 flatcamTools/ToolCopperThieving.py:304 msgid "Line thickness size in Lines Grid." msgstr "Taille d'épaisseur de ligne dans la grille de lignes." -#: flatcamGUI/PreferencesUI.py:7314 flatcamTools/ToolCopperThieving.py:315 +#: flatcamGUI/PreferencesUI.py:7820 flatcamTools/ToolCopperThieving.py:317 msgid "Distance between each two lines in Lines Grid." msgstr "Distance entre deux lignes dans la grille de lignes." -#: flatcamGUI/PreferencesUI.py:7324 flatcamTools/ToolCopperThieving.py:353 +#: flatcamGUI/PreferencesUI.py:7830 flatcamTools/ToolCopperThieving.py:355 msgid "Robber Bar Parameters" msgstr "Paramètres de la Robber Bar" -#: flatcamGUI/PreferencesUI.py:7326 flatcamTools/ToolCopperThieving.py:355 +#: flatcamGUI/PreferencesUI.py:7832 flatcamTools/ToolCopperThieving.py:357 msgid "" "Parameters used for the robber bar.\n" "Robber bar = copper border to help in pattern hole plating." @@ -12493,27 +12922,27 @@ msgstr "" "Paramètres utilisés pour la Robber Bar.\n" "Robber Bar = bordure en cuivre pour faciliter le placage des trous." -#: flatcamGUI/PreferencesUI.py:7334 flatcamTools/ToolCopperThieving.py:363 +#: flatcamGUI/PreferencesUI.py:7840 flatcamTools/ToolCopperThieving.py:365 msgid "Bounding box margin for robber bar." msgstr "Marge de la zone de délimitation pour la Robber Bar." -#: flatcamGUI/PreferencesUI.py:7345 flatcamTools/ToolCopperThieving.py:374 +#: flatcamGUI/PreferencesUI.py:7851 flatcamTools/ToolCopperThieving.py:376 msgid "Thickness" msgstr "Épaisseur" -#: flatcamGUI/PreferencesUI.py:7347 flatcamTools/ToolCopperThieving.py:376 +#: flatcamGUI/PreferencesUI.py:7853 flatcamTools/ToolCopperThieving.py:378 msgid "The robber bar thickness." msgstr "L'épaisseur de la Robber Bar." -#: flatcamGUI/PreferencesUI.py:7357 flatcamTools/ToolCopperThieving.py:407 +#: flatcamGUI/PreferencesUI.py:7863 flatcamTools/ToolCopperThieving.py:409 msgid "Pattern Plating Mask" msgstr "Masque de placage de motifs" -#: flatcamGUI/PreferencesUI.py:7359 flatcamTools/ToolCopperThieving.py:409 +#: flatcamGUI/PreferencesUI.py:7865 flatcamTools/ToolCopperThieving.py:411 msgid "Generate a mask for pattern plating." msgstr "Générez un masque pour le placage de motifs." -#: flatcamGUI/PreferencesUI.py:7366 flatcamTools/ToolCopperThieving.py:431 +#: flatcamGUI/PreferencesUI.py:7872 flatcamTools/ToolCopperThieving.py:434 msgid "" "The distance between the possible copper thieving elements\n" "and/or robber bar and the actual openings in the mask." @@ -12521,16 +12950,17 @@ msgstr "" "La distance entre les éléments de Copper Thieving possibles\n" "et / ou Robber Bar et les ouvertures réelles dans le masque." -#: flatcamGUI/PreferencesUI.py:7385 +#: flatcamGUI/PreferencesUI.py:7891 msgid "Fiducials Tool Options" msgstr "Options de l'outil Fiducials" -#: flatcamGUI/PreferencesUI.py:7396 flatcamGUI/PreferencesUI.py:7512 -#: flatcamTools/ToolCopperThieving.py:91 flatcamTools/ToolFiducials.py:151 +#: flatcamGUI/PreferencesUI.py:7902 flatcamGUI/PreferencesUI.py:8018 +#: flatcamGUI/PreferencesUI.py:8137 flatcamGUI/PreferencesUI.py:8349 +#: flatcamTools/ToolCopperThieving.py:92 flatcamTools/ToolFiducials.py:151 msgid "Parameters used for this tool." msgstr "Paramètres utilisés pour cet outil." -#: flatcamGUI/PreferencesUI.py:7403 flatcamTools/ToolFiducials.py:158 +#: flatcamGUI/PreferencesUI.py:7909 flatcamTools/ToolFiducials.py:158 msgid "" "This set the fiducial diameter if fiducial type is circular,\n" "otherwise is the size of the fiducial.\n" @@ -12540,19 +12970,19 @@ msgstr "" "sinon, c'est la taille du fiduciaire.\n" "L'ouverture du masque de soldat est double." -#: flatcamGUI/PreferencesUI.py:7431 flatcamTools/ToolFiducials.py:186 +#: flatcamGUI/PreferencesUI.py:7937 flatcamTools/ToolFiducials.py:186 msgid "Auto" msgstr "Auto" -#: flatcamGUI/PreferencesUI.py:7432 flatcamTools/ToolFiducials.py:187 +#: flatcamGUI/PreferencesUI.py:7938 flatcamTools/ToolFiducials.py:187 msgid "Manual" msgstr "Manuel" -#: flatcamGUI/PreferencesUI.py:7434 flatcamTools/ToolFiducials.py:189 +#: flatcamGUI/PreferencesUI.py:7940 flatcamTools/ToolFiducials.py:189 msgid "Mode:" msgstr "Mode:" -#: flatcamGUI/PreferencesUI.py:7436 +#: flatcamGUI/PreferencesUI.py:7942 msgid "" "- 'Auto' - automatic placement of fiducials in the corners of the bounding " "box.\n" @@ -12562,19 +12992,19 @@ msgstr "" "sélection.\n" "- «Manuel» - placement manuel des fiduciaires." -#: flatcamGUI/PreferencesUI.py:7444 flatcamTools/ToolFiducials.py:199 +#: flatcamGUI/PreferencesUI.py:7950 flatcamTools/ToolFiducials.py:199 msgid "Up" msgstr "Haut" -#: flatcamGUI/PreferencesUI.py:7445 flatcamTools/ToolFiducials.py:200 +#: flatcamGUI/PreferencesUI.py:7951 flatcamTools/ToolFiducials.py:200 msgid "Down" msgstr "Bas" -#: flatcamGUI/PreferencesUI.py:7448 flatcamTools/ToolFiducials.py:203 +#: flatcamGUI/PreferencesUI.py:7954 flatcamTools/ToolFiducials.py:203 msgid "Second fiducial" msgstr "Deuxième fiducial" -#: flatcamGUI/PreferencesUI.py:7450 flatcamTools/ToolFiducials.py:205 +#: flatcamGUI/PreferencesUI.py:7956 flatcamTools/ToolFiducials.py:205 msgid "" "The position for the second fiducial.\n" "- 'Up' - the order is: bottom-left, top-left, top-right.\n" @@ -12588,19 +13018,19 @@ msgstr "" "- «Aucun» - il n'y a pas de deuxième fiduciaire. L'ordre est: en bas à " "gauche, en haut à droite." -#: flatcamGUI/PreferencesUI.py:7466 flatcamTools/ToolFiducials.py:221 +#: flatcamGUI/PreferencesUI.py:7972 flatcamTools/ToolFiducials.py:221 msgid "Cross" msgstr "Croix" -#: flatcamGUI/PreferencesUI.py:7467 flatcamTools/ToolFiducials.py:222 +#: flatcamGUI/PreferencesUI.py:7973 flatcamTools/ToolFiducials.py:222 msgid "Chess" msgstr "Échecs" -#: flatcamGUI/PreferencesUI.py:7470 flatcamTools/ToolFiducials.py:224 +#: flatcamGUI/PreferencesUI.py:7976 flatcamTools/ToolFiducials.py:224 msgid "Fiducial Type" msgstr "Type fiduciaire" -#: flatcamGUI/PreferencesUI.py:7472 flatcamTools/ToolFiducials.py:226 +#: flatcamGUI/PreferencesUI.py:7978 flatcamTools/ToolFiducials.py:226 msgid "" "The type of fiducial.\n" "- 'Circular' - this is the regular fiducial.\n" @@ -12612,19 +13042,19 @@ msgstr "" "- 'Croix' - croix lignes fiduciales.\n" "- 'Échecs' - modèle d'échecs fiducial." -#: flatcamGUI/PreferencesUI.py:7481 flatcamTools/ToolFiducials.py:235 +#: flatcamGUI/PreferencesUI.py:7987 flatcamTools/ToolFiducials.py:235 msgid "Line thickness" msgstr "Épaisseur de ligne" -#: flatcamGUI/PreferencesUI.py:7501 +#: flatcamGUI/PreferencesUI.py:8007 msgid "Calibration Tool Options" msgstr "Options de l'outil d'Étalonnage" -#: flatcamGUI/PreferencesUI.py:7517 flatcamTools/ToolCalibration.py:181 +#: flatcamGUI/PreferencesUI.py:8023 flatcamTools/ToolCalibration.py:181 msgid "Source Type" msgstr "Type de Source" -#: flatcamGUI/PreferencesUI.py:7518 flatcamTools/ToolCalibration.py:182 +#: flatcamGUI/PreferencesUI.py:8024 flatcamTools/ToolCalibration.py:182 msgid "" "The source of calibration points.\n" "It can be:\n" @@ -12637,27 +13067,27 @@ msgstr "" "- Libre -> cliquez librement sur le canevas pour acquérir les points " "d'étalonnage" -#: flatcamGUI/PreferencesUI.py:7523 flatcamTools/ToolCalibration.py:187 +#: flatcamGUI/PreferencesUI.py:8029 flatcamTools/ToolCalibration.py:187 msgid "Free" msgstr "Libre" -#: flatcamGUI/PreferencesUI.py:7537 flatcamTools/ToolCalibration.py:76 +#: flatcamGUI/PreferencesUI.py:8043 flatcamTools/ToolCalibration.py:76 msgid "Height (Z) for travelling between the points." msgstr "Hauteur (Z) pour voyager entre les points." -#: flatcamGUI/PreferencesUI.py:7549 flatcamTools/ToolCalibration.py:88 +#: flatcamGUI/PreferencesUI.py:8055 flatcamTools/ToolCalibration.py:88 msgid "Verification Z" msgstr "Vérification Z" -#: flatcamGUI/PreferencesUI.py:7551 flatcamTools/ToolCalibration.py:90 +#: flatcamGUI/PreferencesUI.py:8057 flatcamTools/ToolCalibration.py:90 msgid "Height (Z) for checking the point." msgstr "Hauteur (Z) pour vérifier le point." -#: flatcamGUI/PreferencesUI.py:7563 flatcamTools/ToolCalibration.py:102 +#: flatcamGUI/PreferencesUI.py:8069 flatcamTools/ToolCalibration.py:102 msgid "Zero Z tool" msgstr "Remise à Zéro du Z pour l'Outil" -#: flatcamGUI/PreferencesUI.py:7565 flatcamTools/ToolCalibration.py:104 +#: flatcamGUI/PreferencesUI.py:8071 flatcamTools/ToolCalibration.py:104 msgid "" "Include a sequence to zero the height (Z)\n" "of the verification tool." @@ -12665,11 +13095,11 @@ msgstr "" "Inclure une séquence pour mettre à zéro la hauteur (Z)\n" "de l'outil de vérification." -#: flatcamGUI/PreferencesUI.py:7574 flatcamTools/ToolCalibration.py:113 +#: flatcamGUI/PreferencesUI.py:8080 flatcamTools/ToolCalibration.py:113 msgid "Height (Z) for mounting the verification probe." msgstr "Hauteur (Z) pour le montage de la sonde de vérification." -#: flatcamGUI/PreferencesUI.py:7588 flatcamTools/ToolCalibration.py:127 +#: flatcamGUI/PreferencesUI.py:8094 flatcamTools/ToolCalibration.py:127 msgid "" "Toolchange X,Y position.\n" "If no value is entered then the current\n" @@ -12679,11 +13109,11 @@ msgstr "" "Si aucune valeur n'est entrée, le courant\n" "(x, y) le point sera utilisé," -#: flatcamGUI/PreferencesUI.py:7599 flatcamTools/ToolCalibration.py:153 +#: flatcamGUI/PreferencesUI.py:8105 flatcamTools/ToolCalibration.py:153 msgid "Second point" msgstr "Deuxième point" -#: flatcamGUI/PreferencesUI.py:7601 flatcamTools/ToolCalibration.py:155 +#: flatcamGUI/PreferencesUI.py:8107 flatcamTools/ToolCalibration.py:155 msgid "" "Second point in the Gcode verification can be:\n" "- top-left -> the user will align the PCB vertically\n" @@ -12693,45 +13123,250 @@ msgstr "" "- en haut à gauche -> l'utilisateur alignera le PCB verticalement\n" "- en bas à droite -> l'utilisateur alignera le PCB horizontalement" -#: flatcamGUI/PreferencesUI.py:7605 flatcamTools/ToolCalibration.py:159 -msgid "Top-Left" -msgstr "En haut à gauche" +#: flatcamGUI/PreferencesUI.py:8126 +msgid "Extract Drills Options" +msgstr "Options d'Extraction de Forets" -#: flatcamGUI/PreferencesUI.py:7606 flatcamTools/ToolCalibration.py:160 -msgid "Bottom-Right" -msgstr "En bas à droite" +#: flatcamGUI/PreferencesUI.py:8141 flatcamGUI/PreferencesUI.py:8353 +#: flatcamTools/ToolExtractDrills.py:68 flatcamTools/ToolPunchGerber.py:75 +msgid "Processed Pads Type" +msgstr "Type de tampons traités" -#: flatcamGUI/PreferencesUI.py:7620 +#: flatcamGUI/PreferencesUI.py:8143 flatcamGUI/PreferencesUI.py:8355 +#: flatcamTools/ToolExtractDrills.py:70 flatcamTools/ToolPunchGerber.py:77 +msgid "" +"The type of pads shape to be processed.\n" +"If the PCB has many SMD pads with rectangular pads,\n" +"disable the Rectangular aperture." +msgstr "" +"Le type de forme des tampons à traiter.\n" +"Si le PCB a de nombreux pads SMD avec des pads rectangulaires,\n" +"désactiver l'ouverture rectangulaire." + +#: flatcamGUI/PreferencesUI.py:8153 flatcamGUI/PreferencesUI.py:8365 +#: flatcamTools/ToolExtractDrills.py:80 flatcamTools/ToolPunchGerber.py:91 +msgid "Process Circular Pads." +msgstr "Processus tampons circulaires." + +#: flatcamGUI/PreferencesUI.py:8159 flatcamGUI/PreferencesUI.py:8261 +#: flatcamGUI/PreferencesUI.py:8371 flatcamGUI/PreferencesUI.py:8475 +#: flatcamTools/ToolExtractDrills.py:86 flatcamTools/ToolExtractDrills.py:214 +#: flatcamTools/ToolPunchGerber.py:97 flatcamTools/ToolPunchGerber.py:242 +msgid "Oblong" +msgstr "Oblong" + +#: flatcamGUI/PreferencesUI.py:8161 flatcamGUI/PreferencesUI.py:8373 +#: flatcamTools/ToolExtractDrills.py:88 flatcamTools/ToolPunchGerber.py:99 +msgid "Process Oblong Pads." +msgstr "Processus Tampons oblongs." + +#: flatcamGUI/PreferencesUI.py:8169 flatcamGUI/PreferencesUI.py:8381 +#: flatcamTools/ToolExtractDrills.py:96 flatcamTools/ToolPunchGerber.py:107 +msgid "Process Square Pads." +msgstr "Processus Tampons carrés." + +#: flatcamGUI/PreferencesUI.py:8177 flatcamGUI/PreferencesUI.py:8389 +#: flatcamTools/ToolExtractDrills.py:104 flatcamTools/ToolPunchGerber.py:115 +msgid "Process Rectangular Pads." +msgstr "Processus Tampons rectangulaires." + +#: flatcamGUI/PreferencesUI.py:8183 flatcamGUI/PreferencesUI.py:8300 +#: flatcamGUI/PreferencesUI.py:8395 flatcamGUI/PreferencesUI.py:8514 +#: flatcamTools/ToolExtractDrills.py:110 flatcamTools/ToolExtractDrills.py:253 +#: flatcamTools/ToolProperties.py:172 flatcamTools/ToolPunchGerber.py:121 +#: flatcamTools/ToolPunchGerber.py:281 +msgid "Others" +msgstr "Autres" + +#: flatcamGUI/PreferencesUI.py:8185 flatcamGUI/PreferencesUI.py:8397 +#: flatcamTools/ToolExtractDrills.py:112 flatcamTools/ToolPunchGerber.py:123 +msgid "Process pads not in the categories above." +msgstr "Processus tampons n'appartenant pas aux catégories ci-dessus." + +#: flatcamGUI/PreferencesUI.py:8198 flatcamGUI/PreferencesUI.py:8222 +#: flatcamGUI/PreferencesUI.py:8411 flatcamGUI/PreferencesUI.py:8436 +#: flatcamTools/ToolExtractDrills.py:139 flatcamTools/ToolExtractDrills.py:156 +#: flatcamTools/ToolPunchGerber.py:150 flatcamTools/ToolPunchGerber.py:184 +msgid "Fixed Diameter" +msgstr "Diamètre fixe" + +#: flatcamGUI/PreferencesUI.py:8199 flatcamGUI/PreferencesUI.py:8239 +#: flatcamGUI/PreferencesUI.py:8412 flatcamGUI/PreferencesUI.py:8453 +#: flatcamTools/ToolExtractDrills.py:140 flatcamTools/ToolExtractDrills.py:192 +#: flatcamTools/ToolPunchGerber.py:151 flatcamTools/ToolPunchGerber.py:214 +msgid "Fixed Annular Ring" +msgstr "Anneau fixe annulaire" + +#: flatcamGUI/PreferencesUI.py:8200 flatcamGUI/PreferencesUI.py:8413 +#: flatcamTools/ToolExtractDrills.py:141 flatcamTools/ToolPunchGerber.py:152 +msgid "Proportional" +msgstr "Proportionnel" + +#: flatcamGUI/PreferencesUI.py:8206 flatcamTools/ToolExtractDrills.py:130 +msgid "" +"The method for processing pads. Can be:\n" +"- Fixed Diameter -> all holes will have a set size\n" +"- Fixed Annular Ring -> all holes will have a set annular ring\n" +"- Proportional -> each hole size will be a fraction of the pad size" +msgstr "" +"La méthode de traitement des tampons. Peut être:\n" +"- Diamètre fixe -> tous les trous auront une taille définie\n" +"- Anneau fixe annulaire -> tous les trous auront un anneau annulaire fixe\n" +"- Proportionnel -> chaque taille de trou sera une fraction de la taille du " +"tampon" + +#: flatcamGUI/PreferencesUI.py:8232 flatcamGUI/PreferencesUI.py:8446 +#: flatcamTools/ToolExtractDrills.py:166 flatcamTools/ToolPunchGerber.py:194 +msgid "Fixed hole diameter." +msgstr "Diamètre du trou fixe." + +#: flatcamGUI/PreferencesUI.py:8241 flatcamGUI/PreferencesUI.py:8455 +#: flatcamTools/ToolExtractDrills.py:194 flatcamTools/ToolPunchGerber.py:216 +msgid "" +"The size of annular ring.\n" +"The copper sliver between the hole exterior\n" +"and the margin of the copper pad." +msgstr "" +"La taille de l'anneau annulaire.\n" +"Le ruban de cuivre entre l'extérieur du trou\n" +"et la marge du tampon de cuivre." + +#: flatcamGUI/PreferencesUI.py:8250 flatcamGUI/PreferencesUI.py:8464 +#: flatcamTools/ToolExtractDrills.py:203 flatcamTools/ToolPunchGerber.py:231 +msgid "The size of annular ring for circular pads." +msgstr "La taille de l'anneau annulaire pour les coussinets circulaires." + +#: flatcamGUI/PreferencesUI.py:8263 flatcamGUI/PreferencesUI.py:8477 +#: flatcamTools/ToolExtractDrills.py:216 flatcamTools/ToolPunchGerber.py:244 +msgid "The size of annular ring for oblong pads." +msgstr "La taille de l'anneau annulaire pour les coussinets oblongs." + +#: flatcamGUI/PreferencesUI.py:8276 flatcamGUI/PreferencesUI.py:8490 +#: flatcamTools/ToolExtractDrills.py:229 flatcamTools/ToolPunchGerber.py:257 +msgid "The size of annular ring for square pads." +msgstr "La taille de l'anneau annulaire pour les coussinets carrés." + +#: flatcamGUI/PreferencesUI.py:8289 flatcamGUI/PreferencesUI.py:8503 +#: flatcamTools/ToolExtractDrills.py:242 flatcamTools/ToolPunchGerber.py:270 +msgid "The size of annular ring for rectangular pads." +msgstr "La taille de l'anneau annulaire pour les coussinets rectangulaires." + +#: flatcamGUI/PreferencesUI.py:8302 flatcamGUI/PreferencesUI.py:8516 +#: flatcamTools/ToolExtractDrills.py:255 flatcamTools/ToolPunchGerber.py:283 +msgid "The size of annular ring for other pads." +msgstr "La taille de l'anneau annulaire pour les autres tampons." + +#: flatcamGUI/PreferencesUI.py:8312 flatcamGUI/PreferencesUI.py:8526 +#: flatcamTools/ToolExtractDrills.py:276 flatcamTools/ToolPunchGerber.py:299 +msgid "Proportional Diameter" +msgstr "Dia. proportionnel" + +#: flatcamGUI/PreferencesUI.py:8321 flatcamGUI/PreferencesUI.py:8535 +msgid "Factor" +msgstr "Facteur" + +#: flatcamGUI/PreferencesUI.py:8323 flatcamGUI/PreferencesUI.py:8537 +#: flatcamTools/ToolExtractDrills.py:287 flatcamTools/ToolPunchGerber.py:310 +msgid "" +"Proportional Diameter.\n" +"The hole diameter will be a fraction of the pad size." +msgstr "" +"Diamètre proportionnel.\n" +"Le diamètre du trou sera une fraction de la taille du tampon." + +#: flatcamGUI/PreferencesUI.py:8338 +msgid "Punch Gerber Options" +msgstr "Options de poinçonnage Gerber" + +#: flatcamGUI/PreferencesUI.py:8419 flatcamTools/ToolPunchGerber.py:141 +msgid "" +"The punch hole source can be:\n" +"- Excellon Object-> the Excellon object drills center will serve as " +"reference.\n" +"- Fixed Diameter -> will try to use the pads center as reference adding " +"fixed diameter holes.\n" +"- Fixed Annular Ring -> will try to keep a set annular ring.\n" +"- Proportional -> will make a Gerber punch hole having the diameter a " +"percentage of the pad diameter.\n" +msgstr "" +"La source du trou de perforation peut être:\n" +"- Excellon Object-> le centre d'Excellons Object Drills servira de " +"référence.\n" +"- Diamètre fixe -> essaiera d'utiliser le centre des coussinets comme " +"référence en ajoutant des trous de diamètre fixe.\n" +"- Anneau fixe annulaire -> essaiera de garder un anneau annulaire fixe.\n" +"- Proportionnel -> fera un trou de poinçon Gerber ayant le diamètre un " +"pourcentage du diamètre du tampon.\n" + +#: flatcamGUI/PreferencesUI.py:8552 +msgid "Invert Gerber Tool Options" +msgstr "Options de l'outil Inverser Gerber" + +#: flatcamGUI/PreferencesUI.py:8558 +msgid "" +"A tool to invert Gerber geometry from positive to negative\n" +"and in revers." +msgstr "" +"Un outil pour inverser la géométrie Gerber du positif au négatif\n" +"et en sens inverse." + +#: flatcamGUI/PreferencesUI.py:8572 flatcamTools/ToolInvertGerber.py:90 +msgid "" +"Distance by which to avoid\n" +"the edges of the Gerber object." +msgstr "" +"Distance à éviter\n" +"les bords de l'objet Gerber." + +#: flatcamGUI/PreferencesUI.py:8583 flatcamTools/ToolInvertGerber.py:101 +msgid "Lines Join Style" +msgstr "Style de jointure des lignes" + +#: flatcamGUI/PreferencesUI.py:8585 flatcamTools/ToolInvertGerber.py:103 +msgid "" +"The way that the lines in the object outline will be joined.\n" +"Can be:\n" +"- rounded -> an arc is added between two joining lines\n" +"- square -> the lines meet in 90 degrees angle\n" +"- bevel -> the lines are joined by a third line" +msgstr "" +"La façon dont les lignes du contour de l'objet seront jointes.\n" +"Peut être:\n" +"- arrondi -> un arc est ajouté entre deux lignes de jonction\n" +"- carré -> les lignes se rencontrent dans un angle de 90 degrés\n" +"- biseau -> les lignes sont reliées par une troisième ligne" + +#: flatcamGUI/PreferencesUI.py:8608 msgid "Excellon File associations" msgstr "Associations de fichiers Excellon" -#: flatcamGUI/PreferencesUI.py:7633 flatcamGUI/PreferencesUI.py:7706 -#: flatcamGUI/PreferencesUI.py:7776 flatcamGUI/PreferencesUI.py:7846 +#: flatcamGUI/PreferencesUI.py:8621 flatcamGUI/PreferencesUI.py:8694 +#: flatcamGUI/PreferencesUI.py:8764 flatcamGUI/PreferencesUI.py:8834 msgid "Restore" msgstr "Restaurer" -#: flatcamGUI/PreferencesUI.py:7634 flatcamGUI/PreferencesUI.py:7707 -#: flatcamGUI/PreferencesUI.py:7777 +#: flatcamGUI/PreferencesUI.py:8622 flatcamGUI/PreferencesUI.py:8695 +#: flatcamGUI/PreferencesUI.py:8765 msgid "Restore the extension list to the default state." msgstr "Restaurez la liste des extensions à l'état par défaut." -#: flatcamGUI/PreferencesUI.py:7635 flatcamGUI/PreferencesUI.py:7708 -#: flatcamGUI/PreferencesUI.py:7778 flatcamGUI/PreferencesUI.py:7848 +#: flatcamGUI/PreferencesUI.py:8623 flatcamGUI/PreferencesUI.py:8696 +#: flatcamGUI/PreferencesUI.py:8766 flatcamGUI/PreferencesUI.py:8836 msgid "Delete All" msgstr "Supprimer tout" -#: flatcamGUI/PreferencesUI.py:7636 flatcamGUI/PreferencesUI.py:7709 -#: flatcamGUI/PreferencesUI.py:7779 +#: flatcamGUI/PreferencesUI.py:8624 flatcamGUI/PreferencesUI.py:8697 +#: flatcamGUI/PreferencesUI.py:8767 msgid "Delete all extensions from the list." msgstr "Supprimer toutes les extensions de la liste." -#: flatcamGUI/PreferencesUI.py:7644 flatcamGUI/PreferencesUI.py:7717 -#: flatcamGUI/PreferencesUI.py:7787 +#: flatcamGUI/PreferencesUI.py:8632 flatcamGUI/PreferencesUI.py:8705 +#: flatcamGUI/PreferencesUI.py:8775 msgid "Extensions list" msgstr "Liste d'extensions" -#: flatcamGUI/PreferencesUI.py:7646 flatcamGUI/PreferencesUI.py:7719 -#: flatcamGUI/PreferencesUI.py:7789 +#: flatcamGUI/PreferencesUI.py:8634 flatcamGUI/PreferencesUI.py:8707 +#: flatcamGUI/PreferencesUI.py:8777 msgid "" "List of file extensions to be\n" "associated with FlatCAM." @@ -12739,43 +13374,43 @@ msgstr "" "Liste des extensions de fichier à être\n" "associé à FlatCAM." -#: flatcamGUI/PreferencesUI.py:7666 flatcamGUI/PreferencesUI.py:7739 -#: flatcamGUI/PreferencesUI.py:7808 flatcamGUI/PreferencesUI.py:7880 +#: flatcamGUI/PreferencesUI.py:8654 flatcamGUI/PreferencesUI.py:8727 +#: flatcamGUI/PreferencesUI.py:8796 flatcamGUI/PreferencesUI.py:8868 msgid "Extension" msgstr "Extension" -#: flatcamGUI/PreferencesUI.py:7667 flatcamGUI/PreferencesUI.py:7740 -#: flatcamGUI/PreferencesUI.py:7809 +#: flatcamGUI/PreferencesUI.py:8655 flatcamGUI/PreferencesUI.py:8728 +#: flatcamGUI/PreferencesUI.py:8797 msgid "A file extension to be added or deleted to the list." msgstr "Une extension de fichier à ajouter ou à supprimer à la liste." -#: flatcamGUI/PreferencesUI.py:7675 flatcamGUI/PreferencesUI.py:7748 -#: flatcamGUI/PreferencesUI.py:7817 +#: flatcamGUI/PreferencesUI.py:8663 flatcamGUI/PreferencesUI.py:8736 +#: flatcamGUI/PreferencesUI.py:8805 msgid "Add Extension" msgstr "Ajouter une extension" -#: flatcamGUI/PreferencesUI.py:7676 flatcamGUI/PreferencesUI.py:7749 -#: flatcamGUI/PreferencesUI.py:7818 +#: flatcamGUI/PreferencesUI.py:8664 flatcamGUI/PreferencesUI.py:8737 +#: flatcamGUI/PreferencesUI.py:8806 msgid "Add a file extension to the list" msgstr "Ajouter une extension de fichier à la liste" -#: flatcamGUI/PreferencesUI.py:7677 flatcamGUI/PreferencesUI.py:7750 -#: flatcamGUI/PreferencesUI.py:7819 +#: flatcamGUI/PreferencesUI.py:8665 flatcamGUI/PreferencesUI.py:8738 +#: flatcamGUI/PreferencesUI.py:8807 msgid "Delete Extension" msgstr "Supprimer l'extension" -#: flatcamGUI/PreferencesUI.py:7678 flatcamGUI/PreferencesUI.py:7751 -#: flatcamGUI/PreferencesUI.py:7820 +#: flatcamGUI/PreferencesUI.py:8666 flatcamGUI/PreferencesUI.py:8739 +#: flatcamGUI/PreferencesUI.py:8808 msgid "Delete a file extension from the list" msgstr "Supprimer une extension de fichier de la liste" -#: flatcamGUI/PreferencesUI.py:7685 flatcamGUI/PreferencesUI.py:7758 -#: flatcamGUI/PreferencesUI.py:7827 +#: flatcamGUI/PreferencesUI.py:8673 flatcamGUI/PreferencesUI.py:8746 +#: flatcamGUI/PreferencesUI.py:8815 msgid "Apply Association" msgstr "Appliquer l'association" -#: flatcamGUI/PreferencesUI.py:7686 flatcamGUI/PreferencesUI.py:7759 -#: flatcamGUI/PreferencesUI.py:7828 +#: flatcamGUI/PreferencesUI.py:8674 flatcamGUI/PreferencesUI.py:8747 +#: flatcamGUI/PreferencesUI.py:8816 msgid "" "Apply the file associations between\n" "FlatCAM and the files with above extensions.\n" @@ -12787,31 +13422,31 @@ msgstr "" "Ils seront actifs après la prochaine ouverture de session.\n" "Cela ne fonctionne que sous Windows." -#: flatcamGUI/PreferencesUI.py:7703 +#: flatcamGUI/PreferencesUI.py:8691 msgid "GCode File associations" msgstr "Associations de fichiers GCode" -#: flatcamGUI/PreferencesUI.py:7773 +#: flatcamGUI/PreferencesUI.py:8761 msgid "Gerber File associations" msgstr "Associations de fichiers Gerber" -#: flatcamGUI/PreferencesUI.py:7843 +#: flatcamGUI/PreferencesUI.py:8831 msgid "Autocompleter Keywords" msgstr "Mots-clés d'auto-complétion" -#: flatcamGUI/PreferencesUI.py:7847 +#: flatcamGUI/PreferencesUI.py:8835 msgid "Restore the autocompleter keywords list to the default state." msgstr "Restaurez la liste de mots-clés d'auto-complétion à l'état par défaut." -#: flatcamGUI/PreferencesUI.py:7849 +#: flatcamGUI/PreferencesUI.py:8837 msgid "Delete all autocompleter keywords from the list." msgstr "Supprimer tous les mots clés autocompleter de la liste." -#: flatcamGUI/PreferencesUI.py:7857 +#: flatcamGUI/PreferencesUI.py:8845 msgid "Keywords list" msgstr "Liste des mots clés" -#: flatcamGUI/PreferencesUI.py:7859 +#: flatcamGUI/PreferencesUI.py:8847 msgid "" "List of keywords used by\n" "the autocompleter in FlatCAM.\n" @@ -12823,31 +13458,31 @@ msgstr "" "L'auto-compléteur est installé\n" "dans l'éditeur de code et pour le shell Tcl." -#: flatcamGUI/PreferencesUI.py:7881 +#: flatcamGUI/PreferencesUI.py:8869 msgid "A keyword to be added or deleted to the list." msgstr "Un mot clé à ajouter ou à supprimer à la liste." -#: flatcamGUI/PreferencesUI.py:7889 +#: flatcamGUI/PreferencesUI.py:8877 msgid "Add keyword" msgstr "Ajouter un mot clé" -#: flatcamGUI/PreferencesUI.py:7890 +#: flatcamGUI/PreferencesUI.py:8878 msgid "Add a keyword to the list" msgstr "Ajouter un mot clé à la liste" -#: flatcamGUI/PreferencesUI.py:7891 +#: flatcamGUI/PreferencesUI.py:8879 msgid "Delete keyword" msgstr "Supprimer le mot clé" -#: flatcamGUI/PreferencesUI.py:7892 +#: flatcamGUI/PreferencesUI.py:8880 msgid "Delete a keyword from the list" msgstr "Supprimer un mot clé de la liste" -#: flatcamParsers/ParseExcellon.py:314 +#: flatcamParsers/ParseExcellon.py:315 msgid "This is GCODE mark" msgstr "C'est la marque GCODE" -#: flatcamParsers/ParseExcellon.py:431 +#: flatcamParsers/ParseExcellon.py:432 msgid "" "No tool diameter info's. See shell.\n" "A tool change event: T" @@ -12855,7 +13490,7 @@ msgstr "" "Aucune information sur le diamètre de l'outil. Voir shell.\n" "Un événement de changement d'outil: T" -#: flatcamParsers/ParseExcellon.py:434 +#: flatcamParsers/ParseExcellon.py:435 msgid "" "was found but the Excellon file have no informations regarding the tool " "diameters therefore the application will try to load it by using some 'fake' " @@ -12869,11 +13504,11 @@ msgstr "" "L'utilisateur doit modifier l'objet Excellon résultant et modifier les " "diamètres pour refléter les diamètres réels." -#: flatcamParsers/ParseExcellon.py:886 flatcamTools/ToolSolderPaste.py:1330 +#: flatcamParsers/ParseExcellon.py:897 flatcamTools/ToolSolderPaste.py:1327 msgid "An internal error has ocurred. See shell.\n" msgstr "Une erreur interne s'est produite. Voir shell.\n" -#: flatcamParsers/ParseExcellon.py:889 +#: flatcamParsers/ParseExcellon.py:900 msgid "" "Excellon Parser error.\n" "Parsing Failed. Line" @@ -12881,7 +13516,7 @@ msgstr "" "Erreur de l'analyseur Excellon.\n" "Échec de l'analyse. Ligne" -#: flatcamParsers/ParseExcellon.py:973 +#: flatcamParsers/ParseExcellon.py:982 msgid "" "Excellon.create_geometry() -> a drill location was skipped due of not having " "a tool associated.\n" @@ -12899,22 +13534,22 @@ msgstr "Police non supportée, essayez-en une autre." msgid "Gerber processing. Parsing" msgstr "Traitement Gerber. L'analyse" -#: flatcamParsers/ParseGerber.py:426 flatcamParsers/ParseHPGL2.py:176 +#: flatcamParsers/ParseGerber.py:426 flatcamParsers/ParseHPGL2.py:178 msgid "lines" msgstr "lignes" -#: flatcamParsers/ParseGerber.py:970 flatcamParsers/ParseGerber.py:1065 -#: flatcamParsers/ParseHPGL2.py:269 flatcamParsers/ParseHPGL2.py:283 -#: flatcamParsers/ParseHPGL2.py:302 flatcamParsers/ParseHPGL2.py:326 -#: flatcamParsers/ParseHPGL2.py:361 +#: flatcamParsers/ParseGerber.py:1002 flatcamParsers/ParseGerber.py:1102 +#: flatcamParsers/ParseHPGL2.py:271 flatcamParsers/ParseHPGL2.py:285 +#: flatcamParsers/ParseHPGL2.py:304 flatcamParsers/ParseHPGL2.py:328 +#: flatcamParsers/ParseHPGL2.py:363 msgid "Coordinates missing, line ignored" msgstr "Coordonnées manquantes, ligne ignorée" -#: flatcamParsers/ParseGerber.py:972 flatcamParsers/ParseGerber.py:1067 +#: flatcamParsers/ParseGerber.py:1004 flatcamParsers/ParseGerber.py:1104 msgid "GERBER file might be CORRUPT. Check the file !!!" msgstr "Le fichier GERBER est peut-être corrompu. Vérifiez le fichier !!!" -#: flatcamParsers/ParseGerber.py:1021 +#: flatcamParsers/ParseGerber.py:1058 msgid "" "Region does not have enough points. File will be processed but there are " "parser errors. Line number" @@ -12922,66 +13557,214 @@ msgstr "" "La région n'a pas assez de points. Le fichier sera traité, mais il y a des " "erreurs d'analyse. Numéro de ligne" -#: flatcamParsers/ParseGerber.py:1421 flatcamParsers/ParseHPGL2.py:396 +#: flatcamParsers/ParseGerber.py:1488 flatcamParsers/ParseHPGL2.py:398 msgid "Gerber processing. Joining polygons" msgstr "Traitement Gerber. Jointure de polygones" -#: flatcamParsers/ParseGerber.py:1438 +#: flatcamParsers/ParseGerber.py:1505 msgid "Gerber processing. Applying Gerber polarity." msgstr "Traitement Gerber. Appliquer la polarité de Gerber." -#: flatcamParsers/ParseGerber.py:1498 +#: flatcamParsers/ParseGerber.py:1565 msgid "Gerber Line" msgstr "Ligne Gerber" -#: flatcamParsers/ParseGerber.py:1498 +#: flatcamParsers/ParseGerber.py:1565 msgid "Gerber Line Content" msgstr "Contenu de la ligne Gerber" -#: flatcamParsers/ParseGerber.py:1500 +#: flatcamParsers/ParseGerber.py:1567 msgid "Gerber Parser ERROR" msgstr "Gerber Parser ERREUR" -#: flatcamParsers/ParseGerber.py:1884 +#: flatcamParsers/ParseGerber.py:1956 msgid "Gerber Scale done." msgstr "Échelle de Gerber fait." -#: flatcamParsers/ParseGerber.py:1977 +#: flatcamParsers/ParseGerber.py:2049 msgid "Gerber Offset done." msgstr "Gerber offset fait." -#: flatcamParsers/ParseGerber.py:2054 +#: flatcamParsers/ParseGerber.py:2126 msgid "Gerber Mirror done." msgstr "Le miroir de Gerber est fait." -#: flatcamParsers/ParseGerber.py:2128 +#: flatcamParsers/ParseGerber.py:2200 msgid "Gerber Skew done." msgstr "Gerber incline fait." -#: flatcamParsers/ParseGerber.py:2192 +#: flatcamParsers/ParseGerber.py:2263 msgid "Gerber Rotate done." msgstr "La rotation de Gerber est fait." -#: flatcamParsers/ParseGerber.py:2273 +#: flatcamParsers/ParseGerber.py:2419 msgid "Gerber Buffer done." msgstr "Gerber Buffer fait." -#: flatcamParsers/ParseHPGL2.py:176 +#: flatcamParsers/ParseHPGL2.py:178 msgid "HPGL2 processing. Parsing" msgstr "Traitement HPGL2. Analyse" -#: flatcamParsers/ParseHPGL2.py:408 +#: flatcamParsers/ParseHPGL2.py:410 msgid "HPGL2 Line" msgstr "Ligne HPGL2" -#: flatcamParsers/ParseHPGL2.py:408 +#: flatcamParsers/ParseHPGL2.py:410 msgid "HPGL2 Line Content" msgstr "Contenu de la ligne HPGL2" -#: flatcamParsers/ParseHPGL2.py:409 +#: flatcamParsers/ParseHPGL2.py:411 msgid "HPGL2 Parser ERROR" msgstr "ERREUR de l'analyseur HPGL2" +#: flatcamTools/ToolAlignObjects.py:32 +msgid "Align Objects" +msgstr "Aligner les objets" + +#: flatcamTools/ToolAlignObjects.py:61 +msgid "MOVING object" +msgstr "Objet en mouvement" + +#: flatcamTools/ToolAlignObjects.py:65 +msgid "" +"Specify the type of object to be aligned.\n" +"It can be of type: Gerber or Excellon.\n" +"The selection here decide the type of objects that will be\n" +"in the Object combobox." +msgstr "" +"Spécifiez le type d'objet à aligner.\n" +"Il peut être de type: Gerber ou Excellon.\n" +"La sélection ici décide du type d'objets qui seront\n" +"dans la zone de liste déroulante Objet." + +#: flatcamTools/ToolAlignObjects.py:86 +msgid "Object to be aligned." +msgstr "Objet à aligner." + +#: flatcamTools/ToolAlignObjects.py:98 +msgid "TARGET object" +msgstr "Objet CIBLE" + +#: flatcamTools/ToolAlignObjects.py:100 +msgid "" +"Specify the type of object to be aligned to.\n" +"It can be of type: Gerber or Excellon.\n" +"The selection here decide the type of objects that will be\n" +"in the Object combobox." +msgstr "" +"Spécifiez le type d'objet à aligner.\n" +"Il peut être de type: Gerber ou Excellon.\n" +"La sélection ici décide du type d'objets qui seront\n" +"dans la zone de liste déroulante Objet." + +#: flatcamTools/ToolAlignObjects.py:122 +msgid "Object to be aligned to. Aligner." +msgstr "Objet à aligner. Aligner." + +#: flatcamTools/ToolAlignObjects.py:135 +msgid "Alignment Type" +msgstr "Type d'alignement" + +#: flatcamTools/ToolAlignObjects.py:137 +msgid "" +"The type of alignment can be:\n" +"- Single Point -> it require a single point of sync, the action will be a " +"translation\n" +"- Dual Point -> it require two points of sync, the action will be " +"translation followed by rotation" +msgstr "" +"Le type d'alignement peut être:\n" +"- Point unique -> il nécessite un seul point de synchronisation, l'action " +"sera une traduction\n" +"- Double point -> il nécessite deux points de synchronisation, l'action sera " +"la traduction suivie d'une rotation" + +#: flatcamTools/ToolAlignObjects.py:143 +msgid "Single Point" +msgstr "Point unique" + +#: flatcamTools/ToolAlignObjects.py:144 +msgid "Dual Point" +msgstr "Double point" + +#: flatcamTools/ToolAlignObjects.py:159 +msgid "Align Object" +msgstr "Aligner l'objet" + +#: flatcamTools/ToolAlignObjects.py:161 +msgid "" +"Align the specified object to the aligner object.\n" +"If only one point is used then it assumes translation.\n" +"If tho points are used it assume translation and rotation." +msgstr "" +"Alignez l'objet spécifié sur l'objet aligneur.\n" +"Si un seul point est utilisé, il suppose la traduction.\n" +"Si ces points sont utilisés, cela suppose une translation et une rotation." + +#: flatcamTools/ToolAlignObjects.py:176 flatcamTools/ToolCalculators.py:246 +#: flatcamTools/ToolCalibration.py:683 flatcamTools/ToolCopperThieving.py:485 +#: flatcamTools/ToolCutOut.py:372 flatcamTools/ToolDblSided.py:472 +#: flatcamTools/ToolExtractDrills.py:310 flatcamTools/ToolFiducials.py:318 +#: flatcamTools/ToolFilm.py:520 flatcamTools/ToolInvertGerber.py:140 +#: flatcamTools/ToolNCC.py:612 flatcamTools/ToolOptimal.py:238 +#: flatcamTools/ToolPaint.py:556 flatcamTools/ToolPanelize.py:269 +#: flatcamTools/ToolPunchGerber.py:339 flatcamTools/ToolQRCode.py:314 +#: flatcamTools/ToolRulesCheck.py:516 flatcamTools/ToolSolderPaste.py:474 +#: flatcamTools/ToolSub.py:176 flatcamTools/ToolTransform.py:399 +msgid "Reset Tool" +msgstr "Réinitialiser l'outil" + +#: flatcamTools/ToolAlignObjects.py:178 flatcamTools/ToolCalculators.py:248 +#: flatcamTools/ToolCalibration.py:685 flatcamTools/ToolCopperThieving.py:487 +#: flatcamTools/ToolCutOut.py:374 flatcamTools/ToolDblSided.py:474 +#: flatcamTools/ToolExtractDrills.py:312 flatcamTools/ToolFiducials.py:320 +#: flatcamTools/ToolFilm.py:522 flatcamTools/ToolInvertGerber.py:142 +#: flatcamTools/ToolNCC.py:614 flatcamTools/ToolOptimal.py:240 +#: flatcamTools/ToolPaint.py:558 flatcamTools/ToolPanelize.py:271 +#: flatcamTools/ToolPunchGerber.py:341 flatcamTools/ToolQRCode.py:316 +#: flatcamTools/ToolRulesCheck.py:518 flatcamTools/ToolSolderPaste.py:476 +#: flatcamTools/ToolSub.py:178 flatcamTools/ToolTransform.py:401 +msgid "Will reset the tool parameters." +msgstr "Réinitialise les paramètres de l'outil." + +#: flatcamTools/ToolAlignObjects.py:244 +msgid "Align Tool" +msgstr "Outil d'alignement" + +#: flatcamTools/ToolAlignObjects.py:289 +msgid "There is no aligned FlatCAM object selected..." +msgstr "Aucun objet FlatCAM aligné n'est sélectionné ..." + +#: flatcamTools/ToolAlignObjects.py:299 +msgid "There is no aligner FlatCAM object selected..." +msgstr "Aucun objet d'alignement FlatCAM n'est sélectionné ..." + +#: flatcamTools/ToolAlignObjects.py:325 flatcamTools/ToolAlignObjects.py:385 +msgid "First Point" +msgstr "Premier point" + +#: flatcamTools/ToolAlignObjects.py:325 flatcamTools/ToolAlignObjects.py:400 +msgid "Click on the START point." +msgstr "Cliquez sur le point de Départ." + +#: flatcamTools/ToolAlignObjects.py:380 flatcamTools/ToolCalibration.py:920 +msgid "Cancelled by user request." +msgstr "Annulé par demande de l'utilisateur." + +#: flatcamTools/ToolAlignObjects.py:385 flatcamTools/ToolAlignObjects.py:407 +msgid "Click on the DESTINATION point." +msgstr "Cliquez sur le point de Destination." + +#: flatcamTools/ToolAlignObjects.py:385 flatcamTools/ToolAlignObjects.py:400 +#: flatcamTools/ToolAlignObjects.py:407 +msgid " Or right click to cancel." +msgstr " Ou cliquez avec le bouton droit pour annuler." + +#: flatcamTools/ToolAlignObjects.py:400 flatcamTools/ToolAlignObjects.py:407 +#: flatcamTools/ToolFiducials.py:111 +msgid "Second Point" +msgstr "Deuxième point" + #: flatcamTools/ToolCalculators.py:24 msgid "Calculators" msgstr "Calculatrices" @@ -13068,7 +13851,7 @@ msgstr "" "Calculer la valeur d'intensité actuelle et le temps de procédure,\n" "en fonction des paramètres ci-dessus" -#: flatcamTools/ToolCalculators.py:285 +#: flatcamTools/ToolCalculators.py:299 msgid "Calc. Tool" msgstr "Calc. Outil" @@ -13094,25 +13877,25 @@ msgstr "" "Ces quatre points devraient figurer dans les quatre\n" "(autant que possible) coins de l'objet." -#: flatcamTools/ToolCalibration.py:193 flatcamTools/ToolCutOut.py:80 -#: flatcamTools/ToolFilm.py:78 flatcamTools/ToolImage.py:55 -#: flatcamTools/ToolPanelize.py:66 flatcamTools/ToolProperties.py:169 +#: flatcamTools/ToolCalibration.py:193 flatcamTools/ToolFilm.py:76 +#: flatcamTools/ToolImage.py:54 flatcamTools/ToolPanelize.py:78 +#: flatcamTools/ToolProperties.py:177 msgid "Object Type" msgstr "Type d'objet" -#: flatcamTools/ToolCalibration.py:211 +#: flatcamTools/ToolCalibration.py:210 msgid "Source object selection" msgstr "Sélection d'objet source" -#: flatcamTools/ToolCalibration.py:213 +#: flatcamTools/ToolCalibration.py:212 msgid "FlatCAM Object to be used as a source for reference points." msgstr "Objet FlatCAM à utiliser comme source pour les points de référence." -#: flatcamTools/ToolCalibration.py:219 +#: flatcamTools/ToolCalibration.py:218 msgid "Calibration Points" msgstr "Points d'étalonnage" -#: flatcamTools/ToolCalibration.py:221 +#: flatcamTools/ToolCalibration.py:220 msgid "" "Contain the expected calibration points and the\n" "ones measured." @@ -13120,56 +13903,52 @@ msgstr "" "Contiennent les points d'étalonnage attendus et le\n" "ceux mesurés." -#: flatcamTools/ToolCalibration.py:236 flatcamTools/ToolSub.py:74 -#: flatcamTools/ToolSub.py:126 +#: flatcamTools/ToolCalibration.py:235 flatcamTools/ToolSub.py:76 +#: flatcamTools/ToolSub.py:131 msgid "Target" msgstr "Cible" -#: flatcamTools/ToolCalibration.py:237 +#: flatcamTools/ToolCalibration.py:236 msgid "Found Delta" msgstr "Delta trouvé" -#: flatcamTools/ToolCalibration.py:249 +#: flatcamTools/ToolCalibration.py:248 msgid "Bot Left X" msgstr "En bas à gauche X" -#: flatcamTools/ToolCalibration.py:258 +#: flatcamTools/ToolCalibration.py:257 msgid "Bot Left Y" msgstr "En bas à gauche Y" -#: flatcamTools/ToolCalibration.py:266 flatcamTools/ToolCalibration.py:267 -msgid "Origin" -msgstr "Origine" - -#: flatcamTools/ToolCalibration.py:278 +#: flatcamTools/ToolCalibration.py:275 msgid "Bot Right X" msgstr "En bas à droite X" -#: flatcamTools/ToolCalibration.py:288 +#: flatcamTools/ToolCalibration.py:285 msgid "Bot Right Y" msgstr "En bas à droite Y" -#: flatcamTools/ToolCalibration.py:303 +#: flatcamTools/ToolCalibration.py:300 msgid "Top Left X" msgstr "En haut à gauche X" -#: flatcamTools/ToolCalibration.py:312 +#: flatcamTools/ToolCalibration.py:309 msgid "Top Left Y" msgstr "En haut à gauche Y" -#: flatcamTools/ToolCalibration.py:327 +#: flatcamTools/ToolCalibration.py:324 msgid "Top Right X" msgstr "En haut à droite X" -#: flatcamTools/ToolCalibration.py:337 +#: flatcamTools/ToolCalibration.py:334 msgid "Top Right Y" msgstr "En haut à droite Y" -#: flatcamTools/ToolCalibration.py:370 +#: flatcamTools/ToolCalibration.py:367 msgid "Get Points" msgstr "Obtenir des points" -#: flatcamTools/ToolCalibration.py:372 +#: flatcamTools/ToolCalibration.py:369 msgid "" "Pick four points by clicking on canvas if the source choice\n" "is 'free' or inside the object geometry if the source is 'object'.\n" @@ -13183,11 +13962,11 @@ msgstr "" "Ces quatre points devraient être dans les quatre carrés de\n" "L'object." -#: flatcamTools/ToolCalibration.py:393 +#: flatcamTools/ToolCalibration.py:390 msgid "STEP 2: Verification GCode" msgstr "ÉTAPE 2: Vérification GCode" -#: flatcamTools/ToolCalibration.py:395 flatcamTools/ToolCalibration.py:408 +#: flatcamTools/ToolCalibration.py:392 flatcamTools/ToolCalibration.py:405 msgid "" "Generate GCode file to locate and align the PCB by using\n" "the four points acquired above.\n" @@ -13207,15 +13986,15 @@ msgstr "" "bas à droite.\n" "- quatrième point -> point de vérification final. Juste pour évaluation." -#: flatcamTools/ToolCalibration.py:406 flatcamTools/ToolSolderPaste.py:347 +#: flatcamTools/ToolCalibration.py:403 flatcamTools/ToolSolderPaste.py:349 msgid "Generate GCode" msgstr "Générer du GCode" -#: flatcamTools/ToolCalibration.py:432 +#: flatcamTools/ToolCalibration.py:429 msgid "STEP 3: Adjustments" msgstr "ÉTAPE 3: Ajustements" -#: flatcamTools/ToolCalibration.py:434 flatcamTools/ToolCalibration.py:443 +#: flatcamTools/ToolCalibration.py:431 flatcamTools/ToolCalibration.py:440 msgid "" "Calculate Scale and Skew factors based on the differences (delta)\n" "found when checking the PCB pattern. The differences must be filled\n" @@ -13227,15 +14006,15 @@ msgstr "" "être comblées\n" "dans les champs Trouvé (Delta)." -#: flatcamTools/ToolCalibration.py:441 +#: flatcamTools/ToolCalibration.py:438 msgid "Calculate Factors" msgstr "Calculer les facteurs" -#: flatcamTools/ToolCalibration.py:463 +#: flatcamTools/ToolCalibration.py:460 msgid "STEP 4: Adjusted GCode" msgstr "ÉTAPE 4: GCode ajusté" -#: flatcamTools/ToolCalibration.py:465 +#: flatcamTools/ToolCalibration.py:462 msgid "" "Generate verification GCode file adjusted with\n" "the factors above." @@ -13243,43 +14022,43 @@ msgstr "" "Générer un fichier GCode de vérification ajusté avec\n" "les facteurs ci-dessus." -#: flatcamTools/ToolCalibration.py:470 +#: flatcamTools/ToolCalibration.py:467 msgid "Scale Factor X:" msgstr "Facteur d'échelle X:" -#: flatcamTools/ToolCalibration.py:482 +#: flatcamTools/ToolCalibration.py:479 msgid "Scale Factor Y:" msgstr "Facteur d'échelle Y:" -#: flatcamTools/ToolCalibration.py:494 +#: flatcamTools/ToolCalibration.py:491 msgid "Apply Scale Factors" msgstr "Appliquer des facteurs d'échelle" -#: flatcamTools/ToolCalibration.py:496 +#: flatcamTools/ToolCalibration.py:493 msgid "Apply Scale factors on the calibration points." msgstr "Appliquez des facteurs d'échelle aux points d'étalonnage." -#: flatcamTools/ToolCalibration.py:506 +#: flatcamTools/ToolCalibration.py:503 msgid "Skew Angle X:" msgstr "Angle d'inclinaison X:" -#: flatcamTools/ToolCalibration.py:519 +#: flatcamTools/ToolCalibration.py:516 msgid "Skew Angle Y:" msgstr "Angle d'inclinaison Y:" -#: flatcamTools/ToolCalibration.py:532 +#: flatcamTools/ToolCalibration.py:529 msgid "Apply Skew Factors" msgstr "Appliquer les facteurs d'inclinaison" -#: flatcamTools/ToolCalibration.py:534 +#: flatcamTools/ToolCalibration.py:531 msgid "Apply Skew factors on the calibration points." msgstr "Appliquer des facteurs d'inclinaison sur les points d'étalonnage." -#: flatcamTools/ToolCalibration.py:603 +#: flatcamTools/ToolCalibration.py:600 msgid "Generate Adjusted GCode" msgstr "Générer un GCode ajusté" -#: flatcamTools/ToolCalibration.py:605 +#: flatcamTools/ToolCalibration.py:602 msgid "" "Generate verification GCode file adjusted with\n" "the factors set above.\n" @@ -13291,11 +14070,11 @@ msgstr "" "Les paramètres GCode peuvent être réajustés\n" "avant de cliquer sur ce bouton." -#: flatcamTools/ToolCalibration.py:626 +#: flatcamTools/ToolCalibration.py:623 msgid "STEP 5: Calibrate FlatCAM Objects" msgstr "ÉTAPE 5: Calibrer les objets FlatCAM" -#: flatcamTools/ToolCalibration.py:628 +#: flatcamTools/ToolCalibration.py:625 msgid "" "Adjust the FlatCAM objects\n" "with the factors determined and verified above." @@ -13303,27 +14082,27 @@ msgstr "" "Ajuster les objets FlatCAM\n" "avec les facteurs déterminés et vérifiés ci-dessus." -#: flatcamTools/ToolCalibration.py:641 +#: flatcamTools/ToolCalibration.py:637 msgid "Adjusted object type" msgstr "Type d'objet ajusté" -#: flatcamTools/ToolCalibration.py:643 +#: flatcamTools/ToolCalibration.py:638 msgid "Type of the FlatCAM Object to be adjusted." msgstr "Type de l'objet FlatCAM à ajuster." -#: flatcamTools/ToolCalibration.py:654 +#: flatcamTools/ToolCalibration.py:651 msgid "Adjusted object selection" msgstr "Sélection d'objet ajustée" -#: flatcamTools/ToolCalibration.py:656 +#: flatcamTools/ToolCalibration.py:653 msgid "The FlatCAM Object to be adjusted." msgstr "L'objet FlatCAM à ajuster." -#: flatcamTools/ToolCalibration.py:663 +#: flatcamTools/ToolCalibration.py:660 msgid "Calibrate" msgstr "Étalonner" -#: flatcamTools/ToolCalibration.py:665 +#: flatcamTools/ToolCalibration.py:662 msgid "" "Adjust (scale and/or skew) the objects\n" "with the factors determined above." @@ -13331,83 +14110,63 @@ msgstr "" "Ajustez (redimensionnez et / ou inclinez) les objets\n" "avec les facteurs déterminés ci-dessus." -#: flatcamTools/ToolCalibration.py:686 flatcamTools/ToolCopperThieving.py:482 -#: flatcamTools/ToolCutOut.py:362 flatcamTools/ToolDblSided.py:405 -#: flatcamTools/ToolFiducials.py:316 flatcamTools/ToolFilm.py:518 -#: flatcamTools/ToolNonCopperClear.py:486 flatcamTools/ToolOptimal.py:237 -#: flatcamTools/ToolPaint.py:372 flatcamTools/ToolPanelize.py:266 -#: flatcamTools/ToolQRCode.py:314 flatcamTools/ToolRulesCheck.py:507 -#: flatcamTools/ToolSolderPaste.py:470 flatcamTools/ToolSub.py:170 -msgid "Reset Tool" -msgstr "Réinitialiser l'outil" +#: flatcamTools/ToolCalibration.py:770 flatcamTools/ToolCalibration.py:771 +msgid "Origin" +msgstr "Origine" -#: flatcamTools/ToolCalibration.py:688 flatcamTools/ToolCopperThieving.py:484 -#: flatcamTools/ToolCutOut.py:364 flatcamTools/ToolDblSided.py:407 -#: flatcamTools/ToolFiducials.py:318 flatcamTools/ToolFilm.py:520 -#: flatcamTools/ToolNonCopperClear.py:488 flatcamTools/ToolOptimal.py:239 -#: flatcamTools/ToolPaint.py:374 flatcamTools/ToolPanelize.py:268 -#: flatcamTools/ToolQRCode.py:316 flatcamTools/ToolRulesCheck.py:509 -#: flatcamTools/ToolSolderPaste.py:472 flatcamTools/ToolSub.py:172 -msgid "Will reset the tool parameters." -msgstr "Réinitialise les paramètres de l'outil." - -#: flatcamTools/ToolCalibration.py:792 +#: flatcamTools/ToolCalibration.py:800 msgid "Tool initialized" msgstr "Outil initialisé" -#: flatcamTools/ToolCalibration.py:824 +#: flatcamTools/ToolCalibration.py:838 msgid "There is no source FlatCAM object selected..." msgstr "Aucun objet FlatCAM source n'est sélectionné ..." -#: flatcamTools/ToolCalibration.py:845 +#: flatcamTools/ToolCalibration.py:859 msgid "Get First calibration point. Bottom Left..." msgstr "Obtenez le premier point d'étalonnage. En bas à gauche..." -#: flatcamTools/ToolCalibration.py:906 -msgid "Cancelled by user request." -msgstr "Annulé par demande de l'utilisateur." - -#: flatcamTools/ToolCalibration.py:912 +#: flatcamTools/ToolCalibration.py:926 msgid "Get Second calibration point. Bottom Right (Top Left)..." msgstr "" "Obtenez le deuxième point d'étalonnage. En bas à droite (en haut à " "gauche) ..." -#: flatcamTools/ToolCalibration.py:916 +#: flatcamTools/ToolCalibration.py:930 msgid "Get Third calibration point. Top Left (Bottom Right)..." msgstr "" "Obtenez le troisième point d'étalonnage. En haut à gauche (en bas à " "droite) ..." -#: flatcamTools/ToolCalibration.py:920 +#: flatcamTools/ToolCalibration.py:934 msgid "Get Forth calibration point. Top Right..." msgstr "Obtenez le quatrième point d'étalonnage. En haut à droite..." -#: flatcamTools/ToolCalibration.py:924 +#: flatcamTools/ToolCalibration.py:938 msgid "Done. All four points have been acquired." msgstr "Terminé. Les quatre points ont été acquis." -#: flatcamTools/ToolCalibration.py:955 +#: flatcamTools/ToolCalibration.py:969 msgid "Verification GCode for FlatCAM Calibration Tool" msgstr "Vérification GCode pour l'outil d'étalonnage FlatCAM" -#: flatcamTools/ToolCalibration.py:967 flatcamTools/ToolCalibration.py:1053 +#: flatcamTools/ToolCalibration.py:981 flatcamTools/ToolCalibration.py:1067 msgid "Gcode Viewer" msgstr "Visionneuse Gcode" -#: flatcamTools/ToolCalibration.py:983 +#: flatcamTools/ToolCalibration.py:997 msgid "Cancelled. Four points are needed for GCode generation." msgstr "Annulé. Quatre points sont nécessaires pour la génération de GCode." -#: flatcamTools/ToolCalibration.py:1239 flatcamTools/ToolCalibration.py:1335 +#: flatcamTools/ToolCalibration.py:1253 flatcamTools/ToolCalibration.py:1349 msgid "There is no FlatCAM object selected..." msgstr "Aucun objet FlatCAM n'est sélectionné ..." -#: flatcamTools/ToolCopperThieving.py:76 flatcamTools/ToolFiducials.py:260 +#: flatcamTools/ToolCopperThieving.py:77 flatcamTools/ToolFiducials.py:261 msgid "Gerber Object to which will be added a copper thieving." msgstr "Objet Gerber auquel sera ajouté un voleur de cuivre." -#: flatcamTools/ToolCopperThieving.py:98 +#: flatcamTools/ToolCopperThieving.py:99 msgid "" "This set the distance between the copper thieving components\n" "(the polygon fill may be split in multiple polygons)\n" @@ -13417,7 +14176,7 @@ msgstr "" "(le remplissage du polygone peut être divisé en plusieurs polygones)\n" "et les traces de cuivre dans le fichier Gerber." -#: flatcamTools/ToolCopperThieving.py:131 +#: flatcamTools/ToolCopperThieving.py:132 msgid "" "- 'Itself' - the copper thieving extent is based on the object extent.\n" "- 'Area Selection' - left mouse click to start selection of the area to be " @@ -13432,12 +14191,12 @@ msgstr "" "- «Objet de référence» - effectuera un Copper Thieving dans la zone " "spécifiée par un autre objet." -#: flatcamTools/ToolCopperThieving.py:138 -#: flatcamTools/ToolNonCopperClear.py:445 flatcamTools/ToolPaint.py:326 +#: flatcamTools/ToolCopperThieving.py:139 flatcamTools/ToolNCC.py:552 +#: flatcamTools/ToolPaint.py:496 msgid "Ref. Type" msgstr "Type de Réf" -#: flatcamTools/ToolCopperThieving.py:140 +#: flatcamTools/ToolCopperThieving.py:141 msgid "" "The type of FlatCAM object to be used as copper thieving reference.\n" "It can be Gerber, Excellon or Geometry." @@ -13445,36 +14204,21 @@ msgstr "" "Type d'objet FlatCAM à utiliser comme référence de Copper Thieving.\n" "Il peut s'agir de Gerber, Excellon ou Geometry." -#: flatcamTools/ToolCopperThieving.py:144 flatcamTools/ToolDblSided.py:215 -#: flatcamTools/ToolNonCopperClear.py:451 flatcamTools/ToolPaint.py:332 -msgid "Reference Gerber" -msgstr "Référence Gerber" - -#: flatcamTools/ToolCopperThieving.py:145 flatcamTools/ToolDblSided.py:216 -#: flatcamTools/ToolNonCopperClear.py:452 flatcamTools/ToolPaint.py:333 -msgid "Reference Excellon" -msgstr "Référence Excellon" - -#: flatcamTools/ToolCopperThieving.py:146 flatcamTools/ToolDblSided.py:217 -#: flatcamTools/ToolNonCopperClear.py:453 flatcamTools/ToolPaint.py:334 -msgid "Reference Geometry" -msgstr "Géométrie de référence" - -#: flatcamTools/ToolCopperThieving.py:151 -#: flatcamTools/ToolNonCopperClear.py:456 flatcamTools/ToolPaint.py:337 +#: flatcamTools/ToolCopperThieving.py:150 flatcamTools/ToolNCC.py:562 +#: flatcamTools/ToolPaint.py:506 msgid "Ref. Object" msgstr "Réf. Objet" -#: flatcamTools/ToolCopperThieving.py:153 -#: flatcamTools/ToolNonCopperClear.py:458 flatcamTools/ToolPaint.py:339 +#: flatcamTools/ToolCopperThieving.py:152 flatcamTools/ToolNCC.py:564 +#: flatcamTools/ToolPaint.py:508 msgid "The FlatCAM object to be used as non copper clearing reference." msgstr "L'objet FlatCAM à utiliser comme référence d'effacement non en cuivre." -#: flatcamTools/ToolCopperThieving.py:326 +#: flatcamTools/ToolCopperThieving.py:328 msgid "Insert Copper thieving" msgstr "Insérer Copper Thieving" -#: flatcamTools/ToolCopperThieving.py:328 +#: flatcamTools/ToolCopperThieving.py:330 msgid "" "Will add a polygon (may be split in multiple parts)\n" "that will surround the actual Gerber traces at a certain distance." @@ -13482,11 +14226,11 @@ msgstr "" "Ajoutera un polygone (peut être divisé en plusieurs parties)\n" "qui entourera les traces réelles de Gerber à une certaine distance." -#: flatcamTools/ToolCopperThieving.py:387 +#: flatcamTools/ToolCopperThieving.py:389 msgid "Insert Robber Bar" msgstr "Insérer une Robber Bar" -#: flatcamTools/ToolCopperThieving.py:389 +#: flatcamTools/ToolCopperThieving.py:391 msgid "" "Will add a polygon with a defined thickness\n" "that will surround the actual Gerber object\n" @@ -13498,11 +14242,11 @@ msgstr "" "à une certaine distance.\n" "Requis lors du placage des trous." -#: flatcamTools/ToolCopperThieving.py:413 +#: flatcamTools/ToolCopperThieving.py:415 msgid "Select Soldermask object" msgstr "Sélectionner un objet Soldermask" -#: flatcamTools/ToolCopperThieving.py:415 +#: flatcamTools/ToolCopperThieving.py:417 msgid "" "Gerber Object with the soldermask.\n" "It will be used as a base for\n" @@ -13512,11 +14256,11 @@ msgstr "" "Il sera utilisé comme base pour\n" "le masque de placage de motifs." -#: flatcamTools/ToolCopperThieving.py:443 +#: flatcamTools/ToolCopperThieving.py:446 msgid "Plated area" msgstr "Zone plaquée" -#: flatcamTools/ToolCopperThieving.py:445 +#: flatcamTools/ToolCopperThieving.py:448 msgid "" "The area to be plated by pattern plating.\n" "Basically is made from the openings in the plating mask.\n" @@ -13535,19 +14279,19 @@ msgstr "" "un peu plus grand que les tampons en cuivre, et cette zone est\n" "calculé à partir des ouvertures du masque de soldat." -#: flatcamTools/ToolCopperThieving.py:456 +#: flatcamTools/ToolCopperThieving.py:459 msgid "mm" msgstr "mm" -#: flatcamTools/ToolCopperThieving.py:458 +#: flatcamTools/ToolCopperThieving.py:461 msgid "in" msgstr "in" -#: flatcamTools/ToolCopperThieving.py:465 +#: flatcamTools/ToolCopperThieving.py:468 msgid "Generate pattern plating mask" msgstr "Générer un masque de placage de motifs" -#: flatcamTools/ToolCopperThieving.py:467 +#: flatcamTools/ToolCopperThieving.py:470 msgid "" "Will add to the soldermask gerber geometry\n" "the geometries of the copper thieving and/or\n" @@ -13557,138 +14301,139 @@ msgstr "" "les géométries du Copper Thieving et / ou\n" "la Robber Bar si ceux-ci ont été générés." -#: flatcamTools/ToolCopperThieving.py:620 -#: flatcamTools/ToolCopperThieving.py:645 +#: flatcamTools/ToolCopperThieving.py:626 +#: flatcamTools/ToolCopperThieving.py:651 msgid "Lines Grid works only for 'itself' reference ..." msgstr "" "La grille de lignes fonctionne uniquement pour la référence «elle-même» ..." -#: flatcamTools/ToolCopperThieving.py:631 +#: flatcamTools/ToolCopperThieving.py:637 msgid "Solid fill selected." msgstr "Remplissage solide sélectionné." -#: flatcamTools/ToolCopperThieving.py:636 +#: flatcamTools/ToolCopperThieving.py:642 msgid "Dots grid fill selected." msgstr "Remplissage de la grille de points sélectionné." -#: flatcamTools/ToolCopperThieving.py:641 +#: flatcamTools/ToolCopperThieving.py:647 msgid "Squares grid fill selected." msgstr "Remplissage de la grille des carrés sélectionné." -#: flatcamTools/ToolCopperThieving.py:662 -#: flatcamTools/ToolCopperThieving.py:744 -#: flatcamTools/ToolCopperThieving.py:1340 flatcamTools/ToolDblSided.py:564 -#: flatcamTools/ToolFiducials.py:464 flatcamTools/ToolFiducials.py:741 -#: flatcamTools/ToolOptimal.py:342 flatcamTools/ToolQRCode.py:424 +#: flatcamTools/ToolCopperThieving.py:668 +#: flatcamTools/ToolCopperThieving.py:750 +#: flatcamTools/ToolCopperThieving.py:1346 flatcamTools/ToolDblSided.py:658 +#: flatcamTools/ToolExtractDrills.py:436 flatcamTools/ToolFiducials.py:466 +#: flatcamTools/ToolFiducials.py:743 flatcamTools/ToolOptimal.py:343 +#: flatcamTools/ToolPunchGerber.py:512 flatcamTools/ToolQRCode.py:426 msgid "There is no Gerber object loaded ..." msgstr "Il n'y a pas d'objet Gerber chargé ..." -#: flatcamTools/ToolCopperThieving.py:675 -#: flatcamTools/ToolCopperThieving.py:1268 +#: flatcamTools/ToolCopperThieving.py:681 +#: flatcamTools/ToolCopperThieving.py:1274 msgid "Append geometry" msgstr "Ajouter une géométrie" -#: flatcamTools/ToolCopperThieving.py:719 -#: flatcamTools/ToolCopperThieving.py:1301 -#: flatcamTools/ToolCopperThieving.py:1454 +#: flatcamTools/ToolCopperThieving.py:725 +#: flatcamTools/ToolCopperThieving.py:1307 +#: flatcamTools/ToolCopperThieving.py:1460 msgid "Append source file" msgstr "Ajouter un fichier source" -#: flatcamTools/ToolCopperThieving.py:727 -#: flatcamTools/ToolCopperThieving.py:1309 +#: flatcamTools/ToolCopperThieving.py:733 +#: flatcamTools/ToolCopperThieving.py:1315 msgid "Copper Thieving Tool done." msgstr "Outil de Copper Thieving fait." -#: flatcamTools/ToolCopperThieving.py:754 -#: flatcamTools/ToolCopperThieving.py:787 flatcamTools/ToolCutOut.py:468 -#: flatcamTools/ToolCutOut.py:642 flatcamTools/ToolNonCopperClear.py:1151 -#: flatcamTools/ToolNonCopperClear.py:1192 -#: flatcamTools/ToolNonCopperClear.py:1224 flatcamTools/ToolPaint.py:1074 -#: flatcamTools/ToolPanelize.py:401 flatcamTools/ToolPanelize.py:416 -#: flatcamTools/ToolSub.py:288 flatcamTools/ToolSub.py:301 -#: flatcamTools/ToolSub.py:492 flatcamTools/ToolSub.py:507 -#: tclCommands/TclCommandCopperClear.py:97 -#: tclCommands/TclCommandCopperClear.py:146 tclCommands/TclCommandPaint.py:97 +#: flatcamTools/ToolCopperThieving.py:760 +#: flatcamTools/ToolCopperThieving.py:793 flatcamTools/ToolCutOut.py:480 +#: flatcamTools/ToolCutOut.py:667 flatcamTools/ToolInvertGerber.py:208 +#: flatcamTools/ToolNCC.py:1594 flatcamTools/ToolNCC.py:1635 +#: flatcamTools/ToolNCC.py:1664 flatcamTools/ToolPaint.py:1469 +#: flatcamTools/ToolPanelize.py:413 flatcamTools/ToolPanelize.py:428 +#: flatcamTools/ToolSub.py:294 flatcamTools/ToolSub.py:307 +#: flatcamTools/ToolSub.py:498 flatcamTools/ToolSub.py:513 +#: tclCommands/TclCommandCopperClear.py:97 tclCommands/TclCommandPaint.py:99 msgid "Could not retrieve object" msgstr "Impossible de récupérer l'objet" -#: flatcamTools/ToolCopperThieving.py:764 -#: flatcamTools/ToolNonCopperClear.py:1205 +#: flatcamTools/ToolCopperThieving.py:770 flatcamTools/ToolNCC.py:1643 msgid "Click the start point of the area." msgstr "Cliquez sur le point de départ de la zone." -#: flatcamTools/ToolCopperThieving.py:815 +#: flatcamTools/ToolCopperThieving.py:821 msgid "Click the end point of the filling area." msgstr "Cliquez sur le point final de la zone de remplissage." -#: flatcamTools/ToolCopperThieving.py:821 -#: flatcamTools/ToolNonCopperClear.py:1261 flatcamTools/ToolPaint.py:1201 +#: flatcamTools/ToolCopperThieving.py:827 flatcamTools/ToolNCC.py:1705 +#: flatcamTools/ToolNCC.py:1757 flatcamTools/ToolPaint.py:1601 +#: flatcamTools/ToolPaint.py:1652 msgid "Zone added. Click to start adding next zone or right click to finish." msgstr "" "Zone ajoutée. Cliquez pour commencer à ajouter la zone suivante ou faites un " "clic droit pour terminer." -#: flatcamTools/ToolCopperThieving.py:937 -#: flatcamTools/ToolCopperThieving.py:941 -#: flatcamTools/ToolCopperThieving.py:1002 +#: flatcamTools/ToolCopperThieving.py:943 +#: flatcamTools/ToolCopperThieving.py:947 +#: flatcamTools/ToolCopperThieving.py:1008 msgid "Thieving" msgstr "Voleur" -#: flatcamTools/ToolCopperThieving.py:948 +#: flatcamTools/ToolCopperThieving.py:954 msgid "Copper Thieving Tool started. Reading parameters." msgstr "L'outil de Copper Thieving a démarré. Lecture des paramètres." -#: flatcamTools/ToolCopperThieving.py:973 +#: flatcamTools/ToolCopperThieving.py:979 msgid "Copper Thieving Tool. Preparing isolation polygons." msgstr "Outil de Copper Thieving. Préparation des polygones d'isolement." -#: flatcamTools/ToolCopperThieving.py:1018 +#: flatcamTools/ToolCopperThieving.py:1024 msgid "Copper Thieving Tool. Preparing areas to fill with copper." msgstr "Outil de Copper Thieving. Préparer les zones à remplir de cuivre." -#: flatcamTools/ToolCopperThieving.py:1029 flatcamTools/ToolOptimal.py:349 -#: flatcamTools/ToolPanelize.py:793 flatcamTools/ToolRulesCheck.py:1118 +#: flatcamTools/ToolCopperThieving.py:1035 flatcamTools/ToolOptimal.py:350 +#: flatcamTools/ToolPanelize.py:802 flatcamTools/ToolRulesCheck.py:1127 msgid "Working..." msgstr "Travail..." -#: flatcamTools/ToolCopperThieving.py:1056 +#: flatcamTools/ToolCopperThieving.py:1062 msgid "Geometry not supported for bounding box" msgstr "Géométrie non prise en charge pour le cadre de sélection" -#: flatcamTools/ToolCopperThieving.py:1062 -#: flatcamTools/ToolNonCopperClear.py:1513 flatcamTools/ToolPaint.py:2673 +#: flatcamTools/ToolCopperThieving.py:1068 flatcamTools/ToolNCC.py:1928 +#: flatcamTools/ToolNCC.py:1983 flatcamTools/ToolNCC.py:2987 +#: flatcamTools/ToolPaint.py:3375 msgid "No object available." msgstr "Aucun objet disponible." -#: flatcamTools/ToolCopperThieving.py:1099 -#: flatcamTools/ToolNonCopperClear.py:1555 +#: flatcamTools/ToolCopperThieving.py:1105 flatcamTools/ToolNCC.py:1953 +#: flatcamTools/ToolNCC.py:2006 flatcamTools/ToolNCC.py:3029 msgid "The reference object type is not supported." msgstr "Le type d'objet de référence n'est pas pris en charge." -#: flatcamTools/ToolCopperThieving.py:1104 +#: flatcamTools/ToolCopperThieving.py:1110 msgid "Copper Thieving Tool. Appending new geometry and buffering." msgstr "" "Outil de Copper Thieving. Ajout d'une nouvelle géométrie et mise en mémoire " "tampon." -#: flatcamTools/ToolCopperThieving.py:1120 +#: flatcamTools/ToolCopperThieving.py:1126 msgid "Create geometry" msgstr "Créer une géométrie" -#: flatcamTools/ToolCopperThieving.py:1320 -#: flatcamTools/ToolCopperThieving.py:1324 +#: flatcamTools/ToolCopperThieving.py:1326 +#: flatcamTools/ToolCopperThieving.py:1330 msgid "P-Plating Mask" msgstr "Masque de placage P" -#: flatcamTools/ToolCopperThieving.py:1346 +#: flatcamTools/ToolCopperThieving.py:1352 msgid "Append PP-M geometry" msgstr "Ajouter la géométrie du masque P de placage" -#: flatcamTools/ToolCopperThieving.py:1472 +#: flatcamTools/ToolCopperThieving.py:1478 msgid "Generating Pattern Plating Mask done." msgstr "Génération du masque de placage de motif terminée." -#: flatcamTools/ToolCopperThieving.py:1544 +#: flatcamTools/ToolCopperThieving.py:1550 msgid "Copper Thieving Tool exit." msgstr "Sortie de l'outil de Copper Thieving." @@ -13696,7 +14441,19 @@ msgstr "Sortie de l'outil de Copper Thieving." msgid "Cutout PCB" msgstr "Découpe de PCB" -#: flatcamTools/ToolCutOut.py:82 +#: flatcamTools/ToolCutOut.py:70 flatcamTools/ToolPanelize.py:54 +msgid "Source Object" +msgstr "Objet source" + +#: flatcamTools/ToolCutOut.py:71 +msgid "Object to be cutout" +msgstr "Objet à découper" + +#: flatcamTools/ToolCutOut.py:76 +msgid "Kind" +msgstr "Sorte" + +#: flatcamTools/ToolCutOut.py:98 msgid "" "Specify the type of object to be cutout.\n" "It can be of type: Gerber or Geometry.\n" @@ -13708,19 +14465,19 @@ msgstr "" "Ce qui est sélectionné ici dictera le genre\n" "des objets qui vont remplir la liste déroulante 'Object'." -#: flatcamTools/ToolCutOut.py:91 flatcamTools/ToolCutOut.py:92 -msgid "Object to be cutout" -msgstr "Objet à découper" +#: flatcamTools/ToolCutOut.py:122 +msgid "Tool Parameters" +msgstr "Paramètres d'outil" -#: flatcamTools/ToolCutOut.py:230 +#: flatcamTools/ToolCutOut.py:239 msgid "A. Automatic Bridge Gaps" msgstr "A. Lacunes automatiques des ponts" -#: flatcamTools/ToolCutOut.py:232 +#: flatcamTools/ToolCutOut.py:241 msgid "This section handle creation of automatic bridge gaps." msgstr "Cette section gère la création d'espaces de pontage automatiques." -#: flatcamTools/ToolCutOut.py:243 +#: flatcamTools/ToolCutOut.py:252 msgid "" "Number of gaps used for the Automatic cutout.\n" "There can be maximum 8 bridges/gaps.\n" @@ -13744,11 +14501,11 @@ msgstr "" "- 2tb - 2 * Haut + 2 * Bas\n" "- 8 - 2 * gauche + 2 * droite + 2 * en haut + 2 * en bas" -#: flatcamTools/ToolCutOut.py:264 +#: flatcamTools/ToolCutOut.py:273 msgid "Generate Freeform Geometry" msgstr "Générer une géométrie de forme libre" -#: flatcamTools/ToolCutOut.py:266 +#: flatcamTools/ToolCutOut.py:275 msgid "" "Cutout the selected object.\n" "The cutout shape can be of any shape.\n" @@ -13758,11 +14515,11 @@ msgstr "" "La forme de la découpe peut être de n'importe quelle forme.\n" "Utile lorsque le circuit imprimé a une forme non rectangulaire." -#: flatcamTools/ToolCutOut.py:278 +#: flatcamTools/ToolCutOut.py:287 msgid "Generate Rectangular Geometry" msgstr "Générer une géométrie rectangulaire" -#: flatcamTools/ToolCutOut.py:280 +#: flatcamTools/ToolCutOut.py:289 msgid "" "Cutout the selected object.\n" "The resulting cutout shape is\n" @@ -13774,11 +14531,11 @@ msgstr "" "toujours une forme de rectangle et ce sera\n" "la boîte englobante de l'objet." -#: flatcamTools/ToolCutOut.py:299 +#: flatcamTools/ToolCutOut.py:308 msgid "B. Manual Bridge Gaps" msgstr "B. Lacunes manuelles du pont" -#: flatcamTools/ToolCutOut.py:301 +#: flatcamTools/ToolCutOut.py:310 msgid "" "This section handle creation of manual bridge gaps.\n" "This is done by mouse clicking on the perimeter of the\n" @@ -13788,15 +14545,15 @@ msgstr "" "Cela se fait en cliquant avec la souris sur le périmètre de la\n" "Objet de géométrie utilisé comme objet de découpe. " -#: flatcamTools/ToolCutOut.py:319 +#: flatcamTools/ToolCutOut.py:329 msgid "Geometry object used to create the manual cutout." msgstr "Objet de géométrie utilisé pour créer la découpe manuelle." -#: flatcamTools/ToolCutOut.py:328 +#: flatcamTools/ToolCutOut.py:338 msgid "Generate Manual Geometry" msgstr "Générer une géométrie manuelle" -#: flatcamTools/ToolCutOut.py:330 +#: flatcamTools/ToolCutOut.py:340 msgid "" "If the object to be cutout is a Gerber\n" "first create a Geometry that surrounds it,\n" @@ -13809,11 +14566,11 @@ msgstr "" "Sélectionnez le fichier Gerber source dans la liste déroulante d'objets " "supérieure." -#: flatcamTools/ToolCutOut.py:343 +#: flatcamTools/ToolCutOut.py:353 msgid "Manual Add Bridge Gaps" msgstr "Ajout manuel de lacunes dans les ponts" -#: flatcamTools/ToolCutOut.py:345 +#: flatcamTools/ToolCutOut.py:355 msgid "" "Use the left mouse button (LMB) click\n" "to create a bridge gap to separate the PCB from\n" @@ -13827,7 +14584,7 @@ msgstr "" "Le clic LMB doit être fait sur le périmètre de\n" "l'objet Geometry utilisé en tant que géométrie de découpe." -#: flatcamTools/ToolCutOut.py:473 +#: flatcamTools/ToolCutOut.py:485 msgid "" "There is no object selected for Cutout.\n" "Select one and try again." @@ -13835,17 +14592,18 @@ msgstr "" "Aucun objet n'est sélectionné pour la découpe.\n" "Sélectionnez-en un et réessayez." -#: flatcamTools/ToolCutOut.py:479 flatcamTools/ToolCutOut.py:651 -#: flatcamTools/ToolCutOut.py:795 flatcamTools/ToolCutOut.py:877 +#: flatcamTools/ToolCutOut.py:491 flatcamTools/ToolCutOut.py:676 +#: flatcamTools/ToolCutOut.py:839 flatcamTools/ToolCutOut.py:921 +#: tclCommands/TclCommandGeoCutout.py:185 msgid "Tool Diameter is zero value. Change it to a positive real number." msgstr "" "Le diamètre de l'outil est égal à zéro. Changez-le en un nombre réel positif." -#: flatcamTools/ToolCutOut.py:493 flatcamTools/ToolCutOut.py:666 +#: flatcamTools/ToolCutOut.py:505 flatcamTools/ToolCutOut.py:691 msgid "Number of gaps value is missing. Add it and retry." msgstr "Le nombre de lacunes est manquant. Ajoutez-le et réessayez." -#: flatcamTools/ToolCutOut.py:498 flatcamTools/ToolCutOut.py:670 +#: flatcamTools/ToolCutOut.py:510 flatcamTools/ToolCutOut.py:695 msgid "" "Gaps value can be only one of: 'None', 'lr', 'tb', '2lr', '2tb', 4 or 8. " "Fill in a correct value and retry. " @@ -13854,7 +14612,7 @@ msgstr "" "'Aucune', 'lr', 'tb', '2lr', '2tb', 4 ou 8. Saisissez une valeur correcte, " "puis réessayez. " -#: flatcamTools/ToolCutOut.py:503 flatcamTools/ToolCutOut.py:676 +#: flatcamTools/ToolCutOut.py:515 flatcamTools/ToolCutOut.py:701 msgid "" "Cutout operation cannot be done on a multi-geo Geometry.\n" "Optionally, this Multi-geo Geometry can be converted to Single-geo " @@ -13867,40 +14625,45 @@ msgstr "" "géo,\n" "et après cela effectuer la découpe." -#: flatcamTools/ToolCutOut.py:625 flatcamTools/ToolCutOut.py:784 +#: flatcamTools/ToolCutOut.py:650 flatcamTools/ToolCutOut.py:828 msgid "Any form CutOut operation finished." msgstr "Opération de découpe Forme Libre terminée." -#: flatcamTools/ToolCutOut.py:646 flatcamTools/ToolNonCopperClear.py:1155 -#: flatcamTools/ToolPaint.py:994 flatcamTools/ToolPanelize.py:406 -#: tclCommands/TclCommandBbox.py:70 tclCommands/TclCommandNregions.py:70 +#: flatcamTools/ToolCutOut.py:671 flatcamTools/ToolInvertGerber.py:214 +#: flatcamTools/ToolNCC.py:1598 flatcamTools/ToolPaint.py:1392 +#: flatcamTools/ToolPanelize.py:418 tclCommands/TclCommandBbox.py:72 +#: tclCommands/TclCommandNregions.py:72 msgid "Object not found" msgstr "Objet non trouvé" -#: flatcamTools/ToolCutOut.py:789 +#: flatcamTools/ToolCutOut.py:814 +msgid "Rectangular cutout with negative margin is not possible." +msgstr "Une découpe rectangulaire avec une marge négative n'est pas possible." + +#: flatcamTools/ToolCutOut.py:833 msgid "" "Click on the selected geometry object perimeter to create a bridge gap ..." msgstr "" "Cliquez sur le périmètre de l'objet géométrique sélectionné pour créer un " "intervalle de pont ..." -#: flatcamTools/ToolCutOut.py:806 flatcamTools/ToolCutOut.py:832 +#: flatcamTools/ToolCutOut.py:850 flatcamTools/ToolCutOut.py:876 msgid "Could not retrieve Geometry object" msgstr "Impossible de récupérer l'objet de géométrie" -#: flatcamTools/ToolCutOut.py:837 +#: flatcamTools/ToolCutOut.py:881 msgid "Geometry object for manual cutout not found" msgstr "Objet de géométrie pour découpe manuelle introuvable" -#: flatcamTools/ToolCutOut.py:847 +#: flatcamTools/ToolCutOut.py:891 msgid "Added manual Bridge Gap." msgstr "Ajout d'un écart de pont manuel." -#: flatcamTools/ToolCutOut.py:859 +#: flatcamTools/ToolCutOut.py:903 msgid "Could not retrieve Gerber object" msgstr "Impossible de récupérer l'objet Gerber" -#: flatcamTools/ToolCutOut.py:864 +#: flatcamTools/ToolCutOut.py:908 msgid "" "There is no Gerber object selected for Cutout.\n" "Select one and try again." @@ -13908,7 +14671,7 @@ msgstr "" "Aucun objet Gerber n'a été sélectionné pour la découpe.\n" "Sélectionnez-en un et réessayez." -#: flatcamTools/ToolCutOut.py:870 +#: flatcamTools/ToolCutOut.py:914 msgid "" "The selected object has to be of Gerber type.\n" "Select a Gerber file and try again." @@ -13916,11 +14679,11 @@ msgstr "" "L'objet sélectionné doit être de type Gerber.\n" "Sélectionnez un fichier Gerber et réessayez." -#: flatcamTools/ToolCutOut.py:905 +#: flatcamTools/ToolCutOut.py:949 msgid "Geometry not supported for cutout" msgstr "Géométrie non prise en charge pour la découpe" -#: flatcamTools/ToolCutOut.py:960 +#: flatcamTools/ToolCutOut.py:1007 msgid "Making manual bridge gap..." msgstr "Faire un pont manuel ..." @@ -13928,12 +14691,20 @@ msgstr "Faire un pont manuel ..." msgid "2-Sided PCB" msgstr "PCB double face" -#: flatcamTools/ToolDblSided.py:60 +#: flatcamTools/ToolDblSided.py:53 +msgid "Mirror Operation" +msgstr "Miroir Opération" + +#: flatcamTools/ToolDblSided.py:54 +msgid "Objects to be mirrored" +msgstr "Objets à mettre en miroir" + +#: flatcamTools/ToolDblSided.py:66 msgid "Gerber to be mirrored" msgstr "Gerber en miroir" -#: flatcamTools/ToolDblSided.py:64 flatcamTools/ToolDblSided.py:92 -#: flatcamTools/ToolDblSided.py:122 +#: flatcamTools/ToolDblSided.py:70 flatcamTools/ToolDblSided.py:98 +#: flatcamTools/ToolDblSided.py:128 msgid "" "Mirrors (flips) the specified object around \n" "the specified axis. Does not create a new \n" @@ -13943,143 +14714,117 @@ msgstr "" "l'axe spécifié. Ne crée pas de nouveau\n" "objet, mais le modifie." -#: flatcamTools/ToolDblSided.py:88 +#: flatcamTools/ToolDblSided.py:94 msgid "Excellon Object to be mirrored." msgstr "Excellon Objet à refléter." -#: flatcamTools/ToolDblSided.py:117 +#: flatcamTools/ToolDblSided.py:123 msgid "Geometry Obj to be mirrored." msgstr "Objet de géométrie à refléter." -#: flatcamTools/ToolDblSided.py:179 -msgid "Point/Box Reference" -msgstr "Référence de Point/Box" +#: flatcamTools/ToolDblSided.py:159 +msgid "Mirror Parameters" +msgstr "Paramètres de Miroir" -#: flatcamTools/ToolDblSided.py:181 +#: flatcamTools/ToolDblSided.py:160 +msgid "Parameters for the mirror operation" +msgstr "Paramètres de l'opération Miroir" + +#: flatcamTools/ToolDblSided.py:165 +msgid "Mirror Axis" +msgstr "Axe de Miroir" + +#: flatcamTools/ToolDblSided.py:176 msgid "" -"If 'Point' is selected above it store the coordinates (x, y) through which\n" -"the mirroring axis passes.\n" -"If 'Box' is selected above, select here a FlatCAM object (Gerber, Exc or " -"Geo).\n" -"Through the center of this object pass the mirroring axis selected above." +"The coordinates used as reference for the mirror operation.\n" +"Can be:\n" +"- Point -> a set of coordinates (x,y) around which the object is mirrored\n" +"- Box -> a set of coordinates (x, y) obtained from the center of the\n" +"bounding box of another object selected below" msgstr "" -"Si 'Point' est sélectionné ci-dessus, il enregistre les coordonnées (x, y) " -"par lesquelles\n" -"l'axe de symétrie passe.\n" -"Si 'Box' est sélectionné ci-dessus, sélectionnez ici un objet FlatCAM " -"(Gerber, Exc ou Geo).\n" -"Au centre de cet objet, passez l’axe en miroir sélectionné ci-dessus." +"Les coordonnées utilisées comme référence pour l'opération miroir.\n" +"Peut être:\n" +"- Point -> un ensemble de coordonnées (x, y) autour desquelles l'objet est " +"mis en miroir\n" +"- Boîte -> un ensemble de coordonnées (x, y) obtenues à partir du centre de " +"la\n" +"cadre de délimitation d'un autre objet sélectionné ci-dessous" -#: flatcamTools/ToolDblSided.py:189 +#: flatcamTools/ToolDblSided.py:190 +msgid "Point coordinates" +msgstr "Coordonnées du point" + +#: flatcamTools/ToolDblSided.py:195 msgid "" "Add the coordinates in format (x, y) through which the mirroring " "axis \n" " selected in 'MIRROR AXIS' pass.\n" "The (x, y) coordinates are captured by pressing SHIFT key\n" -"and left mouse button click on canvas or you can enter the coords manually." +"and left mouse button click on canvas or you can enter the coordinates " +"manually." msgstr "" -"Ajoutez les coordonnées au format (x, y) à travers lequel l'axe de " -"symétrie\n" -"sélectionné dans la passe 'AXE MIROIR'.\n" -"Les coordonnées (x, y) sont capturées en appuyant sur la touche SHIFT\n" +"Ajoutez les coordonnées au format (x, y) à travers lesquelles l'axe " +"de symétrie\n" +"  sélectionné dans la passe 'AXE MIROIR'.\n" +"Les coordonnées (x, y) sont capturées en appuyant sur la touche MAJ\n" "et cliquez avec le bouton gauche de la souris sur la toile ou vous pouvez " "entrer les coordonnées manuellement." -#: flatcamTools/ToolDblSided.py:230 -msgid "Alignment Drill Coordinates" -msgstr "Coordonnées du foret d'alignement" - -#: flatcamTools/ToolDblSided.py:232 +#: flatcamTools/ToolDblSided.py:219 msgid "" -"Alignment holes (x1, y1), (x2, y2), ... on one side of the mirror axis. For " -"each set of (x, y) coordinates\n" -"entered here, a pair of drills will be created:\n" -"\n" -"- one drill at the coordinates from the field\n" -"- one drill in mirror position over the axis selected above in the 'Mirror " -"Axis'." +"It can be of type: Gerber or Excellon or Geometry.\n" +"The coordinates of the center of the bounding box are used\n" +"as reference for mirror operation." msgstr "" -"Trous d'alignement (x1, y1), (x2, y2), ... d'un côté de l'axe du miroir. " -"Pour chaque ensemble de coordonnées (x, y)\n" -"entré ici, une paire d'exercices sera créée:\n" -"\n" -"- un exercice aux coordonnées du terrain\n" -"- un foret en position miroir sur l'axe sélectionné ci-dessus dans l'axe des " -"miroirs." +"Il peut être de type: Gerber ou Excellon ou Géométrie.\n" +"Les coordonnées du centre du cadre de sélection sont utilisées\n" +"comme référence pour le fonctionnement du miroir." -#: flatcamTools/ToolDblSided.py:247 +#: flatcamTools/ToolDblSided.py:253 +msgid "Bounds Values" +msgstr "Valeurs limites" + +#: flatcamTools/ToolDblSided.py:255 msgid "" -"Add alignment drill holes coords in the format: (x1, y1), (x2, y2), ... \n" -"on one side of the mirror axis.\n" -"\n" -"The coordinates set can be obtained:\n" -"- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" -"- press SHIFT key and left mouse clicking on canvas. Then Ctrl+V in the " -"field.\n" -"- press SHIFT key and left mouse clicking on canvas. Then RMB click in the " -"field and click Paste.\n" -"- by entering the coords manually in the format: (x1, y1), (x2, y2), ..." +"Select on canvas the object(s)\n" +"for which to calculate bounds values." msgstr "" -"Ajouter des trous d'alignement dans le format: (x1, y1), (x2, y2), ...\n" -"d'un côté de l'axe du miroir.\n" -"\n" -"Le jeu de coordonnées peut être obtenu:\n" -"- Appuyez sur la touche SHIFT et cliquez avec le bouton gauche de la souris " -"sur la toile. Puis cliquez sur Ajouter.\n" -"- Appuyez sur la touche SHIFT et cliquez avec le bouton gauche de la souris " -"sur la toile. Puis CTRL + V dans le champ.\n" -"- Appuyez sur la touche SHIFT et cliquez avec le bouton gauche de la souris " -"sur la toile. Ensuite, cliquez sur RMB dans le champ et cliquez sur Coller.\n" -"- en saisissant manuellement les coordonnées au format: (x1, y1), (x2, " -"y2), ..." +"Sélectionnez sur le canevas le ou les objets\n" +"pour lequel calculer les valeurs limites." -#: flatcamTools/ToolDblSided.py:272 -msgid "Alignment Drill Diameter" -msgstr "Diamètre du foret d'alignement" - -#: flatcamTools/ToolDblSided.py:292 -msgid "Create Excellon Object" -msgstr "Créer un objet Excellon" - -#: flatcamTools/ToolDblSided.py:294 -msgid "" -"Creates an Excellon Object containing the\n" -"specified alignment holes and their mirror\n" -"images." -msgstr "" -"Crée un objet Excellon contenant le\n" -"trous d'alignement spécifiés et leur miroir\n" -"images." - -#: flatcamTools/ToolDblSided.py:323 +#: flatcamTools/ToolDblSided.py:265 msgid "X min" msgstr "X min" -#: flatcamTools/ToolDblSided.py:325 flatcamTools/ToolDblSided.py:339 +#: flatcamTools/ToolDblSided.py:267 flatcamTools/ToolDblSided.py:281 msgid "Minimum location." msgstr "Emplacement minimum." -#: flatcamTools/ToolDblSided.py:337 +#: flatcamTools/ToolDblSided.py:279 msgid "Y min" msgstr "Y min" -#: flatcamTools/ToolDblSided.py:351 +#: flatcamTools/ToolDblSided.py:293 msgid "X max" msgstr "X max" -#: flatcamTools/ToolDblSided.py:353 flatcamTools/ToolDblSided.py:367 +#: flatcamTools/ToolDblSided.py:295 flatcamTools/ToolDblSided.py:309 msgid "Maximum location." msgstr "Emplacement maximum." -#: flatcamTools/ToolDblSided.py:365 +#: flatcamTools/ToolDblSided.py:307 msgid "Y max" msgstr "Y max" -#: flatcamTools/ToolDblSided.py:377 +#: flatcamTools/ToolDblSided.py:318 +msgid "Center point coordinates" +msgstr "Coordonnées du point central" + +#: flatcamTools/ToolDblSided.py:320 msgid "Centroid" msgstr "Centroïde" -#: flatcamTools/ToolDblSided.py:379 +#: flatcamTools/ToolDblSided.py:322 msgid "" "The center point location for the rectangular\n" "bounding shape. Centroid. Format is (x, y)." @@ -14087,11 +14832,11 @@ msgstr "" "L'emplacement du point central pour le rectangulaire\n" "forme de délimitation. Centroïde. Le format est (x, y)." -#: flatcamTools/ToolDblSided.py:388 +#: flatcamTools/ToolDblSided.py:331 msgid "Calculate Bounds Values" msgstr "Calculer les valeurs limites" -#: flatcamTools/ToolDblSided.py:390 +#: flatcamTools/ToolDblSided.py:333 msgid "" "Calculate the enveloping rectangular shape coordinates,\n" "for the selection of objects.\n" @@ -14101,11 +14846,105 @@ msgstr "" "pour la sélection d'objets.\n" "La forme de l'enveloppe est parallèle à l'axe X, Y." -#: flatcamTools/ToolDblSided.py:462 +#: flatcamTools/ToolDblSided.py:353 +msgid "PCB Alignment" +msgstr "Alignement PCB" + +#: flatcamTools/ToolDblSided.py:355 flatcamTools/ToolDblSided.py:457 +msgid "" +"Creates an Excellon Object containing the\n" +"specified alignment holes and their mirror\n" +"images." +msgstr "" +"Crée un objet Excellon contenant le\n" +"trous d'alignement spécifiés et leur miroir\n" +"images." + +#: flatcamTools/ToolDblSided.py:362 +msgid "Drill Diameter" +msgstr "Dia. de perçage" + +#: flatcamTools/ToolDblSided.py:391 flatcamTools/ToolDblSided.py:398 +msgid "" +"The reference point used to create the second alignment drill\n" +"from the first alignment drill, by doing mirror.\n" +"It can be modified in the Mirror Parameters -> Reference section" +msgstr "" +"Le point de référence utilisé pour créer le deuxième foret d'alignement\n" +"du premier foret d'alignement, en faisant miroir.\n" +"Il peut être modifié dans la section Paramètres miroir -> Référence" + +#: flatcamTools/ToolDblSided.py:411 +msgid "Alignment Drill Coordinates" +msgstr "Coordonnées du foret d'alignement" + +#: flatcamTools/ToolDblSided.py:413 +msgid "" +"Alignment holes (x1, y1), (x2, y2), ... on one side of the mirror axis. For " +"each set of (x, y) coordinates\n" +"entered here, a pair of drills will be created:\n" +"\n" +"- one drill at the coordinates from the field\n" +"- one drill in mirror position over the axis selected above in the 'Align " +"Axis'." +msgstr "" +"Trous d'alignement (x1, y1), (x2, y2), ... d'un côté de l'axe du miroir. " +"Pour chaque ensemble de coordonnées (x, y)\n" +"entrée ici, une paire de forets sera créée:\n" +"\n" +"- un foret aux coordonnées du terrain\n" +"- un foret en position miroir sur l'axe sélectionné ci-dessus dans 'Aligner " +"l'axe'." + +#: flatcamTools/ToolDblSided.py:421 +msgid "Drill coordinates" +msgstr "Coordonnées de forage" + +#: flatcamTools/ToolDblSided.py:428 +msgid "" +"Add alignment drill holes coordinates in the format: (x1, y1), (x2, " +"y2), ... \n" +"on one side of the alignment axis.\n" +"\n" +"The coordinates set can be obtained:\n" +"- press SHIFT key and left mouse clicking on canvas. Then click Add.\n" +"- press SHIFT key and left mouse clicking on canvas. Then Ctrl+V in the " +"field.\n" +"- press SHIFT key and left mouse clicking on canvas. Then RMB click in the " +"field and click Paste.\n" +"- by entering the coords manually in the format: (x1, y1), (x2, y2), ..." +msgstr "" +"Ajoutez les coordonnées des trous d'alignement au format: (x1, y1), (x2, " +"y2), ...\n" +"d'un côté de l'axe d'alignement.\n" +"\n" +"L'ensemble de coordonnées peut être obtenu:\n" +"- appuyez sur la touche SHIFT et cliquez avec le bouton gauche de la souris " +"sur le canevas. Cliquez ensuite sur Ajouter.\n" +"- appuyez sur la touche SHIFT et cliquez avec le bouton gauche de la souris " +"sur le canevas. Puis Ctrl + V dans le champ.\n" +"- appuyez sur la touche SHIFT et cliquez avec le bouton gauche de la souris " +"sur le canevas. Ensuite, RMB cliquez dans le champ et cliquez sur Coller.\n" +"- en saisissant manuellement les coordonnées au format: (x1, y1), (x2, " +"y2), ..." + +#: flatcamTools/ToolDblSided.py:443 +msgid "Delete Last" +msgstr "Supprimer le dernier" + +#: flatcamTools/ToolDblSided.py:445 +msgid "Delete the last coordinates tuple in the list." +msgstr "Supprimez le dernier tuple de coordonnées de la liste." + +#: flatcamTools/ToolDblSided.py:455 +msgid "Create Excellon Object" +msgstr "Créer un objet Excellon" + +#: flatcamTools/ToolDblSided.py:542 msgid "2-Sided Tool" msgstr "Outil de PCB double face" -#: flatcamTools/ToolDblSided.py:493 +#: flatcamTools/ToolDblSided.py:582 msgid "" "'Point' reference is selected and 'Point' coordinates are missing. Add them " "and retry." @@ -14113,55 +14952,34 @@ msgstr "" "La référence 'Point' est sélectionnée et les coordonnées 'Point' sont " "manquantes. Ajoutez-les et réessayez." -#: flatcamTools/ToolDblSided.py:512 +#: flatcamTools/ToolDblSided.py:601 msgid "There is no Box reference object loaded. Load one and retry." msgstr "" "Il n'y a pas d'objet de référence Box chargé. Chargez-en un et réessayez." -#: flatcamTools/ToolDblSided.py:524 +#: flatcamTools/ToolDblSided.py:613 msgid "No value or wrong format in Drill Dia entry. Add it and retry." msgstr "" "Aucune valeur ou format incorrect dans l'entrée du diamètre du Forage. " "Ajoutez-le et réessayez." -#: flatcamTools/ToolDblSided.py:532 +#: flatcamTools/ToolDblSided.py:624 msgid "There are no Alignment Drill Coordinates to use. Add them and retry." msgstr "" "Il n’ya pas de coordonnées de perceuse d’alignement à utiliser. Ajoutez-les " "et réessayez." -#: flatcamTools/ToolDblSided.py:555 +#: flatcamTools/ToolDblSided.py:649 msgid "Excellon object with alignment drills created..." msgstr "Excellon objet avec des exercices d'alignement créé ..." -#: flatcamTools/ToolDblSided.py:568 flatcamTools/ToolDblSided.py:611 -#: flatcamTools/ToolDblSided.py:655 +#: flatcamTools/ToolDblSided.py:662 flatcamTools/ToolDblSided.py:705 +#: flatcamTools/ToolDblSided.py:749 msgid "Only Gerber, Excellon and Geometry objects can be mirrored." msgstr "" "Seuls les objets Gerber, Excellon et Geometry peuvent être mis en miroir." -#: flatcamTools/ToolDblSided.py:578 -msgid "" -"'Point' coordinates missing. Using Origin (0, 0) as mirroring reference." -msgstr "" -"Les coordonnées 'Point' sont manquantes. Utilisation de Origin (0, 0) comme " -"référence en miroir." - -#: flatcamTools/ToolDblSided.py:588 flatcamTools/ToolDblSided.py:632 -#: flatcamTools/ToolDblSided.py:669 -msgid "There is no Box object loaded ..." -msgstr "Il n'y a pas d'objet Box chargé ..." - -#: flatcamTools/ToolDblSided.py:598 flatcamTools/ToolDblSided.py:642 -#: flatcamTools/ToolDblSided.py:679 -msgid "was mirrored" -msgstr "a été mis en miroir" - -#: flatcamTools/ToolDblSided.py:607 -msgid "There is no Excellon object loaded ..." -msgstr "Il n'y a pas d'objet Excellon chargé ..." - -#: flatcamTools/ToolDblSided.py:622 +#: flatcamTools/ToolDblSided.py:672 flatcamTools/ToolDblSided.py:716 msgid "" "There are no Point coordinates in the Point field. Add coords and try " "again ..." @@ -14169,98 +14987,137 @@ msgstr "" "Il n'y a pas de coordonnées de point dans le champ Point. Ajoutez des " "coordonnées et réessayez ..." -#: flatcamTools/ToolDblSided.py:651 +#: flatcamTools/ToolDblSided.py:682 flatcamTools/ToolDblSided.py:726 +#: flatcamTools/ToolDblSided.py:763 +msgid "There is no Box object loaded ..." +msgstr "Il n'y a pas d'objet Box chargé ..." + +#: flatcamTools/ToolDblSided.py:692 flatcamTools/ToolDblSided.py:736 +#: flatcamTools/ToolDblSided.py:773 +msgid "was mirrored" +msgstr "a été mis en miroir" + +#: flatcamTools/ToolDblSided.py:701 flatcamTools/ToolPunchGerber.py:533 +msgid "There is no Excellon object loaded ..." +msgstr "Il n'y a pas d'objet Excellon chargé ..." + +#: flatcamTools/ToolDblSided.py:745 msgid "There is no Geometry object loaded ..." msgstr "Il n'y a pas d'objet Geometry chargé ..." -#: flatcamTools/ToolDistance.py:50 flatcamTools/ToolDistanceMin.py:50 +#: flatcamTools/ToolDistance.py:57 flatcamTools/ToolDistanceMin.py:51 msgid "Those are the units in which the distance is measured." msgstr "Ce sont les unités dans lesquelles la distance est mesurée." -#: flatcamTools/ToolDistance.py:51 flatcamTools/ToolDistanceMin.py:51 +#: flatcamTools/ToolDistance.py:58 flatcamTools/ToolDistanceMin.py:52 msgid "METRIC (mm)" msgstr "MÉTRIQUE (mm)" -#: flatcamTools/ToolDistance.py:51 flatcamTools/ToolDistanceMin.py:51 +#: flatcamTools/ToolDistance.py:58 flatcamTools/ToolDistanceMin.py:52 msgid "INCH (in)" msgstr "POUCES (po)" -#: flatcamTools/ToolDistance.py:54 +#: flatcamTools/ToolDistance.py:64 +msgid "Snap to center" +msgstr "Accrocher au centre" + +#: flatcamTools/ToolDistance.py:66 +msgid "" +"Mouse cursor will snap to the center of the pad/drill\n" +"when it is hovering over the geometry of the pad/drill." +msgstr "" +"Le curseur de la souris se positionnera au centre du pad / drill\n" +"lorsqu'il survole la géométrie du tampon / de la perceuse." + +#: flatcamTools/ToolDistance.py:76 msgid "Start Coords" msgstr "Démarrer Coords" -#: flatcamTools/ToolDistance.py:55 flatcamTools/ToolDistance.py:75 +#: flatcamTools/ToolDistance.py:77 flatcamTools/ToolDistance.py:82 msgid "This is measuring Start point coordinates." msgstr "Ceci mesure les coordonnées du point de départ." -#: flatcamTools/ToolDistance.py:57 +#: flatcamTools/ToolDistance.py:87 msgid "Stop Coords" msgstr "Arrêtez Coords" -#: flatcamTools/ToolDistance.py:58 flatcamTools/ToolDistance.py:80 +#: flatcamTools/ToolDistance.py:88 flatcamTools/ToolDistance.py:93 msgid "This is the measuring Stop point coordinates." msgstr "Ce sont les coordonnées du point d'arrêt de la mesure." -#: flatcamTools/ToolDistance.py:60 flatcamTools/ToolDistanceMin.py:62 +#: flatcamTools/ToolDistance.py:98 flatcamTools/ToolDistanceMin.py:63 msgid "Dx" msgstr "Dx" -#: flatcamTools/ToolDistance.py:61 flatcamTools/ToolDistance.py:85 -#: flatcamTools/ToolDistanceMin.py:63 flatcamTools/ToolDistanceMin.py:92 +#: flatcamTools/ToolDistance.py:99 flatcamTools/ToolDistance.py:104 +#: flatcamTools/ToolDistanceMin.py:64 flatcamTools/ToolDistanceMin.py:93 msgid "This is the distance measured over the X axis." msgstr "C'est la distance mesurée sur l'axe X." -#: flatcamTools/ToolDistance.py:63 flatcamTools/ToolDistanceMin.py:65 +#: flatcamTools/ToolDistance.py:109 flatcamTools/ToolDistanceMin.py:66 msgid "Dy" msgstr "Dy" -#: flatcamTools/ToolDistance.py:64 flatcamTools/ToolDistance.py:90 -#: flatcamTools/ToolDistanceMin.py:66 flatcamTools/ToolDistanceMin.py:97 +#: flatcamTools/ToolDistance.py:110 flatcamTools/ToolDistance.py:115 +#: flatcamTools/ToolDistanceMin.py:67 flatcamTools/ToolDistanceMin.py:98 msgid "This is the distance measured over the Y axis." msgstr "C'est la distance mesurée sur l'axe Y." -#: flatcamTools/ToolDistance.py:67 flatcamTools/ToolDistance.py:95 -#: flatcamTools/ToolDistanceMin.py:69 flatcamTools/ToolDistanceMin.py:102 +#: flatcamTools/ToolDistance.py:121 flatcamTools/ToolDistance.py:126 +#: flatcamTools/ToolDistanceMin.py:70 flatcamTools/ToolDistanceMin.py:103 msgid "This is orientation angle of the measuring line." msgstr "C'est l'angle d'orientation de la ligne de mesure." -#: flatcamTools/ToolDistance.py:69 flatcamTools/ToolDistanceMin.py:71 +#: flatcamTools/ToolDistance.py:131 flatcamTools/ToolDistanceMin.py:72 msgid "DISTANCE" msgstr "DISTANCE" -#: flatcamTools/ToolDistance.py:70 flatcamTools/ToolDistance.py:100 +#: flatcamTools/ToolDistance.py:132 flatcamTools/ToolDistance.py:137 msgid "This is the point to point Euclidian distance." msgstr "C'est la distance euclidienne de point à point." -#: flatcamTools/ToolDistance.py:102 flatcamTools/ToolDistanceMin.py:114 +#: flatcamTools/ToolDistance.py:142 flatcamTools/ToolDistance.py:337 +#: flatcamTools/ToolDistanceMin.py:115 msgid "Measure" msgstr "Mesure" -#: flatcamTools/ToolDistance.py:212 +#: flatcamTools/ToolDistance.py:272 +msgid "Working" +msgstr "Travail" + +#: flatcamTools/ToolDistance.py:277 msgid "MEASURING: Click on the Start point ..." msgstr "MESURE: Cliquez sur le point de départ ..." -#: flatcamTools/ToolDistance.py:345 +#: flatcamTools/ToolDistance.py:387 +msgid "Distance Tool finished." +msgstr "Outil Distance terminé." + +#: flatcamTools/ToolDistance.py:455 +msgid "Pads overlapped. Aborting." +msgstr "Les coussinets se chevauchaient. Abandon." + +#: flatcamTools/ToolDistance.py:485 msgid "MEASURING: Click on the Destination point ..." msgstr "MESURE: Cliquez sur le point de destination ..." -#: flatcamTools/ToolDistance.py:353 flatcamTools/ToolDistanceMin.py:282 +#: flatcamTools/ToolDistance.py:494 flatcamTools/ToolDistanceMin.py:285 msgid "MEASURING" msgstr "MESURE" -#: flatcamTools/ToolDistance.py:354 flatcamTools/ToolDistanceMin.py:283 +#: flatcamTools/ToolDistance.py:495 flatcamTools/ToolDistanceMin.py:286 msgid "Result" msgstr "Résultat" -#: flatcamTools/ToolDistanceMin.py:31 flatcamTools/ToolDistanceMin.py:152 +#: flatcamTools/ToolDistanceMin.py:32 flatcamTools/ToolDistanceMin.py:144 msgid "Minimum Distance Tool" msgstr "Outil de Distance Minimale" -#: flatcamTools/ToolDistanceMin.py:54 +#: flatcamTools/ToolDistanceMin.py:55 msgid "First object point" msgstr "Premier point" -#: flatcamTools/ToolDistanceMin.py:55 flatcamTools/ToolDistanceMin.py:80 +#: flatcamTools/ToolDistanceMin.py:56 flatcamTools/ToolDistanceMin.py:81 msgid "" "This is first object point coordinates.\n" "This is the start point for measuring distance." @@ -14268,11 +15125,11 @@ msgstr "" "Ce sont les premières coordonnées du point d'objet.\n" "C'est le point de départ pour mesurer la distance." -#: flatcamTools/ToolDistanceMin.py:58 +#: flatcamTools/ToolDistanceMin.py:59 msgid "Second object point" msgstr "Deuxième point" -#: flatcamTools/ToolDistanceMin.py:59 flatcamTools/ToolDistanceMin.py:86 +#: flatcamTools/ToolDistanceMin.py:60 flatcamTools/ToolDistanceMin.py:87 msgid "" "This is second object point coordinates.\n" "This is the end point for measuring distance." @@ -14280,44 +15137,61 @@ msgstr "" "Ce sont les coordonnées du deuxième point de l'objet.\n" "C'est le point final pour mesurer la distance." -#: flatcamTools/ToolDistanceMin.py:72 flatcamTools/ToolDistanceMin.py:107 +#: flatcamTools/ToolDistanceMin.py:73 flatcamTools/ToolDistanceMin.py:108 msgid "This is the point to point Euclidean distance." msgstr "C'est la distance euclidienne de point à point." -#: flatcamTools/ToolDistanceMin.py:74 +#: flatcamTools/ToolDistanceMin.py:75 msgid "Half Point" msgstr "Demi point" -#: flatcamTools/ToolDistanceMin.py:75 flatcamTools/ToolDistanceMin.py:112 +#: flatcamTools/ToolDistanceMin.py:76 flatcamTools/ToolDistanceMin.py:113 msgid "This is the middle point of the point to point Euclidean distance." msgstr "C'est le point central de la distance euclidienne point à point." -#: flatcamTools/ToolDistanceMin.py:117 +#: flatcamTools/ToolDistanceMin.py:118 msgid "Jump to Half Point" msgstr "Aller au demi point" -#: flatcamTools/ToolDistanceMin.py:163 +#: flatcamTools/ToolDistanceMin.py:155 msgid "" "Select two objects and no more, to measure the distance between them ..." msgstr "" "Sélectionnez deux objets et pas plus, pour mesurer la distance qui les " "sépare ..." -#: flatcamTools/ToolDistanceMin.py:204 flatcamTools/ToolDistanceMin.py:214 -#: flatcamTools/ToolDistanceMin.py:223 flatcamTools/ToolDistanceMin.py:244 +#: flatcamTools/ToolDistanceMin.py:196 flatcamTools/ToolDistanceMin.py:217 +#: flatcamTools/ToolDistanceMin.py:226 flatcamTools/ToolDistanceMin.py:247 msgid "Select two objects and no more. Currently the selection has objects: " msgstr "" "Sélectionnez deux objets et pas plus. Actuellement, la sélection a des " "objets: " -#: flatcamTools/ToolDistanceMin.py:291 +#: flatcamTools/ToolDistanceMin.py:294 msgid "Objects intersects or touch at" msgstr "Les objets se croisent ou se touchent à" -#: flatcamTools/ToolDistanceMin.py:297 +#: flatcamTools/ToolDistanceMin.py:300 msgid "Jumped to the half point between the two selected objects" msgstr "Sauté au demi-point entre les deux objets sélectionnés" +#: flatcamTools/ToolExtractDrills.py:29 flatcamTools/ToolExtractDrills.py:295 +msgid "Extract Drills" +msgstr "Extraire des forets" + +#: flatcamTools/ToolExtractDrills.py:62 +msgid "Gerber from which to extract drill holes" +msgstr "Gerber d'où extraire les trous de forage" + +#: flatcamTools/ToolExtractDrills.py:297 +msgid "Extract drills from a given Gerber file." +msgstr "Extraire les trous de forage d'un fichier Gerber donné." + +#: flatcamTools/ToolExtractDrills.py:478 flatcamTools/ToolExtractDrills.py:563 +#: flatcamTools/ToolExtractDrills.py:648 +msgid "No drills extracted. Try different parameters." +msgstr "Aucun trou de forage extrait. Essayez différents paramètres." + #: flatcamTools/ToolFiducials.py:56 msgid "Fiducials Coordinates" msgstr "Coordonnées de Fiducials" @@ -14334,10 +15208,6 @@ msgstr "" msgid "Top Right" msgstr "En haut à droite" -#: flatcamTools/ToolFiducials.py:111 -msgid "Second Point" -msgstr "Deuxième point" - #: flatcamTools/ToolFiducials.py:191 msgid "" "- 'Auto' - automatic placement of fiducials in the corners of the bounding " @@ -14348,31 +15218,31 @@ msgstr "" "sélection.\n" "- «Manuel» - placement manuel des fiduciaires." -#: flatcamTools/ToolFiducials.py:258 +#: flatcamTools/ToolFiducials.py:259 msgid "Copper Gerber" msgstr "Gerber cuivré" -#: flatcamTools/ToolFiducials.py:267 +#: flatcamTools/ToolFiducials.py:268 msgid "Add Fiducial" msgstr "Ajouter Fiducial" -#: flatcamTools/ToolFiducials.py:269 +#: flatcamTools/ToolFiducials.py:270 msgid "Will add a polygon on the copper layer to serve as fiducial." msgstr "Ajoutera un polygone sur la couche de cuivre pour servir de repère." -#: flatcamTools/ToolFiducials.py:285 +#: flatcamTools/ToolFiducials.py:286 msgid "Soldermask Gerber" msgstr "Soldermask Gerber" -#: flatcamTools/ToolFiducials.py:287 +#: flatcamTools/ToolFiducials.py:288 msgid "The Soldermask Gerber object." msgstr "L'objet Soldermask Gerber." -#: flatcamTools/ToolFiducials.py:298 +#: flatcamTools/ToolFiducials.py:300 msgid "Add Soldermask Opening" msgstr "Ajouter une ouverture de Soldermask" -#: flatcamTools/ToolFiducials.py:300 +#: flatcamTools/ToolFiducials.py:302 msgid "" "Will add a polygon on the soldermask layer\n" "to serve as fiducial opening.\n" @@ -14384,25 +15254,25 @@ msgstr "" "Le diamètre est toujours le double du diamètre\n" "pour le cuivre fiducial." -#: flatcamTools/ToolFiducials.py:514 +#: flatcamTools/ToolFiducials.py:516 msgid "Click to add first Fiducial. Bottom Left..." msgstr "Cliquez pour ajouter le premier Fiducial. En bas à gauche..." -#: flatcamTools/ToolFiducials.py:778 +#: flatcamTools/ToolFiducials.py:780 msgid "Click to add the last fiducial. Top Right..." msgstr "Cliquez pour ajouter la dernière fiducie. En haut à droite..." -#: flatcamTools/ToolFiducials.py:783 +#: flatcamTools/ToolFiducials.py:785 msgid "Click to add the second fiducial. Top Left or Bottom Right..." msgstr "" "Cliquez pour ajouter le deuxième repère. En haut à gauche ou en bas à " "droite ..." -#: flatcamTools/ToolFiducials.py:786 flatcamTools/ToolFiducials.py:795 +#: flatcamTools/ToolFiducials.py:788 flatcamTools/ToolFiducials.py:797 msgid "Done. All fiducials have been added." msgstr "Terminé. Tous les fiduciaux ont été ajoutés." -#: flatcamTools/ToolFiducials.py:872 +#: flatcamTools/ToolFiducials.py:874 msgid "Fiducials Tool exit." msgstr "Sortie de l'outil Fiducials." @@ -14410,7 +15280,7 @@ msgstr "Sortie de l'outil Fiducials." msgid "Film PCB" msgstr "Film PCB" -#: flatcamTools/ToolFilm.py:80 +#: flatcamTools/ToolFilm.py:78 msgid "" "Specify the type of object for which to create the film.\n" "The object can be of type: Gerber or Geometry.\n" @@ -14422,11 +15292,11 @@ msgstr "" "La sélection ici décide du type d’objets qui seront\n" "dans la liste déroulante d'objets Film." -#: flatcamTools/ToolFilm.py:94 +#: flatcamTools/ToolFilm.py:92 msgid "Film Object" msgstr "Objet de Film" -#: flatcamTools/ToolFilm.py:96 +#: flatcamTools/ToolFilm.py:94 msgid "Object for which to create the film." msgstr "Objet pour lequel créer le film." @@ -14442,7 +15312,7 @@ msgstr "" "sélection ici détermine le type d'objets qui seront\n" "dans la liste déroulante Objet de Box." -#: flatcamTools/ToolFilm.py:129 flatcamTools/ToolPanelize.py:136 +#: flatcamTools/ToolFilm.py:129 msgid "Box Object" msgstr "Objet Box" @@ -14504,20 +15374,20 @@ msgid "" msgstr "" "Supprimez la géométrie d’Excellon du film pour créer les trous dans les pads." -#: flatcamTools/ToolFilm.py:379 +#: flatcamTools/ToolFilm.py:381 msgid "Punch Size" msgstr "Taille du poinçon" -#: flatcamTools/ToolFilm.py:380 +#: flatcamTools/ToolFilm.py:382 msgid "The value here will control how big is the punch hole in the pads." msgstr "" "La valeur ici contrôlera la taille du trou de perforation dans les pads." -#: flatcamTools/ToolFilm.py:500 +#: flatcamTools/ToolFilm.py:502 msgid "Save Film" msgstr "Enregistrer le Film" -#: flatcamTools/ToolFilm.py:502 +#: flatcamTools/ToolFilm.py:504 msgid "" "Create a Film for the selected object, within\n" "the specified box. Does not create a new \n" @@ -14529,7 +15399,7 @@ msgstr "" "Objet FlatCAM, mais enregistrez-le directement dans le\n" "format sélectionné." -#: flatcamTools/ToolFilm.py:652 +#: flatcamTools/ToolFilm.py:664 msgid "" "Using the Pad center does not work on Geometry objects. Only a Gerber object " "has pads." @@ -14537,40 +15407,36 @@ msgstr "" "L'utilisation du pavé central ne fonctionne pas avec les objets " "géométriques. Seul un objet Gerber a des pads." -#: flatcamTools/ToolFilm.py:662 +#: flatcamTools/ToolFilm.py:674 msgid "No FlatCAM object selected. Load an object for Film and retry." msgstr "" "Aucun objet FlatCAM sélectionné. Chargez un objet pour Film et réessayez." -#: flatcamTools/ToolFilm.py:669 +#: flatcamTools/ToolFilm.py:681 msgid "No FlatCAM object selected. Load an object for Box and retry." msgstr "" "Aucun objet FlatCAM sélectionné. Chargez un objet pour Box et réessayez." -#: flatcamTools/ToolFilm.py:673 +#: flatcamTools/ToolFilm.py:685 msgid "No FlatCAM object selected." msgstr "Aucun objet FlatCAM sélectionné." -#: flatcamTools/ToolFilm.py:684 +#: flatcamTools/ToolFilm.py:696 msgid "Generating Film ..." msgstr "Génération de Film ..." -#: flatcamTools/ToolFilm.py:733 flatcamTools/ToolFilm.py:737 +#: flatcamTools/ToolFilm.py:745 flatcamTools/ToolFilm.py:749 msgid "Export positive film" msgstr "Exporter un film positif" -#: flatcamTools/ToolFilm.py:742 -msgid "Export positive film cancelled." -msgstr "Exporter le film positif annulé." - -#: flatcamTools/ToolFilm.py:770 +#: flatcamTools/ToolFilm.py:782 msgid "" "No Excellon object selected. Load an object for punching reference and retry." msgstr "" "Aucun objet Excellon sélectionné. Charger un objet pour la référence de " "poinçonnage et réessayer." -#: flatcamTools/ToolFilm.py:794 +#: flatcamTools/ToolFilm.py:806 msgid "" " Could not generate punched hole film because the punch hole sizeis bigger " "than some of the apertures in the Gerber object." @@ -14578,7 +15444,7 @@ msgstr "" " Impossible de générer un film perforé car la taille du trou perforé est " "plus grande que certaines des ouvertures de l’objet Gerber." -#: flatcamTools/ToolFilm.py:806 +#: flatcamTools/ToolFilm.py:818 msgid "" "Could not generate punched hole film because the punch hole sizeis bigger " "than some of the apertures in the Gerber object." @@ -14586,7 +15452,7 @@ msgstr "" "Impossible de générer un film perforé car la taille du trou perforé est plus " "grande que certaines des ouvertures de l’objet Gerber." -#: flatcamTools/ToolFilm.py:824 +#: flatcamTools/ToolFilm.py:836 msgid "" "Could not generate punched hole film because the newly created object " "geometry is the same as the one in the source object geometry..." @@ -14594,24 +15460,20 @@ msgstr "" "Impossible de générer un film perforé car la géométrie d'objet nouvellement " "créée est identique à celle de la géométrie de l'objet source ..." -#: flatcamTools/ToolFilm.py:879 flatcamTools/ToolFilm.py:883 +#: flatcamTools/ToolFilm.py:891 flatcamTools/ToolFilm.py:895 msgid "Export negative film" msgstr "Exporter un film négatif" -#: flatcamTools/ToolFilm.py:888 -msgid "Export negative film cancelled." -msgstr "Exporter le film négatif annulé." - -#: flatcamTools/ToolFilm.py:944 flatcamTools/ToolFilm.py:1122 -#: flatcamTools/ToolPanelize.py:421 +#: flatcamTools/ToolFilm.py:956 flatcamTools/ToolFilm.py:1139 +#: flatcamTools/ToolPanelize.py:433 msgid "No object Box. Using instead" msgstr "Aucune Boîte d'objet. Utiliser à la place" -#: flatcamTools/ToolFilm.py:1060 flatcamTools/ToolFilm.py:1235 +#: flatcamTools/ToolFilm.py:1072 flatcamTools/ToolFilm.py:1252 msgid "Film file exported to" msgstr "Fichier de film exporté vers" -#: flatcamTools/ToolFilm.py:1063 flatcamTools/ToolFilm.py:1238 +#: flatcamTools/ToolFilm.py:1075 flatcamTools/ToolFilm.py:1255 msgid "Generating Film ... Please wait." msgstr "Génération de film ... Veuillez patienter." @@ -14623,7 +15485,7 @@ msgstr "Image comme objet" msgid "Image to PCB" msgstr "Image au PCB" -#: flatcamTools/ToolImage.py:57 +#: flatcamTools/ToolImage.py:56 msgid "" "Specify the type of object to create from the image.\n" "It can be of type: Gerber or Geometry." @@ -14631,23 +15493,23 @@ msgstr "" "Spécifiez le type d'objet à créer à partir de l'image.\n" "Il peut être de type: Gerber ou Géométrie." -#: flatcamTools/ToolImage.py:66 +#: flatcamTools/ToolImage.py:65 msgid "DPI value" msgstr "Valeur DPI" -#: flatcamTools/ToolImage.py:67 +#: flatcamTools/ToolImage.py:66 msgid "Specify a DPI value for the image." msgstr "Spécifiez une valeur DPI pour l'image." -#: flatcamTools/ToolImage.py:73 +#: flatcamTools/ToolImage.py:72 msgid "Level of detail" msgstr "Niveau de détail" -#: flatcamTools/ToolImage.py:82 +#: flatcamTools/ToolImage.py:81 msgid "Image type" msgstr "Type d'image" -#: flatcamTools/ToolImage.py:84 +#: flatcamTools/ToolImage.py:83 msgid "" "Choose a method for the image interpretation.\n" "B/W means a black & white image. Color means a colored image." @@ -14656,12 +15518,12 @@ msgstr "" "N / B signifie une image en noir et blanc. Couleur signifie une image " "colorée." -#: flatcamTools/ToolImage.py:93 flatcamTools/ToolImage.py:108 -#: flatcamTools/ToolImage.py:121 flatcamTools/ToolImage.py:134 +#: flatcamTools/ToolImage.py:92 flatcamTools/ToolImage.py:107 +#: flatcamTools/ToolImage.py:120 flatcamTools/ToolImage.py:133 msgid "Mask value" msgstr "Valeur du masque" -#: flatcamTools/ToolImage.py:95 +#: flatcamTools/ToolImage.py:94 msgid "" "Mask for monochrome image.\n" "Takes values between [0 ... 255].\n" @@ -14677,7 +15539,7 @@ msgstr "" "0 signifie pas de détail et 255 signifie tout\n" "(qui est totalement noir)." -#: flatcamTools/ToolImage.py:110 +#: flatcamTools/ToolImage.py:109 msgid "" "Mask for RED color.\n" "Takes values between [0 ... 255].\n" @@ -14689,7 +15551,7 @@ msgstr "" "Décide du niveau de détails à inclure\n" "dans la géométrie résultante." -#: flatcamTools/ToolImage.py:123 +#: flatcamTools/ToolImage.py:122 msgid "" "Mask for GREEN color.\n" "Takes values between [0 ... 255].\n" @@ -14701,7 +15563,7 @@ msgstr "" "Décide du niveau de détails à inclure\n" "dans la géométrie résultante." -#: flatcamTools/ToolImage.py:136 +#: flatcamTools/ToolImage.py:135 msgid "" "Mask for BLUE color.\n" "Takes values between [0 ... 255].\n" @@ -14713,33 +15575,59 @@ msgstr "" "Décide du niveau de détails à inclure\n" "dans la géométrie résultante." -#: flatcamTools/ToolImage.py:144 +#: flatcamTools/ToolImage.py:143 msgid "Import image" msgstr "Importer une image" -#: flatcamTools/ToolImage.py:146 +#: flatcamTools/ToolImage.py:145 msgid "Open a image of raster type and then import it in FlatCAM." msgstr "Ouvrez une image de type raster, puis importez-la dans FlatCAM." -#: flatcamTools/ToolImage.py:183 +#: flatcamTools/ToolImage.py:182 msgid "Image Tool" msgstr "Outil Image" -#: flatcamTools/ToolImage.py:235 flatcamTools/ToolImage.py:238 +#: flatcamTools/ToolImage.py:234 flatcamTools/ToolImage.py:237 msgid "Import IMAGE" msgstr "Importer une Image" -#: flatcamTools/ToolImage.py:286 +#: flatcamTools/ToolImage.py:285 msgid "Importing Image" msgstr "Importation d'Image" +#: flatcamTools/ToolInvertGerber.py:74 +msgid "Gerber object that will be inverted." +msgstr "Objet Gerber qui sera inversé." + +#: flatcamTools/ToolInvertGerber.py:83 +msgid "Parameters for this tool" +msgstr "Paramètres pour cet outil" + +#: flatcamTools/ToolInvertGerber.py:123 +msgid "Invert Gerber" +msgstr "Inverser Gerber" + +#: flatcamTools/ToolInvertGerber.py:125 +msgid "" +"Will invert the Gerber object: areas that have copper\n" +"will be empty of copper and previous empty area will be\n" +"filled with copper." +msgstr "" +"Inversera l'objet Gerber: les zones qui ont du cuivre\n" +"sera vide de cuivre et la zone vide précédente sera\n" +"rempli de cuivre." + +#: flatcamTools/ToolInvertGerber.py:184 +msgid "Invert Tool" +msgstr "Outil Inverser" + #: flatcamTools/ToolMove.py:103 msgid "MOVE: Click on the Start point ..." msgstr "Déplacer: Cliquez sur le point de départ ..." #: flatcamTools/ToolMove.py:114 -msgid "MOVE action cancelled. No object(s) to move." -msgstr "Déplacer: action annulée. Aucun objet à déplacer." +msgid "Cancelled. No object(s) to move." +msgstr "Annulé. Aucun objet à déplacer." #: flatcamTools/ToolMove.py:141 msgid "MOVE: Click on the Destination point ..." @@ -14753,19 +15641,15 @@ msgstr "En mouvement..." msgid "No object(s) selected." msgstr "Aucun objet sélectionné." -#: flatcamTools/ToolMove.py:212 +#: flatcamTools/ToolMove.py:222 msgid "Error when mouse left click." msgstr "Erreur lorsque le clic gauche de la souris." -#: flatcamTools/ToolMove.py:260 -msgid "Move action cancelled." -msgstr "Action de déplacement annulée." - -#: flatcamTools/ToolNonCopperClear.py:38 +#: flatcamTools/ToolNCC.py:42 msgid "Non-Copper Clearing" msgstr "Compensation de la NCC" -#: flatcamTools/ToolNonCopperClear.py:84 +#: flatcamTools/ToolNCC.py:88 msgid "" "Specify the type of object to be cleared of excess copper.\n" "It can be of type: Gerber or Geometry.\n" @@ -14777,11 +15661,11 @@ msgstr "" "Ce qui est sélectionné ici dictera le genre\n" "des objets qui vont remplir la liste déroulante 'Object'." -#: flatcamTools/ToolNonCopperClear.py:101 +#: flatcamTools/ToolNCC.py:110 msgid "Object to be cleared of excess copper." msgstr "Objet à nettoyer de l'excès de cuivre." -#: flatcamTools/ToolNonCopperClear.py:111 +#: flatcamTools/ToolNCC.py:122 msgid "" "Tools pool from which the algorithm\n" "will pick the ones used for copper clearing." @@ -14789,11 +15673,7 @@ msgstr "" "Pool d'outils à partir duquel l'algorithme\n" "choisira ceux utilisés pour le nettoyage du cuivre." -#: flatcamTools/ToolNonCopperClear.py:120 -msgid "Operation" -msgstr "Opération" - -#: flatcamTools/ToolNonCopperClear.py:126 +#: flatcamTools/ToolNCC.py:138 msgid "" "This is the Tool Number.\n" "Non copper clearing will start with the tool with the biggest \n" @@ -14810,7 +15690,7 @@ msgstr "" "dans la géométrie résultante. C’est parce qu’avec certains outils\n" "cette fonction ne pourra pas créer de géométrie de peinture." -#: flatcamTools/ToolNonCopperClear.py:134 +#: flatcamTools/ToolNCC.py:146 msgid "" "Tool Diameter. It's value (in current FlatCAM units)\n" "is the cut width into the material." @@ -14818,7 +15698,7 @@ msgstr "" "Diamètre de l'outil. C'est sa valeur (en unités FlatCAM actuelles)\n" "est la largeur de coupe dans le matériau." -#: flatcamTools/ToolNonCopperClear.py:138 +#: flatcamTools/ToolNCC.py:150 msgid "" "The Tool Type (TT) can be:\n" "- Circular with 1 ... 4 teeth -> it is informative only. Being circular,\n" @@ -14856,34 +15736,7 @@ msgstr "" "d’opération\n" "dans la géométrie résultante en tant qu'isolation." -#: flatcamTools/ToolNonCopperClear.py:151 -msgid "" -"The 'Operation' can be:\n" -"- Isolation -> will ensure that the non-copper clearing is always complete.\n" -"If it's not successful then the non-copper clearing will fail, too.\n" -"- Clear -> the regular non-copper clearing." -msgstr "" -"L'opération peut être:\n" -"- Isolement -> veillera à ce que la clairance sans cuivre soit toujours " -"complète.\n" -"Si cela ne réussit pas, alors le clearing sans cuivre échouera aussi.\n" -"- Clair -> le clearing régulier sans cuivre." - -#: flatcamTools/ToolNonCopperClear.py:209 -msgid "Tool Selection" -msgstr "Sélection d'Outils" - -#: flatcamTools/ToolNonCopperClear.py:273 -msgid "" -"Diameter for the new tool to add in the Tool Table.\n" -"If the tool is V-shape type then this value is automatically\n" -"calculated from the other parameters." -msgstr "" -"Diamètre du nouvel outil à ajouter dans la table d'outils.\n" -"Si l'outil est de type V, cette valeur est automatiquement\n" -"calculé à partir des autres paramètres." - -#: flatcamTools/ToolNonCopperClear.py:288 flatcamTools/ToolPaint.py:190 +#: flatcamTools/ToolNCC.py:296 flatcamTools/ToolPaint.py:279 msgid "" "Add a new tool to the Tool Table\n" "with the diameter specified above." @@ -14891,8 +15744,8 @@ msgstr "" "Ajouter un nouvel outil à la table d'outils\n" "avec le diamètre spécifié ci-dessus." -#: flatcamTools/ToolNonCopperClear.py:300 flatcamTools/ToolPaint.py:202 -#: flatcamTools/ToolSolderPaste.py:129 +#: flatcamTools/ToolNCC.py:318 flatcamTools/ToolPaint.py:301 +#: flatcamTools/ToolSolderPaste.py:131 msgid "" "Delete a selection of tools in the Tool Table\n" "by first selecting a row(s) in the Tool Table." @@ -14900,23 +15753,7 @@ msgstr "" "Supprimer une sélection d'outils dans la table d'outils\n" "en sélectionnant d’abord une ou plusieurs lignes dans la table d’outils." -#: flatcamTools/ToolNonCopperClear.py:435 -msgid "" -"- 'Itself' - the non copper clearing extent is based on the object that is " -"copper cleared.\n" -" - 'Area Selection' - left mouse click to start selection of the area to be " -"painted.\n" -"- 'Reference Object' - will do non copper clearing within the area specified " -"by another object." -msgstr "" -"- `` Lui-même '' - l'étendue de la compensation sans cuivre est basée sur " -"l'objet qui est clarifié en cuivre.\n" -" - «Sélection de zone» - clic gauche de la souris pour démarrer la sélection " -"de la zone à peindre.\n" -"- «Objet de référence» - effectuera un nettoyage sans cuivre dans la zone " -"spécifiée par un autre objet." - -#: flatcamTools/ToolNonCopperClear.py:447 +#: flatcamTools/ToolNCC.py:554 msgid "" "The type of FlatCAM object to be used as non copper clearing reference.\n" "It can be Gerber, Excellon or Geometry." @@ -14924,117 +15761,123 @@ msgstr "" "Type d'objet FlatCAM à utiliser comme référence d'effacement non en cuivre.\n" "Ce peut être Gerber, Excellon ou Géométrie." -#: flatcamTools/ToolNonCopperClear.py:471 +#: flatcamTools/ToolNCC.py:597 flatcamTools/ToolPaint.py:537 msgid "Generate Geometry" msgstr "Générer de la Géométrie" -#: flatcamTools/ToolNonCopperClear.py:582 flatcamTools/ToolPaint.py:493 -#: flatcamTools/ToolSolderPaste.py:553 -msgid "New Tool" -msgstr "Nouvel Outil" - -#: flatcamTools/ToolNonCopperClear.py:981 flatcamTools/ToolPaint.py:766 -#: flatcamTools/ToolSolderPaste.py:887 +#: flatcamTools/ToolNCC.py:1420 flatcamTools/ToolPaint.py:1179 +#: flatcamTools/ToolSolderPaste.py:888 msgid "Please enter a tool diameter to add, in Float format." msgstr "Veuillez saisir un diamètre d'outil à ajouter, au format réel." -#: flatcamTools/ToolNonCopperClear.py:1012 flatcamTools/ToolPaint.py:791 -msgid "Adding tool cancelled. Tool already in Tool Table." -msgstr "Ajout de l'outil annulé. Outil déjà dans la table d'outils." +#: flatcamTools/ToolNCC.py:1451 flatcamTools/ToolNCC.py:4008 +#: flatcamTools/ToolPaint.py:1203 flatcamTools/ToolPaint.py:3598 +#: flatcamTools/ToolSolderPaste.py:917 +msgid "Cancelled. Tool already in Tool Table." +msgstr "Annulé. Outil déjà dans la table d'outils." -#: flatcamTools/ToolNonCopperClear.py:1017 flatcamTools/ToolPaint.py:797 +#: flatcamTools/ToolNCC.py:1458 flatcamTools/ToolNCC.py:4025 +#: flatcamTools/ToolPaint.py:1208 flatcamTools/ToolPaint.py:3615 msgid "New tool added to Tool Table." msgstr "Nouvel outil ajouté à la table d'outils." -#: flatcamTools/ToolNonCopperClear.py:1061 flatcamTools/ToolPaint.py:843 +#: flatcamTools/ToolNCC.py:1502 flatcamTools/ToolPaint.py:1252 msgid "Tool from Tool Table was edited." msgstr "L'outil de la table d'outils a été modifié." -#: flatcamTools/ToolNonCopperClear.py:1072 flatcamTools/ToolPaint.py:855 -#: flatcamTools/ToolSolderPaste.py:978 -msgid "Edit cancelled. New diameter value is already in the Tool Table." +#: flatcamTools/ToolNCC.py:1514 flatcamTools/ToolPaint.py:1264 +#: flatcamTools/ToolSolderPaste.py:977 +msgid "Cancelled. New diameter value is already in the Tool Table." msgstr "" -"Modifier annulé. La nouvelle valeur de diamètre est déjà dans la table " -"d'outils." +"Annulé. La nouvelle valeur de diamètre est déjà dans la table d'outils." -#: flatcamTools/ToolNonCopperClear.py:1119 flatcamTools/ToolPaint.py:953 +#: flatcamTools/ToolNCC.py:1566 flatcamTools/ToolPaint.py:1362 msgid "Delete failed. Select a tool to delete." msgstr "La suppression a échoué. Sélectionnez un outil à supprimer." -#: flatcamTools/ToolNonCopperClear.py:1124 flatcamTools/ToolPaint.py:959 +#: flatcamTools/ToolNCC.py:1572 flatcamTools/ToolPaint.py:1368 msgid "Tool(s) deleted from Tool Table." msgstr "Outil (s) supprimé (s) de la table d'outils." -#: flatcamTools/ToolNonCopperClear.py:1171 +#: flatcamTools/ToolNCC.py:1614 msgid "Wrong Tool Dia value format entered, use a number." msgstr "Mauvais outil Format de valeur Dia entré, utilisez un nombre." -#: flatcamTools/ToolNonCopperClear.py:1180 flatcamTools/ToolPaint.py:1023 +#: flatcamTools/ToolNCC.py:1623 flatcamTools/ToolPaint.py:1419 msgid "No selected tools in Tool Table." msgstr "Aucun outil sélectionné dans la table d'outils." -#: flatcamTools/ToolNonCopperClear.py:1255 flatcamTools/ToolPaint.py:1195 +#: flatcamTools/ToolNCC.py:1699 flatcamTools/ToolPaint.py:1595 msgid "Click the end point of the paint area." msgstr "Cliquez sur le point final de la zone de peinture." -#: flatcamTools/ToolNonCopperClear.py:1410 -#: flatcamTools/ToolNonCopperClear.py:1412 -msgid "Non-Copper clearing ..." -msgstr "Dégagement sans cuivre ..." - -#: flatcamTools/ToolNonCopperClear.py:1422 -msgid "NCC Tool started. Reading parameters." -msgstr "L'outil NCC a commencé. Lecture des paramètres." - -#: flatcamTools/ToolNonCopperClear.py:1485 +#: flatcamTools/ToolNCC.py:1971 flatcamTools/ToolNCC.py:2959 msgid "NCC Tool. Preparing non-copper polygons." msgstr "Outil de la NCC. Préparer des polygones non en cuivre." -#: flatcamTools/ToolNonCopperClear.py:1581 +#: flatcamTools/ToolNCC.py:2030 flatcamTools/ToolNCC.py:3087 +msgid "NCC Tool. Calculate 'empty' area." +msgstr "Outil de la NCC. Calculez la surface \"vide\"." + +#: flatcamTools/ToolNCC.py:2049 flatcamTools/ToolNCC.py:2155 +#: flatcamTools/ToolNCC.py:2169 flatcamTools/ToolNCC.py:3100 +#: flatcamTools/ToolNCC.py:3205 flatcamTools/ToolNCC.py:3220 +#: flatcamTools/ToolNCC.py:3486 flatcamTools/ToolNCC.py:3587 +#: flatcamTools/ToolNCC.py:3602 +msgid "Buffering finished" +msgstr "Mise en mémoire tampon terminée" + +#: flatcamTools/ToolNCC.py:2057 flatcamTools/ToolNCC.py:2176 +#: flatcamTools/ToolNCC.py:3108 flatcamTools/ToolNCC.py:3227 +#: flatcamTools/ToolNCC.py:3493 flatcamTools/ToolNCC.py:3609 +msgid "Could not get the extent of the area to be non copper cleared." +msgstr "Impossible d'obtenir que l'étendue de la zone soit non dépolluée." + +#: flatcamTools/ToolNCC.py:2084 flatcamTools/ToolNCC.py:2162 +#: flatcamTools/ToolNCC.py:3135 flatcamTools/ToolNCC.py:3212 +#: flatcamTools/ToolNCC.py:3513 flatcamTools/ToolNCC.py:3594 +msgid "" +"Isolation geometry is broken. Margin is less than isolation tool diameter." +msgstr "" +"La géométrie d'isolement est rompue. La marge est inférieure au diamètre de " +"l'outil d'isolation." + +#: flatcamTools/ToolNCC.py:2179 flatcamTools/ToolNCC.py:3231 +#: flatcamTools/ToolNCC.py:3612 +msgid "The selected object is not suitable for copper clearing." +msgstr "L'objet sélectionné ne convient pas à la clarification du cuivre." + +#: flatcamTools/ToolNCC.py:2186 flatcamTools/ToolNCC.py:3238 +msgid "NCC Tool. Finished calculation of 'empty' area." +msgstr "Outil de la NCC. Terminé le calcul de la zone \"vide\"." + +#: flatcamTools/ToolNCC.py:2217 flatcamTools/ToolNCC.py:2219 +#: flatcamTools/ToolNCC.py:2911 flatcamTools/ToolNCC.py:2913 +msgid "Non-Copper clearing ..." +msgstr "Dégagement sans cuivre ..." + +#: flatcamTools/ToolNCC.py:2273 flatcamTools/ToolNCC.py:3055 msgid "" "NCC Tool. Finished non-copper polygons. Normal copper clearing task started." msgstr "" "Outil de la NCC. Polygones non-cuivre finis. La tâche normale de nettoyage " "du cuivre a commencé." -#: flatcamTools/ToolNonCopperClear.py:1613 -msgid "NCC Tool. Calculate 'empty' area." -msgstr "Outil de la NCC. Calculez la surface \"vide\"." +#: flatcamTools/ToolNCC.py:2307 flatcamTools/ToolNCC.py:2587 +msgid "NCC Tool failed creating bounding box." +msgstr "L'outil NCC n'a pas pu créer de boîte englobante." -#: flatcamTools/ToolNonCopperClear.py:1626 -#: flatcamTools/ToolNonCopperClear.py:1723 -#: flatcamTools/ToolNonCopperClear.py:1735 -#: flatcamTools/ToolNonCopperClear.py:2018 -#: flatcamTools/ToolNonCopperClear.py:2114 -#: flatcamTools/ToolNonCopperClear.py:2126 -msgid "Buffering finished" -msgstr "Mise en mémoire tampon terminée" +#: flatcamTools/ToolNCC.py:2321 flatcamTools/ToolNCC.py:2604 +#: flatcamTools/ToolNCC.py:3251 flatcamTools/ToolNCC.py:3637 +msgid "NCC Tool clearing with tool diameter" +msgstr "L'outil NCC s'efface avec le diamètre de l'outil" -#: flatcamTools/ToolNonCopperClear.py:1742 -#: flatcamTools/ToolNonCopperClear.py:2132 -msgid "The selected object is not suitable for copper clearing." -msgstr "L'objet sélectionné ne convient pas à la clarification du cuivre." - -#: flatcamTools/ToolNonCopperClear.py:1747 -#: flatcamTools/ToolNonCopperClear.py:2137 -msgid "Could not get the extent of the area to be non copper cleared." -msgstr "Impossible d'obtenir que l'étendue de la zone soit non dépolluée." - -#: flatcamTools/ToolNonCopperClear.py:1754 -msgid "NCC Tool. Finished calculation of 'empty' area." -msgstr "Outil de la NCC. Terminé le calcul de la zone \"vide\"." - -#: flatcamTools/ToolNonCopperClear.py:1768 -#: flatcamTools/ToolNonCopperClear.py:2162 -msgid "NCC Tool clearing with tool diameter = " -msgstr "Outil de la NCC. Dégagement avec diamètre de l'outil = " - -#: flatcamTools/ToolNonCopperClear.py:1771 -#: flatcamTools/ToolNonCopperClear.py:2165 +#: flatcamTools/ToolNCC.py:2321 flatcamTools/ToolNCC.py:2604 +#: flatcamTools/ToolNCC.py:3251 flatcamTools/ToolNCC.py:3637 msgid "started." msgstr "commencé." -#: flatcamTools/ToolNonCopperClear.py:1947 +#: flatcamTools/ToolNCC.py:2513 flatcamTools/ToolNCC.py:3412 msgid "" "There is no NCC Geometry in the file.\n" "Usually it means that the tool diameter is too big for the painted " @@ -15046,26 +15889,26 @@ msgstr "" "géométrie peinte.\n" "Modifiez les paramètres de peinture et réessayez." -#: flatcamTools/ToolNonCopperClear.py:1967 +#: flatcamTools/ToolNCC.py:2522 flatcamTools/ToolNCC.py:3421 msgid "NCC Tool clear all done." msgstr "Outil de la NCC. Effacer tout fait." -#: flatcamTools/ToolNonCopperClear.py:1969 +#: flatcamTools/ToolNCC.py:2525 flatcamTools/ToolNCC.py:3424 msgid "NCC Tool clear all done but the copper features isolation is broken for" msgstr "" "Outil de la CCN. Effacer tout fait, mais l'isolation des caractéristiques de " "cuivre est cassée pour" -#: flatcamTools/ToolNonCopperClear.py:1972 -#: flatcamTools/ToolNonCopperClear.py:2341 +#: flatcamTools/ToolNCC.py:2527 flatcamTools/ToolNCC.py:2812 +#: flatcamTools/ToolNCC.py:3426 flatcamTools/ToolNCC.py:3809 msgid "tools" msgstr "outils" -#: flatcamTools/ToolNonCopperClear.py:2337 +#: flatcamTools/ToolNCC.py:2808 flatcamTools/ToolNCC.py:3805 msgid "NCC Tool Rest Machining clear all done." msgstr "Outil de la NCC. Reste l'usinage clair tout fait." -#: flatcamTools/ToolNonCopperClear.py:2340 +#: flatcamTools/ToolNCC.py:2811 flatcamTools/ToolNCC.py:3808 msgid "" "NCC Tool Rest Machining clear all done but the copper features isolation is " "broken for" @@ -15073,7 +15916,11 @@ msgstr "" "Outil de la NCC. Reste l'usinage clair, tout est fait, mais l'isolation des " "caractéristiques en cuivre est cassée" -#: flatcamTools/ToolNonCopperClear.py:2787 +#: flatcamTools/ToolNCC.py:2923 +msgid "NCC Tool started. Reading parameters." +msgstr "L'outil NCC a commencé. Lecture des paramètres." + +#: flatcamTools/ToolNCC.py:3901 msgid "" "Try to use the Buffering Type = Full in Preferences -> Gerber General. " "Reload the Gerber file after this change." @@ -15081,43 +15928,43 @@ msgstr "" "Essayez d'utiliser le type de mise en tampon = Plein dans Préférences -> " "Général Gerber. Rechargez le fichier Gerber après cette modification." -#: flatcamTools/ToolOptimal.py:79 +#: flatcamTools/ToolOptimal.py:80 msgid "Number of decimals kept for found distances." msgstr "Nombre de décimales conservées pour les distances trouvées." -#: flatcamTools/ToolOptimal.py:87 +#: flatcamTools/ToolOptimal.py:88 msgid "Minimum distance" msgstr "Distance minimale" -#: flatcamTools/ToolOptimal.py:88 +#: flatcamTools/ToolOptimal.py:89 msgid "Display minimum distance between copper features." msgstr "Afficher la distance minimale entre les entités en cuivre." -#: flatcamTools/ToolOptimal.py:92 +#: flatcamTools/ToolOptimal.py:93 msgid "Determined" msgstr "Déterminé" -#: flatcamTools/ToolOptimal.py:106 +#: flatcamTools/ToolOptimal.py:107 msgid "Occurring" msgstr "Se produisant" -#: flatcamTools/ToolOptimal.py:107 +#: flatcamTools/ToolOptimal.py:108 msgid "How many times this minimum is found." msgstr "Combien de fois ce minimum est trouvé." -#: flatcamTools/ToolOptimal.py:113 +#: flatcamTools/ToolOptimal.py:114 msgid "Minimum points coordinates" msgstr "Coordonnées des points minimum" -#: flatcamTools/ToolOptimal.py:114 flatcamTools/ToolOptimal.py:120 +#: flatcamTools/ToolOptimal.py:115 flatcamTools/ToolOptimal.py:121 msgid "Coordinates for points where minimum distance was found." msgstr "Coordonnées des points où une distance minimale a été trouvée." -#: flatcamTools/ToolOptimal.py:133 flatcamTools/ToolOptimal.py:209 +#: flatcamTools/ToolOptimal.py:134 flatcamTools/ToolOptimal.py:210 msgid "Jump to selected position" msgstr "Aller à la position sélectionnée" -#: flatcamTools/ToolOptimal.py:135 flatcamTools/ToolOptimal.py:211 +#: flatcamTools/ToolOptimal.py:136 flatcamTools/ToolOptimal.py:212 msgid "" "Select a position in the Locations text box and then\n" "click this button." @@ -15125,11 +15972,11 @@ msgstr "" "Sélectionnez une position dans la zone de texte Emplacements, puis\n" "cliquez sur ce bouton." -#: flatcamTools/ToolOptimal.py:143 +#: flatcamTools/ToolOptimal.py:144 msgid "Other distances" msgstr "Autres distances" -#: flatcamTools/ToolOptimal.py:144 +#: flatcamTools/ToolOptimal.py:145 msgid "" "Will display other distances in the Gerber file ordered from\n" "the minimum to the maximum, not including the absolute minimum." @@ -15137,13 +15984,13 @@ msgstr "" "Affiche les autres distances dans le fichier Gerber commandé à\n" "le minimum au maximum, sans compter le minimum absolu." -#: flatcamTools/ToolOptimal.py:149 +#: flatcamTools/ToolOptimal.py:150 msgid "Other distances points coordinates" msgstr "Autres points de coordonnées" -#: flatcamTools/ToolOptimal.py:150 flatcamTools/ToolOptimal.py:164 -#: flatcamTools/ToolOptimal.py:171 flatcamTools/ToolOptimal.py:188 -#: flatcamTools/ToolOptimal.py:195 +#: flatcamTools/ToolOptimal.py:151 flatcamTools/ToolOptimal.py:165 +#: flatcamTools/ToolOptimal.py:172 flatcamTools/ToolOptimal.py:189 +#: flatcamTools/ToolOptimal.py:196 msgid "" "Other distances and the coordinates for points\n" "where the distance was found." @@ -15151,19 +15998,19 @@ msgstr "" "Autres distances et coordonnées des points\n" "où la distance a été trouvée." -#: flatcamTools/ToolOptimal.py:163 +#: flatcamTools/ToolOptimal.py:164 msgid "Gerber distances" msgstr "Distances de Gerber" -#: flatcamTools/ToolOptimal.py:187 +#: flatcamTools/ToolOptimal.py:188 msgid "Points coordinates" msgstr "Coords des points" -#: flatcamTools/ToolOptimal.py:219 +#: flatcamTools/ToolOptimal.py:220 msgid "Find Minimum" msgstr "Trouver le minimum" -#: flatcamTools/ToolOptimal.py:221 +#: flatcamTools/ToolOptimal.py:222 msgid "" "Calculate the minimum distance between copper features,\n" "this will allow the determination of the right tool to\n" @@ -15173,11 +16020,11 @@ msgstr "" "cela permettra de déterminer le bon outil pour\n" "utiliser pour l'isolation ou le nettoyage du cuivre." -#: flatcamTools/ToolOptimal.py:346 +#: flatcamTools/ToolOptimal.py:347 msgid "Only Gerber objects can be evaluated." msgstr "Seuls les objets de Gerber peuvent être évalués." -#: flatcamTools/ToolOptimal.py:352 +#: flatcamTools/ToolOptimal.py:353 msgid "" "Optimal Tool. Started to search for the minimum distance between copper " "features." @@ -15185,15 +16032,15 @@ msgstr "" "Outil Optimal. Commencé à rechercher la distance minimale entre les entités " "en cuivre." -#: flatcamTools/ToolOptimal.py:362 +#: flatcamTools/ToolOptimal.py:363 msgid "Optimal Tool. Parsing geometry for aperture" msgstr "Outil Optimal. Analyser la géométrie pour l'ouverture" -#: flatcamTools/ToolOptimal.py:373 +#: flatcamTools/ToolOptimal.py:374 msgid "Optimal Tool. Creating a buffer for the object geometry." msgstr "Outil Optimal. Création d'un tampon pour la géométrie de l'objet." -#: flatcamTools/ToolOptimal.py:383 +#: flatcamTools/ToolOptimal.py:384 msgid "" "The Gerber object has one Polygon as geometry.\n" "There are no distances between geometry elements to be found." @@ -15201,18 +16048,18 @@ msgstr "" "L'objet Gerber a un polygone comme géométrie.\n" "Il n'y a pas de distance entre les éléments géométriques à trouver." -#: flatcamTools/ToolOptimal.py:388 +#: flatcamTools/ToolOptimal.py:389 msgid "" "Optimal Tool. Finding the distances between each two elements. Iterations" msgstr "" "Outil Optimal. Trouver les distances entre chacun des deux éléments. " "Itérations" -#: flatcamTools/ToolOptimal.py:423 +#: flatcamTools/ToolOptimal.py:424 msgid "Optimal Tool. Finding the minimum distance." msgstr "Outil Optimal. Trouver la distance minimale." -#: flatcamTools/ToolOptimal.py:439 +#: flatcamTools/ToolOptimal.py:440 msgid "Optimal Tool. Finished successfully." msgstr "Outil Optimal. Terminé avec succès." @@ -15241,7 +16088,7 @@ msgstr "Le fichier PDF ouvert a échoué." msgid "Rendered" msgstr "Rendu" -#: flatcamTools/ToolPaint.py:87 +#: flatcamTools/ToolPaint.py:82 msgid "" "Specify the type of object to be painted.\n" "It can be of type: Gerber or Geometry.\n" @@ -15257,7 +16104,7 @@ msgstr "" msgid "Object to be painted." msgstr "Objet à peindre." -#: flatcamTools/ToolPaint.py:114 +#: flatcamTools/ToolPaint.py:117 msgid "" "Tools pool from which the algorithm\n" "will pick the ones used for painting." @@ -15265,7 +16112,7 @@ msgstr "" "Pool d'outils à partir duquel l'algorithme\n" "choisira ceux utilisés pour la peinture." -#: flatcamTools/ToolPaint.py:129 +#: flatcamTools/ToolPaint.py:134 msgid "" "This is the Tool Number.\n" "Painting will start with the tool with the biggest diameter,\n" @@ -15281,7 +16128,7 @@ msgstr "" "dans la géométrie résultante. C’est parce qu’avec certains outils\n" "cette fonction ne pourra pas créer de géométrie de peinture." -#: flatcamTools/ToolPaint.py:141 +#: flatcamTools/ToolPaint.py:146 msgid "" "The Tool Type (TT) can be:
- Circular with 1 ... 4 teeth -> it is " "informative only. Being circular,
the cut width in material is exactly " @@ -15308,51 +16155,7 @@ msgstr "" "automatiquement le type d'opération dans la géométrie résultante en tant " "qu'isolation." -#: flatcamTools/ToolPaint.py:178 -msgid "Diameter for the new tool." -msgstr "Diamètre pour le nouvel outil." - -#: flatcamTools/ToolPaint.py:253 -msgid "" -"Algorithm for painting:\n" -"- Standard: Fixed step inwards.\n" -"- Seed-based: Outwards from seed.\n" -"- Line-based: Parallel lines." -msgstr "" -"Algorithme pour la peinture:\n" -"- Standard: pas fixe vers l'intérieur.\n" -"- À base de semences: Extérieur de la graine.\n" -"- Basé sur les lignes: lignes parallèles." - -#: flatcamTools/ToolPaint.py:283 -msgid "" -"If checked, use 'rest machining'.\n" -"Basically it will clear copper outside PCB features,\n" -"using the biggest tool and continue with the next tools,\n" -"from bigger to smaller, to clear areas of copper that\n" -"could not be cleared by previous tool, until there is\n" -"no more copper to clear or there are no more tools.\n" -"\n" -"If not checked, use the standard algorithm." -msgstr "" -"Si coché, utilisez 'repos usining'.\n" -"Fondamentalement, il nettoiera le cuivre en dehors des circuits imprimés,\n" -"en utilisant le plus gros outil et continuer avec les outils suivants,\n" -"du plus grand au plus petit, pour nettoyer les zones de cuivre\n" -"ne pouvait pas être effacé par l’outil précédent, jusqu’à ce que\n" -"plus de cuivre à nettoyer ou il n'y a plus d'outils.\n" -"\n" -"Si non coché, utilisez l'algorithme standard." - -#: flatcamTools/ToolPaint.py:307 -msgid "Polygon Selection" -msgstr "Sélection de polygone" - -#: flatcamTools/ToolPaint.py:309 -msgid "All Polygons" -msgstr "Tous les polygones" - -#: flatcamTools/ToolPaint.py:328 +#: flatcamTools/ToolPaint.py:498 msgid "" "The type of FlatCAM object to be used as paint reference.\n" "It can be Gerber, Excellon or Geometry." @@ -15360,11 +16163,7 @@ msgstr "" "Le type d'objet FlatCAM à utiliser comme référence de peinture.\n" "Ce peut être Gerber, Excellon ou Géométrie." -#: flatcamTools/ToolPaint.py:353 -msgid "Create Paint Geometry" -msgstr "Créer une Géométrie de Peinture" - -#: flatcamTools/ToolPaint.py:355 +#: flatcamTools/ToolPaint.py:539 msgid "" "- 'Area Selection' - left mouse click to start selection of the area to be " "painted.\n" @@ -15382,72 +16181,99 @@ msgstr "" "- 'Objet de référence' - effectuera un nettoyage sans cuivre dans la zone\n" "spécifié par un autre objet." -#: flatcamTools/ToolPaint.py:973 -msgid "Paint Tool. Reading parameters." -msgstr "Outil de Peinture. Lecture des paramètres." - -#: flatcamTools/ToolPaint.py:988 +#: flatcamTools/ToolPaint.py:1388 #, python-format msgid "Could not retrieve object: %s" msgstr "Impossible de récupérer l'objet: %s" -#: flatcamTools/ToolPaint.py:1002 +#: flatcamTools/ToolPaint.py:1398 msgid "Can't do Paint on MultiGeo geometries" msgstr "Impossible de peindre sur des géométries MultiGeo" -#: flatcamTools/ToolPaint.py:1035 +#: flatcamTools/ToolPaint.py:1428 msgid "Click on a polygon to paint it." msgstr "Cliquez sur un polygone pour le peindre." -#: flatcamTools/ToolPaint.py:1054 +#: flatcamTools/ToolPaint.py:1448 msgid "Click the start point of the paint area." msgstr "Cliquez sur le point de départ de la zone de peinture." -#: flatcamTools/ToolPaint.py:1122 +#: flatcamTools/ToolPaint.py:1513 msgid "Click to add next polygon or right click to start painting." msgstr "" "Cliquez pour ajouter le polygone suivant ou cliquez avec le bouton droit " "pour commencer à peindre." -#: flatcamTools/ToolPaint.py:1135 +#: flatcamTools/ToolPaint.py:1526 msgid "Click to add/remove next polygon or right click to start painting." msgstr "" "Cliquez pour ajouter / supprimer le polygone suivant ou cliquez avec le " "bouton droit pour commencer à peindre." -#: flatcamTools/ToolPaint.py:1344 flatcamTools/ToolPaint.py:1347 -#: flatcamTools/ToolPaint.py:1349 flatcamTools/ToolPaint.py:1987 -#: flatcamTools/ToolPaint.py:1991 flatcamTools/ToolPaint.py:1994 -#: flatcamTools/ToolPaint.py:2276 flatcamTools/ToolPaint.py:2281 -#: flatcamTools/ToolPaint.py:2284 flatcamTools/ToolPaint.py:2458 -#: flatcamTools/ToolPaint.py:2465 -msgid "Paint Tool." -msgstr "Outil de Peinture." +#: flatcamTools/ToolPaint.py:2024 +msgid "Painting polygon with method: lines." +msgstr "Peinture polygone avec méthode: lignes." -#: flatcamTools/ToolPaint.py:1344 flatcamTools/ToolPaint.py:1347 -#: flatcamTools/ToolPaint.py:1349 -msgid "Normal painting polygon task started." -msgstr "La tâche de peinture normale du polygone a commencé." +#: flatcamTools/ToolPaint.py:2036 +msgid "Failed. Painting polygon with method: seed." +msgstr "Échoué. Peinture polygone avec méthode: graine." -#: flatcamTools/ToolPaint.py:1345 flatcamTools/ToolPaint.py:1706 -#: flatcamTools/ToolPaint.py:1988 flatcamTools/ToolPaint.py:2278 -#: flatcamTools/ToolPaint.py:2460 -msgid "Buffering geometry..." -msgstr "Mise en tampon de la géométrie ..." +#: flatcamTools/ToolPaint.py:2047 +msgid "Failed. Painting polygon with method: standard." +msgstr "Échoué. Peinture polygone avec méthode: standard." -#: flatcamTools/ToolPaint.py:1367 -msgid "No polygon found." -msgstr "Aucun polygone trouvé." - -#: flatcamTools/ToolPaint.py:1401 -msgid "Painting polygon..." -msgstr "Peinture polygone ..." - -#: flatcamTools/ToolPaint.py:1448 +#: flatcamTools/ToolPaint.py:2063 msgid "Geometry could not be painted completely" msgstr "La géométrie n'a pas pu être peinte complètement" -#: flatcamTools/ToolPaint.py:1481 +#: flatcamTools/ToolPaint.py:2092 flatcamTools/ToolPaint.py:2095 +#: flatcamTools/ToolPaint.py:2103 flatcamTools/ToolPaint.py:2406 +#: flatcamTools/ToolPaint.py:2409 flatcamTools/ToolPaint.py:2417 +#: flatcamTools/ToolPaint.py:2905 flatcamTools/ToolPaint.py:2908 +#: flatcamTools/ToolPaint.py:2914 +msgid "Paint Tool." +msgstr "Outil de Peinture." + +#: flatcamTools/ToolPaint.py:2092 flatcamTools/ToolPaint.py:2095 +#: flatcamTools/ToolPaint.py:2103 +msgid "Normal painting polygon task started." +msgstr "La tâche de peinture normale du polygone a commencé." + +#: flatcamTools/ToolPaint.py:2093 flatcamTools/ToolPaint.py:2407 +#: flatcamTools/ToolPaint.py:2906 +msgid "Buffering geometry..." +msgstr "Mise en tampon de la géométrie ..." + +#: flatcamTools/ToolPaint.py:2115 flatcamTools/ToolPaint.py:2424 +#: flatcamTools/ToolPaint.py:2922 +msgid "No polygon found." +msgstr "Aucun polygone trouvé." + +#: flatcamTools/ToolPaint.py:2145 +msgid "Painting polygon..." +msgstr "Peinture polygone ..." + +#: flatcamTools/ToolPaint.py:2155 flatcamTools/ToolPaint.py:2470 +#: flatcamTools/ToolPaint.py:2660 flatcamTools/ToolPaint.py:2968 +#: flatcamTools/ToolPaint.py:3147 +msgid "Painting with tool diameter = " +msgstr "Peinture avec diamètre d'outil = " + +#: flatcamTools/ToolPaint.py:2156 flatcamTools/ToolPaint.py:2471 +#: flatcamTools/ToolPaint.py:2661 flatcamTools/ToolPaint.py:2969 +#: flatcamTools/ToolPaint.py:3148 +msgid "started" +msgstr "commencé" + +#: flatcamTools/ToolPaint.py:2181 flatcamTools/ToolPaint.py:2497 +#: flatcamTools/ToolPaint.py:2687 flatcamTools/ToolPaint.py:2995 +#: flatcamTools/ToolPaint.py:3174 +msgid "Margin parameter too big. Tool is not used" +msgstr "Paramètre de marge trop grand. L'outil n'est pas utilisé" + +#: flatcamTools/ToolPaint.py:2239 flatcamTools/ToolPaint.py:2566 +#: flatcamTools/ToolPaint.py:2744 flatcamTools/ToolPaint.py:3058 +#: flatcamTools/ToolPaint.py:3236 msgid "" "Could not do Paint. Try a different combination of parameters. Or a " "different strategy of paint" @@ -15455,9 +16281,9 @@ msgstr "" "Impossible de faire de la Peinture. Essayez une combinaison de paramètres " "différente. Ou une stratégie de peinture différente" -#: flatcamTools/ToolPaint.py:1533 flatcamTools/ToolPaint.py:1967 -#: flatcamTools/ToolPaint.py:2117 flatcamTools/ToolPaint.py:2438 -#: flatcamTools/ToolPaint.py:2592 +#: flatcamTools/ToolPaint.py:2296 flatcamTools/ToolPaint.py:2632 +#: flatcamTools/ToolPaint.py:2801 flatcamTools/ToolPaint.py:3119 +#: flatcamTools/ToolPaint.py:3298 msgid "" "There is no Painting Geometry in the file.\n" "Usually it means that the tool diameter is too big for the painted " @@ -15469,80 +16295,66 @@ msgstr "" "géométrie peinte.\n" "Modifiez les paramètres de peinture et réessayez." -#: flatcamTools/ToolPaint.py:1539 +#: flatcamTools/ToolPaint.py:2319 +msgid "Paint Single failed." +msgstr "La peinture «simple» a échoué." + +#: flatcamTools/ToolPaint.py:2325 msgid "Paint Single Done." msgstr "La Peinture Simple était terminée." -#: flatcamTools/ToolPaint.py:1571 flatcamTools/ToolPaint.py:2145 -#: flatcamTools/ToolPaint.py:2620 +#: flatcamTools/ToolPaint.py:2327 flatcamTools/ToolPaint.py:2837 +#: flatcamTools/ToolPaint.py:3334 msgid "Polygon Paint started ..." msgstr "Polygon Paint a commencé ..." -#: flatcamTools/ToolPaint.py:1623 flatcamTools/ToolPaint.py:2207 +#: flatcamTools/ToolPaint.py:2406 flatcamTools/ToolPaint.py:2409 +#: flatcamTools/ToolPaint.py:2417 +msgid "Paint all polygons task started." +msgstr "La tâche de peinture de tous les polygones a commencé." + +#: flatcamTools/ToolPaint.py:2448 flatcamTools/ToolPaint.py:2946 msgid "Painting polygons..." msgstr "Peindre des polygones ..." -#: flatcamTools/ToolPaint.py:1705 flatcamTools/ToolPaint.py:1708 -#: flatcamTools/ToolPaint.py:1710 -msgid "Paint Tool. Normal painting all task started." -msgstr "Outil de Peinture. Peinture normale toutes les tâches ont commencé." - -#: flatcamTools/ToolPaint.py:1744 flatcamTools/ToolPaint.py:2023 -#: flatcamTools/ToolPaint.py:2325 flatcamTools/ToolPaint.py:2501 -msgid "Painting with tool diameter = " -msgstr "Peinture avec diamètre d'outil = " - -#: flatcamTools/ToolPaint.py:1747 flatcamTools/ToolPaint.py:2026 -#: flatcamTools/ToolPaint.py:2328 flatcamTools/ToolPaint.py:2504 -msgid "started" -msgstr "commencé" - -#: flatcamTools/ToolPaint.py:1976 +#: flatcamTools/ToolPaint.py:2641 msgid "Paint All Done." msgstr "Peindre Tout fait." -#: flatcamTools/ToolPaint.py:1987 flatcamTools/ToolPaint.py:1991 -#: flatcamTools/ToolPaint.py:1994 -msgid "Rest machining painting all task started." -msgstr "Reste l'usinage en peignant toutes les tâches commencées." - -#: flatcamTools/ToolPaint.py:2072 flatcamTools/ToolPaint.py:2388 -#: flatcamTools/ToolPaint.py:2548 -msgid "" -"Could not do Paint All. Try a different combination of parameters. Or a " -"different Method of paint" -msgstr "" -"Impossible de Tout Peindre. Essayez une combinaison de paramètres " -"différente. Ou une autre méthode de peinture" - -#: flatcamTools/ToolPaint.py:2126 flatcamTools/ToolPaint.py:2601 +#: flatcamTools/ToolPaint.py:2810 flatcamTools/ToolPaint.py:3307 msgid "Paint All with Rest-Machining done." msgstr "Peignez tout avec le reste de l'usinage fait." -#: flatcamTools/ToolPaint.py:2277 flatcamTools/ToolPaint.py:2281 -#: flatcamTools/ToolPaint.py:2284 -msgid "Normal painting area task started." -msgstr "La tâche de zone de peinture normale a commencé." +#: flatcamTools/ToolPaint.py:2829 +msgid "Paint All failed." +msgstr "La peinture «Tout» a échoué." -#: flatcamTools/ToolPaint.py:2447 +#: flatcamTools/ToolPaint.py:2835 +msgid "Paint Poly All Done." +msgstr "Peinture poly tout fait." + +#: flatcamTools/ToolPaint.py:2905 flatcamTools/ToolPaint.py:2908 +#: flatcamTools/ToolPaint.py:2914 +msgid "Painting area task started." +msgstr "La tâche de zone de peinture a commencé." + +#: flatcamTools/ToolPaint.py:3128 msgid "Paint Area Done." msgstr "Peinture de la Zone réalisée." -#: flatcamTools/ToolPaint.py:2459 flatcamTools/ToolPaint.py:2465 -msgid "Rest machining painting area task started." -msgstr "Reste l'usinage de peinture de la zone de travail a commencé." +#: flatcamTools/ToolPaint.py:3326 +msgid "Paint Area failed." +msgstr "Échec de la peinture de la Zone." -#: flatcamTools/ToolPaint.py:2462 -msgid "Paint Tool. Rest machining painting area task started." -msgstr "" -"Outil de peinture. Reste l'usinage de la peinture de la zone: tâche " -"commencée." +#: flatcamTools/ToolPaint.py:3332 +msgid "Paint Poly Area Done." +msgstr "La peinture 'Poly Zone' est terminée." #: flatcamTools/ToolPanelize.py:34 msgid "Panelize PCB" msgstr "Panéliser PCB" -#: flatcamTools/ToolPanelize.py:68 +#: flatcamTools/ToolPanelize.py:56 msgid "" "Specify the type of object to be panelized\n" "It can be of type: Gerber, Excellon or Geometry.\n" @@ -15554,7 +16366,7 @@ msgstr "" "La sélection ici décide du type d’objets qui seront\n" "dans la liste déroulante d'objets." -#: flatcamTools/ToolPanelize.py:83 +#: flatcamTools/ToolPanelize.py:89 msgid "" "Object to be panelized. This means that it will\n" "be duplicated in an array of rows and columns." @@ -15562,11 +16374,11 @@ msgstr "" "Objet à paramétrer. Cela signifie qu'il sera\n" "être dupliqué dans un tableau de lignes et de colonnes." -#: flatcamTools/ToolPanelize.py:96 +#: flatcamTools/ToolPanelize.py:102 msgid "Penelization Reference" msgstr "Référence de pénalisation" -#: flatcamTools/ToolPanelize.py:98 +#: flatcamTools/ToolPanelize.py:104 msgid "" "Choose the reference for panelization:\n" "- Object = the bounding box of a different object\n" @@ -15586,11 +16398,11 @@ msgstr "" "à cet objet de référence maintenant donc le panneau\n" "objets synchronisés." -#: flatcamTools/ToolPanelize.py:121 +#: flatcamTools/ToolPanelize.py:125 msgid "Box Type" msgstr "Type de Box" -#: flatcamTools/ToolPanelize.py:123 +#: flatcamTools/ToolPanelize.py:127 msgid "" "Specify the type of object to be used as an container for\n" "panelization. It can be: Gerber or Geometry type.\n" @@ -15602,7 +16414,7 @@ msgstr "" "La sélection ici décide du type d’objets qui seront\n" "dans la liste déroulante Objet de Box." -#: flatcamTools/ToolPanelize.py:138 +#: flatcamTools/ToolPanelize.py:141 msgid "" "The actual object that is used a container for the\n" " selected object that is to be panelized." @@ -15610,11 +16422,11 @@ msgstr "" "L'objet réel qui utilise un conteneur pour la\n" "objet sélectionné à panéliser." -#: flatcamTools/ToolPanelize.py:144 +#: flatcamTools/ToolPanelize.py:147 msgid "Panel Data" msgstr "Données du Panneau" -#: flatcamTools/ToolPanelize.py:146 +#: flatcamTools/ToolPanelize.py:149 msgid "" "This informations will shape the resulting panel.\n" "The number of rows and columns will set how many\n" @@ -15630,7 +16442,7 @@ msgstr "" "Les espacements détermineront la distance entre deux\n" "éléments du tableau de panneaux." -#: flatcamTools/ToolPanelize.py:205 +#: flatcamTools/ToolPanelize.py:208 msgid "" "Choose the type of object for the panel object:\n" "- Geometry\n" @@ -15640,15 +16452,15 @@ msgstr "" "- Géométrie\n" "- Gerber" -#: flatcamTools/ToolPanelize.py:213 +#: flatcamTools/ToolPanelize.py:216 msgid "Constrain panel within" msgstr "Contraindre le panneau dans" -#: flatcamTools/ToolPanelize.py:249 +#: flatcamTools/ToolPanelize.py:252 msgid "Panelize Object" msgstr "Objet Panelize" -#: flatcamTools/ToolPanelize.py:251 flatcamTools/ToolRulesCheck.py:492 +#: flatcamTools/ToolPanelize.py:254 flatcamTools/ToolRulesCheck.py:501 msgid "" "Panelize the specified object around the specified box.\n" "In other words it creates multiple copies of the source object,\n" @@ -15658,33 +16470,33 @@ msgstr "" "En d'autres termes, il crée plusieurs copies de l'objet source,\n" "disposés dans un tableau 2D de lignes et de colonnes." -#: flatcamTools/ToolPanelize.py:319 +#: flatcamTools/ToolPanelize.py:322 msgid "Panel. Tool" msgstr "Panneau. Outil" -#: flatcamTools/ToolPanelize.py:448 +#: flatcamTools/ToolPanelize.py:460 msgid "Columns or Rows are zero value. Change them to a positive integer." msgstr "" "Les colonnes ou les lignes ont une valeur zéro. Changez-les en un entier " "positif." -#: flatcamTools/ToolPanelize.py:485 +#: flatcamTools/ToolPanelize.py:497 msgid "Generating panel ... " msgstr "Panneau de génération ... " -#: flatcamTools/ToolPanelize.py:768 +#: flatcamTools/ToolPanelize.py:777 msgid "Generating panel ... Adding the Gerber code." msgstr "Panneau de génération ... Ajout du code Gerber." -#: flatcamTools/ToolPanelize.py:779 +#: flatcamTools/ToolPanelize.py:788 msgid "Generating panel... Spawning copies" msgstr "Génération de panneau ... Création de copies" -#: flatcamTools/ToolPanelize.py:786 +#: flatcamTools/ToolPanelize.py:795 msgid "Panel done..." msgstr "Panel terminé ..." -#: flatcamTools/ToolPanelize.py:789 +#: flatcamTools/ToolPanelize.py:798 #, python-brace-format msgid "" "{text} Too big for the constrain area. Final panel has {col} columns and " @@ -15693,7 +16505,7 @@ msgstr "" "{text} Trop grand pour la zone contrainte. Le panneau final contient {col} " "colonnes et {row}" -#: flatcamTools/ToolPanelize.py:798 +#: flatcamTools/ToolPanelize.py:807 msgid "Panel created successfully." msgstr "Panneau créé avec succès." @@ -15834,163 +16646,214 @@ msgstr "Fichier PcbWizard .INF chargé." msgid "Main PcbWizard Excellon file loaded." msgstr "Le fichier principal de PcbWizard Excellon est chargé." -#: flatcamTools/ToolPcbWizard.py:431 +#: flatcamTools/ToolPcbWizard.py:428 msgid "Cannot parse file" msgstr "Impossible d'analyser le fichier" -#: flatcamTools/ToolPcbWizard.py:456 +#: flatcamTools/ToolPcbWizard.py:452 msgid "Importing Excellon." msgstr "Importer Excellon." -#: flatcamTools/ToolPcbWizard.py:463 +#: flatcamTools/ToolPcbWizard.py:459 msgid "Import Excellon file failed." msgstr "L'importation du fichier Excellon a échoué." -#: flatcamTools/ToolPcbWizard.py:471 +#: flatcamTools/ToolPcbWizard.py:467 msgid "Imported" msgstr "Importé" -#: flatcamTools/ToolPcbWizard.py:475 +#: flatcamTools/ToolPcbWizard.py:471 msgid "Excellon merging is in progress. Please wait..." msgstr "Excellon fusion est en cours. S'il vous plaît, attendez..." -#: flatcamTools/ToolPcbWizard.py:478 +#: flatcamTools/ToolPcbWizard.py:474 msgid "The imported Excellon file is None." msgstr "Le fichier Excellon importé est Aucun." -#: flatcamTools/ToolProperties.py:119 -msgid "Properties Tool was not displayed. No object selected." -msgstr "L'outil de Propriétés n'était pas affiché. Aucun objet sélectionné." - -#: flatcamTools/ToolProperties.py:134 +#: flatcamTools/ToolProperties.py:131 msgid "Object Properties are displayed." msgstr "Les Propriétés de l'objet sont affichées." -#: flatcamTools/ToolProperties.py:135 +#: flatcamTools/ToolProperties.py:136 msgid "Properties Tool" msgstr "Outil de Propriétés" -#: flatcamTools/ToolProperties.py:149 +#: flatcamTools/ToolProperties.py:150 msgid "TYPE" msgstr "TYPE" -#: flatcamTools/ToolProperties.py:150 +#: flatcamTools/ToolProperties.py:151 msgid "NAME" msgstr "NOM" -#: flatcamTools/ToolProperties.py:151 +#: flatcamTools/ToolProperties.py:153 msgid "Dimensions" msgstr "Dimensions" -#: flatcamTools/ToolProperties.py:165 -msgid "Others" -msgstr "Autres" - -#: flatcamTools/ToolProperties.py:172 +#: flatcamTools/ToolProperties.py:181 msgid "Geo Type" msgstr "Type de géo" -#: flatcamTools/ToolProperties.py:173 +#: flatcamTools/ToolProperties.py:184 msgid "Single-Geo" msgstr "Géo-unique" -#: flatcamTools/ToolProperties.py:173 +#: flatcamTools/ToolProperties.py:185 msgid "Multi-Geo" msgstr "Multi-géo" -#: flatcamTools/ToolProperties.py:181 +#: flatcamTools/ToolProperties.py:196 msgid "Calculating dimensions ... Please wait." msgstr "Calcul des dimensions ... Veuillez patienter." -#: flatcamTools/ToolProperties.py:321 flatcamTools/ToolProperties.py:325 -#: flatcamTools/ToolProperties.py:327 +#: flatcamTools/ToolProperties.py:339 flatcamTools/ToolProperties.py:343 +#: flatcamTools/ToolProperties.py:345 msgid "Inch" msgstr "Pouce" -#: flatcamTools/ToolProperties.py:321 flatcamTools/ToolProperties.py:326 -#: flatcamTools/ToolProperties.py:328 +#: flatcamTools/ToolProperties.py:339 flatcamTools/ToolProperties.py:344 +#: flatcamTools/ToolProperties.py:346 msgid "Metric" msgstr "Métrique" -#: flatcamTools/ToolProperties.py:401 flatcamTools/ToolProperties.py:459 +#: flatcamTools/ToolProperties.py:421 flatcamTools/ToolProperties.py:486 msgid "Drills number" msgstr "Nombre de forets" -#: flatcamTools/ToolProperties.py:402 flatcamTools/ToolProperties.py:461 +#: flatcamTools/ToolProperties.py:422 flatcamTools/ToolProperties.py:488 msgid "Slots number" msgstr "Nombre d'emplacements" -#: flatcamTools/ToolProperties.py:404 +#: flatcamTools/ToolProperties.py:424 msgid "Drills total number:" msgstr "Nombre total de forets:" -#: flatcamTools/ToolProperties.py:405 +#: flatcamTools/ToolProperties.py:425 msgid "Slots total number:" msgstr "Nombre total d'emplacements:" -#: flatcamTools/ToolProperties.py:411 flatcamTools/ToolProperties.py:426 -#: flatcamTools/ToolProperties.py:429 flatcamTools/ToolProperties.py:432 -#: flatcamTools/ToolProperties.py:456 +#: flatcamTools/ToolProperties.py:452 flatcamTools/ToolProperties.py:455 +#: flatcamTools/ToolProperties.py:458 flatcamTools/ToolProperties.py:483 msgid "Present" msgstr "Présent" -#: flatcamTools/ToolProperties.py:427 flatcamTools/ToolProperties.py:457 +#: flatcamTools/ToolProperties.py:453 flatcamTools/ToolProperties.py:484 msgid "Solid Geometry" msgstr "Géométrie solide" -#: flatcamTools/ToolProperties.py:430 +#: flatcamTools/ToolProperties.py:456 msgid "GCode Text" msgstr "Texte GCode" -#: flatcamTools/ToolProperties.py:433 +#: flatcamTools/ToolProperties.py:459 msgid "GCode Geometry" msgstr "Géométrie GCode" -#: flatcamTools/ToolProperties.py:435 +#: flatcamTools/ToolProperties.py:462 msgid "Data" msgstr "Les données" -#: flatcamTools/ToolProperties.py:468 +#: flatcamTools/ToolProperties.py:495 msgid "Depth of Cut" msgstr "Profondeur de coupe" -#: flatcamTools/ToolProperties.py:480 +#: flatcamTools/ToolProperties.py:507 msgid "Clearance Height" msgstr "Hauteur de dégagement" -#: flatcamTools/ToolProperties.py:512 +#: flatcamTools/ToolProperties.py:539 msgid "Routing time" msgstr "Temps d'acheminement" -#: flatcamTools/ToolProperties.py:519 +#: flatcamTools/ToolProperties.py:546 msgid "Travelled distance" msgstr "Distance parcourue" -#: flatcamTools/ToolProperties.py:560 +#: flatcamTools/ToolProperties.py:564 msgid "Width" msgstr "Largeur" -#: flatcamTools/ToolProperties.py:566 flatcamTools/ToolProperties.py:574 +#: flatcamTools/ToolProperties.py:570 flatcamTools/ToolProperties.py:578 msgid "Box Area" msgstr "Zone de la boîte" -#: flatcamTools/ToolProperties.py:569 flatcamTools/ToolProperties.py:577 +#: flatcamTools/ToolProperties.py:573 flatcamTools/ToolProperties.py:581 msgid "Convex_Hull Area" msgstr "Zone de coque convexe" -#: flatcamTools/ToolProperties.py:583 flatcamTools/ToolProperties.py:585 +#: flatcamTools/ToolProperties.py:588 flatcamTools/ToolProperties.py:591 msgid "Copper Area" msgstr "Zone de cuivre" -#: flatcamTools/ToolQRCode.py:79 +#: flatcamTools/ToolPunchGerber.py:30 flatcamTools/ToolPunchGerber.py:323 +msgid "Punch Gerber" +msgstr "Percer Gerber" + +#: flatcamTools/ToolPunchGerber.py:65 +msgid "Gerber into which to punch holes" +msgstr "Gerber pour percer des trous" + +#: flatcamTools/ToolPunchGerber.py:85 +msgid "ALL" +msgstr "TOUT" + +#: flatcamTools/ToolPunchGerber.py:166 +msgid "" +"Remove the geometry of Excellon from the Gerber to create the holes in pads." +msgstr "" +"Retirez la géométrie d'Excellon du Gerber pour créer les trous dans les " +"coussinets." + +#: flatcamTools/ToolPunchGerber.py:325 +msgid "" +"Create a Gerber object from the selected object, within\n" +"the specified box." +msgstr "" +"Créez un objet Gerber à partir de l'objet sélectionné, dans\n" +"la case spécifiée." + +#: flatcamTools/ToolPunchGerber.py:425 +msgid "Punch Tool" +msgstr "Outil de Poinçonnage" + +#: flatcamTools/ToolPunchGerber.py:599 +msgid "The value of the fixed diameter is 0.0. Aborting." +msgstr "La valeur du diamètre fixe est de 0,0. Abandon." + +#: flatcamTools/ToolPunchGerber.py:607 +msgid "" +" Could not generate punched hole Gerber because the punch hole sizeis bigger " +"than some of the apertures in the Gerber object." +msgstr "" +" Impossible de générer le trou perforé Gerber car la taille du trou " +"poinçonné est plus grande que certaines des ouvertures de l'objet Gerber." + +#: flatcamTools/ToolPunchGerber.py:619 +msgid "" +"Could not generate punched hole Gerber because the punch hole sizeis bigger " +"than some of the apertures in the Gerber object." +msgstr "" +"Impossible de générer le trou perforé Gerber car la taille du trou poinçonné " +"est plus grande que certaines des ouvertures de l'objet Gerber." + +#: flatcamTools/ToolPunchGerber.py:656 +msgid "" +"Could not generate punched hole Gerber because the newly created object " +"geometry is the same as the one in the source object geometry..." +msgstr "" +"Impossible de générer le trou perforé Gerber car la géométrie de l'objet " +"nouvellement créée est la même que celle de la géométrie de l'objet " +"source ..." + +#: flatcamTools/ToolQRCode.py:80 msgid "Gerber Object to which the QRCode will be added." msgstr "Objet Gerber auquel le QRCode sera ajouté." -#: flatcamTools/ToolQRCode.py:92 +#: flatcamTools/ToolQRCode.py:93 msgid "QRCode Parameters" msgstr "Paramètres QRCode" -#: flatcamTools/ToolQRCode.py:94 +#: flatcamTools/ToolQRCode.py:95 msgid "The parameters used to shape the QRCode." msgstr "Les paramètres utilisés pour façonner le QRCode." @@ -16034,31 +16897,27 @@ msgstr "Insérez QRCode" msgid "Create the QRCode object." msgstr "Créez l'objet QRCode." -#: flatcamTools/ToolQRCode.py:413 flatcamTools/ToolQRCode.py:748 -#: flatcamTools/ToolQRCode.py:797 +#: flatcamTools/ToolQRCode.py:415 flatcamTools/ToolQRCode.py:750 +#: flatcamTools/ToolQRCode.py:799 msgid "Cancelled. There is no QRCode Data in the text box." msgstr "Annulé. Il n'y a pas de données QRCode dans la zone de texte." -#: flatcamTools/ToolQRCode.py:432 +#: flatcamTools/ToolQRCode.py:434 msgid "Generating QRCode geometry" msgstr "Génération de la géométrie QRCode" -#: flatcamTools/ToolQRCode.py:472 +#: flatcamTools/ToolQRCode.py:474 msgid "Click on the Destination point ..." msgstr "Cliquez sur le point de destination ..." -#: flatcamTools/ToolQRCode.py:587 +#: flatcamTools/ToolQRCode.py:589 msgid "QRCode Tool done." msgstr "Outil QRCode terminé." -#: flatcamTools/ToolQRCode.py:780 flatcamTools/ToolQRCode.py:784 +#: flatcamTools/ToolQRCode.py:782 flatcamTools/ToolQRCode.py:786 msgid "Export PNG" msgstr "Exporter en PNG" -#: flatcamTools/ToolQRCode.py:789 -msgid " Export PNG cancelled." -msgstr " Export PNG annulé." - #: flatcamTools/ToolRulesCheck.py:33 msgid "Check Rules" msgstr "Vérifiez les Règles" @@ -16071,79 +16930,79 @@ msgstr "Fichiers Gerber" msgid "Gerber objects for which to check rules." msgstr "Objets Gerber pour lesquels vérifier les règles." -#: flatcamTools/ToolRulesCheck.py:77 +#: flatcamTools/ToolRulesCheck.py:78 msgid "Top" msgstr "Haut" -#: flatcamTools/ToolRulesCheck.py:79 +#: flatcamTools/ToolRulesCheck.py:80 msgid "The Top Gerber Copper object for which rules are checked." msgstr "L'objet cuivre supérieur Gerber pour lequel les règles sont vérifiées." -#: flatcamTools/ToolRulesCheck.py:94 +#: flatcamTools/ToolRulesCheck.py:96 msgid "Bottom" msgstr "Bas" -#: flatcamTools/ToolRulesCheck.py:96 +#: flatcamTools/ToolRulesCheck.py:98 msgid "The Bottom Gerber Copper object for which rules are checked." msgstr "" "Objet de cuivre Gerber inférieur pour lequel les règles sont vérifiées." -#: flatcamTools/ToolRulesCheck.py:111 +#: flatcamTools/ToolRulesCheck.py:114 msgid "SM Top" msgstr "SM Top" -#: flatcamTools/ToolRulesCheck.py:113 +#: flatcamTools/ToolRulesCheck.py:116 msgid "The Top Gerber Solder Mask object for which rules are checked." msgstr "" "Objet de masque de soudure Gerber supérieur pour lequel les règles sont " "vérifiées." -#: flatcamTools/ToolRulesCheck.py:128 +#: flatcamTools/ToolRulesCheck.py:132 msgid "SM Bottom" msgstr "SM Bas" -#: flatcamTools/ToolRulesCheck.py:130 +#: flatcamTools/ToolRulesCheck.py:134 msgid "The Bottom Gerber Solder Mask object for which rules are checked." msgstr "" "Objet de masque de soudure Gerber inférieur pour lequel les règles sont " "vérifiées." -#: flatcamTools/ToolRulesCheck.py:145 +#: flatcamTools/ToolRulesCheck.py:150 msgid "Silk Top" msgstr "Sérigraphie Haut" -#: flatcamTools/ToolRulesCheck.py:147 +#: flatcamTools/ToolRulesCheck.py:152 msgid "The Top Gerber Silkscreen object for which rules are checked." msgstr "" "Objet de la sérigraphie Top Gerber pour lequel les règles sont vérifiées." -#: flatcamTools/ToolRulesCheck.py:162 +#: flatcamTools/ToolRulesCheck.py:168 msgid "Silk Bottom" msgstr "Fond sérigraphie" -#: flatcamTools/ToolRulesCheck.py:164 +#: flatcamTools/ToolRulesCheck.py:170 msgid "The Bottom Gerber Silkscreen object for which rules are checked." msgstr "" "L'objet Gerber Silkscreen inférieur pour lequel les règles sont vérifiées." -#: flatcamTools/ToolRulesCheck.py:181 +#: flatcamTools/ToolRulesCheck.py:188 msgid "The Gerber Outline (Cutout) object for which rules are checked." msgstr "" "Objet de contour de Gerber (découpe) pour lequel les règles sont vérifiées." -#: flatcamTools/ToolRulesCheck.py:192 +#: flatcamTools/ToolRulesCheck.py:199 msgid "Excellon Objects" msgstr "Excellon Objets" -#: flatcamTools/ToolRulesCheck.py:194 +#: flatcamTools/ToolRulesCheck.py:201 msgid "Excellon objects for which to check rules." msgstr "Excellon objets pour lesquels vérifier les règles." -#: flatcamTools/ToolRulesCheck.py:205 +#: flatcamTools/ToolRulesCheck.py:213 msgid "Excellon 1" msgstr "Excellon 1" -#: flatcamTools/ToolRulesCheck.py:207 +#: flatcamTools/ToolRulesCheck.py:215 msgid "" "Excellon object for which to check rules.\n" "Holds the plated holes or a general Excellon file content." @@ -16151,11 +17010,11 @@ msgstr "" "Objet Excellon pour lequel vérifier les règles.\n" "Contient les trous métallisés ou le contenu général d’un fichier Excellon." -#: flatcamTools/ToolRulesCheck.py:223 +#: flatcamTools/ToolRulesCheck.py:232 msgid "Excellon 2" msgstr "Excellon 2" -#: flatcamTools/ToolRulesCheck.py:225 +#: flatcamTools/ToolRulesCheck.py:234 msgid "" "Excellon object for which to check rules.\n" "Holds the non-plated holes." @@ -16163,35 +17022,35 @@ msgstr "" "Objet Excellon pour lequel vérifier les règles.\n" "Maintient les trous non plaqués." -#: flatcamTools/ToolRulesCheck.py:238 +#: flatcamTools/ToolRulesCheck.py:247 msgid "All Rules" msgstr "Toutes les règles" -#: flatcamTools/ToolRulesCheck.py:240 +#: flatcamTools/ToolRulesCheck.py:249 msgid "This check/uncheck all the rules below." msgstr "Cette case à cocher / décocher toutes les règles ci-dessous." -#: flatcamTools/ToolRulesCheck.py:490 +#: flatcamTools/ToolRulesCheck.py:499 msgid "Run Rules Check" msgstr "Exécuter la Vér. des Règles" -#: flatcamTools/ToolRulesCheck.py:1149 flatcamTools/ToolRulesCheck.py:1209 -#: flatcamTools/ToolRulesCheck.py:1246 flatcamTools/ToolRulesCheck.py:1318 -#: flatcamTools/ToolRulesCheck.py:1372 flatcamTools/ToolRulesCheck.py:1410 -#: flatcamTools/ToolRulesCheck.py:1475 +#: flatcamTools/ToolRulesCheck.py:1158 flatcamTools/ToolRulesCheck.py:1218 +#: flatcamTools/ToolRulesCheck.py:1255 flatcamTools/ToolRulesCheck.py:1327 +#: flatcamTools/ToolRulesCheck.py:1381 flatcamTools/ToolRulesCheck.py:1419 +#: flatcamTools/ToolRulesCheck.py:1484 msgid "Value is not valid." msgstr "La valeur n'est pas valide." -#: flatcamTools/ToolRulesCheck.py:1163 +#: flatcamTools/ToolRulesCheck.py:1172 msgid "TOP -> Copper to Copper clearance" msgstr "TOP -> Distance de cuivre à cuivre" -#: flatcamTools/ToolRulesCheck.py:1174 +#: flatcamTools/ToolRulesCheck.py:1183 msgid "BOTTOM -> Copper to Copper clearance" msgstr "EN BAS -> Distance de cuivre à cuivre" -#: flatcamTools/ToolRulesCheck.py:1179 flatcamTools/ToolRulesCheck.py:1273 -#: flatcamTools/ToolRulesCheck.py:1437 +#: flatcamTools/ToolRulesCheck.py:1188 flatcamTools/ToolRulesCheck.py:1282 +#: flatcamTools/ToolRulesCheck.py:1446 msgid "" "At least one Gerber object has to be selected for this rule but none is " "selected." @@ -16199,13 +17058,13 @@ msgstr "" "Au moins un objet Gerber doit être sélectionné pour cette règle, mais aucun " "n'est sélectionné." -#: flatcamTools/ToolRulesCheck.py:1215 +#: flatcamTools/ToolRulesCheck.py:1224 msgid "" "One of the copper Gerber objects or the Outline Gerber object is not valid." msgstr "" "L'un des objets cuivre Gerber ou l'objet Contour Gerber n'est pas valide." -#: flatcamTools/ToolRulesCheck.py:1228 flatcamTools/ToolRulesCheck.py:1392 +#: flatcamTools/ToolRulesCheck.py:1237 flatcamTools/ToolRulesCheck.py:1401 msgid "" "Outline Gerber object presence is mandatory for this rule but it is not " "selected." @@ -16213,31 +17072,31 @@ msgstr "" "La présence de l’objet Gerber est obligatoire pour cette règle, mais elle " "n’est pas sélectionnée." -#: flatcamTools/ToolRulesCheck.py:1245 flatcamTools/ToolRulesCheck.py:1272 +#: flatcamTools/ToolRulesCheck.py:1254 flatcamTools/ToolRulesCheck.py:1281 msgid "Silk to Silk clearance" msgstr "Sérigraphie à distance de sérigraphie" -#: flatcamTools/ToolRulesCheck.py:1258 +#: flatcamTools/ToolRulesCheck.py:1267 msgid "TOP -> Silk to Silk clearance" msgstr "TOP -> Distance de sérigraphie à sérigraphie" -#: flatcamTools/ToolRulesCheck.py:1268 +#: flatcamTools/ToolRulesCheck.py:1277 msgid "BOTTOM -> Silk to Silk clearance" msgstr "BAS -> Distance de sérigraphie à sérigraphie" -#: flatcamTools/ToolRulesCheck.py:1324 +#: flatcamTools/ToolRulesCheck.py:1333 msgid "One or more of the Gerber objects is not valid." msgstr "Un ou plusieurs objets Gerber n'est pas valide." -#: flatcamTools/ToolRulesCheck.py:1332 +#: flatcamTools/ToolRulesCheck.py:1341 msgid "TOP -> Silk to Solder Mask Clearance" msgstr "TOP -> Distance entre masque et masque de soudure" -#: flatcamTools/ToolRulesCheck.py:1338 +#: flatcamTools/ToolRulesCheck.py:1347 msgid "BOTTOM -> Silk to Solder Mask Clearance" msgstr "EN BAS -> Distance de sérigraphie à masque de soudure" -#: flatcamTools/ToolRulesCheck.py:1342 +#: flatcamTools/ToolRulesCheck.py:1351 msgid "" "Both Silk and Solder Mask Gerber objects has to be either both Top or both " "Bottom." @@ -16245,62 +17104,62 @@ msgstr "" "Les objets Gerber Mask de sérigraphie et de masque de soudure doivent être " "tous les deux supérieurs ou inférieurs." -#: flatcamTools/ToolRulesCheck.py:1378 +#: flatcamTools/ToolRulesCheck.py:1387 msgid "" "One of the Silk Gerber objects or the Outline Gerber object is not valid." msgstr "" "L'un des objets Gerber en sérigraphie ou l'objet Contour Gerber n'est pas " "valide." -#: flatcamTools/ToolRulesCheck.py:1422 +#: flatcamTools/ToolRulesCheck.py:1431 msgid "TOP -> Minimum Solder Mask Sliver" msgstr "TOP -> ruban de masque de soudure minimum" -#: flatcamTools/ToolRulesCheck.py:1432 +#: flatcamTools/ToolRulesCheck.py:1441 msgid "BOTTOM -> Minimum Solder Mask Sliver" msgstr "BAS-> ruban de masque de soudure minimum" -#: flatcamTools/ToolRulesCheck.py:1481 +#: flatcamTools/ToolRulesCheck.py:1490 msgid "One of the Copper Gerber objects or the Excellon objects is not valid." msgstr "L'un des objets Copper Gerber ou Excellon n'est pas valide." -#: flatcamTools/ToolRulesCheck.py:1497 +#: flatcamTools/ToolRulesCheck.py:1506 msgid "" "Excellon object presence is mandatory for this rule but none is selected." msgstr "" "La présence d'objet Excellon est obligatoire pour cette règle, mais aucune " "n'est sélectionnée." -#: flatcamTools/ToolRulesCheck.py:1570 flatcamTools/ToolRulesCheck.py:1583 -#: flatcamTools/ToolRulesCheck.py:1594 flatcamTools/ToolRulesCheck.py:1607 +#: flatcamTools/ToolRulesCheck.py:1579 flatcamTools/ToolRulesCheck.py:1592 +#: flatcamTools/ToolRulesCheck.py:1603 flatcamTools/ToolRulesCheck.py:1616 msgid "STATUS" msgstr "STATUT" -#: flatcamTools/ToolRulesCheck.py:1573 flatcamTools/ToolRulesCheck.py:1597 +#: flatcamTools/ToolRulesCheck.py:1582 flatcamTools/ToolRulesCheck.py:1606 msgid "FAILED" msgstr "ÉCHOUÉ" -#: flatcamTools/ToolRulesCheck.py:1586 flatcamTools/ToolRulesCheck.py:1610 +#: flatcamTools/ToolRulesCheck.py:1595 flatcamTools/ToolRulesCheck.py:1619 msgid "PASSED" msgstr "PASSÉ" -#: flatcamTools/ToolRulesCheck.py:1587 flatcamTools/ToolRulesCheck.py:1611 +#: flatcamTools/ToolRulesCheck.py:1596 flatcamTools/ToolRulesCheck.py:1620 msgid "Violations: There are no violations for the current rule." msgstr "Violations: Il n'y a pas de violations pour la règle actuelle." -#: flatcamTools/ToolShell.py:70 flatcamTools/ToolShell.py:72 -msgid "...proccessing..." -msgstr "...en traitement..." +#: flatcamTools/ToolShell.py:72 flatcamTools/ToolShell.py:74 +msgid "...processing..." +msgstr "...En traitement..." -#: flatcamTools/ToolSolderPaste.py:37 +#: flatcamTools/ToolSolderPaste.py:38 msgid "Solder Paste Tool" msgstr "Outil de Pâte à souder" -#: flatcamTools/ToolSolderPaste.py:68 +#: flatcamTools/ToolSolderPaste.py:70 msgid "Gerber Solder paste object. " msgstr "Objet de pâte à souder Gerber. " -#: flatcamTools/ToolSolderPaste.py:75 +#: flatcamTools/ToolSolderPaste.py:77 msgid "" "Tools pool from which the algorithm\n" "will pick the ones used for dispensing solder paste." @@ -16308,7 +17167,7 @@ msgstr "" "Pool d'outils à partir duquel l'algorithme\n" "choisira ceux utilisés pour la distribution de la pâte à souder." -#: flatcamTools/ToolSolderPaste.py:90 +#: flatcamTools/ToolSolderPaste.py:92 msgid "" "This is the Tool Number.\n" "The solder dispensing will start with the tool with the biggest \n" @@ -16323,7 +17182,7 @@ msgstr "" "  avec la pâte à souder, l'application émettra une boîte de message " "d'avertissement." -#: flatcamTools/ToolSolderPaste.py:97 +#: flatcamTools/ToolSolderPaste.py:99 msgid "" "Nozzle tool Diameter. It's value (in current FlatCAM units)\n" "is the width of the solder paste dispensed." @@ -16331,11 +17190,11 @@ msgstr "" "Diamètre de l'outil de buse. C'est sa valeur (en unités FlatCAM actuelles)\n" "est la largeur de la pâte à braser distribuée." -#: flatcamTools/ToolSolderPaste.py:104 +#: flatcamTools/ToolSolderPaste.py:106 msgid "New Nozzle Tool" msgstr "Nouvel Outil de Buse" -#: flatcamTools/ToolSolderPaste.py:123 +#: flatcamTools/ToolSolderPaste.py:125 msgid "" "Add a new nozzle tool to the Tool Table\n" "with the diameter specified above." @@ -16343,15 +17202,15 @@ msgstr "" "Ajouter un nouvel outil de buse à la table d'outils\n" "avec le diamètre spécifié ci-dessus." -#: flatcamTools/ToolSolderPaste.py:135 +#: flatcamTools/ToolSolderPaste.py:137 msgid "Generate solder paste dispensing geometry." msgstr "Générer la géométrie de distribution de la pâte à souder." -#: flatcamTools/ToolSolderPaste.py:154 +#: flatcamTools/ToolSolderPaste.py:156 msgid "STEP 1" msgstr "ÉTAPE 1" -#: flatcamTools/ToolSolderPaste.py:156 +#: flatcamTools/ToolSolderPaste.py:158 msgid "" "First step is to select a number of nozzle tools for usage\n" "and then optionally modify the GCode parameters bellow." @@ -16360,7 +17219,7 @@ msgstr "" "à utiliser.\n" "et éventuellement modifier les paramètres GCode ci-dessous." -#: flatcamTools/ToolSolderPaste.py:159 +#: flatcamTools/ToolSolderPaste.py:161 msgid "" "Select tools.\n" "Modify parameters." @@ -16368,7 +17227,7 @@ msgstr "" "Sélectionnez des outils.\n" "Modifier les paramètres." -#: flatcamTools/ToolSolderPaste.py:279 +#: flatcamTools/ToolSolderPaste.py:281 msgid "" "Feedrate (speed) while moving up vertically\n" " to Dispense position (on Z plane)." @@ -16376,7 +17235,7 @@ msgstr "" "Avance (vitesse) en montant verticalement\n" "position de distribution (sur le plan Z)." -#: flatcamTools/ToolSolderPaste.py:349 +#: flatcamTools/ToolSolderPaste.py:351 msgid "" "Generate GCode for Solder Paste dispensing\n" "on PCB pads." @@ -16384,11 +17243,11 @@ msgstr "" "Générer GCode pour la distribution de pâte à souder\n" "sur les PCB pads." -#: flatcamTools/ToolSolderPaste.py:370 +#: flatcamTools/ToolSolderPaste.py:372 msgid "STEP 2" msgstr "ÉTAPE 2" -#: flatcamTools/ToolSolderPaste.py:372 +#: flatcamTools/ToolSolderPaste.py:374 msgid "" "Second step is to create a solder paste dispensing\n" "geometry out of an Solder Paste Mask Gerber file." @@ -16396,11 +17255,11 @@ msgstr "" "La deuxième étape consiste à créer une distribution de pâte à braser\n" "géométrie d'un fichier Gerber de masque de collage de soudure." -#: flatcamTools/ToolSolderPaste.py:388 +#: flatcamTools/ToolSolderPaste.py:391 msgid "Geo Result" msgstr "Résultat de la Géo" -#: flatcamTools/ToolSolderPaste.py:390 +#: flatcamTools/ToolSolderPaste.py:393 msgid "" "Geometry Solder Paste object.\n" "The name of the object has to end in:\n" @@ -16410,11 +17269,11 @@ msgstr "" "Le nom de l'objet doit se terminer par:\n" "'_solderpaste' comme protection." -#: flatcamTools/ToolSolderPaste.py:399 +#: flatcamTools/ToolSolderPaste.py:402 msgid "STEP 3" msgstr "ÉTAPE 3" -#: flatcamTools/ToolSolderPaste.py:401 +#: flatcamTools/ToolSolderPaste.py:404 msgid "" "Third step is to select a solder paste dispensing geometry,\n" "and then generate a CNCJob object.\n" @@ -16431,11 +17290,11 @@ msgstr "" "vous devez d’abord générer une géométrie avec ces nouveaux paramètres,\n" "et seulement après cela, vous pouvez générer un CNCJob mis à jour." -#: flatcamTools/ToolSolderPaste.py:421 +#: flatcamTools/ToolSolderPaste.py:425 msgid "CNC Result" msgstr "Résultat CNC" -#: flatcamTools/ToolSolderPaste.py:423 +#: flatcamTools/ToolSolderPaste.py:427 msgid "" "CNCJob Solder paste object.\n" "In order to enable the GCode save section,\n" @@ -16447,11 +17306,11 @@ msgstr "" "le nom de l'objet doit se terminer par:\n" "'_solderpaste' comme protection." -#: flatcamTools/ToolSolderPaste.py:433 +#: flatcamTools/ToolSolderPaste.py:437 msgid "View GCode" msgstr "Voir le GCode" -#: flatcamTools/ToolSolderPaste.py:435 +#: flatcamTools/ToolSolderPaste.py:439 msgid "" "View the generated GCode for Solder Paste dispensing\n" "on PCB pads." @@ -16459,11 +17318,11 @@ msgstr "" "Afficher le GCode généré pour la distribution de pâte à souder\n" "sur les plaquettes de circuits imprimés." -#: flatcamTools/ToolSolderPaste.py:445 +#: flatcamTools/ToolSolderPaste.py:449 msgid "Save GCode" msgstr "Enregistrer le GCode" -#: flatcamTools/ToolSolderPaste.py:447 +#: flatcamTools/ToolSolderPaste.py:451 msgid "" "Save the generated GCode for Solder Paste dispensing\n" "on PCB pads, to a file." @@ -16471,11 +17330,11 @@ msgstr "" "Sauvegarder le GCode généré pour la distribution de pâte à souder\n" "sur des plaquettes de circuits imprimés, dans un fichier." -#: flatcamTools/ToolSolderPaste.py:457 +#: flatcamTools/ToolSolderPaste.py:461 msgid "STEP 4" msgstr "ÉTAPE 4" -#: flatcamTools/ToolSolderPaste.py:459 +#: flatcamTools/ToolSolderPaste.py:463 msgid "" "Fourth step (and last) is to select a CNCJob made from \n" "a solder paste dispensing geometry, and then view/save it's GCode." @@ -16485,92 +17344,87 @@ msgstr "" "une géométrie de distribution de la pâte à souder, puis affichez / " "enregistrez son GCode." -#: flatcamTools/ToolSolderPaste.py:917 -msgid "Adding Nozzle tool cancelled. Tool already in Tool Table." -msgstr "" -"L'ajout de l'outil de buse est annulé. Outil déjà dans la table d'outils." - -#: flatcamTools/ToolSolderPaste.py:923 +#: flatcamTools/ToolSolderPaste.py:922 msgid "New Nozzle tool added to Tool Table." msgstr "Nouvel Outil de Buse ajouté à la table d'outils." -#: flatcamTools/ToolSolderPaste.py:966 +#: flatcamTools/ToolSolderPaste.py:965 msgid "Nozzle tool from Tool Table was edited." msgstr "L'outil de buse de la table d'outils a été modifié." -#: flatcamTools/ToolSolderPaste.py:1024 +#: flatcamTools/ToolSolderPaste.py:1023 msgid "Delete failed. Select a Nozzle tool to delete." msgstr "La suppression a échoué. Sélectionnez un outil de buse à supprimer." -#: flatcamTools/ToolSolderPaste.py:1030 +#: flatcamTools/ToolSolderPaste.py:1029 msgid "Nozzle tool(s) deleted from Tool Table." msgstr "Outil (s) de buse supprimé (s) de la table d'outils." -#: flatcamTools/ToolSolderPaste.py:1086 +#: flatcamTools/ToolSolderPaste.py:1085 msgid "No SolderPaste mask Gerber object loaded." msgstr "Aucun objet Gerber de masque de pâte à souder chargé." -#: flatcamTools/ToolSolderPaste.py:1104 +#: flatcamTools/ToolSolderPaste.py:1103 msgid "Creating Solder Paste dispensing geometry." msgstr "Création de la géométrie de distribution de pâte à souder." -#: flatcamTools/ToolSolderPaste.py:1117 +#: flatcamTools/ToolSolderPaste.py:1116 msgid "No Nozzle tools in the tool table." msgstr "Aucun outil de buse dans la table à outils." -#: flatcamTools/ToolSolderPaste.py:1244 +#: flatcamTools/ToolSolderPaste.py:1242 msgid "Cancelled. Empty file, it has no geometry..." msgstr "Annulé. Fichier vide, il n'a pas de géométrie ..." -#: flatcamTools/ToolSolderPaste.py:1248 +#: flatcamTools/ToolSolderPaste.py:1245 msgid "Solder Paste geometry generated successfully" msgstr "Géométrie de pâte à souder générée avec succès" -#: flatcamTools/ToolSolderPaste.py:1255 +#: flatcamTools/ToolSolderPaste.py:1252 msgid "Some or all pads have no solder due of inadequate nozzle diameters..." msgstr "" "Certains ou tous les tampons n'ont pas de soudure en raison de diamètres de " "buse inadéquats ..." -#: flatcamTools/ToolSolderPaste.py:1269 +#: flatcamTools/ToolSolderPaste.py:1266 msgid "Generating Solder Paste dispensing geometry..." msgstr "Génération de géométrie de distribution de pâte à souder ..." -#: flatcamTools/ToolSolderPaste.py:1289 +#: flatcamTools/ToolSolderPaste.py:1286 msgid "There is no Geometry object available." msgstr "Il n'y a pas d'objet Géométrie disponible." -#: flatcamTools/ToolSolderPaste.py:1294 +#: flatcamTools/ToolSolderPaste.py:1291 msgid "This Geometry can't be processed. NOT a solder_paste_tool geometry." msgstr "" "Cette géométrie ne peut pas être traitée. PAS une géométrie " "solder_paste_tool." -#: flatcamTools/ToolSolderPaste.py:1401 +#: flatcamTools/ToolSolderPaste.py:1392 msgid "ToolSolderPaste CNCjob created" msgstr "Outil de Pâte à Souder CNCjob créé" -#: flatcamTools/ToolSolderPaste.py:1422 +#: flatcamTools/ToolSolderPaste.py:1411 msgid "SP GCode Editor" msgstr "Éditeur SP GCode" -#: flatcamTools/ToolSolderPaste.py:1434 flatcamTools/ToolSolderPaste.py:1439 -#: flatcamTools/ToolSolderPaste.py:1494 +#: flatcamTools/ToolSolderPaste.py:1423 flatcamTools/ToolSolderPaste.py:1428 +#: flatcamTools/ToolSolderPaste.py:1483 msgid "" "This CNCJob object can't be processed. NOT a solder_paste_tool CNCJob object." msgstr "" "Cet objet CNCJob ne peut pas être traité. PAS un objet CNCJob " "solder_paste_tool." -#: flatcamTools/ToolSolderPaste.py:1464 +#: flatcamTools/ToolSolderPaste.py:1453 msgid "No Gcode in the object" msgstr "Pas de Gcode dans l'objet" -#: flatcamTools/ToolSolderPaste.py:1504 +#: flatcamTools/ToolSolderPaste.py:1493 msgid "Export GCode ..." msgstr "Exporter le GCode ..." -#: flatcamTools/ToolSolderPaste.py:1552 +#: flatcamTools/ToolSolderPaste.py:1541 msgid "Solder paste dispenser GCode file saved to" msgstr "Fichier GCode du distributeur de pâte à souder enregistré dans" @@ -16578,7 +17432,7 @@ msgstr "Fichier GCode du distributeur de pâte à souder enregistré dans" msgid "Gerber Objects" msgstr "Objets Gerber" -#: flatcamTools/ToolSub.py:76 +#: flatcamTools/ToolSub.py:78 msgid "" "Gerber object from which to subtract\n" "the subtractor Gerber object." @@ -16586,11 +17440,11 @@ msgstr "" "Objet de Gerber auquel soustraire\n" "l'objet soustracteur Gerber." -#: flatcamTools/ToolSub.py:88 flatcamTools/ToolSub.py:140 +#: flatcamTools/ToolSub.py:91 flatcamTools/ToolSub.py:146 msgid "Subtractor" msgstr "Soustracteur" -#: flatcamTools/ToolSub.py:90 +#: flatcamTools/ToolSub.py:93 msgid "" "Gerber object that will be subtracted\n" "from the target Gerber object." @@ -16598,11 +17452,11 @@ msgstr "" "Objet Gerber qui sera soustrait\n" "à partir de l'objet Gerber cible." -#: flatcamTools/ToolSub.py:97 +#: flatcamTools/ToolSub.py:100 msgid "Substract Gerber" msgstr "Soustraire Gerber" -#: flatcamTools/ToolSub.py:99 +#: flatcamTools/ToolSub.py:102 msgid "" "Will remove the area occupied by the subtractor\n" "Gerber from the Target Gerber.\n" @@ -16614,11 +17468,11 @@ msgstr "" "Peut être utilisé pour enlever la sérigraphie qui se chevauchent\n" "sur le masque de soudure." -#: flatcamTools/ToolSub.py:117 +#: flatcamTools/ToolSub.py:120 msgid "Geometry Objects" msgstr "Objets géométriques" -#: flatcamTools/ToolSub.py:128 +#: flatcamTools/ToolSub.py:133 msgid "" "Geometry object from which to subtract\n" "the subtractor Geometry object." @@ -16626,7 +17480,7 @@ msgstr "" "Objet de géométrie à soustraire\n" "l'objet géométrique soustracteur." -#: flatcamTools/ToolSub.py:142 +#: flatcamTools/ToolSub.py:148 msgid "" "Geometry object that will be subtracted\n" "from the target Geometry object." @@ -16634,18 +17488,18 @@ msgstr "" "Objet de géométrie qui sera soustrait\n" "à partir de l'objet de géométrie cible." -#: flatcamTools/ToolSub.py:150 +#: flatcamTools/ToolSub.py:156 msgid "" "Checking this will close the paths cut by the Geometry subtractor object." msgstr "" "En cochant cette case, vous fermez les chemins coupés par l'objet " "soustracteur de géométrie." -#: flatcamTools/ToolSub.py:153 +#: flatcamTools/ToolSub.py:159 msgid "Subtract Geometry" msgstr "Soustraire la géométrie" -#: flatcamTools/ToolSub.py:155 +#: flatcamTools/ToolSub.py:161 msgid "" "Will remove the area occupied by the subtractor\n" "Geometry from the Target Geometry." @@ -16653,58 +17507,58 @@ msgstr "" "Va supprimer la zone occupée par le soustracteur\n" "Géométrie à partir de la géométrie cible." -#: flatcamTools/ToolSub.py:262 +#: flatcamTools/ToolSub.py:263 msgid "Sub Tool" msgstr "Outil Sous" -#: flatcamTools/ToolSub.py:278 flatcamTools/ToolSub.py:483 +#: flatcamTools/ToolSub.py:284 flatcamTools/ToolSub.py:489 msgid "No Target object loaded." msgstr "Aucun objet cible chargé." -#: flatcamTools/ToolSub.py:281 +#: flatcamTools/ToolSub.py:287 msgid "Loading geometry from Gerber objects." msgstr "Chargement de la géométrie à partir d'objets Gerber." -#: flatcamTools/ToolSub.py:293 flatcamTools/ToolSub.py:498 +#: flatcamTools/ToolSub.py:299 flatcamTools/ToolSub.py:504 msgid "No Subtractor object loaded." msgstr "Aucun objet soustracteur n'a été chargé." -#: flatcamTools/ToolSub.py:325 +#: flatcamTools/ToolSub.py:331 msgid "Processing geometry from Subtractor Gerber object." msgstr "Traitement de la géométrie de l'objet Gerber soustracteur." -#: flatcamTools/ToolSub.py:346 +#: flatcamTools/ToolSub.py:352 msgid "Parsing geometry for aperture" msgstr "Analyser la géométrie pour l'ouverture" -#: flatcamTools/ToolSub.py:407 +#: flatcamTools/ToolSub.py:413 msgid "Finished parsing geometry for aperture" msgstr "Géométrie d'analyse terminée pour l'ouverture" -#: flatcamTools/ToolSub.py:452 flatcamTools/ToolSub.py:655 +#: flatcamTools/ToolSub.py:458 flatcamTools/ToolSub.py:661 msgid "Generating new object ..." msgstr "Générer un nouvel objet ..." -#: flatcamTools/ToolSub.py:456 flatcamTools/ToolSub.py:659 -#: flatcamTools/ToolSub.py:740 +#: flatcamTools/ToolSub.py:462 flatcamTools/ToolSub.py:665 +#: flatcamTools/ToolSub.py:746 msgid "Generating new object failed." msgstr "La génération du nouvel objet a échoué." -#: flatcamTools/ToolSub.py:461 flatcamTools/ToolSub.py:665 +#: flatcamTools/ToolSub.py:467 flatcamTools/ToolSub.py:671 msgid "Created" msgstr "Établi" -#: flatcamTools/ToolSub.py:512 +#: flatcamTools/ToolSub.py:518 msgid "Currently, the Subtractor geometry cannot be of type Multigeo." msgstr "" "Actuellement, la géométrie du soustracteur ne peut pas être de type multi-" "géo." -#: flatcamTools/ToolSub.py:557 +#: flatcamTools/ToolSub.py:563 msgid "Parsing solid_geometry ..." msgstr "Analyse de solid_geometry ..." -#: flatcamTools/ToolSub.py:559 +#: flatcamTools/ToolSub.py:565 msgid "Parsing solid_geometry for tool" msgstr "Analyse de solid_geometry pour l'outil" @@ -16712,7 +17566,7 @@ msgstr "Analyse de solid_geometry pour l'outil" msgid "Object Transform" msgstr "Transformation d'objet" -#: flatcamTools/ToolTransform.py:82 +#: flatcamTools/ToolTransform.py:79 msgid "" "Rotate the selected object(s).\n" "The point of reference is the middle of\n" @@ -16722,7 +17576,7 @@ msgstr "" "Le point de référence est le milieu de\n" "le cadre de sélection pour tous les objets sélectionnés." -#: flatcamTools/ToolTransform.py:100 flatcamTools/ToolTransform.py:122 +#: flatcamTools/ToolTransform.py:100 flatcamTools/ToolTransform.py:121 msgid "" "Angle for Skew action, in degrees.\n" "Float number between -360 and 360." @@ -16730,7 +17584,7 @@ msgstr "" "Angle pour l'action asymétrique, en degrés.\n" "Nombre flottant entre -360 et 360." -#: flatcamTools/ToolTransform.py:111 flatcamTools/ToolTransform.py:133 +#: flatcamTools/ToolTransform.py:110 flatcamTools/ToolTransform.py:131 msgid "" "Skew/shear the selected object(s).\n" "The point of reference is the middle of\n" @@ -16740,7 +17594,7 @@ msgstr "" "Le point de référence est le milieu de\n" "le cadre de sélection pour tous les objets sélectionnés." -#: flatcamTools/ToolTransform.py:160 flatcamTools/ToolTransform.py:181 +#: flatcamTools/ToolTransform.py:160 flatcamTools/ToolTransform.py:180 msgid "" "Scale the selected object(s).\n" "The point of reference depends on \n" @@ -16750,7 +17604,7 @@ msgstr "" "Le point de référence dépend de\n" "l'état de la case à cocher référence d'échelle." -#: flatcamTools/ToolTransform.py:229 flatcamTools/ToolTransform.py:250 +#: flatcamTools/ToolTransform.py:229 flatcamTools/ToolTransform.py:249 msgid "" "Offset the selected object(s).\n" "The point of reference is the middle of\n" @@ -16760,202 +17614,612 @@ msgstr "" "Le point de référence est le milieu de\n" "le cadre de sélection pour tous les objets sélectionnés.\n" -#: flatcamTools/ToolTransform.py:268 flatcamTools/ToolTransform.py:274 +#: flatcamTools/ToolTransform.py:269 flatcamTools/ToolTransform.py:274 msgid "Flip the selected object(s) over the X axis." msgstr "Retournez le ou les objets sélectionnés sur l’axe X." -#: flatcamTools/ToolTransform.py:299 +#: flatcamTools/ToolTransform.py:298 msgid "Ref. Point" msgstr "Miroir Réf. Point" -#: flatcamTools/ToolTransform.py:351 +#: flatcamTools/ToolTransform.py:349 msgid "" "Create the buffer effect on each geometry,\n" -"element from the selected object." +"element from the selected object, using the distance." msgstr "" "Créez l'effet tampon sur chaque géométrie,\n" -"élément de l'objet sélectionné." +"élément de l'objet sélectionné, en utilisant la distance." -#: flatcamTools/ToolTransform.py:498 +#: flatcamTools/ToolTransform.py:375 +msgid "" +"Create the buffer effect on each geometry,\n" +"element from the selected object, using the factor." +msgstr "" +"Créez l'effet tampon sur chaque géométrie,\n" +"élément de l'objet sélectionné, en utilisant le facteur." + +#: flatcamTools/ToolTransform.py:480 +msgid "Buffer D" +msgstr "Tampon D" + +#: flatcamTools/ToolTransform.py:481 +msgid "Buffer F" +msgstr "Tampon F" + +#: flatcamTools/ToolTransform.py:558 msgid "Rotate transformation can not be done for a value of 0." msgstr "" "La transformation par rotation ne peut pas être effectuée pour une valeur de " "0." -#: flatcamTools/ToolTransform.py:537 flatcamTools/ToolTransform.py:560 +#: flatcamTools/ToolTransform.py:597 flatcamTools/ToolTransform.py:620 msgid "Scale transformation can not be done for a factor of 0 or 1." msgstr "" "La transformation d'échelle ne peut pas être effectuée pour un facteur de 0 " "ou 1." -#: flatcamTools/ToolTransform.py:575 flatcamTools/ToolTransform.py:585 +#: flatcamTools/ToolTransform.py:635 flatcamTools/ToolTransform.py:645 msgid "Offset transformation can not be done for a value of 0." msgstr "" "La transformation de décalage ne peut pas être effectuée pour une valeur de " "0." -#: flatcamTools/ToolTransform.py:608 +#: flatcamTools/ToolTransform.py:677 msgid "No object selected. Please Select an object to rotate!" msgstr "" "Aucun objet sélectionné. Veuillez sélectionner un objet à faire pivoter!" -#: flatcamTools/ToolTransform.py:636 +#: flatcamTools/ToolTransform.py:703 msgid "CNCJob objects can't be rotated." msgstr "Les objets CNCJob ne peuvent pas être pivotés." -#: flatcamTools/ToolTransform.py:644 +#: flatcamTools/ToolTransform.py:711 msgid "Rotate done" msgstr "Faire pivoter" -#: flatcamTools/ToolTransform.py:649 flatcamTools/ToolTransform.py:724 -#: flatcamTools/ToolTransform.py:779 flatcamTools/ToolTransform.py:838 -#: flatcamTools/ToolTransform.py:874 flatcamTools/ToolTransform.py:910 +#: flatcamTools/ToolTransform.py:714 flatcamTools/ToolTransform.py:784 +#: flatcamTools/ToolTransform.py:834 flatcamTools/ToolTransform.py:890 +#: flatcamTools/ToolTransform.py:922 flatcamTools/ToolTransform.py:958 msgid "Due of" msgstr "À cause de" -#: flatcamTools/ToolTransform.py:649 flatcamTools/ToolTransform.py:724 -#: flatcamTools/ToolTransform.py:779 flatcamTools/ToolTransform.py:838 -#: flatcamTools/ToolTransform.py:874 flatcamTools/ToolTransform.py:910 +#: flatcamTools/ToolTransform.py:714 flatcamTools/ToolTransform.py:784 +#: flatcamTools/ToolTransform.py:834 flatcamTools/ToolTransform.py:890 +#: flatcamTools/ToolTransform.py:922 flatcamTools/ToolTransform.py:958 msgid "action was not executed." msgstr "l'action n'a pas été exécutée." -#: flatcamTools/ToolTransform.py:661 +#: flatcamTools/ToolTransform.py:726 msgid "No object selected. Please Select an object to flip" msgstr "Aucun objet sélectionné. Veuillez sélectionner un objet à refléter" -#: flatcamTools/ToolTransform.py:696 +#: flatcamTools/ToolTransform.py:759 msgid "CNCJob objects can't be mirrored/flipped." msgstr "Les objets CNCJob ne peuvent pas être inversés / inversés." -#: flatcamTools/ToolTransform.py:734 +#: flatcamTools/ToolTransform.py:794 msgid "Skew transformation can not be done for 0, 90 and 180 degrees." msgstr "" "La transformation asymétrique ne peut pas être effectuée pour 0, 90 et 180 " "degrés." -#: flatcamTools/ToolTransform.py:739 +#: flatcamTools/ToolTransform.py:799 msgid "No object selected. Please Select an object to shear/skew!" msgstr "" "Aucun objet sélectionné. Veuillez sélectionner un objet à cisailler / " "incliner!" -#: flatcamTools/ToolTransform.py:761 +#: flatcamTools/ToolTransform.py:819 msgid "CNCJob objects can't be skewed." msgstr "Les objets CNCJob ne peuvent pas être biaisés." -#: flatcamTools/ToolTransform.py:774 +#: flatcamTools/ToolTransform.py:831 msgid "Skew on the" msgstr "Biais sur le" -#: flatcamTools/ToolTransform.py:774 flatcamTools/ToolTransform.py:834 -#: flatcamTools/ToolTransform.py:869 +#: flatcamTools/ToolTransform.py:831 flatcamTools/ToolTransform.py:887 +#: flatcamTools/ToolTransform.py:919 msgid "axis done" msgstr "axe fait" -#: flatcamTools/ToolTransform.py:791 +#: flatcamTools/ToolTransform.py:846 msgid "No object selected. Please Select an object to scale!" msgstr "" "Aucun objet sélectionné. Veuillez sélectionner un objet à mettre à l'échelle!" -#: flatcamTools/ToolTransform.py:824 +#: flatcamTools/ToolTransform.py:877 msgid "CNCJob objects can't be scaled." msgstr "Les objets CNCJob ne peuvent pas être mis à l'échelle." -#: flatcamTools/ToolTransform.py:834 +#: flatcamTools/ToolTransform.py:887 msgid "Scale on the" msgstr "Échelle sur le" -#: flatcamTools/ToolTransform.py:846 +#: flatcamTools/ToolTransform.py:898 msgid "No object selected. Please Select an object to offset!" msgstr "Aucun objet sélectionné. Veuillez sélectionner un objet à compenser!" -#: flatcamTools/ToolTransform.py:855 +#: flatcamTools/ToolTransform.py:905 msgid "CNCJob objects can't be offset." msgstr "CNCJob objects can't be offset." -#: flatcamTools/ToolTransform.py:869 +#: flatcamTools/ToolTransform.py:919 msgid "Offset on the" msgstr "Compenser sur le" -#: flatcamTools/ToolTransform.py:881 +#: flatcamTools/ToolTransform.py:929 msgid "No object selected. Please Select an object to buffer!" msgstr "Aucun objet sélectionné. Veuillez sélectionner un objet à tamponner!" -#: flatcamTools/ToolTransform.py:884 +#: flatcamTools/ToolTransform.py:932 msgid "Applying Buffer" msgstr "Application du tampon" -#: flatcamTools/ToolTransform.py:888 +#: flatcamTools/ToolTransform.py:936 msgid "CNCJob objects can't be buffered." msgstr "Les objets CNCJob ne peuvent pas être mis en mémoire tampon." -#: flatcamTools/ToolTransform.py:905 +#: flatcamTools/ToolTransform.py:953 msgid "Buffer done" msgstr "Tampon terminé" -#: tclCommands/TclCommandBbox.py:74 tclCommands/TclCommandNregions.py:73 +#: tclCommands/TclCommandBbox.py:76 tclCommands/TclCommandNregions.py:75 msgid "Expected FlatCAMGerber or FlatCAMGeometry, got" msgstr "FlatCAMGerber ou FlatCAMGeometry attendu, obtenu" -#: tclCommands/TclCommandBounds.py:64 tclCommands/TclCommandBounds.py:68 +#: tclCommands/TclCommandBounds.py:67 tclCommands/TclCommandBounds.py:71 msgid "Expected a list of objects names separated by comma. Got" msgstr "Attendu une liste de noms d'objets séparés par une virgule. Eu" -#: tclCommands/TclCommandBounds.py:79 +#: tclCommands/TclCommandBounds.py:82 msgid "TclCommand Bounds done." msgstr "TclCommand Bounds terminé." -#: tclCommands/TclCommandCopperClear.py:242 tclCommands/TclCommandPaint.py:240 -msgid "Expected -box ." -msgstr "Attendu -box ." - -#: tclCommands/TclCommandCopperClear.py:251 tclCommands/TclCommandPaint.py:249 -#: tclCommands/TclCommandScale.py:75 +#: tclCommands/TclCommandCopperClear.py:276 tclCommands/TclCommandPaint.py:272 +#: tclCommands/TclCommandScale.py:81 msgid "Could not retrieve box object" msgstr "Impossible de récupérer l'objet boîte" -#: tclCommands/TclCommandCopperClear.py:273 -msgid "" -"None of the following args: 'ref', 'all' were found or none was set to 1.\n" -"Copper clearing failed." -msgstr "" -"Aucun des arguments suivants: 'ref', 'all' ont été trouvés ou aucun n'a été " -"défini sur 1.\n" -"Le nettoyage du cuivre a échoué." +#: tclCommands/TclCommandCopperClear.py:299 +msgid "Expected either -box or -all." +msgstr "Attend soit -box ou -all." -#: tclCommands/TclCommandPaint.py:217 +#: tclCommands/TclCommandGeoCutout.py:148 +msgid "" +"The name of the object for which cutout is done is missing. Add it and retry." +msgstr "" +"Le nom de l'objet pour lequel la découpe est effectuée est manquant. Ajoutez-" +"le et réessayez." + +#: tclCommands/TclCommandGeoCutout.py:190 +msgid "Gaps value can be only one of: 'lr', 'tb', '2lr', '2tb', 4 or 8." +msgstr "" +"La valeur d'espacement ne peut être que l'une des valeurs suivantes: " +"'Aucune', 'lr', 'tb', '2lr', '2tb', 4 ou 8." + +#: tclCommands/TclCommandGeoCutout.py:302 +#: tclCommands/TclCommandGeoCutout.py:360 +msgid "Any-form Cutout operation finished." +msgstr "L'opération de découpe sous n'importe quelle forme est terminée." + +#: tclCommands/TclCommandGeoCutout.py:366 +msgid "Cancelled. Object type is not supported." +msgstr "Annulé. Le type d'objet n'est pas pris en charge." + +#: tclCommands/TclCommandHelp.py:74 +msgid "Available commands:" +msgstr "Commandes disponibles:" + +#: tclCommands/TclCommandHelp.py:112 +msgid "Type help for usage." +msgstr "Tapez help pour l'utiliser." + +#: tclCommands/TclCommandHelp.py:112 +msgid "Example: help open_gerber" +msgstr "Exemple: help open_gerber" + +#: tclCommands/TclCommandPaint.py:244 msgid "Expected -x and -y ." msgstr "Attendu -x et -y ." -#: tclCommands/TclCommandPaint.py:268 +#: tclCommands/TclCommandPaint.py:265 +msgid "Expected -box ." +msgstr "Attendu -box ." + +#: tclCommands/TclCommandPaint.py:286 msgid "" -"There was none of the following args: 'ref', 'single', 'all'.\n" +"None of the following args: 'box', 'single', 'all' were used.\n" "Paint failed." msgstr "" -"Il n'y avait aucun des arguments suivants: 'ref', 'single', 'all'.\n" +"Aucun des arguments suivants: «box», «single», «all» n'a été utilisé.\n" "La peinture a échoué." -#: tclCommands/TclCommandScale.py:95 -msgid "Expected -origin or -origin or -origin
." -msgstr "Attendu -origin ou -origin ou -origin ." +#: tclCommands/TclCommandScale.py:106 +msgid "" +"Expected -origin or -origin or -origin
or - " +"origin 3.0,4.2." +msgstr "" +"Attendu -origin ou -origin ou -origin ou - " +"origin 3.0,4.2.." -#: tclCommands/TclCommandScale.py:104 +#: tclCommands/TclCommandScale.py:119 msgid "Expected -x -y ." msgstr "Attendu -x -y ." -#: tclCommands/TclCommandSetOrigin.py:91 +#: tclCommands/TclCommandSetOrigin.py:95 msgid "Expected a pair of (x, y) coordinates. Got" msgstr "Une paire de coordonnées (x, y) attendue. Eu" -#: tclCommands/TclCommandSetOrigin.py:98 +#: tclCommands/TclCommandSetOrigin.py:102 msgid "Origin set by offsetting all loaded objects with " msgstr "Origine définie en décalant tous les objets chargés avec " -#: tclCommands/TclCommandSubtractRectangle.py:58 +#: tclCommands/TclCommandSubtractRectangle.py:62 msgid "No Geometry name in args. Provide a name and try again." msgstr "" "Aucun nom de géométrie dans les arguments. Indiquez un nom et réessayez." +#~ msgid "Executing Tcl Script ..." +#~ msgstr "Exécution du script Tcl ..." + +#~ msgid "Open cancelled." +#~ msgstr "Ouvert annulé." + +#~ msgid "Preferences default restore was cancelled." +#~ msgstr "La restauration par défaut des préférences a été annulée." + +#~ msgid "FlatCAM preferences import cancelled." +#~ msgstr "Importation des préférences FlatCAM annulée." + +#~ msgid "FlatCAM preferences export cancelled." +#~ msgstr "Exportation des préférences FlatCAM annulée." + +#~ msgid "Multigeo. Geometry merging finished" +#~ msgstr "Multigeo. Fusion de la géométrie terminée" + +#~ msgid "Units conversion cancelled." +#~ msgstr "La conversion des unités a été annulée." + +#~ msgid "Open Gerber cancelled." +#~ msgstr "Ouvert Gerber annulé." + +#~ msgid " Open Excellon cancelled." +#~ msgstr " Ouvert Excellon annulé." + +#~ msgid "Open G-Code cancelled." +#~ msgstr "Ouvert G-code annulé." + +#~ msgid "Open Project cancelled." +#~ msgstr "Projet ouvert annulé." + +#~ msgid "Open HPGL2 file cancelled." +#~ msgstr "Ouvrir HPGL2annulé." + +#~ msgid "Open Config cancelled." +#~ msgstr "Configuration ouverte annulée." + +#~ msgid " Export SVG cancelled." +#~ msgstr " Export SVG annulé." + +#~ msgid "Export PNG cancelled." +#~ msgstr "Exportation PNG annulée." + +#~ msgid "No object selected. Please select an Gerber object to export." +#~ msgstr "" +#~ "Aucun objet sélectionné. Veuillez sélectionner un objet Gerber à exporter." + +#~ msgid "Save Gerber source file cancelled." +#~ msgstr "Enregistrer le fichier source Gerber annulé." + +#~ msgid "No object selected. Please select an Script object to export." +#~ msgstr "" +#~ "Aucun objet sélectionné. Veuillez sélectionner un objet de script à " +#~ "exporter." + +#~ msgid "Save Script source file cancelled." +#~ msgstr "Enregistrer le fichier source du script annulé." + +#~ msgid "No object selected. Please select an Document object to export." +#~ msgstr "" +#~ "Aucun objet sélectionné. Veuillez sélectionner un objet Document à " +#~ "exporter." + +#~ msgid "Save Document source file cancelled." +#~ msgstr "Enregistrer le fichier source du document annulé." + +#~ msgid "No object selected. Please select an Excellon object to export." +#~ msgstr "" +#~ "Aucun objet sélectionné. Veuillez sélectionner un objet Excellon à " +#~ "exporter." + +#~ msgid "Saving Excellon source file cancelled." +#~ msgstr "Enregistrement du fichier source Excellon annulé." + +#~ msgid "No object selected. Please Select an Excellon object to export." +#~ msgstr "" +#~ "Aucun objet sélectionné. Veuillez sélectionner un objet Excellon à " +#~ "exporter." + +#~ msgid "Export Excellon cancelled." +#~ msgstr "Exporter Excellon annulé." + +#~ msgid "No object selected. Please Select an Gerber object to export." +#~ msgstr "" +#~ "Aucun objet sélectionné. Veuillez sélectionner un objet Gerber à exporter." + +#~ msgid "Export Gerber cancelled." +#~ msgstr "Export Gerber annulé." + +#~ msgid "Export DXF cancelled." +#~ msgstr "Exportation DXF annulée." + +#~ msgid "Open SVG cancelled." +#~ msgstr "Ouvrir SVG annulé." + +#~ msgid "Open DXF cancelled." +#~ msgstr "Ouvrir DXF annulé." + +#~ msgid "Open TCL script cancelled." +#~ msgstr "Ouvrir le script TCL annulé." + +#~ msgid "Run TCL script cancelled." +#~ msgstr "Exécuter le script TCL annulé." + +#~ msgid "Save Project cancelled." +#~ msgstr "Enregistrer le projet annulé." + +#~ msgid "Save Object PDF cancelled." +#~ msgstr "Enregistrer l'objet PDF annulé." + +#~ msgid "Shows list of commands." +#~ msgstr "Affiche la liste des commandes." + +#~ msgid "FlatCAM bookmarks export cancelled." +#~ msgstr "Exportation des favoris FlatCAM annulée." + +#~ msgid "FlatCAM bookmarks import cancelled." +#~ msgstr "Importation de favoris FlatCAM annulée." + +#~ msgid "FlatCAM Tools DB export cancelled." +#~ msgstr "Exportation de la base de données des outils FlatCAM annulée." + +#~ msgid "FlatCAM Tools DB import cancelled." +#~ msgstr "Importation de la BD des outils FlatCAM annulée." + +#~ msgid "" +#~ "Wrong value format for self.defaults[\"z_pdepth\"] or self." +#~ "options[\"z_pdepth\"]" +#~ msgstr "" +#~ "Format de valeur incorrect pour self.defaults [\"z_pdepth\"] ou self." +#~ "options [\"z_pdepth\"]" + +#~ msgid "" +#~ "Wrong value format for self.defaults[\"feedrate_probe\"] or self." +#~ "options[\"feedrate_probe\"]" +#~ msgstr "" +#~ "Format de valeur incorrect pour self.defaults [\"feedrate_probe\"] ou " +#~ "self.options [\"feedrate_probe\"]" + +#~ msgid "Starting G-Code..." +#~ msgstr "Démarrer G-Code ..." + +#~ msgid "" +#~ "Algorithm to paint the polygon:
Standard: Fixed step inwards." +#~ "
Seed-based: Outwards from seed." +#~ msgstr "" +#~ "Algorithme pour peindre le polygone:
Standard: pas fixe vers " +#~ "l’intérieur.
Basé sur les semences:vers l’extérieur depuis les " +#~ "semences." + +#~ msgid "Seed-based" +#~ msgstr "À base de semences" + +#~ msgid "Straight lines" +#~ msgstr "Lignes droites" + +#~ msgid "Paint cancelled. No shape selected." +#~ msgstr "Peinture annulée. Aucune forme sélectionnée." + +#~ msgid "Transformation cancelled. No shape selected." +#~ msgstr "Transformation annulée. Aucune forme sélectionnée." + +#~ msgid "Buffer cancelled. No shape selected." +#~ msgstr "Tampon annulé. Aucune forme sélectionnée." + +#~ msgid "Export Code cancelled." +#~ msgstr "Code d'exportation annulé." + +#~ msgid "&Save Project ..." +#~ msgstr "Sauvegarder le projet ..." + +#~ msgid "Save Project C&opy ..." +#~ msgstr "Enregistrer la copie du projet ..." + +#~ msgid "Change the size of the object." +#~ msgstr "Changer la taille de l'objet." + +#~ msgid "Change the position of this object." +#~ msgstr "Changer la position de cet objet." + +#~ msgid "Vector" +#~ msgstr "Vecteur" + +#~ msgid "" +#~ "Create a CNC Job object\n" +#~ "for this drill object." +#~ msgstr "" +#~ "Créer un objet de travail CNC\n" +#~ "pour cet objet de forage." + +#~ msgid "" +#~ "Choose what to use for GCode generation:\n" +#~ "'Drills', 'Slots' or 'Both'.\n" +#~ "When choosing 'Slots' or 'Both', slots will be\n" +#~ "converted to a series of drills." +#~ msgstr "" +#~ "Choisissez ce qu'il faut utiliser pour la génération de GCode:\n" +#~ "«Forages», «Fentes» ou «Les deux».\n" +#~ "Lorsque vous choisissez \"Fentes\" ou \"Les deux\", les slots seront\n" +#~ "converti en une série d'exercices." + +#~ msgid "Generate the CNC Job." +#~ msgstr "Générez le travail CNC." + +#~ msgid "Add Tool from DataBase" +#~ msgstr "Ajouter un outil à partir de la BD" + +#~ msgid "Select a theme for FlatCAM." +#~ msgstr "Sélectionnez un thème pour FlatCAM." + +#~ msgid "Conv." +#~ msgstr "Conv." + +#~ msgid "Diameters of the cutting tools, separated by ','" +#~ msgstr "Diamètres des outils de coupe, séparés par ','" + +#~ msgid "Tools dia" +#~ msgstr "Outils dia" + +#~ msgid "The new tool diameter (cut width) to add in the tool table." +#~ msgstr "" +#~ "Le nouveau diamètre d'outil (largeur de coupe) à ajouter dans la table " +#~ "d'outils." + +#~ msgid "" +#~ "Algorithm for non-copper clearing:
Standard: Fixed step inwards." +#~ "
Seed-based: Outwards from seed.
Line-based: Parallel " +#~ "lines." +#~ msgstr "" +#~ "Algorithme pour le clearing sans cuivre:
Standard: " +#~ "incrémentation fixe.
Basé sur les Semences : Sortant des " +#~ "semences
Basé sur les Lignes : lignes parallèles." + +#~ msgid "Area" +#~ msgstr "Zone" + +#~ msgid "Ref" +#~ msgstr "Réf" + +#~ msgid "" +#~ "- 'Itself' - the non copper clearing extent\n" +#~ "is based on the object that is copper cleared.\n" +#~ " - 'Area Selection' - left mouse click to start selection of the area to " +#~ "be painted.\n" +#~ "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple " +#~ "areas.\n" +#~ "- 'Reference Object' - will do non copper clearing within the area\n" +#~ "specified by another object." +#~ msgstr "" +#~ "- \"Lui-même\" - l'étendue du clearing non en cuivre\n" +#~ "est basé sur l'objet qui est en cuivre effacé.\n" +#~ "- 'Sélection de zone' - cliquez avec le bouton gauche de la souris pour " +#~ "lancer la sélection de la zone à peindre.\n" +#~ "En maintenant une touche de modification enfoncée (CTRL ou SHIFT), vous " +#~ "pourrez ajouter plusieurs zones.\n" +#~ "- 'Objet de référence' - effectuera un nettoyage sans cuivre dans la " +#~ "zone\n" +#~ "spécifié par un autre objet." + +#~ msgid "Sel" +#~ msgstr "Sél" + +#~ msgid "Diameters of nozzle tools, separated by ','" +#~ msgstr "Diamètres des outils de buse, séparés par ','" + +#~ msgid "Reference Gerber" +#~ msgstr "Référence Gerber" + +#~ msgid "Reference Excellon" +#~ msgstr "Référence Excellon" + +#~ msgid "Reference Geometry" +#~ msgstr "Géométrie de référence" + +#~ msgid "Point/Box Reference" +#~ msgstr "Référence de Point/Box" + +#~ msgid "" +#~ "If 'Point' is selected above it store the coordinates (x, y) through " +#~ "which\n" +#~ "the mirroring axis passes.\n" +#~ "If 'Box' is selected above, select here a FlatCAM object (Gerber, Exc or " +#~ "Geo).\n" +#~ "Through the center of this object pass the mirroring axis selected above." +#~ msgstr "" +#~ "Si 'Point' est sélectionné ci-dessus, il enregistre les coordonnées (x, " +#~ "y) par lesquelles\n" +#~ "l'axe de symétrie passe.\n" +#~ "Si 'Box' est sélectionné ci-dessus, sélectionnez ici un objet FlatCAM " +#~ "(Gerber, Exc ou Geo).\n" +#~ "Au centre de cet objet, passez l’axe en miroir sélectionné ci-dessus." + +#~ msgid "Alignment Drill Diameter" +#~ msgstr "Diamètre du foret d'alignement" + +#~ msgid "" +#~ "'Point' coordinates missing. Using Origin (0, 0) as mirroring reference." +#~ msgstr "" +#~ "Les coordonnées 'Point' sont manquantes. Utilisation de Origin (0, 0) " +#~ "comme référence en miroir." + +#~ msgid "Export positive film cancelled." +#~ msgstr "Exporter le film positif annulé." + +#~ msgid "Export negative film cancelled." +#~ msgstr "Exporter le film négatif annulé." + +#~ msgid "Move action cancelled." +#~ msgstr "Action de déplacement annulée." + +#~ msgid "Diameter for the new tool." +#~ msgstr "Diamètre pour le nouvel outil." + +#~ msgid "Create Paint Geometry" +#~ msgstr "Créer une Géométrie de Peinture" + +#~ msgid "Paint Tool. Reading parameters." +#~ msgstr "Outil de Peinture. Lecture des paramètres." + +#~ msgid "Paint Tool. Normal painting all task started." +#~ msgstr "Outil de Peinture. Peinture normale toutes les tâches ont commencé." + +#~ msgid "Rest machining painting all task started." +#~ msgstr "Reste l'usinage en peignant toutes les tâches commencées." + +#~ msgid "" +#~ "Could not do Paint All. Try a different combination of parameters. Or a " +#~ "different Method of paint" +#~ msgstr "" +#~ "Impossible de Tout Peindre. Essayez une combinaison de paramètres " +#~ "différente. Ou une autre méthode de peinture" + +#~ msgid "Rest machining painting area task started." +#~ msgstr "Reste l'usinage de peinture de la zone de travail a commencé." + +#~ msgid "Paint Tool. Rest machining painting area task started." +#~ msgstr "" +#~ "Outil de peinture. Reste l'usinage de la peinture de la zone: tâche " +#~ "commencée." + +#~ msgid "Properties Tool was not displayed. No object selected." +#~ msgstr "L'outil de Propriétés n'était pas affiché. Aucun objet sélectionné." + +#~ msgid " Export PNG cancelled." +#~ msgstr " Export PNG annulé." + +#~ msgid "Adding Nozzle tool cancelled. Tool already in Tool Table." +#~ msgstr "" +#~ "L'ajout de l'outil de buse est annulé. Outil déjà dans la table d'outils." + +#~ msgid "" +#~ "None of the following args: 'ref', 'all' were found or none was set to " +#~ "1.\n" +#~ "Copper clearing failed." +#~ msgstr "" +#~ "Aucun des arguments suivants: 'ref', 'all' ont été trouvés ou aucun n'a " +#~ "été défini sur 1.\n" +#~ "Le nettoyage du cuivre a échoué." + #~ msgid "PostProcessor" #~ msgstr "Post-processeur" @@ -16983,9 +18247,6 @@ msgstr "" #~ msgid "Optimization Time" #~ msgstr "Temps d'optimisation" -#~ msgid "Defaults" -#~ msgstr "Défauts" - #~ msgid "Coordinates decimals" #~ msgstr "Coord décimales" @@ -17054,9 +18315,6 @@ msgstr "" #~ msgid "Wk. size" #~ msgstr "Taille de ET" -#~ msgid "Plot Line" -#~ msgstr "Ligne de dessin" - #~ msgid "Sel. Fill" #~ msgstr "Remplissage sél" @@ -17093,12 +18351,6 @@ msgstr "" #~ msgid "Project at StartUp" #~ msgstr "Projet au démarrage" -#~ msgid "Project AutoHide" -#~ msgstr "Masquer auto le projet" - -#~ msgid "Enable ToolTips" -#~ msgstr "Activer les info-bulles" - #~ msgid "Mouse Cursor" #~ msgstr "Curseur de la souris" @@ -17122,9 +18374,6 @@ msgstr "" #~ msgid "G-code does not have a units code: either G20 or G21" #~ msgstr "G-code n'a pas de code d'unités: G20 ou G21" -#~ msgid "No shape selected. Select a shape to explode" -#~ msgstr "Aucune forme sélectionnée. Sélectionnez une forme à exploser" - #, python-brace-format #~ msgid "" #~ "[selected] {kind} created/selected: {name}" @@ -17419,9 +18668,6 @@ msgstr "" #~ "La valeur de chevauchement doit être comprise entre 0 (inclus) et 1 " #~ "(exclusif), " -#~ msgid "Single Polygon" -#~ msgstr "Polygone unique" - #~ msgid "Overlap value must be between 0 (inclusive) and 1 (exclusive)" #~ msgstr "" #~ "La valeur de chevauchement doit être comprise entre 0 (inclus) et 1 " @@ -17430,9 +18676,6 @@ msgstr "" #~ msgid "Click inside the desired polygon." #~ msgstr "Cliquez à l'intérieur du polygone souhaité." -#~ msgid "Painting polygon at location" -#~ msgstr "Peinture polygone à l'emplacement" - #, fuzzy #~| msgid "{l_save}/Project_{date}" #~ msgid "{l_save}/FlatCAM_Bookmarks_{date}" diff --git a/locale/ro/LC_MESSAGES/strings.mo b/locale/ro/LC_MESSAGES/strings.mo index 19ee1f95112dd078f71266fe810a6fe20644c61b..23055b9258b5f554c1d6dcbfc69a02479868b896 100644 GIT binary patch delta 37 rcmbO`Q+)1B@rD-07N#xCh5GEK3Wg?Drk3p$`piJgvb{o|Rdp@^=7kGx delta 37 rcmbO`Q+)1B@rD-07N#xCh5GC!3Py%jhQ{p``piJgvb{o|Rdp@^<+BT6 diff --git a/locale/ro/LC_MESSAGES/strings.po b/locale/ro/LC_MESSAGES/strings.po index 393d81cd..f22d6f98 100644 --- a/locale/ro/LC_MESSAGES/strings.po +++ b/locale/ro/LC_MESSAGES/strings.po @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2020-04-24 21:10+0300\n" -"PO-Revision-Date: 2020-04-24 21:13+0300\n" +"POT-Creation-Date: 2020-04-25 14:59+0300\n" +"PO-Revision-Date: 2020-04-25 14:59+0300\n" "Last-Translator: \n" "Language-Team: \n" "Language: ro\n" @@ -23,43 +23,43 @@ msgstr "" "X-Poedit-SearchPathExcluded-1: tests\n" "X-Poedit-SearchPathExcluded-2: doc\n" -#: FlatCAMApp.py:784 FlatCAMApp.py:816 FlatCAMCommon.py:1925 +#: FlatCAMApp.py:789 FlatCAMApp.py:821 FlatCAMCommon.py:1925 #: FlatCAMCommon.py:2040 flatcamEditors/FlatCAMGeoEditor.py:500 #: flatcamEditors/FlatCAMGeoEditor.py:570 #: flatcamEditors/FlatCAMGeoEditor.py:5152 flatcamGUI/PreferencesUI.py:5509 #: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 -#: flatcamTools/ToolNCC.py:2401 flatcamTools/ToolNCC.py:2429 -#: flatcamTools/ToolNCC.py:2699 flatcamTools/ToolNCC.py:2731 -#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:1836 +#: flatcamTools/ToolNCC.py:2396 flatcamTools/ToolNCC.py:2424 +#: flatcamTools/ToolNCC.py:2694 flatcamTools/ToolNCC.py:2726 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:1843 #: tclCommands/TclCommandCopperClear.py:128 #: tclCommands/TclCommandCopperClear.py:136 tclCommands/TclCommandPaint.py:127 msgid "Seed" msgstr "Punct_arbitrar" -#: FlatCAMApp.py:790 flatcamGUI/PreferencesUI.py:5588 +#: FlatCAMApp.py:795 flatcamGUI/PreferencesUI.py:5588 #: flatcamGUI/PreferencesUI.py:7695 flatcamTools/ToolCopperThieving.py:126 -#: flatcamTools/ToolNCC.py:535 flatcamTools/ToolNCC.py:1299 -#: flatcamTools/ToolNCC.py:1638 flatcamTools/ToolNCC.py:1919 -#: flatcamTools/ToolNCC.py:1983 flatcamTools/ToolNCC.py:2967 -#: flatcamTools/ToolNCC.py:2976 tclCommands/TclCommandCopperClear.py:190 +#: flatcamTools/ToolNCC.py:535 flatcamTools/ToolNCC.py:1301 +#: flatcamTools/ToolNCC.py:1629 flatcamTools/ToolNCC.py:1914 +#: flatcamTools/ToolNCC.py:1978 flatcamTools/ToolNCC.py:2962 +#: flatcamTools/ToolNCC.py:2971 tclCommands/TclCommandCopperClear.py:190 msgid "Itself" msgstr "Însuşi" -#: FlatCAMApp.py:817 flatcamGUI/PreferencesUI.py:6119 -#: flatcamTools/ToolPaint.py:486 flatcamTools/ToolPaint.py:1415 +#: FlatCAMApp.py:822 flatcamGUI/PreferencesUI.py:6119 +#: flatcamTools/ToolPaint.py:486 flatcamTools/ToolPaint.py:1422 #: tclCommands/TclCommandPaint.py:162 msgid "All Polygons" msgstr "Toate Poligoanele" -#: FlatCAMApp.py:1124 +#: FlatCAMApp.py:1129 msgid "FlatCAM is initializing ..." msgstr "FlatCAM se inițializează ..." -#: FlatCAMApp.py:1809 +#: FlatCAMApp.py:1814 msgid "Could not find the Language files. The App strings are missing." msgstr "Nu am gasit fişierele cu traduceri. Mesajele aplicaţiei lipsesc." -#: FlatCAMApp.py:1903 +#: FlatCAMApp.py:1908 msgid "" "FlatCAM is initializing ...\n" "Canvas initialization started." @@ -67,7 +67,7 @@ msgstr "" "FlatCAM se inițializează ...\n" "Initializarea spațiului de afisare a inceput." -#: FlatCAMApp.py:1923 +#: FlatCAMApp.py:1928 msgid "" "FlatCAM is initializing ...\n" "Canvas initialization started.\n" @@ -77,29 +77,29 @@ msgstr "" "Initializarea spațiului de afisare a inceput.\n" "Initializarea spatiului de afisare s-a terminat in" -#: FlatCAMApp.py:2565 flatcamGUI/GUIElements.py:2592 +#: FlatCAMApp.py:2570 flatcamGUI/GUIElements.py:2592 msgid "Type >help< to get started" msgstr "Tastați >help< pentru a începe" -#: FlatCAMApp.py:2817 FlatCAMApp.py:9393 +#: FlatCAMApp.py:2822 FlatCAMApp.py:9400 msgid "New Project - Not saved" msgstr "Proiect nou - Nu a fost salvat" -#: FlatCAMApp.py:2913 +#: FlatCAMApp.py:2918 msgid "" "Found old default preferences files. Please reboot the application to update." msgstr "" "Au fost găsite fișiere de preferințe implicite vechi. Vă rugăm să reporniți " "aplicația pentru a le actualiza." -#: FlatCAMApp.py:2964 FlatCAMApp.py:3884 FlatCAMApp.py:3933 FlatCAMApp.py:3988 -#: FlatCAMApp.py:4063 FlatCAMApp.py:6111 FlatCAMApp.py:9477 FlatCAMApp.py:9514 -#: FlatCAMApp.py:9556 FlatCAMApp.py:9585 FlatCAMApp.py:9625 FlatCAMApp.py:9650 -#: FlatCAMApp.py:9702 FlatCAMApp.py:9738 FlatCAMApp.py:9784 FlatCAMApp.py:9825 -#: FlatCAMApp.py:9866 FlatCAMApp.py:9907 FlatCAMApp.py:9948 FlatCAMApp.py:9992 -#: FlatCAMApp.py:10048 FlatCAMApp.py:10080 FlatCAMApp.py:10112 -#: FlatCAMApp.py:10349 FlatCAMApp.py:10393 FlatCAMApp.py:10470 -#: FlatCAMApp.py:10525 FlatCAMCommon.py:371 FlatCAMCommon.py:413 +#: FlatCAMApp.py:2969 FlatCAMApp.py:3889 FlatCAMApp.py:3938 FlatCAMApp.py:3993 +#: FlatCAMApp.py:4068 FlatCAMApp.py:6117 FlatCAMApp.py:9484 FlatCAMApp.py:9521 +#: FlatCAMApp.py:9563 FlatCAMApp.py:9592 FlatCAMApp.py:9632 FlatCAMApp.py:9657 +#: FlatCAMApp.py:9709 FlatCAMApp.py:9745 FlatCAMApp.py:9791 FlatCAMApp.py:9832 +#: FlatCAMApp.py:9873 FlatCAMApp.py:9914 FlatCAMApp.py:9955 FlatCAMApp.py:9999 +#: FlatCAMApp.py:10055 FlatCAMApp.py:10087 FlatCAMApp.py:10119 +#: FlatCAMApp.py:10356 FlatCAMApp.py:10400 FlatCAMApp.py:10477 +#: FlatCAMApp.py:10532 FlatCAMCommon.py:371 FlatCAMCommon.py:413 #: FlatCAMCommon.py:1107 FlatCAMCommon.py:1153 FlatCAMCommon.py:2537 #: FlatCAMCommon.py:2583 ObjectCollection.py:122 #: flatcamEditors/FlatCAMExcEditor.py:1024 @@ -113,31 +113,31 @@ msgstr "" msgid "Cancelled." msgstr "Anulat." -#: FlatCAMApp.py:2980 +#: FlatCAMApp.py:2985 msgid "Open Config file failed." msgstr "Deschiderea fişierului de configurare a eşuat." -#: FlatCAMApp.py:2995 +#: FlatCAMApp.py:3000 msgid "Open Script file failed." msgstr "Deschiderea fişierului Script eşuat." -#: FlatCAMApp.py:3021 +#: FlatCAMApp.py:3026 msgid "Open Excellon file failed." msgstr "Deschiderea fişierului Excellon a eşuat." -#: FlatCAMApp.py:3034 +#: FlatCAMApp.py:3039 msgid "Open GCode file failed." msgstr "Deschiderea fişierului GCode a eşuat." -#: FlatCAMApp.py:3047 +#: FlatCAMApp.py:3052 msgid "Open Gerber file failed." msgstr "Deschiderea fişierului Gerber a eşuat." -#: FlatCAMApp.py:3424 +#: FlatCAMApp.py:3429 msgid "Select a Geometry, Gerber or Excellon Object to edit." msgstr "Selectează un obiect tip Geometrie Gerber sau Excellon pentru editare." -#: FlatCAMApp.py:3439 +#: FlatCAMApp.py:3444 msgid "" "Simultaneous editing of tools geometry in a MultiGeo Geometry is not " "possible.\n" @@ -147,94 +147,94 @@ msgstr "" "MultiGeo nu este posibilă.\n" "Se poate edita numai o singură geometrie de fiecare dată." -#: FlatCAMApp.py:3497 +#: FlatCAMApp.py:3502 msgid "Editor is activated ..." msgstr "Editorul este activ ..." -#: FlatCAMApp.py:3518 +#: FlatCAMApp.py:3523 msgid "Do you want to save the edited object?" msgstr "Vrei sa salvezi obiectul editat?" -#: FlatCAMApp.py:3519 flatcamGUI/FlatCAMGUI.py:2273 +#: FlatCAMApp.py:3524 flatcamGUI/FlatCAMGUI.py:2273 msgid "Close Editor" msgstr "Inchide Editorul" -#: FlatCAMApp.py:3522 FlatCAMApp.py:5163 FlatCAMApp.py:8023 FlatCAMApp.py:8049 -#: FlatCAMApp.py:9298 FlatCAMTranslation.py:108 FlatCAMTranslation.py:199 +#: FlatCAMApp.py:3527 FlatCAMApp.py:5169 FlatCAMApp.py:8030 FlatCAMApp.py:8056 +#: FlatCAMApp.py:9305 FlatCAMTranslation.py:108 FlatCAMTranslation.py:199 #: flatcamGUI/FlatCAMGUI.py:2479 msgid "Yes" msgstr "Da" -#: FlatCAMApp.py:3523 FlatCAMApp.py:5164 FlatCAMApp.py:8024 FlatCAMApp.py:8050 -#: FlatCAMApp.py:9299 FlatCAMTranslation.py:109 FlatCAMTranslation.py:200 +#: FlatCAMApp.py:3528 FlatCAMApp.py:5170 FlatCAMApp.py:8031 FlatCAMApp.py:8057 +#: FlatCAMApp.py:9306 FlatCAMTranslation.py:109 FlatCAMTranslation.py:200 #: flatcamGUI/FlatCAMGUI.py:2480 flatcamGUI/PreferencesUI.py:5443 #: flatcamGUI/PreferencesUI.py:5989 flatcamTools/ToolNCC.py:182 #: flatcamTools/ToolPaint.py:166 msgid "No" msgstr "Nu" -#: FlatCAMApp.py:3524 FlatCAMApp.py:5165 FlatCAMApp.py:6049 FlatCAMApp.py:7000 -#: FlatCAMApp.py:9300 FlatCAMCommon.py:572 FlatCAMCommon.py:2127 +#: FlatCAMApp.py:3529 FlatCAMApp.py:5171 FlatCAMApp.py:6055 FlatCAMApp.py:7006 +#: FlatCAMApp.py:9307 FlatCAMCommon.py:572 FlatCAMCommon.py:2127 #: flatcamGUI/FlatCAMGUI.py:1332 msgid "Cancel" msgstr "Anuleaza" -#: FlatCAMApp.py:3556 +#: FlatCAMApp.py:3561 msgid "Object empty after edit." msgstr "Obiectul nu are date dupa editare." -#: FlatCAMApp.py:3560 FlatCAMApp.py:3581 FlatCAMApp.py:3603 +#: FlatCAMApp.py:3565 FlatCAMApp.py:3586 FlatCAMApp.py:3608 msgid "Editor exited. Editor content saved." msgstr "Ieşire din Editor. Continuțul editorului este salvat." -#: FlatCAMApp.py:3607 FlatCAMApp.py:3630 FlatCAMApp.py:3648 +#: FlatCAMApp.py:3612 FlatCAMApp.py:3635 FlatCAMApp.py:3653 msgid "Select a Gerber, Geometry or Excellon Object to update." msgstr "" "Selectează un obiect tip Gerber, Geometrie sau Excellon pentru actualizare." -#: FlatCAMApp.py:3610 +#: FlatCAMApp.py:3615 msgid "is updated, returning to App..." msgstr "este actualizat, întoarcere la aplicaţie..." -#: FlatCAMApp.py:3617 +#: FlatCAMApp.py:3622 msgid "Editor exited. Editor content was not saved." msgstr "Ieşire din Editor. Continuțul editorului nu a fost salvat." -#: FlatCAMApp.py:3810 FlatCAMApp.py:3941 FlatCAMApp.py:5012 +#: FlatCAMApp.py:3815 FlatCAMApp.py:3946 FlatCAMApp.py:5018 msgid "Could not load defaults file." msgstr "Nu am putut incărca fişierul cu valori default." -#: FlatCAMApp.py:3822 FlatCAMApp.py:3949 FlatCAMApp.py:5021 +#: FlatCAMApp.py:3827 FlatCAMApp.py:3954 FlatCAMApp.py:5027 msgid "Failed to parse defaults file." msgstr "Parsarea fişierului cu valori default a eșuat." -#: FlatCAMApp.py:3892 FlatCAMApp.py:5113 +#: FlatCAMApp.py:3897 FlatCAMApp.py:5119 msgid "Could not load factory defaults file." msgstr "" "Fişierul cu valori default de fabrică nu a fost posibil să fie deschis." -#: FlatCAMApp.py:3900 FlatCAMApp.py:5123 +#: FlatCAMApp.py:3905 FlatCAMApp.py:5129 msgid "Failed to parse factory defaults file." msgstr "Parsarea fişierului cu valori default de fabrică a eșuat." -#: FlatCAMApp.py:3908 +#: FlatCAMApp.py:3913 msgid "Preferences default values are restored." msgstr "Valorile implicite pt preferințe sunt restabilite." -#: FlatCAMApp.py:3923 FlatCAMApp.py:3927 +#: FlatCAMApp.py:3928 FlatCAMApp.py:3932 msgid "Import FlatCAM Preferences" msgstr "Importă Preferințele FlatCAM" -#: FlatCAMApp.py:3957 +#: FlatCAMApp.py:3962 msgid "Imported Defaults from" msgstr "Valorile default au fost importate din" -#: FlatCAMApp.py:3977 FlatCAMApp.py:3982 +#: FlatCAMApp.py:3982 FlatCAMApp.py:3987 msgid "Export FlatCAM Preferences" msgstr "Exportă Preferințele FlatCAM" -#: FlatCAMApp.py:3997 FlatCAMApp.py:4071 FlatCAMApp.py:10769 -#: FlatCAMApp.py:10817 FlatCAMApp.py:10943 FlatCAMApp.py:11080 +#: FlatCAMApp.py:4002 FlatCAMApp.py:4076 FlatCAMApp.py:10776 +#: FlatCAMApp.py:10824 FlatCAMApp.py:10950 FlatCAMApp.py:11087 #: FlatCAMCommon.py:379 FlatCAMCommon.py:1115 FlatCAMCommon.py:2545 #: FlatCAMObj.py:7484 flatcamEditors/FlatCAMTextEditor.py:276 #: flatcamTools/ToolFilm.py:1031 flatcamTools/ToolFilm.py:1212 @@ -246,48 +246,48 @@ msgstr "" "Permisiune refuzată, salvarea nu este posibilă.\n" "Cel mai probabil o altă aplicație ține fișierul deschis și inaccesibil." -#: FlatCAMApp.py:4009 +#: FlatCAMApp.py:4014 msgid "Could not load preferences file." msgstr "Nu am putut incărca fişierul cu valori default." -#: FlatCAMApp.py:4028 FlatCAMApp.py:4095 FlatCAMApp.py:5040 +#: FlatCAMApp.py:4033 FlatCAMApp.py:4100 FlatCAMApp.py:5046 msgid "Failed to write defaults to file." msgstr "Salvarea valorilor default intr-un fişier a eșuat." -#: FlatCAMApp.py:4033 +#: FlatCAMApp.py:4038 msgid "Exported preferences to" msgstr "Exportă Preferințele in" -#: FlatCAMApp.py:4053 FlatCAMApp.py:4058 +#: FlatCAMApp.py:4058 FlatCAMApp.py:4063 msgid "Save to file" msgstr "Salvat in" -#: FlatCAMApp.py:4082 +#: FlatCAMApp.py:4087 msgid "Could not load the file." msgstr "Nu am putut incărca fişierul." -#: FlatCAMApp.py:4098 +#: FlatCAMApp.py:4103 msgid "Exported file to" msgstr "S-a exportat fişierul in" -#: FlatCAMApp.py:4181 +#: FlatCAMApp.py:4186 msgid "Failed to open recent files file for writing." msgstr "" "Deschiderea fişierului cu >fişiere recente< pentru a fi salvat a eșuat." -#: FlatCAMApp.py:4192 +#: FlatCAMApp.py:4197 msgid "Failed to open recent projects file for writing." msgstr "" "Deschiderea fişierului cu >proiecte recente< pentru a fi salvat a eșuat." -#: FlatCAMApp.py:4277 FlatCAMApp.py:11276 FlatCAMApp.py:11335 -#: FlatCAMApp.py:11463 FlatCAMApp.py:12189 FlatCAMObj.py:5605 +#: FlatCAMApp.py:4282 FlatCAMApp.py:11283 FlatCAMApp.py:11342 +#: FlatCAMApp.py:11470 FlatCAMApp.py:12196 FlatCAMObj.py:5605 #: flatcamEditors/FlatCAMGrbEditor.py:4231 flatcamTools/ToolPcbWizard.py:433 msgid "An internal error has occurred. See shell.\n" msgstr "" "A apărut o eroare internă. Verifică in TCL Shell pt mai multe detalii.\n" -#: FlatCAMApp.py:4278 +#: FlatCAMApp.py:4283 #, python-brace-format msgid "" "Object ({kind}) failed because: {error} \n" @@ -296,63 +296,63 @@ msgstr "" "Obiectul ({kind}) a eșuat din cauza: {error} \n" "\n" -#: FlatCAMApp.py:4293 +#: FlatCAMApp.py:4298 msgid "Converting units to " msgstr "Se convertesc unitătile la " -#: FlatCAMApp.py:4406 +#: FlatCAMApp.py:4411 msgid "CREATE A NEW FLATCAM TCL SCRIPT" msgstr "CREAȚI UN SCRIPT FLATCAM TCL NOU" -#: FlatCAMApp.py:4407 +#: FlatCAMApp.py:4412 msgid "TCL Tutorial is here" msgstr "Tutorialul TCL este aici" -#: FlatCAMApp.py:4409 +#: FlatCAMApp.py:4414 msgid "FlatCAM commands list" msgstr "Lista de comenzi FlatCAM" -#: FlatCAMApp.py:4460 FlatCAMApp.py:4466 FlatCAMApp.py:4472 FlatCAMApp.py:4478 -#: FlatCAMApp.py:4484 FlatCAMApp.py:4490 +#: FlatCAMApp.py:4465 FlatCAMApp.py:4471 FlatCAMApp.py:4477 FlatCAMApp.py:4483 +#: FlatCAMApp.py:4489 FlatCAMApp.py:4495 msgid "created/selected" msgstr "creat / selectat" -#: FlatCAMApp.py:4505 FlatCAMApp.py:7086 FlatCAMObj.py:278 FlatCAMObj.py:309 +#: FlatCAMApp.py:4510 FlatCAMApp.py:7092 FlatCAMObj.py:278 FlatCAMObj.py:309 #: FlatCAMObj.py:325 FlatCAMObj.py:405 flatcamTools/ToolCopperThieving.py:1482 #: flatcamTools/ToolFiducials.py:809 flatcamTools/ToolMove.py:230 #: flatcamTools/ToolQRCode.py:728 msgid "Plotting" msgstr "Se afișeaz" -#: FlatCAMApp.py:4568 flatcamGUI/FlatCAMGUI.py:530 +#: FlatCAMApp.py:4573 flatcamGUI/FlatCAMGUI.py:530 msgid "About FlatCAM" msgstr "Despre FlatCAM" -#: FlatCAMApp.py:4594 +#: FlatCAMApp.py:4599 msgid "2D Computer-Aided Printed Circuit Board Manufacturing" msgstr "Productie Cablaje Imprimate asistate 2D de PC" -#: FlatCAMApp.py:4595 +#: FlatCAMApp.py:4600 msgid "Development" msgstr "Dezvoltare" -#: FlatCAMApp.py:4596 +#: FlatCAMApp.py:4601 msgid "DOWNLOAD" msgstr "DOWNLOAD" -#: FlatCAMApp.py:4597 +#: FlatCAMApp.py:4602 msgid "Issue tracker" msgstr "Raportare probleme" -#: FlatCAMApp.py:4601 FlatCAMApp.py:4942 flatcamGUI/GUIElements.py:2583 +#: FlatCAMApp.py:4606 FlatCAMApp.py:4948 flatcamGUI/GUIElements.py:2583 msgid "Close" msgstr "Închide" -#: FlatCAMApp.py:4616 +#: FlatCAMApp.py:4621 msgid "Licensed under the MIT license" msgstr "Licențiat sub licența MIT" -#: FlatCAMApp.py:4625 +#: FlatCAMApp.py:4630 msgid "" "Permission is hereby granted, free of charge, to any person obtaining a " "copy\n" @@ -405,7 +405,7 @@ msgstr "" "UTILIZAREA SA,\n" "SAU ORICE TRATĂRI ÎN ACEST SOFTWARE." -#: FlatCAMApp.py:4647 +#: FlatCAMApp.py:4652 msgid "" "Some of the icons used are from the following sources:
Icons by FreepikIcons8Pictograme create de oNline Web Fonts" -#: FlatCAMApp.py:4679 +#: FlatCAMApp.py:4685 msgid "Splash" msgstr "Splash" -#: FlatCAMApp.py:4685 +#: FlatCAMApp.py:4691 msgid "Programmers" msgstr "Programatori" -#: FlatCAMApp.py:4691 +#: FlatCAMApp.py:4697 msgid "Translators" msgstr "Traducatori" -#: FlatCAMApp.py:4697 +#: FlatCAMApp.py:4703 msgid "License" msgstr "Licență" -#: FlatCAMApp.py:4703 +#: FlatCAMApp.py:4709 msgid "Attributions" msgstr "Atribuiri" -#: FlatCAMApp.py:4726 +#: FlatCAMApp.py:4732 msgid "Programmer" msgstr "Programator" -#: FlatCAMApp.py:4727 +#: FlatCAMApp.py:4733 msgid "Status" msgstr "Statut" -#: FlatCAMApp.py:4728 FlatCAMApp.py:4806 +#: FlatCAMApp.py:4734 FlatCAMApp.py:4812 msgid "E-mail" msgstr "E-mail" -#: FlatCAMApp.py:4736 +#: FlatCAMApp.py:4742 msgid "BETA Maintainer >= 2019" msgstr "Programator Beta >= 2019" -#: FlatCAMApp.py:4803 +#: FlatCAMApp.py:4809 msgid "Language" msgstr "Limba" -#: FlatCAMApp.py:4804 +#: FlatCAMApp.py:4810 msgid "Translator" msgstr "Traducător" -#: FlatCAMApp.py:4805 +#: FlatCAMApp.py:4811 msgid "Corrections" msgstr "Corecţii" -#: FlatCAMApp.py:4914 FlatCAMApp.py:4922 FlatCAMApp.py:8068 +#: FlatCAMApp.py:4920 FlatCAMApp.py:4928 FlatCAMApp.py:8075 #: flatcamGUI/FlatCAMGUI.py:512 msgid "Bookmarks Manager" msgstr "Bookmarks Manager" -#: FlatCAMApp.py:4933 +#: FlatCAMApp.py:4939 msgid "" "This entry will resolve to another website if:\n" "\n" @@ -495,28 +495,28 @@ msgstr "" "Dacă nu puteți obține informații despre FlatCAM beta\n" "utilizați linkul canalului YouTube din meniul Ajutor." -#: FlatCAMApp.py:4940 +#: FlatCAMApp.py:4946 msgid "Alternative website" msgstr "Site alternativ" -#: FlatCAMApp.py:5044 FlatCAMApp.py:8032 +#: FlatCAMApp.py:5050 FlatCAMApp.py:8039 msgid "Preferences saved." msgstr "Preferințele au fost salvate." -#: FlatCAMApp.py:5139 +#: FlatCAMApp.py:5145 msgid "Failed to write factory defaults to file." msgstr "" "Salvarea fişierului cu valori default de fabrică intr-un fişier a eșuat." -#: FlatCAMApp.py:5143 +#: FlatCAMApp.py:5149 msgid "Factory defaults saved." msgstr "Valori default de fabrică au fost salvate." -#: FlatCAMApp.py:5153 flatcamGUI/FlatCAMGUI.py:4178 +#: FlatCAMApp.py:5159 flatcamGUI/FlatCAMGUI.py:4178 msgid "Application is saving the project. Please wait ..." msgstr "Aplicația salvează proiectul. Vă rugăm aşteptați ..." -#: FlatCAMApp.py:5158 FlatCAMTranslation.py:194 +#: FlatCAMApp.py:5164 FlatCAMTranslation.py:194 msgid "" "There are files/objects modified in FlatCAM. \n" "Do you want to Save the project?" @@ -524,29 +524,29 @@ msgstr "" "FlatCAM are fişiere/obiecte care au fost modificate. \n" "Dorești să Salvezi proiectul?" -#: FlatCAMApp.py:5161 FlatCAMApp.py:9296 FlatCAMTranslation.py:197 +#: FlatCAMApp.py:5167 FlatCAMApp.py:9303 FlatCAMTranslation.py:197 msgid "Save changes" msgstr "Salvează modificarile" -#: FlatCAMApp.py:5417 +#: FlatCAMApp.py:5423 msgid "Selected Excellon file extensions registered with FlatCAM." msgstr "Extensiile de fișiere Excellon selectate înregistrate cu FlatCAM." -#: FlatCAMApp.py:5439 +#: FlatCAMApp.py:5445 msgid "Selected GCode file extensions registered with FlatCAM." msgstr "Extensii de fișiere GCode selectate înregistrate cu FlatCAM." -#: FlatCAMApp.py:5461 +#: FlatCAMApp.py:5467 msgid "Selected Gerber file extensions registered with FlatCAM." msgstr "Extensii de fișiere Gerber selectate înregistrate cu FlatCAM." -#: FlatCAMApp.py:5649 FlatCAMApp.py:5708 FlatCAMApp.py:5736 +#: FlatCAMApp.py:5655 FlatCAMApp.py:5714 FlatCAMApp.py:5742 msgid "At least two objects are required for join. Objects currently selected" msgstr "" "Cel puțin două obiecte sunt necesare pentru a fi unite. Obiectele selectate " "în prezent" -#: FlatCAMApp.py:5658 +#: FlatCAMApp.py:5664 msgid "" "Failed join. The Geometry objects are of different types.\n" "At least one is MultiGeo type and the other is SingleGeo type. A possibility " @@ -563,48 +563,48 @@ msgstr "" "informatii și rezultatul ar putea să nu fie cel dorit. \n" "Verifică codul G-Code generat." -#: FlatCAMApp.py:5670 FlatCAMApp.py:5680 +#: FlatCAMApp.py:5676 FlatCAMApp.py:5686 msgid "Geometry merging finished" msgstr "Fuziunea geometriei s-a terminat" -#: FlatCAMApp.py:5703 +#: FlatCAMApp.py:5709 msgid "Failed. Excellon joining works only on Excellon objects." msgstr "" "Eșuat. Fuzionarea Excellon functionează doar cu obiecte de tip Excellon." -#: FlatCAMApp.py:5713 +#: FlatCAMApp.py:5719 msgid "Excellon merging finished" msgstr "Fuziunea Excellon a fost terminată" -#: FlatCAMApp.py:5731 +#: FlatCAMApp.py:5737 msgid "Failed. Gerber joining works only on Gerber objects." msgstr "Eșuat. Fuzionarea Gerber functionează doar cu obiecte de tip Gerber ." -#: FlatCAMApp.py:5741 +#: FlatCAMApp.py:5747 msgid "Gerber merging finished" msgstr "Fuziunea Gerber a fost terminată" -#: FlatCAMApp.py:5761 FlatCAMApp.py:5796 +#: FlatCAMApp.py:5767 FlatCAMApp.py:5802 msgid "Failed. Select a Geometry Object and try again." msgstr "Eșuat. Selectează un obiect Geometrie și încearcă din nou." -#: FlatCAMApp.py:5765 FlatCAMApp.py:5801 +#: FlatCAMApp.py:5771 FlatCAMApp.py:5807 msgid "Expected a FlatCAMGeometry, got" msgstr "Se astepta o Geometrie FlatCAM, s-a primit" -#: FlatCAMApp.py:5778 +#: FlatCAMApp.py:5784 msgid "A Geometry object was converted to MultiGeo type." msgstr "Un obiect Geometrie a fost convertit la tipul MultiGeo." -#: FlatCAMApp.py:5816 +#: FlatCAMApp.py:5822 msgid "A Geometry object was converted to SingleGeo type." msgstr "Un obiect Geometrie a fost convertit la tipul SingleGeo ." -#: FlatCAMApp.py:6043 +#: FlatCAMApp.py:6049 msgid "Toggle Units" msgstr "Comută Unitati" -#: FlatCAMApp.py:6045 +#: FlatCAMApp.py:6051 msgid "" "Changing the units of the project\n" "will scale all objects.\n" @@ -616,45 +616,45 @@ msgstr "" "\n" "Doriți să continuați?" -#: FlatCAMApp.py:6048 FlatCAMApp.py:6922 FlatCAMApp.py:6999 FlatCAMApp.py:9669 -#: FlatCAMApp.py:9683 FlatCAMApp.py:10018 FlatCAMApp.py:10028 +#: FlatCAMApp.py:6054 FlatCAMApp.py:6928 FlatCAMApp.py:7005 FlatCAMApp.py:9676 +#: FlatCAMApp.py:9690 FlatCAMApp.py:10025 FlatCAMApp.py:10035 msgid "Ok" msgstr "Ok" -#: FlatCAMApp.py:6097 +#: FlatCAMApp.py:6103 msgid "Converted units to" msgstr "Unitătile au fost convertite in" -#: FlatCAMApp.py:6737 +#: FlatCAMApp.py:6743 msgid "Detachable Tabs" msgstr "Taburi detașabile" -#: FlatCAMApp.py:6811 FlatCAMApp.py:6855 FlatCAMApp.py:6883 FlatCAMApp.py:7815 -#: FlatCAMApp.py:7883 FlatCAMApp.py:7987 +#: FlatCAMApp.py:6817 FlatCAMApp.py:6861 FlatCAMApp.py:6889 FlatCAMApp.py:7822 +#: FlatCAMApp.py:7890 FlatCAMApp.py:7994 msgid "Preferences" msgstr "Preferințe" -#: FlatCAMApp.py:6817 +#: FlatCAMApp.py:6823 msgid "Preferences applied." msgstr "Preferințele au fost aplicate." -#: FlatCAMApp.py:6888 +#: FlatCAMApp.py:6894 msgid "Preferences closed without saving." msgstr "Tab-ul Preferințe a fost închis fără a salva." -#: FlatCAMApp.py:6911 flatcamTools/ToolNCC.py:930 flatcamTools/ToolNCC.py:1435 -#: flatcamTools/ToolPaint.py:855 flatcamTools/ToolSolderPaste.py:568 +#: FlatCAMApp.py:6917 flatcamTools/ToolNCC.py:932 flatcamTools/ToolNCC.py:1426 +#: flatcamTools/ToolPaint.py:858 flatcamTools/ToolSolderPaste.py:568 #: flatcamTools/ToolSolderPaste.py:893 msgid "Please enter a tool diameter with non-zero value, in Float format." msgstr "" "Introduceti un diametru al uneltei valid: valoare ne-nula in format Real." -#: FlatCAMApp.py:6915 flatcamTools/ToolNCC.py:934 flatcamTools/ToolPaint.py:859 +#: FlatCAMApp.py:6921 flatcamTools/ToolNCC.py:936 flatcamTools/ToolPaint.py:862 #: flatcamTools/ToolSolderPaste.py:572 msgid "Adding Tool cancelled" msgstr "Adăugarea unei unelte anulată" -#: FlatCAMApp.py:6918 +#: FlatCAMApp.py:6924 msgid "" "Adding Tool works only when Advanced is checked.\n" "Go to Preferences -> General - Show Advanced Options." @@ -662,11 +662,11 @@ msgstr "" "Adăugarea de unelte noi functionează doar in modul Avansat.\n" "Pentru aceasta mergi in Preferințe -> General - Activează Modul Avansat." -#: FlatCAMApp.py:6994 +#: FlatCAMApp.py:7000 msgid "Delete objects" msgstr "Șterge obiectele" -#: FlatCAMApp.py:6997 +#: FlatCAMApp.py:7003 msgid "" "Are you sure you want to permanently delete\n" "the selected objects?" @@ -674,55 +674,55 @@ msgstr "" "Sigur doriți să ștergeți definitiv\n" "obiectele selectate?" -#: FlatCAMApp.py:7035 +#: FlatCAMApp.py:7041 msgid "Object(s) deleted" msgstr "Obiect(ele) șters(e)" -#: FlatCAMApp.py:7039 FlatCAMApp.py:7194 flatcamTools/ToolDblSided.py:819 +#: FlatCAMApp.py:7045 FlatCAMApp.py:7200 flatcamTools/ToolDblSided.py:819 msgid "Failed. No object(s) selected..." msgstr "Eșuat. Nici-un obiect nu este selectat." -#: FlatCAMApp.py:7041 +#: FlatCAMApp.py:7047 msgid "Save the work in Editor and try again ..." msgstr "Salvează continutul din Editor și încearcă din nou." -#: FlatCAMApp.py:7070 +#: FlatCAMApp.py:7076 msgid "Object deleted" msgstr "Obiectul este șters" -#: FlatCAMApp.py:7097 +#: FlatCAMApp.py:7103 msgid "Click to set the origin ..." msgstr "Click pentru a seta originea..." -#: FlatCAMApp.py:7119 +#: FlatCAMApp.py:7125 msgid "Setting Origin..." msgstr "Setează Originea..." -#: FlatCAMApp.py:7132 FlatCAMApp.py:7234 +#: FlatCAMApp.py:7138 FlatCAMApp.py:7240 msgid "Origin set" msgstr "Originea a fost setată" -#: FlatCAMApp.py:7149 +#: FlatCAMApp.py:7155 msgid "Origin coordinates specified but incomplete." msgstr "Coordonate pentru origine specificate, dar incomplete." -#: FlatCAMApp.py:7190 +#: FlatCAMApp.py:7196 msgid "Moving to Origin..." msgstr "Deplasare către Origine..." -#: FlatCAMApp.py:7271 +#: FlatCAMApp.py:7277 msgid "Jump to ..." msgstr "Sari la ..." -#: FlatCAMApp.py:7272 +#: FlatCAMApp.py:7278 msgid "Enter the coordinates in format X,Y:" msgstr "Introduceți coordonatele in format X,Y:" -#: FlatCAMApp.py:7282 +#: FlatCAMApp.py:7288 msgid "Wrong coordinates. Enter coordinates in format: X,Y" msgstr "Coordonate gresite. Introduceți coordonatele in format X,Y" -#: FlatCAMApp.py:7360 FlatCAMApp.py:7509 +#: FlatCAMApp.py:7366 FlatCAMApp.py:7515 #: flatcamEditors/FlatCAMExcEditor.py:3622 #: flatcamEditors/FlatCAMExcEditor.py:3630 #: flatcamEditors/FlatCAMGeoEditor.py:4349 @@ -738,80 +738,80 @@ msgstr "Coordonate gresite. Introduceți coordonatele in format X,Y" msgid "Done." msgstr "Executat." -#: FlatCAMApp.py:7375 FlatCAMApp.py:9665 FlatCAMApp.py:9761 FlatCAMApp.py:9803 -#: FlatCAMApp.py:9844 FlatCAMApp.py:9885 FlatCAMApp.py:9926 FlatCAMApp.py:9970 -#: FlatCAMApp.py:10014 FlatCAMApp.py:10503 FlatCAMApp.py:10507 +#: FlatCAMApp.py:7381 FlatCAMApp.py:9672 FlatCAMApp.py:9768 FlatCAMApp.py:9810 +#: FlatCAMApp.py:9851 FlatCAMApp.py:9892 FlatCAMApp.py:9933 FlatCAMApp.py:9977 +#: FlatCAMApp.py:10021 FlatCAMApp.py:10510 FlatCAMApp.py:10514 #: flatcamTools/ToolProperties.py:116 msgid "No object selected." msgstr "Nici-un obiect nu este selectat." -#: FlatCAMApp.py:7394 +#: FlatCAMApp.py:7400 msgid "Bottom-Left" msgstr "Stânga jos" -#: FlatCAMApp.py:7395 flatcamGUI/PreferencesUI.py:8111 +#: FlatCAMApp.py:7401 flatcamGUI/PreferencesUI.py:8111 #: flatcamTools/ToolCalibration.py:159 msgid "Top-Left" msgstr "Stânga-sus" -#: FlatCAMApp.py:7396 flatcamGUI/PreferencesUI.py:8112 +#: FlatCAMApp.py:7402 flatcamGUI/PreferencesUI.py:8112 #: flatcamTools/ToolCalibration.py:160 msgid "Bottom-Right" msgstr "Dreapta-jos" -#: FlatCAMApp.py:7397 +#: FlatCAMApp.py:7403 msgid "Top-Right" msgstr "Dreapta-sus" -#: FlatCAMApp.py:7398 flatcamGUI/ObjectUI.py:2624 +#: FlatCAMApp.py:7404 flatcamGUI/ObjectUI.py:2624 msgid "Center" msgstr "Centru" -#: FlatCAMApp.py:7418 +#: FlatCAMApp.py:7424 msgid "Locate ..." msgstr "Localizează ..." -#: FlatCAMApp.py:7679 FlatCAMApp.py:7756 +#: FlatCAMApp.py:7685 FlatCAMApp.py:7762 msgid "No object is selected. Select an object and try again." msgstr "" "Nici-un obiect nu este selectat. Selectează un obiect și incearcă din nou." -#: FlatCAMApp.py:7782 +#: FlatCAMApp.py:7788 msgid "" "Aborting. The current task will be gracefully closed as soon as possible..." msgstr "Intrerup. Taskul curent va fi închis cât mai curând posibil ..." -#: FlatCAMApp.py:7787 +#: FlatCAMApp.py:7794 msgid "The current task was gracefully closed on user request..." msgstr "Taskul curent a fost închis la cererea utilizatorului ..." -#: FlatCAMApp.py:7880 +#: FlatCAMApp.py:7887 msgid "Preferences edited but not saved." msgstr "Preferințele au fost editate dar nu au fost salvate." -#: FlatCAMApp.py:7897 FlatCAMApp.py:7925 FlatCAMApp.py:7952 FlatCAMApp.py:7971 -#: FlatCAMApp.py:8038 FlatCAMCommon.py:1182 FlatCAMCommon.py:1357 +#: FlatCAMApp.py:7904 FlatCAMApp.py:7932 FlatCAMApp.py:7959 FlatCAMApp.py:7978 +#: FlatCAMApp.py:8045 FlatCAMCommon.py:1182 FlatCAMCommon.py:1357 #: FlatCAMCommon.py:2612 FlatCAMCommon.py:2820 FlatCAMObj.py:4798 -#: flatcamTools/ToolNCC.py:3963 flatcamTools/ToolNCC.py:4047 -#: flatcamTools/ToolPaint.py:3537 flatcamTools/ToolPaint.py:3622 +#: flatcamTools/ToolNCC.py:3958 flatcamTools/ToolNCC.py:4042 +#: flatcamTools/ToolPaint.py:3548 flatcamTools/ToolPaint.py:3633 msgid "Tools Database" msgstr "Baza de Date Unelte" -#: FlatCAMApp.py:7949 +#: FlatCAMApp.py:7956 msgid "Tools in Tools Database edited but not saved." msgstr "Uneltele din Baza de date au fost editate dar nu au fost salvate." -#: FlatCAMApp.py:7975 flatcamTools/ToolNCC.py:3970 -#: flatcamTools/ToolPaint.py:3544 +#: FlatCAMApp.py:7982 flatcamTools/ToolNCC.py:3965 +#: flatcamTools/ToolPaint.py:3555 msgid "Tool from DB added in Tool Table." msgstr "Unealtă din Baza de date adăugată in Tabela de Unelte." -#: FlatCAMApp.py:7977 +#: FlatCAMApp.py:7984 msgid "Adding tool from DB is not allowed for this object." msgstr "" "Adaugarea unei unelte din Baza de date nu este permisa pt acest obiect." -#: FlatCAMApp.py:8018 +#: FlatCAMApp.py:8025 msgid "" "One or more values are changed.\n" "Do you want to save the Preferences?" @@ -819,11 +819,11 @@ msgstr "" "Una sau mai multe valori au fost schimbate.\n" "Dorești să salvezi Preferințele?" -#: FlatCAMApp.py:8020 flatcamGUI/FlatCAMGUI.py:291 +#: FlatCAMApp.py:8027 flatcamGUI/FlatCAMGUI.py:291 msgid "Save Preferences" msgstr "Salvează Pref" -#: FlatCAMApp.py:8044 +#: FlatCAMApp.py:8051 msgid "" "One or more Tools are edited.\n" "Do you want to update the Tools Database?" @@ -831,174 +831,174 @@ msgstr "" "Unul sau mai multe Unelte sunt editate.\n" "Doriți să actualizați baza de date a Uneltelor?" -#: FlatCAMApp.py:8046 +#: FlatCAMApp.py:8053 msgid "Save Tools Database" msgstr "Salvează baza de date Unelte" -#: FlatCAMApp.py:8065 FlatCAMApp.py:10252 FlatCAMObj.py:7089 +#: FlatCAMApp.py:8072 FlatCAMApp.py:10259 FlatCAMObj.py:7089 msgid "Code Editor" msgstr "Editor Cod" -#: FlatCAMApp.py:8087 +#: FlatCAMApp.py:8094 msgid "No object selected to Flip on Y axis." msgstr "Nu sete nici-un obiect selectat pentru oglindire pe axa Y." -#: FlatCAMApp.py:8113 +#: FlatCAMApp.py:8120 msgid "Flip on Y axis done." msgstr "Oglindire pe axa Y executată." -#: FlatCAMApp.py:8115 FlatCAMApp.py:8163 +#: FlatCAMApp.py:8122 FlatCAMApp.py:8170 #: flatcamEditors/FlatCAMGrbEditor.py:5893 msgid "Flip action was not executed." msgstr "Acțiunea de Oglindire nu a fost executată." -#: FlatCAMApp.py:8135 +#: FlatCAMApp.py:8142 msgid "No object selected to Flip on X axis." msgstr "Nu este nici-un obiect selectat pentru oglindire pe axa X." -#: FlatCAMApp.py:8161 +#: FlatCAMApp.py:8168 msgid "Flip on X axis done." msgstr "Oglindirea pe axa X executată." -#: FlatCAMApp.py:8183 +#: FlatCAMApp.py:8190 msgid "No object selected to Rotate." msgstr "Nici-un obiect selectat pentru Rotaţie." -#: FlatCAMApp.py:8186 FlatCAMApp.py:8239 FlatCAMApp.py:8278 +#: FlatCAMApp.py:8193 FlatCAMApp.py:8246 FlatCAMApp.py:8285 msgid "Transform" msgstr "Transformare" -#: FlatCAMApp.py:8186 FlatCAMApp.py:8239 FlatCAMApp.py:8278 +#: FlatCAMApp.py:8193 FlatCAMApp.py:8246 FlatCAMApp.py:8285 msgid "Enter the Angle value:" msgstr "Introduceți valoaea Unghiului:" -#: FlatCAMApp.py:8217 +#: FlatCAMApp.py:8224 msgid "Rotation done." msgstr "Rotaţie executată." -#: FlatCAMApp.py:8219 +#: FlatCAMApp.py:8226 msgid "Rotation movement was not executed." msgstr "Mișcarea de rotație nu a fost executată." -#: FlatCAMApp.py:8237 +#: FlatCAMApp.py:8244 msgid "No object selected to Skew/Shear on X axis." msgstr "Nici-un obiect nu este selectat pentru Deformare pe axa X." -#: FlatCAMApp.py:8259 +#: FlatCAMApp.py:8266 msgid "Skew on X axis done." msgstr "Deformare pe axa X terminată." -#: FlatCAMApp.py:8276 +#: FlatCAMApp.py:8283 msgid "No object selected to Skew/Shear on Y axis." msgstr "Nici-un obiect nu este selectat pentru Deformare pe axa Y." -#: FlatCAMApp.py:8298 +#: FlatCAMApp.py:8305 msgid "Skew on Y axis done." msgstr "Deformare pe axa Y terminată." -#: FlatCAMApp.py:8451 FlatCAMApp.py:8498 flatcamGUI/FlatCAMGUI.py:488 +#: FlatCAMApp.py:8458 FlatCAMApp.py:8505 flatcamGUI/FlatCAMGUI.py:488 #: flatcamGUI/FlatCAMGUI.py:1713 msgid "Select All" msgstr "Selectează toate" -#: FlatCAMApp.py:8455 FlatCAMApp.py:8502 flatcamGUI/FlatCAMGUI.py:490 +#: FlatCAMApp.py:8462 FlatCAMApp.py:8509 flatcamGUI/FlatCAMGUI.py:490 msgid "Deselect All" msgstr "Deselectează toate" -#: FlatCAMApp.py:8518 +#: FlatCAMApp.py:8525 msgid "All objects are selected." msgstr "Totate obiectele sunt selectate." -#: FlatCAMApp.py:8528 +#: FlatCAMApp.py:8535 msgid "Objects selection is cleared." msgstr "Nici-un obiect nu este selectat." -#: FlatCAMApp.py:8548 flatcamGUI/FlatCAMGUI.py:1706 +#: FlatCAMApp.py:8555 flatcamGUI/FlatCAMGUI.py:1706 msgid "Grid On/Off" msgstr "Grid On/Off" -#: FlatCAMApp.py:8560 flatcamEditors/FlatCAMGeoEditor.py:940 +#: FlatCAMApp.py:8567 flatcamEditors/FlatCAMGeoEditor.py:940 #: flatcamEditors/FlatCAMGrbEditor.py:2580 #: flatcamEditors/FlatCAMGrbEditor.py:5475 flatcamGUI/ObjectUI.py:1593 #: flatcamTools/ToolDblSided.py:193 flatcamTools/ToolDblSided.py:426 #: flatcamTools/ToolNCC.py:294 flatcamTools/ToolNCC.py:631 -#: flatcamTools/ToolPaint.py:277 flatcamTools/ToolPaint.py:673 +#: flatcamTools/ToolPaint.py:277 flatcamTools/ToolPaint.py:676 #: flatcamTools/ToolSolderPaste.py:123 flatcamTools/ToolSolderPaste.py:597 #: flatcamTools/ToolTransform.py:479 msgid "Add" msgstr "Adaugă" -#: FlatCAMApp.py:8562 FlatCAMObj.py:4416 +#: FlatCAMApp.py:8569 FlatCAMObj.py:4416 #: flatcamEditors/FlatCAMGrbEditor.py:2585 #: flatcamEditors/FlatCAMGrbEditor.py:2733 flatcamGUI/FlatCAMGUI.py:736 #: flatcamGUI/FlatCAMGUI.py:1059 flatcamGUI/FlatCAMGUI.py:2126 #: flatcamGUI/FlatCAMGUI.py:2269 flatcamGUI/FlatCAMGUI.py:2733 #: flatcamGUI/ObjectUI.py:1621 flatcamTools/ToolNCC.py:316 #: flatcamTools/ToolNCC.py:637 flatcamTools/ToolPaint.py:299 -#: flatcamTools/ToolPaint.py:679 flatcamTools/ToolSolderPaste.py:129 +#: flatcamTools/ToolPaint.py:682 flatcamTools/ToolSolderPaste.py:129 #: flatcamTools/ToolSolderPaste.py:600 msgid "Delete" msgstr "Șterge" -#: FlatCAMApp.py:8575 +#: FlatCAMApp.py:8582 msgid "New Grid ..." msgstr "Grid nou ..." -#: FlatCAMApp.py:8576 +#: FlatCAMApp.py:8583 msgid "Enter a Grid Value:" msgstr "Introduceti of valoare pt Grid:" -#: FlatCAMApp.py:8584 FlatCAMApp.py:8611 +#: FlatCAMApp.py:8591 FlatCAMApp.py:8618 msgid "Please enter a grid value with non-zero value, in Float format." msgstr "Introduceți o valoare pentru Grila ne-nula și in format Real." -#: FlatCAMApp.py:8590 +#: FlatCAMApp.py:8597 msgid "New Grid added" msgstr "Grid nou" -#: FlatCAMApp.py:8593 +#: FlatCAMApp.py:8600 msgid "Grid already exists" msgstr "Grila există deja" -#: FlatCAMApp.py:8596 +#: FlatCAMApp.py:8603 msgid "Adding New Grid cancelled" msgstr "Adăugarea unei valori de Grilă a fost anulată" -#: FlatCAMApp.py:8618 +#: FlatCAMApp.py:8625 msgid " Grid Value does not exist" msgstr " Valoarea Grilei nu există" -#: FlatCAMApp.py:8621 +#: FlatCAMApp.py:8628 msgid "Grid Value deleted" msgstr "Valoarea Grila a fost stearsă" -#: FlatCAMApp.py:8624 +#: FlatCAMApp.py:8631 msgid "Delete Grid value cancelled" msgstr "Ștergerea unei valori de Grilă a fost anulată" -#: FlatCAMApp.py:8630 +#: FlatCAMApp.py:8637 msgid "Key Shortcut List" msgstr "Lista de shortcut-uri" -#: FlatCAMApp.py:8664 +#: FlatCAMApp.py:8671 msgid " No object selected to copy it's name" msgstr " Nici-un obiect nu este selectat pentru i se copia valoarea" -#: FlatCAMApp.py:8668 +#: FlatCAMApp.py:8675 msgid "Name copied on clipboard ..." msgstr "Numele a fost copiat pe Clipboard ..." -#: FlatCAMApp.py:8881 flatcamEditors/FlatCAMGrbEditor.py:4421 +#: FlatCAMApp.py:8888 flatcamEditors/FlatCAMGrbEditor.py:4421 msgid "Coordinates copied to clipboard." msgstr "Coordonatele au fost copiate in clipboard." -#: FlatCAMApp.py:9120 FlatCAMApp.py:9126 FlatCAMApp.py:9132 FlatCAMApp.py:9138 +#: FlatCAMApp.py:9127 FlatCAMApp.py:9133 FlatCAMApp.py:9139 FlatCAMApp.py:9145 #: ObjectCollection.py:911 ObjectCollection.py:917 ObjectCollection.py:923 #: ObjectCollection.py:929 ObjectCollection.py:935 ObjectCollection.py:941 msgid "selected" msgstr "selectat" -#: FlatCAMApp.py:9293 +#: FlatCAMApp.py:9300 msgid "" "There are files/objects opened in FlatCAM.\n" "Creating a New project will delete them.\n" @@ -1008,17 +1008,17 @@ msgstr "" "Crearea unui nou Proiect le va șterge..\n" "Doriti să Salvati proiectul curentt?" -#: FlatCAMApp.py:9314 +#: FlatCAMApp.py:9321 msgid "New Project created" msgstr "Un nou Proiect a fost creat" -#: FlatCAMApp.py:9461 FlatCAMApp.py:9465 flatcamGUI/FlatCAMGUI.py:821 +#: FlatCAMApp.py:9468 FlatCAMApp.py:9472 flatcamGUI/FlatCAMGUI.py:821 #: flatcamGUI/FlatCAMGUI.py:2504 msgid "Open Gerber" msgstr "Încarcă Gerber" -#: FlatCAMApp.py:9470 FlatCAMApp.py:9507 FlatCAMApp.py:9549 FlatCAMApp.py:9618 -#: FlatCAMApp.py:10371 FlatCAMApp.py:11546 FlatCAMApp.py:11607 +#: FlatCAMApp.py:9477 FlatCAMApp.py:9514 FlatCAMApp.py:9556 FlatCAMApp.py:9625 +#: FlatCAMApp.py:10378 FlatCAMApp.py:11553 FlatCAMApp.py:11614 msgid "" "Canvas initialization started.\n" "Canvas initialization finished in" @@ -1026,254 +1026,254 @@ msgstr "" "FlatCAM se inițializează ...\n" "Initializarea spațiului de afisare s-a terminat in" -#: FlatCAMApp.py:9472 +#: FlatCAMApp.py:9479 msgid "Opening Gerber file." msgstr "Se incarcă un fişier Gerber." -#: FlatCAMApp.py:9499 FlatCAMApp.py:9503 flatcamGUI/FlatCAMGUI.py:823 +#: FlatCAMApp.py:9506 FlatCAMApp.py:9510 flatcamGUI/FlatCAMGUI.py:823 #: flatcamGUI/FlatCAMGUI.py:2506 msgid "Open Excellon" msgstr "Încarcă Excellon" -#: FlatCAMApp.py:9509 +#: FlatCAMApp.py:9516 msgid "Opening Excellon file." msgstr "Se incarcă un fişier Excellon." -#: FlatCAMApp.py:9540 FlatCAMApp.py:9544 +#: FlatCAMApp.py:9547 FlatCAMApp.py:9551 msgid "Open G-Code" msgstr "Încarcă G-Code" -#: FlatCAMApp.py:9551 +#: FlatCAMApp.py:9558 msgid "Opening G-Code file." msgstr "Se incarcă un fişier G-Code." -#: FlatCAMApp.py:9574 FlatCAMApp.py:9577 flatcamGUI/FlatCAMGUI.py:1715 +#: FlatCAMApp.py:9581 FlatCAMApp.py:9584 flatcamGUI/FlatCAMGUI.py:1715 msgid "Open Project" msgstr "Încarcă Project" -#: FlatCAMApp.py:9609 FlatCAMApp.py:9613 +#: FlatCAMApp.py:9616 FlatCAMApp.py:9620 msgid "Open HPGL2" msgstr "Încarcă HPGL2" -#: FlatCAMApp.py:9620 +#: FlatCAMApp.py:9627 msgid "Opening HPGL2 file." msgstr "Se incarcă un fişier HPGL2." -#: FlatCAMApp.py:9643 FlatCAMApp.py:9646 +#: FlatCAMApp.py:9650 FlatCAMApp.py:9653 msgid "Open Configuration File" msgstr "Încarcă un fişier de Configurare" -#: FlatCAMApp.py:9666 FlatCAMApp.py:10015 +#: FlatCAMApp.py:9673 FlatCAMApp.py:10022 msgid "Please Select a Geometry object to export" msgstr "Selectează un obiect Geometrie pentru export" -#: FlatCAMApp.py:9680 +#: FlatCAMApp.py:9687 msgid "Only Geometry, Gerber and CNCJob objects can be used." msgstr "Doar obiectele Geometrie, Gerber și CNCJob pot fi folosite." -#: FlatCAMApp.py:9693 FlatCAMApp.py:9697 flatcamTools/ToolQRCode.py:829 +#: FlatCAMApp.py:9700 FlatCAMApp.py:9704 flatcamTools/ToolQRCode.py:829 #: flatcamTools/ToolQRCode.py:833 msgid "Export SVG" msgstr "Exporta SVG" -#: FlatCAMApp.py:9723 +#: FlatCAMApp.py:9730 msgid "Data must be a 3D array with last dimension 3 or 4" msgstr "" "Datele trebuie să fie organizate intr-o arie 3D cu ultima dimensiune cu " "valoarea 3 sau 4" -#: FlatCAMApp.py:9729 FlatCAMApp.py:9733 +#: FlatCAMApp.py:9736 FlatCAMApp.py:9740 msgid "Export PNG Image" msgstr "Exporta imagine PNG" -#: FlatCAMApp.py:9767 FlatCAMApp.py:9975 +#: FlatCAMApp.py:9774 FlatCAMApp.py:9982 msgid "Failed. Only Gerber objects can be saved as Gerber files..." msgstr "Eșuat. Doar obiectele tip Gerber pot fi salvate ca fişiere Gerber..." -#: FlatCAMApp.py:9779 +#: FlatCAMApp.py:9786 msgid "Save Gerber source file" msgstr "Salvează codul sursa Gerber ca fişier" -#: FlatCAMApp.py:9808 +#: FlatCAMApp.py:9815 msgid "Failed. Only Script objects can be saved as TCL Script files..." msgstr "" "Eșuat. Doar obiectele tip Script pot fi salvate ca fişiere TCL Script..." -#: FlatCAMApp.py:9820 +#: FlatCAMApp.py:9827 msgid "Save Script source file" msgstr "Salvează codul sursa Script ca fişier" -#: FlatCAMApp.py:9849 +#: FlatCAMApp.py:9856 msgid "Failed. Only Document objects can be saved as Document files..." msgstr "" "Eșuat. Doar obiectele tip Document pot fi salvate ca fişiere Document ..." -#: FlatCAMApp.py:9861 +#: FlatCAMApp.py:9868 msgid "Save Document source file" msgstr "Salvează codul sursa Document ca fişier" -#: FlatCAMApp.py:9890 FlatCAMApp.py:9931 FlatCAMApp.py:10856 +#: FlatCAMApp.py:9897 FlatCAMApp.py:9938 FlatCAMApp.py:10863 msgid "Failed. Only Excellon objects can be saved as Excellon files..." msgstr "" "Eșuat. Doar obiectele tip Excellon pot fi salvate ca fişiere Excellon ..." -#: FlatCAMApp.py:9898 FlatCAMApp.py:9902 +#: FlatCAMApp.py:9905 FlatCAMApp.py:9909 msgid "Save Excellon source file" msgstr "Salvează codul sursa Excellon ca fişier" -#: FlatCAMApp.py:9939 FlatCAMApp.py:9943 +#: FlatCAMApp.py:9946 FlatCAMApp.py:9950 msgid "Export Excellon" msgstr "Exportă Excellon" -#: FlatCAMApp.py:9983 FlatCAMApp.py:9987 +#: FlatCAMApp.py:9990 FlatCAMApp.py:9994 msgid "Export Gerber" msgstr "Exportă Gerber" -#: FlatCAMApp.py:10025 +#: FlatCAMApp.py:10032 msgid "Only Geometry objects can be used." msgstr "Doar obiecte tip Geometrie pot fi folosite." -#: FlatCAMApp.py:10039 FlatCAMApp.py:10043 +#: FlatCAMApp.py:10046 FlatCAMApp.py:10050 msgid "Export DXF" msgstr "Exportă DXF" -#: FlatCAMApp.py:10068 FlatCAMApp.py:10071 +#: FlatCAMApp.py:10075 FlatCAMApp.py:10078 msgid "Import SVG" msgstr "Importă SVG" -#: FlatCAMApp.py:10099 FlatCAMApp.py:10103 +#: FlatCAMApp.py:10106 FlatCAMApp.py:10110 msgid "Import DXF" msgstr "Importa DXF" -#: FlatCAMApp.py:10154 +#: FlatCAMApp.py:10161 msgid "Viewing the source code of the selected object." msgstr "Vizualizarea codului sursă a obiectului selectat." -#: FlatCAMApp.py:10155 FlatCAMObj.py:7075 FlatCAMObj.py:7852 +#: FlatCAMApp.py:10162 FlatCAMObj.py:7075 FlatCAMObj.py:7852 msgid "Loading..." msgstr "Se incarcă..." -#: FlatCAMApp.py:10161 FlatCAMApp.py:10165 +#: FlatCAMApp.py:10168 FlatCAMApp.py:10172 msgid "Select an Gerber or Excellon file to view it's source file." msgstr "Selectati un obiect Gerber sau Excellon pentru a-i vedea codul sursa." -#: FlatCAMApp.py:10179 +#: FlatCAMApp.py:10186 msgid "Source Editor" msgstr "Editor Cod Sursă" -#: FlatCAMApp.py:10219 FlatCAMApp.py:10226 +#: FlatCAMApp.py:10226 FlatCAMApp.py:10233 msgid "There is no selected object for which to see it's source file code." msgstr "Nici-un obiect selectat pentru a-i vedea codul sursa." -#: FlatCAMApp.py:10238 +#: FlatCAMApp.py:10245 msgid "Failed to load the source code for the selected object" msgstr "Codul sursă pentru obiectul selectat nu a putut fi încărcat" -#: FlatCAMApp.py:10274 +#: FlatCAMApp.py:10281 msgid "Go to Line ..." msgstr "Mergi la Linia ..." -#: FlatCAMApp.py:10275 +#: FlatCAMApp.py:10282 msgid "Line:" msgstr "Linia:" -#: FlatCAMApp.py:10304 +#: FlatCAMApp.py:10311 msgid "New TCL script file created in Code Editor." msgstr "Un nou script TCL a fost creat in Editorul de cod." -#: FlatCAMApp.py:10343 FlatCAMApp.py:10345 +#: FlatCAMApp.py:10350 FlatCAMApp.py:10352 msgid "Open TCL script" msgstr "Încarcă TCL script" -#: FlatCAMApp.py:10373 +#: FlatCAMApp.py:10380 msgid "Executing FlatCAMScript file." msgstr "Se executa un fisier script FlatCAM." -#: FlatCAMApp.py:10381 FlatCAMApp.py:10384 +#: FlatCAMApp.py:10388 FlatCAMApp.py:10391 msgid "Run TCL script" msgstr "Ruleaza TCL script" -#: FlatCAMApp.py:10408 +#: FlatCAMApp.py:10415 msgid "TCL script file opened in Code Editor and executed." msgstr "Un fisier script TCL a fost deschis in Editorul de cod si executat." -#: FlatCAMApp.py:10459 FlatCAMApp.py:10465 +#: FlatCAMApp.py:10466 FlatCAMApp.py:10472 msgid "Save Project As ..." msgstr "Salvează Proiectul ca ..." -#: FlatCAMApp.py:10461 flatcamGUI/FlatCAMGUI.py:1119 +#: FlatCAMApp.py:10468 flatcamGUI/FlatCAMGUI.py:1119 #: flatcamGUI/FlatCAMGUI.py:2161 msgid "Project" msgstr "Proiect" -#: FlatCAMApp.py:10500 +#: FlatCAMApp.py:10507 msgid "FlatCAM objects print" msgstr "Tipărirea obiectelor FlatCAM" -#: FlatCAMApp.py:10513 FlatCAMApp.py:10520 +#: FlatCAMApp.py:10520 FlatCAMApp.py:10527 msgid "Save Object as PDF ..." msgstr "Salvați obiectul în format PDF ..." -#: FlatCAMApp.py:10529 +#: FlatCAMApp.py:10536 msgid "Printing PDF ... Please wait." msgstr "Se tipărește PDF ... Vă rugăm să așteptați." -#: FlatCAMApp.py:10708 +#: FlatCAMApp.py:10715 msgid "PDF file saved to" msgstr "Fișierul PDF salvat în" -#: FlatCAMApp.py:10733 +#: FlatCAMApp.py:10740 msgid "Exporting SVG" msgstr "SVG in curs de export" -#: FlatCAMApp.py:10776 +#: FlatCAMApp.py:10783 msgid "SVG file exported to" msgstr "Fişier SVG exportat in" -#: FlatCAMApp.py:10802 +#: FlatCAMApp.py:10809 msgid "" "Save cancelled because source file is empty. Try to export the Gerber file." msgstr "" "Salvare anulată deoarece fișierul sursă este gol. Încercați să exportați " "fișierul Gerber." -#: FlatCAMApp.py:10950 +#: FlatCAMApp.py:10957 msgid "Excellon file exported to" msgstr "Fişierul Excellon exportat in" -#: FlatCAMApp.py:10959 +#: FlatCAMApp.py:10966 msgid "Exporting Excellon" msgstr "Excellon in curs de export" -#: FlatCAMApp.py:10964 FlatCAMApp.py:10971 +#: FlatCAMApp.py:10971 FlatCAMApp.py:10978 msgid "Could not export Excellon file." msgstr "Fişierul Excellon nu a fost posibil să fie exportat." -#: FlatCAMApp.py:11087 +#: FlatCAMApp.py:11094 msgid "Gerber file exported to" msgstr "Fişier Gerber exportat in" -#: FlatCAMApp.py:11095 +#: FlatCAMApp.py:11102 msgid "Exporting Gerber" msgstr "Gerber in curs de export" -#: FlatCAMApp.py:11100 FlatCAMApp.py:11107 +#: FlatCAMApp.py:11107 FlatCAMApp.py:11114 msgid "Could not export Gerber file." msgstr "Fişierul Gerber nu a fost posibil să fie exportat." -#: FlatCAMApp.py:11142 +#: FlatCAMApp.py:11149 msgid "DXF file exported to" msgstr "Fişierul DXF exportat in" -#: FlatCAMApp.py:11148 +#: FlatCAMApp.py:11155 msgid "Exporting DXF" msgstr "DXF in curs de export" -#: FlatCAMApp.py:11153 FlatCAMApp.py:11160 +#: FlatCAMApp.py:11160 FlatCAMApp.py:11167 msgid "Could not export DXF file." msgstr "Fişierul DXF nu a fost posibil să fie exportat." -#: FlatCAMApp.py:11183 FlatCAMApp.py:11225 flatcamTools/ToolImage.py:277 +#: FlatCAMApp.py:11190 FlatCAMApp.py:11232 flatcamTools/ToolImage.py:277 msgid "" "Not supported type is picked as parameter. Only Geometry and Gerber are " "supported" @@ -1281,80 +1281,80 @@ msgstr "" "Tipul parametrului nu este compatibil. Doar obiectele tip Geometrie si " "Gerber sunt acceptate" -#: FlatCAMApp.py:11193 +#: FlatCAMApp.py:11200 msgid "Importing SVG" msgstr "SVG in curs de ia fi importat" -#: FlatCAMApp.py:11204 FlatCAMApp.py:11244 FlatCAMApp.py:11302 -#: FlatCAMApp.py:11367 FlatCAMApp.py:11431 FlatCAMApp.py:11496 -#: FlatCAMApp.py:11533 flatcamTools/ToolImage.py:297 +#: FlatCAMApp.py:11211 FlatCAMApp.py:11251 FlatCAMApp.py:11309 +#: FlatCAMApp.py:11374 FlatCAMApp.py:11438 FlatCAMApp.py:11503 +#: FlatCAMApp.py:11540 flatcamTools/ToolImage.py:297 #: flatcamTools/ToolPDF.py:225 msgid "Opened" msgstr "Încarcat" -#: FlatCAMApp.py:11234 +#: FlatCAMApp.py:11241 msgid "Importing DXF" msgstr "DXF in curs de a fi importat" -#: FlatCAMApp.py:11268 FlatCAMApp.py:11455 +#: FlatCAMApp.py:11275 FlatCAMApp.py:11462 msgid "Failed to open file" msgstr "Eşec in incărcarea fişierului" -#: FlatCAMApp.py:11271 FlatCAMApp.py:11458 +#: FlatCAMApp.py:11278 FlatCAMApp.py:11465 msgid "Failed to parse file" msgstr "Parsarea fişierului a eșuat" -#: FlatCAMApp.py:11283 +#: FlatCAMApp.py:11290 msgid "Object is not Gerber file or empty. Aborting object creation." msgstr "" "Obiectul nu estetip Gerber sau este gol. Se anulează crearea obiectului." -#: FlatCAMApp.py:11288 +#: FlatCAMApp.py:11295 msgid "Opening Gerber" msgstr "Gerber in curs de incărcare" -#: FlatCAMApp.py:11295 +#: FlatCAMApp.py:11302 msgid " Open Gerber failed. Probable not a Gerber file." msgstr " Incărcarea Gerber a eșuat. Probabil nu este de tip Gerber." -#: FlatCAMApp.py:11326 flatcamTools/ToolPcbWizard.py:425 +#: FlatCAMApp.py:11333 flatcamTools/ToolPcbWizard.py:425 msgid "This is not Excellon file." msgstr "Acesta nu este un fişier Excellon." -#: FlatCAMApp.py:11330 +#: FlatCAMApp.py:11337 msgid "Cannot open file" msgstr "Nu se poate incărca fişierul" -#: FlatCAMApp.py:11349 flatcamTools/ToolPDF.py:275 +#: FlatCAMApp.py:11356 flatcamTools/ToolPDF.py:275 #: flatcamTools/ToolPcbWizard.py:447 msgid "No geometry found in file" msgstr "Nici-o informaţie de tip geometrie nu s-a gasit in fişierul" -#: FlatCAMApp.py:11352 +#: FlatCAMApp.py:11359 msgid "Opening Excellon." msgstr "Excellon in curs de incărcare." -#: FlatCAMApp.py:11359 +#: FlatCAMApp.py:11366 msgid "Open Excellon file failed. Probable not an Excellon file." msgstr "Incărcarea Excellon a eșuat. Probabil nu este de tip Excellon." -#: FlatCAMApp.py:11391 +#: FlatCAMApp.py:11398 msgid "Reading GCode file" msgstr "Se citeşte un fişier G-Code" -#: FlatCAMApp.py:11398 +#: FlatCAMApp.py:11405 msgid "Failed to open" msgstr "A eșuat incărcarea fişierului" -#: FlatCAMApp.py:11406 +#: FlatCAMApp.py:11413 msgid "This is not GCODE" msgstr "Acest obiect nu este de tip GCode" -#: FlatCAMApp.py:11411 +#: FlatCAMApp.py:11418 msgid "Opening G-Code." msgstr "G-Code in curs de incărcare." -#: FlatCAMApp.py:11420 +#: FlatCAMApp.py:11427 msgid "" "Failed to create CNCJob Object. Probable not a GCode file. Try to load it " "from File menu.\n" @@ -1365,104 +1365,104 @@ msgstr "" "Încercați să-l încărcați din meniul Fișier. \n" "Incercarea de a crea un obiect CNCJob din G-Code a eșuat in timpul procesarii" -#: FlatCAMApp.py:11477 +#: FlatCAMApp.py:11484 msgid "Object is not HPGL2 file or empty. Aborting object creation." msgstr "" "Obiectul nu este fișier HPGL2 sau este gol. Se renunta la crearea obiectului." -#: FlatCAMApp.py:11482 +#: FlatCAMApp.py:11489 msgid "Opening HPGL2" msgstr "HPGL2 in curs de incărcare" -#: FlatCAMApp.py:11489 +#: FlatCAMApp.py:11496 msgid " Open HPGL2 failed. Probable not a HPGL2 file." msgstr " Incărcarea HPGL2 a eșuat. Probabil nu este de tip HPGL2 ." -#: FlatCAMApp.py:11509 +#: FlatCAMApp.py:11516 msgid "Opening TCL Script..." msgstr "Încarcă TCL script..." -#: FlatCAMApp.py:11517 +#: FlatCAMApp.py:11524 msgid "TCL script file opened in Code Editor." msgstr "S-a încărcat un script TCL în Editorul Cod." -#: FlatCAMApp.py:11520 +#: FlatCAMApp.py:11527 msgid "Failed to open TCL Script." msgstr "Eşec in incărcarea fişierului TCL." -#: FlatCAMApp.py:11548 +#: FlatCAMApp.py:11555 msgid "Opening FlatCAM Config file." msgstr "Se incarca un fişier FlatCAM de configurare." -#: FlatCAMApp.py:11576 +#: FlatCAMApp.py:11583 msgid "Failed to open config file" msgstr "Eşec in incărcarea fişierului de configurare" -#: FlatCAMApp.py:11604 +#: FlatCAMApp.py:11611 msgid "Loading Project ... Please Wait ..." msgstr "Se încarcă proiectul ... Vă rugăm să așteptați ..." -#: FlatCAMApp.py:11609 +#: FlatCAMApp.py:11616 msgid "Opening FlatCAM Project file." msgstr "Se incarca un fisier proiect FlatCAM." -#: FlatCAMApp.py:11619 FlatCAMApp.py:11637 +#: FlatCAMApp.py:11626 FlatCAMApp.py:11644 msgid "Failed to open project file" msgstr "Eşec in incărcarea fişierului proiect" -#: FlatCAMApp.py:11674 +#: FlatCAMApp.py:11681 msgid "Loading Project ... restoring" msgstr "Se încarcă proiectul ... se restabileste" -#: FlatCAMApp.py:11684 +#: FlatCAMApp.py:11691 msgid "Project loaded from" msgstr "Proiectul a fost incărcat din" -#: FlatCAMApp.py:11753 +#: FlatCAMApp.py:11760 msgid "Redrawing all objects" msgstr "Toate obiectele sunt reafisate" -#: FlatCAMApp.py:11842 +#: FlatCAMApp.py:11849 msgid "Failed to load recent item list." msgstr "Eşec in incărcarea listei cu fişiere recente." -#: FlatCAMApp.py:11849 +#: FlatCAMApp.py:11856 msgid "Failed to parse recent item list." msgstr "Eşec in parsarea listei cu fişiere recente." -#: FlatCAMApp.py:11859 +#: FlatCAMApp.py:11866 msgid "Failed to load recent projects item list." msgstr "Eşec in incărcarea listei cu proiecte recente." -#: FlatCAMApp.py:11866 +#: FlatCAMApp.py:11873 msgid "Failed to parse recent project item list." msgstr "Eşec in parsarea listei cu proiecte recente." -#: FlatCAMApp.py:11927 +#: FlatCAMApp.py:11934 msgid "Clear Recent projects" msgstr "Sterge Proiectele recente" -#: FlatCAMApp.py:11951 +#: FlatCAMApp.py:11958 msgid "Clear Recent files" msgstr "Sterge fişierele recente" -#: FlatCAMApp.py:11973 flatcamGUI/FlatCAMGUI.py:1348 +#: FlatCAMApp.py:11980 flatcamGUI/FlatCAMGUI.py:1348 msgid "Shortcut Key List" msgstr "Lista cu taste Shortcut" -#: FlatCAMApp.py:12047 +#: FlatCAMApp.py:12054 msgid "Selected Tab - Choose an Item from Project Tab" msgstr "Tab-ul Selectat - Alege un obiect din Tab-ul Proiect" -#: FlatCAMApp.py:12048 +#: FlatCAMApp.py:12055 msgid "Details" msgstr "Detalii" -#: FlatCAMApp.py:12050 +#: FlatCAMApp.py:12057 msgid "The normal flow when working in FlatCAM is the following:" msgstr "Fluxul normal cand se lucreaza in FlatCAM este urmatorul:" -#: FlatCAMApp.py:12051 +#: FlatCAMApp.py:12058 msgid "" "Load/Import a Gerber, Excellon, Gcode, DXF, Raster Image or SVG file into " "FlatCAM using either the toolbars, key shortcuts or even dragging and " @@ -1472,7 +1472,7 @@ msgstr "" "sau SVG în FlatCAM utilizând fie barele de instrumente, combinatii de taste " "sau chiar tragând fișierele în GUI." -#: FlatCAMApp.py:12054 +#: FlatCAMApp.py:12061 msgid "" "You can also load a FlatCAM project by double clicking on the project file, " "drag and drop of the file into the FLATCAM GUI or through the menu (or " @@ -1482,7 +1482,7 @@ msgstr "" "proiectului, tragând fișierul în fereastra FLATCAM sau prin icon-urile din " "meniu (sau din bara de instrumente) oferite în aplicație." -#: FlatCAMApp.py:12057 +#: FlatCAMApp.py:12064 msgid "" "Once an object is available in the Project Tab, by selecting it and then " "focusing on SELECTED TAB (more simpler is to double click the object name in " @@ -1495,7 +1495,7 @@ msgstr "" "proprietățile obiectului în funcție de tipul său: Gerber, Excellon, " "Geometrie sau obiect CNCJob." -#: FlatCAMApp.py:12061 +#: FlatCAMApp.py:12068 msgid "" "If the selection of the object is done on the canvas by single click " "instead, and the SELECTED TAB is in focus, again the object properties will " @@ -1509,14 +1509,14 @@ msgstr "" "de pe ecran va aduce fila SELECTAT și o va popula chiar dacă nu a fost in " "focus." -#: FlatCAMApp.py:12065 +#: FlatCAMApp.py:12072 msgid "" "You can change the parameters in this screen and the flow direction is like " "this:" msgstr "" "Se pot schimba parametrii in acest ecran si directia de executive este asa:" -#: FlatCAMApp.py:12066 +#: FlatCAMApp.py:12073 msgid "" "Gerber/Excellon Object --> Change Parameter --> Generate Geometry --> " "Geometry Object --> Add tools (change param in Selected Tab) --> Generate " @@ -1529,7 +1529,7 @@ msgstr "" "CNC) și / sau adăugați in fata / la final codul G-code (din nou, efectuat în " "fila SELECȚIONATĂ) -> Salvați codul G-code." -#: FlatCAMApp.py:12070 +#: FlatCAMApp.py:12077 msgid "" "A list of key shortcuts is available through an menu entry in Help --> " "Shortcuts List or through its own key shortcut: F3." @@ -1538,33 +1538,33 @@ msgstr "" "meniul Ajutor -> Lista de combinatii taste sau prin propria tasta asociata: " "F3." -#: FlatCAMApp.py:12134 +#: FlatCAMApp.py:12141 msgid "Failed checking for latest version. Could not connect." msgstr "" "Verificarea pentru ultima versiune a eșuat. Nu a fost posibilă conectarea la " "server." -#: FlatCAMApp.py:12141 +#: FlatCAMApp.py:12148 msgid "Could not parse information about latest version." msgstr "Informatia cu privire la ultima versiune nu s-a putut interpreta." -#: FlatCAMApp.py:12151 +#: FlatCAMApp.py:12158 msgid "FlatCAM is up to date!" msgstr "FlatCAM este la ultima versiune!" -#: FlatCAMApp.py:12156 +#: FlatCAMApp.py:12163 msgid "Newer Version Available" msgstr "O nouă versiune este disponibila" -#: FlatCAMApp.py:12158 +#: FlatCAMApp.py:12165 msgid "There is a newer version of FlatCAM available for download:" msgstr "O nouă versiune de FlatCAM este disponibilă pentru download:" -#: FlatCAMApp.py:12162 +#: FlatCAMApp.py:12169 msgid "info" msgstr "informaţie" -#: FlatCAMApp.py:12190 +#: FlatCAMApp.py:12197 msgid "" "OpenGL canvas initialization failed. HW or HW configuration not supported." "Change the graphic engine to Legacy(2D) in Edit -> Preferences -> General " @@ -1576,87 +1576,87 @@ msgstr "" "Preferinţe -> General\n" "\n" -#: FlatCAMApp.py:12269 +#: FlatCAMApp.py:12276 msgid "All plots disabled." msgstr "Toate afişările sunt dezactivate." -#: FlatCAMApp.py:12276 +#: FlatCAMApp.py:12283 msgid "All non selected plots disabled." msgstr "Toate afişările care nu sunt selectate sunt dezactivate." -#: FlatCAMApp.py:12283 +#: FlatCAMApp.py:12290 msgid "All plots enabled." msgstr "Toate afişările sunt activate." -#: FlatCAMApp.py:12289 +#: FlatCAMApp.py:12296 msgid "Selected plots enabled..." msgstr "Toate afişările selectate sunt activate..." -#: FlatCAMApp.py:12297 +#: FlatCAMApp.py:12304 msgid "Selected plots disabled..." msgstr "Toate afişările selectate sunt dezactivate..." -#: FlatCAMApp.py:12330 +#: FlatCAMApp.py:12337 msgid "Enabling plots ..." msgstr "Activează Afișare ..." -#: FlatCAMApp.py:12382 +#: FlatCAMApp.py:12389 msgid "Disabling plots ..." msgstr "Dezactivează Afișare ..." -#: FlatCAMApp.py:12405 +#: FlatCAMApp.py:12412 msgid "Working ..." msgstr "Se lucrează..." -#: FlatCAMApp.py:12460 flatcamGUI/FlatCAMGUI.py:688 +#: FlatCAMApp.py:12467 flatcamGUI/FlatCAMGUI.py:688 msgid "Red" msgstr "Roșu" -#: FlatCAMApp.py:12462 flatcamGUI/FlatCAMGUI.py:691 +#: FlatCAMApp.py:12469 flatcamGUI/FlatCAMGUI.py:691 msgid "Blue" msgstr "Albastru" -#: FlatCAMApp.py:12465 flatcamGUI/FlatCAMGUI.py:694 +#: FlatCAMApp.py:12472 flatcamGUI/FlatCAMGUI.py:694 msgid "Yellow" msgstr "Galben" -#: FlatCAMApp.py:12467 flatcamGUI/FlatCAMGUI.py:697 +#: FlatCAMApp.py:12474 flatcamGUI/FlatCAMGUI.py:697 msgid "Green" msgstr "Verde" -#: FlatCAMApp.py:12469 flatcamGUI/FlatCAMGUI.py:700 +#: FlatCAMApp.py:12476 flatcamGUI/FlatCAMGUI.py:700 msgid "Purple" msgstr "Violet" -#: FlatCAMApp.py:12471 flatcamGUI/FlatCAMGUI.py:703 +#: FlatCAMApp.py:12478 flatcamGUI/FlatCAMGUI.py:703 msgid "Brown" msgstr "Maro" -#: FlatCAMApp.py:12473 FlatCAMApp.py:12529 flatcamGUI/FlatCAMGUI.py:706 +#: FlatCAMApp.py:12480 FlatCAMApp.py:12536 flatcamGUI/FlatCAMGUI.py:706 msgid "White" msgstr "Alb" -#: FlatCAMApp.py:12475 flatcamGUI/FlatCAMGUI.py:709 +#: FlatCAMApp.py:12482 flatcamGUI/FlatCAMGUI.py:709 msgid "Black" msgstr "Negru" -#: FlatCAMApp.py:12478 flatcamGUI/FlatCAMGUI.py:714 +#: FlatCAMApp.py:12485 flatcamGUI/FlatCAMGUI.py:714 msgid "Custom" msgstr "Personalizat" -#: FlatCAMApp.py:12488 flatcamGUI/FlatCAMGUI.py:722 +#: FlatCAMApp.py:12495 flatcamGUI/FlatCAMGUI.py:722 msgid "Default" msgstr "Implicit" -#: FlatCAMApp.py:12512 flatcamGUI/FlatCAMGUI.py:719 +#: FlatCAMApp.py:12519 flatcamGUI/FlatCAMGUI.py:719 msgid "Opacity" msgstr "Opacitate" -#: FlatCAMApp.py:12514 +#: FlatCAMApp.py:12521 msgid "Set alpha level ..." msgstr "Setează transparenta ..." -#: FlatCAMApp.py:12514 flatcamGUI/PreferencesUI.py:6900 +#: FlatCAMApp.py:12521 flatcamGUI/PreferencesUI.py:6900 #: flatcamGUI/PreferencesUI.py:8230 flatcamGUI/PreferencesUI.py:8444 #: flatcamTools/ToolExtractDrills.py:164 flatcamTools/ToolExtractDrills.py:285 #: flatcamTools/ToolPunchGerber.py:192 flatcamTools/ToolPunchGerber.py:308 @@ -1664,31 +1664,31 @@ msgstr "Setează transparenta ..." msgid "Value" msgstr "Valoare" -#: FlatCAMApp.py:12590 +#: FlatCAMApp.py:12597 msgid "Saving FlatCAM Project" msgstr "Proiectul FlatCAM este in curs de salvare" -#: FlatCAMApp.py:12611 FlatCAMApp.py:12647 +#: FlatCAMApp.py:12618 FlatCAMApp.py:12654 msgid "Project saved to" msgstr "Proiectul s-a salvat in" -#: FlatCAMApp.py:12618 +#: FlatCAMApp.py:12625 msgid "The object is used by another application." msgstr "Obiectul este folosit de o altă aplicație." -#: FlatCAMApp.py:12632 +#: FlatCAMApp.py:12639 msgid "Failed to verify project file" msgstr "Eşec in incărcarea fişierului proiect" -#: FlatCAMApp.py:12632 FlatCAMApp.py:12640 FlatCAMApp.py:12650 +#: FlatCAMApp.py:12639 FlatCAMApp.py:12647 FlatCAMApp.py:12657 msgid "Retry to save it." msgstr "Încercați din nou pentru a-l salva." -#: FlatCAMApp.py:12640 FlatCAMApp.py:12650 +#: FlatCAMApp.py:12647 FlatCAMApp.py:12657 msgid "Failed to parse saved project file" msgstr "Esec in analizarea fişierului Proiect" -#: FlatCAMApp.py:13132 +#: FlatCAMApp.py:13139 msgid "The user requested a graceful exit of the current task." msgstr "Utilizatorul a solicitat o inchidere grațioasă a taskului curent." @@ -2386,7 +2386,7 @@ msgid "Clear" msgstr "Șterge" #: FlatCAMCommon.py:1853 flatcamTools/ToolNCC.py:351 -#: flatcamTools/ToolNCC.py:1627 +#: flatcamTools/ToolNCC.py:1618 msgid "Isolation" msgstr "Tip de izolare" @@ -2495,9 +2495,9 @@ msgstr "" #: FlatCAMCommon.py:1925 FlatCAMCommon.py:2040 #: flatcamEditors/FlatCAMGeoEditor.py:500 flatcamGUI/PreferencesUI.py:5509 #: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 -#: flatcamTools/ToolNCC.py:2395 flatcamTools/ToolNCC.py:2424 -#: flatcamTools/ToolNCC.py:2693 flatcamTools/ToolNCC.py:2725 -#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:1822 +#: flatcamTools/ToolNCC.py:2390 flatcamTools/ToolNCC.py:2419 +#: flatcamTools/ToolNCC.py:2688 flatcamTools/ToolNCC.py:2720 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:1829 #: tclCommands/TclCommandCopperClear.py:126 #: tclCommands/TclCommandCopperClear.py:134 tclCommands/TclCommandPaint.py:125 msgid "Standard" @@ -2507,8 +2507,8 @@ msgstr "Standard" #: flatcamEditors/FlatCAMGeoEditor.py:500 #: flatcamEditors/FlatCAMGeoEditor.py:5156 flatcamGUI/PreferencesUI.py:5509 #: flatcamGUI/PreferencesUI.py:6056 flatcamTools/ToolNCC.py:431 -#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:696 -#: flatcamTools/ToolPaint.py:1850 tclCommands/TclCommandCopperClear.py:130 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:699 +#: flatcamTools/ToolPaint.py:1857 tclCommands/TclCommandCopperClear.py:130 #: tclCommands/TclCommandPaint.py:129 msgid "Lines" msgstr "Linii" @@ -2624,13 +2624,13 @@ msgstr "" #: FlatCAMCommon.py:2040 FlatCAMCommon.py:2042 flatcamGUI/PreferencesUI.py:6056 #: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:392 -#: flatcamTools/ToolPaint.py:690 flatcamTools/ToolPaint.py:695 -#: flatcamTools/ToolPaint.py:1864 tclCommands/TclCommandPaint.py:131 +#: flatcamTools/ToolPaint.py:693 flatcamTools/ToolPaint.py:698 +#: flatcamTools/ToolPaint.py:1871 tclCommands/TclCommandPaint.py:131 msgid "Laser_lines" msgstr "Linii-laser" #: FlatCAMCommon.py:2040 flatcamGUI/PreferencesUI.py:6056 -#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:2015 +#: flatcamTools/ToolPaint.py:390 flatcamTools/ToolPaint.py:2022 #: tclCommands/TclCommandPaint.py:133 msgid "Combo" msgstr "Combinat" @@ -2680,8 +2680,8 @@ msgstr "Deformare..." #: flatcamTools/ToolFilm.py:557 flatcamTools/ToolImage.py:49 #: flatcamTools/ToolImage.py:252 flatcamTools/ToolImage.py:273 #: flatcamTools/ToolNCC.py:96 flatcamTools/ToolNCC.py:558 -#: flatcamTools/ToolNCC.py:1293 flatcamTools/ToolPaint.py:502 -#: flatcamTools/ToolPaint.py:703 flatcamTools/ToolPanelize.py:118 +#: flatcamTools/ToolNCC.py:1295 flatcamTools/ToolPaint.py:502 +#: flatcamTools/ToolPaint.py:706 flatcamTools/ToolPanelize.py:118 #: flatcamTools/ToolPanelize.py:204 flatcamTools/ToolPanelize.py:374 #: flatcamTools/ToolPanelize.py:391 msgid "Gerber" @@ -2697,8 +2697,8 @@ msgstr "Gerber" #: flatcamTools/ToolFilm.py:102 flatcamTools/ToolFilm.py:549 #: flatcamTools/ToolFilm.py:557 flatcamTools/ToolImage.py:49 #: flatcamTools/ToolImage.py:271 flatcamTools/ToolNCC.py:95 -#: flatcamTools/ToolNCC.py:558 flatcamTools/ToolNCC.py:1293 -#: flatcamTools/ToolPaint.py:502 flatcamTools/ToolPaint.py:703 +#: flatcamTools/ToolNCC.py:558 flatcamTools/ToolNCC.py:1295 +#: flatcamTools/ToolPaint.py:502 flatcamTools/ToolPaint.py:706 #: flatcamTools/ToolPanelize.py:118 flatcamTools/ToolPanelize.py:374 #: flatcamTools/ToolPanelize.py:391 msgid "Geometry" @@ -2721,11 +2721,11 @@ msgstr "Buferarea geometriei solide" #: FlatCAMObj.py:1001 camlib.py:979 flatcamGUI/PreferencesUI.py:2476 #: flatcamTools/ToolCopperThieving.py:1017 #: flatcamTools/ToolCopperThieving.py:1206 -#: flatcamTools/ToolCopperThieving.py:1218 flatcamTools/ToolNCC.py:2050 -#: flatcamTools/ToolNCC.py:2158 flatcamTools/ToolNCC.py:2172 -#: flatcamTools/ToolNCC.py:3103 flatcamTools/ToolNCC.py:3208 -#: flatcamTools/ToolNCC.py:3223 flatcamTools/ToolNCC.py:3489 -#: flatcamTools/ToolNCC.py:3590 flatcamTools/ToolNCC.py:3605 +#: flatcamTools/ToolCopperThieving.py:1218 flatcamTools/ToolNCC.py:2045 +#: flatcamTools/ToolNCC.py:2153 flatcamTools/ToolNCC.py:2167 +#: flatcamTools/ToolNCC.py:3098 flatcamTools/ToolNCC.py:3203 +#: flatcamTools/ToolNCC.py:3218 flatcamTools/ToolNCC.py:3484 +#: flatcamTools/ToolNCC.py:3585 flatcamTools/ToolNCC.py:3600 msgid "Buffering" msgstr "Buferare" @@ -2745,7 +2745,7 @@ msgstr "Se izoleaza..." msgid "Click on a polygon to isolate it." msgstr "Faceți clic pe un poligon pentru a-l izola." -#: FlatCAMObj.py:1173 FlatCAMObj.py:1277 flatcamTools/ToolPaint.py:1504 +#: FlatCAMObj.py:1173 FlatCAMObj.py:1277 flatcamTools/ToolPaint.py:1511 msgid "Added polygon" msgstr "S-a adăugat poligon" @@ -2755,7 +2755,7 @@ msgstr "" "Faceți clic pentru a adăuga următorul poligon sau faceți clic dreapta pentru " "a începe izolarea." -#: FlatCAMObj.py:1186 flatcamTools/ToolPaint.py:1518 +#: FlatCAMObj.py:1186 flatcamTools/ToolPaint.py:1525 msgid "Removed polygon" msgstr "Poligon eliminat" @@ -2765,11 +2765,11 @@ msgstr "" "Faceți clic pentru a adăuga / elimina următorul poligon sau faceți clic " "dreapta pentru a începe izolarea." -#: FlatCAMObj.py:1192 flatcamTools/ToolPaint.py:1524 +#: FlatCAMObj.py:1192 flatcamTools/ToolPaint.py:1531 msgid "No polygon detected under click position." msgstr "Nu a fost detectat niciun poligon sub poziția clicului." -#: FlatCAMObj.py:1213 flatcamTools/ToolPaint.py:1553 +#: FlatCAMObj.py:1213 flatcamTools/ToolPaint.py:1560 msgid "List of single polygons is empty. Aborting." msgstr "Lista Poligoanelor este goală. Intrerup." @@ -2782,8 +2782,8 @@ msgstr "Niciun poligon în selecție." msgid "Rough" msgstr "Grosier" -#: FlatCAMObj.py:1410 FlatCAMObj.py:1489 flatcamTools/ToolNCC.py:2086 -#: flatcamTools/ToolNCC.py:3137 flatcamTools/ToolNCC.py:3516 +#: FlatCAMObj.py:1410 FlatCAMObj.py:1489 flatcamTools/ToolNCC.py:2081 +#: flatcamTools/ToolNCC.py:3132 flatcamTools/ToolNCC.py:3511 msgid "Isolation geometry could not be generated." msgstr "Geometria de izolare nu a fost posibil să fie generată." @@ -2810,16 +2810,16 @@ msgstr "Nr. Tot. Sloturi" #: FlatCAMObj.py:2857 FlatCAMObj.py:3069 FlatCAMObj.py:3085 FlatCAMObj.py:3089 #: FlatCAMObj.py:4242 FlatCAMObj.py:4667 FlatCAMObj.py:4703 #: flatcamGUI/ObjectUI.py:817 flatcamGUI/ObjectUI.py:1660 -#: flatcamTools/ToolNCC.py:331 flatcamTools/ToolNCC.py:794 -#: flatcamTools/ToolNCC.py:808 flatcamTools/ToolNCC.py:1189 -#: flatcamTools/ToolPaint.py:314 flatcamTools/ToolPaint.py:764 -#: flatcamTools/ToolPaint.py:776 flatcamTools/ToolPaint.py:1159 +#: flatcamTools/ToolNCC.py:331 flatcamTools/ToolNCC.py:797 +#: flatcamTools/ToolNCC.py:811 flatcamTools/ToolNCC.py:1191 +#: flatcamTools/ToolPaint.py:314 flatcamTools/ToolPaint.py:767 +#: flatcamTools/ToolPaint.py:779 flatcamTools/ToolPaint.py:1166 msgid "Parameters for" msgstr "Parametri pt" #: FlatCAMObj.py:2857 FlatCAMObj.py:3089 FlatCAMObj.py:4242 FlatCAMObj.py:4703 -#: flatcamTools/ToolNCC.py:808 flatcamTools/ToolNCC.py:1189 -#: flatcamTools/ToolPaint.py:776 flatcamTools/ToolPaint.py:1159 +#: flatcamTools/ToolNCC.py:811 flatcamTools/ToolNCC.py:1191 +#: flatcamTools/ToolPaint.py:779 flatcamTools/ToolPaint.py:1166 msgid "Multiple Tools" msgstr "Unelte multiple" @@ -2831,8 +2831,8 @@ msgstr "Nici-o Unealtă selectată" #: flatcamEditors/FlatCAMGeoEditor.py:406 flatcamGUI/FlatCAMGUI.py:496 #: flatcamGUI/FlatCAMGUI.py:1143 flatcamGUI/ObjectUI.py:817 #: flatcamGUI/ObjectUI.py:1660 flatcamTools/ToolNCC.py:331 -#: flatcamTools/ToolNCC.py:794 flatcamTools/ToolPaint.py:314 -#: flatcamTools/ToolPaint.py:764 +#: flatcamTools/ToolNCC.py:797 flatcamTools/ToolPaint.py:314 +#: flatcamTools/ToolPaint.py:767 msgid "Tool" msgstr "Unealta" @@ -2891,7 +2891,7 @@ msgstr "Viteza motor" msgid "Generating CNC Code" msgstr "CNC Code in curs de generare" -#: FlatCAMObj.py:3966 flatcamTools/ToolNCC.py:916 flatcamTools/ToolPaint.py:841 +#: FlatCAMObj.py:3966 flatcamTools/ToolNCC.py:918 flatcamTools/ToolPaint.py:844 msgid "Current Tool parameters were applied to all tools." msgstr "Parametrii Uneltei curente sunt aplicați la toate Uneltele." @@ -2925,8 +2925,8 @@ msgstr "Copiază" #: flatcamEditors/FlatCAMGeoEditor.py:1174 #: flatcamEditors/FlatCAMGeoEditor.py:1218 #: flatcamEditors/FlatCAMGeoEditor.py:1253 -#: flatcamEditors/FlatCAMGeoEditor.py:1281 flatcamTools/ToolNCC.py:1502 -#: flatcamTools/ToolPaint.py:1237 flatcamTools/ToolPaint.py:1408 +#: flatcamEditors/FlatCAMGeoEditor.py:1281 flatcamTools/ToolNCC.py:1493 +#: flatcamTools/ToolPaint.py:1244 flatcamTools/ToolPaint.py:1415 #: flatcamTools/ToolSolderPaste.py:883 flatcamTools/ToolSolderPaste.py:956 msgid "Wrong value format entered, use a number." msgstr "Valoare in format incorect, foloseşte un număr." @@ -4026,7 +4026,7 @@ msgstr "Pictează" #: flatcamEditors/FlatCAMGeoEditor.py:548 flatcamGUI/FlatCAMGUI.py:909 #: flatcamGUI/FlatCAMGUI.py:2588 flatcamGUI/ObjectUI.py:2057 -#: flatcamTools/ToolPaint.py:43 flatcamTools/ToolPaint.py:735 +#: flatcamTools/ToolPaint.py:43 flatcamTools/ToolPaint.py:738 msgid "Paint Tool" msgstr "Unealta Paint" @@ -4661,8 +4661,8 @@ msgstr "Click pe punctul opus pentru terminare ..." msgid "Done. Rectangle completed." msgstr "Executat. Adăugare Pătrat terminată." -#: flatcamEditors/FlatCAMGeoEditor.py:2411 flatcamTools/ToolNCC.py:1737 -#: flatcamTools/ToolPaint.py:1616 +#: flatcamEditors/FlatCAMGeoEditor.py:2411 flatcamTools/ToolNCC.py:1728 +#: flatcamTools/ToolPaint.py:1623 msgid "Click on next Point or click right mouse button to complete ..." msgstr "" "Click pe punctul următor sau click buton dreapta al mousului pentru " @@ -6396,7 +6396,7 @@ msgstr "Unealta Decupare" #: flatcamGUI/FlatCAMGUI.py:907 flatcamGUI/FlatCAMGUI.py:2586 #: flatcamGUI/ObjectUI.py:573 flatcamGUI/ObjectUI.py:2075 -#: flatcamTools/ToolNCC.py:972 +#: flatcamTools/ToolNCC.py:974 msgid "NCC Tool" msgstr "Unealta NCC" @@ -7208,8 +7208,8 @@ msgstr "Nou" #: flatcamTools/ToolCopperThieving.py:159 #: flatcamTools/ToolCopperThieving.py:605 flatcamTools/ToolDblSided.py:226 #: flatcamTools/ToolFilm.py:359 flatcamTools/ToolNCC.py:558 -#: flatcamTools/ToolNCC.py:1293 flatcamTools/ToolPaint.py:502 -#: flatcamTools/ToolPaint.py:703 flatcamTools/ToolPanelize.py:374 +#: flatcamTools/ToolNCC.py:1295 flatcamTools/ToolPaint.py:502 +#: flatcamTools/ToolPaint.py:706 flatcamTools/ToolPanelize.py:374 #: flatcamTools/ToolPunchGerber.py:149 flatcamTools/ToolPunchGerber.py:164 msgid "Excellon" msgstr "Excellon" @@ -7383,8 +7383,8 @@ msgstr "Anulat. Nimic nu este selectat pentru mutare." msgid "New Tool ..." msgstr "O noua Unealtă ..." -#: flatcamGUI/FlatCAMGUI.py:4000 flatcamTools/ToolNCC.py:922 -#: flatcamTools/ToolPaint.py:847 flatcamTools/ToolSolderPaste.py:560 +#: flatcamGUI/FlatCAMGUI.py:4000 flatcamTools/ToolNCC.py:924 +#: flatcamTools/ToolPaint.py:850 flatcamTools/ToolSolderPaste.py:560 msgid "Enter a Tool Diameter" msgstr "Introduceti un Diametru de Unealtă" @@ -8625,8 +8625,8 @@ msgstr "" "in exterior sau poate fi negativă pentru un ofset in interior." #: flatcamGUI/ObjectUI.py:1578 flatcamTools/ToolNCC.py:209 -#: flatcamTools/ToolNCC.py:921 flatcamTools/ToolPaint.py:192 -#: flatcamTools/ToolPaint.py:846 flatcamTools/ToolSolderPaste.py:559 +#: flatcamTools/ToolNCC.py:923 flatcamTools/ToolPaint.py:192 +#: flatcamTools/ToolPaint.py:849 flatcamTools/ToolSolderPaste.py:559 msgid "New Tool" msgstr "O Noua Unealtă" @@ -8640,7 +8640,7 @@ msgstr "" #: flatcamGUI/ObjectUI.py:1600 flatcamTools/ToolNCC.py:300 #: flatcamTools/ToolNCC.py:634 flatcamTools/ToolPaint.py:283 -#: flatcamTools/ToolPaint.py:676 +#: flatcamTools/ToolPaint.py:679 msgid "Add from DB" msgstr "Adaugă Unealtă din DB" @@ -11389,21 +11389,21 @@ msgstr "" #: flatcamGUI/PreferencesUI.py:5588 flatcamGUI/PreferencesUI.py:6119 #: flatcamGUI/PreferencesUI.py:7696 flatcamTools/ToolCopperThieving.py:127 -#: flatcamTools/ToolNCC.py:535 flatcamTools/ToolNCC.py:1309 -#: flatcamTools/ToolNCC.py:1651 flatcamTools/ToolNCC.py:1935 -#: flatcamTools/ToolNCC.py:1990 flatcamTools/ToolPaint.py:486 -#: flatcamTools/ToolPaint.py:939 flatcamTools/ToolPaint.py:1440 +#: flatcamTools/ToolNCC.py:535 flatcamTools/ToolNCC.py:1311 +#: flatcamTools/ToolNCC.py:1642 flatcamTools/ToolNCC.py:1930 +#: flatcamTools/ToolNCC.py:1985 flatcamTools/ToolPaint.py:486 +#: flatcamTools/ToolPaint.py:946 flatcamTools/ToolPaint.py:1447 msgid "Area Selection" msgstr "Selecţie zonă" #: flatcamGUI/PreferencesUI.py:5588 flatcamGUI/PreferencesUI.py:6119 #: flatcamGUI/PreferencesUI.py:7697 flatcamTools/ToolCopperThieving.py:128 #: flatcamTools/ToolDblSided.py:217 flatcamTools/ToolNCC.py:535 -#: flatcamTools/ToolNCC.py:1667 flatcamTools/ToolNCC.py:1941 -#: flatcamTools/ToolNCC.py:1998 flatcamTools/ToolNCC.py:2306 -#: flatcamTools/ToolNCC.py:2586 flatcamTools/ToolNCC.py:3012 -#: flatcamTools/ToolPaint.py:486 flatcamTools/ToolPaint.py:924 -#: flatcamTools/ToolPaint.py:1456 tclCommands/TclCommandCopperClear.py:192 +#: flatcamTools/ToolNCC.py:1658 flatcamTools/ToolNCC.py:1936 +#: flatcamTools/ToolNCC.py:1993 flatcamTools/ToolNCC.py:2301 +#: flatcamTools/ToolNCC.py:2581 flatcamTools/ToolNCC.py:3007 +#: flatcamTools/ToolPaint.py:486 flatcamTools/ToolPaint.py:931 +#: flatcamTools/ToolPaint.py:1463 tclCommands/TclCommandCopperClear.py:192 #: tclCommands/TclCommandPaint.py:166 msgid "Reference Object" msgstr "Obiect Ref" @@ -11667,7 +11667,7 @@ msgstr "" "- „Obiect de referință” - se va procesa zona specificată de un alt obiect." #: flatcamGUI/PreferencesUI.py:6119 flatcamTools/ToolPaint.py:486 -#: flatcamTools/ToolPaint.py:935 flatcamTools/ToolPaint.py:1420 +#: flatcamTools/ToolPaint.py:942 flatcamTools/ToolPaint.py:1427 #: tclCommands/TclCommandPaint.py:164 msgid "Polygon Selection" msgstr "Selecție Poligon" @@ -14371,8 +14371,8 @@ msgstr "Unealta Copper Thieving efectuata." #: flatcamTools/ToolCopperThieving.py:760 #: flatcamTools/ToolCopperThieving.py:793 flatcamTools/ToolCutOut.py:480 #: flatcamTools/ToolCutOut.py:667 flatcamTools/ToolInvertGerber.py:208 -#: flatcamTools/ToolNCC.py:1603 flatcamTools/ToolNCC.py:1644 -#: flatcamTools/ToolNCC.py:1673 flatcamTools/ToolPaint.py:1462 +#: flatcamTools/ToolNCC.py:1594 flatcamTools/ToolNCC.py:1635 +#: flatcamTools/ToolNCC.py:1664 flatcamTools/ToolPaint.py:1469 #: flatcamTools/ToolPanelize.py:413 flatcamTools/ToolPanelize.py:428 #: flatcamTools/ToolSub.py:294 flatcamTools/ToolSub.py:307 #: flatcamTools/ToolSub.py:498 flatcamTools/ToolSub.py:513 @@ -14380,7 +14380,7 @@ msgstr "Unealta Copper Thieving efectuata." msgid "Could not retrieve object" msgstr "Nu s-a putut incărca obiectul" -#: flatcamTools/ToolCopperThieving.py:770 flatcamTools/ToolNCC.py:1652 +#: flatcamTools/ToolCopperThieving.py:770 flatcamTools/ToolNCC.py:1643 msgid "Click the start point of the area." msgstr "Faceți clic pe punctul de pornire al zonei." @@ -14388,9 +14388,9 @@ msgstr "Faceți clic pe punctul de pornire al zonei." msgid "Click the end point of the filling area." msgstr "Faceți clic pe punctul final al zonei de umplere." -#: flatcamTools/ToolCopperThieving.py:827 flatcamTools/ToolNCC.py:1714 -#: flatcamTools/ToolNCC.py:1766 flatcamTools/ToolPaint.py:1594 -#: flatcamTools/ToolPaint.py:1645 +#: flatcamTools/ToolCopperThieving.py:827 flatcamTools/ToolNCC.py:1705 +#: flatcamTools/ToolNCC.py:1757 flatcamTools/ToolPaint.py:1601 +#: flatcamTools/ToolPaint.py:1652 msgid "Zone added. Click to start adding next zone or right click to finish." msgstr "" "Zona adăugată. Faceți clic stanga pt a continua adăugarea de zone sau click " @@ -14423,14 +14423,14 @@ msgstr "Se lucrează..." msgid "Geometry not supported for bounding box" msgstr "Geometria nu este acceptată pentru caseta de delimitare" -#: flatcamTools/ToolCopperThieving.py:1068 flatcamTools/ToolNCC.py:1933 -#: flatcamTools/ToolNCC.py:1988 flatcamTools/ToolNCC.py:2992 -#: flatcamTools/ToolPaint.py:3368 +#: flatcamTools/ToolCopperThieving.py:1068 flatcamTools/ToolNCC.py:1928 +#: flatcamTools/ToolNCC.py:1983 flatcamTools/ToolNCC.py:2987 +#: flatcamTools/ToolPaint.py:3375 msgid "No object available." msgstr "Nici-un obiect disponibil." -#: flatcamTools/ToolCopperThieving.py:1105 flatcamTools/ToolNCC.py:1958 -#: flatcamTools/ToolNCC.py:2011 flatcamTools/ToolNCC.py:3034 +#: flatcamTools/ToolCopperThieving.py:1105 flatcamTools/ToolNCC.py:1953 +#: flatcamTools/ToolNCC.py:2006 flatcamTools/ToolNCC.py:3029 msgid "The reference object type is not supported." msgstr "Tipul de obiect de referintă nu este acceptat." @@ -14655,7 +14655,7 @@ msgid "Any form CutOut operation finished." msgstr "Operatia de decupaj cu formă liberă s-a terminat." #: flatcamTools/ToolCutOut.py:671 flatcamTools/ToolInvertGerber.py:214 -#: flatcamTools/ToolNCC.py:1607 flatcamTools/ToolPaint.py:1385 +#: flatcamTools/ToolNCC.py:1598 flatcamTools/ToolPaint.py:1392 #: flatcamTools/ToolPanelize.py:418 tclCommands/TclCommandBbox.py:72 #: tclCommands/TclCommandNregions.py:72 msgid "Object not found" @@ -15778,120 +15778,120 @@ msgstr "" msgid "Generate Geometry" msgstr "Genereza Geometrie" -#: flatcamTools/ToolNCC.py:1429 flatcamTools/ToolPaint.py:1172 +#: flatcamTools/ToolNCC.py:1420 flatcamTools/ToolPaint.py:1179 #: flatcamTools/ToolSolderPaste.py:888 msgid "Please enter a tool diameter to add, in Float format." msgstr "Introduce diametrul unei unelte pt a fi adăugată, in format Real." -#: flatcamTools/ToolNCC.py:1460 flatcamTools/ToolNCC.py:4013 -#: flatcamTools/ToolPaint.py:1196 flatcamTools/ToolPaint.py:3587 +#: flatcamTools/ToolNCC.py:1451 flatcamTools/ToolNCC.py:4008 +#: flatcamTools/ToolPaint.py:1203 flatcamTools/ToolPaint.py:3598 #: flatcamTools/ToolSolderPaste.py:917 msgid "Cancelled. Tool already in Tool Table." msgstr "Anulat. Unealta există deja in Tabela de Unelte." -#: flatcamTools/ToolNCC.py:1467 flatcamTools/ToolNCC.py:4030 -#: flatcamTools/ToolPaint.py:1201 flatcamTools/ToolPaint.py:3604 +#: flatcamTools/ToolNCC.py:1458 flatcamTools/ToolNCC.py:4025 +#: flatcamTools/ToolPaint.py:1208 flatcamTools/ToolPaint.py:3615 msgid "New tool added to Tool Table." msgstr "O noua unealtă a fost adăugată in Tabela de Unelte." -#: flatcamTools/ToolNCC.py:1511 flatcamTools/ToolPaint.py:1245 +#: flatcamTools/ToolNCC.py:1502 flatcamTools/ToolPaint.py:1252 msgid "Tool from Tool Table was edited." msgstr "O unealtă din Tabela de Unelte a fost editata." -#: flatcamTools/ToolNCC.py:1523 flatcamTools/ToolPaint.py:1257 +#: flatcamTools/ToolNCC.py:1514 flatcamTools/ToolPaint.py:1264 #: flatcamTools/ToolSolderPaste.py:977 msgid "Cancelled. New diameter value is already in the Tool Table." msgstr "" "Anulat. Noua valoare pt diametrul uneltei este deja in Tabela de Unelte." -#: flatcamTools/ToolNCC.py:1575 flatcamTools/ToolPaint.py:1355 +#: flatcamTools/ToolNCC.py:1566 flatcamTools/ToolPaint.py:1362 msgid "Delete failed. Select a tool to delete." msgstr "Ștergere eșuată. Selectează o unealtă pt ștergere." -#: flatcamTools/ToolNCC.py:1581 flatcamTools/ToolPaint.py:1361 +#: flatcamTools/ToolNCC.py:1572 flatcamTools/ToolPaint.py:1368 msgid "Tool(s) deleted from Tool Table." msgstr "Au fost șterse unelte din Tabela de Unelte." -#: flatcamTools/ToolNCC.py:1623 +#: flatcamTools/ToolNCC.py:1614 msgid "Wrong Tool Dia value format entered, use a number." msgstr "Diametrul uneltei este in format gresit, foloseşte un număr Real." -#: flatcamTools/ToolNCC.py:1632 flatcamTools/ToolPaint.py:1412 +#: flatcamTools/ToolNCC.py:1623 flatcamTools/ToolPaint.py:1419 msgid "No selected tools in Tool Table." msgstr "Nu sunt unelte selectate in Tabela de Unelte." -#: flatcamTools/ToolNCC.py:1708 flatcamTools/ToolPaint.py:1588 +#: flatcamTools/ToolNCC.py:1699 flatcamTools/ToolPaint.py:1595 msgid "Click the end point of the paint area." msgstr "Faceți clic pe punctul final al zonei de pictat." -#: flatcamTools/ToolNCC.py:1976 flatcamTools/ToolNCC.py:2964 +#: flatcamTools/ToolNCC.py:1971 flatcamTools/ToolNCC.py:2959 msgid "NCC Tool. Preparing non-copper polygons." msgstr "Unealta NCC. Se pregătesc poligoanele non-cupru." -#: flatcamTools/ToolNCC.py:2035 flatcamTools/ToolNCC.py:3092 +#: flatcamTools/ToolNCC.py:2030 flatcamTools/ToolNCC.py:3087 msgid "NCC Tool. Calculate 'empty' area." msgstr "Unealta NCC. Calculează aria 'goală'." -#: flatcamTools/ToolNCC.py:2054 flatcamTools/ToolNCC.py:2160 -#: flatcamTools/ToolNCC.py:2174 flatcamTools/ToolNCC.py:3105 -#: flatcamTools/ToolNCC.py:3210 flatcamTools/ToolNCC.py:3225 -#: flatcamTools/ToolNCC.py:3491 flatcamTools/ToolNCC.py:3592 -#: flatcamTools/ToolNCC.py:3607 +#: flatcamTools/ToolNCC.py:2049 flatcamTools/ToolNCC.py:2155 +#: flatcamTools/ToolNCC.py:2169 flatcamTools/ToolNCC.py:3100 +#: flatcamTools/ToolNCC.py:3205 flatcamTools/ToolNCC.py:3220 +#: flatcamTools/ToolNCC.py:3486 flatcamTools/ToolNCC.py:3587 +#: flatcamTools/ToolNCC.py:3602 msgid "Buffering finished" msgstr "Buferarea terminată" -#: flatcamTools/ToolNCC.py:2062 flatcamTools/ToolNCC.py:2181 -#: flatcamTools/ToolNCC.py:3113 flatcamTools/ToolNCC.py:3232 -#: flatcamTools/ToolNCC.py:3498 flatcamTools/ToolNCC.py:3614 +#: flatcamTools/ToolNCC.py:2057 flatcamTools/ToolNCC.py:2176 +#: flatcamTools/ToolNCC.py:3108 flatcamTools/ToolNCC.py:3227 +#: flatcamTools/ToolNCC.py:3493 flatcamTools/ToolNCC.py:3609 msgid "Could not get the extent of the area to be non copper cleared." msgstr "" "Nu s-a putut obtine intinderea suprafaței care să fie curățată de cupru." -#: flatcamTools/ToolNCC.py:2089 flatcamTools/ToolNCC.py:2167 -#: flatcamTools/ToolNCC.py:3140 flatcamTools/ToolNCC.py:3217 -#: flatcamTools/ToolNCC.py:3518 flatcamTools/ToolNCC.py:3599 +#: flatcamTools/ToolNCC.py:2084 flatcamTools/ToolNCC.py:2162 +#: flatcamTools/ToolNCC.py:3135 flatcamTools/ToolNCC.py:3212 +#: flatcamTools/ToolNCC.py:3513 flatcamTools/ToolNCC.py:3594 msgid "" "Isolation geometry is broken. Margin is less than isolation tool diameter." msgstr "" "Geometria de Izolare este discontinuă.\n" "Marginea este mai mic decat diametrul uneltei de izolare." -#: flatcamTools/ToolNCC.py:2184 flatcamTools/ToolNCC.py:3236 -#: flatcamTools/ToolNCC.py:3617 +#: flatcamTools/ToolNCC.py:2179 flatcamTools/ToolNCC.py:3231 +#: flatcamTools/ToolNCC.py:3612 msgid "The selected object is not suitable for copper clearing." msgstr "Obiectul selectat nu este potrivit pentru curățarea cuprului." -#: flatcamTools/ToolNCC.py:2191 flatcamTools/ToolNCC.py:3243 +#: flatcamTools/ToolNCC.py:2186 flatcamTools/ToolNCC.py:3238 msgid "NCC Tool. Finished calculation of 'empty' area." msgstr "Unealta NCC. S-a terminat calculul suprafetei 'goale'." -#: flatcamTools/ToolNCC.py:2222 flatcamTools/ToolNCC.py:2224 -#: flatcamTools/ToolNCC.py:2916 flatcamTools/ToolNCC.py:2918 +#: flatcamTools/ToolNCC.py:2217 flatcamTools/ToolNCC.py:2219 +#: flatcamTools/ToolNCC.py:2911 flatcamTools/ToolNCC.py:2913 msgid "Non-Copper clearing ..." msgstr "Curățare Non-Cupru ..." -#: flatcamTools/ToolNCC.py:2278 flatcamTools/ToolNCC.py:3060 +#: flatcamTools/ToolNCC.py:2273 flatcamTools/ToolNCC.py:3055 msgid "" "NCC Tool. Finished non-copper polygons. Normal copper clearing task started." msgstr "" "Unelata NCC. S-a terminat pregătirea poligoanelor non-cupru. Taskul de " "curatare normal de cupru a inceput." -#: flatcamTools/ToolNCC.py:2312 flatcamTools/ToolNCC.py:2592 +#: flatcamTools/ToolNCC.py:2307 flatcamTools/ToolNCC.py:2587 msgid "NCC Tool failed creating bounding box." msgstr "Unealta NCC a esuat in a crea forma inconjurătoare." -#: flatcamTools/ToolNCC.py:2326 flatcamTools/ToolNCC.py:2609 -#: flatcamTools/ToolNCC.py:3256 flatcamTools/ToolNCC.py:3642 +#: flatcamTools/ToolNCC.py:2321 flatcamTools/ToolNCC.py:2604 +#: flatcamTools/ToolNCC.py:3251 flatcamTools/ToolNCC.py:3637 msgid "NCC Tool clearing with tool diameter" msgstr "Unealta NCC cu diametrul uneltei" -#: flatcamTools/ToolNCC.py:2326 flatcamTools/ToolNCC.py:2609 -#: flatcamTools/ToolNCC.py:3256 flatcamTools/ToolNCC.py:3642 +#: flatcamTools/ToolNCC.py:2321 flatcamTools/ToolNCC.py:2604 +#: flatcamTools/ToolNCC.py:3251 flatcamTools/ToolNCC.py:3637 msgid "started." msgstr "a inceput." -#: flatcamTools/ToolNCC.py:2518 flatcamTools/ToolNCC.py:3417 +#: flatcamTools/ToolNCC.py:2513 flatcamTools/ToolNCC.py:3412 msgid "" "There is no NCC Geometry in the file.\n" "Usually it means that the tool diameter is too big for the painted " @@ -15903,25 +15903,25 @@ msgstr "" "pictată.\n" "Schimbați parametrii Paint și încercați din nou." -#: flatcamTools/ToolNCC.py:2527 flatcamTools/ToolNCC.py:3426 +#: flatcamTools/ToolNCC.py:2522 flatcamTools/ToolNCC.py:3421 msgid "NCC Tool clear all done." msgstr "Unealta NCC curătare toate efectuată." -#: flatcamTools/ToolNCC.py:2530 flatcamTools/ToolNCC.py:3429 +#: flatcamTools/ToolNCC.py:2525 flatcamTools/ToolNCC.py:3424 msgid "NCC Tool clear all done but the copper features isolation is broken for" msgstr "" "Unealta NCC curătare toate efectuată dar izolatia este intreruptă pentru" -#: flatcamTools/ToolNCC.py:2532 flatcamTools/ToolNCC.py:2817 -#: flatcamTools/ToolNCC.py:3431 flatcamTools/ToolNCC.py:3814 +#: flatcamTools/ToolNCC.py:2527 flatcamTools/ToolNCC.py:2812 +#: flatcamTools/ToolNCC.py:3426 flatcamTools/ToolNCC.py:3809 msgid "tools" msgstr "unelte" -#: flatcamTools/ToolNCC.py:2813 flatcamTools/ToolNCC.py:3810 +#: flatcamTools/ToolNCC.py:2808 flatcamTools/ToolNCC.py:3805 msgid "NCC Tool Rest Machining clear all done." msgstr "Unealta NCC curătare cu prelucrare tip 'rest' efectuată." -#: flatcamTools/ToolNCC.py:2816 flatcamTools/ToolNCC.py:3813 +#: flatcamTools/ToolNCC.py:2811 flatcamTools/ToolNCC.py:3808 msgid "" "NCC Tool Rest Machining clear all done but the copper features isolation is " "broken for" @@ -15929,11 +15929,11 @@ msgstr "" "Unealta NCC curătare toate cu prelucrare tip 'rest' efectuată dar izolatia " "este intreruptă pentru" -#: flatcamTools/ToolNCC.py:2928 +#: flatcamTools/ToolNCC.py:2923 msgid "NCC Tool started. Reading parameters." msgstr "Unealta NCC a pornit. Se citesc parametrii." -#: flatcamTools/ToolNCC.py:3906 +#: flatcamTools/ToolNCC.py:3901 msgid "" "Try to use the Buffering Type = Full in Preferences -> Gerber General. " "Reload the Gerber file after this change." @@ -16190,99 +16190,99 @@ msgstr "" "- „Obiect de referință” - va face o curățare fără cupru în zona specificată " "de un alt obiect." -#: flatcamTools/ToolPaint.py:1381 +#: flatcamTools/ToolPaint.py:1388 #, python-format msgid "Could not retrieve object: %s" msgstr "Nu s-a putut incărca obiectul: %s" -#: flatcamTools/ToolPaint.py:1391 +#: flatcamTools/ToolPaint.py:1398 msgid "Can't do Paint on MultiGeo geometries" msgstr "Nu se poate face 'pictare' pe geometrii MultiGeo" -#: flatcamTools/ToolPaint.py:1421 +#: flatcamTools/ToolPaint.py:1428 msgid "Click on a polygon to paint it." msgstr "Faceți clic pe un poligon pentru a-l picta." -#: flatcamTools/ToolPaint.py:1441 +#: flatcamTools/ToolPaint.py:1448 msgid "Click the start point of the paint area." msgstr "Faceți clic pe punctul de pornire al zonei de pictat." -#: flatcamTools/ToolPaint.py:1506 +#: flatcamTools/ToolPaint.py:1513 msgid "Click to add next polygon or right click to start painting." msgstr "" "Faceți clic pentru a adăuga următorul poligon sau faceți clic dreapta pentru " "a începe Paint." -#: flatcamTools/ToolPaint.py:1519 +#: flatcamTools/ToolPaint.py:1526 msgid "Click to add/remove next polygon or right click to start painting." msgstr "" "Faceți clic pentru a adăuga / elimina următorul poligon sau faceți clic " "dreapta pentru a începe Paint." -#: flatcamTools/ToolPaint.py:2017 +#: flatcamTools/ToolPaint.py:2024 msgid "Painting polygon with method: lines." msgstr "Se pictează poligonul cu metoda: linii." -#: flatcamTools/ToolPaint.py:2029 +#: flatcamTools/ToolPaint.py:2036 msgid "Failed. Painting polygon with method: seed." msgstr "Esuat. Se pictează poligonul cu metoda: sămantă." -#: flatcamTools/ToolPaint.py:2040 +#: flatcamTools/ToolPaint.py:2047 msgid "Failed. Painting polygon with method: standard." msgstr "Esuat. Se picteaza poligonul cu metoda: standard." -#: flatcamTools/ToolPaint.py:2056 +#: flatcamTools/ToolPaint.py:2063 msgid "Geometry could not be painted completely" msgstr "Geometria nu a fost posibil să fie 'pictată' complet" -#: flatcamTools/ToolPaint.py:2085 flatcamTools/ToolPaint.py:2088 -#: flatcamTools/ToolPaint.py:2096 flatcamTools/ToolPaint.py:2399 -#: flatcamTools/ToolPaint.py:2402 flatcamTools/ToolPaint.py:2410 -#: flatcamTools/ToolPaint.py:2898 flatcamTools/ToolPaint.py:2901 -#: flatcamTools/ToolPaint.py:2907 +#: flatcamTools/ToolPaint.py:2092 flatcamTools/ToolPaint.py:2095 +#: flatcamTools/ToolPaint.py:2103 flatcamTools/ToolPaint.py:2406 +#: flatcamTools/ToolPaint.py:2409 flatcamTools/ToolPaint.py:2417 +#: flatcamTools/ToolPaint.py:2905 flatcamTools/ToolPaint.py:2908 +#: flatcamTools/ToolPaint.py:2914 msgid "Paint Tool." msgstr "Unealta Paint." -#: flatcamTools/ToolPaint.py:2085 flatcamTools/ToolPaint.py:2088 -#: flatcamTools/ToolPaint.py:2096 +#: flatcamTools/ToolPaint.py:2092 flatcamTools/ToolPaint.py:2095 +#: flatcamTools/ToolPaint.py:2103 msgid "Normal painting polygon task started." msgstr "Taskul de pictare normal a unui polygon a inceput." -#: flatcamTools/ToolPaint.py:2086 flatcamTools/ToolPaint.py:2400 -#: flatcamTools/ToolPaint.py:2899 +#: flatcamTools/ToolPaint.py:2093 flatcamTools/ToolPaint.py:2407 +#: flatcamTools/ToolPaint.py:2906 msgid "Buffering geometry..." msgstr "Crează o geometrie de tipul Bufer..." -#: flatcamTools/ToolPaint.py:2108 flatcamTools/ToolPaint.py:2417 -#: flatcamTools/ToolPaint.py:2915 +#: flatcamTools/ToolPaint.py:2115 flatcamTools/ToolPaint.py:2424 +#: flatcamTools/ToolPaint.py:2922 msgid "No polygon found." msgstr "Nu s-a gasit nici-un poligon." -#: flatcamTools/ToolPaint.py:2138 +#: flatcamTools/ToolPaint.py:2145 msgid "Painting polygon..." msgstr "Se 'pictează' un poligon..." -#: flatcamTools/ToolPaint.py:2148 flatcamTools/ToolPaint.py:2463 -#: flatcamTools/ToolPaint.py:2653 flatcamTools/ToolPaint.py:2961 -#: flatcamTools/ToolPaint.py:3140 +#: flatcamTools/ToolPaint.py:2155 flatcamTools/ToolPaint.py:2470 +#: flatcamTools/ToolPaint.py:2660 flatcamTools/ToolPaint.py:2968 +#: flatcamTools/ToolPaint.py:3147 msgid "Painting with tool diameter = " msgstr "Pictand cu o unealtă cu diametrul = " -#: flatcamTools/ToolPaint.py:2149 flatcamTools/ToolPaint.py:2464 -#: flatcamTools/ToolPaint.py:2654 flatcamTools/ToolPaint.py:2962 -#: flatcamTools/ToolPaint.py:3141 +#: flatcamTools/ToolPaint.py:2156 flatcamTools/ToolPaint.py:2471 +#: flatcamTools/ToolPaint.py:2661 flatcamTools/ToolPaint.py:2969 +#: flatcamTools/ToolPaint.py:3148 msgid "started" msgstr "a inceput" -#: flatcamTools/ToolPaint.py:2174 flatcamTools/ToolPaint.py:2490 -#: flatcamTools/ToolPaint.py:2680 flatcamTools/ToolPaint.py:2988 -#: flatcamTools/ToolPaint.py:3167 +#: flatcamTools/ToolPaint.py:2181 flatcamTools/ToolPaint.py:2497 +#: flatcamTools/ToolPaint.py:2687 flatcamTools/ToolPaint.py:2995 +#: flatcamTools/ToolPaint.py:3174 msgid "Margin parameter too big. Tool is not used" msgstr "Parametrul Margine este prea mare. Unealta nu este folosită" -#: flatcamTools/ToolPaint.py:2232 flatcamTools/ToolPaint.py:2559 -#: flatcamTools/ToolPaint.py:2737 flatcamTools/ToolPaint.py:3051 -#: flatcamTools/ToolPaint.py:3229 +#: flatcamTools/ToolPaint.py:2239 flatcamTools/ToolPaint.py:2566 +#: flatcamTools/ToolPaint.py:2744 flatcamTools/ToolPaint.py:3058 +#: flatcamTools/ToolPaint.py:3236 msgid "" "Could not do Paint. Try a different combination of parameters. Or a " "different strategy of paint" @@ -16290,9 +16290,9 @@ msgstr "" "Nu s-a putut face operatia de 'pictare'. Incearcă o combinaţie diferita de " "parametri. Sau o strategie diferita de 'pictare'" -#: flatcamTools/ToolPaint.py:2289 flatcamTools/ToolPaint.py:2625 -#: flatcamTools/ToolPaint.py:2794 flatcamTools/ToolPaint.py:3112 -#: flatcamTools/ToolPaint.py:3291 +#: flatcamTools/ToolPaint.py:2296 flatcamTools/ToolPaint.py:2632 +#: flatcamTools/ToolPaint.py:2801 flatcamTools/ToolPaint.py:3119 +#: flatcamTools/ToolPaint.py:3298 msgid "" "There is no Painting Geometry in the file.\n" "Usually it means that the tool diameter is too big for the painted " @@ -16304,58 +16304,58 @@ msgstr "" "geometrice.\n" "Schimbă parametrii de 'pictare' și încearcă din nou." -#: flatcamTools/ToolPaint.py:2312 +#: flatcamTools/ToolPaint.py:2319 msgid "Paint Single failed." msgstr "Pictarea unui polygon a esuat." -#: flatcamTools/ToolPaint.py:2318 +#: flatcamTools/ToolPaint.py:2325 msgid "Paint Single Done." msgstr "Pictarea unui polygon efectuată." -#: flatcamTools/ToolPaint.py:2320 flatcamTools/ToolPaint.py:2830 -#: flatcamTools/ToolPaint.py:3327 +#: flatcamTools/ToolPaint.py:2327 flatcamTools/ToolPaint.py:2837 +#: flatcamTools/ToolPaint.py:3334 msgid "Polygon Paint started ..." msgstr "Paint pt poligon a inceput ..." -#: flatcamTools/ToolPaint.py:2399 flatcamTools/ToolPaint.py:2402 -#: flatcamTools/ToolPaint.py:2410 +#: flatcamTools/ToolPaint.py:2406 flatcamTools/ToolPaint.py:2409 +#: flatcamTools/ToolPaint.py:2417 msgid "Paint all polygons task started." msgstr "Taskul de pictare pt toate poligoanele a inceput." -#: flatcamTools/ToolPaint.py:2441 flatcamTools/ToolPaint.py:2939 +#: flatcamTools/ToolPaint.py:2448 flatcamTools/ToolPaint.py:2946 msgid "Painting polygons..." msgstr "Se 'pictează' poligoane..." -#: flatcamTools/ToolPaint.py:2634 +#: flatcamTools/ToolPaint.py:2641 msgid "Paint All Done." msgstr "Pictarea Tuturor poligoanelor efectuată." -#: flatcamTools/ToolPaint.py:2803 flatcamTools/ToolPaint.py:3300 +#: flatcamTools/ToolPaint.py:2810 flatcamTools/ToolPaint.py:3307 msgid "Paint All with Rest-Machining done." msgstr "'Paint' pentru toate poligoanele cu strategia Rest a fost efectuată." -#: flatcamTools/ToolPaint.py:2822 +#: flatcamTools/ToolPaint.py:2829 msgid "Paint All failed." msgstr "Pictarea pt toate poligoanele a easuat." -#: flatcamTools/ToolPaint.py:2828 +#: flatcamTools/ToolPaint.py:2835 msgid "Paint Poly All Done." msgstr "Pictarea pt toate poligoanele efectuată." -#: flatcamTools/ToolPaint.py:2898 flatcamTools/ToolPaint.py:2901 -#: flatcamTools/ToolPaint.py:2907 +#: flatcamTools/ToolPaint.py:2905 flatcamTools/ToolPaint.py:2908 +#: flatcamTools/ToolPaint.py:2914 msgid "Painting area task started." msgstr "Taskul de pictare a unei arii a inceput." -#: flatcamTools/ToolPaint.py:3121 +#: flatcamTools/ToolPaint.py:3128 msgid "Paint Area Done." msgstr "Paint pt o zona efectuata." -#: flatcamTools/ToolPaint.py:3319 +#: flatcamTools/ToolPaint.py:3326 msgid "Paint Area failed." msgstr "Pictarea unei Zone a esuat." -#: flatcamTools/ToolPaint.py:3325 +#: flatcamTools/ToolPaint.py:3332 msgid "Paint Poly Area Done." msgstr "Paint pt o Zonă efectuat."