Ejemplo n.º 1
0
    def __init__(self, gui, icon, guidb, plugin_path, ui_exit, action_type):
        parent = gui
        unique_pref_name = 'library_codes:gui_parameters_dialog'
        SizePersistedDialog.__init__(self, parent, unique_pref_name)
        #-----------------------------------------------------
        self.gui = gui
        self.guidb = guidb
        #-----------------------------------------------------
        self.icon = icon
        #-----------------------------------------------------
        self.plugin_path = plugin_path
        #-----------------------------------------------------
        self.ui_exit = ui_exit
        #-----------------------------------------------------
        self.action_type = action_type
        #-----------------------------------------------------
        self.myparentprefs = collections.OrderedDict([])
        prefsdefaults = deepcopy(prefs.defaults)
        tmp_list = []
        #~ for k,v in prefs.iteritems():
        for k, v in iteritems(prefs):
            tmp_list.append(k)
        #END FOR
        #~ for k,v in prefsdefaults.iteritems():
        for k, v in iteritems(prefsdefaults):
            tmp_list.append(k)
        #END FOR
        tmp_set = set(tmp_list)
        tmp_list = list(tmp_set)  #no duplicates
        del tmp_set
        tmp_list.sort()
        for k in tmp_list:
            self.myparentprefs[k] = " "  # ordered by key
        #END FOR
        del tmp_list
        #~ for k,v in prefs.iteritems():
        for k, v in iteritems(prefs):
            self.myparentprefs[k] = v
        #END FOR
        #~ for k,v in prefsdefaults.iteritems():
        for k, v in iteritems(prefsdefaults):
            if not k in prefs:
                prefs[k] = v
            else:
                if not prefs[k] > " ":
                    prefs[k] = v
            if not k in self.myparentprefs:
                self.myparentprefs[k] = v
            else:
                if not self.myparentprefs[k] > " ":
                    self.myparentprefs[k] = v
        #END FOR
        #~ for k,v in self.myparentprefs.iteritems():
        for k, v in iteritems(self.myparentprefs):
            prefs[k] = v
        #END FOR
        prefs  #prefs now synched
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.param_dict = collections.OrderedDict([])
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.init_tooltips_for_parent()
        self.setToolTip(self.parent_tooltip)
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        # Tab 0: LibraryCodesTab
        #-----------------------------------------------------
        #-----------------------------------------------------
        from calibre_plugins.library_codes.library_codes_dialog import LibraryCodesTab
        self.LibraryCodesTab = LibraryCodesTab(self.gui, self.guidb,
                                               self.myparentprefs,
                                               self.param_dict, self.ui_exit,
                                               self.save_dialog_geometry)
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #    Parent             LibraryCodesDialog
        #-----------------------------------------------------
        font = QFont()
        font.setBold(False)
        font.setPointSize(10)

        tablabel_font = QFont()
        tablabel_font.setBold(False)
        tablabel_font.setPointSize(10)

        #-----------------------------------------------------
        self.setWindowTitle('Library Codes')
        self.setWindowIcon(icon)
        #-----------------------------------------------------
        self.layout_frame = QVBoxLayout()
        self.layout_frame.setAlignment(Qt.AlignLeft)
        self.setLayout(self.layout_frame)
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        n_width = 600

        self.LCtabWidget = QTabWidget()
        self.LCtabWidget.setMaximumWidth(n_width)
        self.LCtabWidget.setFont(tablabel_font)

        self.LCtabWidget.addTab(
            self.LibraryCodesTab,
            "Derivation from ISBN or ISSN or Author/Title")
        self.LibraryCodesTab.setToolTip(
            "<p style='white-space:wrap'>Derive Library Codes DDC and/or LCC and/or OCLC-OWI from ISBN or ISSN or Author/Title.  Visit: http://classify.oclc.org/classify2/ "
        )
        self.LibraryCodesTab.setMaximumWidth(n_width)

        #-----------------------------------------------------
        self.layout_frame.addWidget(self.LCtabWidget)
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.resize_dialog()  # inherited from SizePersistedDialog
        #-----------------------------------------------------
        self.LCtabWidget.setCurrentIndex(0)
Ejemplo n.º 2
0
    def __init__(self, window, plugin, keystore, device_id):
        title = _("{} Settings").format(plugin.device)
        super(SettingsDialog, self).__init__(window, title)
        self.setMaximumWidth(540)

        devmgr = plugin.device_manager()
        config = devmgr.config
        handler = keystore.handler
        thread = keystore.thread
        hs_rows, hs_cols = (64, 128)

        def invoke_client(method, *args, **kw_args):
            unpair_after = kw_args.pop('unpair_after', False)

            def task():
                client = devmgr.client_by_id(device_id)
                if not client:
                    raise RuntimeError("Device not connected")
                if method:
                    getattr(client, method)(*args, **kw_args)
                if unpair_after:
                    devmgr.unpair_id(device_id)
                return client.features

            thread.add(task, on_success=update)

        def update(features):
            self.features = features
            set_label_enabled()
            bl_hash = bh2u(features.bootloader_hash)
            bl_hash = "\n".join([bl_hash[:32], bl_hash[32:]])
            noyes = [_("No"), _("Yes")]
            endis = [_("Enable Passphrases"), _("Disable Passphrases")]
            disen = [_("Disabled"), _("Enabled")]
            setchange = [_("Set a PIN"), _("Change PIN")]

            version = "%d.%d.%d" % (features.major_version,
                                    features.minor_version,
                                    features.patch_version)
            coins = ", ".join(coin.coin_name for coin in features.coins)

            device_label.setText(features.label)
            pin_set_label.setText(noyes[features.pin_protection])
            passphrases_label.setText(disen[features.passphrase_protection])
            bl_hash_label.setText(bl_hash)
            label_edit.setText(features.label)
            device_id_label.setText(features.device_id)
            initialized_label.setText(noyes[features.initialized])
            version_label.setText(version)
            coins_label.setText(coins)
            clear_pin_button.setVisible(features.pin_protection)
            clear_pin_warning.setVisible(features.pin_protection)
            pin_button.setText(setchange[features.pin_protection])
            pin_msg.setVisible(not features.pin_protection)
            passphrase_button.setText(endis[features.passphrase_protection])
            language_label.setText(features.language)

        def set_label_enabled():
            label_apply.setEnabled(label_edit.text() != self.features.label)

        def rename():
            invoke_client('change_label', label_edit.text())

        def toggle_passphrase():
            title = _("Confirm Toggle Passphrase Protection")
            currently_enabled = self.features.passphrase_protection
            if currently_enabled:
                msg = _("After disabling passphrases, you can only pair this "
                        "Electrum wallet if it had an empty passphrase.  "
                        "If its passphrase was not empty, you will need to "
                        "create a new wallet with the install wizard.  You "
                        "can use this wallet again at any time by re-enabling "
                        "passphrases and entering its passphrase.")
            else:
                msg = _("Your current Electrum wallet can only be used with "
                        "an empty passphrase.  You must create a separate "
                        "wallet with the install wizard for other passphrases "
                        "as each one generates a new set of addresses.")
            msg += "\n\n" + _("Are you sure you want to proceed?")
            if not self.question(msg, title=title):
                return
            invoke_client('toggle_passphrase', unpair_after=currently_enabled)

        def change_homescreen():
            from PIL import Image  # FIXME
            dialog = QFileDialog(self, _("Choose Homescreen"))
            filename, __ = dialog.getOpenFileName()
            if filename:
                im = Image.open(str(filename))
                if im.size != (hs_cols, hs_rows):
                    raise Exception('Image must be 64 x 128 pixels')
                im = im.convert('1')
                pix = im.load()
                img = ''
                for j in range(hs_rows):
                    for i in range(hs_cols):
                        img += '1' if pix[i, j] else '0'
                img = ''.join(
                    chr(int(img[i:i + 8], 2)) for i in range(0, len(img), 8))
                invoke_client('change_homescreen', img)

        def clear_homescreen():
            invoke_client('change_homescreen', '\x00')

        def set_pin():
            invoke_client('set_pin', remove=False)

        def clear_pin():
            invoke_client('set_pin', remove=True)

        def wipe_device():
            wallet = window.wallet
            if wallet and sum(wallet.get_balance()):
                title = _("Confirm Device Wipe")
                msg = _("Are you SURE you want to wipe the device?\n"
                        "Your wallet still has bitcoins in it!")
                if not self.question(
                        msg, title=title, icon=QMessageBox.Critical):
                    return
            invoke_client('wipe_device', unpair_after=True)

        def slider_moved():
            mins = timeout_slider.sliderPosition()
            timeout_minutes.setText(_("%2d minutes") % mins)

        def slider_released():
            config.set_session_timeout(timeout_slider.sliderPosition() * 60)

        # Information tab
        info_tab = QWidget()
        info_layout = QVBoxLayout(info_tab)
        info_glayout = QGridLayout()
        info_glayout.setColumnStretch(2, 1)
        device_label = QLabel()
        pin_set_label = QLabel()
        passphrases_label = QLabel()
        version_label = QLabel()
        device_id_label = QLabel()
        bl_hash_label = QLabel()
        bl_hash_label.setWordWrap(True)
        coins_label = QLabel()
        coins_label.setWordWrap(True)
        language_label = QLabel()
        initialized_label = QLabel()
        rows = [
            (_("Device Label"), device_label),
            (_("PIN set"), pin_set_label),
            (_("Passphrases"), passphrases_label),
            (_("Firmware Version"), version_label),
            (_("Device ID"), device_id_label),
            (_("Bootloader Hash"), bl_hash_label),
            (_("Supported Coins"), coins_label),
            (_("Language"), language_label),
            (_("Initialized"), initialized_label),
        ]
        for row_num, (label, widget) in enumerate(rows):
            info_glayout.addWidget(QLabel(label), row_num, 0)
            info_glayout.addWidget(widget, row_num, 1)
        info_layout.addLayout(info_glayout)

        # Settings tab
        settings_tab = QWidget()
        settings_layout = QVBoxLayout(settings_tab)
        settings_glayout = QGridLayout()

        # Settings tab - Label
        label_msg = QLabel(
            _("Name this {}.  If you have multiple devices "
              "their labels help distinguish them.").format(plugin.device))
        label_msg.setWordWrap(True)
        label_label = QLabel(_("Device Label"))
        label_edit = QLineEdit()
        label_edit.setMinimumWidth(150)
        label_edit.setMaxLength(plugin.MAX_LABEL_LEN)
        label_apply = QPushButton(_("Apply"))
        label_apply.clicked.connect(rename)
        label_edit.textChanged.connect(set_label_enabled)
        settings_glayout.addWidget(label_label, 0, 0)
        settings_glayout.addWidget(label_edit, 0, 1, 1, 2)
        settings_glayout.addWidget(label_apply, 0, 3)
        settings_glayout.addWidget(label_msg, 1, 1, 1, -1)

        # Settings tab - PIN
        pin_label = QLabel(_("PIN Protection"))
        pin_button = QPushButton()
        pin_button.clicked.connect(set_pin)
        settings_glayout.addWidget(pin_label, 2, 0)
        settings_glayout.addWidget(pin_button, 2, 1)
        pin_msg = QLabel(
            _("PIN protection is strongly recommended.  "
              "A PIN is your only protection against someone "
              "stealing your bitcoins if they obtain physical "
              "access to your {}.").format(plugin.device))
        pin_msg.setWordWrap(True)
        pin_msg.setStyleSheet("color: red")
        settings_glayout.addWidget(pin_msg, 3, 1, 1, -1)

        # Settings tab - Homescreen
        if plugin.device != 'KeepKey':  # Not yet supported by KK firmware
            homescreen_layout = QHBoxLayout()
            homescreen_label = QLabel(_("Homescreen"))
            homescreen_change_button = QPushButton(_("Change..."))
            homescreen_clear_button = QPushButton(_("Reset"))
            homescreen_change_button.clicked.connect(change_homescreen)
            homescreen_clear_button.clicked.connect(clear_homescreen)
            homescreen_msg = QLabel(
                _("You can set the homescreen on your "
                  "device to personalize it.  You must "
                  "choose a {} x {} monochrome black and "
                  "white image.").format(hs_rows, hs_cols))
            homescreen_msg.setWordWrap(True)
            settings_glayout.addWidget(homescreen_label, 4, 0)
            settings_glayout.addWidget(homescreen_change_button, 4, 1)
            settings_glayout.addWidget(homescreen_clear_button, 4, 2)
            settings_glayout.addWidget(homescreen_msg, 5, 1, 1, -1)

        # Settings tab - Session Timeout
        timeout_label = QLabel(_("Session Timeout"))
        timeout_minutes = QLabel()
        timeout_slider = QSlider(Qt.Horizontal)
        timeout_slider.setRange(1, 60)
        timeout_slider.setSingleStep(1)
        timeout_slider.setTickInterval(5)
        timeout_slider.setTickPosition(QSlider.TicksBelow)
        timeout_slider.setTracking(True)
        timeout_msg = QLabel(
            _("Clear the session after the specified period "
              "of inactivity.  Once a session has timed out, "
              "your PIN and passphrase (if enabled) must be "
              "re-entered to use the device."))
        timeout_msg.setWordWrap(True)
        timeout_slider.setSliderPosition(config.get_session_timeout() // 60)
        slider_moved()
        timeout_slider.valueChanged.connect(slider_moved)
        timeout_slider.sliderReleased.connect(slider_released)
        settings_glayout.addWidget(timeout_label, 6, 0)
        settings_glayout.addWidget(timeout_slider, 6, 1, 1, 3)
        settings_glayout.addWidget(timeout_minutes, 6, 4)
        settings_glayout.addWidget(timeout_msg, 7, 1, 1, -1)
        settings_layout.addLayout(settings_glayout)
        settings_layout.addStretch(1)

        # Advanced tab
        advanced_tab = QWidget()
        advanced_layout = QVBoxLayout(advanced_tab)
        advanced_glayout = QGridLayout()

        # Advanced tab - clear PIN
        clear_pin_button = QPushButton(_("Disable PIN"))
        clear_pin_button.clicked.connect(clear_pin)
        clear_pin_warning = QLabel(
            _("If you disable your PIN, anyone with physical access to your "
              "{} device can spend your bitcoins.").format(plugin.device))
        clear_pin_warning.setWordWrap(True)
        clear_pin_warning.setStyleSheet("color: red")
        advanced_glayout.addWidget(clear_pin_button, 0, 2)
        advanced_glayout.addWidget(clear_pin_warning, 1, 0, 1, 5)

        # Advanced tab - toggle passphrase protection
        passphrase_button = QPushButton()
        passphrase_button.clicked.connect(toggle_passphrase)
        passphrase_msg = WWLabel(PASSPHRASE_HELP)
        passphrase_warning = WWLabel(PASSPHRASE_NOT_PIN)
        passphrase_warning.setStyleSheet("color: red")
        advanced_glayout.addWidget(passphrase_button, 3, 2)
        advanced_glayout.addWidget(passphrase_msg, 4, 0, 1, 5)
        advanced_glayout.addWidget(passphrase_warning, 5, 0, 1, 5)

        # Advanced tab - wipe device
        wipe_device_button = QPushButton(_("Wipe Device"))
        wipe_device_button.clicked.connect(wipe_device)
        wipe_device_msg = QLabel(
            _("Wipe the device, removing all data from it.  The firmware "
              "is left unchanged."))
        wipe_device_msg.setWordWrap(True)
        wipe_device_warning = QLabel(
            _("Only wipe a device if you have the recovery seed written down "
              "and the device wallet(s) are empty, otherwise the bitcoins "
              "will be lost forever."))
        wipe_device_warning.setWordWrap(True)
        wipe_device_warning.setStyleSheet("color: red")
        advanced_glayout.addWidget(wipe_device_button, 6, 2)
        advanced_glayout.addWidget(wipe_device_msg, 7, 0, 1, 5)
        advanced_glayout.addWidget(wipe_device_warning, 8, 0, 1, 5)
        advanced_layout.addLayout(advanced_glayout)
        advanced_layout.addStretch(1)

        tabs = QTabWidget(self)
        tabs.addTab(info_tab, _("Information"))
        tabs.addTab(settings_tab, _("Settings"))
        tabs.addTab(advanced_tab, _("Advanced"))
        dialog_vbox = QVBoxLayout(self)
        dialog_vbox.addWidget(tabs)
        dialog_vbox.addLayout(Buttons(CloseButton(self)))

        # Update information
        invoke_client(None)
Ejemplo n.º 3
0
    def __init__(self, fm, pref_name, parent=None):
        QDialog.__init__(self, parent)
        self.fm = fm

        if pref_name == 'column_color_rules':
            self.rule_kind = 'color'
            rule_text = _('column coloring')
        elif pref_name == 'column_icon_rules':
            self.rule_kind = 'icon'
            rule_text = _('column icon')
        elif pref_name == 'cover_grid_icon_rules':
            self.rule_kind = 'emblem'
            rule_text = _('Cover grid emblem')

        self.setWindowIcon(QIcon(I('format-fill-color.png')))
        self.setWindowTitle(_('Create/edit a {0} rule').format(rule_text))

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

        self.l1 = l1 = QLabel(
            _('Create a {0} rule by'
              ' filling in the boxes below').format(rule_text))
        l.addWidget(l1, 0, 0, 1, 8)

        self.f1 = QFrame(self)
        self.f1.setFrameShape(QFrame.HLine)
        l.addWidget(self.f1, 1, 0, 1, 8)

        self.l2 = l2 = QLabel(
            _('Add the emblem:') if self.rule_kind ==
            'emblem' else _('Set the'))
        l.addWidget(l2, 2, 0)

        if self.rule_kind == 'color':
            l.addWidget(QLabel(_('color')))
        elif self.rule_kind == 'icon':
            self.kind_box = QComboBox(self)
            for tt, t in icon_rule_kinds:
                self.kind_box.addItem(tt, t)
            l.addWidget(self.kind_box, 2, 1)
            self.kind_box.setToolTip(
                textwrap.fill(
                    _('If you choose composed icons and multiple rules match, then all the'
                      ' matching icons will be combined, otherwise the icon from the'
                      ' first rule to match will be used.')))
        else:
            pass

        self.l3 = l3 = QLabel(_('of the column:'))
        l.addWidget(l3, 2, 2)

        self.column_box = QComboBox(self)
        l.addWidget(self.column_box, 2, 3)

        self.l4 = l4 = QLabel(_('to'))
        l.addWidget(l4, 2, 4)
        if self.rule_kind == 'emblem':
            l3.setVisible(False), self.column_box.setVisible(
                False), l4.setVisible(False)

        def create_filename_box():
            self.filename_box = f = QComboBox()
            self.filenamebox_view = v = QListView()
            v.setIconSize(QSize(32, 32))
            self.filename_box.setView(v)
            self.orig_filenamebox_view = f.view()
            f.setMinimumContentsLength(20), f.setSizeAdjustPolicy(
                f.AdjustToMinimumContentsLengthWithIcon)
            self.populate_icon_filenames()

        if self.rule_kind == 'color':
            self.color_box = ColorButton(parent=self)
            self.color_label = QLabel('Sample text Sample text')
            self.color_label.setTextFormat(Qt.RichText)
            l.addWidget(self.color_box, 2, 5)
            l.addWidget(self.color_label, 2, 6)
            l.addItem(QSpacerItem(10, 10, QSizePolicy.Expanding), 2, 7)
        elif self.rule_kind == 'emblem':
            create_filename_box()
            self.update_filename_box()
            self.filename_button = QPushButton(QIcon(I('document_open.png')),
                                               _('&Add new image'))
            l.addWidget(self.filename_box)
            l.addWidget(self.filename_button, 2, 6)
            l.addWidget(QLabel(_('(Images should be square-ish)')), 2, 7)
            l.setColumnStretch(7, 10)
        else:
            create_filename_box()

            vb = QVBoxLayout()
            self.multiple_icon_cb = QCheckBox(_('Choose &more than one icon'))
            vb.addWidget(self.multiple_icon_cb)
            self.update_filename_box()
            self.multiple_icon_cb.clicked.connect(self.multiple_box_clicked)
            vb.addWidget(self.filename_box)
            l.addLayout(vb, 2, 5)

            self.filename_button = QPushButton(QIcon(I('document_open.png')),
                                               _('&Add icon'))
            l.addWidget(self.filename_button, 2, 6)
            l.addWidget(QLabel(_('Icons should be square or landscape')), 2, 7)
            l.setColumnStretch(7, 10)

        self.l5 = l5 = QLabel(
            _('Only if the following conditions are all satisfied:'))
        l.addWidget(l5, 3, 0, 1, 7)

        self.scroll_area = sa = QScrollArea(self)
        sa.setMinimumHeight(300)
        sa.setMinimumWidth(950)
        sa.setWidgetResizable(True)
        l.addWidget(sa, 4, 0, 1, 8)

        self.add_button = b = QPushButton(QIcon(I('plus.png')),
                                          _('Add &another condition'))
        l.addWidget(b, 5, 0, 1, 8)
        b.clicked.connect(self.add_blank_condition)

        self.l6 = l6 = QLabel(
            _('You can disable a condition by'
              ' blanking all of its boxes'))
        l.addWidget(l6, 6, 0, 1, 8)

        self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok
                                        | QDialogButtonBox.Cancel)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        l.addWidget(bb, 7, 0, 1, 8)
        if self.rule_kind != 'color':
            self.remove_button = b = bb.addButton(_('&Remove icon'),
                                                  bb.ActionRole)
            b.setIcon(QIcon(I('minus.png')))
            b.setMenu(QMenu())
            b.setToolTip('<p>' + _(
                'Remove a previously added icon. Note that doing so will cause rules that use it to stop working.'
            ))
            self.update_remove_button()

        self.conditions_widget = QWidget(self)
        sa.setWidget(self.conditions_widget)
        self.conditions_widget.setLayout(QVBoxLayout())
        self.conditions_widget.layout().setAlignment(Qt.AlignTop)
        self.conditions = []

        if self.rule_kind == 'color':
            for b in (self.column_box, ):
                b.setSizeAdjustPolicy(b.AdjustToMinimumContentsLengthWithIcon)
                b.setMinimumContentsLength(15)

        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 self.rule_kind != 'color':
                continue
            name = all_columns_string if key == color_row_key else fm[key][
                'name']
            if name:
                self.column_box.addItem(name, key)
        self.column_box.setCurrentIndex(0)

        if self.rule_kind == 'color':
            self.color_box.color = '#000'
            self.update_color_label()
            self.color_box.color_changed.connect(self.update_color_label)
        else:
            self.rule_icon_files = []
            self.filename_button.clicked.connect(self.filename_button_clicked)

        self.resize(self.sizeHint())
