novelWriter 2.6b1__py3-none-any.whl → 2.6b2__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.
Files changed (68) hide show
  1. {novelWriter-2.6b1.dist-info → novelWriter-2.6b2.dist-info}/METADATA +3 -3
  2. {novelWriter-2.6b1.dist-info → novelWriter-2.6b2.dist-info}/RECORD +68 -52
  3. {novelWriter-2.6b1.dist-info → novelWriter-2.6b2.dist-info}/WHEEL +1 -1
  4. novelwriter/__init__.py +49 -10
  5. novelwriter/assets/i18n/nw_de_DE.qm +0 -0
  6. novelwriter/assets/i18n/nw_pt_BR.qm +0 -0
  7. novelwriter/assets/i18n/nw_ru_RU.qm +0 -0
  8. novelwriter/assets/i18n/project_de_DE.json +2 -2
  9. novelwriter/assets/i18n/project_ru_RU.json +11 -0
  10. novelwriter/assets/icons/typicons_dark/icons.conf +7 -0
  11. novelwriter/assets/icons/typicons_dark/mixed_margin-bottom.svg +6 -0
  12. novelwriter/assets/icons/typicons_dark/mixed_margin-left.svg +6 -0
  13. novelwriter/assets/icons/typicons_dark/mixed_margin-right.svg +6 -0
  14. novelwriter/assets/icons/typicons_dark/mixed_margin-top.svg +6 -0
  15. novelwriter/assets/icons/typicons_dark/mixed_size-height.svg +6 -0
  16. novelwriter/assets/icons/typicons_dark/mixed_size-width.svg +6 -0
  17. novelwriter/assets/icons/typicons_dark/nw_toolbar.svg +5 -0
  18. novelwriter/assets/icons/typicons_light/icons.conf +7 -0
  19. novelwriter/assets/icons/typicons_light/mixed_margin-bottom.svg +6 -0
  20. novelwriter/assets/icons/typicons_light/mixed_margin-left.svg +6 -0
  21. novelwriter/assets/icons/typicons_light/mixed_margin-right.svg +6 -0
  22. novelwriter/assets/icons/typicons_light/mixed_margin-top.svg +6 -0
  23. novelwriter/assets/icons/typicons_light/mixed_size-height.svg +6 -0
  24. novelwriter/assets/icons/typicons_light/mixed_size-width.svg +6 -0
  25. novelwriter/assets/icons/typicons_light/nw_toolbar.svg +5 -0
  26. novelwriter/assets/manual.pdf +0 -0
  27. novelwriter/assets/sample.zip +0 -0
  28. novelwriter/assets/text/credits_en.htm +1 -0
  29. novelwriter/common.py +37 -2
  30. novelwriter/config.py +15 -12
  31. novelwriter/constants.py +24 -9
  32. novelwriter/core/coretools.py +111 -125
  33. novelwriter/core/docbuild.py +3 -2
  34. novelwriter/core/index.py +9 -19
  35. novelwriter/core/item.py +39 -6
  36. novelwriter/core/itemmodel.py +518 -0
  37. novelwriter/core/project.py +67 -89
  38. novelwriter/core/status.py +7 -5
  39. novelwriter/core/tree.py +268 -287
  40. novelwriter/dialogs/docmerge.py +7 -17
  41. novelwriter/dialogs/preferences.py +3 -3
  42. novelwriter/dialogs/projectsettings.py +2 -2
  43. novelwriter/enum.py +7 -0
  44. novelwriter/extensions/configlayout.py +6 -4
  45. novelwriter/formats/todocx.py +34 -38
  46. novelwriter/formats/tohtml.py +14 -15
  47. novelwriter/formats/tokenizer.py +21 -17
  48. novelwriter/formats/toodt.py +53 -124
  49. novelwriter/formats/toqdoc.py +92 -44
  50. novelwriter/gui/doceditor.py +230 -219
  51. novelwriter/gui/docviewer.py +38 -9
  52. novelwriter/gui/docviewerpanel.py +14 -22
  53. novelwriter/gui/itemdetails.py +17 -24
  54. novelwriter/gui/mainmenu.py +13 -8
  55. novelwriter/gui/noveltree.py +12 -12
  56. novelwriter/gui/outline.py +10 -11
  57. novelwriter/gui/projtree.py +548 -1202
  58. novelwriter/gui/search.py +9 -10
  59. novelwriter/gui/theme.py +7 -3
  60. novelwriter/guimain.py +59 -43
  61. novelwriter/shared.py +52 -23
  62. novelwriter/text/patterns.py +17 -5
  63. novelwriter/tools/manusbuild.py +13 -11
  64. novelwriter/tools/manussettings.py +42 -52
  65. novelwriter/types.py +7 -1
  66. {novelWriter-2.6b1.dist-info → novelWriter-2.6b2.dist-info}/LICENSE.md +0 -0
  67. {novelWriter-2.6b1.dist-info → novelWriter-2.6b2.dist-info}/entry_points.txt +0 -0
  68. {novelWriter-2.6b1.dist-info → novelWriter-2.6b2.dist-info}/top_level.txt +0 -0
