Skip to content

Commit

Permalink
Fix some minor issues (#1632)
Browse files Browse the repository at this point in the history
  • Loading branch information
vkbo committed Nov 29, 2023
2 parents ef93b41 + f59317c commit 78a75d5
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 59 deletions.
13 changes: 9 additions & 4 deletions novelwriter/gui/doceditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2012,20 +2012,25 @@ def _autoSelect(self) -> QTextCursor:
cPos = cursor.position()
bPos = cursor.block().position()
bLen = cursor.block().length()
apos = nwUnicode.U_APOS + nwUnicode.U_RSQUO

# Scan backwards
# Scan backward
sPos = cPos
for i in range(cPos - bPos):
sPos = cPos - i - 1
if not self._qDocument.characterAt(sPos).isalnum():
cOne = self._qDocument.characterAt(sPos)
cTwo = self._qDocument.characterAt(sPos - 1)
if not (cOne.isalnum() or cOne in apos and cTwo.isalnum()):
sPos += 1
break

# Scan forwards
# Scan forward
ePos = cPos
for i in range(bPos + bLen - cPos):
ePos = cPos + i
if not self._qDocument.characterAt(ePos).isalnum():
cOne = self._qDocument.characterAt(ePos)
cTwo = self._qDocument.characterAt(ePos + 1)
if not (cOne.isalnum() or cOne in apos and cTwo.isalnum()):
break

if ePos - sPos <= 0:
Expand Down
94 changes: 42 additions & 52 deletions novelwriter/gui/noveltree.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,18 +206,18 @@ def __init__(self, novelView: GuiNovelView) -> None:

# Novel Selector
selFont = self.font()
selFont.setWeight(QFont.Bold)
selFont.setWeight(QFont.Weight.Bold)
self.novelPrefix = self.tr("Outline of {0}")
self.novelValue = NovelSelector(self)
self.novelValue.setFont(selFont)
self.novelValue.setMinimumWidth(CONFIG.pxInt(150))
self.novelValue.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.novelValue.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
self.novelValue.novelSelectionChanged.connect(self.setCurrentRoot)

self.tbNovel = QToolButton(self)
self.tbNovel.setToolTip(self.tr("Novel Root"))
self.tbNovel.setIconSize(QSize(iPx, iPx))
self.tbNovel.clicked.connect(self._openNovelSelector)
self.tbNovel.clicked.connect(self.novelValue.showPopup)

# Refresh Button
self.tbRefresh = QToolButton(self)
Expand All @@ -244,7 +244,7 @@ def __init__(self, novelView: GuiNovelView) -> None:
self.tbMore.setToolTip(self.tr("More Options"))
self.tbMore.setIconSize(QSize(iPx, iPx))
self.tbMore.setMenu(self.mMore)
self.tbMore.setPopupMode(QToolButton.InstantPopup)
self.tbMore.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup)

# Assemble
self.outerBox = QHBoxLayout()
Expand Down Expand Up @@ -275,7 +275,7 @@ def updateTheme(self) -> None:
self.tbMore.setIcon(SHARED.theme.getIcon("menu"))

qPalette = self.palette()
qPalette.setBrush(QPalette.Window, qPalette.base())
qPalette.setBrush(QPalette.ColorRole.Window, qPalette.base())
self.setPalette(qPalette)

# StyleSheets
Expand Down Expand Up @@ -327,12 +327,6 @@ def setLastColType(self, colType: NovelTreeColumn, doRefresh: bool = True) -> No
# Private Slots
##

@pyqtSlot()
def _openNovelSelector(self) -> None:
"""Trigger the dropdown list of the novel selector."""
self.novelValue.showPopup()
return

@pyqtSlot()
def _refreshNovelTree(self) -> None:
"""Rebuild the current tree."""
Expand Down Expand Up @@ -408,25 +402,25 @@ def __init__(self, novelView: GuiNovelView) -> None:
cMg = CONFIG.pxInt(6)

self.setIconSize(QSize(iPx, iPx))
self.setFrameStyle(QFrame.NoFrame)
self.setFrameStyle(QFrame.Shape.NoFrame)
self.setUniformRowHeights(True)
self.setAllColumnsShowFocus(True)
self.setHeaderHidden(True)
self.setIndentation(0)
self.setColumnCount(4)
self.setSelectionBehavior(QAbstractItemView.SelectRows)
self.setSelectionMode(QAbstractItemView.SingleSelection)
self.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
self.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
self.setExpandsOnDoubleClick(False)
self.setDragEnabled(False)