Ejemplo n.º 4
0
    def __init__(self, parent, db):
        QDialog.__init__(self, parent)
        self.db = db

        self.setWindowTitle(_('Check library -- Problems found'))
        self.setWindowIcon(QIcon(I('debug.png')))

        self._tl = QHBoxLayout()
        self.setLayout(self._tl)
        self.splitter = QSplitter(self)
        self.left = QWidget(self)
        self.splitter.addWidget(self.left)
        self.helpw = QTextEdit(self)
        self.splitter.addWidget(self.helpw)
        self._tl.addWidget(self.splitter)
        self._layout = QVBoxLayout()
        self.left.setLayout(self._layout)
        self.helpw.setReadOnly(True)
        self.helpw.setText(
            _('''\
        <h1>Help</h1>

        <p>calibre stores the list of your books and their metadata in a
        database. The actual book files and covers are stored as normal
        files in the calibre library folder. The database contains a list of the files
        and covers belonging to each book entry. This tool checks that the
        actual files in the library folder on your computer match the
        information in the database.</p>

        <p>The result of each type of check is shown to the left. The various
        checks are:
        </p>
        <ul>
        <li><b>Invalid titles</b>: These are files and folders appearing
        in the library where books titles should, but that do not have the
        correct form to be a book title.</li>
        <li><b>Extra titles</b>: These are extra files in your calibre
        library that appear to be correctly-formed titles, but have no corresponding
        entries in the database</li>
        <li><b>Invalid authors</b>: These are files appearing
        in the library where only author folders should be.</li>
        <li><b>Extra authors</b>: These are folders in the
        calibre library that appear to be authors but that do not have entries
        in the database</li>
        <li><b>Missing book formats</b>: These are book formats that are in
        the database but have no corresponding format file in the book's folder.
        <li><b>Extra book formats</b>: These are book format files found in
        the book's folder but not in the database.
        <li><b>Unknown files in books</b>: These are extra files in the
        folder of each book that do not correspond to a known format or cover
        file.</li>
        <li><b>Missing cover files</b>: These represent books that are marked
        in the database as having covers but the actual cover files are
        missing.</li>
        <li><b>Cover files not in database</b>: These are books that have
        cover files but are marked as not having covers in the database.</li>
        <li><b>Folder raising exception</b>: These represent folders in the
        calibre library that could not be processed/understood by this
        tool.</li>
        </ul>

        <p>There are two kinds of automatic fixes possible: <i>Delete
        marked</i> and <i>Fix marked</i>.</p>
        <p><i>Delete marked</i> is used to remove extra files/folders/covers that
        have no entries in the database. Check the box next to the item you want
        to delete. Use with caution.</p>

        <p><i>Fix marked</i> is applicable only to covers and missing formats
        (the three lines marked 'fixable'). In the case of missing cover files,
        checking the fixable box and pushing this button will tell calibre that
        there is no cover for all of the books listed. Use this option if you
        are not going to restore the covers from a backup. In the case of extra
        cover files, checking the fixable box and pushing this button will tell
        calibre that the cover files it found are correct for all the books
        listed. Use this when you are not going to delete the file(s). In the
        case of missing formats, checking the fixable box and pushing this
        button will tell calibre that the formats are really gone. Use this if
        you are not going to restore the formats from a backup.</p>

        '''))

        self.log = QTreeWidget(self)
        self.log.itemChanged.connect(self.item_changed)
        self.log.itemExpanded.connect(self.item_expanded_or_collapsed)
        self.log.itemCollapsed.connect(self.item_expanded_or_collapsed)
        self._layout.addWidget(self.log)

        self.check_button = QPushButton(_('&Run the check again'))
        self.check_button.setDefault(False)
        self.check_button.clicked.connect(self.run_the_check)
        self.copy_button = QPushButton(_('Copy &to clipboard'))
        self.copy_button.setDefault(False)
        self.copy_button.clicked.connect(self.copy_to_clipboard)
        self.ok_button = QPushButton(_('&Done'))
        self.ok_button.setDefault(True)
        self.ok_button.clicked.connect(self.accept)
        self.mark_delete_button = QPushButton(_('Mark &all for delete'))
        self.mark_delete_button.setToolTip(_('Mark all deletable subitems'))
        self.mark_delete_button.setDefault(False)
        self.mark_delete_button.clicked.connect(self.mark_for_delete)
        self.delete_button = QPushButton(_('Delete &marked'))
        self.delete_button.setToolTip(
            _('Delete marked files (checked subitems)'))
        self.delete_button.setDefault(False)
        self.delete_button.clicked.connect(self.delete_marked)
        self.mark_fix_button = QPushButton(_('Mar&k all for fix'))
        self.mark_fix_button.setToolTip(_('Mark all fixable items'))
        self.mark_fix_button.setDefault(False)
        self.mark_fix_button.clicked.connect(self.mark_for_fix)
        self.fix_button = QPushButton(_('&Fix marked'))
        self.fix_button.setDefault(False)
        self.fix_button.setEnabled(False)
        self.fix_button.setToolTip(
            _('Fix marked sections (checked fixable items)'))
        self.fix_button.clicked.connect(self.fix_items)
        self.bbox = QGridLayout()
        self.bbox.addWidget(self.check_button, 0, 0)
        self.bbox.addWidget(self.copy_button, 0, 1)
        self.bbox.addWidget(self.ok_button, 0, 2)
        self.bbox.addWidget(self.mark_delete_button, 1, 0)
        self.bbox.addWidget(self.delete_button, 1, 1)
        self.bbox.addWidget(self.mark_fix_button, 2, 0)
        self.bbox.addWidget(self.fix_button, 2, 1)

        h = QHBoxLayout()
        ln = QLabel(_('Names to ignore:'))
        h.addWidget(ln)
        self.name_ignores = QLineEdit()
        self.name_ignores.setText(
            db.prefs.get('check_library_ignore_names', ''))
        self.name_ignores.setToolTip(
            _('Enter comma-separated standard file name wildcards, such as synctoy*.dat'
              ))
        ln.setBuddy(self.name_ignores)
        h.addWidget(self.name_ignores)
        le = QLabel(_('Extensions to ignore:'))
        h.addWidget(le)
        self.ext_ignores = QLineEdit()
        self.ext_ignores.setText(
            db.prefs.get('check_library_ignore_extensions', ''))
        self.ext_ignores.setToolTip(
            _('Enter comma-separated extensions without a leading dot. Used only in book folders'
              ))
        le.setBuddy(self.ext_ignores)
        h.addWidget(self.ext_ignores)
        self._layout.addLayout(h)

        self._layout.addLayout(self.bbox)
        self.resize(950, 500)
Ejemplo n.º 5
0
Archivo: ui.py Proyecto: chaxiu/calibre
    def __init__(self, open_at=None, continue_reading=None, force_reload=False):
        MainWindow.__init__(self, None)
        self.force_reload = force_reload
        connect_lambda(self.book_preparation_started, self, lambda self: self.loading_overlay(_(
            'Preparing book for first read, please wait')), type=Qt.QueuedConnection)
        self.maximized_at_last_fullscreen = False
        self.pending_open_at = open_at
        self.base_window_title = _('E-book viewer')
        self.setWindowTitle(self.base_window_title)
        self.in_full_screen_mode = None
        self.image_popup = ImagePopup(self)
        self.actions_toolbar = at = ActionsToolBar(self)
        at.open_book_at_path.connect(self.ask_for_open)
        self.addToolBar(Qt.LeftToolBarArea, at)
        try:
            os.makedirs(annotations_dir)
        except EnvironmentError:
            pass
        self.current_book_data = {}
        self.book_prepared.connect(self.load_finished, type=Qt.QueuedConnection)
        self.dock_defs = dock_defs()

        def create_dock(title, name, area, areas=Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea):
            ans = QDockWidget(title, self)
            ans.setObjectName(name)
            self.addDockWidget(area, ans)
            ans.setVisible(False)
            return ans

        for dock_def in itervalues(self.dock_defs):
            setattr(self, '{}_dock'.format(dock_def.name.partition('-')[0]), create_dock(
                dock_def.title, dock_def.name, dock_def.initial_area, dock_def.allowed_areas))

        self.toc_container = w = QWidget(self)
        w.l = QVBoxLayout(w)
        self.toc = TOCView(w)
        self.toc.clicked[QModelIndex].connect(self.toc_clicked)
        self.toc.searched.connect(self.toc_searched)
        self.toc_search = TOCSearch(self.toc, parent=w)
        w.l.addWidget(self.toc), w.l.addWidget(self.toc_search), w.l.setContentsMargins(0, 0, 0, 0)
        self.toc_dock.setWidget(w)

        self.lookup_widget = w = Lookup(self)
        self.lookup_dock.visibilityChanged.connect(self.lookup_widget.visibility_changed)
        self.lookup_dock.setWidget(w)

        self.bookmarks_widget = w = BookmarkManager(self)
        connect_lambda(
            w.create_requested, self,
            lambda self: self.web_view.get_current_cfi(self.bookmarks_widget.create_new_bookmark))
        w.edited.connect(self.bookmarks_edited)
        w.activated.connect(self.bookmark_activated)
        w.toggle_requested.connect(self.toggle_bookmarks)
        self.bookmarks_dock.setWidget(w)

        self.web_view = WebView(self)
        self.web_view.cfi_changed.connect(self.cfi_changed)
        self.web_view.reload_book.connect(self.reload_book)
        self.web_view.toggle_toc.connect(self.toggle_toc)
        self.web_view.toggle_bookmarks.connect(self.toggle_bookmarks)
        self.web_view.toggle_inspector.connect(self.toggle_inspector)
        self.web_view.toggle_lookup.connect(self.toggle_lookup)
        self.web_view.quit.connect(self.quit)
        self.web_view.update_current_toc_nodes.connect(self.toc.update_current_toc_nodes)
        self.web_view.toggle_full_screen.connect(self.toggle_full_screen)
        self.web_view.ask_for_open.connect(self.ask_for_open, type=Qt.QueuedConnection)
        self.web_view.selection_changed.connect(self.lookup_widget.selected_text_changed, type=Qt.QueuedConnection)
        self.web_view.view_image.connect(self.view_image, type=Qt.QueuedConnection)
        self.web_view.copy_image.connect(self.copy_image, type=Qt.QueuedConnection)
        self.web_view.show_loading_message.connect(self.show_loading_message)
        self.web_view.show_error.connect(self.show_error)
        self.web_view.print_book.connect(self.print_book, type=Qt.QueuedConnection)
        self.web_view.reset_interface.connect(self.reset_interface, type=Qt.QueuedConnection)
        self.web_view.shortcuts_changed.connect(self.shortcuts_changed)
        self.actions_toolbar.initialize(self.web_view)
        self.setCentralWidget(self.web_view)
        self.loading_overlay = LoadingOverlay(self)
        self.restore_state()
        self.actions_toolbar.update_visibility()
        if continue_reading:
            self.continue_reading()
Ejemplo n.º 6
0
    def _initialize_controls(self):
        self.setWindowTitle(_('User plugins'))
        self.setWindowIcon(QIcon(I('plugins/plugin_updater.png')))
        layout = QVBoxLayout(self)
        self.setLayout(layout)
        title_layout = ImageTitleLayout(self, 'plugins/plugin_updater.png',
                                        _('User plugins'))
        layout.addLayout(title_layout)

        header_layout = QHBoxLayout()
        layout.addLayout(header_layout)
        self.filter_combo = PluginFilterComboBox(self)
        self.filter_combo.setMinimumContentsLength(20)
        self.filter_combo.currentIndexChanged[int].connect(
            self._filter_combo_changed)
        la = QLabel(_('Filter list of &plugins') + ':', self)
        la.setBuddy(self.filter_combo)
        header_layout.addWidget(la)
        header_layout.addWidget(self.filter_combo)
        header_layout.addStretch(10)

        # filter plugins by name
        la = QLabel(_('Filter by &name') + ':', self)
        header_layout.addWidget(la)
        self.filter_by_name_lineedit = QLineEdit(self)
        la.setBuddy(self.filter_by_name_lineedit)
        self.filter_by_name_lineedit.setText("")
        self.filter_by_name_lineedit.textChanged.connect(
            self._filter_name_lineedit_changed)

        header_layout.addWidget(self.filter_by_name_lineedit)

        self.plugin_view = QTableView(self)
        self.plugin_view.horizontalHeader().setStretchLastSection(True)
        self.plugin_view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.plugin_view.setSelectionMode(QAbstractItemView.SingleSelection)
        self.plugin_view.setAlternatingRowColors(True)
        self.plugin_view.setSortingEnabled(True)
        self.plugin_view.setIconSize(QSize(28, 28))
        layout.addWidget(self.plugin_view)

        details_layout = QHBoxLayout()
        layout.addLayout(details_layout)
        forum_label = self.forum_label = QLabel('')
        forum_label.setTextInteractionFlags(Qt.LinksAccessibleByMouse
                                            | Qt.LinksAccessibleByKeyboard)
        forum_label.linkActivated.connect(self._forum_label_activated)
        details_layout.addWidget(QLabel(_('Description') + ':', self), 0,
                                 Qt.AlignLeft)
        details_layout.addWidget(forum_label, 1, Qt.AlignRight)

        self.description = QLabel(self)
        self.description.setFrameStyle(QFrame.Panel | QFrame.Sunken)
        self.description.setAlignment(Qt.AlignTop | Qt.AlignLeft)
        self.description.setMinimumHeight(40)
        self.description.setWordWrap(True)
        layout.addWidget(self.description)

        self.button_box = QDialogButtonBox(QDialogButtonBox.Close)
        self.button_box.rejected.connect(self.reject)
        self.finished.connect(self._finished)
        self.install_button = self.button_box.addButton(
            _('&Install'), QDialogButtonBox.AcceptRole)
        self.install_button.setToolTip(_('Install the selected plugin'))
        self.install_button.clicked.connect(self._install_clicked)
        self.install_button.setEnabled(False)
        self.configure_button = self.button_box.addButton(
            ' ' + _('&Customize plugin ') + ' ', QDialogButtonBox.ResetRole)
        self.configure_button.setToolTip(
            _('Customize the options for this plugin'))
        self.configure_button.clicked.connect(self._configure_clicked)
        self.configure_button.setEnabled(False)
        layout.addWidget(self.button_box)
