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)
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)
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 = []
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)
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)
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)
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
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)
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()
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))
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)
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)
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)
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)
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)
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()
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()
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()
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)
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
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)
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 }' )
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
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)
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)
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
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)
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()
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()
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)