# Lock the column sizes
treeHeader = self.header()
treeHeader.setStretchLastSection(False)
treeHeader.setMinimumSectionSize(iPx + cMg)
treeHeader.setSectionResizeMode(self.C_TITLE, QHeaderView.Stretch)
treeHeader.setSectionResizeMode(self.C_WORDS, QHeaderView.ResizeToContents)
treeHeader.setSectionResizeMode(self.C_EXTRA, QHeaderView.ResizeToContents)
treeHeader.setSectionResizeMode(self.C_MORE, QHeaderView.ResizeToContents)
treeHeader.setSectionResizeMode(self.C_TITLE, QHeaderView.ResizeMode.Stretch)
treeHeader.setSectionResizeMode(self.C_WORDS, QHeaderView.ResizeMode.ResizeToContents)
treeHeader.setSectionResizeMode(self.C_EXTRA, QHeaderView.ResizeMode.ResizeToContents)
treeHeader.setSectionResizeMode(self.C_MORE, QHeaderView.ResizeMode.ResizeToContents)

# Pre-Generate Tree Formatting
fH1 = self.font()
Expand Down Expand Up @@ -455,14 +449,14 @@ def initSettings(self) -> None:
"""Set or update tree widget settings."""
# Scroll bars
if CONFIG.hideVScroll:
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
else:
self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)

if CONFIG.hideHScroll:
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
else:
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)

return

Expand Down Expand Up @@ -522,21 +516,16 @@ def refreshTree(self, rootHandle: str | None = None, overRide: bool = False) ->

def refreshHandle(self, tHandle: str) -> None:
"""Refresh the data for a given handle."""
idxData = SHARED.project.index.getItemData(tHandle)
if idxData is None:
return

logger.debug("Refreshing meta data for item '%s'", tHandle)
for sTitle, tHeading in idxData.items():
sKey = f"{tHandle}:{sTitle}"
trItem = self._treeMap.get(sKey, None)
if trItem is None:
logger.debug("Heading '%s' not in novel tree", sKey)
self.refreshTree()
return

self._updateTreeItemValues(trItem, tHeading, tHandle, sTitle)

if idxData := SHARED.project.index.getItemData(tHandle):
logger.debug("Refreshing meta data for item '%s'", tHandle)
for sTitle, tHeading in idxData.items():
sKey = f"{tHandle}:{sTitle}"
if trItem := self._treeMap.get(sKey, None):
self._updateTreeItemValues(trItem, tHeading, tHandle, sTitle)
else:
logger.debug("Heading '%s' not in novel tree", sKey)
self.refreshTree()
return
return

def getSelectedHandle(self) -> tuple[str | None, str | None]:
Expand Down Expand Up @@ -567,27 +556,25 @@ def setLastColSize(self, colSize: int) -> None:
self._lastColSize = minmax(colSize, 15, 75)/100.0
return

def setActiveHandle(self, tHandle: str | None) -> None:
def setActiveHandle(self, tHandle: str | None, doScroll: bool = False) -> None:
"""Highlight the rows associated with a given handle."""
tStart = time()

didScroll = False
self._actHandle = tHandle
for i in range(self.topLevelItemCount()):
tItem = self.topLevelItem(i)
if tItem is not None:
if tItem := self.topLevelItem(i):
if tItem.data(self.C_DATA, self.D_HANDLE) == tHandle:
tItem.setBackground(self.C_TITLE, self.palette().alternateBase())
tItem.setBackground(self.C_WORDS, self.palette().alternateBase())
tItem.setBackground(self.C_EXTRA, self.palette().alternateBase())
tItem.setBackground(self.C_MORE, self.palette().alternateBase())
if doScroll and not didScroll:
self.scrollToItem(tItem, QAbstractItemView.ScrollHint.PositionAtCenter)
didScroll = True
else:
tItem.setBackground(self.C_TITLE, self.palette().base())
tItem.setBackground(self.C_WORDS, self.palette().base())
tItem.setBackground(self.C_EXTRA, self.palette().base())
tItem.setBackground(self.C_MORE, self.palette().base())

logger.debug("Highlighted Novel Tree in %.3f ms", (time() - tStart)*1000)

return

