예제 #1
0
    def setup_ui(self):
        self.stacks = s = QStackedLayout(self)
        self.w = w = QWidget(self)
        self.w.l = l = QVBoxLayout(w)
        self.pi = pi = ProgressIndicator(self, 256)
        l.addStretch(1), l.addWidget(pi, alignment=Qt.AlignmentFlag.AlignHCenter), l.addSpacing(10)
        w.la = la = QLabel(_('Gathering data, please wait...'))
        f = la.font()
        f.setBold(True), f.setPointSize(28), la.setFont(f)
        l.addWidget(la, alignment=Qt.AlignmentFlag.AlignHCenter), l.addStretch(1)
        s.addWidget(w)

        self.w2 = w = QWidget(self)
        self.l = l = QVBoxLayout(w)
        s.addWidget(w)

        self.la = la = QLabel(_('Choose a program to open %s files') % self.file_type.upper())
        self.plist = pl = QListWidget(self)
        pl.doubleClicked.connect(self.accept)
        pl.setIconSize(QSize(48, 48)), pl.setSpacing(5)
        pl.doubleClicked.connect(self.accept)
        l.addWidget(la), l.addWidget(pl)
        la.setBuddy(pl)

        b = self.bb.addButton(_('&Browse computer for program'), QDialogButtonBox.ButtonRole.ActionRole)
        b.clicked.connect(self.manual)
        l.addWidget(self.bb)
예제 #2
0
파일: exim.py 프로젝트: buoyantair/calibre
    def setup_import_panel(self):
        self.import_panel = w = QWidget(self)
        self.stack.addWidget(w)
        w.stack = s = QStackedLayout(w)
        self.ig = w = QWidget()
        s.addWidget(w)
        w.l = l = QVBoxLayout(w)
        w.la = la = QLabel(
            _('Specify the folder containing the previously exported calibre data that you'
              ' wish to import.'))
        la.setWordWrap(True)
        l.addWidget(la)
        self.export_dir_button = b = QPushButton(QIcon(I('document_open.png')),
                                                 _('Choose &folder'), self)
        b.clicked.connect(self.select_import_folder)
        l.addWidget(b), l.addStretch()

        self.select_libraries_panel = w = QScrollArea(self)
        w.setWidgetResizable(True)
        s.addWidget(w)
        self.slp = w = QWidget(self)
        self.select_libraries_panel.setWidget(w)
        w.l = l = QVBoxLayout(w)
        w.la = la = QLabel(
            _('Specify locations for the libraries you want to import. A location must be an empty folder'
              ' on your computer. If you leave any blank, those libraries will not be imported.'
              ))
        la.setWordWrap(True)
        l.addWidget(la)
예제 #3
0
    def __init__(self, parent):
        QWidget.__init__(self, parent)
        self.sa = QScrollArea(self)
        self.lw = QWidget(self)
        self.l = QVBoxLayout(self.lw)
        self.sa.setWidget(self.lw), self.sa.setWidgetResizable(True)
        self.gl = gl = QVBoxLayout(self)
        self.la = QLabel(_(
            'Add new locations to search for books or authors using the "Search the internet" feature'
            ' of the Content server. The URLs should contain {author} which will be'
            ' replaced by the author name and, for book URLs, {title} which will'
            ' be replaced by the book title.'))
        self.la.setWordWrap(True)
        gl.addWidget(self.la)

        self.h = QHBoxLayout()
        gl.addLayout(self.h)
        self.add_url_button = b = QPushButton(QIcon(I('plus.png')), _('&Add URL'))
        b.clicked.connect(self.add_url)
        self.h.addWidget(b)
        self.export_button = b = QPushButton(_('Export URLs'))
        b.clicked.connect(self.export_urls)
        self.h.addWidget(b)
        self.import_button = b = QPushButton(_('Import URLs'))
        b.clicked.connect(self.import_urls)
        self.h.addWidget(b)
        self.clear_button = b = QPushButton(_('Clear'))
        b.clicked.connect(self.clear)
        self.h.addWidget(b)

        self.h.addStretch(10)
        gl.addWidget(self.sa, stretch=10)
        self.items = []
예제 #4
0
파일: init.py 프로젝트: qykth-git/calibre
    def __init__(self, parent):
        orientation = Qt.Orientation.Vertical
        if config['gui_layout'] == 'narrow':
            orientation = Qt.Orientation.Horizontal if is_widescreen() else Qt.Orientation.Vertical
        idx = 0 if orientation == Qt.Orientation.Vertical else 1
        size = 300 if orientation == Qt.Orientation.Vertical else 550
        Splitter.__init__(self, 'cover_browser_splitter', _('Cover browser'),
                I('cover_flow.png'),
                orientation=orientation, parent=parent,
                connect_button=not config['separate_cover_flow'],
                side_index=idx, initial_side_size=size, initial_show=False,
                shortcut='Shift+Alt+B')

        quickview_widget = QWidget()
        parent.quickview_splitter = QuickviewSplitter(
                parent=self, orientation=Qt.Orientation.Vertical, qv_widget=quickview_widget)
        parent.library_view = BooksView(parent)
        parent.library_view.setObjectName('library_view')
        stack = QStackedWidget(self)
        av = parent.library_view.alternate_views
        parent.pin_container = av.set_stack(stack)
        parent.grid_view = GridView(parent)
        parent.grid_view.setObjectName('grid_view')
        av.add_view('grid', parent.grid_view)
        parent.quickview_splitter.addWidget(stack)

        l = QVBoxLayout()
        l.setContentsMargins(4, 0, 0, 0)
        quickview_widget.setLayout(l)
        parent.quickview_splitter.addWidget(quickview_widget)
        parent.quickview_splitter.hide_quickview_widget()

        self.addWidget(parent.quickview_splitter)
