Skip to content

Commit

Permalink
Fix issues with novel tree last column (#1355)
Browse files Browse the repository at this point in the history
  • Loading branch information
vkbo authored Feb 10, 2023
2 parents 032ab63 + 7fe85dd commit 917a437
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 44 deletions.
75 changes: 43 additions & 32 deletions i18n/nw_base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -757,114 +757,114 @@
<context>
<name>GuiDocEditFooter</name>
<message>
<location filename="../novelwriter/gui/doceditor.py" line="2924" />
<location filename="../novelwriter/gui/doceditor.py" line="2931" />
<source>Status</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/doceditor.py" line="3073" />
<location filename="../novelwriter/gui/doceditor.py" line="3080" />
<source>Line: {0} ({1})</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/doceditor.py" line="3102" />
<location filename="../novelwriter/gui/doceditor.py" line="3109" />
<source>Words: {0} ({1})</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/doceditor.py" line="3107" />
<location filename="../novelwriter/gui/doceditor.py" line="3114" />
<source>Document size is {0} bytes</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/doceditor.py" line="3119" />
<location filename="../novelwriter/gui/doceditor.py" line="3126" />
<source>Words: {0} selected</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/doceditor.py" line="3122" />
<location filename="../novelwriter/gui/doceditor.py" line="3129" />
<source>Character count: {0}</source>
<translation type="unfinished" />
</message>
</context>
<context>
<name>GuiDocEditHeader</name>
<message>
<location filename="../novelwriter/gui/doceditor.py" line="2694" />
<location filename="../novelwriter/gui/doceditor.py" line="2701" />
<source>Edit document label</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/doceditor.py" line="2703" />
<location filename="../novelwriter/gui/doceditor.py" line="2710" />
<source>Search document</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/doceditor.py" line="2712" />
<location filename="../novelwriter/gui/doceditor.py" line="2719" />
<source>Toggle Focus Mode</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/doceditor.py" line="2721" />
<location filename="../novelwriter/gui/doceditor.py" line="2728" />
<source>Close the document</source>
<translation type="unfinished" />
</message>
</context>
<context>
<name>GuiDocEditSearch</name>
<message>
<location filename="../novelwriter/gui/doceditor.py" line="2287" />
<location filename="../novelwriter/gui/doceditor.py" line="2274" />
<location filename="../novelwriter/gui/doceditor.py" line="2294" />
<location filename="../novelwriter/gui/doceditor.py" line="2281" />
<source>Search</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/doceditor.py" line="2279" />
<location filename="../novelwriter/gui/doceditor.py" line="2286" />
<source>Replace</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/doceditor.py" line="2295" />
<location filename="../novelwriter/gui/doceditor.py" line="2302" />
<source>Case Sensitive</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/doceditor.py" line="2301" />
<location filename="../novelwriter/gui/doceditor.py" line="2308" />
<source>Whole Words Only</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/doceditor.py" line="2307" />
<location filename="../novelwriter/gui/doceditor.py" line="2314" />
<source>RegEx Mode</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/doceditor.py" line="2313" />
<location filename="../novelwriter/gui/doceditor.py" line="2320" />
<source>Loop Search</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/doceditor.py" line="2319" />
<location filename="../novelwriter/gui/doceditor.py" line="2326" />
<source>Search Next File</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/doceditor.py" line="2327" />
<location filename="../novelwriter/gui/doceditor.py" line="2334" />
<source>Preserve Case</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/doceditor.py" line="2335" />
<location filename="../novelwriter/gui/doceditor.py" line="2342" />
<source>Close Search</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/doceditor.py" line="2351" />
<location filename="../novelwriter/gui/doceditor.py" line="2358" />
<source>Find in current document</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/doceditor.py" line="2356" />
<location filename="../novelwriter/gui/doceditor.py" line="2363" />
<source>Find and replace in current document</source>
<translation type="unfinished" />
</message>
Expand Down Expand Up @@ -2050,55 +2050,66 @@
<context>
<name>GuiNovelToolBar</name>
<message>
<location filename="../novelwriter/gui/noveltree.py" line="207" />
<location filename="../novelwriter/gui/noveltree.py" line="216" />
<source>Outline of {0}</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/noveltree.py" line="215" />
<location filename="../novelwriter/gui/noveltree.py" line="224" />
<source>Novel Root</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/noveltree.py" line="221" />
<location filename="../novelwriter/gui/noveltree.py" line="230" />
<source>Refresh</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/noveltree.py" line="228" />
<location filename="../novelwriter/gui/noveltree.py" line="237" />
<source>Last Column</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/noveltree.py" line="231" />
<location filename="../novelwriter/gui/noveltree.py" line="240" />
<source>Hidden</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/noveltree.py" line="232" />
<location filename="../novelwriter/gui/noveltree.py" line="241" />
<source>Point of View Character</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/noveltree.py" line="233" />
<location filename="../novelwriter/gui/noveltree.py" line="242" />
<source>Focus Character</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/noveltree.py" line="234" />
<location filename="../novelwriter/gui/noveltree.py" line="243" />
<source>Novel Plot</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/noveltree.py" line="237" />
<location filename="../novelwriter/gui/noveltree.py" line="361" />
<location filename="../novelwriter/gui/noveltree.py" line="246" />
<source>Column Size</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/noveltree.py" line="250" />
<source>More Options</source>
<translation type="unfinished" />
</message>
<message>
<location filename="../novelwriter/gui/noveltree.py" line="361" />
<source>Maximum column size in %</source>
<translation type="unfinished" />
</message>
</context>
<context>
<name>GuiNovelTree</name>
<message>
<location filename="../novelwriter/gui/noveltree.py" line="778" />
<location filename="../novelwriter/gui/noveltree.py" line="815" />
<source>No meta data</source>
<translation type="unfinished" />
</message>
Expand Down
2 changes: 1 addition & 1 deletion novelwriter/core/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"widthCol3", "widthCol4", "wordsPerPage", "countFrom", "clearDouble",
},
"GuiWordList": {"winWidth", "winHeight"},
"GuiNovelView": {"lastCol"},
"GuiNovelView": {"lastCol", "lastColSize"},
}


