Skip to content

Commit

Permalink
Reorganise preferences and add cursor width setting (#2230)
Browse files Browse the repository at this point in the history
  • Loading branch information
vkbo authored Feb 6, 2025
2 parents 589bc7c + 5986678 commit 585f2e5
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 46 deletions.
5 changes: 4 additions & 1 deletion novelwriter/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class Config:
"mainWinSize", "welcomeWinSize", "prefsWinSize", "mainPanePos", "viewPanePos",
"outlinePanePos", "autoSaveProj", "autoSaveDoc", "emphLabels", "backupOnClose",
"askBeforeBackup", "askBeforeExit", "textFont", "textWidth", "textMargin", "tabWidth",
"focusWidth", "hideFocusFooter", "showFullPath", "autoSelect", "doJustify",
"cursorWidth", "focusWidth", "hideFocusFooter", "showFullPath", "autoSelect", "doJustify",
"showTabsNSpaces", "showLineEndings", "showMultiSpaces", "doReplace", "doReplaceSQuote",
"doReplaceDQuote", "doReplaceDash", "doReplaceDots", "autoScroll", "autoScrollPos",
"scrollPastEnd", "dialogStyle", "allowOpenDial", "dialogLine", "narratorBreak",
Expand Down Expand Up @@ -184,6 +184,7 @@ def __init__(self) -> None:
self.textWidth = 700 # Editor text width
self.textMargin = 40 # Editor/viewer text margin
self.tabWidth = 40 # Editor tabulator width
self.cursorWidth = 1 # Editor cursor width

self.focusWidth = 800 # Focus Mode text width
self.hideFocusFooter = False # Hide document footer in Focus Mode
Expand Down Expand Up @@ -626,6 +627,7 @@ def loadConfig(self) -> bool:
self.textWidth = conf.rdInt(sec, "width", self.textWidth)
self.textMargin = conf.rdInt(sec, "margin", self.textMargin)
self.tabWidth = conf.rdInt(sec, "tabwidth", self.tabWidth)
self.cursorWidth = conf.rdInt(sec, "cursorwidth", self.cursorWidth)
self.focusWidth = conf.rdInt(sec, "focuswidth", self.focusWidth)
self.hideFocusFooter = conf.rdBool(sec, "hidefocusfooter", self.hideFocusFooter)
self.doJustify = conf.rdBool(sec, "justify", self.doJustify)
Expand Down Expand Up @@ -741,6 +743,7 @@ def saveConfig(self) -> bool:
"width": str(self.textWidth),
"margin": str(self.textMargin),
"tabwidth": str(self.tabWidth),
"cursorwidth": str(self.cursorWidth),
"focuswidth": str(self.focusWidth),
"hidefocusfooter": str(self.hideFocusFooter),
"justify": str(self.doJustify),
Expand Down
2 changes: 1 addition & 1 deletion novelwriter/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ class nwLabels:
}
THEME_COLORS = {
"theme": QT_TRANSLATE_NOOP("Color", "Theme Colours"),
"default": QT_TRANSLATE_NOOP("Color", "No Colours"),
"default": QT_TRANSLATE_NOOP("Color", "Foreground Colour"),
"faded": QT_TRANSLATE_NOOP("Color", "Faded Colour"),
"red": QT_TRANSLATE_NOOP("Color", "Red"),
"orange": QT_TRANSLATE_NOOP("Color", "Orange"),
Expand Down
103 changes: 64 additions & 39 deletions novelwriter/dialogs/preferences.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,26 +187,6 @@ def buildForm(self) -> None:
self.tr("User interface icon theme."), stretch=(3, 2)
)

# Tree Icon Colours
self.iconColTree = NComboBox(self)
self.iconColTree.setMinimumWidth(200)
for key, label in nwLabels.THEME_COLORS.items():
self.iconColTree.addItem(trConst(label), key)
self.iconColTree.setCurrentData(CONFIG.iconColTree, DEF_TREECOL)

self.mainForm.addRow(
self.tr("Project tree icon colours"), self.iconColTree,
self.tr("Override colours for project icons."), stretch=(3, 2)
)

# Keep Theme Colours on Documents
self.iconColDocs = NSwitch(self)
self.iconColDocs.setChecked(CONFIG.iconColDocs)
self.mainForm.addRow(
self.tr("Keep theme colours on documents"), self.iconColDocs,
self.tr("Only override icon colours for folders.")
)

# Application Font Family
self.guiFont = QLineEdit(self)
self.guiFont.setReadOnly(True)
Expand Down Expand Up @@ -279,14 +259,6 @@ def buildForm(self) -> None:
button=self.textFontButton
)

# Emphasise Labels
self.emphLabels = NSwitch(self)
self.emphLabels.setChecked(CONFIG.emphLabels)
self.mainForm.addRow(
self.tr("Emphasise partition and chapter labels"), self.emphLabels,
self.tr("Makes them stand out in the project tree."),
)

