From dadc7edbd9e65e44692dc79ed92c3ec8364a6686 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sun, 6 Jul 2025 18:14:33 +0200 Subject: [PATCH 1/3] Move the open ended dialogue setting in Preferences (#2454) --- novelwriter/dialogs/preferences.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/novelwriter/dialogs/preferences.py b/novelwriter/dialogs/preferences.py index 281487b3..c01275ba 100644 --- a/novelwriter/dialogs/preferences.py +++ b/novelwriter/dialogs/preferences.py @@ -600,6 +600,7 @@ class GuiPreferences(NDialog): self.sidebar.addButton(title, section) self.mainForm.addGroupLabel(title, section) + # Dialogue Quotes self.dialogStyle = NComboBox(self) self.dialogStyle.addItem(self.tr("None"), 0) self.dialogStyle.addItem(self.tr("Single Quotes"), 1) @@ -611,6 +612,15 @@ class GuiPreferences(NDialog): self.tr("Applies to the selected quote styles.") ) + # Open-Ended Dialogue + self.allowOpenDial = NSwitch(self) + self.allowOpenDial.setChecked(CONFIG.allowOpenDial) + self.mainForm.addRow( + self.tr("Allow open-ended dialogue"), self.allowOpenDial, + self.tr("Highlight dialogue line with no closing quote.") + ) + + # Alternative Dialogue self.altDialogOpen = QLineEdit(self) self.altDialogOpen.setMaxLength(4) self.altDialogOpen.setFixedWidth(boxFixed) @@ -628,13 +638,7 @@ class GuiPreferences(NDialog): self.tr("Custom highlighting of dialogue text.") ) - self.allowOpenDial = NSwitch(self) - self.allowOpenDial.setChecked(CONFIG.allowOpenDial) - self.mainForm.addRow( - self.tr("Allow open-ended dialogue"), self.allowOpenDial, - self.tr("Highlight dialogue line with no closing quote.") - ) - + # Dialogue Line self.dialogLine = QLineEdit(self) self.dialogLine.setMaxLength(4) self.dialogLine.setFixedWidth(boxFixed) @@ -645,6 +649,7 @@ class GuiPreferences(NDialog): self.tr("Lines starting with any of these symbols are dialogue.") ) + # Narrator Break self.narratorBreak = NComboBox(self) self.narratorDialog = NComboBox(self) for key, value in nwQuotes.DASHES.items(): @@ -664,6 +669,7 @@ class GuiPreferences(NDialog): self.tr("Alternates dialogue highlighting within any paragraph.") ) + # Emphasis self.highlightEmph = NSwitch(self) self.highlightEmph.setChecked(CONFIG.highlightEmph) self.mainForm.addRow( @@ -671,6 +677,7 @@ class GuiPreferences(NDialog): self.tr("Applies to the document editor only.") ) + # Additional Spaces self.showMultiSpaces = NSwitch(self) self.showMultiSpaces.setChecked(CONFIG.showMultiSpaces) self.mainForm.addRow( From ec9e478399b35fcd9f57753a30c8bee87cc76c4a Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sun, 6 Jul 2025 18:20:13 +0200 Subject: [PATCH 2/3] Improve dialogue line symbol setting box (#2453) --- novelwriter/common.py | 2 +- novelwriter/dialogs/preferences.py | 30 ++++++++++++++++++---- tests/test_dialogs/test_dlg_preferences.py | 15 ++++++----- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/novelwriter/common.py b/novelwriter/common.py index 2ad42935..9d18515f 100644 --- a/novelwriter/common.py +++ b/novelwriter/common.py @@ -301,7 +301,7 @@ def uniqueCompact(text: str) -> str: def processDialogSymbols(symbols: str) -> str: """Process dialogue line symbols.""" result = "" - for c in uniqueCompact(symbols): + for c in uniqueCompact("".join(symbols.split())): if c in nwQuotes.ALLOWED: result += c return result diff --git a/novelwriter/dialogs/preferences.py b/novelwriter/dialogs/preferences.py index c01275ba..fbeb0523 100644 --- a/novelwriter/dialogs/preferences.py +++ b/novelwriter/dialogs/preferences.py @@ -29,7 +29,7 @@ import logging from PyQt6.QtCore import Qt, pyqtSignal, pyqtSlot from PyQt6.QtGui import QAction, QCloseEvent, QKeyEvent, QKeySequence from PyQt6.QtWidgets import ( - QCompleter, QDialogButtonBox, QFileDialog, QHBoxLayout, QLineEdit, + QCompleter, QDialogButtonBox, QFileDialog, QHBoxLayout, QLineEdit, QMenu, QPushButton, QVBoxLayout, QWidget ) @@ -639,14 +639,26 @@ class GuiPreferences(NDialog): ) # Dialogue Line + self.mnLineSymbols = QMenu(self) + for symbol in nwQuotes.ALLOWED: + label = trConst(nwQuotes.SYMBOLS.get(symbol, nwQuotes.DASHES.get(symbol, "None"))) + self.mnLineSymbols.addAction( + f"[ {symbol } ] {label}", + lambda symbol=symbol: self._insertDialogLineSymbol(symbol) + ) + self.dialogLine = QLineEdit(self) - self.dialogLine.setMaxLength(4) - self.dialogLine.setFixedWidth(boxFixed) + self.dialogLine.setMinimumWidth(100) self.dialogLine.setAlignment(QtAlignCenter) - self.dialogLine.setText(CONFIG.dialogLine) + self.dialogLine.setText(" ".join(CONFIG.dialogLine)) + + self.dialogLineButton = NIconToolButton(self, iSz, "add", "green") + self.dialogLineButton.setMenu(self.mnLineSymbols) + self.mainForm.addRow( self.tr("Dialogue line symbols"), self.dialogLine, - self.tr("Lines starting with any of these symbols are dialogue.") + self.tr("Lines starting with any of these symbols are dialogue."), + button=self.dialogLineButton ) # Narrator Break @@ -913,6 +925,14 @@ class GuiPreferences(NDialog): self.askBeforeBackup.setEnabled(state) return + @pyqtSlot(str) + def _insertDialogLineSymbol(self, symbol: str) -> None: + """Insert a symbol in the dialogue line box.""" + current = self.dialogLine.text() + values = processDialogSymbols(f"{current} {symbol}") + self.dialogLine.setText(" ".join(values)) + return + @pyqtSlot(bool) def _toggleAutoReplaceMain(self, state: bool) -> None: """Toggle switches controlled by the auto replace switch.""" diff --git a/tests/test_dialogs/test_dlg_preferences.py b/tests/test_dialogs/test_dlg_preferences.py index ab5822be..05d7b7e5 100644 --- a/tests/test_dialogs/test_dlg_preferences.py +++ b/tests/test_dialogs/test_dlg_preferences.py @@ -268,14 +268,17 @@ def testDlgPreferences_Settings(qtbot, monkeypatch, nwGUI, fncPath, tstPaths): # Text Highlighting prefs.dialogStyle.setCurrentData(3, 0) prefs.allowOpenDial.setChecked(False) - prefs.dialogLine.setText("–") - prefs.narratorBreak.setCurrentData("–", "") - prefs.narratorDialog.setCurrentData("–", "") + prefs.dialogLine.setText(nwUnicode.U_EMDASH) + prefs.narratorBreak.setCurrentData(nwUnicode.U_EMDASH, "") + prefs.narratorDialog.setCurrentData(nwUnicode.U_EMDASH, "") prefs.altDialogOpen.setText("%") # Symbol also tests for #2455 prefs.altDialogClose.setText("%") # Symbol also tests for #2455 prefs.highlightEmph.setChecked(False) prefs.showMultiSpaces.setChecked(False) + prefs._insertDialogLineSymbol(nwUnicode.U_ENDASH) + assert prefs.dialogLine.text() == f"{nwUnicode.U_ENDASH} {nwUnicode.U_EMDASH}" + assert CONFIG.dialogStyle == 2 assert CONFIG.allowOpenDial is True assert CONFIG.dialogLine == "" @@ -398,9 +401,9 @@ def testDlgPreferences_Settings(qtbot, monkeypatch, nwGUI, fncPath, tstPaths): # Text Highlighting assert CONFIG.dialogStyle == 3 assert CONFIG.allowOpenDial is False - assert CONFIG.dialogLine == "–" - assert CONFIG.narratorBreak == "–" - assert CONFIG.narratorDialog == "–" + assert CONFIG.dialogLine == f"{nwUnicode.U_ENDASH}{nwUnicode.U_EMDASH}" + assert CONFIG.narratorBreak == nwUnicode.U_EMDASH + assert CONFIG.narratorDialog == nwUnicode.U_EMDASH assert CONFIG.altDialogOpen == "%" assert CONFIG.altDialogClose == "%" assert CONFIG.highlightEmph is False From a748a69de38758f962fb5312d3eb17d25185f37c Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sun, 6 Jul 2025 18:24:05 +0200 Subject: [PATCH 3/3] Remove redundant string compact implementation --- novelwriter/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/novelwriter/common.py b/novelwriter/common.py index 9d18515f..2ad42935 100644 --- a/novelwriter/common.py +++ b/novelwriter/common.py @@ -301,7 +301,7 @@ def uniqueCompact(text: str) -> str: def processDialogSymbols(symbols: str) -> str: """Process dialogue line symbols.""" result = "" - for c in uniqueCompact("".join(symbols.split())): + for c in uniqueCompact(symbols): if c in nwQuotes.ALLOWED: result += c return result