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