Skip to content

Commit

Permalink
Optimise a few details and add some tests
Browse files Browse the repository at this point in the history
  • Loading branch information
vkbo committed Nov 26, 2024
1 parent c091e0b commit 43d9546
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 16 deletions.
11 changes: 9 additions & 2 deletions novelwriter/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,9 +436,9 @@ def describeFont(font: QFont) -> str:

def fontMatcher(font: QFont) -> QFont:
"""Make sure the font is the correct family, if possible. This
ensures that Qt doesn't reuse another font under the hood. The
ensures that Qt doesn't re-use another font under the hood. The
default Qt5 font matching algorithm doesn't handle well changing
fonts at runtime.
application fonts at runtime.
"""
info = QFontInfo(font)
if (famRequest := font.family()) != (famActual := info.family()):
Expand All @@ -448,6 +448,7 @@ def fontMatcher(font: QFont) -> QFont:
styleRequest, sizeRequest = font.styleName(), font.pointSize()
logger.info("Lookup: %s, %s, %d pt", famRequest, styleRequest, sizeRequest)
temp = db.font(famRequest, styleRequest, sizeRequest)
temp.setPointSize(sizeRequest) # Make sure it isn't changed
famFound, styleFound, sizeFound = temp.family(), temp.styleName(), temp.pointSize()
if famFound == famRequest:
logger.info("Found: %s, %s, %d pt", famFound, styleFound, sizeFound)
Expand All @@ -464,6 +465,12 @@ def wrapper(*a_: Any) -> None:
return wrapper


def encodeMimeHandles(mimeData: QMimeData, handles: list[str]) -> None:
"""Encode handles into a mime data object."""
mimeData.setData(nwConst.MIME_HANDLE, b"|".join(h.encode() for h in handles))
return


def decodeMimeHandles(mimeData: QMimeData) -> list[str]:
"""Decode and split a mime data object with handles."""
return mimeData.data(nwConst.MIME_HANDLE).data().decode().split("|")
Expand Down
6 changes: 3 additions & 3 deletions novelwriter/core/itemmodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from PyQt5.QtCore import QAbstractItemModel, QMimeData, QModelIndex, Qt
from PyQt5.QtGui import QFont, QIcon

from novelwriter.common import decodeMimeHandles, minmax
from novelwriter.common import decodeMimeHandles, encodeMimeHandles, minmax
from novelwriter.constants import nwConst
from novelwriter.core.item import NWItem
from novelwriter.enum import nwItemClass
Expand Down Expand Up @@ -367,11 +367,11 @@ def mimeTypes(self) -> list[str]:
def mimeData(self, indices: list[QModelIndex]) -> QMimeData:
"""Encode mime data about a selection."""
handles = [
i.internalPointer().item.itemHandle.encode()
i.internalPointer().item.itemHandle
for i in indices if i.isValid() and i.column() == 0
]
mime = QMimeData()
mime.setData(nwConst.MIME_HANDLE, b"|".join(handles))
encodeMimeHandles(mime, handles)
return mime

def canDropMimeData(
Expand Down
6 changes: 4 additions & 2 deletions novelwriter/gui/doceditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -1279,11 +1279,13 @@ def _updateDocCounts(self, cCount: int, wCount: int, pCount: int) -> None:
"""Process the word counter's finished signal."""
if self._docHandle and self._nwItem:
logger.debug("Updating word count")
needsRefresh = wCount != self._nwItem.wordCount
self._nwItem.setCharCount(cCount)
self._nwItem.setWordCount(wCount)
self._nwItem.setParaCount(pCount)
self._nwItem.notifyToRefresh()
self.docFooter.updateWordCount(wCount, False)
if needsRefresh:
self._nwItem.notifyToRefresh()
self.docFooter.updateWordCount(wCount, False)
return

@pyqtSlot()
Expand Down
47 changes: 38 additions & 9 deletions tests/test_base/test_base_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,19 @@

import pytest

from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QColor, QDesktopServices, QFontDatabase
from PyQt5.QtCore import QMimeData, QUrl
from PyQt5.QtGui import QColor, QDesktopServices, QFont, QFontDatabase, QFontInfo

from novelwriter.common import (
NWConfigParser, checkBool, checkFloat, checkInt, checkIntTuple, checkPath,
checkString, checkStringNone, checkUuid, compact, cssCol, describeFont,
elide, firstFloat, formatFileFilter, formatInt, formatTime,
formatTimeStamp, formatVersion, fuzzyTime, getFileSize, hexToInt, isHandle,
isItemClass, isItemLayout, isItemType, isListInstance, isTitleTag,
jsonEncode, makeFileNameSafe, minmax, numberToRoman, openExternalPath,
readTextFile, simplified, transferCase, uniqueCompact, xmlElement,
xmlIndent, xmlSubElem, yesNo
checkString, checkStringNone, checkUuid, compact, cssCol,
decodeMimeHandles, describeFont, elide, encodeMimeHandles, firstFloat,
fontMatcher, formatFileFilter, formatInt, formatTime, formatTimeStamp,
formatVersion, fuzzyTime, getFileSize, hexToInt, isHandle, isItemClass,
isItemLayout, isItemType, isListInstance, isTitleTag, jsonEncode,
makeFileNameSafe, minmax, numberToRoman, openExternalPath, readTextFile,
simplified, transferCase, uniqueCompact, xmlElement, xmlIndent, xmlSubElem,
yesNo
)

from tests.mocked import causeOSError
Expand Down Expand Up @@ -528,6 +529,34 @@ def testBaseCommon_describeFont():
assert describeFont(None) == "Error" # type: ignore


@pytest.mark.base
def testBaseCommon_fontMatcher(monkeypatch):
"""Test the fontMatcher function."""
# Nonsense font is just returned
nonsense = QFont("nonesense", 10)
assert fontMatcher(nonsense) is nonsense

# General font
fontDB = QFontDatabase()
if len(fontDB.families()) > 1:
fontOne = QFont(fontDB.families()[0])
fontTwo = QFont(fontDB.families()[1])
check = QFont(fontOne)
check.setFamily(fontTwo.family())
with monkeypatch.context() as mp:
mp.setattr(QFontInfo, "family", lambda *a: "nonesense")
assert fontMatcher(check).family() == fontTwo.family()


@pytest.mark.base
def testBaseCommon_encodeDecodeMimeHandles(monkeypatch):
"""Test the encodeMimeHandles and decodeMimeHandles functions."""
handles = ["0123456789abc", "123456789abcd", "23456789abcde"]
mimeData = QMimeData()
encodeMimeHandles(mimeData, handles)
assert decodeMimeHandles(mimeData) == handles


@pytest.mark.base
def testBaseCommon_jsonEncode():
"""Test the jsonEncode function."""
Expand Down

0 comments on commit 43d9546

Please sign in to comment.