Ejemplo n.º 7
0
def ask_about_cc_mismatch(gui, db, newdb, missing_cols,
                          incompatible_cols):  # {{{
    source_metadata = db.field_metadata.custom_field_metadata(
        include_composites=True)
    ndbname = os.path.basename(newdb.library_path)

    d = QDialog(gui)
    d.setWindowTitle(_('Different custom columns'))
    l = QFormLayout()
    tl = QVBoxLayout()
    d.setLayout(tl)
    d.s = QScrollArea(d)
    tl.addWidget(d.s)
    d.w = QWidget(d)
    d.s.setWidget(d.w)
    d.s.setWidgetResizable(True)
    d.w.setLayout(l)
    d.setMinimumWidth(600)
    d.setMinimumHeight(500)
    d.bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)

    msg = _(
        'The custom columns in the <i>{0}</i> library are different from the '
        'custom columns in the <i>{1}</i> library. As a result, some metadata might not be copied.'
    ).format(os.path.basename(db.library_path), ndbname)
    d.la = la = QLabel(msg)
    la.setWordWrap(True)
    la.setStyleSheet('QLabel { margin-bottom: 1.5ex }')
    l.addRow(la)
    if incompatible_cols:
        la = d.la2 = QLabel(
            _('The following columns are incompatible - they have the same name'
              ' but different data types. They will be ignored: ') +
            ', '.join(sorted(incompatible_cols, key=sort_key)))
        la.setWordWrap(True)
        la.setStyleSheet('QLabel { margin-bottom: 1.5ex }')
        l.addRow(la)

    missing_widgets = []
    if missing_cols:
        la = d.la3 = QLabel(
            _('The following columns are missing in the <i>{0}</i> library.'
              ' You can choose to add them automatically below.').format(
                  ndbname))
        la.setWordWrap(True)
        l.addRow(la)
        for k in missing_cols:
            widgets = (k, QCheckBox(_('Add to the %s library') % ndbname))
            l.addRow(QLabel(k), widgets[1])
            missing_widgets.append(widgets)
    d.la4 = la = QLabel(
        _('This warning is only shown once per library, per session'))
    la.setWordWrap(True)
    tl.addWidget(la)

    tl.addWidget(d.bb)
    d.bb.accepted.connect(d.accept)
    d.bb.rejected.connect(d.reject)
    d.resize(d.sizeHint())
    if d.exec_() == d.Accepted:
        for k, cb in missing_widgets:
            if cb.isChecked():
                col_meta = source_metadata[k]
                newdb.create_custom_column(col_meta['label'], col_meta['name'],
                                           col_meta['datatype'],
                                           len(col_meta['is_multiple']) > 0,
                                           col_meta['is_editable'],
                                           col_meta['display'])
        return True
    return False
Ejemplo n.º 8
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()
Ejemplo n.º 9
0
    def start(self):
        self.setCurrentWidget(self.wp)
        self.wp.start()

    def stop(self):
        self.wp.stop()
        self.setCurrentWidget(self.after)

    @property
    def msg(self):
        return self.wp.msg

    @msg.setter
    def msg(self, val):
        self.wp.msg = val


if __name__ == '__main__':
    from calibre.gui2 import Application
    app = Application([])
    d = QDialog()
    d.resize(64, 64)
    w = ProgressSpinner(d)
    l = QVBoxLayout(d)
    l.addWidget(w)
    w.start()
    d.exec_()
    del d
    del app
Ejemplo n.º 10
0
    def do_layout(self):
        self.central_widget.clear()
        self.tabs = []
        self.labels = []
        sto = QWidget.setTabOrder

        self.on_drag_enter.connect(self.handle_drag_enter)
        self.tabs.append(DragTrackingWidget(self, self.on_drag_enter))
        self.central_widget.addTab(self.tabs[0], _("&Metadata"))
        self.tabs[0].l = QGridLayout()
        self.tabs[0].setLayout(self.tabs[0].l)

        self.tabs.append(QWidget(self))
        self.central_widget.addTab(self.tabs[1], _("&Cover and formats"))
        self.tabs[1].l = QGridLayout()
        self.tabs[1].setLayout(self.tabs[1].l)

        # accept drop events so we can automatically switch to the second tab to
        # drop covers and formats
        self.tabs[0].setAcceptDrops(True)

        # Tab 0
        tab0 = self.tabs[0]

        tl = QGridLayout()
        gb = QGroupBox(_('&Basic metadata'), self.tabs[0])
        self.tabs[0].l.addWidget(gb, 0, 0, 1, 1)
        gb.setLayout(tl)

        self.button_box_layout.insertWidget(1, self.fetch_metadata_button)
        self.button_box_layout.insertWidget(2, self.config_metadata_button)
        sto(self.button_box, self.fetch_metadata_button)
        sto(self.fetch_metadata_button, self.config_metadata_button)
        sto(self.config_metadata_button, self.title)

        def create_row(row, widget, tab_to, button=None, icon=None, span=1):
            ql = BuddyLabel(widget)
            tl.addWidget(ql, row, 1, 1, 1)
            tl.addWidget(widget, row, 2, 1, 1)
            if button is not None:
                tl.addWidget(button, row, 3, span, 1)
                if icon is not None:
                    button.setIcon(QIcon(I(icon)))
            if tab_to is not None:
                if button is not None:
                    sto(widget, button)
                    sto(button, tab_to)
                else:
                    sto(widget, tab_to)

        tl.addWidget(self.swap_title_author_button, 0, 0, 2, 1)
        tl.addWidget(self.manage_authors_button, 2, 0, 1, 1)
        tl.addWidget(self.paste_isbn_button, 12, 0, 1, 1)
        tl.addWidget(self.tags_editor_button, 6, 0, 1, 1)

        create_row(0, self.title, self.title_sort,
                   button=self.deduce_title_sort_button, span=2,
                   icon='auto_author_sort.png')
        create_row(1, self.title_sort, self.authors)
        create_row(2, self.authors, self.author_sort,
                   button=self.deduce_author_sort_button,
                   span=2, icon='auto_author_sort.png')
        create_row(3, self.author_sort, self.series)
        create_row(4, self.series, self.series_index,
                   button=self.clear_series_button, icon='trash.png')
        create_row(5, self.series_index, self.tags)
        create_row(6, self.tags, self.rating, button=self.clear_tags_button)
        create_row(7, self.rating, self.pubdate, button=self.clear_ratings_button)
        create_row(8, self.pubdate, self.publisher,
                   button=self.pubdate.clear_button, icon='trash.png')
        create_row(9, self.publisher, self.languages)
        create_row(10, self.languages, self.timestamp)
        create_row(11, self.timestamp, self.identifiers,
                   button=self.timestamp.clear_button, icon='trash.png')
        create_row(12, self.identifiers, self.comments,
                   button=self.clear_identifiers_button, icon='trash.png')
        sto(self.clear_identifiers_button, self.swap_title_author_button)
        sto(self.swap_title_author_button, self.manage_authors_button)
        sto(self.manage_authors_button, self.tags_editor_button)
        sto(self.tags_editor_button, self.paste_isbn_button)
        tl.addItem(QSpacerItem(1, 1, QSizePolicy.Fixed, QSizePolicy.Expanding),
                   13, 1, 1 ,1)

        w = getattr(self, 'custom_metadata_widgets_parent', None)
        if w is not None:
            gb = QGroupBox(_('C&ustom metadata'), tab0)
            gbl = QVBoxLayout()
            gb.setLayout(gbl)
            sr = QScrollArea(tab0)
            sr.setWidgetResizable(True)
            sr.setFrameStyle(QFrame.NoFrame)
            sr.setWidget(w)
            gbl.addWidget(sr)
            self.tabs[0].l.addWidget(gb, 0, 1, 1, 1)
            sto(self.identifiers, gb)

        w = QGroupBox(_('&Comments'), tab0)
        sp = QSizePolicy()
        sp.setVerticalStretch(10)
        sp.setHorizontalPolicy(QSizePolicy.Expanding)
        sp.setVerticalPolicy(QSizePolicy.Expanding)
        w.setSizePolicy(sp)
        l = QHBoxLayout()
        w.setLayout(l)
        l.addWidget(self.comments)
        tab0.l.addWidget(w, 1, 0, 1, 2)

        # Tab 1
        tab1 = self.tabs[1]

        wsp = QWidget(tab1)
        wgl = QVBoxLayout()
        wsp.setLayout(wgl)

        # right-hand side of splitter
        gb = QGroupBox(_('Change cover'), tab1)
        l = QGridLayout()
        gb.setLayout(l)
        for i, b in enumerate(self.cover.buttons[:3]):
            l.addWidget(b, 0, i, 1, 1)
            sto(b, self.cover.buttons[i+1])
        hl = QHBoxLayout()
        for b in self.cover.buttons[3:]:
            hl.addWidget(b)
        sto(self.cover.buttons[-2], self.cover.buttons[-1])
        l.addLayout(hl, 1, 0, 1, 3)
        wgl.addWidget(gb)
        wgl.addItem(QSpacerItem(10, 10, QSizePolicy.Expanding,
            QSizePolicy.Expanding))
        wgl.addItem(QSpacerItem(10, 10, QSizePolicy.Expanding,
            QSizePolicy.Expanding))
        wgl.addWidget(self.formats_manager)

        self.splitter = QSplitter(Qt.Horizontal, tab1)
        tab1.l.addWidget(self.splitter)
        self.splitter.addWidget(self.cover)
        self.splitter.addWidget(wsp)

        self.formats_manager.formats.setMaximumWidth(10000)
        self.formats_manager.formats.setIconSize(QSize(64, 64))
Ejemplo n.º 11
0
    def do_layout(self):
        self.central_widget.clear()
        self.labels = []
        sto = QWidget.setTabOrder

        self.central_widget.tabBar().setVisible(False)
        tab0 = QWidget(self)
        self.central_widget.addTab(tab0, _("&Metadata"))
        l = QGridLayout()
        tab0.setLayout(l)

        # Basic metadata in col 0
        tl = QGridLayout()
        gb = QGroupBox(_('Basic metadata'), tab0)
        l.addWidget(gb, 0, 0, 1, 1)
        gb.setLayout(tl)

        self.button_box_layout.insertWidget(1, self.fetch_metadata_button)
        self.button_box_layout.insertWidget(2, self.config_metadata_button)
        sto(self.button_box, self.fetch_metadata_button)
        sto(self.fetch_metadata_button, self.config_metadata_button)
        sto(self.config_metadata_button, self.title)

        def create_row(row, widget, tab_to, button=None, icon=None, span=1):
            ql = BuddyLabel(widget)
            tl.addWidget(ql, row, 1, 1, 1)
            tl.addWidget(widget, row, 2, 1, 1)
            if button is not None:
                tl.addWidget(button, row, 3, span, 1)
                if icon is not None:
                    button.setIcon(QIcon(I(icon)))
            if tab_to is not None:
                if button is not None:
                    sto(widget, button)
                    sto(button, tab_to)
                else:
                    sto(widget, tab_to)

        tl.addWidget(self.swap_title_author_button, 0, 0, 2, 1)
        tl.addWidget(self.manage_authors_button, 2, 0, 2, 1)
        tl.addWidget(self.paste_isbn_button, 12, 0, 1, 1)
        tl.addWidget(self.tags_editor_button, 6, 0, 1, 1)

        create_row(0, self.title, self.title_sort,
                   button=self.deduce_title_sort_button, span=2,
                   icon='auto_author_sort.png')
        create_row(1, self.title_sort, self.authors)
        create_row(2, self.authors, self.author_sort,
                   button=self.deduce_author_sort_button,
                   span=2, icon='auto_author_sort.png')
        create_row(3, self.author_sort, self.series)
        create_row(4, self.series, self.series_index,
                   button=self.clear_series_button, icon='trash.png')
        create_row(5, self.series_index, self.tags)
        create_row(6, self.tags, self.rating, button=self.clear_tags_button)
        create_row(7, self.rating, self.pubdate, button=self.clear_ratings_button)
        create_row(8, self.pubdate, self.publisher,
                   button=self.pubdate.clear_button, icon='trash.png')
        create_row(9, self.publisher, self.languages)
        create_row(10, self.languages, self.timestamp)
        create_row(11, self.timestamp, self.identifiers,
                   button=self.timestamp.clear_button, icon='trash.png')
        create_row(12, self.identifiers, self.comments,
                   button=self.clear_identifiers_button, icon='trash.png')
        sto(self.clear_identifiers_button, self.swap_title_author_button)
        sto(self.swap_title_author_button, self.manage_authors_button)
        sto(self.manage_authors_button, self.tags_editor_button)
        sto(self.tags_editor_button, self.paste_isbn_button)
        tl.addItem(QSpacerItem(1, 1, QSizePolicy.Fixed, QSizePolicy.Expanding),
                   13, 1, 1 ,1)

        # Custom metadata in col 1
        w = getattr(self, 'custom_metadata_widgets_parent', None)
        if w is not None:
            gb = QGroupBox(_('Custom metadata'), tab0)
            gbl = QVBoxLayout()
            gb.setLayout(gbl)
            sr = QScrollArea(gb)
            sr.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
            sr.setWidgetResizable(True)
            sr.setFrameStyle(QFrame.NoFrame)
            sr.setWidget(w)
            gbl.addWidget(sr)
            l.addWidget(gb, 0, 1, 1, 1)
            sp = QSizePolicy()
            sp.setVerticalStretch(10)
            sp.setHorizontalPolicy(QSizePolicy.Minimum)
            sp.setVerticalPolicy(QSizePolicy.Expanding)
            gb.setSizePolicy(sp)
            self.set_custom_metadata_tab_order()

        # comments span col 0 & 1
        w = QGroupBox(_('Comments'), tab0)
        sp = QSizePolicy()
        sp.setVerticalStretch(10)
        sp.setHorizontalPolicy(QSizePolicy.Expanding)
        sp.setVerticalPolicy(QSizePolicy.Expanding)
        w.setSizePolicy(sp)
        lb = QHBoxLayout()
        w.setLayout(lb)
        lb.addWidget(self.comments)
        l.addWidget(w, 1, 0, 1, 2)

        # Cover & formats in col 3
        gb = QGroupBox(_('Cover'), tab0)
        lb = QGridLayout()
        gb.setLayout(lb)
        lb.addWidget(self.cover, 0, 0, 1, 3, alignment=Qt.AlignCenter)
        sto(self.manage_authors_button, self.cover.buttons[0])
        for i, b in enumerate(self.cover.buttons[:3]):
            lb.addWidget(b, 1, i, 1, 1)
            sto(b, self.cover.buttons[i+1])
        hl = QHBoxLayout()
        for b in self.cover.buttons[3:]:
            hl.addWidget(b)
        sto(self.cover.buttons[-2], self.cover.buttons[-1])
        lb.addLayout(hl, 2, 0, 1, 3)
        l.addWidget(gb, 0, 2, 1, 1)
        l.addWidget(self.formats_manager, 1, 2, 1, 1)
        sto(self.cover.buttons[-1], self.formats_manager)

        self.formats_manager.formats.setMaximumWidth(10000)
        self.formats_manager.formats.setIconSize(QSize(32, 32))
Ejemplo n.º 12
0
    def do_layout(self):
        if len(self.db.custom_column_label_map) == 0:
            self.central_widget.tabBar().setVisible(False)
        self.central_widget.clear()
        self.tabs = []
        self.labels = []
        self.tabs.append(QWidget(self))
        self.central_widget.addTab(self.tabs[0], _("&Basic metadata"))
        self.tabs[0].l = l = QVBoxLayout()
        self.tabs[0].tl = tl = QGridLayout()
        self.tabs[0].setLayout(l)
        w = getattr(self, 'custom_metadata_widgets_parent', None)
        if w is not None:
            self.tabs.append(w)
            self.central_widget.addTab(w, _('&Custom metadata'))
        l.addLayout(tl)
        l.addItem(QSpacerItem(10, 15, QSizePolicy.Expanding,
            QSizePolicy.Fixed))

        sto = QWidget.setTabOrder
        sto(self.button_box, self.fetch_metadata_button)
        sto(self.fetch_metadata_button, self.config_metadata_button)
        sto(self.config_metadata_button, self.title)

        def create_row(row, one, two, three, col=1, icon='forward.png'):
            ql = BuddyLabel(one)
            tl.addWidget(ql, row, col+0, 1, 1)
            self.labels.append(ql)
            tl.addWidget(one, row, col+1, 1, 1)
            if two is not None:
                tl.addWidget(two, row, col+2, 1, 1)
                two.setIcon(QIcon(I(icon)))
            ql = BuddyLabel(three)
            tl.addWidget(ql, row, col+3, 1, 1)
            self.labels.append(ql)
            tl.addWidget(three, row, col+4, 1, 1)
            sto(one, two)
            sto(two, three)

        tl.addWidget(self.swap_title_author_button, 0, 0, 1, 1)
        tl.addWidget(self.manage_authors_button, 1, 0, 1, 1)

        create_row(0, self.title, self.deduce_title_sort_button, self.title_sort)
        sto(self.title_sort, self.authors)
        create_row(1, self.authors, self.deduce_author_sort_button, self.author_sort)
        sto(self.author_sort, self.series)
        create_row(2, self.series, self.clear_series_button,
                self.series_index, icon='trash.png')
        sto(self.series_index, self.swap_title_author_button)
        sto(self.swap_title_author_button, self.manage_authors_button)

        tl.addWidget(self.formats_manager, 0, 6, 3, 1)

        self.splitter = Splitter(Qt.Horizontal, self)
        self.splitter.addWidget(self.cover)
        self.splitter.frame_resized.connect(self.cover.frame_resized)
        l.addWidget(self.splitter)
        self.tabs[0].gb = gb = QGroupBox(_('Change cover'), self)
        gb.l = l = QGridLayout()
        gb.setLayout(l)
        sto(self.manage_authors_button, self.cover.buttons[0])
        for i, b in enumerate(self.cover.buttons[:3]):
            l.addWidget(b, 0, i, 1, 1)
            sto(b, self.cover.buttons[i+1])
        gb.hl = QHBoxLayout()
        for b in self.cover.buttons[3:]:
            gb.hl.addWidget(b)
        sto(self.cover.buttons[-2], self.cover.buttons[-1])
        l.addLayout(gb.hl, 1, 0, 1, 3)
        self.tabs[0].middle = w = QWidget(self)
        w.l = l = QGridLayout()
        w.setLayout(w.l)
        self.splitter.addWidget(w)
        def create_row2(row, widget, button=None, front_button=None):
            row += 1
            ql = BuddyLabel(widget)
            if front_button:
                ltl = QHBoxLayout()
                ltl.addWidget(front_button)
                ltl.addWidget(ql)
                l.addLayout(ltl, row, 0, 1, 1)
            else:
                l.addWidget(ql, row, 0, 1, 1)
            l.addWidget(widget, row, 1, 1, 2 if button is None else 1)
            if button is not None:
                l.addWidget(button, row, 2, 1, 1)
            if button is not None:
                sto(widget, button)

        l.addWidget(gb, 0, 0, 1, 3)
        self.tabs[0].spc_one = QSpacerItem(10, 10, QSizePolicy.Expanding,
                QSizePolicy.Expanding)
        l.addItem(self.tabs[0].spc_one, 1, 0, 1, 3)
        sto(self.cover.buttons[-1], self.rating)
        create_row2(1, self.rating, self.clear_ratings_button)
        sto(self.rating, self.clear_ratings_button)
        sto(self.clear_ratings_button, self.tags_editor_button)
        sto(self.tags_editor_button, self.tags)
        create_row2(2, self.tags, self.clear_tags_button, front_button=self.tags_editor_button)
        sto(self.clear_tags_button, self.paste_isbn_button)
        sto(self.paste_isbn_button, self.identifiers)
        create_row2(3, self.identifiers, self.clear_identifiers_button,
                                        front_button=self.paste_isbn_button)
        sto(self.clear_identifiers_button, self.timestamp)
        create_row2(4, self.timestamp, self.timestamp.clear_button)
        sto(self.timestamp.clear_button, self.pubdate)
        create_row2(5, self.pubdate, self.pubdate.clear_button)
        sto(self.pubdate.clear_button, self.publisher)
        create_row2(6, self.publisher)
        sto(self.publisher, self.languages)
        create_row2(7, self.languages)
        self.tabs[0].spc_two = QSpacerItem(10, 10, QSizePolicy.Expanding,
                QSizePolicy.Expanding)
        l.addItem(self.tabs[0].spc_two, 9, 0, 1, 3)
        l.addWidget(self.fetch_metadata_button, 10, 0, 1, 2)
        l.addWidget(self.config_metadata_button, 10, 2, 1, 1)

        self.tabs[0].gb2 = gb = QGroupBox(_('Co&mments'), self)
        gb.l = l = QVBoxLayout()
        gb.setLayout(l)
        l.addWidget(self.comments)
        self.splitter.addWidget(gb)

        self.set_custom_metadata_tab_order()