# Document Path
self.showFullPath = NSwitch(self)
self.showFullPath.setChecked(CONFIG.showFullPath)
Expand All @@ -302,6 +274,42 @@ def buildForm(self) -> None:
self.tr("Include project notes in status bar word count"), self.incNotesWCount
)

# Project View
# ============

title = self.tr("Project View")
section += 1
self.sidebar.addButton(title, section)
self.mainForm.addGroupLabel(title, section)

# Tree Icon Colours
self.iconColTree = NComboBox(self)
self.iconColTree.setMinimumWidth(200)
for key, label in nwLabels.THEME_COLORS.items():
self.iconColTree.addItem(trConst(label), key)
self.iconColTree.setCurrentData(CONFIG.iconColTree, DEF_TREECOL)

self.mainForm.addRow(
self.tr("Project tree icon colours"), self.iconColTree,
self.tr("Override colours for project icons."), stretch=(3, 2)
)

# Keep Theme Colours on Documents
self.iconColDocs = NSwitch(self)
self.iconColDocs.setChecked(CONFIG.iconColDocs)
self.mainForm.addRow(
self.tr("Keep theme colours on documents"), self.iconColDocs,
self.tr("Only override icon colours for folders.")
)

# Emphasise Labels
self.emphLabels = NSwitch(self)
self.emphLabels.setChecked(CONFIG.emphLabels)
self.mainForm.addRow(
self.tr("Emphasise partition and chapter labels"), self.emphLabels,
self.tr("Makes them stand out in the project tree."),
)

# Behaviour
# =========

Expand Down Expand Up @@ -514,6 +522,18 @@ def buildForm(self) -> None:
self.tr("Apply formatting to word under cursor if no selection is made.")
)

# Cursor Width
self.cursorWidth = NSpinBox(self)
self.cursorWidth.setMinimum(1)
self.cursorWidth.setMaximum(20)
self.cursorWidth.setSingleStep(1)
self.cursorWidth.setValue(CONFIG.cursorWidth)
self.mainForm.addRow(
self.tr("Cursor Width"), self.cursorWidth,
self.tr("The width of the editor cursor."),
unit=self.tr("px")
)

# Show Tabs and Spaces
self.showTabsNSpaces = NSwitch(self)
self.showTabsNSpaces.setChecked(CONFIG.showTabsNSpaces)
Expand All @@ -540,7 +560,7 @@ def buildForm(self) -> None:
self.scrollPastEnd = NSwitch(self)
self.scrollPastEnd.setChecked(CONFIG.scrollPastEnd)
self.mainForm.addRow(
self.tr("Scroll past end of the document"), self.scrollPastEnd,
self.tr("Scroll past the end of the document"), self.scrollPastEnd,
self.tr("Also centres the cursor when scrolling.")
)

Expand Down Expand Up @@ -940,39 +960,43 @@ def _doSave(self) -> None:
guiLocale = self.guiLocale.currentData()
guiTheme = self.guiTheme.currentData()
iconTheme = self.iconTheme.currentData()
iconColTree = self.iconColTree.currentData()
iconColDocs = self.iconColDocs.isChecked()

updateTheme |= CONFIG.guiTheme != guiTheme
updateTheme |= CONFIG.iconTheme != iconTheme
updateTheme |= CONFIG.iconColTree != iconColTree
updateTheme |= CONFIG.iconColDocs != iconColDocs
needsRestart |= CONFIG.guiLocale != guiLocale
needsRestart |= CONFIG.guiFont != self._guiFont

CONFIG.guiLocale = guiLocale
CONFIG.guiTheme = guiTheme
CONFIG.iconTheme = iconTheme
CONFIG.iconColTree = iconColTree
CONFIG.iconColDocs = iconColDocs
CONFIG.hideVScroll = self.hideVScroll.isChecked()
CONFIG.hideHScroll = self.hideHScroll.isChecked()
CONFIG.nativeFont = self.nativeFont.isChecked()
CONFIG.setGuiFont(self._guiFont)

# Document Style
guiSyntax = self.guiSyntax.currentData()
emphLabels = self.emphLabels.isChecked()
guiSyntax = self.guiSyntax.currentData()

updateSyntax |= CONFIG.guiSyntax != guiSyntax
refreshTree |= CONFIG.emphLabels != emphLabels

CONFIG.guiSyntax = guiSyntax
CONFIG.emphLabels = emphLabels
CONFIG.showFullPath = self.showFullPath.isChecked()
CONFIG.incNotesWCount = self.incNotesWCount.isChecked()
CONFIG.setTextFont(self._textFont)

# Project View
iconColTree = self.iconColTree.currentData()
iconColDocs = self.iconColDocs.isChecked()
emphLabels = self.emphLabels.isChecked()