예제 #5
0
파일: exim.py 프로젝트: buoyantair/calibre
    def setup_ui(self):
        self.l = l = QVBoxLayout(self)
        self.stack = s = QStackedLayout()
        l.addLayout(s)
        l.addWidget(self.bb)
        self.welcome = w = QWidget(self)
        s.addWidget(w)
        w.l = l = QVBoxLayout(w)
        w.la = la = QLabel('<p>' + _(
            'You can export all calibre data, including your books, settings and plugins'
            ' into a single folder. Then, you can use this tool to re-import all that'
            ' data into a different calibre install, for example, on another computer.'
        ) + '<p>' + _(
            'This is a simple way to move your calibre installation with all its data to'
            ' a new computer, or to replicate your current setup on a second computer.'
        ))
        la.setWordWrap(True)
        l.addWidget(la)
        l.addSpacing(20)
        self.exp_button = b = QPushButton(_('&Export all your calibre data'))
        connect_lambda(b.clicked, self, lambda self: self.show_panel('export'))
        l.addWidget(b), l.addSpacing(20)
        self.imp_button = b = QPushButton(
            _('&Import previously exported data'))
        connect_lambda(b.clicked, self, lambda self: self.show_panel('import'))
        l.addWidget(b), l.addStretch(20)

        self.setup_export_panel()
        self.setup_import_panel()
        self.show_panel(self.initial_panel)
예제 #6
0
파일: exim.py 프로젝트: buoyantair/calibre
 def setup_export_panel(self):
     self.export_panel = w = QWidget(self)
     self.stack.addWidget(w)
     w.l = l = QVBoxLayout(w)
     w.la = la = QLabel(
         _('Select which libraries you want to export below'))
     la.setWordWrap(True), l.addWidget(la)
     self.lib_list = ll = QListWidget(self)
     l.addWidget(ll)
     ll.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
     ll.setStyleSheet('QListView::item { padding: 5px }')
     ll.setAlternatingRowColors(True)
     lpaths = all_known_libraries()
     for lpath in sorted(
             lpaths, key=lambda x: numeric_sort_key(os.path.basename(x))):
         i = QListWidgetItem(self.export_lib_text(lpath), ll)
         i.setData(Qt.ItemDataRole.UserRole, lpath)
         i.setData(Qt.ItemDataRole.UserRole + 1, lpaths[lpath])
         i.setIcon(QIcon(I('lt.png')))
         i.setSelected(True)
     self.update_disk_usage.connect(
         (lambda i, sz: self.lib_list.item(i).setText(
             self.export_lib_text(
                 self.lib_list.item(i).data(Qt.ItemDataRole.UserRole), sz))
          ),
         type=Qt.ConnectionType.QueuedConnection)
예제 #7
0
파일: search.py 프로젝트: qykth-git/calibre
    def setup_store_checks(self):
        first_run = self.config.get('first_run', True)

        # Add check boxes for each store so the user
        # can disable searching specific stores on a
        # per search basis.
        existing = {}
        for n in self.store_checks:
            existing[n] = self.store_checks[n].isChecked()

        self.store_checks = {}

        stores_check_widget = QWidget()
        store_list_layout = QGridLayout()
        stores_check_widget.setLayout(store_list_layout)

        icon = QIcon(I('donate.png'))
        for i, x in enumerate(
                sorted(self.gui.istores.keys(), key=lambda x: x.lower())):
            cbox = QCheckBox(x)
            cbox.setChecked(existing.get(x, first_run))
            store_list_layout.addWidget(cbox, i, 0, 1, 1)
            if self.gui.istores[x].base_plugin.affiliate:
                iw = QLabel(self)
                iw.setToolTip('<p>' + _(
                    'Buying from this store supports the calibre developer: %s</p>'
                ) % self.gui.istores[x].base_plugin.author + '</p>')
                iw.setPixmap(icon.pixmap(16, 16))
                store_list_layout.addWidget(iw, i, 1, 1, 1)
            self.store_checks[x] = cbox
        store_list_layout.setRowStretch(store_list_layout.rowCount(), 10)
        self.store_list.setWidget(stores_check_widget)

        self.config['first_run'] = False
