Exemplo n.º 1
0
    def initialize(self, catalog_name, db):
        self.name = catalog_name
        from calibre.library.catalogs import FIELDS

        db = get_gui().current_db
        self.all_fields = {x for x in FIELDS if x != "all"} | set(db.custom_field_keys())
        sort_order = gprefs.get(self.name + "_db_fields_sort_order", {})
        fm = db.field_metadata

        def name(x):
            if x == "isbn":
                return "ISBN"
            if x == "library_name":
                return _("Library Name")
            if x.endswith("_index"):
                return name(x[: -len("_index")]) + " " + _("Number")
            return fm[x].get("name") or x

        def key(x):
            return (sort_order.get(x, 10000), name(x))

        self.db_fields.clear()
        for x in sorted(self.all_fields, key=key):
            QListWidgetItem(name(x) + " (%s)" % x, self.db_fields).setData(Qt.UserRole, x)
            if x.startswith("#") and fm[x]["datatype"] == "series":
                x += "_index"
                QListWidgetItem(name(x) + " (%s)" % x, self.db_fields).setData(Qt.UserRole, x)

        # Restore the activated fields from last use
        fields = frozenset(gprefs.get(self.name + "_db_fields", self.all_fields))
        for x in range(self.db_fields.count()):
            item = self.db_fields.item(x)
            item.setCheckState(Qt.Checked if unicode(item.data(Qt.UserRole)) in fields else Qt.Unchecked)
Exemplo n.º 2
0
    def check_for_add_to_toolbars(self, plugin):
        from calibre.gui2.preferences.toolbar import ConfigWidget
        from calibre.customize import InterfaceActionBase

        if not isinstance(plugin, InterfaceActionBase):
            return

        all_locations = OrderedDict(ConfigWidget.LOCATIONS)
        plugin_action = plugin.load_actual_plugin(self.gui)
        installed_actions = OrderedDict([
            (key, list(gprefs.get('action-layout-'+key, [])))
            for key in all_locations])

        # If already installed in a GUI container, do nothing
        for action_names in installed_actions.itervalues():
            if plugin_action.name in action_names:
                return

        allowed_locations = [(key, text) for key, text in
                all_locations.iteritems() if key
                not in plugin_action.dont_add_to]
        if not allowed_locations:
            return # This plugin doesn't want to live in the GUI

        from calibre.gui2.dialogs.choose_plugin_toolbars import ChoosePluginToolbarsDialog
        d = ChoosePluginToolbarsDialog(self, plugin_action, allowed_locations)
        if d.exec_() == d.Accepted:
            for key, text in d.selected_locations():
                installed_actions = list(gprefs.get('action-layout-'+key, []))
                installed_actions.append(plugin_action.name)
                gprefs['action-layout-'+key] = tuple(installed_actions)
Exemplo n.º 3
0
    def initialize(self, catalog_name, db):
        self.name = catalog_name
        from calibre.library.catalogs import FIELDS
        db = get_gui().current_db
        self.all_fields = {x for x in FIELDS if x != 'all'} | set(db.custom_field_keys())
        sort_order = gprefs.get(self.name + '_db_fields_sort_order', {})
        fm = db.field_metadata

        def name(x):
            if x == 'isbn':
                return 'ISBN'
            if x == 'library_name':
                return _('Library Name')
            if x.endswith('_index'):
                return name(x[:-len('_index')]) + ' ' + _('Number')
            return fm[x].get('name') or x

        def key(x):
            return (sort_order.get(x, 10000), name(x))

        self.db_fields.clear()
        for x in sorted(self.all_fields, key=key):
            QListWidgetItem(name(x) + ' (%s)' % x, self.db_fields).setData(Qt.UserRole, x)
            if x.startswith('#') and fm[x]['datatype'] == 'series':
                x += '_index'
                QListWidgetItem(name(x) + ' (%s)' % x, self.db_fields).setData(Qt.UserRole, x)

        # Restore the activated fields from last use
        fields = frozenset(gprefs.get(self.name+'_db_fields', self.all_fields))
        for x in range(self.db_fields.count()):
            item = self.db_fields.item(x)
            item.setCheckState(Qt.Checked if unicode(item.data(Qt.UserRole)) in fields else Qt.Unchecked)
Exemplo n.º 4
0
    def __init__(self, mi=None, prefs=None, parent=None):
        QDialog.__init__(self, parent)
        self.setWindowTitle(_('Cover generation settings'))
        self.l = l = QVBoxLayout(self)
        self.setLayout(l)
        self.settings = CoverSettingsWidget(mi=mi, prefs=prefs, parent=self)
        l.addWidget(self.settings)
        self.save_settings = ss = QCheckBox(
            _('Save these settings as the &defaults for future use'))
        ss.setChecked(
            gprefs.get('cover_generation_save_settings_for_future', True))
        l.addWidget(ss)
        self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok
                                        | QDialogButtonBox.Cancel)
        l.addWidget(bb)
        bb.accepted.connect(self.accept), bb.rejected.connect(self.reject)
        bb.b = b = bb.addButton(_('Restore &defaults'), bb.ActionRole)
        b.clicked.connect(self.restore_defaults)
        ss.setToolTip('<p>' + _(
            'Save the current settings as the settings to use always instead of just this time. Remember that'
            ' for styles and colors the actual style or color used is chosen at random from'
            ' the list of checked styles/colors.'))

        self.resize(self.sizeHint())
        geom = gprefs.get('cover_settings_dialog_geom', None)
        if geom is not None:
            self.restoreGeometry(geom)
        self.prefs_for_rendering = None
Exemplo n.º 5
0
 def initializePage(self):
     opf = gprefs.get('add wizard one per folder', True)
     self.opt_one_per_folder.setChecked(opf)
     self.opt_many_per_folder.setChecked(not opf)
     add_dir = gprefs.get('add wizard root folder', None)
     if add_dir is not None:
         self.opt_root_folder.setText(add_dir)
Exemplo n.º 6
0
    def initialize(self, name, db):  # not working properly to update
        from calibre.library.catalogs import FIELDS

        self.all_fields = [x for x in FIELDS if x != 'all']
        # add custom columns
        for x in sorted(db.custom_field_keys()):
            self.all_fields.append(x)
            if db.field_metadata[x]['datatype'] == 'series':
                self.all_fields.append(x+'_index')
        # populate
        for x in self.all_fields:
            QListWidgetItem(x, self.db_fields)

        self.name = name
        fields = gprefs.get(name+'_db_fields', self.all_fields)
        # Restore the activated db_fields from last use
        for x in xrange(self.db_fields.count()):
            item = self.db_fields.item(x)
            item.setSelected(unicode(item.text()) in fields)
        self.bibfile_enc.clear()
        self.bibfile_enc.addItems(['utf-8', 'cp1252', 'ascii/LaTeX'])
        self.bibfile_enctag.clear()
        self.bibfile_enctag.addItems(['strict', 'replace', 'ignore',
            'backslashreplace'])
        self.bib_entry.clear()
        self.bib_entry.addItems(['mixed', 'misc', 'book'])
        # Update dialog fields from stored options
        for opt in self.OPTION_FIELDS:
            opt_value = gprefs.get(self.name + '_' + opt[0], opt[1])
            if opt[0] in ['bibfile_enc', 'bibfile_enctag', 'bib_entry']:
                getattr(self, opt[0]).setCurrentIndex(opt_value)
            elif opt[0] in ['impcit', 'addfiles'] :
                getattr(self, opt[0]).setChecked(opt_value)
            else:
                getattr(self, opt[0]).setText(opt_value)
Exemplo n.º 7
0
def normalize_settings(parser, opts):
    saved_opts = opts
    dh = gprefs.get('lrf_viewer_hyphenate', None)
    if dh is not None:
        opts.hyphenate = bool(dh)
    wb = gprefs.get('lrf_viewer_white_background', None)
    if wb is not None:
        opts.white_background = bool(wb)
    return saved_opts
Exemplo n.º 8
0
def get_saved_field_data(name, all_fields):
    db = get_gui().current_db
    val = db.new_api.pref('catalog-field-data-for-' + name)
    if val is None:
        sort_order = gprefs.get(name + '_db_fields_sort_order', {})
        fields = frozenset(gprefs.get(name+'_db_fields', all_fields))
    else:
        sort_order = val['sort_order']
        fields = frozenset(val['fields'])
    return sort_order, fields
Exemplo n.º 9
0
 def restore_state(self):
     try:
         geom = gprefs.get('jobs_dialog_geometry', bytearray(''))
         self.restoreGeometry(QByteArray(geom))
         state = gprefs.get('jobs view column layout2', bytearray(''))
         self.jobs_view.horizontalHeader().restoreState(QByteArray(state))
     except:
         pass
     idx = self.jobs_view.model().index(0, 0)
     if idx.isValid():
         sm = self.jobs_view.selectionModel()
         sm.select(idx, sm.ClearAndSelect|sm.Rows)
 def initialize(self, name):
     self.name = name
     opt_value = gprefs.get(self.name + '_' + 'library_url', 'http://192.168.2.1/Calibre/Calibre Library')
     self.library_url.setText(opt_value if opt_value else '')
     self.library_url.textChanged.connect(self.library_url_changed)
     self.library_url_changed()
     opt_value = gprefs.get(self.name + '_' + 'exclusion_tags', u'[' + _('Catalog') + u']')
     try:
         opt_value = eval(opt_value)
         opt_value = ', '.join(opt_value)
     except:
         opt_value = None
     self.excluded_tags.setText(opt_value if opt_value else '')
Exemplo n.º 11
0
    def __init__(self, parent, cover_flow):
        QDialog.__init__(self, parent)
        self._layout = QStackedLayout()
        self.setLayout(self._layout)
        self.setWindowTitle(_('Browse by covers'))
        self.layout().addWidget(cover_flow)

        geom = gprefs.get('cover_browser_dialog_geometry', bytearray(''))
        geom = QByteArray(geom)
        if not self.restoreGeometry(geom):
            h, w = available_height()-60, int(available_width()/1.5)
            self.resize(w, h)
        self.action_fs_toggle = a = QAction(self)
        self.addAction(a)
        a.setShortcuts([QKeySequence('F11', QKeySequence.PortableText),
            QKeySequence('Ctrl+Shift+F', QKeySequence.PortableText)])
        a.triggered.connect(self.toggle_fullscreen)
        self.action_esc_fs = a = QAction(self)
        a.triggered.connect(self.show_normal)
        self.addAction(a)
        a.setShortcuts([QKeySequence('Esc', QKeySequence.PortableText)])

        self.pre_fs_geom = None
        cover_flow.setFocus(Qt.OtherFocusReason)
        self.view_action = a = QAction(self)
        iactions = parent.iactions
        self.addAction(a)
        a.setShortcuts(list(iactions['View'].menuless_qaction.shortcuts())+
                [QKeySequence(Qt.Key_Space)])
        a.triggered.connect(iactions['View'].menuless_qaction.trigger)
        self.sd_action = a = QAction(self)
        self.addAction(a)
        a.setShortcuts(list(iactions['Send To Device'].
            menuless_qaction.shortcuts()))
        a.triggered.connect(iactions['Send To Device'].menuless_qaction.trigger)
Exemplo n.º 12
0
    def __init__(self, parent, db, book_id,
            preferred_input_format=None, preferred_output_format=None):
        QDialog.__init__(self, parent)
        self.setupUi(self)
        self.opt_individual_saved_settings.setVisible(False)
        self.db, self.book_id = db, book_id

        self.setup_input_output_formats(self.db, self.book_id, preferred_input_format,
                preferred_output_format)
        self.setup_pipeline()

        self.input_formats.currentIndexChanged[str].connect(self.setup_pipeline)
        self.output_formats.currentIndexChanged[str].connect(self.setup_pipeline)
        self.groups.setSpacing(5)
        self.groups.activated[(QModelIndex)].connect(self.show_pane)
        self.groups.clicked[(QModelIndex)].connect(self.show_pane)
        self.groups.entered[(QModelIndex)].connect(self.show_group_help)
        rb = self.buttonBox.button(self.buttonBox.RestoreDefaults)
        rb.setText(_('Restore &defaults'))
        rb.clicked.connect(self.restore_defaults)
        self.groups.setMouseTracking(True)
        geom = gprefs.get('convert_single_dialog_geom', None)
        if geom:
            self.restoreGeometry(geom)
        else:
            self.resize(self.sizeHint())
Exemplo n.º 13
0
 def get_old_state(self):
     ans = None
     name = unicode(self.objectName())
     if name:
         name += ' books view state'
         ans = gprefs.get(name, None)
     return ans
Exemplo n.º 14
0
 def get_old_state(self):
     ans = None
     name = unicode(self.objectName())
     if name:
         name += ' books view state'
         db = getattr(self.model(), 'db', None)
         if db is not None:
             ans = db.prefs.get(name, None)
             if ans is None:
                 ans = gprefs.get(name, None)
                 try:
                     del gprefs[name]
                 except:
                     pass
                 if ans is not None:
                     db.new_api.set_pref(name, ans)
             else:
                 injected = False
                 if not ans.get('last_modified_injected', False):
                     injected = True
                     ans['last_modified_injected'] = True
                     hc = ans.get('hidden_columns', [])
                     if 'last_modified' not in hc:
                         hc.append('last_modified')
                 if not ans.get('languages_injected', False):
                     injected = True
                     ans['languages_injected'] = True
                     hc = ans.get('hidden_columns', [])
                     if 'languages' not in hc:
                         hc.append('languages')
                 if injected:
                     db.new_api.set_pref(name, ans)
     return ans
Exemplo n.º 15
0
    def process_result(self, group_id, result):
        if result.err:
            mi = self.report_metadata_failure(group_id, result.traceback)
            paths = self.file_groups[group_id]
            has_cover = False
            duplicate_info = set() if self.add_formats_to_existing else False
        else:
            paths, opf, has_cover, duplicate_info = result.value
            try:
                mi = OPF(BytesIO(opf), basedir=self.tdir, populate_spine=False, try_to_guess_cover=False).to_book_metadata()
                mi.read_metadata_failed = False
            except Exception:
                mi = self.report_metadata_failure(group_id, traceback.format_exc())

        if mi.is_null('title'):
            for path in paths:
                mi.title = os.path.splitext(os.path.basename(path))[0]
                break
        if mi.application_id == '__calibre_dummy__':
            mi.application_id = None
        if gprefs.get('tag_map_on_add_rules'):
            from calibre.ebooks.metadata.tag_mapper import map_tags
            mi.tags = map_tags(mi.tags, gprefs['tag_map_on_add_rules'])
        if self.author_map_rules:
            from calibre.ebooks.metadata.author_mapper import map_authors
            new_authors = map_authors(mi.authors, self.author_map_rules)
            if new_authors != mi.authors:
                mi.authors = new_authors
                if self.db is None:
                    mi.author_sort = authors_to_sort_string(mi.authors)
                else:
                    mi.author_sort = self.db.author_sort_from_authors(mi.authors)

        self.pd.msg = mi.title

        cover_path = os.path.join(self.tdir, '%s.cdata' % group_id) if has_cover else None

        if self.db is None:
            if paths:
                self.items.append((mi, cover_path, paths))
            return

        if self.add_formats_to_existing:
            identical_book_ids = find_identical_books(mi, self.find_identical_books_data)
            if identical_book_ids:
                try:
                    self.merge_books(mi, cover_path, paths, identical_book_ids)
                except Exception:
                    a = self.report.append
                    a(''), a('-' * 70)
                    a(_('Failed to merge the book: ') + mi.title)
                    [a('\t' + f) for f in paths]
                    a(_('With error:')), a(traceback.format_exc())
            else:
                self.add_book(mi, cover_path, paths)
        else:
            if duplicate_info or icu_lower(mi.title or _('Unknown')) in self.added_duplicate_info:
                self.duplicates.append((mi, cover_path, paths))
            else:
                self.add_book(mi, cover_path, paths)
Exemplo n.º 16
0
 def read_rules(self):
     try:
         self.compiled_rules = tuple(map(compile_rule, gprefs.get('add_filter_rules', ())))
     except Exception:
         self.compiled_rules = ()
         import traceback
         traceback.print_exc()
