Pārlūkot izejas kodu

- further modifications in Preferences -> General GUI - extended the changes

Marius Stanciu 6 gadi atpakaļ
vecāks
revīzija
f0ed74ce5f
4 mainītis faili ar 356 papildinājumiem un 310 dzēšanām
  1. 52 16
      FlatCAMApp.py
  2. 1 0
      README.md
  3. 11 0
      flatcamGUI/FlatCAMGUI.py
  4. 292 294
      flatcamGUI/PreferencesUI.py

+ 52 - 16
FlatCAMApp.py

@@ -505,6 +505,7 @@ class App(QtCore.QObject):
 
             # General GUI Settings
             "global_theme": 'white',
+            "global_gray_icons": False,
             "global_hover": False,
             "global_selection_shape": True,
             "global_layout": "compact",
@@ -1112,12 +1113,11 @@ class App(QtCore.QObject):
             "global_tpdf_rmargin": self.ui.general_defaults_form.general_app_group.rmargin_entry,
 
             # General GUI Preferences
-            "global_gridx": self.ui.general_defaults_form.general_gui_group.gridx_entry,
-            "global_gridy": self.ui.general_defaults_form.general_gui_group.gridy_entry,
-            "global_snap_max": self.ui.general_defaults_form.general_gui_group.snap_max_dist_entry,
-            "global_workspace": self.ui.general_defaults_form.general_gui_group.workspace_cb,
-            "global_workspaceT": self.ui.general_defaults_form.general_gui_group.wk_cb,
-            "global_workspace_orientation": self.ui.general_defaults_form.general_gui_group.wk_orientation_radio,
+            "global_theme": self.ui.general_defaults_form.general_gui_group.theme_radio,
+            "global_gray_icons": self.ui.general_defaults_form.general_gui_group.gray_icons_cb,
+            "global_layout": self.ui.general_defaults_form.general_gui_group.layout_combo,
+            "global_hover": self.ui.general_defaults_form.general_gui_group.hover_cb,
+            "global_selection_shape": self.ui.general_defaults_form.general_gui_group.selection_cb,
 
             "global_sel_fill": self.ui.general_defaults_form.general_gui_group.sf_color_entry,
             "global_sel_line": self.ui.general_defaults_form.general_gui_group.sl_color_entry,
@@ -1131,10 +1131,13 @@ class App(QtCore.QObject):
             "global_project_autohide": self.ui.general_defaults_form.general_gui_group.project_autohide_cb,
 
             # General GUI Settings
-            "global_theme": self.ui.general_defaults_form.general_gui_set_group.theme_radio,
-            "global_layout": self.ui.general_defaults_form.general_gui_set_group.layout_combo,
-            "global_hover": self.ui.general_defaults_form.general_gui_set_group.hover_cb,
-            "global_selection_shape": self.ui.general_defaults_form.general_gui_set_group.selection_cb,
+            "global_gridx": self.ui.general_defaults_form.general_gui_set_group.gridx_entry,
+            "global_gridy": self.ui.general_defaults_form.general_gui_set_group.gridy_entry,
+            "global_snap_max": self.ui.general_defaults_form.general_gui_set_group.snap_max_dist_entry,
+            "global_workspace": self.ui.general_defaults_form.general_gui_set_group.workspace_cb,
+            "global_workspaceT": self.ui.general_defaults_form.general_gui_set_group.wk_cb,
+            "global_workspace_orientation": self.ui.general_defaults_form.general_gui_set_group.wk_orientation_radio,
+
             "global_systray_icon": self.ui.general_defaults_form.general_gui_set_group.systray_cb,
             "global_shell_at_startup": self.ui.general_defaults_form.general_gui_set_group.shell_startup_cb,
             "global_project_at_startup": self.ui.general_defaults_form.general_gui_set_group.project_startup_cb,
@@ -1994,6 +1997,7 @@ class App(QtCore.QObject):
 
         self.ui.pref_defaults_button.clicked.connect(self.on_restore_defaults_preferences)
         self.ui.pref_open_button.clicked.connect(self.on_preferences_open_folder)
+        self.ui.clear_btn.clicked.connect(self.on_gui_clear)
 
         # #############################################################################
         # ######################### GUI PREFERENCES SIGNALS ###########################
@@ -2060,20 +2064,20 @@ class App(QtCore.QObject):
             self.on_proj_color_dis_button)
 
         # ############################# Workspace Setting Signals #####################