Ejemplo n.º 13
0
    def __init__(self, ids, get_metadata, field_metadata, parent=None,
                 window_title=None,
                 reject_button_tooltip=None,
                 accept_all_tooltip=None,
                 reject_all_tooltip=None,
                 revert_tooltip=None,
                 intro_msg=None,
                 action_button=None,
                 **kwargs):
        QDialog.__init__(self, parent)
        self.l = l = QVBoxLayout()
        self.next_called = False
        self.setLayout(l)
        self.setWindowIcon(QIcon(I('auto_author_sort.png')))
        self.get_metadata = get_metadata
        self.ids = list(ids)
        self.total = len(self.ids)
        self.accepted = OrderedDict()
        self.rejected_ids = set()
        self.window_title = window_title or _('Compare metadata')

        if intro_msg:
            self.la = la = QLabel(intro_msg)
            la.setWordWrap(True)
            l.addWidget(la)

        self.compare_widget = CompareSingle(field_metadata, parent=parent, revert_tooltip=revert_tooltip, **kwargs)
        self.sa = sa = QScrollArea()
        l.addWidget(sa)
        sa.setWidget(self.compare_widget)
        sa.setWidgetResizable(True)

        self.bb = bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Cancel)
        bb.button(QDialogButtonBox.StandardButton.Cancel).setAutoDefault(False)
        bb.rejected.connect(self.reject)
        if self.total > 1:
            self.aarb = b = bb.addButton(_('&Accept all remaining'), QDialogButtonBox.ButtonRole.YesRole)
            b.setIcon(QIcon(I('ok.png'))), b.setAutoDefault(False)
            if accept_all_tooltip:
                b.setToolTip(accept_all_tooltip)
            b.clicked.connect(self.accept_all_remaining)
            self.rarb = b = bb.addButton(_('Re&ject all remaining'), QDialogButtonBox.ButtonRole.ActionRole)
            b.setIcon(QIcon(I('minus.png'))), b.setAutoDefault(False)
            if reject_all_tooltip:
                b.setToolTip(reject_all_tooltip)
            b.clicked.connect(self.reject_all_remaining)
            self.sb = b = bb.addButton(_('R&eject'), QDialogButtonBox.ButtonRole.ActionRole)
            connect_lambda(b.clicked, self, lambda self: self.next_item(False))
            b.setIcon(QIcon(I('minus.png'))), b.setAutoDefault(False)
            if reject_button_tooltip:
                b.setToolTip(reject_button_tooltip)
            self.next_action = ac = QAction(self)
            ac.setShortcut(QKeySequence(Qt.Modifier.ALT | Qt.Key.Key_Right))
            self.addAction(ac)
        if action_button is not None:
            self.acb = b = bb.addButton(action_button[0], QDialogButtonBox.ButtonRole.ActionRole)
            b.setIcon(QIcon(action_button[1]))
            self.action_button_action = action_button[2]
            b.clicked.connect(self.action_button_clicked)
        self.nb = b = bb.addButton(_('&Next') if self.total > 1 else _('&OK'), QDialogButtonBox.ButtonRole.ActionRole)
        if self.total > 1:
            b.setToolTip(_('Move to next [%s]') % self.next_action.shortcut().toString(QKeySequence.SequenceFormat.NativeText))
            self.next_action.triggered.connect(b.click)
        b.setIcon(QIcon(I('forward.png' if self.total > 1 else 'ok.png')))
        connect_lambda(b.clicked, self, lambda self: self.next_item(True))
        b.setDefault(True), b.setAutoDefault(True)
        self.bbh = h = QHBoxLayout()
        h.setContentsMargins(0, 0, 0, 0)
        l.addLayout(h)
        self.markq = m = QCheckBox(_('&Mark rejected books'))
        m.setChecked(gprefs['metadata_diff_mark_rejected'])
        connect_lambda(m.stateChanged[int], self, lambda self: gprefs.set('metadata_diff_mark_rejected', self.markq.isChecked()))
        m.setToolTip(_('Mark rejected books in the book list after this dialog is closed'))
        h.addWidget(m), h.addWidget(bb)

        self.next_item(True)

        desktop = QApplication.instance().desktop()
        geom = desktop.availableGeometry(parent or self)
        width = max(700, min(950, geom.width()-50))
        height = max(650, min(1000, geom.height()-100))
        self.resize(QSize(width, height))
        geom = gprefs.get('diff_dialog_geom', None)
        if geom is not None:
            QApplication.instance().safe_restore_geometry(self, geom)
        b.setFocus(Qt.FocusReason.OtherFocusReason)
        self.next_called = False
Ejemplo n.º 14
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, unicode_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()
Ejemplo n.º 15
0
    def __init__(self, parent=None, one_line_toolbar=False, toolbar_prefs_name=None):
        QWidget.__init__(self, parent)
        self.toolbar_prefs_name = toolbar_prefs_name or self.toolbar_prefs_name
        self.toolbar1 = QToolBar(self)
        self.toolbar2 = QToolBar(self)
        self.toolbar3 = QToolBar(self)
        for i in range(1, 4):
            t = getattr(self, 'toolbar%d'%i)
            t.setIconSize(QSize(18, 18))
        self.editor = EditorWidget(self)
        self.set_html = self.editor.set_html
        self.tabs = QTabWidget(self)
        self.tabs.setTabPosition(self.tabs.South)
        self.wyswyg = QWidget(self.tabs)
        self.code_edit = QPlainTextEdit(self.tabs)
        self.source_dirty = False
        self.wyswyg_dirty = True

        self._layout = QVBoxLayout(self)
        self.wyswyg.layout = l = QVBoxLayout(self.wyswyg)
        self.setLayout(self._layout)
        l.setContentsMargins(0, 0, 0, 0)
        if one_line_toolbar:
            tb = QHBoxLayout()
            l.addLayout(tb)
        else:
            tb = l
        tb.addWidget(self.toolbar1)
        tb.addWidget(self.toolbar2)
        tb.addWidget(self.toolbar3)
        l.addWidget(self.editor)
        self._layout.addWidget(self.tabs)
        self.tabs.addTab(self.wyswyg, _('N&ormal view'))
        self.tabs.addTab(self.code_edit, _('&HTML Source'))
        self.tabs.currentChanged[int].connect(self.change_tab)
        self.highlighter = Highlighter(self.code_edit.document())
        self.layout().setContentsMargins(0, 0, 0, 0)
        if self.toolbar_prefs_name is not None:
            hidden = gprefs.get(self.toolbar_prefs_name)
            if hidden:
                self.hide_toolbars()

        # toolbar1 {{{
        self.toolbar1.addAction(self.editor.action_undo)
        self.toolbar1.addAction(self.editor.action_redo)
        self.toolbar1.addAction(self.editor.action_select_all)
        self.toolbar1.addAction(self.editor.action_remove_format)
        self.toolbar1.addAction(self.editor.action_clear)
        self.toolbar1.addSeparator()

        for x in ('copy', 'cut', 'paste'):
            ac = getattr(self.editor, 'action_'+x)
            self.toolbar1.addAction(ac)

        self.toolbar1.addSeparator()
        self.toolbar1.addAction(self.editor.action_background)
        # }}}

        # toolbar2 {{{
        for x in ('', 'un'):
            ac = getattr(self.editor, 'action_%sordered_list'%x)
            self.toolbar2.addAction(ac)
        self.toolbar2.addSeparator()
        for x in ('superscript', 'subscript', 'indent', 'outdent'):
            self.toolbar2.addAction(getattr(self.editor, 'action_' + x))
            if x in ('subscript', 'outdent'):
                self.toolbar2.addSeparator()

        self.toolbar2.addAction(self.editor.action_block_style)
        w = self.toolbar2.widgetForAction(self.editor.action_block_style)
        w.setPopupMode(w.InstantPopup)
        self.toolbar2.addAction(self.editor.action_insert_link)
        # }}}

        # toolbar3 {{{
        for x in ('bold', 'italic', 'underline', 'strikethrough'):
            ac = getattr(self.editor, 'action_'+x)
            self.toolbar3.addAction(ac)
        self.toolbar3.addSeparator()

        for x in ('left', 'center', 'right', 'justified'):
            ac = getattr(self.editor, 'action_align_'+x)
            self.toolbar3.addAction(ac)
        self.toolbar3.addSeparator()
        self.toolbar3.addAction(self.editor.action_color)
        # }}}

        self.code_edit.textChanged.connect(self.code_dirtied)
        self.editor.page().contentsChanged.connect(self.wyswyg_dirtied)
Ejemplo n.º 16
0
    def init_widget(self):
        """        현재 위젯의 모양등을 초기화        """

        tableWidget = QTableWidget()

        self.setWindowTitle("QComboBox Widget")
        self.resize(1024, 768)  # 크기

        layout_base = QBoxLayout(QBoxLayout.TopToBottom, self)
        self.setLayout(layout_base)

        # 첫 번째 그룹 QBoxLayout
        search = QGroupBox("검색")
        search.setFixedHeight(250)
        layout_base.addWidget(search)

        vlayout = QVBoxLayout()  #버티컬 레이아웃

        layout1 = QHBoxLayout()
        lb1 = QLabel('장르 : ')
        lb1.setFixedSize(QSize(80, 30))
        layout1.addWidget(lb1)
        qb1 = QComboBox()

        qb1.addItem('전체', '%')
        gg = self.getCombo('genre')
        for g in gg:
            qb1.addItem(g[0], g[1])

        qb1.setFixedSize(QSize(150, 30))
        layout1.addWidget(qb1)
        layout1.addStretch(1)
        vlayout.addLayout(layout1)

        layout2 = QHBoxLayout()
        lb2 = QLabel('직업 : ')
        lb2.setFixedSize(QSize(80, 30))
        layout2.addWidget(lb2)
        qb2 = QComboBox()

        jj = self.getCombo('job')
        qb2.addItem('전체', '%')
        for j in jj:
            qb2.addItem(j[0], j[1])

        qb2.setFixedSize(QSize(150, 30))
        layout2.addWidget(qb2)
        layout2.addStretch(1)
        vlayout.addLayout(layout2)

        layout3 = QHBoxLayout()
        lb3 = QLabel('평점 : ')
        lb3.setFixedSize(QSize(80, 30))
        layout3.addWidget(lb3)

        lb3_1 = QLabel('Min')
        lb3_1.setFixedSize(QSize(80, 30))
        layout3.addWidget(lb3_1)

        ql3_1 = QLineEdit()
        ql3_1.setText('0')
        ql3_1.setFixedSize(QSize(150, 30))
        layout3.addWidget(ql3_1)

        lb3_2 = QLabel('Max')
        lb3_2.setFixedSize(QSize(80, 30))
        layout3.addWidget(lb3_2)

        ql3_2 = QLineEdit()
        ql3_2.setFixedSize(QSize(150, 30))
        ql3_2.setText('10')
        layout3.addWidget(ql3_2)

        layout3.addStretch(1)
        vlayout.addLayout(layout3)

        layout4 = QHBoxLayout()
        lb4 = QLabel('Sort by ')
        lb4.setFixedSize(QSize(80, 30))
        layout4.addWidget(lb4)
        qb4 = QComboBox()
        l4 = [['제목', 'a.movietitle'], ['개봉일', 'a.releasedate'],
              ['vod출시일', 'a.videoreleasedate'], ['Url', 'a.IMDBURL'],
              ['장르', 'b.genre_nm'], ['평점', 'c.rating'], ['성별', 'd.gender'],
              ['직업', 'd.occupation']]
        for l in l4:
            qb4.addItem(l[0], l[1])

        qb4.setFixedSize(QSize(150, 30))
        layout4.addWidget(qb4)
        layout4.addStretch(1)
        vlayout.addLayout(layout4)

        def abc():
            print('aaa')
            tableWidget.clear()
            tableWidget.setRowCount(1)
            tableWidget.setHorizontalHeaderLabels(
                ["제목", "개봉일", "vod출시일", "Url", "장르", "평점", "나이", "성별", "직업"])
            v1i = qb1.currentIndex()
            v1t = qb1.itemText(v1i)
            v1d = qb1.itemData(v1i)

            v2i = qb2.currentIndex()
            v2t = qb2.itemText(v2i)
            v2d = qb2.itemData(v2i)

            v31 = ql3_1.text()
            v32 = ql3_2.text()

            v4i = qb4.currentIndex()
            v4t = qb4.itemText(v4i)
            v4d = qb4.itemData(v4i)

            result = self.dbSelect(v1d, v2d, v31, v32, v4d)
            tableWidget.setRowCount(result.__len__())
            tableWidget.setColumnCount(9)
            tableWidget.setHorizontalHeaderLabels(
                ["제목", "개봉일", "vod출시일", "Url", "장르", "평점", "나이", "성별", "직업"])
            row_cnt = 0
            for r in result:
                tableWidget.setItem(row_cnt, 0, QTableWidgetItem(r[0]))
                tableWidget.setItem(row_cnt, 1, QTableWidgetItem(r[1]))
                tableWidget.setItem(row_cnt, 2, QTableWidgetItem(r[2]))
                tableWidget.setItem(row_cnt, 3, QTableWidgetItem(r[3]))
                tableWidget.setItem(row_cnt, 4, QTableWidgetItem(r[4]))
                tableWidget.setItem(row_cnt, 5, QTableWidgetItem(r[5]))
                tableWidget.setItem(row_cnt, 6, QTableWidgetItem(r[6]))
                tableWidget.setItem(row_cnt, 7, QTableWidgetItem(r[7]))
                tableWidget.setItem(row_cnt, 8, QTableWidgetItem(r[8]))
                row_cnt = row_cnt + 1

        layout5 = QHBoxLayout()
        btn5 = QPushButton("검색", self)
        btn5.clicked.connect(abc)

        btn5.setFixedSize(QSize(565, 30))
        layout5.addWidget(btn5)
        layout5.addStretch(1)
        vlayout.addLayout(layout5)

        search.setLayout(vlayout)

        list = QGroupBox("Search Movie")
        layout_base.addWidget(list)
        layout = QHBoxLayout()

        result = self.dbSelect('%', '%', '0', '10', 'a.movietitle')

        # Create table

        #a.movietitle  , a.releasedate , a.videoreleasedate , a.IMDBURL , b.genre_nm , c.rating , d.age , d.gender , d.occupation
        tableWidget.setRowCount(result.__len__())
        tableWidget.setColumnCount(9)
        tableWidget.setHorizontalHeaderLabels(
            ["제목", "개봉일", "vod출시일", "Url", "장르", "평점", "나이", "성별", "직업"])
        row_cnt = 0
        for r in result:
            tableWidget.setItem(row_cnt, 0, QTableWidgetItem(r[0]))
            tableWidget.setItem(row_cnt, 1, QTableWidgetItem(r[1]))
            tableWidget.setItem(row_cnt, 2, QTableWidgetItem(r[2]))
            tableWidget.setItem(row_cnt, 3, QTableWidgetItem(r[3]))
            tableWidget.setItem(row_cnt, 4, QTableWidgetItem(r[4]))
            tableWidget.setItem(row_cnt, 5, QTableWidgetItem(r[5]))
            tableWidget.setItem(row_cnt, 6, QTableWidgetItem(r[6]))
            tableWidget.setItem(row_cnt, 7, QTableWidgetItem(r[7]))
            tableWidget.setItem(row_cnt, 8, QTableWidgetItem(r[8]))
            row_cnt = row_cnt + 1

        layout.addWidget(tableWidget)

        list.setLayout(layout)
