diff --git a/novelwriter/dialogs/preferences.py b/novelwriter/dialogs/preferences.py index 2904476e..f433529e 100644 --- a/novelwriter/dialogs/preferences.py +++ b/novelwriter/dialogs/preferences.py @@ -29,8 +29,8 @@ import logging from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot from PyQt5.QtGui import QCloseEvent, QKeyEvent, QKeySequence from PyQt5.QtWidgets import ( - QAbstractButton, QCompleter, QDialogButtonBox, QFileDialog, QHBoxLayout, - QLineEdit, QPushButton, QVBoxLayout, QWidget + QCompleter, QDialogButtonBox, QFileDialog, QHBoxLayout, QLineEdit, + QPushButton, QVBoxLayout, QWidget ) from novelwriter import CONFIG, SHARED @@ -43,10 +43,7 @@ from novelwriter.extensions.modified import ( ) from novelwriter.extensions.pagedsidebar import NPagedSideBar from novelwriter.extensions.switch import NSwitch -from novelwriter.types import ( - QtAlignCenter, QtDialogApply, QtDialogClose, QtDialogSave, QtRoleAccept, - QtRoleApply, QtRoleReject -) +from novelwriter.types import QtAlignCenter, QtDialogCancel, QtDialogSave logger = logging.getLogger(__name__) @@ -89,8 +86,9 @@ class GuiPreferences(NDialog): self.mainForm.setHelpTextStyle(SHARED.theme.helpText) # Buttons - self.buttonBox = QDialogButtonBox(QtDialogApply | QtDialogSave | QtDialogClose, self) - self.buttonBox.clicked.connect(self._dialogButtonClicked) + self.buttonBox = QDialogButtonBox(QtDialogSave | QtDialogCancel, self) + self.buttonBox.accepted.connect(self._doSave) + self.buttonBox.rejected.connect(self.reject) # Assemble self.searchBox = QHBoxLayout() @@ -784,19 +782,6 @@ class GuiPreferences(NDialog): # Private Slots ## - @pyqtSlot("QAbstractButton*") - def _dialogButtonClicked(self, button: QAbstractButton) -> None: - """Handle button clicks from the dialog button box.""" - role = self.buttonBox.buttonRole(button) - if role == QtRoleApply: - self._saveValues() - elif role == QtRoleAccept: - self._saveValues() - self.close() - elif role == QtRoleReject: - self.close() - return - @pyqtSlot(int) def _sidebarClicked(self, section: int) -> None: """Process a user request to switch page.""" @@ -897,7 +882,7 @@ class GuiPreferences(NDialog): CONFIG.setPreferencesWinSize(self.width(), self.height()) return - def _saveValues(self) -> None: + def _doSave(self) -> None: """Save the values set in the form.""" updateTheme = False needsRestart = False @@ -1012,4 +997,6 @@ class GuiPreferences(NDialog): CONFIG.saveConfig() self.newPreferencesReady.emit(needsRestart, refreshTree, updateTheme, updateSyntax) + self.close() + return diff --git a/novelwriter/extensions/configlayout.py b/novelwriter/extensions/configlayout.py index 53354b4b..42a2e29c 100644 --- a/novelwriter/extensions/configlayout.py +++ b/novelwriter/extensions/configlayout.py @@ -281,13 +281,28 @@ class NColourLabel(QLabel): return + def setTextColors(self, *, color: QColor | None = None, faded: QColor | None = None) -> None: + """Set or update the text colours.""" + self._color = color or self._color + self._faded = faded or self._faded + self._refeshTextColor() + return + def setColorState(self, state: bool) -> None: """Change the colour state.""" if self._state is not state: self._state = state - colour = self.palette() - colour.setColor(QPalette.ColorRole.WindowText, self._color if state else self._faded) - self.setPalette(colour) + self._refeshTextColor() + return + + def _refeshTextColor(self) -> None: + """Refresh the colour of the text on the label.""" + palette = self.palette() + palette.setColor( + QPalette.ColorRole.WindowText, + self._color if self._state else self._faded, + ) + self.setPalette(palette) return diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index 39adc29d..7722339b 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -2919,10 +2919,10 @@ class GuiDocEditHeader(QWidget): palette.setColor(QPalette.ColorRole.Window, SHARED.theme.colBack) palette.setColor(QPalette.ColorRole.WindowText, SHARED.theme.colText) palette.setColor(QPalette.ColorRole.Text, SHARED.theme.colText) - self.setPalette(palette) - self.itemTitle.setPalette(palette) - + self.itemTitle.setTextColors( + color=palette.windowText().color(), faded=SHARED.theme.fadedText + ) return def changeFocusState(self, state: bool) -> None: diff --git a/novelwriter/gui/docviewer.py b/novelwriter/gui/docviewer.py index b28411ab..f013db0b 100644 --- a/novelwriter/gui/docviewer.py +++ b/novelwriter/gui/docviewer.py @@ -741,7 +741,9 @@ class GuiDocViewHeader(QWidget): palette.setColor(QPalette.ColorRole.WindowText, SHARED.theme.colText) palette.setColor(QPalette.ColorRole.Text, SHARED.theme.colText) self.setPalette(palette) - self.itemTitle.setPalette(palette) + self.itemTitle.setTextColors( + color=palette.windowText().color(), faded=SHARED.theme.fadedText + ) return def changeFocusState(self, state: bool) -> None: diff --git a/novelwriter/gui/outline.py b/novelwriter/gui/outline.py index 3a411f35..054f0fb4 100644 --- a/novelwriter/gui/outline.py +++ b/novelwriter/gui/outline.py @@ -268,6 +268,7 @@ class GuiOutlineToolBar(QToolBar): self.aExport.setIcon(SHARED.theme.getIcon("export")) self.tbColumns.setIcon(SHARED.theme.getIcon("menu")) self.tbColumns.setStyleSheet("QToolButton::menu-indicator {image: none;}") + self.novelLabel.setTextColors(color=self.palette().windowText().color()) return def populateNovelList(self) -> None: diff --git a/novelwriter/guimain.py b/novelwriter/guimain.py index b7ccfedf..8e25e25d 100644 --- a/novelwriter/guimain.py +++ b/novelwriter/guimain.py @@ -1006,32 +1006,48 @@ class GuiMain(QMainWindow): def _switchFocus(self, paneNo: nwFocus) -> None: """Switch focus between main GUI views.""" if paneNo == nwFocus.TREE: - if self.projStack.currentWidget() is self.projView: - if self.projView.treeHasFocus(): - self._changeView(nwView.NOVEL) - self.novelView.setTreeFocus() - else: - self.projView.setTreeFocus() - elif self.projStack.currentWidget() is self.novelView: - if self.novelView.treeHasFocus(): - self._changeView(nwView.PROJECT) - self.projView.setTreeFocus() - else: - self.novelView.setTreeFocus() + # Decision Matrix + # vM | vP | fP | vN | fN | Focus + # ----|----|----|----|----|--------- + # T | T | T | F | F | Novel + # T | T | F | F | F | Project + # T | F | F | T | T | Project + # T | F | F | T | F | Novel + # T | F | F | F | F | Project + # F | T | T | F | F | Project + # F | T | F | F | F | Project + # F | F | F | T | T | Novel + # F | F | F | T | F | Novel + # F | F | F | F | F | Project + + vM = self.mainStack.currentWidget() is self.splitMain + vP = self.projStack.currentWidget() is self.projView + vN = self.projStack.currentWidget() is self.novelView + fP = self.projView.treeHasFocus() + fN = self.novelView.treeHasFocus() + + self._changeView(nwView.EDITOR) + if (vM and (vP and fP or vN and not fN)) or (not vM and vN): + self._changeView(nwView.NOVEL) + self.novelView.setTreeFocus() else: self._changeView(nwView.PROJECT) self.projView.setTreeFocus() + elif paneNo == nwFocus.DOCUMENT: self._changeView(nwView.EDITOR) - if self.docEditor.anyFocus(): + hasViewer = self.splitView.isVisible() + if hasViewer and self.docEditor.anyFocus(): self.docViewer.setFocus() - elif self.docViewer.anyFocus(): + elif hasViewer and self.docViewer.anyFocus(): self.docEditor.setFocus() else: self.docEditor.setFocus() + elif paneNo == nwFocus.OUTLINE: self._changeView(nwView.OUTLINE) self.outlineView.setTreeFocus() + return @pyqtSlot(bool, bool, bool, bool) diff --git a/tests/test_dialogs/test_dlg_preferences.py b/tests/test_dialogs/test_dlg_preferences.py index 7a27490a..1d186d83 100644 --- a/tests/test_dialogs/test_dlg_preferences.py +++ b/tests/test_dialogs/test_dlg_preferences.py @@ -30,7 +30,7 @@ from novelwriter import CONFIG, SHARED from novelwriter.constants import nwUnicode from novelwriter.dialogs.preferences import GuiPreferences from novelwriter.dialogs.quotes import GuiQuoteSelect -from novelwriter.types import QtDialogApply, QtDialogClose, QtDialogSave, QtModNone +from novelwriter.types import QtDialogCancel, QtDialogSave, QtModNone KEY_DELAY = 1 @@ -92,7 +92,8 @@ def testDlgPreferences_Actions(qtbot, monkeypatch, nwGUI): """Test the preferences dialog actions.""" monkeypatch.setattr(SHARED._spelling, "listDictionaries", lambda: [("en", "English [en]")]) prefs = GuiPreferences(nwGUI) - prefs.show() + with qtbot.waitExposed(prefs): + prefs.show() # Check Navigation vBar = prefs.mainForm.verticalScrollBar() @@ -116,12 +117,6 @@ def testDlgPreferences_Actions(qtbot, monkeypatch, nwGUI): prefs._gotoSearch() assert value.args[0] < old - # Check Apply Button - prefs.show() - with qtbot.waitSignal(prefs.newPreferencesReady) as signal: - prefs.buttonBox.button(QtDialogApply).click() - assert signal.args == [False, False, False, False] - # Check Save Button prefs.show() with qtbot.waitSignal(prefs.newPreferencesReady) as signal: @@ -130,7 +125,7 @@ def testDlgPreferences_Actions(qtbot, monkeypatch, nwGUI): # Check Close Button prefs.show() - prefs.buttonBox.button(QtDialogClose).click() + prefs.buttonBox.button(QtDialogCancel).click() assert prefs.isHidden() is True # Close Using Escape Key @@ -152,7 +147,8 @@ def testDlgPreferences_Settings(qtbot, monkeypatch, nwGUI, tstPaths): monkeypatch.setattr(CONFIG, "listLanguages", lambda *a: languages) prefs = GuiPreferences(nwGUI) - prefs.show() + with qtbot.waitExposed(prefs): + prefs.show() # Appearance prefs.guiLocale.setCurrentIndex(prefs.guiLocale.findData("en_US")) @@ -315,7 +311,7 @@ def testDlgPreferences_Settings(qtbot, monkeypatch, nwGUI, tstPaths): with monkeypatch.context() as mp: mp.setattr(QFontDatabase, "families", lambda *a: ["TestFont"]) with qtbot.waitSignal(prefs.newPreferencesReady) as signal: - prefs.buttonBox.button(QtDialogApply).click() + prefs.buttonBox.button(QtDialogSave).click() assert signal.args == [True, True, True, True] # Check Settings