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

Merged in Beta_8.994 (pull request #322)

Beta - improvements
Marius Stanciu пре 5 година
родитељ
комит
9f0822ae5d
5 измењених фајлова са 445 додато и 331 уклоњено
  1. 3 1
      CHANGELOG.md
  2. 1 1
      appObjects/FlatCAMGerber.py
  3. 429 313
      appTools/ToolPunchGerber.py
  4. BIN
      locale/tr/LC_MESSAGES/strings.mo
  5. 12 16
      locale/tr/LC_MESSAGES/strings.po

+ 3 - 1
CHANGELOG.md

@@ -27,12 +27,14 @@ CHANGELOG for FlatCAM beta
 - fixed Tcl command Paint
 - fixed Tcl command Paint
 - temporary fix for comboboxes not finding the the value in the items when setting themselves with a value by defaulting to the first item in the list
 - temporary fix for comboboxes not finding the the value in the items when setting themselves with a value by defaulting to the first item in the list
 - fix in Tool Subtract where there was a typo
 - fix in Tool Subtract where there was a typo
+- upgraded the punch Gerber Tool
+- updated the Turkish translation strings (by Mehmet Kaya)
 
 
 27.10.2020
 27.10.2020
 
 
 - created custom classes derived from TextEdit and from LineEdit where I overloaded the context menu and I made all the other classes that were inheriting from them to inherit from those new classes
 - created custom classes derived from TextEdit and from LineEdit where I overloaded the context menu and I made all the other classes that were inheriting from them to inherit from those new classes
 - minor fix in ToolsDB2UI
 - minor fix in ToolsDB2UI
-- updated the Turkuish translation strings (by Mehmet Kaya)
+- updated the Turkish translation strings (by Mehmet Kaya)
 - fixed a bug in conversion of any to Gerber in the section of Excellon conversion
 - fixed a bug in conversion of any to Gerber in the section of Excellon conversion
 - some PEP8 fixes
 - some PEP8 fixes
 - fixed a bug due of recent chagnes in FileMenuHandlers class
 - fixed a bug due of recent chagnes in FileMenuHandlers class

+ 1 - 1
appObjects/FlatCAMGerber.py

@@ -212,7 +212,7 @@ class GerberObject(FlatCAMObj, Gerber):
             self.apertures_row = 0
             self.apertures_row = 0
             aper_no = self.apertures_row + 1
             aper_no = self.apertures_row + 1
             sort = []
             sort = []
-            for k, v in list(self.apertures.items()):
+            for k in list(self.apertures.keys()):
                 sort.append(int(k))
                 sort.append(int(k))
             sorted_apertures = sorted(sort)
             sorted_apertures = sorted(sort)
 
 

+ 429 - 313
appTools/ToolPunchGerber.py

@@ -8,7 +8,7 @@
 from PyQt5 import QtCore, QtWidgets, QtGui
 from PyQt5 import QtCore, QtWidgets, QtGui
 
 
 from appTool import AppTool
 from appTool import AppTool
-from appGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox, FCComboBox
+from appGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox, FCComboBox, FCTable
 
 
 from copy import deepcopy
 from copy import deepcopy
 import logging
 import logging
@@ -45,6 +45,8 @@ class ToolPunchGerber(AppTool):
         self.ui.reset_button.clicked.connect(self.set_tool_ui)
         self.ui.reset_button.clicked.connect(self.set_tool_ui)
         self.ui.punch_object_button.clicked.connect(self.on_generate_object)
         self.ui.punch_object_button.clicked.connect(self.on_generate_object)
 
 
+        self.ui.gerber_object_combo.currentIndexChanged.connect(self.build_tool_ui)
+
         self.ui.circular_cb.stateChanged.connect(
         self.ui.circular_cb.stateChanged.connect(
             lambda state:
             lambda state:
                 self.ui.circular_ring_entry.setDisabled(False) if state else
                 self.ui.circular_ring_entry.setDisabled(False) if state else
@@ -97,6 +99,7 @@ class ToolPunchGerber(AppTool):
         AppTool.run(self)
         AppTool.run(self)
 
 
         self.set_tool_ui()
         self.set_tool_ui()
+        self.build_tool_ui()
 
 
         self.app.ui.notebook.setTabText(2, _("Punch Tool"))
         self.app.ui.notebook.setTabText(2, _("Punch Tool"))
 
 
@@ -106,6 +109,7 @@ class ToolPunchGerber(AppTool):
     def set_tool_ui(self):
     def set_tool_ui(self):
         self.reset_fields()
         self.reset_fields()
 
 
+        self.ui_disconnect()
         self.ui_connect()
         self.ui_connect()
         self.ui.method_punch.set_value(self.app.defaults["tools_punch_hole_type"])
         self.ui.method_punch.set_value(self.app.defaults["tools_punch_hole_type"])
         self.ui.select_all_cb.set_value(False)
         self.ui.select_all_cb.set_value(False)
@@ -126,6 +130,69 @@ class ToolPunchGerber(AppTool):
 
 
         self.ui.factor_entry.set_value(float(self.app.defaults["tools_punch_hole_prop_factor"]))
         self.ui.factor_entry.set_value(float(self.app.defaults["tools_punch_hole_prop_factor"]))
 
 
+    def build_tool_ui(self):
+        # get the Gerber file who is the source of the punched Gerber
+        selection_index = self.ui.gerber_object_combo.currentIndex()
+        model_index = self.app.collection.index(selection_index, 0, self.ui.gerber_object_combo.rootModelIndex())
+        obj = None
+
+        try:
+            obj = model_index.internalPointer().obj
+            sort = [int(k) for k in obj.apertures.keys()]
+            sorted_apertures = sorted(sort)
+        except Exception:
+            # no object loaded
+            sorted_apertures = []
+
+        n = len(sorted_apertures)
+        self.ui.apertures_table.setRowCount(n)
+
+        row = 0
+        for ap_code in sorted_apertures:
+            ap_code = str(ap_code)
+
+            ap_code_item = QtWidgets.QTableWidgetItem(ap_code)
+            ap_code_item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
+
+            ap_type_item = QtWidgets.QTableWidgetItem(str(obj.apertures[ap_code]['type']))
+            ap_type_item.setFlags(QtCore.Qt.ItemIsEnabled)
+
+            try:
+                if obj.apertures[ap_code]['size'] is not None:
+                    size_val = self.app.dec_format(float(obj.apertures[ap_code]['size']), self.decimals)
+                    ap_size_item = QtWidgets.QTableWidgetItem(str(size_val))
+                else:
+                    ap_size_item = QtWidgets.QTableWidgetItem('')
+            except KeyError:
+                ap_size_item = QtWidgets.QTableWidgetItem('')
+            ap_size_item.setFlags(QtCore.Qt.ItemIsEnabled)
+
+            self.ui.apertures_table.setItem(row, 0, ap_code_item)  # Aperture Code
+            self.ui.apertures_table.setItem(row, 1, ap_type_item)  # Aperture Type
+            self.ui.apertures_table.setItem(row, 2, ap_size_item)  # Aperture Dimensions
+
+            # increment row
+            row += 1
+
+        self.ui.apertures_table.resizeColumnsToContents()
+        self.ui.apertures_table.resizeRowsToContents()
+
+        vertical_header = self.ui.apertures_table.verticalHeader()
+        vertical_header.hide()
+        # self.ui.apertures_table.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
+
+        horizontal_header = self.ui.apertures_table.horizontalHeader()
+        horizontal_header.setMinimumSectionSize(10)
+        horizontal_header.setDefaultSectionSize(70)
+        horizontal_header.setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeToContents)
+        horizontal_header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents)
+        horizontal_header.setSectionResizeMode(2, QtWidgets.QHeaderView.Stretch)
+
+        self.ui.apertures_table.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
+        self.ui.apertures_table.setSortingEnabled(False)
+        # self.ui.apertures_table.setMinimumHeight(self.ui.apertures_table.getHeight())
+        # self.ui.apertures_table.setMaximumHeight(self.ui.apertures_table.getHeight())
+
     def on_select_all(self, state):
     def on_select_all(self, state):
         self.ui_disconnect()
         self.ui_disconnect()
         if state:
         if state:
@@ -143,29 +210,29 @@ class ToolPunchGerber(AppTool):
         self.ui_connect()
         self.ui_connect()
 
 
     def on_method(self, val):
     def on_method(self, val):
-        self.ui.exc_label.setEnabled(False)
-        self.ui.exc_combo.setEnabled(False)
-        self.ui.fixed_label.setEnabled(False)
-        self.ui.dia_label.setEnabled(False)
-        self.ui.dia_entry.setEnabled(False)
-        self.ui.ring_frame.setEnabled(False)
-        self.ui.prop_label.setEnabled(False)
-        self.ui.factor_label.setEnabled(False)
-        self.ui.factor_entry.setEnabled(False)
+        self.ui.exc_label.hide()
+        self.ui.exc_combo.hide()
+        self.ui.fixed_label.hide()
+        self.ui.dia_label.hide()
+        self.ui.dia_entry.hide()
+        self.ui.ring_frame.hide()
+        self.ui.prop_label.hide()
+        self.ui.factor_label.hide()
+        self.ui.factor_entry.hide()
 
 
         if val == 'exc':
         if val == 'exc':
-            self.ui.exc_label.setEnabled(True)
-            self.ui.exc_combo.setEnabled(True)
+            self.ui.exc_label.show()
+            self.ui.exc_combo.show()
         elif val == 'fixed':
         elif val == 'fixed':
-            self.ui.fixed_label.setEnabled(True)
-            self.ui.dia_label.setEnabled(True)
-            self.ui.dia_entry.setEnabled(True)
+            self.ui.fixed_label.show()
+            self.ui.dia_label.show()
+            self.ui.dia_entry.show()
         elif val == 'ring':
         elif val == 'ring':
-            self.ui.ring_frame.setEnabled(True)
+            self.ui.ring_frame.show()
         elif val == 'prop':
         elif val == 'prop':
-            self.ui.prop_label.setEnabled(True)
-            self.ui.factor_label.setEnabled(True)
-            self.ui.factor_entry.setEnabled(True)
+            self.ui.prop_label.show()
+            self.ui.factor_label.show()
+            self.ui.factor_entry.show()
 
 
     def ui_connect(self):
     def ui_connect(self):
         self.ui.select_all_cb.stateChanged.connect(self.on_select_all)
         self.ui.select_all_cb.stateChanged.connect(self.on_select_all)
@@ -192,97 +259,114 @@ class ToolPunchGerber(AppTool):
         outname = name + "_punched"
         outname = name + "_punched"
 
 
         punch_method = self.ui.method_punch.get_value()
         punch_method = self.ui.method_punch.get_value()
+        if punch_method == 'exc':
+            self.on_excellon_method(grb_obj, outname)
+        elif punch_method == 'fixed':
+            self.on_fixed_method(grb_obj, outname)
+        elif punch_method == 'ring':
+            self.on_ring_method(grb_obj, outname)
+        elif punch_method == 'prop':
+            self.on_proportional_method(grb_obj, outname)
+
+    def on_excellon_method(self, grb_obj, outname):
+        # get the Excellon file whose geometry will create the punch holes
+        selection_index = self.ui.exc_combo.currentIndex()
+        model_index = self.app.collection.index(selection_index, 0, self.ui.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
 
 
         new_options = {}
         new_options = {}
         for opt in grb_obj.options:
         for opt in grb_obj.options:
             new_options[opt] = deepcopy(grb_obj.options[opt])
             new_options[opt] = deepcopy(grb_obj.options[opt])
 
 
-        if punch_method == 'exc':
+        # 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
 
 
-            # get the Excellon file whose geometry will create the punch holes
-            selection_index = self.ui.exc_combo.currentIndex()
-            model_index = self.app.collection.index(selection_index, 0, self.ui.exc_combo.rootModelIndex())
+            # create the punched Gerber solid_geometry
+        punched_solid_geometry = grb_solid_geometry.difference(exc_solid_geometry)
 
 
-            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
+        # 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()
 
 
-                # create the punched Gerber solid_geometry
-            punched_solid_geometry = grb_solid_geometry.difference(exc_solid_geometry)
+        # find maximum aperture id
+        new_apid = max([int(x) for x, __ in new_apertures_items])
 
 
-            # 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 = {}
-
-            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 tool in exc_obj.tools:
-                            clear_apid_size = exc_obj.tools[tool]['tooldia']
-
-                            if 'drills' in exc_obj.tools[tool]['drills']:
-                                for drill_pt in exc_obj.tools[tool]['drills']:
-                                    # since there may be drills that do not drill into a pad we test only for
-                                    # drills in a pad
-                                    if drill_pt.within(elem['solid']):
-                                        geo_elem = {}
-                                        geo_elem['clear'] = drill_pt
-
-                                        if clear_apid_size not in holes_apertures:
-                                            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'] = []
-
-                                        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(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(punched_solid_geometry)
-                new_obj.source_file = self.app.f_handlers.export_gerber(obj_name=outname, filename=None,
-                                                                        local_use=new_obj, use_thread=False)
-
-            self.app.app_obj.new_object('gerber', outname, init_func)
-        elif punch_method == 'fixed':
-            punch_size = float(self.ui.dia_entry.get_value())
+        # store here the clear geometry, the key is the drill size
+        holes_apertures = {}
 
 
-            if punch_size == 0.0:
-                self.app.inform.emit('[WARNING_NOTCL] %s' % _("The value of the fixed diameter is 0.0. Aborting."))
-                return 'fail'
+        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 tool in exc_obj.tools:
+                        clear_apid_size = exc_obj.tools[tool]['tooldia']
 
 
-            fail_msg = _("Could not generate punched hole Gerber because the punch hole size is bigger than"
-                         " some of the apertures in the Gerber object.")
+                        if 'drills' in exc_obj.tools[tool]['drills']:
+                            for drill_pt in exc_obj.tools[tool]['drills']:
+                                # since there may be drills that do not drill into a pad we test only for
+                                # drills in a pad
+                                if drill_pt.within(elem['solid']):
+                                    geo_elem = {}
+                                    geo_elem['clear'] = drill_pt
 
 
-            punching_geo = []
-            for apid in grb_obj.apertures:
+                                    if clear_apid_size not in holes_apertures:
+                                        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'] = []
+
+                                    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(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(punched_solid_geometry)
+            new_obj.source_file = self.app.f_handlers.export_gerber(obj_name=outname, filename=None,
+                                                                    local_use=new_obj, use_thread=False)
+
+        self.app.app_obj.new_object('gerber', outname, init_func)
+
+    def on_fixed_method(self, grb_obj, outname):
+        punch_size = float(self.ui.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'
+
+        fail_msg = _("Could not generate punched hole Gerber because the punch hole size is bigger than"
+                     " some of the apertures in the Gerber object.")
+
+        new_options = {}
+        for opt in grb_obj.options:
+            new_options[opt] = deepcopy(grb_obj.options[opt])
+
+        # selected codes in thre apertures UI table
+        sel_apid = []
+        for it in self.ui.apertures_table.selectedItems():
+            sel_apid.append(it.text())
+
+        punching_geo = []
+        for apid in grb_obj.apertures:
+            if apid in sel_apid:
                 if grb_obj.apertures[apid]['type'] == 'C' and self.ui.circular_cb.get_value():
                 if grb_obj.apertures[apid]['type'] == 'C' and self.ui.circular_cb.get_value():
                     for elem in grb_obj.apertures[apid]['geometry']:
                     for elem in grb_obj.apertures[apid]['geometry']:
                         if 'follow' in elem:
                         if 'follow' in elem:
@@ -332,103 +416,112 @@ class ToolPunchGerber(AppTool):
                                     return 'fail'
                                     return 'fail'
                                 punching_geo.append(elem['follow'].buffer(punch_size / 2))
                                 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'
+        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'
+
+        # 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 = {}
+
+        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 = {}
+                            geo_elem['clear'] = geo.centroid
+
+                            if clear_apid_size not in holes_apertures:
+                                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'] = []
+
+                            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(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(punched_solid_geometry)
+            new_obj.source_file = self.app.f_handlers.export_gerber(obj_name=outname, filename=None,
+                                                                    local_use=new_obj, use_thread=False)
+
+        self.app.app_obj.new_object('gerber', outname, init_func)
+
+    def on_ring_method(self, grb_obj, outname):
+        circ_r_val = self.ui.circular_ring_entry.get_value()
+        oblong_r_val = self.ui.oblong_ring_entry.get_value()
+        square_r_val = self.ui.square_ring_entry.get_value()
+        rect_r_val = self.ui.rectangular_ring_entry.get_value()
+        other_r_val = self.ui.other_ring_entry.get_value()
+        dia = None
 
 
-            # 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 = {}
-
-            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 = {}
-                                geo_elem['clear'] = geo.centroid
-
-                                if clear_apid_size not in holes_apertures:
-                                    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'] = []
-
-                                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(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(punched_solid_geometry)
-                new_obj.source_file = self.app.f_handlers.export_gerber(obj_name=outname, filename=None,
-                                                                        local_use=new_obj, use_thread=False)
-
-            self.app.app_obj.new_object('gerber', outname, init_func)
-        elif punch_method == 'ring':
-            circ_r_val = self.ui.circular_ring_entry.get_value()
-            oblong_r_val = self.ui.oblong_ring_entry.get_value()
-            square_r_val = self.ui.square_ring_entry.get_value()
-            rect_r_val = self.ui.rectangular_ring_entry.get_value()
-            other_r_val = self.ui.other_ring_entry.get_value()
+        new_options = {}
+        for opt in grb_obj.options:
+            new_options[opt] = deepcopy(grb_obj.options[opt])
 
 
-            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
 
 
-            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
 
 
-            punched_solid_geometry = temp_solid_geometry
+        new_apertures = deepcopy(grb_obj.apertures)
+        new_apertures_items = new_apertures.items()
 
 
-            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])
 
 
-            # find maximum aperture id
-            new_apid = max([int(x) for x, __ in new_apertures_items])
+        # selected codes in the apertures UI table
+        sel_apid = []
+        for it in self.ui.apertures_table.selectedItems():
+            sel_apid.append(it.text())
 
 
-            # store here the clear geometry, the key is the new aperture size
-            holes_apertures = {}
+        # store here the clear geometry, the key is the new aperture size
+        holes_apertures = {}
 
 
-            for apid, apid_value in grb_obj.apertures.items():
-                ap_type = apid_value['type']
-                punching_geo = []
+        for apid, apid_value in grb_obj.apertures.items():
+            ap_type = apid_value['type']
+            punching_geo = []
 
 
+            if apid in sel_apid:
                 if ap_type == 'C' and self.ui.circular_cb.get_value():
                 if ap_type == 'C' and self.ui.circular_cb.get_value():
                     dia = float(apid_value['size']) - (2 * circ_r_val)
                     dia = float(apid_value['size']) - (2 * circ_r_val)
                     for elem in apid_value['geometry']:
                     for elem in apid_value['geometry']:
                         if 'follow' in elem and isinstance(elem['follow'], Point):
                         if 'follow' in elem and isinstance(elem['follow'], Point):
                             punching_geo.append(elem['follow'].buffer(dia / 2))
                             punching_geo.append(elem['follow'].buffer(dia / 2))
-
                 elif ap_type == 'O' and self.ui.oblong_cb.get_value():
                 elif ap_type == 'O' and self.ui.oblong_cb.get_value():
                     width = float(apid_value['width'])
                     width = float(apid_value['width'])
                     height = float(apid_value['height'])
                     height = float(apid_value['height'])
@@ -442,7 +535,6 @@ class ToolPunchGerber(AppTool):
                         if 'follow' in elem:
                         if 'follow' in elem:
                             if isinstance(elem['follow'], Point):
                             if isinstance(elem['follow'], Point):
                                 punching_geo.append(elem['follow'].buffer(dia / 2))
                                 punching_geo.append(elem['follow'].buffer(dia / 2))
-
                 elif ap_type == 'R':
                 elif ap_type == 'R':
                     width = float(apid_value['width'])
                     width = float(apid_value['width'])
                     height = float(apid_value['height'])
                     height = float(apid_value['height'])
@@ -466,7 +558,6 @@ class ToolPunchGerber(AppTool):
                             if 'follow' in elem:
                             if 'follow' in elem:
                                 if isinstance(elem['follow'], Point):
                                 if isinstance(elem['follow'], Point):
                                     punching_geo.append(elem['follow'].buffer(dia / 2))
                                     punching_geo.append(elem['follow'].buffer(dia / 2))
-
                 elif self.ui.other_cb.get_value():
                 elif self.ui.other_cb.get_value():
                     try:
                     try:
                         dia = float(apid_value['size']) - (2 * other_r_val)
                         dia = float(apid_value['size']) - (2 * other_r_val)
@@ -486,88 +577,95 @@ class ToolPunchGerber(AppTool):
                             if isinstance(elem['follow'], Point):
                             if isinstance(elem['follow'], Point):
                                 punching_geo.append(elem['follow'].buffer(dia / 2))
                                 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:
+            # if dia is None then none of the above applied so we skip the following
+            if dia is None:
+                continue
 
 
-                            # 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 = {}
-                                geo_elem['clear'] = geo.centroid
-
-                                if clear_apid_size not in holes_apertures:
-                                    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'] = []
-
-                                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(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)
+            punching_geo = MultiPolygon(punching_geo)
 
 
-                new_obj.solid_geometry = deepcopy(punched_solid_geometry)
-                new_obj.source_file = self.app.f_handlers.export_gerber(obj_name=outname, filename=None,
-                                                                        local_use=new_obj, use_thread=False)
+            if punching_geo is None or punching_geo.is_empty:
+                continue
 
 
-            self.app.app_obj.new_object('gerber', outname, init_func)
+            punched_solid_geometry = punched_solid_geometry.difference(punching_geo)
 
 
-        elif punch_method == 'prop':
-            prop_factor = self.ui.factor_entry.get_value() / 100.0
+            # 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 = {}
+                            geo_elem['clear'] = geo.centroid
+
+                            if clear_apid_size not in holes_apertures:
+                                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'] = []
+
+                            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(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(punched_solid_geometry)
+            new_obj.source_file = self.app.f_handlers.export_gerber(obj_name=outname, filename=None,
+                                                                    local_use=new_obj, use_thread=False)
+
+        self.app.app_obj.new_object('gerber', outname, init_func)
+
+    def on_proportional_method(self, grb_obj, outname):
+        prop_factor = self.ui.factor_entry.get_value() / 100.0
+        dia = None
+        new_options = {}
+        for opt in grb_obj.options:
+            new_options[opt] = deepcopy(grb_obj.options[opt])
 
 
-            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
 
 
-            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
 
 
-            punched_solid_geometry = temp_solid_geometry
+        new_apertures = deepcopy(grb_obj.apertures)
+        new_apertures_items = new_apertures.items()
 
 
-            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])
 
 
-            # find maximum aperture id
-            new_apid = max([int(x) for x, __ in new_apertures_items])
+        # selected codes in the apertures UI table
+        sel_apid = []
+        for it in self.ui.apertures_table.selectedItems():
+            sel_apid.append(it.text())
 
 
-            # store here the clear geometry, the key is the new aperture size
-            holes_apertures = {}
+        # store here the clear geometry, the key is the new aperture size
+        holes_apertures = {}
 
 
-            for apid, apid_value in grb_obj.apertures.items():
-                ap_type = apid_value['type']
-                punching_geo = []
+        for apid, apid_value in grb_obj.apertures.items():
+            ap_type = apid_value['type']
+            punching_geo = []
 
 
+            if apid in sel_apid:
                 if ap_type == 'C' and self.ui.circular_cb.get_value():
                 if ap_type == 'C' and self.ui.circular_cb.get_value():
                     dia = float(apid_value['size']) * prop_factor
                     dia = float(apid_value['size']) * prop_factor
                     for elem in apid_value['geometry']:
                     for elem in apid_value['geometry']:
                         if 'follow' in elem and isinstance(elem['follow'], Point):
                         if 'follow' in elem and isinstance(elem['follow'], Point):
                             punching_geo.append(elem['follow'].buffer(dia / 2))
                             punching_geo.append(elem['follow'].buffer(dia / 2))
-
                 elif ap_type == 'O' and self.ui.oblong_cb.get_value():
                 elif ap_type == 'O' and self.ui.oblong_cb.get_value():
                     width = float(apid_value['width'])
                     width = float(apid_value['width'])
                     height = float(apid_value['height'])
                     height = float(apid_value['height'])
@@ -581,7 +679,6 @@ class ToolPunchGerber(AppTool):
                         if 'follow' in elem:
                         if 'follow' in elem:
                             if isinstance(elem['follow'], Point):
                             if isinstance(elem['follow'], Point):
                                 punching_geo.append(elem['follow'].buffer(dia / 2))
                                 punching_geo.append(elem['follow'].buffer(dia / 2))
-
                 elif ap_type == 'R':
                 elif ap_type == 'R':
                     width = float(apid_value['width'])
                     width = float(apid_value['width'])
                     height = float(apid_value['height'])
                     height = float(apid_value['height'])
@@ -605,7 +702,6 @@ class ToolPunchGerber(AppTool):
                             if 'follow' in elem:
                             if 'follow' in elem:
                                 if isinstance(elem['follow'], Point):
                                 if isinstance(elem['follow'], Point):
                                     punching_geo.append(elem['follow'].buffer(dia / 2))
                                     punching_geo.append(elem['follow'].buffer(dia / 2))
-
                 elif self.ui.other_cb.get_value():
                 elif self.ui.other_cb.get_value():
                     try:
                     try:
                         dia = float(apid_value['size']) * prop_factor
                         dia = float(apid_value['size']) * prop_factor
@@ -625,56 +721,56 @@ class ToolPunchGerber(AppTool):
                             if isinstance(elem['follow'], Point):
                             if isinstance(elem['follow'], Point):
                                 punching_geo.append(elem['follow'].buffer(dia / 2))
                                 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
+            # 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)
+            punching_geo = MultiPolygon(punching_geo)
 
 
-                if punching_geo is None or punching_geo.is_empty:
-                    continue
+            if punching_geo is None or punching_geo.is_empty:
+                continue
 
 
-                punched_solid_geometry = punched_solid_geometry.difference(punching_geo)
+            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:
+            # 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 = {}
-                                geo_elem['clear'] = geo.centroid
+                        # 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 = {}
+                            geo_elem['clear'] = geo.centroid
 
 
-                                if clear_apid_size not in holes_apertures:
-                                    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'] = []
+                            if clear_apid_size not in holes_apertures:
+                                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'] = []
 
 
-                                holes_apertures[clear_apid_size]['geometry'].append(deepcopy(geo_elem))
+                            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)
+        # 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(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)
+        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.apertures = deepcopy(new_apertures)
 
 
-                new_obj.solid_geometry = deepcopy(punched_solid_geometry)
-                new_obj.source_file = self.app.f_handlers.export_gerber(obj_name=outname, filename=None,
-                                                                        local_use=new_obj, use_thread=False)
+            new_obj.solid_geometry = deepcopy(punched_solid_geometry)
+            new_obj.source_file = self.app.f_handlers.export_gerber(obj_name=outname, filename=None,
+                                                                    local_use=new_obj, use_thread=False)
 
 
-            self.app.app_obj.new_object('gerber', outname, init_func)
+        self.app.app_obj.new_object('gerber', outname, init_func)
 
 
     def reset_fields(self):
     def reset_fields(self):
         self.ui.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
         self.ui.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
@@ -738,9 +834,18 @@ class PunchUI:
 
 
         grid_lay.addWidget(self.padt_label, 3, 0, 1, 2)
         grid_lay.addWidget(self.padt_label, 3, 0, 1, 2)
 
 
+        pad_all_grid = QtWidgets.QGridLayout()
+        pad_all_grid.setColumnStretch(0, 0)
+        pad_all_grid.setColumnStretch(1, 1)
+        grid_lay.addLayout(pad_all_grid, 5, 0, 1, 2)
+
+        pad_grid = QtWidgets.QGridLayout()
+        pad_grid.setColumnStretch(0, 0)
+        pad_all_grid.addLayout(pad_grid, 0, 0)
+
         # Select all
         # Select all
         self.select_all_cb = FCCheckBox('%s' % _("ALL"))
         self.select_all_cb = FCCheckBox('%s' % _("ALL"))
-        grid_lay.addWidget(self.select_all_cb)
+        pad_grid.addWidget(self.select_all_cb, 0, 0)
 
 
         # Circular Aperture Selection
         # Circular Aperture Selection
         self.circular_cb = FCCheckBox('%s' % _("Circular"))
         self.circular_cb = FCCheckBox('%s' % _("Circular"))
@@ -748,7 +853,7 @@ class PunchUI:
             _("Process Circular Pads.")
             _("Process Circular Pads.")
         )
         )
 
 
-        grid_lay.addWidget(self.circular_cb, 5, 0, 1, 2)
+        pad_grid.addWidget(self.circular_cb, 1, 0)
 
 
         # Oblong Aperture Selection
         # Oblong Aperture Selection
         self.oblong_cb = FCCheckBox('%s' % _("Oblong"))
         self.oblong_cb = FCCheckBox('%s' % _("Oblong"))
@@ -756,7 +861,7 @@ class PunchUI:
             _("Process Oblong Pads.")
             _("Process Oblong Pads.")
         )
         )
 
 