Ejemplo n.º 17
0
    def __init__(self, parent):
        QWidget.__init__(self, parent)
        self.l = l = QFormLayout(self)
        l.setFieldGrowthPolicy(l.ExpandingFieldsGrow)

        self.hm = hm = QLabel(_(
            'Create a basic news recipe, by adding RSS feeds to it.\n'
            'For some news sources, you will have to use the "Switch to advanced mode" '
            'button below to further customize the fetch process.'))
        hm.setWordWrap(True)
        l.addRow(hm)

        self.title = t = QLineEdit(self)
        l.addRow(_('Recipe &title:'), t)
        t.setStyleSheet('QLineEdit { font-weight: bold }')

        self.oldest_article = o = QSpinBox(self)
        o.setSuffix(' ' + _('day(s)'))
        o.setToolTip(_("The oldest article to download"))
        o.setMinimum(1), o.setMaximum(36500)
        l.addRow(_('&Oldest article:'), o)

        self.max_articles = m = QSpinBox(self)
        m.setMinimum(5), m.setMaximum(100)
        m.setToolTip(_("Maximum number of articles to download per feed."))
        l.addRow(_("&Max. number of articles per feed:"), m)

        self.fg = fg = QGroupBox(self)
        fg.setTitle(_("Feeds in recipe"))
        self.feeds = f = QListWidget(self)
        fg.h = QHBoxLayout(fg)
        fg.h.addWidget(f)
        fg.l = QVBoxLayout()
        self.up_button = b = QToolButton(self)
        b.setIcon(QIcon(I('arrow-up.png')))
        b.setToolTip(_('Move selected feed up'))
        fg.l.addWidget(b)
        b.clicked.connect(self.move_up)
        self.remove_button = b = QToolButton(self)
        b.setIcon(QIcon(I('list_remove.png')))
        b.setToolTip(_('Remove selected feed'))
        fg.l.addWidget(b)
        b.clicked.connect(self.remove_feed)
        self.down_button = b = QToolButton(self)
        b.setIcon(QIcon(I('arrow-down.png')))
        b.setToolTip(_('Move selected feed down'))
        fg.l.addWidget(b)
        b.clicked.connect(self.move_down)
        fg.h.addLayout(fg.l)
        l.addRow(fg)

        self.afg = afg = QGroupBox(self)
        afg.setTitle(_('Add feed to recipe'))
        afg.l = QFormLayout(afg)
        afg.l.setFieldGrowthPolicy(l.ExpandingFieldsGrow)
        self.feed_title = ft = QLineEdit(self)
        afg.l.addRow(_('&Feed title:'), ft)
        self.feed_url = fu = QLineEdit(self)
        afg.l.addRow(_('Feed &URL:'), fu)
        self.afb = b = QPushButton(QIcon(I('plus.png')), _('&Add feed'), self)
        b.setToolTip(_('Add this feed to the recipe'))
        b.clicked.connect(self.add_feed)
        afg.l.addRow(b)
        l.addRow(afg)
Ejemplo n.º 18
0
    def update(self, sim_data_items, check_add_param=True):
        """Adds all elements in the iterable *sim_data_items* to the tree or
        replaces them if they are already present. Issues the *items_changed*
        signal, after all sim data items are added/replaced.

        :param sim_data_items: Iterable collection of :class: `SimDataItem`s to be added

        """
        additional_param_found = []
        all_log_configs = {}
        diff_dict = {}

        # build up a diff dict in order let the software handle multiple configuration parameters
        # in one simulation directory
        # some of the diffs should not be interpreted as parameters
        # those are removed from the dict; for sure QP, RealFormat, InternalFormat, and Warning
        # are not parameters
        # if you want to simulate with your own parameters, make sure that they appear in the
        # logfile
        try:
            for sim_data_item in sim_data_items:
                if sim_data_item.__class__ not in all_log_configs:
                    all_log_configs[sim_data_item.__class__] = []
                    diff_dict[sim_data_item.__class__] = {}
                all_log_configs[sim_data_item.__class__].append(
                    sim_data_item.log_config)
                # create list for all configuration parameters of the simulation_data_item
                # this configuration parameters will be displayed in the VariableTreeModel
                # If a qp parameter is available, we keep it as default in the List.
                # If the qp parameter is the only element in diff_dict or
                # if the user opens single files and not a directory,
                # no dialog window will be opened where you could add/remove all configuration parameters
                # that differ between the sim_data_items
                # TODO: enable multiple configuration parameters for the case that a specific file is opened
                chosen_par = QtWidgets.QListWidget()
                if hasattr(sim_data_item, 'qp'):
                    chosen_par.addItems(['QP'])
                # print(sim_data_item.summary_data['encoder_config'])
            value_filter = ['.yuv', '.bin', '.hevc', '.jem']
            key_filter = []
            for sim_class in all_log_configs.keys():
                for i in range(len(all_log_configs[sim_class]) - 1):
                    current_item, next_item = all_log_configs[sim_class][
                        i], all_log_configs[sim_class][i + 1]
                    for (key, value) in set(current_item.items()) ^ set(
                            next_item.items()):
                        if all(y not in key for y in key_filter):
                            if all(x not in value for x in value_filter):
                                if key not in diff_dict[sim_class]:
                                    diff_dict[sim_class][key] = []
                                    diff_dict[sim_class][key].append(value)
                                else:
                                    if value not in diff_dict[sim_class][key]:
                                        diff_dict[sim_class][key].append(value)

                # dialog window which displays all parameters with varying values in a list
                # the user can drag the parameters, he wants to analyse further into an other list
                # the order of the parameters in the list determines the order of the parameter tree
                if diff_dict[sim_class]:
                    chosen_par.setDragDropMode(QAbstractItemView.DragDrop)
                    chosen_par.setDefaultDropAction(QtCore.Qt.MoveAction)
                    not_chosen_par = QtWidgets.QListWidget()
                    not_chosen_par.addItems([
                        item for item in diff_dict[sim_class] if item != 'QP'
                    ])
                    not_chosen_par.setDragDropMode(QAbstractItemView.DragDrop)
                    not_chosen_par.setDefaultDropAction(QtCore.Qt.MoveAction)
                    if not_chosen_par:
                        # we do not want to create the dialog when testing the code. since the dialog will never be closed
                        # todo: code should not know about test. make dialog available from the outside, let test close it
                        if 'RUNNING_AS_UNITTEST' not in environ:
                            main_layout = QVBoxLayout()
                            dialog = QDialog()
                            dialog.setWindowTitle('Choose Parameters')
                            dialog.setLayout(main_layout)
                            msg = QtWidgets.QLabel()
                            msg.setText(
                                'Additional Parameters have been found.\n'
                                'Move Parameters you want to consider further to the right list.\n'
                            )
                            main_layout.addWidget(msg)
                            list_layout = QHBoxLayout()
                            main_layout.addLayout(list_layout)
                            # TODO: all items dragged into chosen_par should appear above the qp_item
                            list_layout.addWidget(not_chosen_par)
                            list_layout.addWidget(chosen_par)
                            not_chosen_par.show()
                            chosen_par.show()
                            ok_button = QPushButton('OK')
                            main_layout.addWidget(ok_button)
                            ok_button.clicked.connect(dialog.close)
                            dialog.exec()
                    for i in range(len(not_chosen_par)):
                        diff_dict[sim_class].pop(
                            not_chosen_par.item(i).text(), None)
                additional_param_found.append(sim_class)

        except AttributeError:
            # maybe do something useful here
            # This is for conformance with rd data written out by older versions of rdplot
            pass

        for sim_data_item in sim_data_items:

            has_additional_params = False
            if sim_data_item.__class__ in additional_param_found:
                sim_data_item.additional_params = [
                    chosen_par.item(i).text() for i in range(len(chosen_par))
                ]
                has_additional_params = True

            # Get *item* of the tree corresponding to *sim_data_item*
            item = self.create_path(*sim_data_item.tree_identifier_list)

            # This prevents an sim data item overwriting another one
            # with same *tree_identifier_list* but different absolute path
            for value in item.values:
                condition = (value.tree_identifier_list
                             == sim_data_item.tree_identifier_list
                             and value.path != sim_data_item.path
                             and not has_additional_params and check_add_param)
                if condition:
                    raise AmbiguousSimDataItems(
                        ("Ambiguous sim data items: Sim Data Item {} and {}"
                         " have different absolute paths but the same"
                         " position at the tree {}").format(
                             sim_data_item, value,
                             AbstractEncLog.tree_identifier_list))
            # Add *sim_data_item* to the set of values of the tree item *item*
            item.values.add(sim_data_item)

        self.items_changed.emit()
Ejemplo n.º 19
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
            plugin = get_plugin(category, name)
            if plugin is not None:
                self.show_plugin(plugin)
        else:
            self.hide_plugin()
Ejemplo n.º 20
0
    def __init__(self,
                 open_at=None,
                 continue_reading=None,
                 force_reload=False,
                 calibre_book_data=None):
        MainWindow.__init__(self, None)
        self.annotations_saver = None
        self.calibre_book_data_for_first_book = calibre_book_data
        self.shutting_down = self.close_forced = self.shutdown_done = False
        self.force_reload = force_reload
        connect_lambda(self.book_preparation_started,
                       self,
                       lambda self: self.loading_overlay(
                           _('Preparing book for first read, please wait')),
                       type=Qt.QueuedConnection)
        self.maximized_at_last_fullscreen = False
        self.save_pos_timer = t = QTimer(self)
        t.setSingleShot(True), t.setInterval(3000), t.setTimerType(
            Qt.VeryCoarseTimer)
        connect_lambda(t.timeout, self,
                       lambda self: self.save_annotations(in_book_file=False))
        self.pending_open_at = open_at
        self.base_window_title = _('E-book viewer')
        self.setDockOptions(MainWindow.AnimatedDocks
                            | MainWindow.AllowTabbedDocks
                            | MainWindow.AllowNestedDocks)
        self.setWindowTitle(self.base_window_title)
        self.in_full_screen_mode = None
        self.image_popup = ImagePopup(self)
        self.actions_toolbar = at = ActionsToolBar(self)
        at.open_book_at_path.connect(self.ask_for_open)
        self.addToolBar(Qt.LeftToolBarArea, at)
        try:
            os.makedirs(annotations_dir)
        except EnvironmentError:
            pass
        self.current_book_data = {}
        self.book_prepared.connect(self.load_finished,
                                   type=Qt.QueuedConnection)
        self.dock_defs = dock_defs()

        def create_dock(title,
                        name,
                        area,
                        areas=Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea):
            ans = QDockWidget(title, self)
            ans.setObjectName(name)
            self.addDockWidget(area, ans)
            ans.setVisible(False)
            ans.visibilityChanged.connect(self.dock_visibility_changed)
            return ans

        for dock_def in itervalues(self.dock_defs):
            setattr(
                self, '{}_dock'.format(dock_def.name.partition('-')[0]),
                create_dock(dock_def.title, dock_def.name,
                            dock_def.initial_area, dock_def.allowed_areas))

        self.toc_container = w = QWidget(self)
        w.l = QVBoxLayout(w)
        self.toc = TOCView(w)
        self.toc.clicked[QModelIndex].connect(self.toc_clicked)
        self.toc.searched.connect(self.toc_searched)
        self.toc_search = TOCSearch(self.toc, parent=w)
        w.l.addWidget(self.toc), w.l.addWidget(
            self.toc_search), w.l.setContentsMargins(0, 0, 0, 0)
        self.toc_dock.setWidget(w)

        self.search_widget = w = SearchPanel(self)
        w.search_requested.connect(self.start_search)
        w.hide_search_panel.connect(self.search_dock.close)
        w.count_changed.connect(self.search_results_count_changed)
        w.goto_cfi.connect(self.goto_cfi)
        self.search_dock.setWidget(w)
        self.search_dock.visibilityChanged.connect(
            self.search_widget.visibility_changed)

        self.lookup_widget = w = Lookup(self)
        self.lookup_dock.visibilityChanged.connect(
            self.lookup_widget.visibility_changed)
        self.lookup_dock.setWidget(w)

        self.bookmarks_widget = w = BookmarkManager(self)
        connect_lambda(
            w.create_requested, self,
            lambda self: self.web_view.trigger_shortcut('new_bookmark'))
        w.edited.connect(self.bookmarks_edited)
        w.activated.connect(self.bookmark_activated)
        w.toggle_requested.connect(self.toggle_bookmarks)
        self.bookmarks_dock.setWidget(w)

        self.highlights_widget = w = HighlightsPanel(self)
        self.highlights_dock.setWidget(w)

        self.web_view = WebView(self)
        self.web_view.cfi_changed.connect(self.cfi_changed)
        self.web_view.reload_book.connect(self.reload_book)
        self.web_view.toggle_toc.connect(self.toggle_toc)
        self.web_view.show_search.connect(self.show_search)
        self.web_view.find_next.connect(self.search_widget.find_next_requested)
        self.search_widget.show_search_result.connect(
            self.web_view.show_search_result)
        self.web_view.search_result_not_found.connect(
            self.search_widget.search_result_not_found)
        self.web_view.toggle_bookmarks.connect(self.toggle_bookmarks)
        self.web_view.toggle_highlights.connect(self.toggle_highlights)
        self.web_view.new_bookmark.connect(
            self.bookmarks_widget.create_new_bookmark)
        self.web_view.toggle_inspector.connect(self.toggle_inspector)
        self.web_view.toggle_lookup.connect(self.toggle_lookup)
        self.web_view.quit.connect(self.quit)
        self.web_view.update_current_toc_nodes.connect(
            self.toc.update_current_toc_nodes)
        self.web_view.toggle_full_screen.connect(self.toggle_full_screen)
        self.web_view.ask_for_open.connect(self.ask_for_open,
                                           type=Qt.QueuedConnection)
        self.web_view.selection_changed.connect(
            self.lookup_widget.selected_text_changed, type=Qt.QueuedConnection)
        self.web_view.selection_changed.connect(
            self.highlights_widget.selected_text_changed,
            type=Qt.QueuedConnection)
        self.web_view.view_image.connect(self.view_image,
                                         type=Qt.QueuedConnection)
        self.web_view.copy_image.connect(self.copy_image,
                                         type=Qt.QueuedConnection)
        self.web_view.show_loading_message.connect(self.show_loading_message)
        self.web_view.show_error.connect(self.show_error)
        self.web_view.print_book.connect(self.print_book,
                                         type=Qt.QueuedConnection)
        self.web_view.reset_interface.connect(self.reset_interface,
                                              type=Qt.QueuedConnection)
        self.web_view.quit.connect(self.quit, type=Qt.QueuedConnection)
        self.web_view.shortcuts_changed.connect(self.shortcuts_changed)
        self.web_view.scrollbar_context_menu.connect(
            self.scrollbar_context_menu)
        self.web_view.close_prep_finished.connect(self.close_prep_finished)
        self.web_view.highlights_changed.connect(self.highlights_changed)
        self.actions_toolbar.initialize(self.web_view,
                                        self.search_dock.toggleViewAction())
        self.setCentralWidget(self.web_view)
        self.loading_overlay = LoadingOverlay(self)
        self.restore_state()
        self.actions_toolbar.update_visibility()
        self.dock_visibility_changed()
        self.highlights_widget.request_highlight_action.connect(
            self.web_view.highlight_action)
        self.highlights_widget.web_action.connect(self.web_view.generic_action)
        if continue_reading:
            self.continue_reading()
        self.setup_mouse_auto_hide()
Ejemplo n.º 21
0
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.l = l = QVBoxLayout(self)
        self.la = la = QLabel(
            _(
                'calibre contains an internet server that allows you to'
                ' access your book collection using a browser from anywhere'
                ' in the world. Any changes to the settings will only take'
                ' effect after a server restart.'
            )
        )
        la.setWordWrap(True)
        l.addWidget(la)
        l.addSpacing(10)
        self.fl = fl = QFormLayout()
        l.addLayout(fl)
        self.opt_port = sb = QSpinBox(self)
        if options['port'].longdoc:
            sb.setToolTip(options['port'].longdoc)
        sb.setRange(1, 65535)
        sb.valueChanged.connect(self.changed_signal.emit)
        fl.addRow(options['port'].shortdoc + ':', sb)
        l.addSpacing(25)
        self.opt_auth = cb = QCheckBox(
            _('Require &username and password to access the content server')
        )
        l.addWidget(cb)
        self.auth_desc = la = QLabel(self)
        la.setStyleSheet('QLabel { font-size: small; font-style: italic }')
        la.setWordWrap(True)
        l.addWidget(la)
        l.addSpacing(25)
        self.opt_autolaunch_server = al = QCheckBox(
            _('Run server &automatically when calibre starts')
        )
        l.addWidget(al)
        l.addSpacing(25)
        self.h = h = QHBoxLayout()
        l.addLayout(h)
        for text, name in [(_('&Start server'),
                            'start_server'), (_('St&op server'), 'stop_server'),
                           (_('&Test server'),
                            'test_server'), (_('Show server &logs'), 'show_logs')]:
            b = QPushButton(text)
            b.clicked.connect(getattr(self, name).emit)
            setattr(self, name + '_button', b)
            if name == 'show_logs':
                h.addStretch(10)
            h.addWidget(b)
        self.ip_info = QLabel(self)
        self.update_ip_info()
        from calibre.gui2.ui import get_gui
        gui = get_gui()
        if gui is not None:
            gui.iactions['Connect Share'].share_conn_menu.server_state_changed_signal.connect(self.update_ip_info)
        l.addSpacing(10)
        l.addWidget(self.ip_info)
        if set_run_at_startup is not None:
            self.run_at_start_button = b = QPushButton('', self)
            self.set_run_at_start_text()
            b.clicked.connect(self.toggle_run_at_startup)
            l.addSpacing(10)
            l.addWidget(b)
        l.addSpacing(10)

        l.addStretch(10)
