diff --git a/novelwriter/gui/theme.py b/novelwriter/gui/theme.py index 66ba4b93..ee01020c 100644 --- a/novelwriter/gui/theme.py +++ b/novelwriter/gui/theme.py @@ -613,12 +613,13 @@ class GuiIcons: return QPixmap() pixmap = QPixmap(str(imgPath)) + tMode = Qt.TransformationMode.SmoothTransformation if w is not None and h is not None: - return pixmap.scaled(w, h, Qt.IgnoreAspectRatio, Qt.SmoothTransformation) + return pixmap.scaled(w, h, Qt.AspectRatioMode.IgnoreAspectRatio, tMode) elif w is None and h is not None: - return pixmap.scaledToHeight(h, Qt.SmoothTransformation) + return pixmap.scaledToHeight(h, tMode) elif w is not None and h is None: - return pixmap.scaledToWidth(w, Qt.SmoothTransformation) + return pixmap.scaledToWidth(w, tMode) return pixmap @@ -637,8 +638,8 @@ class GuiIcons: pOne = self.getPixmap(self.TOGGLE_ICON_KEYS[name][0], size) pTwo = self.getPixmap(self.TOGGLE_ICON_KEYS[name][1], size) icon = QIcon() - icon.addPixmap(pOne, QIcon.Normal, QIcon.On) - icon.addPixmap(pTwo, QIcon.Normal, QIcon.Off) + icon.addPixmap(pOne, QIcon.Mode.Normal, QIcon.State.On) + icon.addPixmap(pTwo, QIcon.Mode.Normal, QIcon.State.Off) return icon return QIcon() @@ -646,7 +647,7 @@ class GuiIcons: """Return an icon from the icon buffer as a QPixmap. If it doesn't exist, return an empty QPixmap. """ - return self.getIcon(name).pixmap(size[0], size[1], QIcon.Normal) + return self.getIcon(name).pixmap(size[0], size[1], QIcon.Mode.Normal) def getItemIcon(self, tType: nwItemType, tClass: nwItemClass, tLayout: nwItemLayout, hLevel: str = "H0") -> QIcon: diff --git a/novelwriter/tools/welcome.py b/novelwriter/tools/welcome.py index d0d7a78d..8d35c8fc 100644 --- a/novelwriter/tools/welcome.py +++ b/novelwriter/tools/welcome.py @@ -62,6 +62,7 @@ class GuiWelcome(QDialog): super().__init__(parent=mainGui) logger.debug("Create: GuiWelcome") + self.setObjectName("GuiWelcome") self.setWindowTitle(self.tr("Welcome")) self.setMinimumWidth(CONFIG.pxInt(700)) diff --git a/tests/reference/baseConfig_novelwriter.conf b/tests/reference/baseConfig_novelwriter.conf index 5007dd54..6f064701 100644 --- a/tests/reference/baseConfig_novelwriter.conf +++ b/tests/reference/baseConfig_novelwriter.conf @@ -1,5 +1,5 @@ [Meta] -timestamp = 2023-08-08 19:01:25 +timestamp = 2023-12-29 14:11:20 [Main] theme = default @@ -14,8 +14,8 @@ lastpath = [Sizes] mainwindow = 1200, 650 +welcome = 800, 500 preferences = 700, 615 -projloadcols = 280, 60, 160 mainpane = 300, 800 viewpane = 500, 150 outlinepane = 500, 150 diff --git a/tests/reference/guiPreferences_novelwriter.conf b/tests/reference/guiPreferences_novelwriter.conf index 9275b82e..b291bf4a 100644 --- a/tests/reference/guiPreferences_novelwriter.conf +++ b/tests/reference/guiPreferences_novelwriter.conf @@ -1,5 +1,5 @@ [Meta] -timestamp = 2023-08-02 14:53:40 +timestamp = 2023-12-29 14:09:13 [Main] theme = default @@ -14,8 +14,8 @@ lastpath = [Sizes] mainwindow = 1200, 650 -preferences = 765, 614 -projloadcols = 280, 60, 160 +welcome = 800, 500 +preferences = 713, 614 mainpane = 300, 800 viewpane = 500, 150 outlinepane = 500, 150 diff --git a/tests/test_gui/test_gui_guimain.py b/tests/test_gui/test_gui_guimain.py index 657ce7e8..37492050 100644 --- a/tests/test_gui/test_gui_guimain.py +++ b/tests/test_gui/test_gui_guimain.py @@ -31,7 +31,7 @@ from tools import ( from PyQt5.QtGui import QColor, QPalette from PyQt5.QtCore import Qt -from PyQt5.QtWidgets import QDialog, QMenu, QInputDialog +from PyQt5.QtWidgets import QMenu, QInputDialog from novelwriter import CONFIG, SHARED from novelwriter.enum import nwItemType, nwView, nwWidget @@ -39,8 +39,8 @@ from novelwriter.gui.outline import GuiOutlineView from novelwriter.gui.projtree import GuiProjectTree from novelwriter.gui.doceditor import GuiDocEditor from novelwriter.gui.noveltree import GuiNovelView +from novelwriter.tools.welcome import GuiWelcome from novelwriter.dialogs.about import GuiAbout -from novelwriter.dialogs.projload import GuiProjectLoad from novelwriter.dialogs.editlabel import GuiEditLabel KEY_DELAY = 1 @@ -68,8 +68,8 @@ def testGuiMain_ProjectBlocker(nwGUI): @pytest.mark.gui def testGuiMain_Launch(qtbot, monkeypatch, nwGUI, projPath): """Test the handling of launch tasks.""" - monkeypatch.setattr(GuiProjectLoad, "exec_", lambda *a: None) - monkeypatch.setattr(GuiProjectLoad, "result", lambda *a: QDialog.Accepted) + monkeypatch.setattr(GuiWelcome, "exec_", lambda *a: None) + # monkeypatch.setattr(GuiProjectLoad, "result", lambda *a: QDialog.Accepted) CONFIG.lastNotes = "0x0" buildTestProject(nwGUI, projPath) @@ -101,11 +101,10 @@ def testGuiMain_Launch(qtbot, monkeypatch, nwGUI, projPath): # Check that project open dialog launches nwGUI.postLaunchTasks(None) - qtbot.waitUntil(lambda: getGuiItem("GuiProjectLoad") is not None, timeout=1000) - nwLoad = getGuiItem("GuiProjectLoad") - assert isinstance(nwLoad, GuiProjectLoad) - nwLoad.show() - nwLoad.reject() + qtbot.waitUntil(lambda: getGuiItem("GuiWelcome") is not None, timeout=1000) + assert isinstance(welcome := getGuiItem("GuiWelcome"), GuiWelcome) + welcome.show() + welcome.close() # qtbot.stop() diff --git a/tests/test_gui/test_gui_theme.py b/tests/test_gui/test_gui_theme.py index e660c02c..0e0bd14c 100644 --- a/tests/test_gui/test_gui_theme.py +++ b/tests/test_gui/test_gui_theme.py @@ -263,7 +263,7 @@ def testGuiTheme_Syntax(qtbot, monkeypatch, nwGUI): @pytest.mark.gui -def testGuiTheme_Icons(qtbot, caplog, monkeypatch, nwGUI, tstPaths): +def testGuiTheme_IconThemes(qtbot, caplog, monkeypatch, tstPaths): """Test the icon cache class.""" iconCache = SHARED.theme.iconCache @@ -305,38 +305,16 @@ def testGuiTheme_Icons(qtbot, caplog, monkeypatch, nwGUI, tstPaths): assert iconCache.loadTheme("typicons_dark") is True assert "add" in iconCache._themeMap - # Load Decorations - # ================ + # qtbot.stop() - # Invalid name should return empty pixmap - qPix = iconCache.loadDecoration("stuff") - assert qPix.isNull() is True +# END Test testGuiTheme_IconThemes - # Load an image - qPix = iconCache.loadDecoration("wiz-back") - assert qPix.isNull() is False - # Fail finding the file - with monkeypatch.context() as mp: - mp.setattr("pathlib.Path.is_file", lambda *a: False) - qPix = iconCache.loadDecoration("wiz-back") - assert qPix.isNull() is True - - # Test image sizes - qPix = iconCache.loadDecoration("wiz-back", w=100, h=None) - assert qPix.isNull() is False - assert qPix.width() == 100 - assert qPix.height() > 100 - - qPix = iconCache.loadDecoration("wiz-back", w=None, h=100) - assert qPix.isNull() is False - assert qPix.width() < 100 - assert qPix.height() == 100 - - qPix = iconCache.loadDecoration("wiz-back", w=100, h=100) - assert qPix.isNull() is False - assert qPix.width() == 100 - assert qPix.height() == 100 +@pytest.mark.gui +def testGuiTheme_LoadIcons(qtbot): + """Test the icon cache class.""" + iconCache = SHARED.theme.iconCache + assert iconCache.loadTheme("typicons_dark") is True # Load Icons # ========== @@ -368,6 +346,19 @@ def testGuiTheme_Icons(qtbot, caplog, monkeypatch, nwGUI, tstPaths): assert isinstance(qIcon, QIcon) assert qIcon.isNull() is False + # Toggle icon + qIcon = iconCache.getToggleIcon("bullet", (24, 24)) + assert isinstance(qIcon, QIcon) + assert qIcon.isNull() is False + pOn = qIcon.pixmap(24, 24, QIcon.Mode.Normal, QIcon.State.On) + pOff = qIcon.pixmap(24, 24, QIcon.Mode.Normal, QIcon.State.Off) + assert pOn != pOff + + # Unknown toggle icon + qIcon = iconCache.getToggleIcon("stuff", (24, 24)) + assert isinstance(qIcon, QIcon) + assert qIcon.isNull() is True + # Load Item Icons # =============== @@ -421,6 +412,50 @@ def testGuiTheme_Icons(qtbot, caplog, monkeypatch, nwGUI, tstPaths): nwItemType.NO_TYPE, nwItemClass.NOVEL, nwItemLayout.DOCUMENT, hLevel="H0" ).isNull() is True + # qtbot.stop() + +# END Test testGuiTheme_LoadIcons + + +@pytest.mark.gui +def testGuiTheme_LoadDecorations(qtbot, monkeypatch): + """Test the icon cache class.""" + iconCache = SHARED.theme.iconCache + assert iconCache.loadTheme("typicons_dark") is True + + # Load Decorations + # ================ + + # Invalid name should return empty pixmap + qPix = iconCache.loadDecoration("stuff") + assert qPix.isNull() is True + + # Load an image + qPix = iconCache.loadDecoration("welcome") + assert qPix.isNull() is False + + # Fail finding the file + with monkeypatch.context() as mp: + mp.setattr("pathlib.Path.is_file", lambda *a: False) + qPix = iconCache.loadDecoration("welcome") + assert qPix.isNull() is True + + # Test image sizes + qPix = iconCache.loadDecoration("welcome", w=100, h=None) + assert qPix.isNull() is False + assert qPix.width() == 100 + assert qPix.height() > 50 + + qPix = iconCache.loadDecoration("welcome", w=None, h=100) + assert qPix.isNull() is False + assert qPix.width() > 100 + assert qPix.height() == 100 + + qPix = iconCache.loadDecoration("welcome", w=100, h=100) + assert qPix.isNull() is False + assert qPix.width() == 100 + assert qPix.height() == 100 + # Header Decorations # ================== @@ -432,6 +467,18 @@ def testGuiTheme_Icons(qtbot, caplog, monkeypatch, nwGUI, tstPaths): assert iconCache.getHeaderDecoration(4) == iconCache._headerDec[4] assert iconCache.getHeaderDecoration(5) == iconCache._headerDec[4] + # Narrow Header Decorations + # ========================= + + assert iconCache.getHeaderDecorationNarrow(-1) == iconCache._headerDecNarrow[0] + assert iconCache.getHeaderDecorationNarrow(0) == iconCache._headerDecNarrow[0] + assert iconCache.getHeaderDecorationNarrow(1) == iconCache._headerDecNarrow[1] + assert iconCache.getHeaderDecorationNarrow(2) == iconCache._headerDecNarrow[2] + assert iconCache.getHeaderDecorationNarrow(3) == iconCache._headerDecNarrow[3] + assert iconCache.getHeaderDecorationNarrow(4) == iconCache._headerDecNarrow[4] + assert iconCache.getHeaderDecorationNarrow(5) == iconCache._headerDecNarrow[5] + assert iconCache.getHeaderDecorationNarrow(6) == iconCache._headerDecNarrow[5] + # qtbot.stop() -# END Test testGuiTheme_Icons +# END Test testGuiTheme_LoadDecorations