-        grid_lay.addWidget(self.oblong_cb, 6, 0, 1, 2)
+        pad_grid.addWidget(self.oblong_cb, 2, 0)
 
 
         # Square Aperture Selection
         # Square Aperture Selection
         self.square_cb = FCCheckBox('%s' % _("Square"))
         self.square_cb = FCCheckBox('%s' % _("Square"))
@@ -764,7 +869,7 @@ class PunchUI:
             _("Process Square Pads.")
             _("Process Square Pads.")
         )
         )
 
 
-        grid_lay.addWidget(self.square_cb, 7, 0, 1, 2)
+        pad_grid.addWidget(self.square_cb, 3, 0)
 
 
         # Rectangular Aperture Selection
         # Rectangular Aperture Selection
         self.rectangular_cb = FCCheckBox('%s' % _("Rectangular"))
         self.rectangular_cb = FCCheckBox('%s' % _("Rectangular"))
@@ -772,7 +877,7 @@ class PunchUI:
             _("Process Rectangular Pads.")
             _("Process Rectangular Pads.")
         )
         )
 
 
-        grid_lay.addWidget(self.rectangular_cb, 8, 0, 1, 2)
+        pad_grid.addWidget(self.rectangular_cb, 4, 0)
 
 
         # Others type of Apertures Selection
         # Others type of Apertures Selection
         self.other_cb = FCCheckBox('%s' % _("Others"))
         self.other_cb = FCCheckBox('%s' % _("Others"))
