Improve memory handling and fix a few variables (#1913)

This commit is contained in:
Veronica Berglyd Olsen
2024-06-09 00:08:52 +02:00
committed by GitHub
11 changed files with 115 additions and 108 deletions
+3 -6
View File
@@ -57,9 +57,6 @@ class nwConst:
STATUS_MSG_TIMEOUT = 15000 # milliseconds
MAX_SEARCH_RESULT = 1000
# Dialogs
DLG_FINISHED = 2
class nwRegEx:
@@ -414,7 +411,7 @@ class nwUnicode:
U_EMDASH = "\u2014" # Long dash
U_HBAR = "\u2015" # Horizontal bar
U_HELLIP = "\u2026" # Ellipsis
U_MAPOSS = "\u02bc" # Modifier letter single apostrophe
U_MAPOS = "\u02bc" # Modifier letter single apostrophe
U_PRIME = "\u2032" # Prime
U_DPRIME = "\u2033" # Double prime
@@ -481,7 +478,7 @@ class nwUnicode:
H_EMDASH = "—"
H_HBAR = "―"
H_HELLIP = "…"
H_MAPOSS = "ʼ"
H_MAPOS = "ʼ"
H_PRIME = "′"
H_DPRIME = "″"
@@ -546,7 +543,7 @@ class nwHtmlUnicode():
nwUnicode.U_EMDASH: nwUnicode.H_EMDASH,
nwUnicode.U_HBAR: nwUnicode.H_HBAR,
nwUnicode.U_HELLIP: nwUnicode.H_HELLIP,
nwUnicode.U_MAPOSS: nwUnicode.H_MAPOSS,
nwUnicode.U_MAPOS: nwUnicode.H_MAPOS,
nwUnicode.U_PRIME: nwUnicode.H_PRIME,
nwUnicode.U_DPRIME: nwUnicode.H_DPRIME,
+1 -1
View File
@@ -485,7 +485,7 @@ class Tokenizer(ABC):
self._text = xRep.sub(lambda x: repDict[x.group(0)], self._text)
# Process the character translation map
trDict = {nwUnicode.U_MAPOSS: nwUnicode.U_RSQUO}
trDict = {nwUnicode.U_MAPOS: nwUnicode.U_RSQUO}
self._text = self._text.translate(str.maketrans(trDict))
return
+78 -57
View File
@@ -29,13 +29,13 @@ import logging
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
from PyQt5.QtGui import QCloseEvent
from PyQt5.QtWidgets import (
QAbstractButton, QApplication, QCompleter, QDialogButtonBox, QFileDialog,
QHBoxLayout, QLineEdit, QPushButton, QVBoxLayout, QWidget
QAbstractButton, QCompleter, QDialogButtonBox, QFileDialog, QHBoxLayout,
QLineEdit, QPushButton, QVBoxLayout, QWidget
)
from novelwriter import CONFIG, SHARED
from novelwriter.common import describeFont
from novelwriter.constants import nwConst, nwUnicode
from novelwriter.constants import nwUnicode
from novelwriter.dialogs.quotes import GuiQuoteSelect
from novelwriter.extensions.configlayout import NColourLabel, NScrollableForm
from novelwriter.extensions.modified import (
@@ -695,64 +695,62 @@ class GuiPreferences(NDialog):
self.sidebar.addButton(title, section)
self.mainForm.addGroupLabel(title, section)
self.quoteSym = {}
# Single Quote Style
self.quoteSym["SO"] = QLineEdit(self)
self.quoteSym["SO"].setMaxLength(1)
self.quoteSym["SO"].setReadOnly(True)
self.quoteSym["SO"].setFixedWidth(boxFixed)
self.quoteSym["SO"].setAlignment(QtAlignCenter)
self.quoteSym["SO"].setText(CONFIG.fmtSQuoteOpen)
self.btnSingleStyleO = NIconToolButton(self, iSz, "quote")
self.btnSingleStyleO.clicked.connect(lambda: self._getQuote("SO"))
self.fmtSQuoteOpen = QLineEdit(self)
self.fmtSQuoteOpen.setMaxLength(1)
self.fmtSQuoteOpen.setReadOnly(True)
self.fmtSQuoteOpen.setFixedWidth(boxFixed)
self.fmtSQuoteOpen.setAlignment(QtAlignCenter)
self.fmtSQuoteOpen.setText(CONFIG.fmtSQuoteOpen)
self.btnSQuoteOpen = NIconToolButton(self, iSz, "quote")
self.btnSQuoteOpen.clicked.connect(self._changeSingleQuoteOpen)
self.mainForm.addRow(
self.tr("Single quote open style"), self.quoteSym["SO"],
self.tr("Single quote open style"), self.fmtSQuoteOpen,
self.tr("The symbol to use for a leading single quote."),
button=self.btnSingleStyleO
button=self.btnSQuoteOpen
)
self.quoteSym["SC"] = QLineEdit(self)
self.quoteSym["SC"].setMaxLength(1)
self.quoteSym["SC"].setReadOnly(True)
self.quoteSym["SC"].setFixedWidth(boxFixed)
self.quoteSym["SC"].setAlignment(QtAlignCenter)
self.quoteSym["SC"].setText(CONFIG.fmtSQuoteClose)
self.btnSingleStyleC = NIconToolButton(self, iSz, "quote")
self.btnSingleStyleC.clicked.connect(lambda: self._getQuote("SC"))
self.fmtSQuoteClose = QLineEdit(self)
self.fmtSQuoteClose.setMaxLength(1)
self.fmtSQuoteClose.setReadOnly(True)
self.fmtSQuoteClose.setFixedWidth(boxFixed)
self.fmtSQuoteClose.setAlignment(QtAlignCenter)
self.fmtSQuoteClose.setText(CONFIG.fmtSQuoteClose)
self.btnSQuoteClose = NIconToolButton(self, iSz, "quote")
self.btnSQuoteClose.clicked.connect(self._changeSingleQuoteClose)
self.mainForm.addRow(
self.tr("Single quote close style"), self.quoteSym["SC"],
self.tr("Single quote close style"), self.fmtSQuoteClose,
self.tr("The symbol to use for a trailing single quote."),
button=self.btnSingleStyleC
button=self.btnSQuoteClose
)
# Double Quote Style
self.quoteSym["DO"] = QLineEdit(self)
self.quoteSym["DO"].setMaxLength(1)
self.quoteSym["DO"].setReadOnly(True)
self.quoteSym["DO"].setFixedWidth(boxFixed)
self.quoteSym["DO"].setAlignment(QtAlignCenter)
self.quoteSym["DO"].setText(CONFIG.fmtDQuoteOpen)
self.btnDoubleStyleO = NIconToolButton(self, iSz, "quote")
self.btnDoubleStyleO.clicked.connect(lambda: self._getQuote("DO"))
self.fmtDQuoteOpen = QLineEdit(self)
self.fmtDQuoteOpen.setMaxLength(1)
self.fmtDQuoteOpen.setReadOnly(True)
self.fmtDQuoteOpen.setFixedWidth(boxFixed)
self.fmtDQuoteOpen.setAlignment(QtAlignCenter)
self.fmtDQuoteOpen.setText(CONFIG.fmtDQuoteOpen)
self.btnDQuoteOpen = NIconToolButton(self, iSz, "quote")
self.btnDQuoteOpen.clicked.connect(self._changeDoubleQuoteOpen)
self.mainForm.addRow(
self.tr("Double quote open style"), self.quoteSym["DO"],
self.tr("Double quote open style"), self.fmtDQuoteOpen,
self.tr("The symbol to use for a leading double quote."),
button=self.btnDoubleStyleO
button=self.btnDQuoteOpen
)
self.quoteSym["DC"] = QLineEdit(self)
self.quoteSym["DC"].setMaxLength(1)
self.quoteSym["DC"].setReadOnly(True)
self.quoteSym["DC"].setFixedWidth(boxFixed)
self.quoteSym["DC"].setAlignment(QtAlignCenter)
self.quoteSym["DC"].setText(CONFIG.fmtDQuoteClose)
self.btnDoubleStyleC = NIconToolButton(self, iSz, "quote")
self.btnDoubleStyleC.clicked.connect(lambda: self._getQuote("DC"))
self.fmtDQuoteClose = QLineEdit(self)
self.fmtDQuoteClose.setMaxLength(1)
self.fmtDQuoteClose.setReadOnly(True)
self.fmtDQuoteClose.setFixedWidth(boxFixed)
self.fmtDQuoteClose.setAlignment(QtAlignCenter)
self.fmtDQuoteClose.setText(CONFIG.fmtDQuoteClose)
self.btnDQuoteClose = NIconToolButton(self, iSz, "quote")
self.btnDQuoteClose.clicked.connect(self._changeDoubleQuoteClose)
self.mainForm.addRow(
self.tr("Double quote close style"), self.quoteSym["DC"],
self.tr("Double quote close style"), self.fmtDQuoteClose,
self.tr("The symbol to use for a trailing double quote."),
button=self.btnDoubleStyleC
button=self.btnDQuoteClose
)
self.mainForm.finalise()
@@ -769,8 +767,6 @@ class GuiPreferences(NDialog):
logger.debug("Close: GuiPreferences")
self._saveWindowSize()
event.accept()
QApplication.processEvents()
self.done(nwConst.DLG_FINISHED)
self.softDelete()
return
@@ -850,11 +846,36 @@ class GuiPreferences(NDialog):
self.fmtPadThin.setEnabled(state)
return
def _getQuote(self, qType: str) -> None:
"""Dialog for single quote open."""
quote, status = GuiQuoteSelect.getQuote(self, current=self.quoteSym[qType].text())
@pyqtSlot()
def _changeSingleQuoteOpen(self) -> None:
"""Change single quote open style."""
quote, status = GuiQuoteSelect.getQuote(self, current=self.fmtSQuoteOpen.text())
if status:
self.quoteSym[qType].setText(quote)
self.fmtSQuoteOpen.setText(quote)
return
@pyqtSlot()
def _changeSingleQuoteClose(self) -> None:
"""Change single quote close style."""
quote, status = GuiQuoteSelect.getQuote(self, current=self.fmtSQuoteClose.text())
if status:
self.fmtSQuoteClose.setText(quote)
return
@pyqtSlot()
def _changeDoubleQuoteOpen(self) -> None:
"""Change double quote open style."""
quote, status = GuiQuoteSelect.getQuote(self, current=self.fmtDQuoteOpen.text())
if status:
self.fmtDQuoteOpen.setText(quote)
return
@pyqtSlot()
def _changeDoubleQuoteClose(self) -> None:
"""Change double quote close style."""
quote, status = GuiQuoteSelect.getQuote(self, current=self.fmtDQuoteClose.text())
if status:
self.fmtDQuoteClose.setText(quote)
return
##
@@ -874,8 +895,8 @@ class GuiPreferences(NDialog):
refreshTree = False
# Appearance
guiLocale = self.guiLocale.currentData()
guiTheme = self.guiTheme.currentData()
guiLocale = self.guiLocale.currentData()
guiTheme = self.guiTheme.currentData()
updateTheme |= CONFIG.guiTheme != guiTheme
needsRestart |= CONFIG.guiLocale != guiLocale
@@ -972,10 +993,10 @@ class GuiPreferences(NDialog):
CONFIG.fmtPadThin = self.fmtPadThin.isChecked()
# Quotation Style
CONFIG.fmtSQuoteOpen = self.quoteSym["SO"].text()
CONFIG.fmtSQuoteClose = self.quoteSym["SC"].text()
CONFIG.fmtDQuoteOpen = self.quoteSym["DO"].text()
CONFIG.fmtDQuoteClose = self.quoteSym["DC"].text()
CONFIG.fmtSQuoteOpen = self.fmtSQuoteOpen.text()
CONFIG.fmtSQuoteClose = self.fmtSQuoteClose.text()
CONFIG.fmtDQuoteOpen = self.fmtDQuoteOpen.text()
CONFIG.fmtDQuoteClose = self.fmtDQuoteClose.text()
# Finalise
CONFIG.saveConfig()
+2 -2
View File
@@ -64,7 +64,7 @@ from novelwriter.text.counting import standardCounter
from novelwriter.tools.lipsum import GuiLipsum
from novelwriter.types import (
QtAlignCenterTop, QtAlignJustify, QtAlignLeft, QtAlignLeftTop,
QtAlignRight, QtKeepAnchor, QtModCtrl, QtModeNone, QtModShift, QtMouseLeft,
QtAlignRight, QtKeepAnchor, QtModCtrl, QtModNone, QtModShift, QtMouseLeft,
QtMoveAnchor, QtMoveLeft, QtMoveRight
)
@@ -956,7 +956,7 @@ class GuiDocEditor(QPlainTextEdit):
super().keyPressEvent(event)
nPos = self.cursorRect().topLeft().y()
kMod = event.modifiers()
okMod = kMod in (QtModeNone, QtModShift)
okMod = kMod in (QtModNone, QtModShift)
okKey = event.key() not in self.MOVE_KEYS
if nPos != cPos and okMod and okKey:
mPos = CONFIG.autoScrollPos*0.01 * self.viewport().height()
+1 -1
View File
@@ -422,7 +422,7 @@ class GuiMainMenu(QMenuBar):
self.aInsMSApos = self.mInsQuotes.addAction(self.tr("Alternative Apostrophe"))
self.aInsMSApos.setShortcut("Ctrl+K, '")
self.aInsMSApos.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_MAPOSS)
lambda: self.requestDocInsertText.emit(nwUnicode.U_MAPOS)
)
# Insert > Symbols
+9 -16
View File
@@ -239,9 +239,7 @@ class GuiMainStatus(QStatusBar):
"""
import tracemalloc
from collections import Counter
widgets = QApplication.allWidgets()
count = len(QApplication.allWidgets())
if not self._debugInfo:
if tracemalloc.is_tracing():
self._traceMallocRef = "Total"
@@ -249,19 +247,14 @@ class GuiMainStatus(QStatusBar):
self._traceMallocRef = "Relative"
tracemalloc.start()
self._debugInfo = True
self._wCounts = Counter([type(x).__name__ for x in widgets])
if hasattr(self, "_wCounts"):
diff = Counter([type(x).__name__ for x in widgets]) - self._wCounts
for name, count in diff.items():
logger.debug("Widget '%s': +%d", name, count)
mem = tracemalloc.get_traced_memory()
current, peak = tracemalloc.get_traced_memory()
stamp = datetime.now().strftime("%H:%M:%S")
self.showMessage((
f"Debug [{stamp}]"
f" \u2013 Widgets: {len(widgets)}"
f" \u2013 {self._traceMallocRef} Memory: {mem[0]:n}"
f" \u2013 Peak: {mem[1]:n}"
), 6000)
message = (
f"Widgets: {count} \u2013 "
f"{self._traceMallocRef} Memory: {current/1024:,.2f} kiB \u2013 "
f"Peak: {peak/1024:,.2f} kiB"
)
self.showMessage(f"Debug [{stamp}] {message}", 6000)
logger.debug("[MEMINFO] %s", message)
return
+1 -1
View File
@@ -73,7 +73,7 @@ QtUserRole = Qt.ItemDataRole.UserRole
# Keyboard and Mouse Buttons
QtModCtrl = Qt.KeyboardModifier.ControlModifier
QtModeNone = Qt.KeyboardModifier.NoModifier
QtModNone = Qt.KeyboardModifier.NoModifier
QtModShift = Qt.KeyboardModifier.ShiftModifier
QtMouseLeft = Qt.MouseButton.LeftButton
QtMouseMiddle = Qt.MouseButton.MiddleButton
+13 -17
View File
@@ -27,10 +27,10 @@ from PyQt5.QtGui import QFont, QFontDatabase, QKeyEvent
from PyQt5.QtWidgets import QAction, QFileDialog, QFontDialog
from novelwriter import CONFIG, SHARED
from novelwriter.constants import nwConst, nwUnicode
from novelwriter.constants import nwUnicode
from novelwriter.dialogs.preferences import GuiPreferences
from novelwriter.dialogs.quotes import GuiQuoteSelect
from novelwriter.types import QtDialogApply, QtDialogClose, QtDialogSave, QtModeNone
from novelwriter.types import QtDialogApply, QtDialogClose, QtDialogSave, QtModNone
KEY_DELAY = 1
@@ -125,23 +125,19 @@ def testDlgPreferences_Actions(qtbot, monkeypatch, nwGUI):
# Check Save Button
prefs.show()
with qtbot.waitSignal(prefs.newPreferencesReady) as signal:
with qtbot.waitSignal(prefs.finished) as status:
prefs.buttonBox.button(QtDialogSave).click()
assert signal.args == [False, False, False, False]
assert status.args == [nwConst.DLG_FINISHED]
prefs.buttonBox.button(QtDialogSave).click()
assert signal.args == [False, False, False, False]
# Check Close Button
prefs.show()
with qtbot.waitSignal(prefs.finished) as status:
prefs.buttonBox.button(QtDialogClose).click()
assert status.args == [nwConst.DLG_FINISHED]
prefs.buttonBox.button(QtDialogClose).click()
assert prefs.isHidden() is True
# Close Using Escape Key
prefs.show()
with qtbot.waitSignal(prefs.finished) as status:
event = QKeyEvent(QEvent.Type.KeyPress, Qt.Key.Key_Escape, QtModeNone)
prefs.keyPressEvent(event)
assert status.args == [nwConst.DLG_FINISHED]
event = QKeyEvent(QEvent.Type.KeyPress, Qt.Key.Key_Escape, QtModNone)
prefs.keyPressEvent(event)
assert prefs.isHidden() is True
# qtbot.stop()
@@ -299,16 +295,16 @@ def testDlgPreferences_Settings(qtbot, monkeypatch, nwGUI, tstPaths):
# Quotation Style
with monkeypatch.context() as mp:
mp.setattr(GuiQuoteSelect, "getQuote", lambda *a, **k: (nwUnicode.U_LSAQUO, True))
prefs.btnSingleStyleO.click()
prefs.btnSQuoteOpen.click()
with monkeypatch.context() as mp:
mp.setattr(GuiQuoteSelect, "getQuote", lambda *a, **k: (nwUnicode.U_RSAQUO, True))
prefs.btnSingleStyleC.click()
prefs.btnSQuoteClose.click()
with monkeypatch.context() as mp:
mp.setattr(GuiQuoteSelect, "getQuote", lambda *a, **k: (nwUnicode.U_LAQUO, True))
prefs.btnDoubleStyleO.click()
prefs.btnDQuoteOpen.click()
with monkeypatch.context() as mp:
mp.setattr(GuiQuoteSelect, "getQuote", lambda *a, **k: (nwUnicode.U_RAQUO, True))
prefs.btnDoubleStyleC.click()
prefs.btnDQuoteClose.click()
assert CONFIG.fmtSQuoteOpen == nwUnicode.U_LSQUO
assert CONFIG.fmtSQuoteClose == nwUnicode.U_RSQUO
+2 -2
View File
@@ -30,7 +30,7 @@ from novelwriter import CONFIG, SHARED
from novelwriter.core.toqdoc import ToQTextDocument
from novelwriter.enum import nwDocAction
from novelwriter.gui.docviewer import GuiDocViewer
from novelwriter.types import QtModeNone, QtMouseLeft
from novelwriter.types import QtModNone, QtMouseLeft
from tests.mocked import causeException
@@ -61,7 +61,7 @@ def testGuiViewer_Main(qtbot, monkeypatch, nwGUI, prjLipsum):
# Re-select via header click
button = QtMouseLeft
modifier = QtModeNone
modifier = QtModNone
event = QMouseEvent(QEvent.Type.MouseButtonPress, QPoint(), button, button, modifier)
docViewer.docHeader.mousePressEvent(event)
assert nwGUI.projView.projTree.getSelectedHandle() == "88243afbe5ed8"
+1 -1
View File
@@ -400,7 +400,7 @@ def testGuiMainMenu_Insert(qtbot, monkeypatch, nwGUI, fncPath, projPath, mockRnd
nwGUI.docEditor.clear()
nwGUI.mainMenu.aInsMSApos.activate(QAction.Trigger)
assert nwGUI.docEditor.getText() == nwUnicode.U_MAPOSS
assert nwGUI.docEditor.getText() == nwUnicode.U_MAPOS
nwGUI.docEditor.clear()
nwGUI.mainMenu.aInsEllipsis.activate(QAction.Trigger)
+4 -4
View File
@@ -37,7 +37,7 @@ from novelwriter.dialogs.editlabel import GuiEditLabel
from novelwriter.enum import nwItemClass, nwItemLayout, nwItemType, nwWidget
from novelwriter.gui.projtree import GuiProjectTree, GuiProjectView, _TreeContextMenu
from novelwriter.guimain import GuiMain
from novelwriter.types import QtAccepted, QtModeNone, QtMouseLeft, QtMouseMiddle, QtRejected
from novelwriter.types import QtAccepted, QtModNone, QtMouseLeft, QtMouseMiddle, QtRejected
from tests.mocked import causeOSError
from tests.tools import C, buildTestProject
@@ -807,7 +807,7 @@ def testGuiProjTree_AutoScroll(qtbot, monkeypatch, nwGUI: GuiMain, projPath, moc
action = Qt.DropAction.MoveAction
mime = QMimeData()
mouse = QtMouseLeft
modifier = QtModeNone
modifier = QtModNone
# Scroll Down
h = projTree.height()
@@ -864,7 +864,7 @@ def testGuiProjTree_DragAndDrop(qtbot, monkeypatch, caplog, nwGUI: GuiMain, proj
action = Qt.DropAction.MoveAction
mime = QMimeData()
mouse = QtMouseLeft
modifier = QtModeNone
modifier = QtModNone
projTree.saveTreeOrder()
treeOrder = SHARED.project.tree._order
@@ -1064,7 +1064,7 @@ def testGuiProjTree_Other(qtbot, monkeypatch, nwGUI: GuiMain, projPath, mockRnd)
eType = QEvent.Type.MouseButtonPress
pos = projTree.visualItemRect(projTree._getTreeItem(C.hChapterDoc)).center()
button = QtMouseMiddle
modifier = QtModeNone
modifier = QtModNone
# Trigger the viewer
event = QMouseEvent(eType, pos, button, button, modifier)