Exemplo n.º 17
0
    def __init__(self, parent, book_id, fmts, db):
        QDialog.__init__(self, parent)
        self.book_id, self.fmts, self.db_ref = book_id, fmts, weakref.ref(db)
        self._exploded = None
        self._cleanup_dirs = []
        self._cleanup_files = []

        self.setup_ui()
        self.setWindowTitle(_('Tweak Book') + ' - ' + db.title(book_id,
            index_is_id=True))

        button = self.fmt_choice_buttons[0]
        button_map = {unicode(x.text()):x for x in self.fmt_choice_buttons}
        of = prefs['output_format'].upper()
        df = tweaks.get('default_tweak_format', None)
        lf = gprefs.get('last_tweak_format', None)
        if df and df.lower() == 'remember' and lf in button_map:
            button = button_map[lf]
        elif df and df.upper() in button_map:
            button = button_map[df.upper()]
        elif of in button_map:
            button = button_map[of]
        button.setChecked(True)

        self.init_state()
        for button in self.fmt_choice_buttons:
            button.toggled.connect(self.init_state)
Exemplo n.º 18
0
    def __init__(self, current_cover=None, parent=None):
        QDialog.__init__(self, parent)
        self.current_cover = current_cover
        self.log = Log()
        self.cover_pixmap = None

        self.setWindowTitle(_('Downloading cover...'))
        self.setWindowIcon(QIcon(I('default_cover.png')))

        self.l = l = QVBoxLayout()
        self.setLayout(l)

        self.covers_widget = CoversWidget(self.log, self.current_cover, parent=self)
        self.covers_widget.chosen.connect(self.accept)
        l.addWidget(self.covers_widget)

        self.resize(850, 600)

        self.finished.connect(self.cleanup)

        self.bb = QDialogButtonBox(QDialogButtonBox.Cancel|QDialogButtonBox.Ok)
        l.addWidget(self.bb)
        self.log_button = self.bb.addButton(_('&View log'), self.bb.ActionRole)
        self.log_button.clicked.connect(self.view_log)
        self.log_button.setIcon(QIcon(I('debug.png')))
        self.bb.rejected.connect(self.reject)
        self.bb.accepted.connect(self.accept)

        geom = gprefs.get('single-cover-fetch-dialog-geometry', None)
        if geom is not None:
            self.restoreGeometry(geom)
Exemplo n.º 19
0
def show_config_widget(category, name, gui=None, show_restart_msg=False,
        parent=None, never_shutdown=False):
    '''
    Show the preferences plugin identified by category and name

    :param gui: gui instance, if None a hidden gui is created
    :param show_restart_msg: If True and the preferences plugin indicates a
    restart is required, show a message box telling the user to restart
    :param parent: The parent of the displayed dialog

    :return: True iff a restart is required for the changes made by the user to
    take effect
    '''
    from calibre.gui2 import gprefs
    pl = get_plugin(category, name)
    d = ConfigDialog(parent)
    d.resize(750, 550)
    conf_name = 'config_widget_dialog_geometry_%s_%s'%(category, name)
    geom = gprefs.get(conf_name, None)
    d.setWindowTitle(_('Configure ') + name)
    d.setWindowIcon(QIcon(I('config.png')))
    bb = QDialogButtonBox(d)
    bb.setStandardButtons(bb.Apply|bb.Cancel|bb.RestoreDefaults)
    bb.accepted.connect(d.accept)
    bb.rejected.connect(d.reject)
    w = pl.create_widget(d)
    d.set_widget(w)
    bb.button(bb.RestoreDefaults).clicked.connect(w.restore_defaults)
    bb.button(bb.RestoreDefaults).setEnabled(w.supports_restoring_to_defaults)
    bb.button(bb.Apply).setEnabled(False)
    bb.button(bb.Apply).clicked.connect(d.accept)
    def onchange():
        b = bb.button(bb.Apply)
        b.setEnabled(True)
        b.setDefault(True)
        b.setAutoDefault(True)
    w.changed_signal.connect(onchange)
    bb.button(bb.Cancel).setFocus(True)
    l = QVBoxLayout()
    d.setLayout(l)
    l.addWidget(w)
    l.addWidget(bb)
    mygui = gui is None
    if gui is None:
        gui = init_gui()
        mygui = True
    w.genesis(gui)
    w.initialize()
    if geom is not None:
        d.restoreGeometry(geom)
    d.exec_()
    geom = bytearray(d.saveGeometry())
    gprefs[conf_name] = geom
    rr = getattr(d, 'restart_required', False)
    if show_restart_msg and rr:
        from calibre.gui2 import warning_dialog
        warning_dialog(gui, 'Restart required', 'Restart required', show=True)
    if mygui and not never_shutdown:
        gui.shutdown()
    return rr
Exemplo n.º 20
0
    def __init__(self, title, html, parent=None, unique_name=None):
        QDialog.__init__(self, parent)
        self.l = l = QVBoxLayout()
        self.setLayout(l)

        self.tb = QTextBrowser(self)
        self.tb.setHtml('<pre style="font-family: monospace">%s</pre>' % html)
        l.addWidget(self.tb)

        self.bb = QDialogButtonBox(QDialogButtonBox.Ok)
        self.bb.accepted.connect(self.accept)
        self.bb.rejected.connect(self.reject)
        self.copy_button = self.bb.addButton(_('Copy to clipboard'),
                self.bb.ActionRole)
        self.copy_button.setIcon(QIcon(I('edit-copy.png')))
        self.copy_button.clicked.connect(self.copy_to_clipboard)
        l.addWidget(self.bb)

        self.unique_name = unique_name or 'view-log-dialog'
        self.finished.connect(self.dialog_closing)
        self.resize(QSize(700, 500))
        geom = gprefs.get(self.unique_name, None)
        if geom is not None:
            self.restoreGeometry(geom)

        self.setModal(False)
        self.setWindowTitle(title)
        self.setWindowIcon(QIcon(I('debug.png')))
        self.show()
Exemplo n.º 21
0
 def initialize(self, name, db):
     self.name = name
     fields = gprefs.get(name+'_db_fields', self.all_fields)
     # Restore the activated fields from last use
     for x in range(self.db_fields.count()):
         item = self.db_fields.item(x)
         item.setSelected(unicode(item.text()) in fields)
Exemplo n.º 22
0
 def setup_ui(self):
     self.resize(678, 430)
     self.setWindowTitle(_("Add books by ISBN"))
     self.setWindowIcon(QIcon(I('add_book.png')))
     self.l = l = QVBoxLayout(self)
     self.h = h = QHBoxLayout()
     l.addLayout(h)
     self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel, self)
     bb.button(bb.Ok).setText(_('&OK'))
     l.addWidget(bb), bb.accepted.connect(self.accept), bb.rejected.connect(self.reject)
     self.ll = l = QVBoxLayout()
     h.addLayout(l)
     self.isbn_box = i = QPlainTextEdit(self)
     i.setFocus(Qt.OtherFocusReason)
     l.addWidget(i)
     self.paste_button = b = QPushButton(_("&Paste from clipboard"), self)
     l.addWidget(b), b.clicked.connect(self.paste)
     self.lll = l  = QVBoxLayout()
     h.addLayout(l)
     self.label = la = QLabel(_(
         "<p>Enter a list of ISBNs in the box to the left, one per line. calibre will automatically"
         " create entries for books based on the ISBN and download metadata and covers for them.</p>\n"
         "<p>Any invalid ISBNs in the list will be ignored.</p>\n"
         "<p>You can also specify a file that will be added with each ISBN. To do this enter the full"
         " path to the file after a <code>>></code>.  For example:</p>\n"
         "<p><code>9788842915232 >> %s</code></p>"), self)
     l.addWidget(la), la.setWordWrap(True)
     l.addSpacing(20)
     self.la2 = la = QLabel(_("&Tags to set on created book entries:"), self)
     l.addWidget(la)
     self.add_tags = le = QLineEdit(self)
     le.setText(', '.join(gprefs.get('add from ISBN tags', [])))
     la.setBuddy(le)
     l.addWidget(le)
     l.addStretch(10)
Exemplo n.º 23
0
    def initialize(self, defaults=False):
        # Get all itmes in the combobox. If we are resting
        # to defaults we don't want to lose what the user
        # has added.
        val_hist = [unicode(self.re.lineEdit().text())] + [
            unicode(self.re.itemText(i)) for i in xrange(self.re.count())
        ]
        self.re.clear()

        if defaults:
            val = prefs.defaults["filename_pattern"]
        else:
            val = prefs["filename_pattern"]
        self.re.lineEdit().setText(val)

        val_hist += gprefs.get(
            "filename_pattern_history",
            [
                "(?P<title>.+)",
                "(?P<author>[^_-]+) -?\s*(?P<series>[^_0-9-]*)(?P<series_index>[0-9]*)\s*-\s*(?P<title>[^_].+) ?",
            ],
        )
        if val in val_hist:
            del val_hist[val_hist.index(val)]
        val_hist.insert(0, val)
        for v in val_hist:
            # Ensure we don't have duplicate items.
            if v and self.re.findText(v) == -1:
                self.re.addItem(v)
        self.re.setCurrentIndex(0)
Exemplo n.º 24
0
    def __init__(self, db, book_id, regex, doc=None, parent=None):
        QDialog.__init__(self, parent)
        self.setupUi(self)

        self.regex.setText(regex)
        self.regex_valid()

        if not db or not book_id:
            button = self.button_box.addButton(QDialogButtonBox.Open)
            button.clicked.connect(self.open_clicked)
        elif not doc and not self.select_format(db, book_id):
            self.cancelled = True
            return

        if doc:
            self.preview.setPlainText(doc)

        self.cancelled = False
        self.button_box.accepted.connect(self.accept)
        self.regex.textChanged[str].connect(self.regex_valid)
        for src, slot in (('test', 'do'), ('previous', 'goto'), ('next',
            'goto')):
            getattr(self, src).clicked.connect(getattr(self, '%s_%s'%(slot,
                src)))
        self.test.setDefault(True)

        self.match_locs = []
        geom = gprefs.get('regex_builder_geometry', None)
        if geom is not None:
            self.restoreGeometry(QByteArray(geom))
        self.finished.connect(self.save_state)
Exemplo n.º 25
0
 def do_map(self, book_ids, selected):
     from calibre.ebooks.metadata.tag_mapper import map_tags
     from calibre.gui2.tag_mapper import RulesDialog
     from calibre.gui2.device import BusyCursor
     d = RulesDialog(self.gui)
     d.setWindowTitle(ngettext(
         'Map tags for one book in the library',
         'Map tags for {} books in the library', len(book_ids)).format(len(book_ids)))
     d.rules = gprefs.get('library-tag-mapper-ruleset', ())
     txt = ngettext(
         'The changes will be applied to the <b>selected book</b>',
         'The changes will be applied to the <b>{} selected books</b>', len(book_ids)) if selected else ngettext(
         'The changes will be applied to <b>one book in the library</b>',
         'The changes will be applied to <b>{} books in the library</b>', len(book_ids))
     d.edit_widget.msg_label.setText(d.edit_widget.msg_label.text() + '<p>' + txt.format(len(book_ids)))
     if d.exec_() != d.Accepted:
         return
     with BusyCursor():
         rules = d.rules
         gprefs.set('library-tag-mapper-ruleset', rules)
         db = self.gui.current_db.new_api
         tag_map = db.all_field_for('tags', book_ids)
         changed_tag_map = {}
         for book_id, tags in iteritems(tag_map):
             tags = list(tags)
             new_tags = map_tags(tags, rules)
             if tags != new_tags:
                 changed_tag_map[book_id] = new_tags
         if changed_tag_map:
             db.set_field('tags', changed_tag_map)
             self.gui.library_view.model().refresh_ids(tuple(changed_tag_map), current_row=self.gui.library_view.currentIndex().row())
Exemplo n.º 26
0
    def __init__(self, title=None, parent=None):
        QDialog.__init__(self, parent)

        t = title or current_container().mi.title
        self.book_title = t
        self.setWindowTitle(_('Edit the ToC in %s')%t)
        self.setWindowIcon(QIcon(I('toc.png')))

        l = self.l = QVBoxLayout()
        self.setLayout(l)

        self.stacks = s = QStackedWidget(self)
        l.addWidget(s)
        self.toc_view = TOCView(self)
        self.toc_view.add_new_item.connect(self.add_new_item)
        s.addWidget(self.toc_view)
        self.item_edit = ItemEdit(self)
        s.addWidget(self.item_edit)

        bb = self.bb = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
        l.addWidget(bb)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)

        self.read_toc()

        self.resize(950, 630)
        geom = gprefs.get('toc_editor_window_geom', None)
        if geom is not None:
            self.restoreGeometry(bytes(geom))
Exemplo n.º 27
0
    def __init__(self, parent, db, book_id,
            preferred_input_format=None, preferred_output_format=None):
        ResizableDialog.__init__(self, parent)
        self.opt_individual_saved_settings.setVisible(False)
        self.db, self.book_id = db, book_id

        self.setup_input_output_formats(self.db, self.book_id, preferred_input_format,
                preferred_output_format)
        self.setup_pipeline()

        self.connect(self.input_formats, SIGNAL('currentIndexChanged(QString)'),
                self.setup_pipeline)
        self.connect(self.output_formats, SIGNAL('currentIndexChanged(QString)'),
                self.setup_pipeline)
        self.connect(self.groups, SIGNAL('activated(QModelIndex)'),
                self.show_pane)
        self.connect(self.groups, SIGNAL('clicked(QModelIndex)'),
                self.show_pane)
        self.connect(self.groups, SIGNAL('entered(QModelIndex)'),
                self.show_group_help)
        rb = self.buttonBox.button(self.buttonBox.RestoreDefaults)
        self.connect(rb, SIGNAL('clicked()'), self.restore_defaults)
        self.groups.setMouseTracking(True)
        geom = gprefs.get('convert_single_dialog_geom', None)
        if geom:
            self.restoreGeometry(geom)
Exemplo n.º 28
0
 def get_old_state(self):
     ans = None
     name = unicode(self.objectName())
     if name:
         name += " books view state"
         db = getattr(self.model(), "db", None)
         if db is not None:
             ans = db.prefs.get(name, None)
             if ans is None:
                 ans = gprefs.get(name, None)
                 try:
                     del gprefs[name]
                 except:
                     pass
                 if ans is not None:
                     db.new_api.set_pref(name, ans)
             else:
                 injected = False
                 if not ans.get("last_modified_injected", False):
                     injected = True
                     ans["last_modified_injected"] = True
                     hc = ans.get("hidden_columns", [])
                     if "last_modified" not in hc:
                         hc.append("last_modified")
                 if not ans.get("languages_injected", False):
                     injected = True
                     ans["languages_injected"] = True
                     hc = ans.get("hidden_columns", [])
                     if "languages" not in hc:
                         hc.append("languages")
                 if injected:
                     db.new_api.set_pref(name, ans)
     return ans
Exemplo n.º 29
0
Arquivo: add.py Projeto: AEliu/calibre
    def scan(self):

        try:
            compiled_rules = tuple(map(compile_rule, gprefs.get('add_filter_rules', ())))
        except Exception:
            compiled_rules = ()
            import traceback
            traceback.print_exc()

        def find_files(root):
            for dirpath, dirnames, filenames in os.walk(root):
                for files in find_books_in_directory(dirpath, self.single_book_per_directory, compiled_rules=compiled_rules):
                    if self.abort_scan:
                        return
                    self.file_groups[len(self.file_groups)] = files

        def extract(source):
            tdir = tempfile.mkdtemp(suffix='_archive', dir=self.tdir)
            if source.lower().endswith('.zip'):
                from calibre.utils.zipfile import ZipFile
                try:
                    with ZipFile(source) as zf:
                        zf.extractall(tdir)
                except Exception:
                    prints('Corrupt ZIP file, trying to use local headers')
                    from calibre.utils.localunzip import extractall
                    extractall(source, tdir)
            elif source.lower().endswith('.rar'):
                from calibre.utils.unrar import extract
                extract(source, tdir)
            return tdir

        try:
            if isinstance(self.source, basestring):
                find_files(self.source)
                self.ignore_opf = True
            else:
                unreadable_files = []
                for path in self.source:
                    if self.abort_scan:
                        return
                    if os.access(path, os.R_OK):
                        if self.list_of_archives:
                            find_files(extract(path))
                            self.ignore_opf = True
                        else:
                            self.file_groups[len(self.file_groups)] = [path]
                    else:
                        unreadable_files.append(path)
                if unreadable_files:
                    if not self.file_groups:
                        self.scan_error = _('You do not have permission to read the selected file(s).') + '\n'
                        self.scan_error += '\n'.join(unreadable_files)
                    else:
                        a = self.report.append
                        for f in unreadable_files:
                            a(_('Could not add %s as you do not have permission to read the file' % f))
                            a('')
        except Exception:
            self.scan_error = traceback.format_exc()