@@ -780,7 +885,29 @@ class PunchUI:
             _("Process pads not in the categories above.")
             _("Process pads not in the categories above.")
         )
         )
 
 
-        grid_lay.addWidget(self.other_cb, 9, 0, 1, 2)
+        pad_grid.addWidget(self.other_cb, 5, 0)
+
+        # Aperture Table
+        self.apertures_table = FCTable()
+        pad_all_grid.addWidget(self.apertures_table, 0, 1)
+
+        self.apertures_table.setColumnCount(3)
+        self.apertures_table.setHorizontalHeaderLabels([_('Code'), _('Type'), _('Size')])
+        self.apertures_table.setSortingEnabled(False)
+        self.apertures_table.setRowCount(0)
+        self.apertures_table.resizeColumnsToContents()
+        self.apertures_table.resizeRowsToContents()
+
+        self.apertures_table.horizontalHeaderItem(0).setToolTip(
+            _("Aperture Code"))
+        self.apertures_table.horizontalHeaderItem(1).setToolTip(
+            _("Type of aperture: circular, rectangle, macros etc"))
+        self.apertures_table.horizontalHeaderItem(2).setToolTip(
+            _("Aperture Size:"))
+
+        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred)
+        self.apertures_table.setSizePolicy(sizePolicy)
+        self.apertures_table.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
 
 
         separator_line = QtWidgets.QFrame()
         separator_line = QtWidgets.QFrame()
         separator_line.setFrameShape(QtWidgets.QFrame.HLine)
         separator_line.setFrameShape(QtWidgets.QFrame.HLine)