Ejemplo n.º 22
0
    def request_trezor_init_settings(self, wizard, method, model):
        vbox = QVBoxLayout()
        next_enabled = True
        label = QLabel(_("Enter a label to name your device:"))
        name = QLineEdit()
        hl = QHBoxLayout()
        hl.addWidget(label)
        hl.addWidget(name)
        hl.addStretch(1)
        vbox.addLayout(hl)

        def clean_text(widget):
            text = widget.toPlainText().strip()
            return ' '.join(text.split())

        if method in [TIM_NEW, TIM_RECOVER]:
            gb = QGroupBox()
            hbox1 = QHBoxLayout()
            gb.setLayout(hbox1)
            vbox.addWidget(gb)
            gb.setTitle(_("Select your seed length:"))
            bg_numwords = QButtonGroup()
            for i, count in enumerate([12, 18, 24]):
                rb = QRadioButton(gb)
                rb.setText(_("%d words") % count)
                bg_numwords.addButton(rb)
                bg_numwords.setId(rb, i)
                hbox1.addWidget(rb)
                rb.setChecked(True)
            cb_pin = QCheckBox(_('Enable PIN protection'))
            cb_pin.setChecked(True)
        else:
            text = QTextEdit()
            text.setMaximumHeight(60)
            if method == TIM_MNEMONIC:
                msg = _("Enter your BIP39 mnemonic:")
            else:
                msg = _("Enter the master private key beginning with xprv:")

                def set_enabled():
                    from qtum_electrum.keystore import is_xprv
                    wizard.next_button.setEnabled(is_xprv(clean_text(text)))

                text.textChanged.connect(set_enabled)
                next_enabled = False

            vbox.addWidget(QLabel(msg))
            vbox.addWidget(text)
            pin = QLineEdit()
            pin.setValidator(QRegExpValidator(QRegExp('[1-9]{0,9}')))
            pin.setMaximumWidth(100)
            hbox_pin = QHBoxLayout()
            hbox_pin.addWidget(QLabel(_("Enter your PIN (digits 1-9):")))
            hbox_pin.addWidget(pin)
            hbox_pin.addStretch(1)

        if method in [TIM_NEW, TIM_RECOVER]:
            vbox.addWidget(WWLabel(RECOMMEND_PIN))
            vbox.addWidget(cb_pin)
        else:
            vbox.addLayout(hbox_pin)

        passphrase_msg = WWLabel(PASSPHRASE_HELP_SHORT)
        passphrase_warning = WWLabel(PASSPHRASE_NOT_PIN)
        passphrase_warning.setStyleSheet("color: red")
        cb_phrase = QCheckBox(_('Enable passphrases'))
        cb_phrase.setChecked(False)
        vbox.addWidget(passphrase_msg)
        vbox.addWidget(passphrase_warning)
        vbox.addWidget(cb_phrase)

        # ask for recovery type (random word order OR matrix)
        if method == TIM_RECOVER and not model == 'T':
            gb_rectype = QGroupBox()
            hbox_rectype = QHBoxLayout()
            gb_rectype.setLayout(hbox_rectype)
            vbox.addWidget(gb_rectype)
            gb_rectype.setTitle(_("Select recovery type:"))
            bg_rectype = QButtonGroup()

            rb1 = QRadioButton(gb_rectype)
            rb1.setText(_('Scrambled words'))
            bg_rectype.addButton(rb1)
            bg_rectype.setId(rb1, RECOVERY_TYPE_SCRAMBLED_WORDS)
            hbox_rectype.addWidget(rb1)
            rb1.setChecked(True)

            rb2 = QRadioButton(gb_rectype)
            rb2.setText(_('Matrix'))
            bg_rectype.addButton(rb2)
            bg_rectype.setId(rb2, RECOVERY_TYPE_MATRIX)
            hbox_rectype.addWidget(rb2)
        else:
            bg_rectype = None

        wizard.exec_layout(vbox, next_enabled=next_enabled)

        if method in [TIM_NEW, TIM_RECOVER]:
            item = bg_numwords.checkedId()
            pin = cb_pin.isChecked()
            recovery_type = bg_rectype.checkedId() if bg_rectype else None
        else:
            item = ' '.join(str(clean_text(text)).split())
            pin = str(pin.text())
            recovery_type = None

        return item, name.text(), pin, cb_phrase.isChecked(), recovery_type
Ejemplo n.º 23
0
    def __init__(self, debug_javascript):
        MainWindow.__init__(self, None)
        self.setWindowTitle(_('E-book viewer'))
        self.base_window_title = unicode(self.windowTitle())
        self.setObjectName('EbookViewer')
        self.setWindowIcon(QIcon(I('viewer.png')))
        self.setDockOptions(self.AnimatedDocks | self.AllowTabbedDocks)

        self.centralwidget = c = QWidget(self)
        c.setObjectName('centralwidget')
        self.setCentralWidget(c)
        self.central_layout = cl = QGridLayout(c)
        cl.setSpacing(0)
        c.setLayout(cl), cl.setContentsMargins(0, 0, 0, 0)

        self.view = v = DocumentView(self)
        v.setMinimumSize(100, 100)
        self.view.initialize_view(debug_javascript)
        v.setObjectName('view')
        cl.addWidget(v)

        self.vertical_scrollbar = vs = QScrollBar(c)
        vs.setOrientation(Qt.Vertical), vs.setObjectName("vertical_scrollbar")
        cl.addWidget(vs, 0, 1, 2, 1)

        self.horizontal_scrollbar = hs = QScrollBar(c)
        hs.setOrientation(Qt.Horizontal), hs.setObjectName("horizontal_scrollbar")
        cl.addWidget(hs, 1, 0, 1, 1)

        self.tool_bar = tb = ToolBar(self)
        tb.setObjectName('tool_bar'), tb.setIconSize(QSize(32, 32))
        self.addToolBar(Qt.LeftToolBarArea, tb)

        self.tool_bar2 = tb2 = QToolBar(self)
        tb2.setObjectName('tool_bar2')
        self.addToolBar(Qt.TopToolBarArea, tb2)
        self.tool_bar.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.tool_bar2.setContextMenuPolicy(Qt.PreventContextMenu)

        self.pos = DoubleSpinBox()
        self.pos.setDecimals(1)
        self.pos.setSuffix('/'+_('Unknown')+'     ')
        self.pos.setMinimum(1.)
        self.tool_bar2.addWidget(self.pos)
        self.tool_bar2.addSeparator()
        self.reference = Reference()
        self.tool_bar2.addWidget(self.reference)
        self.tool_bar2.addSeparator()
        self.search = SearchBox2(self)
        self.search.setMinimumContentsLength(20)
        self.search.initialize('viewer_search_history')
        self.search.setToolTip(_('Search for text in book'))
        self.search.setMinimumWidth(200)
        self.tool_bar2.addWidget(self.search)

        self.toc_dock = d = QDockWidget(_('Table of Contents'), self)
        d.setContextMenuPolicy(Qt.CustomContextMenu)
        self.toc_container = w = QWidget(self)
        w.l = QVBoxLayout(w)
        self.toc = TOCView(w)
        self.toc_search = TOCSearch(self.toc, parent=w)
        w.l.addWidget(self.toc), w.l.addWidget(self.toc_search), w.l.setContentsMargins(0, 0, 0, 0)
        d.setObjectName('toc-dock')
        d.setWidget(w)
        d.close()  # starts out hidden
        self.addDockWidget(Qt.LeftDockWidgetArea, d)
        d.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)

        self.bookmarks_dock = d = QDockWidget(_('Bookmarks'), self)
        d.setContextMenuPolicy(Qt.CustomContextMenu)
        self.bookmarks = BookmarkManager(self)
        d.setObjectName('bookmarks-dock')
        d.setWidget(self.bookmarks)
        d.close()  # starts out hidden
        self.addDockWidget(Qt.RightDockWidgetArea, d)
        d.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)

        self.footnotes_dock = d = QDockWidget(_('Footnotes'), self)
        d.visibilityChanged.connect(self.footnote_visibility_changed)
        d.setContextMenuPolicy(Qt.CustomContextMenu)
        self.footnotes_view = FootnotesView(self)
        self.footnotes_view.follow_link.connect(self.view.follow_footnote_link)
        self.footnotes_view.close_view.connect(d.close)
        self.view.footnotes.set_footnotes_view(self.footnotes_view)
        d.setObjectName('footnotes-dock')
        d.setWidget(self.footnotes_view)
        d.close()  # starts out hidden
        self.addDockWidget(Qt.BottomDockWidgetArea, d)
        d.setAllowedAreas(Qt.BottomDockWidgetArea | Qt.TopDockWidgetArea | Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)

        self.create_actions()

        self.metadata = Metadata(self.centralwidget)
        self.history = History(self.action_back, self.action_forward)

        self.full_screen_label = QLabel('''
                <center>
                <h1>%s</h1>
                <h3>%s</h3>
                <h3>%s</h3>
                <h3>%s</h3>
                </center>
                '''%(_('Full screen mode'),
                    _('Right click to show controls'),
                    _('Tap in the left or right page margin to turn pages'),
                    _('Press Esc to quit')),
                    self.centralWidget())
        self.full_screen_label.setVisible(False)
        self.full_screen_label.final_height = 200
        self.full_screen_label.setFocusPolicy(Qt.NoFocus)
        self.full_screen_label.setStyleSheet('''
        QLabel {
            text-align: center;
            background-color: white;
            color: black;
            border-width: 1px;
            border-style: solid;
            border-radius: 20px;
        }
        ''')
        self.clock_label = QLabel('99:99', self.centralWidget())
        self.clock_label.setVisible(False)
        self.clock_label.setFocusPolicy(Qt.NoFocus)
        self.info_label_style = '''
            QLabel {
                text-align: center;
                border-width: 1px;
                border-style: solid;
                border-radius: 8px;
                background-color: %s;
                color: %s;
                font-family: monospace;
                font-size: larger;
                padding: 5px;
        }'''
        self.pos_label = QLabel('2000/4000', self.centralWidget())
        self.pos_label.setVisible(False)
        self.pos_label.setFocusPolicy(Qt.NoFocus)

        self.resize(653, 746)
Ejemplo n.º 24
0
 def __init__(self, handler, data):
     '''Ask user for 2nd factor authentication. Support text, security card and paired mobile methods.
     Use last method from settings, but support new pairing and downgrade.
     '''
     QDialog.__init__(self, handler.top_level_window())
     self.handler = handler
     self.txdata = data
     self.idxs = self.txdata['keycardData'] if self.txdata['confirmationType'] > 1 else ''
     self.setMinimumWidth(650)
     self.setWindowTitle(_("Ledger Wallet Authentication"))
     self.cfg = copy.deepcopy(self.handler.win.wallet.get_keystore().cfg)
     self.dongle = self.handler.win.wallet.get_keystore().get_client().dongle
     self.ws = None
     self.pin = ''
     
     self.devmode = self.getDevice2FAMode()
     if self.devmode == 0x11 or self.txdata['confirmationType'] == 1:
         self.cfg['mode'] = 0
     
     vbox = QVBoxLayout()
     self.setLayout(vbox)
     
     def on_change_mode(idx):
         if idx < 2 and self.ws:
             self.ws.stop()
             self.ws = None
         self.cfg['mode'] = 0 if self.devmode == 0x11 else idx if idx > 0 else 1
         if self.cfg['mode'] > 1 and self.cfg['pair'] and not self.ws:
             self.req_validation()
         if self.cfg['mode'] > 0:
             self.handler.win.wallet.get_keystore().cfg = self.cfg
             self.handler.win.wallet.save_keystore()
         self.update_dlg()
     def add_pairing():
         self.do_pairing()
     def return_pin():
         self.pin = self.pintxt.text() if self.txdata['confirmationType'] == 1 else self.cardtxt.text() 
         if self.cfg['mode'] == 1:
             self.pin = ''.join(chr(int(str(i),16)) for i in self.pin)
         self.accept()
     
     self.modebox = QWidget()
     modelayout = QHBoxLayout()
     self.modebox.setLayout(modelayout)
     modelayout.addWidget(QLabel(_("Method:")))
     self.modes = QComboBox()
     modelayout.addWidget(self.modes, 2)
     self.addPair = QPushButton(_("Pair"))
     self.addPair.setMaximumWidth(60)
     modelayout.addWidget(self.addPair)
     modelayout.addStretch(1)
     self.modebox.setMaximumHeight(50)
     vbox.addWidget(self.modebox)
     
     self.populate_modes()
     self.modes.currentIndexChanged.connect(on_change_mode)
     self.addPair.clicked.connect(add_pairing)
     
     self.helpmsg = QTextEdit()
     self.helpmsg.setStyleSheet("QTextEdit { background-color: lightgray; }")
     self.helpmsg.setReadOnly(True)
     vbox.addWidget(self.helpmsg)
     
     self.pinbox = QWidget()
     pinlayout = QHBoxLayout()
     self.pinbox.setLayout(pinlayout)
     self.pintxt = QLineEdit()
     self.pintxt.setEchoMode(2)
     self.pintxt.setMaxLength(4)
     self.pintxt.returnPressed.connect(return_pin)
     pinlayout.addWidget(QLabel(_("Enter PIN:")))
     pinlayout.addWidget(self.pintxt)
     pinlayout.addWidget(QLabel(_("NOT DEVICE PIN - see above")))
     pinlayout.addStretch(1)
     self.pinbox.setVisible(self.cfg['mode'] == 0)
     vbox.addWidget(self.pinbox)
                 
     self.cardbox = QWidget()
     card = QVBoxLayout()
     self.cardbox.setLayout(card)
     self.addrtext = QTextEdit()
     self.addrtext.setStyleSheet("QTextEdit { color:blue; background-color:lightgray; padding:15px 10px; border:none; font-size:20pt; font-family:monospace; }")
     self.addrtext.setReadOnly(True)
     self.addrtext.setMaximumHeight(130)
     card.addWidget(self.addrtext)
     
     def pin_changed(s):
         if len(s) < len(self.idxs):
             i = self.idxs[len(s)]
             addr = self.txdata['address']
             if not constants.net.TESTNET:
                 text = addr[:i] + '<u><b>' + addr[i:i+1] + '</u></b>' + addr[i+1:]
             else:
                 # pin needs to be created from mainnet address
                 addr_mainnet = bitcoin.script_to_address(bitcoin.address_to_script(addr), net=constants.BitcoinMainnet)
                 addr_mainnet = addr_mainnet[:i] + '<u><b>' + addr_mainnet[i:i+1] + '</u></b>' + addr_mainnet[i+1:]
                 text = str(addr) + '\n' + str(addr_mainnet)
             self.addrtext.setHtml(str(text))
         else:
             self.addrtext.setHtml(_("Press Enter"))
             
     pin_changed('')    
     cardpin = QHBoxLayout()
     cardpin.addWidget(QLabel(_("Enter PIN:")))
     self.cardtxt = QLineEdit()
     self.cardtxt.setEchoMode(2)
     self.cardtxt.setMaxLength(len(self.idxs))
     self.cardtxt.textChanged.connect(pin_changed)
     self.cardtxt.returnPressed.connect(return_pin)
     cardpin.addWidget(self.cardtxt)
     cardpin.addWidget(QLabel(_("NOT DEVICE PIN - see above")))
     cardpin.addStretch(1)
     card.addLayout(cardpin)
     self.cardbox.setVisible(self.cfg['mode'] == 1)
     vbox.addWidget(self.cardbox)
     
     self.pairbox = QWidget()
     pairlayout = QVBoxLayout()
     self.pairbox.setLayout(pairlayout)
     pairhelp = QTextEdit(helpTxt[5])
     pairhelp.setStyleSheet("QTextEdit { background-color: lightgray; }")
     pairhelp.setReadOnly(True)
     pairlayout.addWidget(pairhelp, 1)
     self.pairqr = QRCodeWidget()
     pairlayout.addWidget(self.pairqr, 4)
     self.pairbox.setVisible(False)
     vbox.addWidget(self.pairbox)
     self.update_dlg()
     
     if self.cfg['mode'] > 1 and not self.ws:
         self.req_validation()
Ejemplo n.º 25
0
    def request_trezor_init_settings(self, wizard, method, device):
        vbox = QVBoxLayout()
        next_enabled = True
        label = QLabel(_("Enter a label to name your device:"))
        name = QLineEdit()
        hl = QHBoxLayout()
        hl.addWidget(label)
        hl.addWidget(name)
        hl.addStretch(1)
        vbox.addLayout(hl)

        def clean_text(widget):
            text = widget.toPlainText().strip()
            return ' '.join(text.split())

        if method in [TIM_NEW, TIM_RECOVER]:
            gb = QGroupBox()
            hbox1 = QHBoxLayout()
            gb.setLayout(hbox1)
            # KeepKey recovery doesn't need a word count
            if method == TIM_NEW or self.device == 'TREZOR':
                vbox.addWidget(gb)
            gb.setTitle(_("Select your seed length:"))
            bg = QButtonGroup()
            for i, count in enumerate([12, 18, 24]):
                rb = QRadioButton(gb)
                rb.setText(_("{} words").format(count))
                bg.addButton(rb)
                bg.setId(rb, i)
                hbox1.addWidget(rb)
                rb.setChecked(True)
            cb_pin = QCheckBox(_('Enable PIN protection'))
            cb_pin.setChecked(True)
        else:
            text = QTextEdit()
            text.setMaximumHeight(60)
            if method == TIM_MNEMONIC:
                msg = _("Enter your BIP39 mnemonic:")
            else:
                msg = _("Enter the master private key beginning with xprv:")

                def set_enabled():
                    from electrum.keystore import is_xprv
                    wizard.next_button.setEnabled(is_xprv(clean_text(text)))

                text.textChanged.connect(set_enabled)
                next_enabled = False

            vbox.addWidget(QLabel(msg))
            vbox.addWidget(text)
            pin = QLineEdit()
            pin.setValidator(QRegExpValidator(QRegExp('[1-9]{0,9}')))
            pin.setMaximumWidth(100)
            hbox_pin = QHBoxLayout()
            hbox_pin.addWidget(QLabel(_("Enter your PIN (digits 1-9):")))
            hbox_pin.addWidget(pin)
            hbox_pin.addStretch(1)

        if method in [TIM_NEW, TIM_RECOVER]:
            vbox.addWidget(WWLabel(RECOMMEND_PIN))
            vbox.addWidget(cb_pin)
        else:
            vbox.addLayout(hbox_pin)

        passphrase_msg = WWLabel(PASSPHRASE_HELP_SHORT)
        passphrase_warning = WWLabel(PASSPHRASE_NOT_PIN)
        passphrase_warning.setStyleSheet("color: red")
        cb_phrase = QCheckBox(_('Enable passphrases'))
        cb_phrase.setChecked(False)
        vbox.addWidget(passphrase_msg)
        vbox.addWidget(passphrase_warning)
        vbox.addWidget(cb_phrase)

        wizard.exec_layout(vbox, next_enabled=next_enabled)

        if method in [TIM_NEW, TIM_RECOVER]:
            item = bg.checkedId()
            pin = cb_pin.isChecked()
        else:
            item = ' '.join(str(clean_text(text)).split())
            pin = str(pin.text())

        return (item, name.text(), pin, cb_phrase.isChecked())
Ejemplo n.º 26
0
                    '<br>'+unicode_type(err), show=True)

            return False
# }}}