예제 #8
0
    def setup_ui(self):
        from calibre.gui2.convert.look_and_feel_ui import Ui_Form
        f, w = Ui_Form(), QWidget()
        f.setupUi(w)
        self.l = l = QFormLayout(self)
        self.setLayout(l)

        l.addRow(QLabel(_('Select what style information you want completely removed:')))
        self.h = h = QHBoxLayout()

        for name, text in (
                ('fonts', _('&Fonts')), ('margins', _('&Margins')), ('padding', _('&Padding')), ('floats', _('Flo&ats')), ('colors', _('&Colors')),
            ):
            c = QCheckBox(text)
            setattr(self, 'opt_' + name, c)
            h.addWidget(c)
            c.setToolTip(getattr(f, 'filter_css_' + name).toolTip())
        l.addRow(h)

        self.others = o = QLineEdit(self)
        l.addRow(_('&Other CSS properties:'), o)
        o.setToolTip(f.filter_css_others.toolTip())

        if self.current_name is not None:
            self.filter_current = c = QCheckBox(_('Only filter CSS in the current file (%s)') % self.current_name)
            l.addRow(c)

        l.addRow(self.bb)
예제 #9
0
def test(scale=0.25):
    from qt.core import QLabel, QPixmap, QMainWindow, QWidget, QScrollArea, QGridLayout
    from calibre.gui2 import Application
    app = Application([])
    mi = Metadata('Unknown', ['Kovid Goyal', 'John & Doe', 'Author'])
    mi.series = 'A series & styles'
    m = QMainWindow()
    sa = QScrollArea(m)
    w = QWidget(m)
    sa.setWidget(w)
    l = QGridLayout(w)
    w.setLayout(l), l.setSpacing(30)
    scale *= w.devicePixelRatioF()
    labels = []
    for r, color in enumerate(sorted(default_color_themes)):
        for c, style in enumerate(sorted(all_styles())):
            mi.series_index = c + 1
            mi.title = 'An algorithmic cover [%s]' % color
            prefs = override_prefs(cprefs, override_color_theme=color, override_style=style)
            scale_cover(prefs, scale)
            img = generate_cover(mi, prefs=prefs, as_qimage=True)
            img.setDevicePixelRatio(w.devicePixelRatioF())
            la = QLabel()
            la.setPixmap(QPixmap.fromImage(img))
            l.addWidget(la, r, c)
            labels.append(la)
    m.setCentralWidget(sa)
    w.resize(w.sizeHint())
    m.show()
    app.exec()
예제 #10
0
    def __init__(self, names, parent=None):
        QDialog.__init__(self, parent)
        self.names = names
        self.setWindowTitle(_('Choose master file'))
        self.l = l = QVBoxLayout()
        self.setLayout(l)
        self.la = la = QLabel(_('Choose the master file. All selected files will be merged into the master file:'))
        la.setWordWrap(True)
        l.addWidget(la)
        self.sa = sa = QScrollArea(self)
        l.addWidget(sa)
        self.bb = bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
        l.addWidget(bb)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        self.w = w = QWidget(self)
        w.l = QVBoxLayout()
        w.setLayout(w.l)

        buttons = self.buttons = [QRadioButton(n) for n in names]
        buttons[0].setChecked(True)
        for i in buttons:
            w.l.addWidget(i)
        sa.setWidget(w)

        self.resize(self.sizeHint() + QSize(150, 20))
예제 #11
0
    def __init__(self, device, rules):
        QGroupBox.__init__(self, _('Format specific sending'))
        self._device = weakref.ref(device)
        self.l = l = QVBoxLayout()
        self.setLayout(l)
        self.la = la = QLabel('<p>'+_(
            '''You can create rules that control where e-books of a specific
            format are sent to on the device. These will take precedence over
            the folders specified above.'''))
        la.setWordWrap(True)
        l.addWidget(la)
        self.sa = sa = QScrollArea(self)
        sa.setWidgetResizable(True)
        self.w = w = QWidget(self)
        w.l = QVBoxLayout()
        w.setLayout(w.l)
        sa.setWidget(w)
        l.addWidget(sa)
        self.widgets = []
        for rule in rules:
            r = Rule(device, rule)
            self.widgets.append(r)
            w.l.addWidget(r)
            r.remove.connect(self.remove_rule)

        if not self.widgets:
            self.add_rule()

        self.b = b = QPushButton(QIcon(I('plus.png')), _('Add a &new rule'))
        l.addWidget(b)
        b.clicked.connect(self.add_rule)
        self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Ignored)
예제 #12
0
    def hide_plugin(self):
        for sig in 'changed_signal restart_now'.split():
            try:
                getattr(self.showing_widget,
                        sig).disconnect(getattr(self, sig))
            except Exception:
                pass
        self.showing_widget = QWidget(self.scroll_area)
        self.scroll_area.setWidget(self.showing_widget)
        self.setWindowTitle(__appname__ + ' - ' + _('Preferences'))
        self.stack.setCurrentIndex(0)
        self.title_bar.show_plugin()
        self.setWindowIcon(QIcon(I('config.png')))

        for button in (QDialogButtonBox.StandardButton.Apply,
                       QDialogButtonBox.StandardButton.RestoreDefaults,
                       QDialogButtonBox.StandardButton.Cancel):
            button = self.bb.button(button)
            button.setVisible(False)

        self.bb.button(QDialogButtonBox.StandardButton.Close).setVisible(True)
        self.bb.button(QDialogButtonBox.StandardButton.Close).setDefault(
            False), self.bb.button(
                QDialogButtonBox.StandardButton.Close).setDefault(True)
        self.wizard_button.setVisible(True)