Expand Down
57 changes: 47 additions & 10 deletions novelwriter/gui/noveltree.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,13 @@
from PyQt5.QtGui import QFont, QPalette
from PyQt5.QtCore import Qt, QSize, pyqtSlot, pyqtSignal
from PyQt5.QtWidgets import (
QAbstractItemView, QActionGroup, QFrame, QHBoxLayout, QHeaderView, QMenu,
QSizePolicy, QToolButton, QToolTip, QTreeWidget, QTreeWidgetItem,
QVBoxLayout, QWidget
QAbstractItemView, QActionGroup, QFrame, QHBoxLayout, QHeaderView,
QInputDialog, QMenu, QSizePolicy, QToolButton, QToolTip, QTreeWidget,
QTreeWidgetItem, QVBoxLayout, QWidget
)

from novelwriter.enum import nwDocMode, nwItemClass, nwOutline
from novelwriter.common import minmax
from novelwriter.constants import nwHeaders, nwKeyWords, nwLabels, trConst
from novelwriter.gui.components import NovelSelector

Expand Down Expand Up @@ -126,20 +127,28 @@ def openProjectTasks(self):
lastCol = self.theProject.options.getEnum(
"GuiNovelView", "lastCol", NovelTreeColumn, NovelTreeColumn.HIDDEN
)
lastColSize = self.theProject.options.getInt(
"GuiNovelView", "lastColSize", 25
)

self.clearProject()

self.novelBar.buildNovelRootMenu()
self.novelBar.setLastColType(lastCol, doRefresh=False)
self.novelBar.setCurrentRoot(lastNovel)
self.novelBar.setEnabled(True)

self.novelTree.setLastColSize(lastColSize)

return

def closeProjectTasks(self):
"""Run closing project tasks.
"""
lastColType = self.novelTree.lastColType
lastColSize = self.novelTree.lastColSize
self.theProject.options.setValue("GuiNovelView", "lastCol", lastColType)
self.theProject.options.setValue("GuiNovelView", "lastColSize", lastColSize)
return

def setTreeFocus(self):
Expand Down Expand Up @@ -233,6 +242,10 @@ def __init__(self, novelView):
self._addLastColAction(NovelTreeColumn.FOCUS, self.tr("Focus Character"))
self._addLastColAction(NovelTreeColumn.PLOT, self.tr("Novel Plot"))

self.mLastCol.addSeparator()
self.aLastColSize = self.mLastCol.addAction(self.tr("Column Size"))
self.aLastColSize.triggered.connect(self._selectLastColumnSize)

