diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2dc06abf..fb220cf6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,8 @@ CHANGELOG for FlatCAM beta
13.01.2022
- modified the FCMessageBox to have a border and a single color inside the box
+- made sure that the FCMessageBox taskbar icons and message are the correct ones
+- applied the FCMessageBox GUI elements everywhere; there is still a hack in appTranslation file where I needed to re-implement the class due of some circular imports errors
12.01.2022
diff --git a/FlatCAM.py b/FlatCAM.py
index 95340601..e64cd91d 100644
--- a/FlatCAM.py
+++ b/FlatCAM.py
@@ -3,11 +3,13 @@ import os
import traceback
from datetime import datetime
-from PyQt6 import QtWidgets
+from PyQt6 import QtWidgets, QtGui
from PyQt6.QtCore import QSettings, QTimer
from app_Main import App
from appGUI import VisPyPatches
+from appGUI.GUIElements import FCMessageBox
+
from multiprocessing import freeze_support
# import copyreg
# import types
@@ -119,14 +121,16 @@ if __name__ == '__main__':
# show the message
try:
- msgbox = QtWidgets.QMessageBox()
+ msgbox = FCMessageBox()
displayed_msg = "The application encountered a critical error and it will close.\n"\
"Please report this error to the developers."
-
- msgbox.setText(displayed_msg)
+ title = "Critical Error"
+ msgbox.setWindowTitle(title) # taskbar still shows it
+ ic = QtGui.QIcon()
+ ic.addPixmap(QtGui.QPixmap("assets/resources/warning.png"), QtGui.QIcon.Mode.Normal)
+ msgbox.setWindowIcon(ic)
+ msgbox.setText('%s' % displayed_msg)
msgbox.setDetailedText(msg)
- msgbox.setWindowTitle("Critical Error")
- # msgbox.setWindowIcon()
msgbox.setIcon(QtWidgets.QMessageBox.Icon.Critical)
bt_yes = msgbox.addButton("Quit", QtWidgets.QMessageBox.ButtonRole.YesRole)
diff --git a/appEditors/AppTextEditor.py b/appEditors/AppTextEditor.py
index 49276f24..1defa100 100644
--- a/appEditors/AppTextEditor.py
+++ b/appEditors/AppTextEditor.py
@@ -6,7 +6,7 @@
# ##########################################################
from appGUI.GUIElements import FCFileSaveDialog, FCEntry, FCTextAreaExtended, FCTextAreaLineNumber, FCButton, \
- FCGridLayout, FCCheckBox
+ FCCheckBox, FCMessageBox
from PyQt6 import QtPrintSupport, QtWidgets, QtCore, QtGui
from reportlab.platypus import SimpleDocTemplate, Paragraph
@@ -338,13 +338,15 @@ class AppTextEditor(QtWidgets.QWidget):
r = self.code_editor.find(str(text_to_be_found), flags)
if r is False:
- msgbox = QtWidgets.QMessageBox()
- msgbox.setWindowTitle(_('Find'))
- msgbox.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/find32.png'))
- msgbox.setIcon(QtWidgets.QMessageBox.Icon.Question)
+ msgbox = FCMessageBox()
+ title = _("End of document.")
+ txt = '%s' % _("Start from beginning?")
+ msgbox.setWindowTitle(_('Find')) # taskbar still shows it
+ msgbox.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/flatcam_icon128.png'))
+ msgbox.setText('%s' % title)
+ msgbox.setInformativeText(txt)
+ msgbox.setIconPixmap(QtGui.QPixmap(self.app.resource_location + '/find32.png'))
- msgbox.setText(_("End of document."))
- msgbox.setInformativeText('%s' % _("Start from beginning?"))
bt_ok = msgbox.addButton(_('Ok'), QtWidgets.QMessageBox.ButtonRole.AcceptRole)
bt_cancel = msgbox.addButton(_('Cancel'), QtWidgets.QMessageBox.ButtonRole.RejectRole)
diff --git a/appGUI/MainGUI.py b/appGUI/MainGUI.py
index d9c8b45d..3eff4d4c 100644
--- a/appGUI/MainGUI.py
+++ b/appGUI/MainGUI.py
@@ -2339,11 +2339,14 @@ class MainGUI(QtWidgets.QMainWindow):
response = None
bt_yes = None
if forced_clear is False:
- 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'))
- msgbox.setIcon(QtWidgets.QMessageBox.Icon.Question)
+ msgbox = FCMessageBox()
+ title = _("Clear GUI Settings")
+ txt = _("Are you sure you want to delete the GUI Settings? \n")
+ msgbox.setWindowTitle(title) # taskbar still shows it
+ msgbox.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/flatcam_icon128.png'))
+ msgbox.setText('%s' % title)
+ msgbox.setInformativeText(txt)
+ msgbox.setIconPixmap(QtGui.QPixmap(self.app.resource_location + '/trash32.png'))
bt_yes = msgbox.addButton(_('Yes'), QtWidgets.QMessageBox.ButtonRole.YesRole)
bt_no = msgbox.addButton(_('No'), QtWidgets.QMessageBox.ButtonRole.NoRole)
@@ -3410,11 +3413,13 @@ class MainGUI(QtWidgets.QMainWindow):
'out of the first item. In the end press ~X~ key or\n'
'the toolbar button.')
- messagebox = QtWidgets.QMessageBox()
- messagebox.setText(msg)
- messagebox.setWindowTitle(_("Warning"))
- messagebox.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/warning.png'))
- messagebox.setIcon(QtWidgets.QMessageBox.Icon.Question)
+ messagebox = FCMessageBox()
+ title = _("Warning")
+ messagebox.setWindowTitle(title) # taskbar still shows it
+ messagebox.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/flatcam_icon128.png'))
+ messagebox.setText('%s' % title)
+ messagebox.setInformativeText(msg)
+ messagebox.setIcon(QtWidgets.QMessageBox.Icon.Warning)
messagebox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok)
messagebox.setDefaultButton(QtWidgets.QMessageBox.StandardButton.Ok)
@@ -3570,10 +3575,12 @@ class MainGUI(QtWidgets.QMainWindow):
msg = _("Please select geometry items \n"
"on which to perform Intersection Tool.")
- messagebox = QtWidgets.QMessageBox()
- messagebox.setText(msg)
- messagebox.setWindowTitle(_("Warning"))
- messagebox.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/warning.png'))
+ messagebox = FCMessageBox()
+ title = _("Warning")
+ messagebox.setWindowTitle(title) # taskbar still shows it
+ messagebox.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/flatcam_icon128.png'))
+ messagebox.setText('%s' % title)
+ messagebox.setInformativeText(msg)
messagebox.setIcon(QtWidgets.QMessageBox.Icon.Warning)
messagebox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok)
@@ -3617,10 +3624,12 @@ class MainGUI(QtWidgets.QMainWindow):
"Please select geometry items \n"
"on which to perform Substraction Tool.")
- messagebox = QtWidgets.QMessageBox()
- messagebox.setText(msg)
- messagebox.setWindowTitle(_("Warning"))
- messagebox.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/warning.png'))
+ messagebox = FCMessageBox()
+ title = _("Warning")
+ messagebox.setWindowTitle(title) # taskbar still shows it
+ messagebox.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/flatcam_icon128.png'))
+ messagebox.setText('%s' % title)
+ messagebox.setInformativeText(msg)
messagebox.setIcon(QtWidgets.QMessageBox.Icon.Warning)
messagebox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok)
@@ -3639,10 +3648,12 @@ class MainGUI(QtWidgets.QMainWindow):
msg = _("Please select geometry items \n"
"on which to perform union.")
- messagebox = QtWidgets.QMessageBox()
- messagebox.setText(msg)
- messagebox.setWindowTitle(_("Warning"))
- messagebox.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/warning.png'))
+ messagebox = FCMessageBox()
+ title = _("Warning")
+ messagebox.setWindowTitle(title) # taskbar still shows it
+ messagebox.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/flatcam_icon128.png'))
+ messagebox.setText('%s' % title)
+ messagebox.setInformativeText(msg)
messagebox.setIcon(QtWidgets.QMessageBox.Icon.Warning)
messagebox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok)
diff --git a/appGUI/preferences/PreferencesUIManager.py b/appGUI/preferences/PreferencesUIManager.py
index 0319a55c..b46be465 100644
--- a/appGUI/preferences/PreferencesUIManager.py
+++ b/appGUI/preferences/PreferencesUIManager.py
@@ -4,6 +4,8 @@ from PyQt6.QtCore import QSettings
from defaults import FlatCAMDefaults
import logging
+from appGUI.GUIElements import FCMessageBox
+
import gettext
import appTranslation as fcTranslate
import builtins
@@ -1057,10 +1059,13 @@ class PreferencesUIManager:
ge_val = self.ui.general_pref_form.general_app_group.ge_radio.get_value()
if theme_new_val != theme or ge != ge_val:
- msgbox = QtWidgets.QMessageBox()
- msgbox.setText(_("Are you sure you want to continue?"))
- msgbox.setWindowTitle(_("Application will restart"))
- msgbox.setWindowIcon(QtGui.QIcon(self.ui.app.resource_location + '/warning.png'))
+ msgbox = FCMessageBox()
+ title = _("Application will restart")
+ txt = _("Are you sure you want to continue?")
+ msgbox.setWindowTitle(title) # taskbar still shows it
+ msgbox.setWindowIcon(QtGui.QIcon(self.ui.app.resource_location + '/flatcam_icon128.png'))
+ msgbox.setText('%s' % title)
+ msgbox.setInformativeText(txt)
msgbox.setIcon(QtWidgets.QMessageBox.Icon.Question)
bt_yes = msgbox.addButton(_('Yes'), QtWidgets.QMessageBox.ButtonRole.YesRole)
@@ -1278,12 +1283,15 @@ class PreferencesUIManager:
# Prompt user to save
if self.preferences_changed_flag is True:
- msgbox = QtWidgets.QMessageBox(parent=parent)
- msgbox.setText(_("One or more values are changed.\n"
- "Do you want to save?"))
- msgbox.setWindowTitle(_("Save Preferences"))
- msgbox.setWindowIcon(QtGui.QIcon(self.ui.app.resource_location + '/save_as.png'))
- msgbox.setIcon(QtWidgets.QMessageBox.Icon.Question)
+ msgbox = FCMessageBox(parent=parent)
+ title = _("Save Preferences")
+ txt = _("One or more values are changed.\n"
+ "Do you want to save?")
+ msgbox.setWindowTitle(title) # taskbar still shows it
+ msgbox.setWindowIcon(QtGui.QIcon(self.ui.app.resource_location + '/flatcam_icon128.png'))
+ msgbox.setText('%s' % title)
+ msgbox.setInformativeText(txt)
+ msgbox.setIconPixmap(QtGui.QPixmap(self.ui.app.resource_location + '/save_as.png'))
bt_yes = msgbox.addButton(_('Yes'), QtWidgets.QMessageBox.ButtonRole.YesRole)
msgbox.addButton(_('No'), QtWidgets.QMessageBox.ButtonRole.NoRole)
diff --git a/appTranslation.py b/appTranslation.py
index 73d49184..fdc22e1a 100644
--- a/appTranslation.py
+++ b/appTranslation.py
@@ -11,6 +11,7 @@ import logging
from pathlib import Path
from PyQt6 import QtWidgets, QtGui
+from PyQt6.QtCore import Qt
from PyQt6.QtCore import QSettings
import gettext
@@ -107,15 +108,14 @@ def on_language_apply_click(app, restart=False):
return
if restart:
- msgbox = QtWidgets.QMessageBox()
-
- msgbox.setText(_("The application will restart."))
- msgbox.setInformativeText('%s %s?' %
- (_("Are you sure do you want to change the current language to"),
- name.capitalize()))
- msgbox.setWindowTitle('%s ...' % _("Apply Language"))
- msgbox.setWindowIcon(QtGui.QIcon(resource_loc + '/language32.png'))
- msgbox.setIcon(QtWidgets.QMessageBox.Icon.Question)
+ msgbox = FCMessageBox()
+ title = _("The application will restart.")
+ txt = '%s %s?' % (_("Are you sure do you want to change the current language to"), name.capitalize())
+ msgbox.setWindowTitle('%s ...' % _("Apply Language")) # taskbar still shows it
+ msgbox.setWindowIcon(QtGui.QIcon(resource_loc + '/flatcam_icon128.png'))
+ msgbox.setText('%s' % title)
+ msgbox.setInformativeText(txt)
+ msgbox.setIconPixmap(QtGui.QPixmap(resource_loc + '/language32.png'))
bt_yes = msgbox.addButton(_("Yes"), QtWidgets.QMessageBox.ButtonRole.YesRole)
bt_no = msgbox.addButton(_("No"), QtWidgets.QMessageBox.ButtonRole.NoRole)
@@ -212,13 +212,16 @@ def restart_program(app, ask=None):
log.error("FlatCAMTranslation.restart_program() --> %s" % str(err))
if app.should_we_save and app.collection.get_list() or ask is True:
- msgbox = QtWidgets.QMessageBox()
- msgbox.setText(_("There are files/objects modified in FlatCAM. "
- "\n"
- "Do you want to Save the project?"))
- msgbox.setWindowTitle(_("Save changes"))
- msgbox.setWindowIcon(QtGui.QIcon(resource_loc + '/save_as.png'))
- msgbox.setIcon(QtWidgets.QMessageBox.Icon.Question)
+ msgbox = FCMessageBox()
+ title = _("Save changes")
+ txt = _("There are files/objects modified in FlatCAM. "
+ "\n"
+ "Do you want to Save the project?")
+ msgbox.setWindowTitle(title) # taskbar still shows it
+ msgbox.setWindowIcon(QtGui.QIcon(resource_loc + '/flatcam_icon128.png'))
+ msgbox.setText('%s' % title)
+ msgbox.setInformativeText(txt)
+ msgbox.setIconPixmap(QtGui.QPixmap(resource_loc + '/save_as.png'))
bt_yes = msgbox.addButton(_('Yes'), QtWidgets.QMessageBox.ButtonRole.YesRole)
msgbox.addButton(_('No'), QtWidgets.QMessageBox.ButtonRole.NoRole)
@@ -237,15 +240,46 @@ def restart_program(app, ask=None):
os.execl(python, python, *sys.argv)
except Exception as err:
# app_run_as_admin = isAdmin()
- msgbox = QtWidgets.QMessageBox()
-
- msgbox.setText(_("The language will be applied at the next application start."))
- msgbox.setInformativeText(_("The user does not have admin rights or UAC issues."))
- msgbox.setDetailedText(str(err))
- msgbox.setWindowTitle('%s ...' % _("Quit"))
+ msgbox = FCMessageBox()
+ title = _("The language will be applied at the next application start.")
+ txt = _("The user does not have admin rights or UAC issues.")
+ msgbox.setWindowTitle('%s ...' % _("Quit")) # taskbar still shows it
+ msgbox.setWindowIcon(QtGui.QIcon(resource_loc + '/flatcam_icon128.png'))
+ msgbox.setText('%s' % title)
+ msgbox.setInformativeText(txt)
msgbox.setIcon(QtWidgets.QMessageBox.Icon.Critical)
bt_yes = msgbox.addButton(_("Quit"), QtWidgets.QMessageBox.ButtonRole.YesRole)
msgbox.setDefaultButton(bt_yes)
msgbox.exec()
+
+
+# TODO Due of some circular imports issues which I currently can't fix I readd this class here
+# (mainly is located in appGUI.GUIElements) - required for a consistent look
+class FCMessageBox(QtWidgets.QMessageBox):
+ """
+ Frameless QMessageBox
+ """
+
+ def __init__(self, *args, **kwargs):
+ super(FCMessageBox, self).__init__(*args, **kwargs)
+ self.offset = None
+ self.moving = None
+ self.setWindowFlags(self.windowFlags() | Qt.WindowType.FramelessWindowHint | Qt.WindowType.WindowSystemMenuHint)
+
+ self.setStyleSheet(
+ "QDialog { "
+ "border: 1px solid palette(shadow); "
+ "background-color: palette(base); "
+ "}"
+ )
+
+ def mousePressEvent(self, event):
+ if event.button() == Qt.MouseButton.LeftButton:
+ self.moving = True
+ self.offset = event.position()
+
+ def mouseMoveEvent(self, event):
+ if self.moving:
+ self.move(event.globalPosition().toPoint() - self.offset.toPoint())
diff --git a/app_Main.py b/app_Main.py
index 70912e9c..e7a7d104 100644
--- a/app_Main.py
+++ b/app_Main.py
@@ -188,7 +188,7 @@ class App(QtCore.QObject):
excellon_spec_url = "https://www.ucamco.com/files/downloads/file/305/the_xnc_file_format_specification.pdf"
bug_report_url = "https://bitbucket.org/jpcgt/flatcam/issues?status=new&status=open"
donate_url = "https://www.paypal.com/cgi-bin/webscr?cmd=_" \
- "donations&business=WLTJJ3Q77D98L¤cy_code=USD&source=url"
+ "donations&business=WLTJJ3Q77D98L¤cy_code=USD&source=url"
# this variable will hold the project status
# if True it will mean that the project was modified and not saved
should_we_save = False
@@ -2720,6 +2720,8 @@ class App(QtCore.QObject):
msgbox = FCMessageBox()
title = _("Exit Editor")
txt = _("Do you want to save the edited object?")
+ msgbox.setWindowTitle(title) # taskbar still shows it
+ msgbox.setWindowIcon(QtGui.QIcon(self.resource_location + '/flatcam_icon128.png'))
msgbox.setText('%s' % title)
msgbox.setInformativeText(txt)
msgbox.setIconPixmap(QtGui.QPixmap(self.resource_location + '/save_as.png'))
@@ -3955,6 +3957,8 @@ class App(QtCore.QObject):
"to his own website\n\n"
"If you can't get any informations about the application\n"
"use the YouTube channel link from the Help menu.")
+ msgbox.setWindowTitle(title) # taskbar still shows it
+ msgbox.setWindowIcon(QtGui.QIcon(self.resource_location + '/flatcam_icon128.png'))
msgbox.setText('%s\n\n' % title)
msgbox.setInformativeText(txt)
@@ -3984,6 +3988,8 @@ class App(QtCore.QObject):
txt = _("There are files/objects modified in FlatCAM. "
"\n"
"Do you want to Save the project?")
+ msgbox.setWindowTitle(title) # taskbar still shows it
+ msgbox.setWindowIcon(QtGui.QIcon(self.resource_location + '/flatcam_icon128.png'))
msgbox.setText('%s' % title)
msgbox.setInformativeText(txt)
msgbox.setIconPixmap(QtGui.QPixmap(self.resource_location + '/save_as.png'))
@@ -4930,6 +4936,8 @@ class App(QtCore.QObject):
txt = _("Changing the units of the project\n"
"will scale all objects.\n\n"
"Do you want to continue?")
+ msgbox.setWindowTitle(title) # taskbar still shows it
+ msgbox.setWindowIcon(QtGui.QIcon(self.resource_location + '/flatcam_icon128.png'))
msgbox.setText('%s' % title)
msgbox.setInformativeText(txt)
msgbox.setIconPixmap(QtGui.QPixmap(self.resource_location + '/toggle_units32.png'))
@@ -5096,6 +5104,8 @@ class App(QtCore.QObject):
title = _("Tool adding ...")
txt = _("Adding Tool works only when Advanced is checked.\n"
"Go to Preferences -> General - Show Advanced Options.")
+ msgbox.setWindowTitle(title) # taskbar still shows it
+ msgbox.setWindowIcon(QtGui.QIcon(self.resource_location + '/flatcam_icon128.png'))
msgbox.setText('%s' % title)
msgbox.setInformativeText(txt)
msgbox.setIconPixmap(QtGui.QPixmap(self.resource_location + '/warning.png'))
@@ -5185,6 +5195,8 @@ class App(QtCore.QObject):
title = _("Delete objects")
txt = _("Are you sure you want to permanently delete\n"
"the selected objects?")
+ msgbox.setWindowTitle(title) # taskbar still shows it
+ msgbox.setWindowIcon(QtGui.QIcon(self.resource_location + '/flatcam_icon128.png'))
msgbox.setText('%s' % title)
msgbox.setInformativeText(txt)
msgbox.setIconPixmap(QtGui.QPixmap(self.resource_location + '/deleteshape32.png'))
@@ -6742,6 +6754,8 @@ class App(QtCore.QObject):
title = _("Save Tools Database")
txt = _("One or more Tools are edited.\n"
"Do you want to save?")
+ msgbox.setWindowTitle(title) # taskbar still shows it
+ msgbox.setWindowIcon(QtGui.QIcon(self.resource_location + '/flatcam_icon128.png'))
msgbox.setText('%s' % title)
msgbox.setInformativeText(txt)
msgbox.setIconPixmap(QtGui.QPixmap(self.resource_location + '/save_as.png'))
@@ -9529,8 +9543,10 @@ class MenuFileHandlers(QtCore.QObject):
and not isinstance(obj, GerberObject)
and not isinstance(obj, CNCJobObject)
and not isinstance(obj, ExcellonObject)):
- msg = '[ERROR_NOTCL] %s' % _("Only Geometry, Gerber and CNCJob objects can be used.")
+ msg = _("Only Geometry, Gerber and CNCJob objects can be used.")
msgbox = FCMessageBox()
+ msgbox.setWindowTitle(msg) # taskbar still shows it
+ msgbox.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/flatcam_icon128.png'))
msgbox.setInformativeText(msg)
msgbox.setIconPixmap(QtGui.QPixmap(self.app.resource_location + '/waning.png'))
@@ -9880,6 +9896,8 @@ class MenuFileHandlers(QtCore.QObject):
if obj.kind != 'geometry':
msg = _("Only Geometry objects can be used.")
msgbox = FCMessageBox()
+ msgbox.setWindowTitle(msg) # taskbar still shows it
+ msgbox.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/flatcam_icon128.png'))
msgbox.setInformativeText(msg)
msgbox.setIconPixmap(QtGui.QPixmap(self.app.resource_location + '/waning.png'))
@@ -9990,6 +10008,8 @@ class MenuFileHandlers(QtCore.QObject):
txt = _("There are files/objects opened in FlatCAM.\n"
"Creating a New project will delete them.\n"
"Do you want to Save the project?")
+ msgbox.setWindowTitle(title) # taskbar still shows it
+ msgbox.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/flatcam_icon128.png'))
msgbox.setText('%s' % title)
msgbox.setInformativeText(txt)
msgbox.setIconPixmap(QtGui.QPixmap(self.app.resource_location + '/save_as.png'))
@@ -10113,6 +10133,8 @@ class MenuFileHandlers(QtCore.QObject):
msgbox = FCMessageBox()
title = _("Save preferences")
txt = _("Do you want to save the current settings/preferences?")
+ msgbox.setWindowTitle(title) # taskbar still shows it
+ msgbox.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/flatcam_icon128.png'))
msgbox.setText('%s' % title)
msgbox.setInformativeText(txt)
msgbox.setIconPixmap(QtGui.QPixmap(self.app.resource_location + '/save_as.png'))