Fix tag and auto-complete bugs (#2389)
This commit is contained in:
@@ -184,6 +184,10 @@ class nwKeyWords:
|
|||||||
POV_KEY, FOCUS_KEY, CHAR_KEY, PLOT_KEY, TIME_KEY, WORLD_KEY,
|
POV_KEY, FOCUS_KEY, CHAR_KEY, PLOT_KEY, TIME_KEY, WORLD_KEY,
|
||||||
OBJECT_KEY, ENTITY_KEY, CUSTOM_KEY,
|
OBJECT_KEY, ENTITY_KEY, CUSTOM_KEY,
|
||||||
]
|
]
|
||||||
|
CAN_LOOKUP: Final[list[str]] = [
|
||||||
|
POV_KEY, FOCUS_KEY, CHAR_KEY, PLOT_KEY, TIME_KEY, WORLD_KEY,
|
||||||
|
OBJECT_KEY, ENTITY_KEY, CUSTOM_KEY, STORY_KEY, MENTION_KEY,
|
||||||
|
]
|
||||||
|
|
||||||
# Set of Valid Keys
|
# Set of Valid Keys
|
||||||
VALID_KEYS: Final[set[str]] = set(ALL_KEYS)
|
VALID_KEYS: Final[set[str]] = set(ALL_KEYS)
|
||||||
|
|||||||
+16
-10
@@ -131,12 +131,6 @@ class Index:
|
|||||||
self._novelExtra = extra
|
self._novelExtra = extra
|
||||||
return
|
return
|
||||||
|
|
||||||
def setItemClass(self, tHandle: str, itemClass: nwItemClass) -> None:
|
|
||||||
"""Update the class for all tags of a handle."""
|
|
||||||
logger.info("Updating class for '%s'", tHandle)
|
|
||||||
self._tagsIndex.updateClass(tHandle, itemClass.name)
|
|
||||||
return
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Public Methods
|
# Public Methods
|
||||||
##
|
##
|
||||||
@@ -183,6 +177,16 @@ class Index:
|
|||||||
self.scanText(tHandle, self._project.storage.getDocumentText(tHandle))
|
self.scanText(tHandle, self._project.storage.getDocumentText(tHandle))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def refreshHandle(self, tHandle: str) -> None:
|
||||||
|
"""Update the class for all tags of a handle."""
|
||||||
|
if item := self._project.tree[tHandle]:
|
||||||
|
logger.info("Updating class for '%s'", tHandle)
|
||||||
|
if item.isInactiveClass():
|
||||||
|
self.deleteHandle(tHandle)
|
||||||
|
else:
|
||||||
|
self._tagsIndex.updateClass(tHandle, item.itemClass.name)
|
||||||
|
return
|
||||||
|
|
||||||
def indexChangedSince(self, checkTime: int | float) -> bool:
|
def indexChangedSince(self, checkTime: int | float) -> bool:
|
||||||
"""Check if the index has changed since a given time."""
|
"""Check if the index has changed since a given time."""
|
||||||
return self._indexChange > float(checkTime)
|
return self._indexChange > float(checkTime)
|
||||||
@@ -753,10 +757,12 @@ class Index:
|
|||||||
"""Return all tags used by a specific document."""
|
"""Return all tags used by a specific document."""
|
||||||
return self._itemIndex.allItemTags(tHandle) if tHandle else []
|
return self._itemIndex.allItemTags(tHandle) if tHandle else []
|
||||||
|
|
||||||
def getClassTags(self, itemClass: nwItemClass | None) -> list[str]:
|
def getKeyWordTags(self, keyWord: str) -> list[str]:
|
||||||
"""Return all tags based on itemClass."""
|
"""Return all tags usable for a specific keyword."""
|
||||||
name = None if itemClass is None else itemClass.name
|
if keyWord in nwKeyWords.CAN_LOOKUP:
|
||||||
return self._tagsIndex.filterTagNames(name)
|
itemClass = nwKeyWords.KEY_CLASS.get(keyWord)
|
||||||
|
return self._tagsIndex.filterTagNames(itemClass.name if itemClass else None)
|
||||||
|
return []
|
||||||
|
|
||||||
def getTagsData(
|
def getTagsData(
|
||||||
self, activeOnly: bool = True
|
self, activeOnly: bool = True
|
||||||
|
|||||||
@@ -439,7 +439,7 @@ class NWItem:
|
|||||||
self.setClass(itemClass)
|
self.setClass(itemClass)
|
||||||
if self._type == nwItemType.FILE:
|
if self._type == nwItemType.FILE:
|
||||||
# Notify the index of the class change
|
# Notify the index of the class change
|
||||||
self._project.index.setItemClass(self._handle, itemClass)
|
self._project.index.refreshHandle(self._handle)
|
||||||
|
|
||||||
if self._layout == nwItemLayout.NO_LAYOUT:
|
if self._layout == nwItemLayout.NO_LAYOUT:
|
||||||
# If no layout is set, pick one
|
# If no layout is set, pick one
|
||||||
|
|||||||
@@ -1090,11 +1090,14 @@ class GuiDocEditor(QPlainTextEdit):
|
|||||||
show = self._completer.updateMetaText(text, bPos)
|
show = self._completer.updateMetaText(text, bPos)
|
||||||
else:
|
else:
|
||||||
show = self._completer.updateCommentText(text, bPos)
|
show = self._completer.updateCommentText(text, bPos)
|
||||||
point = self.cursorRect().bottomRight()
|
if show:
|
||||||
self._completer.move(viewport.mapToGlobal(point))
|
point = self.cursorRect().bottomRight()
|
||||||
self._completer.setVisible(show)
|
self._completer.move(viewport.mapToGlobal(point))
|
||||||
|
self._completer.show()
|
||||||
|
else:
|
||||||
|
self._completer.close()
|
||||||
else:
|
else:
|
||||||
self._completer.setVisible(False)
|
self._completer.close()
|
||||||
|
|
||||||
if self._doReplace and added == 1:
|
if self._doReplace and added == 1:
|
||||||
cursor = self.textCursor()
|
cursor = self.textCursor()
|
||||||
@@ -2113,9 +2116,7 @@ class CommandCompleter(QMenu):
|
|||||||
length = len(lookup)
|
length = len(lookup)
|
||||||
suffix = ""
|
suffix = ""
|
||||||
options = sorted(filter(
|
options = sorted(filter(
|
||||||
lambda x: lookup in x.lower(), SHARED.project.index.getClassTags(
|
lambda x: lookup in x.lower(), SHARED.project.index.getKeyWordTags(kw.strip())
|
||||||
nwKeyWords.KEY_CLASS.get(kw.strip())
|
|
||||||
)
|
|
||||||
))[:15]
|
))[:15]
|
||||||
|
|
||||||
if not options:
|
if not options:
|
||||||
|
|||||||
@@ -95,12 +95,35 @@ def testCoreIndex_LoadSave(qtbot, monkeypatch, prjLipsum, nwGUI, tstPaths):
|
|||||||
tagIndex = str(index._tagsIndex.packData())
|
tagIndex = str(index._tagsIndex.packData())
|
||||||
itemsIndex = str(index._itemIndex.packData())
|
itemsIndex = str(index._itemIndex.packData())
|
||||||
|
|
||||||
|
# Update item class
|
||||||
|
bHandle = "4c4f28287af27"
|
||||||
|
bItem = project.tree[bHandle]
|
||||||
|
assert bItem is not None
|
||||||
|
|
||||||
|
tagsBod = index._tagsIndex["Bod"]
|
||||||
|
assert tagsBod is not None
|
||||||
|
assert tagsBod["handle"] == bHandle
|
||||||
|
assert tagsBod["class"] == "CHARACTER"
|
||||||
|
|
||||||
|
bItem.setClass(nwItemClass.CUSTOM)
|
||||||
|
index.refreshHandle(bHandle)
|
||||||
|
assert tagsBod is not None
|
||||||
|
assert tagsBod["handle"] == bHandle
|
||||||
|
assert tagsBod["class"] == "CUSTOM"
|
||||||
|
|
||||||
|
# Update item class to inactive
|
||||||
|
bItem.setClass(nwItemClass.TRASH)
|
||||||
|
index.refreshHandle(bHandle)
|
||||||
|
assert "Bod" not in index._tagsIndex
|
||||||
|
bItem.setClass(nwItemClass.CHARACTER)
|
||||||
|
index.reIndexHandle(bHandle)
|
||||||
|
|
||||||
# Delete a handle
|
# Delete a handle
|
||||||
assert index._tagsIndex["Bod"] is not None
|
assert index._tagsIndex["Bod"] is not None
|
||||||
assert index._itemIndex["4c4f28287af27"] is not None
|
assert index._itemIndex[bHandle] is not None
|
||||||
index.deleteHandle("4c4f28287af27")
|
index.deleteHandle(bHandle)
|
||||||
assert index._tagsIndex["Bod"] is None
|
assert index._tagsIndex["Bod"] is None
|
||||||
assert index._itemIndex["4c4f28287af27"] is None
|
assert index._itemIndex[bHandle] is None
|
||||||
|
|
||||||
# Clear the index
|
# Clear the index
|
||||||
index.clear()
|
index.clear()
|
||||||
@@ -766,11 +789,12 @@ def testCoreIndex_ExtractData(nwGUI, fncPath, mockRnd):
|
|||||||
assert index.getDocumentTags(cHandle) == ["jane"]
|
assert index.getDocumentTags(cHandle) == ["jane"]
|
||||||
assert index.getDocumentTags(None) == []
|
assert index.getDocumentTags(None) == []
|
||||||
|
|
||||||
# getClassTags
|
# getKeyWordTags
|
||||||
# ============
|
# ==============
|
||||||
assert index.getClassTags(None) == ["Jane", "John"]
|
assert index.getKeyWordTags("@mention") == ["Jane", "John"]
|
||||||
assert index.getClassTags(nwItemClass.CHARACTER) == ["Jane", "John"]
|
assert index.getKeyWordTags("@char") == ["Jane", "John"]
|
||||||
assert index.getClassTags(nwItemClass.PLOT) == []
|
assert index.getKeyWordTags("@plot") == []
|
||||||
|
assert index.getKeyWordTags("@tag") == []
|
||||||
|
|
||||||
# getTagsData
|
# getTagsData
|
||||||
# ===========
|
# ===========
|
||||||
|
|||||||
Reference in New Issue
Block a user