mirror of
https://github.com/ciromattia/kcc
synced 2026-05-20 14:32:03 +00:00
* Add bulk metadata editing support
* Enable multi-file selection in Metadata Editor using getOpenFileNames()
* Disable Volume, Number, and Title fields in bulk mode
* Pre-fill Series and author fields from first selected file in bulk mode
* Show status "Editing Y files" in bulk mode
* Add progress display during bulk save ("Processing X/Y: filename")
* Disable buttons during processing
* Skip read-only CBR files with error collection
* Show error summary dialog if any files fail to save
* Keep single file metadata editing the same
* Add bulk volume editing with rich tooltip
* Add checkbox next to Volume field for enabling bulk volume editing (only in bulk mode)
* Support single number (5), range (1-10), or comma list (1, 3, 5) input formats
* Sort files alphabetically before volume assignment
* Validate that volume count matches file count
* Add rich HTML tooltip explaining the feature
* Move bulkVolumeCheck widget definition to MetaEditor.ui
* Define bulkVolumeCheck QCheckBox in MetaEditor.ui instead of creating it programmatically in KCC_gui.py
* Update tab order to include bulkVolumeCheck after volumeLine
* Add multi-directory selection for bulk metadata editing
* Shift+click on editor button now opens multi-directory selection dialog
* Multiple directories enable bulk mode with volume number assignment
* Uses Qt's built-in dialog with multi-selection enabled for native look and feel
* Fix volume input validation in bulk metadata editor
* Handle invalid range formats like "1-2-3" or "--" that previously fell through, now returns an error message
* Add explicit check for empty/malformed range parts before attempting to parse
* Add positive number validation for all input types (range, comma-list, single number) to be consistent with single file mode which uses isnumeric()
* Add explicit validation for empty volumes list after parsing
* Keep metadata editor dialog open when error occur during bulks save
* Fix CBR read-only check in bulk metadata editor
* Check all files for CBR format during load instead of during save
* Unify the CBR check for single and bulk mode
* Handle mixed metadata values in bulk editing
* In bulk mode, compare Series + Writer/Penciller/Inker/Colorist across all selected files (instead of using only the first file)
* When values differ, show “(multiple values)” placeholder for that field
* Add hover tooltip with overwrite warning and a File|Value table (or Value|Count summary when there are >20 files)
* Code comments cleanup
* Use ExtendedSelection for multi-directory file dialog
* use !=
200 lines
8.6 KiB
Python
200 lines
8.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
################################################################################
|
|
## Form generated from reading UI file 'MetaEditor.ui'
|
|
##
|
|
## Created by: Qt User Interface Compiler version 6.9.3
|
|
##
|
|
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
|
################################################################################
|
|
|
|
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
|
QMetaObject, QObject, QPoint, QRect,
|
|
QSize, QTime, QUrl, Qt)
|
|
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
|
QFont, QFontDatabase, QGradient, QIcon,
|
|
QImage, QKeySequence, QLinearGradient, QPainter,
|
|
QPalette, QPixmap, QRadialGradient, QTransform)
|
|
from PySide6.QtWidgets import (QApplication, QCheckBox, QDialog, QGridLayout,
|
|
QHBoxLayout, QLabel, QLineEdit, QPushButton,
|
|
QSizePolicy, QVBoxLayout, QWidget)
|
|
from . import KCC_rc
|
|
|
|
class Ui_editorDialog(object):
|
|
def setupUi(self, editorDialog):
|
|
if not editorDialog.objectName():
|
|
editorDialog.setObjectName(u"editorDialog")
|
|
editorDialog.resize(400, 260)
|
|
editorDialog.setMinimumSize(QSize(400, 260))
|
|
icon = QIcon()
|
|
icon.addFile(u":/Icon/icons/comic2ebook.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
|
editorDialog.setWindowIcon(icon)
|
|
self.verticalLayout = QVBoxLayout(editorDialog)
|
|
self.verticalLayout.setObjectName(u"verticalLayout")
|
|
self.verticalLayout.setContentsMargins(-1, -1, -1, 5)
|
|
self.editorWidget = QWidget(editorDialog)
|
|
self.editorWidget.setObjectName(u"editorWidget")
|
|
self.gridLayout = QGridLayout(self.editorWidget)
|
|
self.gridLayout.setObjectName(u"gridLayout")
|
|
self.gridLayout.setContentsMargins(0, 0, 0, 0)
|
|
self.label_1 = QLabel(self.editorWidget)
|
|
self.label_1.setObjectName(u"label_1")
|
|
|
|
self.gridLayout.addWidget(self.label_1, 0, 0, 1, 1)
|
|
|
|
self.seriesLine = QLineEdit(self.editorWidget)
|
|
self.seriesLine.setObjectName(u"seriesLine")
|
|
|
|
self.gridLayout.addWidget(self.seriesLine, 0, 1, 1, 1)
|
|
|
|
self.label_2 = QLabel(self.editorWidget)
|
|
self.label_2.setObjectName(u"label_2")
|
|
|
|
self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1)
|
|
|
|
self.volumeLine = QLineEdit(self.editorWidget)
|
|
self.volumeLine.setObjectName(u"volumeLine")
|
|
|
|
self.gridLayout.addWidget(self.volumeLine, 1, 1, 1, 1)
|
|
|
|
self.bulkVolumeCheck = QCheckBox(self.editorWidget)
|
|
self.bulkVolumeCheck.setObjectName(u"bulkVolumeCheck")
|
|
self.bulkVolumeCheck.setVisible(False)
|
|
|
|
self.gridLayout.addWidget(self.bulkVolumeCheck, 1, 2, 1, 1)
|
|
|
|
self.label_3 = QLabel(self.editorWidget)
|
|
self.label_3.setObjectName(u"label_3")
|
|
|
|
self.gridLayout.addWidget(self.label_3, 3, 0, 1, 1)
|
|
|
|
self.numberLine = QLineEdit(self.editorWidget)
|
|
self.numberLine.setObjectName(u"numberLine")
|
|
|
|
self.gridLayout.addWidget(self.numberLine, 3, 1, 1, 1)
|
|
|
|
self.label_4 = QLabel(self.editorWidget)
|
|
self.label_4.setObjectName(u"label_4")
|
|
|
|
self.gridLayout.addWidget(self.label_4, 4, 0, 1, 1)
|
|
|
|
self.writerLine = QLineEdit(self.editorWidget)
|
|
self.writerLine.setObjectName(u"writerLine")
|
|
|
|
self.gridLayout.addWidget(self.writerLine, 4, 1, 1, 1)
|
|
|
|
self.label_5 = QLabel(self.editorWidget)
|
|
self.label_5.setObjectName(u"label_5")
|
|
|
|
self.gridLayout.addWidget(self.label_5, 5, 0, 1, 1)
|
|
|
|
self.pencillerLine = QLineEdit(self.editorWidget)
|
|
self.pencillerLine.setObjectName(u"pencillerLine")
|
|
|
|
self.gridLayout.addWidget(self.pencillerLine, 5, 1, 1, 1)
|
|
|
|
self.label_6 = QLabel(self.editorWidget)
|
|
self.label_6.setObjectName(u"label_6")
|
|
|
|
self.gridLayout.addWidget(self.label_6, 6, 0, 1, 1)
|
|
|
|
self.inkerLine = QLineEdit(self.editorWidget)
|
|
self.inkerLine.setObjectName(u"inkerLine")
|
|
|
|
self.gridLayout.addWidget(self.inkerLine, 6, 1, 1, 1)
|
|
|
|
self.label_7 = QLabel(self.editorWidget)
|
|
self.label_7.setObjectName(u"label_7")
|
|
|
|
self.gridLayout.addWidget(self.label_7, 7, 0, 1, 1)
|
|
|
|
self.coloristLine = QLineEdit(self.editorWidget)
|
|
self.coloristLine.setObjectName(u"coloristLine")
|
|
|
|
self.gridLayout.addWidget(self.coloristLine, 7, 1, 1, 1)
|
|
|
|
self.label_8 = QLabel(self.editorWidget)
|
|
self.label_8.setObjectName(u"label_8")
|
|
|
|
self.gridLayout.addWidget(self.label_8, 2, 0, 1, 1)
|
|
|
|
self.titleLine = QLineEdit(self.editorWidget)
|
|
self.titleLine.setObjectName(u"titleLine")
|
|
|
|
self.gridLayout.addWidget(self.titleLine, 2, 1, 1, 1)
|
|
|
|
|
|
self.verticalLayout.addWidget(self.editorWidget)
|
|
|
|
self.optionWidget = QWidget(editorDialog)
|
|
self.optionWidget.setObjectName(u"optionWidget")
|
|
self.horizontalLayout = QHBoxLayout(self.optionWidget)
|
|
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
|
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
|
|
self.statusLabel = QLabel(self.optionWidget)
|
|
self.statusLabel.setObjectName(u"statusLabel")
|
|
sizePolicy = QSizePolicy(QSizePolicy.Policy.MinimumExpanding, QSizePolicy.Policy.MinimumExpanding)
|
|
sizePolicy.setHorizontalStretch(0)
|
|
sizePolicy.setVerticalStretch(0)
|
|
sizePolicy.setHeightForWidth(self.statusLabel.sizePolicy().hasHeightForWidth())
|
|
self.statusLabel.setSizePolicy(sizePolicy)
|
|
|
|
self.horizontalLayout.addWidget(self.statusLabel)
|
|
|
|
self.okButton = QPushButton(self.optionWidget)
|
|
self.okButton.setObjectName(u"okButton")
|
|
self.okButton.setMinimumSize(QSize(0, 30))
|
|
icon1 = QIcon()
|
|
icon1.addFile(u":/Other/icons/convert.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
|
self.okButton.setIcon(icon1)
|
|
|
|
self.horizontalLayout.addWidget(self.okButton)
|
|
|
|
self.cancelButton = QPushButton(self.optionWidget)
|
|
self.cancelButton.setObjectName(u"cancelButton")
|
|
self.cancelButton.setMinimumSize(QSize(0, 30))
|
|
icon2 = QIcon()
|
|
icon2.addFile(u":/Other/icons/clear.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
|
self.cancelButton.setIcon(icon2)
|
|
|
|
self.horizontalLayout.addWidget(self.cancelButton)
|
|
|
|
|
|
self.verticalLayout.addWidget(self.optionWidget)
|
|
|
|
QWidget.setTabOrder(self.seriesLine, self.volumeLine)
|
|
QWidget.setTabOrder(self.volumeLine, self.bulkVolumeCheck)
|
|
QWidget.setTabOrder(self.bulkVolumeCheck, self.titleLine)
|
|
QWidget.setTabOrder(self.titleLine, self.numberLine)
|
|
QWidget.setTabOrder(self.numberLine, self.writerLine)
|
|
QWidget.setTabOrder(self.writerLine, self.pencillerLine)
|
|
QWidget.setTabOrder(self.pencillerLine, self.inkerLine)
|
|
QWidget.setTabOrder(self.inkerLine, self.coloristLine)
|
|
QWidget.setTabOrder(self.coloristLine, self.okButton)
|
|
QWidget.setTabOrder(self.okButton, self.cancelButton)
|
|
|
|
self.retranslateUi(editorDialog)
|
|
|
|
QMetaObject.connectSlotsByName(editorDialog)
|
|
# setupUi
|
|
|
|
def retranslateUi(self, editorDialog):
|
|
editorDialog.setWindowTitle(QCoreApplication.translate("editorDialog", u"Metadata editor", None))
|
|
self.label_1.setText(QCoreApplication.translate("editorDialog", u"Series:", None))
|
|
self.label_2.setText(QCoreApplication.translate("editorDialog", u"Volume:", None))
|
|
#if QT_CONFIG(tooltip)
|
|
self.bulkVolumeCheck.setToolTip(QCoreApplication.translate("editorDialog", u"<b>Bulk Volume Editing</b><br>Check this box to assign volume numbers to multiple files.<br><br><b>Input formats:</b><br><code>5</code> \u2192 sequence starting from 5 (5, 6, 7...)<br><code>1-10</code> \u2192 range from 1 to 10<br><code>1, 3, 5</code> \u2192 specific values<br><br><i>Note: Files are sorted alphabetically before assignment.</i>", None))
|
|
#endif // QT_CONFIG(tooltip)
|
|
self.bulkVolumeCheck.setText("")
|
|
self.label_3.setText(QCoreApplication.translate("editorDialog", u"Number:", None))
|
|
self.label_4.setText(QCoreApplication.translate("editorDialog", u"Writer:", None))
|
|
self.label_5.setText(QCoreApplication.translate("editorDialog", u"Penciller:", None))
|
|
self.label_6.setText(QCoreApplication.translate("editorDialog", u"Inker:", None))
|
|
self.label_7.setText(QCoreApplication.translate("editorDialog", u"Colorist:", None))
|
|
self.label_8.setText(QCoreApplication.translate("editorDialog", u"Title:", None))
|
|
self.statusLabel.setText("")
|
|
self.okButton.setText(QCoreApplication.translate("editorDialog", u"Save", None))
|
|
self.cancelButton.setText(QCoreApplication.translate("editorDialog", u"Cancel", None))
|
|
# retranslateUi
|
|
|