@@ -31,13 +31,13 @@ from PyQt5.QtCore import QEvent, pyqtSignal, pyqtSlot
31
31
  from PyQt5.QtGui import QFont, QIcon, QSyntaxHighlighter, QTextCharFormat, QTextDocument
32
32
  from PyQt5.QtWidgets import (
33
33
  QAbstractButton, QAbstractItemView, QDialogButtonBox, QFrame, QGridLayout,
34
- QHBoxLayout, QHeaderView, QLabel, QLineEdit, QMenu, QPlainTextEdit,
35
- QPushButton, QSplitter, QStackedWidget, QTreeWidget, QTreeWidgetItem,
36
- QVBoxLayout, QWidget
34
+ QHBoxLayout, QLabel, QLineEdit, QMenu, QPlainTextEdit, QPushButton,
35
+ QSplitter, QStackedWidget, QTreeWidget, QTreeWidgetItem, QVBoxLayout,
36
+ QWidget
37
37
  )
38
38
 
39
39
  from novelwriter import CONFIG, SHARED
40
- from novelwriter.common import describeFont, qtLambda
40
+ from novelwriter.common import describeFont, fontMatcher, qtLambda
41
41
  from novelwriter.constants import nwHeadFmt, nwKeyWords, nwLabels, nwStyles, trConst
42
42
  from novelwriter.core.buildsettings import BuildSettings, FilterMode