Exemplo n.º 30
0
    def __init__(self, parent, db):
        QDialog.__init__(self, parent)
        self.setupUi(self)
        for val, text in [(0, '')] + [(i, date(2010, i, 1).strftime('%B')) for i in xrange(1, 13)]:
            self.date_month.addItem(text, val)
        for val, text in [('today', _('Today')), ('yesterday', _('Yesterday')), ('thismonth', _('This month'))]:
            self.date_human.addItem(text, val)
        self.date_year.setValue(now().year)
        self.date_day.setSpecialValueText(u' \xa0')
        vals = [((v['search_terms'] or [k])[0], v['name'] or k) for k, v in db.field_metadata.iteritems() if v.get('datatype', None) == 'datetime']
        for k, v in sorted(vals, key=lambda (k, v): sort_key(v)):
            self.date_field.addItem(v, k)

        self.date_year.valueChanged.connect(lambda : self.sel_date.setChecked(True))
        self.date_month.currentIndexChanged.connect(lambda : self.sel_date.setChecked(True))
        self.date_day.valueChanged.connect(lambda : self.sel_date.setChecked(True))
        self.date_daysago.valueChanged.connect(lambda : self.sel_daysago.setChecked(True))
        self.date_human.currentIndexChanged.connect(lambda : self.sel_human.setChecked(True))
        init_dateop(self.dateop_date)
        self.sel_date.setChecked(True)
        self.mc = ''
        searchables = sorted(db.field_metadata.searchable_fields(),
                             key=lambda x: sort_key(x if x[0] != '#' else x[1:]))
        self.general_combo.addItems(searchables)

        all_authors = db.all_authors()
        all_authors.sort(key=lambda x : sort_key(x[1]))
        self.authors_box.setEditText('')
        self.authors_box.set_separator('&')
        self.authors_box.set_space_before_sep(True)
        self.authors_box.set_add_separator(tweaks['authors_completer_append_separator'])
        self.authors_box.update_items_cache(db.all_author_names())

        all_series = db.all_series()
        all_series.sort(key=lambda x : sort_key(x[1]))
        self.series_box.set_separator(None)
        self.series_box.update_items_cache([x[1] for x in all_series])
        self.series_box.show_initial_value('')

        all_tags = db.all_tags()
        self.tags_box.update_items_cache(all_tags)

        self.box_last_values = copy.deepcopy(box_values)
        if self.box_last_values:
            for k,v in self.box_last_values.items():
                if k == 'general_index':
                    continue
                getattr(self, k).setText(v)
            self.general_combo.setCurrentIndex(
                    self.general_combo.findText(self.box_last_values['general_index']))

        self.clear_button.clicked.connect(self.clear_button_pushed)

        current_tab = gprefs.get('advanced search dialog current tab', 0)
        self.tabWidget.setCurrentIndex(current_tab)
        if current_tab == 1:
            self.matchkind.setCurrentIndex(last_matchkind)

        self.tabWidget.currentChanged[int].connect(self.tab_changed)
        self.tab_changed(current_tab)
Exemplo n.º 31
0
    def __init__(self, gui, view, row):
        QDialog.__init__(self, gui, flags=Qt.Window)
        Ui_Quickview.__init__(self)
        self.setupUi(self)
        self.isClosed = False

        self.books_table_column_widths = None
        try:
            self.books_table_column_widths = \
                        gprefs.get('quickview_dialog_books_table_widths', None)
            geom = gprefs.get('quickview_dialog_geometry', bytearray(''))
            self.restoreGeometry(QByteArray(geom))
        except:
            pass

        # Remove the help button from the window title bar
        icon = self.windowIcon()
        self.setWindowFlags(self.windowFlags()
                            & (~Qt.WindowContextHelpButtonHint))
        self.setWindowIcon(icon)

        self.db = view.model().db
        self.view = view
        self.gui = gui
        self.is_closed = False
        self.current_book_id = None
        self.current_key = None
        self.last_search = None
        self.current_column = None
        self.current_item = None
        self.no_valid_items = False

        self.items.setSelectionMode(QAbstractItemView.SingleSelection)
        self.items.currentTextChanged.connect(self.item_selected)

        # Set up the books table columns
        self.books_table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.books_table.setSelectionMode(QAbstractItemView.SingleSelection)
        self.books_table.setColumnCount(3)
        t = QTableWidgetItem(_('Title'))
        self.books_table.setHorizontalHeaderItem(0, t)
        t = QTableWidgetItem(_('Authors'))
        self.books_table.setHorizontalHeaderItem(1, t)
        t = QTableWidgetItem(_('Series'))
        self.books_table.setHorizontalHeaderItem(2, t)
        self.books_table_header_height = self.books_table.height()
        self.books_table.cellDoubleClicked.connect(self.book_doubleclicked)
        self.books_table.sortByColumn(0, Qt.AscendingOrder)

        # get the standard table row height. Do this here because calling
        # resizeRowsToContents can word wrap long cell contents, creating
        # double-high rows
        self.books_table.setRowCount(1)
        self.books_table.setItem(0, 0, TableItem('A', ''))
        self.books_table.resizeRowsToContents()
        self.books_table_row_height = self.books_table.rowHeight(0)
        self.books_table.setRowCount(0)

        # Add the data
        self.refresh(row)

        self.view.clicked.connect(self.slave)
        self.change_quickview_column.connect(self.slave)
        QCoreApplication.instance().aboutToQuit.connect(self.save_state)
        self.search_button.clicked.connect(self.do_search)
        view.model().new_bookdisplay_data.connect(self.book_was_changed)
Exemplo n.º 32
0
 def load_settings(self, name):
     saved = gprefs.get('xpath_toc_settings', {}).get(name, {})
     for i, w in enumerate(self.widgets):
         txt = saved.get(i, '')
         w.edit.setText(txt)
Exemplo n.º 33
0
 def __init__(self, parent, unique_pref_name):
     QDialog.__init__(self, parent)
     self.unique_pref_name = unique_pref_name
     self.geom = gprefs.get(unique_pref_name, None)
     self.finished.connect(self.dialog_closing)
Exemplo n.º 34
0
    def initialize(self, library_path, db, listener, actions, show_gui=True):
        opts = self.opts
        self.preferences_action, self.quit_action = actions
        self.library_path = library_path
        self.library_broker = GuiLibraryBroker(db)
        self.content_server = None
        self.server_change_notification_timer = t = QTimer(self)
        self.server_changes = Queue()
        t.setInterval(1000), t.timeout.connect(self.handle_changes_from_server_debounced), t.setSingleShot(True)
        self._spare_pool = None
        self.must_restart_before_config = False
        self.listener = Listener(listener)
        self.check_messages_timer = QTimer()
        self.check_messages_timer.timeout.connect(self.another_instance_wants_to_talk)
        self.check_messages_timer.start(1000)

        for ac in self.iactions.values():
            try:
                ac.do_genesis()
            except Exception:
                # Ignore errors in third party plugins
                import traceback
                traceback.print_exc()
                if getattr(ac, 'plugin_path', None) is None:
                    raise
        self.donate_action = QAction(QIcon(I('donate.png')),
                _('&Donate to support calibre'), self)
        for st in self.istores.values():
            st.do_genesis()
        MainWindowMixin.init_main_window_mixin(self, db)

        # Jobs Button {{{
        self.job_manager = JobManager()
        self.jobs_dialog = JobsDialog(self, self.job_manager)
        self.jobs_button = JobsButton(parent=self)
        self.jobs_button.initialize(self.jobs_dialog, self.job_manager)
        # }}}

        LayoutMixin.init_layout_mixin(self)
        DeviceMixin.init_device_mixin(self)

        self.progress_indicator = ProgressIndicator(self)
        self.progress_indicator.pos = (0, 20)
        self.verbose = opts.verbose
        self.get_metadata = GetMetadata()
        self.upload_memory = {}
        self.metadata_dialogs = []
        self.default_thumbnail = None
        self.tb_wrapper = textwrap.TextWrapper(width=40)
        self.viewers = collections.deque()
        self.system_tray_icon = None
        do_systray = config['systray_icon'] or opts.start_in_tray
        if do_systray:
            self.system_tray_icon = factory(app_id='com.calibre-ebook.gui').create_system_tray_icon(parent=self, title='calibre')
        if self.system_tray_icon is not None:
            self.system_tray_icon.setIcon(QIcon(I('lt.png', allow_user_override=False)))
            if not (iswindows or isosx):
                self.system_tray_icon.setIcon(QIcon.fromTheme('calibre-tray', self.system_tray_icon.icon()))
            self.system_tray_icon.setToolTip(self.jobs_button.tray_tooltip())
            self.system_tray_icon.setVisible(True)
            self.jobs_button.tray_tooltip_updated.connect(self.system_tray_icon.setToolTip)
        elif do_systray:
            prints('Failed to create system tray icon, your desktop environment probably'
                   ' does not support the StatusNotifier spec https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/')
        self.system_tray_menu = QMenu(self)
        self.toggle_to_tray_action = self.system_tray_menu.addAction(QIcon(I('page.png')), '')
        self.toggle_to_tray_action.triggered.connect(self.system_tray_icon_activated)
        self.system_tray_menu.addAction(self.donate_action)
        self.eject_action = self.system_tray_menu.addAction(
                QIcon(I('eject.png')), _('&Eject connected device'))
        self.eject_action.setEnabled(False)
        self.addAction(self.quit_action)
        self.system_tray_menu.addAction(self.quit_action)
        self.keyboard.register_shortcut('quit calibre', _('Quit calibre'),
                default_keys=('Ctrl+Q',), action=self.quit_action)
        if self.system_tray_icon is not None:
            self.system_tray_icon.setContextMenu(self.system_tray_menu)
            self.system_tray_icon.activated.connect(self.system_tray_icon_activated)
        self.quit_action.triggered[bool].connect(self.quit)
        self.donate_action.triggered[bool].connect(self.donate)
        self.minimize_action = QAction(_('Minimize the calibre window'), self)
        self.addAction(self.minimize_action)
        self.keyboard.register_shortcut('minimize calibre', self.minimize_action.text(),
                default_keys=(), action=self.minimize_action)
        self.minimize_action.triggered.connect(self.showMinimized)

        self.esc_action = QAction(self)
        self.addAction(self.esc_action)
        self.keyboard.register_shortcut('clear current search',
                _('Clear the current search'), default_keys=('Esc',),
                action=self.esc_action)
        self.esc_action.triggered.connect(self.esc)

        self.shift_esc_action = QAction(self)
        self.addAction(self.shift_esc_action)
        self.keyboard.register_shortcut('focus book list',
                _('Focus the book list'), default_keys=('Shift+Esc',),
                action=self.shift_esc_action)
        self.shift_esc_action.triggered.connect(self.shift_esc)

        self.ctrl_esc_action = QAction(self)
        self.addAction(self.ctrl_esc_action)
        self.keyboard.register_shortcut('clear virtual library',
                _('Clear the virtual library'), default_keys=('Ctrl+Esc',),
                action=self.ctrl_esc_action)
        self.ctrl_esc_action.triggered.connect(self.ctrl_esc)

        self.alt_esc_action = QAction(self)
        self.addAction(self.alt_esc_action)
        self.keyboard.register_shortcut('clear additional restriction',
                _('Clear the additional restriction'), default_keys=('Alt+Esc',),
                action=self.alt_esc_action)
        self.alt_esc_action.triggered.connect(self.clear_additional_restriction)

        # ###################### Start spare job server ########################
        QTimer.singleShot(1000, self.create_spare_pool)

        # ###################### Location Manager ########################
        self.location_manager.location_selected.connect(self.location_selected)
        self.location_manager.unmount_device.connect(self.device_manager.umount_device)
        self.location_manager.configure_device.connect(self.configure_connected_device)
        self.location_manager.update_device_metadata.connect(self.update_metadata_on_device)
        self.eject_action.triggered.connect(self.device_manager.umount_device)

        # ################### Update notification ###################
        UpdateMixin.init_update_mixin(self, opts)

        # ###################### Search boxes ########################
        SearchRestrictionMixin.init_search_restriction_mixin(self)
        SavedSearchBoxMixin.init_saved_seach_box_mixin(self)

        # ###################### Library view ########################
        LibraryViewMixin.init_library_view_mixin(self, db)
        SearchBoxMixin.init_search_box_mixin(self)  # Requires current_db

        self.library_view.model().count_changed_signal.connect(
                self.iactions['Choose Library'].count_changed)
        if not gprefs.get('quick_start_guide_added', False):
            try:
                add_quick_start_guide(self.library_view)
            except:
                import traceback
                traceback.print_exc()
        for view in ('library', 'memory', 'card_a', 'card_b'):
            v = getattr(self, '%s_view' % view)
            v.selectionModel().selectionChanged.connect(self.update_status_bar)
            v.model().count_changed_signal.connect(self.update_status_bar)

        self.library_view.model().count_changed()
        self.bars_manager.database_changed(self.library_view.model().db)
        self.library_view.model().database_changed.connect(self.bars_manager.database_changed,
                type=Qt.QueuedConnection)

        # ########################## Tags Browser ##############################
        TagBrowserMixin.init_tag_browser_mixin(self, db)
        self.library_view.model().database_changed.connect(self.populate_tb_manage_menu, type=Qt.QueuedConnection)

        # ######################## Search Restriction ##########################
        if db.prefs['virtual_lib_on_startup']:
            self.apply_virtual_library(db.prefs['virtual_lib_on_startup'])
        self.rebuild_vl_tabs()

        # ########################## Cover Flow ################################

        CoverFlowMixin.init_cover_flow_mixin(self)

        self._calculated_available_height = min(max_available_height()-15,
                self.height())
        self.resize(self.width(), self._calculated_available_height)

        self.build_context_menus()

        for ac in self.iactions.values():
            try:
                ac.gui_layout_complete()
            except:
                import traceback
                traceback.print_exc()
                if ac.plugin_path is None:
                    raise

        if config['autolaunch_server']:
            self.start_content_server()

        self.read_settings()

        self.finalize_layout()
        self.bars_manager.start_animation()
        self.set_window_title()

        for ac in self.iactions.values():
            try:
                ac.initialization_complete()
            except:
                import traceback
                traceback.print_exc()
                if ac.plugin_path is None:
                    raise
        self.set_current_library_information(current_library_name(), db.library_id,
                                             db.field_metadata)

        register_keyboard_shortcuts()
        self.keyboard.finalize()
        if show_gui:
            # Note this has to come after restoreGeometry() because of
            # https://bugreports.qt.io/browse/QTBUG-56831
            self.show()
        if self.system_tray_icon is not None and self.system_tray_icon.isVisible() and opts.start_in_tray:
            self.hide_windows()
        self.auto_adder = AutoAdder(gprefs['auto_add_path'], self)

        # Now that the gui is initialized we can restore the quickview state
        # The same thing will be true for any action-based operation with a
        # layout button
        from calibre.gui2.actions.show_quickview import get_quickview_action_plugin
        qv = get_quickview_action_plugin()
        if qv:
            qv.qv_button.restore_state()
        self.save_layout_state()

        # Collect cycles now
        gc.collect()

        QApplication.instance().shutdown_signal_received.connect(self.quit)
        if show_gui and self.gui_debug is not None:
            QTimer.singleShot(10, self.show_gui_debug_msg)

        self.iactions['Connect Share'].check_smartdevice_menus()
        QTimer.singleShot(1, self.start_smartdevice)
        QTimer.singleShot(100, self.update_toggle_to_tray_action)
