Rewrite index class to use sequential title keys rather than line numbers
This commit is contained in:
@@ -154,11 +154,11 @@ def isHandle(value):
|
||||
|
||||
|
||||
def isTitleTag(value):
|
||||
"""Check if a string is a valid title string.
|
||||
"""Check if a string is a valid title tag string.
|
||||
"""
|
||||
if not isinstance(value, str):
|
||||
return False
|
||||
if len(value) != 7:
|
||||
if len(value) != 5:
|
||||
return False
|
||||
if not value.startswith("T"):
|
||||
return False
|
||||
|
||||
@@ -61,7 +61,6 @@ class nwHeaders:
|
||||
|
||||
H_VALID = ("H0", "H1", "H2", "H3", "H4")
|
||||
H_LEVEL = {"H0": 0, "H1": 1, "H2": 2, "H3": 3, "H4": 4}
|
||||
TT_NONE = "T000000"
|
||||
|
||||
# END Class nwHeaders
|
||||
|
||||
|
||||
+82
-53
@@ -41,6 +41,8 @@ from novelwriter.common import (
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
TT_NONE = "T0000"
|
||||
|
||||
|
||||
class NWIndex:
|
||||
"""This class holds the entire index for a given project. The index
|
||||
@@ -281,50 +283,58 @@ class NWIndex:
|
||||
def _scanActive(self, tHandle, theItem, theText, itemTags):
|
||||
"""Scan an active document for meta data.
|
||||
"""
|
||||
nTitle = 0
|
||||
findHeader = True
|
||||
theLines = theText.splitlines()
|
||||
nTitle = 0 # Line Number of the previous title
|
||||
cTitle = TT_NONE # Tag of the current title
|
||||
pTitle = TT_NONE # Tag of the previous title
|
||||
firstHeader = True # First header has been seen
|
||||
|
||||
theLines = theText.splitlines()
|
||||
for nLine, aLine in enumerate(theLines, start=1):
|
||||
|
||||
if len(aLine.strip()) == 0:
|
||||
if aLine.strip() == "":
|
||||
continue
|
||||
|
||||
if aLine.startswith("#"):
|
||||
if findHeader:
|
||||
hDepth, _ = self._splitHeading(aLine)
|
||||
if hDepth != "H0":
|
||||
theItem.setMainHeading(hDepth)
|
||||
findHeader = False
|
||||
hDepth, hText = self._splitHeading(aLine)
|
||||
if hDepth == "H0":
|
||||
continue
|
||||
|
||||
isTitle = self._indexTitle(tHandle, aLine, nLine)
|
||||
if isTitle and nLine > 0:
|
||||
if firstHeader:
|
||||
theItem.setMainHeading(hDepth)
|
||||
firstHeader = False
|
||||
|
||||
cTitle = self._itemIndex.addItemHeading(tHandle, nLine, hDepth, hText)
|
||||
if cTitle != TT_NONE:
|
||||
if nTitle > 0:
|
||||
# We have a new title, so we need to count the words of the previous one
|
||||
lastText = "\n".join(theLines[nTitle-1:nLine-1])
|
||||
self._indexWordCounts(tHandle, lastText, nTitle)
|
||||
self._indexWordCounts(tHandle, lastText, pTitle)
|
||||
nTitle = nLine
|
||||
pTitle = cTitle
|
||||
|
||||
elif aLine.startswith("@"):
|
||||
self._indexKeyword(tHandle, aLine, nTitle, theItem.itemClass, itemTags)
|
||||
if cTitle != TT_NONE:
|
||||
self._indexKeyword(tHandle, aLine, cTitle, theItem.itemClass, itemTags)
|
||||
|
||||
elif aLine.startswith("%"):
|
||||
if nTitle > 0:
|
||||
if cTitle != TT_NONE:
|
||||
toCheck = aLine[1:].lstrip()
|
||||
synTag = toCheck[:9].lower()
|
||||
tLen = len(aLine)
|
||||
cLen = len(toCheck)
|
||||
cOff = tLen - cLen
|
||||
if synTag == "synopsis:":
|
||||
self._indexSynopsis(tHandle, aLine[cOff+9:].strip(), nTitle)
|
||||
sText = aLine[cOff+9:].strip()
|
||||
self._itemIndex.setHeadingSynopsis(tHandle, cTitle, sText)
|
||||
|
||||
# Count words for remaining text after last heading
|
||||
if nTitle > 0:
|
||||
if pTitle != TT_NONE:
|
||||
lastText = "\n".join(theLines[nTitle-1:])
|
||||
self._indexWordCounts(tHandle, lastText, nTitle)
|
||||
self._indexWordCounts(tHandle, lastText, pTitle)
|
||||
|
||||
# Also count words on a page with no titles
|
||||
if nTitle == 0:
|
||||
self._indexWordCounts(tHandle, theText, nTitle)
|
||||
if cTitle == TT_NONE:
|
||||
self._indexWordCounts(tHandle, theText, cTitle)
|
||||
|
||||
# Prune no longer used tags
|
||||
for tTag, isActive in itemTags.items():
|
||||
@@ -362,34 +372,14 @@ class NWIndex:
|
||||
return "H2", aLine[4:].strip()
|
||||
return "H0", ""
|
||||
|
||||
def _indexTitle(self, tHandle, aLine, nTitle):
|
||||
"""Save information about the title and its location in the
|
||||
file to the index.
|
||||
"""
|
||||
hDepth, hText = self._splitHeading(aLine)
|
||||
if hDepth == "H0":
|
||||
return False
|
||||
|
||||
sTitle = f"T{nTitle:06d}"
|
||||
self._itemIndex.addItemHeading(tHandle, sTitle, hDepth, hText)
|
||||
return True
|
||||
|
||||
def _indexWordCounts(self, tHandle, theText, nTitle):
|
||||
def _indexWordCounts(self, tHandle, theText, sTitle):
|
||||
"""Count text stats and save the counts to the index.
|
||||
"""
|
||||
sTitle = f"T{nTitle:06d}"
|
||||
cC, wC, pC = countWords(theText)
|
||||
self._itemIndex.setHeadingCounts(tHandle, sTitle, cC, wC, pC)
|
||||
self._itemIndex.setHeadingCounts(tHandle, sTitle, cC, wC, pC)
|
||||
return
|
||||
|
||||
def _indexSynopsis(self, tHandle, theText, nTitle):
|
||||
"""Save the synopsis to the index.
|
||||
"""
|
||||
sTitle = f"T{nTitle:06d}"
|
||||
self._itemIndex.setHeadingSynopsis(tHandle, sTitle, theText)
|
||||
return
|
||||
|
||||
def _indexKeyword(self, tHandle, aLine, nTitle, itemClass, itemTags):
|
||||
def _indexKeyword(self, tHandle, aLine, sTitle, itemClass, itemTags):
|
||||
"""Validate and save the information about a reference to a tag
|
||||
in another file, or the setting of a tag in the file. A record
|
||||
of active tags is updated so that no longer used tags can be
|
||||
@@ -404,7 +394,6 @@ class NWIndex:
|
||||
logger.warning("Skipping invalid keyword '%s' in '%s'", theBits[0], tHandle)
|
||||
return
|
||||
|
||||
sTitle = f"T{nTitle:06d}"
|
||||
if theBits[0] == nwKeyWords.TAG_KEY:
|
||||
tagName = theBits[1]
|
||||
self._tagsIndex.add(tagName, tHandle, sTitle, itemClass)
|
||||
@@ -506,6 +495,14 @@ class NWIndex:
|
||||
"""
|
||||
return self._itemIndex[tHandle]
|
||||
|
||||
def getItemHeader(self, tHandle, sTitle):
|
||||
"""Get the header entry for a specific item and heading.
|
||||
"""
|
||||
tItem = self._itemIndex[tHandle]
|
||||
if isinstance(tItem, IndexItem):
|
||||
return tItem[sTitle]
|
||||
return None
|
||||
|
||||
def getNovelWordCount(self, skipExcl=True):
|
||||
"""Count the number of words in the novel project.
|
||||
"""
|
||||
@@ -649,6 +646,8 @@ class TagsIndex:
|
||||
control of the keys.
|
||||
"""
|
||||
|
||||
__slots__ = ("_tags")
|
||||
|
||||
def __init__(self):
|
||||
self._tags = {}
|
||||
return
|
||||
@@ -695,7 +694,7 @@ class TagsIndex:
|
||||
def tagHeading(self, tagKey):
|
||||
"""Get the heading of a given tag.
|
||||
"""
|
||||
return self._tags.get(tagKey, {}).get("heading", nwHeaders.TT_NONE)
|
||||
return self._tags.get(tagKey, {}).get("heading", TT_NONE)
|
||||
|
||||
def tagClass(self, tagKey):
|
||||
"""Get the class of a given tag.
|
||||
@@ -754,6 +753,8 @@ class ItemIndex:
|
||||
IndexHeading object for each header of the text.
|
||||
"""
|
||||
|
||||
__slots__ = ("_project", "_items")
|
||||
|
||||
def __init__(self, project):
|
||||
self._project = project
|
||||
self._items = {}
|
||||
@@ -844,13 +845,15 @@ class ItemIndex:
|
||||
# Setters
|
||||
##
|
||||
|
||||
def addItemHeading(self, tHandle, sTitle, hDepth, hText):
|
||||
"""Set the main heading level of an item.
|
||||
def addItemHeading(self, tHandle, lineNo, hDepth, hText):
|
||||
"""Add a heading to an item.
|
||||
"""
|
||||
if tHandle in self._items:
|
||||
tItem = self._items[tHandle]
|
||||
tItem.addHeading(IndexHeading(sTitle, hDepth, hText))
|
||||
return
|
||||
sTitle = tItem.nextHeading()
|
||||
tItem.addHeading(IndexHeading(sTitle, lineNo, hDepth, hText))
|
||||
return sTitle
|
||||
return TT_NONE
|
||||
|
||||
def setHeadingCounts(self, tHandle, sTitle, cC, wC, pC):
|
||||
"""Set the character, word and paragraph counts of a heading
|
||||
@@ -921,14 +924,16 @@ class IndexItem:
|
||||
must be reset each time the item is re-indexed.
|
||||
"""
|
||||
|
||||
__slots__ = ("_handle", "_item", "_headings", "_headings", "_count")
|
||||
|
||||
def __init__(self, tHandle, tItem):
|
||||
self._handle = tHandle
|
||||
self._item = tItem
|
||||
self._headings = {}
|
||||
self._index = 0
|
||||
self._count = 0
|
||||
|
||||
# Add a placeholder heading
|
||||
self._headings[nwHeaders.TT_NONE] = IndexHeading(nwHeaders.TT_NONE)
|
||||
self._headings[TT_NONE] = IndexHeading(TT_NONE)
|
||||
|
||||
return
|
||||
|
||||
@@ -951,8 +956,8 @@ class IndexItem:
|
||||
"""Add a heading to the item. Also remove the placeholder entry
|
||||
if it exists.
|
||||
"""
|
||||
if nwHeaders.TT_NONE in self._headings:
|
||||
self._headings.pop(nwHeaders.TT_NONE)
|
||||
if TT_NONE in self._headings:
|
||||
self._headings.pop(TT_NONE)
|
||||
self._headings[tHeading.key] = tHeading
|
||||
return
|
||||
|
||||
@@ -1011,6 +1016,12 @@ class IndexItem:
|
||||
tags.append(tag)
|
||||
return tags
|
||||
|
||||
def nextHeading(self):
|
||||
"""Return the next heading key to be used.
|
||||
"""
|
||||
self._count += 1
|
||||
return f"T{self._count:04d}"
|
||||
|
||||
##
|
||||
# Pack/Unpack
|
||||
##
|
||||
@@ -1056,8 +1067,14 @@ class IndexHeading:
|
||||
of all references made under each heading.
|
||||
"""
|
||||
|
||||
def __init__(self, key, level="H0", title=""):
|
||||
__slots__ = (
|
||||
"_key", "_line", "_level", "_title", "_charCount", "_wordCount",
|
||||
"_paraCount", "_synopsis", "_tag", "_refs",
|
||||
)
|
||||
|
||||
def __init__(self, key, line=0, level="H0", title=""):
|
||||
self._key = key
|
||||
self._line = line
|
||||
self._level = level
|
||||
self._title = title
|
||||
|
||||
@@ -1082,6 +1099,10 @@ class IndexHeading:
|
||||
def key(self):
|
||||
return self._key
|
||||
|
||||
@property
|
||||
def line(self):
|
||||
return self._line
|
||||
|
||||
@property
|
||||
def level(self):
|
||||
return self._level
|
||||
@@ -1125,6 +1146,12 @@ class IndexHeading:
|
||||
self._level = level
|
||||
return
|
||||
|
||||
def setLine(self, line):
|
||||
"""Set the line number of a heading.
|
||||
"""
|
||||
self._line = max(0, checkInt(line, 0))
|
||||
return
|
||||
|
||||
def setCounts(self, charCount, wordCount, paraCount):
|
||||
"""Set the character, word and paragraph count. Make sure the
|
||||
value is an integer and is not smaller than 0.
|
||||
@@ -1166,6 +1193,7 @@ class IndexHeading:
|
||||
return {
|
||||
"level": self._level,
|
||||
"title": self._title,
|
||||
"line": self._line,
|
||||
"tag": self._tag,
|
||||
"cCount": self._charCount,
|
||||
"wCount": self._wordCount,
|
||||
@@ -1187,6 +1215,7 @@ class IndexHeading:
|
||||
self.setLevel(data.get("level", "H0"))
|
||||
self._title = str(data.get("title", ""))
|
||||
self._tag = str(data.get("tag", ""))
|
||||
self.setLine(data.get("line", 0))
|
||||
self.setCounts(
|
||||
data.get("cCount", 0),
|
||||
data.get("wCount", 0),
|
||||
|
||||
@@ -40,7 +40,6 @@ from PyQt5.QtWidgets import (
|
||||
)
|
||||
|
||||
from novelwriter.enum import nwDocMode, nwItemClass, nwOutline
|
||||
from novelwriter.common import checkInt
|
||||
from novelwriter.constants import nwHeaders, nwKeyWords, nwLabels, trConst
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -60,7 +59,7 @@ class GuiNovelView(QWidget):
|
||||
|
||||
# Signals for user interaction with the novel tree
|
||||
selectedItemChanged = pyqtSignal(str)
|
||||
openDocumentRequest = pyqtSignal(str, Enum, int, str)
|
||||
openDocumentRequest = pyqtSignal(str, Enum, str)
|
||||
|
||||
def __init__(self, mainGui):
|
||||
super().__init__(parent=mainGui)
|
||||
@@ -543,14 +542,11 @@ class GuiNovelTree(QTreeWidget):
|
||||
selected, return the first.
|
||||
"""
|
||||
selItem = self.selectedItems()
|
||||
tHandle = None
|
||||
tLine = 0
|
||||
if selItem:
|
||||
tHandle = selItem[0].data(self.C_TITLE, self.D_HANDLE)
|
||||
sTitle = selItem[0].data(self.C_TITLE, self.D_TITLE)
|
||||
tLine = checkInt(sTitle[1:], 1) - 1
|
||||
|
||||
return tHandle, tLine
|
||||
return tHandle, sTitle
|
||||
return None, None
|
||||
|
||||
def setLastColType(self, colType, doRefresh=True):
|
||||
"""Change the content type of the last column and rebuild.
|
||||
@@ -609,11 +605,11 @@ class GuiNovelTree(QTreeWidget):
|
||||
if not isinstance(selItem, QTreeWidgetItem):
|
||||
return
|
||||
|
||||
tHandle, _ = self.getSelectedHandle()
|
||||
tHandle, sTitle = self.getSelectedHandle()
|
||||
if tHandle is None:
|
||||
return
|
||||
|
||||
self.novelView.openDocumentRequest.emit(tHandle, nwDocMode.VIEW, -1, "")
|
||||
self.novelView.openDocumentRequest.emit(tHandle, nwDocMode.VIEW, sTitle or "")
|
||||
|
||||
return
|
||||
|
||||
@@ -655,8 +651,8 @@ class GuiNovelTree(QTreeWidget):
|
||||
clicked, and send it to the main gui class for opening in the
|
||||
document editor.
|
||||
"""
|
||||
tHandle, tLine = self.getSelectedHandle()
|
||||
self.novelView.openDocumentRequest.emit(tHandle, nwDocMode.EDIT, tLine, "")
|
||||
tHandle, sTitle = self.getSelectedHandle()
|
||||
self.novelView.openDocumentRequest.emit(tHandle, nwDocMode.EDIT, sTitle or "")
|
||||
return
|
||||
|
||||
##
|
||||
|
||||
+17
-16
@@ -55,6 +55,7 @@ logger = logging.getLogger(__name__)
|
||||
class GuiOutlineView(QWidget):
|
||||
|
||||
loadDocumentTagRequest = pyqtSignal(str, Enum)
|
||||
openDocumentRequest = pyqtSignal(str, Enum, str)
|
||||
|
||||
def __init__(self, mainGui):
|
||||
super().__init__(parent=mainGui)
|
||||
@@ -375,15 +376,16 @@ class GuiOutlineTree(QTreeWidget):
|
||||
hiddenStateChanged = pyqtSignal()
|
||||
activeItemChanged = pyqtSignal(str, str)
|
||||
|
||||
def __init__(self, theOutline):
|
||||
super().__init__(parent=theOutline)
|
||||
def __init__(self, outlineView):
|
||||
super().__init__(parent=outlineView)
|
||||
|
||||
logger.debug("Initialising GuiOutlineTree ...")
|
||||
|
||||
self.mainConf = novelwriter.CONFIG
|
||||
self.mainGui = theOutline.mainGui
|
||||
self.theProject = theOutline.mainGui.theProject
|
||||
self.mainTheme = theOutline.mainGui.mainTheme
|
||||
self.mainConf = novelwriter.CONFIG
|
||||
self.outlineView = outlineView
|
||||
self.mainGui = outlineView.mainGui
|
||||
self.theProject = outlineView.mainGui.theProject
|
||||
self.mainTheme = outlineView.mainGui.mainTheme
|
||||
|
||||
self.setUniformRowHeights(True)
|
||||
self.setFrameStyle(QFrame.NoFrame)
|
||||
@@ -524,13 +526,11 @@ class GuiOutlineTree(QTreeWidget):
|
||||
selected, return the first.
|
||||
"""
|
||||
selItem = self.selectedItems()
|
||||
tHandle = None
|
||||
tLine = 0
|
||||
if selItem:
|
||||
tHandle = selItem[0].data(self._colIdx[nwOutline.TITLE], self.D_HANDLE)
|
||||
tLine = checkInt(selItem[0].text(self._colIdx[nwOutline.LINE]), 1) - 1
|
||||
|
||||
return tHandle, tLine
|
||||
sTitle = selItem[0].data(self._colIdx[nwOutline.TITLE], self.D_TITLE)
|
||||
return tHandle, sTitle
|
||||
return None, None
|
||||
|
||||
##
|
||||
# Slots
|
||||
@@ -542,8 +542,10 @@ class GuiOutlineTree(QTreeWidget):
|
||||
clicked, and send it to the main gui class for opening in the
|
||||
document editor.
|
||||
"""
|
||||
tHandle, tLine = self.getSelectedHandle()
|
||||
self.mainGui.openDocument(tHandle, tLine=tLine - 1, doScroll=True)
|
||||
tHandle, sTitle = self.getSelectedHandle()
|
||||
if tHandle is None:
|
||||
return
|
||||
self.outlineView.openDocumentRequest.emit(tHandle, nwDocMode.EDIT, sTitle or "")
|
||||
return
|
||||
|
||||
@pyqtSlot()
|
||||
@@ -554,9 +556,8 @@ class GuiOutlineTree(QTreeWidget):
|
||||
selItems = self.selectedItems()
|
||||
if selItems:
|
||||
tHandle = selItems[0].data(self._colIdx[nwOutline.TITLE], self.D_HANDLE)
|
||||
sTitle = selItems[0].data(self._colIdx[nwOutline.TITLE], self.D_TITLE)
|
||||
sTitle = selItems[0].data(self._colIdx[nwOutline.TITLE], self.D_TITLE)
|
||||
self.activeItemChanged.emit(tHandle, sTitle)
|
||||
|
||||
return
|
||||
|
||||
@pyqtSlot(int, int, int)
|
||||
@@ -718,7 +719,7 @@ class GuiOutlineTree(QTreeWidget):
|
||||
trItem.setText(self._colIdx[nwOutline.LEVEL], novIdx.level)
|
||||
trItem.setIcon(self._colIdx[nwOutline.LABEL], self._dIcon[nwItem.mainHeading])
|
||||
trItem.setText(self._colIdx[nwOutline.LABEL], nwItem.itemName)
|
||||
trItem.setText(self._colIdx[nwOutline.LINE], sTitle[1:].lstrip("0"))
|
||||
trItem.setText(self._colIdx[nwOutline.LINE], f"{novIdx.line:n}")
|
||||
trItem.setText(self._colIdx[nwOutline.SYNOP], novIdx.synopsis)
|
||||
trItem.setText(self._colIdx[nwOutline.CCOUNT], f"{novIdx.charCount:n}")
|
||||
trItem.setText(self._colIdx[nwOutline.WCOUNT], f"{novIdx.wordCount:n}")
|
||||
|
||||
@@ -60,7 +60,7 @@ class GuiProjectView(QWidget):
|
||||
|
||||
# Signals for user interaction with the project tree
|
||||
selectedItemChanged = pyqtSignal(str)
|
||||
openDocumentRequest = pyqtSignal(str, Enum, int, str)
|
||||
openDocumentRequest = pyqtSignal(str, Enum, str)
|
||||
|
||||
# Requests for the main GUI
|
||||
projectSettingsRequest = pyqtSignal(int)
|
||||
@@ -1144,7 +1144,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
return
|
||||
|
||||
if tItem.isFileType():
|
||||
self.projView.openDocumentRequest.emit(tHandle, nwDocMode.EDIT, -1, "")
|
||||
self.projView.openDocumentRequest.emit(tHandle, nwDocMode.EDIT, "")
|
||||
else:
|
||||
trItem.setExpanded(not trItem.isExpanded())
|
||||
|
||||
@@ -1190,11 +1190,11 @@ class GuiProjectTree(QTreeWidget):
|
||||
if isFile:
|
||||
aOpenDoc = ctxMenu.addAction(self.tr("Open Document"))
|
||||
aOpenDoc.triggered.connect(
|
||||
lambda: self.projView.openDocumentRequest.emit(tHandle, nwDocMode.EDIT, -1, "")
|
||||
lambda: self.projView.openDocumentRequest.emit(tHandle, nwDocMode.EDIT, "")
|
||||
)
|
||||
aViewDoc = ctxMenu.addAction(self.tr("View Document"))
|
||||
aViewDoc.triggered.connect(
|
||||
lambda: self.projView.openDocumentRequest.emit(tHandle, nwDocMode.VIEW, -1, "")
|
||||
lambda: self.projView.openDocumentRequest.emit(tHandle, nwDocMode.VIEW, "")
|
||||
)
|
||||
ctxMenu.addSeparator()
|
||||
|
||||
@@ -1324,7 +1324,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
return
|
||||
|
||||
if tItem.isFileType():
|
||||
self.projView.openDocumentRequest.emit(tHandle, nwDocMode.VIEW, -1, "")
|
||||
self.projView.openDocumentRequest.emit(tHandle, nwDocMode.VIEW, "")
|
||||
|
||||
return
|
||||
|
||||
|
||||
+20
-8
@@ -230,6 +230,7 @@ class GuiMain(QMainWindow):
|
||||
self.docViewer.loadDocumentTagRequest.connect(self._followTag)
|
||||
|
||||
self.outlineView.loadDocumentTagRequest.connect(self._followTag)
|
||||
self.outlineView.openDocumentRequest.connect(self._openDocument)
|
||||
|
||||
# Finalise Initialisation
|
||||
# =======================
|
||||
@@ -650,7 +651,7 @@ class GuiMain(QMainWindow):
|
||||
|
||||
return True
|
||||
|
||||
def viewDocument(self, tHandle=None, tAnchor=None):
|
||||
def viewDocument(self, tHandle=None, sTitle=None):
|
||||
"""Load a document for viewing in the view panel.
|
||||
"""
|
||||
if not self.hasProject:
|
||||
@@ -689,7 +690,8 @@ class GuiMain(QMainWindow):
|
||||
self.splitDocs.setSizes(vPos)
|
||||
self.viewMeta.setVisible(self.mainConf.showRefPanel)
|
||||
|
||||
self.docViewer.navigateTo(tAnchor)
|
||||
if sTitle:
|
||||
self.docViewer.navigateTo(f"#{sTitle}")
|
||||
|
||||
return True
|
||||
|
||||
@@ -777,17 +779,23 @@ class GuiMain(QMainWindow):
|
||||
return False
|
||||
|
||||
tHandle = None
|
||||
sTitle = None
|
||||
tLine = None
|
||||
if self.projView.treeHasFocus():
|
||||
tHandle = self.projView.getSelectedHandle()
|
||||
elif self.novelView.treeHasFocus():
|
||||
tHandle, tLine = self.novelView.getSelectedHandle()
|
||||
tHandle, sTitle = self.novelView.getSelectedHandle()
|
||||
elif self.outlineView.treeHasFocus():
|
||||
tHandle, tLine = self.outlineView.getSelectedHandle()
|
||||
tHandle, sTitle = self.outlineView.getSelectedHandle()
|
||||
else:
|
||||
logger.warning("No item selected")
|
||||
return False
|
||||
|
||||
if tHandle is not None and sTitle is not None:
|
||||
hItem = self.theProject.index.getItemHeader(tHandle, sTitle)
|
||||
if hItem is not None:
|
||||
tLine = hItem.line
|
||||
|
||||
if tHandle is not None:
|
||||
self.openDocument(tHandle, tLine=tLine, changeFocus=False, doScroll=False)
|
||||
|
||||
@@ -1473,18 +1481,22 @@ class GuiMain(QMainWindow):
|
||||
if tMode == nwDocMode.EDIT:
|
||||
self.openDocument(tHandle)
|
||||
elif tMode == nwDocMode.VIEW:
|
||||
self.viewDocument(tHandle=tHandle, tAnchor=f"#{sTitle}")
|
||||
self.viewDocument(tHandle=tHandle, sTitle=sTitle)
|
||||
return
|
||||
|
||||
@pyqtSlot(str, Enum, int, str)
|
||||
def _openDocument(self, tHandle, tMode, tLine, tAnchor):
|
||||
@pyqtSlot(str, Enum, str)
|
||||
def _openDocument(self, tHandle, tMode, sTitle):
|
||||
"""Handle an open document request from one of the tree views.
|
||||
"""
|
||||
if tHandle is not None:
|
||||
if tMode == nwDocMode.EDIT:
|
||||
tLine = None
|
||||
hItem = self.theProject.index.getItemHeader(tHandle, sTitle)
|
||||
if hItem is not None:
|
||||
tLine = hItem.line
|
||||
self.openDocument(tHandle, tLine=tLine, changeFocus=False)
|
||||
elif tMode == nwDocMode.VIEW:
|
||||
self.viewDocument(tHandle=tHandle, tAnchor=(tAnchor or None))
|
||||
self.viewDocument(tHandle=tHandle, sTitle=sTitle)
|
||||
return
|
||||
|
||||
@pyqtSlot(nwView)
|
||||
|
||||
Reference in New Issue
Block a user