Parcourir la source

- updated 2Sided Tool

Marius Stanciu il y a 6 ans
Parent
commit
cd45276819

+ 7 - 2
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
 

+ 1 - 0
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
 

+ 3 - 1
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

+ 2 - 1
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."))

+ 18 - 7
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 <b>box</b> (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()
 

+ 220 - 148
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 <b>(x, y)</b> 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,135 +228,22 @@ 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)
-
-        self.layout.addWidget(QtWidgets.QLabel(""))
-
-        # ## Alignment holes
-        self.alignment_label = QtWidgets.QLabel("<b>%s:</b>" % _('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"
-             "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'.")
-        )
-        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)
-
-        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"
-              "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.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)
-        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)
-
-        # ## Buttons
-        self.create_alignment_hole_button = QtWidgets.QPushButton(_("Create Excellon Object"))
-        self.create_alignment_hole_button.setToolTip(
-            _("Creates an Excellon Object containing the\n"
-              "specified alignment holes and their mirror\n"
-              "images.")
-        )
-        self.create_alignment_hole_button.setStyleSheet("""
-                        QPushButton
-                        {
-                            font-weight: bold;
-                        }
-                        """)
-        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(''))
+        grid_lay2.addWidget(separator_line, 4, 0, 1, 2)
 
-        grid1 = QtWidgets.QGridLayout()
-        self.layout.addLayout(grid1)
-        grid1.setColumnStretch(0, 0)
-        grid1.setColumnStretch(1, 1)
+        grid_lay2.addWidget(QtWidgets.QLabel(""), 5, 0, 1, 2)
 
         # ## Title Bounds Values
         self.bv_label = QtWidgets.QLabel("<b>%s:</b>" % _('Bounds Values'))
@@ -364,76 +251,76 @@ class DblSidedTool(FlatCAMTool):
             _("Select on canvas the object(s)\n"
               "for which to calculate bounds values.")
         )
-        grid1.addWidget(self.bv_label, 0, 0, 1, 2)
+        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_label = QtWidgets.QLabel('%s:' % _("X min"))
-        self.xmin_label.setToolTip(
+        self.xmin_btn = FCButton('%s:' % _("X min"))
+        self.xmin_btn.setToolTip(
             _("Minimum location.")
         )
         self.xmin_entry.setReadOnly(True)
 
-        grid1.addWidget(self.xmin_label, 1, 0)
-        grid1.addWidget(self.xmin_entry, 1, 1)
+        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_label = QtWidgets.QLabel('%s:' % _("Y min"))
-        self.ymin_label.setToolTip(
+        self.ymin_btn = FCButton('%s:' % _("Y min"))
+        self.ymin_btn.setToolTip(
             _("Minimum location.")
         )
         self.ymin_entry.setReadOnly(True)
 
-        grid1.addWidget(self.ymin_label, 2, 0)
-        grid1.addWidget(self.ymin_entry, 2, 1)
+        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_label = QtWidgets.QLabel('%s:' % _("X max"))
-        self.xmax_label.setToolTip(
+        self.xmax_btn = FCButton('%s:' % _("X max"))
+        self.xmax_btn.setToolTip(
             _("Maximum location.")
         )
         self.xmax_entry.setReadOnly(True)
 
-        grid1.addWidget(self.xmax_label, 3, 0)
-        grid1.addWidget(self.xmax_entry, 3, 1)
+        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_label = QtWidgets.QLabel('%s:' % _("Y max"))
-        self.ymax_label.setToolTip(
+        self.ymax_btn = FCButton('%s:' % _("Y max"))
+        self.ymax_btn.setToolTip(
             _("Maximum location.")
         )
         self.ymax_entry.setReadOnly(True)
 
-        grid1.addWidget(self.ymax_label, 4, 0)
-        grid1.addWidget(self.ymax_entry, 4, 1)
+        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_label = QtWidgets.QLabel('%s:' % _("Centroid"))
-        self.center_label.setToolTip(
+        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)
 
-        grid1.addWidget(self.center_label, 5, 0)
-        grid1.addWidget(self.center_entry, 5, 1)
+        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"))
@@ -448,7 +335,130 @@ class DblSidedTool(FlatCAMTool):
                                     font-weight: bold;
                                 }
                                 """)
-        self.layout.addWidget(self.calculate_bb_button)
+        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("<b>%s:</b>" % _('PCB Alignment'))
+        self.alignment_label.setToolTip(
+            _("Creates an Excellon Object containing the\n"
+              "specified alignment holes and their mirror\n"
+              "images.")
+        )
+        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'))
+        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"
+             "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'.")
+        )
+
+        self.alignment_holes = EvalEntry()
+
+        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 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.delete_drill_point_button = FCButton(_("Delete Last"))
+        self.delete_drill_point_button.setToolTip(
+            _("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_lay4.addLayout(drill_hlay, 2, 0, 1, 2)
+
+        # ## Buttons
+        self.create_alignment_hole_button = QtWidgets.QPushButton(_("Create Excellon Object"))
+        self.create_alignment_hole_button.setToolTip(
+            _("Creates an Excellon Object containing the\n"
+              "specified alignment holes and their mirror\n"
+              "images.")
+        )
+        self.create_alignment_hole_button.setStyleSheet("""
+                        QPushButton
+                        {
+                            font-weight: bold;
+                        }
+                        """)
+        self.layout.addWidget(self.create_alignment_hole_button)
 
         self.layout.addStretch()
 
@@ -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('')