-        self.ui.general_defaults_form.general_gui_group.wk_cb.currentIndexChanged.connect(self.on_workspace_modified)
-        self.ui.general_defaults_form.general_gui_group.wk_orientation_radio.activated_custom.connect(
+        self.ui.general_defaults_form.general_gui_set_group.wk_cb.currentIndexChanged.connect(
+            self.on_workspace_modified)
+        self.ui.general_defaults_form.general_gui_set_group.wk_orientation_radio.activated_custom.connect(
             self.on_workspace_modified
         )
 
-        self.ui.general_defaults_form.general_gui_group.workspace_cb.stateChanged.connect(self.on_workspace)
+        self.ui.general_defaults_form.general_gui_set_group.workspace_cb.stateChanged.connect(self.on_workspace)
 
-        self.ui.general_defaults_form.general_gui_set_group.layout_combo.activated.connect(self.on_layout)
+        self.ui.general_defaults_form.general_gui_group.layout_combo.activated.connect(self.on_layout)
 
         # #############################################################################
         # ############################# GUI SETTINGS SIGNALS ##########################
         # #############################################################################
 
-        self.ui.general_defaults_form.general_gui_set_group.theme_radio.activated_custom.connect(self.on_theme_change)
         self.ui.general_defaults_form.general_gui_set_group.cursor_radio.activated_custom.connect(self.on_cursor_type)
 
         # ########## CNC Job related signals #############
@@ -4064,6 +4068,38 @@ class App(QtCore.QObject):
         self.inform.emit('[success] %s' %
                          _("FlatCAM Preferences Folder opened."))
 
+    def on_gui_clear(self):
+        theme_settings = QtCore.QSettings("Open Source", "FlatCAM")
+        if theme_settings.contains("theme"):
+            theme = theme_settings.value('theme', type=str)
+        else:
+            theme = 'white'
+
+        if theme == 'white':
+            resource_loc = 'share'
+        else:
+            resource_loc = 'share'
+
+        msgbox = QtWidgets.QMessageBox()
+        msgbox.setText(_("Are you sure you want to delete the GUI Settings? "
+                         "\n")
+                       )
+        msgbox.setWindowTitle(_("Clear GUI Settings"))
+        msgbox.setWindowIcon(QtGui.QIcon(resource_loc + '/trash32.png'))
+        bt_yes = msgbox.addButton(_('Yes'), QtWidgets.QMessageBox.YesRole)
+        bt_no = msgbox.addButton(_('No'), QtWidgets.QMessageBox.NoRole)
+
+        msgbox.setDefaultButton(bt_no)
+        msgbox.exec_()
+        response = msgbox.clickedButton()
+
+        if response == bt_yes:
+            settings = QSettings("Open Source", "FlatCAM")
+            for key in settings.allKeys():
+                settings.remove(key)
+            # This will write the setting to the platform specific storage.
+            del settings
+
     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
@@ -6899,7 +6935,7 @@ class App(QtCore.QObject):
         if lay:
             current_layout = lay
         else:
-            current_layout = self.ui.general_defaults_form.general_gui_set_group.layout_combo.get_value()
+            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)

+ 1 - 0
README.md

@@ -21,6 +21,7 @@ CAD program, and create G-Code for Isolation routing.
 - 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
 
 25.12.2019
 

+ 11 - 0
flatcamGUI/FlatCAMGUI.py

@@ -1226,6 +1226,17 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
             _("Open the folder where FlatCAM save the preferences files."))
         self.pref_tab_bottom_layout_1.addWidget(self.pref_open_button)
 
+        # Clear Settings
+        self.clear_btn = FCButton('%s' % _('Clear GUI Settings'))
+        self.clear_btn.setMinimumWidth(130)
+
+        self.clear_btn.setToolTip(
+            _("Clear the GUI settings for FlatCAM,\n"
+              "such as: layout, gui state, style, hdpi support etc.")
+        )
+
+        self.pref_tab_bottom_layout_1.addWidget(self.clear_btn)
+
         self.pref_tab_bottom_layout_2 = QtWidgets.QHBoxLayout()
         self.pref_tab_bottom_layout_2.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
         self.pref_tab_bottom_layout.addLayout(self.pref_tab_bottom_layout_2)

+ 292 - 294
flatcamGUI/PreferencesUI.py

@@ -51,7 +51,7 @@ class GeneralPreferencesUI(QtWidgets.QWidget):
         self.decimals = decimals
 
         self.general_app_group = GeneralAppPrefGroupUI(decimals=self.decimals)
-        self.general_app_group.setMinimumWidth(290)
+        self.general_app_group.setMinimumWidth(250)
 
         self.general_gui_group = GeneralGUIPrefGroupUI(decimals=self.decimals)
         self.general_gui_group.setMinimumWidth(250)
@@ -330,147 +330,112 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI):
         grid0.setColumnStretch(0, 0)
         grid0.setColumnStretch(1, 1)
 