Exemplo n.º 35
0
    def __init__(self, gui, initial_plugin=None, close_after_initial=False):
        QDialog.__init__(self, gui)
        self.gui = gui
        self.must_restart = False
        self.do_restart = False
        self.committed = False
        self.close_after_initial = close_after_initial

        self.resize(930, 720)
        nh, nw = min_available_height() - 25, available_width() - 10
        if nh < 0:
            nh = 800
        if nw < 0:
            nw = 600
        nh = min(self.height(), nh)
        nw = min(self.width(), nw)
        self.resize(nw, nh)

        geom = gprefs.get('preferences dialog geometry', None)
        if geom is not None:
            self.restoreGeometry(geom)

        # Center
        if islinux:
            self.move(gui.rect().center() - self.rect().center())

        self.setWindowModality(Qt.ApplicationModal)
        self.setWindowTitle(__appname__ + ' - ' + _('Preferences'))
        self.setWindowIcon(QIcon(I('config.png')))
        self.l = l = QVBoxLayout(self)

        self.stack = QStackedWidget(self)
        self.bb = QDialogButtonBox(QDialogButtonBox.Close
                                   | QDialogButtonBox.Apply
                                   | QDialogButtonBox.Discard
                                   | QDialogButtonBox.RestoreDefaults)
        self.bb.button(self.bb.Apply).clicked.connect(self.accept)
        self.bb.button(self.bb.Discard).clicked.connect(self.reject)
        self.bb.button(self.bb.RestoreDefaults).setIcon(
            QIcon(I('clear_left.png')))
        self.bb.button(self.bb.RestoreDefaults).clicked.connect(
            self.restore_defaults)
        self.wizard_button = self.bb.addButton(_('Run welcome &wizard'),
                                               self.bb.ActionRole)
        self.wizard_button.setIcon(QIcon(I('wizard.png')))
        self.wizard_button.clicked.connect(self.run_wizard,
                                           type=Qt.QueuedConnection)
        self.wizard_button.setAutoDefault(False)
        self.bb.rejected.connect(self.reject)
        self.browser = Browser(self)
        self.browser.show_plugin.connect(self.show_plugin)
        self.stack.addWidget(self.browser)
        self.scroll_area = QScrollArea(self)
        self.stack.addWidget(self.scroll_area)
        self.scroll_area.setWidgetResizable(True)

        self.setContextMenuPolicy(Qt.NoContextMenu)
        self.title_bar = TitleBar(self)
        for ac, tt in [(self.bb.Apply, _('Save changes')),
                       (self.bb.Discard, _('Cancel and return to overview'))]:
            self.bb.button(ac).setToolTip(tt)

        l.addWidget(self.title_bar), l.addWidget(self.stack), l.addWidget(
            self.bb)

        if initial_plugin is not None:
            category, name = initial_plugin[:2]
            plugin = get_plugin(category, name)
            if plugin is not None:
                self.show_plugin(plugin)
                if len(initial_plugin) > 2:
                    w = self.findChild(QWidget, initial_plugin[2])
                    if w is not None:
                        for c in self.showing_widget.children():
                            if isinstance(c, QTabWidget):
                                idx = c.indexOf(w)
                                if idx > -1:
                                    c.setCurrentIndex(idx)
                                    break
        else:
            self.hide_plugin()
Exemplo n.º 36
0
    def do_user_config(self, parent=None):
        '''
        This method shows a configuration dialog for this plugin. It returns
        True if the user clicks OK, False otherwise. The changes are
        automatically applied.
        '''
        from PyQt5.Qt import QDialog, QDialogButtonBox, QVBoxLayout, \
                QLabel, Qt, QLineEdit
        from calibre.gui2 import gprefs

        prefname = 'plugin config dialog:' + self.type + ':' + self.name
        geom = gprefs.get(prefname, None)

        config_dialog = QDialog(parent)
        button_box = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok
                                      | QDialogButtonBox.StandardButton.Cancel)
        v = QVBoxLayout(config_dialog)

        def size_dialog():
            if geom is None:
                config_dialog.resize(config_dialog.sizeHint())
            else:
                from PyQt5.Qt import QApplication
                QApplication.instance().safe_restore_geometry(
                    config_dialog, geom)

        button_box.accepted.connect(config_dialog.accept)
        button_box.rejected.connect(config_dialog.reject)
        config_dialog.setWindowTitle(_('Customize') + ' ' + self.name)
        try:
            config_widget = self.config_widget()
        except NotImplementedError:
            config_widget = None

        if isinstance(config_widget, tuple):
            from calibre.gui2 import warning_dialog
            warning_dialog(parent,
                           _('Cannot configure'),
                           config_widget[0],
                           det_msg=config_widget[1],
                           show=True)
            return False

        if config_widget is not None:
            v.addWidget(config_widget)
            v.addWidget(button_box)
            size_dialog()
            config_dialog.exec_()

            if config_dialog.result() == QDialog.DialogCode.Accepted:
                if hasattr(config_widget, 'validate'):
                    if config_widget.validate():
                        self.save_settings(config_widget)
                else:
                    self.save_settings(config_widget)
        else:
            from calibre.customize.ui import plugin_customization, \
                customize_plugin
            help_text = self.customization_help(gui=True)
            help_text = QLabel(help_text, config_dialog)
            help_text.setWordWrap(True)
            help_text.setTextInteractionFlags(
                Qt.TextInteractionFlag.LinksAccessibleByMouse
                | Qt.TextInteractionFlag.LinksAccessibleByKeyboard)
            help_text.setOpenExternalLinks(True)
            v.addWidget(help_text)
            sc = plugin_customization(self)
            if not sc:
                sc = ''
            sc = sc.strip()
            sc = QLineEdit(sc, config_dialog)
            v.addWidget(sc)
            v.addWidget(button_box)
            size_dialog()
            config_dialog.exec_()

            if config_dialog.result() == QDialog.DialogCode.Accepted:
                sc = unicode_type(sc.text()).strip()
                customize_plugin(self, sc)

        geom = bytearray(config_dialog.saveGeometry())
        gprefs[prefname] = geom

        return config_dialog.result()
Exemplo n.º 37
0
    def __init__(self,
                 parent,
                 db,
                 id_to_select,
                 select_sort,
                 select_link,
                 find_aut_func,
                 is_first_letter=False):
        QDialog.__init__(self, parent)
        Ui_EditAuthorsDialog.__init__(self)
        self.setupUi(self)

        # Remove help icon on title bar
        icon = self.windowIcon()
        self.setWindowFlags(self.windowFlags()
                            & (~Qt.WindowContextHelpButtonHint))
        self.setWindowIcon(icon)

        try:
            self.table_column_widths = \
                        gprefs.get('manage_authors_table_widths', None)
            geom = gprefs.get('manage_authors_dialog_geometry', None)
            if geom:
                QApplication.instance().safe_restore_geometry(
                    self, QByteArray(geom))
        except Exception:
            pass

        self.buttonBox.button(QDialogButtonBox.Ok).setText(_('&OK'))
        self.buttonBox.button(QDialogButtonBox.Cancel).setText(_('&Cancel'))
        self.buttonBox.accepted.connect(self.accepted)
        self.apply_vl_checkbox.stateChanged.connect(self.use_vl_changed)

        # Set up the heading for sorting
        self.table.setSelectionMode(QAbstractItemView.SingleSelection)

        self.find_aut_func = find_aut_func
        self.table.resizeColumnsToContents()
        if self.table.columnWidth(2) < 200:
            self.table.setColumnWidth(2, 200)

        # set up the cellChanged signal only after the table is filled
        self.table.cellChanged.connect(self.cell_changed)

        self.recalc_author_sort.clicked.connect(self.do_recalc_author_sort)
        self.auth_sort_to_author.clicked.connect(self.do_auth_sort_to_author)

        # Capture clicks on the horizontal header to sort the table columns
        hh = self.table.horizontalHeader()
        hh.sectionResized.connect(self.table_column_resized)
        hh.setSectionsClickable(True)
        hh.sectionClicked.connect(self.do_sort)
        hh.setSortIndicatorShown(True)

        # set up the search & filter boxes
        self.find_box.initialize('manage_authors_search')
        le = self.find_box.lineEdit()
        ac = le.findChild(QAction, QT_HIDDEN_CLEAR_ACTION)
        if ac is not None:
            ac.triggered.connect(self.clear_find)
        le.returnPressed.connect(self.do_find)
        self.find_box.editTextChanged.connect(self.find_text_changed)
        self.find_button.clicked.connect(self.do_find)
        self.find_button.setDefault(True)

        self.filter_box.initialize('manage_authors_filter')
        le = self.filter_box.lineEdit()
        ac = le.findChild(QAction, QT_HIDDEN_CLEAR_ACTION)
        if ac is not None:
            ac.triggered.connect(self.clear_filter)
        self.filter_box.lineEdit().returnPressed.connect(self.do_filter)
        self.filter_button.clicked.connect(self.do_filter)

        self.not_found_label = l = QLabel(self.table)
        l.setFrameStyle(QFrame.StyledPanel)
        l.setAutoFillBackground(True)
        l.setText(_('No matches found'))
        l.setAlignment(Qt.AlignVCenter)
        l.resize(l.sizeHint())
        l.move(10, 2)
        l.setVisible(False)
        self.not_found_label_timer = QTimer()
        self.not_found_label_timer.setSingleShot(True)
        self.not_found_label_timer.timeout.connect(
            self.not_found_label_timer_event, type=Qt.QueuedConnection)

        self.table.setContextMenuPolicy(Qt.CustomContextMenu)
        self.table.customContextMenuRequested.connect(self.show_context_menu)

        # Fetch the data
        self.authors = {}
        self.original_authors = {}
        auts = db.new_api.author_data()
        self.completion_data = []
        for id_, v in auts.items():
            name = v['name']
            name = name.replace('|', ',')
            self.completion_data.append(name)
            self.authors[id_] = {
                'name': name,
                'sort': v['sort'],
                'link': v['link']
            }
            self.original_authors[id_] = {
                'name': name,
                'sort': v['sort'],
                'link': v['link']
            }

        self.edited_icon = QIcon(I('modified.png'))
        self.empty_icon = QIcon()
        if prefs['use_primary_find_in_search']:
            self.string_contains = primary_contains
        else:
            self.string_contains = contains

        self.last_sorted_by = 'sort'
        self.author_order = 1
        self.author_sort_order = 0
        self.link_order = 1
        self.show_table(id_to_select, select_sort, select_link,
                        is_first_letter)
Exemplo n.º 38
0
    def __init__(self,
                 window,
                 cat_name,
                 tag_to_match,
                 get_book_ids,
                 sorter,
                 ttm_is_first_letter=False,
                 category=None):
        QDialog.__init__(self, window)
        Ui_TagListEditor.__init__(self)
        self.setupUi(self)
        self.verticalLayout_2.setAlignment(Qt.AlignCenter)
        self.search_box.setMinimumContentsLength(25)

        # Put the category name into the title bar
        t = self.windowTitle()
        self.category_name = cat_name
        self.category = category
        self.setWindowTitle(t + ' (' + cat_name + ')')
        # Remove help icon on title bar
        icon = self.windowIcon()
        self.setWindowFlags(self.windowFlags()
                            & (~Qt.WindowContextHelpButtonHint))
        self.setWindowIcon(icon)

        # Get saved geometry info
        try:
            self.table_column_widths = \
                        gprefs.get('tag_list_editor_table_widths', None)
        except:
            pass

        # initialization
        self.to_rename = {}
        self.to_delete = set()
        self.all_tags = {}
        self.original_names = {}

        self.ordered_tags = []
        self.sorter = sorter
        self.get_book_ids = get_book_ids
        self.text_before_editing = ''

        # Capture clicks on the horizontal header to sort the table columns
        hh = self.table.horizontalHeader()
        hh.sectionResized.connect(self.table_column_resized)
        hh.setSectionsClickable(True)
        hh.sectionClicked.connect(self.do_sort)
        hh.setSortIndicatorShown(True)

        self.last_sorted_by = 'name'
        self.name_order = 0
        self.count_order = 1
        self.was_order = 1

        self.edit_delegate = EditColumnDelegate(self.table)
        self.edit_delegate.editing_finished.connect(self.stop_editing)
        self.edit_delegate.editing_started.connect(self.start_editing)
        self.table.setItemDelegateForColumn(0, self.edit_delegate)

        if prefs['use_primary_find_in_search']:
            self.string_contains = primary_contains
        else:
            self.string_contains = contains

        self.delete_button.clicked.connect(self.delete_tags)
        self.table.delete_pressed.connect(self.delete_pressed)
        self.rename_button.clicked.connect(self.rename_tag)
        self.undo_button.clicked.connect(self.undo_edit)
        self.table.itemDoubleClicked.connect(self._rename_tag)
        self.table.itemChanged.connect(self.finish_editing)

        self.buttonBox.button(QDialogButtonBox.Ok).setText(_('&OK'))
        self.buttonBox.button(QDialogButtonBox.Cancel).setText(_('&Cancel'))
        self.buttonBox.accepted.connect(self.accepted)

        self.search_box.initialize('tag_list_search_box_' + cat_name)
        le = self.search_box.lineEdit()
        ac = le.findChild(QAction, QT_HIDDEN_CLEAR_ACTION)
        if ac is not None:
            ac.triggered.connect(self.clear_search)
        self.search_box.textChanged.connect(self.search_text_changed)
        self.search_button.clicked.connect(self.do_search)
        self.search_button.setDefault(True)
        l = QLabel(self.table)
        self.not_found_label = l
        l.setFrameStyle(QFrame.StyledPanel)
        l.setAutoFillBackground(True)
        l.setText(_('No matches found'))
        l.setAlignment(Qt.AlignVCenter)
        l.resize(l.sizeHint())
        l.move(10, 0)
        l.setVisible(False)
        self.not_found_label_timer = QTimer()
        self.not_found_label_timer.setSingleShot(True)
        self.not_found_label_timer.timeout.connect(
            self.not_found_label_timer_event, type=Qt.QueuedConnection)

        self.filter_box.initialize('tag_list_filter_box_' + cat_name)
        le = self.filter_box.lineEdit()
        ac = le.findChild(QAction, QT_HIDDEN_CLEAR_ACTION)
        if ac is not None:
            ac.triggered.connect(self.clear_filter)
        le.returnPressed.connect(self.do_filter)
        self.filter_button.clicked.connect(self.do_filter)

        self.apply_vl_checkbox.clicked.connect(self.vl_box_changed)

        self.table.setEditTriggers(QTableWidget.EditKeyPressed)

        try:
            geom = gprefs.get('tag_list_editor_dialog_geometry', None)
            if geom is not None:
                QApplication.instance().safe_restore_geometry(
                    self, QByteArray(geom))
            else:
                self.resize(self.sizeHint() + QSize(150, 100))
        except:
            pass
        # Add the data
        self.search_item_row = -1
        self.fill_in_table(None, tag_to_match, ttm_is_first_letter)

        self.table.setContextMenuPolicy(Qt.CustomContextMenu)
        self.table.customContextMenuRequested.connect(self.show_context_menu)
