novelWriter 2.5.1__py3-none-any.whl → 2.6b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {novelWriter-2.5.1.dist-info → novelWriter-2.6b1.dist-info}/METADATA +2 -1
- {novelWriter-2.5.1.dist-info → novelWriter-2.6b1.dist-info}/RECORD +61 -56
- {novelWriter-2.5.1.dist-info → novelWriter-2.6b1.dist-info}/WHEEL +1 -1
- novelwriter/__init__.py +3 -3
- novelwriter/assets/i18n/project_en_GB.json +1 -0
- novelwriter/assets/icons/typicons_dark/icons.conf +1 -0
- novelwriter/assets/icons/typicons_dark/mixed_copy.svg +4 -0
- novelwriter/assets/icons/typicons_light/icons.conf +1 -0
- novelwriter/assets/icons/typicons_light/mixed_copy.svg +4 -0
- novelwriter/assets/manual.pdf +0 -0
- novelwriter/assets/sample.zip +0 -0
- novelwriter/assets/themes/default_light.conf +2 -2
- novelwriter/common.py +63 -0
- novelwriter/config.py +10 -3
- novelwriter/constants.py +153 -60
- novelwriter/core/buildsettings.py +66 -39
- novelwriter/core/coretools.py +34 -22
- novelwriter/core/docbuild.py +130 -169
- novelwriter/core/index.py +29 -18
- novelwriter/core/item.py +2 -2
- novelwriter/core/options.py +4 -1
- novelwriter/core/spellcheck.py +9 -14
- novelwriter/dialogs/preferences.py +45 -32
- novelwriter/dialogs/projectsettings.py +3 -3
- novelwriter/enum.py +29 -23
- novelwriter/extensions/configlayout.py +24 -11
- novelwriter/extensions/modified.py +13 -1
- novelwriter/extensions/pagedsidebar.py +5 -5
- novelwriter/formats/shared.py +155 -0
- novelwriter/formats/todocx.py +1195 -0
- novelwriter/formats/tohtml.py +452 -0
- novelwriter/{core → formats}/tokenizer.py +483 -485
- novelwriter/formats/tomarkdown.py +217 -0
- novelwriter/{core → formats}/toodt.py +270 -320
- novelwriter/formats/toqdoc.py +436 -0
- novelwriter/formats/toraw.py +91 -0
- novelwriter/gui/doceditor.py +240 -193
- novelwriter/gui/dochighlight.py +96 -84
- novelwriter/gui/docviewer.py +56 -30
- novelwriter/gui/docviewerpanel.py +3 -3
- novelwriter/gui/editordocument.py +17 -2
- novelwriter/gui/itemdetails.py +8 -4
- novelwriter/gui/mainmenu.py +121 -60
- novelwriter/gui/noveltree.py +35 -37
- novelwriter/gui/outline.py +186 -238
- novelwriter/gui/projtree.py +142 -131
- novelwriter/gui/sidebar.py +7 -6
- novelwriter/gui/theme.py +5 -4
- novelwriter/guimain.py +43 -155
- novelwriter/shared.py +14 -4
- novelwriter/text/counting.py +2 -0
- novelwriter/text/patterns.py +155 -59
- novelwriter/tools/manusbuild.py +1 -1
- novelwriter/tools/manuscript.py +121 -78
- novelwriter/tools/manussettings.py +403 -260
- novelwriter/tools/welcome.py +4 -4
- novelwriter/tools/writingstats.py +3 -3
- novelwriter/types.py +16 -6
- novelwriter/core/tohtml.py +0 -530
- novelwriter/core/tomarkdown.py +0 -252
- novelwriter/core/toqdoc.py +0 -419
- {novelWriter-2.5.1.dist-info → novelWriter-2.6b1.dist-info}/LICENSE.md +0 -0
- {novelWriter-2.5.1.dist-info → novelWriter-2.6b1.dist-info}/entry_points.txt +0 -0
- {novelWriter-2.5.1.dist-info → novelWriter-2.6b1.dist-info}/top_level.txt +0 -0
novelwriter/gui/outline.py
CHANGED
@@ -42,14 +42,14 @@ from PyQt5.QtWidgets import (
|
|
42
42
|
|
43
43
|
from novelwriter import CONFIG, SHARED
|
44
44
|
from novelwriter.common import checkInt, formatFileFilter, makeFileNameSafe
|
45
|
-
from novelwriter.constants import
|
45
|
+
from novelwriter.constants import nwKeyWords, nwLabels, nwStats, nwStyles, trConst
|
46
46
|
from novelwriter.enum import nwDocMode, nwItemClass, nwItemLayout, nwItemType, nwOutline
|
47
47
|
from novelwriter.error import logException
|
48
48
|
from novelwriter.extensions.configlayout import NColourLabel
|
49
49
|
from novelwriter.extensions.novelselector import NovelSelector
|
50
50
|
from novelwriter.types import (
|
51
51
|
QtAlignLeftTop, QtAlignRight, QtAlignRightTop, QtDecoration,
|
52
|
-
QtSizeExpanding, QtUserRole
|
52
|
+
QtScrollAlwaysOff, QtScrollAsNeeded, QtSizeExpanding, QtUserRole
|
53
53
|
)
|
54
54
|
|
55
55
|
logger = logging.getLogger(__name__)
|
@@ -135,11 +135,15 @@ class GuiOutlineView(QWidget):
|
|
135
135
|
self.outlineBar.populateNovelList()
|
136
136
|
self.outlineBar.setCurrentRoot(lastOutline)
|
137
137
|
self.outlineBar.setEnabled(True)
|
138
|
+
self.outlineData.loadGuiSettings()
|
138
139
|
|
139
140
|
return
|
140
141
|
|
141
142
|
def closeProjectTasks(self) -> None:
|
142
143
|
"""Run closing project tasks."""
|
144
|
+
if self.outlineTree.wasRendered:
|
145
|
+
# If the panel hasn't been drawn yet, those values are incorrect
|
146
|
+
self.outlineData.saveGuiSettings()
|
143
147
|
self.outlineTree.closeProjectTasks()
|
144
148
|
self.outlineData.updateClasses()
|
145
149
|
self.clearOutline()
|
@@ -312,43 +316,49 @@ class GuiOutlineToolBar(QToolBar):
|
|
312
316
|
class GuiOutlineTree(QTreeWidget):
|
313
317
|
|
314
318
|
DEF_WIDTH = {
|
315
|
-
nwOutline.TITLE:
|
316
|
-
nwOutline.LEVEL:
|
317
|
-
nwOutline.LABEL:
|
318
|
-
nwOutline.LINE:
|
319
|
-
nwOutline.
|
320
|
-
nwOutline.
|
321
|
-
nwOutline.
|
322
|
-
nwOutline.
|
323
|
-
nwOutline.
|
324
|
-
nwOutline.
|
325
|
-
nwOutline.
|
326
|
-
nwOutline.
|
327
|
-
nwOutline.
|
328
|
-
nwOutline.
|
329
|
-
nwOutline.
|
330
|
-
nwOutline.
|
331
|
-
nwOutline.
|
319
|
+
nwOutline.TITLE: 200,
|
320
|
+
nwOutline.LEVEL: 40,
|
321
|
+
nwOutline.LABEL: 150,
|
322
|
+
nwOutline.LINE: 40,
|
323
|
+
nwOutline.STATUS: 100,
|
324
|
+
nwOutline.CCOUNT: 50,
|
325
|
+
nwOutline.WCOUNT: 50,
|
326
|
+
nwOutline.PCOUNT: 50,
|
327
|
+
nwOutline.POV: 100,
|
328
|
+
nwOutline.FOCUS: 100,
|
329
|
+
nwOutline.CHAR: 100,
|
330
|
+
nwOutline.PLOT: 100,
|
331
|
+
nwOutline.TIME: 100,
|
332
|
+
nwOutline.WORLD: 100,
|
333
|
+
nwOutline.OBJECT: 100,
|
334
|
+
nwOutline.ENTITY: 100,
|
335
|
+
nwOutline.CUSTOM: 100,
|
336
|
+
nwOutline.STORY: 100,
|
337
|
+
nwOutline.MENTION: 100,
|
338
|
+
nwOutline.SYNOP: 200,
|
332
339
|
}
|
333
340
|
|
334
341
|
DEF_HIDDEN = {
|
335
|
-
nwOutline.TITLE:
|
336
|
-
nwOutline.LEVEL:
|
337
|
-
nwOutline.LABEL:
|
338
|
-
nwOutline.LINE:
|
339
|
-
nwOutline.
|
340
|
-
nwOutline.
|
341
|
-
nwOutline.
|
342
|
-
nwOutline.
|
343
|
-
nwOutline.
|
344
|
-
nwOutline.
|
345
|
-
nwOutline.
|
346
|
-
nwOutline.
|
347
|
-
nwOutline.
|
348
|
-
nwOutline.
|
349
|
-
nwOutline.
|
350
|
-
nwOutline.
|
351
|
-
nwOutline.
|
342
|
+
nwOutline.TITLE: False,
|
343
|
+
nwOutline.LEVEL: True,
|
344
|
+
nwOutline.LABEL: False,
|
345
|
+
nwOutline.LINE: True,
|
346
|
+
nwOutline.STATUS: True,
|
347
|
+
nwOutline.CCOUNT: True,
|
348
|
+
nwOutline.WCOUNT: False,
|
349
|
+
nwOutline.PCOUNT: False,
|
350
|
+
nwOutline.POV: False,
|
351
|
+
nwOutline.FOCUS: True,
|
352
|
+
nwOutline.CHAR: False,
|
353
|
+
nwOutline.PLOT: False,
|
354
|
+
nwOutline.TIME: True,
|
355
|
+
nwOutline.WORLD: False,
|
356
|
+
nwOutline.OBJECT: True,
|
357
|
+
nwOutline.ENTITY: True,
|
358
|
+
nwOutline.CUSTOM: True,
|
359
|
+
nwOutline.STORY: True,
|
360
|
+
nwOutline.MENTION: True,
|
361
|
+
nwOutline.SYNOP: False,
|
352
362
|
}
|
353
363
|
|
354
364
|
D_HANDLE = QtUserRole
|
@@ -426,6 +436,11 @@ class GuiOutlineTree(QTreeWidget):
|
|
426
436
|
def hiddenColumns(self) -> dict[nwOutline, bool]:
|
427
437
|
return self._colHidden
|
428
438
|
|
439
|
+
@property
|
440
|
+
def wasRendered(self) -> bool:
|
441
|
+
"""Returns True after the Outline has been rendered once."""
|
442
|
+
return not self._firstView
|
443
|
+
|
429
444
|
##
|
430
445
|
# Methods
|
431
446
|
##
|
@@ -433,13 +448,13 @@ class GuiOutlineTree(QTreeWidget):
|
|
433
448
|
def initSettings(self) -> None:
|
434
449
|
"""Set or update outline settings."""
|
435
450
|
if CONFIG.hideVScroll:
|
436
|
-
self.setVerticalScrollBarPolicy(
|
451
|
+
self.setVerticalScrollBarPolicy(QtScrollAlwaysOff)
|
437
452
|
else:
|
438
|
-
self.setVerticalScrollBarPolicy(
|
453
|
+
self.setVerticalScrollBarPolicy(QtScrollAsNeeded)
|
439
454
|
if CONFIG.hideHScroll:
|
440
|
-
self.setHorizontalScrollBarPolicy(
|
455
|
+
self.setHorizontalScrollBarPolicy(QtScrollAlwaysOff)
|
441
456
|
else:
|
442
|
-
self.setHorizontalScrollBarPolicy(
|
457
|
+
self.setHorizontalScrollBarPolicy(QtScrollAsNeeded)
|
443
458
|
return
|
444
459
|
|
445
460
|
def clearContent(self) -> None:
|
@@ -465,8 +480,10 @@ class GuiOutlineTree(QTreeWidget):
|
|
465
480
|
|
466
481
|
return
|
467
482
|
|
468
|
-
def refreshTree(
|
469
|
-
|
483
|
+
def refreshTree(
|
484
|
+
self, rootHandle: str | None = None,
|
485
|
+
overRide: bool = False, novelChanged: bool = False
|
486
|
+
) -> None:
|
470
487
|
"""Called whenever the Outline tab is activated and controls
|
471
488
|
what data to load, and if necessary, force a rebuild of the
|
472
489
|
tree.
|
@@ -653,6 +670,7 @@ class GuiOutlineTree(QTreeWidget):
|
|
653
670
|
is fast and doesn't require a rebuild of the tree.
|
654
671
|
"""
|
655
672
|
logger.debug("Rebuilding Outline tree")
|
673
|
+
tStart = time()
|
656
674
|
self.clear()
|
657
675
|
|
658
676
|
if self._firstView:
|
@@ -681,45 +699,51 @@ class GuiOutlineTree(QTreeWidget):
|
|
681
699
|
novStruct = SHARED.project.index.novelStructure(rootHandle=rootHandle, activeOnly=True)
|
682
700
|
for _, tHandle, sTitle, novIdx in novStruct:
|
683
701
|
|
684
|
-
iLevel =
|
702
|
+
iLevel = nwStyles.H_LEVEL.get(novIdx.level, 0)
|
685
703
|
nwItem = SHARED.project.tree[tHandle]
|
686
704
|
if iLevel == 0 or nwItem is None:
|
687
705
|
continue
|
706
|
+
sLabel, sIcon = nwItem.getImportStatus()
|
688
707
|
|
689
|
-
|
708
|
+
item = QTreeWidgetItem()
|
690
709
|
hDec = SHARED.theme.getHeaderDecoration(iLevel)
|
691
710
|
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
711
|
+
item.setData(self._colIdx[nwOutline.TITLE], QtDecoration, hDec)
|
712
|
+
item.setText(self._colIdx[nwOutline.TITLE], novIdx.title)
|
713
|
+
item.setData(self._colIdx[nwOutline.TITLE], self.D_HANDLE, tHandle)
|
714
|
+
item.setData(self._colIdx[nwOutline.TITLE], self.D_TITLE, sTitle)
|
715
|
+
item.setFont(self._colIdx[nwOutline.TITLE], self._hFonts[iLevel])
|
716
|
+
item.setText(self._colIdx[nwOutline.LEVEL], novIdx.level)
|
717
|
+
item.setIcon(self._colIdx[nwOutline.LABEL], self._dIcon[nwItem.mainHeading])
|
718
|
+
item.setText(self._colIdx[nwOutline.LABEL], nwItem.itemName)
|
719
|
+
item.setText(self._colIdx[nwOutline.LINE], f"{novIdx.line:n}")
|
720
|
+
item.setText(self._colIdx[nwOutline.STATUS], sLabel)
|
721
|
+
item.setIcon(self._colIdx[nwOutline.STATUS], sIcon)
|
722
|
+
item.setText(self._colIdx[nwOutline.SYNOP], novIdx.synopsis)
|
723
|
+
item.setText(self._colIdx[nwOutline.CCOUNT], f"{novIdx.charCount:n}")
|
724
|
+
item.setText(self._colIdx[nwOutline.WCOUNT], f"{novIdx.wordCount:n}")
|
725
|
+
item.setText(self._colIdx[nwOutline.PCOUNT], f"{novIdx.paraCount:n}")
|
726
|
+
item.setTextAlignment(self._colIdx[nwOutline.CCOUNT], QtAlignRight)
|
727
|
+
item.setTextAlignment(self._colIdx[nwOutline.WCOUNT], QtAlignRight)
|
728
|
+
item.setTextAlignment(self._colIdx[nwOutline.PCOUNT], QtAlignRight)
|
708
729
|
|
709
730
|
refs = SHARED.project.index.getReferences(tHandle, sTitle)
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
self.
|
731
|
+
item.setText(self._colIdx[nwOutline.POV], ", ".join(refs[nwKeyWords.POV_KEY]))
|
732
|
+
item.setText(self._colIdx[nwOutline.FOCUS], ", ".join(refs[nwKeyWords.FOCUS_KEY]))
|
733
|
+
item.setText(self._colIdx[nwOutline.CHAR], ", ".join(refs[nwKeyWords.CHAR_KEY]))
|
734
|
+
item.setText(self._colIdx[nwOutline.PLOT], ", ".join(refs[nwKeyWords.PLOT_KEY]))
|
735
|
+
item.setText(self._colIdx[nwOutline.TIME], ", ".join(refs[nwKeyWords.TIME_KEY]))
|
736
|
+
item.setText(self._colIdx[nwOutline.WORLD], ", ".join(refs[nwKeyWords.WORLD_KEY]))
|
737
|
+
item.setText(self._colIdx[nwOutline.OBJECT], ", ".join(refs[nwKeyWords.OBJECT_KEY]))
|
738
|
+
item.setText(self._colIdx[nwOutline.ENTITY], ", ".join(refs[nwKeyWords.ENTITY_KEY]))
|
739
|
+
item.setText(self._colIdx[nwOutline.CUSTOM], ", ".join(refs[nwKeyWords.CUSTOM_KEY]))
|
740
|
+
item.setText(self._colIdx[nwOutline.STORY], ", ".join(refs[nwKeyWords.STORY_KEY]))
|
741
|
+
item.setText(self._colIdx[nwOutline.MENTION], ", ".join(refs[nwKeyWords.MENTION_KEY]))
|
742
|
+
|
743
|
+
self.addTopLevelItem(item)
|
721
744
|
|
722
745
|
self._lastBuild = time()
|
746
|
+
logger.debug("Project outline built in %.3f ms", 1000.0*(time() - tStart))
|
723
747
|
|
724
748
|
return
|
725
749
|
|
@@ -793,6 +817,10 @@ class GuiOutlineDetails(QScrollArea):
|
|
793
817
|
|
794
818
|
bFont = SHARED.theme.guiFontB
|
795
819
|
|
820
|
+
trStats1 = trConst(nwLabels.STATS_NAME[nwStats.CHARS_ALL])
|
821
|
+
trStats2 = trConst(nwLabels.STATS_NAME[nwStats.WORDS_ALL])
|
822
|
+
trStats3 = trConst(nwLabels.STATS_NAME[nwStats.PARAGRAPHS])
|
823
|
+
|
796
824
|
# Details Area
|
797
825
|
self.titleLabel = QLabel(self.tr("Title"), self)
|
798
826
|
self.fileLabel = QLabel(self.tr("Document"), self)
|
@@ -813,9 +841,9 @@ class GuiOutlineDetails(QScrollArea):
|
|
813
841
|
self.itemValue.setMaximumWidth(maxTitle)
|
814
842
|
|
815
843
|
# Stats Area
|
816
|
-
self.cCLabel = QLabel(
|
817
|
-
self.wCLabel = QLabel(
|
818
|
-
self.pCLabel = QLabel(
|
844
|
+
self.cCLabel = QLabel(trStats1, self)
|
845
|
+
self.wCLabel = QLabel(trStats2, self)
|
846
|
+
self.pCLabel = QLabel(trStats3, self)
|
819
847
|
self.cCValue = QLabel("", self)
|
820
848
|
self.wCValue = QLabel("", self)
|
821
849
|
self.pCValue = QLabel("", self)
|
@@ -842,96 +870,25 @@ class GuiOutlineDetails(QScrollArea):
|
|
842
870
|
self.synopLWrap = QHBoxLayout()
|
843
871
|
self.synopLWrap.addWidget(self.synopValue, 1)
|
844
872
|
|
845
|
-
# Tags
|
846
|
-
self.povKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.POV_KEY]), self)
|
847
|
-
self.focKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.FOCUS_KEY]), self)
|
848
|
-
self.chrKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.CHAR_KEY]), self)
|
849
|
-
self.pltKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.PLOT_KEY]), self)
|
850
|
-
self.timKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.TIME_KEY]), self)
|
851
|
-
self.wldKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.WORLD_KEY]), self)
|
852
|
-
self.objKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.OBJECT_KEY]), self)
|
853
|
-
self.entKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.ENTITY_KEY]), self)
|
854
|
-
self.cstKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.CUSTOM_KEY]), self)
|
855
|
-
|
856
|
-
self.povKeyLabel.setFont(bFont)
|
857
|
-
self.focKeyLabel.setFont(bFont)
|
858
|
-
self.chrKeyLabel.setFont(bFont)
|
859
|
-
self.pltKeyLabel.setFont(bFont)
|
860
|
-
self.timKeyLabel.setFont(bFont)
|
861
|
-
self.wldKeyLabel.setFont(bFont)
|
862
|
-
self.objKeyLabel.setFont(bFont)
|
863
|
-
self.entKeyLabel.setFont(bFont)
|
864
|
-
self.cstKeyLabel.setFont(bFont)
|
865
|
-
|
866
|
-
self.povKeyLWrap = QHBoxLayout()
|
867
|
-
self.focKeyLWrap = QHBoxLayout()
|
868
|
-
self.chrKeyLWrap = QHBoxLayout()
|
869
|
-
self.pltKeyLWrap = QHBoxLayout()
|
870
|
-
self.timKeyLWrap = QHBoxLayout()
|
871
|
-
self.wldKeyLWrap = QHBoxLayout()
|
872
|
-
self.objKeyLWrap = QHBoxLayout()
|
873
|
-
self.entKeyLWrap = QHBoxLayout()
|
874
|
-
self.cstKeyLWrap = QHBoxLayout()
|
875
|
-
|
876
|
-
self.povKeyValue = QLabel("", self)
|
877
|
-
self.focKeyValue = QLabel("", self)
|
878
|
-
self.chrKeyValue = QLabel("", self)
|
879
|
-
self.pltKeyValue = QLabel("", self)
|
880
|
-
self.timKeyValue = QLabel("", self)
|
881
|
-
self.wldKeyValue = QLabel("", self)
|
882
|
-
self.objKeyValue = QLabel("", self)
|
883
|
-
self.entKeyValue = QLabel("", self)
|
884
|
-
self.cstKeyValue = QLabel("", self)
|
885
|
-
|
886
|
-
self.povKeyValue.setWordWrap(True)
|
887
|
-
self.focKeyValue.setWordWrap(True)
|
888
|
-
self.chrKeyValue.setWordWrap(True)
|
889
|
-
self.pltKeyValue.setWordWrap(True)
|
890
|
-
self.timKeyValue.setWordWrap(True)
|
891
|
-
self.wldKeyValue.setWordWrap(True)
|
892
|
-
self.objKeyValue.setWordWrap(True)
|
893
|
-
self.entKeyValue.setWordWrap(True)
|
894
|
-
self.cstKeyValue.setWordWrap(True)
|
895
|
-
|
896
|
-
self.povKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
|
897
|
-
self.focKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
|
898
|
-
self.chrKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
|
899
|
-
self.pltKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
|
900
|
-
self.timKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
|
901
|
-
self.wldKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
|
902
|
-
self.objKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
|
903
|
-
self.entKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
|
904
|
-
self.cstKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
|
905
|
-
|
906
|
-
self.povKeyLWrap.addWidget(self.povKeyValue, 1)
|
907
|
-
self.focKeyLWrap.addWidget(self.focKeyValue, 1)
|
908
|
-
self.chrKeyLWrap.addWidget(self.chrKeyValue, 1)
|
909
|
-
self.pltKeyLWrap.addWidget(self.pltKeyValue, 1)
|
910
|
-
self.timKeyLWrap.addWidget(self.timKeyValue, 1)
|
911
|
-
self.wldKeyLWrap.addWidget(self.wldKeyValue, 1)
|
912
|
-
self.objKeyLWrap.addWidget(self.objKeyValue, 1)
|
913
|
-
self.entKeyLWrap.addWidget(self.entKeyValue, 1)
|
914
|
-
self.cstKeyLWrap.addWidget(self.cstKeyValue, 1)
|
915
|
-
|
916
873
|
# Selected Item Details
|
917
|
-
self.mainGroup = QGroupBox(self.tr("Title Details"), self)
|
918
874
|
self.mainForm = QGridLayout()
|
875
|
+
self.mainGroup = QGroupBox(self.tr("Title Details"), self)
|
919
876
|
self.mainGroup.setLayout(self.mainForm)
|
920
877
|
|
921
|
-
self.mainForm.addWidget(self.titleLabel,
|
922
|
-
self.mainForm.addWidget(self.titleValue,
|
923
|
-
self.mainForm.addWidget(self.cCLabel,
|
924
|
-
self.mainForm.addWidget(self.cCValue,
|
925
|
-
self.mainForm.addWidget(self.fileLabel,
|
926
|
-
self.mainForm.addWidget(self.fileValue,
|
927
|
-
self.mainForm.addWidget(self.wCLabel,
|
928
|
-
self.mainForm.addWidget(self.wCValue,
|
929
|
-
self.mainForm.addWidget(self.itemLabel,
|
930
|
-
self.mainForm.addWidget(self.itemValue,
|
931
|
-
self.mainForm.addWidget(self.pCLabel,
|
932
|
-
self.mainForm.addWidget(self.pCValue,
|
933
|
-
self.mainForm.addWidget(self.synopLabel,
|
934
|
-
self.mainForm.addLayout(self.synopLWrap,
|
878
|
+
self.mainForm.addWidget(self.titleLabel, 0, 0, 1, 1, QtAlignLeftTop)
|
879
|
+
self.mainForm.addWidget(self.titleValue, 0, 1, 1, 1, QtAlignLeftTop)
|
880
|
+
self.mainForm.addWidget(self.cCLabel, 0, 2, 1, 1, QtAlignLeftTop)
|
881
|
+
self.mainForm.addWidget(self.cCValue, 0, 3, 1, 1, QtAlignRightTop)
|
882
|
+
self.mainForm.addWidget(self.fileLabel, 1, 0, 1, 1, QtAlignLeftTop)
|
883
|
+
self.mainForm.addWidget(self.fileValue, 1, 1, 1, 1, QtAlignLeftTop)
|
884
|
+
self.mainForm.addWidget(self.wCLabel, 1, 2, 1, 1, QtAlignLeftTop)
|
885
|
+
self.mainForm.addWidget(self.wCValue, 1, 3, 1, 1, QtAlignRightTop)
|
886
|
+
self.mainForm.addWidget(self.itemLabel, 2, 0, 1, 1, QtAlignLeftTop)
|
887
|
+
self.mainForm.addWidget(self.itemValue, 2, 1, 1, 1, QtAlignLeftTop)
|
888
|
+
self.mainForm.addWidget(self.pCLabel, 2, 2, 1, 1, QtAlignLeftTop)
|
889
|
+
self.mainForm.addWidget(self.pCValue, 2, 3, 1, 1, QtAlignRightTop)
|
890
|
+
self.mainForm.addWidget(self.synopLabel, 3, 0, 1, 4, QtAlignLeftTop)
|
891
|
+
self.mainForm.addLayout(self.synopLWrap, 4, 0, 1, 4, QtAlignLeftTop)
|
935
892
|
|
936
893
|
self.mainForm.setColumnStretch(1, 1)
|
937
894
|
self.mainForm.setRowStretch(4, 1)
|
@@ -939,45 +896,40 @@ class GuiOutlineDetails(QScrollArea):
|
|
939
896
|
self.mainForm.setVerticalSpacing(vSpace)
|
940
897
|
|
941
898
|
# Selected Item Tags
|
942
|
-
self.tagsGroup = QGroupBox(self.tr("Reference Tags"), self)
|
943
899
|
self.tagsForm = QGridLayout()
|
900
|
+
self.tagsGroup = QGroupBox(self.tr("Reference Tags"), self)
|
944
901
|
self.tagsGroup.setLayout(self.tagsForm)
|
945
902
|
|
946
|
-
self.
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
self.tagsForm.addLayout(self.objKeyLWrap, 6, 1, 1, 1, QtAlignLeftTop)
|
960
|
-
self.tagsForm.addWidget(self.entKeyLabel, 7, 0, 1, 1, QtAlignLeftTop)
|
961
|
-
self.tagsForm.addLayout(self.entKeyLWrap, 7, 1, 1, 1, QtAlignLeftTop)
|
962
|
-
self.tagsForm.addWidget(self.cstKeyLabel, 8, 0, 1, 1, QtAlignLeftTop)
|
963
|
-
self.tagsForm.addLayout(self.cstKeyLWrap, 8, 1, 1, 1, QtAlignLeftTop)
|
903
|
+
self.tagValues: dict[str, tuple[QLabel, QLabel]] = {}
|
904
|
+
for key in nwKeyWords.ALL_KEYS:
|
905
|
+
label = QLabel(trConst(nwLabels.KEY_NAME[key]), self)
|
906
|
+
label.setFont(bFont)
|
907
|
+
value = QLabel("", self)
|
908
|
+
value.setWordWrap(True)
|
909
|
+
value.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
|
910
|
+
layout = QHBoxLayout()
|
911
|
+
layout.addWidget(value, 1)
|
912
|
+
n = len(self.tagValues)
|
913
|
+
self.tagsForm.addWidget(label, n, 0, QtAlignLeftTop)
|
914
|
+
self.tagsForm.addLayout(layout, n, 1, QtAlignLeftTop)
|
915
|
+
self.tagValues[key] = (label, value)
|
964
916
|
|
965
917
|
self.tagsForm.setColumnStretch(1, 1)
|
966
|
-
self.tagsForm.setRowStretch(
|
918
|
+
self.tagsForm.setRowStretch(len(self.tagValues), 1)
|
967
919
|
self.tagsForm.setHorizontalSpacing(hSpace)
|
968
920
|
self.tagsForm.setVerticalSpacing(vSpace)
|
969
921
|
|
970
922
|
# Assemble
|
971
|
-
self.
|
972
|
-
self.
|
973
|
-
self.
|
974
|
-
self.
|
923
|
+
self.mainSplit = QSplitter(Qt.Orientation.Horizontal)
|
924
|
+
self.mainSplit.addWidget(self.mainGroup)
|
925
|
+
self.mainSplit.addWidget(self.tagsGroup)
|
926
|
+
self.mainSplit.setCollapsible(0, False)
|
927
|
+
self.mainSplit.setCollapsible(1, False)
|
975
928
|
|
976
|
-
self.
|
977
|
-
self.setWidget(self.outerWidget)
|
929
|
+
self.setWidget(self.mainSplit)
|
978
930
|
|
979
|
-
self.setHorizontalScrollBarPolicy(
|
980
|
-
self.setVerticalScrollBarPolicy(
|
931
|
+
self.setHorizontalScrollBarPolicy(QtScrollAsNeeded)
|
932
|
+
self.setVerticalScrollBarPolicy(QtScrollAsNeeded)
|
981
933
|
self.setWidgetResizable(True)
|
982
934
|
self.setFrameStyle(QFrame.Shape.NoFrame)
|
983
935
|
|
@@ -990,35 +942,53 @@ class GuiOutlineDetails(QScrollArea):
|
|
990
942
|
def initSettings(self) -> None:
|
991
943
|
"""Set or update outline settings."""
|
992
944
|
if CONFIG.hideVScroll:
|
993
|
-
self.setVerticalScrollBarPolicy(
|
945
|
+
self.setVerticalScrollBarPolicy(QtScrollAlwaysOff)
|
994
946
|
else:
|
995
|
-
self.setVerticalScrollBarPolicy(
|
947
|
+
self.setVerticalScrollBarPolicy(QtScrollAsNeeded)
|
996
948
|
if CONFIG.hideHScroll:
|
997
|
-
self.setHorizontalScrollBarPolicy(
|
949
|
+
self.setHorizontalScrollBarPolicy(QtScrollAlwaysOff)
|
998
950
|
else:
|
999
|
-
self.setHorizontalScrollBarPolicy(
|
951
|
+
self.setHorizontalScrollBarPolicy(QtScrollAsNeeded)
|
1000
952
|
self.updateClasses()
|
1001
953
|
return
|
1002
954
|
|
955
|
+
def loadGuiSettings(self) -> None:
|
956
|
+
"""Run open project tasks."""
|
957
|
+
parent = self.outlineView.parent() # This widget is rendered already
|
958
|
+
width = parent.width() if isinstance(parent, QWidget) else 1000
|
959
|
+
pOptions = SHARED.project.options
|
960
|
+
self.mainSplit.setSizes([
|
961
|
+
CONFIG.pxInt(pOptions.getInt("GuiOutlineDetails", "detailsWidth", width//3)),
|
962
|
+
CONFIG.pxInt(pOptions.getInt("GuiOutlineDetails", "tagsWidth", 2*width//3))
|
963
|
+
])
|
964
|
+
return
|
965
|
+
|
966
|
+
def saveGuiSettings(self) -> None:
|
967
|
+
"""Run close project tasks."""
|
968
|
+
mainSplit = self.mainSplit.sizes()
|
969
|
+
detailsWidth = CONFIG.rpxInt(mainSplit[0])
|
970
|
+
tagsWidth = CONFIG.rpxInt(mainSplit[1])
|
971
|
+
|
972
|
+
logger.debug("Saving State: GuiOutlineDetails")
|
973
|
+
pOptions = SHARED.project.options
|
974
|
+
pOptions.setValue("GuiOutlineDetails", "detailsWidth", detailsWidth)
|
975
|
+
pOptions.setValue("GuiOutlineDetails", "tagsWidth", tagsWidth)
|
976
|
+
return
|
977
|
+
|
1003
978
|
def clearDetails(self) -> None:
|
1004
979
|
"""Clear all the data labels."""
|
1005
980
|
self.titleLabel.setText(self.tr("Title"))
|
1006
|
-
self.titleValue.
|
1007
|
-
self.fileValue.
|
1008
|
-
self.itemValue.
|
1009
|
-
self.cCValue.
|
1010
|
-
self.wCValue.
|
1011
|
-
self.pCValue.
|
1012
|
-
self.synopValue.
|
1013
|
-
|
1014
|
-
self.
|
1015
|
-
|
1016
|
-
|
1017
|
-
self.timKeyValue.setText("")
|
1018
|
-
self.wldKeyValue.setText("")
|
1019
|
-
self.objKeyValue.setText("")
|
1020
|
-
self.entKeyValue.setText("")
|
1021
|
-
self.cstKeyValue.setText("")
|
981
|
+
self.titleValue.clear()
|
982
|
+
self.fileValue.clear()
|
983
|
+
self.itemValue.clear()
|
984
|
+
self.cCValue.clear()
|
985
|
+
self.wCValue.clear()
|
986
|
+
self.pCValue.clear()
|
987
|
+
self.synopValue.clear()
|
988
|
+
|
989
|
+
for _, value in self.tagValues.values():
|
990
|
+
value.clear()
|
991
|
+
|
1022
992
|
self.updateClasses()
|
1023
993
|
return
|
1024
994
|
|
@@ -1050,15 +1020,8 @@ class GuiOutlineDetails(QScrollArea):
|
|
1050
1020
|
|
1051
1021
|
self.synopValue.setText(novIdx.synopsis)
|
1052
1022
|
|
1053
|
-
self.
|
1054
|
-
|
1055
|
-
self.chrKeyValue.setText(self._formatTags(novRefs, nwKeyWords.CHAR_KEY))
|
1056
|
-
self.pltKeyValue.setText(self._formatTags(novRefs, nwKeyWords.PLOT_KEY))
|
1057
|
-
self.timKeyValue.setText(self._formatTags(novRefs, nwKeyWords.TIME_KEY))
|
1058
|
-
self.wldKeyValue.setText(self._formatTags(novRefs, nwKeyWords.WORLD_KEY))
|
1059
|
-
self.objKeyValue.setText(self._formatTags(novRefs, nwKeyWords.OBJECT_KEY))
|
1060
|
-
self.entKeyValue.setText(self._formatTags(novRefs, nwKeyWords.ENTITY_KEY))
|
1061
|
-
self.cstKeyValue.setText(self._formatTags(novRefs, nwKeyWords.CUSTOM_KEY))
|
1023
|
+
for key, (_, value) in self.tagValues.items():
|
1024
|
+
value.setText(self._formatTags(novRefs, key))
|
1062
1025
|
|
1063
1026
|
return
|
1064
1027
|
|
@@ -1066,27 +1029,12 @@ class GuiOutlineDetails(QScrollArea):
|
|
1066
1029
|
def updateClasses(self) -> None:
|
1067
1030
|
"""Update the visibility status of class details."""
|
1068
1031
|
usedClasses = SHARED.project.tree.rootClasses()
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
cstVisible = nwItemClass.CUSTOM in usedClasses
|
1076
|
-
|
1077
|
-
self.pltKeyLabel.setVisible(pltVisible)
|
1078
|
-
self.pltKeyValue.setVisible(pltVisible)
|
1079
|
-
self.timKeyLabel.setVisible(timVisible)
|
1080
|
-
self.timKeyValue.setVisible(timVisible)
|
1081
|
-
self.wldKeyLabel.setVisible(wldVisible)
|
1082
|
-
self.wldKeyValue.setVisible(wldVisible)
|
1083
|
-
self.objKeyLabel.setVisible(objVisible)
|
1084
|
-
self.objKeyValue.setVisible(objVisible)
|
1085
|
-
self.entKeyLabel.setVisible(entVisible)
|
1086
|
-
self.entKeyValue.setVisible(entVisible)
|
1087
|
-
self.cstKeyLabel.setVisible(cstVisible)
|
1088
|
-
self.cstKeyValue.setVisible(cstVisible)
|
1089
|
-
|
1032
|
+
for key, itemClass in nwKeyWords.KEY_CLASS.items():
|
1033
|
+
visible = itemClass in usedClasses
|
1034
|
+
if key in self.tagValues:
|
1035
|
+
label, value = self.tagValues[key]
|
1036
|
+
label.setVisible(visible)
|
1037
|
+
value.setVisible(visible)
|
1090
1038
|
return
|
1091
1039
|
|
1092
1040
|
@staticmethod
|