-        self.grid_label = QtWidgets.QLabel('<b>%s</b>' % _('Grid Settings'))
-        grid0.addWidget(self.grid_label, 0, 0, 1, 2)
-
-        # Grid X Entry
-        self.gridx_label = QtWidgets.QLabel('%s:' % _('X value'))
-        self.gridx_label.setToolTip(
-           _("This is the Grid snap value on X axis.")
+        # Theme selection
+        self.theme_label = QtWidgets.QLabel('%s:' % _('Theme'))
+        self.theme_label.setToolTip(
+            _("Select a theme for FlatCAM.")
         )
-        self.gridx_entry = FCDoubleSpinner()
-        self.gridx_entry.set_precision(self.decimals)
-        self.gridx_entry.setSingleStep(0.1)
 
-        grid0.addWidget(self.gridx_label, 1, 0)
-        grid0.addWidget(self.gridx_entry, 1, 1)
-
-        # Grid Y Entry
-        self.gridy_label = QtWidgets.QLabel('%s:' % _('Y value'))
-        self.gridy_label.setToolTip(
-            _("This is the Grid snap value on Y axis.")
-        )
-        self.gridy_entry = FCDoubleSpinner()
-        self.gridy_entry.set_precision(self.decimals)
-        self.gridy_entry.setSingleStep(0.1)
+        self.theme_radio = RadioSet([
+            {"label": _("Light"), "value": "white"},
+            {"label": _("Dark"), "value": "black"}
+        ], orientation='vertical')
 
-        grid0.addWidget(self.gridy_label, 2, 0)
-        grid0.addWidget(self.gridy_entry, 2, 1)
+        grid0.addWidget(self.theme_label, 0, 0)
+        grid0.addWidget(self.theme_radio, 0, 1)
 
-        # Snap Max Entry
-        self.snap_max_label = QtWidgets.QLabel('%s:' % _('Snap Max'))
-        self.snap_max_label.setToolTip(_("Max. magnet distance"))
-        self.snap_max_dist_entry = FCDoubleSpinner()
-        self.snap_max_dist_entry.set_precision(self.decimals)
-        self.snap_max_dist_entry.setSingleStep(0.1)
+        # Enable Gray Icons
+        self.gray_icons_cb = FCCheckBox('%s' % _('Use Gray Icons'))
+        self.gray_icons_cb.setToolTip(
+            _("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.")
+        )
+        grid0.addWidget(self.gray_icons_cb, 1, 0, 1, 3)
 
-        grid0.addWidget(self.snap_max_label, 3, 0)
-        grid0.addWidget(self.snap_max_dist_entry, 3, 1)
+        self.theme_button = FCButton(_("Apply Theme"))
+        self.theme_button.setToolTip(
+            _("Select a theme for FlatCAM.\n"
+              "The application will restart after change.")
+        )
+        grid0.addWidget(self.theme_button, 2, 0, 1, 3)
 
         separator_line = QtWidgets.QFrame()
         separator_line.setFrameShape(QtWidgets.QFrame.HLine)
         separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
-        grid0.addWidget(separator_line, 4, 0, 1, 2)
-
-        # Workspace
-        self.workspace_label = QtWidgets.QLabel('<b>%s</b>' % _('Workspace Settings'))
-        grid0.addWidget(self.workspace_label, 5, 0, 1, 2)
-
-        self.workspace_cb = FCCheckBox('%s' % _('Active'))
-        self.workspace_cb.setToolTip(
-           _("Draw a delimiting rectangle on canvas.\n"
-             "The purpose is to illustrate the limits for our work.")
-        )
+        grid0.addWidget(separator_line, 3, 0, 1, 2)
 
-        grid0.addWidget(self.workspace_cb, 6, 0, 1, 2)
-
-        self.workspace_type_lbl = QtWidgets.QLabel('%s:' % _('Size'))
-        self.workspace_type_lbl.setToolTip(
-           _("Select the type of rectangle to be used on canvas,\n"
-             "as valid workspace.")
+        # Layout selection
+        self.layout_label = QtWidgets.QLabel('%s:' % _('Layout'))
+        self.layout_label.setToolTip(
+            _("Select an layout for FlatCAM.\n"
+              "It is applied immediately.")
         )
-        self.wk_cb = FCComboBox()
-
-        grid0.addWidget(self.workspace_type_lbl, 7, 0)
-        grid0.addWidget(self.wk_cb, 7, 1)
-
-        self.pagesize = dict()
-        self.pagesize.update(
-            {
-                'A0': (841, 1189),
-                'A1': (594, 841),
-                'A2': (420, 594),
-                'A3': (297, 420),
-                'A4': (210, 297),
-                'A5': (148, 210),
-                'A6': (105, 148),
-                'A7': (74, 105),
-                'A8': (52, 74),
-                'A9': (37, 52),
-                'A10': (26, 37),
-
-                'B0': (1000, 1414),
-                'B1': (707, 1000),
-                'B2': (500, 707),
-                'B3': (353, 500),
-                'B4': (250, 353),
-                'B5': (176, 250),
-                'B6': (125, 176),
-                'B7': (88, 125),
-                'B8': (62, 88),
-                'B9': (44, 62),
-                'B10': (31, 44),
+        self.layout_combo = FCComboBox()
+        # 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")
 
-                'C0': (917, 1297),
-                'C1': (648, 917),
-                'C2': (458, 648),
-                'C3': (324, 458),
-                'C4': (229, 324),
-                'C5': (162, 229),
-                'C6': (114, 162),
-                'C7': (81, 114),
-                'C8': (57, 81),
-                'C9': (40, 57),
-                'C10': (28, 40),
+        grid0.addWidget(self.layout_label, 4, 0)
+        grid0.addWidget(self.layout_combo, 4, 1)
 
-                # American paper sizes
-                'LETTER': (8.5, 11),
-                'LEGAL': (8.5, 14),
-                'ELEVENSEVENTEEN': (11, 17),
+        # Set the current index for layout_combo
+        settings = QSettings("Open Source", "FlatCAM")
+        if settings.contains("layout"):
+            layout = settings.value('layout', type=str)
+            idx = self.layout_combo.findText(layout.capitalize())
+            self.layout_combo.setCurrentIndex(idx)
 
-                # From https://en.wikipedia.org/wiki/Paper_size
-                'JUNIOR_LEGAL': (5, 8),
-                'HALF_LETTER': (5.5, 8),
-                'GOV_LETTER': (8, 10.5),
-                'GOV_LEGAL': (8.5, 13),
-                'LEDGER': (17, 11),
-            }
+        # Style selection
+        self.style_label = QtWidgets.QLabel('%s:' % _('Style'))
+        self.style_label.setToolTip(
+            _("Select an style for FlatCAM.\n"
+              "It will be applied at the next app start.")
         )
+        self.style_combo = FCComboBox()
+        self.style_combo.addItems(QtWidgets.QStyleFactory.keys())
+        # find current style
+        index = self.style_combo.findText(QtWidgets.qApp.style().objectName(), QtCore.Qt.MatchFixedString)
+        self.style_combo.setCurrentIndex(index)
+        self.style_combo.activated[str].connect(self.handle_style)
 
-        page_size_list = list(self.pagesize.keys())
+        grid0.addWidget(self.style_label, 5, 0)
+        grid0.addWidget(self.style_combo, 5, 1)
 
-        self.wk_cb.addItems(page_size_list)
+        # Enable High DPI Support
+        self.hdpi_cb = FCCheckBox('%s' % _('Activate HDPI Support'))
+        self.hdpi_cb.setToolTip(
+            _("Enable High DPI support for FlatCAM.\n"
+              "It will be applied at the next app start.")
+        )
 
-        # Page orientation
-        self.wk_orientation_label = QtWidgets.QLabel('%s:' % _("Orientation"))
-        self.wk_orientation_label.setToolTip(_("Can be:\n"
-                                               "- Portrait\n"
-                                               "- Landscape"))
+        settings = QSettings("Open Source", "FlatCAM")
+        if settings.contains("hdpi"):
+            self.hdpi_cb.set_value(settings.value('hdpi', type=int))
+        else:
+            self.hdpi_cb.set_value(False)
+        self.hdpi_cb.stateChanged.connect(self.handle_hdpi)
 
-        self.wk_orientation_radio = RadioSet([{'label': _('Portrait'), 'value': 'p'},
-                                              {'label': _('Landscape'), 'value': 'l'},
-                                              ], stretch=False)
+        grid0.addWidget(self.hdpi_cb, 6, 0, 1, 3)
 
-        self.wks = OptionalInputSection(self.workspace_cb,
-                                        [
-                                            self.workspace_type_lbl,
-                                            self.wk_cb,
-                                            self.wk_orientation_label,
-                                            self.wk_orientation_radio
-                                        ])
+        # Enable Hover box
+        self.hover_cb = FCCheckBox('%s' % _('Display Hover Shape'))
+        self.hover_cb.setToolTip(
+            _("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.")
+        )
+        grid0.addWidget(self.hover_cb, 8, 0, 1, 3)
 
-        grid0.addWidget(self.wk_orientation_label, 8, 0)
-        grid0.addWidget(self.wk_orientation_radio, 8, 1)
+        # Enable Selection box
+        self.selection_cb = FCCheckBox('%s' % _('Display Selection Shape'))
+        self.selection_cb.setToolTip(
+            _("Enable the display of a selection shape for FlatCAM objects.\n"
+              "It is displayed whenever the mouse selects an object\n"
+              "either by clicking or dragging mouse from left to right or\n"
+              "right to left.")
+        )
+        grid0.addWidget(self.selection_cb, 9, 0, 1, 3)
 
         separator_line = QtWidgets.QFrame()
         separator_line.setFrameShape(QtWidgets.QFrame.HLine)
@@ -478,7 +443,7 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI):
         grid0.addWidget(separator_line, 14, 0, 1, 2)
 
         # Plot Selection (left - right) Color
-        self.sel_lr_label = QtWidgets.QLabel('<b>%s</b>' % _('Object Left-Right Selection Color'))
+        self.sel_lr_label = QtWidgets.QLabel('<b>%s</b>' % _('Left-Right Selection Color'))
         grid0.addWidget(self.sel_lr_label, 15, 0, 1, 2)
 
         self.sl_color_label = QtWidgets.QLabel('%s:' % _('Outline'))
@@ -543,7 +508,7 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI):
         grid0.addWidget(separator_line, 19, 0, 1, 2)
 
         # Plot Selection (left - right) Color
-        self.sel_rl_label = QtWidgets.QLabel('<b>%s</b>' % _('Object Right-Left Selection Color'))
+        self.sel_rl_label = QtWidgets.QLabel('<b>%s</b>' % _('Right-Left Selection Color'))
         grid0.addWidget(self.sel_rl_label, 20, 0, 1, 2)
 
         # Plot Selection (right - left) Line Color
@@ -711,6 +676,24 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI):
 
         self.layout.addStretch()
 
