diff --git a/novelwriter/config.py b/novelwriter/config.py index 91945fe3..af21e7dd 100644 --- a/novelwriter/config.py +++ b/novelwriter/config.py @@ -158,10 +158,12 @@ class Config: self.autoScrollPos = 30 # Start point for typewriter-like scrolling self.scrollPastEnd = True # Scroll past end of document, and centre cursor - self.dialogueStyle = 2 # Quote type to use for dialogue + self.dialogStyle = 2 # Quote type to use for dialogue self.allowOpenDial = True # Allow open-ended dialogue quotes self.narratorBreak = "" # Symbol to use for narrator break - self.dialogueLine = "" # Symbol to use for dialogue line + self.dialogLine = "" # Symbol to use for dialogue line + self.altDialogOpen = "" # Alternative dialog symbol, open + self.altDialogClose = "" # Alternative dialog symbol, close self.highlightEmph = True # Add colour to text emphasis self.stopWhenIdle = True # Stop the status bar clock when the user is idle @@ -619,10 +621,12 @@ class Config: self.showMultiSpaces = conf.rdBool(sec, "showmultispaces", self.showMultiSpaces) self.incNotesWCount = conf.rdBool(sec, "incnoteswcount", self.incNotesWCount) self.showFullPath = conf.rdBool(sec, "showfullpath", self.showFullPath) - self.dialogueStyle = conf.rdInt(sec, "dialoguestyle", self.dialogueStyle) + self.dialogStyle = conf.rdInt(sec, "dialogstyle", self.dialogStyle) self.allowOpenDial = conf.rdBool(sec, "allowopendial", self.allowOpenDial) self.narratorBreak = conf.rdStr(sec, "narratorbreak", self.narratorBreak) - self.dialogueLine = conf.rdStr(sec, "dialogueline", self.dialogueLine) + self.altDialogOpen = conf.rdStr(sec, "altdialogopen", self.altDialogOpen) + self.altDialogClose = conf.rdStr(sec, "altdialogclose", self.altDialogClose) + self.dialogLine = conf.rdStr(sec, "dialogline", self.dialogLine) self.highlightEmph = conf.rdBool(sec, "highlightemph", self.highlightEmph) self.stopWhenIdle = conf.rdBool(sec, "stopwhenidle", self.stopWhenIdle) self.userIdleTime = conf.rdInt(sec, "useridletime", self.userIdleTime) @@ -728,10 +732,12 @@ class Config: "showmultispaces": str(self.showMultiSpaces), "incnoteswcount": str(self.incNotesWCount), "showfullpath": str(self.showFullPath), - "dialoguestyle": str(self.dialogueStyle), + "dialogstyle": str(self.dialogStyle), "allowopendial": str(self.allowOpenDial), "narratorbreak": str(self.narratorBreak), - "dialogueline": str(self.dialogueLine), + "altdialogopen": str(self.altDialogOpen), + "altdialogclose": str(self.altDialogClose), + "dialogline": str(self.dialogLine), "highlightemph": str(self.highlightEmph), "stopwhenidle": str(self.stopWhenIdle), "useridletime": str(self.userIdleTime), diff --git a/novelwriter/dialogs/preferences.py b/novelwriter/dialogs/preferences.py index 6f90a26d..c28ed169 100644 --- a/novelwriter/dialogs/preferences.py +++ b/novelwriter/dialogs/preferences.py @@ -539,14 +539,14 @@ class GuiPreferences(QDialog): self.sidebar.addButton(title, section) self.mainForm.addGroupLabel(title, section) - self.dialogueStyle = NComboBox(self) - self.dialogueStyle.addItem(self.tr("None"), 0) - self.dialogueStyle.addItem(self.tr("Single Quotes"), 1) - self.dialogueStyle.addItem(self.tr("Double Quotes"), 2) - self.dialogueStyle.addItem(self.tr("Both"), 3) - self.dialogueStyle.setCurrentData(CONFIG.dialogueStyle, 2) + self.dialogStyle = NComboBox(self) + self.dialogStyle.addItem(self.tr("None"), 0) + self.dialogStyle.addItem(self.tr("Single Quotes"), 1) + self.dialogStyle.addItem(self.tr("Double Quotes"), 2) + self.dialogStyle.addItem(self.tr("Both"), 3) + self.dialogStyle.setCurrentData(CONFIG.dialogStyle, 2) self.mainForm.addRow( - self.tr("Highlight dialogue"), self.dialogueStyle, + self.tr("Highlight dialogue"), self.dialogStyle, self.tr("Applies to the selected quote styles.") ) @@ -567,16 +567,41 @@ class GuiPreferences(QDialog): self.tr("Symbol to indicate injected narrator break.") ) - self.dialogueLine = QLineEdit(self) - self.dialogueLine.setMaxLength(1) - self.dialogueLine.setFixedWidth(boxFixed) - self.dialogueLine.setAlignment(QtAlignCenter) - self.dialogueLine.setText(CONFIG.dialogueLine) + self.dialogLine = QLineEdit(self) + self.dialogLine.setMaxLength(1) + self.dialogLine.setFixedWidth(boxFixed) + self.dialogLine.setAlignment(QtAlignCenter) + self.dialogLine.setText(CONFIG.dialogLine) self.mainForm.addRow( - self.tr("Dialogue line symbol"), self.dialogueLine, + self.tr("Dialogue line symbol"), self.dialogLine, self.tr("Lines starting with this symbol are dialogue.") ) + self.altDialogOpen = QLineEdit(self) + self.altDialogOpen.setMaxLength(4) + self.altDialogOpen.setFixedWidth(boxFixed) + self.altDialogOpen.setAlignment(QtAlignCenter) + self.altDialogOpen.setText(CONFIG.altDialogOpen) + + self.altDialogClose = QLineEdit(self) + self.altDialogClose.setMaxLength(4) + self.altDialogClose.setFixedWidth(boxFixed) + self.altDialogClose.setAlignment(QtAlignCenter) + self.altDialogClose.setText(CONFIG.altDialogClose) + + self.altDialogBox = QHBoxLayout() + self.altDialogBox.addWidget(self.altDialogOpen) + self.altDialogBox.addWidget(self.altDialogClose) + self.altDialogBox.setContentsMargins(0, 0, 0, 0) + + self.altDialog = QWidget(self) + self.altDialog.setLayout(self.altDialogBox) + + self.mainForm.addRow( + self.tr("Alternative dialog symbols"), self.altDialog, + self.tr("Custom highlighting of dialog text.") + ) + self.highlightEmph = NSwitch(self) self.highlightEmph.setChecked(CONFIG.highlightEmph) self.mainForm.addRow( @@ -936,24 +961,30 @@ class GuiPreferences(QDialog): CONFIG.scrollPastEnd = self.scrollPastEnd.isChecked() # Text Highlighting - dialogueStyle = self.dialogueStyle.currentData() + dialogueStyle = self.dialogStyle.currentData() allowOpenDial = self.allowOpenDial.isChecked() narratorBreak = self.narratorBreak.text() - dialogueLine = self.dialogueLine.text() + dialogueLine = self.dialogLine.text() + altDialogOpen = self.altDialogOpen.text() + altDialogClose = self.altDialogClose.text() highlightEmph = self.highlightEmph.isChecked() showMultiSpaces = self.showMultiSpaces.isChecked() - updateSyntax |= CONFIG.dialogueStyle != dialogueStyle + updateSyntax |= CONFIG.dialogStyle != dialogueStyle updateSyntax |= CONFIG.allowOpenDial != allowOpenDial updateSyntax |= CONFIG.narratorBreak != narratorBreak - updateSyntax |= CONFIG.dialogueLine != dialogueLine + updateSyntax |= CONFIG.dialogLine != dialogueLine + updateSyntax |= CONFIG.altDialogOpen != altDialogOpen + updateSyntax |= CONFIG.altDialogClose != altDialogClose updateSyntax |= CONFIG.highlightEmph != highlightEmph updateSyntax |= CONFIG.showMultiSpaces != showMultiSpaces - CONFIG.dialogueStyle = dialogueStyle + CONFIG.dialogStyle = dialogueStyle CONFIG.allowOpenDial = allowOpenDial CONFIG.narratorBreak = narratorBreak - CONFIG.dialogueLine = dialogueLine + CONFIG.dialogLine = dialogueLine + CONFIG.altDialogOpen = altDialogOpen + CONFIG.altDialogClose = altDialogClose CONFIG.highlightEmph = highlightEmph CONFIG.showMultiSpaces = showMultiSpaces diff --git a/novelwriter/gui/dochighlight.py b/novelwriter/gui/dochighlight.py index 0039f6bb..0554beb3 100644 --- a/novelwriter/gui/dochighlight.py +++ b/novelwriter/gui/dochighlight.py @@ -150,13 +150,13 @@ class GuiDocHighlighter(QSyntaxHighlighter): self._cmnRules.append((rxRule, hlRule)) # Dialogue - if CONFIG.dialogueStyle > 0: + if CONFIG.dialogStyle > 0: symO = "" symC = "" - if CONFIG.dialogueStyle in (1, 3): + if CONFIG.dialogStyle in (1, 3): symO += CONFIG.fmtSQuoteOpen symC += CONFIG.fmtSQuoteClose - if CONFIG.dialogueStyle in (2, 3): + if CONFIG.dialogStyle in (2, 3): symO += CONFIG.fmtDQuoteOpen symC += CONFIG.fmtDQuoteClose @@ -168,7 +168,7 @@ class GuiDocHighlighter(QSyntaxHighlighter): } self._txtRules.append((rxRule, hlRule)) - if sym := CONFIG.dialogueLine: + if sym := CONFIG.dialogLine: rxRule = QRegularExpression(f"^{sym}.*?$") rxRule.setPatternOptions(QRegExUnicode) hlRule = { @@ -184,6 +184,16 @@ class GuiDocHighlighter(QSyntaxHighlighter): } self._txtRules.append((rxRule, hlRule)) + if CONFIG.altDialogOpen and CONFIG.altDialogClose: + symO = QRegularExpression.escape(CONFIG.altDialogOpen) + symC = QRegularExpression.escape(CONFIG.altDialogClose) + rxRule = QRegularExpression(f"\\B{symO}.*?{symC}\\B") + rxRule.setPatternOptions(QRegExUnicode) + hlRule = { + 0: self._hStyles["altdialog"], + } + self._txtRules.append((rxRule, hlRule)) + # Markdown Italic rxRule = QRegularExpression(nwRegEx.FMT_EI) rxRule.setPatternOptions(QRegExUnicode)