self.tbMore = QToolButton(self)
self.tbMore.setToolTip(self.tr("More Options"))
self.tbMore.setIconSize(QSize(iPx, iPx))
Expand Down Expand Up @@ -339,6 +352,19 @@ def _refreshNovelTree(self):
self.novelView.novelTree.refreshTree(rootHandle=rootHandle, overRide=True)
return

@pyqtSlot()
def _selectLastColumnSize(self):
"""Set the maximum width for the last column.
"""
oldSize = self.novelView.novelTree.lastColSize
newSize, isOk = QInputDialog.getInt(
self, self.tr("Column Size"), self.tr("Maximum column size in %"), oldSize, 15, 75, 5
)
if isOk:
self.novelView.novelTree.setLastColSize(newSize)
self._refreshNovelTree()
return

##
# Internal Functions
##
Expand Down Expand Up @@ -379,10 +405,11 @@ def __init__(self, novelView):
self.theProject = novelView.mainGui.theProject

# Internal Variables
self._treeMap = {}
self._lastBuild = 0
self._lastCol = NovelTreeColumn.POV
self._actHandle = None
self._treeMap = {}
self._lastBuild = 0
self._lastCol = NovelTreeColumn.POV
self._lastColSize = 0.25
self._actHandle = None

# Cached Strings
self._povLabel = trConst(nwLabels.KEY_NAME[nwKeyWords.POV_KEY])
Expand Down Expand Up @@ -470,6 +497,10 @@ def updateTheme(self):
def lastColType(self):
return self._lastCol

@property
def lastColSize(self):
return int(self._lastColSize * 100)

##
# Class Methods
##
Expand Down Expand Up @@ -552,6 +583,12 @@ def setLastColType(self, colType, doRefresh=True):
self.refreshTree(rootHandle=lastNovel, overRide=True)
return

def setLastColSize(self, colSize):
"""Set the column size in integer values between 15 and 75.
"""
self._lastColSize = minmax(colSize, 15, 75)/100.0
return

def setActiveHandle(self, tHandle):
"""Highlight the rows associated with a given handle.
"""
Expand Down Expand Up @@ -619,7 +656,7 @@ def resizeEvent(self, event):
newW = event.size().width()
oldW = event.oldSize().width()
if newW != oldW:
eliW = int(0.25 * newW)
eliW = int(self._lastColSize * newW)
fMetric = self.fontMetrics()
for i in range(self.topLevelItemCount()):
trItem = self.topLevelItem(i)
Expand Down Expand Up @@ -709,7 +746,7 @@ def _updateTreeItemValues(self, trItem, idxItem, tHandle, sTitle):
trItem.setData(self.C_MORE, Qt.DecorationRole, self._pMore)

# Custom column
mW = int(0.25 * self.viewport().width())
mW = int(self._lastColSize * self.viewport().width())
lastText, toolTip = self._getLastColumnText(tHandle, sTitle)
elideText = self.fontMetrics().elidedText(lastText, Qt.ElideRight, mW)
trItem.setText(self.C_EXTRA, elideText)
Expand Down Expand Up @@ -741,7 +778,7 @@ def _getLastColumnText(self, tHandle, sTitle):

if refData:
toolText = ", ".join(refData)
return refData[0], f"{refName}: {toolText}"
return toolText, f"{refName}: {toolText}"

return "", ""

Expand Down
9 changes: 8 additions & 1 deletion tests/test_gui/test_gui_noveltree.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

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

from novelwriter.enum import nwWidget, nwItemType
from novelwriter.gui.noveltree import NovelTreeColumn
Expand Down Expand Up @@ -82,6 +82,8 @@ def testGuiNovelTree_TreeItems(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
# Populate Tree
# =============

novelView.setTreeFocus()

nwGUI.projStack.setCurrentIndex(nwGUI.idxNovelView)
nwGUI.rebuildIndex()
novelTree._populateTree(rootHandle=None)
Expand Down Expand Up @@ -172,6 +174,11 @@ def testGuiNovelTree_TreeItems(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
spSize = nwGUI.splitMain.sizes()
nwGUI.splitMain.setSizes([spSize[0] + 10, spSize[1] - 10])

# Resize the last column
with monkeypatch.context() as mp:
mp.setattr(QInputDialog, "getInt", lambda *a, **k: (40, True))
novelBar._selectLastColumnSize()

# Item Meta
# =========

Expand Down

0 comments on commit 917a437

Please sign in to comment.