+        self.theme_button.clicked.connect(self.app.on_theme_change)
+
+    def handle_style(self, style):
+        # set current style
+        settings = QSettings("Open Source", "FlatCAM")
+        settings.setValue('style', style)
+
+        # This will write the setting to the platform specific storage.
+        del settings
+
+    def handle_hdpi(self, state):
+        # set current HDPI
+        settings = QSettings("Open Source", "FlatCAM")
+        settings.setValue('hdpi', state)
+
+        # This will write the setting to the platform specific storage.
+        del settings
+
 
 class GeneralGUISetGroupUI(OptionsGroupUI):
     def __init__(self, decimals=4, parent=None):
@@ -736,118 +719,160 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
         grid0.setColumnStretch(0, 0)
         grid0.setColumnStretch(1, 1)
 
-        grid0.addWidget(QtWidgets.QLabel(''), 0, 0)
+        # GRID Settings
+        self.grid_label = QtWidgets.QLabel('<b>%s</b>' % _('Grid Settings'))
+        grid0.addWidget(self.grid_label, 0, 0, 1, 2)
 
-        # Theme selection
-        self.theme_label = QtWidgets.QLabel('%s:' % _('Theme'))
-        self.theme_label.setToolTip(
-            _("Select a theme for FlatCAM.\n"
-              "The application will restart after change.")
+        # Grid X Entry
+        self.gridx_label = QtWidgets.QLabel('%s:' % _('X value'))
+        self.gridx_label.setToolTip(
+           _("This is the Grid snap value on X axis.")
         )
-        self.theme_radio = RadioSet([
-            {"label": _("Light"), "value": "white"},
-            {"label": _("Dark"), "value": "black"}
-        ], orientation='horizontal', stretch=False)
+        self.gridx_entry = FCDoubleSpinner()
+        self.gridx_entry.set_precision(self.decimals)
+        self.gridx_entry.setSingleStep(0.1)
 
-        grid0.addWidget(self.theme_label, 1, 0)
-        grid0.addWidget(self.theme_radio, 1, 1)
+        grid0.addWidget(self.gridx_label, 1, 0)
+        grid0.addWidget(self.gridx_entry, 1, 1)
 
-        # Layout selection
-        self.layout_label = QtWidgets.QLabel('%s:' % _('Layout'))
-        self.layout_label.setToolTip(
-            _("Select an layout for FlatCAM.\n"
-              "It is applied immediately.")
+        # Grid Y Entry
+        self.gridy_label = QtWidgets.QLabel('%s:' % _('Y value'))
+        self.gridy_label.setToolTip(
+            _("This is the Grid snap value on Y axis.")
         )
-        self.layout_combo = FCComboBox()
-        # 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.gridy_entry = FCDoubleSpinner()
+        self.gridy_entry.set_precision(self.decimals)
+        self.gridy_entry.setSingleStep(0.1)
+
+        grid0.addWidget(self.gridy_label, 2, 0)
+        grid0.addWidget(self.gridy_entry, 2, 1)
 
-        grid0.addWidget(self.layout_label, 2, 0)
-        grid0.addWidget(self.layout_combo, 2, 1)
+        # Snap Max Entry
+        self.snap_max_label = QtWidgets.QLabel('%s:' % _('Snap Max'))
+        self.snap_max_label.setToolTip(_("Max. magnet distance"))
+        self.snap_max_dist_entry = FCDoubleSpinner()
+        self.snap_max_dist_entry.set_precision(self.decimals)
+        self.snap_max_dist_entry.setSingleStep(0.1)
 
-        # Set the current index for layout_combo
-        settings = QSettings("Open Source", "FlatCAM")
-        if settings.contains("layout"):
-            layout = settings.value('layout', type=str)
-            idx = self.layout_combo.findText(layout.capitalize())
-            self.layout_combo.setCurrentIndex(idx)
+        grid0.addWidget(self.snap_max_label, 3, 0)
+        grid0.addWidget(self.snap_max_dist_entry, 3, 1)
 
-        # Style selection
-        self.style_label = QtWidgets.QLabel('%s:' % _('Style'))
-        self.style_label.setToolTip(
-            _("Select an style for FlatCAM.\n"
-              "It will be applied at the next app start.")
+        separator_line = QtWidgets.QFrame()
+        separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+        separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+        grid0.addWidget(separator_line, 4, 0, 1, 2)
+
+        # Workspace
+        self.workspace_label = QtWidgets.QLabel('<b>%s</b>' % _('Workspace Settings'))
+        grid0.addWidget(self.workspace_label, 5, 0, 1, 2)
+
+        self.workspace_cb = FCCheckBox('%s' % _('Active'))
+        self.workspace_cb.setToolTip(
+           _("Draw a delimiting rectangle on canvas.\n"
+             "The purpose is to illustrate the limits for our work.")
         )
-        self.style_combo = FCComboBox()
-        self.style_combo.addItems(QtWidgets.QStyleFactory.keys())
-        # find current style
-        index = self.style_combo.findText(QtWidgets.qApp.style().objectName(), QtCore.Qt.MatchFixedString)
-        self.style_combo.setCurrentIndex(index)
-        self.style_combo.activated[str].connect(self.handle_style)
 
-        grid0.addWidget(self.style_label, 3, 0)
-        grid0.addWidget(self.style_combo, 3, 1)
+        grid0.addWidget(self.workspace_cb, 6, 0, 1, 2)
 
-        # Enable High DPI Support
-        self.hdpi_label = QtWidgets.QLabel('%s:' % _('HDPI Support'))
-        self.hdpi_label.setToolTip(
-            _("Enable High DPI support for FlatCAM.\n"
-              "It will be applied at the next app start.")
+        self.workspace_type_lbl = QtWidgets.QLabel('%s:' % _('Size'))
+        self.workspace_type_lbl.setToolTip(
+           _("Select the type of rectangle to be used on canvas,\n"
+             "as valid workspace.")
         )
-        self.hdpi_cb = FCCheckBox()
+        self.wk_cb = FCComboBox()
 
-        settings = QSettings("Open Source", "FlatCAM")
-        if settings.contains("hdpi"):
-            self.hdpi_cb.set_value(settings.value('hdpi', type=int))
-        else:
-            self.hdpi_cb.set_value(False)
-        self.hdpi_cb.stateChanged.connect(self.handle_hdpi)
+        grid0.addWidget(self.workspace_type_lbl, 7, 0)
+        grid0.addWidget(self.wk_cb, 7, 1)
 
-        grid0.addWidget(self.hdpi_label, 4, 0)
-        grid0.addWidget(self.hdpi_cb, 4, 1)
+        self.pagesize = dict()
+        self.pagesize.update(
+            {
+                'A0': (841, 1189),
+                'A1': (594, 841),
+                'A2': (420, 594),
+                'A3': (297, 420),
+                'A4': (210, 297),
+                'A5': (148, 210),
+                'A6': (105, 148),
+                'A7': (74, 105),
+                'A8': (52, 74),
+                'A9': (37, 52),
+                'A10': (26, 37),
 
-        # Clear Settings
-        self.clear_label = QtWidgets.QLabel('%s:' % _('Clear GUI Settings'))
-        self.clear_label.setToolTip(
-            _("Clear the GUI settings for FlatCAM,\n"
-              "such as: layout, gui state, style, hdpi support etc.")
-        )
-        self.clear_btn = FCButton(_("Clear"))
-        self.clear_btn.clicked.connect(self.handle_clear)
+                'B0': (1000, 1414),
+                'B1': (707, 1000),
+                'B2': (500, 707),
+                'B3': (353, 500),
+                'B4': (250, 353),
+                'B5': (176, 250),
+                'B6': (125, 176),
+                'B7': (88, 125),
+                'B8': (62, 88),
+                'B9': (44, 62),
+                'B10': (31, 44),
+
+                'C0': (917, 1297),
+                'C1': (648, 917),
+                'C2': (458, 648),
+                'C3': (324, 458),
+                'C4': (229, 324),
+                'C5': (162, 229),
+                'C6': (114, 162),
+                'C7': (81, 114),
+                'C8': (57, 81),
+                'C9': (40, 57),
+                'C10': (28, 40),
 
-        grid0.addWidget(self.clear_label, 5, 0)
-        grid0.addWidget(self.clear_btn, 5, 1)
+                # American paper sizes
+                'LETTER': (8.5, 11),
+                'LEGAL': (8.5, 14),
+                'ELEVENSEVENTEEN': (11, 17),
 
-        # Enable Hover box
-        self.hover_label = QtWidgets.QLabel('%s:' % _('Hover Shape'))
-        self.hover_label.setToolTip(
-            _("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.")
+                # From https://en.wikipedia.org/wiki/Paper_size
+                'JUNIOR_LEGAL': (5, 8),
+                'HALF_LETTER': (5.5, 8),
+                'GOV_LETTER': (8, 10.5),
+                'GOV_LEGAL': (8.5, 13),
+                'LEDGER': (17, 11),
+            }
         )
-        self.hover_cb = FCCheckBox()
 
-        grid0.addWidget(self.hover_label, 6, 0)
-        grid0.addWidget(self.hover_cb, 6, 1)
+        page_size_list = list(self.pagesize.keys())
 
-        # Enable Selection box
-        self.selection_label = QtWidgets.QLabel('%s:' % _('Sel. Shape'))
-        self.selection_label.setToolTip(
-            _("Enable the display of a selection shape for FlatCAM objects.\n"
-              "It is displayed whenever the mouse selects an object\n"
-              "either by clicking or dragging mouse from left to right or\n"
-              "right to left.")
-        )
-        self.selection_cb = FCCheckBox()
+        self.wk_cb.addItems(page_size_list)
 
-        grid0.addWidget(self.selection_label, 7, 0)
-        grid0.addWidget(self.selection_cb, 7, 1)
+        # Page orientation
+        self.wk_orientation_label = QtWidgets.QLabel('%s:' % _("Orientation"))
+        self.wk_orientation_label.setToolTip(_("Can be:\n"
+                                               "- Portrait\n"
+                                               "- Landscape"))
 
-        grid0.addWidget(QtWidgets.QLabel(''), 8, 0)
+        self.wk_orientation_radio = RadioSet([{'label': _('Portrait'), 'value': 'p'},
+                                              {'label': _('Landscape'), 'value': 'l'},
+                                              ], stretch=False)
+
+        self.wks = OptionalInputSection(self.workspace_cb,
+                                        [
+                                            self.workspace_type_lbl,
+                                            self.wk_cb,
+                                            self.wk_orientation_label,
+                                            self.wk_orientation_radio
+                                        ])
+
+        grid0.addWidget(self.wk_orientation_label, 8, 0)
+        grid0.addWidget(self.wk_orientation_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)
+
+        # Font Size
+        self.font_size_label = QtWidgets.QLabel('<b>%s</b>' % _('Font Size'))
+        grid0.addWidget(self.font_size_label, 10, 0, 1, 2)
 
         # Notebook Font Size
-        self.notebook_font_size_label = QtWidgets.QLabel('%s:' % _('NB Font Size'))
+        self.notebook_font_size_label = QtWidgets.QLabel('%s:' % _('Notebook'))
         self.notebook_font_size_label.setToolTip(
             _("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"
@@ -864,11 +889,11 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
         else:
             self.notebook_font_size_spinner.set_value(12)
 
-        grid0.addWidget(self.notebook_font_size_label, 9, 0)
-        grid0.addWidget(self.notebook_font_size_spinner, 9, 1)
+        grid0.addWidget(self.notebook_font_size_label, 11, 0)
+        grid0.addWidget(self.notebook_font_size_spinner, 11, 1)
 
         # Axis Font Size
-        self.axis_font_size_label = QtWidgets.QLabel('%s:' % _('Axis Font Size'))
+        self.axis_font_size_label = QtWidgets.QLabel('%s:' % _('Axis'))
         self.axis_font_size_label.setToolTip(
             _("This sets the font size for canvas axis.")
         )
@@ -883,11 +908,11 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
         else:
             self.axis_font_size_spinner.set_value(8)
 
-        grid0.addWidget(self.axis_font_size_label, 10, 0)
-        grid0.addWidget(self.axis_font_size_spinner, 10, 1)
+        grid0.addWidget(self.axis_font_size_label, 12, 0)
+        grid0.addWidget(self.axis_font_size_spinner, 12, 1)
 
         # TextBox Font Size
-        self.textbox_font_size_label = QtWidgets.QLabel('%s:' % _('Textbox Font Size'))
+        self.textbox_font_size_label = QtWidgets.QLabel('%s:' % _('Textbox'))
         self.textbox_font_size_label.setToolTip(
             _("This sets the font size for the Textbox GUI\n"
               "elements that are used in FlatCAM.")
@@ -903,11 +928,8 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
         else:
             self.textbox_font_size_spinner.set_value(10)
 
-        grid0.addWidget(self.textbox_font_size_label, 11, 0)
-        grid0.addWidget(self.textbox_font_size_spinner, 11, 1)
-
-        # Just to add empty rows
-        grid0.addWidget(QtWidgets.QLabel(''), 12, 0)
+        grid0.addWidget(self.textbox_font_size_label, 13, 0)
+        grid0.addWidget(self.textbox_font_size_spinner, 13, 1)
 
         # -----------------------------------------------------------
         # ----------- APPLICATION STARTUP SETTINGS ------------------
@@ -916,10 +938,10 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
         separator_line = QtWidgets.QFrame()
         separator_line.setFrameShape(QtWidgets.QFrame.HLine)
         separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
-        grid0.addWidget(separator_line, 13, 0, 1, 2)
+        grid0.addWidget(separator_line, 14, 0, 1, 2)
 
         self.startup_label = QtWidgets.QLabel('<b>%s</b>' % _('Startup Settings'))
-        grid0.addWidget(self.startup_label, 14, 0, 1, 2)
+        grid0.addWidget(self.startup_label, 15, 0, 1, 2)
 
         # Splash Screen
         self.splash_cb = FCCheckBox('%s' % _('Splash Screen'))
@@ -933,14 +955,14 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
         else:
             self.splash_cb.set_value(False)
 
-        grid0.addWidget(self.splash_cb, 15, 0, 1, 2)
+        grid0.addWidget(self.splash_cb, 16, 0, 1, 2)
 
         # Sys Tray Icon
         self.systray_cb = FCCheckBox('%s' % _('Sys Tray Icon'))
         self.systray_cb.setToolTip(
             _("Enable display of FlatCAM icon in Sys Tray.")
         )
-        grid0.addWidget(self.systray_cb, 16, 0, 1, 2)
+        grid0.addWidget(self.systray_cb, 17, 0, 1, 2)
 
         # Shell StartUp CB
         self.shell_startup_cb = FCCheckBox(label='%s' % _('Show Shell'))
@@ -949,7 +971,7 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
               "start automatically at startup.")
         )
 
-        grid0.addWidget(self.shell_startup_cb, 17, 0, 1, 2)
+        grid0.addWidget(self.shell_startup_cb, 18, 0, 1, 2)
 
         # Project at StartUp CB
         self.project_startup_cb = FCCheckBox(label='%s' % _('Show Project'))
@@ -957,7 +979,7 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
             _("Check this box if you want the project/selected/tool tab area to\n"
               "to be shown automatically at startup.")
         )
-        grid0.addWidget(self.project_startup_cb, 18, 0, 1, 2)
+        grid0.addWidget(self.project_startup_cb, 19, 0, 1, 2)
 
         # -----------------------------------------------------------
         # -------------- MOUSE SETTINGS -----------------------------
@@ -1148,43 +1170,6 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
 
         self.app.cursor_color_3D = self.app.defaults["global_cursor_color"]
 
-    def handle_style(self, style):
-        # set current style
-        settings = QSettings("Open Source", "FlatCAM")
-        settings.setValue('style', style)
-
-        # This will write the setting to the platform specific storage.
-        del settings
-
-    def handle_hdpi(self, state):
-        # set current HDPI
-        settings = QSettings("Open Source", "FlatCAM")
-        settings.setValue('hdpi', state)
-
-        # This will write the setting to the platform specific storage.
-        del settings
-
-    def handle_clear(self):
-        msgbox = QtWidgets.QMessageBox()
-        msgbox.setText(_("Are you sure you want to delete the GUI Settings? "
-                         "\n")
-                       )
-        msgbox.setWindowTitle(_("Clear GUI Settings"))
-        msgbox.setWindowIcon(QtGui.QIcon(self.resource_loc + '/trash32.png'))
-        bt_yes = msgbox.addButton(_('Yes'), QtWidgets.QMessageBox.YesRole)
-        bt_no = msgbox.addButton(_('No'), QtWidgets.QMessageBox.NoRole)
-
-        msgbox.setDefaultButton(bt_no)
-        msgbox.exec_()
-        response = msgbox.clickedButton()
-
-        if response == bt_yes:
-            settings = QSettings("Open Source", "FlatCAM")
-            for key in settings.allKeys():
-                settings.remove(key)
-            # This will write the setting to the platform specific storage.
-            del settings
-
 
 class GeneralAppPrefGroupUI(OptionsGroupUI):
     def __init__(self, decimals=4, parent=None):
@@ -1247,11 +1232,16 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
                                    "Intel HD3000 or older. In this case the plot area will be black therefore\n"
                                    "use the Legacy(2D) mode."))
         self.ge_radio = RadioSet([{'label': _('Legacy(2D)'), 'value': '2D'},
-                                  {'label': _('OpenGL(3D)'), 'value': '3D'}])
+                                  {'label': _('OpenGL(3D)'), 'value': '3D'}],
+                                 orientation='vertical')
 
         grid0.addWidget(self.ge_label, 3, 0)
         grid0.addWidget(self.ge_radio, 3, 1)
-        grid0.addWidget(QtWidgets.QLabel(''), 4, 0)
+
+        separator_line = QtWidgets.QFrame()
+        separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+        separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+        grid0.addWidget(separator_line, 4, 0, 1, 2)
 
         # Application Level for FlatCAM
         self.app_level_label = QtWidgets.QLabel('<span style="color:red;"><b>%s:</b></span>' % _('APP. LEVEL'))
@@ -1277,25 +1267,29 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
         grid0.addWidget(self.portability_label, 6, 0)
         grid0.addWidget(self.portability_cb, 6, 1)
 
+        separator_line = QtWidgets.QFrame()
+        separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+        separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+        grid0.addWidget(separator_line, 7, 0, 1, 2)
+
         # Languages for FlatCAM
-        self.languagelabel = QtWidgets.QLabel('<b>%s:</b>' % _('Languages'))
+        self.languagelabel = QtWidgets.QLabel('<b>%s</b>' % _('Languages'))
         self.languagelabel.setToolTip(_("Set the language used throughout FlatCAM."))
         self.language_cb = FCComboBox()
 
-        grid0.addWidget(self.languagelabel, 7, 0)
-        grid0.addWidget(self.language_cb, 7, 1)
+        grid0.addWidget(self.languagelabel, 8, 0, 1, 2)
+        grid0.addWidget(self.language_cb, 9, 0, 1, 2)
 
         self.language_apply_btn = FCButton(_("Apply Language"))
         self.language_apply_btn.setToolTip(_("Set the language used throughout FlatCAM.\n"
-                                             "The app will restart after click."
-                                             "Windows: When FlatCAM is installed in Program Files\n"
-                                             "directory, it is possible that the app will not\n"
-                                             "restart after the button is clicked due of Windows\n"
-                                             "security features. In this case the language will be\n"
-                                             "applied at the next app start."))
+                                             "The app will restart after click."))
+
+        grid0.addWidget(self.language_apply_btn, 15, 0, 1, 2)
 