if __name__ == '__main__':
    from calibre.gui2 import Application
    from calibre.devices.kobo.driver import KOBOTOUCH
    from calibre.devices.scanner import DeviceScanner
    s = DeviceScanner()
    s.scan()
    app = Application([])
    debug_print("KOBOTOUCH:", KOBOTOUCH)
    dev = KOBOTOUCH(None)
#     dev.startup()
#     cd = dev.detect_managed_devices(s.devices)
#     dev.open(cd, 'test')
    cw = dev.config_widget()
    d = QDialog()
    d.l = QVBoxLayout()
    d.setLayout(d.l)
    d.l.addWidget(cw)
    bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok|QDialogButtonBox.StandardButton.Cancel)
    d.l.addWidget(bb)
    bb.accepted.connect(d.accept)
    bb.rejected.connect(d.reject)
    if d.exec_() == QDialog.DialogCode.Accepted:
        cw.commit()
    dev.shutdown()
Ejemplo n.º 27
0
    def __init__(self, parent, prefs):
        QFrame.__init__(self, parent)
        self.prefs = prefs
        self.setFrameShape(QFrame.StyledPanel)
        self.setMinimumWidth(250)
        self.stack = s = QStackedWidget(self)
        self.l = l = QVBoxLayout()
        self.setLayout(l)
        l.addWidget(s)
        self.root_pane = rp = QWidget(self)
        self.item_pane = ip = QWidget(self)
        self.current_item = None
        s.addWidget(rp)
        s.addWidget(ip)

        self.l1 = la = QLabel('<p>' + _(
            'You can edit existing entries in the Table of Contents by clicking them'
            ' in the panel to the left.'
        ) + '<p>' + _(
            'Entries with a green tick next to them point to a location that has '
            'been verified to exist. Entries with a red dot are broken and may need'
            ' to be fixed.'))
        la.setStyleSheet('QLabel { margin-bottom: 20px }')
        la.setWordWrap(True)
        l = rp.l = QVBoxLayout()
        rp.setLayout(l)
        l.addWidget(la)
        self.add_new_to_root_button = b = QPushButton(_('Create a &new entry'))
        b.clicked.connect(self.add_new_to_root)
        l.addWidget(b)
        l.addStretch()

        self.cfmhb = b = QPushButton(_('Generate ToC from &major headings'))
        b.clicked.connect(self.create_from_major_headings)
        b.setToolTip(
            textwrap.fill(
                _('Generate a Table of Contents from the major headings in the book.'
                  ' This will work if the book identifies its headings using HTML'
                  ' heading tags. Uses the <h1>, <h2> and <h3> tags.')))
        l.addWidget(b)
        self.cfmab = b = QPushButton(_('Generate ToC from &all headings'))
        b.clicked.connect(self.create_from_all_headings)
        b.setToolTip(
            textwrap.fill(
                _('Generate a Table of Contents from all the headings in the book.'
                  ' This will work if the book identifies its headings using HTML'
                  ' heading tags. Uses the <h1-6> tags.')))
        l.addWidget(b)

        self.lb = b = QPushButton(_('Generate ToC from &links'))
        b.clicked.connect(self.create_from_links)
        b.setToolTip(
            textwrap.fill(
                _('Generate a Table of Contents from all the links in the book.'
                  ' Links that point to destinations that do not exist in the book are'
                  ' ignored. Also multiple links with the same destination or the same'
                  ' text are ignored.')))
        l.addWidget(b)

        self.cfb = b = QPushButton(_('Generate ToC from &files'))
        b.clicked.connect(self.create_from_files)
        b.setToolTip(
            textwrap.fill(
                _('Generate a Table of Contents from individual files in the book.'
                  ' Each entry in the ToC will point to the start of the file, the'
                  ' text of the entry will be the "first line" of text from the file.'
                  )))
        l.addWidget(b)

        self.xpb = b = QPushButton(_('Generate ToC from &XPath'))
        b.clicked.connect(self.create_from_user_xpath)
        b.setToolTip(
            textwrap.fill(
                _('Generate a Table of Contents from arbitrary XPath expressions.'
                  )))
        l.addWidget(b)

        self.fal = b = QPushButton(_('&Flatten the ToC'))
        b.clicked.connect(self.flatten_toc)
        b.setToolTip(
            textwrap.fill(
                _('Flatten the Table of Contents, putting all entries at the top level'
                  )))
        l.addWidget(b)

        l.addStretch()
        self.w1 = la = QLabel(
            _('<b>WARNING:</b> calibre only supports the '
              'creation of linear ToCs in AZW3 files. In a '
              'linear ToC every entry must point to a '
              'location after the previous entry. If you '
              'create a non-linear ToC it will be '
              'automatically re-arranged inside the AZW3 file.'))
        la.setWordWrap(True)
        l.addWidget(la)

        l = ip.l = QGridLayout()
        ip.setLayout(l)
        la = ip.heading = QLabel('')
        l.addWidget(la, 0, 0, 1, 2)
        la.setWordWrap(True)
        la = ip.la = QLabel(
            _('You can move this entry around the Table of Contents by drag '
              'and drop or using the up and down buttons to the left'))
        la.setWordWrap(True)
        l.addWidget(la, 1, 0, 1, 2)

        # Item status
        ip.hl1 = hl = QFrame()
        hl.setFrameShape(hl.HLine)
        l.addWidget(hl, l.rowCount(), 0, 1, 2)
        self.icon_label = QLabel()
        self.status_label = QLabel()
        self.status_label.setWordWrap(True)
        l.addWidget(self.icon_label, l.rowCount(), 0)
        l.addWidget(self.status_label, l.rowCount() - 1, 1)
        ip.hl2 = hl = QFrame()
        hl.setFrameShape(hl.HLine)
        l.addWidget(hl, l.rowCount(), 0, 1, 2)

        # Edit/remove item
        rs = l.rowCount()
        ip.b1 = b = QPushButton(QIcon(I('edit_input.png')),
                                _('Change the &location this entry points to'),
                                self)
        b.clicked.connect(self.edit_item)
        l.addWidget(b, l.rowCount() + 1, 0, 1, 2)
        ip.b2 = b = QPushButton(QIcon(I('trash.png')), _('&Remove this entry'),
                                self)
        l.addWidget(b, l.rowCount(), 0, 1, 2)
        b.clicked.connect(self.delete_item)
        ip.hl3 = hl = QFrame()
        hl.setFrameShape(hl.HLine)
        l.addWidget(hl, l.rowCount(), 0, 1, 2)
        l.setRowMinimumHeight(rs, 20)

        # Add new item
        rs = l.rowCount()
        ip.b3 = b = QPushButton(QIcon(I('plus.png')),
                                _('New entry &inside this entry'))
        connect_lambda(b.clicked, self, lambda self: self.add_new('inside'))
        l.addWidget(b, l.rowCount() + 1, 0, 1, 2)
        ip.b4 = b = QPushButton(QIcon(I('plus.png')),
                                _('New entry &above this entry'))
        connect_lambda(b.clicked, self, lambda self: self.add_new('before'))
        l.addWidget(b, l.rowCount(), 0, 1, 2)
        ip.b5 = b = QPushButton(QIcon(I('plus.png')),
                                _('New entry &below this entry'))
        connect_lambda(b.clicked, self, lambda self: self.add_new('after'))
        l.addWidget(b, l.rowCount(), 0, 1, 2)
        # Flatten entry
        ip.b3 = b = QPushButton(QIcon(I('heuristics.png')),
                                _('&Flatten this entry'))
        b.clicked.connect(self.flatten_item)
        b.setToolTip(
            _('All children of this entry are brought to the same '
              'level as this entry.'))
        l.addWidget(b, l.rowCount() + 1, 0, 1, 2)

        ip.hl4 = hl = QFrame()
        hl.setFrameShape(hl.HLine)
        l.addWidget(hl, l.rowCount(), 0, 1, 2)
        l.setRowMinimumHeight(rs, 20)

        # Return to welcome
        rs = l.rowCount()
        ip.b4 = b = QPushButton(QIcon(I('back.png')),
                                _('&Return to welcome screen'))
        b.clicked.connect(self.go_to_root)
        b.setToolTip(_('Go back to the top level view'))
        l.addWidget(b, l.rowCount() + 1, 0, 1, 2)

        l.setRowMinimumHeight(rs, 20)

        l.addWidget(QLabel(), l.rowCount(), 0, 1, 2)
        l.setColumnStretch(1, 10)
        l.setRowStretch(l.rowCount() - 1, 10)
        self.w2 = la = QLabel(self.w1.text())
        self.w2.setWordWrap(True)
        l.addWidget(la, l.rowCount(), 0, 1, 2)
Ejemplo n.º 28
0
    def genesis(self, gui):
        self.gui = gui
        db = gui.library_view.model().db

        r = self.register

        r('gui_layout',
          config,
          restart_required=True,
          choices=[(_('Wide'), 'wide'), (_('Narrow'), 'narrow')])
        r('ui_style',
          gprefs,
          restart_required=True,
          choices=[(_('System default'), 'system'),
                   (_('Calibre style'), 'calibre')])
        r('book_list_tooltips', gprefs)
        r('tag_browser_old_look', gprefs, restart_required=True)
        r('bd_show_cover', gprefs)
        r('bd_overlay_cover_size', gprefs)
        r('cover_grid_width', gprefs)
        r('cover_grid_height', gprefs)
        r('cover_grid_cache_size_multiple', gprefs)
        r('cover_grid_disk_cache_size', gprefs)
        r('cover_grid_spacing', gprefs)
        r('cover_grid_show_title', gprefs)

        r('cover_flow_queue_length', config, restart_required=True)
        r('cover_browser_reflections', gprefs)
        r('show_rating_in_cover_browser', gprefs)
        r('emblem_size', gprefs)
        r('emblem_position',
          gprefs,
          choices=[(_('Left'), 'left'), (_('Top'), 'top'),
                   (_('Right'), 'right'), (_('Bottom'), 'bottom')])
        r('book_list_extra_row_spacing', gprefs)

        def get_esc_lang(l):
            if l == 'en':
                return 'English'
            return get_language(l)

        lang = get_lang()
        if lang is None or lang not in available_translations():
            lang = 'en'
        items = [(l, get_esc_lang(l)) for l in available_translations()
                 if l != lang]
        if lang != 'en':
            items.append(('en', get_esc_lang('en')))
        items.sort(cmp=lambda x, y: cmp(x[1].lower(), y[1].lower()))
        choices = [(y, x) for x, y in items]
        # Default language is the autodetected one
        choices = [(get_language(lang), lang)] + choices
        r('language', prefs, choices=choices, restart_required=True)

        r('show_avg_rating', config)
        r('disable_animations', config)
        r('systray_icon', config, restart_required=True)
        r('show_splash_screen', gprefs)
        r('disable_tray_notification', config)
        r('use_roman_numerals_for_series_number', config)
        r('separate_cover_flow', config, restart_required=True)
        r('cb_fullscreen', gprefs)
        r('cb_preserve_aspect_ratio', gprefs)

        choices = [(_('Off'), 'off'), (_('Small'), 'small'),
                   (_('Medium'), 'medium'), (_('Large'), 'large')]
        r('toolbar_icon_size', gprefs, choices=choices)

        choices = [(_('If there is enough room'), 'auto'),
                   (_('Always'), 'always'), (_('Never'), 'never')]
        r('toolbar_text', gprefs, choices=choices)

        choices = [(_('Disabled'), 'disable'),
                   (_('By first letter'), 'first letter'),
                   (_('Partitioned'), 'partition')]
        r('tags_browser_partition_method', gprefs, choices=choices)
        r('tags_browser_collapse_at', gprefs)
        r('default_author_link', gprefs)
        r('tag_browser_dont_collapse', gprefs, setting=CommaSeparatedList)

        self.search_library_for_author_button.clicked.connect(
            lambda: self.opt_default_author_link.setText('search-calibre'))

        choices = set([
            k for k in db.field_metadata.all_field_keys()
            if (db.field_metadata[k]['is_category'] and
                (db.field_metadata[k]['datatype'] in
                 ['text', 'series', 'enumeration'])
                and not db.field_metadata[k]['display'].get('is_names', False))
            or (db.field_metadata[k]['datatype'] in ['composite'] and
                db.field_metadata[k]['display'].get('make_category', False))
        ])
        choices -= set(
            ['authors', 'publisher', 'formats', 'news', 'identifiers'])
        choices |= set(['search'])
        self.opt_categories_using_hierarchy.update_items_cache(choices)
        r('categories_using_hierarchy',
          db.prefs,
          setting=CommaSeparatedList,
          choices=sorted(list(choices), key=sort_key))

        fm = db.field_metadata
        choices = sorted(
            ((fm[k]['name'], k)
             for k in fm.displayable_field_keys() if fm[k]['name']),
            key=lambda x: sort_key(x[0]))
        r('field_under_covers_in_grid', db.prefs, choices=choices)

        self.current_font = self.initial_font = None
        self.change_font_button.clicked.connect(self.change_font)

        self.display_model = DisplayedFields(self.gui.current_db,
                                             self.field_display_order)
        self.display_model.dataChanged.connect(self.changed_signal)
        self.field_display_order.setModel(self.display_model)
        self.df_up_button.clicked.connect(self.move_df_up)
        self.df_down_button.clicked.connect(self.move_df_down)

        self.edit_rules = EditRules(self.tabWidget)
        self.edit_rules.changed.connect(self.changed_signal)
        self.tabWidget.addTab(self.edit_rules,
                              QIcon(I('format-fill-color.png')),
                              _('Column coloring'))

        self.icon_rules = EditRules(self.tabWidget)
        self.icon_rules.changed.connect(self.changed_signal)
        self.tabWidget.addTab(self.icon_rules, QIcon(I('icon_choose.png')),
                              _('Column icons'))

        self.grid_rules = EditRules(self.emblems_tab)
        self.grid_rules.changed.connect(self.changed_signal)
        self.emblems_tab.setLayout(QVBoxLayout())
        self.emblems_tab.layout().addWidget(self.grid_rules)

        self.tabWidget.setCurrentIndex(0)
        keys = [
            QKeySequence('F11', QKeySequence.PortableText),
            QKeySequence('Ctrl+Shift+F', QKeySequence.PortableText)
        ]
        keys = [unicode(x.toString(QKeySequence.NativeText)) for x in keys]
        self.fs_help_msg.setText(
            unicode(self.fs_help_msg.text()) % (_(' or ').join(keys)))
        self.size_calculated.connect(self.update_cg_cache_size,
                                     type=Qt.QueuedConnection)
        self.tabWidget.currentChanged.connect(self.tab_changed)

        l = self.cg_background_box.layout()
        self.cg_bg_widget = w = Background(self)
        l.addWidget(w, 0, 0, 3, 1)
        self.cover_grid_color_button = b = QPushButton(_('Change &color'),
                                                       self)
        b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        l.addWidget(b, 0, 1)
        b.clicked.connect(self.change_cover_grid_color)
        self.cover_grid_texture_button = b = QPushButton(
            _('Change &background image'), self)
        b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        l.addWidget(b, 1, 1)
        b.clicked.connect(self.change_cover_grid_texture)
        self.cover_grid_default_appearance_button = b = QPushButton(
            _('Restore &default appearance'), self)
        b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        l.addWidget(b, 2, 1)
        b.clicked.connect(self.restore_cover_grid_appearance)
        self.cover_grid_empty_cache.clicked.connect(self.empty_cache)
        self.cover_grid_open_cache.clicked.connect(self.open_cg_cache)
        self.cover_grid_smaller_cover.clicked.connect(
            partial(self.resize_cover, True))
        self.cover_grid_larger_cover.clicked.connect(
            partial(self.resize_cover, False))
        self.cover_grid_reset_size.clicked.connect(self.cg_reset_size)
        self.opt_cover_grid_disk_cache_size.setMinimum(
            self.gui.grid_view.thumbnail_cache.min_disk_cache)
        self.opt_cover_grid_disk_cache_size.setMaximum(
            self.gui.grid_view.thumbnail_cache.min_disk_cache * 100)
        self.opt_cover_grid_width.valueChanged.connect(
            self.update_aspect_ratio)
        self.opt_cover_grid_height.valueChanged.connect(
            self.update_aspect_ratio)
Ejemplo n.º 29
0
    def setupUi(self, x):
        self.l = l = QVBoxLayout(self)
        self.la1 = la = QLabel(
            _("Values for the tweaks are shown below. Edit them to change the behavior of calibre."
              " Your changes will only take effect <b>after a restart</b> of calibre."
              ))
        l.addWidget(la), la.setWordWrap(True)
        self.splitter = s = QSplitter(self)
        s.setChildrenCollapsible(False)
        l.addWidget(s, 10)

        self.lv = lv = QWidget(self)
        lv.l = l2 = QVBoxLayout(lv)
        l2.setContentsMargins(0, 0, 0, 0)
        self.tweaks_view = tv = TweaksView(self)
        l2.addWidget(tv)
        self.plugin_tweaks_button = b = QPushButton(self)
        b.setToolTip(
            _("Edit tweaks for any custom plugins you have installed"))
        b.setText(_("&Plugin tweaks"))
        l2.addWidget(b)
        s.addWidget(lv)

        self.lv1 = lv = QWidget(self)
        s.addWidget(lv)
        lv.g = g = QGridLayout(lv)
        g.setContentsMargins(0, 0, 0, 0)

        self.search = sb = SearchBox2(self)
        sb.sizePolicy().setHorizontalStretch(10)
        sb.setSizeAdjustPolicy(sb.AdjustToMinimumContentsLength)
        sb.setMinimumContentsLength(10)
        g.addWidget(self.search, 0, 0, 1, 1)
        self.next_button = b = QPushButton(self)
        b.setIcon(QIcon(I("arrow-down.png")))
        b.setText(_("&Next"))
        g.addWidget(self.next_button, 0, 1, 1, 1)
        self.previous_button = b = QPushButton(self)
        b.setIcon(QIcon(I("arrow-up.png")))
        b.setText(_("&Previous"))
        g.addWidget(self.previous_button, 0, 2, 1, 1)

        self.hb = hb = QGroupBox(self)
        hb.setTitle(_("Help"))
        hb.l = l2 = QVBoxLayout(hb)
        self.help = h = QPlainTextEdit(self)
        l2.addWidget(h)
        h.setReadOnly(True)
        g.addWidget(hb, 1, 0, 1, 3)

        self.eb = eb = QGroupBox(self)
        g.addWidget(eb, 2, 0, 1, 3)
        eb.setTitle(_("Edit tweak"))
        eb.g = ebg = QGridLayout(eb)
        self.edit_tweak = et = QPlainTextEdit(self)
        et.setMinimumWidth(400)
        et.setLineWrapMode(QPlainTextEdit.NoWrap)
        ebg.addWidget(et, 0, 0, 1, 2)
        self.restore_default_button = b = QPushButton(self)
        b.setToolTip(_("Restore this tweak to its default value"))
        b.setText(_("&Reset this tweak"))
        ebg.addWidget(b, 1, 0, 1, 1)
        self.apply_button = ab = QPushButton(self)
        ab.setToolTip(_("Apply any changes you made to this tweak"))
        ab.setText(_("&Apply changes to this tweak"))
        ebg.addWidget(ab, 1, 1, 1, 1)