예제 #13
0
    def setup_ui(self):
        self.pb = pb = QProgressBar(self)
        pb.setTextVisible(True)
        pb.setSizePolicy(QSizePolicy.Policy.Expanding,
                         QSizePolicy.Policy.Fixed)
        pb.setRange(0, 0)
        self.w = w = QWidget(self)
        self.w.l = l = QVBoxLayout(w)
        l.addStretch(), l.addWidget(pb)
        self.w.la = la = QLabel(_('Checking external links, please wait...'))
        la.setStyleSheet('QLabel { font-size: 20px; font-weight: bold }')
        l.addWidget(la, 0, Qt.AlignmentFlag.AlignCenter), l.addStretch()

        self.l = l = QVBoxLayout(self)
        self.results = QTextBrowser(self)
        self.results.setOpenLinks(False)
        self.results.anchorClicked.connect(self.anchor_clicked)
        self.stack = s = QStackedWidget(self)
        s.addWidget(w), s.addWidget(self.results)
        l.addWidget(s)
        self.bh = h = QHBoxLayout()
        self.check_anchors = ca = QCheckBox(_('Check &anchors'))
        ca.setToolTip(
            _('Check HTML anchors in links (the part after the #).\n'
              ' This can be a little slow, since it requires downloading and parsing all the HTML pages.'
              ))
        ca.setChecked(tprefs.get('check_external_link_anchors', True))
        ca.stateChanged.connect(self.anchors_changed)
        h.addWidget(ca), h.addStretch(100), h.addWidget(self.bb)
        l.addLayout(h)
        self.bb.setStandardButtons(QDialogButtonBox.StandardButton.Close)
        self.rb = b = self.bb.addButton(_('&Refresh'),
                                        QDialogButtonBox.ButtonRole.ActionRole)
        b.setIcon(QIcon(I('view-refresh.png')))
        b.clicked.connect(self.refresh)
예제 #14
0
    def __init__(self, parent=None):
        QStackedWidget.__init__(self, parent)
        self.welcome = w = QLabel('<p>'+_(
            'Double click a file in the left panel to start editing'
            ' it.'))
        self.addWidget(w)
        w.setWordWrap(True)
        w.setAlignment(Qt.AlignmentFlag.AlignTop | Qt.AlignmentFlag.AlignHCenter)

        self.container = c = QWidget(self)
        self.addWidget(c)
        l = c.l = QVBoxLayout(c)
        c.setLayout(l)
        l.setContentsMargins(0, 0, 0, 0)
        self.editor_tabs = t = QTabWidget(c)
        l.addWidget(t)
        t.setDocumentMode(True)
        t.setTabsClosable(True)
        t.setMovable(True)
        pal = self.palette()
        if pal.color(QPalette.ColorRole.WindowText).lightness() > 128:
            i = QImage(I('modified.png'))
            i.invertPixels()
            self.modified_icon = QIcon(QPixmap.fromImage(i))
        else:
            self.modified_icon = QIcon(I('modified.png'))
        self.editor_tabs.currentChanged.connect(self.current_editor_changed)
        self.editor_tabs.tabCloseRequested.connect(self._close_requested)
        self.search_panel = SearchPanel(self)
        l.addWidget(self.search_panel)
        self.restore_state()
        self.editor_tabs.tabBar().installEventFilter(self)
예제 #15
0
 def __init__(self, msg, after=None, parent=None, size=256, interval=10):
     QStackedLayout.__init__(self, parent)
     self.wp = WaitPanel(msg, parent, size, interval)
     if after is None:
         after = QWidget(parent)
     self.after = after
     self.addWidget(self.wp)
     self.addWidget(after)
예제 #16
0
    def __init__(self, pathtobook, title=None, parent=None, prefs=None, write_result_to=None):
        QDialog.__init__(self, parent)
        self.last_reject_at = self.last_accept_at = -1000
        self.write_result_to = write_result_to
        self.prefs = prefs or te_prefs
        self.pathtobook = pathtobook
        self.working = True

        t = title or os.path.basename(pathtobook)
        self.book_title = t
        self.setWindowTitle(_('Edit the ToC in %s')%t)
        self.setWindowIcon(QIcon(I('highlight_only_on.png')))

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

        self.stacks = s = QStackedWidget(self)
        l.addWidget(s)
        self.loading_widget = lw = QWidget(self)
        s.addWidget(lw)
        ll = self.ll = QVBoxLayout()
        lw.setLayout(ll)
        self.pi = pi = ProgressIndicator()
        pi.setDisplaySize(QSize(200, 200))
        pi.startAnimation()
        ll.addWidget(pi, alignment=Qt.AlignmentFlag.AlignHCenter|Qt.AlignmentFlag.AlignCenter)
        la = self.wait_label = QLabel(_('Loading %s, please wait...')%t)
        la.setWordWrap(True)
        f = la.font()
        f.setPointSize(20), la.setFont(f)
        ll.addWidget(la, alignment=Qt.AlignmentFlag.AlignHCenter|Qt.AlignmentFlag.AlignTop)
        self.toc_view = TOCView(self, self.prefs)
        self.toc_view.add_new_item.connect(self.add_new_item)
        self.toc_view.tocw.history_state_changed.connect(self.update_history_buttons)
        s.addWidget(self.toc_view)
        self.item_edit = ItemEdit(self)
        s.addWidget(self.item_edit)

        bb = self.bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok|QDialogButtonBox.StandardButton.Cancel)
        l.addWidget(bb)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        self.undo_button = b = bb.addButton(_('&Undo'), QDialogButtonBox.ButtonRole.ActionRole)
        b.setToolTip(_('Undo the last action, if any'))
        b.setIcon(QIcon(I('edit-undo.png')))
        b.clicked.connect(self.toc_view.undo)

        self.explode_done.connect(self.read_toc, type=Qt.ConnectionType.QueuedConnection)
        self.writing_done.connect(self.really_accept, type=Qt.ConnectionType.QueuedConnection)

        r = self.screen().availableSize()
        self.resize(r.width() - 100, r.height() - 100)
        geom = self.prefs.get('toc_editor_window_geom', None)
        if geom is not None:
            QApplication.instance().safe_restore_geometry(self, bytes(geom))
        self.stacks.currentChanged.connect(self.update_history_buttons)
        self.update_history_buttons()