-        grid0.addWidget(self.language_apply_btn, 8, 0, 1, 2)
-        grid0.addWidget(QtWidgets.QLabel(''), 9, 0)
+        separator_line = QtWidgets.QFrame()
+        separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+        separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+        grid0.addWidget(separator_line, 16, 0, 1, 2)
 
         # Version Check CB
         self.version_check_label = QtWidgets.QLabel('%s:' % _('Version Check'))
@@ -1309,8 +1303,8 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
               "for a new version automatically at startup.")
         )
 
-        grid0.addWidget(self.version_check_label, 10, 0)
-        grid0.addWidget(self.version_check_cb, 10, 1)
+        grid0.addWidget(self.version_check_label, 17, 0)
+        grid0.addWidget(self.version_check_cb, 17, 1)
 
         # Send Stats CB
         self.send_stats_label = QtWidgets.QLabel('%s:' % _('Send Stats'))
@@ -1324,8 +1318,8 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
               "stats automatically at startup, to help improve FlatCAM.")
         )
 
-        grid0.addWidget(self.send_stats_label, 11, 0)
-        grid0.addWidget(self.send_stats_cb, 11, 1)
+        grid0.addWidget(self.send_stats_label, 18, 0)
+        grid0.addWidget(self.send_stats_cb, 18, 1)
 
         self.ois_version_check = OptionalInputSection(self.version_check_cb, [self.send_stats_cb])
 
