Allow display of character count in editor footer and status bar

This commit is contained in:
Veronica Berglyd Olsen
2025-05-18 16:27:30 +02:00
parent 51c7fb2614
commit 916039b420
5 changed files with 87 additions and 52 deletions
+4
View File
@@ -352,6 +352,10 @@ class nwLabels:
nwStats.WORDS_TEXT: QT_TRANSLATE_NOOP("Stats", "Words in Text"),
nwStats.WORDS_TITLE: QT_TRANSLATE_NOOP("Stats", "Words in Headings"),
}
STATS_DISPLAY: Final[dict[str, str]] = {
nwStats.CHARS: QT_TRANSLATE_NOOP("Stats", "Characters: {0} ({1})"),
nwStats.WORDS: QT_TRANSLATE_NOOP("Stats", "Words: {0} ({1})"),
}
BUILD_FMT: Final[dict[nwBuildFmt, str]] = {
nwBuildFmt.ODT: QT_TRANSLATE_NOOP("Constant", "Open Document (.odt)"),
nwBuildFmt.FODT: QT_TRANSLATE_NOOP("Constant", "Flat Open Document (.fodt)"),
+10 -7
View File
@@ -53,10 +53,10 @@ class NWItem:
"""
__slots__ = (
"_active", "_charCount", "_class", "_cursorPos", "_expanded",
"_handle", "_heading", "_import", "_initCount", "_layout", "_name",
"_active", "_charCount", "_charInit", "_class", "_cursorPos",
"_expanded", "_handle", "_heading", "_import", "_layout", "_name",
"_order", "_paraCount", "_parent", "_project", "_root", "_status",
"_type", "_wordCount",
"_type", "_wordCount", "_wordInit",
)
def __init__(self, project: NWProject, handle: str) -> None:
@@ -81,7 +81,8 @@ class NWItem:
self._wordCount = 0 # Current word count
self._paraCount = 0 # Current paragraph count
self._cursorPos = 0 # Last cursor position
self._initCount = 0 # Initial word count
self._wordInit = 0 # Initial character count
self._charInit = 0 # Initial word count
return
@@ -170,7 +171,7 @@ class NWItem:
@property
def initCount(self) -> int:
return self._initCount
return self._wordInit if CONFIG.useCharCount else self._charInit
@property
def cursorPos(self) -> int:
@@ -261,7 +262,8 @@ class NWItem:
self._paraCount = 0
self._cursorPos = 0
self._initCount = self._wordCount
self._wordInit = self._charCount
self._charInit = self._wordCount
return True
@@ -285,7 +287,8 @@ class NWItem:
new._wordCount = source._wordCount
new._paraCount = source._paraCount
new._cursorPos = source._cursorPos
new._initCount = source._initCount
new._wordInit = source._wordInit
new._charInit = source._charInit
return new
##
+29 -19
View File
@@ -55,7 +55,9 @@ from novelwriter import CONFIG, SHARED
from novelwriter.common import (
decodeMimeHandles, fontMatcher, minmax, qtAddAction, qtLambda, transferCase
)
from novelwriter.constants import nwConst, nwKeyWords, nwShortcode, nwUnicode
from novelwriter.constants import (
nwConst, nwKeyWords, nwLabels, nwShortcode, nwStats, nwUnicode, trStats
)
from novelwriter.core.document import NWDocument
from novelwriter.enum import (
nwChange, nwComment, nwDocAction, nwDocInsert, nwDocMode, nwItemClass,
@@ -321,6 +323,7 @@ class GuiDocEditor(QPlainTextEdit):
"""
# Auto-Replace
self._autoReplace.initSettings()
self.docFooter.initSettings()
# Reload spell check and dictionaries
SHARED.updateSpellCheckLanguage()
@@ -1233,7 +1236,8 @@ class GuiDocEditor(QPlainTextEdit):
"""Process the word counter's finished signal."""
if self._docHandle and self._nwItem:
logger.debug("Updating word count")
needsRefresh = wCount != self._nwItem.wordCount
mCount = cCount if CONFIG.useCharCount else wCount
needsRefresh = mCount != self._nwItem.mainCount
self._nwItem.setCharCount(cCount)
self._nwItem.setWordCount(wCount)
self._nwItem.setParaCount(pCount)
@@ -1241,7 +1245,7 @@ class GuiDocEditor(QPlainTextEdit):
self._nwItem.notifyToRefresh()
if not self.textCursor().hasSelection():
# Selection counter should take precedence (#2155)
self.docFooter.updateWordCount(wCount, False)
self.docFooter.updateMainCount(mCount, False)
return
@pyqtSlot()
@@ -1254,7 +1258,7 @@ class GuiDocEditor(QPlainTextEdit):
self._timerSel.start()
else:
self._timerSel.stop()
self.docFooter.updateWordCount(0, False)
self.docFooter.updateMainCount(0, False)
return
@pyqtSlot()
@@ -1271,8 +1275,7 @@ class GuiDocEditor(QPlainTextEdit):
def _updateSelCounts(self, cCount: int, wCount: int, pCount: int) -> None:
"""Update the counts on the counter's finished signal."""
if self._docHandle and self._nwItem:
logger.debug("User selected %d words", wCount)
self.docFooter.updateWordCount(wCount, True)
self.docFooter.updateMainCount(cCount if CONFIG.useCharCount else wCount, True)
self._timerSel.stop()
return
@@ -3045,9 +3048,9 @@ class GuiDocEditFooter(QWidget):
fPx = int(0.9*SHARED.theme.fontPixelSize)
# Cached Translations
self.initSettings()
self._trLineCount = self.tr("Line: {0} ({1})")
self._trWordCount = self.tr("Words: {0} ({1})")
self._trSelectCount = self.tr("Words: {0} selected")
self._trSelectCount = self.tr("Selected: {0}")
# Main Widget Settings
self.setContentsMargins(0, 0, 0, 0)
@@ -3108,7 +3111,7 @@ class GuiDocEditFooter(QWidget):
self.updateTheme()
# Initialise Info
self.updateWordCount(0, False)
self.updateMainCount(0, False)
logger.debug("Ready: GuiDocEditFooter")
@@ -3118,6 +3121,13 @@ class GuiDocEditFooter(QWidget):
# Methods
##
def initSettings(self) -> None:
"""Apply user settings."""
self._trMainCount = trStats(nwLabels.STATS_DISPLAY[
nwStats.CHARS if CONFIG.useCharCount else nwStats.WORDS
])
return
def updateFont(self) -> None:
"""Update the font settings."""
self.setFont(SHARED.theme.guiFont)
@@ -3162,7 +3172,7 @@ class GuiDocEditFooter(QWidget):
self._tItem = SHARED.project.tree[self._docHandle]
self.updateInfo()
self.updateWordCount(0, False)
self.updateMainCount(0, False)
return
@@ -3193,15 +3203,15 @@ class GuiDocEditFooter(QWidget):
)
return
def updateWordCount(self, wCount: int, selection: bool) -> None:
"""Update word counter information."""
if selection and wCount:
wText = self._trSelectCount.format(f"{wCount:n}")
def updateMainCount(self, count: int, selection: bool) -> None:
"""Update main counter information."""
if selection and count:
text = self._trSelectCount.format(f"{count:n}")
elif self._tItem:
wCount = self._tItem.wordCount
wDiff = wCount - self._tItem.initCount
wText = self._trWordCount.format(f"{wCount:n}", f"{wDiff:+n}")
count = self._tItem.mainCount
diff = count - self._tItem.initCount
text = self._trMainCount.format(f"{count:n}", f"{diff:+n}")
else:
wText = self._trWordCount.format("0", "+0")
self.wordsText.setText(wText)
text = self._trMainCount.format("0", "+0")
self.wordsText.setText(text)
return
+14 -6
View File
@@ -33,7 +33,7 @@ from PyQt6.QtWidgets import QApplication, QLabel, QStatusBar, QWidget
from novelwriter import CONFIG, SHARED
from novelwriter.common import formatTime
from novelwriter.constants import nwConst
from novelwriter.constants import nwConst, nwLabels, nwStats, trStats
from novelwriter.extensions.modified import NClickableLabel
from novelwriter.extensions.statusled import StatusLED
@@ -108,11 +108,22 @@ class GuiMainStatus(QStatusBar):
logger.debug("Ready: GuiMainStatus")
self.initSettings()
self.updateTheme()
self.clearStatus()
return
def initSettings(self) -> None:
"""Apply user settings."""
if CONFIG.useCharCount:
self._trStatsCount = trStats(nwLabels.STATS_DISPLAY[nwStats.CHARS])
self._trStatsTip = self.tr("Total character count (session change)")
else:
self._trStatsCount = trStats(nwLabels.STATS_DISPLAY[nwStats.WORDS])
self._trStatsTip = self.tr("Total word count (session change)")
return
def clearStatus(self) -> None:
"""Reset all widgets on the status bar to default values."""
self.setRefTime(-1.0)
@@ -173,11 +184,8 @@ class GuiMainStatus(QStatusBar):
def setProjectStats(self, pWC: int, sWC: int) -> None:
"""Update the current project statistics."""
self.statsText.setText(self.tr("Words: {0} ({1})").format(f"{pWC:n}", f"{sWC:+n}"))
if CONFIG.incNotesWCount:
self.statsText.setToolTip(self.tr("Project word count (session change)"))
else:
self.statsText.setToolTip(self.tr("Novel word count (session change)"))
self.statsText.setText(self._trStatsCount.format(f"{pWC:n}", f"{sWC:+n}"))
self.statsText.setToolTip(self._trStatsTip)
return
def updateTime(self, idleTime: float = 0.0) -> None:
+10
View File
@@ -1077,6 +1077,7 @@ class GuiMain(QMainWindow):
self.projView.initSettings()
self.novelView.initSettings()
self.outlineView.initSettings()
self.mainStatus.initSettings()
# Force update of word count
self._lastTotalCount = 0
@@ -1265,11 +1266,20 @@ class GuiMain(QMainWindow):
SHARED.project.updateCounts()
if CONFIG.incNotesWCount:
if CONFIG.useCharCount:
iTotal = sum(SHARED.project.data.initCounts[2:])
cTotal = sum(SHARED.project.data.currCounts[2:])
else:
iTotal = sum(SHARED.project.data.initCounts[:2])
cTotal = sum(SHARED.project.data.currCounts[:2])
else:
if CONFIG.useCharCount:
iTotal = SHARED.project.data.initCounts[2]
cTotal = SHARED.project.data.currCounts[2]
else:
iTotal = SHARED.project.data.initCounts[0]
cTotal = SHARED.project.data.currCounts[0]
self.mainStatus.setProjectStats(cTotal, cTotal - iTotal)
return