예제 #17
0
    def setup_ui(self):
        self.block_show = False
        self.properties = []
        self.l = l = QVBoxLayout(self)
        self.setLayout(l)
        h = QHBoxLayout()
        l.addLayout(h)
        self.la = la = QLabel(_('&Edit theme:'))
        h.addWidget(la)
        self.theme = t = QComboBox(self)
        la.setBuddy(t)
        t.addItems(sorted(custom_theme_names()))
        t.setMinimumWidth(200)
        if t.count() > 0:
            t.setCurrentIndex(0)
        t.currentIndexChanged[int].connect(self.show_theme)
        h.addWidget(t)

        self.add_button = b = QPushButton(QIcon(I('plus.png')),
                                          _('Add &new theme'), self)
        b.clicked.connect(self.create_new_theme)
        h.addWidget(b)

        self.remove_button = b = QPushButton(QIcon(I('minus.png')),
                                             _('&Remove theme'), self)
        b.clicked.connect(self.remove_theme)
        h.addWidget(b)
        h.addStretch(1)

        self.scroll = s = QScrollArea(self)
        self.w = w = QWidget(self)
        s.setWidget(w), s.setWidgetResizable(True)
        self.cl = cl = QVBoxLayout()
        w.setLayout(cl)

        from calibre.gui2.tweak_book.editor.text import TextEdit
        self.preview = p = TextEdit(self, expected_geometry=(73, 50))
        p.load_text(
            HELP_TEXT.format(*[
                '<b>%s</b>' % x
                for x in ('Normal', 'Visual', 'CursorLine', 'LineNr',
                          'MatchParen', 'Function', 'Type', 'Statement',
                          'Constant', 'SpecialCharacter', 'Error',
                          'SpellError', 'Comment')
            ]))
        p.setMaximumWidth(p.size_hint.width() + 5)
        s.setMinimumWidth(600)
        self.splitter = sp = QSplitter(self)
        l.addWidget(sp)
        sp.addWidget(s), sp.addWidget(p)

        self.bb.clear()
        self.bb.addButton(QDialogButtonBox.StandardButton.Close)
        l.addWidget(self.bb)

        if self.theme.count() > 0:
            self.show_theme()
예제 #18
0
 def __init__(self, parent=None):
     super().__init__(parent)
     self.setWidgetResizable(True)
     self.w = w = QWidget()
     self.setWidget(w)
     w.l = QVBoxLayout(w)
     w.l.addStretch(1)
     self.all_actions = []
     self.new_action()
예제 #19
0
    def __init__(self, parent, model):
        QWidget.__init__(self, parent)

        self.l = l = QHBoxLayout(self)

        self.view = v = QListView(self)
        v.doubleClicked.connect(self.item_activated)
        v.setModel(CustomRecipeModel(model))
        l.addWidget(v)

        self.stacks = s = QStackedWidget(self)
        l.addWidget(s, stretch=10, alignment=Qt.AlignmentFlag.AlignTop)

        self.first_msg = la = QLabel(
            _('Create a new news source by clicking one of the buttons below'))
        la.setWordWrap(True)
        s.addWidget(la)

        self.w = w = QWidget(self)
        w.l = l = QVBoxLayout(w)
        l.setContentsMargins(0, 0, 0, 0)
        s.addWidget(w)

        self.title = la = QLabel(w)
        la.setAlignment(Qt.AlignmentFlag.AlignHCenter
                        | Qt.AlignmentFlag.AlignTop)
        l.addWidget(la)
        l.setSpacing(20)

        self.edit_button = b = QPushButton(QIcon(I('modified.png')),
                                           _('&Edit this recipe'), w)
        b.setSizePolicy(
            QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed))
        b.clicked.connect(self.edit_requested)
        l.addWidget(b)
        self.remove_button = b = QPushButton(QIcon(I('list_remove.png')),
                                             _('&Remove this recipe'), w)
        b.clicked.connect(self.remove)
        b.setSizePolicy(
            QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed))
        l.addWidget(b)
        self.export_button = b = QPushButton(QIcon(I('save.png')),
                                             _('S&ave recipe as file'), w)
        b.setSizePolicy(
            QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed))
        b.clicked.connect(self.save_recipe)
        l.addWidget(b)
        self.download_button = b = QPushButton(
            QIcon(I('download-metadata.png')), _('&Download this recipe'), w)
        b.clicked.connect(self.download)
        b.setSizePolicy(
            QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed))
        l.addWidget(b)

        self.select_row()
        v.selectionModel().currentRowChanged.connect(self.recipe_selected)