Exemplo n.º 39
0
    def __init__(self,
                 parent,
                 current_img,
                 current_url,
                 geom_name='viewer_image_popup_geometry'):
        QDialog.__init__(self)
        self.current_image_name = ''
        self.maximized_at_last_fullscreen = False
        self.setWindowFlag(Qt.WindowType.WindowMinimizeButtonHint)
        self.setWindowFlag(Qt.WindowType.WindowMaximizeButtonHint)
        self.avail_geom = self.screen().availableGeometry()
        self.current_img = current_img
        self.current_url = current_url
        self.factor = 1.0
        self.geom_name = geom_name

        self.scrollarea = sa = ScrollArea()
        sa.setAlignment(Qt.AlignmentFlag.AlignHCenter
                        | Qt.AlignmentFlag.AlignVCenter)
        sa.setBackgroundRole(QPalette.ColorRole.Dark)
        self.label = l = Label(sa)
        sa.toggle_fit.connect(self.toggle_fit)
        sa.setWidget(l)

        self.bb = bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        self.zi_button = zi = bb.addButton(
            _('Zoom &in'), QDialogButtonBox.ButtonRole.ActionRole)
        self.zo_button = zo = bb.addButton(
            _('Zoom &out'), QDialogButtonBox.ButtonRole.ActionRole)
        self.save_button = so = bb.addButton(
            _('&Save as'), QDialogButtonBox.ButtonRole.ActionRole)
        self.rotate_button = ro = bb.addButton(
            _('&Rotate'), QDialogButtonBox.ButtonRole.ActionRole)
        self.fullscreen_button = fo = bb.addButton(
            _('&Full screen'), QDialogButtonBox.ButtonRole.ActionRole)
        zi.setIcon(QIcon(I('plus.png')))
        zo.setIcon(QIcon(I('minus.png')))
        so.setIcon(QIcon(I('save.png')))
        ro.setIcon(QIcon(I('rotate-right.png')))
        fo.setIcon(QIcon(I('page.png')))
        zi.clicked.connect(self.zoom_in)
        zo.clicked.connect(self.zoom_out)
        so.clicked.connect(self.save_image)
        ro.clicked.connect(self.rotate_image)
        fo.setCheckable(True)

        self.l = l = QVBoxLayout(self)
        l.addWidget(sa)
        self.h = h = QHBoxLayout()
        h.setContentsMargins(0, 0, 0, 0)
        l.addLayout(h)
        self.fit_image = i = QCheckBox(_('&Fit image'))
        i.setToolTip(_('Fit image inside the available space'))
        i.setChecked(bool(gprefs.get('image_popup_fit_image')))
        i.stateChanged.connect(self.fit_changed)
        h.addWidget(i), h.addStretch(), h.addWidget(bb)
        if self.fit_image.isChecked():
            self.set_to_viewport_size()
        geom = gprefs.get(self.geom_name)
        if geom is not None:
            self.restoreGeometry(geom)
        fo.setChecked(self.isFullScreen())
        fo.toggled.connect(self.toggle_fullscreen)
Exemplo n.º 40
0
    def __init__(self, db, book_id_map, parent=None):
        from calibre.ebooks.oeb.polish.main import HELP
        QDialog.__init__(self, parent)
        self.db, self.book_id_map = weakref.ref(db), book_id_map
        self.setWindowIcon(QIcon(I('polish.png')))
        title = _('Polish book')
        if len(book_id_map) > 1:
            title = _('Polish %d books') % len(book_id_map)
        self.setWindowTitle(title)

        self.help_text = {
            'polish':
            _('<h3>About Polishing books</h3>%s') % HELP['about'].format(
                _('''<p>If you have both EPUB and ORIGINAL_EPUB in your book,
                  then polishing will run on ORIGINAL_EPUB (the same for other
                  ORIGINAL_* formats).  So if you
                  want Polishing to not run on the ORIGINAL_* format, delete the
                  ORIGINAL_* format before running it.</p>''')),
            'embed':
            _('<h3>Embed referenced fonts</h3>%s') % HELP['embed'],
            'subset':
            _('<h3>Subsetting fonts</h3>%s') % HELP['subset'],
            'smarten_punctuation':
            _('<h3>Smarten punctuation</h3>%s') % HELP['smarten_punctuation'],
            'metadata':
            _('<h3>Updating metadata</h3>'
              '<p>This will update all metadata <i>except</i> the cover in the'
              ' e-book files to match the current metadata in the'
              ' calibre library.</p>'
              ' <p>Note that most e-book'
              ' formats are not capable of supporting all the'
              ' metadata in calibre.</p><p>There is a separate option to'
              ' update the cover.</p>'),
            'do_cover':
            _('<h3>Update cover</h3><p>Update the covers in the e-book files to match the'
              ' current cover in the calibre library.</p>'
              '<p>If the e-book file does not have'
              ' an identifiable cover, a new cover is inserted.</p>'),
            'jacket':
            _('<h3>Book jacket</h3>%s') % HELP['jacket'],
            'remove_jacket':
            _('<h3>Remove book jacket</h3>%s') % HELP['remove_jacket'],
            'remove_unused_css':
            _('<h3>Remove unused CSS rules</h3>%s') %
            HELP['remove_unused_css'],
            'compress_images':
            _('<h3>Losslessly compress images</h3>%s') %
            HELP['compress_images'],
            'add_soft_hyphens':
            _('<h3>Add soft-hyphens</h3>%s') % HELP['add_soft_hyphens'],
            'remove_soft_hyphens':
            _('<h3>Remove soft-hyphens</h3>%s') % HELP['remove_soft_hyphens'],
            'upgrade_book':
            _('<h3>Upgrade book internals</h3>%s') % HELP['upgrade_book'],
        }

        self.l = l = QGridLayout()
        self.setLayout(l)

        self.la = la = QLabel('<b>' + _('Select actions to perform:'))
        l.addWidget(la, 0, 0, 1, 2)

        count = 0
        self.all_actions = OrderedDict([
            ('embed', _('&Embed all referenced fonts')),
            ('subset', _('&Subset all embedded fonts')),
            ('smarten_punctuation', _('Smarten &punctuation')),
            ('metadata', _('Update &metadata in the book files')),
            ('do_cover', _('Update the &cover in the book files')),
            ('jacket', _('Add/replace metadata as a "book &jacket" page')),
            ('remove_jacket', _('&Remove a previously inserted book jacket')),
            ('remove_unused_css', _('Remove &unused CSS rules from the book')),
            ('compress_images', _('Losslessly &compress images')),
            ('add_soft_hyphens', _('Add s&oft hyphens')),
            ('remove_soft_hyphens', _('Remove soft hyphens')),
            ('upgrade_book', _('&Upgrade book internals')),
        ])
        prefs = gprefs.get('polishing_settings', {})
        for name, text in iteritems(self.all_actions):
            count += 1
            x = QCheckBox(text, self)
            x.setChecked(prefs.get(name, False))
            x.setObjectName(name)
            connect_lambda(
                x.stateChanged, self, lambda self, state: self.option_toggled(
                    self.sender().objectName(), state))
            l.addWidget(x, count, 0, 1, 1)
            setattr(self, 'opt_' + name, x)
            la = QLabel(' <a href="#%s">%s</a>' % (name, _('About')))
            setattr(self, 'label_' + name, x)
            la.linkActivated.connect(self.help_link_activated)
            l.addWidget(la, count, 1, 1, 1)

        count += 1
        l.addItem(QSpacerItem(10, 10, vPolicy=QSizePolicy.Expanding), count, 1,
                  1, 2)

        la = self.help_label = QLabel('')
        self.help_link_activated('#polish')
        la.setWordWrap(True)
        la.setTextFormat(Qt.RichText)
        la.setFrameShape(QFrame.StyledPanel)
        la.setAlignment(Qt.AlignLeft | Qt.AlignTop)
        la.setLineWidth(2)
        la.setStyleSheet('QLabel { margin-left: 75px }')
        l.addWidget(la, 0, 2, count + 1, 1)
        l.setColumnStretch(2, 1)

        self.show_reports = sr = QCheckBox(_('Show &report'), self)
        sr.setChecked(gprefs.get('polish_show_reports', True))
        sr.setToolTip(
            textwrap.fill(
                _('Show a report of all the actions performed'
                  ' after polishing is completed')))
        l.addWidget(sr, count + 1, 0, 1, 1)
        self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok
                                        | QDialogButtonBox.Cancel)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        self.save_button = sb = bb.addButton(_('&Save settings'),
                                             bb.ActionRole)
        sb.clicked.connect(self.save_settings)
        self.load_button = lb = bb.addButton(_('&Load settings'),
                                             bb.ActionRole)
        self.load_menu = QMenu(lb)
        lb.setMenu(self.load_menu)
        self.all_button = b = bb.addButton(_('Select &all'), bb.ActionRole)
        connect_lambda(b.clicked, self, lambda self: self.select_all(True))
        self.none_button = b = bb.addButton(_('Select &none'), bb.ActionRole)
        connect_lambda(b.clicked, self, lambda self: self.select_all(False))
        l.addWidget(bb, count + 1, 1, 1, -1)
        self.setup_load_button()

        self.resize(QSize(950, 600))
    def initialize(self, name, db):
        '''

        CheckBoxControls (c_type: check_box):
            ['generate_titles','generate_series','generate_genres',
                            'generate_recently_added','generate_descriptions','include_hr']
        ComboBoxControls (c_type: combo_box):
            ['read_source_field','exclude_source_field','header_note_source_field',
                            'merge_source_field']
        LineEditControls (c_type: line_edit):
            ['exclude_genre','exclude_pattern','exclude_tags','read_pattern',
                            'wishlist_tag']
        RadioButtonControls (c_type: radio_button):
            ['merge_before','merge_after']
        SpinBoxControls (c_type: spin_box):
            ['thumb_width']

        '''

        self.name = name
        self.db = db
        self.populateComboBoxes()

        # Update dialog fields from stored options
        for opt in self.OPTION_FIELDS:
            c_name, c_def, c_type = opt
            opt_value = gprefs.get(self.name + '_' + c_name, c_def)
            if c_type in ['check_box']:
                getattr(self, c_name).setChecked(eval(str(opt_value)))
            elif c_type in ['combo_box'] and opt_value is not None:
                # *** Test this code with combo boxes ***
                #index = self.read_source_field.findText(opt_value)
                index = getattr(self, c_name).findText(opt_value)
                if index == -1 and c_name == 'read_source_field':
                    index = self.read_source_field.findText('Tag')
                #self.read_source_field.setCurrentIndex(index)
                getattr(self, c_name).setCurrentIndex(index)
            elif c_type in ['line_edit']:
                getattr(self, c_name).setText(opt_value if opt_value else '')
            elif c_type in ['radio_button'] and opt_value is not None:
                getattr(self, c_name).setChecked(opt_value)
            elif c_type in ['spin_box']:
                getattr(self, c_name).setValue(float(opt_value))

        # Init self.read_source_field_name
        cs = unicode(self.read_source_field.currentText())
        read_source_spec = self.read_source_fields[cs]
        self.read_source_field_name = read_source_spec['field']

        # Init self.exclude_source_field_name
        self.exclude_source_field_name = ''
        cs = unicode(self.exclude_source_field.currentText())
        if cs > '':
            exclude_source_spec = self.exclude_source_fields[cs]
            self.exclude_source_field_name = exclude_source_spec['field']

        # Init self.merge_source_field_name
        self.merge_source_field_name = ''
        cs = unicode(self.merge_source_field.currentText())
        if cs > '':
            merge_source_spec = self.merge_source_fields[cs]
            self.merge_source_field_name = merge_source_spec['field']

        # Init self.header_note_source_field_name
        self.header_note_source_field_name = ''
        cs = unicode(self.header_note_source_field.currentText())
        if cs > '':
            header_note_source_spec = self.header_note_source_fields[cs]
            self.header_note_source_field_name = header_note_source_spec[
                'field']

        # Hook changes to thumb_width
        self.thumb_width.valueChanged.connect(self.thumb_width_changed)

        # Hook changes to Description section
        self.generate_descriptions.stateChanged.connect(
            self.generate_descriptions_changed)
Exemplo n.º 42
0
 def load_custom_pref(self, name, default=None):
     return gprefs.get(self.unique_pref_name + ':' + name, default)
Exemplo n.º 43
0
    def __init__(self, parent, view, row, link_delegate):
        QDialog.__init__(self, parent)
        self.normal_brush = QBrush(Qt.white)
        self.marked_brush = QBrush(Qt.lightGray)
        self.marked = None
        self.gui = parent
        self.splitter = QSplitter(self)
        self._l = l = QVBoxLayout(self)
        self.setLayout(l)
        l.addWidget(self.splitter)

        self.cover = Cover(self, show_size=gprefs['bd_overlay_cover_size'])
        self.cover.resizeEvent = self.cover_view_resized
        self.cover.cover_changed.connect(self.cover_changed)
        self.cover.open_with_requested.connect(self.open_with)
        self.cover.choose_open_with_requested.connect(self.choose_open_with)
        self.cover_pixmap = None
        self.cover.sizeHint = self.details_size_hint
        self.splitter.addWidget(self.cover)

        self.details = Details(parent.book_details.book_info, self)
        self.details.anchor_clicked.connect(self.on_link_clicked)
        self.link_delegate = link_delegate
        self.details.setAttribute(Qt.WA_OpaquePaintEvent, False)
        palette = self.details.palette()
        self.details.setAcceptDrops(False)
        palette.setBrush(QPalette.Base, Qt.transparent)
        self.details.setPalette(palette)

        self.c = QWidget(self)
        self.c.l = l2 = QGridLayout(self.c)
        l2.setContentsMargins(0, 0, 0, 0)
        self.c.setLayout(l2)
        l2.addWidget(self.details, 0, 0, 1, -1)
        self.splitter.addWidget(self.c)

        self.fit_cover = QCheckBox(_('Fit &cover within view'), self)
        self.fit_cover.setChecked(
            gprefs.get('book_info_dialog_fit_cover', True))
        self.hl = hl = QHBoxLayout()
        hl.setContentsMargins(0, 0, 0, 0)
        l2.addLayout(hl, l2.rowCount(), 0, 1, -1)
        hl.addWidget(self.fit_cover), hl.addStretch()
        self.clabel = QLabel(
            '<div style="text-align: right"><a href="calibre:conf" title="{}" style="text-decoration: none">{}</a>'
            .format(_('Configure this view'), _('Configure')))
        self.clabel.linkActivated.connect(self.configure)
        hl.addWidget(self.clabel)
        self.previous_button = QPushButton(QIcon(I('previous.png')),
                                           _('&Previous'), self)
        self.previous_button.clicked.connect(self.previous)
        l2.addWidget(self.previous_button, l2.rowCount(), 0)
        self.next_button = QPushButton(QIcon(I('next.png')), _('&Next'), self)
        self.next_button.clicked.connect(self.next)
        l2.addWidget(self.next_button, l2.rowCount() - 1, 1)

        self.view = view
        self.path_to_book = None
        self.current_row = None
        self.refresh(row)
        self.view.model().new_bookdisplay_data.connect(self.slave)
        self.fit_cover.stateChanged.connect(self.toggle_cover_fit)
        self.ns = QShortcut(QKeySequence('Alt+Right'), self)
        self.ns.activated.connect(self.next)
        self.ps = QShortcut(QKeySequence('Alt+Left'), self)
        self.ps.activated.connect(self.previous)
        self.next_button.setToolTip(
            _('Next [%s]') %
            unicode_type(self.ns.key().toString(QKeySequence.NativeText)))
        self.previous_button.setToolTip(
            _('Previous [%s]') %
            unicode_type(self.ps.key().toString(QKeySequence.NativeText)))

        geom = QCoreApplication.instance().desktop().availableGeometry(self)
        screen_height = geom.height() - 100
        screen_width = geom.width() - 100
        self.resize(max(int(screen_width / 2), 700), screen_height)
        saved_layout = gprefs.get('book_info_dialog_layout', None)
        if saved_layout is not None:
            try:
                QApplication.instance().safe_restore_geometry(
                    self, saved_layout[0])
                self.splitter.restoreState(saved_layout[1])
            except Exception:
                pass