@@ -832,11 +959,6 @@ class PunchUI:
         grid0.addWidget(self.exc_label, 3, 0, 1, 2)
         grid0.addWidget(self.exc_label, 3, 0, 1, 2)
         grid0.addWidget(self.exc_combo, 4, 0, 1, 2)
         grid0.addWidget(self.exc_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, 5, 0, 1, 2)
-
         # Fixed Dia
         # Fixed Dia
         self.fixed_label = QtWidgets.QLabel('<b>%s</b>' % _("Fixed Diameter"))
         self.fixed_label = QtWidgets.QLabel('<b>%s</b>' % _("Fixed Diameter"))
         grid0.addWidget(self.fixed_label, 6, 0, 1, 2)
         grid0.addWidget(self.fixed_label, 6, 0, 1, 2)
@@ -854,11 +976,9 @@ class PunchUI:
         grid0.addWidget(self.dia_label, 8, 0)
         grid0.addWidget(self.dia_label, 8, 0)
         grid0.addWidget(self.dia_entry, 8, 1)
         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)
-
+        # #############################################################################################################
+        # RING FRAME
+        # #############################################################################################################
         self.ring_frame = QtWidgets.QFrame()
         self.ring_frame = QtWidgets.QFrame()
         self.ring_frame.setContentsMargins(0, 0, 0, 0)
         self.ring_frame.setContentsMargins(0, 0, 0, 0)
         grid0.addWidget(self.ring_frame, 10, 0, 1, 2)
         grid0.addWidget(self.ring_frame, 10, 0, 1, 2)