##
Expand All @@ -601,12 +588,12 @@ def mousePressEvent(self, event: QMouseEvent) -> None:
"""
super().mousePressEvent(event)

if event.button() == Qt.LeftButton:
if event.button() == Qt.MouseButton.LeftButton:
selItem = self.indexAt(event.pos())
if not selItem.isValid():
self.clearSelection()

elif event.button() == Qt.MiddleButton:
elif event.button() == Qt.MouseButton.MiddleButton:
selItem = self.itemAt(event.pos())
if not isinstance(selItem, QTreeWidgetItem):
return
Expand Down Expand Up @@ -637,7 +624,10 @@ def resizeEvent(self, event: QResizeEvent) -> None:
trItem = self.topLevelItem(i)
if isinstance(trItem, QTreeWidgetItem):
lastText = trItem.data(self.C_DATA, self.D_EXTRA)
trItem.setText(self.C_EXTRA, fMetric.elidedText(lastText, Qt.ElideRight, eliW))
trItem.setText(
self.C_EXTRA,
fMetric.elidedText(lastText, Qt.TextElideMode.ElideRight, eliW)
)
return

##
Expand Down Expand Up @@ -693,7 +683,7 @@ def _populateTree(self, rootHandle: str | None) -> None:
newItem.setData(self.C_DATA, self.D_HANDLE, tHandle)
newItem.setData(self.C_DATA, self.D_TITLE, sTitle)
newItem.setData(self.C_DATA, self.D_KEY, tKey)
newItem.setTextAlignment(self.C_WORDS, Qt.AlignRight)
newItem.setTextAlignment(self.C_WORDS, Qt.AlignmentFlag.AlignRight)

self._updateTreeItemValues(newItem, novIdx, tHandle, sTitle)
self._treeMap[tKey] = newItem
Expand All @@ -712,16 +702,16 @@ def _updateTreeItemValues(self, trItem: QTreeWidgetItem, idxItem: IndexHeading,
iLevel = nwHeaders.H_LEVEL.get(idxItem.level, 0)
hDec = SHARED.theme.getHeaderDecoration(iLevel)

trItem.setData(self.C_TITLE, Qt.DecorationRole, hDec)
trItem.setData(self.C_TITLE, Qt.ItemDataRole.DecorationRole, hDec)
trItem.setText(self.C_TITLE, idxItem.title)
trItem.setFont(self.C_TITLE, self._hFonts[iLevel])
trItem.setText(self.C_WORDS, f"{idxItem.wordCount:n}")
trItem.setData(self.C_MORE, Qt.DecorationRole, self._pMore)
trItem.setData(self.C_MORE, Qt.ItemDataRole.DecorationRole, self._pMore)

# Custom column
mW = int(self._lastColSize * self.viewport().width())
lastText, toolTip = self._getLastColumnText(tHandle, sTitle)
elideText = self.fontMetrics().elidedText(lastText, Qt.ElideRight, mW)
elideText = self.fontMetrics().elidedText(lastText, Qt.TextElideMode.ElideRight, mW)
trItem.setText(self.C_EXTRA, elideText)
trItem.setData(self.C_DATA, self.D_EXTRA, lastText)
trItem.setToolTip(self.C_EXTRA, toolTip)
Expand Down
2 changes: 1 addition & 1 deletion novelwriter/guimain.py
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ def openDocument(self, tHandle: str | None, tLine: int | None = None,
if self.docEditor.loadText(tHandle, tLine):
SHARED.project.data.setLastHandle(tHandle, "editor")
self.projView.setSelectedHandle(tHandle, doScroll=doScroll)
self.novelView.setActiveHandle(tHandle)
self.novelView.setActiveHandle(tHandle, doScroll=doScroll)
if changeFocus:
self.docEditor.setFocus()
else:
Expand Down
24 changes: 22 additions & 2 deletions tests/test_gui/test_gui_noveltree.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@
from tools import C, buildTestProject

from PyQt5.QtGui import QFocusEvent
from PyQt5.QtCore import Qt, QEvent
from PyQt5.QtCore import QPoint, Qt, QEvent
from PyQt5.QtWidgets import QInputDialog, QToolTip

from novelwriter import CONFIG, SHARED
from novelwriter.enum import nwWidget, nwItemType
from novelwriter.gui.noveltree import NovelTreeColumn
from novelwriter.gui.noveltree import GuiNovelTree, NovelTreeColumn
from novelwriter.dialogs.editlabel import GuiEditLabel


Expand Down Expand Up @@ -192,12 +192,32 @@ def showText(pos, text):
mIndex = novelTree.model().index(2, novelTree.C_MORE)
with monkeypatch.context() as mp:
mp.setattr(QToolTip, "showText", showText)

ttText = ""
novelTree._treeItemClicked(mIndex)
assert ttText == (
"<p><b>Point of View</b>: Jane<br><b>Focus</b>: Jane</p>"
"<p><b>Synopsis</b>: This is a scene.</p>"
)

ttText = ""
novelTree._popMetaBox(QPoint(1, 1), C.hInvalid, "T0001")
assert ttText == ""

# Set Default Root
# ================
SHARED.project.data.setLastHandle(C.hInvalid, "novelTree")
novelView.openProjectTasks()
assert novelBar.novelValue.handle == C.hNovelRoot

# Tree Focus
# ==========
with monkeypatch.context() as mp:
mp.setattr(GuiNovelTree, "hasFocus", lambda *a: False)
assert novelView.treeHasFocus() is False
mp.setattr(GuiNovelTree, "hasFocus", lambda *a: True)
assert novelView.treeHasFocus() is True

# Other Checks
# ============

Expand Down

0 comments on commit 78a75d5

Please sign in to comment.