예제 #20
0
 def test():
     w = QWidget()
     l = FlowLayout(w)
     la = QLabel('Some text in a label')
     l.addWidget(la)
     c = QCheckBox('A checkboxy widget')
     l.addWidget(c)
     cb = QComboBox()
     cb.addItems(['Item one'])
     l.addWidget(cb)
     return w
예제 #21
0
    def setup_ui(self):
        self.setWindowIcon(QIcon(I('modified.png')))
        self.l = l = QVBoxLayout(self)
        self.stack = s = QStackedLayout()
        l.addLayout(s), l.addWidget(self.bb)
        self.listc = c = QWidget(self)
        s.addWidget(c)
        c.l = l = QVBoxLayout(c)
        c.h = h = QHBoxLayout()
        l.addLayout(h)

        self.search_bar = sb = QLineEdit(self)
        sb.setPlaceholderText(_('Search for a snippet'))
        h.addWidget(sb)
        self.next_button = b = QPushButton(_('&Next'))
        b.clicked.connect(self.find_next)
        h.addWidget(b)

        c.h2 = h = QHBoxLayout()
        l.addLayout(h)
        self.snip_list = sl = QListWidget(self)
        sl.doubleClicked.connect(self.edit_snippet)
        h.addWidget(sl)

        c.l2 = l = QVBoxLayout()
        h.addLayout(l)
        self.add_button = b = QToolButton(self)
        b.setIcon(QIcon(I('plus.png'))), b.setText(_('&Add snippet')), b.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextUnderIcon)
        b.clicked.connect(self.add_snippet)
        l.addWidget(b)

        self.edit_button = b = QToolButton(self)
        b.setIcon(QIcon(I('modified.png'))), b.setText(_('&Edit snippet')), b.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextUnderIcon)
        b.clicked.connect(self.edit_snippet)
        l.addWidget(b)

        self.add_button = b = QToolButton(self)
        b.setIcon(QIcon(I('minus.png'))), b.setText(_('&Remove snippet')), b.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextUnderIcon)
        b.clicked.connect(self.remove_snippet)
        l.addWidget(b)

        self.add_button = b = QToolButton(self)
        b.setIcon(QIcon(I('config.png'))), b.setText(_('Change &built-in')), b.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextUnderIcon)
        b.clicked.connect(self.change_builtin)
        l.addWidget(b)

        for i, snip in enumerate(sorted(user_snippets.get('snippets', []), key=itemgetter('trigger'))):
            item = self.snip_to_item(snip)
            if i == 0:
                self.snip_list.setCurrentItem(item)

        self.edit_snip = es = EditSnippet(self)
        self.stack.addWidget(es)
예제 #22
0
    def init_main_window_mixin(self, db):
        self.setObjectName('MainWindow')
        self.setWindowIcon(QIcon(I('lt.png')))
        self.setWindowTitle(__appname__)

        self.setContextMenuPolicy(Qt.ContextMenuPolicy.NoContextMenu)
        self.centralwidget = QWidget(self)
        self.setCentralWidget(self.centralwidget)
        self._central_widget_layout = l = QVBoxLayout(self.centralwidget)
        l.setContentsMargins(0, 0, 0, 0)
        l.setSpacing(0)
        self.resize(1012, 740)
        self.location_manager = LocationManager(self)

        self.iactions['Fetch News'].init_scheduler(db)

        self.search_bar = SearchBar(self)
        self.bars_manager = BarsManager(self.donate_action,
                                        self.location_manager, self)
        for bar in self.bars_manager.main_bars:
            self.addToolBar(Qt.ToolBarArea.TopToolBarArea, bar)
            bar.setStyleSheet('QToolBar { border: 0px }')
        for bar in self.bars_manager.child_bars:
            self.addToolBar(Qt.ToolBarArea.BottomToolBarArea, bar)
            bar.setStyleSheet('QToolBar { border: 0px }')
        self.bars_manager.update_bars()
        # This is disabled because it introduces various toolbar related bugs
        # The width of the toolbar becomes the sum of both toolbars
        if tweaks['unified_title_toolbar_on_osx']:
            try:
                self.setUnifiedTitleAndToolBarOnMac(True)
            except AttributeError:
                pass  # PyQt seems to be missing this property

        # And now, start adding the real widgets
        l.addWidget(self.search_bar)

        # Add in the widget for the shutdown messages. It is invisible until a
        # message is shown
        smw = self.shutdown_message_widget = QLabel(self)
        smw.setAlignment(Qt.AlignmentFlag.AlignCenter)
        smw.setVisible(False)
        smw.setAutoFillBackground(True)
        smw.setStyleSheet(
            'QLabel { background-color: rgba(200, 200, 200, 200); color: black }'
        )
