1#!/usr/local/bin/python3.8
2
3
4__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
5__docformat__ = 'restructuredtext en'
6__license__   = 'GPL v3'
7
8
9from qt.core import (
10    QDialog, QGridLayout, QLabel, QDialogButtonBox,  QApplication, QSpinBox,
11    QToolButton, QIcon, QLineEdit, QComboBox, QCheckBox)
12from calibre.ebooks.metadata import string_to_authors
13from calibre.gui2.complete2 import EditWithComplete
14from calibre.utils.config import tweaks
15from calibre.gui2 import gprefs
16
17
18class AddEmptyBookDialog(QDialog):
19
20    def __init__(self, parent, db, author, series=None, title=None, dup_title=None):
21        QDialog.__init__(self, parent)
22        self.db = db
23
24        self.setWindowTitle(_('How many empty books?'))
25
26        self._layout = QGridLayout(self)
27        self.setLayout(self._layout)
28
29        self.qty_label = QLabel(_('How many empty books should be added?'))
30        self._layout.addWidget(self.qty_label, 0, 0, 1, 2)
31
32        self.qty_spinbox = QSpinBox(self)
33        self.qty_spinbox.setRange(1, 10000)
34        self.qty_spinbox.setValue(1)
35        self._layout.addWidget(self.qty_spinbox, 1, 0, 1, 2)
36
37        self.author_label = QLabel(_('Set the author of the new books to:'))
38        self._layout.addWidget(self.author_label, 2, 0, 1, 2)
39
40        self.authors_combo = EditWithComplete(self)
41        self.authors_combo.setSizeAdjustPolicy(
42                QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon)
43        self.authors_combo.setEditable(True)
44        self._layout.addWidget(self.authors_combo, 3, 0, 1, 1)
45        self.initialize_authors(db, author)
46
47        self.clear_button = QToolButton(self)
48        self.clear_button.setIcon(QIcon(I('trash.png')))
49        self.clear_button.setToolTip(_('Reset author to Unknown'))
50        self.clear_button.clicked.connect(self.reset_author)
51        self._layout.addWidget(self.clear_button, 3, 1, 1, 1)
52
53        self.series_label = QLabel(_('Set the series of the new books to:'))
54        self._layout.addWidget(self.series_label, 4, 0, 1, 2)
55
56        self.series_combo = EditWithComplete(self)
57        self.series_combo.setSizeAdjustPolicy(
58                QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon)
59        self.series_combo.setEditable(True)
60        self._layout.addWidget(self.series_combo, 5, 0, 1, 1)
61        self.initialize_series(db, series)
62
63        self.sclear_button = QToolButton(self)
64        self.sclear_button.setIcon(QIcon(I('trash.png')))
65        self.sclear_button.setToolTip(_('Reset series'))
66        self.sclear_button.clicked.connect(self.reset_series)
67        self._layout.addWidget(self.sclear_button, 5, 1, 1, 1)
68
69        self.title_label = QLabel(_('Set the title of the new books to:'))
70        self._layout.addWidget(self.title_label, 6, 0, 1, 2)
71
72        self.title_edit = QLineEdit(self)
73        self.title_edit.setText(title or '')
74        self._layout.addWidget(self.title_edit, 7, 0, 1, 1)
75
76        self.tclear_button = QToolButton(self)
77        self.tclear_button.setIcon(QIcon(I('trash.png')))
78        self.tclear_button.setToolTip(_('Reset title'))
79        self.tclear_button.clicked.connect(self.title_edit.clear)
80        self._layout.addWidget(self.tclear_button, 7, 1, 1, 1)
81
82        self.format_label = QLabel(_('Also create an empty e-book in format:'))
83        self._layout.addWidget(self.format_label, 8, 0, 1, 2)
84        c = self.format_value = QComboBox(self)
85        from calibre.ebooks.oeb.polish.create import valid_empty_formats
86        possible_formats = [''] + sorted(x.upper() for x in valid_empty_formats)
87        c.addItems(possible_formats)
88        c.setToolTip(_('Also create an empty book format file that you can subsequently edit'))
89        if gprefs.get('create_empty_epub_file', False):
90            # Migration of the check box
91            gprefs.set('create_empty_format_file', 'epub')
92            del gprefs['create_empty_epub_file']
93        use_format = gprefs.get('create_empty_format_file', '').upper()
94        try:
95            c.setCurrentIndex(possible_formats.index(use_format))
96        except Exception:
97            pass
98        self._layout.addWidget(c, 9, 0, 1, 1)
99
100        self.copy_formats = cf = QCheckBox(_('Also copy book &formats when duplicating a book'), self)
101        cf.setToolTip(_(
102            'Also copy all e-book files into the newly created duplicate'
103            ' books.'))
104        cf.setChecked(gprefs.get('create_empty_copy_dup_formats', False))
105        self._layout.addWidget(cf, 10, 0, 1, -1)
106
107        button_box = self.bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
108        button_box.accepted.connect(self.accept)
109        button_box.rejected.connect(self.reject)
110        self._layout.addWidget(button_box, 11, 0, 1, -1)
111        if dup_title:
112            self.dup_button = b = button_box.addButton(_('&Duplicate current book'), QDialogButtonBox.ButtonRole.ActionRole)
113            b.clicked.connect(self.do_duplicate_book)
114            b.setIcon(QIcon(I('edit-copy.png')))
115            b.setToolTip(_(
116                'Make the new empty book records exact duplicates\n'
117                'of the current book "%s", with all metadata identical'
118            ) % dup_title)
119        self.resize(self.sizeHint())
120        self.duplicate_current_book = False
121
122    def do_duplicate_book(self):
123        self.duplicate_current_book = True
124        self.accept()
125
126    def accept(self):
127        self.save_settings()
128        return QDialog.accept(self)
129
130    def save_settings(self):
131        gprefs['create_empty_format_file'] = self.format_value.currentText().lower()
132        gprefs['create_empty_copy_dup_formats'] = self.copy_formats.isChecked()
133
134    def reject(self):
135        self.save_settings()
136        return QDialog.reject(self)
137
138    def reset_author(self, *args):
139        self.authors_combo.setEditText(_('Unknown'))
140
141    def reset_series(self):
142        self.series_combo.setEditText('')
143
144    def initialize_authors(self, db, author):
145        au = author
146        if not au:
147            au = _('Unknown')
148        self.authors_combo.show_initial_value(au.replace('|', ','))
149
150        self.authors_combo.set_separator('&')
151        self.authors_combo.set_space_before_sep(True)
152        self.authors_combo.set_add_separator(tweaks['authors_completer_append_separator'])
153        self.authors_combo.update_items_cache(db.all_author_names())
154
155    def initialize_series(self, db, series):
156        self.series_combo.show_initial_value(series or '')
157        self.series_combo.update_items_cache(db.all_series_names())
158        self.series_combo.set_separator(None)
159
160    @property
161    def qty_to_add(self):
162        return self.qty_spinbox.value()
163
164    @property
165    def selected_authors(self):
166        return string_to_authors(str(self.authors_combo.text()))
167
168    @property
169    def selected_series(self):
170        return str(self.series_combo.text())
171
172    @property
173    def selected_title(self):
174        return self.title_edit.text().strip()
175
176
177if __name__ == '__main__':
178    from calibre.library import db
179    db = db()
180    app = QApplication([])
181    d = AddEmptyBookDialog(None, db, 'Test Author')
182    d.exec()
183