Krita Source Code Documentation
Loading...
Searching...
No Matches
comics_export_dialog.py
Go to the documentation of this file.
1"""
2SPDX-FileCopyrightText: 2017 Wolthera van Hövell tot Westerflier <griffinvalley@gmail.com>
3
4This file is part of the Comics Project Management Tools(CPMT).
5
6SPDX-License-Identifier: GPL-3.0-or-later
7"""
8
9"""
10A dialog for editing the exporter settings.
11"""
12
13from enum import IntEnum
14try:
15 from PyQt6.QtGui import QStandardItem, QStandardItemModel, QColor, QFont, QIcon, QPixmap
16 from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QGroupBox, QFormLayout, QCheckBox, QComboBox, QSpinBox, QWidget, QVBoxLayout, QHBoxLayout, QTabWidget, QPushButton, QLineEdit, QLabel, QListView, QTableView, QFontComboBox, QColorDialog, QStyledItemDelegate
17 from PyQt6.QtCore import Qt, QUuid
18except:
19 from PyQt5.QtGui import QStandardItem, QStandardItemModel, QColor, QFont, QIcon, QPixmap
20 from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QGroupBox, QFormLayout, QCheckBox, QComboBox, QSpinBox, QWidget, QVBoxLayout, QHBoxLayout, QTabWidget, QPushButton, QLineEdit, QLabel, QListView, QTableView, QFontComboBox, QColorDialog, QStyledItemDelegate
21 from PyQt5.QtCore import Qt, QUuid
22from builtins import i18n, Application
23
24"""
25A generic widget to make selecting size easier.
26It works by initialising with a config name(like "scale"), and then optionally setting the config with a dictionary.
27Then, afterwards, you get the config with a dictionary, with the config name being the entry the values are under.
28"""
29
30
32 configName = ""
33
34 def __init__(self, configName, batch=False, fileType=True):
35 super().__init__()
36 self.configNameconfigName = configName
37 self.setTitle(i18n("Adjust Working File"))
38 formLayout = QFormLayout()
39 self.setLayout(formLayout)
40 self.crop = QCheckBox(i18n("Crop files before resize"))
41 self.cmbFile = QComboBox()
42 self.cmbFile.addItems(["png", "jpg", "webp"])
43 self.resizeMethod = QComboBox()
44 self.resizeMethod.addItems([i18n("Percentage"), i18n("DPI"), i18n("Maximum Width"), i18n("Maximum Height")])
45 self.resizeMethod.currentIndexChanged.connect(self.slot_set_enabledslot_set_enabled)
46 self.spn_DPI = QSpinBox()
47 self.spn_DPI.setMaximum(1200)
48 self.spn_DPI.setSuffix(i18n(" DPI"))
49 self.spn_DPI.setValue(72)
50 self.spn_PER = QSpinBox()
51 if batch is True:
52 self.spn_PER.setMaximum(1000)
53 else:
54 self.spn_PER.setMaximum(100)
55 self.spn_PER.setSuffix(" %")
56 self.spn_PER.setValue(100)
57 self.spn_width = QSpinBox()
58 self.spn_width.setMaximum(99999)
59 self.spn_width.setSuffix(" px")
60 self.spn_width.setValue(800)
61 self.spn_height = QSpinBox()
62 self.spn_height.setMaximum(99999)
63 self.spn_height.setSuffix(" px")
64 self.spn_height.setValue(800)
65
66 if batch is False:
67 formLayout.addRow("", self.crop)
68 if fileType is True and configName != "TIFF":
69 formLayout.addRow(i18n("File Type"), self.cmbFile)
70 formLayout.addRow(i18n("Method:"), self.resizeMethod)
71 formLayout.addRow(i18n("DPI:"), self.spn_DPI)
72 formLayout.addRow(i18n("Percentage:"), self.spn_PER)
73 formLayout.addRow(i18n("Width:"), self.spn_width)
74 formLayout.addRow(i18n("Height:"), self.spn_height)
76
78 method = self.resizeMethod.currentIndex()
79 self.spn_DPI.setEnabled(False)
80 self.spn_PER.setEnabled(False)
81 self.spn_width.setEnabled(False)
82 self.spn_height.setEnabled(False)
83
84 if method == 0:
85 self.spn_PER.setEnabled(True)
86 if method == 1:
87 self.spn_DPI.setEnabled(True)
88 if method == 2:
89 self.spn_width.setEnabled(True)
90 if method == 3:
91 self.spn_height.setEnabled(True)
92
93 def set_config(self, config):
94 if self.configNameconfigName in config.keys():
95 mConfig = config[self.configNameconfigName]
96 if "Method" in mConfig.keys():
97 self.resizeMethod.setCurrentIndex(mConfig["Method"])
98 if "FileType" in mConfig.keys():
99 self.cmbFile.setCurrentText(mConfig["FileType"])
100 if "Crop" in mConfig.keys():
101 self.crop.setChecked(mConfig["Crop"])
102 if "DPI" in mConfig.keys():
103 self.spn_DPI.setValue(mConfig["DPI"])
104 if "Percentage" in mConfig.keys():
105 self.spn_PER.setValue(mConfig["Percentage"])
106 if "Width" in mConfig.keys():
107 self.spn_width.setValue(mConfig["Width"])
108 if "Height" in mConfig.keys():
109 self.spn_height.setValue(mConfig["Height"])
111
112 def get_config(self, config):
113 mConfig = {}
114 mConfig["Method"] = self.resizeMethod.currentIndex()
115 if self.configNameconfigName == "TIFF":
116 mConfig["FileType"] = "tiff"
117 else:
118 mConfig["FileType"] = self.cmbFile.currentText()
119 mConfig["Crop"] = self.crop.isChecked()
120 mConfig["DPI"] = self.spn_DPI.value()
121 mConfig["Percentage"] = self.spn_PER.value()
122 mConfig["Width"] = self.spn_width.value()
123 mConfig["Height"] = self.spn_height.value()
124 config[self.configNameconfigName] = mConfig
125 return config
126
127
128"""
129Quick combobox for selecting the color label.
130"""
131
132
133class labelSelector(QComboBox):
134 def __init__(self):
135 super(labelSelector, self).__init__()
136 lisOfColors = []
137 lisOfColors.append(Qt.GlobalColor.transparent)
138 lisOfColors.append(QColor(91, 173, 220))
139 lisOfColors.append(QColor(151, 202, 63))
140 lisOfColors.append(QColor(247, 229, 61))
141 lisOfColors.append(QColor(255, 170, 63))
142 lisOfColors.append(QColor(177, 102, 63))
143 lisOfColors.append(QColor(238, 50, 51))
144 lisOfColors.append(QColor(191, 106, 209))
145 lisOfColors.append(QColor(118, 119, 114))
146
147 self.itemModel = QStandardItemModel()
148 for color in lisOfColors:
149 item = QStandardItem()
150 item.setFlags(Qt.ItemFlag.ItemIsUserCheckable | Qt.ItemFlag.ItemIsEnabled)
151 item.setCheckState(Qt.CheckState.Unchecked)
152 item.setText(" ")
153 item.setData(color, Qt.ItemDataRole.BackgroundRole)
154 self.itemModel.appendRow(item)
155 self.setModel(self.itemModel)
156
157 def getLabels(self):
158 listOfIndexes = []
159 for i in range(self.itemModel.rowCount()):
160 index = self.itemModel.index(i, 0)
161 item = self.itemModel.itemFromIndex(index)
162 if item.checkState():
163 listOfIndexes.append(i)
164 return listOfIndexes
165
166 def setLabels(self, listOfIndexes):
167 for i in listOfIndexes:
168 index = self.itemModel.index(i, 0)
169 item = self.itemModel.itemFromIndex(index)
170 item.setCheckState(True)
171
172"""
173Little Enum to keep track of where in the item we add styles.
174"""
175class styleEnum(IntEnum):
176 FONT = Qt.ItemDataRole.UserRole + 1
177 FONTLIST = Qt.ItemDataRole.UserRole + 2
178 FONTGENERIC = Qt.ItemDataRole.UserRole + 3
179 BOLD = Qt.ItemDataRole.UserRole + 4
180 ITALIC = Qt.ItemDataRole.UserRole + 5
181"""
182A simple delegate to allows editing fonts with a QFontComboBox
183"""
184class font_list_delegate(QStyledItemDelegate):
185 def __init__(self, parent=None):
186 super(QStyledItemDelegate, self).__init__(parent)
187 def createEditor(self, parent, option, index):
188 editor = QFontComboBox(parent)
189 return editor
190
191"""
192The comic export settings dialog will allow configuring the export.
193
194This config consists of...
195
196* Crop settings. for removing bleeds.
197* Selecting layer labels to remove.
198* Choosing which formats to export to.
199 * Choosing how to resize these
200 * Whether to crop.
201 * Which file type to use.
202
203And for ACBF, it gives the ability to edit acbf document info.
204
205"""
206
207
209 acbfStylesList = ["speech", "commentary", "formal", "letter", "code", "heading", "audio", "thought", "sign", "sound", "emphasis", "strong"]
210
211 def __init__(self):
212 super().__init__()
213 self.setLayout(QVBoxLayout())
214 self.setWindowTitle(i18n("Export Settings"))
215 buttons = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
216
217 buttons.accepted.connect(self.accept)
218 buttons.rejected.connect(self.reject)
219 mainWidget = QTabWidget()
220 self.layout().addWidget(mainWidget)
221 self.layout().addWidget(buttons)
222
223 # Set basic crop settings
224 # Set which layers to remove before export.
225 mainExportSettings = QWidget()
226 mainExportSettings.setLayout(QVBoxLayout())
227 groupExportCrop = QGroupBox(i18n("Crop Settings"))
228 formCrop = QFormLayout()
229 groupExportCrop.setLayout(formCrop)
230 self.chk_toOutmostGuides = QCheckBox(i18n("Crop to outmost guides"))
231 self.chk_toOutmostGuides.setChecked(True)
232 self.chk_toOutmostGuides.setToolTip(i18n("This will crop to the outmost guides if possible and otherwise use the underlying crop settings."))
233 formCrop.addRow("", self.chk_toOutmostGuides)
234 btn_fromSelection = QPushButton(i18n("Set Margins from Active Selection"))
236 # This doesn't work.
237 formCrop.addRow("", btn_fromSelection)
238 self.spn_marginLeft = QSpinBox()
239 self.spn_marginLeft.setMaximum(99999)
240 self.spn_marginLeft.setSuffix(" px")
241 formCrop.addRow(i18n("Left:"), self.spn_marginLeft)
242 self.spn_marginTop = QSpinBox()
243 self.spn_marginTop.setMaximum(99999)
244 self.spn_marginTop.setSuffix(" px")
245 formCrop.addRow(i18n("Top:"), self.spn_marginTop)
246 self.spn_marginRight = QSpinBox()
247 self.spn_marginRight.setMaximum(99999)
248 self.spn_marginRight.setSuffix(" px")
249 formCrop.addRow(i18n("Right:"), self.spn_marginRight)
250 self.spn_marginBottom = QSpinBox()
251 self.spn_marginBottom.setMaximum(99999)
252 self.spn_marginBottom.setSuffix(" px")
253 formCrop.addRow(i18n("Bottom:"), self.spn_marginBottom)
254 groupExportLayers = QGroupBox(i18n("Layers"))
255 formLayers = QFormLayout()
256 groupExportLayers.setLayout(formLayers)
258 formLayers.addRow(i18n("Label for removal:"), self.cmbLabelsRemove)
259 self.ln_text_layer_name = QLineEdit()
260 self.ln_text_layer_name.setToolTip(i18n("These are keywords that can be used to identify text layers. A layer only needs to contain the keyword to be recognized. Keywords should be comma separated."))
261 self.ln_panel_layer_name = QLineEdit()
262 self.ln_panel_layer_name.setToolTip(i18n("These are keywords that can be used to identify panel layers. A layer only needs to contain the keyword to be recognized. Keywords should be comma separated."))
263 formLayers.addRow(i18n("Text Layer Key:"), self.ln_text_layer_name)
264 formLayers.addRow(i18n("Panel Layer Key:"), self.ln_panel_layer_name)
265
266 mainExportSettings.layout().addWidget(groupExportCrop)
267 mainExportSettings.layout().addWidget(groupExportLayers)
268 mainWidget.addTab(mainExportSettings, i18n("General"))
269
270 # CBZ, crop, resize, which metadata to add.
271 CBZexportSettings = QWidget()
272 CBZexportSettings.setLayout(QVBoxLayout())
273 self.CBZactive = QCheckBox(i18n("Export to CBZ"))
274 CBZexportSettings.layout().addWidget(self.CBZactive)
276 CBZexportSettings.layout().addWidget(self.CBZgroupResize)
277 self.CBZactive.clicked.connect(self.CBZgroupResize.setEnabled)
278 CBZgroupMeta = QGroupBox(i18n("Metadata to Add"))
279 # CBZexportSettings.layout().addWidget(CBZgroupMeta)
280 CBZgroupMeta.setLayout(QFormLayout())
281
282 mainWidget.addTab(CBZexportSettings, i18n("CBZ"))
283
284 # ACBF, crop, resize, creator name, version history, panel layer, text layers.
285 ACBFExportSettings = QWidget()
286 ACBFform = QFormLayout()
287 ACBFExportSettings.setLayout(QVBoxLayout())
288 ACBFdocInfo = QGroupBox()
289 ACBFdocInfo.setTitle(i18n("ACBF Document Info"))
290 ACBFdocInfo.setLayout(ACBFform)
291 self.lnACBFID = QLabel()
292 self.lnACBFID.setToolTip(i18n("By default this will be filled with a generated universal unique identifier. The ID by itself is merely so that comic book library management programs can figure out if this particular comic is already in their database and whether it has been rated. Of course, the UUID can be changed into something else by manually changing the JSON, but this is advanced usage."))
293 self.spnACBFVersion = QSpinBox()
294 self.ACBFhistoryModel = QStandardItemModel()
295 acbfHistoryList = QListView()
296 acbfHistoryList.setModel(self.ACBFhistoryModel)
297 btn_add_history = QPushButton(i18n("Add History Entry"))
298 btn_add_history.clicked.connect(self.slot_add_history_itemslot_add_history_item)
300 self.chkIncludeTranslatorComments.setText(i18n("Include translator's comments"))
301 self.chkIncludeTranslatorComments.setToolTip(i18n("A PO file can contain translator's comments. If this is checked, the translations comments will be added as references into the ACBF file."))
302 self.lnTranslatorHeader = QLineEdit()
303
304 ACBFform.addRow(i18n("ACBF UID:"), self.lnACBFID)
305 ACBFform.addRow(i18n("Version:"), self.spnACBFVersion)
306 ACBFform.addRow(i18n("Version history:"), acbfHistoryList)
307 ACBFform.addRow("", btn_add_history)
308 ACBFform.addRow("", self.chkIncludeTranslatorComments)
309 ACBFform.addRow(i18n("Translator header:"), self.lnTranslatorHeader)
310
311 ACBFAuthorInfo = QWidget()
312 acbfAVbox = QVBoxLayout(ACBFAuthorInfo)
313 infoLabel = QLabel(i18n("The people responsible for the generation of the CBZ/ACBF files."))
314 infoLabel.setWordWrap(True)
315 ACBFAuthorInfo.layout().addWidget(infoLabel)
316 self.ACBFauthorModel = QStandardItemModel(0, 6)
317 labels = [i18n("Nick Name"), i18n("Given Name"), i18n("Middle Name"), i18n("Family Name"), i18n("Email"), i18n("Homepage")]
318 self.ACBFauthorModel.setHorizontalHeaderLabels(labels)
319 self.ACBFauthorTable = QTableView()
320 acbfAVbox.addWidget(self.ACBFauthorTable)
321 self.ACBFauthorTable.setModel(self.ACBFauthorModel)
322 self.ACBFauthorTable.verticalHeader().setDragEnabled(True)
323 self.ACBFauthorTable.verticalHeader().setDropIndicatorShown(True)
324 self.ACBFauthorTable.verticalHeader().setSectionsMovable(True)
325 self.ACBFauthorTable.verticalHeader().sectionMoved.connect(self.slot_reset_author_row_visualslot_reset_author_row_visual)
326 AuthorButtons = QHBoxLayout()
327 btn_add_author = QPushButton(i18n("Add Author"))
328 btn_add_author.clicked.connect(self.slot_add_authorslot_add_author)
329 AuthorButtons.addWidget(btn_add_author)
330 btn_remove_author = QPushButton(i18n("Remove Author"))
331 btn_remove_author.clicked.connect(self.slot_remove_authorslot_remove_author)
332 AuthorButtons.addWidget(btn_remove_author)
333 acbfAVbox.addLayout(AuthorButtons)
334
335 ACBFStyle = QWidget()
336 ACBFStyle.setLayout(QHBoxLayout())
337 self.ACBFStylesModel = QStandardItemModel()
338 self.ACBFStyleClass = QListView()
339 self.ACBFStyleClass.setModel(self.ACBFStylesModel)
340 ACBFStyle.layout().addWidget(self.ACBFStyleClass)
341 ACBFStyleEdit = QWidget()
342 ACBFStyleEditVB = QVBoxLayout(ACBFStyleEdit)
343 self.ACBFuseFont = QCheckBox(i18n("Use font"))
344 self.ACBFFontList = QListView()
345 self.ACBFFontList.setItemDelegate(font_list_delegate())
347 self.ACBFFontListModel = QStandardItemModel()
350 self.btnAcbfAddFont = QPushButton()
351 self.btnAcbfAddFont.setIcon(Application.icon("list-add"))
353 self.btn_acbf_remove_font = QPushButton()
354 self.btn_acbf_remove_font.setIcon(Application.icon("edit-delete"))
356 self.ACBFFontList.setModel(self.ACBFFontListModel)
357 self.ACBFdefaultFont = QComboBox()
358 self.ACBFdefaultFont.addItems(["sans-serif", "serif", "monospace", "cursive", "fantasy"])
359 acbfFontButtons = QHBoxLayout()
360 acbfFontButtons.addWidget(self.btnAcbfAddFont)
361 acbfFontButtons.addWidget(self.btn_acbf_remove_font)
362 self.ACBFBold = QCheckBox(i18n("Bold"))
363 self.ACBFItal = QCheckBox(i18n("Italic"))
365 self.ACBFStyleClass.selectionModel().selectionChanged.connect(self.slot_set_styleslot_set_style)
366 self.ACBFStylesModel.itemChanged.connect(self.slot_set_styleslot_set_style)
369 colorWidget = QGroupBox(self)
370 colorWidget.setTitle(i18n("Text Colors"))
371 colorWidget.setLayout(QVBoxLayout())
372 self.regularColor = QColorDialog()
373 self.invertedColor = QColorDialog()
374 self.btn_acbfRegColor = QPushButton(i18n("Regular Text"), self)
376 self.btn_acbfInvColor = QPushButton(i18n("Inverted Text"), self)
378 colorWidget.layout().addWidget(self.btn_acbfRegColor)
379 colorWidget.layout().addWidget(self.btn_acbfInvColor)
380 ACBFStyleEditVB.addWidget(colorWidget)
381 ACBFStyleEditVB.addWidget(self.ACBFuseFont)
382 ACBFStyleEditVB.addWidget(self.ACBFFontList)
383 ACBFStyleEditVB.addLayout(acbfFontButtons)
384 ACBFStyleEditVB.addWidget(self.ACBFdefaultFont)
385 ACBFStyleEditVB.addWidget(self.ACBFBold)
386 ACBFStyleEditVB.addWidget(self.ACBFItal)
387 ACBFStyleEditVB.addStretch()
388 ACBFStyle.layout().addWidget(ACBFStyleEdit)
389
390 ACBFTabwidget = QTabWidget()
391 ACBFTabwidget.addTab(ACBFdocInfo, i18n("Document Info"))
392 ACBFTabwidget.addTab(ACBFAuthorInfo, i18n("Author Info"))
393 ACBFTabwidget.addTab(ACBFStyle, i18n("Style Sheet"))
394 ACBFExportSettings.layout().addWidget(ACBFTabwidget)
395 mainWidget.addTab(ACBFExportSettings, i18n("ACBF"))
396
397 # Epub export, crop, resize, other questions.
398 EPUBexportSettings = QWidget()
399 EPUBexportSettings.setLayout(QVBoxLayout())
400 self.EPUBactive = QCheckBox(i18n("Export to EPUB"))
401 EPUBexportSettings.layout().addWidget(self.EPUBactive)
403 EPUBexportSettings.layout().addWidget(self.EPUBgroupResize)
404 self.EPUBactive.clicked.connect(self.EPUBgroupResize.setEnabled)
405 mainWidget.addTab(EPUBexportSettings, i18n("EPUB"))
406
407 # For Print. Crop, no resize.
408 TIFFExportSettings = QWidget()
409 TIFFExportSettings.setLayout(QVBoxLayout())
410 self.TIFFactive = QCheckBox(i18n("Export to TIFF"))
411 TIFFExportSettings.layout().addWidget(self.TIFFactive)
413 TIFFExportSettings.layout().addWidget(self.TIFFgroupResize)
414 self.TIFFactive.clicked.connect(self.TIFFgroupResize.setEnabled)
415 mainWidget.addTab(TIFFExportSettings, i18n("TIFF"))
416
417 # SVG, crop, resize, embed vs link.
418 #SVGExportSettings = QWidget()
419
420 #mainWidget.addTab(SVGExportSettings, i18n("SVG"))
421
422 """
423 Add a history item to the acbf version history list.
424 """
425
427 newItem = QStandardItem()
428 newItem.setText(str(i18n("v{version}-in this version...")).format(version=str(self.spnACBFVersion.value())))
429 self.ACBFhistoryModel.appendRow(newItem)
430
431 """
432 Get the margins by treating the active selection in a document as the trim area.
433 This allows people to snap selections to a vector or something, and then get the margins.
434 """
435
437 doc = Application.activeDocument()
438 if doc is not None:
439 if doc.selection() is not None:
440 self.spn_marginLeft.setValue(doc.selection().x())
441 self.spn_marginTop.setValue(doc.selection().y())
442 self.spn_marginRight.setValue(doc.width() - (doc.selection().x() + doc.selection().width()))
443 self.spn_marginBottom.setValue(doc.height() - (doc.selection().y() + doc.selection().height()))
444
445 """
446 Add an author with default values initialised.
447 """
448
450 listItems = []
451 listItems.append(QStandardItem(i18n("Anon"))) # Nick name
452 listItems.append(QStandardItem(i18n("John"))) # First name
453 listItems.append(QStandardItem()) # Middle name
454 listItems.append(QStandardItem(i18n("Doe"))) # Last name
455 listItems.append(QStandardItem()) # email
456 listItems.append(QStandardItem()) # homepage
457 self.ACBFauthorModel.appendRow(listItems)
458
459 """
460 Remove the selected author from the author list.
461 """
462
464 self.ACBFauthorModel.removeRow(self.ACBFauthorTable.currentIndex().row())
465
466 """
467 Ensure that the drag and drop of authors doesn't mess up the labels.
468 """
469
471 headerLabelList = []
472 for i in range(self.ACBFauthorTable.verticalHeader().count()):
473 headerLabelList.append(str(i))
474 for i in range(self.ACBFauthorTable.verticalHeader().count()):
475 logicalI = self.ACBFauthorTable.verticalHeader().logicalIndex(i)
476 headerLabelList[logicalI] = str(i + 1)
477 self.ACBFauthorModel.setVerticalHeaderLabels(headerLabelList)
478 """
479 Set the style item to the gui item's style.
480 """
481
482 def slot_set_style(self):
483 index = self.ACBFStyleClass.currentIndex()
484 if index.isValid():
485 item = self.ACBFStylesModel.item(index.row())
486 fontUsed = item.data(role=styleEnum.FONT)
487 if fontUsed is not None:
488 self.ACBFuseFont.setChecked(fontUsed)
489 else:
490 self.ACBFuseFont.setChecked(False)
492 fontList = item.data(role=styleEnum.FONTLIST)
493 self.ACBFFontListModel.clear()
494 for font in fontList:
495 NewItem = QStandardItem(font)
496 NewItem.setEditable(True)
497 self.ACBFFontListModel.appendRow(NewItem)
498 self.ACBFdefaultFont.setCurrentText(str(item.data(role=styleEnum.FONTGENERIC)))
499 bold = item.data(role=styleEnum.BOLD)
500 if bold is not None:
501 self.ACBFBold.setChecked(bold)
502 else:
503 self.ACBFBold.setChecked(False)
504 italic = item.data(role=styleEnum.ITALIC)
505 if italic is not None:
506 self.ACBFItal.setChecked(italic)
507 else:
508 self.ACBFItal.setChecked(False)
509
510 """
511 Set the gui items to the currently selected style.
512 """
513
515 index = self.ACBFStyleClass.currentIndex()
516 if index.isValid():
517 item = self.ACBFStylesModel.item(index.row())
518 fontList = []
519 for row in range(self.ACBFFontListModel.rowCount()):
520 font = self.ACBFFontListModel.item(row)
521 fontList.append(font.text())
522 item.setData(self.ACBFuseFont.isChecked(), role=styleEnum.FONT)
523 item.setData(fontList, role=styleEnum.FONTLIST)
524 item.setData(self.ACBFdefaultFont.currentText(), role=styleEnum.FONTGENERIC)
525 item.setData(self.ACBFBold.isChecked(), role=styleEnum.BOLD)
526 item.setData(self.ACBFItal.isChecked(), role=styleEnum.ITALIC)
527 self.ACBFStylesModel.setItem(index.row(), item)
528 """
529 Change the regular color
530 """
531
533 if (self.regularColor.exec() == QDialog.DialogCode.Accepted):
534 square = QPixmap(32, 32)
535 square.fill(self.regularColor.currentColor())
536 self.btn_acbfRegColor.setIcon(QIcon(square))
537 """
538 change the inverted color
539 """
540
542 if (self.invertedColor.exec() == QDialog.DialogCode.Accepted):
543 square = QPixmap(32, 32)
544 square.fill(self.invertedColor.currentColor())
545 self.btn_acbfInvColor.setIcon(QIcon(square))
546
548 self.ACBFFontList.setEnabled(self.ACBFuseFont.isChecked())
549 self.btn_acbf_remove_font.setEnabled(self.ACBFuseFont.isChecked())
550 self.btnAcbfAddFont.setEnabled(self.ACBFuseFont.isChecked())
551 self.ACBFdefaultFont.setEnabled(self.ACBFuseFont.isChecked())
552 if self.ACBFFontListModel.rowCount() < 2:
553 self.btn_acbf_remove_font.setEnabled(False)
554
556 NewItem = QStandardItem(QFont().family())
557 NewItem.setEditable(True)
558 self.ACBFFontListModel.appendRow(NewItem)
559
561 index = self.ACBFFontList.currentIndex()
562 if index.isValid():
563 self.ACBFFontListModel.removeRow(index.row())
564 if self.ACBFFontListModel.rowCount() < 2:
565 self.btn_acbf_remove_font.setEnabled(False)
566
567 """
568 Load the UI values from the config dictionary given.
569 """
570
571 def setConfig(self, config):
572 if "cropToGuides" in config.keys():
573 self.chk_toOutmostGuides.setChecked(config["cropToGuides"])
574 if "cropLeft" in config.keys():
575 self.spn_marginLeft.setValue(config["cropLeft"])
576 if "cropTop" in config.keys():
577 self.spn_marginTop.setValue(config["cropTop"])
578 if "cropRight" in config.keys():
579 self.spn_marginRight.setValue(config["cropRight"])
580 if "cropBottom" in config.keys():
581 self.spn_marginBottom.setValue(config["cropBottom"])
582 if "labelsToRemove" in config.keys():
583 self.cmbLabelsRemove.setLabels(config["labelsToRemove"])
584 if "textLayerNames" in config.keys():
585 self.ln_text_layer_name.setText(", ".join(config["textLayerNames"]))
586 else:
587 self.ln_text_layer_name.setText("text")
588 if "panelLayerNames" in config.keys():
589 self.ln_panel_layer_name.setText(", ".join(config["panelLayerNames"]))
590 else:
591 self.ln_panel_layer_name.setText("panels")
592 self.CBZgroupResize.set_config(config)
593 if "CBZactive" in config.keys():
594 self.CBZactive.setChecked(config["CBZactive"])
595 self.EPUBgroupResize.set_config(config)
596 if "EPUBactive" in config.keys():
597 self.EPUBactive.setChecked(config["EPUBactive"])
598 self.TIFFgroupResize.set_config(config)
599 if "TIFFactive" in config.keys():
600 self.TIFFactive.setChecked(config["TIFFactive"])
601
602 if "acbfAuthor" in config.keys():
603 if isinstance(config["acbfAuthor"], list):
604 for author in config["acbfAuthor"]:
605 listItems = []
606 listItems.append(QStandardItem(author.get("nickname", "")))
607 listItems.append(QStandardItem(author.get("first-name", "")))
608 listItems.append(QStandardItem(author.get("initials", "")))
609 listItems.append(QStandardItem(author.get("last-name", "")))
610 listItems.append(QStandardItem(author.get("email", "")))
611 listItems.append(QStandardItem(author.get("homepage", "")))
612 self.ACBFauthorModel.appendRow(listItems)
613 pass
614 else:
615 listItems = []
616 listItems.append(QStandardItem(config["acbfAuthor"])) # Nick name
617 for i in range(0, 5):
618 listItems.append(QStandardItem()) # First name
619 self.ACBFauthorModel.appendRow(listItems)
620
621 if "uuid" in config.keys():
622 self.lnACBFID.setText(config["uuid"])
623 elif "acbfID" in config.keys():
624 self.lnACBFID.setText(config["acbfID"])
625 else:
626 config["uuid"] = QUuid.createUuid().toString()
627 self.lnACBFID.setText(config["uuid"])
628 if "acbfVersion" in config.keys():
629 self.spnACBFVersion.setValue(config["acbfVersion"])
630 if "acbfHistory" in config.keys():
631 for h in config["acbfHistory"]:
632 item = QStandardItem()
633 item.setText(h)
634 self.ACBFhistoryModel.appendRow(item)
635 if "acbfStyles" in config.keys():
636 styleDict = config.get("acbfStyles", {})
637 for key in self.acbfStylesList:
638 keyDict = styleDict.get(key, {})
639 style = QStandardItem(key.title())
640 style.setCheckable(True)
641 if key in styleDict.keys():
642 style.setCheckState(Qt.CheckState.Checked)
643 else:
644 style.setCheckState(Qt.CheckState.Unchecked)
645 fontOn = False
646 if "font" in keyDict.keys() or "genericfont" in keyDict.keys():
647 fontOn = True
648 style.setData(fontOn, role=styleEnum.FONT)
649 if "font" in keyDict:
650 fontlist = keyDict["font"]
651 if isinstance(fontlist, list):
652 font = keyDict.get("font", QFont().family())
653 style.setData(font, role=styleEnum.FONTLIST)
654 else:
655 style.setData([fontlist], role=styleEnum.FONTLIST)
656 else:
657 style.setData([QFont().family()], role=styleEnum.FONTLIST)
658 style.setData(keyDict.get("genericfont", "sans-serif"), role=styleEnum.FONTGENERIC)
659 style.setData(keyDict.get("bold", False), role=styleEnum.BOLD)
660 style.setData(keyDict.get("ital", False), role=styleEnum.ITALIC)
661 self.ACBFStylesModel.appendRow(style)
662 keyDict = styleDict.get("general", {})
663 self.regularColor.setCurrentColor(QColor(keyDict.get("color", "#000000")))
664 square = QPixmap(32, 32)
665 square.fill(self.regularColor.currentColor())
666 self.btn_acbfRegColor.setIcon(QIcon(square))
667 keyDict = styleDict.get("inverted", {})
668 self.invertedColor.setCurrentColor(QColor(keyDict.get("color", "#FFFFFF")))
669 square.fill(self.invertedColor.currentColor())
670 self.btn_acbfInvColor.setIcon(QIcon(square))
671 else:
672 for key in self.acbfStylesList:
673 style = QStandardItem(key.title())
674 style.setCheckable(True)
675 style.setCheckState(Qt.CheckState.Unchecked)
676 style.setData(False, role=styleEnum.FONT)
677 style.setData(QFont().family(), role=styleEnum.FONTLIST)
678 style.setData("sans-serif", role=styleEnum.FONTGENERIC)
679 style.setData(False, role=styleEnum.BOLD) #Bold
680 style.setData(False, role=styleEnum.ITALIC) #Italic
681 self.ACBFStylesModel.appendRow(style)
682 self.CBZgroupResize.setEnabled(self.CBZactive.isChecked())
683 self.lnTranslatorHeader.setText(config.get("translatorHeader", "Translator's Notes"))
684 self.chkIncludeTranslatorComments.setChecked(config.get("includeTranslComment", False))
685
686 """
687 Store the GUI values into the config dictionary given.
688
689 @return the config diactionary filled with new values.
690 """
691
692 def getConfig(self, config):
693
694 config["cropToGuides"] = self.chk_toOutmostGuides.isChecked()
695 config["cropLeft"] = self.spn_marginLeft.value()
696 config["cropTop"] = self.spn_marginTop.value()
697 config["cropRight"] = self.spn_marginRight.value()
698 config["cropBottom"] = self.spn_marginBottom.value()
699 config["labelsToRemove"] = self.cmbLabelsRemove.getLabels()
700 config["CBZactive"] = self.CBZactive.isChecked()
701 config = self.CBZgroupResize.get_config(config)
702 config["EPUBactive"] = self.EPUBactive.isChecked()
703 config = self.EPUBgroupResize.get_config(config)
704 config["TIFFactive"] = self.TIFFactive.isChecked()
705 config = self.TIFFgroupResize.get_config(config)
706 authorList = []
707 for row in range(self.ACBFauthorTable.verticalHeader().count()):
708 logicalIndex = self.ACBFauthorTable.verticalHeader().logicalIndex(row)
709 listEntries = ["nickname", "first-name", "initials", "last-name", "email", "homepage"]
710 author = {}
711 for i in range(len(listEntries)):
712 entry = self.ACBFauthorModel.data(self.ACBFauthorModel.index(logicalIndex, i))
713 if entry is None:
714 entry = " "
715 if entry.isspace() is False and len(entry) > 0:
716 author[listEntries[i]] = entry
717 elif listEntries[i] in author.keys():
718 author.pop(listEntries[i])
719 authorList.append(author)
720 config["acbfAuthor"] = authorList
721 config["acbfVersion"] = self.spnACBFVersion.value()
722 versionList = []
723 for r in range(self.ACBFhistoryModel.rowCount()):
724 index = self.ACBFhistoryModel.index(r, 0)
725 versionList.append(self.ACBFhistoryModel.data(index, Qt.ItemDisplayrole.DisplayRole))
726 config["acbfHistory"] = versionList
727
728 acbfStylesDict = {}
729 for row in range(0, self.ACBFStylesModel.rowCount()):
730 entry = self.ACBFStylesModel.item(row)
731 if entry.checkState() == Qt.CheckState.Checked:
732 key = entry.text().lower()
733 style = {}
734 if entry.data(role=styleEnum.FONT):
735 font = entry.data(role=styleEnum.FONTLIST)
736 if font is not None:
737 style["font"] = font
738 genericfont = entry.data(role=styleEnum.FONTGENERIC)
739 if font is not None:
740 style["genericfont"] = genericfont
741 bold = entry.data(role=styleEnum.BOLD)
742 if bold is not None:
743 style["bold"] = bold
744 italic = entry.data(role=styleEnum.ITALIC)
745 if italic is not None:
746 style["ital"] = italic
747 acbfStylesDict[key] = style
748 acbfStylesDict["general"] = {"color": self.regularColor.currentColor().name()}
749 acbfStylesDict["inverted"] = {"color": self.invertedColor.currentColor().name()}
750 config["acbfStyles"] = acbfStylesDict
751 config["translatorHeader"] = self.lnTranslatorHeader.text()
752 config["includeTranslComment"] = self.chkIncludeTranslatorComments.isChecked()
753
754 # Turn this into something that retrieves from a line-edit when string freeze is over.
755 config["textLayerNames"] = self.ln_text_layer_name.text().split(",")
756 config["panelLayerNames"] = self.ln_panel_layer_name.text().split(",")
757 return config
float value(const T *src, size_t ch)