예제 #23
0
    def color_override(self, name):
        w = QWidget(self)
        l = QHBoxLayout(w)

        def b(name, text, tt):
            ans = QRadioButton(text, w)
            l.addWidget(ans)
            ans.setToolTip(tt)
            setattr(w, name, ans)
            ans.setObjectName(name)
            return ans

        b(
            'unset', _('No change'),
            _('Use the colors from the book styles, defaulting to black-on-white'
              ))
        b(
            'auto', _('Theme based'),
            _('When using a dark theme force dark colors, otherwise same as "No change"'
              ))
        b('manual', _('Custom'), _('Choose a custom color'))

        c = w.color_button = ColorButton(parent=w)
        l.addWidget(c)
        connect_lambda(c.clicked, w, lambda w: w.manual.setChecked(True))

        def getter(w):
            if w.unset.isChecked():
                return 'unset'
            if w.auto.isChecked():
                return 'auto'
            return w.color_button.color or 'auto'

        def setter(w, val):
            val = val or 'auto'
            if val == 'unset':
                w.unset.setChecked(True)
            elif val == 'auto':
                w.auto.setChecked(True)
            else:
                w.manual.setChecked(True)
                w.color_button.color = val

        self(name, widget=w, getter=getter, setter=setter)
        l.setContentsMargins(0, 0, 0, 0)
        return w
예제 #24
0
    def setup_ui(self):
        self.l = l = QVBoxLayout(self)
        self.splitter = s = QSplitter(self)
        s.setChildrenCollapsible(False)
        l.addWidget(s), l.addWidget(self.bb)
        self.bb.setStandardButtons(QDialogButtonBox.StandardButton.Yes
                                   | QDialogButtonBox.StandardButton.No)
        self.left = w = QWidget(self)
        s.addWidget(w)
        w.l = l = QVBoxLayout(w)
        l.setContentsMargins(0, 0, 0, 0)

        def cb(name, text, tt=''):
            ans = QCheckBox(text)
            l.addWidget(ans)
            prefs_key = ans.prefs_key = 'choose-merge-cb-' + name
            ans.setChecked(gprefs.get(prefs_key, True))
            connect_lambda(ans.stateChanged,
                           self,
                           lambda self, state: self.state_changed(
                               getattr(self, name), state),
                           type=Qt.ConnectionType.QueuedConnection)
            if tt:
                ans.setToolTip(tt)
            setattr(self, name, ans)
            return ans

        cb('merge_metadata', _('Merge metadata'),
           _('Merge the metadata of the selected books into the target book'))
        cb(
            'merge_formats', _('Merge formats'),
            _('Merge the book files of the selected books into the target book'
              ))
        cb('delete_books', _('Delete merged books'),
           _('Delete the selected books after merging'))
        l.addStretch(10)
        self.msg = la = QLabel(self)
        la.setWordWrap(True)
        l.addWidget(la)
        self.update_msg()

        self.right = r = Target(self.mi, self)
        s.addWidget(r)
예제 #25
0
    def __init__(self, parent=None):
        QScrollArea.__init__(self, parent)
        self.setWidgetResizable(True)

        category_map, category_names = {}, {}
        for plugin in preferences_plugins():
            if plugin.category not in category_map:
                category_map[plugin.category] = plugin.category_order
            if category_map[plugin.category] < plugin.category_order:
                category_map[plugin.category] = plugin.category_order
            if plugin.category not in category_names:
                category_names[plugin.category] = (plugin.gui_category
                                                   if plugin.gui_category else
                                                   plugin.category)

        self.category_names = category_names

        categories = list(category_map.keys())
        categories.sort(key=lambda x: category_map[x])

        self.category_map = OrderedDict()
        for c in categories:
            self.category_map[c] = []

        for plugin in preferences_plugins():
            self.category_map[plugin.category].append(plugin)

        for plugins in self.category_map.values():
            plugins.sort(key=lambda x: x.name_order)

        self.widgets = []
        self._layout = QVBoxLayout()
        self.container = QWidget(self)
        self.container.setLayout(self._layout)
        self.setWidget(self.container)

        for name, plugins in self.category_map.items():
            w = Category(name, plugins, self.category_names[name], parent=self)
            self.widgets.append(w)
            self._layout.addWidget(w)
            w.plugin_activated.connect(self.show_plugin.emit)
        self._layout.addStretch(1)
