Don't show create note for tag option for story and mention keywords (#2212)

This commit is contained in:
Veronica Berglyd Olsen
2025-01-30 17:28:18 +01:00
parent 3509374f25
commit 9532be585b
3 changed files with 47 additions and 23 deletions
+4
View File
@@ -173,6 +173,10 @@ class nwKeyWords:
TAG_KEY, POV_KEY, FOCUS_KEY, CHAR_KEY, PLOT_KEY, TIME_KEY, WORLD_KEY, TAG_KEY, POV_KEY, FOCUS_KEY, CHAR_KEY, PLOT_KEY, TIME_KEY, WORLD_KEY,
OBJECT_KEY, ENTITY_KEY, CUSTOM_KEY, STORY_KEY, MENTION_KEY, OBJECT_KEY, ENTITY_KEY, CUSTOM_KEY, STORY_KEY, MENTION_KEY,
] ]
CAN_CREATE = [
POV_KEY, FOCUS_KEY, CHAR_KEY, PLOT_KEY, TIME_KEY, WORLD_KEY,
OBJECT_KEY, ENTITY_KEY, CUSTOM_KEY,
]
# Set of Valid Keys # Set of Valid Keys
VALID_KEYS = set(ALL_KEYS) VALID_KEYS = set(ALL_KEYS)
+33 -14
View File
@@ -34,7 +34,7 @@ from __future__ import annotations
import bisect import bisect
import logging import logging
from enum import Enum from enum import Enum, IntFlag
from time import time from time import time
from PyQt5.QtCore import ( from PyQt5.QtCore import (
@@ -57,7 +57,7 @@ from novelwriter.constants import nwConst, nwKeyWords, nwShortcode, nwUnicode
from novelwriter.core.document import NWDocument from novelwriter.core.document import NWDocument
from novelwriter.enum import ( from novelwriter.enum import (
nwChange, nwComment, nwDocAction, nwDocInsert, nwDocMode, nwItemClass, nwChange, nwComment, nwDocAction, nwDocInsert, nwDocMode, nwItemClass,
nwItemType, nwTrinary nwItemType
) )
from novelwriter.extensions.configlayout import NColourLabel from novelwriter.extensions.configlayout import NColourLabel
from novelwriter.extensions.eventfilters import WheelEventFilter from novelwriter.extensions.eventfilters import WheelEventFilter
@@ -84,6 +84,15 @@ class _SelectAction(Enum):
MOVE_AFTER = 3 MOVE_AFTER = 3
class _TagAction(IntFlag):
NONE = 0b0000
GOOD = 0b0001
BAD = 0b0010
FOLLOW = 0b0100
CREATE = 0b1000
class GuiDocEditor(QPlainTextEdit): class GuiDocEditor(QPlainTextEdit):
"""Gui Widget: Main Document Editor""" """Gui Widget: Main Document Editor"""
@@ -1158,11 +1167,12 @@ class GuiDocEditor(QPlainTextEdit):
# Follow # Follow
status = self._processTag(cursor=pCursor, follow=False) status = self._processTag(cursor=pCursor, follow=False)
if status == nwTrinary.POSITIVE: print(status)
if status & _TagAction.FOLLOW:
action = ctxMenu.addAction(self.tr("Follow Tag")) action = ctxMenu.addAction(self.tr("Follow Tag"))
action.triggered.connect(qtLambda(self._processTag, cursor=pCursor, follow=True)) action.triggered.connect(qtLambda(self._processTag, cursor=pCursor, follow=True))
ctxMenu.addSeparator() ctxMenu.addSeparator()
elif status == nwTrinary.NEGATIVE: elif status & _TagAction.CREATE:
action = ctxMenu.addAction(self.tr("Create Note for Tag")) action = ctxMenu.addAction(self.tr("Create Note for Tag"))
action.triggered.connect(qtLambda(self._processTag, cursor=pCursor, create=True)) action.triggered.connect(qtLambda(self._processTag, cursor=pCursor, create=True))
ctxMenu.addSeparator() ctxMenu.addSeparator()
@@ -1925,8 +1935,9 @@ class GuiDocEditor(QPlainTextEdit):
self._qDocument.syntaxHighlighter.rehighlightBlock(block) self._qDocument.syntaxHighlighter.rehighlightBlock(block)
return return
def _processTag(self, cursor: QTextCursor | None = None, def _processTag(
follow: bool = True, create: bool = False) -> nwTrinary: self, cursor: QTextCursor | None = None, follow: bool = True, create: bool = False
) -> _TagAction:
"""Activated by Ctrl+Enter. Checks that we're in a block """Activated by Ctrl+Enter. Checks that we're in a block
starting with '@'. We then find the tag under the cursor and starting with '@'. We then find the tag under the cursor and
check that it is not the tag itself. If all this is fine, we check that it is not the tag itself. If all this is fine, we
@@ -1936,19 +1947,22 @@ class GuiDocEditor(QPlainTextEdit):
if cursor is None: if cursor is None:
cursor = self.textCursor() cursor = self.textCursor()
status = _TagAction.NONE
block = cursor.block() block = cursor.block()
text = block.text() text = block.text()
if len(text) == 0: if len(text) == 0:
return nwTrinary.NEUTRAL return status
if text.startswith("@") and self._docHandle: if text.startswith("@") and self._docHandle:
isGood, tBits, tPos = SHARED.project.index.scanThis(text) isGood, tBits, tPos = SHARED.project.index.scanThis(text)
if ( if (
not isGood or not tBits or tBits[0] == nwKeyWords.TAG_KEY not isGood
or tBits[0] not in nwKeyWords.VALID_KEYS or not tBits
or (key := tBits[0]) == nwKeyWords.TAG_KEY
or key not in nwKeyWords.VALID_KEYS
): ):
return nwTrinary.NEUTRAL return status
tag = "" tag = ""
exist = False exist = False
@@ -1965,7 +1979,14 @@ class GuiDocEditor(QPlainTextEdit):
if not tag or tag.startswith("@"): if not tag or tag.startswith("@"):
# The keyword cannot be looked up, so we ignore that # The keyword cannot be looked up, so we ignore that
return nwTrinary.NEUTRAL return status
if not exist and key in nwKeyWords.CAN_CREATE:
# Must only be set if we have a tag selected
status |= _TagAction.CREATE
if exist:
status |= _TagAction.FOLLOW
if follow and exist: if follow and exist:
logger.debug("Attempting to follow tag '%s'", tag) logger.debug("Attempting to follow tag '%s'", tag)
@@ -1977,9 +1998,7 @@ class GuiDocEditor(QPlainTextEdit):
itemClass = nwKeyWords.KEY_CLASS.get(tBits[0], nwItemClass.NO_CLASS) itemClass = nwKeyWords.KEY_CLASS.get(tBits[0], nwItemClass.NO_CLASS)
self.requestNewNoteCreation.emit(tag, itemClass) self.requestNewNoteCreation.emit(tag, itemClass)
return nwTrinary.POSITIVE if exist else nwTrinary.NEGATIVE return status
return nwTrinary.NEUTRAL
def _emitRenameItem(self, block: QTextBlock) -> None: def _emitRenameItem(self, block: QTextBlock) -> None:
"""Emit a signal to request an item be renamed.""" """Emit a signal to request an item be renamed."""
+10 -9
View File
@@ -35,8 +35,8 @@ from novelwriter import CONFIG, SHARED
from novelwriter.common import decodeMimeHandles from novelwriter.common import decodeMimeHandles
from novelwriter.constants import nwKeyWords, nwUnicode from novelwriter.constants import nwKeyWords, nwUnicode
from novelwriter.dialogs.editlabel import GuiEditLabel from novelwriter.dialogs.editlabel import GuiEditLabel
from novelwriter.enum import nwDocAction, nwDocInsert, nwItemClass, nwItemLayout, nwTrinary from novelwriter.enum import nwDocAction, nwDocInsert, nwItemClass, nwItemLayout
from novelwriter.gui.doceditor import GuiDocEditor from novelwriter.gui.doceditor import GuiDocEditor, _TagAction
from novelwriter.text.counting import standardCounter from novelwriter.text.counting import standardCounter
from novelwriter.types import ( from novelwriter.types import (
QtAlignJustify, QtAlignLeft, QtKeepAnchor, QtModCtrl, QtModNone, QtAlignJustify, QtAlignLeft, QtKeepAnchor, QtModCtrl, QtModNone,
@@ -1693,21 +1693,22 @@ def testGuiEditor_Tags(qtbot, nwGUI, projPath, ipsumText, mockRnd):
# Empty Block # Empty Block
docEditor.setCursorLine(2) docEditor.setCursorLine(2)
assert docEditor._processTag() is nwTrinary.NEUTRAL assert docEditor._processTag() == _TagAction.NONE
# Not On Tag # Not On Tag
docEditor.setCursorLine(1) docEditor.setCursorLine(1)
assert docEditor._processTag() is nwTrinary.NEUTRAL assert docEditor._processTag() == _TagAction.NONE
# On Tag Keyword # On Tag Keyword
docEditor.setCursorPosition(15) docEditor.setCursorPosition(15)
assert docEditor._processTag() is nwTrinary.NEUTRAL assert docEditor._processTag() == _TagAction.NONE
# On Known Tag, No Follow # On Known Tag, No Follow
docEditor.setCursorPosition(22) docEditor.setCursorPosition(22)
assert docEditor._processTag(follow=False) is nwTrinary.POSITIVE assert docEditor._processTag(follow=False) == _TagAction.FOLLOW
assert nwGUI.docViewer._docHandle is None assert nwGUI.docViewer._docHandle is None
# qtbot.stop()
# On Known Tag, Follow # On Known Tag, Follow
docEditor.setCursorPosition(22) docEditor.setCursorPosition(22)
position = docEditor.cursorRect().center() position = docEditor.cursorRect().center()
@@ -1723,13 +1724,13 @@ def testGuiEditor_Tags(qtbot, nwGUI, projPath, ipsumText, mockRnd):
# On Unknown Tag, Create It # On Unknown Tag, Create It
assert "0000000000011" not in SHARED.project.tree assert "0000000000011" not in SHARED.project.tree
docEditor.setCursorPosition(28) docEditor.setCursorPosition(28)
assert docEditor._processTag(create=True) is nwTrinary.NEGATIVE assert docEditor._processTag(create=True) == _TagAction.CREATE
assert "0000000000011" in SHARED.project.tree assert "0000000000011" in SHARED.project.tree
# On Unknown Tag, Missing Root # On Unknown Tag, Missing Root
assert "0000000000012" not in SHARED.project.tree assert "0000000000012" not in SHARED.project.tree
docEditor.setCursorPosition(42) docEditor.setCursorPosition(42)
assert docEditor._processTag(create=True) is nwTrinary.NEGATIVE assert docEditor._processTag(create=True) == _TagAction.CREATE
oHandle = SHARED.project.tree.findRoot(nwItemClass.OBJECT) oHandle = SHARED.project.tree.findRoot(nwItemClass.OBJECT)
assert oHandle == "0000000000012" assert oHandle == "0000000000012"
@@ -1738,7 +1739,7 @@ def testGuiEditor_Tags(qtbot, nwGUI, projPath, ipsumText, mockRnd):
assert oItem.itemParent == "0000000000012" assert oItem.itemParent == "0000000000012"
docEditor.setCursorPosition(47) docEditor.setCursorPosition(47)
assert docEditor._processTag() is nwTrinary.NEUTRAL assert docEditor._processTag() == _TagAction.NONE
# qtbot.stop() # qtbot.stop()