43
43
  from novelwriter.extensions.configlayout import (
@@ -51,7 +51,8 @@ from novelwriter.extensions.switch import NSwitch
51
51
  from novelwriter.extensions.switchbox import NSwitchBox
52
52
  from novelwriter.types import (
53
53
  QtAlignCenter, QtAlignLeft, QtDialogApply, QtDialogClose, QtDialogSave,
54
- QtRoleAccept, QtRoleApply, QtRoleReject, QtUserRole
54
+ QtHeaderFixed, QtHeaderStretch, QtRoleAccept, QtRoleApply, QtRoleReject,
55
+ QtUserRole
55
56
  )
56
57
 
57
58
  if TYPE_CHECKING: # pragma: no cover
@@ -313,9 +314,9 @@ class _FilterTab(NFixedPage):
313
314
  treeHeader = self.optTree.header()
314
315
  treeHeader.setStretchLastSection(False)
315
316
  treeHeader.setMinimumSectionSize(iPx + cMg) # See Issue #1551
316
- treeHeader.setSectionResizeMode(self.C_NAME, QHeaderView.ResizeMode.Stretch)
317
- treeHeader.setSectionResizeMode(self.C_ACTIVE, QHeaderView.ResizeMode.Fixed)
318
- treeHeader.setSectionResizeMode(self.C_STATUS, QHeaderView.ResizeMode.Fixed)
317
+ treeHeader.setSectionResizeMode(self.C_NAME, QtHeaderStretch)
318
+ treeHeader.setSectionResizeMode(self.C_ACTIVE, QtHeaderFixed)
319
+ treeHeader.setSectionResizeMode(self.C_STATUS, QtHeaderFixed)
319
320
  treeHeader.resizeSection(self.C_ACTIVE, iPx + cMg)
320
321
  treeHeader.resizeSection(self.C_STATUS, iPx + cMg)
321
322
 
@@ -418,8 +419,7 @@ class _FilterTab(NFixedPage):
418
419
  logger.debug("Building project tree")
419
420
  self._treeMap = {}
420
421
  self.optTree.clear()
421
- for nwItem in SHARED.project.iterProjectItems():
422
-
422
+ for nwItem in SHARED.project.tree:
423
423
  tHandle = nwItem.itemHandle
424
424
  pHandle = nwItem.itemParent
425
425
  rHandle = nwItem.itemRoot
@@ -428,28 +428,15 @@ class _FilterTab(NFixedPage):
428
428
  continue
429
429
 
430
430
  isFile = nwItem.isFileType()
431
- isActive = nwItem.isActive
432
-
433
431
  if nwItem.isInactiveClass() or not self._build.isRootAllowed(rHandle):
434
432
  continue
435
433
 
436
- hLevel = nwItem.mainHeading
437
- itemIcon = SHARED.theme.getItemIcon(
438
- nwItem.itemType, nwItem.itemClass, nwItem.itemLayout, hLevel
439
- )
440
-
441
- if isFile:
442
- iconName = "checked" if isActive else "unchecked"
443
- else:
444
- iconName = "noncheckable"
445
-
446
434
  trItem = QTreeWidgetItem()
447
- trItem.setIcon(self.C_NAME, itemIcon)
435
+ trItem.setIcon(self.C_NAME, nwItem.getMainIcon())
448
436
  trItem.setText(self.C_NAME, nwItem.itemName)
449
437
  trItem.setData(self.C_DATA, self.D_HANDLE, tHandle)
450
438
  trItem.setData(self.C_DATA, self.D_FILE, isFile)
451
- trItem.setIcon(self.C_ACTIVE, SHARED.theme.getIcon(iconName))
452
-
439
+ trItem.setIcon(self.C_ACTIVE, nwItem.getActiveStatus()[1])
453
440
  trItem.setTextAlignment(self.C_NAME, QtAlignLeft)
454
441
 
455
442
  if pHandle is None and nwItem.isRootType():
@@ -496,11 +483,8 @@ class _FilterTab(NFixedPage):
496
483
  self.filterOpt.addLabel(self.tr("Select Root Folders"))
497
484
  for tHandle, nwItem in SHARED.project.tree.iterRoots(None):
498
485
  if not nwItem.isInactiveClass():
499
- itemIcon = SHARED.theme.getItemIcon(
500
- nwItem.itemType, nwItem.itemClass, nwItem.itemLayout
501
- )
502
486
  self.filterOpt.addItem(
503
- itemIcon, nwItem.itemName, f"root:{tHandle}",
487
+ nwItem.getMainIcon(), nwItem.itemName, f"root:{tHandle}",
504
488
  default=self._build.isRootAllowed(tHandle)
505
489
  )
506
490
 
@@ -964,15 +948,6 @@ class _FormattingTab(NScrollableForm):
964
948
  spW = 6*SHARED.theme.textNWidth
965
949
  dbW = 8*SHARED.theme.textNWidth
966
950
 
967
- # Common Translations
968
-
969
- trW = self.tr("W:") # Width
970
- trH = self.tr("H:") # Height
971
- trT = self.tr("T:") # Top
972
- trB = self.tr("B:") # Bottom
973
- trL = self.tr("L:") # Left
974
- trR = self.tr("R:") # Right
975
-
976
951
  # Text Content
977
952
  # ============
978
953
 
@@ -1084,6 +1059,13 @@ class _FormattingTab(NScrollableForm):
1084
1059
  self._sidebar.addButton(title, section)
1085
1060
  self.addGroupLabel(title, section)
1086
1061
 
1062
+ pixT = SHARED.theme.getPixmap("margin_top", (iPx, iPx))
1063
+ pixB = SHARED.theme.getPixmap("margin_bottom", (iPx, iPx))
1064
+ pixL = SHARED.theme.getPixmap("margin_left", (iPx, iPx))
1065
+ pixR = SHARED.theme.getPixmap("margin_right", (iPx, iPx))
1066
+ pixH = SHARED.theme.getPixmap("size_height", (iPx, iPx))
1067
+ pixW = SHARED.theme.getPixmap("size_width", (iPx, iPx))
1068
+
1087
1069
  # Title
1088
1070
  self.titleMarginT = NDoubleSpinBox(self)
1089
1071
  self.titleMarginT.setFixedWidth(dbW)
@@ -1093,7 +1075,8 @@ class _FormattingTab(NScrollableForm):
1093
1075
 
1094
1076
  self.addRow(
1095
1077
  trConst(nwStyles.T_LABEL["H0"]),
1096
- [trT, self.titleMarginT, 6, trB, self.titleMarginB],
1078
+ [pixT, self.titleMarginT, 6, pixB, self.titleMarginB],
1079
+ unit="em",
1097
1080
  )
1098
1081
 
1099
1082
  # Heading 1
@@ -1105,7 +1088,8 @@ class _FormattingTab(NScrollableForm):
1105
1088
 
1106
1089
  self.addRow(
1107
1090
  trConst(nwStyles.T_LABEL["H1"]),
1108
- [trT, self.h1MarginT, 6, trB, self.h1MarginB],
1091
+ [pixT, self.h1MarginT, 6, pixB, self.h1MarginB],
1092
+ unit="em",
1109
1093
  )
1110
1094
 
1111
1095
  # Heading 2
@@ -1117,7 +1101,8 @@ class _FormattingTab(NScrollableForm):
1117
1101
 
1118
1102
  self.addRow(
1119
1103
  trConst(nwStyles.T_LABEL["H2"]),
1120
- [trT, self.h2MarginT, 6, trB, self.h2MarginB],
1104
+ [pixT, self.h2MarginT, 6, pixB, self.h2MarginB],
1105
+ unit="em",
1121
1106
  )
1122
1107
 
1123
1108
  # Heading 3
@@ -1129,7 +1114,8 @@ class _FormattingTab(NScrollableForm):
1129
1114
 
1130
1115
  self.addRow(
1131
1116
  trConst(nwStyles.T_LABEL["H3"]),
1132
- [trT, self.h3MarginT, 6, trB, self.h3MarginB],
1117
+ [pixT, self.h3MarginT, 6, pixB, self.h3MarginB],
1118
+ unit="em",
1133
1119
  )
1134
1120
 
1135
1121
  # Heading 4
@@ -1141,7 +1127,8 @@ class _FormattingTab(NScrollableForm):
1141
1127
 
1142
1128
  self.addRow(
1143
1129
  trConst(nwStyles.T_LABEL["H4"]),
1144
- [trT, self.h4MarginT, 6, trB, self.h4MarginB],
1130
+ [pixT, self.h4MarginT, 6, pixB, self.h4MarginB],
1131
+ unit="em",
1145
1132
  )
1146
1133
 
1147
1134
  # Text
@@ -1153,7 +1140,8 @@ class _FormattingTab(NScrollableForm):
1153
1140
 
1154
1141
  self.addRow(
1155
1142
  trConst(nwStyles.T_LABEL["TT"]),
1156
- [trT, self.textMarginT, 6, trB, self.textMarginB],
1143
+ [pixT, self.textMarginT, 6, pixB, self.textMarginB],
1144
+ unit="em",
1157
1145
  )
1158
1146
 
1159
1147
  # Separator
@@ -1165,7 +1153,8 @@ class _FormattingTab(NScrollableForm):
1165
1153
 
1166
1154
  self.addRow(
1167
1155
  trConst(nwStyles.T_LABEL["SP"]),
1168
- [trT, self.sepMarginT, 6, trB, self.sepMarginB],
1156
+ [pixT, self.sepMarginT, 6, pixB, self.sepMarginB],
1157
+ unit="em",
1169
1158
  )
1170
1159
 
1171
1160
  # Page Layout
@@ -1198,7 +1187,7 @@ class _FormattingTab(NScrollableForm):
1198
1187
 
1199
1188
  self.addRow(
1200
1189
  self._build.getLabel("format.pageSize"),
1201
- [self.pageSize, 6, trW, self.pageWidth, 6, trH, self.pageHeight],
1190
+ [self.pageSize, 6, pixW, self.pageWidth, 6, pixH, self.pageHeight],
1202
1191
  )
1203
1192
 
1204
1193
  # Page Margins
@@ -1216,11 +1205,11 @@ class _FormattingTab(NScrollableForm):
1216
1205
 
1217
1206
  self.addRow(
1218
1207
  self._build.getLabel("format.pageMargins"),
1219
- [trT, self.topMargin, 6, trB, self.bottomMargin],
1208
+ [pixT, self.topMargin, 6, pixB, self.bottomMargin],
1220
1209
  )
1221
1210
  self.addRow(
1222
1211
  "",
1223
- [trL, self.leftMargin, 6, trR, self.rightMargin],
1212
+ [pixL, self.leftMargin, 6, pixR, self.rightMargin],
1224
1213
  )
1225
1214
 
1226
1215
  # Open Document
@@ -1292,8 +1281,9 @@ class _FormattingTab(NScrollableForm):
1292
1281
  # Text Format
1293
1282
  # ===========
1294
1283
 
1295
- self._textFont = QFont()
1296
- self._textFont.fromString(self._build.getStr("format.textFont"))
1284
+ font = QFont()
1285
+ font.fromString(self._build.getStr("format.textFont"))
1286
+ self._textFont = fontMatcher(font)
1297
1287
 
1298
1288
  self.textFont.setText(describeFont(self._textFont))
1299
1289
  self.textFont.setCursorPosition(0)
@@ -1448,9 +1438,9 @@ class _FormattingTab(NScrollableForm):
1448
1438
  """Open the QFontDialog and set a font for the font style."""
1449
1439
  font, status = SHARED.getFont(self._textFont, CONFIG.nativeFont)
1450
1440
  if status:
1451
- self.textFont.setText(describeFont(font))
1441
+ self._textFont = fontMatcher(font)
1442
+ self.textFont.setText(describeFont(self._textFont))
1452
1443
  self.textFont.setCursorPosition(0)
1453
- self._textFont = font
1454
1444
  return
1455
1445
 
1456
1446
  @pyqtSlot(int)
novelwriter/types.py CHANGED
@@ -28,7 +28,7 @@ from PyQt5.QtGui import (
28
28
  QColor, QFont, QPainter, QTextBlockFormat, QTextCharFormat, QTextCursor,
29
29
  QTextFormat
30
30
  )
31
- from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QSizePolicy, QStyle
31
+ from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QHeaderView, QSizePolicy, QStyle
32
32
 
33
33
  # Qt Alignment Flags
34
34
 
@@ -119,6 +119,12 @@ QtSizeIgnored = QSizePolicy.Policy.Ignored
119
119
  QtSizeMinimum = QSizePolicy.Policy.Minimum
120
120
  QtSizeMinimumExpanding = QSizePolicy.Policy.MinimumExpanding
121
121
 
122
+ # Resize Mode
123
+
124
+ QtHeaderStretch = QHeaderView.ResizeMode.Stretch
125
+ QtHeaderToContents = QHeaderView.ResizeMode.ResizeToContents
126
+ QtHeaderFixed = QHeaderView.ResizeMode.Fixed
127
+
122
128
  # Scroll Bar Policy
123
129
 
124
130
  QtScrollAlwaysOff = Qt.ScrollBarPolicy.ScrollBarAlwaysOff