@@ -1350,8 +1344,8 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
         )
         self.worker_number_sb.set_range(2, 16)
 
-        grid0.addWidget(self.worker_number_label, 14, 0)
-        grid0.addWidget(self.worker_number_sb, 14, 1)
+        grid0.addWidget(self.worker_number_label, 19, 0)
+        grid0.addWidget(self.worker_number_sb, 19, 1)
 
         # Geometric tolerance
         tol_label = QtWidgets.QLabel('%s:' % _("Geo Tolerance"))
@@ -1375,9 +1369,13 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
         self.tol_entry.setSingleStep(0.001)
         self.tol_entry.set_precision(6)
 
-        grid0.addWidget(tol_label, 15, 0)
-        grid0.addWidget(self.tol_entry, 15, 1)
-        grid0.addWidget(QtWidgets.QLabel(''), 16, 0)
+        grid0.addWidget(tol_label, 20, 0)
+        grid0.addWidget(self.tol_entry, 20, 1)
+
+        separator_line = QtWidgets.QFrame()
+        separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+        separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+        grid0.addWidget(separator_line, 21, 0, 1, 2)
 
         # Open behavior
         self.open_style_cb = FCCheckBox('%s' % _('"Open" behavior'))
@@ -1388,7 +1386,7 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
               "path for saving files or the path for opening files.")
         )
 