updateTheme |= CONFIG.iconColTree != iconColTree
updateTheme |= CONFIG.iconColDocs != iconColDocs
refreshTree |= CONFIG.emphLabels != emphLabels

CONFIG.iconColTree = iconColTree
CONFIG.iconColDocs = iconColDocs
CONFIG.emphLabels = emphLabels

# Behaviour
CONFIG.autoSaveDoc = self.autoSaveDoc.value()
CONFIG.autoSaveProj = self.autoSaveProj.value()
Expand All @@ -998,6 +1022,7 @@ def _doSave(self) -> None:
# Text Editing
CONFIG.spellLanguage = self.spellLanguage.currentData()
CONFIG.autoSelect = self.autoSelect.isChecked()
CONFIG.cursorWidth = self.cursorWidth.value()
CONFIG.showTabsNSpaces = self.showTabsNSpaces.isChecked()
CONFIG.showLineEndings = self.showLineEndings.isChecked()

Expand Down
3 changes: 2 additions & 1 deletion novelwriter/gui/doceditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,9 @@ def initEditor(self) -> None:
else:
self.setHorizontalScrollBarPolicy(QtScrollAsNeeded)

# Refresh the tab stops
# Refresh sizes
self.setTabStopDistance(CONFIG.tabWidth)
self.setCursorWidth(CONFIG.cursorWidth)

# If we have a document open, we should refresh it in case the
# font changed, otherwise we just clear the editor entirely,
Expand Down
3 changes: 2 additions & 1 deletion tests/reference/baseConfig_novelwriter.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[Meta]
timestamp = 2025-01-29 11:56:34
timestamp = 2025-02-06 11:05:16

[Main]
font =
Expand Down Expand Up @@ -36,6 +36,7 @@ textfont =
width = 700
margin = 40
tabwidth = 40
cursorwidth = 1
focuswidth = 800
hidefocusfooter = False
justify = False
Expand Down
20 changes: 17 additions & 3 deletions tests/test_dialogs/test_dlg_preferences.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,16 +178,23 @@ def testDlgPreferences_Settings(qtbot, monkeypatch, nwGUI, fncPath, tstPaths):
mp.setattr(QFontDialog, "getFont", lambda *a, **k: (QFont(), True))
prefs.nativeFont.setChecked(False) # Use Qt font dialog
prefs.textFontButton.click()
prefs.emphLabels.setChecked(False)
prefs.showFullPath.setChecked(False)
prefs.incNotesWCount.setChecked(False)

assert CONFIG.guiSyntax != "default_dark"
assert CONFIG.textFont.family() != ""
assert CONFIG.emphLabels is True
assert CONFIG.showFullPath is True
assert CONFIG.incNotesWCount is True

# Project View
prefs.iconColTree.setCurrentData("faded", "default")
prefs.iconColDocs.setChecked(True)
prefs.emphLabels.setChecked(False)

assert CONFIG.iconColTree == "theme"
assert CONFIG.iconColDocs is False
assert CONFIG.emphLabels is True

# Behaviour
prefs.autoSaveDoc.stepUp()
prefs.autoSaveProj.stepUp()
Expand Down Expand Up @@ -235,11 +242,13 @@ def testDlgPreferences_Settings(qtbot, monkeypatch, nwGUI, fncPath, tstPaths):
# Text Editing
prefs.spellLanguage.setCurrentIndex(prefs.spellLanguage.findData("de"))
prefs.autoSelect.setChecked(False)
prefs.cursorWidth.setValue(5)
prefs.showTabsNSpaces.setChecked(True)
prefs.showLineEndings.setChecked(True)

assert CONFIG.spellLanguage != "de"
assert CONFIG.autoSelect is True
assert CONFIG.cursorWidth == 1
assert CONFIG.showTabsNSpaces is False
assert CONFIG.showLineEndings is False

Expand Down Expand Up @@ -339,10 +348,14 @@ def testDlgPreferences_Settings(qtbot, monkeypatch, nwGUI, fncPath, tstPaths):
# Document Style
assert CONFIG.guiSyntax == "default_dark"
assert CONFIG.textFont == QFont()
assert CONFIG.emphLabels is False
assert CONFIG.showFullPath is False
assert CONFIG.incNotesWCount is False

# Project View
assert CONFIG.iconColTree == "faded"
assert CONFIG.iconColDocs is True
assert CONFIG.emphLabels is False

# Behaviour
assert CONFIG.autoSaveDoc == 31
assert CONFIG.autoSaveProj == 61
Expand All @@ -368,6 +381,7 @@ def testDlgPreferences_Settings(qtbot, monkeypatch, nwGUI, fncPath, tstPaths):
# Text Editing
assert CONFIG.spellLanguage == "de"
assert CONFIG.autoSelect is False
assert CONFIG.cursorWidth == 5
assert CONFIG.showTabsNSpaces is True
assert CONFIG.showLineEndings is True

Expand Down

0 comments on commit 585f2e5

Please sign in to comment.