Ejemplo n.º 30
0
    def __init__(self, mygui, myguidb, mymainprefs, myparam_dict, myuiexit,
                 mysavedialoggeometry):
        super(LibraryCodesTab, self).__init__()
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.gui = mygui
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.guidb = myguidb
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.lib_path = self.gui.library_view.model().db.library_path
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.mytabprefs = mymainprefs
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.param_dict = myparam_dict
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.ui_exit = myuiexit
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.save_dialog_geometry = mysavedialoggeometry
        #-----------------------------------------------------
        #-----------------------------------------------------
        font = QFont()
        font.setBold(False)
        font.setPointSize(10)
        #-----------------------------------------------------
        self.layout_top = QVBoxLayout()
        self.layout_top.setSpacing(0)
        self.layout_top.setAlignment(Qt.AlignLeft)
        self.setLayout(self.layout_top)
        #-----------------------------------------------------
        self.scroll_area_frame = QScrollArea()
        self.scroll_area_frame.setAlignment(Qt.AlignLeft)
        self.scroll_area_frame.setWidgetResizable(True)
        self.scroll_area_frame.ensureVisible(400, 400)

        self.layout_top.addWidget(
            self.scroll_area_frame
        )  # the scroll area is now the child of the parent of self.layout_top

        # NOTE: the self.scroll_area_frame.setWidget(self.scroll_widget) is at the end of the init() AFTER all children have been created and assigned to a layout...

        #-----------------------------------------------------
        self.scroll_widget = QWidget()
        self.layout_top.addWidget(
            self.scroll_widget
        )  # causes automatic reparenting of QWidget to the parent of self.layout_top, which is:  self .
        #-----------------------------------------------------
        self.layout_frame = QVBoxLayout()
        self.layout_frame.setSpacing(0)
        self.layout_frame.setAlignment(Qt.AlignLeft)

        self.scroll_widget.setLayout(
            self.layout_frame
        )  # causes automatic reparenting of any widget later added to self.layout_frame to the parent of self.layout_frame, which is:  QWidget .

        #-----------------------------------------------------
        self.lc_groupbox = QGroupBox('Settings:')
        self.lc_groupbox.setMaximumWidth(400)
        self.lc_groupbox.setToolTip(
            "<p style='white-space:wrap'>The settings that control 'Library Codes'.  Using only ISBN or ISSN or Author/Title, Library Codes for selected books will be derived using the Current Settings."
        )
        self.layout_frame.addWidget(self.lc_groupbox)

        self.lc_layout = QGridLayout()
        self.lc_groupbox.setLayout(self.lc_layout)
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.spacing0 = QLabel()
        self.layout_frame.addWidget(self.spacing0)
        self.spacing0.setMaximumHeight(20)
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.button_box = QDialogButtonBox()
        self.button_box.setOrientation(Qt.Horizontal)
        self.button_box.setCenterButtons(True)

        self.layout_frame.addWidget(self.button_box)
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.push_button_save_only = QPushButton("Save")
        self.push_button_save_only.clicked.connect(self.save_settings)
        self.push_button_save_only.setDefault(True)
        self.push_button_save_only.setFont(font)
        self.push_button_save_only.setToolTip(
            "<p style='white-space:wrap'>Save all user settings.")
        self.button_box.addButton(self.push_button_save_only, 0)

        self.push_button_exit_only = QPushButton("Exit")
        self.push_button_exit_only.clicked.connect(self.exit_only)
        self.push_button_exit_only.setDefault(False)
        self.push_button_exit_only.setFont(font)
        self.push_button_exit_only.setToolTip(
            "<p style='white-space:wrap'>Exit immediately without saving anything."
        )
        self.button_box.addButton(self.push_button_exit_only, 0)
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------

        r = 4

        self.ddc_labelname = QLineEdit(self)
        self.ddc_labelname.setText(self.mytabprefs['DDC'])
        self.ddc_labelname.setFont(font)
        self.ddc_labelname.setToolTip(
            "<p style='white-space:wrap'>Custom Column Search/Lookup #name for DDC.<br><br>See:  https://www.oclc.org/dewey/features/summaries.en.html"
        )
        self.ddc_labelname.setMaximumWidth(100)
        self.lc_layout.addWidget(self.ddc_labelname, r, 0)

        self.ddc_activate_checkbox = QCheckBox(
            "Activate 'Dewey Decimal Code' Classification?")
        self.ddc_activate_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want to derive DDC?")
        r = r + 1
        self.lc_layout.addWidget(self.ddc_activate_checkbox, r, 0)
        if prefs['DDC_IS_ACTIVE'] == unicode_type(S_TRUE):
            self.ddc_activate_checkbox.setChecked(True)
        else:
            self.ddc_activate_checkbox.setChecked(False)
        #-----------------------------------------------------
        self.spacing1 = QLabel()
        r = r + 1
        self.lc_layout.addWidget(self.spacing1, r, 0)
        self.spacing1.setMaximumHeight(10)
        #-----------------------------------------------------
        self.lcc_labelname = QLineEdit(self)
        self.lcc_labelname.setText(self.mytabprefs['LCC'])
        self.lcc_labelname.setFont(font)
        self.lcc_labelname.setToolTip(
            "<p style='white-space:wrap'>Custom Column Search/Lookup #name for LCC.<br><br>See: http://www.loc.gov/catdir/cpso/lcco/ "
        )
        self.lcc_labelname.setMaximumWidth(100)
        r = r + 4
        self.lc_layout.addWidget(self.lcc_labelname, r, 0)

        self.lcc_activate_checkbox = QCheckBox(
            "Activate 'Library of Congress Code' Classification?")
        self.lcc_activate_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want to derive LCC?")
        r = r + 1
        self.lc_layout.addWidget(self.lcc_activate_checkbox, r, 0)
        if prefs['LCC_IS_ACTIVE'] == unicode_type(S_TRUE):
            self.lcc_activate_checkbox.setChecked(True)
        else:
            self.lcc_activate_checkbox.setChecked(False)
        #-----------------------------------------------------
        self.spacing2 = QLabel("")
        r = r + 1
        self.lc_layout.addWidget(self.spacing2, r, 0)
        self.spacing2.setMaximumHeight(10)
        #-----------------------------------------------------

        self.fast_labelname = QLineEdit(self)
        self.fast_labelname.setText(self.mytabprefs['FAST'])
        self.fast_labelname.setFont(font)
        self.fast_labelname.setToolTip(
            "<p style='white-space:wrap'>Custom Column Search/Lookup #name for FAST Tag Values. "
        )
        self.fast_labelname.setMinimumWidth(100)
        self.fast_labelname.setMaximumWidth(100)
        r = r + 4
        self.lc_layout.addWidget(self.fast_labelname, r, 0)

        self.fast_activate_checkbox = QCheckBox("Activate 'FAST' Tags?")
        self.fast_activate_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want to derive FAST Tags?\
                                                                                                                    <br><br>Text.  Behaves like Tags. Not Names.<br><br>"
        )
        r = r + 1
        self.lc_layout.addWidget(self.fast_activate_checkbox, r, 0)
        if prefs['FAST_IS_ACTIVE'] == unicode_type(S_TRUE):
            self.fast_activate_checkbox.setChecked(True)
        else:
            self.fast_activate_checkbox.setChecked(False)

        #-----------------------------------------------------
        self.spacing6 = QLabel("")
        r = r + 1
        self.lc_layout.addWidget(self.spacing6, r, 0)
        self.spacing6.setMaximumHeight(10)
        #-----------------------------------------------------

        self.oclc_labelname = QLineEdit(self)
        self.oclc_labelname.setText(self.mytabprefs['OCLC'])
        self.oclc_labelname.setFont(font)
        self.oclc_labelname.setToolTip(
            "<p style='white-space:wrap'>Custom Column Search/Lookup #name for OCLC-OWI.<br><br>See: #http://classify.oclc.org/classify2/   "
        )
        self.oclc_labelname.setMaximumWidth(100)
        r = r + 4
        self.lc_layout.addWidget(self.oclc_labelname, r, 0)

        self.oclc_activate_checkbox = QCheckBox(
            "Activate 'Online Computer Library Center' Work ID Code?")
        self.oclc_activate_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want to derive OCLC-OWI?")
        r = r + 1
        self.lc_layout.addWidget(self.oclc_activate_checkbox, r, 0)
        if self.mytabprefs['OCLC_IS_ACTIVE'] == unicode_type(S_TRUE):
            self.oclc_activate_checkbox.setChecked(True)
        else:
            self.oclc_activate_checkbox.setChecked(False)
        #-----------------------------------------------------
        self.spacing5 = QLabel("")
        r = r + 1
        self.lc_layout.addWidget(self.spacing5, r, 0)
        self.spacing5.setMaximumHeight(10)
        #-----------------------------------------------------
        self.lc_author_details_labelname = QLineEdit(self)
        self.lc_author_details_labelname.setText(
            self.mytabprefs['EXTRA_AUTHOR_DETAILS'])
        self.lc_author_details_labelname.setFont(font)
        self.lc_author_details_labelname.setToolTip(
            "<p style='white-space:wrap'>Custom Column Search/Lookup #name for 'LC Extra Author Details'.\
                                                                                                                              <br><br>Text.  Behaves like Tags. Not Names.<br><br>"
        )
        self.lc_author_details_labelname.setMaximumWidth(100)
        r = r + 4
        self.lc_layout.addWidget(self.lc_author_details_labelname, r, 0)

        self.lc_author_details_checkbox = QCheckBox(
            "Activate 'Library Codes Extra Author Details'?")
        self.lc_author_details_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want to add (never delete or replace) any available Tag-like values to this Custom Column if they are associated with the OCLC-OWI Identifier?"
        )
        r = r + 1
        self.lc_layout.addWidget(self.lc_author_details_checkbox, r, 0)
        if self.mytabprefs['EXTRA_AUTHOR_DETAILS_IS_ACTIVE'] == unicode_type(
                S_TRUE):
            self.lc_author_details_checkbox.setChecked(True)
        else:
            self.lc_author_details_checkbox.setChecked(False)
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.spacing4 = QLabel()
        r = r + 1
        self.lc_layout.addWidget(self.spacing4, r, 0)
        self.spacing4.setMaximumHeight(10)
        #-----------------------------------------------------
        font.setBold(False)
        font.setPointSize(7)
        #-----------------------------------------------------
        self.push_button_autoadd_custom_columns = QPushButton(
            "Automatically Add Activated Custom Columns?")
        self.push_button_autoadd_custom_columns.clicked.connect(
            self.autoadd_custom_columns)
        self.push_button_autoadd_custom_columns.setDefault(False)
        self.push_button_autoadd_custom_columns.setFont(font)
        self.push_button_autoadd_custom_columns.setToolTip(
            "<p style='white-space:wrap'>Do you want to automatically add the Custom Columns selected above?<br><br>If you have any issues, please add them manually."
        )
        r = r + 4
        self.lc_layout.addWidget(self.push_button_autoadd_custom_columns, r, 0)
        self.push_button_autoadd_custom_columns.setMaximumWidth(250)
        #-----------------------------------------------------
        self.lc_custom_columns_generation_label = QLabel()
        r = r + 1
        self.lc_layout.addWidget(self.lc_custom_columns_generation_label, r, 0)
        self.lc_custom_columns_generation_label.setText(
            "                                                              ")
        self.lc_custom_columns_generation_label.setMaximumHeight(10)
        self.lc_custom_columns_generation_label.setFont(font)

        self.oclc_identifier_only_checkbox = QCheckBox(
            "Always Create OCLC-OWI as an 'Identifier' (à la ISBN)?")
        self.oclc_identifier_only_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want to update Calibre's Identifiers for an Identifier of 'OCLC-OWI',\
                                                                                                                                 regardless of whether you want its own Custom Column updated?\
                                                                                                                                <br><br>REQUIRED to derive DDC/LCC using Author/Title."
        )
        r = r + 2
        self.lc_layout.addWidget(self.oclc_identifier_only_checkbox, r, 0)
        if prefs['OCLC_IDENTIFIER'] == unicode_type(S_TRUE):
            self.oclc_identifier_only_checkbox.setChecked(True)
        else:
            self.oclc_identifier_only_checkbox.setChecked(False)

        #-----------------------------------------------------
        self.spacing3 = QLabel("")
        r = r + 1
        self.lc_layout.addWidget(self.spacing3, r, 0)
        self.spacing3.setMaximumHeight(10)
        #-----------------------------------------------------
        font.setBold(False)
        font.setPointSize(10)
        #-----------------------------------------------------
        self.lc_genre_labelname = QLineEdit(self)
        self.lc_genre_labelname.setText(self.mytabprefs['GENRE'])
        self.lc_genre_labelname.setFont(font)
        self.lc_genre_labelname.setToolTip(
            "<p style='white-space:wrap'>Custom Column Search/Lookup #name for 'Genre'.\
                                                                                                                              <br><br>Text.  Behaves like Tags.<br><br>"
        )
        self.lc_genre_labelname.setMaximumWidth(100)
        r = r + 1
        self.lc_layout.addWidget(self.lc_genre_labelname, r, 0)

        self.lc_checkbox_buttongroup = QButtonGroup()
        self.lc_checkbox_buttongroup.setExclusive(True)

        self.lc_genre_ddc_checkbox = QCheckBox(
            "Update 'Genre' using DDC-to-Genre Mappings?")
        self.lc_genre_ddc_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want LC to update 'Genre' using the DDC-to-Genre mapping in Table _lc_genre_mapping?"
        )
        r = r + 1
        self.lc_layout.addWidget(self.lc_genre_ddc_checkbox, r, 0)

        self.lc_genre_lcc_checkbox = QCheckBox(
            "Update 'Genre' using LCC-to-Genre Mappings?")
        self.lc_genre_lcc_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want LC to update 'Genre' using the LCC-to-Genre mapping in Table _lc_genre_mapping?"
        )
        r = r + 1
        self.lc_layout.addWidget(self.lc_genre_lcc_checkbox, r, 0)

        self.lc_genre_inactive_checkbox = QCheckBox(
            "Do not update 'Genre' at all")
        self.lc_genre_inactive_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do no 'Genre' processing at all?")
        r = r + 1
        self.lc_layout.addWidget(self.lc_genre_inactive_checkbox, r, 0)

        self.lc_checkbox_buttongroup.addButton(self.lc_genre_ddc_checkbox)
        self.lc_checkbox_buttongroup.addButton(self.lc_genre_lcc_checkbox)
        self.lc_checkbox_buttongroup.addButton(self.lc_genre_inactive_checkbox)

        if self.mytabprefs['GENRE_DDC_IS_ACTIVE'] == unicode_type(S_TRUE):
            self.lc_genre_ddc_checkbox.setChecked(True)
        elif self.mytabprefs['GENRE_LCC_IS_ACTIVE'] == unicode_type(S_TRUE):
            self.lc_genre_lcc_checkbox.setChecked(True)
        elif self.mytabprefs['GENRE_IS_INACTIVE'] == unicode_type(S_TRUE):
            self.lc_genre_inactive_checkbox.setChecked(True)

        self.lc_exact_match_checkbox = QCheckBox(
            "DDC: Require an 'Exact Match', not a 'Best Match'?")
        self.lc_exact_match_checkbox.setToolTip(
            "<p style='white-space:wrap'>Check this checkbox if you want an exact DDC match to be required in Table _lc_genre_mapping.  Otherwise, a 'best match' will be used via progressive shortening from right to left, but not past any decimal point.  If there is no decimal point in a book's DDC, then no progressive shortening will be performed at all."
        )
        r = r + 1
        self.lc_layout.addWidget(self.lc_exact_match_checkbox, r, 0)

        if self.mytabprefs['GENRE_EXACT_MATCH'] == unicode_type(S_TRUE):
            self.lc_exact_match_checkbox.setChecked(True)

        self.spin_lcc = QSpinBox(self)
        self.spin_lcc.setMinimum(1)
        self.spin_lcc.setMaximum(50)
        self.spin_lcc.setProperty('value', prefs['GENRE_LCC_MATCH_LENGTH'])
        self.spin_lcc.setMaximumWidth(250)
        self.spin_lcc.setSuffix("    LCC: Maximum Length to Match")
        self.spin_lcc.setToolTip(
            "<p style='white-space:nowrap'>Maximum number of characters in the LCC that should be used to map to the 'Genre', starting from the left.  A maximum of 1 guarantees a (broad) match.\
                                                                                                   <br><br>LCCs are structured with either 1 or 2 beginning letters, so 2-character LCCs have special matching logic.\
                                                                                                   <br><br>Example:   Assume maximum = 2 for a LCC of 'Q1':  Q1 would be attempted.  If it failed, because the 2nd digit is a number, 'Q' would be attempted.\
                                                                                                   <br><br>Example:   Assume maximum = 2 for a LCC of 'PN1969.C65':  PN would be attempted.  If it failed, nothing else would be attempted.\
                                                                                                   <br><br>Example:   Assume maximum = 4 for a LCC of 'PN1969.C65':  PN19 would be attempted.  If it failed, nothing else would be attempted.\
                                                                                                   <br><br>Example:   Assume maximum = 4 for a LCC of 'Q1':  Q1 would be attempted.  If it failed, because the 2nd digit is a number, 'Q' would be attempted.\
                                                                                                   <br><br>Example:   Assume maximum = 4 for a LCC of 'Q389':  Q389 would be attempted.  If it failed, nothing else would be attempted."
        )
        r = r + 2
        self.lc_layout.addWidget(self.spin_lcc, r, 0)

        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.scroll_widget.resize(self.sizeHint())
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.scroll_area_frame.setWidget(
            self.scroll_widget
        )  # now that all widgets have been created and assigned to a layout...
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.scroll_area_frame.resize(self.sizeHint())
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.resize(self.sizeHint())