novelWriter 2.2rc1__py3-none-any.whl → 2.3b1__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.2rc1.dist-info → novelWriter-2.3b1.dist-info}/METADATA +1 -1
- {novelWriter-2.2rc1.dist-info → novelWriter-2.3b1.dist-info}/RECORD +141 -129
- {novelWriter-2.2rc1.dist-info → novelWriter-2.3b1.dist-info}/WHEEL +1 -1
- novelwriter/__init__.py +11 -6
- novelwriter/assets/i18n/nw_de_DE.qm +0 -0
- novelwriter/assets/i18n/nw_en_US.qm +0 -0
- novelwriter/assets/i18n/nw_es_419.qm +0 -0
- novelwriter/assets/i18n/nw_fr_FR.qm +0 -0
- novelwriter/assets/i18n/nw_it_IT.qm +0 -0
- novelwriter/assets/i18n/nw_ja_JP.qm +0 -0
- novelwriter/assets/i18n/nw_nb_NO.qm +0 -0
- novelwriter/assets/i18n/nw_zh_CN.qm +0 -0
- novelwriter/assets/i18n/project_de_DE.json +1 -0
- novelwriter/assets/i18n/project_en_US.json +1 -0
- novelwriter/assets/i18n/project_es_419.json +11 -0
- novelwriter/assets/i18n/project_fr_FR.json +11 -0
- novelwriter/assets/i18n/project_it_IT.json +11 -0
- novelwriter/assets/i18n/project_ja_JP.json +2 -1
- novelwriter/assets/i18n/project_nb_NO.json +1 -0
- novelwriter/assets/i18n/project_zh_CN.json +11 -0
- novelwriter/assets/icons/typicons_dark/icons.conf +9 -2
- novelwriter/assets/icons/typicons_dark/mixed_import.svg +5 -0
- novelwriter/assets/icons/typicons_dark/nw_tb-bold-md.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_tb-bold.svg +3 -1
- novelwriter/assets/icons/typicons_dark/nw_tb-italic-md.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_tb-italic.svg +3 -1
- novelwriter/assets/icons/typicons_dark/nw_tb-strike-md.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_tb-strike.svg +3 -1
- novelwriter/assets/icons/typicons_dark/nw_tb-subscript.svg +4 -2
- novelwriter/assets/icons/typicons_dark/nw_tb-superscript.svg +4 -2
- novelwriter/assets/icons/typicons_dark/nw_tb-underline.svg +4 -2
- novelwriter/assets/icons/typicons_dark/typ_document-add-col.svg +8 -0
- novelwriter/assets/icons/typicons_dark/typ_document-add.svg +4 -0
- novelwriter/assets/icons/typicons_dark/typ_document.svg +4 -0
- novelwriter/assets/icons/typicons_dark/typ_th-dot-more.svg +4 -0
- novelwriter/assets/icons/typicons_light/icons.conf +9 -2
- novelwriter/assets/icons/typicons_light/mixed_import.svg +5 -0
- novelwriter/assets/icons/typicons_light/nw_tb-bold-md.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_tb-bold.svg +3 -1
- novelwriter/assets/icons/typicons_light/nw_tb-italic-md.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_tb-italic.svg +3 -1
- novelwriter/assets/icons/typicons_light/nw_tb-strike-md.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_tb-strike.svg +3 -1
- novelwriter/assets/icons/typicons_light/nw_tb-subscript.svg +4 -2
- novelwriter/assets/icons/typicons_light/nw_tb-superscript.svg +4 -2
- novelwriter/assets/icons/typicons_light/nw_tb-underline.svg +4 -2
- novelwriter/assets/icons/typicons_light/typ_document-add-col.svg +8 -0
- novelwriter/assets/icons/typicons_light/typ_document-add.svg +4 -0
- novelwriter/assets/icons/typicons_light/typ_document.svg +4 -0
- novelwriter/assets/icons/typicons_light/typ_th-dot-more.svg +4 -0
- novelwriter/assets/images/novelwriter-text-dark.svg +4 -0
- novelwriter/assets/images/novelwriter-text-light.svg +4 -0
- novelwriter/assets/images/welcome-dark.jpg +0 -0
- novelwriter/assets/images/welcome-light.jpg +0 -0
- novelwriter/assets/manual.pdf +0 -0
- novelwriter/assets/sample.zip +0 -0
- novelwriter/assets/syntax/default_dark.conf +1 -0
- novelwriter/assets/syntax/default_light.conf +1 -0
- novelwriter/assets/syntax/grey_dark.conf +1 -0
- novelwriter/assets/syntax/grey_light.conf +1 -0
- novelwriter/assets/syntax/light_owl.conf +1 -0
- novelwriter/assets/syntax/night_owl.conf +1 -0
- novelwriter/assets/syntax/solarized_dark.conf +1 -0
- novelwriter/assets/syntax/solarized_light.conf +1 -0
- novelwriter/assets/syntax/tomorrow.conf +1 -0
- novelwriter/assets/syntax/tomorrow_night.conf +1 -0
- novelwriter/assets/syntax/tomorrow_night_blue.conf +1 -0
- novelwriter/assets/syntax/tomorrow_night_bright.conf +1 -0
- novelwriter/assets/syntax/tomorrow_night_eighties.conf +1 -0
- novelwriter/assets/text/credits_en.htm +4 -2
- novelwriter/assets/themes/default_dark.conf +2 -2
- novelwriter/assets/themes/default_light.conf +2 -2
- novelwriter/common.py +64 -66
- novelwriter/config.py +39 -44
- novelwriter/constants.py +39 -17
- novelwriter/core/buildsettings.py +8 -8
- novelwriter/core/coretools.py +194 -155
- novelwriter/core/docbuild.py +7 -4
- novelwriter/core/document.py +7 -7
- novelwriter/core/index.py +90 -57
- novelwriter/core/item.py +23 -5
- novelwriter/core/options.py +11 -10
- novelwriter/core/project.py +72 -47
- novelwriter/core/projectdata.py +3 -16
- novelwriter/core/projectxml.py +14 -42
- novelwriter/core/sessions.py +4 -3
- novelwriter/core/spellcheck.py +6 -4
- novelwriter/core/status.py +5 -4
- novelwriter/core/storage.py +179 -141
- novelwriter/core/tohtml.py +6 -4
- novelwriter/core/tokenizer.py +74 -46
- novelwriter/core/tomd.py +2 -2
- novelwriter/core/toodt.py +41 -31
- novelwriter/core/tree.py +5 -4
- novelwriter/dialogs/about.py +88 -179
- novelwriter/dialogs/docmerge.py +30 -20
- novelwriter/dialogs/docsplit.py +33 -22
- novelwriter/dialogs/editlabel.py +20 -8
- novelwriter/dialogs/preferences.py +562 -725
- novelwriter/dialogs/{projsettings.py → projectsettings.py} +301 -270
- novelwriter/dialogs/quotes.py +47 -36
- novelwriter/dialogs/wordlist.py +128 -59
- novelwriter/enum.py +25 -22
- novelwriter/error.py +2 -2
- novelwriter/extensions/circularprogress.py +12 -12
- novelwriter/extensions/configlayout.py +185 -146
- novelwriter/extensions/{wheeleventfilter.py → eventfilters.py} +15 -5
- novelwriter/extensions/modified.py +81 -0
- novelwriter/extensions/novelselector.py +27 -13
- novelwriter/extensions/pagedsidebar.py +15 -20
- novelwriter/extensions/simpleprogress.py +8 -9
- novelwriter/extensions/statusled.py +9 -9
- novelwriter/extensions/switch.py +32 -64
- novelwriter/extensions/switchbox.py +2 -7
- novelwriter/extensions/versioninfo.py +153 -0
- novelwriter/gui/doceditor.py +250 -214
- novelwriter/gui/dochighlight.py +66 -94
- novelwriter/gui/docviewer.py +71 -98
- novelwriter/gui/docviewerpanel.py +140 -47
- novelwriter/gui/editordocument.py +3 -3
- novelwriter/gui/itemdetails.py +9 -9
- novelwriter/gui/mainmenu.py +47 -46
- novelwriter/gui/noveltree.py +53 -61
- novelwriter/gui/outline.py +100 -76
- novelwriter/gui/projtree.py +193 -67
- novelwriter/gui/sidebar.py +9 -8
- novelwriter/gui/statusbar.py +49 -7
- novelwriter/gui/theme.py +65 -74
- novelwriter/guimain.py +173 -330
- novelwriter/shared.py +68 -30
- novelwriter/tools/dictionaries.py +7 -8
- novelwriter/tools/lipsum.py +34 -28
- novelwriter/tools/manusbuild.py +3 -4
- novelwriter/tools/manuscript.py +25 -32
- novelwriter/tools/manussettings.py +194 -225
- novelwriter/tools/noveldetails.py +525 -0
- novelwriter/tools/welcome.py +802 -0
- novelwriter/tools/writingstats.py +26 -13
- novelwriter/assets/icons/typicons_dark/nw_tb-markdown.svg +0 -8
- novelwriter/assets/icons/typicons_dark/nw_tb-shortcode.svg +0 -8
- novelwriter/assets/icons/typicons_light/nw_tb-markdown.svg +0 -8
- novelwriter/assets/icons/typicons_light/nw_tb-shortcode.svg +0 -8
- novelwriter/assets/images/wizard-back.jpg +0 -0
- novelwriter/assets/text/gplv3_en.htm +0 -641
- novelwriter/assets/text/release_notes.htm +0 -17
- novelwriter/dialogs/projdetails.py +0 -525
- novelwriter/dialogs/projload.py +0 -298
- novelwriter/dialogs/updates.py +0 -182
- novelwriter/extensions/pageddialog.py +0 -130
- novelwriter/tools/projwizard.py +0 -478
- {novelWriter-2.2rc1.dist-info → novelWriter-2.3b1.dist-info}/LICENSE.md +0 -0
- {novelWriter-2.2rc1.dist-info → novelWriter-2.3b1.dist-info}/entry_points.txt +0 -0
- {novelWriter-2.2rc1.dist-info → novelWriter-2.3b1.dist-info}/top_level.txt +0 -0
novelwriter/gui/noveltree.py
CHANGED
@@ -8,7 +8,7 @@ Created: 2022-06-12 [2.0rc1] GuiNovelView
|
|
8
8
|
Created: 2022-06-12 [2.0rc1] GuiNovelToolBar
|
9
9
|
|
10
10
|
This file is a part of novelWriter
|
11
|
-
Copyright 2018–
|
11
|
+
Copyright 2018–2024, Veronica Berglyd Olsen
|
12
12
|
|
13
13
|
This program is free software: you can redistribute it and/or modify
|
14
14
|
it under the terms of the GNU General Public License as published by
|
@@ -145,6 +145,7 @@ class GuiNovelView(QWidget):
|
|
145
145
|
"""Run closing project tasks."""
|
146
146
|
lastColType = self.novelTree.lastColType
|
147
147
|
lastColSize = self.novelTree.lastColSize
|
148
|
+
logger.debug("Saving State: GuiNovelView")
|
148
149
|
pOptions = SHARED.project.options
|
149
150
|
pOptions.setValue("GuiNovelView", "lastCol", lastColType)
|
150
151
|
pOptions.setValue("GuiNovelView", "lastColSize", lastColSize)
|
@@ -205,18 +206,19 @@ class GuiNovelToolBar(QWidget):
|
|
205
206
|
|
206
207
|
# Novel Selector
|
207
208
|
selFont = self.font()
|
208
|
-
selFont.setWeight(QFont.Bold)
|
209
|
-
|
209
|
+
selFont.setWeight(QFont.Weight.Bold)
|
210
|
+
|
210
211
|
self.novelValue = NovelSelector(self)
|
211
212
|
self.novelValue.setFont(selFont)
|
213
|
+
self.novelValue.setListFormat(self.tr("Outline of {0}"))
|
212
214
|
self.novelValue.setMinimumWidth(CONFIG.pxInt(150))
|
213
|
-
self.novelValue.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
215
|
+
self.novelValue.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
|
214
216
|
self.novelValue.novelSelectionChanged.connect(self.setCurrentRoot)
|
215
217
|
|
216
218
|
self.tbNovel = QToolButton(self)
|
217
219
|
self.tbNovel.setToolTip(self.tr("Novel Root"))
|
218
220
|
self.tbNovel.setIconSize(QSize(iPx, iPx))
|
219
|
-
self.tbNovel.clicked.connect(self.
|
221
|
+
self.tbNovel.clicked.connect(self.novelValue.showPopup)
|
220
222
|
|
221
223
|
# Refresh Button
|
222
224
|
self.tbRefresh = QToolButton(self)
|
@@ -243,7 +245,7 @@ class GuiNovelToolBar(QWidget):
|
|
243
245
|
self.tbMore.setToolTip(self.tr("More Options"))
|
244
246
|
self.tbMore.setIconSize(QSize(iPx, iPx))
|
245
247
|
self.tbMore.setMenu(self.mMore)
|
246
|
-
self.tbMore.setPopupMode(QToolButton.InstantPopup)
|
248
|
+
self.tbMore.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup)
|
247
249
|
|
248
250
|
# Assemble
|
249
251
|
self.outerBox = QHBoxLayout()
|
@@ -274,7 +276,7 @@ class GuiNovelToolBar(QWidget):
|
|
274
276
|
self.tbMore.setIcon(SHARED.theme.getIcon("menu"))
|
275
277
|
|
276
278
|
qPalette = self.palette()
|
277
|
-
qPalette.setBrush(QPalette.Window, qPalette.base())
|
279
|
+
qPalette.setBrush(QPalette.ColorRole.Window, qPalette.base())
|
278
280
|
self.setPalette(qPalette)
|
279
281
|
|
280
282
|
# StyleSheets
|
@@ -293,7 +295,7 @@ class GuiNovelToolBar(QWidget):
|
|
293
295
|
"QComboBox {border-style: none; padding-left: 0;} "
|
294
296
|
"QComboBox::drop-down {border-style: none}"
|
295
297
|
)
|
296
|
-
self.novelValue.
|
298
|
+
self.novelValue.refreshNovelList()
|
297
299
|
self.tbNovel.setVisible(self.novelValue.count() > 1)
|
298
300
|
|
299
301
|
return
|
@@ -306,7 +308,7 @@ class GuiNovelToolBar(QWidget):
|
|
306
308
|
|
307
309
|
def buildNovelRootMenu(self) -> None:
|
308
310
|
"""Build the novel root menu."""
|
309
|
-
self.novelValue.
|
311
|
+
self.novelValue.refreshNovelList()
|
310
312
|
self.tbNovel.setVisible(self.novelValue.count() > 1)
|
311
313
|
return
|
312
314
|
|
@@ -326,12 +328,6 @@ class GuiNovelToolBar(QWidget):
|
|
326
328
|
# Private Slots
|
327
329
|
##
|
328
330
|
|
329
|
-
@pyqtSlot()
|
330
|
-
def _openNovelSelector(self) -> None:
|
331
|
-
"""Trigger the dropdown list of the novel selector."""
|
332
|
-
self.novelValue.showPopup()
|
333
|
-
return
|
334
|
-
|
335
331
|
@pyqtSlot()
|
336
332
|
def _refreshNovelTree(self) -> None:
|
337
333
|
"""Rebuild the current tree."""
|
@@ -407,14 +403,14 @@ class GuiNovelTree(QTreeWidget):
|
|
407
403
|
cMg = CONFIG.pxInt(6)
|
408
404
|
|
409
405
|
self.setIconSize(QSize(iPx, iPx))
|
410
|
-
self.setFrameStyle(QFrame.NoFrame)
|
406
|
+
self.setFrameStyle(QFrame.Shape.NoFrame)
|
411
407
|
self.setUniformRowHeights(True)
|
412
408
|
self.setAllColumnsShowFocus(True)
|
413
409
|
self.setHeaderHidden(True)
|
414
410
|
self.setIndentation(0)
|
415
411
|
self.setColumnCount(4)
|
416
|
-
self.setSelectionBehavior(QAbstractItemView.SelectRows)
|
417
|
-
self.setSelectionMode(QAbstractItemView.SingleSelection)
|
412
|
+
self.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
|
413
|
+
self.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
|
418
414
|
self.setExpandsOnDoubleClick(False)
|
419
415
|
self.setDragEnabled(False)
|
420
416
|
|
@@ -422,10 +418,10 @@ class GuiNovelTree(QTreeWidget):
|
|
422
418
|
treeHeader = self.header()
|
423
419
|
treeHeader.setStretchLastSection(False)
|
424
420
|
treeHeader.setMinimumSectionSize(iPx + cMg)
|
425
|
-
treeHeader.setSectionResizeMode(self.C_TITLE, QHeaderView.Stretch)
|
426
|
-
treeHeader.setSectionResizeMode(self.C_WORDS, QHeaderView.ResizeToContents)
|
427
|
-
treeHeader.setSectionResizeMode(self.C_EXTRA, QHeaderView.ResizeToContents)
|
428
|
-
treeHeader.setSectionResizeMode(self.C_MORE, QHeaderView.ResizeToContents)
|
421
|
+
treeHeader.setSectionResizeMode(self.C_TITLE, QHeaderView.ResizeMode.Stretch)
|
422
|
+
treeHeader.setSectionResizeMode(self.C_WORDS, QHeaderView.ResizeMode.ResizeToContents)
|
423
|
+
treeHeader.setSectionResizeMode(self.C_EXTRA, QHeaderView.ResizeMode.ResizeToContents)
|
424
|
+
treeHeader.setSectionResizeMode(self.C_MORE, QHeaderView.ResizeMode.ResizeToContents)
|
429
425
|
|
430
426
|
# Pre-Generate Tree Formatting
|
431
427
|
fH1 = self.font()
|
@@ -454,14 +450,14 @@ class GuiNovelTree(QTreeWidget):
|
|
454
450
|
"""Set or update tree widget settings."""
|
455
451
|
# Scroll bars
|
456
452
|
if CONFIG.hideVScroll:
|
457
|
-
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
453
|
+
self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
458
454
|
else:
|
459
|
-
self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
455
|
+
self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
|
460
456
|
|
461
457
|
if CONFIG.hideHScroll:
|
462
|
-
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
458
|
+
self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
463
459
|
else:
|
464
|
-
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
460
|
+
self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
|
465
461
|
|
466
462
|
return
|
467
463
|
|
@@ -521,21 +517,16 @@ class GuiNovelTree(QTreeWidget):
|
|
521
517
|
|
522
518
|
def refreshHandle(self, tHandle: str) -> None:
|
523
519
|
"""Refresh the data for a given handle."""
|
524
|
-
idxData
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
self.refreshTree()
|
535
|
-
return
|
536
|
-
|
537
|
-
self._updateTreeItemValues(trItem, tHeading, tHandle, sTitle)
|
538
|
-
|
520
|
+
if idxData := SHARED.project.index.getItemData(tHandle):
|
521
|
+
logger.debug("Refreshing meta data for item '%s'", tHandle)
|
522
|
+
for sTitle, tHeading in idxData.items():
|
523
|
+
sKey = f"{tHandle}:{sTitle}"
|
524
|
+
if trItem := self._treeMap.get(sKey, None):
|
525
|
+
self._updateTreeItemValues(trItem, tHeading, tHandle, sTitle)
|
526
|
+
else:
|
527
|
+
logger.debug("Heading '%s' not in novel tree", sKey)
|
528
|
+
self.refreshTree()
|
529
|
+
return
|
539
530
|
return
|
540
531
|
|
541
532
|
def getSelectedHandle(self) -> tuple[str | None, str | None]:
|
@@ -566,27 +557,25 @@ class GuiNovelTree(QTreeWidget):
|
|
566
557
|
self._lastColSize = minmax(colSize, 15, 75)/100.0
|
567
558
|
return
|
568
559
|
|
569
|
-
def setActiveHandle(self, tHandle: str | None) -> None:
|
560
|
+
def setActiveHandle(self, tHandle: str | None, doScroll: bool = False) -> None:
|
570
561
|
"""Highlight the rows associated with a given handle."""
|
571
|
-
|
572
|
-
|
562
|
+
didScroll = False
|
573
563
|
self._actHandle = tHandle
|
574
564
|
for i in range(self.topLevelItemCount()):
|
575
|
-
tItem
|
576
|
-
if tItem is not None:
|
565
|
+
if tItem := self.topLevelItem(i):
|
577
566
|
if tItem.data(self.C_DATA, self.D_HANDLE) == tHandle:
|
578
567
|
tItem.setBackground(self.C_TITLE, self.palette().alternateBase())
|
579
568
|
tItem.setBackground(self.C_WORDS, self.palette().alternateBase())
|
580
569
|
tItem.setBackground(self.C_EXTRA, self.palette().alternateBase())
|
581
570
|
tItem.setBackground(self.C_MORE, self.palette().alternateBase())
|
571
|
+
if doScroll and not didScroll:
|
572
|
+
self.scrollToItem(tItem, QAbstractItemView.ScrollHint.PositionAtCenter)
|
573
|
+
didScroll = True
|
582
574
|
else:
|
583
575
|
tItem.setBackground(self.C_TITLE, self.palette().base())
|
584
576
|
tItem.setBackground(self.C_WORDS, self.palette().base())
|
585
577
|
tItem.setBackground(self.C_EXTRA, self.palette().base())
|
586
578
|
tItem.setBackground(self.C_MORE, self.palette().base())
|
587
|
-
|
588
|
-
logger.debug("Highlighted Novel Tree in %.3f ms", (time() - tStart)*1000)
|
589
|
-
|
590
579
|
return
|
591
580
|
|
592
581
|
##
|
@@ -600,12 +589,12 @@ class GuiNovelTree(QTreeWidget):
|
|
600
589
|
"""
|
601
590
|
super().mousePressEvent(event)
|
602
591
|
|
603
|
-
if event.button() == Qt.LeftButton:
|
592
|
+
if event.button() == Qt.MouseButton.LeftButton:
|
604
593
|
selItem = self.indexAt(event.pos())
|
605
594
|
if not selItem.isValid():
|
606
595
|
self.clearSelection()
|
607
596
|
|
608
|
-
elif event.button() == Qt.MiddleButton:
|
597
|
+
elif event.button() == Qt.MouseButton.MiddleButton:
|
609
598
|
selItem = self.itemAt(event.pos())
|
610
599
|
if not isinstance(selItem, QTreeWidgetItem):
|
611
600
|
return
|
@@ -636,7 +625,10 @@ class GuiNovelTree(QTreeWidget):
|
|
636
625
|
trItem = self.topLevelItem(i)
|
637
626
|
if isinstance(trItem, QTreeWidgetItem):
|
638
627
|
lastText = trItem.data(self.C_DATA, self.D_EXTRA)
|
639
|
-
trItem.setText(
|
628
|
+
trItem.setText(
|
629
|
+
self.C_EXTRA,
|
630
|
+
fMetric.elidedText(lastText, Qt.TextElideMode.ElideRight, eliW)
|
631
|
+
)
|
640
632
|
return
|
641
633
|
|
642
634
|
##
|
@@ -683,7 +675,7 @@ class GuiNovelTree(QTreeWidget):
|
|
683
675
|
tStart = time()
|
684
676
|
logger.debug("Building novel tree for root item '%s'", rootHandle)
|
685
677
|
|
686
|
-
novStruct = SHARED.project.index.novelStructure(rootHandle=rootHandle,
|
678
|
+
novStruct = SHARED.project.index.novelStructure(rootHandle=rootHandle, activeOnly=True)
|
687
679
|
for tKey, tHandle, sTitle, novIdx in novStruct:
|
688
680
|
if novIdx.level == "H0":
|
689
681
|
continue
|
@@ -692,7 +684,7 @@ class GuiNovelTree(QTreeWidget):
|
|
692
684
|
newItem.setData(self.C_DATA, self.D_HANDLE, tHandle)
|
693
685
|
newItem.setData(self.C_DATA, self.D_TITLE, sTitle)
|
694
686
|
newItem.setData(self.C_DATA, self.D_KEY, tKey)
|
695
|
-
newItem.setTextAlignment(self.C_WORDS, Qt.AlignRight)
|
687
|
+
newItem.setTextAlignment(self.C_WORDS, Qt.AlignmentFlag.AlignRight)
|
696
688
|
|
697
689
|
self._updateTreeItemValues(newItem, novIdx, tHandle, sTitle)
|
698
690
|
self._treeMap[tKey] = newItem
|
@@ -711,16 +703,16 @@ class GuiNovelTree(QTreeWidget):
|
|
711
703
|
iLevel = nwHeaders.H_LEVEL.get(idxItem.level, 0)
|
712
704
|
hDec = SHARED.theme.getHeaderDecoration(iLevel)
|
713
705
|
|
714
|
-
trItem.setData(self.C_TITLE, Qt.DecorationRole, hDec)
|
706
|
+
trItem.setData(self.C_TITLE, Qt.ItemDataRole.DecorationRole, hDec)
|
715
707
|
trItem.setText(self.C_TITLE, idxItem.title)
|
716
708
|
trItem.setFont(self.C_TITLE, self._hFonts[iLevel])
|
717
709
|
trItem.setText(self.C_WORDS, f"{idxItem.wordCount:n}")
|
718
|
-
trItem.setData(self.C_MORE, Qt.DecorationRole, self._pMore)
|
710
|
+
trItem.setData(self.C_MORE, Qt.ItemDataRole.DecorationRole, self._pMore)
|
719
711
|
|
720
712
|
# Custom column
|
721
713
|
mW = int(self._lastColSize * self.viewport().width())
|
722
714
|
lastText, toolTip = self._getLastColumnText(tHandle, sTitle)
|
723
|
-
elideText = self.fontMetrics().elidedText(lastText, Qt.ElideRight, mW)
|
715
|
+
elideText = self.fontMetrics().elidedText(lastText, Qt.TextElideMode.ElideRight, mW)
|
724
716
|
trItem.setText(self.C_EXTRA, elideText)
|
725
717
|
trItem.setData(self.C_DATA, self.D_EXTRA, lastText)
|
726
718
|
trItem.setToolTip(self.C_EXTRA, toolTip)
|
@@ -734,17 +726,17 @@ class GuiNovelTree(QTreeWidget):
|
|
734
726
|
|
735
727
|
refData = []
|
736
728
|
refName = ""
|
737
|
-
|
729
|
+
refs = SHARED.project.index.getReferences(tHandle, sTitle)
|
738
730
|
if self._lastCol == NovelTreeColumn.POV:
|
739
|
-
refData =
|
731
|
+
refData = refs[nwKeyWords.POV_KEY]
|
740
732
|
refName = self._povLabel
|
741
733
|
|
742
734
|
elif self._lastCol == NovelTreeColumn.FOCUS:
|
743
|
-
refData =
|
735
|
+
refData = refs[nwKeyWords.FOCUS_KEY]
|
744
736
|
refName = self._focLabel
|
745
737
|
|
746
738
|
elif self._lastCol == NovelTreeColumn.PLOT:
|
747
|
-
refData =
|
739
|
+
refData = refs[nwKeyWords.PLOT_KEY]
|
748
740
|
refName = self._pltLabel
|
749
741
|
|
750
742
|
if refData:
|
novelwriter/gui/outline.py
CHANGED
@@ -10,7 +10,7 @@ Created: 2019-11-16 [0.4.1] GuiOutlineHeaderMenu
|
|
10
10
|
Created: 2020-06-02 [0.7] GuiOutlineDetails
|
11
11
|
|
12
12
|
This file is a part of novelWriter
|
13
|
-
Copyright 2018–
|
13
|
+
Copyright 2018–2024, Veronica Berglyd Olsen
|
14
14
|
|
15
15
|
This program is free software: you can redistribute it and/or modify
|
16
16
|
it under the terms of the GNU General Public License as published by
|
@@ -27,18 +27,17 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
27
27
|
"""
|
28
28
|
from __future__ import annotations
|
29
29
|
|
30
|
+
import csv
|
30
31
|
import logging
|
31
32
|
|
32
33
|
from time import time
|
33
34
|
from enum import Enum
|
34
35
|
|
35
|
-
from PyQt5.QtCore import
|
36
|
-
Qt, pyqtSignal, pyqtSlot, QSize, QT_TRANSLATE_NOOP
|
37
|
-
)
|
36
|
+
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot, QSize, QT_TRANSLATE_NOOP
|
38
37
|
from PyQt5.QtWidgets import (
|
39
|
-
QAbstractItemView, QAction, QFrame, QGridLayout, QGroupBox,
|
40
|
-
QLabel, QMenu, QScrollArea, QSizePolicy, QSplitter, QToolBar,
|
41
|
-
QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
|
38
|
+
QAbstractItemView, QAction, QFileDialog, QFrame, QGridLayout, QGroupBox,
|
39
|
+
QHBoxLayout, QLabel, QMenu, QScrollArea, QSizePolicy, QSplitter, QToolBar,
|
40
|
+
QToolButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
|
42
41
|
)
|
43
42
|
|
44
43
|
from novelwriter import CONFIG, SHARED
|
@@ -46,7 +45,7 @@ from novelwriter.enum import (
|
|
46
45
|
nwDocMode, nwItemClass, nwItemLayout, nwItemType, nwOutline
|
47
46
|
)
|
48
47
|
from novelwriter.error import logException
|
49
|
-
from novelwriter.common import checkInt
|
48
|
+
from novelwriter.common import checkInt, formatFileFilter, makeFileNameSafe
|
50
49
|
from novelwriter.constants import nwHeaders, trConst, nwKeyWords, nwLabels
|
51
50
|
from novelwriter.extensions.novelselector import NovelSelector
|
52
51
|
|
@@ -88,6 +87,7 @@ class GuiOutlineView(QWidget):
|
|
88
87
|
self.outlineData.itemTagClicked.connect(self._tagClicked)
|
89
88
|
self.outlineBar.loadNovelRootRequest.connect(self._rootItemChanged)
|
90
89
|
self.outlineBar.viewColumnToggled.connect(self.outlineTree.menuColumnToggled)
|
90
|
+
self.outlineBar.outlineExportRequest.connect(self.outlineTree.exportOutline)
|
91
91
|
|
92
92
|
# Function Mappings
|
93
93
|
self.getSelectedHandle = self.outlineTree.getSelectedHandle
|
@@ -124,7 +124,7 @@ class GuiOutlineView(QWidget):
|
|
124
124
|
def openProjectTasks(self) -> None:
|
125
125
|
"""Run open project tasks."""
|
126
126
|
lastOutline = SHARED.project.data.getLastHandle("outline")
|
127
|
-
if not
|
127
|
+
if not lastOutline or lastOutline not in SHARED.project.tree:
|
128
128
|
lastOutline = SHARED.project.tree.findRoot(nwItemClass.NOVEL)
|
129
129
|
|
130
130
|
logger.debug("Setting outline tree to root item '%s'", lastOutline)
|
@@ -198,6 +198,7 @@ class GuiOutlineView(QWidget):
|
|
198
198
|
class GuiOutlineToolBar(QToolBar):
|
199
199
|
|
200
200
|
loadNovelRootRequest = pyqtSignal(str)
|
201
|
+
outlineExportRequest = pyqtSignal()
|
201
202
|
viewColumnToggled = pyqtSignal(bool, Enum)
|
202
203
|
|
203
204
|
def __init__(self, outlineView: GuiOutlineView) -> None:
|
@@ -220,6 +221,7 @@ class GuiOutlineToolBar(QToolBar):
|
|
220
221
|
self.novelLabel.setContentsMargins(0, 0, mPx, 0)
|
221
222
|
|
222
223
|
self.novelValue = NovelSelector(self)
|
224
|
+
self.novelValue.setIncludeAll(True)
|
223
225
|
self.novelValue.setMinimumWidth(CONFIG.pxInt(200))
|
224
226
|
self.novelValue.novelSelectionChanged.connect(self._novelValueChanged)
|
225
227
|
|
@@ -227,6 +229,9 @@ class GuiOutlineToolBar(QToolBar):
|
|
227
229
|
self.aRefresh = QAction(self.tr("Refresh"), self)
|
228
230
|
self.aRefresh.triggered.connect(self._refreshRequested)
|
229
231
|
|
232
|
+
self.aExport = QAction(self.tr("Export CSV"), self)
|
233
|
+
self.aExport.triggered.connect(self._exportRequested)
|
234
|
+
|
230
235
|
# Column Menu
|
231
236
|
self.mColumns = GuiOutlineHeaderMenu(self)
|
232
237
|
self.mColumns.columnToggled.connect(
|
@@ -242,6 +247,7 @@ class GuiOutlineToolBar(QToolBar):
|
|
242
247
|
self.addWidget(self.novelValue)
|
243
248
|
self.addSeparator()
|
244
249
|
self.addAction(self.aRefresh)
|
250
|
+
self.addAction(self.aExport)
|
245
251
|
self.addWidget(self.tbColumns)
|
246
252
|
self.addWidget(stretch)
|
247
253
|
|
@@ -258,15 +264,16 @@ class GuiOutlineToolBar(QToolBar):
|
|
258
264
|
def updateTheme(self) -> None:
|
259
265
|
"""Update theme elements."""
|
260
266
|
self.setStyleSheet("QToolBar {border: 0px;}")
|
261
|
-
self.novelValue.
|
267
|
+
self.novelValue.refreshNovelList()
|
262
268
|
self.aRefresh.setIcon(SHARED.theme.getIcon("refresh"))
|
269
|
+
self.aExport.setIcon(SHARED.theme.getIcon("export"))
|
263
270
|
self.tbColumns.setIcon(SHARED.theme.getIcon("menu"))
|
264
271
|
self.tbColumns.setStyleSheet("QToolButton::menu-indicator {image: none;}")
|
265
272
|
return
|
266
273
|
|
267
274
|
def populateNovelList(self) -> None:
|
268
275
|
"""Reload the content of the novel list."""
|
269
|
-
self.novelValue.
|
276
|
+
self.novelValue.refreshNovelList()
|
270
277
|
return
|
271
278
|
|
272
279
|
def setCurrentRoot(self, rootHandle: str | None) -> None:
|
@@ -295,6 +302,12 @@ class GuiOutlineToolBar(QToolBar):
|
|
295
302
|
self.loadNovelRootRequest.emit(self.novelValue.handle)
|
296
303
|
return
|
297
304
|
|
305
|
+
@pyqtSlot()
|
306
|
+
def _exportRequested(self) -> None:
|
307
|
+
"""Emit a signal that an export of the outline was requested."""
|
308
|
+
self.outlineExportRequest.emit()
|
309
|
+
return
|
310
|
+
|
298
311
|
# END Class GuiOutlineToolBar
|
299
312
|
|
300
313
|
|
@@ -491,15 +504,48 @@ class GuiOutlineTree(QTreeWidget):
|
|
491
504
|
"""Get the currently selected handle. If multiple items are
|
492
505
|
selected, return the first.
|
493
506
|
"""
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
sTitle = selItem[0].data(self._colIdx[nwOutline.TITLE], self.D_TITLE)
|
507
|
+
if item := self.selectedItems():
|
508
|
+
tHandle = item[0].data(self._colIdx[nwOutline.TITLE], self.D_HANDLE)
|
509
|
+
sTitle = item[0].data(self._colIdx[nwOutline.TITLE], self.D_TITLE)
|
498
510
|
return tHandle, sTitle
|
499
511
|
return None, None
|
500
512
|
|
501
513
|
##
|
502
|
-
# Slots
|
514
|
+
# Public Slots
|
515
|
+
##
|
516
|
+
|
517
|
+
@pyqtSlot(bool, Enum)
|
518
|
+
def menuColumnToggled(self, isChecked: bool, hItem: nwOutline) -> None:
|
519
|
+
"""Receive the changes to column visibility forwarded by the
|
520
|
+
column selection menu.
|
521
|
+
"""
|
522
|
+
if hItem in self._colIdx:
|
523
|
+
self.setColumnHidden(self._colIdx[hItem], not isChecked)
|
524
|
+
self._saveHeaderState()
|
525
|
+
return
|
526
|
+
|
527
|
+
@pyqtSlot()
|
528
|
+
def exportOutline(self) -> None:
|
529
|
+
"""Export the outline as a CSV file."""
|
530
|
+
path = CONFIG.lastPath() / f"{makeFileNameSafe(SHARED.project.data.name)}.csv"
|
531
|
+
path, _ = QFileDialog.getSaveFileName(
|
532
|
+
self, self.tr("Save Outline As"), str(path), formatFileFilter(["*.csv", "*"])
|
533
|
+
)
|
534
|
+
if path:
|
535
|
+
CONFIG.setLastPath(path)
|
536
|
+
logger.info("Writing CSV file: %s", path)
|
537
|
+
cols = [col for col in self._treeOrder if not self._colHidden[col]]
|
538
|
+
order = [self._colIdx[col] for col in cols]
|
539
|
+
with open(path, mode="w", newline="") as csvFile:
|
540
|
+
writer = csv.writer(csvFile, dialect="excel", quoting=csv.QUOTE_ALL)
|
541
|
+
writer.writerow([trConst(nwLabels.OUTLINE_COLS[col]) for col in cols])
|
542
|
+
for i in range(self.topLevelItemCount()):
|
543
|
+
if item := self.topLevelItem(i):
|
544
|
+
writer.writerow(item.text(i) for i in order)
|
545
|
+
return
|
546
|
+
|
547
|
+
##
|
548
|
+
# Private Slots
|
503
549
|
##
|
504
550
|
|
505
551
|
@pyqtSlot("QTreeWidgetItem*", int)
|
@@ -509,9 +555,8 @@ class GuiOutlineTree(QTreeWidget):
|
|
509
555
|
document editor.
|
510
556
|
"""
|
511
557
|
tHandle, sTitle = self.getSelectedHandle()
|
512
|
-
if tHandle
|
513
|
-
|
514
|
-
self.outlineView.openDocumentRequest.emit(tHandle, nwDocMode.EDIT, sTitle or "", True)
|
558
|
+
if tHandle:
|
559
|
+
self.outlineView.openDocumentRequest.emit(tHandle, nwDocMode.EDIT, sTitle or "", True)
|
515
560
|
return
|
516
561
|
|
517
562
|
@pyqtSlot()
|
@@ -535,16 +580,6 @@ class GuiOutlineTree(QTreeWidget):
|
|
535
580
|
self._saveHeaderState()
|
536
581
|
return
|
537
582
|
|
538
|
-
@pyqtSlot(bool, Enum)
|
539
|
-
def menuColumnToggled(self, isChecked: bool, hItem: nwOutline) -> None:
|
540
|
-
"""Receive the changes to column visibility forwarded by the
|
541
|
-
column selection menu.
|
542
|
-
"""
|
543
|
-
if hItem in self._colIdx:
|
544
|
-
self.setColumnHidden(self._colIdx[hItem], not isChecked)
|
545
|
-
self._saveHeaderState()
|
546
|
-
return
|
547
|
-
|
548
583
|
##
|
549
584
|
# Internal Functions
|
550
585
|
##
|
@@ -606,6 +641,7 @@ class GuiOutlineTree(QTreeWidget):
|
|
606
641
|
logHidden, orgWidth if logHidden and logWidth == 0 else logWidth
|
607
642
|
]
|
608
643
|
|
644
|
+
logger.debug("Saving State: GuiOutline")
|
609
645
|
pOptions = SHARED.project.options
|
610
646
|
pOptions.setValue("GuiOutline", "columnState", colState)
|
611
647
|
pOptions.saveSettings()
|
@@ -623,12 +659,12 @@ class GuiOutlineTree(QTreeWidget):
|
|
623
659
|
self.clear()
|
624
660
|
|
625
661
|
if self._firstView:
|
626
|
-
|
662
|
+
labels = []
|
627
663
|
for i, hItem in enumerate(self._treeOrder):
|
628
|
-
|
664
|
+
labels.append(trConst(nwLabels.OUTLINE_COLS[hItem]))
|
629
665
|
self._colIdx[hItem] = i
|
630
666
|
|
631
|
-
self.setHeaderLabels(
|
667
|
+
self.setHeaderLabels(labels)
|
632
668
|
for hItem in self._treeOrder:
|
633
669
|
self.setColumnWidth(self._colIdx[hItem], self._colWidth[hItem])
|
634
670
|
self.setColumnHidden(self._colIdx[hItem], self._colHidden[hItem])
|
@@ -645,7 +681,7 @@ class GuiOutlineTree(QTreeWidget):
|
|
645
681
|
headItem.setTextAlignment(
|
646
682
|
self._colIdx[nwOutline.PCOUNT], Qt.AlignmentFlag.AlignRight)
|
647
683
|
|
648
|
-
novStruct = SHARED.project.index.novelStructure(rootHandle=rootHandle,
|
684
|
+
novStruct = SHARED.project.index.novelStructure(rootHandle=rootHandle, activeOnly=True)
|
649
685
|
for _, tHandle, sTitle, novIdx in novStruct:
|
650
686
|
|
651
687
|
iLevel = nwHeaders.H_LEVEL.get(novIdx.level, 0)
|
@@ -841,18 +877,15 @@ class GuiOutlineDetails(QScrollArea):
|
|
841
877
|
self.entKeyValue.setWordWrap(True)
|
842
878
|
self.cstKeyValue.setWordWrap(True)
|
843
879
|
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
self.
|
848
|
-
self.
|
849
|
-
self.
|
850
|
-
self.
|
851
|
-
self.
|
852
|
-
self.
|
853
|
-
self.objKeyValue.linkActivated.connect(tagClicked)
|
854
|
-
self.entKeyValue.linkActivated.connect(tagClicked)
|
855
|
-
self.cstKeyValue.linkActivated.connect(tagClicked)
|
880
|
+
self.povKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
|
881
|
+
self.focKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
|
882
|
+
self.chrKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
|
883
|
+
self.pltKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
|
884
|
+
self.timKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
|
885
|
+
self.wldKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
|
886
|
+
self.objKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
|
887
|
+
self.entKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
|
888
|
+
self.cstKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
|
856
889
|
|
857
890
|
self.povKeyLWrap.addWidget(self.povKeyValue, 1)
|
858
891
|
self.focKeyLWrap.addWidget(self.focKeyValue, 1)
|
@@ -981,49 +1014,40 @@ class GuiOutlineDetails(QScrollArea):
|
|
981
1014
|
##
|
982
1015
|
|
983
1016
|
@pyqtSlot(str, str)
|
984
|
-
def showItem(self, tHandle: str, sTitle: str) ->
|
1017
|
+
def showItem(self, tHandle: str, sTitle: str) -> None:
|
985
1018
|
"""Update the content of the tree with the given handle and line
|
986
1019
|
number pointing to a header.
|
987
1020
|
"""
|
988
1021
|
pIndex = SHARED.project.index
|
989
1022
|
nwItem = SHARED.project.tree[tHandle]
|
990
1023
|
novIdx = pIndex.getItemHeader(tHandle, sTitle)
|
991
|
-
|
992
|
-
if nwItem
|
993
|
-
|
994
|
-
|
995
|
-
if novIdx.level in self.LVL_MAP:
|
996
|
-
self.titleLabel.setText("<b>%s</b>" % self.tr(self.LVL_MAP[novIdx.level]))
|
997
|
-
else:
|
998
|
-
self.titleLabel.setText("<b>%s</b>" % self.tr("Title"))
|
999
|
-
self.titleValue.setText(novIdx.title)
|
1024
|
+
novRefs = pIndex.getReferences(tHandle, sTitle)
|
1025
|
+
if nwItem and novIdx:
|
1026
|
+
self.titleLabel.setText("<b>%s</b>" % self.tr(self.LVL_MAP.get(novIdx.level, "H1")))
|
1027
|
+
self.titleValue.setText(novIdx.title)
|
1000
1028
|
|
1001
|
-
|
1029
|
+
itemStatus, _ = nwItem.getImportStatus(incIcon=False)
|
1002
1030
|
|
1003
|
-
|
1004
|
-
|
1031
|
+
self.fileValue.setText(nwItem.itemName)
|
1032
|
+
self.itemValue.setText(itemStatus)
|
1005
1033
|
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1034
|
+
self.cCValue.setText(f"{checkInt(novIdx.charCount, 0):n}")
|
1035
|
+
self.wCValue.setText(f"{checkInt(novIdx.wordCount, 0):n}")
|
1036
|
+
self.pCValue.setText(f"{checkInt(novIdx.paraCount, 0):n}")
|
1009
1037
|
|
1010
|
-
|
1011
|
-
self.wCValue.setText(f"{wC:n}")
|
1012
|
-
self.pCValue.setText(f"{pC:n}")
|
1038
|
+
self.synopValue.setText(novIdx.synopsis)
|
1013
1039
|
|
1014
|
-
|
1040
|
+
self.povKeyValue.setText(self._formatTags(novRefs, nwKeyWords.POV_KEY))
|
1041
|
+
self.focKeyValue.setText(self._formatTags(novRefs, nwKeyWords.FOCUS_KEY))
|
1042
|
+
self.chrKeyValue.setText(self._formatTags(novRefs, nwKeyWords.CHAR_KEY))
|
1043
|
+
self.pltKeyValue.setText(self._formatTags(novRefs, nwKeyWords.PLOT_KEY))
|
1044
|
+
self.timKeyValue.setText(self._formatTags(novRefs, nwKeyWords.TIME_KEY))
|
1045
|
+
self.wldKeyValue.setText(self._formatTags(novRefs, nwKeyWords.WORLD_KEY))
|
1046
|
+
self.objKeyValue.setText(self._formatTags(novRefs, nwKeyWords.OBJECT_KEY))
|
1047
|
+
self.entKeyValue.setText(self._formatTags(novRefs, nwKeyWords.ENTITY_KEY))
|
1048
|
+
self.cstKeyValue.setText(self._formatTags(novRefs, nwKeyWords.CUSTOM_KEY))
|
1015
1049
|
|
1016
|
-
|
1017
|
-
self.focKeyValue.setText(self._formatTags(theRefs, nwKeyWords.FOCUS_KEY))
|
1018
|
-
self.chrKeyValue.setText(self._formatTags(theRefs, nwKeyWords.CHAR_KEY))
|
1019
|
-
self.pltKeyValue.setText(self._formatTags(theRefs, nwKeyWords.PLOT_KEY))
|
1020
|
-
self.timKeyValue.setText(self._formatTags(theRefs, nwKeyWords.TIME_KEY))
|
1021
|
-
self.wldKeyValue.setText(self._formatTags(theRefs, nwKeyWords.WORLD_KEY))
|
1022
|
-
self.objKeyValue.setText(self._formatTags(theRefs, nwKeyWords.OBJECT_KEY))
|
1023
|
-
self.entKeyValue.setText(self._formatTags(theRefs, nwKeyWords.ENTITY_KEY))
|
1024
|
-
self.cstKeyValue.setText(self._formatTags(theRefs, nwKeyWords.CUSTOM_KEY))
|
1025
|
-
|
1026
|
-
return True
|
1050
|
+
return
|
1027
1051
|
|
1028
1052
|
@pyqtSlot()
|
1029
1053
|
def updateClasses(self) -> None:
|