- moved some of the GUI related methods from FlatCAMApp.App to the flatcamGUI.FlatCAMGUI class

- moved Shortcuts Tab creation in it's own class
This commit is contained in:
Marius Stanciu 2020-05-18 15:43:07 +03:00 committed by Marius
parent a9c777030b
commit 4c83e87feb
6 changed files with 2486 additions and 2462 deletions

View File

@ -14,7 +14,8 @@ CHANGELOG for FlatCAM beta
- trying to fix the pixmap load crash when running a FlatCAMScript
- made the workspace label in the status bar clickable and also added a status bar message on status toggle for workspace
- modified the GUI for Film and Panelize Tools
- moved some of the GUI related methods from FlatCAMApp.App to the flatcamGUI.FlatCAMGUI class
- moved Shortcuts Tab creation in it's own class
17.05.2020

View File

@ -20,7 +20,6 @@ import time
import ctypes
import traceback
from PyQt5.QtCore import pyqtSlot, Qt
from shapely.geometry import Point, MultiPolygon
from io import StringIO
@ -72,7 +71,7 @@ from camlib import to_dict, dict2obj, ET, ParseError, Geometry, CNCjob
from flatcamGUI.PlotCanvas import *
from flatcamGUI.PlotCanvasLegacy import *
from flatcamGUI.FlatCAMGUI import *
from flatcamGUI.GUIElements import FCFileSaveDialog
from flatcamGUI.GUIElements import FCFileSaveDialog, message_dialog, FlatCAMSystemTray
# FlatCAM Pre-processors
from FlatCAMPostProc import load_preprocessors
@ -528,12 +527,6 @@ class App(QtCore.QObject):
self.ui.geom_update[int, int, int, int, int].connect(self.save_geometry)
self.ui.final_save.connect(self.final_save)
# restore the toolbar view
self.restore_toolbar_view()
# restore the GUI geometry
self.restore_main_win_geom()
# set FlatCAM units in the Status bar
self.set_screen_units(self.defaults['units'])
@ -783,7 +776,7 @@ class App(QtCore.QObject):
self.inform.connect(self.info)
# signal to be called when the app is quiting
self.app_quit.connect(self.quit_application, type=Qt.QueuedConnection)
self.message.connect(self.message_dialog)
self.message.connect(lambda: message_dialog(parent=self.ui))
# self.progress.connect(self.set_progress_bar)
# signals that are emitted when object state changes
@ -895,17 +888,17 @@ class App(QtCore.QObject):
self.ui.menuview_replot.triggered.connect(self.plot_all)
self.ui.menuview_toggle_code_editor.triggered.connect(self.on_toggle_code_editor)
self.ui.menuview_toggle_fscreen.triggered.connect(self.on_fullscreen)
self.ui.menuview_toggle_parea.triggered.connect(self.on_toggle_plotarea)
self.ui.menuview_toggle_notebook.triggered.connect(self.on_toggle_notebook)
self.ui.menu_toggle_nb.triggered.connect(self.on_toggle_notebook)
self.ui.menuview_toggle_grid.triggered.connect(self.on_toggle_grid)
self.ui.menuview_toggle_fscreen.triggered.connect(self.ui.on_fullscreen)
self.ui.menuview_toggle_parea.triggered.connect(self.ui.on_toggle_plotarea)
self.ui.menuview_toggle_notebook.triggered.connect(self.ui.on_toggle_notebook)
self.ui.menu_toggle_nb.triggered.connect(self.ui.on_toggle_notebook)
self.ui.menuview_toggle_grid.triggered.connect(self.ui.on_toggle_grid)
self.ui.menuview_toggle_grid_lines.triggered.connect(self.on_toggle_grid_lines)
self.ui.menuview_toggle_axis.triggered.connect(self.on_toggle_axis)
self.ui.menuview_toggle_workspace.triggered.connect(self.on_workspace_toggle)
self.ui.menuview_toggle_hud.triggered.connect(self.on_toggle_hud)
self.ui.menutoolshell.triggered.connect(self.toggle_shell)
self.ui.menutoolshell.triggered.connect(self.ui.toggle_shell_ui)
self.ui.menuhelp_about.triggered.connect(self.on_about)
self.ui.menuhelp_manual.triggered.connect(lambda: webbrowser.open(self.manual_url))
@ -940,7 +933,7 @@ class App(QtCore.QObject):
# Context Menu
self.ui.popmenu_disable.triggered.connect(lambda: self.toggle_plots(self.collection.get_selected()))
self.ui.popmenu_panel_toggle.triggered.connect(self.on_toggle_notebook)
self.ui.popmenu_panel_toggle.triggered.connect(self.ui.on_toggle_notebook)
self.ui.popmenu_new_geo.triggered.connect(self.new_geometry_object)
self.ui.popmenu_new_grb.triggered.connect(self.new_gerber_object)
@ -1496,9 +1489,6 @@ class App(QtCore.QObject):
# Variable to hold the status of the grid lines
self.toggle_grid_lines = True
# Variable to store the status of the fullscreen event
self.toggle_fscreen = False
# Variable to store the status of the code editor
self.toggle_codeeditor = False
@ -2045,7 +2035,7 @@ class App(QtCore.QObject):
# re-add the TCL Shell action to the Tools menu and reconnect it to ist slot function
self.ui.menutoolshell = self.ui.menutool.addAction(QtGui.QIcon(self.resource_location + '/shell16.png'),
'&Command Line\tS')
self.ui.menutoolshell.triggered.connect(self.toggle_shell)
self.ui.menutoolshell.triggered.connect(self.ui.toggle_shell_ui)
# third install all of them
try:
@ -2101,7 +2091,7 @@ class App(QtCore.QObject):
self.ui.locate_btn.triggered.connect(lambda: self.on_locate(obj=self.collection.get_active()))
# Scripting Toolbar Signals
self.ui.shell_btn.triggered.connect(self.toggle_shell)
self.ui.shell_btn.triggered.connect(self.ui.toggle_shell_ui)
self.ui.new_script_btn.triggered.connect(self.on_filenewscript)
self.ui.open_script_btn.triggered.connect(self.on_fileopenscript)
self.ui.run_script_btn.triggered.connect(self.on_filerunscript)
@ -2462,63 +2452,6 @@ class App(QtCore.QObject):
if msg != '':
self.shell_message(msg)
def restore_toolbar_view(self):
"""
Some toolbars may be hidden by user and here we restore the state of the toolbars visibility that
was saved in the defaults dictionary.
:return: None
"""
tb = self.defaults["global_toolbar_view"]
if tb & 1:
self.ui.toolbarfile.setVisible(True)
else:
self.ui.toolbarfile.setVisible(False)
if tb & 2:
self.ui.toolbargeo.setVisible(True)
else:
self.ui.toolbargeo.setVisible(False)
if tb & 4:
self.ui.toolbarview.setVisible(True)
else:
self.ui.toolbarview.setVisible(False)
if tb & 8:
self.ui.toolbartools.setVisible(True)
else:
self.ui.toolbartools.setVisible(False)
if tb & 16:
self.ui.exc_edit_toolbar.setVisible(True)
else:
self.ui.exc_edit_toolbar.setVisible(False)
if tb & 32:
self.ui.geo_edit_toolbar.setVisible(True)
else:
self.ui.geo_edit_toolbar.setVisible(False)
if tb & 64:
self.ui.grb_edit_toolbar.setVisible(True)
else:
self.ui.grb_edit_toolbar.setVisible(False)
# if tb & 128:
# self.ui.snap_toolbar.setVisible(True)
# else:
# self.ui.snap_toolbar.setVisible(False)
# Grid Toolbar is always active now
self.ui.snap_toolbar.setVisible(True)
if tb & 256:
self.ui.toolbarshell.setVisible(True)
else:
self.ui.toolbarshell.setVisible(False)
def on_import_preferences(self):
"""
Loads the application default settings from a saved file into
@ -2680,32 +2613,6 @@ class App(QtCore.QObject):
self.defaults["global_def_notebook_width"] = notebook_width
self.preferencesUiManager.save_defaults()
def restore_main_win_geom(self):
try:
self.ui.setGeometry(self.defaults["global_def_win_x"],
self.defaults["global_def_win_y"],
self.defaults["global_def_win_w"],
self.defaults["global_def_win_h"])
self.ui.splitter.setSizes([self.defaults["global_def_notebook_width"], 0])
except KeyError as e:
log.debug("App.restore_main_win_geom() --> %s" % str(e))
def message_dialog(self, title, message, kind="info"):
"""
Builds and show a custom QMessageBox to be used in FlatCAM.
:param title: title of the QMessageBox
:param message: message to be displayed
:param kind: type of QMessageBox; will display a specific icon.
:return:
"""
icon = {"info": QtWidgets.QMessageBox.Information,
"warning": QtWidgets.QMessageBox.Warning,
"error": QtWidgets.QMessageBox.Critical}[str(kind)]
dlg = QtWidgets.QMessageBox(icon, title, message, parent=self.ui)
dlg.setText(message)
dlg.exec_()
def register_recent(self, kind, filename):
"""
Will register the files opened into record dictionaries. The FlatCAM projects has it's own
@ -4501,75 +4408,6 @@ class App(QtCore.QObject):
self.ui.grid_gap_x_entry.set_value(val_x, decimals=self.decimals)
self.ui.grid_gap_y_entry.set_value(val_y, decimals=self.decimals)
def on_fullscreen(self, disable=False):
self.defaults.report_usage("on_fullscreen()")
flags = self.ui.windowFlags()
if self.toggle_fscreen is False and disable is False:
# self.ui.showFullScreen()
self.ui.setWindowFlags(flags | Qt.FramelessWindowHint)
a = self.ui.geometry()
self.x_pos = a.x()
self.y_pos = a.y()
self.width = a.width()
self.height = a.height()
# set new geometry to full desktop rect
# Subtracting and adding the pixels below it's hack to bypass a bug in Qt5 and OpenGL that made that a
# window drawn with OpenGL in fullscreen will not show any other windows on top which means that menus and
# everything else will not work without this hack. This happen in Windows.
# https://bugreports.qt.io/browse/QTBUG-41309
desktop = QtWidgets.QApplication.desktop()
screen = desktop.screenNumber(QtGui.QCursor.pos())
rec = desktop.screenGeometry(screen)
x = rec.x() - 1
y = rec.y() - 1
h = rec.height() + 2
w = rec.width() + 2
self.ui.setGeometry(x, y, w, h)
self.ui.show()
for tb in self.ui.findChildren(QtWidgets.QToolBar):
tb.setVisible(False)
self.ui.snap_toolbar.setVisible(True) # This is always visible
# self.ui.splitter_left.setVisible(False)
self.ui.splitter.setSizes([0, 1])
self.toggle_fscreen = True
elif self.toggle_fscreen is True or disable is True:
self.ui.setWindowFlags(flags & ~Qt.FramelessWindowHint)
self.ui.setGeometry(self.x_pos, self.y_pos, self.width, self.height)
self.ui.showNormal()
self.restore_toolbar_view()
# self.ui.splitter_left.setVisible(True)
self.toggle_fscreen = False
def on_toggle_plotarea(self):
self.defaults.report_usage("on_toggle_plotarea()")
try:
name = self.ui.plot_tab_area.widget(0).objectName()
except AttributeError:
self.ui.plot_tab_area.addTab(self.ui.plot_tab, "Plot Area")
# remove the close button from the Plot Area tab (first tab index = 0) as this one will always be ON
self.ui.plot_tab_area.protectTab(0)
return
if name != 'plotarea_tab':
self.ui.plot_tab_area.insertTab(0, self.ui.plot_tab, "Plot Area")
# remove the close button from the Plot Area tab (first tab index = 0) as this one will always be ON
self.ui.plot_tab_area.protectTab(0)
else:
self.ui.plot_tab_area.closeTab(0)
def on_toggle_notebook(self):
if self.ui.splitter.sizes()[0] == 0:
self.ui.splitter.setSizes([1, 1])
self.ui.menu_toggle_nb.setChecked(True)
else:
self.ui.splitter.setSizes([0, 1])
self.ui.menu_toggle_nb.setChecked(False)
def on_toggle_axis(self):
self.defaults.report_usage("on_toggle_axis()")
@ -4603,11 +4441,6 @@ class App(QtCore.QObject):
def on_toggle_hud(self):
self.plotcanvas.on_toggle_hud(state=False if self.plotcanvas.hud_enabled else True)
def on_toggle_grid(self):
self.defaults.report_usage("on_toggle_grid()")
self.ui.grid_snap_btn.trigger()
def on_toggle_grid_lines(self):
self.defaults.report_usage("on_toggle_grd_lines()")
@ -10789,34 +10622,6 @@ class App(QtCore.QObject):
self.preferencesUiManager.defaults_read_form()
self.options.update(self.defaults)
def toggle_shell(self):
"""
Toggle shell: if is visible close it, if it is closed then open it
:return: None
"""
self.defaults.report_usage("toggle_shell()")
if self.ui.shell_dock.isVisible():
self.ui.shell_dock.hide()
self.plotcanvas.native.setFocus()
else:
self.ui.shell_dock.show()
# I want to take the focus and give it to the Tcl Shell when the Tcl Shell is run
# self.shell._edit.setFocus()
QtCore.QTimer.singleShot(0, lambda: self.ui.shell_dock.widget()._edit.setFocus())
# HACK - simulate a mouse click - alternative
# no_km = QtCore.Qt.KeyboardModifier(QtCore.Qt.NoModifier) # no KB modifier
# pos = QtCore.QPoint((self.shell._edit.width() - 40), (self.shell._edit.height() - 2))
# e = QtGui.QMouseEvent(QtCore.QEvent.MouseButtonPress, pos, QtCore.Qt.LeftButton, QtCore.Qt.LeftButton,
# no_km)
# QtWidgets.qApp.sendEvent(self.shell._edit, e)
# f = QtGui.QMouseEvent(QtCore.QEvent.MouseButtonRelease, pos, QtCore.Qt.LeftButton, QtCore.Qt.LeftButton,
# no_km)
# QtWidgets.qApp.sendEvent(self.shell._edit, f)
def shell_message(self, msg, show=False, error=False, warning=False, success=False, selected=False):
"""
Shows a message on the FlatCAM Shell

View File

@ -6,7 +6,7 @@
# MIT Licence #
# ##########################################################
from flatcamGUI.FlatCAMGUI import FlatCAMActivityView
from flatcamGUI.GUIElements import FlatCAMActivityView
from PyQt5 import QtCore
import weakref

File diff suppressed because it is too large Load Diff

View File

@ -2475,7 +2475,8 @@ class SpinBoxDelegate(QtWidgets.QItemDelegate):
def updateEditorGeometry(self, editor, option, index):
editor.setGeometry(option.rect)
def setDecimals(self, spinbox, digits):
@staticmethod
def setDecimals(spinbox, digits):
spinbox.setDecimals(digits)
@ -2942,6 +2943,207 @@ class FCFileSaveDialog(QtWidgets.QFileDialog):
return filename, _filter
class FlatCAMActivityView(QtWidgets.QWidget):
"""
This class create and control the activity icon displayed in the App status bar
"""
def __init__(self, app, parent=None):
super().__init__(parent=parent)
self.app = app
if self.app.defaults["global_activity_icon"] == "Ball green":
icon = self.app.resource_location + '/active_2_static.png'
movie = self.app.resource_location + "/active_2.gif"
elif self.app.defaults["global_activity_icon"] == "Ball black":
icon = self.app.resource_location + '/active_static.png'
movie = self.app.resource_location + "/active.gif"
elif self.app.defaults["global_activity_icon"] == "Arrow green":
icon = self.app.resource_location + '/active_3_static.png'
movie = self.app.resource_location + "/active_3.gif"
elif self.app.defaults["global_activity_icon"] == "Eclipse green":
icon = self.app.resource_location + '/active_4_static.png'
movie = self.app.resource_location + "/active_4.gif"
else:
icon = self.app.resource_location + '/active_static.png'
movie = self.app.resource_location + "/active.gif"
self.setMinimumWidth(200)
self.movie_path = movie
self.icon_path = icon
self.icon = QtWidgets.QLabel(self)
self.icon.setGeometry(0, 0, 16, 12)
self.movie = QtGui.QMovie(self.movie_path)
self.icon.setMovie(self.movie)
# self.movie.start()
layout = QtWidgets.QHBoxLayout()
layout.setContentsMargins(5, 0, 5, 0)
layout.setAlignment(QtCore.Qt.AlignLeft)
self.setLayout(layout)
layout.addWidget(self.icon)
self.text = QtWidgets.QLabel(self)
self.text.setText(_("Idle."))
self.icon.setPixmap(QtGui.QPixmap(self.icon_path))
layout.addWidget(self.text)
def set_idle(self):
self.movie.stop()
self.text.setText(_("Idle."))
def set_busy(self, msg, no_movie=None):
if no_movie is not True:
self.icon.setMovie(self.movie)
self.movie.start()
self.text.setText(msg)
class FlatCAMInfoBar(QtWidgets.QWidget):
"""
This class create a place to display the App messages in the Status Bar
"""
def __init__(self, parent=None, app=None):
super(FlatCAMInfoBar, self).__init__(parent=parent)
self.app = app
self.icon = QtWidgets.QLabel(self)
self.icon.setGeometry(0, 0, 12, 12)
self.pmap = QtGui.QPixmap(self.app.resource_location + '/graylight12.png')
self.icon.setPixmap(self.pmap)
self.lock_pmaps = False
layout = QtWidgets.QHBoxLayout()
layout.setContentsMargins(5, 0, 5, 0)
self.setLayout(layout)
layout.addWidget(self.icon)
self.text = QtWidgets.QLabel(self)
self.text.setText(_("Application started ..."))
self.text.setToolTip(_("Hello!"))
layout.addWidget(self.text)
layout.addStretch()
def set_text_(self, text, color=None):
self.text.setText(text)
self.text.setToolTip(text)
if color:
self.text.setStyleSheet('color: %s' % str(color))
def set_status(self, text, level="info"):
level = str(level)
if self.lock_pmaps is not True:
self.pmap.fill()
if level == "ERROR" or level == "ERROR_NOTCL":
self.pmap = QtGui.QPixmap(self.app.resource_location + '/redlight12.png')
elif level.lower() == "success":
self.pmap = QtGui.QPixmap(self.app.resource_location + '/greenlight12.png')
elif level == "WARNING" or level == "WARNING_NOTCL":
self.pmap = QtGui.QPixmap(self.app.resource_location + '/yellowlight12.png')
elif level.lower() == "selected":
self.pmap = QtGui.QPixmap(self.app.resource_location + '/bluelight12.png')
else:
self.pmap = QtGui.QPixmap(self.app.resource_location + '/graylight12.png')
try:
self.set_text_(text)
self.icon.setPixmap(self.pmap)
except Exception as e:
log.debug("FlatCAMInfoBar.set_status() --> %s" % str(e))
class FlatCAMSystemTray(QtWidgets.QSystemTrayIcon):
"""
This class create the Sys Tray icon for the app
"""
def __init__(self, app, icon, headless=None, parent=None):
# QtWidgets.QSystemTrayIcon.__init__(self, icon, parent)
super().__init__(icon, parent=parent)
self.app = app
menu = QtWidgets.QMenu(parent)
menu_runscript = QtWidgets.QAction(QtGui.QIcon(self.app.resource_location + '/script14.png'),
'%s' % _('Run Script ...'), self)
menu_runscript.setToolTip(
_("Will run the opened Tcl Script thus\n"
"enabling the automation of certain\n"
"functions of FlatCAM.")
)
menu.addAction(menu_runscript)
menu.addSeparator()
if headless is None:
self.menu_open = menu.addMenu(QtGui.QIcon(self.app.resource_location + '/folder32_bis.png'), _('Open'))
# Open Project ...
menu_openproject = QtWidgets.QAction(QtGui.QIcon(self.app.resource_location + '/folder16.png'),
_('Open Project ...'), self)
self.menu_open.addAction(menu_openproject)
self.menu_open.addSeparator()
# Open Gerber ...
menu_opengerber = QtWidgets.QAction(QtGui.QIcon(self.app.resource_location + '/flatcam_icon24.png'),
_('Open &Gerber ...\tCtrl+G'), self)
self.menu_open.addAction(menu_opengerber)
# Open Excellon ...
menu_openexcellon = QtWidgets.QAction(QtGui.QIcon(self.app.resource_location + '/open_excellon32.png'),
_('Open &Excellon ...\tCtrl+E'), self)
self.menu_open.addAction(menu_openexcellon)
# Open G-Code ...
menu_opengcode = QtWidgets.QAction(QtGui.QIcon(self.app.resource_location + '/code.png'),
_('Open G-&Code ...'), self)
self.menu_open.addAction(menu_opengcode)
self.menu_open.addSeparator()
menu_openproject.triggered.connect(self.app.on_file_openproject)
menu_opengerber.triggered.connect(self.app.on_fileopengerber)
menu_openexcellon.triggered.connect(self.app.on_fileopenexcellon)
menu_opengcode.triggered.connect(self.app.on_fileopengcode)
exitAction = menu.addAction(_("Exit"))
exitAction.setIcon(QtGui.QIcon(self.app.resource_location + '/power16.png'))
self.setContextMenu(menu)
menu_runscript.triggered.connect(lambda: self.app.on_filerunscript(
silent=True if self.app.cmd_line_headless == 1 else False))
exitAction.triggered.connect(self.app.final_save)
def message_dialog(title, message, kind="info", parent=None):
"""
Builds and show a custom QMessageBox to be used in FlatCAM.
:param title: title of the QMessageBox
:param message: message to be displayed
:param kind: type of QMessageBox; will display a specific icon.
:param parent: parent
:return: None
"""
icon = {"info": QtWidgets.QMessageBox.Information,
"warning": QtWidgets.QMessageBox.Warning,
"error": QtWidgets.QMessageBox.Critical}[str(kind)]
dlg = QtWidgets.QMessageBox(icon, title, message, parent=parent)
dlg.setText(message)
dlg.exec_()
def rreplace(s, old, new, occurrence):
"""
Credits go here:

View File

@ -380,12 +380,11 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
def on_toggle_shell_from_settings(self, state):
"""
Toggle shell: if is visible close it, if it is closed then open it
Toggle shell ui: if is visible close it, if it is closed then open it
:return: None
"""
self.app.defaults.report_usage("on_toggle_shell_from_settings()")
if state is True:
if not self.app.ui.shell_dock.isVisible():
self.app.ui.shell_dock.show()