예제 #26
0
    def __init__(self, username, restriction, parent=None):
        QDialog.__init__(self, parent)
        self.setWindowTitle(_('Change library access permissions for {}').format(username))
        self.username = username
        self._items = []
        self.l = l = QFormLayout(self)
        l.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.AllNonFixedFieldsGrow)

        self.libraries = t = QWidget(self)
        t.setObjectName('libraries')
        t.l = QVBoxLayout(self.libraries)
        self.atype = a = QComboBox(self)
        a.addItems([_('All libraries'), _('Only the specified libraries'), _('All except the specified libraries')])
        self.library_restrictions = restriction['library_restrictions'].copy()
        if restriction['allowed_library_names']:
            a.setCurrentIndex(1)
            self.items = restriction['allowed_library_names']
        elif restriction['blocked_library_names']:
            a.setCurrentIndex(2)
            self.items = restriction['blocked_library_names']
        else:
            a.setCurrentIndex(0)
        a.currentIndexChanged.connect(self.atype_changed)
        l.addRow(_('Allow access to:'), a)

        self.msg = la = QLabel(self)
        la.setWordWrap(True)
        l.addRow(la)
        self.la = la = QLabel(_('Specify the libraries below:'))
        la.setWordWrap(True)
        self.sa = sa = QScrollArea(self)
        sa.setWidget(t), sa.setWidgetResizable(True)
        l.addRow(la), l.addRow(sa)
        self.atype_changed()

        self.bb = bb = QDialogButtonBox(
            QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
        )
        bb.accepted.connect(self.accept), bb.rejected.connect(self.reject)
        l.addWidget(bb)
        self.items = self.items
예제 #27
0
    def setup_ui(self):
        self.l = l = QVBoxLayout(self)
        self.splitter = s = QSplitter(self)
        s.setChildrenCollapsible(False)
        l.addWidget(s), l.addWidget(self.bb)
        self.bb.setStandardButtons(QDialogButtonBox.StandardButton.Yes
                                   | QDialogButtonBox.StandardButton.No)

        self.left = w = QWidget(self)
        s.addWidget(w)
        w.l = l = QVBoxLayout(w)
        l.setContentsMargins(0, 0, 0, 0)
        self.la = la = QLabel(self.msg)
        la.setWordWrap(True)
        l.addWidget(la)
        self.confirm = c = QCheckBox(_('Show this confirmation again'), self)
        c.setChecked(True)
        c.stateChanged.connect(self.toggle)
        l.addWidget(c)

        self.right = r = Target(self.mi, self)
        s.addWidget(r)
예제 #28
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.ConnectionType.QueuedConnection)
        self.maximized_at_last_fullscreen = False
        self.save_pos_timer = t = QTimer(self)
        t.setSingleShot(True), t.setInterval(3000), t.setTimerType(Qt.TimerType.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(QMainWindow.DockOption.AnimatedDocks | QMainWindow.DockOption.AllowTabbedDocks | QMainWindow.DockOption.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.ToolBarArea.LeftToolBarArea, at)
        try:
            os.makedirs(annotations_dir)
        except EnvironmentError:
            pass
        self.current_book_data = {}
        get_current_book_data(self.current_book_data)
        self.book_prepared.connect(self.load_finished, type=Qt.ConnectionType.QueuedConnection)
        self.dock_defs = dock_defs()

        def create_dock(title, name, area, areas=Qt.DockWidgetArea.LeftDockWidgetArea | Qt.DockWidgetArea.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)
        w.toggle_requested.connect(self.toggle_highlights)

        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.search_result_discovered.connect(self.search_widget.search_result_discovered)
        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.ConnectionType.QueuedConnection)
        self.web_view.selection_changed.connect(self.lookup_widget.selected_text_changed, type=Qt.ConnectionType.QueuedConnection)
        self.web_view.selection_changed.connect(self.highlights_widget.selected_text_changed, type=Qt.ConnectionType.QueuedConnection)
        self.web_view.view_image.connect(self.view_image, type=Qt.ConnectionType.QueuedConnection)
        self.web_view.copy_image.connect(self.copy_image, type=Qt.ConnectionType.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.ConnectionType.QueuedConnection)
        self.web_view.reset_interface.connect(self.reset_interface, type=Qt.ConnectionType.QueuedConnection)
        self.web_view.quit.connect(self.quit, type=Qt.ConnectionType.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.web_view.edit_book.connect(self.edit_book)
        self.actions_toolbar.initialize(self.web_view, self.search_dock.toggleViewAction())
        at.update_action_state(False)
        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()
예제 #29
0
                                 Qt.ConnectionType.QueuedConnection)

    def stop_animation(self):
        self.animation.stop()
        self.animation_finished()

    def paintEvent(self, ev):
        size = self._icon_size if self._icon_size > 10 else self.iconSize(
        ).width()
        p = QPainter(self)
        opt = QStyleOptionToolButton()
        self.initStyleOption(opt)
        s = self.style()
        opt.iconSize = QSize(size, size)
        s.drawComplexControl(QStyle.ComplexControl.CC_ToolButton, opt, p, self)


if __name__ == '__main__':
    from qt.core import QApplication, QHBoxLayout
    app = QApplication([])
    w = QWidget()
    w.setLayout(QHBoxLayout())
    b = ThrobbingButton()
    b.setIcon(QIcon(I('donate.png')))
    w.layout().addWidget(b)
    w.show()
    b.set_normal_icon_size(64, 64)
    b.start_animation()

    app.exec()
예제 #30
0
 def __init__(self, parent=None):
     QScrollArea.__init__(self, parent)
     self.setWidgetResizable(True)
     self.w = QWidget(self)
     self.l = QGridLayout(self.w)
     self.setWidget(self.w)