Exemplo n.º 44
0
    def __init__(self, parent):
        QWidget.__init__(self, parent)
        self.setLayout(QVBoxLayout())

        self.la = la = QLabel(
            '<b>' + _('Select a destination for the Table of Contents entry'))
        self.layout().addWidget(la)
        self.splitter = sp = QSplitter(self)
        self.layout().addWidget(sp)
        self.layout().setStretch(1, 10)
        sp.setOpaqueResize(False)
        sp.setChildrenCollapsible(False)

        self.dest_list = dl = QListWidget(self)
        dl.setMinimumWidth(250)
        dl.currentItemChanged.connect(self.current_changed)
        sp.addWidget(dl)

        w = self.w = QWidget(self)
        l = w.l = QGridLayout()
        w.setLayout(l)
        self.view = WebView(self)
        self.view.elem_clicked.connect(self.elem_clicked)
        l.addWidget(self.view, 0, 0, 1, 3)
        sp.addWidget(w)

        self.search_text = s = QLineEdit(self)
        s.setPlaceholderText(_('Search for text...'))
        l.addWidget(s, 1, 0)
        self.ns_button = b = QPushButton(QIcon(I('arrow-down.png')),
                                         _('Find &next'), self)
        b.clicked.connect(self.find_next)
        l.addWidget(b, 1, 1)
        self.ps_button = b = QPushButton(QIcon(I('arrow-up.png')),
                                         _('Find &previous'), self)
        l.addWidget(b, 1, 2)
        b.clicked.connect(self.find_previous)

        self.f = f = QFrame()
        f.setFrameShape(f.StyledPanel)
        f.setMinimumWidth(250)
        l = f.l = QVBoxLayout()
        f.setLayout(l)
        sp.addWidget(f)

        f.la = la = QLabel('<p>' + _(
            'Here you can choose a destination for the Table of Contents\' entry'
            ' to point to. First choose a file from the book in the left-most panel. The'
            ' file will open in the central panel.<p>'
            'Then choose a location inside the file. To do so, simply click on'
            ' the place in the central panel that you want to use as the'
            ' destination. As you move the mouse around the central panel, a'
            ' thick green line appears, indicating the precise location'
            ' that will be selected when you click.'))
        la.setStyleSheet('QLabel { margin-bottom: 20px }')
        la.setWordWrap(True)
        l.addWidget(la)

        f.la2 = la = QLabel('<b>' + _('&Name of the ToC entry:'))
        l.addWidget(la)
        self.name = QLineEdit(self)
        la.setBuddy(self.name)
        l.addWidget(self.name)

        self.base_msg = '<b>' + _('Currently selected destination:') + '</b>'
        self.dest_label = la = QLabel(self.base_msg)
        la.setWordWrap(True)
        la.setStyleSheet('QLabel { margin-top: 20px }')
        l.addWidget(la)

        l.addStretch()

        state = gprefs.get('toc_edit_splitter_state', None)
        if state is not None:
            sp.restoreState(state)
Exemplo n.º 45
0
    def __init__(self,
                 parent,
                 text,
                 mi=None,
                 fm=None,
                 color_field=None,
                 icon_field_key=None,
                 icon_rule_kind=None,
                 doing_emblem=False,
                 text_is_placeholder=False,
                 dialog_is_st_editor=False,
                 global_vars=None,
                 all_functions=None,
                 builtin_functions=None):
        QDialog.__init__(self, parent)
        Ui_TemplateDialog.__init__(self)
        self.setupUi(self)

        self.coloring = color_field is not None
        self.iconing = icon_field_key is not None
        self.embleming = doing_emblem
        self.dialog_is_st_editor = dialog_is_st_editor
        if global_vars is None:
            self.global_vars = {}
        else:
            self.global_vars = global_vars

        cols = []
        if fm is not None:
            for key in sorted(
                    displayable_columns(fm),
                    key=lambda k: sort_key(fm[k]['name']
                                           if k != color_row_key else 0)):
                if key == color_row_key and not self.coloring:
                    continue
                from calibre.gui2.preferences.coloring import all_columns_string
                name = all_columns_string if key == color_row_key else fm[key][
                    'name']
                if name:
                    cols.append((name, key))

        self.color_layout.setVisible(False)
        self.icon_layout.setVisible(False)

        if self.coloring:
            self.color_layout.setVisible(True)
            for n1, k1 in cols:
                self.colored_field.addItem(
                    n1 + (' (' + k1 + ')' if k1 != color_row_key else ''), k1)
            self.colored_field.setCurrentIndex(
                self.colored_field.findData(color_field))
        elif self.iconing or self.embleming:
            self.icon_layout.setVisible(True)
            if self.embleming:
                self.icon_kind_label.setVisible(False)
                self.icon_kind.setVisible(False)
                self.icon_chooser_label.setVisible(False)
                self.icon_field.setVisible(False)

            for n1, k1 in cols:
                self.icon_field.addItem('{} ({})'.format(n1, k1), k1)
            self.icon_file_names = []
            d = os.path.join(config_dir, 'cc_icons')
            if os.path.exists(d):
                for icon_file in os.listdir(d):
                    icon_file = icu_lower(icon_file)
                    if os.path.exists(os.path.join(d, icon_file)):
                        if icon_file.endswith('.png'):
                            self.icon_file_names.append(icon_file)
            self.icon_file_names.sort(key=sort_key)
            self.update_filename_box()

            if self.iconing:
                dex = 0
                from calibre.gui2.preferences.coloring import icon_rule_kinds
                for i, tup in enumerate(icon_rule_kinds):
                    txt, val = tup
                    self.icon_kind.addItem(txt, userData=(val))
                    if val == icon_rule_kind:
                        dex = i
                self.icon_kind.setCurrentIndex(dex)
                self.icon_field.setCurrentIndex(
                    self.icon_field.findData(icon_field_key))

        if dialog_is_st_editor:
            self.buttonBox.setVisible(False)
        else:
            self.new_doc_label.setVisible(False)
            self.new_doc.setVisible(False)
            self.template_name_label.setVisible(False)
            self.template_name.setVisible(False)

        if mi:
            if not isinstance(mi, list):
                mi = (mi, )
        else:
            mi = Metadata(_('Title'), [_('Author')])
            mi.author_sort = _('Author Sort')
            mi.series = ngettext('Series', 'Series', 1)
            mi.series_index = 3
            mi.rating = 4.0
            mi.tags = [_('Tag 1'), _('Tag 2')]
            mi.languages = ['eng']
            mi.id = 1
            if fm is not None:
                mi.set_all_user_metadata(fm.custom_field_metadata())
            else:
                # No field metadata. Grab a copy from the current library so
                # that we can validate any custom column names. The values for
                # the columns will all be empty, which in some very unusual
                # cases might cause formatter errors. We can live with that.
                from calibre.gui2.ui import get_gui
                mi.set_all_user_metadata(get_gui(
                ).current_db.new_api.field_metadata.custom_field_metadata())
            for col in mi.get_all_user_metadata(False):
                mi.set(col, (col, ), 0)
            mi = (mi, )
        self.mi = mi

        # Set up the display table
        self.table_column_widths = None
        try:
            self.table_column_widths = \
                        gprefs.get('template_editor_table_widths', None)
        except:
            pass
        tv = self.template_value
        tv.setRowCount(len(mi))
        tv.setColumnCount(2)
        tv.setHorizontalHeaderLabels((_('Book title'), _('Template value')))
        tv.horizontalHeader().setStretchLastSection(True)
        tv.horizontalHeader().sectionResized.connect(self.table_column_resized)
        # Set the height of the table
        h = tv.rowHeight(0) * min(len(mi), 5)
        h += 2 * tv.frameWidth() + tv.horizontalHeader().height()
        tv.setMinimumHeight(h)
        tv.setMaximumHeight(h)
        # Set the size of the title column
        if self.table_column_widths:
            tv.setColumnWidth(0, self.table_column_widths[0])
        else:
            tv.setColumnWidth(0, tv.fontMetrics().averageCharWidth() * 10)
        # Use our own widget to get rid of elision. setTextElideMode() doesn't work
        for r in range(0, len(mi)):
            w = QLineEdit(tv)
            w.setReadOnly(True)
            tv.setCellWidget(r, 0, w)
            w = QLineEdit(tv)
            w.setReadOnly(True)
            tv.setCellWidget(r, 1, w)
        tv.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)

        # Remove help icon on title bar
        icon = self.windowIcon()
        self.setWindowFlags(self.windowFlags()
                            & (~Qt.WindowType.WindowContextHelpButtonHint))
        self.setWindowIcon(icon)

        self.all_functions = all_functions if all_functions else formatter_functions(
        ).get_functions()
        self.builtins = (builtin_functions if builtin_functions else
                         formatter_functions().get_builtins_and_aliases())

        self.last_text = ''
        self.highlighter = TemplateHighlighter(self.textbox.document(),
                                               builtin_functions=self.builtins)
        self.textbox.cursorPositionChanged.connect(self.text_cursor_changed)
        self.textbox.textChanged.connect(self.textbox_changed)
        self.textbox.setFont(self.get_current_font())

        self.textbox.setTabStopWidth(10)
        self.source_code.setTabStopWidth(10)
        self.documentation.setReadOnly(True)
        self.source_code.setReadOnly(True)

        if text is not None:
            if text_is_placeholder:
                self.textbox.setPlaceholderText(text)
                self.textbox.clear()
                text = ''
            else:
                self.textbox.setPlainText(text)
        else:
            text = ''
        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setText(
            _('&OK'))
        self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setText(
            _('&Cancel'))

        self.color_copy_button.clicked.connect(self.color_to_clipboard)
        self.filename_button.clicked.connect(self.filename_button_clicked)
        self.icon_copy_button.clicked.connect(self.icon_to_clipboard)

        try:
            with open(P('template-functions.json'), 'rb') as f:
                self.builtin_source_dict = json.load(f, encoding='utf-8')
        except:
            self.builtin_source_dict = {}

        func_names = sorted(self.all_functions)
        self.function.clear()
        self.function.addItem('')
        for f in func_names:
            self.function.addItem(
                '{}  --  {}'.format(
                    f, self.function_type_string(f, longform=False)), f)
        self.function.setCurrentIndex(0)
        self.function.currentIndexChanged.connect(self.function_changed)
        self.display_values(text)
        self.rule = (None, '')

        tt = _('Template language tutorial')
        self.template_tutorial.setText(
            '<a href="%s">%s</a>' % (localize_user_manual_link(
                'https://manual.calibre-ebook.com/template_lang.html'), tt))
        tt = _('Template function reference')
        self.template_func_reference.setText(
            '<a href="%s">%s</a>' % (localize_user_manual_link(
                'https://manual.calibre-ebook.com/generated/en/template_ref.html'
            ), tt))

        s = gprefs.get('template_editor_break_on_print', False)
        self.go_button.setEnabled(s)
        self.remove_all_button.setEnabled(s)
        self.set_all_button.setEnabled(s)
        self.toggle_button.setEnabled(s)
        self.breakpoint_line_box.setEnabled(s)
        self.breakpoint_line_box_label.setEnabled(s)
        self.break_box.setChecked(s)
        self.break_box.stateChanged.connect(self.break_box_changed)
        self.go_button.clicked.connect(self.go_button_pressed)
        self.textbox.setFocus()
        self.set_up_font_boxes()
        self.toggle_button.clicked.connect(self.toggle_button_pressed)
        self.remove_all_button.clicked.connect(self.remove_all_button_pressed)
        self.set_all_button.clicked.connect(self.set_all_button_pressed)

        self.load_button.clicked.connect(self.load_template)
        self.save_button.clicked.connect(self.save_template)
        # Now geometry
        try:
            geom = gprefs.get('template_editor_dialog_geometry', None)
            if geom is not None:
                QApplication.instance().safe_restore_geometry(
                    self, QByteArray(geom))
        except Exception:
            pass
Exemplo n.º 46
0
 def restore_state(self):
     if self.count() > 1:
         state = gprefs.get(self.save_name + '_state', self.default_state())
         self.apply_state(state, save_desired=False)
         self.desired_side_size = state[1]
Exemplo n.º 47
0
    def __init__(self, parent, mi, op_label, op_value, locals_, line_number):
        super().__init__(parent)
        self.mi = mi
        self.setModal(True)
        l = QVBoxLayout(self)
        t = self.table = QTableWidget(self)
        t.setColumnCount(2)
        t.setHorizontalHeaderLabels((_('Name'), _('Value')))
        t.setRowCount(2)
        l.addWidget(t)

        self.table_column_widths = None
        try:
            self.table_column_widths = \
                        gprefs.get('template_editor_break_table_widths', None)
            t.setColumnWidth(0, self.table_column_widths[0])
        except:
            t.setColumnWidth(0, t.fontMetrics().averageCharWidth() * 20)
        t.horizontalHeader().sectionResized.connect(self.table_column_resized)
        t.horizontalHeader().setStretchLastSection(True)

        bb = QDialogButtonBox()
        b = bb.addButton(_('&Continue'),
                         QDialogButtonBox.ButtonRole.AcceptRole)
        b.setIcon(QIcon(I('sync-right.png')))
        b.setToolTip(_('Continue running the template'))
        b.setDefault(True)
        l.addWidget(bb)
        b = bb.addButton(_('&Stop'), QDialogButtonBox.ButtonRole.RejectRole)
        b.setIcon(QIcon(I('list_remove.png')))
        b.setToolTip(_('Stop running the template'))
        l.addWidget(bb)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        self.setLayout(l)

        self.setWindowTitle(
            _('Break: line {0}, book {1}').format(line_number, self.mi.title))

        local_names = sorted(locals_.keys())
        rows = len(local_names)
        self.table.setRowCount(rows + 2)
        self.table.setItem(0, 0, BreakReporterItem(op_label))
        self.table.item(0, 0).setToolTip(
            _('The name of the template language operation'))
        self.table.setItem(0, 1, BreakReporterItem(op_value))

        self.mi_combo = QComboBox()
        t.setCellWidget(1, 0, self.mi_combo)
        self.mi_combo.addItems(self.get_field_keys())
        self.mi_combo.setToolTip('Choose a book metadata field to display')
        self.mi_combo.setCurrentIndex(-1)
        self.mi_combo.currentTextChanged.connect(self.get_field_value)
        for i, k in enumerate(local_names):
            itm = BreakReporterItem(k)
            itm.setToolTip(_('A variable in the template'))
            self.table.setItem(i + 2, 0, itm)
            itm = BreakReporterItem(locals_[k])
            itm.setToolTip(_('The value of the variable'))
            self.table.setItem(i + 2, 1, itm)

        try:
            geom = gprefs.get('template_editor_break_geometry', None)
            if geom is not None:
                QApplication.instance().safe_restore_geometry(
                    self, QByteArray(geom))
        except Exception:
            pass
Exemplo n.º 48
0
    def add_empty(self, *args):
        '''
        Add an empty book item to the library. This does not import any formats
        from a book file.
        '''
        author = series = title = None
        index = self.gui.library_view.currentIndex()
        if index.isValid():
            raw = index.model().db.authors(index.row())
            if raw:
                authors = [a.strip().replace('|', ',') for a in raw.split(',')]
                if authors:
                    author = authors[0]
            series = index.model().db.series(index.row())
            title = index.model().db.title(index.row())
        dlg = AddEmptyBookDialog(self.gui,
                                 self.gui.library_view.model().db,
                                 author,
                                 series,
                                 dup_title=title)
        if dlg.exec_() == dlg.Accepted:
            temp_files = []
            num = dlg.qty_to_add
            series = dlg.selected_series
            title = dlg.selected_title or _('Unknown')
            db = self.gui.library_view.model().db
            ids, orig_fmts = [], []
            if dlg.duplicate_current_book:
                origmi = db.get_metadata(index.row(),
                                         get_cover=True,
                                         cover_as_data=True)
                if dlg.copy_formats.isChecked():
                    book_id = db.id(index.row())
                    orig_fmts = tuple(
                        db.new_api.format(book_id, fmt, as_path=True)
                        for fmt in db.new_api.formats(book_id))

            for x in xrange(num):
                if dlg.duplicate_current_book:
                    mi = origmi
                else:
                    mi = MetaInformation(title, dlg.selected_authors)
                    if series:
                        mi.series = series
                        mi.series_index = db.get_next_series_num_for(series)
                fmts = []
                empty_format = gprefs.get('create_empty_format_file', '')
                if dlg.duplicate_current_book and dlg.copy_formats.isChecked():
                    fmts = orig_fmts
                elif empty_format:
                    from calibre.ebooks.oeb.polish.create import create_book
                    pt = PersistentTemporaryFile(suffix='.' + empty_format)
                    pt.close()
                    temp_files.append(pt.name)
                    create_book(mi, pt.name, fmt=empty_format)
                    fmts = [pt.name]
                ids.append(db.import_book(mi, fmts))
            tuple(map(os.remove, orig_fmts))
            self.gui.library_view.model().books_added(num)
            self.gui.refresh_cover_browser()
            self.gui.tags_view.recount()
            if ids:
                ids.reverse()
                self.gui.library_view.select_rows(ids)
            for path in temp_files:
                os.remove(path)