-        grid0.addWidget(self.open_style_cb, 17, 0, 1, 2)
+        grid0.addWidget(self.open_style_cb, 22, 0, 1, 2)
 
         # Save compressed project CB
         self.save_type_cb = FCCheckBox(_('Save Compressed Project'))
@@ -1397,7 +1395,7 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
               "When checked it will save a compressed FlatCAM project.")
         )
 
-        grid0.addWidget(self.save_type_cb, 18, 0, 1, 2)
+        grid0.addWidget(self.save_type_cb, 23, 0, 1, 2)
 
         # Project LZMA Comppression Level
         self.compress_spinner = FCSpinner()
@@ -1409,8 +1407,8 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
               "but require more RAM usage and more processing time.")
         )
 
-        grid0.addWidget(self.compress_label, 19, 0)
-        grid0.addWidget(self.compress_spinner, 19, 1)
+        grid0.addWidget(self.compress_label, 24, 0)
+        grid0.addWidget(self.compress_spinner, 24, 1)
 
         self.proj_ois = OptionalInputSection(self.save_type_cb, [self.compress_label, self.compress_spinner], True)
 
@@ -1423,8 +1421,8 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
               "but the menu will hold only so much.")
         )
 
-        grid0.addWidget(self.bm_limit_label, 20, 0)
-        grid0.addWidget(self.bm_limit_spinner, 20, 1)
+        grid0.addWidget(self.bm_limit_label, 25, 0)
+        grid0.addWidget(self.bm_limit_spinner, 25, 1)
 
         # Machinist settings that allow unsafe settings
         self.machinist_cb = FCCheckBox(_("Allow Machinist Unsafe Settings"))
@@ -1436,7 +1434,7 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
               "<<WARNING>>: Don't change this unless you know what you are doing !!!")
         )
 
-        grid0.addWidget(self.machinist_cb, 21, 0, 1, 2)
+        grid0.addWidget(self.machinist_cb, 26, 0, 1, 2)
 
         separator_line = QtWidgets.QFrame()
         separator_line.setFrameShape(QtWidgets.QFrame.HLine)