From 19b7b51eea19a58626d7d41c3a8d049d2b6ba584 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Wed, 10 Feb 2021 21:46:55 +0100
Subject: [PATCH 1/5] Add the @focus keyword to the base constant classes
---
nw/constants/constants.py | 8 ++++++--
nw/constants/enum.py | 17 +++++++++--------
2 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/nw/constants/constants.py b/nw/constants/constants.py
index 0909b1f2..94c66244 100644
--- a/nw/constants/constants.py
+++ b/nw/constants/constants.py
@@ -86,6 +86,7 @@ class nwKeyWords:
TAG_KEY = "@tag"
POV_KEY = "@pov"
+ FOCUS_KEY = "@focus"
CHAR_KEY = "@char"
PLOT_KEY = "@plot"
TIME_KEY = "@time"
@@ -96,14 +97,15 @@ class nwKeyWords:
# Set of Valid Keys
VALID_KEYS = {
- TAG_KEY, POV_KEY, CHAR_KEY, PLOT_KEY, TIME_KEY,
+ TAG_KEY, POV_KEY, FOCUS_KEY, CHAR_KEY, PLOT_KEY, TIME_KEY,
WORLD_KEY, OBJECT_KEY, ENTITY_KEY, CUSTOM_KEY
}
# Map from Keys to Item Class
KEY_CLASS = {
- CHAR_KEY : nwItemClass.CHARACTER,
POV_KEY : nwItemClass.CHARACTER,
+ FOCUS_KEY : nwItemClass.CHARACTER,
+ CHAR_KEY : nwItemClass.CHARACTER,
PLOT_KEY : nwItemClass.PLOT,
TIME_KEY : nwItemClass.TIMELINE,
WORLD_KEY : nwItemClass.WORLD,
@@ -180,6 +182,7 @@ class nwLabels():
KEY_NAME = {
nwKeyWords.TAG_KEY : "Tag",
nwKeyWords.POV_KEY : "Point of View",
+ nwKeyWords.FOCUS_KEY : "Focus",
nwKeyWords.CHAR_KEY : "Characters",
nwKeyWords.PLOT_KEY : "Plot",
nwKeyWords.TIME_KEY : "Timeline",
@@ -197,6 +200,7 @@ class nwLabels():
nwOutline.WCOUNT : "Words",
nwOutline.PCOUNT : "Pars",
nwOutline.POV : "POV",
+ nwOutline.FOCUS : "Focus",
nwOutline.CHAR : KEY_NAME[nwKeyWords.CHAR_KEY],
nwOutline.PLOT : KEY_NAME[nwKeyWords.PLOT_KEY],
nwOutline.TIME : KEY_NAME[nwKeyWords.TIME_KEY],
diff --git a/nw/constants/enum.py b/nw/constants/enum.py
index 3e343f14..539c0ae0 100644
--- a/nw/constants/enum.py
+++ b/nw/constants/enum.py
@@ -127,13 +127,14 @@ class nwOutline(Enum):
WCOUNT = 5
PCOUNT = 6
POV = 7
- CHAR = 8
- PLOT = 9
- TIME = 10
- WORLD = 11
- OBJECT = 12
- ENTITY = 13
- CUSTOM = 14
- SYNOP = 15
+ FOCUS = 8
+ CHAR = 9
+ PLOT = 10
+ TIME = 11
+ WORLD = 12
+ OBJECT = 13
+ ENTITY = 14
+ CUSTOM = 15
+ SYNOP = 16
# END Enum nwOutline
From 4c95b1d7ad0459e286149628ac4cb96ac4683d0c Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Wed, 10 Feb 2021 21:47:23 +0100
Subject: [PATCH 2/5] Add Focus reference to the GUI elements
---
nw/gui/mainmenu.py | 1 +
nw/gui/outline.py | 3 +++
nw/gui/outlinedetails.py | 40 +++++++++++++++++++++++++---------------
3 files changed, 29 insertions(+), 15 deletions(-)
diff --git a/nw/gui/mainmenu.py b/nw/gui/mainmenu.py
index 428c053c..e91679ef 100644
--- a/nw/gui/mainmenu.py
+++ b/nw/gui/mainmenu.py
@@ -728,6 +728,7 @@ class GuiMainMenu(QMenuBar):
self.mInsKWItems = {}
self.mInsKWItems[nwKeyWords.TAG_KEY] = (QAction(self.mInsKeywords), "Ctrl+K, G")
self.mInsKWItems[nwKeyWords.POV_KEY] = (QAction(self.mInsKeywords), "Ctrl+K, V")
+ self.mInsKWItems[nwKeyWords.FOCUS_KEY] = (QAction(self.mInsKeywords), "Ctrl+K, F")
self.mInsKWItems[nwKeyWords.CHAR_KEY] = (QAction(self.mInsKeywords), "Ctrl+K, C")
self.mInsKWItems[nwKeyWords.PLOT_KEY] = (QAction(self.mInsKeywords), "Ctrl+K, P")
self.mInsKWItems[nwKeyWords.TIME_KEY] = (QAction(self.mInsKeywords), "Ctrl+K, T")
diff --git a/nw/gui/outline.py b/nw/gui/outline.py
index 291171cd..666c8026 100644
--- a/nw/gui/outline.py
+++ b/nw/gui/outline.py
@@ -49,6 +49,7 @@ class GuiOutline(QTreeWidget):
nwOutline.WCOUNT : 50,
nwOutline.PCOUNT : 50,
nwOutline.POV : 100,
+ nwOutline.FOCUS : 100,
nwOutline.CHAR : 100,
nwOutline.PLOT : 100,
nwOutline.TIME : 100,
@@ -68,6 +69,7 @@ class GuiOutline(QTreeWidget):
nwOutline.WCOUNT : False,
nwOutline.PCOUNT : False,
nwOutline.POV : False,
+ nwOutline.FOCUS : True,
nwOutline.CHAR : False,
nwOutline.PLOT : False,
nwOutline.TIME : True,
@@ -451,6 +453,7 @@ class GuiOutline(QTreeWidget):
theRefs = self.theIndex.getReferences(tHandle, sTitle)
newItem.setText(self.colIndex[nwOutline.POV], ", ".join(theRefs[nwKeyWords.POV_KEY]))
+ newItem.setText(self.colIndex[nwOutline.FOCUS], ", ".join(theRefs[nwKeyWords.FOCUS_KEY]))
newItem.setText(self.colIndex[nwOutline.CHAR], ", ".join(theRefs[nwKeyWords.CHAR_KEY]))
newItem.setText(self.colIndex[nwOutline.PLOT], ", ".join(theRefs[nwKeyWords.PLOT_KEY]))
newItem.setText(self.colIndex[nwOutline.TIME], ", ".join(theRefs[nwKeyWords.TIME_KEY]))
diff --git a/nw/gui/outlinedetails.py b/nw/gui/outlinedetails.py
index 94ab542e..15785ff8 100644
--- a/nw/gui/outlinedetails.py
+++ b/nw/gui/outlinedetails.py
@@ -105,6 +105,7 @@ class GuiOutlineDetails(QScrollArea):
# Tags
self.povKeyLabel = QLabel("%s" % nwLabels.KEY_NAME[nwKeyWords.POV_KEY])
+ self.focKeyLabel = QLabel("%s" % nwLabels.KEY_NAME[nwKeyWords.FOCUS_KEY])
self.chrKeyLabel = QLabel("%s" % nwLabels.KEY_NAME[nwKeyWords.CHAR_KEY])
self.pltKeyLabel = QLabel("%s" % nwLabels.KEY_NAME[nwKeyWords.PLOT_KEY])
self.timKeyLabel = QLabel("%s" % nwLabels.KEY_NAME[nwKeyWords.TIME_KEY])
@@ -114,6 +115,7 @@ class GuiOutlineDetails(QScrollArea):
self.cstKeyLabel = QLabel("%s" % nwLabels.KEY_NAME[nwKeyWords.CUSTOM_KEY])
self.povKeyLWrap = QHBoxLayout()
+ self.focKeyLWrap = QHBoxLayout()
self.chrKeyLWrap = QHBoxLayout()
self.pltKeyLWrap = QHBoxLayout()
self.timKeyLWrap = QHBoxLayout()
@@ -123,6 +125,7 @@ class GuiOutlineDetails(QScrollArea):
self.cstKeyLWrap = QHBoxLayout()
self.povKeyValue = QLabel("")
+ self.focKeyValue = QLabel("")
self.chrKeyValue = QLabel("")
self.pltKeyValue = QLabel("")
self.timKeyValue = QLabel("")
@@ -132,6 +135,7 @@ class GuiOutlineDetails(QScrollArea):
self.cstKeyValue = QLabel("")
self.povKeyValue.setWordWrap(True)
+ self.focKeyValue.setWordWrap(True)
self.chrKeyValue.setWordWrap(True)
self.pltKeyValue.setWordWrap(True)
self.timKeyValue.setWordWrap(True)
@@ -141,6 +145,7 @@ class GuiOutlineDetails(QScrollArea):
self.cstKeyValue.setWordWrap(True)
self.povKeyValue.linkActivated.connect(self._tagClicked)
+ self.focKeyValue.linkActivated.connect(self._tagClicked)
self.chrKeyValue.linkActivated.connect(self._tagClicked)
self.pltKeyValue.linkActivated.connect(self._tagClicked)
self.timKeyValue.linkActivated.connect(self._tagClicked)
@@ -150,6 +155,7 @@ class GuiOutlineDetails(QScrollArea):
self.cstKeyValue.linkActivated.connect(self._tagClicked)
self.povKeyLWrap.addWidget(self.povKeyValue, 1)
+ self.focKeyLWrap.addWidget(self.focKeyValue, 1)
self.chrKeyLWrap.addWidget(self.chrKeyValue, 1)
self.pltKeyLWrap.addWidget(self.pltKeyValue, 1)
self.timKeyLWrap.addWidget(self.timKeyValue, 1)
@@ -190,23 +196,25 @@ class GuiOutlineDetails(QScrollArea):
self.tagsForm.addWidget(self.povKeyLabel, 0, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.tagsForm.addLayout(self.povKeyLWrap, 0, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
- self.tagsForm.addWidget(self.chrKeyLabel, 1, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
- self.tagsForm.addLayout(self.chrKeyLWrap, 1, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
- self.tagsForm.addWidget(self.pltKeyLabel, 2, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
- self.tagsForm.addLayout(self.pltKeyLWrap, 2, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
- self.tagsForm.addWidget(self.timKeyLabel, 3, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
- self.tagsForm.addLayout(self.timKeyLWrap, 3, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
- self.tagsForm.addWidget(self.wldKeyLabel, 4, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
- self.tagsForm.addLayout(self.wldKeyLWrap, 4, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
- self.tagsForm.addWidget(self.objKeyLabel, 5, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
- self.tagsForm.addLayout(self.objKeyLWrap, 5, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
- self.tagsForm.addWidget(self.entKeyLabel, 6, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
- self.tagsForm.addLayout(self.entKeyLWrap, 6, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
- self.tagsForm.addWidget(self.cstKeyLabel, 7, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
- self.tagsForm.addLayout(self.cstKeyLWrap, 7, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
+ self.tagsForm.addWidget(self.focKeyLabel, 1, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
+ self.tagsForm.addLayout(self.focKeyLWrap, 1, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
+ self.tagsForm.addWidget(self.chrKeyLabel, 2, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
+ self.tagsForm.addLayout(self.chrKeyLWrap, 2, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
+ self.tagsForm.addWidget(self.pltKeyLabel, 3, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
+ self.tagsForm.addLayout(self.pltKeyLWrap, 3, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
+ self.tagsForm.addWidget(self.timKeyLabel, 4, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
+ self.tagsForm.addLayout(self.timKeyLWrap, 4, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
+ self.tagsForm.addWidget(self.wldKeyLabel, 5, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
+ self.tagsForm.addLayout(self.wldKeyLWrap, 5, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
+ self.tagsForm.addWidget(self.objKeyLabel, 6, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
+ self.tagsForm.addLayout(self.objKeyLWrap, 6, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
+ self.tagsForm.addWidget(self.entKeyLabel, 7, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
+ self.tagsForm.addLayout(self.entKeyLWrap, 7, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
+ self.tagsForm.addWidget(self.cstKeyLabel, 8, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
+ self.tagsForm.addLayout(self.cstKeyLWrap, 8, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.tagsForm.setColumnStretch(1, 1)
- self.tagsForm.setRowStretch(7, 1)
+ self.tagsForm.setRowStretch(8, 1)
self.tagsForm.setHorizontalSpacing(hSpace)
self.tagsForm.setVerticalSpacing(vSpace)
@@ -257,6 +265,7 @@ class GuiOutlineDetails(QScrollArea):
self.pCValue.setText("")
self.synopValue.setText("")
self.povKeyValue.setText("")
+ self.focKeyValue.setText("")
self.chrKeyValue.setText("")
self.pltKeyValue.setText("")
self.timKeyValue.setText("")
@@ -296,6 +305,7 @@ class GuiOutlineDetails(QScrollArea):
self.synopValue.setText(novIdx["synopsis"])
self.povKeyValue.setText(self._formatTags(theRefs, nwKeyWords.POV_KEY))
+ self.focKeyValue.setText(self._formatTags(theRefs, nwKeyWords.FOCUS_KEY))
self.chrKeyValue.setText(self._formatTags(theRefs, nwKeyWords.CHAR_KEY))
self.pltKeyValue.setText(self._formatTags(theRefs, nwKeyWords.PLOT_KEY))
self.timKeyValue.setText(self._formatTags(theRefs, nwKeyWords.TIME_KEY))
From fdd188516bf4673226667cfdd10a1413496b1474 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Wed, 10 Feb 2021 21:47:42 +0100
Subject: [PATCH 3/5] Update sample project and test
---
sample/content/bc0cbd2a407f3.nwd | 2 ++
sample/nwProject.nwx | 12 ++++++------
tests/test_gui/test_gui_mainmenu.py | 4 ++++
3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/sample/content/bc0cbd2a407f3.nwd b/sample/content/bc0cbd2a407f3.nwd
index 17524248..80f75eef 100644
--- a/sample/content/bc0cbd2a407f3.nwd
+++ b/sample/content/bc0cbd2a407f3.nwd
@@ -4,6 +4,7 @@
### Another Scene
@pov: John
+@focus: Jane
@location: Earth
Adding more scenes to a chapter is as easy as adding more scene files, with a level three heading, or just adding another level three heading in the same file if that works for the way you want to structure your files.
@@ -13,6 +14,7 @@ In fact, if you wish, you can add all the scenes in the chapter file too. All no
### More Scenes
@pov: Jane
+@focus: John
@location: Earth
This is a second scene in the same file as the previous scene. You can always split the files up later.
diff --git a/sample/nwProject.nwx b/sample/nwProject.nwx
index 4bc8a637..9fc95dda 100644
--- a/sample/nwProject.nwx
+++ b/sample/nwProject.nwx
@@ -1,13 +1,13 @@
-
+
Sample Project
Sample Project
Jane Smith
Jay Doh
- 886
- 158
- 42826
+ 935
+ 161
+ 46219
False
@@ -120,7 +120,7 @@
1810
318
8
- 219
+ 3
-
Another Scene
@@ -132,7 +132,7 @@
476
93
3
- 428
+ 430
-
Interlude
diff --git a/tests/test_gui/test_gui_mainmenu.py b/tests/test_gui/test_gui_mainmenu.py
index f6504abf..50305184 100644
--- a/tests/test_gui/test_gui_mainmenu.py
+++ b/tests/test_gui/test_gui_mainmenu.py
@@ -500,6 +500,10 @@ def testGuiMenu_Insert(qtbot, monkeypatch, nwGUI, fncDir, fncProj):
nwGUI.mainMenu.mInsKWItems[nwKeyWords.POV_KEY][0].activate(QAction.Trigger)
assert nwGUI.docEditor.getText() == "Stuff\n%s: " % nwKeyWords.POV_KEY
+ nwGUI.docEditor.setText("Stuff")
+ nwGUI.mainMenu.mInsKWItems[nwKeyWords.FOCUS_KEY][0].activate(QAction.Trigger)
+ assert nwGUI.docEditor.getText() == "Stuff\n%s: " % nwKeyWords.FOCUS_KEY
+
nwGUI.docEditor.setText("Stuff")
nwGUI.mainMenu.mInsKWItems[nwKeyWords.CHAR_KEY][0].activate(QAction.Trigger)
assert nwGUI.docEditor.getText() == "Stuff\n%s: " % nwKeyWords.CHAR_KEY
From 2d3f848ab3c8cb2c09c167c661f2f4b825cb29ee Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Wed, 10 Feb 2021 21:58:25 +0100
Subject: [PATCH 4/5] Update documentation with references to the @focus
keyword
---
docs/source/usage_interface.rst | 1 +
docs/source/usage_projects.rst | 5 +++--
docs/source/usage_structure.rst | 17 +++++++++++------
3 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/docs/source/usage_interface.rst b/docs/source/usage_interface.rst
index f5b8d68d..f8c419a1 100644
--- a/docs/source/usage_interface.rst
+++ b/docs/source/usage_interface.rst
@@ -453,6 +453,7 @@ a key or key combination for the inserted content.
":kbd:`Ctrl`:kbd:`K`, :kbd:`Ctrl`:kbd:`D`", "Insert a division sign."
":kbd:`Ctrl`:kbd:`K`, :kbd:`G`", "Insert a ``@tag`` keyword."
":kbd:`Ctrl`:kbd:`K`, :kbd:`V`", "Insert a ``@pov`` keyword."
+ ":kbd:`Ctrl`:kbd:`K`, :kbd:`F`", "Insert a ``@focus`` keyword."
":kbd:`Ctrl`:kbd:`K`, :kbd:`C`", "Insert a ``@char`` keyword."
":kbd:`Ctrl`:kbd:`K`, :kbd:`P`", "Insert a ``@plot`` keyword."
":kbd:`Ctrl`:kbd:`K`, :kbd:`T`", "Insert a ``@time`` keyword."
diff --git a/docs/source/usage_projects.rst b/docs/source/usage_projects.rst
index e00dd234..60266f16 100644
--- a/docs/source/usage_projects.rst
+++ b/docs/source/usage_projects.rst
@@ -51,8 +51,9 @@ no restrictions are enforced by the application. You can use them however you wa
:guilabel:`Characters`
Character notes go in this root folder. These are especially important if one wants to use the
Outline view to see which character appears where, and which part of the story is told from a
- specific character's point-of-view. Tags in this folder can be references using the ``@pov``
- keyword for point-of-view characters, or the ``@char`` keyword for other characters.
+ specific character's point-of-view or focusing on a particular character's storyline. Tags in
+ this folder can be referenced using the ``@pov`` keyword for point-of-view characters,
+ ``@focus`` for a focus character, or the ``@char`` keyword for any other characters.
:guilabel:`Locations`
The locations folder is for various scene locations that you want to track. Tags in this folder
diff --git a/docs/source/usage_structure.rst b/docs/source/usage_structure.rst
index 8bfe81d5..1bed764c 100644
--- a/docs/source/usage_structure.rst
+++ b/docs/source/usage_structure.rst
@@ -103,28 +103,33 @@ allow multiple values.
The point-of-view character for the current section. The target must be a note tag in the
:guilabel:`Character` type root folder.
+``@focus``
+ The character that has the focus for the current section. This can be used in cases where the
+ focus is not a point-of-view character. The target must be a note tag in the
+ :guilabel:`Character` type root folder.
+
``@char``
- Other characters in the current section. The target must be a note tag in a
+ Other characters in the current section. The target must be a note tag in the
:guilabel:`Character` type root folder. This should not include the point-of-view character.
``@plot``
- The plot or subplot advanced in the current section. The target must be a note tag in a
+ The plot or subplot advanced in the current section. The target must be a note tag in thje
:guilabel:`Plot` type root folder.
``@time``
- The timelines touched by the current section. The target must be a note tag in a
+ The timelines touched by the current section. The target must be a note tag in the
:guilabel:`Timeline` type root folder.
``@location``
- The location the current section takes place in. The target must be a note tag in a
+ The location the current section takes place in. The target must be a note tag in the
:guilabel:`Locations` type root folder.
``@object``
- Objects present in the current section. The target must be a note tag in an :guilabel:`Object`
+ Objects present in the current section. The target must be a note tag in the :guilabel:`Object`
type root folder.
``@entity``
- Entities present in the current section. The target must be a note tag in an
+ Entities present in the current section. The target must be a note tag in the
:guilabel:`Entities` type root folder.
``@custom``
From 6c07ecb700835bdcccd4277fb91a495513e13ecd Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Wed, 10 Feb 2021 22:03:18 +0100
Subject: [PATCH 5/5] Fix a typo
---
docs/source/usage_structure.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/source/usage_structure.rst b/docs/source/usage_structure.rst
index 1bed764c..5a903efb 100644
--- a/docs/source/usage_structure.rst
+++ b/docs/source/usage_structure.rst
@@ -113,7 +113,7 @@ allow multiple values.
:guilabel:`Character` type root folder. This should not include the point-of-view character.
``@plot``
- The plot or subplot advanced in the current section. The target must be a note tag in thje
+ The plot or subplot advanced in the current section. The target must be a note tag in the
:guilabel:`Plot` type root folder.
``@time``