Exemplo n.º 49
0
    def do_add(self, data):
        from calibre.ebooks.metadata.opf2 import OPF

        gui = self.parent()
        if gui is None:
            return
        m = gui.library_view.model()
        count = 0

        needs_rescan = False
        duplicates = []
        added_ids = set()

        for fname, tdir in data:
            paths = [os.path.join(self.worker.path, fname)]
            sz = os.path.join(tdir, 'size.txt')
            try:
                with open(sz, 'rb') as f:
                    sz = int(f.read())
                if sz != os.stat(paths[0]).st_size:
                    raise Exception('Looks like the file was written to after'
                            ' we tried to read metadata')
            except:
                needs_rescan = True
                try:
                    self.worker.staging.remove(fname)
                except KeyError:
                    pass

                continue

            mi = os.path.join(tdir, 'metadata.opf')
            if not os.access(mi, os.R_OK):
                continue
            mi = OPF(open(mi, 'rb'), tdir, populate_spine=False).to_book_metadata()
            if gprefs.get('tag_map_on_add_rules'):
                from calibre.ebooks.metadata.tag_mapper import map_tags
                mi.tags = map_tags(mi.tags, gprefs['tag_map_on_add_rules'])
            if gprefs.get('author_map_on_add_rules'):
                from calibre.ebooks.metadata.author_mapper import map_authors, compile_rules
                new_authors = map_authors(mi.authors, compile_rules(gprefs['author_map_on_add_rules']))
                if new_authors != mi.authors:
                    mi.authors = new_authors
                    mi.author_sort = gui.current_db.new_api.author_sort_from_authors(mi.authors)
            mi = [mi]
            dups, ids = m.add_books(paths,
                    [os.path.splitext(fname)[1][1:].upper()], mi,
                    add_duplicates=not gprefs['auto_add_check_for_duplicates'],
                    return_ids=True)
            added_ids |= set(ids)
            num = len(ids)
            if dups:
                path = dups[0][0]
                with open(os.path.join(tdir, 'dup_cache.'+dups[1][0].lower()),
                        'wb') as dest, open(path, 'rb') as src:
                    shutil.copyfileobj(src, dest)
                    dups[0][0] = dest.name
                duplicates.append(dups)

            try:
                os.remove(paths[0])
                self.worker.staging.remove(fname)
            except:
                import traceback
                traceback.print_exc()
            count += num

        if duplicates:
            paths, formats, metadata = [], [], []
            for p, f, mis in duplicates:
                paths.extend(p)
                formats.extend(f)
                metadata.extend(mis)
            dups = [(mic, mic.cover, [p]) for mic, p in zip(metadata, paths)]
            d = DuplicatesQuestion(m.db, dups, parent=gui)
            dups = tuple(d.duplicates)
            if dups:
                paths, formats, metadata = [], [], []
                for mi, cover, book_paths in dups:
                    paths.extend(book_paths)
                    formats.extend([p.rpartition('.')[-1] for p in book_paths])
                    metadata.extend([mi for i in book_paths])
                ids = m.add_books(paths, formats, metadata,
                        add_duplicates=True, return_ids=True)[1]
                added_ids |= set(ids)
                num = len(ids)
                count += num

        for fname, tdir in data:
            try:
                shutil.rmtree(tdir)
            except:
                pass

        if added_ids and gprefs['auto_add_auto_convert']:
            self.auto_convert.emit(added_ids)

        if count > 0:
            m.books_added(count)
            gui.status_bar.show_message(
                (_('Added a book automatically from {src}') if count == 1 else _('Added {num} books automatically from {src}')).format(
                    num=count, src=self.worker.path), 2000)
            gui.refresh_cover_browser()

        if needs_rescan:
            QTimer.singleShot(2000, self.dir_changed)
Exemplo n.º 50
0
    def __init__(self,
                 parent,
                 text,
                 mi=None,
                 fm=None,
                 color_field=None,
                 icon_field_key=None,
                 icon_rule_kind=None,
                 doing_emblem=False,
                 text_is_placeholder=False,
                 dialog_is_st_editor=False,
                 global_vars=None,
                 all_functions=None,
                 builtin_functions=None):
        QDialog.__init__(self, parent)
        Ui_TemplateDialog.__init__(self)
        self.setupUi(self)

        self.coloring = color_field is not None
        self.iconing = icon_field_key is not None
        self.embleming = doing_emblem
        self.dialog_is_st_editor = dialog_is_st_editor
        if global_vars is None:
            self.global_vars = {}
        else:
            self.global_vars = global_vars

        cols = []
        self.fm = fm
        if fm is not None:
            for key in sorted(
                    displayable_columns(fm),
                    key=lambda k: sort_key(fm[k]['name']
                                           if k != color_row_key else 0)):
                if key == color_row_key and not self.coloring:
                    continue
                from calibre.gui2.preferences.coloring import all_columns_string
                name = all_columns_string if key == color_row_key else fm[key][
                    'name']
                if name:
                    cols.append((name, key))

        self.color_layout.setVisible(False)
        self.icon_layout.setVisible(False)

        if self.coloring:
            self.color_layout.setVisible(True)
            for n1, k1 in cols:
                self.colored_field.addItem(
                    n1 + (' (' + k1 + ')' if k1 != color_row_key else ''), k1)
            self.colored_field.setCurrentIndex(
                self.colored_field.findData(color_field))
        elif self.iconing or self.embleming:
            self.icon_layout.setVisible(True)
            if self.embleming:
                self.icon_kind_label.setVisible(False)
                self.icon_kind.setVisible(False)
                self.icon_chooser_label.setVisible(False)
                self.icon_field.setVisible(False)

            for n1, k1 in cols:
                self.icon_field.addItem(f'{n1} ({k1})', k1)
            self.icon_file_names = []
            d = os.path.join(config_dir, 'cc_icons')
            if os.path.exists(d):
                for icon_file in os.listdir(d):
                    icon_file = icu_lower(icon_file)
                    if os.path.exists(os.path.join(d, icon_file)):
                        if icon_file.endswith('.png'):
                            self.icon_file_names.append(icon_file)
            self.icon_file_names.sort(key=sort_key)
            self.update_filename_box()

            if self.iconing:
                dex = 0
                from calibre.gui2.preferences.coloring import icon_rule_kinds
                for i, tup in enumerate(icon_rule_kinds):
                    txt, val = tup
                    self.icon_kind.addItem(txt, userData=(val))
                    if val == icon_rule_kind:
                        dex = i
                self.icon_kind.setCurrentIndex(dex)
                self.icon_field.setCurrentIndex(
                    self.icon_field.findData(icon_field_key))

        self.setup_saved_template_editor(not dialog_is_st_editor,
                                         dialog_is_st_editor)
        # Remove help icon on title bar
        icon = self.windowIcon()
        self.setWindowFlags(self.windowFlags()
                            & (~Qt.WindowType.WindowContextHelpButtonHint))
        self.setWindowIcon(icon)

        self.all_functions = all_functions if all_functions else formatter_functions(
        ).get_functions()
        self.builtins = (builtin_functions if builtin_functions else
                         formatter_functions().get_builtins_and_aliases())

        # Set up the display table
        self.table_column_widths = None
        try:
            self.table_column_widths = \
                        gprefs.get('template_editor_table_widths', None)
        except:
            pass
        self.set_mi(mi, fm)

        self.last_text = ''
        self.highlighter = TemplateHighlighter(self.textbox.document(),
                                               builtin_functions=self.builtins)
        self.textbox.cursorPositionChanged.connect(self.text_cursor_changed)
        self.textbox.textChanged.connect(self.textbox_changed)
        self.set_editor_font()

        self.documentation.setReadOnly(True)
        self.source_code.setReadOnly(True)

        if text is not None:
            if text_is_placeholder:
                self.textbox.setPlaceholderText(text)
                self.textbox.clear()
                text = ''
            else:
                self.textbox.setPlainText(text)
        else:
            text = ''
        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setText(
            _('&OK'))
        self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setText(
            _('&Cancel'))

        self.color_copy_button.clicked.connect(self.color_to_clipboard)
        self.filename_button.clicked.connect(self.filename_button_clicked)
        self.icon_copy_button.clicked.connect(self.icon_to_clipboard)

        try:
            with open(P('template-functions.json'), 'rb') as f:
                self.builtin_source_dict = json.load(f, encoding='utf-8')
        except:
            self.builtin_source_dict = {}

        func_names = sorted(self.all_functions)
        self.function.clear()
        self.function.addItem('')
        for f in func_names:
            self.function.addItem(
                '{}  --  {}'.format(
                    f, self.function_type_string(f, longform=False)), f)
        self.function.setCurrentIndex(0)
        self.function.currentIndexChanged.connect(self.function_changed)
        self.rule = (None, '')

        tt = _('Template language tutorial')
        self.template_tutorial.setText('<a href="{}">{}</a>'.format(
            localize_user_manual_link(
                'https://manual.calibre-ebook.com/template_lang.html'), tt))
        tt = _('Template function reference')
        self.template_func_reference.setText('<a href="{}">{}</a>'.format(
            localize_user_manual_link(
                'https://manual.calibre-ebook.com/generated/en/template_ref.html'
            ), tt))

        s = gprefs.get('template_editor_break_on_print', False)
        self.go_button.setEnabled(s)
        self.remove_all_button.setEnabled(s)
        self.set_all_button.setEnabled(s)
        self.toggle_button.setEnabled(s)
        self.breakpoint_line_box.setEnabled(s)
        self.breakpoint_line_box_label.setEnabled(s)
        self.break_box.setChecked(s)
        self.break_box.stateChanged.connect(self.break_box_changed)
        self.go_button.clicked.connect(self.go_button_pressed)
        self.textbox.setFocus()
        self.set_up_font_boxes()
        self.toggle_button.clicked.connect(self.toggle_button_pressed)
        self.remove_all_button.clicked.connect(self.remove_all_button_pressed)
        self.set_all_button.clicked.connect(self.set_all_button_pressed)

        self.load_button.clicked.connect(self.load_template_from_file)
        self.save_button.clicked.connect(self.save_template)

        self.set_word_wrap(
            gprefs.get('gpm_template_editor_word_wrap_mode', True))
        self.textbox.setContextMenuPolicy(
            Qt.ContextMenuPolicy.CustomContextMenu)
        self.textbox.customContextMenuRequested.connect(self.show_context_menu)
        # Now geometry
        try:
            geom = gprefs.get('template_editor_dialog_geometry', None)
            if geom is not None:
                QApplication.instance().safe_restore_geometry(
                    self, QByteArray(geom))
        except Exception:
            pass
Exemplo n.º 51
0
    def __init__(self, parent, db, id_to_select, select_sort, select_link):
        QDialog.__init__(self, parent)
        Ui_EditAuthorsDialog.__init__(self)
        self.setupUi(self)
        # Remove help icon on title bar
        icon = self.windowIcon()
        self.setWindowFlags(self.windowFlags()&(~Qt.WindowContextHelpButtonHint))
        self.setWindowIcon(icon)

        try:
            self.table_column_widths = \
                        gprefs.get('manage_authors_table_widths', None)
            geom = gprefs.get('manage_authors_dialog_geometry', bytearray(''))
            self.restoreGeometry(QByteArray(geom))
        except:
            pass

        self.buttonBox.button(QDialogButtonBox.Ok).setText(_('&OK'))
        self.buttonBox.button(QDialogButtonBox.Cancel).setText(_('&Cancel'))
        self.buttonBox.accepted.connect(self.accepted)

        # Set up the column headings
        self.table.setSelectionMode(QAbstractItemView.SingleSelection)
        self.table.setColumnCount(3)
        self.down_arrow_icon = QIcon(I('arrow-down.png'))
        self.up_arrow_icon = QIcon(I('arrow-up.png'))
        self.blank_icon = QIcon(I('blank.png'))
        self.auth_col = QTableWidgetItem(_('Author'))
        self.table.setHorizontalHeaderItem(0, self.auth_col)
        self.auth_col.setIcon(self.blank_icon)
        self.aus_col = QTableWidgetItem(_('Author sort'))
        self.table.setHorizontalHeaderItem(1, self.aus_col)
        self.aus_col.setIcon(self.up_arrow_icon)
        self.aul_col = QTableWidgetItem(_('Link'))
        self.table.setHorizontalHeaderItem(2, self.aul_col)
        self.aus_col.setIcon(self.blank_icon)

        # Add the data
        self.authors = {}
        auts = db.get_authors_with_ids()
        self.table.setRowCount(len(auts))
        select_item = None
        for row, (id, author, sort, link) in enumerate(auts):
            author = author.replace('|', ',')
            self.authors[id] = (author, sort, link)
            aut = tableItem(author)
            aut.setData(Qt.UserRole, id)
            sort = tableItem(sort)
            link = tableItem(link)
            self.table.setItem(row, 0, aut)
            self.table.setItem(row, 1, sort)
            self.table.setItem(row, 2, link)
            if id_to_select in (id, author):
                if select_sort:
                    select_item = sort
                elif select_link:
                    select_item = link
                else:
                    select_item = aut
        self.table.resizeColumnsToContents()
        if self.table.columnWidth(2) < 200:
            self.table.setColumnWidth(2, 200)

        # set up the cellChanged signal only after the table is filled
        self.table.cellChanged.connect(self.cell_changed)

        # set up sort buttons
        self.sort_by_author.setCheckable(True)
        self.sort_by_author.setChecked(False)
        self.sort_by_author.clicked.connect(self.do_sort_by_author)
        self.author_order = 1

        self.table.sortByColumn(1, Qt.AscendingOrder)
        self.sort_by_author_sort.clicked.connect(self.do_sort_by_author_sort)
        self.sort_by_author_sort.setCheckable(True)
        self.sort_by_author_sort.setChecked(True)
        self.author_sort_order = 1

        self.recalc_author_sort.clicked.connect(self.do_recalc_author_sort)
        self.auth_sort_to_author.clicked.connect(self.do_auth_sort_to_author)

        # Position on the desired item
        if select_item is not None:
            self.table.setCurrentItem(select_item)
            self.table.editItem(select_item)
            self.start_find_pos = select_item.row() * 2 + select_item.column()
        else:
            self.table.setCurrentCell(0, 0)
            self.start_find_pos = -1

        # set up the search box
        self.find_box.initialize('manage_authors_search')
        self.find_box.lineEdit().returnPressed.connect(self.do_find)
        self.find_box.editTextChanged.connect(self.find_text_changed)
        self.find_button.clicked.connect(self.do_find)
        self.find_button.setDefault(True)

        l = QLabel(self.table)
        self.not_found_label = l
        l.setFrameStyle(QFrame.StyledPanel)
        l.setAutoFillBackground(True)
        l.setText(_('No matches found'))
        l.setAlignment(Qt.AlignVCenter)
        l.resize(l.sizeHint())
        l.move(10,20)
        l.setVisible(False)
        self.not_found_label.move(40, 40)
        self.not_found_label_timer = QTimer()
        self.not_found_label_timer.setSingleShot(True)
        self.not_found_label_timer.timeout.connect(
                self.not_found_label_timer_event, type=Qt.QueuedConnection)

        self.table.setContextMenuPolicy(Qt.CustomContextMenu)
        self.table.customContextMenuRequested .connect(self.show_context_menu)