@@ -946,11 +1066,7 @@ class PunchUI:
 
 
         self.grid1.addWidget(self.other_ring_label, 7, 0)
         self.grid1.addWidget(self.other_ring_label, 7, 0)
         self.grid1.addWidget(self.other_ring_entry, 7, 1)
         self.grid1.addWidget(self.other_ring_entry, 7, 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
         # Proportional value
         self.prop_label = QtWidgets.QLabel('<b>%s</b>' % _("Proportional Diameter"))
         self.prop_label = QtWidgets.QLabel('<b>%s</b>' % _("Proportional Diameter"))
@@ -1012,10 +1128,10 @@ class PunchUI:
         self.rectangular_ring_entry.setEnabled(False)
         self.rectangular_ring_entry.setEnabled(False)
         self.other_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.dia_entry.hide()
+        self.dia_label.hide()
+        self.factor_label.hide()
+        self.factor_entry.hide()
 
 
         # #################################### FINSIHED GUI ###########################
         # #################################### FINSIHED GUI ###########################
         # #############################################################################
         # #############################################################################

BIN
locale/tr/LC_MESSAGES/strings.mo


+ 12 - 16
locale/tr/LC_MESSAGES/strings.po

@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 msgstr ""
 "Project-Id-Version: \n"
 "Project-Id-Version: \n"
 "POT-Creation-Date: 2020-10-28 10:58+0200\n"
 "POT-Creation-Date: 2020-10-28 10:58+0200\n"
-"PO-Revision-Date: 2020-10-28 10:58+0200\n"
+"PO-Revision-Date: 2020-10-28 15:13+0300\n"
 "Last-Translator: \n"
 "Last-Translator: \n"
 "Language-Team: \n"
 "Language-Team: \n"
 "Language: tr_TR\n"
 "Language: tr_TR\n"
@@ -89,10 +89,8 @@ msgid "Bookmark added."
 msgstr "Yer işareti eklendi."
 msgstr "Yer işareti eklendi."
 
 
 #: Bookmark.py:243 app_Main.py:3207 app_Main.py:3249
 #: Bookmark.py:243 app_Main.py:3207 app_Main.py:3249
-#, fuzzy
-#| msgid "Backup"
 msgid "Backup Site"
 msgid "Backup Site"
-msgstr "Yedekleme"
+msgstr "Alternatif Web Sayfası"
 
 
 #: Bookmark.py:244
 #: Bookmark.py:244
 msgid "This bookmark can not be removed"
 msgid "This bookmark can not be removed"
@@ -4986,7 +4984,7 @@ msgstr "Gerber Özellikleri"
 
 
 #: appGUI/MainGUI.py:610
 #: appGUI/MainGUI.py:610
 msgid "Shortcuts List"
 msgid "Shortcuts List"
-msgstr ""
+msgstr "Klavye Kısayol Listesi"
 
 
 #: appGUI/MainGUI.py:610 appGUI/MainGUI.py:4398
 #: appGUI/MainGUI.py:610 appGUI/MainGUI.py:4398
 msgid "F3"
 msgid "F3"
@@ -13722,11 +13720,11 @@ msgstr "Hatanın nedeni"
 
 
 #: appObjects/ObjectCollection.py:1195
 #: appObjects/ObjectCollection.py:1195
 msgid "All objects are selected."
 msgid "All objects are selected."
-msgstr "Hatanın nedeni."
+msgstr "Nesnelerin Tümü Seçildi."
 
 
 #: appObjects/ObjectCollection.py:1205
 #: appObjects/ObjectCollection.py:1205
 msgid "Objects selection is cleared."
 msgid "Objects selection is cleared."
-msgstr "Nesnelerin seçimi temizlendi."
+msgstr "Nesnelerin seçimi kaldırıldı."
 
 
 #: appParsers/ParseExcellon.py:292
 #: appParsers/ParseExcellon.py:292
 msgid "This is GCODE mark"
 msgid "This is GCODE mark"
@@ -18536,20 +18534,18 @@ msgid ""
 "If you can't get any informations about the application\n"
 "If you can't get any informations about the application\n"
 "use the YouTube channel link from the Help menu."
 "use the YouTube channel link from the Help menu."
 msgstr ""
 msgstr ""
-"Aşağıdaki durumlarda bu girişe başka bir\n"
-"sitede izin verilecektir:\n"
+"Bu giriş, aşağıdaki durumlarda başka bir web sayfasına yönlendirecektir:\n"
 "\n"
 "\n"
-"1. FlatCAM.org web sitesi çalışmıyor\n"
-"2. Birisi FlatCAM projesini çatalladı ve \n"
-"kendi web sitesine işaret etmek istiyor\n"
+"1. FlatCAM.org sayfası kapandığında\n"
+"2. Birisi FlatCAM projesini kopyaladığında ve sizi kendi web sayfasına \n"
+"yönlendirmek istediğinde\n"
 "\n"
 "\n"
-"Uygulama'in beta sürümü hakkında herhangi\n"
-"bir bilgi alamıyorsanız, Yardım menüsündeki\n"
-"YouTube kanalı bağlantısını kullanın."
+"Uygulama hakkında bilgi alamazsanız, Yardım menüsünden \n"
+"\"YouTube Kanalı\" bağlantısını kullanın."
 
 
 #: app_Main.py:3294
 #: app_Main.py:3294
 msgid "Alternative website"
 msgid "Alternative website"
-msgstr "Alternatif web sitesi"
+msgstr "Alternatif Web Sayfası"
 
 
 #: app_Main.py:3636
 #: app_Main.py:3636
 msgid "Selected Excellon file extensions registered with FlatCAM."
 msgid "Selected Excellon file extensions registered with FlatCAM."