Exemplo n.º 52
0
 def restore_state(self):
     if gprefs.get('grid view visible', False):
         self.toggle()
Exemplo n.º 53
0
Arquivo: main.py Projeto: sss/calibre
    def __init__(self, gui, initial_plugin=None, close_after_initial=False):
        QMainWindow.__init__(self, gui)
        self.gui = gui
        self.must_restart = False
        self.committed = False
        self.close_after_initial = close_after_initial

        self.resize(930, 720)
        nh, nw = min_available_height()-25, available_width()-10
        if nh < 0:
            nh = 800
        if nw < 0:
            nw = 600
        nh = min(self.height(), nh)
        nw = min(self.width(), nw)
        self.resize(nw, nh)
        self.esc_action = QAction(self)
        self.addAction(self.esc_action)
        self.esc_action.setShortcut(QKeySequence(Qt.Key_Escape))
        self.esc_action.triggered.connect(self.esc)

        geom = gprefs.get('preferences_window_geometry', None)
        if geom is not None:
            self.restoreGeometry(geom)

        # Center
        if islinux:
            self.move(gui.rect().center() - self.rect().center())

        self.setWindowModality(Qt.WindowModal)
        self.setWindowTitle(__appname__ + ' - ' + _('Preferences'))
        self.setWindowIcon(QIcon(I('config.png')))

        self.status_bar = StatusBar(self)
        self.setStatusBar(self.status_bar)

        self.stack = QStackedWidget(self)
        self.cw = QWidget(self)
        self.cw.setLayout(QVBoxLayout())
        self.cw.layout().addWidget(self.stack)
        self.bb = QDialogButtonBox(QDialogButtonBox.Close)
        self.wizard_button = self.bb.addButton(_('Run welcome wizard'),
                self.bb.ActionRole)
        self.wizard_button.setIcon(QIcon(I('wizard.png')))
        self.wizard_button.clicked.connect(self.run_wizard,
                type=Qt.QueuedConnection)
        self.cw.layout().addWidget(self.bb)
        self.bb.button(self.bb.Close).setDefault(True)
        self.bb.rejected.connect(self.close, type=Qt.QueuedConnection)
        self.setCentralWidget(self.cw)
        self.browser = Browser(self)
        self.browser.show_plugin.connect(self.show_plugin)
        self.stack.addWidget(self.browser)
        self.scroll_area = QScrollArea(self)
        self.stack.addWidget(self.scroll_area)
        self.scroll_area.setWidgetResizable(True)

        self.setContextMenuPolicy(Qt.NoContextMenu)
        self.bar = QToolBar(self)
        self.addToolBar(self.bar)
        self.bar.setVisible(False)
        self.bar.setIconSize(QSize(ICON_SIZE, ICON_SIZE))
        self.bar.setMovable(False)
        self.bar.setFloatable(False)
        self.bar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        self.apply_action = self.bar.addAction(QIcon(I('ok.png')), _('&Apply'),
                self.commit)
        self.cancel_action = self.bar.addAction(QIcon(I('window-close.png')),
                _('&Cancel'),                self.cancel)
        self.bar_title = BarTitle(self.bar)
        self.bar.addWidget(self.bar_title)
        self.restore_action = self.bar.addAction(QIcon(I('clear_left.png')),
                _('Restore &defaults'), self.restore_defaults)
        for ac, tt in [('apply', _('Save changes')),
                ('cancel', _('Cancel and return to overview'))]:
            ac = getattr(self, ac+'_action')
            ac.setToolTip(tt)
            ac.setWhatsThis(tt)
            ac.setStatusTip(tt)

        for ch in self.bar.children():
            if isinstance(ch, QToolButton):
                ch.setCursor(Qt.PointingHandCursor)
                ch.setAutoRaise(True)

        self.stack.setCurrentIndex(0)

        if initial_plugin is not None:
            category, name = initial_plugin
            plugin = get_plugin(category, name)
            if plugin is not None:
                self.show_plugin(plugin)
Exemplo n.º 54
0
 def restore_state(self):
     self.setChecked(bool(gprefs.get('search bar visible', True)))
Exemplo n.º 55
0
    def __init__(self, gui, view, id_, row_index):
        QDialog.__init__(self, gui, flags=Qt.Window)
        Ui_MatchBooks.__init__(self)
        self.setupUi(self)
        self.isClosed = False

        self.books_table_column_widths = None
        try:
            self.books_table_column_widths = \
                        gprefs.get('match_books_dialog_books_table_widths', None)
            geom = gprefs.get('match_books_dialog_geometry', None)
            if geom:
                QApplication.instance().safe_restore_geometry(
                    self, QByteArray(geom))
        except:
            pass

        self.search_text.initialize('match_books_dialog')

        # Remove the help button from the window title bar
        icon = self.windowIcon()
        self.setWindowFlags(self.windowFlags()
                            & (~Qt.WindowContextHelpButtonHint))
        self.setWindowIcon(icon)

        self.device_db = view.model().db
        self.library_db = gui.library_view.model().db
        self.view = view
        self.gui = gui
        self.current_device_book_id = id_
        self.current_device_book_index = row_index
        self.current_library_book_id = None

        # Set up the books table columns
        self.books_table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.books_table.setSelectionMode(QAbstractItemView.SingleSelection)
        self.books_table.setColumnCount(3)
        t = QTableWidgetItem(_('Title'))
        self.books_table.setHorizontalHeaderItem(0, t)
        t = QTableWidgetItem(_('Authors'))
        self.books_table.setHorizontalHeaderItem(1, t)
        t = QTableWidgetItem(ngettext("Series", 'Series', 1))
        self.books_table.setHorizontalHeaderItem(2, t)
        self.books_table_header_height = self.books_table.height()
        self.books_table.cellDoubleClicked.connect(self.book_doubleclicked)
        self.books_table.cellClicked.connect(self.book_clicked)
        self.books_table.sortByColumn(0, Qt.AscendingOrder)

        # get the standard table row height. Do this here because calling
        # resizeRowsToContents can word wrap long cell contents, creating
        # double-high rows
        self.books_table.setRowCount(1)
        self.books_table.setItem(0, 0, TableItem('A', ''))
        self.books_table.resizeRowsToContents()
        self.books_table_row_height = self.books_table.rowHeight(0)
        self.books_table.setRowCount(0)

        self.search_button.clicked.connect(self.do_search)
        self.search_button.setDefault(False)
        self.search_text.lineEdit().returnPressed.connect(self.return_pressed)

        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        self.ignore_next_key = False

        search_text = self.device_db[self.current_device_book_id].title
        search_text = search_text.replace('(', '\\(').replace(')', '\\)')
        self.search_text.setText(search_text)
Exemplo n.º 56
0
 def set_sizes(self):
     sizes = gprefs.get('quickview_dialog_heights', [])
     if len(sizes) == 2:
         self.setSizes(sizes)
Exemplo n.º 57
0
    def __init__(self, parent, view, row, link_delegate):
        QDialog.__init__(self, parent)
        self.normal_brush = QBrush(Qt.white)
        self.marked_brush = QBrush(Qt.lightGray)
        self.marked = None
        self.gui = parent
        self.splitter = QSplitter(self)
        self._l = l = QVBoxLayout(self)
        self.setLayout(l)
        l.addWidget(self.splitter)

        self.cover = CoverView(self)
        self.cover.resizeEvent = self.cover_view_resized
        self.cover.cover_changed.connect(self.cover_changed)
        self.cover_pixmap = None
        self.cover.sizeHint = self.details_size_hint
        self.splitter.addWidget(self.cover)

        self.details = QWebView(self)
        self.details.sizeHint = self.details_size_hint
        self.details.page().setLinkDelegationPolicy(
            self.details.page().DelegateAllLinks)
        self.details.linkClicked.connect(self.link_clicked)
        s = self.details.page().settings()
        s.setAttribute(s.JavascriptEnabled, False)
        self.css = css()
        self.link_delegate = link_delegate
        self.details.setAttribute(Qt.WA_OpaquePaintEvent, False)
        palette = self.details.palette()
        self.details.setAcceptDrops(False)
        palette.setBrush(QPalette.Base, Qt.transparent)
        self.details.page().setPalette(palette)

        self.c = QWidget(self)
        self.c.l = l2 = QGridLayout(self.c)
        self.c.setLayout(l2)
        l2.addWidget(self.details, 0, 0, 1, -1)
        self.splitter.addWidget(self.c)

        self.fit_cover = QCheckBox(_('Fit &cover within view'), self)
        self.fit_cover.setChecked(
            gprefs.get('book_info_dialog_fit_cover', True))
        l2.addWidget(self.fit_cover, l2.rowCount(), 0, 1, -1)
        self.previous_button = QPushButton(QIcon(I('previous.png')),
                                           _('&Previous'), self)
        self.previous_button.clicked.connect(self.previous)
        l2.addWidget(self.previous_button, l2.rowCount(), 0)
        self.next_button = QPushButton(QIcon(I('next.png')), _('&Next'), self)
        self.next_button.clicked.connect(self.next)
        l2.addWidget(self.next_button, l2.rowCount() - 1, 1)

        self.view = view
        self.current_row = None
        self.refresh(row)
        self.view.model().new_bookdisplay_data.connect(self.slave)
        self.fit_cover.stateChanged.connect(self.toggle_cover_fit)
        self.ns = QShortcut(QKeySequence('Alt+Right'), self)
        self.ns.activated.connect(self.next)
        self.ps = QShortcut(QKeySequence('Alt+Left'), self)
        self.ps.activated.connect(self.previous)
        self.next_button.setToolTip(
            _('Next [%s]') %
            unicode(self.ns.key().toString(QKeySequence.NativeText)))
        self.previous_button.setToolTip(
            _('Previous [%s]') %
            unicode(self.ps.key().toString(QKeySequence.NativeText)))

        geom = QCoreApplication.instance().desktop().availableGeometry(self)
        screen_height = geom.height() - 100
        screen_width = geom.width() - 100
        self.resize(max(int(screen_width / 2), 700), screen_height)
        saved_layout = gprefs.get('book_info_dialog_layout', None)
        if saved_layout is not None:
            try:
                self.restoreGeometry(saved_layout[0])
                self.splitter.restoreState(saved_layout[1])
            except Exception:
                pass
Exemplo n.º 58
0
 def read_stats(self):
     stats = gprefs.get('library_usage_stats', {})
     self.stats = stats
Exemplo n.º 59
0
    def setup_ui(self):
        self.vl = vl = QVBoxLayout(self)
        self.stack = l = QStackedLayout()
        self.pi = pi = ProgressIndicator(self, 256)
        vl.addLayout(l), vl.addWidget(self.bb)
        self.restore_defs_button = b = self.bb.addButton(
            _('Restore &default icons'), self.bb.ActionRole)
        b.clicked.connect(self.restore_defaults)
        b.setIcon(QIcon(I('view-refresh.png')))
        self.c = c = QWidget(self)
        self.c.v = v = QVBoxLayout(self.c)
        v.addStretch(), v.addWidget(pi, 0, Qt.AlignCenter)
        self.wait_msg = m = QLabel(self)
        v.addWidget(m, 0, Qt.AlignCenter), v.addStretch()
        f = m.font()
        f.setBold(True), f.setPointSize(28), m.setFont(f)
        self.start_spinner()

        l.addWidget(c)
        self.w = w = QWidget(self)
        l.addWidget(w)
        w.l = l = QGridLayout(w)

        def add_row(x, y=None):
            if isinstance(x, type('')):
                x = QLabel(x)
            row = l.rowCount()
            if y is None:
                if isinstance(x, QLabel):
                    x.setWordWrap(True)
                l.addWidget(x, row, 0, 1, 2)
            else:
                if isinstance(x, QLabel):
                    x.setBuddy(y)
                l.addWidget(x, row, 0), l.addWidget(y, row, 1)

        add_row(
            _('Choose an icon theme below. You will need to restart'
              ' calibre to see the new icons.'))
        add_row(
            _('Current icon theme:') + '\xa0<b>' +
            (self.current_theme or 'None'))
        self.sort_by = sb = QComboBox(self)
        add_row(_('&Sort by:'), sb)
        sb.addItems([
            _('Number of icons'),
            _('Popularity'),
            _('Name'),
        ])
        sb.setEditable(False), sb.setCurrentIndex(
            gprefs.get('choose_icon_theme_sort_by', 1))
        sb.currentIndexChanged[int].connect(self.re_sort)
        sb.currentIndexChanged[int].connect(
            lambda: gprefs.set('choose_icon_theme_sort_by', sb.currentIndex()))
        self.theme_list = tl = QListWidget(self)
        tl.setVerticalScrollMode(tl.ScrollPerPixel)
        self.delegate = Delegate(tl)
        tl.setItemDelegate(self.delegate)
        tl.itemDoubleClicked.connect(self.accept)
        add_row(tl)

        t = Thread(name='GetIconThemes', target=self.get_themes)
        t.daemon = True
        t.start()
Exemplo n.º 60
0
    def __init__(self, parent, db):
        QDialog.__init__(self, parent)
        self.setupUi(self)
        self.um_label.setText(self.um_label.text() % localize_user_manual_link(
            'http://manual.calibre-ebook.com/gui.html#the-search-interface'))
        for val, text in [(0, '')] + [(i, date(2010, i, 1).strftime('%B'))
                                      for i in xrange(1, 13)]:
            self.date_month.addItem(text, val)
        for val, text in [('today', _('Today')), ('yesterday', _('Yesterday')),
                          ('thismonth', _('This month'))]:
            self.date_human.addItem(text, val)
        self.date_year.setValue(now().year)
        self.date_day.setSpecialValueText(u' \xa0')
        vals = [((v['search_terms'] or [k])[0], v['name'] or k)
                for k, v in db.field_metadata.iteritems()
                if v.get('datatype', None) == 'datetime']
        for k, v in sorted(vals, key=lambda (k, v): sort_key(v)):
            self.date_field.addItem(v, k)

        self.date_year.valueChanged.connect(
            lambda: self.sel_date.setChecked(True))
        self.date_month.currentIndexChanged.connect(
            lambda: self.sel_date.setChecked(True))
        self.date_day.valueChanged.connect(
            lambda: self.sel_date.setChecked(True))
        self.date_daysago.valueChanged.connect(
            lambda: self.sel_daysago.setChecked(True))
        self.date_human.currentIndexChanged.connect(
            lambda: self.sel_human.setChecked(True))
        init_dateop(self.dateop_date)
        self.sel_date.setChecked(True)
        self.mc = ''
        searchables = sorted(db.field_metadata.searchable_fields(),
                             key=lambda x: sort_key(x
                                                    if x[0] != '#' else x[1:]))
        self.general_combo.addItems(searchables)

        all_authors = db.all_authors()
        all_authors.sort(key=lambda x: sort_key(x[1]))
        self.authors_box.setEditText('')
        self.authors_box.set_separator('&')
        self.authors_box.set_space_before_sep(True)
        self.authors_box.set_add_separator(
            tweaks['authors_completer_append_separator'])
        self.authors_box.update_items_cache(db.all_author_names())

        all_series = db.all_series()
        all_series.sort(key=lambda x: sort_key(x[1]))
        self.series_box.set_separator(None)
        self.series_box.update_items_cache([x[1] for x in all_series])
        self.series_box.show_initial_value('')

        all_tags = db.all_tags()
        self.tags_box.update_items_cache(all_tags)

        self.box_last_values = copy.deepcopy(box_values)
        if self.box_last_values:
            for k, v in self.box_last_values.items():
                if k == 'general_index':
                    continue
                getattr(self, k).setText(v)
            self.general_combo.setCurrentIndex(
                self.general_combo.findText(
                    self.box_last_values['general_index']))

        self.clear_button.clicked.connect(self.clear_button_pushed)

        current_tab = gprefs.get('advanced search dialog current tab', 0)
        self.tabWidget.setCurrentIndex(current_tab)
        if current_tab == 1:
            self.matchkind.setCurrentIndex(last_matchkind)

        self.tabWidget.currentChanged[int].connect(self.tab_changed)
        self.tab_changed(current_tab)
        self.resize(self.sizeHint())